Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Seperate EMAG into EMAG and Authentication Disruptor #34337

Open
wants to merge 10 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions Content.Server/Access/Systems/AccessOverriderSystem.cs
Original file line number Diff line number Diff line change
Expand Up @@ -245,6 +245,10 @@ private void TryWriteToTargetAccessReaderId(EntityUid uid,
$"{ToPrettyString(player):player} has modified {ToPrettyString(accessReaderEnt.Value):entity} with the following allowed access level holders: [{string.Join(", ", addedTags.Union(removedTags))}] [{string.Join(", ", newAccessList)}]");

accessReaderEnt.Value.Comp.AccessLists = ConvertAccessListToHashSet(newAccessList);

var ev = new OnAccessOverriderAccessUpdatedEvent(player);
RaiseLocalEvent(component.TargetAccessReaderId, ref ev);

Dirty(accessReaderEnt.Value);
}

Expand Down
4 changes: 2 additions & 2 deletions Content.Server/Ninja/Systems/SpaceNinjaSystem.cs
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ public override void Initialize()
{
base.Initialize();

SubscribeLocalEvent<SpaceNinjaComponent, EmaggedSomethingEvent>(OnDoorjack);
SubscribeLocalEvent<SpaceNinjaComponent, AccessBrokeSomethingEvent>(OnDoorjack);
SubscribeLocalEvent<SpaceNinjaComponent, ResearchStolenEvent>(OnResearchStolen);
SubscribeLocalEvent<SpaceNinjaComponent, ThreatCalledInEvent>(OnThreatCalledIn);
SubscribeLocalEvent<SpaceNinjaComponent, CriminalRecordsHackedEvent>(OnCriminalRecordsHacked);
Expand Down Expand Up @@ -118,7 +118,7 @@ public override bool TryUseCharge(EntityUid user, float charge)
/// <summary>
/// Increment greentext when emagging a door.
/// </summary>
private void OnDoorjack(EntityUid uid, SpaceNinjaComponent comp, ref EmaggedSomethingEvent args)
private void OnDoorjack(EntityUid uid, SpaceNinjaComponent comp, ref AccessBrokeSomethingEvent args)
{
// incase someone lets ninja emag non-doors double check it here
if (!HasComp<DoorComponent>(args.Target))
Expand Down
2 changes: 1 addition & 1 deletion Content.Server/VendingMachines/VendingMachineSystem.cs
Original file line number Diff line number Diff line change
Expand Up @@ -232,7 +232,7 @@ public bool IsAuthorized(EntityUid uid, EntityUid sender, VendingMachineComponen
if (!TryComp<AccessReaderComponent>(uid, out var accessReader))
return true;

if (_accessReader.IsAllowed(sender, uid, accessReader) || HasComp<EmaggedComponent>(uid))
if (_accessReader.IsAllowed(sender, uid, accessReader))
return true;

Popup.PopupEntity(Loc.GetString("vending-machine-component-try-eject-access-denied"), uid);
Expand Down
2 changes: 1 addition & 1 deletion Content.Shared/Access/Components/AccessReaderComponent.cs
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ public sealed partial class AccessReaderComponent : Component
/// Whether or not emag interactions have an effect on this.
/// </summary>
[DataField]
public bool BreakOnEmag = true;
public bool BreakOnAccessBreaker = true;
}

[DataDefinition, Serializable, NetSerializable]
Expand Down
16 changes: 11 additions & 5 deletions Content.Shared/Access/Systems/AccessReaderSystem.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
using System.Diagnostics.CodeAnalysis;
using System.Linq;
using Content.Shared.Access.Components;
using Content.Shared.AccessBreaker;
using Content.Shared.DeviceLinking.Events;
using Content.Shared.Emag.Components;
using Content.Shared.Emag.Systems;
Expand Down Expand Up @@ -33,7 +34,7 @@ public override void Initialize()
{
base.Initialize();

SubscribeLocalEvent<AccessReaderComponent, GotEmaggedEvent>(OnEmagged);
SubscribeLocalEvent<AccessReaderComponent, GotAccessBrokenEvent>(OnAccessBreak);
SubscribeLocalEvent<AccessReaderComponent, LinkAttemptEvent>(OnLinkAttempt);

SubscribeLocalEvent<AccessReaderComponent, ComponentGetState>(OnGetState);
Expand Down Expand Up @@ -75,13 +76,17 @@ private void OnLinkAttempt(EntityUid uid, AccessReaderComponent component, LinkA
args.Cancel();
}

private void OnEmagged(EntityUid uid, AccessReaderComponent reader, ref GotEmaggedEvent args)
private void OnAccessBreak(EntityUid uid, AccessReaderComponent reader, ref GotAccessBrokenEvent args)
{
if (!reader.BreakOnEmag)
if (!reader.BreakOnAccessBreaker)
return;

if (!GetMainAccessReader(uid, out var accessReader))
return;

args.Handled = true;
reader.Enabled = false;
reader.AccessLog.Clear();
accessReader.Value.Comp.AccessLists.Clear();
accessReader.Value.Comp.AccessLog.Clear();
Dirty(uid, reader);
}

Expand Down Expand Up @@ -135,6 +140,7 @@ public bool GetMainAccessReader(EntityUid uid, [NotNullWhen(true)] out Entity<Ac
return true;
}
}

return true;
}

Expand Down
3 changes: 3 additions & 0 deletions Content.Shared/Access/Systems/SharedAccessOverriderSystem.cs
Original file line number Diff line number Diff line change
Expand Up @@ -45,3 +45,6 @@ public AccessOverriderDoAfterEvent()
}
}
}

[ByRefEvent]
public record struct OnAccessOverriderAccessUpdatedEvent(EntityUid UserUid, bool Handled = false);
18 changes: 18 additions & 0 deletions Content.Shared/AccessBreaker/Components/AccessBreakerComponent.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
using Content.Shared.Tag;
using Robust.Shared.GameStates;
using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype;

namespace Content.Shared.AccessBreaker;

[Access(typeof(AccessBreakerSystem))]
[RegisterComponent, NetworkedComponent]
[AutoGenerateComponentState]
public sealed partial class AccessBreakerComponent : Component
{
/// <summary>
/// The tag that marks an entity as immune to the access breaker.
/// </summary>
[DataField(customTypeSerializer: typeof(PrototypeIdSerializer<TagPrototype>))]
[AutoNetworkedField]
public string AccessBreakerImmuneTag = "AccessBreakerImmune";
}
12 changes: 12 additions & 0 deletions Content.Shared/AccessBreaker/Components/AccessBrokenComponent.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
using Robust.Shared.GameStates;

namespace Content.Shared.AccessBreaker;

/// <summary>
/// Marker component for breaking access and locks
/// </summary>
[RegisterComponent, NetworkedComponent]
public sealed partial class AccessBrokenComponent : Component
{

}
109 changes: 109 additions & 0 deletions Content.Shared/AccessBreaker/Systems/AccessBreakerSystem.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
using Content.Shared.Administration.Logs;
using Content.Shared.Charges.Components;
using Content.Shared.Charges.Systems;
using Content.Shared.Database;
using Content.Shared.Emag.Components;
using Content.Shared.IdentityManagement;
using Content.Shared.Interaction;
using Content.Shared.Popups;
using Content.Shared.Tag;

namespace Content.Shared.AccessBreaker;

public sealed class AccessBreakerSystem : EntitySystem
{
[Dependency] private readonly ISharedAdminLogManager _adminLogger = default!;
[Dependency] private readonly SharedChargesSystem _charges = default!;
[Dependency] private readonly SharedPopupSystem _popup = default!;
[Dependency] private readonly TagSystem _tag = default!;

public override void Initialize()
{
base.Initialize();

SubscribeLocalEvent<AccessBreakerComponent, AfterInteractEvent>(OnAfterInteract);
SubscribeLocalEvent<AccessBrokenComponent, OnAccessOverriderAccessUpdatedEvent>(OnAccessFixed);
}

private void OnAfterInteract(Entity<AccessBreakerComponent> ent, ref AfterInteractEvent args)
{
if (!args.CanReach || args.Target is not { } target)
return;

args.Handled = TryBreakAccess(ent, args.User, target, ent.Comp);
}

private void OnAccessFixed(Entity<AccessBrokenComponent> ent, ref OnAccessOverriderAccessUpdatedEvent args)
{
RemCompDeferred<AccessBrokenComponent>(ent);

args.Handled = true;
}

/// <summary>
/// Tries to break the access/lock on a target entity
/// </summary>
public bool TryBreakAccess(EntityUid uid, EntityUid user, EntityUid target, AccessBreakerComponent? comp = null)
{
if (!Resolve(uid, ref comp, false))
return false;

if (_tag.HasTag(target, comp.AccessBreakerImmuneTag))
return false;

TryComp<LimitedChargesComponent>(uid, out var charges);
if (_charges.IsEmpty(uid, charges))
{
_popup.PopupClient(Loc.GetString("access-breaker-no-charges"), user, user);
return false;
}

var handled = DoAccessBreakerEffect(user, target);
if (!handled)
return false;

_popup.PopupClient(Loc.GetString("access-breaker-success", ("target", Identity.Entity(target, EntityManager))), user,
user, PopupType.Medium);

_adminLogger.Add(LogType.Emag, LogImpact.High, $"{ToPrettyString(user):player} broke the access of {ToPrettyString(target):target}");

if (charges != null)
_charges.UseCharge(uid, charges);
return true;
}

/// <summary>
/// Does the access breaker effect on a specified entity
/// </summary>
public bool DoAccessBreakerEffect(EntityUid user, EntityUid target)
{
if (HasComp<AccessBrokenComponent>(target))
return false;

var onAttemptAccessBreakEvent = new OnAttemptAccessBreakEvent(user);
RaiseLocalEvent(target, ref onAttemptAccessBreakEvent);

// prevent breaking if attempt fails
if (onAttemptAccessBreakEvent.Handled)
return false;

var accessBrokenEvent = new GotAccessBrokenEvent(user);
RaiseLocalEvent(target, ref accessBrokenEvent);

if (accessBrokenEvent.Handled)
EnsureComp<AccessBrokenComponent>(target);
return accessBrokenEvent.Handled;
}
}

/// <summary>
/// Shows a popup to emag user (client side only!) and adds <see cref="EmaggedComponent"/> to the entity when handled
/// </summary>
/// <param name="UserUid">Emag user</param>
/// <param name="Handled">Did the emagging succeed? Causes a user-only popup to show on client side</param>
/// <remarks>Needs to be handled in shared/client, not just the server, to actually show the emagging popup</remarks>
[ByRefEvent]
public record struct GotAccessBrokenEvent(EntityUid UserUid, bool Handled = false);

[ByRefEvent]
public record struct OnAttemptAccessBreakEvent(EntityUid UserUid, bool Handled = false);
9 changes: 5 additions & 4 deletions Content.Shared/Doors/Systems/SharedDoorSystem.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
using System.Linq;
using Content.Shared.Access.Components;
using Content.Shared.Access.Systems;
using Content.Shared.AccessBreaker;
using Content.Shared.Administration.Logs;
using Content.Shared.Damage;
using Content.Shared.Database;
Expand Down Expand Up @@ -78,8 +79,8 @@ public override void Initialize()
SubscribeLocalEvent<DoorComponent, WeldableChangedEvent>(OnWeldChanged);
SubscribeLocalEvent<DoorComponent, GetPryTimeModifierEvent>(OnPryTimeModifier);

SubscribeLocalEvent<DoorComponent, OnAttemptEmagEvent>(OnAttemptEmag);
SubscribeLocalEvent<DoorComponent, GotEmaggedEvent>(OnEmagged);
SubscribeLocalEvent<DoorComponent, OnAttemptAccessBreakEvent>(OnAttemptAccessBreak);
SubscribeLocalEvent<DoorComponent, GotAccessBrokenEvent>(OnAccessBreak);
}

protected virtual void OnComponentInit(Entity<DoorComponent> ent, ref ComponentInit args)
Expand Down Expand Up @@ -118,7 +119,7 @@ private void OnRemove(Entity<DoorComponent> door, ref ComponentRemove args)
_activeDoors.Remove(door);
}

private void OnAttemptEmag(EntityUid uid, DoorComponent door, ref OnAttemptEmagEvent args)
private void OnAttemptAccessBreak(EntityUid uid, DoorComponent door, ref OnAttemptAccessBreakEvent args)
{
if (!TryComp<AirlockComponent>(uid, out var airlock))
{
Expand All @@ -138,7 +139,7 @@ private void OnAttemptEmag(EntityUid uid, DoorComponent door, ref OnAttemptEmagE
}
}

private void OnEmagged(EntityUid uid, DoorComponent door, ref GotEmaggedEvent args)
private void OnAccessBreak(EntityUid uid, DoorComponent door, ref GotAccessBrokenEvent args)
{
if (!SetState(uid, DoorState.Emagging, door))
return;
Expand Down
1 change: 0 additions & 1 deletion Content.Shared/Emag/Systems/EmagSystem.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@
using Content.Shared.IdentityManagement;
using Content.Shared.Interaction;
using Content.Shared.Popups;
using Content.Shared.Silicons.Laws.Components;
using Content.Shared.Tag;

namespace Content.Shared.Emag.Systems;
Expand Down
4 changes: 2 additions & 2 deletions Content.Shared/Lock/LockComponent.cs
Original file line number Diff line number Diff line change
Expand Up @@ -54,9 +54,9 @@ public sealed partial class LockComponent : Component
/// <summary>
/// Whether or not an emag disables it.
/// </summary>
[DataField("breakOnEmag")]
[DataField]
[AutoNetworkedField]
public bool BreakOnEmag = true;
public bool BreakOnAccessBreaker = true;

/// <summary>
/// Amount of do-after time needed to lock the entity.
Expand Down
9 changes: 4 additions & 5 deletions Content.Shared/Lock/LockSystem.cs
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
using Content.Shared.Access.Components;
using Content.Shared.Access.Systems;
using Content.Shared.AccessBreaker;
using Content.Shared.ActionBlocker;
using Content.Shared.Construction.Components;
using Content.Shared.DoAfter;
using Content.Shared.Emag.Systems;
using Content.Shared.Examine;
using Content.Shared.IdentityManagement;
using Content.Shared.Interaction;
Expand Down Expand Up @@ -43,7 +43,7 @@ public override void Initialize()
SubscribeLocalEvent<LockComponent, StorageOpenAttemptEvent>(OnStorageOpenAttempt);
SubscribeLocalEvent<LockComponent, ExaminedEvent>(OnExamined);
SubscribeLocalEvent<LockComponent, GetVerbsEvent<AlternativeVerb>>(AddToggleLockVerb);
SubscribeLocalEvent<LockComponent, GotEmaggedEvent>(OnEmagged);
SubscribeLocalEvent<LockComponent, GotAccessBrokenEvent>(OnAccessBreak);
SubscribeLocalEvent<LockComponent, LockDoAfter>(OnDoAfterLock);
SubscribeLocalEvent<LockComponent, UnlockDoAfter>(OnDoAfterUnlock);
SubscribeLocalEvent<LockComponent, StorageInteractAttemptEvent>(OnStorageInteractAttempt);
Expand Down Expand Up @@ -293,9 +293,9 @@ private void AddToggleLockVerb(EntityUid uid, LockComponent component, GetVerbsE
args.Verbs.Add(verb);
}

private void OnEmagged(EntityUid uid, LockComponent component, ref GotEmaggedEvent args)
private void OnAccessBreak(EntityUid uid, LockComponent component, ref GotAccessBrokenEvent args)
{
if (!component.Locked || !component.BreakOnEmag)
if (!component.Locked || !component.BreakOnAccessBreaker)
return;

_audio.PlayPredicted(component.UnlockSound, uid, args.UserUid);
Expand All @@ -307,7 +307,6 @@ private void OnEmagged(EntityUid uid, LockComponent component, ref GotEmaggedEve
var ev = new LockToggledEvent(false);
RaiseLocalEvent(uid, ref ev, true);

RemComp<LockComponent>(uid); //Literally destroys the lock as a tell it was emagged
args.Handled = true;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,14 +10,14 @@ namespace Content.Shared.Ninja.Components;
/// Component for emagging things on click.
/// No charges but checks against a whitelist.
/// </summary>
[RegisterComponent, NetworkedComponent, Access(typeof(EmagProviderSystem))]
public sealed partial class EmagProviderComponent : Component
[RegisterComponent, NetworkedComponent, Access(typeof(AccessBreakerProviderSystem))]
public sealed partial class AccessBreakerProviderComponent : Component
{
/// <summary>
/// The tag that marks an entity as immune to emagging.
/// </summary>
[DataField]
public ProtoId<TagPrototype> EmagImmuneTag = "EmagImmune";
public ProtoId<TagPrototype> AccessBreakerImmuneTag = "AccessBreakerImmune";

/// <summary>
/// Whitelist that entities must be on to work.
Expand Down
Loading
Loading