using KianaBH.Internationalization; using KianaBH.Util; using Newtonsoft.Json; using Newtonsoft.Json.Linq; using System.Reflection; namespace KianaBH.Data; public class ResourceManager { public static Logger Logger { get; } = new("ResourceManager"); public static bool IsLoaded { get; set; } public static void LoadGameData() { LoadExcel(); } public static void LoadExcel() { var classes = Assembly.GetExecutingAssembly().GetTypes(); // Get all classes in the assembly List resList = []; foreach (var cls in classes.Where(x => x.IsSubclassOf(typeof(ExcelResource)))) { var res = LoadSingleExcelResource(cls); if (res != null) resList.AddRange(res); } foreach (var cls in resList) cls.AfterAllDone(); } public static List? LoadSingleExcel(Type cls) where T : ExcelResource, new() { return LoadSingleExcelResource(cls) as List; } public static List? LoadSingleExcelResource(Type cls) { var attribute = (ResourceEntity?)Attribute.GetCustomAttribute(cls, typeof(ResourceEntity)); if (attribute == null) return null; var resource = (ExcelResource)Activator.CreateInstance(cls)!; var count = 0; List resList = []; foreach (var fileName in attribute.FileName) try { var path = ConfigManager.Config.Path.ResourcePath + "/ExcelOutput/" + fileName; var file = new FileInfo(path); if (!file.Exists) { Logger.Error(I18NManager.Translate("Server.ServerInfo.FailedToReadItem", fileName, I18NManager.Translate("Word.NotFound"))); continue; } var json = file.OpenText().ReadToEnd(); using (var reader = new JsonTextReader(new StringReader(json))) { reader.Read(); switch (reader.TokenType) { case JsonToken.StartArray: { // array var jArray = JArray.Parse(json); foreach (var item in jArray) { var res = JsonConvert.DeserializeObject(item.ToString(), cls); resList.Add((ExcelResource)res!); ((ExcelResource?)res)?.Loaded(); count++; } break; } case JsonToken.StartObject: { // dictionary var jObject = JObject.Parse(json); foreach (var (_, obj) in jObject) { var instance = JsonConvert.DeserializeObject(obj!.ToString(), cls); if (((ExcelResource?)instance)?.GetId() == 0 || (ExcelResource?)instance == null) { // Deserialize as JObject to handle nested dictionaries var nestedObject = JsonConvert.DeserializeObject(obj.ToString()); foreach (var nestedItem in nestedObject ?? []) { var nestedInstance = JsonConvert.DeserializeObject(nestedItem.Value!.ToString(), cls); resList.Add((ExcelResource)nestedInstance!); ((ExcelResource?)nestedInstance)?.Loaded(); count++; } } else { resList.Add((ExcelResource)instance); ((ExcelResource)instance).Loaded(); } count++; } break; } } } resource.Finalized(); } catch (Exception ex) { Logger.Error( I18NManager.Translate("Server.ServerInfo.FailedToReadItem", fileName, I18NManager.Translate("Word.Error")), ex); } Logger.Info(I18NManager.Translate("Server.ServerInfo.LoadedItems", count.ToString(), cls.Name)); return resList; } public static T? LoadCustomFile(string filetype, string filename) { var type = I18NManager.Translate("Word." + filetype); Logger.Info(I18NManager.Translate("Server.ServerInfo.LoadingItem", type)); FileInfo file = new(ConfigManager.Config.Path.DataPath + $"/{filename}.json"); T? customFile = default; if (!file.Exists) { Logger.Warn(I18NManager.Translate("Server.ServerInfo.ConfigMissing", type, $"{ConfigManager.Config.Path.DataPath}/{filename}.json", type)); return customFile; } try { using var reader = file.OpenRead(); using StreamReader reader2 = new(reader); var text = reader2.ReadToEnd(); var json = JsonConvert.DeserializeObject(text); customFile = json; } catch (Exception ex) { Logger.Error("Error in reading " + file.Name, ex); } switch (customFile) { case Dictionary d: Logger.Info(I18NManager.Translate("Server.ServerInfo.LoadedItems", d.Count.ToString(), type)); break; case Dictionary> di: Logger.Info(I18NManager.Translate("Server.ServerInfo.LoadedItems", di.Count.ToString(), type)); break; default: Logger.Info(I18NManager.Translate("Server.ServerInfo.LoadedItem", filetype)); break; } return customFile; } }