Migration of game replays to GZipped format.

This commit is contained in:
marcins78@gmail.com
2012-03-04 22:00:00 +00:00
parent 127d1ccacc
commit 0f49a73ae7
4 changed files with 107 additions and 42 deletions

View File

@@ -16,11 +16,11 @@ 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.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.*;
import java.util.*;
import java.util.zip.Deflater;
import java.util.zip.DeflaterOutputStream;
import java.util.zip.InflaterInputStream;
public class GameRecorder {
private static String _possibleChars = "abcdefghijklmnopqrstuvwxyz0123456789";
@@ -32,6 +32,46 @@ public class GameRecorder {
_gameHistoryDao = gameHistoryDao;
}
public void migrateReplays() {
System.out.println("Migrating replays");
try {
File gameReplayFolder = new File(ApplicationRoot.getRoot(), "replay");
for (File file : gameReplayFolder.listFiles()) {
System.out.println("Migrating user: " + file.getName());
for (File replayFile : file.listFiles()) {
if (replayFile.getName().endsWith(".xml")) {
if (replayFile.length() > 0)
zipFile(replayFile);
replayFile.delete();
}
}
}
} catch (IOException exp) {
System.out.println("Exception: " + exp.getMessage());
exp.printStackTrace();
}
}
private void zipFile(File replayFile) throws IOException {
OutputStream out = getRecordingWriteStream(replayFile.getParentFile().getName(), replayFile.getName().substring(0, replayFile.getName().length() - 4));
try {
// Associate a file input stream for the current file
FileInputStream in = new FileInputStream(replayFile);
try {
// Transfer bytes from the current file to the ZIP file
byte[] buffer = new byte[1024];
int len;
while ((len = in.read(buffer)) > 0)
out.write(buffer, 0, len);
} finally {
in.close();
}
} finally {
out.close();
}
}
private String randomUid() {
int length = 16;
char[] chars = new char[length];
@@ -46,7 +86,7 @@ public class GameRecorder {
final File file = getRecordingFile(playerId, gameId);
if (!file.exists() || !file.isFile())
return null;
return new FileInputStream(file);
return new InflaterInputStream(new FileInputStream(file));
}
public GameRecordingInProgress recordGame(LotroGameMediator lotroGame, final String formatName, final Map<String, String> deckNames) {
@@ -74,7 +114,15 @@ public class GameRecorder {
private File getRecordingFile(String playerId, String gameId) {
File gameReplayFolder = new File(ApplicationRoot.getRoot(), "replay");
File playerReplayFolder = new File(gameReplayFolder, playerId);
return new File(playerReplayFolder, gameId + ".xml");
return new File(playerReplayFolder, gameId + ".xml.gz");
}
private OutputStream getRecordingWriteStream(String playerId, String gameId) throws IOException {
File recordingFile = getRecordingFile(playerId, gameId);
recordingFile.getParentFile().mkdirs();
Deflater deflater = new Deflater(9);
return new DeflaterOutputStream(new FileOutputStream(recordingFile), deflater);
}
private Map<String, String> saveRecordedChannels(Map<String, GatheringParticipantCommunicationChannel> gameProgress) {
@@ -82,38 +130,35 @@ public class GameRecorder {
for (Map.Entry<String, GatheringParticipantCommunicationChannel> playerRecordings : gameProgress.entrySet()) {
String playerId = playerRecordings.getKey();
File replayFile;
String gameRecordingId;
do {
gameRecordingId = randomUid();
replayFile = getRecordingFile(playerId, gameRecordingId);
} while (replayFile.exists());
replayFile.getParentFile().mkdirs();
String gameRecordingId = getRecordingId(playerId);
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));
OutputStream replayStream = getRecordingWriteStream(playerId, gameRecordingId);
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));
}
doc.appendChild(gameReplay);
// Prepare the DOM document for writing
Source source = new DOMSource(doc);
// Prepare the output file
Result streamResult = new StreamResult(replayStream);
// Write the DOM document to the file
Transformer xformer = TransformerFactory.newInstance().newTransformer();
xformer.transform(source, streamResult);
} finally {
replayStream.close();
}
doc.appendChild(gameReplay);
// Prepare the DOM document for writing
Source source = new DOMSource(doc);
// Prepare the output file
Result streamResult = new StreamResult(replayFile);
// Write the DOM document to the file
Transformer xformer = TransformerFactory.newInstance().newTransformer();
xformer.transform(source, streamResult);
} catch (Exception exp) {
}
@@ -121,4 +166,14 @@ public class GameRecorder {
}
return result;
}
private String getRecordingId(String playerId) {
String result;
File recordingFile;
do {
result = randomUid();
recordingFile = getRecordingFile(playerId, result);
} while (recordingFile.exists());
return result;
}
}

View File

@@ -82,6 +82,10 @@ public class LotroServer extends AbstractServer {
_gameRecorder = new GameRecorder(_gameHistoryDao);
}
public void migrateReplays() {
_gameRecorder.migrateReplays();
}
public InputStream getGameRecording(String playerId, String gameId) throws IOException {
return _gameRecorder.getRecordedGame(playerId, gameId);
}

View File

@@ -5,10 +5,7 @@ import com.gempukku.lotro.db.DeckDAO;
import com.gempukku.lotro.db.LeagueDAO;
import com.gempukku.lotro.db.LeagueSerieDAO;
import com.gempukku.lotro.db.vo.CollectionType;
import com.gempukku.lotro.game.CardCollection;
import com.gempukku.lotro.game.DefaultCardCollection;
import com.gempukku.lotro.game.LotroCardBlueprintLibrary;
import com.gempukku.lotro.game.Player;
import com.gempukku.lotro.game.*;
import com.gempukku.lotro.hall.HallServer;
import com.gempukku.lotro.league.LeagueService;
import com.sun.jersey.spi.resource.Singleton;
@@ -39,6 +36,8 @@ public class AdminResource extends AbstractResource {
private LotroCardBlueprintLibrary _library;
@Context
private HallServer _hallServer;
@Context
private LotroServer _lotroServer;
@Path("/clearCache")
@GET
@@ -54,6 +53,17 @@ public class AdminResource extends AbstractResource {
return "OK";
}
@Path("/migrate")
@GET
public String migrate(
@Context HttpServletRequest request) throws Exception {
validateAdmin(request);
_lotroServer.migrateReplays();
return "OK";
}
@Path("/shutdown")
@GET
public String shutdown(

View File

@@ -50,10 +50,6 @@ public class ServerResource extends AbstractResource {
ApplicationRoot.setRoot(new File("/etc/gemp-lotr"));
else
ApplicationRoot.setRoot(new File("i:\\gemp-lotr"));
_logger.debug("starting resource");
_logger.debug("Resource created");
}
@Path("/login")