1
0
mirror of https://github.com/RaidMax/IW4M-Admin.git synced 2025-06-10 15:20:48 -05:00

Added !unmute, !tempmute, !listmutes

Quick fix for PowerShell IE use

Makes date readable for target player

Resolved translation string inconsistencies

Minor code cleanups

Initial commit from review

Cleaned up code & amended a few checks

Comment typo

Fix infinite unmuting

Removed unnecessary checks (Unmuting an already unmuted player will not trigger MuteStateMeta creation (if already doesn't exist))
Resolved !listmutes showing expired mutes

Committing before refactor

Refactor from review

Removed reference to AdditionalProperty

Fix check for meta state when unmuting

Continued request solves main problem

Handle potential failed command execution

Missed CommandExecuted onJoin

Fix another PS Reference to Invoke-WebRequest

Fixes review issues & Cleaned up code
Adds support for Intercepting Commands via Plugin (Credit: @RaidMax)

Comparing

Revert formatting changes

Removing MuteList for Penalty
Added Mute, TempMute & Unmute Penalty

Fixed reference in Mute.csproj & Removed ListMutesCommand.cs
This commit is contained in:
Amos
2022-10-05 21:29:31 +01:00
committed by RaidMax
parent 89e6dbf49a
commit 2ec9332251
14 changed files with 468 additions and 94 deletions

View File

@ -1,47 +1,111 @@
using SharedLibraryCore;
using Microsoft.Extensions.Logging;
using SharedLibraryCore;
using SharedLibraryCore.Commands;
using SharedLibraryCore.Database.Models;
using SharedLibraryCore.Helpers;
using SharedLibraryCore.Interfaces;
using JsonSerializer = System.Text.Json.JsonSerializer;
namespace Mute;
public class Plugin : IPlugin
{
private readonly IInteractionRegistration _interactionRegistration;
private static readonly string MuteInteraction = nameof(MuteInteraction);
public Plugin(IMetaServiceV2 metaService, IInteractionRegistration interactionRegistration)
{
_interactionRegistration = interactionRegistration;
DataManager = new DataManager(metaService);
}
public string Name => "Mute";
public float Version => (float) Utilities.GetVersionAsDouble();
public string Author => "Amos";
public static string MuteKey = "IW4MMute";
public static DataManager DataManager;
public const string MuteKey = "IW4MMute";
public static MuteManager MuteManager { get; private set; } = null!;
public static IManager Manager { get; private set; } = null!;
public static readonly Server.Game[] SupportedGames = {Server.Game.IW4};
private static readonly string[] DisabledCommands = {nameof(PrivateMessageAdminsCommand), "PrivateMessageCommand"};
private readonly IInteractionRegistration _interactionRegistration;
private static readonly string MuteInteraction = nameof(MuteInteraction);
public Plugin(IMetaServiceV2 metaService, IInteractionRegistration interactionRegistration,
ITranslationLookup translationLookup, ILogger<Plugin> logger)
{
_interactionRegistration = interactionRegistration;
MuteManager = new MuteManager(metaService, translationLookup, logger);
}
public async Task OnEventAsync(GameEvent gameEvent, Server server)
{
if (!SupportedGames.Contains(server.GameName)) return;
switch (gameEvent.Type)
{
case GameEvent.EventType.Command:
break;
case GameEvent.EventType.Join:
switch (await DataManager.ReadPersistentData(gameEvent.Origin))
// Check if user has any meta set, else ignore (unmuted)
var muteMetaJoin = await MuteManager.GetCurrentMuteState(gameEvent.Origin);
switch (muteMetaJoin.MuteState)
{
case MuteState.Muted:
await server.ExecuteCommandAsync($"muteClient {gameEvent.Origin.ClientNumber}");
// Let the client know when their mute expires.
gameEvent.Origin.Tell(Utilities.CurrentLocalization
.LocalizationIndex["PLUGINS_MUTE_REMAINING_TIME"].FormatExt(
muteMetaJoin.Expiration is not null
? muteMetaJoin.Expiration.Value.HumanizeForCurrentCulture()
: Utilities.CurrentLocalization.LocalizationIndex["PLUGINS_MUTE_NEVER"],
muteMetaJoin.Reason));
break;
case MuteState.Unmuting:
await server.ExecuteCommandAsync($"unmute {gameEvent.Origin.ClientNumber}");
await DataManager.WritePersistentData(gameEvent.Origin, MuteState.Unmuted);
// Handle unmute of unmuted players.
await MuteManager.Unmute(server, Utilities.IW4MAdminClient(), gameEvent.Origin,
muteMetaJoin.Reason);
gameEvent.Origin.Tell(Utilities.CurrentLocalization
.LocalizationIndex["PLUGINS_MUTE_COMMANDS_UNMUTE_TARGET_UNMUTED"]
.FormatExt(muteMetaJoin.Reason));
break;
case MuteState.Unmuted:
}
break;
case GameEvent.EventType.Say:
var muteMetaSay = await MuteManager.GetCurrentMuteState(gameEvent.Origin);
switch (muteMetaSay.MuteState)
{
case MuteState.Muted:
// Let the client know when their mute expires.
gameEvent.Origin.Tell(Utilities.CurrentLocalization
.LocalizationIndex["PLUGINS_MUTE_REMAINING_TIME"].FormatExt(
muteMetaSay.Expiration is not null
? muteMetaSay.Expiration.Value.HumanizeForCurrentCulture()
: Utilities.CurrentLocalization.LocalizationIndex["PLUGINS_MUTE_NEVER"],
muteMetaSay.Reason));
break;
}
break;
case GameEvent.EventType.Update:
// Get correct EFClient object
var client = server.GetClientsAsList()
.FirstOrDefault(client => client.NetworkId == gameEvent.Origin.NetworkId);
if (client == null) break;
var muteMetaUpdate = await MuteManager.GetCurrentMuteState(client);
if (!muteMetaUpdate.CommandExecuted)
{
await MuteManager.PerformGameCommand(server, client, muteMetaUpdate);
}
switch (muteMetaUpdate.MuteState)
{
case MuteState.Muted:
// Handle unmute if expired.
if (MuteManager.IsExpiredMute(muteMetaUpdate))
{
await MuteManager.Unmute(server, Utilities.IW4MAdminClient(), client,
Utilities.CurrentLocalization.LocalizationIndex["PLUGINS_MUTE_EXPIRED"]);
client.Tell(
Utilities.CurrentLocalization.LocalizationIndex["PLUGINS_MUTE_TARGET_EXPIRED"]);
}
break;
}
@ -51,16 +115,30 @@ public class Plugin : IPlugin
public Task OnLoadAsync(IManager manager)
{
Manager = manager;
manager.CommandInterceptors.Add(gameEvent =>
{
if (gameEvent.Extra is not Command command) return true;
return !DisabledCommands.Contains(command.GetType().Name) && !command.IsBroadcast;
});
_interactionRegistration.RegisterInteraction(MuteInteraction, async (clientId, game, token) =>
{
if (!clientId.HasValue || game.HasValue && !SupportedGames.Contains((Server.Game)game.Value))
if (!clientId.HasValue || game.HasValue && !SupportedGames.Contains((Server.Game) game.Value))
{
return null;
}
var muteState = await DataManager.ReadPersistentData(new EFClient { ClientId = clientId.Value });
var reasonInput = new {Name = "Reason", Placeholder = "Reason", TargetId = clientId};
var durationInput = new {Name = "Length", Placeholder = "Length", TargetId = clientId};
var inputs = new[] {reasonInput, durationInput};
var inputsJson = JsonSerializer.Serialize(inputs);
return muteState is MuteState.Unmuted or MuteState.Unmuting
var clientMuteMetaState = (await MuteManager.GetCurrentMuteState(new EFClient {ClientId = clientId.Value}))
.MuteState;
return clientMuteMetaState is MuteState.Unmuted or MuteState.Unmuting
? new InteractionData
{
EntityId = clientId,
@ -69,11 +147,19 @@ public class Plugin : IPlugin
ActionPath = "DynamicAction",
ActionMeta = new()
{
{ "InteractionId", "command" },
{ "Data", $"mute @{clientId.Value}" },
{ "ActionButtonLabel", Utilities.CurrentLocalization.LocalizationIndex["WEBFRONT_PROFILE_CONTEXT_MENU_ACTION_MUTE"] },
{ "Name", Utilities.CurrentLocalization.LocalizationIndex["WEBFRONT_PROFILE_CONTEXT_MENU_ACTION_MUTE"] },
{ "ShouldRefresh", true.ToString() }
{"InteractionId", "command"},
{"Data", $"mute @{clientId.Value}"},
{"Outputs", $"{reasonInput.Name},{durationInput.Name}"},
{"Inputs", inputsJson},
{
"ActionButtonLabel",
Utilities.CurrentLocalization.LocalizationIndex["WEBFRONT_PROFILE_CONTEXT_MENU_ACTION_MUTE"]
},
{
"Name",
Utilities.CurrentLocalization.LocalizationIndex["WEBFRONT_PROFILE_CONTEXT_MENU_ACTION_MUTE"]
},
{"ShouldRefresh", true.ToString()}
},
MinimumPermission = Data.Models.Client.EFClient.Permission.Moderator,
Source = Name
@ -81,22 +167,32 @@ public class Plugin : IPlugin
: new InteractionData
{
EntityId = clientId,
Name = Utilities.CurrentLocalization.LocalizationIndex["WEBFRONT_PROFILE_CONTEXT_MENU_ACTION_UNMUTE"],
Name = Utilities.CurrentLocalization.LocalizationIndex[
"WEBFRONT_PROFILE_CONTEXT_MENU_ACTION_UNMUTE"],
DisplayMeta = "oi-volume-high",
ActionPath = "DynamicAction",
ActionMeta = new()
{
{ "InteractionId", "command" },
{ "Data", $"mute @{clientId.Value}" },
{ "ActionButtonLabel", Utilities.CurrentLocalization.LocalizationIndex["WEBFRONT_PROFILE_CONTEXT_MENU_ACTION_UNMUTE"] },
{ "Name", Utilities.CurrentLocalization.LocalizationIndex["WEBFRONT_PROFILE_CONTEXT_MENU_ACTION_UNMUTE"] },
{ "ShouldRefresh", true.ToString() }
{"InteractionId", "command"},
{"Data", $"mute @{clientId.Value}"},
{"Outputs", $"{reasonInput.Name},{durationInput.Name}"},
{"Inputs", inputsJson},
{
"ActionButtonLabel",
Utilities.CurrentLocalization.LocalizationIndex[
"WEBFRONT_PROFILE_CONTEXT_MENU_ACTION_UNMUTE"]
},
{
"Name",
Utilities.CurrentLocalization.LocalizationIndex[
"WEBFRONT_PROFILE_CONTEXT_MENU_ACTION_UNMUTE"]
},
{"ShouldRefresh", true.ToString()}
},
MinimumPermission = Data.Models.Client.EFClient.Permission.Moderator,
Source = Name
};
});
return Task.CompletedTask;
}