improved parse_chat

This commit is contained in:
əlemi 2021-11-22 12:57:10 +01:00
parent 0d43b4b5bf
commit f47d82733c
3 changed files with 28 additions and 16 deletions

View file

@ -37,7 +37,7 @@ if __name__ == "__main__":
@client.on_packet(PacketChat, ConnectionState.PLAY) @client.on_packet(PacketChat, ConnectionState.PLAY)
async def print_chat(packet: PacketChat): async def print_chat(packet: PacketChat):
msg = parse_chat(json.loads(packet.message), color=color) msg = parse_chat(packet.message, ansi_color=color)
print(f"[{packet.position}] {msg}") print(f"[{packet.position}] {msg}")
client.run() # will block and start asyncio event loop client.run() # will block and start asyncio event loop

View file

@ -1,5 +1,6 @@
import asyncio import asyncio
import logging import logging
import json
import uuid import uuid
from dataclasses import dataclass from dataclasses import dataclass
@ -20,7 +21,7 @@ from .mc.proto.login.serverbound import PacketLoginStart, PacketEncryptionBegin
from .mc.proto.login.clientbound import ( from .mc.proto.login.clientbound import (
PacketCompress, PacketDisconnect, PacketEncryptionBegin, PacketLoginPluginRequest, PacketSuccess PacketCompress, PacketDisconnect, PacketEncryptionBegin, PacketLoginPluginRequest, PacketSuccess
) )
from .util import encryption from .util import encryption, helpers
LOGGER = logging.getLogger(__name__) LOGGER = logging.getLogger(__name__)
@ -246,7 +247,7 @@ class MinecraftClient(CallbacksHolder, Runnable):
self._logger.info("Login success, joining world...") self._logger.info("Login success, joining world...")
return True return True
elif isinstance(packet, PacketDisconnect): elif isinstance(packet, PacketDisconnect):
self._logger.error("Kicked while logging in") self._logger.error("Kicked while logging in : %s", helpers.parse_chat(packet.reason))
break break
return False return False
@ -263,7 +264,7 @@ class MinecraftClient(CallbacksHolder, Runnable):
keep_alive_packet = PacketKeepAliveResponse(340, keepAliveId=packet.keepAliveId) keep_alive_packet = PacketKeepAliveResponse(340, keepAliveId=packet.keepAliveId)
await self.dispatcher.write(keep_alive_packet) await self.dispatcher.write(keep_alive_packet)
elif isinstance(packet, PacketKickDisconnect): elif isinstance(packet, PacketKickDisconnect):
self._logger.error("Kicked while in game") self._logger.error("Kicked while in game : %s", helpers.parse_chat(packet.reason))
break break
self.run_callbacks(Packet, packet) self.run_callbacks(Packet, packet)
self.run_callbacks(type(packet), packet) self.run_callbacks(type(packet), packet)

View file

@ -1,4 +1,8 @@
from termcolor import colored import json
from typing import Union
from termcolor import colored # TODO don't use a lib and put ANSI escaped by hand maybe?
_EQUIVALENTS = { _EQUIVALENTS = {
"dark_red" : "red", "dark_red" : "red",
@ -32,18 +36,25 @@ def _parse_formatted_block(msg:dict) -> str:
else: else:
return colored(msg["text"], "white", attrs=attr) return colored(msg["text"], "white", attrs=attr)
def parse_chat(msg:dict, color:bool=True) -> str: def parse_chat(msg:Union[dict,str], ansi_color:bool=False) -> str:
"""Recursive function to parse minecraft chat json, with optional colors""" """Recursive function to parse minecraft chat json, with optional colors"""
if isinstance(msg, str):
try:
data = json.loads(msg)
except ValueError:
return str(msg) # It's not json, it's already plaintext
else:
data = msg
out = "" out = ""
if "text" in msg: if "text" in data:
if color: if ansi_color:
out += _parse_formatted_block(msg) out += _parse_formatted_block(data)
else: else:
out += msg["text"] out += data["text"]
if "with" in msg: if "with" in data:
for elem in msg["with"]: for elem in data["with"]:
out += parse_chat(elem, color) out += parse_chat(elem, ansi_color)
if "extra" in msg: if "extra" in data:
for elem in msg["extra"]: for elem in data["extra"]:
out += parse_chat(elem, color) out += parse_chat(elem, ansi_color)
return out return out