extends Node2D var server: TCPServer = null # Called when the node enters the scene tree for the first time. func _ready(): server = TCPServer.new() var status = server.listen(25565) if status != OK: print('статус не ок') var segment_bits = 0x7F var continue_bit = 0x80 func read_var_int(conn: StreamPeerTCP): var value = 0 var position = 0 var byte while true: byte = conn.get_8() value |= (byte & segment_bits) << position if (byte & continue_bit) == 0: break position += 7 if position >= 32: assert(false, 'varint слишком большой') return value func shr(value: int, shift: int): if value < 0: return ((-value) >> shift) | (0x7000 >> shift) return value >> shift func write_var_int_test(value: int): var result = 0 while true: if (value & ~segment_bits) == 0: result = (result << 8) | value return result result = (result << 8) | ((value & segment_bits) | continue_bit) value = shr(value, 7) func write_var_int(value: int, conn: StreamPeerTCP): var result = 0 while true: if (value & ~segment_bits) == 0: conn.put_8(value) print('%x' % value) return conn.put_8((value & segment_bits) | continue_bit) print('%x' % ((value & segment_bits) | continue_bit)) value = shr(value, 7) return result func read_minecraft_string(conn: StreamPeerTCP): var character_count = read_var_int(conn) var str = "" while character_count > 0: var byte = conn.get_8() character_count -= 1 if byte < 0x80: # 1 byte sequence (ASCII) str += char(byte) elif byte < 0xE0: str += char(((byte & 0x1F) << 6) | (conn.get_8() & 0x3F)) character_count -= 1 elif byte < 0xF0: # 3 byte sequence str += char(((byte & 0x0F) << 12) | ((conn.get_8() & 0x3F) << 6) | (conn.get_8() & 0x3F)) character_count -= 1 else: # 4 byte sequence (very rare) str += char(((byte & 0x07) << 18) | ((conn.get_8() & 0x3F) << 12) | ((conn.get_8() & 0x3F) << 6) | (conn.get_8() & 0x3F)) character_count -= 1 return str func handle(conn: StreamPeerTCP): var size = read_var_int(conn) print('size %s' % size) var packet_id = conn.get_8() print('packet_id %s' % packet_id) if packet_id != 0x00: return false var protocol_version = read_var_int(conn) print('Protocol version: ', protocol_version) var host = read_minecraft_string(conn) print('Host %s' % host) var port = conn.get_16() print('Port %s' % port) var next_state = read_var_int(conn) print('Next state %s' % next_state) if next_state != 1: return false size = read_var_int(conn) print('size %s' % size) packet_id = conn.get_8() print('packet_id %s' % packet_id) if packet_id != 0x00: return false var response = str({ "version": { "name": "1.19.3", "protocol": protocol_version }, "players": { "max": 100, "online": 5, "sample": [ { "name": "thinkofdeath", "id": "4566e69f-c907-48ee-8d71-d7ba5aa00d20" } ] }, "description": { "text": "Hello world" }, "enforcesSecureChat": true }) print('отправляем данные') conn.put_8(0x00) size = write_var_int_test(response.length()) print('size %s; ' % response.length(), '%x' % size) write_var_int(response.length(), conn) conn.poll() print('status %s' % conn.get_status()) conn.put_data(response.to_utf8_buffer()) print('отправили данные') print('client sent something') return true var conns: Array[StreamPeerTCP] = [] # Called every frame. 'delta' is the elapsed time since the previous frame. func _process(delta): for i in range(conns.size() - 1, -1, -1): var conn = conns[i] conn.poll() if conn.get_status() != 2: print('Connection %s:%s has status %s, killing' % [conn.get_connected_host(), conn.get_connected_port(), conn.get_status()]) conns.remove_at(i) if server.is_connection_available(): var conn: StreamPeerTCP = server.take_connection() conn.big_endian = true print('Took connection from %s:%s, status %s' % [conn.get_connected_host(), conn.get_connected_port(), conn.get_status()]) var status = handle(conn) if not status: print('Сервер отклонил подключение по причине пошёл нафиг') conn.disconnect_from_host() print() conns.push_back(conn)