mirror of
https://github.com/magefree/mage.git
synced 2025-12-20 10:40:06 -08:00
GUI: improved chat messages with card names and popup supports (example: [[card name]], closes #4189);
This commit is contained in:
parent
d1f9e9cc90
commit
7475ee922a
3 changed files with 64 additions and 54 deletions
|
|
@ -97,6 +97,7 @@ public class ChatPanelBasic extends javax.swing.JPanel {
|
||||||
*/
|
*/
|
||||||
public ChatPanelBasic() {
|
public ChatPanelBasic() {
|
||||||
initComponents();
|
initComponents();
|
||||||
|
txtConversation.enableHyperlinksAndCardPopups();
|
||||||
setBackground(new Color(0, 0, 0, CHAT_ALPHA));
|
setBackground(new Color(0, 0, 0, CHAT_ALPHA));
|
||||||
changeGUISize(GUISizeHelper.chatFont);
|
changeGUISize(GUISizeHelper.chatFont);
|
||||||
if (jScrollPaneTxt != null) {
|
if (jScrollPaneTxt != null) {
|
||||||
|
|
|
||||||
|
|
@ -533,6 +533,7 @@ public class CallbackClientImpl implements CallbackClient {
|
||||||
.append("<br/>").append("<b>/w username message</b> - send private message to player (whisper)")
|
.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>/pings</b> - show players and watchers ping")
|
||||||
.append("<br/>").append("<b>/fix</b> - fix frozen game")
|
.append("<br/>").append("<b>/fix</b> - fix frozen game")
|
||||||
|
.append("<br/>").append("<b>[[card name]]</b> - insert card with popup info")
|
||||||
.toString(),
|
.toString(),
|
||||||
null, null, MessageType.USER_INFO, ChatMessage.MessageColor.BLUE);
|
null, null, MessageType.USER_INFO, ChatMessage.MessageColor.BLUE);
|
||||||
break;
|
break;
|
||||||
|
|
|
||||||
|
|
@ -2,11 +2,13 @@ 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.constants.Constants;
|
||||||
import mage.game.Game;
|
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.managers.ChatManager;
|
import mage.server.managers.ChatManager;
|
||||||
import mage.server.managers.ManagerFactory;
|
import mage.server.managers.ManagerFactory;
|
||||||
|
import mage.util.GameLog;
|
||||||
import mage.utils.SystemUtil;
|
import mage.utils.SystemUtil;
|
||||||
import mage.view.ChatMessage.MessageColor;
|
import mage.view.ChatMessage.MessageColor;
|
||||||
import mage.view.ChatMessage.MessageType;
|
import mage.view.ChatMessage.MessageType;
|
||||||
|
|
@ -24,12 +26,12 @@ import java.util.regex.Pattern;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author BetaSteward_at_googlemail.com
|
* @author BetaSteward_at_googlemail.com, JayDi85
|
||||||
*/
|
*/
|
||||||
public class ChatManagerImpl implements ChatManager {
|
public class ChatManagerImpl implements ChatManager {
|
||||||
|
|
||||||
private static final Logger logger = Logger.getLogger(ChatManagerImpl.class);
|
private static final Logger logger = Logger.getLogger(ChatManagerImpl.class);
|
||||||
private static final HashMap<String, String> userMessages = new HashMap<>();
|
private static final HashMap<String, String> lastUserMessages = new HashMap<>(); // user->chat+message
|
||||||
|
|
||||||
private final ManagerFactory managerFactory;
|
private final ManagerFactory managerFactory;
|
||||||
private final ConcurrentHashMap<UUID, ChatSession> chatSessions = new ConcurrentHashMap<>();
|
private final ConcurrentHashMap<UUID, ChatSession> chatSessions = new ConcurrentHashMap<>();
|
||||||
|
|
@ -59,7 +61,7 @@ public class ChatManagerImpl implements ChatManager {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void clearUserMessageStorage() {
|
public void clearUserMessageStorage() {
|
||||||
userMessages.clear();
|
lastUserMessages.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
@ -91,14 +93,16 @@ public class ChatManagerImpl implements ChatManager {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
final Pattern cardNamePattern = Pattern.compile("\\[(.*?)\\]");
|
final Pattern cardNamePattern = Pattern.compile("\\[\\[(.*?)\\]\\]"); // uses scryfall bot style from github: [[name]]
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void broadcast(UUID chatId, String userName, String message, MessageColor color, boolean withTime, Game game, MessageType messageType, SoundToPlay soundToPlay) {
|
public void broadcast(UUID chatId, String userName, String message, MessageColor color, boolean withTime, Game game, MessageType messageType, SoundToPlay soundToPlay) {
|
||||||
|
String finalMessage = message;
|
||||||
ChatSession chatSession = chatSessions.get(chatId);
|
ChatSession chatSession = chatSessions.get(chatId);
|
||||||
if (chatSession != null) {
|
|
||||||
if (message.startsWith("\\") || message.startsWith("/")) {
|
|
||||||
Optional<User> user = managerFactory.userManager().getUserByName(userName);
|
Optional<User> user = managerFactory.userManager().getUserByName(userName);
|
||||||
|
if (chatSession != null) {
|
||||||
|
// special commads
|
||||||
|
if (message.startsWith("\\") || message.startsWith("/")) {
|
||||||
if (user.isPresent()) {
|
if (user.isPresent()) {
|
||||||
if (!performUserCommand(user.get(), message, chatId, false)) {
|
if (!performUserCommand(user.get(), message, chatId, false)) {
|
||||||
performUserCommand(user.get(), message, chatId, true);
|
performUserCommand(user.get(), message, chatId, true);
|
||||||
|
|
@ -107,66 +111,70 @@ public class ChatManagerImpl implements ChatManager {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// enrich non-game messages with popup hints and other refs
|
||||||
if (messageType != MessageType.GAME && !userName.isEmpty()) {
|
if (messageType != MessageType.GAME && !userName.isEmpty()) {
|
||||||
Optional<User> u = managerFactory.userManager().getUserByName(userName);
|
if (user.isPresent()) {
|
||||||
if (u.isPresent()) {
|
|
||||||
|
|
||||||
User user = u.get();
|
|
||||||
String messageId = chatId.toString() + message;
|
|
||||||
if (messageId.equals(userMessages.get(userName))) {
|
|
||||||
// prevent identical messages
|
|
||||||
String informUser = "Your message appears to be identical to your last message";
|
|
||||||
chatSessions.get(chatId).broadcastInfoToUser(user, informUser);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (message.length() > 500) {
|
|
||||||
message = message.replaceFirst("^(.{500}).*", "$1 (rest of message truncated)");
|
|
||||||
}
|
|
||||||
|
|
||||||
String messageToCheck = message;
|
|
||||||
Matcher matchPattern = cardNamePattern.matcher(message);
|
|
||||||
while (matchPattern.find()) {
|
|
||||||
String cardName = matchPattern.group(1);
|
|
||||||
CardInfo cardInfo = CardRepository.instance.findPreferredCoreExpansionCard(cardName);
|
|
||||||
if (cardInfo != null) {
|
|
||||||
String colour = "silver";
|
|
||||||
if (cardInfo.getCard().getColor(null).isMulticolored()) {
|
|
||||||
colour = "yellow";
|
|
||||||
} else if (cardInfo.getCard().getColor(null).isWhite()) {
|
|
||||||
colour = "white";
|
|
||||||
} else if (cardInfo.getCard().getColor(null).isBlue()) {
|
|
||||||
colour = "blue";
|
|
||||||
} else if (cardInfo.getCard().getColor(null).isBlack()) {
|
|
||||||
colour = "black";
|
|
||||||
} else if (cardInfo.getCard().getColor(null).isRed()) {
|
|
||||||
colour = "red";
|
|
||||||
} else if (cardInfo.getCard().getColor(null).isGreen()) {
|
|
||||||
colour = "green";
|
|
||||||
}
|
|
||||||
messageToCheck = messageToCheck.replaceFirst("\\[" + cardName + "\\]", "card");
|
|
||||||
String displayCardName = "<font bgcolor=orange color=" + colour + '>' + cardName + "</font>";
|
|
||||||
message = message.replaceFirst("\\[" + cardName + "\\]", displayCardName);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
userMessages.put(userName, messageId);
|
|
||||||
|
|
||||||
|
// muted by admin
|
||||||
if (messageType == MessageType.TALK) {
|
if (messageType == MessageType.TALK) {
|
||||||
if (user.getChatLockedUntil() != null) {
|
if (user.get().getChatLockedUntil() != null) {
|
||||||
if (user.getChatLockedUntil().compareTo(Calendar.getInstance().getTime()) > 0) {
|
if (user.get().getChatLockedUntil().compareTo(Calendar.getInstance().getTime()) > 0) {
|
||||||
chatSessions.get(chatId).broadcastInfoToUser(user, "Your chat is muted until " + SystemUtil.dateFormat.format(user.getChatLockedUntil()));
|
// still muted
|
||||||
|
chatSessions.get(chatId).broadcastInfoToUser(user.get(), "Your chat is muted until "
|
||||||
|
+ SystemUtil.dateFormat.format(user.get().getChatLockedUntil()));
|
||||||
return;
|
return;
|
||||||
} else {
|
} else {
|
||||||
user.setChatLockedUntil(null);
|
// reset and allows
|
||||||
|
user.get().setChatLockedUntil(null);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// spam protection
|
||||||
|
String messageId = chatId.toString() + message;
|
||||||
|
if (messageId.equals(lastUserMessages.get(userName))) {
|
||||||
|
chatSessions.get(chatId).broadcastInfoToUser(user.get(), "Ignore duplicated message");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
lastUserMessages.put(userName, messageId);
|
||||||
|
|
||||||
|
// message limit
|
||||||
|
if (message.length() > Constants.MAX_CHAT_MESSAGE_SIZE) {
|
||||||
|
// too big messages must be ignored in parent code, so only system messages possible here
|
||||||
|
message = message.replaceFirst("^(.{" + Constants.MAX_CHAT_MESSAGE_SIZE + "}).*", "$1 (rest of message truncated)");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// insert card names with popup support
|
||||||
|
String messageToCheck = message;
|
||||||
|
Matcher matchPattern = cardNamePattern.matcher(message);
|
||||||
|
int foundCount = 0;
|
||||||
|
while (matchPattern.find()) {
|
||||||
|
// abuse protection
|
||||||
|
foundCount++;
|
||||||
|
if (foundCount > 5) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: add search by lower case and partly text like github bot (maybe slow and abuseable, so test before implement)
|
||||||
|
String searchName = matchPattern.group(1);
|
||||||
|
CardInfo cardInfo = CardRepository.instance.findCard(searchName, true);
|
||||||
|
if (cardInfo != null) {
|
||||||
|
String newMessagePart = GameLog.getColoredObjectIdName(
|
||||||
|
cardInfo.getCard().getColor(),
|
||||||
|
UUID.randomUUID(),
|
||||||
|
cardInfo.getName(),
|
||||||
|
"",
|
||||||
|
cardInfo.getName()
|
||||||
|
);
|
||||||
|
messageToCheck = messageToCheck.replaceFirst("\\[\\[" + searchName + "\\]\\]", "[[" + newMessagePart + "]]");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
chatSession.broadcast(userName, message, color, withTime, game, messageType, soundToPlay);
|
finalMessage = messageToCheck;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// all other messages
|
||||||
|
chatSession.broadcast(userName, finalMessage, color, withTime, game, messageType, soundToPlay);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue