Skip to content

Commit

Permalink
SendingAdminChatMessageEvent (#2159)
Browse files Browse the repository at this point in the history
* SendingAdminChatMessage

* oh 'lol

Co-authored-by: VALERA771 <72030575+VALERA771@users.noreply.github.com>

* Update SendingAdminChatMessageEventsArgs.cs

---------

Co-authored-by: VALERA771 <72030575+VALERA771@users.noreply.github.com>
Co-authored-by: Nao <60253860+NaoUnderscore@users.noreply.github.com>
  • Loading branch information
3 people authored Oct 24, 2023
1 parent 3178bac commit 42e3092
Show file tree
Hide file tree
Showing 4 changed files with 165 additions and 0 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
// -----------------------------------------------------------------------
// <copyright file="SendingAdminChatMessageEventsArgs.cs" company="Exiled Team">
// Copyright (c) Exiled Team. All rights reserved.
// Licensed under the CC BY-SA 3.0 license.
// </copyright>
// -----------------------------------------------------------------------

namespace Exiled.Events.EventArgs.Player
{
using Exiled.API.Features;
using Exiled.API.Features.Pickups;
using Exiled.Events.EventArgs.Interfaces;

using InventorySystem.Items.Pickups;
using InventorySystem.Searching;

/// <summary>
/// Contains all information before a player sends a message in AdminChat.
/// </summary>
public class SendingAdminChatMessageEventsArgs : IPlayerEvent, IDeniableEvent
{
/// <summary>
/// Initializes a new instance of the <see cref="SendingAdminChatMessageEventsArgs" /> class.
/// </summary>
/// <param name="player">
/// <inheritdoc cref="Player" />
/// </param>
/// <param name="message">
/// <inheritdoc cref="Message" />
/// </param>
/// <param name="isAllowed">
/// <inheritdoc cref="IsAllowed" />
/// </param>
public SendingAdminChatMessageEventsArgs(Player player, string message, bool isAllowed)
{
Player = player;
Message = message;
IsAllowed = isAllowed;
}

/// <summary>
/// Gets or sets a value indicating whether the pickup can be searched.
/// </summary>
public bool IsAllowed { get; set; }

/// <summary>
/// Gets or sets the message which is being sent.
/// </summary>
public string Message { get; set; }

/// <summary>
/// Gets the player who's sending the message.
/// </summary>
public Player Player { get; }
}
}
11 changes: 11 additions & 0 deletions Exiled.Events/Handlers/Player.cs
Original file line number Diff line number Diff line change
Expand Up @@ -452,6 +452,11 @@ public class Player
/// </summary>
public static Event<SearchingPickupEventArgs> SearchingPickup { get; set; } = new();

/// <summary>
/// Invoked before a <see cref="API.Features.Player"/> send a message in AdminChat.
/// </summary>
public static Event<SendingAdminChatMessageEventsArgs> SendingAdminChatMessage { get; set; } = new();

/// <summary>
/// Invoked before a <see cref="API.Features.Player"/> damage a Window.
/// </summary> // TODO: DamagingWindow instead of PlayerDamageWindow
Expand Down Expand Up @@ -896,6 +901,12 @@ public class Player
/// <param name="ev">The <see cref="SearchingPickupEventArgs"/> instance.</param>
public static void OnSearchPickupRequest(SearchingPickupEventArgs ev) => SearchingPickup.InvokeSafely(ev);

/// <summary>
/// Called before a <see cref="API.Features.Player"/> searches a Pickup.
/// </summary>
/// <param name="ev">The <see cref="SendingAdminChatMessageEventsArgs"/> instance.</param>
public static void OnSendingAdminChatMessage(SendingAdminChatMessageEventsArgs ev) => SendingAdminChatMessage.InvokeSafely(ev);

/// <summary>
/// Called before KillPlayer is called.
/// </summary>
Expand Down
97 changes: 97 additions & 0 deletions Exiled.Events/Patches/Events/Player/SendingAdminChatMessage.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
// -----------------------------------------------------------------------
// <copyright file="SendingAdminChatMessage.cs" company="Exiled Team">
// Copyright (c) Exiled Team. All rights reserved.
// Licensed under the CC BY-SA 3.0 license.
// </copyright>
// -----------------------------------------------------------------------

namespace Exiled.Events.Patches.Events.Player
{
using System.Collections.Generic;
using System.Reflection.Emit;

using API.Features;
using API.Features.Pools;
using Exiled.Events.Attributes;
using Exiled.Events.EventArgs.Player;

using HarmonyLib;

using InventorySystem.Items.Pickups;
using InventorySystem.Searching;
using RemoteAdmin;

using static HarmonyLib.AccessTools;

/// <summary>
/// Patches <see cref="CommandProcessor.ProcessAdminChat(string, CommandSender)" />.
/// Adds the <see cref="Handlers.Player.SendingAdminChatMessage" /> event.
/// </summary>
[EventPatch(typeof(Handlers.Player), nameof(Handlers.Player.SendingAdminChatMessage))]
[HarmonyPatch(typeof(CommandProcessor), nameof(CommandProcessor.ProcessAdminChat))]
internal static class SendingAdminChatMessage
{
private static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstruction> instructions, ILGenerator generator)
{
List<CodeInstruction> newInstructions = ListPool<CodeInstruction>.Pool.Get(instructions);

Label allowLabel = generator.DefineLabel();

LocalBuilder ev = generator.DeclareLocal(typeof(SendingAdminChatMessageEventsArgs));

int offset = 0;
int index = newInstructions.FindIndex(instruction => instruction.opcode == OpCodes.Ldloca_S) + offset;

newInstructions.InsertRange(
index,
new[]
{
// Player.Get(Hub)
new CodeInstruction(OpCodes.Ldloc_1).MoveLabelsFrom(newInstructions[index]),
new(OpCodes.Ldfld, Field(typeof(PlayerCommandSender), nameof(PlayerCommandSender.ReferenceHub))),
new(OpCodes.Call, Method(typeof(Player), nameof(Player.Get), new[] { typeof(ReferenceHub) })),

// message
new(OpCodes.Ldarg_0),

// SearchingPickupEventArgs ev = new(Player, ItemPickupBase, SearchSession, SearchCompletor, float);
new(OpCodes.Newobj, GetDeclaredConstructors(typeof(SendingAdminChatMessageEventsArgs))[0]),
new(OpCodes.Dup),
new(OpCodes.Dup),
new(OpCodes.Stloc_S, ev.LocalIndex),

// Handlers.Player.OnSearchPickupRequest(ev)
new(OpCodes.Call, Method(typeof(Handlers.Player), nameof(Handlers.Player.OnSendingAdminChatMessage))),

// if (ev.IsAllowed)
// goto allowLabel;
new(OpCodes.Callvirt, PropertyGetter(typeof(SendingAdminChatMessageEventsArgs), nameof(SendingAdminChatMessageEventsArgs.IsAllowed))),
new(OpCodes.Brfalse_S, allowLabel),

// IsNotAllowedMessaqe(ev.Player);
// return;
new(OpCodes.Ldloc_S, ev.LocalIndex),
new(OpCodes.Call, PropertyGetter(typeof(SendingAdminChatMessageEventsArgs), nameof(SendingAdminChatMessageEventsArgs.Player))),
new(OpCodes.Call, Method(typeof(SendingAdminChatMessage), nameof(SendingAdminChatMessage.IsNotAllowedMessaqe))),
new(OpCodes.Ret),

// message = ev.Message;
new CodeInstruction(OpCodes.Ldloc_S, ev.LocalIndex).WithLabels(allowLabel),
new(OpCodes.Call, PropertyGetter(typeof(SendingAdminChatMessageEventsArgs), nameof(SendingAdminChatMessageEventsArgs.Message))),
new(OpCodes.Starg_S, 0),
});

for (int z = 0; z < newInstructions.Count; z++)
yield return newInstructions[z];

ListPool<CodeInstruction>.Pool.Return(newInstructions);
}

private static void IsNotAllowedMessaqe(Player player)
{
if (player == null)
return;
player.RemoteAdminMessage("AdminChatMessage Cancel by a plugin", false, "EXILED:Event");
}
}
}
1 change: 1 addition & 0 deletions Exiled.Loader/LoaderPlugin.cs
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ public class LoaderPlugin
/// Called by PluginAPI when the plugin is enabled.
/// </summary>
[PluginEntryPoint("Exiled Loader", null, "Loads the EXILED Plugin Framework.", "Exiled-Team")]
[PluginPriority(byte.MinValue)]
public void Enable()
{
if (!Config.IsEnabled)
Expand Down

0 comments on commit 42e3092

Please sign in to comment.