diff --git a/Content.Client/GameObjects/Components/HandheldLightComponent.cs b/Content.Client/GameObjects/Components/HandheldLightComponent.cs index b97f0717e7..d6f4a75aaa 100644 --- a/Content.Client/GameObjects/Components/HandheldLightComponent.cs +++ b/Content.Client/GameObjects/Components/HandheldLightComponent.cs @@ -1,4 +1,4 @@ -using System; +using System; using Content.Shared.GameObjects.Components; using Robust.Client.Graphics.Drawing; using Robust.Client.UserInterface; @@ -22,7 +22,8 @@ namespace Content.Client.GameObjects.Components public override void HandleComponentState(ComponentState curState, ComponentState nextState) { - var cast = (HandheldLightComponentState) curState; + if (!(curState is HandheldLightComponentState cast)) + return; Charge = cast.Charge; } diff --git a/Content.Client/GameObjects/Components/Mobs/CombatModeComponent.cs b/Content.Client/GameObjects/Components/Mobs/CombatModeComponent.cs index 06b0235838..e003d99569 100644 --- a/Content.Client/GameObjects/Components/Mobs/CombatModeComponent.cs +++ b/Content.Client/GameObjects/Components/Mobs/CombatModeComponent.cs @@ -31,7 +31,8 @@ namespace Content.Client.GameObjects.Components.Mobs { base.HandleComponentState(curState, nextState); - var state = (CombatModeComponentState) curState; + if (!(curState is CombatModeComponentState state)) + return; IsInCombatMode = state.IsInCombatMode; ActiveZone = state.TargetingZone; diff --git a/Content.Client/GameObjects/Components/StackComponent.cs b/Content.Client/GameObjects/Components/StackComponent.cs index 9c47f69470..717372091a 100644 --- a/Content.Client/GameObjects/Components/StackComponent.cs +++ b/Content.Client/GameObjects/Components/StackComponent.cs @@ -1,4 +1,4 @@ -using Content.Client.UserInterface; +using Content.Client.UserInterface; using Content.Client.Utility; using Content.Shared.GameObjects.Components; using Robust.Client.UserInterface; @@ -22,7 +22,8 @@ namespace Content.Client.GameObjects.Components public override void HandleComponentState(ComponentState curState, ComponentState nextState) { - var cast = (StackComponentState) curState; + if (!(curState is StackComponentState cast)) + return; Count = cast.Count; MaxCount = cast.MaxCount; diff --git a/Content.Client/GameObjects/Components/Weapons/Ranged/BallisticMagazineWeaponComponent.cs b/Content.Client/GameObjects/Components/Weapons/Ranged/BallisticMagazineWeaponComponent.cs index b5eb8bd044..1917dbcd65 100644 --- a/Content.Client/GameObjects/Components/Weapons/Ranged/BallisticMagazineWeaponComponent.cs +++ b/Content.Client/GameObjects/Components/Weapons/Ranged/BallisticMagazineWeaponComponent.cs @@ -1,4 +1,4 @@ -using System; +using System; using Content.Client.Animations; using Content.Client.UserInterface; using Content.Client.Utility; @@ -99,7 +99,8 @@ namespace Content.Client.GameObjects.Components.Weapons.Ranged public override void HandleComponentState(ComponentState curState, ComponentState nextState) { - var cast = (BallisticMagazineWeaponComponentState) curState; + if (!(curState is BallisticMagazineWeaponComponentState cast)) + return; Chambered = cast.Chambered; MagazineCount = cast.MagazineCount; diff --git a/Content.Client/GameObjects/Components/WelderComponent.cs b/Content.Client/GameObjects/Components/WelderComponent.cs index 088894e1d3..dc7387b559 100644 --- a/Content.Client/GameObjects/Components/WelderComponent.cs +++ b/Content.Client/GameObjects/Components/WelderComponent.cs @@ -1,4 +1,4 @@ -using System; +using System; using Content.Client.UserInterface; using Content.Client.Utility; using Content.Shared.GameObjects; @@ -26,7 +26,8 @@ namespace Content.Client.GameObjects.Components public override void HandleComponentState(ComponentState curState, ComponentState nextState) { - var cast = (WelderComponentState) curState; + if (!(curState is WelderComponentState cast)) + return; FuelCapacity = cast.FuelCapacity; Fuel = cast.Fuel; diff --git a/Content.Shared/GameObjects/Components/Items/ItemCooldownComponent.cs b/Content.Shared/GameObjects/Components/Items/ItemCooldownComponent.cs index 9943c7f9a3..c2425cc9bc 100644 --- a/Content.Shared/GameObjects/Components/Items/ItemCooldownComponent.cs +++ b/Content.Shared/GameObjects/Components/Items/ItemCooldownComponent.cs @@ -1,4 +1,4 @@ -using System; +using System; using Robust.Shared.GameObjects; using Robust.Shared.Serialization; using Robust.Shared.ViewVariables; @@ -62,7 +62,8 @@ namespace Content.Shared.GameObjects.Components.Items public override void HandleComponentState(ComponentState curState, ComponentState nextState) { - var cast = (ItemCooldownComponentState) curState; + if (!(curState is ItemCooldownComponentState cast)) + return; CooldownStart = cast.CooldownStart; CooldownEnd = cast.CooldownEnd; diff --git a/Content.Shared/GameObjects/Components/Mobs/SharedHumanoidAppearanceComponent.cs b/Content.Shared/GameObjects/Components/Mobs/SharedHumanoidAppearanceComponent.cs index b50430a8d5..93f13b549e 100644 --- a/Content.Shared/GameObjects/Components/Mobs/SharedHumanoidAppearanceComponent.cs +++ b/Content.Shared/GameObjects/Components/Mobs/SharedHumanoidAppearanceComponent.cs @@ -1,4 +1,4 @@ -using System; +using System; using Content.Shared.Preferences; using Robust.Shared.GameObjects; using Robust.Shared.Serialization; @@ -43,7 +43,9 @@ namespace Content.Shared.GameObjects.Components.Mobs public override void HandleComponentState(ComponentState curState, ComponentState nextState) { - var cast = (HumanoidAppearanceComponentState) curState; + if (!(curState is HumanoidAppearanceComponentState cast)) + return; + Appearance = cast.Appearance; Sex = cast.Sex; } diff --git a/Content.Tests/Shared/Gamestates/ComponentStateNullTest.cs b/Content.Tests/Shared/Gamestates/ComponentStateNullTest.cs new file mode 100644 index 0000000000..5bf4709ff5 --- /dev/null +++ b/Content.Tests/Shared/Gamestates/ComponentStateNullTest.cs @@ -0,0 +1,75 @@ +using System; +using System.Collections.Generic; +using System.Reflection; +using NUnit.Framework; +using Robust.Shared.ContentPack; +using Robust.Shared.GameObjects; +using Robust.Shared.Interfaces.GameObjects; +using Robust.Shared.Interfaces.Reflection; +using Robust.Shared.Reflection; + +namespace Content.Tests.Shared.GameStates +{ + [TestFixture] + public class ComponentStateNullTest + { + [Test] + public void HandleComponentState_NullStates_NotThrow() + { + var reflection = ReflectionManagerFactory(); + var comps = reflection.GetAllChildren(); + + foreach (var compType in comps) + { + // Any component should be able to be instantiated without DI injection. + var compInstance = (IComponent) Activator.CreateInstance(compType); + + // Any component should treat this as a null function. + compInstance.HandleComponentState(null, null); + } + } + + private static IReflectionManager ReflectionManagerFactory() + { + AppDomain.CurrentDomain.Load("Robust.Client"); + AppDomain.CurrentDomain.Load("Content.Client"); + AppDomain.CurrentDomain.Load("Robust.Server"); + AppDomain.CurrentDomain.Load("Content.Server"); + AppDomain.CurrentDomain.Load("Robust.Shared"); + AppDomain.CurrentDomain.Load("Content.Shared"); + + var assemblies = new List(7); + assemblies.Add(AppDomain.CurrentDomain.GetAssemblyByName("Robust.Client")); + assemblies.Add(AppDomain.CurrentDomain.GetAssemblyByName("Content.Client")); + assemblies.Add(AppDomain.CurrentDomain.GetAssemblyByName("Robust.Server")); + assemblies.Add(AppDomain.CurrentDomain.GetAssemblyByName("Content.Server")); + assemblies.Add(AppDomain.CurrentDomain.GetAssemblyByName("Robust.Shared")); + assemblies.Add(AppDomain.CurrentDomain.GetAssemblyByName("Content.Shared")); + assemblies.Add(Assembly.GetExecutingAssembly()); + + var reflection = new FullReflectionManager(); + + reflection.LoadAssemblies(assemblies); + + return reflection; + } + + private class FullReflectionManager : ReflectionManager + { + protected override IEnumerable TypePrefixes => Prefixes; + + private static readonly string[] Prefixes = { + "", + + "Robust.Client.", + "Content.Client.", + + "Robust.Shared.", + "Content.Shared.", + + "Robust.Server.", + "Content.Server.", + }; + } + } +}