fix: synchronize late-joining players
This commit is contained in:
parent
5c3eba1ad2
commit
2aeaf1d44d
6 changed files with 371 additions and 49 deletions
|
|
@ -5,6 +5,7 @@ const BURST_COUNT: int = 3
|
|||
const WINDOW_COUNT: int = 5
|
||||
const WINDOW_SECONDS: float = 10.0
|
||||
const CALL_COOLDOWN_MILLISECONDS: int = 90
|
||||
const MAX_PENDING_MESSAGES_PER_PEER: int = 8
|
||||
const DEDICATED_CHAT_WARNING: String = (
|
||||
"Privacy notice: This dedicated server records and retains chat messages."
|
||||
)
|
||||
|
|
@ -40,6 +41,7 @@ var _last_call_msec: Dictionary[int, int] = {}
|
|||
var _call_variant_indices: Dictionary[int, int] = {}
|
||||
var _sequence: int = 0
|
||||
var _peer_names: Dictionary[int, String] = {}
|
||||
var _pending_peer_messages: Dictionary[int, Array] = {}
|
||||
var _relationships: PlayerRelationshipStore
|
||||
var _dedicated_history_enabled: bool = false
|
||||
var _chat_log_path: String = ""
|
||||
|
|
@ -418,9 +420,11 @@ func _apply_message(
|
|||
else:
|
||||
var sender_id := int(data["sender_peer_id"])
|
||||
var record := _session.get_peer_record(sender_id)
|
||||
if record == null:
|
||||
_queue_pending_peer_message(sender_id, data, emit_live_signals)
|
||||
return
|
||||
valid_signature = (
|
||||
record != null
|
||||
and record.identity_fingerprint == str(data["sender_fingerprint"])
|
||||
record.identity_fingerprint == str(data["sender_fingerprint"])
|
||||
and _session.verify_peer_action(
|
||||
sender_id,
|
||||
"chat_send",
|
||||
|
|
@ -466,7 +470,47 @@ func receive_chat_rejection(message: String) -> void:
|
|||
send_rejected.emit(message.left(80))
|
||||
|
||||
|
||||
func _queue_pending_peer_message(
|
||||
peer_id: int,
|
||||
message: Dictionary,
|
||||
emit_live_signals: bool,
|
||||
) -> void:
|
||||
if peer_id <= 0:
|
||||
return
|
||||
var pending: Array = _pending_peer_messages.get(peer_id, [])
|
||||
var message_id := str(message.get("message_id", ""))
|
||||
for value: Variant in pending:
|
||||
if (
|
||||
typeof(value) == TYPE_DICTIONARY
|
||||
and str(value.get("message", {}).get("message_id", "")) == message_id
|
||||
):
|
||||
return
|
||||
pending.append({
|
||||
"message": message.duplicate(true),
|
||||
"emit_live_signals": emit_live_signals,
|
||||
})
|
||||
while pending.size() > MAX_PENDING_MESSAGES_PER_PEER:
|
||||
pending.pop_front()
|
||||
_pending_peer_messages[peer_id] = pending
|
||||
|
||||
|
||||
func _flush_pending_peer_messages(peer_id: int) -> void:
|
||||
var pending: Array = _pending_peer_messages.get(peer_id, [])
|
||||
_pending_peer_messages.erase(peer_id)
|
||||
for value: Variant in pending:
|
||||
if typeof(value) != TYPE_DICTIONARY:
|
||||
continue
|
||||
var queued: Dictionary = value
|
||||
if typeof(queued.get("message")) != TYPE_DICTIONARY:
|
||||
continue
|
||||
_apply_message(
|
||||
queued["message"],
|
||||
bool(queued.get("emit_live_signals", true)),
|
||||
)
|
||||
|
||||
|
||||
func _on_peer_authenticated(peer_id: int, display_name: String) -> void:
|
||||
_flush_pending_peer_messages(peer_id)
|
||||
if not _session.is_host():
|
||||
return
|
||||
_peer_names[peer_id] = display_name
|
||||
|
|
@ -500,6 +544,7 @@ func _on_peer_removed(peer_id: int) -> void:
|
|||
_rate_times.erase(peer_id)
|
||||
_last_call_msec.erase(peer_id)
|
||||
_call_variant_indices.erase(peer_id)
|
||||
_pending_peer_messages.erase(peer_id)
|
||||
if not _session.is_host():
|
||||
return
|
||||
var display_name: String = _peer_names.get(peer_id, "Player")
|
||||
|
|
@ -601,6 +646,7 @@ func _on_session_state_changed(state: NetworkSession.State) -> void:
|
|||
_last_call_msec.clear()
|
||||
_call_variant_indices.clear()
|
||||
_peer_names.clear()
|
||||
_pending_peer_messages.clear()
|
||||
_sequence = 0
|
||||
history_replaced.emit([])
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue