mirror of
https://github.com/ppy/osu.git
synced 2024-12-15 02:42:54 +08:00
Merge branch 'master' into migrate-country-rank
This commit is contained in:
commit
2b1ab3576b
2
.github/ISSUE_TEMPLATE/01-bug-issues.md
vendored
2
.github/ISSUE_TEMPLATE/01-bug-issues.md
vendored
@ -13,4 +13,6 @@ about: Issues regarding encountered bugs.
|
|||||||
*please attach logs here, which are located at:*
|
*please attach logs here, which are located at:*
|
||||||
- `%AppData%/osu/logs` *(on Windows),*
|
- `%AppData%/osu/logs` *(on Windows),*
|
||||||
- `~/.local/share/osu/logs` *(on Linux & macOS).*
|
- `~/.local/share/osu/logs` *(on Linux & macOS).*
|
||||||
|
- `Android/Data/sh.ppy.osulazer/logs` *(on Android)*,
|
||||||
|
- on iOS they can be obtained by connecting your device to your desktop and copying the `logs` directory from the app's own document storage using iTunes. (https://support.apple.com/en-us/HT201301#copy-to-computer)
|
||||||
-->
|
-->
|
||||||
|
2
.github/ISSUE_TEMPLATE/02-crash-issues.md
vendored
2
.github/ISSUE_TEMPLATE/02-crash-issues.md
vendored
@ -13,6 +13,8 @@ about: Issues regarding crashes or permanent freezes.
|
|||||||
*please attach logs here, which are located at:*
|
*please attach logs here, which are located at:*
|
||||||
- `%AppData%/osu/logs` *(on Windows),*
|
- `%AppData%/osu/logs` *(on Windows),*
|
||||||
- `~/.local/share/osu/logs` *(on Linux & macOS).*
|
- `~/.local/share/osu/logs` *(on Linux & macOS).*
|
||||||
|
- `Android/Data/sh.ppy.osulazer/logs` *(on Android)*,
|
||||||
|
- on iOS they can be obtained by connecting your device to your desktop and copying the `logs` directory from the app's own document storage using iTunes. (https://support.apple.com/en-us/HT201301#copy-to-computer)
|
||||||
-->
|
-->
|
||||||
|
|
||||||
**Computer Specifications:**
|
**Computer Specifications:**
|
||||||
|
@ -52,6 +52,6 @@
|
|||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="ppy.osu.Game.Resources" Version="2021.211.1" />
|
<PackageReference Include="ppy.osu.Game.Resources" Version="2021.211.1" />
|
||||||
<PackageReference Include="ppy.osu.Framework.Android" Version="2021.226.0" />
|
<PackageReference Include="ppy.osu.Framework.Android" Version="2021.302.0" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
</Project>
|
</Project>
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
<Import Project="..\osu.TestProject.props" />
|
<Import Project="..\osu.TestProject.props" />
|
||||||
<ItemGroup Label="Package References">
|
<ItemGroup Label="Package References">
|
||||||
<PackageReference Include="Appveyor.TestLogger" Version="2.0.0" />
|
<PackageReference Include="Appveyor.TestLogger" Version="2.0.0" />
|
||||||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.8.3" />
|
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.9.1" />
|
||||||
<PackageReference Include="NUnit" Version="3.13.1" />
|
<PackageReference Include="NUnit" Version="3.13.1" />
|
||||||
<PackageReference Include="NUnit3TestAdapter" Version="3.17.0" />
|
<PackageReference Include="NUnit3TestAdapter" Version="3.17.0" />
|
||||||
<PackageReference Update="Microsoft.EntityFrameworkCore.Sqlite" Version="2.1.4" />
|
<PackageReference Update="Microsoft.EntityFrameworkCore.Sqlite" Version="2.1.4" />
|
||||||
|
@ -69,7 +69,7 @@ namespace osu.Game.Rulesets.Catch.Difficulty
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override Skill[] CreateSkills(IBeatmap beatmap)
|
protected override Skill[] CreateSkills(IBeatmap beatmap, Mod[] mods)
|
||||||
{
|
{
|
||||||
halfCatcherWidth = Catcher.CalculateCatchWidth(beatmap.BeatmapInfo.BaseDifficulty) * 0.5f;
|
halfCatcherWidth = Catcher.CalculateCatchWidth(beatmap.BeatmapInfo.BaseDifficulty) * 0.5f;
|
||||||
|
|
||||||
@ -78,7 +78,7 @@ namespace osu.Game.Rulesets.Catch.Difficulty
|
|||||||
|
|
||||||
return new Skill[]
|
return new Skill[]
|
||||||
{
|
{
|
||||||
new Movement(halfCatcherWidth),
|
new Movement(mods, halfCatcherWidth),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -5,6 +5,7 @@ using System;
|
|||||||
using osu.Game.Rulesets.Catch.Difficulty.Preprocessing;
|
using osu.Game.Rulesets.Catch.Difficulty.Preprocessing;
|
||||||
using osu.Game.Rulesets.Difficulty.Preprocessing;
|
using osu.Game.Rulesets.Difficulty.Preprocessing;
|
||||||
using osu.Game.Rulesets.Difficulty.Skills;
|
using osu.Game.Rulesets.Difficulty.Skills;
|
||||||
|
using osu.Game.Rulesets.Mods;
|
||||||
|
|
||||||
namespace osu.Game.Rulesets.Catch.Difficulty.Skills
|
namespace osu.Game.Rulesets.Catch.Difficulty.Skills
|
||||||
{
|
{
|
||||||
@ -25,7 +26,8 @@ namespace osu.Game.Rulesets.Catch.Difficulty.Skills
|
|||||||
private float lastDistanceMoved;
|
private float lastDistanceMoved;
|
||||||
private double lastStrainTime;
|
private double lastStrainTime;
|
||||||
|
|
||||||
public Movement(float halfCatcherWidth)
|
public Movement(Mod[] mods, float halfCatcherWidth)
|
||||||
|
: base(mods)
|
||||||
{
|
{
|
||||||
HalfCatcherWidth = halfCatcherWidth;
|
HalfCatcherWidth = halfCatcherWidth;
|
||||||
}
|
}
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
<Import Project="..\osu.TestProject.props" />
|
<Import Project="..\osu.TestProject.props" />
|
||||||
<ItemGroup Label="Package References">
|
<ItemGroup Label="Package References">
|
||||||
<PackageReference Include="Appveyor.TestLogger" Version="2.0.0" />
|
<PackageReference Include="Appveyor.TestLogger" Version="2.0.0" />
|
||||||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.8.3" />
|
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.9.1" />
|
||||||
<PackageReference Include="NUnit" Version="3.13.1" />
|
<PackageReference Include="NUnit" Version="3.13.1" />
|
||||||
<PackageReference Include="NUnit3TestAdapter" Version="3.17.0" />
|
<PackageReference Include="NUnit3TestAdapter" Version="3.17.0" />
|
||||||
<PackageReference Update="Microsoft.EntityFrameworkCore.Sqlite" Version="2.1.4" />
|
<PackageReference Update="Microsoft.EntityFrameworkCore.Sqlite" Version="2.1.4" />
|
||||||
|
@ -68,9 +68,9 @@ namespace osu.Game.Rulesets.Mania.Difficulty
|
|||||||
// Sorting is done in CreateDifficultyHitObjects, since the full list of hitobjects is required.
|
// Sorting is done in CreateDifficultyHitObjects, since the full list of hitobjects is required.
|
||||||
protected override IEnumerable<DifficultyHitObject> SortObjects(IEnumerable<DifficultyHitObject> input) => input;
|
protected override IEnumerable<DifficultyHitObject> SortObjects(IEnumerable<DifficultyHitObject> input) => input;
|
||||||
|
|
||||||
protected override Skill[] CreateSkills(IBeatmap beatmap) => new Skill[]
|
protected override Skill[] CreateSkills(IBeatmap beatmap, Mod[] mods) => new Skill[]
|
||||||
{
|
{
|
||||||
new Strain(((ManiaBeatmap)beatmap).TotalColumns)
|
new Strain(mods, ((ManiaBeatmap)beatmap).TotalColumns)
|
||||||
};
|
};
|
||||||
|
|
||||||
protected override Mod[] DifficultyAdjustmentMods
|
protected override Mod[] DifficultyAdjustmentMods
|
||||||
|
@ -6,6 +6,7 @@ using osu.Framework.Utils;
|
|||||||
using osu.Game.Rulesets.Difficulty.Preprocessing;
|
using osu.Game.Rulesets.Difficulty.Preprocessing;
|
||||||
using osu.Game.Rulesets.Difficulty.Skills;
|
using osu.Game.Rulesets.Difficulty.Skills;
|
||||||
using osu.Game.Rulesets.Mania.Difficulty.Preprocessing;
|
using osu.Game.Rulesets.Mania.Difficulty.Preprocessing;
|
||||||
|
using osu.Game.Rulesets.Mods;
|
||||||
using osu.Game.Rulesets.Objects;
|
using osu.Game.Rulesets.Objects;
|
||||||
|
|
||||||
namespace osu.Game.Rulesets.Mania.Difficulty.Skills
|
namespace osu.Game.Rulesets.Mania.Difficulty.Skills
|
||||||
@ -24,7 +25,8 @@ namespace osu.Game.Rulesets.Mania.Difficulty.Skills
|
|||||||
private double individualStrain;
|
private double individualStrain;
|
||||||
private double overallStrain;
|
private double overallStrain;
|
||||||
|
|
||||||
public Strain(int totalColumns)
|
public Strain(Mod[] mods, int totalColumns)
|
||||||
|
: base(mods)
|
||||||
{
|
{
|
||||||
holdEndTimes = new double[totalColumns];
|
holdEndTimes = new double[totalColumns];
|
||||||
individualStrains = new double[totalColumns];
|
individualStrains = new double[totalColumns];
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
<Import Project="..\osu.TestProject.props" />
|
<Import Project="..\osu.TestProject.props" />
|
||||||
<ItemGroup Label="Package References">
|
<ItemGroup Label="Package References">
|
||||||
<PackageReference Include="Appveyor.TestLogger" Version="2.0.0" />
|
<PackageReference Include="Appveyor.TestLogger" Version="2.0.0" />
|
||||||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.8.3" />
|
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.9.1" />
|
||||||
<PackageReference Include="NUnit" Version="3.13.1" />
|
<PackageReference Include="NUnit" Version="3.13.1" />
|
||||||
<PackageReference Include="NUnit3TestAdapter" Version="3.17.0" />
|
<PackageReference Include="NUnit3TestAdapter" Version="3.17.0" />
|
||||||
<PackageReference Update="Microsoft.EntityFrameworkCore.Sqlite" Version="2.1.4" />
|
<PackageReference Update="Microsoft.EntityFrameworkCore.Sqlite" Version="2.1.4" />
|
||||||
|
@ -79,10 +79,10 @@ namespace osu.Game.Rulesets.Osu.Difficulty
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override Skill[] CreateSkills(IBeatmap beatmap) => new Skill[]
|
protected override Skill[] CreateSkills(IBeatmap beatmap, Mod[] mods) => new Skill[]
|
||||||
{
|
{
|
||||||
new Aim(),
|
new Aim(mods),
|
||||||
new Speed()
|
new Speed(mods)
|
||||||
};
|
};
|
||||||
|
|
||||||
protected override Mod[] DifficultyAdjustmentMods => new Mod[]
|
protected override Mod[] DifficultyAdjustmentMods => new Mod[]
|
||||||
|
@ -4,6 +4,7 @@
|
|||||||
using System;
|
using System;
|
||||||
using osu.Game.Rulesets.Difficulty.Preprocessing;
|
using osu.Game.Rulesets.Difficulty.Preprocessing;
|
||||||
using osu.Game.Rulesets.Difficulty.Skills;
|
using osu.Game.Rulesets.Difficulty.Skills;
|
||||||
|
using osu.Game.Rulesets.Mods;
|
||||||
using osu.Game.Rulesets.Osu.Difficulty.Preprocessing;
|
using osu.Game.Rulesets.Osu.Difficulty.Preprocessing;
|
||||||
using osu.Game.Rulesets.Osu.Objects;
|
using osu.Game.Rulesets.Osu.Objects;
|
||||||
|
|
||||||
@ -17,6 +18,11 @@ namespace osu.Game.Rulesets.Osu.Difficulty.Skills
|
|||||||
private const double angle_bonus_begin = Math.PI / 3;
|
private const double angle_bonus_begin = Math.PI / 3;
|
||||||
private const double timing_threshold = 107;
|
private const double timing_threshold = 107;
|
||||||
|
|
||||||
|
public Aim(Mod[] mods)
|
||||||
|
: base(mods)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
protected override double SkillMultiplier => 26.25;
|
protected override double SkillMultiplier => 26.25;
|
||||||
protected override double StrainDecayBase => 0.15;
|
protected override double StrainDecayBase => 0.15;
|
||||||
|
|
||||||
|
@ -4,6 +4,7 @@
|
|||||||
using System;
|
using System;
|
||||||
using osu.Game.Rulesets.Difficulty.Preprocessing;
|
using osu.Game.Rulesets.Difficulty.Preprocessing;
|
||||||
using osu.Game.Rulesets.Difficulty.Skills;
|
using osu.Game.Rulesets.Difficulty.Skills;
|
||||||
|
using osu.Game.Rulesets.Mods;
|
||||||
using osu.Game.Rulesets.Osu.Difficulty.Preprocessing;
|
using osu.Game.Rulesets.Osu.Difficulty.Preprocessing;
|
||||||
using osu.Game.Rulesets.Osu.Objects;
|
using osu.Game.Rulesets.Osu.Objects;
|
||||||
|
|
||||||
@ -27,6 +28,11 @@ namespace osu.Game.Rulesets.Osu.Difficulty.Skills
|
|||||||
private const double max_speed_bonus = 45; // ~330BPM
|
private const double max_speed_bonus = 45; // ~330BPM
|
||||||
private const double speed_balancing_factor = 40;
|
private const double speed_balancing_factor = 40;
|
||||||
|
|
||||||
|
public Speed(Mod[] mods)
|
||||||
|
: base(mods)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
protected override double StrainValueOf(DifficultyHitObject current)
|
protected override double StrainValueOf(DifficultyHitObject current)
|
||||||
{
|
{
|
||||||
if (current.BaseObject is Spinner)
|
if (current.BaseObject is Spinner)
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
<Import Project="..\osu.TestProject.props" />
|
<Import Project="..\osu.TestProject.props" />
|
||||||
<ItemGroup Label="Package References">
|
<ItemGroup Label="Package References">
|
||||||
<PackageReference Include="Appveyor.TestLogger" Version="2.0.0" />
|
<PackageReference Include="Appveyor.TestLogger" Version="2.0.0" />
|
||||||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.8.3" />
|
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.9.1" />
|
||||||
<PackageReference Include="NUnit" Version="3.13.1" />
|
<PackageReference Include="NUnit" Version="3.13.1" />
|
||||||
<PackageReference Include="NUnit3TestAdapter" Version="3.17.0" />
|
<PackageReference Include="NUnit3TestAdapter" Version="3.17.0" />
|
||||||
<PackageReference Update="Microsoft.EntityFrameworkCore.Sqlite" Version="2.1.4" />
|
<PackageReference Update="Microsoft.EntityFrameworkCore.Sqlite" Version="2.1.4" />
|
||||||
|
@ -5,6 +5,7 @@ using System;
|
|||||||
using osu.Game.Rulesets.Difficulty.Preprocessing;
|
using osu.Game.Rulesets.Difficulty.Preprocessing;
|
||||||
using osu.Game.Rulesets.Difficulty.Skills;
|
using osu.Game.Rulesets.Difficulty.Skills;
|
||||||
using osu.Game.Rulesets.Difficulty.Utils;
|
using osu.Game.Rulesets.Difficulty.Utils;
|
||||||
|
using osu.Game.Rulesets.Mods;
|
||||||
using osu.Game.Rulesets.Taiko.Difficulty.Preprocessing;
|
using osu.Game.Rulesets.Taiko.Difficulty.Preprocessing;
|
||||||
using osu.Game.Rulesets.Taiko.Objects;
|
using osu.Game.Rulesets.Taiko.Objects;
|
||||||
|
|
||||||
@ -39,6 +40,11 @@ namespace osu.Game.Rulesets.Taiko.Difficulty.Skills
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
private int currentMonoLength;
|
private int currentMonoLength;
|
||||||
|
|
||||||
|
public Colour(Mod[] mods)
|
||||||
|
: base(mods)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
protected override double StrainValueOf(DifficultyHitObject current)
|
protected override double StrainValueOf(DifficultyHitObject current)
|
||||||
{
|
{
|
||||||
// changing from/to a drum roll or a swell does not constitute a colour change.
|
// changing from/to a drum roll or a swell does not constitute a colour change.
|
||||||
|
@ -5,6 +5,7 @@ using System;
|
|||||||
using osu.Game.Rulesets.Difficulty.Preprocessing;
|
using osu.Game.Rulesets.Difficulty.Preprocessing;
|
||||||
using osu.Game.Rulesets.Difficulty.Skills;
|
using osu.Game.Rulesets.Difficulty.Skills;
|
||||||
using osu.Game.Rulesets.Difficulty.Utils;
|
using osu.Game.Rulesets.Difficulty.Utils;
|
||||||
|
using osu.Game.Rulesets.Mods;
|
||||||
using osu.Game.Rulesets.Taiko.Difficulty.Preprocessing;
|
using osu.Game.Rulesets.Taiko.Difficulty.Preprocessing;
|
||||||
using osu.Game.Rulesets.Taiko.Objects;
|
using osu.Game.Rulesets.Taiko.Objects;
|
||||||
|
|
||||||
@ -47,6 +48,11 @@ namespace osu.Game.Rulesets.Taiko.Difficulty.Skills
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
private int notesSinceRhythmChange;
|
private int notesSinceRhythmChange;
|
||||||
|
|
||||||
|
public Rhythm(Mod[] mods)
|
||||||
|
: base(mods)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
protected override double StrainValueOf(DifficultyHitObject current)
|
protected override double StrainValueOf(DifficultyHitObject current)
|
||||||
{
|
{
|
||||||
// drum rolls and swells are exempt.
|
// drum rolls and swells are exempt.
|
||||||
|
@ -5,6 +5,7 @@ using System.Linq;
|
|||||||
using osu.Game.Rulesets.Difficulty.Preprocessing;
|
using osu.Game.Rulesets.Difficulty.Preprocessing;
|
||||||
using osu.Game.Rulesets.Difficulty.Skills;
|
using osu.Game.Rulesets.Difficulty.Skills;
|
||||||
using osu.Game.Rulesets.Difficulty.Utils;
|
using osu.Game.Rulesets.Difficulty.Utils;
|
||||||
|
using osu.Game.Rulesets.Mods;
|
||||||
using osu.Game.Rulesets.Taiko.Difficulty.Preprocessing;
|
using osu.Game.Rulesets.Taiko.Difficulty.Preprocessing;
|
||||||
using osu.Game.Rulesets.Taiko.Objects;
|
using osu.Game.Rulesets.Taiko.Objects;
|
||||||
|
|
||||||
@ -48,8 +49,10 @@ namespace osu.Game.Rulesets.Taiko.Difficulty.Skills
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Creates a <see cref="Stamina"/> skill.
|
/// Creates a <see cref="Stamina"/> skill.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
/// <param name="mods">Mods for use in skill calculations.</param>
|
||||||
/// <param name="rightHand">Whether this instance is performing calculations for the right hand.</param>
|
/// <param name="rightHand">Whether this instance is performing calculations for the right hand.</param>
|
||||||
public Stamina(bool rightHand)
|
public Stamina(Mod[] mods, bool rightHand)
|
||||||
|
: base(mods)
|
||||||
{
|
{
|
||||||
hand = rightHand ? 1 : 0;
|
hand = rightHand ? 1 : 0;
|
||||||
}
|
}
|
||||||
|
@ -29,12 +29,12 @@ namespace osu.Game.Rulesets.Taiko.Difficulty
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override Skill[] CreateSkills(IBeatmap beatmap) => new Skill[]
|
protected override Skill[] CreateSkills(IBeatmap beatmap, Mod[] mods) => new Skill[]
|
||||||
{
|
{
|
||||||
new Colour(),
|
new Colour(mods),
|
||||||
new Rhythm(),
|
new Rhythm(mods),
|
||||||
new Stamina(true),
|
new Stamina(mods, true),
|
||||||
new Stamina(false),
|
new Stamina(mods, false),
|
||||||
};
|
};
|
||||||
|
|
||||||
protected override Mod[] DifficultyAdjustmentMods => new Mod[]
|
protected override Mod[] DifficultyAdjustmentMods => new Mod[]
|
||||||
|
@ -35,7 +35,7 @@ namespace osu.Game.Rulesets.Taiko.Skinning.Legacy
|
|||||||
{
|
{
|
||||||
// if a taiko skin is providing explosion sprites, hide the judgements completely
|
// if a taiko skin is providing explosion sprites, hide the judgements completely
|
||||||
if (hasExplosion.Value)
|
if (hasExplosion.Value)
|
||||||
return Drawable.Empty();
|
return Drawable.Empty().With(d => d.Expire());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!(component is TaikoSkinComponent taikoComponent))
|
if (!(component is TaikoSkinComponent taikoComponent))
|
||||||
@ -118,7 +118,7 @@ namespace osu.Game.Rulesets.Taiko.Skinning.Legacy
|
|||||||
// suppress the default kiai explosion if the skin brings its own sprites.
|
// suppress the default kiai explosion if the skin brings its own sprites.
|
||||||
// the drawable needs to expire as soon as possible to avoid accumulating empty drawables on the playfield.
|
// the drawable needs to expire as soon as possible to avoid accumulating empty drawables on the playfield.
|
||||||
if (hasExplosion.Value)
|
if (hasExplosion.Value)
|
||||||
return Drawable.Empty().With(d => d.LifetimeEnd = double.MinValue);
|
return Drawable.Empty().With(d => d.Expire());
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
|
|
||||||
|
@ -71,7 +71,7 @@
|
|||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup Label="Package References">
|
<ItemGroup Label="Package References">
|
||||||
<PackageReference Include="DeepEqual" Version="2.0.0" />
|
<PackageReference Include="DeepEqual" Version="2.0.0" />
|
||||||
<PackageReference Include="Moq" Version="4.16.0" />
|
<PackageReference Include="Moq" Version="4.16.1" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<Import Project="$(MSBuildExtensionsPath)\Xamarin\Android\Xamarin.Android.CSharp.targets" />
|
<Import Project="$(MSBuildExtensionsPath)\Xamarin\Android\Xamarin.Android.CSharp.targets" />
|
||||||
</Project>
|
</Project>
|
@ -45,7 +45,7 @@
|
|||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup Label="Package References">
|
<ItemGroup Label="Package References">
|
||||||
<PackageReference Include="DeepEqual" Version="2.0.0" />
|
<PackageReference Include="DeepEqual" Version="2.0.0" />
|
||||||
<PackageReference Include="Moq" Version="4.16.0" />
|
<PackageReference Include="Moq" Version="4.16.1" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<Import Project="$(MSBuildExtensionsPath)\Xamarin\iOS\Xamarin.iOS.CSharp.targets" />
|
<Import Project="$(MSBuildExtensionsPath)\Xamarin\iOS\Xamarin.iOS.CSharp.targets" />
|
||||||
</Project>
|
</Project>
|
@ -212,7 +212,7 @@ namespace osu.Game.Tests.NonVisual
|
|||||||
throw new NotImplementedException();
|
throw new NotImplementedException();
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override Skill[] CreateSkills(IBeatmap beatmap)
|
protected override Skill[] CreateSkills(IBeatmap beatmap, Mod[] mods)
|
||||||
{
|
{
|
||||||
throw new NotImplementedException();
|
throw new NotImplementedException();
|
||||||
}
|
}
|
||||||
|
35
osu.Game.Tests/OnlinePlay/StatefulMultiplayerClientTest.cs
Normal file
35
osu.Game.Tests/OnlinePlay/StatefulMultiplayerClientTest.cs
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
// 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 NUnit.Framework;
|
||||||
|
using osu.Framework.Testing;
|
||||||
|
using osu.Game.Tests.Visual.Multiplayer;
|
||||||
|
using osu.Game.Users;
|
||||||
|
|
||||||
|
namespace osu.Game.Tests.OnlinePlay
|
||||||
|
{
|
||||||
|
[HeadlessTest]
|
||||||
|
public class StatefulMultiplayerClientTest : MultiplayerTestScene
|
||||||
|
{
|
||||||
|
[Test]
|
||||||
|
public void TestUserAddedOnJoin()
|
||||||
|
{
|
||||||
|
var user = new User { Id = 33 };
|
||||||
|
|
||||||
|
AddRepeatStep("add user multiple times", () => Client.AddUser(user), 3);
|
||||||
|
AddAssert("room has 2 users", () => Client.Room?.Users.Count == 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void TestUserRemovedOnLeave()
|
||||||
|
{
|
||||||
|
var user = new User { Id = 44 };
|
||||||
|
|
||||||
|
AddStep("add user", () => Client.AddUser(user));
|
||||||
|
AddAssert("room has 2 users", () => Client.Room?.Users.Count == 2);
|
||||||
|
|
||||||
|
AddRepeatStep("remove user multiple times", () => Client.RemoveUser(user), 3);
|
||||||
|
AddAssert("room has 1 user", () => Client.Room?.Users.Count == 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -1,46 +1,41 @@
|
|||||||
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
// 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.
|
// See the LICENCE file in the repository root for full licence text.
|
||||||
|
|
||||||
using NUnit.Framework;
|
using osu.Framework.Allocation;
|
||||||
|
using osu.Game.Online.Multiplayer;
|
||||||
using osu.Game.Screens.OnlinePlay.Components;
|
using osu.Game.Screens.OnlinePlay.Components;
|
||||||
using osu.Game.Users;
|
|
||||||
|
|
||||||
namespace osu.Game.Tests.Visual.Multiplayer
|
namespace osu.Game.Tests.Visual.Multiplayer
|
||||||
{
|
{
|
||||||
public class TestSceneMultiplayer : MultiplayerTestScene
|
public class TestSceneMultiplayer : ScreenTestScene
|
||||||
{
|
{
|
||||||
|
private TestMultiplayer multiplayerScreen;
|
||||||
|
|
||||||
public TestSceneMultiplayer()
|
public TestSceneMultiplayer()
|
||||||
{
|
{
|
||||||
var multi = new TestMultiplayer();
|
AddStep("show", () =>
|
||||||
|
{
|
||||||
|
multiplayerScreen = new TestMultiplayer();
|
||||||
|
|
||||||
AddStep("show", () => LoadScreen(multi));
|
// Needs to be added at a higher level since the multiplayer screen becomes non-current.
|
||||||
AddUntilStep("wait for loaded", () => multi.IsLoaded);
|
Child = multiplayerScreen.Client;
|
||||||
}
|
|
||||||
|
|
||||||
[Test]
|
LoadScreen(multiplayerScreen);
|
||||||
public void TestOneUserJoinedMultipleTimes()
|
});
|
||||||
{
|
|
||||||
var user = new User { Id = 33 };
|
|
||||||
|
|
||||||
AddRepeatStep("add user multiple times", () => Client.AddUser(user), 3);
|
AddUntilStep("wait for loaded", () => multiplayerScreen.IsLoaded);
|
||||||
|
|
||||||
AddAssert("room has 2 users", () => Client.Room?.Users.Count == 2);
|
|
||||||
}
|
|
||||||
|
|
||||||
[Test]
|
|
||||||
public void TestOneUserLeftMultipleTimes()
|
|
||||||
{
|
|
||||||
var user = new User { Id = 44 };
|
|
||||||
|
|
||||||
AddStep("add user", () => Client.AddUser(user));
|
|
||||||
AddAssert("room has 2 users", () => Client.Room?.Users.Count == 2);
|
|
||||||
|
|
||||||
AddRepeatStep("remove user multiple times", () => Client.RemoveUser(user), 3);
|
|
||||||
AddAssert("room has 1 user", () => Client.Room?.Users.Count == 1);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private class TestMultiplayer : Screens.OnlinePlay.Multiplayer.Multiplayer
|
private class TestMultiplayer : Screens.OnlinePlay.Multiplayer.Multiplayer
|
||||||
{
|
{
|
||||||
|
[Cached(typeof(StatefulMultiplayerClient))]
|
||||||
|
public readonly TestMultiplayerClient Client;
|
||||||
|
|
||||||
|
public TestMultiplayer()
|
||||||
|
{
|
||||||
|
Client = new TestMultiplayerClient((TestMultiplayerRoomManager)RoomManager);
|
||||||
|
}
|
||||||
|
|
||||||
protected override RoomManager CreateRoomManager() => new TestMultiplayerRoomManager();
|
protected override RoomManager CreateRoomManager() => new TestMultiplayerRoomManager();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3,12 +3,10 @@
|
|||||||
|
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using NUnit.Framework;
|
using NUnit.Framework;
|
||||||
using osu.Framework.Allocation;
|
|
||||||
using osu.Framework.Screens;
|
using osu.Framework.Screens;
|
||||||
using osu.Framework.Testing;
|
using osu.Framework.Testing;
|
||||||
using osu.Game.Online.Rooms;
|
using osu.Game.Online.Rooms;
|
||||||
using osu.Game.Rulesets.Osu;
|
using osu.Game.Rulesets.Osu;
|
||||||
using osu.Game.Screens.OnlinePlay;
|
|
||||||
using osu.Game.Screens.OnlinePlay.Multiplayer;
|
using osu.Game.Screens.OnlinePlay.Multiplayer;
|
||||||
using osu.Game.Screens.OnlinePlay.Multiplayer.Match;
|
using osu.Game.Screens.OnlinePlay.Multiplayer.Match;
|
||||||
using osu.Game.Tests.Beatmaps;
|
using osu.Game.Tests.Beatmaps;
|
||||||
@ -20,9 +18,6 @@ namespace osu.Game.Tests.Visual.Multiplayer
|
|||||||
{
|
{
|
||||||
private MultiplayerMatchSubScreen screen;
|
private MultiplayerMatchSubScreen screen;
|
||||||
|
|
||||||
[Cached]
|
|
||||||
private OngoingOperationTracker ongoingOperationTracker = new OngoingOperationTracker();
|
|
||||||
|
|
||||||
public TestSceneMultiplayerMatchSubScreen()
|
public TestSceneMultiplayerMatchSubScreen()
|
||||||
: base(false)
|
: base(false)
|
||||||
{
|
{
|
||||||
|
@ -1,10 +1,13 @@
|
|||||||
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
// 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.
|
// See the LICENCE file in the repository root for full licence text.
|
||||||
|
|
||||||
|
using System;
|
||||||
using NUnit.Framework;
|
using NUnit.Framework;
|
||||||
using osu.Framework.Graphics;
|
using osu.Framework.Graphics;
|
||||||
using osu.Framework.Testing;
|
using osu.Framework.Testing;
|
||||||
using osu.Game.Online.Rooms;
|
using osu.Game.Online.Rooms;
|
||||||
|
using osu.Game.Screens.OnlinePlay.Components;
|
||||||
|
using osu.Game.Tests.Beatmaps;
|
||||||
|
|
||||||
namespace osu.Game.Tests.Visual.Multiplayer
|
namespace osu.Game.Tests.Visual.Multiplayer
|
||||||
{
|
{
|
||||||
@ -21,15 +24,15 @@ namespace osu.Game.Tests.Visual.Multiplayer
|
|||||||
{
|
{
|
||||||
createRoomManager().With(d => d.OnLoadComplete += _ =>
|
createRoomManager().With(d => d.OnLoadComplete += _ =>
|
||||||
{
|
{
|
||||||
roomManager.CreateRoom(new Room { Name = { Value = "1" } });
|
roomManager.CreateRoom(createRoom(r => r.Name.Value = "1"));
|
||||||
roomManager.PartRoom();
|
roomManager.PartRoom();
|
||||||
roomManager.CreateRoom(new Room { Name = { Value = "2" } });
|
roomManager.CreateRoom(createRoom(r => r.Name.Value = "2"));
|
||||||
roomManager.PartRoom();
|
roomManager.PartRoom();
|
||||||
roomManager.ClearRooms();
|
roomManager.ClearRooms();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
AddAssert("manager polled for rooms", () => roomManager.Rooms.Count == 2);
|
AddAssert("manager polled for rooms", () => ((RoomManager)roomManager).Rooms.Count == 2);
|
||||||
AddAssert("initial rooms received", () => roomManager.InitialRoomsReceived.Value);
|
AddAssert("initial rooms received", () => roomManager.InitialRoomsReceived.Value);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -40,16 +43,16 @@ namespace osu.Game.Tests.Visual.Multiplayer
|
|||||||
{
|
{
|
||||||
createRoomManager().With(d => d.OnLoadComplete += _ =>
|
createRoomManager().With(d => d.OnLoadComplete += _ =>
|
||||||
{
|
{
|
||||||
roomManager.CreateRoom(new Room());
|
roomManager.CreateRoom(createRoom());
|
||||||
roomManager.PartRoom();
|
roomManager.PartRoom();
|
||||||
roomManager.CreateRoom(new Room());
|
roomManager.CreateRoom(createRoom());
|
||||||
roomManager.PartRoom();
|
roomManager.PartRoom();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
AddStep("disconnect", () => roomContainer.Client.Disconnect());
|
AddStep("disconnect", () => roomContainer.Client.Disconnect());
|
||||||
|
|
||||||
AddAssert("rooms cleared", () => roomManager.Rooms.Count == 0);
|
AddAssert("rooms cleared", () => ((RoomManager)roomManager).Rooms.Count == 0);
|
||||||
AddAssert("initial rooms not received", () => !roomManager.InitialRoomsReceived.Value);
|
AddAssert("initial rooms not received", () => !roomManager.InitialRoomsReceived.Value);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -60,9 +63,9 @@ namespace osu.Game.Tests.Visual.Multiplayer
|
|||||||
{
|
{
|
||||||
createRoomManager().With(d => d.OnLoadComplete += _ =>
|
createRoomManager().With(d => d.OnLoadComplete += _ =>
|
||||||
{
|
{
|
||||||
roomManager.CreateRoom(new Room());
|
roomManager.CreateRoom(createRoom());
|
||||||
roomManager.PartRoom();
|
roomManager.PartRoom();
|
||||||
roomManager.CreateRoom(new Room());
|
roomManager.CreateRoom(createRoom());
|
||||||
roomManager.PartRoom();
|
roomManager.PartRoom();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@ -70,7 +73,7 @@ namespace osu.Game.Tests.Visual.Multiplayer
|
|||||||
AddStep("disconnect", () => roomContainer.Client.Disconnect());
|
AddStep("disconnect", () => roomContainer.Client.Disconnect());
|
||||||
AddStep("connect", () => roomContainer.Client.Connect());
|
AddStep("connect", () => roomContainer.Client.Connect());
|
||||||
|
|
||||||
AddAssert("manager polled for rooms", () => roomManager.Rooms.Count == 2);
|
AddAssert("manager polled for rooms", () => ((RoomManager)roomManager).Rooms.Count == 2);
|
||||||
AddAssert("initial rooms received", () => roomManager.InitialRoomsReceived.Value);
|
AddAssert("initial rooms received", () => roomManager.InitialRoomsReceived.Value);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -81,12 +84,12 @@ namespace osu.Game.Tests.Visual.Multiplayer
|
|||||||
{
|
{
|
||||||
createRoomManager().With(d => d.OnLoadComplete += _ =>
|
createRoomManager().With(d => d.OnLoadComplete += _ =>
|
||||||
{
|
{
|
||||||
roomManager.CreateRoom(new Room());
|
roomManager.CreateRoom(createRoom());
|
||||||
roomManager.ClearRooms();
|
roomManager.ClearRooms();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
AddAssert("manager not polled for rooms", () => roomManager.Rooms.Count == 0);
|
AddAssert("manager not polled for rooms", () => ((RoomManager)roomManager).Rooms.Count == 0);
|
||||||
AddAssert("initial rooms not received", () => !roomManager.InitialRoomsReceived.Value);
|
AddAssert("initial rooms not received", () => !roomManager.InitialRoomsReceived.Value);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -97,7 +100,7 @@ namespace osu.Game.Tests.Visual.Multiplayer
|
|||||||
{
|
{
|
||||||
createRoomManager().With(d => d.OnLoadComplete += _ =>
|
createRoomManager().With(d => d.OnLoadComplete += _ =>
|
||||||
{
|
{
|
||||||
roomManager.CreateRoom(new Room());
|
roomManager.CreateRoom(createRoom());
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -111,7 +114,7 @@ namespace osu.Game.Tests.Visual.Multiplayer
|
|||||||
{
|
{
|
||||||
createRoomManager().With(d => d.OnLoadComplete += _ =>
|
createRoomManager().With(d => d.OnLoadComplete += _ =>
|
||||||
{
|
{
|
||||||
roomManager.CreateRoom(new Room());
|
roomManager.CreateRoom(createRoom());
|
||||||
roomManager.PartRoom();
|
roomManager.PartRoom();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@ -126,7 +129,7 @@ namespace osu.Game.Tests.Visual.Multiplayer
|
|||||||
{
|
{
|
||||||
createRoomManager().With(d => d.OnLoadComplete += _ =>
|
createRoomManager().With(d => d.OnLoadComplete += _ =>
|
||||||
{
|
{
|
||||||
var r = new Room();
|
var r = createRoom();
|
||||||
roomManager.CreateRoom(r);
|
roomManager.CreateRoom(r);
|
||||||
roomManager.PartRoom();
|
roomManager.PartRoom();
|
||||||
roomManager.JoinRoom(r);
|
roomManager.JoinRoom(r);
|
||||||
@ -136,6 +139,21 @@ namespace osu.Game.Tests.Visual.Multiplayer
|
|||||||
AddUntilStep("multiplayer room joined", () => roomContainer.Client.Room != null);
|
AddUntilStep("multiplayer room joined", () => roomContainer.Client.Room != null);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private Room createRoom(Action<Room> initFunc = null)
|
||||||
|
{
|
||||||
|
var room = new Room();
|
||||||
|
|
||||||
|
room.Name.Value = "test room";
|
||||||
|
room.Playlist.Add(new PlaylistItem
|
||||||
|
{
|
||||||
|
Beatmap = { Value = new TestBeatmap(Ruleset.Value).BeatmapInfo },
|
||||||
|
Ruleset = { Value = Ruleset.Value }
|
||||||
|
});
|
||||||
|
|
||||||
|
initFunc?.Invoke(room);
|
||||||
|
return room;
|
||||||
|
}
|
||||||
|
|
||||||
private TestMultiplayerRoomManager createRoomManager()
|
private TestMultiplayerRoomManager createRoomManager()
|
||||||
{
|
{
|
||||||
Child = roomContainer = new TestMultiplayerRoomContainer
|
Child = roomContainer = new TestMultiplayerRoomContainer
|
||||||
|
43
osu.Game.Tests/Visual/Settings/TestSceneSettingsItem.cs
Normal file
43
osu.Game.Tests/Visual/Settings/TestSceneSettingsItem.cs
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
// 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.Linq;
|
||||||
|
using NUnit.Framework;
|
||||||
|
using osu.Framework.Bindables;
|
||||||
|
using osu.Framework.Graphics;
|
||||||
|
using osu.Framework.Testing;
|
||||||
|
using osu.Game.Overlays.Settings;
|
||||||
|
|
||||||
|
namespace osu.Game.Tests.Visual.Settings
|
||||||
|
{
|
||||||
|
[TestFixture]
|
||||||
|
public class TestSceneSettingsItem : OsuTestScene
|
||||||
|
{
|
||||||
|
[Test]
|
||||||
|
public void TestRestoreDefaultValueButtonVisibility()
|
||||||
|
{
|
||||||
|
TestSettingsTextBox textBox = null;
|
||||||
|
|
||||||
|
AddStep("create settings item", () => Child = textBox = new TestSettingsTextBox
|
||||||
|
{
|
||||||
|
Current = new Bindable<string>
|
||||||
|
{
|
||||||
|
Default = "test",
|
||||||
|
Value = "test"
|
||||||
|
}
|
||||||
|
});
|
||||||
|
AddAssert("restore button hidden", () => textBox.RestoreDefaultValueButton.Alpha == 0);
|
||||||
|
|
||||||
|
AddStep("change value from default", () => textBox.Current.Value = "non-default");
|
||||||
|
AddUntilStep("restore button shown", () => textBox.RestoreDefaultValueButton.Alpha > 0);
|
||||||
|
|
||||||
|
AddStep("restore default", () => textBox.Current.SetDefault());
|
||||||
|
AddUntilStep("restore button hidden", () => textBox.RestoreDefaultValueButton.Alpha == 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
private class TestSettingsTextBox : SettingsTextBox
|
||||||
|
{
|
||||||
|
public new Drawable RestoreDefaultValueButton => this.ChildrenOfType<RestoreDefaultValueButton>().Single();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -3,11 +3,11 @@
|
|||||||
<ItemGroup Label="Package References">
|
<ItemGroup Label="Package References">
|
||||||
<PackageReference Include="Appveyor.TestLogger" Version="2.0.0" />
|
<PackageReference Include="Appveyor.TestLogger" Version="2.0.0" />
|
||||||
<PackageReference Include="DeepEqual" Version="2.0.0" />
|
<PackageReference Include="DeepEqual" Version="2.0.0" />
|
||||||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.8.3" />
|
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.9.1" />
|
||||||
<PackageReference Include="NUnit" Version="3.13.1" />
|
<PackageReference Include="NUnit" Version="3.13.1" />
|
||||||
<PackageReference Include="NUnit3TestAdapter" Version="3.17.0" />
|
<PackageReference Include="NUnit3TestAdapter" Version="3.17.0" />
|
||||||
<PackageReference Update="Microsoft.EntityFrameworkCore.Sqlite" Version="2.1.4" />
|
<PackageReference Update="Microsoft.EntityFrameworkCore.Sqlite" Version="2.1.4" />
|
||||||
<PackageReference Include="Moq" Version="4.16.0" />
|
<PackageReference Include="Moq" Version="4.16.1" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<PropertyGroup Label="Project">
|
<PropertyGroup Label="Project">
|
||||||
<OutputType>WinExe</OutputType>
|
<OutputType>WinExe</OutputType>
|
||||||
|
@ -5,7 +5,7 @@
|
|||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<ItemGroup Label="Package References">
|
<ItemGroup Label="Package References">
|
||||||
<PackageReference Include="Appveyor.TestLogger" Version="2.0.0" />
|
<PackageReference Include="Appveyor.TestLogger" Version="2.0.0" />
|
||||||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.8.3" />
|
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.9.1" />
|
||||||
<PackageReference Include="NUnit" Version="3.13.1" />
|
<PackageReference Include="NUnit" Version="3.13.1" />
|
||||||
<PackageReference Include="NUnit3TestAdapter" Version="3.17.0" />
|
<PackageReference Include="NUnit3TestAdapter" Version="3.17.0" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
@ -20,6 +20,7 @@ using osu.Framework.IO.Stores;
|
|||||||
using osu.Framework.Lists;
|
using osu.Framework.Lists;
|
||||||
using osu.Framework.Logging;
|
using osu.Framework.Logging;
|
||||||
using osu.Framework.Platform;
|
using osu.Framework.Platform;
|
||||||
|
using osu.Framework.Statistics;
|
||||||
using osu.Framework.Testing;
|
using osu.Framework.Testing;
|
||||||
using osu.Game.Beatmaps.Formats;
|
using osu.Game.Beatmaps.Formats;
|
||||||
using osu.Game.Database;
|
using osu.Game.Database;
|
||||||
@ -311,6 +312,9 @@ namespace osu.Game.Beatmaps
|
|||||||
|
|
||||||
workingCache.Add(working = new BeatmapManagerWorkingBeatmap(beatmapInfo, this));
|
workingCache.Add(working = new BeatmapManagerWorkingBeatmap(beatmapInfo, this));
|
||||||
|
|
||||||
|
// best effort; may be higher than expected.
|
||||||
|
GlobalStatistics.Get<int>(nameof(Beatmaps), $"Cached {nameof(WorkingBeatmap)}s").Value = workingCache.Count();
|
||||||
|
|
||||||
return working;
|
return working;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -12,7 +12,6 @@ using osu.Framework.Audio;
|
|||||||
using osu.Framework.Audio.Track;
|
using osu.Framework.Audio.Track;
|
||||||
using osu.Framework.Graphics.Textures;
|
using osu.Framework.Graphics.Textures;
|
||||||
using osu.Framework.Logging;
|
using osu.Framework.Logging;
|
||||||
using osu.Framework.Statistics;
|
|
||||||
using osu.Framework.Testing;
|
using osu.Framework.Testing;
|
||||||
using osu.Game.Rulesets;
|
using osu.Game.Rulesets;
|
||||||
using osu.Game.Rulesets.Mods;
|
using osu.Game.Rulesets.Mods;
|
||||||
@ -34,8 +33,6 @@ namespace osu.Game.Beatmaps
|
|||||||
|
|
||||||
protected AudioManager AudioManager { get; }
|
protected AudioManager AudioManager { get; }
|
||||||
|
|
||||||
private static readonly GlobalStatistic<int> total_count = GlobalStatistics.Get<int>(nameof(Beatmaps), $"Total {nameof(WorkingBeatmap)}s");
|
|
||||||
|
|
||||||
protected WorkingBeatmap(BeatmapInfo beatmapInfo, AudioManager audioManager)
|
protected WorkingBeatmap(BeatmapInfo beatmapInfo, AudioManager audioManager)
|
||||||
{
|
{
|
||||||
AudioManager = audioManager;
|
AudioManager = audioManager;
|
||||||
@ -47,8 +44,6 @@ namespace osu.Game.Beatmaps
|
|||||||
waveform = new RecyclableLazy<Waveform>(GetWaveform);
|
waveform = new RecyclableLazy<Waveform>(GetWaveform);
|
||||||
storyboard = new RecyclableLazy<Storyboard>(GetStoryboard);
|
storyboard = new RecyclableLazy<Storyboard>(GetStoryboard);
|
||||||
skin = new RecyclableLazy<ISkin>(GetSkin);
|
skin = new RecyclableLazy<ISkin>(GetSkin);
|
||||||
|
|
||||||
total_count.Value++;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected virtual Track GetVirtualTrack(double emptyLength = 0)
|
protected virtual Track GetVirtualTrack(double emptyLength = 0)
|
||||||
@ -331,11 +326,6 @@ namespace osu.Game.Beatmaps
|
|||||||
protected virtual ISkin GetSkin() => new DefaultSkin();
|
protected virtual ISkin GetSkin() => new DefaultSkin();
|
||||||
private readonly RecyclableLazy<ISkin> skin;
|
private readonly RecyclableLazy<ISkin> skin;
|
||||||
|
|
||||||
~WorkingBeatmap()
|
|
||||||
{
|
|
||||||
total_count.Value--;
|
|
||||||
}
|
|
||||||
|
|
||||||
public class RecyclableLazy<T>
|
public class RecyclableLazy<T>
|
||||||
{
|
{
|
||||||
private Lazy<T> lazy;
|
private Lazy<T> lazy;
|
||||||
|
@ -54,10 +54,5 @@ namespace osu.Game.Database
|
|||||||
Dispose(true);
|
Dispose(true);
|
||||||
GC.SuppressFinalize(this);
|
GC.SuppressFinalize(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
~DatabaseWriteUsage()
|
|
||||||
{
|
|
||||||
Dispose(false);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -9,7 +9,9 @@ using System.Threading.Tasks;
|
|||||||
using Microsoft.AspNetCore.SignalR.Client;
|
using Microsoft.AspNetCore.SignalR.Client;
|
||||||
using osu.Framework.Allocation;
|
using osu.Framework.Allocation;
|
||||||
using osu.Framework.Bindables;
|
using osu.Framework.Bindables;
|
||||||
|
using osu.Game.Beatmaps;
|
||||||
using osu.Game.Online.API;
|
using osu.Game.Online.API;
|
||||||
|
using osu.Game.Online.API.Requests;
|
||||||
using osu.Game.Online.Rooms;
|
using osu.Game.Online.Rooms;
|
||||||
|
|
||||||
namespace osu.Game.Online.Multiplayer
|
namespace osu.Game.Online.Multiplayer
|
||||||
@ -121,6 +123,29 @@ namespace osu.Game.Online.Multiplayer
|
|||||||
return connection.InvokeAsync(nameof(IMultiplayerServer.StartMatch));
|
return connection.InvokeAsync(nameof(IMultiplayerServer.StartMatch));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected override Task<BeatmapSetInfo> GetOnlineBeatmapSet(int beatmapId, CancellationToken cancellationToken = default)
|
||||||
|
{
|
||||||
|
var tcs = new TaskCompletionSource<BeatmapSetInfo>();
|
||||||
|
var req = new GetBeatmapSetRequest(beatmapId, BeatmapSetLookupType.BeatmapId);
|
||||||
|
|
||||||
|
req.Success += res =>
|
||||||
|
{
|
||||||
|
if (cancellationToken.IsCancellationRequested)
|
||||||
|
{
|
||||||
|
tcs.SetCanceled();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
tcs.SetResult(res.ToBeatmapSet(Rulesets));
|
||||||
|
};
|
||||||
|
|
||||||
|
req.Failure += e => tcs.SetException(e);
|
||||||
|
|
||||||
|
API.Queue(req);
|
||||||
|
|
||||||
|
return tcs.Task;
|
||||||
|
}
|
||||||
|
|
||||||
protected override void Dispose(bool isDisposing)
|
protected override void Dispose(bool isDisposing)
|
||||||
{
|
{
|
||||||
base.Dispose(isDisposing);
|
base.Dispose(isDisposing);
|
||||||
|
@ -17,8 +17,6 @@ using osu.Framework.Logging;
|
|||||||
using osu.Game.Beatmaps;
|
using osu.Game.Beatmaps;
|
||||||
using osu.Game.Database;
|
using osu.Game.Database;
|
||||||
using osu.Game.Online.API;
|
using osu.Game.Online.API;
|
||||||
using osu.Game.Online.API.Requests;
|
|
||||||
using osu.Game.Online.API.Requests.Responses;
|
|
||||||
using osu.Game.Online.Rooms;
|
using osu.Game.Online.Rooms;
|
||||||
using osu.Game.Online.Rooms.RoomStatuses;
|
using osu.Game.Online.Rooms.RoomStatuses;
|
||||||
using osu.Game.Rulesets;
|
using osu.Game.Rulesets;
|
||||||
@ -71,7 +69,7 @@ namespace osu.Game.Online.Multiplayer
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// The <see cref="MultiplayerRoomUser"/> corresponding to the local player, if available.
|
/// The <see cref="MultiplayerRoomUser"/> corresponding to the local player, if available.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public MultiplayerRoomUser? LocalUser => Room?.Users.SingleOrDefault(u => u.User?.Id == api.LocalUser.Value.Id);
|
public MultiplayerRoomUser? LocalUser => Room?.Users.SingleOrDefault(u => u.User?.Id == API.LocalUser.Value.Id);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Whether the <see cref="LocalUser"/> is the host in <see cref="Room"/>.
|
/// Whether the <see cref="LocalUser"/> is the host in <see cref="Room"/>.
|
||||||
@ -85,15 +83,15 @@ namespace osu.Game.Online.Multiplayer
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Resolved]
|
||||||
|
protected IAPIProvider API { get; private set; } = null!;
|
||||||
|
|
||||||
|
[Resolved]
|
||||||
|
protected RulesetStore Rulesets { get; private set; } = null!;
|
||||||
|
|
||||||
[Resolved]
|
[Resolved]
|
||||||
private UserLookupCache userLookupCache { get; set; } = null!;
|
private UserLookupCache userLookupCache { get; set; } = null!;
|
||||||
|
|
||||||
[Resolved]
|
|
||||||
private IAPIProvider api { get; set; } = null!;
|
|
||||||
|
|
||||||
[Resolved]
|
|
||||||
private RulesetStore rulesets { get; set; } = null!;
|
|
||||||
|
|
||||||
// Only exists for compatibility with old osu-server-spectator build.
|
// Only exists for compatibility with old osu-server-spectator build.
|
||||||
// Todo: Can be removed on 2021/02/26.
|
// Todo: Can be removed on 2021/02/26.
|
||||||
private long defaultPlaylistItemId;
|
private long defaultPlaylistItemId;
|
||||||
@ -515,30 +513,26 @@ namespace osu.Game.Online.Multiplayer
|
|||||||
|
|
||||||
RoomUpdated?.Invoke();
|
RoomUpdated?.Invoke();
|
||||||
|
|
||||||
var req = new GetBeatmapSetRequest(settings.BeatmapID, BeatmapSetLookupType.BeatmapId);
|
GetOnlineBeatmapSet(settings.BeatmapID, cancellationToken).ContinueWith(set => Schedule(() =>
|
||||||
req.Success += res =>
|
|
||||||
{
|
{
|
||||||
if (cancellationToken.IsCancellationRequested)
|
if (cancellationToken.IsCancellationRequested)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
updatePlaylist(settings, res);
|
updatePlaylist(settings, set.Result);
|
||||||
};
|
}), TaskContinuationOptions.OnlyOnRanToCompletion);
|
||||||
|
|
||||||
api.Queue(req);
|
|
||||||
}, cancellationToken);
|
}, cancellationToken);
|
||||||
|
|
||||||
private void updatePlaylist(MultiplayerRoomSettings settings, APIBeatmapSet onlineSet)
|
private void updatePlaylist(MultiplayerRoomSettings settings, BeatmapSetInfo beatmapSet)
|
||||||
{
|
{
|
||||||
if (Room == null || !Room.Settings.Equals(settings))
|
if (Room == null || !Room.Settings.Equals(settings))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
Debug.Assert(apiRoom != null);
|
Debug.Assert(apiRoom != null);
|
||||||
|
|
||||||
var beatmapSet = onlineSet.ToBeatmapSet(rulesets);
|
|
||||||
var beatmap = beatmapSet.Beatmaps.Single(b => b.OnlineBeatmapID == settings.BeatmapID);
|
var beatmap = beatmapSet.Beatmaps.Single(b => b.OnlineBeatmapID == settings.BeatmapID);
|
||||||
beatmap.MD5Hash = settings.BeatmapChecksum;
|
beatmap.MD5Hash = settings.BeatmapChecksum;
|
||||||
|
|
||||||
var ruleset = rulesets.GetRuleset(settings.RulesetID).CreateInstance();
|
var ruleset = Rulesets.GetRuleset(settings.RulesetID).CreateInstance();
|
||||||
var mods = settings.RequiredMods.Select(m => m.ToMod(ruleset));
|
var mods = settings.RequiredMods.Select(m => m.ToMod(ruleset));
|
||||||
var allowedMods = settings.AllowedMods.Select(m => m.ToMod(ruleset));
|
var allowedMods = settings.AllowedMods.Select(m => m.ToMod(ruleset));
|
||||||
|
|
||||||
@ -568,6 +562,14 @@ namespace osu.Game.Online.Multiplayer
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Retrieves a <see cref="BeatmapSetInfo"/> from an online source.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="beatmapId">The beatmap set ID.</param>
|
||||||
|
/// <param name="cancellationToken">A token to cancel the request.</param>
|
||||||
|
/// <returns>The <see cref="BeatmapSetInfo"/> retrieval task.</returns>
|
||||||
|
protected abstract Task<BeatmapSetInfo> GetOnlineBeatmapSet(int beatmapId, CancellationToken cancellationToken = default);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// For the provided user ID, update whether the user is included in <see cref="CurrentMatchPlayingUserIds"/>.
|
/// For the provided user ID, update whether the user is included in <see cref="CurrentMatchPlayingUserIds"/>.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
@ -361,14 +361,6 @@ namespace osu.Game
|
|||||||
|
|
||||||
PerformFromScreen(screen =>
|
PerformFromScreen(screen =>
|
||||||
{
|
{
|
||||||
// we might already be at song select, so a check is required before performing the load to solo.
|
|
||||||
if (screen is MainMenu)
|
|
||||||
menuScreen.LoadToSolo();
|
|
||||||
|
|
||||||
// we might even already be at the song
|
|
||||||
if (Beatmap.Value.BeatmapSetInfo.Hash == databasedSet.Hash && (difficultyCriteria?.Invoke(Beatmap.Value.BeatmapInfo) ?? true))
|
|
||||||
return;
|
|
||||||
|
|
||||||
// Find beatmaps that match our predicate.
|
// Find beatmaps that match our predicate.
|
||||||
var beatmaps = databasedSet.Beatmaps.Where(b => difficultyCriteria?.Invoke(b) ?? true).ToList();
|
var beatmaps = databasedSet.Beatmaps.Where(b => difficultyCriteria?.Invoke(b) ?? true).ToList();
|
||||||
|
|
||||||
@ -381,9 +373,16 @@ namespace osu.Game
|
|||||||
?? beatmaps.FirstOrDefault(b => b.Ruleset.Equals(Ruleset.Value))
|
?? beatmaps.FirstOrDefault(b => b.Ruleset.Equals(Ruleset.Value))
|
||||||
?? beatmaps.First();
|
?? beatmaps.First();
|
||||||
|
|
||||||
Ruleset.Value = selection.Ruleset;
|
if (screen is IHandlePresentBeatmap presentableScreen)
|
||||||
Beatmap.Value = BeatmapManager.GetWorkingBeatmap(selection);
|
{
|
||||||
}, validScreens: new[] { typeof(SongSelect) });
|
presentableScreen.PresentBeatmap(BeatmapManager.GetWorkingBeatmap(selection), selection.Ruleset);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Ruleset.Value = selection.Ruleset;
|
||||||
|
Beatmap.Value = BeatmapManager.GetWorkingBeatmap(selection);
|
||||||
|
}
|
||||||
|
}, validScreens: new[] { typeof(SongSelect), typeof(IHandlePresentBeatmap) });
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@ -881,13 +880,8 @@ namespace osu.Game
|
|||||||
switch (action)
|
switch (action)
|
||||||
{
|
{
|
||||||
case GlobalAction.ResetInputSettings:
|
case GlobalAction.ResetInputSettings:
|
||||||
var sensitivity = frameworkConfig.GetBindable<double>(FrameworkSetting.CursorSensitivity);
|
frameworkConfig.GetBindable<string>(FrameworkSetting.IgnoredInputHandlers).SetDefault();
|
||||||
|
frameworkConfig.GetBindable<double>(FrameworkSetting.CursorSensitivity).SetDefault();
|
||||||
sensitivity.Disabled = false;
|
|
||||||
sensitivity.Value = 1;
|
|
||||||
sensitivity.Disabled = true;
|
|
||||||
|
|
||||||
frameworkConfig.Set(FrameworkSetting.IgnoredInputHandlers, string.Empty);
|
|
||||||
frameworkConfig.GetBindable<ConfineMouseMode>(FrameworkSetting.ConfineMouseMode).SetDefault();
|
frameworkConfig.GetBindable<ConfineMouseMode>(FrameworkSetting.ConfineMouseMode).SetDefault();
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
|
42
osu.Game/Overlays/Dialog/ConfirmDialog.cs
Normal file
42
osu.Game/Overlays/Dialog/ConfirmDialog.cs
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
// 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 osu.Framework.Graphics.Sprites;
|
||||||
|
|
||||||
|
namespace osu.Game.Overlays.Dialog
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// A dialog which confirms a user action.
|
||||||
|
/// </summary>
|
||||||
|
public class ConfirmDialog : PopupDialog
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Construct a new confirmation dialog.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="message">The description of the action to be displayed to the user.</param>
|
||||||
|
/// <param name="onConfirm">An action to perform on confirmation.</param>
|
||||||
|
/// <param name="onCancel">An optional action to perform on cancel.</param>
|
||||||
|
public ConfirmDialog(string message, Action onConfirm, Action onCancel = null)
|
||||||
|
{
|
||||||
|
HeaderText = message;
|
||||||
|
BodyText = "Last chance to turn back";
|
||||||
|
|
||||||
|
Icon = FontAwesome.Solid.ExclamationTriangle;
|
||||||
|
|
||||||
|
Buttons = new PopupDialogButton[]
|
||||||
|
{
|
||||||
|
new PopupDialogOkButton
|
||||||
|
{
|
||||||
|
Text = @"Yes",
|
||||||
|
Action = onConfirm
|
||||||
|
},
|
||||||
|
new PopupDialogCancelButton
|
||||||
|
{
|
||||||
|
Text = @"Cancel",
|
||||||
|
Action = onCancel
|
||||||
|
},
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -17,7 +17,11 @@ namespace osu.Game.Overlays.Settings.Sections.Input
|
|||||||
protected override string Header => "Mouse";
|
protected override string Header => "Mouse";
|
||||||
|
|
||||||
private readonly BindableBool rawInputToggle = new BindableBool();
|
private readonly BindableBool rawInputToggle = new BindableBool();
|
||||||
private Bindable<double> sensitivityBindable = new BindableDouble();
|
|
||||||
|
private Bindable<double> configSensitivity;
|
||||||
|
|
||||||
|
private Bindable<double> localSensitivity;
|
||||||
|
|
||||||
private Bindable<string> ignoredInputHandlers;
|
private Bindable<string> ignoredInputHandlers;
|
||||||
|
|
||||||
private Bindable<WindowMode> windowMode;
|
private Bindable<WindowMode> windowMode;
|
||||||
@ -26,12 +30,12 @@ namespace osu.Game.Overlays.Settings.Sections.Input
|
|||||||
[BackgroundDependencyLoader]
|
[BackgroundDependencyLoader]
|
||||||
private void load(OsuConfigManager osuConfig, FrameworkConfigManager config)
|
private void load(OsuConfigManager osuConfig, FrameworkConfigManager config)
|
||||||
{
|
{
|
||||||
var configSensitivity = config.GetBindable<double>(FrameworkSetting.CursorSensitivity);
|
|
||||||
|
|
||||||
// use local bindable to avoid changing enabled state of game host's bindable.
|
// use local bindable to avoid changing enabled state of game host's bindable.
|
||||||
sensitivityBindable = configSensitivity.GetUnboundCopy();
|
configSensitivity = config.GetBindable<double>(FrameworkSetting.CursorSensitivity);
|
||||||
configSensitivity.BindValueChanged(val => sensitivityBindable.Value = val.NewValue);
|
localSensitivity = configSensitivity.GetUnboundCopy();
|
||||||
sensitivityBindable.BindValueChanged(val => configSensitivity.Value = val.NewValue);
|
|
||||||
|
windowMode = config.GetBindable<WindowMode>(FrameworkSetting.WindowMode);
|
||||||
|
ignoredInputHandlers = config.GetBindable<string>(FrameworkSetting.IgnoredInputHandlers);
|
||||||
|
|
||||||
Children = new Drawable[]
|
Children = new Drawable[]
|
||||||
{
|
{
|
||||||
@ -43,7 +47,7 @@ namespace osu.Game.Overlays.Settings.Sections.Input
|
|||||||
new SensitivitySetting
|
new SensitivitySetting
|
||||||
{
|
{
|
||||||
LabelText = "Cursor sensitivity",
|
LabelText = "Cursor sensitivity",
|
||||||
Current = sensitivityBindable
|
Current = localSensitivity
|
||||||
},
|
},
|
||||||
new SettingsCheckbox
|
new SettingsCheckbox
|
||||||
{
|
{
|
||||||
@ -66,14 +70,43 @@ namespace osu.Game.Overlays.Settings.Sections.Input
|
|||||||
Current = osuConfig.GetBindable<bool>(OsuSetting.MouseDisableButtons)
|
Current = osuConfig.GetBindable<bool>(OsuSetting.MouseDisableButtons)
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
}
|
||||||
|
|
||||||
windowMode = config.GetBindable<WindowMode>(FrameworkSetting.WindowMode);
|
protected override void LoadComplete()
|
||||||
windowMode.BindValueChanged(mode => confineMouseModeSetting.Alpha = mode.NewValue == WindowMode.Fullscreen ? 0 : 1, true);
|
{
|
||||||
|
base.LoadComplete();
|
||||||
|
|
||||||
|
configSensitivity.BindValueChanged(val =>
|
||||||
|
{
|
||||||
|
var disabled = localSensitivity.Disabled;
|
||||||
|
|
||||||
|
localSensitivity.Disabled = false;
|
||||||
|
localSensitivity.Value = val.NewValue;
|
||||||
|
localSensitivity.Disabled = disabled;
|
||||||
|
}, true);
|
||||||
|
|
||||||
|
localSensitivity.BindValueChanged(val => configSensitivity.Value = val.NewValue);
|
||||||
|
|
||||||
|
windowMode.BindValueChanged(mode =>
|
||||||
|
{
|
||||||
|
var isFullscreen = mode.NewValue == WindowMode.Fullscreen;
|
||||||
|
|
||||||
|
if (isFullscreen)
|
||||||
|
{
|
||||||
|
confineMouseModeSetting.Current.Disabled = true;
|
||||||
|
confineMouseModeSetting.TooltipText = "Not applicable in full screen mode";
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
confineMouseModeSetting.Current.Disabled = false;
|
||||||
|
confineMouseModeSetting.TooltipText = string.Empty;
|
||||||
|
}
|
||||||
|
}, true);
|
||||||
|
|
||||||
if (RuntimeInfo.OS != RuntimeInfo.Platform.Windows)
|
if (RuntimeInfo.OS != RuntimeInfo.Platform.Windows)
|
||||||
{
|
{
|
||||||
rawInputToggle.Disabled = true;
|
rawInputToggle.Disabled = true;
|
||||||
sensitivityBindable.Disabled = true;
|
localSensitivity.Disabled = true;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -86,12 +119,11 @@ namespace osu.Game.Overlays.Settings.Sections.Input
|
|||||||
ignoredInputHandlers.Value = enabled.NewValue ? standard_mouse_handlers : raw_mouse_handler;
|
ignoredInputHandlers.Value = enabled.NewValue ? standard_mouse_handlers : raw_mouse_handler;
|
||||||
};
|
};
|
||||||
|
|
||||||
ignoredInputHandlers = config.GetBindable<string>(FrameworkSetting.IgnoredInputHandlers);
|
|
||||||
ignoredInputHandlers.ValueChanged += handler =>
|
ignoredInputHandlers.ValueChanged += handler =>
|
||||||
{
|
{
|
||||||
bool raw = !handler.NewValue.Contains("Raw");
|
bool raw = !handler.NewValue.Contains("Raw");
|
||||||
rawInputToggle.Value = raw;
|
rawInputToggle.Value = raw;
|
||||||
sensitivityBindable.Disabled = !raw;
|
localSensitivity.Disabled = !raw;
|
||||||
};
|
};
|
||||||
|
|
||||||
ignoredInputHandlers.TriggerChange();
|
ignoredInputHandlers.TriggerChange();
|
||||||
|
@ -121,7 +121,7 @@ namespace osu.Game.Overlays.Settings
|
|||||||
labelText.Alpha = controlWithCurrent.Current.Disabled ? 0.3f : 1;
|
labelText.Alpha = controlWithCurrent.Current.Disabled ? 0.3f : 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
private class RestoreDefaultValueButton : Container, IHasTooltip
|
protected internal class RestoreDefaultValueButton : Container, IHasTooltip
|
||||||
{
|
{
|
||||||
private Bindable<T> bindable;
|
private Bindable<T> bindable;
|
||||||
|
|
||||||
@ -147,6 +147,7 @@ namespace osu.Game.Overlays.Settings
|
|||||||
RelativeSizeAxes = Axes.Y;
|
RelativeSizeAxes = Axes.Y;
|
||||||
Width = SettingsPanel.CONTENT_MARGINS;
|
Width = SettingsPanel.CONTENT_MARGINS;
|
||||||
Alpha = 0f;
|
Alpha = 0f;
|
||||||
|
AlwaysPresent = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
[BackgroundDependencyLoader]
|
[BackgroundDependencyLoader]
|
||||||
|
@ -5,11 +5,9 @@ using System;
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using osu.Framework.Allocation;
|
using osu.Framework.Allocation;
|
||||||
using osu.Framework.Bindables;
|
|
||||||
using osu.Framework.Graphics;
|
using osu.Framework.Graphics;
|
||||||
using osu.Framework.Screens;
|
using osu.Framework.Screens;
|
||||||
using osu.Framework.Threading;
|
using osu.Framework.Threading;
|
||||||
using osu.Game.Beatmaps;
|
|
||||||
using osu.Game.Overlays;
|
using osu.Game.Overlays;
|
||||||
using osu.Game.Overlays.Dialog;
|
using osu.Game.Overlays.Dialog;
|
||||||
using osu.Game.Overlays.Notifications;
|
using osu.Game.Overlays.Notifications;
|
||||||
@ -30,9 +28,6 @@ namespace osu.Game
|
|||||||
[Resolved]
|
[Resolved]
|
||||||
private DialogOverlay dialogOverlay { get; set; }
|
private DialogOverlay dialogOverlay { get; set; }
|
||||||
|
|
||||||
[Resolved]
|
|
||||||
private IBindable<WorkingBeatmap> beatmap { get; set; }
|
|
||||||
|
|
||||||
[Resolved(canBeNull: true)]
|
[Resolved(canBeNull: true)]
|
||||||
private OsuGame game { get; set; }
|
private OsuGame game { get; set; }
|
||||||
|
|
||||||
@ -90,7 +85,7 @@ namespace osu.Game
|
|||||||
var type = current.GetType();
|
var type = current.GetType();
|
||||||
|
|
||||||
// check if we are already at a valid target screen.
|
// check if we are already at a valid target screen.
|
||||||
if (validScreens.Any(t => t.IsAssignableFrom(type)) && !beatmap.Disabled)
|
if (validScreens.Any(t => t.IsAssignableFrom(type)))
|
||||||
{
|
{
|
||||||
finalAction(current);
|
finalAction(current);
|
||||||
Cancel();
|
Cancel();
|
||||||
|
@ -64,7 +64,7 @@ namespace osu.Game.Rulesets.Difficulty
|
|||||||
|
|
||||||
private DifficultyAttributes calculate(IBeatmap beatmap, Mod[] mods, double clockRate)
|
private DifficultyAttributes calculate(IBeatmap beatmap, Mod[] mods, double clockRate)
|
||||||
{
|
{
|
||||||
var skills = CreateSkills(beatmap);
|
var skills = CreateSkills(beatmap, mods);
|
||||||
|
|
||||||
if (!beatmap.HitObjects.Any())
|
if (!beatmap.HitObjects.Any())
|
||||||
return CreateDifficultyAttributes(beatmap, mods, skills, clockRate);
|
return CreateDifficultyAttributes(beatmap, mods, skills, clockRate);
|
||||||
@ -202,7 +202,8 @@ namespace osu.Game.Rulesets.Difficulty
|
|||||||
/// Creates the <see cref="Skill"/>s to calculate the difficulty of an <see cref="IBeatmap"/>.
|
/// Creates the <see cref="Skill"/>s to calculate the difficulty of an <see cref="IBeatmap"/>.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="beatmap">The <see cref="IBeatmap"/> whose difficulty will be calculated.</param>
|
/// <param name="beatmap">The <see cref="IBeatmap"/> whose difficulty will be calculated.</param>
|
||||||
|
/// <param name="mods">Mods to calculate difficulty with.</param>
|
||||||
/// <returns>The <see cref="Skill"/>s.</returns>
|
/// <returns>The <see cref="Skill"/>s.</returns>
|
||||||
protected abstract Skill[] CreateSkills(IBeatmap beatmap);
|
protected abstract Skill[] CreateSkills(IBeatmap beatmap, Mod[] mods);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -6,6 +6,7 @@ using System.Collections.Generic;
|
|||||||
using System.Linq;
|
using System.Linq;
|
||||||
using osu.Game.Rulesets.Difficulty.Preprocessing;
|
using osu.Game.Rulesets.Difficulty.Preprocessing;
|
||||||
using osu.Game.Rulesets.Difficulty.Utils;
|
using osu.Game.Rulesets.Difficulty.Utils;
|
||||||
|
using osu.Game.Rulesets.Mods;
|
||||||
|
|
||||||
namespace osu.Game.Rulesets.Difficulty.Skills
|
namespace osu.Game.Rulesets.Difficulty.Skills
|
||||||
{
|
{
|
||||||
@ -46,10 +47,22 @@ namespace osu.Game.Rulesets.Difficulty.Skills
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
protected double CurrentStrain { get; private set; } = 1;
|
protected double CurrentStrain { get; private set; } = 1;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Mods for use in skill calculations.
|
||||||
|
/// </summary>
|
||||||
|
protected IReadOnlyList<Mod> Mods => mods;
|
||||||
|
|
||||||
private double currentSectionPeak = 1; // We also keep track of the peak strain level in the current section.
|
private double currentSectionPeak = 1; // We also keep track of the peak strain level in the current section.
|
||||||
|
|
||||||
private readonly List<double> strainPeaks = new List<double>();
|
private readonly List<double> strainPeaks = new List<double>();
|
||||||
|
|
||||||
|
private readonly Mod[] mods;
|
||||||
|
|
||||||
|
protected Skill(Mod[] mods)
|
||||||
|
{
|
||||||
|
this.mods = mods;
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Process a <see cref="DifficultyHitObject"/> and update current strain values accordingly.
|
/// Process a <see cref="DifficultyHitObject"/> and update current strain values accordingly.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
@ -150,17 +150,13 @@ namespace osu.Game.Rulesets.Judgements
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (JudgementBody.Drawable is IAnimatableJudgement animatable)
|
if (JudgementBody.Drawable is IAnimatableJudgement animatable)
|
||||||
{
|
|
||||||
var drawableAnimation = (Drawable)animatable;
|
|
||||||
|
|
||||||
animatable.PlayAnimation();
|
animatable.PlayAnimation();
|
||||||
|
|
||||||
// a derived version of DrawableJudgement may be proposing a lifetime.
|
// a derived version of DrawableJudgement may be proposing a lifetime.
|
||||||
// if not adjusted (or the skinned portion requires greater bounds than calculated) use the skinned source's lifetime.
|
// if not adjusted (or the skinned portion requires greater bounds than calculated) use the skinned source's lifetime.
|
||||||
double lastTransformTime = drawableAnimation.LatestTransformEndTime;
|
double lastTransformTime = JudgementBody.Drawable.LatestTransformEndTime;
|
||||||
if (LifetimeEnd == double.MaxValue || lastTransformTime > LifetimeEnd)
|
if (LifetimeEnd == double.MaxValue || lastTransformTime > LifetimeEnd)
|
||||||
LifetimeEnd = lastTransformTime;
|
LifetimeEnd = lastTransformTime;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -63,6 +63,7 @@ namespace osu.Game.Rulesets.UI
|
|||||||
|
|
||||||
~DrawableRulesetDependencies()
|
~DrawableRulesetDependencies()
|
||||||
{
|
{
|
||||||
|
// required to potentially clean up sample store from audio hierarchy.
|
||||||
Dispose(false);
|
Dispose(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
23
osu.Game/Screens/IHandlePresentBeatmap.cs
Normal file
23
osu.Game/Screens/IHandlePresentBeatmap.cs
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
// 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.Game.Beatmaps;
|
||||||
|
using osu.Game.Rulesets;
|
||||||
|
|
||||||
|
namespace osu.Game.Screens
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Denotes a screen which can handle beatmap / ruleset selection via local logic.
|
||||||
|
/// This is used in the <see cref="OsuGame.PresentBeatmap"/> flow to handle cases which require custom logic,
|
||||||
|
/// for instance, if a lease is held on the Beatmap.
|
||||||
|
/// </summary>
|
||||||
|
public interface IHandlePresentBeatmap
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Invoked with a requested beatmap / ruleset for selection.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="beatmap">The beatmap to be selected.</param>
|
||||||
|
/// <param name="ruleset">The ruleset to be selected.</param>
|
||||||
|
void PresentBeatmap(WorkingBeatmap beatmap, RulesetInfo ruleset);
|
||||||
|
}
|
||||||
|
}
|
@ -9,10 +9,15 @@ namespace osu.Game.Screens.Menu
|
|||||||
{
|
{
|
||||||
public class ConfirmExitDialog : PopupDialog
|
public class ConfirmExitDialog : PopupDialog
|
||||||
{
|
{
|
||||||
public ConfirmExitDialog(Action confirm, Action cancel)
|
/// <summary>
|
||||||
|
/// Construct a new exit confirmation dialog.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="onConfirm">An action to perform on confirmation.</param>
|
||||||
|
/// <param name="onCancel">An optional action to perform on cancel.</param>
|
||||||
|
public ConfirmExitDialog(Action onConfirm, Action onCancel = null)
|
||||||
{
|
{
|
||||||
HeaderText = "Are you sure you want to exit?";
|
HeaderText = "Are you sure you want to exit osu!?";
|
||||||
BodyText = "Last chance to back out.";
|
BodyText = "Last chance to turn back";
|
||||||
|
|
||||||
Icon = FontAwesome.Solid.ExclamationTriangle;
|
Icon = FontAwesome.Solid.ExclamationTriangle;
|
||||||
|
|
||||||
@ -20,13 +25,13 @@ namespace osu.Game.Screens.Menu
|
|||||||
{
|
{
|
||||||
new PopupDialogOkButton
|
new PopupDialogOkButton
|
||||||
{
|
{
|
||||||
Text = @"Goodbye",
|
Text = @"Let me out!",
|
||||||
Action = confirm
|
Action = onConfirm
|
||||||
},
|
},
|
||||||
new PopupDialogCancelButton
|
new PopupDialogCancelButton
|
||||||
{
|
{
|
||||||
Text = @"Just a little more",
|
Text = @"Just a little more...",
|
||||||
Action = cancel
|
Action = onCancel
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -9,12 +9,14 @@ using osu.Framework.Bindables;
|
|||||||
using osu.Framework.Graphics;
|
using osu.Framework.Graphics;
|
||||||
using osu.Framework.Platform;
|
using osu.Framework.Platform;
|
||||||
using osu.Framework.Screens;
|
using osu.Framework.Screens;
|
||||||
|
using osu.Game.Beatmaps;
|
||||||
using osu.Game.Configuration;
|
using osu.Game.Configuration;
|
||||||
using osu.Game.Graphics;
|
using osu.Game.Graphics;
|
||||||
using osu.Game.Graphics.Containers;
|
using osu.Game.Graphics.Containers;
|
||||||
using osu.Game.IO;
|
using osu.Game.IO;
|
||||||
using osu.Game.Online.API;
|
using osu.Game.Online.API;
|
||||||
using osu.Game.Overlays;
|
using osu.Game.Overlays;
|
||||||
|
using osu.Game.Rulesets;
|
||||||
using osu.Game.Screens.Backgrounds;
|
using osu.Game.Screens.Backgrounds;
|
||||||
using osu.Game.Screens.Edit;
|
using osu.Game.Screens.Edit;
|
||||||
using osu.Game.Screens.OnlinePlay.Multiplayer;
|
using osu.Game.Screens.OnlinePlay.Multiplayer;
|
||||||
@ -23,7 +25,7 @@ using osu.Game.Screens.Select;
|
|||||||
|
|
||||||
namespace osu.Game.Screens.Menu
|
namespace osu.Game.Screens.Menu
|
||||||
{
|
{
|
||||||
public class MainMenu : OsuScreen
|
public class MainMenu : OsuScreen, IHandlePresentBeatmap
|
||||||
{
|
{
|
||||||
public const float FADE_IN_DURATION = 300;
|
public const float FADE_IN_DURATION = 300;
|
||||||
|
|
||||||
@ -104,7 +106,7 @@ namespace osu.Game.Screens.Menu
|
|||||||
Beatmap.SetDefault();
|
Beatmap.SetDefault();
|
||||||
this.Push(new Editor());
|
this.Push(new Editor());
|
||||||
},
|
},
|
||||||
OnSolo = onSolo,
|
OnSolo = loadSoloSongSelect,
|
||||||
OnMultiplayer = () => this.Push(new Multiplayer()),
|
OnMultiplayer = () => this.Push(new Multiplayer()),
|
||||||
OnPlaylists = () => this.Push(new Playlists()),
|
OnPlaylists = () => this.Push(new Playlists()),
|
||||||
OnExit = confirmAndExit,
|
OnExit = confirmAndExit,
|
||||||
@ -160,9 +162,7 @@ namespace osu.Game.Screens.Menu
|
|||||||
LoadComponentAsync(songSelect = new PlaySongSelect());
|
LoadComponentAsync(songSelect = new PlaySongSelect());
|
||||||
}
|
}
|
||||||
|
|
||||||
public void LoadToSolo() => Schedule(onSolo);
|
private void loadSoloSongSelect() => this.Push(consumeSongSelect());
|
||||||
|
|
||||||
private void onSolo() => this.Push(consumeSongSelect());
|
|
||||||
|
|
||||||
private Screen consumeSongSelect()
|
private Screen consumeSongSelect()
|
||||||
{
|
{
|
||||||
@ -289,5 +289,13 @@ namespace osu.Game.Screens.Menu
|
|||||||
this.FadeOut(3000);
|
this.FadeOut(3000);
|
||||||
return base.OnExiting(next);
|
return base.OnExiting(next);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void PresentBeatmap(WorkingBeatmap beatmap, RulesetInfo ruleset)
|
||||||
|
{
|
||||||
|
Beatmap.Value = beatmap;
|
||||||
|
Ruleset.Value = ruleset;
|
||||||
|
|
||||||
|
Schedule(loadSoloSongSelect);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -4,9 +4,11 @@
|
|||||||
using osu.Framework.Allocation;
|
using osu.Framework.Allocation;
|
||||||
using osu.Framework.Logging;
|
using osu.Framework.Logging;
|
||||||
using osu.Framework.Screens;
|
using osu.Framework.Screens;
|
||||||
|
using osu.Game.Beatmaps;
|
||||||
using osu.Game.Graphics.UserInterface;
|
using osu.Game.Graphics.UserInterface;
|
||||||
using osu.Game.Online.Multiplayer;
|
using osu.Game.Online.Multiplayer;
|
||||||
using osu.Game.Online.Rooms;
|
using osu.Game.Online.Rooms;
|
||||||
|
using osu.Game.Rulesets;
|
||||||
using osu.Game.Rulesets.Mods;
|
using osu.Game.Rulesets.Mods;
|
||||||
using osu.Game.Screens.Select;
|
using osu.Game.Screens.Select;
|
||||||
|
|
||||||
@ -19,6 +21,23 @@ namespace osu.Game.Screens.OnlinePlay.Multiplayer
|
|||||||
|
|
||||||
private LoadingLayer loadingLayer;
|
private LoadingLayer loadingLayer;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Construct a new instance of multiplayer song select.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="beatmap">An optional initial beatmap selection to perform.</param>
|
||||||
|
/// <param name="ruleset">An optional initial ruleset selection to perform.</param>
|
||||||
|
public MultiplayerMatchSongSelect(WorkingBeatmap beatmap = null, RulesetInfo ruleset = null)
|
||||||
|
{
|
||||||
|
if (beatmap != null || ruleset != null)
|
||||||
|
{
|
||||||
|
Schedule(() =>
|
||||||
|
{
|
||||||
|
if (beatmap != null) Beatmap.Value = beatmap;
|
||||||
|
if (ruleset != null) Ruleset.Value = ruleset;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
[BackgroundDependencyLoader]
|
[BackgroundDependencyLoader]
|
||||||
private void load()
|
private void load()
|
||||||
{
|
{
|
||||||
|
@ -12,9 +12,13 @@ using osu.Framework.Graphics;
|
|||||||
using osu.Framework.Graphics.Containers;
|
using osu.Framework.Graphics.Containers;
|
||||||
using osu.Framework.Screens;
|
using osu.Framework.Screens;
|
||||||
using osu.Framework.Threading;
|
using osu.Framework.Threading;
|
||||||
|
using osu.Game.Beatmaps;
|
||||||
using osu.Game.Configuration;
|
using osu.Game.Configuration;
|
||||||
using osu.Game.Online.Multiplayer;
|
using osu.Game.Online.Multiplayer;
|
||||||
using osu.Game.Online.Rooms;
|
using osu.Game.Online.Rooms;
|
||||||
|
using osu.Game.Overlays;
|
||||||
|
using osu.Game.Overlays.Dialog;
|
||||||
|
using osu.Game.Rulesets;
|
||||||
using osu.Game.Rulesets.Mods;
|
using osu.Game.Rulesets.Mods;
|
||||||
using osu.Game.Screens.OnlinePlay.Components;
|
using osu.Game.Screens.OnlinePlay.Components;
|
||||||
using osu.Game.Screens.OnlinePlay.Match;
|
using osu.Game.Screens.OnlinePlay.Match;
|
||||||
@ -29,7 +33,7 @@ using ParticipantsList = osu.Game.Screens.OnlinePlay.Multiplayer.Participants.Pa
|
|||||||
namespace osu.Game.Screens.OnlinePlay.Multiplayer
|
namespace osu.Game.Screens.OnlinePlay.Multiplayer
|
||||||
{
|
{
|
||||||
[Cached]
|
[Cached]
|
||||||
public class MultiplayerMatchSubScreen : RoomSubScreen
|
public class MultiplayerMatchSubScreen : RoomSubScreen, IHandlePresentBeatmap
|
||||||
{
|
{
|
||||||
public override string Title { get; }
|
public override string Title { get; }
|
||||||
|
|
||||||
@ -279,14 +283,36 @@ namespace osu.Game.Screens.OnlinePlay.Multiplayer
|
|||||||
Mods.Value = client.LocalUser.Mods.Select(m => m.ToMod(ruleset)).Concat(SelectedItem.Value.RequiredMods).ToList();
|
Mods.Value = client.LocalUser.Mods.Select(m => m.ToMod(ruleset)).Concat(SelectedItem.Value.RequiredMods).ToList();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Resolved(canBeNull: true)]
|
||||||
|
private DialogOverlay dialogOverlay { get; set; }
|
||||||
|
|
||||||
|
private bool exitConfirmed;
|
||||||
|
|
||||||
public override bool OnBackButton()
|
public override bool OnBackButton()
|
||||||
{
|
{
|
||||||
if (client.Room != null && settingsOverlay.State.Value == Visibility.Visible)
|
if (client.Room == null)
|
||||||
|
{
|
||||||
|
// room has not been created yet; exit immediately.
|
||||||
|
return base.OnBackButton();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (settingsOverlay.State.Value == Visibility.Visible)
|
||||||
{
|
{
|
||||||
settingsOverlay.Hide();
|
settingsOverlay.Hide();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!exitConfirmed && dialogOverlay != null)
|
||||||
|
{
|
||||||
|
dialogOverlay.Push(new ConfirmDialog("Are you sure you want to leave this multiplayer match?", () =>
|
||||||
|
{
|
||||||
|
exitConfirmed = true;
|
||||||
|
this.Exit();
|
||||||
|
}));
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
return base.OnBackButton();
|
return base.OnBackButton();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -394,5 +420,21 @@ namespace osu.Game.Screens.OnlinePlay.Multiplayer
|
|||||||
|
|
||||||
modSettingChangeTracker?.Dispose();
|
modSettingChangeTracker?.Dispose();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void PresentBeatmap(WorkingBeatmap beatmap, RulesetInfo ruleset)
|
||||||
|
{
|
||||||
|
if (!this.IsCurrentScreen())
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (!client.IsHost)
|
||||||
|
{
|
||||||
|
// todo: should handle this when the request queue is implemented.
|
||||||
|
// if we decide that the presentation should exit the user from the multiplayer game, the PresentBeatmap
|
||||||
|
// flow may need to change to support an "unable to present" return value.
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.Push(new MultiplayerMatchSongSelect(beatmap, ruleset));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -84,14 +84,15 @@ namespace osu.Game.Screens.Play.HUD
|
|||||||
{
|
{
|
||||||
InternalChildren = new[]
|
InternalChildren = new[]
|
||||||
{
|
{
|
||||||
displayedCountSpriteText = createSpriteText().With(s =>
|
|
||||||
{
|
|
||||||
s.Alpha = 0;
|
|
||||||
}),
|
|
||||||
popOutCount = createSpriteText().With(s =>
|
popOutCount = createSpriteText().With(s =>
|
||||||
{
|
{
|
||||||
s.Alpha = 0;
|
s.Alpha = 0;
|
||||||
s.Margin = new MarginPadding(0.05f);
|
s.Margin = new MarginPadding(0.05f);
|
||||||
|
s.Blending = BlendingParameters.Additive;
|
||||||
|
}),
|
||||||
|
displayedCountSpriteText = createSpriteText().With(s =>
|
||||||
|
{
|
||||||
|
s.Alpha = 0;
|
||||||
})
|
})
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -36,6 +36,7 @@ namespace osu.Game.Skinning
|
|||||||
|
|
||||||
~Skin()
|
~Skin()
|
||||||
{
|
{
|
||||||
|
// required to potentially clean up sample store from audio hierarchy.
|
||||||
Dispose(false);
|
Dispose(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -7,8 +7,10 @@ using osu.Framework.Bindables;
|
|||||||
using osu.Framework.Graphics;
|
using osu.Framework.Graphics;
|
||||||
using osu.Framework.Graphics.Containers;
|
using osu.Framework.Graphics.Containers;
|
||||||
using osu.Game.Online.Multiplayer;
|
using osu.Game.Online.Multiplayer;
|
||||||
|
using osu.Game.Online.Rooms;
|
||||||
using osu.Game.Screens.OnlinePlay;
|
using osu.Game.Screens.OnlinePlay;
|
||||||
using osu.Game.Screens.OnlinePlay.Lounge.Components;
|
using osu.Game.Screens.OnlinePlay.Lounge.Components;
|
||||||
|
using osu.Game.Tests.Beatmaps;
|
||||||
|
|
||||||
namespace osu.Game.Tests.Visual.Multiplayer
|
namespace osu.Game.Tests.Visual.Multiplayer
|
||||||
{
|
{
|
||||||
@ -48,7 +50,16 @@ namespace osu.Game.Tests.Visual.Multiplayer
|
|||||||
RoomManager.Schedule(() => RoomManager.PartRoom());
|
RoomManager.Schedule(() => RoomManager.PartRoom());
|
||||||
|
|
||||||
if (joinRoom)
|
if (joinRoom)
|
||||||
|
{
|
||||||
|
Room.Name.Value = "test name";
|
||||||
|
Room.Playlist.Add(new PlaylistItem
|
||||||
|
{
|
||||||
|
Beatmap = { Value = new TestBeatmap(Ruleset.Value).BeatmapInfo },
|
||||||
|
Ruleset = { Value = Ruleset.Value }
|
||||||
|
});
|
||||||
|
|
||||||
RoomManager.Schedule(() => RoomManager.CreateRoom(Room));
|
RoomManager.Schedule(() => RoomManager.CreateRoom(Room));
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
public override void SetUpSteps()
|
public override void SetUpSteps()
|
||||||
|
@ -3,12 +3,15 @@
|
|||||||
|
|
||||||
#nullable enable
|
#nullable enable
|
||||||
|
|
||||||
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
using System.Threading;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using osu.Framework.Allocation;
|
using osu.Framework.Allocation;
|
||||||
using osu.Framework.Bindables;
|
using osu.Framework.Bindables;
|
||||||
|
using osu.Game.Beatmaps;
|
||||||
using osu.Game.Online.API;
|
using osu.Game.Online.API;
|
||||||
using osu.Game.Online.Multiplayer;
|
using osu.Game.Online.Multiplayer;
|
||||||
using osu.Game.Online.Rooms;
|
using osu.Game.Online.Rooms;
|
||||||
@ -25,6 +28,16 @@ namespace osu.Game.Tests.Visual.Multiplayer
|
|||||||
[Resolved]
|
[Resolved]
|
||||||
private IAPIProvider api { get; set; } = null!;
|
private IAPIProvider api { get; set; } = null!;
|
||||||
|
|
||||||
|
[Resolved]
|
||||||
|
private BeatmapManager beatmaps { get; set; } = null!;
|
||||||
|
|
||||||
|
private readonly TestMultiplayerRoomManager roomManager;
|
||||||
|
|
||||||
|
public TestMultiplayerClient(TestMultiplayerRoomManager roomManager)
|
||||||
|
{
|
||||||
|
this.roomManager = roomManager;
|
||||||
|
}
|
||||||
|
|
||||||
public void Connect() => isConnected.Value = true;
|
public void Connect() => isConnected.Value = true;
|
||||||
|
|
||||||
public void Disconnect() => isConnected.Value = false;
|
public void Disconnect() => isConnected.Value = false;
|
||||||
@ -89,13 +102,28 @@ namespace osu.Game.Tests.Visual.Multiplayer
|
|||||||
|
|
||||||
protected override Task<MultiplayerRoom> JoinRoom(long roomId)
|
protected override Task<MultiplayerRoom> JoinRoom(long roomId)
|
||||||
{
|
{
|
||||||
var user = new MultiplayerRoomUser(api.LocalUser.Value.Id) { User = api.LocalUser.Value };
|
var apiRoom = roomManager.Rooms.Single(r => r.RoomID.Value == roomId);
|
||||||
|
|
||||||
var room = new MultiplayerRoom(roomId);
|
var user = new MultiplayerRoomUser(api.LocalUser.Value.Id)
|
||||||
room.Users.Add(user);
|
{
|
||||||
|
User = api.LocalUser.Value
|
||||||
|
};
|
||||||
|
|
||||||
if (room.Users.Count == 1)
|
var room = new MultiplayerRoom(roomId)
|
||||||
room.Host = user;
|
{
|
||||||
|
Settings =
|
||||||
|
{
|
||||||
|
Name = apiRoom.Name.Value,
|
||||||
|
BeatmapID = apiRoom.Playlist.Last().BeatmapID,
|
||||||
|
RulesetID = apiRoom.Playlist.Last().RulesetID,
|
||||||
|
BeatmapChecksum = apiRoom.Playlist.Last().Beatmap.Value.MD5Hash,
|
||||||
|
RequiredMods = apiRoom.Playlist.Last().RequiredMods.Select(m => new APIMod(m)).ToArray(),
|
||||||
|
AllowedMods = apiRoom.Playlist.Last().AllowedMods.Select(m => new APIMod(m)).ToArray(),
|
||||||
|
PlaylistItemId = apiRoom.Playlist.Last().ID
|
||||||
|
},
|
||||||
|
Users = { user },
|
||||||
|
Host = user
|
||||||
|
};
|
||||||
|
|
||||||
return Task.FromResult(room);
|
return Task.FromResult(room);
|
||||||
}
|
}
|
||||||
@ -150,5 +178,19 @@ namespace osu.Game.Tests.Visual.Multiplayer
|
|||||||
|
|
||||||
return ((IMultiplayerClient)this).LoadRequested();
|
return ((IMultiplayerClient)this).LoadRequested();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected override Task<BeatmapSetInfo> GetOnlineBeatmapSet(int beatmapId, CancellationToken cancellationToken = default)
|
||||||
|
{
|
||||||
|
Debug.Assert(Room != null);
|
||||||
|
|
||||||
|
var apiRoom = roomManager.Rooms.Single(r => r.RoomID.Value == Room.RoomID);
|
||||||
|
var set = apiRoom.Playlist.FirstOrDefault(p => p.BeatmapID == beatmapId)?.Beatmap.Value.BeatmapSet
|
||||||
|
?? beatmaps.QueryBeatmap(b => b.OnlineBeatmapID == beatmapId)?.BeatmapSet;
|
||||||
|
|
||||||
|
if (set == null)
|
||||||
|
throw new InvalidOperationException("Beatmap not found.");
|
||||||
|
|
||||||
|
return Task.FromResult(set);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -32,11 +32,15 @@ namespace osu.Game.Tests.Visual.Multiplayer
|
|||||||
{
|
{
|
||||||
RelativeSizeAxes = Axes.Both;
|
RelativeSizeAxes = Axes.Both;
|
||||||
|
|
||||||
|
RoomManager = new TestMultiplayerRoomManager();
|
||||||
|
Client = new TestMultiplayerClient(RoomManager);
|
||||||
|
OngoingOperationTracker = new OngoingOperationTracker();
|
||||||
|
|
||||||
AddRangeInternal(new Drawable[]
|
AddRangeInternal(new Drawable[]
|
||||||
{
|
{
|
||||||
Client = new TestMultiplayerClient(),
|
Client,
|
||||||
RoomManager = new TestMultiplayerRoomManager(),
|
RoomManager,
|
||||||
OngoingOperationTracker = new OngoingOperationTracker(),
|
OngoingOperationTracker,
|
||||||
content = new Container { RelativeSizeAxes = Axes.Both }
|
content = new Container { RelativeSizeAxes = Axes.Both }
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -27,7 +27,7 @@ namespace osu.Game.Tests.Visual.Multiplayer
|
|||||||
[Cached]
|
[Cached]
|
||||||
public readonly Bindable<FilterCriteria> Filter = new Bindable<FilterCriteria>(new FilterCriteria());
|
public readonly Bindable<FilterCriteria> Filter = new Bindable<FilterCriteria>(new FilterCriteria());
|
||||||
|
|
||||||
private readonly List<Room> rooms = new List<Room>();
|
public new readonly List<Room> Rooms = new List<Room>();
|
||||||
|
|
||||||
protected override void LoadComplete()
|
protected override void LoadComplete()
|
||||||
{
|
{
|
||||||
@ -35,6 +35,7 @@ namespace osu.Game.Tests.Visual.Multiplayer
|
|||||||
|
|
||||||
int currentScoreId = 0;
|
int currentScoreId = 0;
|
||||||
int currentRoomId = 0;
|
int currentRoomId = 0;
|
||||||
|
int currentPlaylistItemId = 0;
|
||||||
|
|
||||||
((DummyAPIAccess)api).HandleRequest = req =>
|
((DummyAPIAccess)api).HandleRequest = req =>
|
||||||
{
|
{
|
||||||
@ -46,7 +47,10 @@ namespace osu.Game.Tests.Visual.Multiplayer
|
|||||||
createdRoom.CopyFrom(createRoomRequest.Room);
|
createdRoom.CopyFrom(createRoomRequest.Room);
|
||||||
createdRoom.RoomID.Value ??= currentRoomId++;
|
createdRoom.RoomID.Value ??= currentRoomId++;
|
||||||
|
|
||||||
rooms.Add(createdRoom);
|
for (int i = 0; i < createdRoom.Playlist.Count; i++)
|
||||||
|
createdRoom.Playlist[i].ID = currentPlaylistItemId++;
|
||||||
|
|
||||||
|
Rooms.Add(createdRoom);
|
||||||
createRoomRequest.TriggerSuccess(createdRoom);
|
createRoomRequest.TriggerSuccess(createdRoom);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -61,7 +65,7 @@ namespace osu.Game.Tests.Visual.Multiplayer
|
|||||||
case GetRoomsRequest getRoomsRequest:
|
case GetRoomsRequest getRoomsRequest:
|
||||||
var roomsWithoutParticipants = new List<Room>();
|
var roomsWithoutParticipants = new List<Room>();
|
||||||
|
|
||||||
foreach (var r in rooms)
|
foreach (var r in Rooms)
|
||||||
{
|
{
|
||||||
var newRoom = new Room();
|
var newRoom = new Room();
|
||||||
|
|
||||||
@ -75,7 +79,7 @@ namespace osu.Game.Tests.Visual.Multiplayer
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case GetRoomRequest getRoomRequest:
|
case GetRoomRequest getRoomRequest:
|
||||||
getRoomRequest.TriggerSuccess(rooms.Single(r => r.RoomID.Value == getRoomRequest.RoomId));
|
getRoomRequest.TriggerSuccess(Rooms.Single(r => r.RoomID.Value == getRoomRequest.RoomId));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case GetBeatmapSetRequest getBeatmapSetRequest:
|
case GetBeatmapSetRequest getBeatmapSetRequest:
|
||||||
|
@ -86,11 +86,6 @@ namespace osu.Game.Utils
|
|||||||
|
|
||||||
#region Disposal
|
#region Disposal
|
||||||
|
|
||||||
~SentryLogger()
|
|
||||||
{
|
|
||||||
Dispose(false);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void Dispose()
|
public void Dispose()
|
||||||
{
|
{
|
||||||
Dispose(true);
|
Dispose(true);
|
||||||
|
@ -22,17 +22,17 @@
|
|||||||
<PackageReference Include="Humanizer" Version="2.8.26" />
|
<PackageReference Include="Humanizer" Version="2.8.26" />
|
||||||
<PackageReference Include="MessagePack" Version="2.2.85" />
|
<PackageReference Include="MessagePack" Version="2.2.85" />
|
||||||
<PackageReference Include="Microsoft.AspNetCore.SignalR.Client" Version="5.0.2" />
|
<PackageReference Include="Microsoft.AspNetCore.SignalR.Client" Version="5.0.2" />
|
||||||
<PackageReference Include="Microsoft.AspNetCore.SignalR.Protocols.MessagePack" Version="5.0.2" />
|
<PackageReference Include="Microsoft.AspNetCore.SignalR.Protocols.MessagePack" Version="5.0.3" />
|
||||||
<PackageReference Include="Microsoft.AspNetCore.SignalR.Protocols.NewtonsoftJson" Version="5.0.2" />
|
<PackageReference Include="Microsoft.AspNetCore.SignalR.Protocols.NewtonsoftJson" Version="5.0.2" />
|
||||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="2.2.6" />
|
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="2.2.6" />
|
||||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite.Core" Version="2.2.6" />
|
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite.Core" Version="2.2.6" />
|
||||||
<PackageReference Include="Microsoft.Extensions.Configuration.Abstractions" Version="2.2.0" />
|
<PackageReference Include="Microsoft.Extensions.Configuration.Abstractions" Version="2.2.0" />
|
||||||
<PackageReference Include="Microsoft.NETCore.Targets" Version="3.1.0" />
|
<PackageReference Include="Microsoft.NETCore.Targets" Version="3.1.0" />
|
||||||
<PackageReference Include="Newtonsoft.Json" Version="12.0.3" />
|
<PackageReference Include="Newtonsoft.Json" Version="12.0.3" />
|
||||||
<PackageReference Include="ppy.osu.Framework" Version="2021.226.0" />
|
<PackageReference Include="ppy.osu.Framework" Version="2021.302.0" />
|
||||||
<PackageReference Include="ppy.osu.Game.Resources" Version="2021.211.1" />
|
<PackageReference Include="ppy.osu.Game.Resources" Version="2021.211.1" />
|
||||||
<PackageReference Include="Sentry" Version="3.0.1" />
|
<PackageReference Include="Sentry" Version="3.0.7" />
|
||||||
<PackageReference Include="SharpCompress" Version="0.27.1" />
|
<PackageReference Include="SharpCompress" Version="0.28.1" />
|
||||||
<PackageReference Include="NUnit" Version="3.13.1" />
|
<PackageReference Include="NUnit" Version="3.13.1" />
|
||||||
<PackageReference Include="System.ComponentModel.Annotations" Version="5.0.0" />
|
<PackageReference Include="System.ComponentModel.Annotations" Version="5.0.0" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
@ -70,7 +70,7 @@
|
|||||||
<Reference Include="System.Net.Http" />
|
<Reference Include="System.Net.Http" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup Label="Package References">
|
<ItemGroup Label="Package References">
|
||||||
<PackageReference Include="ppy.osu.Framework.iOS" Version="2021.226.0" />
|
<PackageReference Include="ppy.osu.Framework.iOS" Version="2021.302.0" />
|
||||||
<PackageReference Include="ppy.osu.Game.Resources" Version="2021.211.1" />
|
<PackageReference Include="ppy.osu.Game.Resources" Version="2021.211.1" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<!-- See https://github.com/dotnet/runtime/issues/35988 (can be removed after Xamarin uses net5.0 / net6.0) -->
|
<!-- See https://github.com/dotnet/runtime/issues/35988 (can be removed after Xamarin uses net5.0 / net6.0) -->
|
||||||
@ -80,7 +80,7 @@
|
|||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="Microsoft.AspNetCore.SignalR.Client" Version="3.0.3" />
|
<PackageReference Include="Microsoft.AspNetCore.SignalR.Client" Version="3.0.3" />
|
||||||
<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="3.0.3" />
|
<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="3.0.3" />
|
||||||
<PackageReference Include="Microsoft.AspNetCore.SignalR.Protocols.MessagePack" Version="3.0.3" />
|
<PackageReference Include="Microsoft.AspNetCore.SignalR.Protocols.MessagePack" Version="5.0.3" />
|
||||||
<PackageReference Include="MessagePack" Version="1.7.3.7" />
|
<PackageReference Include="MessagePack" Version="1.7.3.7" />
|
||||||
<PackageReference Include="MessagePack.Annotations" Version="2.2.85" />
|
<PackageReference Include="MessagePack.Annotations" Version="2.2.85" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
@ -91,8 +91,8 @@
|
|||||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="2.2.6" />
|
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="2.2.6" />
|
||||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite.Core" Version="2.2.6" />
|
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite.Core" Version="2.2.6" />
|
||||||
<PackageReference Include="Newtonsoft.Json" Version="12.0.3" />
|
<PackageReference Include="Newtonsoft.Json" Version="12.0.3" />
|
||||||
<PackageReference Include="ppy.osu.Framework" Version="2021.226.0" />
|
<PackageReference Include="ppy.osu.Framework" Version="2021.302.0" />
|
||||||
<PackageReference Include="SharpCompress" Version="0.27.1" />
|
<PackageReference Include="SharpCompress" Version="0.28.1" />
|
||||||
<PackageReference Include="NUnit" Version="3.12.0" />
|
<PackageReference Include="NUnit" Version="3.12.0" />
|
||||||
<PackageReference Include="SharpRaven" Version="2.4.0" />
|
<PackageReference Include="SharpRaven" Version="2.4.0" />
|
||||||
<PackageReference Include="System.ComponentModel.Annotations" Version="5.0.0" />
|
<PackageReference Include="System.ComponentModel.Annotations" Version="5.0.0" />
|
||||||
|
Loading…
Reference in New Issue
Block a user