2020-06-03 11:46:59 +02:00
using System.Linq ;
2021-10-22 05:31:07 +03:00
using Content.Server.Access.Systems ;
2022-08-08 22:10:01 -07:00
using Content.Server.Station.Systems ;
using Content.Server.StationRecords ;
2021-06-09 22:19:39 +02:00
using Content.Server.UserInterface ;
2021-12-16 23:42:02 +13:00
using Content.Shared.Access.Components ;
2021-12-26 17:07:28 +13:00
using Content.Shared.Access.Systems ;
2022-08-08 22:10:01 -07:00
using Content.Shared.StationRecords ;
using Content.Server.Administration.Logs ;
2022-08-07 20:21:56 -03:00
using Content.Shared.Database ;
2022-08-16 21:03:23 -07:00
using Content.Shared.Roles ;
2021-02-11 01:13:03 -08:00
using Robust.Server.GameObjects ;
2022-08-16 21:03:23 -07:00
using Robust.Shared.Prototypes ;
2019-09-06 08:12:44 +02:00
2021-06-09 22:19:39 +02:00
namespace Content.Server.Access.Components
2019-09-06 08:12:44 +02:00
{
[RegisterComponent]
2021-11-24 20:03:07 +13:00
[ComponentReference(typeof(SharedIdCardConsoleComponent))]
public sealed class IdCardConsoleComponent : SharedIdCardConsoleComponent
2019-09-06 08:12:44 +02:00
{
2021-12-05 18:09:01 +01:00
[Dependency] private readonly IEntityManager _entities = default ! ;
2022-08-07 20:21:56 -03:00
[Dependency] private readonly IAdminLogManager _adminLogger = default ! ;
2022-08-16 21:03:23 -07:00
[Dependency] private readonly IPrototypeManager _prototypeManager = default ! ;
2019-09-06 08:12:44 +02:00
2020-08-24 20:47:17 +02:00
[ViewVariables] private BoundUserInterface ? UserInterface = > Owner . GetUIOrNull ( IdCardConsoleUiKey . Key ) ;
2019-09-06 08:12:44 +02:00
2022-08-16 21:03:23 -07:00
private StationRecordsSystem ? _recordSystem ;
private StationSystem ? _stationSystem ;
2021-06-19 19:41:26 -07:00
protected override void Initialize ( )
2019-09-06 08:12:44 +02:00
{
base . Initialize ( ) ;
2021-12-26 17:07:28 +13:00
Owner . EnsureComponentWarn < AccessReaderComponent > ( ) ;
2020-12-04 13:26:54 +01:00
Owner . EnsureComponentWarn < ServerUserInterfaceComponent > ( ) ;
2020-08-22 22:29:20 +02:00
2022-08-16 21:03:23 -07:00
_stationSystem = _entities . EntitySysManager . GetEntitySystem < StationSystem > ( ) ;
_recordSystem = _entities . EntitySysManager . GetEntitySystem < StationRecordsSystem > ( ) ;
2020-12-04 13:26:54 +01:00
if ( UserInterface ! = null )
2020-08-22 22:29:20 +02:00
{
UserInterface . OnReceiveMessage + = OnUiReceiveMessage ;
}
2022-08-07 20:21:56 -03:00
2019-09-06 08:12:44 +02:00
}
private void OnUiReceiveMessage ( ServerBoundUserInterfaceMessage obj )
{
2021-12-05 18:09:01 +01:00
if ( obj . Session . AttachedEntity is not { Valid : true } player )
2020-08-22 22:29:20 +02:00
{
return ;
}
2019-09-06 08:12:44 +02:00
switch ( obj . Message )
{
case WriteToTargetIdMessage msg :
2022-08-16 21:03:23 -07:00
TryWriteToTargetId ( msg . FullName , msg . JobTitle , msg . AccessList , msg . JobPrototype , player ) ;
2021-11-24 20:03:07 +13:00
UpdateUserInterface ( ) ;
2019-09-06 08:12:44 +02:00
break ;
}
}
/// <summary>
2021-12-26 17:07:28 +13:00
/// Returns true if there is an ID in <see cref="PrivilegedIdSlot"/> and said ID satisfies the requirements of <see cref="AccessReaderComponent"/>.
2019-09-06 08:12:44 +02:00
/// </summary>
private bool PrivilegedIdIsAuthorized ( )
{
2021-12-26 17:07:28 +13:00
if ( ! _entities . TryGetComponent ( Owner , out AccessReaderComponent ? reader ) )
2020-08-22 22:29:20 +02:00
{
return true ;
}
2021-11-24 20:03:07 +13:00
var privilegedIdEntity = PrivilegedIdSlot . Item ;
2022-08-16 21:03:23 -07:00
var accessSystem = _entities . EntitySysManager . GetEntitySystem < AccessReaderSystem > ( ) ;
2022-06-01 11:26:50 -04:00
return privilegedIdEntity ! = null & & accessSystem . IsAllowed ( privilegedIdEntity . Value , reader ) ;
2019-09-06 08:12:44 +02:00
}
2020-08-22 22:29:20 +02:00
2019-09-06 08:12:44 +02:00
/// <summary>
2022-08-07 20:21:56 -03:00
/// Called whenever an access button is pressed, adding or removing that access from the target ID card.
2021-11-24 20:03:07 +13:00
/// Writes data passed from the UI into the ID stored in <see cref="TargetIdSlot"/>, if present.
2019-09-06 08:12:44 +02:00
/// </summary>
2022-08-16 21:03:23 -07:00
private void TryWriteToTargetId ( string newFullName , string newJobTitle , List < string > newAccessList , string newJobProto , EntityUid player )
2019-09-06 08:12:44 +02:00
{
2021-12-05 18:09:01 +01:00
if ( TargetIdSlot . Item is not { Valid : true } targetIdEntity | | ! PrivilegedIdIsAuthorized ( ) )
2019-09-06 08:12:44 +02:00
return ;
2022-08-16 21:03:23 -07:00
var cardSystem = _entities . EntitySysManager . GetEntitySystem < IdCardSystem > ( ) ;
2022-08-07 20:21:56 -03:00
cardSystem . TryChangeFullName ( targetIdEntity , newFullName , player : player ) ;
cardSystem . TryChangeJobTitle ( targetIdEntity , newJobTitle , player : player ) ;
2019-09-06 08:12:44 +02:00
2022-05-21 14:19:02 +10:00
if ( ! newAccessList . TrueForAll ( x = > AccessLevels . Contains ( x ) ) )
2019-09-06 08:12:44 +02:00
{
2020-09-13 14:23:52 +02:00
Logger . Warning ( "Tried to write unknown access tag." ) ;
2019-09-06 08:12:44 +02:00
return ;
}
2021-10-22 05:31:07 +03:00
2022-08-16 21:03:23 -07:00
var accessSystem = _entities . EntitySysManager . GetEntitySystem < AccessSystem > ( ) ;
2022-12-19 21:53:20 -06:00
var oldTags = accessSystem . TryGetTags ( targetIdEntity ) ? ? new List < string > ( ) ;
oldTags = oldTags . ToList ( ) ;
if ( oldTags . SequenceEqual ( newAccessList ) )
return ;
var addedTags = newAccessList . Except ( oldTags ) . Select ( tag = > "+" + tag ) . ToList ( ) ;
var removedTags = oldTags . Except ( newAccessList ) . Select ( tag = > "-" + tag ) . ToList ( ) ;
2021-12-03 15:53:09 +01:00
accessSystem . TrySetTags ( targetIdEntity , newAccessList ) ;
2022-08-07 20:21:56 -03:00
/ * TODO : ECS IdCardConsoleComponent and then log on card ejection , together with the save .
This current implementation is pretty shit as it logs 27 entries ( 27 lines ) if someone decides to give themselves AA * /
_adminLogger . Add ( LogType . Action , LogImpact . Medium ,
2022-12-19 21:53:20 -06:00
$"{_entities.ToPrettyString(player):player} has modified {_entities.ToPrettyString(targetIdEntity):entity} with the following accesses: [{String.Join(" , ", addedTags.Union(removedTags))}] [{string.Join(" , ", newAccessList)}]" ) ;
2022-08-07 20:21:56 -03:00
2022-08-16 21:03:23 -07:00
UpdateStationRecord ( targetIdEntity , newFullName , newJobTitle , newJobProto ) ;
2022-08-08 22:10:01 -07:00
}
2022-08-16 21:03:23 -07:00
private void UpdateStationRecord ( EntityUid idCard , string newFullName , string newJobTitle , string newJobProto )
2022-08-08 22:10:01 -07:00
{
2022-08-16 21:03:23 -07:00
var station = _stationSystem ? . GetOwningStation ( Owner ) ;
2022-08-08 22:10:01 -07:00
if ( station = = null
2022-08-16 21:03:23 -07:00
| | _recordSystem = = null
2022-08-08 22:10:01 -07:00
| | ! _entities . TryGetComponent ( idCard , out StationRecordKeyStorageComponent ? keyStorage )
| | keyStorage . Key = = null
2022-08-16 21:03:23 -07:00
| | ! _recordSystem . TryGetRecord ( station . Value , keyStorage . Key . Value , out GeneralStationRecord ? record ) )
2022-08-08 22:10:01 -07:00
{
return ;
}
record . Name = newFullName ;
record . JobTitle = newJobTitle ;
2022-08-16 21:03:23 -07:00
if ( _prototypeManager . TryIndex ( newJobProto , out JobPrototype ? job ) )
{
record . JobPrototype = newJobProto ;
record . JobIcon = job . Icon ;
}
_recordSystem . Synchronize ( station . Value ) ;
2019-09-06 08:12:44 +02:00
}
2021-11-24 20:03:07 +13:00
public void UpdateUserInterface ( )
2019-09-06 08:12:44 +02:00
{
2021-12-16 23:42:02 +13:00
if ( ! Initialized )
return ;
2019-09-06 08:12:44 +02:00
IdCardConsoleBoundUserInterfaceState newState ;
// this could be prettier
2021-12-05 18:09:01 +01:00
if ( TargetIdSlot . Item is not { Valid : true } targetIdEntity )
2019-09-06 08:12:44 +02:00
{
2021-12-05 18:09:01 +01:00
var privilegedIdName = string . Empty ;
if ( PrivilegedIdSlot . Item is { Valid : true } item )
{
privilegedIdName = _entities . GetComponent < MetaDataComponent > ( item ) . EntityName ;
}
2019-09-06 08:12:44 +02:00
newState = new IdCardConsoleBoundUserInterfaceState (
2021-11-24 20:03:07 +13:00
PrivilegedIdSlot . HasItem ,
2019-09-06 08:12:44 +02:00
PrivilegedIdIsAuthorized ( ) ,
false ,
null ,
null ,
2019-10-21 22:54:16 +02:00
null ,
2022-08-16 21:03:23 -07:00
string . Empty ,
2022-09-06 04:20:00 +02:00
privilegedIdName ,
2021-11-24 20:03:07 +13:00
string . Empty ) ;
2019-09-06 08:12:44 +02:00
}
else
{
2021-12-05 18:09:01 +01:00
var targetIdComponent = _entities . GetComponent < IdCardComponent > ( targetIdEntity ) ;
var targetAccessComponent = _entities . GetComponent < AccessComponent > ( targetIdEntity ) ;
2021-12-03 15:09:45 +01:00
var name = string . Empty ;
2021-12-05 18:09:01 +01:00
if ( PrivilegedIdSlot . Item is { Valid : true } item )
name = _entities . GetComponent < MetaDataComponent > ( item ) . EntityName ;
2022-08-16 21:03:23 -07:00
var station = _stationSystem ? . GetOwningStation ( Owner ) ;
var jobProto = string . Empty ;
if ( _recordSystem ! = null
& & station ! = null
& & _entities . TryGetComponent ( targetIdEntity , out StationRecordKeyStorageComponent ? keyStorage )
& & keyStorage . Key ! = null
& & _recordSystem . TryGetRecord ( station . Value , keyStorage . Key . Value ,
out GeneralStationRecord ? record ) )
{
jobProto = record . JobPrototype ;
}
2019-09-06 08:12:44 +02:00
newState = new IdCardConsoleBoundUserInterfaceState (
2021-11-24 20:03:07 +13:00
PrivilegedIdSlot . HasItem ,
2019-09-06 08:12:44 +02:00
PrivilegedIdIsAuthorized ( ) ,
true ,
targetIdComponent . FullName ,
targetIdComponent . JobTitle ,
2020-06-03 11:46:59 +02:00
targetAccessComponent . Tags . ToArray ( ) ,
2022-08-16 21:03:23 -07:00
jobProto ,
2021-12-03 15:09:45 +01:00
name ,
2021-12-05 18:09:01 +01:00
_entities . GetComponent < MetaDataComponent > ( targetIdEntity ) . EntityName ) ;
2019-09-06 08:12:44 +02:00
}
2020-08-22 22:29:20 +02:00
UserInterface ? . SetState ( newState ) ;
2019-09-06 08:12:44 +02:00
}
}
}