Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[EXILED::EVENTS] Adding PlayingAudioLog #69

Merged
merged 11 commits into from
Aug 27, 2024
44 changes: 44 additions & 0 deletions EXILED/Exiled.Events/EventArgs/Player/PlayingAudioLogEventArgs.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
// -----------------------------------------------------------------------
// <copyright file="PlayingAudioLogEventArgs.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 API.Features;

using Interfaces;

/// <summary>
/// Contains all information before a player plays the AudioLog.
/// </summary>
public class PlayingAudioLogEventArgs : IPlayerEvent, IDeniableEvent
{
/// <summary>
/// Initializes a new instance of the <see cref="PlayingAudioLogEventArgs" /> class.
/// </summary>
/// <param name="player">
/// <inheritdoc cref="Player" />
/// </param>
/// <param name="isAllowed">
/// <inheritdoc cref="IsAllowed" />
/// </param>
public PlayingAudioLogEventArgs(Player player, bool isAllowed = true)
{
Player = player;
IsAllowed = isAllowed;
}

/// <summary>
/// Gets or sets a value indicating whether or not the audio will start.
/// </summary>
public bool IsAllowed { get; set; }

/// <summary>
/// Gets the player who started the AudioLog.
/// </summary>
public Player Player { get; }
}
}
11 changes: 11 additions & 0 deletions EXILED/Exiled.Events/Handlers/Player.cs
Original file line number Diff line number Diff line change
Expand Up @@ -208,6 +208,11 @@ public class Player
/// </summary>
public static Event<DroppingNothingEventArgs> DroppingNothing { get; set; } = new();

/// <summary>
/// Invoked before playing an AudioLog.
/// </summary>
public static Event<PlayingAudioLogEventArgs> PlayingAudioLog { get; set; } = new();

/// <summary>
/// Invoked before picking up an <see cref="API.Features.Items.Item"/>.
/// </summary>
Expand Down Expand Up @@ -691,6 +696,12 @@ public class Player
/// <param name="ev">The <see cref="DroppingNothingEventArgs"/> instance.</param>
public static void OnDroppingNothing(DroppingNothingEventArgs ev) => DroppingNothing.InvokeSafely(ev);

/// <summary>
/// Called before a <see cref="API.Features.Player"/> plays an AudioLog.
/// </summary>
/// <param name="ev">The <see cref="PlayingAudioLogEventArgs"/> instance.</param>
public static void OnPlayingAudioLog(PlayingAudioLogEventArgs ev) => PlayingAudioLog.InvokeSafely(ev);

/// <summary>
/// Called before a <see cref="API.Features.Player"/> picks up an item.
/// </summary>
Expand Down
68 changes: 68 additions & 0 deletions EXILED/Exiled.Events/Patches/Events/Player/PlayingAudioLog.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
// -----------------------------------------------------------------------
// <copyright file="PlayingAudioLog.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 MapGeneration.Spawnables;

using static HarmonyLib.AccessTools;

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

Label retLabel = generator.DefineLabel();

newInstructions.InsertRange(
0,
new CodeInstruction[]
{
// Player player = Player.Get(ReferenceHub);
new(OpCodes.Ldarg_1),
new(OpCodes.Call, Method(typeof(Player), nameof(Player.Get), new[] { typeof(ReferenceHub) })),

// true
new(OpCodes.Ldc_I4_1),

// PlayingAudioLogEventArgs ev = new(Player, bool)
new(OpCodes.Newobj, GetDeclaredConstructors(typeof(PlayingAudioLogEventArgs))[0]),
new(OpCodes.Dup),

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

// if (!ev.IsAllowed)
// return;
new(OpCodes.Callvirt, PropertyGetter(typeof(PlayingAudioLogEventArgs), nameof(PlayingAudioLogEventArgs.IsAllowed))),
new(OpCodes.Brfalse, retLabel),
});

newInstructions[newInstructions.Count - 1].labels.Add(retLabel);

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

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