using System.Diagnostics.CodeAnalysis;
using Content.Shared.Administration;
using Content.Shared.Chemistry;
using Robust.Server.Player;
using Robust.Shared.Enums;
using Robust.Shared.Network;
using Robust.Shared.Player;
namespace Content.Server.Administration;
///
/// This handles the server portion of quick dialogs, including opening them.
///
public sealed partial class QuickDialogSystem : EntitySystem
{
[Dependency] private readonly IPlayerManager _playerManager = default!;
///
/// Contains the success/cancel actions for a dialog.
///
private readonly Dictionary okAction, Action cancelAction)> _openDialogs = new();
private readonly Dictionary> _openDialogsByUser = new();
private int _nextDialogId = 1;
///
public override void Initialize()
{
_playerManager.PlayerStatusChanged += PlayerManagerOnPlayerStatusChanged;
SubscribeNetworkEvent(Handler);
}
public override void Shutdown()
{
base.Shutdown();
_playerManager.PlayerStatusChanged -= PlayerManagerOnPlayerStatusChanged;
}
private void Handler(QuickDialogResponseEvent msg, EntitySessionEventArgs args)
{
if (!_openDialogs.ContainsKey(msg.DialogId) || !_openDialogsByUser[args.SenderSession.UserId].Contains(msg.DialogId))
{
args.SenderSession.Channel.Disconnect($"Replied with invalid quick dialog data with id {msg.DialogId}.");
return;
}
switch (msg.ButtonPressed)
{
case QuickDialogButtonFlag.OkButton:
_openDialogs[msg.DialogId].okAction.Invoke(msg);
break;
case QuickDialogButtonFlag.CancelButton:
_openDialogs[msg.DialogId].cancelAction.Invoke();
break;
default:
throw new ArgumentOutOfRangeException();
}
_openDialogs.Remove(msg.DialogId);
_openDialogsByUser[args.SenderSession.UserId].Remove(msg.DialogId);
}
private int GetDialogId()
{
return _nextDialogId++;
}
private void PlayerManagerOnPlayerStatusChanged(object? sender, SessionStatusEventArgs e)
{
if (e.NewStatus != SessionStatus.Disconnected && e.NewStatus != SessionStatus.Zombie)
return;
var user = e.Session.UserId;
if (!_openDialogsByUser.ContainsKey(user))
return;
foreach (var dialogId in _openDialogsByUser[user])
{
_openDialogs[dialogId].cancelAction.Invoke();
_openDialogs.Remove(dialogId);
}
_openDialogsByUser.Remove(user);
}
private void OpenDialogInternal(ICommonSession session, string title, List entries, QuickDialogButtonFlag buttons, Action okAction, Action cancelAction)
{
var did = GetDialogId();
RaiseNetworkEvent(
new QuickDialogOpenEvent(
title,
entries,
did,
buttons),
session
);
_openDialogs.Add(did, (okAction, cancelAction));
if (!_openDialogsByUser.ContainsKey(session.UserId))
_openDialogsByUser.Add(session.UserId, new List());
_openDialogsByUser[session.UserId].Add(did);
}
private bool TryParseQuickDialogList(List entries, Dictionary responces, out object[]? output)
{
if(entries.Count != responces.Count)
{
output = null;
return false;
}
output = new object[entries.Count];
for(int i = 0; i < entries.Count; i++)
{
var entryType = entries[i].Type;
var input = responces[(i+1).ToString()]; //starts with "1"
if(!TryParseQuickDialog