From aec6506ca1194ef95a302fcfa85e6ab47a2326b3 Mon Sep 17 00:00:00 2001
From: VALERA771 <72030575+VALERA771@users.noreply.github.com>
Date: Thu, 30 Jan 2025 13:33:00 +0300
Subject: [PATCH 01/24] fix: `Room::NearestRooms` fix (#417)
fix: new generation
---
EXILED/Exiled.API/Features/Room.cs | 12 ++++++++++--
EXILED/Exiled.Events/Patches/Generic/DoorList.cs | 1 -
2 files changed, 10 insertions(+), 3 deletions(-)
diff --git a/EXILED/Exiled.API/Features/Room.cs b/EXILED/Exiled.API/Features/Room.cs
index dc880fe69c..9fde18957c 100644
--- a/EXILED/Exiled.API/Features/Room.cs
+++ b/EXILED/Exiled.API/Features/Room.cs
@@ -132,7 +132,16 @@ public class Room : MonoBehaviour, IWorldSpace
///
/// Gets a of around the .
///
- public IReadOnlyList NearestRooms { get; private set; }
+ public IReadOnlyList NearestRooms
+ {
+ get
+ {
+ if (NearestRoomsValue.Count == 0 && Identifier.ConnectedRooms.Count > 0)
+ NearestRoomsValue.AddRange(Identifier.ConnectedRooms.Select(Get));
+
+ return NearestRoomsValue;
+ }
+ }
///
/// Gets a of in the .
@@ -438,7 +447,6 @@ internal void InternalCreate()
Windows = WindowsValue.AsReadOnly();
Doors = DoorsValue.AsReadOnly();
- NearestRooms = NearestRoomsValue.AsReadOnly();
Speakers = SpeakersValue.AsReadOnly();
Cameras = CamerasValue.AsReadOnly();
}
diff --git a/EXILED/Exiled.Events/Patches/Generic/DoorList.cs b/EXILED/Exiled.Events/Patches/Generic/DoorList.cs
index 8ae6a40910..2057bbd0f5 100644
--- a/EXILED/Exiled.Events/Patches/Generic/DoorList.cs
+++ b/EXILED/Exiled.Events/Patches/Generic/DoorList.cs
@@ -76,7 +76,6 @@ private static void InitDoor(DoorVariant doorVariant)
foreach (Room room in rooms)
{
room.DoorsValue.Add(door);
- room.NearestRoomsValue.AddRange(rooms.Except(new List() { room }));
}
if (door.Is(out CheckpointDoor checkpoint))
From 2c89b5980586d94211978fcc660ac69fd908c582 Mon Sep 17 00:00:00 2001
From: TtroubleTT <121741230+TtroubleTT@users.noreply.github.com>
Date: Thu, 30 Jan 2025 02:40:57 -0800
Subject: [PATCH 02/24] fix: Fixes Custom Weapon Reload (#418)
fix custom weapon reloading issues
Co-authored-by: Yamato <66829532+louis1706@users.noreply.github.com>
---
.../API/Features/CustomWeapon.cs | 24 +++++++++++++++----
1 file changed, 20 insertions(+), 4 deletions(-)
diff --git a/EXILED/Exiled.CustomItems/API/Features/CustomWeapon.cs b/EXILED/Exiled.CustomItems/API/Features/CustomWeapon.cs
index 96122fa641..0eb927dc3e 100644
--- a/EXILED/Exiled.CustomItems/API/Features/CustomWeapon.cs
+++ b/EXILED/Exiled.CustomItems/API/Features/CustomWeapon.cs
@@ -10,13 +10,14 @@ namespace Exiled.CustomItems.API.Features
using System;
using System.Linq;
+ using Exiled.API.Enums;
using Exiled.API.Extensions;
using Exiled.API.Features;
using Exiled.API.Features.DamageHandlers;
using Exiled.API.Features.Items;
using Exiled.API.Features.Pickups;
using Exiled.Events.EventArgs.Player;
-
+ using InventorySystem;
using InventorySystem.Items.Firearms.Attachments;
using InventorySystem.Items.Firearms.Attachments.Components;
using InventorySystem.Items.Firearms.Modules;
@@ -230,9 +231,24 @@ private void OnInternalReloaded(ReloadedWeaponEventArgs ev)
if (ClipSize > 0)
{
int ammoChambered = ((AutomaticActionModule)ev.Firearm.Base.Modules.FirstOrDefault(x => x is AutomaticActionModule))?.SyncAmmoChambered ?? 0;
- int ammodrop = -(ClipSize - ev.Firearm.MagazineAmmo) - ammoChambered;
- ev.Firearm.MagazineAmmo = ClipSize - ammoChambered;
- ev.Player.AddAmmo(ev.Firearm.AmmoType, (ushort)Mathf.Clamp(ammodrop, ushort.MinValue, ushort.MaxValue));
+ int ammoToGive = ClipSize - ammoChambered;
+
+ AmmoType ammoType = ev.Firearm.AmmoType;
+ int firearmAmmo = ev.Firearm.MagazineAmmo;
+ int ammoDrop = -(ClipSize - firearmAmmo - ammoChambered);
+
+ int ammoInInventory = ev.Player.Ammo[ammoType.GetItemType()] + firearmAmmo;
+ if (ammoToGive < ammoInInventory)
+ {
+ ev.Firearm.MagazineAmmo = ammoToGive;
+ int newAmmo = ev.Player.Inventory.GetCurAmmo(ammoType.GetItemType()) + ammoDrop;
+ ev.Player.Inventory.ServerSetAmmo(ammoType.GetItemType(), newAmmo);
+ }
+ else
+ {
+ ev.Firearm.MagazineAmmo = ammoInInventory;
+ ev.Player.Inventory.ServerSetAmmo(ammoType.GetItemType(), 0);
+ }
}
OnReloaded(ev);
From cd7ba63f46801272d41eacd7b17a557b04c61388 Mon Sep 17 00:00:00 2001
From: Trevlouw <45270312+Trevlouw@users.noreply.github.com>
Date: Thu, 30 Jan 2025 05:41:36 -0500
Subject: [PATCH 03/24] feat: UserTextInputSetting and SliderSetting (#416)
* feat: ShadowType
More features for the Light wrapper
* Why did we make this
This is about as cooked as the other EXILED SSS stuff, only useful in OnEnabled();
* I definitely didnt forget to cover my copy pasting
---
.../Features/Core/UserSettings/SettingBase.cs | 2 +
.../Core/UserSettings/SliderSetting.cs | 124 ++++++++++++++++++
.../Core/UserSettings/UserTextInputSetting.cs | 90 +++++++++++++
3 files changed, 216 insertions(+)
create mode 100644 EXILED/Exiled.API/Features/Core/UserSettings/SliderSetting.cs
create mode 100644 EXILED/Exiled.API/Features/Core/UserSettings/UserTextInputSetting.cs
diff --git a/EXILED/Exiled.API/Features/Core/UserSettings/SettingBase.cs b/EXILED/Exiled.API/Features/Core/UserSettings/SettingBase.cs
index 5af5f615e7..776b80cca3 100644
--- a/EXILED/Exiled.API/Features/Core/UserSettings/SettingBase.cs
+++ b/EXILED/Exiled.API/Features/Core/UserSettings/SettingBase.cs
@@ -176,6 +176,8 @@ public static bool TryGetSetting(Player player, int id, out T setting)
SSGroupHeader header => new HeaderSetting(header),
SSKeybindSetting keybindSetting => new KeybindSetting(keybindSetting),
SSTwoButtonsSetting twoButtonsSetting => new TwoButtonsSetting(twoButtonsSetting),
+ SSPlaintextSetting plainTextSetting => new UserTextInputSetting(plainTextSetting),
+ SSSliderSetting sliderSetting => new SliderSetting(sliderSetting),
_ => new SettingBase(settingBase)
};
diff --git a/EXILED/Exiled.API/Features/Core/UserSettings/SliderSetting.cs b/EXILED/Exiled.API/Features/Core/UserSettings/SliderSetting.cs
new file mode 100644
index 0000000000..66d88174d9
--- /dev/null
+++ b/EXILED/Exiled.API/Features/Core/UserSettings/SliderSetting.cs
@@ -0,0 +1,124 @@
+// -----------------------------------------------------------------------
+//
+// Copyright (c) ExMod Team. All rights reserved.
+// Licensed under the CC BY-SA 3.0 license.
+//
+// -----------------------------------------------------------------------
+
+namespace Exiled.API.Features.Core.UserSettings
+{
+ using System;
+
+ using Exiled.API.Interfaces;
+ using global::UserSettings.ServerSpecific;
+
+ ///
+ /// Represents a slider setting.
+ ///
+ public class SliderSetting : SettingBase, IWrapper
+ {
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ public SliderSetting(int id, string label, float minValue, float maxValue, float defaultValue, bool isInteger = false, string stringFormat = "0.##", string displayFormat = "{0}", string hintDescription = null)
+ : this(new SSSliderSetting(id, label, minValue, maxValue, defaultValue, isInteger, stringFormat, displayFormat, hintDescription))
+ {
+ Base = (SSSliderSetting)base.Base;
+ }
+
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ /// A instance.
+ internal SliderSetting(SSSliderSetting settingBase)
+ : base(settingBase)
+ {
+ Base = settingBase;
+ }
+
+ ///
+ /// Gets or sets the minimum value of the slider.
+ ///
+ public float MinimumValue
+ {
+ get => Base.MinValue;
+ set => Base.MinValue = value;
+ }
+
+ ///
+ /// Gets or sets the maximum value of the slider.
+ ///
+ public float MaximumValue
+ {
+ get => Base.MaxValue;
+ set => Base.MaxValue = value;
+ }
+
+ ///
+ /// Gets or sets the default value of the slider.
+ ///
+ public float DefaultValue
+ {
+ get => Base.DefaultValue;
+ set => Base.DefaultValue = value;
+ }
+
+ ///
+ /// Gets or sets a value indicating whether the slider displays integers.
+ ///
+ public bool IsInteger
+ {
+ get => Base.Integer;
+ set => Base.Integer = value;
+ }
+
+ ///
+ /// Gets a value indicating whether the slider is currently being dragged.
+ ///
+ public bool IsBeingDragged => Base.SyncDragging;
+
+ ///
+ /// Gets a float that represents the current value of the slider.
+ ///
+ public float SliderValue => Base.Integer ? Base.SyncIntValue : Base.SyncFloatValue;
+
+ ///
+ /// Gets or sets the formatting used for the number in the slider.
+ ///
+ public string StringFormat
+ {
+ get => Base.ValueToStringFormat;
+ set => Base.ValueToStringFormat = value;
+ }
+
+ ///
+ /// Gets or sets the formatting used for the final display of the value of the slider.
+ ///
+ public string DisplayFormat
+ {
+ get => Base.FinalDisplayFormat;
+ set => Base.FinalDisplayFormat = value;
+ }
+
+ ///
+ public new SSSliderSetting Base { get; }
+
+ ///
+ /// Returns a representation of this .
+ ///
+ /// A string in human-readable format.
+ public override string ToString()
+ {
+ return base.ToString() + $" /{MinimumValue}/ *{MaximumValue}* +{DefaultValue}+ '{SliderValue}'";
+ }
+ }
+}
\ No newline at end of file
diff --git a/EXILED/Exiled.API/Features/Core/UserSettings/UserTextInputSetting.cs b/EXILED/Exiled.API/Features/Core/UserSettings/UserTextInputSetting.cs
new file mode 100644
index 0000000000..8944558e03
--- /dev/null
+++ b/EXILED/Exiled.API/Features/Core/UserSettings/UserTextInputSetting.cs
@@ -0,0 +1,90 @@
+// -----------------------------------------------------------------------
+//
+// Copyright (c) ExMod Team. All rights reserved.
+// Licensed under the CC BY-SA 3.0 license.
+//
+// -----------------------------------------------------------------------
+
+namespace Exiled.API.Features.Core.UserSettings
+{
+ using System;
+
+ using Exiled.API.Interfaces;
+ using global::UserSettings.ServerSpecific;
+ using TMPro;
+
+ ///
+ /// Represents a user text input setting.
+ ///
+ public class UserTextInputSetting : SettingBase, IWrapper
+ {
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ /// ///
+ public UserTextInputSetting(int id, string label, string placeHolder = "", int characterLimit = 64, TMP_InputField.ContentType contentType = TMP_InputField.ContentType.Standard, string hintDescription = null)
+ : this(new SSPlaintextSetting(id, label, placeHolder, characterLimit, contentType, hintDescription))
+ {
+ Base = (SSPlaintextSetting)base.Base;
+ }
+
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ /// A instance.
+ internal UserTextInputSetting(SSPlaintextSetting settingBase)
+ : base(settingBase)
+ {
+ Base = settingBase;
+ }
+
+ ///
+ public new SSPlaintextSetting Base { get; }
+
+ ///
+ /// Gets the value of the text entered by a client.
+ ///
+ public string Text => Base.SyncInputText;
+
+ ///
+ /// Gets or sets a value indicating the placeholder shown within the PlainTextSetting.
+ ///
+ public string PlaceHolder
+ {
+ get => Base.Placeholder;
+ set => Base.Placeholder = value;
+ }
+
+ ///
+ /// Gets or sets a value indicating the type of content within the PlainTextSetting.
+ ///
+ public TMP_InputField.ContentType ContentType
+ {
+ get => Base.ContentType;
+ set => Base.ContentType = value;
+ }
+
+ ///
+ /// Gets or sets a value indicating the max number of characters in the PlainTextSetting.
+ ///
+ public int CharacterLimit
+ {
+ get => Base.CharacterLimit;
+ set => Base.CharacterLimit = value;
+ }
+
+ ///
+ /// Returns a representation of this .
+ ///
+ /// A string in human-readable format.
+ public override string ToString()
+ {
+ return base.ToString() + $" /{Text}/ *{ContentType}* +{CharacterLimit}+";
+ }
+ }
+}
\ No newline at end of file
From 936b864f96db402fea6f02109c851bd9b36d905c Mon Sep 17 00:00:00 2001
From: TtroubleTT <121741230+TtroubleTT@users.noreply.github.com>
Date: Sun, 2 Feb 2025 11:15:56 -0800
Subject: [PATCH 04/24] fix: Potential Error Fix With Custom Weapon Reloading
(#421)
* fix potential dictionary error
* apply suggestion
Co-authored-by: Yamato <66829532+louis1706@users.noreply.github.com>
---------
Co-authored-by: Yamato <66829532+louis1706@users.noreply.github.com>
---
EXILED/Exiled.CustomItems/API/Features/CustomWeapon.cs | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/EXILED/Exiled.CustomItems/API/Features/CustomWeapon.cs b/EXILED/Exiled.CustomItems/API/Features/CustomWeapon.cs
index 0eb927dc3e..6e8cf58e29 100644
--- a/EXILED/Exiled.CustomItems/API/Features/CustomWeapon.cs
+++ b/EXILED/Exiled.CustomItems/API/Features/CustomWeapon.cs
@@ -237,7 +237,7 @@ private void OnInternalReloaded(ReloadedWeaponEventArgs ev)
int firearmAmmo = ev.Firearm.MagazineAmmo;
int ammoDrop = -(ClipSize - firearmAmmo - ammoChambered);
- int ammoInInventory = ev.Player.Ammo[ammoType.GetItemType()] + firearmAmmo;
+ int ammoInInventory = ev.Player.GetAmmo(ammoType) + firearmAmmo;
if (ammoToGive < ammoInInventory)
{
ev.Firearm.MagazineAmmo = ammoToGive;
From 61c1c2340ca52a8c1a1204a958d855dbcfd4817a Mon Sep 17 00:00:00 2001
From: TtroubleTT <121741230+TtroubleTT@users.noreply.github.com>
Date: Wed, 5 Feb 2025 05:33:48 -0800
Subject: [PATCH 05/24] fix: Fix Custom Roles Lagging Back When Spawning (#428)
fix custom roles lagging back
---
EXILED/Exiled.CustomRoles/API/Features/CustomRole.cs | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/EXILED/Exiled.CustomRoles/API/Features/CustomRole.cs b/EXILED/Exiled.CustomRoles/API/Features/CustomRole.cs
index 7de3e2eefd..7d7fd8b5bf 100644
--- a/EXILED/Exiled.CustomRoles/API/Features/CustomRole.cs
+++ b/EXILED/Exiled.CustomRoles/API/Features/CustomRole.cs
@@ -861,7 +861,7 @@ protected virtual void SubscribeEvents()
Log.Debug($"{Name}: Loading events.");
Exiled.Events.Handlers.Player.ChangingNickname += OnInternalChangingNickname;
Exiled.Events.Handlers.Player.ChangingRole += OnInternalChangingRole;
- Exiled.Events.Handlers.Player.Spawning += OnInternalSpawning;
+ Exiled.Events.Handlers.Player.Spawned += OnInternalSpawned;
Exiled.Events.Handlers.Player.SpawningRagdoll += OnSpawningRagdoll;
Exiled.Events.Handlers.Player.Destroying += OnDestroying;
}
@@ -877,7 +877,7 @@ protected virtual void UnsubscribeEvents()
Log.Debug($"{Name}: Unloading events.");
Exiled.Events.Handlers.Player.ChangingNickname -= OnInternalChangingNickname;
Exiled.Events.Handlers.Player.ChangingRole -= OnInternalChangingRole;
- Exiled.Events.Handlers.Player.Spawning -= OnInternalSpawning;
+ Exiled.Events.Handlers.Player.Spawned -= OnInternalSpawned;
Exiled.Events.Handlers.Player.SpawningRagdoll -= OnSpawningRagdoll;
Exiled.Events.Handlers.Player.Destroying -= OnDestroying;
}
@@ -918,9 +918,9 @@ private void OnInternalChangingNickname(ChangingNicknameEventArgs ev)
ev.Player.CustomInfo = $"{ev.NewName}\n{CustomInfo}";
}
- private void OnInternalSpawning(SpawningEventArgs ev)
+ private void OnInternalSpawned(SpawnedEventArgs ev)
{
- if (!IgnoreSpawnSystem && SpawnChance > 0 && !Check(ev.Player) && ev.NewRole == Role && Loader.Random.NextDouble() * 100 <= SpawnChance)
+ if (!IgnoreSpawnSystem && SpawnChance > 0 && !Check(ev.Player) && ev.Player.Role.Type == Role && Loader.Random.NextDouble() * 100 <= SpawnChance)
AddRole(ev.Player);
}
From 571f49ee43e428fdd6edf15615180585f1c7e11a Mon Sep 17 00:00:00 2001
From: Lumi
Date: Thu, 13 Feb 2025 12:37:25 +0000
Subject: [PATCH 06/24] feat: send to player specific settings (#432)
---
.../Exiled.API/Features/Core/UserSettings/SettingBase.cs | 8 ++++++++
1 file changed, 8 insertions(+)
diff --git a/EXILED/Exiled.API/Features/Core/UserSettings/SettingBase.cs b/EXILED/Exiled.API/Features/Core/UserSettings/SettingBase.cs
index 776b80cca3..b27ae1fc78 100644
--- a/EXILED/Exiled.API/Features/Core/UserSettings/SettingBase.cs
+++ b/EXILED/Exiled.API/Features/Core/UserSettings/SettingBase.cs
@@ -218,6 +218,14 @@ public static void SendToAll(Func predicate)
/// Target player.
public static void SendToPlayer(Player player) => ServerSpecificSettingsSync.SendToPlayer(player.ReferenceHub);
+ ///
+ /// Syncs specific settings with the specified target.
+ ///
+ /// Target player.
+ /// Settings to send to the player.
+ public static void SendToPlayer(Player player, IEnumerable settings) =>
+ ServerSpecificSettingsSync.SendToPlayer(player.ReferenceHub, settings.Select(setting => setting.Base).ToArray());
+
///
/// Registers all settings from the specified collection.
///
From a7d8d2bd9e3fac4f20cf6f515e533fe0b8655348 Mon Sep 17 00:00:00 2001
From: Nameless <85962933+Misfiy@users.noreply.github.com>
Date: Thu, 13 Feb 2025 13:38:50 +0100
Subject: [PATCH 07/24] fix: Npc cant get flashed (#429)
---
.../Patches/Events/Map/ExplodingFlashGrenade.cs | 5 ++---
1 file changed, 2 insertions(+), 3 deletions(-)
diff --git a/EXILED/Exiled.Events/Patches/Events/Map/ExplodingFlashGrenade.cs b/EXILED/Exiled.Events/Patches/Events/Map/ExplodingFlashGrenade.cs
index 4413d18299..0884e28710 100644
--- a/EXILED/Exiled.Events/Patches/Events/Map/ExplodingFlashGrenade.cs
+++ b/EXILED/Exiled.Events/Patches/Events/Map/ExplodingFlashGrenade.cs
@@ -8,6 +8,7 @@
namespace Exiled.Events.Patches.Events.Map
{
using System.Collections.Generic;
+ using System.Linq;
using System.Reflection.Emit;
using API.Features;
@@ -64,7 +65,7 @@ private static IEnumerable Transpiler(IEnumerable targetToAffect = HashSetPool.Pool.Get();
- foreach (Player player in Player.List)
+ foreach (Player player in ReferenceHub.AllHubs.Select(Player.Get))
{
if ((instance.transform.position - player.Position).sqrMagnitude >= distance)
continue;
@@ -88,9 +89,7 @@ private static void ProcessEvent(FlashbangGrenade instance, float distance)
return;
foreach (Player player in explodingGrenadeEvent.TargetsToAffect)
- {
instance.ProcessPlayer(player.ReferenceHub);
- }
}
}
}
\ No newline at end of file
From 6eb4b1ea08979bc020371da21e72b6069b197a8f Mon Sep 17 00:00:00 2001
From: Nameless <85962933+Misfiy@users.noreply.github.com>
Date: Thu, 13 Feb 2025 13:45:37 +0100
Subject: [PATCH 08/24] feat: remove sex (#395)
---
EXILED/Exiled.Loader/Features/LoaderMessages.cs | 11 +++++++----
1 file changed, 7 insertions(+), 4 deletions(-)
diff --git a/EXILED/Exiled.Loader/Features/LoaderMessages.cs b/EXILED/Exiled.Loader/Features/LoaderMessages.cs
index f53aac3870..a1834e35ea 100644
--- a/EXILED/Exiled.Loader/Features/LoaderMessages.cs
+++ b/EXILED/Exiled.Loader/Features/LoaderMessages.cs
@@ -29,7 +29,7 @@ public static class LoaderMessages
▀ ";
///
- /// Gets the easter egg loader message.
+ /// Gets the Easter egg loader message.
///
public static string EasterEgg => @"
▄████████ ▄████████ ▀████ ▐████▀ ▄█ ▄█ ▄████████ ████████▄
@@ -43,7 +43,7 @@ public static class LoaderMessages
";
///
- /// Gets the christmas loader message.
+ /// Gets the Christmas loader message.
///
public static string Christmas => @"
__
@@ -60,7 +60,7 @@ public static class LoaderMessages
|____)_)";
///
- /// Gets the halloween loader message.
+ /// Gets the Halloween loader message.
///
public static string Halloween => @"
@@@@@@@@ @@@ @@@ @@@ @@@ @@@@@@@@ @@@@@@@
@@ -81,7 +81,10 @@ @@@@@@@@ @@@ @@@ @@@ @@@ @@@@@@@@ @@@@@@@@
/// The correspondent loader message.
public static string GetMessage()
{
- if (Loader.Version.ToString().Contains("6.9") || Loader.Random.NextDouble() <= 0.069)
+ if (Environment.GetCommandLineArgs().Contains("--defaultloadmessage"))
+ return Default;
+
+ if (!Environment.GetCommandLineArgs().Contains("--noeasteregg") && (Loader.Version.ToString().Contains("6.9") || Loader.Random.NextDouble() <= 0.069))
return EasterEgg;
return DateTime.Today.Month switch
From f52bab7a6c31394b229554d0f8dfbc90a4002744 Mon Sep 17 00:00:00 2001
From: Yamato <66829532+louis1706@users.noreply.github.com>
Date: Thu, 13 Feb 2025 13:54:36 +0100
Subject: [PATCH 09/24] feat: Server.IsHeavilyModded is Obsolete (#419)
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
* Server.IsHeavilyModded
* Update EXILED/Exiled.API/Features/Server.cs
Co-authored-by: Vladislav Popovič
* Update EXILED/Exiled.API/Features/Server.cs
Co-authored-by: Vladislav Popovič
* Update EXILED/Exiled.API/Features/Server.cs
Co-authored-by: Vladislav Popovič
---------
Co-authored-by: Vladislav Popovič
---
EXILED/Exiled.API/Features/Server.cs | 13 +++++++++++++
1 file changed, 13 insertions(+)
diff --git a/EXILED/Exiled.API/Features/Server.cs b/EXILED/Exiled.API/Features/Server.cs
index c79d0c4c1d..57d1752725 100644
--- a/EXILED/Exiled.API/Features/Server.cs
+++ b/EXILED/Exiled.API/Features/Server.cs
@@ -174,7 +174,20 @@ public static int MaxPlayerCount
/// Read the VSR for more info about its usage.
///
///
+ [Obsolete("This field has been deleted because it used the wrong field (TransparentlyModded)")]
public static bool IsHeavilyModded
+ {
+ get => false;
+ set => _ = value;
+ }
+
+ ///
+ /// Gets or sets a value indicating whether the server is marked as Transparently Modded.
+ ///
+ /// It is not used now, wait for a new VSR update.
+ ///
+ ///
+ public static bool IsTransparentlyModded
{
get => ServerConsole.TransparentlyModdedServerConfig;
set => ServerConsole.TransparentlyModdedServerConfig = value;
From dafca44a0968e4c84112f0d61b2c77dbc96f1a33 Mon Sep 17 00:00:00 2001
From: TtroubleTT <121741230+TtroubleTT@users.noreply.github.com>
Date: Thu, 13 Feb 2025 04:55:26 -0800
Subject: [PATCH 10/24] fix: Player Custom Firearm Reloading Exploit (#422)
* fix player exploiting ammo amount by switching off weapon
* fix quick reload exploit
* abort it made things worse
---
EXILED/Exiled.CustomItems/API/Features/CustomWeapon.cs | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/EXILED/Exiled.CustomItems/API/Features/CustomWeapon.cs b/EXILED/Exiled.CustomItems/API/Features/CustomWeapon.cs
index 6e8cf58e29..e775ee3e9f 100644
--- a/EXILED/Exiled.CustomItems/API/Features/CustomWeapon.cs
+++ b/EXILED/Exiled.CustomItems/API/Features/CustomWeapon.cs
@@ -225,7 +225,7 @@ private void OnInternalReloading(ReloadingWeaponEventArgs ev)
private void OnInternalReloaded(ReloadedWeaponEventArgs ev)
{
- if (!Check(ev.Player.CurrentItem))
+ if (!Check(ev.Item))
return;
if (ClipSize > 0)
From 19122697ffcdf89a4c64fdb391910a301efe1e50 Mon Sep 17 00:00:00 2001
From: TtroubleTT <121741230+TtroubleTT@users.noreply.github.com>
Date: Thu, 13 Feb 2025 05:42:07 -0800
Subject: [PATCH 11/24] fix: Add SCP-1344 Effect to IsPositive Extension (#426)
add 1344 to ispostive extension
---
EXILED/Exiled.API/Extensions/EffectTypeExtension.cs | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/EXILED/Exiled.API/Extensions/EffectTypeExtension.cs b/EXILED/Exiled.API/Extensions/EffectTypeExtension.cs
index ad8119fe3d..dc209c3ba0 100644
--- a/EXILED/Exiled.API/Extensions/EffectTypeExtension.cs
+++ b/EXILED/Exiled.API/Extensions/EffectTypeExtension.cs
@@ -175,7 +175,7 @@ or EffectType.Disabled or EffectType.Ensnared or EffectType.Exhausted or EffectT
///
public static bool IsPositive(this EffectType effect) => effect is EffectType.BodyshotReduction or EffectType.DamageReduction
or EffectType.Invigorated or EffectType.Invisible or EffectType.MovementBoost or EffectType.RainbowTaste
- or EffectType.Scp207 or EffectType.Scp1853 or EffectType.Vitality or EffectType.AntiScp207 or EffectType.Ghostly;
+ or EffectType.Scp207 or EffectType.Scp1853 or EffectType.Vitality or EffectType.AntiScp207 or EffectType.Ghostly or EffectType.Scp1344;
///
/// Returns whether the provided affects the player's movement speed.
From 403f449fac5dfa3af507b40dc92cb4ed3ac37966 Mon Sep 17 00:00:00 2001
From: Banalny-Banan <133122450+Banalny-Banan@users.noreply.github.com>
Date: Thu, 13 Feb 2025 16:44:02 +0200
Subject: [PATCH 12/24] feat: added GameObject and Transform properties to
AdminToy (#431)
---
EXILED/Exiled.API/Features/Toys/AdminToy.cs | 10 ++++++++++
EXILED/Exiled.API/Features/Toys/ShootingTargetToy.cs | 6 ++----
2 files changed, 12 insertions(+), 4 deletions(-)
diff --git a/EXILED/Exiled.API/Features/Toys/AdminToy.cs b/EXILED/Exiled.API/Features/Toys/AdminToy.cs
index 01f54e8d26..a3ffa539cd 100644
--- a/EXILED/Exiled.API/Features/Toys/AdminToy.cs
+++ b/EXILED/Exiled.API/Features/Toys/AdminToy.cs
@@ -115,6 +115,16 @@ public Vector3 Scale
}
}
+ ///
+ /// Gets the of the toy.
+ ///
+ public GameObject GameObject => AdminToyBase.gameObject;
+
+ ///
+ /// Gets the of the toy.
+ ///
+ public Transform Transform => AdminToyBase.transform;
+
///
/// Gets or sets the movement smoothing value of the toy.
///
diff --git a/EXILED/Exiled.API/Features/Toys/ShootingTargetToy.cs b/EXILED/Exiled.API/Features/Toys/ShootingTargetToy.cs
index a9051baed8..86246ffd28 100644
--- a/EXILED/Exiled.API/Features/Toys/ShootingTargetToy.cs
+++ b/EXILED/Exiled.API/Features/Toys/ShootingTargetToy.cs
@@ -66,10 +66,8 @@ internal ShootingTargetToy(ShootingTarget target)
///
public ShootingTarget Base { get; }
- ///
- /// Gets the of the target.
- ///
- public GameObject GameObject => Base.gameObject;
+ ///
+ public new GameObject GameObject => base.GameObject;
///
/// Gets the of the bullseye.
From c85a92dd993fb240592eaceb0d8a3dd786cfa57c Mon Sep 17 00:00:00 2001
From: Yamato <66829532+louis1706@users.noreply.github.com>
Date: Thu, 13 Feb 2025 15:45:14 +0100
Subject: [PATCH 13/24] fix: Fixing TriggeringTesla not detecting NPC (#424)
---
EXILED/Exiled.Events/Patches/Events/Player/TriggeringTesla.cs | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/EXILED/Exiled.Events/Patches/Events/Player/TriggeringTesla.cs b/EXILED/Exiled.Events/Patches/Events/Player/TriggeringTesla.cs
index 05f9b37280..4034169a6a 100644
--- a/EXILED/Exiled.Events/Patches/Events/Player/TriggeringTesla.cs
+++ b/EXILED/Exiled.Events/Patches/Events/Player/TriggeringTesla.cs
@@ -8,6 +8,7 @@
namespace Exiled.Events.Patches.Events.Player
{
using System.Collections.Generic;
+ using System.Linq;
using System.Reflection.Emit;
using API.Features;
@@ -68,7 +69,7 @@ private static void TriggeringTeslaEvent(BaseTeslaGate baseTeslaGate, ref bool i
{
TeslaGate teslaGate = TeslaGate.Get(baseTeslaGate);
- foreach (Player player in Player.List)
+ foreach (Player player in ReferenceHub.AllHubs.Select(Player.Get))
{
if (player is null || !teslaGate.CanBeIdle(player))
continue;
From 02e2bf699f27b79b92b406140b1cd08c8f49ce05 Mon Sep 17 00:00:00 2001
From: Snivy Films <120346554+SnivyFilms@users.noreply.github.com>
Date: Fri, 14 Feb 2025 02:38:55 -0500
Subject: [PATCH 14/24] feat: Dynamic spawn location additions (#388)
---
EXILED/Exiled.API/Enums/SpawnLocationType.cs | 25 +++++++++++++++++++
.../Exiled.API/Extensions/SpawnExtensions.cs | 6 +++++
2 files changed, 31 insertions(+)
diff --git a/EXILED/Exiled.API/Enums/SpawnLocationType.cs b/EXILED/Exiled.API/Enums/SpawnLocationType.cs
index 1ebd57cc95..ae957d3362 100644
--- a/EXILED/Exiled.API/Enums/SpawnLocationType.cs
+++ b/EXILED/Exiled.API/Enums/SpawnLocationType.cs
@@ -143,5 +143,30 @@ public enum SpawnLocationType
/// Just inside the LCZ WC door.
///
InsideLczWc,
+
+ ///
+ /// Inside the Glass Box in GR-18.
+ ///
+ InsideGr18Glass,
+
+ ///
+ /// Inside 106's Primary Door
+ ///
+ Inside106Primary,
+
+ ///
+ /// Inside 106's Secondary Door
+ ///
+ Inside106Secondary,
+
+ ///
+ /// Inside 939 Cryo Chamber
+ ///
+ Inside939Cryo,
+
+ ///
+ /// Inside SCP-079's Armory
+ ///
+ Inside079Armory,
}
}
\ No newline at end of file
diff --git a/EXILED/Exiled.API/Extensions/SpawnExtensions.cs b/EXILED/Exiled.API/Extensions/SpawnExtensions.cs
index a987a56265..29da4ab802 100644
--- a/EXILED/Exiled.API/Extensions/SpawnExtensions.cs
+++ b/EXILED/Exiled.API/Extensions/SpawnExtensions.cs
@@ -34,6 +34,7 @@ public static class SpawnExtensions
SpawnLocationType.Inside914,
SpawnLocationType.Inside049Armory,
SpawnLocationType.InsideLczCafe,
+ SpawnLocationType.Inside939Cryo,
};
///
@@ -102,6 +103,11 @@ public static Vector3 GetPosition(this SpawnLocationType location)
SpawnLocationType.Inside173Connector => "173_CONNECTOR",
SpawnLocationType.InsideEscapePrimary => "ESCAPE_PRIMARY",
SpawnLocationType.InsideEscapeSecondary => "ESCAPE_SECONDARY",
+ SpawnLocationType.InsideGr18Glass => "GR18_INNER",
+ SpawnLocationType.Inside106Primary => "106_PRIMARY",
+ SpawnLocationType.Inside106Secondary => "106_SECONDARY",
+ SpawnLocationType.Inside939Cryo => "939_CRYO",
+ SpawnLocationType.Inside079Armory => "079_ARMORY",
_ => default,
};
}
From 1c27f25deaecfde1945b4f8ecdc164366a3d6f27 Mon Sep 17 00:00:00 2001
From: Banalny-Banan <133122450+Banalny-Banan@users.noreply.github.com>
Date: Fri, 14 Feb 2025 22:12:28 +0200
Subject: [PATCH 15/24] feat: Added ICommandSender to Kicking/Banning EventArgs
(#436)
initial
---
.../EventArgs/Player/BanningEventArgs.cs | 6 ++++--
.../EventArgs/Player/KickingEventArgs.cs | 13 +++++++++++--
.../Exiled.Events/Patches/Events/Player/Banning.cs | 10 ++++++++++
.../Exiled.Events/Patches/Events/Player/Kicking.cs | 5 ++++-
4 files changed, 29 insertions(+), 5 deletions(-)
diff --git a/EXILED/Exiled.Events/EventArgs/Player/BanningEventArgs.cs b/EXILED/Exiled.Events/EventArgs/Player/BanningEventArgs.cs
index 585e244773..86d15bf8d8 100644
--- a/EXILED/Exiled.Events/EventArgs/Player/BanningEventArgs.cs
+++ b/EXILED/Exiled.Events/EventArgs/Player/BanningEventArgs.cs
@@ -10,6 +10,7 @@ namespace Exiled.Events.EventArgs.Player
using System.Reflection;
using API.Features;
+ using CommandSystem;
///
/// Contains all information before banning a player from the server.
@@ -23,12 +24,13 @@ public class BanningEventArgs : KickingEventArgs
///
/// The ban target.
/// The ban issuer.
+ /// The ban command sender.
/// The ban seconds duration.
/// The ban reason.
/// The ban full message.
/// Indicates whether the event can be executed or not.
- public BanningEventArgs(Player target, Player issuer, long duration, string reason, string fullMessage, bool isAllowed = true)
- : base(target, issuer, reason, fullMessage, isAllowed)
+ public BanningEventArgs(Player target, Player issuer, ICommandSender commandSender, long duration, string reason, string fullMessage, bool isAllowed = true)
+ : base(target, issuer, commandSender, reason, fullMessage, isAllowed)
{
Duration = duration;
}
diff --git a/EXILED/Exiled.Events/EventArgs/Player/KickingEventArgs.cs b/EXILED/Exiled.Events/EventArgs/Player/KickingEventArgs.cs
index 036b2aa4c2..cfa2864b85 100644
--- a/EXILED/Exiled.Events/EventArgs/Player/KickingEventArgs.cs
+++ b/EXILED/Exiled.Events/EventArgs/Player/KickingEventArgs.cs
@@ -10,7 +10,7 @@ namespace Exiled.Events.EventArgs.Player
using System.Reflection;
using API.Features;
-
+ using CommandSystem;
using Interfaces;
///
@@ -32,6 +32,9 @@ public class KickingEventArgs : IPlayerEvent, IDeniableEvent
///
///
///
+ ///
+ ///
+ ///
///
///
///
@@ -41,10 +44,11 @@ public class KickingEventArgs : IPlayerEvent, IDeniableEvent
///
///
///
- public KickingEventArgs(Player target, Player issuer, string reason, string fullMessage, bool isAllowed = true)
+ public KickingEventArgs(Player target, Player issuer, ICommandSender commandSender, string reason, string fullMessage, bool isAllowed = true)
{
Target = target;
Player = issuer ?? Server.Host;
+ CommandSender = commandSender;
Reason = reason;
startkickmessage = fullMessage;
IsAllowed = isAllowed;
@@ -114,6 +118,11 @@ public Player Player
}
}
+ ///
+ /// Gets the command sender.
+ ///
+ public ICommandSender CommandSender { get; }
+
///
/// Logs the kick, anti-backdoor protection from malicious plugins.
///
diff --git a/EXILED/Exiled.Events/Patches/Events/Player/Banning.cs b/EXILED/Exiled.Events/Patches/Events/Player/Banning.cs
index 271d22ffe5..573c2bd820 100644
--- a/EXILED/Exiled.Events/Patches/Events/Player/Banning.cs
+++ b/EXILED/Exiled.Events/Patches/Events/Player/Banning.cs
@@ -46,16 +46,24 @@ private static IEnumerable Transpiler(IEnumerable Transpiler(IEnumerable Transpiler(IEnumerable Transpiler(IEnumerable
Date: Mon, 17 Feb 2025 19:02:24 +0200
Subject: [PATCH 16/24] fix: OnShooting target freeze (#438)
initial
---
.../Patches/Events/Player/Shooting.cs | 66 ++++++++++++-------
1 file changed, 44 insertions(+), 22 deletions(-)
diff --git a/EXILED/Exiled.Events/Patches/Events/Player/Shooting.cs b/EXILED/Exiled.Events/Patches/Events/Player/Shooting.cs
index 501c1f812b..7fe54c41a3 100644
--- a/EXILED/Exiled.Events/Patches/Events/Player/Shooting.cs
+++ b/EXILED/Exiled.Events/Patches/Events/Player/Shooting.cs
@@ -7,6 +7,7 @@
namespace Exiled.Events.Patches.Events.Player
{
+ using System;
using System.Collections.Generic;
using System.Reflection;
using System.Reflection.Emit;
@@ -34,8 +35,6 @@ private static IEnumerable Transpiler(IEnumerable newInstructions = ListPool.Pool.Get(instructions);
Label returnLabel = generator.DefineLabel();
- Label continueLabel1 = generator.DefineLabel();
- Label continueLabel2 = generator.DefineLabel();
/*
[] <= Here
@@ -59,37 +58,60 @@ private static IEnumerable Transpiler(IEnumerable
- new[]
- {
- // ShootingEventArgs ev = new(firearm, this)
- new(OpCodes.Ldarg_1),
- new(OpCodes.Ldarg_0),
- new(OpCodes.Newobj, constructorInfo),
+ // Handlers.Player.OnShooting(ev)
+ new(OpCodes.Dup), // Dup to keep ev on the stack
+ new(OpCodes.Call, Method(typeof(Handlers.Player), nameof(Handlers.Player.OnShooting))),
- // Handlers.Player.OnShooting(ev)
- new(OpCodes.Dup), // Dup to keep ev on the stack
- new(OpCodes.Call, Method(typeof(Handlers.Player), nameof(Handlers.Player.OnShooting))),
+ // if (!ev.IsAllowed) return
+ new(OpCodes.Callvirt, PropertyGetter(typeof(ShootingEventArgs), nameof(ShootingEventArgs.IsAllowed))),
+ new(OpCodes.Brtrue_S, continueLabel2),
- // if (!ev.IsAllowed) return
- new(OpCodes.Callvirt, PropertyGetter(typeof(ShootingEventArgs), nameof(ShootingEventArgs.IsAllowed))),
- new(OpCodes.Brtrue_S, continueLabel),
- new(OpCodes.Leave_S, returnLabel),
+ // Dispose target FpcBacktracker
+ new(OpCodes.Ldloc_S, 5),
+ new(OpCodes.Callvirt, Method(typeof(IDisposable), nameof(IDisposable.Dispose))),
- new CodeInstruction(OpCodes.Nop).WithLabels(continueLabel),
- };
+ new(OpCodes.Leave_S, returnLabel),
+ new CodeInstruction(OpCodes.Nop).WithLabels(continueLabel2),
+ };
newInstructions.InsertRange( // noTargetIndex goes first because it's higher then hasTargetIndex so it won't mess it up
noTargetIndex,
- patchInstructions1);
+ noTargetInstructions);
newInstructions[noTargetIndex].WithLabels(noTargetLabels);
newInstructions.InsertRange(
hasTargetIndex,
- patchInstructions2);
+ hasTargetInstructions);
newInstructions[newInstructions.Count - 1].WithLabels(returnLabel);
From 57d043f3eb1763dee60f32ddbeb17103b36922f0 Mon Sep 17 00:00:00 2001
From: Banalny-Banan <133122450+Banalny-Banan@users.noreply.github.com>
Date: Mon, 17 Feb 2025 19:03:48 +0200
Subject: [PATCH 17/24] fix: randomized firearm attachments (#430)
* first
* backward compatibility
---
EXILED/Exiled.API/Features/Items/Firearm.cs | 27 +++++++++----------
.../Features/Pickups/FirearmPickup.cs | 22 +++++++--------
.../Patches/Generic/FirearmDistribution.cs | 27 -------------------
3 files changed, 24 insertions(+), 52 deletions(-)
delete mode 100644 EXILED/Exiled.Events/Patches/Generic/FirearmDistribution.cs
diff --git a/EXILED/Exiled.API/Features/Items/Firearm.cs b/EXILED/Exiled.API/Features/Items/Firearm.cs
index 663144ff8f..eeee66adcd 100644
--- a/EXILED/Exiled.API/Features/Items/Firearm.cs
+++ b/EXILED/Exiled.API/Features/Items/Firearm.cs
@@ -364,30 +364,29 @@ public static Firearm Create(FirearmType type)
/// The to add.
public void AddAttachment(AttachmentIdentifier identifier)
{
- uint toRemove = 0;
- uint code = 1;
+ // Fallback addedCode onto AvailableAttachments' code in case it's 0
+ uint addedCode = identifier.Code == 0
+ ? AvailableAttachments[FirearmType].FirstOrDefault(attId => attId.Name == identifier.Name).Code
+ : identifier.Code;
+
+ // Look for conflicting attachment (attachment that occupies the same slot)
+ uint conflicting = 0;
+ uint current = 1;
foreach (Attachment attachment in Base.Attachments)
{
if (attachment.Slot == identifier.Slot && attachment.IsEnabled)
{
- toRemove = code;
+ conflicting = current;
break;
}
- code *= 2;
+ current *= 2;
}
- uint newCode = identifier.Code == 0
- ? AvailableAttachments[FirearmType].FirstOrDefault(
- attId =>
- attId.Name == identifier.Name).Code
- : identifier.Code;
-
- Base.ApplyAttachmentsCode((Base.GetCurrentAttachmentsCode() & ~toRemove) | newCode, true);
-
- // TODO Not finish
- // Base.Status = new FirearmStatus(Math.Min(Ammo, MaxAmmo), Base.Status.Flags, Base.GetCurrentAttachmentsCode());
+ uint code = Base.ValidateAttachmentsCode((Base.GetCurrentAttachmentsCode() & ~conflicting) | addedCode);
+ Base.ApplyAttachmentsCode(code, false);
+ AttachmentCodeSync.ServerSetCode(Serial, code);
}
///
diff --git a/EXILED/Exiled.API/Features/Pickups/FirearmPickup.cs b/EXILED/Exiled.API/Features/Pickups/FirearmPickup.cs
index feb8d4c57e..b1534a0ef8 100644
--- a/EXILED/Exiled.API/Features/Pickups/FirearmPickup.cs
+++ b/EXILED/Exiled.API/Features/Pickups/FirearmPickup.cs
@@ -7,6 +7,8 @@
namespace Exiled.API.Features.Pickups
{
+ using System;
+
using Exiled.API.Interfaces;
using InventorySystem.Items;
@@ -56,7 +58,8 @@ internal FirearmPickup(ItemType type)
///
/// Gets a value indicating whether the pickup is already distributed.
///
- public bool IsDistributed { get; internal set; }
+ [Obsolete("Feature deprecated")]
+ public bool IsDistributed { get; }
///
/// Gets or sets a value indicating how much ammo can contain this .
@@ -104,7 +107,7 @@ public int Ammo
}
///
- /// Gets or sets a ammo drain per shoot.
+ /// Gets or sets the ammo drain per shoot.
///
///
/// Always by default.
@@ -121,19 +124,16 @@ public uint Attachments
set => Base.Worldmodel.Setup(Base.CurId, Base.Worldmodel.WorldmodelType, value);
}
- ///
- public override void Spawn()
- {
- base.Spawn();
- if (!IsDistributed)
- Base.OnDistributed();
- }
+ ///
+ /// Initializes the item as if it was spawned naturally by map generation.
+ ///
+ public void Distribute() => Base.OnDistributed();
///
- /// Returns the FirearmPickup in a human readable format.
+ /// Returns the FirearmPickup in a human-readable format.
///
/// A string containing FirearmPickup related data.
- public override string ToString() => $"{Type} ({Serial}) [{Weight}] *{Scale}* |{IsDistributed}| -{/*Ammo*/0}-";
+ public override string ToString() => $"{Type} ({Serial}) [{Weight}] *{Scale}*";
///
internal override void ReadItemInfo(Items.Item item)
diff --git a/EXILED/Exiled.Events/Patches/Generic/FirearmDistribution.cs b/EXILED/Exiled.Events/Patches/Generic/FirearmDistribution.cs
deleted file mode 100644
index 30deefa442..0000000000
--- a/EXILED/Exiled.Events/Patches/Generic/FirearmDistribution.cs
+++ /dev/null
@@ -1,27 +0,0 @@
-// -----------------------------------------------------------------------
-//
-// Copyright (c) ExMod Team. All rights reserved.
-// Licensed under the CC BY-SA 3.0 license.
-//
-// -----------------------------------------------------------------------
-
-namespace Exiled.Events.Patches.Generic
-{
-#pragma warning disable SA1313
- using Exiled.API.Features.Pickups;
- using HarmonyLib;
-
- using BaseFirearm = InventorySystem.Items.Firearms.FirearmPickup;
-
- ///
- /// Patch to add .
- ///
- [HarmonyPatch(typeof(BaseFirearm), nameof(BaseFirearm.OnDistributed))]
- internal static class FirearmDistribution
- {
- private static void Postfix(BaseFirearm __instance)
- {
- Pickup.Get(__instance).IsDistributed = true;
- }
- }
-}
\ No newline at end of file
From 9be51adf9074c7605395c11fb45390fab730607c Mon Sep 17 00:00:00 2001
From: Num1ock <71600441+Num10ck@users.noreply.github.com>
Date: Tue, 18 Feb 2025 17:32:23 +0400
Subject: [PATCH 18/24] feat: Added method `Exiled.API.Features.Map.Clean`
(#437)
---
EXILED/Exiled.API/Features/Map.cs | 16 ++++++++++++++++
1 file changed, 16 insertions(+)
diff --git a/EXILED/Exiled.API/Features/Map.cs b/EXILED/Exiled.API/Features/Map.cs
index c51fd1665b..4a953744f2 100644
--- a/EXILED/Exiled.API/Features/Map.cs
+++ b/EXILED/Exiled.API/Features/Map.cs
@@ -13,6 +13,8 @@ namespace Exiled.API.Features
using System.Collections.ObjectModel;
using System.Linq;
+ using CommandSystem.Commands.RemoteAdmin.Cleanup;
+ using Decals;
using Enums;
using Exiled.API.Extensions;
using Exiled.API.Features.Hazards;
@@ -27,6 +29,7 @@ namespace Exiled.API.Features
using PlayerRoles.Ragdolls;
using UnityEngine;
using Utils;
+ using Utils.Networking;
using Object = UnityEngine.Object;
@@ -271,6 +274,19 @@ public static void CleanAllRagdolls(IEnumerable ragDolls)
ragDoll.Destroy();
}
+ ///
+ /// Destroy specified amount of specified object.
+ ///
+ /// Decal type to destroy.
+ /// Amount of decals to destroy.
+ public static void Clean(DecalPoolType decalType, int amount) => new DecalCleanupMessage(decalType, amount).SendToAuthenticated();
+
+ ///
+ /// Destroy all specified objects.
+ ///
+ /// Decal type to destroy.
+ public static void Clean(DecalPoolType decalType) => Clean(decalType, int.MaxValue);
+
///
/// Places a blood decal.
///
From 95d2d54bcc9f61ac4be7b569d36cbce48e9b8ad8 Mon Sep 17 00:00:00 2001
From: Yamato <66829532+louis1706@users.noreply.github.com>
Date: Sat, 22 Feb 2025 00:08:44 +0100
Subject: [PATCH 19/24] fix: Fix NW Hypothermia bug (#441)
Fix NW Hypothermia bug
---
EXILED/Exiled.Events/Handlers/Internal/Round.cs | 7 +++++++
1 file changed, 7 insertions(+)
diff --git a/EXILED/Exiled.Events/Handlers/Internal/Round.cs b/EXILED/Exiled.Events/Handlers/Internal/Round.cs
index 87d5d2a2ca..99212af062 100644
--- a/EXILED/Exiled.Events/Handlers/Internal/Round.cs
+++ b/EXILED/Exiled.Events/Handlers/Internal/Round.cs
@@ -27,6 +27,7 @@ namespace Exiled.Events.Handlers.Internal
using InventorySystem.Items.Firearms.Attachments;
using InventorySystem.Items.Firearms.Attachments.Components;
using InventorySystem.Items.Usables;
+ using InventorySystem.Items.Usables.Scp244.Hypothermia;
using PlayerRoles;
using PlayerRoles.RoleAssign;
using Utils.NonAllocLINQ;
@@ -105,6 +106,12 @@ public static void OnVerified(VerifiedEventArgs ev)
ev.Player.SendFakeSyncVar(room.RoomLightControllerNetIdentity, typeof(RoomLightController), nameof(RoomLightController.NetworkLightsEnabled), true);
ev.Player.SendFakeSyncVar(room.RoomLightControllerNetIdentity, typeof(RoomLightController), nameof(RoomLightController.NetworkLightsEnabled), false);
}
+
+ // TODO: Remove if this has been fixed for https://git.scpslgame.com/northwood-qa/scpsl-bug-reporting/-/issues/947
+ if (ev.Player.TryGetEffect(out Hypothermia hypothermia))
+ {
+ hypothermia.SubEffects = hypothermia.SubEffects.Where(x => x.GetType() != typeof(PostProcessSubEffect)).ToArray();
+ }
}
private static void GenerateAttachments()
From 1f28777f2ef4e9abc0cc3a843b77a2b9aa757136 Mon Sep 17 00:00:00 2001
From: TtroubleTT <121741230+TtroubleTT@users.noreply.github.com>
Date: Tue, 25 Feb 2025 04:08:39 -0800
Subject: [PATCH 20/24] feat: Have NPC In Player List (#445)
npc are in player list
---
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 ada3c952af..498f7c0c1f 100644
--- a/EXILED/Exiled.API/Features/Player.cs
+++ b/EXILED/Exiled.API/Features/Player.cs
@@ -138,7 +138,7 @@ public Player(GameObject gameObject)
///
/// Gets a list of all 's on the server.
///
- public static IReadOnlyCollection List => Dictionary.Values.Where(x => !x.IsNPC).ToList();
+ public static IReadOnlyCollection List => Dictionary.Values.ToList();
///
/// Gets a containing cached and their user ids.
From f6cd7d6be1ec2ab76d03dfa908180cfcf8978ebc Mon Sep 17 00:00:00 2001
From: Num1ock <71600441+Num10ck@users.noreply.github.com>
Date: Tue, 25 Feb 2025 16:09:54 +0400
Subject: [PATCH 21/24] feat: Spawning NPCs via RA adds them to the `Npc.List`
(#440)
* feat: Spawning NPCs via RA adds them to the `Npc.List`
* Update RemoteAdminNpcCommandAddToDictionaryFix.cs
RemoteAdminNpcCommandAddToDictionaryFix is now static.
* Code style changes.
Co-authored-by: Yamato <66829532+louis1706@users.noreply.github.com>
* Documentation fix.
---------
Co-authored-by: Yamato <66829532+louis1706@users.noreply.github.com>
---
...RemoteAdminNpcCommandAddToDictionaryFix.cs | 70 +++++++++++++++++++
1 file changed, 70 insertions(+)
create mode 100644 EXILED/Exiled.Events/Patches/Fixes/RemoteAdminNpcCommandAddToDictionaryFix.cs
diff --git a/EXILED/Exiled.Events/Patches/Fixes/RemoteAdminNpcCommandAddToDictionaryFix.cs b/EXILED/Exiled.Events/Patches/Fixes/RemoteAdminNpcCommandAddToDictionaryFix.cs
new file mode 100644
index 0000000000..cb7b867f77
--- /dev/null
+++ b/EXILED/Exiled.Events/Patches/Fixes/RemoteAdminNpcCommandAddToDictionaryFix.cs
@@ -0,0 +1,70 @@
+// -----------------------------------------------------------------------
+//
+// Copyright (c) ExMod Team. All rights reserved.
+// Licensed under the CC BY-SA 3.0 license.
+//
+// -----------------------------------------------------------------------
+
+namespace Exiled.Events.Patches.Fixes
+{
+ using System.Collections.Generic;
+ using System.Reflection;
+ using System.Reflection.Emit;
+
+ using CommandSystem.Commands.RemoteAdmin.Dummies;
+ using Exiled.API.Features;
+ using Exiled.API.Features.Pools;
+ using GameCore;
+ using HarmonyLib;
+ using UnityEngine;
+
+ using static HarmonyLib.AccessTools;
+
+ ///
+ /// Fix to add created via RA to the .
+ ///
+ [HarmonyPatch(typeof(SpawnDummyCommand), nameof(SpawnDummyCommand.Execute))]
+ internal static class RemoteAdminNpcCommandAddToDictionaryFix
+ {
+ private static IEnumerable Transpiler(IEnumerable instructions, ILGenerator generator)
+ {
+ List newInstructions = ListPool.Pool.Get(instructions);
+
+ MethodBase method = Method(typeof(DummyUtils), nameof(DummyUtils.SpawnDummy));
+
+ // call ReferenceHub GameCore.DummyUtils::SpawnDummy(string)
+ int index = newInstructions.FindIndex(instruction =>
+ instruction.operand == (object)method) + 1;
+
+ LocalBuilder npc = generator.DeclareLocal(typeof(Npc));
+
+ // pop
+ newInstructions.RemoveAt(index);
+
+ newInstructions.InsertRange(
+ index,
+ new CodeInstruction[]
+ {
+ // Npc::.ctor(ReferenceHub)
+ new(OpCodes.Newobj, Constructor(typeof(Npc), new[] { typeof(ReferenceHub) })),
+ new(OpCodes.Stloc_S, npc.LocalIndex),
+
+ // Player.Dictionary.get_Dictionary
+ new(OpCodes.Call, PropertyGetter(typeof(Player), nameof(Player.Dictionary))),
+ new(OpCodes.Ldloc_S, npc.LocalIndex),
+
+ // Player::GameObject.get_GameObject
+ new(OpCodes.Callvirt, PropertyGetter(typeof(Player), nameof(Player.GameObject))),
+ new(OpCodes.Ldloc_S, npc.LocalIndex),
+
+ // Player.Dictionary.Add(GameObject, ReferenceHub)
+ new(OpCodes.Callvirt, Method(typeof(Dictionary), nameof(Dictionary.Add))),
+ });
+
+ for (int i = 0; i < newInstructions.Count; i++)
+ yield return newInstructions[i];
+
+ ListPool.Pool.Return(newInstructions);
+ }
+ }
+}
From 8485d8f971d566fa096f7607ad7c2421a4701baf Mon Sep 17 00:00:00 2001
From: R2kip <56793105+R2kip@users.noreply.github.com>
Date: Tue, 25 Feb 2025 15:10:07 +0300
Subject: [PATCH 22/24] fix: IntercomSpeaking event (#442)
* Fix IntercomSpeaking event
* ops
---
.../Patches/Events/Player/IntercomSpeaking.cs | 9 ++++-----
1 file changed, 4 insertions(+), 5 deletions(-)
diff --git a/EXILED/Exiled.Events/Patches/Events/Player/IntercomSpeaking.cs b/EXILED/Exiled.Events/Patches/Events/Player/IntercomSpeaking.cs
index 902b3d7ed6..08542cd432 100644
--- a/EXILED/Exiled.Events/Patches/Events/Player/IntercomSpeaking.cs
+++ b/EXILED/Exiled.Events/Patches/Events/Player/IntercomSpeaking.cs
@@ -38,15 +38,14 @@ private static IEnumerable Transpiler(IEnumerable instruction.Calls(Method(typeof(Stopwatch), nameof(Stopwatch.Restart)))) + offset;
+ int index = newInstructions.FindIndex(instruction => instruction.StoresField(Field(typeof(Intercom), nameof(Intercom._curSpeaker)))) + offset;
newInstructions.InsertRange(
index,
new CodeInstruction[]
{
- // Player.Get(this._curSpeaker)
- new(OpCodes.Ldarg_0),
- new(OpCodes.Ldfld, Field(typeof(Intercom), nameof(Intercom._curSpeaker))),
+ // Player.Get(first)
+ new(OpCodes.Ldloc_1),
new(OpCodes.Call, Method(typeof(Player), nameof(Player.Get), new[] { typeof(ReferenceHub) })),
// true
@@ -73,4 +72,4 @@ private static IEnumerable Transpiler(IEnumerable.Pool.Return(newInstructions);
}
}
-}
\ No newline at end of file
+}
From 6885df86a6b25449ad16b20b94cdc7327c88f075 Mon Sep 17 00:00:00 2001
From: Yamato
Date: Wed, 26 Feb 2025 13:21:02 +0100
Subject: [PATCH 23/24] 9.5.1
---
EXILED/EXILED.props | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/EXILED/EXILED.props b/EXILED/EXILED.props
index 45f9709b8e..641692ba4d 100644
--- a/EXILED/EXILED.props
+++ b/EXILED/EXILED.props
@@ -15,7 +15,7 @@
- 9.5.0
+ 9.5.1
false
From 7e326a0e7df7cb599e0603153fd1c141eba6868e Mon Sep 17 00:00:00 2001
From: hatulaile <158590752+hatulaile@users.noreply.github.com>
Date: Thu, 27 Feb 2025 14:14:38 +0800
Subject: [PATCH 24/24] feat: Added a list of players who are turned away from
SCP-939 AmnesticCloud (#446)
---
.../Exiled.API/Features/Roles/Scp939Role.cs | 5 ++
EXILED/Exiled.Events/Config.cs | 6 ++
.../Exiled.Events/Handlers/Internal/Round.cs | 1 +
.../Patches/Generic/StayAtAmnesticCloud.cs | 85 +++++++++++++++++++
4 files changed, 97 insertions(+)
create mode 100644 EXILED/Exiled.Events/Patches/Generic/StayAtAmnesticCloud.cs
diff --git a/EXILED/Exiled.API/Features/Roles/Scp939Role.cs b/EXILED/Exiled.API/Features/Roles/Scp939Role.cs
index 4396f8f87b..65ab01864a 100644
--- a/EXILED/Exiled.API/Features/Roles/Scp939Role.cs
+++ b/EXILED/Exiled.API/Features/Roles/Scp939Role.cs
@@ -90,6 +90,11 @@ internal Scp939Role(Scp939GameRole baseRole)
///
~Scp939Role() => ListPool.Pool.Return(VisiblePlayers);
+ ///
+ /// Gets a list of players who are turned away from SCP-939 AmnesticCloud Ability.
+ ///
+ public static HashSet TurnedPlayers { get; } = new(20);
+
///
public override RoleTypeId Type { get; } = RoleTypeId.Scp939;
diff --git a/EXILED/Exiled.Events/Config.cs b/EXILED/Exiled.Events/Config.cs
index 56a8206e74..5559774efa 100644
--- a/EXILED/Exiled.Events/Config.cs
+++ b/EXILED/Exiled.Events/Config.cs
@@ -44,6 +44,12 @@ public sealed class Config : IConfig
[Description("Indicates whether SCP-049 can sense tutorial players")]
public bool CanScp049SenseTutorial { get; set; } = true;
+ ///
+ /// Gets or sets a value indicating whether Tutorial is affected by Scp-939 Amnestic Cloud.
+ ///
+ [Description("Indicates whether Tutorial is affected by Scp-939 Amnestic Cloud")]
+ public bool TutorialAffectedByScp939AmnesticCloud { get; set; } = true;
+
///
/// Gets or sets a value indicating whether tutorial is affected by SCP-079 scan.
///
diff --git a/EXILED/Exiled.Events/Handlers/Internal/Round.cs b/EXILED/Exiled.Events/Handlers/Internal/Round.cs
index 99212af062..2091870dfa 100644
--- a/EXILED/Exiled.Events/Handlers/Internal/Round.cs
+++ b/EXILED/Exiled.Events/Handlers/Internal/Round.cs
@@ -62,6 +62,7 @@ public static void OnRestartingRound()
Scp173Role.TurnedPlayers.Clear();
Scp096Role.TurnedPlayers.Clear();
Scp079Role.TurnedPlayers.Clear();
+ Scp939Role.TurnedPlayers.Clear();
MultiAdminFeatures.CallEvent(MultiAdminFeatures.EventType.ROUND_END);
diff --git a/EXILED/Exiled.Events/Patches/Generic/StayAtAmnesticCloud.cs b/EXILED/Exiled.Events/Patches/Generic/StayAtAmnesticCloud.cs
new file mode 100644
index 0000000000..6541c383f3
--- /dev/null
+++ b/EXILED/Exiled.Events/Patches/Generic/StayAtAmnesticCloud.cs
@@ -0,0 +1,85 @@
+// -----------------------------------------------------------------------
+//
+// Copyright (c) ExMod Team. All rights reserved.
+// Licensed under the CC BY-SA 3.0 license.
+//
+// -----------------------------------------------------------------------
+
+namespace Exiled.Events.Patches.Generic
+{
+ using System.Collections.Generic;
+ using System.Reflection.Emit;
+
+ using Exiled.API.Features;
+ using Exiled.API.Features.Pools;
+ using HarmonyLib;
+ using PlayerRoles;
+ using PlayerRoles.PlayableScps.Scp939;
+
+ using static HarmonyLib.AccessTools;
+
+ using ExiledEvents = Exiled.Events.Events;
+ using Scp939Role = API.Features.Roles.Scp939Role;
+
+ ///
+ /// Patches .
+ /// .
+ ///
+ [HarmonyPatch(typeof(Scp939AmnesticCloudInstance), nameof(Scp939AmnesticCloudInstance.OnStay))]
+ internal static class StayAtAmnesticCloud
+ {
+ private static IEnumerable Transpiler(IEnumerable instructions, ILGenerator generator)
+ {
+ List newInstructions = ListPool.Pool.Get(instructions);
+
+ Label continueLabel = generator.DefineLabel();
+
+ Label returnLabel = generator.DefineLabel();
+
+ // Second check pointer
+ // We use it to pass execution
+ // to the second check if the first check fails,
+ // otherwise the second check won't be executed
+ Label secondCheckPointer = generator.DefineLabel();
+
+ newInstructions[0].WithLabels(continueLabel);
+
+ // if (referenceHub.roleManager.CurrentRole.RoleTypeId == RoleTypeId.Tutorial && ExiledEvents.Instance.Config.TutorialAffectedByScp939AmnesticCloud
+ // || Scp939Role.TurnedPlayers.Contains(Player.Get(referenceHub)))
+ // return;
+ newInstructions.InsertRange(
+ 0,
+ new[]
+ {
+ // if ((referenceHub.roleManager.CurrentRole.RoleTypeId == RoleTypeId.Tutorial &&
+ new(OpCodes.Ldarg_1),
+ new(OpCodes.Ldfld, Field(typeof(ReferenceHub), nameof(ReferenceHub.roleManager))),
+ new(OpCodes.Callvirt, PropertyGetter(typeof(PlayerRoleManager), nameof(PlayerRoleManager.CurrentRole))),
+ new(OpCodes.Callvirt, PropertyGetter(typeof(PlayerRoleBase), nameof(PlayerRoleBase.RoleTypeId))),
+ new(OpCodes.Ldc_I4_S, (sbyte)RoleTypeId.Tutorial),
+ new(OpCodes.Bne_Un_S, secondCheckPointer),
+
+ // ExiledEvents.Instance.Config.TutorialAffectedByScp939AmnesticCloud)
+ new(OpCodes.Call, PropertyGetter(typeof(ExiledEvents), nameof(ExiledEvents.Instance))),
+ new(OpCodes.Callvirt, PropertyGetter(typeof(Plugin), nameof(Plugin.Config))),
+ new(OpCodes.Callvirt, PropertyGetter(typeof(Config), nameof(Config.TutorialAffectedByScp939AmnesticCloud))),
+ new(OpCodes.Brtrue_S, returnLabel),
+
+ // || Scp939Role.TurnedPlayers.Contains(Player.Get(referenceHub))
+ new CodeInstruction(OpCodes.Call, PropertyGetter(typeof(Scp939Role), nameof(Scp939Role.TurnedPlayers))).WithLabels(secondCheckPointer),
+ new(OpCodes.Ldarg_1),
+ new(OpCodes.Call, Method(typeof(Player), nameof(Player.Get), new[] { typeof(ReferenceHub) })),
+ new(OpCodes.Callvirt, Method(typeof(HashSet), nameof(HashSet.Contains))),
+ new(OpCodes.Brfalse_S, continueLabel),
+
+ // return;
+ new CodeInstruction(OpCodes.Ret).WithLabels(returnLabel),
+ });
+
+ for (int i = 0; i < newInstructions.Count; i++)
+ yield return newInstructions[i];
+
+ ListPool.Pool.Return(newInstructions);
+ }
+ }
+}
\ No newline at end of file