More Networking fixups.

This commit is contained in:
Patrick_Pluto 2024-12-06 11:11:51 +01:00
parent 390db61bb6
commit c07c04e8f9
3 changed files with 68 additions and 27 deletions

View file

@ -1,5 +1,11 @@
extends Node extends Node
# This tells the game what the logmode is.
# 0 -> None
# 1 -> Errors
# 2 -> Errors/Warnings
# 3 -> Errors/Warnings/Infos
# 4 -> All
var logmode: int = 4 var logmode: int = 4
var ip: String = "127.0.0.1" var ip: String = "127.0.0.1"

View file

@ -1,14 +1,10 @@
extends Node extends Node
# This tells the game what the logmode is. var mutex: Mutex = Mutex.new()
# 0 -> None
# 1 -> Errors
# 2 -> Errors/Warnings
# 3 -> Errors/Warnings/Infos
# 4 -> All
# Used for errors. # Used for errors.
func error(message: String, alert_message: String) -> void: func error(message: String, alert_message: String) -> void:
mutex.lock()
if message == "": if message == "":
message = "Empty message string passed to an error message!" message = "Empty message string passed to an error message!"
if Game.logmode >= 1: if Game.logmode >= 1:
@ -19,26 +15,35 @@ func error(message: String, alert_message: String) -> void:
else: else:
OS.alert("An error has occured. The program will now exit.", "Error!") OS.alert("An error has occured. The program will now exit.", "Error!")
get_tree().quit() get_tree().quit()
mutex.unlock()
# Used for warnings. # Used for warnings.
func warning(message: String) -> void: func warning(message: String) -> void:
mutex.lock()
if message == "": if message == "":
message = "Empty message string passed to a warning message!" message = "Empty message string passed to a warning message!"
if Game.logmode >= 2: if Game.logmode >= 2:
printerr("[WARNING] " + message) printerr("[WARNING] " + message)
mutex.unlock()
# Used for simple info. # Used for simple info.
func info(message: String) -> void: func info(message: String) -> void:
mutex.lock()
if message == "": if message == "":
warning("Empty message string passed to an info message!") warning("Empty message string passed to an info message!")
mutex.unlock()
return return
if Game.logmode >= 3: if Game.logmode >= 3:
print("[INFO] " + message) print("[INFO] " + message)
mutex.unlock()
# Used for debugging. # Used for debugging.
func debug(message: String) -> void: func debug(message: String) -> void:
mutex.lock()
if message == "": if message == "":
warning("Empty message string passed to a debug message!") warning("Empty message string passed to a debug message!")
mutex.unlock()
return return
if Game.logmode >= 4: if Game.logmode >= 4:
print("[DEBUG] " + message) print("[DEBUG] " + message)
mutex.unlock()

View file

@ -16,6 +16,7 @@ func _ready() -> void:
Log.error("FAILED to connect the peer_disconnected signal to _on_peer_disconnected!", "Internal Error: Failed to connect signal.") Log.error("FAILED to connect the peer_disconnected signal to _on_peer_disconnected!", "Internal Error: Failed to connect signal.")
if playerlist_changed.connect(_on_playerlist_changed) != OK: if playerlist_changed.connect(_on_playerlist_changed) != OK:
Log.error("FAILED to connect the playerlist_changed signal to _on_playerlist_changed!", "Internal Error: Failed to connect signal.") Log.error("FAILED to connect the playerlist_changed signal to _on_playerlist_changed!", "Internal Error: Failed to connect signal.")
func _on_playerlist_changed() -> void: func _on_playerlist_changed() -> void:
pass pass
@ -49,7 +50,7 @@ func close_network() -> void:
var mutex: Mutex = Mutex.new() var mutex: Mutex = Mutex.new()
var rooms: Dictionary = {} var rooms: Dictionary = {}
# peers has two different uses: On the server it is an index of all rooms with their peers, while on the client it is just a lookup table for peers and their usernames. var server_peers: Dictionary = {}
var peers: Dictionary = {} var peers: Dictionary = {}
var isManager: bool = false var isManager: bool = false
var managerID: int var managerID: int
@ -69,26 +70,36 @@ func _on_peer_disconnected(id: int) -> void:
var roomname: String = rooms[id] var roomname: String = rooms[id]
if !rooms.erase(roomname): if !rooms.erase(roomname):
Log.warning("The room %s associated with %d doesn't exist in rooms, even though it should!" % [roomname, id]) Log.warning("The room %s associated with %d doesn't exist in rooms, even though it should!" % [roomname, id])
mutex.unlock()
return
if !rooms.erase(id): if !rooms.erase(id):
Log.warning("The peer %d doesn't exist in rooms, even though it should!" % id) Log.warning("The peer %d doesn't exist in rooms, even though it should!" % id)
for peer: int in peers[roomname]: mutex.unlock()
return
for peer: int in server_peers[roomname]:
if peer == id: if peer == id:
continue continue
if rpc_id(peer, "host_disconnected_message"): if rpc_id(peer, "host_disconnected_message"):
Log.warning("Peer %d couldn't be disconnected!" % peer) Log.warning("Peer %d couldn't be disconnected!" % peer)
if !peers.erase(roomname): mutex.unlock()
return
if !server_peers.erase(roomname):
Log.warning("Room %s couldn't be found, even though it should exist!" % roomname) Log.warning("Room %s couldn't be found, even though it should exist!" % roomname)
mutex.unlock()
return
Log.info("Room %s terminated." % roomname) Log.info("Room %s terminated." % roomname)
else: else:
for room: String in peers: for room: String in server_peers:
for peer: int in peers[room]: for peer: int in server_peers[room]:
if peer == id: if peer == id:
var peer_array: Array = peers[room] var peer_array: Array = server_peers[room]
peer_array.erase(id) peer_array.erase(id)
peers[room] = peer_array server_peers[room] = peer_array
for found_peer: int in peers[room]: for found_peer: int in server_peers[room]:
if rpc_id(found_peer, "peer_disconnected_message") != OK: if rpc_id(found_peer, "peer_disconnected_message", id) != OK:
Log.warning("Failed to send disconnect message to %d!" % found_peer) Log.warning("Failed to send disconnect message to %d!" % found_peer)
mutex.unlock()
return
mutex.unlock() mutex.unlock()
# The following function sends the roomname selected by the client. # The following function sends the roomname selected by the client.
@ -99,17 +110,19 @@ func send_roomname(roomname: String) -> void:
if !rooms.has(roomname) and !rooms.has(multiplayer.get_remote_sender_id()): if !rooms.has(roomname) and !rooms.has(multiplayer.get_remote_sender_id()):
rooms[roomname] = multiplayer.get_remote_sender_id() rooms[roomname] = multiplayer.get_remote_sender_id()
rooms[multiplayer.get_remote_sender_id()] = roomname rooms[multiplayer.get_remote_sender_id()] = roomname
peers[roomname] = [multiplayer.get_remote_sender_id()] server_peers[roomname] = [multiplayer.get_remote_sender_id()]
Log.info("Room %s registered." % roomname) Log.info("Room %s registered." % roomname)
if rpc_id(multiplayer.get_remote_sender_id(), "server_response", 0, rooms[roomname]) != OK: if rpc_id(multiplayer.get_remote_sender_id(), "server_response", 0, rooms[roomname]) != OK:
Log.warning("Failed to send elevation reply to %d!") Log.warning("Failed to send elevation reply to %d!")
elif peers[roomname] is Array: elif server_peers[roomname] is Array:
# For some odd reason, Godot doesn't allow casting peers[roomname] to an Array, but this works? # For some odd reason, Godot doesn't allow casting server_peers[roomname] to an Array, but this works?
var peer_array: Array = peers[roomname] var peer_array: Array = server_peers[roomname]
peer_array.append(multiplayer.get_remote_sender_id()) peer_array.append(multiplayer.get_remote_sender_id())
peers[roomname] = peer_array server_peers[roomname] = peer_array
if rpc_id(multiplayer.get_remote_sender_id(), "server_response", 1, rooms[roomname]) != OK: if rpc_id(multiplayer.get_remote_sender_id(), "server_response", 1, rooms[roomname]) != OK:
Log.warning("Failed to send join reply to %d!") Log.warning("Failed to send join reply to %d!")
mutex.unlock()
return
Log.debug("Room %s joined by peer %d." % [roomname, multiplayer.get_remote_sender_id()]) Log.debug("Room %s joined by peer %d." % [roomname, multiplayer.get_remote_sender_id()])
else: else:
Log.warning("Peer %d tried to send this client a request meant for the authority!" % multiplayer.get_remote_sender_id()) Log.warning("Peer %d tried to send this client a request meant for the authority!" % multiplayer.get_remote_sender_id())
@ -120,13 +133,26 @@ func send_roomname(roomname: String) -> void:
# This is the message sent out if the host of the room has left. # This is the message sent out if the host of the room has left.
@rpc("authority", "call_remote", "reliable") @rpc("authority", "call_remote", "reliable")
func host_disconnected_message() -> void: func host_disconnected_message() -> void:
pass # TODO: Implement this Log.info("Host disconnected from the session.")
managerID = 1
close_network()
if get_tree().change_scene_to_file("res://start.tscn"):
Log.warning("Failed to change back to the main scene!")
# This is the message sent out if a peer in the room has left. # This is the message sent out if a peer in the room has left.
@rpc("authority", "call_remote", "reliable") @rpc("authority", "call_remote", "reliable")
func peer_disconnected_message() -> void: func peer_disconnected_message(id: int) -> void:
pass # TODO: Implement this for peer: String in peers:
if peers[peer] == id:
if !peers.erase(peer):
Log.warning("Peer %d never existed, but was tasked to remove it!" % id)
return
if emit_signal("playerlist_changed") != OK:
Log.warning("Couldn't emit playerlist_changed signal.")
return
Log.info("Peer %d successfully removed." % id)
# This is the initial server response, which tells the client what its role is. # This is the initial server response, which tells the client what its role is.
@rpc("authority", "call_remote", "reliable") @rpc("authority", "call_remote", "reliable")
func server_response(status: int, manager: int) -> void: func server_response(status: int, manager: int) -> void:
@ -152,9 +178,9 @@ func inform_server(roomname: String) -> void:
mutex.lock() mutex.lock()
if multiplayer.get_unique_id() == 1: if multiplayer.get_unique_id() == 1:
if multiplayer.get_remote_sender_id() == rooms[roomname]: if multiplayer.get_remote_sender_id() == rooms[roomname]:
var peer_array: Array = peers[roomname] var peer_array: Array = server_peers[roomname]
peer_array.append(multiplayer.get_remote_sender_id()) peer_array.append(multiplayer.get_remote_sender_id())
peers[roomname] = peer_array server_peers[roomname] = peer_array
else: else:
Log.warning("Peer %d attempted to trick the server into adding it to the room!" % multiplayer.get_remote_sender_id()) Log.warning("Peer %d attempted to trick the server into adding it to the room!" % multiplayer.get_remote_sender_id())
else: else:
@ -165,12 +191,16 @@ func inform_server(roomname: String) -> void:
@rpc("any_peer", "call_remote", "reliable") @rpc("any_peer", "call_remote", "reliable")
func request_playerlist(peername: String) -> void: func request_playerlist(peername: String) -> void:
if isManager: if isManager:
if !peers.has(peername): if !peers.has(peername) and !peers.has(multiplayer.get_remote_sender_id()):
peers[peername] = multiplayer.get_remote_sender_id() peers[peername] = multiplayer.get_remote_sender_id()
if rpc_id(multiplayer.get_remote_sender_id(), "send_playerlist", 0, peers) != OK: if rpc_id(multiplayer.get_remote_sender_id(), "send_playerlist", 0, peers) != OK:
Log.warning("Failed to send join status to %d." % multiplayer.get_remote_sender_id()) Log.warning("Failed to send join status to %d." % multiplayer.get_remote_sender_id())
if !peers.erase(peername):
Log.warning("Couldn't reverse adding %d to the playerlist." % peername)
return
if rpc_id(1, "inform_server", Game.roomname) != OK: if rpc_id(1, "inform_server", Game.roomname) != OK:
Log.warning("Failed to send playerinfo to server.") Log.warning("Failed to send playerinfo to server.")
return
for peer: String in peers: for peer: String in peers:
var remote_id: int = peers[peer] var remote_id: int = peers[peer]
if remote_id != multiplayer.get_unique_id(): if remote_id != multiplayer.get_unique_id():