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

fix: fix announcing ntf/chaos entrance events #314

Merged
merged 2 commits into from
Dec 17, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@

namespace Exiled.Events.EventArgs.Map
{
using System.Text;

using Exiled.API.Features.Waves;
using Exiled.Events.EventArgs.Interfaces;
using Respawning.Announcements;
Expand All @@ -20,19 +22,25 @@ public class AnnouncingChaosEntranceEventArgs : IDeniableEvent
/// Initializes a new instance of the <see cref="AnnouncingChaosEntranceEventArgs"/> class.
/// </summary>
/// <param name="announcement"><inheritdoc cref="Wave"/></param>
/// <param name="isAllowed"><inheritdoc cref="IsAllowed"/></param>
public AnnouncingChaosEntranceEventArgs(WaveAnnouncementBase announcement, bool isAllowed = true)
/// <param name="builder"><inheritdoc cref="Words"/></param>
public AnnouncingChaosEntranceEventArgs(WaveAnnouncementBase announcement, StringBuilder builder)
{
Wave = TimedWave.GetTimedWaves().Find(x => x.Announcement == announcement);
IsAllowed = isAllowed;
Words = builder;
}

/// <summary>
/// Gets the entering wave.
/// </summary>
public TimedWave Wave { get; }

/// <summary>
/// Gets the <see cref="StringBuilder"/> of the words that C.A.S.S.I.E will say.
/// <remarks>It doesn't affect the subtitle part that will be sent to the client.</remarks>
/// </summary>
public StringBuilder Words { get; }

/// <inheritdoc/>
public bool IsAllowed { get; set; }
public bool IsAllowed { get; set; } = true;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,9 @@

namespace Exiled.Events.EventArgs.Map
{
using Exiled.API.Features.Waves;
using Interfaces;
using Respawning.Announcements;

/// <summary>
/// Contains all information before C.A.S.S.I.E announces the NTF entrance.
Expand All @@ -17,26 +19,23 @@ public class AnnouncingNtfEntranceEventArgs : IDeniableEvent
/// <summary>
/// Initializes a new instance of the <see cref="AnnouncingNtfEntranceEventArgs" /> class.
/// </summary>
/// <param name="scpsLeft">
/// <inheritdoc cref="ScpsLeft" />
/// </param>
/// <param name="unitName">
/// <inheritdoc cref="UnitName" />
/// </param>
/// <param name="unitNumber">
/// <inheritdoc cref="UnitNumber" />
/// </param>
/// <param name="isAllowed">
/// <inheritdoc cref="IsAllowed" />
/// </param>
public AnnouncingNtfEntranceEventArgs(int scpsLeft, string unitName, int unitNumber, bool isAllowed = true)
/// <param name="announcement"><inheritdoc cref="Wave"/></param>
/// <param name="scpsLeft"><inheritdoc cref="ScpsLeft"/></param>
/// <param name="unitName"><inheritdoc cref="UnitName"/></param>
/// <param name="unitNumber"><inheritdoc cref="UnitNumber"/></param>
public AnnouncingNtfEntranceEventArgs(WaveAnnouncementBase announcement, int scpsLeft, string unitName, int unitNumber)
{
Wave = TimedWave.GetTimedWaves().Find(x => x.Announcement == announcement);
ScpsLeft = scpsLeft;
UnitName = unitName;
UnitNumber = unitNumber;
IsAllowed = isAllowed;
}

/// <summary>
/// Gets the entering wave.
/// </summary>
public TimedWave Wave { get; }

/// <summary>
/// Gets or sets the number of SCPs left.
/// </summary>
Expand All @@ -55,6 +54,6 @@ public AnnouncingNtfEntranceEventArgs(int scpsLeft, string unitName, int unitNum
/// <summary>
/// Gets or sets a value indicating whether the NTF spawn will be announced by C.A.S.S.I.E.
/// </summary>
public bool IsAllowed { get; set; } // TODO possibly not working
public bool IsAllowed { get; set; } = true;
}
}
41 changes: 33 additions & 8 deletions EXILED/Exiled.Events/Patches/Events/Map/AnnouncingChaosEntrance.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,9 @@
namespace Exiled.Events.Patches.Events.Map
{
using System.Collections.Generic;
using System.Reflection;
using System.Reflection.Emit;
using System.Text;

using Exiled.API.Features.Pools;
using Exiled.Events.Attributes;
Expand All @@ -23,32 +25,55 @@ namespace Exiled.Events.Patches.Events.Map
/// to add <see cref="Handlers.Map.AnnouncingChaosEntrance"/> event.
/// </summary>
[EventPatch(typeof(Handlers.Map), nameof(Handlers.Map.AnnouncingChaosEntrance))]
[HarmonyPatch(typeof(ChaosWaveAnnouncement), nameof(ChaosWaveAnnouncement.CreateAnnouncementString))]
[HarmonyPatch(typeof(ChaosMiniwaveAnnouncement), nameof(ChaosMiniwaveAnnouncement.CreateAnnouncementString))]
[HarmonyPatch]
internal static class AnnouncingChaosEntrance
{
private static IEnumerable<MethodBase> TargetMethods()
{
yield return Method(typeof(ChaosWaveAnnouncement), nameof(ChaosWaveAnnouncement.CreateAnnouncementString));
yield return Method(typeof(ChaosMiniwaveAnnouncement), nameof(ChaosMiniwaveAnnouncement.CreateAnnouncementString));
}

private static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstruction> instruction, ILGenerator generator)
{
List<CodeInstruction> newInstructions = ListPool<CodeInstruction>.Pool.Get(instruction);

Label returnLabel = generator.DefineLabel();
Label continueLabel = generator.DefineLabel();

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

int index = newInstructions.FindIndex(i => i.opcode == OpCodes.Ldloca_S);

newInstructions.InsertRange(0, new CodeInstruction[]
newInstructions.InsertRange(index, new[]
{
// WaveAnnouncementBase
new(OpCodes.Ldarg_0),

new(OpCodes.Ldc_I4_1),
// builder
new(OpCodes.Ldarg_1),

// new AnnouncingChaosEntranceEventArgs(WaveAnnouncementBase, StringBuilder)
new(OpCodes.Newobj, GetDeclaredConstructors(typeof(AnnouncingChaosEntranceEventArgs))[0]),
new(OpCodes.Dup),
new(OpCodes.Dup),
new(OpCodes.Stloc_S, ev.LocalIndex),

// Map.OnAnnouncingChaosEntrance(ev)
new(OpCodes.Call, Method(typeof(Handlers.Map), nameof(Handlers.Map.OnAnnouncingChaosEntrance))),

// if (!ev.IsAllowed)
// builder.Clear();
// return;
new(OpCodes.Callvirt, PropertyGetter(typeof(AnnouncingChaosEntranceEventArgs), nameof(AnnouncingChaosEntranceEventArgs.IsAllowed))),
new(OpCodes.Brfalse_S, returnLabel),
});
new(OpCodes.Brtrue_S, continueLabel),

newInstructions[newInstructions.Count - 1].labels.Add(returnLabel);
new(OpCodes.Ldarg_1),
new(OpCodes.Callvirt, Method(typeof(StringBuilder), nameof(StringBuilder.Clear))),
new(OpCodes.Pop),
new(OpCodes.Ret),

new CodeInstruction(OpCodes.Nop).WithLabels(continueLabel),
});

for (int z = 0; z < newInstructions.Count; z++)
yield return newInstructions[z];
Expand Down
34 changes: 14 additions & 20 deletions EXILED/Exiled.Events/Patches/Events/Map/AnnouncingNtfEntrance.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
namespace Exiled.Events.Patches.Events.Map
{
using System.Collections.Generic;
using System.Reflection;
using System.Reflection.Emit;
using System.Text.RegularExpressions;

Expand All @@ -26,10 +27,15 @@ namespace Exiled.Events.Patches.Events.Map
/// Adds the <see cref="Map.AnnouncingNtfEntrance" /> event.
/// </summary>
[EventPatch(typeof(Map), nameof(Map.AnnouncingNtfEntrance))]
[HarmonyPatch(typeof(NtfWaveAnnouncement), nameof(NtfWaveAnnouncement.CreateAnnouncementString))]
[HarmonyPatch(typeof(NtfMiniwaveAnnouncement), nameof(NtfMiniwaveAnnouncement.CreateAnnouncementString))]
[HarmonyPatch]
internal static class AnnouncingNtfEntrance
{
private static IEnumerable<MethodBase> TargetMethods()
{
yield return Method(typeof(NtfWaveAnnouncement), nameof(NtfWaveAnnouncement.CreateAnnouncementString));
yield return Method(typeof(NtfMiniwaveAnnouncement), nameof(NtfMiniwaveAnnouncement.CreateAnnouncementString));
}

private static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstruction> instructions, ILGenerator generator)
{
List<CodeInstruction> newInstructions = ListPool<CodeInstruction>.Pool.Get(instructions);
Expand All @@ -42,23 +48,13 @@ private static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstructi
int offset = 1;
int index = newInstructions.FindIndex(instruction => instruction.opcode == OpCodes.Stloc_3) + offset;

// int scpsLeft = ReferenceHub.GetAllHubs().Values.Count(x => x.characterClassManager.CurRole.team == Team.SCP && x.characterClassManager.CurClass != RoleTypeId.Scp0492);
// string unitNameClear = Regex.Replace(unitName, "<[^>]*?>", string.Empty);
// string[] unitInformation = unitNameClear.Split('-');
//
// AnnouncingNtfEntranceEventArgs ev = new(scpsLeft, unitInformation[0], int.Parse(unitInformation[1]));
// Map.OnAnnouncingNtfEntrance(ev);
//
// if (!ev.IsAllowed)
// return;
//
// unitName = $"{ev.UnitName}-{ev.UnitNumber};
// cassieUnitName = this.GetCassieUnitName(unitName);
// scpsLeft = ev.ScpsLeft;
newInstructions.InsertRange(
index,
new CodeInstruction[]
{
// WaveAnnouncementBase
new(OpCodes.Ldarg_0),

// int scpsLeft = ReferenceHub.GetAllHubs().Values.Count(x => x.characterClassManager.CurRole.team == Team.SCP && x.characterClassManager.CurClass != RoleTypeId.Scp0492);
new(OpCodes.Ldloc_3),

Expand Down Expand Up @@ -86,7 +82,6 @@ private static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstructi
new(OpCodes.Ldc_I4_1),
new(OpCodes.Ldelem_Ref),
new(OpCodes.Call, Method(typeof(int), nameof(int.Parse), new[] { typeof(string) })),
new(OpCodes.Ldc_I4_1),
new(OpCodes.Newobj, GetDeclaredConstructors(typeof(AnnouncingNtfEntranceEventArgs))[0]),
new(OpCodes.Dup),
new(OpCodes.Dup),
Expand All @@ -98,7 +93,9 @@ private static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstructi
new(OpCodes.Callvirt, PropertyGetter(typeof(AnnouncingNtfEntranceEventArgs), nameof(AnnouncingNtfEntranceEventArgs.IsAllowed))),
new(OpCodes.Brfalse_S, ret),

// unitName = $"{ev.UnitName}-{ev.UnitNumber};
// lastGeneratedName = $"{ev.UnitName}-{ev.UnitNumber}";
// cassie = rule.TranslateToCassie(lastGeneratedName);
new(OpCodes.Ldloc_0),
new(OpCodes.Ldstr, "{0}-{1}"),
new(OpCodes.Ldloc_S, ev.LocalIndex),
new(OpCodes.Callvirt, PropertyGetter(typeof(AnnouncingNtfEntranceEventArgs), nameof(AnnouncingNtfEntranceEventArgs.UnitName))),
Expand All @@ -108,9 +105,6 @@ private static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstructi
new(OpCodes.Call, Method(typeof(string), nameof(string.Format), new[] { typeof(string), typeof(object), typeof(object) })),
new(OpCodes.Dup),
new(OpCodes.Stloc_1),

// cassieUnitName = this.TranslateToCassie(unitName);
new(OpCodes.Ldloc_0),
new(OpCodes.Callvirt, Method(typeof(UnitNamingRule), nameof(UnitNamingRule.TranslateToCassie))),
new(OpCodes.Stloc_2),

Expand Down
57 changes: 57 additions & 0 deletions EXILED/Exiled.Events/Patches/Events/Map/AnnouncingTeamEntrance.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
// -----------------------------------------------------------------------
// <copyright file="AnnouncingTeamEntrance.cs" company="ExMod Team">
// Copyright (c) ExMod Team. All rights reserved.
// Licensed under the CC BY-SA 3.0 license.
// </copyright>
// -----------------------------------------------------------------------

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

using Exiled.API.Features.Pools;
using Exiled.Events.Attributes;
using Exiled.Events.EventArgs.Map;
using HarmonyLib;
using Respawning.Announcements;

using static HarmonyLib.AccessTools;

/// <summary>
/// Patches <see cref="WaveAnnouncementBase.PlayAnnouncement"/> to prevent cassie from playing empty string.
/// </summary>
[EventPatch(typeof(Handlers.Map), nameof(Handlers.Map.AnnouncingNtfEntrance))]
[EventPatch(typeof(Handlers.Map), nameof(Handlers.Map.AnnouncingChaosEntrance))]
[HarmonyPatch(typeof(WaveAnnouncementBase), nameof(WaveAnnouncementBase.PlayAnnouncement))]
internal static class AnnouncingTeamEntrance
{
private static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstruction> instruction, ILGenerator generator)
{
List<CodeInstruction> newInstructions = ListPool<CodeInstruction>.Pool.Get(instruction);

Label returnLabel = generator.DefineLabel();

int index = newInstructions.FindLastIndex(i => i.opcode == OpCodes.Ldsfld);

newInstructions.InsertRange(index, new CodeInstruction[]
{
// if (stringReturn == "")
// return;
new(OpCodes.Ldloc_S, 4),
new(OpCodes.Ldstr, string.Empty),
new(OpCodes.Ceq),
new(OpCodes.Brtrue_S, returnLabel),
});

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

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

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