From a0bdfda91273bf24f74916c968589199a28d642c Mon Sep 17 00:00:00 2001 From: Oleg Agafonov Date: Sun, 2 Nov 2025 01:07:22 +0400 Subject: [PATCH] cheats: fixed AI naming, improved cheat commands compatibility: - added additional aliases for Human (me) and Computer (opponent, ai); - now same cheat command will be work in real, test, duel or multiplayer games (Computer/Human); - now same cheat command will be work in human only games; - fixed wrong/random AI opponent selection in multiplayer games; - fixed wrong opponent selection after first opponent's loose in multiplayer games; --- .../java/mage/client/table/TablesPanel.java | 8 +-- .../src/main/java/mage/utils/SystemUtil.java | 62 +++++++++++++++---- 2 files changed, 53 insertions(+), 17 deletions(-) diff --git a/Mage.Client/src/main/java/mage/client/table/TablesPanel.java b/Mage.Client/src/main/java/mage/client/table/TablesPanel.java index 0cb2e6e4242..9030054dc6a 100644 --- a/Mage.Client/src/main/java/mage/client/table/TablesPanel.java +++ b/Mage.Client/src/main/java/mage/client/table/TablesPanel.java @@ -1700,7 +1700,7 @@ public class TablesPanel extends javax.swing.JPanel { MatchOptions options = new MatchOptions(gameName, gameType, multiPlayer); options.getPlayerTypes().add(PlayerType.HUMAN); options.getPlayerTypes().add(aiType); - for (int i=2 ; i < numPlayers ; i++) { + for (int i = 2; i < numPlayers; i++) { options.getPlayerTypes().add(aiType); } options.setDeckType("Variant Magic - Freeform Commander"); @@ -1719,9 +1719,9 @@ public class TablesPanel extends javax.swing.JPanel { table = SessionHandler.createTable(roomId, options); SessionHandler.joinTable(roomId, table.getTableId(), "Human", PlayerType.HUMAN, 1, testDeck, ""); - SessionHandler.joinTable(roomId, table.getTableId(), "Computer", aiType, 1, testDeck, ""); - for (int i=2 ; i < numPlayers ; i++) { - SessionHandler.joinTable(roomId, table.getTableId(), "Computer" + i, aiType, 1, testDeck, ""); + SessionHandler.joinTable(roomId, table.getTableId(), "Computer" + (multiPlayer ? " 2" : ""), aiType, 1, testDeck, ""); + for (int i = 2; i < numPlayers; i++) { + SessionHandler.joinTable(roomId, table.getTableId(), "Computer " + (i + 1), aiType, 1, testDeck, ""); } SessionHandler.startMatch(roomId, table.getTableId()); } catch (HeadlessException ex) { diff --git a/Mage.Common/src/main/java/mage/utils/SystemUtil.java b/Mage.Common/src/main/java/mage/utils/SystemUtil.java index c8144e49def..17124d7a084 100644 --- a/Mage.Common/src/main/java/mage/utils/SystemUtil.java +++ b/Mage.Common/src/main/java/mage/utils/SystemUtil.java @@ -601,14 +601,13 @@ public final class SystemUtil { continue; } - Optional playerOptional = findPlayer(game, command.player); - if (!playerOptional.isPresent()) { + Player player = findPlayer(game, command.player, feedbackPlayer); + if (player == null) { String mes = String.format("Unknown player: %s", line); errorsList.add(mes); logger.warn(mes); continue; } - Player player = playerOptional.get(); // SPECIAL token/emblem call (without SET name) if ("token".equalsIgnoreCase(command.zone)) { @@ -860,17 +859,54 @@ public final class SystemUtil { return false; } - /** - * Find player by name. - * - * @param game - * @param name - * @return - */ - private static Optional findPlayer(Game game, String name) { - return game.getPlayers().values().stream() - .filter(player -> player.getName().equals(name)).findFirst(); + private static Player findPlayer(Game game, String needName, Player feedbackPlayer) { + // real names + Player res = game.getPlayerList().stream() + .map(game::getPlayer) + .filter(Objects::nonNull) + .filter(player -> player.getName().equals(needName)) + .findFirst() + .orElse(null); + // test names - cheat commands will be compatible in both modes (quick test and normal) + if (res == null) { + switch (needName.toLowerCase(Locale.ENGLISH)) { + case "me": + case "human": + case "human 1": + res = feedbackPlayer; + break; + case "opponent": + case "opponent 1": + case "computer": + case "computer 1": // multiplayer game uses Computer 2+ naming + case "ai": + case "ai 1": + // try AI + res = game.getPlayerList().stream() + .map(game::getPlayer) + .filter(Objects::nonNull) + .filter(Player::isInGame) + .filter(Player::isComputer) + .findFirst() + .orElse(null); + if (res == null) { + // try opponent (human only games) + res = game.getOpponents(feedbackPlayer.getId(), true).stream() + .map(game::getPlayer) + .filter(Objects::nonNull) + .filter(Player::isInGame) + .findFirst() + .orElse(null); + } + break; + default: + // raise error message due unknown player name + break; + } + } + + return res; } public static String sanitize(String input) {