mirror of
https://github.com/ppy/osu
synced 2024-12-14 02:46:27 +00:00
Merge branch 'master' into multi-queueing-modes
This commit is contained in:
commit
4b498c7bd6
1
.idea/.idea.osu.iOS/.idea/.name
generated
Normal file
1
.idea/.idea.osu.iOS/.idea/.name
generated
Normal file
@ -0,0 +1 @@
|
||||
osu.iOS
|
8
.idea/.idea.osu.iOS/.idea/indexLayout.xml
generated
Normal file
8
.idea/.idea.osu.iOS/.idea/indexLayout.xml
generated
Normal file
@ -0,0 +1,8 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="UserContentModel">
|
||||
<attachedFolders />
|
||||
<explicitIncludes />
|
||||
<explicitExcludes />
|
||||
</component>
|
||||
</project>
|
6
.idea/.idea.osu.iOS/.idea/misc.xml
generated
Normal file
6
.idea/.idea.osu.iOS/.idea/misc.xml
generated
Normal file
@ -0,0 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="com.jetbrains.rider.android.RiderAndroidMiscFileCreationComponent">
|
||||
<option name="ENSURE_MISC_FILE_EXISTS" value="true" />
|
||||
</component>
|
||||
</project>
|
6
.idea/.idea.osu.iOS/.idea/projectSettingsUpdater.xml
generated
Normal file
6
.idea/.idea.osu.iOS/.idea/projectSettingsUpdater.xml
generated
Normal file
@ -0,0 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="RiderProjectSettingsUpdater">
|
||||
<option name="vcsConfiguration" value="2" />
|
||||
</component>
|
||||
</project>
|
6
.idea/.idea.osu.iOS/.idea/vcs.xml
generated
Normal file
6
.idea/.idea.osu.iOS/.idea/vcs.xml
generated
Normal file
@ -0,0 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="VcsDirectoryMappings">
|
||||
<mapping directory="$PROJECT_DIR$" vcs="Git" />
|
||||
</component>
|
||||
</project>
|
@ -12,7 +12,7 @@
|
||||
<PackageReference Include="Appveyor.TestLogger" Version="2.0.0" />
|
||||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.0.0" />
|
||||
<PackageReference Include="NUnit" Version="3.13.2" />
|
||||
<PackageReference Include="NUnit3TestAdapter" Version="4.0.0" />
|
||||
<PackageReference Include="NUnit3TestAdapter" Version="4.1.0" />
|
||||
<PackageReference Update="Microsoft.EntityFrameworkCore.Sqlite" Version="2.1.4" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
|
@ -20,7 +20,7 @@ namespace osu.Game.Rulesets.EmptyFreeform
|
||||
|
||||
protected override DifficultyAttributes CreateDifficultyAttributes(IBeatmap beatmap, Mod[] mods, Skill[] skills, double clockRate)
|
||||
{
|
||||
return new DifficultyAttributes(mods, skills, 0);
|
||||
return new DifficultyAttributes(mods, 0);
|
||||
}
|
||||
|
||||
protected override IEnumerable<DifficultyHitObject> CreateDifficultyHitObjects(IBeatmap beatmap, double clockRate) => Enumerable.Empty<DifficultyHitObject>();
|
||||
|
@ -12,7 +12,7 @@
|
||||
<PackageReference Include="Appveyor.TestLogger" Version="2.0.0" />
|
||||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.0.0" />
|
||||
<PackageReference Include="NUnit" Version="3.13.2" />
|
||||
<PackageReference Include="NUnit3TestAdapter" Version="4.0.0" />
|
||||
<PackageReference Include="NUnit3TestAdapter" Version="4.1.0" />
|
||||
<PackageReference Update="Microsoft.EntityFrameworkCore.Sqlite" Version="2.1.4" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
|
@ -20,7 +20,7 @@ namespace osu.Game.Rulesets.Pippidon
|
||||
|
||||
protected override DifficultyAttributes CreateDifficultyAttributes(IBeatmap beatmap, Mod[] mods, Skill[] skills, double clockRate)
|
||||
{
|
||||
return new DifficultyAttributes(mods, skills, 0);
|
||||
return new DifficultyAttributes(mods, 0);
|
||||
}
|
||||
|
||||
protected override IEnumerable<DifficultyHitObject> CreateDifficultyHitObjects(IBeatmap beatmap, double clockRate) => Enumerable.Empty<DifficultyHitObject>();
|
||||
|
@ -12,7 +12,7 @@
|
||||
<PackageReference Include="Appveyor.TestLogger" Version="2.0.0" />
|
||||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.0.0" />
|
||||
<PackageReference Include="NUnit" Version="3.13.2" />
|
||||
<PackageReference Include="NUnit3TestAdapter" Version="4.0.0" />
|
||||
<PackageReference Include="NUnit3TestAdapter" Version="4.1.0" />
|
||||
<PackageReference Update="Microsoft.EntityFrameworkCore.Sqlite" Version="2.1.4" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
|
@ -20,7 +20,7 @@ namespace osu.Game.Rulesets.EmptyScrolling
|
||||
|
||||
protected override DifficultyAttributes CreateDifficultyAttributes(IBeatmap beatmap, Mod[] mods, Skill[] skills, double clockRate)
|
||||
{
|
||||
return new DifficultyAttributes(mods, skills, 0);
|
||||
return new DifficultyAttributes(mods, 0);
|
||||
}
|
||||
|
||||
protected override IEnumerable<DifficultyHitObject> CreateDifficultyHitObjects(IBeatmap beatmap, double clockRate) => Enumerable.Empty<DifficultyHitObject>();
|
||||
|
@ -12,7 +12,7 @@
|
||||
<PackageReference Include="Appveyor.TestLogger" Version="2.0.0" />
|
||||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.0.0" />
|
||||
<PackageReference Include="NUnit" Version="3.13.2" />
|
||||
<PackageReference Include="NUnit3TestAdapter" Version="4.0.0" />
|
||||
<PackageReference Include="NUnit3TestAdapter" Version="4.1.0" />
|
||||
<PackageReference Update="Microsoft.EntityFrameworkCore.Sqlite" Version="2.1.4" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
|
@ -20,7 +20,7 @@ namespace osu.Game.Rulesets.Pippidon
|
||||
|
||||
protected override DifficultyAttributes CreateDifficultyAttributes(IBeatmap beatmap, Mod[] mods, Skill[] skills, double clockRate)
|
||||
{
|
||||
return new DifficultyAttributes(mods, skills, 0);
|
||||
return new DifficultyAttributes(mods, 0);
|
||||
}
|
||||
|
||||
protected override IEnumerable<DifficultyHitObject> CreateDifficultyHitObjects(IBeatmap beatmap, double clockRate) => Enumerable.Empty<DifficultyHitObject>();
|
||||
|
@ -52,10 +52,10 @@
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<PackageReference Include="ppy.osu.Game.Resources" Version="2021.1112.0" />
|
||||
<PackageReference Include="ppy.osu.Framework.Android" Version="2021.1118.0" />
|
||||
<PackageReference Include="ppy.osu.Framework.Android" Version="2021.1119.0" />
|
||||
</ItemGroup>
|
||||
<ItemGroup Label="Transitive Dependencies">
|
||||
<!-- Realm needs to be directly referenced in all Xamarin projects, as it will not pull in its transitive dependencies otherwise. -->
|
||||
<PackageReference Include="Realm" Version="10.6.0" />
|
||||
<PackageReference Include="Realm" Version="10.7.1" />
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
|
@ -9,7 +9,7 @@
|
||||
<ItemGroup>
|
||||
<PackageReference Include="BenchmarkDotNet" Version="0.13.1" />
|
||||
<PackageReference Include="nunit" Version="3.13.2" />
|
||||
<PackageReference Include="NUnit3TestAdapter" Version="4.0.0" />
|
||||
<PackageReference Include="NUnit3TestAdapter" Version="4.1.0" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
@ -1,6 +1,7 @@
|
||||
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
||||
// See the LICENCE file in the repository root for full licence text.
|
||||
|
||||
using osu.Framework.iOS;
|
||||
using UIKit;
|
||||
|
||||
namespace osu.Game.Rulesets.Catch.Tests.iOS
|
||||
@ -9,7 +10,7 @@ namespace osu.Game.Rulesets.Catch.Tests.iOS
|
||||
{
|
||||
public static void Main(string[] args)
|
||||
{
|
||||
UIApplication.Main(args, "GameUIApplication", "AppDelegate");
|
||||
UIApplication.Main(args, typeof(GameUIApplication), typeof(AppDelegate));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -4,7 +4,7 @@
|
||||
<PackageReference Include="Appveyor.TestLogger" Version="2.0.0" />
|
||||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.0.0" />
|
||||
<PackageReference Include="NUnit" Version="3.13.2" />
|
||||
<PackageReference Include="NUnit3TestAdapter" Version="4.0.0" />
|
||||
<PackageReference Include="NUnit3TestAdapter" Version="4.1.0" />
|
||||
<PackageReference Update="Microsoft.EntityFrameworkCore.Sqlite" Version="2.1.4" />
|
||||
</ItemGroup>
|
||||
<PropertyGroup Label="Project">
|
||||
|
@ -31,7 +31,7 @@ namespace osu.Game.Rulesets.Catch.Difficulty
|
||||
protected override DifficultyAttributes CreateDifficultyAttributes(IBeatmap beatmap, Mod[] mods, Skill[] skills, double clockRate)
|
||||
{
|
||||
if (beatmap.HitObjects.Count == 0)
|
||||
return new CatchDifficultyAttributes { Mods = mods, Skills = skills };
|
||||
return new CatchDifficultyAttributes { Mods = mods };
|
||||
|
||||
// this is the same as osu!, so there's potential to share the implementation... maybe
|
||||
double preempt = IBeatmapDifficultyInfo.DifficultyRange(beatmap.Difficulty.ApproachRate, 1800, 1200, 450) / clockRate;
|
||||
@ -42,7 +42,6 @@ namespace osu.Game.Rulesets.Catch.Difficulty
|
||||
Mods = mods,
|
||||
ApproachRate = preempt > 1200.0 ? -(preempt - 1800.0) / 120.0 : -(preempt - 1200.0) / 150.0 + 5.0,
|
||||
MaxCombo = beatmap.HitObjects.Count(h => h is Fruit) + beatmap.HitObjects.OfType<JuiceStream>().SelectMany(j => j.NestedHitObjects).Count(h => !(h is TinyDroplet)),
|
||||
Skills = skills
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -1,6 +1,7 @@
|
||||
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
||||
// See the LICENCE file in the repository root for full licence text.
|
||||
|
||||
using osu.Framework.iOS;
|
||||
using UIKit;
|
||||
|
||||
namespace osu.Game.Rulesets.Mania.Tests.iOS
|
||||
@ -9,7 +10,7 @@ namespace osu.Game.Rulesets.Mania.Tests.iOS
|
||||
{
|
||||
public static void Main(string[] args)
|
||||
{
|
||||
UIApplication.Main(args, "GameUIApplication", "AppDelegate");
|
||||
UIApplication.Main(args, typeof(GameUIApplication), typeof(AppDelegate));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -4,7 +4,7 @@
|
||||
<PackageReference Include="Appveyor.TestLogger" Version="2.0.0" />
|
||||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.0.0" />
|
||||
<PackageReference Include="NUnit" Version="3.13.2" />
|
||||
<PackageReference Include="NUnit3TestAdapter" Version="4.0.0" />
|
||||
<PackageReference Include="NUnit3TestAdapter" Version="4.1.0" />
|
||||
<PackageReference Update="Microsoft.EntityFrameworkCore.Sqlite" Version="2.1.4" />
|
||||
</ItemGroup>
|
||||
<PropertyGroup Label="Project">
|
||||
|
@ -39,7 +39,7 @@ namespace osu.Game.Rulesets.Mania.Difficulty
|
||||
protected override DifficultyAttributes CreateDifficultyAttributes(IBeatmap beatmap, Mod[] mods, Skill[] skills, double clockRate)
|
||||
{
|
||||
if (beatmap.HitObjects.Count == 0)
|
||||
return new ManiaDifficultyAttributes { Mods = mods, Skills = skills };
|
||||
return new ManiaDifficultyAttributes { Mods = mods };
|
||||
|
||||
HitWindows hitWindows = new ManiaHitWindows();
|
||||
hitWindows.SetDifficulty(beatmap.Difficulty.OverallDifficulty);
|
||||
@ -51,7 +51,6 @@ namespace osu.Game.Rulesets.Mania.Difficulty
|
||||
GreatHitWindow = Math.Ceiling(getHitWindow300(mods) / clockRate),
|
||||
ScoreMultiplier = getScoreMultiplier(mods),
|
||||
MaxCombo = beatmap.HitObjects.Sum(h => h is HoldNote ? 2 : 1),
|
||||
Skills = skills
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -1,6 +1,7 @@
|
||||
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
||||
// See the LICENCE file in the repository root for full licence text.
|
||||
|
||||
using osu.Framework.iOS;
|
||||
using UIKit;
|
||||
|
||||
namespace osu.Game.Rulesets.Osu.Tests.iOS
|
||||
@ -9,7 +10,7 @@ namespace osu.Game.Rulesets.Osu.Tests.iOS
|
||||
{
|
||||
public static void Main(string[] args)
|
||||
{
|
||||
UIApplication.Main(args, "GameUIApplication", "AppDelegate");
|
||||
UIApplication.Main(args, typeof(GameUIApplication), typeof(AppDelegate));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -5,7 +5,7 @@
|
||||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.0.0" />
|
||||
<PackageReference Include="Moq" Version="4.16.1" />
|
||||
<PackageReference Include="NUnit" Version="3.13.2" />
|
||||
<PackageReference Include="NUnit3TestAdapter" Version="4.0.0" />
|
||||
<PackageReference Include="NUnit3TestAdapter" Version="4.1.0" />
|
||||
<PackageReference Update="Microsoft.EntityFrameworkCore.Sqlite" Version="2.1.4" />
|
||||
</ItemGroup>
|
||||
<PropertyGroup Label="Project">
|
||||
|
@ -31,7 +31,7 @@ namespace osu.Game.Rulesets.Osu.Difficulty
|
||||
protected override DifficultyAttributes CreateDifficultyAttributes(IBeatmap beatmap, Mod[] mods, Skill[] skills, double clockRate)
|
||||
{
|
||||
if (beatmap.HitObjects.Count == 0)
|
||||
return new OsuDifficultyAttributes { Mods = mods, Skills = skills };
|
||||
return new OsuDifficultyAttributes { Mods = mods };
|
||||
|
||||
double aimRating = Math.Sqrt(skills[0].DifficultyValue()) * difficulty_multiplier;
|
||||
double aimRatingNoSliders = Math.Sqrt(skills[1].DifficultyValue()) * difficulty_multiplier;
|
||||
@ -85,7 +85,6 @@ namespace osu.Game.Rulesets.Osu.Difficulty
|
||||
HitCircleCount = hitCirclesCount,
|
||||
SliderCount = sliderCount,
|
||||
SpinnerCount = spinnerCount,
|
||||
Skills = skills
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -1,6 +1,7 @@
|
||||
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
||||
// See the LICENCE file in the repository root for full licence text.
|
||||
|
||||
using osu.Framework.iOS;
|
||||
using UIKit;
|
||||
|
||||
namespace osu.Game.Rulesets.Taiko.Tests.iOS
|
||||
@ -9,7 +10,7 @@ namespace osu.Game.Rulesets.Taiko.Tests.iOS
|
||||
{
|
||||
public static void Main(string[] args)
|
||||
{
|
||||
UIApplication.Main(args, "GameUIApplication", "AppDelegate");
|
||||
UIApplication.Main(args, typeof(GameUIApplication), typeof(AppDelegate));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -4,7 +4,7 @@
|
||||
<PackageReference Include="Appveyor.TestLogger" Version="2.0.0" />
|
||||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.0.0" />
|
||||
<PackageReference Include="NUnit" Version="3.13.2" />
|
||||
<PackageReference Include="NUnit3TestAdapter" Version="4.0.0" />
|
||||
<PackageReference Include="NUnit3TestAdapter" Version="4.1.0" />
|
||||
<PackageReference Update="Microsoft.EntityFrameworkCore.Sqlite" Version="2.1.4" />
|
||||
</ItemGroup>
|
||||
<PropertyGroup Label="Project">
|
||||
|
@ -65,7 +65,7 @@ namespace osu.Game.Rulesets.Taiko.Difficulty
|
||||
protected override DifficultyAttributes CreateDifficultyAttributes(IBeatmap beatmap, Mod[] mods, Skill[] skills, double clockRate)
|
||||
{
|
||||
if (beatmap.HitObjects.Count == 0)
|
||||
return new TaikoDifficultyAttributes { Mods = mods, Skills = skills };
|
||||
return new TaikoDifficultyAttributes { Mods = mods };
|
||||
|
||||
var colour = (Colour)skills[0];
|
||||
var rhythm = (Rhythm)skills[1];
|
||||
@ -96,7 +96,6 @@ namespace osu.Game.Rulesets.Taiko.Difficulty
|
||||
ColourStrain = colourRating,
|
||||
GreatHitWindow = hitWindows.WindowFor(HitResult.Great) / clockRate,
|
||||
MaxCombo = beatmap.HitObjects.Count(h => h is Hit),
|
||||
Skills = skills
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -1,6 +1,7 @@
|
||||
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
||||
// See the LICENCE file in the repository root for full licence text.
|
||||
|
||||
using osu.Framework.iOS;
|
||||
using UIKit;
|
||||
|
||||
namespace osu.Game.Tests.iOS
|
||||
@ -9,7 +10,7 @@ namespace osu.Game.Tests.iOS
|
||||
{
|
||||
public static void Main(string[] args)
|
||||
{
|
||||
UIApplication.Main(args, "GameUIApplication", "AppDelegate");
|
||||
UIApplication.Main(args, typeof(GameUIApplication), typeof(AppDelegate));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -16,6 +16,7 @@ using osu.Framework.Extensions.ObjectExtensions;
|
||||
using osu.Framework.Logging;
|
||||
using osu.Game.Beatmaps;
|
||||
using osu.Game.Database;
|
||||
using osu.Game.Extensions;
|
||||
using osu.Game.IO;
|
||||
using osu.Game.Online.API.Requests.Responses;
|
||||
using osu.Game.Overlays.Notifications;
|
||||
@ -363,15 +364,15 @@ namespace osu.Game.Tests.Beatmaps.IO
|
||||
var files = osu.Dependencies.Get<FileStore>();
|
||||
|
||||
long originalLength;
|
||||
using (var stream = files.Storage.GetStream(firstFile.FileInfo.StoragePath))
|
||||
using (var stream = files.Storage.GetStream(firstFile.FileInfo.GetStoragePath()))
|
||||
originalLength = stream.Length;
|
||||
|
||||
using (var stream = files.Storage.GetStream(firstFile.FileInfo.StoragePath, FileAccess.Write, FileMode.Create))
|
||||
using (var stream = files.Storage.GetStream(firstFile.FileInfo.GetStoragePath(), FileAccess.Write, FileMode.Create))
|
||||
stream.WriteByte(0);
|
||||
|
||||
var importedSecondTime = await LoadOszIntoOsu(osu);
|
||||
|
||||
using (var stream = files.Storage.GetStream(firstFile.FileInfo.StoragePath))
|
||||
using (var stream = files.Storage.GetStream(firstFile.FileInfo.GetStoragePath()))
|
||||
Assert.AreEqual(stream.Length, originalLength, "Corruption was not fixed on second import");
|
||||
|
||||
// check the newly "imported" beatmap is actually just the restored previous import. since it matches hash.
|
||||
|
@ -164,9 +164,9 @@ namespace osu.Game.Tests.Beatmaps
|
||||
{
|
||||
public Func<DifficultyCacheLookup, StarDifficulty> ComputeDifficulty { get; set; }
|
||||
|
||||
protected override Task<StarDifficulty> ComputeValueAsync(DifficultyCacheLookup lookup, CancellationToken token = default)
|
||||
protected override Task<StarDifficulty?> ComputeValueAsync(DifficultyCacheLookup lookup, CancellationToken token = default)
|
||||
{
|
||||
return Task.FromResult(ComputeDifficulty?.Invoke(lookup) ?? new StarDifficulty(BASE_STARS, 0));
|
||||
return Task.FromResult<StarDifficulty?>(ComputeDifficulty?.Invoke(lookup) ?? new StarDifficulty(BASE_STARS, 0));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -9,6 +9,7 @@ using Moq;
|
||||
using NUnit.Framework;
|
||||
using osu.Game.Beatmaps;
|
||||
using osu.Game.Rulesets;
|
||||
using osu.Game.Rulesets.Mods;
|
||||
using osu.Game.Rulesets.Objects;
|
||||
using osu.Game.Rulesets.Osu;
|
||||
using osu.Game.Rulesets.Osu.Beatmaps;
|
||||
@ -40,7 +41,7 @@ namespace osu.Game.Tests.Beatmaps
|
||||
Task.Factory.StartNew(() =>
|
||||
{
|
||||
loadStarted.Set();
|
||||
Assert.Throws<OperationCanceledException>(() => working.GetPlayableBeatmap(new OsuRuleset().RulesetInfo, cancellationToken: cts.Token));
|
||||
Assert.Throws<OperationCanceledException>(() => working.GetPlayableBeatmap(new OsuRuleset().RulesetInfo, Array.Empty<Mod>(), cts.Token));
|
||||
loadCompleted.Set();
|
||||
}, TaskCreationOptions.LongRunning);
|
||||
|
||||
@ -58,7 +59,7 @@ namespace osu.Game.Tests.Beatmaps
|
||||
{
|
||||
var working = new TestNeverLoadsWorkingBeatmap();
|
||||
|
||||
Assert.Throws<OperationCanceledException>(() => working.GetPlayableBeatmap(new OsuRuleset().RulesetInfo));
|
||||
Assert.Throws(Is.InstanceOf<TimeoutException>(), () => working.GetPlayableBeatmap(new OsuRuleset().RulesetInfo));
|
||||
|
||||
working.ResetEvent.Set();
|
||||
}
|
||||
|
@ -14,6 +14,7 @@ using osu.Framework.Extensions.ObjectExtensions;
|
||||
using osu.Framework.Logging;
|
||||
using osu.Game.Beatmaps;
|
||||
using osu.Game.Database;
|
||||
using osu.Game.Extensions;
|
||||
using osu.Game.IO.Archives;
|
||||
using osu.Game.Models;
|
||||
using osu.Game.Overlays.Notifications;
|
||||
@ -348,15 +349,15 @@ namespace osu.Game.Tests.Database
|
||||
var firstFile = imported.Files.First();
|
||||
|
||||
long originalLength;
|
||||
using (var stream = storage.GetStream(firstFile.File.StoragePath))
|
||||
using (var stream = storage.GetStream(firstFile.File.GetStoragePath()))
|
||||
originalLength = stream.Length;
|
||||
|
||||
using (var stream = storage.GetStream(firstFile.File.StoragePath, FileAccess.Write, FileMode.Create))
|
||||
using (var stream = storage.GetStream(firstFile.File.GetStoragePath(), FileAccess.Write, FileMode.Create))
|
||||
stream.WriteByte(0);
|
||||
|
||||
var importedSecondTime = await LoadOszIntoStore(importer, realmFactory.Context);
|
||||
|
||||
using (var stream = storage.GetStream(firstFile.File.StoragePath))
|
||||
using (var stream = storage.GetStream(firstFile.File.GetStoragePath()))
|
||||
Assert.AreEqual(stream.Length, originalLength, "Corruption was not fixed on second import");
|
||||
|
||||
// check the newly "imported" beatmap is actually just the restored previous import. since it matches hash.
|
||||
|
@ -6,6 +6,7 @@ using System.IO;
|
||||
using System.Linq;
|
||||
using NUnit.Framework;
|
||||
using osu.Framework.Logging;
|
||||
using osu.Game.Extensions;
|
||||
using osu.Game.Models;
|
||||
using osu.Game.Stores;
|
||||
|
||||
@ -28,7 +29,7 @@ namespace osu.Game.Tests.Database
|
||||
realm.Write(() => files.Add(testData, realm));
|
||||
|
||||
Assert.True(files.Storage.Exists("0/05/054edec1d0211f624fed0cbca9d4f9400b0e491c43742af2c5b0abebf0c990d8"));
|
||||
Assert.True(files.Storage.Exists(realm.All<RealmFile>().First().StoragePath));
|
||||
Assert.True(files.Storage.Exists(realm.All<RealmFile>().First().GetStoragePath()));
|
||||
});
|
||||
}
|
||||
|
||||
@ -74,7 +75,7 @@ namespace osu.Game.Tests.Database
|
||||
|
||||
Logger.Log($"Import complete at {timer.ElapsedMilliseconds}");
|
||||
|
||||
string path = file.StoragePath;
|
||||
string path = file.GetStoragePath();
|
||||
|
||||
Assert.True(realm.All<RealmFile>().Any());
|
||||
Assert.True(files.Storage.Exists(path));
|
||||
@ -98,7 +99,7 @@ namespace osu.Game.Tests.Database
|
||||
|
||||
var file = realm.Write(() => files.Add(new MemoryStream(new byte[] { 0, 1, 2, 3 }), realm));
|
||||
|
||||
string path = file.StoragePath;
|
||||
string path = file.GetStoragePath();
|
||||
|
||||
Assert.True(realm.All<RealmFile>().Any());
|
||||
Assert.True(files.Storage.Exists(path));
|
||||
|
@ -140,7 +140,7 @@ namespace osu.Game.Tests.Visual.SongSelect
|
||||
}
|
||||
}
|
||||
|
||||
public override async Task<StarDifficulty> GetDifficultyAsync(IBeatmapInfo beatmapInfo, IRulesetInfo rulesetInfo = null, IEnumerable<Mod> mods = null, CancellationToken cancellationToken = default)
|
||||
public override async Task<StarDifficulty?> GetDifficultyAsync(IBeatmapInfo beatmapInfo, IRulesetInfo rulesetInfo = null, IEnumerable<Mod> mods = null, CancellationToken cancellationToken = default)
|
||||
{
|
||||
if (blockCalculation)
|
||||
await calculationBlocker.Task.ConfigureAwait(false);
|
||||
|
@ -6,7 +6,7 @@
|
||||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.0.0" />
|
||||
<PackageReference Include="Nito.AsyncEx" Version="5.1.2" />
|
||||
<PackageReference Include="NUnit" Version="3.13.2" />
|
||||
<PackageReference Include="NUnit3TestAdapter" Version="4.0.0" />
|
||||
<PackageReference Include="NUnit3TestAdapter" Version="4.1.0" />
|
||||
<PackageReference Update="Microsoft.EntityFrameworkCore.Sqlite" Version="2.1.4" />
|
||||
<PackageReference Include="Moq" Version="4.16.1" />
|
||||
</ItemGroup>
|
||||
|
@ -7,7 +7,7 @@
|
||||
<PackageReference Include="Appveyor.TestLogger" Version="2.0.0" />
|
||||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.0.0" />
|
||||
<PackageReference Include="NUnit" Version="3.13.2" />
|
||||
<PackageReference Include="NUnit3TestAdapter" Version="4.0.0" />
|
||||
<PackageReference Include="NUnit3TestAdapter" Version="4.1.0" />
|
||||
</ItemGroup>
|
||||
<PropertyGroup Label="Project">
|
||||
<OutputType>WinExe</OutputType>
|
||||
|
@ -27,7 +27,7 @@ namespace osu.Game.Beatmaps
|
||||
/// A component which performs and acts as a central cache for difficulty calculations of beatmap/ruleset/mod combinations.
|
||||
/// Currently not persisted between game sessions.
|
||||
/// </summary>
|
||||
public class BeatmapDifficultyCache : MemoryCachingComponent<BeatmapDifficultyCache.DifficultyCacheLookup, StarDifficulty>
|
||||
public class BeatmapDifficultyCache : MemoryCachingComponent<BeatmapDifficultyCache.DifficultyCacheLookup, StarDifficulty?>
|
||||
{
|
||||
// Too many simultaneous updates can lead to stutters. One thread seems to work fine for song select display purposes.
|
||||
private readonly ThreadedTaskScheduler updateScheduler = new ThreadedTaskScheduler(1, nameof(BeatmapDifficultyCache));
|
||||
@ -120,9 +120,13 @@ namespace osu.Game.Beatmaps
|
||||
/// <param name="rulesetInfo">The <see cref="IRulesetInfo"/> to get the difficulty with.</param>
|
||||
/// <param name="mods">The <see cref="Mod"/>s to get the difficulty with.</param>
|
||||
/// <param name="cancellationToken">An optional <see cref="CancellationToken"/> which stops computing the star difficulty.</param>
|
||||
/// <returns>The <see cref="StarDifficulty"/>.</returns>
|
||||
public virtual Task<StarDifficulty> GetDifficultyAsync([NotNull] IBeatmapInfo beatmapInfo, [CanBeNull] IRulesetInfo rulesetInfo = null,
|
||||
[CanBeNull] IEnumerable<Mod> mods = null, CancellationToken cancellationToken = default)
|
||||
/// <returns>
|
||||
/// The requested <see cref="StarDifficulty"/>, if non-<see langword="null"/>.
|
||||
/// A <see langword="null"/> return value indicates that the difficulty process failed or was interrupted early,
|
||||
/// and as such there is no usable star difficulty value to be returned.
|
||||
/// </returns>
|
||||
public virtual Task<StarDifficulty?> GetDifficultyAsync([NotNull] IBeatmapInfo beatmapInfo, [CanBeNull] IRulesetInfo rulesetInfo = null,
|
||||
[CanBeNull] IEnumerable<Mod> mods = null, CancellationToken cancellationToken = default)
|
||||
{
|
||||
// In the case that the user hasn't given us a ruleset, use the beatmap's default ruleset.
|
||||
rulesetInfo ??= beatmapInfo.Ruleset;
|
||||
@ -134,13 +138,13 @@ namespace osu.Game.Beatmaps
|
||||
if (localBeatmapInfo == null || localBeatmapInfo.ID == 0 || localRulesetInfo == null)
|
||||
{
|
||||
// If not, fall back to the existing star difficulty (e.g. from an online source).
|
||||
return Task.FromResult(new StarDifficulty(beatmapInfo.StarRating, (beatmapInfo as IBeatmapOnlineInfo)?.MaxCombo ?? 0));
|
||||
return Task.FromResult<StarDifficulty?>(new StarDifficulty(beatmapInfo.StarRating, (beatmapInfo as IBeatmapOnlineInfo)?.MaxCombo ?? 0));
|
||||
}
|
||||
|
||||
return GetAsync(new DifficultyCacheLookup(localBeatmapInfo, localRulesetInfo, mods), cancellationToken);
|
||||
}
|
||||
|
||||
protected override Task<StarDifficulty> ComputeValueAsync(DifficultyCacheLookup lookup, CancellationToken cancellationToken = default)
|
||||
protected override Task<StarDifficulty?> ComputeValueAsync(DifficultyCacheLookup lookup, CancellationToken cancellationToken = default)
|
||||
{
|
||||
return Task.Factory.StartNew(() =>
|
||||
{
|
||||
@ -151,6 +155,8 @@ namespace osu.Game.Beatmaps
|
||||
}, cancellationToken, TaskCreationOptions.HideScheduler | TaskCreationOptions.RunContinuationsAsynchronously, updateScheduler);
|
||||
}
|
||||
|
||||
protected override bool CacheNullValues => false;
|
||||
|
||||
public Task<List<TimedDifficultyAttributes>> GetTimedDifficultyAttributesAsync(IWorkingBeatmap beatmap, Ruleset ruleset, Mod[] mods, CancellationToken cancellationToken = default)
|
||||
{
|
||||
return Task.Factory.StartNew(() => ruleset.CreateDifficultyCalculator(beatmap).CalculateTimed(mods, cancellationToken),
|
||||
@ -260,7 +266,7 @@ namespace osu.Game.Beatmaps
|
||||
// We're on a threadpool thread, but we should exit back to the update thread so consumers can safely handle value-changed events.
|
||||
Schedule(() =>
|
||||
{
|
||||
if (!cancellationToken.IsCancellationRequested)
|
||||
if (!cancellationToken.IsCancellationRequested && t.Result != null)
|
||||
bindable.Value = t.Result;
|
||||
});
|
||||
}, cancellationToken);
|
||||
@ -272,7 +278,7 @@ namespace osu.Game.Beatmaps
|
||||
/// <param name="key">The <see cref="DifficultyCacheLookup"/> that defines the computation parameters.</param>
|
||||
/// <param name="cancellationToken">The cancellation token.</param>
|
||||
/// <returns>The <see cref="StarDifficulty"/>.</returns>
|
||||
private StarDifficulty computeDifficulty(in DifficultyCacheLookup key, CancellationToken cancellationToken = default)
|
||||
private StarDifficulty? computeDifficulty(in DifficultyCacheLookup key, CancellationToken cancellationToken = default)
|
||||
{
|
||||
// In the case that the user hasn't given us a ruleset, use the beatmap's default ruleset.
|
||||
var beatmapInfo = key.BeatmapInfo;
|
||||
@ -288,16 +294,23 @@ namespace osu.Game.Beatmaps
|
||||
|
||||
return new StarDifficulty(attributes);
|
||||
}
|
||||
catch (BeatmapInvalidForRulesetException e)
|
||||
catch (OperationCanceledException)
|
||||
{
|
||||
// no need to log, cancellations are expected as part of normal operation.
|
||||
return null;
|
||||
}
|
||||
catch (BeatmapInvalidForRulesetException invalidForRuleset)
|
||||
{
|
||||
if (rulesetInfo.Equals(beatmapInfo.Ruleset))
|
||||
Logger.Error(e, $"Failed to convert {beatmapInfo.OnlineID} to the beatmap's default ruleset ({beatmapInfo.Ruleset}).");
|
||||
Logger.Error(invalidForRuleset, $"Failed to convert {beatmapInfo.OnlineID} to the beatmap's default ruleset ({beatmapInfo.Ruleset}).");
|
||||
|
||||
return new StarDifficulty();
|
||||
return null;
|
||||
}
|
||||
catch
|
||||
catch (Exception unknownException)
|
||||
{
|
||||
return new StarDifficulty();
|
||||
Logger.Error(unknownException, "Failed to calculate beatmap difficulty");
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -18,6 +18,7 @@ using osu.Framework.Platform;
|
||||
using osu.Framework.Testing;
|
||||
using osu.Game.Beatmaps.Formats;
|
||||
using osu.Game.Database;
|
||||
using osu.Game.Extensions;
|
||||
using osu.Game.IO;
|
||||
using osu.Game.IO.Archives;
|
||||
using osu.Game.Rulesets;
|
||||
@ -384,7 +385,7 @@ namespace osu.Game.Beatmaps
|
||||
|
||||
foreach (var file in files.Where(f => f.Filename.EndsWith(".osu", StringComparison.OrdinalIgnoreCase)))
|
||||
{
|
||||
using (var raw = Files.Store.GetStream(file.FileInfo.StoragePath))
|
||||
using (var raw = Files.Store.GetStream(file.FileInfo.GetStoragePath()))
|
||||
using (var ms = new MemoryStream()) // we need a memory stream so we can seek
|
||||
using (var sr = new LineBufferedReader(ms))
|
||||
{
|
||||
|
@ -8,6 +8,7 @@ using System.Linq;
|
||||
using JetBrains.Annotations;
|
||||
using osu.Framework.Testing;
|
||||
using osu.Game.Database;
|
||||
using osu.Game.Extensions;
|
||||
|
||||
namespace osu.Game.Beatmaps
|
||||
{
|
||||
@ -61,7 +62,7 @@ namespace osu.Game.Beatmaps
|
||||
/// The path returned is relative to the user file storage.
|
||||
/// </summary>
|
||||
/// <param name="filename">The name of the file to get the storage path of.</param>
|
||||
public string GetPathForFile(string filename) => Files.SingleOrDefault(f => string.Equals(f.Filename, filename, StringComparison.OrdinalIgnoreCase))?.FileInfo.StoragePath;
|
||||
public string GetPathForFile(string filename) => Files.SingleOrDefault(f => string.Equals(f.Filename, filename, StringComparison.OrdinalIgnoreCase))?.FileInfo.GetStoragePath();
|
||||
|
||||
public override string ToString() => Metadata?.ToString() ?? base.ToString();
|
||||
|
||||
|
@ -90,12 +90,31 @@ namespace osu.Game.Beatmaps
|
||||
/// have been applied, and <see cref="HitObject"/>s have been fully constructed.
|
||||
/// </para>
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// By default, the beatmap load process will be interrupted after 10 seconds.
|
||||
/// For finer-grained control over the load process, use the
|
||||
/// <see cref="GetPlayableBeatmap(osu.Game.Rulesets.IRulesetInfo,System.Collections.Generic.IReadOnlyList{osu.Game.Rulesets.Mods.Mod},System.Threading.CancellationToken)"/>
|
||||
/// overload instead.
|
||||
/// </remarks>
|
||||
/// <param name="ruleset">The <see cref="RulesetInfo"/> to create a playable <see cref="IBeatmap"/> for.</param>
|
||||
/// <param name="mods">The <see cref="Mod"/>s to apply to the <see cref="IBeatmap"/>.</param>
|
||||
/// <param name="cancellationToken">Cancellation token that cancels the beatmap loading process. If not provided, a default timeout of 10,000ms will be applied to the load process.</param>
|
||||
/// <returns>The converted <see cref="IBeatmap"/>.</returns>
|
||||
/// <exception cref="BeatmapInvalidForRulesetException">If <see cref="Beatmap"/> could not be converted to <paramref name="ruleset"/>.</exception>
|
||||
IBeatmap GetPlayableBeatmap(IRulesetInfo ruleset, IReadOnlyList<Mod> mods = null, CancellationToken? cancellationToken = null);
|
||||
IBeatmap GetPlayableBeatmap(IRulesetInfo ruleset, IReadOnlyList<Mod> mods = null);
|
||||
|
||||
/// <summary>
|
||||
/// Constructs a playable <see cref="IBeatmap"/> from <see cref="Beatmap"/> using the applicable converters for a specific <see cref="RulesetInfo"/>.
|
||||
/// <para>
|
||||
/// The returned <see cref="IBeatmap"/> is in a playable state - all <see cref="HitObject"/> and <see cref="BeatmapDifficulty"/> <see cref="Mod"/>s
|
||||
/// have been applied, and <see cref="HitObject"/>s have been fully constructed.
|
||||
/// </para>
|
||||
/// </summary>
|
||||
/// <param name="ruleset">The <see cref="RulesetInfo"/> to create a playable <see cref="IBeatmap"/> for.</param>
|
||||
/// <param name="mods">The <see cref="Mod"/>s to apply to the <see cref="IBeatmap"/>.</param>
|
||||
/// <param name="cancellationToken">Cancellation token that cancels the beatmap loading process.</param>
|
||||
/// <returns>The converted <see cref="IBeatmap"/>.</returns>
|
||||
/// <exception cref="BeatmapInvalidForRulesetException">If <see cref="Beatmap"/> could not be converted to <paramref name="ruleset"/>.</exception>
|
||||
IBeatmap GetPlayableBeatmap(IRulesetInfo ruleset, IReadOnlyList<Mod> mods, CancellationToken cancellationToken);
|
||||
|
||||
/// <summary>
|
||||
/// Load a new audio track instance for this beatmap. This should be called once before accessing <see cref="Track"/>.
|
||||
|
@ -79,14 +79,24 @@ namespace osu.Game.Beatmaps
|
||||
/// <returns>The applicable <see cref="IBeatmapConverter"/>.</returns>
|
||||
protected virtual IBeatmapConverter CreateBeatmapConverter(IBeatmap beatmap, Ruleset ruleset) => ruleset.CreateBeatmapConverter(beatmap);
|
||||
|
||||
public virtual IBeatmap GetPlayableBeatmap(IRulesetInfo ruleset, IReadOnlyList<Mod> mods = null, CancellationToken? cancellationToken = null)
|
||||
public IBeatmap GetPlayableBeatmap([NotNull] IRulesetInfo ruleset, IReadOnlyList<Mod> mods = null)
|
||||
{
|
||||
var token = cancellationToken ??
|
||||
// don't apply the default timeout when debugger is attached (may be breakpointing / debugging).
|
||||
(Debugger.IsAttached ? new CancellationToken() : new CancellationTokenSource(10000).Token);
|
||||
|
||||
mods ??= Array.Empty<Mod>();
|
||||
try
|
||||
{
|
||||
using (var cancellationTokenSource = new CancellationTokenSource(10_000))
|
||||
{
|
||||
// don't apply the default timeout when debugger is attached (may be breakpointing / debugging).
|
||||
return GetPlayableBeatmap(ruleset, mods ?? Array.Empty<Mod>(), Debugger.IsAttached ? new CancellationToken() : cancellationTokenSource.Token);
|
||||
}
|
||||
}
|
||||
catch (OperationCanceledException)
|
||||
{
|
||||
throw new BeatmapLoadTimeoutException(BeatmapInfo);
|
||||
}
|
||||
}
|
||||
|
||||
public virtual IBeatmap GetPlayableBeatmap([NotNull] IRulesetInfo ruleset, [NotNull] IReadOnlyList<Mod> mods, CancellationToken token)
|
||||
{
|
||||
var rulesetInstance = ruleset.CreateInstance();
|
||||
|
||||
if (rulesetInstance == null)
|
||||
@ -101,9 +111,7 @@ namespace osu.Game.Beatmaps
|
||||
// Apply conversion mods
|
||||
foreach (var mod in mods.OfType<IApplicableToBeatmapConverter>())
|
||||
{
|
||||
if (token.IsCancellationRequested)
|
||||
throw new BeatmapLoadTimeoutException(BeatmapInfo);
|
||||
|
||||
token.ThrowIfCancellationRequested();
|
||||
mod.ApplyToBeatmapConverter(converter);
|
||||
}
|
||||
|
||||
@ -113,9 +121,7 @@ namespace osu.Game.Beatmaps
|
||||
// Apply conversion mods to the result
|
||||
foreach (var mod in mods.OfType<IApplicableAfterBeatmapConversion>())
|
||||
{
|
||||
if (token.IsCancellationRequested)
|
||||
throw new BeatmapLoadTimeoutException(BeatmapInfo);
|
||||
|
||||
token.ThrowIfCancellationRequested();
|
||||
mod.ApplyToBeatmap(converted);
|
||||
}
|
||||
|
||||
@ -124,9 +130,7 @@ namespace osu.Game.Beatmaps
|
||||
{
|
||||
foreach (var mod in mods.OfType<IApplicableToDifficulty>())
|
||||
{
|
||||
if (token.IsCancellationRequested)
|
||||
throw new BeatmapLoadTimeoutException(BeatmapInfo);
|
||||
|
||||
token.ThrowIfCancellationRequested();
|
||||
mod.ApplyToDifficulty(converted.Difficulty);
|
||||
}
|
||||
}
|
||||
@ -139,28 +143,17 @@ namespace osu.Game.Beatmaps
|
||||
processor?.PreProcess();
|
||||
|
||||
// Compute default values for hitobjects, including creating nested hitobjects in-case they're needed
|
||||
try
|
||||
foreach (var obj in converted.HitObjects)
|
||||
{
|
||||
foreach (var obj in converted.HitObjects)
|
||||
{
|
||||
if (token.IsCancellationRequested)
|
||||
throw new BeatmapLoadTimeoutException(BeatmapInfo);
|
||||
|
||||
obj.ApplyDefaults(converted.ControlPointInfo, converted.Difficulty, token);
|
||||
}
|
||||
}
|
||||
catch (OperationCanceledException)
|
||||
{
|
||||
throw new BeatmapLoadTimeoutException(BeatmapInfo);
|
||||
token.ThrowIfCancellationRequested();
|
||||
obj.ApplyDefaults(converted.ControlPointInfo, converted.Difficulty, token);
|
||||
}
|
||||
|
||||
foreach (var mod in mods.OfType<IApplicableToHitObject>())
|
||||
{
|
||||
foreach (var obj in converted.HitObjects)
|
||||
{
|
||||
if (token.IsCancellationRequested)
|
||||
throw new BeatmapLoadTimeoutException(BeatmapInfo);
|
||||
|
||||
token.ThrowIfCancellationRequested();
|
||||
mod.ApplyToHitObject(obj);
|
||||
}
|
||||
}
|
||||
|
@ -325,7 +325,7 @@ namespace osu.Game.Database
|
||||
|
||||
foreach (TFileModel file in hashableFiles)
|
||||
{
|
||||
using (Stream s = Files.Store.GetStream(file.FileInfo.StoragePath))
|
||||
using (Stream s = Files.Store.GetStream(file.FileInfo.GetStoragePath()))
|
||||
s.CopyTo(hashable);
|
||||
}
|
||||
|
||||
@ -480,7 +480,7 @@ namespace osu.Game.Database
|
||||
using (var archive = ZipArchive.Create())
|
||||
{
|
||||
foreach (var file in model.Files)
|
||||
archive.AddEntry(file.Filename, Files.Storage.GetStream(file.FileInfo.StoragePath));
|
||||
archive.AddEntry(file.Filename, Files.Storage.GetStream(file.FileInfo.GetStoragePath()));
|
||||
|
||||
archive.SaveTo(outputStream);
|
||||
}
|
||||
|
@ -1,8 +1,10 @@
|
||||
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
||||
// See the LICENCE file in the repository root for full licence text.
|
||||
|
||||
using System.IO;
|
||||
using osu.Game.Beatmaps;
|
||||
using osu.Game.Database;
|
||||
using osu.Game.IO;
|
||||
using osu.Game.Online.API.Requests.Responses;
|
||||
using osu.Game.Rulesets;
|
||||
using osu.Game.Scoring;
|
||||
@ -14,6 +16,13 @@ namespace osu.Game.Extensions
|
||||
{
|
||||
public static class ModelExtensions
|
||||
{
|
||||
/// <summary>
|
||||
/// Get the relative path in osu! storage for this file.
|
||||
/// </summary>
|
||||
/// <param name="fileInfo">The file info.</param>
|
||||
/// <returns>A relative file path.</returns>
|
||||
public static string GetStoragePath(this IFileInfo fileInfo) => Path.Combine(fileInfo.Hash.Remove(1), fileInfo.Hash.Remove(2), fileInfo.Hash);
|
||||
|
||||
/// <summary>
|
||||
/// Returns a user-facing string representing the <paramref name="model"/>.
|
||||
/// </summary>
|
||||
|
@ -1,7 +1,6 @@
|
||||
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
||||
// See the LICENCE file in the repository root for full licence text.
|
||||
|
||||
using System.IO;
|
||||
using osu.Game.Database;
|
||||
|
||||
namespace osu.Game.IO
|
||||
@ -12,8 +11,6 @@ namespace osu.Game.IO
|
||||
|
||||
public string Hash { get; set; }
|
||||
|
||||
public string StoragePath => Path.Combine(Hash.Remove(1), Hash.Remove(2), Hash);
|
||||
|
||||
public int ReferenceCount { get; set; }
|
||||
}
|
||||
}
|
||||
|
@ -12,6 +12,7 @@ using osu.Framework.IO.Stores;
|
||||
using osu.Framework.Logging;
|
||||
using osu.Framework.Platform;
|
||||
using osu.Game.Database;
|
||||
using osu.Game.Extensions;
|
||||
|
||||
namespace osu.Game.IO
|
||||
{
|
||||
@ -47,7 +48,7 @@ namespace osu.Game.IO
|
||||
|
||||
var info = existing ?? new FileInfo { Hash = hash };
|
||||
|
||||
string path = info.StoragePath;
|
||||
string path = info.GetStoragePath();
|
||||
|
||||
// we may be re-adding a file to fix missing store entries.
|
||||
bool requiresCopy = !Storage.Exists(path);
|
||||
@ -120,7 +121,7 @@ namespace osu.Game.IO
|
||||
{
|
||||
try
|
||||
{
|
||||
Storage.Delete(f.StoragePath);
|
||||
Storage.Delete(f.GetStoragePath());
|
||||
context.FileInfo.Remove(f);
|
||||
}
|
||||
catch (Exception e)
|
||||
|
@ -6,7 +6,7 @@ namespace osu.Game.Migrations
|
||||
{
|
||||
protected override void Up(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
// There was a change that baetmaps were being loaded with "-1" online IDs, which is completely incorrect.
|
||||
// There was a change that beatmaps were being loaded with "-1" online IDs, which is completely incorrect.
|
||||
// This ensures there will not be unique key conflicts as a result of these incorrectly imported beatmaps.
|
||||
migrationBuilder.Sql("UPDATE BeatmapSetInfo SET OnlineBeatmapSetID = null WHERE OnlineBeatmapSetID <= 0");
|
||||
}
|
||||
|
@ -52,7 +52,7 @@ namespace osu.Game.Models
|
||||
/// The path returned is relative to the user file storage.
|
||||
/// </summary>
|
||||
/// <param name="filename">The name of the file to get the storage path of.</param>
|
||||
public string? GetPathForFile(string filename) => Files.SingleOrDefault(f => string.Equals(f.Filename, filename, StringComparison.OrdinalIgnoreCase))?.File.StoragePath;
|
||||
public string? GetPathForFile(string filename) => Files.SingleOrDefault(f => string.Equals(f.Filename, filename, StringComparison.OrdinalIgnoreCase))?.File.GetStoragePath();
|
||||
|
||||
public bool Equals(RealmBeatmapSet? other)
|
||||
{
|
||||
|
@ -1,7 +1,6 @@
|
||||
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
||||
// See the LICENCE file in the repository root for full licence text.
|
||||
|
||||
using System.IO;
|
||||
using osu.Framework.Testing;
|
||||
using osu.Game.IO;
|
||||
using Realms;
|
||||
@ -16,7 +15,5 @@ namespace osu.Game.Models
|
||||
{
|
||||
[PrimaryKey]
|
||||
public string Hash { get; set; } = string.Empty;
|
||||
|
||||
public string StoragePath => Path.Combine(Hash.Remove(1), Hash.Remove(2), Hash);
|
||||
}
|
||||
}
|
||||
|
@ -17,8 +17,9 @@ namespace osu.Game.Online
|
||||
public class SignalRDerivedTypeWorkaroundJsonConverter : JsonConverter
|
||||
{
|
||||
public override bool CanConvert(Type objectType) =>
|
||||
SignalRUnionWorkaroundResolver.BASE_TYPES.Contains(objectType) ||
|
||||
SignalRUnionWorkaroundResolver.DERIVED_TYPES.Contains(objectType);
|
||||
SignalRWorkaroundTypes.BASE_TYPE_MAPPING.Any(t =>
|
||||
objectType == t.baseType ||
|
||||
objectType == t.derivedType);
|
||||
|
||||
public override object? ReadJson(JsonReader reader, Type objectType, object? o, JsonSerializer jsonSerializer)
|
||||
{
|
||||
@ -29,7 +30,7 @@ namespace osu.Game.Online
|
||||
|
||||
string type = (string)obj[@"$dtype"]!;
|
||||
|
||||
var resolvedType = SignalRUnionWorkaroundResolver.DERIVED_TYPES.Single(t => t.Name == type);
|
||||
var resolvedType = SignalRWorkaroundTypes.BASE_TYPE_MAPPING.Select(t => t.derivedType).Single(t => t.Name == type);
|
||||
|
||||
object? instance = Activator.CreateInstance(resolvedType);
|
||||
|
||||
|
@ -3,11 +3,10 @@
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using MessagePack;
|
||||
using MessagePack.Formatters;
|
||||
using MessagePack.Resolvers;
|
||||
using osu.Game.Online.Multiplayer;
|
||||
using osu.Game.Online.Multiplayer.MatchTypes.TeamVersus;
|
||||
|
||||
namespace osu.Game.Online
|
||||
{
|
||||
@ -20,34 +19,22 @@ namespace osu.Game.Online
|
||||
public static readonly MessagePackSerializerOptions OPTIONS =
|
||||
MessagePackSerializerOptions.Standard.WithResolver(new SignalRUnionWorkaroundResolver());
|
||||
|
||||
public static readonly IReadOnlyList<Type> BASE_TYPES = new[]
|
||||
{
|
||||
typeof(MatchServerEvent),
|
||||
typeof(MatchUserRequest),
|
||||
typeof(MatchRoomState),
|
||||
typeof(MatchUserState),
|
||||
};
|
||||
private static readonly IReadOnlyDictionary<Type, IMessagePackFormatter> formatter_map = createFormatterMap();
|
||||
|
||||
public static readonly IReadOnlyList<Type> DERIVED_TYPES = new[]
|
||||
private static IReadOnlyDictionary<Type, IMessagePackFormatter> createFormatterMap()
|
||||
{
|
||||
typeof(ChangeTeamRequest),
|
||||
typeof(TeamVersusRoomState),
|
||||
typeof(TeamVersusUserState),
|
||||
};
|
||||
IEnumerable<(Type derivedType, Type baseType)> baseMap = SignalRWorkaroundTypes.BASE_TYPE_MAPPING;
|
||||
|
||||
private static readonly IReadOnlyDictionary<Type, IMessagePackFormatter> formatter_map = new Dictionary<Type, IMessagePackFormatter>
|
||||
{
|
||||
{ typeof(TeamVersusUserState), new TypeRedirectingFormatter<TeamVersusUserState, MatchUserState>() },
|
||||
{ typeof(TeamVersusRoomState), new TypeRedirectingFormatter<TeamVersusRoomState, MatchRoomState>() },
|
||||
{ typeof(ChangeTeamRequest), new TypeRedirectingFormatter<ChangeTeamRequest, MatchUserRequest>() },
|
||||
|
||||
// These should not be required. The fallback should work. But something is weird with the way caching is done.
|
||||
// This should not be required. The fallback should work. But something is weird with the way caching is done.
|
||||
// For future adventurers, I would not advise looking into this further. It's likely not worth the effort.
|
||||
{ typeof(MatchUserState), new TypeRedirectingFormatter<MatchUserState, MatchUserState>() },
|
||||
{ typeof(MatchRoomState), new TypeRedirectingFormatter<MatchRoomState, MatchRoomState>() },
|
||||
{ typeof(MatchUserRequest), new TypeRedirectingFormatter<MatchUserRequest, MatchUserRequest>() },
|
||||
{ typeof(MatchServerEvent), new TypeRedirectingFormatter<MatchServerEvent, MatchServerEvent>() },
|
||||
};
|
||||
baseMap = baseMap.Concat(baseMap.Select(t => (t.baseType, t.baseType)));
|
||||
|
||||
return new Dictionary<Type, IMessagePackFormatter>(baseMap.Select(t =>
|
||||
{
|
||||
var formatter = (IMessagePackFormatter)Activator.CreateInstance(typeof(TypeRedirectingFormatter<,>).MakeGenericType(t.derivedType, t.baseType));
|
||||
return new KeyValuePair<Type, IMessagePackFormatter>(t.derivedType, formatter);
|
||||
}));
|
||||
}
|
||||
|
||||
public IMessagePackFormatter<T> GetFormatter<T>()
|
||||
{
|
||||
|
25
osu.Game/Online/SignalRWorkaroundTypes.cs
Normal file
25
osu.Game/Online/SignalRWorkaroundTypes.cs
Normal file
@ -0,0 +1,25 @@
|
||||
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
||||
// See the LICENCE file in the repository root for full licence text.
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using osu.Game.Online.Multiplayer;
|
||||
using osu.Game.Online.Multiplayer.MatchTypes.TeamVersus;
|
||||
|
||||
namespace osu.Game.Online
|
||||
{
|
||||
/// <summary>
|
||||
/// A static class providing the list of types requiring workarounds for serialisation in SignalR.
|
||||
/// </summary>
|
||||
/// <seealso cref="SignalRUnionWorkaroundResolver"/>
|
||||
/// <seealso cref="SignalRDerivedTypeWorkaroundJsonConverter"/>
|
||||
internal static class SignalRWorkaroundTypes
|
||||
{
|
||||
internal static readonly IReadOnlyList<(Type derivedType, Type baseType)> BASE_TYPE_MAPPING = new[]
|
||||
{
|
||||
(typeof(ChangeTeamRequest), typeof(MatchUserRequest)),
|
||||
(typeof(TeamVersusRoomState), typeof(MatchRoomState)),
|
||||
(typeof(TeamVersusUserState), typeof(MatchUserState)),
|
||||
};
|
||||
}
|
||||
}
|
@ -4,7 +4,6 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Newtonsoft.Json;
|
||||
using osu.Game.Rulesets.Difficulty.Skills;
|
||||
using osu.Game.Rulesets.Mods;
|
||||
|
||||
namespace osu.Game.Rulesets.Difficulty
|
||||
@ -31,11 +30,6 @@ namespace osu.Game.Rulesets.Difficulty
|
||||
/// </summary>
|
||||
public Mod[] Mods { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The skills resulting from the difficulty calculation.
|
||||
/// </summary>
|
||||
public Skill[] Skills { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The combined star rating of all skill.
|
||||
/// </summary>
|
||||
@ -59,12 +53,10 @@ namespace osu.Game.Rulesets.Difficulty
|
||||
/// Creates new <see cref="DifficultyAttributes"/>.
|
||||
/// </summary>
|
||||
/// <param name="mods">The mods which were applied to the beatmap.</param>
|
||||
/// <param name="skills">The skills resulting from the difficulty calculation.</param>
|
||||
/// <param name="starRating">The combined star rating of all skills.</param>
|
||||
public DifficultyAttributes(Mod[] mods, Skill[] skills, double starRating)
|
||||
public DifficultyAttributes(Mod[] mods, double starRating)
|
||||
{
|
||||
Mods = mods;
|
||||
Skills = skills;
|
||||
StarRating = starRating;
|
||||
}
|
||||
|
||||
|
@ -11,6 +11,10 @@ namespace osu.Game.Rulesets.Difficulty.Skills
|
||||
/// <summary>
|
||||
/// A bare minimal abstract skill for fully custom skill implementations.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// This class should be considered a "processing" class and not persisted, as it keeps references to
|
||||
/// gameplay objects after processing is run (see <see cref="Previous"/>).
|
||||
/// </remarks>
|
||||
public abstract class Skill
|
||||
{
|
||||
/// <summary>
|
||||
|
@ -6,6 +6,7 @@ using System.IO;
|
||||
using System.Linq;
|
||||
using ManagedBass;
|
||||
using osu.Framework.Audio.Callbacks;
|
||||
using osu.Game.Extensions;
|
||||
using osu.Game.Rulesets.Edit.Checks.Components;
|
||||
|
||||
namespace osu.Game.Rulesets.Edit.Checks
|
||||
@ -31,7 +32,7 @@ namespace osu.Game.Rulesets.Edit.Checks
|
||||
|
||||
foreach (var file in beatmapSet.Files)
|
||||
{
|
||||
using (Stream data = context.WorkingBeatmap.GetStream(file.FileInfo.StoragePath))
|
||||
using (Stream data = context.WorkingBeatmap.GetStream(file.FileInfo.GetStoragePath()))
|
||||
{
|
||||
if (data == null)
|
||||
continue;
|
||||
|
@ -3,6 +3,7 @@
|
||||
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using osu.Game.Extensions;
|
||||
using osu.Game.Rulesets.Edit.Checks.Components;
|
||||
|
||||
namespace osu.Game.Rulesets.Edit.Checks
|
||||
@ -22,7 +23,7 @@ namespace osu.Game.Rulesets.Edit.Checks
|
||||
|
||||
foreach (var file in beatmapSet.Files)
|
||||
{
|
||||
using (Stream data = context.WorkingBeatmap.GetStream(file.FileInfo.StoragePath))
|
||||
using (Stream data = context.WorkingBeatmap.GetStream(file.FileInfo.GetStoragePath()))
|
||||
{
|
||||
if (data?.Length == 0)
|
||||
yield return new IssueTemplateZeroBytes(this).Create(file.Filename);
|
||||
|
@ -5,6 +5,7 @@ using System;
|
||||
using System.Linq;
|
||||
using osu.Framework.IO.Stores;
|
||||
using osu.Game.Beatmaps;
|
||||
using osu.Game.Extensions;
|
||||
using osu.Game.Rulesets;
|
||||
using osu.Game.Scoring.Legacy;
|
||||
|
||||
@ -16,7 +17,7 @@ namespace osu.Game.Scoring
|
||||
{
|
||||
ScoreInfo = score;
|
||||
|
||||
string replayFilename = score.Files.FirstOrDefault(f => f.Filename.EndsWith(".osr", StringComparison.InvariantCultureIgnoreCase))?.FileInfo.StoragePath;
|
||||
string replayFilename = score.Files.FirstOrDefault(f => f.Filename.EndsWith(".osr", StringComparison.InvariantCultureIgnoreCase))?.FileInfo.GetStoragePath();
|
||||
|
||||
if (replayFilename == null)
|
||||
return;
|
||||
|
@ -162,7 +162,12 @@ namespace osu.Game.Scoring
|
||||
|
||||
// We can compute the max combo locally after the async beatmap difficulty computation.
|
||||
var difficulty = await difficulties().GetDifficultyAsync(score.BeatmapInfo, score.Ruleset, score.Mods, cancellationToken).ConfigureAwait(false);
|
||||
beatmapMaxCombo = difficulty.MaxCombo;
|
||||
|
||||
// Something failed during difficulty calculation. Fall back to provided score.
|
||||
if (difficulty == null)
|
||||
return score.TotalScore;
|
||||
|
||||
beatmapMaxCombo = difficulty.Value.MaxCombo;
|
||||
}
|
||||
}
|
||||
else
|
||||
|
@ -13,6 +13,7 @@ using osu.Framework.Logging;
|
||||
using osu.Framework.Platform;
|
||||
using osu.Game.Beatmaps;
|
||||
using osu.Game.Database;
|
||||
using osu.Game.Extensions;
|
||||
using osu.Game.IO.Archives;
|
||||
using osu.Game.Rulesets;
|
||||
using osu.Game.Scoring.Legacy;
|
||||
@ -77,7 +78,7 @@ namespace osu.Game.Scoring
|
||||
if (file == null)
|
||||
return;
|
||||
|
||||
using (var inputStream = Files.Storage.GetStream(file.FileInfo.StoragePath))
|
||||
using (var inputStream = Files.Storage.GetStream(file.FileInfo.GetStoragePath()))
|
||||
inputStream.CopyTo(outputStream);
|
||||
}
|
||||
|
||||
|
@ -37,12 +37,12 @@ namespace osu.Game.Scoring
|
||||
var attributes = await difficultyCache.GetDifficultyAsync(score.BeatmapInfo, score.Ruleset, score.Mods, token).ConfigureAwait(false);
|
||||
|
||||
// Performance calculation requires the beatmap and ruleset to be locally available. If not, return a default value.
|
||||
if (attributes.Attributes == null)
|
||||
if (attributes?.Attributes == null)
|
||||
return null;
|
||||
|
||||
token.ThrowIfCancellationRequested();
|
||||
|
||||
var calculator = score.Ruleset.CreateInstance().CreatePerformanceCalculator(attributes.Attributes, score);
|
||||
var calculator = score.Ruleset.CreateInstance().CreatePerformanceCalculator(attributes.Value.Attributes, score);
|
||||
|
||||
return calculator?.Calculate();
|
||||
}
|
||||
|
@ -421,7 +421,19 @@ namespace osu.Game.Screens.OnlinePlay.Multiplayer.Match
|
||||
{
|
||||
Debug.Assert(applyingSettingsOperation != null);
|
||||
|
||||
ErrorText.Text = text;
|
||||
// see https://github.com/ppy/osu-web/blob/2c97aaeb64fb4ed97c747d8383a35b30f57428c7/app/Models/Multiplayer/PlaylistItem.php#L48.
|
||||
const string not_found_prefix = "beatmaps not found:";
|
||||
|
||||
if (text.StartsWith(not_found_prefix, StringComparison.Ordinal))
|
||||
{
|
||||
ErrorText.Text = "The selected beatmap is not available online.";
|
||||
SelectedItem.Value.MarkInvalid();
|
||||
}
|
||||
else
|
||||
{
|
||||
ErrorText.Text = text;
|
||||
}
|
||||
|
||||
ErrorText.FadeIn(50);
|
||||
|
||||
applyingSettingsOperation.Dispose();
|
||||
|
@ -216,7 +216,7 @@ namespace osu.Game.Screens.Play.HUD
|
||||
this.gameplayBeatmap = gameplayBeatmap;
|
||||
}
|
||||
|
||||
public override IBeatmap GetPlayableBeatmap(IRulesetInfo ruleset, IReadOnlyList<Mod> mods = null, CancellationToken? cancellationToken = null)
|
||||
public override IBeatmap GetPlayableBeatmap(IRulesetInfo ruleset, IReadOnlyList<Mod> mods, CancellationToken cancellationToken)
|
||||
=> gameplayBeatmap;
|
||||
|
||||
protected override IBeatmap GetBeatmap() => gameplayBeatmap;
|
||||
|
@ -143,14 +143,6 @@ namespace osu.Game.Screens.Ranking.Expanded
|
||||
Origin = Anchor.TopCentre,
|
||||
AutoSizeAxes = Axes.Both,
|
||||
Spacing = new Vector2(5, 0),
|
||||
Children = new Drawable[]
|
||||
{
|
||||
new StarRatingDisplay(starDifficulty)
|
||||
{
|
||||
Anchor = Anchor.CentreLeft,
|
||||
Origin = Anchor.CentreLeft
|
||||
},
|
||||
}
|
||||
},
|
||||
new FillFlowContainer
|
||||
{
|
||||
@ -231,6 +223,15 @@ namespace osu.Game.Screens.Ranking.Expanded
|
||||
if (score.Date != default)
|
||||
AddInternal(new PlayedOnText(score.Date));
|
||||
|
||||
if (starDifficulty != null)
|
||||
{
|
||||
starAndModDisplay.Add(new StarRatingDisplay(starDifficulty.Value)
|
||||
{
|
||||
Anchor = Anchor.CentreLeft,
|
||||
Origin = Anchor.CentreLeft
|
||||
});
|
||||
}
|
||||
|
||||
if (score.Mods.Any())
|
||||
{
|
||||
starAndModDisplay.Add(new ModDisplay
|
||||
|
@ -152,7 +152,10 @@ namespace osu.Game.Screens.Select.Details
|
||||
|
||||
Task.WhenAll(normalStarDifficulty, moddedStarDifficulty).ContinueWith(_ => Schedule(() =>
|
||||
{
|
||||
starDifficulty.Value = ((float)normalStarDifficulty.Result.Stars, (float)moddedStarDifficulty.Result.Stars);
|
||||
if (normalStarDifficulty.Result == null || moddedStarDifficulty.Result == null)
|
||||
return;
|
||||
|
||||
starDifficulty.Value = ((float)normalStarDifficulty.Result.Value.Stars, (float)moddedStarDifficulty.Result.Value.Stars);
|
||||
}), starDifficultyCancellationSource.Token, TaskContinuationOptions.OnlyOnRanToCompletion, TaskScheduler.Current);
|
||||
}
|
||||
|
||||
|
@ -7,6 +7,7 @@ using System.Linq;
|
||||
using osu.Framework.Extensions;
|
||||
using osu.Framework.IO.Stores;
|
||||
using osu.Game.Database;
|
||||
using osu.Game.Extensions;
|
||||
|
||||
namespace osu.Game.Skinning
|
||||
{
|
||||
@ -35,7 +36,7 @@ namespace osu.Game.Skinning
|
||||
}
|
||||
|
||||
private string getPathForFile(string filename) =>
|
||||
source.Files.Find(f => string.Equals(f.Filename, filename, StringComparison.OrdinalIgnoreCase))?.FileInfo.StoragePath;
|
||||
source.Files.Find(f => string.Equals(f.Filename, filename, StringComparison.OrdinalIgnoreCase))?.FileInfo.GetStoragePath();
|
||||
|
||||
public override IEnumerable<string> GetAvailableResources() => source.Files.Select(f => f.Filename);
|
||||
}
|
||||
|
@ -15,6 +15,7 @@ using osu.Framework.Graphics.OpenGL.Textures;
|
||||
using osu.Framework.Graphics.Textures;
|
||||
using osu.Framework.Logging;
|
||||
using osu.Game.Audio;
|
||||
using osu.Game.Extensions;
|
||||
using osu.Game.IO;
|
||||
using osu.Game.Screens.Play.HUD;
|
||||
|
||||
@ -63,7 +64,7 @@ namespace osu.Game.Skinning
|
||||
if (fileInfo == null)
|
||||
continue;
|
||||
|
||||
byte[] bytes = resources?.Files.Get(fileInfo.FileInfo.StoragePath);
|
||||
byte[] bytes = resources?.Files.Get(fileInfo.FileInfo.GetStoragePath());
|
||||
|
||||
if (bytes == null)
|
||||
continue;
|
||||
@ -93,7 +94,7 @@ namespace osu.Game.Skinning
|
||||
|
||||
private Stream getConfigurationStream()
|
||||
{
|
||||
string path = SkinInfo.Files.SingleOrDefault(f => f.Filename.Equals(@"skin.ini", StringComparison.OrdinalIgnoreCase))?.FileInfo.StoragePath;
|
||||
string path = SkinInfo.Files.SingleOrDefault(f => f.Filename.Equals(@"skin.ini", StringComparison.OrdinalIgnoreCase))?.FileInfo.GetStoragePath();
|
||||
|
||||
if (string.IsNullOrEmpty(path))
|
||||
return null;
|
||||
|
@ -215,7 +215,7 @@ namespace osu.Game.Skinning
|
||||
{
|
||||
using (var sw = new StreamWriter(stream, Encoding.UTF8, 1024, true))
|
||||
{
|
||||
using (var existingStream = Files.Storage.GetStream(existingFile.FileInfo.StoragePath))
|
||||
using (var existingStream = Files.Storage.GetStream(existingFile.FileInfo.GetStoragePath()))
|
||||
using (var sr = new StreamReader(existingStream))
|
||||
{
|
||||
string line;
|
||||
|
@ -18,6 +18,7 @@ using osu.Framework.Testing;
|
||||
using osu.Game.Beatmaps;
|
||||
using osu.Game.Beatmaps.Formats;
|
||||
using osu.Game.Database;
|
||||
using osu.Game.Extensions;
|
||||
using osu.Game.IO;
|
||||
using osu.Game.IO.Archives;
|
||||
using osu.Game.Models;
|
||||
@ -197,7 +198,7 @@ namespace osu.Game.Stores
|
||||
|
||||
foreach (var file in files.Where(f => f.Filename.EndsWith(".osu", StringComparison.OrdinalIgnoreCase)))
|
||||
{
|
||||
using (var memoryStream = new MemoryStream(Files.Store.Get(file.File.StoragePath))) // we need a memory stream so we can seek
|
||||
using (var memoryStream = new MemoryStream(Files.Store.Get(file.File.GetStoragePath()))) // we need a memory stream so we can seek
|
||||
{
|
||||
IBeatmap decoded;
|
||||
using (var lineReader = new LineBufferedReader(memoryStream, true))
|
||||
|
@ -15,6 +15,7 @@ using osu.Framework.Logging;
|
||||
using osu.Framework.Platform;
|
||||
using osu.Framework.Threading;
|
||||
using osu.Game.Database;
|
||||
using osu.Game.Extensions;
|
||||
using osu.Game.IO.Archives;
|
||||
using osu.Game.Models;
|
||||
using osu.Game.Overlays.Notifications;
|
||||
@ -305,7 +306,7 @@ namespace osu.Game.Stores
|
||||
|
||||
foreach (RealmNamedFileUsage file in item.Files.Where(f => HashableFileTypes.Any(ext => f.Filename.EndsWith(ext, StringComparison.OrdinalIgnoreCase))).OrderBy(f => f.Filename))
|
||||
{
|
||||
using (Stream s = Files.Store.GetStream(file.File.StoragePath))
|
||||
using (Stream s = Files.Store.GetStream(file.File.GetStoragePath()))
|
||||
s.CopyTo(hashable);
|
||||
}
|
||||
|
||||
|
@ -10,6 +10,7 @@ using osu.Framework.Logging;
|
||||
using osu.Framework.Platform;
|
||||
using osu.Framework.Testing;
|
||||
using osu.Game.Database;
|
||||
using osu.Game.Extensions;
|
||||
using osu.Game.Models;
|
||||
using Realms;
|
||||
|
||||
@ -64,7 +65,7 @@ namespace osu.Game.Stores
|
||||
{
|
||||
data.Seek(0, SeekOrigin.Begin);
|
||||
|
||||
using (var output = Storage.GetStream(file.StoragePath, FileAccess.Write))
|
||||
using (var output = Storage.GetStream(file.GetStoragePath(), FileAccess.Write))
|
||||
data.CopyTo(output);
|
||||
|
||||
data.Seek(0, SeekOrigin.Begin);
|
||||
@ -72,7 +73,7 @@ namespace osu.Game.Stores
|
||||
|
||||
private bool checkFileExistsAndMatchesHash(RealmFile file)
|
||||
{
|
||||
string path = file.StoragePath;
|
||||
string path = file.GetStoragePath();
|
||||
|
||||
// we may be re-adding a file to fix missing store entries.
|
||||
if (!Storage.Exists(path))
|
||||
@ -100,7 +101,7 @@ namespace osu.Game.Stores
|
||||
|
||||
try
|
||||
{
|
||||
Storage.Delete(file.StoragePath);
|
||||
Storage.Delete(file.GetStoragePath());
|
||||
realm.Remove(file);
|
||||
}
|
||||
catch (Exception e)
|
||||
|
@ -2,6 +2,7 @@
|
||||
// See the LICENCE file in the repository root for full licence text.
|
||||
|
||||
using System;
|
||||
using System.Linq;
|
||||
using osu.Framework.Allocation;
|
||||
using osu.Framework.Bindables;
|
||||
using osu.Framework.Graphics;
|
||||
@ -9,6 +10,7 @@ using osu.Framework.Graphics.Containers;
|
||||
using osu.Framework.Graphics.Textures;
|
||||
using osu.Framework.Graphics.Video;
|
||||
using osu.Game.Beatmaps;
|
||||
using osu.Game.Extensions;
|
||||
|
||||
namespace osu.Game.Storyboards.Drawables
|
||||
{
|
||||
@ -29,7 +31,7 @@ namespace osu.Game.Storyboards.Drawables
|
||||
[BackgroundDependencyLoader(true)]
|
||||
private void load(IBindable<WorkingBeatmap> beatmap, TextureStore textureStore)
|
||||
{
|
||||
string path = beatmap.Value.BeatmapSetInfo?.Files.Find(f => f.Filename.Equals(Video.Path, StringComparison.OrdinalIgnoreCase))?.FileInfo.StoragePath;
|
||||
string path = beatmap.Value.BeatmapSetInfo?.Files.FirstOrDefault(f => f.Filename.Equals(Video.Path, StringComparison.OrdinalIgnoreCase))?.File.GetStoragePath();
|
||||
|
||||
if (path == null)
|
||||
return;
|
||||
|
@ -8,6 +8,7 @@ using osu.Framework.Graphics;
|
||||
using osu.Framework.Graphics.Sprites;
|
||||
using osu.Framework.Graphics.Textures;
|
||||
using osu.Game.Beatmaps;
|
||||
using osu.Game.Extensions;
|
||||
using osu.Game.Skinning;
|
||||
using osu.Game.Storyboards.Drawables;
|
||||
|
||||
@ -95,7 +96,7 @@ namespace osu.Game.Storyboards
|
||||
public Drawable CreateSpriteFromResourcePath(string path, TextureStore textureStore)
|
||||
{
|
||||
Drawable drawable = null;
|
||||
string storyboardPath = BeatmapInfo.BeatmapSet?.Files.Find(f => f.Filename.Equals(path, StringComparison.OrdinalIgnoreCase))?.FileInfo.StoragePath;
|
||||
string storyboardPath = BeatmapInfo.BeatmapSet?.Files.Find(f => f.Filename.Equals(path, StringComparison.OrdinalIgnoreCase))?.FileInfo.GetStoragePath();
|
||||
|
||||
if (!string.IsNullOrEmpty(storyboardPath))
|
||||
drawable = new Sprite { Texture = textureStore.Get(storyboardPath) };
|
||||
|
@ -20,8 +20,8 @@
|
||||
<ItemGroup Label="Package References">
|
||||
<PackageReference Include="AutoMapper" Version="10.1.1" />
|
||||
<PackageReference Include="DiffPlex" Version="1.7.0" />
|
||||
<PackageReference Include="HtmlAgilityPack" Version="1.11.37" />
|
||||
<PackageReference Include="Humanizer" Version="2.11.10" />
|
||||
<PackageReference Include="HtmlAgilityPack" Version="1.11.38" />
|
||||
<PackageReference Include="Humanizer" Version="2.13.14" />
|
||||
<PackageReference Include="MessagePack" Version="2.3.85" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.SignalR.Client" Version="5.0.11" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.SignalR.Protocols.MessagePack" Version="5.0.11" />
|
||||
@ -35,10 +35,10 @@
|
||||
<PrivateAssets>all</PrivateAssets>
|
||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||
</PackageReference>
|
||||
<PackageReference Include="Realm" Version="10.6.0" />
|
||||
<PackageReference Include="ppy.osu.Framework" Version="2021.1118.0" />
|
||||
<PackageReference Include="Realm" Version="10.7.1" />
|
||||
<PackageReference Include="ppy.osu.Framework" Version="2021.1119.0" />
|
||||
<PackageReference Include="ppy.osu.Game.Resources" Version="2021.1112.0" />
|
||||
<PackageReference Include="Sentry" Version="3.10.0" />
|
||||
<PackageReference Include="Sentry" Version="3.11.1" />
|
||||
<PackageReference Include="SharpCompress" Version="0.30.0" />
|
||||
<PackageReference Include="NUnit" Version="3.13.2" />
|
||||
<PackageReference Include="System.ComponentModel.Annotations" Version="5.0.0" />
|
||||
|
@ -4,17 +4,19 @@
|
||||
<ProjectTypeGuids>{FEACFBD2-3405-455C-9665-78FE426C6842};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
|
||||
<IPhoneResourcePrefix>Resources</IPhoneResourcePrefix>
|
||||
<RestoreProjectStyle>PackageReference</RestoreProjectStyle>
|
||||
<DefaultMtouchExtraArgs>--nolinkaway</DefaultMtouchExtraArgs>
|
||||
<DefaultMtouchGccFlags>-lstdc++ -lbz2 -framework AudioToolbox -framework AVFoundation -framework CoreMedia -framework VideoToolbox -framework SystemConfiguration -framework CFNetwork -framework Accelerate</DefaultMtouchGccFlags>
|
||||
<OutputPath>bin\$(Platform)\$(Configuration)</OutputPath>
|
||||
<MtouchI18n>cjk,mideast,other,rare,west</MtouchI18n>
|
||||
<OptimizePNGs>false</OptimizePNGs>
|
||||
<MtouchExtraArgs>$(DefaultMtouchExtraArgs) -gcc_flags "$(DefaultMtouchGccFlags)"</MtouchExtraArgs>
|
||||
<MtouchHttpClientHandler>NSUrlSessionHandler</MtouchHttpClientHandler>
|
||||
<MtouchVerbosity></MtouchVerbosity>
|
||||
<CodesignKey>iPhone Developer</CodesignKey>
|
||||
<AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup>
|
||||
<!-- Generated via osu.Framework.iOS/generate-symbol-strip-flags.sh -->
|
||||
<GeneratedMtouchSymbolStripFlags>--nosymbolstrip=BASS_FX_BPM_BeatCallbackReset --nosymbolstrip=BASS_FX_BPM_BeatCallbackSet --nosymbolstrip=BASS_FX_BPM_BeatDecodeGet --nosymbolstrip=BASS_FX_BPM_BeatFree --nosymbolstrip=BASS_FX_BPM_BeatGetParameters --nosymbolstrip=BASS_FX_BPM_BeatSetParameters --nosymbolstrip=BASS_FX_BPM_CallbackReset --nosymbolstrip=BASS_FX_BPM_CallbackSet --nosymbolstrip=BASS_FX_BPM_DecodeGet --nosymbolstrip=BASS_FX_BPM_Free --nosymbolstrip=BASS_FX_BPM_Translate --nosymbolstrip=BASS_FX_GetVersion --nosymbolstrip=BASS_FX_ReverseCreate --nosymbolstrip=BASS_FX_ReverseGetSource --nosymbolstrip=BASS_FX_TempoCreate --nosymbolstrip=BASS_FX_TempoGetRateRatio --nosymbolstrip=BASS_FX_TempoGetSource --nosymbolstrip=BASS_Mixer_ChannelFlags --nosymbolstrip=BASS_Mixer_ChannelGetData --nosymbolstrip=BASS_Mixer_ChannelGetEnvelopePos --nosymbolstrip=BASS_Mixer_ChannelGetLevel --nosymbolstrip=BASS_Mixer_ChannelGetLevelEx --nosymbolstrip=BASS_Mixer_ChannelGetMatrix --nosymbolstrip=BASS_Mixer_ChannelGetMixer --nosymbolstrip=BASS_Mixer_ChannelGetPosition --nosymbolstrip=BASS_Mixer_ChannelGetPositionEx --nosymbolstrip=BASS_Mixer_ChannelIsActive --nosymbolstrip=BASS_Mixer_ChannelRemove --nosymbolstrip=BASS_Mixer_ChannelRemoveSync --nosymbolstrip=BASS_Mixer_ChannelSetEnvelope --nosymbolstrip=BASS_Mixer_ChannelSetEnvelopePos --nosymbolstrip=BASS_Mixer_ChannelSetMatrix --nosymbolstrip=BASS_Mixer_ChannelSetMatrixEx --nosymbolstrip=BASS_Mixer_ChannelSetPosition --nosymbolstrip=BASS_Mixer_ChannelSetSync --nosymbolstrip=BASS_Mixer_GetVersion --nosymbolstrip=BASS_Mixer_StreamAddChannel --nosymbolstrip=BASS_Mixer_StreamAddChannelEx --nosymbolstrip=BASS_Mixer_StreamCreate --nosymbolstrip=BASS_Mixer_StreamGetChannels --nosymbolstrip=BASS_Split_StreamCreate --nosymbolstrip=BASS_Split_StreamGetAvailable --nosymbolstrip=BASS_Split_StreamGetSource --nosymbolstrip=BASS_Split_StreamGetSplits --nosymbolstrip=BASS_Split_StreamReset --nosymbolstrip=BASS_Split_StreamResetEx</GeneratedMtouchSymbolStripFlags>
|
||||
<MtouchExtraArgs>--nolinkaway $(GeneratedMtouchSymbolStripFlags)</MtouchExtraArgs>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)' == 'Debug'">
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
<DebugType>full</DebugType>
|
||||
@ -49,18 +51,6 @@
|
||||
<DeviceSpecificBuild>true</DeviceSpecificBuild>
|
||||
<IOSDebuggerPort>28126</IOSDebuggerPort>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<NativeReference Include="$(OutputPath)\libbass.a;$(OutputPath)\libbass_fx.a">
|
||||
<Kind>Static</Kind>
|
||||
<SmartLink>False</SmartLink>
|
||||
<ForceLoad>True</ForceLoad>
|
||||
</NativeReference>
|
||||
<NativeReference Include="$(OutputPath)\libavcodec.a;$(OutputPath)\libavdevice.a;$(OutputPath)\libavfilter.a;$(OutputPath)\libavformat.a;$(OutputPath)\libavutil.a;$(OutputPath)\libswresample.a;$(OutputPath)\libswscale.a">
|
||||
<Kind>Static</Kind>
|
||||
<SmartLink>False</SmartLink>
|
||||
<ForceLoad>True</ForceLoad>
|
||||
</NativeReference>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Reference Include="System" />
|
||||
<Reference Include="System.Xml" />
|
||||
@ -70,7 +60,7 @@
|
||||
<Reference Include="System.Net.Http" />
|
||||
</ItemGroup>
|
||||
<ItemGroup Label="Package References">
|
||||
<PackageReference Include="ppy.osu.Framework.iOS" Version="2021.1118.0" />
|
||||
<PackageReference Include="ppy.osu.Framework.iOS" Version="2021.1119.0" />
|
||||
<PackageReference Include="ppy.osu.Game.Resources" Version="2021.1112.0" />
|
||||
</ItemGroup>
|
||||
<!-- See https://github.com/dotnet/runtime/issues/35988 (can be removed after Xamarin uses net5.0 / net6.0) -->
|
||||
@ -88,17 +78,17 @@
|
||||
</ItemGroup>
|
||||
<!-- Xamarin.iOS does not automatically handle transitive dependencies from NuGet packages. -->
|
||||
<ItemGroup Label="Transitive Dependencies">
|
||||
<PackageReference Include="DiffPlex" Version="1.6.3" />
|
||||
<PackageReference Include="Humanizer" Version="2.11.10" />
|
||||
<PackageReference Include="DiffPlex" Version="1.7.0" />
|
||||
<PackageReference Include="Humanizer" Version="2.13.14" />
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="2.2.6" />
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite.Core" Version="2.2.6" />
|
||||
<PackageReference Include="Newtonsoft.Json" Version="13.0.1" />
|
||||
<PackageReference Include="ppy.osu.Framework" Version="2021.1118.0" />
|
||||
<PackageReference Include="ppy.osu.Framework" Version="2021.1119.0" />
|
||||
<PackageReference Include="SharpCompress" Version="0.30.0" />
|
||||
<PackageReference Include="NUnit" Version="3.13.2" />
|
||||
<PackageReference Include="SharpRaven" Version="2.4.0" />
|
||||
<PackageReference Include="System.ComponentModel.Annotations" Version="5.0.0" />
|
||||
<PackageReference Include="ppy.osu.Framework.NativeLibs" Version="2021.805.0" ExcludeAssets="all" />
|
||||
<PackageReference Include="Realm" Version="10.6.0" />
|
||||
<PackageReference Include="Realm" Version="10.7.1" />
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
|
@ -1,6 +1,7 @@
|
||||
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
||||
// See the LICENCE file in the repository root for full licence text.
|
||||
|
||||
using osu.Framework.iOS;
|
||||
using UIKit;
|
||||
|
||||
namespace osu.iOS
|
||||
@ -9,7 +10,7 @@ namespace osu.iOS
|
||||
{
|
||||
public static void Main(string[] args)
|
||||
{
|
||||
UIApplication.Main(args, "GameUIApplication", "AppDelegate");
|
||||
UIApplication.Main(args, typeof(GameUIApplication), typeof(AppDelegate));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user