using System; using System.IO; using System.Windows.Forms; using System.Xml; namespace TeslaConsole.RedPlanet; internal static class RPDefaults { public abstract class ScenarioDefaults { private bool mScoreCompression; private TimeSpan mMissionLength = new TimeSpan(0, 10, 0); private string mMapKey; private string mVehicleKey; private string mTimeOfDayKey; private string mWeatherKey; private int mLaunchDelay = 15; public bool ScoreCompression { get { return mScoreCompression; } set { mScoreCompression = value; } } public TimeSpan MissionLength { get { return mMissionLength; } set { mMissionLength = value; } } public string MapKey { get { return mMapKey; } set { mMapKey = value; } } public string VehicleKey { get { return mVehicleKey; } set { mVehicleKey = value; } } public string TimeOfDayKey { get { return mTimeOfDayKey; } set { mTimeOfDayKey = value; } } public string WeatherKey { get { return mWeatherKey; } set { mWeatherKey = value; } } public int LaunchDelay { get { return mLaunchDelay; } set { mLaunchDelay = value; } } public ScenarioDefaults() { } public abstract void Save(XmlNode parrentNode); protected void SaveCommonData(XmlNode scenarioNode) { scenarioNode.AppendChild(scenarioNode.OwnerDocument.CreateElement("ScoreCompression")).InnerText = mScoreCompression.ToString(); scenarioNode.AppendChild(scenarioNode.OwnerDocument.CreateElement("MissionLength")).InnerText = mMissionLength.ToString(); if (!string.IsNullOrEmpty(mMapKey)) { scenarioNode.AppendChild(scenarioNode.OwnerDocument.CreateElement("MapKey")).InnerText = mMapKey; } if (!string.IsNullOrEmpty(mVehicleKey)) { scenarioNode.AppendChild(scenarioNode.OwnerDocument.CreateElement("VehicleKey")).InnerText = mVehicleKey; } if (!string.IsNullOrEmpty(mTimeOfDayKey)) { scenarioNode.AppendChild(scenarioNode.OwnerDocument.CreateElement("TimeOfDayKey")).InnerText = mTimeOfDayKey; } if (!string.IsNullOrEmpty(mWeatherKey)) { scenarioNode.AppendChild(scenarioNode.OwnerDocument.CreateElement("WeatherKey")).InnerText = mWeatherKey; } scenarioNode.AppendChild(scenarioNode.OwnerDocument.CreateElement("LaunchDelay")).InnerText = mLaunchDelay.ToString(); } public abstract void Parse(XmlNode scenarioNode); protected bool ParseCommonData(XmlNode node) { switch (node.Name) { case "ScoreCompression": { if (bool.TryParse(node.InnerText, out var result2)) { mScoreCompression = result2; } return true; } case "MissionLength": { if (TimeSpan.TryParse(node.InnerText, out var result3)) { mMissionLength = result3; } return true; } case "MapKey": if (!string.IsNullOrEmpty(node.InnerText)) { mMapKey = node.InnerText; } return true; case "VehicleKey": if (!string.IsNullOrEmpty(node.InnerText)) { mVehicleKey = node.InnerText; } return true; case "TimeOfDayKey": if (!string.IsNullOrEmpty(node.InnerText)) { mTimeOfDayKey = node.InnerText; } return true; case "WeatherKey": if (!string.IsNullOrEmpty(node.InnerText)) { mWeatherKey = node.InnerText; } return true; case "LaunchDelay": { if (int.TryParse(node.InnerText, out var result)) { mLaunchDelay = result; } return true; } default: return false; } } } public class DeathRaceDefaults : ScenarioDefaults { public const string DeathRaceNode = "DeathRaceDefaults"; private string mColorKey; private string mBadgeKey; public string ColorKey { get { return mColorKey; } set { mColorKey = value; } } public string BadgeKey { get { return mBadgeKey; } set { mBadgeKey = value; } } public override void Save(XmlNode parrentNode) { XmlNode xmlNode = parrentNode.AppendChild(parrentNode.OwnerDocument.CreateElement("DeathRaceDefaults")); SaveCommonData(xmlNode); if (!string.IsNullOrEmpty(mColorKey)) { xmlNode.AppendChild(xmlNode.OwnerDocument.CreateElement("ColorKey")).InnerText = mColorKey; } if (!string.IsNullOrEmpty(mBadgeKey)) { xmlNode.AppendChild(xmlNode.OwnerDocument.CreateElement("BadgeKey")).InnerText = mBadgeKey; } } public override void Parse(XmlNode scenarioNode) { foreach (XmlNode childNode in scenarioNode.ChildNodes) { if (ParseCommonData(childNode)) { continue; } switch (childNode.Name) { case "ColorKey": if (!string.IsNullOrEmpty(childNode.InnerText)) { mColorKey = childNode.InnerText; } break; case "BadgeKey": if (!string.IsNullOrEmpty(childNode.InnerText)) { mBadgeKey = childNode.InnerText; } break; } } } } public class FootballDefaults : ScenarioDefaults { public const string FootballNode = "FootballDefaults"; private string mTeamKey; private string mPositionKey; public string TeamKey { get { return mTeamKey; } set { mTeamKey = value; } } public string PositionKey { get { return mPositionKey; } set { mPositionKey = value; } } public override void Save(XmlNode parrentNode) { XmlNode xmlNode = parrentNode.AppendChild(parrentNode.OwnerDocument.CreateElement("FootballDefaults")); SaveCommonData(xmlNode); if (!string.IsNullOrEmpty(mTeamKey)) { xmlNode.AppendChild(xmlNode.OwnerDocument.CreateElement("TeamKey")).InnerText = mTeamKey; } if (!string.IsNullOrEmpty(mPositionKey)) { xmlNode.AppendChild(xmlNode.OwnerDocument.CreateElement("PositionKey")).InnerText = mPositionKey; } } public override void Parse(XmlNode scenarioNode) { foreach (XmlNode childNode in scenarioNode.ChildNodes) { if (ParseCommonData(childNode)) { continue; } switch (childNode.Name) { case "TeamKey": if (!string.IsNullOrEmpty(childNode.InnerText)) { mTeamKey = childNode.InnerText; } break; case "PositionKey": if (!string.IsNullOrEmpty(childNode.InnerText)) { mPositionKey = childNode.InnerText; } break; } } } } private static readonly string sDefaultsFilePath; private static readonly DeathRaceDefaults sDeathRace; private static readonly FootballDefaults sFootball; public static DeathRaceDefaults DeathRace => sDeathRace; public static FootballDefaults Football => sFootball; /// /// When set, the Red Planet game pages target each pod's DOSBox-X guest /// (last octet +100) instead of the pod itself. A machine-level setting for /// the emulator preservation pods, so it is stored once per defaults file /// rather than per scenario. /// public static bool DosBoxAddressShift { get; set; } static RPDefaults() { sDefaultsFilePath = Path.Combine(Program.GetCommonAppDataDirectory(), "RPDefaults.rpd"); sDeathRace = new DeathRaceDefaults(); sFootball = new FootballDefaults(); if (File.Exists(sDefaultsFilePath)) { try { Import(sDefaultsFilePath); } catch (Exception) { MessageBox.Show("The Red Planet defaults file appears to be corrupt. Please open the Red Planet Defaults Dialog and save to create a new defaults file.", "Error Loading Red Planet Defaults!", MessageBoxButtons.OK); } } } public static void Import(string fileName) { XmlDocument xmlDocument = new XmlDocument(); xmlDocument.Load(fileName); foreach (XmlNode childNode in xmlDocument.DocumentElement.ChildNodes) { switch (childNode.Name) { case "DeathRaceDefaults": sDeathRace.Parse(childNode); break; case "FootballDefaults": sFootball.Parse(childNode); break; case "DosBoxAddressShift": { if (bool.TryParse(childNode.InnerText, out var result)) { DosBoxAddressShift = result; } break; } } } } public static void Save() { try { Export(sDefaultsFilePath); } catch (Exception) { MessageBox.Show("The Red Planet defaults file could not be saved. These defaults will only be remembered until the application is closed.", "Error Saving Red Planet Defaults!", MessageBoxButtons.OK); } } public static void Export(string filePath) { XmlDocument xmlDocument = new XmlDocument(); xmlDocument.AppendChild(xmlDocument.CreateElement("RPDefaults")); sDeathRace.Save(xmlDocument.DocumentElement); sFootball.Save(xmlDocument.DocumentElement); xmlDocument.DocumentElement.AppendChild(xmlDocument.CreateElement("DosBoxAddressShift")).InnerText = DosBoxAddressShift.ToString(); string directoryName = Path.GetDirectoryName(filePath); if (!Directory.Exists(directoryName)) { Directory.CreateDirectory(directoryName); } xmlDocument.Save(filePath); } }