fix webrtc FINALLY!

This commit is contained in:
2026-01-20 00:38:42 +01:00
parent 1c247f3d82
commit e88da9a169

View File

@@ -2483,7 +2483,13 @@ func _send_dungeon_blob_sync(client_peer_id: int):
# Send metadata first # Send metadata first
var metadata = dungeon_blob_metadata var metadata = dungeon_blob_metadata
print("GameWorld: HOST - [CHUNK 0] Sending metadata...") print("GameWorld: HOST - [CHUNK 0] Sending metadata...")
_sync_dungeon_blob_metadata.rpc_id(client_peer_id, metadata.seed, metadata.level, metadata.map_size, metadata.host_room, total_chunks) # Include all state data in metadata so client knows what's already changed
var defeated_list = metadata.get("defeated_enemies", [])
var broken_list = metadata.get("broken_objects", [])
var door_states_list = metadata.get("door_states", [])
var opened_chests_list = metadata.get("opened_chests", [])
var loot_list = metadata.get("existing_loot", [])
_sync_dungeon_blob_metadata.rpc_id(client_peer_id, metadata.seed, metadata.level, metadata.map_size, metadata.host_room, total_chunks, defeated_list, broken_list, door_states_list, opened_chests_list, loot_list)
# Initialize acknowledgment tracking # Initialize acknowledgment tracking
var chunk_acks = {} var chunk_acks = {}
@@ -2729,11 +2735,73 @@ func _pack_dungeon_blob():
LogManager.log("GameWorld: Packing dungeon blob - enemies: " + str(enemy_count) + ", torches: " + str(torch_count) + ", objects: " + str(object_count), LogManager.CATEGORY_DUNGEON) LogManager.log("GameWorld: Packing dungeon blob - enemies: " + str(enemy_count) + ", torches: " + str(torch_count) + ", objects: " + str(object_count), LogManager.CATEGORY_DUNGEON)
# Store metadata separately (small, sent first) # Store metadata separately (small, sent first)
# Include defeated enemies so clients know which enemies not to spawn
var defeated_indices = []
for enemy_index in defeated_enemies.keys():
defeated_indices.append(enemy_index)
# Collect broken object indices
var broken_indices = []
for obj_index in broken_objects.keys():
broken_indices.append(obj_index)
# Collect door states
var door_states_list = []
var entities_node = get_node_or_null("Entities")
if entities_node:
for child in entities_node.get_children():
if child.is_in_group("blocking_door") or child.has_method("_sync_door_open"):
var door_state = {
"door_name": child.name,
"is_closed": child.is_closed if "is_closed" in child else true,
"puzzle_solved": child.puzzle_solved if "puzzle_solved" in child else false,
"key_used": child.key_used if "key_used" in child else false,
"position": child.position if "position" in child else Vector2.ZERO,
"closed_position": child.closed_position if "closed_position" in child else Vector2.ZERO,
"open_offset": child.open_offset if "open_offset" in child else Vector2.ZERO
}
door_states_list.append(door_state)
# Collect opened chest names
var opened_chest_names = []
if entities_node:
for child in entities_node.get_children():
if child.is_in_group("interactable_object"):
if "object_type" in child and child.object_type == "Chest":
if "is_chest_opened" in child and child.is_chest_opened:
opened_chest_names.append(child.name)
# Collect existing loot
var loot_list = []
if entities_node:
for child in entities_node.get_children():
if child.is_in_group("loot"):
var current_velocity = child.velocity if "velocity" in child else Vector2.ZERO
var current_velocity_z = child.velocity_z if "velocity_z" in child else 0.0
var loot_data = {
"position": child.global_position,
"loot_type": child.loot_type if "loot_type" in child else 0,
"loot_id": child.get_meta("loot_id") if child.has_meta("loot_id") else -1,
"velocity": current_velocity,
"velocity_z": current_velocity_z
}
# For item loot, include item data
if child.loot_type == child.LootType.ITEM and "item" in child and child.item:
var item = child.item
if item.has_method("save"):
loot_data["item_data"] = item.save()
loot_list.append(loot_data)
dungeon_blob_metadata = { dungeon_blob_metadata = {
"seed": dungeon_seed, "seed": dungeon_seed,
"level": current_level, "level": current_level,
"map_size": full_dungeon_data.map_size, "map_size": full_dungeon_data.map_size,
"host_room": _get_host_room() "host_room": _get_host_room(),
"defeated_enemies": defeated_indices,
"broken_objects": broken_indices,
"door_states": door_states_list,
"opened_chests": opened_chest_names,
"existing_loot": loot_list
} }
# Serialize to bytes # Serialize to bytes
@@ -2906,11 +2974,56 @@ func _sync_dungeon(dungeon_data_sync: Dictionary, seed_value: int, level: int, h
call_deferred("_fix_player_appearance_after_dungeon_sync") call_deferred("_fix_player_appearance_after_dungeon_sync")
@rpc("authority", "reliable", "call_local") @rpc("authority", "reliable", "call_local")
func _sync_dungeon_blob_metadata(seed_value: int, level: int, map_size_sync: Vector2i, host_room: Dictionary, total_chunks: int): func _sync_dungeon_blob_metadata(seed_value: int, level: int, map_size_sync: Vector2i, host_room: Dictionary, total_chunks: int, defeated_enemies_list: Array = [], broken_objects_list: Array = [], door_states_list: Array = [], opened_chests_list: Array = [], existing_loot_list: Array = []):
# Client receives metadata for blob sync # Client receives metadata for blob sync
print("=== _sync_dungeon_blob_metadata RPC RECEIVED on client ===") print("=== _sync_dungeon_blob_metadata RPC RECEIVED on client ===")
print("=== [CHUNK 0] Client received blob metadata - Level: ", level, ", Map size: ", map_size_sync, ", Total chunks: ", total_chunks, " ===") print("=== [CHUNK 0] Client received blob metadata - Level: ", level, ", Map size: ", map_size_sync, ", Total chunks: ", total_chunks)
print("=== Defeated enemies: ", defeated_enemies_list.size(), ", Broken objects: ", broken_objects_list.size(), ", Door states: ", door_states_list.size(), ", Opened chests: ", opened_chests_list.size(), ", Existing loot: ", existing_loot_list.size(), " ===")
if not multiplayer.is_server(): if not multiplayer.is_server():
# Store defeated enemies BEFORE dungeon is unpacked and enemies are spawned
defeated_enemies.clear()
for enemy_index in defeated_enemies_list:
defeated_enemies[enemy_index] = true
if defeated_enemies_list.size() > 0:
print("GameWorld: Client - Received ", defeated_enemies_list.size(), " defeated enemy indices before dungeon spawn")
LogManager.log("GameWorld: Client received " + str(defeated_enemies_list.size()) + " defeated enemy indices", LogManager.CATEGORY_NETWORK)
# Store broken objects BEFORE objects are spawned
broken_objects.clear()
for obj_index in broken_objects_list:
broken_objects[obj_index] = true
if broken_objects_list.size() > 0:
print("GameWorld: Client - Received ", broken_objects_list.size(), " broken object indices before dungeon spawn")
LogManager.log("GameWorld: Client received " + str(broken_objects_list.size()) + " broken object indices", LogManager.CATEGORY_NETWORK)
# Store door states (will be applied after doors spawn)
pending_door_states.clear()
for door_state in door_states_list:
var door_name = door_state.get("door_name", "")
if door_name != "":
pending_door_states[door_name] = door_state
if door_states_list.size() > 0:
print("GameWorld: Client - Received ", door_states_list.size(), " door states before dungeon spawn")
LogManager.log("GameWorld: Client received " + str(door_states_list.size()) + " door states", LogManager.CATEGORY_NETWORK)
# Store opened chest states (will be applied after chests spawn)
pending_chest_opens.clear()
for chest_name in opened_chests_list:
pending_chest_opens[chest_name] = {
"loot_type": "coin", # Default, actual loot type should be stored if available
"player_peer_id": 0,
"item_data": {}
}
if opened_chests_list.size() > 0:
print("GameWorld: Client - Received ", opened_chests_list.size(), " opened chest names before dungeon spawn")
LogManager.log("GameWorld: Client received " + str(opened_chests_list.size()) + " opened chest names", LogManager.CATEGORY_NETWORK)
# Store existing loot (will be spawned after dungeon is loaded)
# We'll need to store this temporarily and spawn it after dungeon is ready
# For now, we'll spawn it immediately after dungeon blob is reassembled
if existing_loot_list.size() > 0:
print("GameWorld: Client - Received ", existing_loot_list.size(), " existing loot items before dungeon spawn")
LogManager.log("GameWorld: Client received " + str(existing_loot_list.size()) + " existing loot items", LogManager.CATEGORY_NETWORK)
# Check if this is a new level (different from current) # Check if this is a new level (different from current)
var is_new_level = (current_level != level) var is_new_level = (current_level != level)
if is_new_level: if is_new_level:
@@ -2921,11 +3034,13 @@ func _sync_dungeon_blob_metadata(seed_value: int, level: int, map_size_sync: Vec
dungeon_sync_in_progress.clear() dungeon_sync_in_progress.clear()
# Reset blob sync state # Reset blob sync state
# Store metadata including state data for later use
dungeon_sync_metadata = { dungeon_sync_metadata = {
"map_size": map_size_sync, "map_size": map_size_sync,
"seed": seed_value, "seed": seed_value,
"level": level, "level": level,
"host_room": host_room "host_room": host_room,
"existing_loot": existing_loot_list # Store for spawning after dungeon is ready
} }
dungeon_sync_chunks.clear() dungeon_sync_chunks.clear()
dungeon_sync_received_chunks = 0 dungeon_sync_received_chunks = 0
@@ -3168,6 +3283,31 @@ func _reassemble_dungeon_blob():
_spawn_room_triggers() _spawn_room_triggers()
print("GameWorld: Client - Room triggers spawned") print("GameWorld: Client - Room triggers spawned")
# Apply door states (from metadata) - after doors are spawned
if pending_door_states.size() > 0:
print("GameWorld: Client - Applying ", pending_door_states.size(), " pending door states...")
var entities_node = get_node_or_null("Entities")
if entities_node:
for child in entities_node.get_children():
if child.is_in_group("blocking_door") or child.has_method("_sync_door_open"):
if pending_door_states.has(child.name):
_apply_pending_door_state(child)
print("GameWorld: Client - Door states applied")
# Spawn existing loot (from metadata) - call the RPC handler directly since we're the client
if dungeon_sync_metadata.has("existing_loot"):
var loot_list = dungeon_sync_metadata.existing_loot
if loot_list.size() > 0:
print("GameWorld: Client - Spawning ", loot_list.size(), " existing loot items from metadata...")
for loot_data in loot_list:
if loot_data.has("item_data"):
# Call the RPC handler directly (it's marked as call_local)
_sync_item_loot_spawn(loot_data.position, loot_data.item_data, loot_data.get("velocity", Vector2.ZERO), loot_data.get("velocity_z", 0.0), loot_data.get("loot_id", -1))
else:
# Call the RPC handler directly (it's marked as call_local)
_sync_loot_spawn(loot_data.position, loot_data.get("loot_type", 0), loot_data.get("velocity", Vector2.ZERO), loot_data.get("velocity_z", 0.0), loot_data.get("loot_id", -1))
print("GameWorld: Client - Existing loot spawned")
# Update spawn points # Update spawn points
print("GameWorld: Client - Updating spawn points...") print("GameWorld: Client - Updating spawn points...")
var host_room = dungeon_sync_metadata.host_room var host_room = dungeon_sync_metadata.host_room