From eb18019b4005e5e59f432800be71dabfb7d9ed79 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mustafa=20SAVA=C5=9E?= Date: Sun, 1 Feb 2026 21:07:00 +0300 Subject: [PATCH 1/5] =?UTF-8?q?ZoneChangedReborn=C5=9F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../EventArgs/Player/RoomChangedEventArgs.cs | 11 ++-- .../EventArgs/Player/ZoneChangedEventArgs.cs | 59 +++++++++++++++++++ EXILED/Exiled.Events/Features/Event{T}.cs | 5 ++ EXILED/Exiled.Events/Handlers/Player.cs | 29 ++++++++- .../Patches/Events/Player/ChangedRoom.cs | 8 ++- 5 files changed, 103 insertions(+), 9 deletions(-) create mode 100644 EXILED/Exiled.Events/EventArgs/Player/ZoneChangedEventArgs.cs diff --git a/EXILED/Exiled.Events/EventArgs/Player/RoomChangedEventArgs.cs b/EXILED/Exiled.Events/EventArgs/Player/RoomChangedEventArgs.cs index 57f17a3eda..c6a989b5a3 100644 --- a/EXILED/Exiled.Events/EventArgs/Player/RoomChangedEventArgs.cs +++ b/EXILED/Exiled.Events/EventArgs/Player/RoomChangedEventArgs.cs @@ -8,7 +8,6 @@ namespace Exiled.Events.EventArgs.Player { using Exiled.API.Features; using Exiled.Events.EventArgs.Interfaces; - using MapGeneration; /// /// Contains the information when a player changes rooms. @@ -19,13 +18,13 @@ public class RoomChangedEventArgs : IPlayerEvent /// Initializes a new instance of the class. /// /// The player whose room has changed. - /// The room identifier before the change (Can be null on round start). + /// The room identifier before the change. /// The room identifier after the change. - public RoomChangedEventArgs(ReferenceHub player, RoomIdentifier oldRoom, RoomIdentifier newRoom) + public RoomChangedEventArgs(Player player, Room oldRoom, Room newRoom) { - Player = Player.Get(player); - OldRoom = Room.Get(oldRoom); - NewRoom = Room.Get(newRoom); + Player = player; + OldRoom = oldRoom; + NewRoom = newRoom; } /// diff --git a/EXILED/Exiled.Events/EventArgs/Player/ZoneChangedEventArgs.cs b/EXILED/Exiled.Events/EventArgs/Player/ZoneChangedEventArgs.cs new file mode 100644 index 0000000000..3e6d998ed9 --- /dev/null +++ b/EXILED/Exiled.Events/EventArgs/Player/ZoneChangedEventArgs.cs @@ -0,0 +1,59 @@ +// ----------------------------------------------------------------------- +// +// Copyright (c) ExMod Team. All rights reserved. +// Licensed under the CC BY-SA 3.0 license. +// +// ----------------------------------------------------------------------- + +namespace Exiled.Events.EventArgs.Player +{ + using Exiled.API.Enums; + using Exiled.API.Features; + using Exiled.Events.EventArgs.Interfaces; + + /// + /// Contains the information when a player changes zones. + /// + public class ZoneChangedEventArgs : IPlayerEvent + { + /// + /// Initializes a new instance of the class. + /// + /// The player whose zone has changed. + /// The previous room the player was in. + /// The new room the player entered. + /// The previous zone the player was in. + /// The new zone the player entered. + public ZoneChangedEventArgs(Player player, Room oldRoom, Room newRoom, ZoneType oldZone, ZoneType newZone) + { + Player = player; + OldRoom = oldRoom; + NewRoom = newRoom; + OldZone = oldZone; + NewZone = newZone; + } + + /// + public Player Player { get; } + + /// + /// Gets the previous zone the player was in. + /// + public ZoneType OldZone { get; } + + /// + /// Gets the new zone the player entered. + /// + public ZoneType NewZone { get; } + + /// + /// Gets the previous room the player was in. + /// + public Room OldRoom { get; } + + /// + /// Gets the new room the player entered. + /// + public Room NewRoom { get; } + } +} \ No newline at end of file diff --git a/EXILED/Exiled.Events/Features/Event{T}.cs b/EXILED/Exiled.Events/Features/Event{T}.cs index 2d6252b91e..fed05bf477 100644 --- a/EXILED/Exiled.Events/Features/Event{T}.cs +++ b/EXILED/Exiled.Events/Features/Event{T}.cs @@ -65,6 +65,11 @@ public Event() /// public static IReadOnlyDictionary> Dictionary => TypeToEvent; + /// + /// Gets a value indicating whether this event has any subscribers. + /// + public bool HasSubscribers => innerEvent.Count > 0 || innerAsyncEvent.Count > 0; + /// /// Subscribes a target to the inner event and checks if patching is possible, if dynamic patching is enabled. /// diff --git a/EXILED/Exiled.Events/Handlers/Player.cs b/EXILED/Exiled.Events/Handlers/Player.cs index 998b54f813..63c7169843 100644 --- a/EXILED/Exiled.Events/Handlers/Player.cs +++ b/EXILED/Exiled.Events/Handlers/Player.cs @@ -9,6 +9,9 @@ namespace Exiled.Events.Handlers { using System; + using Exiled.API.Enums; + using Exiled.API.Features; + #pragma warning disable IDE0079 #pragma warning disable IDE0060 #pragma warning disable SA1623 // Property summary documentation should match accessors @@ -16,6 +19,7 @@ namespace Exiled.Events.Handlers using Exiled.Events.EventArgs.Player; using Exiled.Events.Features; + using LabApi.Events.Arguments.PlayerEvents; /// @@ -505,6 +509,11 @@ public class Player /// public static Event RoomChanged { get; set; } = new(); + /// + /// Invoked when a changes zones. + /// + public static Event ZoneChanged { get; set; } = new(); + /// /// Invoked before a toggles the NoClip mode. /// @@ -835,7 +844,25 @@ public class Player /// Called when a changes rooms. /// /// The instance. - public static void OnRoomChanged(RoomChangedEventArgs ev) => RoomChanged.InvokeSafely(ev); + public static void OnRoomChanged(RoomChangedEventArgs ev) + { + RoomChanged.InvokeSafely(ev); + + if (!ZoneChanged.HasSubscribers) + return; + + ZoneType oldZone = ev.OldRoom?.Zone ?? ZoneType.Unspecified; + ZoneType newZone = ev.NewRoom?.Zone ?? ZoneType.Unspecified; + + if (oldZone != newZone) + OnZoneChanged(new ZoneChangedEventArgs(ev.Player, ev.OldRoom, ev.NewRoom, oldZone, newZone)); + } + + /// + /// Called when a changes zones. + /// + /// The instance. + public static void OnZoneChanged(ZoneChangedEventArgs ev) => ZoneChanged.InvokeSafely(ev); /// /// Called before a escapes. diff --git a/EXILED/Exiled.Events/Patches/Events/Player/ChangedRoom.cs b/EXILED/Exiled.Events/Patches/Events/Player/ChangedRoom.cs index 376587b14e..b7ffcdbf8c 100644 --- a/EXILED/Exiled.Events/Patches/Events/Player/ChangedRoom.cs +++ b/EXILED/Exiled.Events/Patches/Events/Player/ChangedRoom.cs @@ -25,6 +25,7 @@ namespace Exiled.Events.Patches.Events.Player /// Patches to add the event. /// [EventPatch(typeof(Player), nameof(Player.RoomChanged))] + [EventPatch(typeof(Player), nameof(Player.ZoneChanged))] [HarmonyPatch(typeof(CurrentRoomPlayerCache), nameof(CurrentRoomPlayerCache.ValidateCache))] internal class ChangedRoom { @@ -40,19 +41,22 @@ private static IEnumerable Transpiler(IEnumerable Date: Mon, 2 Feb 2026 14:30:52 +0300 Subject: [PATCH 2/5] revert transpiler change --- .../EventArgs/Player/RoomChangedEventArgs.cs | 10 ++++++---- .../Exiled.Events/Patches/Events/Player/ChangedRoom.cs | 7 ++----- 2 files changed, 8 insertions(+), 9 deletions(-) diff --git a/EXILED/Exiled.Events/EventArgs/Player/RoomChangedEventArgs.cs b/EXILED/Exiled.Events/EventArgs/Player/RoomChangedEventArgs.cs index c6a989b5a3..c640b78217 100644 --- a/EXILED/Exiled.Events/EventArgs/Player/RoomChangedEventArgs.cs +++ b/EXILED/Exiled.Events/EventArgs/Player/RoomChangedEventArgs.cs @@ -9,6 +9,8 @@ namespace Exiled.Events.EventArgs.Player using Exiled.API.Features; using Exiled.Events.EventArgs.Interfaces; + using MapGeneration; + /// /// Contains the information when a player changes rooms. /// @@ -20,11 +22,11 @@ public class RoomChangedEventArgs : IPlayerEvent /// The player whose room has changed. /// The room identifier before the change. /// The room identifier after the change. - public RoomChangedEventArgs(Player player, Room oldRoom, Room newRoom) + public RoomChangedEventArgs(ReferenceHub player, RoomIdentifier oldRoom, RoomIdentifier newRoom) { - Player = player; - OldRoom = oldRoom; - NewRoom = newRoom; + Player = Player.Get(player); + OldRoom = Room.Get(oldRoom); + NewRoom = Room.Get(newRoom); } /// diff --git a/EXILED/Exiled.Events/Patches/Events/Player/ChangedRoom.cs b/EXILED/Exiled.Events/Patches/Events/Player/ChangedRoom.cs index b7ffcdbf8c..071e1c5fe1 100644 --- a/EXILED/Exiled.Events/Patches/Events/Player/ChangedRoom.cs +++ b/EXILED/Exiled.Events/Patches/Events/Player/ChangedRoom.cs @@ -41,22 +41,19 @@ private static IEnumerable Transpiler(IEnumerable Date: Mon, 2 Feb 2026 14:42:48 +0300 Subject: [PATCH 3/5] hassubscribes to patched --- EXILED/Exiled.Events/Features/Event{T}.cs | 14 ++++++-------- EXILED/Exiled.Events/Handlers/Player.cs | 2 +- 2 files changed, 7 insertions(+), 9 deletions(-) diff --git a/EXILED/Exiled.Events/Features/Event{T}.cs b/EXILED/Exiled.Events/Features/Event{T}.cs index fed05bf477..65ea0ccd09 100644 --- a/EXILED/Exiled.Events/Features/Event{T}.cs +++ b/EXILED/Exiled.Events/Features/Event{T}.cs @@ -50,8 +50,6 @@ private record AsyncRegistration(CustomAsyncEventHandler handler, int priorit private readonly List innerAsyncEvent = new(); - private bool patched; - /// /// Initializes a new instance of the class. /// @@ -66,9 +64,9 @@ public Event() public static IReadOnlyDictionary> Dictionary => TypeToEvent; /// - /// Gets a value indicating whether this event has any subscribers. + /// Gets a value indicating whether the Harmony patch for this event has been applied. /// - public bool HasSubscribers => innerEvent.Count > 0 || innerAsyncEvent.Count > 0; + public bool Patched { get; private set; } /// /// Subscribes a target to the inner event and checks if patching is possible, if dynamic patching is enabled. @@ -134,10 +132,10 @@ public void Subscribe(CustomEventHandler handler, int priority) { Log.Assert(Events.Instance is not null, $"{nameof(Events.Instance)} is null, please ensure you have exiled_events enabled!"); - if (Events.Instance.Config.UseDynamicPatching && !patched) + if (Events.Instance.Config.UseDynamicPatching && !Patched) { Events.Instance.Patcher.Patch(this); - patched = true; + Patched = true; } if (handler == null) @@ -173,10 +171,10 @@ public void Subscribe(CustomAsyncEventHandler handler, int priority) { Log.Assert(Events.Instance is not null, $"{nameof(Events.Instance)} is null, please ensure you have exiled_events enabled!"); - if (Events.Instance.Config.UseDynamicPatching && !patched) + if (Events.Instance.Config.UseDynamicPatching && !Patched) { Events.Instance.Patcher.Patch(this); - patched = true; + Patched = true; } if (handler == null) diff --git a/EXILED/Exiled.Events/Handlers/Player.cs b/EXILED/Exiled.Events/Handlers/Player.cs index 63c7169843..49dc14f00f 100644 --- a/EXILED/Exiled.Events/Handlers/Player.cs +++ b/EXILED/Exiled.Events/Handlers/Player.cs @@ -848,7 +848,7 @@ public static void OnRoomChanged(RoomChangedEventArgs ev) { RoomChanged.InvokeSafely(ev); - if (!ZoneChanged.HasSubscribers) + if (!ZoneChanged.Patched) return; ZoneType oldZone = ev.OldRoom?.Zone ?? ZoneType.Unspecified; From 06053c3bc7bae92438e49cf801b68a782d1eb537 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mustafa=20SAVA=C5=9E?= Date: Mon, 2 Feb 2026 14:55:02 +0300 Subject: [PATCH 4/5] fixed --- EXILED/Exiled.Events/Features/Event{T}.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/EXILED/Exiled.Events/Features/Event{T}.cs b/EXILED/Exiled.Events/Features/Event{T}.cs index 65ea0ccd09..847adc883d 100644 --- a/EXILED/Exiled.Events/Features/Event{T}.cs +++ b/EXILED/Exiled.Events/Features/Event{T}.cs @@ -66,7 +66,7 @@ public Event() /// /// Gets a value indicating whether the Harmony patch for this event has been applied. /// - public bool Patched { get; private set; } + public bool Patched { get; private set; } = !Events.Instance.Config.UseDynamicPatching; /// /// Subscribes a target to the inner event and checks if patching is possible, if dynamic patching is enabled. From 28d3e5d316da68e37cae2164e9422684c28703e9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mustafa=20SAVA=C5=9E?= Date: Mon, 2 Feb 2026 22:46:19 +0300 Subject: [PATCH 5/5] addded patched event too --- EXILED/Exiled.Events/Features/Event.cs | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/EXILED/Exiled.Events/Features/Event.cs b/EXILED/Exiled.Events/Features/Event.cs index bbbc638401..7db233c910 100644 --- a/EXILED/Exiled.Events/Features/Event.cs +++ b/EXILED/Exiled.Events/Features/Event.cs @@ -45,8 +45,6 @@ private record AsyncRegistration(CustomAsyncEventHandler handler, int priority); private readonly List innerAsyncEvent = new(); - private bool patched; - /// /// Initializes a new instance of the class. /// @@ -60,6 +58,11 @@ public Event() /// public static IReadOnlyList List => EventsValue; + /// + /// Gets a value indicating whether the Harmony patch for this event has been applied. + /// + public bool Patched { get; private set; } = !Events.Instance.Config.UseDynamicPatching; + /// /// Subscribes a to the inner event, and checks patches if dynamic patching is enabled. /// @@ -124,10 +127,10 @@ public void Subscribe(CustomEventHandler handler, int priority) { Log.Assert(Events.Instance is not null, $"{nameof(Events.Instance)} is null, please ensure you have exiled_events enabled!"); - if (Events.Instance.Config.UseDynamicPatching && !patched) + if (Events.Instance.Config.UseDynamicPatching && !Patched) { Events.Instance.Patcher.Patch(this); - patched = true; + Patched = true; } if (handler == null) @@ -163,10 +166,10 @@ public void Subscribe(CustomAsyncEventHandler handler, int priority) { Log.Assert(Events.Instance is not null, $"{nameof(Events.Instance)} is null, please ensure you have exiled_events enabled!"); - if (Events.Instance.Config.UseDynamicPatching && !patched) + if (Events.Instance.Config.UseDynamicPatching && !Patched) { Events.Instance.Patcher.Patch(this); - patched = true; + Patched = true; } if (handler == null)