/// <summary>Parses a openBVE panel.animated.xml file</summary> /// <param name="PanelFile">The relative path of the panel configuration file from the train</param> /// <param name="TrainPath">The on-disk path to the train</param> /// <param name="Train">The train</param> /// <param name="Car">The car index to add the panel to</param> internal static void ParsePanelAnimatedXml(string PanelFile, string TrainPath, TrainManager.Train Train, int Car) { // The current XML file to load string FileName = PanelFile; if (!File.Exists(FileName)) { FileName = Path.CombineFile(TrainPath, PanelFile); } XDocument CurrentXML = XDocument.Load(FileName, LoadOptions.SetLineInfo); // Check for null if (CurrentXML.Root == null) { // We couldn't find any valid XML, so return false throw new System.IO.InvalidDataException(); } IEnumerable <XElement> DocumentElements = CurrentXML.Root.Elements("PanelAnimated"); // Check this file actually contains OpenBVE panel definition elements if (DocumentElements == null || !DocumentElements.Any()) { // We couldn't find any valid XML, so return false throw new System.IO.InvalidDataException(); } foreach (XElement element in DocumentElements) { ParsePanelAnimatedNode(element, FileName, TrainPath, Train, Car, Train.Cars[Car].CarSections[0], 0); } }
private static void ParseNode(string basePath, XElement parentNode, SoundElement element) { foreach (XElement childNode in parentNode.Elements()) { switch (childNode.Name.LocalName.ToLowerInvariant()) { case "filename": if (!childNode.Value.Any() || Path.ContainsInvalidChars(childNode.Value)) { Interface.AddMessage(MessageType.Error, false, $"FileName {childNode.Value} contains illegal characters or is empty in XML node {parentNode.Name.LocalName} at line {((IXmlLineInfo)childNode).LineNumber}."); return; } element.FilePath = Path.CombineFile(basePath, childNode.Value); break; case "position": string[] Arguments = childNode.Value.Split(','); double x = 0.0, y = 0.0, z = 0.0; if (Arguments.Length >= 1 && Arguments[0].Length > 0 && !NumberFormats.TryParseDoubleVb6(Arguments[0], out x)) { Interface.AddMessage(MessageType.Error, false, $"Sound radius X {Arguments[0]} in XML node {parentNode.Name.LocalName} at line {((IXmlLineInfo)childNode).LineNumber} is invalid."); x = 0.0; } if (Arguments.Length >= 2 && Arguments[1].Length > 0 && !NumberFormats.TryParseDoubleVb6(Arguments[1], out y)) { Interface.AddMessage(MessageType.Error, false, $"Sound radius Y {Arguments[1]} in XML node {parentNode.Name.LocalName} at line {((IXmlLineInfo)childNode).LineNumber} is invalid."); y = 0.0; } if (Arguments.Length >= 3 && Arguments[2].Length > 0 && !NumberFormats.TryParseDoubleVb6(Arguments[2], out z)) { Interface.AddMessage(MessageType.Error, false, $"Sound radius Z {Arguments[2]} in XML node {parentNode.Name.LocalName} at line {((IXmlLineInfo)childNode).LineNumber} is invalid."); z = 0.0; } element.PositionX = x; element.PositionY = y; element.PositionZ = z; element.DefinedPosition = true; break; case "radius": double radius; if (!NumberFormats.TryParseDoubleVb6(childNode.Value, out radius)) { Interface.AddMessage(MessageType.Error, false, $"The sound radius {childNode.Value} in XML node {parentNode.Name.LocalName} at line {((IXmlLineInfo)childNode).LineNumber} is invalid."); } element.Radius = radius; element.DefinedRadius = true; break; } } }
private static void CheckFile <T, U>(ICollection <SoundElement> elements, string trainFolder, string fileName, U key) where T : SoundElement <U>, new() { string filePath = Path.CombineFile(trainFolder, fileName); if (File.Exists(filePath)) { elements.Add(new T { Key = key, FilePath = filePath }); } }
private void buttonSelectFolder_Click(object sender, EventArgs e) { folderBrowserDialog = new FolderBrowserDialog(); if (folderBrowserDialog.ShowDialog() == DialogResult.OK) { ConvertTrainDat.FileName = Path.CombineFile(folderBrowserDialog.SelectedPath, "train.dat"); ConvertSoundCfg.FileName = Path.CombineFile(folderBrowserDialog.SelectedPath, "sound.cfg"); ConvertExtensionsCfg.FileName = Path.CombineFile(folderBrowserDialog.SelectedPath, "extensions.cfg"); textBox1.Text = folderBrowserDialog.SelectedPath; } }
internal static void LoadRoutePatchDatabase(ref Dictionary <string, RoutefilePatch> routePatches, string databaseFile = "") { //The current XML file to load XmlDocument currentXML = new XmlDocument(); if (databaseFile == string.Empty) { databaseFile = Path.CombineFile(Plugin.FileSystem.GetDataFolder("Compatibility\\RoutePatches"), "database.xml"); if (!File.Exists(databaseFile)) { return; } } currentXML.Load(databaseFile); //Check for null if (currentXML.DocumentElement != null) { XmlNodeList DocumentNodes = currentXML.DocumentElement.SelectNodes("/openBVE/RoutePatches"); //Check this file actually contains OpenBVE route patch definition nodes if (DocumentNodes != null) { for (int i = 0; i < DocumentNodes.Count; i++) { if (DocumentNodes[i].HasChildNodes) { foreach (XmlElement childNode in DocumentNodes[i].ChildNodes.OfType <XmlElement>()) { switch (childNode.Name) { case "Patch": if (childNode.HasChildNodes) { ParsePatchNode(childNode, ref routePatches); } break; case "PatchList": string folder = System.IO.Path.GetDirectoryName(databaseFile); string newFile = Path.CombineFile(folder, childNode.InnerText); if (File.Exists(newFile)) { LoadRoutePatchDatabase(ref routePatches, newFile); } break; } } } } } } }
private void process_Click(object sender, EventArgs e) { updateLogBoxText = "Loading parameters from train.dat file " + ConvertTrainDat.FileName + Environment.NewLine; ConvertTrainDat.Process(this); if (!System.IO.File.Exists(ConvertSoundCfg.FileName)) { updateLogBoxText += "INFO: No sound.cfg file detected." + Environment.NewLine; //TODO: Is it worth spinning up a default XML for the BVE2 sound-set?? if (MessageBox.Show("The selected folder does not contain a valid sound.cfg", "CarXML Convertor", MessageBoxButtons.OKCancel, MessageBoxIcon.Information) == DialogResult.Cancel) { updateLogBoxText += "Aborting...."; return; } } if (System.IO.File.Exists(Path.CombineFile(System.IO.Path.GetDirectoryName(ConvertSoundCfg.FileName), "sound.xml"))) { updateLogBoxText += "INFO: An existing sound.xml file was detected." + Environment.NewLine; if (MessageBox.Show("The selected folder already contains a sound.xml file. \r\n Do you wish to continue?", "CarXML Convertor", MessageBoxButtons.OKCancel, MessageBoxIcon.Information) == DialogResult.Cancel) { updateLogBoxText += "Aborting...."; return; } updateLogBoxText += "Overwriting...." + Environment.NewLine; } updateLogBoxText += "Loading existing sound.cfg file " + ConvertSoundCfg.FileName + Environment.NewLine; ConvertSoundCfg.Process(this); if (System.IO.File.Exists(Path.CombineFile(System.IO.Path.GetDirectoryName(ConvertExtensionsCfg.FileName), "train.xml"))) { updateLogBoxText += "INFO: An existing train.xml file was detected." + Environment.NewLine; if (MessageBox.Show("The selected folder already contains a train.xml file. \r\n Do you wish to continue?", "CarXML Convertor", MessageBoxButtons.OKCancel, MessageBoxIcon.Information) == DialogResult.Cancel) { return; } updateLogBoxText += "Overwriting...." + Environment.NewLine; } if (this.radioButtonSingleFile.Checked == true) { updateLogBoxText += "INFO: Using a single train.xml file." + Environment.NewLine; ConvertExtensionsCfg.SingleFile = true; } else { updateLogBoxText += "INFO: Using a train.xml file with child car files." + Environment.NewLine; ConvertExtensionsCfg.SingleFile = false; } ConvertExtensionsCfg.Process(this); updateLogBoxText += "Processing complete."; }
private void buttonSelectFolder_Click(object sender, EventArgs e) { folderBrowserDialog = new FolderBrowserDialog(); if (folderBrowserDialog.ShowDialog() == DialogResult.OK) { ConvertTrainDat.FileName = Path.CombineFile(folderBrowserDialog.SelectedPath, "train.dat"); ConvertSoundCfg.FileName = Path.CombineFile(folderBrowserDialog.SelectedPath, "sound.cfg"); //TODO: //Check for all train components when the above is complete //Error checking?? if (!System.IO.File.Exists(ConvertSoundCfg.FileName)) { return; } textBox1.Text = ConvertSoundCfg.FileName; } }
internal static void ParsePatchNode(XmlNode node, ref Dictionary <string, RoutefilePatch> routeFixes) { RoutefilePatch currentPatch = new RoutefilePatch(); string currentHash = string.Empty; foreach (XmlElement childNode in node.ChildNodes.OfType <XmlElement>()) { string t; switch (childNode.Name) { case "Hash": currentHash = childNode.InnerText; break; case "FileName": currentPatch.FileName = childNode.InnerText; break; case "LineEndingFix": t = childNode.InnerText.Trim().ToLowerInvariant(); if (t == "1" || t == "true") { currentPatch.LineEndingFix = true; } else { currentPatch.LineEndingFix = false; } break; case "IgnorePitchRoll": t = childNode.InnerText.Trim().ToLowerInvariant(); if (t == "1" || t == "true") { currentPatch.IgnorePitchRoll = true; } else { currentPatch.IgnorePitchRoll = false; } break; case "LogMessage": currentPatch.LogMessage = childNode.InnerText; break; case "CylinderHack": t = childNode.InnerText.Trim().ToLowerInvariant(); if (t == "1" || t == "true") { currentPatch.CylinderHack = true; } else { currentPatch.CylinderHack = false; } break; case "Expression": t = childNode.Attributes["Number"].InnerText; int expressionNumber; if (NumberFormats.TryParseIntVb6(t, out expressionNumber)) { currentPatch.ExpressionFixes.Add(expressionNumber, childNode.InnerText); } break; case "XParser": switch (childNode.InnerText.ToLowerInvariant()) { case "original": currentPatch.XParser = XParsers.Original; break; case "new": currentPatch.XParser = XParsers.NewXParser; break; case "assimp": currentPatch.XParser = XParsers.Assimp; break; } break; case "DummyRailTypes": string[] splitString = childNode.InnerText.Split(','); for (int i = 0; i < splitString.Length; i++) { int rt; if (NumberFormats.TryParseIntVb6(splitString[i], out rt)) { currentPatch.DummyRailTypes.Add(rt); } } break; case "DummyGroundTypes": splitString = childNode.InnerText.Split(','); for (int i = 0; i < splitString.Length; i++) { int gt; if (NumberFormats.TryParseIntVb6(splitString[i], out gt)) { currentPatch.DummyGroundTypes.Add(gt); } } break; case "Derailments": t = childNode.InnerText.Trim().ToLowerInvariant(); if (t == "0" || t == "false") { currentPatch.Derailments = false; } else { currentPatch.Derailments = true; } break; case "Toppling": t = childNode.InnerText.Trim().ToLowerInvariant(); if (t == "0" || t == "false") { currentPatch.Derailments = false; } else { currentPatch.Derailments = true; } break; case "SignalSet": string signalFile = Path.CombineFile(Plugin.FileSystem.GetDataFolder("Compatibility\\Signals"), childNode.InnerText.Trim()); if (File.Exists(signalFile)) { currentPatch.CompatibilitySignalSet = signalFile; } break; case "AccurateObjectDisposal": t = childNode.InnerText.Trim().ToLowerInvariant(); if (t == "1" || t == "true") { currentPatch.AccurateObjectDisposal = true; } else { currentPatch.AccurateObjectDisposal = false; } break; case "SplitLineHack": t = childNode.InnerText.Trim().ToLowerInvariant(); if (t == "1" || t == "true") { currentPatch.SplitLineHack = true; } else { currentPatch.SplitLineHack = false; } break; case "AllowTrackPositionArguments": t = childNode.InnerText.Trim().ToLowerInvariant(); if (t == "1" || t == "true") { currentPatch.AllowTrackPositionArguments = true; } else { currentPatch.AllowTrackPositionArguments = false; } break; case "DisableSemiTransparentFaces": t = childNode.InnerText.Trim().ToLowerInvariant(); if (t == "1" || t == "true") { currentPatch.DisableSemiTransparentFaces = true; } else { currentPatch.DisableSemiTransparentFaces = false; } break; case "ReducedColorTransparency": t = childNode.InnerText.Trim().ToLowerInvariant(); if (t == "1" || t == "true") { currentPatch.ReducedColorTransparency = true; } else { currentPatch.ReducedColorTransparency = false; } break; } } if (!routeFixes.ContainsKey(currentHash)) { routeFixes.Add(currentHash, currentPatch); } else { Plugin.CurrentHost.AddMessage(MessageType.Error, false, "The RoutePatches database contains a duplicate entry with hash " + currentHash); } }
internal static void ReadExtensionsCfg() { string[] Lines = System.IO.File.ReadAllLines(FileName, System.Text.Encoding.Default); for (int i = 0; i < Lines.Length; i++) { int j = Lines[i].IndexOf(';'); if (j >= 0) { Lines[i] = Lines[i].Substring(0, j).Trim(); } else { Lines[i] = Lines[i].Trim(); } } for (int i = 0; i < Lines.Length; i++) { if (Lines[i].Length != 0) { switch (Lines[i].ToLowerInvariant()) { case "[exterior]": // exterior i++; while (i < Lines.Length && !Lines[i].StartsWith("[", StringComparison.Ordinal) & !Lines[i].EndsWith("]", StringComparison.Ordinal)) { if (Lines[i].Length != 0) { int j = Lines[i].IndexOf("=", StringComparison.Ordinal); if (j >= 0) { string a = Lines[i].Substring(0, j).TrimEnd(); string b = Lines[i].Substring(j + 1).TrimStart(); int n; if (int.TryParse(a, System.Globalization.NumberStyles.Integer, Culture, out n)) { if (n >= 0 & n < ConvertTrainDat.NumberOfCars) { if (!String.IsNullOrEmpty(b) && !Path.ContainsInvalidChars(b)) { string File = OpenBveApi.Path.CombineFile(System.IO.Path.GetDirectoryName(FileName), b); if (System.IO.File.Exists(File)) { CarInfos[n].Object = b; } } } } } } i++; } i--; break; default: if (Lines[i].StartsWith("[car", StringComparison.OrdinalIgnoreCase) & Lines[i].EndsWith("]", StringComparison.Ordinal)) { // car string t = Lines[i].Substring(4, Lines[i].Length - 5); int n; if (int.TryParse(t, System.Globalization.NumberStyles.Integer, Culture, out n)) { if (n >= 0 & n < ConvertTrainDat.NumberOfCars) { i++; while (i < Lines.Length && !Lines[i].StartsWith("[", StringComparison.Ordinal) & !Lines[i].EndsWith("]", StringComparison.Ordinal)) { if (Lines[i].Length != 0) { int j = Lines[i].IndexOf("=", StringComparison.Ordinal); if (j >= 0) { string a = Lines[i].Substring(0, j).TrimEnd(); string b = Lines[i].Substring(j + 1).TrimStart(); switch (a.ToLowerInvariant()) { case "object": if (!String.IsNullOrEmpty(b) && !Path.ContainsInvalidChars(b)) { string File = OpenBveApi.Path.CombineFile(System.IO.Path.GetDirectoryName(FileName), b); if (System.IO.File.Exists(File)) { CarInfos[n].Object = b; } } break; case "length": { double m; if (double.TryParse(b, System.Globalization.NumberStyles.Float, Culture, out m)) { if (m > 0.0) { CarInfos[n].Length = m; } } } break; case "axles": int k = b.IndexOf(','); if (k >= 0) { string c = b.Substring(0, k).TrimEnd(); string d = b.Substring(k + 1).TrimStart(); double rear, front; if (double.TryParse(c, System.Globalization.NumberStyles.Float, Culture, out rear) && double.TryParse(d, System.Globalization.NumberStyles.Float, Culture, out front)) { CarInfos[n].RearAxle = rear; CarInfos[n].FrontAxle = front; CarInfos[n].AxlesDefined = true; } } break; case "reversed": CarInfos[n].Reversed = b.Equals("true", StringComparison.OrdinalIgnoreCase); break; } } } i++; } i--; } } } /* * else if (Lines[i].StartsWith("[coupler", StringComparison.OrdinalIgnoreCase) & Lines[i].EndsWith("]", StringComparison.Ordinal)) * { * // coupler * string t = Lines[i].Substring(8, Lines[i].Length - 9); * int n; if (int.TryParse(t, System.Globalization.NumberStyles.Integer, Culture, out n)) * { * if (n >= 0 & n < Train.Couplers.Length) * { * i++; while (i < Lines.Length && !Lines[i].StartsWith("[", StringComparison.Ordinal) & !Lines[i].EndsWith("]", StringComparison.Ordinal)) * { * if (Lines[i].Length != 0) * { * int j = Lines[i].IndexOf("=", StringComparison.Ordinal); * if (j >= 0) * { * string a = Lines[i].Substring(0, j).TrimEnd(); * string b = Lines[i].Substring(j + 1).TrimStart(); * switch (a.ToLowerInvariant()) * { * case "distances": * { * int k = b.IndexOf(','); * if (k >= 0) * { * string c = b.Substring(0, k).TrimEnd(); * string d = b.Substring(k + 1).TrimStart(); * double min, max; * if (!double.TryParse(c, System.Globalization.NumberStyles.Float, Culture, out min)) * { * Interface.AddMessage(Interface.MessageType.Error, false, "Minimum is expected to be a floating-point number in " + a + " at line " + (i + 1).ToString(Culture) + " in file " + FileName); * } * else if (!double.TryParse(d, System.Globalization.NumberStyles.Float, Culture, out max)) * { * Interface.AddMessage(Interface.MessageType.Error, false, "Maximum is expected to be a floating-point number in " + a + " at line " + (i + 1).ToString(Culture) + " in file " + FileName); * } * else if (min > max) * { * Interface.AddMessage(Interface.MessageType.Error, false, "Minimum is expected to be less than Maximum in " + a + " at line " + (i + 1).ToString(Culture) + " in file " + FileName); * } * else * { * Train.Couplers[n].MinimumDistanceBetweenCars = min; * Train.Couplers[n].MaximumDistanceBetweenCars = max; * } * } * else * { * Interface.AddMessage(Interface.MessageType.Error, false, "An argument-separating comma is expected in " + a + " at line " + (i + 1).ToString(Culture) + " in file " + FileName); * } * } * break; * default: * Interface.AddMessage(Interface.MessageType.Warning, false, "Unsupported key-value pair " + a + " encountered at line " + (i + 1).ToString(Culture) + " in file " + FileName); * break; * } * } * else * { * Interface.AddMessage(Interface.MessageType.Error, false, "Invalid statement " + Lines[i] + " encountered at line " + (i + 1).ToString(Culture) + " in file " + FileName); * } * } * i++; * } * i--; * } * else * { * Interface.AddMessage(Interface.MessageType.Error, false, "The coupler index " + t + " does not reference an existing coupler at line " + (i + 1).ToString(Culture) + " in file " + FileName); * } * } * else * { * Interface.AddMessage(Interface.MessageType.Error, false, "The coupler index is expected to be an integer at line " + (i + 1).ToString(Culture) + " in file " + FileName); * } * } */ else if (Lines[i].StartsWith("[bogie", StringComparison.OrdinalIgnoreCase) & Lines[i].EndsWith("]", StringComparison.Ordinal)) { // car string t = Lines[i].Substring(6, Lines[i].Length - 7); int n; if (int.TryParse(t, System.Globalization.NumberStyles.Integer, Culture, out n)) { //Assuming that there are two bogies per car bool IsOdd = (n % 2 != 0); int CarIndex = n / 2; if (n >= 0 & n < ConvertTrainDat.NumberOfCars * 2) { bool DefinedAxles = false; i++; while (i < Lines.Length && !Lines[i].StartsWith("[", StringComparison.Ordinal) & !Lines[i].EndsWith("]", StringComparison.Ordinal)) { if (Lines[i].Length != 0) { int j = Lines[i].IndexOf("=", StringComparison.Ordinal); if (j >= 0) { string a = Lines[i].Substring(0, j).TrimEnd(); string b = Lines[i].Substring(j + 1).TrimStart(); switch (a.ToLowerInvariant()) { case "object": if (!String.IsNullOrEmpty(b) && !Path.ContainsInvalidChars(b)) { string File = OpenBveApi.Path.CombineFile(System.IO.Path.GetDirectoryName(FileName), b); if (System.IO.File.Exists(File)) { if (IsOdd) { CarInfos[CarIndex].FrontBogie.Object = b; } else { CarInfos[CarIndex].RearBogie.Object = b; } } } break; case "axles": int k = b.IndexOf(','); if (k >= 0) { string c = b.Substring(0, k).TrimEnd(); string d = b.Substring(k + 1).TrimStart(); double rear, front; if (double.TryParse(c, System.Globalization.NumberStyles.Float, Culture, out rear) && double.TryParse(d, System.Globalization.NumberStyles.Float, Culture, out front)) { if (IsOdd) { CarInfos[CarIndex].FrontBogie.RearAxle = rear; CarInfos[CarIndex].FrontBogie.FrontAxle = front; CarInfos[CarIndex].FrontBogie.AxlesDefined = true; } else { CarInfos[CarIndex].RearBogie.RearAxle = rear; CarInfos[CarIndex].RearBogie.FrontAxle = front; CarInfos[CarIndex].RearBogie.AxlesDefined = true; } } } break; case "reversed": if (IsOdd) { CarInfos[n].FrontBogie.Reversed = b.Equals("true", StringComparison.OrdinalIgnoreCase); } else { CarInfos[n].RearBogie.Reversed = b.Equals("true", StringComparison.OrdinalIgnoreCase); } break; } } } i++; } i--; } } } break; } } } }
internal static void Process() { if (!System.IO.File.Exists(FileName)) { MessageBox.Show("The selected folder does not contain a valid sound.cfg \r\n Please retry.", "CarXML Convertor", MessageBoxButtons.OK, MessageBoxIcon.Information); } if (System.IO.File.Exists(Path.CombineFile(System.IO.Path.GetDirectoryName(FileName), "sound.xml"))) { if (MessageBox.Show("The selected folder already contains a sound.xml file. \r\n Do you wish to continue?", "CarXML Convertor", MessageBoxButtons.OKCancel, MessageBoxIcon.Information) == DialogResult.Cancel) { return; } } panel = new Vector3(DriverPosition.X, DriverPosition.Y, DriverPosition.Z + 1.0); string[] Lines = System.IO.File.ReadAllLines(FileName); List <string> newLines = new List <string>(); for (int i = 0; i < Lines.Length; i++) { int j = Lines[i].IndexOf(';'); if (j >= 0) { Lines[i] = Lines[i].Substring(0, j).Trim(); } else { Lines[i] = Lines[i].Trim(); } } if (Lines.Length < 1 || string.Compare(Lines[0], "version 1.0", StringComparison.OrdinalIgnoreCase) != 0) { MessageBox.Show("Invalid sound.cfg format declaration."); return; } newLines.Add("<?xml version=\"1.0\" encoding=\"utf-8\"?>"); newLines.Add("<openBVE xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\">"); newLines.Add("<CarSounds>"); for (int i = 0; i < Lines.Length; i++) { switch (Lines[i].ToLowerInvariant()) { case "[run]": newLines.Add("<Run>"); i++; while (i < Lines.Length && !Lines[i].StartsWith("[", StringComparison.Ordinal)) { int j = Lines[i].IndexOf("=", StringComparison.Ordinal); if (j >= 0) { string a = Lines[i].Substring(0, j).TrimEnd(); string b = Lines[i].Substring(j + 1).TrimStart(); int k; if (!int.TryParse(a, System.Globalization.NumberStyles.Integer, CultureInfo.InvariantCulture, out k)) { continue; } if (b.Length == 0 || Path.ContainsInvalidChars(b)) { continue; } if (k >= 0) { newLines.Add("<Sound>"); newLines.Add("<Index>" + k + "</Index>"); newLines.Add("<FileName>" + b + "</FileName>"); newLines.Add("<Position>0,0,0</Position>"); newLines.Add("<Radius>10.0</Radius>"); newLines.Add("</Sound>"); } } i++; } i--; newLines.Add("</Run>"); break; case "[motor]": newLines.Add("<Motor>"); i++; while (i < Lines.Length && !Lines[i].StartsWith("[", StringComparison.Ordinal)) { int j = Lines[i].IndexOf("=", StringComparison.Ordinal); if (j >= 0) { string a = Lines[i].Substring(0, j).TrimEnd(); string b = Lines[i].Substring(j + 1).TrimStart(); int k; if (!int.TryParse(a, System.Globalization.NumberStyles.Integer, CultureInfo.InvariantCulture, out k)) { continue; } if (b.Length == 0 || Path.ContainsInvalidChars(b)) { continue; } if (k >= 0) { newLines.Add("<Sound>"); newLines.Add("<Index>" + k + "</Index>"); newLines.Add("<FileName>" + b + "</FileName>"); newLines.Add("<Position>0,0,0</Position>"); newLines.Add("<Radius>10.0</Radius>"); newLines.Add("</Sound>"); } } i++; } i--; newLines.Add("</Motor>"); break; case "[ats]": newLines.Add("<ATS>"); i++; while (i < Lines.Length && !Lines[i].StartsWith("[", StringComparison.Ordinal)) { int j = Lines[i].IndexOf("=", StringComparison.Ordinal); if (j >= 0) { string a = Lines[i].Substring(0, j).TrimEnd(); string b = Lines[i].Substring(j + 1).TrimStart(); int k; if (!int.TryParse(a, System.Globalization.NumberStyles.Integer, CultureInfo.InvariantCulture, out k)) { continue; } if (b.Length == 0 || Path.ContainsInvalidChars(b)) { continue; } if (k >= 0) { newLines.Add("<Sound>"); newLines.Add("<Index>" + k + "</Index>"); newLines.Add("<FileName>" + b + "</FileName>"); newLines.Add("<Position>0,0,0</Position>"); newLines.Add("<Radius>10.0</Radius>"); newLines.Add("</Sound>"); } } i++; } i--; newLines.Add("</ATS>"); break; case "[switch]": newLines.Add("<Switch>"); i++; while (i < Lines.Length && !Lines[i].StartsWith("[", StringComparison.Ordinal)) { int j = Lines[i].IndexOf("=", StringComparison.Ordinal); if (j >= 0) { string a = Lines[i].Substring(0, j).TrimEnd(); string b = Lines[i].Substring(j + 1).TrimStart(); int k; if (!int.TryParse(a, System.Globalization.NumberStyles.Integer, CultureInfo.InvariantCulture, out k)) { continue; } if (b.Length == 0 || Path.ContainsInvalidChars(b)) { continue; } if (k >= 0) { newLines.Add("<Sound>"); newLines.Add("<Index>" + k + "</Index>"); newLines.Add("<FileName>" + b + "</FileName>"); newLines.Add("<Position>0,0,0</Position>"); newLines.Add("<Radius>10.0</Radius>"); newLines.Add("</Sound>"); } } i++; } i--; newLines.Add("</Switch>"); break; case "[brake]": newLines.Add("<Brake>"); i++; while (i < Lines.Length && !Lines[i].StartsWith("[", StringComparison.Ordinal)) { int j = Lines[i].IndexOf("=", StringComparison.Ordinal); if (j >= 0) { string a = Lines[i].Substring(0, j).TrimEnd(); string b = Lines[i].Substring(j + 1).TrimStart(); if (b.Length == 0 || Path.ContainsInvalidChars(b)) { continue; } switch (a.ToLowerInvariant()) { case "bc release high": newLines.Add("<ReleaseHigh>"); newLines.Add("<FileName>" + b + "</FileName>"); newLines.Add("<Position>0,0,0</Position>"); newLines.Add("<Radius>5.0</Radius>"); newLines.Add("</ReleaseHigh>"); break; case "bc release": newLines.Add("<Release>"); newLines.Add("<FileName>" + b + "</FileName>"); newLines.Add("<Position>0,0,0</Position>"); newLines.Add("<Radius>5.0</Radius>"); newLines.Add("</Release>"); break; case "bc release full": newLines.Add("<ReleaseFull>"); newLines.Add("<FileName>" + b + "</FileName>"); newLines.Add("<Position>0,0,0</Position>"); newLines.Add("<Radius>5.0</Radius>"); newLines.Add("</ReleaseFull>"); break; case "emergency": newLines.Add("<Emergency>"); newLines.Add("<FileName>" + b + "</FileName>"); newLines.Add("<Position>0,0,0</Position>"); newLines.Add("<Radius>5.0</Radius>"); newLines.Add("</Emergency>"); break; case "bp decomp": newLines.Add("<Application>"); newLines.Add("<FileName>" + b + "</FileName>"); newLines.Add("<Position>0,0,0</Position>"); newLines.Add("<Radius>5.0</Radius>"); newLines.Add("</Application>"); break; } } i++; } i--; newLines.Add("</Brake>"); break; case "[compressor]": newLines.Add("<Compressor>"); i++; while (i < Lines.Length && !Lines[i].StartsWith("[", StringComparison.Ordinal)) { int j = Lines[i].IndexOf("=", StringComparison.Ordinal); if (j >= 0) { string a = Lines[i].Substring(0, j).TrimEnd(); string b = Lines[i].Substring(j + 1).TrimStart(); if (b.Length == 0 || Path.ContainsInvalidChars(b)) { continue; } switch (a.ToLowerInvariant()) { case "attack": newLines.Add("<Start>"); newLines.Add("<FileName>" + b + "</FileName>"); newLines.Add("<Position>0,0,0</Position>"); newLines.Add("<Radius>10.0</Radius>"); newLines.Add("</Start>"); break; case "loop": newLines.Add("<Loop>"); newLines.Add("<FileName>" + b + "</FileName>"); newLines.Add("<Position>0,0,0</Position>"); newLines.Add("<Radius>10.0</Radius>"); newLines.Add("</Loop>"); break; case "release": newLines.Add("<End>"); newLines.Add("<FileName>" + b + "</FileName>"); newLines.Add("<Position>0,0,0</Position>"); newLines.Add("<Radius>10.0</Radius>"); newLines.Add("</End>"); break; } } i++; } i--; newLines.Add("</Compressor>"); break; case "[suspension]": newLines.Add("<Suspension>"); i++; while (i < Lines.Length && !Lines[i].StartsWith("[", StringComparison.Ordinal)) { int j = Lines[i].IndexOf("=", StringComparison.Ordinal); if (j >= 0) { string a = Lines[i].Substring(0, j).TrimEnd(); string b = Lines[i].Substring(j + 1).TrimStart(); if (b.Length == 0 || Path.ContainsInvalidChars(b)) { continue; } switch (a.ToLowerInvariant()) { case "left": newLines.Add("<Left>"); newLines.Add("<FileName>" + b + "</FileName>"); newLines.Add("<Position>0,0,0</Position>"); newLines.Add("<Radius>5.0</Radius>"); newLines.Add("</Left>"); break; case "right": newLines.Add("<Right>"); newLines.Add("<FileName>" + b + "</FileName>"); newLines.Add("<Position>0,0,0</Position>"); newLines.Add("<Radius>5.0</Radius>"); newLines.Add("</Right>"); break; } } i++; } i--; newLines.Add("</Suspension>"); break; case "[horn]": newLines.Add("<Horn>"); i++; List <string> primary = new List <string>(); List <string> secondary = new List <string>(); List <string> music = new List <string>(); while (i < Lines.Length && !Lines[i].StartsWith("[", StringComparison.Ordinal)) { int j = Lines[i].IndexOf("=", StringComparison.Ordinal); if (j >= 0) { string a = Lines[i].Substring(0, j).TrimEnd(); string b = Lines[i].Substring(j + 1).TrimStart(); if (b.Length == 0 || Path.ContainsInvalidChars(b)) { continue; } switch (a.ToLowerInvariant()) { //PRIMARY HORN (Enter) case "primarystart": primary.Add("<Start>"); primary.Add("<FileName>" + b + "</FileName>"); primary.Add("<Position>" + front + "</Position>"); primary.Add("<Radius>5.0</Radius>"); primary.Add("</Start>"); break; case "primaryend": case "primaryrelease": primary.Add("<End>"); primary.Add("<FileName>" + b + "</FileName>"); primary.Add("<Position>" + front + "</Position>"); primary.Add("<Radius>5.0</Radius>"); primary.Add("</End>"); break; case "primaryloop": case "primary": primary.Add("<Loop>"); primary.Add("<FileName>" + b + "</FileName>"); primary.Add("<Position>" + front + "</Position>"); primary.Add("<Radius>5.0</Radius>"); primary.Add("</Loop>"); break; //SECONDARY HORN (Numpad Enter) case "secondarystart": secondary.Add("<Start>"); secondary.Add("<FileName>" + b + "</FileName>"); secondary.Add("<Position>" + front + "</Position>"); secondary.Add("<Radius>5.0</Radius>"); secondary.Add("</Start>"); break; case "secondaryend": case "secondaryrelease": secondary.Add("<End>"); secondary.Add("<FileName>" + b + "</FileName>"); secondary.Add("<Position>" + front + "</Position>"); secondary.Add("<Radius>5.0</Radius>"); secondary.Add("</End>"); break; case "secondaryloop": case "secondary": secondary.Add("<Loop>"); secondary.Add("<FileName>" + b + "</FileName>"); secondary.Add("<Position>" + front + "</Position>"); secondary.Add("<Radius>5.0</Radius>"); secondary.Add("</Loop>"); break; //MUSIC HORN case "musicstart": music.Add("<Start>"); music.Add("<FileName>" + b + "</FileName>"); music.Add("<Position>" + front + "</Position>"); music.Add("<Radius>5.0</Radius>"); music.Add("</Start>"); break; case "musicend": case "musicrelease": music.Add("<End>"); music.Add("<FileName>" + b + "</FileName>"); music.Add("<Position>" + front + "</Position>"); music.Add("<Radius>5.0</Radius>"); music.Add("</End>"); break; case "musicloop": case "music": music.Add("<Loop>"); music.Add("<FileName>" + b + "</FileName>"); music.Add("<Position>" + front + "</Position>"); music.Add("<Radius>5.0</Radius>"); music.Add("</Loop>"); break; } } i++; } i--; if (primary.Count != 0) { newLines.Add("<Primary>"); newLines.AddRange(primary); newLines.Add("</Primary>"); } if (secondary.Count != 0) { newLines.Add("<Secondary>"); newLines.AddRange(secondary); newLines.Add("</Secondary>"); } if (music.Count != 0) { newLines.Add("<Music>"); newLines.AddRange(music); newLines.Add("<Toggle>true</Toggle>"); newLines.Add("</Music>"); } newLines.Add("</Horn>"); break; case "[door]": newLines.Add("<Door>"); i++; while (i < Lines.Length && !Lines[i].StartsWith("[", StringComparison.Ordinal)) { int j = Lines[i].IndexOf("=", StringComparison.Ordinal); if (j >= 0) { string a = Lines[i].Substring(0, j).TrimEnd(); string b = Lines[i].Substring(j + 1).TrimStart(); if (b.Length == 0 || Path.ContainsInvalidChars(b)) { continue; } else { switch (a.ToLowerInvariant()) { case "open left": newLines.Add("<OpenLeft>"); newLines.Add("<FileName>" + b + "</FileName>"); newLines.Add("<Position>-1.3,0,0</Position>"); newLines.Add("<Radius>5.0</Radius>"); newLines.Add("</OpenLeft>"); break; case "open right": newLines.Add("<OpenRight>"); newLines.Add("<FileName>" + b + "</FileName>"); newLines.Add("<Position>1.3,0,0</Position>"); newLines.Add("<Radius>5.0</Radius>"); newLines.Add("</OpenRight>"); break; case "close left": newLines.Add("<CloseLeft>"); newLines.Add("<FileName>" + b + "</FileName>"); newLines.Add("<Position>-1.3,0,0</Position>"); newLines.Add("<Radius>5.0</Radius>"); newLines.Add("</CloseLeft>"); break; case "close right": newLines.Add("<CloseRight>"); newLines.Add("<FileName>" + b + "</FileName>"); newLines.Add("<Position>1.3,0,0</Position>"); newLines.Add("<Radius>5.0</Radius>"); newLines.Add("</CloseRight>"); break; } } } i++; } i--; newLines.Add("</Door>"); break; case "[buzzer]": i++; while (i < Lines.Length && !Lines[i].StartsWith("[", StringComparison.Ordinal)) { int j = Lines[i].IndexOf("=", StringComparison.Ordinal); if (j >= 0) { string a = Lines[i].Substring(0, j).TrimEnd(); string b = Lines[i].Substring(j + 1).TrimStart(); if (b.Length == 0 || Path.ContainsInvalidChars(b)) { continue; } switch (a.ToLowerInvariant()) { case "correct": newLines.Add("<Buzzer>"); newLines.Add("<FileName>" + b + "</FileName>"); newLines.Add("<Position>" + panel + "</Position>"); newLines.Add("<Radius>2.0</Radius>"); newLines.Add("</Buzzer>"); break; } } i++; } i--; break; case "[pilot lamp]": newLines.Add("<PilotLamp>"); i++; while (i < Lines.Length && !Lines[i].StartsWith("[", StringComparison.Ordinal)) { int j = Lines[i].IndexOf("=", StringComparison.Ordinal); if (j >= 0) { string a = Lines[i].Substring(0, j).TrimEnd(); string b = Lines[i].Substring(j + 1).TrimStart(); if (b.Length == 0 || Path.ContainsInvalidChars(b)) { continue; } switch (a.ToLowerInvariant()) { case "on": newLines.Add("<On>"); newLines.Add("<FileName>" + b + "</FileName>"); newLines.Add("<Position>" + panel + "</Position>"); newLines.Add("<Radius>2.0</Radius>"); newLines.Add("</On>"); break; case "off": newLines.Add("<Off>"); newLines.Add("<FileName>" + b + "</FileName>"); newLines.Add("<Position>" + panel + "</Position>"); newLines.Add("<Radius>2.0</Radius>"); newLines.Add("</Off>"); break; } } i++; } i--; newLines.Add("</PilotLamp>"); break; case "[brake handle]": newLines.Add("<BrakeHandle>"); i++; while (i < Lines.Length && !Lines[i].StartsWith("[", StringComparison.Ordinal)) { int j = Lines[i].IndexOf("=", StringComparison.Ordinal); if (j >= 0) { string a = Lines[i].Substring(0, j).TrimEnd(); string b = Lines[i].Substring(j + 1).TrimStart(); if (b.Length == 0 || Path.ContainsInvalidChars(b)) { continue; } switch (a.ToLowerInvariant()) { case "apply": newLines.Add("<Apply>"); newLines.Add("<FileName>" + b + "</FileName>"); newLines.Add("<Position>" + panel + "</Position>"); newLines.Add("<Radius>2.0</Radius>"); newLines.Add("</Apply>"); break; case "release": newLines.Add("<Release>"); newLines.Add("<FileName>" + b + "</FileName>"); newLines.Add("<Position>" + panel + "</Position>"); newLines.Add("<Radius>2.0</Radius>"); newLines.Add("</Release>"); break; case "min": newLines.Add("<Minimum>"); newLines.Add("<FileName>" + b + "</FileName>"); newLines.Add("<Position>" + panel + "</Position>"); newLines.Add("<Radius>2.0</Radius>"); newLines.Add("</Minimum>"); break; case "max": newLines.Add("<Maximum>"); newLines.Add("<FileName>" + b + "</FileName>"); newLines.Add("<Position>" + panel + "</Position>"); newLines.Add("<Radius>2.0</Radius>"); newLines.Add("</Maximum>"); break; } } i++; } i--; newLines.Add("</BrakeHandle>"); break; case "[master controller]": newLines.Add("<PowerHandle>"); i++; while (i < Lines.Length && !Lines[i].StartsWith("[", StringComparison.Ordinal)) { int j = Lines[i].IndexOf("=", StringComparison.Ordinal); if (j >= 0) { string a = Lines[i].Substring(0, j).TrimEnd(); string b = Lines[i].Substring(j + 1).TrimStart(); if (b.Length == 0 || Path.ContainsInvalidChars(b)) { continue; } else { switch (a.ToLowerInvariant()) { case "up": newLines.Add("<Increase>"); newLines.Add("<FileName>" + b + "</FileName>"); newLines.Add("<Position>" + panel + "</Position>"); newLines.Add("<Radius>2.0</Radius>"); newLines.Add("</Increase>"); break; case "down": newLines.Add("<Decrease>"); newLines.Add("<FileName>" + b + "</FileName>"); newLines.Add("<Position>" + panel + "</Position>"); newLines.Add("<Radius>2.0</Radius>"); newLines.Add("</Decrease>"); break; case "min": newLines.Add("<Minimum>"); newLines.Add("<FileName>" + b + "</FileName>"); newLines.Add("<Position>" + panel + "</Position>"); newLines.Add("<Radius>2.0</Radius>"); newLines.Add("</Minimum>"); break; case "max": newLines.Add("<Maximum>"); newLines.Add("<FileName>" + b + "</FileName>"); newLines.Add("<Position>" + panel + "</Position>"); newLines.Add("<Radius>2.0</Radius>"); newLines.Add("</Maximum>"); break; } } } i++; } i--; newLines.Add("</PowerHandle>"); break; case "[reverser]": newLines.Add("<Reverser>"); i++; while (i < Lines.Length && !Lines[i].StartsWith("[", StringComparison.Ordinal)) { int j = Lines[i].IndexOf("=", StringComparison.Ordinal); if (j >= 0) { string a = Lines[i].Substring(0, j).TrimEnd(); string b = Lines[i].Substring(j + 1).TrimStart(); if (b.Length == 0 || Path.ContainsInvalidChars(b)) { continue; } switch (a.ToLowerInvariant()) { case "on": newLines.Add("<On>"); newLines.Add("<FileName>" + b + "</FileName>"); newLines.Add("<Position>" + panel + "</Position>"); newLines.Add("<Radius>2.0</Radius>"); newLines.Add("</On>"); break; case "off": newLines.Add("<Off>"); newLines.Add("<FileName>" + b + "</FileName>"); newLines.Add("<Position>" + panel + "</Position>"); newLines.Add("<Radius>2.0</Radius>"); newLines.Add("</Off>"); break; } } i++; } i--; newLines.Add("</Reverser>"); break; case "[breaker]": newLines.Add("<Breaker>"); i++; while (i < Lines.Length && !Lines[i].StartsWith("[", StringComparison.Ordinal)) { int j = Lines[i].IndexOf("=", StringComparison.Ordinal); if (j >= 0) { string a = Lines[i].Substring(0, j).TrimEnd(); string b = Lines[i].Substring(j + 1).TrimStart(); if (b.Length == 0 || Path.ContainsInvalidChars(b)) { continue; } else { switch (a.ToLowerInvariant()) { case "on": newLines.Add("<On>"); newLines.Add("<FileName>" + b + "</FileName>"); newLines.Add("<Position>" + panel + "</Position>"); newLines.Add("<Radius>5.0</Radius>"); newLines.Add("</On>"); break; case "off": newLines.Add("<Off>"); newLines.Add("<FileName>" + b + "</FileName>"); newLines.Add("<Position>" + panel + "</Position>"); newLines.Add("<Radius>5.0</Radius>"); newLines.Add("</Off>"); break; } } } i++; } i--; newLines.Add("</Breaker>"); break; case "[others]": i++; while (i < Lines.Length && !Lines[i].StartsWith("[", StringComparison.Ordinal)) { int j = Lines[i].IndexOf("=", StringComparison.Ordinal); if (j >= 0) { string a = Lines[i].Substring(0, j).TrimEnd(); string b = Lines[i].Substring(j + 1).TrimStart(); if (b.Length == 0 || Path.ContainsInvalidChars(b)) { continue; } switch (a.ToLowerInvariant()) { case "noise": newLines.Add("<Loop>"); newLines.Add("<FileName>" + b + "</FileName>"); newLines.Add("<Position>0,0,0</Position>"); newLines.Add("<Radius>10.0</Radius>"); newLines.Add("</Loop>"); break; case "shoe": newLines.Add("<Rub>"); newLines.Add("<FileName>" + b + "</FileName>"); newLines.Add("<Position>0,0,0</Position>"); newLines.Add("<Radius>10.0</Radius>"); newLines.Add("</Rub>"); break; } } i++; } i--; break; } } newLines.Add("</CarSounds>"); newLines.Add("</openBVE>"); try { string fileOut = System.IO.Path.Combine(System.IO.Path.GetDirectoryName(FileName), "sound.xml"); using (StreamWriter sw = new StreamWriter(fileOut)) { foreach (String s in newLines) { sw.WriteLine(s); } } } catch { MessageBox.Show("An error occured whilst writing the new XML file. \r\n Please check for write permissions.", "CarXML Convertor", MessageBoxButtons.OK, MessageBoxIcon.Hand); return; } MessageBox.Show("Conversion succeeded.", "CarXML Convertor", MessageBoxButtons.OK, MessageBoxIcon.Information); }
internal static void ReadExtensionsCfg() { string[] Lines = System.IO.File.ReadAllLines(FileName, System.Text.Encoding.Default); for (int i = 0; i < Lines.Length; i++) { int j = Lines[i].IndexOf(';'); if (j >= 0) { Lines[i] = Lines[i].Substring(0, j).Trim(new char[] { }); } else { Lines[i] = Lines[i].Trim(new char[] { }); } } for (int i = 0; i < Lines.Length; i++) { if (Lines[i].Length != 0) { switch (Lines[i].ToLowerInvariant()) { case "[exterior]": // exterior i++; while (i < Lines.Length && !Lines[i].StartsWith("[", StringComparison.Ordinal) & !Lines[i].EndsWith("]", StringComparison.Ordinal)) { if (Lines[i].Length != 0) { int j = Lines[i].IndexOf("=", StringComparison.Ordinal); if (j >= 0) { string a = Lines[i].Substring(0, j).TrimEnd(new char[] { }); string b = Lines[i].Substring(j + 1).TrimStart(new char[] { }); int n; if (int.TryParse(a, System.Globalization.NumberStyles.Integer, Culture, out n)) { if (n >= 0 & n < ConvertTrainDat.NumberOfCars) { if (!String.IsNullOrEmpty(b) && !Path.ContainsInvalidChars(b)) { string File = OpenBveApi.Path.CombineFile(System.IO.Path.GetDirectoryName(FileName), b); if (System.IO.File.Exists(File)) { CarInfos[n].Object = b; } } } } } } i++; } i--; break; default: if (Lines[i].StartsWith("[car", StringComparison.OrdinalIgnoreCase) & Lines[i].EndsWith("]", StringComparison.Ordinal)) { // car string t = Lines[i].Substring(4, Lines[i].Length - 5); int n; if (int.TryParse(t, System.Globalization.NumberStyles.Integer, Culture, out n)) { if (n >= 0 & n < ConvertTrainDat.NumberOfCars) { i++; while (i < Lines.Length && !Lines[i].StartsWith("[", StringComparison.Ordinal) & !Lines[i].EndsWith("]", StringComparison.Ordinal)) { if (Lines[i].Length != 0) { int j = Lines[i].IndexOf("=", StringComparison.Ordinal); if (j >= 0) { string a = Lines[i].Substring(0, j).TrimEnd(new char[] { }); string b = Lines[i].Substring(j + 1).TrimStart(new char[] { }); switch (a.ToLowerInvariant()) { case "object": if (!String.IsNullOrEmpty(b) && !Path.ContainsInvalidChars(b)) { string File = OpenBveApi.Path.CombineFile(System.IO.Path.GetDirectoryName(FileName), b); if (System.IO.File.Exists(File)) { CarInfos[n].Object = b; } } break; case "length": { double m; if (double.TryParse(b, System.Globalization.NumberStyles.Float, Culture, out m)) { if (m > 0.0) { CarInfos[n].Length = m; } } } break; case "axles": int k = b.IndexOf(','); if (k >= 0) { string c = b.Substring(0, k).TrimEnd(new char[] { }); string d = b.Substring(k + 1).TrimStart(new char[] { }); double rear, front; if (double.TryParse(c, System.Globalization.NumberStyles.Float, Culture, out rear) && double.TryParse(d, System.Globalization.NumberStyles.Float, Culture, out front)) { CarInfos[n].RearAxle = rear; CarInfos[n].FrontAxle = front; CarInfos[n].AxlesDefined = true; } } break; case "reversed": CarInfos[n].Reversed = b.Equals("true", StringComparison.OrdinalIgnoreCase); break; case "loadingsway": CarInfos[n].LoadingSway = b.Equals("true", StringComparison.OrdinalIgnoreCase); break; } } } i++; } i--; } } } else if (Lines[i].StartsWith("[coupler", StringComparison.OrdinalIgnoreCase) & Lines[i].EndsWith("]", StringComparison.Ordinal)) { // coupler string t = Lines[i].Substring(8, Lines[i].Length - 9); int n; if (int.TryParse(t, System.Globalization.NumberStyles.Integer, Culture, out n)) { if (n >= 0 & n < Couplers.Length) { i++; while (i < Lines.Length && !Lines[i].StartsWith("[", StringComparison.Ordinal) & !Lines[i].EndsWith("]", StringComparison.Ordinal)) { if (Lines[i].Length != 0) { int j = Lines[i].IndexOf("=", StringComparison.Ordinal); if (j >= 0) { string a = Lines[i].Substring(0, j).TrimEnd(new char[] { }); string b = Lines[i].Substring(j + 1).TrimStart(new char[] { }); switch (a.ToLowerInvariant()) { case "distances": { int k = b.IndexOf(','); if (k >= 0) { string c = b.Substring(0, k).TrimEnd(new char[] { }); string d = b.Substring(k + 1).TrimStart(new char[] { }); double min, max; if (!double.TryParse(c, System.Globalization.NumberStyles.Float, Culture, out min)) { } else if (!double.TryParse(d, System.Globalization.NumberStyles.Float, Culture, out max)) { } else { Couplers[n] = new Coupler { Min = min, Max = max }; } } } break; } } } i++; } i--; } } } else if (Lines[i].StartsWith("[bogie", StringComparison.OrdinalIgnoreCase) & Lines[i].EndsWith("]", StringComparison.Ordinal)) { // car string t = Lines[i].Substring(6, Lines[i].Length - 7); int n; if (int.TryParse(t, System.Globalization.NumberStyles.Integer, Culture, out n)) { //Assuming that there are two bogies per car bool IsOdd = (n % 2 != 0); int CarIndex = n / 2; if (n >= 0 & n < ConvertTrainDat.NumberOfCars * 2) { i++; while (i < Lines.Length && !Lines[i].StartsWith("[", StringComparison.Ordinal) & !Lines[i].EndsWith("]", StringComparison.Ordinal)) { if (Lines[i].Length != 0) { int j = Lines[i].IndexOf("=", StringComparison.Ordinal); if (j >= 0) { string a = Lines[i].Substring(0, j).TrimEnd(new char[] { }); string b = Lines[i].Substring(j + 1).TrimStart(new char[] { }); switch (a.ToLowerInvariant()) { case "object": if (!String.IsNullOrEmpty(b) && !Path.ContainsInvalidChars(b)) { string File = OpenBveApi.Path.CombineFile(System.IO.Path.GetDirectoryName(FileName), b); if (System.IO.File.Exists(File)) { if (IsOdd) { CarInfos[CarIndex].RearBogie.Object = b; } else { CarInfos[CarIndex].FrontBogie.Object = b; } } } break; case "axles": int k = b.IndexOf(','); if (k >= 0) { string c = b.Substring(0, k).TrimEnd(new char[] { }); string d = b.Substring(k + 1).TrimStart(new char[] { }); double rear, front; if (double.TryParse(c, System.Globalization.NumberStyles.Float, Culture, out rear) && double.TryParse(d, System.Globalization.NumberStyles.Float, Culture, out front)) { if (IsOdd) { CarInfos[CarIndex].RearBogie.RearAxle = rear; CarInfos[CarIndex].RearBogie.FrontAxle = front; CarInfos[CarIndex].RearBogie.AxlesDefined = true; } else { CarInfos[CarIndex].FrontBogie.RearAxle = rear; CarInfos[CarIndex].FrontBogie.FrontAxle = front; CarInfos[CarIndex].FrontBogie.AxlesDefined = true; } } } break; case "reversed": if (IsOdd) { CarInfos[CarIndex].FrontBogie.Reversed = b.Equals("true", StringComparison.OrdinalIgnoreCase); } else { CarInfos[CarIndex].RearBogie.Reversed = b.Equals("true", StringComparison.OrdinalIgnoreCase); } break; } } } i++; } i--; } } } break; } } } }
/// <summary>Gets the default train folder for a given route file</summary> /// <returns>The absolute on-disk path of the train folder</returns> internal static string GetDefaultTrainFolder(string RouteFile) { if (string.IsNullOrEmpty(Interface.CurrentOptions.TrainName)) { return(string.Empty); } string Folder; try { Folder = System.IO.Path.GetDirectoryName(RouteFile); if (Interface.CurrentOptions.TrainName[0] == '$') { Folder = Path.CombineDirectory(Folder, Interface.CurrentOptions.TrainName); if (Directory.Exists(Folder)) { string File = Path.CombineFile(Folder, "train.dat"); if (System.IO.File.Exists(File)) { return(Folder); } } } } catch { Folder = null; } bool recursionTest = false; string lastFolder = null; try { while (true) { string TrainFolder = Path.CombineDirectory(Folder, "Train"); var OldFolder = Folder; if (Directory.Exists(TrainFolder)) { try { Folder = Path.CombineDirectory(TrainFolder, Interface.CurrentOptions.TrainName); } catch (Exception ex) { if (ex is ArgumentException) { break; // Invalid character in path causes infinite recursion } Folder = null; } if (Folder != null) { char c = System.IO.Path.DirectorySeparatorChar; if (Directory.Exists(Folder)) { string File = Path.CombineFile(Folder, "train.dat"); if (System.IO.File.Exists(File)) { // train found return(Folder); } if (lastFolder == Folder || recursionTest) { break; } lastFolder = Folder; } else if (Folder.ToLowerInvariant().Contains(c + "railway" + c)) { //If we have a misplaced Train folder in either our Railway\Route //or Railway folders, this can cause the train search to fail //Detect the presence of a railway folder and carry on traversing upwards if this is the case recursionTest = true; Folder = OldFolder; } else { break; } } } if (Folder == null) { continue; } DirectoryInfo Info = Directory.GetParent(Folder); if (Info != null) { Folder = Info.FullName; } else { break; } } } catch { //Something broke, but we don't care as it just shows an error below } return(string.Empty); }
/// <summary>Loads a list of compatibility signal objects</summary> /// <param name="currentHost">The host application interface</param> /// <param name="fileName">The file name of the object list</param> /// <param name="objects">The returned array of speed limits</param> /// <param name="signalPost">Sets the default signal post</param> /// <param name="speedLimits">The array of signal speed limits</param> /// <returns>An array of compatability signal objects</returns> public static void ReadCompatibilitySignalXML(HostInterface currentHost, string fileName, out CompatibilitySignalObject[] objects, out UnifiedObject signalPost, out double[] speedLimits) { signalPost = new StaticObject(currentHost); objects = new CompatibilitySignalObject[9]; //Default Japanese speed limits converted to m/s speedLimits = new[] { 0.0, 6.94444444444444, 15.2777777777778, 20.8333333333333, double.PositiveInfinity, double.PositiveInfinity }; XmlDocument currentXML = new XmlDocument(); currentXML.Load(fileName); string currentPath = System.IO.Path.GetDirectoryName(fileName); if (currentXML.DocumentElement != null) { XmlNode node = currentXML.SelectSingleNode("/openBVE/CompatibilitySignals/SignalSetName"); if (node != null) { currentHost.AddMessage(MessageType.Information, false, "INFO: Using the " + node.InnerText + " compatibility signal set."); } XmlNodeList DocumentNodes = currentXML.DocumentElement.SelectNodes("/openBVE/CompatibilitySignals/Signal"); if (DocumentNodes != null) { int index = 0; foreach (XmlNode nn in DocumentNodes) { List <StaticObject> objectList = new List <StaticObject>(); List <int> aspectList = new List <int>(); try { if (nn.HasChildNodes) { foreach (XmlNode n in nn.ChildNodes) { if (n.Name != "Aspect") { continue; } int aspect = 0; if (!NumberFormats.TryParseIntVb6(n.Attributes["Number"].Value, out aspect)) { currentHost.AddMessage(MessageType.Error, true, "Invalid aspect number " + aspect + " in the signal object list in the compatability signal file " + fileName); continue; } aspectList.Add(aspect); StaticObject staticObject = new StaticObject(currentHost); if (n.InnerText.ToLowerInvariant() != "null") { string objectFile = Path.CombineFile(currentPath, n.InnerText); if (File.Exists(objectFile)) { currentHost.LoadStaticObject(objectFile, Encoding.UTF8, false, out staticObject); } else { currentHost.AddMessage(MessageType.Error, true, "Compatibility signal file " + objectFile + " not found in " + fileName); } } objectList.Add(staticObject); } } } catch { currentHost.AddMessage(MessageType.Error, true, "An unexpected error was encountered whilst processing the compatability signal file " + fileName); } objects[index] = new CompatibilitySignalObject(aspectList.ToArray(), objectList.ToArray()); index++; } } string signalPostFile = Path.CombineFile(currentPath, "Japanese\\signal_post.csv"); //default plain post try { node = currentXML.SelectSingleNode("/openBVE/CompatibilitySignals/SignalPost"); if (node != null) { string newFile = Path.CombineFile(currentPath, node.InnerText); if (System.IO.File.Exists(newFile)) { signalPostFile = newFile; } } currentHost.LoadObject(signalPostFile, Encoding.UTF8, out signalPost); } catch { currentHost.AddMessage(MessageType.Error, true, "An unexpected error was encountered whilst processing the compatability signal file " + fileName); } DocumentNodes = currentXML.DocumentElement.SelectNodes("/openBVE/CompatibilitySignals/SpeedLimits"); if (DocumentNodes != null) { foreach (XmlNode nn in DocumentNodes) { try { if (nn.HasChildNodes) { foreach (XmlNode n in nn.ChildNodes) { if (n.Name != "Aspect") { continue; } int aspect = 0; if (n.Attributes != null) { if (!NumberFormats.TryParseIntVb6(n.Attributes["Number"].Value, out aspect)) { currentHost.AddMessage(MessageType.Error, true, "Invalid aspect number " + aspect + " in the speed limit list in the compatability signal file " + fileName); continue; } } if (aspect <= speedLimits.Length) { int l = speedLimits.Length; Array.Resize(ref speedLimits, aspect + 1); for (int i = l; i < speedLimits.Length; i++) { speedLimits[i] = double.PositiveInfinity; } if (!NumberFormats.TryParseDoubleVb6(n.InnerText, out speedLimits[aspect])) { speedLimits[aspect] = double.MaxValue; if (n.InnerText.ToLowerInvariant() != "unlimited") { currentHost.AddMessage(MessageType.Error, true, "Invalid speed limit provided for aspect " + aspect + " in the compatability signal file " + fileName); } } else { //convert to m/s as that's what we use internally speedLimits[aspect] *= 0.277777777777778; } } } } } catch { currentHost.AddMessage(MessageType.Error, true, "An unexpected error was encountered whilst processing the compatability signal file " + fileName); } } } } }
/******************** * MENU C'TOR *********************/ public SingleMenu(MenuType menuType, int data = 0, double maxWidth = 0) { MaxWidth = maxWidth; Type = menuType; int i, menuItem; int jump = 0; Vector2 size; Align = TextAlignment.TopMiddle; Height = Width = 0; Selection = 0; // defaults to first menu item switch (menuType) { case MenuType.GameStart: // top level menu if (routeWorkerThread == null) { //Create the worker threads on first launch of main menu routeWorkerThread = new BackgroundWorker(); routeWorkerThread.DoWork += routeWorkerThread_doWork; routeWorkerThread.RunWorkerCompleted += routeWorkerThread_completed; packageWorkerThread = new BackgroundWorker(); packageWorkerThread.DoWork += packageWorkerThread_doWork; packageWorkerThread.RunWorkerCompleted += packageWorkerThread_completed; Manipulation.ProgressChanged += OnWorkerProgressChanged; Manipulation.ProblemReport += OnWorkerReportsProblem; Manipulation.OperationCompleted += OnPackageOperationCompleted; //Load texture Program.CurrentHost.RegisterTexture(Path.CombineFile(Program.FileSystem.DataFolder, "Menu\\loading.png"), new TextureParameters(null, null), out routePictureBox.Texture); } Items = new MenuEntry[5]; Items[0] = new MenuCommand("Open Route File", MenuTag.RouteList, 0); if (!Interface.CurrentOptions.KioskMode) { //Don't allow quitting or customisation of the controls in kiosk mode Items[1] = new MenuCommand(Translations.GetInterfaceString("options"), MenuTag.Options, 0); Items[2] = new MenuCommand(Translations.GetInterfaceString("menu_customize_controls"), MenuTag.MenuControls, 0); Items[3] = new MenuCommand(Translations.GetInterfaceString("packages_title"), MenuTag.Packages, 0); Items[4] = new MenuCommand(Translations.GetInterfaceString("menu_quit"), MenuTag.MenuQuit, 0); } else { Array.Resize(ref Items, Items.Length - 3); } SearchDirectory = Program.FileSystem.InitialRouteFolder; Align = TextAlignment.TopLeft; break; case MenuType.Packages: Items = new MenuEntry[4]; Items[0] = new MenuCaption(Translations.GetInterfaceString("packages_title")); Items[1] = new MenuCommand(Translations.GetInterfaceString("packages_install_header"), MenuTag.PackageInstall, 0); Items[2] = new MenuCommand(Translations.GetInterfaceString("packages_uninstall_button"), MenuTag.PackageUninstall, 0); Items[3] = new MenuCommand(Translations.GetInterfaceString("packages_button_cancel"), MenuTag.MenuBack, 0); Align = TextAlignment.TopLeft; break; case MenuType.PackageUninstall: routeDescriptionBox.Text = string.Empty; Items = new MenuEntry[5]; Items[0] = new MenuCaption(Translations.GetInterfaceString("packages_list_type")); Items[1] = new MenuCommand(Translations.GetInterfaceString("packages_type_route"), MenuTag.UninstallRoute, 0); Items[2] = new MenuCommand(Translations.GetInterfaceString("packages_type_train"), MenuTag.UninstallTrain, 0); Items[3] = new MenuCommand(Translations.GetInterfaceString("packages_type_other"), MenuTag.UninstallOther, 0); Items[4] = new MenuCommand(Translations.GetInterfaceString("packages_button_cancel"), MenuTag.MenuBack, 0); Align = TextAlignment.TopLeft; break; case MenuType.UninstallRoute: Items = new MenuEntry[Database.currentDatabase.InstalledRoutes.Count + 1]; Items[0] = new MenuCaption(Translations.GetInterfaceString("packages_list")); for (int j = 0; j < Database.currentDatabase.InstalledRoutes.Count; j++) { Items[j + 1] = new MenuCommand(Database.currentDatabase.InstalledRoutes[j].Name, MenuTag.Package, Database.currentDatabase.InstalledRoutes[j]); } Align = TextAlignment.TopLeft; break; case MenuType.UninstallTrain: Items = new MenuEntry[Database.currentDatabase.InstalledTrains.Count + 1]; Items[0] = new MenuCaption(Translations.GetInterfaceString("packages_list")); for (int j = 0; j < Database.currentDatabase.InstalledTrains.Count; j++) { Items[j + 1] = new MenuCommand(Database.currentDatabase.InstalledTrains[j].Name, MenuTag.Package, Database.currentDatabase.InstalledTrains[j]); } Align = TextAlignment.TopLeft; break; case MenuType.UninstallOther: Items = new MenuEntry[Database.currentDatabase.InstalledOther.Count + 1]; Items[0] = new MenuCaption(Translations.GetInterfaceString("packages_list")); for (int j = 0; j < Database.currentDatabase.InstalledOther.Count; j++) { Items[j + 1] = new MenuCommand(Database.currentDatabase.InstalledOther[j].Name, MenuTag.Package, Database.currentDatabase.InstalledOther[j]); } Align = TextAlignment.TopLeft; break; case MenuType.PackageInstall: string[] potentialFiles = { }; string[] directoryList = { }; bool drives = false; if (SearchDirectory != string.Empty) { try { potentialFiles = Directory.GetFiles(SearchDirectory); directoryList = Directory.GetDirectories(SearchDirectory); } catch { // Ignored } } else { DriveInfo[] systemDrives = DriveInfo.GetDrives(); directoryList = new string[systemDrives.Length]; for (int k = 0; k < systemDrives.Length; k++) { directoryList[k] = systemDrives[k].Name; } drives = true; } Items = new MenuEntry[potentialFiles.Length + directoryList.Length + 2]; Items[0] = new MenuCaption(SearchDirectory); Items[1] = new MenuCommand("...", MenuTag.ParentDirectory, 0); int totalEntries = 2; for (int j = 0; j < directoryList.Length; j++) { DirectoryInfo directoryInfo = new DirectoryInfo(directoryList[j]); if (Program.CurrentHost.Platform != HostPlatform.MicrosoftWindows && directoryInfo.Name[0] == '.') { continue; } Items[totalEntries] = new MenuCommand(directoryInfo.Name, MenuTag.Directory, 0); if (drives) { Program.CurrentHost.RegisterTexture(Path.CombineFile(Program.FileSystem.DataFolder, "Menu\\icon_disk.png"), new TextureParameters(null, null), out Items[totalEntries].Icon); } else { Program.CurrentHost.RegisterTexture(Path.CombineFile(Program.FileSystem.DataFolder, "Menu\\icon_folder.png"), new TextureParameters(null, null), out Items[totalEntries].Icon); } totalEntries++; } for (int j = 0; j < potentialFiles.Length; j++) { string fileName = System.IO.Path.GetFileName(potentialFiles[j]); if (Program.CurrentHost.Platform != HostPlatform.MicrosoftWindows && fileName[0] == '.') { continue; } Items[totalEntries] = new MenuCommand(fileName, MenuTag.File, 0); string ext = System.IO.Path.GetExtension(fileName); if (!iconCache.ContainsKey(ext)) { // As some people have used arbritary extensions for packages, let's show all files // Try and pull out the default icon from the cache for something a little nicer looking try { Icon icon = Icon.ExtractAssociatedIcon(potentialFiles[j]); if (icon != null) { Texture t; Program.CurrentHost.RegisterTexture(icon.ToBitmap(), new TextureParameters(null, null), out t); iconCache.Add(ext, t); Items[totalEntries].Icon = t; } } catch { // Ignored } } else { Items[totalEntries].Icon = iconCache[ext]; } totalEntries++; } Array.Resize(ref Items, totalEntries); Align = TextAlignment.TopLeft; break; case MenuType.Options: Items = new MenuEntry[8]; Items[0] = new MenuCaption(Translations.GetInterfaceString("panel_options")); Items[1] = new MenuOption(MenuOptionType.ScreenResolution, Translations.GetInterfaceString("options_resolution"), Program.Renderer.Screen.AvailableResolutions.ToArray()); Items[2] = new MenuOption(MenuOptionType.FullScreen, Translations.GetInterfaceString("options_display_mode_fullscreen"), new[] { "true", "false" }); Items[3] = new MenuOption(MenuOptionType.Interpolation, Translations.GetInterfaceString("options_quality_interpolation"), new[] { Translations.GetInterfaceString("options_quality_interpolation_mode_nearest"), Translations.GetInterfaceString("options_quality_interpolation_mode_bilinear"), Translations.GetInterfaceString("options_quality_interpolation_mode_nearestmipmap"), Translations.GetInterfaceString("options_quality_interpolation_mode_bilinearmipmap"), Translations.GetInterfaceString("options_quality_interpolation_mode_trilinearmipmap"), Translations.GetInterfaceString("options_quality_interpolation_mode_anisotropic") }); Items[4] = new MenuOption(MenuOptionType.AnisotropicLevel, Translations.GetInterfaceString("options_quality_interpolation_anisotropic_level"), new[] { "0", "2", "4", "8", "16" }); Items[5] = new MenuOption(MenuOptionType.AntialiasingLevel, Translations.GetInterfaceString("options_quality_interpolation_antialiasing_level"), new[] { "0", "2", "4", "8", "16" }); Items[6] = new MenuOption(MenuOptionType.ViewingDistance, Translations.GetInterfaceString("options_quality_distance_viewingdistance"), new[] { "400", "600", "800", "1000", "1500", "2000" }); Items[7] = new MenuCommand(Translations.GetInterfaceString("menu_back"), MenuTag.MenuBack, 0); Align = TextAlignment.TopLeft; break; case MenuType.RouteList: potentialFiles = new string[] { }; directoryList = new string[] { }; drives = false; if (SearchDirectory != string.Empty) { try { potentialFiles = Directory.GetFiles(SearchDirectory); directoryList = Directory.GetDirectories(SearchDirectory); } catch { // Ignored } } else { DriveInfo[] systemDrives = DriveInfo.GetDrives(); directoryList = new string[systemDrives.Length]; for (int k = 0; k < systemDrives.Length; k++) { directoryList[k] = systemDrives[k].Name; } drives = true; } Items = new MenuEntry[potentialFiles.Length + directoryList.Length + 2]; Items[0] = new MenuCaption(SearchDirectory); Items[1] = new MenuCommand("...", MenuTag.ParentDirectory, 0); totalEntries = 2; for (int j = 0; j < directoryList.Length; j++) { DirectoryInfo directoryInfo = new DirectoryInfo(directoryList[j]); if (Program.CurrentHost.Platform != HostPlatform.MicrosoftWindows && directoryInfo.Name[0] == '.') { continue; } Items[totalEntries] = new MenuCommand(directoryInfo.Name, MenuTag.Directory, 0); if (drives) { Program.CurrentHost.RegisterTexture(Path.CombineFile(Program.FileSystem.DataFolder, "Menu\\icon_disk.png"), new TextureParameters(null, null), out Items[totalEntries].Icon); } else { Program.CurrentHost.RegisterTexture(Path.CombineFile(Program.FileSystem.DataFolder, "Menu\\icon_folder.png"), new TextureParameters(null, null), out Items[totalEntries].Icon); } totalEntries++; } for (int j = 0; j < potentialFiles.Length; j++) { string fileName = System.IO.Path.GetFileName(potentialFiles[j]); if (Program.CurrentHost.Platform != HostPlatform.MicrosoftWindows && fileName[0] == '.') { continue; } if (fileName.ToLowerInvariant().EndsWith(".csv") || fileName.ToLowerInvariant().EndsWith(".rw")) { Items[totalEntries] = new MenuCommand(fileName, MenuTag.RouteFile, 0); Program.CurrentHost.RegisterTexture(Path.CombineFile(Program.FileSystem.DataFolder, "Menu\\icon_route.png"), new TextureParameters(null, null), out Items[totalEntries].Icon); totalEntries++; } } Array.Resize(ref Items, totalEntries); Align = TextAlignment.TopLeft; break; case MenuType.TrainList: potentialFiles = new string[] { }; directoryList = new string[] { }; drives = false; if (SearchDirectory != string.Empty) { try { potentialFiles = Directory.GetFiles(SearchDirectory); directoryList = Directory.GetDirectories(SearchDirectory); } catch { // Ignored } } else { DriveInfo[] systemDrives = DriveInfo.GetDrives(); directoryList = new string[systemDrives.Length]; for (int k = 0; k < systemDrives.Length; k++) { directoryList[k] = systemDrives[k].Name; } drives = true; } Items = new MenuEntry[potentialFiles.Length + directoryList.Length + 2]; Items[0] = new MenuCaption(SearchDirectory); Items[1] = new MenuCommand("...", MenuTag.ParentDirectory, 0); totalEntries = 2; for (int j = 0; j < directoryList.Length; j++) { bool isTrain = false; for (int k = 0; k < Program.CurrentHost.Plugins.Length; k++) { if (Program.CurrentHost.Plugins[k].Train != null && Program.CurrentHost.Plugins[k].Train.CanLoadTrain(directoryList[j])) { isTrain = true; break; } } DirectoryInfo directoryInfo = new DirectoryInfo(directoryList[j]); if (Program.CurrentHost.Platform != HostPlatform.MicrosoftWindows && directoryInfo.Name[0] == '.') { continue; } if (!isTrain) { Items[totalEntries] = new MenuCommand(directoryInfo.Name, MenuTag.Directory, 0); if (drives) { Program.CurrentHost.RegisterTexture(Path.CombineFile(Program.FileSystem.DataFolder, "Menu\\icon_disk.png"), new TextureParameters(null, null), out Items[totalEntries].Icon); } else { Program.CurrentHost.RegisterTexture(Path.CombineFile(Program.FileSystem.DataFolder, "Menu\\icon_folder.png"), new TextureParameters(null, null), out Items[totalEntries].Icon); } } else { Items[totalEntries] = new MenuCommand(directoryInfo.Name, MenuTag.TrainDirectory, 0); Program.CurrentHost.RegisterTexture(Path.CombineFile(Program.FileSystem.DataFolder, "Menu\\icon_train.png"), new TextureParameters(null, null), out Items[totalEntries].Icon); } totalEntries++; } Array.Resize(ref Items, totalEntries); Align = TextAlignment.TopLeft; break; case MenuType.Top: // top level menu if (Interface.CurrentOptions.ScreenReaderAvailable) { if (!Tolk.Output(Translations.GetInterfaceString("menu_title"))) { // failed to output to screen reader, so don't keep trying Interface.CurrentOptions.ScreenReaderAvailable = false; } } for (i = 0; i < Program.CurrentRoute.Stations.Length; i++) { if (Program.CurrentRoute.Stations[i].PlayerStops() & Program.CurrentRoute.Stations[i].Stops.Length > 0) { jump = 1; break; } } Items = new MenuEntry[4 + jump]; Items[0] = new MenuCommand(Translations.GetInterfaceString("menu_resume"), MenuTag.BackToSim, 0); if (jump > 0) { Items[1] = new MenuCommand(Translations.GetInterfaceString("menu_jump"), MenuTag.MenuJumpToStation, 0); } if (!Interface.CurrentOptions.KioskMode) { //Don't allow quitting or customisation of the controls in kiosk mode Items[1 + jump] = new MenuCommand(Translations.GetInterfaceString("menu_exit"), MenuTag.MenuExitToMainMenu, 0); Items[2 + jump] = new MenuCommand(Translations.GetInterfaceString("menu_customize_controls"), MenuTag.MenuControls, 0); Items[3 + jump] = new MenuCommand(Translations.GetInterfaceString("menu_quit"), MenuTag.MenuQuit, 0); } else { Array.Resize(ref Items, Items.Length - 3); } break; case MenuType.JumpToStation: // list of stations to jump to // count the number of available stations menuItem = 0; for (i = 0; i < Program.CurrentRoute.Stations.Length; i++) { if (Program.CurrentRoute.Stations[i].PlayerStops() & Program.CurrentRoute.Stations[i].Stops.Length > 0) { menuItem++; } } // list available stations, selecting the next station as predefined choice jump = 0; // no jump found yet Items = new MenuEntry[menuItem + 1]; Items[0] = new MenuCommand(Translations.GetInterfaceString("menu_back"), MenuTag.MenuBack, 0); menuItem = 1; for (i = 0; i < Program.CurrentRoute.Stations.Length; i++) { if (Program.CurrentRoute.Stations[i].PlayerStops() & Program.CurrentRoute.Stations[i].Stops.Length > 0) { Items[menuItem] = new MenuCommand(Program.CurrentRoute.Stations[i].Name, MenuTag.JumpToStation, i); // if no preferred jump-to-station found yet and this station is // after the last station the user stopped at, select this item if (jump == 0 && i > TrainManagerBase.PlayerTrain.LastStation) { jump = i; Selection = menuItem; } menuItem++; } } Align = TextAlignment.TopLeft; break; case MenuType.ExitToMainMenu: Items = new MenuEntry[3]; Items[0] = new MenuCaption(Translations.GetInterfaceString("menu_exit_question")); Items[1] = new MenuCommand(Translations.GetInterfaceString("menu_exit_no"), MenuTag.MenuBack, 0); Items[2] = new MenuCommand(Translations.GetInterfaceString("menu_exit_yes"), MenuTag.ExitToMainMenu, 0); Selection = 1; break; case MenuType.Quit: // ask for quit confirmation Items = new MenuEntry[3]; Items[0] = new MenuCaption(Translations.GetInterfaceString("menu_quit_question")); Items[1] = new MenuCommand(Translations.GetInterfaceString("menu_quit_no"), MenuTag.MenuBack, 0); Items[2] = new MenuCommand(Translations.GetInterfaceString("menu_quit_yes"), MenuTag.Quit, 0); Selection = 1; break; case MenuType.Controls: //Refresh the joystick list Program.Joysticks.RefreshJoysticks(); Items = new MenuEntry[Interface.CurrentControls.Length + 1]; Items[0] = new MenuCommand(Translations.GetInterfaceString("menu_back"), MenuTag.MenuBack, 0); for (i = 0; i < Interface.CurrentControls.Length; i++) { Items[i + 1] = new MenuCommand(Interface.CurrentControls[i].Command.ToString(), MenuTag.Control, i); } Align = TextAlignment.TopLeft; break; case MenuType.Control: //Refresh the joystick list Program.Joysticks.RefreshJoysticks(); Selection = SelectionNone; Items = new MenuEntry[4]; // get code name and description Control loadedControl = Interface.CurrentControls[data]; for (int h = 0; h < Translations.CommandInfos.Length; h++) { if (Translations.CommandInfos[h].Command == loadedControl.Command) { Items[0] = new MenuCommand(loadedControl.Command.ToString() + " - " + Translations.CommandInfos[h].Description, MenuTag.None, 0); break; } } // get assignment String str = ""; switch (loadedControl.Method) { case ControlMethod.Keyboard: string keyName = loadedControl.Key.ToString(); for (int k = 0; k < Translations.TranslatedKeys.Length; k++) { if (Translations.TranslatedKeys[k].Key == loadedControl.Key) { keyName = Translations.TranslatedKeys[k].Description; break; } } if (loadedControl.Modifier != KeyboardModifier.None) { str = Translations.GetInterfaceString("menu_keyboard") + " [" + loadedControl.Modifier + "-" + keyName + "]"; } else { str = Translations.GetInterfaceString("menu_keyboard") + " [" + keyName + "]"; } break; case ControlMethod.Joystick: str = Translations.GetInterfaceString("menu_joystick") + " " + loadedControl.Device + " [" + loadedControl.Component + " " + loadedControl.Element + "]"; switch (loadedControl.Component) { case JoystickComponent.FullAxis: case JoystickComponent.Axis: str += " " + (loadedControl.Direction == 1 ? Translations.GetInterfaceString("menu_joystickdirection_positive") : Translations.GetInterfaceString("menu_joystickdirection_negative")); break; // case Interface.JoystickComponent.Button: // NOTHING TO DO FOR THIS CASE! // str = str; // break; case JoystickComponent.Hat: str += " " + (OpenTK.Input.HatPosition)loadedControl.Direction; break; case JoystickComponent.Invalid: str = Translations.GetInterfaceString("menu_joystick_notavailable"); break; } break; case ControlMethod.RailDriver: str = "RailDriver [" + loadedControl.Component + " " + loadedControl.Element + "]"; switch (loadedControl.Component) { case JoystickComponent.FullAxis: case JoystickComponent.Axis: str += " " + (loadedControl.Direction == 1 ? Translations.GetInterfaceString("menu_joystickdirection_positive") : Translations.GetInterfaceString("menu_joystickdirection_negative")); break; case JoystickComponent.Invalid: str = Translations.GetInterfaceString("menu_joystick_notavailable"); break; } break; case ControlMethod.Invalid: str = Translations.GetInterfaceString("menu_joystick_notavailable"); break; } Items[1] = new MenuCommand(Translations.GetInterfaceString("menu_assignment_current") + " " + str, MenuTag.None, 0); Items[2] = new MenuCommand(" ", MenuTag.None, 0); Items[3] = new MenuCommand(Translations.GetInterfaceString("menu_assign"), MenuTag.None, 0); break; case MenuType.TrainDefault: Interface.CurrentOptions.TrainFolder = Loading.GetDefaultTrainFolder(currentFile); bool canLoad = false; for (int j = 0; j < Program.CurrentHost.Plugins.Length; j++) { if (Program.CurrentHost.Plugins[j].Train != null && Program.CurrentHost.Plugins[j].Train.CanLoadTrain(Interface.CurrentOptions.TrainFolder)) { canLoad = true; break; } } if (canLoad) { Items = new MenuEntry[3]; Items[0] = new MenuCaption(Translations.GetInterfaceString("start_train_default")); Items[1] = new MenuCommand(Translations.GetInterfaceString("start_train_default_yes"), MenuTag.Yes, 0); Items[2] = new MenuCommand(Translations.GetInterfaceString("start_train_default_no"), MenuTag.No, 0); Selection = 1; } else { SearchDirectory = Program.FileSystem.InitialTrainFolder; //Default train not found or not valid Instance.PushMenu(MenuType.TrainList); } break; } // compute menu extent for (i = 0; i < Items.Length; i++) { if (Items[i] == null) { continue; } size = Game.Menu.MenuFont.MeasureString(Items[i].Text); if (Items[i].Icon != null) { size.X += size.Y * 1.25; } if (size.X > Width) { Width = size.X; } if (MaxWidth != 0 && size.X > MaxWidth) { for (int j = Items[i].Text.Length - 1; j > 0; j--) { string trimmedText = Items[i].Text.Substring(0, j); size = Game.Menu.MenuFont.MeasureString(trimmedText); double mwi = MaxWidth; if (Items[i].Icon != null) { mwi -= size.Y * 1.25; } if (size.X < mwi) { Items[i].DisplayLength = trimmedText.Length; break; } } Width = MaxWidth; } if (!(Items[i] is MenuCaption && menuType != MenuType.RouteList && menuType != MenuType.GameStart && menuType != MenuType.Packages) && size.X > ItemWidth) { ItemWidth = size.X; } } Height = Items.Length * Game.Menu.LineHeight; TopItem = 0; }
internal static void Process(MainForm form) { Thread.CurrentThread.CurrentCulture = CultureInfo.InvariantCulture; if (!System.IO.File.Exists(FileName)) { return; } mainForm = form; panel = new Vector3(DriverPosition.X, DriverPosition.Y, DriverPosition.Z + 1.0); string[] Lines = System.IO.File.ReadAllLines(FileName); TabbedList newLines = new TabbedList(); for (int i = 0; i < Lines.Length; i++) { int j = Lines[i].IndexOf(';'); if (j >= 0) { Lines[i] = Lines[i].Substring(0, j).Trim(new char[] { }); } else { Lines[i] = Lines[i].Trim(new char[] { }); } } if (Lines.Length < 1 || string.Compare(Lines[0], "version 1.0", StringComparison.OrdinalIgnoreCase) != 0) { mainForm.updateLogBoxText += "Invalid sound.cfg format string " + Lines[0] + Environment.NewLine; MessageBox.Show("Invalid sound.cfg format declaration."); return; } newLines.Add("<CarSounds>"); for (int i = 0; i < Lines.Length; i++) { switch (Lines[i].ToLowerInvariant()) { case "[run]": newLines.Add("<Run>"); i++; while (i < Lines.Length && !Lines[i].StartsWith("[", StringComparison.Ordinal)) { int j = Lines[i].IndexOf("=", StringComparison.Ordinal); if (j >= 0) { string a = Lines[i].Substring(0, j).TrimEnd(new char[] { }); string b = Lines[i].Substring(j + 1).TrimStart(new char[] { }); int k; if (!int.TryParse(a, System.Globalization.NumberStyles.Integer, CultureInfo.InvariantCulture, out k)) { continue; } if (b.Length == 0 || Path.ContainsInvalidChars(b)) { continue; } if (k >= 0) { newLines.Add("<Sound>"); newLines.Add("<Index>" + k + "</Index>"); newLines.Add("<FileName>" + b + "</FileName>"); newLines.Add("<Position>0,0,0</Position>"); newLines.Add("<Radius>10.0</Radius>"); newLines.Add("</Sound>"); } } i++; } i--; newLines.Add("</Run>"); break; case "[motor]": newLines.Add("<Motor>"); i++; while (i < Lines.Length && !Lines[i].StartsWith("[", StringComparison.Ordinal)) { int j = Lines[i].IndexOf("=", StringComparison.Ordinal); if (j >= 0) { string a = Lines[i].Substring(0, j).TrimEnd(new char[] { }); string b = Lines[i].Substring(j + 1).TrimStart(new char[] { }); int k; if (!int.TryParse(a, System.Globalization.NumberStyles.Integer, CultureInfo.InvariantCulture, out k)) { continue; } if (b.Length == 0 || Path.ContainsInvalidChars(b)) { continue; } if (k >= 0) { newLines.Add("<Sound>"); newLines.Add("<Index>" + k + "</Index>"); newLines.Add("<FileName>" + b + "</FileName>"); newLines.Add("<Position>0,0,0</Position>"); newLines.Add("<Radius>10.0</Radius>"); newLines.Add("</Sound>"); } } i++; } i--; newLines.Add("</Motor>"); break; case "[ats]": newLines.Add("<ATS>"); i++; while (i < Lines.Length && !Lines[i].StartsWith("[", StringComparison.Ordinal)) { int j = Lines[i].IndexOf("=", StringComparison.Ordinal); if (j >= 0) { string a = Lines[i].Substring(0, j).TrimEnd(new char[] { }); string b = Lines[i].Substring(j + 1).TrimStart(new char[] { }); int k; if (!int.TryParse(a, System.Globalization.NumberStyles.Integer, CultureInfo.InvariantCulture, out k)) { continue; } if (b.Length == 0 || Path.ContainsInvalidChars(b)) { continue; } if (k >= 0) { newLines.Add("<Sound>"); newLines.Add("<Index>" + k + "</Index>"); newLines.Add("<FileName>" + b + "</FileName>"); newLines.Add("<Position>0,0,0</Position>"); newLines.Add("<Radius>10.0</Radius>"); newLines.Add("</Sound>"); } } i++; } i--; newLines.Add("</ATS>"); break; case "[switch]": newLines.Add("<Switch>"); i++; while (i < Lines.Length && !Lines[i].StartsWith("[", StringComparison.Ordinal)) { int j = Lines[i].IndexOf("=", StringComparison.Ordinal); if (j >= 0) { string a = Lines[i].Substring(0, j).TrimEnd(new char[] { }); string b = Lines[i].Substring(j + 1).TrimStart(new char[] { }); int k; if (!int.TryParse(a, System.Globalization.NumberStyles.Integer, CultureInfo.InvariantCulture, out k)) { continue; } if (b.Length == 0 || Path.ContainsInvalidChars(b)) { continue; } if (k >= 0) { newLines.Add("<Sound>"); newLines.Add("<Index>" + k + "</Index>"); newLines.Add("<FileName>" + b + "</FileName>"); newLines.Add("<Position>0,0,0</Position>"); newLines.Add("<Radius>10.0</Radius>"); newLines.Add("</Sound>"); } } i++; } i--; newLines.Add("</Switch>"); break; case "[brake]": newLines.Add("<Brake>"); i++; while (i < Lines.Length && !Lines[i].StartsWith("[", StringComparison.Ordinal)) { int j = Lines[i].IndexOf("=", StringComparison.Ordinal); if (j >= 0) { string a = Lines[i].Substring(0, j).TrimEnd(new char[] { }); string b = Lines[i].Substring(j + 1).TrimStart(new char[] { }); if (b.Length == 0 || Path.ContainsInvalidChars(b)) { continue; } switch (a.ToLowerInvariant()) { case "bc release high": newLines.Add("<ReleaseHigh>"); newLines.Add("<FileName>" + b + "</FileName>"); newLines.Add("<Position>0,0,0</Position>"); newLines.Add("<Radius>5.0</Radius>"); newLines.Add("</ReleaseHigh>"); break; case "bc release": newLines.Add("<Release>"); newLines.Add("<FileName>" + b + "</FileName>"); newLines.Add("<Position>0,0,0</Position>"); newLines.Add("<Radius>5.0</Radius>"); newLines.Add("</Release>"); break; case "bc release full": newLines.Add("<ReleaseFull>"); newLines.Add("<FileName>" + b + "</FileName>"); newLines.Add("<Position>0,0,0</Position>"); newLines.Add("<Radius>5.0</Radius>"); newLines.Add("</ReleaseFull>"); break; case "emergency": newLines.Add("<Emergency>"); newLines.Add("<FileName>" + b + "</FileName>"); newLines.Add("<Position>0,0,0</Position>"); newLines.Add("<Radius>5.0</Radius>"); newLines.Add("</Emergency>"); break; case "bp decomp": newLines.Add("<Application>"); newLines.Add("<FileName>" + b + "</FileName>"); newLines.Add("<Position>0,0,0</Position>"); newLines.Add("<Radius>5.0</Radius>"); newLines.Add("</Application>"); break; } } i++; } i--; newLines.Add("</Brake>"); break; case "[compressor]": newLines.Add("<Compressor>"); i++; while (i < Lines.Length && !Lines[i].StartsWith("[", StringComparison.Ordinal)) { int j = Lines[i].IndexOf("=", StringComparison.Ordinal); if (j >= 0) { string a = Lines[i].Substring(0, j).TrimEnd(new char[] { }); string b = Lines[i].Substring(j + 1).TrimStart(new char[] { }); if (b.Length == 0 || Path.ContainsInvalidChars(b)) { continue; } switch (a.ToLowerInvariant()) { case "attack": newLines.Add("<Start>"); newLines.Add("<FileName>" + b + "</FileName>"); newLines.Add("<Position>0,0,0</Position>"); newLines.Add("<Radius>10.0</Radius>"); newLines.Add("</Start>"); break; case "loop": newLines.Add("<Loop>"); newLines.Add("<FileName>" + b + "</FileName>"); newLines.Add("<Position>0,0,0</Position>"); newLines.Add("<Radius>10.0</Radius>"); newLines.Add("</Loop>"); break; case "release": newLines.Add("<End>"); newLines.Add("<FileName>" + b + "</FileName>"); newLines.Add("<Position>0,0,0</Position>"); newLines.Add("<Radius>10.0</Radius>"); newLines.Add("</End>"); break; } } i++; } i--; newLines.Add("</Compressor>"); break; case "[suspension]": newLines.Add("<Suspension>"); i++; while (i < Lines.Length && !Lines[i].StartsWith("[", StringComparison.Ordinal)) { int j = Lines[i].IndexOf("=", StringComparison.Ordinal); if (j >= 0) { string a = Lines[i].Substring(0, j).TrimEnd(new char[] { }); string b = Lines[i].Substring(j + 1).TrimStart(new char[] { }); if (b.Length == 0 || Path.ContainsInvalidChars(b)) { continue; } switch (a.ToLowerInvariant()) { case "left": newLines.Add("<Left>"); newLines.Add("<FileName>" + b + "</FileName>"); newLines.Add("<Position>0,0,0</Position>"); newLines.Add("<Radius>5.0</Radius>"); newLines.Add("</Left>"); break; case "right": newLines.Add("<Right>"); newLines.Add("<FileName>" + b + "</FileName>"); newLines.Add("<Position>0,0,0</Position>"); newLines.Add("<Radius>5.0</Radius>"); newLines.Add("</Right>"); break; } } i++; } i--; newLines.Add("</Suspension>"); break; case "[horn]": newLines.Add("<Horn>"); i++; List <string> primary = new List <string>(); List <string> secondary = new List <string>(); List <string> music = new List <string>(); while (i < Lines.Length && !Lines[i].StartsWith("[", StringComparison.Ordinal)) { int j = Lines[i].IndexOf("=", StringComparison.Ordinal); if (j >= 0) { string a = Lines[i].Substring(0, j).TrimEnd(new char[] { }); string b = Lines[i].Substring(j + 1).TrimStart(new char[] { }); if (b.Length == 0 || Path.ContainsInvalidChars(b)) { continue; } switch (a.ToLowerInvariant()) { //PRIMARY HORN (Enter) case "primarystart": primary.Add("<Start>"); primary.Add("<FileName>" + b + "</FileName>"); primary.Add("<Position>" + front + "</Position>"); primary.Add("<Radius>30.0</Radius>"); primary.Add("</Start>"); break; case "primaryend": case "primaryrelease": primary.Add("<End>"); primary.Add("<FileName>" + b + "</FileName>"); primary.Add("<Position>" + front + "</Position>"); primary.Add("<Radius>30.0</Radius>"); primary.Add("</End>"); break; case "primaryloop": case "primary": primary.Add("<Loop>"); primary.Add("<FileName>" + b + "</FileName>"); primary.Add("<Position>" + front + "</Position>"); primary.Add("<Radius>30.0</Radius>"); primary.Add("</Loop>"); break; //SECONDARY HORN (Numpad Enter) case "secondarystart": secondary.Add("<Start>"); secondary.Add("<FileName>" + b + "</FileName>"); secondary.Add("<Position>" + front + "</Position>"); secondary.Add("<Radius>30.0</Radius>"); secondary.Add("</Start>"); break; case "secondaryend": case "secondaryrelease": secondary.Add("<End>"); secondary.Add("<FileName>" + b + "</FileName>"); secondary.Add("<Position>" + front + "</Position>"); secondary.Add("<Radius>30.0</Radius>"); secondary.Add("</End>"); break; case "secondaryloop": case "secondary": secondary.Add("<Loop>"); secondary.Add("<FileName>" + b + "</FileName>"); secondary.Add("<Position>" + front + "</Position>"); secondary.Add("<Radius>30.0</Radius>"); secondary.Add("</Loop>"); break; //MUSIC HORN case "musicstart": music.Add("<Start>"); music.Add("<FileName>" + b + "</FileName>"); music.Add("<Position>" + front + "</Position>"); music.Add("<Radius>30.0</Radius>"); music.Add("</Start>"); break; case "musicend": case "musicrelease": music.Add("<End>"); music.Add("<FileName>" + b + "</FileName>"); music.Add("<Position>" + front + "</Position>"); music.Add("<Radius>30.0</Radius>"); music.Add("</End>"); break; case "musicloop": case "music": music.Add("<Loop>"); music.Add("<FileName>" + b + "</FileName>"); music.Add("<Position>" + front + "</Position>"); music.Add("<Radius>30.0</Radius>"); music.Add("</Loop>"); break; } } i++; } i--; if (primary.Count != 0) { newLines.Add("<Primary>"); newLines.AddRange(primary); newLines.Add("</Primary>"); } if (secondary.Count != 0) { newLines.Add("<Secondary>"); newLines.AddRange(secondary); newLines.Add("</Secondary>"); } if (music.Count != 0) { newLines.Add("<Music>"); newLines.AddRange(music); newLines.Add("<Toggle>true</Toggle>"); newLines.Add("</Music>"); } newLines.Add("</Horn>"); break; case "[door]": newLines.Add("<Door>"); i++; while (i < Lines.Length && !Lines[i].StartsWith("[", StringComparison.Ordinal)) { int j = Lines[i].IndexOf("=", StringComparison.Ordinal); if (j >= 0) { string a = Lines[i].Substring(0, j).TrimEnd(new char[] { }); string b = Lines[i].Substring(j + 1).TrimStart(new char[] { }); if (b.Length == 0 || Path.ContainsInvalidChars(b)) { continue; } else { switch (a.ToLowerInvariant()) { case "open left": newLines.Add("<OpenLeft>"); newLines.Add("<FileName>" + b + "</FileName>"); newLines.Add("<Position>-1.3,0,0</Position>"); newLines.Add("<Radius>5.0</Radius>"); newLines.Add("</OpenLeft>"); break; case "open right": newLines.Add("<OpenRight>"); newLines.Add("<FileName>" + b + "</FileName>"); newLines.Add("<Position>1.3,0,0</Position>"); newLines.Add("<Radius>5.0</Radius>"); newLines.Add("</OpenRight>"); break; case "close left": newLines.Add("<CloseLeft>"); newLines.Add("<FileName>" + b + "</FileName>"); newLines.Add("<Position>-1.3,0,0</Position>"); newLines.Add("<Radius>5.0</Radius>"); newLines.Add("</CloseLeft>"); break; case "close right": newLines.Add("<CloseRight>"); newLines.Add("<FileName>" + b + "</FileName>"); newLines.Add("<Position>1.3,0,0</Position>"); newLines.Add("<Radius>5.0</Radius>"); newLines.Add("</CloseRight>"); break; } } } i++; } i--; newLines.Add("</Door>"); break; case "[buzzer]": i++; while (i < Lines.Length && !Lines[i].StartsWith("[", StringComparison.Ordinal)) { int j = Lines[i].IndexOf("=", StringComparison.Ordinal); if (j >= 0) { string a = Lines[i].Substring(0, j).TrimEnd(new char[] { }); string b = Lines[i].Substring(j + 1).TrimStart(new char[] { }); if (b.Length == 0 || Path.ContainsInvalidChars(b)) { continue; } switch (a.ToLowerInvariant()) { case "correct": newLines.Add("<Buzzer>"); newLines.Add("<FileName>" + b + "</FileName>"); newLines.Add("<Position>" + panel + "</Position>"); newLines.Add("<Radius>2.0</Radius>"); newLines.Add("</Buzzer>"); break; } } i++; } i--; break; case "[pilot lamp]": newLines.Add("<PilotLamp>"); i++; while (i < Lines.Length && !Lines[i].StartsWith("[", StringComparison.Ordinal)) { int j = Lines[i].IndexOf("=", StringComparison.Ordinal); if (j >= 0) { string a = Lines[i].Substring(0, j).TrimEnd(new char[] { }); string b = Lines[i].Substring(j + 1).TrimStart(new char[] { }); if (b.Length == 0 || Path.ContainsInvalidChars(b)) { continue; } switch (a.ToLowerInvariant()) { case "on": newLines.Add("<On>"); newLines.Add("<FileName>" + b + "</FileName>"); newLines.Add("<Position>" + panel + "</Position>"); newLines.Add("<Radius>2.0</Radius>"); newLines.Add("</On>"); break; case "off": newLines.Add("<Off>"); newLines.Add("<FileName>" + b + "</FileName>"); newLines.Add("<Position>" + panel + "</Position>"); newLines.Add("<Radius>2.0</Radius>"); newLines.Add("</Off>"); break; } } i++; } i--; newLines.Add("</PilotLamp>"); break; case "[brake handle]": newLines.Add("<BrakeHandle>"); i++; while (i < Lines.Length && !Lines[i].StartsWith("[", StringComparison.Ordinal)) { int j = Lines[i].IndexOf("=", StringComparison.Ordinal); if (j >= 0) { string a = Lines[i].Substring(0, j).TrimEnd(new char[] { }); string b = Lines[i].Substring(j + 1).TrimStart(new char[] { }); if (b.Length == 0 || Path.ContainsInvalidChars(b)) { continue; } switch (a.ToLowerInvariant()) { case "apply": newLines.Add("<Apply>"); newLines.Add("<FileName>" + b + "</FileName>"); newLines.Add("<Position>" + panel + "</Position>"); newLines.Add("<Radius>2.0</Radius>"); newLines.Add("</Apply>"); break; case "applyfast": newLines.Add("<ApplyFast>"); newLines.Add("<FileName>" + b + "</FileName>"); newLines.Add("<Position>" + panel + "</Position>"); newLines.Add("<Radius>2.0</Radius>"); newLines.Add("</ApplyFast>"); break; case "release": newLines.Add("<Release>"); newLines.Add("<FileName>" + b + "</FileName>"); newLines.Add("<Position>" + panel + "</Position>"); newLines.Add("<Radius>2.0</Radius>"); newLines.Add("</Release>"); break; case "releasefast": newLines.Add("<ReleaseFast>"); newLines.Add("<FileName>" + b + "</FileName>"); newLines.Add("<Position>" + panel + "</Position>"); newLines.Add("<Radius>2.0</Radius>"); newLines.Add("</ReleaseFast>"); break; case "min": newLines.Add("<Minimum>"); newLines.Add("<FileName>" + b + "</FileName>"); newLines.Add("<Position>" + panel + "</Position>"); newLines.Add("<Radius>2.0</Radius>"); newLines.Add("</Minimum>"); break; case "max": newLines.Add("<Maximum>"); newLines.Add("<FileName>" + b + "</FileName>"); newLines.Add("<Position>" + panel + "</Position>"); newLines.Add("<Radius>2.0</Radius>"); newLines.Add("</Maximum>"); break; } } i++; } i--; newLines.Add("</BrakeHandle>"); break; case "[master controller]": newLines.Add("<PowerHandle>"); i++; while (i < Lines.Length && !Lines[i].StartsWith("[", StringComparison.Ordinal)) { int j = Lines[i].IndexOf("=", StringComparison.Ordinal); if (j >= 0) { string a = Lines[i].Substring(0, j).TrimEnd(new char[] { }); string b = Lines[i].Substring(j + 1).TrimStart(new char[] { }); if (b.Length == 0 || Path.ContainsInvalidChars(b)) { continue; } else { switch (a.ToLowerInvariant()) { case "up": newLines.Add("<Increase>"); newLines.Add("<FileName>" + b + "</FileName>"); newLines.Add("<Position>" + panel + "</Position>"); newLines.Add("<Radius>2.0</Radius>"); newLines.Add("</Increase>"); break; case "upfast": newLines.Add("<IncreaseFast>"); newLines.Add("<FileName>" + b + "</FileName>"); newLines.Add("<Position>" + panel + "</Position>"); newLines.Add("<Radius>2.0</Radius>"); newLines.Add("</IncreaseFast>"); break; case "down": newLines.Add("<Decrease>"); newLines.Add("<FileName>" + b + "</FileName>"); newLines.Add("<Position>" + panel + "</Position>"); newLines.Add("<Radius>2.0</Radius>"); newLines.Add("</Decrease>"); break; case "downfast": newLines.Add("<DecreaseFast>"); newLines.Add("<FileName>" + b + "</FileName>"); newLines.Add("<Position>" + panel + "</Position>"); newLines.Add("<Radius>2.0</Radius>"); newLines.Add("</DecreaseFast>"); break; case "min": newLines.Add("<Minimum>"); newLines.Add("<FileName>" + b + "</FileName>"); newLines.Add("<Position>" + panel + "</Position>"); newLines.Add("<Radius>2.0</Radius>"); newLines.Add("</Minimum>"); break; case "max": newLines.Add("<Maximum>"); newLines.Add("<FileName>" + b + "</FileName>"); newLines.Add("<Position>" + panel + "</Position>"); newLines.Add("<Radius>2.0</Radius>"); newLines.Add("</Maximum>"); break; } } } i++; } i--; newLines.Add("</PowerHandle>"); break; case "[reverser]": newLines.Add("<Reverser>"); i++; while (i < Lines.Length && !Lines[i].StartsWith("[", StringComparison.Ordinal)) { int j = Lines[i].IndexOf("=", StringComparison.Ordinal); if (j >= 0) { string a = Lines[i].Substring(0, j).TrimEnd(new char[] { }); string b = Lines[i].Substring(j + 1).TrimStart(new char[] { }); if (b.Length == 0 || Path.ContainsInvalidChars(b)) { continue; } switch (a.ToLowerInvariant()) { case "on": newLines.Add("<On>"); newLines.Add("<FileName>" + b + "</FileName>"); newLines.Add("<Position>" + panel + "</Position>"); newLines.Add("<Radius>2.0</Radius>"); newLines.Add("</On>"); break; case "off": newLines.Add("<Off>"); newLines.Add("<FileName>" + b + "</FileName>"); newLines.Add("<Position>" + panel + "</Position>"); newLines.Add("<Radius>2.0</Radius>"); newLines.Add("</Off>"); break; } } i++; } i--; newLines.Add("</Reverser>"); break; case "[breaker]": newLines.Add("<Breaker>"); i++; while (i < Lines.Length && !Lines[i].StartsWith("[", StringComparison.Ordinal)) { int j = Lines[i].IndexOf("=", StringComparison.Ordinal); if (j >= 0) { string a = Lines[i].Substring(0, j).TrimEnd(new char[] { }); string b = Lines[i].Substring(j + 1).TrimStart(new char[] { }); if (b.Length == 0 || Path.ContainsInvalidChars(b)) { continue; } else { switch (a.ToLowerInvariant()) { case "on": newLines.Add("<On>"); newLines.Add("<FileName>" + b + "</FileName>"); newLines.Add("<Position>" + panel + "</Position>"); newLines.Add("<Radius>5.0</Radius>"); newLines.Add("</On>"); break; case "off": newLines.Add("<Off>"); newLines.Add("<FileName>" + b + "</FileName>"); newLines.Add("<Position>" + panel + "</Position>"); newLines.Add("<Radius>5.0</Radius>"); newLines.Add("</Off>"); break; } } } i++; } i--; newLines.Add("</Breaker>"); break; case "[others]": i++; while (i < Lines.Length && !Lines[i].StartsWith("[", StringComparison.Ordinal)) { int j = Lines[i].IndexOf("=", StringComparison.Ordinal); if (j >= 0) { string a = Lines[i].Substring(0, j).TrimEnd(new char[] { }); string b = Lines[i].Substring(j + 1).TrimStart(new char[] { }); if (b.Length == 0 || Path.ContainsInvalidChars(b)) { continue; } switch (a.ToLowerInvariant()) { case "noise": newLines.Add("<Loop>"); newLines.Add("<FileName>" + b + "</FileName>"); newLines.Add("<Position>0,0,0</Position>"); newLines.Add("<Radius>10.0</Radius>"); newLines.Add("</Loop>"); break; case "shoe": newLines.Add("<Rub>"); newLines.Add("<FileName>" + b + "</FileName>"); newLines.Add("<Position>0,0,0</Position>"); newLines.Add("<Radius>10.0</Radius>"); newLines.Add("</Rub>"); break; } } i++; } i--; break; } } newLines.Add("</CarSounds>"); newLines.Add("</openBVE>"); string fileOut = System.IO.Path.Combine(System.IO.Path.GetDirectoryName(FileName), "sound.xml"); try { using (StreamWriter sw = new StreamWriter(fileOut)) { foreach (String s in newLines.Lines) { sw.WriteLine(s); } } } catch { mainForm.updateLogBoxText += "Error writing file " + fileOut + Environment.NewLine; MessageBox.Show("An error occured whilst writing the new XML file. \r\n Please check for write permissions.", "CarXML Convertor", MessageBoxButtons.OK, MessageBoxIcon.Hand); return; } }
/// <summary>Is called when the plugin is loaded.</summary> /// <param name="properties">The properties supplied to the plugin on loading.</param> /// <returns>Whether the plugin was loaded successfully.</returns> public bool Load(LoadProperties properties) { properties.Panel = new int[512]; SoundManager.Initialise(properties.PlaySound, 512); MessageManager.Initialise(properties.AddMessage); properties.AISupport = AISupport.Basic; this.Train = new Train(properties.Panel); //No AI Support //properties.AISupport = AISupport.None; this.Train = new Train(properties.Panel); string configFile = Path.CombineFile(properties.TrainFolder, "BVEC_Ats.cfg"); string OS_ATSDLL = Path.CombineFile(properties.TrainFolder, "OS_ATS1.dll"); string SZ_ATSDLL = Path.CombineFile(properties.TrainFolder, "OS_SZ_ATS1.dll"); string SZ_ATSDLL_2 = Path.CombineFile(properties.TrainFolder, "OS_SZ_Ats2_0.dll"); string OS_ATSconfigFile = Path.CombineFile(properties.TrainFolder, "OS_ATS1.cfg"); string SZ_ATSconfigFile = Path.CombineFile(properties.TrainFolder, "OS_SZ_ATS1.cfg"); string SZ_ATS_2configFile = Path.CombineFile(properties.TrainFolder, "OS_SZ_Ats2_0.cfg"); string ODF_ATSconfigFile = Path.CombineFile(properties.TrainFolder, "OdakyufanAts.cfg"); TrainFolder = properties.TrainFolder; //Delete error.log from previous run if (File.Exists(Path.CombineFile(properties.TrainFolder, "error.log"))) { try { File.Delete(Path.CombineFile(properties.TrainFolder, "error.log")); } catch { FolderWriteAccess = false; } } if (File.Exists(configFile)) { //Check for the automatic generator version string generatorversion; using (var reader = new StreamReader(configFile)) { //Read in first line generatorversion = reader.ReadLine(); } //If it exists try { if (generatorversion != null && generatorversion.StartsWith(";GenVersion=")) { string versiontext = Regex.Match(generatorversion, @"\d+").Value; int version = Int32.Parse(versiontext, NumberStyles.Number, CultureInfo.InvariantCulture); //If we're below the current version, try to upgrade again if (version < 1) { if (File.Exists(OS_ATSDLL) && File.Exists(OS_ATSconfigFile)) { try { string[] Lines = UpgradeOSATS.UpgradeConfigurationFile(OS_ATSconfigFile, properties.TrainFolder); } catch (Exception) { properties.FailureReason = "An error occured whilst attempting to upgrade the OS_ATS configuration."; return(false); } } } } } catch (Exception) { properties.FailureReason = "Empty configuration file detected."; return(false); } //Now try loading try { string[] Lines = File.ReadAllLines(configFile, Encoding.UTF8); this.Train.LoadConfigurationFile(Lines); return(true); } catch (Exception ex) { properties.FailureReason = "Error loading the configuration file: " + ex.Message; return(false); } } if (!File.Exists(configFile) && File.Exists(OS_ATSDLL) && File.Exists(OS_ATSconfigFile)) { //The F92_en is blacklisted due to a custom OS_ATS version if (Regex.IsMatch(properties.TrainFolder, @"\\F92_en(\\)?", RegexOptions.IgnoreCase)) { properties.FailureReason = "The F92_en is not currently a supported train."; try { using (StreamWriter sw = File.CreateText(Path.CombineFile(properties.TrainFolder, "error.log"))) { sw.WriteLine("The F92_en is not currently a supported train"); } return(false); } catch { return(false); } } //If there is no existing BVEC_ATS configuration file, but OS_ATS and the appropriate //configuration files exist, then attempt to upgrade the existing file to BVEC_ATS try { string[] Lines = UpgradeOSATS.UpgradeConfigurationFile(OS_ATSconfigFile, properties.TrainFolder); try { File.WriteAllLines(Path.CombineFile(TrainFolder, "BVEC_ATS.cfg"), Lines); } catch { //Error writing the new configuration file } this.Train.LoadConfigurationFile(Lines); return(true); } catch (Exception) { properties.FailureReason = "Error upgrading the existing OS_ATS configuration."; using (StreamWriter sw = File.CreateText(Path.CombineFile(properties.TrainFolder, "error.log"))) { sw.WriteLine("An existing OS_ATS configuration was found."); sw.WriteLine("However, an error occurred upgrading the existing OS_ATS configuration."); } return(false); } } if (File.Exists(SZ_ATSDLL)) { //We've found an OS_SZ_ATS equipped train //Upgrade for this is in alpha try { string[] Lines = UpgradeOSSZATS.UpgradeConfigurationFile(SZ_ATSconfigFile, properties.TrainFolder); try { File.WriteAllLines(Path.CombineFile(TrainFolder, "BVEC_ATS.cfg"), Lines); } catch { //Error writing the new configuration file } this.Train.LoadConfigurationFile(Lines); return(true); } catch (Exception) { properties.FailureReason = "Error upgrading the existing OS_SZ_ATS configuration."; using (StreamWriter sw = File.CreateText(Path.CombineFile(properties.TrainFolder, "error.log"))) { sw.WriteLine("An existing OS_SZ_ATS configuration was found."); sw.WriteLine("However, an error occurred upgrading the existing OS_SZ_ATS configuration."); } return(false); } } else { if (File.Exists(SZ_ATSDLL_2)) { //We've found an OS_SZ_ATS equipped train //Upgrade for this is in alpha try { string[] Lines = UpgradeOSSZATS.UpgradeConfigurationFile(SZ_ATS_2configFile, properties.TrainFolder); try { File.WriteAllLines(Path.CombineFile(TrainFolder, "BVEC_ATS.cfg"), Lines); } catch { //Error writing the new configuration file } this.Train.LoadConfigurationFile(Lines); return(true); } catch (Exception) { properties.FailureReason = "Error upgrading the existing OS_SZ_ATS configuration."; using (StreamWriter sw = File.CreateText(Path.CombineFile(properties.TrainFolder, "error.log"))) { sw.WriteLine("An existing OS_SZ_ATS configuration was found."); sw.WriteLine("However, an error occurred upgrading the existing OS_SZ_ATS configuration."); } return(false); } } if (File.Exists(ODF_ATSconfigFile)) { //We've found an OdyakufanATS equipped train //Upgrade for this is in alpha try { File.Copy(ODF_ATSconfigFile, configFile); string[] Lines = File.ReadAllLines(configFile); this.Train.LoadConfigurationFile(Lines); return(true); } catch (Exception ex) { properties.FailureReason = "Error loading the configuration file: " + ex.Message; return(false); } } else { properties.FailureReason = "No supported configuration files exist."; //Write out error.log with details of what it thinks was found and missing using (StreamWriter sw = File.CreateText(Path.CombineFile(properties.TrainFolder, "error.log"))) { sw.WriteLine("Plugin location " + Convert.ToString(properties.TrainFolder)); if (File.Exists(OS_ATSDLL)) { sw.WriteLine("OS_ATS DLL found"); } else { sw.WriteLine("No OS_ATS DLL found"); } if (File.Exists(OS_ATSconfigFile)) { sw.WriteLine("OS_ATS configuration file found"); } else { sw.WriteLine("No OS_ATS configuration file found"); } } return(false); } } }