buySell cards added

This commit is contained in:
Michael Wain 2024-06-19 03:50:41 +03:00
parent fdb3579ea1
commit 580f34c754
25 changed files with 400 additions and 110 deletions

View File

@ -4,12 +4,60 @@ import com.alterdekim.Protocol;
import com.alterdekim.hearthhack.component.TcpConnection;
import com.alterdekim.hearthhack.util.BattleNetPacket;
import com.alterdekim.hearthhack.util.ClientRequestBody;
import lombok.extern.slf4j.Slf4j;
import java.util.stream.IntStream;
import static com.alterdekim.hearthhack.util.GameUtilities.generateNotification;
@Slf4j
public class BuySellCard extends ClientRequestParser {
@Override
public void parse(BattleNetPacket packet, ClientRequestBody body, TcpConnection conn) throws Exception {
Protocol.BuySellCard request = Protocol.BuySellCard.parseFrom(body.getBody());
int count = request.hasCount() ? request.getCount() : 1;
if( request.getBuying() ) {
if( conn.getUserService().getDustForUserId(conn.getUserId()) < request.getUnitBuyPrice()*count ) {
sendResponse(Protocol.BoughtSoldCard.newBuilder()
.setAmount(0)
.setResult(Protocol.BoughtSoldCard.Result.WRONG_BUY_PRICE)
.setDef(request.getDef())
.build(), conn);
return;
}
IntStream.range(0, count).forEach(i -> conn.getUserService().addCardToCollection(conn.getUserId(), (long) request.getDef().getAsset(), request.getDef().getPremium() != 0, true));
conn.getUserService().setDustForUserId(conn.getUserId(), conn.getUserService().getDustForUserId(conn.getUserId())-(request.getUnitBuyPrice()*count));
sendResponse(Protocol.BoughtSoldCard.newBuilder()
.setAmount(request.getUnitBuyPrice()*count)
.setCount(count)
.setResult(Protocol.BoughtSoldCard.Result.BOUGHT)
.setDef(request.getDef())
.build(), conn);
return;
}
conn.getUserService().removeCardToCollection(conn.getUserId(), (long) request.getDef().getAsset(), request.getDef().getPremium() != 0);
conn.getUserService().setDustForUserId(conn.getUserId(), conn.getUserService().getDustForUserId(conn.getUserId())+(request.getUnitSellPrice()*count));
sendResponse(Protocol.BoughtSoldCard.newBuilder()
.setAmount(request.getUnitSellPrice()*count)
.setCount(count)
.setResult(Protocol.BoughtSoldCard.Result.SOLD)
.setDef(request.getDef())
.build(), conn);
}
private void sendResponse(Protocol.BoughtSoldCard response, TcpConnection conn) throws Exception {
Protocol.Notification n = generateNotification(258, response.toByteString(), response.getSerializedSize());
Protocol.Header header = Protocol.Header.newBuilder()
.setServiceId(4)
.setMethodId(1)
.setToken(conn.nextToken())
.setObjectId(0)
.setSize(n.getSerializedSize())
.setStatus(0)
.build();
conn.send(new BattleNetPacket(header, n.toByteArray()));
}
@Override

View File

@ -1,14 +1,18 @@
package com.alterdekim.hearthhack.component.processor.client.request;
import com.alterdekim.Protocol;
import com.alterdekim.hearthhack.component.TcpConnection;
import com.alterdekim.hearthhack.util.BattleNetPacket;
import com.alterdekim.hearthhack.util.ClientRequestBody;
import lombok.extern.slf4j.Slf4j;
@Slf4j
public class DeckUpdate extends ClientRequestParser {
@Override
public void parse(BattleNetPacket packet, ClientRequestBody body, TcpConnection conn) throws Exception {
// 222 DeckSetData
Protocol.DeckSetData data = Protocol.DeckSetData.parseFrom(body.getBody());
log.info("DeckSetData: {}", data);
}
@Override

View File

@ -11,8 +11,8 @@ public class SetCardSeen extends ClientRequestParser {
@Override
public void parse(BattleNetPacket packet, ClientRequestBody body, TcpConnection conn) throws Exception {
Protocol.AckCardSeen request = Protocol.AckCardSeen.parseFrom(body.getBody());
List<Protocol.CardDef> l = request.getCardDefsList();
request.getCardDefsList()
.forEach(c -> conn.getUserService().updateCardSeenCollection(conn.getUserId(), (long) c.getAsset(), c.getPremium() != 0, true));
}
@Override

View File

@ -9,6 +9,7 @@ import java.util.List;
import java.util.stream.Collectors;
import static com.alterdekim.hearthhack.util.GameUtilities.generateEmptyNotification;
import static com.alterdekim.hearthhack.util.GameUtilities.generateNotification;
import static com.alterdekim.hearthhack.util.GetAccountInfoRequest.COLLECTION;
@ -26,8 +27,6 @@ public class Collection extends GenericParser {
@Override
public void parseGenericRequest(int token, TcpConnection conn) throws Exception {
// my collection
List<Protocol.CardStack> l = conn.getUserService().getCollectionOfUser(conn.getUserId())
.stream()
.map(p -> Protocol.CardStack.newBuilder()
@ -40,13 +39,11 @@ public class Collection extends GenericParser {
.build())
.collect(Collectors.toList());
log.info("Collection: {}", l);
Protocol.Collection collection = Protocol.Collection.newBuilder()
.addAllStacks(l)
.build();
Protocol.Notification n = generateEmptyNotification(207);
Protocol.Notification n = generateNotification(207, collection.toByteString(), collection.getSerializedSize());
Protocol.Header header = Protocol.Header.newBuilder()
.setServiceId(4)

View File

@ -1,51 +1,27 @@
package com.alterdekim.hearthhack.game;
public enum TagCardSet {
// Token: 0x04000B64 RID: 2916
INVALID,
// Token: 0x04000B65 RID: 2917
TEST_TEMPORARY,
// Token: 0x04000B66 RID: 2918
CORE,
// Token: 0x04000B67 RID: 2919
EXPERT1,
// Token: 0x04000B68 RID: 2920
REWARD,
// Token: 0x04000B69 RID: 2921
MISSIONS,
// Token: 0x04000B6A RID: 2922
DEMO,
// Token: 0x04000B6B RID: 2923
NONE,
// Token: 0x04000B6C RID: 2924
CHEAT,
// Token: 0x04000B6D RID: 2925
BLANK,
// Token: 0x04000B6E RID: 2926
DEBUG_SP,
// Token: 0x04000B6F RID: 2927
PROMO,
// Token: 0x04000B70 RID: 2928
FP1,
// Token: 0x04000B71 RID: 2929
PE1,
// Token: 0x04000B72 RID: 2930
BRM,
// Token: 0x04000B73 RID: 2931
TGT,
// Token: 0x04000B74 RID: 2932
CREDITS,
// Token: 0x04000B75 RID: 2933
HERO_SKINS,
// Token: 0x04000B76 RID: 2934
TB,
// Token: 0x04000B77 RID: 2935
SLUSH,
// Token: 0x04000B78 RID: 2936
LOE,
// Token: 0x04000B79 RID: 2937
OG,
// Token: 0x04000B7A RID: 2938
OG_RESERVE
}
}

View File

@ -0,0 +1,15 @@
package com.alterdekim.hearthhack.game;
public enum TagCardType {
INVALID,
GAME,
PLAYER,
HERO,
MINION,
SPELL,
ENCHANTMENT,
WEAPON,
ITEM,
TOKEN,
HERO_POWER
}

View File

@ -0,0 +1,16 @@
package com.alterdekim.hearthhack.game;
public enum TagClass {
INVALID,
DEATHKNIGHT,
DRUID,
HUNTER,
MAGE,
PALADIN,
PRIEST,
ROGUE,
SHAMAN,
WARLOCK,
WARRIOR,
DREAM
}

View File

@ -0,0 +1,8 @@
package com.alterdekim.hearthhack.game;
public enum TagEnchantmentVisual {
INVALID,
POSITIVE,
NEGATIVE,
NEUTRAL
}

View File

@ -0,0 +1,8 @@
package com.alterdekim.hearthhack.game;
public enum TagFaction {
INVALID,
HORDE,
ALLIANCE,
NEUTRAL
}

View File

@ -0,0 +1,11 @@
package com.alterdekim.hearthhack.game;
public enum TagGoldRewardState {
INVALID,
ELIGIBLE,
WRONG_GAME_TYPE,
ALREADY_CAPPED,
BAD_RATING,
SHORT_GAME,
OVER_CAIS
}

View File

@ -0,0 +1,9 @@
package com.alterdekim.hearthhack.game;
public enum TagMulligan {
INVALID,
INPUT,
DEALING,
WAITING,
DONE
}

View File

@ -0,0 +1,13 @@
package com.alterdekim.hearthhack.game;
public enum TagPlayState {
INVALID,
PLAYING,
WINNING,
LOSING,
WON,
LOST,
TIED,
DISCONNECTED,
CONCEDED
}

View File

@ -0,0 +1,6 @@
package com.alterdekim.hearthhack.game;
public enum TagPremium {
NORMAL,
GOLDEN
}

View File

@ -0,0 +1,29 @@
package com.alterdekim.hearthhack.game;
public enum TagRace {
INVALID,
BLOODELF,
DRAENEI,
DWARF,
GNOME,
GOBLIN,
HUMAN,
NIGHTELF,
ORC,
TAUREN,
TROLL,
UNDEAD,
WORGEN,
GOBLIN2,
MURLOC,
DEMON,
SCOURGE,
MECHANICAL,
ELEMENTAL,
OGRE,
PET,
TOTEM,
NERUBIAN,
PIRATE,
DRAGON
}

View File

@ -0,0 +1,10 @@
package com.alterdekim.hearthhack.game;
public enum TagRarity {
INVALID,
COMMON,
FREE,
RARE,
EPIC,
LEGENDARY
}

View File

@ -0,0 +1,8 @@
package com.alterdekim.hearthhack.game;
public enum TagState {
INVALID,
LOADING,
RUNNING,
COMPLETE
}

View File

@ -0,0 +1,22 @@
package com.alterdekim.hearthhack.game;
public enum TagStep {
INVALID,
BEGIN_FIRST,
BEGIN_SHUFFLE,
BEGIN_DRAW,
BEGIN_MULLIGAN,
MAIN_BEGIN,
MAIN_READY,
MAIN_RESOURCE,
MAIN_DRAW,
MAIN_START,
MAIN_ACTION,
MAIN_COMBAT,
MAIN_END,
MAIN_NEXT,
FINAL_WRAPUP,
FINAL_GAMEOVER,
MAIN_CLEANUP,
MAIN_START_TRIGGERS
}

View File

@ -0,0 +1,13 @@
package com.alterdekim.hearthhack.game;
public enum TagType {
UNKNOWN,
BOOL,
NUMBER,
COUNTER,
ENTITY,
PLAYER,
TEAM,
ENTITY_DEFINITION,
STRING
}

View File

@ -0,0 +1,12 @@
package com.alterdekim.hearthhack.game;
public enum TagZone {
INVALID,
PLAY,
DECK,
HAND,
GRAVEYARD,
REMOVEDFROMGAME,
SETASIDE,
SECRET
}

View File

@ -4,9 +4,11 @@ import com.alterdekim.hearthhack.dto.UserCardDTO;
import com.alterdekim.hearthhack.entity.User;
import com.alterdekim.hearthhack.entity.UserCard;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Modifying;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param;
import org.springframework.stereotype.Repository;
import org.springframework.transaction.annotation.Transactional;
import java.util.List;
@ -15,4 +17,14 @@ public interface UserCardRepository extends JpaRepository<UserCard, Long> {
@Query(nativeQuery = true)
List<UserCardDTO> getCollectionOfUser(@Param("userId") Long userId);
@Modifying
@Transactional
@Query(value = "UPDATE UserCard u SET u.hasSeen = :hasSeen WHERE u.userId = :userId AND u.assetId = :assetId AND u.isPremium = :isPremium")
void updateSeenByUserIdAndCard(@Param("userId") Long userId, @Param("assetId") Long assetId, @Param("isPremium") Boolean isPremium, @Param("hasSeen") Boolean hasSeen);
@Modifying
@Transactional
@Query(value = "DELETE FROM UserCard u WHERE u.id IN (SELECT MAX(b.id) FROM UserCard b WHERE b.userId = :userId AND b.assetId = :assetId AND b.isPremium = :isPremium)")
void remove(@Param("userId") Long userId, @Param("assetId") Long assetId, @Param("isPremium") Boolean isPremium);
}

View File

@ -22,4 +22,9 @@ public interface UserRepository extends JpaRepository<User, Long> {
@Modifying
@Query(value = "UPDATE User u SET u.goldBalance = :goldCount WHERE u.id = :userId")
void updateGoldOfUser(@Param("userId") Long userId, @Param("goldCount") Integer goldCount);
@Transactional
@Modifying
@Query(value = "UPDATE User u SET u.dustBalance = :dustCount WHERE u.id = :userId")
void updateDustOfUser(@Param("userId") Long userId, @Param("dustCount") Integer dustCount);
}

View File

@ -76,6 +76,10 @@ public class UserService implements IService {
userRepository.updateGoldOfUser(userId, gold);
}
public void setDustForUserId(Long userId, Integer dust) {
userRepository.updateDustOfUser(userId, dust);
}
public Integer getDustForUserId(Long userId) {
return userRepository.findById(userId).get().getDustBalance();
}
@ -98,10 +102,18 @@ public class UserService implements IService {
this.userCardRepository.save(new UserCard(userId, assetId, isPremium, hasSeen));
}
public void removeCardToCollection(Long userId, Long assetId, Boolean isPremium) {
this.userCardRepository.remove(userId, assetId, isPremium);
}
public List<UserCardDTO> getCollectionOfUser(Long userId) {
return this.userCardRepository.getCollectionOfUser(userId);
}
public void updateCardSeenCollection(Long userId, Long assetId, Boolean isPremium, Boolean hasSeen) {
this.userCardRepository.updateSeenByUserIdAndCard(userId, assetId, isPremium, hasSeen);
}
public List<UserDTO> findAllUsers() {
List<User> users = userRepository.findAll();
return users.stream().map(this::convertEntityToDto)

View File

@ -18,27 +18,4 @@ public class CardsXML {
@JsonProperty("Entity")
@JacksonXmlElementWrapper(useWrapping = false)
private List<XMLEntity> entities;
public Optional<XMLEntity> findEntityByCardId(String cardId) {
return this.entities.stream().filter(p -> p.getCardId().equals(cardId)).findFirst();
}
public List<XMLEntity> findEntitiesByTagVal(GameTag tag, Integer val) {
return this.entities.stream()
.filter(p -> p.getTags()
.stream()
.anyMatch(f -> f.getEnumID().intValue() == tag.getValue().intValue() && f.getValue().intValue() == val.intValue())
)
.collect(Collectors.toList());
}
public List<XMLEntity> findEntitiesByTagVal(GameTag tag, String val) {
return this.entities.stream()
.filter(p -> p.getTags()
.stream()
.anyMatch(f -> f.getEnumID().intValue() == tag.getValue().intValue() && f.getVal().equals(val))
)
.collect(Collectors.toList());
}
}

View File

@ -3357,4 +3357,58 @@ message BuySellCard {
required bool buying = 3;
optional int32 unit_sell_price = 4;
optional int32 unit_buy_price = 5;
}
// ref: PegasusUtil.DeckRenamed
message DeckRenamed {
// ref: PegasusUtil.DeckRenamed/PacketID
enum PacketID {
ID = 219;
}
required int64 deck = 1;
required string name = 2;
}
// ref: PegasusUtil.DeckSetData
message DeckSetData {
// ref: PegasusUtil.DeckSetData/PacketID
enum PacketID {
system = 0;
ID = 222;
}
required int64 deck = 1;
repeated DeckCardData cards = 2;
optional CardDef hero = 3;
optional int32 card_back = 4;
optional bool tagged_standard = 5;
}
// ref: PegasusUtil.BoughtSoldCard
message BoughtSoldCard {
// ref: PegasusUtil.BoughtSoldCard/PacketID
enum PacketID {
ID = 258;
}
// ref: PegasusUtil.BoughtSoldCard/Result
enum Result {
GENERIC_FAILURE = 1;
SOLD = 2;
BOUGHT = 3;
SOULBOUND = 4;
WRONG_SELL_PRICE = 5;
WRONG_BUY_PRICE = 6;
NO_PERMISSION = 7;
EVENT_NOT_ACTIVE = 8;
}
required CardDef def = 1;
required int32 amount = 2;
required Result result = 3;
optional int32 count = 4;
optional bool nerfed = 5;
optional int32 unit_sell_price = 6;
optional int32 unit_buy_price = 7;
}