Example #1
0
        public static bool ReadMarkerXML(string fileName, double StartingPosition, ref Marker Marker)
        {
            double          EndingPosition = Double.PositiveInfinity;
            AbstractMessage Message        = null;
            //The current XML file to load
            XmlDocument currentXML = new XmlDocument();

            //Load the marker's XML file
            currentXML.Load(fileName);
            string Path = System.IO.Path.GetDirectoryName(fileName);

            if (currentXML.DocumentElement != null)
            {
                bool        iM            = false;
                XmlNodeList DocumentNodes = currentXML.DocumentElement.SelectNodes("/openBVE/TextMarker");

                if (DocumentNodes == null || DocumentNodes.Count == 0)
                {
                    DocumentNodes = currentXML.DocumentElement.SelectNodes("/openBVE/ImageMarker");
                    iM            = true;
                }
                if (DocumentNodes == null || DocumentNodes.Count == 0)
                {
                    Plugin.CurrentHost.AddMessage(MessageType.Error, false, "No marker nodes defined in XML file " + fileName);
                    return(false);
                }
                foreach (XmlNode n in DocumentNodes)
                {
                    if (n.ChildNodes.OfType <XmlElement>().Any())
                    {
                        bool         EarlyDefined = false, LateDefined = false;
                        string       EarlyText = null, Text = null, LateText = null;
                        string[]     Trains = null;
                        Texture      EarlyTexture = null, Texture = null, LateTexture = null;
                        double       EarlyTime = 0.0, LateTime = 0.0, TimeOut = Double.PositiveInfinity;
                        MessageColor EarlyColor = MessageColor.White, OnTimeColor = MessageColor.White, LateColor = MessageColor.White;
                        foreach (XmlNode c in n.ChildNodes)
                        {
                            switch (c.Name.ToLowerInvariant())
                            {
                            case "early":
                                if (!c.ChildNodes.OfType <XmlElement>().Any())
                                {
                                    Plugin.CurrentHost.AddMessage(MessageType.Error, false, "No paramaters defined for the early message in " + fileName);
                                }
                                foreach (XmlNode cc in c.ChildNodes)
                                {
                                    switch (cc.Name.ToLowerInvariant())
                                    {
                                    case "text":
                                        EarlyText = cc.InnerText;
                                        break;

                                    case "texture":
                                    case "image":
                                        string f;
                                        try
                                        {
                                            f = OpenBveApi.Path.CombineFile(Path, cc.InnerText);
                                        }
                                        catch
                                        {
                                            Plugin.CurrentHost.AddMessage(MessageType.Error, false, "MessageEarlyTexture path was malformed in file " + fileName);
                                            break;
                                        }
                                        if (System.IO.File.Exists(f))
                                        {
                                            if (!Plugin.CurrentHost.RegisterTexture(f, new TextureParameters(null, null), out EarlyTexture))
                                            {
                                                Plugin.CurrentHost.AddMessage(MessageType.Error, false, "Loading MessageEarlyTexture " + f + " failed.");
                                            }
                                        }
                                        else
                                        {
                                            Plugin.CurrentHost.AddMessage(MessageType.Error, false, "MessageEarlyTexture " + f + " does not exist.");
                                        }
                                        break;

                                    case "time":
                                        if (!Parser.TryParseTime(cc.InnerText, out EarlyTime))
                                        {
                                            Plugin.CurrentHost.AddMessage(MessageType.Error, false, "Early message time invalid in " + fileName);
                                        }
                                        EarlyDefined = true;
                                        break;

                                    case "color":
                                        EarlyColor = ParseColor(cc.InnerText, fileName);
                                        break;
                                    }
                                }
                                break;

                            case "ontime":
                                if (!c.ChildNodes.OfType <XmlElement>().Any())
                                {
                                    Plugin.CurrentHost.AddMessage(MessageType.Error, false,
                                                                  "No paramaters defined for the on-time message in " + fileName);
                                }
                                foreach (XmlNode cc in c.ChildNodes)
                                {
                                    switch (cc.Name.ToLowerInvariant())
                                    {
                                    case "text":
                                        Text = cc.InnerText;
                                        break;

                                    case "texture":
                                    case "image":
                                        string f;
                                        try
                                        {
                                            f = OpenBveApi.Path.CombineFile(Path, cc.InnerText);
                                        }
                                        catch
                                        {
                                            Plugin.CurrentHost.AddMessage(MessageType.Error, false, "MessageTexture path was malformed in file " + fileName);
                                            break;
                                        }
                                        if (System.IO.File.Exists(f))
                                        {
                                            if (!Plugin.CurrentHost.RegisterTexture(f, new TextureParameters(null, null), out Texture))
                                            {
                                                Plugin.CurrentHost.AddMessage(MessageType.Error, false, "Loading MessageTexture " + f + " failed.");
                                            }
                                        }
                                        else
                                        {
                                            Plugin.CurrentHost.AddMessage(MessageType.Error, false, "MessageTexture " + f + " does not exist.");
                                        }
                                        break;

                                    case "color":
                                        OnTimeColor = ParseColor(cc.InnerText, fileName);
                                        break;

                                    case "time":
                                        Plugin.CurrentHost.AddMessage(MessageType.Error, false, "OnTime should not contain a TIME declaration in " + fileName);
                                        break;
                                    }
                                }
                                break;

                            case "late":
                                if (!c.ChildNodes.OfType <XmlElement>().Any())
                                {
                                    Plugin.CurrentHost.AddMessage(MessageType.Error, false,
                                                                  "No paramaters defined for the late message in " + fileName);
                                }

                                foreach (XmlNode cc in c.ChildNodes)
                                {
                                    switch (cc.Name.ToLowerInvariant())
                                    {
                                    case "text":
                                        LateText = cc.InnerText;
                                        break;

                                    case "texture":
                                    case "image":
                                        string f;
                                        try
                                        {
                                            f = OpenBveApi.Path.CombineFile(Path, cc.InnerText);
                                        }
                                        catch
                                        {
                                            Plugin.CurrentHost.AddMessage(MessageType.Error, false, "MessageLateTexture path was malformed in file " + fileName);
                                            break;
                                        }
                                        if (System.IO.File.Exists(f))
                                        {
                                            if (!Plugin.CurrentHost.RegisterTexture(f, new TextureParameters(null, null), out LateTexture))
                                            {
                                                Plugin.CurrentHost.AddMessage(MessageType.Error, false, "Loading MessageLateTexture " + f + " failed.");
                                            }
                                        }
                                        else
                                        {
                                            Plugin.CurrentHost.AddMessage(MessageType.Error, false, "MessageLateTexture " + f + " does not exist.");
                                        }
                                        break;

                                    case "time":
                                        if (!Parser.TryParseTime(cc.InnerText, out LateTime))
                                        {
                                            Plugin.CurrentHost.AddMessage(MessageType.Error, false, "Early message time invalid in " + fileName);
                                        }
                                        LateDefined = true;
                                        break;

                                    case "color":
                                        LateColor = ParseColor(cc.InnerText, fileName);
                                        break;
                                    }
                                }
                                break;

                            case "timeout":
                                if (!NumberFormats.TryParseDouble(c.InnerText, new[] { 1.0 }, out TimeOut))
                                {
                                    Plugin.CurrentHost.AddMessage(MessageType.Error, false, "Marker timeout invalid in " + fileName);
                                }
                                break;

                            case "distance":
                                if (!NumberFormats.TryParseDouble(c.InnerText, new[] { 1.0 }, out EndingPosition))
                                {
                                    Plugin.CurrentHost.AddMessage(MessageType.Error, false, "Marker distance invalid in " + fileName);
                                }
                                break;

                            case "trains":
                                Trains = c.InnerText.Split(';');
                                break;
                            }
                        }
                        //Check this marker is valid
                        if (TimeOut == Double.PositiveInfinity && EndingPosition == Double.PositiveInfinity)
                        {
                            Plugin.CurrentHost.AddMessage(MessageType.Error, false, "No marker timeout or distance defined in marker XML " + fileName);
                            return(false);
                        }
                        if (EndingPosition != Double.PositiveInfinity)
                        {
                            if (Math.Abs(EndingPosition) == EndingPosition)
                            {
                                //Positive
                                EndingPosition = StartingPosition + EndingPosition;
                            }
                            else
                            {
                                //Negative
                                EndingPosition    = StartingPosition;
                                StartingPosition -= EndingPosition;
                            }
                        }
                        TextureMessage t = new TextureMessage(Plugin.CurrentHost);
                        GeneralMessage m = new GeneralMessage();
                        //Add variants

                        if (EarlyDefined)
                        {
                            if (iM)
                            {
                                if (EarlyTexture != null)
                                {
                                    t.MessageEarlyTime    = EarlyTime;
                                    t.MessageEarlyTexture = EarlyTexture;
                                }
                                else
                                {
                                    Plugin.CurrentHost.AddMessage(MessageType.Warning, false, "An early time was defined, but no message was specified in MarkerXML " + fileName);
                                }
                            }
                            else
                            {
                                if (EarlyText != null)
                                {
                                    m.MessageEarlyTime  = EarlyTime;
                                    m.MessageEarlyText  = EarlyText;
                                    m.MessageEarlyColor = EarlyColor;
                                }
                                else
                                {
                                    Plugin.CurrentHost.AddMessage(MessageType.Warning, false, "An early time was defined, but no message was specified in MarkerXML " + fileName);
                                }
                            }
                        }
                        if (LateDefined)
                        {
                            if (iM)
                            {
                                if (LateTexture != null)
                                {
                                    t.MessageLateTime    = LateTime;
                                    t.MessageLateTexture = LateTexture;
                                }
                                else
                                {
                                    Plugin.CurrentHost.AddMessage(MessageType.Warning, false, "A late time was defined, but no message was specified in MarkerXML " + fileName);
                                }
                            }
                            else
                            {
                                if (LateText != null)
                                {
                                    m.MessageLateTime  = LateTime;
                                    m.MessageLateText  = LateText;
                                    m.MessageLateColor = LateColor;
                                }
                                else
                                {
                                    Plugin.CurrentHost.AddMessage(MessageType.Warning, false, "An early time was defined, but no message was specified in MarkerXML " + fileName);
                                }
                            }
                        }
                        //Final on-time message
                        if (iM)
                        {
                            t.Trains = Trains;
                            if (Texture != null)
                            {
                                t.MessageOnTimeTexture = Texture;
                            }
                        }
                        else
                        {
                            m.Trains = Trains;
                            if (Text != null)
                            {
                                m.MessageOnTimeText = Text;
                                m.Color             = OnTimeColor;
                            }
                        }
                        if (iM)
                        {
                            Message = t;
                        }
                        else
                        {
                            Message = m;
                        }
                    }
                }
            }
            Marker = new Marker(StartingPosition, EndingPosition, Message);
            return(true);
        }
Example #2
0
        // parse route for data
        private void ParseRouteForData(string FileName, System.Text.Encoding Encoding, Expression[] Expressions, double[] UnitOfLength, ref RouteData Data, bool PreviewOnly)
        {
            CurrentStation = -1;
            CurrentStop    = -1;
            CurrentSection = 0;

            string Section = ""; bool SectionAlwaysPrefix = false;
            int    BlockIndex = 0;

            CurrentRoute.Stations = new RouteStation[] { };
            Data.RequestStops     = new StopRequest[] { };
            double progressFactor = Expressions.Length == 0 ? 0.3333 : 0.3333 / Expressions.Length;

            // process non-track namespaces
            //Check for any special-cased fixes we might need
            CheckForAvailablePatch(FileName, ref Data, ref Expressions, PreviewOnly);
            //Apply parameters to object loaders
            if (!PreviewOnly)
            {
                for (int i = 0; i < Plugin.CurrentHost.Plugins.Length; i++)
                {
                    if (Plugin.CurrentHost.Plugins[i].Object != null)
                    {
                        EnabledHacks.BveTsHacks        = Plugin.CurrentOptions.EnableBveTsHacks;
                        EnabledHacks.BlackTransparency = true;
                        Plugin.CurrentHost.Plugins[i].Object.SetCompatibilityHacks(EnabledHacks);
                        //Remember that these will be ignored if not the correct plugin
                        Plugin.CurrentHost.Plugins[i].Object.SetObjectParser(Plugin.CurrentOptions.CurrentXParser);
                        Plugin.CurrentHost.Plugins[i].Object.SetObjectParser(Plugin.CurrentOptions.CurrentObjParser);
                    }
                }
            }

            for (int j = 0; j < Expressions.Length; j++)
            {
                Plugin.CurrentProgress = j * progressFactor;
                if ((j & 255) == 0)
                {
                    System.Threading.Thread.Sleep(1);
                    if (Plugin.Cancel)
                    {
                        Plugin.IsLoading = false;
                        return;
                    }
                }
                if (Expressions[j].Text.StartsWith("[") && Expressions[j].Text.EndsWith("]"))
                {
                    Section = Expressions[j].Text.Substring(1, Expressions[j].Text.Length - 2).Trim(new char[] { });
                    if (string.Compare(Section, "object", StringComparison.OrdinalIgnoreCase) == 0)
                    {
                        Section = "Structure";
                    }
                    else if (string.Compare(Section, "railway", StringComparison.OrdinalIgnoreCase) == 0)
                    {
                        Section = "Track";
                    }
                    SectionAlwaysPrefix = true;
                }
                else
                {
                    // find equals
                    if (IsRW)
                    {
                        Expressions[j].ConvertRwToCsv(Section, SectionAlwaysPrefix);
                    }

                    // separate command and arguments
                    string Command, ArgumentSequence;
                    Expressions[j].SeparateCommandsAndArguments(out Command, out ArgumentSequence, Culture, false, IsRW, Section);
                    // process command
                    bool NumberCheck = !IsRW || string.Compare(Section, "track", StringComparison.OrdinalIgnoreCase) == 0;
                    if (NumberCheck && NumberFormats.IsValidDouble(Command, UnitOfLength))
                    {
                        // track position (ignored)
                    }
                    else
                    {
                        string[] Arguments = SplitArguments(ArgumentSequence);

                        // preprocess command
                        if (Command.ToLowerInvariant() == "with")
                        {
                            if (Arguments.Length >= 1)
                            {
                                Section             = Arguments[0];
                                SectionAlwaysPrefix = false;
                            }
                            else
                            {
                                Section             = "";
                                SectionAlwaysPrefix = false;
                            }
                            Command = null;
                        }
                        else
                        {
                            if (Command.StartsWith("."))
                            {
                                Command = Section + Command;
                            }
                            else if (SectionAlwaysPrefix)
                            {
                                Command = Section + "." + Command;
                            }
                            Command = Command.Replace(".Void", "");
                            if (Command.StartsWith("structure", StringComparison.OrdinalIgnoreCase) && Command.EndsWith(".load", StringComparison.OrdinalIgnoreCase))
                            {
                                Command = Command.Substring(0, Command.Length - 5).TrimEnd(new char[] { });
                            }
                            else if (Command.StartsWith("texture.background", StringComparison.OrdinalIgnoreCase) && Command.EndsWith(".load", StringComparison.OrdinalIgnoreCase))
                            {
                                Command = Command.Substring(0, Command.Length - 5).TrimEnd(new char[] { });
                            }
                            else if (Command.StartsWith("texture.background", StringComparison.OrdinalIgnoreCase) && Command.EndsWith(".x", StringComparison.OrdinalIgnoreCase))
                            {
                                Command = "texture.backgroundx" + Command.Substring(18, Command.Length - 20).TrimEnd(new char[] { });
                            }
                            else if (Command.StartsWith("texture.background", StringComparison.OrdinalIgnoreCase) && Command.EndsWith(".aspect", StringComparison.OrdinalIgnoreCase))
                            {
                                Command = "texture.backgroundaspect" + Command.Substring(18, Command.Length - 25).TrimEnd(new char[] { });
                            }
                            else if (Command.StartsWith("structure.back", StringComparison.OrdinalIgnoreCase) && Command.EndsWith(".x", StringComparison.OrdinalIgnoreCase))
                            {
                                Command = "texture.backgroundx" + Command.Substring(14, Command.Length - 16).TrimEnd(new char[] { });
                            }
                            else if (Command.StartsWith("structure.back", StringComparison.OrdinalIgnoreCase) && Command.EndsWith(".aspect", StringComparison.OrdinalIgnoreCase))
                            {
                                Command = "texture.backgroundaspect" + Command.Substring(14, Command.Length - 21).TrimEnd(new char[] { });
                            }
                            else if (Command.StartsWith("cycle", StringComparison.OrdinalIgnoreCase) && Command.EndsWith(".params", StringComparison.OrdinalIgnoreCase))
                            {
                                Command = Command.Substring(0, Command.Length - 7).TrimEnd(new char[] { });
                            }
                            else if (Command.StartsWith("signal", StringComparison.OrdinalIgnoreCase) && Command.EndsWith(".load", StringComparison.OrdinalIgnoreCase))
                            {
                                Command = Command.Substring(0, Command.Length - 5).TrimEnd(new char[] { });
                            }
                            else if (Command.StartsWith("train.run", StringComparison.OrdinalIgnoreCase) && Command.EndsWith(".set", StringComparison.OrdinalIgnoreCase))
                            {
                                Command = Command.Substring(0, Command.Length - 4).TrimEnd(new char[] { });
                            }
                            else if (Command.StartsWith("train.flange", StringComparison.OrdinalIgnoreCase) && Command.EndsWith(".set", StringComparison.OrdinalIgnoreCase))
                            {
                                Command = Command.Substring(0, Command.Length - 4).TrimEnd(new char[] { });
                            }
                            else if (Command.StartsWith("train.timetable", StringComparison.OrdinalIgnoreCase) && Command.EndsWith(".day.load", StringComparison.OrdinalIgnoreCase))
                            {
                                Command = "train.timetable.day" + Command.Substring(15, Command.Length - 24).Trim(new char[] { });
                            }
                            else if (Command.StartsWith("train.timetable", StringComparison.OrdinalIgnoreCase) && Command.EndsWith(".night.load", StringComparison.OrdinalIgnoreCase))
                            {
                                Command = "train.timetable.night" + Command.Substring(15, Command.Length - 26).Trim(new char[] { });
                            }
                            else if (Command.StartsWith("train.timetable", StringComparison.OrdinalIgnoreCase) && Command.EndsWith(".day", StringComparison.OrdinalIgnoreCase))
                            {
                                Command = "train.timetable.day" + Command.Substring(15, Command.Length - 19).Trim(new char[] { });
                            }
                            else if (Command.StartsWith("train.timetable", StringComparison.OrdinalIgnoreCase) && Command.EndsWith(".night", StringComparison.OrdinalIgnoreCase))
                            {
                                Command = "train.timetable.night" + Command.Substring(15, Command.Length - 21).Trim(new char[] { });
                            }
                            else if (Command.StartsWith("route.signal", StringComparison.OrdinalIgnoreCase) && Command.EndsWith(".set", StringComparison.OrdinalIgnoreCase))
                            {
                                Command = Command.Substring(0, Command.Length - 4).TrimEnd(new char[] { });
                            }
                            else if (Command.StartsWith("route.runinterval", StringComparison.OrdinalIgnoreCase))
                            {
                                Command = "train.interval" + Command.Substring(17, Command.Length - 17);
                            }
                            else if (Command.StartsWith("train.gauge", StringComparison.OrdinalIgnoreCase))
                            {
                                Command = "route.gauge" + Command.Substring(11, Command.Length - 11);
                            }
                            else if (Command.StartsWith("texture.", StringComparison.OrdinalIgnoreCase))
                            {
                                Command = "structure." + Command.Substring(8, Command.Length - 8);
                            }
                            //Needed after the initial processing to make the enum parse work
                            Command = Command.Replace("timetable.day", "timetableday");
                            Command = Command.Replace("timetable.night", "timetablenight");
                        }

                        int[] commandIndices = FindIndices(ref Command, Expressions[j]);

                        // process command
                        if (!string.IsNullOrEmpty(Command))
                        {
                            int    period    = Command.IndexOf('.');
                            string nameSpace = string.Empty;
                            if (period != -1)
                            {
                                nameSpace = Command.Substring(0, period).ToLowerInvariant();
                                Command   = Command.Substring(period + 1);
                            }
                            Command = Command.ToLowerInvariant();

                            switch (nameSpace)
                            {
                            case "options":
                                OptionsCommand parsedOptionCommand;
                                if (Enum.TryParse(Command, true, out parsedOptionCommand))
                                {
                                    ParseOptionCommand(parsedOptionCommand, Arguments, UnitOfLength, Expressions[j], ref Data, PreviewOnly);
                                }
                                else
                                {
                                    Plugin.CurrentHost.AddMessage(MessageType.Error, false, "Unrecognised command " + Command + " encountered in the Options namespace at line " + Expressions[j].Line.ToString(Culture) + ", column " + Expressions[j].Column.ToString(Culture) + " in file " + Expressions[j].File);
                                }
                                break;

                            case "route":
                                RouteCommand parsedRouteCommand;
                                if (Enum.TryParse(Command, true, out parsedRouteCommand))
                                {
                                    ParseRouteCommand(parsedRouteCommand, Arguments, commandIndices[0], FileName, UnitOfLength, Expressions[j], ref Data, PreviewOnly);
                                }
                                else
                                {
                                    Plugin.CurrentHost.AddMessage(MessageType.Error, false, "Unrecognised command " + Command + " encountered in the Route namespace at line " + Expressions[j].Line.ToString(Culture) + ", column " + Expressions[j].Column.ToString(Culture) + " in file " + Expressions[j].File);
                                }
                                break;

                            case "train":
                                TrainCommand parsedTrainCommand;
                                if (Enum.TryParse(Command.Split(' ')[0], true, out parsedTrainCommand))
                                {
                                    ParseTrainCommand(parsedTrainCommand, Arguments, commandIndices[0], Expressions[j], ref Data, PreviewOnly);
                                }
                                else
                                {
                                    Plugin.CurrentHost.AddMessage(MessageType.Error, false, "Unrecognised command " + Command + " encountered in the Train namespace at line " + Expressions[j].Line.ToString(Culture) + ", column " + Expressions[j].Column.ToString(Culture) + " in file " + Expressions[j].File);
                                }
                                break;

                            case "structure":
                            case "texture":
                                StructureCommand parsedStructureCommand;
                                if (Enum.TryParse(Command, true, out parsedStructureCommand))
                                {
                                    ParseStructureCommand(parsedStructureCommand, Arguments, commandIndices, Encoding, Expressions[j], ref Data, PreviewOnly);
                                }
                                else
                                {
                                    Plugin.CurrentHost.AddMessage(MessageType.Error, false, "Unrecognised command " + Command + " encountered in the Structure namespace at line " + Expressions[j].Line.ToString(Culture) + ", column " + Expressions[j].Column.ToString(Culture) + " in file " + Expressions[j].File);
                                }
                                break;

                            case "":
                                ParseSignalCommand(Command, Arguments, commandIndices[0], Encoding, Expressions[j], ref Data, PreviewOnly);
                                break;

                            case "cycle":
                                CycleCommand parsedCycleCommand;
                                if (Enum.TryParse(Command, true, out parsedCycleCommand))
                                {
                                    ParseCycleCommand(parsedCycleCommand, Arguments, commandIndices[0], Expressions[j], ref Data, PreviewOnly);
                                }
                                else
                                {
                                    Plugin.CurrentHost.AddMessage(MessageType.Error, false, "Unrecognised command " + Command + " encountered in the Cycle namespace at line " + Expressions[j].Line.ToString(Culture) + ", column " + Expressions[j].Column.ToString(Culture) + " in file " + Expressions[j].File);
                                }
                                break;

                            case "track":
                                break;

                            // ReSharper disable once RedundantEmptySwitchSection
                            default:
                                /*
                                 * This needs an unrecognised command at some stage
                                 */
                                break;
                            }
                        }
                    }
                }
            }

            // process track namespace
            for (int j = 0; j < Expressions.Length; j++)
            {
                Plugin.CurrentProgress = 0.3333 + j * progressFactor;
                if ((j & 255) == 0)
                {
                    System.Threading.Thread.Sleep(1);
                    if (Plugin.Cancel)
                    {
                        Plugin.IsLoading = false;
                        return;
                    }
                }
                if (Data.LineEndingFix)
                {
                    if (Expressions[j].Text.EndsWith("_"))
                    {
                        Expressions[j].Text = Expressions[j].Text.Substring(0, Expressions[j].Text.Length - 1).Trim(new char[] { });
                    }
                }
                if (Expressions[j].Text.StartsWith("[") && Expressions[j].Text.EndsWith("]"))
                {
                    Section = Expressions[j].Text.Substring(1, Expressions[j].Text.Length - 2).Trim(new char[] { });
                    if (string.Compare(Section, "object", StringComparison.OrdinalIgnoreCase) == 0)
                    {
                        Section = "Structure";
                    }
                    else if (string.Compare(Section, "railway", StringComparison.OrdinalIgnoreCase) == 0)
                    {
                        Section = "Track";
                    }
                    SectionAlwaysPrefix = true;
                }
                else
                {
                    if (IsRW)
                    {
                        Expressions[j].ConvertRwToCsv(Section, SectionAlwaysPrefix);
                    }
                    // separate command and arguments
                    string Command, ArgumentSequence;
                    Expressions[j].SeparateCommandsAndArguments(out Command, out ArgumentSequence, Culture, false, IsRW, Section);
                    // process command
                    double currentTrackPosition;
                    bool   NumberCheck = !IsRW || string.Compare(Section, "track", StringComparison.OrdinalIgnoreCase) == 0;
                    if (NumberCheck && NumberFormats.TryParseDouble(Command, UnitOfLength, out currentTrackPosition))
                    {
                        // track position
                        if (ArgumentSequence.Length != 0)
                        {
                            Plugin.CurrentHost.AddMessage(MessageType.Error, false, "A track position must not contain any arguments at line " + Expressions[j].Line.ToString(Culture) + ", column " + Expressions[j].Column.ToString(Culture) + " in file " + Expressions[j].File);
                            if (AllowTrackPositionArguments)
                            {
                                Data.TrackPosition = currentTrackPosition;
                                BlockIndex         = (int)Math.Floor(currentTrackPosition / Data.BlockInterval + 0.001);
                                if (Data.FirstUsedBlock == -1)
                                {
                                    Data.FirstUsedBlock = BlockIndex;
                                }
                                Data.CreateMissingBlocks(BlockIndex, PreviewOnly);
                            }
                        }
                        else if (currentTrackPosition < 0.0)
                        {
                            Plugin.CurrentHost.AddMessage(MessageType.Error, false, "Negative track position encountered at line " + Expressions[j].Line.ToString(Culture) + ", column " + Expressions[j].Column.ToString(Culture) + " in file " + Expressions[j].File);
                        }
                        else
                        {
                            if (Plugin.CurrentOptions.EnableBveTsHacks && IsRW && currentTrackPosition == 4535545100)
                            {
                                //WMATA Red line has an erroneous track position causing an out of memory cascade
                                currentTrackPosition = 45355;
                            }
                            Data.TrackPosition = currentTrackPosition;
                            BlockIndex         = (int)Math.Floor(currentTrackPosition / Data.BlockInterval + 0.001);
                            if (Data.FirstUsedBlock == -1)
                            {
                                Data.FirstUsedBlock = BlockIndex;
                            }
                            Data.CreateMissingBlocks(BlockIndex, PreviewOnly);
                        }
                    }
                    else
                    {
                        string[] Arguments = SplitArguments(ArgumentSequence);

                        // preprocess command
                        if (Command.ToLowerInvariant() == "with")
                        {
                            if (Arguments.Length >= 1)
                            {
                                Section             = Arguments[0];
                                SectionAlwaysPrefix = false;
                            }
                            else
                            {
                                Section             = "";
                                SectionAlwaysPrefix = false;
                            }
                            Command = null;
                        }
                        else
                        {
                            if (Command.StartsWith("."))
                            {
                                Command = Section + Command;
                            }
                            else if (SectionAlwaysPrefix)
                            {
                                Command = Section + "." + Command;
                            }
                            Command = Command.Replace(".Void", "");
                        }

                        // process command
                        if (!string.IsNullOrEmpty(Command))
                        {
                            int    period    = Command.IndexOf('.');
                            string nameSpace = string.Empty;
                            if (period != -1)
                            {
                                nameSpace = Command.Substring(0, period).ToLowerInvariant();
                                Command   = Command.Substring(period + 1);
                            }
                            if (nameSpace.StartsWith("signal", StringComparison.InvariantCultureIgnoreCase))
                            {
                                nameSpace = "";
                            }
                            Command = Command.ToLowerInvariant();

                            switch (nameSpace)
                            {
                            case "track":
                                TrackCommand parsedCommand;
                                if (Enum.TryParse(Command, true, out parsedCommand))
                                {
                                    ParseTrackCommand(parsedCommand, Arguments, FileName, UnitOfLength, Expressions[j], ref Data, BlockIndex, PreviewOnly);
                                }
                                else
                                {
                                    Plugin.CurrentHost.AddMessage(MessageType.Error, false, "Unrecognised command " + Command + " encountered in the Route namespace at line " + Expressions[j].Line.ToString(Culture) + ", column " + Expressions[j].Column.ToString(Culture) + " in file " + Expressions[j].File);
                                }
                                break;

                            case "options":
                            case "route":
                            case "train":
                            case "structure":
                            case "texture":
                            case "":
                            case "cycle":
                                break;

                            default:
                                Plugin.CurrentHost.AddMessage(MessageType.Warning, false, "The command " + Command + " is not supported at line " + Expressions[j].Line.ToString(Culture) + ", column " + Expressions[j].Column.ToString(Culture) + " in file " + Expressions[j].File);
                                break;
                            }
                        }
                    }
                }
            }
        }
Example #3
0
        private void PreprocessSortByTrackPosition(double[] UnitFactors, ref Expression[] Expressions)
        {
            PositionedExpression[] p = new PositionedExpression[Expressions.Length];
            int    n           = 0;
            double a           = -1.0;
            bool   NumberCheck = !IsRW;

            for (int i = 0; i < Expressions.Length; i++)
            {
                if (IsRW)
                {
                    // only check for track positions in the railway section for RW routes
                    if (Expressions[i].Text.StartsWith("[", StringComparison.Ordinal) & Expressions[i].Text.EndsWith("]", StringComparison.Ordinal))
                    {
                        string s = Expressions[i].Text.Substring(1, Expressions[i].Text.Length - 2).Trim(new char[] { });
                        NumberCheck = string.Compare(s, "Railway", StringComparison.OrdinalIgnoreCase) == 0;
                    }
                }
                double x;
                if (NumberCheck && NumberFormats.TryParseDouble(Expressions[i].Text, UnitFactors, out x))
                {
                    x += Expressions[i].TrackPositionOffset;
                    if (x >= 0.0)
                    {
                        if (Plugin.CurrentOptions.EnableBveTsHacks)
                        {
                            switch (System.IO.Path.GetFileName(Expressions[i].File.ToLowerInvariant()))
                            {
                            case "balloch - dumbarton central special nighttime run.csv":
                            case "balloch - dumbarton central summer 2004 morning run.csv":
                                if (x != 0 || a != 4125)
                                {
                                    //Misplaced comma in the middle of the line causes this to be interpreted as a track position
                                    a = x;
                                }
                                break;

                            default:
                                a = x;
                                break;
                            }
                        }
                        else
                        {
                            a = x;
                        }
                    }
                    else
                    {
                        Plugin.CurrentHost.AddMessage(MessageType.Error, false, "Negative track position encountered at line " + Expressions[i].Line.ToString(Culture) + ", column " + Expressions[i].Column.ToString(Culture) + " in file " + Expressions[i].File);
                    }
                }
                else
                {
                    p[n].TrackPosition = a;
                    p[n].Expression    = Expressions[i];
                    int j = n;
                    n++;
                    while (j > 0)
                    {
                        if (p[j].TrackPosition < p[j - 1].TrackPosition)
                        {
                            PositionedExpression t = p[j];
                            p[j]     = p[j - 1];
                            p[j - 1] = t;
                            j--;
                        }
                        else
                        {
                            break;
                        }
                    }
                }
            }
            a = -1.0;
            Expression[] e = new Expression[Expressions.Length];
            int          m = 0;

            for (int i = 0; i < n; i++)
            {
                if (p[i].TrackPosition != a)
                {
                    a    = p[i].TrackPosition;
                    e[m] = new Expression(string.Empty, (a / UnitFactors[UnitFactors.Length - 1]).ToString(Culture), -1, -1, -1);
                    m++;
                }
                e[m] = p[i].Expression;
                m++;
            }
            Array.Resize(ref e, m);
            Expressions = e;
        }
Example #4
0
        public static bool ReadMarkerXML(string fileName, ref CsvRwRouteParser.Marker marker)
        {
            //The current XML file to load
            XmlDocument currentXML = new XmlDocument();

            //Load the marker's XML file
            currentXML.Load(fileName);
            string Path = System.IO.Path.GetDirectoryName(fileName);

            if (currentXML.DocumentElement != null)
            {
                bool        iM            = false;
                XmlNodeList DocumentNodes = currentXML.DocumentElement.SelectNodes("/openBVE/TextMarker");

                if (DocumentNodes == null || DocumentNodes.Count == 0)
                {
                    DocumentNodes = currentXML.DocumentElement.SelectNodes("/openBVE/ImageMarker");
                    iM            = true;
                }
                if (DocumentNodes == null || DocumentNodes.Count == 0)
                {
                    Interface.AddMessage(Interface.MessageType.Error, false, "No marker nodes defined in XML file " + fileName);
                    return(false);
                }
                marker = new CsvRwRouteParser.Marker();
                foreach (XmlNode n in DocumentNodes)
                {
                    if (n.HasChildNodes)
                    {
                        bool             EarlyDefined = false, LateDefined = false;
                        string           EarlyText = null, Text = null, LateText = null;
                        string[]         Trains = null;
                        Textures.Texture EarlyTexture = null, Texture = null, LateTexture = null;
                        double           EarlyTime = 0.0, LateTime = 0.0, TimeOut = Double.PositiveInfinity, EndingPosition = Double.PositiveInfinity;
                        OpenBveApi.Colors.MessageColor EarlyColor = MessageColor.White, OnTimeColor = MessageColor.White, LateColor = MessageColor.White;
                        foreach (XmlNode c in n.ChildNodes)
                        {
                            switch (c.Name.ToLowerInvariant())
                            {
                            case "early":
                                if (!c.HasChildNodes)
                                {
                                    Interface.AddMessage(Interface.MessageType.Error, false,
                                                         "No paramaters defined for the early message in " + fileName);
                                }
                                foreach (XmlNode cc in c.ChildNodes)
                                {
                                    switch (cc.Name.ToLowerInvariant())
                                    {
                                    case "text":
                                        EarlyText = cc.InnerText;
                                        break;

                                    case "texture":
                                        var f = OpenBveApi.Path.CombineFile(Path, cc.InnerText);
                                        if (System.IO.File.Exists(f))
                                        {
                                            if (!Textures.RegisterTexture(f, out EarlyTexture))
                                            {
                                                Interface.AddMessage(Interface.MessageType.Error, false, "Loading MessageEarlyTexture " + f + " failed.");
                                            }
                                        }
                                        else
                                        {
                                            Interface.AddMessage(Interface.MessageType.Error, false, "MessageEarlyTexture " + f + " does not exist.");
                                        }
                                        break;

                                    case "time":
                                        if (!Interface.TryParseTime(cc.InnerText, out EarlyTime))
                                        {
                                            Interface.AddMessage(Interface.MessageType.Error, false, "Early message time invalid in " + fileName);
                                        }
                                        EarlyDefined = true;
                                        break;

                                    case "color":
                                        EarlyColor = ParseColor(cc.InnerText, fileName);
                                        break;
                                    }
                                }
                                break;

                            case "ontime":
                                if (!c.HasChildNodes)
                                {
                                    Interface.AddMessage(Interface.MessageType.Error, false,
                                                         "No paramaters defined for the on-time message in " + fileName);
                                }
                                foreach (XmlNode cc in c.ChildNodes)
                                {
                                    switch (cc.Name.ToLowerInvariant())
                                    {
                                    case "text":
                                        Text = cc.InnerText;
                                        break;

                                    case "texture":
                                        var f = OpenBveApi.Path.CombineFile(Path, cc.InnerText);
                                        if (System.IO.File.Exists(f))
                                        {
                                            if (!Textures.RegisterTexture(f, out Texture))
                                            {
                                                Interface.AddMessage(Interface.MessageType.Error, false, "Loading MessageTexture " + f + " failed.");
                                            }
                                        }
                                        else
                                        {
                                            Interface.AddMessage(Interface.MessageType.Error, false, "MessageTexture " + f + " does not exist.");
                                        }
                                        break;

                                    case "color":
                                        OnTimeColor = ParseColor(cc.InnerText, fileName);
                                        break;
                                    }
                                }
                                break;

                            case "late":
                                if (!c.HasChildNodes)
                                {
                                    Interface.AddMessage(Interface.MessageType.Error, false,
                                                         "No paramaters defined for the late message in " + fileName);
                                }

                                foreach (XmlNode cc in c.ChildNodes)
                                {
                                    switch (cc.Name.ToLowerInvariant())
                                    {
                                    case "text":
                                        LateText = cc.InnerText;
                                        break;

                                    case "texture":
                                        var f = OpenBveApi.Path.CombineFile(Path, cc.InnerText);
                                        if (System.IO.File.Exists(f))
                                        {
                                            if (!Textures.RegisterTexture(f, out LateTexture))
                                            {
                                                Interface.AddMessage(Interface.MessageType.Error, false, "Loading MessageLateTexture " + f + " failed.");
                                            }
                                        }
                                        else
                                        {
                                            Interface.AddMessage(Interface.MessageType.Error, false, "MessageLateTexture " + f + " does not exist.");
                                        }
                                        break;

                                    case "time":
                                        if (!Interface.TryParseTime(cc.InnerText, out LateTime))
                                        {
                                            Interface.AddMessage(Interface.MessageType.Error, false, "Early message time invalid in " + fileName);
                                        }
                                        LateDefined = true;
                                        break;

                                    case "color":
                                        LateColor = ParseColor(cc.InnerText, fileName);
                                        break;
                                    }
                                }
                                break;

                            case "timeout":
                                if (!NumberFormats.TryParseDouble(c.InnerText, new[] { 1.0 }, out TimeOut))
                                {
                                    Interface.AddMessage(Interface.MessageType.Error, false, "Marker timeout invalid in " + fileName);
                                }
                                break;

                            case "distance":
                                if (!NumberFormats.TryParseDouble(c.InnerText, new[] { 1.0 }, out EndingPosition))
                                {
                                    Interface.AddMessage(Interface.MessageType.Error, false, "Marker distance invalid in " + fileName);
                                }
                                break;

                            case "trains":
                                Trains = c.InnerText.Split(';');
                                break;
                            }
                        }
                        //Check this marker is valid
                        if (TimeOut == Double.PositiveInfinity && EndingPosition == Double.PositiveInfinity)
                        {
                            Interface.AddMessage(Interface.MessageType.Error, false, "No marker timeout or distance defined in marker XML " + fileName);
                            return(false);
                        }
                        if (EndingPosition != Double.PositiveInfinity)
                        {
                            marker.EndingPosition = EndingPosition;
                        }
                        MessageManager.TextureMessage t = new MessageManager.TextureMessage();
                        MessageManager.GeneralMessage m = new MessageManager.GeneralMessage();
                        //Add variants

                        if (EarlyDefined)
                        {
                            if (iM)
                            {
                                if (EarlyTexture != null)
                                {
                                    t.MessageEarlyTime    = EarlyTime;
                                    t.MessageEarlyTexture = EarlyTexture;
                                }
                                else
                                {
                                    Interface.AddMessage(Interface.MessageType.Warning, false, "An early time was defined, but no message was specified in MarkerXML " + fileName);
                                }
                            }
                            else
                            {
                                if (EarlyText != null)
                                {
                                    m.MessageEarlyTime = EarlyTime;
                                    m.MessageEarlyText = EarlyText;
                                    m.MessageColor     = EarlyColor;
                                }
                                else
                                {
                                    Interface.AddMessage(Interface.MessageType.Warning, false, "An early time was defined, but no message was specified in MarkerXML " + fileName);
                                }
                            }
                        }
                        if (LateDefined)
                        {
                            if (iM)
                            {
                                if (LateTexture != null)
                                {
                                    t.MessageLateTime    = LateTime;
                                    t.MessageLateTexture = LateTexture;
                                }
                                else
                                {
                                    Interface.AddMessage(Interface.MessageType.Warning, false, "A late time was defined, but no message was specified in MarkerXML " + fileName);
                                }
                            }
                            else
                            {
                                if (LateText != null)
                                {
                                    m.MessageLateTime  = LateTime;
                                    m.MessageLateText  = LateText;
                                    m.MessageLateColor = LateColor;
                                }
                                else
                                {
                                    Interface.AddMessage(Interface.MessageType.Warning, false, "An early time was defined, but no message was specified in MarkerXML " + fileName);
                                }
                            }
                        }
                        //Final on-time message
                        if (iM)
                        {
                            t.Trains = Trains;
                            if (Texture != null)
                            {
                                t.MessageOnTimeTexture = Texture;
                            }
                        }
                        else
                        {
                            m.Trains = Trains;
                            if (Text != null)
                            {
                                m.MessageOnTimeText = Text;
                                m.Color             = OnTimeColor;
                            }
                        }
                        if (iM)
                        {
                            marker.Message = t;
                        }
                        else
                        {
                            marker.Message = m;
                        }
                    }
                }
            }
            return(true);
        }