Adding MTG card database storage for use in MTG Trader.
This commit is contained in:
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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")) {
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user