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
|
|
@ -73,11 +73,12 @@ public sealed class Database(string connectionString)
|
||||||
var r = o.Recipient;
|
var r = o.Recipient;
|
||||||
await Exec(connection, token, """
|
await Exec(connection, token, """
|
||||||
INSERT IGNORE INTO wh_messages
|
INSERT IGNORE INTO wh_messages
|
||||||
(message_key, sent_at, server_id, map, sender_steamid64, sender_name, sender_team, sender_alive,
|
(message_key, sent_at, server_id, map, channel, sender_steamid64, sender_name, sender_team, sender_alive,
|
||||||
recipient_steamid64, recipient_name, recipient_team, recipient_alive, target, message, result)
|
recipient_steamid64, recipient_name, recipient_team, recipient_alive, target, message, result)
|
||||||
VALUES (@key, @at, @server, @map, @sid, @sname, @steam, @salive, @rid, @rname, @rteam, @ralive, @target, @message, @result)
|
VALUES (@key, @at, @server, @map, @channel, @sid, @sname, @steam, @salive, @rid, @rname, @rteam, @ralive, @target, @message, @result)
|
||||||
""", ("@key", o.Key), ("@at", o.At), ("@server", o.ServerId), ("@map", Clip(o.Map, 64)),
|
""", ("@key", o.Key), ("@at", o.At), ("@server", o.ServerId), ("@map", Clip(o.Map, 64)), ("@channel", Clip(o.Channel, 16)),
|
||||||
("@sid", o.Sender.SteamId), ("@sname", Clip(o.Sender.Name, 128)), ("@steam", o.Sender.Team), ("@salive", o.Sender.Alive),
|
("@sid", o.Sender.SteamId == 0 ? null : o.Sender.SteamId), ("@sname", Clip(o.Sender.Name, 128)),
|
||||||
|
("@steam", o.Sender.Team), ("@salive", o.Sender.Alive),
|
||||||
("@rid", r?.SteamId), ("@rname", Clip(r?.Name, 128)), ("@rteam", r?.Team), ("@ralive", r?.Alive),
|
("@rid", r?.SteamId), ("@rname", Clip(r?.Name, 128)), ("@rteam", r?.Team), ("@ralive", r?.Alive),
|
||||||
("@target", Clip(o.Target, 128)), ("@message", Clip(o.Message, 512)), ("@result", o.Result));
|
("@target", Clip(o.Target, 128)), ("@message", Clip(o.Message, 512)), ("@result", o.Result));
|
||||||
break;
|
break;
|
||||||
|
|
|
||||||
|
|
@ -1,30 +1,38 @@
|
||||||
-- Whisper's tables, in CS2-SimpleAdmin's database. Applied once at load, tracked in wh_migrations.
|
-- Whisper's tables, in CS2-SimpleAdmin's database. Applied once at load, tracked in wh_migrations.
|
||||||
-- All times are UTC.
|
-- All times are UTC.
|
||||||
|
|
||||||
-- One row per private message attempt, sent or not (while History is on in Whisper.json).
|
-- Every chat message, private message and staff message (while History is on in Whisper.json).
|
||||||
-- result: sent, blocked, gagged, cooldown, no_target, ambiguous, group_target, too_long.
|
-- channel: all, team (normal chat), pm (/pm and /r), staff (@ team chat from staff), to_staff
|
||||||
-- The recipient columns are NULL when no single player was found. team: 0 none, 1 spectator,
|
-- (@ team chat from a player), or the SimpleAdmin command used: css_say, css_asay, css_psay,
|
||||||
-- 2 T, 3 CT. alive: 1 when on T/CT with a living pawn. target is what the sender typed for it.
|
-- css_csay, css_hsay, css_cssay.
|
||||||
|
-- result: sent; gagged (blocked by a gag or silence); command (a ! or / chat command); and for pm,
|
||||||
|
-- blocked, cooldown, too_long, no_target, ambiguous or group_target. Staff commands are logged
|
||||||
|
-- as typed, so one the sender wasn't allowed to use is still "sent".
|
||||||
|
-- The sender columns are NULL for the server console (RCON, the web panel). The recipient columns
|
||||||
|
-- are for pm only, NULL when no single player was found. team: 0 none, 1 spectator, 2 T, 3 CT.
|
||||||
|
-- alive: 1 when on T/CT with a living pawn. target is what the sender typed for it (pm, css_psay).
|
||||||
CREATE TABLE IF NOT EXISTS `wh_messages` (
|
CREATE TABLE IF NOT EXISTS `wh_messages` (
|
||||||
`id` bigint unsigned NOT NULL AUTO_INCREMENT,
|
`id` bigint unsigned NOT NULL AUTO_INCREMENT,
|
||||||
`message_key` char(32) NOT NULL,
|
`message_key` char(32) NOT NULL,
|
||||||
`sent_at` datetime NOT NULL,
|
`sent_at` datetime NOT NULL,
|
||||||
`server_id` int NULL,
|
`server_id` int NULL,
|
||||||
`map` varchar(64) NOT NULL,
|
`map` varchar(64) NOT NULL,
|
||||||
`sender_steamid64` bigint unsigned NOT NULL,
|
`channel` varchar(16) NOT NULL,
|
||||||
|
`sender_steamid64` bigint unsigned NULL,
|
||||||
`sender_name` varchar(128) NOT NULL,
|
`sender_name` varchar(128) NOT NULL,
|
||||||
`sender_team` tinyint NOT NULL,
|
`sender_team` tinyint NULL,
|
||||||
`sender_alive` tinyint NOT NULL,
|
`sender_alive` tinyint NULL,
|
||||||
`recipient_steamid64` bigint unsigned NULL,
|
`recipient_steamid64` bigint unsigned NULL,
|
||||||
`recipient_name` varchar(128) NULL,
|
`recipient_name` varchar(128) NULL,
|
||||||
`recipient_team` tinyint NULL,
|
`recipient_team` tinyint NULL,
|
||||||
`recipient_alive` tinyint NULL,
|
`recipient_alive` tinyint NULL,
|
||||||
`target` varchar(128) NOT NULL,
|
`target` varchar(128) NULL,
|
||||||
`message` varchar(512) NOT NULL,
|
`message` varchar(512) NOT NULL,
|
||||||
`result` varchar(16) NOT NULL,
|
`result` varchar(16) NOT NULL,
|
||||||
PRIMARY KEY (`id`),
|
PRIMARY KEY (`id`),
|
||||||
UNIQUE KEY `uq_message_key` (`message_key`),
|
UNIQUE KEY `uq_message_key` (`message_key`),
|
||||||
KEY `ix_sent_at` (`sent_at`),
|
KEY `ix_sent_at` (`sent_at`),
|
||||||
|
KEY `ix_channel` (`channel`, `sent_at`),
|
||||||
KEY `ix_sender` (`sender_steamid64`, `sent_at`),
|
KEY `ix_sender` (`sender_steamid64`, `sent_at`),
|
||||||
KEY `ix_recipient` (`recipient_steamid64`, `sent_at`)
|
KEY `ix_recipient` (`recipient_steamid64`, `sent_at`)
|
||||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;
|
||||||
|
|
|
||||||
21
Ops.cs
21
Ops.cs
|
|
@ -11,20 +11,35 @@ namespace Whisper;
|
||||||
[JsonDerivedType(typeof(BlockRemove), "block_remove")]
|
[JsonDerivedType(typeof(BlockRemove), "block_remove")]
|
||||||
public abstract record Op;
|
public abstract record Op;
|
||||||
|
|
||||||
public sealed record PlayerState(ulong SteamId, string Name, int Team, bool Alive);
|
// A player as they were when the message was sent. Console: SteamId 0, no team.
|
||||||
|
public sealed record PlayerState(ulong SteamId, string Name, int? Team, bool? Alive)
|
||||||
|
{
|
||||||
|
public static readonly PlayerState Console = new(0, "Console", null, null);
|
||||||
|
}
|
||||||
|
|
||||||
public sealed record MessageRecord(
|
public sealed record MessageRecord(
|
||||||
string Key, DateTime At, int? ServerId, string Map, PlayerState Sender, PlayerState? Recipient,
|
string Key, DateTime At, int? ServerId, string Map, string Channel, PlayerState Sender, PlayerState? Recipient,
|
||||||
string Target, string Message, string Result) : Op;
|
string? Target, string Message, string Result) : Op;
|
||||||
|
|
||||||
public sealed record BlockAdd(ulong Blocker, ulong Blocked, string BlockedName, DateTime At) : Op;
|
public sealed record BlockAdd(ulong Blocker, ulong Blocked, string BlockedName, DateTime At) : Op;
|
||||||
|
|
||||||
public sealed record BlockRemove(ulong Blocker, ulong Blocked) : Op;
|
public sealed record BlockRemove(ulong Blocker, ulong Blocked) : Op;
|
||||||
|
|
||||||
|
// Where a message went (wh_messages.channel). SimpleAdmin's commands are logged by their own name.
|
||||||
|
public static class ChatChannel
|
||||||
|
{
|
||||||
|
public const string All = "all";
|
||||||
|
public const string Team = "team";
|
||||||
|
public const string Pm = "pm";
|
||||||
|
public const string Staff = "staff";
|
||||||
|
public const string ToStaff = "to_staff";
|
||||||
|
}
|
||||||
|
|
||||||
// What the message log calls each outcome (wh_messages.result).
|
// What the message log calls each outcome (wh_messages.result).
|
||||||
public static class Result
|
public static class Result
|
||||||
{
|
{
|
||||||
public const string Sent = "sent";
|
public const string Sent = "sent";
|
||||||
|
public const string Command = "command";
|
||||||
public const string Blocked = "blocked";
|
public const string Blocked = "blocked";
|
||||||
public const string Gagged = "gagged";
|
public const string Gagged = "gagged";
|
||||||
public const string Cooldown = "cooldown";
|
public const string Cooldown = "cooldown";
|
||||||
|
|
|
||||||
31
README.md
31
README.md
|
|
@ -69,19 +69,36 @@ tables created on first load and tracked in `wh_migrations`. All times are UTC.
|
||||||
|
|
||||||
### History
|
### History
|
||||||
|
|
||||||
With `History` on, each `/pm` and `/r`, sent or not, is a row in `wh_messages`: when (`sent_at`),
|
With `History` on, every message is a row in `wh_messages`, sent or not:
|
||||||
`server_id` (SimpleAdmin's), `map`, the sender's and recipient's SteamID64, name, team (0 none,
|
|
||||||
1 spectator, 2 T, 3 CT) and whether alive, the `target` as typed, the `message`, and the `result`:
|
| `channel` | What |
|
||||||
`sent`, `blocked`, `gagged`, `cooldown`, `too_long`, `no_target`, `ambiguous` or `group_target`. The
|
|---|---|
|
||||||
recipient columns are `NULL` when no single player was found.
|
| `all`, `team` | Normal chat, including `!`/`/` commands (`result` `command`) other than the ones below |
|
||||||
|
| `pm` | `/pm`, `/w` and `/r` |
|
||||||
|
| `staff`, `to_staff` | `@` team chat, from staff (`@css/chat`) or from a player to staff |
|
||||||
|
| `css_say`, `css_asay`, `css_psay`, `css_csay`, `css_hsay`, `css_cssay` | SimpleAdmin's say commands, typed in console, sent over RCON (the web panel too), or as `!asay` and the like in chat. `@` in all chat from staff is `css_say`, as SimpleAdmin runs it |
|
||||||
|
|
||||||
|
Each row has when (`sent_at`), `server_id` (SimpleAdmin's), `map`, the sender's SteamID64, name,
|
||||||
|
team (0 none, 1 spectator, 2 T, 3 CT) and whether alive (all `NULL` and "Console" for the server
|
||||||
|
console), the `message`, and the `result`: `sent`, `gagged` (stopped by a gag or silence; `@` team
|
||||||
|
chat gets through one), `command`, or for `pm` `blocked`, `cooldown`, `too_long`, `no_target`,
|
||||||
|
`ambiguous` or `group_target`. PMs also have the recipient's SteamID64, name, team and whether alive,
|
||||||
|
and `target` as typed (`css_psay` has `target` too). Staff commands are logged as typed, so one the
|
||||||
|
sender wasn't allowed to use still says `sent`.
|
||||||
|
|
||||||
|
Chat is seen by a catch-all command listener added in `Load`. CSS runs catch-alls before any
|
||||||
|
per-command listener (CS2-Tags' `say`, say), in the order they were added, and stops at the first
|
||||||
|
that returns `Stop`. CS2-SimpleAdmin adds its catch-all (which stops gagged players and handles `@`)
|
||||||
|
in `OnAllPluginsLoaded`, after every plugin's `Load`, so Whisper always sees a line before it's
|
||||||
|
stopped or rewritten. Keep that in mind if SimpleAdmin ever moves its listener into `Load`.
|
||||||
|
|
||||||
`css_whisper_history off` stops it at once and saves the setting to `Whisper.json`; rows already kept
|
`css_whisper_history off` stops it at once and saves the setting to `Whisper.json`; rows already kept
|
||||||
stay. Writes go in order on a background task and spool to `plugins/Whisper/spool.jsonl` while the
|
stay. Writes go in order on a background task and spool to `plugins/Whisper/spool.jsonl` while the
|
||||||
database is down.
|
database is down.
|
||||||
|
|
||||||
```sql
|
```sql
|
||||||
SELECT sent_at, map, sender_name, sender_steamid64, sender_team, sender_alive,
|
SELECT sent_at, map, channel, sender_name, sender_steamid64, sender_team, sender_alive,
|
||||||
recipient_name, recipient_steamid64, recipient_team, recipient_alive, message, result
|
recipient_name, message, result
|
||||||
FROM wh_messages ORDER BY sent_at DESC LIMIT 50;
|
FROM wh_messages ORDER BY sent_at DESC LIMIT 50;
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
|
||||||
90
Whisper.cs
90
Whisper.cs
|
|
@ -15,8 +15,15 @@ using Microsoft.Extensions.Logging;
|
||||||
namespace Whisper;
|
namespace Whisper;
|
||||||
|
|
||||||
// Private messages between players: /pm <target> <message>, /r to reply, and /block, /blocklist,
|
// 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
|
// /unblock. Lines use CS2-Tags' rank prefixes and colours from tags.json. While History is on, every
|
||||||
// CS2-SimpleAdmin's database (wh_messages) while History is on, and blocks in wh_blocks.
|
// 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
|
// 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
|
// 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 class Whisper : BasePlugin, IPluginConfig<WhisperConfig>
|
||||||
{
|
{
|
||||||
public override string ModuleName => "Whisper";
|
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 ModuleAuthor => "astra";
|
||||||
public override string ModuleDescription => "Private messages between players";
|
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)
|
private static readonly HashSet<string> ChatCommands = new(StringComparer.OrdinalIgnoreCase)
|
||||||
{ "pm", "w", "r", "block", "blocklist", "unblock" };
|
{ "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.
|
// Targets that mean more than one player. A PM goes to one.
|
||||||
private static readonly HashSet<string> GroupTargets = new(StringComparer.OrdinalIgnoreCase)
|
private static readonly HashSet<string> GroupTargets = new(StringComparer.OrdinalIgnoreCase)
|
||||||
{ "@all", "@t", "@ct", "@spec", "@alive", "@dead", "@bot", "@bots", "@human", "@humans", "@!me" };
|
{ "@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),
|
_tags = new Tags(Path.Combine(Server.GameDirectory, "csgo", "addons", "counterstrikesharp", Config.TagsFile),
|
||||||
message => Logger.LogWarning("{Message}", message));
|
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", OnSay, HookMode.Pre);
|
||||||
AddCommandListener("say_team", OnSay, HookMode.Pre);
|
AddCommandListener("say_team", OnSay, HookMode.Pre);
|
||||||
RegisterEventHandler<EventPlayerConnectFull>(OnPlayerConnectFull);
|
RegisterEventHandler<EventPlayerConnectFull>(OnPlayerConnectFull);
|
||||||
|
|
@ -200,13 +213,73 @@ public class Whisper : BasePlugin, IPluginConfig<WhisperConfig>
|
||||||
|
|
||||||
// --- Chat -----------------------------------------------------------------------
|
// --- 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)
|
private HookResult OnSay(CCSPlayerController? player, CommandInfo info)
|
||||||
{
|
{
|
||||||
if (player is not { IsValid: true, IsBot: false })
|
if (player is not { IsValid: true, IsBot: false })
|
||||||
return HookResult.Continue;
|
return HookResult.Continue;
|
||||||
var text = info.GetArg(1);
|
var text = info.GetArg(1);
|
||||||
var trigger = CoreConfig.PublicChatTrigger.Concat(CoreConfig.SilentChatTrigger)
|
var trigger = ChatTrigger(text);
|
||||||
.FirstOrDefault(t => t.Length > 0 && text.StartsWith(t));
|
|
||||||
if (trigger == null)
|
if (trigger == null)
|
||||||
return HookResult.Continue;
|
return HookResult.Continue;
|
||||||
|
|
||||||
|
|
@ -602,7 +675,10 @@ public class Whisper : BasePlugin, IPluginConfig<WhisperConfig>
|
||||||
|
|
||||||
// --- History --------------------------------------------------------------------
|
// --- 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)
|
if (!Config.History || _writer == null)
|
||||||
return;
|
return;
|
||||||
|
|
@ -615,7 +691,7 @@ public class Whisper : BasePlugin, IPluginConfig<WhisperConfig>
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
_writer.Enqueue(new MessageRecord(Guid.NewGuid().ToString("N"), DateTime.UtcNow, serverId, Server.MapName ?? "",
|
_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")]
|
[ConsoleCommand("css_whisper_history", "Turns keeping message history on or off")]
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue