From 043d9a98ba58c30ee05a7e13210126b2b085502b Mon Sep 17 00:00:00 2001 From: VALERA771 <72030575+VALERA771@users.noreply.github.com> Date: Sun, 10 Nov 2024 01:16:47 +0300 Subject: [PATCH] `[Exiled::Events]` `[Exiled::API]` New event + new property (#31) * new ev + previous role * suggestions * uwu * suj * fix * uwu --------- Co-authored-by: Yamato <66829532+louis1706@users.noreply.github.com> --- EXILED/Exiled.API/Features/Player.cs | 11 ++- .../EventArgs/Player/EscapedEventArgs.cs | 70 +++++++++++++++++++ EXILED/Exiled.Events/Handlers/Player.cs | 11 +++ .../{Escaping.cs => EscapingAndEscaped.cs} | 51 ++++++++++++-- 4 files changed, 136 insertions(+), 7 deletions(-) create mode 100644 EXILED/Exiled.Events/EventArgs/Player/EscapedEventArgs.cs rename EXILED/Exiled.Events/Patches/Events/Player/{Escaping.cs => EscapingAndEscaped.cs} (74%) diff --git a/EXILED/Exiled.API/Features/Player.cs b/EXILED/Exiled.API/Features/Player.cs index d5e3d3eae..c6cd27514 100644 --- a/EXILED/Exiled.API/Features/Player.cs +++ b/EXILED/Exiled.API/Features/Player.cs @@ -589,9 +589,18 @@ public PlayerPermissions RemoteAdminPermissions public Role Role { get => role ??= Role.Create(RoleManager.CurrentRole); - internal set => role = value; + internal set + { + PreviousRole = role.Type; + role = value; + } } + /// + /// Gets the role that player had before changing role. + /// + public RoleTypeId PreviousRole { get; private set; } + /// /// Gets or sets the player's SCP preferences. /// diff --git a/EXILED/Exiled.Events/EventArgs/Player/EscapedEventArgs.cs b/EXILED/Exiled.Events/EventArgs/Player/EscapedEventArgs.cs new file mode 100644 index 000000000..f185f7845 --- /dev/null +++ b/EXILED/Exiled.Events/EventArgs/Player/EscapedEventArgs.cs @@ -0,0 +1,70 @@ +// ----------------------------------------------------------------------- +// +// Copyright (c) Exiled Team. All rights reserved. +// Licensed under the CC BY-SA 3.0 license. +// +// ----------------------------------------------------------------------- + +namespace Exiled.Events.EventArgs.Player +{ + using System; + using System.Collections.Generic; + + using Exiled.API.Enums; + using Exiled.API.Features; + using Exiled.API.Features.Roles; + using Exiled.Events.EventArgs.Interfaces; + using PlayerRoles; + using Respawning; + + /// + /// Contains all information after player has escaped. + /// + public class EscapedEventArgs : IPlayerEvent + { + /// + /// Initializes a new instance of the class. + /// + /// + /// + /// + /// , . + public EscapedEventArgs(Player player, EscapeScenario escapeScenario, Role role, KeyValuePair kvp) + { + Player = player; + EscapeScenario = escapeScenario; + Team = kvp.Key; + Tickets = kvp.Value; + OldRole = role; + EscapeTime = (int)Math.Ceiling(role.ActiveTime.TotalSeconds); + } + + /// + public Player Player { get; } + + /// + /// Gets the type of escape. + /// + public EscapeScenario EscapeScenario { get; } + + /// + /// Gets the that gained tickets for this escape. + /// + public SpawnableTeamType Team { get; } + + /// + /// Gets the amount of tickets gained for this escape. + /// + public float Tickets { get; } + + /// + /// Gets the previous role for this player. + /// + public Role OldRole { get; } + + /// + /// Gets the time in seconds since round started. + /// + public int EscapeTime { get; } + } +} \ No newline at end of file diff --git a/EXILED/Exiled.Events/Handlers/Player.cs b/EXILED/Exiled.Events/Handlers/Player.cs index 2e6209741..576cc3bb0 100644 --- a/EXILED/Exiled.Events/Handlers/Player.cs +++ b/EXILED/Exiled.Events/Handlers/Player.cs @@ -239,6 +239,11 @@ public class Player /// public static Event Escaping { get; set; } = new(); + /// + /// Invoked after a escapes. + /// + public static Event Escaped { get; set; } = new(); + /// /// Invoked before a begins speaking to the intercom. /// @@ -734,6 +739,12 @@ public class Player /// The instance. public static void OnEscaping(EscapingEventArgs ev) => Escaping.InvokeSafely(ev); + /// + /// Called after a escapes. + /// + /// The instance. + public static void OnEscaped(EscapedEventArgs ev) => Escaped.InvokeSafely(ev); + /// /// Called before a begins speaking to the intercom. /// diff --git a/EXILED/Exiled.Events/Patches/Events/Player/Escaping.cs b/EXILED/Exiled.Events/Patches/Events/Player/EscapingAndEscaped.cs similarity index 74% rename from EXILED/Exiled.Events/Patches/Events/Player/Escaping.cs rename to EXILED/Exiled.Events/Patches/Events/Player/EscapingAndEscaped.cs index 048de1136..a48e531d9 100644 --- a/EXILED/Exiled.Events/Patches/Events/Player/Escaping.cs +++ b/EXILED/Exiled.Events/Patches/Events/Player/EscapingAndEscaped.cs @@ -1,5 +1,5 @@ // ----------------------------------------------------------------------- -// +// // Copyright (c) Exiled Team. All rights reserved. // Licensed under the CC BY-SA 3.0 license. // @@ -8,6 +8,7 @@ namespace Exiled.Events.Patches.Events.Player { #pragma warning disable SA1402 // File may only contain a single type +#pragma warning disable IDE0060 using System; using System.Collections.Generic; @@ -18,8 +19,8 @@ namespace Exiled.Events.Patches.Events.Player using API.Enums; using API.Features; using API.Features.Pools; - using EventArgs.Player; + using Exiled.API.Features.Roles; using Exiled.Events.Attributes; using HarmonyLib; using PlayerRoles.FirstPersonControl; @@ -28,11 +29,12 @@ namespace Exiled.Events.Patches.Events.Player using static HarmonyLib.AccessTools; /// - /// Patches for . + /// Patches for and . /// [EventPatch(typeof(Handlers.Player), nameof(Handlers.Player.Escaping))] + [EventPatch(typeof(Handlers.Player), nameof(Handlers.Player.Escaped))] [HarmonyPatch(typeof(Escape), nameof(Escape.ServerHandlePlayer))] - internal static class Escaping + internal static class EscapingAndEscaped { private static IEnumerable Transpiler(IEnumerable instructions, ILGenerator generator) { @@ -42,6 +44,7 @@ private static IEnumerable Transpiler(IEnumerable instruction.opcode == OpCodes.Newobj) + offset; @@ -97,9 +100,44 @@ private static IEnumerable Transpiler(IEnumerable x.Is(OpCodes.Stfld, Field(typeof(Escape.EscapeMessage), nameof(Escape.EscapeMessage.EscapeTime)))) + offset; + + newInstructions.InsertRange(index, new CodeInstruction[] + { + // role = ev.Player.Role + new(OpCodes.Ldloc_S, ev.LocalIndex), + new(OpCodes.Callvirt, PropertyGetter(typeof(EscapingEventArgs), nameof(EscapingEventArgs.Player))), + new(OpCodes.Callvirt, PropertyGetter(typeof(Player), nameof(Player.Role))), + new(OpCodes.Stloc_S, role.LocalIndex), + }); + + newInstructions.InsertRange(newInstructions.Count - 1, new CodeInstruction[] + { + // ev.Player + new(OpCodes.Ldloc_S, ev.LocalIndex), + new(OpCodes.Callvirt, PropertyGetter(typeof(EscapingEventArgs), nameof(EscapingEventArgs.Player))), + + // escapeScenario + new(OpCodes.Ldloc_1), + + // role + new(OpCodes.Ldloc_S, role.LocalIndex), + + // ev.RespawnTickets.Key + new(OpCodes.Ldloc_S, ev.LocalIndex), + new(OpCodes.Callvirt, PropertyGetter(typeof(EscapingEventArgs), nameof(EscapingEventArgs.RespawnTickets))), + + // EscapedEventArgs ev2 = new(ev.Player, ev.EscapeScenario, role, float, SpawnableTeamType); + new(OpCodes.Newobj, GetDeclaredConstructors(typeof(EscapedEventArgs))[0]), + + // Handlers.Player.OnEscaped(ev); + new(OpCodes.Call, Method(typeof(Handlers.Player), nameof(Handlers.Player.OnEscaped))), + }); + newInstructions[newInstructions.Count - 1].WithLabels(returnLabel); for (int z = 0; z < newInstructions.Count; z++) @@ -120,6 +158,7 @@ private static void GrantAllTickets(EscapingEventArgs ev) /// Replaces last returned to . /// [EventPatch(typeof(Handlers.Player), nameof(Handlers.Player.Escaping))] + [EventPatch(typeof(Handlers.Player), nameof(Handlers.Player.Escaped))] [HarmonyPatch(typeof(Escape), nameof(Escape.ServerGetScenario))] internal static class GetScenario { @@ -151,4 +190,4 @@ private static IEnumerable Transpiler(IEnumerable.Pool.Return(newInstructions); } } -} +} \ No newline at end of file