mirror of
https://github.com/correl/mage.git
synced 2024-11-25 03:00:11 +00:00
* Game: improved fix command (more info and fixes);
* Game: improved game startup message (more info about private messages and players stats);
This commit is contained in:
parent
b59c8b663d
commit
58d7a96031
4 changed files with 119 additions and 63 deletions
|
@ -399,7 +399,8 @@ public class CallbackClientImpl implements CallbackClient {
|
||||||
}
|
}
|
||||||
switch (usedPanel.getChatType()) {
|
switch (usedPanel.getChatType()) {
|
||||||
case GAME:
|
case GAME:
|
||||||
usedPanel.receiveMessage("", new StringBuilder("You may use hot keys to play faster:")
|
usedPanel.receiveMessage("", new StringBuilder()
|
||||||
|
.append("HOTKEYS:")
|
||||||
.append("<br/>Turn mousewheel up (ALT-e) - enlarge image of card the mousepointer hovers over")
|
.append("<br/>Turn mousewheel up (ALT-e) - enlarge image of card the mousepointer hovers over")
|
||||||
.append("<br/>Turn mousewheel down (ALT-s) - enlarge original/alternate image of card the mousepointer hovers over")
|
.append("<br/>Turn mousewheel down (ALT-s) - enlarge original/alternate image of card the mousepointer hovers over")
|
||||||
.append("<br/><b>")
|
.append("<br/><b>")
|
||||||
|
@ -429,12 +430,19 @@ public class CallbackClientImpl implements CallbackClient {
|
||||||
.append("<br/><b>")
|
.append("<br/><b>")
|
||||||
.append(KeyEvent.getKeyText(PreferencesDialog.getCurrentControlKey(PreferencesDialog.KEY_CONTROL_SWITCH_CHAT)))
|
.append(KeyEvent.getKeyText(PreferencesDialog.getCurrentControlKey(PreferencesDialog.KEY_CONTROL_SWITCH_CHAT)))
|
||||||
.append("</b> - Switth in/out to chat text field")
|
.append("</b> - Switth in/out to chat text field")
|
||||||
|
/*
|
||||||
.append("<br/><b>")
|
.append("<br/><b>")
|
||||||
.append(KeyEvent.getKeyText(PreferencesDialog.getCurrentControlKey(PreferencesDialog.KEY_CONTROL_TOGGLE_MACRO)))
|
.append(KeyEvent.getKeyText(PreferencesDialog.getCurrentControlKey(PreferencesDialog.KEY_CONTROL_TOGGLE_MACRO)))
|
||||||
.append("</b> - Toggle recording a sequence of actions to repeat. Will not pause if interrupted and can fail if a selected card changes such as when scrying top card to bottom.")
|
.append("</b> - Toggle recording a sequence of actions to repeat. Will not pause if interrupted and can fail if a selected card changes such as when scrying top card to bottom.")
|
||||||
.append("<br/><b>").append(System.getProperty("os.name").contains("Mac OS X") ? "Cmd" : "Ctrl").append(" + click</b> - Hold priority while casting a spell or activating an ability")
|
.append("<br/><b>").append(System.getProperty("os.name").contains("Mac OS X") ? "Cmd" : "Ctrl").append(" + click</b> - Hold priority while casting a spell or activating an ability")
|
||||||
.append("<br/>").append("Type <b>/fix</b> message in chat to fix freezed game")
|
*/
|
||||||
.append("<br/>").append("Type <b>/pings</b> message in chat to show players and watchers ping")
|
.append("<br/>")
|
||||||
|
.append("<br/>")
|
||||||
|
.append("CHAT COMMANDS:")
|
||||||
|
.append("<br/>").append("<b>/h username </b> - show player's stats (history)")
|
||||||
|
.append("<br/>").append("<b>/w username message</b> - send private message to player (whisper)")
|
||||||
|
.append("<br/>").append("<b>/pings</b> - show players and watchers ping")
|
||||||
|
.append("<br/>").append("<b>/fix</b> - fix freezed game")
|
||||||
.toString(),
|
.toString(),
|
||||||
null, MessageType.USER_INFO, ChatMessage.MessageColor.BLUE);
|
null, MessageType.USER_INFO, ChatMessage.MessageColor.BLUE);
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -232,7 +232,7 @@ public enum ChatManager {
|
||||||
if (entry.getKey().equals(id)) {
|
if (entry.getKey().equals(id)) {
|
||||||
GameController controller = entry.getValue();
|
GameController controller = entry.getValue();
|
||||||
if (controller != null) {
|
if (controller != null) {
|
||||||
message += controller.attemptToFixGame();
|
message += controller.attemptToFixGame(user);
|
||||||
chatSessions.get(chatId).broadcastInfoToUser(user, message);
|
chatSessions.get(chatId).broadcastInfoToUser(user, message);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -37,7 +37,6 @@ public class User {
|
||||||
private static final Logger logger = Logger.getLogger(User.class);
|
private static final Logger logger = Logger.getLogger(User.class);
|
||||||
|
|
||||||
public enum UserState {
|
public enum UserState {
|
||||||
|
|
||||||
Created, // Used if user is created an not connected to the session
|
Created, // Used if user is created an not connected to the session
|
||||||
Connected, // Used if user is correctly connected
|
Connected, // Used if user is correctly connected
|
||||||
Disconnected, // Used if the user lost connection
|
Disconnected, // Used if the user lost connection
|
||||||
|
|
|
@ -1185,7 +1185,7 @@ public class GameController implements GameCallback {
|
||||||
}
|
}
|
||||||
|
|
||||||
private String getName(Player player) {
|
private String getName(Player player) {
|
||||||
return player != null ? player.getName() : "-";
|
return player != null ? player.getName() : "none";
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getPingsInfo() {
|
public String getPingsInfo() {
|
||||||
|
@ -1211,7 +1211,19 @@ public class GameController implements GameCallback {
|
||||||
return String.join("<br>", usersInfo);
|
return String.join("<br>", usersInfo);
|
||||||
}
|
}
|
||||||
|
|
||||||
public String attemptToFixGame() {
|
private String asGood(String text) {
|
||||||
|
return "<font color='green'><b>" + text + "</b></font>";
|
||||||
|
}
|
||||||
|
|
||||||
|
private String asBad(String text) {
|
||||||
|
return "<font color='red'><b>" + text + "</b></font>";
|
||||||
|
}
|
||||||
|
|
||||||
|
private String asWarning(String text) {
|
||||||
|
return "<font color='aqua'><b>" + text + "</b></font>";
|
||||||
|
}
|
||||||
|
|
||||||
|
public String attemptToFixGame(User user) {
|
||||||
// try to fix disconnects
|
// try to fix disconnects
|
||||||
|
|
||||||
if (game == null) {
|
if (game == null) {
|
||||||
|
@ -1222,7 +1234,7 @@ public class GameController implements GameCallback {
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
|
|
||||||
logger.warn("FIX command was called for game " + game.getId() + " - players: " +
|
logger.warn("FIX command was called by " + user.getName() + " for game " + game.getId() + " - players: " +
|
||||||
game.getPlayerList().stream()
|
game.getPlayerList().stream()
|
||||||
.map(game::getPlayer)
|
.map(game::getPlayer)
|
||||||
.filter(Objects::nonNull)
|
.filter(Objects::nonNull)
|
||||||
|
@ -1230,100 +1242,137 @@ public class GameController implements GameCallback {
|
||||||
.collect(Collectors.joining(", ")));
|
.collect(Collectors.joining(", ")));
|
||||||
|
|
||||||
StringBuilder sb = new StringBuilder();
|
StringBuilder sb = new StringBuilder();
|
||||||
sb.append("<br/>Game State:<br/><font size=-2>");
|
sb.append("<font color='red'>FIX command called by " + user.getName() + "</font>");
|
||||||
sb.append(state);
|
sb.append("<font size='-2'>"); // font resize start for all next logs
|
||||||
|
sb.append("<br>Game ID: " + game.getId());
|
||||||
|
|
||||||
|
// pings info
|
||||||
|
sb.append("<br>");
|
||||||
|
sb.append(getPingsInfo());
|
||||||
|
|
||||||
boolean fixedAlready = false;
|
boolean fixedAlready = false;
|
||||||
|
|
||||||
Player activePlayer = game.getPlayer(state.getActivePlayerId());
|
|
||||||
|
|
||||||
List<String> fixActions = new ArrayList<>(); // for logs info
|
List<String> fixActions = new ArrayList<>(); // for logs info
|
||||||
|
|
||||||
// fix active
|
// fix active
|
||||||
sb.append("<br>Checking active player: " + getName(activePlayer));
|
Player playerActive = game.getPlayer(state.getActivePlayerId());
|
||||||
if (activePlayer != null && activePlayer.hasLeft()) {
|
sb.append("<br>Fixing active player: " + getName(playerActive));
|
||||||
fixActions.add("active player");
|
if (playerActive != null && !playerActive.canRespond()) {
|
||||||
sb.append("<br>Found disconnected player! Concede...");
|
fixActions.add("active player fix");
|
||||||
activePlayer.concede(game);
|
|
||||||
activePlayer.leave(); // abort any wait response actions
|
|
||||||
|
|
||||||
|
sb.append("<br><font color='red'>WARNING, active player can't respond.</font>");
|
||||||
|
sb.append("<br>Try to concede...");
|
||||||
|
playerActive.concede(game);
|
||||||
|
playerActive.leave(); // abort any wait response actions
|
||||||
|
sb.append(" (" + asWarning("OK") + ", concede done)");
|
||||||
|
|
||||||
|
sb.append("<br>Try to skip step...");
|
||||||
Phase currentPhase = game.getPhase();
|
Phase currentPhase = game.getPhase();
|
||||||
if (currentPhase != null) {
|
if (currentPhase != null) {
|
||||||
currentPhase.getStep().skipStep(game, state.getActivePlayerId());
|
currentPhase.getStep().skipStep(game, state.getActivePlayerId());
|
||||||
sb.append("<br>Forcibly passing the phase!");
|
|
||||||
fixedAlready = true;
|
fixedAlready = true;
|
||||||
|
sb.append(" (" + asWarning("OK") + ", skip step done)");
|
||||||
} else {
|
} else {
|
||||||
sb.append("<br>Current phase null");
|
sb.append(" (" + asBad("FAIL") + ", step is null)");
|
||||||
}
|
}
|
||||||
sb.append("<br>Active player has left");
|
} else {
|
||||||
|
sb.append(playerActive != null ? " (" + asGood("OK") + ", can respond)" : " (" + asGood("OK") + ", no player)");
|
||||||
}
|
}
|
||||||
|
|
||||||
// fix lost choosing dialog
|
// fix lost choosing dialog
|
||||||
sb.append("<br>Checking choosing player: " + getName(game.getPlayer(state.getChoosingPlayerId())));
|
Player choosingPlayer = game.getPlayer(state.getChoosingPlayerId());
|
||||||
if (state.getChoosingPlayerId() != null) {
|
sb.append("<br>Fixing choosing player: " + getName(choosingPlayer));
|
||||||
if (game.getPlayer(state.getChoosingPlayerId()).hasLeft()) {
|
if (choosingPlayer != null && !choosingPlayer.canRespond()) {
|
||||||
fixActions.add("choosing player");
|
fixActions.add("choosing player fix");
|
||||||
sb.append("<br>Found disconnected player! Concede...");
|
|
||||||
Player p = game.getPlayer(state.getChoosingPlayerId());
|
sb.append("<br><font color='red'>WARNING, choosing player can't respond.</font>");
|
||||||
if (p != null) {
|
sb.append("<br>Try to concede...");
|
||||||
p.concede(game);
|
choosingPlayer.concede(game);
|
||||||
p.leave(); // abort any wait response actions
|
choosingPlayer.leave(); // abort any wait response actions
|
||||||
}
|
sb.append(" (" + asWarning("OK") + ", concede done)");
|
||||||
|
|
||||||
|
sb.append("<br>Try to skip step...");
|
||||||
|
if (fixedAlready) {
|
||||||
|
sb.append(" (OK, already skipped before)");
|
||||||
|
} else {
|
||||||
Phase currentPhase = game.getPhase();
|
Phase currentPhase = game.getPhase();
|
||||||
if (currentPhase != null && !fixedAlready) {
|
if (currentPhase != null) {
|
||||||
currentPhase.getStep().endStep(game, state.getActivePlayerId());
|
currentPhase.getStep().skipStep(game, state.getActivePlayerId());
|
||||||
fixedAlready = true;
|
fixedAlready = true;
|
||||||
sb.append("<br>Forcibly passing the phase!");
|
sb.append(" (" + asWarning("OK") + ", skip step done)");
|
||||||
} else if (currentPhase == null) {
|
} else {
|
||||||
sb.append("<br>Current phase null");
|
sb.append(" (" + asBad("FAIL") + ", step is null)");
|
||||||
}
|
}
|
||||||
sb.append("<br>Choosing player has left");
|
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
sb.append(choosingPlayer != null ? " (" + asGood("OK") + ", can respond)" : " (" + asGood("OK") + ", no player)");
|
||||||
}
|
}
|
||||||
|
|
||||||
// fix lost priority
|
// fix lost priority
|
||||||
Player p = game.getPlayer(state.getPriorityPlayerId());
|
Player priorityPlayer = game.getPlayer(state.getPriorityPlayerId());
|
||||||
sb.append("<br>Checking priority player: " + getName(game.getPlayer(state.getPriorityPlayerId())));
|
sb.append("<br>Fixing priority player: " + getName(priorityPlayer));
|
||||||
if (p != null) {
|
if (priorityPlayer != null && !priorityPlayer.canRespond()) {
|
||||||
if (p.hasLeft()) {
|
fixActions.add("priority player fix");
|
||||||
fixActions.add("priority player");
|
|
||||||
sb.append("<br>Found disconnected player! Concede...");
|
|
||||||
p.concede(game);
|
|
||||||
p.leave(); // abort any wait response actions
|
|
||||||
|
|
||||||
|
sb.append("<br><font color='red'>WARNING, priority player can't respond.</font>");
|
||||||
|
sb.append("<br>Try to concede...");
|
||||||
|
priorityPlayer.concede(game);
|
||||||
|
priorityPlayer.leave(); // abort any wait response actions
|
||||||
|
sb.append(" (" + asWarning("OK") + ", concede done)");
|
||||||
|
|
||||||
|
sb.append("<br>Try to skip step...");
|
||||||
|
if (fixedAlready) {
|
||||||
|
sb.append(" (" + asWarning("OK") + ", already skipped before)");
|
||||||
|
} else {
|
||||||
Phase currentPhase = game.getPhase();
|
Phase currentPhase = game.getPhase();
|
||||||
if (currentPhase != null && !fixedAlready) {
|
if (currentPhase != null) {
|
||||||
currentPhase.getStep().skipStep(game, state.getActivePlayerId());
|
currentPhase.getStep().skipStep(game, state.getActivePlayerId());
|
||||||
fixedAlready = true;
|
fixedAlready = true;
|
||||||
sb.append("<br>Forcibly passing the phase!");
|
sb.append(" (" + asWarning("OK") + ", skip step done)");
|
||||||
|
} else {
|
||||||
|
sb.append(" (" + asBad("FAIL") + ", step is null)");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
sb.append("</font>");
|
} else {
|
||||||
|
sb.append(priorityPlayer != null ? " (" + asGood("OK") + ", can respond)" : " (" + asGood("OK") + ", no player)");
|
||||||
}
|
}
|
||||||
|
|
||||||
// fix timeout
|
// fix timeout
|
||||||
sb.append("<br>Checking Future Timeout: ");
|
sb.append("<br>Fixing future timeout: ");
|
||||||
if (futureTimeout != null) {
|
if (futureTimeout != null) {
|
||||||
sb.append("Cancelled?=");
|
sb.append("cancelled?=" + futureTimeout.isCancelled());
|
||||||
sb.append(futureTimeout.isCancelled());
|
sb.append("...done?=" + futureTimeout.isDone());
|
||||||
sb.append(",,,Done?=");
|
int delay = (int) futureTimeout.getDelay(TimeUnit.SECONDS);
|
||||||
sb.append(futureTimeout.isDone());
|
sb.append("...getDelay?=" + delay);
|
||||||
sb.append(",,,GetDelay?=");
|
if (delay < 25) {
|
||||||
sb.append((int) futureTimeout.getDelay(TimeUnit.SECONDS));
|
fixActions.add("future timeout fix");
|
||||||
if ((int) futureTimeout.getDelay(TimeUnit.SECONDS) < 25) {
|
|
||||||
fixActions.add("future timeout");
|
sb.append("<br><font color='red'>WARNING, future timeout delay < 25</font>");
|
||||||
|
sb.append("<br>Try to pass...");
|
||||||
PassAbility pass = new PassAbility();
|
PassAbility pass = new PassAbility();
|
||||||
game.endTurn(pass);
|
game.endTurn(pass);
|
||||||
sb.append("<br>Forcibly passing the turn!");
|
sb.append(" (" + asWarning("OK") + ", pass done)");
|
||||||
|
} else {
|
||||||
|
sb.append(" (" + asGood("OK") + ", delay > 25)");
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
sb.append("Not using future Timeout!");
|
sb.append(" (" + asGood("OK") + ", timeout is not using)");
|
||||||
}
|
}
|
||||||
sb.append("</font>");
|
|
||||||
|
|
||||||
|
// TODO: fix non started game (send game started event to user?)
|
||||||
|
|
||||||
|
|
||||||
|
// ALL DONE
|
||||||
if (fixActions.isEmpty()) {
|
if (fixActions.isEmpty()) {
|
||||||
fixActions.add("none actions");
|
fixActions.add("none");
|
||||||
}
|
}
|
||||||
logger.warn("FIX command result for game " + game.getId() + ": " + fixActions.stream().collect(Collectors.joining(", ")));
|
String appliedFixes = fixActions.stream().collect(Collectors.joining(", "));
|
||||||
|
sb.append("<br>Applied fixes: " + appliedFixes);
|
||||||
|
sb.append("</font>"); // font resize end
|
||||||
|
sb.append("<br>");
|
||||||
|
|
||||||
|
logger.warn("FIX command result for game " + game.getId() + ": " + appliedFixes);
|
||||||
|
|
||||||
|
System.out.println(sb.toString());
|
||||||
|
|
||||||
return sb.toString();
|
return sb.toString();
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue