Content PR for YAML hot reloading (#3319)

* Content PR for YAML hot reloading

* Add CanAdminReloadPrototypes (host permission)

* IndexedPrototype fixes
This commit is contained in:
DrSmugleaf
2021-02-20 00:05:24 +01:00
committed by GitHub
parent 0ae4a6792f
commit 3e702723fd
42 changed files with 95 additions and 54 deletions

View File

@@ -490,6 +490,11 @@ namespace Content.Server.Administration
return GetAdminData(session)?.CanAdminMenu() ?? false;
}
public bool CanAdminReloadPrototypes(IPlayerSession session)
{
return GetAdminData(session)?.CanAdminReloadPrototypes() ?? false;
}
private void SendPermsChangedEvent(IPlayerSession session)
{
var flags = GetAdminData(session)?.Flags;

View File

@@ -23,7 +23,7 @@ namespace Content.Server.Atmos.Reactions
}
[Prototype("gasReaction")]
public class GasReactionPrototype : IPrototype, IIndexedPrototype
public class GasReactionPrototype : IPrototype
{
public string ID { get; private set; }

View File

@@ -66,7 +66,7 @@ namespace Content.Server.Botany
}
[Prototype("seed")]
public class Seed : IPrototype, IIndexedPrototype, IExposeData
public class Seed : IPrototype, IExposeData
{
private const string SeedPrototype = "SeedBase";

View File

@@ -6,7 +6,7 @@ using YamlDotNet.RepresentationModel;
namespace Content.Server.GameObjects.Components.BarSign
{
[Prototype("barSign")]
public class BarSignPrototype : IPrototype, IIndexedPrototype
public class BarSignPrototype : IPrototype
{
public string ID { get; private set; }
public string Icon { get; private set; }

View File

@@ -12,7 +12,7 @@ using YamlDotNet.RepresentationModel;
namespace Content.Server.Holiday
{
[Prototype("holiday")]
public class HolidayPrototype : IPrototype, IIndexedPrototype
public class HolidayPrototype : IPrototype
{
[ViewVariables] public string Name { get; private set; } = string.Empty;
[ViewVariables] public string ID { get; private set; } = string.Empty;

View File

@@ -10,7 +10,7 @@ using YamlDotNet.RepresentationModel;
namespace Content.Server.Objectives
{
[Prototype("objective")]
public class ObjectivePrototype : IPrototype, IIndexedPrototype
public class ObjectivePrototype : IPrototype
{
[ViewVariables]
public string ID { get; private set; }

View File

@@ -9,7 +9,7 @@ namespace Content.Shared.Access
/// Defines a single access level that can be stored on ID cards and checked for.
/// </summary>
[Prototype("accessLevel")]
public class AccessLevelPrototype : IPrototype, IIndexedPrototype
public class AccessLevelPrototype : IPrototype
{
public void LoadFrom(YamlMappingNode mapping)
{

View File

@@ -15,6 +15,8 @@ namespace Content.Shared.Actions
/// </summary>
public abstract class BaseActionPrototype : IPrototype
{
public string ID { get; private set; }
/// <summary>
/// Icon representing this action in the UI.
/// </summary>
@@ -89,7 +91,11 @@ namespace Content.Shared.Actions
var serializer = YamlObjectSerializer.NewReader(mapping);
serializer.DataReadFunction("name", string.Empty,
s => Name = FormattedMessage.FromMarkup(s));
s =>
{
ID = s;
Name = FormattedMessage.FromMarkup(s);
});
serializer.DataReadFunction("description", string.Empty,
s => Description = FormattedMessage.FromMarkup(s));

View File

@@ -64,5 +64,10 @@ namespace Content.Shared.Administration
{
return HasFlag(AdminFlags.Admin);
}
public bool CanAdminReloadPrototypes()
{
return HasFlag(AdminFlags.Host);
}
}
}

View File

@@ -12,23 +12,29 @@ namespace Content.Shared.Alert
[Prototype("alertOrder")]
public class AlertOrderPrototype : IPrototype, IComparer<AlertPrototype>
{
public string ID { get; private set; }
private readonly Dictionary<AlertType, int> _typeToIdx = new();
private readonly Dictionary<AlertCategory, int> _categoryToIdx = new();
public void LoadFrom(YamlMappingNode mapping)
{
var serializer = YamlObjectSerializer.NewReader(mapping);
serializer.DataField(this, x => x.ID, "id", string.Empty);
if (!mapping.TryGetNode("order", out YamlSequenceNode orderMapping)) return;
int i = 0;
var i = 0;
foreach (var entryYaml in orderMapping)
{
var orderEntry = (YamlMappingNode) entryYaml;
var serializer = YamlObjectSerializer.NewReader(orderEntry);
if (serializer.TryReadDataField("category", out AlertCategory alertCategory))
var orderSerializer = YamlObjectSerializer.NewReader(orderEntry);
if (orderSerializer.TryReadDataField("category", out AlertCategory alertCategory))
{
_categoryToIdx[alertCategory] = i++;
}
else if (serializer.TryReadDataField("alertType", out AlertType alertType))
else if (orderSerializer.TryReadDataField("alertType", out AlertType alertType))
{
_typeToIdx[alertType] = i++;
}

View File

@@ -17,6 +17,8 @@ namespace Content.Shared.Alert
[Prototype("alert")]
public class AlertPrototype : IPrototype
{
public string ID { get; private set; }
/// <summary>
/// Type of alert, no 2 alert prototypes should have the same one.
/// </summary>
@@ -94,7 +96,11 @@ namespace Content.Shared.Alert
serializer.DataField(ref _minSeverity, "minSeverity", (short) 1);
serializer.DataReadFunction("name", string.Empty,
s => Name = FormattedMessage.FromMarkup(s));
s =>
{
ID = s;
Name = FormattedMessage.FromMarkup(s);
});
serializer.DataReadFunction("description", string.Empty,
s => Description = FormattedMessage.FromMarkup(s));

View File

@@ -5,7 +5,7 @@ using YamlDotNet.RepresentationModel;
namespace Content.Shared.Atmos
{
[Prototype("gas")]
public class GasPrototype : IPrototype, IIndexedPrototype
public class GasPrototype : IPrototype
{
public string Name { get; private set; }

View File

@@ -6,7 +6,7 @@ using YamlDotNet.RepresentationModel;
namespace Content.Shared.Audio
{
[Prototype("soundCollection")]
public sealed class SoundCollectionPrototype : IPrototype, IIndexedPrototype
public sealed class SoundCollectionPrototype : IPrototype
{
public string ID { get; private set; }
public IReadOnlyList<string> PickFiles { get; private set; }

View File

@@ -14,7 +14,7 @@ namespace Content.Shared.Chemistry
/// Prototype for chemical reaction definitions
/// </summary>
[Prototype("reaction")]
public class ReactionPrototype : IPrototype, IIndexedPrototype
public class ReactionPrototype : IPrototype
{
private string _id = default!;
private string _name = default!;

View File

@@ -15,7 +15,7 @@ using YamlDotNet.RepresentationModel;
namespace Content.Shared.Chemistry
{
[Prototype("reagent")]
public class ReagentPrototype : IPrototype, IIndexedPrototype
public class ReagentPrototype : IPrototype
{
[Dependency] private readonly IModuleManager _moduleManager = default!;

View File

@@ -10,7 +10,7 @@ using YamlDotNet.RepresentationModel;
namespace Content.Shared.Construction
{
[Prototype("constructionGraph")]
public class ConstructionGraphPrototype : IPrototype, IIndexedPrototype
public class ConstructionGraphPrototype : IPrototype
{
private readonly Dictionary<string, ConstructionGraphNode> _nodes = new();
private readonly Dictionary<ValueTuple<string, string>, ConstructionGraphNode[]> _paths = new();

View File

@@ -7,7 +7,7 @@ using YamlDotNet.RepresentationModel;
namespace Content.Shared.Construction
{
[Prototype("construction")]
public class ConstructionPrototype : IPrototype, IIndexedPrototype
public class ConstructionPrototype : IPrototype
{
private List<IConstructionCondition> _conditions;

View File

@@ -12,7 +12,7 @@ namespace Content.Shared.Damage.DamageContainer
/// </summary>
[Prototype("damageContainer")]
[Serializable, NetSerializable]
public class DamageContainerPrototype : IPrototype, IIndexedPrototype
public class DamageContainerPrototype : IPrototype
{
private bool _supportAll;
private HashSet<DamageClass> _supportedClasses;

View File

@@ -12,7 +12,7 @@ namespace Content.Shared.Damage.ResistanceSet
/// </summary>
[Prototype("resistanceSet")]
[Serializable, NetSerializable]
public class ResistanceSetPrototype : IPrototype, IIndexedPrototype
public class ResistanceSetPrototype : IPrototype
{
private Dictionary<DamageType, float> _coefficients;
private Dictionary<DamageType, int> _flatReductions;

View File

@@ -13,7 +13,7 @@ namespace Content.Shared.GameObjects.Components.Body.Preset
/// </summary>
[Prototype("bodyPreset")]
[Serializable, NetSerializable]
public class BodyPresetPrototype : IPrototype, IIndexedPrototype
public class BodyPresetPrototype : IPrototype
{
private string _id;
private string _name;

View File

@@ -14,7 +14,7 @@ namespace Content.Shared.GameObjects.Components.Body.Template
/// </summary>
[Prototype("bodyTemplate")]
[Serializable, NetSerializable]
public class BodyTemplatePrototype : IPrototype, IIndexedPrototype
public class BodyTemplatePrototype : IPrototype
{
private string _id;
private string _name;

View File

@@ -13,7 +13,7 @@ namespace Content.Shared.GameObjects.Components.Chemistry.ReagentDispenser
/// machines define their inventory.
/// </summary>
[Serializable, NetSerializable, Prototype("reagentDispenserInventory")]
public class ReagentDispenserInventoryPrototype : IPrototype, IIndexedPrototype
public class ReagentDispenserInventoryPrototype : IPrototype
{
private string _id;
private List<string> _inventory;

View File

@@ -73,6 +73,8 @@ namespace Content.Shared.GameObjects.Components
[Serializable, NetSerializable, Prototype("crayonDecal")]
public class CrayonDecalPrototype : IPrototype
{
public string ID { get; private set; }
private string _spritePath;
public string SpritePath => _spritePath;
@@ -83,6 +85,7 @@ namespace Content.Shared.GameObjects.Components
{
var serializer = YamlObjectSerializer.NewReader(mapping);
serializer.DataField(this, x => x.ID, "id", string.Empty);
serializer.DataField(ref _spritePath, "spritePath", "");
serializer.DataField(ref _decals, "decals", new List<string>());
}

View File

@@ -8,7 +8,7 @@ using YamlDotNet.RepresentationModel;
namespace Content.Shared.GameObjects.Components.Weapons.Melee
{
[Prototype("MeleeWeaponAnimation")]
public sealed class MeleeWeaponAnimationPrototype : IPrototype, IIndexedPrototype
public sealed class MeleeWeaponAnimationPrototype : IPrototype
{
private string _prototype;
private string _state;

View File

@@ -10,9 +10,9 @@ namespace Content.Shared.Maps
{
[UsedImplicitly]
[Prototype("tile")]
public sealed class ContentTileDefinition : IPrototype, IIndexedPrototype, ITileDefinition
public sealed class ContentTileDefinition : IPrototype, ITileDefinition
{
string IIndexedPrototype.ID => Name;
string IPrototype.ID => Name;
public string Name { get; private set; }
public ushort TileId { get; private set; }

View File

@@ -112,7 +112,7 @@ namespace Content.Shared.Materials
}
[Prototype("material")]
public class MaterialPrototype : IPrototype, IIndexedPrototype
public class MaterialPrototype : IPrototype
{
public string ID { get; private set; }

View File

@@ -9,7 +9,7 @@ using YamlDotNet.RepresentationModel;
namespace Content.Shared.Prototypes.Cargo
{
[NetSerializable, Serializable, Prototype("cargoProduct")]
public class CargoProductPrototype : IPrototype, IIndexedPrototype
public class CargoProductPrototype : IPrototype
{
private string _id;
private string _name;

View File

@@ -6,7 +6,7 @@ using YamlDotNet.RepresentationModel;
namespace Content.Shared.Prototypes
{
[Prototype("dataset")]
public class DatasetPrototype : IPrototype, IIndexedPrototype
public class DatasetPrototype : IPrototype
{
private string _id;
public string ID => _id;

View File

@@ -9,12 +9,9 @@ namespace Content.Shared.Prototypes.Kitchen
/// <summary>
/// A recipe for space microwaves.
/// </summary>
[Prototype("microwaveMealRecipe")]
public class FoodRecipePrototype : IPrototype, IIndexedPrototype
public class FoodRecipePrototype : IPrototype
{
private string _id;
private string _name;
private string _result;
@@ -30,7 +27,6 @@ namespace Content.Shared.Prototypes.Kitchen
public IReadOnlyDictionary<string, int> IngredientsReagents => _ingsReagents;
public IReadOnlyDictionary<string, int> IngredientsSolids => _ingsSolids;
public void LoadFrom(YamlMappingNode mapping)
{
var serializer = YamlObjectSerializer.NewReader(mapping);
@@ -42,6 +38,5 @@ namespace Content.Shared.Prototypes.Kitchen
serializer.DataField(ref _ingsSolids, "solids", new Dictionary<string, int>());
serializer.DataField(ref _cookTime, "time", 5);
}
}
}

View File

@@ -6,9 +6,8 @@ using YamlDotNet.RepresentationModel;
namespace Content.Shared.Prototypes.PDA
{
[Prototype("uplinkListing")]
public class UplinkStoreListingPrototype : IPrototype, IIndexedPrototype
public class UplinkStoreListingPrototype : IPrototype
{
private string _id;
private string _itemId;
private int _price;
@@ -23,6 +22,7 @@ namespace Content.Shared.Prototypes.PDA
public UplinkCategory Category => _category;
public string Description => _desc;
public string ListingName => _name;
public void LoadFrom(YamlMappingNode mapping)
{
var serializer = YamlObjectSerializer.NewReader(mapping);
@@ -32,7 +32,6 @@ namespace Content.Shared.Prototypes.PDA
serializer.DataField(ref _category, "category", UplinkCategory.Utility);
serializer.DataField(ref _desc, "description", string.Empty);
serializer.DataField(ref _name, "listingName", string.Empty);
}
}
}

View File

@@ -12,7 +12,7 @@ namespace Content.Shared.Prototypes.Tag
/// gets saved in TagComponent.
/// </summary>
[Prototype("Tag")]
public class TagPrototype : IPrototype, IIndexedPrototype
public class TagPrototype : IPrototype
{
public string ID { get; [UsedImplicitly] private set; } = default!;

View File

@@ -10,7 +10,7 @@ using YamlDotNet.RepresentationModel;
namespace Content.Shared.Research
{
[NetSerializable, Serializable, Prototype("latheRecipe")]
public class LatheRecipePrototype : IPrototype, IIndexedPrototype
public class LatheRecipePrototype : IPrototype
{
private string _name;
private string _id;

View File

@@ -9,7 +9,7 @@ using YamlDotNet.RepresentationModel;
namespace Content.Shared.Research
{
[NetSerializable, Serializable, Prototype("technology")]
public class TechnologyPrototype : IPrototype, IIndexedPrototype
public class TechnologyPrototype : IPrototype
{
private string _name;
private string _id;

View File

@@ -9,7 +9,7 @@ namespace Content.Shared.Roles
/// Describes information for a single antag.
/// </summary>
[Prototype("antag")]
public class AntagPrototype : IPrototype, IIndexedPrototype
public class AntagPrototype : IPrototype
{
public string ID { get; private set; }

View File

@@ -11,7 +11,7 @@ namespace Content.Shared.Roles
/// Describes information for a single job on the station.
/// </summary>
[Prototype("job")]
public class JobPrototype : IPrototype, IIndexedPrototype
public class JobPrototype : IPrototype
{
public string ID { get; private set; }

View File

@@ -12,7 +12,7 @@ using static Content.Shared.GameObjects.Components.Inventory.EquipmentSlotDefine
namespace Content.Shared.Roles
{
[Prototype("startingGear")]
public class StartingGearPrototype : IPrototype, IIndexedPrototype
public class StartingGearPrototype : IPrototype
{
private string _id = default!;
private Dictionary<Slots, string> _equipment = default!;

View File

@@ -7,7 +7,7 @@ using YamlDotNet.RepresentationModel;
namespace Content.Shared.VendingMachines
{
[Serializable, NetSerializable, Prototype("vendingMachineInventory")]
public class VendingMachineInventoryPrototype : IPrototype, IIndexedPrototype
public class VendingMachineInventoryPrototype : IPrototype
{
private string _id;
private string _name;

View File

@@ -15,11 +15,13 @@ namespace Content.Tests.Server.GameObjects.Components.Mobs
{
const string PROTOTYPES = @"
- type: alert
name: AlertLowPressure
alertType: LowPressure
category: Pressure
icon: /Textures/Interface/Alerts/Pressure/lowpressure.png
- type: alert
name: AlertHighPressure
alertType: HighPressure
category: Pressure
icon: /Textures/Interface/Alerts/Pressure/highpressure.png

View File

@@ -12,10 +12,12 @@ namespace Content.Tests.Shared.Alert
{
const string PROTOTYPES = @"
- type: alert
name: AlertLowPressure
alertType: LowPressure
icon: /Textures/Interface/Alerts/Pressure/lowpressure.png
- type: alert
name: AlertHighPressure
alertType: HighPressure
icon: /Textures/Interface/Alerts/Pressure/highpressure.png
";

View File

@@ -23,39 +23,49 @@ namespace Content.Tests.Shared.Alert
- category: Temperature
- type: alert
name: AlertLowPressure
category: Pressure
alertType: LowPressure
- type: alert
name: AlertOverfed
category: Hunger
alertType: Overfed
- type: alert
name: AlertHighPressure
category: Pressure
alertType: HighPressure
- type: alert
name: AlertPeckish
category: Hunger
alertType: Peckish
- type: alert
name: AlertStun
alertType: Stun
- type: alert
name: AlertHandcuffed
alertType: Handcuffed
- type: alert
name: AlertHot
category: Temperature
alertType: Hot
- type: alert
name: AlertCold
category: Temperature
alertType: Cold
- type: alert
name: AlertWeightless
alertType: Weightless
- type: alert
name: AlertPilotingShuttle
alertType: PilotingShuttle
";

View File

@@ -2,6 +2,7 @@
# Defines ordering in alert tab, higher up = higher in tab.
# List below can contain alert type or category, if both are present the id will take precedence.
# If item is not in list it will go at the bottom (ties broken by alert type enum value)
id: BaseAlertOrder
order:
- category: Health
- alertType: Fire
@@ -197,35 +198,35 @@
- type: alert
alertType: Debug1
icon: /Textures/Interface/Alerts/Human/human1.png
name: Debug
name: Debug1
description: Debug
- type: alert
alertType: Debug2
icon: /Textures/Interface/Alerts/Human/human2.png
name: Debug
name: Debug2
description: Debug
- type: alert
alertType: Debug3
icon: /Textures/Interface/Alerts/Human/human3.png
name: Debug
name: Debug3
description: Debug
- type: alert
alertType: Debug4
icon: /Textures/Interface/Alerts/Human/human4.png
name: Debug
name: Debug4
description: Debug
- type: alert
alertType: Debug5
icon: /Textures/Interface/Alerts/Human/human5.png
name: Debug
name: Debug5
description: Debug
- type: alert
alertType: Debug6
icon: /Textures/Interface/Alerts/Human/human6.png
name: Debug
name: Debug6
description: Debug

View File

@@ -1,4 +1,5 @@
- type: crayonDecal
id: BaseDecals
spritePath: "Constructible/Misc/crayondecals.rsi"
decals:
- 0