Search code examples
pythonproxypackageminecraftpython-sockets

Minecraft proxy in python using socket, only 2 packages get sent


I'm trying to code a proxy in python for a Minecraft server that is hosted on my own computer. While I want to intercept and modify the packages that get sent between the client and the server, at first I just want to send all packages through without modifying them. The problem is that only 2 packages get sent: one from the server to the client and one from the client to the server.

I'm using the socket and threading library in python. Also important to note is that in the server.properties file I have online_mode turned off, because when online_mode was turned on the server tried to encrypt the connection which led to Minecraft getting stuck at "Encrypting..." when connecting via the proxy.

While I have tried this many times, I still get the same results, so here's an example from ChatGPT:

import socket
import threading

def handle_client(client_socket, target_host, target_port):
    # Connect to the target server
    target_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    target_socket.connect((target_host, target_port))

    # Relay data between client and target
    while True:
        data = client_socket.recv(4096)
        if len(data) == 0:
            print("Client connection closed.")
            break
        print(f'Received from client: {data}')
        target_socket.send(data)
        print("Sent to target.")

        response = target_socket.recv(4096)
        if len(response) == 0:
            print("Target connection closed.")
            break
        print(f'Received from target: {response}')
        client_socket.send(response)
        print("Sent to client.")

    # Close the connections
    client_socket.close()
    target_socket.close()

def start_proxy(proxy_port, target_host, target_port):
    # Create a server socket
    server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    server_socket.bind(('localhost', proxy_port))
    server_socket.listen(5)
    print(f'Proxy server listening on port {proxy_port}')

    while True:
        client_socket, addr = server_socket.accept()
        print(f'Accepted connection from {addr[0]}:{addr[1]}')
        client_handler = threading.Thread(
            target=handle_client,
            args=(client_socket, target_host, target_port)
        )
        client_handler.start()

# Usage example
proxy_port = 55555
target_host = "localhost"
target_port = 25565

start_proxy(proxy_port, target_host, target_port)

My Minecraft server runs on localhost (a.k.a 127.0.0.1) on port 25565 and the proxy listens on localhost:55555. When I run the code and then join the server via the proxy (localhost:55555) in Minecraft, I get the following printed messages:

Proxy server listening on port 55555
Accepted connection from 127.0.0.1:52403
Received from client: b'\x10\x00\xfa\x05\tlocalhost\xd9\x03\x02"\x00\x0fBoterBramKroket\x01\x11Zu\x9eC\xa3N\xd6\xbf\x03\\\x00\xe6\x96\xcc\x00'
Sent to target.
Received from target: b'\x03\x03\x80\x02'
Sent to client.
Client connection closed.

I don't understand why the other packages won't get sent. I hope someone has experience in coding minecraft proxies and can tell me more, thanks in advance!


Solution

  • Hi will test I founded how to do it here the code. So the in your code is that problem is you need to handle server and client in thread because the two in the same while as recv wait for data and that blocking the client part as two separate thread send server data to client and one send client data to the server. Thanks for the help with the base code !

    import socket
    import threading
    
    class handle_server(threading.Thread):
        def __init__(self,client_socket,target_host, target_port,target_socket):
            super().__init__()
            self.client_socket = client_socket
            self.target_host = target_host
            self.target_port = target_port
            self.target_socket = target_socket
        def run(self):
            client_socket = self.client_socket
            target_host   = self.target_host
            target_port   = self.target_port
            target_socket = self.target_socket
            while True:
                data = client_socket.recv(4096 * 8 * 8 * 8)
                if len(data) == 0:
                    print("Client connection closed.")
                    break
                print(f'Received from server: {data}')
                target_socket.send(data)
                print("Sent to target.")
    
            client_socket.close()
            target_socket.close()
    
    
    class handle_client_Thread(threading.Thread):
        def __init__(self,client_socket,target_host, target_port,target_socket):
            self.client_socket = client_socket
            self.target_host = target_host
            self.target_port = target_port
            self.target_socket = target_socket
            super().__init__()
        def run(self):
            client_socket = self.client_socket
            target_host   = self.target_host
            target_port   = self.target_port
            target_socket = self.target_socket
            while True:
                response = target_socket.recv(4096 * 8 * 8 * 8)
                if len(response) == 0:
                    print("Target connection closed.")
                    break
                print(f'Received from client: {response}')
                client_socket.send(response)
                print("Sent to client.")
    
            client_socket.close()
            target_socket.close()
    
    def handle_client(client_socket, target_host, target_port):
        # Connect to the target server
        target_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        target_socket.connect((target_host, target_port))
        handle_server(client_socket, target_host, target_port,target_socket).start()
        handle_client_Thread(client_socket, target_host, target_port,target_socket).start()
    
    def start_proxy(proxy_port, target_host, target_port):
        # Create a server socket
        server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        server_socket.bind(('localhost', proxy_port))
        server_socket.listen(5)
        print(f'Proxy server listening on port {proxy_port}')
    
        while True:
            client_socket, addr = server_socket.accept()
            print(f'Accepted connection from {addr[0]}:{addr[1]}')
            client_handler = threading.Thread(
                target=handle_client,
                args=(client_socket, target_host, target_port)
            )
            client_handler.start()
    
    
    # Usage example
    proxy_port = 55555
    target_host = "localhost"
    target_port = 25565
    
    start_proxy(proxy_port, target_host, target_port)