mirror of
https://github.com/correl/mage.git
synced 2025-04-06 01:04:10 -09:00
* Game: fixed priority lost on rollback (example: game skips to next step instead current step after a rollback error);
* Game: added game logs on rollback error;
This commit is contained in:
parent
c8445c31a3
commit
1d60c2039b
4 changed files with 26 additions and 11 deletions
Mage/src/main/java/mage
|
@ -452,7 +452,7 @@ public interface Game extends MageItem, Serializable, Copyable<Game> {
|
|||
|
||||
int bookmarkState();
|
||||
|
||||
void restoreState(int bookmark, String context);
|
||||
GameState restoreState(int bookmark, String context);
|
||||
|
||||
void removeBookmark(int bookmark);
|
||||
|
||||
|
|
|
@ -846,9 +846,10 @@ public abstract class GameImpl implements Game {
|
|||
*
|
||||
* @param bookmark
|
||||
* @param context additional information for error message
|
||||
* @return current restored state (if all fine)
|
||||
*/
|
||||
@Override
|
||||
public void restoreState(int bookmark, String context) {
|
||||
public GameState restoreState(int bookmark, String context) {
|
||||
if (!simulation && !this.hasEnded()) { // if player left or game is over no undo is possible - this could lead to wrong winner
|
||||
if (bookmark != 0) {
|
||||
if (!savedStates.contains(bookmark - 1)) {
|
||||
|
@ -863,11 +864,12 @@ public abstract class GameImpl implements Game {
|
|||
if (restore != null) {
|
||||
state.restore(restore);
|
||||
playerList.setCurrent(state.getPlayerByOrderId());
|
||||
return state;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -1469,7 +1471,7 @@ public abstract class GameImpl implements Game {
|
|||
public void playPriority(UUID activePlayerId, boolean resuming) {
|
||||
int errorContinueCounter = 0;
|
||||
infiniteLoopCounter = 0;
|
||||
int bookmark = 0;
|
||||
int rollbackBookmark = 0;
|
||||
clearAllBookmarks();
|
||||
try {
|
||||
applyEffects();
|
||||
|
@ -1484,8 +1486,8 @@ public abstract class GameImpl implements Game {
|
|||
Player player;
|
||||
while (!isPaused() && !checkIfGameIsOver()) {
|
||||
try {
|
||||
if (bookmark == 0) {
|
||||
bookmark = bookmarkState();
|
||||
if (rollbackBookmark == 0) {
|
||||
rollbackBookmark = bookmarkState();
|
||||
}
|
||||
player = getPlayer(state.getPlayerList().get());
|
||||
state.setPriorityPlayerId(player.getId());
|
||||
|
@ -1542,12 +1544,22 @@ public abstract class GameImpl implements Game {
|
|||
logger.fatal(ex.getStackTrace());
|
||||
}
|
||||
this.fireErrorEvent("Game exception occurred: ", ex);
|
||||
restoreState(bookmark, "Game exception: " + ex.getMessage());
|
||||
bookmark = 0;
|
||||
|
||||
// rollback game to prev state
|
||||
GameState restoredState = restoreState(rollbackBookmark, "Game exception: " + ex.getMessage());
|
||||
rollbackBookmark = 0;
|
||||
|
||||
if (errorContinueCounter > 15) {
|
||||
throw new MageException("Iterated player priority after game exception too often, game ends! Last error:\n "
|
||||
+ ex.getMessage());
|
||||
}
|
||||
|
||||
if (restoredState != null) {
|
||||
this.informPlayers(String.format("Auto-restored to %s due game error: %s", restoredState, ex.getMessage()));
|
||||
} else {
|
||||
logger.error("Can't auto-restore to prev state.");
|
||||
}
|
||||
|
||||
Player activePlayer = this.getPlayer(getActivePlayerId());
|
||||
if (activePlayer != null && !activePlayer.isTestsMode()) {
|
||||
errorContinueCounter++;
|
||||
|
|
|
@ -25,6 +25,7 @@ import mage.filter.FilterCard;
|
|||
import mage.filter.FilterMana;
|
||||
import mage.filter.FilterPermanent;
|
||||
import mage.game.Game;
|
||||
import mage.game.GameState;
|
||||
import mage.game.Graveyard;
|
||||
import mage.game.Table;
|
||||
import mage.game.combat.CombatGroup;
|
||||
|
@ -541,11 +542,12 @@ public interface Player extends MageItem, Copyable<Player> {
|
|||
|
||||
void resetStoredBookmark(Game game);
|
||||
|
||||
default void restoreState(int bookmark, String text, Game game) {
|
||||
game.restoreState(bookmark, text);
|
||||
default GameState restoreState(int bookmark, String text, Game game) {
|
||||
GameState state = game.restoreState(bookmark, text);
|
||||
if (getStoredBookmark() >= bookmark) {
|
||||
resetStoredBookmark(game);
|
||||
}
|
||||
return state;
|
||||
}
|
||||
|
||||
void revealCards(Ability source, Cards cards, Game game);
|
||||
|
|
|
@ -294,13 +294,14 @@ public abstract class PlayerImpl implements Player, Serializable {
|
|||
this.human = player.isHuman();
|
||||
this.life = player.getLife();
|
||||
|
||||
this.passed = player.isPassed();
|
||||
|
||||
// Don't restore more global states. If restored they are probably cause for unintended draws (https://github.com/magefree/mage/issues/1205).
|
||||
// this.wins = player.hasWon();
|
||||
// this.loses = player.hasLost();
|
||||
// this.left = player.hasLeft();
|
||||
// this.quit = player.hasQuit();
|
||||
// Makes no sense to restore
|
||||
// this.passed = player.isPassed();
|
||||
// this.priorityTimeLeft = player.getPriorityTimeLeft();
|
||||
// this.idleTimeout = player.hasIdleTimeout();
|
||||
// this.timerTimeout = player.hasTimerTimeout();
|
||||
|
|
Loading…
Add table
Reference in a new issue