Files
crystall-punk-14/Content.Server/Chat/Managers/ChatManager.cs

295 lines
11 KiB
C#
Raw Normal View History

using System.Linq;
using System.Text;
2022-01-19 13:35:31 +11:00
using Content.Server.Administration.Logs;
2021-06-09 22:19:39 +02:00
using Content.Server.Administration.Managers;
using Content.Server.Ghost.Components;
using Content.Server.Headset;
using Content.Server.MoMMI;
using Content.Server.Players;
2021-06-09 22:19:39 +02:00
using Content.Server.Preferences.Managers;
using Content.Server.Radio.EntitySystems;
Diseases (#7057) * Disease system first pass * Renamed HealthChange * First working version of diseases (wtf???) * Fix the cursed yaml initialization * Pop-Up effect * Generic status effect * Create copy of prototype * CureDiseaseEffect * Disease resistance * Spaceacillin * Nerf spaceacillin now that we know it works * Sneezing, Coughing, Snoughing * Fix queuing, prevent future issues * Disease protection * Disease outbreak event * Disease Reagent Cure * Chem cause disease effect * Disease artifacts * Try infect when interacting with diseased * Diseases don't have to be infectious * Talking without a mask does a snough * Temperature cure * Bedrest * DiseaseAdjustReagent * Tweak how disease statuses work to be a bit less shit * A few more diseases * Natural immunity (can't get the same disease twice) * Polished up some diseases, touched up spaceacillin production * Rebalanced transmission * Edit a few diseases, make disease cures support a minimum value * Nitrile gloves, more disease protection sources * Health scanner shows diseased status * Clean up disease system * Traitor item * Mouth swabs * Disease diagnoser machine * Support for clean samples * Vaccines + fixes * Pass on disease resistant clothes * More work on non-infectious diseases & vaccines * Handle dead bodies * Added the relatively CBT visualizer * Pass over diseases and their populators * Comment stuff * Readability cleanup * Add printing sound to diagnoser, fix printing bug * vaccinator sound, seal up some classes * Make disease protection equip detection not shit (thanks whoever wrote addaccentcomponent) * Mirror review * More review stuff * More mirror review stuff * Refactor snoughing * Redid report creator * Fix snough messages, new vaccinator sound * Mirror review naming * Woops, forgot the artifact * Add recipes and fills * Rebalance space cold and robovirus * Give lizarb disease interaction stuff * Tweak some stuff and move things around * Add diseases to mice (since animal vectors are interesting and can be used to make vaccines) * Remove unused reagent
2022-03-13 21:02:55 -04:00
using Content.Server.Disease;
using Content.Server.Disease.Components;
using Content.Shared.Disease.Components;
2021-06-09 22:19:39 +02:00
using Content.Shared.ActionBlocker;
using Content.Shared.Administration;
using Content.Shared.CCVar;
using Content.Shared.Chat;
2022-01-19 13:35:31 +11:00
using Content.Shared.Database;
2021-06-09 22:19:39 +02:00
using Content.Shared.Inventory;
2021-09-26 15:18:45 +02:00
using Content.Shared.Popups;
using Robust.Server.GameObjects;
using Robust.Server.Player;
using Robust.Shared.Audio;
2021-02-16 20:14:32 +01:00
using Robust.Shared.Configuration;
using Robust.Shared.Console;
using Robust.Shared.Network;
using Robust.Shared.Player;
using Robust.Shared.Players;
using Robust.Shared.Random;
using Robust.Shared.Utility;
2021-06-09 22:19:39 +02:00
using static Content.Server.Chat.Managers.IChatManager;
2021-06-09 22:19:39 +02:00
namespace Content.Server.Chat.Managers
{
/// <summary>
/// Dispatches chat messages to clients.
/// </summary>
internal sealed class ChatManager : IChatManager
{
2021-02-28 18:51:42 +01:00
private static readonly Dictionary<string, string> PatronOocColors = new()
{
// I had plans for multiple colors and those went nowhere so...
{ "nuclear_operative", "#aa00ff" },
{ "syndicate_agent", "#aa00ff" },
{ "revolutionary", "#aa00ff" }
};
2021-02-16 20:14:32 +01:00
[Dependency] private readonly IServerNetManager _netManager = default!;
[Dependency] private readonly IMoMMILink _mommiLink = default!;
[Dependency] private readonly IAdminManager _adminManager = default!;
[Dependency] private readonly IServerPreferencesManager _preferencesManager = default!;
[Dependency] private readonly IConfigurationManager _configurationManager = default!;
2022-01-19 13:35:31 +11:00
private AdminLogSystem _logs = default!;
/// <summary>
/// The maximum length a player-sent message can be sent
/// </summary>
public int MaxMessageLength => _configurationManager.GetCVar(CCVars.ChatMaxMessageLength);
2021-02-16 20:14:32 +01:00
private bool _oocEnabled = true;
private bool _adminOocEnabled = true;
public void Initialize()
{
2022-01-19 13:35:31 +11:00
_logs = EntitySystem.Get<AdminLogSystem>();
_netManager.RegisterNetMessage<MsgChatMessage>();
2021-02-16 20:14:32 +01:00
_configurationManager.OnValueChanged(CCVars.OocEnabled, OnOocEnabledChanged, true);
_configurationManager.OnValueChanged(CCVars.AdminOocEnabled, OnAdminOocEnabledChanged, true);
}
private void OnOocEnabledChanged(bool val)
{
2022-01-19 13:35:31 +11:00
if (_oocEnabled == val) return;
2021-02-16 20:14:32 +01:00
_oocEnabled = val;
DispatchServerAnnouncement(Loc.GetString(val ? "chat-manager-ooc-chat-enabled-message" : "chat-manager-ooc-chat-disabled-message"));
2021-02-16 20:14:32 +01:00
}
private void OnAdminOocEnabledChanged(bool val)
{
2022-01-19 13:35:31 +11:00
if (_adminOocEnabled == val) return;
2021-02-16 20:14:32 +01:00
_adminOocEnabled = val;
DispatchServerAnnouncement(Loc.GetString(val ? "chat-manager-admin-ooc-chat-enabled-message" : "chat-manager-admin-ooc-chat-disabled-message"));
}
2022-03-30 22:21:58 -07:00
#region Server Announcements
public void DispatchServerAnnouncement(string message, Color? colorOverride = null)
{
var messageWrap = Loc.GetString("chat-manager-server-wrap-message");
2022-03-30 22:21:58 -07:00
ChatMessageToAll(ChatChannel.Server, message, messageWrap, colorOverride);
2021-02-12 10:45:22 +01:00
Logger.InfoS("SERVER", message);
2022-01-19 13:35:31 +11:00
_logs.Add(LogType.Chat, LogImpact.Low, $"Server announcement: {message}");
}
public void DispatchStationAnnouncement(string message, string sender = "Central Command", bool playDefaultSound = true, Color? colorOverride = null)
{
var messageWrap = Loc.GetString("chat-manager-sender-announcement-wrap-message", ("sender", sender));
2022-03-30 22:21:58 -07:00
ChatMessageToAll(ChatChannel.Radio, message, messageWrap, colorOverride);
if (playDefaultSound)
{
SoundSystem.Play(Filter.Broadcast(), "/Audio/Announcements/announce.ogg", AudioParams.Default.WithVolume(-2f));
}
2022-01-19 13:35:31 +11:00
_logs.Add(LogType.Chat, LogImpact.Low, $"Station Announcement from {sender}: {message}");
}
public void DispatchServerMessage(IPlayerSession player, string message)
{
var messageWrap = Loc.GetString("chat-manager-server-wrap-message");
2022-03-30 22:21:58 -07:00
ChatMessageToOne(ChatChannel.Server, message, messageWrap, default, false, player.ConnectedClient);
2022-03-30 22:21:58 -07:00
_logs.Add(LogType.Chat, LogImpact.Low, $"Server message to {player:Player}: {message}");
}
2022-03-30 22:21:58 -07:00
public void SendAdminAnnouncement(string message)
{
2022-03-30 22:21:58 -07:00
var clients = _adminManager.ActiveAdmins.Select(p => p.ConnectedClient);
message = FormattedMessage.EscapeText(message);
2021-12-05 18:09:01 +01:00
2022-03-30 22:21:58 -07:00
var messageWrap = Loc.GetString("chat-manager-send-admin-announcement-wrap-message",
("adminChannelName", Loc.GetString("chat-manager-admin-channel-name")));
2022-03-30 22:21:58 -07:00
ChatMessageToMany(ChatChannel.Admin, message, messageWrap, default, false, clients.ToList());
_logs.Add(LogType.Chat, LogImpact.Low, $"Admin announcement from {message}: {message}");
}
2022-03-30 22:21:58 -07:00
public void SendHookOOC(string sender, string message)
{
2021-12-20 12:42:42 +01:00
message = FormattedMessage.EscapeText(message);
2022-03-30 22:21:58 -07:00
var messageWrap = Loc.GetString("chat-manager-send-hook-ooc-wrap-message", ("senderName", sender));
ChatMessageToAll(ChatChannel.OOC, message, messageWrap);
_logs.Add(LogType.Chat, LogImpact.Low, $"Hook OOC from {sender}: {message}");
}
2022-03-30 22:21:58 -07:00
#endregion
2022-03-30 22:21:58 -07:00
#region Public OOC Chat API
2022-03-30 22:21:58 -07:00
/// <summary>
/// Called for a player to attempt sending an OOC, out-of-game. message.
/// </summary>
/// <param name="player">The player sending the message.</param>
/// <param name="message">The message.</param>
/// <param name="type">The type of message.</param>
public void TrySendOOCMessage(IPlayerSession player, string message, OOCChatType type)
{
2022-01-11 16:29:55 +03:00
// Check if message exceeds the character limit
if (message.Length > MaxMessageLength)
{
DispatchServerMessage(player, Loc.GetString("chat-manager-max-message-length-exceeded-message", ("limit", MaxMessageLength)));
2022-01-11 16:29:55 +03:00
return;
}
message = FormattedMessage.EscapeText(message);
2022-03-30 22:21:58 -07:00
switch (type)
{
case OOCChatType.OOC:
SendOOC(player, message);
break;
case OOCChatType.Admin:
SendAdminChat(player, message);
break;
}
}
2022-03-30 22:21:58 -07:00
#endregion
2022-01-19 13:35:31 +11:00
2022-03-30 22:21:58 -07:00
#region Private API
2022-03-30 22:21:58 -07:00
private void SendOOC(IPlayerSession player, string message)
{
2021-02-16 20:14:32 +01:00
if (_adminManager.IsAdmin(player))
{
if (!_adminOocEnabled)
{
return;
}
}
else if (!_oocEnabled)
{
return;
}
2022-03-30 22:21:58 -07:00
Color? colorOverride = null;
var messageWrap = Loc.GetString("chat-manager-send-ooc-wrap-message", ("playerName",player.Name));
if (_adminManager.HasAdminFlag(player, AdminFlags.Admin))
{
2021-02-16 20:14:32 +01:00
var prefs = _preferencesManager.GetPreferences(player.UserId);
2022-03-30 22:21:58 -07:00
colorOverride = prefs.AdminOOCColor;
}
2021-02-28 18:51:42 +01:00
if (player.ConnectedClient.UserData.PatronTier is { } patron &&
PatronOocColors.TryGetValue(patron, out var patronColor))
{
2022-03-30 22:21:58 -07:00
messageWrap = Loc.GetString("chat-manager-send-ooc-patron-wrap-message", ("patronColor", patronColor),("playerName", player.Name));
2021-02-28 18:51:42 +01:00
}
//TODO: player.Name color, this will need to change the structure of the MsgChatMessage
2022-03-30 22:21:58 -07:00
ChatMessageToAll(ChatChannel.OOC, message, messageWrap, colorOverride);
_mommiLink.SendOOCMessage(player.Name, message);
2022-01-19 13:35:31 +11:00
_logs.Add(LogType.Chat, LogImpact.Low, $"OOC from {player:Player}: {message}");
2019-04-17 23:31:43 +02:00
}
2022-03-30 22:21:58 -07:00
private void SendAdminChat(IPlayerSession player, string message)
{
2022-03-30 22:21:58 -07:00
if (!_adminManager.IsAdmin(player))
{
2022-03-30 22:21:58 -07:00
_logs.Add(LogType.Chat, LogImpact.Extreme, $"{player:Player} attempted to send admin message but was not admin");
return;
}
var clients = _adminManager.ActiveAdmins.Select(p => p.ConnectedClient);
2022-03-30 22:21:58 -07:00
var messageWrap = Loc.GetString("chat-manager-send-admin-chat-wrap-message",
("adminChannelName", Loc.GetString("chat-manager-admin-channel-name")),
("playerName", player.Name));
2022-03-30 22:21:58 -07:00
ChatMessageToMany(ChatChannel.Admin, message, messageWrap, default, false, clients.ToList());
2022-01-19 13:35:31 +11:00
_logs.Add(LogType.Chat, $"Admin chat from {player:Player}: {message}");
}
2022-03-30 22:21:58 -07:00
#endregion
2020-11-01 23:56:35 +01:00
2022-03-30 22:21:58 -07:00
#region Utility
2022-03-30 22:21:58 -07:00
public void ChatMessageToOne(ChatChannel channel, string message, string messageWrap, EntityUid source, bool hideChat, INetChannel client)
{
var msg = new MsgChatMessage();
2022-03-30 22:21:58 -07:00
msg.Channel = channel;
2020-11-01 23:56:35 +01:00
msg.Message = message;
2022-03-30 22:21:58 -07:00
msg.MessageWrap = messageWrap;
msg.SenderEntity = source;
msg.HideChat = hideChat;
_netManager.ServerSendMessage(msg, client);
}
2022-03-30 22:21:58 -07:00
public void ChatMessageToMany(ChatChannel channel, string message, string messageWrap, EntityUid source, bool hideChat, List<INetChannel> clients)
{
var msg = new MsgChatMessage();
msg.Channel = channel;
2019-04-17 23:31:43 +02:00
msg.Message = message;
msg.MessageWrap = messageWrap;
msg.SenderEntity = source;
msg.HideChat = hideChat;
2022-03-30 22:21:58 -07:00
_netManager.ServerSendToMany(msg, clients);
}
2022-03-30 22:21:58 -07:00
public void ChatMessageToAll(ChatChannel channel, string message, string messageWrap, Color? colorOverride = null)
{
var msg = new MsgChatMessage();
msg.Channel = channel;
msg.Message = message;
msg.MessageWrap = messageWrap;
if (colorOverride != null)
{
msg.MessageColorOverride = colorOverride.Value;
}
2019-04-17 23:31:43 +02:00
_netManager.ServerSendToAll(msg);
}
2022-03-30 22:21:58 -07:00
public bool MessageCharacterLimit(IPlayerSession? player, string message)
{
var isOverLength = false;
2022-03-30 22:21:58 -07:00
// Non-players don't need to be checked.
if (player == null)
return false;
// Check if message exceeds the character limit if the sender is a player
2022-03-30 22:21:58 -07:00
if (message.Length > MaxMessageLength)
{
var feedback = Loc.GetString("chat-manager-max-message-length-exceeded-message", ("limit", MaxMessageLength));
2022-03-30 22:21:58 -07:00
DispatchServerMessage(player, feedback);
isOverLength = true;
}
return isOverLength;
}
2022-03-30 22:21:58 -07:00
#endregion
}
2022-03-30 22:21:58 -07:00
public enum OOCChatType : byte
{
OOC,
Admin
}
}