diff --git a/Mage.Server/src/main/java/mage/server/ChatManager.java b/Mage.Server/src/main/java/mage/server/ChatManager.java index 3779a6f055d..c3707941a79 100644 --- a/Mage.Server/src/main/java/mage/server/ChatManager.java +++ b/Mage.Server/src/main/java/mage/server/ChatManager.java @@ -64,7 +64,7 @@ public class ChatManager { public void leaveChat(UUID chatId, UUID userId) { if (chatSessions.containsKey(chatId)) { - chatSessions.get(chatId).kill(userId, User.DisconnectReason.CleaningUp); + chatSessions.get(chatId).kill(userId, DisconnectReason.CleaningUp); } } @@ -158,7 +158,7 @@ public class ChatManager { } } - public void removeUser(UUID userId, User.DisconnectReason reason) { + public void removeUser(UUID userId, DisconnectReason reason) { Logger.getLogger(ChatManager.class).debug("ChatManager: Remove user start"); for (ChatSession chat: chatSessions.values()) { chat.kill(userId, reason); diff --git a/Mage.Server/src/main/java/mage/server/ChatSession.java b/Mage.Server/src/main/java/mage/server/ChatSession.java index 6f513d592b2..9f5bba441f5 100644 --- a/Mage.Server/src/main/java/mage/server/ChatSession.java +++ b/Mage.Server/src/main/java/mage/server/ChatSession.java @@ -65,7 +65,7 @@ public class ChatSession { } } - synchronized public void kill(UUID userId, User.DisconnectReason reason) { + synchronized public void kill(UUID userId, DisconnectReason reason) { if (userId != null && clients.containsKey(userId)) { String userName = clients.get(userId); logger.debug(userName + " leaves chat: " + chatId); @@ -133,7 +133,7 @@ public class ChatSession { user.fireCallback(new ClientCallback("chatMessage", chatId, new ChatMessage(username, msg, time, color, messageType, soundToPlay))); } else { - kill(userId, User.DisconnectReason.CleaningUp); + kill(userId, DisconnectReason.CleaningUp); } } } diff --git a/Mage.Server/src/main/java/mage/server/DisconnectReason.java b/Mage.Server/src/main/java/mage/server/DisconnectReason.java new file mode 100644 index 00000000000..39ab6a87f37 --- /dev/null +++ b/Mage.Server/src/main/java/mage/server/DisconnectReason.java @@ -0,0 +1,10 @@ +package mage.server; + +/** + * + * @author LevelX2 + */ + +public enum DisconnectReason { + LostConnection, Disconnected, CleaningUp, ConnectingOtherInstance, AdminDisconnect, SessionExpired, Undefined; +} diff --git a/Mage.Server/src/main/java/mage/server/Main.java b/Mage.Server/src/main/java/mage/server/Main.java index d99dd991938..d9ad4e4bf2e 100644 --- a/Mage.Server/src/main/java/mage/server/Main.java +++ b/Mage.Server/src/main/java/mage/server/Main.java @@ -187,11 +187,11 @@ public class Main { } sessionInfo.append(" at ").append(session.getHost()).append(" sessionId: ").append(session.getId()); if (throwable instanceof ClientDisconnectedException) { - SessionManager.getInstance().disconnect(client.getSessionId(), true); + SessionManager.getInstance().disconnect(client.getSessionId(), DisconnectReason.Disconnected); logger.debug("Client disconnected - " + sessionInfo); } else { - SessionManager.getInstance().disconnect(client.getSessionId(), false); + SessionManager.getInstance().disconnect(client.getSessionId(), DisconnectReason.LostConnection); logger.info("Connection to client lost - " + sessionInfo); } } @@ -259,7 +259,7 @@ public class Main { public void removeListener(InvokerCallbackHandler callbackHandler) { ServerInvokerCallbackHandler handler = (ServerInvokerCallbackHandler) callbackHandler; String sessionId = handler.getClientSessionId(); - SessionManager.getInstance().disconnect(sessionId, true); + SessionManager.getInstance().disconnect(sessionId, DisconnectReason.Disconnected); } } diff --git a/Mage.Server/src/main/java/mage/server/Session.java b/Mage.Server/src/main/java/mage/server/Session.java index e3e79b90991..067c71eddb3 100644 --- a/Mage.Server/src/main/java/mage/server/Session.java +++ b/Mage.Server/src/main/java/mage/server/Session.java @@ -106,7 +106,7 @@ public class Session { //throw new MageException("This machine is already connected"); //disconnect previous one logger.info("Disconnecting another user instance: " + userName); - UserManager.getInstance().disconnect(user.getId(), User.DisconnectReason.ConnectingOtherInstance); + UserManager.getInstance().disconnect(user.getId(), DisconnectReason.ConnectingOtherInstance); } } else { return new StringBuilder("User name ").append(userName).append(" already in use (or your IP address changed)").toString(); @@ -205,12 +205,12 @@ public class Session { sb.append(" sessionId: ").append(sessionId); logger.info(sb); } - UserManager.getInstance().disconnect(userId, User.DisconnectReason.LostConnection); + UserManager.getInstance().disconnect(userId, DisconnectReason.LostConnection); } - public void kill() { - logger.debug("session removed for user " + userId); - UserManager.getInstance().removeUser(userId, User.DisconnectReason.Disconnected); + public void kill(DisconnectReason reason) { + logger.debug("session removed for user " + userId + " - reason: " + reason.toString()); + UserManager.getInstance().removeUser(userId, reason); } synchronized void fireCallback(final ClientCallback call) { diff --git a/Mage.Server/src/main/java/mage/server/SessionManager.java b/Mage.Server/src/main/java/mage/server/SessionManager.java index 7066fb77f7b..982f0a1073b 100644 --- a/Mage.Server/src/main/java/mage/server/SessionManager.java +++ b/Mage.Server/src/main/java/mage/server/SessionManager.java @@ -27,6 +27,9 @@ */ package mage.server; +import java.util.HashMap; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; import mage.MageException; import mage.server.services.LogKeys; import mage.server.services.impl.LogServiceImpl; @@ -34,10 +37,6 @@ import mage.view.UserDataView; import org.apache.log4j.Logger; import org.jboss.remoting.callback.InvokerCallbackHandler; -import java.util.HashMap; -import java.util.Map; -import java.util.concurrent.ConcurrentHashMap; - /** * * @author BetaSteward_at_googlemail.com @@ -56,7 +55,13 @@ public class SessionManager { if (sessions == null || sessionId == null) { return null; } - return sessions.get(sessionId); + Session session = sessions.get(sessionId); + if (session != null && session.getUserId() != null && UserManager.getInstance().getUser(session.getUserId()) == null) { + logger.error("User for session " + sessionId + " with userId " + session.getUserId() + " is missing. Session removed. Cause for this still unclear."); + disconnect(sessionId, DisconnectReason.LostConnection); + return null; + } + return session; } public void createSession(String sessionId, InvokerCallbackHandler callbackHandler) { @@ -102,21 +107,31 @@ public class SessionManager { return false; } - public synchronized void disconnect(String sessionId, boolean voluntary) { - Session session = sessions.get(sessionId); - sessions.remove(sessionId); + public synchronized void disconnect(String sessionId, DisconnectReason reason) { + Session session = sessions.get(sessionId); if (session != null) { - if (voluntary) { - // disconnected - session.kill(); - LogServiceImpl.instance.log(LogKeys.KEY_SESSION_KILLED, sessionId); - } else { - // lost connection - session.userLostConnection(); - LogServiceImpl.instance.log(LogKeys.KEY_SESSION_DISCONNECTED, sessionId); + sessions.remove(sessionId); + switch (reason) { + case Disconnected: + session.kill(reason); + LogServiceImpl.instance.log(LogKeys.KEY_SESSION_KILLED, sessionId); + break; + case SessionExpired: + session.kill(reason); + LogServiceImpl.instance.log(LogKeys.KEY_SESSION_EXPIRED, sessionId); + break; + case AdminDisconnect: + session.kill(reason); + break; + case LostConnection: + session.userLostConnection(); + LogServiceImpl.instance.log(LogKeys.KEY_SESSION_DISCONNECTED, sessionId); + break; + default: + logger.error("endSession: unexpected reason " + reason.toString() + " - sessionId: "+ sessionId); } } else { - logger.info("disconnect: could not find session with id " + sessionId); + logger.error("endSession: could not find session with id " + sessionId); } } @@ -130,14 +145,14 @@ public class SessionManager { public void disconnectUser(String sessionId, String userSessionId) { if (isAdmin(sessionId)) { - disconnect(userSessionId, true); + disconnect(userSessionId, DisconnectReason.AdminDisconnect); LogServiceImpl.instance.log(LogKeys.KEY_SESSION_DISCONNECTED_BY_ADMIN, sessionId, userSessionId); } } public void endUserSession(String sessionId, String userSessionId) { if (isAdmin(sessionId)) { - disconnect(userSessionId, false); + disconnect(userSessionId, DisconnectReason.AdminDisconnect); LogServiceImpl.instance.log(LogKeys.KEY_SESSION_END_BY_ADMIN, sessionId, userSessionId); } } diff --git a/Mage.Server/src/main/java/mage/server/TableManager.java b/Mage.Server/src/main/java/mage/server/TableManager.java index cb29b7696a3..49f893dd828 100644 --- a/Mage.Server/src/main/java/mage/server/TableManager.java +++ b/Mage.Server/src/main/java/mage/server/TableManager.java @@ -28,12 +28,15 @@ package mage.server; -import java.util.*; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Date; +import java.util.List; +import java.util.UUID; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.Executors; import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.TimeUnit; - import mage.MageException; import mage.cards.decks.Deck; import mage.cards.decks.DeckCardLists; @@ -43,7 +46,6 @@ import mage.game.Table; import mage.game.draft.Draft; import mage.game.match.Match; import mage.game.match.MatchOptions; -import mage.game.match.MatchPlayer; import mage.game.tournament.Tournament; import mage.game.tournament.TournamentOptions; import mage.players.Player; @@ -51,7 +53,6 @@ import mage.server.game.GameManager; import mage.server.game.GamesRoomManager; import org.apache.log4j.Logger; - /** * * @author BetaSteward_at_googlemail.com @@ -255,12 +256,6 @@ public class TableManager { } } -// public void startChallenge(UUID userId, UUID roomId, UUID tableId, UUID challengeId) { -// if (controllers.containsKey(tableId)) { -// controllers.get(tableId).startChallenge(userId, challengeId); -// } -// } - public void startTournament(UUID userId, UUID roomId, UUID tableId) { if (controllers.containsKey(tableId)) { controllers.get(tableId).startTournament(userId); diff --git a/Mage.Server/src/main/java/mage/server/User.java b/Mage.Server/src/main/java/mage/server/User.java index aea64648122..312a582a395 100644 --- a/Mage.Server/src/main/java/mage/server/User.java +++ b/Mage.Server/src/main/java/mage/server/User.java @@ -62,10 +62,6 @@ public class User { Created, Connected, Disconnected, Reconnected; } - public enum DisconnectReason { - LostConnection, Disconnected, CleaningUp, ConnectingOtherInstance; - } - private final UUID userId; private final String userName; private final String host; diff --git a/Mage.Server/src/main/java/mage/server/UserManager.java b/Mage.Server/src/main/java/mage/server/UserManager.java index 0a63a46ea19..ced0f76f45c 100644 --- a/Mage.Server/src/main/java/mage/server/UserManager.java +++ b/Mage.Server/src/main/java/mage/server/UserManager.java @@ -38,7 +38,6 @@ import java.util.concurrent.Executors; import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.TimeUnit; import mage.server.util.ThreadExecutor; -import mage.view.ChatMessage.MessageColor; import org.apache.log4j.Logger; /** @@ -52,14 +51,16 @@ public class UserManager { protected static ScheduledExecutorService expireExecutor = Executors.newSingleThreadScheduledExecutor(); - private static final UserManager INSTANCE = new UserManager(); private static final Logger logger = Logger.getLogger(UserManager.class); + private final ConcurrentHashMap users = new ConcurrentHashMap<>(); + private static final ExecutorService callExecutor = ThreadExecutor.getInstance().getCallExecutor(); + + private static final UserManager INSTANCE = new UserManager(); + public static UserManager getInstance() { return INSTANCE; } - - private static final ExecutorService callExecutor = ThreadExecutor.getInstance().getCallExecutor(); private UserManager() { expireExecutor.scheduleAtFixedRate(new Runnable() { @@ -70,8 +71,6 @@ public class UserManager { }, 60, 60, TimeUnit.SECONDS); } - private final ConcurrentHashMap users = new ConcurrentHashMap<>(); - public User createUser(String userName, String host) { if (findUser(userName) != null) { return null; //user already exists @@ -106,7 +105,7 @@ public class UserManager { return false; } - public void disconnect(UUID userId, User.DisconnectReason reason) { + public void disconnect(UUID userId, DisconnectReason reason) { if (userId != null) { if (users.containsKey(userId)) { User user = users.get(userId); @@ -123,7 +122,7 @@ public class UserManager { return false; } - public void removeUser(UUID userId, User.DisconnectReason reason) { + public void removeUser(UUID userId, DisconnectReason reason) { User user = users.get(userId); if (user != null) { logger.debug(new StringBuilder("Remove user: ").append(user.getName()) @@ -166,8 +165,7 @@ public class UserManager { if (user.isExpired(expired.getTime())) { logger.info(new StringBuilder(user.getName()).append(": session expired userId: ").append(user.getId()) .append(" Host: ").append(user.getHost())); - user.kill(User.DisconnectReason.LostConnection); - users.remove(user.getId()); + SessionManager.getInstance().getSession(user.getSessionId()).kill(DisconnectReason.SessionExpired); } } logger.debug("checkExpired - end"); diff --git a/Mage.Server/src/main/java/mage/server/services/LogKeys.java b/Mage.Server/src/main/java/mage/server/services/LogKeys.java index 15090223ddd..45a77a7ef42 100644 --- a/Mage.Server/src/main/java/mage/server/services/LogKeys.java +++ b/Mage.Server/src/main/java/mage/server/services/LogKeys.java @@ -13,6 +13,8 @@ public interface LogKeys { String KEY_SESSION_KILLED = "sessionKilled"; + String KEY_SESSION_EXPIRED = "sessionExpired"; + String KEY_SESSION_DISCONNECTED = "sessionDisconnected"; String KEY_SESSION_DISCONNECTED_BY_ADMIN = "sessionDisconnectedByAdmin";