diff --git a/EXILED/Exiled.API/Features/Npc.cs b/EXILED/Exiled.API/Features/Npc.cs index 52f339dea..82a6c7374 100644 --- a/EXILED/Exiled.API/Features/Npc.cs +++ b/EXILED/Exiled.API/Features/Npc.cs @@ -11,7 +11,9 @@ namespace Exiled.API.Features using System; using System.Collections.Generic; using System.Linq; + using System.Reflection; + using CentralAuth; using CommandSystem; using Exiled.API.Enums; using Exiled.API.Extensions; @@ -140,55 +142,69 @@ public override Vector3 Position /// The userID of the NPC. /// The position to spawn the NPC. /// The spawned. - public static Npc Spawn(string name, RoleTypeId role, int id = 0, string userId = "", Vector3? position = null) + public static Npc Spawn(string name, RoleTypeId role, int id = 0, string userId = PlayerAuthenticationManager.DedicatedId, Vector3? position = null) { - GameObject newObject = Object.Instantiate(NetworkManager.singleton.playerPrefab); + GameObject newObject = UnityEngine.Object.Instantiate(Mirror.NetworkManager.singleton.playerPrefab); + Npc npc = new(newObject) { - IsVerified = true, IsNPC = true, }; - try - { - npc.ReferenceHub.roleManager.InitializeNewRole(RoleTypeId.None, RoleChangeReason.None); - } - catch (Exception e) + + if (!RecyclablePlayerId.FreeIds.Contains(id) && RecyclablePlayerId._autoIncrement >= id) { - Log.Debug($"Ignore: {e}"); + Log.Warn($"{Assembly.GetCallingAssembly().GetName().Name} tried to spawn an NPC with a duplicate PlayerID. Using auto-incremented ID instead to avoid an ID clash."); + id = new RecyclablePlayerId(true).Value; } - if (RecyclablePlayerId.FreeIds.Contains(id)) + try { - RecyclablePlayerId.FreeIds.RemoveFromQueue(id); + if (userId == PlayerAuthenticationManager.DedicatedId) + { + npc.ReferenceHub.authManager.SyncedUserId = userId; + try + { + npc.ReferenceHub.authManager.InstanceMode = ClientInstanceMode.DedicatedServer; + } + catch (Exception e) + { + Log.Debug($"Ignore: {e.Message}"); + } + } + else + { + npc.ReferenceHub.authManager.InstanceMode = ClientInstanceMode.Unverified; + npc.ReferenceHub.authManager._privUserId = userId == string.Empty ? $"Dummy@localhost" : userId; + } } - else if (RecyclablePlayerId._autoIncrement >= id) + catch (Exception e) { - RecyclablePlayerId._autoIncrement = id = RecyclablePlayerId._autoIncrement + 1; + Log.Debug($"Ignore: {e.Message}"); } - FakeConnection fakeConnection = new(id); - NetworkServer.AddPlayerForConnection(fakeConnection, newObject); try { - npc.ReferenceHub.authManager.UserId = string.IsNullOrEmpty(userId) ? $"Dummy@localhost" : userId; + npc.ReferenceHub.roleManager.InitializeNewRole(RoleTypeId.None, RoleChangeReason.None); } catch (Exception e) { - Log.Debug($"Ignore: {e}"); + Log.Debug($"Ignore: {e.Message}"); } + FakeConnection fakeConnection = new(id); + NetworkServer.AddPlayerForConnection(fakeConnection, newObject); + npc.ReferenceHub.nicknameSync.Network_myNickSync = name; Dictionary.Add(newObject, npc); - Timing.CallDelayed( - 0.3f, - () => - { - npc.Role.Set(role, SpawnReason.RoundStart, position is null ? RoleSpawnFlags.All : RoleSpawnFlags.AssignInventory); - }); + Timing.CallDelayed(0.5f, () => + { + npc.Role.Set(role, SpawnReason.RoundStart, position is null ? RoleSpawnFlags.All : RoleSpawnFlags.AssignInventory); + + if (position is not null) + npc.Position = position.Value; + }); - if (position is not null) - Timing.CallDelayed(0.5f, () => npc.Position = position.Value); return npc; }