Merge pull request #1532 from space-syndicate/upstream-sync

Upstream sync
This commit is contained in:
Morb 2023-10-28 14:40:41 +03:00 • committed by GitHub
commit fb62c1ef83
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
587 changed files with 18561 additions and 7864 deletions

View file

@ -338,5 +338,8 @@ dotnet_naming_symbols.type_parameters_symbols.applicable_kinds = type_parameter
resharper_braces_for_ifelse = required_for_multiline
resharper_keep_existing_attribute_arrangement = true
[*.{csproj,xml,yml,dll.config,msbuildproj,targets}]
[*.{csproj,xml,yml,yaml,dll.config,msbuildproj,targets}]
indent_size = 2
[{*.yaml,*.yml}]
ij_yaml_indent_sequence_value = false

View file

@ -2,7 +2,6 @@ using System.IO;
using System.Linq;
using Content.Shared.Actions;
using JetBrains.Annotations;
using Robust.Client.GameObjects;
using Robust.Client.Player;
using Robust.Shared.ContentPack;
using Robust.Shared.GameStates;
@ -41,8 +40,8 @@ namespace Content.Client.Actions
public override void Initialize()
{
base.Initialize();
SubscribeLocalEvent<ActionsComponent, PlayerAttachedEvent>(OnPlayerAttached);
SubscribeLocalEvent<ActionsComponent, PlayerDetachedEvent>(OnPlayerDetached);
SubscribeLocalEvent<ActionsComponent, LocalPlayerAttachedEvent>(OnPlayerAttached);
SubscribeLocalEvent<ActionsComponent, LocalPlayerDetachedEvent>(OnPlayerDetached);
SubscribeLocalEvent<ActionsComponent, ComponentHandleState>(HandleComponentState);
SubscribeLocalEvent<InstantActionComponent, ComponentHandleState>(OnInstantHandleState);
@ -196,12 +195,12 @@ namespace Content.Client.Actions
return GetActions(user);
}
private void OnPlayerAttached(EntityUid uid, ActionsComponent component, PlayerAttachedEvent args)
private void OnPlayerAttached(EntityUid uid, ActionsComponent component, LocalPlayerAttachedEvent args)
{
LinkAllActions(component);
}
private void OnPlayerDetached(EntityUid uid, ActionsComponent component, PlayerDetachedEvent? args = null)
private void OnPlayerDetached(EntityUid uid, ActionsComponent component, LocalPlayerDetachedEvent? args = null)
{
UnlinkAllActions();
}

View file

@ -4,7 +4,7 @@ using Robust.Client.Console;
using Robust.Client.Player;
using Robust.Shared.ContentPack;
using Robust.Shared.Network;
using Robust.Shared.Players;
using Robust.Shared.Player;
using Robust.Shared.Utility;
namespace Content.Client.Administration.Managers

View file

@ -22,7 +22,7 @@ namespace Content.Client.Administration.UI.CustomControls
private List<PlayerInfo> _playerList = new();
private readonly List<PlayerInfo> _sortedPlayerList = new();
public event Action<PlayerInfo?>? OnSelectionChanged;
public event Action<PlayerInfo>? OnSelectionChanged;
public IReadOnlyList<PlayerInfo> PlayerInfo => _playerList;
public Func<PlayerInfo, string, string>? OverrideText;
@ -46,9 +46,9 @@ namespace Content.Client.Administration.UI.CustomControls
BackgroundPanel.PanelOverride = new StyleBoxFlat {BackgroundColor = new Color(32, 32, 40)};
}
private void PlayerListItemPressed(BaseButton.ButtonEventArgs args, ListData data)
private void PlayerListItemPressed(BaseButton.ButtonEventArgs? args, ListData? data)
{
if (data is not PlayerListData {Info: var selectedPlayer})
if (args == null || data is not PlayerListData {Info: var selectedPlayer})
return;
if (args.Event.Function == EngineKeyFunctions.UIClick)
{

View file

@ -5,7 +5,6 @@ using Robust.Client.Console;
using Robust.Client.UserInterface.Controls;
using Robust.Client.UserInterface.CustomControls;
using Robust.Shared.IoC;
using Robust.Shared.Players;
namespace Content.Client.Administration.UI.Tabs.AdminTab
{

View file

@ -1,7 +1,6 @@
using System.Linq;
using Content.Shared.Alert;
using JetBrains.Annotations;
using Robust.Client.GameObjects;
using Robust.Client.Player;
using Robust.Shared.Prototypes;
@ -22,8 +21,8 @@ public sealed class ClientAlertsSystem : AlertsSystem
{
base.Initialize();
SubscribeLocalEvent<AlertsComponent, PlayerAttachedEvent>(OnPlayerAttached);
SubscribeLocalEvent<AlertsComponent, PlayerDetachedEvent>(OnPlayerDetached);
SubscribeLocalEvent<AlertsComponent, LocalPlayerAttachedEvent>(OnPlayerAttached);
SubscribeLocalEvent<AlertsComponent, LocalPlayerDetachedEvent>(OnPlayerDetached);
SubscribeLocalEvent<AlertsComponent, AfterAutoHandleStateEvent>(ClientAlertsHandleState);
}
@ -69,7 +68,7 @@ public sealed class ClientAlertsSystem : AlertsSystem
SyncAlerts?.Invoke(this, component.Alerts);
}
private void OnPlayerAttached(EntityUid uid, AlertsComponent component, PlayerAttachedEvent args)
private void OnPlayerAttached(EntityUid uid, AlertsComponent component, LocalPlayerAttachedEvent args)
{
if (_playerManager.LocalPlayer?.ControlledEntity != uid)
return;
@ -87,7 +86,7 @@ public sealed class ClientAlertsSystem : AlertsSystem
ClearAlerts?.Invoke(this, EventArgs.Empty);
}
private void OnPlayerDetached(EntityUid uid, AlertsComponent component, PlayerDetachedEvent args)
private void OnPlayerDetached(EntityUid uid, AlertsComponent component, LocalPlayerDetachedEvent args)
{
ClearAlerts?.Invoke(this, EventArgs.Empty);
}

View file

@ -1,6 +1,5 @@
using Content.Shared.CharacterInfo;
using Content.Shared.Objectives;
using Robust.Client.GameObjects;
using Robust.Client.Player;
using Robust.Client.UserInterface;
@ -11,14 +10,11 @@ public sealed class CharacterInfoSystem : EntitySystem
[Dependency] private readonly IPlayerManager _players = default!;
public event Action<CharacterData>? OnCharacterUpdate;
public event Action? OnCharacterDetached;
public override void Initialize()
{
base.Initialize();
SubscribeLocalEvent<PlayerAttachSysMessage>(OnPlayerAttached);
SubscribeNetworkEvent<CharacterInfoEvent>(OnCharacterInfoEvent);
}
@ -33,14 +29,6 @@ public sealed class CharacterInfoSystem : EntitySystem
RaiseNetworkEvent(new RequestCharacterInfoEvent(GetNetEntity(entity.Value)));
}
private void OnPlayerAttached(PlayerAttachSysMessage msg)
{
if (msg.AttachedEntity == default)
{
OnCharacterDetached?.Invoke();
}
}
private void OnCharacterInfoEvent(CharacterInfoEvent msg, EntitySessionEventArgs args)
{
var entity = GetEntity(msg.NetEntity);

View file

@ -1,8 +1,6 @@
using Content.Shared.Smoking;
using Robust.Shared.Spawners;
using Content.Shared.Chemistry.Components;
using Robust.Client.Animations;
using Robust.Client.GameObjects;
using Robust.Shared.Network;
using Robust.Shared.Timing;
namespace Content.Client.Chemistry.Visualizers;
@ -18,6 +16,7 @@ public sealed class FoamVisualizerSystem : VisualizerSystem<FoamVisualsComponent
{
base.Initialize();
SubscribeLocalEvent<FoamVisualsComponent, ComponentInit>(OnComponentInit);
SubscribeLocalEvent<FoamVisualsComponent, AnimationCompletedEvent>(OnAnimationComplete);
}
public override void Update(float frameTime)
@ -27,11 +26,11 @@ public sealed class FoamVisualizerSystem : VisualizerSystem<FoamVisualsComponent
if (!_timing.IsFirstTimePredicted)
return;
var query = EntityQueryEnumerator<FoamVisualsComponent, TimedDespawnComponent>();
var query = EntityQueryEnumerator<FoamVisualsComponent, SmokeComponent>();
while (query.MoveNext(out var uid, out var comp, out var despawn))
while (query.MoveNext(out var uid, out var comp, out var smoke))
{
if (despawn.Lifetime > 1f)
if (_timing.CurTime < comp.StartTime + TimeSpan.FromSeconds(smoke.Duration) - TimeSpan.FromSeconds(comp.AnimationTime))
continue;
// Despawn animation.
@ -48,6 +47,7 @@ public sealed class FoamVisualizerSystem : VisualizerSystem<FoamVisualsComponent
/// </summary>
private void OnComponentInit(EntityUid uid, FoamVisualsComponent comp, ComponentInit args)
{
comp.StartTime = _timing.CurTime;
comp.Animation = new Animation
{
Length = TimeSpan.FromSeconds(comp.AnimationTime),
@ -58,12 +58,21 @@ public sealed class FoamVisualizerSystem : VisualizerSystem<FoamVisualsComponent
LayerKey = FoamVisualLayers.Base,
KeyFrames =
{
new AnimationTrackSpriteFlick.KeyFrame(comp.State, 0f)
new AnimationTrackSpriteFlick.KeyFrame(comp.AnimationState, 0f)
}
}
}
};
}
private void OnAnimationComplete(EntityUid uid, FoamVisualsComponent component, AnimationCompletedEvent args)
{
if (args.Key != FoamVisualsComponent.AnimationKey)
return;
if (TryComp<SpriteComponent>(uid, out var sprite))
sprite.Visible = false;
}
}
public enum FoamVisualLayers : byte

View file

@ -1,5 +1,6 @@
using Robust.Client.Animations;
using Robust.Client.Graphics;
using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom;
namespace Content.Client.Chemistry.Visualizers;
@ -15,18 +16,21 @@ public sealed partial class FoamVisualsComponent : Component
/// </summary>
public const string AnimationKey = "foamdissolve_animation";
[DataField(customTypeSerializer: typeof(TimeOffsetSerializer))]
public TimeSpan StartTime;
/// <summary>
/// How long the foam visually dissolves for.
/// </summary>
[DataField("animationTime")]
public float AnimationTime = 0.6f;
[DataField]
public float AnimationTime = 0.5f;
/// <summary>
/// The state of the entities base sprite RSI that is displayed when the foam dissolves.
/// Cannot use <see cref="RSI.StateKey"/> because it does not have <see cref="DataDefinitionAttribute"/> and I am not making an engine PR at this time.
/// </summary>
[DataField("animationState")]
public string State = "foam-dissolve";
[DataField]
public string AnimationState = "foam-dissolve";
/// <summary>
/// The animation used while the foam dissolves.

View file

@ -38,7 +38,7 @@ namespace Content.Client.Construction
base.Initialize();
UpdatesOutsidePrediction = true;
SubscribeLocalEvent<PlayerAttachSysMessage>(HandlePlayerAttached);
SubscribeLocalEvent<LocalPlayerAttachedEvent>(HandlePlayerAttached);
SubscribeNetworkEvent<AckStructureConstructionMessage>(HandleAckStructure);
SubscribeNetworkEvent<ResponseConstructionGuide>(OnConstructionGuideReceived);
@ -110,9 +110,9 @@ namespace Content.Client.Construction
ClearGhost(msg.GhostId);
}
private void HandlePlayerAttached(PlayerAttachSysMessage msg)
private void HandlePlayerAttached(LocalPlayerAttachedEvent msg)
{
var available = IsCraftingAvailable(msg.AttachedEntity);
var available = IsCraftingAvailable(msg.Entity);
UpdateCraftingAvailability(available);
}

View file

@ -1,5 +1,4 @@
using Content.Shared.Drugs;
using Robust.Client.GameObjects;
using Robust.Client.Graphics;
using Robust.Client.Player;
@ -24,18 +23,18 @@ public sealed class DrugOverlaySystem : EntitySystem
SubscribeLocalEvent<SeeingRainbowsComponent, ComponentInit>(OnInit);
SubscribeLocalEvent<SeeingRainbowsComponent, ComponentShutdown>(OnShutdown);
SubscribeLocalEvent<SeeingRainbowsComponent, PlayerAttachedEvent>(OnPlayerAttached);
SubscribeLocalEvent<SeeingRainbowsComponent, PlayerDetachedEvent>(OnPlayerDetached);
SubscribeLocalEvent<SeeingRainbowsComponent, LocalPlayerAttachedEvent>(OnPlayerAttached);
SubscribeLocalEvent<SeeingRainbowsComponent, LocalPlayerDetachedEvent>(OnPlayerDetached);
_overlay = new();
}
private void OnPlayerAttached(EntityUid uid, SeeingRainbowsComponent component, PlayerAttachedEvent args)
private void OnPlayerAttached(EntityUid uid, SeeingRainbowsComponent component, LocalPlayerAttachedEvent args)
{
_overlayMan.AddOverlay(_overlay);
}
private void OnPlayerDetached(EntityUid uid, SeeingRainbowsComponent component, PlayerDetachedEvent args)
private void OnPlayerDetached(EntityUid uid, SeeingRainbowsComponent component, LocalPlayerDetachedEvent args)
{
_overlay.Intoxication = 0;
_overlayMan.RemoveOverlay(_overlay);

View file

@ -1,5 +1,4 @@
using Content.Shared.Drunk;
using Robust.Client.GameObjects;
using Robust.Client.Graphics;
using Robust.Client.Player;
@ -19,18 +18,18 @@ public sealed class DrunkSystem : SharedDrunkSystem
SubscribeLocalEvent<DrunkComponent, ComponentInit>(OnDrunkInit);
SubscribeLocalEvent<DrunkComponent, ComponentShutdown>(OnDrunkShutdown);
SubscribeLocalEvent<DrunkComponent, PlayerAttachedEvent>(OnPlayerAttached);
SubscribeLocalEvent<DrunkComponent, PlayerDetachedEvent>(OnPlayerDetached);
SubscribeLocalEvent<DrunkComponent, LocalPlayerAttachedEvent>(OnPlayerAttached);
SubscribeLocalEvent<DrunkComponent, LocalPlayerDetachedEvent>(OnPlayerDetached);
_overlay = new();
}
private void OnPlayerAttached(EntityUid uid, DrunkComponent component, PlayerAttachedEvent args)
private void OnPlayerAttached(EntityUid uid, DrunkComponent component, LocalPlayerAttachedEvent args)
{
_overlayMan.AddOverlay(_overlay);
}
private void OnPlayerDetached(EntityUid uid, DrunkComponent component, PlayerDetachedEvent args)
private void OnPlayerDetached(EntityUid uid, DrunkComponent component, LocalPlayerDetachedEvent args)
{
_overlay.CurrentBoozePower = 0;
_overlayMan.RemoveOverlay(_overlay);

View file

@ -1,17 +1,7 @@
using Content.Shared.Eye.Blinding;
using Robust.Client.GameObjects;
using Robust.Client.Graphics;
using Robust.Client.Player;
using System;
using System.Collections.Generic;
using System.Linq;
using Content.Shared.Administration;
using Content.Shared.Administration.Events;
using Content.Shared.Eye.Blinding.Components;
using Content.Shared.GameTicking;
using Robust.Shared.GameObjects;
using Robust.Shared.Network;
namespace Content.Client.Eye.Blinding;
@ -31,20 +21,20 @@ public sealed class BlindingSystem : EntitySystem
SubscribeLocalEvent<BlindableComponent, ComponentInit>(OnBlindInit);
SubscribeLocalEvent<BlindableComponent, ComponentShutdown>(OnBlindShutdown);
SubscribeLocalEvent<BlindableComponent, PlayerAttachedEvent>(OnPlayerAttached);
SubscribeLocalEvent<BlindableComponent, PlayerDetachedEvent>(OnPlayerDetached);
SubscribeLocalEvent<BlindableComponent, LocalPlayerAttachedEvent>(OnPlayerAttached);
SubscribeLocalEvent<BlindableComponent, LocalPlayerDetachedEvent>(OnPlayerDetached);
SubscribeNetworkEvent<RoundRestartCleanupEvent>(RoundRestartCleanup);
_overlay = new();
}
private void OnPlayerAttached(EntityUid uid, BlindableComponent component, PlayerAttachedEvent args)
private void OnPlayerAttached(EntityUid uid, BlindableComponent component, LocalPlayerAttachedEvent args)
{
_overlayMan.AddOverlay(_overlay);
}
private void OnPlayerDetached(EntityUid uid, BlindableComponent component, PlayerDetachedEvent args)
private void OnPlayerDetached(EntityUid uid, BlindableComponent component, LocalPlayerDetachedEvent args)
{
_overlayMan.RemoveOverlay(_overlay);
_lightManager.Enabled = true;

View file

@ -1,9 +1,6 @@
using Content.Shared.Eye.Blinding;
using Content.Shared.Eye.Blinding.Components;
using Robust.Client.GameObjects;
using Robust.Client.Graphics;
using Robust.Client.Player;
using Robust.Shared.GameStates;
namespace Content.Client.Eye.Blinding;
@ -20,18 +17,18 @@ public sealed class BlurryVisionSystem : EntitySystem
SubscribeLocalEvent<BlurryVisionComponent, ComponentInit>(OnBlurryInit);
SubscribeLocalEvent<BlurryVisionComponent, ComponentShutdown>(OnBlurryShutdown);
SubscribeLocalEvent<BlurryVisionComponent, PlayerAttachedEvent>(OnPlayerAttached);
SubscribeLocalEvent<BlurryVisionComponent, PlayerDetachedEvent>(OnPlayerDetached);
SubscribeLocalEvent<BlurryVisionComponent, LocalPlayerAttachedEvent>(OnPlayerAttached);
SubscribeLocalEvent<BlurryVisionComponent, LocalPlayerDetachedEvent>(OnPlayerDetached);
_overlay = new();
}
private void OnPlayerAttached(EntityUid uid, BlurryVisionComponent component, PlayerAttachedEvent args)
private void OnPlayerAttached(EntityUid uid, BlurryVisionComponent component, LocalPlayerAttachedEvent args)
{
_overlayMan.AddOverlay(_overlay);
}
private void OnPlayerDetached(EntityUid uid, BlurryVisionComponent component, PlayerDetachedEvent args)
private void OnPlayerDetached(EntityUid uid, BlurryVisionComponent component, LocalPlayerDetachedEvent args)
{
_overlayMan.RemoveOverlay(_overlay);
}

View file

@ -30,7 +30,7 @@ public sealed class EyeLerpingSystem : EntitySystem
SubscribeLocalEvent<EyeAttachedEvent>(OnAttached);
SubscribeLocalEvent<LerpingEyeComponent, EntParentChangedMessage>(HandleMapChange);
SubscribeLocalEvent<LerpingEyeComponent, PlayerDetachedEvent>(OnDetached);
SubscribeLocalEvent<LerpingEyeComponent, LocalPlayerDetachedEvent>(OnDetached);
UpdatesAfter.Add(typeof(TransformSystem));
UpdatesAfter.Add(typeof(PhysicsSystem));
@ -94,7 +94,7 @@ public sealed class EyeLerpingSystem : EntitySystem
AddEye(ev.Entity, ev.Component, true);
}
private void OnDetached(EntityUid uid, LerpingEyeComponent component, PlayerDetachedEvent args)
private void OnDetached(EntityUid uid, LerpingEyeComponent component, LocalPlayerDetachedEvent args)
{
if (!component.ManuallyAdded)
RemCompDeferred(uid, component);

View file

@ -4,7 +4,7 @@ using Robust.Client.Input;
using Robust.Shared.Input.Binding;
using Robust.Shared;
using Robust.Shared.Configuration;
using Robust.Shared.Players;
using Robust.Shared.Player;
namespace Content.Client.Fullscreen;
public sealed class FullscreenHook

View file

@ -16,7 +16,7 @@ using Robust.Shared.Console;
using Robust.Shared.Input;
using Robust.Shared.Input.Binding;
using Robust.Shared.Map;
using Robust.Shared.Players;
using Robust.Shared.Player;
using Robust.Shared.Timing;
namespace Content.Client.Gameplay

View file

@ -58,10 +58,10 @@ namespace Content.Client.Ghost
SubscribeLocalEvent<GhostComponent, ComponentRemove>(OnGhostRemove);
SubscribeLocalEvent<GhostComponent, AfterAutoHandleStateEvent>(OnGhostState);
SubscribeLocalEvent<GhostComponent, PlayerAttachedEvent>(OnGhostPlayerAttach);
SubscribeLocalEvent<GhostComponent, PlayerDetachedEvent>(OnGhostPlayerDetach);
SubscribeLocalEvent<GhostComponent, LocalPlayerAttachedEvent>(OnGhostPlayerAttach);
SubscribeLocalEvent<GhostComponent, LocalPlayerDetachedEvent>(OnGhostPlayerDetach);
SubscribeLocalEvent<PlayerAttachedEvent>(OnPlayerAttach);
SubscribeLocalEvent<LocalPlayerAttachedEvent>(OnPlayerAttach);
SubscribeNetworkEvent<GhostWarpsResponseEvent>(OnGhostWarpsResponse);
SubscribeNetworkEvent<GhostUpdateGhostRoleCountEvent>(OnUpdateGhostRoleCount);
@ -130,7 +130,7 @@ namespace Content.Client.Ghost
PlayerRemoved?.Invoke(component);
}
private void OnGhostPlayerAttach(EntityUid uid, GhostComponent component, PlayerAttachedEvent playerAttachedEvent)
private void OnGhostPlayerAttach(EntityUid uid, GhostComponent component, LocalPlayerAttachedEvent localPlayerAttachedEvent)
{
if (uid != _playerManager.LocalPlayer?.ControlledEntity)
return;
@ -161,13 +161,13 @@ namespace Content.Client.Ghost
return true;
}
private void OnGhostPlayerDetach(EntityUid uid, GhostComponent component, PlayerDetachedEvent args)
private void OnGhostPlayerDetach(EntityUid uid, GhostComponent component, LocalPlayerDetachedEvent args)
{
if (PlayerDetach(uid))
component.IsAttached = false;
}
private void OnPlayerAttach(PlayerAttachedEvent ev)
private void OnPlayerAttach(LocalPlayerAttachedEvent ev)
{
if (!HasComp<GhostComponent>(ev.Entity))
PlayerDetach(ev.Entity);

View file

@ -42,8 +42,8 @@ namespace Content.Client.Hands.Systems
{
base.Initialize();
SubscribeLocalEvent<HandsComponent, PlayerAttachedEvent>(HandlePlayerAttached);
SubscribeLocalEvent<HandsComponent, PlayerDetachedEvent>(HandlePlayerDetached);
SubscribeLocalEvent<HandsComponent, LocalPlayerAttachedEvent>(HandlePlayerAttached);
SubscribeLocalEvent<HandsComponent, LocalPlayerDetachedEvent>(HandlePlayerDetached);
SubscribeLocalEvent<HandsComponent, ComponentStartup>(OnHandsStartup);
SubscribeLocalEvent<HandsComponent, ComponentShutdown>(OnHandsShutdown);
SubscribeLocalEvent<HandsComponent, ComponentHandleState>(HandleComponentState);
@ -361,12 +361,12 @@ namespace Content.Client.Hands.Systems
#region Gui
private void HandlePlayerAttached(EntityUid uid, HandsComponent component, PlayerAttachedEvent args)
private void HandlePlayerAttached(EntityUid uid, HandsComponent component, LocalPlayerAttachedEvent args)
{
OnPlayerHandsAdded?.Invoke(component);
}
private void HandlePlayerDetached(EntityUid uid, HandsComponent component, PlayerDetachedEvent args)
private void HandlePlayerDetached(EntityUid uid, HandsComponent component, LocalPlayerDetachedEvent args)
{
OnPlayerHandsRemoved?.Invoke();
}

View file

@ -1,9 +1,33 @@
<DefaultWindow xmlns="https://spacestation14.io"
MinSize="250 100"
SetSize="250 100">
<BoxContainer Orientation="Vertical">
<Label
Name="Diagnostics"
Text="{Loc health-analyzer-window-no-patient-data-text}"/>
</BoxContainer>
</DefaultWindow>
SetSize="250 100">
<ScrollContainer
VerticalExpand="True">
<BoxContainer
Name="RootContainer"
Orientation="Vertical">
<Label
Name="NoPatientDataText"
Text="{Loc health-analyzer-window-no-patient-data-text}" />
<BoxContainer
Name="PatientDataContainer"
Orientation="Vertical"
Margin="0 0 5 10">
<Label
Name="PatientName"/>
<Label
Name="Temperature"
Margin="0 5 0 0"/>
<Label
Name="BloodLevel"
Margin="0 5 0 0"/>
<Label
Name="patientDamageAmount"
Margin="0 15 0 0"/>
</BoxContainer>
<BoxContainer
Name="GroupsContainer"
Orientation="Vertical">
</BoxContainer>
</BoxContainer>
</ScrollContainer>
</DefaultWindow>

View file

@ -1,5 +1,5 @@
using System.Linq;
using System.Numerics;
using System.Text;
using Content.Shared.Damage;
using Content.Shared.Damage.Prototypes;
using Content.Shared.FixedPoint;
@ -8,85 +8,182 @@ using Content.Shared.MedicalScanner;
using Robust.Client.AutoGenerated;
using Robust.Client.UserInterface.CustomControls;
using Robust.Client.UserInterface.XAML;
using Robust.Client.GameObjects;
using Robust.Client.Graphics;
using Robust.Client.UserInterface.Controls;
using Robust.Client.ResourceManagement;
using Robust.Shared.Prototypes;
using Robust.Shared.Utility;
namespace Content.Client.HealthAnalyzer.UI
{
[GenerateTypedNameReferences]
public sealed partial class HealthAnalyzerWindow : DefaultWindow
{
private readonly IEntityManager _entityManager;
private readonly SpriteSystem _spriteSystem;
private readonly IPrototypeManager _prototypes;
private readonly IResourceCache _cache;
private const int AnalyzerHeight = 430;
private const int AnalyzerWidth = 300;
public HealthAnalyzerWindow()
{
RobustXamlLoader.Load(this);
var dependencies = IoCManager.Instance!;
_entityManager = dependencies.Resolve<IEntityManager>();
_spriteSystem = _entityManager.System<SpriteSystem>();
_prototypes = dependencies.Resolve<IPrototypeManager>();
_cache = dependencies.Resolve<IResourceCache>();
}
public void Populate(HealthAnalyzerScannedUserMessage msg)
{
var text = new StringBuilder();
var entities = IoCManager.Resolve<IEntityManager>();
var target = entities.GetEntity(msg.TargetEntity);
GroupsContainer.RemoveAllChildren();
if (msg.TargetEntity != null && entities.TryGetComponent<DamageableComponent>(target, out var damageable))
var target = _entityManager.GetEntity(msg.TargetEntity);
if (target == null
|| !_entityManager.TryGetComponent<DamageableComponent>(target, out var damageable))
{
string entityName = "Unknown";
if (msg.TargetEntity != null &&
entities.HasComponent<MetaDataComponent>(target.Value))
{
entityName = Identity.Name(target.Value, entities);
}
IReadOnlyDictionary<string, FixedPoint2> damagePerGroup = damageable.DamagePerGroup;
IReadOnlyDictionary<string, FixedPoint2> damagePerType = damageable.Damage.DamageDict;
text.Append($"{Loc.GetString("health-analyzer-window-entity-health-text", ("entityName", entityName))}\n\n");
text.Append($"{Loc.GetString("health-analyzer-window-entity-temperature-text", ("temperature", float.IsNaN(msg.Temperature) ? "N/A" : $"{msg.Temperature - 273f:F1} °C"))}\n");
text.Append($"{Loc.GetString("health-analyzer-window-entity-blood-level-text", ("bloodLevel", float.IsNaN(msg.BloodLevel) ? "N/A" : $"{msg.BloodLevel * 100:F1} %"))}\n\n");
// Damage
text.Append($"{Loc.GetString("health-analyzer-window-entity-damage-total-text", ("amount", damageable.TotalDamage))}\n");
HashSet<string> shownTypes = new();
var protos = IoCManager.Resolve<IPrototypeManager>();
// Show the total damage and type breakdown for each damage group.
foreach (var (damageGroupId, damageAmount) in damagePerGroup)
{
if (damageAmount == 0)
{
continue;
}
text.Append($"\n{Loc.GetString("health-analyzer-window-damage-group-text", ("damageGroup", Loc.GetString("health-analyzer-window-damage-group-" + damageGroupId)), ("amount", damageAmount))}");
// Show the damage for each type in that group.
var group = protos.Index<DamageGroupPrototype>(damageGroupId);
foreach (var type in group.DamageTypes)
{
if (damagePerType.TryGetValue(type, out var typeAmount) )
{
// If damage types are allowed to belong to more than one damage group, they may appear twice here. Mark them as duplicate.
if (!shownTypes.Contains(type) && typeAmount > 0)
{
shownTypes.Add(type);
text.Append($"\n- {Loc.GetString("health-analyzer-window-damage-type-text", ("damageType", Loc.GetString("health-analyzer-window-damage-type-" + type)), ("amount", typeAmount))}");
}
}
}
text.AppendLine();
}
Diagnostics.Text = text.ToString();
SetSize = new Vector2(250, 600);
NoPatientDataText.Visible = true;
return;
}
else
NoPatientDataText.Visible = false;
string entityName = Loc.GetString("health-analyzer-window-entity-unknown-text");
if (_entityManager.HasComponent<MetaDataComponent>(target.Value))
{
Diagnostics.Text = Loc.GetString("health-analyzer-window-no-patient-data-text");
SetSize = new Vector2(250, 100);
entityName = Identity.Name(target.Value, _entityManager);
}
PatientName.Text = Loc.GetString(
"health-analyzer-window-entity-health-text",
("entityName", entityName)
);
Temperature.Text = Loc.GetString("health-analyzer-window-entity-temperature-text",
("temperature", float.IsNaN(msg.Temperature) ? "N/A" : $"{msg.Temperature - 273f:F1} °C")
);
BloodLevel.Text = Loc.GetString("health-analyzer-window-entity-blood-level-text",
("bloodLevel", float.IsNaN(msg.BloodLevel) ? "N/A" : $"{msg.BloodLevel * 100:F1} %")
);
patientDamageAmount.Text = Loc.GetString(
"health-analyzer-window-entity-damage-total-text",
("amount", damageable.TotalDamage)
);
var damageSortedGroups =
damageable.DamagePerGroup.OrderBy(damage => damage.Value)
.ToDictionary(x => x.Key, x => x.Value);
IReadOnlyDictionary<string, FixedPoint2> damagePerType = damageable.Damage.DamageDict;
DrawDiagnosticGroups(damageSortedGroups, damagePerType);
SetHeight = AnalyzerHeight;
SetWidth = AnalyzerWidth;
}
private void DrawDiagnosticGroups(
Dictionary<string, FixedPoint2> groups, IReadOnlyDictionary<string, FixedPoint2> damageDict)
{
HashSet<string> shownTypes = new();
// Show the total damage and type breakdown for each damage group.
foreach (var (damageGroupId, damageAmount) in groups.Reverse())
{
if (damageAmount == 0)
continue;
var groupTitleText = $"{Loc.GetString(
"health-analyzer-window-damage-group-text",
("damageGroup", Loc.GetString("health-analyzer-window-damage-group-" + damageGroupId)),
("amount", damageAmount)
)}";
var groupContainer = new BoxContainer
{
Margin = new Thickness(0, 0, 0, 15),
Align = BoxContainer.AlignMode.Begin,
Orientation = BoxContainer.LayoutOrientation.Vertical,
};
groupContainer.AddChild(CreateDiagnosticGroupTitle(groupTitleText, damageGroupId, damageAmount.Int()));
GroupsContainer.AddChild(groupContainer);
// Show the damage for each type in that group.
var group = _prototypes.Index<DamageGroupPrototype>(damageGroupId);
foreach (var type in group.DamageTypes)
{
if (damageDict.TryGetValue(type, out var typeAmount) && typeAmount > 0)
{
// If damage types are allowed to belong to more than one damage group,
// they may appear twice here. Mark them as duplicate.
if (shownTypes.Contains(type))
continue;
shownTypes.Add(type);
var damageString = Loc.GetString(
"health-analyzer-window-damage-type-text",
("damageType", Loc.GetString("health-analyzer-window-damage-type-" + type)),
("amount", typeAmount)
);
groupContainer.AddChild(CreateDiagnosticItemLabel(damageString.Insert(0, "- ")));
}
}
}
}
private Texture GetTexture(string texture)
{
var rsiPath = new ResPath("/Textures/Objects/Devices/health_analyzer.rsi");
var rsiSprite = new SpriteSpecifier.Rsi(rsiPath, texture);
var rsi = _cache.GetResource<RSIResource>(rsiSprite.RsiPath).RSI;
if (!rsi.TryGetState(rsiSprite.RsiState, out var state))
{
rsiSprite = new SpriteSpecifier.Rsi(rsiPath, "unknown");
}
return _spriteSystem.Frame0(rsiSprite);
}
private static Label CreateDiagnosticItemLabel(string text)
{
return new Label
{
Margin = new Thickness(2, 2),
Text = text,
};
}
private BoxContainer CreateDiagnosticGroupTitle(string text, string id, int damageAmount)
{
var rootContainer = new BoxContainer
{
VerticalAlignment = VAlignment.Bottom,
Orientation = BoxContainer.LayoutOrientation.Horizontal
};
rootContainer.AddChild(new TextureRect
{
Margin = new Thickness(0, 3),
SetSize = new Vector2(30, 30),
Texture = GetTexture(id.ToLower())
});
rootContainer.AddChild(CreateDiagnosticItemLabel(text));
return rootContainer;
}
}
}

View file

@ -3,8 +3,8 @@ using Content.Shared.Damage;
using Content.Shared.GameTicking;
using Content.Shared.Mobs.Components;
using JetBrains.Annotations;
using Robust.Client.GameObjects;
using Robust.Client.Graphics;
using Robust.Client.Player;
namespace Content.Client.HealthOverlay
{
@ -13,9 +13,9 @@ namespace Content.Client.HealthOverlay
{
[Dependency] private readonly IEyeManager _eyeManager = default!;
[Dependency] private readonly IEntityManager _entities = default!;
[Dependency] private readonly IPlayerManager _player = default!;
private readonly Dictionary<EntityUid, HealthOverlayGui> _guis = new();
private EntityUid? _attachedEntity;
private bool _enabled;
public bool Enabled
@ -42,7 +42,6 @@ namespace Content.Client.HealthOverlay
base.Initialize();
SubscribeNetworkEvent<RoundRestartCleanupEvent>(Reset);
SubscribeLocalEvent<PlayerAttachSysMessage>(HandlePlayerAttached);
}
public void Reset(RoundRestartCleanupEvent ev)
@ -53,12 +52,6 @@ namespace Content.Client.HealthOverlay
}
_guis.Clear();
_attachedEntity = default;
}
private void HandlePlayerAttached(PlayerAttachSysMessage message)
{
_attachedEntity = message.AttachedEntity;
}
public override void FrameUpdate(float frameTime)
@ -70,7 +63,7 @@ namespace Content.Client.HealthOverlay
return;
}
if (_attachedEntity is not {} ent || Deleted(ent))
if (_player.LocalEntity is not {} ent || Deleted(ent))
{
return;
}

View file

@ -10,7 +10,6 @@ using Content.Shared.Inventory;
using Content.Shared.Inventory.Events;
using Content.Shared.Storage;
using JetBrains.Annotations;
using Robust.Client.GameObjects;
using Robust.Client.Player;
using Robust.Client.UserInterface;
using Robust.Shared.Containers;
@ -43,8 +42,8 @@ namespace Content.Client.Inventory
UpdatesOutsidePrediction = true;
base.Initialize();
SubscribeLocalEvent<InventorySlotsComponent, PlayerAttachedEvent>(OnPlayerAttached);
SubscribeLocalEvent<InventorySlotsComponent, PlayerDetachedEvent>(OnPlayerDetached);
SubscribeLocalEvent<InventorySlotsComponent, LocalPlayerAttachedEvent>(OnPlayerAttached);
SubscribeLocalEvent<InventorySlotsComponent, LocalPlayerDetachedEvent>(OnPlayerDetached);
SubscribeLocalEvent<InventoryComponent, ComponentShutdown>(OnShutdown);
@ -113,12 +112,12 @@ namespace Content.Client.Inventory
OnUnlinkInventory?.Invoke();
}
private void OnPlayerDetached(EntityUid uid, InventorySlotsComponent component, PlayerDetachedEvent args)
private void OnPlayerDetached(EntityUid uid, InventorySlotsComponent component, LocalPlayerDetachedEvent args)
{
OnUnlinkInventory?.Invoke();
}
private void OnPlayerAttached(EntityUid uid, InventorySlotsComponent component, PlayerAttachedEvent args)
private void OnPlayerAttached(EntityUid uid, InventorySlotsComponent component, LocalPlayerAttachedEvent args)
{
if (TryGetSlots(uid, out var definitions))
{

View file

@ -4,4 +4,24 @@ namespace Content.Client.Mind;
public sealed class MindSystem : SharedMindSystem
{
public override void Initialize()
{
base.Initialize();
SubscribeLocalEvent<MindComponent, AfterAutoHandleStateEvent>(OnHandleState);
}
private void OnHandleState(EntityUid uid, MindComponent component, ref AfterAutoHandleStateEvent args)
{
// Because minds are generally not networked, there might be weird situations were a client thinks multiple
// users share a mind? E.g., if an admin periodical gets sent all minds via some PVS override, but doesn't get
// sent intermediate states? Not sure if this is actually possible, but better to be safe.
foreach (var (user, mind) in UserMinds)
{
if (mind == uid)
UserMinds.Remove(user);
}
if (component.UserId != null)
UserMinds[component.UserId.Value] = uid;
}
}

View file

@ -1,7 +1,6 @@
using Content.Shared.GameTicking;
using Content.Shared.Inventory;
using Content.Shared.Inventory.Events;
using Robust.Client.GameObjects;
using Robust.Client.Player;
namespace Content.Client.Overlays;
@ -24,8 +23,8 @@ public abstract class EquipmentHudSystem<T> : EntitySystem where T : IComponent
SubscribeLocalEvent<T, ComponentStartup>(OnStartup);
SubscribeLocalEvent<T, ComponentRemove>(OnRemove);
SubscribeLocalEvent<PlayerAttachedEvent>(OnPlayerAttached);
SubscribeLocalEvent<PlayerDetachedEvent>(OnPlayerDetached);
SubscribeLocalEvent<LocalPlayerAttachedEvent>(OnPlayerAttached);
SubscribeLocalEvent<LocalPlayerDetachedEvent>(OnPlayerDetached);
SubscribeLocalEvent<T, GotEquippedEvent>(OnCompEquip);
SubscribeLocalEvent<T, GotUnequippedEvent>(OnCompUnequip);
@ -65,12 +64,12 @@ public abstract class EquipmentHudSystem<T> : EntitySystem where T : IComponent
RefreshOverlay(uid);
}
private void OnPlayerAttached(PlayerAttachedEvent args)
private void OnPlayerAttached(LocalPlayerAttachedEvent args)
{
RefreshOverlay(args.Entity);
}
private void OnPlayerDetached(PlayerDetachedEvent args)
private void OnPlayerDetached(LocalPlayerDetachedEvent args)
{
if (_player.LocalPlayer?.ControlledEntity == null)
Deactivate();

View file

@ -1,7 +1,6 @@
using Content.Shared.Movement.Components;
using Content.Shared.Movement.Systems;
using Content.Shared.Pulling.Components;
using Robust.Client.GameObjects;
using Robust.Client.Physics;
using Robust.Client.Player;
using Robust.Shared.Physics.Components;
@ -17,10 +16,10 @@ namespace Content.Client.Physics.Controllers
public override void Initialize()
{
base.Initialize();
SubscribeLocalEvent<RelayInputMoverComponent, PlayerAttachedEvent>(OnRelayPlayerAttached);
SubscribeLocalEvent<RelayInputMoverComponent, PlayerDetachedEvent>(OnRelayPlayerDetached);
SubscribeLocalEvent<InputMoverComponent, PlayerAttachedEvent>(OnPlayerAttached);
SubscribeLocalEvent<InputMoverComponent, PlayerDetachedEvent>(OnPlayerDetached);
SubscribeLocalEvent<RelayInputMoverComponent, LocalPlayerAttachedEvent>(OnRelayPlayerAttached);
SubscribeLocalEvent<RelayInputMoverComponent, LocalPlayerDetachedEvent>(OnRelayPlayerDetached);
SubscribeLocalEvent<InputMoverComponent, LocalPlayerAttachedEvent>(OnPlayerAttached);
SubscribeLocalEvent<InputMoverComponent, LocalPlayerDetachedEvent>(OnPlayerDetached);
SubscribeLocalEvent<InputMoverComponent, UpdateIsPredictedEvent>(OnUpdatePredicted);
SubscribeLocalEvent<MovementRelayTargetComponent, UpdateIsPredictedEvent>(OnUpdateRelayTargetPredicted);
@ -54,7 +53,7 @@ namespace Content.Client.Physics.Controllers
// What if the entity is being pulled by a vehicle controlled by the player?
}
private void OnRelayPlayerAttached(EntityUid uid, RelayInputMoverComponent component, PlayerAttachedEvent args)
private void OnRelayPlayerAttached(EntityUid uid, RelayInputMoverComponent component, LocalPlayerAttachedEvent args)
{
Physics.UpdateIsPredicted(uid);
Physics.UpdateIsPredicted(component.RelayEntity);
@ -62,7 +61,7 @@ namespace Content.Client.Physics.Controllers
SetMoveInput(inputMover, MoveButtons.None);
}
private void OnRelayPlayerDetached(EntityUid uid, RelayInputMoverComponent component, PlayerDetachedEvent args)
private void OnRelayPlayerDetached(EntityUid uid, RelayInputMoverComponent component, LocalPlayerDetachedEvent args)
{
Physics.UpdateIsPredicted(uid);
Physics.UpdateIsPredicted(component.RelayEntity);
@ -70,12 +69,12 @@ namespace Content.Client.Physics.Controllers
SetMoveInput(inputMover, MoveButtons.None);
}
private void OnPlayerAttached(EntityUid uid, InputMoverComponent component, PlayerAttachedEvent args)
private void OnPlayerAttached(EntityUid uid, InputMoverComponent component, LocalPlayerAttachedEvent args)
{
SetMoveInput(component, MoveButtons.None);
}
private void OnPlayerDetached(EntityUid uid, InputMoverComponent component, PlayerDetachedEvent args)
private void OnPlayerDetached(EntityUid uid, InputMoverComponent component, LocalPlayerDetachedEvent args)
{
SetMoveInput(component, MoveButtons.None);
}

View file

@ -1,11 +1,11 @@
using Content.Shared.Players;
using Robust.Shared.Players;
using Robust.Shared.Player;
namespace Content.Client.Players;
public sealed class PlayerSystem : SharedPlayerSystem
{
public override PlayerData? ContentData(ICommonSession? session)
public override ContentPlayerData? ContentData(ICommonSession? session)
{
return null;
}

View file

@ -9,7 +9,6 @@ using Robust.Client.UserInterface;
using Robust.Shared.Configuration;
using Robust.Shared.Map;
using Robust.Shared.Player;
using Robust.Shared.Players;
using Robust.Shared.Prototypes;
using Robust.Shared.Replays;
using Robust.Shared.Timing;

View file

@ -14,6 +14,7 @@ public sealed partial class GeneratorWindow : FancyWindow
[Dependency] private readonly IEntityManager _entityManager = default!;
[Dependency] private readonly ILocalizationManager _loc = default!;
private readonly SharedPowerSwitchableSystem _switchable;
private readonly FuelGeneratorComponent? _component;
private PortableGeneratorComponentBuiState? _lastState;
@ -24,6 +25,7 @@ public sealed partial class GeneratorWindow : FancyWindow
IoCManager.InjectDependencies(this);
_entityManager.TryGetComponent(entity, out _component);
_switchable = _entityManager.System<SharedPowerSwitchableSystem>();
EntityView.SetEntity(entity);
TargetPower.IsValid += IsValid;
@ -99,17 +101,16 @@ public sealed partial class GeneratorWindow : FancyWindow
StatusLabel.SetOnlyStyleClass("Danger");
}
var canSwitch = _entityManager.TryGetComponent(_entity, out PowerSwitchableGeneratorComponent? switchable);
var canSwitch = _entityManager.TryGetComponent(_entity, out PowerSwitchableComponent? switchable);
OutputSwitchLabel.Visible = canSwitch;
OutputSwitchButton.Visible = canSwitch;
if (canSwitch)
if (switchable != null)
{
var isHV = switchable!.ActiveOutput == PowerSwitchableGeneratorOutput.HV;
OutputSwitchLabel.Text =
Loc.GetString(isHV ? "portable-generator-ui-switch-hv" : "portable-generator-ui-switch-mv");
OutputSwitchButton.Text =
Loc.GetString(isHV ? "portable-generator-ui-switch-to-mv" : "portable-generator-ui-switch-to-hv");
var voltage = _switchable.VoltageString(_switchable.GetVoltage(_entity, switchable));
OutputSwitchLabel.Text = Loc.GetString("portable-generator-ui-current-output", ("voltage", voltage));
var nextVoltage = _switchable.VoltageString(_switchable.GetNextVoltage(_entity, switchable));
OutputSwitchButton.Text = Loc.GetString("power-switchable-switch-voltage", ("voltage", nextVoltage));
OutputSwitchButton.Disabled = state.On;
}

View file

@ -0,0 +1,7 @@
using Content.Shared.Power.Generator;
namespace Content.Client.Power.Generator;
public sealed class PowerSwitchableSystem : SharedPowerSwitchableSystem
{
}

View file

@ -2,7 +2,7 @@ using Content.Shared.Movement.Components;
using Robust.Shared.Input;
using Robust.Shared.Input.Binding;
using Robust.Shared.Map;
using Robust.Shared.Players;
using Robust.Shared.Player;
namespace Content.Client.Replay.Spectator;

View file

@ -1,5 +1,5 @@
using Content.Shared.Movement.Components;
using Robust.Client.GameObjects;
using Robust.Client.Player;
using Robust.Shared.Map;
using Robust.Shared.Map.Components;
using Robust.Shared.Network;
@ -79,7 +79,7 @@ public sealed partial class ReplaySpectatorSystem
public void SetSpectatorPosition(SpectatorData data)
{
if (_player.LocalPlayer == null)
if (_player.LocalSession == null)
return;
if (data.Controller != null
@ -87,13 +87,13 @@ public sealed partial class ReplaySpectatorSystem
&& Exists(session.AttachedEntity)
&& Transform(session.AttachedEntity.Value).MapID != MapId.Nullspace)
{
_player.LocalPlayer.AttachEntity(session.AttachedEntity.Value, EntityManager, _client);
_player.SetAttachedEntity(_player.LocalSession, session.AttachedEntity);
return;
}
if (Exists(data.Entity) && Transform(data.Entity).MapID != MapId.Nullspace)
{
_player.LocalPlayer.AttachEntity(data.Entity, EntityManager, _client);
_player.SetAttachedEntity(_player.LocalSession, data.Entity);
return;
}
@ -118,7 +118,7 @@ public sealed partial class ReplaySpectatorSystem
return;
}
if (data.Eye != null && TryComp(_player.LocalPlayer.ControlledEntity, out InputMoverComponent? newMover))
if (data.Eye != null && TryComp(_player.LocalSession.AttachedEntity, out InputMoverComponent? newMover))
{
newMover.RelativeEntity = data.Eye.Value.Ent;
newMover.TargetRelativeRotation = newMover.RelativeRotation = data.Eye.Value.Rot;
@ -177,7 +177,7 @@ public sealed partial class ReplaySpectatorSystem
SetSpectatorPosition(default);
}
private void OnDetached(EntityUid uid, ReplaySpectatorComponent component, PlayerDetachedEvent args)
private void OnDetached(EntityUid uid, ReplaySpectatorComponent component, LocalPlayerDetachedEvent args)
{
if (IsClientSide(uid))
QueueDel(uid);

View file

@ -32,10 +32,10 @@ public sealed partial class ReplaySpectatorSystem
public void SpectateEntity(EntityUid target)
{
if (_player.LocalPlayer == null)
if (_player.LocalSession == null)
return;
var old = _player.LocalPlayer.ControlledEntity;
var old = _player.LocalSession.AttachedEntity;
if (old == target)
{
@ -44,7 +44,7 @@ public sealed partial class ReplaySpectatorSystem
return;
}
_player.LocalPlayer.AttachEntity(target, EntityManager, _client);
_player.SetAttachedEntity(_player.LocalSession, target);
EnsureComp<ReplaySpectatorComponent>(target);
_stateMan.RequestStateChange<ReplaySpectateEntityState>();
@ -59,10 +59,10 @@ public sealed partial class ReplaySpectatorSystem
public TransformComponent SpawnSpectatorGhost(EntityCoordinates coords, bool gridAttach)
{
if (_player.LocalPlayer == null)
if (_player.LocalSession == null)
throw new InvalidOperationException();
var old = _player.LocalPlayer.ControlledEntity;
var old = _player.LocalSession.AttachedEntity;
var ent = Spawn("ReplayObserver", coords);
_eye.SetMaxZoom(ent, Vector2.One * 5);
@ -73,7 +73,7 @@ public sealed partial class ReplaySpectatorSystem
if (gridAttach)
_transform.AttachToGridOrMap(ent);
_player.LocalPlayer.AttachEntity(ent, EntityManager, _client);
_player.SetAttachedEntity(_player.LocalSession, ent);
if (old != null)
{
@ -93,7 +93,7 @@ public sealed partial class ReplaySpectatorSystem
{
if (args.Length == 0)
{
if (_player.LocalPlayer?.ControlledEntity is { } current)
if (_player.LocalSession?.AttachedEntity is { } current)
SpawnSpectatorGhost(new EntityCoordinates(current, default), true);
else
SpawnSpectatorGhost(default, true);

View file

@ -6,7 +6,6 @@ using Robust.Client.Player;
using Robust.Client.Replays.Playback;
using Robust.Client.State;
using Robust.Shared.Console;
using Robust.Shared.Network;
using Robust.Shared.Serialization.Markdown.Mapping;
namespace Content.Client.Replay.Spectator;
@ -40,7 +39,7 @@ public sealed partial class ReplaySpectatorSystem : EntitySystem
SubscribeLocalEvent<GetVerbsEvent<AlternativeVerb>>(OnGetAlternativeVerbs);
SubscribeLocalEvent<ReplaySpectatorComponent, EntityTerminatingEvent>(OnTerminating);
SubscribeLocalEvent<ReplaySpectatorComponent, PlayerDetachedEvent>(OnDetached);
SubscribeLocalEvent<ReplaySpectatorComponent, LocalPlayerDetachedEvent>(OnDetached);
SubscribeLocalEvent<ReplaySpectatorComponent, EntParentChangedMessage>(OnParentChanged);
InitializeBlockers();

View file

@ -5,7 +5,7 @@ using Robust.Client.Console;
using Robust.Client.Placement;
using Robust.Client.Placement.Modes;
using Robust.Shared.Map;
using Robust.Shared.Players;
using Robust.Shared.Player;
namespace Content.Client.Sandbox
{

View file

@ -89,7 +89,7 @@ public class DockingControl : Control
// Draw the fixtures around the dock before drawing it
if (_entManager.TryGetComponent<FixturesComponent>(GridEntity, out var fixtures))
{
foreach (var (_, fixture) in fixtures.Fixtures)
foreach (var fixture in fixtures.Fixtures.Values)
{
var poly = (PolygonShape) fixture.Shape;
@ -151,7 +151,7 @@ public class DockingControl : Control
var xformQuery = _entManager.GetEntityQuery<TransformComponent>();
_grids.Clear();
_mapManager.FindGridsIntersecting(gridXform.MapID, new Box2(worldPos - RangeVector, worldPos + RangeVector));
_mapManager.FindGridsIntersecting(gridXform.MapID, new Box2(worldPos - RangeVector, worldPos + RangeVector), ref _grids);
foreach (var grid in _grids)
{

View file

@ -61,9 +61,9 @@ namespace Content.Client.Storage
_window?.BuildEntityList(uid, component);
}
public void InteractWithItem(BaseButton.ButtonEventArgs args, ListData cData)
public void InteractWithItem(BaseButton.ButtonEventArgs? args, ListData? cData)
{
if (cData is not EntityListData { Uid: var entity })
if (args == null || cData is not EntityListData { Uid: var entity })
return;
if (args.Event.Function == EngineKeyFunctions.UIClick)

View file

@ -5,6 +5,7 @@ using Content.Shared.Tools;
using Content.Shared.Tools.Components;
using Robust.Client.GameObjects;
using Robust.Shared.GameStates;
using SharedToolSystem = Content.Shared.Tools.Systems.SharedToolSystem;
namespace Content.Client.Tools
{

View file

@ -1,8 +1,6 @@
using System.Numerics;
using Content.Shared.Traits.Assorted;
using Content.Client.Camera;
using Robust.Shared.Random;
using Robust.Client.GameObjects;
using Robust.Client.Player;
using Robust.Shared.Timing;
@ -19,7 +17,7 @@ public sealed class ParacusiaSystem : SharedParacusiaSystem
{
base.Initialize();
SubscribeLocalEvent<ParacusiaComponent, ComponentStartup>(OnComponentStartup);
SubscribeLocalEvent<ParacusiaComponent, PlayerDetachedEvent>(OnPlayerDetach);
SubscribeLocalEvent<ParacusiaComponent, LocalPlayerDetachedEvent>(OnPlayerDetach);
}
public override void Update(float frameTime)
@ -40,7 +38,7 @@ public sealed class ParacusiaSystem : SharedParacusiaSystem
component.NextIncidentTime = _timing.CurTime + TimeSpan.FromSeconds(_random.NextFloat(component.MinTimeBetweenIncidents, component.MaxTimeBetweenIncidents));
}
private void OnPlayerDetach(EntityUid uid, ParacusiaComponent component, PlayerDetachedEvent args)
private void OnPlayerDetach(EntityUid uid, ParacusiaComponent component, LocalPlayerDetachedEvent args)
{
component.Stream?.Stop();
}

View file

@ -22,7 +22,7 @@ public sealed class ListContainer : Control
}
public bool Toggle { get; set; }
public Action<ListData, ListContainerButton>? GenerateItem;
public Action<BaseButton.ButtonEventArgs, ListData>? ItemPressed;
public Action<BaseButton.ButtonEventArgs?, ListData?>? ItemPressed;
public IReadOnlyList<ListData> Data => _data;
private const int DefaultSeparation = 3;
@ -92,6 +92,12 @@ public sealed class ListContainer : Control
_data = data.ToList();
_updateChildren = true;
InvalidateArrange();
if (_selected != null && !data.Contains(_selected))
{
_selected = null;
ItemPressed?.Invoke(null, null);
}
}
public void DirtyList()

View file

@ -8,6 +8,7 @@ using Content.Client.UserInterface.Systems.Objectives.Controls;
using Content.Shared.Input;
using JetBrains.Annotations;
using Robust.Client.GameObjects;
using Robust.Client.Player;
using Robust.Client.UserInterface;
using Robust.Client.UserInterface.Controllers;
using Robust.Client.UserInterface.Controls;
@ -21,6 +22,7 @@ namespace Content.Client.UserInterface.Systems.Character;
[UsedImplicitly]
public sealed class CharacterUIController : UIController, IOnStateEntered<GameplayState>, IOnStateExited<GameplayState>, IOnSystemChanged<CharacterInfoSystem>
{
[Dependency] private readonly IPlayerManager _player = default!;
[UISystemDependency] private readonly CharacterInfoSystem _characterInfo = default!;
[UISystemDependency] private readonly SpriteSystem _sprite = default!;
@ -56,13 +58,13 @@ public sealed class CharacterUIController : UIController, IOnStateEntered<Gamepl
public void OnSystemLoaded(CharacterInfoSystem system)
{
system.OnCharacterUpdate += CharacterUpdated;
system.OnCharacterDetached += CharacterDetached;
_player.LocalPlayerDetached += CharacterDetached;
}
public void OnSystemUnloaded(CharacterInfoSystem system)
{
system.OnCharacterUpdate -= CharacterUpdated;
system.OnCharacterDetached -= CharacterDetached;
_player.LocalPlayerDetached -= CharacterDetached;
}
public void UnloadButton()
@ -160,7 +162,7 @@ public sealed class CharacterUIController : UIController, IOnStateEntered<Gamepl
_window.RolePlaceholder.Visible = briefing == null && !controls.Any() && !objectives.Any();
}
private void CharacterDetached()
private void CharacterDetached(EntityUid uid)
{
CloseWindow();
}

View file

@ -162,7 +162,8 @@ public sealed class ChatUIController : UIController
_sawmill = Logger.GetSawmill("chat");
_sawmill.Level = LogLevel.Info;
_admin.AdminStatusUpdated += UpdateChannelPermissions;
_player.LocalPlayerChanged += OnLocalPlayerChanged;
_player.LocalPlayerAttached += OnAttachedChanged;
_player.LocalPlayerDetached += OnAttachedChanged;
_state.OnStateChanged += StateChanged;
_net.RegisterNetMessage<MsgChatMessage>(OnChatMessage);
_net.RegisterNetMessage<MsgDeleteChatMessagesBy>(OnDeleteChatMessagesBy);
@ -170,7 +171,7 @@ public sealed class ChatUIController : UIController
_speechBubbleRoot = new LayoutContainer();
OnLocalPlayerChanged(new LocalPlayerChangedEventArgs(null, _player.LocalPlayer));
UpdateChannelPermissions();
_input.SetInputCommand(ContentKeyFunctions.FocusChat,
InputCmdHandler.FromDelegate(_ => FocusChat()));
@ -363,29 +364,7 @@ public sealed class ChatUIController : UIController
_speechBubbleRoot.SetPositionLast();
}
private void OnLocalPlayerChanged(LocalPlayerChangedEventArgs obj)
{
if (obj.OldPlayer != null)
{
obj.OldPlayer.EntityAttached -= OnLocalPlayerEntityAttached;
obj.OldPlayer.EntityDetached -= OnLocalPlayerEntityDetached;
}
if (obj.NewPlayer != null)
{
obj.NewPlayer.EntityAttached += OnLocalPlayerEntityAttached;
obj.NewPlayer.EntityDetached += OnLocalPlayerEntityDetached;
}
UpdateChannelPermissions();
}
private void OnLocalPlayerEntityAttached(EntityAttachedEventArgs obj)
{
UpdateChannelPermissions();
}
private void OnLocalPlayerEntityDetached(EntityDetachedEventArgs obj)
private void OnAttachedChanged(EntityUid uid)
{
UpdateChannelPermissions();
}

View file

@ -1,11 +1,9 @@
using Content.Client.Alerts;
using Content.Shared.Damage;
using Content.Shared.FixedPoint;
using Content.Shared.Mobs;
using Content.Shared.Mobs.Components;
using Content.Shared.Mobs.Systems;
using JetBrains.Annotations;
using Robust.Client.GameObjects;
using Robust.Client.Graphics;
using Robust.Client.Player;
using Robust.Client.UserInterface;
@ -25,13 +23,13 @@ public sealed class DamageOverlayUiController : UIController
public override void Initialize()
{
_overlay = new Overlays.DamageOverlay();
SubscribeLocalEvent<PlayerAttachedEvent>(OnPlayerAttach);
SubscribeLocalEvent<PlayerDetachedEvent>(OnPlayerDetached);
SubscribeLocalEvent<LocalPlayerAttachedEvent>(OnPlayerAttach);
SubscribeLocalEvent<LocalPlayerDetachedEvent>(OnPlayerDetached);
SubscribeLocalEvent<MobStateChangedEvent>(OnMobStateChanged);
SubscribeLocalEvent<MobThresholdChecked>(OnThresholdCheck);
}
private void OnPlayerAttach(PlayerAttachedEvent args)
private void OnPlayerAttach(LocalPlayerAttachedEvent args)
{
ClearOverlay();
if (!EntityManager.TryGetComponent<MobStateComponent>(args.Entity, out var mobState))
@ -41,7 +39,7 @@ public sealed class DamageOverlayUiController : UIController
_overlayManager.AddOverlay(_overlay);
}
private void OnPlayerDetached(PlayerDetachedEvent args)
private void OnPlayerDetached(LocalPlayerDetachedEvent args)
{
_overlayManager.RemoveOverlay(_overlay);
ClearOverlay();

View file

@ -17,7 +17,7 @@ using Robust.Client.UserInterface.Controllers;
using Robust.Client.UserInterface.Controllers.Implementations;
using Robust.Shared.Input.Binding;
using Robust.Shared.Map;
using Robust.Shared.Players;
using Robust.Shared.Player;
using Robust.Shared.Utility;
using static Robust.Client.UserInterface.Controls.BaseButton;

View file

@ -1,6 +1,6 @@
<DefaultWindow xmlns="https://spacestation14.io">
<BoxContainer Orientation="Vertical">
<LineEdit Name="SearchBar" PlaceHolder="{Loc 'vending-machine-component-search-filter'}" HorizontalExpand="True" Margin ="0 4"/>
<LineEdit Name="SearchBar" PlaceHolder="{Loc 'vending-machine-component-search-filter'}" HorizontalExpand="True" Margin ="0 4" Access="Public"/>
<ItemList Name="VendingContents"
SizeFlagsStretchRatio="8"
VerticalExpand="True">

View file

@ -6,7 +6,6 @@ using Robust.Client.Graphics;
using Robust.Client.UserInterface.Controls;
using Robust.Client.UserInterface.CustomControls;
using Robust.Client.UserInterface.XAML;
using Robust.Shared.Graphics;
using Robust.Shared.Prototypes;
namespace Content.Client.VendingMachines.UI
@ -33,7 +32,6 @@ namespace Content.Client.VendingMachines.UI
VendingContents.OnItemSelected += args =>
{
SearchBar.Text = string.Empty;
OnItemSelected?.Invoke(args);
};
}
@ -42,8 +40,10 @@ namespace Content.Client.VendingMachines.UI
/// Populates the list of available items on the vending machine interface
/// and sets icons based on their prototypes
/// </summary>
public void Populate(List<VendingMachineInventoryEntry> inventory, string? filter = null)
public void Populate(List<VendingMachineInventoryEntry> inventory, out List<int> filteredInventory, string? filter = null)
{
filteredInventory = new();
if (inventory.Count == 0)
{
VendingContents.Clear();
@ -94,6 +94,7 @@ namespace Content.Client.VendingMachines.UI
vendingItem.Text = $"{itemName} [{entry.Amount}]";
vendingItem.Icon = icon;
filteredInventory.Add(i);
}
SetSizeAfterUpdate(longestEntry.Length, inventory.Count);

View file

@ -1,6 +1,5 @@
using Content.Client.VendingMachines.UI;
using Content.Shared.VendingMachines;
using Robust.Client.GameObjects;
using Robust.Client.UserInterface.Controls;
using System.Linq;
@ -14,6 +13,9 @@ namespace Content.Client.VendingMachines
[ViewVariables]
private List<VendingMachineInventoryEntry> _cachedInventory = new();
[ViewVariables]
private List<int> _cachedFilteredIndex = new();
public VendingMachineBoundUserInterface(EntityUid owner, Enum uiKey) : base(owner, uiKey)
{
}
@ -32,7 +34,7 @@ namespace Content.Client.VendingMachines
_menu.OnItemSelected += OnItemSelected;
_menu.OnSearchChanged += OnSearchChanged;
_menu.Populate(_cachedInventory);
_menu.Populate(_cachedInventory, out _cachedFilteredIndex);
_menu.OpenCentered();
}
@ -46,7 +48,7 @@ namespace Content.Client.VendingMachines
_cachedInventory = newState.Inventory;
_menu?.Populate(_cachedInventory);
_menu?.Populate(_cachedInventory, out _cachedFilteredIndex, _menu.SearchBar.Text);
}
private void OnItemSelected(ItemList.ItemListSelectedEventArgs args)
@ -54,7 +56,7 @@ namespace Content.Client.VendingMachines
if (_cachedInventory.Count == 0)
return;
var selectedItem = _cachedInventory.ElementAtOrDefault(args.ItemIndex);
var selectedItem = _cachedInventory.ElementAtOrDefault(_cachedFilteredIndex.ElementAtOrDefault(args.ItemIndex));
if (selectedItem == null)
return;
@ -78,7 +80,7 @@ namespace Content.Client.VendingMachines
private void OnSearchChanged(string? filter)
{
_menu?.Populate(_cachedInventory, filter);
_menu?.Populate(_cachedInventory, out _cachedFilteredIndex, filter);
}
}
}

View file

@ -16,7 +16,8 @@ using Robust.Client.State;
using Robust.Shared.Input;
using Robust.Shared.Map;
using Robust.Shared.Player;
using Robust.Shared.Players;
using Robust.Shared.Prototypes;
using Robust.Shared.Timing;
namespace Content.Client.Weapons.Melee;

View file

@ -3,13 +3,11 @@ using System.Collections.Generic;
using System.IO;
using System.Linq;
using Content.Server.GameTicking;
using Content.Server.Players;
using Content.Shared.Mind;
using Content.Shared.Players;
using Robust.Server.Player;
using Robust.Shared.GameObjects;
using Robust.Shared.IoC;
using Robust.Shared.Network;
using Robust.Shared.Player;
using Robust.Shared.Timing;
using Robust.UnitTesting;
@ -30,8 +28,8 @@ public sealed partial class TestPair
public RobustIntegrationTest.ServerIntegrationInstance Server { get; private set; } = default!;
public RobustIntegrationTest.ClientIntegrationInstance Client { get; private set; } = default!;
public IPlayerSession? Player => (IPlayerSession?) Server.PlayerMan.Sessions.FirstOrDefault();
public PlayerData? PlayerData => Player?.Data.ContentData();
public ICommonSession? Player => Server.PlayerMan.Sessions.FirstOrDefault();
public ContentPlayerData? PlayerData => Player?.Data.ContentData();
public PoolTestLogHandler ServerLogHandler { get; private set; } = default!;
public PoolTestLogHandler ClientLogHandler { get; private set; } = default!;

View file

@ -3,8 +3,6 @@ using Content.Shared.Actions;
using Content.Shared.CombatMode;
using Robust.Server.Player;
using Robust.Shared.GameObjects;
using Robust.Shared.Players;
using PlayerManager = Robust.Client.Player.PlayerManager;
namespace Content.IntegrationTests.Tests.Actions;
@ -26,7 +24,7 @@ public sealed class ActionsAddedTest
var sEntMan = server.ResolveDependency<IEntityManager>();
var cEntMan = client.ResolveDependency<IEntityManager>();
var clientSession = client.ResolveDependency<Robust.Client.Player.IPlayerManager>().LocalPlayer?.Session;
var serverSession = server.ResolveDependency<IPlayerManager>().ServerSessions.Single();
var serverSession = server.ResolveDependency<IPlayerManager>().Sessions.Single();
var sActionSystem = server.System<SharedActionsSystem>();
var cActionSystem = client.System<SharedActionsSystem>();

View file

@ -7,8 +7,6 @@ using Content.Shared.Administration.Logs;
using Content.Shared.Database;
using Robust.Server.Player;
using Robust.Shared.GameObjects;
using Robust.Shared.Map;
using Robust.Shared.Utility;
namespace Content.IntegrationTests.Tests.Administration.Logs;
@ -177,7 +175,7 @@ public sealed class AddTests
await server.WaitPost(() =>
{
var player = sPlayers.ServerSessions.First();
var player = sPlayers.Sessions.First();
playerGuid = player.UserId;
Assert.DoesNotThrow(() =>
@ -280,7 +278,7 @@ public sealed class AddTests
await server.WaitPost(() =>
{
var player = sPlayers.ServerSessions.Single();
var player = sPlayers.Sessions.Single();
sAdminLogSystem.Add(LogType.Unknown, $"{player} {player} test log: {guid}");
});
@ -318,7 +316,7 @@ public sealed class AddTests
await server.WaitPost(() =>
{
var player = sPlayers.ServerSessions.Single();
var player = sPlayers.Sessions.Single();
sAdminLogSystem.Add(LogType.Unknown, $"{player:first} {player:second} test log: {guid}");
});

View file

@ -5,6 +5,7 @@ using Content.Server.GameTicking;
using Content.Shared.Database;
using Robust.Server.Player;
using Robust.Shared.GameObjects;
using Robust.Shared.Player;
namespace Content.IntegrationTests.Tests.Administration.Logs;
@ -27,11 +28,11 @@ public sealed class QueryTests
var date = DateTime.UtcNow;
var guid = Guid.NewGuid();
IPlayerSession player = default;
ICommonSession player = default;
await server.WaitPost(() =>
{
player = sPlayers.ServerSessions.First();
player = sPlayers.Sessions.First();
sAdminLogSystem.Add(LogType.Unknown, $"{player.AttachedEntity:Entity} test log: {guid}");
});

View file

@ -25,7 +25,7 @@ public sealed class EuiManagerTest
await server.WaitAssertion(() =>
{
var clientSession = sPlayerManager.ServerSessions.Single();
var clientSession = sPlayerManager.Sessions.Single();
var ui = new AdminAnnounceEui();
eui.OpenEui(ui, clientSession);
});

View file

@ -14,6 +14,7 @@ using Content.Shared.Hands.Components;
using Content.Shared.Hands.EntitySystems;
using Content.Shared.Interaction;
using Content.Shared.Mind;
using Content.Shared.Players;
using Robust.Client.Input;
using Robust.Client.UserInterface;
using Robust.Server.GameObjects;
@ -21,7 +22,7 @@ using Robust.Server.Player;
using Robust.Shared.GameObjects;
using Robust.Shared.Log;
using Robust.Shared.Map;
using Robust.Shared.Players;
using Robust.Shared.Player;
using Robust.Shared.Prototypes;
using Robust.Shared.Timing;
using Robust.UnitTesting;
@ -67,7 +68,7 @@ public abstract partial class InteractionTest
protected NetEntity Player;
protected ICommonSession ClientSession = default!;
protected IPlayerSession ServerSession = default!;
protected ICommonSession ServerSession = default!;
public EntityUid? ClientTarget;

View file

@ -5,6 +5,7 @@ using Content.Server.Ghost.Roles.Components;
using Content.Server.Players;
using Content.Shared.Ghost;
using Content.Shared.Mind;
using Content.Shared.Players;
using Robust.Shared.Console;
using Robust.Shared.GameObjects;
using Robust.Shared.Map;
@ -43,7 +44,7 @@ public sealed class GhostRoleTests
var sPlayerMan = server.ResolveDependency<Robust.Server.Player.IPlayerManager>();
var conHost = client.ResolveDependency<IConsoleHost>();
var mindSystem = entMan.System<SharedMindSystem>();
var session = sPlayerMan.ServerSessions.Single();
var session = sPlayerMan.Sessions.Single();
var originalMindId = session.ContentData()!.Mind!.Value;
// Spawn player entity & attach

View file

@ -2,6 +2,7 @@ using System.Linq;
using Content.Server.Players;
using Content.Shared.Ghost;
using Content.Shared.Mind;
using Content.Shared.Players;
using Robust.Server.Console;
using Robust.Server.GameObjects;
using Robust.Server.Player;
@ -35,7 +36,7 @@ public sealed partial class MindTests
MindComponent mind = default!;
await server.WaitAssertion(() =>
{
var player = playerMan.ServerSessions.Single();
var player = playerMan.Sessions.Single();
playerEnt = entMan.SpawnEntity(null, MapCoordinates.Nullspace);
visitEnt = entMan.SpawnEntity(null, MapCoordinates.Nullspace);
@ -81,7 +82,7 @@ public sealed partial class MindTests
var entMan = server.ResolveDependency<IServerEntityManager>();
var mapManager = server.ResolveDependency<IMapManager>();
var playerMan = server.ResolveDependency<IPlayerManager>();
var player = playerMan.ServerSessions.Single();
var player = playerMan.Sessions.Single();
var mindSystem = entMan.EntitySysManager.GetEntitySystem<SharedMindSystem>();
@ -128,7 +129,7 @@ public sealed partial class MindTests
var entMan = server.ResolveDependency<IServerEntityManager>();
var playerMan = server.ResolveDependency<IPlayerManager>();
var player = playerMan.ServerSessions.Single();
var player = playerMan.Sessions.Single();
Assert.That(!entMan.HasComponent<GhostComponent>(player.AttachedEntity), "Player was initially a ghost?");
@ -162,7 +163,7 @@ public sealed partial class MindTests
var mindSystem = entMan.EntitySysManager.GetEntitySystem<SharedMindSystem>();
var mind = GetMind(pair);
var player = playerMan.ServerSessions.Single();
var player = playerMan.Sessions.Single();
#pragma warning disable NUnit2045 // Interdependent assertions.
Assert.That(player.AttachedEntity, Is.Not.Null);
Assert.That(entMan.EntityExists(player.AttachedEntity));
@ -218,7 +219,7 @@ public sealed partial class MindTests
var playerMan = server.ResolveDependency<IPlayerManager>();
var serverConsole = server.ResolveDependency<IServerConsoleHost>();
var player = playerMan.ServerSessions.Single();
var player = playerMan.Sessions.Single();
var ghost = await BecomeGhost(pair);
@ -263,7 +264,7 @@ public sealed partial class MindTests
var playerMan = server.ResolveDependency<IPlayerManager>();
var serverConsole = server.ResolveDependency<IServerConsoleHost>();
var player = playerMan.ServerSessions.Single();
var player = playerMan.Sessions.Single();
EntityUid ghost = default!;

View file

@ -1,14 +1,17 @@
using System.Linq;
using Content.IntegrationTests.Pair;
using Content.Server.Mind;
using Content.Server.Players;
using Content.Shared.Ghost;
using Content.Shared.Mind;
using Content.Shared.Players;
using Robust.Server.GameObjects;
using Robust.Server.Player;
using Robust.Shared.Enums;
using Robust.Shared.GameObjects;
using Robust.Shared.Map;
using Robust.Shared.Network;
using Robust.Shared.Player;
namespace Content.IntegrationTests.Tests.Minds;
@ -36,7 +39,7 @@ public sealed partial class MindTests
var playerMan = pair.Server.ResolveDependency<IPlayerManager>();
var mindSys = entMan.System<SharedMindSystem>();
var player = playerMan.ServerSessions.Single();
var player = playerMan.Sessions.Single();
EntityUid entity = default;
EntityUid mindId = default!;
@ -71,7 +74,7 @@ public sealed partial class MindTests
EntityUid mindId = default!;
MindComponent mind = default!;
var player = playerMan.ServerSessions.Single();
var player = playerMan.Sessions.Single();
await pair.Server.WaitAssertion(() =>
{
var oldUid = player.AttachedEntity;
@ -116,20 +119,25 @@ public sealed partial class MindTests
/// </summary>
private static (EntityUid Id, MindComponent Comp) GetMind(Pair.TestPair pair)
{
var playerMan = pair.Server.ResolveDependency<IPlayerManager>();
var entMan = pair.Server.ResolveDependency<IEntityManager>();
var player = playerMan.ServerSessions.SingleOrDefault();
var playerMan = pair.Server.PlayerMan;
var entMan = pair.Server.EntMan;
var player = playerMan.Sessions.SingleOrDefault();
Assert.That(player, Is.Not.Null);
var mindId = player.ContentData()!.Mind!.Value;
Assert.That(mindId, Is.Not.EqualTo(default(EntityUid)));
var mind = entMan.GetComponent<MindComponent>(mindId);
ActorComponent actor = default!;
Assert.Multiple(() =>
{
Assert.That(player, Is.EqualTo(mind.Session), "Player session does not match mind session");
Assert.That(entMan.System<MindSystem>().GetMind(player.UserId), Is.EqualTo(mindId));
Assert.That(player.AttachedEntity, Is.EqualTo(mind.CurrentEntity), "Player is not attached to the mind's current entity.");
Assert.That(entMan.EntityExists(mind.OwnedEntity), "The mind's current entity does not exist");
Assert.That(mind.VisitingEntity == null || entMan.EntityExists(mind.VisitingEntity), "The minds visited entity does not exist.");
Assert.That(entMan.TryGetComponent(mind.CurrentEntity, out actor));
});
Assert.That(actor.PlayerSession, Is.EqualTo(mind.Session));
return (mindId, mind);
}
@ -139,7 +147,7 @@ public sealed partial class MindTests
var netManager = pair.Client.ResolveDependency<IClientNetManager>();
var playerMan = pair.Server.ResolveDependency<IPlayerManager>();
var entMan = pair.Server.ResolveDependency<IEntityManager>();
var player = playerMan.ServerSessions.Single();
var player = playerMan.Sessions.Single();
var mindId = player.ContentData()!.Mind!.Value;
var mind = entMan.GetComponent<MindComponent>(mindId);
@ -161,21 +169,21 @@ public sealed partial class MindTests
{
var netManager = pair.Client.ResolveDependency<IClientNetManager>();
var playerMan = pair.Server.ResolveDependency<IPlayerManager>();
Assert.That(!playerMan.ServerSessions.Any());
Assert.That(!playerMan.Sessions.Any());
await Task.WhenAll(pair.Client.WaitIdleAsync(), pair.Client.WaitIdleAsync());
pair.Client.SetConnectTarget(pair.Server);
await pair.Client.WaitPost(() => netManager.ClientConnect(null!, 0, username));
await pair.RunTicksSync(5);
var player = playerMan.ServerSessions.Single();
var player = playerMan.Sessions.Single();
Assert.That(player.Status, Is.EqualTo(SessionStatus.InGame));
}
private static async Task<IPlayerSession> DisconnectReconnect(Pair.TestPair pair)
private static async Task<ICommonSession> DisconnectReconnect(Pair.TestPair pair)
{
var playerMan = pair.Server.ResolveDependency<IPlayerManager>();
var player = playerMan.ServerSessions.Single();
var player = playerMan.Sessions.Single();
var name = player.Name;
var id = player.UserId;
@ -183,7 +191,7 @@ public sealed partial class MindTests
await Connect(pair, name);
// Session has changed
var newSession = playerMan.ServerSessions.Single();
var newSession = playerMan.Sessions.Single();
Assert.Multiple(() =>
{
Assert.That(newSession, Is.Not.EqualTo(player));

View file

@ -1,6 +1,8 @@
using System.Linq;
using Content.Shared.Ghost;
using Content.Shared.Mind;
using NUnit.Framework.Interfaces;
using Robust.Server.GameObjects;
using Robust.Server.Player;
using Robust.Shared.GameObjects;
using Robust.Shared.Map;
@ -49,7 +51,7 @@ public sealed partial class MindTests
var mind = GetMind(pair);
var playerMan = pair.Server.ResolveDependency<IPlayerManager>();
var player = playerMan.ServerSessions.Single();
var player = playerMan.Sessions.Single();
var name = player.Name;
var user = player.UserId;
Assert.That(mind.Comp.OwnedEntity, Is.Not.Null);
@ -72,7 +74,7 @@ public sealed partial class MindTests
// Reconnect
await Connect(pair, name);
player = playerMan.ServerSessions.Single();
player = playerMan.Sessions.Single();
Assert.Multiple(() =>
{
Assert.That(user, Is.EqualTo(player.UserId));
@ -127,8 +129,10 @@ public sealed partial class MindTests
var mindSys = entMan.System<SharedMindSystem>();
var mind = GetMind(pair);
Assert.Null(mind.Comp.VisitingEntity);
// Make player visit a new mob
var original = mind.Comp.CurrentEntity;
var original = mind.Comp.OwnedEntity;
EntityUid visiting = default;
await pair.Server.WaitAssertion(() =>
{
@ -137,6 +141,7 @@ public sealed partial class MindTests
});
await pair.RunTicksSync(5);
Assert.That(mind.Comp.VisitingEntity, Is.EqualTo(visiting));
await DisconnectReconnect(pair);
// Player is back in control of the visited mob, mind was preserved
@ -150,4 +155,32 @@ public sealed partial class MindTests
await pair.CleanReturnAsync();
}
// This test will do the following
// - connect as a normal player
// - disconnect
// - reconnect
// - assert that they return to the original entity.
[Test]
public async Task TestReconnect()
{
await using var pair = await SetupPair();
var mind = GetMind(pair);
Assert.Null(mind.Comp.VisitingEntity);
Assert.NotNull(mind.Comp.OwnedEntity);
var entity = mind.Comp.OwnedEntity;
await pair.RunTicksSync(5);
await DisconnectReconnect(pair);
await pair.RunTicksSync(5);
var newMind = GetMind(pair);
Assert.Null(newMind.Comp.VisitingEntity);
Assert.That(newMind.Comp.OwnedEntity, Is.EqualTo(entity));
Assert.That(newMind.Id, Is.EqualTo(mind.Id));
await pair.CleanReturnAsync();
}
}

View file

@ -11,6 +11,7 @@ using Content.Shared.Damage.Prototypes;
using Content.Shared.FixedPoint;
using Content.Shared.Mind;
using Content.Shared.Mind.Components;
using Content.Shared.Players;
using Content.Shared.Roles;
using Content.Shared.Roles.Jobs;
using Robust.Server.Console;
@ -67,13 +68,12 @@ public sealed partial class MindTests
var entity = entMan.SpawnEntity(null, new MapCoordinates());
var mindComp = entMan.EnsureComponent<MindContainerComponent>(entity);
var mindId = mindSystem.CreateMind(null);
var mind = entMan.GetComponent<MindComponent>(mindId);
var mind = mindSystem.CreateMind(null);
Assert.That(mind.UserId, Is.EqualTo(null));
Assert.That(mind.Comp.UserId, Is.EqualTo(null));
mindSystem.TransferTo(mindId, entity, mind: mind);
Assert.That(mindSystem.GetMind(entity, mindComp), Is.EqualTo(mindId));
mindSystem.TransferTo(mind, entity, mind: mind);
Assert.That(mindSystem.GetMind(entity, mindComp), Is.EqualTo(mind.Owner));
});
await pair.CleanReturnAsync();
@ -94,11 +94,11 @@ public sealed partial class MindTests
var entity = entMan.SpawnEntity(null, new MapCoordinates());
var mindComp = entMan.EnsureComponent<MindContainerComponent>(entity);
var mindId = mindSystem.CreateMind(null);
var mindId = mindSystem.CreateMind(null).Owner;
mindSystem.TransferTo(mindId, entity);
Assert.That(mindSystem.GetMind(entity, mindComp), Is.EqualTo(mindId));
var mind2 = mindSystem.CreateMind(null);
var mind2 = mindSystem.CreateMind(null).Owner;
mindSystem.TransferTo(mind2, entity);
Assert.Multiple(() =>
{
@ -184,7 +184,7 @@ public sealed partial class MindTests
var mindComp = entMan.EnsureComponent<MindContainerComponent>(entity);
entMan.EnsureComponent<MindContainerComponent>(targetEntity);
var mind = mindSystem.CreateMind(null);
var mind = mindSystem.CreateMind(null).Owner;
mindSystem.TransferTo(mind, entity);
@ -276,7 +276,7 @@ public sealed partial class MindTests
var entity = entMan.SpawnEntity(null, new MapCoordinates());
var mindComp = entMan.EnsureComponent<MindContainerComponent>(entity);
var mindId = mindSystem.CreateMind(null);
var mindId = mindSystem.CreateMind(null).Owner;
var mind = entMan.EnsureComponent<MindComponent>(mindId);
Assert.That(mind.UserId, Is.EqualTo(null));
@ -334,7 +334,7 @@ public sealed partial class MindTests
public async Task TestPlayerCanGhost()
{
// Client is needed to spawn session
await using var pair = await PoolManager.GetServerClient(new PoolSettings { Connected = true });
await using var pair = await PoolManager.GetServerClient(new PoolSettings { Connected = true, DummyTicker = false });
var server = pair.Server;
var entMan = server.ResolveDependency<IServerEntityManager>();
@ -346,7 +346,7 @@ public sealed partial class MindTests
EntityUid entity = default!;
EntityUid mindId = default!;
MindComponent mind = default!;
var player = playerMan.ServerSessions.Single();
var player = playerMan.Sessions.Single();
await server.WaitAssertion(() =>
{
@ -407,12 +407,6 @@ public sealed partial class MindTests
await pair.CleanReturnAsync();
}
// TODO Implement
/*[Test]
public async Task TestPlayerCanReturnFromGhostWhenDead()
{
}*/
[Test]
public async Task TestGhostDoesNotInfiniteLoop()
{
@ -433,7 +427,7 @@ public sealed partial class MindTests
EntityUid ghost = default!;
EntityUid mindId = default!;
MindComponent mind = default!;
var player = playerMan.ServerSessions.Single();
var player = playerMan.Sessions.Single();
await server.WaitAssertion(() =>
{

View file

@ -2,8 +2,7 @@
using System.Collections.Generic;
using Content.IntegrationTests.Pair;
using Content.Server.Administration.Managers;
using Robust.Server.Player;
using Robust.Shared.Players;
using Robust.Shared.Player;
using Robust.Shared.Toolshed;
using Robust.Shared.Toolshed.Errors;
using Robust.Shared.Toolshed.Syntax;
@ -60,7 +59,7 @@ public abstract class ToolshedTest : IInvocationContext
AdminManager = Server.ResolveDependency<IAdminManager>();
}
protected bool InvokeCommand(string command, out object? result, IPlayerSession? session = null)
protected bool InvokeCommand(string command, out object? result, ICommonSession? session = null)
{
return Toolshed.InvokeCommand(this, command, null, out result);
}
@ -95,7 +94,7 @@ public abstract class ToolshedTest : IInvocationContext
return true;
}
protected IPlayerSession? InvocationSession { get; set; }
protected ICommonSession? InvocationSession { get; set; }
public ICommonSession? Session
{

View file

@ -68,7 +68,7 @@ namespace Content.MapRenderer.Painters
await server.WaitPost(() =>
{
var playerEntity = sPlayerManager.ServerSessions.Single().AttachedEntity;
var playerEntity = sPlayerManager.Sessions.Single().AttachedEntity;
if (playerEntity.HasValue)
{

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,39 @@
#nullable disable
using System;
using Microsoft.EntityFrameworkCore.Migrations;
namespace Content.Server.Database.Migrations.Postgres
{
/// <inheritdoc />
public partial class RoundStartDate : Migration
{
/// <inheritdoc />
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.AddColumn<DateTime>(
name: "start_date",
table: "round",
type: "timestamp with time zone",
nullable: false,
defaultValue: new DateTime(1, 1, 1, 0, 0, 0, 0, DateTimeKind.Unspecified));
migrationBuilder.CreateIndex(
name: "IX_round_start_date",
table: "round",
column: "start_date");
}
/// <inheritdoc />
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropIndex(
name: "IX_round_start_date",
table: "round");
migrationBuilder.DropColumn(
name: "start_date",
table: "round");
}
}
}

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,47 @@
#nullable disable
using Microsoft.EntityFrameworkCore.Migrations;
using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata;
namespace Content.Server.Database.Migrations.Postgres
{
/// <inheritdoc />
public partial class DropAdminLogEntity : Migration
{
/// <inheritdoc />
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropTable(
name: "admin_log_entity");
}
/// <inheritdoc />
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.CreateTable(
name: "admin_log_entity",
columns: table => new
{
uid = table.Column<int>(type: "integer", nullable: false)
.Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn),
admin_log_id = table.Column<int>(type: "integer", nullable: true),
admin_log_round_id = table.Column<int>(type: "integer", nullable: true),
name = table.Column<string>(type: "text", nullable: true)
},
constraints: table =>
{
table.PrimaryKey("PK_admin_log_entity", x => x.uid);
table.ForeignKey(
name: "FK_admin_log_entity_admin_log_admin_log_id_admin_log_round_id",
columns: x => new { x.admin_log_id, x.admin_log_round_id },
principalTable: "admin_log",
principalColumns: new[] { "admin_log_id", "round_id" });
});
migrationBuilder.CreateIndex(
name: "IX_admin_log_entity_admin_log_id_admin_log_round_id",
table: "admin_log_entity",
columns: new[] { "admin_log_id", "admin_log_round_id" });
}
}
}

View file

@ -133,36 +133,6 @@ namespace Content.Server.Database.Migrations.Postgres
b.ToTable("admin_log", (string)null);
});
modelBuilder.Entity("Content.Server.Database.AdminLogEntity", b =>
{
b.Property<int>("Uid")
.ValueGeneratedOnAdd()
.HasColumnType("integer")
.HasColumnName("uid");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Uid"));
b.Property<int?>("AdminLogId")
.HasColumnType("integer")
.HasColumnName("admin_log_id");
b.Property<int?>("AdminLogRoundId")
.HasColumnType("integer")
.HasColumnName("admin_log_round_id");
b.Property<string>("Name")
.HasColumnType("text")
.HasColumnName("name");
b.HasKey("Uid")
.HasName("PK_admin_log_entity");
b.HasIndex("AdminLogId", "AdminLogRoundId")
.HasDatabaseName("IX_admin_log_entity_admin_log_id_admin_log_round_id");
b.ToTable("admin_log_entity", (string)null);
});
modelBuilder.Entity("Content.Server.Database.AdminLogPlayer", b =>
{
b.Property<Guid>("PlayerUserId")
@ -863,12 +833,20 @@ namespace Content.Server.Database.Migrations.Postgres
.HasColumnType("integer")
.HasColumnName("server_id");
b.Property<DateTime>("StartDate")
.ValueGeneratedOnAdd()
.HasColumnType("timestamp with time zone")
.HasDefaultValue(new DateTime(1, 1, 1, 0, 0, 0, 0, DateTimeKind.Unspecified))
.HasColumnName("start_date");
b.HasKey("Id")
.HasName("PK_round");
b.HasIndex("ServerId")
.HasDatabaseName("IX_round_server_id");
b.HasIndex("StartDate");
b.ToTable("round", (string)null);
});
@ -1311,14 +1289,6 @@ namespace Content.Server.Database.Migrations.Postgres
b.Navigation("Round");
});
modelBuilder.Entity("Content.Server.Database.AdminLogEntity", b =>
{
b.HasOne("Content.Server.Database.AdminLog", null)
.WithMany("Entities")
.HasForeignKey("AdminLogId", "AdminLogRoundId")
.HasConstraintName("FK_admin_log_entity_admin_log_admin_log_id_admin_log_round_id");
});
modelBuilder.Entity("Content.Server.Database.AdminLogPlayer", b =>
{
b.HasOne("Content.Server.Database.Player", "Player")
@ -1676,8 +1646,6 @@ namespace Content.Server.Database.Migrations.Postgres
modelBuilder.Entity("Content.Server.Database.AdminLog", b =>
{
b.Navigation("Entities");
b.Navigation("Players");
});

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,39 @@
#nullable disable
using System;
using Microsoft.EntityFrameworkCore.Migrations;
namespace Content.Server.Database.Migrations.Sqlite
{
/// <inheritdoc />
public partial class RoundStartDate : Migration
{
/// <inheritdoc />
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.AddColumn<DateTime>(
name: "start_date",
table: "round",
type: "TEXT",
nullable: false,
defaultValue: new DateTime(1, 1, 1, 0, 0, 0, 0, DateTimeKind.Unspecified));
migrationBuilder.CreateIndex(
name: "IX_round_start_date",
table: "round",
column: "start_date");
}
/// <inheritdoc />
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropIndex(
name: "IX_round_start_date",
table: "round");
migrationBuilder.DropColumn(
name: "start_date",
table: "round");
}
}
}

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,46 @@
#nullable disable
using Microsoft.EntityFrameworkCore.Migrations;
namespace Content.Server.Database.Migrations.Sqlite
{
/// <inheritdoc />
public partial class DropAdminLogEntity : Migration
{
/// <inheritdoc />
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropTable(
name: "admin_log_entity");
}
/// <inheritdoc />
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.CreateTable(
name: "admin_log_entity",
columns: table => new
{
uid = table.Column<int>(type: "INTEGER", nullable: false)
.Annotation("Sqlite:Autoincrement", true),
admin_log_id = table.Column<int>(type: "INTEGER", nullable: true),
admin_log_round_id = table.Column<int>(type: "INTEGER", nullable: true),
name = table.Column<string>(type: "TEXT", nullable: true)
},
constraints: table =>
{
table.PrimaryKey("PK_admin_log_entity", x => x.uid);
table.ForeignKey(
name: "FK_admin_log_entity_admin_log_admin_log_id_admin_log_round_id",
columns: x => new { x.admin_log_id, x.admin_log_round_id },
principalTable: "admin_log",
principalColumns: new[] { "admin_log_id", "round_id" });
});
migrationBuilder.CreateIndex(
name: "IX_admin_log_entity_admin_log_id_admin_log_round_id",
table: "admin_log_entity",
columns: new[] { "admin_log_id", "admin_log_round_id" });
}
}
}

View file

@ -119,34 +119,6 @@ namespace Content.Server.Database.Migrations.Sqlite
b.ToTable("admin_log", (string)null);
});
modelBuilder.Entity("Content.Server.Database.AdminLogEntity", b =>
{
b.Property<int>("Uid")
.ValueGeneratedOnAdd()
.HasColumnType("INTEGER")
.HasColumnName("uid");
b.Property<int?>("AdminLogId")
.HasColumnType("INTEGER")
.HasColumnName("admin_log_id");
b.Property<int?>("AdminLogRoundId")
.HasColumnType("INTEGER")
.HasColumnName("admin_log_round_id");
b.Property<string>("Name")
.HasColumnType("TEXT")
.HasColumnName("name");
b.HasKey("Uid")
.HasName("PK_admin_log_entity");
b.HasIndex("AdminLogId", "AdminLogRoundId")
.HasDatabaseName("IX_admin_log_entity_admin_log_id_admin_log_round_id");
b.ToTable("admin_log_entity", (string)null);
});
modelBuilder.Entity("Content.Server.Database.AdminLogPlayer", b =>
{
b.Property<Guid>("PlayerUserId")
@ -813,12 +785,20 @@ namespace Content.Server.Database.Migrations.Sqlite
.HasColumnType("INTEGER")
.HasColumnName("server_id");
b.Property<DateTime>("StartDate")
.ValueGeneratedOnAdd()
.HasColumnType("TEXT")
.HasDefaultValue(new DateTime(1, 1, 1, 0, 0, 0, 0, DateTimeKind.Unspecified))
.HasColumnName("start_date");
b.HasKey("Id")
.HasName("PK_round");
b.HasIndex("ServerId")
.HasDatabaseName("IX_round_server_id");
b.HasIndex("StartDate");
b.ToTable("round", (string)null);
});
@ -1241,14 +1221,6 @@ namespace Content.Server.Database.Migrations.Sqlite
b.Navigation("Round");
});
modelBuilder.Entity("Content.Server.Database.AdminLogEntity", b =>
{
b.HasOne("Content.Server.Database.AdminLog", null)
.WithMany("Entities")
.HasForeignKey("AdminLogId", "AdminLogRoundId")
.HasConstraintName("FK_admin_log_entity_admin_log_admin_log_id_admin_log_round_id");
});
modelBuilder.Entity("Content.Server.Database.AdminLogPlayer", b =>
{
b.HasOne("Content.Server.Database.Player", "Player")
@ -1606,8 +1578,6 @@ namespace Content.Server.Database.Migrations.Sqlite
modelBuilder.Entity("Content.Server.Database.AdminLog", b =>
{
b.Navigation("Entities");
b.Navigation("Players");
});

View file

@ -111,6 +111,13 @@ namespace Content.Server.Database
.HasForeignKey(player => player.PlayerUserId)
.HasPrincipalKey(player => player.UserId);
modelBuilder.Entity<Round>()
.HasIndex(round => round.StartDate);
modelBuilder.Entity<Round>()
.Property(round => round.StartDate)
.HasDefaultValue(default(DateTime));
modelBuilder.Entity<AdminLogPlayer>()
.HasKey(logPlayer => new {logPlayer.PlayerUserId, logPlayer.LogId, logPlayer.RoundId});
@ -469,6 +476,8 @@ namespace Content.Server.Database
[Key, DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int Id { get; set; }
public DateTime StartDate { get; set; }
public List<Player> Players { get; set; } = default!;
public List<AdminLog> AdminLogs { get; set; } = default!;
@ -508,8 +517,6 @@ namespace Content.Server.Database
[Required, Column(TypeName = "jsonb")] public JsonDocument Json { get; set; } = default!;
public List<AdminLogPlayer> Players { get; set; } = default!;
public List<AdminLogEntity> Entities { get; set; } = default!;
}
public class AdminLogPlayer
@ -522,12 +529,6 @@ namespace Content.Server.Database
[ForeignKey("LogId,RoundId")] public AdminLog Log { get; set; } = default!;
}
public class AdminLogEntity
{
[Required, Key] public int Uid { get; set; }
public string? Name { get; set; } = default!;
}
// Used by SS14.Admin
public interface IBanCommon<TUnban> where TUnban : IUnbanCommon
{

View file

@ -1,5 +1,5 @@
using Content.Shared.Administration;
using Robust.Server.Player;
using Robust.Shared.Player;
namespace Content.Server.Administration
{
@ -8,7 +8,7 @@ namespace Content.Server.Administration
/// </summary>
public sealed class AdminPermsChangedEventArgs : EventArgs
{
public AdminPermsChangedEventArgs(IPlayerSession player, AdminFlags? flags)
public AdminPermsChangedEventArgs(ICommonSession player, AdminFlags? flags)
{
Player = player;
Flags = flags;
@ -17,7 +17,7 @@ namespace Content.Server.Administration
/// <summary>
/// The player that had their admin permissions changed.
/// </summary>
public IPlayerSession Player { get; }
public ICommonSession Player { get; }
/// <summary>
/// The admin flags of the player. Null if the player is no longer an admin.

View file

@ -2,7 +2,6 @@
using Content.Shared.Administration;
using Content.Shared.Ghost;
using Content.Shared.Mind;
using Robust.Server.Player;
using Robust.Shared.Console;
namespace Content.Server.Administration.Commands
@ -18,7 +17,7 @@ namespace Content.Server.Administration.Commands
public void Execute(IConsoleShell shell, string argStr, string[] args)
{
var player = shell.Player as IPlayerSession;
var player = shell.Player;
if (player == null)
{
shell.WriteLine("Nah");

View file

@ -2,7 +2,6 @@
using Content.Server.Administration.Managers;
using Content.Server.Afk;
using Content.Shared.Administration;
using Robust.Server.Player;
using Robust.Shared.Console;
using Robust.Shared.Utility;
@ -35,7 +34,7 @@ public sealed class AdminWhoCommand : IConsoleCommand
if (adminData.Title is { } title)
sb.Append($": [{title}]");
if (shell.Player is IPlayerSession player && adminMgr.HasAdminFlag(player, AdminFlags.Admin))
if (shell.Player is { } player && adminMgr.HasAdminFlag(player, AdminFlags.Admin))
{
if (afk.IsAfk(admin))
sb.Append(" [AFK]");

View file

@ -1,7 +1,6 @@
using Content.Server.Administration.UI;
using Content.Server.EUI;
using Content.Shared.Administration;
using Robust.Server.Player;
using Robust.Shared.Console;
namespace Content.Server.Administration.Commands
@ -17,7 +16,7 @@ namespace Content.Server.Administration.Commands
public void Execute(IConsoleShell shell, string argStr, string[] args)
{
var player = shell.Player as IPlayerSession;
var player = shell.Player;
if (player == null)
{
shell.WriteLine("This does not work from the server console.");

View file

@ -1,15 +1,8 @@
using System.Linq;
using System.Net;
using System.Net.Sockets;
using System.Text;
using Content.Server.Administration.Managers;
using Content.Server.Administration.Notes;
using Content.Server.Database;
using Content.Server.GameTicking;
using Content.Shared.Administration;
using Content.Shared.CCVar;
using Content.Shared.Database;
using Content.Shared.Players.PlayTimeTracking;
using Robust.Server.Player;
using Robust.Shared.Configuration;
using Robust.Shared.Console;
@ -84,7 +77,7 @@ public sealed class BanCommand : LocalizedCommands
}
var located = await _locator.LookupIdByNameOrIdAsync(target);
var player = shell.Player as IPlayerSession;
var player = shell.Player;
if (located == null)
{
@ -102,7 +95,7 @@ public sealed class BanCommand : LocalizedCommands
{
if (args.Length == 1)
{
var options = _playerManager.ServerSessions.Select(c => c.Name).OrderBy(c => c).ToArray();
var options = _playerManager.Sessions.Select(c => c.Name).OrderBy(c => c).ToArray();
return CompletionResult.FromHintOptions(options, LocalizationManager.GetString("cmd-ban-hint"));
}

View file

@ -36,7 +36,7 @@ public sealed class BanListCommand : LocalizedCommands
return;
}
if (shell.Player is not IPlayerSession player)
if (shell.Player is not { } player)
{
var bans = await _dbManager.GetServerBansAsync(data.LastAddress, data.UserId, data.LastHWId, false);
@ -67,7 +67,7 @@ public sealed class BanListCommand : LocalizedCommands
return CompletionResult.Empty;
var playerMgr = IoCManager.Resolve<IPlayerManager>();
var options = playerMgr.ServerSessions.Select(c => c.Name).OrderBy(c => c).ToArray();
var options = playerMgr.Sessions.Select(c => c.Name).OrderBy(c => c).ToArray();
return CompletionResult.FromHintOptions(options, Loc.GetString("cmd-banlist-hint"));
}
}

View file

@ -1,12 +1,6 @@
using Content.Shared.Administration;
using Robust.Shared.Console;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Content.Server.EUI;
using Robust.Server.Player;
namespace Content.Server.Administration.Commands;
@ -21,7 +15,7 @@ public sealed class BanPanelCommand : LocalizedCommands
public override async void Execute(IConsoleShell shell, string argStr, string[] args)
{
if (shell.Player is not IPlayerSession player)
if (shell.Player is not { } player)
{
shell.WriteError(Loc.GetString("cmd-banpanel-server"));
return;

View file

@ -1,6 +1,5 @@
using Content.Server.Mind;
using Content.Shared.Administration;
using Content.Shared.Mind;
using Robust.Server.Player;
using Robust.Shared.Console;
namespace Content.Server.Administration.Commands
@ -16,7 +15,7 @@ namespace Content.Server.Administration.Commands
public void Execute(IConsoleShell shell, string argStr, string[] args)
{
if (shell.Player is not IPlayerSession player)
if (shell.Player is not { } player)
{
shell.WriteLine("shell-server-cannot");
return;
@ -42,14 +41,7 @@ namespace Content.Server.Administration.Commands
return;
}
var mindSystem = _entities.System<SharedMindSystem>();
if (!mindSystem.TryGetMind(target, out var mindId, out var mind))
{
shell.WriteLine(Loc.GetString("shell-entity-is-not-mob"));
return;
}
mindSystem.TransferTo(mindId, target, mind: mind);
_entities.System<MindSystem>().ControlMob(player.UserId, target);
}
}
}

View file

@ -1,7 +1,5 @@
using Content.Server.Chat;
using Content.Server.Chat.Systems;
using Content.Shared.Administration;
using Robust.Server.Player;
using Robust.Shared.Console;
namespace Content.Server.Administration.Commands
@ -17,7 +15,7 @@ namespace Content.Server.Administration.Commands
public void Execute(IConsoleShell shell, string argStr, string[] args)
{
var player = shell.Player as IPlayerSession;
var player = shell.Player;
if (player == null)
{
shell.WriteLine("shell-only-players-can-run-this-command");

View file

@ -1,10 +1,8 @@
using Content.Server.Administration.Managers;
using Content.Shared.Administration;
using JetBrains.Annotations;
using Robust.Server.Player;
using Robust.Shared.Console;
namespace Content.Server.Administration.Commands
{
[UsedImplicitly]
@ -17,7 +15,7 @@ namespace Content.Server.Administration.Commands
public void Execute(IConsoleShell shell, string argStr, string[] args)
{
var player = shell.Player as IPlayerSession;
var player = shell.Player;
if (player == null)
{
shell.WriteLine("You cannot use this command from the server console.");

View file

@ -3,7 +3,6 @@ using Content.Server.EUI;
using Content.Server.Explosion.EntitySystems;
using Content.Shared.Administration;
using Content.Shared.Explosion;
using Robust.Server.Player;
using Robust.Shared.Console;
using Robust.Shared.Map;
using Robust.Shared.Prototypes;
@ -21,7 +20,7 @@ public sealed class OpenExplosionEui : IConsoleCommand
public void Execute(IConsoleShell shell, string argStr, string[] args)
{
var player = shell.Player as IPlayerSession;
var player = shell.Player;
if (player == null)
{
shell.WriteError("This does not work from the server console.");

View file

@ -1,7 +1,6 @@
using Content.Server.EUI;
using Content.Server.Fax.AdminUI;
using Content.Shared.Administration;
using Robust.Server.Player;
using Robust.Shared.Console;
namespace Content.Server.Administration.Commands;
@ -16,7 +15,7 @@ public sealed class FaxUiCommand : IConsoleCommand
public void Execute(IConsoleShell shell, string argStr, string[] args)
{
var player = shell.Player as IPlayerSession;
var player = shell.Player;
if (player == null)
{
shell.WriteLine("shell-only-players-can-run-this-command");

View file

@ -1,7 +1,6 @@
using Content.Server.Administration.Logs;
using Content.Server.EUI;
using Content.Shared.Administration;
using Robust.Server.Player;
using Robust.Shared.Console;
namespace Content.Server.Administration.Commands;
@ -15,7 +14,7 @@ public sealed class OpenAdminLogsCommand : IConsoleCommand
public void Execute(IConsoleShell shell, string argStr, string[] args)
{
if (shell.Player is not IPlayerSession player)
if (shell.Player is not { } player)
{
shell.WriteLine("This does not work from the server console.");
return;

View file

@ -1,7 +1,5 @@
using Content.Server.Administration.Notes;
using Content.Server.Database;
using Content.Shared.Administration;
using Robust.Server.Player;
using Robust.Shared.Console;
namespace Content.Server.Administration.Commands;
@ -17,7 +15,7 @@ public sealed class OpenAdminNotesCommand : IConsoleCommand
public async void Execute(IConsoleShell shell, string argStr, string[] args)
{
if (shell.Player is not IPlayerSession player)
if (shell.Player is not { } player)
{
shell.WriteError("This does not work from the server console.");
return;

View file

@ -1,10 +1,8 @@
using Content.Server.Administration.UI;
using Content.Server.EUI;
using Content.Shared.Administration;
using Robust.Server.Player;
using Robust.Shared.Console;
namespace Content.Server.Administration.Commands
{
[AdminCommand(AdminFlags.Permissions)]
@ -16,7 +14,7 @@ namespace Content.Server.Administration.Commands
public void Execute(IConsoleShell shell, string argStr, string[] args)
{
var player = shell.Player as IPlayerSession;
var player = shell.Player;
if (player == null)
{
shell.WriteLine("This does not work from the server console.");

View file

@ -1,7 +1,6 @@
using Content.Server.Administration.Notes;
using Content.Shared.Administration;
using Content.Shared.CCVar;
using Robust.Server.Player;
using Robust.Shared.Configuration;
using Robust.Shared.Console;
@ -27,7 +26,7 @@ public sealed class OpenUserVisibleNotesCommand : IConsoleCommand
return;
}
if (shell.Player is not IPlayerSession player)
if (shell.Player is not { } player)
{
shell.WriteError("This does not work from the server console.");
return;

View file

@ -1,7 +1,6 @@
using System.Text;
using Content.Server.Database;
using Content.Shared.Administration;
using Robust.Server.Player;
using Robust.Shared.Console;
namespace Content.Server.Administration.Commands
@ -15,7 +14,7 @@ namespace Content.Server.Administration.Commands
public async void Execute(IConsoleShell shell, string argStr, string[] args)
{
var player = shell.Player as IPlayerSession;
var player = shell.Player;
var dbMan = IoCManager.Resolve<IServerDbManager>();
if (args.Length != 1)

View file

@ -6,7 +6,6 @@ using Robust.Shared.Audio;
using Robust.Shared.Console;
using Robust.Shared.ContentPack;
using Robust.Shared.Player;
using Robust.Shared.Players;
using Robust.Shared.Prototypes;
namespace Content.Server.Administration.Commands;

View file

@ -1,9 +1,7 @@
using Content.Server.Administration.Managers;
using Content.Shared.Administration;
using Robust.Server.Player;
using Robust.Shared.Console;
namespace Content.Server.Administration.Commands
{
[AnyCommand]
@ -15,7 +13,7 @@ namespace Content.Server.Administration.Commands
public void Execute(IConsoleShell shell, string argStr, string[] args)
{
var player = shell.Player as IPlayerSession;
var player = shell.Player;
if (player == null)
{
shell.WriteLine("You cannot use this command from the server console.");

View file

@ -1,8 +1,6 @@
using Content.Server.Database;
using Content.Server.Preferences.Managers;
using Content.Shared.Administration;
using Robust.Server.Player;
using Robust.Shared.Console;
namespace Content.Server.Administration.Commands
@ -16,7 +14,7 @@ namespace Content.Server.Administration.Commands
public void Execute(IConsoleShell shell, string argStr, string[] args)
{
if (!(shell.Player is IPlayerSession))
if (shell.Player == null)
{
shell.WriteError(Loc.GetString("shell-only-players-can-run-this-command"));
return;

View file

@ -2,6 +2,7 @@ using Content.Server.Players;
using Content.Shared.Administration;
using Content.Shared.Mind;
using Content.Shared.Mind.Components;
using Content.Shared.Players;
using Robust.Server.Player;
using Robust.Shared.Console;

View file

@ -10,7 +10,6 @@ using Content.Shared.PDA;
using Content.Shared.Preferences;
using Content.Shared.Roles;
using Robust.Server.GameObjects;
using Robust.Server.Player;
using Robust.Shared.Console;
using Robust.Shared.Prototypes;
@ -57,7 +56,7 @@ namespace Content.Server.Administration.Commands
if (args.Length == 1)
{
if (shell.Player is not IPlayerSession player)
if (shell.Player is not { } player)
{
shell.WriteError(Loc.GetString("set-outfit-command-is-not-player-error"));
return;

View file

@ -12,6 +12,7 @@ public sealed class VariantizeCommand : IConsoleCommand
{
[Dependency] private readonly IEntityManager _entManager = default!;
[Dependency] private readonly IRobustRandom _random = default!;
[Dependency] private readonly ITileDefinitionManager _tileDefManager = default!;
public string Command => "variantize";
@ -39,11 +40,14 @@ public sealed class VariantizeCommand : IConsoleCommand
return;
}
foreach (var tile in gridComp.GetAllTiles())
var mapsSystem = _entManager.System<SharedMapSystem>();
var tileSystem = _entManager.System<TileSystem>();
foreach (var tile in mapsSystem.GetAllTiles(euid.Value, gridComp))
{
var def = tile.GetContentTileDefinition();
var newTile = new Tile(tile.Tile.TypeId, tile.Tile.Flags, def.PickVariant(_random));
gridComp.SetTile(tile.GridIndices, newTile);
var def = tile.GetContentTileDefinition(_tileDefManager);
var newTile = new Tile(tile.Tile.TypeId, tile.Tile.Flags, tileSystem.PickVariant(def));
mapsSystem.SetTile(euid.Value, gridComp, tile.GridIndices, newTile);
}
}
}

View file

@ -4,11 +4,9 @@ using Content.Server.Warps;
using Content.Shared.Administration;
using Content.Shared.Follower;
using Content.Shared.Ghost;
using Robust.Server.Player;
using Robust.Shared.Console;
using Robust.Shared.Enums;
using Robust.Shared.Map;
using Robust.Shared.Physics;
using Robust.Shared.Physics.Components;
using Robust.Shared.Physics.Systems;
@ -28,7 +26,7 @@ namespace Content.Server.Administration.Commands
public void Execute(IConsoleShell shell, string argStr, string[] args)
{
var player = shell.Player as IPlayerSession;
var player = shell.Player;
if (player == null)
{
shell.WriteLine("Only players can use this command");

View file

@ -1,8 +1,8 @@
using Content.Server.Database;
using Content.Shared.CCVar;
using Robust.Server.Player;
using Robust.Server.Upload;
using Robust.Shared.Configuration;
using Robust.Shared.Player;
using Robust.Shared.Upload;
namespace Content.Server.Administration;
@ -22,7 +22,7 @@ public sealed class ContentNetworkResourceManager
_netRes.OnResourceUploaded += OnUploadResource;
}
private async void OnUploadResource(IPlayerSession session, NetworkResourceUploadMessage msg)
private async void OnUploadResource(ICommonSession session, NetworkResourceUploadMessage msg)
{
if (StoreUploaded)
await _serverDb.AddUploadedResourceLogAsync(session.UserId, DateTime.Now, msg.RelativePath.ToString(), msg.Data);

View file

@ -2,10 +2,9 @@
using System.Text.Json;
using System.Text.Json.Serialization;
using Content.Server.Administration.Logs.Converters;
using Content.Server.Database;
using Robust.Server.GameObjects;
using Robust.Server.Player;
using Robust.Shared.Map;
using Robust.Shared.Player;
namespace Content.Server.Administration.Logs;
@ -34,10 +33,9 @@ public sealed partial class AdminLogManager
_sawmill.Debug($"Admin log converters found: {string.Join(" ", converterNames)}");
}
private (JsonDocument Json, HashSet<Guid> Players, List<AdminLogEntity> Entities) ToJson(
private (JsonDocument Json, HashSet<Guid> Players) ToJson(
Dictionary<string, object?> properties)
{
var entities = new Dictionary<EntityUid, AdminLogEntity>();
var players = new HashSet<Guid>();
var parsed = new Dictionary<string, object?>();
@ -46,7 +44,7 @@ public sealed partial class AdminLogManager
var value = properties[key];
value = value switch
{
IPlayerSession player => new SerializablePlayer(player),
ICommonSession player => new SerializablePlayer(player),
EntityCoordinates entityCoordinates => new SerializableEntityCoordinates(_entityManager, entityCoordinates),
_ => value
};
@ -58,29 +56,17 @@ public sealed partial class AdminLogManager
{
EntityUid id => id,
EntityStringRepresentation rep => rep.Uid,
IPlayerSession {AttachedEntity: {Valid: true}} session => session.AttachedEntity,
ICommonSession {AttachedEntity: {Valid: true}} session => session.AttachedEntity,
IComponent component => component.Owner,
_ => null
};
if (entityId is not { } uid)
{
continue;
}
var entityName = _entityManager.TryGetComponent(uid, out MetaDataComponent? metadata)
? metadata.EntityName
: null;
// TODO set the id too whenever we feel like running a migration for 10 hours
entities.TryAdd(uid, new AdminLogEntity { Name = entityName });
if (_entityManager.TryGetComponent(uid, out ActorComponent? actor))
if (_entityManager.TryGetComponent(entityId, out ActorComponent? actor))
{
players.Add(actor.PlayerSession.UserId.UserId);
}
}
return (JsonSerializer.SerializeToDocument(parsed, _jsonOptions), players, entities.Values.ToList());
return (JsonSerializer.SerializeToDocument(parsed, _jsonOptions), players);
}
}

View file

@ -278,7 +278,7 @@ public sealed partial class AdminLogManager : SharedAdminLogManager, IAdminLogMa
}
}
private void Add(LogType type, LogImpact impact, string message, JsonDocument json, HashSet<Guid> players, List<AdminLogEntity> entities)
private void Add(LogType type, LogImpact impact, string message, JsonDocument json, HashSet<Guid> players)
{
var preRound = _runLevel == GameRunLevel.PreRoundLobby;
var count = preRound ? _preRoundLogQueue.Count : _logQueue.Count;
@ -297,8 +297,7 @@ public sealed partial class AdminLogManager : SharedAdminLogManager, IAdminLogMa
Date = DateTime.UtcNow,
Message = message,
Json = json,
Players = new List<AdminLogPlayer>(players.Count),
Entities = entities
Players = new List<AdminLogPlayer>(players.Count)
};
foreach (var id in players)
@ -331,10 +330,10 @@ public sealed partial class AdminLogManager : SharedAdminLogManager, IAdminLogMa
return;
}
var (json, players, entities) = ToJson(handler.Values);
var (json, players) = ToJson(handler.Values);
var message = handler.ToStringAndClear();
Add(type, impact, message, json, players, entities);
Add(type, impact, message, json, players);
}
public override void Add(LogType type, ref LogStringHandler handler)

View file

@ -1,5 +1,5 @@
using System.Text.Json;
using Robust.Server.Player;
using Robust.Shared.Player;
namespace Content.Server.Administration.Logs.Converters;
@ -36,9 +36,9 @@ public sealed class PlayerSessionConverter : AdminLogConverter<SerializablePlaye
public readonly struct SerializablePlayer
{
public readonly IPlayerSession Player;
public readonly ICommonSession Player;
public SerializablePlayer(IPlayerSession player)
public SerializablePlayer(ICommonSession player)
{
Player = player;
}

Some files were not shown because too many files have changed in this diff Show more