using System.Text.RegularExpressions; using MongoIdTplGenerator.Utils; using SPTarkov.DI.Annotations; using SPTarkov.Server.Core.Models.Common; using SPTarkov.Server.Core.Models.Eft.Common.Tables; using SPTarkov.Server.Core.Models.Utils; using SPTarkov.Server.Core.Servers; using SPTarkov.Server.Core.Utils; using Path = System.IO.Path; namespace MongoIdTplGenerator.Generators; [Injectable] public class BaseClassesIdGenerator( ISptLogger logger, DatabaseServer databaseServer, FileUtil fileUtil, LocaleUtil localeUtil ) : IMongoIdGenerator { private string _enumDir; private Dictionary _items; public Task Run() { // Figure out our source and target directories var projectDir = Directory.GetParent("./").Parent.Parent.Parent.Parent.Parent; _enumDir = Path.Combine( projectDir.FullName, "Libraries", "SPTarkov.Server.Core", "Models", "Enums" ); _items = databaseServer.GetTables().Templates.Items; // Generate an object containing all item name to ID associations var orderedItemsObject = GenerateItemsObject(); // Log any changes to enum values, so the source can be updated as required LogEnumValueChanges(orderedItemsObject, "BaseClasses", typeof(BaseClasses)); var itemTplOutPath = Path.Combine(_enumDir, "BaseClasses.cs"); WriteEnumsToFile( itemTplOutPath, new Dictionary> { { nameof(BaseClasses), orderedItemsObject }, } ); logger.Info("Generating items finished"); return Task.CompletedTask; } /// /// Return an object containing all items in the game with a generated name /// /// An object containing a generated item name to item ID association private Dictionary GenerateItemsObject() { var itemsObject = new Dictionary(); foreach (var item in _items.Values) { // Skip invalid items (Non-Item types, and shrapnel) if (item.Type != "Node") { continue; } var underscoredName = Regex.Replace(item.Name, @"(? kv1.Key.CompareTo(kv2.Key)); var orderedItemsObject = itemList.ToDictionary(kv => kv.Key, kv => kv.Value); return orderedItemsObject; } private void LogEnumValueChanges( Dictionary data, string enumName, Type originalEnum ) { // First generate a mapping of the original enum values to names var originalEnumValues = new Dictionary(); foreach (var field in originalEnum.GetFields()) { originalEnumValues.Add(field.GetValue(null)!.ToString()!, field.Name); } // Loop through our new data, and find anywhere the given ID's name doesn't match the original enum foreach (var kv in data) { if (originalEnumValues.ContainsKey(kv.Value) && originalEnumValues[kv.Value] != kv.Key) { logger.Warning( $"Enum {enumName} key has changed for {kv.Value}, {originalEnumValues[kv.Value]} => {kv.Key}" ); } } } private void WriteEnumsToFile( string outputPath, Dictionary> enumEntries ) { var enumFileData = "using SPTarkov.Server.Core.Models.Common;\n\n" + "// This is an auto generated file, do not modify. Re-generate by running MongoIdTplGenerator.exe"; foreach (var (enumName, data) in enumEntries) { enumFileData += $"\npublic static class {enumName}\n{{\n"; foreach (var (key, value) in data) { enumFileData += $" public static readonly MongoId {key} = new MongoId(\"{value}\");\n"; } enumFileData += "}\n"; } fileUtil.WriteFile(outputPath, enumFileData); } }