Created
November 2, 2025 00:41
-
-
Save NoodlesNZ/7d697b6b8c19596db5ea97913be58977 to your computer and use it in GitHub Desktop.
Minecraft proxy
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| import socket, threading, time | |
| LISTEN_HOST, LISTEN_PORT = "127.0.0.1", 25566 | |
| TARGET_HOST, TARGET_PORT = "192.168.4.1", 25565 | |
| # minimal VarInt reader | |
| def read_varint(data, off=0): | |
| num, shift, i = 0, 0, 0 | |
| while True: | |
| if off + i >= len(data) or i >= 5: | |
| return None, 0 # need more | |
| b = data[off + i] | |
| num |= (b & 0x7F) << shift | |
| i += 1; shift += 7 | |
| if (b & 0x80) == 0: | |
| return num, i | |
| def extract_mc_packet(buf): | |
| """Return (packet_bytes, total_len) if a complete packet (VarInt length + payload) is present.""" | |
| length, len_len = read_varint(buf, 0) | |
| if length is None: | |
| return None, 0 | |
| total = len_len + length | |
| if len(buf) < total: | |
| return None, 0 | |
| return buf[:total], total | |
| def pipe_client_to_server(cs, ss): | |
| buf = bytearray() | |
| sent_handshake = False | |
| cs.settimeout(0.1) | |
| while True: | |
| try: | |
| chunk = cs.recv(65535) | |
| if not chunk: | |
| break | |
| buf.extend(chunk) | |
| # send complete packets one by one | |
| while True: | |
| pkt, used = extract_mc_packet(buf) | |
| if not pkt: break | |
| # first packet during connection is the handshake | |
| if not sent_handshake: | |
| ss.sendall(pkt) # send only the handshake | |
| sent_handshake = True | |
| del buf[:used] | |
| time.sleep(0.15) # <-- the crucial pause | |
| continue | |
| # forward subsequent packets normally | |
| ss.sendall(pkt) | |
| del buf[:used] | |
| except socket.timeout: | |
| continue | |
| try: | |
| ss.shutdown(socket.SHUT_WR) | |
| except Exception: | |
| pass | |
| def pipe_server_to_client(ss, cs): | |
| while True: | |
| data = ss.recv(65535) | |
| if not data: | |
| break | |
| cs.sendall(data) | |
| try: | |
| cs.shutdown(socket.SHUT_WR) | |
| except Exception: | |
| pass | |
| def handle_client(csock, addr): | |
| with socket.create_connection((TARGET_HOST, TARGET_PORT)) as ssock: | |
| t1 = threading.Thread(target=pipe_client_to_server, args=(csock, ssock), daemon=True) | |
| t2 = threading.Thread(target=pipe_server_to_client, args=(ssock, csock), daemon=True) | |
| t1.start(); t2.start() | |
| t1.join(); t2.join() | |
| def main(): | |
| with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as ls: | |
| ls.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) | |
| ls.bind((LISTEN_HOST, LISTEN_PORT)) | |
| ls.listen(64) | |
| print(f"Listening on {LISTEN_HOST}:{LISTEN_PORT}, forwarding to {TARGET_HOST}:{TARGET_PORT}") | |
| while True: | |
| c, a = ls.accept() | |
| threading.Thread(target=handle_client, args=(c, a), daemon=True).start() | |
| if __name__ == "__main__": | |
| main() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment