diff --git a/EXILED/Exiled.API/Extensions/MirrorExtensions.cs b/EXILED/Exiled.API/Extensions/MirrorExtensions.cs
index 3ba47fd9a8..9fb9e47409 100644
--- a/EXILED/Exiled.API/Extensions/MirrorExtensions.cs
+++ b/EXILED/Exiled.API/Extensions/MirrorExtensions.cs
@@ -476,8 +476,8 @@ public static void SendFakeEffectTo(this Player effectOwner, Player target, Effe
///
/// The player who will become not spectatable.
/// The viewer who will see this change.
- /// The faked value.
- public static void SetFakeSpectatable(Player target, Player viewer, bool value) => viewer.Connection.Send(new SpectatableVisibilityMessages.SpectatableVisibilityMessage(target.ReferenceHub, value));
+ /// Determine if the player will be force hidden.
+ public static void SetFakeSpectatable(Player target, Player viewer, bool isforceHidden) => viewer.Connection.Send(new SpectatableVisibilityMessages.SpectatableVisibilityMessage(target.ReferenceHub, isforceHidden));
///
/// Makes the server resend a message to all clients updating a keycards details to current values.
diff --git a/EXILED/Exiled.Events/EventArgs/Player/ReceivingVoiceMessageEventArgs.cs b/EXILED/Exiled.Events/EventArgs/Player/ReceivingVoiceMessageEventArgs.cs
new file mode 100644
index 0000000000..22fea56160
--- /dev/null
+++ b/EXILED/Exiled.Events/EventArgs/Player/ReceivingVoiceMessageEventArgs.cs
@@ -0,0 +1,68 @@
+// -----------------------------------------------------------------------
+//
+// Copyright (c) ExMod Team. All rights reserved.
+// Licensed under the CC BY-SA 3.0 license.
+//
+// -----------------------------------------------------------------------using System;
+
+namespace Exiled.Events.EventArgs.Player
+{
+ using Exiled.API.Features;
+ using Exiled.Events.EventArgs.Interfaces;
+ using PlayerRoles.Voice;
+ using VoiceChat.Networking;
+
+ using IVoiceRole = API.Features.Roles.IVoiceRole;
+
+ ///
+ /// Contains all information before player receiving a voice message.
+ ///
+ public class ReceivingVoiceMessageEventArgs : IPlayerEvent, IDeniableEvent
+ {
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ /// The voice message being sent.
+ /// The player receiving the voice message.
+ /// The player sending the voice message.
+ /// A value indicating whether the player is allowed to receive the voice message.
+ public ReceivingVoiceMessageEventArgs(VoiceMessage voiceMessage, Player receiver, Player sender, bool isAllowed)
+ {
+ Player = receiver;
+ VoiceMessage = voiceMessage;
+ Sender = sender;
+
+ if (Sender.Role is IVoiceRole iVR)
+ {
+ VoiceModule = iVR.VoiceModule;
+ }
+
+ IsAllowed = isAllowed;
+ }
+
+ ///
+ /// Gets the player receiving the voice message.
+ ///
+ public Player Player { get; }
+
+ ///
+ /// Gets the player sended the voice message.
+ ///
+ public Player Sender { get; }
+
+ ///
+ /// Gets or sets the 's .
+ ///
+ public VoiceMessage VoiceMessage { get; set; }
+
+ ///
+ /// Gets the 's .
+ ///
+ public VoiceModuleBase VoiceModule { get; }
+
+ ///
+ /// Gets or sets a value indicating whether the player can receive the voice message.
+ ///
+ public bool IsAllowed { get; set; }
+ }
+}
diff --git a/EXILED/Exiled.Events/EventArgs/Player/TransmittingEventArgs.cs b/EXILED/Exiled.Events/EventArgs/Player/TransmittingEventArgs.cs
index 96e1ffde45..5ccc41bb2a 100644
--- a/EXILED/Exiled.Events/EventArgs/Player/TransmittingEventArgs.cs
+++ b/EXILED/Exiled.Events/EventArgs/Player/TransmittingEventArgs.cs
@@ -12,6 +12,8 @@ namespace Exiled.Events.EventArgs.Player
using PlayerRoles.Voice;
+ using VoiceChat.Networking;
+
///
/// Contains all information regarding the player using the radio.
///
@@ -23,16 +25,18 @@ public class TransmittingEventArgs : IPlayerEvent, IDeniableEvent
///
///
///
- ///
- ///
+ ///
+ ///
///
///
///
///
- public TransmittingEventArgs(Player player, VoiceModuleBase voiceModule, bool isAllowed = true)
+ public TransmittingEventArgs(Player player, VoiceMessage voiceMessage, bool isAllowed)
{
Player = player;
- VoiceModule = voiceModule;
+ VoiceMessage = voiceMessage;
+ if (player.Role is IVoiceRole voiceRole)
+ VoiceModule = voiceRole.VoiceModule;
IsAllowed = isAllowed;
}
@@ -41,6 +45,11 @@ public TransmittingEventArgs(Player player, VoiceModuleBase voiceModule, bool is
///
public Player Player { get; }
+ ///
+ /// Gets or sets the 's .
+ ///
+ public VoiceMessage VoiceMessage { get; set; }
+
///
/// Gets the 's .
///
diff --git a/EXILED/Exiled.Events/EventArgs/Player/VoiceChattingEventArgs.cs b/EXILED/Exiled.Events/EventArgs/Player/VoiceChattingEventArgs.cs
index c67e7bb72f..b39cedc025 100644
--- a/EXILED/Exiled.Events/EventArgs/Player/VoiceChattingEventArgs.cs
+++ b/EXILED/Exiled.Events/EventArgs/Player/VoiceChattingEventArgs.cs
@@ -28,17 +28,15 @@ public class VoiceChattingEventArgs : IPlayerEvent, IDeniableEvent
///
///
///
- ///
- ///
- ///
///
///
///
- public VoiceChattingEventArgs(Player player, VoiceMessage voiceMessage, VoiceModuleBase voiceModule, bool isAllowed = true)
+ public VoiceChattingEventArgs(Player player, VoiceMessage voiceMessage, bool isAllowed)
{
Player = player;
VoiceMessage = voiceMessage;
- VoiceModule = voiceModule;
+ if (player.Role is IVoiceRole voiceRole)
+ VoiceModule = voiceRole.VoiceModule;
IsAllowed = isAllowed;
}
diff --git a/EXILED/Exiled.Events/Events.cs b/EXILED/Exiled.Events/Events.cs
index c941abd7ca..39fd4808b7 100644
--- a/EXILED/Exiled.Events/Events.cs
+++ b/EXILED/Exiled.Events/Events.cs
@@ -90,6 +90,8 @@ public override void OnEnabled()
ServerSpecificSettingsSync.ServerOnSettingValueReceived += SettingBase.OnSettingUpdated;
+ LabApi.Events.Handlers.PlayerEvents.SendingVoiceMessage += Handlers.Player.OnVoiceChatting;
+ LabApi.Events.Handlers.PlayerEvents.ReceivingVoiceMessage += Handlers.Player.OnReceivingVoiceMessage;
LabApi.Events.Handlers.PlayerEvents.ReloadingWeapon += Handlers.Player.OnReloadingWeapon;
LabApi.Events.Handlers.PlayerEvents.UnloadingWeapon += Handlers.Player.OnUnloadingWeapon;
@@ -133,6 +135,8 @@ public override void OnDisabled()
ServerSpecificSettingsSync.ServerOnSettingValueReceived -= SettingBase.OnSettingUpdated;
+ LabApi.Events.Handlers.PlayerEvents.SendingVoiceMessage -= Handlers.Player.OnVoiceChatting;
+ LabApi.Events.Handlers.PlayerEvents.ReceivingVoiceMessage -= Handlers.Player.OnReceivingVoiceMessage;
LabApi.Events.Handlers.PlayerEvents.ReloadingWeapon -= Handlers.Player.OnReloadingWeapon;
LabApi.Events.Handlers.PlayerEvents.UnloadingWeapon -= Handlers.Player.OnUnloadingWeapon;
diff --git a/EXILED/Exiled.Events/Handlers/Player.cs b/EXILED/Exiled.Events/Handlers/Player.cs
index 998b54f813..11a890b5bf 100644
--- a/EXILED/Exiled.Events/Handlers/Player.cs
+++ b/EXILED/Exiled.Events/Handlers/Player.cs
@@ -470,6 +470,11 @@ public class Player
///
public static Event VoiceChatting { get; set; } = new();
+ ///
+ /// Invoked before a receiving a voice message.
+ ///
+ public static Event ReceivingVoiceMessage { get; set; } = new();
+
///
/// Invoked before a makes noise.
///
@@ -1042,8 +1047,37 @@ public static void OnUnloadingWeapon(PlayerUnloadingWeaponEventArgs ev)
///
/// Invoked after a presses the voicechat key.
///
- /// The instance.
- public static void OnVoiceChatting(VoiceChattingEventArgs ev) => VoiceChatting.InvokeSafely(ev);
+ /// The instance.
+ public static void OnVoiceChatting(PlayerSendingVoiceMessageEventArgs ev)
+ {
+ VoiceChattingEventArgs evVoiceChatting = new(ev.Player, ev.Message, ev.IsAllowed);
+ VoiceChatting.InvokeSafely(evVoiceChatting);
+
+ ev.IsAllowed = evVoiceChatting.IsAllowed;
+ ev.Message = evVoiceChatting.VoiceMessage;
+
+ if(ev.Message.Channel == VoiceChat.VoiceChatChannel.Radio)
+ {
+ TransmittingEventArgs evTransmitting = new(ev.Player, ev.Message, ev.IsAllowed);
+ OnTransmitting(evTransmitting);
+
+ ev.Message = evTransmitting.VoiceMessage;
+ ev.IsAllowed = evTransmitting.IsAllowed;
+ }
+ }
+
+ ///
+ /// Invoked before a receiving a voice message.
+ ///
+ /// The instance.
+ public static void OnReceivingVoiceMessage(PlayerReceivingVoiceMessageEventArgs ev)
+ {
+ ReceivingVoiceMessageEventArgs evReceivingVoiceMessage = new(ev.Message, ev.Player, ev.Sender, ev.IsAllowed);
+ ReceivingVoiceMessage.InvokeSafely(evReceivingVoiceMessage);
+
+ ev.IsAllowed = evReceivingVoiceMessage.IsAllowed;
+ ev.Message = evReceivingVoiceMessage.VoiceMessage;
+ }
///
/// Called before a makes noise.
diff --git a/EXILED/Exiled.Events/Patches/Events/Player/VoiceChatting.cs b/EXILED/Exiled.Events/Patches/Events/Player/VoiceChatting.cs
deleted file mode 100644
index a6d49a70f9..0000000000
--- a/EXILED/Exiled.Events/Patches/Events/Player/VoiceChatting.cs
+++ /dev/null
@@ -1,150 +0,0 @@
-// -----------------------------------------------------------------------
-//
-// Copyright (c) ExMod Team. All rights reserved.
-// Licensed under the CC BY-SA 3.0 license.
-//
-// -----------------------------------------------------------------------
-
-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.Attributes;
- using Exiled.Events.EventArgs.Player;
-
- using HarmonyLib;
-
- using Mirror;
-
- using PlayerRoles.Voice;
-
- using VoiceChat;
- using VoiceChat.Networking;
-
- using static HarmonyLib.AccessTools;
-
- ///
- /// Patches .
- /// Adds the event.
- /// Adds the event.
- ///
- [EventPatch(typeof(Handlers.Player), nameof(Handlers.Player.VoiceChatting))]
- [EventPatch(typeof(Handlers.Player), nameof(Handlers.Player.Transmitting))]
- [HarmonyPatch(typeof(VoiceTransceiver), nameof(VoiceTransceiver.ServerReceiveMessage))]
- internal static class VoiceChatting
- {
- private static IEnumerable Transpiler(IEnumerable instructions, ILGenerator generator)
- {
- List newInstructions = ListPool.Pool.Get(instructions);
-
- Label retLabel = generator.DefineLabel();
- Label isMutedLabel = generator.DefineLabel();
- Label skipLabel = generator.DefineLabel();
- List