diff options
author | Joffrey BION <joffrey.bion@gmail.com> | 2016-12-11 14:03:28 +0100 |
---|---|---|
committer | Joffrey BION <joffrey.bion@gmail.com> | 2016-12-11 14:03:28 +0100 |
commit | 4beb63343f658a17b9ccd6236fced501e5d15dea (patch) | |
tree | f3a8f14a6b25ad82c958dd1192ced7a539ac1d4f /src/main/java/org/luxons | |
parent | Add special action skeleton to finish wonders data parsing (diff) | |
download | seven-wonders-4beb63343f658a17b9ccd6236fced501e5d15dea.tar.gz seven-wonders-4beb63343f658a17b9ccd6236fced501e5d15dea.tar.bz2 seven-wonders-4beb63343f658a17b9ccd6236fced501e5d15dea.zip |
Add WS experiment test page
This pages allows to test spring/STOMP config to see which messages are properly broadcasted to all users, which are just sent to the caller, and which are sent a specific user from the server.
Diffstat (limited to 'src/main/java/org/luxons')
12 files changed, 233 insertions, 115 deletions
diff --git a/src/main/java/org/luxons/sevenwonders/app/SevenWonders.java b/src/main/java/org/luxons/sevenwonders/SevenWonders.java index 48f10045..2c20c5d3 100644 --- a/src/main/java/org/luxons/sevenwonders/app/SevenWonders.java +++ b/src/main/java/org/luxons/sevenwonders/SevenWonders.java @@ -1,4 +1,4 @@ -package org.luxons.sevenwonders.app; +package org.luxons.sevenwonders; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; diff --git a/src/main/java/org/luxons/sevenwonders/app/WebSocketConfig.java b/src/main/java/org/luxons/sevenwonders/WebSocketConfig.java index e969c44e..bbe91c16 100644 --- a/src/main/java/org/luxons/sevenwonders/app/WebSocketConfig.java +++ b/src/main/java/org/luxons/sevenwonders/WebSocketConfig.java @@ -1,4 +1,4 @@ -package org.luxons.sevenwonders.app; +package org.luxons.sevenwonders; import org.springframework.context.annotation.Configuration; import org.springframework.messaging.simp.config.MessageBrokerRegistry; @@ -12,7 +12,11 @@ public class WebSocketConfig extends AbstractWebSocketMessageBrokerConfigurer { @Override public void configureMessageBroker(MessageBrokerRegistry config) { - config.enableSimpleBroker("/broadcast"); + // prefixes for all subscriptions + config.enableSimpleBroker("/broadcast", "/queue", "/topic"); + config.setUserDestinationPrefix("/user"); + + // prefix for all calls from clients config.setApplicationDestinationPrefixes("/app"); } diff --git a/src/main/java/org/luxons/sevenwonders/app/actions/JoinGameAction.java b/src/main/java/org/luxons/sevenwonders/actions/JoinGameAction.java index 66476427..a9a84d78 100644 --- a/src/main/java/org/luxons/sevenwonders/app/actions/JoinGameAction.java +++ b/src/main/java/org/luxons/sevenwonders/actions/JoinGameAction.java @@ -1,4 +1,4 @@ -package org.luxons.sevenwonders.app.actions; +package org.luxons.sevenwonders.actions; public class JoinGameAction { diff --git a/src/main/java/org/luxons/sevenwonders/app/LobbyController.java b/src/main/java/org/luxons/sevenwonders/controllers/LobbyController.java index a1358a58..f97c5fe2 100644 --- a/src/main/java/org/luxons/sevenwonders/app/LobbyController.java +++ b/src/main/java/org/luxons/sevenwonders/controllers/LobbyController.java @@ -1,26 +1,35 @@ -package org.luxons.sevenwonders.app; +package org.luxons.sevenwonders.controllers; import java.util.HashMap; import java.util.Map; -import org.luxons.sevenwonders.app.actions.JoinGameAction; +import org.luxons.sevenwonders.actions.JoinGameAction; import org.luxons.sevenwonders.game.Game; import org.luxons.sevenwonders.game.Player; import org.luxons.sevenwonders.game.Settings; -import org.luxons.sevenwonders.game.data.GameDataLoader; +import org.luxons.sevenwonders.game.data.GameDefinitionLoader; +import org.springframework.beans.factory.annotation.Autowired; import org.springframework.messaging.handler.annotation.MessageMapping; import org.springframework.messaging.handler.annotation.SendTo; import org.springframework.messaging.simp.SimpMessageHeaderAccessor; import org.springframework.stereotype.Controller; @Controller +//@MessageMapping("/lobby") public class LobbyController { + private final GameDefinitionLoader gameDefinitionLoader; + private long lastGameId = 0; private Map<String, Game> games = new HashMap<>(); - @MessageMapping("/lobby/create-game") + @Autowired + public LobbyController(GameDefinitionLoader gameDefinitionLoader) { + this.gameDefinitionLoader = gameDefinitionLoader; + } + + @MessageMapping("/create-game") @SendTo("/broadcast/games") public String createGame(SimpMessageHeaderAccessor headerAccessor) throws Exception { System.out.println("Received message: " + headerAccessor.getSessionId()); @@ -30,12 +39,12 @@ public class LobbyController { System.out.println("Creating game " + id); Settings settings = new Settings(); - Game game = new Game(settings, GameDataLoader.load(settings)); + Game game = new Game(settings, GameDefinitionLoader.load().create(settings)); games.put(id, game); return id; } - @MessageMapping("/lobby/join-game") + @MessageMapping("/join-game") @SendTo("/broadcast/players") public Player joinGame(SimpMessageHeaderAccessor headerAccessor, JoinGameAction joinAction) throws Exception { Thread.sleep(1000); // simulated delay diff --git a/src/main/java/org/luxons/sevenwonders/controllers/TestController.java b/src/main/java/org/luxons/sevenwonders/controllers/TestController.java new file mode 100644 index 00000000..06ebbdf3 --- /dev/null +++ b/src/main/java/org/luxons/sevenwonders/controllers/TestController.java @@ -0,0 +1,65 @@ +package org.luxons.sevenwonders.controllers; + +import org.springframework.messaging.handler.annotation.MessageMapping; +import org.springframework.messaging.handler.annotation.SendTo; +import org.springframework.messaging.simp.SimpMessageHeaderAccessor; +import org.springframework.messaging.simp.annotation.SendToUser; +import org.springframework.stereotype.Controller; + +@Controller +public class TestController { + + // sent to subscribers of /topic/test1 + @MessageMapping("/test1") + public String test1(SimpMessageHeaderAccessor headerAccessor) throws Exception { + System.out.println("No annotation - " + headerAccessor.getSessionId()); + + return "success test1"; + } + + // sent to subscribers of /broadcast/test2 + @MessageMapping("/test2") + @SendTo("/broadcast/test2") + public String test2(SimpMessageHeaderAccessor headerAccessor) throws Exception { + System.out.println("@SendTo /broadcast/test2 - " + headerAccessor.getSessionId()); + + return "success test2"; + } + + @MessageMapping("/test3") + @SendToUser("/broadcast/test3") + public String test3(SimpMessageHeaderAccessor headerAccessor) throws Exception { + System.out.println("@SendToUser /broadcast/test3 - " + headerAccessor.getSessionId()); + + return "success test3"; + } + + @MessageMapping("/test4") + @SendToUser("/test4") + public String test4(SimpMessageHeaderAccessor headerAccessor) throws Exception { + System.out.println("@SendToUser /test4 - " + headerAccessor.getSessionId()); + + return "success test4"; + } + + // sent to the caller user if he subscribed to /user/queue/test5 + // other subscribers of /user/queue/test5 are NOT notified + @MessageMapping("/test5") + @SendToUser + public String test5(SimpMessageHeaderAccessor headerAccessor) throws Exception { + System.out.println("@SendToUser (no path) - " + headerAccessor.getSessionId()); + + return "success test5"; + } + + // sent to the caller user if he subscribed to /user/queue/test5 + // other subscribers of /user/queue/test5 are NOT notified + @MessageMapping("/test6") + // TODO + public String test6(SimpMessageHeaderAccessor headerAccessor) throws Exception { + // TODO + System.out.println("@SendToUser (no path) - " + headerAccessor.getSessionId()); + + return "success test6"; + } +} diff --git a/src/main/java/org/luxons/sevenwonders/game/Decks.java b/src/main/java/org/luxons/sevenwonders/game/Decks.java new file mode 100644 index 00000000..72dff4e9 --- /dev/null +++ b/src/main/java/org/luxons/sevenwonders/game/Decks.java @@ -0,0 +1,21 @@ +package org.luxons.sevenwonders.game; + +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.luxons.sevenwonders.game.cards.Card; + +public class Decks { + + private Map<Integer, List<Card>> cardsPerAge = new HashMap<>(); + + public Decks(Map<Integer, List<Card>> cardsPerAge) { + this.cardsPerAge = cardsPerAge; + } + + public List<Card> getCards(int age) { + return cardsPerAge.getOrDefault(age, Collections.emptyList()); + } +} diff --git a/src/main/java/org/luxons/sevenwonders/game/Game.java b/src/main/java/org/luxons/sevenwonders/game/Game.java index 08c34578..ec2665fe 100644 --- a/src/main/java/org/luxons/sevenwonders/game/Game.java +++ b/src/main/java/org/luxons/sevenwonders/game/Game.java @@ -5,7 +5,6 @@ import java.util.Collections; import java.util.List; import org.luxons.sevenwonders.game.boards.Board; -import org.luxons.sevenwonders.game.data.GameData; import org.luxons.sevenwonders.game.wonders.Wonder; public class Game { @@ -14,9 +13,9 @@ public class Game { private final Settings settings; - private List<Player> players; + private final List<Player> players; - private List<Board> boards; + private final List<Board> boards; private State state = State.LOBBY; @@ -36,10 +35,17 @@ public class Game { } int playerId = players.size(); players.add(player); - boards.add(new Board(pickWonder(), settings)); return playerId; } + public synchronized void startGame() { + if (!hasEnoughPlayers()) { + throw new PlayerUnderflowException(); + } + state = State.PLAYING; + randomizeBoards(); + } + private boolean hasStarted() { return state == State.PLAYING; } @@ -48,28 +54,16 @@ public class Game { return players.size() >= data.getMaxPlayers(); } - private Wonder pickWonder() { - List<Wonder> availableWonders = new ArrayList<>(data.getWonders()); - removeAlreadyUsedWondersFrom(availableWonders); - Collections.shuffle(availableWonders); - return availableWonders.get(0); - } - - private void removeAlreadyUsedWondersFrom(List<Wonder> wonders) { - boards.stream().map(Board::getWonder).forEach(wonders::remove); - } - - public synchronized void startGame() { - if (!hasEnoughPlayers()) { - throw new PlayerUnderflowException(); - } - state = State.PLAYING; - } - private boolean hasEnoughPlayers() { return players.size() >= data.getMinPlayers(); } + private void randomizeBoards() { + List<Wonder> randomizedWonders = new ArrayList<>(data.getWonders()); + Collections.shuffle(randomizedWonders, settings.getRandom()); + randomizedWonders.stream().map(w -> new Board(w, settings)).forEach(boards::add); + } + public class GameAlreadyStartedException extends IllegalStateException { } diff --git a/src/main/java/org/luxons/sevenwonders/game/data/GameData.java b/src/main/java/org/luxons/sevenwonders/game/GameData.java index 9abf69c4..100389be 100644 --- a/src/main/java/org/luxons/sevenwonders/game/data/GameData.java +++ b/src/main/java/org/luxons/sevenwonders/game/GameData.java @@ -1,4 +1,4 @@ -package org.luxons.sevenwonders.game.data; +package org.luxons.sevenwonders.game; import java.util.ArrayList; import java.util.List; @@ -7,30 +7,27 @@ import org.luxons.sevenwonders.game.wonders.Wonder; public class GameData { - private int minPlayers = 3; + private final int minPlayers; - private int maxPlayers = 7; + private final int maxPlayers; private List<Wonder> wonders = new ArrayList<>(); private Decks decks; - public int getMinPlayers() { - return minPlayers; + public GameData(int minPlayers, int maxPlayers) { + this.minPlayers = minPlayers; + this.maxPlayers = maxPlayers; } - public void setMinPlayers(int minPlayers) { - this.minPlayers = minPlayers; + public int getMinPlayers() { + return minPlayers; } public int getMaxPlayers() { return maxPlayers; } - public void setMaxPlayers(int maxPlayers) { - this.maxPlayers = maxPlayers; - } - public List<Wonder> getWonders() { return wonders; } diff --git a/src/main/java/org/luxons/sevenwonders/game/data/Decks.java b/src/main/java/org/luxons/sevenwonders/game/data/Decks.java deleted file mode 100644 index ea12ee8f..00000000 --- a/src/main/java/org/luxons/sevenwonders/game/data/Decks.java +++ /dev/null @@ -1,57 +0,0 @@ -package org.luxons.sevenwonders.game.data; - -import java.util.ArrayList; -import java.util.Collections; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.stream.Collectors; - -import org.luxons.sevenwonders.game.Settings; -import org.luxons.sevenwonders.game.cards.Card; -import org.luxons.sevenwonders.game.data.definitions.CardDefinition; -import org.luxons.sevenwonders.game.data.definitions.DecksDefinition; - -public class Decks { - - private Map<Integer, List<Card>> cardsPerAge = new HashMap<>(); - - public Decks(DecksDefinition decksDefinition, Settings settings) { - cardsPerAge.put(1, prepareStandardDeck(decksDefinition.getAge1(), settings)); - cardsPerAge.put(2, prepareStandardDeck(decksDefinition.getAge2(), settings)); - cardsPerAge.put(3, prepareAge3Deck(decksDefinition, settings)); - } - - public List<Card> getCards(int age) { - return cardsPerAge.getOrDefault(age, Collections.emptyList()); - } - - private static List<Card> prepareStandardDeck(List<CardDefinition> defs, Settings settings) { - List<Card> cards = createDeck(defs, settings); - Collections.shuffle(cards, settings.getRandom()); - return cards; - } - - private static List<Card> prepareAge3Deck(DecksDefinition decksDefinition, Settings settings) { - List<Card> age3deck = createDeck(decksDefinition.getAge3(), settings); - age3deck.addAll(createGuildCards(decksDefinition.getGuildCards(), settings)); - Collections.shuffle(age3deck, settings.getRandom()); - return age3deck; - } - - private static List<Card> createDeck(List<CardDefinition> defs, Settings settings) { - List<Card> cards = new ArrayList<>(); - for (CardDefinition def : defs) { - for (int i = 0; i < def.getCountPerNbPlayer().get(settings.getNbPlayers()); i++) { - cards.add(def.create(settings)); - } - } - return cards; - } - - private static List<Card> createGuildCards(List<CardDefinition> defs, Settings settings) { - List<Card> guild = defs.stream().map((def) -> def.create(settings)).collect(Collectors.toList()); - Collections.shuffle(guild, settings.getRandom()); - return guild.subList(0, settings.getNbPlayers()); - } -} diff --git a/src/main/java/org/luxons/sevenwonders/game/data/GameDataLoader.java b/src/main/java/org/luxons/sevenwonders/game/data/GameDefinitionLoader.java index a4c14a7b..a2f39ed4 100644 --- a/src/main/java/org/luxons/sevenwonders/game/data/GameDataLoader.java +++ b/src/main/java/org/luxons/sevenwonders/game/data/GameDefinitionLoader.java @@ -5,15 +5,13 @@ import java.io.InputStream; import java.io.InputStreamReader; import java.io.Reader; import java.lang.reflect.Type; -import java.util.Arrays; import java.util.List; -import java.util.stream.Collectors; import com.google.gson.Gson; import com.google.gson.GsonBuilder; import com.google.gson.reflect.TypeToken; -import org.luxons.sevenwonders.game.Settings; import org.luxons.sevenwonders.game.data.definitions.DecksDefinition; +import org.luxons.sevenwonders.game.data.definitions.GameDefinition; import org.luxons.sevenwonders.game.data.definitions.WonderDefinition; import org.luxons.sevenwonders.game.data.serializers.NumericEffectSerializer; import org.luxons.sevenwonders.game.data.serializers.ProductionIncreaseSerializer; @@ -28,10 +26,12 @@ import org.luxons.sevenwonders.game.effects.RawPointsIncrease; import org.luxons.sevenwonders.game.effects.ScienceProgress; import org.luxons.sevenwonders.game.resources.ResourceType; import org.luxons.sevenwonders.game.resources.Resources; +import org.springframework.stereotype.Component; -public class GameDataLoader { +@Component +public class GameDefinitionLoader { - private static final String BASE_PACKAGE = GameDataLoader.class.getPackage().getName(); + private static final String BASE_PACKAGE = GameDefinitionLoader.class.getPackage().getName(); private static final String BASE_PACKAGE_PATH = '/' + BASE_PACKAGE.replace('.', '/'); @@ -39,15 +39,18 @@ public class GameDataLoader { private static final String WONDERS_FILE = "wonders.json"; - public static GameData load(Settings settings) { - GameData data = new GameData(); + private final GameDefinition gameDefinition; - WonderDefinition[] wonders = loadWonders(); - data.setWonders(Arrays.stream(wonders).map(def -> def.create(settings)).collect(Collectors.toList())); + public GameDefinitionLoader() { + gameDefinition = new GameDefinition(loadWonders(), loadDecks()); + } + + public GameDefinition getGameDefinition() { + return gameDefinition; + } - DecksDefinition decksDefinition = loadDecks(); - data.setDecks(decksDefinition.create(settings)); - return data; + public static GameDefinition load() { + return new GameDefinition(loadWonders(), loadDecks()); } private static WonderDefinition[] loadWonders() { @@ -59,7 +62,7 @@ public class GameDataLoader { } private static <T> T readJsonFile(String filename, Class<T> clazz) { - InputStream in = GameDataLoader.class.getResourceAsStream(BASE_PACKAGE_PATH + '/' + filename); + InputStream in = GameDefinitionLoader.class.getResourceAsStream(BASE_PACKAGE_PATH + '/' + filename); Reader reader = new BufferedReader(new InputStreamReader(in)); Gson gson = createGson(); return gson.fromJson(reader, clazz); diff --git a/src/main/java/org/luxons/sevenwonders/game/data/definitions/DecksDefinition.java b/src/main/java/org/luxons/sevenwonders/game/data/definitions/DecksDefinition.java index bfe89d12..aaa44475 100644 --- a/src/main/java/org/luxons/sevenwonders/game/data/definitions/DecksDefinition.java +++ b/src/main/java/org/luxons/sevenwonders/game/data/definitions/DecksDefinition.java @@ -1,9 +1,15 @@ package org.luxons.sevenwonders.game.data.definitions; +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashMap; import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; import org.luxons.sevenwonders.game.Settings; -import org.luxons.sevenwonders.game.data.Decks; +import org.luxons.sevenwonders.game.cards.Card; +import org.luxons.sevenwonders.game.Decks; public class DecksDefinition implements Definition<Decks> { @@ -33,6 +39,39 @@ public class DecksDefinition implements Definition<Decks> { @Override public Decks create(Settings settings) { - return new Decks(this, settings); + Map<Integer, List<Card>> cardsPerAge = new HashMap<>(); + cardsPerAge.put(1, prepareStandardDeck(age1, settings)); + cardsPerAge.put(2, prepareStandardDeck(age2, settings)); + cardsPerAge.put(3, prepareAge3Deck(settings)); + return new Decks(cardsPerAge); + } + + private static List<Card> prepareStandardDeck(List<CardDefinition> defs, Settings settings) { + List<Card> cards = createDeck(defs, settings); + Collections.shuffle(cards, settings.getRandom()); + return cards; + } + + private List<Card> prepareAge3Deck(Settings settings) { + List<Card> age3deck = createDeck(age3, settings); + age3deck.addAll(createGuildCards(guildCards, settings)); + Collections.shuffle(age3deck, settings.getRandom()); + return age3deck; + } + + private static List<Card> createDeck(List<CardDefinition> defs, Settings settings) { + List<Card> cards = new ArrayList<>(); + for (CardDefinition def : defs) { + for (int i = 0; i < def.getCountPerNbPlayer().get(settings.getNbPlayers()); i++) { + cards.add(def.create(settings)); + } + } + return cards; + } + + private static List<Card> createGuildCards(List<CardDefinition> defs, Settings settings) { + List<Card> guild = defs.stream().map((def) -> def.create(settings)).collect(Collectors.toList()); + Collections.shuffle(guild, settings.getRandom()); + return guild.subList(0, settings.getNbPlayers()); } } diff --git a/src/main/java/org/luxons/sevenwonders/game/data/definitions/GameDefinition.java b/src/main/java/org/luxons/sevenwonders/game/data/definitions/GameDefinition.java new file mode 100644 index 00000000..5947c547 --- /dev/null +++ b/src/main/java/org/luxons/sevenwonders/game/data/definitions/GameDefinition.java @@ -0,0 +1,43 @@ +package org.luxons.sevenwonders.game.data.definitions; + +import java.util.Arrays; +import java.util.List; +import java.util.stream.Collectors; + +import org.luxons.sevenwonders.game.Settings; +import org.luxons.sevenwonders.game.GameData; +import org.luxons.sevenwonders.game.wonders.Wonder; + +public class GameDefinition implements Definition<GameData> { + + /** + * This value is heavily dependent on the JSON data. Any change must be carefully thought through. + */ + private static final int MIN_PLAYERS = 3; + + /** + * This value is heavily dependent on the JSON data. Any change must be carefully thought through. + */ + private static final int MAX_PLAYERS = 7; + + private WonderDefinition[] wonders; + + private DecksDefinition decks; + + public GameDefinition(WonderDefinition[] wonders, DecksDefinition decks) { + this.wonders = wonders; + this.decks = decks; + } + + @Override + public GameData create(Settings settings) { + GameData data = new GameData(MIN_PLAYERS, MAX_PLAYERS); + data.setWonders(createWonders(settings)); + data.setDecks(decks.create(settings)); + return data; + } + + private List<Wonder> createWonders(Settings settings) { + return Arrays.stream(wonders).map(def -> def.create(settings)).collect(Collectors.toList()); + } +} |