Added connection speed information per user (milliseconds the ping needs). Some minor changes to server console.

This commit is contained in:
LevelX2 2014-08-31 17:46:14 +02:00
parent 1285df5da3
commit b98c16f061
20 changed files with 166 additions and 54 deletions

View file

@ -1233,17 +1233,17 @@ public class MageFrame extends javax.swing.JFrame implements MageClient {
SwingUtilities.invokeLater(new Runnable() { SwingUtilities.invokeLater(new Runnable() {
@Override @Override
public void run() { public void run() {
setStatusText("Not connected");
disableButtons(); disableButtons();
hideGames();
hideTables();
if (JOptionPane.showConfirmDialog(MageFrame.this, "The connection to server was lost. Reconnect?", "Warning", JOptionPane.YES_NO_OPTION) == JOptionPane.YES_OPTION) { if (JOptionPane.showConfirmDialog(MageFrame.this, "The connection to server was lost. Reconnect?", "Warning", JOptionPane.YES_NO_OPTION) == JOptionPane.YES_OPTION) {
session.disconnect(false); // session.disconnect(false);
tablesPane.clearChat(); // tablesPane.clearChat();
if (performConnect()) { if (performConnect()) {
enableButtons(); enableButtons();
} }
} else { // } else {
setStatusText("Not connected");
hideGames();
hideTables();
} }
} }
}); });

View file

@ -46,6 +46,7 @@ import javax.swing.table.AbstractTableModel;
import javax.swing.table.JTableHeader; import javax.swing.table.JTableHeader;
import javax.swing.table.TableColumn; import javax.swing.table.TableColumn;
import javax.swing.table.TableColumnModel; import javax.swing.table.TableColumnModel;
import javax.swing.table.TableRowSorter;
import mage.client.MageFrame; import mage.client.MageFrame;
import mage.remote.MageRemoteException; import mage.remote.MageRemoteException;
import mage.remote.Session; import mage.remote.Session;
@ -152,6 +153,7 @@ public class ChatPanel extends javax.swing.JPanel {
initComponents(); initComponents();
jTablePlayers.setBackground(new Color(0, 0, 0, 0)); jTablePlayers.setBackground(new Color(0, 0, 0, 0));
jTablePlayers.setForeground(Color.white); jTablePlayers.setForeground(Color.white);
jTablePlayers.setRowSorter(new TableRowSorter(tableModel));
setBackground(new Color(0, 0, 0, 100)); setBackground(new Color(0, 0, 0, 100));
if (jScrollPaneTxt != null) { if (jScrollPaneTxt != null) {
jScrollPaneTxt.setBackground(new Color(0, 0, 0, 100)); jScrollPaneTxt.setBackground(new Color(0, 0, 0, 100));
@ -301,7 +303,7 @@ public class ChatPanel extends javax.swing.JPanel {
class TableModel extends AbstractTableModel { class TableModel extends AbstractTableModel {
private final String[] columnNames = new String[]{"Players", "Info", "Games"}; private final String[] columnNames = new String[]{"Players", "Info", "Games", "Connection"};
private UsersView[] players = new UsersView[0]; private UsersView[] players = new UsersView[0];
public void loadData(Collection<RoomUsersView> roomUserInfoList) throws MageRemoteException { public void loadData(Collection<RoomUsersView> roomUserInfoList) throws MageRemoteException {
@ -334,6 +336,8 @@ public class ChatPanel extends javax.swing.JPanel {
return players[arg0].getInfoState(); return players[arg0].getInfoState();
case 2: case 2:
return players[arg0].getInfoGames(); return players[arg0].getInfoGames();
case 3:
return players[arg0].getInfoPing();
} }
return ""; return "";
} }

View file

@ -74,7 +74,7 @@ public final class Constants {
public static final int PRIORITY_TIME_SEC = 1200; public static final int PRIORITY_TIME_SEC = 1200;
public enum SessionState { public enum SessionState {
DISCONNECTED, CONNECTED, CONNECTING, DISCONNECTING, SERVER_UNAVAILABLE, SERVER_STARTING; DISCONNECTED, CONNECTED, CONNECTING, DISCONNECTING, SERVER_STARTING;
} }
public enum Option { public enum Option {

View file

@ -47,7 +47,6 @@ import mage.view.TournamentView;
import mage.view.UserDataView; import mage.view.UserDataView;
import mage.view.RoomUsersView; import mage.view.RoomUsersView;
import mage.view.UserView; import mage.view.UserView;
import mage.view.UsersView;
/** /**
* *
@ -76,7 +75,7 @@ public interface MageServer {
Object getServerMessagesCompressed(String sessionId) throws MageException; // messages of the day Object getServerMessagesCompressed(String sessionId) throws MageException; // messages of the day
// ping - extends session // ping - extends session
boolean ping(String sessionId) throws MageException; boolean ping(String sessionId, String pingInfo) throws MageException;
//table methods //table methods
TableView createTable(String sessionId, UUID roomId, MatchOptions matchOptions) throws MageException; TableView createTable(String sessionId, UUID roomId, MatchOptions matchOptions) throws MageException;

View file

@ -57,6 +57,8 @@ import org.jboss.remoting.transporter.TransporterClient;
import java.net.*; import java.net.*;
import java.util.*; import java.util.*;
import java.util.concurrent.TimeUnit;
/** /**
* *
@ -75,7 +77,9 @@ public class SessionImpl implements Session {
private ServerState serverState; private ServerState serverState;
private SessionState sessionState = SessionState.DISCONNECTED; private SessionState sessionState = SessionState.DISCONNECTED;
private Connection connection; private Connection connection;
private final static int PING_CYCLES = 10;
private final LinkedList<Long> pingTime = new LinkedList<>();
private String pingInfo = "";
private static boolean debugMode = false; private static boolean debugMode = false;
private boolean canceled = false; private boolean canceled = false;
@ -303,11 +307,11 @@ public class SessionImpl implements Session {
} }
@Override @Override
public synchronized void disconnect(boolean showMessage) { public synchronized void disconnect(boolean errorCall) {
if (isConnected()) { if (isConnected()) {
sessionState = SessionState.DISCONNECTING; sessionState = SessionState.DISCONNECTING;
} }
if (connection == null) { if (connection == null || sessionState == SessionState.DISCONNECTED) {
return; return;
} }
try { try {
@ -320,11 +324,12 @@ public class SessionImpl implements Session {
if (sessionState == SessionState.DISCONNECTING || sessionState == SessionState.CONNECTING) { if (sessionState == SessionState.DISCONNECTING || sessionState == SessionState.CONNECTING) {
sessionState = SessionState.DISCONNECTED; sessionState = SessionState.DISCONNECTED;
logger.info("Disconnected ... "); logger.info("Disconnected ... ");
}
client.disconnected(); client.disconnected();
if (showMessage) { if (errorCall) {
client.showError("Network error. You have been disconnected"); client.showError("Network error. You have been disconnected");
} }
pingTime.clear();
}
} }
@Override @Override
@ -1305,7 +1310,6 @@ public class SessionImpl implements Session {
private void handleThrowable(Throwable t) { private void handleThrowable(Throwable t) {
logger.fatal("Communication error", t); logger.fatal("Communication error", t);
sessionState = SessionState.SERVER_UNAVAILABLE;
disconnect(true); disconnect(true);
} }
@ -1350,9 +1354,23 @@ public class SessionImpl implements Session {
public boolean ping() { public boolean ping() {
try { try {
if (isConnected()) { if (isConnected()) {
if (!server.ping(sessionId)) { long startTime = System.nanoTime();
if (!server.ping(sessionId, pingInfo)) {
logger.error(new StringBuilder("Ping failed: ").append(this.getUserName()).append(" Session: ").append(sessionId).append(" to MAGE server at ").append(connection.getHost()).append(":").append(connection.getPort()).toString()); logger.error(new StringBuilder("Ping failed: ").append(this.getUserName()).append(" Session: ").append(sessionId).append(" to MAGE server at ").append(connection.getHost()).append(":").append(connection.getPort()).toString());
throw new MageException("Ping failed");
} }
pingTime.add(System.nanoTime() - startTime);
long milliSeconds = TimeUnit.MILLISECONDS.convert(pingTime.getLast(), TimeUnit.NANOSECONDS);
String lastPing = milliSeconds > 0 ? milliSeconds+"ms" : "<1ms";
if (pingTime.size() > PING_CYCLES) {
pingTime.poll();
}
long sum = 0;
for (Long time :pingTime) {
sum += time;
}
milliSeconds = TimeUnit.MILLISECONDS.convert(sum / pingTime.size(), TimeUnit.NANOSECONDS);
pingInfo = lastPing + " (Av: " + (milliSeconds > 0 ? milliSeconds + "ms":"<1ms")+")";
} }
return true; return true;
} catch (MageException ex) { } catch (MageException ex) {

View file

@ -31,6 +31,7 @@ import java.io.Serializable;
import java.util.Date; import java.util.Date;
/** /**
* Admin Console View
* *
* @author BetaSteward_at_googlemail.com * @author BetaSteward_at_googlemail.com
*/ */
@ -40,12 +41,14 @@ public class UserView implements Serializable {
private final String host; private final String host;
private final String sessionId; private final String sessionId;
private final Date timeConnected; private final Date timeConnected;
private final String gameInfo;
public UserView(String userName, String host, String sessionId, Date timeConnected) { public UserView(String userName, String host, String sessionId, Date timeConnected, String gameInfo) {
this.userName = userName; this.userName = userName;
this.host = host; this.host = host;
this.sessionId = sessionId; this.sessionId = sessionId;
this.timeConnected = timeConnected; this.timeConnected = timeConnected;
this.gameInfo = gameInfo;
} }
public String getUserName() { public String getUserName() {
@ -64,4 +67,8 @@ public class UserView implements Serializable {
return timeConnected; return timeConnected;
} }
public String getGameInfo() {
return gameInfo;
}
} }

View file

@ -40,11 +40,13 @@ public class UsersView implements Serializable {
private final String userName; private final String userName;
private final String infoState; private final String infoState;
private final String infoGames; private final String infoGames;
private final String infoPing;
public UsersView(String userName, String infoState, String infoGames) { public UsersView(String userName, String infoState, String infoGames, String infoPing) {
this.userName = userName; this.userName = userName;
this.infoState = infoState; this.infoState = infoState;
this.infoGames = infoGames; this.infoGames = infoGames;
this.infoPing = infoPing;
} }
public String getUserName() { public String getUserName() {
@ -59,4 +61,8 @@ public class UsersView implements Serializable {
return infoGames; return infoGames;
} }
public String getInfoPing() {
return infoPing;
}
} }

View file

@ -487,7 +487,7 @@ public class ConnectDialog extends JDialog {
private void findPublicServerActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButton1ActionPerformed private void findPublicServerActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButton1ActionPerformed
BufferedReader in = null; BufferedReader in = null;
try { try {
URL serverListURL = new URL("http://download.magefree.com/files/server-list.txt"); URL serverListURL = new URL("http://XMage.info/files/server-list.txt");
in = new BufferedReader(new InputStreamReader(serverListURL.openStream())); in = new BufferedReader(new InputStreamReader(serverListURL.openStream()));
List<String> servers = new ArrayList<>(); List<String> servers = new ArrayList<>();

View file

@ -39,6 +39,11 @@ import java.awt.event.WindowEvent;
import java.util.concurrent.Executors; import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
import java.util.prefs.Preferences;
import javax.swing.Box;
import javax.swing.JOptionPane;
import javax.swing.SwingUtilities;
import javax.swing.UIManager;
import mage.interfaces.MageClient; import mage.interfaces.MageClient;
import mage.interfaces.callback.ClientCallback; import mage.interfaces.callback.ClientCallback;
import mage.remote.Connection; import mage.remote.Connection;
@ -47,9 +52,6 @@ import mage.remote.SessionImpl;
import mage.utils.MageVersion; import mage.utils.MageVersion;
import org.apache.log4j.Logger; import org.apache.log4j.Logger;
import javax.swing.*;
import java.util.prefs.Preferences;
/** /**
* *
* @author BetaSteward_at_googlemail.com * @author BetaSteward_at_googlemail.com
@ -121,7 +123,7 @@ public class ConsoleFrame extends javax.swing.JFrame implements MageClient {
public void enableButtons() { public void enableButtons() {
btnConnect.setEnabled(true); btnConnect.setEnabled(true);
btnConnect.setText("Disconnect"); btnConnect.setText("Disconnect & Close");
btnSendMessage.setEnabled(true); btnSendMessage.setEnabled(true);
} }

View file

@ -40,8 +40,11 @@ import java.util.List;
import java.util.UUID; import java.util.UUID;
import java.util.concurrent.CancellationException; import java.util.concurrent.CancellationException;
import java.util.concurrent.ExecutionException; import java.util.concurrent.ExecutionException;
import static javax.swing.JTable.AUTO_RESIZE_NEXT_COLUMN;
import static javax.swing.JTable.AUTO_RESIZE_OFF;
import javax.swing.SwingWorker; import javax.swing.SwingWorker;
import javax.swing.table.AbstractTableModel; import javax.swing.table.AbstractTableModel;
import javax.swing.table.TableRowSorter;
import mage.remote.Session; import mage.remote.Session;
import mage.view.TableView; import mage.view.TableView;
import mage.view.UserView; import mage.view.UserView;
@ -66,7 +69,12 @@ public class ConsolePanel extends javax.swing.JPanel {
this.tableTableModel = new TableTableModel(); this.tableTableModel = new TableTableModel();
initComponents(); initComponents();
this.tblUsers.createDefaultColumnsFromModel(); this.tblUsers.createDefaultColumnsFromModel();
this.tblUsers.setRowSorter(new TableRowSorter(tableUserModel));
this.tblUsers.setAutoResizeMode(AUTO_RESIZE_OFF);
this.tblTables.createDefaultColumnsFromModel(); this.tblTables.createDefaultColumnsFromModel();
this.tblTables.setRowSorter(new TableRowSorter(tableTableModel));
this.tblUsers.setAutoResizeMode(AUTO_RESIZE_NEXT_COLUMN);
} }
public void update(List<UserView> users) { public void update(List<UserView> users) {
@ -259,17 +267,17 @@ public class ConsolePanel extends javax.swing.JPanel {
}// </editor-fold>//GEN-END:initComponents }// </editor-fold>//GEN-END:initComponents
private void btnDisconnectActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnDisconnectActionPerformed private void btnDisconnectActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnDisconnectActionPerformed
int row = this.tblUsers.getSelectedRow(); int row = this.tblUsers.convertRowIndexToModel(tblUsers.getSelectedRow());
ConsoleFrame.getSession().disconnectUser((String)tableUserModel.getValueAt(row, 3)); ConsoleFrame.getSession().disconnectUser((String)tableUserModel.getValueAt(row, 3));
}//GEN-LAST:event_btnDisconnectActionPerformed }//GEN-LAST:event_btnDisconnectActionPerformed
private void btnRemoveTableActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnRemoveTableActionPerformed private void btnRemoveTableActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnRemoveTableActionPerformed
int row = this.tblTables.getSelectedRow(); int row = this.tblTables.convertRowIndexToModel(tblTables.getSelectedRow());
ConsoleFrame.getSession().removeTable((UUID)tableTableModel.getValueAt(row, 7)); ConsoleFrame.getSession().removeTable((UUID)tableTableModel.getValueAt(row, 7));
}//GEN-LAST:event_btnRemoveTableActionPerformed }//GEN-LAST:event_btnRemoveTableActionPerformed
private void btnEndSessionActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnEndSessionActionPerformed private void btnEndSessionActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnEndSessionActionPerformed
int row = this.tblUsers.getSelectedRow(); int row = this.tblUsers.convertRowIndexToModel(tblUsers.getSelectedRow());
ConsoleFrame.getSession().endUserSession((String) tableUserModel.getValueAt(row, 3)); ConsoleFrame.getSession().endUserSession((String) tableUserModel.getValueAt(row, 3));
}//GEN-LAST:event_btnEndSessionActionPerformed }//GEN-LAST:event_btnEndSessionActionPerformed
@ -292,7 +300,7 @@ public class ConsolePanel extends javax.swing.JPanel {
} }
class TableUserModel extends AbstractTableModel { class TableUserModel extends AbstractTableModel {
private final String[] columnNames = new String[]{"User Name", "Host", "Time Connected"}; private final String[] columnNames = new String[]{"User Name", "Host", "Time Connected", "SessionId", "Gameinfo"};
private UserView[] users = new UserView[0]; private UserView[] users = new UserView[0];
private static final DateFormat formatter = new SimpleDateFormat("HH:mm:ss"); private static final DateFormat formatter = new SimpleDateFormat("HH:mm:ss");
@ -322,6 +330,8 @@ class TableUserModel extends AbstractTableModel {
return formatter.format(users[arg0].getConnectionTime()); return formatter.format(users[arg0].getConnectionTime());
case 3: case 3:
return users[arg0].getSessionId(); return users[arg0].getSessionId();
case 4:
return users[arg0].getGameInfo();
} }
return ""; return "";
} }
@ -438,12 +448,13 @@ class UpdateUsersTask extends SwingWorker<Void, List<UserView>> {
protected Void doInBackground() throws Exception { protected Void doInBackground() throws Exception {
while (!isCancelled()) { while (!isCancelled()) {
List<UserView> users = session.getUsers(); List<UserView> users = session.getUsers();
if (previousUsers == null || checkUserListChanged(users)) { if (previousUsers == null || checkUserListChanged(users)) {
logger.debug("Need to update the user list"); logger.debug("Need to update the user list");
this.publish(users); this.publish(users);
previousUsers = users; previousUsers = users;
} }
Thread.sleep(1000); Thread.sleep(2000);
} }
return null; return null;
} }
@ -508,7 +519,7 @@ class UpdateTablesTask extends SwingWorker<Void, Collection<TableView>> {
protected Void doInBackground() throws Exception { protected Void doInBackground() throws Exception {
while (!isCancelled()) { while (!isCancelled()) {
this.publish(session.getTables(roomId)); this.publish(session.getTables(roomId));
Thread.sleep(1000); Thread.sleep(3000);
} }
return null; return null;
} }

View file

@ -93,6 +93,12 @@ public class ChatSession {
case SessionExpired: case SessionExpired:
message = " session expired"; message = " session expired";
break; break;
case AdminDisconnect:
message = " was disconnected by the Admin";
break;
case ConnectingOtherInstance:
message = " reconnected and replaced still active old session";
break;
case CleaningUp: case CleaningUp:
message = null; message = null;
break; break;

View file

@ -330,8 +330,8 @@ public class MageServerImpl implements MageServer {
} }
@Override @Override
public boolean ping(String sessionId) { public boolean ping(String sessionId, String pingInfo) {
return SessionManager.getInstance().extendUserSession(sessionId); return SessionManager.getInstance().extendUserSession(sessionId, pingInfo);
} }
// @Override // @Override
@ -959,6 +959,13 @@ public class MageServerImpl implements MageServer {
}); });
} }
/**
* Get user data for admin console
*
* @param sessionId
* @return
* @throws MageException
*/
@Override @Override
public List<UserView> getUsers(String sessionId) throws MageException { public List<UserView> getUsers(String sessionId) throws MageException {
return executeWithResult("getUsers", sessionId, new ActionWithNullNegativeResult<List<UserView>>() { return executeWithResult("getUsers", sessionId, new ActionWithNullNegativeResult<List<UserView>>() {
@ -966,7 +973,8 @@ public class MageServerImpl implements MageServer {
public List<UserView> execute() throws MageException { public List<UserView> execute() throws MageException {
List<UserView> users = new ArrayList<>(); List<UserView> users = new ArrayList<>();
for (User user : UserManager.getInstance().getUsers()) { for (User user : UserManager.getInstance().getUsers()) {
users.add(new UserView(user.getName(), user.getHost(), user.getSessionId(), user.getConnectionTime()));
users.add(new UserView(user.getName(), user.getHost(), user.getSessionId(), user.getConnectionTime(), user.getGameInfo()));
} }
return users; return users;
} }

View file

@ -99,7 +99,7 @@ public class Session {
if (user == null) { // user already exists if (user == null) { // user already exists
user = UserManager.getInstance().findUser(userName); user = UserManager.getInstance().findUser(userName);
if (user.getHost().equals(host)) { if (user.getHost().equals(host)) {
user.updateLastActivity(); // minimizes possible expiration user.updateLastActivity(null); // minimizes possible expiration
this.userId = user.getId(); this.userId = user.getId();
if (user.getSessionId().isEmpty()) { if (user.getSessionId().isEmpty()) {
logger.info("Reconnecting session for " + userName); logger.info("Reconnecting session for " + userName);

View file

@ -152,12 +152,34 @@ public class SessionManager {
return map; return map;
} }
/**
* Admin requested the disconnect of a user
* @param sessionId
* @param userSessionId
*/
public void disconnectUser(String sessionId, String userSessionId) { public void disconnectUser(String sessionId, String userSessionId) {
if (isAdmin(sessionId)) { if (isAdmin(sessionId)) {
User userAdmin, user;
if ((userAdmin = getUserFromSession(sessionId)) != null) {
if ((user = getUserFromSession(userSessionId)) != null) {
user.showUserMessage("Admin operation","Your session was disconnected by Admin.");
userAdmin.showUserMessage("Admin action", "User" + user.getName() + " was disconnected.");
disconnect(userSessionId, DisconnectReason.AdminDisconnect); disconnect(userSessionId, DisconnectReason.AdminDisconnect);
LogServiceImpl.instance.log(LogKeys.KEY_SESSION_DISCONNECTED_BY_ADMIN, sessionId, userSessionId); LogServiceImpl.instance.log(LogKeys.KEY_SESSION_DISCONNECTED_BY_ADMIN, sessionId, userSessionId);
} else {
userAdmin.showUserMessage("Admin operation","User with sessionId " + userSessionId + " could not be found!");
} }
} }
}
}
private User getUserFromSession(String sessionId) {
Session session = getSession(sessionId);
if (session == null) {
return null;
}
return UserManager.getInstance().getUser(session.getUserId());
}
public void endUserSession(String sessionId, String userSessionId) { public void endUserSession(String sessionId, String userSessionId) {
if (isAdmin(sessionId)) { if (isAdmin(sessionId)) {
@ -186,10 +208,10 @@ public class SessionManager {
return null; return null;
} }
public boolean extendUserSession(String sessionId) { public boolean extendUserSession(String sessionId, String pingInfo) {
Session session = sessions.get(sessionId); Session session = sessions.get(sessionId);
if (session != null) { if (session != null) {
return UserManager.getInstance().extendUserSession(session.getUserId()); return UserManager.getInstance().extendUserSession(session.getUserId(), pingInfo);
} }
return false; return false;
} }

View file

@ -34,6 +34,7 @@ import java.util.ArrayList;
import java.util.Collection; import java.util.Collection;
import java.util.Date; import java.util.Date;
import java.util.List; import java.util.List;
import java.util.Map.Entry;
import java.util.UUID; import java.util.UUID;
import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.Executors; import java.util.concurrent.Executors;
@ -51,6 +52,7 @@ import mage.game.match.MatchOptions;
import mage.game.tournament.Tournament; import mage.game.tournament.Tournament;
import mage.game.tournament.TournamentOptions; import mage.game.tournament.TournamentOptions;
import mage.players.Player; import mage.players.Player;
import mage.server.game.GameController;
import mage.server.game.GameManager; import mage.server.game.GameManager;
import mage.server.game.GamesRoomManager; import mage.server.game.GamesRoomManager;
import org.apache.log4j.Logger; import org.apache.log4j.Logger;
@ -379,11 +381,17 @@ public class TableManager {
for (Table table: tables.values()) { for (Table table: tables.values()) {
logger.debug(table.getId() + " [" + table.getName()+ "] " + formatter.format(table.getStartTime()) +" (" + table.getState().toString() + ")"); logger.debug(table.getId() + " [" + table.getName()+ "] " + formatter.format(table.getStartTime()) +" (" + table.getState().toString() + ")");
} }
logger.debug("------- Games: " + GameManager.getInstance().getNumberActiveGames() + " --------------------------------------------");
for (Entry<UUID, GameController> entry: GameManager.getInstance().getGameController().entrySet()) {
logger.debug(entry.getKey() + entry.getValue().getPlayerNameList());
}
logger.debug("--- Server state END ------------------------------------------"); logger.debug("--- Server state END ------------------------------------------");
} }
private void checkExpired() { private void checkExpired() {
if (logger.isDebugEnabled()) {
debugServerState(); debugServerState();
}
Date now = new Date(); Date now = new Date();
List<UUID> toRemove = new ArrayList<>(); List<UUID> toRemove = new ArrayList<>();
for (Table table : tables.values()) { for (Table table : tables.values()) {

View file

@ -75,7 +75,8 @@ public class User {
private final Map<UUID, Deck> sideboarding; private final Map<UUID, Deck> sideboarding;
private final List<UUID> watchedGames; private final List<UUID> watchedGames;
private String sessionId; private String sessionId;
private String info; private String info = "";
private String pingInfo = "";
private Date lastActivity; private Date lastActivity;
private UserState userState; private UserState userState;
private UserData userData; private UserData userData;
@ -238,7 +239,10 @@ public class User {
GameManager.getInstance().sendPlayerInteger(gameId, userId, data); GameManager.getInstance().sendPlayerInteger(gameId, userId, data);
} }
public void updateLastActivity() { public void updateLastActivity(String pingInfo) {
if (pingInfo != null) {
this.pingInfo = pingInfo;
}
lastActivity = new Date(); lastActivity = new Date();
if (userState == UserState.Disconnected) { // this can happen if user reconnects very fast after disconnect if (userState == UserState.Disconnected) { // this can happen if user reconnects very fast after disconnect
userState = UserState.Reconnected; userState = UserState.Reconnected;
@ -458,4 +462,8 @@ public class User {
return userState; return userState;
} }
public String getPingInfo() {
return pingInfo;
}
} }

View file

@ -145,11 +145,11 @@ public class UserManager {
} }
} }
public boolean extendUserSession(UUID userId) { public boolean extendUserSession(UUID userId, String pingInfo) {
if (userId != null) { if (userId != null) {
User user = users.get(userId); User user = users.get(userId);
if (user != null) { if (user != null) {
user.updateLastActivity(); user.updateLastActivity(pingInfo);
return true; return true;
} }
} }

View file

@ -826,4 +826,17 @@ public class GameController implements GameCallback {
} }
return gameSessions.get(playerId); return gameSessions.get(playerId);
} }
public String getPlayerNameList() {
StringBuilder sb = new StringBuilder(" [");
for (UUID playerId: userPlayerMap.values()) {
Player player = game.getPlayer(playerId);
if (player != null) {
sb.append(player.getName()).append("(Left=").append(player.hasLeft() ? "Y":"N").append(") ");
} else {
sb.append("player missing: ").append(playerId).append(" ");
}
}
return sb.append("]").toString();
}
} }

View file

@ -62,10 +62,6 @@ public class GameManager {
} }
} }
// public void destroyChatSession(UUID gameId) {
// gameControllers.remove(gameId);
// }
public UUID getChatId(UUID gameId) { public UUID getChatId(UUID gameId) {
if (gameControllers.containsKey(gameId)) { if (gameControllers.containsKey(gameId)) {
return gameControllers.get(gameId).getChatId(); return gameControllers.get(gameId).getChatId();
@ -213,4 +209,8 @@ public class GameManager {
public int getNumberActiveGames() { public int getNumberActiveGames() {
return gameControllers.size(); return gameControllers.size();
} }
public ConcurrentHashMap<UUID, GameController> getGameController() {
return gameControllers;
}
} }

View file

@ -118,10 +118,10 @@ public class GamesRoomImpl extends RoomImpl implements GamesRoom, Serializable {
List<UsersView> users = new ArrayList<>(); List<UsersView> users = new ArrayList<>();
for (User user : UserManager.getInstance().getUsers()) { for (User user : UserManager.getInstance().getUsers()) {
try { try {
users.add(new UsersView(user.getName(), user.getInfo(), user.getGameInfo())); users.add(new UsersView(user.getName(), user.getInfo(), user.getGameInfo(), user.getPingInfo()));
} catch (Exception ex) { } catch (Exception ex) {
logger.fatal("User update exception: " + user.getName() + " - " + ex.toString(), ex); logger.fatal("User update exception: " + user.getName() + " - " + ex.toString(), ex);
users.add(new UsersView(user.getName(), user.getInfo(), "[exception]")); users.add(new UsersView(user.getName(), user.getInfo(), "[exception]", user.getPingInfo()));
} }
} }