Skip to content

Instantly share code, notes, and snippets.

@jegor377
Last active May 20, 2025 18:37
Show Gist options
  • Save jegor377/da6b14e3c4c188d9773c5438c7ba0bbb to your computer and use it in GitHub Desktop.
Save jegor377/da6b14e3c4c188d9773c5438c7ba0bbb to your computer and use it in GitHub Desktop.
Godot TCP API Client Code
extends Node
const BIG_ENDIAN = 'big'
const LITTLE_ENDIAN = 'little'
const INT_SIZE = 4
const ERROR_INDEX = 0
const DATA_INDEX = 1
const MAX_SIGNALS_COUNT = 255
onready var stream_peer = StreamPeerTCP.new()
onready var signals = []
func _process(delta):
if is_connected_to_server():
pool_packets()
remove_old_signals()
func int2bytes(integer: int, out_mode: String = BIG_ENDIAN):
var conv = var2bytes(integer)
var result = PoolByteArray()
var start_pos = 4
if out_mode == BIG_ENDIAN:
for i in range(start_pos, conv.size()):
result.append(conv[conv.size() - i + start_pos - 1])
elif out_mode == LITTLE_ENDIAN:
for i in range(start_pos, conv.size()):
result.append(conv[i])
if result.size() > 0:
return result
func bytes2int(bytes: PoolByteArray, in_mode: String = BIG_ENDIAN):
var formated_int = PoolByteArray([2, 0, 0, 0])
if in_mode == BIG_ENDIAN:
for i in range(0, bytes.size()):
formated_int.append(bytes[bytes.size() - i - 1])
elif in_mode == LITTLE_ENDIAN:
formated_int.append_array(bytes)
return bytes2var(formated_int)
func pool_packets():
if stream_peer.get_available_bytes() > 0:
var packet_size = stream_peer.get_partial_data(INT_SIZE)
assert(packet_size[ERROR_INDEX] == OK)
packet_size = bytes2int(packet_size[DATA_INDEX])
print("Received packed with size: ", packet_size)
var raw_packet: PoolByteArray = stream_peer.get_partial_data(packet_size)
assert(raw_packet[ERROR_INDEX] == OK)
var raw_packet_data = raw_packet[DATA_INDEX]
print_packet(raw_packet[DATA_INDEX])
var json_packet = parse_json(raw_packet_data.get_string_from_utf8())
signals.append(json_packet)
func remove_old_signals():
if signals.size() > MAX_SIGNALS_COUNT:
signals.pop_front()
func pop_signal(signal_name):
# Pops first signal with specified name from the signals stack and returns it.
for signal_id in range(0, signals.size()):
if signals[signal_id]["signal_name"] == signal_name:
var result = signals[signal_id]
signals.remove(signal_id)
return result
return null
func print_packet(packet):
print("Packet: ", packet.get_string_from_utf8())
func is_connected_to_server():
return stream_peer.get_status() == StreamPeerTCP.STATUS_CONNECTED
func connect_to_server(host, port):
stream_peer.connect_to_host(host, port)
func send(signal_name: String, data_packet: Dictionary = {}):
assert(is_connected_to_server())
var prepared_json_packet = {
"signal_name": signal_name,
"data": data_packet
}
var packet_bytes = JSON.print(prepared_json_packet).to_utf8()
var packet_size = len(packet_bytes)
var prepared_final_packet = int2bytes(packet_size)
prepared_final_packet.append_array(packet_bytes)
stream_peer.put_data(prepared_final_packet)
func _exit_tree():
if is_connected_to_server():
send("disconnect")
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment