fix: synchronize late-joining players

This commit is contained in:
Alexander Sellite 2026-08-23 01:23:00 -04:00
parent 5c3eba1ad2
commit 2aeaf1d44d
6 changed files with 371 additions and 49 deletions

View file

@ -97,6 +97,10 @@ func preview_appearance(appearance: Dictionary) -> bool:
_preferences.display_name,
snapshot,
)
var authorization := _make_appearance_preview_authorization(snapshot)
var local_record := _session.get_peer_record(local_peer_id)
if local_record != null:
local_record.profile_authorization = authorization.duplicate(true)
if _session.is_host():
_broadcast_appearance_preview_to_supported_peers(
local_peer_id,
@ -105,20 +109,27 @@ func preview_appearance(appearance: Dictionary) -> bool:
elif _session.supports_server_capability(
NetworkProtocol.APPEARANCE_PREVIEW_CAPABILITY
):
var request: Dictionary = {
"request_id": _new_id(),
"session_id": _session.get_session_id(),
"appearance": snapshot.duplicate(true),
"sender_fingerprint": _session.get_local_identity_fingerprint(),
}
request["sender_signature"] = _session.sign_local_action(
"appearance_preview",
NetworkProfileProtocol.appearance_preview_signature_fields(request),
)
submit_appearance_preview.rpc_id(1, request)
submit_appearance_preview.rpc_id(1, authorization)
return true
func _make_appearance_preview_authorization(
appearance: Dictionary,
) -> Dictionary:
var request: Dictionary = {
"domain": "appearance_preview",
"request_id": _new_id(),
"session_id": _session.get_session_id(),
"appearance": appearance.duplicate(true),
"sender_fingerprint": _session.get_local_identity_fingerprint(),
}
request["sender_signature"] = _session.sign_local_action(
"appearance_preview",
NetworkProfileProtocol.appearance_preview_signature_fields(request),
)
return request
func restore_persisted_appearance() -> void:
preview_appearance(_appearance_store.get_snapshot())
@ -274,6 +285,9 @@ func submit_appearance_preview(data: Dictionary) -> void:
var appearance := CharacterCustomizationCatalog.sanitized_snapshot(
data["appearance"]
)
var authorization := data.duplicate(true)
authorization["domain"] = "appearance_preview"
record.profile_authorization = authorization
_session.apply_canonical_profile(
sender_id,
record.display_name,
@ -482,23 +496,16 @@ func broadcast_profile_snapshot(
or not CharacterCustomizationCatalog.validate_snapshot(appearance)
):
return
if not authorization.is_empty():
var signed := authorization.duplicate(true)
signed["display_name"] = display_name
signed["appearance"] = appearance
var record := _session.get_peer_record(peer_id)
if (
record == null
or record.identity_fingerprint
!= str(signed.get("sender_fingerprint", ""))
or not _session.verify_peer_action(
peer_id,
"profile_update",
NetworkProfileProtocol.signature_fields(signed),
signed.get("sender_signature", PackedByteArray()),
)
):
return
if (
not authorization.is_empty()
and not _session.verify_profile_authorization(
peer_id,
display_name,
appearance,
authorization,
)
):
return
_session.apply_canonical_profile(peer_id, display_name, appearance)
_apply_to_avatar(peer_id, appearance)
profile_snapshot_changed.emit(peer_id, display_name, appearance.duplicate(true))