Add support for chat commands

This commit is contained in:
Tanner Collin 2020-09-08 17:51:27 -06:00
parent 100b4da80d
commit a76d02d53c
3 changed files with 70 additions and 18 deletions

10
bot.py
View File

@ -177,14 +177,10 @@ def bot(global_state):
g.chunks = ChunksManager(g.mcdata) g.chunks = ChunksManager(g.mcdata)
g.chunks.register(g.connection) g.chunks.register(g.connection)
g.chat = ChatManager()
g.chat.register(g.connection)
g.connection.connect() g.connection.connect()
def packet_wrapper(handler): def packet_wrapper(handler):
def wrapper(packet): def wrapper(packet):
print('Wrapper:', handler)
handler(packet, g) handler(packet, g)
return wrapper return wrapper
@ -197,6 +193,10 @@ def bot(global_state):
h3 = packet_wrapper(packet_handlers.handle_block_change) h3 = packet_wrapper(packet_handlers.handle_block_change)
g.connection.register_packet_listener(h3, BlockChangePacket) g.connection.register_packet_listener(h3, BlockChangePacket)
g.chat = ChatManager(g)
h4 = packet_wrapper(packet_handlers.handle_chat)
g.chat.set_handler(h4)
try: try:
while not g.pos: while not g.pos:
time.sleep(TICK) time.sleep(TICK)
@ -207,9 +207,7 @@ def bot(global_state):
time.sleep(TICK) time.sleep(TICK)
print('Chunks loaded.') print('Chunks loaded.')
print('init..')
init(g) init(g)
print('done init')
while g.running: while g.running:
tick(g) tick(g)

View File

@ -3,34 +3,40 @@ import json
from minecraft.networking.packets import clientbound, serverbound from minecraft.networking.packets import clientbound, serverbound
class ChatManager: class ChatManager:
def __init__(self, global_state):
self.g = global_state
self.handler = None
def __init__(self): self.g.connection.register_packet_listener(self.print_chat, clientbound.play.ChatMessagePacket)
return
def translate_chat(self, data): def translate_chat(self, data):
if isinstance(data, str): if isinstance(data, str):
return data return data
elif 'extra' in data: elif 'extra' in data:
return "".join([self.translate_chat(x) for x in data['extra']]) return ''.join([self.translate_chat(x) for x in data['extra']])
elif 'text' in data: elif 'text' in data:
return data['text'] return data['text']
else: else:
return "?" return '?'
def print_chat(self, chat_packet): def print_chat(self, chat_packet):
# TODO: Replace with handler # TODO: Replace with handler
try: try:
print("[%s] %s"%(chat_packet.field_string('position'), self.translate_chat(json.loads(chat_packet.json_data)))) source = chat_packet.field_string('position')
text = self.translate_chat(json.loads(chat_packet.json_data))
print('[%s] %s'%(source, text))
if self.handler:
self.handler((source, text))
except Exception as ex: except Exception as ex:
print("Exception %r on message (%s): %s" % (ex, chat_packet.field_string('position'), chat_packet.json_data)) print('Exception %r on message (%s): %s' % (ex, chat_packet.field_string('position'), chat_packet.json_data))
def register(self, connection): def set_handler(self, func):
connection.register_packet_listener(self.print_chat, clientbound.play.ChatMessagePacket) self.handler = func
def send(self, connection, text): def send(self, text):
if not text: if not text:
# Prevents connection bug when sending empty chat message # Prevents connection bug when sending empty chat message
return return
packet = serverbound.play.ChatPacket() packet = serverbound.play.ChatPacket()
packet.message = text packet.message = text
connection.write_packet(packet) self.g.connection.write_packet(packet)

View File

@ -1,8 +1,11 @@
import re
import time import time
import importlib import importlib
from panda3d.core import LPoint3f from panda3d.core import LPoint3f
from minecraft.networking.packets import Packet, clientbound, serverbound
import utils import utils
importlib.reload(utils) importlib.reload(utils)
import path import path
@ -47,3 +50,48 @@ def handle_position_and_look(packet, g):
print(packet) print(packet)
p = LPoint3f(x=packet.x, y=packet.y, z=packet.z) p = LPoint3f(x=packet.x, y=packet.y, z=packet.z)
g.pos = p g.pos = p
def handle_chat(message, g):
source, text = message
reply = None
match = re.match(r'<(\w+)> (.*)', text)
if match:
sender, text = match.groups()
else:
return
if text.startswith('! '):
text = text[2:]
elif text.startswith('!'):
text = text[1:]
else:
return
if ' ' in text:
command = text.split(' ', 1)[0]
data = text.split(' ', 1)[1]
else:
command = text
if command == 'ping':
reply = 'pong'
if command == 'echo' and data:
reply = data
if command == 'respawn':
packet = serverbound.play.ClientStatusPacket()
packet.action_id = serverbound.play.ClientStatusPacket.RESPAWN
g.connection.write_packet(packet)
reply = 'ok'
if command == 'pos':
reply = str(utils.pint(g.pos))[1:-1]
if command == 'afk':
reply = '/afk'
if reply:
print(reply)
g.chat.send(reply)