From d309005c47afe0e8ed54b5d8e48d2afcc4a9095b Mon Sep 17 00:00:00 2001 From: "marcins78@gmail.com" Date: Tue, 18 Oct 2011 16:24:20 +0000 Subject: [PATCH] Recording games. --- .../lotro/game/state/EventSerializer.java | 82 +++++++++++++++++++ .../gempukku/lotro/game/state/GameState.java | 71 +++++++++++++++- .../lotro/logic/timing/DefaultLotroGame.java | 2 + .../gempukku/lotro/server/ServerResource.java | 77 +---------------- 4 files changed, 154 insertions(+), 78 deletions(-) create mode 100644 gemp-lotr/gemp-lotr-logic/src/main/java/com/gempukku/lotro/game/state/EventSerializer.java diff --git a/gemp-lotr/gemp-lotr-logic/src/main/java/com/gempukku/lotro/game/state/EventSerializer.java b/gemp-lotr/gemp-lotr-logic/src/main/java/com/gempukku/lotro/game/state/EventSerializer.java new file mode 100644 index 000000000..26b3d3076 --- /dev/null +++ b/gemp-lotr/gemp-lotr-logic/src/main/java/com/gempukku/lotro/game/state/EventSerializer.java @@ -0,0 +1,82 @@ +package com.gempukku.lotro.game.state; + +import com.gempukku.lotro.common.Zone; +import com.gempukku.lotro.logic.timing.GameStats; +import org.w3c.dom.Document; +import org.w3c.dom.Element; +import org.w3c.dom.Node; + +import java.util.Map; + +public class EventSerializer { + public Node serializeEvent(Document doc, GameEvent gameEvent) { + Element eventElem = doc.createElement("gameEvent"); + eventElem.setAttribute("type", gameEvent.getType().name()); + if (gameEvent.getBlueprintId() != null) + eventElem.setAttribute("blueprintId", gameEvent.getBlueprintId()); + if (gameEvent.getCardId() != null) + eventElem.setAttribute("cardId", gameEvent.getCardId().toString()); + if (gameEvent.getIndex() != null) + eventElem.setAttribute("index", gameEvent.getIndex().toString()); + if (gameEvent.getControllerId() != null) + eventElem.setAttribute("controllerId", gameEvent.getControllerId()); + if (gameEvent.getParticipantId() != null) + eventElem.setAttribute("participantId", gameEvent.getParticipantId()); + if (gameEvent.getAllParticipantIds() != null) { + StringBuilder sb = new StringBuilder(); + boolean first = true; + for (String participantId : gameEvent.getAllParticipantIds()) { + if (!first) sb.append(","); + sb.append(participantId); + first = false; + } + eventElem.setAttribute("allParticipantIds", sb.toString()); + } + if (gameEvent.getPhase() != null) + eventElem.setAttribute("phase", gameEvent.getPhase().name()); + if (gameEvent.getTargetCardId() != null) + eventElem.setAttribute("targetCardId", gameEvent.getTargetCardId().toString()); + if (gameEvent.getZone() != null) + eventElem.setAttribute("zone", gameEvent.getZone().name()); + if (gameEvent.getToken() != null) + eventElem.setAttribute("token", gameEvent.getToken().name()); + if (gameEvent.getCount() != null) + eventElem.setAttribute("count", gameEvent.getCount().toString()); + if (gameEvent.getOtherCardIds() != null) { + StringBuilder sb = new StringBuilder(); + boolean first = true; + for (int cardId : gameEvent.getOtherCardIds()) { + if (!first) sb.append(","); + sb.append(cardId); + first = false; + } + eventElem.setAttribute("otherCardIds", sb.toString()); + } + if (gameEvent.getMessage() != null) + eventElem.setAttribute("message", gameEvent.getMessage()); + if (gameEvent.getGameStats() != null) { + GameStats gameStats = gameEvent.getGameStats(); + eventElem.setAttribute("fellowshipArchery", String.valueOf(gameStats.getFellowshipArchery())); + eventElem.setAttribute("shadowArchery", String.valueOf(gameStats.getShadowArchery())); + + eventElem.setAttribute("fellowshipStrength", String.valueOf(gameStats.getFellowshipSkirmishStrength())); + eventElem.setAttribute("shadowStrength", String.valueOf(gameStats.getShadowSkirmishStrength())); + + eventElem.setAttribute("moveLimit", String.valueOf(gameStats.getMoveLimit())); + eventElem.setAttribute("moveCount", String.valueOf(gameStats.getMoveCount())); + + for (Map.Entry> playerZoneSizes : gameStats.getZoneSizes().entrySet()) { + final Element playerZonesElem = doc.createElement("playerZones"); + + playerZonesElem.setAttribute("name", playerZoneSizes.getKey()); + + for (Map.Entry zoneSizes : playerZoneSizes.getValue().entrySet()) + playerZonesElem.setAttribute(zoneSizes.getKey().name(), zoneSizes.getValue().toString()); + + eventElem.appendChild(playerZonesElem); + } + } + + return eventElem; + } +} diff --git a/gemp-lotr/gemp-lotr-logic/src/main/java/com/gempukku/lotro/game/state/GameState.java b/gemp-lotr/gemp-lotr-logic/src/main/java/com/gempukku/lotro/game/state/GameState.java index 695698518..e00bfa6f3 100644 --- a/gemp-lotr/gemp-lotr-logic/src/main/java/com/gempukku/lotro/game/state/GameState.java +++ b/gemp-lotr/gemp-lotr-logic/src/main/java/com/gempukku/lotro/game/state/GameState.java @@ -6,7 +6,18 @@ import com.gempukku.lotro.game.*; import com.gempukku.lotro.logic.PlayerOrder; import com.gempukku.lotro.logic.modifiers.ModifiersEnvironment; import com.gempukku.lotro.logic.timing.GameStats; +import org.w3c.dom.Document; +import org.w3c.dom.Element; +import javax.xml.parsers.DocumentBuilder; +import javax.xml.parsers.DocumentBuilderFactory; +import javax.xml.transform.Result; +import javax.xml.transform.Source; +import javax.xml.transform.Transformer; +import javax.xml.transform.TransformerFactory; +import javax.xml.transform.dom.DOMSource; +import javax.xml.transform.stream.StreamResult; +import java.io.File; import java.util.*; public class GameState { @@ -40,7 +51,7 @@ public class GameState { private List _assignments = new LinkedList(); private Skirmish _skirmish = null; - private Map _recordinglisteners = new HashMap(); + private Map _recordingListeners = new HashMap(); private Map _gameStateListeners = new HashMap(); private int _nextCardId = 0; @@ -65,12 +76,64 @@ public class GameState { } for (String playerId : playerOrder.getAllPlayers()) - _recordinglisteners.put(playerId, new GatheringParticipantCommunicationChannel(playerId)); + _recordingListeners.put(playerId, new GatheringParticipantCommunicationChannel(playerId)); for (String playerId : _gameStateListeners.keySet()) sendStateToPlayer(playerId); } + private String _possibleChars = "abcdefghijklmnopqrstuvwxyz0123456789"; + private int _charsCount = _possibleChars.length(); + + private String randomUid() { + int length = 10; + char[] chars = new char[length]; + Random rnd = new Random(); + for (int i = 0; i < 10; i++) + chars[i] = _possibleChars.charAt(rnd.nextInt(_charsCount)); + + return new String(chars); + } + + public void gameFinished() { + File gameReplayFolder = new File("i:\\gemp-lotr\\replay"); + gameReplayFolder.mkdirs(); + for (Map.Entry playerRecordings : _recordingListeners.entrySet()) { + String playerId = playerRecordings.getKey(); + File playerReplayFolder = new File(gameReplayFolder, playerId); + playerReplayFolder.mkdir(); + File replayFile; + do { + replayFile = new File(playerReplayFolder, randomUid() + ".xml"); + } while (replayFile.exists()); + + final List gameEvents = playerRecordings.getValue().consumeGameEvents(); + + try { + DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance(); + DocumentBuilder documentBuilder = documentBuilderFactory.newDocumentBuilder(); + Document doc = documentBuilder.newDocument(); + Element gameReplay = doc.createElement("gameReplay"); + EventSerializer serializer = new EventSerializer(); + for (GameEvent gameEvent : gameEvents) { + gameReplay.appendChild(serializer.serializeEvent(doc, gameEvent)); + } + + // Prepare the DOM document for writing + Source source = new DOMSource(doc); + + // Prepare the output file + Result result = new StreamResult(replayFile); + + // Write the DOM document to the file + Transformer xformer = TransformerFactory.newInstance().newTransformer(); + xformer.transform(source, result); + } catch (Exception exp) { + + } + } + } + private void addPlayerCards(String playerId, List cards, LotroCardBlueprintLibrary library) { for (String blueprintId : cards) { LotroCardBlueprint card = library.getLotroCardBlueprint(blueprintId); @@ -123,13 +186,13 @@ public class GameState { if (result != null) listeners.add(result); - listeners.add(_recordinglisteners.get(owner)); + listeners.add(_recordingListeners.get(owner)); return listeners; } private Collection getAllGameStateListeners() { Set allListeners = new HashSet(_gameStateListeners.values()); - allListeners.addAll(_recordinglisteners.values()); + allListeners.addAll(_recordingListeners.values()); return allListeners; } diff --git a/gemp-lotr/gemp-lotr-logic/src/main/java/com/gempukku/lotro/logic/timing/DefaultLotroGame.java b/gemp-lotr/gemp-lotr-logic/src/main/java/com/gempukku/lotro/logic/timing/DefaultLotroGame.java index 327916b13..4e6db41aa 100644 --- a/gemp-lotr/gemp-lotr-logic/src/main/java/com/gempukku/lotro/logic/timing/DefaultLotroGame.java +++ b/gemp-lotr/gemp-lotr-logic/src/main/java/com/gempukku/lotro/logic/timing/DefaultLotroGame.java @@ -107,6 +107,8 @@ public class DefaultLotroGame implements LotroGame { _winReason = reason; if (_gameState != null) _gameState.sendMessage(_winnerPlayerId + " is the winner due to: " + reason); + if (_gameState != null) + _gameState.gameFinished(); if (_gameResultListener != null) { Set losers = new HashSet(_allPlayers); losers.remove(_winnerPlayerId); diff --git a/gemp-lotr/gemp-lotr-web/src/main/java/com/gempukku/lotro/server/ServerResource.java b/gemp-lotr/gemp-lotr-web/src/main/java/com/gempukku/lotro/server/ServerResource.java index 4721f4048..ae0c3d96d 100644 --- a/gemp-lotr/gemp-lotr-web/src/main/java/com/gempukku/lotro/server/ServerResource.java +++ b/gemp-lotr/gemp-lotr-web/src/main/java/com/gempukku/lotro/server/ServerResource.java @@ -4,7 +4,6 @@ import com.gempukku.lotro.chat.ChatMessage; import com.gempukku.lotro.chat.ChatRoomMediator; import com.gempukku.lotro.chat.ChatServer; import com.gempukku.lotro.common.Side; -import com.gempukku.lotro.common.Zone; import com.gempukku.lotro.db.CollectionDAO; import com.gempukku.lotro.db.DbAccess; import com.gempukku.lotro.db.DeckDAO; @@ -12,13 +11,13 @@ import com.gempukku.lotro.db.PlayerDAO; import com.gempukku.lotro.db.vo.League; import com.gempukku.lotro.db.vo.Player; import com.gempukku.lotro.game.*; +import com.gempukku.lotro.game.state.EventSerializer; import com.gempukku.lotro.game.state.GameEvent; import com.gempukku.lotro.hall.HallException; import com.gempukku.lotro.hall.HallInfoVisitor; import com.gempukku.lotro.hall.HallServer; import com.gempukku.lotro.league.LeagueService; import com.gempukku.lotro.logic.decisions.AwaitingDecision; -import com.gempukku.lotro.logic.timing.GameStats; import com.gempukku.lotro.logic.vo.LotroDeck; import com.sun.jersey.spi.resource.Singleton; import org.apache.commons.lang.StringEscapeUtils; @@ -647,6 +646,7 @@ public class ServerResource { private class SerializationVisitor implements ParticipantCommunicationVisitor { private Document _doc; private Element _element; + private EventSerializer _eventSerializer = new EventSerializer(); private SerializationVisitor(Document doc, Element element) { _doc = doc; @@ -655,7 +655,7 @@ public class ServerResource { @Override public void visitGameEvent(GameEvent gameEvent) { - _element.appendChild(serializeEvent(_doc, gameEvent)); + _element.appendChild(_eventSerializer.serializeEvent(_doc, gameEvent)); } @Override @@ -705,77 +705,6 @@ public class ServerResource { return decisionElem; } - private Node serializeEvent(Document doc, GameEvent gameEvent) { - Element eventElem = doc.createElement("gameEvent"); - eventElem.setAttribute("type", gameEvent.getType().name()); - if (gameEvent.getBlueprintId() != null) - eventElem.setAttribute("blueprintId", gameEvent.getBlueprintId()); - if (gameEvent.getCardId() != null) - eventElem.setAttribute("cardId", gameEvent.getCardId().toString()); - if (gameEvent.getIndex() != null) - eventElem.setAttribute("index", gameEvent.getIndex().toString()); - if (gameEvent.getControllerId() != null) - eventElem.setAttribute("controllerId", gameEvent.getControllerId()); - if (gameEvent.getParticipantId() != null) - eventElem.setAttribute("participantId", gameEvent.getParticipantId()); - if (gameEvent.getAllParticipantIds() != null) { - StringBuilder sb = new StringBuilder(); - boolean first = true; - for (String participantId : gameEvent.getAllParticipantIds()) { - if (!first) sb.append(","); - sb.append(participantId); - first = false; - } - eventElem.setAttribute("allParticipantIds", sb.toString()); - } - if (gameEvent.getPhase() != null) - eventElem.setAttribute("phase", gameEvent.getPhase().name()); - if (gameEvent.getTargetCardId() != null) - eventElem.setAttribute("targetCardId", gameEvent.getTargetCardId().toString()); - if (gameEvent.getZone() != null) - eventElem.setAttribute("zone", gameEvent.getZone().name()); - if (gameEvent.getToken() != null) - eventElem.setAttribute("token", gameEvent.getToken().name()); - if (gameEvent.getCount() != null) - eventElem.setAttribute("count", gameEvent.getCount().toString()); - if (gameEvent.getOtherCardIds() != null) { - StringBuilder sb = new StringBuilder(); - boolean first = true; - for (int cardId : gameEvent.getOtherCardIds()) { - if (!first) sb.append(","); - sb.append(cardId); - first = false; - } - eventElem.setAttribute("otherCardIds", sb.toString()); - } - if (gameEvent.getMessage() != null) - eventElem.setAttribute("message", gameEvent.getMessage()); - if (gameEvent.getGameStats() != null) { - GameStats gameStats = gameEvent.getGameStats(); - eventElem.setAttribute("fellowshipArchery", String.valueOf(gameStats.getFellowshipArchery())); - eventElem.setAttribute("shadowArchery", String.valueOf(gameStats.getShadowArchery())); - - eventElem.setAttribute("fellowshipStrength", String.valueOf(gameStats.getFellowshipSkirmishStrength())); - eventElem.setAttribute("shadowStrength", String.valueOf(gameStats.getShadowSkirmishStrength())); - - eventElem.setAttribute("moveLimit", String.valueOf(gameStats.getMoveLimit())); - eventElem.setAttribute("moveCount", String.valueOf(gameStats.getMoveCount())); - - for (Map.Entry> playerZoneSizes : gameStats.getZoneSizes().entrySet()) { - final Element playerZonesElem = doc.createElement("playerZones"); - - playerZonesElem.setAttribute("name", playerZoneSizes.getKey()); - - for (Map.Entry zoneSizes : playerZoneSizes.getValue().entrySet()) - playerZonesElem.setAttribute(zoneSizes.getKey().name(), zoneSizes.getValue().toString()); - - eventElem.appendChild(playerZonesElem); - } - } - - return eventElem; - } - private void logUser(HttpServletRequest request, String login) { request.getSession().setAttribute("logged", login); }