diff --git a/YARG.Core/IO/DTA/DTAEntry.cs b/YARG.Core/IO/DTA/DTAEntry.cs index a0c856950..c0a38dd93 100644 --- a/YARG.Core/IO/DTA/DTAEntry.cs +++ b/YARG.Core/IO/DTA/DTAEntry.cs @@ -52,6 +52,8 @@ public class DTAEntry public long? HopoThreshold; public Encoding Encoding; + public bool DiscUpdate; + public RBCONDifficulties Difficulties = RBCONDifficulties.Default; public DTAEntry(Encoding encoding) @@ -279,7 +281,11 @@ string Convert(string str) StringBuilder authors = new(); foreach (string str in YARGDTAReader.ExtractArray_String(ref container)) { - if (str != "disc_update") + if (str == "disc_update") + { + DiscUpdate = true; + } + else { if (authors.Length == 0 && Charter == SongMetadata.DEFAULT_CHARTER) { diff --git a/YARG.Core/IO/DTA/YARGDTAReader.cs b/YARG.Core/IO/DTA/YARGDTAReader.cs index a2808836d..94c264b82 100644 --- a/YARG.Core/IO/DTA/YARGDTAReader.cs +++ b/YARG.Core/IO/DTA/YARGDTAReader.cs @@ -284,23 +284,20 @@ public static void EndNode(ref YARGTextContainer container) break; } } - else if (textState != TextScopeState.Quotes) + else if (textState == TextScopeState.None) { - if (textState != TextScopeState.Apostrophes) + switch (curr) { - switch (curr) - { - case '(': ++scopeLevel; break; - case ')': --scopeLevel; break; - case '\'': textState = TextScopeState.Apostrophes; break; - case ';': textState = TextScopeState.Comment; break; - } - } - else if (curr == '\'') - { - textState = TextScopeState.None; + case '(': ++scopeLevel; break; + case ')': --scopeLevel; break; + case '\'': textState = TextScopeState.Apostrophes; break; + case ';': textState = TextScopeState.Comment; break; } } + else if (textState == TextScopeState.Apostrophes && curr == '\'') + { + textState = TextScopeState.None; + } } SkipWhitespace(ref container); } diff --git a/YARG.Core/MoonscraperChartParser/IO/Chart/ChartReader.cs b/YARG.Core/MoonscraperChartParser/IO/Chart/ChartReader.cs index 2cba6960b..291989951 100644 --- a/YARG.Core/MoonscraperChartParser/IO/Chart/ChartReader.cs +++ b/YARG.Core/MoonscraperChartParser/IO/Chart/ChartReader.cs @@ -174,30 +174,44 @@ static int GetLineCount(ReadOnlySpan chartText, int startIndex, int relati var search = chartText[index..]; - // Find section name - int nameStartIndex = search.IndexOf('['); - int nameEndIndex = search.IndexOf(']'); - if (nameStartIndex < 0) - // No more sections present - return false; - - if (nameEndIndex < 0) + int nameStartIndex; + while (true) { - int startLine = GetLineCount(chartText, index, nameStartIndex); - throw new Exception($"Missing end bracket for section name on line {startLine}!"); + nameStartIndex = search.IndexOf('['); + if (nameStartIndex < 0) + { + // No more sections present + return false; + } + + int test = nameStartIndex++; + while (test > 0) + { + --test; + if (search[test] > 32 || search[test] == '\n') + { + break; + } + } + + index += nameStartIndex; + + var curr = search[test]; + search = search[nameStartIndex..]; + if (test == 0 || curr == '\n') + { + break; + } } - if (nameEndIndex < nameStartIndex) + int nameEndIndex = search.IndexOf(']'); + if (nameEndIndex < 0) { int startLine = GetLineCount(chartText, index, nameStartIndex); - int endLine = GetLineCount(chartText, index, nameEndIndex); - if (startLine == endLine) - throw new Exception($"Misordered section name brackets on line {startLine}!"); - else - throw new Exception($"Misordered section name brackets! Start bracket on line {startLine}, end on line {endLine}"); + throw new Exception($"Missing end bracket for section name on line {startLine}!"); } - sectionName = search[++nameStartIndex..nameEndIndex]; + sectionName = search[..nameEndIndex++]; search = search[nameEndIndex..]; index += nameEndIndex; @@ -209,28 +223,45 @@ static int GetLineCount(ReadOnlySpan chartText, int startIndex, int relati // Find section body int sectionStartIndex = search.IndexOf('{'); - int sectionEndIndex = search.IndexOf('}'); if (sectionStartIndex < 0) { int startLine = GetLineCount(chartText, index, nameStartIndex); throw new Exception($"Missing section body for section [{sectionName.ToString()}]! (starting on line {startLine})"); } + ++sectionStartIndex; + search = search[sectionStartIndex..]; + index += sectionStartIndex; - if (sectionEndIndex < 0) + int sectionEndIndex = 0; + while (true) { - int startLine = GetLineCount(chartText, index, nameStartIndex); - throw new Exception($"Missing body end bracket for section [{sectionName.ToString()}]! (starting on line {startLine})"); - } + int sectionEndOffset = search[sectionEndIndex..].IndexOf('}'); + if (sectionEndOffset < 0) + { + int startLine = GetLineCount(chartText, index + sectionEndIndex, nameStartIndex); + throw new Exception($"Missing body end bracket for section [{sectionName.ToString()}]! (starting on line {startLine})"); + } - if (sectionEndIndex < sectionStartIndex) - { - int startLine = GetLineCount(chartText, index, sectionStartIndex); - int endLine = GetLineCount(chartText, index, sectionEndIndex); - throw new Exception($"Misordered section body brackets! Start bracket on line {startLine}, end on line {endLine}"); + int test = sectionEndIndex + sectionEndOffset; + while (test > sectionEndIndex) + { + --test; + if (search[test] > 32 || search[test] == '\n') + { + break; + } + } + + sectionEndIndex += sectionEndOffset; + if (test == 0 || search[test] == '\n') + { + break; + } + ++sectionEndIndex; } - sectionBody = search[++sectionStartIndex..sectionEndIndex].SplitTrimmedAscii('\n'); - index += ++sectionEndIndex; + sectionBody = search[sectionStartIndex..sectionEndIndex].SplitTrimmedAscii('\n'); + index += sectionEndIndex + 1; return true; } @@ -365,7 +396,7 @@ private static void SubmitDataGlobals(MoonSong song, AsciiTrimSplitter sectionLi if (typeCodeText[0] == 'E') { // Get event text - var eventText = TextEvents.NormalizeTextEvent(remaining.TrimOnce('"')); + var eventText = TextEvents.NormalizeTextEvent(remaining.TrimOnce('"').Trim()); // Check for section events if (TextEvents.TryParseSectionEvent(eventText, out var sectionName)) diff --git a/YARG.Core/Parsing/TextEvents.cs b/YARG.Core/Parsing/TextEvents.cs index 44df28399..888abec1f 100644 --- a/YARG.Core/Parsing/TextEvents.cs +++ b/YARG.Core/Parsing/TextEvents.cs @@ -1,4 +1,4 @@ -using System; +using System; using YARG.Core.Extensions; namespace YARG.Core.Parsing @@ -62,17 +62,15 @@ public static partial class TextEvents /// All other methods that operate on text events expect them to be normalized. /// // Equivalent to reading the capture of this regex: \[(.*?)\] - public static ReadOnlySpan NormalizeTextEvent(ReadOnlySpan text, out bool strippedBrackets) + public static ReadOnlySpan NormalizeTextEvent(ReadOnlySpan text, out bool hadBrackets) { - // Isolate text inside brackets - strippedBrackets = false; - int startIndex = text.IndexOf('['); - int lastIndex = text.IndexOf(']'); - if (startIndex < 0 || lastIndex < 0 || lastIndex < startIndex) - return text.Trim(); - - strippedBrackets = true; - return text[++startIndex..lastIndex].Trim(); + hadBrackets = text.Length > 0 && text[0] == '[' && text[^1] == ']'; + if (hadBrackets) + { + // Remove brackets + text = text[1..(text.Length - 1)]; + } + return text; } /// diff --git a/YARG.Core/Song/Cache/CacheHandler.cs b/YARG.Core/Song/Cache/CacheHandler.cs index 673f5807d..0923dddb2 100644 --- a/YARG.Core/Song/Cache/CacheHandler.cs +++ b/YARG.Core/Song/Cache/CacheHandler.cs @@ -805,7 +805,7 @@ protected void InitModification(CONModification modification, string name) modification.UpdateDTA.LoadData(name, container); } modification.Midi = update.Midi; - if (modification.Midi == null) + if (modification.Midi == null && modification.UpdateDTA.DiscUpdate) { YargLogger.LogFormatWarning("Update midi expected in directory {0}", Path.Combine(group.Directory, name)); }