From 859349cd1b7ba847b29413c80b4f861e59c549d3 Mon Sep 17 00:00:00 2001 From: Jesus QC <69375249+Jesus-QC@users.noreply.github.com> Date: Fri, 19 Jul 2024 06:29:45 +0200 Subject: [PATCH 01/58] Exiled 8.10.0 Release --- EXILED/Exiled.API/Extensions/MirrorExtensions.cs | 8 -------- 1 file changed, 8 deletions(-) diff --git a/EXILED/Exiled.API/Extensions/MirrorExtensions.cs b/EXILED/Exiled.API/Extensions/MirrorExtensions.cs index f8a97ac9b..8b30327d4 100644 --- a/EXILED/Exiled.API/Extensions/MirrorExtensions.cs +++ b/EXILED/Exiled.API/Extensions/MirrorExtensions.cs @@ -197,14 +197,6 @@ public static void PlayGunSound(this Player player, Vector3 position, ItemType i /// The state to set the lights to. True for on, false for off. public static void SetRoomLightsForTargetOnly(this Room room, Player target, bool value) => target.SendFakeSyncVar(room.RoomLightControllerNetIdentity, typeof(RoomLightController), nameof(RoomLightController.NetworkLightsEnabled), value); - /// - /// Sets the lights of a to be either on or off, visible only to the player. - /// - /// The room to modify the lights of. - /// The player who will see the lights state change. - /// The state to set the lights to. True for on, false for off. - public static void SetRoomLightsForTargetOnly(this Room room, Player target, bool value) => target.SendFakeSyncVar(room.RoomLightControllerNetIdentity, typeof(RoomLightController), nameof(RoomLightController.NetworkLightsEnabled), value); - /// /// Sets of a that only the player can see. /// From 806e5f36e2ff930c615e7f6028c48dffa4fdfa60 Mon Sep 17 00:00:00 2001 From: Jesus QC <69375249+Jesus-QC@users.noreply.github.com> Date: Fri, 19 Jul 2024 06:49:59 +0200 Subject: [PATCH 02/58] [API] PrefabHelper (#97) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Nameless <85962933+Misfiy@users.noreply.github.com> Co-authored-by: Vladislav Popovič Co-authored-by: Yamato Co-authored-by: Ika <36999341+IkaOverride@users.noreply.github.com> Co-authored-by: Roblox-Player ;) <87085480+XShine555@users.noreply.github.com> Co-authored-by: Banalny-Banan <133122450+Banalny-Banan@users.noreply.github.com> Co-authored-by: Bolton <48883340+BoltonDev@users.noreply.github.com> Co-authored-by: xNexusACS <83370388+xNexusACS@users.noreply.github.com> --- EXILED/Exiled.API/Enums/PrefabType.cs | 277 ++++++++++++++++++ .../Features/Attributes/PrefabAttribute.cs | 37 +++ EXILED/Exiled.API/Features/PrefabHelper.cs | 92 ++++++ .../Handlers/Internal/MapGenerated.cs | 3 +- 4 files changed, 408 insertions(+), 1 deletion(-) create mode 100644 EXILED/Exiled.API/Enums/PrefabType.cs create mode 100644 EXILED/Exiled.API/Features/Attributes/PrefabAttribute.cs create mode 100644 EXILED/Exiled.API/Features/PrefabHelper.cs diff --git a/EXILED/Exiled.API/Enums/PrefabType.cs b/EXILED/Exiled.API/Enums/PrefabType.cs new file mode 100644 index 000000000..fbcd3dcbf --- /dev/null +++ b/EXILED/Exiled.API/Enums/PrefabType.cs @@ -0,0 +1,277 @@ +// ----------------------------------------------------------------------- +// +// Copyright (c) Exiled Team. All rights reserved. +// Licensed under the CC BY-SA 3.0 license. +// +// ----------------------------------------------------------------------- + +namespace Exiled.API.Enums +{ + using Exiled.API.Features.Attributes; + + /// + /// Type of prefab. + /// + public enum PrefabType + { +#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member +#pragma warning disable SA1602 // Enumeration items should be documented + [Prefab(1883254029, "Player")] + Player, + + [Prefab(2295511789, "EZ BreakableDoor")] + EZBreakableDoor, + + [Prefab(2295511789, "HCZ BreakableDoor")] + HCZBreakableDoor, + + [Prefab(3038351124, "LCZ BreakableDoor")] + LCZBreakableDoor, + + [Prefab(1704345398, "sportTargetPrefab")] + SportTarget, + + [Prefab(858699872, "dboyTargetPrefab")] + DBoyTarget, + + [Prefab(3613149668, "binaryTargetPrefab")] + BinaryTarget, + + [Prefab(1306864341, "TantrumObj")] + TantrumObj, + + [Prefab(1321952889, "PrimitiveObjectToy")] + PrimitiveObjectToy, + + [Prefab(3956448839, "LightSourceToy")] + LightSourceToy, + + [Prefab(2672653014, "RegularKeycardPickup")] + RegularKeycardPickup, + + [Prefab(335436768, "ChaosKeycardPickup")] + ChaosKeycardPickup, + + [Prefab(248357067, "RadioPickup")] + RadioPickup, + + [Prefab(1925130715, "Com15Pickup")] + Com15Pickup, + + [Prefab(2808038258, "MedkitPickup")] + MedkitPickup, + + [Prefab(2606539874, "FlashlightPickup")] + FlashlightPickup, + + [Prefab(2974277164, "MicroHidPickup")] + MicroHidPickup, + + [Prefab(1367360155, "SCP500Pickup")] + SCP500Pickup, + + [Prefab(689511071, "SCP207Pickup")] + SCP207Pickup, + + [Prefab(4056235189, "Ammo12gaPickup")] + Ammo12gaPickup, + + [Prefab(212068596, "E11SRPickup")] + E11SRPickup, + + [Prefab(1982658896, "CrossvecPickup")] + CrossvecPickup, + + [Prefab(2474630775, "Ammo556mmPickup")] + Ammo556mmPickup, + + [Prefab(3462306180, "Fsp9Pickup")] + Fsp9Pickup, + + [Prefab(2405374689, "LogicerPickup")] + LogicerPickup, + + [Prefab(1273232029, "HegPickup")] + HegPickup, + + [Prefab(3871663704, "FlashbangPickup")] + FlashbangPickup, + + [Prefab(1499866827, "Ammo44calPickup")] + Ammo44calPickup, + + [Prefab(3685499023, "Ammo762mmPickup")] + Ammo762mmPickup, + + [Prefab(2344368365, "Ammo9mmPickup")] + Ammo9mmPickup, + + [Prefab(1749039070, "Com18Pickup")] + Com18Pickup, + + [Prefab(3525743409, "Scp018Projectile")] + Scp018Projectile, + + [Prefab(3711531185, "SCP268Pickup")] + SCP268Pickup, + + [Prefab(1573779433, "AdrenalinePrefab")] + AdrenalinePrefab, + + [Prefab(3124923193, "PainkillersPickup")] + PainkillersPickup, + + [Prefab(3134959991, "CoinPickup")] + CoinPickup, + + [Prefab(941440279, "Light Armor Pickup")] + LightArmorPickup, + + [Prefab(3118088094, "Combat Armor Pickup")] + CombatArmorPickup, + + [Prefab(3164421243, "Heavy Armor Pickup")] + HeavyArmorPickup, + + [Prefab(1861159387, "RevolverPickup")] + RevolverPickup, + + [Prefab(3814984482, "AkPickup")] + AkPickup, + + [Prefab(3180035653, "ShotgunPickup")] + ShotgunPickup, + + [Prefab(464602874, "Scp330Pickup")] + Scp330Pickup, + + [Prefab(1983050408, "Scp2176Projectile")] + Scp2176Projectile, + + [Prefab(2088018000, "SCP244APickup Variant")] + SCP244APickup, + + [Prefab(3030062014, "SCP244BPickup Variant")] + SCP244BPickup, + + [Prefab(2702950243, "SCP1853Pickup")] + SCP1853Pickup, + + [Prefab(3881162440, "DisruptorPickup")] + DisruptorPickup, + + [Prefab(504857316, "Com45Pickup")] + Com45Pickup, + + [Prefab(303271247, "SCP1576Pickup")] + SCP1576Pickup, + + [Prefab(2915316078, "JailbirdPickup")] + JailbirdPickup, + + [Prefab(1209253563, "AntiSCP207Pickup")] + AntiSCP207Pickup, + + [Prefab(2216560136, "FRMG0Pickup")] + FRMG0Pickup, + + [Prefab(74988289, "A7Pickup")] + A7Pickup, + + [Prefab(3532394942, "LanternPickup")] + LanternPickup, + + [Prefab(825024811, "Amnestic Cloud Hazard")] + AmnesticCloudHazard, + + [Prefab(2286635216, "Scp018PedestalStructure Variant")] + Scp018PedestalStructure, + + [Prefab(664776131, "Scp207PedestalStructure Variant")] + Scp207PedestalStructure, + + [Prefab(3724306703, "Scp244PedestalStructure Variant")] + Scp244PedestalStructure, + + [Prefab(3849573771, "Scp268PedestalStructure Variant")] + Scp268PedestalStructure, + + [Prefab(373821065, "Scp500PedestalStructure Variant")] + Scp500PedestalStructure, + + [Prefab(3962534659, "Scp1853PedestalStructure Variant")] + Scp1853PedestalStructure, + + [Prefab(3578915554, "Scp2176PedestalStructure Variant")] + Scp2176PedestalStructure, + + [Prefab(3372339835, "Scp1576PedestalStructure Variant")] + Scp1576PedestalStructure, + + [Prefab(2830750618, "LargeGunLockerStructure")] + LargeGunLockerStructure, + + [Prefab(3352879624, "RifleRackStructure")] + RifleRackStructure, + + [Prefab(1964083310, "MiscLocker")] + MiscLocker, + + [Prefab(2724603877, "GeneratorStructure")] + GeneratorStructure, + + [Prefab(1783091262, "Spawnable Work Station Structure")] + WorkstationStructure, + + [Prefab(4040822781, "RegularMedkitStructure")] + RegularMedkitStructure, + + [Prefab(2525847434, "AdrenalineMedkitStructure")] + AdrenalineMedkitStructure, + + [Prefab(427210814, "HegProjectile")] + HegProjectile, + + [Prefab(2409733045, "FlashbangProjectile")] + FlashbangProjectile, + + [Prefab(1062458989, "SCP-173_Ragdoll")] + Scp173Ragdoll, + + [Prefab(1951328980, "Ragdoll_1")] + Ragdoll1, + + [Prefab(992490681, "SCP-106_Ragdoll")] + Scp106Ragdoll, + + [Prefab(3219675689, "Ragdoll_4")] + Ragdoll4, + + [Prefab(417388851, "Ragdoll_7")] + Ragdoll7, + + [Prefab(3185790062, "Ragdoll_6")] + Ragdoll6, + + [Prefab(2567420661, "Ragdoll_8")] + Ragdoll8, + + [Prefab(149379640, "SCP-096_Ragdoll")] + Scp096Ragdoll, + + [Prefab(1862774274, "Ragdoll_10")] + Ragdoll10, + + [Prefab(2710373253, "Ragdoll_Tut")] + RagdollTutorial, + + [Prefab(1389252654, "Ragdoll_12")] + Ragdoll12, + + [Prefab(3175759689, "SCP-939_Ragdoll")] + Scp939Ragdoll, + + [Prefab(3721192489, "Scp3114_Ragdoll")] + Scp3114Ragdoll, + } +} \ No newline at end of file diff --git a/EXILED/Exiled.API/Features/Attributes/PrefabAttribute.cs b/EXILED/Exiled.API/Features/Attributes/PrefabAttribute.cs new file mode 100644 index 000000000..b2ba66fb7 --- /dev/null +++ b/EXILED/Exiled.API/Features/Attributes/PrefabAttribute.cs @@ -0,0 +1,37 @@ +// ----------------------------------------------------------------------- +// +// Copyright (c) Exiled Team. All rights reserved. +// Licensed under the CC BY-SA 3.0 license. +// +// ----------------------------------------------------------------------- + +namespace Exiled.API.Features.Attributes +{ + using System; + + /// + [AttributeUsage(AttributeTargets.Field, AllowMultiple = false)] + public class PrefabAttribute : Attribute + { + /// + /// Initializes a new instance of the class. + /// + /// + /// + public PrefabAttribute(uint assetId, string name) + { + AssetId = assetId; + Name = name; + } + + /// + /// Gets the prefab's asset id. + /// + public uint AssetId { get; } + + /// + /// Gets the prefab's name. + /// + public string Name { get; } + } +} \ No newline at end of file diff --git a/EXILED/Exiled.API/Features/PrefabHelper.cs b/EXILED/Exiled.API/Features/PrefabHelper.cs new file mode 100644 index 000000000..de97e15d5 --- /dev/null +++ b/EXILED/Exiled.API/Features/PrefabHelper.cs @@ -0,0 +1,92 @@ +// ----------------------------------------------------------------------- +// +// Copyright (c) Exiled Team. All rights reserved. +// Licensed under the CC BY-SA 3.0 license. +// +// ----------------------------------------------------------------------- + +namespace Exiled.API.Features +{ + using System; + using System.Collections.Generic; + using System.Collections.ObjectModel; + using System.Linq; + using System.Reflection; + + using Exiled.API.Enums; + using Exiled.API.Features.Attributes; + using Mirror; + using UnityEngine; + + /// + /// Helper for Prefabs. + /// + public static class PrefabHelper + { + private static readonly Dictionary Stored = new(); + + /// + /// Gets a dictionary of to . + /// + public static ReadOnlyDictionary PrefabToGameObject => new(Stored); + + /// + /// Gets the prefab attribute of a prefab type. + /// + /// The prefab type. + /// The . + public static PrefabAttribute GetPrefabAttribute(this PrefabType prefabType) + { + Type type = prefabType.GetType(); + return type.GetField(Enum.GetName(type, prefabType)).GetCustomAttribute(); + } + + /// + /// Spawns a prefab on server. + /// + /// The prefab type. + /// The position to spawn the prefab. + /// The rotation of the prefab. + /// The instantied. + public static GameObject Spawn(PrefabType prefabType, Vector3 position = default, Quaternion rotation = default) + { + if (!Stored.TryGetValue(prefabType, out GameObject gameObject)) + return null; + GameObject newGameObject = UnityEngine.Object.Instantiate(gameObject, position, rotation); + NetworkServer.Spawn(newGameObject); + return newGameObject; + } + + /// + /// Spawns a prefab on server. + /// + /// The prefab type. + /// The position to spawn the prefab. + /// The rotation of the prefab. + /// The type. + /// The instantied. + public static T Spawn(PrefabType prefabType, Vector3 position = default, Quaternion rotation = default) + where T : Component + { + if (!Stored.TryGetValue(prefabType, out GameObject gameObject) || !gameObject.TryGetComponent(out T component)) + return null; + T obj = UnityEngine.Object.Instantiate(component, position, rotation); + NetworkServer.Spawn(obj.gameObject); + return obj; + } + + /// + /// Loads all prefabs. + /// + internal static void LoadPrefabs() + { + Stored.Clear(); + + foreach (PrefabType prefabType in EnumUtils.Values) + { + PrefabAttribute attribute = prefabType.GetPrefabAttribute(); + Stored.Add(prefabType, NetworkClient.prefabs.FirstOrDefault(prefab => prefab.Key == attribute.AssetId || prefab.Value.name.Contains(attribute.Name)).Value); + } + } + } +} \ 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 2c9fc1ba4..1b1dadf46 100644 --- a/EXILED/Exiled.Events/Handlers/Internal/MapGenerated.cs +++ b/EXILED/Exiled.Events/Handlers/Internal/MapGenerated.cs @@ -46,6 +46,7 @@ internal static class MapGenerated public static void OnMapGenerated() { Map.ClearCache(); + PrefabHelper.LoadPrefabs(); // TODO: Fix For (https://trello.com/c/cUwpZDLs/5003-config-teamrespawnqueue-in-configgameplay-is-not-working-as-expected) PlayerRoles.RoleAssign.HumanSpawner.Handlers[PlayerRoles.Team.ChaosInsurgency] = new PlayerRoles.RoleAssign.OneRoleHumanSpawner(PlayerRoles.RoleTypeId.ChaosConscript); @@ -65,7 +66,7 @@ private static void GenerateCache() private static void GenerateAttachments() { - foreach (FirearmType firearmType in Enum.GetValues(typeof(FirearmType))) + foreach (FirearmType firearmType in EnumUtils.Values) { if (firearmType == FirearmType.None) continue; From b292db7107a49e06d4db95324c248bcb82d0d17e Mon Sep 17 00:00:00 2001 From: Jesus QC <69375249+Jesus-QC@users.noreply.github.com> Date: Fri, 19 Jul 2024 07:15:05 +0200 Subject: [PATCH 03/58] nuget push refs --- .github/workflows/push_nuget.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/push_nuget.yml b/.github/workflows/push_nuget.yml index ebac51f72..3234c9187 100644 --- a/.github/workflows/push_nuget.yml +++ b/.github/workflows/push_nuget.yml @@ -10,7 +10,7 @@ defaults: working-directory: ./EXILED env: - EXILED_REFERENCES_URL: https://misaka-zerotwo.github.io/SL-References/Master.zip + EXILED_REFERENCES_URL: https://Exiled-Official.github.io/SL-References/Master.zip EXILED_REFERENCES_PATH: ${{ github.workspace }}/EXILED/References jobs: From 53392e10eb2f93a5bf886d5fd954d0f56b9c1dcb Mon Sep 17 00:00:00 2001 From: Jesus QC <69375249+Jesus-QC@users.noreply.github.com> Date: Sat, 20 Jul 2024 00:07:38 +0200 Subject: [PATCH 04/58] 8.10.1 (#113) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Nameless <85962933+Misfiy@users.noreply.github.com> Co-authored-by: Vladislav Popovič Co-authored-by: Yamato Co-authored-by: Ika <36999341+IkaOverride@users.noreply.github.com> Co-authored-by: Roblox-Player ;) <87085480+XShine555@users.noreply.github.com> Co-authored-by: Banalny-Banan <133122450+Banalny-Banan@users.noreply.github.com> Co-authored-by: Bolton <48883340+BoltonDev@users.noreply.github.com> Co-authored-by: xNexusACS <83370388+xNexusACS@users.noreply.github.com> Co-authored-by: Yamato <66829532+louis1706@users.noreply.github.com> Co-authored-by: IRacle Co-authored-by: IRacle <79921583+IRacle1@users.noreply.github.com> --- .github/workflows/push_nuget.yml | 2 +- EXILED/EXILED.props | 2 +- EXILED/Exiled.API/Features/Toys/AdminToy.cs | 20 +++- EXILED/Exiled.API/Features/Toys/Light.cs | 6 +- EXILED/Exiled.API/Features/Toys/Primitive.cs | 28 ++--- .../Features/Toys/ShootingTargetToy.cs | 6 +- .../EventArgs/Scp3114/StranglingEventArgs.cs | 73 ++++-------- .../Patches/Events/Player/SpawningRagdoll.cs | 111 +++++------------- .../Patches/Events/Scp3114/Strangling.cs | 47 +++++--- 9 files changed, 124 insertions(+), 171 deletions(-) diff --git a/.github/workflows/push_nuget.yml b/.github/workflows/push_nuget.yml index 3234c9187..ccf1c1edc 100644 --- a/.github/workflows/push_nuget.yml +++ b/.github/workflows/push_nuget.yml @@ -41,7 +41,7 @@ jobs: shell: pwsh run: | ./build.ps1 -BuildNuGet - $File = (Get-ChildItem -Path . -Include 'EXILED.*.nupkg' -Recurse).Name + $File = (Get-ChildItem -Path . -Include 'EXILEDOFFICIAL.*.nupkg' -Recurse).Name Out-File -FilePath ${{ github.env }} -InputObject "PackageFile=$File" -Encoding utf-8 -Append - name: Push NuGet diff --git a/EXILED/EXILED.props b/EXILED/EXILED.props index f6933294b..13e1fd39d 100644 --- a/EXILED/EXILED.props +++ b/EXILED/EXILED.props @@ -15,7 +15,7 @@ - 8.10.0 + 8.10.1-pre false diff --git a/EXILED/Exiled.API/Features/Toys/AdminToy.cs b/EXILED/Exiled.API/Features/Toys/AdminToy.cs index 4e506c632..fdbe03da1 100644 --- a/EXILED/Exiled.API/Features/Toys/AdminToy.cs +++ b/EXILED/Exiled.API/Features/Toys/AdminToy.cs @@ -70,7 +70,11 @@ public Footprint Footprint public Vector3 Position { get => AdminToyBase.transform.position; - set => AdminToyBase.transform.position = value; + set + { + AdminToyBase.transform.position = value; + AdminToyBase.NetworkPosition = value; + } } /// @@ -79,7 +83,11 @@ public Vector3 Position public Quaternion Rotation { get => AdminToyBase.transform.rotation; - set => AdminToyBase.transform.rotation = value; + set + { + AdminToyBase.transform.rotation = value; + AdminToyBase.NetworkRotation = new LowPrecisionQuaternion(value); + } } /// @@ -88,7 +96,11 @@ public Quaternion Rotation public Vector3 Scale { get => AdminToyBase.transform.localScale; - set => AdminToyBase.transform.localScale = value; + set + { + AdminToyBase.transform.localScale = value; + AdminToyBase.NetworkScale = value; + } } /// @@ -110,7 +122,7 @@ public byte MovementSmoothing public bool IsStatic { get => AdminToyBase.IsStatic; - set => AdminToyBase.IsStatic = value; + set => AdminToyBase.NetworkIsStatic = value; } /// diff --git a/EXILED/Exiled.API/Features/Toys/Light.cs b/EXILED/Exiled.API/Features/Toys/Light.cs index 8e7c5b1bb..e484c9e04 100644 --- a/EXILED/Exiled.API/Features/Toys/Light.cs +++ b/EXILED/Exiled.API/Features/Toys/Light.cs @@ -97,9 +97,9 @@ public static Light Create(Vector3? position /*= null*/, Vector3? rotation /*= n { Light light = new(UnityEngine.Object.Instantiate(ToysHelper.LightBaseObject)); - light.AdminToyBase.transform.position = position ?? Vector3.zero; - light.AdminToyBase.transform.eulerAngles = rotation ?? Vector3.zero; - light.AdminToyBase.transform.localScale = scale ?? Vector3.one; + light.Position = position ?? Vector3.zero; + light.Rotation = Quaternion.Euler(rotation ?? Vector3.zero); + light.Scale = scale ?? Vector3.one; if (spawn) light.Spawn(); diff --git a/EXILED/Exiled.API/Features/Toys/Primitive.cs b/EXILED/Exiled.API/Features/Toys/Primitive.cs index 898aa1fbc..647350b16 100644 --- a/EXILED/Exiled.API/Features/Toys/Primitive.cs +++ b/EXILED/Exiled.API/Features/Toys/Primitive.cs @@ -117,14 +117,13 @@ public static Primitive Create(Vector3? position /*= null*/, Vector3? rotation / { Primitive primitive = new(Object.Instantiate(ToysHelper.PrimitiveBaseObject)); - primitive.AdminToyBase.transform.position = position ?? Vector3.zero; - primitive.AdminToyBase.transform.eulerAngles = rotation ?? Vector3.zero; - primitive.AdminToyBase.transform.localScale = scale ?? Vector3.one; + primitive.Position = position ?? Vector3.zero; + primitive.Rotation = Quaternion.Euler(rotation ?? Vector3.zero); + primitive.Scale = scale ?? Vector3.one; if (spawn) primitive.Spawn(); - primitive.AdminToyBase.NetworkScale = primitive.AdminToyBase.transform.localScale; primitive.Color = color ?? Color.gray; return primitive; @@ -144,14 +143,13 @@ public static Primitive Create(PrimitiveType primitiveType /*= PrimitiveType.Sph { Primitive primitive = new(Object.Instantiate(ToysHelper.PrimitiveBaseObject)); - primitive.AdminToyBase.transform.position = position ?? Vector3.zero; - primitive.AdminToyBase.transform.eulerAngles = rotation ?? Vector3.zero; - primitive.AdminToyBase.transform.localScale = scale ?? Vector3.one; + primitive.Position = position ?? Vector3.zero; + primitive.Rotation = Quaternion.Euler(rotation ?? Vector3.zero); + primitive.Scale = scale ?? Vector3.one; if (spawn) primitive.Spawn(); - primitive.AdminToyBase.NetworkScale = primitive.AdminToyBase.transform.localScale; primitive.Base.NetworkPrimitiveType = primitiveType; primitive.Color = color ?? Color.gray; @@ -173,15 +171,14 @@ public static Primitive Create(PrimitiveType primitiveType /*= PrimitiveType.Sph { Primitive primitive = new(Object.Instantiate(ToysHelper.PrimitiveBaseObject)); - primitive.AdminToyBase.transform.position = position ?? Vector3.zero; - primitive.AdminToyBase.transform.eulerAngles = rotation ?? Vector3.zero; - primitive.AdminToyBase.transform.localScale = scale ?? Vector3.one; + primitive.Position = position ?? Vector3.zero; + primitive.Rotation = Quaternion.Euler(rotation ?? Vector3.zero); + primitive.Scale = scale ?? Vector3.one; primitive.Flags = flags; if (spawn) primitive.Spawn(); - primitive.AdminToyBase.NetworkScale = primitive.AdminToyBase.transform.localScale; primitive.Base.NetworkPrimitiveType = primitiveType; primitive.Color = color ?? Color.gray; @@ -197,15 +194,14 @@ public static Primitive Create(PrimitiveSettings primitiveSettings) { Primitive primitive = new(Object.Instantiate(ToysHelper.PrimitiveBaseObject)); - primitive.AdminToyBase.transform.position = primitiveSettings.Position; - primitive.AdminToyBase.transform.eulerAngles = primitiveSettings.Rotation; - primitive.AdminToyBase.transform.localScale = primitiveSettings.Scale; + primitive.Position = primitiveSettings.Position; + primitive.Rotation = Quaternion.Euler(primitiveSettings.Rotation); + primitive.Scale = primitiveSettings.Scale; primitive.Flags = primitiveSettings.Flags; if (primitiveSettings.Spawn) primitive.Spawn(); - primitive.AdminToyBase.NetworkScale = primitive.AdminToyBase.transform.localScale; primitive.Base.NetworkPrimitiveType = primitiveSettings.PrimitiveType; primitive.Color = primitiveSettings.Color; primitive.IsStatic = primitiveSettings.IsStatic; diff --git a/EXILED/Exiled.API/Features/Toys/ShootingTargetToy.cs b/EXILED/Exiled.API/Features/Toys/ShootingTargetToy.cs index 3a0d0362c..01cb47db3 100644 --- a/EXILED/Exiled.API/Features/Toys/ShootingTargetToy.cs +++ b/EXILED/Exiled.API/Features/Toys/ShootingTargetToy.cs @@ -182,9 +182,9 @@ public static ShootingTargetToy Create(ShootingTargetType type, Vector3? positio } } - shootingTargetToy.AdminToyBase.transform.position = position ?? Vector3.zero; - shootingTargetToy.AdminToyBase.transform.eulerAngles = rotation ?? Vector3.zero; - shootingTargetToy.AdminToyBase.transform.localScale = scale ?? Vector3.one; + shootingTargetToy.Position = position ?? Vector3.zero; + shootingTargetToy.Rotation = Quaternion.Euler(rotation ?? Vector3.zero); + shootingTargetToy.Scale = scale ?? Vector3.one; if (spawn) shootingTargetToy.Spawn(); diff --git a/EXILED/Exiled.Events/EventArgs/Scp3114/StranglingEventArgs.cs b/EXILED/Exiled.Events/EventArgs/Scp3114/StranglingEventArgs.cs index 10db68777..da790afc6 100644 --- a/EXILED/Exiled.Events/EventArgs/Scp3114/StranglingEventArgs.cs +++ b/EXILED/Exiled.Events/EventArgs/Scp3114/StranglingEventArgs.cs @@ -1,4 +1,4 @@ -// ----------------------------------------------------------------------- +// ----------------------------------------------------------------------- // // Copyright (c) Exiled Team. All rights reserved. // Licensed under the CC BY-SA 3.0 license. @@ -7,69 +7,48 @@ namespace Exiled.Events.EventArgs.Scp3114 { - using Exiled.API.Features; - using Exiled.Events.EventArgs.Interfaces; - + using API.Features; + using Interfaces; using PlayerRoles.PlayableScps.Scp3114; - using HumanRole = PlayerRoles.HumanRole; - using Scp3114Role = API.Features.Roles.Scp3114Role; + using Scp3114Role = Exiled.API.Features.Roles.Scp3114Role; /// - /// Contains all information before strangling a player. + /// Contains all information before SCP-3114 strangles a player. /// public class StranglingEventArgs : IScp3114Event, IDeniableEvent { - private readonly Scp3114Strangle strangle; - private Player target = null; - /// - /// Initializes a new instance of the class. + /// Initializes a new instance of the class. /// - /// The instance. - /// The triggering the event. - /// The being targeted. - public StranglingEventArgs(Scp3114Strangle strangle, Player player, Scp3114Strangle.StrangleTarget target) - { - this.strangle = strangle; - Scp3114 = player.Role.As(); - Player = player; - Target = Player.Get(target.Target); - StrangleTarget = target; - } - - /// - public Scp3114Role Scp3114 { get; } - - /// - public Player Player + /// + /// The instance which this is being instantiated from. + /// + /// + /// The being targeted. + /// + public StranglingEventArgs(ReferenceHub hub, ReferenceHub target) { - get => target; - set - { - target = value; - - if (target == null) - { - StrangleTarget = default(Scp3114Strangle.StrangleTarget); - return; - } - - StrangleTarget = new(target.ReferenceHub, strangle.GetStranglePosition(target.ReferenceHub.roleManager.CurrentRole as HumanRole), Player.Position); - } + Player = Player.Get(hub); + Scp3114 = Player.Role.As(); + Target = Player.Get(target); } + /// /// - /// Gets the target player. + /// The who is Scp-3114. /// - public Player Target { get; } + public Player Player { get; } + + /// + public Scp3114Role Scp3114 { get; } /// - /// Gets the . This value is updated when is changed. + /// Gets the being strangled. /// - public Scp3114Strangle.StrangleTarget? StrangleTarget { get; private set; } + public Player Target { get; } - /// + /// public bool IsAllowed { get; set; } = true; } -} \ No newline at end of file +} diff --git a/EXILED/Exiled.Events/Patches/Events/Player/SpawningRagdoll.cs b/EXILED/Exiled.Events/Patches/Events/Player/SpawningRagdoll.cs index 08f0d34aa..e0c5fb61c 100644 --- a/EXILED/Exiled.Events/Patches/Events/Player/SpawningRagdoll.cs +++ b/EXILED/Exiled.Events/Patches/Events/Player/SpawningRagdoll.cs @@ -11,11 +11,13 @@ namespace Exiled.Events.Patches.Events.Player using System.Reflection.Emit; using API.Features.Pools; + using Exiled.API.Features; using Exiled.Events.Attributes; using Exiled.Events.EventArgs.Player; using HarmonyLib; + using PlayerRoles.Ragdolls; using PlayerStatsSystem; @@ -39,45 +41,21 @@ private static IEnumerable Transpiler(IEnumerable newInstructions = ListPool.Pool.Get(instructions); - Label ret = generator.DefineLabel(); + Label cnt = generator.DefineLabel(); LocalBuilder ev = generator.DeclareLocal(typeof(SpawningRagdollEventArgs)); - LocalBuilder newRagdoll = generator.DeclareLocal(typeof(Ragdoll)); - LocalBuilder localScale = generator.DeclareLocal(typeof(Vector3)); - LocalBuilder evScale = generator.DeclareLocal(typeof(Vector3)); - LocalBuilder targetScale = generator.DeclareLocal(typeof(Vector3)); int offset = 0; - int index = newInstructions.FindIndex(instruction => instruction.opcode == OpCodes.Ldloc_1) + offset; - - // remove - // "basicRagdoll.NetworkInfo = new RagdollData(owner, handler, transform.localPosition, transform.localRotation);" - newInstructions.RemoveRange(index, 9); + int index = newInstructions.FindIndex(instruction => instruction.Calls(PropertySetter(typeof(BasicRagdoll), nameof(BasicRagdoll.NetworkInfo)))) + offset; - // replace with - newInstructions.InsertRange(index, new[] + newInstructions.InsertRange(index, new CodeInstruction[] { - // hub - new CodeInstruction(OpCodes.Ldarg_0), - - // handler - new(OpCodes.Ldarg_1), - - // ragdollRole.transform.localPosition - new(OpCodes.Ldloc_2), - new(OpCodes.Callvirt, PropertyGetter(typeof(Transform), nameof(Transform.localPosition))), - - // ragdollRole.transform.localRotation - new(OpCodes.Ldloc_2), - new(OpCodes.Callvirt, PropertyGetter(typeof(Transform), nameof(Transform.localRotation))), - - // new RagdollInfo(ReferenceHub, DamageHandlerBase, Vector3, Quaternion) - new(OpCodes.Newobj, GetDeclaredConstructors(typeof(RagdollData))[0]), + // RagdollInfo loads into stack before il inject // true new(OpCodes.Ldc_I4_1), - // SpawningRagdollEventArgs ev = new(RagdollInfo, DamageHandlerBase, bool) + // SpawningRagdollEventArgs ev = new(RagdollInfo, bool) new(OpCodes.Newobj, GetDeclaredConstructors(typeof(SpawningRagdollEventArgs))[0]), new(OpCodes.Dup), new(OpCodes.Dup), @@ -86,66 +64,41 @@ private static IEnumerable Transpiler(IEnumerable Transpiler(IEnumerable.Pool.Return(newInstructions); } } -} \ No newline at end of file +} diff --git a/EXILED/Exiled.Events/Patches/Events/Scp3114/Strangling.cs b/EXILED/Exiled.Events/Patches/Events/Scp3114/Strangling.cs index e4cdba5ed..57ed08f40 100644 --- a/EXILED/Exiled.Events/Patches/Events/Scp3114/Strangling.cs +++ b/EXILED/Exiled.Events/Patches/Events/Scp3114/Strangling.cs @@ -7,9 +7,11 @@ namespace Exiled.Events.Patches.Events.Scp3114 { + using System; using System.Collections.Generic; using System.Reflection.Emit; + using Exiled.API.Features; using Exiled.API.Features.Pools; using Exiled.Events.Attributes; using Exiled.Events.EventArgs.Scp3114; @@ -31,32 +33,45 @@ internal class Strangling private static IEnumerable Transpiler(IEnumerable instruction, ILGenerator generator) { List newInstructions = ListPool.Pool.Get(instruction); - Label retLabel = generator.DefineLabel(); + + Label retLabel = newInstructions[newInstructions.Count - 2].labels[0]; + Label jumpLabel = generator.DefineLabel(); + LocalBuilder ev = generator.DeclareLocal(typeof(StranglingEventArgs)); - const int offset = 0; - int index = newInstructions.FindIndex(i => i.opcode == OpCodes.Ldloc_3) + offset; + const int offset = -1; + int index = newInstructions.FindIndex(i => i.LoadsField(Field(typeof(ReferenceHub), nameof(ReferenceHub.playerEffectsController)))) + offset; newInstructions.InsertRange(index, new CodeInstruction[] { - new(OpCodes.Ldarg_0), - new(OpCodes.Ldarg_0), + // this.Owner + new CodeInstruction(OpCodes.Ldarg_0).MoveLabelsFrom(newInstructions[index]), new(OpCodes.Callvirt, PropertyGetter(typeof(Scp3114Strangle), nameof(Scp3114Strangle.Owner))), - new(OpCodes.Call, Method(typeof(Player), nameof(Player.Get), new[] { typeof(ReferenceHub) })), - new(OpCodes.Ldloc_3), + + // target + new(OpCodes.Ldloc_0), + + // StranglingEventArgs ev = new(ReferenceHub, ReferenceHub); new(OpCodes.Newobj, GetDeclaredConstructors(typeof(StranglingEventArgs))[0]), new(OpCodes.Dup), - new(OpCodes.Dup), - new(OpCodes.Call, Method(typeof(Handlers.Scp3114), nameof(Handlers.Scp3114.OnStrangling))), - new(OpCodes.Stloc, ev.LocalIndex), + + // Scp3114.OnStrangling(ev); + new(OpCodes.Call, Method(typeof(Scp3114), nameof(Scp3114.OnStrangling))), + + // if (ev.IsAllowed) goto jumpLabel; new(OpCodes.Callvirt, PropertyGetter(typeof(StranglingEventArgs), nameof(StranglingEventArgs.IsAllowed))), - new(OpCodes.Brfalse_S, retLabel), - new(OpCodes.Ldloc, ev.LocalIndex), - new(OpCodes.Callvirt, PropertyGetter(typeof(StranglingEventArgs), nameof(StranglingEventArgs.StrangleTarget))), - new(OpCodes.Stloc_3), - }); + new(OpCodes.Brtrue_S, jumpLabel), - newInstructions[newInstructions.Count - 1].labels.Add(retLabel); + // return strangleTarget = null; + new(OpCodes.Ldloca_S, 4), + new(OpCodes.Initobj, typeof(Scp3114Strangle.StrangleTarget?)), + new(OpCodes.Ldloc_S, 4), + new(OpCodes.Stloc_S, 4), + new(OpCodes.Leave, retLabel), + + // jump: + new CodeInstruction(OpCodes.Nop).WithLabels(jumpLabel), + }); for (int z = 0; z < newInstructions.Count; z++) yield return newInstructions[z]; From a874fe8cc3ff20e4ad1f9fcd878bec6b50c8e687 Mon Sep 17 00:00:00 2001 From: Jesus QC <69375249+Jesus-QC@users.noreply.github.com> Date: Sat, 20 Jul 2024 00:29:11 +0200 Subject: [PATCH 05/58] 8.10.1-pre (#115) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Nameless <85962933+Misfiy@users.noreply.github.com> Co-authored-by: Vladislav Popovič Co-authored-by: Yamato Co-authored-by: Ika <36999341+IkaOverride@users.noreply.github.com> Co-authored-by: Roblox-Player ;) <87085480+XShine555@users.noreply.github.com> Co-authored-by: Banalny-Banan <133122450+Banalny-Banan@users.noreply.github.com> Co-authored-by: Bolton <48883340+BoltonDev@users.noreply.github.com> Co-authored-by: xNexusACS <83370388+xNexusACS@users.noreply.github.com> Co-authored-by: Yamato <66829532+louis1706@users.noreply.github.com> Co-authored-by: IRacle Co-authored-by: IRacle <79921583+IRacle1@users.noreply.github.com> --- EXILED/Exiled.API/Features/Player.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/EXILED/Exiled.API/Features/Player.cs b/EXILED/Exiled.API/Features/Player.cs index c95837571..c6fc25aa1 100644 --- a/EXILED/Exiled.API/Features/Player.cs +++ b/EXILED/Exiled.API/Features/Player.cs @@ -665,7 +665,7 @@ public ScpSpawnPreferences.SpawnPreferences ScpPreferences /// Gets a value indicating whether or not the player's is any NTF rank. /// Equivalent to checking the player's . /// - public bool IsNTF => Role?.Team is Team.FoundationForces; + public bool IsNTF => Role?.Team is Team.FoundationForces && Role?.Type is not RoleTypeId.FacilityGuard; /// /// Gets a value indicating whether or not the player's is any Chaos rank. From 7ab6f668d5ed12316a8ec7a0264c35164f08cd90 Mon Sep 17 00:00:00 2001 From: Jesus QC <69375249+Jesus-QC@users.noreply.github.com> Date: Sat, 20 Jul 2024 00:38:37 +0200 Subject: [PATCH 06/58] nuget push fix --- .github/workflows/push_nuget.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/push_nuget.yml b/.github/workflows/push_nuget.yml index ccf1c1edc..72e45189e 100644 --- a/.github/workflows/push_nuget.yml +++ b/.github/workflows/push_nuget.yml @@ -46,4 +46,4 @@ jobs: - name: Push NuGet shell: pwsh - run: nuget push EXILED/${{ env.PackageFile }} -ApiKey ${{ secrets.NUGET_API_KEY }} -Source https://api.nuget.org/v3/index.json + run: nuget push ${{ env.PackageFile }} -ApiKey ${{ secrets.NUGET_API_KEY }} -Source https://api.nuget.org/v3/index.json From f3dd508d9f1fa73f3962bebc026784d3a32d7c5e Mon Sep 17 00:00:00 2001 From: IRacle <79921583+IRacle1@users.noreply.github.com> Date: Sat, 20 Jul 2024 14:43:34 +0300 Subject: [PATCH 07/58] Revert `IsNtf` cringe (#119) --- EXILED/Exiled.API/Features/Player.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/EXILED/Exiled.API/Features/Player.cs b/EXILED/Exiled.API/Features/Player.cs index c6fc25aa1..e184478ea 100644 --- a/EXILED/Exiled.API/Features/Player.cs +++ b/EXILED/Exiled.API/Features/Player.cs @@ -665,7 +665,8 @@ public ScpSpawnPreferences.SpawnPreferences ScpPreferences /// Gets a value indicating whether or not the player's is any NTF rank. /// Equivalent to checking the player's . /// - public bool IsNTF => Role?.Team is Team.FoundationForces && Role?.Type is not RoleTypeId.FacilityGuard; + // TODO: Change logic for FacilityGuard in next major update + public bool IsNTF => Role?.Team is Team.FoundationForces; /// /// Gets a value indicating whether or not the player's is any Chaos rank. From 1fbce17cc8c7f8bb0588d2c31bc70f3946d59213 Mon Sep 17 00:00:00 2001 From: IRacle <79921583+IRacle1@users.noreply.github.com> Date: Sat, 20 Jul 2024 17:03:11 +0300 Subject: [PATCH 08/58] `ChangingRadioPresetEventArgs::Radio` property (#109) --- .../Player/ChangingRadioPresetEventArgs.cs | 19 +++++++++++++++++-- .../Events/Player/ChangingRadioPreset.cs | 8 ++++++-- 2 files changed, 23 insertions(+), 4 deletions(-) diff --git a/EXILED/Exiled.Events/EventArgs/Player/ChangingRadioPresetEventArgs.cs b/EXILED/Exiled.Events/EventArgs/Player/ChangingRadioPresetEventArgs.cs index 651612a0c..7b59f2fb9 100644 --- a/EXILED/Exiled.Events/EventArgs/Player/ChangingRadioPresetEventArgs.cs +++ b/EXILED/Exiled.Events/EventArgs/Player/ChangingRadioPresetEventArgs.cs @@ -10,15 +10,18 @@ namespace Exiled.Events.EventArgs.Player using API.Features; using Exiled.API.Enums; + using Exiled.API.Features.Items; using Interfaces; + using InventorySystem.Items.Radio; + using static InventorySystem.Items.Radio.RadioMessages; /// /// Contains all information before radio preset is changed. /// - public class ChangingRadioPresetEventArgs : IPlayerEvent, IDeniableEvent + public class ChangingRadioPresetEventArgs : IPlayerEvent, IItemEvent, IDeniableEvent { /// /// Initializes a new instance of the class. @@ -26,6 +29,9 @@ public class ChangingRadioPresetEventArgs : IPlayerEvent, IDeniableEvent /// /// /// + /// + /// + /// /// /// /// @@ -35,9 +41,10 @@ public class ChangingRadioPresetEventArgs : IPlayerEvent, IDeniableEvent /// /// /// - public ChangingRadioPresetEventArgs(Player player, RadioRangeLevel oldValue, RadioRangeLevel newValue, bool isAllowed = true) + public ChangingRadioPresetEventArgs(Player player, RadioItem item, RadioRangeLevel oldValue, RadioRangeLevel newValue, bool isAllowed = true) { Player = player; + Radio = (Radio)Item.Get(item); OldValue = (RadioRange)oldValue; NewValue = (RadioRange)newValue; IsAllowed = isAllowed; @@ -64,5 +71,13 @@ public ChangingRadioPresetEventArgs(Player player, RadioRangeLevel oldValue, Rad /// Gets the player who's using the radio. /// public Player Player { get; } + + /// + public Item Item => Radio; + + /// + /// Gets the which is being used. + /// + public Radio Radio { get; } } } \ No newline at end of file diff --git a/EXILED/Exiled.Events/Patches/Events/Player/ChangingRadioPreset.cs b/EXILED/Exiled.Events/Patches/Events/Player/ChangingRadioPreset.cs index 1199215c8..602a349a2 100644 --- a/EXILED/Exiled.Events/Patches/Events/Player/ChangingRadioPreset.cs +++ b/EXILED/Exiled.Events/Patches/Events/Player/ChangingRadioPreset.cs @@ -12,6 +12,7 @@ namespace Exiled.Events.Patches.Events.Player using API.Features; using API.Features.Pools; + using Exiled.Events.Attributes; using Exiled.Events.EventArgs.Player; @@ -50,6 +51,9 @@ private static IEnumerable Transpiler(IEnumerable Transpiler(IEnumerable Transpiler(IEnumerable.Pool.Return(newInstructions); } } -} \ No newline at end of file +} From a8b55171ccf5df55493a0f40614f06941f4709bb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vladislav=20Popovi=C4=8D?= Date: Sat, 20 Jul 2024 17:09:26 +0300 Subject: [PATCH 09/58] Add `InstantKill` property (#75) --- EXILED/Exiled.Events/EventArgs/Player/HurtingEventArgs.cs | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/EXILED/Exiled.Events/EventArgs/Player/HurtingEventArgs.cs b/EXILED/Exiled.Events/EventArgs/Player/HurtingEventArgs.cs index b5b8912ac..b6b450f7b 100644 --- a/EXILED/Exiled.Events/EventArgs/Player/HurtingEventArgs.cs +++ b/EXILED/Exiled.Events/EventArgs/Player/HurtingEventArgs.cs @@ -9,8 +9,8 @@ namespace Exiled.Events.EventArgs.Player { using API.Features; using API.Features.DamageHandlers; - using Interfaces; + using PlayerStatsSystem; using CustomAttackerHandler = API.Features.DamageHandlers.AttackerDamageHandler; using DamageHandlerBase = PlayerStatsSystem.DamageHandlerBase; @@ -55,6 +55,11 @@ public float Amount /// public CustomDamageHandler DamageHandler { get; set; } + /// + /// Gets a value indicating whether the incoming damage is an instant kill. + /// + public bool IsInstantKill => Amount == StandardDamageHandler.KillValue; + /// public bool IsAllowed { get; set; } = true; } From 96ee04f3ada735ecd1d3f02e531432fd7c61b27f Mon Sep 17 00:00:00 2001 From: Jesus QC <69375249+Jesus-QC@users.noreply.github.com> Date: Sat, 20 Jul 2024 16:42:22 +0200 Subject: [PATCH 10/58] version bump --- EXILED/EXILED.props | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/EXILED/EXILED.props b/EXILED/EXILED.props index 13e1fd39d..75fd84a47 100644 --- a/EXILED/EXILED.props +++ b/EXILED/EXILED.props @@ -15,7 +15,7 @@ - 8.10.1-pre + 8.11.0-pre false From 6b203e602ca1666caae789f7a3a6763f1f8cb67f Mon Sep 17 00:00:00 2001 From: IRacle <79921583+IRacle1@users.noreply.github.com> Date: Sat, 20 Jul 2024 18:18:25 +0300 Subject: [PATCH 11/58] Things (#122) --- EXILED/Exiled.API/Features/Items/Firearm.cs | 2 +- EXILED/Exiled.API/Features/Items/Item.cs | 4 ++-- EXILED/Exiled.API/Features/Items/Throwable.cs | 9 ++++++++- EXILED/Exiled.API/Features/Player.cs | 2 ++ EXILED/Exiled.API/Features/Round.cs | 2 +- .../Patches/Events/Item/KeycardInteracting.cs | 2 +- .../Exiled.Events/Patches/Fixes/GrenadePropertiesFix.cs | 1 - 7 files changed, 15 insertions(+), 7 deletions(-) diff --git a/EXILED/Exiled.API/Features/Items/Firearm.cs b/EXILED/Exiled.API/Features/Items/Firearm.cs index b6ab15fb4..e05a9180f 100644 --- a/EXILED/Exiled.API/Features/Items/Firearm.cs +++ b/EXILED/Exiled.API/Features/Items/Firearm.cs @@ -72,7 +72,7 @@ internal Firearm(ItemType type) if (Base.HasAdvantageFlag(AttachmentDescriptiveAdvantages.Flashlight)) firearmStatusFlags |= FirearmStatusFlags.FlashlightEnabled; - Base.Status = new FirearmStatus(Base.AmmoManagerModule.MaxAmmo, firearmStatusFlags, Base.Status.Attachments); + Base.Status = new FirearmStatus(MaxAmmo, firearmStatusFlags, Base.Status.Attachments); } /// . diff --git a/EXILED/Exiled.API/Features/Items/Item.cs b/EXILED/Exiled.API/Features/Items/Item.cs index 0a9bf69f9..fd0bba35a 100644 --- a/EXILED/Exiled.API/Features/Items/Item.cs +++ b/EXILED/Exiled.API/Features/Items/Item.cs @@ -99,7 +99,7 @@ public ushort Serial /// /// Gets or sets the scale for the item. /// - public Vector3 Scale { get; set; } = Vector3.one; + public virtual Vector3 Scale { get; set; } = Vector3.one; /// /// Gets the of the item. @@ -259,7 +259,7 @@ public static Item Get(ItemBase itemBase) public static Item Create(ItemType type, Player owner = null) => type switch { ItemType.SCP268 => new Usable(type), - ItemType.Adrenaline or ItemType.Medkit or ItemType.Painkillers or ItemType.SCP500 or ItemType.SCP207 or ItemType.SCP1853 => new Consumable(type), + ItemType.Adrenaline or ItemType.Medkit or ItemType.Painkillers or ItemType.SCP500 or ItemType.SCP207 or ItemType.SCP1853 or ItemType.AntiSCP207 => new Consumable(type), ItemType.SCP244a or ItemType.SCP244b => new Scp244(type), ItemType.Ammo9x19 or ItemType.Ammo12gauge or ItemType.Ammo44cal or ItemType.Ammo556x45 or ItemType.Ammo762x39 => new Ammo(type), ItemType.Flashlight or ItemType.Lantern => new Flashlight(type), diff --git a/EXILED/Exiled.API/Features/Items/Throwable.cs b/EXILED/Exiled.API/Features/Items/Throwable.cs index 8e7e24a58..4946d1722 100644 --- a/EXILED/Exiled.API/Features/Items/Throwable.cs +++ b/EXILED/Exiled.API/Features/Items/Throwable.cs @@ -45,6 +45,13 @@ internal Throwable(ItemType type, Player player = null) { } + /// + public override Vector3 Scale + { + get => base.Scale; + set => Projectile.Scale = base.Scale = value; + } + /// /// Gets the base for this item. /// @@ -101,4 +108,4 @@ public void Throw(bool fullForce = true) /// A string containing Throwable-related data. public override string ToString() => $"{Type} ({Serial}) [{Weight}] *{Scale}* |{PinPullTime}|"; } -} \ No newline at end of file +} diff --git a/EXILED/Exiled.API/Features/Player.cs b/EXILED/Exiled.API/Features/Player.cs index e184478ea..4991e13d4 100644 --- a/EXILED/Exiled.API/Features/Player.cs +++ b/EXILED/Exiled.API/Features/Player.cs @@ -2154,6 +2154,8 @@ public bool UseItem(Item item) usableItem.Base.Owner = referenceHub; usableItem.Base.ServerOnUsingCompleted(); + typeof(UsableItemsController).InvokeStaticEvent(nameof(UsableItemsController.ServerOnUsingCompleted), new object[] { referenceHub, usableItem.Base }); + if (usableItem.Base is not null) usableItem.Destroy(); diff --git a/EXILED/Exiled.API/Features/Round.cs b/EXILED/Exiled.API/Features/Round.cs index e2a424d4d..ed334f519 100644 --- a/EXILED/Exiled.API/Features/Round.cs +++ b/EXILED/Exiled.API/Features/Round.cs @@ -49,7 +49,7 @@ public static class Round /// /// Gets a value indicating whether the round in progress or not. /// - public static bool InProgress => ReferenceHub.LocalHub is not null && RoundSummary.RoundInProgress(); + public static bool InProgress => ReferenceHub.LocalHub != null && RoundSummary.RoundInProgress(); /// /// Gets a value indicating whether the round is ended or not. diff --git a/EXILED/Exiled.Events/Patches/Events/Item/KeycardInteracting.cs b/EXILED/Exiled.Events/Patches/Events/Item/KeycardInteracting.cs index 97c4f4d23..288e5d212 100644 --- a/EXILED/Exiled.Events/Patches/Events/Item/KeycardInteracting.cs +++ b/EXILED/Exiled.Events/Patches/Events/Item/KeycardInteracting.cs @@ -33,7 +33,7 @@ namespace Exiled.Events.Patches.Events.Item /// Patches . /// Adds the event. /// - [EventPatch(typeof(Handlers.Player), nameof(Handlers.Player.InteractingDoor))] + [EventPatch(typeof(Handlers.Item), nameof(Handlers.Item.KeycardInteracting))] [HarmonyPatch(typeof(KeycardPickup), nameof(KeycardPickup.ProcessCollision))] internal static class KeycardInteracting { diff --git a/EXILED/Exiled.Events/Patches/Fixes/GrenadePropertiesFix.cs b/EXILED/Exiled.Events/Patches/Fixes/GrenadePropertiesFix.cs index bb42e350a..8c37c4f9a 100644 --- a/EXILED/Exiled.Events/Patches/Fixes/GrenadePropertiesFix.cs +++ b/EXILED/Exiled.Events/Patches/Fixes/GrenadePropertiesFix.cs @@ -54,7 +54,6 @@ private static IEnumerable Transpiler(IEnumerable Date: Sat, 20 Jul 2024 17:43:12 +0200 Subject: [PATCH 12/58] preparing for update --- EXILED/EXILED.props | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/EXILED/EXILED.props b/EXILED/EXILED.props index 75fd84a47..953b133c6 100644 --- a/EXILED/EXILED.props +++ b/EXILED/EXILED.props @@ -15,7 +15,7 @@ - 8.11.0-pre + 8.11.0 false From e20f7ccd1855fa0bb6b9ce138e5aa5b45305b0fc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=BE=89=E5=A4=9C?= Date: Sun, 21 Jul 2024 02:32:42 +0800 Subject: [PATCH 13/58] SCP 939 PlayingFootstep Reimplementation (#126) --- .../Scp939/PlayingFootstepEventArgs.cs | 57 +++++++++++++ EXILED/Exiled.Events/Handlers/Scp939.cs | 11 +++ .../Patches/Events/Scp939/PlayingFootstep.cs | 79 +++++++++++++++++++ 3 files changed, 147 insertions(+) create mode 100644 EXILED/Exiled.Events/EventArgs/Scp939/PlayingFootstepEventArgs.cs create mode 100644 EXILED/Exiled.Events/Patches/Events/Scp939/PlayingFootstep.cs diff --git a/EXILED/Exiled.Events/EventArgs/Scp939/PlayingFootstepEventArgs.cs b/EXILED/Exiled.Events/EventArgs/Scp939/PlayingFootstepEventArgs.cs new file mode 100644 index 000000000..bf0ed25c6 --- /dev/null +++ b/EXILED/Exiled.Events/EventArgs/Scp939/PlayingFootstepEventArgs.cs @@ -0,0 +1,57 @@ +// ----------------------------------------------------------------------- +// +// Copyright (c) Exiled Team. All rights reserved. +// Licensed under the CC BY-SA 3.0 license. +// +// ----------------------------------------------------------------------- + +namespace Exiled.Events.EventArgs.Scp939 +{ + using API.Features; + using Exiled.API.Features.Roles; + using Interfaces; + + /// + /// Contains all information before the footsteps are being shown to SCP-939. + /// + public class PlayingFootstepEventArgs : IScp939Event, IDeniableEvent + { + /// + /// Initializes a new instance of the class. + /// + /// + /// The player who's controlling SCP-939. + /// + /// + /// The player who's being shown to SCP-939. + /// + /// + /// Indicates whether the footstep action is allowed. + /// + public PlayingFootstepEventArgs(Player target, Player player, bool isAllowed = true) + { + Player = player; + Scp939 = Player.Role.As(); + Target = target; + IsAllowed = isAllowed; + } + + /// + /// Gets the player who's controlling SCP-939. + /// + public Player Player { get; } + + /// + public Scp939Role Scp939 { get; } + + /// + /// Gets the player who's being shown to SCP-939. + /// + public Player Target { get; } + + /// + /// Gets or sets a value indicating whether footsteps are visible. + /// + public bool IsAllowed { get; set; } + } +} diff --git a/EXILED/Exiled.Events/Handlers/Scp939.cs b/EXILED/Exiled.Events/Handlers/Scp939.cs index e8c582d36..14d1245c6 100644 --- a/EXILED/Exiled.Events/Handlers/Scp939.cs +++ b/EXILED/Exiled.Events/Handlers/Scp939.cs @@ -37,6 +37,11 @@ public static class Scp939 /// public static Event PlayingVoice { get; set; } = new(); + /// + /// Invoked before footstep displayed to SCP-939. + /// + public static Event PlayingFootstep { get; set; } = new(); + /// /// Invoked before SCP-939 will save Human voice. /// @@ -94,6 +99,12 @@ public static class Scp939 /// The instance. public static void OnPlayingSound(PlayingSoundEventArgs ev) => PlayingSound.InvokeSafely(ev); + /// + /// Called before footstep displayed to SCP-939. + /// + /// The instance. + public static void OnPlayingFootstep(PlayingFootstepEventArgs ev) => PlayingFootstep.InvokeSafely(ev); + /// /// Called after SCP-939 attacks. /// diff --git a/EXILED/Exiled.Events/Patches/Events/Scp939/PlayingFootstep.cs b/EXILED/Exiled.Events/Patches/Events/Scp939/PlayingFootstep.cs new file mode 100644 index 000000000..6bfdfa41c --- /dev/null +++ b/EXILED/Exiled.Events/Patches/Events/Scp939/PlayingFootstep.cs @@ -0,0 +1,79 @@ +// ----------------------------------------------------------------------- +// +// Copyright (c) Exiled Team. All rights reserved. +// Licensed under the CC BY-SA 3.0 license. +// +// ----------------------------------------------------------------------- + +namespace Exiled.Events.Patches.Events.Scp939 +{ + using System.Collections.Generic; + using System.Reflection.Emit; + + using Exiled.API.Features.Pools; + using Exiled.Events.Attributes; + using Exiled.Events.EventArgs.Scp939; + using Exiled.Events.Handlers; + + using HarmonyLib; + using PlayerRoles.FirstPersonControl.Thirdperson; + using PlayerRoles.PlayableScps.Scp939; + using PlayerRoles.PlayableScps.Scp939.Ripples; + using PlayerRoles.Subroutines; + + using static HarmonyLib.AccessTools; + + /// + /// Patches + /// to add the event. + /// + [EventPatch(typeof(Scp939), nameof(Scp939.PlayingFootstep))] + [HarmonyPatch(typeof(FootstepRippleTrigger), nameof(FootstepRippleTrigger.OnFootstepPlayed))] + internal static class PlayingFootstep + { + private static IEnumerable Transpiler(IEnumerable instructions, ILGenerator generator) + { + List newInstructions = ListPool.Pool.Get(instructions); + + Label ret = generator.DefineLabel(); + + int offset = 3; + int index = newInstructions.FindLastIndex(i => i.Calls(Method(typeof(RippleTriggerBase), nameof(RippleTriggerBase.CheckVisibility)))) + offset; + + newInstructions.InsertRange(index, new CodeInstruction[] + { + // Player target = Player.Get(characterModel.OwnerHub); + new CodeInstruction(OpCodes.Ldarg_1).MoveLabelsFrom(newInstructions[index]), + new(OpCodes.Callvirt, PropertyGetter(typeof(CharacterModel), nameof(CharacterModel.OwnerHub))), + new(OpCodes.Call, Method(typeof(API.Features.Player), nameof(API.Features.Player.Get), new[] { typeof(ReferenceHub) })), + + // Player player = Player.Get(this.Owner); + new(OpCodes.Ldarg_0), + new(OpCodes.Call, PropertyGetter(typeof(StandardSubroutine), nameof(StandardSubroutine.Owner))), + new(OpCodes.Call, Method(typeof(API.Features.Player), nameof(API.Features.Player.Get), new[] { typeof(ReferenceHub) })), + + // true; + new(OpCodes.Ldc_I4_1), + + // PlayingFootstepEventArgs ev = (player, scp939, true); + new(OpCodes.Newobj, GetDeclaredConstructors(typeof(PlayingFootstepEventArgs))[0]), + new(OpCodes.Dup), + + // Handlers.Scp939.OnPlayingFootstep(ev); + new(OpCodes.Call, Method(typeof(Scp939), nameof(Scp939.OnPlayingFootstep))), + + // if (!IsAllowed) + // return; + new(OpCodes.Callvirt, PropertyGetter(typeof(PlayingFootstepEventArgs), nameof(PlayingFootstepEventArgs.IsAllowed))), + new(OpCodes.Brfalse_S, ret), + }); + + newInstructions[newInstructions.Count - 1].labels.Add(ret); + + for (int z = 0; z < newInstructions.Count; z++) + yield return newInstructions[z]; + + ListPool.Pool.Return(newInstructions); + } + } +} From 996cd0abad97383304eb9e3ea1088d6eac43410d Mon Sep 17 00:00:00 2001 From: Misaka-ZeroTwo <45165615+Misaka-ZeroTwo@users.noreply.github.com> Date: Sun, 21 Jul 2024 14:48:35 +0800 Subject: [PATCH 14/58] Update release.yml --- .github/workflows/release.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 035650f02..bcbe907cc 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -11,7 +11,7 @@ defaults: working-directory: ./EXILED env: - EXILED_REFERENCES_URL: https://Exiled-Official.github.io/SL-References/Master.zip + EXILED_REFERENCES_URL: https://Exiled-Official.github.io/SL-References/Dev.zip EXILED_REFERENCES_PATH: ${{ github.workspace }}/EXILED/References EXILED_DLL_ARCHIVER_URL: https://github.com/Exiled-Official/EXILED-DLL-Archiver/releases/latest/download/EXILED-DLL-Archiver.exe From 74c22803082f2eb67c60f88ae8607d26de97bbeb Mon Sep 17 00:00:00 2001 From: Jesus QC <69375249+Jesus-QC@users.noreply.github.com> Date: Mon, 22 Jul 2024 02:18:00 +0200 Subject: [PATCH 15/58] fetching master (#132) Co-authored-by: Nameless <85962933+Misfiy@users.noreply.github.com> Co-authored-by: Misaka-ZeroTwo <45165615+Misaka-ZeroTwo@users.noreply.github.com> --- .github/workflows/release.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 035650f02..bcbe907cc 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -11,7 +11,7 @@ defaults: working-directory: ./EXILED env: - EXILED_REFERENCES_URL: https://Exiled-Official.github.io/SL-References/Master.zip + EXILED_REFERENCES_URL: https://Exiled-Official.github.io/SL-References/Dev.zip EXILED_REFERENCES_PATH: ${{ github.workspace }}/EXILED/References EXILED_DLL_ARCHIVER_URL: https://github.com/Exiled-Official/EXILED-DLL-Archiver/releases/latest/download/EXILED-DLL-Archiver.exe From 42346565e83869956f78c27a22f83f0e4f6e5790 Mon Sep 17 00:00:00 2001 From: Jesus QC <69375249+Jesus-QC@users.noreply.github.com> Date: Mon, 22 Jul 2024 13:37:41 +0200 Subject: [PATCH 16/58] DocFX Reimplementation (#131) --- .github/workflows/docs.yml | 100 +++++----- EXILED/docs/articles/contributing/index.md | 38 ++++ EXILED/docs/articles/index.md | 49 +++++ .../articles/installation/automatic/linux.md | 43 +++++ .../installation/automatic/windows.md | 43 +++++ EXILED/docs/articles/installation/index.md | 15 ++ EXILED/docs/articles/installation/manual.md | 24 +++ EXILED/docs/articles/plugins/events.md | 61 +++++++ EXILED/docs/articles/plugins/mec.md | 49 +++++ EXILED/docs/articles/plugins/structure.md | 172 ++++++++++++++++++ EXILED/docs/articles/toc.yml | 21 +++ EXILED/docs/assets/exiled.png | Bin 0 -> 852 bytes EXILED/docs/assets/favicon.ico | Bin 0 -> 251966 bytes EXILED/docs/docfx.json | 60 ++++++ EXILED/docs/filterConfig.yml | 10 + EXILED/docs/index.md | 16 ++ EXILED/docs/toc.yml | 6 + 17 files changed, 662 insertions(+), 45 deletions(-) create mode 100644 EXILED/docs/articles/contributing/index.md create mode 100644 EXILED/docs/articles/index.md create mode 100644 EXILED/docs/articles/installation/automatic/linux.md create mode 100644 EXILED/docs/articles/installation/automatic/windows.md create mode 100644 EXILED/docs/articles/installation/index.md create mode 100644 EXILED/docs/articles/installation/manual.md create mode 100644 EXILED/docs/articles/plugins/events.md create mode 100644 EXILED/docs/articles/plugins/mec.md create mode 100644 EXILED/docs/articles/plugins/structure.md create mode 100644 EXILED/docs/articles/toc.yml create mode 100644 EXILED/docs/assets/exiled.png create mode 100644 EXILED/docs/assets/favicon.ico create mode 100644 EXILED/docs/docfx.json create mode 100644 EXILED/docs/filterConfig.yml create mode 100644 EXILED/docs/index.md create mode 100644 EXILED/docs/toc.yml diff --git a/.github/workflows/docs.yml b/.github/workflows/docs.yml index e22c60eb2..351cdd3be 100644 --- a/.github/workflows/docs.yml +++ b/.github/workflows/docs.yml @@ -4,55 +4,65 @@ on: push: branches: - master - pull_request: - branches: - - master -defaults: - run: - working-directory: ./EXILED +# Sets permissions of the GITHUB_TOKEN to allow deployment to GitHub Pages +permissions: + actions: read + pages: write + id-token: write env: - EXILED_REFERENCES_URL: https://misaka-zerotwo.github.io/SL-References/Master.zip + EXILED_REFERENCES_URL: https://Exiled-Official.github.io/SL-References/Dev.zip EXILED_REFERENCES_PATH: ${{ github.workspace }}/EXILED/References + +# Allow only one concurrent deployment, skipping runs queued between the run in-progress and latest queued. +# However, do NOT cancel in-progress runs as we want to allow these production deployments to complete. +# Important due to https://t.ly/5DZAy +concurrency: + group: "pages" + cancel-in-progress: false jobs: - build_and_publish_docs: - runs-on: windows-latest - + publish-docs: + environment: + name: github-pages + url: ${{ steps.deployment.outputs.page_url }} + + runs-on: ubuntu-latest + steps: - - name: Checkout - uses: actions/checkout@v2.3.4 - - - name: Setup .NET Core SDK - uses: actions/setup-dotnet@v1.7.2 - - - name: Setup Nuget - uses: iRebbok/setup-nuget@master - - - name: Get references - shell: pwsh - run: | - Invoke-WebRequest -Uri ${{ EXILED_REFERENCES_URL }} -OutFile ${{ github.workspace }}/EXILED/References.zip - Expand-Archive -Path References.zip -DestinationPath ${{ env.EXILED_REFERENCES_PATH }} - - - name: Download DocFX - uses: crazy-max/ghaction-chocolatey@v1 - with: - args: install docfx --pre - - - name: Run DocFX - env: - EXILED_REFERENCES: ${{ env.EXILED_REFERENCES_PATH }} - run: docfx docfx.json; docfx docfx.json - - - name: Deploy to GitHub Pages - if: github.event_name == 'push' && success() #Only publishes on push to master to avoid docs mishaps - uses: crazy-max/ghaction-github-pages@v2 - with: - target_branch: gh-pages - build_dir: _site - keep_history: true - jekyll: false - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + - name: Checkout + uses: actions/checkout@v3 + + - name: Dotnet Setup + uses: actions/setup-dotnet@v3 + with: + dotnet-version: 8.x + + - run: dotnet tool update -g docfx + + - name: Setup .NET Core SDK + uses: actions/setup-dotnet@v1.7.2 + + - name: Setup Nuget + uses: iRebbok/setup-nuget@master + + - name: Get references + shell: pwsh + run: | + Invoke-WebRequest -Uri $env:EXILED_REFERENCES_URL -OutFile $env:GITHUB_WORKSPACE/EXILED/References.zip + Expand-Archive -Path $env:GITHUB_WORKSPACE/EXILED/References.zip -DestinationPath $env:EXILED_REFERENCES_PATH + + - run: docfx EXILED/docs/docfx.json + env: + EXILED_REFERENCES: ${{ env.EXILED_REFERENCES_PATH }} + + - name: Upload artifact + uses: actions/upload-pages-artifact@v3 + with: + # Upload entire repository + path: 'EXILED/docs/_site' + + - name: Deploy to GitHub Pages + id: deployment + uses: actions/deploy-pages@v4 diff --git a/EXILED/docs/articles/contributing/index.md b/EXILED/docs/articles/contributing/index.md new file mode 100644 index 000000000..021e1baa6 --- /dev/null +++ b/EXILED/docs/articles/contributing/index.md @@ -0,0 +1,38 @@ +--- +title: Contributing to EXILED +--- +# Contributing to EXILED + +This is a simple tutorial guiding you to contribute to our framework. + +### Forking EXILED +First, create a fork of our [GitHub repository](https://github.com/Exiled-Official/EXILED). + +Then, clone it to your computer like so: `git clone https://github.com/your-username/EXILED.git` + +Open a terminal in your forked EXILED folder and run ```git checkout dev```. This will switch you to the dev branch, which all pull requests should be submitted to. + +### Setting `EXILED_REFERENCES` + +If you haven't already, install the `SCP: Secret Laboratory Dedicated Server` through Steam or extract [this zip file](https://Exiled-Official.github.io/SL-References/Dev.zip) to an easily accessible folder. + +#### Windows users +Open the Environment Variables menu by searching for `Environment Variables` in the Start Menu. + +Create a new environment variable titled `EXILED_REFERENCES`. + +The value should point to `your_steamapps_directory/common/SCP Secret Laboratory Dedicated Server/SCPSL_Data/Managed`, or to the folder where you extracted the zip file mentioned earlier. + +#### Linux users +Add `export EXILED_REFERENCES="PATH"` to your `~/.bashrc` or similar file. + +PATH should point to `your_steamapps_directory/common/SCP Secret Laboratory Dedicated Server/SCPSL_Data/Managed`, or to the folder where you extracted the zip file mentioned earlier. + +--- + +You should now be able to open the EXILED directory in your favorite IDE. + + +Once you are done, test your changes thoroughly, and then submit a pull request to the main EXILED repository. Make sure you are targeting the `dev` branch, not `master`! + +Happy coding! \ No newline at end of file diff --git a/EXILED/docs/articles/index.md b/EXILED/docs/articles/index.md new file mode 100644 index 000000000..48ce7e0e1 --- /dev/null +++ b/EXILED/docs/articles/index.md @@ -0,0 +1,49 @@ +--- +title: Introduction +--- + +# Exiled Introduction + +## About EXILED + +**EXILED** is a low level plugin framework for SCP: Secret Laboratory. + +It offers an event system for developers to hook in order to manipulate or change game code, or implement their own functions. + +All **EXILED** events are coded with [Harmony](https://harmony.pardeike.net/) using IL transpilers, meaning they require no direct editing of server Assemblies to function, which allows for two unique benefits. + +- The entirety of the frameworks code can be freely published and shared. Allowing developers to better understand how it works, as well as contributing to the framework itself. +- Since all of the code related to the framework is done outside of the server assembly, things like small game updates will have little, if any, effect on the framework. + +--- + +# Frequently Asked Questions + +## What is EXILED? +EXILED - short for "EXtended In-runtime Library for External Development" is a plugin framework for SCP: Secret Laboratory compatible with MP2. It is not a direct replacement for SMOD, but it's purpose is to implement an event-based framework using Harmony patches, that plugin developers can utilize to develop plugins for SCP:SL servers. + +## How do I install EXILED? +See the [Installation](https://jesus-qc.github.io/EXILED/articles/installation/index.html) page for installation information. + +## How do I install plugins? +All plugins contain a DLL file (found in its latest release) that is used to load the plugin. Place the plugin in the appropriate plugin folder. +- Windows: `%AppData%\EXILED\Configs(ServerPortHere)-configs.yml` +- Linux: `~/.config/EXILED/Configs(ServerPortHere)-configs.yml` + +## Where is plugin configuration stored? +Plugin configuration is stored in a separate folder than the base-game config files. +- Windows: `%AppData%\EXILED\Plugins` +- Linux: `~/.config/EXILED/Plugins` + +## Is there a plugin for upgrading items in hand, inside SCP-914? +No, this is unnecessary because this is a base-game feature! Simply set the `914_mode` config_gameplay config to `DroppedAndHeld`. + +## What is Harmony? +Harmony is a library that examines the code of a program as it is being run, allowing developers to tap into those functions, and run their own code, either adding onto, or completely replacing, the code the program would normally run. + + +The reason EXILED uses harmony is to allow easier updating of the framework in conjunction with game updates. Under ideal circumstances, a new game update will not break EXILED itself, and the only thing needed to make EXILED work again, is a very simple copy/paste of a few lines of code into the new Assembly-CSharp file. + + +By keeping all of our code outside of the Assembly, other developers can have full, unhindered access to the entirety of EXILED's source code, making collaboration easier.
+Additionally, it means that our code will be mostly unaffected by game updates. Unless the game drastically changes code in a very specific function EXILED uses for an event patch, a game update may not even require EXILED itself to also be updated. diff --git a/EXILED/docs/articles/installation/automatic/linux.md b/EXILED/docs/articles/installation/automatic/linux.md new file mode 100644 index 000000000..2bd2e6934 --- /dev/null +++ b/EXILED/docs/articles/installation/automatic/linux.md @@ -0,0 +1,43 @@ +--- +title: Automatic Linux Installation +--- + +# Automatic Linux Installation + +Download `Exiled.Installer-Linux` from [here](https://github.com/Exiled-Official/EXILED/releases). + +Move it into your **server directory** and run it using `./Exiled.Installer-Linux` +- Make sure the server directory is the one where LocalAdmin executable is found. + +#### Usage +``` +Usage: + Exiled.Installer [options] [[--] ...]] + +Options: + -p, --path (REQUIRED) Path to the folder with the SL server [default: YourWorkingFolder] + --appdata (REQUIRED) Forces the folder to be the AppData folder (useful for containers when pterodactyl runs as root) [default: YourAppDataPath] + --pre-releases Includes pre-releases [default: False] + --target-version Target version for installation + --github--token Uses a token for auth in case the rate limit is exceeded (no permissions required) + --exit Automatically exits the application anyway + --get-versions Gets all possible versions for installation + --version Show version information + -?, -h, --help Show help and usage information + +Additional Arguments: + Arguments passed to the application that is being run. +``` + +----- + +#### Examples + +- ##### Installation in a specific folder, specific version and specific appdata folder +```powershell title="Basic installation in the folder you are in" +.\Exiled.Installer-Linux --pre-releases +``` + +```powershell title="Installation in a specific folder, specific version and specific appdata folder" +.\Exiled.Installer-Linux -p /home/user/scpsl/server --appdata /home/user/scpsl --target-version 2.0.8 +``` \ No newline at end of file diff --git a/EXILED/docs/articles/installation/automatic/windows.md b/EXILED/docs/articles/installation/automatic/windows.md new file mode 100644 index 000000000..d28ba2449 --- /dev/null +++ b/EXILED/docs/articles/installation/automatic/windows.md @@ -0,0 +1,43 @@ +--- +title: Automatic Windows Installation +--- + +# Automatic Windows Installation + +Download `Exiled.Installer-Win.exe` from [here](https://github.com/Exiled-Official/EXILED/releases). + +Move it into your **server directory** and double click the .exe. +- Make sure the server directory is the one where LocalAdmin.exe is found. + +#### Usage +``` +Usage: + Exiled.Installer [options] [[--] ...]] + +Options: + -p, --path (REQUIRED) Path to the folder with the SL server [default: YourWorkingFolder] + --appdata (REQUIRED) Forces the folder to be the AppData folder (useful for containers when pterodactyl runs as root) [default: YourAppDataPath] + --pre-releases Includes pre-releases [default: False] + --target-version Target version for installation + --github--token Uses a token for auth in case the rate limit is exceeded (no permissions required) + --exit Automatically exits the application anyway + --get-versions Gets all possible versions for installation + --version Show version information + -?, -h, --help Show help and usage information + +Additional Arguments: + Arguments passed to the application that is being run. +``` + +----- + +#### Examples +Using powershell. + +```powershell title="Basic installation in the folder you are in" +.\Exiled.Installer-Win --pre-releases +``` + +```powershell title="Installation in a specific folder, specific version and specific appdata folder" +.\Exiled.Installer-Win -p D:\Games\SCPSL\Server --appdata C --target-version 2.0.8 +``` \ No newline at end of file diff --git a/EXILED/docs/articles/installation/index.md b/EXILED/docs/articles/installation/index.md new file mode 100644 index 000000000..dba236d2c --- /dev/null +++ b/EXILED/docs/articles/installation/index.md @@ -0,0 +1,15 @@ +--- +title: Installing EXILED +--- + +# Installing EXILED + +## Automatic Installation + +Exiled has a tool that allows you to install **automatically** the framework for you. + +## Guides + +- [Window Automatic Installation](/EXILED/articles/installation/automatic/windows.html). +- [Linux Automatic Installation](/EXILED/articles/installation/automatic/linux.html). +- [Manual Installation](EXILED/articles/installation/manual.html). \ No newline at end of file diff --git a/EXILED/docs/articles/installation/manual.md b/EXILED/docs/articles/installation/manual.md new file mode 100644 index 000000000..650f02fbc --- /dev/null +++ b/EXILED/docs/articles/installation/manual.md @@ -0,0 +1,24 @@ +--- +title: Manual Installation +--- + +# Manual Installation + +You can download exiled manually following this steps: + +### Pick a release + +You can select a release inside [our official GitHub repo](https://github.com/Exiled-Official/EXILED/releases/). + +### Download the release + +Download the `Exiled.tar.gz` file and extract it with your favourite tool, we recommend [7Zip](https://www.7-zip.org/) or [WinRar](https://www.win-rar.com/download.html?&L=6). + +### Installation + +1. Move the file **``Assembly-CSharp.dll``** to: **`(Your Server Folder)/SCPSL_Data/Managed`** and replace the file. +2. Move the **``EXILED``** folder to **`%appdata%`** + +#### Note: +- Windows: This **`%appdata%`** folder is the one located inside **`AppData/Roaming`**, not just `AppData`. +- Linux: This **`%appdata%`** folder is the one called **`~/.config`**. \ No newline at end of file diff --git a/EXILED/docs/articles/plugins/events.md b/EXILED/docs/articles/plugins/events.md new file mode 100644 index 000000000..8bd83cc15 --- /dev/null +++ b/EXILED/docs/articles/plugins/events.md @@ -0,0 +1,61 @@ +--- +title: Events +--- + +This tutorial assumes that you are familiar with C# and with setting up a plugin in the EXILED framework. See the tutorial if you are unfamiliar with setting up a plugin using EXILED. + +# Events: What are they? +**Events** play a key role in the EXILED framework and all of the plugins utilizing it. Almost every plugin created using the EXILED framework uses events in one way or another. So, what are they? An event is a simple way of being informed when *something* happens. Events range from the round ending, to a player throwing an item or opening a door, to even SCP-096 being enraged! Events allow you to attach code that executes when something occurs before, during, or at the conclusion of a round. + +For example, say that you have the following method. + +```cs +public void OnDead() +{ + // Show hint to player. +} +``` + +With EXILED, it is possible to achieve the desired result: Showing a hint to a player who dies. + +## Event structure +The EXILED framework consists of two different types of events: Events that can be disallowed, and those that cannot. Events that can be disallowed can prevent certain events from happening; as an example, preventing a player from dying when they normally should. The ability to prevent certain events from happening is what gives EXILED its beauty. + +All events are part of a static class called a **handler**. All handlers can be found in the `Exiled.Events` namespace. Every handler is related to a specific feature in the game (eg. `Exiled.Events.Scp096` contains SCP-096 related events). + +Almost all events have a corresponding **event argument** class. The event argument provides the data of an event, as well as the ability to prevent it from occurring. All event arguments can be found in the `Exiled.Events.EventArgs` namespace, and all event arguments inherit from `System.EventArgs`. + +### Example: Enraging event +The following is the structure of the `Exiled.Events.EventArgs.EnragingEventArgs`. +```cs +public class EnragingEventArgs : System.EventArgs +{ + // Note: Constructor omitted. + public Scp096 Scp096 { get; } // The SCP-096 instance. + public Player Player { get; } // The player controlling SCP-096. + public bool IsAllowed { get; set; } // Whether or not SCP-096 can be enraged. +} +``` +Notice the `IsAllowed` property of the event. This property, which defaults to `true`, can be set to `false` to prevent SCP-096 from being enraged. For most events that can be disallowed, `IsAllowed` is set to `true` by default, and plugins can set it to `false` to prevent the event from occurring. However, in some cases, `IsAllowed` defaults to false and plugins can set it to `true` to *allow* the event to occur. An example of this behavior is the `InteractingDoor` event. `IsAllowed` will default to `false` in this event if a player cannot open a door, however plugins may set it to `true` to allow the player to open it regardless. + +## Connecting events +Events can be connected and disconnected by using the `+=` and `-=` operators. These can be used in the plugin's `OnEnabled` and `OnDisabled` methods, respectively. +```cs +// Base plugin class +// This example assumes a method called "OnEnraging" exists in this class. For best practice, you should create a new class to handle events. +using Exiled.Events; +public override void OnEnabled() +{ + Scp096.Enraging += OnEnraging; // Scp096 is the event handler, while Enraging is the name of the event. The += operator connects this event to the provided method. +} +public override void OnDisabled() +{ + Scp096.Enraging -= OnEnraging; // The -= operator disconnects this event from the provided method. +} +// Some other class +using Exiled.Events.EventArgs; +public void OnEnraging(EnragingEventArgs ev) // ev is the arguments for the event. Every event has a different argument class with different parameters, so make sure to check its documentation. +{ + Log.Info(ev.Player.Nickname + " has just been enraged!"); +} +``` \ No newline at end of file diff --git a/EXILED/docs/articles/plugins/mec.md b/EXILED/docs/articles/plugins/mec.md new file mode 100644 index 000000000..af80eb0c7 --- /dev/null +++ b/EXILED/docs/articles/plugins/mec.md @@ -0,0 +1,49 @@ +--- +title: MEC (More Effective Coroutines) +--- + +This tutorial assumes that you are familiar with C# and with setting up a plugin in the EXILED framework. See the Plugin Structure tutorial if you are unfamiliar with setting up a plugin using **EXILED**. + +# MEC (More Effective Coroutines) +If you are unfamiliar with MEC, this will be a very brief and simple primer to get you started. **MEC Coroutines** are basically timed methods, that support waiting periods of time before continuing execution, without interrupting/sleeping the main game thread. MEC coroutines are safe to use with Unity, unlike traditional threading, which *will* crash the server. + +MEC is useful for plugins which require a pre-defined timeout between execution. As an example, an automatic nuke plugin would want to pause for a certain amount of seconds before activating the warhead. A supply drop plugin would want to wait in certain intervals before executing a supply drop. Both of these are possible with MEC. + +## Setup +Unlike other API provided by SCP:SL, MEC requires a reference to the `Assembly-CSharp-firstpass` DLL file. After referencing this file, a `using MEC;` statement allows MEC to be used. + +## Coroutine +MEC offers [tons of features](http://trinary.tech/category/mec/free/) for controlling threads. For this tutorial, we are going to look at two of them: coroutines, and delayed calls. A coroutine is a method that is executed by MEC and supports delays. These methods must return type `IEnumerator` and must be called by `Timing.RunCoroutine(Method())`. An example can be seen below, using an infinite loop with a 5 second delay. + +```cs +using MEC; +using Exiled.API.Features; +public void SomeMethod() +{ + Timing.RunCoroutine(MyCoroutine()); +} +public IEnumerator MyCoroutine() +{ + for (;;) //repeat the loop infinitely + { + Log.Info("Hey, I'm a infinite loop!"); //Call Log.Info to print a line to the game console/server logs. + yield return Timing.WaitForSeconds(5f); //Tells the coroutine to wait 5 seconds before continuing. Since this is at the end of the loop, it effectively stalls the loop from repeating for 5 seconds. + } +} +``` +This example prints, "Hey, I'm an infinite loop!" every 5 seconds infinitely. Coroutines can have multiple `yield return` statements. + +## Delayed Calls +A simpler method of running an action after a delay is using `Timing.CallDelayed(float, Action)`, which executes code after a given number of seconds passes. This method does not require a coroutine to be created, hence why it's useful. An example can be seen below, logging a message 5 seconds after the method is called. +```cs +using MEC; +using Exiled.API.Features; +public void SomeMethod() +{ + Timing.CallDelayed(5f, () => // Execute the provided method 5 seconds late. + { + Log.Info("This log was printed 5 seconds late!"); + }) +} +``` +It is ***strongly*** recommended that you do some googling, or ask around **[in the EXILED Discord server](https://discord.gg/PyUkWTg)** if you are unfamiliar with MEC and would like to learn more, get advice, or need help. Questions, no matter how 'stupid' they are, will always be answered as helpfully and clearly as possible for plugin developers to excel. Better code is better for everyone. diff --git a/EXILED/docs/articles/plugins/structure.md b/EXILED/docs/articles/plugins/structure.md new file mode 100644 index 000000000..7a0d5997d --- /dev/null +++ b/EXILED/docs/articles/plugins/structure.md @@ -0,0 +1,172 @@ +--- +title: Plugin Structure +--- + +This tutorial assumes that you are familiar with C#. + +### Plugin Structure +In order to be loaded onto the framework, *every* plugin must follow a certain structure and inherit from certain members. If this is not achieved, the plugin will not execute. This tutorial will explain the proper setup for a plugin on the EXILED framework. + +## Plugin Core +Every plugin must have a .cs file that consists of the plugin class itself. This file (and the class itself) are typically simply named "Plugin"; however, any name is appropriate for the main plugin class. This example will use "Plugin" as the name of the class. + +After the main file is created, the Plugin class must be declared as a plugin, so that the EXILED framework loads it. This can be done by inheriting the `Plugin` class, provided in the `Exiled.API.Features` namespace. + +The following example shows how to properly inherit the class. However, notice the `Config` class inside of the angled brackets. This class must be created and must inherit from `IConfig`, which is part of the `Exiled.API.Interfaces` namespace. Upon the creation of the Config class, the interface will require you to add an `IsEnabled` property. +```cs +namespace MyPluginNamespace +{ + using Exiled.API.Features; + public class Plugin : Plugin + { + // This plugin will now be recognized by the EXILED framework! + } + // It is strongly encouraged to create a separate file for your Config class. + using Exiled.API.Interfaces; + public class Config : IConfig + { + public bool IsEnabled { get; set; } + } +} +``` +By creating the `Config` class and including it in the angled brackets, the rest of the plugin's code, as well as the EXILED framework, will recognize that the class resembles configuration for server owners. For more information about setting up configuration, see the Configuration section below. + +## OnEnabled and OnDisabled +The plugin is now successfully loaded onto the framework. However, it doesn't actually do anything; no functionality has been assigned. The `Plugin` class provides two overridable methods in order to give the plugin functionality: `OnEnabled` and `OnDisabled`. These two methods do exactly as they sound: Execute when the plugin is enabled/loaded, and when it is disabled. + +The following example shows how to utilize these methods to send a message to the console. +```cs +namespace MyPluginNamespace +{ + using Exiled.API.Features; + public class Plugin : Plugin + { + public override void OnEnabled() + { + Log.Info("My plugin has been enabled!"); + } + public override void OnDisabled() + { + Log.Info("My plugin has been disabled!"); + } + } + // Config.cs file + using Exiled.API.Interfaces; + public class Config : IConfig + { + public bool IsEnabled { get; set; } + } +} +``` +All of the code for the plugin *must* be enabled in the OnEnabled method, and *must* be disabled on the OnDisabled method. It is important that these two methods execute as expected, because server hosts can enable and disable plugins as much as they'd like, and the plugin *must* be able to respond to these changes appropriately. + +## Plugin Data +In order for a plugin to be submitted for public use, the plugin must override three properties: `Name`, `Author`, and `Version`. The first two are strings, whereas the last one is a `Version` class (`using System;` is required). + +The following example shows how to properly override this data. +```cs +namespace MyPluginNamespace +{ + using System; + using Exiled.API.Features; + public class Plugin : Plugin + { + public override string Name => "My Awesome Plugin"; + public override string Author => "MyName"; + public override Version Version => new Version(1, 0, 0); + } + // ... +} +``` + +## Configuration +This section is related to creating and reading the value of configuration. + +### Creating Configs +A lot of plugins provide configuration to allow the server hosts to change various features of the plugin. Luckily, creating configuration is very simple. + +To start, take a look at your Config.cs file. +```cs +namespace MyPluginNamespace +{ + using Exiled.API.Interfaces; + public class Config : IConfig + { + public bool IsEnabled { get; set; } + } +} +``` +There is currently one config, called `IsEnabled`. As stated above, this config is required and cannot be removed. However, more config can be added. The YAML serialization allows almost any type to be added and still work, including bools, ints, arrays of anything, enums, and even whole classes! + +In the following example, a config file with three configs is created. +```cs +namespace MyPluginNamespace +{ + using Exiled.API.Interfaces; + public class Config : IConfig + { + public bool IsEnabled { get; set; } + public bool MyBoolConfig { get; set; } + public string MyStringConfig { get; set; } + public int MyIntConfig { get; set; } = 5; // Set to 5 by default. + } +} +``` +To server hosts, the functionality of these configs might be confusing at first. So, the `System.ComponentModel.DescriptionAttribute` can be used to provide a description for each config! +```cs +namespace MyPluginNamespace +{ + using System.ComponentModel; + using Exiled.API.Interfaces; + public class Config : IConfig + { + [Description("Whether or not the plugin is enabled.")] + public bool IsEnabled { get; set; } + [Description("Config that must be true or false!")] + public bool MyBoolConfig { get; set; } + [Description("Config that must be a string!")] + public string MyStringConfig { get; set; } + [Description("Config that must be a number! Defaults to 5.")] + public int MyIntConfig { get; set; } = 5; + } +} +``` + +### Reading Configs +> [!NOTE] +> You do not need to read the value of the `IsEnabled` config; EXILED will automatically prevent your plugin from executing if its `IsEnabled` config is set to false. + + +Reading configuration is more simple than creating it. The base `Plugin` class provides a property, called `Config`, which can be used to access these values. + +In the following example, our config from the previous class is displayed when the plugin starts. +```cs +namespace MyPluginNamespace +{ + using Exiled.API.Features; + public class Plugin : Plugin + { + public override void OnEnabled() + { + Log.Info("Boolean config: " + Config.MyBoolConfig); + Log.Info("String config: " + Config.MyStringConfig); + Log.Info("Int config: " + Config.MyIntConfig); + } + } + // Config.cs file + using System.ComponentModel; + using Exiled.API.Interfaces; + public class Config : IConfig + { + [Description("Whether or not the plugin is enabled.")] + public bool IsEnabled { get; set; } + [Description("Config that must be true or false!")] + public bool MyBoolConfig { get; set; } + [Description("Config that must be a string!")] + public string MyStringConfig { get; set; } + [Description("Config that must be a number! Defaults to 5.")] + public int MyIntConfig { get; set; } = 5; + } +} +``` + diff --git a/EXILED/docs/articles/toc.yml b/EXILED/docs/articles/toc.yml new file mode 100644 index 000000000..5b863000c --- /dev/null +++ b/EXILED/docs/articles/toc.yml @@ -0,0 +1,21 @@ +- name: Introduction + href: index.md +- name: Installation + href: installation/index.md + items: + - name: Automatic (Linux) + href: installation/automatic/linux.md + - name: Automatic (Windows) + href: installation/automatic/windows.md + - name: Manual + href: installation/manual.md +- name: Plugin Development + items: + - name: Plugin Structure + href: plugins/structure.md + - name: More Effective Coroutines + href: plugins/mec.md + - name: Events + href: plugins/events.md +- name: Contributing + href: contributing/index.md diff --git a/EXILED/docs/assets/exiled.png b/EXILED/docs/assets/exiled.png new file mode 100644 index 0000000000000000000000000000000000000000..b80bc81af4252754719707448abd06dc0aa7353a GIT binary patch literal 852 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 literal 0 HcmV?d00001 diff --git a/EXILED/docs/docfx.json b/EXILED/docs/docfx.json new file mode 100644 index 000000000..a84191683 --- /dev/null +++ b/EXILED/docs/docfx.json @@ -0,0 +1,60 @@ +{ + "metadata": [ + { + "src": [ + { + "files": [ + "**/*.csproj" + ], + "exclude": [ + "**/bin/**", + "**/obj/**" + ], + "src": "../" + } + ], + "dest": "api", + "filter": "filterConfig.yml", + "namespaceLayout": "nested", + } + ], + "build": { + "globalMetadata": { + "_appTitle": "EXILED", + "_appLogoPath": "assets/exiled.png", + "_appFaviconPath": "assets/favicon.ico", + "_enableSearch": true, + "_lang": "en", + "_gitContribute": { + "repo": "https://github.com/Exiled-Official/EXILED", + "branch": "dev" + } + }, + "template": ["default", "modern"], + "content": [ + { + "files": [ + "api/**.yml", + "api/index.md", + "toc.yml", + "*.md" + ] + }, + { + "files": [ + "articles/toc.yml", + "articles/**.md" + ] + } + ], + "resource": [ + { + "files": [ + "assets/**" + ] + } + ], + "dest": "_site", + "docfx": "SGVsbG8sIHRoaXMgd2FzIG1hZGUgYnkgamVzdXNxYywgaG9wZSB5b3UgYXJlIG5vdCBjb3B5aW5nIHRoaXMgYmVjYXVzZSBpdCB3b3VsZCBiZSBoaWxhcmlvdXMg8J+YrfCfmK3wn5it8J+YrQ==" + } +} diff --git a/EXILED/docs/filterConfig.yml b/EXILED/docs/filterConfig.yml new file mode 100644 index 000000000..1fa0a3ca9 --- /dev/null +++ b/EXILED/docs/filterConfig.yml @@ -0,0 +1,10 @@ +apiRules: + - exclude: + uidRegex: Exiled.Updater + type: Namespace + - exclude: + uidRegex: Exiled.Example + type: Namespace + - exclude: + uidRegex: Exiled.CreditTags + type: Namespace diff --git a/EXILED/docs/index.md b/EXILED/docs/index.md new file mode 100644 index 000000000..58917327b --- /dev/null +++ b/EXILED/docs/index.md @@ -0,0 +1,16 @@ +--- +title: Home +--- +# Exiled +Join our [Discord](https://discord.gg/PyUkWTg) for support. + +EXILED is a plugin framework for SCP: Secret Laboratory servers. It offers an event system for developers to hook into in order to manipulate or change game code or implement their own functions. + +## Support +We consistently deliver updates and releases to address bugs and introduce new features or contributions swiftly. + +## Community +We encourage developers to contribute actively rather than solely relying on Exiled, thereby boosting project activity. + +## Features +We offer diverse features, providing users with flexibility. These features are optional, catering to various needs. diff --git a/EXILED/docs/toc.yml b/EXILED/docs/toc.yml new file mode 100644 index 000000000..bbebe92c1 --- /dev/null +++ b/EXILED/docs/toc.yml @@ -0,0 +1,6 @@ +- name: Articles + href: articles/ +- name: API Documentation + href: api/Exiled.html +- name: Repository + href: https://github.com/Exiled-Official/EXILED From 887b6c40306f70abded5b8f0627b5873b57a86b1 Mon Sep 17 00:00:00 2001 From: Jesus QC <69375249+Jesus-QC@users.noreply.github.com> Date: Mon, 22 Jul 2024 13:37:58 +0200 Subject: [PATCH 17/58] [README] Design (#130) --- .github/README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/README.md b/.github/README.md index 76ea43932..038283f47 100644 --- a/.github/README.md +++ b/.github/README.md @@ -1,3 +1,4 @@ +
Exiled SCPSL, SCP Secret Laboratory Exiled, Exiled SCP: Secret Laboratory, Modding Framework, Mods, Exiled Mod SCPSL

Exiled

EXtended In-runtime Library for External Development
From 4ae0e0230bb1a97b540667fa17ba9335216aa369 Mon Sep 17 00:00:00 2001 From: Misaka-ZeroTwo <45165615+Misaka-ZeroTwo@users.noreply.github.com> Date: Tue, 23 Jul 2024 18:37:41 +0800 Subject: [PATCH 18/58] [CustomItems, Loader] Fix Null references (#135) Co-authored-by: Nameless <85962933+Misfiy@users.noreply.github.com> --- EXILED/Exiled.CustomItems/API/Features/CustomArmor.cs | 2 +- EXILED/Exiled.Loader/LoaderPlugin.cs | 6 ++++++ 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/EXILED/Exiled.CustomItems/API/Features/CustomArmor.cs b/EXILED/Exiled.CustomItems/API/Features/CustomArmor.cs index b41051f12..b50954d64 100644 --- a/EXILED/Exiled.CustomItems/API/Features/CustomArmor.cs +++ b/EXILED/Exiled.CustomItems/API/Features/CustomArmor.cs @@ -30,7 +30,7 @@ public override ItemType Type get => base.Type; set { - if (!value.IsArmor() && (value != ItemType.None)) + if (value != ItemType.None && !value.IsArmor()) throw new ArgumentOutOfRangeException("Type", value, "Invalid armor type."); base.Type = value; diff --git a/EXILED/Exiled.Loader/LoaderPlugin.cs b/EXILED/Exiled.Loader/LoaderPlugin.cs index 23dc888e2..ea9977fb4 100644 --- a/EXILED/Exiled.Loader/LoaderPlugin.cs +++ b/EXILED/Exiled.Loader/LoaderPlugin.cs @@ -38,6 +38,12 @@ public class LoaderPlugin [PluginPriority(byte.MinValue)] public void Enable() { + if (Config == null) + { + Log.Error("Detected null config, EXILED will not be loaded."); + return; + } + if (!Config.IsEnabled) { Log.Info("EXILED is disabled on this server via config."); From f28433e4d11f5dd49db6c87e1dd010c69473cd38 Mon Sep 17 00:00:00 2001 From: Jesus QC <69375249+Jesus-QC@users.noreply.github.com> Date: Wed, 24 Jul 2024 10:35:43 +0200 Subject: [PATCH 19/58] fetch (#136) Co-authored-by: Nameless <85962933+Misfiy@users.noreply.github.com> Co-authored-by: Misaka-ZeroTwo <45165615+Misaka-ZeroTwo@users.noreply.github.com> --- .github/README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/README.md b/.github/README.md index 76ea43932..038283f47 100644 --- a/.github/README.md +++ b/.github/README.md @@ -1,3 +1,4 @@ +
Exiled SCPSL, SCP Secret Laboratory Exiled, Exiled SCP: Secret Laboratory, Modding Framework, Mods, Exiled Mod SCPSL

Exiled

EXtended In-runtime Library for External Development
From 5eb907718d39e7fd92ce83e53c7f175e9c0e91ad Mon Sep 17 00:00:00 2001 From: Jesus QC <69375249+Jesus-QC@users.noreply.github.com> Date: Wed, 24 Jul 2024 10:36:28 +0200 Subject: [PATCH 20/58] Update README.md --- .github/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/README.md b/.github/README.md index 038283f47..4da34bd0b 100644 --- a/.github/README.md +++ b/.github/README.md @@ -112,5 +112,5 @@ Localized READMEs
-
This repo is a fork of Exiled-Team/EXILED after the old repository was taken hostage by the old lead developer.
+
This repo is a fork of Exiled-Team/EXILED after changes in project leadership.
You can access the commit this update was forked from here.
From b48c4ae43ccac8341ab91c6e3df835dcda4a0852 Mon Sep 17 00:00:00 2001 From: Jesus QC <69375249+Jesus-QC@users.noreply.github.com> Date: Wed, 24 Jul 2024 10:37:14 +0200 Subject: [PATCH 21/58] [README] CCBYSA3.0 --- .github/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/README.md b/.github/README.md index 038283f47..4da34bd0b 100644 --- a/.github/README.md +++ b/.github/README.md @@ -112,5 +112,5 @@ Localized READMEs -
This repo is a fork of Exiled-Team/EXILED after the old repository was taken hostage by the old lead developer.
+
This repo is a fork of Exiled-Team/EXILED after changes in project leadership.
You can access the commit this update was forked from here.
From 1ddf14c57abbdae3782d898c0fff93cc23a9a05b Mon Sep 17 00:00:00 2001 From: Jesus QC <69375249+Jesus-QC@users.noreply.github.com> Date: Wed, 24 Jul 2024 10:37:45 +0200 Subject: [PATCH 22/58] ccbysa3 (#137) Co-authored-by: Nameless <85962933+Misfiy@users.noreply.github.com> Co-authored-by: Misaka-ZeroTwo <45165615+Misaka-ZeroTwo@users.noreply.github.com> From abae896c23573678cd52e88a4975b5606346b346 Mon Sep 17 00:00:00 2001 From: Misaka-ZeroTwo <45165615+Misaka-ZeroTwo@users.noreply.github.com> Date: Fri, 26 Jul 2024 00:19:35 +0800 Subject: [PATCH 23/58] Update main.yml --- .github/workflows/main.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 7be77c41a..6f9bc0f85 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -13,7 +13,7 @@ defaults: working-directory: ./EXILED env: - EXILED_REFERENCES_URL: https://Exiled-Official.github.io/SL-References/Master.zip + EXILED_REFERENCES_URL: https://exmod-team.github.io/SL-References/Master.zip EXILED_REFERENCES_PATH: ${{ github.workspace }}/EXILED/References jobs: From 8d7dab9e1b01d22d5d0b20e42b22c6c4f3d09f53 Mon Sep 17 00:00:00 2001 From: Misaka-ZeroTwo <45165615+Misaka-ZeroTwo@users.noreply.github.com> Date: Fri, 26 Jul 2024 00:20:50 +0800 Subject: [PATCH 24/58] Update release.yml --- .github/workflows/release.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index bcbe907cc..efdac4cc8 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -11,9 +11,9 @@ defaults: working-directory: ./EXILED env: - EXILED_REFERENCES_URL: https://Exiled-Official.github.io/SL-References/Dev.zip + EXILED_REFERENCES_URL: https://exmod-team.github.io/SL-References/Dev.zip EXILED_REFERENCES_PATH: ${{ github.workspace }}/EXILED/References - EXILED_DLL_ARCHIVER_URL: https://github.com/Exiled-Official/EXILED-DLL-Archiver/releases/latest/download/EXILED-DLL-Archiver.exe + EXILED_DLL_ARCHIVER_URL: https://github.com/ExMod-Team/EXILED-DLL-Archiver/releases/latest/download/EXILED-DLL-Archiver.exe jobs: build: From 475db8c32b3e2d0ce0b0014b1cee25828063cfa1 Mon Sep 17 00:00:00 2001 From: Misaka-ZeroTwo <45165615+Misaka-ZeroTwo@users.noreply.github.com> Date: Fri, 26 Jul 2024 00:22:48 +0800 Subject: [PATCH 25/58] Update dev.yml --- .github/workflows/dev.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/dev.yml b/.github/workflows/dev.yml index 6a9486427..c1f7fe301 100644 --- a/.github/workflows/dev.yml +++ b/.github/workflows/dev.yml @@ -14,9 +14,9 @@ defaults: working-directory: ./EXILED env: - EXILED_REFERENCES_URL: https://Exiled-Official.github.io/SL-References/Dev.zip + EXILED_REFERENCES_URL: https://exmod-team.github.io/SL-Reference/Dev.zip EXILED_REFERENCES_PATH: ${{ github.workspace }}/EXILED/References - EXILED_DLL_ARCHIVER_URL: https://github.com/Exiled-Official/EXILED-DLL-Archiver/releases/latest/download/EXILED-DLL-Archiver.exe + EXILED_DLL_ARCHIVER_URL: https://github.com/ExMod-Team/EXILED-DLL-Archiver/releases/latest/download/EXILED-DLL-Archiver.exe jobs: From 4e7406bc6facb4d23ce1f3137577d7e31a48c863 Mon Sep 17 00:00:00 2001 From: Misaka-ZeroTwo <45165615+Misaka-ZeroTwo@users.noreply.github.com> Date: Fri, 26 Jul 2024 00:31:24 +0800 Subject: [PATCH 26/58] Update Updater.cs --- EXILED/Exiled.Loader/Updater.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/EXILED/Exiled.Loader/Updater.cs b/EXILED/Exiled.Loader/Updater.cs index 6990c1812..fb0636570 100644 --- a/EXILED/Exiled.Loader/Updater.cs +++ b/EXILED/Exiled.Loader/Updater.cs @@ -31,7 +31,7 @@ namespace Exiled.Loader ///
internal sealed class Updater { - private const long REPOID = 828620622; + private const long REPOID = 833723500; private const string INSTALLER_ASSET_NAME_LINUX = "Exiled.Installer-Linux"; private const string INSTALLER_ASSET_NAME_WIN = "Exiled.Installer-Win.exe"; @@ -332,4 +332,4 @@ private bool FindAsset(string assetName, Release release, out ReleaseAsset asset return false; } } -} \ No newline at end of file +} From dfed0ee07c6e4380105d2477ef27142406ef249a Mon Sep 17 00:00:00 2001 From: Misaka-ZeroTwo <45165615+Misaka-ZeroTwo@users.noreply.github.com> Date: Fri, 26 Jul 2024 00:31:46 +0800 Subject: [PATCH 27/58] Update Program.cs --- EXILED/Exiled.Installer/Program.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/EXILED/Exiled.Installer/Program.cs b/EXILED/Exiled.Installer/Program.cs index 34912cc51..559c17c82 100644 --- a/EXILED/Exiled.Installer/Program.cs +++ b/EXILED/Exiled.Installer/Program.cs @@ -42,7 +42,7 @@ internal enum PathResolution internal static class Program { - private const long RepoID = 828620622; + private const long RepoID = 833723500; private const string ExiledAssetName = "exiled.tar.gz"; // This is the lowest version the installer will check to install @@ -303,4 +303,4 @@ private static Release FindRelease(CommandSettings args, IEnumerable re return enumerable.First(); } } -} \ No newline at end of file +} From 0b108104c391b3622b1b196a082b6fcea632444a Mon Sep 17 00:00:00 2001 From: Misaka-ZeroTwo <45165615+Misaka-ZeroTwo@users.noreply.github.com> Date: Fri, 26 Jul 2024 01:33:28 +0800 Subject: [PATCH 28/58] Update dev.yml --- .github/workflows/dev.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/dev.yml b/.github/workflows/dev.yml index c1f7fe301..a608aa15a 100644 --- a/.github/workflows/dev.yml +++ b/.github/workflows/dev.yml @@ -14,7 +14,7 @@ defaults: working-directory: ./EXILED env: - EXILED_REFERENCES_URL: https://exmod-team.github.io/SL-Reference/Dev.zip + EXILED_REFERENCES_URL: https://exmod-team.github.io/SL-References/Dev.zip EXILED_REFERENCES_PATH: ${{ github.workspace }}/EXILED/References EXILED_DLL_ARCHIVER_URL: https://github.com/ExMod-Team/EXILED-DLL-Archiver/releases/latest/download/EXILED-DLL-Archiver.exe From 42b541e4602f28313d1a6a9fb1f1c006660585d4 Mon Sep 17 00:00:00 2001 From: Misaka-ZeroTwo <45165615+Misaka-ZeroTwo@users.noreply.github.com> Date: Fri, 26 Jul 2024 17:39:39 +0800 Subject: [PATCH 29/58] Update labeler.yml --- .github/labeler.yml | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/.github/labeler.yml b/.github/labeler.yml index 34ff31f3f..5098459b0 100644 --- a/.github/labeler.yml +++ b/.github/labeler.yml @@ -13,29 +13,28 @@ Scripts: # Add the 'Scripts' label regarding-events: # Add the 'Events' label - changed-files: - - any-glob-to-any-file: Exiled.Events/** # Any Modifications to events + - any-glob-to-any-file: EXILED/Exiled.Events/** # Any Modifications to events regarding-api: # Add the 'API' label - changed-files: - - any-glob-to-any-file: Exiled.API/** # Any modifications to the API + - any-glob-to-any-file: EXILED/Exiled.API/** # Any modifications to the API regarding-transpiler: # Add the 'transpiler' label - changed-files: - - any-glob-to-any-file: Exiled.Events/Patches/**/* # Any modifications to transpiler files + - any-glob-to-any-file: EXILED/Exiled.Events/Patches/**/* # Any modifications to transpiler files CustomModules: # Add the 'CustomModules' label - changed-files: - - any-glob-to-any-file: Exiled.CustomModules/** # Any modifications to CustomModules + - any-glob-to-any-file: EXILED/Exiled.CustomModules/** # Any modifications to CustomModules Installer: # Add the 'Installer' label - changed-files: - - any-glob-to-any-file: Exiled.Installer/** # Any modifications to the Installer + - any-glob-to-any-file: EXILED/Exiled.Installer/** # Any modifications to the Installer Localization: # Add the 'Localization' label - changed-files: - - any-glob-to-any-file: Localization/** # Any modifications to Localization + - any-glob-to-any-file: EXILED/Localization/** # Any modifications to Localization GitHub_Actions: # Add the 'GitHub' label - changed-files: - any-glob-to-any-file: .github/** # Any modifications to github related files - From 92af4ce0a4e98085e2a9e5e266845530c1b99625 Mon Sep 17 00:00:00 2001 From: Misaka-ZeroTwo <45165615+Misaka-ZeroTwo@users.noreply.github.com> Date: Fri, 26 Jul 2024 17:39:56 +0800 Subject: [PATCH 30/58] Update labeler.yml --- .github/labeler.yml | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/.github/labeler.yml b/.github/labeler.yml index 34ff31f3f..5098459b0 100644 --- a/.github/labeler.yml +++ b/.github/labeler.yml @@ -13,29 +13,28 @@ Scripts: # Add the 'Scripts' label regarding-events: # Add the 'Events' label - changed-files: - - any-glob-to-any-file: Exiled.Events/** # Any Modifications to events + - any-glob-to-any-file: EXILED/Exiled.Events/** # Any Modifications to events regarding-api: # Add the 'API' label - changed-files: - - any-glob-to-any-file: Exiled.API/** # Any modifications to the API + - any-glob-to-any-file: EXILED/Exiled.API/** # Any modifications to the API regarding-transpiler: # Add the 'transpiler' label - changed-files: - - any-glob-to-any-file: Exiled.Events/Patches/**/* # Any modifications to transpiler files + - any-glob-to-any-file: EXILED/Exiled.Events/Patches/**/* # Any modifications to transpiler files CustomModules: # Add the 'CustomModules' label - changed-files: - - any-glob-to-any-file: Exiled.CustomModules/** # Any modifications to CustomModules + - any-glob-to-any-file: EXILED/Exiled.CustomModules/** # Any modifications to CustomModules Installer: # Add the 'Installer' label - changed-files: - - any-glob-to-any-file: Exiled.Installer/** # Any modifications to the Installer + - any-glob-to-any-file: EXILED/Exiled.Installer/** # Any modifications to the Installer Localization: # Add the 'Localization' label - changed-files: - - any-glob-to-any-file: Localization/** # Any modifications to Localization + - any-glob-to-any-file: EXILED/Localization/** # Any modifications to Localization GitHub_Actions: # Add the 'GitHub' label - changed-files: - any-glob-to-any-file: .github/** # Any modifications to github related files - From fd3840aac37e308cdb4efde92ec01d19da91b188 Mon Sep 17 00:00:00 2001 From: Misaka-ZeroTwo <45165615+Misaka-ZeroTwo@users.noreply.github.com> Date: Wed, 31 Jul 2024 19:07:27 +0800 Subject: [PATCH 31/58] Merge to dev (#8) --- .github/workflows/main.yml | 2 +- .github/workflows/release.yml | 4 ++-- EXILED/Exiled.Installer/Program.cs | 4 ++-- EXILED/Exiled.Loader/Updater.cs | 4 ++-- 4 files changed, 7 insertions(+), 7 deletions(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 7be77c41a..6f9bc0f85 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -13,7 +13,7 @@ defaults: working-directory: ./EXILED env: - EXILED_REFERENCES_URL: https://Exiled-Official.github.io/SL-References/Master.zip + EXILED_REFERENCES_URL: https://exmod-team.github.io/SL-References/Master.zip EXILED_REFERENCES_PATH: ${{ github.workspace }}/EXILED/References jobs: diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index bcbe907cc..efdac4cc8 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -11,9 +11,9 @@ defaults: working-directory: ./EXILED env: - EXILED_REFERENCES_URL: https://Exiled-Official.github.io/SL-References/Dev.zip + EXILED_REFERENCES_URL: https://exmod-team.github.io/SL-References/Dev.zip EXILED_REFERENCES_PATH: ${{ github.workspace }}/EXILED/References - EXILED_DLL_ARCHIVER_URL: https://github.com/Exiled-Official/EXILED-DLL-Archiver/releases/latest/download/EXILED-DLL-Archiver.exe + EXILED_DLL_ARCHIVER_URL: https://github.com/ExMod-Team/EXILED-DLL-Archiver/releases/latest/download/EXILED-DLL-Archiver.exe jobs: build: diff --git a/EXILED/Exiled.Installer/Program.cs b/EXILED/Exiled.Installer/Program.cs index 34912cc51..559c17c82 100644 --- a/EXILED/Exiled.Installer/Program.cs +++ b/EXILED/Exiled.Installer/Program.cs @@ -42,7 +42,7 @@ internal enum PathResolution internal static class Program { - private const long RepoID = 828620622; + private const long RepoID = 833723500; private const string ExiledAssetName = "exiled.tar.gz"; // This is the lowest version the installer will check to install @@ -303,4 +303,4 @@ private static Release FindRelease(CommandSettings args, IEnumerable re return enumerable.First(); } } -} \ No newline at end of file +} diff --git a/EXILED/Exiled.Loader/Updater.cs b/EXILED/Exiled.Loader/Updater.cs index 6990c1812..fb0636570 100644 --- a/EXILED/Exiled.Loader/Updater.cs +++ b/EXILED/Exiled.Loader/Updater.cs @@ -31,7 +31,7 @@ namespace Exiled.Loader ///
internal sealed class Updater { - private const long REPOID = 828620622; + private const long REPOID = 833723500; private const string INSTALLER_ASSET_NAME_LINUX = "Exiled.Installer-Linux"; private const string INSTALLER_ASSET_NAME_WIN = "Exiled.Installer-Win.exe"; @@ -332,4 +332,4 @@ private bool FindAsset(string assetName, Release release, out ReleaseAsset asset return false; } } -} \ No newline at end of file +} From 21dae1226880e687150a61e43d6a202c38bfa991 Mon Sep 17 00:00:00 2001 From: Yamato Date: Wed, 31 Jul 2024 19:37:54 +0200 Subject: [PATCH 32/58] This will not be used --- .../Generic/Scp049API/CallAbilityDuration.cs | 63 ---------- .../Scp049API/SenseAbilityBaseCooldown.cs | 64 ---------- .../Scp049API/SenseAbilityReducedCooldown.cs | 64 ---------- .../Scp106API/CooldownReductionReward.cs | 67 ----------- .../Patches/Generic/Scp106API/CustomAttack.cs | 111 ------------------ .../Scp106API/HunterAtlastCostPerMetter.cs | 67 ----------- .../Scp106API/SinkholeAbilityCooldown.cs | 67 ----------- .../Generic/Scp106API/StalkVigorUse.cs | 84 ------------- .../Generic/Scp106API/VigorRegeneration.cs | 66 ----------- 9 files changed, 653 deletions(-) delete mode 100644 EXILED/Exiled.Events/Patches/Generic/Scp049API/CallAbilityDuration.cs delete mode 100644 EXILED/Exiled.Events/Patches/Generic/Scp049API/SenseAbilityBaseCooldown.cs delete mode 100644 EXILED/Exiled.Events/Patches/Generic/Scp049API/SenseAbilityReducedCooldown.cs delete mode 100644 EXILED/Exiled.Events/Patches/Generic/Scp106API/CooldownReductionReward.cs delete mode 100644 EXILED/Exiled.Events/Patches/Generic/Scp106API/CustomAttack.cs delete mode 100644 EXILED/Exiled.Events/Patches/Generic/Scp106API/HunterAtlastCostPerMetter.cs delete mode 100644 EXILED/Exiled.Events/Patches/Generic/Scp106API/SinkholeAbilityCooldown.cs delete mode 100644 EXILED/Exiled.Events/Patches/Generic/Scp106API/StalkVigorUse.cs delete mode 100644 EXILED/Exiled.Events/Patches/Generic/Scp106API/VigorRegeneration.cs diff --git a/EXILED/Exiled.Events/Patches/Generic/Scp049API/CallAbilityDuration.cs b/EXILED/Exiled.Events/Patches/Generic/Scp049API/CallAbilityDuration.cs deleted file mode 100644 index ddfb45adb..000000000 --- a/EXILED/Exiled.Events/Patches/Generic/Scp049API/CallAbilityDuration.cs +++ /dev/null @@ -1,63 +0,0 @@ -// ----------------------------------------------------------------------- -// -// Copyright (c) Exiled Team. All rights reserved. -// Licensed under the CC BY-SA 3.0 license. -// -// ----------------------------------------------------------------------- - -namespace Exiled.Events.Patches.Generic.Scp079API -{ - using System.Collections.Generic; - using System.Reflection.Emit; - - using API.Features.Pools; - using Exiled.API.Features; - using HarmonyLib; - using PlayerRoles.PlayableScps.Scp049; - using PlayerRoles.Subroutines; - - using static HarmonyLib.AccessTools; - - using BaseScp049Role = PlayerRoles.PlayableScps.Scp049.Scp049Role; - using Scp049Role = API.Features.Roles.Scp049Role; - - /// - /// Patches . - /// Adds the property. - /// - // [HarmonyPatch(typeof(Scp049CallAbility), nameof(Scp049CallAbility.ServerProcessCmd))] - internal class CallAbilityDuration - { - private static IEnumerable Transpiler(IEnumerable instructions, ILGenerator generator) - { - List newInstructions = ListPool.Pool.Get(instructions); - - LocalBuilder scp049Role = generator.DeclareLocal(typeof(Scp049Role)); - - // replace "this.Duration.Trigger(20.0)" with "this.Duration.Trigger((Player.Get(base.Owner).Role as Scp049Role).CallAbilityDuration)" - int offset = -1; - int index = newInstructions.FindIndex(instruction => instruction.operand == (object)Method(typeof(AbilityCooldown), nameof(AbilityCooldown.Trigger))) + offset; - newInstructions.RemoveAt(index); - - newInstructions.InsertRange( - index, - new CodeInstruction[] - { - // Player.Get(base.Owner).Role - new(OpCodes.Ldarg_0), - new(OpCodes.Call, PropertyGetter(typeof(StandardSubroutine), nameof(StandardSubroutine.Owner))), - new(OpCodes.Call, Method(typeof(Player), nameof(Player.Get), new[] { typeof(ReferenceHub) })), - new(OpCodes.Callvirt, PropertyGetter(typeof(Player), nameof(Player.Role))), - - // (Player.Get(base.Owner).Role as Scp049Role).CallAbilityDuration - new(OpCodes.Isinst, typeof(Scp049Role)), - new(OpCodes.Callvirt, PropertyGetter(typeof(Scp049Role), nameof(Scp049Role.CallAbilityDuration))), - }); - - for (int z = 0; z < newInstructions.Count; z++) - yield return newInstructions[z]; - - ListPool.Pool.Return(newInstructions); - } - } -} \ No newline at end of file diff --git a/EXILED/Exiled.Events/Patches/Generic/Scp049API/SenseAbilityBaseCooldown.cs b/EXILED/Exiled.Events/Patches/Generic/Scp049API/SenseAbilityBaseCooldown.cs deleted file mode 100644 index a70583b5f..000000000 --- a/EXILED/Exiled.Events/Patches/Generic/Scp049API/SenseAbilityBaseCooldown.cs +++ /dev/null @@ -1,64 +0,0 @@ -// ----------------------------------------------------------------------- -// -// Copyright (c) Exiled Team. All rights reserved. -// Licensed under the CC BY-SA 3.0 license. -// -// ----------------------------------------------------------------------- - -namespace Exiled.Events.Patches.Generic.Scp079API -{ - using System.Collections.Generic; - using System.Reflection.Emit; - - using API.Features.Pools; - using Exiled.API.Features; - - using HarmonyLib; - using PlayerRoles.PlayableScps.Scp049; - using PlayerRoles.Subroutines; - - using static HarmonyLib.AccessTools; - - using BaseScp049Role = PlayerRoles.PlayableScps.Scp049.Scp049Role; - using Scp049Role = API.Features.Roles.Scp049Role; - - /// - /// Patches . - /// Adds the property. - /// - // [HarmonyPatch(typeof(Scp049SenseAbility), nameof(Scp049SenseAbility.ServerProcessKilledPlayer))] - internal class SenseAbilityBaseCooldown - { - private static IEnumerable Transpiler(IEnumerable instructions, ILGenerator generator) - { - List newInstructions = ListPool.Pool.Get(instructions); - - LocalBuilder scp049Role = generator.DeclareLocal(typeof(Scp049Role)); - - // replace "this.Duration.Trigger(40.0)" with "this.Duration.Trigger((Player.Get(base.Owner).Role as Scp049Role).SenseAbilityBaseCooldown)" - int offset = -1; - int index = newInstructions.FindIndex(instruction => instruction.operand == (object)Method(typeof(AbilityCooldown), nameof(AbilityCooldown.Trigger))) + offset; - newInstructions.RemoveAt(index); - - newInstructions.InsertRange( - index, - new CodeInstruction[] - { - // Player.Get(base.Owner).Role - new(OpCodes.Ldarg_0), - new(OpCodes.Call, PropertyGetter(typeof(StandardSubroutine), nameof(StandardSubroutine.Owner))), - new(OpCodes.Call, Method(typeof(Player), nameof(Player.Get), new[] { typeof(ReferenceHub) })), - new(OpCodes.Callvirt, PropertyGetter(typeof(Player), nameof(Player.Role))), - - // (Player.Get(base.Owner).Role as Scp049Role).SenseAbilityBaseCooldown - new(OpCodes.Isinst, typeof(Scp049Role)), - new(OpCodes.Callvirt, PropertyGetter(typeof(Scp049Role), nameof(Scp049Role.SenseAbilityBaseCooldown))), - }); - - for (int z = 0; z < newInstructions.Count; z++) - yield return newInstructions[z]; - - ListPool.Pool.Return(newInstructions); - } - } -} \ No newline at end of file diff --git a/EXILED/Exiled.Events/Patches/Generic/Scp049API/SenseAbilityReducedCooldown.cs b/EXILED/Exiled.Events/Patches/Generic/Scp049API/SenseAbilityReducedCooldown.cs deleted file mode 100644 index 88c8333a1..000000000 --- a/EXILED/Exiled.Events/Patches/Generic/Scp049API/SenseAbilityReducedCooldown.cs +++ /dev/null @@ -1,64 +0,0 @@ -// ----------------------------------------------------------------------- -// -// Copyright (c) Exiled Team. All rights reserved. -// Licensed under the CC BY-SA 3.0 license. -// -// ----------------------------------------------------------------------- - -namespace Exiled.Events.Patches.Generic.Scp079API -{ - using System.Collections.Generic; - using System.Reflection.Emit; - - using API.Features.Pools; - using Exiled.API.Features; - - using HarmonyLib; - using PlayerRoles.PlayableScps.Scp049; - using PlayerRoles.Subroutines; - - using static HarmonyLib.AccessTools; - - using BaseScp049Role = PlayerRoles.PlayableScps.Scp049.Scp049Role; - using Scp049Role = API.Features.Roles.Scp049Role; - - /// - /// Patches . - /// Adds the property. - /// - // [HarmonyPatch(typeof(Scp049SenseAbility), nameof(Scp049SenseAbility.ServerLoseTarget))] - internal class SenseAbilityReducedCooldown - { - private static IEnumerable Transpiler(IEnumerable instructions, ILGenerator generator) - { - List newInstructions = ListPool.Pool.Get(instructions); - - LocalBuilder scp049Role = generator.DeclareLocal(typeof(Scp049Role)); - - // replace "this.Duration.Trigger(40.0)" with "this.Duration.Trigger((Player.Get(base.Owner).Role as Scp049Role).SenseAbilityReducedCooldown)" - int offset = -1; - int index = newInstructions.FindIndex(instruction => instruction.operand == (object)Method(typeof(AbilityCooldown), nameof(AbilityCooldown.Trigger))) + offset; - newInstructions.RemoveAt(index); - - newInstructions.InsertRange( - index, - new CodeInstruction[] - { - // Player.Get(base.Owner).Role - new(OpCodes.Ldarg_0), - new(OpCodes.Call, PropertyGetter(typeof(StandardSubroutine), nameof(StandardSubroutine.Owner))), - new(OpCodes.Call, Method(typeof(Player), nameof(Player.Get), new[] { typeof(ReferenceHub) })), - new(OpCodes.Callvirt, PropertyGetter(typeof(Player), nameof(Player.Role))), - - // (Player.Get(base.Owner).Role as Scp049Role).SenseAbilityReducedCooldown - new(OpCodes.Isinst, typeof(Scp049Role)), - new(OpCodes.Callvirt, PropertyGetter(typeof(Scp049Role), nameof(Scp049Role.SenseAbilityReducedCooldown))), - }); - - for (int z = 0; z < newInstructions.Count; z++) - yield return newInstructions[z]; - - ListPool.Pool.Return(newInstructions); - } - } -} \ No newline at end of file diff --git a/EXILED/Exiled.Events/Patches/Generic/Scp106API/CooldownReductionReward.cs b/EXILED/Exiled.Events/Patches/Generic/Scp106API/CooldownReductionReward.cs deleted file mode 100644 index 4f509aad2..000000000 --- a/EXILED/Exiled.Events/Patches/Generic/Scp106API/CooldownReductionReward.cs +++ /dev/null @@ -1,67 +0,0 @@ -// ----------------------------------------------------------------------- -// -// Copyright (c) Exiled Team. All rights reserved. -// Licensed under the CC BY-SA 3.0 license. -// -// ----------------------------------------------------------------------- - -namespace Exiled.Events.Patches.Generic.Scp106API -{ - using System.Collections.Generic; - using System.Reflection; - using System.Reflection.Emit; - - using API.Features.Pools; - using Exiled.API.Features; - using HarmonyLib; - using PlayerRoles.PlayableScps.Scp106; - using PlayerRoles.Subroutines; - - using static HarmonyLib.AccessTools; - - using BaseScp106Role = PlayerRoles.PlayableScps.Scp106.Scp106Role; - using Scp106Role = API.Features.Roles.Scp106Role; - - /// - /// Patches . - /// Adds the property. - /// - // [HarmonyPatch(typeof(Scp106Attack), nameof(Scp106Attack.ReduceSinkholeCooldown))] - internal class CooldownReductionReward - { - private static IEnumerable Transpiler(IEnumerable instructions, ILGenerator generator) - { - List newInstructions = ListPool.Pool.Get(instructions); - - LocalBuilder scp049Role = generator.DeclareLocal(typeof(Scp106Role)); - - // replace "base.ScpRole.Sinkhole.Cooldown.NextUse -= 5.0; - // with - // Scp106Role scp106Role = Player.Get(this.Owner).Role.As() - // replace "base.ScpRole.Sinkhole.Cooldown.NextUse -= scp106Role.CooldownReductionReward; - int offset = 0; - int index = newInstructions.FindLastIndex(instruction => instruction.opcode == OpCodes.Ldc_R4) + offset; - newInstructions.RemoveAt(index); - - newInstructions.InsertRange( - index, - new CodeInstruction[] - { - // Player.Get(base.Owner).Role - new(OpCodes.Ldarg_0), - new(OpCodes.Call, PropertyGetter(typeof(StandardSubroutine), nameof(StandardSubroutine.Owner))), - new(OpCodes.Call, Method(typeof(Player), nameof(Player.Get), new[] { typeof(ReferenceHub) })), - new(OpCodes.Callvirt, PropertyGetter(typeof(Player), nameof(Player.Role))), - - // (Player.Get(base.Owner).Role as Scp106Role).CooldownReductionReward - new(OpCodes.Isinst, typeof(Scp106Role)), - new(OpCodes.Callvirt, PropertyGetter(typeof(Scp106Role), nameof(Scp106Role.CooldownReductionReward))), - }); - - for (int z = 0; z < newInstructions.Count; z++) - yield return newInstructions[z]; - - ListPool.Pool.Return(newInstructions); - } - } -} diff --git a/EXILED/Exiled.Events/Patches/Generic/Scp106API/CustomAttack.cs b/EXILED/Exiled.Events/Patches/Generic/Scp106API/CustomAttack.cs deleted file mode 100644 index f6469919a..000000000 --- a/EXILED/Exiled.Events/Patches/Generic/Scp106API/CustomAttack.cs +++ /dev/null @@ -1,111 +0,0 @@ -// ----------------------------------------------------------------------- -// -// Copyright (c) Exiled Team. All rights reserved. -// Licensed under the CC BY-SA 3.0 license. -// -// ----------------------------------------------------------------------- - -namespace Exiled.Events.Patches.Generic.Scp106API -{ - using System.Collections.Generic; - using System.Reflection.Emit; - - using API.Features.Pools; - using Exiled.API.Features; - using HarmonyLib; - using PlayerRoles.PlayableScps.Scp106; - using PlayerRoles.Subroutines; - - using static HarmonyLib.AccessTools; - - using BaseScp106Role = PlayerRoles.PlayableScps.Scp106.Scp106Role; - using Scp106Role = API.Features.Roles.Scp106Role; - - /// - /// Patches . - /// Adds the , , property. - /// - // [HarmonyPatch(typeof(Scp106Attack), nameof(Scp106Attack.ServerShoot))] - internal class CustomAttack - { - private static IEnumerable Transpiler(IEnumerable instructions, ILGenerator generator) - { - List newInstructions = ListPool.Pool.Get(instructions); - - LocalBuilder scp049Role = generator.DeclareLocal(typeof(Scp106Role)); - - // replace "base.Vigor.VigorAmount += 0.3f;" - // with - // Scp106Role scp106Role = Player.Get(this.Owner).Role.As() - // "base.Vigor.VigorAmount += scp106Role.VigorCaptureReward;" - int offset = 0; - int index = newInstructions.FindIndex(instruction => instruction.operand == (object)Scp106Attack.VigorCaptureReward) + offset; - newInstructions.RemoveAt(index); - - newInstructions.InsertRange( - index, - new CodeInstruction[] - { - // Player.Get(base.Owner).Role - new(OpCodes.Ldarg_0), - new(OpCodes.Call, PropertyGetter(typeof(StandardSubroutine), nameof(StandardSubroutine.Owner))), - new(OpCodes.Call, Method(typeof(Player), nameof(Player.Get), new[] { typeof(ReferenceHub) })), - new(OpCodes.Callvirt, PropertyGetter(typeof(Player), nameof(Player.Role))), - - // (Player.Get(base.Owner).Role as Scp106Role).AttackDamage - new(OpCodes.Isinst, typeof(Scp106Role)), - new(OpCodes.Callvirt, PropertyGetter(typeof(Scp106Role), nameof(Scp106Role.VigorCaptureReward))), - }); - - // replace "base.Vigor.VigorAmount += 0.3f;" - // with - // Scp106Role scp106Role = Player.Get(this.Owner).Role.As() - // "base.Vigor.VigorAmount += scp106Role.VigorCaptureReward;" - offset = 0; - index = newInstructions.FindIndex(instruction => instruction.operand == (object)Scp106Attack.VigorCaptureReward) + offset; - newInstructions.RemoveAt(index); - - newInstructions.InsertRange( - index, - new CodeInstruction[] - { - // Player.Get(base.Owner).Role - new(OpCodes.Ldarg_0), - new(OpCodes.Call, PropertyGetter(typeof(StandardSubroutine), nameof(StandardSubroutine.Owner))), - new(OpCodes.Call, Method(typeof(Player), nameof(Player.Get), new[] { typeof(ReferenceHub) })), - new(OpCodes.Callvirt, PropertyGetter(typeof(Player), nameof(Player.Role))), - - // (Player.Get(base.Owner).Role as Scp106Role).AttackDamage - new(OpCodes.Isinst, typeof(Scp106Role)), - new(OpCodes.Callvirt, PropertyGetter(typeof(Scp106Role), nameof(Scp106Role.VigorCaptureReward))), - }); - - // replace "playerEffectsController.EnableEffect(20f, false);" - // with - // Scp106Role scp106Role = Player.Get(this.Owner).Role.As() - // "playerEffectsController.EnableEffect(scp106Role.CorrodingTime, false);" - offset = 0; - index = newInstructions.FindLastIndex(instruction => instruction.opcode == OpCodes.Ldc_R4) + offset; - newInstructions.RemoveAt(index); - - newInstructions.InsertRange( - index, - new CodeInstruction[] - { - // Player.Get(base.Owner).Role - new(OpCodes.Ldarg_0), - new(OpCodes.Call, PropertyGetter(typeof(StandardSubroutine), nameof(StandardSubroutine.Owner))), - new(OpCodes.Call, Method(typeof(Player), nameof(Player.Get), new[] { typeof(ReferenceHub) })), - new(OpCodes.Callvirt, PropertyGetter(typeof(Player), nameof(Player.Role))), - - // (Player.Get(base.Owner).Role as Scp106Role).CorrodingTime - new(OpCodes.Isinst, typeof(Scp106Role)), - new(OpCodes.Callvirt, PropertyGetter(typeof(Scp106Role), nameof(Scp106Role.CorrodingTime))), - }); - for (int z = 0; z < newInstructions.Count; z++) - yield return newInstructions[z]; - - ListPool.Pool.Return(newInstructions); - } - } -} diff --git a/EXILED/Exiled.Events/Patches/Generic/Scp106API/HunterAtlastCostPerMetter.cs b/EXILED/Exiled.Events/Patches/Generic/Scp106API/HunterAtlastCostPerMetter.cs deleted file mode 100644 index d85ac0151..000000000 --- a/EXILED/Exiled.Events/Patches/Generic/Scp106API/HunterAtlastCostPerMetter.cs +++ /dev/null @@ -1,67 +0,0 @@ -// ----------------------------------------------------------------------- -// -// Copyright (c) Exiled Team. All rights reserved. -// Licensed under the CC BY-SA 3.0 license. -// -// ----------------------------------------------------------------------- - -namespace Exiled.Events.Patches.Generic.Scp106API -{ - using System.Collections.Generic; - using System.Reflection; - using System.Reflection.Emit; - - using API.Features.Pools; - using Exiled.API.Features; - using HarmonyLib; - using PlayerRoles.PlayableScps.Scp106; - using PlayerRoles.Subroutines; - - using static HarmonyLib.AccessTools; - - using BaseScp106Role = PlayerRoles.PlayableScps.Scp106.Scp106Role; - using Scp106Role = API.Features.Roles.Scp106Role; - - /// - /// Patches . - /// Adds the property. - /// - // [HarmonyPatch(typeof(Scp106HuntersAtlasAbility), nameof(Scp106HuntersAtlasAbility.ServerProcessCmd))] - internal class HunterAtlastCostPerMetter - { - private static IEnumerable Transpiler(IEnumerable instructions, ILGenerator generator) - { - List newInstructions = ListPool.Pool.Get(instructions); - - LocalBuilder scp049Role = generator.DeclareLocal(typeof(Scp106Role)); - - // replace "num = (position2 - this._syncPos).MagnitudeIgnoreY() * 0.019f;" - // with - // Scp106Role scp106Role = Player.Get(this.Owner).Role.As() - // replace "num = (position2 - this._syncPos).MagnitudeIgnoreY() * scp106Role.HuntersAtlasCostPerMeter;" - int offset = 0; - int index = newInstructions.FindLastIndex(instruction => instruction.opcode == OpCodes.Ldc_R4) + offset; - newInstructions.RemoveAt(index); - - newInstructions.InsertRange( - index, - new CodeInstruction[] - { - // Player.Get(base.Owner).Role - new(OpCodes.Ldarg_0), - new(OpCodes.Call, PropertyGetter(typeof(StandardSubroutine), nameof(StandardSubroutine.Owner))), - new(OpCodes.Call, Method(typeof(Player), nameof(Player.Get), new[] { typeof(ReferenceHub) })), - new(OpCodes.Callvirt, PropertyGetter(typeof(Player), nameof(Player.Role))), - - // (Player.Get(base.Owner).Role as Scp106Role).HuntersAtlasCostPerMeter - new(OpCodes.Isinst, typeof(Scp106Role)), - new(OpCodes.Callvirt, PropertyGetter(typeof(Scp106Role), nameof(Scp106Role.HuntersAtlasCostPerMeter))), - }); - - for (int z = 0; z < newInstructions.Count; z++) - yield return newInstructions[z]; - - ListPool.Pool.Return(newInstructions); - } - } -} diff --git a/EXILED/Exiled.Events/Patches/Generic/Scp106API/SinkholeAbilityCooldown.cs b/EXILED/Exiled.Events/Patches/Generic/Scp106API/SinkholeAbilityCooldown.cs deleted file mode 100644 index 519fef858..000000000 --- a/EXILED/Exiled.Events/Patches/Generic/Scp106API/SinkholeAbilityCooldown.cs +++ /dev/null @@ -1,67 +0,0 @@ -// ----------------------------------------------------------------------- -// -// Copyright (c) Exiled Team. All rights reserved. -// Licensed under the CC BY-SA 3.0 license. -// -// ----------------------------------------------------------------------- - -namespace Exiled.Events.Patches.Generic.Scp106API -{ - using System.Collections.Generic; - using System.Reflection; - using System.Reflection.Emit; - - using API.Features.Pools; - using Exiled.API.Features; - using HarmonyLib; - using PlayerRoles.PlayableScps.Scp106; - using PlayerRoles.Subroutines; - - using static HarmonyLib.AccessTools; - - using BaseScp106Role = PlayerRoles.PlayableScps.Scp106.Scp106Role; - using Scp106Role = API.Features.Roles.Scp106Role; - - /// - /// Patches . - /// Adds the property. - /// - // [HarmonyPatch(typeof(Scp106Attack), nameof(Scp106Attack.ReduceSinkholeCooldown))] - internal class SinkholeAbilityCooldown - { - private static IEnumerable Transpiler(IEnumerable instructions, ILGenerator generator) - { - List newInstructions = ListPool.Pool.Get(instructions); - - LocalBuilder scp049Role = generator.DeclareLocal(typeof(Scp106Role)); - - // replace "this.Cooldown.Trigger(20.0);" - // with - // Scp106Role scp106Role = Player.Get(this.Owner).Role.As() - // replace "this.Cooldown.Trigger(scp106Role.SinkholeCooldownDuration);" - int offset = 0; - int index = newInstructions.FindLastIndex(instruction => instruction.opcode == OpCodes.Ldc_R4) + offset; - newInstructions.RemoveAt(index); - - newInstructions.InsertRange( - index, - new CodeInstruction[] - { - // Player.Get(base.Owner).Role - new(OpCodes.Ldarg_0), - new(OpCodes.Call, PropertyGetter(typeof(StandardSubroutine), nameof(StandardSubroutine.Owner))), - new(OpCodes.Call, Method(typeof(Player), nameof(Player.Get), new[] { typeof(ReferenceHub) })), - new(OpCodes.Callvirt, PropertyGetter(typeof(Player), nameof(Player.Role))), - - // (Player.Get(base.Owner).Role as Scp106Role).SinkholeCooldownDuration - new(OpCodes.Isinst, typeof(Scp106Role)), - new(OpCodes.Callvirt, PropertyGetter(typeof(Scp106Role), nameof(Scp106Role.SinkholeCooldownDuration))), - }); - - for (int z = 0; z < newInstructions.Count; z++) - yield return newInstructions[z]; - - ListPool.Pool.Return(newInstructions); - } - } -} diff --git a/EXILED/Exiled.Events/Patches/Generic/Scp106API/StalkVigorUse.cs b/EXILED/Exiled.Events/Patches/Generic/Scp106API/StalkVigorUse.cs deleted file mode 100644 index 38b7a9e53..000000000 --- a/EXILED/Exiled.Events/Patches/Generic/Scp106API/StalkVigorUse.cs +++ /dev/null @@ -1,84 +0,0 @@ -// ----------------------------------------------------------------------- -// -// Copyright (c) Exiled Team. All rights reserved. -// Licensed under the CC BY-SA 3.0 license. -// -// ----------------------------------------------------------------------- - -namespace Exiled.Events.Patches.Generic.Scp106API -{ - using System.Collections.Generic; - using System.Reflection.Emit; - - using API.Features.Pools; - using Exiled.API.Features; - using HarmonyLib; - using PlayerRoles.PlayableScps.Scp106; - using PlayerRoles.Subroutines; - - using static HarmonyLib.AccessTools; - - using BaseScp106Role = PlayerRoles.PlayableScps.Scp106.Scp106Role; - using Scp106Role = API.Features.Roles.Scp106Role; - - /// - /// Patches . - /// Adds the and property. - /// - // [HarmonyPatch(typeof(Scp106StalkAbility), nameof(Scp106StalkAbility.UpdateServerside))] - internal class StalkVigorUse - { - private static IEnumerable Transpiler(IEnumerable instructions, ILGenerator generator) - { - List newInstructions = ListPool.Pool.Get(instructions); - - LocalBuilder scp049Role = generator.DeclareLocal(typeof(Scp106Role)); - - // replace "float num = base.ScpRole.FpcModule.Motor.MovementDetected ? 0.09f : 0.06f;" - // with - // Scp106Role scp106Role = Player.Get(this.Owner).Role.As() - // "float num = base.ScpRole.FpcModule.Motor.MovementDetected ? scp106Role.VigorStalkCostMoving : scp106Role.VigorStalkCostStationary;" - int offset = 0; - int index = newInstructions.FindIndex(instruction => instruction.opcode == OpCodes.Ldc_R4) + offset; - newInstructions.RemoveAt(index); - - newInstructions.InsertRange( - index, - new CodeInstruction[] - { - // Player.Get(base.Owner).Role - new(OpCodes.Ldarg_0), - new(OpCodes.Call, PropertyGetter(typeof(StandardSubroutine), nameof(StandardSubroutine.Owner))), - new(OpCodes.Call, Method(typeof(Player), nameof(Player.Get), new[] { typeof(ReferenceHub) })), - new(OpCodes.Callvirt, PropertyGetter(typeof(Player), nameof(Player.Role))), - - // (Player.Get(base.Owner).Role as Scp106Role).VigorStalkCostMoving - new(OpCodes.Isinst, typeof(Scp106Role)), - new(OpCodes.Callvirt, PropertyGetter(typeof(Scp106Role), nameof(Scp106Role.VigorStalkCostMoving))), - }); - - offset = 0; - index = newInstructions.FindIndex(instruction => instruction.opcode == OpCodes.Ldc_R4) + offset; - newInstructions.RemoveAt(index); - - newInstructions.InsertRange( - index, - new CodeInstruction[] - { - // Player.Get(base.Owner).Role - new(OpCodes.Ldarg_0), - new(OpCodes.Call, PropertyGetter(typeof(StandardSubroutine), nameof(StandardSubroutine.Owner))), - new(OpCodes.Call, Method(typeof(Player), nameof(Player.Get), new[] { typeof(ReferenceHub) })), - new(OpCodes.Callvirt, PropertyGetter(typeof(Player), nameof(Player.Role))), - - // (Player.Get(base.Owner).Role as Scp106Role).VigorStalkCostStationary - new(OpCodes.Isinst, typeof(Scp106Role)), - new(OpCodes.Callvirt, PropertyGetter(typeof(Scp106Role), nameof(Scp106Role.VigorStalkCostStationary))), - }); - for (int z = 0; z < newInstructions.Count; z++) - yield return newInstructions[z]; - - ListPool.Pool.Return(newInstructions); - } - } -} diff --git a/EXILED/Exiled.Events/Patches/Generic/Scp106API/VigorRegeneration.cs b/EXILED/Exiled.Events/Patches/Generic/Scp106API/VigorRegeneration.cs deleted file mode 100644 index f14fd51d1..000000000 --- a/EXILED/Exiled.Events/Patches/Generic/Scp106API/VigorRegeneration.cs +++ /dev/null @@ -1,66 +0,0 @@ -// ----------------------------------------------------------------------- -// -// Copyright (c) Exiled Team. All rights reserved. -// Licensed under the CC BY-SA 3.0 license. -// -// ----------------------------------------------------------------------- - -namespace Exiled.Events.Patches.Generic.Scp106API -{ - using System.Collections.Generic; - using System.Reflection.Emit; - - using API.Features.Pools; - using Exiled.API.Features; - using HarmonyLib; - using PlayerRoles.PlayableScps.Scp106; - using PlayerRoles.Subroutines; - - using static HarmonyLib.AccessTools; - - using BaseScp106Role = PlayerRoles.PlayableScps.Scp106.Scp106Role; - using Scp106Role = API.Features.Roles.Scp106Role; - - /// - /// Patches . - /// Adds the property. - /// - // [HarmonyPatch(typeof(Scp106StalkAbility), nameof(Scp106StalkAbility.UpdateMovementState))] - internal class VigorRegeneration - { - private static IEnumerable Transpiler(IEnumerable instructions, ILGenerator generator) - { - List newInstructions = ListPool.Pool.Get(instructions); - - LocalBuilder scp049Role = generator.DeclareLocal(typeof(Scp106Role)); - - // replace "base.Vigor.VigorAmount += 0.03f * Time.deltaTime;" - // with - // Scp106Role scp106Role = Player.Get(this.Owner).Role.As() - // "base.Vigor.VigorAmount += scp106Role.VigorRegeneration * Time.deltaTime;" - int offset = -4; - int index = newInstructions.FindIndex(instruction => instruction.operand == (object)PropertySetter(typeof(Scp106VigorAbilityBase), nameof(Scp106VigorAbilityBase.VigorAmount))) + offset; - newInstructions.RemoveAt(index); - - newInstructions.InsertRange( - index, - new CodeInstruction[] - { - // Player.Get(base.Owner).Role - new(OpCodes.Ldarg_0), - new(OpCodes.Call, PropertyGetter(typeof(StandardSubroutine), nameof(StandardSubroutine.Owner))), - new(OpCodes.Call, Method(typeof(Player), nameof(Player.Get), new[] { typeof(ReferenceHub) })), - new(OpCodes.Callvirt, PropertyGetter(typeof(Player), nameof(Player.Role))), - - // (Player.Get(base.Owner).Role as Scp106Role).VigorRegeneration - new(OpCodes.Isinst, typeof(Scp106Role)), - new(OpCodes.Callvirt, PropertyGetter(typeof(Scp106Role), nameof(Scp106Role.VigorRegeneration))), - }); - - for (int z = 0; z < newInstructions.Count; z++) - yield return newInstructions[z]; - - ListPool.Pool.Return(newInstructions); - } - } -} From bd63934fd1e27c66f9766d7edf08033c63580c4e Mon Sep 17 00:00:00 2001 From: Yamato <66829532+louis1706@users.noreply.github.com> Date: Thu, 1 Aug 2024 00:22:18 +0200 Subject: [PATCH 33/58] This will not be used (#13) --- .../Generic/Scp049API/CallAbilityDuration.cs | 63 ---------- .../Scp049API/SenseAbilityBaseCooldown.cs | 64 ---------- .../Scp049API/SenseAbilityReducedCooldown.cs | 64 ---------- .../Scp106API/CooldownReductionReward.cs | 67 ----------- .../Patches/Generic/Scp106API/CustomAttack.cs | 111 ------------------ .../Scp106API/HunterAtlastCostPerMetter.cs | 67 ----------- .../Scp106API/SinkholeAbilityCooldown.cs | 67 ----------- .../Generic/Scp106API/StalkVigorUse.cs | 84 ------------- .../Generic/Scp106API/VigorRegeneration.cs | 66 ----------- 9 files changed, 653 deletions(-) delete mode 100644 EXILED/Exiled.Events/Patches/Generic/Scp049API/CallAbilityDuration.cs delete mode 100644 EXILED/Exiled.Events/Patches/Generic/Scp049API/SenseAbilityBaseCooldown.cs delete mode 100644 EXILED/Exiled.Events/Patches/Generic/Scp049API/SenseAbilityReducedCooldown.cs delete mode 100644 EXILED/Exiled.Events/Patches/Generic/Scp106API/CooldownReductionReward.cs delete mode 100644 EXILED/Exiled.Events/Patches/Generic/Scp106API/CustomAttack.cs delete mode 100644 EXILED/Exiled.Events/Patches/Generic/Scp106API/HunterAtlastCostPerMetter.cs delete mode 100644 EXILED/Exiled.Events/Patches/Generic/Scp106API/SinkholeAbilityCooldown.cs delete mode 100644 EXILED/Exiled.Events/Patches/Generic/Scp106API/StalkVigorUse.cs delete mode 100644 EXILED/Exiled.Events/Patches/Generic/Scp106API/VigorRegeneration.cs diff --git a/EXILED/Exiled.Events/Patches/Generic/Scp049API/CallAbilityDuration.cs b/EXILED/Exiled.Events/Patches/Generic/Scp049API/CallAbilityDuration.cs deleted file mode 100644 index ddfb45adb..000000000 --- a/EXILED/Exiled.Events/Patches/Generic/Scp049API/CallAbilityDuration.cs +++ /dev/null @@ -1,63 +0,0 @@ -// ----------------------------------------------------------------------- -// -// Copyright (c) Exiled Team. All rights reserved. -// Licensed under the CC BY-SA 3.0 license. -// -// ----------------------------------------------------------------------- - -namespace Exiled.Events.Patches.Generic.Scp079API -{ - using System.Collections.Generic; - using System.Reflection.Emit; - - using API.Features.Pools; - using Exiled.API.Features; - using HarmonyLib; - using PlayerRoles.PlayableScps.Scp049; - using PlayerRoles.Subroutines; - - using static HarmonyLib.AccessTools; - - using BaseScp049Role = PlayerRoles.PlayableScps.Scp049.Scp049Role; - using Scp049Role = API.Features.Roles.Scp049Role; - - /// - /// Patches . - /// Adds the property. - /// - // [HarmonyPatch(typeof(Scp049CallAbility), nameof(Scp049CallAbility.ServerProcessCmd))] - internal class CallAbilityDuration - { - private static IEnumerable Transpiler(IEnumerable instructions, ILGenerator generator) - { - List newInstructions = ListPool.Pool.Get(instructions); - - LocalBuilder scp049Role = generator.DeclareLocal(typeof(Scp049Role)); - - // replace "this.Duration.Trigger(20.0)" with "this.Duration.Trigger((Player.Get(base.Owner).Role as Scp049Role).CallAbilityDuration)" - int offset = -1; - int index = newInstructions.FindIndex(instruction => instruction.operand == (object)Method(typeof(AbilityCooldown), nameof(AbilityCooldown.Trigger))) + offset; - newInstructions.RemoveAt(index); - - newInstructions.InsertRange( - index, - new CodeInstruction[] - { - // Player.Get(base.Owner).Role - new(OpCodes.Ldarg_0), - new(OpCodes.Call, PropertyGetter(typeof(StandardSubroutine), nameof(StandardSubroutine.Owner))), - new(OpCodes.Call, Method(typeof(Player), nameof(Player.Get), new[] { typeof(ReferenceHub) })), - new(OpCodes.Callvirt, PropertyGetter(typeof(Player), nameof(Player.Role))), - - // (Player.Get(base.Owner).Role as Scp049Role).CallAbilityDuration - new(OpCodes.Isinst, typeof(Scp049Role)), - new(OpCodes.Callvirt, PropertyGetter(typeof(Scp049Role), nameof(Scp049Role.CallAbilityDuration))), - }); - - for (int z = 0; z < newInstructions.Count; z++) - yield return newInstructions[z]; - - ListPool.Pool.Return(newInstructions); - } - } -} \ No newline at end of file diff --git a/EXILED/Exiled.Events/Patches/Generic/Scp049API/SenseAbilityBaseCooldown.cs b/EXILED/Exiled.Events/Patches/Generic/Scp049API/SenseAbilityBaseCooldown.cs deleted file mode 100644 index a70583b5f..000000000 --- a/EXILED/Exiled.Events/Patches/Generic/Scp049API/SenseAbilityBaseCooldown.cs +++ /dev/null @@ -1,64 +0,0 @@ -// ----------------------------------------------------------------------- -// -// Copyright (c) Exiled Team. All rights reserved. -// Licensed under the CC BY-SA 3.0 license. -// -// ----------------------------------------------------------------------- - -namespace Exiled.Events.Patches.Generic.Scp079API -{ - using System.Collections.Generic; - using System.Reflection.Emit; - - using API.Features.Pools; - using Exiled.API.Features; - - using HarmonyLib; - using PlayerRoles.PlayableScps.Scp049; - using PlayerRoles.Subroutines; - - using static HarmonyLib.AccessTools; - - using BaseScp049Role = PlayerRoles.PlayableScps.Scp049.Scp049Role; - using Scp049Role = API.Features.Roles.Scp049Role; - - /// - /// Patches . - /// Adds the property. - /// - // [HarmonyPatch(typeof(Scp049SenseAbility), nameof(Scp049SenseAbility.ServerProcessKilledPlayer))] - internal class SenseAbilityBaseCooldown - { - private static IEnumerable Transpiler(IEnumerable instructions, ILGenerator generator) - { - List newInstructions = ListPool.Pool.Get(instructions); - - LocalBuilder scp049Role = generator.DeclareLocal(typeof(Scp049Role)); - - // replace "this.Duration.Trigger(40.0)" with "this.Duration.Trigger((Player.Get(base.Owner).Role as Scp049Role).SenseAbilityBaseCooldown)" - int offset = -1; - int index = newInstructions.FindIndex(instruction => instruction.operand == (object)Method(typeof(AbilityCooldown), nameof(AbilityCooldown.Trigger))) + offset; - newInstructions.RemoveAt(index); - - newInstructions.InsertRange( - index, - new CodeInstruction[] - { - // Player.Get(base.Owner).Role - new(OpCodes.Ldarg_0), - new(OpCodes.Call, PropertyGetter(typeof(StandardSubroutine), nameof(StandardSubroutine.Owner))), - new(OpCodes.Call, Method(typeof(Player), nameof(Player.Get), new[] { typeof(ReferenceHub) })), - new(OpCodes.Callvirt, PropertyGetter(typeof(Player), nameof(Player.Role))), - - // (Player.Get(base.Owner).Role as Scp049Role).SenseAbilityBaseCooldown - new(OpCodes.Isinst, typeof(Scp049Role)), - new(OpCodes.Callvirt, PropertyGetter(typeof(Scp049Role), nameof(Scp049Role.SenseAbilityBaseCooldown))), - }); - - for (int z = 0; z < newInstructions.Count; z++) - yield return newInstructions[z]; - - ListPool.Pool.Return(newInstructions); - } - } -} \ No newline at end of file diff --git a/EXILED/Exiled.Events/Patches/Generic/Scp049API/SenseAbilityReducedCooldown.cs b/EXILED/Exiled.Events/Patches/Generic/Scp049API/SenseAbilityReducedCooldown.cs deleted file mode 100644 index 88c8333a1..000000000 --- a/EXILED/Exiled.Events/Patches/Generic/Scp049API/SenseAbilityReducedCooldown.cs +++ /dev/null @@ -1,64 +0,0 @@ -// ----------------------------------------------------------------------- -// -// Copyright (c) Exiled Team. All rights reserved. -// Licensed under the CC BY-SA 3.0 license. -// -// ----------------------------------------------------------------------- - -namespace Exiled.Events.Patches.Generic.Scp079API -{ - using System.Collections.Generic; - using System.Reflection.Emit; - - using API.Features.Pools; - using Exiled.API.Features; - - using HarmonyLib; - using PlayerRoles.PlayableScps.Scp049; - using PlayerRoles.Subroutines; - - using static HarmonyLib.AccessTools; - - using BaseScp049Role = PlayerRoles.PlayableScps.Scp049.Scp049Role; - using Scp049Role = API.Features.Roles.Scp049Role; - - /// - /// Patches . - /// Adds the property. - /// - // [HarmonyPatch(typeof(Scp049SenseAbility), nameof(Scp049SenseAbility.ServerLoseTarget))] - internal class SenseAbilityReducedCooldown - { - private static IEnumerable Transpiler(IEnumerable instructions, ILGenerator generator) - { - List newInstructions = ListPool.Pool.Get(instructions); - - LocalBuilder scp049Role = generator.DeclareLocal(typeof(Scp049Role)); - - // replace "this.Duration.Trigger(40.0)" with "this.Duration.Trigger((Player.Get(base.Owner).Role as Scp049Role).SenseAbilityReducedCooldown)" - int offset = -1; - int index = newInstructions.FindIndex(instruction => instruction.operand == (object)Method(typeof(AbilityCooldown), nameof(AbilityCooldown.Trigger))) + offset; - newInstructions.RemoveAt(index); - - newInstructions.InsertRange( - index, - new CodeInstruction[] - { - // Player.Get(base.Owner).Role - new(OpCodes.Ldarg_0), - new(OpCodes.Call, PropertyGetter(typeof(StandardSubroutine), nameof(StandardSubroutine.Owner))), - new(OpCodes.Call, Method(typeof(Player), nameof(Player.Get), new[] { typeof(ReferenceHub) })), - new(OpCodes.Callvirt, PropertyGetter(typeof(Player), nameof(Player.Role))), - - // (Player.Get(base.Owner).Role as Scp049Role).SenseAbilityReducedCooldown - new(OpCodes.Isinst, typeof(Scp049Role)), - new(OpCodes.Callvirt, PropertyGetter(typeof(Scp049Role), nameof(Scp049Role.SenseAbilityReducedCooldown))), - }); - - for (int z = 0; z < newInstructions.Count; z++) - yield return newInstructions[z]; - - ListPool.Pool.Return(newInstructions); - } - } -} \ No newline at end of file diff --git a/EXILED/Exiled.Events/Patches/Generic/Scp106API/CooldownReductionReward.cs b/EXILED/Exiled.Events/Patches/Generic/Scp106API/CooldownReductionReward.cs deleted file mode 100644 index 4f509aad2..000000000 --- a/EXILED/Exiled.Events/Patches/Generic/Scp106API/CooldownReductionReward.cs +++ /dev/null @@ -1,67 +0,0 @@ -// ----------------------------------------------------------------------- -// -// Copyright (c) Exiled Team. All rights reserved. -// Licensed under the CC BY-SA 3.0 license. -// -// ----------------------------------------------------------------------- - -namespace Exiled.Events.Patches.Generic.Scp106API -{ - using System.Collections.Generic; - using System.Reflection; - using System.Reflection.Emit; - - using API.Features.Pools; - using Exiled.API.Features; - using HarmonyLib; - using PlayerRoles.PlayableScps.Scp106; - using PlayerRoles.Subroutines; - - using static HarmonyLib.AccessTools; - - using BaseScp106Role = PlayerRoles.PlayableScps.Scp106.Scp106Role; - using Scp106Role = API.Features.Roles.Scp106Role; - - /// - /// Patches . - /// Adds the property. - /// - // [HarmonyPatch(typeof(Scp106Attack), nameof(Scp106Attack.ReduceSinkholeCooldown))] - internal class CooldownReductionReward - { - private static IEnumerable Transpiler(IEnumerable instructions, ILGenerator generator) - { - List newInstructions = ListPool.Pool.Get(instructions); - - LocalBuilder scp049Role = generator.DeclareLocal(typeof(Scp106Role)); - - // replace "base.ScpRole.Sinkhole.Cooldown.NextUse -= 5.0; - // with - // Scp106Role scp106Role = Player.Get(this.Owner).Role.As() - // replace "base.ScpRole.Sinkhole.Cooldown.NextUse -= scp106Role.CooldownReductionReward; - int offset = 0; - int index = newInstructions.FindLastIndex(instruction => instruction.opcode == OpCodes.Ldc_R4) + offset; - newInstructions.RemoveAt(index); - - newInstructions.InsertRange( - index, - new CodeInstruction[] - { - // Player.Get(base.Owner).Role - new(OpCodes.Ldarg_0), - new(OpCodes.Call, PropertyGetter(typeof(StandardSubroutine), nameof(StandardSubroutine.Owner))), - new(OpCodes.Call, Method(typeof(Player), nameof(Player.Get), new[] { typeof(ReferenceHub) })), - new(OpCodes.Callvirt, PropertyGetter(typeof(Player), nameof(Player.Role))), - - // (Player.Get(base.Owner).Role as Scp106Role).CooldownReductionReward - new(OpCodes.Isinst, typeof(Scp106Role)), - new(OpCodes.Callvirt, PropertyGetter(typeof(Scp106Role), nameof(Scp106Role.CooldownReductionReward))), - }); - - for (int z = 0; z < newInstructions.Count; z++) - yield return newInstructions[z]; - - ListPool.Pool.Return(newInstructions); - } - } -} diff --git a/EXILED/Exiled.Events/Patches/Generic/Scp106API/CustomAttack.cs b/EXILED/Exiled.Events/Patches/Generic/Scp106API/CustomAttack.cs deleted file mode 100644 index f6469919a..000000000 --- a/EXILED/Exiled.Events/Patches/Generic/Scp106API/CustomAttack.cs +++ /dev/null @@ -1,111 +0,0 @@ -// ----------------------------------------------------------------------- -// -// Copyright (c) Exiled Team. All rights reserved. -// Licensed under the CC BY-SA 3.0 license. -// -// ----------------------------------------------------------------------- - -namespace Exiled.Events.Patches.Generic.Scp106API -{ - using System.Collections.Generic; - using System.Reflection.Emit; - - using API.Features.Pools; - using Exiled.API.Features; - using HarmonyLib; - using PlayerRoles.PlayableScps.Scp106; - using PlayerRoles.Subroutines; - - using static HarmonyLib.AccessTools; - - using BaseScp106Role = PlayerRoles.PlayableScps.Scp106.Scp106Role; - using Scp106Role = API.Features.Roles.Scp106Role; - - /// - /// Patches . - /// Adds the , , property. - /// - // [HarmonyPatch(typeof(Scp106Attack), nameof(Scp106Attack.ServerShoot))] - internal class CustomAttack - { - private static IEnumerable Transpiler(IEnumerable instructions, ILGenerator generator) - { - List newInstructions = ListPool.Pool.Get(instructions); - - LocalBuilder scp049Role = generator.DeclareLocal(typeof(Scp106Role)); - - // replace "base.Vigor.VigorAmount += 0.3f;" - // with - // Scp106Role scp106Role = Player.Get(this.Owner).Role.As() - // "base.Vigor.VigorAmount += scp106Role.VigorCaptureReward;" - int offset = 0; - int index = newInstructions.FindIndex(instruction => instruction.operand == (object)Scp106Attack.VigorCaptureReward) + offset; - newInstructions.RemoveAt(index); - - newInstructions.InsertRange( - index, - new CodeInstruction[] - { - // Player.Get(base.Owner).Role - new(OpCodes.Ldarg_0), - new(OpCodes.Call, PropertyGetter(typeof(StandardSubroutine), nameof(StandardSubroutine.Owner))), - new(OpCodes.Call, Method(typeof(Player), nameof(Player.Get), new[] { typeof(ReferenceHub) })), - new(OpCodes.Callvirt, PropertyGetter(typeof(Player), nameof(Player.Role))), - - // (Player.Get(base.Owner).Role as Scp106Role).AttackDamage - new(OpCodes.Isinst, typeof(Scp106Role)), - new(OpCodes.Callvirt, PropertyGetter(typeof(Scp106Role), nameof(Scp106Role.VigorCaptureReward))), - }); - - // replace "base.Vigor.VigorAmount += 0.3f;" - // with - // Scp106Role scp106Role = Player.Get(this.Owner).Role.As() - // "base.Vigor.VigorAmount += scp106Role.VigorCaptureReward;" - offset = 0; - index = newInstructions.FindIndex(instruction => instruction.operand == (object)Scp106Attack.VigorCaptureReward) + offset; - newInstructions.RemoveAt(index); - - newInstructions.InsertRange( - index, - new CodeInstruction[] - { - // Player.Get(base.Owner).Role - new(OpCodes.Ldarg_0), - new(OpCodes.Call, PropertyGetter(typeof(StandardSubroutine), nameof(StandardSubroutine.Owner))), - new(OpCodes.Call, Method(typeof(Player), nameof(Player.Get), new[] { typeof(ReferenceHub) })), - new(OpCodes.Callvirt, PropertyGetter(typeof(Player), nameof(Player.Role))), - - // (Player.Get(base.Owner).Role as Scp106Role).AttackDamage - new(OpCodes.Isinst, typeof(Scp106Role)), - new(OpCodes.Callvirt, PropertyGetter(typeof(Scp106Role), nameof(Scp106Role.VigorCaptureReward))), - }); - - // replace "playerEffectsController.EnableEffect(20f, false);" - // with - // Scp106Role scp106Role = Player.Get(this.Owner).Role.As() - // "playerEffectsController.EnableEffect(scp106Role.CorrodingTime, false);" - offset = 0; - index = newInstructions.FindLastIndex(instruction => instruction.opcode == OpCodes.Ldc_R4) + offset; - newInstructions.RemoveAt(index); - - newInstructions.InsertRange( - index, - new CodeInstruction[] - { - // Player.Get(base.Owner).Role - new(OpCodes.Ldarg_0), - new(OpCodes.Call, PropertyGetter(typeof(StandardSubroutine), nameof(StandardSubroutine.Owner))), - new(OpCodes.Call, Method(typeof(Player), nameof(Player.Get), new[] { typeof(ReferenceHub) })), - new(OpCodes.Callvirt, PropertyGetter(typeof(Player), nameof(Player.Role))), - - // (Player.Get(base.Owner).Role as Scp106Role).CorrodingTime - new(OpCodes.Isinst, typeof(Scp106Role)), - new(OpCodes.Callvirt, PropertyGetter(typeof(Scp106Role), nameof(Scp106Role.CorrodingTime))), - }); - for (int z = 0; z < newInstructions.Count; z++) - yield return newInstructions[z]; - - ListPool.Pool.Return(newInstructions); - } - } -} diff --git a/EXILED/Exiled.Events/Patches/Generic/Scp106API/HunterAtlastCostPerMetter.cs b/EXILED/Exiled.Events/Patches/Generic/Scp106API/HunterAtlastCostPerMetter.cs deleted file mode 100644 index d85ac0151..000000000 --- a/EXILED/Exiled.Events/Patches/Generic/Scp106API/HunterAtlastCostPerMetter.cs +++ /dev/null @@ -1,67 +0,0 @@ -// ----------------------------------------------------------------------- -// -// Copyright (c) Exiled Team. All rights reserved. -// Licensed under the CC BY-SA 3.0 license. -// -// ----------------------------------------------------------------------- - -namespace Exiled.Events.Patches.Generic.Scp106API -{ - using System.Collections.Generic; - using System.Reflection; - using System.Reflection.Emit; - - using API.Features.Pools; - using Exiled.API.Features; - using HarmonyLib; - using PlayerRoles.PlayableScps.Scp106; - using PlayerRoles.Subroutines; - - using static HarmonyLib.AccessTools; - - using BaseScp106Role = PlayerRoles.PlayableScps.Scp106.Scp106Role; - using Scp106Role = API.Features.Roles.Scp106Role; - - /// - /// Patches . - /// Adds the property. - /// - // [HarmonyPatch(typeof(Scp106HuntersAtlasAbility), nameof(Scp106HuntersAtlasAbility.ServerProcessCmd))] - internal class HunterAtlastCostPerMetter - { - private static IEnumerable Transpiler(IEnumerable instructions, ILGenerator generator) - { - List newInstructions = ListPool.Pool.Get(instructions); - - LocalBuilder scp049Role = generator.DeclareLocal(typeof(Scp106Role)); - - // replace "num = (position2 - this._syncPos).MagnitudeIgnoreY() * 0.019f;" - // with - // Scp106Role scp106Role = Player.Get(this.Owner).Role.As() - // replace "num = (position2 - this._syncPos).MagnitudeIgnoreY() * scp106Role.HuntersAtlasCostPerMeter;" - int offset = 0; - int index = newInstructions.FindLastIndex(instruction => instruction.opcode == OpCodes.Ldc_R4) + offset; - newInstructions.RemoveAt(index); - - newInstructions.InsertRange( - index, - new CodeInstruction[] - { - // Player.Get(base.Owner).Role - new(OpCodes.Ldarg_0), - new(OpCodes.Call, PropertyGetter(typeof(StandardSubroutine), nameof(StandardSubroutine.Owner))), - new(OpCodes.Call, Method(typeof(Player), nameof(Player.Get), new[] { typeof(ReferenceHub) })), - new(OpCodes.Callvirt, PropertyGetter(typeof(Player), nameof(Player.Role))), - - // (Player.Get(base.Owner).Role as Scp106Role).HuntersAtlasCostPerMeter - new(OpCodes.Isinst, typeof(Scp106Role)), - new(OpCodes.Callvirt, PropertyGetter(typeof(Scp106Role), nameof(Scp106Role.HuntersAtlasCostPerMeter))), - }); - - for (int z = 0; z < newInstructions.Count; z++) - yield return newInstructions[z]; - - ListPool.Pool.Return(newInstructions); - } - } -} diff --git a/EXILED/Exiled.Events/Patches/Generic/Scp106API/SinkholeAbilityCooldown.cs b/EXILED/Exiled.Events/Patches/Generic/Scp106API/SinkholeAbilityCooldown.cs deleted file mode 100644 index 519fef858..000000000 --- a/EXILED/Exiled.Events/Patches/Generic/Scp106API/SinkholeAbilityCooldown.cs +++ /dev/null @@ -1,67 +0,0 @@ -// ----------------------------------------------------------------------- -// -// Copyright (c) Exiled Team. All rights reserved. -// Licensed under the CC BY-SA 3.0 license. -// -// ----------------------------------------------------------------------- - -namespace Exiled.Events.Patches.Generic.Scp106API -{ - using System.Collections.Generic; - using System.Reflection; - using System.Reflection.Emit; - - using API.Features.Pools; - using Exiled.API.Features; - using HarmonyLib; - using PlayerRoles.PlayableScps.Scp106; - using PlayerRoles.Subroutines; - - using static HarmonyLib.AccessTools; - - using BaseScp106Role = PlayerRoles.PlayableScps.Scp106.Scp106Role; - using Scp106Role = API.Features.Roles.Scp106Role; - - /// - /// Patches . - /// Adds the property. - /// - // [HarmonyPatch(typeof(Scp106Attack), nameof(Scp106Attack.ReduceSinkholeCooldown))] - internal class SinkholeAbilityCooldown - { - private static IEnumerable Transpiler(IEnumerable instructions, ILGenerator generator) - { - List newInstructions = ListPool.Pool.Get(instructions); - - LocalBuilder scp049Role = generator.DeclareLocal(typeof(Scp106Role)); - - // replace "this.Cooldown.Trigger(20.0);" - // with - // Scp106Role scp106Role = Player.Get(this.Owner).Role.As() - // replace "this.Cooldown.Trigger(scp106Role.SinkholeCooldownDuration);" - int offset = 0; - int index = newInstructions.FindLastIndex(instruction => instruction.opcode == OpCodes.Ldc_R4) + offset; - newInstructions.RemoveAt(index); - - newInstructions.InsertRange( - index, - new CodeInstruction[] - { - // Player.Get(base.Owner).Role - new(OpCodes.Ldarg_0), - new(OpCodes.Call, PropertyGetter(typeof(StandardSubroutine), nameof(StandardSubroutine.Owner))), - new(OpCodes.Call, Method(typeof(Player), nameof(Player.Get), new[] { typeof(ReferenceHub) })), - new(OpCodes.Callvirt, PropertyGetter(typeof(Player), nameof(Player.Role))), - - // (Player.Get(base.Owner).Role as Scp106Role).SinkholeCooldownDuration - new(OpCodes.Isinst, typeof(Scp106Role)), - new(OpCodes.Callvirt, PropertyGetter(typeof(Scp106Role), nameof(Scp106Role.SinkholeCooldownDuration))), - }); - - for (int z = 0; z < newInstructions.Count; z++) - yield return newInstructions[z]; - - ListPool.Pool.Return(newInstructions); - } - } -} diff --git a/EXILED/Exiled.Events/Patches/Generic/Scp106API/StalkVigorUse.cs b/EXILED/Exiled.Events/Patches/Generic/Scp106API/StalkVigorUse.cs deleted file mode 100644 index 38b7a9e53..000000000 --- a/EXILED/Exiled.Events/Patches/Generic/Scp106API/StalkVigorUse.cs +++ /dev/null @@ -1,84 +0,0 @@ -// ----------------------------------------------------------------------- -// -// Copyright (c) Exiled Team. All rights reserved. -// Licensed under the CC BY-SA 3.0 license. -// -// ----------------------------------------------------------------------- - -namespace Exiled.Events.Patches.Generic.Scp106API -{ - using System.Collections.Generic; - using System.Reflection.Emit; - - using API.Features.Pools; - using Exiled.API.Features; - using HarmonyLib; - using PlayerRoles.PlayableScps.Scp106; - using PlayerRoles.Subroutines; - - using static HarmonyLib.AccessTools; - - using BaseScp106Role = PlayerRoles.PlayableScps.Scp106.Scp106Role; - using Scp106Role = API.Features.Roles.Scp106Role; - - /// - /// Patches . - /// Adds the and property. - /// - // [HarmonyPatch(typeof(Scp106StalkAbility), nameof(Scp106StalkAbility.UpdateServerside))] - internal class StalkVigorUse - { - private static IEnumerable Transpiler(IEnumerable instructions, ILGenerator generator) - { - List newInstructions = ListPool.Pool.Get(instructions); - - LocalBuilder scp049Role = generator.DeclareLocal(typeof(Scp106Role)); - - // replace "float num = base.ScpRole.FpcModule.Motor.MovementDetected ? 0.09f : 0.06f;" - // with - // Scp106Role scp106Role = Player.Get(this.Owner).Role.As() - // "float num = base.ScpRole.FpcModule.Motor.MovementDetected ? scp106Role.VigorStalkCostMoving : scp106Role.VigorStalkCostStationary;" - int offset = 0; - int index = newInstructions.FindIndex(instruction => instruction.opcode == OpCodes.Ldc_R4) + offset; - newInstructions.RemoveAt(index); - - newInstructions.InsertRange( - index, - new CodeInstruction[] - { - // Player.Get(base.Owner).Role - new(OpCodes.Ldarg_0), - new(OpCodes.Call, PropertyGetter(typeof(StandardSubroutine), nameof(StandardSubroutine.Owner))), - new(OpCodes.Call, Method(typeof(Player), nameof(Player.Get), new[] { typeof(ReferenceHub) })), - new(OpCodes.Callvirt, PropertyGetter(typeof(Player), nameof(Player.Role))), - - // (Player.Get(base.Owner).Role as Scp106Role).VigorStalkCostMoving - new(OpCodes.Isinst, typeof(Scp106Role)), - new(OpCodes.Callvirt, PropertyGetter(typeof(Scp106Role), nameof(Scp106Role.VigorStalkCostMoving))), - }); - - offset = 0; - index = newInstructions.FindIndex(instruction => instruction.opcode == OpCodes.Ldc_R4) + offset; - newInstructions.RemoveAt(index); - - newInstructions.InsertRange( - index, - new CodeInstruction[] - { - // Player.Get(base.Owner).Role - new(OpCodes.Ldarg_0), - new(OpCodes.Call, PropertyGetter(typeof(StandardSubroutine), nameof(StandardSubroutine.Owner))), - new(OpCodes.Call, Method(typeof(Player), nameof(Player.Get), new[] { typeof(ReferenceHub) })), - new(OpCodes.Callvirt, PropertyGetter(typeof(Player), nameof(Player.Role))), - - // (Player.Get(base.Owner).Role as Scp106Role).VigorStalkCostStationary - new(OpCodes.Isinst, typeof(Scp106Role)), - new(OpCodes.Callvirt, PropertyGetter(typeof(Scp106Role), nameof(Scp106Role.VigorStalkCostStationary))), - }); - for (int z = 0; z < newInstructions.Count; z++) - yield return newInstructions[z]; - - ListPool.Pool.Return(newInstructions); - } - } -} diff --git a/EXILED/Exiled.Events/Patches/Generic/Scp106API/VigorRegeneration.cs b/EXILED/Exiled.Events/Patches/Generic/Scp106API/VigorRegeneration.cs deleted file mode 100644 index f14fd51d1..000000000 --- a/EXILED/Exiled.Events/Patches/Generic/Scp106API/VigorRegeneration.cs +++ /dev/null @@ -1,66 +0,0 @@ -// ----------------------------------------------------------------------- -// -// Copyright (c) Exiled Team. All rights reserved. -// Licensed under the CC BY-SA 3.0 license. -// -// ----------------------------------------------------------------------- - -namespace Exiled.Events.Patches.Generic.Scp106API -{ - using System.Collections.Generic; - using System.Reflection.Emit; - - using API.Features.Pools; - using Exiled.API.Features; - using HarmonyLib; - using PlayerRoles.PlayableScps.Scp106; - using PlayerRoles.Subroutines; - - using static HarmonyLib.AccessTools; - - using BaseScp106Role = PlayerRoles.PlayableScps.Scp106.Scp106Role; - using Scp106Role = API.Features.Roles.Scp106Role; - - /// - /// Patches . - /// Adds the property. - /// - // [HarmonyPatch(typeof(Scp106StalkAbility), nameof(Scp106StalkAbility.UpdateMovementState))] - internal class VigorRegeneration - { - private static IEnumerable Transpiler(IEnumerable instructions, ILGenerator generator) - { - List newInstructions = ListPool.Pool.Get(instructions); - - LocalBuilder scp049Role = generator.DeclareLocal(typeof(Scp106Role)); - - // replace "base.Vigor.VigorAmount += 0.03f * Time.deltaTime;" - // with - // Scp106Role scp106Role = Player.Get(this.Owner).Role.As() - // "base.Vigor.VigorAmount += scp106Role.VigorRegeneration * Time.deltaTime;" - int offset = -4; - int index = newInstructions.FindIndex(instruction => instruction.operand == (object)PropertySetter(typeof(Scp106VigorAbilityBase), nameof(Scp106VigorAbilityBase.VigorAmount))) + offset; - newInstructions.RemoveAt(index); - - newInstructions.InsertRange( - index, - new CodeInstruction[] - { - // Player.Get(base.Owner).Role - new(OpCodes.Ldarg_0), - new(OpCodes.Call, PropertyGetter(typeof(StandardSubroutine), nameof(StandardSubroutine.Owner))), - new(OpCodes.Call, Method(typeof(Player), nameof(Player.Get), new[] { typeof(ReferenceHub) })), - new(OpCodes.Callvirt, PropertyGetter(typeof(Player), nameof(Player.Role))), - - // (Player.Get(base.Owner).Role as Scp106Role).VigorRegeneration - new(OpCodes.Isinst, typeof(Scp106Role)), - new(OpCodes.Callvirt, PropertyGetter(typeof(Scp106Role), nameof(Scp106Role.VigorRegeneration))), - }); - - for (int z = 0; z < newInstructions.Count; z++) - yield return newInstructions[z]; - - ListPool.Pool.Return(newInstructions); - } - } -} From 4654bf21815cb2a478d63c1e978f2f6e28a12119 Mon Sep 17 00:00:00 2001 From: x3rt Date: Wed, 31 Jul 2024 16:26:25 -0600 Subject: [PATCH 34/58] Clear Ammo before Clearing Items (#4) --- EXILED/Exiled.API/Features/Player.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/EXILED/Exiled.API/Features/Player.cs b/EXILED/Exiled.API/Features/Player.cs index 4991e13d4..def165726 100644 --- a/EXILED/Exiled.API/Features/Player.cs +++ b/EXILED/Exiled.API/Features/Player.cs @@ -2728,8 +2728,8 @@ public void ResetInventory(IEnumerable newItems) /// public void ClearInventory(bool destroy = true) { - ClearItems(destroy); ClearAmmo(); + ClearItems(destroy); } /// From 596a425645cfd7e23360fd92da89616ce64aed01 Mon Sep 17 00:00:00 2001 From: Jesus QC <69375249+Jesus-QC@users.noreply.github.com> Date: Thu, 1 Aug 2024 01:21:28 +0200 Subject: [PATCH 35/58] fetching master (#138) Co-authored-by: Nameless <85962933+Misfiy@users.noreply.github.com> Co-authored-by: Misaka-ZeroTwo <45165615+Misaka-ZeroTwo@users.noreply.github.com> --- .github/labeler.yml | 13 ++++++------- .github/workflows/main.yml | 2 +- .github/workflows/release.yml | 4 ++-- EXILED/Exiled.Installer/Program.cs | 4 ++-- EXILED/Exiled.Loader/Updater.cs | 4 ++-- 5 files changed, 13 insertions(+), 14 deletions(-) diff --git a/.github/labeler.yml b/.github/labeler.yml index 34ff31f3f..5098459b0 100644 --- a/.github/labeler.yml +++ b/.github/labeler.yml @@ -13,29 +13,28 @@ Scripts: # Add the 'Scripts' label regarding-events: # Add the 'Events' label - changed-files: - - any-glob-to-any-file: Exiled.Events/** # Any Modifications to events + - any-glob-to-any-file: EXILED/Exiled.Events/** # Any Modifications to events regarding-api: # Add the 'API' label - changed-files: - - any-glob-to-any-file: Exiled.API/** # Any modifications to the API + - any-glob-to-any-file: EXILED/Exiled.API/** # Any modifications to the API regarding-transpiler: # Add the 'transpiler' label - changed-files: - - any-glob-to-any-file: Exiled.Events/Patches/**/* # Any modifications to transpiler files + - any-glob-to-any-file: EXILED/Exiled.Events/Patches/**/* # Any modifications to transpiler files CustomModules: # Add the 'CustomModules' label - changed-files: - - any-glob-to-any-file: Exiled.CustomModules/** # Any modifications to CustomModules + - any-glob-to-any-file: EXILED/Exiled.CustomModules/** # Any modifications to CustomModules Installer: # Add the 'Installer' label - changed-files: - - any-glob-to-any-file: Exiled.Installer/** # Any modifications to the Installer + - any-glob-to-any-file: EXILED/Exiled.Installer/** # Any modifications to the Installer Localization: # Add the 'Localization' label - changed-files: - - any-glob-to-any-file: Localization/** # Any modifications to Localization + - any-glob-to-any-file: EXILED/Localization/** # Any modifications to Localization GitHub_Actions: # Add the 'GitHub' label - changed-files: - any-glob-to-any-file: .github/** # Any modifications to github related files - diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 7be77c41a..6f9bc0f85 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -13,7 +13,7 @@ defaults: working-directory: ./EXILED env: - EXILED_REFERENCES_URL: https://Exiled-Official.github.io/SL-References/Master.zip + EXILED_REFERENCES_URL: https://exmod-team.github.io/SL-References/Master.zip EXILED_REFERENCES_PATH: ${{ github.workspace }}/EXILED/References jobs: diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index bcbe907cc..efdac4cc8 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -11,9 +11,9 @@ defaults: working-directory: ./EXILED env: - EXILED_REFERENCES_URL: https://Exiled-Official.github.io/SL-References/Dev.zip + EXILED_REFERENCES_URL: https://exmod-team.github.io/SL-References/Dev.zip EXILED_REFERENCES_PATH: ${{ github.workspace }}/EXILED/References - EXILED_DLL_ARCHIVER_URL: https://github.com/Exiled-Official/EXILED-DLL-Archiver/releases/latest/download/EXILED-DLL-Archiver.exe + EXILED_DLL_ARCHIVER_URL: https://github.com/ExMod-Team/EXILED-DLL-Archiver/releases/latest/download/EXILED-DLL-Archiver.exe jobs: build: diff --git a/EXILED/Exiled.Installer/Program.cs b/EXILED/Exiled.Installer/Program.cs index 34912cc51..559c17c82 100644 --- a/EXILED/Exiled.Installer/Program.cs +++ b/EXILED/Exiled.Installer/Program.cs @@ -42,7 +42,7 @@ internal enum PathResolution internal static class Program { - private const long RepoID = 828620622; + private const long RepoID = 833723500; private const string ExiledAssetName = "exiled.tar.gz"; // This is the lowest version the installer will check to install @@ -303,4 +303,4 @@ private static Release FindRelease(CommandSettings args, IEnumerable re return enumerable.First(); } } -} \ No newline at end of file +} diff --git a/EXILED/Exiled.Loader/Updater.cs b/EXILED/Exiled.Loader/Updater.cs index 6990c1812..fb0636570 100644 --- a/EXILED/Exiled.Loader/Updater.cs +++ b/EXILED/Exiled.Loader/Updater.cs @@ -31,7 +31,7 @@ namespace Exiled.Loader /// internal sealed class Updater { - private const long REPOID = 828620622; + private const long REPOID = 833723500; private const string INSTALLER_ASSET_NAME_LINUX = "Exiled.Installer-Linux"; private const string INSTALLER_ASSET_NAME_WIN = "Exiled.Installer-Win.exe"; @@ -332,4 +332,4 @@ private bool FindAsset(string assetName, Release release, out ReleaseAsset asset return false; } } -} \ No newline at end of file +} From 2b0276b62ba06808e4ccf900ef58152f889d55b6 Mon Sep 17 00:00:00 2001 From: Misaka-ZeroTwo <45165615+Misaka-ZeroTwo@users.noreply.github.com> Date: Thu, 1 Aug 2024 20:49:03 +0800 Subject: [PATCH 36/58] Update labeler.yml --- .github/labeler.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/labeler.yml b/.github/labeler.yml index 5098459b0..97048dd23 100644 --- a/.github/labeler.yml +++ b/.github/labeler.yml @@ -35,6 +35,6 @@ Localization: # Add the 'Localization' label - changed-files: - any-glob-to-any-file: EXILED/Localization/** # Any modifications to Localization -GitHub_Actions: # Add the 'GitHub' label +GitHub: # Add the 'GitHub' label - changed-files: - any-glob-to-any-file: .github/** # Any modifications to github related files From 04bffe85addfc161051d32bb41fc2828062d21d1 Mon Sep 17 00:00:00 2001 From: Misaka-ZeroTwo <45165615+Misaka-ZeroTwo@users.noreply.github.com> Date: Thu, 1 Aug 2024 20:49:20 +0800 Subject: [PATCH 37/58] Update labeler.yml --- .github/labeler.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/labeler.yml b/.github/labeler.yml index 5098459b0..97048dd23 100644 --- a/.github/labeler.yml +++ b/.github/labeler.yml @@ -35,6 +35,6 @@ Localization: # Add the 'Localization' label - changed-files: - any-glob-to-any-file: EXILED/Localization/** # Any modifications to Localization -GitHub_Actions: # Add the 'GitHub' label +GitHub: # Add the 'GitHub' label - changed-files: - any-glob-to-any-file: .github/** # Any modifications to github related files From 0698e6ee9f55adae1f2e37375226842b3986fef4 Mon Sep 17 00:00:00 2001 From: ZeroTwo <63092138+NotZer0Two@users.noreply.github.com> Date: Thu, 1 Aug 2024 19:41:18 +0200 Subject: [PATCH 38/58] `[Exiled::API]` Added WhitelistedPlayers, SetIntercomDisplayTextForTargetOnly and ResetIntercomDisplayText (#6) * Sync Changes * Suggestion Co-authored-by: Misaka-ZeroTwo <45165615+Misaka-ZeroTwo@users.noreply.github.com> --------- Co-authored-by: Misaka-ZeroTwo <45165615+Misaka-ZeroTwo@users.noreply.github.com> --- EXILED/Exiled.API/Extensions/MirrorExtensions.cs | 13 +++++++++++++ EXILED/Exiled.API/Features/Server.cs | 5 +++++ 2 files changed, 18 insertions(+) diff --git a/EXILED/Exiled.API/Extensions/MirrorExtensions.cs b/EXILED/Exiled.API/Extensions/MirrorExtensions.cs index 8b30327d4..2dd66766c 100644 --- a/EXILED/Exiled.API/Extensions/MirrorExtensions.cs +++ b/EXILED/Exiled.API/Extensions/MirrorExtensions.cs @@ -25,6 +25,7 @@ namespace Exiled.API.Extensions using PlayerRoles; using PlayerRoles.FirstPersonControl; using PlayerRoles.PlayableScps.Scp049.Zombies; + using PlayerRoles.Voice; using RelativePositioning; using Respawning; @@ -181,6 +182,18 @@ public static void PlayGunSound(this Player player, Vector3 position, ItemType i player.Connection.Send(message); } + /// + /// Sets that only the player can see. + /// + /// Only this player can see Display Text. + /// Text displayed to the player. + public static void SetIntercomDisplayTextForTargetOnly(this Player target, string text) => target.SendFakeSyncVar(IntercomDisplay._singleton.netIdentity, typeof(IntercomDisplay), nameof(IntercomDisplay.Network_overrideText), text); + + /// + /// Resync . + /// + public static void ResetIntercomDisplayText() => ResyncSyncVar(IntercomDisplay._singleton.netIdentity, typeof(IntercomDisplay), nameof(IntercomDisplay.Network_overrideText)); + /// /// Sets of a that only the player can see. /// diff --git a/EXILED/Exiled.API/Features/Server.cs b/EXILED/Exiled.API/Features/Server.cs index 26cf64c98..908096434 100644 --- a/EXILED/Exiled.API/Features/Server.cs +++ b/EXILED/Exiled.API/Features/Server.cs @@ -178,6 +178,11 @@ public static bool IsWhitelisted set => ServerConsole.WhiteListEnabled = value; } + /// + /// Gets the list of user IDs of players currently whitelisted. + /// + public static HashSet WhitelistedPlayers => WhiteList.Users; + /// /// Gets a value indicating whether or not this server is verified. /// From 2e1686e120528c4d7dfaf7b6f1ec7d369ad33a26 Mon Sep 17 00:00:00 2001 From: Misaka-ZeroTwo <45165615+Misaka-ZeroTwo@users.noreply.github.com> Date: Fri, 2 Aug 2024 01:46:22 +0800 Subject: [PATCH 39/58] Fix ChargingJailbird (#2) * Update ChargingJailbirdEventArgs.cs * Update JailbirdPatch.cs * Update dev.yml * Update labeler.yml --- .../EventArgs/Item/ChargingJailbirdEventArgs.cs | 11 ++++++++++- .../Patches/Events/Item/JailbirdPatch.cs | 5 +---- 2 files changed, 11 insertions(+), 5 deletions(-) diff --git a/EXILED/Exiled.Events/EventArgs/Item/ChargingJailbirdEventArgs.cs b/EXILED/Exiled.Events/EventArgs/Item/ChargingJailbirdEventArgs.cs index 1b17a1bb0..38f6ea7f8 100644 --- a/EXILED/Exiled.Events/EventArgs/Item/ChargingJailbirdEventArgs.cs +++ b/EXILED/Exiled.Events/EventArgs/Item/ChargingJailbirdEventArgs.cs @@ -7,6 +7,8 @@ namespace Exiled.Events.EventArgs.Item { + using System; + using Exiled.API.Features; using Exiled.API.Features.Items; using Exiled.Events.EventArgs.Interfaces; @@ -26,7 +28,9 @@ public ChargingJailbirdEventArgs(ReferenceHub player, InventorySystem.Items.Item { Player = Player.Get(player); Item = Item.Get(swingItem); +#pragma warning disable CS0618 IsAllowed = isAllowed; +#pragma warning restore CS0618 } /// @@ -42,6 +46,11 @@ public ChargingJailbirdEventArgs(ReferenceHub player, InventorySystem.Items.Item /// /// Gets or sets a value indicating whether or not the Jailbird can be charged. /// - public bool IsAllowed { get; set; } + public bool IsAllowed + { + get; + [Obsolete("This event cannot be denied as it will cause desync.")] + set; + } } } diff --git a/EXILED/Exiled.Events/Patches/Events/Item/JailbirdPatch.cs b/EXILED/Exiled.Events/Patches/Events/Item/JailbirdPatch.cs index ec33236e0..1f8489fd3 100644 --- a/EXILED/Exiled.Events/Patches/Events/Item/JailbirdPatch.cs +++ b/EXILED/Exiled.Events/Patches/Events/Item/JailbirdPatch.cs @@ -88,10 +88,7 @@ private static bool HandleJailbird(JailbirdItem instance, JailbirdMessageType me ChargingJailbirdEventArgs ev = new(instance.Owner, instance); Item.OnChargingJailbird(ev); - if (ev.IsAllowed) - return true; - instance.SendRpc(JailbirdMessageType.ChargeFailed, null); - return false; + return true; } default: From ef07853c3740c51f5379be7c4a96d377811af77f Mon Sep 17 00:00:00 2001 From: VALERA771 <72030575+VALERA771@users.noreply.github.com> Date: Thu, 1 Aug 2024 22:10:58 +0300 Subject: [PATCH 40/58] Adding auto assignment to pr (#7) * Create auto-assigning.yml * Update and rename labeler.yml to pull_request_opened.yml * Delete .github/workflows/auto-assigning.yml --- .github/workflows/{labeler.yml => pull_request_opened.yml} | 4 ++++ 1 file changed, 4 insertions(+) rename .github/workflows/{labeler.yml => pull_request_opened.yml} (79%) diff --git a/.github/workflows/labeler.yml b/.github/workflows/pull_request_opened.yml similarity index 79% rename from .github/workflows/labeler.yml rename to .github/workflows/pull_request_opened.yml index 0486bfaec..aa26845fb 100644 --- a/.github/workflows/labeler.yml +++ b/.github/workflows/pull_request_opened.yml @@ -20,3 +20,7 @@ jobs: repo-token: ${{ secrets.GITHUB_TOKEN }} configuration-path: .github/labeler.yml sync-labels: true + assign-author: + runs-on: ubuntu-latest + steps: + - uses: toshimaru/auto-author-assign@v2.1.1 From e6661e8f27e23a47591cba79d08e477490d2284f Mon Sep 17 00:00:00 2001 From: Jesus QC <69375249+Jesus-QC@users.noreply.github.com> Date: Thu, 1 Aug 2024 21:31:13 +0200 Subject: [PATCH 41/58] Update dev.yml --- .github/workflows/dev.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/dev.yml b/.github/workflows/dev.yml index 6a9486427..fc2b53f4f 100644 --- a/.github/workflows/dev.yml +++ b/.github/workflows/dev.yml @@ -14,7 +14,7 @@ defaults: working-directory: ./EXILED env: - EXILED_REFERENCES_URL: https://Exiled-Official.github.io/SL-References/Dev.zip + EXILED_REFERENCES_URL: https://exmod-team.github.io/SL-References/Master.zip EXILED_REFERENCES_PATH: ${{ github.workspace }}/EXILED/References EXILED_DLL_ARCHIVER_URL: https://github.com/Exiled-Official/EXILED-DLL-Archiver/releases/latest/download/EXILED-DLL-Archiver.exe From fe05d8dd6026365e9b1215913ffd8200d0c6823c Mon Sep 17 00:00:00 2001 From: Jesus QC <69375249+Jesus-QC@users.noreply.github.com> Date: Thu, 1 Aug 2024 21:31:50 +0200 Subject: [PATCH 42/58] fixed docs pipeline --- .github/workflows/docs.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/docs.yml b/.github/workflows/docs.yml index 351cdd3be..df73ad9a5 100644 --- a/.github/workflows/docs.yml +++ b/.github/workflows/docs.yml @@ -12,7 +12,7 @@ permissions: id-token: write env: - EXILED_REFERENCES_URL: https://Exiled-Official.github.io/SL-References/Dev.zip + EXILED_REFERENCES_URL: https://exmod-team.github.io/SL-References/Master.zip EXILED_REFERENCES_PATH: ${{ github.workspace }}/EXILED/References # Allow only one concurrent deployment, skipping runs queued between the run in-progress and latest queued. From 5783c17177f406792b3b4f83a5a0f46ed4b1089a Mon Sep 17 00:00:00 2001 From: Misaka-ZeroTwo <45165615+Misaka-ZeroTwo@users.noreply.github.com> Date: Fri, 2 Aug 2024 05:24:38 +0800 Subject: [PATCH 43/58] Pull request template (#10) * Create pull_request_template.md * Update pull_request_template.md * Update pull_request_template.md * Update pull_request_template.md * Update pull_request_template.md --- .github/pull_request_template.md | 35 ++++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) create mode 100644 .github/pull_request_template.md diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md new file mode 100644 index 000000000..032dc22c6 --- /dev/null +++ b/.github/pull_request_template.md @@ -0,0 +1,35 @@ +## Description +**Describe the changes** + + +**What is the current behavior?** (You can also link to an open issue here) + + +**What is the new behavior?** (if this is a feature change) + + +**Does this PR introduce a breaking change?** (What changes might users need to make in their application due to this PR?) + + +**Other information**: + +
+ +## Types of changes + +- [ ] Bug fix (non-breaking change which fixes an issue) +- [ ] New feature (non-breaking change which adds functionality) +- [ ] Breaking change (fix or feature that would cause existing functionality to change) +- [ ] Documentations +
+ +## Submission checklist + +- [ ] I have checked the project can be compiled +- [ ] I have tested my changes and it worked as expected + +### Patches (if there are any changes related to Harmony patches) +- [ ] I have checked no IL patching errors in the console + +### Other +- [ ] Still requires more testing From c9654eee7c41eacf1b4301c45f58ea7c39b14765 Mon Sep 17 00:00:00 2001 From: VALERA771 <72030575+VALERA771@users.noreply.github.com> Date: Fri, 2 Aug 2024 00:26:08 +0300 Subject: [PATCH 44/58] uwu (#5) --- EXILED/Exiled.API/Features/Player.cs | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/EXILED/Exiled.API/Features/Player.cs b/EXILED/Exiled.API/Features/Player.cs index def165726..ed937ead5 100644 --- a/EXILED/Exiled.API/Features/Player.cs +++ b/EXILED/Exiled.API/Features/Player.cs @@ -2319,6 +2319,16 @@ public void Broadcast(ushort duration, string message, global::Broadcast.Broadca public void AddAmmo(AmmoType ammoType, ushort amount) => Inventory.ServerAddAmmo(ammoType.GetItemType(), amount); + /// + /// Adds the amount of a specified ammo type to player's inventory. + /// + /// A dictionary of ammo types that will be added. + public void AddAmmo(Dictionary ammoBag) + { + foreach (KeyValuePair kvp in ammoBag) + AddAmmo(kvp.Key, kvp.Value); + } + /// /// Adds the amount of a weapon's ammo type to the player's inventory. /// @@ -2338,6 +2348,16 @@ public void SetAmmo(AmmoType ammoType, ushort amount) Inventory.ServerSetAmmo(itemType, amount); } + /// + /// Sets the amount of a specified ammo type to player's inventory. + /// + /// A dictionary of ammo types that will be added. + public void SetAmmo(Dictionary ammoBag) + { + foreach (KeyValuePair kvp in ammoBag) + SetAmmo(kvp.Key, kvp.Value); + } + /// /// Gets the ammo count of a specified ammo type in a player's inventory. /// From 0b577df72c4956d5dff1c9e9087cfa6b52674d39 Mon Sep 17 00:00:00 2001 From: Alex Rouse <123724383+ALEXWARELLC@users.noreply.github.com> Date: Fri, 2 Aug 2024 18:29:22 +0800 Subject: [PATCH 45/58] Possible fix for broken GitHub Action. (#25) --- .github/workflows/pull_request_opened.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.github/workflows/pull_request_opened.yml b/.github/workflows/pull_request_opened.yml index aa26845fb..a54bed971 100644 --- a/.github/workflows/pull_request_opened.yml +++ b/.github/workflows/pull_request_opened.yml @@ -22,5 +22,8 @@ jobs: sync-labels: true assign-author: runs-on: ubuntu-latest + permissions: + pull-requests: write + steps: - uses: toshimaru/auto-author-assign@v2.1.1 From 565373318d5aba8d2af3a438a03f2988a8a87e38 Mon Sep 17 00:00:00 2001 From: Yamato <66829532+louis1706@users.noreply.github.com> Date: Fri, 2 Aug 2024 21:12:57 +0200 Subject: [PATCH 46/58] AdminToy.List (#18) * AdminToy.List * Better AdminToy::Get() * Update EXILED/Exiled.API/Features/Toys/AdminToy.cs Co-authored-by: IRacle <79921583+IRacle1@users.noreply.github.com> * TODO * Fix Error * Fix2 --------- Co-authored-by: IRacle <79921583+IRacle1@users.noreply.github.com> --- EXILED/Exiled.API/Features/Map.cs | 7 +--- EXILED/Exiled.API/Features/Toys/AdminToy.cs | 33 +++++++++++++++++-- .../Handlers/Internal/SceneUnloaded.cs | 4 +-- 3 files changed, 33 insertions(+), 11 deletions(-) diff --git a/EXILED/Exiled.API/Features/Map.cs b/EXILED/Exiled.API/Features/Map.cs index 14f6d8214..24edcc90c 100644 --- a/EXILED/Exiled.API/Features/Map.cs +++ b/EXILED/Exiled.API/Features/Map.cs @@ -57,11 +57,6 @@ public static class Map ///
internal static readonly List TeleportsValue = new(8); - /// - /// A list of s on the map. - /// - internal static readonly List ToysValue = new(); - private static TantrumEnvironmentalHazard tantrumPrefab; private static Scp939AmnesticCloudInstance amnesticCloudPrefab; @@ -130,7 +125,7 @@ DecontaminationController.Singleton.NetworkDecontaminationOverride is Decontamin /// /// Gets all objects. /// - public static ReadOnlyCollection Toys { get; } = ToysValue.AsReadOnly(); + public static ReadOnlyCollection Toys => AdminToy.BaseToAdminToy.Values.ToList().AsReadOnly(); // TODO: Obsolete it and make people use AdminToy.List /// /// Gets or sets the current seed of the map. diff --git a/EXILED/Exiled.API/Features/Toys/AdminToy.cs b/EXILED/Exiled.API/Features/Toys/AdminToy.cs index fdbe03da1..2139059e9 100644 --- a/EXILED/Exiled.API/Features/Toys/AdminToy.cs +++ b/EXILED/Exiled.API/Features/Toys/AdminToy.cs @@ -7,6 +7,7 @@ namespace Exiled.API.Features.Toys { + using System.Collections.Generic; using System.Linq; using AdminToys; @@ -14,6 +15,7 @@ namespace Exiled.API.Features.Toys using Enums; using Exiled.API.Interfaces; using Footprinting; + using InventorySystem.Items; using Mirror; using UnityEngine; @@ -23,6 +25,11 @@ namespace Exiled.API.Features.Toys /// public abstract class AdminToy : IWorldSpace { + /// + /// A dictionary of all 's that have been converted into . + /// + internal static readonly Dictionary BaseToAdminToy = new(new ComponentsEqualityComparer()); + /// /// Initializes a new instance of the class. /// @@ -33,9 +40,14 @@ internal AdminToy(AdminToyBase toyAdminToyBase, AdminToyType type) AdminToyBase = toyAdminToyBase; ToyType = type; - Map.ToysValue.Add(this); + BaseToAdminToy.Add(toyAdminToyBase, this); } + /// + /// Gets a list of all 's on the server. + /// + public static IReadOnlyCollection List => BaseToAdminToy.Values; + /// /// Gets the original . /// @@ -130,7 +142,22 @@ public bool IsStatic ///
/// The instance. /// The corresponding instance. - public static AdminToy Get(AdminToyBase adminToyBase) => Map.Toys.FirstOrDefault(x => x.AdminToyBase == adminToyBase); + public static AdminToy Get(AdminToyBase adminToyBase) + { + if (adminToyBase == null) + return null; + + if (BaseToAdminToy.TryGetValue(adminToyBase, out AdminToy adminToy)) + return adminToy; + + return adminToyBase switch + { + LightSourceToy lightSourceToy => new Light(lightSourceToy), + PrimitiveObjectToy primitiveObjectToy => new Primitive(primitiveObjectToy), + ShootingTarget shootingTarget => new ShootingTargetToy(shootingTarget), + _ => throw new System.NotImplementedException() + }; + } /// /// Spawns the toy into the game. Use to remove it. @@ -147,7 +174,7 @@ public bool IsStatic /// public void Destroy() { - Map.ToysValue.Remove(this); + BaseToAdminToy.Remove(AdminToyBase); NetworkServer.Destroy(AdminToyBase.gameObject); } } diff --git a/EXILED/Exiled.Events/Handlers/Internal/SceneUnloaded.cs b/EXILED/Exiled.Events/Handlers/Internal/SceneUnloaded.cs index 9bcb75cc8..4ecdc5f93 100644 --- a/EXILED/Exiled.Events/Handlers/Internal/SceneUnloaded.cs +++ b/EXILED/Exiled.Events/Handlers/Internal/SceneUnloaded.cs @@ -8,7 +8,7 @@ namespace Exiled.Events.Handlers.Internal { using API.Features; - + using Exiled.API.Features.Toys; using UnityEngine.SceneManagement; #pragma warning disable SA1611 // Element parameters should be documented @@ -35,7 +35,7 @@ public static void OnSceneUnloaded(Scene _) { Player.UserIdsCache.Clear(); Player.Dictionary.Clear(); - Map.ToysValue.Clear(); + AdminToy.BaseToAdminToy.Clear(); } } } \ No newline at end of file From 5a519a43b5be251f741dd5a8272267a08cb8892d Mon Sep 17 00:00:00 2001 From: Yamato <66829532+louis1706@users.noreply.github.com> Date: Fri, 2 Aug 2024 21:18:36 +0200 Subject: [PATCH 47/58] Fix `Jailbird::WearState` (#12) * Jailbird * Fix * Exception * Fix NW moment --- EXILED/Exiled.API/Features/Items/Jailbird.cs | 30 ++++++++- .../Item/ChargingJailbirdEventArgs.cs | 11 +++- .../EventArgs/Item/SwingingEventArgs.cs | 9 ++- .../Patches/Fixes/Jailbird914CoarseFix.cs | 61 +++++++++++++++++++ 4 files changed, 104 insertions(+), 7 deletions(-) create mode 100644 EXILED/Exiled.Events/Patches/Fixes/Jailbird914CoarseFix.cs diff --git a/EXILED/Exiled.API/Features/Items/Jailbird.cs b/EXILED/Exiled.API/Features/Items/Jailbird.cs index 9e508da11..2f8bfb524 100644 --- a/EXILED/Exiled.API/Features/Items/Jailbird.cs +++ b/EXILED/Exiled.API/Features/Items/Jailbird.cs @@ -7,11 +7,14 @@ namespace Exiled.API.Features.Items { + using System; + using Exiled.API.Features.Pickups; using Exiled.API.Interfaces; using InventorySystem.Items.Autosync; using InventorySystem.Items.Jailbird; using Mirror; + using UnityEngine; using JailbirdPickup = Pickups.JailbirdPickup; @@ -114,12 +117,35 @@ public JailbirdWearState WearState get => Base._deterioration.WearState; set { - if (JailbirdDeteriorationTracker.ReceivedStates.ContainsKey(Serial)) - JailbirdDeteriorationTracker.ReceivedStates[Serial] = value; + TotalDamageDealt = GetDamage(value); + TotalCharges = GetCharge(value); Base._deterioration.RecheckUsage(); } } + /// + /// Calculates the damage corresponding to a given . + /// + /// The wear state to calculate damage for. + /// The amount of damage associated with the specified wear state. + public float GetDamage(JailbirdWearState wearState) + { + foreach (Keyframe keyframe in Base._deterioration._damageToWearState.keys) + { + if (Base._deterioration.FloatToState(keyframe.value) == wearState) + return keyframe.time; + } + + throw new Exception("Wear state not found in damage to wear state mapping."); + } + + /// + /// Gets the charge needed to reach a specific . + /// + /// The desired wear state to calculate the charge for. + /// The charge value required to achieve the specified wear state. + public int GetCharge(JailbirdWearState wearState) => (int)wearState; + /// /// Breaks the Jailbird. /// diff --git a/EXILED/Exiled.Events/EventArgs/Item/ChargingJailbirdEventArgs.cs b/EXILED/Exiled.Events/EventArgs/Item/ChargingJailbirdEventArgs.cs index 38f6ea7f8..6ac613800 100644 --- a/EXILED/Exiled.Events/EventArgs/Item/ChargingJailbirdEventArgs.cs +++ b/EXILED/Exiled.Events/EventArgs/Item/ChargingJailbirdEventArgs.cs @@ -27,7 +27,7 @@ public class ChargingJailbirdEventArgs : IPlayerEvent, IItemEvent, IDeniableEven public ChargingJailbirdEventArgs(ReferenceHub player, InventorySystem.Items.ItemBase swingItem, bool isAllowed = true) { Player = Player.Get(player); - Item = Item.Get(swingItem); + Jailbird = (Jailbird)Item.Get(swingItem); #pragma warning disable CS0618 IsAllowed = isAllowed; #pragma warning restore CS0618 @@ -39,9 +39,14 @@ public ChargingJailbirdEventArgs(ReferenceHub player, InventorySystem.Items.Item public Player Player { get; } /// - /// Gets the that is being charged. This will always be a . + /// Gets the that is being charged. /// - public Item Item { get; } + public Jailbird Jailbird { get; } + + /// + /// Gets the that is being charged. + /// + public Item Item => Jailbird; /// /// Gets or sets a value indicating whether or not the Jailbird can be charged. diff --git a/EXILED/Exiled.Events/EventArgs/Item/SwingingEventArgs.cs b/EXILED/Exiled.Events/EventArgs/Item/SwingingEventArgs.cs index 17c0319b0..6c8f0fce8 100644 --- a/EXILED/Exiled.Events/EventArgs/Item/SwingingEventArgs.cs +++ b/EXILED/Exiled.Events/EventArgs/Item/SwingingEventArgs.cs @@ -25,7 +25,7 @@ public class SwingingEventArgs : IPlayerEvent, IItemEvent, IDeniableEvent public SwingingEventArgs(ReferenceHub player, InventorySystem.Items.ItemBase swingItem, bool isAllowed = true) { Player = Player.Get(player); - Item = Item.Get(swingItem); + Jailbird = (Jailbird)Item.Get(swingItem); IsAllowed = isAllowed; } @@ -34,10 +34,15 @@ public SwingingEventArgs(ReferenceHub player, InventorySystem.Items.ItemBase swi /// public Player Player { get; } + /// + /// Gets the that is being swung. + /// + public Jailbird Jailbird { get; } + /// /// Gets the that is being swung. /// - public Item Item { get; } + public Item Item => Jailbird; /// /// Gets or sets a value indicating whether or not the item can be swung. diff --git a/EXILED/Exiled.Events/Patches/Fixes/Jailbird914CoarseFix.cs b/EXILED/Exiled.Events/Patches/Fixes/Jailbird914CoarseFix.cs new file mode 100644 index 000000000..680e40608 --- /dev/null +++ b/EXILED/Exiled.Events/Patches/Fixes/Jailbird914CoarseFix.cs @@ -0,0 +1,61 @@ +// ----------------------------------------------------------------------- +// +// Copyright (c) Exiled Team. All rights reserved. +// Licensed under the CC BY-SA 3.0 license. +// +// ----------------------------------------------------------------------- + +namespace Exiled.Events.Patches.Events.Player +{ +#pragma warning disable IDE0060 + + using System.Collections.Generic; + using System.Reflection.Emit; + + using API.Features; + using API.Features.Pools; + + using HarmonyLib; + using InventorySystem.Items.Jailbird; + using Mirror; + + using static HarmonyLib.AccessTools; + + /// + /// Patches . + /// Bug reported to NW (https://trello.com/c/kyr3hV9B). + /// + [HarmonyPatch(typeof(JailbirdDeteriorationTracker), nameof(JailbirdDeteriorationTracker.Setup))] + internal static class Jailbird914CoarseFix + { + private static IEnumerable Transpiler(IEnumerable instructions, ILGenerator generator) + { + List newInstructions = ListPool.Pool.Get(instructions); + + int offset = -1; + int index = newInstructions.FindIndex(i => i.opcode == OpCodes.Blt_S) + offset; + + List