fish-station/Content.Server/_Sunrise/Messenger/MessengerServerSystem.Messages.cs

288 lines
11 KiB
C#

using System.Linq;
using Content.Shared.DeviceNetwork;
using Content.Shared.DeviceNetwork.Components;
using Content.Shared.DeviceNetwork.Events;
using Content.Shared._Sunrise.Messenger;
namespace Content.Server._Sunrise.Messenger;
/// <summary>
/// Часть системы мессенджера, отвечающая за обработку сообщений
/// </summary>
public sealed partial class MessengerServerSystem
{
private void HandleSendMessage(EntityUid uid, MessengerServerComponent component, DeviceNetworkPacketEvent args)
{
if (!args.Data.TryGetValue(MessengerCommands.CmdSendMessage, out NetworkPayload? messageData))
return;
if (!messageData.TryGetValue("content", out string? content) || string.IsNullOrWhiteSpace(content))
return;
if (!component.Users.TryGetValue(args.SenderAddress, out var sender))
return;
UpdateUserInfoFromPda(uid, component, args.SenderAddress, sender);
var timestamp = GetStationTime();
if (messageData.TryGetValue("group_id", out string? groupId) && !string.IsNullOrWhiteSpace(groupId))
{
SendGroupMessage(uid, component, sender, groupId, content, timestamp);
}
else if (messageData.TryGetValue("recipient_id", out string? recipientId) && !string.IsNullOrWhiteSpace(recipientId))
{
SendPersonalMessage(uid, component, sender, recipientId, content, timestamp);
}
}
private void SendPersonalMessage(EntityUid uid, MessengerServerComponent component, MessengerUser sender, string recipientId, string content, TimeSpan timestamp)
{
if (!component.Users.ContainsKey(recipientId))
return;
var messageId = GetNextMessageId(uid, component);
var message = new MessengerMessage(sender.UserId, sender.Name, content, timestamp, null, recipientId, isRead: false, messageId, sender.JobIconId);
var chatId = GetPersonalChatId(sender.UserId, recipientId);
if (!component.MessageHistory.TryGetValue(chatId, out var history))
{
history = new List<MessengerMessage>();
component.MessageHistory[chatId] = history;
}
history.Add(message);
TrimMessageHistory(history, component.MaxMessageHistory);
var isChatOpen = component.OpenChats.TryGetValue(recipientId, out var openChatId) && openChatId == chatId;
if (isChatOpen)
{
message.IsRead = true;
}
else
{
if (!component.UnreadCounts.TryGetValue(recipientId, out var recipientUnreads))
{
recipientUnreads = new Dictionary<string, int>();
component.UnreadCounts[recipientId] = recipientUnreads;
}
recipientUnreads.TryGetValue(chatId, out var currentCount);
recipientUnreads[chatId] = currentCount + 1;
}
if (!TryComp<DeviceNetworkComponent>(uid, out var serverDevice))
return;
uint? pdaFrequency = null;
if (_prototypeManager.TryIndex(component.PdaFrequencyId, out var pdaFreq))
{
pdaFrequency = pdaFreq.Frequency;
}
var payload = new NetworkPayload
{
[DeviceNetworkConstants.Command] = MessengerCommands.CmdMessageReceived,
["sender_id"] = message.SenderId,
["sender_name"] = message.SenderName,
["content"] = message.Content,
["timestamp"] = message.Timestamp.TotalSeconds,
["group_id"] = message.GroupId ?? string.Empty,
["recipient_id"] = message.RecipientId ?? string.Empty,
["is_read"] = message.IsRead,
["message_id"] = message.MessageId,
["sender_job_icon_id"] = message.SenderJobIconId?.Id ?? string.Empty
};
if (pdaFrequency.HasValue)
{
_deviceNetwork.QueuePacket(uid, recipientId, payload, frequency: pdaFrequency, network: serverDevice.DeviceNetId);
_deviceNetwork.QueuePacket(uid, sender.UserId, payload, frequency: pdaFrequency, network: serverDevice.DeviceNetId);
}
else
{
_deviceNetwork.QueuePacket(uid, recipientId, payload);
_deviceNetwork.QueuePacket(uid, sender.UserId, payload);
}
if (isChatOpen && pdaFrequency.HasValue)
{
var updatePayload = new NetworkPayload
{
[DeviceNetworkConstants.Command] = MessengerCommands.CmdMessagesList,
["messages"] = new List<Dictionary<string, object>>
{
new ()
{
["sender_id"] = message.SenderId,
["sender_name"] = message.SenderName,
["content"] = message.Content,
["timestamp"] = message.Timestamp.TotalSeconds,
["group_id"] = message.GroupId ?? string.Empty,
["recipient_id"] = message.RecipientId ?? string.Empty,
["is_read"] = message.IsRead,
["message_id"] = message.MessageId
}
},
["chat_id"] = chatId
};
_deviceNetwork.QueuePacket(uid, sender.UserId, updatePayload, frequency: pdaFrequency, network: serverDevice.DeviceNetId);
}
}
private void SendGroupMessage(EntityUid uid, MessengerServerComponent component, MessengerUser sender, string groupId, string content, TimeSpan timestamp)
{
if (!component.Groups.TryGetValue(groupId, out var group))
return;
if (!group.Members.Contains(sender.UserId))
return;
var messageId = GetNextMessageId(uid, component);
var message = new MessengerMessage(sender.UserId, sender.Name, content, timestamp, groupId, null, false, messageId, sender.JobIconId);
if (!component.MessageHistory.TryGetValue(groupId, out var history))
{
history = new List<MessengerMessage>();
component.MessageHistory[groupId] = history;
}
history.Add(message);
TrimMessageHistory(history, component.MaxMessageHistory);
if (!TryComp<DeviceNetworkComponent>(uid, out var serverDevice))
return;
uint? pdaFrequency = null;
if (_prototypeManager.TryIndex(component.PdaFrequencyId, out var pdaFreq))
{
pdaFrequency = pdaFreq.Frequency;
}
foreach (var memberId in group.Members)
{
if (memberId == sender.UserId)
continue;
var isMemberChatOpen = component.OpenChats.TryGetValue(memberId, out var memberOpenChatId) && memberOpenChatId == groupId;
if (!isMemberChatOpen)
{
if (!component.UnreadCounts.TryGetValue(memberId, out var memberUnreads))
{
memberUnreads = new Dictionary<string, int>();
component.UnreadCounts[memberId] = memberUnreads;
}
memberUnreads.TryGetValue(groupId, out var currentCount);
memberUnreads[groupId] = currentCount + 1;
}
}
var payload = new NetworkPayload
{
[DeviceNetworkConstants.Command] = MessengerCommands.CmdMessageReceived,
["sender_id"] = message.SenderId,
["sender_name"] = message.SenderName,
["content"] = message.Content,
["timestamp"] = message.Timestamp.TotalSeconds,
["group_id"] = message.GroupId ?? string.Empty,
["recipient_id"] = message.RecipientId ?? string.Empty,
["is_read"] = message.IsRead,
["message_id"] = message.MessageId,
["sender_job_icon_id"] = message.SenderJobIconId?.Id ?? string.Empty
};
foreach (var memberId in group.Members)
{
if (pdaFrequency.HasValue)
{
_deviceNetwork.QueuePacket(uid, memberId, payload, frequency: pdaFrequency, network: serverDevice.DeviceNetId);
}
else
{
_deviceNetwork.QueuePacket(uid, memberId, payload);
}
}
}
/// <summary>
/// Обрабатывает удаление сообщения пользователем
/// </summary>
private void HandleDeleteMessage(EntityUid uid, MessengerServerComponent component, DeviceNetworkPacketEvent args)
{
if (!args.Data.TryGetValue(MessengerCommands.CmdDeleteMessage, out NetworkPayload? deleteData))
return;
if (!deleteData.TryGetValue("message_id", out object? messageIdObj) ||
!deleteData.TryGetValue("chat_id", out string? chatId))
return;
if (!long.TryParse(messageIdObj?.ToString(), out var messageId))
return;
if (!component.Users.TryGetValue(args.SenderAddress, out var user))
return;
if (!component.MessageHistory.TryGetValue(chatId, out var history))
return;
var message = history.FirstOrDefault(m => m.MessageId == messageId);
if (message == null)
return;
if (message.SenderId != user.UserId)
return;
history.Remove(message);
if (!TryComp<DeviceNetworkComponent>(uid, out var serverDevice))
return;
uint? pdaFrequency = null;
if (_prototypeManager.TryIndex(component.PdaFrequencyId, out var pdaFreq))
{
pdaFrequency = pdaFreq.Frequency;
}
var recipients = new HashSet<string>();
if (chatId.StartsWith("personal_"))
{
var parts = chatId.Split('_');
if (parts.Length >= 3)
{
recipients.Add(parts[1]);
recipients.Add(parts[2]);
}
}
else
{
if (component.Groups.TryGetValue(chatId, out var group))
{
foreach (var memberId in group.Members)
{
recipients.Add(memberId);
}
}
}
var deletePayload = new NetworkPayload
{
[DeviceNetworkConstants.Command] = MessengerCommands.CmdMessageDeleted,
["message_id"] = messageId,
["chat_id"] = chatId
};
foreach (var recipientId in recipients)
{
if (pdaFrequency.HasValue)
{
_deviceNetwork.QueuePacket(uid, recipientId, deletePayload, frequency: pdaFrequency, network: serverDevice.DeviceNetId);
}
else
{
_deviceNetwork.QueuePacket(uid, recipientId, deletePayload);
}
}
}
}