From 350897b0e2683fd7e8f02575bcf4449fb0f7aac4 Mon Sep 17 00:00:00 2001 From: LevelX2 Date: Sun, 28 Sep 2014 15:45:35 +0200 Subject: [PATCH] Some fixes to player quits game handling. --- .../src/main/java/mage/server/User.java | 7 ++++- .../java/mage/server/game/GameController.java | 8 ++++- .../java/mage/server/game/GameSession.java | 30 ++++++++++++++++--- Mage/src/mage/players/PlayerImpl.java | 16 +++++----- 4 files changed, 47 insertions(+), 14 deletions(-) diff --git a/Mage.Server/src/main/java/mage/server/User.java b/Mage.Server/src/main/java/mage/server/User.java index e69e874afc9..163bf65d5dd 100644 --- a/Mage.Server/src/main/java/mage/server/User.java +++ b/Mage.Server/src/main/java/mage/server/User.java @@ -338,25 +338,30 @@ public class User { logger.debug("REMOVE " + getName() + " Game sessions: " + gameSessions.size() ); for (GameSession gameSession: gameSessions.values()) { logger.debug("-- kill game session of gameId: " + gameSession.getGameId() ); - gameSession.kill(); + gameSession.quitGame(); } + gameSessions.clear(); logger.debug("REMOVE " + getName() + " Draft sessions " + draftSessions.size()); for (DraftSession draftSession: draftSessions.values()) { draftSession.setKilled(); } + draftSessions.clear(); logger.debug("REMOVE " + getName() + " Tournament sessions " + tournamentSessions.size()); for (TournamentSession tournamentSession: tournamentSessions.values()) { tournamentSession.setKilled(); } + tournamentSessions.clear(); logger.debug("REMOVE " + getName() + " Tables " + tables.size()); for (Entry entry: tables.entrySet()) { logger.debug("-- leave tableId: " + entry.getValue().getId()); TableManager.getInstance().leaveTable(userId, entry.getValue().getId()); } + tables.clear(); logger.debug("REMOVE " + getName() + " watched Games " + watchedGames.size()); for (UUID gameId: watchedGames) { GameManager.getInstance().stopWatching(gameId, userId); } + watchedGames.clear(); logger.debug("REMOVE " + getName() + " Chats "); ChatManager.getInstance().removeUser(userId, reason); } diff --git a/Mage.Server/src/main/java/mage/server/game/GameController.java b/Mage.Server/src/main/java/mage/server/game/GameController.java index 581d9dbe042..ce0a7d3f8ff 100644 --- a/Mage.Server/src/main/java/mage/server/game/GameController.java +++ b/Mage.Server/src/main/java/mage/server/game/GameController.java @@ -379,7 +379,13 @@ public class GameController implements GameCallback { // } public void quitMatch(UUID userId) { - game.quit(getPlayerId(userId)); + UUID playerId = getPlayerId(userId); + if (playerId != null) { + GameSession gameSession = gameSessions.get(playerId); + if (gameSession != null) { + gameSession.quitGame(); + } + } } public void sendPlayerAction(PlayerAction playerAction, UUID userId) { diff --git a/Mage.Server/src/main/java/mage/server/game/GameSession.java b/Mage.Server/src/main/java/mage/server/game/GameSession.java index 7d6a4894ca1..a5e2fc8c9ee 100644 --- a/Mage.Server/src/main/java/mage/server/game/GameSession.java +++ b/Mage.Server/src/main/java/mage/server/game/GameSession.java @@ -44,6 +44,7 @@ import org.apache.log4j.Logger; import java.io.Serializable; import java.util.*; import java.util.Map.Entry; +import java.util.concurrent.ExecutorService; import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.ScheduledFuture; import java.util.concurrent.TimeUnit; @@ -62,6 +63,7 @@ public class GameSession extends GameWatcher { private ScheduledFuture futureTimeout; protected static ScheduledExecutorService timeoutExecutor = ThreadExecutor.getInstance().getTimeoutExecutor(); + private static final ExecutorService callExecutor = ThreadExecutor.getInstance().getCallExecutor(); private UserData userData; @@ -274,11 +276,31 @@ public class GameSession extends GameWatcher { return game.getId(); } - public void kill() { + public void quitGame() { if (game != null) { - if (game.getPlayer(playerId).isInGame()) { - logger.debug("QUIT game playerId: " + playerId + " gameId: " + game.getId()); - game.quit(playerId); + final Player player = game.getPlayer(playerId); + if (player != null && player.isInGame()) { + callExecutor.execute( + new Runnable() { + @Override + public void run() { + try { + player.quit(game); + } catch (Exception ex) { + if (ex != null) { + logger.fatal("Game session game quit exception " + (ex.getMessage() == null ? "null":ex.getMessage())); + if (ex.getCause() != null) { + logger.debug("- Cause: " + (ex.getCause().getMessage() == null ? "null":ex.getCause().getMessage())); + } + ex.printStackTrace(); + }else { + logger.fatal("Game session game quit exception - null"); + } + } + } + } + ); + } } else { logger.error("game object missing playerId: " + (playerId == null ? "[null]":playerId)); diff --git a/Mage/src/mage/players/PlayerImpl.java b/Mage/src/mage/players/PlayerImpl.java index 6121883143f..cea3de91cdd 100644 --- a/Mage/src/mage/players/PlayerImpl.java +++ b/Mage/src/mage/players/PlayerImpl.java @@ -169,7 +169,7 @@ public abstract class PlayerImpl implements Player, Serializable { protected int priorityTimeLeft = Integer.MAX_VALUE; - + // // conceded or connection lost game protected boolean left; // set if the player quits the complete match @@ -1599,30 +1599,30 @@ public abstract class PlayerImpl implements Player, Serializable { @Override public void quit(Game game) { - logger.debug(getName() + " quits the match."); - game.informPlayers(getName() + " quits the match."); quit = true; this.concede(game); + logger.debug(getName() + " quits the match."); + game.informPlayers(getName() + " quits the match."); } @Override public void timerTimeout(Game game) { - game.informPlayers(getName() + " has run out of time. Loosing the Match."); quit = true; timerTimeout = true; this.concede(game); + game.informPlayers(getName() + " has run out of time. Loosing the Match."); } @Override public void idleTimeout(Game game) { - game.informPlayers(new StringBuilder(getName()).append(" was idle for too long. Loosing the Match.").toString()); quit = true; idleTimeout = true; this.concede(game); + game.informPlayers(new StringBuilder(getName()).append(" was idle for too long. Loosing the Match.").toString()); } @Override - public void concede(Game game) { + public void concede(Game game) { logger.debug(this.getName() + (" concedes gameId:" +game.getId())); game.gameOver(playerId); logger.debug("Before lost " + this.getName()); @@ -1681,7 +1681,7 @@ public abstract class PlayerImpl implements Player, Serializable { if (!this.wins) { this.loses = true; game.fireEvent(GameEvent.getEvent(GameEvent.EventType.LOST, null, null, playerId)); - game.informPlayers(new StringBuilder(this.getName()).append(" has lost the game.").toString()); + game.informPlayers(this.getName()+ " has lost the game."); } else { logger.debug(this.getName() + " has already won - stop lost"); } @@ -1738,7 +1738,7 @@ public abstract class PlayerImpl implements Player, Serializable { } @Override public boolean isInGame() { - return !hasLost() && !hasWon() && !hasLeft(); + return !hasQuit() && !hasLost() && !hasWon() && !hasLeft(); } @Override