diff --git a/Mage.Server/src/main/java/mage/server/ChatSession.java b/Mage.Server/src/main/java/mage/server/ChatSession.java index 32bc16bb11..d75c43a14c 100644 --- a/Mage.Server/src/main/java/mage/server/ChatSession.java +++ b/Mage.Server/src/main/java/mage/server/ChatSession.java @@ -27,6 +27,9 @@ */ package mage.server; +import java.text.DateFormat; +import java.util.*; +import java.util.concurrent.ConcurrentHashMap; import mage.interfaces.callback.ClientCallback; import mage.interfaces.callback.ClientCallbackMethod; import mage.view.ChatMessage; @@ -35,10 +38,6 @@ import mage.view.ChatMessage.MessageType; import mage.view.ChatMessage.SoundToPlay; import org.apache.log4j.Logger; -import java.text.DateFormat; -import java.util.*; -import java.util.concurrent.ConcurrentHashMap; - /** * @author BetaSteward_at_googlemail.com */ @@ -78,7 +77,7 @@ public class ChatSession { } if (userId != null && clients.containsKey(userId)) { String userName = clients.get(userId); - if (reason != DisconnectReason.LostConnection) { // for lost connection the user will be reconnected or session expire so no remove of chat yet + if (reason != DisconnectReason.LostConnection) { // for lost connection the user will be reconnected or session expire so no removeUserFromAllTables of chat yet clients.remove(userId); logger.debug(userName + '(' + reason.toString() + ')' + " removed from chatId " + chatId); } diff --git a/Mage.Server/src/main/java/mage/server/MageServerImpl.java b/Mage.Server/src/main/java/mage/server/MageServerImpl.java index a2f346307b..463a5b9d7e 100644 --- a/Mage.Server/src/main/java/mage/server/MageServerImpl.java +++ b/Mage.Server/src/main/java/mage/server/MageServerImpl.java @@ -796,13 +796,21 @@ public class MageServerImpl implements MageServer { @Override public void quitMatch(final UUID gameId, final String sessionId) throws MageException { execute("quitMatch", sessionId, () -> { - Optional session = SessionManager.instance.getSession(sessionId); - if (!session.isPresent()) { - logger.error("Session not found : " + sessionId); - } else { - UUID userId = session.get().getUserId(); + try { + callExecutor.execute( + () -> { + Optional session = SessionManager.instance.getSession(sessionId); + if (!session.isPresent()) { + logger.error("Session not found : " + sessionId); + } else { + UUID userId = session.get().getUserId(); + GameManager.instance.quitMatch(gameId, userId); + } - GameManager.instance.quitMatch(gameId, userId); + } + ); + } catch (Exception ex) { + handleException(ex); } }); } @@ -810,33 +818,51 @@ public class MageServerImpl implements MageServer { @Override public void quitTournament(final UUID tournamentId, final String sessionId) throws MageException { execute("quitTournament", sessionId, () -> { - Optional session = SessionManager.instance.getSession(sessionId); - if (!session.isPresent()) { - logger.error("Session not found : " + sessionId); - } else { - UUID userId = session.get().getUserId(); + try { + callExecutor.execute( + () -> { + Optional session = SessionManager.instance.getSession(sessionId); + if (!session.isPresent()) { + logger.error("Session not found : " + sessionId); + } else { + UUID userId = session.get().getUserId(); - TournamentManager.instance.quit(tournamentId, userId); + TournamentManager.instance.quit(tournamentId, userId); + } + } + ); + } catch (Exception ex) { + handleException(ex); } }); } @Override + public void quitDraft(final UUID draftId, final String sessionId) throws MageException { execute("quitDraft", sessionId, () -> { - Optional session = SessionManager.instance.getSession(sessionId); - if (!session.isPresent()) { - logger.error("Session not found : " + sessionId); - } else { - UUID userId = session.get().getUserId(); - UUID tableId = DraftManager.instance.getControllerByDraftId(draftId).getTableId(); - Table table = TableManager.instance.getTable(tableId); - if (table.isTournament()) { - UUID tournamentId = table.getTournament().getId(); - TournamentManager.instance.quit(tournamentId, userId); - } + try { + callExecutor.execute( + () -> { + Optional session = SessionManager.instance.getSession(sessionId); + if (!session.isPresent()) { + logger.error("Session not found : " + sessionId); + } else { + UUID userId = session.get().getUserId(); + UUID tableId = DraftManager.instance.getControllerByDraftId(draftId).getTableId(); + Table table = TableManager.instance.getTable(tableId); + if (table.isTournament()) { + UUID tournamentId = table.getTournament().getId(); + TournamentManager.instance.quit(tournamentId, userId); + } + } + } + ); + } catch (Exception ex) { + handleException(ex); } - }); + } + ); } @Override @@ -1257,6 +1283,7 @@ public class MageServerImpl implements MageServer { @Override public List getMissingCardsData(List classNames) { return CardRepository.instance.getMissingCards(classNames); + } private static class MyActionWithNullNegativeResult extends ActionWithNullNegativeResult { diff --git a/Mage.Server/src/main/java/mage/server/Session.java b/Mage.Server/src/main/java/mage/server/Session.java index 9ffa412181..96d2a10858 100644 --- a/Mage.Server/src/main/java/mage/server/Session.java +++ b/Mage.Server/src/main/java/mage/server/Session.java @@ -356,7 +356,7 @@ public class Session { } else { logger.error("SESSION LOCK - kill: userId " + userId); } - UserManager.instance.removeUser(userId, reason); + UserManager.instance.removeUserFromAllTables(userId, reason); } catch (InterruptedException ex) { logger.error("SESSION LOCK - kill: userId " + userId, ex); } finally { diff --git a/Mage.Server/src/main/java/mage/server/TableController.java b/Mage.Server/src/main/java/mage/server/TableController.java index e56a427727..7e0130e644 100644 --- a/Mage.Server/src/main/java/mage/server/TableController.java +++ b/Mage.Server/src/main/java/mage/server/TableController.java @@ -511,7 +511,7 @@ public class TableController { if (this.userId != null && this.userId.equals(userId) // tourn. sub tables have no creator user && (table.getState() == TableState.WAITING || table.getState() == TableState.READY_TO_START)) { - // table not started yet and user is the owner, remove the table + // table not started yet and user is the owner, removeUserFromAllTables the table TableManager.instance.removeTable(table.getId()); } else { UUID playerId = userPlayerMap.get(userId); @@ -826,7 +826,7 @@ public class TableController { } user.showUserMessage("Match info", sb.toString()); } - // remove table from user - table manager holds table for display of finished matches + // removeUserFromAllTables table from user - table manager holds table for display of finished matches if (!table.isTournamentSubTable()) { user.removeTable(entry.getValue()); } @@ -913,7 +913,7 @@ public class TableController { return false; } } else { - // check if table creator is still a valid user, if not remove table + // check if table creator is still a valid user, if not removeUserFromAllTables table return UserManager.instance.getUser(userId).isPresent(); } } diff --git a/Mage.Server/src/main/java/mage/server/TableManager.java b/Mage.Server/src/main/java/mage/server/TableManager.java index 289a3a66cb..f068bbc904 100644 --- a/Mage.Server/src/main/java/mage/server/TableManager.java +++ b/Mage.Server/src/main/java/mage/server/TableManager.java @@ -161,7 +161,7 @@ public enum TableManager { } } - // remove user from all tournament sub tables + // removeUserFromAllTables user from all tournament sub tables public void userQuitTournamentSubTables(UUID userId) { for (TableController controller : controllers.values()) { if (controller.getTable() != null) { @@ -174,7 +174,7 @@ public enum TableManager { } } - // remove user from all sub tables of a tournament + // removeUserFromAllTables user from all sub tables of a tournament public void userQuitTournamentSubTables(UUID tournamentId, UUID userId) { for (TableController controller : controllers.values()) { if (controller.getTable().isTournamentSubTable() && controller.getTable().getTournament().getId().equals(tournamentId)) { @@ -386,8 +386,8 @@ public enum TableManager { for (Table table : tableCopy) { try { if (table.getState() != TableState.FINISHED - && ((System.currentTimeMillis() - table.getStartTime().getTime()) / 1000) > 30) { // remove only if table started longer than 30 seconds ago - // remove tables and games not valid anymore + && ((System.currentTimeMillis() - table.getStartTime().getTime()) / 1000) > 30) { // removeUserFromAllTables only if table started longer than 30 seconds ago + // removeUserFromAllTables tables and games not valid anymore logger.debug(table.getId() + " [" + table.getName() + "] " + formatter.format(table.getStartTime() == null ? table.getCreateTime() : table.getCreateTime()) + " (" + table.getState().toString() + ") " + (table.isTournament() ? "- Tournament" : "")); getController(table.getId()).ifPresent(tableController -> { if ((table.isTournament() && !tableController.isTournamentStillValid()) diff --git a/Mage.Server/src/main/java/mage/server/User.java b/Mage.Server/src/main/java/mage/server/User.java index 523a892671..a176a9bd04 100644 --- a/Mage.Server/src/main/java/mage/server/User.java +++ b/Mage.Server/src/main/java/mage/server/User.java @@ -437,7 +437,7 @@ public class User { sideboarding.remove(tableId); } - public void remove(DisconnectReason reason) { + public void removeUserFromAllTables(DisconnectReason reason) { logger.trace("REMOVE " + userName + " Draft sessions " + draftSessions.size()); for (DraftSession draftSession : draftSessions.values()) { draftSession.setKilled(); diff --git a/Mage.Server/src/main/java/mage/server/UserManager.java b/Mage.Server/src/main/java/mage/server/UserManager.java index 5545ac825e..1c937776a7 100644 --- a/Mage.Server/src/main/java/mage/server/UserManager.java +++ b/Mage.Server/src/main/java/mage/server/UserManager.java @@ -112,6 +112,7 @@ public enum UserManager { if (user.isPresent()) { user.get().setSessionId(""); if (reason == DisconnectReason.Disconnected) { + removeUserFromAllTables(userId, reason); user.get().setUserState(UserState.Offline); } } @@ -130,19 +131,17 @@ public enum UserManager { return false; } - public void removeUser(final UUID userId, final DisconnectReason reason) { + public void removeUserFromAllTables(final UUID userId, final DisconnectReason reason) { if (userId != null) { getUser(userId).ifPresent(user -> USER_EXECUTOR.execute( () -> { try { LOGGER.info("USER REMOVE - " + user.getName() + " (" + reason.toString() + ") userId: " + userId + " [" + user.getGameInfo() + ']'); - user.remove(reason); + user.removeUserFromAllTables(reason); LOGGER.debug("USER REMOVE END - " + user.getName()); } catch (Exception ex) { handleException(ex); - } finally { - users.remove(userId); } } )); @@ -168,26 +167,39 @@ public enum UserManager { * */ private void checkExpired() { - Calendar calendarExp = Calendar.getInstance(); - calendarExp.add(Calendar.MINUTE, -3); - Calendar calendarRemove = Calendar.getInstance(); - calendarRemove.add(Calendar.MINUTE, -8); - List toRemove = new ArrayList<>(); - for (User user : users.values()) { - if (user.getUserState() != UserState.Offline - && user.isExpired(calendarExp.getTime())) { - if (user.getUserState() == UserState.Connected) { - user.lostConnection(); - disconnect(user.getId(), DisconnectReason.BecameInactive); + try { + Calendar calendarExp = Calendar.getInstance(); + calendarExp.add(Calendar.MINUTE, -3); + Calendar calendarRemove = Calendar.getInstance(); + calendarRemove.add(Calendar.MINUTE, -8); + List toRemove = new ArrayList<>(); + for (User user : users.values()) { + try { + if (user.getUserState() == UserState.Offline) { + if (user.isExpired(calendarRemove.getTime())) { + toRemove.add(user); + } + } else { + if (user.isExpired(calendarExp.getTime())) { + if (user.getUserState() == UserState.Connected) { + user.lostConnection(); + disconnect(user.getId(), DisconnectReason.BecameInactive); + } + removeUserFromAllTables(user.getId(), DisconnectReason.SessionExpired); + user.setUserState(UserState.Offline); + // Remove the user from all tournaments + + } + } + } catch (Exception ex) { + handleException(ex); } - user.setUserState(UserState.Offline); } - if (user.getUserState() == UserState.Offline && user.isExpired(calendarRemove.getTime())) { - toRemove.add(user); + for (User user : toRemove) { + users.remove(user.getId()); } - } - for (User user : toRemove) { - removeUser(user.getId(), DisconnectReason.SessionExpired); + } catch (Exception ex) { + handleException(ex); } } @@ -196,23 +208,27 @@ public enum UserManager { * */ private void updateUserInfoList() { - List newUserInfoList = new ArrayList<>(); - for (User user : UserManager.instance.getUsers()) { - newUserInfoList.add(new UserView( - user.getName(), - user.getHost(), - user.getSessionId(), - user.getConnectionTime(), - user.getLastActivity(), - user.getGameInfo(), - user.getUserState().toString(), - user.getChatLockedUntil(), - user.getClientVersion(), - user.getEmail(), - user.getUserIdStr() - )); + try { + List newUserInfoList = new ArrayList<>(); + for (User user : UserManager.instance.getUsers()) { + newUserInfoList.add(new UserView( + user.getName(), + user.getHost(), + user.getSessionId(), + user.getConnectionTime(), + user.getLastActivity(), + user.getGameInfo(), + user.getUserState().toString(), + user.getChatLockedUntil(), + user.getClientVersion(), + user.getEmail(), + user.getUserIdStr() + )); + } + userInfoList = newUserInfoList; + } catch (Exception ex) { + handleException(ex); } - userInfoList = newUserInfoList; } public List getUserInfoList() { diff --git a/Mage.Server/src/main/java/mage/server/game/GamesRoomImpl.java b/Mage.Server/src/main/java/mage/server/game/GamesRoomImpl.java index 100190f24a..f405558091 100644 --- a/Mage.Server/src/main/java/mage/server/game/GamesRoomImpl.java +++ b/Mage.Server/src/main/java/mage/server/game/GamesRoomImpl.java @@ -95,7 +95,7 @@ public class GamesRoomImpl extends RoomImpl implements GamesRoom, Serializable { } else if (matchList.size() < 50) { matchList.add(new MatchView(table)); } else { - // more since 50 matches finished since this match so remove it + // more since 50 matches finished since this match so removeUserFromAllTables it if (table.isTournament()) { TournamentManager.instance.removeTournament(table.getTournament().getId()); }