mirror of
https://github.com/magefree/mage.git
synced 2025-12-24 12:31:59 -08:00
Network upgrade and new reconnection mode (#11527)
Network upgrade and new reconnection mode: * users can disconnect or close app without game progress loose now; * disconnect dialog will show active tables stats and additional options; * all active tables will be restored on reconnect (tables, tourneys, games, drafts, sideboarding, constructing); * user must use same server and username on next connection; * there are few minutes for reconnect until server kick off a disconnected player from all player's tables (concede/loose); * now you can safety reconnect after IP change (after proxy/vpn/wifi/router restart); Other improvements and fixes: * gui: main menu - improved switch panel button, added stats about current tables/panels; * gui: improved data sync and updates (fixes many use cases with empty battlefield, not started games/drafts/tourneys, not updatable drafts, etc); * gui: improved stability on game updates (fixes some random errors related to wrong threads); * server: fixed miss messages about player's disconnection problems for other players in the chat; * refactor: simplified and improved connection and network related code, deleted outdated code, added docs; * tests: improved load test to support lands only set for more stable performance/network testing (set TEST_AI_RANDOM_DECK_SETS = PELP and run test_TwoAIPlayGame_Multiple);
This commit is contained in:
parent
7f0558ff3c
commit
960e896903
71 changed files with 1274 additions and 802 deletions
|
|
@ -124,6 +124,9 @@ public class MageFrame extends javax.swing.JFrame implements MageClient {
|
|||
private static int startPort = -1;
|
||||
private static boolean debugMode = false;
|
||||
|
||||
private JToggleButton switchPanelsButton = null; // from main menu
|
||||
private static String SWITCH_PANELS_BUTTON_NAME = "Switch panels";
|
||||
|
||||
private static final Map<UUID, ChatPanelBasic> CHATS = new HashMap<>();
|
||||
private static final Map<UUID, GamePanel> GAMES = new HashMap<>();
|
||||
private static final Map<UUID, DraftPanel> DRAFTS = new HashMap<>();
|
||||
|
|
@ -189,9 +192,6 @@ public class MageFrame extends javax.swing.JFrame implements MageClient {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates new form MageFrame
|
||||
*/
|
||||
public MageFrame() throws MageException {
|
||||
File cacertsFile = new File(System.getProperty("user.dir") + "/release/cacerts").getAbsoluteFile();
|
||||
if (!cacertsFile.exists()) { // When running from the jar file the contents of the /release folder will have been expanded into the home folder as part of packaging
|
||||
|
|
@ -283,6 +283,23 @@ public class MageFrame extends javax.swing.JFrame implements MageClient {
|
|||
|
||||
initComponents();
|
||||
|
||||
// auto-update switch panels button with actual stats
|
||||
desktopPane.addContainerListener(new ContainerAdapter() {
|
||||
@Override
|
||||
public void componentAdded(ContainerEvent e) {
|
||||
if (desktopPane.getLayer(e.getComponent()) == JLayeredPane.DEFAULT_LAYER) {
|
||||
updateSwitchPanelsButton();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void componentRemoved(ContainerEvent e) {
|
||||
if (desktopPane.getLayer(e.getComponent()) == JLayeredPane.DEFAULT_LAYER) {
|
||||
updateSwitchPanelsButton();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
desktopPane.setDesktopManager(new MageDesktopManager());
|
||||
|
||||
setSize(1024, 768);
|
||||
|
|
@ -303,8 +320,12 @@ public class MageFrame extends javax.swing.JFrame implements MageClient {
|
|||
|
||||
updateMemUsageTask = new UpdateMemUsageTask(jMemUsageLabel);
|
||||
|
||||
// create default server lobby and hide it until connect
|
||||
tablesPane = new TablesPane();
|
||||
desktopPane.add(tablesPane, javax.swing.JLayeredPane.DEFAULT_LAYER);
|
||||
SwingUtilities.invokeLater(() -> {
|
||||
this.hideServerLobby();
|
||||
});
|
||||
|
||||
addTooltipContainer();
|
||||
setBackground();
|
||||
|
|
@ -565,15 +586,27 @@ public class MageFrame extends javax.swing.JFrame implements MageClient {
|
|||
}
|
||||
|
||||
private AbstractButton createSwitchPanelsButton() {
|
||||
final JToggleButton switchPanelsButton = new JToggleButton("Switch panels");
|
||||
switchPanelsButton.addItemListener(e -> {
|
||||
this.switchPanelsButton = new JToggleButton(SWITCH_PANELS_BUTTON_NAME);
|
||||
this.switchPanelsButton.addItemListener(e -> {
|
||||
if (e.getStateChange() == ItemEvent.SELECTED) {
|
||||
createAndShowSwitchPanelsMenu((JComponent) e.getSource(), switchPanelsButton);
|
||||
createAndShowSwitchPanelsMenu((JComponent) e.getSource(), this.switchPanelsButton);
|
||||
}
|
||||
});
|
||||
switchPanelsButton.setFocusable(false);
|
||||
switchPanelsButton.setHorizontalTextPosition(SwingConstants.LEADING);
|
||||
return switchPanelsButton;
|
||||
this.switchPanelsButton.setFocusable(false);
|
||||
this.switchPanelsButton.setHorizontalTextPosition(SwingConstants.LEADING);
|
||||
return this.switchPanelsButton;
|
||||
}
|
||||
|
||||
private void updateSwitchPanelsButton() {
|
||||
if (this.switchPanelsButton != null) {
|
||||
int totalCount = getPanelsCount(false);
|
||||
int activeCount = getPanelsCount(true);
|
||||
this.switchPanelsButton.setText(SWITCH_PANELS_BUTTON_NAME + String.format(" (%d)", totalCount));
|
||||
this.switchPanelsButton.setToolTipText(String.format("Click to switch between panels (active panels: %d of %d)",
|
||||
activeCount,
|
||||
totalCount
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
private void createAndShowSwitchPanelsMenu(final JComponent component, final AbstractButton windowButton) {
|
||||
|
|
@ -762,17 +795,27 @@ public class MageFrame extends javax.swing.JFrame implements MageClient {
|
|||
}
|
||||
|
||||
public void showTournament(UUID tournamentId) {
|
||||
// existing tourney
|
||||
TournamentPane tournamentPane = null;
|
||||
for (Component component : desktopPane.getComponents()) {
|
||||
if (component instanceof TournamentPane
|
||||
&& ((TournamentPane) component).getTournamentId().equals(tournamentId)) {
|
||||
setActive((TournamentPane) component);
|
||||
return;
|
||||
tournamentPane = (TournamentPane) component;
|
||||
}
|
||||
}
|
||||
TournamentPane tournamentPane = new TournamentPane();
|
||||
desktopPane.add(tournamentPane, JLayeredPane.DEFAULT_LAYER);
|
||||
tournamentPane.setVisible(true);
|
||||
tournamentPane.showTournament(tournamentId);
|
||||
|
||||
// new tourney
|
||||
if (tournamentPane == null) {
|
||||
tournamentPane = new TournamentPane();
|
||||
desktopPane.add(tournamentPane, JLayeredPane.DEFAULT_LAYER);
|
||||
tournamentPane.setVisible(true);
|
||||
tournamentPane.showTournament(tournamentId);
|
||||
}
|
||||
|
||||
// if user connects on startup then there are possible multiple tables open, so keep only actual
|
||||
// priority: game > constructing > draft > tourney
|
||||
// TODO: activate panel by priority
|
||||
|
||||
setActive(tournamentPane);
|
||||
}
|
||||
|
||||
|
|
@ -843,7 +886,7 @@ public class MageFrame extends javax.swing.JFrame implements MageClient {
|
|||
LOGGER.debug("connecting (auto): " + currentConnection.getProxyType().toString()
|
||||
+ ' ' + currentConnection.getProxyHost() + ' ' + currentConnection.getProxyPort() + ' ' + currentConnection.getProxyUsername());
|
||||
if (MageFrame.connect(currentConnection)) {
|
||||
prepareAndShowTablesPane();
|
||||
prepareAndShowServerLobby();
|
||||
return true;
|
||||
} else {
|
||||
showMessage("Unable connect to server: " + SessionHandler.getLastConnectError());
|
||||
|
|
@ -1075,10 +1118,7 @@ public class MageFrame extends javax.swing.JFrame implements MageClient {
|
|||
|
||||
private void btnConnectActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnConnectActionPerformed
|
||||
if (SessionHandler.isConnected()) {
|
||||
UserRequestMessage message = new UserRequestMessage("Confirm disconnect", "Are you sure you want to disconnect?");
|
||||
message.setButton1("No", null);
|
||||
message.setButton2("Yes", PlayerAction.CLIENT_DISCONNECT);
|
||||
showUserRequestDialog(message);
|
||||
tryDisconnectOrExit(false);
|
||||
} else {
|
||||
connectDialog.showDialog();
|
||||
setWindowTitle();
|
||||
|
|
@ -1148,15 +1188,34 @@ public class MageFrame extends javax.swing.JFrame implements MageClient {
|
|||
}
|
||||
|
||||
public void exitApp() {
|
||||
tryDisconnectOrExit(true);
|
||||
}
|
||||
|
||||
private void tryDisconnectOrExit(Boolean needExit) {
|
||||
String actionName = needExit ? "exit" : "disconnect";
|
||||
PlayerAction actionFull = needExit ? PlayerAction.CLIENT_EXIT_FULL : PlayerAction.CLIENT_DISCONNECT_FULL;
|
||||
PlayerAction actionKeepTables = needExit ? PlayerAction.CLIENT_EXIT_KEEP_GAMES : PlayerAction.CLIENT_DISCONNECT_KEEP_GAMES;
|
||||
double windowSizeRatio = 1.3;
|
||||
if (SessionHandler.isConnected()) {
|
||||
UserRequestMessage message = new UserRequestMessage("Confirm disconnect", "You are currently connected. Are you sure you want to disconnect?");
|
||||
message.setButton1("No", null);
|
||||
message.setButton2("Yes", PlayerAction.CLIENT_EXIT);
|
||||
int activeTables = MageFrame.getInstance().getPanelsCount(true);
|
||||
UserRequestMessage message = new UserRequestMessage(
|
||||
"Confirm " + actionName,
|
||||
"You are connected and has " + activeTables + " active table(s). You can quit from all your tables (concede) or ask server to wait a few minutes for reconnect. What to do?"
|
||||
);
|
||||
String totalInfo = (activeTables == 0 ? "" : String.format(" from %d table%s", activeTables, (activeTables > 1 ? "s" : "")));
|
||||
message.setButton1("Cancel", null);
|
||||
message.setButton2("Wait for me", actionKeepTables);
|
||||
message.setButton3("Quit" + totalInfo, actionFull);
|
||||
message.setWindowSizeRatio(windowSizeRatio);
|
||||
MageFrame.getInstance().showUserRequestDialog(message);
|
||||
} else {
|
||||
UserRequestMessage message = new UserRequestMessage("Confirm exit", "Are you sure you want to exit?");
|
||||
message.setButton1("No", null);
|
||||
message.setButton2("Yes", PlayerAction.CLIENT_EXIT);
|
||||
UserRequestMessage message = new UserRequestMessage(
|
||||
"Confirm " + actionName,
|
||||
"Are you sure you want to " + actionName + "?"
|
||||
);
|
||||
message.setButton1("Cancel", null);
|
||||
message.setButton2("Yes", actionFull);
|
||||
message.setWindowSizeRatio(windowSizeRatio);
|
||||
MageFrame.getInstance().showUserRequestDialog(message);
|
||||
}
|
||||
}
|
||||
|
|
@ -1171,17 +1230,18 @@ public class MageFrame extends javax.swing.JFrame implements MageClient {
|
|||
btnDeckEditor.setEnabled(true);
|
||||
}
|
||||
|
||||
public void hideTables() {
|
||||
public void hideServerLobby() {
|
||||
this.tablesPane.hideTables();
|
||||
updateSwitchPanelsButton();
|
||||
}
|
||||
|
||||
public void setTableFilter() {
|
||||
public void setServerLobbyTablesFilter() {
|
||||
if (this.tablesPane != null) {
|
||||
this.tablesPane.setTableFilter();
|
||||
}
|
||||
}
|
||||
|
||||
public void prepareAndShowTablesPane() {
|
||||
public void prepareAndShowServerLobby() {
|
||||
// Update the tables pane with the new session
|
||||
this.tablesPane.showTables();
|
||||
|
||||
|
|
@ -1191,6 +1251,8 @@ public class MageFrame extends javax.swing.JFrame implements MageClient {
|
|||
if (topPanebefore != null && topPanebefore != tablesPane) {
|
||||
setActive(topPanebefore);
|
||||
}
|
||||
|
||||
updateSwitchPanelsButton();
|
||||
}
|
||||
|
||||
public void hideGames() {
|
||||
|
|
@ -1253,14 +1315,18 @@ public class MageFrame extends javax.swing.JFrame implements MageClient {
|
|||
}
|
||||
|
||||
public void showUserRequestDialog(final UserRequestMessage userRequestMessage) {
|
||||
final UserRequestDialog userRequestDialog = new UserRequestDialog();
|
||||
if (SwingUtilities.isEventDispatchThread()) {
|
||||
innerShowUserRequestDialog(userRequestMessage);
|
||||
} else {
|
||||
SwingUtilities.invokeLater(() -> innerShowUserRequestDialog(userRequestMessage));
|
||||
}
|
||||
}
|
||||
|
||||
private void innerShowUserRequestDialog(final UserRequestMessage userRequestMessage) {
|
||||
UserRequestDialog userRequestDialog = new UserRequestDialog();
|
||||
userRequestDialog.setLocation(100, 100);
|
||||
desktopPane.add(userRequestDialog, JLayeredPane.MODAL_LAYER);
|
||||
if (SwingUtilities.isEventDispatchThread()) {
|
||||
userRequestDialog.showDialog(userRequestMessage);
|
||||
} else {
|
||||
SwingUtilities.invokeLater(() -> userRequestDialog.showDialog(userRequestMessage));
|
||||
}
|
||||
userRequestDialog.showDialog(userRequestMessage);
|
||||
}
|
||||
|
||||
public void showErrorDialog(final String title, final String message) {
|
||||
|
|
@ -1478,50 +1544,55 @@ public class MageFrame extends javax.swing.JFrame implements MageClient {
|
|||
DRAFTS.put(draftId, draftPanel);
|
||||
}
|
||||
|
||||
public BalloonTip getBalloonTip() {
|
||||
return balloonTip;
|
||||
/**
|
||||
* Return total number of panels/frames (game panel, deck editor panel, etc)
|
||||
*
|
||||
* @param onlyActive return only active panels (related to online like game panel, but not game viewer)
|
||||
* @return
|
||||
*/
|
||||
public int getPanelsCount(boolean onlyActive) {
|
||||
return (int) Arrays.stream(this.desktopPane.getComponentsInLayer(javax.swing.JLayeredPane.DEFAULT_LAYER))
|
||||
.filter(Component::isVisible)
|
||||
.filter(p -> p instanceof MagePane)
|
||||
.map(p -> (MagePane) p)
|
||||
.filter(p-> !onlyActive || p.isActiveTable())
|
||||
.count();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void connected(final String message) {
|
||||
if (SwingUtilities.isEventDispatchThread()) {
|
||||
SwingUtilities.invokeLater(() -> {
|
||||
setConnectButtonText(message);
|
||||
enableButtons();
|
||||
} else {
|
||||
SwingUtilities.invokeLater(() -> {
|
||||
setConnectButtonText(message);
|
||||
enableButtons();
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void disconnected(final boolean askToReconnect) {
|
||||
if (SwingUtilities.isEventDispatchThread()) { // Returns true if the current thread is an AWT event dispatching thread.
|
||||
if (SwingUtilities.isEventDispatchThread()) {
|
||||
// REMOTE task, e.g. connecting
|
||||
LOGGER.info("Disconnected from remote task");
|
||||
LOGGER.info("Disconnected from server side");
|
||||
} else {
|
||||
// USER mode, e.g. user plays and got disconnect
|
||||
LOGGER.info("Disconnected from client side");
|
||||
}
|
||||
|
||||
SwingUtilities.invokeLater(() -> {
|
||||
// user already disconnected, can't do any online actions like quite chat
|
||||
// but try to keep session
|
||||
// TODO: why it ignore askToReconnect here, but use custom reconnect dialog later?! Need research
|
||||
SessionHandler.disconnect(false, true);
|
||||
setConnectButtonText(NOT_CONNECTED_BUTTON);
|
||||
disableButtons();
|
||||
hideGames();
|
||||
hideTables();
|
||||
} else {
|
||||
// USER mode, e.g. user plays and got disconnect
|
||||
LOGGER.info("Disconnected from user mode");
|
||||
SwingUtilities.invokeLater(() -> {
|
||||
SessionHandler.disconnect(false); // user already disconnected, can't do any online actions like quite chat
|
||||
setConnectButtonText(NOT_CONNECTED_BUTTON);
|
||||
disableButtons();
|
||||
hideGames();
|
||||
hideTables();
|
||||
if (askToReconnect) {
|
||||
UserRequestMessage message = new UserRequestMessage("Connection lost", "The connection to server was lost. Reconnect to " + MagePreferences.getLastServerAddress() + "?");
|
||||
message.setButton1("No", null);
|
||||
message.setButton2("Yes", PlayerAction.CLIENT_RECONNECT);
|
||||
showUserRequestDialog(message);
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
hideServerLobby();
|
||||
if (askToReconnect) {
|
||||
UserRequestMessage message = new UserRequestMessage("Connection lost", "The connection to server was lost. Reconnect to " + MagePreferences.getLastServerAddress() + "?");
|
||||
message.setButton1("No", null);
|
||||
message.setButton2("Yes", PlayerAction.CLIENT_RECONNECT);
|
||||
showUserRequestDialog(message);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
@ -1539,8 +1610,13 @@ public class MageFrame extends javax.swing.JFrame implements MageClient {
|
|||
}
|
||||
|
||||
@Override
|
||||
public void processCallback(ClientCallback callback) {
|
||||
callbackClient.processCallback(callback);
|
||||
public void onCallback(ClientCallback callback) {
|
||||
callbackClient.onCallback(callback);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onNewConnection() {
|
||||
callbackClient.onNewConnection();
|
||||
}
|
||||
|
||||
public void sendUserReplay(PlayerAction playerAction, UserRequestMessage userRequestMessage) {
|
||||
|
|
@ -1551,13 +1627,11 @@ public class MageFrame extends javax.swing.JFrame implements MageClient {
|
|||
case CLIENT_DOWNLOAD_CARD_IMAGES:
|
||||
DownloadPicturesService.startDownload();
|
||||
break;
|
||||
case CLIENT_DISCONNECT:
|
||||
if (SessionHandler.isConnected()) {
|
||||
SessionHandler.disconnect(false);
|
||||
}
|
||||
tablesPane.clearChat();
|
||||
showMessage("You have disconnected");
|
||||
setWindowTitle();
|
||||
case CLIENT_DISCONNECT_FULL:
|
||||
doClientDisconnect(false, "You have disconnected");
|
||||
break;
|
||||
case CLIENT_DISCONNECT_KEEP_GAMES:
|
||||
doClientDisconnect(true, "You have disconnected and have few minutes to reconnect");
|
||||
break;
|
||||
case CLIENT_QUIT_TOURNAMENT:
|
||||
SessionHandler.quitTournament(userRequestMessage.getTournamentId());
|
||||
|
|
@ -1580,15 +1654,13 @@ public class MageFrame extends javax.swing.JFrame implements MageClient {
|
|||
}
|
||||
removeGame(userRequestMessage.getGameId());
|
||||
break;
|
||||
case CLIENT_EXIT:
|
||||
if (SessionHandler.isConnected()) {
|
||||
SessionHandler.disconnect(false);
|
||||
}
|
||||
CardRepository.instance.closeDB();
|
||||
tablesPane.cleanUp();
|
||||
Plugins.instance.shutdown();
|
||||
dispose();
|
||||
System.exit(0);
|
||||
case CLIENT_EXIT_FULL:
|
||||
doClientDisconnect(false, "");
|
||||
doClientShutdownAndExit();
|
||||
break;
|
||||
case CLIENT_EXIT_KEEP_GAMES:
|
||||
doClientDisconnect(true, "");
|
||||
doClientShutdownAndExit();
|
||||
break;
|
||||
case CLIENT_REMOVE_TABLE:
|
||||
SessionHandler.removeTable(userRequestMessage.getRoomId(), userRequestMessage.getTableId());
|
||||
|
|
@ -1609,6 +1681,26 @@ public class MageFrame extends javax.swing.JFrame implements MageClient {
|
|||
}
|
||||
}
|
||||
|
||||
private void doClientDisconnect(boolean keepMySessionActive, String afterMessage) {
|
||||
if (SessionHandler.isConnected()) {
|
||||
SessionHandler.disconnect(false, keepMySessionActive);
|
||||
}
|
||||
tablesPane.clearChat();
|
||||
setWindowTitle();
|
||||
|
||||
if (!afterMessage.isEmpty()) {
|
||||
showMessage(afterMessage);
|
||||
}
|
||||
}
|
||||
|
||||
private void doClientShutdownAndExit() {
|
||||
tablesPane.cleanUp();
|
||||
CardRepository.instance.closeDB();
|
||||
Plugins.instance.shutdown();
|
||||
dispose();
|
||||
System.exit(0);
|
||||
}
|
||||
|
||||
private void endTables() {
|
||||
for (UUID gameId : GAMES.keySet()) {
|
||||
SessionHandler.quitMatch(gameId);
|
||||
|
|
|
|||
|
|
@ -3,21 +3,19 @@
|
|||
import java.awt.*;
|
||||
|
||||
/**
|
||||
* GUI: basic class for all full screen frames/tabs (example: game pane, deck editor pane, card viewer, etc)
|
||||
*
|
||||
* @author BetaSteward_at_googlemail.com
|
||||
*/
|
||||
public abstract class MagePane extends javax.swing.JLayeredPane {
|
||||
|
||||
private String title = "no title set";
|
||||
|
||||
/**
|
||||
* Creates new form MagePane
|
||||
*/
|
||||
public MagePane() {
|
||||
initComponents();
|
||||
}
|
||||
|
||||
public void changeGUISize() {
|
||||
|
||||
}
|
||||
|
||||
public void setTitle(String title) {
|
||||
|
|
@ -53,6 +51,12 @@
|
|||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Active table: game pane, deck editor in sideboarding mode, etc
|
||||
* Non active table: client side panes like card viewer, deck viewer, etc
|
||||
*/
|
||||
abstract public boolean isActiveTable();
|
||||
|
||||
/**
|
||||
* This method is called from within the constructor to initialize the form.
|
||||
* WARNING: Do NOT modify this code. The content of this method is always
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@ import static mage.cards.decks.DeckFormats.XMAGE;
|
|||
import mage.client.chat.LocalCommands;
|
||||
import mage.client.constants.Constants.DeckEditorMode;
|
||||
import mage.client.dialog.PreferencesDialog;
|
||||
import mage.client.preference.MagePreferences;
|
||||
import mage.constants.ManaType;
|
||||
import mage.constants.PlayerAction;
|
||||
import mage.game.match.MatchOptions;
|
||||
|
|
@ -41,7 +42,6 @@ public final class SessionHandler {
|
|||
}
|
||||
|
||||
public static void startSession(MageFrame mageFrame) {
|
||||
|
||||
session = new SessionImpl(mageFrame);
|
||||
session.setJsonLogActive("true".equals(PreferencesDialog.getCachedValue(PreferencesDialog.KEY_JSON_GAME_LOG_AUTO_SAVE, "true")));
|
||||
}
|
||||
|
|
@ -64,10 +64,22 @@ public final class SessionHandler {
|
|||
|
||||
public static boolean connect(Connection connection) {
|
||||
lastConnectError = "";
|
||||
|
||||
// restore last used session
|
||||
String restoreSessionId = MagePreferences.findRestoreSession(connection.getHost(), connection.getUsername());
|
||||
if (!restoreSessionId.isEmpty()) {
|
||||
logger.info("Connect: trying to restore old session for user " + connection.getUsername());
|
||||
session.setRestoreSessionId(restoreSessionId);
|
||||
}
|
||||
|
||||
// connect
|
||||
if (session.connectStart(connection)) {
|
||||
// save current session for restore
|
||||
MagePreferences.saveRestoreSession(connection.getHost(), connection.getUsername(), getSessionId());
|
||||
return true;
|
||||
} else {
|
||||
lastConnectError = session.getLastError();
|
||||
disconnect(false, true);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
|
@ -80,8 +92,16 @@ public final class SessionHandler {
|
|||
return session.connectAbort();
|
||||
}
|
||||
|
||||
public static void disconnect(boolean showmessage) {
|
||||
session.connectStop(showmessage);
|
||||
public static void disconnect(boolean askForReconnect, boolean keepMySessionActive) {
|
||||
if (!keepMySessionActive) {
|
||||
String serverName = session.getServerHost();
|
||||
String userName = session.getUserName();
|
||||
if (!serverName.isEmpty() && !userName.isEmpty()) {
|
||||
MagePreferences.saveRestoreSession(serverName, userName, "");
|
||||
}
|
||||
}
|
||||
|
||||
session.connectStop(askForReconnect, keepMySessionActive);
|
||||
}
|
||||
|
||||
public static void sendPlayerAction(PlayerAction playerAction, UUID gameId, Object relatedUserId) {
|
||||
|
|
|
|||
|
|
@ -9,10 +9,9 @@ import mage.client.dialog.PreferencesDialog;
|
|||
import mage.client.plugins.adapters.MageActionCallback;
|
||||
import mage.client.plugins.impl.Plugins;
|
||||
import mage.client.util.ClientDefaultSettings;
|
||||
import mage.utils.SystemUtil;
|
||||
import mage.util.ThreadUtils;
|
||||
import mage.view.CardView;
|
||||
|
||||
import javax.swing.*;
|
||||
import java.awt.*;
|
||||
import java.util.UUID;
|
||||
|
||||
|
|
@ -107,7 +106,7 @@ public class VirtualCardInfo {
|
|||
}
|
||||
|
||||
public boolean prepared() {
|
||||
SystemUtil.ensureRunInGUISwingThread();
|
||||
ThreadUtils.ensureRunInGUISwingThread();
|
||||
|
||||
return this.cardView != null
|
||||
&& this.cardComponent != null
|
||||
|
|
|
|||
|
|
@ -37,7 +37,7 @@ public final class LocalCommands {
|
|||
return false;
|
||||
}
|
||||
|
||||
final String serverAddress = SessionHandler.getSession().getServerHostname().orElse("");
|
||||
final String serverAddress = SessionHandler.getSession().getServerHost();
|
||||
Optional<String> response = Optional.empty();
|
||||
|
||||
String command = st.nextToken();
|
||||
|
|
@ -69,6 +69,6 @@ public final class LocalCommands {
|
|||
final String text = new StringBuilder().append("<font color=yellow>").append(response).append("</font>").toString();
|
||||
ClientCallback chatMessage = new ClientCallback(ClientCallbackMethod.CHATMESSAGE, chatId,
|
||||
new ChatMessage("", text, new Date(), null, ChatMessage.MessageColor.BLUE));
|
||||
MageFrame.getInstance().processCallback(chatMessage);
|
||||
MageFrame.getInstance().onCallback(chatMessage);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -11,7 +11,6 @@ import mage.client.game.GamePanel;
|
|||
import mage.game.command.Plane;
|
||||
import mage.util.CardUtil;
|
||||
import mage.util.GameLog;
|
||||
import mage.utils.ThreadUtils;
|
||||
import mage.view.CardView;
|
||||
import mage.view.PlaneView;
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
package mage.client.components;
|
||||
|
||||
import mage.utils.ThreadUtils;
|
||||
import mage.util.ThreadUtils;
|
||||
import org.apache.log4j.Logger;
|
||||
|
||||
import java.awt.Component;
|
||||
|
|
|
|||
|
|
@ -12,13 +12,14 @@ import java.util.Map;
|
|||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
* GUI: deck editor, used all around the app
|
||||
*
|
||||
* @author BetaSteward_at_googlemail.com
|
||||
*/
|
||||
public class DeckEditorPane extends MagePane {
|
||||
|
||||
/**
|
||||
* Creates new form TablesPane
|
||||
*/
|
||||
private UUID tableId = null;
|
||||
|
||||
public DeckEditorPane() {
|
||||
boolean initialized = false;
|
||||
if (Plugins.instance.isThemePluginLoaded()) {
|
||||
|
|
@ -45,6 +46,7 @@ public class DeckEditorPane extends MagePane {
|
|||
}
|
||||
|
||||
public void show(DeckEditorMode mode, Deck deck, String name, UUID tableId, int time) {
|
||||
this.tableId = tableId;
|
||||
if (mode == DeckEditorMode.SIDEBOARDING
|
||||
|| mode == DeckEditorMode.LIMITED_BUILDING
|
||||
|| mode == DeckEditorMode.LIMITED_SIDEBOARD_BUILDING) {
|
||||
|
|
@ -60,6 +62,11 @@ public class DeckEditorPane extends MagePane {
|
|||
this.repaint();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isActiveTable() {
|
||||
return this.tableId != null;
|
||||
}
|
||||
|
||||
public DeckEditorMode getDeckEditorMode() {
|
||||
return this.deckEditorPanel1.getDeckEditorMode();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -52,6 +52,11 @@ public class CollectionViewerPane extends MagePane {
|
|||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isActiveTable() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setVisible(boolean aFlag) {
|
||||
super.setVisible(aFlag);
|
||||
|
|
|
|||
|
|
@ -1,6 +1,5 @@
|
|||
package mage.client.dialog;
|
||||
|
||||
import mage.cards.repository.RepositoryUtil;
|
||||
import mage.choices.Choice;
|
||||
import mage.choices.ChoiceImpl;
|
||||
import mage.client.MageFrame;
|
||||
|
|
@ -8,10 +7,8 @@ import mage.client.SessionHandler;
|
|||
import mage.client.preference.MagePreferences;
|
||||
import mage.client.util.ClientDefaultSettings;
|
||||
import mage.client.util.gui.countryBox.CountryItemEditor;
|
||||
import mage.client.util.sets.ConstructedFormats;
|
||||
import mage.remote.Connection;
|
||||
import mage.utils.StreamUtils;
|
||||
import mage.utils.ThreadUtils;
|
||||
import org.apache.log4j.Logger;
|
||||
|
||||
import javax.swing.*;
|
||||
|
|
@ -702,7 +699,7 @@ public class ConnectDialog extends MageDialog {
|
|||
// so the connection dialog will be visible all that time
|
||||
SwingUtilities.invokeLater(() -> {
|
||||
doAfterConnected();
|
||||
MageFrame.getInstance().prepareAndShowTablesPane();
|
||||
MageFrame.getInstance().prepareAndShowServerLobby();
|
||||
btnConnect.setEnabled(true);
|
||||
});
|
||||
} else {
|
||||
|
|
|
|||
|
|
@ -602,7 +602,7 @@ public class NewTableDialog extends MageDialog {
|
|||
options.setQuitRatio((Integer) this.spnQuitRatio.getValue());
|
||||
options.setMinimumRating((Integer) this.spnMinimumRating.getValue());
|
||||
options.setEdhPowerLevel((Integer) this.spnEdhPowerLevel.getValue());
|
||||
String serverAddress = SessionHandler.getSession().getServerHostname().orElse("");
|
||||
String serverAddress = SessionHandler.getSession().getServerHost();
|
||||
options.setBannedUsers(IgnoreList.getIgnoredUsers(serverAddress));
|
||||
options.setLimited(options.getDeckType().startsWith("Limited"));
|
||||
if (options.getDeckType().startsWith("Variant Magic - Freeform Unlimited Commander")) {
|
||||
|
|
|
|||
|
|
@ -1322,7 +1322,7 @@ public class NewTournamentDialog extends MageDialog {
|
|||
}
|
||||
}
|
||||
|
||||
String serverAddress = SessionHandler.getSession().getServerHostname().orElse("");
|
||||
String serverAddress = SessionHandler.getSession().getServerHost();
|
||||
tOptions.getMatchOptions().setBannedUsers(IgnoreList.getIgnoredUsers(serverAddress));
|
||||
|
||||
tOptions.getMatchOptions().setMatchTimeLimit((MatchTimeLimit) this.cbTimeLimit.getSelectedItem());
|
||||
|
|
|
|||
|
|
@ -10,7 +10,8 @@ import javax.swing.plaf.basic.BasicInternalFrameUI;
|
|||
import java.awt.*;
|
||||
|
||||
/**
|
||||
* App GUI: confirm some actions from the user (example: close the app)
|
||||
* GUI: global window message with additional action to choose (example: close the app)
|
||||
* Can be used in any places (in games, in app, etc)
|
||||
*
|
||||
* @author BetaSteward_at_googlemail.com
|
||||
*/
|
||||
|
|
@ -74,6 +75,17 @@ public class UserRequestDialog extends MageDialog {
|
|||
} else {
|
||||
this.btn3.setVisible(false);
|
||||
}
|
||||
|
||||
// improved auto-size
|
||||
// height looks bad, so change only width
|
||||
this.pack();
|
||||
Dimension newPreferedSize = new Dimension(this.getPreferredSize());
|
||||
newPreferedSize.setSize(
|
||||
newPreferedSize.width * userRequestMessage.getWindowSizeRatio(),
|
||||
newPreferedSize.height/* * userRequestMessage.getWindowSizeRatio()*/
|
||||
);
|
||||
this.setPreferredSize(newPreferedSize);
|
||||
|
||||
this.pack();
|
||||
this.revalidate();
|
||||
this.repaint();
|
||||
|
|
@ -177,7 +189,7 @@ public class UserRequestDialog extends MageDialog {
|
|||
}//GEN-LAST:event_btn3ActionPerformed
|
||||
|
||||
private void sendUserReplay(PlayerAction playerAction) {
|
||||
MageFrame.getInstance().sendUserReplay(playerAction, userRequestMessage);
|
||||
SwingUtilities.invokeLater(() ->MageFrame.getInstance().sendUserReplay(playerAction, userRequestMessage));
|
||||
}
|
||||
|
||||
// Variables declaration - do not modify//GEN-BEGIN:variables
|
||||
|
|
|
|||
|
|
@ -9,15 +9,14 @@ import mage.client.MagePane;
|
|||
import mage.client.plugins.impl.Plugins;
|
||||
|
||||
/**
|
||||
* Game GUI: draft panel with scrolls
|
||||
* Game GUI: draft frame
|
||||
*
|
||||
* @author BetaSteward_at_googlemail.com
|
||||
*/
|
||||
public class DraftPane extends MagePane {
|
||||
|
||||
/**
|
||||
* Creates new form DraftPane
|
||||
*/
|
||||
UUID draftId = null;
|
||||
|
||||
public DraftPane() {
|
||||
boolean initialized = false;
|
||||
if (Plugins.instance.isThemePluginLoaded()) {
|
||||
|
|
@ -44,10 +43,16 @@ public class DraftPane extends MagePane {
|
|||
}
|
||||
|
||||
public void showDraft(UUID draftId) {
|
||||
this.draftId = draftId;
|
||||
this.setTitle("Draft - " + draftId);
|
||||
this.draftPanel1.showDraft(draftId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isActiveTable() {
|
||||
return this.draftId != null;
|
||||
}
|
||||
|
||||
public void removeDraft() {
|
||||
draftPanel1.cleanUp();
|
||||
this.removeFrame();
|
||||
|
|
|
|||
|
|
@ -92,7 +92,7 @@ public class BattlefieldPanel extends javax.swing.JLayeredPane {
|
|||
gameUpdateTimer = new Timer(GAME_REDRAW_TIMEOUT_MS, evt -> SwingUtilities.invokeLater(() -> {
|
||||
gameUpdateTimer.stop();
|
||||
ClientCallback updateMessage = new ClientCallback(ClientCallbackMethod.GAME_REDRAW_GUI, gameId);
|
||||
MageFrame.getInstance().processCallback(updateMessage);
|
||||
MageFrame.getInstance().onCallback(updateMessage);
|
||||
}));
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ import javax.swing.*;
|
|||
import mage.client.MagePane;
|
||||
|
||||
/**
|
||||
* Game GUI: game panel with scrollbars
|
||||
* Game GUI: game frame (game panel with scrolls)
|
||||
*
|
||||
* @author BetaSteward_at_googlemail.com
|
||||
*/
|
||||
|
|
@ -31,6 +31,11 @@ public class GamePane extends MagePane {
|
|||
gamePanel.showGame(gameId, playerId, this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isActiveTable() {
|
||||
return this.gameId != null;
|
||||
}
|
||||
|
||||
public void cleanUp() {
|
||||
gamePanel.cleanUp();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1469,6 +1469,10 @@ public final class GamePanel extends javax.swing.JPanel {
|
|||
this.feedbackPanel.prepareFeedback(FeedbackMode.QUESTION, question, false, options, true, gameView.getPhase());
|
||||
}
|
||||
|
||||
public boolean isMissGameData() {
|
||||
return lastGameData.game == null || lastGameData.game.getPlayers().isEmpty();
|
||||
}
|
||||
|
||||
private void keepLastGameData(int messageId, GameView game, boolean showPlayable, Map<String, Serializable> options, Set<UUID> targets) {
|
||||
lastGameData.messageId = messageId;
|
||||
lastGameData.setNewGame(game);
|
||||
|
|
|
|||
|
|
@ -585,7 +585,7 @@ public class PlayerPanelExt extends javax.swing.JPanel {
|
|||
resized = ImageHelper.getResizedImage(BufferedImageBuilder.bufferImage(image, BufferedImage.TYPE_INT_ARGB), r);
|
||||
cheat = new JButton();
|
||||
cheat.setIcon(new ImageIcon(resized));
|
||||
cheat.setToolTipText("Cheat button");
|
||||
cheat.setToolTipText("Cheat button (activate it on your priority only)");
|
||||
cheat.addActionListener(e -> btnCheatActionPerformed(e));
|
||||
|
||||
// tools button like hints
|
||||
|
|
|
|||
|
|
@ -23,7 +23,7 @@ import mage.components.CardInfoPane;
|
|||
import mage.constants.EnlargeMode;
|
||||
import mage.constants.Zone;
|
||||
import mage.util.DebugUtil;
|
||||
import mage.utils.ThreadUtils;
|
||||
import mage.util.ThreadUtils;
|
||||
import mage.view.CardView;
|
||||
import mage.view.PermanentView;
|
||||
import org.apache.log4j.Logger;
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@ import com.google.common.collect.Sets;
|
|||
import mage.client.MageFrame;
|
||||
import mage.client.util.ClientDefaultSettings;
|
||||
|
||||
import java.util.Date;
|
||||
import java.util.Set;
|
||||
import java.util.prefs.BackingStoreException;
|
||||
import java.util.prefs.Preferences;
|
||||
|
|
@ -18,6 +19,7 @@ public final class MagePreferences {
|
|||
private static final String KEY_EMAIL = "email";
|
||||
private static final String KEY_AUTO_CONNECT = "autoConnect";
|
||||
private static final String NODE_KEY_IGNORE_LIST = "ignoreListString";
|
||||
private static final String NODE_KEY_RESTORE_SESSIONS_LIST = "restoreSessionsListString";
|
||||
|
||||
private static String lastServerAddress = "";
|
||||
private static int lastServerPort = 0;
|
||||
|
|
@ -64,6 +66,7 @@ public final class MagePreferences {
|
|||
return userName;
|
||||
}
|
||||
// For clients older than 1.4.7, userName is stored without a serverAddress prefix.
|
||||
// TODO: outdated code, can be removed, 2023-12-05
|
||||
return prefs().get(KEY_USER_NAME, "");
|
||||
}
|
||||
|
||||
|
|
@ -143,6 +146,19 @@ public final class MagePreferences {
|
|||
return prefs().node(NODE_KEY_IGNORE_LIST).node(serverAddress);
|
||||
}
|
||||
|
||||
private static Preferences restoreSessionsListNode(String serverAddress) {
|
||||
return prefs().node(NODE_KEY_RESTORE_SESSIONS_LIST).node(serverAddress);
|
||||
}
|
||||
|
||||
public static void saveRestoreSession(String serverAddress, String userName, String sessionId) {
|
||||
restoreSessionsListNode(serverAddress).put(userName, sessionId);
|
||||
restoreSessionsListNode(serverAddress).putLong("lastUpdated", new Date().getTime());
|
||||
}
|
||||
|
||||
public static String findRestoreSession(String serverAddress, String userName) {
|
||||
return restoreSessionsListNode(serverAddress).get(userName, "");
|
||||
}
|
||||
|
||||
public static void saveLastServer() {
|
||||
lastServerAddress = getServerAddressWithDefault(ClientDefaultSettings.serverName);
|
||||
lastServerPort = getServerPortWithDefault(ClientDefaultSettings.port);
|
||||
|
|
|
|||
|
|
@ -28,31 +28,52 @@ import java.awt.event.KeyEvent;
|
|||
import java.util.*;
|
||||
|
||||
/**
|
||||
* @author BetaSteward_at_googlemail.com
|
||||
* @author BetaSteward_at_googlemail.com, JayDi85
|
||||
*/
|
||||
public class CallbackClientImpl implements CallbackClient {
|
||||
|
||||
private static final Logger logger = Logger.getLogger(CallbackClientImpl.class);
|
||||
|
||||
private static final boolean DEBUG_CALLBACK_MESSAGES_LOG = false; // show all callback messages (server commands)
|
||||
|
||||
private final MageFrame frame;
|
||||
private final Map<ClientCallbackType, Integer> lastMessages;
|
||||
private final Map<UUID, GameClientMessage> firstGameData;
|
||||
|
||||
public CallbackClientImpl(MageFrame frame) {
|
||||
this.frame = frame;
|
||||
this.lastMessages = new HashMap<>();
|
||||
this.firstGameData = new HashMap<>();
|
||||
Arrays.stream(ClientCallbackType.values()).forEach(t -> this.lastMessages.put(t, 0));
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized void processCallback(final ClientCallback callback) {
|
||||
public void onNewConnection() {
|
||||
// must clean temp data for each new connection
|
||||
this.lastMessages.clear();
|
||||
this.firstGameData.clear();
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized void onCallback(final ClientCallback callback) {
|
||||
callback.decompressData();
|
||||
|
||||
// put replay related code here
|
||||
SaveObjectUtil.saveObject(callback.getData(), callback.getMethod().toString());
|
||||
|
||||
// reconnect fix with miss data, part 1 of 2
|
||||
// on reconnect many events can come in diff order, so init GameView data with first available info
|
||||
// game_start event can come after game view - must save it here (part 1) before real use in swing thread (part 2)
|
||||
if (callback.getData() instanceof GameClientMessage) {
|
||||
firstGameData.putIfAbsent(callback.getObjectId(), (GameClientMessage) callback.getData());
|
||||
}
|
||||
|
||||
// all GUI related code must be executed in swing thread
|
||||
SwingUtilities.invokeLater(() -> {
|
||||
try {
|
||||
logger.debug("message " + callback.getMessageId() + " - " + callback.getMethod().getType() + " - " + callback.getMethod());
|
||||
if (DEBUG_CALLBACK_MESSAGES_LOG) {
|
||||
logger.info("message " + callback.getMessageId() + " - " + callback.getMethod().getType() + " - " + callback.getMethod());
|
||||
}
|
||||
|
||||
// process bad connection (events can income in wrong order, so outdated data must be ignored)
|
||||
// - table/dialog events like game start, game end, choose dialog - must be processed anyway
|
||||
|
|
@ -92,6 +113,24 @@ public class CallbackClientImpl implements CallbackClient {
|
|||
TableClientMessage message = (TableClientMessage) callback.getData();
|
||||
GameManager.instance.setCurrentPlayerUUID(message.getPlayerId());
|
||||
gameStarted(callback.getMessageId(), message.getGameId(), message.getPlayerId());
|
||||
|
||||
// reconnect fix with miss data, part 2 of 2
|
||||
// START_GAME event can come after GAME_INIT or any other, so must force update with first info
|
||||
// START_GAME even raises before a real game start, so it hasn't GameView in payload
|
||||
GamePanel gamePanel = MageFrame.getGame(callback.getObjectId());
|
||||
if (gamePanel != null && gamePanel.isMissGameData()) {
|
||||
GameClientMessage mes = firstGameData.getOrDefault(callback.getObjectId(), null);
|
||||
if (mes != null) {
|
||||
logger.warn("Found miss game data, requesting latest info... (possible reason: reconnect)");
|
||||
gamePanel.init(callback.getMessageId(), mes.getGameView(), true);
|
||||
// ask server to resent latest data
|
||||
// TODO: replace by special async request like requestGameUpdate
|
||||
SessionHandler.sendPlayerUUID(callback.getObjectId(), UUID.randomUUID());
|
||||
} else {
|
||||
// it's ok, new game come here
|
||||
// logger.error("Found miss game data, but can't find any usefull info (report to developers)");
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
@ -101,12 +140,6 @@ public class CallbackClientImpl implements CallbackClient {
|
|||
break;
|
||||
}
|
||||
|
||||
case START_DRAFT: {
|
||||
TableClientMessage message = (TableClientMessage) callback.getData();
|
||||
draftStarted(callback.getMessageId(), message.getGameId(), message.getPlayerId());
|
||||
break;
|
||||
}
|
||||
|
||||
case REPLAY_GAME: {
|
||||
replayGame(callback.getObjectId());
|
||||
break;
|
||||
|
|
@ -126,7 +159,7 @@ public class CallbackClientImpl implements CallbackClient {
|
|||
ChatMessage message = (ChatMessage) callback.getData();
|
||||
// Drop messages from ignored users
|
||||
if (message.getUsername() != null && IgnoreList.IGNORED_MESSAGE_TYPES.contains(message.getMessageType())) {
|
||||
final String serverAddress = SessionHandler.getSession().getServerHostname().orElse("");
|
||||
final String serverAddress = SessionHandler.getSession().getServerHost();
|
||||
if (IgnoreList.userIsIgnored(serverAddress, message.getUsername())) {
|
||||
break;
|
||||
}
|
||||
|
|
@ -426,6 +459,12 @@ public class CallbackClientImpl implements CallbackClient {
|
|||
break;
|
||||
}
|
||||
|
||||
case START_DRAFT: {
|
||||
TableClientMessage message = (TableClientMessage) callback.getData();
|
||||
draftStarted(callback.getMessageId(), message.getGameId(), message.getPlayerId());
|
||||
break;
|
||||
}
|
||||
|
||||
case DRAFT_OVER: {
|
||||
MageFrame.removeDraft(callback.getObjectId());
|
||||
break;
|
||||
|
|
@ -544,7 +583,7 @@ public class CallbackClientImpl implements CallbackClient {
|
|||
null, null, MessageType.USER_INFO, ChatMessage.MessageColor.BLUE);
|
||||
break;
|
||||
case TABLES:
|
||||
String serverAddress = SessionHandler.getSession().getServerHostname().orElse("");
|
||||
String serverAddress = SessionHandler.getSession().getServerHost();
|
||||
usedPanel.receiveMessage("", new StringBuilder("Download card images by using the \"Images\" main menu.")
|
||||
.append("<br/>Download icons and symbols by using the \"Symbols\" main menu.")
|
||||
.append("<br/>\\list - show a list of available chat commands.")
|
||||
|
|
|
|||
|
|
@ -1,4 +1,3 @@
|
|||
|
||||
package mage.client.table;
|
||||
|
||||
import java.util.UUID;
|
||||
|
|
@ -9,14 +8,14 @@ import mage.client.SessionHandler;
|
|||
import mage.client.plugins.impl.Plugins;
|
||||
|
||||
/**
|
||||
* Game GUI: lobby frame
|
||||
*
|
||||
* @author BetaSteward_at_googlemail.com
|
||||
*/
|
||||
public class TablesPane extends MagePane {
|
||||
|
||||
/**
|
||||
* Creates new form TablesPane
|
||||
*/
|
||||
UUID roomId = null;
|
||||
|
||||
public TablesPane() {
|
||||
boolean initialized = false;
|
||||
if (Plugins.instance.isThemePluginLoaded()) {
|
||||
|
|
@ -47,11 +46,17 @@ public class TablesPane extends MagePane {
|
|||
public void showTables() {
|
||||
UUID roomId = SessionHandler.getSession().getMainRoomId();
|
||||
if (roomId != null) {
|
||||
this.setTitle("Tables");
|
||||
this.roomId = roomId;
|
||||
this.setTitle("Server's lobby");
|
||||
tablesPanel.showTables(roomId);
|
||||
this.repaint();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isActiveTable() {
|
||||
// it's defalt server lobby, so don't count it as active
|
||||
return false;
|
||||
}
|
||||
|
||||
public void hideTables() {
|
||||
|
|
|
|||
|
|
@ -940,7 +940,7 @@ public class TablesPanel extends javax.swing.JPanel {
|
|||
|
||||
// Hide games of ignored players
|
||||
java.util.List<RowFilter<Object, Object>> ignoreListFilterList = new ArrayList<>();
|
||||
String serverAddress = SessionHandler.getSession().getServerHostname().orElse("");
|
||||
String serverAddress = SessionHandler.getSession().getServerHost();
|
||||
final Set<String> ignoreListCopy = IgnoreList.getIgnoredUsers(serverAddress);
|
||||
if (!ignoreListCopy.isEmpty()) {
|
||||
ignoreListFilterList.add(new RowFilter<Object, Object>() {
|
||||
|
|
@ -1718,7 +1718,7 @@ public class TablesPanel extends javax.swing.JPanel {
|
|||
options.setRollbackTurnsAllowed(true);
|
||||
options.setQuitRatio(100);
|
||||
options.setMinimumRating(0);
|
||||
String serverAddress = SessionHandler.getSession().getServerHostname().orElse("");
|
||||
String serverAddress = SessionHandler.getSession().getServerHost();
|
||||
options.setBannedUsers(IgnoreList.getIgnoredUsers(serverAddress));
|
||||
table = SessionHandler.createTable(roomId, options);
|
||||
|
||||
|
|
|
|||
|
|
@ -4,24 +4,30 @@ import java.util.UUID;
|
|||
import mage.client.MagePane;
|
||||
|
||||
/**
|
||||
* Game GUI: tournament frame
|
||||
*
|
||||
* @author BetaSteward_at_googlemail.com
|
||||
*/
|
||||
public class TournamentPane extends MagePane {
|
||||
|
||||
/**
|
||||
* Creates new form TournamentPane
|
||||
*/
|
||||
UUID tournamentId = null;
|
||||
|
||||
public TournamentPane() {
|
||||
initComponents();
|
||||
}
|
||||
|
||||
public void showTournament(UUID tournamentId) {
|
||||
this.tournamentId = tournamentId;
|
||||
this.setTitle("Tournament " + tournamentId);
|
||||
this.tournamentPanel.showTournament(tournamentId);
|
||||
this.repaint();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isActiveTable() {
|
||||
return this.tournamentId != null;
|
||||
}
|
||||
|
||||
public void removeTournament() {
|
||||
tournamentPanel.cleanUp();
|
||||
removeFrame();
|
||||
|
|
|
|||
|
|
@ -53,15 +53,15 @@ public final class IgnoreList {
|
|||
}
|
||||
|
||||
MagePreferences.addIgnoredUser(serverAddress, user);
|
||||
updateTablesTable();
|
||||
updateServerLobbyTables();
|
||||
|
||||
return "Added " + user + " to your ignore list on " + serverAddress + " (total: " + getIgnoredUsers(serverAddress).size() + ")";
|
||||
}
|
||||
|
||||
private static void updateTablesTable() {
|
||||
private static void updateServerLobbyTables() {
|
||||
MageFrame mageFrame = MageFrame.getInstance();
|
||||
if (mageFrame != null) {
|
||||
mageFrame.setTableFilter();
|
||||
mageFrame.setServerLobbyTablesFilter();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -70,7 +70,7 @@ public final class IgnoreList {
|
|||
return usage(serverAddress);
|
||||
}
|
||||
if (MagePreferences.removeIgnoredUser(serverAddress, user)) {
|
||||
updateTablesTable();
|
||||
updateServerLobbyTables();
|
||||
return "Removed " + user + " from your ignore list on " + serverAddress + " (total: " + getIgnoredUsers(serverAddress).size() + ")";
|
||||
} else {
|
||||
return "No such user \"" + user + "\" on your ignore list on " + serverAddress + " (total: " + getIgnoredUsers(serverAddress).size() + ")";
|
||||
|
|
|
|||
|
|
@ -19,7 +19,7 @@ import javax.sound.sampled.SourceDataLine;
|
|||
|
||||
import org.apache.log4j.Logger;
|
||||
|
||||
import mage.utils.ThreadUtils;
|
||||
import mage.util.ThreadUtils;
|
||||
|
||||
public class LinePool {
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue