using Content.Server.Administration.Logs;
using Content.Server.Administration.Managers;
using Content.Server.Chat.Managers;
using Content.Server.Chat.Systems;
using Content.Shared.Abilities.Psionics;
using Content.Shared.Psionics.Passives;
using Content.Shared.Bed.Sleep;
using Content.Shared.Chat;
using Content.Shared.Database;
using Content.Shared.Drugs;
using Content.Shared.Mobs;
using Content.Shared.Mobs.Components;
using Content.Shared.Psionics.Glimmer;
using Robust.Shared.Network;
using Robust.Shared.Player;
using Robust.Shared.Random;
using System.Linq;
using System.Text;
namespace Content.Server.Chat;
///
/// Extensions for Telepathic chat stuff
///
public sealed partial class TelepathicChatSystem : EntitySystem
{
[Dependency] private readonly IAdminManager _adminManager = default!;
[Dependency] private readonly IChatManager _chatManager = default!;
[Dependency] private readonly IRobustRandom _random = default!;
[Dependency] private readonly IAdminLogManager _adminLogger = default!;
[Dependency] private readonly GlimmerSystem _glimmerSystem = default!;
[Dependency] private readonly ChatSystem _chatSystem = default!;
public override void Initialize()
{
base.Initialize();
InitializePsychognomy();
}
private (IEnumerable normal, IEnumerable psychog) GetPsionicChatClients()
{
var psions = Filter.Empty()
.AddWhereAttachedEntity(IsEligibleForTelepathy)
.Recipients;
var normalSessions = psions.Where(p => !HasComp(p.AttachedEntity)).Select(p => p.Channel);
var psychogSessions = psions.Where(p => HasComp(p.AttachedEntity)).Select(p => p.Channel);
return (normalSessions, psychogSessions);
}
private IEnumerable GetAdminClients()
{
return _adminManager.ActiveAdmins
.Select(p => p.Channel);
}
private List GetDreamers(IEnumerable removeList)
{
var filteredList = new List();
var filtered = Filter.Empty()
.AddWhereAttachedEntity(entity =>
HasComp(entity) && !HasComp(entity)
|| HasComp(entity)
|| HasComp(entity) && !HasComp(entity) && !HasComp(entity))
.Recipients
.Select(p => p.Channel);
if (filtered.ToList() != null)
filteredList = filtered.ToList();
foreach (var entity in removeList)
filteredList.Remove(entity);
return filteredList;
}
private bool IsEligibleForTelepathy(EntityUid entity)
{
return HasComp(entity)
&& !HasComp(entity)
&& !HasComp(entity)
&& !HasComp(entity)
&& (!TryComp(entity, out var mobstate) || mobstate.CurrentState == MobState.Alive);
}
public void SendTelepathicChat(EntityUid source, string message, bool hideChat)
{
if (!IsEligibleForTelepathy(source))
return;
var clients = GetPsionicChatClients();
var admins = GetAdminClients();
string messageWrap;
string adminMessageWrap;
messageWrap = Loc.GetString("chat-manager-send-telepathic-chat-wrap-message",
("telepathicChannelName", Loc.GetString("chat-manager-telepathic-channel-name")), ("message", message));
adminMessageWrap = Loc.GetString("chat-manager-send-telepathic-chat-wrap-message-admin",
("source", source), ("message", message));
_adminLogger.Add(LogType.Chat, LogImpact.Low, $"Telepathic chat from {ToPrettyString(source):Player}: {message}");
_chatManager.ChatMessageToMany(ChatChannel.Telepathic, message, messageWrap, source, hideChat, true, clients.normal.ToList(), Color.PaleVioletRed);
_chatManager.ChatMessageToMany(ChatChannel.Telepathic, message, adminMessageWrap, source, hideChat, true, admins, Color.PaleVioletRed);
if (clients.psychog.Count() > 0)
{
var descriptor = SourceToDescriptor(source);
string psychogMessageWrap;
psychogMessageWrap = Loc.GetString("chat-manager-send-telepathic-chat-wrap-message-psychognomy",
("source", descriptor.ToUpper()), ("message", message));
_chatManager.ChatMessageToMany(ChatChannel.Telepathic, message, psychogMessageWrap, source, hideChat, true, clients.psychog.ToList(), Color.PaleVioletRed);
}
if (_random.Prob(0.1f))
_glimmerSystem.DeltaGlimmerInput(1);
if (_random.Prob(Math.Min(0.33f + (float) _glimmerSystem.GlimmerOutput / 1500, 1)))
{
float obfuscation = 0.25f + (float) _glimmerSystem.GlimmerOutput / 2000;
var obfuscated = ObfuscateMessageReadability(message, obfuscation);
_chatManager.ChatMessageToMany(ChatChannel.Telepathic, obfuscated, messageWrap, source, hideChat, false, GetDreamers(clients.normal.Concat(clients.psychog)), Color.PaleVioletRed);
}
foreach (var repeater in EntityQuery())
_chatSystem.TrySendInGameICMessage(repeater.Owner, message, InGameICChatType.Speak, false);
}
private string ObfuscateMessageReadability(string message, float chance)
{
var modifiedMessage = new StringBuilder(message);
for (var i = 0; i < message.Length; i++)
{
if (char.IsWhiteSpace(modifiedMessage[i]))
{
continue;
}
if (_random.Prob(1 - chance))
{
modifiedMessage[i] = '~';
}
}
return modifiedMessage.ToString();
}
}