2022-10-05 16:29:31 -04:00
|
|
|
|
using Microsoft.Extensions.Logging;
|
|
|
|
|
using SharedLibraryCore;
|
|
|
|
|
using SharedLibraryCore.Commands;
|
2022-09-08 16:03:38 -04:00
|
|
|
|
using SharedLibraryCore.Database.Models;
|
|
|
|
|
using SharedLibraryCore.Helpers;
|
2022-08-26 13:09:33 -04:00
|
|
|
|
using SharedLibraryCore.Interfaces;
|
2022-10-05 16:29:31 -04:00
|
|
|
|
using JsonSerializer = System.Text.Json.JsonSerializer;
|
2022-08-26 13:09:33 -04:00
|
|
|
|
|
|
|
|
|
namespace Mute;
|
|
|
|
|
|
|
|
|
|
public class Plugin : IPlugin
|
|
|
|
|
{
|
2022-10-05 16:29:31 -04:00
|
|
|
|
public string Name => "Mute";
|
|
|
|
|
public float Version => (float) Utilities.GetVersionAsDouble();
|
|
|
|
|
public string Author => "Amos";
|
|
|
|
|
|
|
|
|
|
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"};
|
2022-09-08 16:03:38 -04:00
|
|
|
|
private readonly IInteractionRegistration _interactionRegistration;
|
|
|
|
|
private static readonly string MuteInteraction = nameof(MuteInteraction);
|
|
|
|
|
|
2022-10-05 16:29:31 -04:00
|
|
|
|
public Plugin(IMetaServiceV2 metaService, IInteractionRegistration interactionRegistration,
|
|
|
|
|
ITranslationLookup translationLookup, ILogger<Plugin> logger)
|
2022-08-26 13:09:33 -04:00
|
|
|
|
{
|
2022-09-08 16:03:38 -04:00
|
|
|
|
_interactionRegistration = interactionRegistration;
|
2022-10-05 16:29:31 -04:00
|
|
|
|
MuteManager = new MuteManager(metaService, translationLookup, logger);
|
2022-08-26 13:09:33 -04:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public async Task OnEventAsync(GameEvent gameEvent, Server server)
|
|
|
|
|
{
|
|
|
|
|
if (!SupportedGames.Contains(server.GameName)) return;
|
|
|
|
|
|
2022-10-05 16:29:31 -04:00
|
|
|
|
|
2022-08-26 13:09:33 -04:00
|
|
|
|
switch (gameEvent.Type)
|
|
|
|
|
{
|
2022-10-05 16:29:31 -04:00
|
|
|
|
case GameEvent.EventType.Command:
|
|
|
|
|
|
|
|
|
|
break;
|
2022-08-26 13:09:33 -04:00
|
|
|
|
case GameEvent.EventType.Join:
|
2022-10-05 16:29:31 -04:00
|
|
|
|
// Check if user has any meta set, else ignore (unmuted)
|
|
|
|
|
var muteMetaJoin = await MuteManager.GetCurrentMuteState(gameEvent.Origin);
|
|
|
|
|
|
|
|
|
|
switch (muteMetaJoin.MuteState)
|
2022-08-26 13:09:33 -04:00
|
|
|
|
{
|
|
|
|
|
case MuteState.Muted:
|
2022-10-05 16:29:31 -04:00
|
|
|
|
// 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));
|
2022-08-26 13:09:33 -04:00
|
|
|
|
break;
|
|
|
|
|
case MuteState.Unmuting:
|
2022-10-05 16:29:31 -04:00
|
|
|
|
// 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));
|
2022-08-26 13:09:33 -04:00
|
|
|
|
break;
|
2022-10-05 16:29:31 -04:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
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"]);
|
|
|
|
|
}
|
|
|
|
|
|
2022-08-26 13:09:33 -04:00
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public Task OnLoadAsync(IManager manager)
|
|
|
|
|
{
|
2022-10-05 16:29:31 -04:00
|
|
|
|
Manager = manager;
|
|
|
|
|
|
|
|
|
|
manager.CommandInterceptors.Add(gameEvent =>
|
|
|
|
|
{
|
|
|
|
|
if (gameEvent.Extra is not Command command) return true;
|
|
|
|
|
return !DisabledCommands.Contains(command.GetType().Name) && !command.IsBroadcast;
|
|
|
|
|
});
|
|
|
|
|
|
2022-09-08 16:03:38 -04:00
|
|
|
|
_interactionRegistration.RegisterInteraction(MuteInteraction, async (clientId, game, token) =>
|
|
|
|
|
{
|
2022-10-05 16:29:31 -04:00
|
|
|
|
if (!clientId.HasValue || game.HasValue && !SupportedGames.Contains((Server.Game) game.Value))
|
2022-09-08 16:03:38 -04:00
|
|
|
|
{
|
|
|
|
|
return null;
|
|
|
|
|
}
|
|
|
|
|
|
2022-10-05 16:29:31 -04:00
|
|
|
|
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);
|
2022-09-08 16:03:38 -04:00
|
|
|
|
|
2022-10-05 16:29:31 -04:00
|
|
|
|
var clientMuteMetaState = (await MuteManager.GetCurrentMuteState(new EFClient {ClientId = clientId.Value}))
|
|
|
|
|
.MuteState;
|
|
|
|
|
|
|
|
|
|
return clientMuteMetaState is MuteState.Unmuted or MuteState.Unmuting
|
2022-09-08 16:03:38 -04:00
|
|
|
|
? new InteractionData
|
|
|
|
|
{
|
|
|
|
|
EntityId = clientId,
|
|
|
|
|
Name = Utilities.CurrentLocalization.LocalizationIndex["WEBFRONT_PROFILE_CONTEXT_MENU_ACTION_MUTE"],
|
|
|
|
|
DisplayMeta = "oi-volume-off",
|
|
|
|
|
ActionPath = "DynamicAction",
|
|
|
|
|
ActionMeta = new()
|
|
|
|
|
{
|
2022-10-05 16:29:31 -04:00
|
|
|
|
{"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()}
|
2022-09-08 16:03:38 -04:00
|
|
|
|
},
|
|
|
|
|
MinimumPermission = Data.Models.Client.EFClient.Permission.Moderator,
|
|
|
|
|
Source = Name
|
|
|
|
|
}
|
|
|
|
|
: new InteractionData
|
|
|
|
|
{
|
|
|
|
|
EntityId = clientId,
|
2022-10-05 16:29:31 -04:00
|
|
|
|
Name = Utilities.CurrentLocalization.LocalizationIndex[
|
|
|
|
|
"WEBFRONT_PROFILE_CONTEXT_MENU_ACTION_UNMUTE"],
|
2022-09-08 16:03:38 -04:00
|
|
|
|
DisplayMeta = "oi-volume-high",
|
|
|
|
|
ActionPath = "DynamicAction",
|
|
|
|
|
ActionMeta = new()
|
|
|
|
|
{
|
2022-10-05 16:29:31 -04:00
|
|
|
|
{"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()}
|
2022-09-08 16:03:38 -04:00
|
|
|
|
},
|
|
|
|
|
MinimumPermission = Data.Models.Client.EFClient.Permission.Moderator,
|
|
|
|
|
Source = Name
|
|
|
|
|
};
|
|
|
|
|
});
|
2022-08-26 13:09:33 -04:00
|
|
|
|
return Task.CompletedTask;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public Task OnUnloadAsync()
|
|
|
|
|
{
|
2022-09-08 16:03:38 -04:00
|
|
|
|
_interactionRegistration.UnregisterInteraction(MuteInteraction);
|
2022-08-26 13:09:33 -04:00
|
|
|
|
return Task.CompletedTask;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public Task OnTickAsync(Server server)
|
|
|
|
|
{
|
|
|
|
|
return Task.CompletedTask;
|
|
|
|
|
}
|
|
|
|
|
}
|