Adding MTG card database storage for use in MTG Trader.

This commit is contained in:
MarcinSc
2015-12-01 16:12:38 -08:00
parent abf27f98fb
commit 42381668be
7 changed files with 171 additions and 9 deletions

View File

@@ -5,7 +5,12 @@ import com.gempukku.lotro.db.IpBanDAO;
import org.apache.commons.io.IOUtils;
import org.apache.log4j.Logger;
import org.jboss.netty.buffer.ChannelBuffers;
import org.jboss.netty.channel.*;
import org.jboss.netty.channel.ChannelFuture;
import org.jboss.netty.channel.ChannelFutureListener;
import org.jboss.netty.channel.ChannelHandlerContext;
import org.jboss.netty.channel.ExceptionEvent;
import org.jboss.netty.channel.MessageEvent;
import org.jboss.netty.channel.SimpleChannelUpstreamHandler;
import org.jboss.netty.handler.codec.http.DefaultHttpResponse;
import org.jboss.netty.handler.codec.http.HttpRequest;
import org.jboss.netty.handler.codec.http.HttpResponse;
@@ -17,7 +22,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.*;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.StringWriter;
import java.lang.reflect.Type;
import java.net.InetSocketAddress;
import java.text.SimpleDateFormat;
@@ -26,10 +35,16 @@ import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import static org.jboss.netty.handler.codec.http.HttpHeaders.Names.*;
import static org.jboss.netty.handler.codec.http.HttpHeaders.Names.CACHE_CONTROL;
import static org.jboss.netty.handler.codec.http.HttpHeaders.Names.CONTENT_LENGTH;
import static org.jboss.netty.handler.codec.http.HttpHeaders.Names.CONTENT_TYPE;
import static org.jboss.netty.handler.codec.http.HttpHeaders.Names.EXPIRES;
import static org.jboss.netty.handler.codec.http.HttpHeaders.Names.PRAGMA;
import static org.jboss.netty.handler.codec.http.HttpHeaders.is100ContinueExpected;
import static org.jboss.netty.handler.codec.http.HttpHeaders.isKeepAlive;
import static org.jboss.netty.handler.codec.http.HttpResponseStatus.*;
import static org.jboss.netty.handler.codec.http.HttpResponseStatus.BAD_REQUEST;
import static org.jboss.netty.handler.codec.http.HttpResponseStatus.CONTINUE;
import static org.jboss.netty.handler.codec.http.HttpResponseStatus.OK;
import static org.jboss.netty.handler.codec.http.HttpVersion.HTTP_1_1;
public class LotroHttpRequestHandler extends SimpleChannelUpstreamHandler {
@@ -110,9 +125,7 @@ public class LotroHttpRequestHandler extends SimpleChannelUpstreamHandler {
}
@Override
public void writeByteResponse(String contentType, byte[] bytes) {
Map<String, String> headers = new HashMap<String, String>();
headers.put(CONTENT_TYPE, contentType);
public void writeByteResponse(byte[] bytes, Map<String, String> headers) {
writeHttpByteResponse(requestInformation, request, bytes, headers, e);
}

View File

@@ -13,7 +13,7 @@ public interface ResponseWriter {
public void writeHtmlResponse(String html);
public void writeByteResponse(String contentType, byte[] bytes);
public void writeByteResponse(byte[] bytes, Map<String, String> headers);
public void writeXmlResponse(Document document);

View File

@@ -0,0 +1,49 @@
package com.gempukku.lotro.async.handler;
import com.gempukku.lotro.async.ResponseWriter;
import com.gempukku.mtg.MtgCardServer;
import org.jboss.netty.channel.MessageEvent;
import org.jboss.netty.handler.codec.http.HttpHeaders;
import org.jboss.netty.handler.codec.http.HttpRequest;
import java.lang.reflect.Type;
import java.util.HashMap;
import java.util.Map;
import static org.jboss.netty.handler.codec.http.HttpHeaders.Names.CONTENT_TYPE;
import static org.jboss.netty.handler.codec.http.HttpHeaders.Names.IF_NONE_MATCH;
public class MtgCardsRequestHandler implements UriRequestHandler {
private MtgCardServer _mtgCardServer;
public MtgCardsRequestHandler(Map<Type, Object> context) {
_mtgCardServer = (MtgCardServer) context.get(MtgCardServer.class);
}
@Override
public void handleRequest(String uri, HttpRequest request, Map<Type, Object> context, ResponseWriter responseWriter, MessageEvent e) throws Exception {
MtgCardServer.CardDatabaseHolder cardDatabaseHolder = _mtgCardServer.getCardDatabaseHolder();
if (cardDatabaseHolder == null || clientHasCurrentVersion(request, cardDatabaseHolder.getUpdateMarker())) {
responseWriter.writeError(304);
return;
}
Map<String, String> headers = new HashMap<String, String>();
headers.put(CONTENT_TYPE, "application/json; charset=UTF-8");
headers.put(HttpHeaders.Names.ETAG, cardDatabaseHolder.getUpdateMarker());
responseWriter.writeByteResponse(cardDatabaseHolder.getBytes(), headers);
}
private boolean clientHasCurrentVersion(HttpRequest request, String version) {
String ifNoneMatch = request.getHeader(IF_NONE_MATCH);
if (ifNoneMatch != null) {
String[] clientKnownVersions = ifNoneMatch.split(",");
for (String clientKnownVersion : clientKnownVersions) {
if (clientKnownVersion.trim().equals(version))
return true;
}
}
return false;
}
}

View File

@@ -10,8 +10,11 @@ import org.jboss.netty.handler.codec.http.HttpRequest;
import java.io.ByteArrayOutputStream;
import java.io.InputStream;
import java.lang.reflect.Type;
import java.util.HashMap;
import java.util.Map;
import static org.jboss.netty.handler.codec.http.HttpHeaders.Names.CONTENT_TYPE;
public class ReplayRequestHandler extends LotroServerRequestHandler implements UriRequestHandler {
private GameRecorder _gameRecorder;
@@ -49,7 +52,10 @@ public class ReplayRequestHandler extends LotroServerRequestHandler implements U
recordedGame.close();
}
responseWriter.writeByteResponse("application/html; charset=UTF-8", baos.toByteArray());
Map<String, String> headers = new HashMap<String, String>();
headers.put(CONTENT_TYPE, "application/html; charset=UTF-8");
responseWriter.writeByteResponse(baos.toByteArray(), headers);
} else {
responseWriter.writeError(404);
}

View File

@@ -30,6 +30,7 @@ public class RootUriRequestHandler implements UriRequestHandler {
private ServerStatsRequestHandler _serverStatsRequestHandler;
private PlayerStatsRequestHandler _playerStatsRequestHandler;
private TournamentRequestHandler _tournamentRequestHandler;
private MtgCardsRequestHandler _mtgCardsRequestHandler;
public RootUriRequestHandler(Map<Type, Object> context) {
_webRequestHandler = new WebRequestHandler(ApplicationConfiguration.getProperty("web.path"));
@@ -50,12 +51,15 @@ public class RootUriRequestHandler implements UriRequestHandler {
_serverStatsRequestHandler = new ServerStatsRequestHandler(context);
_playerStatsRequestHandler = new PlayerStatsRequestHandler(context);
_tournamentRequestHandler = new TournamentRequestHandler(context);
_mtgCardsRequestHandler = new MtgCardsRequestHandler(context);
}
@Override
public void handleRequest(String uri, HttpRequest request, Map<Type, Object> context, ResponseWriter responseWriter, MessageEvent e) throws Exception {
if (uri.startsWith(_webContextPath)) {
_webRequestHandler.handleRequest(uri.substring(_webContextPath.length()), request, context, responseWriter, e);
} else if (uri.equals("/mtg-cards/database.json")) {
_mtgCardsRequestHandler.handleRequest(uri, request, context, responseWriter, e);
} else if (uri.equals("/gemp-lotr")) {
responseWriter.writeError(301, Collections.singletonMap("Location", "/gemp-lotr/"));
} else if (uri.startsWith(_serverContextPath +"hall")) {

View File

@@ -32,9 +32,13 @@ import com.gempukku.lotro.tournament.TournamentMatchDAO;
import com.gempukku.lotro.tournament.TournamentPlayerDAO;
import com.gempukku.lotro.tournament.TournamentPrizeSchemeRegistry;
import com.gempukku.lotro.tournament.TournamentService;
import com.gempukku.mtg.MtgCardServer;
import java.lang.reflect.Type;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Map;
import java.util.TimeZone;
public class ServerBuilder {
public static void fillObjectMap(Map<Type, Object> objectMap) {
@@ -120,6 +124,17 @@ public class ServerBuilder {
pairingMechanismRegistry,
extract(objectMap, CardSets.class)
));
try {
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
sdf.setTimeZone(TimeZone.getTimeZone("EST"));
long someDownloadTime = sdf.parse("2015-01-01 04:25:00").getTime();
objectMap.put(MtgCardServer.class,
new MtgCardServer(someDownloadTime, 24L * 60 * 60 * 1000));
} catch (ParseException exp) {
}
}
private static <T> T extract(Map<Type, Object> objectMap, Class<T> clazz) {
@@ -130,12 +145,14 @@ public class ServerBuilder {
}
public static void constructObjects(Map<Type, Object> objectMap) {
extract(objectMap, MtgCardServer.class).startServer();
extract(objectMap, HallServer.class).startServer();
extract(objectMap, LotroServer.class).startServer();
extract(objectMap, ChatServer.class).startServer();
}
public static void destroyObjects(Map<Type, Object> objectMap) {
extract(objectMap, MtgCardServer.class).stopServer();
extract(objectMap, HallServer.class).stopServer();
extract(objectMap, LotroServer.class).stopServer();
extract(objectMap, ChatServer.class).stopServer();

View File

@@ -0,0 +1,73 @@
package com.gempukku.mtg;
import com.gempukku.lotro.AbstractServer;
import java.nio.charset.Charset;
public class MtgCardServer extends AbstractServer {
private volatile CardDatabaseHolder _cardDatabaseHolder;
private long _downloadEvery;
private long _nextStart;
public MtgCardServer(long someDownloadTime, long downloadEvery) {
_downloadEvery = downloadEvery;
long number = (System.currentTimeMillis() - someDownloadTime) / downloadEvery;
_nextStart = someDownloadTime + number * downloadEvery;
}
private void updateDatabase() {
Thread thr = new Thread(new UpdateDatabase());
thr.start();
}
public CardDatabaseHolder getCardDatabaseHolder() {
return _cardDatabaseHolder;
}
@Override
protected void cleanup() {
if (_nextStart < System.currentTimeMillis()) {
updateDatabase();
_nextStart += _downloadEvery;
}
}
public class CardDatabaseHolder {
private String _updateMarker;
private byte[] _bytes;
public CardDatabaseHolder(byte[] bytes, String updateMarker) {
_bytes = bytes;
_updateMarker = updateMarker;
}
public String getUpdateMarker() {
return _updateMarker;
}
public byte[] getBytes() {
return _bytes;
}
}
private byte[] getDatabase() {
String exampleString = "[" +
"{\"id\":\"sc\",\"name\":\"Snapcaster Mage\",\"info\":\"Innistrad\",\"midPrice\":5956}," +
"{\"id\":\"scf\",\"name\":\"Snapcaster Mage\",\"info\":\"Innistrad · Foil\",\"midPrice\":18040}," +
"{\"id\":\"ara\",\"name\":\"Ancestral Recall\",\"info\":\"Alpha\",\"midPrice\":500000}," +
"{\"id\":\"ara\",\"name\":\"Ancestral Recall\",\"info\":\"Beta\",\"midPrice\":300000}," +
"{\"id\":\"ara\",\"name\":\"Ancestral Recall\",\"info\":\"Unlimited\",\"midPrice\":50000}" +
"]";
return exampleString.getBytes(Charset.forName("UTF-8"));
}
public class UpdateDatabase implements Runnable {
public void run() {
String updateMarker = String.valueOf(System.currentTimeMillis());
_cardDatabaseHolder = new CardDatabaseHolder(getDatabase(), updateMarker);
}
}
}