Skip to content

Commit

Permalink
Voicechatting (#1730)
Browse files Browse the repository at this point in the history
* Removed old voice chat patch from ChangingSpeakerStatusAndVoiceChatting.cs and created VoiceChatting.cs for use instead of VoiceModuleBase VoiceTransceiver.ServerReceiveMessage for get the actual message.

* Added comments.

* Removed breaking change

* Update VoiceChattingEventArgs.cs

---------

Co-authored-by: louis1706 <[email protected]>
  • Loading branch information
Monaldcry7788 and louis1706 authored May 15, 2023
1 parent 8eb01af commit b4ce6b1
Show file tree
Hide file tree
Showing 3 changed files with 121 additions and 35 deletions.
15 changes: 13 additions & 2 deletions Exiled.Events/EventArgs/Player/VoiceChattingEventArgs.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ namespace Exiled.Events.EventArgs.Player

using PlayerRoles.Voice;

using VoiceChat.Networking;

/// <summary>
/// Contains all information after a player presses the voicechat key.
/// </summary>
Expand All @@ -23,15 +25,19 @@ public class VoiceChattingEventArgs : IPlayerEvent, IDeniableEvent
/// <param name="player">
/// <inheritdoc cref="Player" />
/// </param>
/// <param name="voiceMessage">
/// <inheritdoc cref="VoiceMessage" />
/// </param>
/// <param name="voiceModule">
/// <inheritdoc cref="VoiceModule" />
/// </param>
/// <param name="isAllowed">
/// <inheritdoc cref="IsAllowed" />
/// </param>
public VoiceChattingEventArgs(Player player, VoiceModuleBase voiceModule, bool isAllowed = true)
public VoiceChattingEventArgs(Player player, VoiceMessage voiceMessage, VoiceModuleBase voiceModule, bool isAllowed = true)
{
Player = player;
VoiceMessage = voiceMessage;
VoiceModule = voiceModule;
IsAllowed = isAllowed;
}
Expand All @@ -41,6 +47,11 @@ public VoiceChattingEventArgs(Player player, VoiceModuleBase voiceModule, bool i
/// </summary>
public Player Player { get; }

/// <summary>
/// Gets or sets the <see cref="Player"/>'s <see cref="VoiceMessage" />.
/// </summary>
public VoiceMessage VoiceMessage { get; set; }

/// <summary>
/// Gets the <see cref="Player"/>'s <see cref="VoiceModuleBase" />.
/// </summary>
Expand All @@ -51,4 +62,4 @@ public VoiceChattingEventArgs(Player player, VoiceModuleBase voiceModule, bool i
/// </summary>
public bool IsAllowed { get; set; }
}
}
}
108 changes: 108 additions & 0 deletions Exiled.Events/Patches/Events/Player/VoiceChatting.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
// -----------------------------------------------------------------------
// <copyright file="VoiceChatting.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.Pools;
using API.Features.Roles;

using Exiled.Events.EventArgs.Player;

using HarmonyLib;

using Mirror;

using PlayerRoles.Voice;

using VoiceChat.Networking;

using static HarmonyLib.AccessTools;

/// <summary>
/// patches <see cref="VoiceTransceiver.ServerReceiveMessage(NetworkConnection, VoiceMessage)"/> to add the <see cref="Handlers.Player.VoiceChatting"/> event.
/// </summary>
[HarmonyPatch(typeof(VoiceTransceiver), nameof(VoiceTransceiver.ServerReceiveMessage))]
internal static class VoiceChatting
{
private static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstruction> instructions, ILGenerator generator)
{
List<CodeInstruction> newInstructions = ListPool<CodeInstruction>.Pool.Get(instructions);

Label retLabel = generator.DefineLabel();
Label voiceRoleLabel = generator.DefineLabel();

LocalBuilder ev = generator.DeclareLocal(typeof(VoiceChattingEventArgs));
LocalBuilder player = generator.DeclareLocal(typeof(API.Features.Player));
LocalBuilder voiceRole = generator.DeclareLocal(typeof(IVoiceRole));

newInstructions[0].labels.Add(voiceRoleLabel);

newInstructions.InsertRange(0, new CodeInstruction[]
{
// Player.Get(msg.Speaker);
new(OpCodes.Ldarg_1),
new(OpCodes.Ldfld, Field(typeof(VoiceMessage), nameof(VoiceMessage.Speaker))),
new(OpCodes.Call, Method(typeof(API.Features.Player), nameof(API.Features.Player.Get), new[] { typeof(ReferenceHub) })),
new(OpCodes.Dup),
new(OpCodes.Stloc_S, player.LocalIndex),

// if (player.Role.Base is not IVoiceRole voiceRole)
// ignore.
new(OpCodes.Callvirt, PropertyGetter(typeof(API.Features.Player), nameof(API.Features.Player.Role))),
new(OpCodes.Callvirt, PropertyGetter(typeof(Role), nameof(Role.Base))),
new(OpCodes.Isinst, typeof(IVoiceRole)),
new(OpCodes.Dup),
new(OpCodes.Stloc_S, voiceRole.LocalIndex),
new(OpCodes.Ldnull),
new(OpCodes.Cgt_Un),
new(OpCodes.Brfalse_S, voiceRoleLabel),

// Player.Get(msg.Speaker);
new(OpCodes.Ldloc_S, player.LocalIndex),

// msg
new(OpCodes.Ldarg_1),

// voiceModule.
new(OpCodes.Ldloc_S, voiceRole.LocalIndex),
new(OpCodes.Callvirt, PropertyGetter(typeof(IVoiceRole), nameof(IVoiceRole.VoiceModule))),

// true
new(OpCodes.Ldc_I4_1),

// VoiceChattingEventArgs ev = new(Player, VoiceMessage);
new(OpCodes.Newobj, GetDeclaredConstructors(typeof(VoiceChattingEventArgs))[0]),
new(OpCodes.Dup),
new(OpCodes.Dup),
new(OpCodes.Stloc_S, ev.LocalIndex),

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

// if (!ev.IsAllowed)
// return;
new(OpCodes.Callvirt, PropertyGetter(typeof(VoiceChattingEventArgs), nameof(VoiceChattingEventArgs.IsAllowed))),
new(OpCodes.Brfalse_S, retLabel),

// ev.VoiceMessage = msg;
new(OpCodes.Ldloc_S, ev.LocalIndex),
new(OpCodes.Callvirt, PropertyGetter(typeof(VoiceChattingEventArgs), nameof(VoiceChattingEventArgs.VoiceMessage))),
new(OpCodes.Stloc_1),
});

newInstructions[newInstructions.Count - 1].WithLabels(retLabel);

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

ListPool<CodeInstruction>.Pool.Return(newInstructions);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@ namespace Exiled.Events.Patches.Events.Scp079

using API.Features.Pools;

using Exiled.Events.EventArgs.Player;
using Exiled.Events.EventArgs.Scp079;
using Exiled.Events.Handlers;

Expand Down Expand Up @@ -45,13 +44,6 @@ private static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstructi

newInstructions[index].WithLabels(continueLabel);

// VoiceChattingEventArgs voiceChattingEv = new(Player.Get(this.Owner), this, true)
//
// Handlers.Player.OnVoiceChatting(voiceChattingEv)
//
// if (!voiceChattingEv.IsAllowed)
// return;
//
// if (base.CurrentChannel != VoiceChatChannel.Proximity)
// goto continueLabel;
//
Expand All @@ -64,31 +56,6 @@ private static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstructi
index,
new CodeInstruction[]
{
// Player.Get(this.Owner)
new(OpCodes.Ldarg_0),
new(OpCodes.Call, PropertyGetter(typeof(VoiceModuleBase), nameof(VoiceModuleBase.Owner))),
new(OpCodes.Call, Method(typeof(Player), nameof(Player.Get), new[] { typeof(ReferenceHub) })),
new(OpCodes.Dup),
new(OpCodes.Stloc_S, player.LocalIndex),

// this
new(OpCodes.Ldarg_0),

// true
new(OpCodes.Ldc_I4_1),

// VoiceChattingEventArgs voiceChattingEv = new(Player, VoiceModuleBase, bool)
new(OpCodes.Newobj, GetDeclaredConstructors(typeof(VoiceChattingEventArgs))[0]),
new(OpCodes.Dup),

// Handlers.Player.OnVoiceChatting(voiceChattingEv)
new(OpCodes.Call, Method(typeof(Handlers.Player), nameof(Handlers.Player.OnVoiceChatting))),

// if (!voiceChattingEv.IsAllowed)
// return;
new(OpCodes.Callvirt, PropertyGetter(typeof(VoiceChattingEventArgs), nameof(VoiceChattingEventArgs.IsAllowed))),
new(OpCodes.Brfalse_S, returnLabel),

// if (this.Role.RoleTypeId != RoleTypeId.Scp079)
// goto continueLabel;
new(OpCodes.Ldarg_0),
Expand Down

0 comments on commit b4ce6b1

Please sign in to comment.