From 44088b3102d60384f7ada70912041778815c14b8 Mon Sep 17 00:00:00 2001 From: IRacle Date: Wed, 27 Nov 2024 18:56:32 +0300 Subject: [PATCH 01/20] spawning --- EXILED/Exiled.Events/Patches/Events/Player/Spawning.cs | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/EXILED/Exiled.Events/Patches/Events/Player/Spawning.cs b/EXILED/Exiled.Events/Patches/Events/Player/Spawning.cs index e5ea08d1fb..cadd63c585 100644 --- a/EXILED/Exiled.Events/Patches/Events/Player/Spawning.cs +++ b/EXILED/Exiled.Events/Patches/Events/Player/Spawning.cs @@ -27,14 +27,9 @@ namespace Exiled.Events.Patches.Events.Player /// Adds the event. /// Fix for spawning in void. /// - [HarmonyPatch] + [HarmonyPatch(typeof(RoleSpawnpointManager), nameof(RoleSpawnpointManager.SetPosition))] internal static class Spawning { - private static MethodInfo TargetMethod() - { - return Method(TypeByName("PlayerRoles.FirstPersonControl.Spawnpoints.RoleSpawnpointManager").GetNestedTypes(all)[1], "b__2_0"); - } - private static bool Prefix(ReferenceHub hub, PlayerRoleBase prevRole, PlayerRoleBase newRole) { if (newRole.ServerSpawnReason == RoleChangeReason.Destroyed || !Player.TryGet(hub, out Player player)) From ac456282329359f1d7fab8c6522ded8bc94cfeba Mon Sep 17 00:00:00 2001 From: IRacle Date: Wed, 27 Nov 2024 18:56:36 +0300 Subject: [PATCH 02/20] shooting --- .../Patches/Events/Player/Shooting.cs | 33 ++++++------------- 1 file changed, 10 insertions(+), 23 deletions(-) diff --git a/EXILED/Exiled.Events/Patches/Events/Player/Shooting.cs b/EXILED/Exiled.Events/Patches/Events/Player/Shooting.cs index 3c779e7043..fc1265b8e1 100644 --- a/EXILED/Exiled.Events/Patches/Events/Player/Shooting.cs +++ b/EXILED/Exiled.Events/Patches/Events/Player/Shooting.cs @@ -18,8 +18,10 @@ namespace Exiled.Events.Patches.Events.Player using HarmonyLib; + using InventorySystem.Items.Firearms; using InventorySystem.Items.Firearms.BasicMessages; using InventorySystem.Items.Firearms.Modules; + using InventorySystem.Items.Firearms.Modules.Misc; using static HarmonyLib.AccessTools; @@ -29,41 +31,33 @@ namespace Exiled.Events.Patches.Events.Player /// [EventPatch(typeof(Handlers.Player), nameof(Handlers.Player.Shooting))] - // [HarmonyPatch(typeof(FirearmBasicMessagesHandler), nameof(FirearmBasicMessagesHandler.ServerShotReceived))] + [HarmonyPatch(typeof(ShotBacktrackData), nameof(ShotBacktrackData.ProcessShot))] internal static class Shooting { - /* private static IEnumerable Transpiler(IEnumerable instructions, ILGenerator generator) { List newInstructions = ListPool.Pool.Get(instructions); - Label isAllowedLabel = generator.DefineLabel(); Label returnLabel = generator.DefineLabel(); - LocalBuilder ev = generator.DeclareLocal(typeof(ShootingEventArgs)); - - int offset = -2; - int index = newInstructions.FindIndex(instruction => instruction.Calls(Method(typeof(IActionModule), nameof(IActionModule.ServerAuthorizeShot)))) + offset; + int offset = 1; + int index = newInstructions.FindIndex(instruction => instruction.opcode == OpCodes.Stloc_2) + offset; newInstructions.InsertRange( index, new[] { - // Player.Get(referenceHub) - new CodeInstruction(OpCodes.Ldloc_0).MoveLabelsFrom(newInstructions[index]), + // Player.Get(firearm.Owner) + new(OpCodes.Ldarg_1), + new(OpCodes.Callvirt, PropertyGetter(typeof(Firearm), nameof(Firearm.Owner))), new(OpCodes.Call, Method(typeof(Player), nameof(Player.Get), new[] { typeof(ReferenceHub) })), // firearm - new(OpCodes.Ldloc_1), - - // msg - new(OpCodes.Ldarg_1), + new CodeInstruction(OpCodes.Ldarg_1).MoveLabelsFrom(newInstructions[index]), - // ShootingEventArgs ev = new(Player, firearm, ShotMessage) + // ShootingEventArgs ev = new(Player, firearm) new(OpCodes.Newobj, GetDeclaredConstructors(typeof(ShootingEventArgs))[0]), new(OpCodes.Dup), - new(OpCodes.Dup), - new(OpCodes.Stloc, ev.LocalIndex), // Handlers.Player.OnShooting(ev) new(OpCodes.Call, Method(typeof(Handlers.Player), nameof(Handlers.Player.OnShooting))), @@ -72,12 +66,6 @@ private static IEnumerable Transpiler(IEnumerable Transpiler(IEnumerable.Pool.Return(newInstructions); } - */ } } \ No newline at end of file From 7224ce753a963f58a94b948058e9ed17b6893062 Mon Sep 17 00:00:00 2001 From: IRacle Date: Wed, 27 Nov 2024 20:47:05 +0300 Subject: [PATCH 03/20] respawning roundend --- .../Server/RespawningTeamEventArgs.cs | 25 ++++++------ .../Patches/Events/Server/RespawningTeam.cs | 40 +++++++++---------- .../Patches/Events/Server/RoundEnd.cs | 17 ++------ 3 files changed, 33 insertions(+), 49 deletions(-) diff --git a/EXILED/Exiled.Events/EventArgs/Server/RespawningTeamEventArgs.cs b/EXILED/Exiled.Events/EventArgs/Server/RespawningTeamEventArgs.cs index f475591a6f..963d06351f 100644 --- a/EXILED/Exiled.Events/EventArgs/Server/RespawningTeamEventArgs.cs +++ b/EXILED/Exiled.Events/EventArgs/Server/RespawningTeamEventArgs.cs @@ -29,25 +29,19 @@ public class RespawningTeamEventArgs : IDeniableEvent /// /// /// - /// - /// - /// /// /// /// - /// + /// /// /// - /// - /// - /// - public RespawningTeamEventArgs(List players, Queue queue, int maxRespawn, SpawnableWaveBase nextKnownTeam, bool isAllowed = true) + public RespawningTeamEventArgs(List players, int maxRespawn, SpawnableWaveBase wave) { Players = players; MaximumRespawnAmount = maxRespawn; - SpawnQueue = queue; - NextKnownTeam = nextKnownTeam; - IsAllowed = isAllowed; + SpawnQueue = WaveSpawner.SpawnQueue; + Wave = wave; + IsAllowed = true; } /// @@ -74,9 +68,14 @@ public int MaximumRespawnAmount } /// - /// Gets or sets a value indicating what the next respawnable team is. + /// Gets or sets a value indicating what the next wave is. + /// + public SpawnableWaveBase Wave { get; set; } + + /// + /// Gets a value indicating what the next respawnable team is. /// - public SpawnableWaveBase NextKnownTeam { get; set; } + public SpawnableTeamType NextKnownTeam => Wave.TargetFaction.GetSpawnableTeam(); /// /// Gets or sets a value indicating whether the spawn can occur. diff --git a/EXILED/Exiled.Events/Patches/Events/Server/RespawningTeam.cs b/EXILED/Exiled.Events/Patches/Events/Server/RespawningTeam.cs index ea2f3546ff..50baf6384e 100644 --- a/EXILED/Exiled.Events/Patches/Events/Server/RespawningTeam.cs +++ b/EXILED/Exiled.Events/Patches/Events/Server/RespawningTeam.cs @@ -7,12 +7,15 @@ namespace Exiled.Events.Patches.Events.Server { + using System; using System.Collections.Generic; using System.Linq; using System.Reflection; using System.Reflection.Emit; using API.Features.Pools; + + using Exiled.API.Extensions; using Exiled.Events.Attributes; using Exiled.Events.EventArgs.Server; using Exiled.Events.Handlers; @@ -50,23 +53,20 @@ private static IEnumerable Transpiler(IEnumerable Transpiler(IEnumerable), nameof(Queue.Clear))), + new(OpCodes.Newobj, Constructor(typeof(List), new Type[0])), new(OpCodes.Ret), // load "ev" four times new CodeInstruction(OpCodes.Ldloc_S, ev.LocalIndex).WithLabels(continueLabel), new(OpCodes.Dup), new(OpCodes.Dup), - new(OpCodes.Dup), // num = ev.MaximumRespawnAmount new(OpCodes.Callvirt, PropertyGetter(typeof(RespawningTeamEventArgs), nameof(RespawningTeamEventArgs.MaximumRespawnAmount))), - new(OpCodes.Stloc_S, 4), + new(OpCodes.Stloc_3), // list = GetHubs(ev.Players) new(OpCodes.Callvirt, PropertyGetter(typeof(RespawningTeamEventArgs), nameof(RespawningTeamEventArgs.Players))), new(OpCodes.Call, Method(typeof(RespawningTeam), nameof(GetHubs))), - new(OpCodes.Stloc_1), - - // queueToFill = ev.SpawnQueue; - new CodeInstruction(OpCodes.Callvirt, PropertyGetter(typeof(RespawningTeamEventArgs), nameof(RespawningTeamEventArgs.SpawnQueue))), - new(OpCodes.Call, Method(typeof(RespawningTeam), nameof(RefillQueue))), + new(OpCodes.Stloc_S, 2), - // wave = ev.NextKnownTeam; - new(OpCodes.Callvirt, PropertyGetter(typeof(RespawningTeamEventArgs), nameof(RespawningTeamEventArgs.NextKnownTeam))), - new(OpCodes.Starg_S, 1), + // wave = ev.Wave; + new(OpCodes.Callvirt, PropertyGetter(typeof(RespawningTeamEventArgs), nameof(RespawningTeamEventArgs.Wave))), + new(OpCodes.Starg_S, 0), }); for (int z = 0; z < newInstructions.Count; z++) diff --git a/EXILED/Exiled.Events/Patches/Events/Server/RoundEnd.cs b/EXILED/Exiled.Events/Patches/Events/Server/RoundEnd.cs index e9295a33c7..2fdeef44c8 100644 --- a/EXILED/Exiled.Events/Patches/Events/Server/RoundEnd.cs +++ b/EXILED/Exiled.Events/Patches/Events/Server/RoundEnd.cs @@ -12,6 +12,7 @@ namespace Exiled.Events.Patches.Events.Server using System.Reflection; using System.Reflection.Emit; + using Exiled.API.Extensions; using Exiled.API.Features; using Exiled.API.Features.Pools; using Exiled.Events.EventArgs.Server; @@ -35,7 +36,7 @@ internal static class RoundEnd private static MethodInfo TargetMethod() { - PrivateType = typeof(RoundSummary).GetNestedTypes(all)[5]; + PrivateType = typeof(RoundSummary).GetNestedTypes(all)[6]; return Method(PrivateType, "MoveNext"); } @@ -58,7 +59,7 @@ private static IEnumerable Transpiler(IEnumerable), nameof(HashSet.Contains))), new(OpCodes.Brtrue_S, jmp), }); @@ -68,19 +69,7 @@ private static IEnumerable Transpiler(IEnumerable x.Calls(PropertyGetter(typeof(RoundSummary), nameof(RoundSummary.Network_extraTargets)))) + offset; - Label label = (Label)newInstructions[index].operand; - newInstructions.RemoveAt(index); - newInstructions.InsertRange( - index, - new CodeInstruction[] - { - new(OpCodes.Ldc_I4_0), - new(OpCodes.Bgt_S, label), - }); offset = -1; index = newInstructions.FindIndex(x => x.opcode == OpCodes.Ldfld && x.operand == (object)Field(typeof(RoundSummary), nameof(RoundSummary._roundEnded))) + offset; From 2ff51ea678b0541566e2da01018d15510a361717 Mon Sep 17 00:00:00 2001 From: IRacle Date: Wed, 27 Nov 2024 21:58:10 +0300 Subject: [PATCH 04/20] 914 --- .../Patches/Events/Scp914/UpgradingPlayer.cs | 46 ++++++++----------- 1 file changed, 20 insertions(+), 26 deletions(-) diff --git a/EXILED/Exiled.Events/Patches/Events/Scp914/UpgradingPlayer.cs b/EXILED/Exiled.Events/Patches/Events/Scp914/UpgradingPlayer.cs index 385a98155a..194c148ea8 100644 --- a/EXILED/Exiled.Events/Patches/Events/Scp914/UpgradingPlayer.cs +++ b/EXILED/Exiled.Events/Patches/Events/Scp914/UpgradingPlayer.cs @@ -36,27 +36,21 @@ private static IEnumerable Transpiler(IEnumerable newInstructions = ListPool.Pool.Get(instructions); - // Find override position - const int offset = -3; - int index = newInstructions.FindIndex(instruction => instruction.Calls(Method(typeof(FpcExtensionMethods), nameof(FpcExtensionMethods.TryOverridePosition)))) + offset; - Label returnLabel = generator.DefineLabel(); LocalBuilder curSetting = generator.DeclareLocal(typeof(Scp914KnobSetting)); LocalBuilder ev = generator.DeclareLocal(typeof(UpgradingPlayerEventArgs)); - // Move labels from override - 3 position (Right after a branch) - List [EventPatch(typeof(Handlers.Scp106), nameof(Handlers.Scp106.ExitStalking))] - [HarmonyPatch(typeof(Scp106StalkAbility), nameof(Scp106StalkAbility.ServerSetStalk), MethodType.Setter)] + [HarmonyPatch(typeof(Scp106StalkAbility), nameof(Scp106StalkAbility.ServerSetStalk))] public class ExitStalking { private static IEnumerable Transpiler(IEnumerable instructions, ILGenerator generator) From 65adb122dd9225a5f4ac9f760f8328e2899d1ea7 Mon Sep 17 00:00:00 2001 From: IRacle Date: Wed, 27 Nov 2024 23:21:55 +0300 Subject: [PATCH 14/20] lol --- .../Patches/Generic/PocketDimensionTeleportList.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/EXILED/Exiled.Events/Patches/Generic/PocketDimensionTeleportList.cs b/EXILED/Exiled.Events/Patches/Generic/PocketDimensionTeleportList.cs index f537907649..91a54a9c4f 100644 --- a/EXILED/Exiled.Events/Patches/Generic/PocketDimensionTeleportList.cs +++ b/EXILED/Exiled.Events/Patches/Generic/PocketDimensionTeleportList.cs @@ -20,7 +20,7 @@ internal class PocketDimensionTeleportList { [HarmonyPatch(typeof(PocketDimensionTeleport), nameof(PocketDimensionTeleport.Awake))] [HarmonyPostfix] - private static void Adding(PocketDimensionTeleport __instance) => _ = Map.TeleportsValue.AddItem(__instance); + private static void Adding(PocketDimensionTeleport __instance) => Map.TeleportsValue.Add(__instance); [HarmonyPatch(typeof(PocketDimensionTeleport), nameof(PocketDimensionTeleport.OnDestroy))] [HarmonyPostfix] From cbe215549030ac857848b5b024c6a59de4f6fd42 Mon Sep 17 00:00:00 2001 From: Misaka-ZeroTwo <45165615+Misaka-ZeroTwo@users.noreply.github.com> Date: Thu, 28 Nov 2024 02:34:18 -0500 Subject: [PATCH 15/20] Update RoundEnd.cs --- EXILED/Exiled.Events/Patches/Events/Server/RoundEnd.cs | 2 -- 1 file changed, 2 deletions(-) diff --git a/EXILED/Exiled.Events/Patches/Events/Server/RoundEnd.cs b/EXILED/Exiled.Events/Patches/Events/Server/RoundEnd.cs index 2fdeef44c8..9412f3fb92 100644 --- a/EXILED/Exiled.Events/Patches/Events/Server/RoundEnd.cs +++ b/EXILED/Exiled.Events/Patches/Events/Server/RoundEnd.cs @@ -69,8 +69,6 @@ private static IEnumerable Transpiler(IEnumerable x.opcode == OpCodes.Ldfld && x.operand == (object)Field(typeof(RoundSummary), nameof(RoundSummary._roundEnded))) + offset; From 725e2902af52a7da79bcaa095b0bbb68ebebfafb Mon Sep 17 00:00:00 2001 From: IRacle Date: Thu, 28 Nov 2024 17:36:33 +0300 Subject: [PATCH 16/20] xd --- EXILED/Exiled.Events/Patches/Events/Scp914/UpgradingPlayer.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/EXILED/Exiled.Events/Patches/Events/Scp914/UpgradingPlayer.cs b/EXILED/Exiled.Events/Patches/Events/Scp914/UpgradingPlayer.cs index 194c148ea8..899a09f2bf 100644 --- a/EXILED/Exiled.Events/Patches/Events/Scp914/UpgradingPlayer.cs +++ b/EXILED/Exiled.Events/Patches/Events/Scp914/UpgradingPlayer.cs @@ -132,7 +132,7 @@ private static IEnumerable Transpiler(IEnumerable Date: Thu, 28 Nov 2024 18:13:14 +0300 Subject: [PATCH 17/20] =?UTF-8?q?=F0=9F=A5=B9=F0=9F=A5=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- EXILED/Exiled.API/Features/Window.cs | 4 +- .../EventArgs/Player/SpawningEventArgs.cs | 22 ++++- .../Handlers/Internal/MapGenerated.cs | 47 +--------- .../Exiled.Events/Handlers/Internal/Round.cs | 49 +++++++++++ .../Events/Player/ChangingRoleAndSpawned.cs | 87 ++++++++++--------- .../Patches/Events/Player/Joined.cs | 6 +- .../Patches/Events/Player/Spawning.cs | 80 +++++++++++------ .../Events/Server/WaitingForPlayers.cs | 31 +++++++ 8 files changed, 204 insertions(+), 122 deletions(-) create mode 100644 Exiled/Exiled.Events/Patches/Events/Server/WaitingForPlayers.cs diff --git a/EXILED/Exiled.API/Features/Window.cs b/EXILED/Exiled.API/Features/Window.cs index 79a7f5acf9..f0765b732c 100644 --- a/EXILED/Exiled.API/Features/Window.cs +++ b/EXILED/Exiled.API/Features/Window.cs @@ -220,7 +220,9 @@ public void DamageWindow(float amount, DamageHandlerBase handler) RoomType.LczGlassBox => GlassType.GR18, RoomType.LczPlants => GlassType.Plants, RoomType.Hcz049 => GlassType.Scp049, - RoomType.Hcz079 => Recontainer.Base._activatorGlass == Base ? GlassType.Scp079Trigger : GlassType.Scp079, + + // TODO: Recontainer.Base._activatorGlass == Base ? GlassType.Scp079Trigger : GlassType.Scp079 + RoomType.Hcz079 => GlassType.Scp079, RoomType.HczHid => GlassType.MicroHid, RoomType.HczTestRoom => GlassType.TestRoom, RoomType.HczEzCheckpointA => GlassType.HczEzCheckpointA, diff --git a/EXILED/Exiled.Events/EventArgs/Player/SpawningEventArgs.cs b/EXILED/Exiled.Events/EventArgs/Player/SpawningEventArgs.cs index 43bcfefd59..bc543dc586 100644 --- a/EXILED/Exiled.Events/EventArgs/Player/SpawningEventArgs.cs +++ b/EXILED/Exiled.Events/EventArgs/Player/SpawningEventArgs.cs @@ -7,11 +7,12 @@ namespace Exiled.Events.EventArgs.Player { + using System; + using Exiled.API.Features; using Exiled.API.Features.Roles; using Exiled.Events.EventArgs.Interfaces; using PlayerRoles; - using UnityEngine; /// @@ -31,11 +32,15 @@ public class SpawningEventArgs : IPlayerEvent /// /// /// - public SpawningEventArgs(Player player, Vector3 position, float rotation) + /// + /// the spawned player's new role. + /// + public SpawningEventArgs(Player player, Vector3 position, float rotation, PlayerRoleBase newRole) { Player = player; Position = position; HorizontalRotation = rotation; + NewRole = Role.Create(newRole); } /// @@ -58,5 +63,16 @@ public SpawningEventArgs(Player player, Vector3 position, float rotation) /// Rotation will apply only for . /// public float HorizontalRotation { get; set; } + + /// + /// Gets the player's old role. + /// + [Obsolete("Removed because the method is no longer provide OldRole since version 14.0. Use Player.Role instead")] + public Role OldRole { get; } + + /// + /// Gets the player's new role. + /// + public Role NewRole { get; } } -} \ No newline at end of file +} diff --git a/EXILED/Exiled.Events/Handlers/Internal/MapGenerated.cs b/EXILED/Exiled.Events/Handlers/Internal/MapGenerated.cs index ef323edb7d..6c71d3a83e 100644 --- a/EXILED/Exiled.Events/Handlers/Internal/MapGenerated.cs +++ b/EXILED/Exiled.Events/Handlers/Internal/MapGenerated.cs @@ -54,52 +54,7 @@ public static void OnMapGenerated() PlayerRoles.RoleAssign.HumanSpawner.Handlers[PlayerRoles.Team.OtherAlive] = new PlayerRoles.RoleAssign.OneRoleHumanSpawner(PlayerRoles.RoleTypeId.Tutorial); PlayerRoles.RoleAssign.HumanSpawner.Handlers[PlayerRoles.Team.Dead] = new PlayerRoles.RoleAssign.OneRoleHumanSpawner(PlayerRoles.RoleTypeId.Spectator); - GenerateAttachments(); - Timing.CallDelayed(1, GenerateCache); - } - - private static void GenerateCache() - { - Handlers.Map.OnGenerated(); - - Timing.CallDelayed(0.1f, Handlers.Server.OnWaitingForPlayers); - } - - private static void GenerateAttachments() - { - foreach (FirearmType firearmType in EnumUtils.Values) - { - if (firearmType == FirearmType.None) - continue; - - if (Item.Create(firearmType.GetItemType()) is not Firearm firearm) - continue; - - Firearm.ItemTypeToFirearmInstance.Add(firearmType, firearm); - - List attachmentIdentifiers = ListPool.Pool.Get(); - HashSet attachmentsSlots = HashSetPool.Pool.Get(); - - uint code = 1; - - foreach (Attachment attachment in firearm.Attachments) - { - attachmentsSlots.Add(attachment.Slot); - attachmentIdentifiers.Add(new(code, attachment.Name, attachment.Slot)); - code *= 2U; - } - - uint baseCode = 0; - attachmentsSlots.ForEach(slot => baseCode += attachmentIdentifiers - .Where(attachment => attachment.Slot == slot) - .Min(slot => slot.Code)); - - Firearm.BaseCodesValue.Add(firearmType, baseCode); - Firearm.AvailableAttachmentsValue.Add(firearmType, attachmentIdentifiers.ToArray()); - - ListPool.Pool.Return(attachmentIdentifiers); - HashSetPool.Pool.Return(attachmentsSlots); - } + Timing.CallDelayed(1, Handlers.Map.OnGenerated); } } } \ No newline at end of file diff --git a/EXILED/Exiled.Events/Handlers/Internal/Round.cs b/EXILED/Exiled.Events/Handlers/Internal/Round.cs index 5c9ff4c5fa..01aebaf3e3 100644 --- a/EXILED/Exiled.Events/Handlers/Internal/Round.cs +++ b/EXILED/Exiled.Events/Handlers/Internal/Round.cs @@ -7,21 +7,29 @@ namespace Exiled.Events.Handlers.Internal { + using System.Collections.Generic; using System.Linq; using CentralAuth; using Exiled.API.Extensions; using Exiled.API.Features; + using Exiled.API.Features.Items; + using Exiled.API.Features.Pools; using Exiled.API.Features.Roles; + using Exiled.API.Structs; using Exiled.Events.EventArgs.Player; using Exiled.Events.EventArgs.Scp049; using Exiled.Loader; using Exiled.Loader.Features; using InventorySystem; + using InventorySystem.Items.Firearms.Attachments; + using InventorySystem.Items.Firearms.Attachments.Components; using InventorySystem.Items.Usables; using PlayerRoles; using PlayerRoles.RoleAssign; + using Utils.NonAllocLINQ; + /// /// Handles some round clean-up events and some others related to players. /// @@ -33,6 +41,7 @@ internal static class Round /// public static void OnWaitingForPlayers() { + GenerateAttachments(); MultiAdminFeatures.CallEvent(MultiAdminFeatures.EventType.WAITING_FOR_PLAYERS); if (Events.Instance.Config.ShouldReloadConfigsAtRoundRestart) @@ -93,5 +102,45 @@ public static void OnVerified(VerifiedEventArgs ev) ev.Player.SendFakeSyncVar(room.RoomLightControllerNetIdentity, typeof(RoomLightController), nameof(RoomLightController.NetworkLightsEnabled), false); } } + + private static void GenerateAttachments() + { + foreach (FirearmType firearmType in EnumUtils.Values) + { + if (firearmType == FirearmType.None) + continue; + + Log.Warn(firearmType.GetItemType()); + Log.Warn(Server.Host == null); + + if (Item.Create(firearmType.GetItemType()) is not Firearm firearm) + continue; + + Firearm.ItemTypeToFirearmInstance.Add(firearmType, firearm); + + List attachmentIdentifiers = ListPool.Pool.Get(); + HashSet attachmentsSlots = HashSetPool.Pool.Get(); + + uint code = 1; + + foreach (Attachment attachment in firearm.Attachments) + { + attachmentsSlots.Add(attachment.Slot); + attachmentIdentifiers.Add(new(code, attachment.Name, attachment.Slot)); + code *= 2U; + } + + uint baseCode = 0; + attachmentsSlots.ForEach(slot => baseCode += attachmentIdentifiers + .Where(attachment => attachment.Slot == slot) + .Min(slot => slot.Code)); + + Firearm.BaseCodesValue.Add(firearmType, baseCode); + Firearm.AvailableAttachmentsValue.Add(firearmType, attachmentIdentifiers.ToArray()); + + ListPool.Pool.Return(attachmentIdentifiers); + HashSetPool.Pool.Return(attachmentsSlots); + } + } } } diff --git a/EXILED/Exiled.Events/Patches/Events/Player/ChangingRoleAndSpawned.cs b/EXILED/Exiled.Events/Patches/Events/Player/ChangingRoleAndSpawned.cs index 37cbdc9e7a..5e7b1d0d18 100644 --- a/EXILED/Exiled.Events/Patches/Events/Player/ChangingRoleAndSpawned.cs +++ b/EXILED/Exiled.Events/Patches/Events/Player/ChangingRoleAndSpawned.cs @@ -18,12 +18,17 @@ namespace Exiled.Events.Patches.Events.Player using Exiled.Events.EventArgs.Player; using HarmonyLib; using InventorySystem; + using InventorySystem.Configs; using InventorySystem.Items; using InventorySystem.Items.Armor; using InventorySystem.Items.Pickups; + using InventorySystem.Items.Usables.Scp1344; + using Mirror; + using PlayerRoles; using static HarmonyLib.AccessTools; + using static UnityEngine.GraphicsBuffer; using Player = Handlers.Player; @@ -146,18 +151,8 @@ private static IEnumerable Transpiler(IEnumerable list = new(); + List list = new List(); if (inventory.TryGetBodyArmor(out BodyArmor bodyArmor)) + { bodyArmor.DontRemoveExcessOnDrop = true; + } - while (inventory.UserInventory.Items.Count > 0) + HashSet hashSet = HashSetPool.Pool.Get(); + foreach (KeyValuePair item2 in inventory.UserInventory.Items) { - int startCount = inventory.UserInventory.Items.Count; - ushort key = inventory.UserInventory.Items.ElementAt(0).Key; - ItemPickupBase item = inventory.ServerDropItem(key); - - // If the list wasn't changed, we need to manually remove the item to avoid a softlock. - if (startCount == inventory.UserInventory.Items.Count) - inventory.UserInventory.Items.Remove(key); + if (item2.Value is Scp1344Item scp1344Item) + { + scp1344Item.Status = Scp1344Status.Idle; + } else - list.Add(item); + { + hashSet.Add(item2.Key); + } } + foreach (ushort item3 in hashSet) + { + list.Add(inventory.ServerDropItem(item3)); + } + + HashSetPool.Pool.Return(hashSet); InventoryItemProvider.PreviousInventoryPickups[ev.Player.ReferenceHub] = list; } - else + + if (!flag) { while (inventory.UserInventory.Items.Count > 0) { - int startCount = inventory.UserInventory.Items.Count; - ushort key = inventory.UserInventory.Items.ElementAt(0).Key; - inventory.ServerRemoveItem(key, null); - - // If the list wasn't changed, we need to manually remove the item to avoid a softlock. - if (startCount == inventory.UserInventory.Items.Count) - inventory.UserInventory.Items.Remove(key); + inventory.ServerRemoveItem(inventory.UserInventory.Items.ElementAt(0).Key, null); } inventory.UserInventory.ReserveAmmo.Clear(); inventory.SendAmmoNextFrame = true; } - foreach (ItemType item in ev.Items) - inventory.ServerAddItem(item, ItemAddReason.StartingItem); + if (!StartingInventories.DefinedInventories.TryGetValue(ev.NewRole, out InventoryRoleInfo value)) + { + return; + } - foreach (KeyValuePair keyValuePair in ev.Ammo) - inventory.ServerAddAmmo(keyValuePair.Key, keyValuePair.Value); + foreach (KeyValuePair item in value.Ammo) + { + inventory.ServerAddAmmo(item.Key, item.Value); + } - foreach (KeyValuePair item in inventory.UserInventory.Items) - InventoryItemProvider.OnItemProvided?.Invoke(ev.Player.ReferenceHub, item.Value); + for (int i = 0; i < value.Items.Length; i++) + { + ItemBase arg = inventory.ServerAddItem(value.Items[i], ItemAddReason.StartingItem, 0); + InventoryItemProvider.OnItemProvided?.Invoke(ev.Player.ReferenceHub, arg); + } - InventoryItemProvider.SpawnPreviousInventoryPickups(ev.Player.ReferenceHub); + InventoryItemProvider.InventoriesToReplenish.Enqueue(ev.Player.ReferenceHub); } catch (Exception exception) { @@ -251,4 +258,4 @@ private static void ChangeInventory(ChangingRoleEventArgs ev) } } } -} \ No newline at end of file +} diff --git a/EXILED/Exiled.Events/Patches/Events/Player/Joined.cs b/EXILED/Exiled.Events/Patches/Events/Player/Joined.cs index 75fc346a87..18421e5044 100644 --- a/EXILED/Exiled.Events/Patches/Events/Player/Joined.cs +++ b/EXILED/Exiled.Events/Patches/Events/Player/Joined.cs @@ -39,11 +39,7 @@ internal static void CallEvent(ReferenceHub hub, out Player player) #endif Player.UnverifiedPlayers.Add(hub.gameObject, player); - if (ReferenceHub._hostHub == null) - { - Server.Host = player; - } - else + if (ReferenceHub._hostHub != null) { Handlers.Player.OnJoined(new JoinedEventArgs(player)); } diff --git a/EXILED/Exiled.Events/Patches/Events/Player/Spawning.cs b/EXILED/Exiled.Events/Patches/Events/Player/Spawning.cs index d3a1cb7b00..af8b3a6c20 100644 --- a/EXILED/Exiled.Events/Patches/Events/Player/Spawning.cs +++ b/EXILED/Exiled.Events/Patches/Events/Player/Spawning.cs @@ -7,17 +7,17 @@ namespace Exiled.Events.Patches.Events.Player { + using System.Collections.Generic; using System.Reflection; + using System.Reflection.Emit; - using API.Features; + using Exiled.API.Features; + using Exiled.API.Features.Pools; + using Exiled.Events.Attributes; using Exiled.Events.EventArgs.Player; - using HarmonyLib; - using PlayerRoles; - using PlayerRoles.FirstPersonControl; using PlayerRoles.FirstPersonControl.Spawnpoints; - using UnityEngine; using static HarmonyLib.AccessTools; @@ -27,38 +27,64 @@ namespace Exiled.Events.Patches.Events.Player /// Adds the event. /// Fix for spawning in void. /// + [EventPatch(typeof(Handlers.Player), nameof(Handlers.Player.Spawning))] [HarmonyPatch(typeof(RoleSpawnpointManager), nameof(RoleSpawnpointManager.SetPosition))] internal static class Spawning { - private static bool Prefix(ReferenceHub hub, PlayerRoleBase newRole) + private static IEnumerable Transpiler(IEnumerable instructions, ILGenerator generator) { - if (newRole.ServerSpawnReason == RoleChangeReason.Destroyed || !Player.TryGet(hub, out Player player)) - return true; + List newInstructions = ListPool.Pool.Get(instructions); + + int offset = -1; - Vector3 oldPosition = hub.transform.position; - float oldRotation = 0; + // Locate the call to `Transform.position` setter to determine where to insert new instructions. + int index = newInstructions.FindIndex(instr => instr.Calls(PropertySetter(typeof(Transform), nameof(Transform.position)))) + offset; - if (newRole is IFpcRole fpcRole) + // Declare the `SpawningEventArgs` local variable. + LocalBuilder ev = generator.DeclareLocal(typeof(SpawningEventArgs)); + + newInstructions.InsertRange( + index, + new[] { - if (newRole.ServerSpawnFlags.HasFlag(RoleSpawnFlags.UseSpawnpoint) && fpcRole.SpawnpointHandler != null && fpcRole.SpawnpointHandler.TryGetSpawnpoint(out Vector3 position, out float horizontalRot)) - { - oldPosition = position; - oldRotation = horizontalRot; - } + // Load `ReferenceHub` (argument 0) and get `Player`. + new CodeInstruction(OpCodes.Ldarg_0), // Load `hub` (first argument passed to the method). + new CodeInstruction(OpCodes.Call, Method(typeof(Player), nameof(Player.Get), new[] { typeof(ReferenceHub) })), // Call Player.Get(hub) to get the Player instance. - SpawningEventArgs ev = new(player, oldPosition, oldRotation); + // Load `position` (local variable 2). + new CodeInstruction(OpCodes.Ldloc_2), - Handlers.Player.OnSpawning(ev); + // Load `rotation` (local variable 3). + new CodeInstruction(OpCodes.Ldloc_3), - player.Position = ev.Position; - fpcRole.FpcModule.MouseLook.CurrentHorizontal = ev.HorizontalRotation; - } - else - { - Handlers.Player.OnSpawning(new(player, oldPosition, oldRotation)); - } + // Load `newRole` (argument 1). + new CodeInstruction(OpCodes.Ldarg_1), // Load `newRole` from argument 1. + + // Create a new instance of `SpawningEventArgs`. + new CodeInstruction(OpCodes.Newobj, GetDeclaredConstructors(typeof(SpawningEventArgs))[0]), + + // Duplicate the object to store it and pass it around. + new CodeInstruction(OpCodes.Dup), // Duplicate the `SpawningEventArgs` object. + new CodeInstruction(OpCodes.Stloc, ev.LocalIndex), // Store the duplicated object in a local variable. + + // Call `Handlers.Player.OnSpawning`. + new CodeInstruction(OpCodes.Call, Method(typeof(Handlers.Player), nameof(Handlers.Player.OnSpawning))), + + // Modify `position` from `ev.Position`. + new CodeInstruction(OpCodes.Ldloc, ev.LocalIndex), // Load the `SpawningEventArgs` object stored in the local variable. + new CodeInstruction(OpCodes.Call, PropertyGetter(typeof(SpawningEventArgs), nameof(SpawningEventArgs.Position))), // Get the `Position` property from `SpawningEventArgs`. + new CodeInstruction(OpCodes.Stloc_2), // Store the position value back in the local variable 2 (`position`). + + // Modify `rotation` from `ev.HorizontalRotation`. + new CodeInstruction(OpCodes.Ldloc, ev.LocalIndex), // Load the `SpawningEventArgs` object again. + new CodeInstruction(OpCodes.Call, PropertyGetter(typeof(SpawningEventArgs), nameof(SpawningEventArgs.HorizontalRotation))), // Get the `HorizontalRotation` property from `SpawningEventArgs`. + new CodeInstruction(OpCodes.Stloc_3), // Store the rotation value back in the local variable 3 (`rotation`). + }); + + for (int z = 0; z < newInstructions.Count; z++) + yield return newInstructions[z]; - return false; + ListPool.Pool.Return(newInstructions); } } -} \ No newline at end of file +} diff --git a/Exiled/Exiled.Events/Patches/Events/Server/WaitingForPlayers.cs b/Exiled/Exiled.Events/Patches/Events/Server/WaitingForPlayers.cs new file mode 100644 index 0000000000..ec2d14a980 --- /dev/null +++ b/Exiled/Exiled.Events/Patches/Events/Server/WaitingForPlayers.cs @@ -0,0 +1,31 @@ +// ----------------------------------------------------------------------- +// +// Copyright (c) ExMod Team. All rights reserved. +// Licensed under the CC BY-SA 3.0 license. +// +// ----------------------------------------------------------------------- + +namespace Exiled.Events.Patches.Events.Server +{ +#pragma warning disable SA1313 // Parameter names should begin with lower-case letter + + using API.Features; + using HarmonyLib; + + /// + /// Patches . + /// Adds the event. + /// + [HarmonyPatch(typeof(ReferenceHub), nameof(ReferenceHub.Start))] + internal static class WaitingForPlayers + { + private static void Postfix(ReferenceHub __instance) + { + if (!__instance.isLocalPlayer) + return; + + Server.Host = new Player(__instance); + Handlers.Server.OnWaitingForPlayers(); + } + } +} From e46b68a820fab5ac316ed3c02eb5bb331f896a81 Mon Sep 17 00:00:00 2001 From: IRacle Date: Thu, 28 Nov 2024 18:25:10 +0300 Subject: [PATCH 18/20] =?UTF-8?q?minus=20aura=F0=9F=98=AD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- EXILED/Exiled.Events/Handlers/Internal/Round.cs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/EXILED/Exiled.Events/Handlers/Internal/Round.cs b/EXILED/Exiled.Events/Handlers/Internal/Round.cs index 01aebaf3e3..f1cad19a77 100644 --- a/EXILED/Exiled.Events/Handlers/Internal/Round.cs +++ b/EXILED/Exiled.Events/Handlers/Internal/Round.cs @@ -11,6 +11,8 @@ namespace Exiled.Events.Handlers.Internal using System.Linq; using CentralAuth; + + using Exiled.API.Enums; using Exiled.API.Extensions; using Exiled.API.Features; using Exiled.API.Features.Items; From 05d373070ea6c635cff62a283fdfa1e898518b83 Mon Sep 17 00:00:00 2001 From: IRacle Date: Thu, 28 Nov 2024 20:34:14 +0300 Subject: [PATCH 19/20] nuh oh --- EXILED/Exiled.Events/Handlers/Internal/Round.cs | 3 --- 1 file changed, 3 deletions(-) diff --git a/EXILED/Exiled.Events/Handlers/Internal/Round.cs b/EXILED/Exiled.Events/Handlers/Internal/Round.cs index f1cad19a77..7f64274c50 100644 --- a/EXILED/Exiled.Events/Handlers/Internal/Round.cs +++ b/EXILED/Exiled.Events/Handlers/Internal/Round.cs @@ -112,9 +112,6 @@ private static void GenerateAttachments() if (firearmType == FirearmType.None) continue; - Log.Warn(firearmType.GetItemType()); - Log.Warn(Server.Host == null); - if (Item.Create(firearmType.GetItemType()) is not Firearm firearm) continue; From 2d947d132cd67bddb0aaa5dbd53af29cd2880e4a Mon Sep 17 00:00:00 2001 From: IRacle Date: Thu, 28 Nov 2024 21:34:45 +0300 Subject: [PATCH 20/20] i cooked --- .../Exiled.Events/Patches/Events/Server/WaitingForPlayers.cs | 1 + 1 file changed, 1 insertion(+) rename {Exiled => EXILED}/Exiled.Events/Patches/Events/Server/WaitingForPlayers.cs (99%) diff --git a/Exiled/Exiled.Events/Patches/Events/Server/WaitingForPlayers.cs b/EXILED/Exiled.Events/Patches/Events/Server/WaitingForPlayers.cs similarity index 99% rename from Exiled/Exiled.Events/Patches/Events/Server/WaitingForPlayers.cs rename to EXILED/Exiled.Events/Patches/Events/Server/WaitingForPlayers.cs index ec2d14a980..9a2902e766 100644 --- a/Exiled/Exiled.Events/Patches/Events/Server/WaitingForPlayers.cs +++ b/EXILED/Exiled.Events/Patches/Events/Server/WaitingForPlayers.cs @@ -10,6 +10,7 @@ namespace Exiled.Events.Patches.Events.Server #pragma warning disable SA1313 // Parameter names should begin with lower-case letter using API.Features; + using HarmonyLib; ///