Message JSON
See original GitHub issueHello, currently having an issue with messages that I’m having a little trouble diagnosing and fixing. When connecting to mc.civclassic.com
which is a server with various mods, there’s a case in which a ServerChatPacket
’s full text will be stringed JSON. Below is an example of what happens when merely dumping packet.getMessage().getFullText()
into the console.
[22:57:47] [INFO] You have engaged in combat. Type /ct to check your timer.
[22:57:47] [INFO] You have been Combat Tagged on Login
[22:58:07] [INFO] You are no longer in combat.
[22:58:15] [INFO] {"hoverEvent":{"action":"show_text","value":[{"text":"Location: [world <x> <y> <z>]\nGroup: <group name>\nType: Logging"}]},"text":"ºb * <Player> entered snitch at [world <x> <y> <z>]"}
[22:59:31] [INFO] <Cranite> local chat test
[22:59:57] [INFO] [Group] Cranite: group chat test
There are two possible reasons that I can think of:-
-
The JukeAlert plugin is sending stringed JSON as actual message contents rather than the message itself, and so this becomes an issue when MCProtocolLib does not recursively attempt to parse messages. JukeAlert’s alert sending code is here but I believe this to be unlikely, as both the Minecraft native client and Minecraft Console Client render it without a problem. Although both may recursively parse messages, who knows.
-
The message itself does not get parsed correctly by MCProtocolLib, either here or here. Not sure which as both have the same outcome, and I can’t seem to use
MinecraftProtocol.registerIncoming
to replaceServerChatPacket
with a different class so I can see the raw data involved. I’ve even gone so far as to packet sniff my own data, but to no avail.
My most recent solution has been to add a listener that listens for any received ServerChatPacket
to which it will then attempt to recursively parse its contents into JSON until it fails at which point it will emit that as a MessageEvent
, like so:
# Listener
public class MessageListener extends SessionAdapter {
@Override
public void packetReceived(PacketReceivedEvent event) {
Session session = event.getSession();
if (event.getPacket() instanceof ServerChatPacket) {
ServerChatPacket packet = event.getPacket();
Message message = parseMessagePacket(packet.getMessage());
session.callEvent(new MessageEvent(session, message, packet.getType()));
}
}
public static Message parseMessagePacket(Message message) {
try {
JsonParser parser = new JsonParser();
JsonElement json = parser.parse(message.getFullText());
Message parsed = Message.fromJson(json);
return parseMessagePacket(parsed);
}
catch(Exception e) {
return message;
}
}
}
# Connected Event
public class MessageEvent extends ConnectedEvent {
private Message message;
private MessageType type;
public MessageEvent(Session session, Message message, MessageType type) {
super(session);
this.message = message;
this.type = type;
}
@Override
public void call(SessionListener listener) {
listener.connected(this);
}
public Message getMessage() {
return this.message;
}
public MessageType getType() {
return this.type;
}
}
But not even this works… any suggestions?
If you’d like to test this out yourself, you’ll need two accounts, or one account and a volunteer with their own.
- Log on to CivClassics
- Place down a note block or juke box
- Punch it with smooth stone, or iron ingot, or diamond to create a snitch (you should see the enchantment table rune effect collapse into the block.)
- Now have the bot login to that account.
- Have your second account, or your volunteer run in and out of the snitch’s boundary, which is 10 blocks from the snitch.
This should re-create the issue I am having.
Issue Analytics
- State:
- Created 5 years ago
- Comments:9 (5 by maintainers)
Top GitHub Comments
If I’m honest, the current Message setup needs an overhaul. It doesn’t really fit in with the philosophy of being merely a protocol implantation if it’s making decisions over messages, such as relegating anything it cannot parse with its own understanding as a text message. It would be better in my opinion if messages were parsed into a generic message class with hases and getters and letting the developer decide how to deal with the contents. You can provide tools such as
getFullText()
still, but the ultimate decider of what a message is should be up to the programmer, not the protocol.Sorry for the long delay, it’s been a busy few weeks. Finally got this implemented in https://github.com/Steveice10/MCProtocolLib/commit/050ddd3911ed989406b62ee5fa23d8a147e615a7
Let me know if there are still any issues with chat parsing.