Enable nullability in Content.Server (#3685)
This commit is contained in:
@@ -15,8 +15,6 @@ using Content.Server.GameObjects.Components.Mobs.Speech;
|
||||
using Content.Server.GameObjects.Components.Observer;
|
||||
using Content.Server.GameObjects.Components.PDA;
|
||||
using Content.Server.GameTicking.GamePresets;
|
||||
using Content.Server.Holiday;
|
||||
using Content.Server.Holiday.Interfaces;
|
||||
using Content.Server.Interfaces;
|
||||
using Content.Server.Interfaces.Chat;
|
||||
using Content.Server.Interfaces.GameTicking;
|
||||
@@ -80,7 +78,7 @@ namespace Content.Server.GameTicking
|
||||
|
||||
[ViewVariables] private bool _initialized;
|
||||
|
||||
[ViewVariables] private Type _presetType;
|
||||
[ViewVariables] private Type? _presetType;
|
||||
|
||||
[ViewVariables] private TimeSpan _pauseTime;
|
||||
[ViewVariables] private bool _roundStartCountdownHasNotStartedYetDueToNoPlayers;
|
||||
@@ -93,7 +91,7 @@ namespace Content.Server.GameTicking
|
||||
[ViewVariables] private bool LobbyEnabled => _configurationManager.GetCVar(CCVars.GameLobbyEnabled);
|
||||
|
||||
[ViewVariables] private bool _updateOnRoundEnd;
|
||||
private CancellationTokenSource _updateShutdownCts;
|
||||
private CancellationTokenSource? _updateShutdownCts;
|
||||
|
||||
|
||||
[ViewVariables] public bool Paused { get; private set; }
|
||||
@@ -118,24 +116,24 @@ namespace Content.Server.GameTicking
|
||||
}
|
||||
|
||||
[ViewVariables]
|
||||
public GamePreset Preset
|
||||
public GamePreset? Preset
|
||||
{
|
||||
get => _preset == null ? MakeGamePreset(null) : _preset;
|
||||
get => _preset ?? MakeGamePreset(new Dictionary<NetUserId, HumanoidCharacterProfile>());
|
||||
set => _preset = value;
|
||||
}
|
||||
|
||||
public ImmutableDictionary<string, Type> Presets { get; private set; }
|
||||
public ImmutableDictionary<string, Type> Presets { get; private set; } = default!;
|
||||
|
||||
private GamePreset _preset;
|
||||
private GamePreset? _preset;
|
||||
|
||||
public event Action<GameRunLevelChangedEventArgs> OnRunLevelChanged;
|
||||
public event Action<GameRuleAddedEventArgs> OnRuleAdded;
|
||||
public event Action<GameRunLevelChangedEventArgs>? OnRunLevelChanged;
|
||||
public event Action<GameRuleAddedEventArgs>? OnRuleAdded;
|
||||
|
||||
private TimeSpan LobbyDuration =>
|
||||
TimeSpan.FromSeconds(_configurationManager.GetCVar(CCVars.GameLobbyDuration));
|
||||
|
||||
private SoundCollectionPrototype _lobbyCollection = default!;
|
||||
[ViewVariables] public string LobbySong { get; private set; }
|
||||
[ViewVariables] public string LobbySong { get; private set; } = default!;
|
||||
|
||||
public override void Initialize()
|
||||
{
|
||||
@@ -356,7 +354,7 @@ namespace Content.Server.GameTicking
|
||||
|
||||
private void UpdateLateJoinStatus()
|
||||
{
|
||||
var msg = new MsgTickerLateJoinStatus(null) {Disallowed = DisallowLateJoin};
|
||||
var msg = new MsgTickerLateJoinStatus(null!) {Disallowed = DisallowLateJoin};
|
||||
_netManager.ServerSendToAll(msg);
|
||||
}
|
||||
|
||||
@@ -382,8 +380,8 @@ namespace Content.Server.GameTicking
|
||||
|
||||
//Tell every client the round has ended.
|
||||
var roundEndMessage = _netManager.CreateNetMessage<MsgRoundEndMessage>();
|
||||
roundEndMessage.GamemodeTitle = Preset.ModeTitle;
|
||||
roundEndMessage.RoundEndText = roundEndText + $"\n{Preset.GetRoundEndDescription()}";
|
||||
roundEndMessage.GamemodeTitle = Preset?.ModeTitle ?? string.Empty;
|
||||
roundEndMessage.RoundEndText = roundEndText + $"\n{Preset?.GetRoundEndDescription() ?? string.Empty}";
|
||||
|
||||
//Get the timespan of the round.
|
||||
roundEndMessage.RoundDuration = IoCManager.Resolve<IGameTiming>().RealTime.Subtract(_roundStartTimeSpan);
|
||||
@@ -392,7 +390,8 @@ namespace Content.Server.GameTicking
|
||||
var listOfPlayerInfo = new List<RoundEndPlayerInfo>();
|
||||
foreach (var ply in PlayerManager.GetAllPlayers().OrderBy(p => p.Name))
|
||||
{
|
||||
var mind = ply.ContentData().Mind;
|
||||
var mind = ply.ContentData()?.Mind;
|
||||
|
||||
if (mind != null)
|
||||
{
|
||||
_playersInLobby.TryGetValue(ply, out var status);
|
||||
@@ -400,7 +399,7 @@ namespace Content.Server.GameTicking
|
||||
var playerEndRoundInfo = new RoundEndPlayerInfo()
|
||||
{
|
||||
PlayerOOCName = ply.Name,
|
||||
PlayerICName = mind.CurrentEntity.Name,
|
||||
PlayerICName = mind.CurrentEntity?.Name,
|
||||
Role = antag
|
||||
? mind.AllRoles.First(role => role.Antagonist).Name
|
||||
: mind.AllRoles.FirstOrDefault()?.Name ?? Loc.GetString("Unknown"),
|
||||
@@ -417,8 +416,10 @@ namespace Content.Server.GameTicking
|
||||
|
||||
public void Respawn(IPlayerSession targetPlayer)
|
||||
{
|
||||
targetPlayer.AttachedEntity.TryGetComponent<GhostComponent>(out var ghost);
|
||||
var ghost = targetPlayer.AttachedEntity?.GetComponentOrNull<GhostComponent>();
|
||||
|
||||
targetPlayer.ContentData()?.WipeMind();
|
||||
|
||||
if (ghost?.Deleted == false)
|
||||
ghost.Owner.Delete();
|
||||
|
||||
@@ -437,7 +438,7 @@ namespace Content.Server.GameTicking
|
||||
_netManager.ServerSendToAll(GetStatusSingle(player, PlayerStatus.Observer));
|
||||
}
|
||||
|
||||
public void MakeJoinGame(IPlayerSession player, string jobId = null)
|
||||
public void MakeJoinGame(IPlayerSession player, string? jobId = null)
|
||||
{
|
||||
if (!_playersInLobby.ContainsKey(player)) return;
|
||||
|
||||
@@ -473,7 +474,7 @@ namespace Content.Server.GameTicking
|
||||
|
||||
public bool OnGhostAttempt(Mind mind, bool canReturnGlobal)
|
||||
{
|
||||
return Preset.OnGhostAttempt(mind, canReturnGlobal);
|
||||
return Preset?.OnGhostAttempt(mind, canReturnGlobal) ?? false;
|
||||
}
|
||||
|
||||
public T AddGameRule<T>() where T : GameRule, new()
|
||||
@@ -488,14 +489,30 @@ namespace Content.Server.GameTicking
|
||||
return instance;
|
||||
}
|
||||
|
||||
public bool HasGameRule(Type t)
|
||||
public bool HasGameRule(string? name)
|
||||
{
|
||||
if (t == null || !typeof(GameRule).IsAssignableFrom(t))
|
||||
if (name == null)
|
||||
return false;
|
||||
|
||||
foreach (var rule in _gameRules)
|
||||
{
|
||||
if (rule.GetType().IsAssignableFrom(t))
|
||||
if (rule.GetType().Name == name)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public bool HasGameRule(Type? type)
|
||||
{
|
||||
if (type == null || !typeof(GameRule).IsAssignableFrom(type))
|
||||
return false;
|
||||
|
||||
foreach (var rule in _gameRules)
|
||||
{
|
||||
if (rule.GetType().IsAssignableFrom(type))
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -513,7 +530,7 @@ namespace Content.Server.GameTicking
|
||||
|
||||
public IEnumerable<GameRule> ActiveGameRules => _gameRules;
|
||||
|
||||
public bool TryGetPreset(string name, [NotNullWhen(true)] out Type type)
|
||||
public bool TryGetPreset(string name, [NotNullWhen(true)] out Type? type)
|
||||
{
|
||||
name = name.ToLowerInvariant();
|
||||
return Presets.TryGetValue(name, out type);
|
||||
@@ -597,12 +614,16 @@ namespace Content.Server.GameTicking
|
||||
return Paused;
|
||||
}
|
||||
|
||||
private IEntity _spawnPlayerMob(Job job, HumanoidCharacterProfile profile, bool lateJoin = true)
|
||||
private IEntity _spawnPlayerMob(Job job, HumanoidCharacterProfile? profile, bool lateJoin = true)
|
||||
{
|
||||
var coordinates = lateJoin ? GetLateJoinSpawnPoint() : GetJobSpawnPoint(job.Prototype.ID);
|
||||
var entity = _entityManager.SpawnEntity(PlayerPrototypeName, coordinates);
|
||||
var startingGear = _prototypeManager.Index<StartingGearPrototype>(job.StartingGear);
|
||||
EquipStartingGear(entity, startingGear, profile);
|
||||
|
||||
if (job.StartingGear != null)
|
||||
{
|
||||
var startingGear = _prototypeManager.Index<StartingGearPrototype>(job.StartingGear);
|
||||
EquipStartingGear(entity, startingGear, profile);
|
||||
}
|
||||
|
||||
if (profile != null)
|
||||
{
|
||||
@@ -613,9 +634,9 @@ namespace Content.Server.GameTicking
|
||||
return entity;
|
||||
}
|
||||
|
||||
public void EquipStartingGear(IEntity entity, StartingGearPrototype startingGear, HumanoidCharacterProfile profile)
|
||||
public void EquipStartingGear(IEntity entity, StartingGearPrototype startingGear, HumanoidCharacterProfile? profile)
|
||||
{
|
||||
if (entity.TryGetComponent(out InventoryComponent inventory))
|
||||
if (entity.TryGetComponent(out InventoryComponent? inventory))
|
||||
{
|
||||
foreach (var slot in AllSlots)
|
||||
{
|
||||
@@ -628,7 +649,7 @@ namespace Content.Server.GameTicking
|
||||
}
|
||||
}
|
||||
|
||||
if (entity.TryGetComponent(out HandsComponent handsComponent))
|
||||
if (entity.TryGetComponent(out HandsComponent? handsComponent))
|
||||
{
|
||||
var inhand = startingGear.Inhand;
|
||||
foreach (var (hand, prototype) in inhand)
|
||||
@@ -669,7 +690,7 @@ namespace Content.Server.GameTicking
|
||||
foreach (var entity in _entityManager.GetEntities(new TypeEntityQuery(typeof(SpawnPointComponent))))
|
||||
{
|
||||
var point = entity.GetComponent<SpawnPointComponent>();
|
||||
if (point.SpawnType == SpawnPointType.Job && point.Job.ID == jobId)
|
||||
if (point.SpawnType == SpawnPointType.Job && point.Job?.ID == jobId)
|
||||
possiblePoints.Add(entity.Transform.Coordinates);
|
||||
}
|
||||
|
||||
@@ -754,7 +775,13 @@ namespace Content.Server.GameTicking
|
||||
{
|
||||
DefaultMap = _mapManager.CreateMap();
|
||||
var startTime = _gameTiming.RealTime;
|
||||
var grid = _mapLoader.LoadBlueprint(DefaultMap, GetMap());
|
||||
var map = GetMap();
|
||||
var grid = _mapLoader.LoadBlueprint(DefaultMap, map);
|
||||
|
||||
if (grid == null)
|
||||
{
|
||||
throw new InvalidOperationException($"No grid found for map {map}");
|
||||
}
|
||||
|
||||
DefaultGridId = grid.Index;
|
||||
_spawnPoint = grid.ToCoordinates();
|
||||
@@ -763,7 +790,7 @@ namespace Content.Server.GameTicking
|
||||
Logger.InfoS("ticker", $"Loaded map in {timeSpan.TotalMilliseconds:N2}ms.");
|
||||
}
|
||||
|
||||
protected override void PlayerStatusChanged(object sender, SessionStatusEventArgs args)
|
||||
protected override void PlayerStatusChanged(object? sender, SessionStatusEventArgs args)
|
||||
{
|
||||
base.PlayerStatusChanged(sender, args);
|
||||
|
||||
@@ -794,7 +821,10 @@ namespace Content.Server.GameTicking
|
||||
_prefsManager.OnClientConnected(session);
|
||||
|
||||
var data = session.ContentData();
|
||||
if (data.Mind == null)
|
||||
|
||||
DebugTools.AssertNotNull(data);
|
||||
|
||||
if (data!.Mind == null)
|
||||
{
|
||||
if (LobbyEnabled)
|
||||
{
|
||||
@@ -871,7 +901,7 @@ namespace Content.Server.GameTicking
|
||||
}, _updateShutdownCts.Token);
|
||||
}
|
||||
|
||||
private void SpawnPlayer(IPlayerSession session, string jobId = null, bool lateJoin = true)
|
||||
private void SpawnPlayer(IPlayerSession session, string? jobId = null, bool lateJoin = true)
|
||||
{
|
||||
var character = GetPlayerProfile(session);
|
||||
|
||||
@@ -881,7 +911,7 @@ namespace Content.Server.GameTicking
|
||||
|
||||
private void SpawnPlayer(IPlayerSession session,
|
||||
HumanoidCharacterProfile character,
|
||||
string jobId = null,
|
||||
string? jobId = null,
|
||||
bool lateJoin = true)
|
||||
{
|
||||
if (lateJoin && DisallowLateJoin)
|
||||
@@ -893,17 +923,17 @@ namespace Content.Server.GameTicking
|
||||
_playerJoinGame(session);
|
||||
|
||||
var data = session.ContentData();
|
||||
data.WipeMind();
|
||||
|
||||
DebugTools.AssertNotNull(data);
|
||||
|
||||
data!.WipeMind();
|
||||
data.Mind = new Mind(session.UserId)
|
||||
{
|
||||
CharacterName = character.Name
|
||||
};
|
||||
|
||||
if (jobId == null)
|
||||
{
|
||||
// Pick best job best on prefs.
|
||||
jobId = PickBestAvailableJob(character);
|
||||
}
|
||||
// Pick best job best on prefs.
|
||||
jobId ??= PickBestAvailableJob(character);
|
||||
|
||||
var jobPrototype = _prototypeManager.Index<JobPrototype>(jobId);
|
||||
var job = new Job(data.Mind, jobPrototype);
|
||||
@@ -931,14 +961,14 @@ namespace Content.Server.GameTicking
|
||||
EquipIdCard(mob, character.Name, jobPrototype);
|
||||
jobPrototype.Special?.AfterEquip(mob);
|
||||
|
||||
Preset.OnSpawnPlayerCompleted(session, mob, lateJoin);
|
||||
Preset?.OnSpawnPlayerCompleted(session, mob, lateJoin);
|
||||
}
|
||||
|
||||
private void EquipIdCard(IEntity mob, string characterName, JobPrototype jobPrototype)
|
||||
{
|
||||
var inventory = mob.GetComponent<InventoryComponent>();
|
||||
|
||||
if (!inventory.TryGetSlotItem(Slots.IDCARD, out ItemComponent pdaItem))
|
||||
if (!inventory.TryGetSlotItem(Slots.IDCARD, out ItemComponent? pdaItem))
|
||||
{
|
||||
return;
|
||||
}
|
||||
@@ -946,7 +976,7 @@ namespace Content.Server.GameTicking
|
||||
var pda = pdaItem.Owner;
|
||||
|
||||
var pdaComponent = pda.GetComponent<PDAComponent>();
|
||||
if (pdaComponent.IdSlotEmpty)
|
||||
if (pdaComponent.ContainedID == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
@@ -973,7 +1003,10 @@ namespace Content.Server.GameTicking
|
||||
var name = GetPlayerProfile(session).Name;
|
||||
|
||||
var data = session.ContentData();
|
||||
data.WipeMind();
|
||||
|
||||
DebugTools.AssertNotNull(data);
|
||||
|
||||
data!.WipeMind();
|
||||
data.Mind = new Mind(session.UserId);
|
||||
|
||||
var mob = _spawnObserverMob();
|
||||
@@ -1069,6 +1102,11 @@ namespace Content.Server.GameTicking
|
||||
|
||||
private string GetInfoText()
|
||||
{
|
||||
if (Preset == null)
|
||||
{
|
||||
return string.Empty;
|
||||
}
|
||||
|
||||
var gmTitle = Preset.ModeTitle;
|
||||
var desc = Preset.Description;
|
||||
return Loc.GetString(@"Hi and welcome to [color=white]Space Station 14![/color]
|
||||
|
||||
Reference in New Issue
Block a user