From 023a5c6e4faef1cd82bde231af6ed481f89d43c8 Mon Sep 17 00:00:00 2001 From: Tav TaOr Date: Fri, 10 May 2019 19:12:32 +0300 Subject: [PATCH 01/49] Add the ability to ignore the user's mouse movement. --- osu.Game.Rulesets.Osu/OsuInputManager.cs | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/osu.Game.Rulesets.Osu/OsuInputManager.cs b/osu.Game.Rulesets.Osu/OsuInputManager.cs index b9e083d35b..b4cc556ff2 100644 --- a/osu.Game.Rulesets.Osu/OsuInputManager.cs +++ b/osu.Game.Rulesets.Osu/OsuInputManager.cs @@ -18,6 +18,8 @@ namespace osu.Game.Rulesets.Osu set => ((OsuKeyBindingContainer)KeyBindingContainer).AllowUserPresses = value; } + public bool AllowUserCursorMovement { get; set; } = true; + protected override RulesetKeyBindingContainer CreateKeyBindingContainer(RulesetInfo ruleset, int variant, SimultaneousBindingMode unique) => new OsuKeyBindingContainer(ruleset, variant, unique); @@ -26,6 +28,16 @@ namespace osu.Game.Rulesets.Osu { } + protected override bool Handle(UIEvent e) + { + if (!AllowUserCursorMovement && e is MouseMoveEvent) + { + return false; + } + + return base.Handle(e); + } + private class OsuKeyBindingContainer : RulesetKeyBindingContainer { public bool AllowUserPresses = true; From bda0b35d849d15e01cf6ba4cd4ddd97d225e06c2 Mon Sep 17 00:00:00 2001 From: Tav TaOr Date: Fri, 10 May 2019 19:46:13 +0300 Subject: [PATCH 02/49] Slight formating change. --- osu.Game.Rulesets.Osu/OsuInputManager.cs | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/osu.Game.Rulesets.Osu/OsuInputManager.cs b/osu.Game.Rulesets.Osu/OsuInputManager.cs index b4cc556ff2..58e275ba26 100644 --- a/osu.Game.Rulesets.Osu/OsuInputManager.cs +++ b/osu.Game.Rulesets.Osu/OsuInputManager.cs @@ -30,10 +30,7 @@ namespace osu.Game.Rulesets.Osu protected override bool Handle(UIEvent e) { - if (!AllowUserCursorMovement && e is MouseMoveEvent) - { - return false; - } + if (e is MouseMoveEvent && !AllowUserCursorMovement) return false; return base.Handle(e); } From d229fed1287c3d48878ab7e91981cf123fbd429d Mon Sep 17 00:00:00 2001 From: Tav TaOr Date: Sun, 12 May 2019 14:00:43 +0300 Subject: [PATCH 03/49] Implemented Autopilot --- osu.Game.Rulesets.Osu/Mods/OsuModAutopilot.cs | 44 ++++++++++++++++++- 1 file changed, 43 insertions(+), 1 deletion(-) diff --git a/osu.Game.Rulesets.Osu/Mods/OsuModAutopilot.cs b/osu.Game.Rulesets.Osu/Mods/OsuModAutopilot.cs index 401bd28d7c..7c423235fa 100644 --- a/osu.Game.Rulesets.Osu/Mods/OsuModAutopilot.cs +++ b/osu.Game.Rulesets.Osu/Mods/OsuModAutopilot.cs @@ -2,13 +2,19 @@ // See the LICENCE file in the repository root for full licence text. using System; +using System.Collections.Generic; +using System.Linq; using osu.Framework.Graphics.Sprites; +using osu.Framework.Input.StateChanges; using osu.Game.Graphics; using osu.Game.Rulesets.Mods; +using osu.Game.Rulesets.Osu.Objects; +using osu.Game.Rulesets.Osu.Replays; +using osu.Game.Rulesets.UI; namespace osu.Game.Rulesets.Osu.Mods { - public class OsuModAutopilot : Mod + public class OsuModAutopilot : Mod, IApplicableFailOverride, IUpdatableByPlayfield, IApplicableToDrawableRuleset { public override string Name => "Autopilot"; public override string Acronym => "AP"; @@ -17,5 +23,41 @@ namespace osu.Game.Rulesets.Osu.Mods public override string Description => @"Automatic cursor movement - just follow the rhythm."; public override double ScoreMultiplier => 1; public override Type[] IncompatibleMods => new[] { typeof(OsuModSpunOut), typeof(ModRelax), typeof(ModSuddenDeath), typeof(ModNoFail), typeof(ModAutoplay) }; + + public bool AllowFail => false; + + private OsuInputManager inputManager; + + private List replayFrames; + private int frameIndex = 0; + + public void Update(Playfield playfield) + { + // If we are on the last replay frame, no need to do anything + if (frameIndex == replayFrames.Count - 1) + { + return; + } + + // Check if we are closer to the next replay frame then the current one + if (Math.Abs(replayFrames[frameIndex].Time - playfield.Time.Current) >= Math.Abs(replayFrames[frameIndex + 1].Time - playfield.Time.Current)) + { + // If we are, move to the next frame, and update the mouse position + frameIndex++; + new MousePositionAbsoluteInput() { Position = playfield.ToScreenSpace(replayFrames[frameIndex].Position) }.Apply(inputManager.CurrentState, inputManager); + } + + // TODO: Implement the functionality to automatically spin spinners + } + + public void ApplyToDrawableRuleset(DrawableRuleset drawableRuleset) + { + // Grab the input manager to disable the user's cursor, and for future use + inputManager = (OsuInputManager)drawableRuleset.KeyBindingInputManager; + inputManager.AllowUserCursorMovement = false; + + // Generate the replay frames the cursor should follow + replayFrames = new OsuAutoGenerator(drawableRuleset.Beatmap).Generate().Frames.Cast().ToList(); + } } } From 2051be7453ad5c201f0d6e11ecb737a68df1866e Mon Sep 17 00:00:00 2001 From: Tav TaOr Date: Sun, 12 May 2019 15:00:59 +0300 Subject: [PATCH 04/49] Minor changes to pass the AppVeyor test --- osu.Game.Rulesets.Osu/Mods/OsuModAutopilot.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/osu.Game.Rulesets.Osu/Mods/OsuModAutopilot.cs b/osu.Game.Rulesets.Osu/Mods/OsuModAutopilot.cs index 7c423235fa..a9b99f3afe 100644 --- a/osu.Game.Rulesets.Osu/Mods/OsuModAutopilot.cs +++ b/osu.Game.Rulesets.Osu/Mods/OsuModAutopilot.cs @@ -29,7 +29,7 @@ namespace osu.Game.Rulesets.Osu.Mods private OsuInputManager inputManager; private List replayFrames; - private int frameIndex = 0; + private int frameIndex; public void Update(Playfield playfield) { @@ -44,7 +44,7 @@ namespace osu.Game.Rulesets.Osu.Mods { // If we are, move to the next frame, and update the mouse position frameIndex++; - new MousePositionAbsoluteInput() { Position = playfield.ToScreenSpace(replayFrames[frameIndex].Position) }.Apply(inputManager.CurrentState, inputManager); + new MousePositionAbsoluteInput { Position = playfield.ToScreenSpace(replayFrames[frameIndex].Position) }.Apply(inputManager.CurrentState, inputManager); } // TODO: Implement the functionality to automatically spin spinners From dfd7b1111492735a7ecd7aead43163edbee439f6 Mon Sep 17 00:00:00 2001 From: Tav TaOr Date: Sun, 12 May 2019 16:04:37 +0300 Subject: [PATCH 05/49] Changed the unimplemented mod test to use OsuModSpunOut instead of OsuModAutopilot since Autopilot is implemented now. --- osu.Game.Tests/Visual/UserInterface/TestCaseMods.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/osu.Game.Tests/Visual/UserInterface/TestCaseMods.cs b/osu.Game.Tests/Visual/UserInterface/TestCaseMods.cs index fd003c7ea2..7d1242083e 100644 --- a/osu.Game.Tests/Visual/UserInterface/TestCaseMods.cs +++ b/osu.Game.Tests/Visual/UserInterface/TestCaseMods.cs @@ -90,7 +90,7 @@ namespace osu.Game.Tests.Visual.UserInterface var doubleTimeMod = harderMods.OfType().FirstOrDefault(m => m.Mods.Any(a => a is OsuModDoubleTime)); - var autoPilotMod = assistMods.FirstOrDefault(m => m is OsuModAutopilot); + var spunOutMod = easierMods.FirstOrDefault(m => m is OsuModSpunOut); var easy = easierMods.FirstOrDefault(m => m is OsuModEasy); var hardRock = harderMods.FirstOrDefault(m => m is OsuModHardRock); @@ -102,7 +102,7 @@ namespace osu.Game.Tests.Visual.UserInterface testMultiplierTextColour(noFailMod, modSelect.LowMultiplierColour); testMultiplierTextColour(hiddenMod, modSelect.HighMultiplierColour); - testUnimplementedMod(autoPilotMod); + testUnimplementedMod(spunOutMod); } [Test] From fca1b9325d4800edb79f4a24d4c4a82b500046bb Mon Sep 17 00:00:00 2001 From: Tav TaOr Date: Sun, 12 May 2019 16:18:27 +0300 Subject: [PATCH 06/49] Deleted the assistMods variable since it is never used --- osu.Game.Tests/Visual/UserInterface/TestCaseMods.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/osu.Game.Tests/Visual/UserInterface/TestCaseMods.cs b/osu.Game.Tests/Visual/UserInterface/TestCaseMods.cs index 7d1242083e..4fbb12d6df 100644 --- a/osu.Game.Tests/Visual/UserInterface/TestCaseMods.cs +++ b/osu.Game.Tests/Visual/UserInterface/TestCaseMods.cs @@ -83,7 +83,6 @@ namespace osu.Game.Tests.Visual.UserInterface var easierMods = instance.GetModsFor(ModType.DifficultyReduction); var harderMods = instance.GetModsFor(ModType.DifficultyIncrease); - var assistMods = instance.GetModsFor(ModType.Automation); var noFailMod = easierMods.FirstOrDefault(m => m is OsuModNoFail); var hiddenMod = harderMods.FirstOrDefault(m => m is OsuModHidden); From 7c50bdd173ce5c7fbd3cd3d1eaa52725eff372e9 Mon Sep 17 00:00:00 2001 From: Tav TaOr Date: Wed, 15 May 2019 23:48:37 +0300 Subject: [PATCH 07/49] Removed redundant parentheses. --- osu.Game.Rulesets.Osu/Mods/OsuModAutopilot.cs | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/osu.Game.Rulesets.Osu/Mods/OsuModAutopilot.cs b/osu.Game.Rulesets.Osu/Mods/OsuModAutopilot.cs index a9b99f3afe..1853b0228f 100644 --- a/osu.Game.Rulesets.Osu/Mods/OsuModAutopilot.cs +++ b/osu.Game.Rulesets.Osu/Mods/OsuModAutopilot.cs @@ -34,10 +34,7 @@ namespace osu.Game.Rulesets.Osu.Mods public void Update(Playfield playfield) { // If we are on the last replay frame, no need to do anything - if (frameIndex == replayFrames.Count - 1) - { - return; - } + if (frameIndex == replayFrames.Count - 1) return; // Check if we are closer to the next replay frame then the current one if (Math.Abs(replayFrames[frameIndex].Time - playfield.Time.Current) >= Math.Abs(replayFrames[frameIndex + 1].Time - playfield.Time.Current)) From cd6fe918821aec9d150311bcc6ac0ec653b672dc Mon Sep 17 00:00:00 2001 From: David Zhao Date: Mon, 5 Aug 2019 19:56:35 +0900 Subject: [PATCH 08/49] Log error for invalid events --- .../Formats/LegacyBeatmapDecoderTest.cs | 17 + osu.Game.Tests/Resources/invalid-events.osu | 1004 +++++++++++++++++ .../Beatmaps/Formats/LegacyBeatmapDecoder.cs | 6 +- .../Formats/LegacyStoryboardDecoder.cs | 3 +- 4 files changed, 1028 insertions(+), 2 deletions(-) create mode 100644 osu.Game.Tests/Resources/invalid-events.osu diff --git a/osu.Game.Tests/Beatmaps/Formats/LegacyBeatmapDecoderTest.cs b/osu.Game.Tests/Beatmaps/Formats/LegacyBeatmapDecoderTest.cs index d087251e7e..98464b8d91 100644 --- a/osu.Game.Tests/Beatmaps/Formats/LegacyBeatmapDecoderTest.cs +++ b/osu.Game.Tests/Beatmaps/Formats/LegacyBeatmapDecoderTest.cs @@ -482,5 +482,22 @@ namespace osu.Game.Tests.Beatmaps.Formats Assert.AreEqual(hitObjects[0].Samples[0].Bank, hitObjects[0].Samples[1].Bank); } } + + [Test] + public void TestDecodeInvalidEvents() + { + using (var normalResStream = TestResources.OpenResource("Soleily - Renatus (Gamu) [Insane].osu")) + using (var normalStream = new StreamReader(normalResStream)) + using (var resStream = TestResources.OpenResource("invalid-events.osu")) + using (var stream = new StreamReader(resStream)) + { + var decoder = Decoder.GetDecoder(stream); + var goodBeatmap = decoder.Decode(normalStream); + Beatmap badBeatmap = null; + + Assert.DoesNotThrow(() => badBeatmap = decoder.Decode(stream)); + Assert.AreEqual(goodBeatmap.HitObjects.Count, badBeatmap.HitObjects.Count); + } + } } } diff --git a/osu.Game.Tests/Resources/invalid-events.osu b/osu.Game.Tests/Resources/invalid-events.osu new file mode 100644 index 0000000000..a8e767585c --- /dev/null +++ b/osu.Game.Tests/Resources/invalid-events.osu @@ -0,0 +1,1004 @@ +osu file format v14 + +[General] +AudioFilename: 03. Renatus - Soleily 192kbps.mp3 +AudioLeadIn: 0 +PreviewTime: 164471 +Countdown: 0 +SampleSet: Soft +StackLeniency: 0.7 +Mode: 0 +LetterboxInBreaks: 0 +WidescreenStoryboard: 0 + +[Editor] +Bookmarks: 11505,22054,32604,43153,53703,64252,74802,85351,95901,106450,116999,119637,130186,140735,151285,161834,164471,175020,185570,196119,206669,209306 +DistanceSpacing: 1.8 +BeatDivisor: 4 +GridSize: 4 +TimelineZoom: 2 + +[Metadata] +Title:Renatus +TitleUnicode:Renatus +Artist:Soleily +ArtistUnicode:Soleily +Creator:Gamu +Version:Insane +Source: +Tags:MBC7 Unisphere 地球ヤバイEP Chikyu Yabai +BeatmapID:557821 +BeatmapSetID:241526 + +[Difficulty] +HPDrainRate:6.5 +CircleSize:4 +OverallDifficulty:8 +ApproachRate:9 +SliderMultiplier:1.8 +SliderTickRate:2 + +[Events] +bad,event,this,should,fail +//Background and Video events +0,0,"machinetop_background.jpg",0,0 +//Break Periods +2,122474,140135 +//Storyboard Layer 0 (Background) +//Storyboard Layer 1 (Fail) +//Storyboard Layer 2 (Pass) +//Storyboard Layer 3 (Foreground) +//Storyboard Sound Samples + +[TimingPoints] +956,329.67032967033,4,2,0,60,1,0 +20736,-100,4,2,0,65,0,0 +22054,-100,4,2,0,70,0,0 +43153,-100,4,2,0,60,0,0 +48428,-100,4,2,0,50,0,0 +52879,-100,4,2,0,50,0,0 +53373,-100,4,2,0,60,0,0 +53703,-100,4,2,0,70,0,1 +74719,-100,4,2,0,70,0,0 +74802,-100,4,2,0,70,0,1 +95901,-100,4,2,0,70,0,0 +116999,-133.333333333333,4,2,0,50,0,0 +117164,-133.333333333333,4,2,0,30,0,0 +117329,-79.9999999999999,4,2,0,50,0,0 +117659,-100,4,2,0,50,0,0 +118977,-100,4,2,0,60,0,0 +119307,-100,4,2,0,70,0,0 +119637,659.340659340659,4,2,0,80,1,0 +119966,-100,4,2,0,70,0,0 +120296,-100,4,2,0,60,0,0 +120626,-100,4,2,0,50,0,0 +120955,-100,4,2,0,40,0,0 +121285,-100,4,2,0,30,0,0 +121615,-100,4,2,0,20,0,0 +121944,-100,4,2,0,10,0,0 +122274,-100,4,2,0,5,0,0 +140735,-100,4,2,0,50,0,0 +151285,-80,4,2,0,60,0,0 +161834,329.67032967033,4,2,0,65,1,0 +164141,-100,4,2,0,70,0,0 +164471,-100,4,2,0,70,0,1 +185487,-100,4,2,0,70,0,0 +185570,-100,4,2,0,70,0,1 +206669,659.340659340659,4,2,0,80,1,0 +206998,-100,4,2,0,70,0,0 +207328,-100,4,2,0,60,0,0 +207658,-100,4,2,0,50,0,0 +207987,-100,4,2,0,40,0,0 +208317,-100,4,2,0,30,0,0 +208647,-100,4,2,0,20,0,0 +208976,-100,4,2,0,10,0,0 +209306,-100,4,2,0,5,0,0 + + +[Colours] +Combo1 : 142,199,255 +Combo2 : 255,128,128 +Combo3 : 128,255,255 +Combo4 : 128,255,128 +Combo5 : 255,187,255 +Combo6 : 255,177,140 +Combo7 : 100,100,100,100 + +[HitObjects] +192,168,956,6,0,P|184:128|200:80,1,90,4|0,1:2|0:0,0:0:0:0: +304,56,1285,1,8,0:0:0:0: +244,236,1450,2,0,P|204:252|156:244,1,90,2|0,0:0|0:0,0:0:0:0: +276,156,1780,2,0,P|310:181|329:226,1,90,2|8,1:2|0:0,0:0:0:0: +300,328,2109,1,2,0:0:0:0: +192,332,2274,6,0,L|144:340,2,45,0|0|0,1:0|0:0|0:0,0:0:0:0: +388,300,2604,1,8,0:0:0:0: +244,236,2769,1,0,1:0:0:0: +232,208,2851,1,0,0:0:0:0: +224,176,2934,1,0,0:0:0:0: +228,144,3016,1,0,0:0:0:0: +244,116,3098,1,0,1:0:0:0: +332,52,3263,2,0,P|376:48|424:56,1,90,8|0,0:0|0:0,0:0:0:0: +488,228,3593,5,0,1:0:0:0: +460,240,3675,1,0,0:0:0:0: +428,236,3758,1,0,0:0:0:0: +292,160,3923,2,0,P|288:204|300:252,1,90,8|0,0:0|0:0,0:0:0:0: +316,276,4170,1,0,0:0:0:0: +344,292,4252,2,0,L|388:300,1,45,0|0,0:0|0:0,0:0:0:0: +288,356,4417,2,0,L|244:364,1,45,0|0,1:0|0:0,0:0:0:0: +168,328,4582,2,0,P|124:324|72:332,1,90,8|0,0:0|0:0,0:0:0:0: +24,188,4912,5,0,1:0:0:0: +56,192,4994,1,0,0:0:0:0: +88,196,5076,1,0,0:0:0:0: +148,108,5241,1,8,0:0:0:0: +188,240,5406,1,0,1:0:0:0: +188,240,5488,1,0,0:0:0:0: +188,240,5571,2,0,L|168:328,1,90,0|0,0:0|1:0,0:0:0:0: +260,216,5901,2,0,P|236:180|188:164,1,90,8|0,0:0|0:0,0:0:0:0: +248,296,6230,6,0,L|348:292,1,90,0|0,1:0|0:0,0:0:0:0: +504,232,6560,1,8,0:0:0:0: +400,204,6725,1,0,0:0:0:0: +392,176,6807,1,0,0:0:0:0: +384,144,6890,1,0,0:0:0:0: +376,116,6972,1,0,0:0:0:0: +368,88,7054,1,0,1:0:0:0: +188,48,7219,2,0,L|208:140,1,90,8|0,0:0|0:0,0:0:0:0: +248,296,7549,5,0,1:0:0:0: +207,135,7714,1,0,0:0:0:0: +156,232,7879,1,8,0:0:0:0: +316,191,8043,1,0,1:0:0:0: +316,191,8126,1,0,0:0:0:0: +316,191,8208,2,0,L|372:200,1,45,0|0,0:0|0:0,0:0:0:0: +492,200,8373,2,0,L|447:207,1,45,0|0,1:0|0:0,0:0:0:0: +408,136,8538,2,0,P|396:92|400:48,1,90,8|0,0:0|0:0,0:0:0:0: +260,32,8868,5,0,1:0:0:0: +252,64,8950,1,0,0:0:0:0: +236,92,9032,2,0,P|204:116|148:128,1,90,0|8,0:0|0:0,0:0:0:0: +28,188,9362,1,0,0:0:0:0: +60,196,9445,1,0,0:0:0:0: +88,212,9527,2,0,P|112:244|124:300,1,90,0|0,0:0|1:0,0:0:0:0: +112,128,9857,2,0,P|152:156|184:196,1,90,8|0,0:0|0:0,0:0:0:0: +216,288,10186,5,0,1:0:0:0: +216,288,10269,1,0,0:0:0:0: +216,288,10351,1,0,0:0:0:0: +268,192,10516,1,8,0:0:0:0: +356,128,10681,1,0,1:0:0:0: +388,120,10763,1,0,0:0:0:0: +420,128,10846,2,0,P|440:168|436:220,1,90,0|0,0:0|1:0,0:0:0:0: +332,328,11175,2,0,L|280:332,1,45,8|8,0:0|0:0,0:0:0:0: +216,288,11340,2,0,L|164:292,1,45,0|0,1:0|0:0,1:0:0:0: +100,248,11505,5,4,1:2:0:0: +148,116,11670,1,2,0:0:0:0: +268,192,11835,1,10,0:0:0:0: +136,328,11999,2,0,L|44:336,1,90,2|0,0:0|0:0,0:0:0:0: +216,288,12329,1,2,1:2:0:0: +148,116,12494,1,10,0:0:0:0: +100,248,12659,1,2,0:0:0:0: +268,192,12824,5,0,1:0:0:0: +268,192,12906,1,0,0:0:0:0: +268,192,12988,1,0,0:0:0:0: +340,272,13153,2,0,P|384:276|432:264,1,90,8|0,0:0|1:0,0:0:0:0: +452,244,13401,1,0,0:0:0:0: +468,216,13483,2,0,L|476:124,1,90,0|0,0:0|1:0,0:0:0:0: +368,32,13813,2,0,L|360:121,1,90,8|0,0:0|0:0,0:0:0:0: +340,272,14142,6,0,L|316:316,2,45,0|0|0,1:0|0:0|0:0,0:0:0:0: +452,244,14472,1,8,0:0:0:0: +268,192,14637,1,0,0:0:0:0: +236,188,14719,1,0,0:0:0:0: +204,192,14802,2,0,P|172:228|160:272,1,90,0|0,0:0|1:0,0:0:0:0: +128,140,15131,2,0,P|160:104|172:60,1,90,8|0,0:0|0:0,0:0:0:0: +64,52,15461,6,0,L|20:68,2,45,0|0|0,1:0|0:0|0:0,0:0:0:0: +171,64,15791,1,8,0:0:0:0: +264,8,15956,2,0,L|356:12,1,90,0|0,1:0|0:0,0:0:0:0: +452,56,16285,1,0,1:0:0:0: +296,140,16450,2,0,L|206:136,1,90,8|0,0:0|0:0,0:0:0:0: +108,184,16780,6,0,P|92:224|96:272,1,90,0|0,1:0|0:0,0:0:0:0: +200,244,17109,1,8,0:0:0:0: +108,108,17274,2,0,L|12:116,1,90,0|0,0:0|0:0,0:0:0:0: +200,244,17604,1,0,1:0:0:0: +296,140,17769,2,0,L|385:132,1,90,8|0,0:0|0:0,0:0:0:0: +480,184,18098,5,0,1:0:0:0: +488,216,18181,1,0,0:0:0:0: +496,248,18263,2,0,L|492:340,1,90,0|8,0:0|0:0,0:0:0:0: +404,224,18593,2,0,L|396:176,2,45,0|0|0,1:0|0:0|0:0,0:0:0:0: +304,264,18923,1,0,1:0:0:0: +200,244,19087,2,0,P|156:240|108:248,1,90,8|0,0:0|0:0,0:0:0:0: +296,140,19417,6,0,P|340:144|388:136,1,90,0|0,1:0|0:0,0:0:0:0: +440,44,19747,1,8,0:0:0:0: +404,224,19912,1,0,0:0:0:0: +404,224,19994,1,0,0:0:0:0: +404,224,20076,2,0,L|412:320,1,90,0|0,0:0|1:0,0:0:0:0: +200,244,20406,2,0,L|192:154,1,90,8|0,0:0|0:0,0:0:0:0: +184,44,20736,5,4,1:2:0:0: +152,40,20818,1,0,0:0:0:0: +120,48,20901,1,0,0:0:0:0: +96,68,20983,1,0,0:0:0:0: +76,92,21065,1,2,0:3:0:0: +64,120,21148,1,0,0:0:0:0: +60,152,21230,1,0,1:0:0:0: +64,184,21313,1,0,0:0:0:0: +76,212,21395,2,0,L|96:252,3,45,0|0|0|0,0:0|0:0|1:0|0:0,0:0:0:0: +144,316,21725,2,0,L|188:324,3,45,0|0|2|0,0:0|0:0|0:3|0:0,0:0:0:0: +268,340,22054,6,0,L|364:336,1,90,4|0,1:2|0:0,0:0:0:0: +452,280,22384,1,8,0:0:0:0: +512,188,22549,2,0,P|516:144|504:96,1,90,2|0,0:0|0:0,0:0:0:0: +340,24,22879,2,0,P|336:68|348:116,1,90,2|8,1:2|0:0,0:0:0:0: +420,192,23208,1,2,0:0:0:0: +328,252,23373,6,0,L|232:240,1,90,0|0,1:0|0:0,0:0:0:0: +64,256,23703,1,8,0:0:0:0: +144,184,23868,2,0,P|148:140|136:88,1,90,0|0,1:0|0:0,0:0:0:0: +40,52,24197,1,2,1:2:0:0: +139,95,24362,1,8,0:0:0:0: +216,20,24527,1,0,0:0:0:0: +315,63,24692,6,0,P|360:72|408:68,1,90,2|0,1:2|0:0,0:0:0:0: +492,132,25021,1,8,0:0:0:0: +412,204,25186,2,0,P|403:249|407:297,1,90,2|0,0:0|0:0,0:0:0:0: +268,328,25516,2,0,P|277:283|273:235,1,90,2|8,1:2|0:0,0:0:0:0: +232,140,25846,2,0,P|187:131|139:135,1,90,2|0,0:0|1:0,0:0:0:0: +64,208,26175,5,2,0:0:0:0: +44,316,26340,1,8,0:0:0:0: +148,280,26505,1,2,1:2:0:0: +456,208,26835,1,2,1:2:0:0: +476,316,26999,1,10,0:0:0:0: +372,280,27164,1,2,0:0:0:0: +356,172,27329,6,0,L|380:80,1,90,0|0,1:0|0:0,0:0:0:0: +456,208,27659,1,8,0:0:0:0: +300,236,27824,1,2,0:0:0:0: +300,236,27906,1,0,0:0:0:0: +300,236,27988,2,0,L|208:228,1,90,0|2,0:0|1:2,0:0:0:0: +140,312,28318,1,8,0:0:0:0: +372,280,28483,2,0,L|464:272,1,90,2|0,0:0|1:0,0:0:0:0: +500,136,28813,5,2,0:0:0:0: +432,56,28977,1,8,0:0:0:0: +328,24,29142,2,0,P|284:24|236:28,1,90,2|0,1:2|0:0,0:0:0:0: +80,144,29472,1,2,1:2:0:0: +116,44,29637,1,10,0:0:0:0: +184,128,29802,1,2,0:0:0:0: +20,88,29966,6,0,P|1:164|73:227,1,180,2|10,1:2|0:0,0:0:0:0: +184,128,30461,2,0,P|227:120|276:124,1,90,2|0,0:0|0:0,0:0:0:0: +392,188,30791,1,2,1:2:0:0: +272,260,30956,1,8,0:0:0:0: +396,328,31120,1,0,0:0:0:0: +256,348,31285,5,2,1:2:0:0: +224,344,31368,1,0,1:0:0:0: +192,340,31450,2,0,L|172:248,1,90,2|0,1:2|1:0,0:0:0:0: +8,136,31780,2,0,L|27:223,1,90,2|0,1:2|0:0,0:0:0:0: +56,328,32109,1,2,1:2:0:0: +108,192,32274,1,2,1:2:0:0: +100,160,32357,1,0,1:0:0:0: +92,132,32439,1,2,1:2:0:0: +84,104,32521,1,0,1:0:0:0: +76,72,32604,6,0,P|100:112|148:136,1,90,4|0,1:2|0:0,0:0:0:0: +240,168,32934,1,8,0:0:0:0: +336,124,33098,2,0,L|344:80,2,45,2|0|0,0:0|0:0|0:0,0:0:0:0: +264,248,33428,2,0,P|220:248|176:220,1,90,2|8,1:2|0:0,0:0:0:0: +260,84,33758,1,2,0:0:0:0: +344,212,33923,5,0,1:0:0:0: +344,212,34005,1,0,0:0:0:0: +344,212,34087,1,0,0:0:0:0: +440,160,34252,1,8,0:0:0:0: +312,320,34417,2,0,P|272:336|220:324,1,90,0|0,1:0|0:0,0:0:0:0: +156,176,34747,2,0,P|196:160|248:172,2,90,2|8|0,1:2|0:0|0:0,0:0:0:0: +132,280,35241,5,2,1:2:0:0: +132,280,35324,1,0,0:0:0:0: +132,280,35406,2,0,L|120:376,1,90,0|8,0:0|0:0,0:0:0:0: +312,320,35736,2,0,L|300:230,1,90,2|0,0:0|0:0,0:0:0:0: +316,124,36065,1,2,1:2:0:0: +400,192,36230,1,8,0:0:0:0: +300,230,36395,2,0,P|255:231|211:224,1,90,2|0,0:0|1:0,0:0:0:0: +24,132,36725,5,0,0:0:0:0: +132,152,36890,1,8,0:0:0:0: +60,232,37054,1,2,1:2:0:0: +60,232,37137,1,0,0:0:0:0: +60,232,37219,1,0,0:0:0:0: +92,56,37384,2,0,L|184:44,1,90,2|10,1:2|0:0,0:0:0:0: +316,124,37714,2,0,L|226:135,1,90,2|0,0:0|1:0,0:0:0:0: +60,232,38043,6,0,P|52:276|64:328,1,90,0|8,0:0|0:0,0:0:0:0: +220,152,38373,2,0,P|176:144|124:156,1,90,2|0,0:0|0:0,0:0:0:0: +176,252,38703,1,2,1:2:0:0: +323,213,38868,2,0,L|316:124,1,90,8|2,0:0|0:0,0:0:0:0: +332,320,39197,5,0,1:0:0:0: +424,260,39362,1,2,0:0:0:0: +260,272,39527,2,0,P|246:313|256:360,1,90,8|2,0:0|1:2,0:0:0:0: +408,336,39857,1,0,0:0:0:0: +176,252,40021,2,0,L|80:260,2,90,2|10|2,1:2|0:0|0:0,0:0:0:0: +324,212,40516,5,2,1:2:0:0: +324,212,40598,1,0,1:0:0:0: +324,212,40681,1,0,1:0:0:0: +200,336,40846,1,2,1:2:0:0: +236,188,41010,1,2,1:2:0:0: +236,188,41093,1,0,1:0:0:0: +236,188,41175,1,0,1:0:0:0: +281,357,41340,1,2,1:2:0:0: +176,252,41505,1,2,1:2:0:0: +176,252,41587,1,0,1:0:0:0: +176,252,41670,1,0,1:0:0:0: +344,297,41835,5,2,1:2:0:0: +432,232,41999,1,2,1:2:0:0: +444,204,42082,1,0,1:0:0:0: +448,172,42164,1,0,1:0:0:0: +444,140,42247,1,0,1:0:0:0: +432,112,42329,2,0,L|440:64,2,45,2|0|0,1:2|1:0|1:0,0:0:0:0: +236,188,42659,1,0,0:0:0:0: +340,172,42824,1,2,0:3:0:0: +272,88,42988,1,0,0:0:0:0: +132,160,43153,6,0,P|148:248|220:296,1,180,4|8,1:2|0:0,0:0:0:0: +324,320,43648,2,0,L|336:364,2,45,0|0|0,0:0|0:0|0:0,0:0:0:0: +292,216,43977,1,0,1:0:0:0: +396,240,44142,2,0,P|440:244|488:232,1,90,8|0,0:0|0:0,0:0:0:0: +328,124,44472,6,0,P|284:120|236:132,1,90,0|0,1:0|0:0,0:0:0:0: +168,212,44802,1,8,0:0:0:0: +192,316,44966,1,0,1:0:0:0: +140,220,45131,1,0,0:0:0:0: +83,310,45296,1,0,1:0:0:0: +114,205,45461,1,8,0:0:0:0: +10,229,45626,1,0,0:0:0:0: +106,176,45791,6,0,P|113:133|108:85,1,90,0|0,1:0|0:0,0:0:0:0: +204,136,46120,1,8,0:0:0:0: +256,40,46285,1,0,0:0:0:0: +256,40,46368,1,0,0:0:0:0: +256,40,46450,2,0,L|356:44,1,90,0|0,0:0|1:0,0:0:0:0: +501,124,46780,2,0,L|412:128,1,90,8|0,0:0|0:0,0:0:0:0: +324,192,47109,5,0,1:0:0:0: +356,296,47274,1,0,0:0:0:0: +284,216,47439,1,8,0:0:0:0: +269,323,47604,1,0,1:0:0:0: +237,220,47769,1,0,0:0:0:0: +178,311,47934,1,0,1:0:0:0: +191,203,48098,1,8,0:0:0:0: +99,261,48263,1,0,0:0:0:0: +156,168,48428,6,0,B|176:112|136:64|136:64|200:96,1,180,4|8,1:2|0:0,0:0:0:0: +300,124,48923,2,0,L|392:120,1,90,0|0,0:0|0:0,0:0:0:0: +468,48,49252,1,0,1:0:0:0: +390,120,49417,2,0,P|390:164|406:208,1,90,8|0,0:0|0:0,0:0:0:0: +352,344,49747,6,0,P|352:300|336:256,1,90,4|0,1:2|0:0,0:0:0:0: +240,208,50076,1,8,0:0:0:0: +163,320,50241,2,0,P|207:324|252:316,1,90,0|0,1:0|0:0,0:0:0:0: +240,208,50571,1,0,1:0:0:0: +76,296,50736,2,0,P|76:340|92:384,1,90,8|0,0:0|0:0,0:0:0:0: +312,164,51065,6,0,P|236:124|160:184,1,180,4|8,1:2|0:0,0:0:0:0: +247,297,51560,2,0,L|240:208,1,90,0|0,0:0|0:0,0:0:0:0: +224,48,51890,1,0,1:0:0:0: +332,56,52054,2,0,L|366:58,5,30,8|0|0|0|0|0,0:0|0:0|0:0|0:0|0:0|0:0,0:0:0:0: +408,64,52384,6,0,P|420:108|416:156,1,90,0|0,1:0|0:0,0:0:0:0: +360,260,52714,1,8,0:0:0:0: +247,297,52879,2,0,B|203:281|159:297|159:297|115:313|71:297,1,180,0|0,1:0|1:0,0:0:0:0: +116,196,53373,1,8,0:0:0:0: +120,164,53456,1,0,0:0:0:0: +124,132,53538,1,0,0:0:0:0: +128,100,53620,1,0,0:0:0:0: +132,68,53703,5,4,1:2:0:0: +40,136,53868,1,0,0:0:0:0: +204,160,54032,2,0,L|304:152,1,90,8|0,0:0|0:0,0:0:0:0: +408,64,54362,1,0,0:0:0:0: +408,64,54445,1,0,0:0:0:0: +408,64,54527,2,0,P|404:112|416:160,1,90,0|8,1:0|0:0,0:0:0:0: +484,236,54857,1,0,0:0:0:0: +428,328,55021,5,0,1:0:0:0: +328,296,55186,1,0,0:0:0:0: +328,296,55269,1,0,0:0:0:0: +328,296,55351,1,8,0:0:0:0: +416,300,55516,1,0,1:0:0:0: +472,208,55681,1,0,0:0:0:0: +316,268,55846,1,0,1:0:0:0: +460,180,56010,1,8,0:0:0:0: +304,240,56175,1,0,0:0:0:0: +404,272,56340,5,0,1:0:0:0: +448,152,56505,1,0,0:0:0:0: +448,152,56587,1,0,0:0:0:0: +448,152,56670,2,0,P|456:112|448:60,1,90,8|0,0:0|0:0,0:0:0:0: +268,28,56999,2,0,P|260:68|268:120,1,90,0|0,0:0|1:0,0:0:0:0: +404,272,57329,2,0,P|444:280|496:272,2,90,8|0|0,0:0|0:0|1:0,0:0:0:0: +304,240,57824,5,0,0:0:0:0: +252,336,57988,1,8,0:0:0:0: +196,244,58153,1,0,1:0:0:0: +24,256,58318,1,0,0:0:0:0: +116,200,58483,1,0,1:0:0:0: +136,60,58648,1,8,0:0:0:0: +192,152,58813,1,0,0:0:0:0: +304,240,58977,6,0,P|348:252|396:248,1,90,0|0,1:0|0:0,0:0:0:0: +456,116,59307,2,0,P|412:104|364:108,1,90,8|0,0:0|0:0,0:0:0:0: +273,161,59637,1,0,0:0:0:0: +136,60,59802,1,0,1:0:0:0: +192,152,59966,1,8,0:0:0:0: +23,177,60131,1,0,0:0:0:0: +129,203,60296,5,0,1:0:0:0: +88,304,60461,2,0,P|132:311|176:303,1,90,0|8,0:0|0:0,0:0:0:0: +304,240,60791,1,0,1:0:0:0: +304,240,60873,1,0,0:0:0:0: +304,240,60956,2,0,L|312:288,3,45,0|0|0|0,0:0|0:0|1:0|0:0,0:0:0:0: +384,256,61285,2,0,L|392:304,3,45,8|0|0|0,0:0|0:0|0:0|0:0,0:0:0:0: +464,272,61615,5,2,1:2:0:0: +488,168,61780,1,2,0:0:0:0: +428,80,61945,1,10,0:0:0:0: +332,32,62109,2,0,P|288:28|240:36,1,90,2|0,0:0|0:0,0:0:0:0: +28,216,62439,1,2,1:2:0:0: +88,304,62604,1,10,0:0:0:0: +184,352,62769,2,0,P|228:356|276:348,1,90,2|0,0:0|1:0,0:0:0:0: +384,256,63098,6,0,P|409:219|426:174,1,90,2|8,0:0|0:0,0:0:0:0: +428,80,63428,2,0,L|420:36,2,45,2|0|0,1:2|0:0|0:0,0:0:0:0: +456,288,63758,1,2,1:2:0:0: +324,200,63923,1,10,1:2:0:0: +292,204,64005,1,0,1:0:0:0: +260,208,64087,1,2,1:2:0:0: +228,212,64170,1,0,1:0:0:0: +196,216,64252,5,4,1:2:0:0: +104,160,64417,1,0,0:0:0:0: +228,296,64582,2,0,L|320:284,1,90,8|0,0:0|0:0,0:0:0:0: +344,112,64912,1,0,0:0:0:0: +344,112,64994,1,0,0:0:0:0: +344,112,65076,2,0,L|254:123,1,90,0|8,1:0|0:0,0:0:0:0: +144,284,65406,2,0,P|148:328|176:364,1,90,0|0,0:0|1:0,0:0:0:0: +196,216,65736,5,0,0:0:0:0: +196,216,65818,1,0,0:0:0:0: +196,216,65901,2,0,P|155:198|110:205,1,90,8|0,0:0|1:0,0:0:0:0: +36,284,66230,1,0,0:0:0:0: +4,180,66395,1,0,1:0:0:0: +132,24,66560,1,8,0:0:0:0: +100,128,66725,1,0,0:0:0:0: +24,48,66890,5,0,1:0:0:0: +212,108,67054,1,0,0:0:0:0: +212,108,67137,1,0,0:0:0:0: +212,108,67219,2,0,L|300:92,1,90,8|0,0:0|0:0,0:0:0:0: +472,144,67549,2,0,L|384:160,1,90,0|0,0:0|1:0,0:0:0:0: +196,216,67879,2,0,P|240:216|288:240,1,90,8|0,0:0|0:0,0:0:0:0: +324,336,68208,5,0,1:0:0:0: +144,288,68373,1,0,0:0:0:0: +58,170,68538,1,8,0:0:0:0: +196,215,68703,1,0,1:0:0:0: +58,260,68868,1,0,0:0:0:0: +144,142,69032,2,0,L|138:108,2,30,0|0|0,1:0|0:0|0:0,0:0:0:0: +144,142,69197,2,0,P|184:124|232:132,1,90,8|0,0:0|0:0,0:0:0:0: +312,248,69527,6,0,L|324:338,1,90,0|0,1:0|0:0,0:0:0:0: +436,248,69857,1,8,0:0:0:0: +432,216,69939,1,0,0:0:0:0: +428,184,70021,1,0,0:0:0:0: +328,120,70186,1,0,0:0:0:0: +324,152,70269,1,0,0:0:0:0: +320,184,70351,1,0,1:0:0:0: +316,216,70434,1,0,0:0:0:0: +312,248,70516,2,0,L|320:300,1,45,8|0,0:0|0:0,0:0:0:0: +244,340,70681,2,0,L|237:295,1,45,0|0,0:0|0:0,0:0:0:0: +216,224,70846,6,0,P|168:216|124:224,1,90,0|0,1:0|0:0,0:0:0:0: +40,288,71175,1,8,0:0:0:0: +2,95,71340,2,0,P|-4:139|4:184,1,90,0|0,1:0|0:0,0:0:0:0: +164,304,71670,1,0,1:0:0:0: +312,248,71835,1,8,0:0:0:0: +244,340,71999,1,0,0:0:0:0: +216,224,72164,6,0,L|228:132,1,90,0|0,1:0|0:0,0:0:0:0: +332,148,72494,2,0,L|344:56,1,90,8|0,0:0|0:0,0:0:0:0: +312,248,72824,1,0,0:0:0:0: +164,304,72988,1,0,1:0:0:0: +332,336,73153,1,8,0:0:0:0: +360,324,73236,1,0,0:0:0:0: +384,304,73318,1,0,0:0:0:0: +399,276,73401,1,0,0:0:0:0: +403,244,73483,6,0,L|396:200,3,45,4|0|2|0,1:2|0:0|0:0|1:0,0:0:0:0: +420,112,73813,2,0,L|427:68,3,45,2|0|2|0,1:2|0:0|1:2|0:0,0:0:0:0: +352,16,74142,2,0,L|345:60,3,45,0|0|2|0,0:0|1:0|1:2|0:0,0:0:0:0: +332,148,74472,1,2,1:2:0:0: +332,148,74554,1,0,1:0:0:0: +332,148,74637,1,2,1:2:0:0: +332,148,74719,1,0,1:0:0:0: +332,148,74802,6,0,P|360:216|320:312,1,180,4|2,1:2|0:3,0:0:0:0: +190,310,75296,2,0,P|151:231|180:148,1,180,4|0,1:2|0:0,0:0:0:0: +256,56,75791,1,0,0:0:0:0: +332,148,75956,1,2,0:3:0:0: +179,148,76120,5,4,1:2:0:0: +336,64,76285,1,4,1:2:0:0: +256,224,76450,1,2,0:3:0:0: +176,64,76615,1,4,1:2:0:0: +256,140,76780,2,0,L|256:324,1,180,2|0,0:0|0:0,0:0:0:0: +364,300,77274,1,2,0:3:0:0: +148,300,77439,6,0,P|104:316|76:356,1,90,4|0,1:2|0:0,0:0:0:0: +24,252,77769,2,0,L|16:208,3,45,8|0|0|0,0:0|0:0|0:0|0:0,0:0:0:0: +96,212,78098,2,0,L|104:168,3,45,0|0|0|0,0:0|0:0|1:0|0:0,0:0:0:0: +32,128,78428,2,0,L|24:84,3,45,8|0|0|0,0:0|0:0|0:0|0:0,0:0:0:0: +104,88,78758,5,2,1:2:0:0: +204,132,78923,1,0,0:0:0:0: +236,124,79005,1,0,0:0:0:0: +268,116,79087,2,0,L|280:68,3,45,8|0|0|0,0:0|0:0|1:0|0:0,0:0:0:0: +348,100,79417,2,0,L|360:52,3,45,0|0|0|0,0:0|0:0|1:0|0:0,0:0:0:0: +428,84,79747,1,8,1:2:0:0: +460,76,79829,1,0,1:0:0:0: +492,68,79912,1,0,1:0:0:0: +492,260,80076,6,0,P|400:248|328:296,1,180,4|2,1:2|0:3,0:0:0:0: +144,236,80571,2,0,P|236:248|308:200,1,180,4|0,1:2|0:0,0:0:0:0: +348,100,81065,2,0,P|348:56|336:8,1,90,0|2,0:0|0:3,0:0:0:0: +140,48,81395,5,4,1:2:0:0: +244,68,81560,1,4,1:2:0:0: +144,236,81725,1,2,0:3:0:0: +176,133,81890,1,4,1:2:0:0: +184,304,82054,2,0,P|100:300|68:220,1,180,2|0,0:0|0:0,0:0:0:0: +100,116,82549,1,2,0:3:0:0: +264,244,82714,6,0,L|272:340,1,90,4|0,1:2|0:0,0:0:0:0: +380,316,83043,1,8,0:0:0:0: +396,288,83126,1,0,0:0:0:0: +400,256,83208,1,0,0:0:0:0: +396,224,83291,1,0,0:0:0:0: +380,196,83373,2,0,L|336:176,3,45,0|0|0|0,0:0|0:0|1:0|0:0,0:0:0:0: +272,148,83703,1,8,0:0:0:0: +256,120,83785,1,0,0:0:0:0: +252,88,83868,1,0,0:0:0:0: +256,56,83950,1,0,0:0:0:0: +272,28,84032,6,0,L|316:8,3,45,2|0|0|0,1:2|0:0|0:0|0:0,0:0:0:0: +360,72,84362,2,0,L|408:72,3,45,8|0|0|0,0:0|0:0|1:0|0:0,0:0:0:0: +421,149,84692,2,0,L|464:169,3,45,2|0|0|0,0:0|0:0|1:0|0:0,0:0:0:0: +443,244,85021,2,0,L|473:281,3,45,8|0|0|0,1:2|1:0|0:0|0:0,0:0:0:0: +422,339,85351,6,0,L|240:348,1,180,4|2,1:2|0:3,0:0:0:0: +76,172,85846,2,0,L|255:163,1,180,4|0,1:2|0:0,0:0:0:0: +421,149,86340,2,0,P|435:107|428:56,1,90,0|2,0:0|0:3,0:0:0:0: +228,56,86670,5,4,1:2:0:0: +280,192,86835,1,4,1:2:0:0: +328,96,86999,1,2,0:3:0:0: +180,152,87164,1,4,1:2:0:0: +28,100,87330,2,0,P|16:56|20:8,1,90,2|0,0:0|0:0,0:0:0:0: +0,180,87659,1,0,0:0:0:0: +28,284,87824,1,2,0:3:0:0: +108,352,87988,6,0,P|152:360|196:356,1,90,4|0,1:2|0:0,0:0:0:0: +276,284,88318,1,8,0:0:0:0: +304,272,88401,1,0,0:0:0:0: +336,268,88483,1,0,0:0:0:0: +368,272,88565,1,0,0:0:0:0: +396,284,88648,2,0,L|432:312,1,45,0|0,0:0|0:0,0:0:0:0: +488,252,88813,2,0,L|452:224,1,45,0|0,1:0|0:0,0:0:0:0: +400,164,88977,2,0,L|396:116,3,45,8|0|0|0,0:0|0:0|0:0|0:0,0:0:0:0: +316,64,89307,6,0,L|320:160,1,90,2|0,1:2|0:0,0:0:0:0: +276,284,89637,1,8,0:0:0:0: +248,296,89719,1,0,0:0:0:0: +216,300,89802,1,0,1:0:0:0: +184,296,89884,1,0,0:0:0:0: +156,284,89966,2,0,L|120:256,1,45,0|0,0:0|0:0,0:0:0:0: +176,200,90131,2,0,L|140:172,1,45,0|0,1:0|0:0,0:0:0:0: +196,116,90296,2,0,L|160:88,3,45,8|0|0|0,1:2|1:0|1:0|0:0,0:0:0:0: +92,44,90626,6,0,P|48:44|24:160,1,180,4|2,1:2|0:3,0:0:0:0: +156,284,91120,2,0,B|200:300|244:284|244:284|288:268|332:284,1,180,4|0,1:2|0:0,0:0:0:0: +176,200,91615,2,0,P|176:156|196:116,1,90,0|2,0:0|0:3,0:0:0:0: +264,28,91945,6,0,L|353:39,1,90,4|0,1:2|1:0,0:0:0:0: +453,159,92274,2,0,L|364:148,1,90,2|4,0:3|1:2,0:0:0:0: +268,196,92604,2,0,P|260:268|328:348,1,180,2|0,0:0|0:0,0:0:0:0: +364,248,93098,1,2,0:3:0:0: +176,200,93263,5,4,1:2:0:0: +72,228,93428,1,0,1:0:0:0: +152,92,93593,1,0,1:0:0:0: +256,64,93758,1,0,1:0:0:0: +336,200,93923,5,0,1:0:0:0: +440,228,94087,1,0,1:0:0:0: +360,92,94252,1,0,1:0:0:0: +256,64,94417,1,0,1:0:0:0: +176,200,94582,5,2,1:2:0:0: +168,228,94664,1,0,1:0:0:0: +168,260,94747,1,0,1:0:0:0: +172,292,94829,1,0,1:0:0:0: +192,316,94912,1,0,1:0:0:0: +220,328,94994,1,0,1:0:0:0: +252,332,95076,1,0,1:0:0:0: +280,320,95159,1,0,1:0:0:0: +300,296,95241,2,0,L|308:248,3,45,2|0|0|0,1:2|1:0|1:0|1:0,0:0:0:0: +312,172,95571,2,0,L|304:127,3,45,0|0|0|0,1:0|1:0|1:0|1:0,0:0:0:0: +256,64,95901,6,0,P|208:56|164:60,1,90,4|0,1:2|0:0,0:0:0:0: +76,116,96230,1,8,0:0:0:0: +60,224,96395,1,0,0:0:0:0: +60,224,96477,1,0,0:0:0:0: +160,184,96642,1,0,0:0:0:0: +160,184,96725,1,0,1:0:0:0: +63,26,96890,2,0,L|76:116,1,90,8|0,0:0|0:0,0:0:0:0: +136,272,97219,5,0,1:0:0:0: +168,268,97302,1,0,0:0:0:0: +200,264,97384,1,0,0:0:0:0: +232,260,97466,1,0,0:0:0:0: +264,256,97549,1,8,0:0:0:0: +384,136,97714,1,0,1:0:0:0: +376,168,97796,1,0,0:0:0:0: +380,200,97879,1,0,0:0:0:0: +392,228,97961,1,0,0:0:0:0: +416,248,98043,2,0,P|464:260|512:260,2,90,0|8|0,1:0|0:0|0:0,0:0:0:0: +231,105,98538,6,0,L|188:116,2,45,0|0|0,1:0|0:0|0:0,0:0:0:0: +376,56,98868,2,0,L|420:64,1,45,8|0,0:0|0:0,0:0:0:0: +384,136,99032,1,0,0:0:0:0: +384,136,99115,2,0,P|340:128|304:92,1,90,0|0,0:0|0:0,0:0:0:0: +303,18,99362,2,0,L|207:26,2,90,0|8|0,1:0|0:0|0:0,0:0:0:0: +452,88,99857,5,0,1:0:0:0: +465,116,99939,1,0,0:0:0:0: +466,147,100021,1,0,0:0:0:0: +456,177,100104,1,0,0:0:0:0: +436,201,100186,2,0,P|416:213|389:216,3,45,8|0|0|0,0:0|0:0|1:0|0:0,0:0:0:0: +320,188,100516,2,0,P|300:176|273:173,3,45,0|0|0|0,0:0|1:0|1:0|0:0,0:0:0:0: +204,200,100846,2,0,P|192:220|189:247,3,45,8|0|0|0,0:0|0:0|1:0|0:0,0:0:0:0: +188,320,101175,6,0,P|143:322|100:310,1,90,0|0,1:0|0:0,0:0:0:0: +76,292,101423,1,0,0:0:0:0: +76,292,101505,1,8,0:0:0:0: +76,292,101587,2,0,L|72:248,1,45 +12,68,101835,2,0,L|6:24,2,45,0|0|0,0:0|0:0|1:0,0:0:0:0: +104,140,102164,2,0,L|171:132,3,45,8|0|0|0,0:0|0:0|0:0|0:0,0:0:0:0: +224,124,102494,6,0,P|236:164|232:216,1,90,0|0,1:0|0:0,0:0:0:0: +288,296,102824,1,8,0:0:0:0: +288,296,102906,1,0,0:0:0:0: +288,296,102988,2,0,P|328:284|380:288,1,90,0|0,1:0|0:0,0:0:0:0: +404,304,103236,1,0,0:0:0:0: +424,328,103318,1,0,1:0:0:0: +448,188,103483,2,0,L|440:140,3,45,8|0|0|0,0:0|0:0|0:0|0:0,0:0:0:0: +424,72,103813,5,0,1:0:0:0: +324,112,103977,1,0,0:0:0:0: +324,112,104060,1,0,0:0:0:0: +324,112,104142,2,0,P|280:116|232:104,1,90,8|0,0:0|0:0,0:0:0:0: +160,28,104472,1,0,0:0:0:0: +216,208,104637,1,0,1:0:0:0: +216,208,104719,1,0,0:0:0:0: +216,208,104802,1,8,0:0:0:0: +352,240,104966,1,0,0:0:0:0: +384,244,105049,1,0,0:0:0:0: +416,248,105131,6,0,L|460:240,4,45,0|0|0|0|8,1:0|0:0|0:0|0:0|0:0,0:0:0:0: +272,288,105626,1,0,1:0:0:0: +264,320,105708,1,0,0:0:0:0: +256,352,105791,2,0,L|204:356,5,30,0|0|0|0|0|0,0:0|0:0|0:0|1:0|0:0|0:0,0:0:0:0: +156,332,106120,2,0,L|104:336,5,30,8|0|0|0|0|0,0:0|0:0|0:0|1:0|0:0|0:0,0:0:0:0: +56,312,106450,5,4,1:2:0:0: +4,188,106615,1,0,0:0:0:0: +168,220,106780,2,0,P|127:232|79:228,1,90,8|0,0:0|0:0,0:0:0:0: +112,124,107109,1,0,0:0:0:0: +272,216,107274,2,0,L|264:316,1,90,0|8,1:0|0:0,0:0:0:0: +400,268,107604,1,0,0:0:0:0: +428,132,107769,5,0,1:0:0:0: +428,132,107851,1,0,0:0:0:0: +428,132,107934,1,0,0:0:0:0: +428,132,108016,1,0,0:0:0:0: +428,132,108098,1,8,0:0:0:0: +332,84,108263,2,0,P|288:80|232:88,1,90,0|0,1:0|0:0,0:0:0:0: +112,124,108593,1,0,1:0:0:0: +148,264,108758,1,8,0:0:0:0: +16,236,108923,1,0,0:0:0:0: +264,126,109087,6,0,L|272:216,1,90,0|0,1:0|0:0,0:0:0:0: +452,224,109417,2,0,L|460:320,1,90,8|0,0:0|0:0,0:0:0:0: +360,232,109747,1,0,0:0:0:0: +348,56,109912,1,0,1:0:0:0: +416,140,110076,1,8,0:0:0:0: +256,112,110241,2,0,P|212:120|160:112,1,90,0|0,0:0|1:0,0:0:0:0: +348,56,110571,6,0,L|331:150,1,90,0|8,0:0|0:0,0:0:0:0: +208,328,110901,2,0,L|191:239,1,90,0|0,1:0|0:0,0:0:0:0: +184,216,111148,1,0,1:0:0:0: +178,194,111230,1,0,1:0:0:0: +68,272,111395,1,8,0:0:0:0: +56,136,111560,1,0,1:0:0:0: +178,194,111725,6,0,P|219:203|267:199,1,90,4|0,1:2|0:0,0:0:0:0: +364,148,112054,1,8,0:0:0:0: +384,256,112219,2,0,P|406:291|443:322,1,90,0|0,0:0|0:0,0:0:0:0: +488,224,112549,1,0,1:0:0:0: +304,232,112714,2,0,L|208:224,2,90,8|0|0,0:0|0:0|1:0,0:0:0:0: +208,328,113208,6,0,L|112:320,1,90,0|8,0:0|0:0,0:0:0:0: +26,184,113538,2,0,L|116:192,1,90,0|0,1:0|0:0,0:0:0:0: +304,232,113868,1,0,1:0:0:0: +116,192,114032,1,8,0:0:0:0: +224,132,114197,1,0,0:0:0:0: +208,328,114362,6,0,B|272:360|320:312|320:312|340:368,1,180,4|8,1:2|0:0,0:0:0:0: +304,232,114857,2,0,P|300:184|308:140,1,90,0|0,0:0|0:0,0:0:0:0: +384,64,115186,1,0,1:0:0:0: +307,143,115351,1,8,0:0:0:0: +256,48,115516,1,0,0:0:0:0: +456,24,115681,6,0,B|482:101|420:136|420:136|440:184,1,180,4|8,1:2|0:0,0:0:0:0: +384,64,116175,2,0,P|340:56|296:64,1,90,0|0,1:0|0:0,0:0:0:0: +211,171,116505,1,0,1:0:0:0: +439,181,116670,2,0,L|448:84,1,90,8|0,0:0|0:0,0:0:0:0: +372,296,116999,6,2,L|304:292,1,67.5000025749208,2|0,0:1|0:0,0:0:0:0: +136,252,117329,6,2,P|196:260|212:172,1,168.75,0|0,0:0|0:0,0:0:0:0: +192,148,117659,1,2,0:3:0:0: +164,132,117741,1,2,0:3:0:0: +132,124,117824,1,2,1:3:0:0: +100,132,117906,1,2,0:3:0:0: +72,148,117988,2,0,L|52:56,1,90,2|8,0:3|0:0,0:0:0:0: +36,244,118318,5,0,1:0:0:0: +76,344,118483,1,0,1:0:0:0: +184,352,118648,1,0,1:0:0:0: +244,264,118813,1,0,1:0:0:0: +244,264,118895,1,0,1:0:0:0: +244,264,118977,2,0,L|288:260,3,45,2|0|2|0,1:2|0:0|0:0|0:0,0:0:0:0: +332,328,119307,2,0,L|376:324,3,45,2|0|2|0,1:2|0:0|0:0|0:0,0:0:0:0: +412,252,119637,5,4,1:2:0:0: +256,192,119719,12,0,122274,0:0:0:0: +256,192,140735,6,0,L|228:156,1,45,4|0,1:2|0:0,0:0:0:0: +152,132,141065,2,0,P|129:129|104:136,1,45 +48,192,141395,2,0,P|40:236|52:280,1,90,8|8,0:0|0:0,0:0:0:0: +196,352,142054,6,0,L|308:340,1,90,8|8,0:0|1:2,0:0:0:0: +336,280,142549,1,0,0:0:0:0: +404,324,142713,1,8,0:0:0:0: +404,324,142878,1,8,0:0:0:0: +292,120,143373,5,0,1:0:0:0: +212,104,143538,1,0,0:0:0:0: +140,140,143702,1,0,0:0:0:0: +120,220,143867,1,0,0:0:0:0: +144,296,144032,2,0,P|184:320|228:316,1,90,10|8,0:0|0:0,0:0:0:0: +372,212,144691,6,0,P|327:209|290:232,1,90,10|8,0:0|1:2,0:0:0:0: +348,288,145186,1,0,0:0:0:0: +452,220,145351,1,10,0:0:0:0: +452,220,145516,1,8,0:0:0:0: +328,36,146010,5,2,1:2:0:0: +264,88,146175,1,0,0:0:0:0: +184,108,146340,1,0,0:0:0:0: +104,88,146505,1,0,0:0:0:0: +44,36,146669,1,8,0:0:0:0: +44,36,146999,1,8,0:0:0:0: +44,36,147329,6,0,L|24:84,1,45,8|0,0:0|0:0,0:0:0:0: +52,156,147658,2,0,L|71:204,1,45,8|0,1:2|0:0,0:0:0:0: +144,236,147988,1,8,0:0:0:0: +144,236,148153,1,8,0:0:0:0: +316,64,148647,5,0,1:0:0:0: +380,116,148812,1,0,0:0:0:0: +408,192,148977,1,0,0:0:0:0: +380,268,149142,1,0,0:0:0:0: +316,320,149307,2,0,L|224:316,1,90,10|8,0:0|0:0,0:0:0:0: +64,248,149966,5,10,0:0:0:0: +144,236,150131,1,0,0:0:0:0: +188,168,150296,1,8,1:2:0:0: +192,88,150461,1,0,0:0:0:0: +140,24,150626,2,0,P|120:16|96:20,1,45,10|0,0:0|0:0,0:0:0:0: +260,132,150955,2,0,P|280:140|304:136,1,45,2|0,0:0|0:0,0:0:0:0: +476,48,151285,6,0,L|484:160,1,112.5,4|0,1:2|0:0,0:0:0:0: +464,236,151779,1,0,0:0:0:0: +436,308,151944,2,0,P|380:320|324:308,1,112.5,8|8,0:0|0:0,0:0:0:0: +76,308,152604,6,0,P|132:320|188:308,1,112.5,8|8,0:0|1:2,0:0:0:0: +256,88,153263,1,8,0:0:0:0: +256,168,153428,1,8,0:0:0:0: +256,168,153922,5,4,1:2:0:0: +256,248,154087,1,0,0:0:0:0: +324,128,154252,1,0,0:0:0:0: +188,128,154417,1,0,0:0:0:0: +332,212,154582,2,0,L|388:204,1,56.25,10|0,0:0|0:0,0:0:0:0: +492,152,154911,2,0,L|436:144,1,56.25,8|0,0:0|0:0,0:0:0:0: +324,128,155241,5,10,0:0:0:0: +180,212,155406,1,0,0:0:0:0: +332,212,155571,1,8,1:2:0:0: +188,128,155735,1,0,0:0:0:0: +256,248,155900,1,10,0:0:0:0: +256,248,156065,2,0,L|256:304,2,56.25,0|0|0,0:0|0:0|0:0,0:0:0:0: +180,212,156560,6,0,L|124:204,1,56.25,4|0,1:2|0:0,0:0:0:0: +20,152,156889,2,0,L|76:144,1,56.25,0|0,0:0|0:0,0:0:0:0: +188,128,157219,2,0,P|212:72|192:16,1,112.5,8|8,0:0|0:0,0:0:0:0: +132,72,157713,1,0,0:0:0:0: +180,212,157878,6,0,L|236:208,1,56.25,8|0,0:0|0:0,0:0:0:0: +360,252,158208,2,8,L|304:248,1,56.25,8|0,1:2|0:0,0:0:0:0: +168,292,158538,2,0,L|160:356,2,56.25,8|8|0,0:0|0:0|0:0,0:0:0:0: +180,212,159032,1,0,0:0:0:0: +144,140,159197,6,0,P|104:128|36:148,1,112.5,2|0,1:2|0:0,0:0:0:0: +12,220,159691,1,0,0:0:0:0: +36,296,159856,2,0,P|60:316|92:324,1,56.25,8|0,0:0|0:0,0:0:0:0: +215,264,160186,2,0,P|189:273|168:292,1,56.25,8|0,0:0|0:0,0:0:0:0: +228,344,160516,6,0,L|284:340,1,56.25,10|0,0:0|0:0,0:0:0:0: +328,276,160845,2,0,L|384:272,1,56.25,8|0,1:2|0:0,0:0:0:0: +428,208,161175,1,8,0:0:0:0: +440,128,161340,1,8,0:0:0:0: +400,60,161505,1,2,0:0:0:0: +328,28,161669,1,0,0:0:0:0: +212,76,161834,6,0,P|200:120|208:164,1,90,2|0,1:2|1:0,0:0:0:0: +300,308,162163,2,0,P|312:264|304:220,1,90,2|0,1:2|1:0,0:0:0:0: +140,236,162493,2,0,P|184:248|228:240,1,90,2|0,1:2|1:0,0:0:0:0: +372,148,162823,2,0,P|328:136|284:144,1,90,2|0,1:2|1:0,0:0:0:0: +104,316,163152,5,2,1:2:0:0: +78,297,163235,1,0,1:0:0:0: +60,270,163317,1,0,1:0:0:0: +54,239,163399,1,0,1:0:0:0: +58,207,163482,1,2,1:2:0:0: +74,180,163564,1,0,1:0:0:0: +98,159,163647,1,0,1:0:0:0: +127,149,163729,1,0,1:0:0:0: +158,150,163812,2,0,L|208:160,1,45,2|0,1:2|1:0,0:0:0:0: +344,184,163976,2,0,L|294:194,1,45,0|0,1:0|1:0,0:0:0:0: +140,236,164141,1,4,1:2:0:0: +140,236,164471,6,0,L|232:252,1,90,4|0,1:2|0:0,0:0:0:0: +344,184,164801,1,8,0:0:0:0: +380,284,164965,1,0,0:0:0:0: +368,104,165130,2,0,P|324:104|284:128,1,90,0|0,0:0|1:0,0:0:0:0: +356,360,165460,2,0,P|400:360|440:336,1,90,8|0,0:0|0:0,0:0:0:0: +432,208,165790,5,0,1:0:0:0: +292,260,165954,1,0,0:0:0:0: +344,184,166119,1,8,0:0:0:0: +204,236,166284,1,0,1:0:0:0: +204,236,166366,1,0,0:0:0:0: +204,236,166449,2,0,L|216:328,1,90,0|0,0:0|1:0,0:0:0:0: +120,208,166779,2,0,L|131:118,1,90,8|0,0:0|0:0,0:0:0:0: +204,236,167108,5,0,1:0:0:0: +32,216,167273,1,0,0:0:0:0: +130,118,167438,1,8,0:0:0:0: +110,298,167603,1,0,0:0:0:0: +110,298,167685,1,0,0:0:0:0: +110,298,167768,2,0,L|121:208,1,90,0|0,0:0|1:0,0:0:0:0: +304,40,168097,2,0,L|315:130,1,90,8|0,0:0|0:0,0:0:0:0: +328,236,168427,5,0,1:0:0:0: +184,148,168592,1,0,0:0:0:0: +314,129,168757,1,8,0:0:0:0: +197,254,168921,1,0,1:0:0:0: +197,254,169004,1,0,0:0:0:0: +197,254,169086,2,0,P|220:292|260:312,1,90,0|0,0:0|1:0,0:0:0:0: +409,210,169416,2,0,P|365:211|328:236,1,90,8|0,0:0|0:0,0:0:0:0: +488,232,169746,6,0,P|487:192|464:149,1,90,0|0,1:0|0:0,0:0:0:0: +314,129,170075,1,8,0:0:0:0: +409,210,170240,1,0,0:0:0:0: +332,40,170405,2,0,L|240:36,1,90,0|0,0:0|1:0,0:0:0:0: +68,144,170735,2,0,L|157:140,1,90,8|0,0:0|0:0,0:0:0:0: +314,129,171064,5,0,1:0:0:0: +332,40,171229,1,0,0:0:0:0: +324,216,171394,1,8,0:0:0:0: +306,305,171559,1,0,1:0:0:0: +257,178,171724,1,0,0:0:0:0: +168,160,171888,1,0,1:0:0:0: +384,164,172053,1,8,0:0:0:0: +473,182,172218,1,0,0:0:0:0: +306,305,172383,6,0,L|216:312,1,90,0|0,1:0|0:0,0:0:0:0: +60,172,172713,1,8,0:0:0:0: +120,260,172877,1,0,0:0:0:0: +168,160,173042,2,0,L|172:68,1,90,0|0,0:0|1:0,0:0:0:0: +309,216,173372,2,0,L|306:306,1,90,8|0,0:0|0:0,0:0:0:0: +120,260,173702,5,0,1:0:0:0: +152,256,173784,1,0,1:0:0:0: +184,252,173866,1,0,1:0:0:0: +309,216,174031,1,8,0:0:0:0: +103,168,174196,1,0,1:0:0:0: +135,164,174279,1,0,1:0:0:0: +167,160,174361,1,0,1:0:0:0: +292,124,174526,1,0,1:0:0:0: +87,76,174691,1,8,1:2:0:0: +119,72,174773,1,0,1:0:0:0: +151,68,174855,1,0,1:0:0:0: +276,32,175020,6,0,L|368:40,1,90,0|0,1:0|0:0,0:0:0:0: +448,108,175350,1,8,0:0:0:0: +292,124,175515,1,0,0:0:0:0: +292,124,175597,1,0,0:0:0:0: +292,124,175680,2,0,L|308:216,1,90,0|0,0:0|1:0,0:0:0:0: +328,320,176009,1,8,0:0:0:0: +408,248,176174,1,0,0:0:0:0: +220,300,176339,6,0,P|176:304|128:292,1,90,0|0,1:0|0:0,0:0:0:0: +16,120,176669,1,8,0:0:0:0: +120,152,176834,1,0,1:0:0:0: +120,152,176916,1,0,0:0:0:0: +120,152,176998,2,0,L|124:200,1,45 +212,176,177163,2,0,L|239:215,1,45,0|0,1:0|0:0,0:0:0:0: +292,124,177328,2,0,P|302:79|283:30,1,90,8|0,0:0|0:0,0:0:0:0: +344,192,177658,6,0,P|372:156|376:104,1,90,0|0,1:0|0:0,0:0:0:0: +212,88,177987,1,8,0:0:0:0: +272,228,178152,1,0,0:0:0:0: +272,228,178235,1,0,0:0:0:0: +272,228,178317,1,0,0:0:0:0: +292,124,178482,1,0,1:0:0:0: +180,180,178647,1,8,0:0:0:0: +200,284,178812,1,0,0:0:0:0: +292,124,178976,5,0,1:0:0:0: +288,92,179059,1,0,0:0:0:0: +280,60,179141,2,0,P|248:24|208:14,1,90,0|8,0:0|0:0,0:0:0:0: +22,65,179471,2,0,P|67:71|112:68,1,90,0|0,1:0|0:0,0:0:0:0: +212,88,179801,1,0,1:0:0:0: +22,65,179965,1,8,0:0:0:0: +180,180,180130,5,0,0:0:0:0: +180,180,180213,1,0,0:0:0:0: +180,180,180295,2,0,P|184:224|172:272,1,90,0|0,1:0|0:0,0:0:0:0: +76,216,180625,2,0,P|72:172|84:124,1,90,8|0,0:0|0:0,0:0:0:0: +380,240,180954,2,0,P|384:284|372:332,1,90,0|0,0:0|1:0,0:0:0:0: +276,276,181284,2,0,P|272:232|284:184,1,90,8|0,0:0|0:0,0:0:0:0: +374,129,181614,5,0,1:0:0:0: +300,352,181779,2,0,L|204:348,2,90,0|8|0,0:0|0:0|1:0,0:0:0:0: +448,180,182273,1,2,0:0:0:0: +448,180,182438,1,2,1:2:0:0: +276,276,182603,1,10,0:0:0:0: +276,276,182768,1,2,0:0:0:0: +96,200,182932,6,0,L|88:108,1,90,0|0,1:0|0:0,0:0:0:0: +96,200,183262,1,8,0:0:0:0: +12,68,183427,2,0,P|72:24|164:68,1,180,0|0,0:0|1:0,0:0:0:0: +140,272,183921,2,0,P|92:284|52:271,1,90,8|0,0:0|0:0,0:0:0:0: +176,156,184251,5,0,1:0:0:0: +208,152,184334,1,0,1:0:0:0: +240,148,184416,1,0,1:0:0:0: +308,64,184581,1,8,0:0:0:0: +296,240,184746,1,0,1:0:0:0: +312,268,184828,1,0,1:0:0:0: +336,284,184910,1,0,1:0:0:0: +368,292,184993,1,0,1:0:0:0: +400,288,185075,1,0,1:0:0:0: +464,184,185240,1,8,0:0:0:0: +468,152,185323,1,0,0:0:0:0: +472,120,185405,2,0,L|464:76,1,45,0|0,1:0|1:0,0:0:0:0: +388,96,185570,6,0,P|360:132|316:148,1,90,4|0,1:2|0:0,0:0:0:0: +224,46,185899,2,0,P|268:43|308:63,1,90,8|0,0:0|0:0,0:0:0:0: +296,240,186229,1,0,0:0:0:0: +308,64,186394,1,0,1:0:0:0: +296,240,186559,2,0,L|312:332,1,90,8|0,0:0|0:0,0:0:0:0: +464,184,186888,6,0,P|420:180|372:188,1,90,0|0,1:0|0:0,0:0:0:0: +296,240,187218,1,8,0:0:0:0: +136,292,187383,2,0,P|94:277|54:249,1,90,0|0,1:0|0:0,0:0:0:0: +21,159,187713,1,0,1:0:0:0: +104,8,187877,2,0,L|124:96,1,90,10|0,0:0|0:0,0:0:0:0: +124,96,188207,6,0,P|152:132|196:148,1,90,0|0,1:0|0:0,0:0:0:0: +287,46,188537,2,0,P|243:43|204:63,1,90,8|0,0:0|0:0,0:0:0:0: +216,240,188866,1,2,0:0:0:0: +204,64,189031,1,0,1:0:0:0: +216,240,189196,2,0,L|200:332,1,90,8|0,0:0|0:0,0:0:0:0: +40,240,189526,5,2,1:2:0:0: +128,192,189691,1,0,0:0:0:0: +216,240,189855,1,8,0:0:0:0: +304,192,190020,1,0,1:0:0:0: +392,240,190185,2,0,L|400:332,1,90,2|0,0:0|1:0,0:0:0:0: +464,168,190515,2,0,L|456:76,1,90,8|0,0:0|0:0,0:0:0:0: +392,240,190844,6,0,P|364:272|312:292,1,90,2|0,1:2|0:0,0:0:0:0: +220,140,191174,2,0,P|248:108|296:92,1,90,8|0,0:0|0:0,0:0:0:0: +324,96,191421,1,0,0:0:0:0: +356,104,191504,2,0,L|340:16,1,90,0|0,0:0|1:0,0:0:0:0: +256,276,191834,2,0,L|272:364,1,90,8|0,0:0|0:0,0:0:0:0: +392,240,192163,5,0,1:0:0:0: +356,104,192328,1,0,0:0:0:0: +220,140,192493,1,8,0:0:0:0: +256,276,192658,1,0,1:0:0:0: +305,191,192823,1,0,0:0:0:0: +212,56,192987,1,0,1:0:0:0: +200,220,193152,1,10,0:0:0:0: +200,220,193482,6,0,P|156:228|108:220,1,90,0|0,1:0|0:0,0:0:0:0: +88,116,193812,1,8,0:0:0:0: +16,192,193976,1,0,0:0:0:0: +16,192,194059,1,0,0:0:0:0: +16,192,194141,2,0,L|28:288,1,90,2|0,0:0|1:0,0:0:0:0: +188,309,194471,2,0,L|200:220,1,90,8|0,0:0|0:0,0:0:0:0: +216,112,194801,5,2,1:2:0:0: +216,112,194883,1,0,1:0:0:0: +216,112,194965,1,0,1:0:0:0: +361,25,195130,1,8,0:0:0:0: +294,180,195295,1,0,1:0:0:0: +294,180,195377,1,0,1:0:0:0: +294,180,195460,1,2,0:0:0:0: +256,16,195625,1,0,1:0:0:0: +384,127,195790,1,10,1:2:0:0: +416,132,195872,1,0,1:0:0:0: +448,140,195954,2,0,L|452:84,1,45,0|0,1:0|1:0,0:0:0:0: +416,216,196119,6,0,P|412:264|432:312,1,90,4|0,1:2|0:0,0:0:0:0: +304,268,196449,2,0,P|308:220|288:172,1,90,8|0,0:0|0:0,0:0:0:0: +216,112,196779,2,0,L|120:104,1,90,0|0,0:0|1:0,0:0:0:0: +52,248,197108,2,0,L|141:255,1,90,8|0,0:0|0:0,0:0:0:0: +304,268,197438,5,0,1:0:0:0: +416,216,197603,1,0,0:0:0:0: +408,340,197768,1,8,0:0:0:0: +332,180,197932,1,0,1:0:0:0: +332,180,198015,1,0,0:0:0:0: +332,180,198097,2,0,P|360:140|400:120,1,90,0|0,0:0|1:0,0:0:0:0: +484,284,198427,1,10,0:0:0:0: +304,268,198592,1,2,0:0:0:0: +416,216,198757,6,0,P|428:172|420:124,1,90,2|0,1:2|0:0,0:0:0:0: +344,52,199086,1,8,0:0:0:0: +332,180,199251,1,0,0:0:0:0: +164,236,199416,2,0,P|152:192|160:144,1,90,0|0,0:0|1:0,0:0:0:0: +236,72,199746,1,8,0:0:0:0: +248,200,199910,1,0,0:0:0:0: +156,328,200075,6,0,L|56:320,1,90,2|0,1:2|0:0,0:0:0:0: +164,236,200405,1,8,0:0:0:0: +256,292,200570,2,0,P|300:296|344:284,1,90,0|0,1:0|0:0,0:0:0:0: +432,220,200899,2,0,L|460:308,2,90,0|8|0,1:0|0:0|0:0,0:0:0:0: +392,120,201394,5,4,1:2:0:0: +396,32,201559,1,0,1:0:0:0: +316,72,201724,1,0,1:0:0:0: +256,6,201888,1,0,1:0:0:0: +228,91,202053,1,0,1:0:0:0: +139,87,202218,1,0,1:0:0:0: +179,166,202383,1,0,1:0:0:0: +113,226,202548,1,0,1:0:0:0: +197,253,202713,5,4,1:2:0:0: +193,342,202877,1,0,1:0:0:0: +272,302,203042,1,0,1:0:0:0: +332,367,203207,1,0,1:0:0:0: +359,283,203372,1,2,1:2:0:0: +448,287,203537,1,2,1:2:0:0: +407,208,203702,1,2,1:2:0:0: +472,147,203866,1,2,1:2:0:0: +387,121,204031,5,4,1:2:0:0: +360,100,204114,1,0,1:0:0:0: +344,72,204196,1,0,1:0:0:0: +336,40,204279,1,0,1:0:0:0: +340,8,204361,1,0,1:0:0:0: +316,28,204443,1,0,1:0:0:0: +284,32,204526,1,0,1:0:0:0: +252,28,204608,1,0,1:0:0:0: +228,8,204691,2,0,L|184:20,7,45,4|0|0|0|0|0|0|0,1:2|1:0|1:0|1:0|1:0|1:0|1:0|1:0,0:0:0:0: +112,56,205350,5,4,1:2:0:0: +100,84,205432,1,0,1:0:0:0: +96,116,205515,1,0,1:0:0:0: +100,148,205597,1,0,1:0:0:0: +112,176,205680,1,0,1:0:0:0: +124,204,205762,1,0,1:0:0:0: +128,236,205844,1,0,1:0:0:0: +124,268,205927,1,0,1:0:0:0: +112,296,206009,2,0,L|71:313,3,45,2|0|2|0,1:2|0:0|0:0|0:0,0:0:0:0: +192,312,206339,2,0,L|175:353,3,45,2|0|2|0,1:2|0:0|0:0|0:0,0:0:0:0: +256,264,206669,5,4,1:2:0:0: +256,192,206751,12,0,209306,0:0:0:0: diff --git a/osu.Game/Beatmaps/Formats/LegacyBeatmapDecoder.cs b/osu.Game/Beatmaps/Formats/LegacyBeatmapDecoder.cs index 3cd425ea44..24843f8c32 100644 --- a/osu.Game/Beatmaps/Formats/LegacyBeatmapDecoder.cs +++ b/osu.Game/Beatmaps/Formats/LegacyBeatmapDecoder.cs @@ -290,8 +290,12 @@ namespace osu.Game.Beatmaps.Formats string[] split = line.Split(','); EventType type; + if (!Enum.TryParse(split[0], out type)) - throw new InvalidDataException($@"Unknown event type {split[0]}"); + { + Logger.Log($"A beatmap event could not be parsed and will be ignored: {split[0]}", LoggingTarget.Runtime, LogLevel.Important); + return; + } switch (type) { diff --git a/osu.Game/Beatmaps/Formats/LegacyStoryboardDecoder.cs b/osu.Game/Beatmaps/Formats/LegacyStoryboardDecoder.cs index f6e2bf6966..1dcafb4669 100644 --- a/osu.Game/Beatmaps/Formats/LegacyStoryboardDecoder.cs +++ b/osu.Game/Beatmaps/Formats/LegacyStoryboardDecoder.cs @@ -10,6 +10,7 @@ using osuTK; using osuTK.Graphics; using osu.Framework.Graphics; using osu.Framework.IO.File; +using osu.Framework.Logging; using osu.Game.Storyboards; namespace osu.Game.Beatmaps.Formats @@ -83,7 +84,7 @@ namespace osu.Game.Beatmaps.Formats EventType type; if (!Enum.TryParse(split[0], out type)) - throw new InvalidDataException($@"Unknown event type {split[0]}"); + Logger.Log($"A storyboard event could not be parsed and will be ignored: {split[0]}", LoggingTarget.Runtime, LogLevel.Important); switch (type) { From a5c17ae26d81b778c2b8e87f2c1c074d7bf72267 Mon Sep 17 00:00:00 2001 From: David Zhao Date: Tue, 6 Aug 2019 10:14:36 +0900 Subject: [PATCH 09/49] Don't use GetDecoder --- osu.Game.Tests/Beatmaps/Formats/LegacyBeatmapDecoderTest.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/osu.Game.Tests/Beatmaps/Formats/LegacyBeatmapDecoderTest.cs b/osu.Game.Tests/Beatmaps/Formats/LegacyBeatmapDecoderTest.cs index 98464b8d91..7e0374023e 100644 --- a/osu.Game.Tests/Beatmaps/Formats/LegacyBeatmapDecoderTest.cs +++ b/osu.Game.Tests/Beatmaps/Formats/LegacyBeatmapDecoderTest.cs @@ -486,12 +486,13 @@ namespace osu.Game.Tests.Beatmaps.Formats [Test] public void TestDecodeInvalidEvents() { + var decoder = new LegacyBeatmapDecoder { ApplyOffsets = false }; + using (var normalResStream = TestResources.OpenResource("Soleily - Renatus (Gamu) [Insane].osu")) using (var normalStream = new StreamReader(normalResStream)) using (var resStream = TestResources.OpenResource("invalid-events.osu")) using (var stream = new StreamReader(resStream)) { - var decoder = Decoder.GetDecoder(stream); var goodBeatmap = decoder.Decode(normalStream); Beatmap badBeatmap = null; From b8c38d4dfd5ba9a8cd3acc70ab0f0fcda7495cb7 Mon Sep 17 00:00:00 2001 From: David Zhao Date: Tue, 6 Aug 2019 10:36:26 +0900 Subject: [PATCH 10/49] remove unnecessary assert --- osu.Game.Tests/Beatmaps/Formats/LegacyBeatmapDecoderTest.cs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/osu.Game.Tests/Beatmaps/Formats/LegacyBeatmapDecoderTest.cs b/osu.Game.Tests/Beatmaps/Formats/LegacyBeatmapDecoderTest.cs index 7e0374023e..bbc3b05d89 100644 --- a/osu.Game.Tests/Beatmaps/Formats/LegacyBeatmapDecoderTest.cs +++ b/osu.Game.Tests/Beatmaps/Formats/LegacyBeatmapDecoderTest.cs @@ -494,9 +494,8 @@ namespace osu.Game.Tests.Beatmaps.Formats using (var stream = new StreamReader(resStream)) { var goodBeatmap = decoder.Decode(normalStream); - Beatmap badBeatmap = null; + var badBeatmap = decoder.Decode(stream); - Assert.DoesNotThrow(() => badBeatmap = decoder.Decode(stream)); Assert.AreEqual(goodBeatmap.HitObjects.Count, badBeatmap.HitObjects.Count); } } From 2c32d886d7cf77e7615ebe93a7afadb00b1d81ef Mon Sep 17 00:00:00 2001 From: David Zhao Date: Tue, 6 Aug 2019 10:39:54 +0900 Subject: [PATCH 11/49] Add better asserts --- osu.Game.Tests/Beatmaps/Formats/LegacyBeatmapDecoderTest.cs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/osu.Game.Tests/Beatmaps/Formats/LegacyBeatmapDecoderTest.cs b/osu.Game.Tests/Beatmaps/Formats/LegacyBeatmapDecoderTest.cs index bbc3b05d89..e88c3c8ecc 100644 --- a/osu.Game.Tests/Beatmaps/Formats/LegacyBeatmapDecoderTest.cs +++ b/osu.Game.Tests/Beatmaps/Formats/LegacyBeatmapDecoderTest.cs @@ -496,6 +496,8 @@ namespace osu.Game.Tests.Beatmaps.Formats var goodBeatmap = decoder.Decode(normalStream); var badBeatmap = decoder.Decode(stream); + Assert.AreEqual(goodBeatmap.Breaks[0].Duration, badBeatmap.Breaks[0].Duration); + Assert.AreEqual(goodBeatmap.Metadata.BackgroundFile, badBeatmap.Metadata.BackgroundFile); Assert.AreEqual(goodBeatmap.HitObjects.Count, badBeatmap.HitObjects.Count); } } From 66b02c02831a2004c53b755d0159fea08c9bf2ad Mon Sep 17 00:00:00 2001 From: David Zhao Date: Tue, 6 Aug 2019 12:27:10 +0900 Subject: [PATCH 12/49] log type as well --- osu.Game/Beatmaps/Formats/LegacyBeatmapDecoder.cs | 2 +- osu.Game/Beatmaps/Formats/LegacyStoryboardDecoder.cs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/osu.Game/Beatmaps/Formats/LegacyBeatmapDecoder.cs b/osu.Game/Beatmaps/Formats/LegacyBeatmapDecoder.cs index 24843f8c32..c92c0ba22d 100644 --- a/osu.Game/Beatmaps/Formats/LegacyBeatmapDecoder.cs +++ b/osu.Game/Beatmaps/Formats/LegacyBeatmapDecoder.cs @@ -293,7 +293,7 @@ namespace osu.Game.Beatmaps.Formats if (!Enum.TryParse(split[0], out type)) { - Logger.Log($"A beatmap event could not be parsed and will be ignored: {split[0]}", LoggingTarget.Runtime, LogLevel.Important); + Logger.Log($"A beatmap {type} event could not be parsed and will be ignored: {split[0]}", LoggingTarget.Runtime, LogLevel.Important); return; } diff --git a/osu.Game/Beatmaps/Formats/LegacyStoryboardDecoder.cs b/osu.Game/Beatmaps/Formats/LegacyStoryboardDecoder.cs index 1dcafb4669..512eea0822 100644 --- a/osu.Game/Beatmaps/Formats/LegacyStoryboardDecoder.cs +++ b/osu.Game/Beatmaps/Formats/LegacyStoryboardDecoder.cs @@ -84,7 +84,7 @@ namespace osu.Game.Beatmaps.Formats EventType type; if (!Enum.TryParse(split[0], out type)) - Logger.Log($"A storyboard event could not be parsed and will be ignored: {split[0]}", LoggingTarget.Runtime, LogLevel.Important); + Logger.Log($"A storyboard {type} event could not be parsed and will be ignored: {split[0]}", LoggingTarget.Runtime, LogLevel.Important); switch (type) { From 497d2cb67784287c5217fe0c5279bfab7748bab7 Mon Sep 17 00:00:00 2001 From: David Zhao Date: Tue, 6 Aug 2019 12:35:18 +0900 Subject: [PATCH 13/49] shorten tests and rename --- .../Formats/LegacyBeatmapDecoderTest.cs | 13 +- osu.Game.Tests/Resources/invalid-events.osu | 992 +----------------- osu.Game.Tests/Resources/valid-events.osu | 12 + 3 files changed, 19 insertions(+), 998 deletions(-) create mode 100644 osu.Game.Tests/Resources/valid-events.osu diff --git a/osu.Game.Tests/Beatmaps/Formats/LegacyBeatmapDecoderTest.cs b/osu.Game.Tests/Beatmaps/Formats/LegacyBeatmapDecoderTest.cs index e88c3c8ecc..49a6f646ba 100644 --- a/osu.Game.Tests/Beatmaps/Formats/LegacyBeatmapDecoderTest.cs +++ b/osu.Game.Tests/Beatmaps/Formats/LegacyBeatmapDecoderTest.cs @@ -488,17 +488,16 @@ namespace osu.Game.Tests.Beatmaps.Formats { var decoder = new LegacyBeatmapDecoder { ApplyOffsets = false }; - using (var normalResStream = TestResources.OpenResource("Soleily - Renatus (Gamu) [Insane].osu")) - using (var normalStream = new StreamReader(normalResStream)) - using (var resStream = TestResources.OpenResource("invalid-events.osu")) - using (var stream = new StreamReader(resStream)) + using (var goodResStream = TestResources.OpenResource("valid-events.osu")) + using (var goodStream = new StreamReader(goodResStream)) + using (var badResStream = TestResources.OpenResource("invalid-events.osu")) + using (var badStream = new StreamReader(badResStream)) { - var goodBeatmap = decoder.Decode(normalStream); - var badBeatmap = decoder.Decode(stream); + var goodBeatmap = decoder.Decode(goodStream); + var badBeatmap = decoder.Decode(badStream); Assert.AreEqual(goodBeatmap.Breaks[0].Duration, badBeatmap.Breaks[0].Duration); Assert.AreEqual(goodBeatmap.Metadata.BackgroundFile, badBeatmap.Metadata.BackgroundFile); - Assert.AreEqual(goodBeatmap.HitObjects.Count, badBeatmap.HitObjects.Count); } } } diff --git a/osu.Game.Tests/Resources/invalid-events.osu b/osu.Game.Tests/Resources/invalid-events.osu index a8e767585c..df86b26dba 100644 --- a/osu.Game.Tests/Resources/invalid-events.osu +++ b/osu.Game.Tests/Resources/invalid-events.osu @@ -1,43 +1,5 @@ osu file format v14 -[General] -AudioFilename: 03. Renatus - Soleily 192kbps.mp3 -AudioLeadIn: 0 -PreviewTime: 164471 -Countdown: 0 -SampleSet: Soft -StackLeniency: 0.7 -Mode: 0 -LetterboxInBreaks: 0 -WidescreenStoryboard: 0 - -[Editor] -Bookmarks: 11505,22054,32604,43153,53703,64252,74802,85351,95901,106450,116999,119637,130186,140735,151285,161834,164471,175020,185570,196119,206669,209306 -DistanceSpacing: 1.8 -BeatDivisor: 4 -GridSize: 4 -TimelineZoom: 2 - -[Metadata] -Title:Renatus -TitleUnicode:Renatus -Artist:Soleily -ArtistUnicode:Soleily -Creator:Gamu -Version:Insane -Source: -Tags:MBC7 Unisphere 地球ヤバイEP Chikyu Yabai -BeatmapID:557821 -BeatmapSetID:241526 - -[Difficulty] -HPDrainRate:6.5 -CircleSize:4 -OverallDifficulty:8 -ApproachRate:9 -SliderMultiplier:1.8 -SliderTickRate:2 - [Events] bad,event,this,should,fail //Background and Video events @@ -45,960 +7,8 @@ bad,event,this,should,fail //Break Periods 2,122474,140135 //Storyboard Layer 0 (Background) +this,is,also,bad //Storyboard Layer 1 (Fail) //Storyboard Layer 2 (Pass) //Storyboard Layer 3 (Foreground) //Storyboard Sound Samples - -[TimingPoints] -956,329.67032967033,4,2,0,60,1,0 -20736,-100,4,2,0,65,0,0 -22054,-100,4,2,0,70,0,0 -43153,-100,4,2,0,60,0,0 -48428,-100,4,2,0,50,0,0 -52879,-100,4,2,0,50,0,0 -53373,-100,4,2,0,60,0,0 -53703,-100,4,2,0,70,0,1 -74719,-100,4,2,0,70,0,0 -74802,-100,4,2,0,70,0,1 -95901,-100,4,2,0,70,0,0 -116999,-133.333333333333,4,2,0,50,0,0 -117164,-133.333333333333,4,2,0,30,0,0 -117329,-79.9999999999999,4,2,0,50,0,0 -117659,-100,4,2,0,50,0,0 -118977,-100,4,2,0,60,0,0 -119307,-100,4,2,0,70,0,0 -119637,659.340659340659,4,2,0,80,1,0 -119966,-100,4,2,0,70,0,0 -120296,-100,4,2,0,60,0,0 -120626,-100,4,2,0,50,0,0 -120955,-100,4,2,0,40,0,0 -121285,-100,4,2,0,30,0,0 -121615,-100,4,2,0,20,0,0 -121944,-100,4,2,0,10,0,0 -122274,-100,4,2,0,5,0,0 -140735,-100,4,2,0,50,0,0 -151285,-80,4,2,0,60,0,0 -161834,329.67032967033,4,2,0,65,1,0 -164141,-100,4,2,0,70,0,0 -164471,-100,4,2,0,70,0,1 -185487,-100,4,2,0,70,0,0 -185570,-100,4,2,0,70,0,1 -206669,659.340659340659,4,2,0,80,1,0 -206998,-100,4,2,0,70,0,0 -207328,-100,4,2,0,60,0,0 -207658,-100,4,2,0,50,0,0 -207987,-100,4,2,0,40,0,0 -208317,-100,4,2,0,30,0,0 -208647,-100,4,2,0,20,0,0 -208976,-100,4,2,0,10,0,0 -209306,-100,4,2,0,5,0,0 - - -[Colours] -Combo1 : 142,199,255 -Combo2 : 255,128,128 -Combo3 : 128,255,255 -Combo4 : 128,255,128 -Combo5 : 255,187,255 -Combo6 : 255,177,140 -Combo7 : 100,100,100,100 - -[HitObjects] -192,168,956,6,0,P|184:128|200:80,1,90,4|0,1:2|0:0,0:0:0:0: -304,56,1285,1,8,0:0:0:0: -244,236,1450,2,0,P|204:252|156:244,1,90,2|0,0:0|0:0,0:0:0:0: -276,156,1780,2,0,P|310:181|329:226,1,90,2|8,1:2|0:0,0:0:0:0: -300,328,2109,1,2,0:0:0:0: -192,332,2274,6,0,L|144:340,2,45,0|0|0,1:0|0:0|0:0,0:0:0:0: -388,300,2604,1,8,0:0:0:0: -244,236,2769,1,0,1:0:0:0: -232,208,2851,1,0,0:0:0:0: -224,176,2934,1,0,0:0:0:0: -228,144,3016,1,0,0:0:0:0: -244,116,3098,1,0,1:0:0:0: -332,52,3263,2,0,P|376:48|424:56,1,90,8|0,0:0|0:0,0:0:0:0: -488,228,3593,5,0,1:0:0:0: -460,240,3675,1,0,0:0:0:0: -428,236,3758,1,0,0:0:0:0: -292,160,3923,2,0,P|288:204|300:252,1,90,8|0,0:0|0:0,0:0:0:0: -316,276,4170,1,0,0:0:0:0: -344,292,4252,2,0,L|388:300,1,45,0|0,0:0|0:0,0:0:0:0: -288,356,4417,2,0,L|244:364,1,45,0|0,1:0|0:0,0:0:0:0: -168,328,4582,2,0,P|124:324|72:332,1,90,8|0,0:0|0:0,0:0:0:0: -24,188,4912,5,0,1:0:0:0: -56,192,4994,1,0,0:0:0:0: -88,196,5076,1,0,0:0:0:0: -148,108,5241,1,8,0:0:0:0: -188,240,5406,1,0,1:0:0:0: -188,240,5488,1,0,0:0:0:0: -188,240,5571,2,0,L|168:328,1,90,0|0,0:0|1:0,0:0:0:0: -260,216,5901,2,0,P|236:180|188:164,1,90,8|0,0:0|0:0,0:0:0:0: -248,296,6230,6,0,L|348:292,1,90,0|0,1:0|0:0,0:0:0:0: -504,232,6560,1,8,0:0:0:0: -400,204,6725,1,0,0:0:0:0: -392,176,6807,1,0,0:0:0:0: -384,144,6890,1,0,0:0:0:0: -376,116,6972,1,0,0:0:0:0: -368,88,7054,1,0,1:0:0:0: -188,48,7219,2,0,L|208:140,1,90,8|0,0:0|0:0,0:0:0:0: -248,296,7549,5,0,1:0:0:0: -207,135,7714,1,0,0:0:0:0: -156,232,7879,1,8,0:0:0:0: -316,191,8043,1,0,1:0:0:0: -316,191,8126,1,0,0:0:0:0: -316,191,8208,2,0,L|372:200,1,45,0|0,0:0|0:0,0:0:0:0: -492,200,8373,2,0,L|447:207,1,45,0|0,1:0|0:0,0:0:0:0: -408,136,8538,2,0,P|396:92|400:48,1,90,8|0,0:0|0:0,0:0:0:0: -260,32,8868,5,0,1:0:0:0: -252,64,8950,1,0,0:0:0:0: -236,92,9032,2,0,P|204:116|148:128,1,90,0|8,0:0|0:0,0:0:0:0: -28,188,9362,1,0,0:0:0:0: -60,196,9445,1,0,0:0:0:0: -88,212,9527,2,0,P|112:244|124:300,1,90,0|0,0:0|1:0,0:0:0:0: -112,128,9857,2,0,P|152:156|184:196,1,90,8|0,0:0|0:0,0:0:0:0: -216,288,10186,5,0,1:0:0:0: -216,288,10269,1,0,0:0:0:0: -216,288,10351,1,0,0:0:0:0: -268,192,10516,1,8,0:0:0:0: -356,128,10681,1,0,1:0:0:0: -388,120,10763,1,0,0:0:0:0: -420,128,10846,2,0,P|440:168|436:220,1,90,0|0,0:0|1:0,0:0:0:0: -332,328,11175,2,0,L|280:332,1,45,8|8,0:0|0:0,0:0:0:0: -216,288,11340,2,0,L|164:292,1,45,0|0,1:0|0:0,1:0:0:0: -100,248,11505,5,4,1:2:0:0: -148,116,11670,1,2,0:0:0:0: -268,192,11835,1,10,0:0:0:0: -136,328,11999,2,0,L|44:336,1,90,2|0,0:0|0:0,0:0:0:0: -216,288,12329,1,2,1:2:0:0: -148,116,12494,1,10,0:0:0:0: -100,248,12659,1,2,0:0:0:0: -268,192,12824,5,0,1:0:0:0: -268,192,12906,1,0,0:0:0:0: -268,192,12988,1,0,0:0:0:0: -340,272,13153,2,0,P|384:276|432:264,1,90,8|0,0:0|1:0,0:0:0:0: -452,244,13401,1,0,0:0:0:0: -468,216,13483,2,0,L|476:124,1,90,0|0,0:0|1:0,0:0:0:0: -368,32,13813,2,0,L|360:121,1,90,8|0,0:0|0:0,0:0:0:0: -340,272,14142,6,0,L|316:316,2,45,0|0|0,1:0|0:0|0:0,0:0:0:0: -452,244,14472,1,8,0:0:0:0: -268,192,14637,1,0,0:0:0:0: -236,188,14719,1,0,0:0:0:0: -204,192,14802,2,0,P|172:228|160:272,1,90,0|0,0:0|1:0,0:0:0:0: -128,140,15131,2,0,P|160:104|172:60,1,90,8|0,0:0|0:0,0:0:0:0: -64,52,15461,6,0,L|20:68,2,45,0|0|0,1:0|0:0|0:0,0:0:0:0: -171,64,15791,1,8,0:0:0:0: -264,8,15956,2,0,L|356:12,1,90,0|0,1:0|0:0,0:0:0:0: -452,56,16285,1,0,1:0:0:0: -296,140,16450,2,0,L|206:136,1,90,8|0,0:0|0:0,0:0:0:0: -108,184,16780,6,0,P|92:224|96:272,1,90,0|0,1:0|0:0,0:0:0:0: -200,244,17109,1,8,0:0:0:0: -108,108,17274,2,0,L|12:116,1,90,0|0,0:0|0:0,0:0:0:0: -200,244,17604,1,0,1:0:0:0: -296,140,17769,2,0,L|385:132,1,90,8|0,0:0|0:0,0:0:0:0: -480,184,18098,5,0,1:0:0:0: -488,216,18181,1,0,0:0:0:0: -496,248,18263,2,0,L|492:340,1,90,0|8,0:0|0:0,0:0:0:0: -404,224,18593,2,0,L|396:176,2,45,0|0|0,1:0|0:0|0:0,0:0:0:0: -304,264,18923,1,0,1:0:0:0: -200,244,19087,2,0,P|156:240|108:248,1,90,8|0,0:0|0:0,0:0:0:0: -296,140,19417,6,0,P|340:144|388:136,1,90,0|0,1:0|0:0,0:0:0:0: -440,44,19747,1,8,0:0:0:0: -404,224,19912,1,0,0:0:0:0: -404,224,19994,1,0,0:0:0:0: -404,224,20076,2,0,L|412:320,1,90,0|0,0:0|1:0,0:0:0:0: -200,244,20406,2,0,L|192:154,1,90,8|0,0:0|0:0,0:0:0:0: -184,44,20736,5,4,1:2:0:0: -152,40,20818,1,0,0:0:0:0: -120,48,20901,1,0,0:0:0:0: -96,68,20983,1,0,0:0:0:0: -76,92,21065,1,2,0:3:0:0: -64,120,21148,1,0,0:0:0:0: -60,152,21230,1,0,1:0:0:0: -64,184,21313,1,0,0:0:0:0: -76,212,21395,2,0,L|96:252,3,45,0|0|0|0,0:0|0:0|1:0|0:0,0:0:0:0: -144,316,21725,2,0,L|188:324,3,45,0|0|2|0,0:0|0:0|0:3|0:0,0:0:0:0: -268,340,22054,6,0,L|364:336,1,90,4|0,1:2|0:0,0:0:0:0: -452,280,22384,1,8,0:0:0:0: -512,188,22549,2,0,P|516:144|504:96,1,90,2|0,0:0|0:0,0:0:0:0: -340,24,22879,2,0,P|336:68|348:116,1,90,2|8,1:2|0:0,0:0:0:0: -420,192,23208,1,2,0:0:0:0: -328,252,23373,6,0,L|232:240,1,90,0|0,1:0|0:0,0:0:0:0: -64,256,23703,1,8,0:0:0:0: -144,184,23868,2,0,P|148:140|136:88,1,90,0|0,1:0|0:0,0:0:0:0: -40,52,24197,1,2,1:2:0:0: -139,95,24362,1,8,0:0:0:0: -216,20,24527,1,0,0:0:0:0: -315,63,24692,6,0,P|360:72|408:68,1,90,2|0,1:2|0:0,0:0:0:0: -492,132,25021,1,8,0:0:0:0: -412,204,25186,2,0,P|403:249|407:297,1,90,2|0,0:0|0:0,0:0:0:0: -268,328,25516,2,0,P|277:283|273:235,1,90,2|8,1:2|0:0,0:0:0:0: -232,140,25846,2,0,P|187:131|139:135,1,90,2|0,0:0|1:0,0:0:0:0: -64,208,26175,5,2,0:0:0:0: -44,316,26340,1,8,0:0:0:0: -148,280,26505,1,2,1:2:0:0: -456,208,26835,1,2,1:2:0:0: -476,316,26999,1,10,0:0:0:0: -372,280,27164,1,2,0:0:0:0: -356,172,27329,6,0,L|380:80,1,90,0|0,1:0|0:0,0:0:0:0: -456,208,27659,1,8,0:0:0:0: -300,236,27824,1,2,0:0:0:0: -300,236,27906,1,0,0:0:0:0: -300,236,27988,2,0,L|208:228,1,90,0|2,0:0|1:2,0:0:0:0: -140,312,28318,1,8,0:0:0:0: -372,280,28483,2,0,L|464:272,1,90,2|0,0:0|1:0,0:0:0:0: -500,136,28813,5,2,0:0:0:0: -432,56,28977,1,8,0:0:0:0: -328,24,29142,2,0,P|284:24|236:28,1,90,2|0,1:2|0:0,0:0:0:0: -80,144,29472,1,2,1:2:0:0: -116,44,29637,1,10,0:0:0:0: -184,128,29802,1,2,0:0:0:0: -20,88,29966,6,0,P|1:164|73:227,1,180,2|10,1:2|0:0,0:0:0:0: -184,128,30461,2,0,P|227:120|276:124,1,90,2|0,0:0|0:0,0:0:0:0: -392,188,30791,1,2,1:2:0:0: -272,260,30956,1,8,0:0:0:0: -396,328,31120,1,0,0:0:0:0: -256,348,31285,5,2,1:2:0:0: -224,344,31368,1,0,1:0:0:0: -192,340,31450,2,0,L|172:248,1,90,2|0,1:2|1:0,0:0:0:0: -8,136,31780,2,0,L|27:223,1,90,2|0,1:2|0:0,0:0:0:0: -56,328,32109,1,2,1:2:0:0: -108,192,32274,1,2,1:2:0:0: -100,160,32357,1,0,1:0:0:0: -92,132,32439,1,2,1:2:0:0: -84,104,32521,1,0,1:0:0:0: -76,72,32604,6,0,P|100:112|148:136,1,90,4|0,1:2|0:0,0:0:0:0: -240,168,32934,1,8,0:0:0:0: -336,124,33098,2,0,L|344:80,2,45,2|0|0,0:0|0:0|0:0,0:0:0:0: -264,248,33428,2,0,P|220:248|176:220,1,90,2|8,1:2|0:0,0:0:0:0: -260,84,33758,1,2,0:0:0:0: -344,212,33923,5,0,1:0:0:0: -344,212,34005,1,0,0:0:0:0: -344,212,34087,1,0,0:0:0:0: -440,160,34252,1,8,0:0:0:0: -312,320,34417,2,0,P|272:336|220:324,1,90,0|0,1:0|0:0,0:0:0:0: -156,176,34747,2,0,P|196:160|248:172,2,90,2|8|0,1:2|0:0|0:0,0:0:0:0: -132,280,35241,5,2,1:2:0:0: -132,280,35324,1,0,0:0:0:0: -132,280,35406,2,0,L|120:376,1,90,0|8,0:0|0:0,0:0:0:0: -312,320,35736,2,0,L|300:230,1,90,2|0,0:0|0:0,0:0:0:0: -316,124,36065,1,2,1:2:0:0: -400,192,36230,1,8,0:0:0:0: -300,230,36395,2,0,P|255:231|211:224,1,90,2|0,0:0|1:0,0:0:0:0: -24,132,36725,5,0,0:0:0:0: -132,152,36890,1,8,0:0:0:0: -60,232,37054,1,2,1:2:0:0: -60,232,37137,1,0,0:0:0:0: -60,232,37219,1,0,0:0:0:0: -92,56,37384,2,0,L|184:44,1,90,2|10,1:2|0:0,0:0:0:0: -316,124,37714,2,0,L|226:135,1,90,2|0,0:0|1:0,0:0:0:0: -60,232,38043,6,0,P|52:276|64:328,1,90,0|8,0:0|0:0,0:0:0:0: -220,152,38373,2,0,P|176:144|124:156,1,90,2|0,0:0|0:0,0:0:0:0: -176,252,38703,1,2,1:2:0:0: -323,213,38868,2,0,L|316:124,1,90,8|2,0:0|0:0,0:0:0:0: -332,320,39197,5,0,1:0:0:0: -424,260,39362,1,2,0:0:0:0: -260,272,39527,2,0,P|246:313|256:360,1,90,8|2,0:0|1:2,0:0:0:0: -408,336,39857,1,0,0:0:0:0: -176,252,40021,2,0,L|80:260,2,90,2|10|2,1:2|0:0|0:0,0:0:0:0: -324,212,40516,5,2,1:2:0:0: -324,212,40598,1,0,1:0:0:0: -324,212,40681,1,0,1:0:0:0: -200,336,40846,1,2,1:2:0:0: -236,188,41010,1,2,1:2:0:0: -236,188,41093,1,0,1:0:0:0: -236,188,41175,1,0,1:0:0:0: -281,357,41340,1,2,1:2:0:0: -176,252,41505,1,2,1:2:0:0: -176,252,41587,1,0,1:0:0:0: -176,252,41670,1,0,1:0:0:0: -344,297,41835,5,2,1:2:0:0: -432,232,41999,1,2,1:2:0:0: -444,204,42082,1,0,1:0:0:0: -448,172,42164,1,0,1:0:0:0: -444,140,42247,1,0,1:0:0:0: -432,112,42329,2,0,L|440:64,2,45,2|0|0,1:2|1:0|1:0,0:0:0:0: -236,188,42659,1,0,0:0:0:0: -340,172,42824,1,2,0:3:0:0: -272,88,42988,1,0,0:0:0:0: -132,160,43153,6,0,P|148:248|220:296,1,180,4|8,1:2|0:0,0:0:0:0: -324,320,43648,2,0,L|336:364,2,45,0|0|0,0:0|0:0|0:0,0:0:0:0: -292,216,43977,1,0,1:0:0:0: -396,240,44142,2,0,P|440:244|488:232,1,90,8|0,0:0|0:0,0:0:0:0: -328,124,44472,6,0,P|284:120|236:132,1,90,0|0,1:0|0:0,0:0:0:0: -168,212,44802,1,8,0:0:0:0: -192,316,44966,1,0,1:0:0:0: -140,220,45131,1,0,0:0:0:0: -83,310,45296,1,0,1:0:0:0: -114,205,45461,1,8,0:0:0:0: -10,229,45626,1,0,0:0:0:0: -106,176,45791,6,0,P|113:133|108:85,1,90,0|0,1:0|0:0,0:0:0:0: -204,136,46120,1,8,0:0:0:0: -256,40,46285,1,0,0:0:0:0: -256,40,46368,1,0,0:0:0:0: -256,40,46450,2,0,L|356:44,1,90,0|0,0:0|1:0,0:0:0:0: -501,124,46780,2,0,L|412:128,1,90,8|0,0:0|0:0,0:0:0:0: -324,192,47109,5,0,1:0:0:0: -356,296,47274,1,0,0:0:0:0: -284,216,47439,1,8,0:0:0:0: -269,323,47604,1,0,1:0:0:0: -237,220,47769,1,0,0:0:0:0: -178,311,47934,1,0,1:0:0:0: -191,203,48098,1,8,0:0:0:0: -99,261,48263,1,0,0:0:0:0: -156,168,48428,6,0,B|176:112|136:64|136:64|200:96,1,180,4|8,1:2|0:0,0:0:0:0: -300,124,48923,2,0,L|392:120,1,90,0|0,0:0|0:0,0:0:0:0: -468,48,49252,1,0,1:0:0:0: -390,120,49417,2,0,P|390:164|406:208,1,90,8|0,0:0|0:0,0:0:0:0: -352,344,49747,6,0,P|352:300|336:256,1,90,4|0,1:2|0:0,0:0:0:0: -240,208,50076,1,8,0:0:0:0: -163,320,50241,2,0,P|207:324|252:316,1,90,0|0,1:0|0:0,0:0:0:0: -240,208,50571,1,0,1:0:0:0: -76,296,50736,2,0,P|76:340|92:384,1,90,8|0,0:0|0:0,0:0:0:0: -312,164,51065,6,0,P|236:124|160:184,1,180,4|8,1:2|0:0,0:0:0:0: -247,297,51560,2,0,L|240:208,1,90,0|0,0:0|0:0,0:0:0:0: -224,48,51890,1,0,1:0:0:0: -332,56,52054,2,0,L|366:58,5,30,8|0|0|0|0|0,0:0|0:0|0:0|0:0|0:0|0:0,0:0:0:0: -408,64,52384,6,0,P|420:108|416:156,1,90,0|0,1:0|0:0,0:0:0:0: -360,260,52714,1,8,0:0:0:0: -247,297,52879,2,0,B|203:281|159:297|159:297|115:313|71:297,1,180,0|0,1:0|1:0,0:0:0:0: -116,196,53373,1,8,0:0:0:0: -120,164,53456,1,0,0:0:0:0: -124,132,53538,1,0,0:0:0:0: -128,100,53620,1,0,0:0:0:0: -132,68,53703,5,4,1:2:0:0: -40,136,53868,1,0,0:0:0:0: -204,160,54032,2,0,L|304:152,1,90,8|0,0:0|0:0,0:0:0:0: -408,64,54362,1,0,0:0:0:0: -408,64,54445,1,0,0:0:0:0: -408,64,54527,2,0,P|404:112|416:160,1,90,0|8,1:0|0:0,0:0:0:0: -484,236,54857,1,0,0:0:0:0: -428,328,55021,5,0,1:0:0:0: -328,296,55186,1,0,0:0:0:0: -328,296,55269,1,0,0:0:0:0: -328,296,55351,1,8,0:0:0:0: -416,300,55516,1,0,1:0:0:0: -472,208,55681,1,0,0:0:0:0: -316,268,55846,1,0,1:0:0:0: -460,180,56010,1,8,0:0:0:0: -304,240,56175,1,0,0:0:0:0: -404,272,56340,5,0,1:0:0:0: -448,152,56505,1,0,0:0:0:0: -448,152,56587,1,0,0:0:0:0: -448,152,56670,2,0,P|456:112|448:60,1,90,8|0,0:0|0:0,0:0:0:0: -268,28,56999,2,0,P|260:68|268:120,1,90,0|0,0:0|1:0,0:0:0:0: -404,272,57329,2,0,P|444:280|496:272,2,90,8|0|0,0:0|0:0|1:0,0:0:0:0: -304,240,57824,5,0,0:0:0:0: -252,336,57988,1,8,0:0:0:0: -196,244,58153,1,0,1:0:0:0: -24,256,58318,1,0,0:0:0:0: -116,200,58483,1,0,1:0:0:0: -136,60,58648,1,8,0:0:0:0: -192,152,58813,1,0,0:0:0:0: -304,240,58977,6,0,P|348:252|396:248,1,90,0|0,1:0|0:0,0:0:0:0: -456,116,59307,2,0,P|412:104|364:108,1,90,8|0,0:0|0:0,0:0:0:0: -273,161,59637,1,0,0:0:0:0: -136,60,59802,1,0,1:0:0:0: -192,152,59966,1,8,0:0:0:0: -23,177,60131,1,0,0:0:0:0: -129,203,60296,5,0,1:0:0:0: -88,304,60461,2,0,P|132:311|176:303,1,90,0|8,0:0|0:0,0:0:0:0: -304,240,60791,1,0,1:0:0:0: -304,240,60873,1,0,0:0:0:0: -304,240,60956,2,0,L|312:288,3,45,0|0|0|0,0:0|0:0|1:0|0:0,0:0:0:0: -384,256,61285,2,0,L|392:304,3,45,8|0|0|0,0:0|0:0|0:0|0:0,0:0:0:0: -464,272,61615,5,2,1:2:0:0: -488,168,61780,1,2,0:0:0:0: -428,80,61945,1,10,0:0:0:0: -332,32,62109,2,0,P|288:28|240:36,1,90,2|0,0:0|0:0,0:0:0:0: -28,216,62439,1,2,1:2:0:0: -88,304,62604,1,10,0:0:0:0: -184,352,62769,2,0,P|228:356|276:348,1,90,2|0,0:0|1:0,0:0:0:0: -384,256,63098,6,0,P|409:219|426:174,1,90,2|8,0:0|0:0,0:0:0:0: -428,80,63428,2,0,L|420:36,2,45,2|0|0,1:2|0:0|0:0,0:0:0:0: -456,288,63758,1,2,1:2:0:0: -324,200,63923,1,10,1:2:0:0: -292,204,64005,1,0,1:0:0:0: -260,208,64087,1,2,1:2:0:0: -228,212,64170,1,0,1:0:0:0: -196,216,64252,5,4,1:2:0:0: -104,160,64417,1,0,0:0:0:0: -228,296,64582,2,0,L|320:284,1,90,8|0,0:0|0:0,0:0:0:0: -344,112,64912,1,0,0:0:0:0: -344,112,64994,1,0,0:0:0:0: -344,112,65076,2,0,L|254:123,1,90,0|8,1:0|0:0,0:0:0:0: -144,284,65406,2,0,P|148:328|176:364,1,90,0|0,0:0|1:0,0:0:0:0: -196,216,65736,5,0,0:0:0:0: -196,216,65818,1,0,0:0:0:0: -196,216,65901,2,0,P|155:198|110:205,1,90,8|0,0:0|1:0,0:0:0:0: -36,284,66230,1,0,0:0:0:0: -4,180,66395,1,0,1:0:0:0: -132,24,66560,1,8,0:0:0:0: -100,128,66725,1,0,0:0:0:0: -24,48,66890,5,0,1:0:0:0: -212,108,67054,1,0,0:0:0:0: -212,108,67137,1,0,0:0:0:0: -212,108,67219,2,0,L|300:92,1,90,8|0,0:0|0:0,0:0:0:0: -472,144,67549,2,0,L|384:160,1,90,0|0,0:0|1:0,0:0:0:0: -196,216,67879,2,0,P|240:216|288:240,1,90,8|0,0:0|0:0,0:0:0:0: -324,336,68208,5,0,1:0:0:0: -144,288,68373,1,0,0:0:0:0: -58,170,68538,1,8,0:0:0:0: -196,215,68703,1,0,1:0:0:0: -58,260,68868,1,0,0:0:0:0: -144,142,69032,2,0,L|138:108,2,30,0|0|0,1:0|0:0|0:0,0:0:0:0: -144,142,69197,2,0,P|184:124|232:132,1,90,8|0,0:0|0:0,0:0:0:0: -312,248,69527,6,0,L|324:338,1,90,0|0,1:0|0:0,0:0:0:0: -436,248,69857,1,8,0:0:0:0: -432,216,69939,1,0,0:0:0:0: -428,184,70021,1,0,0:0:0:0: -328,120,70186,1,0,0:0:0:0: -324,152,70269,1,0,0:0:0:0: -320,184,70351,1,0,1:0:0:0: -316,216,70434,1,0,0:0:0:0: -312,248,70516,2,0,L|320:300,1,45,8|0,0:0|0:0,0:0:0:0: -244,340,70681,2,0,L|237:295,1,45,0|0,0:0|0:0,0:0:0:0: -216,224,70846,6,0,P|168:216|124:224,1,90,0|0,1:0|0:0,0:0:0:0: -40,288,71175,1,8,0:0:0:0: -2,95,71340,2,0,P|-4:139|4:184,1,90,0|0,1:0|0:0,0:0:0:0: -164,304,71670,1,0,1:0:0:0: -312,248,71835,1,8,0:0:0:0: -244,340,71999,1,0,0:0:0:0: -216,224,72164,6,0,L|228:132,1,90,0|0,1:0|0:0,0:0:0:0: -332,148,72494,2,0,L|344:56,1,90,8|0,0:0|0:0,0:0:0:0: -312,248,72824,1,0,0:0:0:0: -164,304,72988,1,0,1:0:0:0: -332,336,73153,1,8,0:0:0:0: -360,324,73236,1,0,0:0:0:0: -384,304,73318,1,0,0:0:0:0: -399,276,73401,1,0,0:0:0:0: -403,244,73483,6,0,L|396:200,3,45,4|0|2|0,1:2|0:0|0:0|1:0,0:0:0:0: -420,112,73813,2,0,L|427:68,3,45,2|0|2|0,1:2|0:0|1:2|0:0,0:0:0:0: -352,16,74142,2,0,L|345:60,3,45,0|0|2|0,0:0|1:0|1:2|0:0,0:0:0:0: -332,148,74472,1,2,1:2:0:0: -332,148,74554,1,0,1:0:0:0: -332,148,74637,1,2,1:2:0:0: -332,148,74719,1,0,1:0:0:0: -332,148,74802,6,0,P|360:216|320:312,1,180,4|2,1:2|0:3,0:0:0:0: -190,310,75296,2,0,P|151:231|180:148,1,180,4|0,1:2|0:0,0:0:0:0: -256,56,75791,1,0,0:0:0:0: -332,148,75956,1,2,0:3:0:0: -179,148,76120,5,4,1:2:0:0: -336,64,76285,1,4,1:2:0:0: -256,224,76450,1,2,0:3:0:0: -176,64,76615,1,4,1:2:0:0: -256,140,76780,2,0,L|256:324,1,180,2|0,0:0|0:0,0:0:0:0: -364,300,77274,1,2,0:3:0:0: -148,300,77439,6,0,P|104:316|76:356,1,90,4|0,1:2|0:0,0:0:0:0: -24,252,77769,2,0,L|16:208,3,45,8|0|0|0,0:0|0:0|0:0|0:0,0:0:0:0: -96,212,78098,2,0,L|104:168,3,45,0|0|0|0,0:0|0:0|1:0|0:0,0:0:0:0: -32,128,78428,2,0,L|24:84,3,45,8|0|0|0,0:0|0:0|0:0|0:0,0:0:0:0: -104,88,78758,5,2,1:2:0:0: -204,132,78923,1,0,0:0:0:0: -236,124,79005,1,0,0:0:0:0: -268,116,79087,2,0,L|280:68,3,45,8|0|0|0,0:0|0:0|1:0|0:0,0:0:0:0: -348,100,79417,2,0,L|360:52,3,45,0|0|0|0,0:0|0:0|1:0|0:0,0:0:0:0: -428,84,79747,1,8,1:2:0:0: -460,76,79829,1,0,1:0:0:0: -492,68,79912,1,0,1:0:0:0: -492,260,80076,6,0,P|400:248|328:296,1,180,4|2,1:2|0:3,0:0:0:0: -144,236,80571,2,0,P|236:248|308:200,1,180,4|0,1:2|0:0,0:0:0:0: -348,100,81065,2,0,P|348:56|336:8,1,90,0|2,0:0|0:3,0:0:0:0: -140,48,81395,5,4,1:2:0:0: -244,68,81560,1,4,1:2:0:0: -144,236,81725,1,2,0:3:0:0: -176,133,81890,1,4,1:2:0:0: -184,304,82054,2,0,P|100:300|68:220,1,180,2|0,0:0|0:0,0:0:0:0: -100,116,82549,1,2,0:3:0:0: -264,244,82714,6,0,L|272:340,1,90,4|0,1:2|0:0,0:0:0:0: -380,316,83043,1,8,0:0:0:0: -396,288,83126,1,0,0:0:0:0: -400,256,83208,1,0,0:0:0:0: -396,224,83291,1,0,0:0:0:0: -380,196,83373,2,0,L|336:176,3,45,0|0|0|0,0:0|0:0|1:0|0:0,0:0:0:0: -272,148,83703,1,8,0:0:0:0: -256,120,83785,1,0,0:0:0:0: -252,88,83868,1,0,0:0:0:0: -256,56,83950,1,0,0:0:0:0: -272,28,84032,6,0,L|316:8,3,45,2|0|0|0,1:2|0:0|0:0|0:0,0:0:0:0: -360,72,84362,2,0,L|408:72,3,45,8|0|0|0,0:0|0:0|1:0|0:0,0:0:0:0: -421,149,84692,2,0,L|464:169,3,45,2|0|0|0,0:0|0:0|1:0|0:0,0:0:0:0: -443,244,85021,2,0,L|473:281,3,45,8|0|0|0,1:2|1:0|0:0|0:0,0:0:0:0: -422,339,85351,6,0,L|240:348,1,180,4|2,1:2|0:3,0:0:0:0: -76,172,85846,2,0,L|255:163,1,180,4|0,1:2|0:0,0:0:0:0: -421,149,86340,2,0,P|435:107|428:56,1,90,0|2,0:0|0:3,0:0:0:0: -228,56,86670,5,4,1:2:0:0: -280,192,86835,1,4,1:2:0:0: -328,96,86999,1,2,0:3:0:0: -180,152,87164,1,4,1:2:0:0: -28,100,87330,2,0,P|16:56|20:8,1,90,2|0,0:0|0:0,0:0:0:0: -0,180,87659,1,0,0:0:0:0: -28,284,87824,1,2,0:3:0:0: -108,352,87988,6,0,P|152:360|196:356,1,90,4|0,1:2|0:0,0:0:0:0: -276,284,88318,1,8,0:0:0:0: -304,272,88401,1,0,0:0:0:0: -336,268,88483,1,0,0:0:0:0: -368,272,88565,1,0,0:0:0:0: -396,284,88648,2,0,L|432:312,1,45,0|0,0:0|0:0,0:0:0:0: -488,252,88813,2,0,L|452:224,1,45,0|0,1:0|0:0,0:0:0:0: -400,164,88977,2,0,L|396:116,3,45,8|0|0|0,0:0|0:0|0:0|0:0,0:0:0:0: -316,64,89307,6,0,L|320:160,1,90,2|0,1:2|0:0,0:0:0:0: -276,284,89637,1,8,0:0:0:0: -248,296,89719,1,0,0:0:0:0: -216,300,89802,1,0,1:0:0:0: -184,296,89884,1,0,0:0:0:0: -156,284,89966,2,0,L|120:256,1,45,0|0,0:0|0:0,0:0:0:0: -176,200,90131,2,0,L|140:172,1,45,0|0,1:0|0:0,0:0:0:0: -196,116,90296,2,0,L|160:88,3,45,8|0|0|0,1:2|1:0|1:0|0:0,0:0:0:0: -92,44,90626,6,0,P|48:44|24:160,1,180,4|2,1:2|0:3,0:0:0:0: -156,284,91120,2,0,B|200:300|244:284|244:284|288:268|332:284,1,180,4|0,1:2|0:0,0:0:0:0: -176,200,91615,2,0,P|176:156|196:116,1,90,0|2,0:0|0:3,0:0:0:0: -264,28,91945,6,0,L|353:39,1,90,4|0,1:2|1:0,0:0:0:0: -453,159,92274,2,0,L|364:148,1,90,2|4,0:3|1:2,0:0:0:0: -268,196,92604,2,0,P|260:268|328:348,1,180,2|0,0:0|0:0,0:0:0:0: -364,248,93098,1,2,0:3:0:0: -176,200,93263,5,4,1:2:0:0: -72,228,93428,1,0,1:0:0:0: -152,92,93593,1,0,1:0:0:0: -256,64,93758,1,0,1:0:0:0: -336,200,93923,5,0,1:0:0:0: -440,228,94087,1,0,1:0:0:0: -360,92,94252,1,0,1:0:0:0: -256,64,94417,1,0,1:0:0:0: -176,200,94582,5,2,1:2:0:0: -168,228,94664,1,0,1:0:0:0: -168,260,94747,1,0,1:0:0:0: -172,292,94829,1,0,1:0:0:0: -192,316,94912,1,0,1:0:0:0: -220,328,94994,1,0,1:0:0:0: -252,332,95076,1,0,1:0:0:0: -280,320,95159,1,0,1:0:0:0: -300,296,95241,2,0,L|308:248,3,45,2|0|0|0,1:2|1:0|1:0|1:0,0:0:0:0: -312,172,95571,2,0,L|304:127,3,45,0|0|0|0,1:0|1:0|1:0|1:0,0:0:0:0: -256,64,95901,6,0,P|208:56|164:60,1,90,4|0,1:2|0:0,0:0:0:0: -76,116,96230,1,8,0:0:0:0: -60,224,96395,1,0,0:0:0:0: -60,224,96477,1,0,0:0:0:0: -160,184,96642,1,0,0:0:0:0: -160,184,96725,1,0,1:0:0:0: -63,26,96890,2,0,L|76:116,1,90,8|0,0:0|0:0,0:0:0:0: -136,272,97219,5,0,1:0:0:0: -168,268,97302,1,0,0:0:0:0: -200,264,97384,1,0,0:0:0:0: -232,260,97466,1,0,0:0:0:0: -264,256,97549,1,8,0:0:0:0: -384,136,97714,1,0,1:0:0:0: -376,168,97796,1,0,0:0:0:0: -380,200,97879,1,0,0:0:0:0: -392,228,97961,1,0,0:0:0:0: -416,248,98043,2,0,P|464:260|512:260,2,90,0|8|0,1:0|0:0|0:0,0:0:0:0: -231,105,98538,6,0,L|188:116,2,45,0|0|0,1:0|0:0|0:0,0:0:0:0: -376,56,98868,2,0,L|420:64,1,45,8|0,0:0|0:0,0:0:0:0: -384,136,99032,1,0,0:0:0:0: -384,136,99115,2,0,P|340:128|304:92,1,90,0|0,0:0|0:0,0:0:0:0: -303,18,99362,2,0,L|207:26,2,90,0|8|0,1:0|0:0|0:0,0:0:0:0: -452,88,99857,5,0,1:0:0:0: -465,116,99939,1,0,0:0:0:0: -466,147,100021,1,0,0:0:0:0: -456,177,100104,1,0,0:0:0:0: -436,201,100186,2,0,P|416:213|389:216,3,45,8|0|0|0,0:0|0:0|1:0|0:0,0:0:0:0: -320,188,100516,2,0,P|300:176|273:173,3,45,0|0|0|0,0:0|1:0|1:0|0:0,0:0:0:0: -204,200,100846,2,0,P|192:220|189:247,3,45,8|0|0|0,0:0|0:0|1:0|0:0,0:0:0:0: -188,320,101175,6,0,P|143:322|100:310,1,90,0|0,1:0|0:0,0:0:0:0: -76,292,101423,1,0,0:0:0:0: -76,292,101505,1,8,0:0:0:0: -76,292,101587,2,0,L|72:248,1,45 -12,68,101835,2,0,L|6:24,2,45,0|0|0,0:0|0:0|1:0,0:0:0:0: -104,140,102164,2,0,L|171:132,3,45,8|0|0|0,0:0|0:0|0:0|0:0,0:0:0:0: -224,124,102494,6,0,P|236:164|232:216,1,90,0|0,1:0|0:0,0:0:0:0: -288,296,102824,1,8,0:0:0:0: -288,296,102906,1,0,0:0:0:0: -288,296,102988,2,0,P|328:284|380:288,1,90,0|0,1:0|0:0,0:0:0:0: -404,304,103236,1,0,0:0:0:0: -424,328,103318,1,0,1:0:0:0: -448,188,103483,2,0,L|440:140,3,45,8|0|0|0,0:0|0:0|0:0|0:0,0:0:0:0: -424,72,103813,5,0,1:0:0:0: -324,112,103977,1,0,0:0:0:0: -324,112,104060,1,0,0:0:0:0: -324,112,104142,2,0,P|280:116|232:104,1,90,8|0,0:0|0:0,0:0:0:0: -160,28,104472,1,0,0:0:0:0: -216,208,104637,1,0,1:0:0:0: -216,208,104719,1,0,0:0:0:0: -216,208,104802,1,8,0:0:0:0: -352,240,104966,1,0,0:0:0:0: -384,244,105049,1,0,0:0:0:0: -416,248,105131,6,0,L|460:240,4,45,0|0|0|0|8,1:0|0:0|0:0|0:0|0:0,0:0:0:0: -272,288,105626,1,0,1:0:0:0: -264,320,105708,1,0,0:0:0:0: -256,352,105791,2,0,L|204:356,5,30,0|0|0|0|0|0,0:0|0:0|0:0|1:0|0:0|0:0,0:0:0:0: -156,332,106120,2,0,L|104:336,5,30,8|0|0|0|0|0,0:0|0:0|0:0|1:0|0:0|0:0,0:0:0:0: -56,312,106450,5,4,1:2:0:0: -4,188,106615,1,0,0:0:0:0: -168,220,106780,2,0,P|127:232|79:228,1,90,8|0,0:0|0:0,0:0:0:0: -112,124,107109,1,0,0:0:0:0: -272,216,107274,2,0,L|264:316,1,90,0|8,1:0|0:0,0:0:0:0: -400,268,107604,1,0,0:0:0:0: -428,132,107769,5,0,1:0:0:0: -428,132,107851,1,0,0:0:0:0: -428,132,107934,1,0,0:0:0:0: -428,132,108016,1,0,0:0:0:0: -428,132,108098,1,8,0:0:0:0: -332,84,108263,2,0,P|288:80|232:88,1,90,0|0,1:0|0:0,0:0:0:0: -112,124,108593,1,0,1:0:0:0: -148,264,108758,1,8,0:0:0:0: -16,236,108923,1,0,0:0:0:0: -264,126,109087,6,0,L|272:216,1,90,0|0,1:0|0:0,0:0:0:0: -452,224,109417,2,0,L|460:320,1,90,8|0,0:0|0:0,0:0:0:0: -360,232,109747,1,0,0:0:0:0: -348,56,109912,1,0,1:0:0:0: -416,140,110076,1,8,0:0:0:0: -256,112,110241,2,0,P|212:120|160:112,1,90,0|0,0:0|1:0,0:0:0:0: -348,56,110571,6,0,L|331:150,1,90,0|8,0:0|0:0,0:0:0:0: -208,328,110901,2,0,L|191:239,1,90,0|0,1:0|0:0,0:0:0:0: -184,216,111148,1,0,1:0:0:0: -178,194,111230,1,0,1:0:0:0: -68,272,111395,1,8,0:0:0:0: -56,136,111560,1,0,1:0:0:0: -178,194,111725,6,0,P|219:203|267:199,1,90,4|0,1:2|0:0,0:0:0:0: -364,148,112054,1,8,0:0:0:0: -384,256,112219,2,0,P|406:291|443:322,1,90,0|0,0:0|0:0,0:0:0:0: -488,224,112549,1,0,1:0:0:0: -304,232,112714,2,0,L|208:224,2,90,8|0|0,0:0|0:0|1:0,0:0:0:0: -208,328,113208,6,0,L|112:320,1,90,0|8,0:0|0:0,0:0:0:0: -26,184,113538,2,0,L|116:192,1,90,0|0,1:0|0:0,0:0:0:0: -304,232,113868,1,0,1:0:0:0: -116,192,114032,1,8,0:0:0:0: -224,132,114197,1,0,0:0:0:0: -208,328,114362,6,0,B|272:360|320:312|320:312|340:368,1,180,4|8,1:2|0:0,0:0:0:0: -304,232,114857,2,0,P|300:184|308:140,1,90,0|0,0:0|0:0,0:0:0:0: -384,64,115186,1,0,1:0:0:0: -307,143,115351,1,8,0:0:0:0: -256,48,115516,1,0,0:0:0:0: -456,24,115681,6,0,B|482:101|420:136|420:136|440:184,1,180,4|8,1:2|0:0,0:0:0:0: -384,64,116175,2,0,P|340:56|296:64,1,90,0|0,1:0|0:0,0:0:0:0: -211,171,116505,1,0,1:0:0:0: -439,181,116670,2,0,L|448:84,1,90,8|0,0:0|0:0,0:0:0:0: -372,296,116999,6,2,L|304:292,1,67.5000025749208,2|0,0:1|0:0,0:0:0:0: -136,252,117329,6,2,P|196:260|212:172,1,168.75,0|0,0:0|0:0,0:0:0:0: -192,148,117659,1,2,0:3:0:0: -164,132,117741,1,2,0:3:0:0: -132,124,117824,1,2,1:3:0:0: -100,132,117906,1,2,0:3:0:0: -72,148,117988,2,0,L|52:56,1,90,2|8,0:3|0:0,0:0:0:0: -36,244,118318,5,0,1:0:0:0: -76,344,118483,1,0,1:0:0:0: -184,352,118648,1,0,1:0:0:0: -244,264,118813,1,0,1:0:0:0: -244,264,118895,1,0,1:0:0:0: -244,264,118977,2,0,L|288:260,3,45,2|0|2|0,1:2|0:0|0:0|0:0,0:0:0:0: -332,328,119307,2,0,L|376:324,3,45,2|0|2|0,1:2|0:0|0:0|0:0,0:0:0:0: -412,252,119637,5,4,1:2:0:0: -256,192,119719,12,0,122274,0:0:0:0: -256,192,140735,6,0,L|228:156,1,45,4|0,1:2|0:0,0:0:0:0: -152,132,141065,2,0,P|129:129|104:136,1,45 -48,192,141395,2,0,P|40:236|52:280,1,90,8|8,0:0|0:0,0:0:0:0: -196,352,142054,6,0,L|308:340,1,90,8|8,0:0|1:2,0:0:0:0: -336,280,142549,1,0,0:0:0:0: -404,324,142713,1,8,0:0:0:0: -404,324,142878,1,8,0:0:0:0: -292,120,143373,5,0,1:0:0:0: -212,104,143538,1,0,0:0:0:0: -140,140,143702,1,0,0:0:0:0: -120,220,143867,1,0,0:0:0:0: -144,296,144032,2,0,P|184:320|228:316,1,90,10|8,0:0|0:0,0:0:0:0: -372,212,144691,6,0,P|327:209|290:232,1,90,10|8,0:0|1:2,0:0:0:0: -348,288,145186,1,0,0:0:0:0: -452,220,145351,1,10,0:0:0:0: -452,220,145516,1,8,0:0:0:0: -328,36,146010,5,2,1:2:0:0: -264,88,146175,1,0,0:0:0:0: -184,108,146340,1,0,0:0:0:0: -104,88,146505,1,0,0:0:0:0: -44,36,146669,1,8,0:0:0:0: -44,36,146999,1,8,0:0:0:0: -44,36,147329,6,0,L|24:84,1,45,8|0,0:0|0:0,0:0:0:0: -52,156,147658,2,0,L|71:204,1,45,8|0,1:2|0:0,0:0:0:0: -144,236,147988,1,8,0:0:0:0: -144,236,148153,1,8,0:0:0:0: -316,64,148647,5,0,1:0:0:0: -380,116,148812,1,0,0:0:0:0: -408,192,148977,1,0,0:0:0:0: -380,268,149142,1,0,0:0:0:0: -316,320,149307,2,0,L|224:316,1,90,10|8,0:0|0:0,0:0:0:0: -64,248,149966,5,10,0:0:0:0: -144,236,150131,1,0,0:0:0:0: -188,168,150296,1,8,1:2:0:0: -192,88,150461,1,0,0:0:0:0: -140,24,150626,2,0,P|120:16|96:20,1,45,10|0,0:0|0:0,0:0:0:0: -260,132,150955,2,0,P|280:140|304:136,1,45,2|0,0:0|0:0,0:0:0:0: -476,48,151285,6,0,L|484:160,1,112.5,4|0,1:2|0:0,0:0:0:0: -464,236,151779,1,0,0:0:0:0: -436,308,151944,2,0,P|380:320|324:308,1,112.5,8|8,0:0|0:0,0:0:0:0: -76,308,152604,6,0,P|132:320|188:308,1,112.5,8|8,0:0|1:2,0:0:0:0: -256,88,153263,1,8,0:0:0:0: -256,168,153428,1,8,0:0:0:0: -256,168,153922,5,4,1:2:0:0: -256,248,154087,1,0,0:0:0:0: -324,128,154252,1,0,0:0:0:0: -188,128,154417,1,0,0:0:0:0: -332,212,154582,2,0,L|388:204,1,56.25,10|0,0:0|0:0,0:0:0:0: -492,152,154911,2,0,L|436:144,1,56.25,8|0,0:0|0:0,0:0:0:0: -324,128,155241,5,10,0:0:0:0: -180,212,155406,1,0,0:0:0:0: -332,212,155571,1,8,1:2:0:0: -188,128,155735,1,0,0:0:0:0: -256,248,155900,1,10,0:0:0:0: -256,248,156065,2,0,L|256:304,2,56.25,0|0|0,0:0|0:0|0:0,0:0:0:0: -180,212,156560,6,0,L|124:204,1,56.25,4|0,1:2|0:0,0:0:0:0: -20,152,156889,2,0,L|76:144,1,56.25,0|0,0:0|0:0,0:0:0:0: -188,128,157219,2,0,P|212:72|192:16,1,112.5,8|8,0:0|0:0,0:0:0:0: -132,72,157713,1,0,0:0:0:0: -180,212,157878,6,0,L|236:208,1,56.25,8|0,0:0|0:0,0:0:0:0: -360,252,158208,2,8,L|304:248,1,56.25,8|0,1:2|0:0,0:0:0:0: -168,292,158538,2,0,L|160:356,2,56.25,8|8|0,0:0|0:0|0:0,0:0:0:0: -180,212,159032,1,0,0:0:0:0: -144,140,159197,6,0,P|104:128|36:148,1,112.5,2|0,1:2|0:0,0:0:0:0: -12,220,159691,1,0,0:0:0:0: -36,296,159856,2,0,P|60:316|92:324,1,56.25,8|0,0:0|0:0,0:0:0:0: -215,264,160186,2,0,P|189:273|168:292,1,56.25,8|0,0:0|0:0,0:0:0:0: -228,344,160516,6,0,L|284:340,1,56.25,10|0,0:0|0:0,0:0:0:0: -328,276,160845,2,0,L|384:272,1,56.25,8|0,1:2|0:0,0:0:0:0: -428,208,161175,1,8,0:0:0:0: -440,128,161340,1,8,0:0:0:0: -400,60,161505,1,2,0:0:0:0: -328,28,161669,1,0,0:0:0:0: -212,76,161834,6,0,P|200:120|208:164,1,90,2|0,1:2|1:0,0:0:0:0: -300,308,162163,2,0,P|312:264|304:220,1,90,2|0,1:2|1:0,0:0:0:0: -140,236,162493,2,0,P|184:248|228:240,1,90,2|0,1:2|1:0,0:0:0:0: -372,148,162823,2,0,P|328:136|284:144,1,90,2|0,1:2|1:0,0:0:0:0: -104,316,163152,5,2,1:2:0:0: -78,297,163235,1,0,1:0:0:0: -60,270,163317,1,0,1:0:0:0: -54,239,163399,1,0,1:0:0:0: -58,207,163482,1,2,1:2:0:0: -74,180,163564,1,0,1:0:0:0: -98,159,163647,1,0,1:0:0:0: -127,149,163729,1,0,1:0:0:0: -158,150,163812,2,0,L|208:160,1,45,2|0,1:2|1:0,0:0:0:0: -344,184,163976,2,0,L|294:194,1,45,0|0,1:0|1:0,0:0:0:0: -140,236,164141,1,4,1:2:0:0: -140,236,164471,6,0,L|232:252,1,90,4|0,1:2|0:0,0:0:0:0: -344,184,164801,1,8,0:0:0:0: -380,284,164965,1,0,0:0:0:0: -368,104,165130,2,0,P|324:104|284:128,1,90,0|0,0:0|1:0,0:0:0:0: -356,360,165460,2,0,P|400:360|440:336,1,90,8|0,0:0|0:0,0:0:0:0: -432,208,165790,5,0,1:0:0:0: -292,260,165954,1,0,0:0:0:0: -344,184,166119,1,8,0:0:0:0: -204,236,166284,1,0,1:0:0:0: -204,236,166366,1,0,0:0:0:0: -204,236,166449,2,0,L|216:328,1,90,0|0,0:0|1:0,0:0:0:0: -120,208,166779,2,0,L|131:118,1,90,8|0,0:0|0:0,0:0:0:0: -204,236,167108,5,0,1:0:0:0: -32,216,167273,1,0,0:0:0:0: -130,118,167438,1,8,0:0:0:0: -110,298,167603,1,0,0:0:0:0: -110,298,167685,1,0,0:0:0:0: -110,298,167768,2,0,L|121:208,1,90,0|0,0:0|1:0,0:0:0:0: -304,40,168097,2,0,L|315:130,1,90,8|0,0:0|0:0,0:0:0:0: -328,236,168427,5,0,1:0:0:0: -184,148,168592,1,0,0:0:0:0: -314,129,168757,1,8,0:0:0:0: -197,254,168921,1,0,1:0:0:0: -197,254,169004,1,0,0:0:0:0: -197,254,169086,2,0,P|220:292|260:312,1,90,0|0,0:0|1:0,0:0:0:0: -409,210,169416,2,0,P|365:211|328:236,1,90,8|0,0:0|0:0,0:0:0:0: -488,232,169746,6,0,P|487:192|464:149,1,90,0|0,1:0|0:0,0:0:0:0: -314,129,170075,1,8,0:0:0:0: -409,210,170240,1,0,0:0:0:0: -332,40,170405,2,0,L|240:36,1,90,0|0,0:0|1:0,0:0:0:0: -68,144,170735,2,0,L|157:140,1,90,8|0,0:0|0:0,0:0:0:0: -314,129,171064,5,0,1:0:0:0: -332,40,171229,1,0,0:0:0:0: -324,216,171394,1,8,0:0:0:0: -306,305,171559,1,0,1:0:0:0: -257,178,171724,1,0,0:0:0:0: -168,160,171888,1,0,1:0:0:0: -384,164,172053,1,8,0:0:0:0: -473,182,172218,1,0,0:0:0:0: -306,305,172383,6,0,L|216:312,1,90,0|0,1:0|0:0,0:0:0:0: -60,172,172713,1,8,0:0:0:0: -120,260,172877,1,0,0:0:0:0: -168,160,173042,2,0,L|172:68,1,90,0|0,0:0|1:0,0:0:0:0: -309,216,173372,2,0,L|306:306,1,90,8|0,0:0|0:0,0:0:0:0: -120,260,173702,5,0,1:0:0:0: -152,256,173784,1,0,1:0:0:0: -184,252,173866,1,0,1:0:0:0: -309,216,174031,1,8,0:0:0:0: -103,168,174196,1,0,1:0:0:0: -135,164,174279,1,0,1:0:0:0: -167,160,174361,1,0,1:0:0:0: -292,124,174526,1,0,1:0:0:0: -87,76,174691,1,8,1:2:0:0: -119,72,174773,1,0,1:0:0:0: -151,68,174855,1,0,1:0:0:0: -276,32,175020,6,0,L|368:40,1,90,0|0,1:0|0:0,0:0:0:0: -448,108,175350,1,8,0:0:0:0: -292,124,175515,1,0,0:0:0:0: -292,124,175597,1,0,0:0:0:0: -292,124,175680,2,0,L|308:216,1,90,0|0,0:0|1:0,0:0:0:0: -328,320,176009,1,8,0:0:0:0: -408,248,176174,1,0,0:0:0:0: -220,300,176339,6,0,P|176:304|128:292,1,90,0|0,1:0|0:0,0:0:0:0: -16,120,176669,1,8,0:0:0:0: -120,152,176834,1,0,1:0:0:0: -120,152,176916,1,0,0:0:0:0: -120,152,176998,2,0,L|124:200,1,45 -212,176,177163,2,0,L|239:215,1,45,0|0,1:0|0:0,0:0:0:0: -292,124,177328,2,0,P|302:79|283:30,1,90,8|0,0:0|0:0,0:0:0:0: -344,192,177658,6,0,P|372:156|376:104,1,90,0|0,1:0|0:0,0:0:0:0: -212,88,177987,1,8,0:0:0:0: -272,228,178152,1,0,0:0:0:0: -272,228,178235,1,0,0:0:0:0: -272,228,178317,1,0,0:0:0:0: -292,124,178482,1,0,1:0:0:0: -180,180,178647,1,8,0:0:0:0: -200,284,178812,1,0,0:0:0:0: -292,124,178976,5,0,1:0:0:0: -288,92,179059,1,0,0:0:0:0: -280,60,179141,2,0,P|248:24|208:14,1,90,0|8,0:0|0:0,0:0:0:0: -22,65,179471,2,0,P|67:71|112:68,1,90,0|0,1:0|0:0,0:0:0:0: -212,88,179801,1,0,1:0:0:0: -22,65,179965,1,8,0:0:0:0: -180,180,180130,5,0,0:0:0:0: -180,180,180213,1,0,0:0:0:0: -180,180,180295,2,0,P|184:224|172:272,1,90,0|0,1:0|0:0,0:0:0:0: -76,216,180625,2,0,P|72:172|84:124,1,90,8|0,0:0|0:0,0:0:0:0: -380,240,180954,2,0,P|384:284|372:332,1,90,0|0,0:0|1:0,0:0:0:0: -276,276,181284,2,0,P|272:232|284:184,1,90,8|0,0:0|0:0,0:0:0:0: -374,129,181614,5,0,1:0:0:0: -300,352,181779,2,0,L|204:348,2,90,0|8|0,0:0|0:0|1:0,0:0:0:0: -448,180,182273,1,2,0:0:0:0: -448,180,182438,1,2,1:2:0:0: -276,276,182603,1,10,0:0:0:0: -276,276,182768,1,2,0:0:0:0: -96,200,182932,6,0,L|88:108,1,90,0|0,1:0|0:0,0:0:0:0: -96,200,183262,1,8,0:0:0:0: -12,68,183427,2,0,P|72:24|164:68,1,180,0|0,0:0|1:0,0:0:0:0: -140,272,183921,2,0,P|92:284|52:271,1,90,8|0,0:0|0:0,0:0:0:0: -176,156,184251,5,0,1:0:0:0: -208,152,184334,1,0,1:0:0:0: -240,148,184416,1,0,1:0:0:0: -308,64,184581,1,8,0:0:0:0: -296,240,184746,1,0,1:0:0:0: -312,268,184828,1,0,1:0:0:0: -336,284,184910,1,0,1:0:0:0: -368,292,184993,1,0,1:0:0:0: -400,288,185075,1,0,1:0:0:0: -464,184,185240,1,8,0:0:0:0: -468,152,185323,1,0,0:0:0:0: -472,120,185405,2,0,L|464:76,1,45,0|0,1:0|1:0,0:0:0:0: -388,96,185570,6,0,P|360:132|316:148,1,90,4|0,1:2|0:0,0:0:0:0: -224,46,185899,2,0,P|268:43|308:63,1,90,8|0,0:0|0:0,0:0:0:0: -296,240,186229,1,0,0:0:0:0: -308,64,186394,1,0,1:0:0:0: -296,240,186559,2,0,L|312:332,1,90,8|0,0:0|0:0,0:0:0:0: -464,184,186888,6,0,P|420:180|372:188,1,90,0|0,1:0|0:0,0:0:0:0: -296,240,187218,1,8,0:0:0:0: -136,292,187383,2,0,P|94:277|54:249,1,90,0|0,1:0|0:0,0:0:0:0: -21,159,187713,1,0,1:0:0:0: -104,8,187877,2,0,L|124:96,1,90,10|0,0:0|0:0,0:0:0:0: -124,96,188207,6,0,P|152:132|196:148,1,90,0|0,1:0|0:0,0:0:0:0: -287,46,188537,2,0,P|243:43|204:63,1,90,8|0,0:0|0:0,0:0:0:0: -216,240,188866,1,2,0:0:0:0: -204,64,189031,1,0,1:0:0:0: -216,240,189196,2,0,L|200:332,1,90,8|0,0:0|0:0,0:0:0:0: -40,240,189526,5,2,1:2:0:0: -128,192,189691,1,0,0:0:0:0: -216,240,189855,1,8,0:0:0:0: -304,192,190020,1,0,1:0:0:0: -392,240,190185,2,0,L|400:332,1,90,2|0,0:0|1:0,0:0:0:0: -464,168,190515,2,0,L|456:76,1,90,8|0,0:0|0:0,0:0:0:0: -392,240,190844,6,0,P|364:272|312:292,1,90,2|0,1:2|0:0,0:0:0:0: -220,140,191174,2,0,P|248:108|296:92,1,90,8|0,0:0|0:0,0:0:0:0: -324,96,191421,1,0,0:0:0:0: -356,104,191504,2,0,L|340:16,1,90,0|0,0:0|1:0,0:0:0:0: -256,276,191834,2,0,L|272:364,1,90,8|0,0:0|0:0,0:0:0:0: -392,240,192163,5,0,1:0:0:0: -356,104,192328,1,0,0:0:0:0: -220,140,192493,1,8,0:0:0:0: -256,276,192658,1,0,1:0:0:0: -305,191,192823,1,0,0:0:0:0: -212,56,192987,1,0,1:0:0:0: -200,220,193152,1,10,0:0:0:0: -200,220,193482,6,0,P|156:228|108:220,1,90,0|0,1:0|0:0,0:0:0:0: -88,116,193812,1,8,0:0:0:0: -16,192,193976,1,0,0:0:0:0: -16,192,194059,1,0,0:0:0:0: -16,192,194141,2,0,L|28:288,1,90,2|0,0:0|1:0,0:0:0:0: -188,309,194471,2,0,L|200:220,1,90,8|0,0:0|0:0,0:0:0:0: -216,112,194801,5,2,1:2:0:0: -216,112,194883,1,0,1:0:0:0: -216,112,194965,1,0,1:0:0:0: -361,25,195130,1,8,0:0:0:0: -294,180,195295,1,0,1:0:0:0: -294,180,195377,1,0,1:0:0:0: -294,180,195460,1,2,0:0:0:0: -256,16,195625,1,0,1:0:0:0: -384,127,195790,1,10,1:2:0:0: -416,132,195872,1,0,1:0:0:0: -448,140,195954,2,0,L|452:84,1,45,0|0,1:0|1:0,0:0:0:0: -416,216,196119,6,0,P|412:264|432:312,1,90,4|0,1:2|0:0,0:0:0:0: -304,268,196449,2,0,P|308:220|288:172,1,90,8|0,0:0|0:0,0:0:0:0: -216,112,196779,2,0,L|120:104,1,90,0|0,0:0|1:0,0:0:0:0: -52,248,197108,2,0,L|141:255,1,90,8|0,0:0|0:0,0:0:0:0: -304,268,197438,5,0,1:0:0:0: -416,216,197603,1,0,0:0:0:0: -408,340,197768,1,8,0:0:0:0: -332,180,197932,1,0,1:0:0:0: -332,180,198015,1,0,0:0:0:0: -332,180,198097,2,0,P|360:140|400:120,1,90,0|0,0:0|1:0,0:0:0:0: -484,284,198427,1,10,0:0:0:0: -304,268,198592,1,2,0:0:0:0: -416,216,198757,6,0,P|428:172|420:124,1,90,2|0,1:2|0:0,0:0:0:0: -344,52,199086,1,8,0:0:0:0: -332,180,199251,1,0,0:0:0:0: -164,236,199416,2,0,P|152:192|160:144,1,90,0|0,0:0|1:0,0:0:0:0: -236,72,199746,1,8,0:0:0:0: -248,200,199910,1,0,0:0:0:0: -156,328,200075,6,0,L|56:320,1,90,2|0,1:2|0:0,0:0:0:0: -164,236,200405,1,8,0:0:0:0: -256,292,200570,2,0,P|300:296|344:284,1,90,0|0,1:0|0:0,0:0:0:0: -432,220,200899,2,0,L|460:308,2,90,0|8|0,1:0|0:0|0:0,0:0:0:0: -392,120,201394,5,4,1:2:0:0: -396,32,201559,1,0,1:0:0:0: -316,72,201724,1,0,1:0:0:0: -256,6,201888,1,0,1:0:0:0: -228,91,202053,1,0,1:0:0:0: -139,87,202218,1,0,1:0:0:0: -179,166,202383,1,0,1:0:0:0: -113,226,202548,1,0,1:0:0:0: -197,253,202713,5,4,1:2:0:0: -193,342,202877,1,0,1:0:0:0: -272,302,203042,1,0,1:0:0:0: -332,367,203207,1,0,1:0:0:0: -359,283,203372,1,2,1:2:0:0: -448,287,203537,1,2,1:2:0:0: -407,208,203702,1,2,1:2:0:0: -472,147,203866,1,2,1:2:0:0: -387,121,204031,5,4,1:2:0:0: -360,100,204114,1,0,1:0:0:0: -344,72,204196,1,0,1:0:0:0: -336,40,204279,1,0,1:0:0:0: -340,8,204361,1,0,1:0:0:0: -316,28,204443,1,0,1:0:0:0: -284,32,204526,1,0,1:0:0:0: -252,28,204608,1,0,1:0:0:0: -228,8,204691,2,0,L|184:20,7,45,4|0|0|0|0|0|0|0,1:2|1:0|1:0|1:0|1:0|1:0|1:0|1:0,0:0:0:0: -112,56,205350,5,4,1:2:0:0: -100,84,205432,1,0,1:0:0:0: -96,116,205515,1,0,1:0:0:0: -100,148,205597,1,0,1:0:0:0: -112,176,205680,1,0,1:0:0:0: -124,204,205762,1,0,1:0:0:0: -128,236,205844,1,0,1:0:0:0: -124,268,205927,1,0,1:0:0:0: -112,296,206009,2,0,L|71:313,3,45,2|0|2|0,1:2|0:0|0:0|0:0,0:0:0:0: -192,312,206339,2,0,L|175:353,3,45,2|0|2|0,1:2|0:0|0:0|0:0,0:0:0:0: -256,264,206669,5,4,1:2:0:0: -256,192,206751,12,0,209306,0:0:0:0: diff --git a/osu.Game.Tests/Resources/valid-events.osu b/osu.Game.Tests/Resources/valid-events.osu new file mode 100644 index 0000000000..ed3614b4ed --- /dev/null +++ b/osu.Game.Tests/Resources/valid-events.osu @@ -0,0 +1,12 @@ +osu file format v14 + +[Events] +//Background and Video events +0,0,"machinetop_background.jpg",0,0 +//Break Periods +2,122474,140135 +//Storyboard Layer 0 (Background) +//Storyboard Layer 1 (Fail) +//Storyboard Layer 2 (Pass) +//Storyboard Layer 3 (Foreground) +//Storyboard Sound Samples From 669c2462eca3cae95a5944e2581585eeb7d5312c Mon Sep 17 00:00:00 2001 From: David Zhao Date: Wed, 7 Aug 2019 16:25:38 +0900 Subject: [PATCH 14/49] Don't consider the type --- osu.Game/Beatmaps/Formats/LegacyBeatmapDecoder.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Beatmaps/Formats/LegacyBeatmapDecoder.cs b/osu.Game/Beatmaps/Formats/LegacyBeatmapDecoder.cs index c92c0ba22d..24843f8c32 100644 --- a/osu.Game/Beatmaps/Formats/LegacyBeatmapDecoder.cs +++ b/osu.Game/Beatmaps/Formats/LegacyBeatmapDecoder.cs @@ -293,7 +293,7 @@ namespace osu.Game.Beatmaps.Formats if (!Enum.TryParse(split[0], out type)) { - Logger.Log($"A beatmap {type} event could not be parsed and will be ignored: {split[0]}", LoggingTarget.Runtime, LogLevel.Important); + Logger.Log($"A beatmap event could not be parsed and will be ignored: {split[0]}", LoggingTarget.Runtime, LogLevel.Important); return; } From c0d3d47c2995dc581f716b4a17ecad8f2d742064 Mon Sep 17 00:00:00 2001 From: David Zhao Date: Wed, 7 Aug 2019 16:49:53 +0900 Subject: [PATCH 15/49] Don't consider type for storyboards either --- osu.Game/Beatmaps/Formats/LegacyStoryboardDecoder.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Beatmaps/Formats/LegacyStoryboardDecoder.cs b/osu.Game/Beatmaps/Formats/LegacyStoryboardDecoder.cs index 512eea0822..1dcafb4669 100644 --- a/osu.Game/Beatmaps/Formats/LegacyStoryboardDecoder.cs +++ b/osu.Game/Beatmaps/Formats/LegacyStoryboardDecoder.cs @@ -84,7 +84,7 @@ namespace osu.Game.Beatmaps.Formats EventType type; if (!Enum.TryParse(split[0], out type)) - Logger.Log($"A storyboard {type} event could not be parsed and will be ignored: {split[0]}", LoggingTarget.Runtime, LogLevel.Important); + Logger.Log($"A storyboard event could not be parsed and will be ignored: {split[0]}", LoggingTarget.Runtime, LogLevel.Important); switch (type) { From 7bcec31ea370d87a1a58958c0a405f3ff780de0c Mon Sep 17 00:00:00 2001 From: David Zhao Date: Wed, 7 Aug 2019 17:08:41 +0900 Subject: [PATCH 16/49] mention that the event was the type --- osu.Game/Beatmaps/Formats/LegacyBeatmapDecoder.cs | 2 +- osu.Game/Beatmaps/Formats/LegacyStoryboardDecoder.cs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/osu.Game/Beatmaps/Formats/LegacyBeatmapDecoder.cs b/osu.Game/Beatmaps/Formats/LegacyBeatmapDecoder.cs index 24843f8c32..b1261855f2 100644 --- a/osu.Game/Beatmaps/Formats/LegacyBeatmapDecoder.cs +++ b/osu.Game/Beatmaps/Formats/LegacyBeatmapDecoder.cs @@ -293,7 +293,7 @@ namespace osu.Game.Beatmaps.Formats if (!Enum.TryParse(split[0], out type)) { - Logger.Log($"A beatmap event could not be parsed and will be ignored: {split[0]}", LoggingTarget.Runtime, LogLevel.Important); + Logger.Log($"Unknown beatmap event of type {split[0]} could not be parsed and will be ignored.", LoggingTarget.Runtime, LogLevel.Important); return; } diff --git a/osu.Game/Beatmaps/Formats/LegacyStoryboardDecoder.cs b/osu.Game/Beatmaps/Formats/LegacyStoryboardDecoder.cs index 512eea0822..584388333d 100644 --- a/osu.Game/Beatmaps/Formats/LegacyStoryboardDecoder.cs +++ b/osu.Game/Beatmaps/Formats/LegacyStoryboardDecoder.cs @@ -84,7 +84,7 @@ namespace osu.Game.Beatmaps.Formats EventType type; if (!Enum.TryParse(split[0], out type)) - Logger.Log($"A storyboard {type} event could not be parsed and will be ignored: {split[0]}", LoggingTarget.Runtime, LogLevel.Important); + Logger.Log($"Unknown storyboard event of type {split[0]} could not be parsed and will be ignored.", LoggingTarget.Runtime, LogLevel.Important); switch (type) { From da15e19912783b3848d9315ed365013c712dfa2c Mon Sep 17 00:00:00 2001 From: David Zhao Date: Wed, 7 Aug 2019 18:40:58 +0900 Subject: [PATCH 17/49] return on storyboard side --- osu.Game/Beatmaps/Formats/LegacyStoryboardDecoder.cs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/osu.Game/Beatmaps/Formats/LegacyStoryboardDecoder.cs b/osu.Game/Beatmaps/Formats/LegacyStoryboardDecoder.cs index 584388333d..f950437e75 100644 --- a/osu.Game/Beatmaps/Formats/LegacyStoryboardDecoder.cs +++ b/osu.Game/Beatmaps/Formats/LegacyStoryboardDecoder.cs @@ -83,8 +83,12 @@ namespace osu.Game.Beatmaps.Formats storyboardSprite = null; EventType type; + if (!Enum.TryParse(split[0], out type)) + { Logger.Log($"Unknown storyboard event of type {split[0]} could not be parsed and will be ignored.", LoggingTarget.Runtime, LogLevel.Important); + return; + } switch (type) { From 15a592e25eec64efd0d7e53ae9d52356a4dbf6ec Mon Sep 17 00:00:00 2001 From: David Zhao Date: Wed, 7 Aug 2019 19:25:40 +0900 Subject: [PATCH 18/49] Just assert doesn't throw and don't catch at LegacyDecoder --- .../Beatmaps/Formats/LegacyBeatmapDecoderTest.cs | 10 ++-------- osu.Game.Tests/Resources/valid-events.osu | 12 ------------ osu.Game/Beatmaps/Formats/LegacyDecoder.cs | 9 +-------- 3 files changed, 3 insertions(+), 28 deletions(-) delete mode 100644 osu.Game.Tests/Resources/valid-events.osu diff --git a/osu.Game.Tests/Beatmaps/Formats/LegacyBeatmapDecoderTest.cs b/osu.Game.Tests/Beatmaps/Formats/LegacyBeatmapDecoderTest.cs index 49a6f646ba..535320530d 100644 --- a/osu.Game.Tests/Beatmaps/Formats/LegacyBeatmapDecoderTest.cs +++ b/osu.Game.Tests/Beatmaps/Formats/LegacyBeatmapDecoderTest.cs @@ -484,20 +484,14 @@ namespace osu.Game.Tests.Beatmaps.Formats } [Test] - public void TestDecodeInvalidEvents() + public void TestInvalidEventStillPasses() { var decoder = new LegacyBeatmapDecoder { ApplyOffsets = false }; - using (var goodResStream = TestResources.OpenResource("valid-events.osu")) - using (var goodStream = new StreamReader(goodResStream)) using (var badResStream = TestResources.OpenResource("invalid-events.osu")) using (var badStream = new StreamReader(badResStream)) { - var goodBeatmap = decoder.Decode(goodStream); - var badBeatmap = decoder.Decode(badStream); - - Assert.AreEqual(goodBeatmap.Breaks[0].Duration, badBeatmap.Breaks[0].Duration); - Assert.AreEqual(goodBeatmap.Metadata.BackgroundFile, badBeatmap.Metadata.BackgroundFile); + Assert.DoesNotThrow(() => decoder.Decode(badStream)); } } } diff --git a/osu.Game.Tests/Resources/valid-events.osu b/osu.Game.Tests/Resources/valid-events.osu deleted file mode 100644 index ed3614b4ed..0000000000 --- a/osu.Game.Tests/Resources/valid-events.osu +++ /dev/null @@ -1,12 +0,0 @@ -osu file format v14 - -[Events] -//Background and Video events -0,0,"machinetop_background.jpg",0,0 -//Break Periods -2,122474,140135 -//Storyboard Layer 0 (Background) -//Storyboard Layer 1 (Fail) -//Storyboard Layer 2 (Pass) -//Storyboard Layer 3 (Foreground) -//Storyboard Sound Samples diff --git a/osu.Game/Beatmaps/Formats/LegacyDecoder.cs b/osu.Game/Beatmaps/Formats/LegacyDecoder.cs index 7999c82761..17e278c48e 100644 --- a/osu.Game/Beatmaps/Formats/LegacyDecoder.cs +++ b/osu.Game/Beatmaps/Formats/LegacyDecoder.cs @@ -43,14 +43,7 @@ namespace osu.Game.Beatmaps.Formats continue; } - try - { - ParseLine(output, section, line); - } - catch (Exception e) - { - Logger.Error(e, $"Failed to process line \"{line}\" into {output}"); - } + ParseLine(output, section, line); } } From b8ccba02f2017dea054b3fce5413e90dff08670c Mon Sep 17 00:00:00 2001 From: David Zhao Date: Wed, 7 Aug 2019 19:33:54 +0900 Subject: [PATCH 19/49] Log to runtime instead --- osu.Game/Beatmaps/Formats/LegacyDecoder.cs | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/osu.Game/Beatmaps/Formats/LegacyDecoder.cs b/osu.Game/Beatmaps/Formats/LegacyDecoder.cs index 17e278c48e..8365fb17d3 100644 --- a/osu.Game/Beatmaps/Formats/LegacyDecoder.cs +++ b/osu.Game/Beatmaps/Formats/LegacyDecoder.cs @@ -43,7 +43,14 @@ namespace osu.Game.Beatmaps.Formats continue; } - ParseLine(output, section, line); + try + { + ParseLine(output, section, line); + } + catch (Exception e) + { + Logger.Log($"Failed to process line \"{line}\" into {output}", LoggingTarget.Runtime, LogLevel.Important); + } } } From bde89adcb72b85fb76476065e017b8533ea79338 Mon Sep 17 00:00:00 2001 From: David Zhao Date: Wed, 7 Aug 2019 19:45:29 +0900 Subject: [PATCH 20/49] show exception message --- osu.Game/Beatmaps/Formats/LegacyDecoder.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Beatmaps/Formats/LegacyDecoder.cs b/osu.Game/Beatmaps/Formats/LegacyDecoder.cs index 8365fb17d3..d6d6804d16 100644 --- a/osu.Game/Beatmaps/Formats/LegacyDecoder.cs +++ b/osu.Game/Beatmaps/Formats/LegacyDecoder.cs @@ -49,7 +49,7 @@ namespace osu.Game.Beatmaps.Formats } catch (Exception e) { - Logger.Log($"Failed to process line \"{line}\" into {output}", LoggingTarget.Runtime, LogLevel.Important); + Logger.Log($"Failed to process line \"{line}\" into {output}: {e.Message}", LoggingTarget.Runtime, LogLevel.Important); } } } From d5b26b86dafbe9b870b50dd23b74f68ad101471d Mon Sep 17 00:00:00 2001 From: iiSaLMaN Date: Wed, 7 Aug 2019 22:18:10 +0300 Subject: [PATCH 21/49] Fix storyboard not showing on disabled user dim --- osu.Game/Graphics/Containers/UserDimContainer.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/osu.Game/Graphics/Containers/UserDimContainer.cs b/osu.Game/Graphics/Containers/UserDimContainer.cs index 03de5f651f..dd5134168f 100644 --- a/osu.Game/Graphics/Containers/UserDimContainer.cs +++ b/osu.Game/Graphics/Containers/UserDimContainer.cs @@ -76,9 +76,9 @@ namespace osu.Game.Graphics.Containers /// protected virtual void UpdateVisuals() { - ContentDisplayed = ShowDimContent; + ContentDisplayed = !EnableUserDim.Value || ShowDimContent; - dimContent.FadeTo((ContentDisplayed) ? 1 : 0, BACKGROUND_FADE_DURATION, Easing.OutQuint); + dimContent.FadeTo(ContentDisplayed ? 1 : 0, BACKGROUND_FADE_DURATION, Easing.OutQuint); dimContent.FadeColour(EnableUserDim.Value ? OsuColour.Gray(1 - (float)UserDimLevel.Value) : Color4.White, BACKGROUND_FADE_DURATION, Easing.OutQuint); } } From a345955f45c51d4ecaeb9cc728db1f30ce40d1f3 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 8 Aug 2019 13:57:04 +0900 Subject: [PATCH 22/49] Add mentions linking ScoreProcessor apply/revert methods together --- osu.Game/Rulesets/Scoring/ScoreProcessor.cs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/osu.Game/Rulesets/Scoring/ScoreProcessor.cs b/osu.Game/Rulesets/Scoring/ScoreProcessor.cs index 2e863f7edb..ba2375bec1 100644 --- a/osu.Game/Rulesets/Scoring/ScoreProcessor.cs +++ b/osu.Game/Rulesets/Scoring/ScoreProcessor.cs @@ -313,6 +313,9 @@ namespace osu.Game.Rulesets.Scoring /// /// Applies the score change of a to this . /// + /// + /// Any changes applied via this method can be reverted via . + /// /// The to apply. protected virtual void ApplyResult(JudgementResult result) { @@ -357,7 +360,7 @@ namespace osu.Game.Rulesets.Scoring } /// - /// Reverts the score change of a that was applied to this . + /// Reverts the score change of a that was applied to this via . /// /// The judgement scoring result. protected virtual void RevertResult(JudgementResult result) From ac2060f1cf4d1befc59d2b56531d58736f0dd021 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Thu, 8 Aug 2019 14:44:04 +0900 Subject: [PATCH 23/49] Throw exceptions and let LegacyDecoder handle them --- .../Beatmaps/Formats/LegacyBeatmapDecoder.cs | 153 ++++----- .../Formats/LegacyStoryboardDecoder.cs | 6 +- .../Objects/Legacy/ConvertHitObjectParser.cs | 323 +++++++++--------- 3 files changed, 223 insertions(+), 259 deletions(-) diff --git a/osu.Game/Beatmaps/Formats/LegacyBeatmapDecoder.cs b/osu.Game/Beatmaps/Formats/LegacyBeatmapDecoder.cs index b1261855f2..02d969b571 100644 --- a/osu.Game/Beatmaps/Formats/LegacyBeatmapDecoder.cs +++ b/osu.Game/Beatmaps/Formats/LegacyBeatmapDecoder.cs @@ -5,7 +5,6 @@ using System; using System.IO; using System.Linq; using osu.Framework.IO.File; -using osu.Framework.Logging; using osu.Game.Beatmaps.Timing; using osu.Game.Rulesets.Objects.Legacy; using osu.Game.Beatmaps.ControlPoints; @@ -292,10 +291,7 @@ namespace osu.Game.Beatmaps.Formats EventType type; if (!Enum.TryParse(split[0], out type)) - { - Logger.Log($"Unknown beatmap event of type {split[0]} could not be parsed and will be ignored.", LoggingTarget.Runtime, LogLevel.Important); - return; - } + throw new InvalidDataException($@"Unknown event type: {split[0]}"); switch (type) { @@ -323,90 +319,79 @@ namespace osu.Game.Beatmaps.Formats private void handleTimingPoint(string line) { - try + string[] split = line.Split(','); + + double time = getOffsetTime(Parsing.ParseDouble(split[0].Trim())); + double beatLength = Parsing.ParseDouble(split[1].Trim()); + double speedMultiplier = beatLength < 0 ? 100.0 / -beatLength : 1; + + TimeSignatures timeSignature = TimeSignatures.SimpleQuadruple; + if (split.Length >= 3) + timeSignature = split[2][0] == '0' ? TimeSignatures.SimpleQuadruple : (TimeSignatures)Parsing.ParseInt(split[2]); + + LegacySampleBank sampleSet = defaultSampleBank; + if (split.Length >= 4) + sampleSet = (LegacySampleBank)Parsing.ParseInt(split[3]); + + int customSampleBank = 0; + if (split.Length >= 5) + customSampleBank = Parsing.ParseInt(split[4]); + + int sampleVolume = defaultSampleVolume; + if (split.Length >= 6) + sampleVolume = Parsing.ParseInt(split[5]); + + bool timingChange = true; + if (split.Length >= 7) + timingChange = split[6][0] == '1'; + + bool kiaiMode = false; + bool omitFirstBarSignature = false; + + if (split.Length >= 8) { - string[] split = line.Split(','); - - double time = getOffsetTime(Parsing.ParseDouble(split[0].Trim())); - double beatLength = Parsing.ParseDouble(split[1].Trim()); - double speedMultiplier = beatLength < 0 ? 100.0 / -beatLength : 1; - - TimeSignatures timeSignature = TimeSignatures.SimpleQuadruple; - if (split.Length >= 3) - timeSignature = split[2][0] == '0' ? TimeSignatures.SimpleQuadruple : (TimeSignatures)Parsing.ParseInt(split[2]); - - LegacySampleBank sampleSet = defaultSampleBank; - if (split.Length >= 4) - sampleSet = (LegacySampleBank)Parsing.ParseInt(split[3]); - - int customSampleBank = 0; - if (split.Length >= 5) - customSampleBank = Parsing.ParseInt(split[4]); - - int sampleVolume = defaultSampleVolume; - if (split.Length >= 6) - sampleVolume = Parsing.ParseInt(split[5]); - - bool timingChange = true; - if (split.Length >= 7) - timingChange = split[6][0] == '1'; - - bool kiaiMode = false; - bool omitFirstBarSignature = false; - - if (split.Length >= 8) - { - EffectFlags effectFlags = (EffectFlags)Parsing.ParseInt(split[7]); - kiaiMode = effectFlags.HasFlag(EffectFlags.Kiai); - omitFirstBarSignature = effectFlags.HasFlag(EffectFlags.OmitFirstBarLine); - } - - string stringSampleSet = sampleSet.ToString().ToLowerInvariant(); - if (stringSampleSet == @"none") - stringSampleSet = @"normal"; - - if (timingChange) - { - var controlPoint = CreateTimingControlPoint(); - controlPoint.Time = time; - controlPoint.BeatLength = beatLength; - controlPoint.TimeSignature = timeSignature; - - handleTimingControlPoint(controlPoint); - } - - handleDifficultyControlPoint(new DifficultyControlPoint - { - Time = time, - SpeedMultiplier = speedMultiplier, - AutoGenerated = timingChange - }); - - handleEffectControlPoint(new EffectControlPoint - { - Time = time, - KiaiMode = kiaiMode, - OmitFirstBarLine = omitFirstBarSignature, - AutoGenerated = timingChange - }); - - handleSampleControlPoint(new LegacySampleControlPoint - { - Time = time, - SampleBank = stringSampleSet, - SampleVolume = sampleVolume, - CustomSampleBank = customSampleBank, - AutoGenerated = timingChange - }); + EffectFlags effectFlags = (EffectFlags)Parsing.ParseInt(split[7]); + kiaiMode = effectFlags.HasFlag(EffectFlags.Kiai); + omitFirstBarSignature = effectFlags.HasFlag(EffectFlags.OmitFirstBarLine); } - catch (FormatException) + + string stringSampleSet = sampleSet.ToString().ToLowerInvariant(); + if (stringSampleSet == @"none") + stringSampleSet = @"normal"; + + if (timingChange) { - Logger.Log("A timing point could not be parsed correctly and will be ignored", LoggingTarget.Runtime, LogLevel.Important); + var controlPoint = CreateTimingControlPoint(); + controlPoint.Time = time; + controlPoint.BeatLength = beatLength; + controlPoint.TimeSignature = timeSignature; + + handleTimingControlPoint(controlPoint); } - catch (OverflowException) + + handleDifficultyControlPoint(new DifficultyControlPoint { - Logger.Log("A timing point could not be parsed correctly and will be ignored", LoggingTarget.Runtime, LogLevel.Important); - } + Time = time, + SpeedMultiplier = speedMultiplier, + AutoGenerated = timingChange + }); + + handleEffectControlPoint(new EffectControlPoint + { + Time = time, + KiaiMode = kiaiMode, + OmitFirstBarLine = omitFirstBarSignature, + AutoGenerated = timingChange + }); + + handleSampleControlPoint(new LegacySampleControlPoint + { + Time = time, + SampleBank = stringSampleSet, + SampleVolume = sampleVolume, + CustomSampleBank = customSampleBank, + AutoGenerated = timingChange + }); } private void handleTimingControlPoint(TimingControlPoint newPoint) diff --git a/osu.Game/Beatmaps/Formats/LegacyStoryboardDecoder.cs b/osu.Game/Beatmaps/Formats/LegacyStoryboardDecoder.cs index f950437e75..3ae1c3ef12 100644 --- a/osu.Game/Beatmaps/Formats/LegacyStoryboardDecoder.cs +++ b/osu.Game/Beatmaps/Formats/LegacyStoryboardDecoder.cs @@ -10,7 +10,6 @@ using osuTK; using osuTK.Graphics; using osu.Framework.Graphics; using osu.Framework.IO.File; -using osu.Framework.Logging; using osu.Game.Storyboards; namespace osu.Game.Beatmaps.Formats @@ -85,10 +84,7 @@ namespace osu.Game.Beatmaps.Formats EventType type; if (!Enum.TryParse(split[0], out type)) - { - Logger.Log($"Unknown storyboard event of type {split[0]} could not be parsed and will be ignored.", LoggingTarget.Runtime, LogLevel.Important); - return; - } + throw new InvalidDataException($@"Unknown event type: {split[0]}"); switch (type) { diff --git a/osu.Game/Rulesets/Objects/Legacy/ConvertHitObjectParser.cs b/osu.Game/Rulesets/Objects/Legacy/ConvertHitObjectParser.cs index d70c1bf7d3..442e37edf5 100644 --- a/osu.Game/Rulesets/Objects/Legacy/ConvertHitObjectParser.cs +++ b/osu.Game/Rulesets/Objects/Legacy/ConvertHitObjectParser.cs @@ -10,7 +10,6 @@ using osu.Game.Beatmaps.Formats; using osu.Game.Audio; using System.Linq; using JetBrains.Annotations; -using osu.Framework.Logging; using osu.Framework.MathUtils; namespace osu.Game.Rulesets.Objects.Legacy @@ -41,208 +40,192 @@ namespace osu.Game.Rulesets.Objects.Legacy [CanBeNull] public override HitObject Parse(string text) { - try + string[] split = text.Split(','); + + Vector2 pos = new Vector2((int)Parsing.ParseFloat(split[0], Parsing.MAX_COORDINATE_VALUE), (int)Parsing.ParseFloat(split[1], Parsing.MAX_COORDINATE_VALUE)); + + double startTime = Parsing.ParseDouble(split[2]) + Offset; + + ConvertHitObjectType type = (ConvertHitObjectType)Parsing.ParseInt(split[3]); + + int comboOffset = (int)(type & ConvertHitObjectType.ComboOffset) >> 4; + type &= ~ConvertHitObjectType.ComboOffset; + + bool combo = type.HasFlag(ConvertHitObjectType.NewCombo); + type &= ~ConvertHitObjectType.NewCombo; + + var soundType = (LegacySoundType)Parsing.ParseInt(split[4]); + var bankInfo = new SampleBankInfo(); + + HitObject result = null; + + if (type.HasFlag(ConvertHitObjectType.Circle)) { - string[] split = text.Split(','); + result = CreateHit(pos, combo, comboOffset); - Vector2 pos = new Vector2((int)Parsing.ParseFloat(split[0], Parsing.MAX_COORDINATE_VALUE), (int)Parsing.ParseFloat(split[1], Parsing.MAX_COORDINATE_VALUE)); + if (split.Length > 5) + readCustomSampleBanks(split[5], bankInfo); + } + else if (type.HasFlag(ConvertHitObjectType.Slider)) + { + PathType pathType = PathType.Catmull; + double? length = null; - double startTime = Parsing.ParseDouble(split[2]) + Offset; + string[] pointSplit = split[5].Split('|'); - ConvertHitObjectType type = (ConvertHitObjectType)Parsing.ParseInt(split[3]); + int pointCount = 1; + foreach (var t in pointSplit) + if (t.Length > 1) + pointCount++; - int comboOffset = (int)(type & ConvertHitObjectType.ComboOffset) >> 4; - type &= ~ConvertHitObjectType.ComboOffset; + var points = new Vector2[pointCount]; - bool combo = type.HasFlag(ConvertHitObjectType.NewCombo); - type &= ~ConvertHitObjectType.NewCombo; + int pointIndex = 1; - var soundType = (LegacySoundType)Parsing.ParseInt(split[4]); - var bankInfo = new SampleBankInfo(); - - HitObject result = null; - - if (type.HasFlag(ConvertHitObjectType.Circle)) + foreach (string t in pointSplit) { - result = CreateHit(pos, combo, comboOffset); - - if (split.Length > 5) - readCustomSampleBanks(split[5], bankInfo); - } - else if (type.HasFlag(ConvertHitObjectType.Slider)) - { - PathType pathType = PathType.Catmull; - double? length = null; - - string[] pointSplit = split[5].Split('|'); - - int pointCount = 1; - foreach (var t in pointSplit) - if (t.Length > 1) - pointCount++; - - var points = new Vector2[pointCount]; - - int pointIndex = 1; - - foreach (string t in pointSplit) + if (t.Length == 1) { - if (t.Length == 1) + switch (t) { - switch (t) - { - case @"C": - pathType = PathType.Catmull; - break; - - case @"B": - pathType = PathType.Bezier; - break; - - case @"L": - pathType = PathType.Linear; - break; - - case @"P": - pathType = PathType.PerfectCurve; - break; - } - - continue; - } - - string[] temp = t.Split(':'); - points[pointIndex++] = new Vector2((int)Parsing.ParseDouble(temp[0], Parsing.MAX_COORDINATE_VALUE), (int)Parsing.ParseDouble(temp[1], Parsing.MAX_COORDINATE_VALUE)) - pos; - } - - // osu-stable special-cased colinear perfect curves to a CurveType.Linear - bool isLinear(Vector2[] p) => Precision.AlmostEquals(0, (p[1].Y - p[0].Y) * (p[2].X - p[0].X) - (p[1].X - p[0].X) * (p[2].Y - p[0].Y)); - - if (points.Length == 3 && pathType == PathType.PerfectCurve && isLinear(points)) - pathType = PathType.Linear; - - int repeatCount = Parsing.ParseInt(split[6]); - - if (repeatCount > 9000) - throw new ArgumentOutOfRangeException(nameof(repeatCount), @"Repeat count is way too high"); - - // osu-stable treated the first span of the slider as a repeat, but no repeats are happening - repeatCount = Math.Max(0, repeatCount - 1); - - if (split.Length > 7) - { - length = Math.Max(0, Parsing.ParseDouble(split[7])); - if (length == 0) - length = null; - } - - if (split.Length > 10) - readCustomSampleBanks(split[10], bankInfo); - - // One node for each repeat + the start and end nodes - int nodes = repeatCount + 2; - - // Populate node sample bank infos with the default hit object sample bank - var nodeBankInfos = new List(); - for (int i = 0; i < nodes; i++) - nodeBankInfos.Add(bankInfo.Clone()); - - // Read any per-node sample banks - if (split.Length > 9 && split[9].Length > 0) - { - string[] sets = split[9].Split('|'); - - for (int i = 0; i < nodes; i++) - { - if (i >= sets.Length) + case @"C": + pathType = PathType.Catmull; break; - SampleBankInfo info = nodeBankInfos[i]; - readCustomSampleBanks(sets[i], info); - } - } - - // Populate node sound types with the default hit object sound type - var nodeSoundTypes = new List(); - for (int i = 0; i < nodes; i++) - nodeSoundTypes.Add(soundType); - - // Read any per-node sound types - if (split.Length > 8 && split[8].Length > 0) - { - string[] adds = split[8].Split('|'); - - for (int i = 0; i < nodes; i++) - { - if (i >= adds.Length) + case @"B": + pathType = PathType.Bezier; break; - int sound; - int.TryParse(adds[i], out sound); - nodeSoundTypes[i] = (LegacySoundType)sound; + case @"L": + pathType = PathType.Linear; + break; + + case @"P": + pathType = PathType.PerfectCurve; + break; } + + continue; } - // Generate the final per-node samples - var nodeSamples = new List>(nodes); + string[] temp = t.Split(':'); + points[pointIndex++] = new Vector2((int)Parsing.ParseDouble(temp[0], Parsing.MAX_COORDINATE_VALUE), (int)Parsing.ParseDouble(temp[1], Parsing.MAX_COORDINATE_VALUE)) - pos; + } + + // osu-stable special-cased colinear perfect curves to a CurveType.Linear + bool isLinear(Vector2[] p) => Precision.AlmostEquals(0, (p[1].Y - p[0].Y) * (p[2].X - p[0].X) - (p[1].X - p[0].X) * (p[2].Y - p[0].Y)); + + if (points.Length == 3 && pathType == PathType.PerfectCurve && isLinear(points)) + pathType = PathType.Linear; + + int repeatCount = Parsing.ParseInt(split[6]); + + if (repeatCount > 9000) + throw new ArgumentOutOfRangeException(nameof(repeatCount), @"Repeat count is way too high"); + + // osu-stable treated the first span of the slider as a repeat, but no repeats are happening + repeatCount = Math.Max(0, repeatCount - 1); + + if (split.Length > 7) + { + length = Math.Max(0, Parsing.ParseDouble(split[7])); + if (length == 0) + length = null; + } + + if (split.Length > 10) + readCustomSampleBanks(split[10], bankInfo); + + // One node for each repeat + the start and end nodes + int nodes = repeatCount + 2; + + // Populate node sample bank infos with the default hit object sample bank + var nodeBankInfos = new List(); + for (int i = 0; i < nodes; i++) + nodeBankInfos.Add(bankInfo.Clone()); + + // Read any per-node sample banks + if (split.Length > 9 && split[9].Length > 0) + { + string[] sets = split[9].Split('|'); + for (int i = 0; i < nodes; i++) - nodeSamples.Add(convertSoundType(nodeSoundTypes[i], nodeBankInfos[i])); - - result = CreateSlider(pos, combo, comboOffset, points, length, pathType, repeatCount, nodeSamples); - - // The samples are played when the slider ends, which is the last node - result.Samples = nodeSamples[nodeSamples.Count - 1]; - } - else if (type.HasFlag(ConvertHitObjectType.Spinner)) - { - double endTime = Math.Max(startTime, Parsing.ParseDouble(split[5]) + Offset); - - result = CreateSpinner(new Vector2(512, 384) / 2, combo, comboOffset, endTime); - - if (split.Length > 6) - readCustomSampleBanks(split[6], bankInfo); - } - else if (type.HasFlag(ConvertHitObjectType.Hold)) - { - // Note: Hold is generated by BMS converts - - double endTime = Math.Max(startTime, Parsing.ParseDouble(split[2])); - - if (split.Length > 5 && !string.IsNullOrEmpty(split[5])) { - string[] ss = split[5].Split(':'); - endTime = Math.Max(startTime, Parsing.ParseDouble(ss[0])); - readCustomSampleBanks(string.Join(":", ss.Skip(1)), bankInfo); + if (i >= sets.Length) + break; + + SampleBankInfo info = nodeBankInfos[i]; + readCustomSampleBanks(sets[i], info); } - - result = CreateHold(pos, combo, comboOffset, endTime + Offset); } - if (result == null) + // Populate node sound types with the default hit object sound type + var nodeSoundTypes = new List(); + for (int i = 0; i < nodes; i++) + nodeSoundTypes.Add(soundType); + + // Read any per-node sound types + if (split.Length > 8 && split[8].Length > 0) { - Logger.Log($"Unknown hit object type: {type}. Skipped.", level: LogLevel.Error); - return null; + string[] adds = split[8].Split('|'); + + for (int i = 0; i < nodes; i++) + { + if (i >= adds.Length) + break; + + int sound; + int.TryParse(adds[i], out sound); + nodeSoundTypes[i] = (LegacySoundType)sound; + } } - result.StartTime = startTime; + // Generate the final per-node samples + var nodeSamples = new List>(nodes); + for (int i = 0; i < nodes; i++) + nodeSamples.Add(convertSoundType(nodeSoundTypes[i], nodeBankInfos[i])); - if (result.Samples.Count == 0) - result.Samples = convertSoundType(soundType, bankInfo); + result = CreateSlider(pos, combo, comboOffset, points, length, pathType, repeatCount, nodeSamples); - FirstObject = false; - - return result; + // The samples are played when the slider ends, which is the last node + result.Samples = nodeSamples[nodeSamples.Count - 1]; } - catch (FormatException) + else if (type.HasFlag(ConvertHitObjectType.Spinner)) { - Logger.Log("A hitobject could not be parsed correctly and will be ignored", LoggingTarget.Runtime, LogLevel.Important); + double endTime = Math.Max(startTime, Parsing.ParseDouble(split[5]) + Offset); + + result = CreateSpinner(new Vector2(512, 384) / 2, combo, comboOffset, endTime); + + if (split.Length > 6) + readCustomSampleBanks(split[6], bankInfo); } - catch (OverflowException) + else if (type.HasFlag(ConvertHitObjectType.Hold)) { - Logger.Log("A hitobject could not be parsed correctly and will be ignored", LoggingTarget.Runtime, LogLevel.Important); + // Note: Hold is generated by BMS converts + + double endTime = Math.Max(startTime, Parsing.ParseDouble(split[2])); + + if (split.Length > 5 && !string.IsNullOrEmpty(split[5])) + { + string[] ss = split[5].Split(':'); + endTime = Math.Max(startTime, Parsing.ParseDouble(ss[0])); + readCustomSampleBanks(string.Join(":", ss.Skip(1)), bankInfo); + } + + result = CreateHold(pos, combo, comboOffset, endTime + Offset); } - return null; + if (result == null) + throw new InvalidDataException($"Unknown hit object type: {type}"); + + result.StartTime = startTime; + + if (result.Samples.Count == 0) + result.Samples = convertSoundType(soundType, bankInfo); + + FirstObject = false; + + return result; } private void readCustomSampleBanks(string str, SampleBankInfo bankInfo) From de4ad1f62586fb3c55cd8067ac9672f284c8cfbf Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Thu, 8 Aug 2019 14:44:49 +0900 Subject: [PATCH 24/49] Fix bad log message --- osu.Game/Rulesets/Objects/Legacy/ConvertHitObjectParser.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Rulesets/Objects/Legacy/ConvertHitObjectParser.cs b/osu.Game/Rulesets/Objects/Legacy/ConvertHitObjectParser.cs index 442e37edf5..e990938291 100644 --- a/osu.Game/Rulesets/Objects/Legacy/ConvertHitObjectParser.cs +++ b/osu.Game/Rulesets/Objects/Legacy/ConvertHitObjectParser.cs @@ -216,7 +216,7 @@ namespace osu.Game.Rulesets.Objects.Legacy } if (result == null) - throw new InvalidDataException($"Unknown hit object type: {type}"); + throw new InvalidDataException($"Unknown hit object type: {split[3]}"); result.StartTime = startTime; From 6d5a7041fdf7873c36eff28d8e624e68fc0088ca Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 8 Aug 2019 17:10:06 +0900 Subject: [PATCH 25/49] Move system user colour assignment to ensure consistency --- osu.Game/Online/Chat/ErrorMessage.cs | 2 +- osu.Game/Users/User.cs | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/osu.Game/Online/Chat/ErrorMessage.cs b/osu.Game/Online/Chat/ErrorMessage.cs index a8ff0e9a98..87a65fb3f1 100644 --- a/osu.Game/Online/Chat/ErrorMessage.cs +++ b/osu.Game/Online/Chat/ErrorMessage.cs @@ -8,7 +8,7 @@ namespace osu.Game.Online.Chat public ErrorMessage(string message) : base(message) { - Sender.Colour = @"ff0000"; + // todo: this should likely be styled differently in the future. } } } diff --git a/osu.Game/Users/User.cs b/osu.Game/Users/User.cs index b738eff4a6..a5f3578711 100644 --- a/osu.Game/Users/User.cs +++ b/osu.Game/Users/User.cs @@ -187,6 +187,7 @@ namespace osu.Game.Users public static readonly User SYSTEM_USER = new User { Username = "system", + Colour = @"9c0101", Id = 0 }; From 3ebfa0505c21bec9ef00fe643b05dbd52336444b Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Thu, 8 Aug 2019 18:26:03 +0900 Subject: [PATCH 26/49] Don't share single scheduler across all model managers --- osu.Game/Database/ArchiveModelManager.cs | 29 +++++++++++------------- 1 file changed, 13 insertions(+), 16 deletions(-) diff --git a/osu.Game/Database/ArchiveModelManager.cs b/osu.Game/Database/ArchiveModelManager.cs index efb76deff8..52d3f013ce 100644 --- a/osu.Game/Database/ArchiveModelManager.cs +++ b/osu.Game/Database/ArchiveModelManager.cs @@ -31,10 +31,21 @@ namespace osu.Game.Database /// /// The model type. /// The associated file join type. - public abstract class ArchiveModelManager : ArchiveModelManager, ICanAcceptFiles, IModelManager + public abstract class ArchiveModelManager : ICanAcceptFiles, IModelManager where TModel : class, IHasFiles, IHasPrimaryKey, ISoftDelete where TFileModel : INamedFileInfo, new() { + private const int import_queue_request_concurrency = 1; + + /// + /// A singleton scheduler shared by all . + /// + /// + /// This scheduler generally performs IO and CPU intensive work so concurrency is limited harshly. + /// It is mainly being used as a queue mechanism for large imports. + /// + private static readonly ThreadedTaskScheduler import_scheduler = new ThreadedTaskScheduler(import_queue_request_concurrency, nameof(ArchiveModelManager)); + /// /// Set an endpoint for notifications to be posted to. /// @@ -336,7 +347,7 @@ namespace osu.Game.Database flushEvents(true); return item; - }, cancellationToken, TaskCreationOptions.HideScheduler, IMPORT_SCHEDULER).Unwrap(); + }, cancellationToken, TaskCreationOptions.HideScheduler, import_scheduler).Unwrap(); /// /// Perform an update of the specified item. @@ -646,18 +657,4 @@ namespace osu.Game.Database #endregion } - - public abstract class ArchiveModelManager - { - private const int import_queue_request_concurrency = 1; - - /// - /// A singleton scheduler shared by all . - /// - /// - /// This scheduler generally performs IO and CPU intensive work so concurrency is limited harshly. - /// It is mainly being used as a queue mechanism for large imports. - /// - protected static readonly ThreadedTaskScheduler IMPORT_SCHEDULER = new ThreadedTaskScheduler(import_queue_request_concurrency, nameof(ArchiveModelManager)); - } } From 537973fc458f50a260e1e8d31f217a146b02cd88 Mon Sep 17 00:00:00 2001 From: iiSaLMaN Date: Thu, 8 Aug 2019 15:59:29 +0300 Subject: [PATCH 27/49] Add test for disabling user dim on storyboard --- .../Background/TestSceneUserDimContainer.cs | 26 +++++++++++++++++-- 1 file changed, 24 insertions(+), 2 deletions(-) diff --git a/osu.Game.Tests/Visual/Background/TestSceneUserDimContainer.cs b/osu.Game.Tests/Visual/Background/TestSceneUserDimContainer.cs index f114559114..bffee7f1f7 100644 --- a/osu.Game.Tests/Visual/Background/TestSceneUserDimContainer.cs +++ b/osu.Game.Tests/Visual/Background/TestSceneUserDimContainer.cs @@ -149,10 +149,10 @@ namespace osu.Game.Tests.Visual.Background } /// - /// Check if the is properly accepting user-defined visual changes at all. + /// Check if the is properly accepting user-defined visual changes in background at all. /// [Test] - public void DisableUserDimTest() + public void DisableUserDimBackgroundTest() { performFullSetup(); waitForDim(); @@ -165,6 +165,28 @@ namespace osu.Game.Tests.Visual.Background AddAssert("Screen is dimmed and blur applied", () => songSelect.IsBackgroundDimmed() && songSelect.IsUserBlurApplied()); } + /// + /// Check if the is properly accepting user-defined visual changes in storyboard at all. + /// + [Test] + public void DisableUserDimStoryboardTest() + { + performFullSetup(); + createFakeStoryboard(); + AddStep("Storyboard Enabled", () => + { + player.ReplacesBackground.Value = true; + player.StoryboardEnabled.Value = true; + }); + AddStep("EnableUserDim enabled", () => player.DimmableStoryboard.EnableUserDim.Value = true); + AddStep("Set dim level to 1", () => songSelect.DimLevel.Value = 1f); + waitForDim(); + AddAssert("Storyboard is invisible", () => !player.IsStoryboardVisible); + AddStep("EnableUserDim disabled", () => player.DimmableStoryboard.EnableUserDim.Value = false); + waitForDim(); + AddAssert("Storyboard is visible", () => player.IsStoryboardVisible); + } + /// /// Check if the visual settings container retains dim and blur when pausing /// From 88b9942b2ac601d33c40a41f8d3625b7788eabf5 Mon Sep 17 00:00:00 2001 From: iiSaLMaN Date: Thu, 8 Aug 2019 17:07:06 +0300 Subject: [PATCH 28/49] Move EnableUserDim check to defualt value of ShowDimContent --- osu.Game/Graphics/Containers/UserDimContainer.cs | 2 +- osu.Game/Screens/Play/DimmableStoryboard.cs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/osu.Game/Graphics/Containers/UserDimContainer.cs b/osu.Game/Graphics/Containers/UserDimContainer.cs index dd5134168f..b7da5592a8 100644 --- a/osu.Game/Graphics/Containers/UserDimContainer.cs +++ b/osu.Game/Graphics/Containers/UserDimContainer.cs @@ -69,7 +69,7 @@ namespace osu.Game.Graphics.Containers /// /// Whether the content of this container should currently be visible. /// - protected virtual bool ShowDimContent => true; + protected virtual bool ShowDimContent => !EnableUserDim.Value; /// /// Should be invoked when any dependent dim level or user setting is changed and bring the visual state up-to-date. diff --git a/osu.Game/Screens/Play/DimmableStoryboard.cs b/osu.Game/Screens/Play/DimmableStoryboard.cs index 45dff039b6..10ddaeb354 100644 --- a/osu.Game/Screens/Play/DimmableStoryboard.cs +++ b/osu.Game/Screens/Play/DimmableStoryboard.cs @@ -33,7 +33,7 @@ namespace osu.Game.Screens.Play base.LoadComplete(); } - protected override bool ShowDimContent => ShowStoryboard.Value && UserDimLevel.Value < 1; + protected override bool ShowDimContent => base.ShowDimContent || ShowStoryboard.Value && UserDimLevel.Value < 1; private void initializeStoryboard(bool async) { From bedb744a2e067a53d6aa5fdcbc1c6ede16245b9e Mon Sep 17 00:00:00 2001 From: iiSaLMaN Date: Thu, 8 Aug 2019 17:11:26 +0300 Subject: [PATCH 29/49] Add parentheses --- osu.Game/Screens/Play/DimmableStoryboard.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Screens/Play/DimmableStoryboard.cs b/osu.Game/Screens/Play/DimmableStoryboard.cs index 10ddaeb354..8d1f703791 100644 --- a/osu.Game/Screens/Play/DimmableStoryboard.cs +++ b/osu.Game/Screens/Play/DimmableStoryboard.cs @@ -33,7 +33,7 @@ namespace osu.Game.Screens.Play base.LoadComplete(); } - protected override bool ShowDimContent => base.ShowDimContent || ShowStoryboard.Value && UserDimLevel.Value < 1; + protected override bool ShowDimContent => base.ShowDimContent || (ShowStoryboard.Value && UserDimLevel.Value < 1); private void initializeStoryboard(bool async) { From a3d90da7d4663ee1e0653bdcb9d70143bc89ae9b Mon Sep 17 00:00:00 2001 From: iiSaLMaN Date: Thu, 8 Aug 2019 17:29:52 +0300 Subject: [PATCH 30/49] Remove unnecessary check --- osu.Game/Graphics/Containers/UserDimContainer.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Graphics/Containers/UserDimContainer.cs b/osu.Game/Graphics/Containers/UserDimContainer.cs index b7da5592a8..6696a5bfe0 100644 --- a/osu.Game/Graphics/Containers/UserDimContainer.cs +++ b/osu.Game/Graphics/Containers/UserDimContainer.cs @@ -76,7 +76,7 @@ namespace osu.Game.Graphics.Containers /// protected virtual void UpdateVisuals() { - ContentDisplayed = !EnableUserDim.Value || ShowDimContent; + ContentDisplayed = ShowDimContent; dimContent.FadeTo(ContentDisplayed ? 1 : 0, BACKGROUND_FADE_DURATION, Easing.OutQuint); dimContent.FadeColour(EnableUserDim.Value ? OsuColour.Gray(1 - (float)UserDimLevel.Value) : Color4.White, BACKGROUND_FADE_DURATION, Easing.OutQuint); From 0fcc6c1676089fd2dd963f937bf317b68252336e Mon Sep 17 00:00:00 2001 From: iiSaLMaN Date: Thu, 8 Aug 2019 22:13:48 +0300 Subject: [PATCH 31/49] Add DimLevel property --- osu.Game/Graphics/Containers/UserDimContainer.cs | 6 ++++-- osu.Game/Screens/Play/DimmableStoryboard.cs | 2 +- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/osu.Game/Graphics/Containers/UserDimContainer.cs b/osu.Game/Graphics/Containers/UserDimContainer.cs index 6696a5bfe0..023964d701 100644 --- a/osu.Game/Graphics/Containers/UserDimContainer.cs +++ b/osu.Game/Graphics/Containers/UserDimContainer.cs @@ -36,6 +36,8 @@ namespace osu.Game.Graphics.Containers protected Bindable ShowStoryboard { get; private set; } + protected double DimLevel => EnableUserDim.Value ? UserDimLevel.Value : 0; + protected override Container Content => dimContent; private Container dimContent { get; } @@ -69,7 +71,7 @@ namespace osu.Game.Graphics.Containers /// /// Whether the content of this container should currently be visible. /// - protected virtual bool ShowDimContent => !EnableUserDim.Value; + protected virtual bool ShowDimContent => true; /// /// Should be invoked when any dependent dim level or user setting is changed and bring the visual state up-to-date. @@ -79,7 +81,7 @@ namespace osu.Game.Graphics.Containers ContentDisplayed = ShowDimContent; dimContent.FadeTo(ContentDisplayed ? 1 : 0, BACKGROUND_FADE_DURATION, Easing.OutQuint); - dimContent.FadeColour(EnableUserDim.Value ? OsuColour.Gray(1 - (float)UserDimLevel.Value) : Color4.White, BACKGROUND_FADE_DURATION, Easing.OutQuint); + dimContent.FadeColour(OsuColour.Gray(1 - (float)DimLevel), BACKGROUND_FADE_DURATION, Easing.OutQuint); } } } diff --git a/osu.Game/Screens/Play/DimmableStoryboard.cs b/osu.Game/Screens/Play/DimmableStoryboard.cs index 8d1f703791..2154526e54 100644 --- a/osu.Game/Screens/Play/DimmableStoryboard.cs +++ b/osu.Game/Screens/Play/DimmableStoryboard.cs @@ -33,7 +33,7 @@ namespace osu.Game.Screens.Play base.LoadComplete(); } - protected override bool ShowDimContent => base.ShowDimContent || (ShowStoryboard.Value && UserDimLevel.Value < 1); + protected override bool ShowDimContent => ShowStoryboard.Value && DimLevel < 1; private void initializeStoryboard(bool async) { From 565034e658ace24fd3d2ab493bc0df5496a9cdfb Mon Sep 17 00:00:00 2001 From: iiSaLMaN Date: Thu, 8 Aug 2019 22:14:51 +0300 Subject: [PATCH 32/49] Remove unnecessary using directive --- osu.Game/Graphics/Containers/UserDimContainer.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/osu.Game/Graphics/Containers/UserDimContainer.cs b/osu.Game/Graphics/Containers/UserDimContainer.cs index 023964d701..2b7635cc88 100644 --- a/osu.Game/Graphics/Containers/UserDimContainer.cs +++ b/osu.Game/Graphics/Containers/UserDimContainer.cs @@ -6,7 +6,6 @@ using osu.Framework.Bindables; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Game.Configuration; -using osuTK.Graphics; namespace osu.Game.Graphics.Containers { From 7e9c100c9b25dd450e290da9d74ac068010f0044 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 9 Aug 2019 12:29:33 +0900 Subject: [PATCH 33/49] Apply new resharper refactors --- osu.Game.Rulesets.Mania/Beatmaps/Patterns/Legacy/PatternType.cs | 2 +- osu.Game/Beatmaps/Legacy/LegacyMods.cs | 2 +- osu.Game/Graphics/UserInterface/Bar.cs | 2 +- osu.Game/Rulesets/Objects/Legacy/ConvertHitObjectType.cs | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/osu.Game.Rulesets.Mania/Beatmaps/Patterns/Legacy/PatternType.cs b/osu.Game.Rulesets.Mania/Beatmaps/Patterns/Legacy/PatternType.cs index a3cd455886..e4a28167ec 100644 --- a/osu.Game.Rulesets.Mania/Beatmaps/Patterns/Legacy/PatternType.cs +++ b/osu.Game.Rulesets.Mania/Beatmaps/Patterns/Legacy/PatternType.cs @@ -16,7 +16,7 @@ namespace osu.Game.Rulesets.Mania.Beatmaps.Patterns.Legacy /// /// Keep the same as last row. /// - ForceStack = 1 << 0, + ForceStack = 1, /// /// Keep different from last row. diff --git a/osu.Game/Beatmaps/Legacy/LegacyMods.cs b/osu.Game/Beatmaps/Legacy/LegacyMods.cs index 8e53c24e7b..583e950e49 100644 --- a/osu.Game/Beatmaps/Legacy/LegacyMods.cs +++ b/osu.Game/Beatmaps/Legacy/LegacyMods.cs @@ -9,7 +9,7 @@ namespace osu.Game.Beatmaps.Legacy public enum LegacyMods { None = 0, - NoFail = 1 << 0, + NoFail = 1, Easy = 1 << 1, TouchDevice = 1 << 2, Hidden = 1 << 3, diff --git a/osu.Game/Graphics/UserInterface/Bar.cs b/osu.Game/Graphics/UserInterface/Bar.cs index 2a858ccbcf..f8d5955503 100644 --- a/osu.Game/Graphics/UserInterface/Bar.cs +++ b/osu.Game/Graphics/UserInterface/Bar.cs @@ -110,7 +110,7 @@ namespace osu.Game.Graphics.UserInterface [Flags] public enum BarDirection { - LeftToRight = 1 << 0, + LeftToRight = 1, RightToLeft = 1 << 1, TopToBottom = 1 << 2, BottomToTop = 1 << 3, diff --git a/osu.Game/Rulesets/Objects/Legacy/ConvertHitObjectType.cs b/osu.Game/Rulesets/Objects/Legacy/ConvertHitObjectType.cs index c9f7224643..eab37b682c 100644 --- a/osu.Game/Rulesets/Objects/Legacy/ConvertHitObjectType.cs +++ b/osu.Game/Rulesets/Objects/Legacy/ConvertHitObjectType.cs @@ -8,7 +8,7 @@ namespace osu.Game.Rulesets.Objects.Legacy [Flags] internal enum ConvertHitObjectType { - Circle = 1 << 0, + Circle = 1, Slider = 1 << 1, NewCombo = 1 << 2, Spinner = 1 << 3, From ca33efead43eafe29d0fbc0861e4918cae261f68 Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Fri, 9 Aug 2019 03:58:06 +0000 Subject: [PATCH 34/49] Bump ppy.osu.Game.Resources from 2019.702.0 to 2019.731.1 Bumps [ppy.osu.Game.Resources](https://github.com/ppy/osu-resources) from 2019.702.0 to 2019.731.1. - [Release notes](https://github.com/ppy/osu-resources/releases) - [Commits](https://github.com/ppy/osu-resources/compare/2019.702.0...2019.731.1) Signed-off-by: dependabot-preview[bot] --- osu.Android.props | 2 +- osu.Game/osu.Game.csproj | 2 +- osu.iOS.props | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/osu.Android.props b/osu.Android.props index c4cdffa8a5..40c15a1162 100644 --- a/osu.Android.props +++ b/osu.Android.props @@ -62,7 +62,7 @@ - + diff --git a/osu.Game/osu.Game.csproj b/osu.Game/osu.Game.csproj index 02bf053468..8ee325c2ac 100644 --- a/osu.Game/osu.Game.csproj +++ b/osu.Game/osu.Game.csproj @@ -14,7 +14,7 @@ - + diff --git a/osu.iOS.props b/osu.iOS.props index 5b43a6f46f..b46438f766 100644 --- a/osu.iOS.props +++ b/osu.iOS.props @@ -104,7 +104,7 @@ - + From 58e98e53d276c96eb362f75b84cb9579bb3d4cb0 Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Fri, 9 Aug 2019 03:58:06 +0000 Subject: [PATCH 35/49] Bump NUnit3TestAdapter from 3.13.0 to 3.14.0 Bumps [NUnit3TestAdapter](https://github.com/nunit/nunit3-vs-adapter) from 3.13.0 to 3.14.0. - [Release notes](https://github.com/nunit/nunit3-vs-adapter/releases) - [Commits](https://github.com/nunit/nunit3-vs-adapter/compare/V3.13...V3.14) Signed-off-by: dependabot-preview[bot] --- .../osu.Game.Rulesets.Catch.Tests.csproj | 2 +- .../osu.Game.Rulesets.Mania.Tests.csproj | 2 +- osu.Game.Rulesets.Osu.Tests/osu.Game.Rulesets.Osu.Tests.csproj | 2 +- .../osu.Game.Rulesets.Taiko.Tests.csproj | 2 +- osu.Game.Tests/osu.Game.Tests.csproj | 2 +- osu.Game.Tournament.Tests/osu.Game.Tournament.Tests.csproj | 2 +- 6 files changed, 6 insertions(+), 6 deletions(-) diff --git a/osu.Game.Rulesets.Catch.Tests/osu.Game.Rulesets.Catch.Tests.csproj b/osu.Game.Rulesets.Catch.Tests/osu.Game.Rulesets.Catch.Tests.csproj index 9acf47a67c..4100404da6 100644 --- a/osu.Game.Rulesets.Catch.Tests/osu.Game.Rulesets.Catch.Tests.csproj +++ b/osu.Game.Rulesets.Catch.Tests/osu.Game.Rulesets.Catch.Tests.csproj @@ -4,7 +4,7 @@ - + diff --git a/osu.Game.Rulesets.Mania.Tests/osu.Game.Rulesets.Mania.Tests.csproj b/osu.Game.Rulesets.Mania.Tests/osu.Game.Rulesets.Mania.Tests.csproj index df5131dd8b..013d2a71d4 100644 --- a/osu.Game.Rulesets.Mania.Tests/osu.Game.Rulesets.Mania.Tests.csproj +++ b/osu.Game.Rulesets.Mania.Tests/osu.Game.Rulesets.Mania.Tests.csproj @@ -4,7 +4,7 @@ - + diff --git a/osu.Game.Rulesets.Osu.Tests/osu.Game.Rulesets.Osu.Tests.csproj b/osu.Game.Rulesets.Osu.Tests/osu.Game.Rulesets.Osu.Tests.csproj index bb3e5a66f3..92c5c77aac 100644 --- a/osu.Game.Rulesets.Osu.Tests/osu.Game.Rulesets.Osu.Tests.csproj +++ b/osu.Game.Rulesets.Osu.Tests/osu.Game.Rulesets.Osu.Tests.csproj @@ -4,7 +4,7 @@ - + diff --git a/osu.Game.Rulesets.Taiko.Tests/osu.Game.Rulesets.Taiko.Tests.csproj b/osu.Game.Rulesets.Taiko.Tests/osu.Game.Rulesets.Taiko.Tests.csproj index 5510c3a9d9..82055ecaee 100644 --- a/osu.Game.Rulesets.Taiko.Tests/osu.Game.Rulesets.Taiko.Tests.csproj +++ b/osu.Game.Rulesets.Taiko.Tests/osu.Game.Rulesets.Taiko.Tests.csproj @@ -4,7 +4,7 @@ - + diff --git a/osu.Game.Tests/osu.Game.Tests.csproj b/osu.Game.Tests/osu.Game.Tests.csproj index 659f5415c3..50530088c2 100644 --- a/osu.Game.Tests/osu.Game.Tests.csproj +++ b/osu.Game.Tests/osu.Game.Tests.csproj @@ -5,7 +5,7 @@ - + diff --git a/osu.Game.Tournament.Tests/osu.Game.Tournament.Tests.csproj b/osu.Game.Tournament.Tests/osu.Game.Tournament.Tests.csproj index dad2fe0877..257db89a20 100644 --- a/osu.Game.Tournament.Tests/osu.Game.Tournament.Tests.csproj +++ b/osu.Game.Tournament.Tests/osu.Game.Tournament.Tests.csproj @@ -7,7 +7,7 @@ - + WinExe From 90b1fe81f3ffa99167bfa20af7b87ba3c60c8ca9 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 9 Aug 2019 19:12:29 +0900 Subject: [PATCH 36/49] Update cached usage in line with framework changes --- osu.Game.Rulesets.Mania/Objects/Drawables/Pieces/BodyPiece.cs | 2 +- osu.Game.Rulesets.Osu/Objects/Slider.cs | 2 +- osu.Game.Tournament/Screens/Ladder/LadderScreen.cs | 2 +- osu.Game/Graphics/Backgrounds/Triangles.cs | 4 ++-- osu.Game/Graphics/UserInterface/LineGraph.cs | 2 +- osu.Game/Rulesets/UI/Scrolling/ScrollingHitObjectContainer.cs | 2 +- osu.Game/Screens/Play/SquareGraph.cs | 2 +- osu.Game/Screens/Select/BeatmapCarousel.cs | 4 ++-- osu.Game/Storyboards/CommandTimeline.cs | 4 ++-- 9 files changed, 12 insertions(+), 12 deletions(-) diff --git a/osu.Game.Rulesets.Mania/Objects/Drawables/Pieces/BodyPiece.cs b/osu.Game.Rulesets.Mania/Objects/Drawables/Pieces/BodyPiece.cs index 8102718edf..a92e56d3c3 100644 --- a/osu.Game.Rulesets.Mania/Objects/Drawables/Pieces/BodyPiece.cs +++ b/osu.Game.Rulesets.Mania/Objects/Drawables/Pieces/BodyPiece.cs @@ -100,7 +100,7 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables.Pieces } } - private Cached subtractionCache = new Cached(); + private readonly Cached subtractionCache = new Cached(); public override bool Invalidate(Invalidation invalidation = Invalidation.All, Drawable source = null, bool shallPropagate = true) { diff --git a/osu.Game.Rulesets.Osu/Objects/Slider.cs b/osu.Game.Rulesets.Osu/Objects/Slider.cs index a4638c31f2..d3279652c7 100644 --- a/osu.Game.Rulesets.Osu/Objects/Slider.cs +++ b/osu.Game.Rulesets.Osu/Objects/Slider.cs @@ -26,7 +26,7 @@ namespace osu.Game.Rulesets.Osu.Objects public double EndTime => StartTime + this.SpanCount() * Path.Distance / Velocity; public double Duration => EndTime - StartTime; - private Cached endPositionCache; + private readonly Cached endPositionCache = new Cached(); public override Vector2 EndPosition => endPositionCache.IsValid ? endPositionCache.Value : endPositionCache.Value = Position + this.CurvePositionAt(1); diff --git a/osu.Game.Tournament/Screens/Ladder/LadderScreen.cs b/osu.Game.Tournament/Screens/Ladder/LadderScreen.cs index 67531ce5d3..83a41a662f 100644 --- a/osu.Game.Tournament/Screens/Ladder/LadderScreen.cs +++ b/osu.Game.Tournament/Screens/Ladder/LadderScreen.cs @@ -88,7 +88,7 @@ namespace osu.Game.Tournament.Screens.Ladder }; } - private Cached layout = new Cached(); + private readonly Cached layout = new Cached(); protected override void Update() { diff --git a/osu.Game/Graphics/Backgrounds/Triangles.cs b/osu.Game/Graphics/Backgrounds/Triangles.cs index 2b68e8530d..dffa0c4fd5 100644 --- a/osu.Game/Graphics/Backgrounds/Triangles.cs +++ b/osu.Game/Graphics/Backgrounds/Triangles.cs @@ -191,7 +191,7 @@ namespace osu.Game.Graphics.Backgrounds private readonly List parts = new List(); private Vector2 size; - private TriangleBatch vertexBatch; + private QuadBatch vertexBatch; public TrianglesDrawNode(Triangles source) : base(source) @@ -217,7 +217,7 @@ namespace osu.Game.Graphics.Backgrounds if (Source.AimCount > 0 && (vertexBatch == null || vertexBatch.Size != Source.AimCount)) { vertexBatch?.Dispose(); - vertexBatch = new TriangleBatch(Source.AimCount, 1); + vertexBatch = new QuadBatch(Source.AimCount, 1); } shader.Bind(); diff --git a/osu.Game/Graphics/UserInterface/LineGraph.cs b/osu.Game/Graphics/UserInterface/LineGraph.cs index 714e953816..6d65b77cbf 100644 --- a/osu.Game/Graphics/UserInterface/LineGraph.cs +++ b/osu.Game/Graphics/UserInterface/LineGraph.cs @@ -93,7 +93,7 @@ namespace osu.Game.Graphics.UserInterface return base.Invalidate(invalidation, source, shallPropagate); } - private Cached pathCached = new Cached(); + private readonly Cached pathCached = new Cached(); protected override void Update() { diff --git a/osu.Game/Rulesets/UI/Scrolling/ScrollingHitObjectContainer.cs b/osu.Game/Rulesets/UI/Scrolling/ScrollingHitObjectContainer.cs index 069e2d1a0b..19247d8a37 100644 --- a/osu.Game/Rulesets/UI/Scrolling/ScrollingHitObjectContainer.cs +++ b/osu.Game/Rulesets/UI/Scrolling/ScrollingHitObjectContainer.cs @@ -19,7 +19,7 @@ namespace osu.Game.Rulesets.UI.Scrolling [Resolved] private IScrollingInfo scrollingInfo { get; set; } - private Cached initialStateCache = new Cached(); + private readonly Cached initialStateCache = new Cached(); public ScrollingHitObjectContainer() { diff --git a/osu.Game/Screens/Play/SquareGraph.cs b/osu.Game/Screens/Play/SquareGraph.cs index 5b7a9574b6..9c56725c4e 100644 --- a/osu.Game/Screens/Play/SquareGraph.cs +++ b/osu.Game/Screens/Play/SquareGraph.cs @@ -75,7 +75,7 @@ namespace osu.Game.Screens.Play return base.Invalidate(invalidation, source, shallPropagate); } - private Cached layout = new Cached(); + private readonly Cached layout = new Cached(); private ScheduledDelegate scheduledCreate; protected override void Update() diff --git a/osu.Game/Screens/Select/BeatmapCarousel.cs b/osu.Game/Screens/Select/BeatmapCarousel.cs index cf88b697d9..7366fa8c17 100644 --- a/osu.Game/Screens/Select/BeatmapCarousel.cs +++ b/osu.Game/Screens/Select/BeatmapCarousel.cs @@ -93,8 +93,8 @@ namespace osu.Game.Screens.Select } private readonly List yPositions = new List(); - private Cached itemsCache = new Cached(); - private Cached scrollPositionCache = new Cached(); + private readonly Cached itemsCache = new Cached(); + private readonly Cached scrollPositionCache = new Cached(); private readonly Container scrollableContent; diff --git a/osu.Game/Storyboards/CommandTimeline.cs b/osu.Game/Storyboards/CommandTimeline.cs index aa1f137cf3..bcf642b4ea 100644 --- a/osu.Game/Storyboards/CommandTimeline.cs +++ b/osu.Game/Storyboards/CommandTimeline.cs @@ -15,10 +15,10 @@ namespace osu.Game.Storyboards public IEnumerable Commands => commands.OrderBy(c => c.StartTime); public bool HasCommands => commands.Count > 0; - private Cached startTimeBacking; + private readonly Cached startTimeBacking = new Cached(); public double StartTime => startTimeBacking.IsValid ? startTimeBacking : startTimeBacking.Value = HasCommands ? commands.Min(c => c.StartTime) : double.MinValue; - private Cached endTimeBacking; + private readonly Cached endTimeBacking = new Cached(); public double EndTime => endTimeBacking.IsValid ? endTimeBacking : endTimeBacking.Value = HasCommands ? commands.Max(c => c.EndTime) : double.MaxValue; public T StartValue => HasCommands ? commands.OrderBy(c => c.StartTime).First().StartValue : default; From 6264a6a1c95b9b3c924e2ace2b4f8ff0594862f3 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 9 Aug 2019 20:18:02 +0900 Subject: [PATCH 37/49] Adjust slider snaking and hitcircle fading to match stable --- .../Objects/Drawables/Pieces/SnakingSliderBody.cs | 2 +- osu.Game.Rulesets.Osu/Objects/OsuHitObject.cs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/SnakingSliderBody.cs b/osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/SnakingSliderBody.cs index 0590ca1d96..70a1bad4a3 100644 --- a/osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/SnakingSliderBody.cs +++ b/osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/SnakingSliderBody.cs @@ -69,7 +69,7 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables.Pieces var spanProgress = slider.ProgressAt(completionProgress); double start = 0; - double end = SnakingIn.Value ? MathHelper.Clamp((Time.Current - (slider.StartTime - slider.TimePreempt)) / slider.TimeFadeIn, 0, 1) : 1; + double end = SnakingIn.Value ? MathHelper.Clamp((Time.Current - (slider.StartTime - slider.TimePreempt)) / (slider.TimePreempt / 3), 0, 1) : 1; if (span >= slider.SpanCount() - 1) { diff --git a/osu.Game.Rulesets.Osu/Objects/OsuHitObject.cs b/osu.Game.Rulesets.Osu/Objects/OsuHitObject.cs index d1221fd2d3..b52bfcd181 100644 --- a/osu.Game.Rulesets.Osu/Objects/OsuHitObject.cs +++ b/osu.Game.Rulesets.Osu/Objects/OsuHitObject.cs @@ -69,7 +69,7 @@ namespace osu.Game.Rulesets.Osu.Objects base.ApplyDefaultsToSelf(controlPointInfo, difficulty); TimePreempt = (float)BeatmapDifficulty.DifficultyRange(difficulty.ApproachRate, 1800, 1200, 450); - TimeFadeIn = (float)BeatmapDifficulty.DifficultyRange(difficulty.ApproachRate, 1200, 800, 300); + TimeFadeIn = 400; // as per osu-stable Scale = (1.0f - 0.7f * (difficulty.CircleSize - 5) / 5) / 2; } From caf13ae52ddbf06fbf11fe3c711e1fb304f8915f Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 9 Aug 2019 23:29:32 +0900 Subject: [PATCH 38/49] Update framework --- osu.Android.props | 2 +- osu.Game/osu.Game.csproj | 2 +- osu.iOS.props | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/osu.Android.props b/osu.Android.props index 40c15a1162..3b2e6574ac 100644 --- a/osu.Android.props +++ b/osu.Android.props @@ -63,6 +63,6 @@ - + diff --git a/osu.Game/osu.Game.csproj b/osu.Game/osu.Game.csproj index 8ee325c2ac..1dd19ac7ed 100644 --- a/osu.Game/osu.Game.csproj +++ b/osu.Game/osu.Game.csproj @@ -15,7 +15,7 @@ - + diff --git a/osu.iOS.props b/osu.iOS.props index b46438f766..1c3faeed39 100644 --- a/osu.iOS.props +++ b/osu.iOS.props @@ -105,8 +105,8 @@ - - + + From b0a71779877c55e6b181e8e50207de80ff79e96a Mon Sep 17 00:00:00 2001 From: Lucas A Date: Sat, 10 Aug 2019 13:26:19 +0200 Subject: [PATCH 39/49] Add ScreenTitleIcon class, used for displaying custom specific icons on overlays. --- .../Graphics/UserInterface/ScreenTitle.cs | 2 +- .../Graphics/UserInterface/ScreenTitleIcon.cs | 61 +++++++++++++++++++ .../Overlays/Changelog/ChangelogHeader.cs | 45 +------------- 3 files changed, 63 insertions(+), 45 deletions(-) create mode 100644 osu.Game/Graphics/UserInterface/ScreenTitleIcon.cs diff --git a/osu.Game/Graphics/UserInterface/ScreenTitle.cs b/osu.Game/Graphics/UserInterface/ScreenTitle.cs index 7b39238e5e..10fc312d8b 100644 --- a/osu.Game/Graphics/UserInterface/ScreenTitle.cs +++ b/osu.Game/Graphics/UserInterface/ScreenTitle.cs @@ -15,7 +15,7 @@ namespace osu.Game.Graphics.UserInterface { public const float ICON_WIDTH = ICON_SIZE + icon_spacing; - protected const float ICON_SIZE = 25; + public const float ICON_SIZE = 25; private SpriteIcon iconSprite; private readonly OsuSpriteText titleText, pageText; diff --git a/osu.Game/Graphics/UserInterface/ScreenTitleIcon.cs b/osu.Game/Graphics/UserInterface/ScreenTitleIcon.cs new file mode 100644 index 0000000000..12e0617e35 --- /dev/null +++ b/osu.Game/Graphics/UserInterface/ScreenTitleIcon.cs @@ -0,0 +1,61 @@ +using osu.Framework.Allocation; +using osu.Framework.Graphics; +using osu.Framework.Graphics.Containers; +using osu.Framework.Graphics.Shapes; +using osu.Framework.Graphics.Sprites; +using osu.Framework.Graphics.Textures; +using osuTK; + +namespace osu.Game.Graphics.UserInterface +{ + /// + /// A custom icon class for use with + /// + public class ScreenTitleIcon : CompositeDrawable + { + private const float circle_allowance = 0.8f; + + private string icon; + + public ScreenTitleIcon(string icon) + { + this.icon = icon; + } + + [BackgroundDependencyLoader] + private void load(TextureStore textures, OsuColour colours) + { + Size = new Vector2(ScreenTitle.ICON_SIZE / circle_allowance); + + InternalChildren = new Drawable[] + { + new CircularContainer + { + Masking = true, + BorderColour = colours.Violet, + BorderThickness = 3, + MaskingSmoothness = 1, + RelativeSizeAxes = Axes.Both, + Children = new Drawable[] + { + new Sprite + { + RelativeSizeAxes = Axes.Both, + Texture = textures.Get(icon), + Size = new Vector2(circle_allowance), + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + }, + new Box + { + RelativeSizeAxes = Axes.Both, + Colour = colours.Violet, + Alpha = 0, + AlwaysPresent = true, + }, + } + }, + }; + } + } +} diff --git a/osu.Game/Overlays/Changelog/ChangelogHeader.cs b/osu.Game/Overlays/Changelog/ChangelogHeader.cs index fca62fbb44..8b78216136 100644 --- a/osu.Game/Overlays/Changelog/ChangelogHeader.cs +++ b/osu.Game/Overlays/Changelog/ChangelogHeader.cs @@ -7,13 +7,11 @@ using osu.Framework.Allocation; using osu.Framework.Bindables; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; -using osu.Framework.Graphics.Shapes; using osu.Framework.Graphics.Sprites; using osu.Framework.Graphics.Textures; using osu.Game.Graphics; using osu.Game.Graphics.UserInterface; using osu.Game.Online.API.Requests.Responses; -using osuTK; namespace osu.Game.Overlays.Changelog { @@ -123,48 +121,7 @@ namespace osu.Game.Overlays.Changelog AccentColour = colours.Violet; } - protected override Drawable CreateIcon() => new ChangelogIcon(); - - internal class ChangelogIcon : CompositeDrawable - { - private const float circle_allowance = 0.8f; - - [BackgroundDependencyLoader] - private void load(TextureStore textures, OsuColour colours) - { - Size = new Vector2(ICON_SIZE / circle_allowance); - - InternalChildren = new Drawable[] - { - new CircularContainer - { - Masking = true, - BorderColour = colours.Violet, - BorderThickness = 3, - MaskingSmoothness = 1, - RelativeSizeAxes = Axes.Both, - Children = new Drawable[] - { - new Sprite - { - RelativeSizeAxes = Axes.Both, - Texture = textures.Get(@"Icons/changelog"), - Size = new Vector2(circle_allowance), - Anchor = Anchor.Centre, - Origin = Anchor.Centre, - }, - new Box - { - RelativeSizeAxes = Axes.Both, - Colour = colours.Violet, - Alpha = 0, - AlwaysPresent = true, - }, - } - }, - }; - } - } + protected override Drawable CreateIcon() => new ScreenTitleIcon(@"Icons/changelog"); } } } From 8eb3409a648bb03ff702d2f66807e6c0e0c02c86 Mon Sep 17 00:00:00 2001 From: Lucas A Date: Sat, 10 Aug 2019 14:03:44 +0200 Subject: [PATCH 40/49] Add missing licence header --- osu.Game/Graphics/UserInterface/ScreenTitleIcon.cs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/osu.Game/Graphics/UserInterface/ScreenTitleIcon.cs b/osu.Game/Graphics/UserInterface/ScreenTitleIcon.cs index 12e0617e35..8a42645b37 100644 --- a/osu.Game/Graphics/UserInterface/ScreenTitleIcon.cs +++ b/osu.Game/Graphics/UserInterface/ScreenTitleIcon.cs @@ -1,4 +1,7 @@ -using osu.Framework.Allocation; +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + +using osu.Framework.Allocation; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Shapes; From d55f9404dab5cd639d8f3524df9e97c31bf909f3 Mon Sep 17 00:00:00 2001 From: Lucas A Date: Sat, 10 Aug 2019 14:23:37 +0200 Subject: [PATCH 41/49] Fix CI issues --- osu.Game/Graphics/UserInterface/ScreenTitleIcon.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Graphics/UserInterface/ScreenTitleIcon.cs b/osu.Game/Graphics/UserInterface/ScreenTitleIcon.cs index 8a42645b37..4ce554009a 100644 --- a/osu.Game/Graphics/UserInterface/ScreenTitleIcon.cs +++ b/osu.Game/Graphics/UserInterface/ScreenTitleIcon.cs @@ -18,7 +18,7 @@ namespace osu.Game.Graphics.UserInterface { private const float circle_allowance = 0.8f; - private string icon; + private readonly string icon; public ScreenTitleIcon(string icon) { From 684c37bf05e8bc3367d5c48d4997a7e1bab75157 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Sun, 11 Aug 2019 16:15:44 +0900 Subject: [PATCH 42/49] Rename class to better match usage --- ...{ScreenTitleIcon.cs => ScreenTitleTextureIcon.cs} | 12 ++++++------ osu.Game/Overlays/Changelog/ChangelogHeader.cs | 2 +- 2 files changed, 7 insertions(+), 7 deletions(-) rename osu.Game/Graphics/UserInterface/{ScreenTitleIcon.cs => ScreenTitleTextureIcon.cs} (85%) diff --git a/osu.Game/Graphics/UserInterface/ScreenTitleIcon.cs b/osu.Game/Graphics/UserInterface/ScreenTitleTextureIcon.cs similarity index 85% rename from osu.Game/Graphics/UserInterface/ScreenTitleIcon.cs rename to osu.Game/Graphics/UserInterface/ScreenTitleTextureIcon.cs index 4ce554009a..f590e7e357 100644 --- a/osu.Game/Graphics/UserInterface/ScreenTitleIcon.cs +++ b/osu.Game/Graphics/UserInterface/ScreenTitleTextureIcon.cs @@ -12,17 +12,17 @@ using osuTK; namespace osu.Game.Graphics.UserInterface { /// - /// A custom icon class for use with + /// A custom icon class for use with based off a texture resource. /// - public class ScreenTitleIcon : CompositeDrawable + public class ScreenTitleTextureIcon : CompositeDrawable { private const float circle_allowance = 0.8f; - private readonly string icon; + private readonly string textureName; - public ScreenTitleIcon(string icon) + public ScreenTitleTextureIcon(string textureName) { - this.icon = icon; + this.textureName = textureName; } [BackgroundDependencyLoader] @@ -44,7 +44,7 @@ namespace osu.Game.Graphics.UserInterface new Sprite { RelativeSizeAxes = Axes.Both, - Texture = textures.Get(icon), + Texture = textures.Get(textureName), Size = new Vector2(circle_allowance), Anchor = Anchor.Centre, Origin = Anchor.Centre, diff --git a/osu.Game/Overlays/Changelog/ChangelogHeader.cs b/osu.Game/Overlays/Changelog/ChangelogHeader.cs index 8b78216136..b2e9be24b3 100644 --- a/osu.Game/Overlays/Changelog/ChangelogHeader.cs +++ b/osu.Game/Overlays/Changelog/ChangelogHeader.cs @@ -121,7 +121,7 @@ namespace osu.Game.Overlays.Changelog AccentColour = colours.Violet; } - protected override Drawable CreateIcon() => new ScreenTitleIcon(@"Icons/changelog"); + protected override Drawable CreateIcon() => new ScreenTitleTextureIcon(@"Icons/changelog"); } } } From cc4ee2df0591301b420675255a28e0612862654f Mon Sep 17 00:00:00 2001 From: Unknown Date: Sun, 11 Aug 2019 16:41:56 +0200 Subject: [PATCH 43/49] add ToString() override to Beatmap class --- osu.Game/Beatmaps/Beatmap.cs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/osu.Game/Beatmaps/Beatmap.cs b/osu.Game/Beatmaps/Beatmap.cs index 4ebeee40bf..6079a112e6 100644 --- a/osu.Game/Beatmaps/Beatmap.cs +++ b/osu.Game/Beatmaps/Beatmap.cs @@ -60,5 +60,7 @@ namespace osu.Game.Beatmaps public class Beatmap : Beatmap { public new Beatmap Clone() => (Beatmap)base.Clone(); + + public override string ToString() => BeatmapInfo?.ToString(); } } From ce62f6b56e76e13f7ca17891d37453514e3eb3e0 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 12 Aug 2019 01:40:11 +0900 Subject: [PATCH 44/49] ToString should never return null --- osu.Game/Beatmaps/Beatmap.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Beatmaps/Beatmap.cs b/osu.Game/Beatmaps/Beatmap.cs index 6079a112e6..a09a1bb9cb 100644 --- a/osu.Game/Beatmaps/Beatmap.cs +++ b/osu.Game/Beatmaps/Beatmap.cs @@ -61,6 +61,6 @@ namespace osu.Game.Beatmaps { public new Beatmap Clone() => (Beatmap)base.Clone(); - public override string ToString() => BeatmapInfo?.ToString(); + public override string ToString() => BeatmapInfo?.ToString() ?? base.ToString(); } } From ff4b271f64c508227f8d70c4301046afad16f2e4 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 12 Aug 2019 01:42:05 +0900 Subject: [PATCH 45/49] Add extra quotations around output --- osu.Game/Beatmaps/Formats/LegacyDecoder.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/osu.Game/Beatmaps/Formats/LegacyDecoder.cs b/osu.Game/Beatmaps/Formats/LegacyDecoder.cs index d6d6804d16..9a8197ad82 100644 --- a/osu.Game/Beatmaps/Formats/LegacyDecoder.cs +++ b/osu.Game/Beatmaps/Formats/LegacyDecoder.cs @@ -36,7 +36,7 @@ namespace osu.Game.Beatmaps.Formats { if (!Enum.TryParse(line.Substring(1, line.Length - 2), out section)) { - Logger.Log($"Unknown section \"{line}\" in {output}"); + Logger.Log($"Unknown section \"{line}\" in \"{output}\""); section = Section.None; } @@ -49,7 +49,7 @@ namespace osu.Game.Beatmaps.Formats } catch (Exception e) { - Logger.Log($"Failed to process line \"{line}\" into {output}: {e.Message}", LoggingTarget.Runtime, LogLevel.Important); + Logger.Log($"Failed to process line \"{line}\" into \"{output}\": {e.Message}", LoggingTarget.Runtime, LogLevel.Important); } } } From bc32726f3caee2c95c3111095f4b089e0326fc64 Mon Sep 17 00:00:00 2001 From: Salman Ahmed Date: Sun, 11 Aug 2019 23:08:14 +0300 Subject: [PATCH 46/49] Apply renaming suggestions Co-Authored-By: Dean Herbert --- osu.Game.Tests/Visual/Background/TestSceneUserDimContainer.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/osu.Game.Tests/Visual/Background/TestSceneUserDimContainer.cs b/osu.Game.Tests/Visual/Background/TestSceneUserDimContainer.cs index bffee7f1f7..813ca904ca 100644 --- a/osu.Game.Tests/Visual/Background/TestSceneUserDimContainer.cs +++ b/osu.Game.Tests/Visual/Background/TestSceneUserDimContainer.cs @@ -149,7 +149,7 @@ namespace osu.Game.Tests.Visual.Background } /// - /// Check if the is properly accepting user-defined visual changes in background at all. + /// Ensure is properly accepting user-defined visual changes for a background. /// [Test] public void DisableUserDimBackgroundTest() @@ -166,7 +166,7 @@ namespace osu.Game.Tests.Visual.Background } /// - /// Check if the is properly accepting user-defined visual changes in storyboard at all. + /// Ensure is properly accepting user-defined visual changes for a storyboard. /// [Test] public void DisableUserDimStoryboardTest() From fe20e1924352fcfea0918e14f55b0c43b6038ffd Mon Sep 17 00:00:00 2001 From: iiSaLMaN Date: Sun, 11 Aug 2019 23:19:22 +0300 Subject: [PATCH 47/49] Rename toggling steps --- .../Visual/Background/TestSceneUserDimContainer.cs | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/osu.Game.Tests/Visual/Background/TestSceneUserDimContainer.cs b/osu.Game.Tests/Visual/Background/TestSceneUserDimContainer.cs index 813ca904ca..3061a3a542 100644 --- a/osu.Game.Tests/Visual/Background/TestSceneUserDimContainer.cs +++ b/osu.Game.Tests/Visual/Background/TestSceneUserDimContainer.cs @@ -119,14 +119,14 @@ namespace osu.Game.Tests.Visual.Background { performFullSetup(); createFakeStoryboard(); - AddStep("Storyboard Enabled", () => + AddStep("Enable Storyboard", () => { player.ReplacesBackground.Value = true; player.StoryboardEnabled.Value = true; }); waitForDim(); AddAssert("Background is invisible, storyboard is visible", () => songSelect.IsBackgroundInvisible() && player.IsStoryboardVisible); - AddStep("Storyboard Disabled", () => + AddStep("Disable Storyboard", () => { player.ReplacesBackground.Value = false; player.StoryboardEnabled.Value = false; @@ -157,10 +157,10 @@ namespace osu.Game.Tests.Visual.Background performFullSetup(); waitForDim(); AddAssert("Screen is dimmed and blur applied", () => songSelect.IsBackgroundDimmed() && songSelect.IsUserBlurApplied()); - AddStep("EnableUserDim disabled", () => songSelect.DimEnabled.Value = false); + AddStep("Enable user dim", () => songSelect.DimEnabled.Value = false); waitForDim(); AddAssert("Screen is undimmed and user blur removed", () => songSelect.IsBackgroundUndimmed() && songSelect.IsUserBlurDisabled()); - AddStep("EnableUserDim enabled", () => songSelect.DimEnabled.Value = true); + AddStep("Disable user dim", () => songSelect.DimEnabled.Value = true); waitForDim(); AddAssert("Screen is dimmed and blur applied", () => songSelect.IsBackgroundDimmed() && songSelect.IsUserBlurApplied()); } @@ -173,16 +173,16 @@ namespace osu.Game.Tests.Visual.Background { performFullSetup(); createFakeStoryboard(); - AddStep("Storyboard Enabled", () => + AddStep("Enable Storyboard", () => { player.ReplacesBackground.Value = true; player.StoryboardEnabled.Value = true; }); - AddStep("EnableUserDim enabled", () => player.DimmableStoryboard.EnableUserDim.Value = true); + AddStep("Enable user dim", () => player.DimmableStoryboard.EnableUserDim.Value = true); AddStep("Set dim level to 1", () => songSelect.DimLevel.Value = 1f); waitForDim(); AddAssert("Storyboard is invisible", () => !player.IsStoryboardVisible); - AddStep("EnableUserDim disabled", () => player.DimmableStoryboard.EnableUserDim.Value = false); + AddStep("Disable user dim", () => player.DimmableStoryboard.EnableUserDim.Value = false); waitForDim(); AddAssert("Storyboard is visible", () => player.IsStoryboardVisible); } From 45b4fc9201849483d0d08ec770c6c5b89d413d6a Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 12 Aug 2019 15:00:32 +0900 Subject: [PATCH 48/49] Add xmldoc --- osu.Game.Rulesets.Osu/OsuInputManager.cs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/osu.Game.Rulesets.Osu/OsuInputManager.cs b/osu.Game.Rulesets.Osu/OsuInputManager.cs index 58e275ba26..cdea7276f3 100644 --- a/osu.Game.Rulesets.Osu/OsuInputManager.cs +++ b/osu.Game.Rulesets.Osu/OsuInputManager.cs @@ -18,6 +18,10 @@ namespace osu.Game.Rulesets.Osu set => ((OsuKeyBindingContainer)KeyBindingContainer).AllowUserPresses = value; } + /// + /// Whether the user's cursor movement events should be accepted. + /// Can be used to block only movement while still accepting button input. + /// public bool AllowUserCursorMovement { get; set; } = true; protected override RulesetKeyBindingContainer CreateKeyBindingContainer(RulesetInfo ruleset, int variant, SimultaneousBindingMode unique) From 707911acac196e5c97ce6d6f5b95a0dbeb3dcdbc Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 12 Aug 2019 15:05:27 +0900 Subject: [PATCH 49/49] Tidy up code formatting / variable naming --- osu.Game.Rulesets.Osu/Mods/OsuModAutopilot.cs | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/osu.Game.Rulesets.Osu/Mods/OsuModAutopilot.cs b/osu.Game.Rulesets.Osu/Mods/OsuModAutopilot.cs index 1853b0228f..ca72f18e9c 100644 --- a/osu.Game.Rulesets.Osu/Mods/OsuModAutopilot.cs +++ b/osu.Game.Rulesets.Osu/Mods/OsuModAutopilot.cs @@ -29,19 +29,21 @@ namespace osu.Game.Rulesets.Osu.Mods private OsuInputManager inputManager; private List replayFrames; - private int frameIndex; + + private int currentFrame; public void Update(Playfield playfield) { - // If we are on the last replay frame, no need to do anything - if (frameIndex == replayFrames.Count - 1) return; + if (currentFrame == replayFrames.Count - 1) return; - // Check if we are closer to the next replay frame then the current one - if (Math.Abs(replayFrames[frameIndex].Time - playfield.Time.Current) >= Math.Abs(replayFrames[frameIndex + 1].Time - playfield.Time.Current)) + double time = playfield.Time.Current; + + // Very naive implementation of autopilot based on proximity to replay frames. + // TODO: this needs to be based on user interactions to better match stable (pausing until judgement is registered). + if (Math.Abs(replayFrames[currentFrame + 1].Time - time) <= Math.Abs(replayFrames[currentFrame].Time - time)) { - // If we are, move to the next frame, and update the mouse position - frameIndex++; - new MousePositionAbsoluteInput { Position = playfield.ToScreenSpace(replayFrames[frameIndex].Position) }.Apply(inputManager.CurrentState, inputManager); + currentFrame++; + new MousePositionAbsoluteInput { Position = playfield.ToScreenSpace(replayFrames[currentFrame].Position) }.Apply(inputManager.CurrentState, inputManager); } // TODO: Implement the functionality to automatically spin spinners