From 315b0621bc32d1944b487e4f6bf42024f16c9ebf Mon Sep 17 00:00:00 2001 From: Pieter-Jan Briers Date: Fri, 20 Nov 2020 15:45:10 +0100 Subject: [PATCH 01/13] Use IDynamicTypeFactory instead of new T() in SharedMechanismComponent.cs --- .../Components/Body/Mechanism/SharedMechanismComponent.cs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/Content.Shared/GameObjects/Components/Body/Mechanism/SharedMechanismComponent.cs b/Content.Shared/GameObjects/Components/Body/Mechanism/SharedMechanismComponent.cs index 4c5e1b9b5d..a53fc0cc73 100644 --- a/Content.Shared/GameObjects/Components/Body/Mechanism/SharedMechanismComponent.cs +++ b/Content.Shared/GameObjects/Components/Body/Mechanism/SharedMechanismComponent.cs @@ -158,8 +158,7 @@ namespace Content.Shared.GameObjects.Components.Body.Mechanism return true; } - behavior = new T(); - IoCManager.InjectDependencies(behavior); + behavior = IoCManager.Resolve().CreateInstance(); _behaviors.Add(typeof(T), behavior); behavior.Initialize(this); behavior.Startup(); From 20fb55d8e920028f58fc0f5cb023991b607b1fa8 Mon Sep 17 00:00:00 2001 From: Pieter-Jan Briers Date: Fri, 20 Nov 2020 16:01:56 +0100 Subject: [PATCH 02/13] "sandboxing" is a word. --- SpaceStation14.sln.DotSettings | 1 + 1 file changed, 1 insertion(+) diff --git a/SpaceStation14.sln.DotSettings b/SpaceStation14.sln.DotSettings index 27f3ba2fc7..5a253ba69d 100644 --- a/SpaceStation14.sln.DotSettings +++ b/SpaceStation14.sln.DotSettings @@ -131,6 +131,7 @@ True True True + True True True True From 82ecdea5090f587eebea6b01c089a4e01a177a8e Mon Sep 17 00:00:00 2001 From: Pieter-Jan Briers Date: Mon, 23 Nov 2020 00:43:12 +0100 Subject: [PATCH 03/13] Fix incorrect usages of expression DataField. --- Content.Shared/Atmos/GasPrototype.cs | 22 +++++++++---------- .../SharedExpendableLightComponent.cs | 22 +++++++++---------- 2 files changed, 22 insertions(+), 22 deletions(-) diff --git a/Content.Shared/Atmos/GasPrototype.cs b/Content.Shared/Atmos/GasPrototype.cs index 3186b09847..1878f6a9b0 100644 --- a/Content.Shared/Atmos/GasPrototype.cs +++ b/Content.Shared/Atmos/GasPrototype.cs @@ -67,17 +67,17 @@ namespace Content.Shared.Atmos { var serializer = YamlObjectSerializer.NewReader(mapping); - serializer.DataField(this, x => ID, "id", string.Empty); - serializer.DataField(this, x => Name, "name", string.Empty); - serializer.DataField(this, x => OverlayPath, "overlayPath", string.Empty); - serializer.DataField(this, x => SpecificHeat, "specificHeat", 0f); - serializer.DataField(this, x => HeatCapacityRatio, "heatCapacityRatio", 1.4f); - serializer.DataField(this, x => MolarMass, "molarMass", 1f); - serializer.DataField(this, x => GasMolesVisible, "gasMolesVisible", 0.25f); - serializer.DataField(this, x => GasOverlayTexture, "gasOverlayTexture", string.Empty); - serializer.DataField(this, x => GasOverlaySprite, "gasOverlaySprite", string.Empty); - serializer.DataField(this, x => GasOverlayState, "gasOverlayState", string.Empty); - serializer.DataField(this, x => Color, "color", string.Empty); + serializer.DataField(this, x => x.ID, "id", string.Empty); + serializer.DataField(this, x => x.Name, "name", string.Empty); + serializer.DataField(this, x => x.OverlayPath, "overlayPath", string.Empty); + serializer.DataField(this, x => x.SpecificHeat, "specificHeat", 0f); + serializer.DataField(this, x => x.HeatCapacityRatio, "heatCapacityRatio", 1.4f); + serializer.DataField(this, x => x.MolarMass, "molarMass", 1f); + serializer.DataField(this, x => x.GasMolesVisible, "gasMolesVisible", 0.25f); + serializer.DataField(this, x => x.GasOverlayTexture, "gasOverlayTexture", string.Empty); + serializer.DataField(this, x => x.GasOverlaySprite, "gasOverlaySprite", string.Empty); + serializer.DataField(this, x => x.GasOverlayState, "gasOverlayState", string.Empty); + serializer.DataField(this, x => x.Color, "color", string.Empty); } } } diff --git a/Content.Shared/GameObjects/Components/SharedExpendableLightComponent.cs b/Content.Shared/GameObjects/Components/SharedExpendableLightComponent.cs index 5db6ad8f9b..64ad517b91 100644 --- a/Content.Shared/GameObjects/Components/SharedExpendableLightComponent.cs +++ b/Content.Shared/GameObjects/Components/SharedExpendableLightComponent.cs @@ -64,17 +64,17 @@ namespace Content.Shared.GameObjects.Components { base.ExposeData(serializer); - serializer.DataField(this, x => TurnOnBehaviourID, "turnOnBehaviourID", string.Empty); - serializer.DataField(this, x => FadeOutBehaviourID, "fadeOutBehaviourID", string.Empty); - serializer.DataField(this, x => GlowDuration, "glowDuration", 60 * 15f); - serializer.DataField(this, x => FadeOutDuration, "fadeOutDuration", 60 * 5f); - serializer.DataField(this, x => SpentName, "spentName", string.Empty); - serializer.DataField(this, x => SpentDesc, "spentDesc", string.Empty); - serializer.DataField(this, x => IconStateLit, "iconStateOn", string.Empty); - serializer.DataField(this, x => IconStateSpent, "iconStateSpent", string.Empty); - serializer.DataField(this, x => LitSound, "litSound", string.Empty); - serializer.DataField(this, x => LoopedSound, "loopedSound", string.Empty); - serializer.DataField(this, x => DieSound, "dieSound", string.Empty); + serializer.DataField(this, x => x.TurnOnBehaviourID, "turnOnBehaviourID", string.Empty); + serializer.DataField(this, x => x.FadeOutBehaviourID, "fadeOutBehaviourID", string.Empty); + serializer.DataField(this, x => x.GlowDuration, "glowDuration", 60 * 15f); + serializer.DataField(this, x => x.FadeOutDuration, "fadeOutDuration", 60 * 5f); + serializer.DataField(this, x => x.SpentName, "spentName", string.Empty); + serializer.DataField(this, x => x.SpentDesc, "spentDesc", string.Empty); + serializer.DataField(this, x => x.IconStateLit, "iconStateOn", string.Empty); + serializer.DataField(this, x => x.IconStateSpent, "iconStateSpent", string.Empty); + serializer.DataField(this, x => x.LitSound, "litSound", string.Empty); + serializer.DataField(this, x => x.LoopedSound, "loopedSound", string.Empty); + serializer.DataField(this, x => x.DieSound, "dieSound", string.Empty); } } } From fcb5787d339b22fc8ac8e33ab7b5f753bf136c40 Mon Sep 17 00:00:00 2001 From: Pieter-Jan Briers Date: Tue, 24 Nov 2020 00:14:23 +0100 Subject: [PATCH 04/13] Use YamlDotNet to load patrons JSON file. So that i don't have to add Newtonsoft.Json stuff to the sandbox whitelist. YAML is a JSON superset after all... --- Content.Client/UserInterface/CreditsWindow.cs | 42 +++++++++---------- 1 file changed, 20 insertions(+), 22 deletions(-) diff --git a/Content.Client/UserInterface/CreditsWindow.cs b/Content.Client/UserInterface/CreditsWindow.cs index 1bdd4c7a76..c43271c270 100644 --- a/Content.Client/UserInterface/CreditsWindow.cs +++ b/Content.Client/UserInterface/CreditsWindow.cs @@ -3,7 +3,6 @@ using System.Collections.Generic; using System.IO; using System.Linq; using Content.Client.UserInterface.Stylesheets; -using Newtonsoft.Json; using Robust.Client.Credits; using Robust.Client.Interfaces.ResourceManagement; using Robust.Client.UserInterface; @@ -13,6 +12,7 @@ using Robust.Shared.IoC; using Robust.Shared.Localization; using Robust.Shared.Maths; using Robust.Shared.Utility; +using YamlDotNet.RepresentationModel; namespace Content.Client.UserInterface { @@ -82,7 +82,7 @@ namespace Content.Client.UserInterface var margin = new MarginContainer {MarginLeftOverride = 2, MarginTopOverride = 2}; var vBox = new VBoxContainer(); margin.AddChild(vBox); - var patrons = ReadJson("/Credits/Patrons.json"); + var patrons = LoadPatrons(); Button patronButton; vBox.AddChild(patronButton = new Button @@ -117,6 +117,16 @@ namespace Content.Client.UserInterface patronsList.AddChild(margin); } + private IEnumerable LoadPatrons() + { + var yamlStream = _resourceManager.ContentFileReadYaml(new ResourcePath("/Credits/Patrons.json")); + var sequence = (YamlSequenceNode) yamlStream.Documents[0].RootNode; + + return sequence + .Cast() + .Select(m => new PatronEntry(m["Name"].AsString(), m["Tier"].AsString())); + } + private void PopulateCredits(Control contributorsList) { Button contributeButton; @@ -141,6 +151,7 @@ namespace Content.Client.UserInterface }); var first = true; + void AddSection(string title, string path, bool markup = false) { if (!first) @@ -190,29 +201,16 @@ namespace Content.Client.UserInterface } } - private T ReadJson(string path) - { - var serializer = new JsonSerializer(); - - using var stream = _resourceManager.ContentFileRead(path); - using var streamReader = new StreamReader(stream); - using var jsonTextReader = new JsonTextReader(streamReader); - - return serializer.Deserialize(jsonTextReader)!; - } - - [JsonObject(ItemRequired = Required.Always)] private sealed class PatronEntry { - public string Name { get; set; } = default!; - public string Tier { get; set; } = default!; - } + public string Name { get; } + public string Tier { get; } - [JsonObject(ItemRequired = Required.Always)] - private sealed class OpenSourceLicense - { - public string Name { get; set; } = default!; - public string License { get; set; } = default!; + public PatronEntry(string name, string tier) + { + Name = name; + Tier = tier; + } } } } From 6395345925c30f683f02d1289ed1a1a1cb5b3841 Mon Sep 17 00:00:00 2001 From: Pieter-Jan Briers Date: Tue, 24 Nov 2020 00:14:46 +0100 Subject: [PATCH 05/13] Fix bad reflection usage from OverlayEffectsComponent. --- .../Mobs/ClientOverlayEffectsComponent.cs | 20 ++++--------------- .../Graphics/Overlays/FlashOverlay.cs | 9 ++++++--- Content.Shared/Interfaces/IConfigurable.cs | 7 ------- .../Interfaces/IConfigurableOverlay.cs | 9 +++++++++ 4 files changed, 19 insertions(+), 26 deletions(-) delete mode 100644 Content.Shared/Interfaces/IConfigurable.cs create mode 100644 Content.Shared/Interfaces/IConfigurableOverlay.cs diff --git a/Content.Client/GameObjects/Components/Mobs/ClientOverlayEffectsComponent.cs b/Content.Client/GameObjects/Components/Mobs/ClientOverlayEffectsComponent.cs index 8aae18facf..34a3f25e1e 100644 --- a/Content.Client/GameObjects/Components/Mobs/ClientOverlayEffectsComponent.cs +++ b/Content.Client/GameObjects/Components/Mobs/ClientOverlayEffectsComponent.cs @@ -141,23 +141,11 @@ namespace Content.Client.GameObjects.Components.Mobs private void UpdateOverlayConfiguration(OverlayContainer container, Overlay overlay) { - var configurableTypes = overlay.GetType() - .GetInterfaces() - .Where(type => - type.IsGenericType - && type.GetGenericTypeDefinition() == typeof(IConfigurable<>) - && container.Parameters.Exists(p => p.GetType() == type.GenericTypeArguments.First())) - .ToList(); - - if (configurableTypes.Count > 0) + if (overlay is IConfigurableOverlay configurable) { - foreach (var type in configurableTypes) + foreach (var param in container.Parameters) { - var method = type.GetMethod(nameof(IConfigurable.Configure)); - var parameter = container.Parameters - .First(p => p.GetType() == type.GenericTypeArguments.First()); - - method!.Invoke(overlay, new []{ parameter }); + configurable.Configure(param); } } } @@ -169,7 +157,7 @@ namespace Content.Client.GameObjects.Components.Mobs if (overlayType != null) { - overlay = Activator.CreateInstance(overlayType) as Overlay; + overlay = IoCManager.Resolve().CreateInstance(overlayType); UpdateOverlayConfiguration(container, overlay); return true; } diff --git a/Content.Client/Graphics/Overlays/FlashOverlay.cs b/Content.Client/Graphics/Overlays/FlashOverlay.cs index 278e2c0884..547e4dcb17 100644 --- a/Content.Client/Graphics/Overlays/FlashOverlay.cs +++ b/Content.Client/Graphics/Overlays/FlashOverlay.cs @@ -14,7 +14,7 @@ using SixLabors.ImageSharp.PixelFormats; namespace Content.Client.Graphics.Overlays { - public class FlashOverlay : Overlay, IConfigurable + public class FlashOverlay : Overlay, IConfigurableOverlay { [Dependency] private readonly IPrototypeManager _prototypeManager = default!; [Dependency] private readonly IClyde _displayManager = default!; @@ -61,9 +61,12 @@ namespace Content.Client.Graphics.Overlays _screenshotTexture = null; } - public void Configure(TimedOverlayParameter parameters) + public void Configure(OverlayParameter parameters) { - _lastsFor = parameters.Length; + if (parameters is TimedOverlayParameter timedParams) + { + _lastsFor = timedParams.Length; + } } } } diff --git a/Content.Shared/Interfaces/IConfigurable.cs b/Content.Shared/Interfaces/IConfigurable.cs deleted file mode 100644 index 17fbe07880..0000000000 --- a/Content.Shared/Interfaces/IConfigurable.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Content.Shared.Interfaces -{ - public interface IConfigurable - { - public void Configure(T parameters); - } -} diff --git a/Content.Shared/Interfaces/IConfigurableOverlay.cs b/Content.Shared/Interfaces/IConfigurableOverlay.cs new file mode 100644 index 0000000000..e1f0a6b974 --- /dev/null +++ b/Content.Shared/Interfaces/IConfigurableOverlay.cs @@ -0,0 +1,9 @@ +using Content.Shared.GameObjects.Components.Mobs; + +namespace Content.Shared.Interfaces +{ + public interface IConfigurableOverlay + { + void Configure(OverlayParameter parameter); + } +} From e59aa1c2cc5757827f852917bd2225a7254ac1b0 Mon Sep 17 00:00:00 2001 From: Pieter-Jan Briers Date: Tue, 24 Nov 2020 00:15:00 +0100 Subject: [PATCH 06/13] Fix another case of constant expression DataField. --- .../GameObjects/Components/Instruments/InstrumentComponent.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Content.Client/GameObjects/Components/Instruments/InstrumentComponent.cs b/Content.Client/GameObjects/Components/Instruments/InstrumentComponent.cs index d30bcf6da9..82c46e5a94 100644 --- a/Content.Client/GameObjects/Components/Instruments/InstrumentComponent.cs +++ b/Content.Client/GameObjects/Components/Instruments/InstrumentComponent.cs @@ -227,7 +227,7 @@ namespace Content.Client.GameObjects.Components.Instruments public override void ExposeData(ObjectSerializer serializer) { base.ExposeData(serializer); - serializer.DataField(this, x => Handheld, "handheld", false); + serializer.DataField(this, x => x.Handheld, "handheld", false); serializer.DataField(ref _instrumentProgram, "program", (byte) 1); serializer.DataField(ref _instrumentBank, "bank", (byte) 0); serializer.DataField(ref _allowPercussion, "allowPercussion", false); From 21976e265cb36f070f2ede57fa3ba0897b7a6423 Mon Sep 17 00:00:00 2001 From: Pieter-Jan Briers Date: Tue, 24 Nov 2020 00:15:30 +0100 Subject: [PATCH 07/13] Remove Nett .Get<> methods from content. They could allow bypassing sandbox due to how the deserialization logic works. --- Content.Client/Parallax/ParallaxGenerator.cs | 65 ++++++++++---------- 1 file changed, 32 insertions(+), 33 deletions(-) diff --git a/Content.Client/Parallax/ParallaxGenerator.cs b/Content.Client/Parallax/ParallaxGenerator.cs index ab358c2b41..d905c19dd9 100644 --- a/Content.Client/Parallax/ParallaxGenerator.cs +++ b/Content.Client/Parallax/ParallaxGenerator.cs @@ -44,18 +44,17 @@ namespace Content.Client.Parallax private void _loadConfig(TomlTable config) { - foreach (var layerArray in config.Get("layers").Items) + foreach (var layerArray in ((TomlTableArray)config.Get("layers")).Items) { - var layer = layerArray.Get(); - switch (layer.Get("type")) + switch (((TomlValue) layerArray.Get("type")).Value) { case "noise": - var layerNoise = new LayerNoise(layer); + var layerNoise = new LayerNoise(layerArray); Layers.Add(layerNoise); break; case "points": - var layerPoint = new LayerPoints(layer); + var layerPoint = new LayerPoints(layerArray); Layers.Add(layerPoint); break; @@ -89,62 +88,62 @@ namespace Content.Client.Parallax { if (table.TryGetValue("innercolor", out var tomlObject)) { - InnerColor = Color.FromHex(tomlObject.Get()); + InnerColor = Color.FromHex(((TomlValue) tomlObject).Value); } if (table.TryGetValue("outercolor", out tomlObject)) { - OuterColor = Color.FromHex(tomlObject.Get()); + OuterColor = Color.FromHex(((TomlValue) tomlObject).Value); } if (table.TryGetValue("seed", out tomlObject)) { - Seed = (uint) tomlObject.Get(); + Seed = (uint) ((TomlValue) tomlObject).Value; } if (table.TryGetValue("persistence", out tomlObject)) { - Persistence = float.Parse(tomlObject.Get(), CultureInfo.InvariantCulture); + Persistence = float.Parse(((TomlValue) tomlObject).Value, CultureInfo.InvariantCulture); } if (table.TryGetValue("lacunarity", out tomlObject)) { - Lacunarity = float.Parse(tomlObject.Get(), CultureInfo.InvariantCulture); + Lacunarity = float.Parse(((TomlValue) tomlObject).Value, CultureInfo.InvariantCulture); } if (table.TryGetValue("frequency", out tomlObject)) { - Frequency = float.Parse(tomlObject.Get(), CultureInfo.InvariantCulture); + Frequency = float.Parse(((TomlValue) tomlObject).Value, CultureInfo.InvariantCulture); } if (table.TryGetValue("octaves", out tomlObject)) { - Octaves = (uint) tomlObject.Get(); + Octaves = (uint) ((TomlValue) tomlObject).Value; } if (table.TryGetValue("threshold", out tomlObject)) { - Threshold = float.Parse(tomlObject.Get(), CultureInfo.InvariantCulture); + Threshold = float.Parse(((TomlValue) tomlObject).Value, CultureInfo.InvariantCulture); } if (table.TryGetValue("sourcefactor", out tomlObject)) { - SrcFactor = (Color.BlendFactor) Enum.Parse(typeof(Color.BlendFactor), tomlObject.Get()); + SrcFactor = (Color.BlendFactor) Enum.Parse(typeof(Color.BlendFactor), ((TomlValue) tomlObject).Value); } if (table.TryGetValue("destfactor", out tomlObject)) { - DstFactor = (Color.BlendFactor) Enum.Parse(typeof(Color.BlendFactor), tomlObject.Get()); + DstFactor = (Color.BlendFactor) Enum.Parse(typeof(Color.BlendFactor), ((TomlValue) tomlObject).Value); } if (table.TryGetValue("power", out tomlObject)) { - Power = float.Parse(tomlObject.Get(), CultureInfo.InvariantCulture); + Power = float.Parse(((TomlValue) tomlObject).Value, CultureInfo.InvariantCulture); } if (table.TryGetValue("noise_type", out tomlObject)) { - switch (tomlObject.Get()) + switch (((TomlValue) tomlObject).Value) { case "fbm": NoiseType = NoiseGenerator.NoiseType.Fbm; @@ -226,78 +225,78 @@ namespace Content.Client.Parallax { if (table.TryGetValue("seed", out var tomlObject)) { - Seed = tomlObject.Get(); + Seed = ((TomlValue) tomlObject).Value; } if (table.TryGetValue("count", out tomlObject)) { - PointCount = tomlObject.Get(); + PointCount = ((TomlValue) tomlObject).Value; } if (table.TryGetValue("sourcefactor", out tomlObject)) { - SrcFactor = (Color.BlendFactor) Enum.Parse(typeof(Color.BlendFactor), tomlObject.Get()); + SrcFactor = (Color.BlendFactor) Enum.Parse(typeof(Color.BlendFactor), ((TomlValue) tomlObject).Value); } if (table.TryGetValue("destfactor", out tomlObject)) { - DstFactor = (Color.BlendFactor) Enum.Parse(typeof(Color.BlendFactor), tomlObject.Get()); + DstFactor = (Color.BlendFactor) Enum.Parse(typeof(Color.BlendFactor), ((TomlValue) tomlObject).Value); } if (table.TryGetValue("farcolor", out tomlObject)) { - FarColor = Color.FromHex(tomlObject.Get()); + FarColor = Color.FromHex(((TomlValue) tomlObject).Value); } if (table.TryGetValue("closecolor", out tomlObject)) { - CloseColor = Color.FromHex(tomlObject.Get()); + CloseColor = Color.FromHex(((TomlValue) tomlObject).Value); } if (table.TryGetValue("pointsize", out tomlObject)) { - PointSize = tomlObject.Get(); + PointSize = ((TomlValue) tomlObject).Value; } // Noise mask stuff. if (table.TryGetValue("mask", out tomlObject)) { - Masked = tomlObject.Get(); + Masked = ((TomlValue) tomlObject).Value; } if (table.TryGetValue("maskseed", out tomlObject)) { - MaskSeed = (uint) tomlObject.Get(); + MaskSeed = (uint) ((TomlValue) tomlObject).Value; } if (table.TryGetValue("maskpersistence", out tomlObject)) { - MaskPersistence = float.Parse(tomlObject.Get(), CultureInfo.InvariantCulture); + MaskPersistence = float.Parse(((TomlValue) tomlObject).Value, CultureInfo.InvariantCulture); } if (table.TryGetValue("masklacunarity", out tomlObject)) { - MaskLacunarity = float.Parse(tomlObject.Get(), CultureInfo.InvariantCulture); + MaskLacunarity = float.Parse(((TomlValue) tomlObject).Value, CultureInfo.InvariantCulture); } if (table.TryGetValue("maskfrequency", out tomlObject)) { - MaskFrequency = float.Parse(tomlObject.Get(), CultureInfo.InvariantCulture); + MaskFrequency = float.Parse(((TomlValue) tomlObject).Value, CultureInfo.InvariantCulture); } if (table.TryGetValue("maskoctaves", out tomlObject)) { - MaskOctaves = (uint) tomlObject.Get(); + MaskOctaves = (uint) ((TomlValue) tomlObject).Value; } if (table.TryGetValue("maskthreshold", out tomlObject)) { - MaskThreshold = float.Parse(tomlObject.Get(), CultureInfo.InvariantCulture); + MaskThreshold = float.Parse(((TomlValue) tomlObject).Value, CultureInfo.InvariantCulture); } if (table.TryGetValue("masknoise_type", out tomlObject)) { - switch (tomlObject.Get()) + switch (((TomlValue) tomlObject).Value) { case "fbm": MaskNoiseType = NoiseGenerator.NoiseType.Fbm; @@ -312,7 +311,7 @@ namespace Content.Client.Parallax if (table.TryGetValue("maskpower", out tomlObject)) { - MaskPower = float.Parse(tomlObject.Get(), CultureInfo.InvariantCulture); + MaskPower = float.Parse(((TomlValue) tomlObject).Value, CultureInfo.InvariantCulture); } } From 14b793b3b517a43da5588ca30f96aceaa6d93cbf Mon Sep 17 00:00:00 2001 From: Pieter-Jan Briers Date: Tue, 24 Nov 2020 02:40:42 +0100 Subject: [PATCH 08/13] Fix tests. --- .../ContentIntegrationTest.cs | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/Content.IntegrationTests/ContentIntegrationTest.cs b/Content.IntegrationTests/ContentIntegrationTest.cs index cd73571d31..07177639c8 100644 --- a/Content.IntegrationTests/ContentIntegrationTest.cs +++ b/Content.IntegrationTests/ContentIntegrationTest.cs @@ -23,6 +23,7 @@ namespace Content.IntegrationTests protected sealed override ClientIntegrationInstance StartClient(ClientIntegrationOptions options = null) { options ??= new ClientIntegrationOptions(); + options.ExtraAssemblies = new[] {typeof(ContentIntegrationTest).Assembly}; // ReSharper disable once RedundantNameQualifier options.ClientContentAssembly = typeof(EntryPoint).Assembly; @@ -53,6 +54,7 @@ namespace Content.IntegrationTests protected override ServerIntegrationInstance StartServer(ServerIntegrationOptions options = null) { options ??= new ServerIntegrationOptions(); + options.ExtraAssemblies = new[] {typeof(ContentIntegrationTest).Assembly}; options.ServerContentAssembly = typeof(Server.EntryPoint).Assembly; options.SharedContentAssembly = typeof(Shared.EntryPoint).Assembly; options.BeforeStart += () => @@ -89,7 +91,9 @@ namespace Content.IntegrationTests return StartServer(options); } - protected async Task<(ClientIntegrationInstance client, ServerIntegrationInstance server)> StartConnectedServerClientPair(ClientIntegrationOptions clientOptions = null, ServerIntegrationOptions serverOptions = null) + protected async Task<(ClientIntegrationInstance client, ServerIntegrationInstance server)> + StartConnectedServerClientPair(ClientIntegrationOptions clientOptions = null, + ServerIntegrationOptions serverOptions = null) { var client = StartClient(clientOptions); var server = StartServer(serverOptions); @@ -100,7 +104,9 @@ namespace Content.IntegrationTests } - protected async Task<(ClientIntegrationInstance client, ServerIntegrationInstance server)> StartConnectedServerDummyTickerClientPair(ClientIntegrationOptions clientOptions = null, ServerIntegrationOptions serverOptions = null) + protected async Task<(ClientIntegrationInstance client, ServerIntegrationInstance server)> + StartConnectedServerDummyTickerClientPair(ClientIntegrationOptions clientOptions = null, + ServerIntegrationOptions serverOptions = null) { var client = StartClient(clientOptions); var server = StartServerDummyTicker(serverOptions); @@ -136,7 +142,8 @@ namespace Content.IntegrationTests return grid; } - protected async Task WaitUntil(IntegrationInstance instance, Func func, int maxTicks = 600, int tickStep = 1) + protected async Task WaitUntil(IntegrationInstance instance, Func func, int maxTicks = 600, + int tickStep = 1) { var ticksAwaited = 0; bool passed; @@ -160,7 +167,8 @@ namespace Content.IntegrationTests Assert.That(passed); } - private static async Task StartConnectedPairShared(ClientIntegrationInstance client, ServerIntegrationInstance server) + private static async Task StartConnectedPairShared(ClientIntegrationInstance client, + ServerIntegrationInstance server) { await Task.WhenAll(client.WaitIdleAsync(), server.WaitIdleAsync()); @@ -174,7 +182,8 @@ namespace Content.IntegrationTests /// /// Runs ticks on both server and client while keeping their main loop in sync. /// - protected static async Task RunTicksSync(ClientIntegrationInstance client, ServerIntegrationInstance server, int ticks) + protected static async Task RunTicksSync(ClientIntegrationInstance client, ServerIntegrationInstance server, + int ticks) { for (var i = 0; i < ticks; i++) { From 0cc74f70950cb833d434bb3560eab54595900c21 Mon Sep 17 00:00:00 2001 From: Pieter-Jan Briers Date: Tue, 24 Nov 2020 12:53:24 +0100 Subject: [PATCH 09/13] Use Robust color instead of System.Drawing. --- .../GameObjects/Components/Actor/CharacterInfoComponent.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Content.Client/GameObjects/Components/Actor/CharacterInfoComponent.cs b/Content.Client/GameObjects/Components/Actor/CharacterInfoComponent.cs index 28f7ffb381..2a49499211 100644 --- a/Content.Client/GameObjects/Components/Actor/CharacterInfoComponent.cs +++ b/Content.Client/GameObjects/Components/Actor/CharacterInfoComponent.cs @@ -1,5 +1,4 @@ #nullable enable -using System.Drawing; using Content.Client.GameObjects.Components.Mobs; using Content.Client.UserInterface; using Content.Client.UserInterface.Stylesheets; @@ -13,6 +12,7 @@ using Robust.Shared.GameObjects; using Robust.Shared.Interfaces.Network; using Robust.Shared.IoC; using Robust.Shared.Localization; +using Robust.Shared.Maths; using Robust.Shared.Players; namespace Content.Client.GameObjects.Components.Actor From af9e0a35eff63a090e29972f1e5a53ecc79ea7f0 Mon Sep 17 00:00:00 2001 From: Pieter-Jan Briers Date: Wed, 25 Nov 2020 16:23:51 +0100 Subject: [PATCH 10/13] Update content unit tests for engine modloader changes. --- .../ContentIntegrationTest.cs | 21 ++++++++++------- .../Networking/SimplePredictReconcileTest.cs | 2 ++ .../Tests/ResettingEntitySystemTests.cs | 2 ++ Content.Tests/ContentUnitTest.cs | 23 +++++++++++++++++++ .../Mobs/ServerAlertsComponentTests.cs | 1 - .../Shared/Alert/AlertManagerTests.cs | 4 +--- .../Shared/Alert/AlertOrderPrototypeTests.cs | 4 +--- .../Shared/Alert/AlertPrototypeTests.cs | 2 +- 8 files changed, 43 insertions(+), 16 deletions(-) diff --git a/Content.IntegrationTests/ContentIntegrationTest.cs b/Content.IntegrationTests/ContentIntegrationTest.cs index 07177639c8..e1914cadc2 100644 --- a/Content.IntegrationTests/ContentIntegrationTest.cs +++ b/Content.IntegrationTests/ContentIntegrationTest.cs @@ -13,7 +13,6 @@ using Robust.Shared.Interfaces.Network; using Robust.Shared.IoC; using Robust.Shared.Map; using Robust.UnitTesting; -using EntryPoint = Content.Client.EntryPoint; namespace Content.IntegrationTests { @@ -23,11 +22,14 @@ namespace Content.IntegrationTests protected sealed override ClientIntegrationInstance StartClient(ClientIntegrationOptions options = null) { options ??= new ClientIntegrationOptions(); - options.ExtraAssemblies = new[] {typeof(ContentIntegrationTest).Assembly}; - // ReSharper disable once RedundantNameQualifier - options.ClientContentAssembly = typeof(EntryPoint).Assembly; - options.SharedContentAssembly = typeof(Shared.EntryPoint).Assembly; + options.ContentAssemblies = new[] + { + typeof(Shared.EntryPoint).Assembly, + typeof(Client.EntryPoint).Assembly, + typeof(ContentIntegrationTest).Assembly + }; + options.BeforeStart += () => { IoCManager.Resolve().SetModuleBaseCallbacks(new ClientModuleTestingCallbacks @@ -54,9 +56,12 @@ namespace Content.IntegrationTests protected override ServerIntegrationInstance StartServer(ServerIntegrationOptions options = null) { options ??= new ServerIntegrationOptions(); - options.ExtraAssemblies = new[] {typeof(ContentIntegrationTest).Assembly}; - options.ServerContentAssembly = typeof(Server.EntryPoint).Assembly; - options.SharedContentAssembly = typeof(Shared.EntryPoint).Assembly; + options.ContentAssemblies = new[] + { + typeof(Shared.EntryPoint).Assembly, + typeof(Server.EntryPoint).Assembly, + typeof(ContentIntegrationTest).Assembly + }; options.BeforeStart += () => { IoCManager.Resolve().SetModuleBaseCallbacks(new ServerModuleTestingCallbacks diff --git a/Content.IntegrationTests/Tests/Networking/SimplePredictReconcileTest.cs b/Content.IntegrationTests/Tests/Networking/SimplePredictReconcileTest.cs index f37fe7215e..31f3d93633 100644 --- a/Content.IntegrationTests/Tests/Networking/SimplePredictReconcileTest.cs +++ b/Content.IntegrationTests/Tests/Networking/SimplePredictReconcileTest.cs @@ -14,6 +14,7 @@ using Robust.Shared.Interfaces.Map; using Robust.Shared.Interfaces.Timing; using Robust.Shared.IoC; using Robust.Shared.Map; +using Robust.Shared.Reflection; using Robust.Shared.Timing; namespace Content.IntegrationTests.Tests.Networking @@ -425,6 +426,7 @@ namespace Content.IntegrationTests.Tests.Networking } } + [Reflect(false)] private sealed class PredictionTestEntitySystem : EntitySystem { public bool Allow { get; set; } = true; diff --git a/Content.IntegrationTests/Tests/ResettingEntitySystemTests.cs b/Content.IntegrationTests/Tests/ResettingEntitySystemTests.cs index 01dd1a4127..99df0017fb 100644 --- a/Content.IntegrationTests/Tests/ResettingEntitySystemTests.cs +++ b/Content.IntegrationTests/Tests/ResettingEntitySystemTests.cs @@ -6,6 +6,7 @@ using NUnit.Framework; using Robust.Shared.GameObjects.Systems; using Robust.Shared.Interfaces.GameObjects; using Robust.Shared.IoC; +using Robust.Shared.Reflection; namespace Content.IntegrationTests.Tests { @@ -13,6 +14,7 @@ namespace Content.IntegrationTests.Tests [TestOf(typeof(IResettingEntitySystem))] public class ResettingEntitySystemTests : ContentIntegrationTest { + [Reflect(false)] private class TestResettingEntitySystem : EntitySystem, IResettingEntitySystem { public bool HasBeenReset { get; set; } diff --git a/Content.Tests/ContentUnitTest.cs b/Content.Tests/ContentUnitTest.cs index fe6980a312..cc06d7a6bb 100644 --- a/Content.Tests/ContentUnitTest.cs +++ b/Content.Tests/ContentUnitTest.cs @@ -1,3 +1,5 @@ +using System.Collections.Generic; +using System.Reflection; using Content.Client; using Content.Server; using Robust.UnitTesting; @@ -19,5 +21,26 @@ namespace Content.Tests ClientContentIoC.Register(); } } + + protected override Assembly[] GetContentAssemblies() + { + var l = new List + { + typeof(Content.Shared.EntryPoint).Assembly + }; + + if (Project == UnitTestProject.Server) + { + l.Add(typeof(Content.Server.EntryPoint).Assembly); + } + else if (Project == UnitTestProject.Client) + { + l.Add(typeof(Content.Client.EntryPoint).Assembly); + } + + l.Add(typeof(ContentUnitTest).Assembly); + + return l.ToArray(); + } } } diff --git a/Content.Tests/Server/GameObjects/Components/Mobs/ServerAlertsComponentTests.cs b/Content.Tests/Server/GameObjects/Components/Mobs/ServerAlertsComponentTests.cs index 48062b1e62..89ddb24c53 100644 --- a/Content.Tests/Server/GameObjects/Components/Mobs/ServerAlertsComponentTests.cs +++ b/Content.Tests/Server/GameObjects/Components/Mobs/ServerAlertsComponentTests.cs @@ -37,7 +37,6 @@ namespace Content.Tests.Server.GameObjects.Components.Mobs // in a unit test var prototypeManager = IoCManager.Resolve(); - prototypeManager.RegisterType(typeof(AlertPrototype)); var factory = IoCManager.Resolve(); factory.Register(); prototypeManager.LoadFromStream(new StringReader(PROTOTYPES)); diff --git a/Content.Tests/Shared/Alert/AlertManagerTests.cs b/Content.Tests/Shared/Alert/AlertManagerTests.cs index 7601b04eb9..9a82d89e08 100644 --- a/Content.Tests/Shared/Alert/AlertManagerTests.cs +++ b/Content.Tests/Shared/Alert/AlertManagerTests.cs @@ -12,7 +12,7 @@ using YamlDotNet.RepresentationModel; namespace Content.Tests.Shared.Alert { [TestFixture, TestOf(typeof(AlertManager))] - public class AlertManagerTests : RobustUnitTest + public class AlertManagerTests : ContentUnitTest { const string PROTOTYPES = @" - type: alert @@ -28,9 +28,7 @@ namespace Content.Tests.Shared.Alert public void TestAlertManager() { var prototypeManager = IoCManager.Resolve(); - prototypeManager.RegisterType(typeof(AlertPrototype)); prototypeManager.LoadFromStream(new StringReader(PROTOTYPES)); - IoCManager.RegisterInstance(new AlertManager()); var alertManager = IoCManager.Resolve(); alertManager.Initialize(); diff --git a/Content.Tests/Shared/Alert/AlertOrderPrototypeTests.cs b/Content.Tests/Shared/Alert/AlertOrderPrototypeTests.cs index f67914ef6b..b7aad0e5ce 100644 --- a/Content.Tests/Shared/Alert/AlertOrderPrototypeTests.cs +++ b/Content.Tests/Shared/Alert/AlertOrderPrototypeTests.cs @@ -10,7 +10,7 @@ using Robust.UnitTesting; namespace Content.Tests.Shared.Alert { [TestFixture, TestOf(typeof(AlertOrderPrototype))] - public class AlertOrderPrototypeTests : RobustUnitTest + public class AlertOrderPrototypeTests : ContentUnitTest { const string PROTOTYPES = @" - type: alertOrder @@ -64,8 +64,6 @@ namespace Content.Tests.Shared.Alert public void TestAlertOrderPrototype() { var prototypeManager = IoCManager.Resolve(); - prototypeManager.RegisterType(typeof(AlertPrototype)); - prototypeManager.RegisterType(typeof(AlertOrderPrototype)); prototypeManager.LoadFromStream(new StringReader(PROTOTYPES)); var alertOrder = prototypeManager.EnumeratePrototypes().FirstOrDefault(); diff --git a/Content.Tests/Shared/Alert/AlertPrototypeTests.cs b/Content.Tests/Shared/Alert/AlertPrototypeTests.cs index d4104a568f..6729028337 100644 --- a/Content.Tests/Shared/Alert/AlertPrototypeTests.cs +++ b/Content.Tests/Shared/Alert/AlertPrototypeTests.cs @@ -11,7 +11,7 @@ using YamlDotNet.RepresentationModel; namespace Content.Tests.Shared.Alert { [TestFixture, TestOf(typeof(AlertPrototype))] - public class AlertPrototypeTests : RobustUnitTest + public class AlertPrototypeTests : ContentUnitTest { private const string PROTOTYPE = @"- type: alert alertType: HumanHealth From 0dbb75051e05703471fae5baa825905bc48d735e Mon Sep 17 00:00:00 2001 From: Pieter-Jan Briers Date: Wed, 25 Nov 2020 18:00:18 +0100 Subject: [PATCH 11/13] Content changes for file dialog stuff. --- .../Instruments/InstrumentComponent.cs | 5 ++-- Content.Client/Instruments/InstrumentMenu.cs | 30 ++++++++++++------- 2 files changed, 22 insertions(+), 13 deletions(-) diff --git a/Content.Client/GameObjects/Components/Instruments/InstrumentComponent.cs b/Content.Client/GameObjects/Components/Instruments/InstrumentComponent.cs index 82c46e5a94..dddf6441ff 100644 --- a/Content.Client/GameObjects/Components/Instruments/InstrumentComponent.cs +++ b/Content.Client/GameObjects/Components/Instruments/InstrumentComponent.cs @@ -349,12 +349,11 @@ namespace Content.Client.GameObjects.Components.Instruments return true; } - /// - public bool OpenMidi(string filename) + public bool OpenMidi(ReadOnlySpan data) { SetupRenderer(); - if (_renderer == null || !_renderer.OpenMidi(filename)) + if (_renderer == null || !_renderer.OpenMidi(data)) { return false; } diff --git a/Content.Client/Instruments/InstrumentMenu.cs b/Content.Client/Instruments/InstrumentMenu.cs index 9c9769f7c6..9bcb8d1411 100644 --- a/Content.Client/Instruments/InstrumentMenu.cs +++ b/Content.Client/Instruments/InstrumentMenu.cs @@ -1,3 +1,6 @@ +using System; +using System.IO; +using System.Threading.Tasks; using Content.Client.GameObjects.Components.Instruments; using Content.Client.UserInterface.Stylesheets; using Content.Client.Utility; @@ -174,25 +177,31 @@ namespace Content.Client.Instruments private async void MidiFileButtonOnOnPressed(BaseButton.ButtonEventArgs obj) { var filters = new FileDialogFilters(new FileDialogFilters.Group("mid", "midi")); - var filename = await _fileDialogManager.OpenFile(filters); + var file = await _fileDialogManager.OpenFile(filters); // The following checks are only in place to prevent players from playing MIDI songs locally. // There are equivalents for these checks on the server. - if (string.IsNullOrEmpty(filename)) return; + if (file == null) return; - if (!_midiManager.IsMidiFile(filename)) + /*if (!_midiManager.IsMidiFile(filename)) { Logger.Warning($"Not a midi file! Chosen file: {filename}"); return; - } + }*/ if (!PlayCheck()) return; MidiStopButtonOnPressed(null); - await Timer.Delay(100); - if (!_owner.Instrument.OpenMidi(filename)) return; + var memStream = new MemoryStream((int) file.Length); + // 100ms delay is due to a race condition or something idk. + // While we're waiting, load it into memory. + await Task.WhenAll(Timer.Delay(100), file.CopyToAsync(memStream)); + + if (!_owner.Instrument.OpenMidi(memStream.GetBuffer().AsSpan(0, (int) memStream.Length))) + return; + MidiPlaybackSetButtonsDisabled(false); if (_midiInputButton.Pressed) _midiInputButton.Pressed = false; @@ -222,14 +231,15 @@ namespace Content.Client.Instruments var localPlayer = IoCManager.Resolve().LocalPlayer; // If we don't have a player or controlled entity, we return. - if(localPlayer?.ControlledEntity == null) return false; + if (localPlayer?.ControlledEntity == null) return false; // If the instrument is handheld and we're not holding it, we return. - if((instrument.Handheld && (conMan == null - || conMan.Owner != localPlayer.ControlledEntity))) return false; + if ((instrument.Handheld && (conMan == null + || conMan.Owner != localPlayer.ControlledEntity))) return false; // We check that we're in range unobstructed just in case. - return localPlayer.InRangeUnobstructed(instrumentEnt, predicate:(e) => e == instrumentEnt || e == localPlayer.ControlledEntity); + return localPlayer.InRangeUnobstructed(instrumentEnt, + predicate: (e) => e == instrumentEnt || e == localPlayer.ControlledEntity); } private void MidiStopButtonOnPressed(BaseButton.ButtonEventArgs obj) From 92f5f4c8f071ec3bd7ee2ecbde9176e92f28d50e Mon Sep 17 00:00:00 2001 From: Pieter-Jan Briers Date: Thu, 26 Nov 2020 23:13:18 +0100 Subject: [PATCH 12/13] Content side changes for HttpListener. --- Content.Server/Content.Server.csproj | 1 - Content.Server/MoMMILink.cs | 5 ++--- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/Content.Server/Content.Server.csproj b/Content.Server/Content.Server.csproj index 8923cb0774..ea79f33285 100644 --- a/Content.Server/Content.Server.csproj +++ b/Content.Server/Content.Server.csproj @@ -14,7 +14,6 @@ - diff --git a/Content.Server/MoMMILink.cs b/Content.Server/MoMMILink.cs index 692dcd59c5..bc7b4aaf01 100644 --- a/Content.Server/MoMMILink.cs +++ b/Content.Server/MoMMILink.cs @@ -6,7 +6,6 @@ using System.Threading.Tasks; using Content.Server.Interfaces; using Content.Server.Interfaces.Chat; using Content.Shared; -using Microsoft.AspNetCore.Http; using Newtonsoft.Json; using Robust.Server.Interfaces.ServerStatus; using Robust.Server.ServerStatus; @@ -74,9 +73,9 @@ namespace Content.Server } } - private bool _handleChatPost(HttpMethod method, HttpRequest request, HttpResponse response) + private bool _handleChatPost(HttpMethod method, HttpListenerRequest request, HttpListenerResponse response) { - if (method != HttpMethod.Post || request.Path != "/ooc") + if (method != HttpMethod.Post || request.Url!.AbsolutePath != "/ooc") { return false; } From 42214036c7048e3390259bb1b0cfe3d6dba5b4f4 Mon Sep 17 00:00:00 2001 From: Pieter-Jan Briers Date: Fri, 27 Nov 2020 00:53:43 +0100 Subject: [PATCH 13/13] Update submodule --- RobustToolbox | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/RobustToolbox b/RobustToolbox index 26d1a04bbf..2b39c05472 160000 --- a/RobustToolbox +++ b/RobustToolbox @@ -1 +1 @@ -Subproject commit 26d1a04bbfb424696adda02df2c5ca67145ba92f +Subproject commit 2b39c05472156f45e92446a2c4fe5ea3a35c7887