using System.Collections.Generic; using System.Xml; using System.Xml.Linq; public static class CustomGameOptions { private static string SaveDataPath = ""; private static string ModPath = ""; private static string GameOptionsFilename = "CustomGameOptions.xml"; public static bool ReloadUI = false; public static Dictionary StoredOptions; static CustomGameOptions() { //Log.Out("CustomGameOptions-CustomGameOptions START"); StoredOptions = new Dictionary(); var mod = ModManager.GetMod("zzz_REBIRTH__Utils", true); ModPath = mod.Path; SaveDataPath = GameIO.GetUserGameDataDir() + "/RebirthData"; Directory.CreateDirectory(SaveDataPath); //Log.Out("DataConfigPath = " + SaveDataPath); } public static void CheckConfigs() { //Log.Out("CustomGameOptions-CheckConfigs START"); if (GameManager.IsDedicatedServer) { string path = SaveDataPath + "/" + GameOptionsFilename; //Log.Out("CustomGameOptions-CheckConfigs IS DEDICATED"); if (!File.Exists(path)) { //Log.Out("CustomGameOptions-CheckConfigs FILE DOES NOT EXIST"); LoadDefaultGameOptions(); SaveGameOptions(); } } } public static void LoadConfigs(XmlFile xmlFile) { //Log.Out("CustomGameOptions-LoadConfigs START"); LoadGameOptions(xmlFile); //Log.Out("Custom Game Options Loaded."); RebirthVariables.setConfigVariables(); RebirthVariables.randomWeaponInitiated = false; } public static void LoadDefaultGameOptions() { var path = ModPath + "/Config/XUi_Menu/"; if (File.Exists(path + "windows.xml")) { XDocument xWindows = SdXDocument.Load(path + "windows.xml"); if (xWindows.Root == null) { throw new Exception("Invalid CustomGameOptions file: " + path); } foreach (XElement xmlElement in xWindows.Descendants("gameoption")) { var value = xmlElement.GetAttribute("default_value"); var name = xmlElement.GetAttribute("name"); StoredOptions[name] = value; } } //Log.Out("Custom Game Options Default Values Loaded."); } public static void LoadGameOptions(XmlFile xmlFile, bool isContinueGame = false) { //Log.Out("CustomGameOptions-LoadGameOptions START"); //Log.Out("CustomGameOptions-LoadGameOptions isContinueGame: " + isContinueGame); //string savePath = $"{SaveDataPath}/CustomGameOptions/{GamePrefs.GetString(EnumGamePrefs.GameWorld)}/{GamePrefs.GetString(EnumGamePrefs.GameName)}"; string savePath = $"{SaveDataPath}"; //Log.Out("CustomGameOptions-LoadGameOptions savePath: " + savePath); if (GameManager.IsDedicatedServer) { LoadDefaultGameOptions(); } XDocument xdocument = new XDocument(); if (xmlFile == null) { //Log.Out("CustomGameOptions-LoadGameOptions LOCAL"); if (!string.IsNullOrEmpty(savePath)) { string path = savePath + "/" + GameOptionsFilename; //Log.Out("CustomGameOptions-LoadGameOptions PATH EXISTS, SaveDataPath: " + SaveDataPath); if (File.Exists(path)) { //Log.Out("CustomGameOptions-LoadGameOptions FILE EXISTS A"); xdocument = SdXDocument.Load(path); } else { //Log.Out("CustomGameOptions-LoadGameOptions FILE DOES NOT EXIST, path: " + path); string oldPath = ModPath + "/CustomGameOptions" + "/" + GameOptionsFilename; //Log.Out("CustomGameOptions-LoadGameOptions old path: " + oldPath); if (File.Exists(oldPath)) { //Log.Out("CustomGameOptions-LoadGameOptions FILE EXISTS B"); xdocument = SdXDocument.Load(oldPath); } else { //Log.Out("CustomGameOptions-LoadGameOptions FILE DOES NOT EXIST B"); LoadDefaultGameOptions(); SaveGameOptions(); xdocument = SdXDocument.Load(path); } } } } else { //Log.Out("CustomGameOptions-LoadGameOptions xmlFile"); xdocument = xmlFile.XmlDoc; } if (xdocument.Root == null) { throw new Exception("Invalid CustomGameOptions file"); } foreach (XElement xmlElement in xdocument.Root.Elements()) { if (xmlElement.Name == "config") { if (!xmlElement.HasAttribute("name")) { throw new Exception("Attribute 'name' missing on item"); } if (!xmlElement.HasAttribute("value")) { throw new Exception("Attribute 'value' missing on item"); } var value = xmlElement.GetAttribute("value"); var name = xmlElement.GetAttribute("name"); StoredOptions[name] = value; Log.Out($"CustomGameOption {name}: {value}"); } } if (GameManager.IsDedicatedServer) { SaveGameOptions(); } } public static void SaveGameOptions() { //Log.Out("CustomGameOptions-SaveGameOptions START"); XmlDocument xmlDocument = new XmlDocument(); XmlDeclaration newChild = xmlDocument.CreateXmlDeclaration("1.0", "UTF-8", null); xmlDocument.InsertBefore(newChild, xmlDocument.DocumentElement); XmlNode parent = xmlDocument.AppendChild(xmlDocument.CreateElement("customgameoptions")); foreach (var key in StoredOptions.Keys) { parent.AppendChild(CreateXMLGameOptionChild(xmlDocument, key, StoredOptions[key].ToString())); } //Log.Out(SerializeToString(xmlDocument)); // Make sure folder is there before saving string savePath = $"{SaveDataPath}/CustomGameOptions/{GamePrefs.GetString(EnumGamePrefs.GameWorld)}/{GamePrefs.GetString(EnumGamePrefs.GameName)}"; //Log.Out("CustomGameOptions-SaveGameOptions savePath: " + savePath); //Directory.CreateDirectory(savePath); Directory.CreateDirectory(SaveDataPath); //var path = savePath + "/" + GameOptionsFilename; //File.WriteAllText(path, SerializeToString(xmlDocument), Encoding.UTF8); // Write a copy to the root of the RebirthData folder XmlWriterSettings settings = new XmlWriterSettings { Indent = true, // Enable indentation IndentChars = " ", // Use 4 spaces for indentation (you can adjust this as needed) NewLineOnAttributes = false // Optionally place attributes on new lines }; string path = SaveDataPath + "/" + GameOptionsFilename; // Write the formatted XML to file using (XmlWriter writer = XmlWriter.Create(path, settings)) { xmlDocument.Save(writer); } //File.WriteAllText(path, SerializeToString(xmlDocument), Encoding.UTF8); } private static XmlElement CreateXMLGameOptionChild(XmlDocument xmlDocument, string name, string value) { XmlElement xmlElement = xmlDocument.CreateElement("config"); XmlAttribute xmlAttributeName = xmlDocument.CreateAttribute("name"); xmlAttributeName.Value = name; xmlElement.Attributes.Append(xmlAttributeName); XmlAttribute xmlAttributeValue = xmlDocument.CreateAttribute("value"); xmlAttributeValue.Value = value.ToLower(); xmlElement.Attributes.Append(xmlAttributeValue); return xmlElement; } private static string SerializeToString(XmlDocument xmlDocument) { string result; using (StringWriter stringWriter = new StringWriter()) { using (XmlTextWriter xmlTextWriter = new XmlTextWriter(stringWriter)) { xmlDocument.WriteTo(xmlTextWriter); result = stringWriter.ToString(); } } return result; } public static bool HasValue(string name) { return StoredOptions.ContainsKey(name); } public static void SetValue(string name, object value) { //Log.Out("CustomGameOptions-SetValue NEW VALUE StoredOptions[" + name + "]: " + value); StoredOptions[name] = value.ToString(); //Log.Out("CustomGameOptions-SetValue SET VALUE StoredOptions[" + name + "]: " + StoredOptions[name]); } public static int GetInt(string name, int defaultValue = 0) { if (!StoredOptions.ContainsKey(name)) { return defaultValue; } return int.TryParse(StoredOptions[name], out var output) ? output : defaultValue; } public static string GetString(string name, string defaultValue = "") { if (!StoredOptions.ContainsKey(name)) { return defaultValue; } //Log.Out("StoredOptions[" + name + "].ToString(): " + StoredOptions[name].ToString()); //Log.Out("LOCALIZED StoredOptions[" + name + "].ToString(): " + Localization.Get(StoredOptions[name].ToString())); return StoredOptions[name].ToString(); } public static bool GetBool(string name, bool defaultValue = false) { if (!StoredOptions.ContainsKey(name)) { return defaultValue; } return bool.TryParse(StoredOptions[name], out var output) ? output : defaultValue; } }