using System.Linq;
using Content.Server._Sunrise.CartridgeLoader.Cartridges;
using Content.Server.DeviceNetwork.Components;
using Content.Shared.DeviceNetwork;
using Content.Shared.DeviceNetwork.Components;
using Content.Shared._Sunrise.Messenger;
using Content.Shared.PDA;
using Content.Shared.Access.Components;
using Content.Shared.DeviceNetwork.Events;
using Content.Shared.GameTicking;
using Content.Shared.CartridgeLoader;
using Content.Shared.StatusIcon;
using Robust.Shared.Prototypes;
namespace Content.Server._Sunrise.Messenger;
///
/// Часть системы мессенджера, отвечающая за регистрацию пользователей
///
public sealed partial class MessengerServerSystem
{
private void OnPlayerSpawnComplete(PlayerSpawnCompleteEvent args)
{
EntityUid? pdaUid = null;
if (_inventory.TryGetSlotEntity(args.Mob, "idcard", out var idCardEntity) &&
TryComp(idCardEntity, out _))
{
pdaUid = idCardEntity;
}
else if (_inventory.TryGetSlotEntity(args.Mob, "belt", out var beltEntity) &&
TryComp(beltEntity, out _))
{
pdaUid = beltEntity;
}
else
{
var handsQuery = EntityQueryEnumerator();
while (handsQuery.MoveNext(out var uid, out var pda))
{
if (pda.PdaOwner == args.Mob)
{
pdaUid = uid;
break;
}
}
}
if (pdaUid == null)
{
Sawmill.Warning($"No PDA found for player: {ToPrettyString(args.Mob)}");
return;
}
if (!TryComp(pdaUid.Value, out var pdaComp) || pdaComp.PdaOwner == null)
{
Sawmill.Debug($"PDA {ToPrettyString(pdaUid.Value)} has no owner, skipping automatic registration");
return;
}
var station = _stationSystem.GetOwningStation(args.Mob);
if (station == null)
{
var mobXform = Transform(args.Mob);
station = _stationSystem.GetStations().FirstOrDefault(s => Transform(s).MapID == mobXform.MapID);
}
if (station == null)
station = _stationSystem.GetStations().FirstOrDefault();
if (station == null)
{
Sawmill.Warning($"No station found for player: {ToPrettyString(args.Mob)}");
return;
}
Sawmill.Debug($"Player station: {ToPrettyString(station.Value)}");
var serverQuery = EntityQueryEnumerator();
EntityUid? serverUid = null;
MessengerServerComponent? serverComponent = null;
DeviceNetworkComponent? serverDevice = null;
int serverCount = 0;
while (serverQuery.MoveNext(out var uid, out var comp, out var singleton, out var device))
{
serverCount++;
var serverStation = _stationSystem.GetOwningStation(uid);
if (serverStation != station)
continue;
if (!_singletonServer.IsActiveServer(uid, singleton))
{
continue;
}
serverUid = uid;
serverComponent = comp;
serverDevice = device;
break;
}
if (serverCount == 0)
{
Sawmill.Warning($"No messenger servers found on station: {ToPrettyString(station.Value)}");
}
if (serverUid == null || serverComponent == null || serverDevice == null)
{
Sawmill.Warning($"No active messenger server found for player: {ToPrettyString(args.Mob)}");
return;
}
Sawmill.Debug($"Server DeviceNetwork before registration: Address={serverDevice.Address}, TransmitFrequency={serverDevice.TransmitFrequency}, ReceiveFrequency={serverDevice.ReceiveFrequency}");
RegisterUserFromPda(serverUid.Value, serverComponent, pdaUid.Value);
}
///
/// Регистрирует пользователя на сервере мессенджера по его PDA
///
private void RegisterUserFromPda(EntityUid uid, MessengerServerComponent component, EntityUid pdaUid)
{
if (!TryComp(pdaUid, out var pda))
{
Sawmill.Warning($"PDA component not found: {ToPrettyString(pdaUid)}");
return;
}
if (!TryComp(pdaUid, out var pdaDevice))
{
Sawmill.Warning($"DeviceNetwork component not found on PDA: {ToPrettyString(pdaUid)}");
return;
}
if (string.IsNullOrEmpty(pdaDevice.Address))
{
return;
}
var userId = pdaDevice.Address;
var userName = pda.OwnerName ?? Loc.GetString("messenger-user-unknown");
string? jobTitle = null;
var departments = new List();
ProtoId jobIconId = "JobIconUnknown";
if (pda.ContainedId != null && TryComp(pda.ContainedId.Value, out var idCard))
{
jobTitle = idCard.LocalizedJobTitle;
departments.AddRange(idCard.JobDepartments.Select(d => (string) d));
jobIconId = idCard.JobIcon;
}
var user = new MessengerUser(userId, userName, jobTitle, departments, jobIconId);
component.Users[userId] = user;
AddUserToAutoGroups(uid, component, userId, userName, departments);
if (!TryComp(uid, out var serverDevice))
{
Sawmill.Warning($"Server does not have DeviceNetworkComponent: {ToPrettyString(uid)}");
return;
}
uint? pdaFrequency;
if (_prototypeManager.TryIndex(component.PdaFrequencyId, out var pdaFreq))
{
pdaFrequency = pdaFreq.Frequency;
}
else
{
Sawmill.Error($"PDA frequency prototype not found");
return;
}
var response = new NetworkPayload
{
[DeviceNetworkConstants.Command] = MessengerCommands.CmdUserRegistered,
["user_id"] = userId,
["user_name"] = userName,
["job_title"] = jobTitle ?? string.Empty,
["department_id"] = user.DepartmentId ?? string.Empty,
["department_ids"] = user.DepartmentIds,
["job_icon_id"] = jobIconId.Id
};
if (_deviceNetwork.IsAddressPresent(serverDevice.DeviceNetId, userId))
{
_deviceNetwork.QueuePacket(uid, userId, response, frequency: pdaFrequency, network: serverDevice.DeviceNetId);
}
var usersPayload = new NetworkPayload
{
[DeviceNetworkConstants.Command] = MessengerCommands.CmdUsersList,
["users"] = component.Users.Values.Select(u => new Dictionary
{
["user_id"] = u.UserId,
["user_name"] = u.Name,
["job_title"] = u.JobTitle ?? string.Empty,
["department_id"] = u.DepartmentId ?? string.Empty,
["department_ids"] = u.DepartmentIds,
["job_icon_id"] = u.JobIconId?.Id ?? string.Empty
}).ToList()
};
if (_deviceNetwork.IsAddressPresent(serverDevice.DeviceNetId, userId))
{
_deviceNetwork.QueuePacket(uid, userId, usersPayload, frequency: pdaFrequency, network: serverDevice.DeviceNetId);
}
var groupsList = component.Groups.Values.ToList();
var groupsData = new List>();
foreach (var group in groupsList)
{
if (group.GroupId == "common")
{
if (!group.Members.Contains(userId))
continue;
}
else if (group.GroupId.StartsWith("dept_"))
{
if (!group.Members.Contains(userId))
continue;
}
else if (group.GroupId.StartsWith("group_"))
{
if (!group.Members.Contains(userId))
continue;
}
var membersList = new List