# res://scripts/network.gd extends Node signal connected(room_id: String) signal disconnected(reason: String) signal state_changed() signal message_received(type: String, payload: Variant) signal error(msg: String) const colyseus := preload("res://addons/godot_colyseus/lib/colyseus.gd") const RoomState := preload("res://scripts/room_state.gd") const Room := preload("res://addons/godot_colyseus/lib/room.gd") var client: colyseus.Client var room: Room var state: RoomState var _connecting := false var _endpoint := "" #func is_connected() -> bool: #return room != null func connect_and_join(endpoint: String, room_name: String = "my_room") -> void: if _connecting: return if room != null: emit_signal("error", "Already connected.") return _connecting = true _endpoint = endpoint client = colyseus.Client.new(endpoint) var promise = client.join_or_create(RoomState, room_name) await promise.completed _connecting = false if promise.get_state() == promise.State.Failed: var msg := "Join failed: %s" % str(promise.get_error()) emit_signal("error", msg) return # old addon: result is a property room = promise.result if room == null: emit_signal("error", "Join succeeded but room is null (promise.result).") return state = room.get_state() as RoomState if state == null: emit_signal("error", "Joined but could not cast state to RoomState.") return # --- wire listeners --- room.on_state_change.on(Callable(self, "_on_state_change")) # if addon supports on_leave / on_error, hook them too (safe-guarded) if "on_leave" in room: room.on_leave.on(Callable(self, "_on_room_left")) if "on_error" in room: room.on_error.on(Callable(self, "_on_room_error")) emit_signal("connected", room.room_id) func leave() -> void: if room == null: return # some addons use room.leave(), some room.disconnect() if room.has_method("leave"): room.leave() elif room.has_method("disconnect"): pass #room.disconnect() _cleanup("left") func send(type: String, payload: Variant = null) -> void: if room == null: emit_signal("error", "Cannot send, not connected.") return room.send(type, payload) func listen_message(type: String) -> void: if room == null: emit_signal("error", "Cannot listen, not connected.") return room.on_message(type).on(Callable(self, "_on_message").bind(type)) func reconnect(room_name: String = "my_room") -> void: _cleanup("reconnect") await connect_and_join(_endpoint, room_name) func _on_state_change(_new_state = null) -> void: emit_signal("state_changed") func _on_message(payload: Variant, type: String) -> void: emit_signal("message_received", type, payload) func _on_room_left(code = null) -> void: _cleanup("room_left %s" % str(code)) func _on_room_error(code = null, message = null) -> void: _cleanup("room_error %s %s" % [str(code), str(message)]) func _cleanup(reason: String) -> void: room = null state = null emit_signal("disconnected", reason)