fix: synchronize late-joining players
This commit is contained in:
parent
5c3eba1ad2
commit
2aeaf1d44d
6 changed files with 371 additions and 49 deletions
|
|
@ -1559,8 +1559,9 @@ func _apply_spawn_entry(entry: Dictionary) -> void:
|
|||
own_snapshot["visual_yaw"] = float(entry["yaw"])
|
||||
own_avatar.apply_network_teleport(own_snapshot)
|
||||
return
|
||||
var peer_was_added: bool = false
|
||||
if not _registry.has_peer(peer_id):
|
||||
_registry.add_peer(
|
||||
if not _registry.add_peer(
|
||||
peer_id,
|
||||
entry["profile_id"],
|
||||
entry["display_name"],
|
||||
|
|
@ -1568,8 +1569,14 @@ func _apply_spawn_entry(entry: Dictionary) -> void:
|
|||
str(entry.get("identity_fingerprint", "")),
|
||||
str(entry.get("identity_public_key", "")),
|
||||
_sanitized_capabilities(entry.get("capability_flags", [])),
|
||||
)
|
||||
):
|
||||
return
|
||||
peer_was_added = true
|
||||
var added_record := _registry.get_peer(peer_id)
|
||||
if added_record != null:
|
||||
added_record.profile_authorization = Dictionary(
|
||||
entry.get("profile_authorization", {})
|
||||
).duplicate(true)
|
||||
if added_record != null and added_record.identity_authenticated:
|
||||
_archive_authenticated_identity(added_record)
|
||||
var status := _known_players.observe(
|
||||
|
|
@ -1596,6 +1603,8 @@ func _apply_spawn_entry(entry: Dictionary) -> void:
|
|||
var record := _registry.get_peer(peer_id)
|
||||
if avatar != null and record != null:
|
||||
avatar.apply_appearance_snapshot(record.appearance_snapshot)
|
||||
if peer_was_added and record != null:
|
||||
peer_authenticated.emit(peer_id, record.display_name)
|
||||
|
||||
|
||||
func _build_spawn_list() -> Array[Dictionary]:
|
||||
|
|
@ -1695,25 +1704,62 @@ func _update_local_operator() -> void:
|
|||
_local_operator = bool(_operator_peer_ids.get(local_peer_id, false))
|
||||
|
||||
|
||||
func _verify_spawn_identity(entry: Dictionary) -> bool:
|
||||
var fingerprint := str(entry.get("identity_fingerprint", ""))
|
||||
var public_pem := NetworkIdentityCrypto.normalize_public_pem(
|
||||
str(entry.get("identity_public_key", ""))
|
||||
)
|
||||
if (
|
||||
NetworkIdentityCrypto.fingerprint_public_pem(public_pem) != fingerprint
|
||||
or typeof(entry.get("profile_authorization")) != TYPE_DICTIONARY
|
||||
):
|
||||
func verify_profile_authorization(
|
||||
peer_id: int,
|
||||
display_name: String,
|
||||
appearance: Dictionary,
|
||||
authorization: Dictionary,
|
||||
) -> bool:
|
||||
var record := _registry.get_peer(peer_id)
|
||||
if record == null:
|
||||
return false
|
||||
return _verify_profile_authorization_fields(
|
||||
peer_id,
|
||||
record.profile_id,
|
||||
display_name,
|
||||
appearance,
|
||||
record.identity_fingerprint,
|
||||
record.identity_public_key,
|
||||
authorization,
|
||||
)
|
||||
|
||||
|
||||
func _verify_spawn_identity(entry: Dictionary) -> bool:
|
||||
if typeof(entry.get("profile_authorization")) != TYPE_DICTIONARY:
|
||||
return false
|
||||
return _verify_profile_authorization_fields(
|
||||
int(entry.get("peer_id", 0)),
|
||||
str(entry.get("profile_id", "")),
|
||||
str(entry.get("display_name", "")),
|
||||
Dictionary(entry.get("appearance", {})),
|
||||
str(entry.get("identity_fingerprint", "")),
|
||||
str(entry.get("identity_public_key", "")),
|
||||
Dictionary(entry.get("profile_authorization", {})),
|
||||
)
|
||||
|
||||
|
||||
func _verify_profile_authorization_fields(
|
||||
peer_id: int,
|
||||
profile_id: String,
|
||||
display_name: String,
|
||||
appearance: Dictionary,
|
||||
fingerprint: String,
|
||||
identity_public_key: String,
|
||||
authorization: Dictionary,
|
||||
) -> bool:
|
||||
var public_pem := NetworkIdentityCrypto.normalize_public_pem(
|
||||
identity_public_key
|
||||
)
|
||||
if NetworkIdentityCrypto.fingerprint_public_pem(public_pem) != fingerprint:
|
||||
return false
|
||||
var authorization: Dictionary = entry["profile_authorization"]
|
||||
if authorization.is_empty():
|
||||
return int(entry.get("peer_id", 0)) == 1
|
||||
return peer_id == 1
|
||||
if authorization.get("domain") == "handshake_client_profile":
|
||||
var hello := NetworkProtocol.make_client_hello(
|
||||
str(entry.get("profile_id", "")),
|
||||
str(entry.get("display_name", "")),
|
||||
profile_id,
|
||||
display_name,
|
||||
str(authorization.get("client_nonce", "")),
|
||||
Dictionary(entry.get("appearance", {})),
|
||||
appearance,
|
||||
fingerprint,
|
||||
authorization.get("signature", PackedByteArray()),
|
||||
)
|
||||
|
|
@ -1723,10 +1769,23 @@ func _verify_spawn_identity(entry: Dictionary) -> bool:
|
|||
NetworkProtocol.client_profile_fields(hello),
|
||||
hello["identity_signature"],
|
||||
)
|
||||
if authorization.get("domain") == "appearance_preview":
|
||||
if str(authorization.get("sender_fingerprint", "")) != fingerprint:
|
||||
return false
|
||||
var preview := authorization.duplicate(true)
|
||||
preview["appearance"] = appearance
|
||||
return NetworkIdentityCrypto.verify_fields(
|
||||
NetworkIdentityCrypto.load_public_key(public_pem),
|
||||
"appearance_preview",
|
||||
NetworkProfileProtocol.appearance_preview_signature_fields(preview),
|
||||
preview.get("sender_signature", PackedByteArray()),
|
||||
)
|
||||
if authorization.has("sender_signature"):
|
||||
if str(authorization.get("sender_fingerprint", "")) != fingerprint:
|
||||
return false
|
||||
var signed := authorization.duplicate(true)
|
||||
signed["display_name"] = entry.get("display_name", "")
|
||||
signed["appearance"] = entry.get("appearance", {})
|
||||
signed["display_name"] = display_name
|
||||
signed["appearance"] = appearance
|
||||
return NetworkIdentityCrypto.verify_fields(
|
||||
NetworkIdentityCrypto.load_public_key(public_pem),
|
||||
"profile_update",
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue