Recording games.

This commit is contained in:
marcins78@gmail.com
2011-10-18 16:24:20 +00:00
parent 1cbc1400f3
commit d309005c47
4 changed files with 154 additions and 78 deletions

View File

@@ -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<String, Map<Zone, Integer>> playerZoneSizes : gameStats.getZoneSizes().entrySet()) {
final Element playerZonesElem = doc.createElement("playerZones");
playerZonesElem.setAttribute("name", playerZoneSizes.getKey());
for (Map.Entry<Zone, Integer> zoneSizes : playerZoneSizes.getValue().entrySet())
playerZonesElem.setAttribute(zoneSizes.getKey().name(), zoneSizes.getValue().toString());
eventElem.appendChild(playerZonesElem);
}
}
return eventElem;
}
}

View File

@@ -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<Assignment> _assignments = new LinkedList<Assignment>();
private Skirmish _skirmish = null;
private Map<String, GatheringParticipantCommunicationChannel> _recordinglisteners = new HashMap<String, GatheringParticipantCommunicationChannel>();
private Map<String, GatheringParticipantCommunicationChannel> _recordingListeners = new HashMap<String, GatheringParticipantCommunicationChannel>();
private Map<String, GameStateListener> _gameStateListeners = new HashMap<String, GameStateListener>();
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<String, GatheringParticipantCommunicationChannel> 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<GameEvent> 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<String> 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<GameStateListener> getAllGameStateListeners() {
Set<GameStateListener> allListeners = new HashSet<GameStateListener>(_gameStateListeners.values());
allListeners.addAll(_recordinglisteners.values());
allListeners.addAll(_recordingListeners.values());
return allListeners;
}

View File

@@ -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<String> losers = new HashSet<String>(_allPlayers);
losers.remove(_winnerPlayerId);

View File

@@ -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<String, Map<Zone, Integer>> playerZoneSizes : gameStats.getZoneSizes().entrySet()) {
final Element playerZonesElem = doc.createElement("playerZones");
playerZonesElem.setAttribute("name", playerZoneSizes.getKey());
for (Map.Entry<Zone, Integer> 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);
}