diff --git a/Content.Shared/Entry/EntryPoint.cs b/Content.Shared/Entry/EntryPoint.cs index bd31b1fd7ca..df267b08cb1 100644 --- a/Content.Shared/Entry/EntryPoint.cs +++ b/Content.Shared/Entry/EntryPoint.cs @@ -1,16 +1,18 @@ -using Content.Shared.CCVar; -using Content.Shared.Chemistry.Reaction; -using Content.Shared.Chemistry.Reagent; +using System.Diagnostics.CodeAnalysis; +using System.IO; +using System.Linq; using Content.Shared.Humanoid.Markings; using Content.Shared.IoC; -using Content.Shared.Localizations; using Content.Shared.Maps; using Robust.Shared; using Robust.Shared.Configuration; using Robust.Shared.ContentPack; using Robust.Shared.Map; -using Robust.Shared.Network; using Robust.Shared.Prototypes; +using Robust.Shared.Serialization.Markdown; +using Robust.Shared.Serialization.Markdown.Sequence; +using Robust.Shared.Serialization.Markdown.Value; +using Robust.Shared.Utility; namespace Content.Shared.Entry { @@ -18,6 +20,9 @@ public sealed class EntryPoint : GameShared { [Dependency] private readonly IPrototypeManager _prototypeManager = default!; [Dependency] private readonly ITileDefinitionManager _tileDefinitionManager = default!; + [Dependency] private readonly IResourceManager _resMan = default!; + + private readonly ResPath _ignoreFileDirectory = new("/IgnoredPrototypes/"); public override void PreInit() { @@ -32,6 +37,7 @@ public override void Shutdown() public override void Init() { + IgnorePrototypes(); } public override void PostInit() @@ -96,5 +102,48 @@ private void PrototypeReload(PrototypesReloadedEventArgs obj) def.AssignTileId(_tileDefinitionManager[def.ID].TileId); } } + + private void IgnorePrototypes() + { + if (!TryReadFile(out var sequences)) + return; + + foreach (var sequence in sequences) + { + foreach (var node in sequence.Sequence) + { + var path = new ResPath(((ValueDataNode) node).Value); + + if (string.IsNullOrEmpty(path.Extension)) + { + _prototypeManager.AbstractDirectory(path); + } + else + { + _prototypeManager.AbstractFile(path); + } + } + } + } + + private bool TryReadFile([NotNullWhen(true)] out List? sequence) + { + sequence = new(); + + foreach (var path in _resMan.ContentFindFiles(_ignoreFileDirectory)) + { + if (!_resMan.TryContentFileRead(path, out var stream)) + continue; + + using var reader = new StreamReader(stream, EncodingHelpers.UTF8); + var documents = DataNodeParser.ParseYamlStream(reader).FirstOrDefault(); + + if (documents == null) + continue; + + sequence.Add((SequenceDataNode) documents.Root); + } + return true; + } } } diff --git a/Resources/IgnoredPrototypes/ignoredPrototypes.yml b/Resources/IgnoredPrototypes/ignoredPrototypes.yml new file mode 100644 index 00000000000..695cee007f6 --- /dev/null +++ b/Resources/IgnoredPrototypes/ignoredPrototypes.yml @@ -0,0 +1,8 @@ +# This is a basic list that specifies files for which the prototypes inside of them will be made abstract. +# This supports all prototype kinds and is intended to allow servers to remove prototypes in a relatively clean way. +# This method does not break inheritance, but you will still have to remove usages. + +# e.g., you can specify both directories and specific files by adding lines like: +# +# - /Prototypes/Guidebook +# - /Prototypes/Catalog/uplink_catalog.yml