* Some changes to game handling to support replay in the future (not working yet).

This commit is contained in:
LevelX2 2014-02-07 16:07:15 +01:00
parent 9a15bdb933
commit e6f55d3b80
10 changed files with 55 additions and 37 deletions

View file

@ -345,13 +345,13 @@ public class TableController {
} }
} }
public boolean replayTable(UUID userId) { // public boolean replayTable(UUID userId) {
if (table.getState() != TableState.FINISHED) { // if (table.getState() != TableState.FINISHED) {
return false; // return false;
} // }
ReplayManager.getInstance().replayGame(table.getId(), userId); // ReplayManager.getInstance().replayGame(table.getId(), userId);
return true; // return true;
} // }
private Player createPlayer(String name, String playerType, int skill) { private Player createPlayer(String name, String playerType, int skill) {
Player player; Player player;

View file

@ -249,12 +249,12 @@ public class TableManager {
return false; return false;
} }
public boolean replayTable(UUID userId, UUID tableId) { // public boolean replayTable(UUID userId, UUID tableId) {
if (controllers.containsKey(tableId)) { // if (controllers.containsKey(tableId)) {
return controllers.get(tableId).replayTable(userId); // return controllers.get(tableId).replayTable(userId);
} // }
return false; // return false;
} // }
public void endGame(UUID tableId) { public void endGame(UUID tableId) {
if (controllers.containsKey(tableId)) { if (controllers.containsKey(tableId)) {

View file

@ -35,7 +35,6 @@ import java.util.Map.Entry;
import java.util.UUID; import java.util.UUID;
import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentHashMap;
import mage.cards.decks.Deck; import mage.cards.decks.Deck;
import mage.constants.TableState;
import mage.game.Table; import mage.game.Table;
import mage.interfaces.callback.ClientCallback; import mage.interfaces.callback.ClientCallback;
import mage.players.net.UserData; import mage.players.net.UserData;

View file

@ -111,6 +111,7 @@ public class GameController implements GameCallback {
this.userPlayerMap = userPlayerMap; this.userPlayerMap = userPlayerMap;
chatId = ChatManager.getInstance().createChatSession(); chatId = ChatManager.getInstance().createChatSession();
this.game = game; this.game = game;
this.game.setSaveGame(ConfigSettings.getInstance().isSaveGameActivated());
this.tableId = tableId; this.tableId = tableId;
this.choosingPlayerId = choosingPlayerId; this.choosingPlayerId = choosingPlayerId;
for (Player player: game.getPlayers().values()) { for (Player player: game.getPlayers().values()) {

View file

@ -73,5 +73,8 @@ public class ReplayManager {
replaySessions.get(gameId.toString() + userId.toString()).next(moves); replaySessions.get(gameId.toString() + userId.toString()).next(moves);
} }
public void endReplay(UUID gameId, UUID userId) {
replaySessions.remove(gameId.toString() + userId.toString());
}
} }

View file

@ -35,7 +35,6 @@ import mage.interfaces.callback.ClientCallback;
import mage.server.User; import mage.server.User;
import mage.server.UserManager; import mage.server.UserManager;
import mage.view.GameView; import mage.view.GameView;
import org.apache.log4j.Logger;
/** /**
* *
@ -43,8 +42,7 @@ import org.apache.log4j.Logger;
*/ */
public class ReplaySession implements GameCallback { public class ReplaySession implements GameCallback {
private static final Logger logger = Logger.getLogger(ReplaySession.class); private final GameReplay replay;
private GameReplay replay;
protected UUID userId; protected UUID userId;
ReplaySession(UUID gameId, UUID userId) { ReplaySession(UUID gameId, UUID userId) {
@ -85,6 +83,7 @@ public class ReplaySession implements GameCallback {
if (user != null) { if (user != null) {
user.fireCallback(new ClientCallback("replayDone", replay.getGame().getId(), result)); user.fireCallback(new ClientCallback("replayDone", replay.getGame().getId(), result));
} }
ReplayManager.getInstance().endReplay(replay.getGame().getId(), userId);
} }
private void updateGame(final GameState state, Game game) { private void updateGame(final GameState state, Game game) {

View file

@ -232,12 +232,14 @@ public interface Game extends MageItem, Serializable {
int doAction(MageAction action); int doAction(MageAction action);
//game transaction methods //game transaction methods
void saveState(); void saveState(boolean bookmark);
int bookmarkState(); int bookmarkState();
void restoreState(int bookmark); void restoreState(int bookmark);
void removeBookmark(int bookmark); void removeBookmark(int bookmark);
int getSavedStateSize(); int getSavedStateSize();
boolean isSaveGame();
void setSaveGame(boolean saveGame);
// game options // game options
void setGameOptions(GameOptions options); void setGameOptions(GameOptions options);

View file

@ -38,7 +38,6 @@ import java.util.HashMap;
import java.util.HashSet; import java.util.HashSet;
import java.util.Iterator; import java.util.Iterator;
import java.util.LinkedHashMap; import java.util.LinkedHashMap;
import java.util.LinkedList;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Map.Entry; import java.util.Map.Entry;
@ -177,15 +176,15 @@ public abstract class GameImpl<T extends GameImpl<T>> implements Game, Serializa
public static volatile int copyCount = 0; public static volatile int copyCount = 0;
public static volatile long copyTime = 0; public static volatile long copyTime = 0;
private transient LinkedList<MageAction> actions; // private final transient LinkedList<MageAction> actions;
private Player scorePlayer; private Player scorePlayer;
private int score = 0; // private int score = 0;
private Player losingPlayer; private Player losingPlayer;
private boolean stateCheckRequired = false; private boolean stateCheckRequired = false;
// used to indicate that currently applied replacement effects have to check for scope relevance (614.12 13/01/18) // used to indicate that currently applied replacement effects have to check for scope relevance (614.12 13/01/18)
private boolean scopeRelevant = false; private boolean scopeRelevant = false;
private boolean saveGame = false;
private int priorityTime; private int priorityTime;
@Override @Override
@ -197,7 +196,7 @@ public abstract class GameImpl<T extends GameImpl<T>> implements Game, Serializa
this.freeMulligans = freeMulligans; this.freeMulligans = freeMulligans;
this.attackOption = attackOption; this.attackOption = attackOption;
this.state = new GameState(); this.state = new GameState();
this.actions = new LinkedList<MageAction>(); // this.actions = new LinkedList<MageAction>();
} }
public GameImpl(final GameImpl<T> game) { public GameImpl(final GameImpl<T> game) {
@ -213,9 +212,7 @@ public abstract class GameImpl<T extends GameImpl<T>> implements Game, Serializa
this.freeMulligans = game.freeMulligans; this.freeMulligans = game.freeMulligans;
this.attackOption = game.attackOption; this.attackOption = game.attackOption;
this.state = game.state.copy(); this.state = game.state.copy();
// Issue 350 // Ai simulation modifies e.g. zoneChangeCounter so copy is needed if AI active
// this.gameCards = game.gameCards;
// issue #187 (else zoneChangeCounter modified by AI -> illegal target)
for (Map.Entry<UUID, Card> entry: game.gameCards.entrySet()) { for (Map.Entry<UUID, Card> entry: game.gameCards.entrySet()) {
this.gameCards.put(entry.getKey(), entry.getValue().copy()); this.gameCards.put(entry.getKey(), entry.getValue().copy());
} }
@ -227,11 +224,12 @@ public abstract class GameImpl<T extends GameImpl<T>> implements Game, Serializa
copyCount++; copyCount++;
copyTime += (System.currentTimeMillis() - t1); copyTime += (System.currentTimeMillis() - t1);
} }
this.actions = new LinkedList<MageAction>(); // this.actions = new LinkedList<MageAction>();
this.stateCheckRequired = game.stateCheckRequired; this.stateCheckRequired = game.stateCheckRequired;
this.scorePlayer = game.scorePlayer; this.scorePlayer = game.scorePlayer;
this.scopeRelevant = game.scopeRelevant; this.scopeRelevant = game.scopeRelevant;
this.priorityTime = game.priorityTime; this.priorityTime = game.priorityTime;
this.saveGame = game.saveGame;
} }
@Override @Override
@ -428,9 +426,11 @@ public abstract class GameImpl<T extends GameImpl<T>> implements Game, Serializa
} }
@Override @Override
public void saveState() { public void saveState(boolean bookmark) {
if (!simulation && gameStates != null) { if (!simulation && gameStates != null) {
gameStates.save(state); if (bookmark || saveGame) {
gameStates.save(state);
}
} }
} }
@ -479,7 +479,7 @@ public abstract class GameImpl<T extends GameImpl<T>> implements Game, Serializa
@Override @Override
public int bookmarkState() { public int bookmarkState() {
if (!simulation) { if (!simulation) {
saveState(); saveState(true);
if (logger.isDebugEnabled()) { if (logger.isDebugEnabled()) {
logger.debug("Bookmarking state: " + gameStates.getSize()); logger.debug("Bookmarking state: " + gameStates.getSize());
} }
@ -641,7 +641,7 @@ public abstract class GameImpl<T extends GameImpl<T>> implements Game, Serializa
if (gameOptions.stopOnTurn != null && gameOptions.stopAtStep == PhaseStep.UNTAP) { if (gameOptions.stopOnTurn != null && gameOptions.stopAtStep == PhaseStep.UNTAP) {
if (gameOptions.stopOnTurn.equals(state.getTurnNum())) { if (gameOptions.stopOnTurn.equals(state.getTurnNum())) {
winnerId = null; //DRAW winnerId = null; //DRAW
//saveState(); saveState(false);
return true; return true;
} }
} }
@ -662,7 +662,7 @@ public abstract class GameImpl<T extends GameImpl<T>> implements Game, Serializa
} }
fireStatusEvent(startMessage, false); fireStatusEvent(startMessage, false);
//saveState(); saveState(false);
//20091005 - 103.1 //20091005 - 103.1
if (!gameOptions.skipInitShuffling) { //don't shuffle in test mode for card injection on top of player's libraries if (!gameOptions.skipInitShuffling) { //don't shuffle in test mode for card injection on top of player's libraries
@ -719,7 +719,7 @@ public abstract class GameImpl<T extends GameImpl<T>> implements Game, Serializa
mulligan(player.getId()); mulligan(player.getId());
} }
fireInformEvent(player.getName() + " keeps hand"); fireInformEvent(player.getName() + " keeps hand");
//saveState(); saveState(false);
} }
for (UUID playerId : state.getPlayerList(startingPlayerId)) { for (UUID playerId : state.getPlayerList(startingPlayerId)) {
@ -806,6 +806,8 @@ public abstract class GameImpl<T extends GameImpl<T>> implements Game, Serializa
for (Player player: state.getPlayers().values()) { for (Player player: state.getPlayers().values()) {
player.abort(); player.abort();
} }
// allow gc
gameCards.clear();
} }
} }
@ -947,6 +949,7 @@ public abstract class GameImpl<T extends GameImpl<T>> implements Game, Serializa
} }
//resetLKI(); //resetLKI();
applyEffects(); applyEffects();
saveState(false);
if (isPaused() || isGameOver()) { if (isPaused() || isGameOver()) {
return; return;
} }
@ -2057,7 +2060,7 @@ public abstract class GameImpl<T extends GameImpl<T>> implements Game, Serializa
public int doAction(MageAction action) { public int doAction(MageAction action) {
//actions.add(action); //actions.add(action);
int value = action.doAction(this); int value = action.doAction(this);
score += action.getScore(scorePlayer); // score += action.getScore(scorePlayer);
return value; return value;
} }
@ -2128,6 +2131,17 @@ public abstract class GameImpl<T extends GameImpl<T>> implements Game, Serializa
return this.scopeRelevant; return this.scopeRelevant;
} }
@Override
public boolean isSaveGame() {
return saveGame;
}
@Override
public void setSaveGame(boolean saveGame) {
this.saveGame = saveGame;
}
public void setStartMessage(String startMessage) { public void setStartMessage(String startMessage) {
this.startMessage = startMessage; this.startMessage = startMessage;
} }

View file

@ -43,7 +43,7 @@ public class GameStates implements Serializable {
private static final transient Logger logger = Logger.getLogger(GameStates.class); private static final transient Logger logger = Logger.getLogger(GameStates.class);
// private List<byte[]> states = new LinkedList<byte[]>(); // private List<byte[]> states = new LinkedList<byte[]>();
private List<GameState> states = new LinkedList<GameState>(); private final List<GameState> states = new LinkedList<GameState>();
public void save(GameState gameState) { public void save(GameState gameState) {
// states.add(new Copier<GameState>().copyCompressed(gameState)); // states.add(new Copier<GameState>().copyCompressed(gameState));

View file

@ -173,7 +173,7 @@ public abstract class MatchImpl implements Match {
} }
protected void initGame(Game game) throws GameException { protected void initGame(Game game) throws GameException {
shufflePlayers(); shufflePlayers();
for (MatchPlayer matchPlayer: this.players) { for (MatchPlayer matchPlayer: this.players) {
if (!matchPlayer.hasQuit()) { if (!matchPlayer.hasQuit()) {
matchPlayer.getPlayer().init(game); matchPlayer.getPlayer().init(game);