Files
airplane-mode/scripts/network.gd

110 lines
2.9 KiB
GDScript

# 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)