* UI: added turn number and step info in game logs

This commit is contained in:
Oleg Agafonov 2020-02-28 20:27:07 +04:00
parent 190c3ecc00
commit 2e73f9d1c5
21 changed files with 546 additions and 529 deletions

View file

@ -7,17 +7,6 @@
*/ */
package mage.client.chat; package mage.client.chat;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.event.KeyEvent;
import java.text.DateFormat;
import java.util.Date;
import java.util.Locale;
import java.util.UUID;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import javax.swing.JTextField;
import mage.client.MageFrame; import mage.client.MageFrame;
import mage.client.SessionHandler; import mage.client.SessionHandler;
import mage.client.dialog.PreferencesDialog; import mage.client.dialog.PreferencesDialog;
@ -26,8 +15,17 @@ import mage.view.ChatMessage.MessageColor;
import mage.view.ChatMessage.MessageType; import mage.view.ChatMessage.MessageType;
import org.mage.card.arcane.ManaSymbols; import org.mage.card.arcane.ManaSymbols;
import javax.swing.*;
import java.awt.*;
import java.awt.event.KeyEvent;
import java.text.DateFormat;
import java.util.Date;
import java.util.Locale;
import java.util.UUID;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/** /**
*
* @author BetaSteward_at_googlemail.com, nantuko * @author BetaSteward_at_googlemail.com, nantuko
*/ */
public class ChatPanelBasic extends javax.swing.JPanel { public class ChatPanelBasic extends javax.swing.JPanel {
@ -86,9 +84,9 @@ public class ChatPanelBasic extends javax.swing.JPanel {
NONE, GAME, CHAT NONE, GAME, CHAT
} }
/** /**
* Controls the output start messages as the chat panel is created * Controls the output start messages as the chat panel is created
*
*/ */
protected ChatType chatType = ChatType.DEFAULT; protected ChatType chatType = ChatType.DEFAULT;
@ -96,12 +94,11 @@ public class ChatPanelBasic extends javax.swing.JPanel {
DEFAULT, GAME, TABLES, TOURNAMENT DEFAULT, GAME, TABLES, TOURNAMENT
} }
protected boolean startMessageDone = false; protected boolean startMessageDone = false;
/** /**
*
* Creates new form ChatPanel * Creates new form ChatPanel
*
*/ */
public ChatPanelBasic() { public ChatPanelBasic() {
initComponents(); initComponents();
@ -201,13 +198,13 @@ public class ChatPanelBasic extends javax.swing.JPanel {
message = message.replaceAll("\\.", ""); message = message.replaceAll("\\.", "");
message = '.' + message + '.'; message = '.' + message + '.';
matchPattern = profanity2Pattern.matcher(message); matchPattern = profanity2Pattern.matcher(message);
if (matchPattern.find()) { return matchPattern.find();
return true;
}
} }
return false; return false;
} }
Pattern cardNamePattern = Pattern.compile(".*<font bgcolor=orange.*?</font>.*");
/** /**
* Display message in the chat. Use different colors for timestamp, username * Display message in the chat. Use different colors for timestamp, username
* and message. * and message.
@ -215,15 +212,14 @@ public class ChatPanelBasic extends javax.swing.JPanel {
* @param username message sender * @param username message sender
* @param message message itself * @param message message itself
* @param time timestamp * @param time timestamp
* @param turnInfo game turn info, can be null for non game messages
* @param messageType * @param messageType
* @param color Preferred color. Not used. * @param color Preferred color. Not used.
*/ */
Pattern cardNamePattern = Pattern.compile(".*<font bgcolor=orange.*?</font>.*"); public void receiveMessage(String username, String message, Date time, String turnInfo, MessageType messageType, MessageColor color) {
public void receiveMessage(String username, String message, Date time, MessageType messageType, MessageColor color) {
StringBuilder text = new StringBuilder(); StringBuilder text = new StringBuilder();
if (time != null) { if (time != null) {
text.append(getColoredText(TIMESTAMP_COLOR, timeFormatter.format(time) + ": ")); text.append(getColoredText(TIMESTAMP_COLOR, timeFormatter.format(time) + (turnInfo == null ? "" : ", " + turnInfo) + ": "));
} }
String userColor; String userColor;
String textColor; String textColor;

View file

@ -1,17 +1,15 @@
package mage.client.chat; package mage.client.chat;
import java.awt.Font;
import java.util.Date;
import mage.client.SessionHandler; import mage.client.SessionHandler;
import mage.client.components.ColorPane; import mage.client.components.ColorPane;
import mage.client.util.GUISizeHelper; import mage.client.util.GUISizeHelper;
import mage.view.ChatMessage; import mage.view.ChatMessage;
import org.mage.card.arcane.ManaSymbols; import org.mage.card.arcane.ManaSymbols;
import java.awt.*;
import java.util.Date;
/** /**
*
* @author LevelX2 * @author LevelX2
*/ */
public class ChatPanelSeparated extends ChatPanelBasic { public class ChatPanelSeparated extends ChatPanelBasic {
@ -25,39 +23,39 @@ public class ChatPanelSeparated extends ChatPanelBasic {
* @param username message sender * @param username message sender
* @param message message itself * @param message message itself
* @param time timestamp * @param time timestamp
* @param turnInfo game turn info, can be null for non game messages
* @param messageType * @param messageType
* @param color Preferred color. Not used. * @param color Preferred color. Not used.
*/ */
@Override @Override
public void receiveMessage(String username, String message, Date time, ChatMessage.MessageType messageType, ChatMessage.MessageColor color) { public void receiveMessage(String username, String message, Date time, String turnInfo, ChatMessage.MessageType messageType, ChatMessage.MessageColor color) {
String userColor;
String textColor;
String userSeparator = " ";
StringBuilder text = new StringBuilder();
switch (messageType) { switch (messageType) {
case TALK: case TALK:
case WHISPER_TO: case WHISPER_TO:
case WHISPER_FROM: case WHISPER_FROM:
case USER_INFO: case USER_INFO:
super.receiveMessage(username, message, time, messageType, color); // message in main chat
super.receiveMessage(username, message, time, turnInfo, messageType, color);
return; return;
} case STATUS:
StringBuilder text = new StringBuilder();
if (time != null) {
text.append(getColoredText(TIMESTAMP_COLOR, timeFormatter.format(time) + ": "));
}
String userColor;
String textColor;
String userSeparator = " ";
switch (messageType) {
case STATUS: // a message to all chat user
textColor = STATUS_COLOR; textColor = STATUS_COLOR;
userColor = STATUS_COLOR; userColor = STATUS_COLOR;
break; break;
case USER_INFO: // a personal message
textColor = USER_INFO_COLOR;
userColor = USER_INFO_COLOR;
break;
default: default:
case GAME:
userColor = SessionHandler.getUserName().equals(username) ? MY_COLOR : OPPONENT_COLOR; userColor = SessionHandler.getUserName().equals(username) ? MY_COLOR : OPPONENT_COLOR;
textColor = MESSAGE_COLOR; textColor = MESSAGE_COLOR;
userSeparator = ": "; userSeparator = ": ";
break;
}
// message in game log
if (time != null) {
text.append(getColoredText(TIMESTAMP_COLOR, timeFormatter.format(time) + (turnInfo == null ? "" : ", " + turnInfo) + ": "));
} }
if (color == ChatMessage.MessageColor.ORANGE) { if (color == ChatMessage.MessageColor.ORANGE) {
textColor = "Orange"; textColor = "Orange";

View file

@ -68,7 +68,7 @@ public final class LocalCommands {
private static void displayLocalCommandResponse(UUID chatId, String response) { private static void displayLocalCommandResponse(UUID chatId, String response) {
final String text = new StringBuilder().append("<font color=yellow>").append(response).append("</font>").toString(); final String text = new StringBuilder().append("<font color=yellow>").append(response).append("</font>").toString();
ClientCallback chatMessage = new ClientCallback(ClientCallbackMethod.CHATMESSAGE, chatId, ClientCallback chatMessage = new ClientCallback(ClientCallbackMethod.CHATMESSAGE, chatId,
new ChatMessage("", text, new Date(), ChatMessage.MessageColor.BLUE)); new ChatMessage("", text, new Date(), null, ChatMessage.MessageColor.BLUE));
MageFrame.getInstance().processCallback(chatMessage); MageFrame.getInstance().processCallback(chatMessage);
} }
} }

View file

@ -3826,7 +3826,7 @@ public class PreferencesDialog extends javax.swing.JDialog {
addAvatar(jPanel32, 32, false, false); addAvatar(jPanel32, 32, false, false);
} catch (Exception e) { } catch (Exception e) {
logger.error(e, e); logger.error(e.getMessage(), e);
} }
} }

View file

@ -109,9 +109,9 @@ public class CallbackClientImpl implements CallbackClient {
} }
// send the message to subchat if exists and it's not a game message // send the message to subchat if exists and it's not a game message
if (message.getMessageType() != MessageType.GAME && panel.getConnectedChat() != null) { if (message.getMessageType() != MessageType.GAME && panel.getConnectedChat() != null) {
panel.getConnectedChat().receiveMessage(message.getUsername(), message.getMessage(), message.getTime(), message.getMessageType(), ChatMessage.MessageColor.BLACK); panel.getConnectedChat().receiveMessage(message.getUsername(), message.getMessage(), message.getTime(), message.getTurnInfo(), message.getMessageType(), ChatMessage.MessageColor.BLACK);
} else { } else {
panel.receiveMessage(message.getUsername(), message.getMessage(), message.getTime(), message.getMessageType(), message.getColor()); panel.receiveMessage(message.getUsername(), message.getMessage(), message.getTime(), message.getTurnInfo(), message.getMessageType(), message.getColor());
} }
} }
@ -444,11 +444,11 @@ public class CallbackClientImpl implements CallbackClient {
.append("<br/>").append("<b>/pings</b> - show players and watchers ping") .append("<br/>").append("<b>/pings</b> - show players and watchers ping")
.append("<br/>").append("<b>/fix</b> - fix freezed game") .append("<br/>").append("<b>/fix</b> - fix freezed game")
.toString(), .toString(),
null, MessageType.USER_INFO, ChatMessage.MessageColor.BLUE); null, null, MessageType.USER_INFO, ChatMessage.MessageColor.BLUE);
break; break;
case TOURNAMENT: case TOURNAMENT:
usedPanel.receiveMessage("", "On this panel you can see the players, their state and the results of the games of the tournament. Also you can chat with the competitors of the tournament.", usedPanel.receiveMessage("", "On this panel you can see the players, their state and the results of the games of the tournament. Also you can chat with the competitors of the tournament.",
null, MessageType.USER_INFO, ChatMessage.MessageColor.BLUE); null, null, MessageType.USER_INFO, ChatMessage.MessageColor.BLUE);
break; break;
case TABLES: case TABLES:
String serverAddress = SessionHandler.getSession().getServerHostname().orElseGet(() -> ""); String serverAddress = SessionHandler.getSession().getServerHostname().orElseGet(() -> "");
@ -457,7 +457,7 @@ public class CallbackClientImpl implements CallbackClient {
.append("<br/>\\list - show a list of available chat commands.") .append("<br/>\\list - show a list of available chat commands.")
.append("<br/>").append(IgnoreList.usage(serverAddress)) .append("<br/>").append(IgnoreList.usage(serverAddress))
.append("<br/>Type <font color=green>\\w yourUserName profanity 0 (or 1 or 2)</font> to turn off/on the profanity filter").toString(), .append("<br/>Type <font color=green>\\w yourUserName profanity 0 (or 1 or 2)</font> to turn off/on the profanity filter").toString(),
null, MessageType.USER_INFO, ChatMessage.MessageColor.BLUE); null, null, MessageType.USER_INFO, ChatMessage.MessageColor.BLUE);
break; break;
default: default:
break; break;

View file

@ -470,7 +470,7 @@ public final class ImageCache {
image = ImageIO.read(inputStream); image = ImageIO.read(inputStream);
} }
} catch (Exception e) { } catch (Exception e) {
LOGGER.error(e, e); LOGGER.error(e.getMessage(), e);
} }
return image; return image;
@ -488,7 +488,7 @@ public final class ImageCache {
ImageIO.write(image, format, outputStream); ImageIO.write(image, format, outputStream);
} }
} catch (IOException e) { } catch (IOException e) {
LOGGER.error(e, e); LOGGER.error(e.getMessage(), e);
imageFile.delete(); imageFile.delete();
} }
return image; return image;

View file

@ -1,12 +1,11 @@
package mage.view; package mage.view;
import mage.game.Game;
import java.io.Serializable; import java.io.Serializable;
import java.util.Date; import java.util.Date;
/** /**
*
* @author BetaSteward_at_googlemail.com * @author BetaSteward_at_googlemail.com
*/ */
public class ChatMessage implements Serializable { public class ChatMessage implements Serializable {
@ -14,6 +13,7 @@ public class ChatMessage implements Serializable {
private String username; private String username;
private Date time; private Date time;
private String turnInfo;
private String message; private String message;
private MessageColor color; private MessageColor color;
private SoundToPlay soundToPlay; private SoundToPlay soundToPlay;
@ -31,23 +31,39 @@ public class ChatMessage implements Serializable {
PlayerLeft, PlayerQuitTournament, PlayerSubmittedDeck, PlayerWhispered PlayerLeft, PlayerQuitTournament, PlayerSubmittedDeck, PlayerWhispered
} }
public ChatMessage(String username, String message, Date time, MessageColor color) { public ChatMessage(String username, String message, Date time, Game game, MessageColor color) {
this(username, message, time, color, null); this(username, message, time, game, color, null);
} }
public ChatMessage(String username, String message, Date time, MessageColor color, SoundToPlay soundToPlay) { public ChatMessage(String username, String message, Date time, Game game, MessageColor color, SoundToPlay soundToPlay) {
this(username, message, time, color, MessageType.TALK, soundToPlay); this(username, message, time, null, color, MessageType.TALK, soundToPlay);
} }
public ChatMessage(String username, String message, Date time, MessageColor color, MessageType messageType, SoundToPlay soundToPlay) { public ChatMessage(String username, String message, Date time, Game game, MessageColor color, MessageType messageType, SoundToPlay soundToPlay) {
this.username = username; this.username = username;
this.message = message; this.message = message;
this.time = time; this.time = time;
this.turnInfo = prepareTurnInfo(game);
this.color = color; this.color = color;
this.messageType = messageType; this.messageType = messageType;
this.soundToPlay = soundToPlay; this.soundToPlay = soundToPlay;
} }
private String prepareTurnInfo(Game game) {
// no turn info
if (game == null) {
return null;
}
// not started game
if (game.getStep() == null) {
return "T0";
}
// normal game
return "T" + game.getTurnNum() + "." + game.getStep().getType().getStepShortText();
}
public String getMessage() { public String getMessage() {
return message; return message;
} }
@ -72,6 +88,10 @@ public class ChatMessage implements Serializable {
return time; return time;
} }
public String getTurnInfo() {
return turnInfo;
}
public SoundToPlay getSoundToPlay() { public SoundToPlay getSoundToPlay() {
return soundToPlay; return soundToPlay;
} }

View file

@ -2,6 +2,7 @@ package mage.server;
import mage.cards.repository.CardInfo; import mage.cards.repository.CardInfo;
import mage.cards.repository.CardRepository; import mage.cards.repository.CardRepository;
import mage.game.Game;
import mage.server.exceptions.UserNotFoundException; import mage.server.exceptions.UserNotFoundException;
import mage.server.game.GameController; import mage.server.game.GameController;
import mage.server.game.GameManager; import mage.server.game.GameManager;
@ -81,17 +82,9 @@ public enum ChatManager {
} }
} }
public void broadcast(UUID chatId, String userName, String message, MessageColor color, boolean withTime) {
this.broadcast(chatId, userName, message, color, withTime, MessageType.TALK);
}
public void broadcast(UUID chatId, String userName, String message, MessageColor color, boolean withTime, MessageType messageType) {
this.broadcast(chatId, userName, message, color, withTime, messageType, null);
}
final Pattern cardNamePattern = Pattern.compile("\\[(.*?)\\]"); final Pattern cardNamePattern = Pattern.compile("\\[(.*?)\\]");
public void broadcast(UUID chatId, String userName, String message, MessageColor color, boolean withTime, MessageType messageType, SoundToPlay soundToPlay) { public void broadcast(UUID chatId, String userName, String message, MessageColor color, boolean withTime, Game game, MessageType messageType, SoundToPlay soundToPlay) {
ChatSession chatSession = chatSessions.get(chatId); ChatSession chatSession = chatSessions.get(chatId);
if (chatSession != null) { if (chatSession != null) {
if (message.startsWith("\\") || message.startsWith("/")) { if (message.startsWith("\\") || message.startsWith("/")) {
@ -163,7 +156,7 @@ public enum ChatManager {
} }
} }
chatSession.broadcast(userName, message, color, withTime, messageType, soundToPlay); chatSession.broadcast(userName, message, color, withTime, game, messageType, soundToPlay);
} }
} }
@ -324,7 +317,7 @@ public enum ChatManager {
getChatSessions() getChatSessions()
.stream() .stream()
.filter(chat -> chat.hasUser(userId)) .filter(chat -> chat.hasUser(userId))
.forEach(session -> session.broadcast(user.getName(), message, color, true, MessageType.TALK, null)); .forEach(session -> session.broadcast(user.getName(), message, color, true, null, MessageType.TALK, null));
}); });
} }
@ -334,7 +327,7 @@ public enum ChatManager {
-> getChatSessions() -> getChatSessions()
.stream() .stream()
.filter(chat -> chat.hasUser(userId)) .filter(chat -> chat.hasUser(userId))
.forEach(chatSession -> chatSession.broadcast(null, user.getName() + " has reconnected", MessageColor.BLUE, true, MessageType.STATUS, null))); .forEach(chatSession -> chatSession.broadcast(null, user.getName() + " has reconnected", MessageColor.BLUE, true, null, MessageType.STATUS, null)));
} }
@ -357,7 +350,7 @@ public enum ChatManager {
if (chatSessions.size() > 0) { if (chatSessions.size() > 0) {
logger.info("INFORM OPPONENTS by " + user.getName() + ": " + message); logger.info("INFORM OPPONENTS by " + user.getName() + ": " + message);
chatSessions.forEach(chatSession -> chatSession.broadcast(null, message, MessageColor.BLUE, true, MessageType.STATUS, null)); chatSessions.forEach(chatSession -> chatSession.broadcast(null, message, MessageColor.BLUE, true, null, MessageType.STATUS, null));
} }
}); });
} }

View file

@ -1,6 +1,14 @@
package mage.server; package mage.server;
import mage.game.Game;
import mage.interfaces.callback.ClientCallback;
import mage.interfaces.callback.ClientCallbackMethod;
import mage.view.ChatMessage;
import mage.view.ChatMessage.MessageColor;
import mage.view.ChatMessage.MessageType;
import mage.view.ChatMessage.SoundToPlay;
import org.apache.log4j.Logger;
import java.text.DateFormat; import java.text.DateFormat;
import java.util.*; import java.util.*;
import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentHashMap;
@ -8,13 +16,6 @@ import java.util.concurrent.ConcurrentMap;
import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReadWriteLock; import java.util.concurrent.locks.ReadWriteLock;
import java.util.concurrent.locks.ReentrantReadWriteLock; import java.util.concurrent.locks.ReentrantReadWriteLock;
import mage.interfaces.callback.ClientCallback;
import mage.interfaces.callback.ClientCallbackMethod;
import mage.view.ChatMessage;
import mage.view.ChatMessage.MessageColor;
import mage.view.ChatMessage.MessageType;
import mage.view.ChatMessage.SoundToPlay;
import org.apache.log4j.Logger;
/** /**
* @author BetaSteward_at_googlemail.com * @author BetaSteward_at_googlemail.com
@ -48,7 +49,7 @@ public class ChatSession {
} finally { } finally {
w.unlock(); w.unlock();
} }
broadcast(null, userName + " has joined (" + user.getClientVersion() + ')', MessageColor.BLUE, true, MessageType.STATUS, null); broadcast(null, userName + " has joined (" + user.getClientVersion() + ')', MessageColor.BLUE, true, null, MessageType.STATUS, null);
logger.trace(userName + " joined chat " + chatId); logger.trace(userName + " joined chat " + chatId);
} }
}); });
@ -76,7 +77,7 @@ public class ChatSession {
String message = reason.getMessage(); String message = reason.getMessage();
if (!message.isEmpty()) { if (!message.isEmpty()) {
broadcast(null, userName + message, MessageColor.BLUE, true, MessageType.STATUS, null); broadcast(null, userName + message, MessageColor.BLUE, true, null, MessageType.STATUS, null);
} }
} }
} catch (Exception ex) { } catch (Exception ex) {
@ -86,7 +87,8 @@ public class ChatSession {
public boolean broadcastInfoToUser(User toUser, String message) { public boolean broadcastInfoToUser(User toUser, String message) {
if (clients.containsKey(toUser.getId())) { if (clients.containsKey(toUser.getId())) {
toUser.fireCallback(new ClientCallback(ClientCallbackMethod.CHATMESSAGE, chatId, new ChatMessage(null, message, new Date(), MessageColor.BLUE, MessageType.USER_INFO, null))); toUser.fireCallback(new ClientCallback(ClientCallbackMethod.CHATMESSAGE, chatId,
new ChatMessage(null, message, new Date(), null, MessageColor.BLUE, MessageType.USER_INFO, null)));
return true; return true;
} }
return false; return false;
@ -95,20 +97,21 @@ public class ChatSession {
public boolean broadcastWhisperToUser(User fromUser, User toUser, String message) { public boolean broadcastWhisperToUser(User fromUser, User toUser, String message) {
if (clients.containsKey(toUser.getId())) { if (clients.containsKey(toUser.getId())) {
toUser.fireCallback(new ClientCallback(ClientCallbackMethod.CHATMESSAGE, chatId, toUser.fireCallback(new ClientCallback(ClientCallbackMethod.CHATMESSAGE, chatId,
new ChatMessage(fromUser.getName(), message, new Date(), MessageColor.YELLOW, MessageType.WHISPER_FROM, SoundToPlay.PlayerWhispered))); new ChatMessage(fromUser.getName(), message, new Date(), null, MessageColor.YELLOW, MessageType.WHISPER_FROM, SoundToPlay.PlayerWhispered)));
if (clients.containsKey(fromUser.getId())) { if (clients.containsKey(fromUser.getId())) {
fromUser.fireCallback(new ClientCallback(ClientCallbackMethod.CHATMESSAGE, chatId, fromUser.fireCallback(new ClientCallback(ClientCallbackMethod.CHATMESSAGE, chatId,
new ChatMessage(toUser.getName(), message, new Date(), MessageColor.YELLOW, MessageType.WHISPER_TO, null))); new ChatMessage(toUser.getName(), message, new Date(), null, MessageColor.YELLOW, MessageType.WHISPER_TO, null)));
return true; return true;
} }
} }
return false; return false;
} }
public void broadcast(String userName, String message, MessageColor color, boolean withTime, MessageType messageType, SoundToPlay soundToPlay) { public void broadcast(String userName, String message, MessageColor color, boolean withTime, Game game, MessageType messageType, SoundToPlay soundToPlay) {
if (!message.isEmpty()) { if (!message.isEmpty()) {
Set<UUID> clientsToRemove = new HashSet<>(); Set<UUID> clientsToRemove = new HashSet<>();
ClientCallback clientCallback = new ClientCallback(ClientCallbackMethod.CHATMESSAGE, chatId, new ChatMessage(userName, message, (withTime ? new Date() : null), color, messageType, soundToPlay)); ClientCallback clientCallback = new ClientCallback(ClientCallbackMethod.CHATMESSAGE, chatId,
new ChatMessage(userName, message, (withTime ? new Date() : null), game, color, messageType, soundToPlay));
List<UUID> chatUserIds = new ArrayList<>(); List<UUID> chatUserIds = new ArrayList<>();
final Lock r = lock.readLock(); final Lock r = lock.readLock();
r.lock(); r.lock();

View file

@ -10,7 +10,6 @@ import mage.cards.repository.ExpansionRepository;
import mage.constants.ManaType; import mage.constants.ManaType;
import mage.constants.PlayerAction; import mage.constants.PlayerAction;
import mage.constants.TableState; import mage.constants.TableState;
import mage.game.GameException;
import mage.game.Table; import mage.game.Table;
import mage.game.match.MatchOptions; import mage.game.match.MatchOptions;
import mage.game.tournament.TournamentOptions; import mage.game.tournament.TournamentOptions;
@ -494,7 +493,7 @@ public class MageServerImpl implements MageServer {
public void sendChatMessage(final UUID chatId, final String userName, final String message) throws MageException { public void sendChatMessage(final UUID chatId, final String userName, final String message) throws MageException {
try { try {
callExecutor.execute( callExecutor.execute(
() -> ChatManager.instance.broadcast(chatId, userName, StringEscapeUtils.escapeHtml4(message), MessageColor.BLUE, true, ChatMessage.MessageType.TALK, null) () -> ChatManager.instance.broadcast(chatId, userName, StringEscapeUtils.escapeHtml4(message), MessageColor.BLUE, true, null, ChatMessage.MessageType.TALK, null)
); );
} catch (Exception ex) { } catch (Exception ex) {
handleException(ex); handleException(ex);
@ -1129,9 +1128,9 @@ public class MageServerImpl implements MageServer {
execute("sendBroadcastMessage", sessionId, () -> { execute("sendBroadcastMessage", sessionId, () -> {
for (User user : UserManager.instance.getUsers()) { for (User user : UserManager.instance.getUsers()) {
if (message.toLowerCase(Locale.ENGLISH).startsWith("warn")) { if (message.toLowerCase(Locale.ENGLISH).startsWith("warn")) {
user.fireCallback(new ClientCallback(ClientCallbackMethod.SERVER_MESSAGE, null, new ChatMessage("SERVER", message, null, MessageColor.RED))); user.fireCallback(new ClientCallback(ClientCallbackMethod.SERVER_MESSAGE, null, new ChatMessage("SERVER", message, null, null, MessageColor.RED)));
} else { } else {
user.fireCallback(new ClientCallback(ClientCallbackMethod.SERVER_MESSAGE, null, new ChatMessage("SERVER", message, null, MessageColor.BLUE))); user.fireCallback(new ClientCallback(ClientCallbackMethod.SERVER_MESSAGE, null, new ChatMessage("SERVER", message, null, null, MessageColor.BLUE)));
} }
} }
}, true); }, true);

View file

@ -545,7 +545,7 @@ public class TableController {
} }
Optional<User> user = UserManager.instance.getUser(userId); Optional<User> user = UserManager.instance.getUser(userId);
if (user.isPresent()) { if (user.isPresent()) {
ChatManager.instance.broadcast(chatId, user.get().getName(), "has left the table", ChatMessage.MessageColor.BLUE, true, ChatMessage.MessageType.STATUS, ChatMessage.SoundToPlay.PlayerLeft); ChatManager.instance.broadcast(chatId, user.get().getName(), "has left the table", ChatMessage.MessageColor.BLUE, true, null, ChatMessage.MessageType.STATUS, ChatMessage.SoundToPlay.PlayerLeft);
if (!table.isTournamentSubTable()) { if (!table.isTournamentSubTable()) {
user.get().removeTable(playerId); user.get().removeTable(playerId);
} }

View file

@ -120,11 +120,11 @@ public class GameController implements GameCallback {
updateGame(); updateGame();
break; break;
case INFO: case INFO:
ChatManager.instance.broadcast(chatId, "", event.getMessage(), MessageColor.BLACK, true, MessageType.GAME, null); ChatManager.instance.broadcast(chatId, "", event.getMessage(), MessageColor.BLACK, true, event.getGame(), MessageType.GAME, null);
logger.trace(game.getId() + " " + event.getMessage()); logger.trace(game.getId() + " " + event.getMessage());
break; break;
case STATUS: case STATUS:
ChatManager.instance.broadcast(chatId, "", event.getMessage(), MessageColor.ORANGE, event.getWithTime(), MessageType.GAME, null); ChatManager.instance.broadcast(chatId, "", event.getMessage(), MessageColor.ORANGE, event.getWithTime(), event.getWithTurnInfo() ? event.getGame() : null, MessageType.GAME, null);
logger.trace(game.getId() + " " + event.getMessage()); logger.trace(game.getId() + " " + event.getMessage());
break; break;
case ERROR: case ERROR:
@ -300,7 +300,7 @@ public class GameController implements GameCallback {
} }
user.get().addGame(playerId, gameSession); user.get().addGame(playerId, gameSession);
logger.debug("Player " + player.getName() + ' ' + playerId + " has " + joinType + " gameId: " + game.getId()); logger.debug("Player " + player.getName() + ' ' + playerId + " has " + joinType + " gameId: " + game.getId());
ChatManager.instance.broadcast(chatId, "", game.getPlayer(playerId).getLogName() + " has " + joinType + " the game", MessageColor.ORANGE, true, MessageType.GAME, null); ChatManager.instance.broadcast(chatId, "", game.getPlayer(playerId).getLogName() + " has " + joinType + " the game", MessageColor.ORANGE, true, game, MessageType.GAME, null);
checkStart(); checkStart();
} }
@ -361,7 +361,7 @@ public class GameController implements GameCallback {
+ " is forced to join the game (waiting ends after " + " is forced to join the game (waiting ends after "
+ GAME_TIMEOUTS_CANCEL_PLAYER_GAME_JOINING_AFTER_INACTIVE_SECS + GAME_TIMEOUTS_CANCEL_PLAYER_GAME_JOINING_AFTER_INACTIVE_SECS
+ " secs, applied fixes: " + problemPlayerFixes + ")", + " secs, applied fixes: " + problemPlayerFixes + ")",
MessageColor.BLUE, true, ChatMessage.MessageType.STATUS, null); MessageColor.BLUE, true, game, ChatMessage.MessageType.STATUS, null);
} }
if (!user.isConnected() && user.getSecondsDisconnected() > GAME_TIMEOUTS_CANCEL_PLAYER_GAME_JOINING_AFTER_INACTIVE_SECS) { if (!user.isConnected() && user.getSecondsDisconnected() > GAME_TIMEOUTS_CANCEL_PLAYER_GAME_JOINING_AFTER_INACTIVE_SECS) {
@ -425,7 +425,7 @@ public class GameController implements GameCallback {
// Dont want people on our ignore list to stalk us // Dont want people on our ignore list to stalk us
UserManager.instance.getUser(userId).ifPresent(user -> { UserManager.instance.getUser(userId).ifPresent(user -> {
user.showUserMessage("Not allowed", "You are banned from watching this game"); user.showUserMessage("Not allowed", "You are banned from watching this game");
ChatManager.instance.broadcast(chatId, user.getName(), " tried to join, but is banned", MessageColor.BLUE, true, ChatMessage.MessageType.STATUS, null); ChatManager.instance.broadcast(chatId, user.getName(), " tried to join, but is banned", MessageColor.BLUE, true, game, ChatMessage.MessageType.STATUS, null);
}); });
return false; return false;
} }
@ -440,7 +440,7 @@ public class GameController implements GameCallback {
} }
gameWatcher.init(); gameWatcher.init();
user.addGameWatchInfo(game.getId()); user.addGameWatchInfo(game.getId());
ChatManager.instance.broadcast(chatId, user.getName(), " has started watching", MessageColor.BLUE, true, ChatMessage.MessageType.STATUS, null); ChatManager.instance.broadcast(chatId, user.getName(), " has started watching", MessageColor.BLUE, true, game, ChatMessage.MessageType.STATUS, null);
}); });
return true; return true;
} }
@ -454,7 +454,7 @@ public class GameController implements GameCallback {
w.unlock(); w.unlock();
} }
UserManager.instance.getUser(userId).ifPresent(user -> { UserManager.instance.getUser(userId).ifPresent(user -> {
ChatManager.instance.broadcast(chatId, user.getName(), " has stopped watching", MessageColor.BLUE, true, ChatMessage.MessageType.STATUS, null); ChatManager.instance.broadcast(chatId, user.getName(), " has stopped watching", MessageColor.BLUE, true, game, ChatMessage.MessageType.STATUS, null);
}); });
} }
@ -699,7 +699,7 @@ public class GameController implements GameCallback {
String sb = player.getLogName() String sb = player.getLogName()
+ " has timed out (player had priority and was not active for " + " has timed out (player had priority and was not active for "
+ ConfigSettings.instance.getMaxSecondsIdle() + " seconds ) - Auto concede."; + ConfigSettings.instance.getMaxSecondsIdle() + " seconds ) - Auto concede.";
ChatManager.instance.broadcast(chatId, "", sb, MessageColor.BLACK, true, MessageType.STATUS, null); ChatManager.instance.broadcast(chatId, "", sb, MessageColor.BLACK, true, game, MessageType.STATUS, null);
game.idleTimeout(playerId); game.idleTimeout(playerId);
} }
} }

View file

@ -1,12 +1,5 @@
package mage.server.tournament; package mage.server.tournament;
import java.util.Map.Entry;
import java.util.Optional;
import java.util.UUID;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import mage.MageException; import mage.MageException;
import mage.cards.decks.Deck; import mage.cards.decks.Deck;
import mage.constants.TableState; import mage.constants.TableState;
@ -38,6 +31,12 @@ import mage.view.ChatMessage.SoundToPlay;
import mage.view.TournamentView; import mage.view.TournamentView;
import org.apache.log4j.Logger; import org.apache.log4j.Logger;
import java.util.Map.Entry;
import java.util.Optional;
import java.util.UUID;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
/** /**
* @author BetaSteward_at_googlemail.com * @author BetaSteward_at_googlemail.com
*/ */
@ -68,7 +67,7 @@ public class TournamentController {
checkPlayersState(); checkPlayersState();
break; break;
case INFO: case INFO:
ChatManager.instance.broadcast(chatId, "", event.getMessage(), MessageColor.BLACK, true, MessageType.STATUS, null); ChatManager.instance.broadcast(chatId, "", event.getMessage(), MessageColor.BLACK, true, null, MessageType.STATUS, null);
logger.debug(tournament.getId() + " " + event.getMessage()); logger.debug(tournament.getId() + " " + event.getMessage());
break; break;
case START_DRAFT: case START_DRAFT:
@ -123,7 +122,7 @@ public class TournamentController {
if (!player.getPlayer().isHuman()) { if (!player.getPlayer().isHuman()) {
player.setJoined(); player.setJoined();
logger.debug("player " + player.getPlayer().getId() + " has joined tournament " + tournament.getId()); logger.debug("player " + player.getPlayer().getId() + " has joined tournament " + tournament.getId());
ChatManager.instance.broadcast(chatId, "", player.getPlayer().getLogName() + " has joined the tournament", MessageColor.BLACK, true, MessageType.STATUS, null); ChatManager.instance.broadcast(chatId, "", player.getPlayer().getLogName() + " has joined the tournament", MessageColor.BLACK, true, null, MessageType.STATUS, null);
} }
} }
checkStart(); checkStart();
@ -153,7 +152,7 @@ public class TournamentController {
TournamentPlayer player = tournament.getPlayer(playerId); TournamentPlayer player = tournament.getPlayer(playerId);
player.setJoined(); player.setJoined();
logger.debug("player " + player.getPlayer().getName() + " - client has joined tournament " + tournament.getId()); logger.debug("player " + player.getPlayer().getName() + " - client has joined tournament " + tournament.getId());
ChatManager.instance.broadcast(chatId, "", player.getPlayer().getLogName() + " has joined the tournament", MessageColor.BLACK, true, MessageType.STATUS, null); ChatManager.instance.broadcast(chatId, "", player.getPlayer().getLogName() + " has joined the tournament", MessageColor.BLACK, true, null, MessageType.STATUS, null);
checkStart(); checkStart();
} else { } else {
logger.error("User not found userId: " + userId + " tournamentId: " + tournament.getId()); logger.error("User not found userId: " + userId + " tournamentId: " + tournament.getId());
@ -320,7 +319,7 @@ public class TournamentController {
TournamentPlayer player = tournament.getPlayer(playerId); TournamentPlayer player = tournament.getPlayer(playerId);
if (player != null && !player.hasQuit()) { if (player != null && !player.hasQuit()) {
tournamentSessions.get(playerId).submitDeck(deck); tournamentSessions.get(playerId).submitDeck(deck);
ChatManager.instance.broadcast(chatId, "", player.getPlayer().getLogName() + " has submitted their tournament deck", MessageColor.BLACK, true, MessageType.STATUS, SoundToPlay.PlayerSubmittedDeck); ChatManager.instance.broadcast(chatId, "", player.getPlayer().getLogName() + " has submitted their tournament deck", MessageColor.BLACK, true, null, MessageType.STATUS, SoundToPlay.PlayerSubmittedDeck);
} }
} }
} }
@ -405,12 +404,11 @@ public class TournamentController {
tournamentPlayer.setQuit(info, status); tournamentPlayer.setQuit(info, status);
tournament.quit(playerId); tournament.quit(playerId);
tournamentSession.quit(); tournamentSession.quit();
ChatManager.instance.broadcast(chatId, "", tournamentPlayer.getPlayer().getLogName() + " has quit the tournament", MessageColor.BLACK, true, MessageType.STATUS, SoundToPlay.PlayerQuitTournament); ChatManager.instance.broadcast(chatId, "", tournamentPlayer.getPlayer().getLogName() + " has quit the tournament", MessageColor.BLACK, true, null, MessageType.STATUS, SoundToPlay.PlayerQuitTournament);
} }
} }
private boolean checkToReplaceDraftPlayerByAi(UUID userId, TournamentPlayer leavingPlayer) { private boolean checkToReplaceDraftPlayerByAi(UUID userId, TournamentPlayer leavingPlayer) {
int humans = 0; int humans = 0;
for (TournamentPlayer tPlayer : tournament.getPlayers()) { for (TournamentPlayer tPlayer : tournament.getPlayers()) {
if (tPlayer.getPlayer().isHuman()) { if (tPlayer.getPlayer().isHuman()) {
@ -432,7 +430,7 @@ public class TournamentController {
user.get().removeTable(leavingPlayer.getPlayer().getId()); user.get().removeTable(leavingPlayer.getPlayer().getId());
user.get().removeTournament(leavingPlayer.getPlayer().getId()); user.get().removeTournament(leavingPlayer.getPlayer().getId());
} }
ChatManager.instance.broadcast(chatId, "", leavingPlayer.getPlayer().getLogName() + " was replaced by draftbot", MessageColor.BLACK, true, MessageType.STATUS, null); ChatManager.instance.broadcast(chatId, "", leavingPlayer.getPlayer().getLogName() + " was replaced by draftbot", MessageColor.BLACK, true, null, MessageType.STATUS, null);
}); });
return true; return true;
} }

View file

@ -1,4 +1,3 @@
package mage.server.util; package mage.server.util;
import mage.utils.StreamUtils; import mage.utils.StreamUtils;
@ -130,7 +129,7 @@ public enum ServerMessagesUtil {
} }
} }
} catch (Exception e) { } catch (Exception e) {
log.error(e, e); log.error(e.getMessage(), e);
} finally { } finally {
StreamUtils.closeQuietly(is); StreamUtils.closeQuietly(is);
} }

View file

@ -61,8 +61,8 @@ public class MulliganTestBase {
Mulligan mulligan = mulliganType.getMulligan(freeMulligans); Mulligan mulligan = mulliganType.getMulligan(freeMulligans);
Game game = new TwoPlayerDuel(LEFT, ONE, mulligan, 20) { Game game = new TwoPlayerDuel(LEFT, ONE, mulligan, 20) {
@Override @Override
public void fireStatusEvent(String message, boolean withTime) { public void fireStatusEvent(String message, boolean withTime, boolean withTurnInfo) {
super.fireStatusEvent(message, withTime); super.fireStatusEvent(message, withTime, withTurnInfo);
} }
@Override @Override

View file

@ -1,36 +1,37 @@
package mage.constants; package mage.constants;
/** /**
*
* @author North * @author North
*/ */
public enum PhaseStep { public enum PhaseStep {
UNTAP ("Untap", 0, "untap step"), UNTAP("Untap", 0, "untap step", "UN"),
UPKEEP ("Upkeep", 1, "upkeep"), // card texts don't use the word "step" for this phase step UPKEEP("Upkeep", 1, "upkeep", "UP"), // card texts don't use the word "step" for this phase step
DRAW ("Draw", 2, "draw step"), DRAW("Draw", 2, "draw step", "DR"),
PRECOMBAT_MAIN ("Precombat Main", 3,"precombat main step"), PRECOMBAT_MAIN("Precombat Main", 3, "precombat main step", "PM"),
BEGIN_COMBAT ("Begin Combat", 4, "begin combat step"), BEGIN_COMBAT("Begin Combat", 4, "begin combat step", "BC"),
DECLARE_ATTACKERS ("Declare Attackers", 5, "declare attackers step"), DECLARE_ATTACKERS("Declare Attackers", 5, "declare attackers step", "DA"),
DECLARE_BLOCKERS ("Declare Blockers", 6, "declare blockers step"), DECLARE_BLOCKERS("Declare Blockers", 6, "declare blockers step", "DB"),
FIRST_COMBAT_DAMAGE ("First Combat Damage", 7, "first combat damage"), FIRST_COMBAT_DAMAGE("First Combat Damage", 7, "first combat damage", "FCD"),
COMBAT_DAMAGE ("Combat Damage", 8, "combat damage step"), COMBAT_DAMAGE("Combat Damage", 8, "combat damage step", "CD"),
END_COMBAT ("End Combat", 9, "end combat step"), END_COMBAT("End Combat", 9, "end combat step", "EC"),
POSTCOMBAT_MAIN ("Postcombat Main", 10, "postcombat main step"), POSTCOMBAT_MAIN("Postcombat Main", 10, "postcombat main step", "PM"),
END_TURN ("End Turn", 11, "end turn step"), END_TURN("End Turn", 11, "end turn step", "ET"),
CLEANUP ("Cleanup", 12, "cleanup step"); CLEANUP("Cleanup", 12, "cleanup step", "CL");
private final String text; private final String text;
private final String stepText; private final String stepText;
private final String stepShortText; // for chats/logs
/** /**
* Index is used for game state scoring system. * Index is used for game state scoring system.
*/ */
private final int index; private final int index;
PhaseStep(String text, int index, String stepText) { PhaseStep(String text, int index, String stepText, String stepShortText) {
this.text = text; this.text = text;
this.index = index; this.index = index;
this.stepText = stepText; this.stepText = stepText;
this.stepShortText = stepShortText;
} }
public boolean isBefore(PhaseStep other) { public boolean isBefore(PhaseStep other) {
@ -54,4 +55,7 @@ public enum PhaseStep {
return stepText; return stepText;
} }
public String getStepShortText() {
return stepShortText;
}
} }

View file

@ -1,8 +1,5 @@
package mage.game; package mage.game;
import java.io.Serializable;
import java.util.*;
import java.util.stream.Collectors;
import mage.MageItem; import mage.MageItem;
import mage.MageObject; import mage.MageObject;
import mage.abilities.Ability; import mage.abilities.Ability;
@ -44,6 +41,10 @@ import mage.players.Players;
import mage.util.MessageToClient; import mage.util.MessageToClient;
import mage.util.functions.ApplyToPermanent; import mage.util.functions.ApplyToPermanent;
import java.io.Serializable;
import java.util.*;
import java.util.stream.Collectors;
public interface Game extends MageItem, Serializable { public interface Game extends MageItem, Serializable {
MatchType getGameType(); MatchType getGameType();
@ -266,7 +267,7 @@ public interface Game extends MageItem, Serializable {
void fireInformEvent(String message); void fireInformEvent(String message);
void fireStatusEvent(String message, boolean withTime); void fireStatusEvent(String message, boolean withTime, boolean withTurnInfo);
void fireUpdatePlayersEvent(); void fireUpdatePlayersEvent();

View file

@ -921,7 +921,7 @@ public abstract class GameImpl implements Game, Serializable {
if (startMessage == null || startMessage.isEmpty()) { if (startMessage == null || startMessage.isEmpty()) {
startMessage = "Game has started"; startMessage = "Game has started";
} }
fireStatusEvent(startMessage, false); fireStatusEvent(startMessage, false, false);
saveState(false); saveState(false);
@ -2369,11 +2369,11 @@ public abstract class GameImpl implements Game, Serializable {
} }
@Override @Override
public void fireStatusEvent(String message, boolean withTime) { public void fireStatusEvent(String message, boolean withTime, boolean withTurnInfo) {
if (simulation) { if (simulation) {
return; return;
} }
tableEventSource.fireTableEvent(EventType.STATUS, message, withTime, this); tableEventSource.fireTableEvent(EventType.STATUS, message, withTime, withTurnInfo, this);
} }
@Override @Override

View file

@ -1,10 +1,5 @@
package mage.game.events; package mage.game.events;
import java.io.Serializable;
import java.util.EventObject;
import java.util.UUID;
import mage.cards.Cards; import mage.cards.Cards;
import mage.cards.decks.Deck; import mage.cards.decks.Deck;
import mage.game.Game; import mage.game.Game;
@ -13,8 +8,11 @@ import mage.game.match.MatchOptions;
import mage.game.tournament.MultiplayerRound; import mage.game.tournament.MultiplayerRound;
import mage.game.tournament.TournamentPairing; import mage.game.tournament.TournamentPairing;
import java.io.Serializable;
import java.util.EventObject;
import java.util.UUID;
/** /**
*
* @author BetaSteward_at_googlemail.com * @author BetaSteward_at_googlemail.com
*/ */
public class TableEvent extends EventObject implements ExternalEvent, Serializable { public class TableEvent extends EventObject implements ExternalEvent, Serializable {
@ -37,6 +35,7 @@ public class TableEvent extends EventObject implements ExternalEvent, Serializab
private MatchOptions options; private MatchOptions options;
private int timeout; private int timeout;
private boolean withTime; private boolean withTime;
private boolean withTurnInfo;
public TableEvent(EventType eventType) { public TableEvent(EventType eventType) {
super(eventType); super(eventType);
@ -48,11 +47,16 @@ public class TableEvent extends EventObject implements ExternalEvent, Serializab
} }
public TableEvent(EventType eventType, String message, boolean withTime, Game game) { public TableEvent(EventType eventType, String message, boolean withTime, Game game) {
this(eventType, message, withTime, withTime, game); // turn info with time always (exception: start turn message)
}
public TableEvent(EventType eventType, String message, boolean withTime, boolean withTurnInfo, Game game) {
super(game); super(game);
this.game = game; this.game = game;
this.message = message; this.message = message;
this.eventType = eventType; this.eventType = eventType;
this.withTime = withTime; this.withTime = withTime;
this.withTurnInfo = withTurnInfo;
} }
public TableEvent(EventType eventType, String message, Cards cards, Game game) { public TableEvent(EventType eventType, String message, Cards cards, Game game) {
@ -150,4 +154,8 @@ public class TableEvent extends EventObject implements ExternalEvent, Serializab
public boolean getWithTime() { public boolean getWithTime() {
return withTime; return withTime;
} }
public boolean getWithTurnInfo() {
return withTurnInfo;
}
} }

View file

@ -1,5 +1,3 @@
package mage.game.events; package mage.game.events;
import mage.cards.Cards; import mage.cards.Cards;
@ -8,19 +6,19 @@ import mage.game.Game;
import mage.game.draft.Draft; import mage.game.draft.Draft;
import mage.game.events.TableEvent.EventType; import mage.game.events.TableEvent.EventType;
import mage.game.match.MatchOptions; import mage.game.match.MatchOptions;
import mage.game.tournament.MultiplayerRound;
import mage.game.tournament.TournamentPairing; import mage.game.tournament.TournamentPairing;
import java.io.Serializable; import java.io.Serializable;
import java.util.UUID; import java.util.UUID;
import mage.game.tournament.MultiplayerRound;
/** /**
*
* @author BetaSteward_at_googlemail.com * @author BetaSteward_at_googlemail.com
*/ */
public class TableEventSource implements EventSource<TableEvent>, Serializable { public class TableEventSource implements EventSource<TableEvent>, Serializable {
protected final EventDispatcher<TableEvent> dispatcher = new EventDispatcher<TableEvent>() {}; protected final EventDispatcher<TableEvent> dispatcher = new EventDispatcher<TableEvent>() {
};
@Override @Override
public void addListener(Listener<TableEvent> listener) { public void addListener(Listener<TableEvent> listener) {
@ -41,8 +39,8 @@ public class TableEventSource implements EventSource<TableEvent>, Serializable {
dispatcher.fireEvent(new TableEvent(eventType, message, game)); dispatcher.fireEvent(new TableEvent(eventType, message, game));
} }
public void fireTableEvent(EventType eventType, String message, boolean withTime, Game game) { public void fireTableEvent(EventType eventType, String message, boolean withTime, boolean withTurnInfo, Game game) {
dispatcher.fireEvent(new TableEvent(eventType, message, withTime, game)); dispatcher.fireEvent(new TableEvent(eventType, message, withTime, withTurnInfo, game));
} }
public void fireTableEvent(EventType eventType, UUID playerId, String message, Game game) { public void fireTableEvent(EventType eventType, UUID playerId, String message, Game game) {

View file

@ -333,6 +333,6 @@ public class Turn implements Serializable {
} }
} }
sb.append(')'); sb.append(')');
game.fireStatusEvent(sb.toString(), true); game.fireStatusEvent(sb.toString(), true, false);
} }
} }