Improve yaml validation errors for ignored prototypes (#5886)

* Improve yaml validation errors for ignored prototypes

* release notes

* Comments
This commit is contained in:
Leon Friedrich
2025-05-10 21:37:42 +10:00
committed by GitHub
parent b3cf427013
commit d24854d94f
5 changed files with 35 additions and 8 deletions

View File

@@ -39,7 +39,7 @@ END TEMPLATE-->
### New features
*None yet*
* Added `IPrototypeManager.IsIgnored()` for checking whether a given prototype kind has been marked as ignored via `RegisterIgnore()`.
### Bugfixes
@@ -47,7 +47,7 @@ END TEMPLATE-->
### Other
*None yet*
* The yaml prototype id serialiser now provides better feedback when trying to validate an id for a prototype kind that has been ignored via `IPrototypeManager.RegisterIgnore()`
### Internal

View File

@@ -306,6 +306,11 @@ public interface IPrototypeManager
/// </summary>
void RegisterIgnore(string name);
/// <summary>
/// Checks whether the given gind name has been marked as ignored via <see cref="RegisterIgnore"/>
/// </summary>
bool IsIgnored(string name);
/// <summary>
/// Loads several prototype kinds into the manager. Note that this will re-build a frozen dictionary and should be avoided if possible.
/// </summary>

View File

@@ -920,6 +920,8 @@ namespace Robust.Shared.Prototypes
return TryGetKindFrom(typeof(T), out kind);
}
public bool IsIgnored(string name) => _ignoredPrototypeTypes.Contains(name);
/// <inheritdoc />
public void RegisterIgnore(string name)
{
@@ -973,6 +975,17 @@ namespace Robust.Shared.Prototypes
var name = attribute.Type ?? CalculatePrototypeName(kind);
if (_ignoredPrototypeTypes.Contains(name))
{
// For whatever reason, we are registering a prototype despite it having been marked as ignored.
// This often happens when someone is moving a server or client prototype to shared. Maybe this should
// log an error, but I want to avoid breaking changes and maaaaybe there some weird instance where you
// want the client to know that a prototype kind exists, without having the client load information
// about the individual prototypes? So for now lets just log a warning instead of introducing breaking
// changes.
Sawmill.Warning($"Registering an ignored prototype {kind}");
}
if (_kindNames.TryGetValue(name, out var existing))
{
throw new InvalidImplementationException(kind,

View File

@@ -3,6 +3,7 @@ using Robust.Shared.Prototypes;
using Robust.Shared.Serialization.Manager;
using Robust.Shared.Serialization.Markdown.Validation;
using Robust.Shared.Serialization.Markdown.Value;
using Robust.Shared.Serialization.TypeSerializers.Implementations.Generic;
using Robust.Shared.Serialization.TypeSerializers.Interfaces;
namespace Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype
@@ -30,10 +31,7 @@ namespace Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Pro
public virtual ValidationNode Validate(ISerializationManager serializationManager, ValueDataNode node,
IDependencyCollection dependencies, ISerializationContext? context = null)
{
var protoMan = dependencies.Resolve<IPrototypeManager>();
return protoMan.TryGetKindFrom<TPrototype>(out _) && protoMan.HasIndex<TPrototype>(node.Value)
? new ValidatedValueNode(node)
: new ErrorNode(node, $"PrototypeID {node.Value} for type {typeof(TPrototype)} at {node.Start} not found");
return ProtoIdSerializer<TPrototype>.Validate(dependencies, node);
}
}
}

View File

@@ -19,8 +19,19 @@ public sealed class ProtoIdSerializer<T> : ITypeSerializer<ProtoId<T>, ValueData
{
public ValidationNode Validate(ISerializationManager serialization, ValueDataNode node, IDependencyCollection dependencies, ISerializationContext? context = null)
{
var prototypes = dependencies.Resolve<IPrototypeManager>();
if (prototypes.TryGetKindFrom<T>(out _) && prototypes.HasMapping<T>(node.Value))
return Validate(dependencies, node);
}
public static ValidationNode Validate(IDependencyCollection deps, ValueDataNode node)
{
var proto = deps.Resolve<IPrototypeManager>();
if (!proto.TryGetKindFrom<T>(out var kind))
return new ErrorNode(node, $"Unknown prototype kind: {typeof(T)}");
if (proto.IsIgnored(kind))
return new ErrorNode(node,$"Attempting to validate an ignored prototype: {typeof(T)}.\nDid you forget to remove the IPrototypeManager.RegisterIgnore(\"{kind}\") call when moving a prototype to Shared?");
if (proto.HasMapping<T>(node.Value))
return new ValidatedValueNode(node);
return new ErrorNode(node, $"No {typeof(T)} found with id {node.Value}");