Initial Cardcast support. Hard-coded to pull the Reject Pack for testing.
WARNING: This disables the JVM's SSL certificate checking, and only allows 'api.cardcastgame.com' when checking hosts. The proper solution would be to ensure that the JVM's trust store will accept that certificate.
This commit is contained in:
parent
f5060113db
commit
8638dcadd4
|
@ -33,6 +33,9 @@ import java.util.concurrent.TimeUnit;
|
||||||
import javax.servlet.ServletContext;
|
import javax.servlet.ServletContext;
|
||||||
import javax.servlet.ServletContextEvent;
|
import javax.servlet.ServletContextEvent;
|
||||||
|
|
||||||
|
import net.socialgamer.cah.cardcast.CardcastModule;
|
||||||
|
import net.socialgamer.cah.cardcast.CardcastService;
|
||||||
|
|
||||||
import org.apache.log4j.PropertyConfigurator;
|
import org.apache.log4j.PropertyConfigurator;
|
||||||
|
|
||||||
import com.google.inject.Guice;
|
import com.google.inject.Guice;
|
||||||
|
@ -108,6 +111,7 @@ public class StartupUtils extends GuiceServletContextListener {
|
||||||
|
|
||||||
reconfigureLogging(contextEvent.getServletContext());
|
reconfigureLogging(contextEvent.getServletContext());
|
||||||
reloadProperties(contextEvent.getServletContext());
|
reloadProperties(contextEvent.getServletContext());
|
||||||
|
CardcastService.hackSslVerifier();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void reloadProperties(final ServletContext context) {
|
public static void reloadProperties(final ServletContext context) {
|
||||||
|
@ -130,6 +134,6 @@ public class StartupUtils extends GuiceServletContextListener {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected Injector getInjector() {
|
protected Injector getInjector() {
|
||||||
return Guice.createInjector(new CahModule());
|
return Guice.createInjector(new CahModule(), new CardcastModule());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,44 @@
|
||||||
|
package net.socialgamer.cah.cardcast;
|
||||||
|
|
||||||
|
import net.socialgamer.cah.data.BlackCard;
|
||||||
|
|
||||||
|
|
||||||
|
public class CardcastBlackCard extends BlackCard {
|
||||||
|
|
||||||
|
private final int id;
|
||||||
|
private final String text;
|
||||||
|
private final int draw;
|
||||||
|
private final int pick;
|
||||||
|
|
||||||
|
public CardcastBlackCard(final int id, final String text, final int draw, final int pick) {
|
||||||
|
this.id = id;
|
||||||
|
this.text = text;
|
||||||
|
this.draw = draw;
|
||||||
|
this.pick = pick;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getId() {
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getText() {
|
||||||
|
return text;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getWatermark() {
|
||||||
|
return "CC";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getDraw() {
|
||||||
|
return draw;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getPick() {
|
||||||
|
return pick;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,61 @@
|
||||||
|
package net.socialgamer.cah.cardcast;
|
||||||
|
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
import net.socialgamer.cah.data.CardSet;
|
||||||
|
|
||||||
|
|
||||||
|
public class CardcastDeck extends CardSet {
|
||||||
|
private final String name;
|
||||||
|
private final String code;
|
||||||
|
private final String description;
|
||||||
|
private final Set<CardcastBlackCard> blackCards = new HashSet<CardcastBlackCard>();
|
||||||
|
private final Set<CardcastWhiteCard> whiteCards = new HashSet<CardcastWhiteCard>();
|
||||||
|
|
||||||
|
public CardcastDeck(final String name, final String code, final String description) {
|
||||||
|
this.name = name;
|
||||||
|
this.code = code;
|
||||||
|
this.description = description;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getId() {
|
||||||
|
return -Integer.parseInt(code, 36);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getName() {
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getDescription() {
|
||||||
|
return description;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isActive() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isBaseDeck() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getWeight() {
|
||||||
|
return Integer.MAX_VALUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Set<CardcastBlackCard> getBlackCards() {
|
||||||
|
return blackCards;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Set<CardcastWhiteCard> getWhiteCards() {
|
||||||
|
return whiteCards;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,33 @@
|
||||||
|
package net.socialgamer.cah.cardcast;
|
||||||
|
|
||||||
|
import java.lang.annotation.Retention;
|
||||||
|
import java.lang.annotation.RetentionPolicy;
|
||||||
|
import java.util.concurrent.atomic.AtomicInteger;
|
||||||
|
|
||||||
|
import net.socialgamer.cah.data.GameOptions;
|
||||||
|
|
||||||
|
import com.google.inject.AbstractModule;
|
||||||
|
import com.google.inject.BindingAnnotation;
|
||||||
|
import com.google.inject.Provides;
|
||||||
|
|
||||||
|
|
||||||
|
public class CardcastModule extends AbstractModule {
|
||||||
|
|
||||||
|
AtomicInteger cardId = new AtomicInteger(-(GameOptions.MAX_BLANK_CARD_LIMIT + 1));
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void configure() {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Provides
|
||||||
|
@CardcastCardId
|
||||||
|
Integer provideCardId() {
|
||||||
|
return cardId.decrementAndGet();
|
||||||
|
}
|
||||||
|
|
||||||
|
@BindingAnnotation
|
||||||
|
@Retention(RetentionPolicy.RUNTIME)
|
||||||
|
public @interface CardcastCardId {
|
||||||
|
/**/
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,271 @@
|
||||||
|
package net.socialgamer.cah.cardcast;
|
||||||
|
|
||||||
|
import java.io.BufferedReader;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.io.InputStreamReader;
|
||||||
|
import java.lang.ref.SoftReference;
|
||||||
|
import java.net.HttpURLConnection;
|
||||||
|
import java.net.URL;
|
||||||
|
import java.security.cert.X509Certificate;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
|
import javax.net.ssl.HostnameVerifier;
|
||||||
|
import javax.net.ssl.HttpsURLConnection;
|
||||||
|
import javax.net.ssl.SSLContext;
|
||||||
|
import javax.net.ssl.SSLSession;
|
||||||
|
import javax.net.ssl.TrustManager;
|
||||||
|
import javax.net.ssl.X509TrustManager;
|
||||||
|
|
||||||
|
import net.socialgamer.cah.cardcast.CardcastModule.CardcastCardId;
|
||||||
|
|
||||||
|
import org.apache.commons.lang3.StringUtils;
|
||||||
|
import org.apache.log4j.Logger;
|
||||||
|
import org.json.simple.JSONArray;
|
||||||
|
import org.json.simple.JSONObject;
|
||||||
|
import org.json.simple.JSONValue;
|
||||||
|
|
||||||
|
import com.google.inject.Inject;
|
||||||
|
import com.google.inject.Provider;
|
||||||
|
|
||||||
|
|
||||||
|
public class CardcastService {
|
||||||
|
private static final Logger LOG = Logger.getLogger(CardcastService.class);
|
||||||
|
|
||||||
|
private static final String HOSTNAME = "api.cardcastgame.com";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Base URL to the Cardcast API.
|
||||||
|
*/
|
||||||
|
private static final String BASE_URL = "https://" + HOSTNAME + "/v1/decks/";
|
||||||
|
/**
|
||||||
|
* URL to the Cardcast API for information about a card set. The only format replacement is the
|
||||||
|
* string deck ID.
|
||||||
|
*/
|
||||||
|
private static final String CARD_SET_INFO_URL_FORMAT_STRING = BASE_URL + "%s";
|
||||||
|
/**
|
||||||
|
* URL to the Cardcast API for cards in a card set. The only format replacement is the string
|
||||||
|
* deck ID.
|
||||||
|
*/
|
||||||
|
private static final String CARD_SET_CARDS_URL_FORMAT_STRING = CARD_SET_INFO_URL_FORMAT_STRING
|
||||||
|
+ "/cards";
|
||||||
|
|
||||||
|
private static final int GET_TIMEOUT = (int) TimeUnit.SECONDS.toMillis(3);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* How long to cache nonexistent card sets, or after an error occurs while querying for the card
|
||||||
|
* set. We need to do this to prevent DoS attacks.
|
||||||
|
*/
|
||||||
|
private static final long INVALID_SET_CACHE_LIFETIME = TimeUnit.SECONDS.toMillis(30);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* How long to cache valid card sets.
|
||||||
|
*/
|
||||||
|
private static final long VALID_SET_CACHE_LIFETIME = TimeUnit.MINUTES.toMillis(15);
|
||||||
|
|
||||||
|
private static final Map<String, SoftReference<CardcastCacheEntry>> cache = Collections
|
||||||
|
.synchronizedMap(new HashMap<String, SoftReference<CardcastCacheEntry>>());
|
||||||
|
|
||||||
|
private final Provider<Integer> cardIdProvider;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
public CardcastService(@CardcastCardId final Provider<Integer> cardIdProvider) {
|
||||||
|
this.cardIdProvider = cardIdProvider;
|
||||||
|
}
|
||||||
|
|
||||||
|
private class CardcastCacheEntry {
|
||||||
|
final long expires;
|
||||||
|
final CardcastDeck deck;
|
||||||
|
|
||||||
|
CardcastCacheEntry(final long cacheLifetime, final CardcastDeck deck) {
|
||||||
|
this.expires = System.currentTimeMillis() + cacheLifetime;
|
||||||
|
this.deck = deck;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private CardcastCacheEntry checkCache(final String setId) {
|
||||||
|
final SoftReference<CardcastCacheEntry> soft = cache.get(setId);
|
||||||
|
if (null == soft) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return soft.get();
|
||||||
|
}
|
||||||
|
|
||||||
|
public CardcastDeck loadSet(final String setId) {
|
||||||
|
final CardcastCacheEntry cached = checkCache(setId);
|
||||||
|
if (null != cached && cached.expires < System.currentTimeMillis()) {
|
||||||
|
return cached.deck;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
final String infoContent = getUrlContent(String
|
||||||
|
.format(CARD_SET_INFO_URL_FORMAT_STRING, setId));
|
||||||
|
if (null == infoContent) {
|
||||||
|
// failed to load
|
||||||
|
cacheMissingSet(setId);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
final JSONObject info = (JSONObject) JSONValue.parse(infoContent);
|
||||||
|
|
||||||
|
final String cardContent = getUrlContent(String.format(
|
||||||
|
CARD_SET_CARDS_URL_FORMAT_STRING, setId));
|
||||||
|
if (null == cardContent) {
|
||||||
|
// failed to load
|
||||||
|
cacheMissingSet(setId);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
final JSONObject cards = (JSONObject) JSONValue.parse(cardContent);
|
||||||
|
|
||||||
|
final String name = (String) info.get("name");
|
||||||
|
final String description = (String) info.get("description");
|
||||||
|
if (null == name || null == description || name.isEmpty()) {
|
||||||
|
// We require a name. Blank description is acceptable, but cannot be null.
|
||||||
|
cacheMissingSet(setId);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
final CardcastDeck deck = new CardcastDeck(name, setId, description);
|
||||||
|
|
||||||
|
// load up the cards
|
||||||
|
final JSONArray blacks = (JSONArray) cards.get("calls");
|
||||||
|
if (null != blacks) {
|
||||||
|
for (final Object black : blacks) {
|
||||||
|
final JSONArray texts = (JSONArray) ((JSONObject) black).get("text");
|
||||||
|
if (null != texts) {
|
||||||
|
// TODO this is going to need some work to look pretty.
|
||||||
|
final List<String> strs = new ArrayList<String>(texts.size());
|
||||||
|
for (final Object o : texts) {
|
||||||
|
strs.add((String) o);
|
||||||
|
}
|
||||||
|
final String text = StringUtils.join(strs, "____");
|
||||||
|
final int pick = strs.size() - 1;
|
||||||
|
final int draw = (pick >= 3 ? pick - 1 : 0);
|
||||||
|
final CardcastBlackCard card = new CardcastBlackCard(cardIdProvider.get(), text, draw,
|
||||||
|
pick);
|
||||||
|
deck.getBlackCards().add(card);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
final JSONArray whites = (JSONArray) cards.get("responses");
|
||||||
|
if (null != whites) {
|
||||||
|
for (final Object white : whites) {
|
||||||
|
final JSONArray texts = (JSONArray) ((JSONObject) white).get("text");
|
||||||
|
if (null != texts) {
|
||||||
|
// The white cards should only ever have one element in text, but let's be safe.
|
||||||
|
final List<String> strs = new ArrayList<String>(texts.size());
|
||||||
|
for (final Object o : texts) {
|
||||||
|
strs.add((String) o);
|
||||||
|
}
|
||||||
|
final String text = StringUtils.join(strs, "");
|
||||||
|
final CardcastWhiteCard card = new CardcastWhiteCard(cardIdProvider.get(), text);
|
||||||
|
deck.getWhiteCards().add(card);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
cacheSet(setId, deck);
|
||||||
|
return deck;
|
||||||
|
} catch (final Exception e) {
|
||||||
|
LOG.error(String.format("Unable to load deck %s from Cardcast", setId), e);
|
||||||
|
e.printStackTrace();
|
||||||
|
cacheMissingSet(setId);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void cachePut(final String setId, final CardcastDeck deck, final long timeout) {
|
||||||
|
LOG.info(String.format("Caching %s=%s for %d ms", setId, deck, timeout));
|
||||||
|
cache.put(setId, new SoftReference<CardcastCacheEntry>(new CardcastCacheEntry(timeout, deck)));
|
||||||
|
}
|
||||||
|
|
||||||
|
private void cacheSet(final String setId, final CardcastDeck deck) {
|
||||||
|
cachePut(setId, deck, VALID_SET_CACHE_LIFETIME);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void cacheMissingSet(final String setId) {
|
||||||
|
cachePut(setId, null, INVALID_SET_CACHE_LIFETIME);
|
||||||
|
}
|
||||||
|
|
||||||
|
private String getUrlContent(final String urlStr) throws IOException {
|
||||||
|
final URL url = new URL(urlStr);
|
||||||
|
final HttpURLConnection conn = (HttpURLConnection) url.openConnection();
|
||||||
|
conn.setDoInput(true);
|
||||||
|
conn.setDoOutput(false);
|
||||||
|
conn.setRequestMethod("GET");
|
||||||
|
conn.setInstanceFollowRedirects(true);
|
||||||
|
conn.setReadTimeout(GET_TIMEOUT);
|
||||||
|
conn.setConnectTimeout(GET_TIMEOUT);
|
||||||
|
|
||||||
|
final int code = conn.getResponseCode();
|
||||||
|
if (HttpURLConnection.HTTP_OK != code) {
|
||||||
|
LOG.error(String.format("Got HTTP response code %d from Cardcast for %s", code, urlStr));
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
final String contentType = conn.getContentType();
|
||||||
|
if (!"application/json".equals(contentType)) {
|
||||||
|
LOG.error(String.format("Got content-type %s from Cardcast for %s", contentType, urlStr));
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
final InputStream is = conn.getInputStream();
|
||||||
|
final InputStreamReader isr = new InputStreamReader(is);
|
||||||
|
final BufferedReader reader = new BufferedReader(isr);
|
||||||
|
final StringBuilder builder = new StringBuilder(4096);
|
||||||
|
String line;
|
||||||
|
while ((line = reader.readLine()) != null) {
|
||||||
|
builder.append(line);
|
||||||
|
builder.append('\n');
|
||||||
|
}
|
||||||
|
reader.close();
|
||||||
|
isr.close();
|
||||||
|
is.close();
|
||||||
|
|
||||||
|
return builder.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void hackSslVerifier() {
|
||||||
|
// FIXME: My JVM doesn't like the certificate. I should go add StartSSL's root certificate to
|
||||||
|
// its trust store, and document steps. For now, I'm going to disable SSL certificate checking.
|
||||||
|
|
||||||
|
// Create a trust manager that does not validate certificate chains
|
||||||
|
final TrustManager[] trustAllCerts = new TrustManager[] {
|
||||||
|
new X509TrustManager() {
|
||||||
|
@Override
|
||||||
|
public X509Certificate[] getAcceptedIssuers() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void checkClientTrusted(final X509Certificate[] certs, final String authType) {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void checkServerTrusted(final X509Certificate[] certs, final String authType) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
try {
|
||||||
|
final SSLContext sc = SSLContext.getInstance("SSL");
|
||||||
|
sc.init(null, trustAllCerts, new java.security.SecureRandom());
|
||||||
|
HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());
|
||||||
|
} catch (final Exception e) {
|
||||||
|
LOG.error("Unable to install trust-all security manager", e);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create host name verifier that only trusts cardcast
|
||||||
|
final HostnameVerifier allHostsValid = new HostnameVerifier() {
|
||||||
|
@Override
|
||||||
|
public boolean verify(final String hostname, final SSLSession session) {
|
||||||
|
return HOSTNAME.equals(hostname);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
HttpsURLConnection.setDefaultHostnameVerifier(allHostsValid);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,35 @@
|
||||||
|
package net.socialgamer.cah.cardcast;
|
||||||
|
|
||||||
|
import net.socialgamer.cah.data.WhiteCard;
|
||||||
|
|
||||||
|
|
||||||
|
public class CardcastWhiteCard extends WhiteCard {
|
||||||
|
|
||||||
|
private final int id;
|
||||||
|
private final String text;
|
||||||
|
|
||||||
|
public CardcastWhiteCard(final int id, final String text) {
|
||||||
|
this.id = id;
|
||||||
|
this.text = text;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getId() {
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getText() {
|
||||||
|
return text;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getWatermark() {
|
||||||
|
return "CC";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isWriteIn() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
|
@ -49,6 +49,7 @@ import net.socialgamer.cah.Constants.LongPollResponse;
|
||||||
import net.socialgamer.cah.Constants.ReturnableData;
|
import net.socialgamer.cah.Constants.ReturnableData;
|
||||||
import net.socialgamer.cah.Constants.WhiteCardData;
|
import net.socialgamer.cah.Constants.WhiteCardData;
|
||||||
import net.socialgamer.cah.SafeTimerTask;
|
import net.socialgamer.cah.SafeTimerTask;
|
||||||
|
import net.socialgamer.cah.cardcast.CardcastService;
|
||||||
import net.socialgamer.cah.data.GameManager.GameId;
|
import net.socialgamer.cah.data.GameManager.GameId;
|
||||||
import net.socialgamer.cah.data.QueuedMessage.MessageType;
|
import net.socialgamer.cah.data.QueuedMessage.MessageType;
|
||||||
|
|
||||||
|
@ -144,6 +145,7 @@ public class Game {
|
||||||
private final Object roundTimerLock = new Object();
|
private final Object roundTimerLock = new Object();
|
||||||
private volatile ScheduledFuture<?> lastScheduledFuture;
|
private volatile ScheduledFuture<?> lastScheduledFuture;
|
||||||
private final ScheduledThreadPoolExecutor globalTimer;
|
private final ScheduledThreadPoolExecutor globalTimer;
|
||||||
|
private final Provider<CardcastService> cardcastServiceProvider;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a new game.
|
* Create a new game.
|
||||||
|
@ -161,12 +163,14 @@ public class Game {
|
||||||
@Inject
|
@Inject
|
||||||
public Game(@GameId final Integer id, final ConnectedUsers connectedUsers,
|
public Game(@GameId final Integer id, final ConnectedUsers connectedUsers,
|
||||||
final GameManager gameManager, final ScheduledThreadPoolExecutor globalTimer,
|
final GameManager gameManager, final ScheduledThreadPoolExecutor globalTimer,
|
||||||
final Provider<Session> sessionProvider) {
|
final Provider<Session> sessionProvider,
|
||||||
|
final Provider<CardcastService> cardcastServiceProvider) {
|
||||||
this.id = id;
|
this.id = id;
|
||||||
this.connectedUsers = connectedUsers;
|
this.connectedUsers = connectedUsers;
|
||||||
this.gameManager = gameManager;
|
this.gameManager = gameManager;
|
||||||
this.globalTimer = globalTimer;
|
this.globalTimer = globalTimer;
|
||||||
this.sessionProvider = sessionProvider;
|
this.sessionProvider = sessionProvider;
|
||||||
|
this.cardcastServiceProvider = cardcastServiceProvider;
|
||||||
|
|
||||||
state = GameState.LOBBY;
|
state = GameState.LOBBY;
|
||||||
}
|
}
|
||||||
|
@ -648,6 +652,9 @@ public class Game {
|
||||||
final List<CardSet> cardSets = session.createQuery("from PyxCardSet where id in (:ids)")
|
final List<CardSet> cardSets = session.createQuery("from PyxCardSet where id in (:ids)")
|
||||||
.setParameterList("ids", options.getPyxCardSetIds()).list();
|
.setParameterList("ids", options.getPyxCardSetIds()).list();
|
||||||
|
|
||||||
|
// FIXME hardcode hack for testing GBTXA
|
||||||
|
cardSets.add(cardcastServiceProvider.get().loadSet("GBTXA"));
|
||||||
|
|
||||||
blackDeck = new BlackDeck(cardSets);
|
blackDeck = new BlackDeck(cardSets);
|
||||||
whiteDeck = new WhiteDeck(cardSets, options.blanksInDeck);
|
whiteDeck = new WhiteDeck(cardSets, options.blanksInDeck);
|
||||||
} catch (final Exception e) {
|
} catch (final Exception e) {
|
||||||
|
|
|
@ -40,6 +40,7 @@ import java.util.concurrent.ThreadFactory;
|
||||||
import java.util.concurrent.atomic.AtomicInteger;
|
import java.util.concurrent.atomic.AtomicInteger;
|
||||||
|
|
||||||
import net.socialgamer.cah.HibernateUtil;
|
import net.socialgamer.cah.HibernateUtil;
|
||||||
|
import net.socialgamer.cah.cardcast.CardcastModule.CardcastCardId;
|
||||||
import net.socialgamer.cah.data.GameManager.GameId;
|
import net.socialgamer.cah.data.GameManager.GameId;
|
||||||
import net.socialgamer.cah.data.GameManager.MaxGames;
|
import net.socialgamer.cah.data.GameManager.MaxGames;
|
||||||
import net.socialgamer.cah.data.QueuedMessage.MessageType;
|
import net.socialgamer.cah.data.QueuedMessage.MessageType;
|
||||||
|
@ -114,6 +115,13 @@ public class GameManagerTest {
|
||||||
Session provideSession() {
|
Session provideSession() {
|
||||||
return HibernateUtil.instance.sessionFactory.openSession();
|
return HibernateUtil.instance.sessionFactory.openSession();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("unused")
|
||||||
|
@Provides
|
||||||
|
@CardcastCardId
|
||||||
|
Integer provideCardcastCardId() {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
gameManager = injector.getInstance(GameManager.class);
|
gameManager = injector.getInstance(GameManager.class);
|
||||||
|
@ -135,11 +143,11 @@ public class GameManagerTest {
|
||||||
|
|
||||||
// fill it up with 3 games
|
// fill it up with 3 games
|
||||||
assertEquals(0, gameManager.get().intValue());
|
assertEquals(0, gameManager.get().intValue());
|
||||||
gameManager.getGames().put(0, new Game(0, cuMock, gameManager, timer, null));
|
gameManager.getGames().put(0, new Game(0, cuMock, gameManager, timer, null, null));
|
||||||
assertEquals(1, gameManager.get().intValue());
|
assertEquals(1, gameManager.get().intValue());
|
||||||
gameManager.getGames().put(1, new Game(1, cuMock, gameManager, timer, null));
|
gameManager.getGames().put(1, new Game(1, cuMock, gameManager, timer, null, null));
|
||||||
assertEquals(2, gameManager.get().intValue());
|
assertEquals(2, gameManager.get().intValue());
|
||||||
gameManager.getGames().put(2, new Game(2, cuMock, gameManager, timer, null));
|
gameManager.getGames().put(2, new Game(2, cuMock, gameManager, timer, null, null));
|
||||||
// make sure it says it can't make any more
|
// make sure it says it can't make any more
|
||||||
assertEquals(-1, gameManager.get().intValue());
|
assertEquals(-1, gameManager.get().intValue());
|
||||||
|
|
||||||
|
@ -147,13 +155,13 @@ public class GameManagerTest {
|
||||||
gameManager.destroyGame(1);
|
gameManager.destroyGame(1);
|
||||||
// make sure it re-uses that id
|
// make sure it re-uses that id
|
||||||
assertEquals(1, gameManager.get().intValue());
|
assertEquals(1, gameManager.get().intValue());
|
||||||
gameManager.getGames().put(1, new Game(1, cuMock, gameManager, timer, null));
|
gameManager.getGames().put(1, new Game(1, cuMock, gameManager, timer, null, null));
|
||||||
assertEquals(-1, gameManager.get().intValue());
|
assertEquals(-1, gameManager.get().intValue());
|
||||||
|
|
||||||
// remove game 1 out from under it, to make sure it'll fix itself
|
// remove game 1 out from under it, to make sure it'll fix itself
|
||||||
gameManager.getGames().remove(1);
|
gameManager.getGames().remove(1);
|
||||||
assertEquals(1, gameManager.get().intValue());
|
assertEquals(1, gameManager.get().intValue());
|
||||||
gameManager.getGames().put(1, new Game(1, cuMock, gameManager, timer, null));
|
gameManager.getGames().put(1, new Game(1, cuMock, gameManager, timer, null, null));
|
||||||
assertEquals(-1, gameManager.get().intValue());
|
assertEquals(-1, gameManager.get().intValue());
|
||||||
|
|
||||||
gameManager.destroyGame(2);
|
gameManager.destroyGame(2);
|
||||||
|
|
|
@ -61,7 +61,7 @@ public class GameTest {
|
||||||
public void setUp() throws Exception {
|
public void setUp() throws Exception {
|
||||||
cuMock = createMock(ConnectedUsers.class);
|
cuMock = createMock(ConnectedUsers.class);
|
||||||
gmMock = createMock(GameManager.class);
|
gmMock = createMock(GameManager.class);
|
||||||
game = new Game(0, cuMock, gmMock, timer, null);
|
game = new Game(0, cuMock, gmMock, timer, null, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
|
|
Loading…
Reference in New Issue