diff --git a/src/main/java/com/alterdekim/hearthhack/component/GameConnection.java b/src/main/java/com/alterdekim/hearthhack/component/GameConnection.java index 7f45a33..d65c84e 100644 --- a/src/main/java/com/alterdekim/hearthhack/component/GameConnection.java +++ b/src/main/java/com/alterdekim/hearthhack/component/GameConnection.java @@ -44,6 +44,10 @@ public class GameConnection extends Thread { if( room.isEmpty() || !room.get().getPassword().equals(handshake.getPassword()) || !room.get().getPlayers().stream().anyMatch(p -> p.getUserId().longValue() == handshake.getClientHandle()) ) { + log.error("Handshake error details: room={}; password_equals={}; containsPlayer={}", room.isEmpty(), + room.get().getPassword().equals(handshake.getPassword()), + room.get().getPlayers().stream().anyMatch(p -> p.getUserId().longValue() == handshake.getClientHandle())); + log.error("Handshake error pwd: client={}; orig={}", handshake.getPassword(), room.get().getPassword()); log.error("Handshake failed!"); return; } diff --git a/src/main/java/com/alterdekim/hearthhack/component/GamePool.java b/src/main/java/com/alterdekim/hearthhack/component/GamePool.java index bc4d66f..18cfe5b 100644 --- a/src/main/java/com/alterdekim/hearthhack/component/GamePool.java +++ b/src/main/java/com/alterdekim/hearthhack/component/GamePool.java @@ -1,10 +1,12 @@ package com.alterdekim.hearthhack.component; +import com.alterdekim.hearthhack.component.interfaces.OnRoomFullCallback; import com.alterdekim.hearthhack.config.ObjectConfig; import com.alterdekim.hearthhack.dto.RoomPlayerDTO; import com.alterdekim.hearthhack.service.RoomService; import com.alterdekim.hearthhack.service.UserService; import jakarta.annotation.PostConstruct; +import lombok.Getter; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.scheduling.annotation.Scheduled; @@ -29,7 +31,10 @@ public class GamePool { private final ConcurrentHashMap games = new ConcurrentHashMap<>(); - private static final int PLAYERS_COUNT = 1; // TODO: MAKE 2 PLAYERS FOR PRODUCTION + @Getter + private final ConcurrentHashMap callbacks = new ConcurrentHashMap<>(); + + public static final int PLAYERS_COUNT = 2; // TODO: MAKE 2 PLAYERS FOR PRODUCTION @Scheduled(fixedRate = 200) private void refreshRooms() { @@ -40,8 +45,12 @@ public class GamePool { List players = r.getPlayers(); log.info("Put room by id: {}", r.getId()); games.put(r.getId(), new GameRoom(players, userService, r.getRoomPassword(), config)); + players.stream() + .filter(p -> callbacks.containsKey(p.getUserId())) + .forEach(p -> callbacks.get(p.getUserId()).onRoomFull()); roomService.removeRoom(r.getId()); }); + // TODO: move gamemaster thread stuff here } @PostConstruct diff --git a/src/main/java/com/alterdekim/hearthhack/component/GameRoom.java b/src/main/java/com/alterdekim/hearthhack/component/GameRoom.java index 4778362..adadb36 100644 --- a/src/main/java/com/alterdekim/hearthhack/component/GameRoom.java +++ b/src/main/java/com/alterdekim/hearthhack/component/GameRoom.java @@ -245,67 +245,73 @@ public class GameRoom extends Thread implements IGameRoom { @Override public void createGameEntity() { + // TODO: rewrite board generation, and send each packet not via broadcast, but via target send. log.info("create Game Entity"); - PegasusGame.PowerHistory powerHistory = PegasusGame.PowerHistory.newBuilder() - .addList(PegasusGame.PowerHistoryData.newBuilder() - .setCreateGame(PegasusGame.PowerHistoryCreateGame.newBuilder() - .setGameEntity(PegasusGame.Entity.newBuilder() - .setId(1) - .addTags(PegasusGame.Tag.newBuilder() - .setName(10) - .setValue(85) - ) - .addTags(PegasusGame.Tag.newBuilder() - .setName(GameTag.CARDTYPE.getValue()) - .setValue(TagCardType.GAME.ordinal()) - ) - .addTags(PegasusGame.Tag.newBuilder() - .setName(GameTag.TURN.getValue()) - .setValue(1) - ) - .addTags(PegasusGame.Tag.newBuilder() - .setName(GameTag.STATE.getValue()) - .setValue(TagState.RUNNING.ordinal()) - ) - .addTags(PegasusGame.Tag.newBuilder() - .setName(GameTag.ZONE.getValue()) - .setValue(TagZone.PLAY.ordinal()) - ) - .addTags(PegasusGame.Tag.newBuilder() - .setName(GameTag.ENTITY_ID.getValue()) - .setValue(1) - ) - .addTags(PegasusGame.Tag.newBuilder() - .setName(GameTag.STEP.getValue()) - .setValue(TagStep.BEGIN_MULLIGAN.ordinal()) // 10 - ) - .addTags(PegasusGame.Tag.newBuilder() - .setName(GameTag.NEXT_STEP.getValue()) - .setValue(TagStep.BEGIN_MULLIGAN.ordinal()) // 12 - ) - ) - .addAllPlayers(createPlayersEntity()) - ) - ).build(); + for( RoomPlayerDTO player : this.players ) { + PegasusGame.PowerHistory powerHistory = PegasusGame.PowerHistory.newBuilder() + .addList(PegasusGame.PowerHistoryData.newBuilder() + .setCreateGame(PegasusGame.PowerHistoryCreateGame.newBuilder() + .setGameEntity(PegasusGame.Entity.newBuilder() + .setId(1) + .addTags(PegasusGame.Tag.newBuilder() + .setName(10) + .setValue(85) + ) + .addTags(PegasusGame.Tag.newBuilder() + .setName(GameTag.CARDTYPE.getValue()) + .setValue(TagCardType.GAME.ordinal()) + ) + .addTags(PegasusGame.Tag.newBuilder() + .setName(GameTag.TURN.getValue()) + .setValue(1) + ) + .addTags(PegasusGame.Tag.newBuilder() + .setName(GameTag.STATE.getValue()) + .setValue(TagState.RUNNING.ordinal()) + ) + .addTags(PegasusGame.Tag.newBuilder() + .setName(GameTag.ZONE.getValue()) + .setValue(TagZone.PLAY.ordinal()) + ) + .addTags(PegasusGame.Tag.newBuilder() + .setName(GameTag.ENTITY_ID.getValue()) + .setValue(1) + ) + .addTags(PegasusGame.Tag.newBuilder() + .setName(GameTag.STEP.getValue()) + .setValue(TagStep.BEGIN_MULLIGAN.ordinal()) // 10 + ) + .addTags(PegasusGame.Tag.newBuilder() + .setName(GameTag.NEXT_STEP.getValue()) + .setValue(TagStep.BEGIN_MULLIGAN.ordinal()) // 12 + ) + ) + .addAllPlayers(createPlayersEntity(player)) + ) + ).build(); + + this.send(player.getUserId(), new PegasusPacket(19, 0, powerHistory.toByteArray())); + } - this.broadcast(new PegasusPacket(19, 0, powerHistory.toByteArray())); this.nextGlobalState(); } - public List createPlayersEntity() { + public List createPlayersEntity(RoomPlayerDTO player) { log.info("create Players entities"); List pls = new ArrayList<>(); + List rel_players = new ArrayList<>(Collections.singletonList(player)); + players.stream().filter(p -> p.getUserId().longValue() != p.getUserId().longValue()).forEach(rel_players::add); for( int i = 2, pi = 0; i < 4; i++, pi++ ) { final PegasusGame.Entity.Builder entity = PegasusGame.Entity.newBuilder().setId(i == 2 ? 3 : 2); - if( pi < this.players.size() ) { - players.get(pi).setController(i == 2 ? 2 : 1); + if( pi < rel_players.size() ) { + rel_players.get(pi).setController(i == 2 ? 2 : 1); GameDeck gd = new GameDeck(); - userService.getDeckContentForDeckId(players.get(pi).getUserId(), players.get(pi).getDeckId()) + userService.getDeckContentForDeckId(rel_players.get(pi).getUserId(), rel_players.get(pi).getDeckId()) .stream() .map(d -> card2Entity(d.getAssetId()).get()) .forEach(gd::addCard); - decks.put(players.get(pi).getUserId(), gd); + decks.put(rel_players.get(pi).getUserId(), gd); } if( i == 2 ) { @@ -403,7 +409,7 @@ public class GameRoom extends Thread implements IGameRoom { PegasusGame.Player.newBuilder() .setId(i) .setGameAccountId(bnets.get(i-2)) - .setCardBack(pi < this.players.size() ? userService.getCardBackById(players.get(pi).getUserId()).getBackId() : 0) + .setCardBack(pi < rel_players.size() ? userService.getCardBackById(rel_players.get(pi).getUserId()).getBackId() : 0) .setEntity(entity) .build() ); @@ -414,86 +420,19 @@ public class GameRoom extends Thread implements IGameRoom { @Override public void createDeckEntities() { log.info("create Deck Entities"); - // sugar for debug with 1 player. Must be erased after debug. + this.players.forEach(this::generateDeck); + } + + private void generateDeck(RoomPlayerDTO p1) { PegasusGame.PowerHistory.Builder pw = PegasusGame.PowerHistory.newBuilder(); - for(int i = 0; i < 26; i++, this.entity_id++) { - pw.addList(PegasusGame.PowerHistoryData.newBuilder() - .setFullEntity(PegasusGame.PowerHistoryEntity.newBuilder() - .setEntity(this.entity_id) - .setName("") - .addTags(PegasusGame.Tag.newBuilder() - .setName(GameTag.ENTITY_ID.getValue()) - .setValue(this.entity_id) - ) - .addTags(PegasusGame.Tag.newBuilder() - .setName(GameTag.CONTROLLER.getValue()) - .setValue(1) - ) - .addTags(PegasusGame.Tag.newBuilder() - .setName(GameTag.ZONE.getValue()) - .setValue(TagZone.DECK.ordinal()) - ) - ) - ); - } + List rel_players = new ArrayList<>(Collections.singletonList(p1)); + players.stream().filter(p -> p.getUserId().longValue() != p.getUserId().longValue()).forEach(rel_players::add); - for(int i = 1; i <= 5; i++, this.entity_id++) { - pw.addList(PegasusGame.PowerHistoryData.newBuilder() - .setFullEntity(PegasusGame.PowerHistoryEntity.newBuilder() - .setEntity(this.entity_id) - .setName("") - .addTags(PegasusGame.Tag.newBuilder() - .setName(GameTag.ENTITY_ID.getValue()) - .setValue(this.entity_id) - ) - .addTags(PegasusGame.Tag.newBuilder() - .setName(GameTag.CONTROLLER.getValue()) - .setValue(1) - ) - .addTags(PegasusGame.Tag.newBuilder() - .setName(GameTag.ZONE_POSITION.getValue()) - .setValue(i) - ) - .addTags(PegasusGame.Tag.newBuilder() - .setName(GameTag.ZONE.getValue()) - .setValue(TagZone.HAND.ordinal()) - ) - ) - ); - } - - List ens = List.of( - card2Entity("TB_SPT_Boss").get(), - card2Entity("CS1h_001").get() - ); - //this.hero_p1 = this.entity_id; - for(int i = 0; i < 2; i++, this.entity_id++) { - pw.addList(PegasusGame.PowerHistoryData.newBuilder() - .setFullEntity(ens.get(i) - .setEntity(this.entity_id) - .addTags(PegasusGame.Tag.newBuilder() - .setName(GameTag.ENTITY_ID.getValue()) - .setValue(this.entity_id) - ) - .addTags(PegasusGame.Tag.newBuilder() - .setName(GameTag.CONTROLLER.getValue()) - .setValue(1) - ) - .addTags(PegasusGame.Tag.newBuilder() - .setName(GameTag.ZONE.getValue()) - .setValue(TagZone.PLAY.ordinal()) - ) - ) - ); - } - - // other player - for( RoomPlayerDTO player : this.players ) { + for( RoomPlayerDTO player : rel_players ) { int di = 0; for (int i = 0; i < 26; i++, this.entity_id++, di++) { PegasusGame.PowerHistoryEntity.Builder b = di < this.decks.get(player.getUserId()).getSize() ? this.decks.get(player.getUserId()).getCard(di) : PegasusGame.PowerHistoryEntity.newBuilder(); - log.info("bBuilder: {}", b.getName()); pw.addList(PegasusGame.PowerHistoryData.newBuilder() .setFullEntity(b .setEntity(this.entity_id) @@ -516,7 +455,6 @@ public class GameRoom extends Thread implements IGameRoom { for (int i = 1; i <= 3; i++, this.entity_id++, di++) { PegasusGame.PowerHistoryEntity.Builder b = di < this.decks.get(player.getUserId()).getSize() ? this.decks.get(player.getUserId()).getCard(di) : PegasusGame.PowerHistoryEntity.newBuilder(); - log.info("HAND: {}; {}; {}; {}", b, di < this.decks.get(player.getUserId()).getSize(), di, this.decks.get(player.getUserId()).getSize()); pw.addList(PegasusGame.PowerHistoryData.newBuilder() .setFullEntity(b .setEntity(this.entity_id) @@ -568,7 +506,7 @@ public class GameRoom extends Thread implements IGameRoom { this.entity_id++; } - this.broadcast(new PegasusPacket(19, 0, pw.build().toByteArray())); + this.send(p1.getUserId(), new PegasusPacket(19, 0, pw.build().toByteArray())); this.nextGlobalState(); } @@ -576,10 +514,16 @@ public class GameRoom extends Thread implements IGameRoom { @Override public void createPlayerHeroEntity() { log.info("Player hero entity"); + this.players.forEach(this::generateHeroes); + } + private void generateHeroes(RoomPlayerDTO p1) { PegasusGame.PowerHistory.Builder pw = PegasusGame.PowerHistory.newBuilder(); - for(RoomPlayerDTO player : players) { + List rel_players = new ArrayList<>(Collections.singletonList(p1)); + players.stream().filter(p -> p.getUserId().longValue() != p.getUserId().longValue()).forEach(rel_players::add); + + for(RoomPlayerDTO player : rel_players) { Optional deck = userService.getDecksForUser(player.getUserId()) .stream() .filter(d -> d.getId().longValue() == player.getDeckId().longValue()) @@ -646,7 +590,7 @@ public class GameRoom extends Thread implements IGameRoom { .setChoiceType(1) .setCountMin(0) .setCountMax(3) - .addAllEntities(decks.get(players.get(0).getUserId()) + .addAllEntities(decks.get(rel_players.get(0).getUserId()) .getHandCards() .stream() .map(PegasusGame.PowerHistoryEntity.Builder::getEntity) @@ -656,9 +600,9 @@ public class GameRoom extends Thread implements IGameRoom { .setPlayerId(2) .build(); - this.broadcast(new PegasusPacket( 17, 0, entityChoices.toByteArray())); + this.send(p1.getUserId(), new PegasusPacket( 17, 0, entityChoices.toByteArray())); - this.broadcast(new PegasusPacket(19, 0, pw.build().toByteArray())); + this.send(p1.getUserId(), new PegasusPacket(19, 0, pw.build().toByteArray())); this.entity_id++; @@ -689,6 +633,10 @@ public class GameRoom extends Thread implements IGameRoom { this.players.forEach(p -> this.outcomeQueue.add(new OutcomeGamePacket(p.getUserId(), packet))); } + private void send(Long playerId, PegasusPacket packet) { + this.outcomeQueue.add(new OutcomeGamePacket(playerId, packet)); + } + private void nextGlobalState() { this.globalState = GameState.next(this.globalState); } diff --git a/src/main/java/com/alterdekim/hearthhack/component/TcpConnection.java b/src/main/java/com/alterdekim/hearthhack/component/TcpConnection.java index d6b8f88..af91792 100644 --- a/src/main/java/com/alterdekim/hearthhack/component/TcpConnection.java +++ b/src/main/java/com/alterdekim/hearthhack/component/TcpConnection.java @@ -39,6 +39,9 @@ public class TcpConnection extends Thread { @Getter private final RoomService roomService; + @Getter + private final GamePool gamePool; + @Getter @Setter private Long userId; diff --git a/src/main/java/com/alterdekim/hearthhack/component/TcpServer.java b/src/main/java/com/alterdekim/hearthhack/component/TcpServer.java index 2b91ebe..e302373 100644 --- a/src/main/java/com/alterdekim/hearthhack/component/TcpServer.java +++ b/src/main/java/com/alterdekim/hearthhack/component/TcpServer.java @@ -40,6 +40,9 @@ public class TcpServer extends ReflectionLoader { @Autowired private RoomService roomService; + @Autowired + private GamePool gamePool; + @Scheduled(fixedDelay = 5000) private void start() { try { @@ -59,7 +62,7 @@ public class TcpServer extends ReflectionLoader { while(true) { SSLSocket s = (SSLSocket) serverSocket.accept(); - TcpConnection c = new TcpConnection(s, this.getParsers(), dbfConfig, userService, roomService); + TcpConnection c = new TcpConnection(s, this.getParsers(), dbfConfig, userService, roomService, gamePool); connections.add(c); c.start(); log.info("New Connection Established From {}", s.getInetAddress().toString()); diff --git a/src/main/java/com/alterdekim/hearthhack/component/interfaces/OnRoomFullCallback.java b/src/main/java/com/alterdekim/hearthhack/component/interfaces/OnRoomFullCallback.java new file mode 100644 index 0000000..3f6fc11 --- /dev/null +++ b/src/main/java/com/alterdekim/hearthhack/component/interfaces/OnRoomFullCallback.java @@ -0,0 +1,5 @@ +package com.alterdekim.hearthhack.component.interfaces; + +public interface OnRoomFullCallback { + void onRoomFull(); +} diff --git a/src/main/java/com/alterdekim/hearthhack/component/processor/GameMasterProcessor.java b/src/main/java/com/alterdekim/hearthhack/component/processor/GameMasterProcessor.java index ad9cf4b..2af82c6 100644 --- a/src/main/java/com/alterdekim/hearthhack/component/processor/GameMasterProcessor.java +++ b/src/main/java/com/alterdekim/hearthhack/component/processor/GameMasterProcessor.java @@ -2,14 +2,19 @@ package com.alterdekim.hearthhack.component.processor; import com.alterdekim.Protocol; import com.alterdekim.hearthhack.component.TcpConnection; +import com.alterdekim.hearthhack.component.interfaces.OnRoomFullCallback; import com.alterdekim.hearthhack.dto.RoomDTO; import com.alterdekim.hearthhack.util.BattleNetPacket; import com.alterdekim.hearthhack.util.GameType; import com.google.protobuf.ByteString; +import lombok.AllArgsConstructor; +import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import java.util.UUID; +import static com.alterdekim.hearthhack.component.GamePool.PLAYERS_COUNT; + @Slf4j public class GameMasterProcessor extends Processor { @@ -21,7 +26,7 @@ public class GameMasterProcessor extends Processor { // FindGameRequest FindGameResponse game_master // GameType Protocol.FindGameRequest gameRequest = Protocol.FindGameRequest.parseFrom(packet.getBody()); - log.info("FindGameRequest: {}", gameRequest); + //log.info("FindGameRequest: {}", gameRequest); Protocol.Attribute a = gameRequest.getProperties().getCreationAttributesList().stream() .filter(p -> p.hasName() && p.getName().equals("type")) .findFirst() @@ -62,8 +67,11 @@ public class GameMasterProcessor extends Processor { conn.send(new BattleNetPacket(header, notification.toByteArray())); - String pwd = UUID.randomUUID().toString(); - Long roomId = conn.getRoomService().createRoom(new RoomDTO(pwd)); // TODO: make 1 player rooms check. + final String uuid = UUID.randomUUID().toString(); + + Long roomId = conn.getRoomService().findRoomWithPlayer().orElse(conn.getRoomService().createRoom(new RoomDTO(uuid))); // TODO: make 1 player rooms check. + log.info("Got roomID (join/create): {}", roomId); + final String pwd = conn.getRoomService().findById(roomId).orElse(new RoomDTO(uuid)).getRoomPassword(); conn.getRoomService().joinRoom(roomId, conn.getUserId(), gameRequest.getPlayerList().get(0) .getAttributeList() @@ -75,97 +83,104 @@ public class GameMasterProcessor extends Processor { .getIntValue() ); // TODO: make 1 player rooms check. - Thread.sleep(1000L); - - Protocol.Notification n1 = Protocol.Notification.newBuilder() - .setType("G_RESULT") - .setSenderId(Protocol.EntityId.newBuilder() - .setLow(0) - .setHigh(144115188075855872L)) - .setTargetId(Protocol.EntityId.newBuilder() - .setLow(78330215L) - .setHigh(144115198130930503L)) - .addAttribute(Protocol.Attribute.newBuilder() - .setName("game_request_id") - .setValue( - Protocol.Variant.newBuilder() - .setUintValue(1338541484650062879L * 10L) - ) - ) - .addAttribute(Protocol.Attribute.newBuilder() - .setName("game_handle") - .setValue( - Protocol.Variant.newBuilder() - .setMessageValue( - Protocol.GameHandle.newBuilder() - .setFactoryId( (143637261465044426L * 100L) + 14L ) - .setGameId(Protocol.EntityId.newBuilder() - .setHigh(432345578572981998L) - .setLow((123678367967794400L * 100L) + 12L)) - .build() - .toByteString() - ) - ) - ) - .addAttribute(Protocol.Attribute.newBuilder() - .setName("connection_info") - .setValue( - Protocol.Variant.newBuilder() - .setMessageValue( - Protocol.ConnectInfo.newBuilder() - .setMemberId(Protocol.EntityId.newBuilder() - .setHigh(144115198130930503L) - .setLow(78330215L) + conn.getGamePool().getCallbacks().put(conn.getUserId(), new OnRoomFullCallback() { + @Override + public void onRoomFull() { + try { + Protocol.Notification n1 = Protocol.Notification.newBuilder() + .setType("G_RESULT") + .setSenderId(Protocol.EntityId.newBuilder() + .setLow(0) + .setHigh(144115188075855872L)) + .setTargetId(Protocol.EntityId.newBuilder() + .setLow(78330215L) + .setHigh(144115198130930503L)) + .addAttribute(Protocol.Attribute.newBuilder() + .setName("game_request_id") + .setValue( + Protocol.Variant.newBuilder() + .setUintValue(1338541484650062879L * 10L) + ) + ) + .addAttribute(Protocol.Attribute.newBuilder() + .setName("game_handle") + .setValue( + Protocol.Variant.newBuilder() + .setMessageValue( + Protocol.GameHandle.newBuilder() + .setFactoryId((143637261465044426L * 100L) + 14L) + .setGameId(Protocol.EntityId.newBuilder() + .setHigh(432345578572981998L) + .setLow((123678367967794400L * 100L) + 12L)) + .build() + .toByteString() ) - .setHost("192.168.0.10") - .setPort(3724) - .setToken(ByteString.copyFromUtf8(pwd)) // password - .addAttribute(Protocol.Attribute - .newBuilder() - .setName("version") - .setValue(Protocol.Variant.newBuilder().setStringValue("eiK2qv"))) - .addAttribute(Protocol.Attribute - .newBuilder() - .setName("game") - .setValue(Protocol.Variant.newBuilder().setIntValue(roomId))) // game_id - .addAttribute(Protocol.Attribute - .newBuilder() - .setName("player") - .setValue(Protocol.Variant.newBuilder().setIntValue(1L))) - .addAttribute(Protocol.Attribute - .newBuilder() - .setName("id") - .setValue(Protocol.Variant.newBuilder().setIntValue(conn.getUserId()))) - .addAttribute(Protocol.Attribute - .newBuilder() - .setName("resumable") - .setValue(Protocol.Variant.newBuilder().setBoolValue(true))) - .addAttribute(Protocol.Attribute - .newBuilder() - .setName("spectator_password") - .setValue(Protocol.Variant.newBuilder().setStringValue("oDipIf"))) - .build().toByteString() - ) - ) - ) - .addAttribute(Protocol.Attribute.newBuilder() - .setName("error") - .setValue( - Protocol.Variant.newBuilder() - .setUintValue(0) - ) - ).build(); + ) + ) + .addAttribute(Protocol.Attribute.newBuilder() + .setName("connection_info") + .setValue( + Protocol.Variant.newBuilder() + .setMessageValue( + Protocol.ConnectInfo.newBuilder() + .setMemberId(Protocol.EntityId.newBuilder() + .setHigh(144115198130930503L) + .setLow(78330215L) + ) + .setHost("192.168.0.10") + .setPort(3724) + .setToken(ByteString.copyFromUtf8(pwd)) // password + .addAttribute(Protocol.Attribute + .newBuilder() + .setName("version") + .setValue(Protocol.Variant.newBuilder().setStringValue("eiK2qv"))) + .addAttribute(Protocol.Attribute + .newBuilder() + .setName("game") + .setValue(Protocol.Variant.newBuilder().setIntValue(roomId))) // game_id + .addAttribute(Protocol.Attribute + .newBuilder() + .setName("player") + .setValue(Protocol.Variant.newBuilder().setIntValue(1L))) + .addAttribute(Protocol.Attribute + .newBuilder() + .setName("id") + .setValue(Protocol.Variant.newBuilder().setIntValue(conn.getUserId()))) + .addAttribute(Protocol.Attribute + .newBuilder() + .setName("resumable") + .setValue(Protocol.Variant.newBuilder().setBoolValue(true))) + .addAttribute(Protocol.Attribute + .newBuilder() + .setName("spectator_password") + .setValue(Protocol.Variant.newBuilder().setStringValue("oDipIf"))) + .build().toByteString() + ) + ) + ) + .addAttribute(Protocol.Attribute.newBuilder() + .setName("error") + .setValue( + Protocol.Variant.newBuilder() + .setUintValue(0) + ) + ).build(); - header = Protocol.Header.newBuilder() - .setServiceId(4) - .setMethodId(1) - .setSize(n1.getSerializedSize()) - .setToken(conn.nextToken()) - .setObjectId(0) - .setStatus(0) - .build(); + Protocol.Header header = Protocol.Header.newBuilder() + .setServiceId(4) + .setMethodId(1) + .setSize(n1.getSerializedSize()) + .setToken(conn.nextToken()) + .setObjectId(0) + .setStatus(0) + .build(); - conn.send(new BattleNetPacket(header, n1.toByteArray())); + conn.send(new BattleNetPacket(header, n1.toByteArray())); + } catch (Exception e) { + log.error("GameMasterCallback: {}", e.getMessage()); + } + } + }); } @Override diff --git a/src/main/java/com/alterdekim/hearthhack/service/RoomService.java b/src/main/java/com/alterdekim/hearthhack/service/RoomService.java index abb6a32..11410f2 100644 --- a/src/main/java/com/alterdekim/hearthhack/service/RoomService.java +++ b/src/main/java/com/alterdekim/hearthhack/service/RoomService.java @@ -3,6 +3,7 @@ package com.alterdekim.hearthhack.service; import com.alterdekim.hearthhack.dto.RoomDTO; import com.alterdekim.hearthhack.dto.RoomPlayerDTO; import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Service; import java.util.ArrayList; @@ -12,6 +13,9 @@ import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentMap; import java.util.stream.Collectors; +import static com.alterdekim.hearthhack.component.GamePool.PLAYERS_COUNT; + +@Slf4j @Service public class RoomService implements IService { @@ -56,4 +60,12 @@ public class RoomService implements IService { r.getPlayers().add(new RoomPlayerDTO(userId, deckId)); map.put(roomId, r); } + + public Optional findRoomWithPlayer() { + return this.map.values() + .stream() + .filter(r -> !r.getPlayers().isEmpty() && r.getPlayers().size() < PLAYERS_COUNT) + .map(RoomDTO::getId) + .findFirst(); + } }