198 lines
5.8 KiB
GDScript
198 lines
5.8 KiB
GDScript
extends Node
|
|
|
|
"""
|
|
This module is responsible for making a WebSocket connection to the signaller
|
|
in order to enable establishish WebRTC P2P connections. Another module is
|
|
expected to fully setup the peer connections.
|
|
"""
|
|
|
|
signal lobby_new(lobbiesList)
|
|
signal lobby_delete(id)
|
|
signal lobby_joined(id, peer_id)
|
|
signal lobby_left(id)
|
|
signal peer_joined(peers)
|
|
signal peer_left(id)
|
|
signal candidate_received(data)
|
|
signal offer_received(data)
|
|
signal answer_received(data)
|
|
signal client_id_set(client_id)
|
|
signal peer_id_set(peer_id)
|
|
signal websocket_connected
|
|
signal websocket_disconnected
|
|
|
|
onready var ws: WebSocketClient = WebSocketClient.new()
|
|
|
|
onready var client_id = null
|
|
onready var lobby_id = null
|
|
onready var peer_id = null
|
|
onready var display_name = "UnnamedPlayer"
|
|
onready var lobby_name = null
|
|
|
|
func is_host(): return peer_id == 1
|
|
|
|
const DISPLAY_NAME_FILE = "user://display_name.txt"
|
|
|
|
func _ready():
|
|
var dnf = File.new()
|
|
if dnf.open(DISPLAY_NAME_FILE, File.READ) == OK:
|
|
display_name = dnf.get_as_text()
|
|
dnf.close()
|
|
var _result = ws.connect("data_received", self, "_parse_msg")
|
|
_result = ws.connect("connection_established", self, "_connected")
|
|
_result = ws.connect("connection_closed", self, "_closed")
|
|
_result = ws.connect("connection_error", self, "_closed", [false])
|
|
_result = ws.connect("connection_failed", self, "_closed", [false])
|
|
_result = ws.connect("connection_succeeded", self, "_succ")
|
|
_result = ws.connect("server_close_request", self, "_close_request")
|
|
|
|
func _succ():
|
|
print("WebSocket Connection Succeeded")
|
|
|
|
func close():
|
|
ws.disconnect_from_host()
|
|
|
|
func connect_to_websocket_signaller(url: String):
|
|
print("WebSocket: %s" % ws)
|
|
close()
|
|
print("Attempting to connect to WebSocket signalling server at %s" % url)
|
|
var result = ws.connect_to_url(url)
|
|
if result != OK:
|
|
print("FAILED TO CONNECT TO %s" % url)
|
|
print("WebSocket Connect Result: %s" % result)
|
|
|
|
func _closed(unknown):
|
|
print("WebSocket closed: %s: " % unknown)
|
|
emit_signal("websocket_disconnected")
|
|
|
|
func _close_request(code: int, reason: String):
|
|
print("Received WebSocket close request from signalling server - Code: %s, Reason: %s" % [code, reason])
|
|
|
|
func _connected(protocol = ""):
|
|
print("WebSocket signaller connected via protocol %s" % protocol)
|
|
ws.get_peer(1).set_write_mode(WebSocketPeer.WRITE_MODE_TEXT)
|
|
emit_signal("websocket_connected")
|
|
_send("json:%s" % JSON.print({
|
|
"type": "init",
|
|
"data": {
|
|
"name": display_name
|
|
}
|
|
}))
|
|
|
|
func _process(_delta: float):
|
|
var status: int = ws.get_connection_status()
|
|
if status == WebSocketClient.CONNECTION_CONNECTED or status == WebSocketClient.CONNECTION_CONNECTING:
|
|
ws.poll()
|
|
|
|
func join_lobby(id: String):
|
|
return _send("lobby_join:%s" % id)
|
|
|
|
func create_lobby():
|
|
return _send("lobby_create")
|
|
|
|
func request_lobby_list():
|
|
return _send("request_lobby_list")
|
|
|
|
func request_peer_list():
|
|
return _send("request_peer_list")
|
|
|
|
func set_display_name(new_display_name: String):
|
|
display_name = new_display_name
|
|
_send("update_display_name:%s" % display_name)
|
|
var dnf = File.new()
|
|
if dnf.open(DISPLAY_NAME_FILE, File.WRITE) == OK:
|
|
dnf.store_string(display_name)
|
|
dnf.close()
|
|
|
|
func _send(s: String):
|
|
return ws.get_peer(1).put_packet(s.to_utf8())
|
|
|
|
func set_lobby_name(s: String):
|
|
if is_host():
|
|
_send("json:%s" % JSON.print({"type": "update_lobby", "data": {"name": s}}))
|
|
|
|
func lock_lobby():
|
|
if is_host():
|
|
_send("json:%s" % JSON.print({"type": "update_lobby", "data": {"locked": true}}))
|
|
|
|
func set_lobby_max_players(n: int):
|
|
if is_host():
|
|
_send("json:%s" % JSON.print({"type": "update_lobby", "data": {"maxPlayers": n}}))
|
|
|
|
func _parse_msg():
|
|
var msg: String = ws.get_peer(1).get_packet().get_string_from_utf8()
|
|
if msg.begins_with("json:"):
|
|
var data = JSON.parse(msg.substr(5))
|
|
if data.error == OK:
|
|
handle_message(data.result)
|
|
var _result = ws.get_peer(1).put_packet("".to_utf8())
|
|
else:
|
|
print("Unhandled message: %s" % msg)
|
|
|
|
func handle_message(data: Dictionary):
|
|
match data["type"]:
|
|
"your_id":
|
|
client_id = data["data"]["id"]
|
|
emit_signal("client_id_set", client_id)
|
|
"your_peer_id":
|
|
peer_id = int(data["data"])
|
|
emit_signal("peer_id_set", peer_id)
|
|
|
|
"lobby_list": emit_signal("lobby_new", data["data"])
|
|
"lobby_new": emit_signal("lobby_new", [data])
|
|
"lobby_delete": emit_signal("lobby_delete", data["id"])
|
|
|
|
"lobby_joined":
|
|
lobby_id = data["id"]
|
|
lobby_name = data["name"]
|
|
peer_id = data["peerId"]
|
|
emit_signal("lobby_joined", data["id"], data["peerId"])
|
|
"lobby_left":
|
|
lobby_id = null
|
|
lobby_name = null
|
|
emit_signal("lobby_left", data["id"])
|
|
|
|
"peer_joined":
|
|
print(typeof(data), data)
|
|
if data.get("id") != null: emit_signal("peer_joined", [data])
|
|
else: emit_signal("peer_joined", data["data"])
|
|
"peer_left":
|
|
print("Peer Left: %s" % data)
|
|
emit_signal("peer_left", data["data"])
|
|
|
|
"candidate":
|
|
print("Candidate received - Data: %s" % JSON.print(data["data"]))
|
|
emit_signal("candidate_received", data["data"])
|
|
"offer":
|
|
print("Offer received - Data: %s" % JSON.print(data["data"]))
|
|
emit_signal("offer_received", data["data"])
|
|
"answer":
|
|
print("Answer received - Data: %s" % JSON.print(data["data"]))
|
|
emit_signal("answer_received", data["data"])
|
|
"ping":
|
|
# print("Signaller Ping")
|
|
_send("pong")
|
|
_: print("Unhandled Message - Data: %s" % JSON.print(data))
|
|
|
|
func send_candidate(peerId, mid, index, sdp) -> int:
|
|
return _send("json:%s" % JSON.print({
|
|
"type": "candidate",
|
|
"data": {
|
|
"peerId": peerId,
|
|
"mid": mid,
|
|
"index": index,
|
|
"sdp": sdp
|
|
}
|
|
}))
|
|
|
|
func send_offer(peerId, offer) -> int:
|
|
return _send("json:%s" % JSON.print({ "type": "offer", "data": {"peerId": peerId, "offer": offer }}))
|
|
|
|
func send_answer(peerId, answer) -> int:
|
|
return _send("json:%s" % JSON.print({ "type": "answer", "data": {"peerId": peerId, "answer": answer }}))
|
|
|
|
"""
|
|
elif type.begins_with("S: "):
|
|
emit_signal("lobby_sealed")
|
|
return
|
|
"""
|