Fix station deletion bug (#10348)

This commit is contained in:
Leon Friedrich
2022-08-07 15:53:07 +12:00
committed by GitHub
parent 31141ad0fb
commit 099d38b562
5 changed files with 44 additions and 21 deletions

View File

@@ -25,7 +25,6 @@ namespace Content.Server.Station.Systems;
[PublicAPI]
public sealed class StationSystem : EntitySystem
{
[Dependency] private readonly IChatManager _chatManager = default!;
[Dependency] private readonly IConfigurationManager _configurationManager = default!;
[Dependency] private readonly ILogManager _logManager = default!;
[Dependency] private readonly IMapManager _mapManager = default!;
@@ -59,8 +58,9 @@ public sealed class StationSystem : EntitySystem
SubscribeLocalEvent<GameRunLevelChangedEvent>(OnRoundEnd);
SubscribeLocalEvent<PreGameMapLoad>(OnPreGameMapLoad);
SubscribeLocalEvent<PostGameMapLoad>(OnPostGameMapLoad);
SubscribeLocalEvent<StationDataComponent, ComponentAdd>(OnStationStartup);
SubscribeLocalEvent<StationDataComponent, ComponentAdd>(OnStationAdd);
SubscribeLocalEvent<StationDataComponent, ComponentShutdown>(OnStationDeleted);
SubscribeLocalEvent<StationDataComponent, EntParentChangedMessage>(OnParentChanged);
_configurationManager.OnValueChanged(CCVars.StationOffset, x => _randomStationOffset = x, true);
_configurationManager.OnValueChanged(CCVars.MaxStationOffset, x => _maxRandomStationOffset = x, true);
@@ -85,7 +85,7 @@ public sealed class StationSystem : EntitySystem
#region Event handlers
private void OnStationStartup(EntityUid uid, StationDataComponent component, ComponentAdd args)
private void OnStationAdd(EntityUid uid, StationDataComponent component, ComponentAdd args)
{
_stations.Add(uid);
@@ -94,11 +94,36 @@ public sealed class StationSystem : EntitySystem
private void OnStationDeleted(EntityUid uid, StationDataComponent component, ComponentShutdown args)
{
_stations.Remove(uid);
if (_stations.Contains(uid) && // Was not deleted via DeleteStation()
_gameTicker.RunLevel == GameRunLevel.InRound) // And not due to a round restart
{
throw new InvalidOperationException($"Station entity {ToPrettyString(uid)} is getting deleted mid-round.");
}
_stations.Remove(uid);
RaiseNetworkEvent(new StationsUpdatedEvent(_stations), Filter.Broadcast());
}
/// <summary>
/// If a station data entity is getting re-parented mid-round, this will log an error.
/// </summary>
/// <remarks>
/// This doesn't really achieve anything, it just for debugging any future station data bugs.
/// </remarks>
private void OnParentChanged(EntityUid uid, StationDataComponent component, ref EntParentChangedMessage args)
{
if (_gameTicker.RunLevel != GameRunLevel.InRound ||
MetaData(uid).EntityLifeStage >= EntityLifeStage.MapInitialized ||
component.LifeStage <= ComponentLifeStage.Initializing)
{
return;
}
// Yeah this doesn't actually stop the parent change..... it just ineffectually yells about it.
// STOP RIGHT THERE CRIMINAL SCUM
_sawmill.Error($"Station entity {ToPrettyString(uid)} is getting reparented from {ToPrettyString(args.OldParent ?? EntityUid.Invalid)} to {ToPrettyString(args.Transform.ParentUid)}");
}
private void OnPreGameMapLoad(PreGameMapLoad ev)
{
// this is only for maps loaded during round setup!
@@ -261,8 +286,12 @@ public sealed class StationSystem : EntitySystem
/// <returns>The initialized station.</returns>
public EntityUid InitializeNewStation(StationConfig? stationConfig, IEnumerable<EntityUid>? gridIds, string? name = null)
{
//HACK: This needs to go in null-space but that crashes currently.
var station = Spawn(null, new MapCoordinates(0, 0, _gameTicker.DefaultMap));
// TODO SERIALIZATION The station data needs to be saveable somehow, but when a map gets saved, this entity
// won't be included because its in null-space. Also, what happens to shuttles on other maps?
_transform.DetachParentToNull(Transform(station));
var data = AddComp<StationDataComponent>(station);
var metaData = MetaData(station);
data.StationConfig = stationConfig;
@@ -374,6 +403,7 @@ public sealed class StationSystem : EntitySystem
if (!Resolve(station, ref stationData))
throw new ArgumentException("Tried to use a non-station entity as a station!", nameof(station));
// component shutdown will error if the station was not removed from _stations prior to deletion.
_stations.Remove(station);
Del(station);
}