Remove type information from own types

Doesn't work well with runtime loaded resource packs (mods).
main
copygirl 2 weeks ago
parent 2290e058b6
commit a3e8841667
  1. 2
      Scenes/copy_multiplayer_settings.gd
  2. 2
      Scenes/player_settings.gd
  3. 2
      Scenes/player_stats.gd
  4. 44
      Scenes/sync_controller.gd
  5. 10
      Utility/stream_buffer.gd
  6. 57
      copyMultiplayer.gd

@ -1,4 +1,4 @@
class_name copyMultiplayerSettings #class_name copyMultiplayerSettings
extends TabContainer extends TabContainer
@export var visible_icon : Texture2D @export var visible_icon : Texture2D

@ -1,4 +1,4 @@
class_name PlayerSettings #class_name PlayerSettings
extends Container extends Container
signal value_changed(Transform3D) signal value_changed(Transform3D)

@ -1,4 +1,4 @@
class_name PlayerStats #class_name PlayerStats
extends Container extends Container
var history: Array[Dictionary] = [] var history: Array[Dictionary] = []

@ -1,10 +1,12 @@
class_name SyncController #class_name SyncController
extends Area3D extends Area3D
static var StreamBuffer = load("res://Mods/copyMultiplayer/Utility/stream_buffer.gd")
@export var shape: CollisionShape3D @export var shape: CollisionShape3D
var peer_id: int var peer_id: int
var module: copyMultiplayer var module #: copyMultiplayer
var model_controller: ModelController var model_controller: ModelController
var nickname: String var nickname: String
@ -19,15 +21,15 @@ var skeleton : Skeleton3D
var anim_player : AnimationPlayer var anim_player : AnimationPlayer
var anim_root : Node var anim_root : Node
var settings : PlayerSettings var settings #: PlayerSettings
var stats : PlayerStats var stats #: PlayerStats
var pings : Dictionary var pings : Dictionary
var is_dragging := false var is_dragging := false
var drag_current: Vector3 var drag_current: Vector3
# Reusable buffer to write data for synchronizing models. # 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: func _ready() -> void:
peer_id = name.to_int() peer_id = name.to_int()
@ -91,7 +93,7 @@ func change_model(
if not filename.is_valid_filename(): if not filename.is_valid_filename():
module.print_log("ERROR: '%s' is not a valid file name!" % filename) module.print_log("ERROR: '%s' is not a valid file name!" % filename)
return 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): 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 ]) module.print_log("%s wanted to switch to '%s', but it doesn't exist, skipping" % [ get_display_name(), filename ])
return return
@ -122,7 +124,7 @@ func sync_model_animation(
if stats: stats.push(buffer.size()) if stats: stats.push(buffer.size())
var uncompressed_buffer := buffer.decompress(uncompressed_length, FileAccess.COMPRESSION_ZSTD); 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() model.transform = stream.read_transform16()
@ -140,10 +142,10 @@ func sync_model_animation(
# 256 bones (and blendshapes) should be enough, right? # 256 bones (and blendshapes) should be enough, right?
for i in stream.read_uint8(): 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) all_bones[lookup].pose = stream.read_bone_pose(all_bones[lookup].pose)
for i in stream.read_uint8(): for i in stream.read_uint8():
var lookup := stream.read_uint8() var lookup: int = stream.read_uint8()
all_blendshapes[lookup].value = stream.read_range16() all_blendshapes[lookup].value = stream.read_range16()
# Apply all the values to bones / blendshapes. # 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) anim_node.set("blend_shapes/" + blendshape.path.get_subname(0), blendshape.value)
@warning_ignore("shadowed_variable") @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. # Check if there's other players we're connected to.
if module.multiplayer.get_peers().size() == 0: return if module.multiplayer.get_peers().size() == 0: return
var model := module.get_model() var model = module.get_model()
var skeleton := module.get_skeleton() var skeleton = module.get_skeleton()
var anim_player := model.find_child("AnimationPlayer", false, false) var anim_player = model.find_child("AnimationPlayer", false, false)
var anim_root := anim_player.get_node_or_null(anim_player.root_node) var anim_root = anim_player.get_node_or_null(anim_player.root_node)
if (not model) or (not skeleton) or (not anim_root): return if (not model) or (not skeleton) or (not anim_root): return
write_stream.write_transform16(model.transform) write_stream.write_transform16(model.transform)
@ -174,16 +176,16 @@ static func send_model_animation(module: copyMultiplayer) -> void:
var active_blendshapes := [] var active_blendshapes := []
for i in module.bone_lookup.size(): for i in module.bone_lookup.size():
var bone_name := module.bone_lookup[i] var bone_name = module.bone_lookup[i]
var bone_idx := skeleton.find_bone(bone_name) var bone_idx = skeleton.find_bone(bone_name)
var bone_pose := skeleton.get_bone_pose(bone_idx) var bone_pose = skeleton.get_bone_pose(bone_idx)
var bone_rest := skeleton.get_bone_rest(bone_idx) var bone_rest = skeleton.get_bone_rest(bone_idx)
if not bone_pose.is_equal_approx(bone_rest): if not bone_pose.is_equal_approx(bone_rest):
restless_bones.append({ lookup = i, pose = bone_pose, rest = bone_rest }) restless_bones.append({ lookup = i, pose = bone_pose, rest = bone_rest })
for i in module.blendshape_lookup.size(): for i in module.blendshape_lookup.size():
var anim_path := module.blendshape_lookup[i] var anim_path = module.blendshape_lookup[i]
var anim_node := anim_root.get_node_or_null(anim_path) var anim_node = anim_root.get_node_or_null(anim_path)
var value: float = anim_node.get("blend_shapes/" + anim_path.get_subname(0)) var value: float = anim_node.get("blend_shapes/" + anim_path.get_subname(0))
if not is_zero_approx(value): if not is_zero_approx(value):
active_blendshapes.append({ lookup = i, value = 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) write_stream.write_range16(blendshape.value)
# The compression still helps, so we'll keep it for now. # 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? # 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.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) module.sync_model_animation.rpc(module.version, write_stream.size, compressed_buffer)

@ -1,4 +1,4 @@
class_name StreamBuffer #class_name StreamBuffer
extends Resource extends Resource
# This maximum capacity is just to ensure we're not doing something wrong, # 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. ## Creates a new StreamBuffer with the specified capacity.
## This is intended for writing / encoding data. ## 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() var _buffer = PackedByteArray()
_buffer.resize(initial_capacity) _buffer.resize(initial_capacity)
return StreamBuffer.new(_buffer) return new(_buffer)
## Creates a new StreamBuffer from the specified buffer, pre-initializing "size". ## Creates a new StreamBuffer from the specified buffer, pre-initializing "size".
## This is intended for reading / decoding data. ## This is intended for reading / decoding data.
static func from_buffer(_buffer: PackedByteArray) -> StreamBuffer: static func from_buffer(_buffer: PackedByteArray): #-> StreamBuffer:
var stream := StreamBuffer.new(_buffer) var stream := new(_buffer)
stream.size = stream.capacity stream.size = stream.capacity
return stream return stream

@ -1,13 +1,17 @@
class_name copyMultiplayer #class_name copyMultiplayer
extends Mod_Base 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 cache := ""
@export var nickname := "" @export var nickname := ""
@export var address := "" @export var address := ""
@export var port := 52410 @export var port := 52410
var main_controller: ModelController var main_controller: ModelController
var main_stats : PlayerStats var main_stats #: PlayerStats
var ping_update_timer: Timer var ping_update_timer: Timer
## Hardcoded list of bone names that will get syncronized. ## Hardcoded list of bone names that will get syncronized.
@ -58,7 +62,7 @@ func _ready() -> void:
setup_button_connections() setup_button_connections()
# Filter whitespace characters from nickname before saving it to "nickname" field. # 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_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.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) 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() return load("res://Mods/copyMultiplayer/Scenes/copy_multiplayer_settings.tscn").instantiate()
# Override base method to provide type hint. # Override base method to provide type hint.
func get_settings_window() -> copyMultiplayerSettings: # func get_settings_window() -> copyMultiplayerSettings:
return super.get_settings_window() # return super.get_settings_window()
func setup_setting_widget(category: String, setting: String, setup_events: bool) -> void: 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 ]) var widget: Control = settings.get("%s_%s" % [ category, setting ])
_settings_properties.append({ name = setting, args = { } }) _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", { }) widget.set_meta("reset_button", { })
func setup_button_connections() -> void: 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_join.pressed.connect(on_join_pressed)
settings.connect_host.pressed.connect(on_host_pressed) settings.connect_host.pressed.connect(on_host_pressed)
settings.connect_disconnect.pressed.connect(on_disconnect_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") 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 container = get_settings_window().get_node("Players/VBoxContainer")
var result := player_settings_scene.instantiate() var result := player_settings_scene.instantiate()
container.add_child(result) container.add_child(result)
return result return result
var player_stats_scene: PackedScene = load("res://Mods/copyMultiplayer/Scenes/player_stats.tscn") 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 container = get_settings_window().get_node("Stats/VBoxContainer")
var result := player_stats_scene.instantiate() var result := player_stats_scene.instantiate()
container.add_child(result) container.add_child(result)
@ -202,7 +206,7 @@ func on_server_disconnected() -> void:
func update_enabled_state(is_online: bool) -> 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.settings_nickname .editable = !is_online
settings.connect_address .editable = !is_online settings.connect_address .editable = !is_online
settings.connect_port .editable = !is_online settings.connect_port .editable = !is_online
@ -220,8 +224,7 @@ func update_status() -> void:
## Removes all networked player models. ## Removes all networked player models.
func clear_player_models() -> void: func clear_player_models() -> void:
for controller in get_children(): for controller in get_all_sync_controllers():
if controller is SyncController:
remove_child(controller) remove_child(controller)
controller.queue_free() controller.queue_free()
@ -266,19 +269,21 @@ func scene_init() -> void:
change_model.rpc(version, bone_lookup, blendshape_lookup, filename) change_model.rpc(version, bone_lookup, blendshape_lookup, filename)
func get_sync_controller(peer_id: int) -> SyncController: func get_sync_controller(peer_id: int): #-> SyncController:
return get_node_or_null(str(peer_id)) as SyncController return get_node_or_null(str(peer_id)) #as SyncController
func get_all_sync_controllers() -> Array[SyncController]: func get_all_sync_controllers(): #-> Array[SyncController]:
var result: Array[SyncController] = [] return get_children()
for controller in get_children(): # NOTE: Let's just assume all child nodes are SyncController.
if controller is SyncController: # var result: Array[SyncController] = []
result.append(controller) # for controller in get_children():
return result # 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 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 if controller: return controller.stats
return null return null
@ -288,7 +293,7 @@ func update_pings(pairs: Array[int]) -> void:
for i in range(0, pairs.size(), 2): for i in range(0, pairs.size(), 2):
var peer_id := pairs[i] var peer_id := pairs[i]
var ping := pairs[i + 1] 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) if stats: stats.set_ping(ping)
func do_update_pings() -> void: func do_update_pings() -> void:
@ -303,7 +308,7 @@ func do_update_pings() -> void:
@rpc("any_peer", "reliable") @rpc("any_peer", "reliable")
func change_nickname(new_nickname: String) -> void: func change_nickname(new_nickname: String) -> void:
var peer_id := multiplayer.get_remote_sender_id() 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) if controller: controller.change_nickname(new_nickname)
@rpc("any_peer", "reliable") @rpc("any_peer", "reliable")
@ -314,7 +319,7 @@ func change_model(
filename: String, filename: String,
) -> void: ) -> void:
var peer_id := multiplayer.get_remote_sender_id() 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) if controller: controller.change_model(new_version, new_bone_lookup, new_blendshape_lookup, filename)
@rpc("any_peer", "unreliable_ordered") @rpc("any_peer", "unreliable_ordered")
@ -324,5 +329,5 @@ func sync_model_animation(
buffer: PackedByteArray, buffer: PackedByteArray,
) -> void: ) -> void:
var peer_id := multiplayer.get_remote_sender_id() 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) if controller: controller.sync_model_animation(current_version, uncompressed_length, buffer)

Loading…
Cancel
Save