Sync from GitHub main #1

Open
nomad wants to merge 145 commits from sync/from-github into main
Showing only changes of commit b04fca8154 - Show all commits
+32 -2
View File
@@ -769,8 +769,16 @@ class FalloutTogetherServer:
return False
normalized["playerId"] = client.player_id
normalized["serverTime"] = time.time()
durable_fields = ("equippedItems", "appearance", "characterName")
with self._lock:
self._last_player_state_by_player_id[client.player_id] = dict(normalized)
if any(field in normalized for field in durable_fields):
cached = dict(self._last_player_state_by_player_id.get(client.player_id, {}))
cached.update({"type": "playerState", "playerId": client.player_id, "serverTime": normalized["serverTime"]})
for field in durable_fields:
if field in normalized:
cached[field] = normalized[field]
cached.pop("actionEvents", None)
self._last_player_state_by_player_id[client.player_id] = cached
self._stats["playerStatePacketsReceived"] += 1
self._broadcast_player_state(client, normalized)
return True
@@ -1177,7 +1185,29 @@ class FalloutTogetherServer:
self._disconnect_client(recipient)
def _broadcast_player_state(self, sender: ClientSession, packet: dict[str, Any]) -> None:
successful, failed = self._broadcast_to_active(packet, exclude=sender, v2_only=True)
with self._lock:
recipients = [
client
for client in self._active_clients_locked()
if client.connection != sender.connection and client.protocol_version >= PROTOCOL_VERSION
]
successful = 0
failed: list[ClientSession] = []
durable_fields = ("equippedItems", "appearance", "characterName")
sender_scope_known = _scope_from_state(sender.last_transform) is not None
for recipient in recipients:
relay_packet = dict(packet)
if "actionEvents" in relay_packet:
recipient_scope_known = _scope_from_state(recipient.last_transform) is not None
if not sender_scope_known or not recipient_scope_known or not states_share_interest(sender.last_transform, recipient.last_transform):
relay_packet.pop("actionEvents", None)
if "actionEvents" not in relay_packet and not any(field in relay_packet for field in durable_fields):
continue
try:
self._send_packet(recipient, relay_packet, broadcast=True)
successful += 1
except (OSError, ValueError):
failed.append(recipient)
with self._lock:
self._stats["playerStatePacketsBroadcast"] += successful
for client in failed: