online fix

This commit is contained in:
2025-10-27 14:34:26 +01:00
parent 3c5507dd87
commit cf44edc19a
4 changed files with 80 additions and 4 deletions

View File

@@ -9,6 +9,7 @@ namespace MegaKoop.Game.Networking
private const int EnemyIdRange = 10000; private const int EnemyIdRange = 10000;
private static int nextEnemyId = EnemyIdStart; private static int nextEnemyId = EnemyIdStart;
private static readonly System.Collections.Generic.HashSet<int> ActiveEnemyIds = new();
[RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.BeforeSceneLoad)] [RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.BeforeSceneLoad)]
private static void ResetOnLoad() private static void ResetOnLoad()
@@ -19,6 +20,7 @@ namespace MegaKoop.Game.Networking
public static void Reset() public static void Reset()
{ {
nextEnemyId = EnemyIdStart; nextEnemyId = EnemyIdStart;
ActiveEnemyIds.Clear();
} }
public static int AllocateEnemyId() public static int AllocateEnemyId()
@@ -30,7 +32,7 @@ namespace MegaKoop.Game.Networking
const int maxAttempts = EnemyIdRange; const int maxAttempts = EnemyIdRange;
int attempts = 0; int attempts = 0;
while ((NetworkIdRegistry.IsIdRegistered(nextEnemyId) || NetworkIdRegistry.IsIdReserved(nextEnemyId)) && attempts < maxAttempts) while ((ActiveEnemyIds.Contains(nextEnemyId) || NetworkIdRegistry.IsIdRegistered(nextEnemyId) || NetworkIdRegistry.IsIdReserved(nextEnemyId)) && attempts < maxAttempts)
{ {
AdvanceEnemyCursor(); AdvanceEnemyCursor();
attempts++; attempts++;
@@ -38,6 +40,7 @@ namespace MegaKoop.Game.Networking
int allocated = nextEnemyId; int allocated = nextEnemyId;
AdvanceEnemyCursor(); AdvanceEnemyCursor();
ActiveEnemyIds.Add(allocated);
return allocated; return allocated;
} }
@@ -51,6 +54,18 @@ namespace MegaKoop.Game.Networking
{ {
nextEnemyId = id + 1; nextEnemyId = id + 1;
} }
if (id >= EnemyIdStart)
{
ActiveEnemyIds.Add(id);
}
}
public static void ReleaseEnemyId(int id)
{
if (id >= EnemyIdStart)
{
ActiveEnemyIds.Remove(id);
}
} }
private static void AdvanceEnemyCursor() private static void AdvanceEnemyCursor()

View File

@@ -22,7 +22,15 @@ namespace MegaKoop.Game.Networking
private void OnDestroy() private void OnDestroy()
{ {
if (networkId != 0)
{
if (NetworkIdAllocator.IsEnemyId(networkId))
{
NetworkIdAllocator.ReleaseEnemyId(networkId);
}
NetworkIdRegistry.Unregister(networkId); NetworkIdRegistry.Unregister(networkId);
networkId = 0;
}
} }
private void Register() private void Register()
@@ -32,6 +40,11 @@ namespace MegaKoop.Game.Networking
return; return;
} }
if (NetworkIdAllocator.IsEnemyId(networkId))
{
NetworkIdAllocator.SyncEnemyCursor(networkId);
}
if (!NetworkIdRegistry.TryRegister(this)) if (!NetworkIdRegistry.TryRegister(this))
{ {
Debug.LogError($"[NetworkIdentity] Failed to register {name} with ID {networkId}. " + Debug.LogError($"[NetworkIdentity] Failed to register {name} with ID {networkId}. " +
@@ -68,11 +81,21 @@ namespace MegaKoop.Game.Networking
// Unregister old ID if it was registered // Unregister old ID if it was registered
if (networkId != 0) if (networkId != 0)
{ {
if (NetworkIdAllocator.IsEnemyId(networkId))
{
NetworkIdAllocator.ReleaseEnemyId(networkId);
}
NetworkIdRegistry.Unregister(networkId); NetworkIdRegistry.Unregister(networkId);
} }
networkId = id; networkId = id;
if (NetworkIdAllocator.IsEnemyId(networkId))
{
NetworkIdAllocator.SyncEnemyCursor(networkId);
}
// Register with new ID // Register with new ID
if (!NetworkIdRegistry.TryRegister(this)) if (!NetworkIdRegistry.TryRegister(this))
{ {
@@ -85,5 +108,25 @@ namespace MegaKoop.Game.Networking
/// Gets the current network ID without triggering registration. /// Gets the current network ID without triggering registration.
/// </summary> /// </summary>
public int GetNetworkId() => networkId; public int GetNetworkId() => networkId;
/// <summary>
/// Clears the current network ID and unregisters without emitting duplicate warnings.
/// </summary>
public void ClearNetworkId()
{
if (networkId == 0)
{
return;
}
int id = networkId;
NetworkIdRegistry.Unregister(id);
if (NetworkIdAllocator.IsEnemyId(id))
{
NetworkIdAllocator.ReleaseEnemyId(id);
}
networkId = 0;
}
} }
} }

View File

@@ -279,6 +279,19 @@ namespace MegaKoop.Game.Networking
hasPendingRemoteSpawn = false; hasPendingRemoteSpawn = false;
return; return;
} }
EnemyDefinitionRegistry.Register(definition);
if (pendingRemoteSpawn.NetworkId != 0 && NetworkIdentity.TryGet(pendingRemoteSpawn.NetworkId, out var existingIdentity) && existingIdentity != null)
{
var existingInstance = existingIdentity.gameObject;
if (existingInstance != null)
{
existingInstance.SetActive(true);
existingInstance.transform.SetPositionAndRotation(pendingRemoteSpawn.Position + definition.PrefabPivotOffset, pendingRemoteSpawn.Rotation);
hasPendingRemoteSpawn = false;
}
return;
}
bool success = spawner != null && spawner.TrySpawn(definition, pendingRemoteSpawn.Position); bool success = spawner != null && spawner.TrySpawn(definition, pendingRemoteSpawn.Position);
if (success) if (success)
@@ -348,7 +361,6 @@ namespace MegaKoop.Game.Networking
var identity = instance.GetComponent<NetworkIdentity>(); var identity = instance.GetComponent<NetworkIdentity>();
if (identity != null && pendingRemoteSpawn.NetworkId != 0 && identity.NetworkId != pendingRemoteSpawn.NetworkId) if (identity != null && pendingRemoteSpawn.NetworkId != 0 && identity.NetworkId != pendingRemoteSpawn.NetworkId)
{ {
NetworkIdAllocator.SyncEnemyCursor(pendingRemoteSpawn.NetworkId);
identity.SetNetworkId(pendingRemoteSpawn.NetworkId); identity.SetNetworkId(pendingRemoteSpawn.NetworkId);
} }
} }

View File

@@ -4,6 +4,7 @@ using Game.Scripts.Runtime.Abstractions;
using Game.Scripts.Runtime.Data; using Game.Scripts.Runtime.Data;
using UnityEngine; using UnityEngine;
using Unity.Netcode; using Unity.Netcode;
using MegaKoop.Game.Networking;
namespace Game.Scripts.Runtime.Pooling namespace Game.Scripts.Runtime.Pooling
{ {
@@ -144,6 +145,8 @@ namespace Game.Scripts.Runtime.Pooling
{ {
Destroy(netObj); Destroy(netObj);
} }
var identity = instance.GetComponent<NetworkIdentity>();
identity?.ClearNetworkId();
bucket.Available.Enqueue(instance); bucket.Available.Enqueue(instance);
item.Handle?.NotifyDespawned(); item.Handle?.NotifyDespawned();
InstanceDespawned?.Invoke(instance, item.Definition); InstanceDespawned?.Invoke(instance, item.Definition);
@@ -183,6 +186,9 @@ namespace Game.Scripts.Runtime.Pooling
go.name = $"{definition.Prefab.name}_Pooled"; go.name = $"{definition.Prefab.name}_Pooled";
go.SetActive(false); go.SetActive(false);
var identity = go.GetComponent<NetworkIdentity>();
identity?.ClearNetworkId();
var handle = go.GetComponent<PooledInstance>(); var handle = go.GetComponent<PooledInstance>();
if (handle == null) if (handle == null)
{ {