From d01a9bec392e7f3528ede0a76d2594d0e2195cb4 Mon Sep 17 00:00:00 2001 From: Chris Bell Date: Sat, 14 Dec 2024 21:53:11 -0600 Subject: [PATCH] Network auth and syncronization for the player --- .../core/enviroment/dev-level/dev-level.tscn | 8 ++--- .../core/networking/scripts/NetworkManager.gd | 7 ++-- assets/core/networking/scripts/Syncronizer.gd | 32 +++++++++++------- .../core/player-controller/scenes/player.tscn | 9 +++-- .../core/player-controller/scripts/player.gd | 33 +++++++++++++++++-- 5 files changed, 66 insertions(+), 23 deletions(-) diff --git a/assets/core/enviroment/dev-level/dev-level.tscn b/assets/core/enviroment/dev-level/dev-level.tscn index dad4c5f..9347fa3 100644 --- a/assets/core/enviroment/dev-level/dev-level.tscn +++ b/assets/core/enviroment/dev-level/dev-level.tscn @@ -1,17 +1,13 @@ -[gd_scene load_steps=5 format=3 uid="uid://ewovs6ns5y3k"] +[gd_scene load_steps=4 format=3 uid="uid://ewovs6ns5y3k"] -[ext_resource type="PackedScene" uid="uid://c6w0ivy4hetrl" path="res://assets/core/player-controller/scenes/player.tscn" id="2_q510b"] [ext_resource type="PackedScene" uid="uid://y0xb2vktsr1k" path="res://assets/core/ships/shuttle-class/shuttle-class.tscn" id="3_lsckv"] [ext_resource type="PackedScene" uid="uid://dqymnaouq1mu2" path="res://assets/core/enviroment/dev-level/terrain.tscn" id="3_vcq2f"] [ext_resource type="PackedScene" uid="uid://dlv4cwhskx8dr" path="res://assets/core/enviroment/custom-skies/sky.tscn" id="4_uss2e"] [node name="DevLevel" type="Node3D"] -[node name="Player" parent="." instance=ExtResource("2_q510b")] -transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -5.46532, 9.08969, 5.43659) -joystick_camera_sens_multiplier = 5.0 - [node name="level" parent="." instance=ExtResource("3_vcq2f")] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, -20, 0) [node name="ShuttleClass" parent="." instance=ExtResource("3_lsckv")] transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 8.4922, 0) diff --git a/assets/core/networking/scripts/NetworkManager.gd b/assets/core/networking/scripts/NetworkManager.gd index 5859d7a..2f334a7 100644 --- a/assets/core/networking/scripts/NetworkManager.gd +++ b/assets/core/networking/scripts/NetworkManager.gd @@ -357,6 +357,9 @@ func _on_game_started(): for member in lobby_members: - var player: Node3D = player_scene.instantiate() - level.add_child(player) + var player: Player = player_scene.instantiate() player.name = "Player_" + str(member["steam_id"]) + player.username = Steam.getFriendPersonaName(member["steam_id"]) + level.add_child(player) + if member["steam_id"] == steam_id: + player.is_network_authority = true diff --git a/assets/core/networking/scripts/Syncronizer.gd b/assets/core/networking/scripts/Syncronizer.gd index eb7f8e8..8121b22 100644 --- a/assets/core/networking/scripts/Syncronizer.gd +++ b/assets/core/networking/scripts/Syncronizer.gd @@ -7,19 +7,29 @@ class_name Syncronizer signal property_changed(node_id: int, property_name: String, value: Variant) func _ready() -> void: - for property_name in properties_to_sync: - self.connect("property_changed", Callable(self, "_on_property_changed")) - - NetworkManager.property_update_received.connect(Callable(self, "_on_property_update_received")) + # Connect the signal only once + if not is_connected("property_changed", Callable(self, "_on_property_changed")): + connect("property_changed", Callable(self, "_on_property_changed")) + NetworkManager.property_update_received.connect(Callable(self, "_on_property_update_received")) func _on_property_changed(node_id: int, property_name: String, value: Variant) -> void: - if node_id == get_instance_id() and property_name in properties_to_sync: - self.set(property_name, value) - emit_signal("property_changed", node_id, property_name, value) - + if node_id == get_instance_id() and property_name in properties_to_sync: + if get(property_name) != value: + disconnect("property_changed", Callable(self, "_on_property_changed")) + set(property_name, value) + emit_signal("property_changed", node_id, property_name, value) + connect("property_changed", Callable(self, "_on_property_changed")) func set_property(property_name: String, value: Variant) -> void: - if property_name in properties_to_sync: - self.set(property_name, value) - emit_signal("property_changed", get_instance_id(), property_name, value) \ No newline at end of file + if property_name in properties_to_sync: + if get(property_name) != value: + disconnect("property_changed", Callable(self, "_on_property_changed")) + set(property_name, value) + emit_signal("property_changed", get_instance_id(), property_name, value) + connect("property_changed", Callable(self, "_on_property_changed")) + +func get_property(property_name: String) -> Variant: + if property_name in properties_to_sync: + return get(property_name) + return null diff --git a/assets/core/player-controller/scenes/player.tscn b/assets/core/player-controller/scenes/player.tscn index 1ab7490..17a93d3 100644 --- a/assets/core/player-controller/scenes/player.tscn +++ b/assets/core/player-controller/scenes/player.tscn @@ -1,10 +1,11 @@ -[gd_scene load_steps=11 format=3 uid="uid://c6w0ivy4hetrl"] +[gd_scene load_steps=12 format=3 uid="uid://c6w0ivy4hetrl"] [ext_resource type="Script" path="res://assets/core/player-controller/scripts/player.gd" id="1_bv7t4"] [ext_resource type="Script" path="res://assets/core/player-controller/scripts/player_interacter.gd" id="2_wvu3d"] [ext_resource type="Script" path="res://assets/core/player-controller/scripts/player_hud.gd" id="3_02ne1"] [ext_resource type="Shader" path="res://assets/core/player-controller/scenes/inverted_crosshair.gdshader" id="3_rakxt"] [ext_resource type="Texture2D" uid="uid://c3lblkyavjtol" path="res://assets/core/player-controller/2d_crosshair_dot.png" id="4_3uwxe"] +[ext_resource type="Script" path="res://assets/core/networking/scripts/Syncronizer.gd" id="6_hwrq2"] [sub_resource type="CapsuleMesh" id="CapsuleMesh_v7b3h"] radius = 0.35 @@ -22,9 +23,10 @@ shader = ExtResource("3_rakxt") [sub_resource type="ShaderMaterial" id="ShaderMaterial_0n7pd"] shader = ExtResource("3_rakxt") -[node name="Player" type="CharacterBody3D" node_paths=PackedStringArray("camera")] +[node name="Player" type="CharacterBody3D" node_paths=PackedStringArray("synchronizer", "camera")] collision_mask = 242 script = ExtResource("1_bv7t4") +synchronizer = NodePath("Syncronizer") camera = NodePath("Neck/Camera3D") [node name="PlayerTag" type="Label3D" parent="."] @@ -111,3 +113,6 @@ theme_override_font_sizes/font_size = 35 text = "999 FPS" horizontal_alignment = 2 vertical_alignment = 1 + +[node name="Syncronizer" type="Node" parent="."] +script = ExtResource("6_hwrq2") diff --git a/assets/core/player-controller/scripts/player.gd b/assets/core/player-controller/scripts/player.gd index a3eca63..2e0e428 100644 --- a/assets/core/player-controller/scripts/player.gd +++ b/assets/core/player-controller/scripts/player.gd @@ -1,9 +1,13 @@ class_name Player extends CharacterBody3D +@export var synchronizer: Syncronizer + var player_tag: Label3D var username: String = "" var is_piloting: bool = false +var is_network_authority: bool = false + @export_category("Player") @export_range(1, 35, 1) var speed: float = 5 # m/s @export_range(10, 400, 1) var acceleration: float = 100 # m/s^2 @@ -26,12 +30,18 @@ var jump_vel: Vector3 # Jumping velocity var current_ship: Ship -func _ready() -> void: - capture_mouse() +func _enter_tree() -> void: player_tag = get_node("PlayerTag") + player_tag.text = username + synchronizer.properties_to_sync = ["global_position", "global_rotation", "is_piloting"] + + if is_network_authority: + camera.current = true + capture_mouse() func _unhandled_input(event: InputEvent) -> void: + if !is_network_authority: return if Input.mouse_mode == Input.MOUSE_MODE_CAPTURED: if event is InputEventMouseMotion: is_using_joystick = false @@ -44,6 +54,7 @@ func _unhandled_input(event: InputEvent) -> void: func _input(event): + if !is_network_authority: return if event.is_action_pressed("esc") and Input.mouse_mode == Input.MOUSE_MODE_CAPTURED: release_mouse() elif event.is_action_pressed("esc") and not Input.mouse_mode == Input.MOUSE_MODE_CAPTURED: @@ -51,6 +62,7 @@ func _input(event): func _physics_process(delta: float) -> void: + if !is_network_authority: return if current_ship != null: if is_piloting: #if we are piloting a ship global_transform.basis = current_ship.global_transform.basis @@ -71,15 +83,29 @@ func _physics_process(delta: float) -> void: move_and_slide() +func _process(delta: float) -> void: + if !is_network_authority: return + + # Check if position changed and update synchronizer + if global_position != synchronizer.get_property("global_position"): + synchronizer.set_property("global_position", global_position) + + # Check if rotation changed and update synchronizer + if global_rotation != synchronizer.get_property("global_rotation"): + synchronizer.set_property("global_rotation", global_rotation) + func capture_mouse() -> void: + if !is_network_authority: return Input.set_mouse_mode(Input.MOUSE_MODE_CAPTURED) func release_mouse() -> void: + if !is_network_authority: return Input.set_mouse_mode(Input.MOUSE_MODE_VISIBLE) func _rotate_camera(sens_mod: float = 1.0) -> void: + if !is_network_authority: return var camera_sens_final = camera_sens if is_using_joystick: camera_sens_final = camera_sens * joystick_camera_sens_multiplier @@ -120,17 +146,20 @@ func _jump(delta: float) -> Vector3: func player_entered_ship(ship_global_position: Vector3, ship: Ship): + if !is_network_authority: return current_ship = ship print(ship.ship_id) print(global_position) func player_exited_ship(ship_global_position: Vector3, ship: Ship): + if !is_network_authority: return current_ship = null print(ship.ship_id) print(global_position) func set_is_piloting(state: bool): + if !is_network_authority: return is_piloting = state GameConsole.log_debug("player pilot state" + str(is_piloting))