Skip to content

Commit

Permalink
Add plando schema file generation
Browse files Browse the repository at this point in the history
  • Loading branch information
MattEqualsCoder committed Dec 15, 2024
1 parent 8711b0d commit 33074e2
Show file tree
Hide file tree
Showing 6 changed files with 78 additions and 22 deletions.
51 changes: 35 additions & 16 deletions src/TrackerCouncil.Smz3.Data.SchemaGenerator/Program.cs
Original file line number Diff line number Diff line change
@@ -1,15 +1,20 @@
using System.ComponentModel;
using System.Reflection;
using System.Text;
using System.Text.RegularExpressions;
using Microsoft.Extensions.DependencyInjection;
using Newtonsoft.Json.Schema;
using Newtonsoft.Json.Schema.Generation;
using NJsonSchema.Generation;
using NJsonSchema.NewtonsoftJson.Generation;
using Serilog;
using Serilog.Events;
using TrackerCouncil.Smz3.Data.Configuration;
using TrackerCouncil.Smz3.Data.Configuration.ConfigFiles;
using TrackerCouncil.Smz3.Data.Configuration.ConfigTypes;
using TrackerCouncil.Smz3.Data.Options;
using YamlDotNet.Serialization;
using JsonSchemaGenerator = NJsonSchema.Generation.JsonSchemaGenerator;

namespace TrackerCouncil.Smz3.Data.SchemaGenerator;

Expand Down Expand Up @@ -60,6 +65,34 @@ public static void Main(string[] args)

CreateSchemas(outputPath);
CreateTemplates(outputPath);
CreatePlandoSchema(outputPath);
}

private static void CreatePlandoSchema(string outputPath)
{
var plandoConfig = new PlandoConfig();
var serializer = new SerializerBuilder()
.DisableAliases()
.Build();
var newHashCode = serializer.Serialize(plandoConfig).GetHashCode();
if (newHashCode == PlandoConfig.SHashCode)
{
Log.Information("PlandoConfig default object matches SHashCode value of {Code}", newHashCode);
return;
}

Log.Information(
"New PlandoConfig HashCode {NewHashCode} does not match prior PlandoConfig.SHashCode value of {OldHashCode}",
newHashCode, PlandoConfig.SHashCode);

var schemaPath = Path.Combine(outputPath, "Schemas");
var generator = new JSchemaGenerator();
generator.GenerationProviders.Add(new StringEnumGenerationProvider());
var schema = generator.Generate(typeof(PlandoConfig), false);
var path = Path.Combine(schemaPath, "plando.json");
File.WriteAllText(path, schema.ToString());

Log.Information("Wrote {Type} schema to {Path}. Update PlandoConfig SHashCode value to {Hash}", typeof(PlandoConfig).FullName, path, newHashCode);
}

private static void CreateSchemas(string outputPath)
Expand All @@ -81,6 +114,7 @@ private static void CreateSchemas(string outputPath)
{
var path = Path.Combine(schemaPath, type.Item2);
var schema = generator.Generate(type.Item1);

var text = schrodingersStringReplacement.Replace(schema.ToJson(), "").Replace("\\n", " ");

for (var i = 0; i < 5; i++)
Expand Down Expand Up @@ -255,7 +289,7 @@ private static SchrodingersString GetPopulatedSchrodingersString(string name, bo

private static string GetOutputPath()
{
var slnDirectory = new DirectoryInfo(SolutionPath);
var slnDirectory = new DirectoryInfo(RandomizerDirectories.SolutionPath);
if (slnDirectory.Parent?.GetDirectories().Any(x => x.Name == "SMZ3CasConfigs") == true)
{
return slnDirectory.Parent.GetDirectories().First(x => x.Name == "SMZ3CasConfigs").FullName;
Expand All @@ -265,19 +299,4 @@ private static string GetOutputPath()
return Path.Combine(slnDirectory.FullName, "src", "SchemaGenerator", "Output");
}
}

private static string SolutionPath
{
get
{
var directory = new DirectoryInfo(Directory.GetCurrentDirectory());

while (directory != null && !directory.GetFiles("*.sln").Any())
{
directory = directory.Parent;
}

return Path.Combine(directory!.FullName);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Newtonsoft.Json.Schema" Version="4.0.1" />
<PackageReference Include="NJsonSchema" Version="11.0.2" />
<PackageReference Include="NJsonSchema.NewtonsoftJson" Version="11.0.2" />
<PackageReference Include="Serilog" Version="4.1.0" />
Expand Down
4 changes: 2 additions & 2 deletions src/TrackerCouncil.Smz3.Data/Logic/LogicConfig.cs
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ public LogicConfig(bool enableAllCasOptions, bool enableAllTricks, WallJumpDiffi
WallJumpDifficulty = wallJumpDifficulty;
}

[YamlIgnore]
[YamlIgnore, Newtonsoft.Json.JsonIgnore]
[DynamicFormFieldText(groupName: "CasTop")]
public string CasLogicDescription => "Logic settings that will make the experience more relaxed and easier to play.";

Expand Down Expand Up @@ -76,7 +76,7 @@ public LogicConfig(bool enableAllCasOptions, bool enableAllTricks, WallJumpDiffi
[DynamicFormFieldCheckBox(checkBoxText: "Include Quarter Magic", toolTipText: "Adds an additional progressive half magic to the item pool.", groupName: "CasMiddle")]
public bool QuarterMagic { get; set; }

[YamlIgnore]
[YamlIgnore, Newtonsoft.Json.JsonIgnore]
[DynamicFormFieldText(groupName: "TricksTop")]
public string TricksDescription => "Logic settings that will make the game more difficult by requiring you to do techniques or maneuvers not typically required in the vanilla games.";

Expand Down
12 changes: 10 additions & 2 deletions src/TrackerCouncil.Smz3.Data/Options/PlandoConfig.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
using TrackerCouncil.Smz3.Data.WorldData;
using TrackerCouncil.Smz3.Data.WorldData.Regions;
using TrackerCouncil.Smz3.Shared.Enums;
using YamlDotNet.Core;
using YamlDotNet.Serialization;

namespace TrackerCouncil.Smz3.Data.Options;
Expand All @@ -15,6 +16,12 @@ namespace TrackerCouncil.Smz3.Data.Options;
/// </summary>
public class PlandoConfig // TODO: Consider using this instead of SeedData?
{
/// <summary>
/// Number that represents the hash code the serialized string this class. Used to prevent unnecessary generation
/// of the schema file to prevent going over usage limits.
/// </summary>
public static int SHashCode = 0;

/// <summary>
/// Initializes a new empty instance of the <see cref="PlandoConfig"/>
/// class.
Expand All @@ -38,7 +45,7 @@ public PlandoConfig(World world)
TourianBossCount = world.Config.TourianBossCount;
Items = world.Locations
.ToDictionary(x => x.ToString(), x => x.Item.Type);
Rewards = world.Regions.Where(x => x is IHasReward)
Rewards = world.Regions.Where(x => x is IHasReward r && !r.RewardType.IsInCategory(RewardCategory.NonRandomized) && r.RewardType.IsInCategory(RewardCategory.Zelda))
.ToDictionary(x => x.ToString(), x => ((IHasReward)x).RewardType);
Medallions = world.Regions.Where(x => x is IHasPrerequisite)
.ToDictionary(x => x.ToString(), x => ((IHasPrerequisite)x).RequiredItem);
Expand All @@ -63,9 +70,10 @@ public PlandoConfig(World world)
/// Gets or sets the name of the file from which the plando config was
/// deserialized.
/// </summary>
[YamlIgnore]
[YamlIgnore, Newtonsoft.Json.JsonIgnore]
public string FileName { get; set; } = "";

[YamlMember(ScalarStyle = ScalarStyle.DoubleQuoted)]
public string Seed { get; set; } = "";

/// <summary>
Expand Down
2 changes: 1 addition & 1 deletion src/TrackerCouncil.Smz3.Data/Options/PlandoTextConfig.cs
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ public class PlandoTextConfig

public string? HintTileSouthEastDarkworldCave { get; init; }

[YamlIgnore]
[YamlIgnore, Newtonsoft.Json.JsonIgnore]
public bool HasHintTileText => !string.IsNullOrEmpty(HintTileEasternPalace) ||
!string.IsNullOrEmpty(HintTileTowerOfHeraFloor4) ||
!string.IsNullOrEmpty(HintTileSpectacleRock) ||
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
using System.Threading.Tasks;
using Microsoft.Extensions.Logging;
using SnesConnectorLibrary;
using TrackerCouncil.Smz3.Data;
using TrackerCouncil.Smz3.Data.GeneratedData;
using TrackerCouncil.Smz3.Data.Options;
using TrackerCouncil.Smz3.Data.WorldData.Regions;
Expand All @@ -16,6 +17,8 @@ namespace TrackerCouncil.Smz3.SeedGenerator.Generation;

public class RomTextService(ILogger<RomTextService> logger, IGameHintService gameHintService, ISnesConnectorService snesConnectorService)
{
private static readonly string s_plandoSchemaPath = @"https://raw.githubusercontent.com/TheTrackerCouncil/SMZ3CasConfigs/refs/heads/main/Schemas/plando.json";

public async Task<string> WriteSpoilerLog(RandomizerOptions options, SeedData seed, Config config, string folderPath, string fileSuffix, bool isParsedRom = false)
{
var spoilerLog = GetSpoilerLog(options, seed, config.Race || config.DisableSpoilerLog, isParsedRom);
Expand Down Expand Up @@ -78,7 +81,14 @@ public void PrepareAutoTrackerFiles(RandomizerOptions options)
var plandoConfig = new PlandoConfig(world);

var serializer = new YamlDotNet.Serialization.Serializer();
return serializer.Serialize(plandoConfig);

StringBuilder output = new();
output.AppendLine($"# yaml-language-server: $schema={GetPlandoSchemaPath()}");
output.AppendLine();
output.AppendLine("# Visual Studio Code with the redhat YAML extension is recommended for schema validation.");
output.AppendLine();
output.AppendLine(serializer.Serialize(plandoConfig));
return output.ToString();
}
catch (Exception ex)
{
Expand All @@ -87,6 +97,24 @@ public void PrepareAutoTrackerFiles(RandomizerOptions options)
}
}

private static string GetPlandoSchemaPath()
{
#if DEBUG
var parentDir = new DirectoryInfo(RandomizerDirectories.SolutionPath).Parent;
var localPlandoSchemaPath = Path.Combine(parentDir?.FullName ?? RandomizerDirectories.SolutionPath, "SMZ3CasConfigs", "Schemas", "plando.json");
if (File.Exists(localPlandoSchemaPath))
{
return localPlandoSchemaPath;
}
else
{
return s_plandoSchemaPath;
}
#else
return s_plandoSchemaPath;
#endif
}

/// <summary>
/// Underlines text in the spoiler log
/// </summary>
Expand Down

0 comments on commit 33074e2

Please sign in to comment.