|
| 1 | +import _thread |
| 2 | +import json |
| 3 | +import socket |
| 4 | +import uuid |
| 5 | + |
| 6 | +import byte_utils |
| 7 | + |
| 8 | + |
| 9 | +class SocketServer: |
| 10 | + ip = None |
| 11 | + port = None |
| 12 | + motd = None |
| 13 | + version_text = None |
| 14 | + kick_message = None |
| 15 | + samples = None |
| 16 | + server_icon = None |
| 17 | + s = None |
| 18 | + |
| 19 | + def __init__(self, ip, port, motd, version_text, kick_message, samples, server_icon): |
| 20 | + self.ip = ip |
| 21 | + self.port = port |
| 22 | + self.motd = motd |
| 23 | + self.version_text = version_text |
| 24 | + self.kick_message = kick_message |
| 25 | + self.samples = samples |
| 26 | + self.server_icon = server_icon |
| 27 | + |
| 28 | + def on_new_client(self, client_socket, addr): |
| 29 | + data = client_socket.recv(1024) |
| 30 | + (length, i) = byte_utils.read_varint(data, 0) |
| 31 | + (packetID, i) = byte_utils.read_varint(data, i) |
| 32 | + |
| 33 | + if packetID == 0: |
| 34 | + (version, i) = byte_utils.read_varint(data, i) |
| 35 | + (ip, i) = byte_utils.read_utf(data, i) |
| 36 | + (port_tuple, i) = byte_utils.read_ushort(data, i) |
| 37 | + (state, i) = byte_utils.read_varint(data, i) |
| 38 | + if state == 1: |
| 39 | + print("%s:%s has pinged the server (%s:%s)" % (addr[0], addr[1], ip, port_tuple[0])) |
| 40 | + |
| 41 | + motd = {} |
| 42 | + motd["version"] = {} |
| 43 | + motd["version"]["name"] = self.version_text |
| 44 | + motd["version"]["protocol"] = 2 |
| 45 | + motd["players"] = {} |
| 46 | + motd["players"]["max"] = 0 |
| 47 | + motd["players"]["online"] = 0 |
| 48 | + motd["players"]["sample"] = [] |
| 49 | + |
| 50 | + for sample in self.samples: |
| 51 | + motd["players"]["sample"].append({"name": sample, "id": str(uuid.uuid4())}) |
| 52 | + |
| 53 | + motd["description"] = {"text": self.motd} |
| 54 | + |
| 55 | + if len(self.server_icon) > 0: |
| 56 | + motd["favicon"] = self.server_icon |
| 57 | + |
| 58 | + print(motd) |
| 59 | + |
| 60 | + self.write_response(client_socket, json.dumps(motd)) |
| 61 | + elif state == 2: |
| 62 | + print("%s:%s has tried to connect to the server (%s:%s)" % (addr[0], addr[1], ip, port_tuple[0])) |
| 63 | + self.write_response(client_socket, json.dumps({"text": self.kick_message})) |
| 64 | + else: |
| 65 | + print("%s:%s tried to request a login/ping with a unknown state: %s" % (addr[0], addr[1], state)) |
| 66 | + elif packetID == 1: |
| 67 | + (long, i) = byte_utils.read_long(data, i) |
| 68 | + response = bytearray() |
| 69 | + byte_utils.write_varint(response, 9) |
| 70 | + byte_utils.write_varint(response, 1) |
| 71 | + bytearray.append(long) |
| 72 | + client_socket.sendall(bytearray) |
| 73 | + print("Send pong to %s" % addr) |
| 74 | + else: |
| 75 | + print("%s tried to request a unknown packet: %s" % (addr, packetID)) |
| 76 | + |
| 77 | + def write_response(self, client_socket, response): |
| 78 | + response_array = bytearray() |
| 79 | + byte_utils.write_varint(response_array, 0) |
| 80 | + byte_utils.write_utf(response_array, response) |
| 81 | + length = bytearray() |
| 82 | + byte_utils.write_varint(length, len(response_array)) |
| 83 | + client_socket.sendall(length) |
| 84 | + client_socket.sendall(response_array) |
| 85 | + |
| 86 | + def start(self): |
| 87 | + self.s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) |
| 88 | + self.s.bind((self.ip, self.port)) |
| 89 | + self.s.settimeout(5000) |
| 90 | + self.s.listen(30) |
| 91 | + print("Server started!") |
| 92 | + while 1: |
| 93 | + (client, address) = self.s.accept() |
| 94 | + _thread.start_new_thread(self.on_new_client, (client, address,)) |
| 95 | + |
| 96 | + def close(self): |
| 97 | + self.s.close() |
0 commit comments