More mplayer cleanup
This commit is contained in:
parent
9c41eaa3b4
commit
202c44cabf
8 changed files with 209 additions and 452 deletions
|
@ -36,7 +36,6 @@ func goto_game():
|
||||||
goto_scene("game")
|
goto_scene("game")
|
||||||
|
|
||||||
func lobby_browser():
|
func lobby_browser():
|
||||||
client.close()
|
|
||||||
goto_scene("lobby_browser")
|
goto_scene("lobby_browser")
|
||||||
|
|
||||||
func lobby():
|
func lobby():
|
||||||
|
|
|
@ -6,17 +6,21 @@ const DEFAULT_SIGNALLER_URL = "ws://localhost:8888"
|
||||||
# const DEFAULT_SIGNALLER_URL = "wss://webrtc-signaller.deno.dev:443"
|
# const DEFAULT_SIGNALLER_URL = "wss://webrtc-signaller.deno.dev:443"
|
||||||
|
|
||||||
const DEFAULT_ICE_SERVERS = [
|
const DEFAULT_ICE_SERVERS = [
|
||||||
{ "urls": ["stun:[::1]:3478", "stun:stun.l.google.com:19302"] },
|
# first element in this array is for STUN
|
||||||
|
{ "urls": ["stun:localhost:3478", "stun:stun.l.google.com:19302"] },
|
||||||
# { "urls": ["stun:stun.l.google.com:19302"] }, # just google
|
# { "urls": ["stun:stun.l.google.com:19302"] }, # just google
|
||||||
# { "urls": ["stun:[::1]:3478"] }, # just localhost
|
# { "urls": ["stun:localhost:3478"] }, # just localhost
|
||||||
|
# {} # TURN servers
|
||||||
]
|
]
|
||||||
|
|
||||||
signal lobby_data(lobbies)
|
signal lobby_data(lobbies)
|
||||||
|
signal lobby_begin_join(uuid)
|
||||||
signal lobby_joined(lobby_and_peer)
|
signal lobby_joined(lobby_and_peer)
|
||||||
signal lobby_left(id)
|
signal lobby_left(uuid)
|
||||||
signal lobby_delete(id)
|
signal lobby_delete(uuid)
|
||||||
|
|
||||||
signal peer_data(peers)
|
signal peer_data(peers)
|
||||||
|
signal peer_created(peer)
|
||||||
signal peer_left(id)
|
signal peer_left(id)
|
||||||
signal peer_init(id)
|
signal peer_init(id)
|
||||||
|
|
||||||
|
@ -34,7 +38,7 @@ signal signaller_connected
|
||||||
signal signaller_connection_failure
|
signal signaller_connection_failure
|
||||||
signal signaller_disconnected
|
signal signaller_disconnected
|
||||||
|
|
||||||
onready var webrtc = WebRTCMultiplayer.new()
|
onready var webrtc = null
|
||||||
onready var websocket = WebSocketClient.new()
|
onready var websocket = WebSocketClient.new()
|
||||||
|
|
||||||
onready var display_name = DEFAULT_DISPLAY_NAME setget set_display_name
|
onready var display_name = DEFAULT_DISPLAY_NAME setget set_display_name
|
||||||
|
@ -50,10 +54,6 @@ func _init():
|
||||||
func _ready():
|
func _ready():
|
||||||
display_name = _load_display_name()
|
display_name = _load_display_name()
|
||||||
|
|
||||||
webrtc.connect("connection_succeeded", self, "_webrtc_connection_succeeded")
|
|
||||||
webrtc.connect("peer_connected", self, "_webrtc_peer_connected")
|
|
||||||
webrtc.connect("peer_disconnected", self, "_webrtc_peer_disconnected")
|
|
||||||
|
|
||||||
websocket.connect("connection_established", self, "_signaller_connected")
|
websocket.connect("connection_established", self, "_signaller_connected")
|
||||||
websocket.connect("data_received", self, "_signaller_data")
|
websocket.connect("data_received", self, "_signaller_data")
|
||||||
websocket.connect("server_close_request", self, "_signaller_close_request")
|
websocket.connect("server_close_request", self, "_signaller_close_request")
|
||||||
|
@ -61,7 +61,16 @@ func _ready():
|
||||||
websocket.connect("connection_error", self, "_signaller_error", [false])
|
websocket.connect("connection_error", self, "_signaller_error", [false])
|
||||||
websocket.connect("connection_failed", self, "_signaller_error", [false])
|
websocket.connect("connection_failed", self, "_signaller_error", [false])
|
||||||
|
|
||||||
|
func is_signaller_connected():
|
||||||
|
return websocket.get_connection_status() in [
|
||||||
|
websocket.CONNECTION_CONNECTED,
|
||||||
|
websocket.CONNECTION_CONNECTED,
|
||||||
|
]
|
||||||
|
|
||||||
|
func is_in_lobby(): return current_lobby != null
|
||||||
|
|
||||||
func connect_to_signaller(url = signaller_url):
|
func connect_to_signaller(url = signaller_url):
|
||||||
|
if url == signaller_url and is_signaller_connected(): return
|
||||||
signaller_url = url
|
signaller_url = url
|
||||||
close()
|
close()
|
||||||
print("Attempting to connect to WebSocket signalling server at %s" % signaller_url)
|
print("Attempting to connect to WebSocket signalling server at %s" % signaller_url)
|
||||||
|
@ -70,7 +79,7 @@ func connect_to_signaller(url = signaller_url):
|
||||||
print("Failed to connect to WebSocket signalling server at %s: %s" % [signaller_url, result])
|
print("Failed to connect to WebSocket signalling server at %s: %s" % [signaller_url, result])
|
||||||
|
|
||||||
func close():
|
func close():
|
||||||
webrtc.close()
|
if webrtc != null: webrtc.close()
|
||||||
websocket.disconnect_from_host()
|
websocket.disconnect_from_host()
|
||||||
|
|
||||||
func set_display_name(new_display_name: String):
|
func set_display_name(new_display_name: String):
|
||||||
|
@ -81,15 +90,19 @@ func request_lobby_list():
|
||||||
return _send("request_lobby_list")
|
return _send("request_lobby_list")
|
||||||
|
|
||||||
func join_lobby(id: String):
|
func join_lobby(id: String):
|
||||||
return _send("lobby_join:%s" % id)
|
emit_signal("lobby_begin_join", id)
|
||||||
|
call_deferred("_send", "lobby_join:%s" % id)
|
||||||
|
|
||||||
|
func leave_lobby():
|
||||||
|
return _send("lobby_leave")
|
||||||
|
|
||||||
func get_lobby_name():
|
func get_lobby_name():
|
||||||
return current_lobby.name
|
return current_lobby.name if current_lobby.has("name") else null
|
||||||
|
|
||||||
func create_lobby():
|
func create_lobby():
|
||||||
return _send("lobby_create")
|
_send("lobby_create")
|
||||||
|
|
||||||
func is_host(): return get_tree().get_network_unique_id() == 1
|
func is_host(): return is_signaller_connected() and is_in_lobby() and get_tree().get_network_unique_id() == 1
|
||||||
|
|
||||||
func set_lobby_name(s: String):
|
func set_lobby_name(s: String):
|
||||||
if is_host(): _send_json({"name": s}, "update_lobby")
|
if is_host(): _send_json({"name": s}, "update_lobby")
|
||||||
|
@ -141,7 +154,7 @@ func _signaller_connected(protocol = ""):
|
||||||
|
|
||||||
func _process(_delta: float):
|
func _process(_delta: float):
|
||||||
var status: int = websocket.get_connection_status()
|
var status: int = websocket.get_connection_status()
|
||||||
if status == WebSocketClient.CONNECTION_CONNECTED or status == WebSocketClient.CONNECTION_CONNECTING:
|
if status in [WebSocketClient.CONNECTION_CONNECTED, WebSocketClient.CONNECTION_CONNECTING]:
|
||||||
websocket.poll()
|
websocket.poll()
|
||||||
|
|
||||||
func _signaller_data():
|
func _signaller_data():
|
||||||
|
@ -155,36 +168,105 @@ func _signaller_data():
|
||||||
var d = msg.split(":", false, 2)
|
var d = msg.split(":", false, 2)
|
||||||
_process_signaller_message({type = d[0], data = d[1]})
|
_process_signaller_message({type = d[0], data = d[1]})
|
||||||
|
|
||||||
|
func _init_webrtc_peer(data):
|
||||||
|
webrtc = WebRTCMultiplayer.new()
|
||||||
|
webrtc.connect("connection_succeeded", self, "_webrtc_connection_succeeded")
|
||||||
|
webrtc.connect("peer_connected", self, "_webrtc_peer_connected")
|
||||||
|
webrtc.connect("peer_disconnected", self, "_webrtc_peer_disconnected")
|
||||||
|
webrtc.initialize(int(data), true)
|
||||||
|
get_tree().network_peer = webrtc
|
||||||
|
|
||||||
|
func _deinit_webrtc_peer():
|
||||||
|
webrtc.close()
|
||||||
|
get_tree().network_peer = null
|
||||||
|
webrtc = null
|
||||||
|
|
||||||
func _process_signaller_message(data: Dictionary):
|
func _process_signaller_message(data: Dictionary):
|
||||||
match data["type"]:
|
match data["type"]:
|
||||||
# "init":
|
# "init":
|
||||||
"init_peer":
|
"init_peer": _init_webrtc_peer(data.data)
|
||||||
webrtc.initialize(int(data.data), true)
|
|
||||||
get_tree().network_peer = webrtc
|
|
||||||
|
|
||||||
"lobby_data": emit_signal("lobby_data", data.data)
|
"lobby_data": emit_signal("lobby_data", data.data)
|
||||||
"lobby_delete": emit_signal("lobby_delete", data.id)
|
"lobby_delete": emit_signal("lobby_delete", data.uuid)
|
||||||
"lobby_joined":
|
"lobby_joined": _lobby_joined(data)
|
||||||
current_lobby = data
|
"lobby_left": _lobby_left(data.uuid)
|
||||||
emit_signal("lobby_joined", data)
|
|
||||||
"lobby_left": emit_signal("lobby_left", data.id)
|
|
||||||
|
|
||||||
"peer_data":
|
"peer_data": _signaller_peer_data([data] if data.has("id") else data.data)
|
||||||
emit_signal("peer_data", [data] if data.has("id") else data.data)
|
"peer_left": _signaller_peer_left(data.id)
|
||||||
"peer_left": emit_signal("peer_left", data.data)
|
|
||||||
|
|
||||||
"candidate":
|
"candidate": _webrtc_candidate_received(data)
|
||||||
print("Candidate received - Data: %s" % JSON.print(data))
|
"offer": _webrtc_offer_received(data)
|
||||||
emit_signal("candidate_received", data)
|
"answer": _webrtc_answer_received(data)
|
||||||
"offer":
|
|
||||||
print("Offer received - Data: %s" % JSON.print(data))
|
|
||||||
emit_signal("offer_received", data)
|
|
||||||
"answer":
|
|
||||||
print("Answer received - Data: %s" % JSON.print(data))
|
|
||||||
emit_signal("answer_received", data)
|
|
||||||
"ping": _send("pong")
|
"ping": _send("pong")
|
||||||
_: print("Unhandled Message - Data: %s" % JSON.print(data))
|
_: print("Unhandled Message - Data: %s" % JSON.print(data))
|
||||||
|
|
||||||
|
func _lobby_joined(lobby_data):
|
||||||
|
current_lobby = lobby_data
|
||||||
|
print("Lobby Joined: %s" % lobby_data)
|
||||||
|
emit_signal("lobby_joined", lobby_data)
|
||||||
|
|
||||||
|
func _lobby_left(uuid):
|
||||||
|
current_lobby = null
|
||||||
|
print("Lobby Left: %s" % uuid)
|
||||||
|
emit_signal("lobby_left", uuid)
|
||||||
|
_deinit_webrtc_peer()
|
||||||
|
|
||||||
|
func _create_peer(data):
|
||||||
|
var id = data.id
|
||||||
|
var peer: WebRTCPeerConnection = WebRTCPeerConnection.new()
|
||||||
|
print("Creating WebRTC Peer %s" % [id])
|
||||||
|
peer.connect("session_description_created", self, "_webrtc_offer_created", [id])
|
||||||
|
peer.connect("ice_candidate_created", self, "_new_ice_candidate", [id])
|
||||||
|
peer.initialize({"iceServers": DEFAULT_ICE_SERVERS})
|
||||||
|
webrtc.add_peer(peer, int(id))
|
||||||
|
# this guarantees only one peer sends the offer and that offers are never
|
||||||
|
# sent to ourselves?
|
||||||
|
if int(id) > webrtc.get_unique_id(): peer.create_offer()
|
||||||
|
emit_signal("peer_created", data)
|
||||||
|
|
||||||
|
func _webrtc_offer_created(type, data, id):
|
||||||
|
print("WebRTC %s created for peer %s" % [type, id])
|
||||||
|
if not webrtc.has_peer(int(id)): return
|
||||||
|
print("WebRTC local description set for peer %s" % id)
|
||||||
|
webrtc.get_peer(id).connection.set_local_description(type, data)
|
||||||
|
print("--> Local Description: %s" % JSON.print(data))
|
||||||
|
if type == "offer": send_offer(id, data)
|
||||||
|
else: send_answer(id, data)
|
||||||
|
|
||||||
|
func _new_ice_candidate(mid, index, sdp, id):
|
||||||
|
print("New ICE candidate for peer %s" % id)
|
||||||
|
send_candidate(id, mid, index, sdp)
|
||||||
|
|
||||||
|
func _signaller_peer_left(id): if peers.has(id): peers.delete(id)
|
||||||
|
|
||||||
|
func _signaller_peer_data(peers):
|
||||||
|
for peer in peers:
|
||||||
|
if peer.has("id") and not webrtc.has_peer(int(peer.id)):
|
||||||
|
_create_peer(peer)
|
||||||
|
emit_signal("peer_data", peers)
|
||||||
|
|
||||||
|
func _webrtc_offer_received(data):
|
||||||
|
if webrtc.has_peer(int(data.id)):
|
||||||
|
print("Setting offer remote description for peer %s" % data.id)
|
||||||
|
print("--> Offer: %s" % JSON.print(data.offer))
|
||||||
|
webrtc.get_peer(data.id).connection.set_remote_description("offer", data.offer)
|
||||||
|
else:
|
||||||
|
print("Received an offer for a peer with ID %s that hasn't been added" % data.id)
|
||||||
|
|
||||||
|
func _webrtc_answer_received(data):
|
||||||
|
if webrtc.has_peer(data.id):
|
||||||
|
print("Setting answer remote description for peer %s" % data.id)
|
||||||
|
print("--> Answer: %s" % JSON.print(data.answer))
|
||||||
|
webrtc.get_peer(data.id).connection.set_remote_description("answer", data.answer)
|
||||||
|
|
||||||
|
func _webrtc_candidate_received(data):
|
||||||
|
if webrtc.has_peer(data.id):
|
||||||
|
print("Adding ice candidate for peer %s" % data.id)
|
||||||
|
print("--> Candidate: %s" % JSON.print(data.candidate))
|
||||||
|
webrtc.get_peer(data.id).connection.add_ice_candidate(data.mid, data.index, data.sdp)
|
||||||
|
else:
|
||||||
|
print("Received candidate for non-existant peer %s" % data.id)
|
||||||
|
|
||||||
func _load_display_name():
|
func _load_display_name():
|
||||||
var _display_name = DEFAULT_DISPLAY_NAME
|
var _display_name = DEFAULT_DISPLAY_NAME
|
||||||
var display_name_file = File.new()
|
var display_name_file = File.new()
|
||||||
|
|
|
@ -1,197 +0,0 @@
|
||||||
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.
|
|
||||||
"""
|
|
||||||
|
|
||||||
const DISPLAY_NAME_FILE = "user://display_name.txt"
|
|
||||||
const DEFAULT_DISPLAY_NAME = "UnnamedPlayer"
|
|
||||||
|
|
||||||
# lobby data
|
|
||||||
signal lobby_data(lobbies)
|
|
||||||
signal lobby_joined(lobby_and_peer)
|
|
||||||
signal lobby_left(id)
|
|
||||||
signal lobby_delete(id)
|
|
||||||
|
|
||||||
# peer data
|
|
||||||
signal peer_data(peers)
|
|
||||||
signal peer_left(id)
|
|
||||||
signal peer_init(peer_id)
|
|
||||||
|
|
||||||
# WebRTC negotiations
|
|
||||||
signal candidate_received(cand)
|
|
||||||
signal offer_received(data)
|
|
||||||
signal answer_received(data)
|
|
||||||
|
|
||||||
# underlying websocket
|
|
||||||
signal received_message
|
|
||||||
signal connected
|
|
||||||
signal connection_failure
|
|
||||||
signal disconnected
|
|
||||||
|
|
||||||
onready var websocket: WebSocketClient = WebSocketClient.new()
|
|
||||||
onready var client_id = null
|
|
||||||
onready var display_name = DEFAULT_DISPLAY_NAME setget set_display_name
|
|
||||||
onready var peer_id = null
|
|
||||||
|
|
||||||
onready var lobby_data = null
|
|
||||||
|
|
||||||
var websocket_url = null
|
|
||||||
|
|
||||||
func _init(url):
|
|
||||||
websocket_url = url
|
|
||||||
|
|
||||||
func _ready():
|
|
||||||
display_name = _load_display_name()
|
|
||||||
websocket.connect("data_received", self, "_handle_data")
|
|
||||||
websocket.connect("connection_established", self, "_connected")
|
|
||||||
# websocket.connect("connection_succeeded", self, "_connection_succeeded")
|
|
||||||
websocket.connect("connection_closed", self, "_closed")
|
|
||||||
websocket.connect("connection_error", self, "_connection_error", [false])
|
|
||||||
websocket.connect("connection_failed", self, "_connection_error", [false])
|
|
||||||
websocket.connect("server_close_request", self, "_close_request")
|
|
||||||
|
|
||||||
func connect_websocket():
|
|
||||||
close()
|
|
||||||
print("Attempting to connect to WebSocket signalling server at %s" % websocket_url)
|
|
||||||
var result = websocket.connect_to_url(websocket_url)
|
|
||||||
if result != OK:
|
|
||||||
print("Failed to connect to WebSocket signalling server at %s: %s" % [websocket_url, result])
|
|
||||||
|
|
||||||
func close():
|
|
||||||
websocket.disconnect_from_host()
|
|
||||||
|
|
||||||
func set_display_name(new_display_name: String):
|
|
||||||
display_name = new_display_name
|
|
||||||
_send("update_display_name:%s" % display_name)
|
|
||||||
|
|
||||||
func request_lobby_list():
|
|
||||||
return _send("request_lobby_list")
|
|
||||||
|
|
||||||
func join_lobby(id: String):
|
|
||||||
return _send("lobby_join:%s" % id)
|
|
||||||
|
|
||||||
func create_lobby():
|
|
||||||
return _send("lobby_create")
|
|
||||||
|
|
||||||
func is_host(): return peer_id == 1
|
|
||||||
|
|
||||||
func set_lobby_name(s: String):
|
|
||||||
if is_host(): _send_json({"name": s}, "update_lobby")
|
|
||||||
|
|
||||||
func lock_lobby():
|
|
||||||
if is_host(): _send_json({"locked": true}, "update_lobby")
|
|
||||||
|
|
||||||
func set_lobby_max_players(n: int):
|
|
||||||
if is_host(): _send_json({"maxPlayers": n}, "update_lobby")
|
|
||||||
|
|
||||||
func request_peer_list(): _send("request_peer_list")
|
|
||||||
|
|
||||||
func send_candidate(peerId, mid, index, sdp) -> int:
|
|
||||||
return _send_json({"peerId": peerId, "mid": mid, "index": index, "sdp": sdp}, "candidate")
|
|
||||||
|
|
||||||
func send_offer(peerId, offer) -> int:
|
|
||||||
return _send_json({"peerId": peerId, "offer": offer }, "offer")
|
|
||||||
|
|
||||||
func send_answer(peerId, answer) -> int:
|
|
||||||
return _send_json({"peerId": peerId, "answer": answer }, "answer")
|
|
||||||
|
|
||||||
func get_lobby_name(): return lobby_data.name
|
|
||||||
|
|
||||||
func _closed(code):
|
|
||||||
print("WebSocket closed: %s: " % code)
|
|
||||||
emit_signal("disconnected")
|
|
||||||
|
|
||||||
func _close_request(code: int, reason: String):
|
|
||||||
print("Received WebSocket close request from signalling server - Code: %s, Reason: %s" % [code, reason])
|
|
||||||
# TODO: does this fire _closed?
|
|
||||||
|
|
||||||
func _connected(protocol = ""):
|
|
||||||
print("Signaller connected via WebSocket using protocol %s" % protocol)
|
|
||||||
websocket.get_peer(1).set_write_mode(WebSocketPeer.WRITE_MODE_TEXT)
|
|
||||||
emit_signal("connected")
|
|
||||||
_send_json({name = display_name}, "init")
|
|
||||||
|
|
||||||
func _process(_delta: float):
|
|
||||||
var status: int = websocket.get_connection_status()
|
|
||||||
if status == WebSocketClient.CONNECTION_CONNECTED or status == WebSocketClient.CONNECTION_CONNECTING:
|
|
||||||
websocket.poll()
|
|
||||||
|
|
||||||
func _handle_data():
|
|
||||||
var msg: String = websocket.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:
|
|
||||||
_process_message(data.result)
|
|
||||||
var _result = websocket.get_peer(1).put_packet("".to_utf8())
|
|
||||||
else:
|
|
||||||
var d = msg.split(":", false, 2)
|
|
||||||
_process_message({type = d[0], data = d[1]})
|
|
||||||
|
|
||||||
func _process_message(data: Dictionary):
|
|
||||||
match data["type"]:
|
|
||||||
"init":
|
|
||||||
client_id = data.id
|
|
||||||
print("Signaller Received init response: %s" % data)
|
|
||||||
"init_peer":
|
|
||||||
print("init_peer: %s" % data)
|
|
||||||
peer_id = int(data.data)
|
|
||||||
emit_signal("peer_init", peer_id)
|
|
||||||
|
|
||||||
"lobby_data": emit_signal("lobby_data", data.data)
|
|
||||||
"lobby_delete": emit_signal("lobby_delete", data.id)
|
|
||||||
|
|
||||||
"lobby_joined":
|
|
||||||
print("lobby_joined: %s" % data)
|
|
||||||
lobby_data = data
|
|
||||||
emit_signal("lobby_joined", data)
|
|
||||||
"lobby_left":
|
|
||||||
peer_id = null
|
|
||||||
emit_signal("lobby_left", data["id"])
|
|
||||||
|
|
||||||
"peer_data":
|
|
||||||
emit_signal("peer_data", [data] if data.has("id") else data["data"])
|
|
||||||
"peer_left":
|
|
||||||
print("Peer Left: %s" % data)
|
|
||||||
emit_signal("peer_left", data["data"])
|
|
||||||
|
|
||||||
"candidate":
|
|
||||||
print("Candidate received - Data: %s" % JSON.print(data))
|
|
||||||
emit_signal("candidate_received", data)
|
|
||||||
"offer":
|
|
||||||
print("Offer received - Data: %s" % JSON.print(data))
|
|
||||||
emit_signal("offer_received", data)
|
|
||||||
"answer":
|
|
||||||
print("Answer received - Data: %s" % JSON.print(data))
|
|
||||||
emit_signal("answer_received", data)
|
|
||||||
"ping":
|
|
||||||
_send("pong")
|
|
||||||
_: print("Unhandled Message - Data: %s" % JSON.print(data))
|
|
||||||
|
|
||||||
func _load_display_name():
|
|
||||||
var _display_name = DEFAULT_DISPLAY_NAME
|
|
||||||
var display_name_file = File.new()
|
|
||||||
if display_name_file.open(DISPLAY_NAME_FILE, File.READ) == OK:
|
|
||||||
_display_name = display_name_file.get_as_text()
|
|
||||||
else:
|
|
||||||
print("Failed to open %s for reading display_name, creating default" % DISPLAY_NAME_FILE)
|
|
||||||
_store_display_name()
|
|
||||||
display_name_file.close()
|
|
||||||
return _display_name
|
|
||||||
|
|
||||||
func _store_display_name():
|
|
||||||
var display_name_file = File.new()
|
|
||||||
if display_name_file.open(DISPLAY_NAME_FILE, File.WRITE) == OK:
|
|
||||||
display_name_file.store_string(display_name)
|
|
||||||
else:
|
|
||||||
print("Failed to open %s for writing display_name" % DISPLAY_NAME_FILE)
|
|
||||||
display_name_file.close()
|
|
||||||
|
|
||||||
func _send(s: String):
|
|
||||||
return websocket.get_peer(1).put_packet(s.to_utf8())
|
|
||||||
|
|
||||||
func _send_json(data: Dictionary, type=null):
|
|
||||||
if type != null: data["type"] = type
|
|
||||||
_send("json:%s" % JSON.print(data))
|
|
|
@ -1,136 +0,0 @@
|
||||||
extends Node
|
|
||||||
|
|
||||||
"""
|
|
||||||
This module sets up WebRTC peer connections.
|
|
||||||
"""
|
|
||||||
|
|
||||||
signal peer_connected(id)
|
|
||||||
signal peer_disconnected(id)
|
|
||||||
signal connection_succeeded()
|
|
||||||
signal signaller_disconnected()
|
|
||||||
|
|
||||||
onready var webrtc = WebRTCMultiplayer.new()
|
|
||||||
|
|
||||||
var signaller_client = null
|
|
||||||
var ice_servers = null
|
|
||||||
var peers = {}
|
|
||||||
var peers_id_mappings = {}
|
|
||||||
|
|
||||||
func _init(_ice_servers, _signaller_client):
|
|
||||||
ice_servers = _ice_servers
|
|
||||||
signaller_client = _signaller_client
|
|
||||||
print("Initializing WebRTCNegotiator with ICE servers: %s" % ice_servers)
|
|
||||||
|
|
||||||
func _ready():
|
|
||||||
signaller_client.connect("disconnected", self, "_signaller_disconnected")
|
|
||||||
|
|
||||||
signaller_client.connect("offer_received", self, "_offer_received")
|
|
||||||
signaller_client.connect("answer_received", self, "_answer_received")
|
|
||||||
signaller_client.connect("candidate_received", self, "_candidate_received")
|
|
||||||
|
|
||||||
signaller_client.connect("peer_data", self, "_peer_data")
|
|
||||||
|
|
||||||
webrtc.connect("connection_succeeded", self, "_connection_succeeded")
|
|
||||||
webrtc.connect("peer_connected", self, "_peer_connected")
|
|
||||||
webrtc.connect("peer_disconnected", self, "_peer_disconnected")
|
|
||||||
|
|
||||||
# connect("lobby_sealed", self, "lobby_sealed")
|
|
||||||
|
|
||||||
add_child(self.signaller_client)
|
|
||||||
|
|
||||||
func _peer_connected(peer_id):
|
|
||||||
print("FULLY CONNECTED PEER: %s" % peer_id)
|
|
||||||
emit_signal("peer_connected", peer_id)
|
|
||||||
|
|
||||||
func _peer_disconnected(peer_id):
|
|
||||||
print("FULLY CONNECTED PEER DISCONNECTING: %s" % peer_id)
|
|
||||||
emit_signal("peer_disconnected")
|
|
||||||
|
|
||||||
func _connection_succeeded():
|
|
||||||
print("FULLY CONNECTED")
|
|
||||||
emit_signal("connection_succeeded")
|
|
||||||
|
|
||||||
func _signaller_disconnected():
|
|
||||||
print("SIGNALLER DISCONNECTED")
|
|
||||||
emit_signal("signaller_disconnected")
|
|
||||||
|
|
||||||
func close():
|
|
||||||
webrtc.close()
|
|
||||||
signaller_client.close()
|
|
||||||
|
|
||||||
func connect_to_signaller():
|
|
||||||
signaller_client.connect_websocket()
|
|
||||||
|
|
||||||
func peer_by_peer_id(peer_id):
|
|
||||||
if peers_id_mappings.has(peer_id):
|
|
||||||
var p = peers_id_mappings[peer_id]
|
|
||||||
if peers.has(p):
|
|
||||||
return peers[p]
|
|
||||||
return null
|
|
||||||
|
|
||||||
func _create_peer(peer_id):
|
|
||||||
# if peer_id == signaller_client.peer_id: return
|
|
||||||
var peer: WebRTCPeerConnection = WebRTCPeerConnection.new()
|
|
||||||
print("New Net Peer with peer_id %d" % [peer_id])
|
|
||||||
var _peer_init_results = peer.initialize({"iceServers": ice_servers})
|
|
||||||
var _result = peer.connect("session_description_created", self, "_offer_created", [peer_id])
|
|
||||||
_result = peer.connect("ice_candidate_created", self, "_new_ice_candidate", [peer_id])
|
|
||||||
webrtc.add_peer(peer, peer_id)
|
|
||||||
var uid = webrtc.get_unique_id()
|
|
||||||
if peer_id > uid:
|
|
||||||
var offer_result = peer.create_offer()
|
|
||||||
print("Create Offer Result: %s" % offer_result)
|
|
||||||
else:
|
|
||||||
print("Did not create offer: %d <= %d" % [peer_id, uid])
|
|
||||||
return peer
|
|
||||||
|
|
||||||
func _new_ice_candidate(mid, index, sdp, peer_id):
|
|
||||||
print("New ICE Candidate - MID: %s, Index: %s, SDP: %s, PeerID: %s" % [mid, index, sdp, peer_id])
|
|
||||||
signaller_client.send_candidate(peer_id, mid, index, sdp)
|
|
||||||
|
|
||||||
func _offer_created(type, data, peer_id):
|
|
||||||
print("%s created - PeerID: %s, Data: %s" % [type, peer_id, JSON.print(data)])
|
|
||||||
if not webrtc.has_peer(peer_id): return
|
|
||||||
webrtc.get_peer(peer_id).connection.set_local_description(type, data)
|
|
||||||
if type == "offer": signaller_client.send_offer(peer_id, data)
|
|
||||||
else: signaller_client.send_answer(peer_id, data)
|
|
||||||
|
|
||||||
func _peer_id_set(peer_id):
|
|
||||||
print("Peer ID received %s - setting up to peer..." % [peer_id])
|
|
||||||
webrtc.initialize(peer_id, true)
|
|
||||||
get_tree().network_peer = webrtc
|
|
||||||
|
|
||||||
func _peer_data(peers):
|
|
||||||
for i in range(len(peers)):
|
|
||||||
var peer = peers[i]
|
|
||||||
if peer.has("peerId"):
|
|
||||||
var peer_id = peer.peerId
|
|
||||||
if not webrtc.has_peer(peer_id):
|
|
||||||
_create_peer(peer_id)
|
|
||||||
|
|
||||||
func peer_disconnected(id):
|
|
||||||
print("Peer %s disconnected" % id)
|
|
||||||
if webrtc.has_peer(id):
|
|
||||||
webrtc.remove_peer(id)
|
|
||||||
|
|
||||||
func _offer_received(data):
|
|
||||||
var id = data.peerId
|
|
||||||
if webrtc.has_peer(id):
|
|
||||||
print("Setting offer remote description: %s" % JSON.print(data.offer))
|
|
||||||
webrtc.get_peer(id).connection.set_remote_description("offer", data.offer)
|
|
||||||
else:
|
|
||||||
print("Received an offer for a peer with ID %s that hasn't been added" % id)
|
|
||||||
|
|
||||||
func _answer_received(data):
|
|
||||||
var id = data.peerId
|
|
||||||
if webrtc.has_peer(id):
|
|
||||||
print("Setting answer remote description: %s" % JSON.print(data))
|
|
||||||
webrtc.get_peer(id).connection.set_remote_description("answer", data.answer)
|
|
||||||
|
|
||||||
func _candidate_received(data):
|
|
||||||
var id = data.peerId
|
|
||||||
if webrtc.has_peer(id):
|
|
||||||
print("Adding ice candidate: %s" % JSON.print(data))
|
|
||||||
webrtc.get_peer(id).connection.add_ice_candidate(data.mid, data.index, data.sdp)
|
|
||||||
else:
|
|
||||||
print("Received candidate for non-existant peer %s" % id)
|
|
|
@ -2,7 +2,7 @@ extends HBoxContainer
|
||||||
|
|
||||||
class_name LobbyControl
|
class_name LobbyControl
|
||||||
|
|
||||||
export(String) var id = "Some UUID"
|
export(String) var uuid = "Some UUID"
|
||||||
export(String) var display_name = "Lobby" setget set_display_name
|
export(String) var display_name = "Lobby" setget set_display_name
|
||||||
export(int) var max_players = 20 setget set_max_players
|
export(int) var max_players = 20 setget set_max_players
|
||||||
export(int) var current_players = 1 setget set_current_players
|
export(int) var current_players = 1 setget set_current_players
|
||||||
|
@ -14,7 +14,7 @@ func _ready():
|
||||||
func _update_text():
|
func _update_text():
|
||||||
$Label.text = "%s (%d/%d players)" % [display_name, current_players, max_players]
|
$Label.text = "%s (%d/%d players)" % [display_name, current_players, max_players]
|
||||||
|
|
||||||
const keys = ["id", "display_name", "max_players", "current_players", "locked"]
|
const keys = ["uuid", "display_name", "max_players", "current_players", "locked"]
|
||||||
func set_with_dict(dict):
|
func set_with_dict(dict):
|
||||||
if dict.has("name"): self.display_name = dict["name"]
|
if dict.has("name"): self.display_name = dict["name"]
|
||||||
for k in keys:
|
for k in keys:
|
||||||
|
@ -34,4 +34,4 @@ func set_current_players(n):
|
||||||
_update_text()
|
_update_text()
|
||||||
|
|
||||||
func _on_join_pressed():
|
func _on_join_pressed():
|
||||||
Global.signaller_client.join_lobby(id)
|
Global.client.join_lobby(uuid)
|
||||||
|
|
|
@ -15,14 +15,14 @@ func _ready():
|
||||||
display_name_edit.text = Global.client.display_name
|
display_name_edit.text = Global.client.display_name
|
||||||
Global.client.connect("lobby_data", self, "_lobby_data")
|
Global.client.connect("lobby_data", self, "_lobby_data")
|
||||||
Global.client.connect("lobby_delete", self, "_lobby_delete")
|
Global.client.connect("lobby_delete", self, "_lobby_delete")
|
||||||
Global.client.connect("lobby_joined", self, "_lobby_joined")
|
Global.client.connect("lobby_begin_join", self, "_lobby_begin_join")
|
||||||
Global.client.connect("lobby_left", self, "_lobby_left")
|
Global.client.connect("lobby_left", self, "_lobby_left")
|
||||||
Global.client.connect("signaller_connected", self, "_signaller_connected")
|
Global.client.connect("signaller_connected", self, "_signaller_connected")
|
||||||
Global.client.connect("signaller_disconnected", self, "_signaller_disconnected")
|
Global.client.connect("signaller_disconnected", self, "_signaller_disconnected")
|
||||||
Global.client.connect_to_signaller()
|
if Global.client.is_signaller_connected():
|
||||||
|
_signaller_connected()
|
||||||
if Global.check_onetime_flag("create-lobby"):
|
else:
|
||||||
Global.client.create_lobby()
|
Global.client.connect_to_signaller()
|
||||||
|
|
||||||
# TODO: add search
|
# TODO: add search
|
||||||
func _input(ev):
|
func _input(ev):
|
||||||
|
@ -39,59 +39,59 @@ func _signaller_disconnected():
|
||||||
Global.main_menu()
|
Global.main_menu()
|
||||||
|
|
||||||
func _signaller_connected():
|
func _signaller_connected():
|
||||||
Global.client.request_lobby_list()
|
print("Lobby Browser: Signaller Connected")
|
||||||
|
if Global.check_onetime_flag("create-lobby"):
|
||||||
|
call_deferred("_on_create_lobby_pressed")
|
||||||
|
else:
|
||||||
|
Global.client.request_lobby_list()
|
||||||
|
|
||||||
func _lobby_joined(data):
|
func _lobby_begin_join(data):
|
||||||
print("Lobby Joined: %s" % data)
|
print("Joining Lobby: %s" % data)
|
||||||
Global.lobby()
|
Global.lobby()
|
||||||
|
|
||||||
func _lobby_left(_id):
|
func _lobby_left(_uuid):
|
||||||
Global.lobby_browser()
|
Global.lobby_browser()
|
||||||
|
|
||||||
func _on_back_pressed():
|
func _on_back_pressed():
|
||||||
Global.main_menu()
|
Global.main_menu()
|
||||||
|
|
||||||
func _on_create_lobby_pressed():
|
func _on_create_lobby_pressed():
|
||||||
|
Global.lobby()
|
||||||
Global.client.create_lobby()
|
Global.client.create_lobby()
|
||||||
|
|
||||||
func _on_join_pressed():
|
|
||||||
var items = lobbies.get_selected_items()
|
|
||||||
if len(items) > 0:
|
|
||||||
Global.client.join_lobby(lobbies.get_item_metadata(items[0])["id"])
|
|
||||||
|
|
||||||
func _lobby_data(new_lobbies: Array):
|
func _lobby_data(new_lobbies: Array):
|
||||||
for l in new_lobbies:
|
for l in new_lobbies:
|
||||||
if lobbies.has(l.id): _update_lobby(l.id, l)
|
if lobbies.has(l.uuid): _update_lobby(l.uuid, l)
|
||||||
else: _add_lobby(l.id, l)
|
else: _add_lobby(l.uuid, l)
|
||||||
|
|
||||||
if Global.check_onetime_flag("join-first-available-lobby"):
|
if Global.check_onetime_flag("join-first-available-lobby"):
|
||||||
Global.client.join_lobby(l.id)
|
Global.client.join_lobby(l.uuid)
|
||||||
|
|
||||||
func _lobby_delete(id: String):
|
func _lobby_delete(uuid: String):
|
||||||
print("Lobby Deleted: %s" % id)
|
print("Lobby Deleted: %s" % uuid)
|
||||||
_delete_lobby(id)
|
_delete_lobby(uuid)
|
||||||
|
|
||||||
func _add_lobby(id, lobby_data):
|
func _add_lobby(uuid, lobby_data):
|
||||||
call_deferred("_update_lobbies_text")
|
call_deferred("_update_lobbies_text")
|
||||||
print("New Lobby ", lobby_data)
|
print("New Lobby ", lobby_data)
|
||||||
# if lobby_data.currentPlayers > 0:
|
# if lobby_data.currentPlayers > 0:
|
||||||
var new_lobby = lobby.instance()
|
var new_lobby = lobby.instance()
|
||||||
new_lobby.set_with_dict(lobby_data)
|
new_lobby.set_with_dict(lobby_data)
|
||||||
lobbies_grid.add_child(new_lobby)
|
lobbies_grid.add_child(new_lobby)
|
||||||
lobbies[id] = new_lobby
|
lobbies[uuid] = new_lobby
|
||||||
|
|
||||||
func _update_lobby(id, lobby_data):
|
func _update_lobby(uuid, lobby_data):
|
||||||
call_deferred("_update_lobbies_text")
|
call_deferred("_update_lobbies_text")
|
||||||
print("Updated Lobby ", lobby_data)
|
print("Updated Lobby ", lobby_data)
|
||||||
lobbies[id].set_with_dict(lobby_data)
|
lobbies[uuid].set_with_dict(lobby_data)
|
||||||
|
|
||||||
func _delete_lobby(id):
|
func _delete_lobby(uuid):
|
||||||
call_deferred("_update_lobbies_text")
|
call_deferred("_update_lobbies_text")
|
||||||
if lobbies.has(id):
|
if lobbies.has(uuid):
|
||||||
print("Removing lobby...")
|
print("Removing lobby...")
|
||||||
lobbies_grid.remove_child(lobbies[id])
|
lobbies_grid.remove_child(lobbies[uuid])
|
||||||
lobbies[id].queue_free()
|
lobbies[uuid].queue_free()
|
||||||
lobbies.erase(id)
|
lobbies.erase(uuid)
|
||||||
|
|
||||||
func _update_lobbies_text():
|
func _update_lobbies_text():
|
||||||
var n = lobbies.size()
|
var n = lobbies.size()
|
||||||
|
|
|
@ -18,63 +18,50 @@ onready var peers_id_mappings = {}
|
||||||
onready var is_host = false
|
onready var is_host = false
|
||||||
|
|
||||||
func _ready():
|
func _ready():
|
||||||
Global.client.connect("peer_data", self, "_peer_data")
|
Global.client.connect("peer_created", self, "_peer_created")
|
||||||
Global.client.connect("peer_left", self, "_peer_left")
|
Global.client.connect("peer_left", self, "_peer_left")
|
||||||
Global.client.connect("lobby_left", self, "_lobby_left")
|
Global.client.connect("lobby_left", self, "_lobby_left")
|
||||||
Global.client.connect("lobby_data", self, "_lobby_data")
|
Global.client.connect("lobby_data", self, "_lobby_data")
|
||||||
|
Global.client.connect("lobby_joined", self, "_lobby_joined")
|
||||||
|
|
||||||
Global.client.connect("signaller_disconnected", self, "_signaller_disconnected")
|
Global.client.connect("signaller_disconnected", self, "_signaller_disconnected")
|
||||||
Global.client.connect("webrtc_connection_succeeded", self, "_connection_succeeded")
|
Global.client.connect("webrtc_connection_succeeded", self, "_webrtc_connection_succeeded")
|
||||||
|
|
||||||
# lobby_name.text = "%s" % Global.client.lobby_name
|
# lobby_name.text = "%s" % Global.client.lobby_name
|
||||||
|
|
||||||
Global.client.call_deferred("request_peer_list")
|
# call_deferred("add_chat", "# to %s" % Global.client.get_lobby_name())
|
||||||
call_deferred("add_chat", "# Connected to %s" % Global.client.get_lobby_name())
|
|
||||||
|
|
||||||
# hide/show controls depending on whether or not we're the host
|
# hide/show controls depending on whether or not we're the host
|
||||||
is_host = Global.client.is_host()
|
_update_ui()
|
||||||
if is_host:
|
|
||||||
ready_up.queue_free()
|
|
||||||
else:
|
|
||||||
lobby_name.editable = false
|
|
||||||
max_players.editable = false
|
|
||||||
start.queue_free()
|
|
||||||
lock.queue_free()
|
|
||||||
|
|
||||||
# until we fully connect
|
|
||||||
ready_up.disabled = true
|
|
||||||
chat_edit.editable = false
|
|
||||||
send_button.disabled = true
|
|
||||||
print("Setting up lobby... %s %s" % [get_tree().get_network_unique_id(), is_host])
|
|
||||||
|
|
||||||
func _connection_succeeded():
|
func _signaller_disconnected():
|
||||||
ready_up.disabled = false
|
Global.main_menu()
|
||||||
send_button.disabled = false
|
|
||||||
chat_edit.editable = true
|
|
||||||
|
|
||||||
func _lobby_update(l):
|
func _lobby_joined(data):
|
||||||
for u in l:
|
add_chat("# Connected to %s" % data.name)
|
||||||
if !is_host:
|
_update_ui()
|
||||||
max_players.text = str(u.maxPlayers)
|
Global.client.request_peer_list()
|
||||||
lobby_name.text = u.name
|
|
||||||
print(l)
|
|
||||||
break
|
|
||||||
|
|
||||||
func _peer_data(peers):
|
func _webrtc_connection_succeeded():
|
||||||
|
if !is_host:
|
||||||
|
ready_up.disabled = false
|
||||||
|
send_button.disabled = false
|
||||||
|
chat_edit.editable = true
|
||||||
|
Global.client.request_peer_list()
|
||||||
|
|
||||||
|
func _peer_created(peer):
|
||||||
call_deferred("update_player_count")
|
call_deferred("update_player_count")
|
||||||
if is_host: call_deferred("update_can_start")
|
if is_host: call_deferred("update_can_start")
|
||||||
for p in peers:
|
if peers.has(peer.id): _update_peer(peer.id, peer)
|
||||||
if peers.has(p.id): _update_peer(p.id, p)
|
else: _add_peer(peer.id, peer)
|
||||||
else: _add_peer(p.id, p)
|
|
||||||
|
|
||||||
func _add_peer(id, peer_data):
|
func _add_peer(id, p):
|
||||||
call_deferred("update_player_count")
|
call_deferred("update_player_count")
|
||||||
var new_peer = peer.instance()
|
var new_peer = peer.instance()
|
||||||
if peer_data.peerId == 1: peer_data.ready = true
|
if p.id == 1: p.ready = true
|
||||||
new_peer.set_with_dict(peer_data)
|
new_peer.set_with_dict(p)
|
||||||
peers_grid.add_child(new_peer)
|
peers_grid.add_child(new_peer)
|
||||||
peers[id] = new_peer
|
peers[id] = new_peer
|
||||||
peers_id_mappings[int(peer_data.peerId)] = id
|
|
||||||
add_chat("> %s joined the lobby" % new_peer.display_name)
|
add_chat("> %s joined the lobby" % new_peer.display_name)
|
||||||
|
|
||||||
func _update_peer(id, peer_data):
|
func _update_peer(id, peer_data):
|
||||||
|
@ -142,18 +129,29 @@ remotesync func start_game():
|
||||||
|
|
||||||
remotesync func set_ready(ready):
|
remotesync func set_ready(ready):
|
||||||
var from = get_tree().get_rpc_sender_id()
|
var from = get_tree().get_rpc_sender_id()
|
||||||
print(from)
|
print("Set Ready: %s %s" % [from, ready])
|
||||||
peer_by_peer_id(from).ready = ready
|
Global.client.peers[from].ready = ready
|
||||||
if is_host: update_can_start()
|
if is_host: update_can_start()
|
||||||
|
|
||||||
func _on_TextEdit_text_entered(_new_text):
|
func _on_TextEdit_text_entered(_new_text):
|
||||||
if !send_button.disabled:
|
if !send_button.disabled:
|
||||||
send_chat_message()
|
send_chat_message()
|
||||||
|
|
||||||
|
func _update_ui():
|
||||||
|
is_host = Global.client.is_host()
|
||||||
|
ready_up.visible = !is_host
|
||||||
|
lobby_name.editable = is_host
|
||||||
|
max_players.editable = is_host
|
||||||
|
start.visible = is_host
|
||||||
|
lock.visible = is_host
|
||||||
|
var is_in_lobby = Global.client.is_in_lobby()
|
||||||
|
ready_up.disabled = !is_in_lobby
|
||||||
|
chat_edit.editable = is_in_lobby
|
||||||
|
send_button.disabled = !is_in_lobby
|
||||||
|
|
||||||
func _lobby_left(_id): Global.lobby_browser()
|
func _lobby_left(_id): Global.lobby_browser()
|
||||||
func _on_leave_button_pressed(): Global.lobby_browser()
|
func _on_leave_button_pressed(): Global.client.leave_lobby()
|
||||||
func update_player_count(): peers_list_label.text = "Players: %d" % peers.size()
|
func update_player_count(): peers_list_label.text = "Players: %d" % peers.size()
|
||||||
func _on_Button_pressed(): send_chat_message()
|
func _on_Button_pressed(): send_chat_message()
|
||||||
func _on_ready_up_toggled(button_pressed: bool): rpc("set_ready", button_pressed)
|
func _on_ready_up_toggled(button_pressed: bool): rpc("set_ready", button_pressed)
|
||||||
func _on_lobby_info_text_changed(new_text: String): Global.client.set_lobby_name(new_text)
|
func _on_lobby_info_text_changed(new_text: String): Global.client.set_lobby_name(new_text)
|
||||||
func _signaller_disconnected(): Global.main_menu()
|
|
||||||
|
|
31
server.ts
31
server.ts
|
@ -3,8 +3,8 @@
|
||||||
const SERVER_VERSION = "0.2.0";
|
const SERVER_VERSION = "0.2.0";
|
||||||
// TODO: version comparison
|
// TODO: version comparison
|
||||||
|
|
||||||
type UUID = string;
|
|
||||||
type ID = number;
|
type ID = number;
|
||||||
|
type UUID = string;
|
||||||
|
|
||||||
// app state
|
// app state
|
||||||
const allLobbies = new Map<UUID, Lobby>();
|
const allLobbies = new Map<UUID, Lobby>();
|
||||||
|
@ -57,6 +57,7 @@ class Client {
|
||||||
}
|
}
|
||||||
|
|
||||||
remove() {
|
remove() {
|
||||||
|
console.debug(`Removing Client ${this.uuid}`);
|
||||||
this.lobbyLeave();
|
this.lobbyLeave();
|
||||||
if (this.isConnected()) {
|
if (this.isConnected()) {
|
||||||
this.socket.close();
|
this.socket.close();
|
||||||
|
@ -73,6 +74,7 @@ class Client {
|
||||||
: message,
|
: message,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
// TODO: maybe log when we try to send and we're not connected?
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.error(
|
console.error(
|
||||||
`Failed to send on socket ${this.socket} to client ${this.id}: ${
|
`Failed to send on socket ${this.socket} to client ${this.id}: ${
|
||||||
|
@ -104,6 +106,7 @@ class Client {
|
||||||
this.lobby.clients.forEach(({ id, name }) => {
|
this.lobby.clients.forEach(({ id, name }) => {
|
||||||
if (typeof id === "number") peers.push({ id, name });
|
if (typeof id === "number") peers.push({ id, name });
|
||||||
});
|
});
|
||||||
|
console.debug(`Sending peer list with ${peers.length} peers...`);
|
||||||
this.send(buildMessage("peer_data", peers));
|
this.send(buildMessage("peer_data", peers));
|
||||||
// TODO: chunk async?
|
// TODO: chunk async?
|
||||||
}
|
}
|
||||||
|
@ -172,12 +175,11 @@ class Client {
|
||||||
this.send(`[info] cannot leave lobby (not in a lobby)`);
|
this.send(`[info] cannot leave lobby (not in a lobby)`);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
console.debug(`Client ${this.uuid} leaving Lobby ${this.lobby?.uuid}`);
|
||||||
|
leavingLobby.removeClient(this);
|
||||||
this.id = null;
|
this.id = null;
|
||||||
this.lobby = null;
|
this.lobby = null;
|
||||||
if (this.isConnected()) {
|
this.send(buildMessage("lobby_left", { uuid: leavingLobby.uuid }));
|
||||||
this.send(buildMessage("lobby_left", { id: leavingLobby.uuid }));
|
|
||||||
}
|
|
||||||
leavingLobby.removeClient(this);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -201,6 +203,10 @@ class Lobby {
|
||||||
|
|
||||||
this._shouldNotify = true;
|
this._shouldNotify = true;
|
||||||
|
|
||||||
|
console.debug(
|
||||||
|
`Lobby ${this.uuid} created by Client ${this.hostClientUuid}`,
|
||||||
|
);
|
||||||
|
|
||||||
allLobbies.set(this.uuid, this);
|
allLobbies.set(this.uuid, this);
|
||||||
host.id = 1;
|
host.id = 1;
|
||||||
host.lobbyJoin(this);
|
host.lobbyJoin(this);
|
||||||
|
@ -221,7 +227,7 @@ class Lobby {
|
||||||
requestor: Client,
|
requestor: Client,
|
||||||
newValues: { name?: string; maxPlayers?: number; locked?: boolean },
|
newValues: { name?: string; maxPlayers?: number; locked?: boolean },
|
||||||
) {
|
) {
|
||||||
if (requestor.id === 1) {
|
if (requestor.uuid === this.hostClientUuid) {
|
||||||
for (const k in newValues) {
|
for (const k in newValues) {
|
||||||
switch (k) {
|
switch (k) {
|
||||||
case "name":
|
case "name":
|
||||||
|
@ -254,6 +260,7 @@ class Lobby {
|
||||||
|
|
||||||
remove() {
|
remove() {
|
||||||
this._shouldNotify = false;
|
this._shouldNotify = false;
|
||||||
|
console.debug(`Removing Lobby ${this.uuid}`);
|
||||||
allLobbies.delete(this.uuid);
|
allLobbies.delete(this.uuid);
|
||||||
allClients.forEach((client) => client.lobbyDelete(this));
|
allClients.forEach((client) => client.lobbyDelete(this));
|
||||||
this.clients.forEach((client) => {
|
this.clients.forEach((client) => {
|
||||||
|
@ -271,6 +278,9 @@ class Lobby {
|
||||||
crypto.getRandomValues(arr);
|
crypto.getRandomValues(arr);
|
||||||
client.id = Math.abs(arr[0]);
|
client.id = Math.abs(arr[0]);
|
||||||
}
|
}
|
||||||
|
console.debug(
|
||||||
|
`Adding Client ${client.uuid} Lobby ${this.uuid} as peer ${client.id}`,
|
||||||
|
);
|
||||||
client.send(buildMessage("init_peer", client.id));
|
client.send(buildMessage("init_peer", client.id));
|
||||||
this.broadcast(
|
this.broadcast(
|
||||||
buildMessage("peer_data", [{
|
buildMessage("peer_data", [{
|
||||||
|
@ -293,9 +303,10 @@ class Lobby {
|
||||||
removeClient({ id, uuid }: Client) {
|
removeClient({ id, uuid }: Client) {
|
||||||
if (typeof id !== "number") return;
|
if (typeof id !== "number") return;
|
||||||
this.clients.delete(id);
|
this.clients.delete(id);
|
||||||
this.broadcast(buildMessage("peer_left", [{ id }]));
|
this.broadcast(buildMessage("peer_left", { id }));
|
||||||
|
console.debug(`Removing Client ${this.uuid} from Lobby ${this.uuid}`);
|
||||||
if (uuid === this.hostClientUuid) {
|
if (uuid === this.hostClientUuid) {
|
||||||
console.warn("Host left!");
|
console.warn(`Host left, removing Lobby ${this.uuid}`);
|
||||||
this.remove();
|
this.remove();
|
||||||
}
|
}
|
||||||
this.notify();
|
this.notify();
|
||||||
|
@ -343,7 +354,7 @@ function onMessage(client: Client, ev: MessageEvent) {
|
||||||
// TODO: log who from? IPs etc.?
|
// TODO: log who from? IPs etc.?
|
||||||
const msg = parseMessage(ev.data);
|
const msg = parseMessage(ev.data);
|
||||||
if (msg.type === "pong") return;
|
if (msg.type === "pong") return;
|
||||||
console.log("Client Message Received", msg);
|
console.debug("Client Message Received", msg);
|
||||||
switch (msg.type) {
|
switch (msg.type) {
|
||||||
case "init":
|
case "init":
|
||||||
if (msg.data && (msg.data as { name: string })["name"]) {
|
if (msg.data && (msg.data as { name: string })["name"]) {
|
||||||
|
@ -421,7 +432,7 @@ function onMessage(client: Client, ev: MessageEvent) {
|
||||||
}
|
}
|
||||||
|
|
||||||
function onSocketOpen(client: Client, _ev: Event) {
|
function onSocketOpen(client: Client, _ev: Event) {
|
||||||
console.log("New Client", client.id);
|
console.log("New Client", client.uuid);
|
||||||
}
|
}
|
||||||
|
|
||||||
function onClientLeave(client: Client) {
|
function onClientLeave(client: Client) {
|
||||||
|
|
Loading…
Reference in a new issue