diff --git a/Scenes/copy_multiplayer_settings.gd b/Scenes/copy_multiplayer_settings.gd index 79df733..bb2be9d 100644 --- a/Scenes/copy_multiplayer_settings.gd +++ b/Scenes/copy_multiplayer_settings.gd @@ -1,4 +1,4 @@ -class_name copyMultiplayerSettings +#class_name copyMultiplayerSettings extends TabContainer @export var visible_icon : Texture2D diff --git a/Scenes/player_settings.gd b/Scenes/player_settings.gd index 836d270..18c17a9 100644 --- a/Scenes/player_settings.gd +++ b/Scenes/player_settings.gd @@ -1,4 +1,4 @@ -class_name PlayerSettings +#class_name PlayerSettings extends Container signal value_changed(Transform3D) diff --git a/Scenes/player_stats.gd b/Scenes/player_stats.gd index 524c5e0..109aa22 100644 --- a/Scenes/player_stats.gd +++ b/Scenes/player_stats.gd @@ -1,4 +1,4 @@ -class_name PlayerStats +#class_name PlayerStats extends Container var history: Array[Dictionary] = [] diff --git a/Scenes/sync_controller.gd b/Scenes/sync_controller.gd index bca3de9..9ba494a 100644 --- a/Scenes/sync_controller.gd +++ b/Scenes/sync_controller.gd @@ -1,10 +1,12 @@ -class_name SyncController +#class_name SyncController extends Area3D +static var StreamBuffer = load("res://Mods/copyMultiplayer/Utility/stream_buffer.gd") + @export var shape: CollisionShape3D var peer_id: int -var module: copyMultiplayer +var module #: copyMultiplayer var model_controller: ModelController var nickname: String @@ -19,15 +21,15 @@ var skeleton : Skeleton3D var anim_player : AnimationPlayer var anim_root : Node -var settings : PlayerSettings -var stats : PlayerStats -var pings : Dictionary +var settings #: PlayerSettings +var stats #: PlayerStats +var pings : Dictionary var is_dragging := false var drag_current: Vector3 # Reusable buffer to write data for synchronizing models. -static var write_stream: StreamBuffer = StreamBuffer.with_capacity(2048) +static var write_stream = StreamBuffer.with_capacity(2048) func _ready() -> void: peer_id = name.to_int() @@ -91,7 +93,7 @@ func change_model( if not filename.is_valid_filename(): module.print_log("ERROR: '%s' is not a valid file name!" % filename) return - var full_path := module.cache.path_join(filename) + var full_path: String = module.cache.path_join(filename) if not FileAccess.file_exists(full_path): module.print_log("%s wanted to switch to '%s', but it doesn't exist, skipping" % [ get_display_name(), filename ]) return @@ -122,7 +124,7 @@ func sync_model_animation( if stats: stats.push(buffer.size()) var uncompressed_buffer := buffer.decompress(uncompressed_length, FileAccess.COMPRESSION_ZSTD); - var stream := StreamBuffer.from_buffer(uncompressed_buffer) + var stream = StreamBuffer.from_buffer(uncompressed_buffer) model.transform = stream.read_transform16() @@ -140,10 +142,10 @@ func sync_model_animation( # 256 bones (and blendshapes) should be enough, right? for i in stream.read_uint8(): - var lookup := stream.read_uint8() + var lookup: int = stream.read_uint8() all_bones[lookup].pose = stream.read_bone_pose(all_bones[lookup].pose) for i in stream.read_uint8(): - var lookup := stream.read_uint8() + var lookup: int = stream.read_uint8() all_blendshapes[lookup].value = stream.read_range16() # Apply all the values to bones / blendshapes. @@ -156,14 +158,14 @@ func sync_model_animation( anim_node.set("blend_shapes/" + blendshape.path.get_subname(0), blendshape.value) @warning_ignore("shadowed_variable") -static func send_model_animation(module: copyMultiplayer) -> void: +static func send_model_animation(module) -> void: # Check if there's other players we're connected to. if module.multiplayer.get_peers().size() == 0: return - var model := module.get_model() - var skeleton := module.get_skeleton() - var anim_player := model.find_child("AnimationPlayer", false, false) - var anim_root := anim_player.get_node_or_null(anim_player.root_node) + var model = module.get_model() + var skeleton = module.get_skeleton() + var anim_player = model.find_child("AnimationPlayer", false, false) + var anim_root = anim_player.get_node_or_null(anim_player.root_node) if (not model) or (not skeleton) or (not anim_root): return write_stream.write_transform16(model.transform) @@ -174,16 +176,16 @@ static func send_model_animation(module: copyMultiplayer) -> void: var active_blendshapes := [] for i in module.bone_lookup.size(): - var bone_name := module.bone_lookup[i] - var bone_idx := skeleton.find_bone(bone_name) - var bone_pose := skeleton.get_bone_pose(bone_idx) - var bone_rest := skeleton.get_bone_rest(bone_idx) + var bone_name = module.bone_lookup[i] + var bone_idx = skeleton.find_bone(bone_name) + var bone_pose = skeleton.get_bone_pose(bone_idx) + var bone_rest = skeleton.get_bone_rest(bone_idx) if not bone_pose.is_equal_approx(bone_rest): restless_bones.append({ lookup = i, pose = bone_pose, rest = bone_rest }) for i in module.blendshape_lookup.size(): - var anim_path := module.blendshape_lookup[i] - var anim_node := anim_root.get_node_or_null(anim_path) + var anim_path = module.blendshape_lookup[i] + var anim_node = anim_root.get_node_or_null(anim_path) var value: float = anim_node.get("blend_shapes/" + anim_path.get_subname(0)) if not is_zero_approx(value): active_blendshapes.append({ lookup = i, value = value }) @@ -199,7 +201,7 @@ static func send_model_animation(module: copyMultiplayer) -> void: write_stream.write_range16(blendshape.value) # The compression still helps, so we'll keep it for now. - var compressed_buffer := write_stream.slice().compress(FileAccess.COMPRESSION_ZSTD); + var compressed_buffer = write_stream.slice().compress(FileAccess.COMPRESSION_ZSTD); # Uncomment this to see packet size. Can we hit < 256 bytes? # module.set_status("Packet size: %d bytes (%d uncompressed)" % [ compressed_buffer.size(), write_stream.size ]) module.sync_model_animation.rpc(module.version, write_stream.size, compressed_buffer) diff --git a/Utility/stream_buffer.gd b/Utility/stream_buffer.gd index 0e3da84..ddc2626 100644 --- a/Utility/stream_buffer.gd +++ b/Utility/stream_buffer.gd @@ -1,4 +1,4 @@ -class_name StreamBuffer +#class_name StreamBuffer extends Resource # This maximum capacity is just to ensure we're not doing something wrong, @@ -18,15 +18,15 @@ func _init(_buffer: PackedByteArray) -> void: ## Creates a new StreamBuffer with the specified capacity. ## This is intended for writing / encoding data. -static func with_capacity(initial_capacity: int) -> StreamBuffer: +static func with_capacity(initial_capacity: int): #-> StreamBuffer: var _buffer = PackedByteArray() _buffer.resize(initial_capacity) - return StreamBuffer.new(_buffer) + return new(_buffer) ## Creates a new StreamBuffer from the specified buffer, pre-initializing "size". ## This is intended for reading / decoding data. -static func from_buffer(_buffer: PackedByteArray) -> StreamBuffer: - var stream := StreamBuffer.new(_buffer) +static func from_buffer(_buffer: PackedByteArray): #-> StreamBuffer: + var stream := new(_buffer) stream.size = stream.capacity return stream diff --git a/copyMultiplayer.gd b/copyMultiplayer.gd index 8e8a12f..8f97286 100644 --- a/copyMultiplayer.gd +++ b/copyMultiplayer.gd @@ -1,13 +1,17 @@ -class_name copyMultiplayer +#class_name copyMultiplayer extends Mod_Base +# NOTE: Due to issues with resource pack loading at runtime, we can't use +# typed references to this mod. This is a crime to all slime-kind. +static var SyncController = load("res://Mods/copyMultiplayer/Scenes/sync_controller.gd") + @export var cache := "" @export var nickname := "" @export var address := "" @export var port := 52410 var main_controller: ModelController -var main_stats : PlayerStats +var main_stats #: PlayerStats var ping_update_timer: Timer ## Hardcoded list of bone names that will get syncronized. @@ -58,7 +62,7 @@ func _ready() -> void: setup_button_connections() # Filter whitespace characters from nickname before saving it to "nickname" field. - var nickname_widget := get_settings_window().settings_nickname + var nickname_widget = get_settings_window().settings_nickname nickname_widget.text_changed.connect(func(new_text): modify_setting("nickname", new_text.strip_edges())) nickname_widget.text_submitted.connect(func(_new_text): nickname_widget.text = nickname; main_stats.set_nickname(nickname)) nickname_widget.focus_exited.connect(func(): nickname_widget.text = nickname) @@ -76,11 +80,11 @@ func _create_settings_window() -> Control: return load("res://Mods/copyMultiplayer/Scenes/copy_multiplayer_settings.tscn").instantiate() # Override base method to provide type hint. -func get_settings_window() -> copyMultiplayerSettings: - return super.get_settings_window() +# func get_settings_window() -> copyMultiplayerSettings: +# return super.get_settings_window() func setup_setting_widget(category: String, setting: String, setup_events: bool) -> void: - var settings := get_settings_window() + var settings = get_settings_window() var widget: Control = settings.get("%s_%s" % [ category, setting ]) _settings_properties.append({ name = setting, args = { } }) @@ -97,7 +101,7 @@ func setup_setting_widget(category: String, setting: String, setup_events: bool) widget.set_meta("reset_button", { }) func setup_button_connections() -> void: - var settings := get_settings_window() + var settings = get_settings_window() settings.connect_join.pressed.connect(on_join_pressed) settings.connect_host.pressed.connect(on_host_pressed) settings.connect_disconnect.pressed.connect(on_disconnect_pressed) @@ -107,14 +111,14 @@ func load_after(_old : Dictionary, _new : Dictionary) -> void: var player_settings_scene: PackedScene = load("res://Mods/copyMultiplayer/Scenes/player_settings.tscn") -func new_player_settings() -> PlayerSettings: +func new_player_settings(): #-> PlayerSettings: var container = get_settings_window().get_node("Players/VBoxContainer") var result := player_settings_scene.instantiate() container.add_child(result) return result var player_stats_scene: PackedScene = load("res://Mods/copyMultiplayer/Scenes/player_stats.tscn") -func new_player_stats() -> PlayerStats: +func new_player_stats(): #-> PlayerStats: var container = get_settings_window().get_node("Stats/VBoxContainer") var result := player_stats_scene.instantiate() container.add_child(result) @@ -202,7 +206,7 @@ func on_server_disconnected() -> void: func update_enabled_state(is_online: bool) -> void: - var settings := get_settings_window() + var settings = get_settings_window() settings.settings_nickname .editable = !is_online settings.connect_address .editable = !is_online settings.connect_port .editable = !is_online @@ -220,10 +224,9 @@ func update_status() -> void: ## Removes all networked player models. func clear_player_models() -> void: - for controller in get_children(): - if controller is SyncController: - remove_child(controller) - controller.queue_free() + for controller in get_all_sync_controllers(): + remove_child(controller) + controller.queue_free() func _process(_delta: float) -> void: @@ -266,19 +269,21 @@ func scene_init() -> void: change_model.rpc(version, bone_lookup, blendshape_lookup, filename) -func get_sync_controller(peer_id: int) -> SyncController: - return get_node_or_null(str(peer_id)) as SyncController +func get_sync_controller(peer_id: int): #-> SyncController: + return get_node_or_null(str(peer_id)) #as SyncController -func get_all_sync_controllers() -> Array[SyncController]: - var result: Array[SyncController] = [] - for controller in get_children(): - if controller is SyncController: - result.append(controller) - return result +func get_all_sync_controllers(): #-> Array[SyncController]: + return get_children() + # NOTE: Let's just assume all child nodes are SyncController. + # var result: Array[SyncController] = [] + # for controller in get_children(): + # if controller is SyncController: + # result.append(controller) + # return result -func get_player_stats(peer_id: int) -> PlayerStats: +func get_player_stats(peer_id: int): #-> PlayerStats: if peer_id == multiplayer.get_unique_id(): return main_stats - var controller := get_sync_controller(peer_id) + var controller = get_sync_controller(peer_id) if controller: return controller.stats return null @@ -288,7 +293,7 @@ func update_pings(pairs: Array[int]) -> void: for i in range(0, pairs.size(), 2): var peer_id := pairs[i] var ping := pairs[i + 1] - var stats := get_player_stats(peer_id) + var stats = get_player_stats(peer_id) if stats: stats.set_ping(ping) func do_update_pings() -> void: @@ -303,7 +308,7 @@ func do_update_pings() -> void: @rpc("any_peer", "reliable") func change_nickname(new_nickname: String) -> void: var peer_id := multiplayer.get_remote_sender_id() - var controller := get_sync_controller(peer_id) + var controller = get_sync_controller(peer_id) if controller: controller.change_nickname(new_nickname) @rpc("any_peer", "reliable") @@ -314,7 +319,7 @@ func change_model( filename: String, ) -> void: var peer_id := multiplayer.get_remote_sender_id() - var controller := get_sync_controller(peer_id) + var controller = get_sync_controller(peer_id) if controller: controller.change_model(new_version, new_bone_lookup, new_blendshape_lookup, filename) @rpc("any_peer", "unreliable_ordered") @@ -324,5 +329,5 @@ func sync_model_animation( buffer: PackedByteArray, ) -> void: var peer_id := multiplayer.get_remote_sender_id() - var controller := get_sync_controller(peer_id) + var controller = get_sync_controller(peer_id) if controller: controller.sync_model_animation(current_version, uncompressed_length, buffer)