Add support for chat commands
This commit is contained in:
		
							
								
								
									
										10
									
								
								bot.py
									
									
									
									
									
								
							
							
						
						
									
										10
									
								
								bot.py
									
									
									
									
									
								
							@@ -177,14 +177,10 @@ def bot(global_state):
 | 
			
		||||
        g.chunks = ChunksManager(g.mcdata)
 | 
			
		||||
        g.chunks.register(g.connection)
 | 
			
		||||
 | 
			
		||||
        g.chat = ChatManager()
 | 
			
		||||
        g.chat.register(g.connection)
 | 
			
		||||
 | 
			
		||||
        g.connection.connect()
 | 
			
		||||
 | 
			
		||||
    def packet_wrapper(handler):
 | 
			
		||||
        def wrapper(packet):
 | 
			
		||||
            print('Wrapper:', handler)
 | 
			
		||||
            handler(packet, g)
 | 
			
		||||
        return wrapper
 | 
			
		||||
 | 
			
		||||
@@ -197,6 +193,10 @@ def bot(global_state):
 | 
			
		||||
    h3 = packet_wrapper(packet_handlers.handle_block_change)
 | 
			
		||||
    g.connection.register_packet_listener(h3, BlockChangePacket)
 | 
			
		||||
 | 
			
		||||
    g.chat = ChatManager(g)
 | 
			
		||||
    h4 = packet_wrapper(packet_handlers.handle_chat)
 | 
			
		||||
    g.chat.set_handler(h4)
 | 
			
		||||
 | 
			
		||||
    try:
 | 
			
		||||
        while not g.pos:
 | 
			
		||||
            time.sleep(TICK)
 | 
			
		||||
@@ -207,9 +207,7 @@ def bot(global_state):
 | 
			
		||||
            time.sleep(TICK)
 | 
			
		||||
        print('Chunks loaded.')
 | 
			
		||||
 | 
			
		||||
        print('init..')
 | 
			
		||||
        init(g)
 | 
			
		||||
        print('done init')
 | 
			
		||||
 | 
			
		||||
        while g.running:
 | 
			
		||||
            tick(g)
 | 
			
		||||
 
 | 
			
		||||
@@ -3,34 +3,40 @@ import json
 | 
			
		||||
from minecraft.networking.packets import clientbound, serverbound
 | 
			
		||||
 | 
			
		||||
class ChatManager:
 | 
			
		||||
    def __init__(self, global_state):
 | 
			
		||||
        self.g = global_state
 | 
			
		||||
        self.handler = None
 | 
			
		||||
 | 
			
		||||
    def __init__(self):
 | 
			
		||||
        return
 | 
			
		||||
        self.g.connection.register_packet_listener(self.print_chat, clientbound.play.ChatMessagePacket)
 | 
			
		||||
 | 
			
		||||
    def translate_chat(self, data):
 | 
			
		||||
        if isinstance(data, str):
 | 
			
		||||
            return 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:
 | 
			
		||||
            return data['text']
 | 
			
		||||
        else:
 | 
			
		||||
            return "?"
 | 
			
		||||
            return '?'
 | 
			
		||||
 | 
			
		||||
    def print_chat(self, chat_packet):
 | 
			
		||||
        # TODO: Replace with handler
 | 
			
		||||
        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:
 | 
			
		||||
            print("Exception %r on message (%s): %s" % (ex, chat_packet.field_string('position'), chat_packet.json_data))
 | 
			
		||||
    
 | 
			
		||||
    def register(self, connection):
 | 
			
		||||
        connection.register_packet_listener(self.print_chat, clientbound.play.ChatMessagePacket)
 | 
			
		||||
    
 | 
			
		||||
    def send(self, connection, text):
 | 
			
		||||
            print('Exception %r on message (%s): %s' % (ex, chat_packet.field_string('position'), chat_packet.json_data))
 | 
			
		||||
 | 
			
		||||
    def set_handler(self, func):
 | 
			
		||||
        self.handler = func
 | 
			
		||||
 | 
			
		||||
    def send(self, text):
 | 
			
		||||
        if not text:
 | 
			
		||||
            # Prevents connection bug when sending empty chat message
 | 
			
		||||
            return
 | 
			
		||||
        packet = serverbound.play.ChatPacket()
 | 
			
		||||
        packet.message = text
 | 
			
		||||
        connection.write_packet(packet)
 | 
			
		||||
        self.g.connection.write_packet(packet)
 | 
			
		||||
 
 | 
			
		||||
@@ -1,8 +1,11 @@
 | 
			
		||||
import re
 | 
			
		||||
import time
 | 
			
		||||
import importlib
 | 
			
		||||
 | 
			
		||||
from panda3d.core import LPoint3f
 | 
			
		||||
 | 
			
		||||
from minecraft.networking.packets import Packet, clientbound, serverbound
 | 
			
		||||
 | 
			
		||||
import utils
 | 
			
		||||
importlib.reload(utils)
 | 
			
		||||
import path
 | 
			
		||||
@@ -47,3 +50,48 @@ def handle_position_and_look(packet, g):
 | 
			
		||||
    print(packet)
 | 
			
		||||
    p = LPoint3f(x=packet.x, y=packet.y, z=packet.z)
 | 
			
		||||
    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)
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user