0.2.0: keep all chat, @ staff chat and SimpleAdmin's say commands too
wh_messages now holds every message with a channel (all, team, pm, staff, to_staff, css_say/asay/psay/csay/hsay/cssay) and NULL sender columns for the console. Seen by a catch-all listener added in Load, which CSS runs before CS2-SimpleAdmin's (added in OnAllPluginsLoaded), so gagged lines and @ chat are kept before SimpleAdmin stops or rewrites them. Replaces 001_CreateTables in place: drop wh_messages and wh_migrations first.
This commit is contained in:
parent
c414e8a770
commit
06823c2d47
5 changed files with 146 additions and 29 deletions
90
Whisper.cs
90
Whisper.cs
|
|
@ -15,8 +15,15 @@ using Microsoft.Extensions.Logging;
|
|||
namespace Whisper;
|
||||
|
||||
// Private messages between players: /pm <target> <message>, /r to reply, and /block, /blocklist,
|
||||
// /unblock. Lines use CS2-Tags' rank prefixes and colours from tags.json. Each message is kept in
|
||||
// CS2-SimpleAdmin's database (wh_messages) while History is on, and blocks in wh_blocks.
|
||||
// /unblock. Lines use CS2-Tags' rank prefixes and colours from tags.json. While History is on, every
|
||||
// message is kept in CS2-SimpleAdmin's database (wh_messages): private ones, all and team chat, @
|
||||
// staff chat and SimpleAdmin's say commands. Blocks are in wh_blocks.
|
||||
//
|
||||
// Chat is seen by a catch-all command listener added in Load. CSS runs catch-alls before any
|
||||
// per-command listener, in the order they were added, and stops at the first that returns Stop.
|
||||
// CS2-SimpleAdmin adds its own (which stops gagged players' chat and handles @) in
|
||||
// OnAllPluginsLoaded, after every plugin's Load, so this one always sees a line first. It only
|
||||
// looks, never blocks.
|
||||
//
|
||||
// Chat commands are caught in a say listener rather than left to CSS's chat triggers: for "!pm" the
|
||||
// game prints the whole line, message and all, to everyone before CSS runs the command. Stopping
|
||||
|
|
@ -27,7 +34,7 @@ namespace Whisper;
|
|||
public class Whisper : BasePlugin, IPluginConfig<WhisperConfig>
|
||||
{
|
||||
public override string ModuleName => "Whisper";
|
||||
public override string ModuleVersion => "0.1.0";
|
||||
public override string ModuleVersion => "0.2.0";
|
||||
public override string ModuleAuthor => "astra";
|
||||
public override string ModuleDescription => "Private messages between players";
|
||||
|
||||
|
|
@ -37,6 +44,10 @@ public class Whisper : BasePlugin, IPluginConfig<WhisperConfig>
|
|||
private static readonly HashSet<string> ChatCommands = new(StringComparer.OrdinalIgnoreCase)
|
||||
{ "pm", "w", "r", "block", "blocklist", "unblock" };
|
||||
|
||||
// SimpleAdmin's commands that send a message, logged under their own name as the channel.
|
||||
private static readonly HashSet<string> StaffCommands = new(StringComparer.OrdinalIgnoreCase)
|
||||
{ "css_say", "css_asay", "css_psay", "css_csay", "css_hsay", "css_cssay" };
|
||||
|
||||
// Targets that mean more than one player. A PM goes to one.
|
||||
private static readonly HashSet<string> GroupTargets = new(StringComparer.OrdinalIgnoreCase)
|
||||
{ "@all", "@t", "@ct", "@spec", "@alive", "@dead", "@bot", "@bots", "@human", "@humans", "@!me" };
|
||||
|
|
@ -69,6 +80,8 @@ public class Whisper : BasePlugin, IPluginConfig<WhisperConfig>
|
|||
_tags = new Tags(Path.Combine(Server.GameDirectory, "csgo", "addons", "counterstrikesharp", Config.TagsFile),
|
||||
message => Logger.LogWarning("{Message}", message));
|
||||
|
||||
// In Load, not OnAllPluginsLoaded: see the top of this file.
|
||||
AddCommandListener(null, OnAnyCommand, HookMode.Pre);
|
||||
AddCommandListener("say", OnSay, HookMode.Pre);
|
||||
AddCommandListener("say_team", OnSay, HookMode.Pre);
|
||||
RegisterEventHandler<EventPlayerConnectFull>(OnPlayerConnectFull);
|
||||
|
|
@ -200,13 +213,73 @@ public class Whisper : BasePlugin, IPluginConfig<WhisperConfig>
|
|||
|
||||
// --- Chat -----------------------------------------------------------------------
|
||||
|
||||
// Logs chat and staff messages as they're sent. Never blocks anything.
|
||||
private HookResult OnAnyCommand(CCSPlayerController? player, CommandInfo info)
|
||||
{
|
||||
if (!Config.History || _writer == null)
|
||||
return HookResult.Continue;
|
||||
var command = info.GetArg(0).ToLowerInvariant();
|
||||
|
||||
if (StaffCommands.Contains(command))
|
||||
{
|
||||
// Typed in console, RCON (the web panel too), or "!asay" in chat, which CSS runs as css_asay.
|
||||
var sender = player is { IsValid: true, IsBot: false } ? StateOf(player) : player == null ? PlayerState.Console : null;
|
||||
if (sender == null)
|
||||
return HookResult.Continue;
|
||||
var rest = info.ArgString;
|
||||
var target = command == "css_psay" ? NextToken(ref rest) : null;
|
||||
var message = rest.Trim();
|
||||
if (message.Length > 0)
|
||||
Log(command, sender, null, target, message, Result.Sent);
|
||||
return HookResult.Continue;
|
||||
}
|
||||
|
||||
if (command is not ("say" or "say_team") || player is not { IsValid: true, IsBot: false })
|
||||
return HookResult.Continue;
|
||||
var text = info.GetArg(1);
|
||||
if (text.Length == 0)
|
||||
return HookResult.Continue;
|
||||
var team = command == "say_team";
|
||||
var channel = team ? ChatChannel.Team : ChatChannel.All;
|
||||
|
||||
var trigger = ChatTrigger(text);
|
||||
if (trigger != null)
|
||||
{
|
||||
var rest = text[trigger.Length..];
|
||||
var word = NextToken(ref rest).ToLowerInvariant();
|
||||
// Logged on their own: PMs where they're sent, "!asay" and the like as the command.
|
||||
if (!ChatCommands.Contains(word) && !StaffCommands.Contains("css_" + word))
|
||||
Log(channel, StateOf(player), null, null, text, Result.Command);
|
||||
return HookResult.Continue;
|
||||
}
|
||||
|
||||
if (text.StartsWith('@'))
|
||||
{
|
||||
var chatStaff = AdminManager.PlayerHasPermissions(player, "@css/chat");
|
||||
// SimpleAdmin runs this as css_say, which is logged then.
|
||||
if (!team && chatStaff)
|
||||
return HookResult.Continue;
|
||||
// @ team chat goes to staff, and gets through a gag.
|
||||
if (team)
|
||||
{
|
||||
Log(chatStaff ? ChatChannel.Staff : ChatChannel.ToStaff, StateOf(player), null, null, text[1..].Trim(), Result.Sent);
|
||||
return HookResult.Continue;
|
||||
}
|
||||
}
|
||||
|
||||
Log(channel, StateOf(player), null, null, text, IsGagged(player, out _) ? Result.Gagged : Result.Sent);
|
||||
return HookResult.Continue;
|
||||
}
|
||||
|
||||
private static string? ChatTrigger(string text) =>
|
||||
CoreConfig.PublicChatTrigger.Concat(CoreConfig.SilentChatTrigger).FirstOrDefault(t => t.Length > 0 && text.StartsWith(t));
|
||||
|
||||
private HookResult OnSay(CCSPlayerController? player, CommandInfo info)
|
||||
{
|
||||
if (player is not { IsValid: true, IsBot: false })
|
||||
return HookResult.Continue;
|
||||
var text = info.GetArg(1);
|
||||
var trigger = CoreConfig.PublicChatTrigger.Concat(CoreConfig.SilentChatTrigger)
|
||||
.FirstOrDefault(t => t.Length > 0 && text.StartsWith(t));
|
||||
var trigger = ChatTrigger(text);
|
||||
if (trigger == null)
|
||||
return HookResult.Continue;
|
||||
|
||||
|
|
@ -602,7 +675,10 @@ public class Whisper : BasePlugin, IPluginConfig<WhisperConfig>
|
|||
|
||||
// --- History --------------------------------------------------------------------
|
||||
|
||||
private void Log(CCSPlayerController sender, CCSPlayerController? recipient, string target, string message, string result)
|
||||
private void Log(CCSPlayerController sender, CCSPlayerController? recipient, string target, string message, string result) =>
|
||||
Log(ChatChannel.Pm, StateOf(sender), recipient, target, message, result);
|
||||
|
||||
private void Log(string channel, PlayerState sender, CCSPlayerController? recipient, string? target, string message, string result)
|
||||
{
|
||||
if (!Config.History || _writer == null)
|
||||
return;
|
||||
|
|
@ -615,7 +691,7 @@ public class Whisper : BasePlugin, IPluginConfig<WhisperConfig>
|
|||
{
|
||||
}
|
||||
_writer.Enqueue(new MessageRecord(Guid.NewGuid().ToString("N"), DateTime.UtcNow, serverId, Server.MapName ?? "",
|
||||
StateOf(sender), recipient == null ? null : StateOf(recipient), target, message, result));
|
||||
channel, sender, recipient == null ? null : StateOf(recipient), target, message, result));
|
||||
}
|
||||
|
||||
[ConsoleCommand("css_whisper_history", "Turns keeping message history on or off")]
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue