Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 4 additions & 2 deletions src/scenes/managers/app/network.gd
Original file line number Diff line number Diff line change
Expand Up @@ -98,10 +98,12 @@ func start_server(port: int = 0, root_scene: Enum.BaseLevel = Enum.BaseLevel.GRI
scene_m.set_master_root_from_program(_scene, Enum.BaseLevel.GRID)

scene_m.start_master_scene(_scene)
scene_m.set_active_session(_scene)

# DEV: Force spawn the host.
scene_m.get_master_scene(_scene).get_node("PlayerManager").add_player(1)
scene_m.set_active_session(_scene)
# FIXME: This is probably bad design.
scene_m.get_master_scene(_scene).get_node("NetworkManager")._on_peer_connected(1)

Events.dash_session_changed.emit(_scene)

return response_dict
Expand Down
27 changes: 19 additions & 8 deletions src/scenes/managers/app/scene.gd
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,8 @@ func stop_master_scene(id: String):
func set_active_session(session_id: String):
GlobalLogger.log("Setting session '%s' active." % session_id)

active_session = session_id

for _scene in network_m.get_connected_sessions():
# Each session gets disabled
scene_container.get_node(_scene.id).visible = false
Expand All @@ -141,7 +143,6 @@ func set_active_session(session_id: String):

# session_id gets enabled.
scene_container.get_node(session_id).process_mode = Node.PROCESS_MODE_INHERIT
active_session = session_id
_set_camera_active_state(session_id, true)
scene_container.get_node(session_id).visible = true
_set_player_authority_state(session_id, true)
Expand Down Expand Up @@ -176,9 +177,13 @@ func _set_camera_active_state(session_id, state: bool = false) -> void:
var player_manager: Node = master_scene.get_node("PlayerManager")
var player_database = player_manager.players
var my_database_entry = player_database.get(my_id)
var camera = my_database_entry.get("node").get_node("Head/Camera3D")
if my_database_entry != null:
if my_database_entry.node == null:
# FIXME: This error should not be necessary, there is a bigger problem somewhere else.
return

camera.current = state
var camera = my_database_entry.node.get_node("Head/Camera3D")
camera.current = state
return


Expand All @@ -192,11 +197,17 @@ func _set_player_authority_state(session_id, is_active: bool = false) -> void:
var player_manager: Node = master_scene.get_node("PlayerManager")
var player_database = player_manager.players
var my_database_entry = player_database.get(my_id)
var player = my_database_entry.get("node")

if is_active:
player.set_multiplayer_authority(int(my_id))
return
if my_database_entry != null:
var player = my_database_entry.node

if player == null:
# FIXME: This error should not be necessary, there is a bigger problem somewhere else.
return

if is_active:
player.set_multiplayer_authority(int(my_id))
return

player.set_multiplayer_authority(0)
player.set_multiplayer_authority(0)
return
47 changes: 43 additions & 4 deletions src/scenes/managers/scene/network.gd
Original file line number Diff line number Diff line change
Expand Up @@ -71,12 +71,13 @@ func entity_position(entity_id: int, position):
@rpc("any_peer", "reliable")
func dev_request_spawnables_database() -> void:
var caller_id = multiplayer.get_remote_sender_id()
var the_data = spawnable_m._database
spawnable_m.receive_database.rpc_id(caller_id, the_data, spawnable_m._database_id)
spawnable_m.sync_all()
return

# FIXME: We should not need to send the database_id, the host should tell the client what the id of a node is!
GlobalLogger.log("Sending spawnable database to peer %d: %d entries, DB_ID: %d" % [caller_id, spawnable_m._database.size(), spawnable_m._database_id])
spawnable_m.receive_database.rpc_id(caller_id, spawnable_m._database, spawnable_m._database_id, player_m.players)
return

# FIXME Old dev function. Should be refactored!
@rpc("any_peer", "reliable")
func dev_request_sync() -> void:
if is_multiplayer_authority() == false:
Expand All @@ -90,7 +91,10 @@ func gizmo_selection(node_id: int, to_select: bool) -> void:


func _on_connected_to_server():
# When the client is connected to the server, request the database from the server.
GlobalLogger.log("[%s] I am connected to a server." % _my_id)

# Request the spawnable database from host
rpc_id(1, "dev_request_spawnables_database")


Expand All @@ -103,11 +107,25 @@ func _on_peer_connected(peer_id: int):
if is_multiplayer_authority() == false:
return

GlobalLogger.log("Peer '%s' is connected! Creating a player controller." % [peer_id])

# Add player to the database.
player_m.add_player(peer_id)
player_m.add_player.rpc(peer_id)

# Spawn the player controller.
var _entity = await spawnable_m.create("OM_PlayerController")

# Set the player node in the player database.
player_m.set_player_node(peer_id, _entity)

# The host adds a listener for the on_delete, then spawns the player back in.
_entity.connect("tree_exiting", _on_peer_player_node_destroyed.bind(peer_id, int(_entity.name)))

GlobalLogger.log("[%s] Peer '%s' connected to our server." % [_my_id, peer_id])

rpc_id(peer_id, "set_root", Enum.BaseLevel.GRID)
# FIXME: There are now two functions that do this. Refactor one of them out. The newer one has better player node syncing.
rpc_id(peer_id, "add_players", player_m.players)
return

Expand All @@ -121,3 +139,24 @@ func _on_peer_disconnected(peer_id: int) -> void:

GlobalLogger.log("[%s] Peer '%s' disconnected to our server." % [_my_id, peer_id])
return

func _on_peer_player_node_destroyed(peer_id: int, node_id: int) -> void:
GlobalLogger.log("Peer '%s' was destroyed! Queued a player controller respawn." % [peer_id])
spawnable_m.destroy(node_id)
spawnable_m.destroy.rpc(node_id)

var _timer = get_tree().create_timer(1)

_timer.timeout.connect(func () -> void:
if player_m.players.keys().has(peer_id) == false:
# Check to see if player still exists in the database, don't spawn if they are gone.
GlobalLogger.log("Peer '%s' was disconnected, not respawning a player controller." % [peer_id])
return

var _entity = await spawnable_m.create("OM_PlayerController")
spawnable_m.set_authority.rpc(int(_entity.name), peer_id)
player_m.set_player_node(peer_id, _entity)
_entity.connect("tree_exiting", _on_peer_player_node_destroyed.bind(peer_id))
)

return
48 changes: 24 additions & 24 deletions src/scenes/managers/scene/player.gd
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,11 @@
# --- License
extends Node

@onready var spawnable_m = get_node("../SpawnableManager")

const PLAYER_TEMPLATE = {
"peer_id": 0,
"has_spawned": false,
"node_id": -1,
"node": null,
}

Expand All @@ -26,9 +28,18 @@ func add_player(peer_id: int) -> void:
GlobalLogger.log("[%s] Adding peer '%s' to the player list" % [caller_id, peer_id])
database_template.set("peer_id", peer_id)
players.set(str(peer_id), database_template)
return

spawn_player(str(peer_id))
func set_player_database(database: Dictionary) -> void:
players = database

# Fix the database references
for _player in players.keys():
var _entry = players[_player]
var _db_entry = spawnable_m.get_by_id(int(_entry.node_id))
_entry.node = _db_entry.node

return

@rpc("authority", "reliable")
func remove_player(peer_id: int) -> void:
Expand All @@ -38,34 +49,23 @@ func remove_player(peer_id: int) -> void:
players[str(peer_id)].get("node").queue_free()
players.erase(str(peer_id))

@rpc("authority", "reliable")
func set_player_node(peer_id: int, node: Node3D) -> void:
var _target = players[str(peer_id)]

@rpc("authority", "unreliable")
func spawn_player(peer_id: String) -> void:
var caller_id = multiplayer.get_remote_sender_id()

if players[peer_id].get("has_spawned") == true:
GlobalLogger.log("[%s] Did not spawn peer '%s', already exists!" % [caller_id, peer_id], Enum.LogLevel.WARNING)
# TODO: Error warnings
if _target == null:
return

GlobalLogger.log("[%s] Spawning peer '%s'" % [caller_id, peer_id])
_target.node = node
_target.node_id = node.name

if module_active == false:
GlobalLogger.log("[%s] Could not spawn peer '%s', module inactive." % [caller_id, peer_id])
return

var _player_scene: PackedScene = load("res://scenes/players/player.tscn")
var _new_player: Node3D = _player_scene.instantiate()
_new_player.name = str(peer_id)
_new_player.position = Vector3(0, 0, 0)
_new_player.set_multiplayer_authority(int(peer_id))
get_node("../root").add_child(_new_player)
var player_node = get_node("../root").get_node(str(peer_id))
GlobalLogger.log("[%s] Spawned peer '%s'." % [caller_id, peer_id])
players[peer_id].set("node", player_node)
players[peer_id].set("has_spawned", true)
# If this is our own player node being set, ensure we have authority
if peer_id == multiplayer.get_unique_id():
if node and node.has_method("set_multiplayer_authority"):
node.set_multiplayer_authority(peer_id)
return


func kill_player() -> void:
GlobalLogger.log("'%s' is not implemented." % get_stack()[0]["function"], Enum.LogLevel.WARNING)
return
Expand Down
Loading