2023-06-25 18:19:34 +03:00
using System.Linq ;
using Content.Server.Administration.Managers ;
using Content.Server.Popups ;
using Content.Shared.Administration ;
using Content.Shared.Administration.Logs ;
using Content.Shared.Database ;
using Content.Shared.Hands.Components ;
2024-01-27 09:34:07 +03:00
using Content.Shared.Inventory.VirtualItem ;
2023-06-25 18:19:34 +03:00
using Content.Shared.Verbs ;
2024-01-28 18:37:24 +07:00
using Content.Shared._White.Radials ;
using Content.Shared._White.Radials.Systems ;
2023-06-25 18:19:34 +03:00
using Robust.Server.Player ;
2024-01-28 18:18:54 +07:00
namespace Content.Server._White.Radials ;
2023-06-25 18:19:34 +03:00
public sealed class RadialSystem : SharedRadialSystem
{
[Dependency] private readonly ISharedAdminLogManager _adminLogger = default ! ;
[Dependency] private readonly PopupSystem _popupSystem = default ! ;
[Dependency] private readonly IAdminManager _adminMgr = default ! ;
public override void Initialize ( )
{
base . Initialize ( ) ;
SubscribeNetworkEvent < RequestServerRadialsEvent > ( HandleRadialRequest ) ;
}
private void HandleRadialRequest ( RequestServerRadialsEvent args , EntitySessionEventArgs eventArgs )
{
2024-01-19 13:14:12 +03:00
var player = eventArgs . SenderSession ;
2023-06-25 18:19:34 +03:00
2024-01-19 13:14:12 +03:00
if ( ! EntityManager . EntityExists ( GetEntity ( args . EntityUid ) ) )
2023-06-25 18:19:34 +03:00
{
Logger . Warning ( $"{nameof(HandleRadialRequest)} called on a non-existent entity with id {args.EntityUid} by player {player}." ) ;
return ;
}
if ( player . AttachedEntity is not { } attached )
{
Logger . Warning ( $"{nameof(HandleRadialRequest)} called by player {player} with no attached entity." ) ;
return ;
}
// We do not verify that the user has access to the requested entity. The individual verbs should check
// this, and some verbs (e.g. view variables) won't even care about whether an entity is accessible through
// the entity menu or not.
2024-01-19 13:14:12 +03:00
var force = args . AdminRequest & & _adminMgr . HasAdminFlag ( eventArgs . SenderSession , AdminFlags . Admin ) ;
2023-06-25 18:19:34 +03:00
List < Type > radialsTypes = new ( ) ;
foreach ( var key in args . RadialTypes )
{
var type = Radial . RadialTypes . FirstOrDefault ( x = > x . Name = = key ) ;
if ( type ! = null )
radialsTypes . Add ( type ) ;
else
Logger . Error ( $"Unknown verb type received: {key}" ) ;
}
var response =
2024-01-19 13:14:12 +03:00
new RadialsResponseEvent ( args . EntityUid , GetLocalRadials ( GetEntity ( args . EntityUid ) , attached , radialsTypes , force ) ) ;
2023-06-25 18:19:34 +03:00
RaiseNetworkEvent ( response , player . ConnectedClient ) ;
}
/// <summary>
/// Execute the provided verb.
/// </summary>
/// <remarks>
/// This will try to call the action delegates and raise the local events for the given verb.
/// </remarks>
public override void ExecuteRadial ( Radial radial , EntityUid user , EntityUid target , bool forced = false )
{
// is this verb actually valid?
if ( radial . Disabled )
{
// Send an informative pop-up message
if ( ! string . IsNullOrWhiteSpace ( radial . Message ) )
_popupSystem . PopupEntity ( radial . Message , user , user ) ;
return ;
}
// first, lets log the verb. Just in case it ends up crashing the server or something.
LogRadial ( radial , user , target , forced ) ;
base . ExecuteRadial ( radial , user , target , forced ) ;
}
public void LogRadial ( Radial radial , EntityUid user , EntityUid target , bool forced )
{
// first get the held item. again.
EntityUid ? holding = null ;
if ( TryComp ( user , out HandsComponent ? hands ) & &
hands . ActiveHandEntity is EntityUid heldEntity )
{
holding = heldEntity ;
}
// if this is a virtual pull, get the held entity
2024-01-27 09:34:07 +03:00
if ( holding ! = null & & TryComp ( holding , out VirtualItemComponent ? pull ) )
2023-06-25 18:19:34 +03:00
holding = pull . BlockingEntity ;
var verbText = $"{radial.Text}" . Trim ( ) ;
// lets not frame people, eh?
var executionText = forced ? "was forced to execute" : "executed" ;
if ( holding = = null )
{
_adminLogger . Add ( LogType . Verb , radial . Impact ,
$"{ToPrettyString(user):user} {executionText} the [{verbText:verb}] verb targeting {ToPrettyString(target):target}" ) ;
}
else
{
_adminLogger . Add ( LogType . Verb , radial . Impact ,
$"{ToPrettyString(user):user} {executionText} the [{verbText:verb}] verb targeting {ToPrettyString(target):target} while holding {ToPrettyString(holding.Value):held}" ) ;
}
}
}