mirror of
https://github.com/ppy/osu.git
synced 2025-01-13 15:52:54 +08:00
Merge branch 'master' into realm-integration/skins-rebase
This commit is contained in:
commit
452fa93444
@ -51,8 +51,8 @@
|
|||||||
<Reference Include="Java.Interop" />
|
<Reference Include="Java.Interop" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="ppy.osu.Game.Resources" Version="2021.1112.0" />
|
<PackageReference Include="ppy.osu.Game.Resources" Version="2021.1203.0" />
|
||||||
<PackageReference Include="ppy.osu.Framework.Android" Version="2021.1127.0" />
|
<PackageReference Include="ppy.osu.Framework.Android" Version="2021.1203.0" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup Label="Transitive Dependencies">
|
<ItemGroup Label="Transitive Dependencies">
|
||||||
<!-- Realm needs to be directly referenced in all Xamarin projects, as it will not pull in its transitive dependencies otherwise. -->
|
<!-- Realm needs to be directly referenced in all Xamarin projects, as it will not pull in its transitive dependencies otherwise. -->
|
||||||
|
@ -0,0 +1,18 @@
|
|||||||
|
// 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.
|
||||||
|
|
||||||
|
namespace osu.Desktop.LegacyIpc
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// A difficulty calculation request from the legacy client.
|
||||||
|
/// </summary>
|
||||||
|
/// <remarks>
|
||||||
|
/// Synchronise any changes with osu!stable.
|
||||||
|
/// </remarks>
|
||||||
|
public class LegacyIpcDifficultyCalculationRequest
|
||||||
|
{
|
||||||
|
public string BeatmapFile { get; set; }
|
||||||
|
public int RulesetId { get; set; }
|
||||||
|
public int Mods { get; set; }
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,16 @@
|
|||||||
|
// 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.
|
||||||
|
|
||||||
|
namespace osu.Desktop.LegacyIpc
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// A difficulty calculation response returned to the legacy client.
|
||||||
|
/// </summary>
|
||||||
|
/// <remarks>
|
||||||
|
/// Synchronise any changes with osu!stable.
|
||||||
|
/// </remarks>
|
||||||
|
public class LegacyIpcDifficultyCalculationResponse
|
||||||
|
{
|
||||||
|
public double StarRating { get; set; }
|
||||||
|
}
|
||||||
|
}
|
53
osu.Desktop/LegacyIpc/LegacyIpcMessage.cs
Normal file
53
osu.Desktop/LegacyIpc/LegacyIpcMessage.cs
Normal file
@ -0,0 +1,53 @@
|
|||||||
|
// 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.Platform;
|
||||||
|
using Newtonsoft.Json.Linq;
|
||||||
|
|
||||||
|
namespace osu.Desktop.LegacyIpc
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// An <see cref="IpcMessage"/> that can be used to communicate to and from legacy clients.
|
||||||
|
/// <para>
|
||||||
|
/// In order to deserialise types at either end, types must be serialised as their <see cref="System.Type.AssemblyQualifiedName"/>,
|
||||||
|
/// however this cannot be done since osu!stable and osu!lazer live in two different assemblies.
|
||||||
|
/// <br />
|
||||||
|
/// To get around this, this class exists which serialises a payload (<see cref="LegacyIpcMessage.Data"/>) as an <see cref="System.Object"/> type,
|
||||||
|
/// which can be deserialised at either end because it is part of the core library (mscorlib / System.Private.CorLib).
|
||||||
|
/// The payload contains the data to be sent over the IPC channel.
|
||||||
|
/// <br />
|
||||||
|
/// At either end, Json.NET deserialises the payload into a <see cref="JObject"/> which is manually converted back into the expected <see cref="LegacyIpcMessage.Data"/> type,
|
||||||
|
/// which then further contains another <see cref="JObject"/> representing the data sent over the IPC channel whose type can likewise be lazily matched through
|
||||||
|
/// <see cref="LegacyIpcMessage.Data.MessageType"/>.
|
||||||
|
/// </para>
|
||||||
|
/// </summary>
|
||||||
|
/// <remarks>
|
||||||
|
/// Synchronise any changes with osu-stable.
|
||||||
|
/// </remarks>
|
||||||
|
public class LegacyIpcMessage : IpcMessage
|
||||||
|
{
|
||||||
|
public LegacyIpcMessage()
|
||||||
|
{
|
||||||
|
// Types/assemblies are not inter-compatible, so always serialise/deserialise into objects.
|
||||||
|
base.Type = typeof(object).FullName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public new string Type => base.Type; // Hide setter.
|
||||||
|
|
||||||
|
public new object Value
|
||||||
|
{
|
||||||
|
get => base.Value;
|
||||||
|
set => base.Value = new Data
|
||||||
|
{
|
||||||
|
MessageType = value.GetType().Name,
|
||||||
|
MessageData = value
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
public class Data
|
||||||
|
{
|
||||||
|
public string MessageType { get; set; }
|
||||||
|
public object MessageData { get; set; }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
121
osu.Desktop/LegacyIpc/LegacyTcpIpcProvider.cs
Normal file
121
osu.Desktop/LegacyIpc/LegacyTcpIpcProvider.cs
Normal file
@ -0,0 +1,121 @@
|
|||||||
|
// 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.Linq;
|
||||||
|
using Newtonsoft.Json.Linq;
|
||||||
|
using osu.Framework.Logging;
|
||||||
|
using osu.Framework.Platform;
|
||||||
|
using osu.Game.Beatmaps;
|
||||||
|
using osu.Game.Beatmaps.Legacy;
|
||||||
|
using osu.Game.Rulesets;
|
||||||
|
using osu.Game.Rulesets.Catch;
|
||||||
|
using osu.Game.Rulesets.Mania;
|
||||||
|
using osu.Game.Rulesets.Mods;
|
||||||
|
using osu.Game.Rulesets.Osu;
|
||||||
|
using osu.Game.Rulesets.Taiko;
|
||||||
|
|
||||||
|
#nullable enable
|
||||||
|
|
||||||
|
namespace osu.Desktop.LegacyIpc
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Provides IPC to legacy osu! clients.
|
||||||
|
/// </summary>
|
||||||
|
public class LegacyTcpIpcProvider : TcpIpcProvider
|
||||||
|
{
|
||||||
|
private static readonly Logger logger = Logger.GetLogger("legacy-ipc");
|
||||||
|
|
||||||
|
public LegacyTcpIpcProvider()
|
||||||
|
: base(45357)
|
||||||
|
{
|
||||||
|
MessageReceived += msg =>
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
logger.Add("Processing legacy IPC message...");
|
||||||
|
logger.Add($" {msg.Value}", LogLevel.Debug);
|
||||||
|
|
||||||
|
// See explanation in LegacyIpcMessage for why this is done this way.
|
||||||
|
var legacyData = ((JObject)msg.Value).ToObject<LegacyIpcMessage.Data>();
|
||||||
|
object value = parseObject((JObject)legacyData!.MessageData, legacyData.MessageType);
|
||||||
|
|
||||||
|
return new LegacyIpcMessage
|
||||||
|
{
|
||||||
|
Value = onLegacyIpcMessageReceived(value)
|
||||||
|
};
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
logger.Add($"Processing IPC message failed: {msg.Value}", exception: ex);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
private object parseObject(JObject value, string type)
|
||||||
|
{
|
||||||
|
switch (type)
|
||||||
|
{
|
||||||
|
case nameof(LegacyIpcDifficultyCalculationRequest):
|
||||||
|
return value.ToObject<LegacyIpcDifficultyCalculationRequest>()
|
||||||
|
?? throw new InvalidOperationException($"Failed to parse request {value}");
|
||||||
|
|
||||||
|
case nameof(LegacyIpcDifficultyCalculationResponse):
|
||||||
|
return value.ToObject<LegacyIpcDifficultyCalculationResponse>()
|
||||||
|
?? throw new InvalidOperationException($"Failed to parse request {value}");
|
||||||
|
|
||||||
|
default:
|
||||||
|
throw new ArgumentException($"Unsupported object type {type}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private object onLegacyIpcMessageReceived(object message)
|
||||||
|
{
|
||||||
|
switch (message)
|
||||||
|
{
|
||||||
|
case LegacyIpcDifficultyCalculationRequest req:
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var ruleset = getLegacyRulesetFromID(req.RulesetId);
|
||||||
|
|
||||||
|
Mod[] mods = ruleset.ConvertFromLegacyMods((LegacyMods)req.Mods).ToArray();
|
||||||
|
WorkingBeatmap beatmap = new FlatFileWorkingBeatmap(req.BeatmapFile, _ => ruleset);
|
||||||
|
|
||||||
|
return new LegacyIpcDifficultyCalculationResponse
|
||||||
|
{
|
||||||
|
StarRating = ruleset.CreateDifficultyCalculator(beatmap).Calculate(mods).StarRating
|
||||||
|
};
|
||||||
|
}
|
||||||
|
catch
|
||||||
|
{
|
||||||
|
return new LegacyIpcDifficultyCalculationResponse();
|
||||||
|
}
|
||||||
|
|
||||||
|
default:
|
||||||
|
throw new ArgumentException($"Unsupported message type {message}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static Ruleset getLegacyRulesetFromID(int rulesetId)
|
||||||
|
{
|
||||||
|
switch (rulesetId)
|
||||||
|
{
|
||||||
|
case 0:
|
||||||
|
return new OsuRuleset();
|
||||||
|
|
||||||
|
case 1:
|
||||||
|
return new TaikoRuleset();
|
||||||
|
|
||||||
|
case 2:
|
||||||
|
return new CatchRuleset();
|
||||||
|
|
||||||
|
case 3:
|
||||||
|
return new ManiaRuleset();
|
||||||
|
|
||||||
|
default:
|
||||||
|
throw new ArgumentException("Invalid ruleset id");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -5,6 +5,7 @@ using System;
|
|||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
using osu.Desktop.LegacyIpc;
|
||||||
using osu.Framework;
|
using osu.Framework;
|
||||||
using osu.Framework.Development;
|
using osu.Framework.Development;
|
||||||
using osu.Framework.Logging;
|
using osu.Framework.Logging;
|
||||||
@ -18,8 +19,10 @@ namespace osu.Desktop
|
|||||||
{
|
{
|
||||||
private const string base_game_name = @"osu";
|
private const string base_game_name = @"osu";
|
||||||
|
|
||||||
|
private static LegacyTcpIpcProvider legacyIpc;
|
||||||
|
|
||||||
[STAThread]
|
[STAThread]
|
||||||
public static int Main(string[] args)
|
public static void Main(string[] args)
|
||||||
{
|
{
|
||||||
// Back up the cwd before DesktopGameHost changes it
|
// Back up the cwd before DesktopGameHost changes it
|
||||||
string cwd = Environment.CurrentDirectory;
|
string cwd = Environment.CurrentDirectory;
|
||||||
@ -69,14 +72,29 @@ namespace osu.Desktop
|
|||||||
throw new TimeoutException(@"IPC took too long to send");
|
throw new TimeoutException(@"IPC took too long to send");
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// we want to allow multiple instances to be started when in debug.
|
// we want to allow multiple instances to be started when in debug.
|
||||||
if (!DebugUtils.IsDebugBuild)
|
if (!DebugUtils.IsDebugBuild)
|
||||||
{
|
{
|
||||||
Logger.Log(@"osu! does not support multiple running instances.", LoggingTarget.Runtime, LogLevel.Error);
|
Logger.Log(@"osu! does not support multiple running instances.", LoggingTarget.Runtime, LogLevel.Error);
|
||||||
return 0;
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (host.IsPrimaryInstance)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
Logger.Log("Starting legacy IPC provider...");
|
||||||
|
legacyIpc = new LegacyTcpIpcProvider();
|
||||||
|
legacyIpc.Bind();
|
||||||
|
legacyIpc.StartAsync();
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
Logger.Error(ex, "Failed to start legacy IPC provider");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -84,8 +102,6 @@ namespace osu.Desktop
|
|||||||
host.Run(new TournamentGame());
|
host.Run(new TournamentGame());
|
||||||
else
|
else
|
||||||
host.Run(new OsuGameDesktop(args));
|
host.Run(new OsuGameDesktop(args));
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -9,7 +9,6 @@ using osu.Framework.Bindables;
|
|||||||
using osu.Framework.Caching;
|
using osu.Framework.Caching;
|
||||||
using osu.Framework.Graphics;
|
using osu.Framework.Graphics;
|
||||||
using osu.Framework.Graphics.Shapes;
|
using osu.Framework.Graphics.Shapes;
|
||||||
using osu.Game.Beatmaps;
|
|
||||||
using osu.Game.Graphics;
|
using osu.Game.Graphics;
|
||||||
using osu.Game.Rulesets.Edit;
|
using osu.Game.Rulesets.Edit;
|
||||||
using osu.Game.Rulesets.Mania.UI;
|
using osu.Game.Rulesets.Mania.UI;
|
||||||
@ -46,12 +45,6 @@ namespace osu.Game.Rulesets.Mania.Edit
|
|||||||
[Resolved]
|
[Resolved]
|
||||||
private EditorBeatmap beatmap { get; set; }
|
private EditorBeatmap beatmap { get; set; }
|
||||||
|
|
||||||
[Resolved]
|
|
||||||
private IScrollingInfo scrollingInfo { get; set; }
|
|
||||||
|
|
||||||
[Resolved]
|
|
||||||
private Bindable<WorkingBeatmap> working { get; set; }
|
|
||||||
|
|
||||||
[Resolved]
|
[Resolved]
|
||||||
private OsuColour colours { get; set; }
|
private OsuColour colours { get; set; }
|
||||||
|
|
||||||
|
@ -7,16 +7,12 @@ using osu.Framework.Allocation;
|
|||||||
using osu.Game.Rulesets.Edit;
|
using osu.Game.Rulesets.Edit;
|
||||||
using osu.Game.Rulesets.Mania.Objects;
|
using osu.Game.Rulesets.Mania.Objects;
|
||||||
using osu.Game.Rulesets.Objects;
|
using osu.Game.Rulesets.Objects;
|
||||||
using osu.Game.Rulesets.UI.Scrolling;
|
|
||||||
using osu.Game.Screens.Edit.Compose.Components;
|
using osu.Game.Screens.Edit.Compose.Components;
|
||||||
|
|
||||||
namespace osu.Game.Rulesets.Mania.Edit
|
namespace osu.Game.Rulesets.Mania.Edit
|
||||||
{
|
{
|
||||||
public class ManiaSelectionHandler : EditorSelectionHandler
|
public class ManiaSelectionHandler : EditorSelectionHandler
|
||||||
{
|
{
|
||||||
[Resolved]
|
|
||||||
private IScrollingInfo scrollingInfo { get; set; }
|
|
||||||
|
|
||||||
[Resolved]
|
[Resolved]
|
||||||
private HitObjectComposer composer { get; set; }
|
private HitObjectComposer composer { get; set; }
|
||||||
|
|
||||||
|
@ -15,9 +15,6 @@ namespace osu.Game.Rulesets.Mania.UI
|
|||||||
|
|
||||||
public JudgementResult Result { get; private set; }
|
public JudgementResult Result { get; private set; }
|
||||||
|
|
||||||
[Resolved]
|
|
||||||
private Column column { get; set; }
|
|
||||||
|
|
||||||
private SkinnableDrawable skinnableExplosion;
|
private SkinnableDrawable skinnableExplosion;
|
||||||
|
|
||||||
public PoolableHitExplosion()
|
public PoolableHitExplosion()
|
||||||
|
@ -12,7 +12,6 @@ using osu.Framework.Input.Events;
|
|||||||
using osu.Game.Graphics;
|
using osu.Game.Graphics;
|
||||||
using osu.Game.Rulesets.Taiko.Objects;
|
using osu.Game.Rulesets.Taiko.Objects;
|
||||||
using osu.Game.Rulesets.UI;
|
using osu.Game.Rulesets.UI;
|
||||||
using osu.Game.Screens.Play;
|
|
||||||
using osu.Game.Skinning;
|
using osu.Game.Skinning;
|
||||||
using osuTK;
|
using osuTK;
|
||||||
|
|
||||||
@ -149,9 +148,6 @@ namespace osu.Game.Rulesets.Taiko.UI
|
|||||||
centreHit.Colour = colours.Pink;
|
centreHit.Colour = colours.Pink;
|
||||||
}
|
}
|
||||||
|
|
||||||
[Resolved(canBeNull: true)]
|
|
||||||
private GameplayClock gameplayClock { get; set; }
|
|
||||||
|
|
||||||
public bool OnPressed(KeyBindingPressEvent<TaikoAction> e)
|
public bool OnPressed(KeyBindingPressEvent<TaikoAction> e)
|
||||||
{
|
{
|
||||||
Drawable target = null;
|
Drawable target = null;
|
||||||
|
@ -2,14 +2,20 @@
|
|||||||
// 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.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.Globalization;
|
||||||
|
using System.IO;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using NUnit.Framework;
|
using NUnit.Framework;
|
||||||
using osu.Framework.Utils;
|
using osu.Framework.Utils;
|
||||||
using osu.Game.Beatmaps;
|
using osu.Game.Beatmaps;
|
||||||
|
using osu.Game.Replays;
|
||||||
using osu.Game.Rulesets;
|
using osu.Game.Rulesets;
|
||||||
using osu.Game.Rulesets.Catch;
|
using osu.Game.Rulesets.Catch;
|
||||||
using osu.Game.Rulesets.Mania;
|
using osu.Game.Rulesets.Mania;
|
||||||
using osu.Game.Rulesets.Osu;
|
using osu.Game.Rulesets.Osu;
|
||||||
|
using osu.Game.Rulesets.Osu.Replays;
|
||||||
|
using osu.Game.Rulesets.Osu.UI;
|
||||||
|
using osu.Game.Rulesets.Replays;
|
||||||
using osu.Game.Rulesets.Scoring;
|
using osu.Game.Rulesets.Scoring;
|
||||||
using osu.Game.Rulesets.Taiko;
|
using osu.Game.Rulesets.Taiko;
|
||||||
using osu.Game.Scoring;
|
using osu.Game.Scoring;
|
||||||
@ -21,6 +27,14 @@ namespace osu.Game.Tests.Beatmaps.Formats
|
|||||||
[TestFixture]
|
[TestFixture]
|
||||||
public class LegacyScoreDecoderTest
|
public class LegacyScoreDecoderTest
|
||||||
{
|
{
|
||||||
|
private CultureInfo originalCulture;
|
||||||
|
|
||||||
|
[SetUp]
|
||||||
|
public void SetUp()
|
||||||
|
{
|
||||||
|
originalCulture = CultureInfo.CurrentCulture;
|
||||||
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
public void TestDecodeManiaReplay()
|
public void TestDecodeManiaReplay()
|
||||||
{
|
{
|
||||||
@ -44,6 +58,59 @@ namespace osu.Game.Tests.Beatmaps.Formats
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void TestCultureInvariance()
|
||||||
|
{
|
||||||
|
var ruleset = new OsuRuleset().RulesetInfo;
|
||||||
|
var scoreInfo = new TestScoreInfo(ruleset);
|
||||||
|
var beatmap = new TestBeatmap(ruleset);
|
||||||
|
var score = new Score
|
||||||
|
{
|
||||||
|
ScoreInfo = scoreInfo,
|
||||||
|
Replay = new Replay
|
||||||
|
{
|
||||||
|
Frames = new List<ReplayFrame>
|
||||||
|
{
|
||||||
|
new OsuReplayFrame(2000, OsuPlayfield.BASE_SIZE / 2, OsuAction.LeftButton)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// the "se" culture is used here, as it encodes the negative number sign as U+2212 MINUS SIGN,
|
||||||
|
// rather than the classic ASCII U+002D HYPHEN-MINUS.
|
||||||
|
CultureInfo.CurrentCulture = new CultureInfo("se");
|
||||||
|
|
||||||
|
var encodeStream = new MemoryStream();
|
||||||
|
|
||||||
|
var encoder = new LegacyScoreEncoder(score, beatmap);
|
||||||
|
encoder.Encode(encodeStream);
|
||||||
|
|
||||||
|
var decodeStream = new MemoryStream(encodeStream.GetBuffer());
|
||||||
|
|
||||||
|
var decoder = new TestLegacyScoreDecoder();
|
||||||
|
var decodedAfterEncode = decoder.Parse(decodeStream);
|
||||||
|
|
||||||
|
Assert.Multiple(() =>
|
||||||
|
{
|
||||||
|
Assert.That(decodedAfterEncode, Is.Not.Null);
|
||||||
|
|
||||||
|
Assert.That(decodedAfterEncode.ScoreInfo.User.Username, Is.EqualTo(scoreInfo.User.Username));
|
||||||
|
Assert.That(decodedAfterEncode.ScoreInfo.BeatmapInfoID, Is.EqualTo(scoreInfo.BeatmapInfoID));
|
||||||
|
Assert.That(decodedAfterEncode.ScoreInfo.Ruleset, Is.EqualTo(scoreInfo.Ruleset));
|
||||||
|
Assert.That(decodedAfterEncode.ScoreInfo.TotalScore, Is.EqualTo(scoreInfo.TotalScore));
|
||||||
|
Assert.That(decodedAfterEncode.ScoreInfo.MaxCombo, Is.EqualTo(scoreInfo.MaxCombo));
|
||||||
|
Assert.That(decodedAfterEncode.ScoreInfo.Date, Is.EqualTo(scoreInfo.Date));
|
||||||
|
|
||||||
|
Assert.That(decodedAfterEncode.Replay.Frames.Count, Is.EqualTo(1));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
[TearDown]
|
||||||
|
public void TearDown()
|
||||||
|
{
|
||||||
|
CultureInfo.CurrentCulture = originalCulture;
|
||||||
|
}
|
||||||
|
|
||||||
private class TestLegacyScoreDecoder : LegacyScoreDecoder
|
private class TestLegacyScoreDecoder : LegacyScoreDecoder
|
||||||
{
|
{
|
||||||
private static readonly Dictionary<int, Ruleset> rulesets = new Ruleset[]
|
private static readonly Dictionary<int, Ruleset> rulesets = new Ruleset[]
|
||||||
|
@ -25,9 +25,6 @@ namespace osu.Game.Tests.Beatmaps
|
|||||||
|
|
||||||
private BeatmapSetInfo importedSet;
|
private BeatmapSetInfo importedSet;
|
||||||
|
|
||||||
[Resolved]
|
|
||||||
private BeatmapManager beatmaps { get; set; }
|
|
||||||
|
|
||||||
private TestBeatmapDifficultyCache difficultyCache;
|
private TestBeatmapDifficultyCache difficultyCache;
|
||||||
|
|
||||||
private IBindable<StarDifficulty?> starDifficultyBindable;
|
private IBindable<StarDifficulty?> starDifficultyBindable;
|
||||||
|
@ -45,9 +45,9 @@ namespace osu.Game.Tests.Database
|
|||||||
{
|
{
|
||||||
var rulesets = new RealmRulesetStore(realmFactory, storage);
|
var rulesets = new RealmRulesetStore(realmFactory, storage);
|
||||||
|
|
||||||
Assert.IsTrue((rulesets.AvailableRulesets.First() as RealmRuleset)?.IsManaged == false);
|
Assert.IsFalse(rulesets.AvailableRulesets.First().IsManaged);
|
||||||
Assert.IsTrue((rulesets.GetRuleset(0) as RealmRuleset)?.IsManaged == false);
|
Assert.IsFalse(rulesets.GetRuleset(0)?.IsManaged);
|
||||||
Assert.IsTrue((rulesets.GetRuleset("mania") as RealmRuleset)?.IsManaged == false);
|
Assert.IsFalse(rulesets.GetRuleset("mania")?.IsManaged);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -18,9 +18,6 @@ namespace osu.Game.Tests.Input
|
|||||||
[Resolved]
|
[Resolved]
|
||||||
private FrameworkConfigManager frameworkConfigManager { get; set; }
|
private FrameworkConfigManager frameworkConfigManager { get; set; }
|
||||||
|
|
||||||
[Resolved]
|
|
||||||
private OsuConfigManager osuConfigManager { get; set; }
|
|
||||||
|
|
||||||
[TestCase(WindowMode.Windowed)]
|
[TestCase(WindowMode.Windowed)]
|
||||||
[TestCase(WindowMode.Borderless)]
|
[TestCase(WindowMode.Borderless)]
|
||||||
public void TestDisableConfining(WindowMode windowMode)
|
public void TestDisableConfining(WindowMode windowMode)
|
||||||
|
@ -16,6 +16,27 @@ namespace osu.Game.Tests.NonVisual.Multiplayer
|
|||||||
[HeadlessTest]
|
[HeadlessTest]
|
||||||
public class StatefulMultiplayerClientTest : MultiplayerTestScene
|
public class StatefulMultiplayerClientTest : MultiplayerTestScene
|
||||||
{
|
{
|
||||||
|
[Test]
|
||||||
|
public void TestUserAddedOnJoin()
|
||||||
|
{
|
||||||
|
var user = new APIUser { 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 APIUser { 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);
|
||||||
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
public void TestPlayingUserTracking()
|
public void TestPlayingUserTracking()
|
||||||
{
|
{
|
||||||
|
@ -1,35 +0,0 @@
|
|||||||
// 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.Online.API.Requests.Responses;
|
|
||||||
using osu.Game.Tests.Visual.Multiplayer;
|
|
||||||
|
|
||||||
namespace osu.Game.Tests.OnlinePlay
|
|
||||||
{
|
|
||||||
[HeadlessTest]
|
|
||||||
public class StatefulMultiplayerClientTest : MultiplayerTestScene
|
|
||||||
{
|
|
||||||
[Test]
|
|
||||||
public void TestUserAddedOnJoin()
|
|
||||||
{
|
|
||||||
var user = new APIUser { 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 APIUser { 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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -2,12 +2,10 @@
|
|||||||
// 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 NUnit.Framework;
|
||||||
using osu.Framework.Allocation;
|
|
||||||
using osu.Framework.Graphics;
|
using osu.Framework.Graphics;
|
||||||
using osu.Framework.Testing;
|
using osu.Framework.Testing;
|
||||||
using osu.Game.Rulesets;
|
using osu.Game.Rulesets;
|
||||||
using osu.Game.Rulesets.Osu;
|
using osu.Game.Rulesets.Osu;
|
||||||
using osu.Game.Skinning;
|
|
||||||
using osu.Game.Skinning.Editor;
|
using osu.Game.Skinning.Editor;
|
||||||
|
|
||||||
namespace osu.Game.Tests.Visual.Gameplay
|
namespace osu.Game.Tests.Visual.Gameplay
|
||||||
@ -16,9 +14,6 @@ namespace osu.Game.Tests.Visual.Gameplay
|
|||||||
{
|
{
|
||||||
private SkinEditor skinEditor;
|
private SkinEditor skinEditor;
|
||||||
|
|
||||||
[Resolved]
|
|
||||||
private SkinManager skinManager { get; set; }
|
|
||||||
|
|
||||||
protected override bool Autoplay => true;
|
protected override bool Autoplay => true;
|
||||||
|
|
||||||
[SetUpSteps]
|
[SetUpSteps]
|
||||||
|
@ -10,7 +10,6 @@ using osu.Framework.Extensions.IEnumerableExtensions;
|
|||||||
using osu.Framework.Graphics;
|
using osu.Framework.Graphics;
|
||||||
using osu.Framework.Graphics.Containers;
|
using osu.Framework.Graphics.Containers;
|
||||||
using osu.Framework.Testing;
|
using osu.Framework.Testing;
|
||||||
using osu.Game.Configuration;
|
|
||||||
using osu.Game.Rulesets;
|
using osu.Game.Rulesets;
|
||||||
using osu.Game.Rulesets.Mods;
|
using osu.Game.Rulesets.Mods;
|
||||||
using osu.Game.Rulesets.Osu;
|
using osu.Game.Rulesets.Osu;
|
||||||
@ -36,9 +35,6 @@ namespace osu.Game.Tests.Visual.Gameplay
|
|||||||
private Drawable hideTarget => hudOverlay.KeyCounter;
|
private Drawable hideTarget => hudOverlay.KeyCounter;
|
||||||
private FillFlowContainer<KeyCounter> keyCounterFlow => hudOverlay.KeyCounter.ChildrenOfType<FillFlowContainer<KeyCounter>>().First();
|
private FillFlowContainer<KeyCounter> keyCounterFlow => hudOverlay.KeyCounter.ChildrenOfType<FillFlowContainer<KeyCounter>>().First();
|
||||||
|
|
||||||
[Resolved]
|
|
||||||
private OsuConfigManager config { get; set; }
|
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
public void TestComboCounterIncrementing()
|
public void TestComboCounterIncrementing()
|
||||||
{
|
{
|
||||||
|
@ -20,7 +20,7 @@ namespace osu.Game.Tests.Visual.Menus
|
|||||||
private TestToolbar toolbar;
|
private TestToolbar toolbar;
|
||||||
|
|
||||||
[Resolved]
|
[Resolved]
|
||||||
private RulesetStore rulesets { get; set; }
|
private IRulesetStore rulesets { get; set; }
|
||||||
|
|
||||||
[SetUp]
|
[SetUp]
|
||||||
public void SetUp() => Schedule(() =>
|
public void SetUp() => Schedule(() =>
|
||||||
|
@ -2,11 +2,8 @@
|
|||||||
// 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 NUnit.Framework;
|
||||||
using osu.Framework.Allocation;
|
|
||||||
using osu.Framework.Graphics;
|
using osu.Framework.Graphics;
|
||||||
using osu.Game.Beatmaps;
|
|
||||||
using osu.Game.Online.Rooms;
|
using osu.Game.Online.Rooms;
|
||||||
using osu.Game.Rulesets;
|
|
||||||
using osu.Game.Rulesets.Osu;
|
using osu.Game.Rulesets.Osu;
|
||||||
using osu.Game.Rulesets.Osu.Mods;
|
using osu.Game.Rulesets.Osu.Mods;
|
||||||
using osu.Game.Screens.OnlinePlay.Components;
|
using osu.Game.Screens.OnlinePlay.Components;
|
||||||
@ -18,12 +15,6 @@ namespace osu.Game.Tests.Visual.Multiplayer
|
|||||||
{
|
{
|
||||||
public class TestSceneMatchBeatmapDetailArea : OnlinePlayTestScene
|
public class TestSceneMatchBeatmapDetailArea : OnlinePlayTestScene
|
||||||
{
|
{
|
||||||
[Resolved]
|
|
||||||
private BeatmapManager beatmapManager { get; set; }
|
|
||||||
|
|
||||||
[Resolved]
|
|
||||||
private RulesetStore rulesetStore { get; set; }
|
|
||||||
|
|
||||||
[SetUp]
|
[SetUp]
|
||||||
public new void Setup() => Schedule(() =>
|
public new void Setup() => Schedule(() =>
|
||||||
{
|
{
|
||||||
|
@ -0,0 +1,234 @@
|
|||||||
|
// 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.Linq;
|
||||||
|
using NUnit.Framework;
|
||||||
|
using osu.Framework.Allocation;
|
||||||
|
using osu.Framework.Audio;
|
||||||
|
using osu.Framework.Graphics;
|
||||||
|
using osu.Framework.Platform;
|
||||||
|
using osu.Framework.Testing;
|
||||||
|
using osu.Game.Beatmaps;
|
||||||
|
using osu.Game.Online.Multiplayer;
|
||||||
|
using osu.Game.Online.Rooms;
|
||||||
|
using osu.Game.Rulesets;
|
||||||
|
using osu.Game.Screens.OnlinePlay;
|
||||||
|
using osu.Game.Screens.OnlinePlay.Multiplayer.Match.Playlist;
|
||||||
|
using osu.Game.Tests.Beatmaps;
|
||||||
|
using osu.Game.Tests.Resources;
|
||||||
|
using osuTK;
|
||||||
|
|
||||||
|
namespace osu.Game.Tests.Visual.Multiplayer
|
||||||
|
{
|
||||||
|
public class TestSceneMultiplayerPlaylist : MultiplayerTestScene
|
||||||
|
{
|
||||||
|
private MultiplayerPlaylist list;
|
||||||
|
private BeatmapManager beatmaps;
|
||||||
|
private RulesetStore rulesets;
|
||||||
|
private BeatmapSetInfo importedSet;
|
||||||
|
private BeatmapInfo importedBeatmap;
|
||||||
|
|
||||||
|
[BackgroundDependencyLoader]
|
||||||
|
private void load(GameHost host, AudioManager audio)
|
||||||
|
{
|
||||||
|
Dependencies.Cache(rulesets = new RulesetStore(ContextFactory));
|
||||||
|
Dependencies.Cache(beatmaps = new BeatmapManager(LocalStorage, ContextFactory, rulesets, null, audio, Resources, host, Beatmap.Default));
|
||||||
|
}
|
||||||
|
|
||||||
|
[SetUp]
|
||||||
|
public new void Setup() => Schedule(() =>
|
||||||
|
{
|
||||||
|
Child = list = new MultiplayerPlaylist
|
||||||
|
{
|
||||||
|
Anchor = Anchor.Centre,
|
||||||
|
Origin = Anchor.Centre,
|
||||||
|
RelativeSizeAxes = Axes.Both,
|
||||||
|
Size = new Vector2(0.4f, 0.8f)
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
|
[SetUpSteps]
|
||||||
|
public new void SetUpSteps()
|
||||||
|
{
|
||||||
|
AddStep("import beatmap", () =>
|
||||||
|
{
|
||||||
|
beatmaps.Import(TestResources.GetQuickTestBeatmapForImport()).Wait();
|
||||||
|
importedSet = beatmaps.GetAllUsableBeatmapSetsEnumerable(IncludedDetails.All).First();
|
||||||
|
importedBeatmap = importedSet.Beatmaps.First(b => b.RulesetID == 0);
|
||||||
|
});
|
||||||
|
|
||||||
|
AddStep("change to all players mode", () => Client.ChangeSettings(new MultiplayerRoomSettings { QueueMode = QueueMode.AllPlayers }));
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void TestNonExpiredItemsAddedToQueueList()
|
||||||
|
{
|
||||||
|
assertItemInQueueListStep(1, 0);
|
||||||
|
|
||||||
|
addItemStep();
|
||||||
|
assertItemInQueueListStep(2, 1);
|
||||||
|
|
||||||
|
addItemStep();
|
||||||
|
assertItemInQueueListStep(3, 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void TestExpiredItemsAddedToHistoryList()
|
||||||
|
{
|
||||||
|
assertItemInQueueListStep(1, 0);
|
||||||
|
|
||||||
|
addItemStep(true);
|
||||||
|
assertItemInHistoryListStep(2, 0);
|
||||||
|
|
||||||
|
addItemStep(true);
|
||||||
|
assertItemInHistoryListStep(3, 0);
|
||||||
|
assertItemInHistoryListStep(2, 1);
|
||||||
|
|
||||||
|
// Initial item is still in the queue.
|
||||||
|
assertItemInQueueListStep(1, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void TestExpiredItemsMoveToQueueList()
|
||||||
|
{
|
||||||
|
addItemStep();
|
||||||
|
addItemStep();
|
||||||
|
|
||||||
|
AddStep("finish current item", () => Client.FinishCurrentItem());
|
||||||
|
|
||||||
|
assertItemInHistoryListStep(1, 0);
|
||||||
|
assertItemInQueueListStep(2, 0);
|
||||||
|
assertItemInQueueListStep(3, 1);
|
||||||
|
|
||||||
|
AddStep("finish current item", () => Client.FinishCurrentItem());
|
||||||
|
|
||||||
|
assertItemInHistoryListStep(2, 0);
|
||||||
|
assertItemInHistoryListStep(1, 1);
|
||||||
|
assertItemInQueueListStep(3, 0);
|
||||||
|
|
||||||
|
AddStep("finish current item", () => Client.FinishCurrentItem());
|
||||||
|
|
||||||
|
assertItemInHistoryListStep(3, 0);
|
||||||
|
assertItemInHistoryListStep(2, 1);
|
||||||
|
assertItemInHistoryListStep(1, 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void TestListsClearedWhenRoomLeft()
|
||||||
|
{
|
||||||
|
addItemStep();
|
||||||
|
AddStep("finish current item", () => Client.FinishCurrentItem());
|
||||||
|
|
||||||
|
AddStep("leave room", () => RoomManager.PartRoom());
|
||||||
|
AddUntilStep("wait for room part", () => Client.Room == null);
|
||||||
|
|
||||||
|
AddUntilStep("item 0 not in lists", () => !inHistoryList(0) && !inQueueList(0));
|
||||||
|
AddUntilStep("item 1 not in lists", () => !inHistoryList(0) && !inQueueList(0));
|
||||||
|
}
|
||||||
|
|
||||||
|
[Ignore("Expired items are initially removed from the room.")]
|
||||||
|
[Test]
|
||||||
|
public void TestJoinRoomWithMixedItemsAddedInCorrectLists()
|
||||||
|
{
|
||||||
|
AddStep("leave room", () => RoomManager.PartRoom());
|
||||||
|
AddUntilStep("wait for room part", () => Client.Room == null);
|
||||||
|
|
||||||
|
AddStep("join room with items", () =>
|
||||||
|
{
|
||||||
|
RoomManager.CreateRoom(new Room
|
||||||
|
{
|
||||||
|
Name = { Value = "test name" },
|
||||||
|
Playlist =
|
||||||
|
{
|
||||||
|
new PlaylistItem
|
||||||
|
{
|
||||||
|
Beatmap = { Value = new TestBeatmap(Ruleset.Value).BeatmapInfo },
|
||||||
|
Ruleset = { Value = Ruleset.Value }
|
||||||
|
},
|
||||||
|
new PlaylistItem
|
||||||
|
{
|
||||||
|
Beatmap = { Value = new TestBeatmap(Ruleset.Value).BeatmapInfo },
|
||||||
|
Ruleset = { Value = Ruleset.Value },
|
||||||
|
Expired = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
AddUntilStep("wait for room join", () => RoomJoined);
|
||||||
|
|
||||||
|
assertItemInQueueListStep(1, 0);
|
||||||
|
assertItemInHistoryListStep(2, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Adds a step to create a new playlist item.
|
||||||
|
/// </summary>
|
||||||
|
private void addItemStep(bool expired = false) => AddStep("add item", () => Client.AddPlaylistItem(new MultiplayerPlaylistItem(new PlaylistItem
|
||||||
|
{
|
||||||
|
Beatmap = { Value = importedBeatmap },
|
||||||
|
BeatmapID = importedBeatmap.OnlineID ?? -1,
|
||||||
|
Expired = expired,
|
||||||
|
PlayedAt = DateTimeOffset.Now
|
||||||
|
})));
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Asserts the position of a given playlist item in the queue list.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="playlistItemId">The item id.</param>
|
||||||
|
/// <param name="visualIndex">The index at which the item should appear visually. The item with index 0 is at the top of the list.</param>
|
||||||
|
private void assertItemInQueueListStep(int playlistItemId, int visualIndex)
|
||||||
|
{
|
||||||
|
changeDisplayModeStep(MultiplayerPlaylistDisplayMode.Queue);
|
||||||
|
|
||||||
|
AddUntilStep($"{playlistItemId} in queue at pos = {visualIndex}", () =>
|
||||||
|
{
|
||||||
|
return !inHistoryList(playlistItemId)
|
||||||
|
&& this.ChildrenOfType<MultiplayerQueueList>()
|
||||||
|
.Single()
|
||||||
|
.ChildrenOfType<DrawableRoomPlaylistItem>()
|
||||||
|
.OrderBy(drawable => drawable.Position.Y)
|
||||||
|
.TakeWhile(drawable => drawable.Item.ID != playlistItemId)
|
||||||
|
.Count() == visualIndex;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Asserts the position of a given playlist item in the history list.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="playlistItemId">The item id.</param>
|
||||||
|
/// <param name="visualIndex">The index at which the item should appear visually. The item with index 0 is at the top of the list.</param>
|
||||||
|
private void assertItemInHistoryListStep(int playlistItemId, int visualIndex)
|
||||||
|
{
|
||||||
|
changeDisplayModeStep(MultiplayerPlaylistDisplayMode.History);
|
||||||
|
|
||||||
|
AddUntilStep($"{playlistItemId} in history at pos = {visualIndex}", () =>
|
||||||
|
{
|
||||||
|
return !inQueueList(playlistItemId)
|
||||||
|
&& this.ChildrenOfType<MultiplayerHistoryList>()
|
||||||
|
.Single()
|
||||||
|
.ChildrenOfType<DrawableRoomPlaylistItem>()
|
||||||
|
.OrderBy(drawable => drawable.Position.Y)
|
||||||
|
.TakeWhile(drawable => drawable.Item.ID != playlistItemId)
|
||||||
|
.Count() == visualIndex;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private void changeDisplayModeStep(MultiplayerPlaylistDisplayMode mode) => AddStep($"change list to {mode}", () => list.DisplayMode.Value = mode);
|
||||||
|
|
||||||
|
private bool inQueueList(int playlistItemId)
|
||||||
|
{
|
||||||
|
return this.ChildrenOfType<MultiplayerQueueList>()
|
||||||
|
.Single()
|
||||||
|
.Items.Any(i => i.ID == playlistItemId);
|
||||||
|
}
|
||||||
|
|
||||||
|
private bool inHistoryList(int playlistItemId)
|
||||||
|
{
|
||||||
|
return this.ChildrenOfType<MultiplayerHistoryList>()
|
||||||
|
.Single()
|
||||||
|
.Items.Any(i => i.ID == playlistItemId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -24,9 +24,6 @@ namespace osu.Game.Tests.Visual.Multiplayer
|
|||||||
{
|
{
|
||||||
public class TestScenePlaylistsSongSelect : OnlinePlayTestScene
|
public class TestScenePlaylistsSongSelect : OnlinePlayTestScene
|
||||||
{
|
{
|
||||||
[Resolved]
|
|
||||||
private BeatmapManager beatmapManager { get; set; }
|
|
||||||
|
|
||||||
private BeatmapManager manager;
|
private BeatmapManager manager;
|
||||||
|
|
||||||
private RulesetStore rulesets;
|
private RulesetStore rulesets;
|
||||||
|
@ -0,0 +1,99 @@
|
|||||||
|
// 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.Game.Configuration;
|
||||||
|
using osu.Game.Screens.Play;
|
||||||
|
using osu.Game.Tests.Beatmaps.IO;
|
||||||
|
using osuTK.Input;
|
||||||
|
|
||||||
|
namespace osu.Game.Tests.Visual.Navigation
|
||||||
|
{
|
||||||
|
public class TestSceneMouseWheelVolumeAdjust : OsuGameTestScene
|
||||||
|
{
|
||||||
|
public override void SetUpSteps()
|
||||||
|
{
|
||||||
|
base.SetUpSteps();
|
||||||
|
|
||||||
|
// Headless tests are always at minimum volume. This covers interactive tests, matching that initial value.
|
||||||
|
AddStep("Set volume to min", () => Game.Audio.Volume.Value = 0);
|
||||||
|
AddAssert("Volume is min", () => Game.Audio.AggregateVolume.Value == 0);
|
||||||
|
AddStep("Move mouse to centre", () => InputManager.MoveMouseTo(Game.ScreenSpaceDrawQuad.Centre));
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void TestAdjustVolumeFromMainMenu()
|
||||||
|
{
|
||||||
|
// First scroll makes volume controls appear, second adjusts volume.
|
||||||
|
AddRepeatStep("Adjust volume using mouse wheel", () => InputManager.ScrollVerticalBy(5), 2);
|
||||||
|
AddUntilStep("Volume is above zero", () => Game.Audio.AggregateVolume.Value > 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void TestAdjustVolumeFromPlayerWheelEnabled()
|
||||||
|
{
|
||||||
|
loadToPlayerNonBreakTime();
|
||||||
|
|
||||||
|
// First scroll makes volume controls appear, second adjusts volume.
|
||||||
|
AddRepeatStep("Adjust volume using mouse wheel", () => InputManager.ScrollVerticalBy(5), 2);
|
||||||
|
AddAssert("Volume is above zero", () => Game.Audio.Volume.Value > 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void TestAdjustVolumeFromPlayerWheelDisabled()
|
||||||
|
{
|
||||||
|
AddStep("disable wheel volume adjust", () => Game.LocalConfig.SetValue(OsuSetting.MouseDisableWheel, true));
|
||||||
|
|
||||||
|
loadToPlayerNonBreakTime();
|
||||||
|
|
||||||
|
// First scroll makes volume controls appear, second adjusts volume.
|
||||||
|
AddRepeatStep("Adjust volume using mouse wheel", () => InputManager.ScrollVerticalBy(5), 2);
|
||||||
|
AddAssert("Volume is still zero", () => Game.Audio.Volume.Value == 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void TestAdjustVolumeFromPlayerWheelDisabledHoldingAlt()
|
||||||
|
{
|
||||||
|
AddStep("disable wheel volume adjust", () => Game.LocalConfig.SetValue(OsuSetting.MouseDisableWheel, true));
|
||||||
|
|
||||||
|
loadToPlayerNonBreakTime();
|
||||||
|
|
||||||
|
// First scroll makes volume controls appear, second adjusts volume.
|
||||||
|
AddRepeatStep("Adjust volume using mouse wheel holding alt", () =>
|
||||||
|
{
|
||||||
|
InputManager.PressKey(Key.AltLeft);
|
||||||
|
InputManager.ScrollVerticalBy(5);
|
||||||
|
InputManager.ReleaseKey(Key.AltLeft);
|
||||||
|
}, 2);
|
||||||
|
|
||||||
|
AddAssert("Volume is above zero", () => Game.Audio.Volume.Value > 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void loadToPlayerNonBreakTime()
|
||||||
|
{
|
||||||
|
Player player = null;
|
||||||
|
Screens.Select.SongSelect songSelect = null;
|
||||||
|
PushAndConfirm(() => songSelect = new TestSceneScreenNavigation.TestPlaySongSelect());
|
||||||
|
AddUntilStep("wait for song select", () => songSelect.BeatmapSetsLoaded);
|
||||||
|
|
||||||
|
AddStep("import beatmap", () => ImportBeatmapTest.LoadOszIntoOsu(Game, virtualTrack: true).Wait());
|
||||||
|
AddUntilStep("wait for selected", () => !Game.Beatmap.IsDefault);
|
||||||
|
AddStep("press enter", () => InputManager.Key(Key.Enter));
|
||||||
|
|
||||||
|
AddUntilStep("wait for player", () =>
|
||||||
|
{
|
||||||
|
// dismiss any notifications that may appear (ie. muted notification).
|
||||||
|
clickMouseInCentre();
|
||||||
|
return (player = Game.ScreenStack.CurrentScreen as Player) != null;
|
||||||
|
});
|
||||||
|
|
||||||
|
AddUntilStep("wait for play time active", () => !player.IsBreakTime.Value);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void clickMouseInCentre()
|
||||||
|
{
|
||||||
|
InputManager.MoveMouseTo(Game.ScreenSpaceDrawQuad.Centre);
|
||||||
|
InputManager.Click(MouseButton.Left);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -83,9 +83,6 @@ namespace osu.Game.Tests.Visual.Navigation
|
|||||||
[Resolved]
|
[Resolved]
|
||||||
private OsuGameBase gameBase { get; set; }
|
private OsuGameBase gameBase { get; set; }
|
||||||
|
|
||||||
[Resolved]
|
|
||||||
private GameHost host { get; set; }
|
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
public void TestNullRulesetHandled()
|
public void TestNullRulesetHandled()
|
||||||
{
|
{
|
||||||
|
@ -25,7 +25,7 @@ namespace osu.Game.Tests.Visual.Online
|
|||||||
}
|
}
|
||||||
|
|
||||||
[Resolved]
|
[Resolved]
|
||||||
private RulesetStore rulesets { get; set; }
|
private IRulesetStore rulesets { get; set; }
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
public void TestMultipleRulesetsBeatmapSet()
|
public void TestMultipleRulesetsBeatmapSet()
|
||||||
|
@ -30,7 +30,7 @@ namespace osu.Game.Tests.Visual.Online
|
|||||||
}
|
}
|
||||||
|
|
||||||
[Resolved]
|
[Resolved]
|
||||||
private RulesetStore rulesets { get; set; }
|
private IRulesetStore rulesets { get; set; }
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
public void TestLoading()
|
public void TestLoading()
|
||||||
|
@ -13,7 +13,6 @@ using osu.Framework.Graphics;
|
|||||||
using osu.Framework.Graphics.Containers;
|
using osu.Framework.Graphics.Containers;
|
||||||
using osu.Framework.Graphics.UserInterface;
|
using osu.Framework.Graphics.UserInterface;
|
||||||
using osu.Framework.Input;
|
using osu.Framework.Input;
|
||||||
using osu.Framework.Platform;
|
|
||||||
using osu.Framework.Testing;
|
using osu.Framework.Testing;
|
||||||
using osu.Game.Graphics.UserInterface;
|
using osu.Game.Graphics.UserInterface;
|
||||||
using osu.Game.Online.API;
|
using osu.Game.Online.API;
|
||||||
@ -47,9 +46,6 @@ namespace osu.Game.Tests.Visual.Online
|
|||||||
[CanBeNull]
|
[CanBeNull]
|
||||||
private Func<Channel, List<Message>> onGetMessages;
|
private Func<Channel, List<Message>> onGetMessages;
|
||||||
|
|
||||||
[Resolved]
|
|
||||||
private GameHost host { get; set; }
|
|
||||||
|
|
||||||
public TestSceneChatOverlay()
|
public TestSceneChatOverlay()
|
||||||
{
|
{
|
||||||
channels = Enumerable.Range(1, 10)
|
channels = Enumerable.Range(1, 10)
|
||||||
|
@ -24,7 +24,7 @@ namespace osu.Game.Tests.Visual.Online
|
|||||||
private TestUserListPanel evast;
|
private TestUserListPanel evast;
|
||||||
|
|
||||||
[Resolved]
|
[Resolved]
|
||||||
private RulesetStore rulesetStore { get; set; }
|
private IRulesetStore rulesetStore { get; set; }
|
||||||
|
|
||||||
[SetUp]
|
[SetUp]
|
||||||
public void SetUp() => Schedule(() =>
|
public void SetUp() => Schedule(() =>
|
||||||
|
@ -4,8 +4,6 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using NUnit.Framework;
|
using NUnit.Framework;
|
||||||
using osu.Framework.Allocation;
|
|
||||||
using osu.Game.Online.API;
|
|
||||||
using osu.Game.Online.API.Requests.Responses;
|
using osu.Game.Online.API.Requests.Responses;
|
||||||
using osu.Game.Overlays;
|
using osu.Game.Overlays;
|
||||||
using osu.Game.Overlays.Profile;
|
using osu.Game.Overlays.Profile;
|
||||||
@ -20,9 +18,6 @@ namespace osu.Game.Tests.Visual.Online
|
|||||||
|
|
||||||
private readonly TestUserProfileOverlay profile;
|
private readonly TestUserProfileOverlay profile;
|
||||||
|
|
||||||
[Resolved]
|
|
||||||
private IAPIProvider api { get; set; }
|
|
||||||
|
|
||||||
public static readonly APIUser TEST_USER = new APIUser
|
public static readonly APIUser TEST_USER = new APIUser
|
||||||
{
|
{
|
||||||
Username = @"Somebody",
|
Username = @"Somebody",
|
||||||
|
@ -9,7 +9,6 @@ using osu.Framework.Graphics;
|
|||||||
using osu.Framework.Graphics.Containers;
|
using osu.Framework.Graphics.Containers;
|
||||||
using osu.Framework.Graphics.Shapes;
|
using osu.Framework.Graphics.Shapes;
|
||||||
using osu.Game.Beatmaps;
|
using osu.Game.Beatmaps;
|
||||||
using osu.Game.Rulesets;
|
|
||||||
using osu.Game.Rulesets.Osu;
|
using osu.Game.Rulesets.Osu;
|
||||||
using osu.Game.Scoring;
|
using osu.Game.Scoring;
|
||||||
using osu.Game.Screens.Ranking;
|
using osu.Game.Screens.Ranking;
|
||||||
@ -20,9 +19,6 @@ namespace osu.Game.Tests.Visual.Ranking
|
|||||||
{
|
{
|
||||||
public class TestSceneContractedPanelMiddleContent : OsuTestScene
|
public class TestSceneContractedPanelMiddleContent : OsuTestScene
|
||||||
{
|
{
|
||||||
[Resolved]
|
|
||||||
private RulesetStore rulesetStore { get; set; }
|
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
public void TestShowPanel()
|
public void TestShowPanel()
|
||||||
{
|
{
|
||||||
|
@ -135,6 +135,35 @@ namespace osu.Game.Tests.Visual.UserInterface
|
|||||||
AddAssert("bpm is default", () => lastBpm != null && Precision.AlmostEquals(lastBpm.Value, 60));
|
AddAssert("bpm is default", () => lastBpm != null && Precision.AlmostEquals(lastBpm.Value, 60));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[TestCase(true)]
|
||||||
|
[TestCase(false)]
|
||||||
|
public void TestEarlyActivationEffectPoint(bool earlyActivating)
|
||||||
|
{
|
||||||
|
double earlyActivationMilliseconds = earlyActivating ? 100 : 0;
|
||||||
|
ControlPoint actualEffectPoint = null;
|
||||||
|
|
||||||
|
AddStep($"set early activation to {earlyActivationMilliseconds}", () => beatContainer.EarlyActivationMilliseconds = earlyActivationMilliseconds);
|
||||||
|
|
||||||
|
AddStep("seek before kiai effect point", () =>
|
||||||
|
{
|
||||||
|
ControlPoint expectedEffectPoint = Beatmap.Value.Beatmap.ControlPointInfo.EffectPoints.First(ep => ep.KiaiMode);
|
||||||
|
actualEffectPoint = null;
|
||||||
|
beatContainer.AllowMistimedEventFiring = false;
|
||||||
|
|
||||||
|
beatContainer.NewBeat = (i, timingControlPoint, effectControlPoint, channelAmplitudes) =>
|
||||||
|
{
|
||||||
|
if (Precision.AlmostEquals(gameplayClockContainer.CurrentTime + earlyActivationMilliseconds, expectedEffectPoint.Time, BeatSyncedContainer.MISTIMED_ALLOWANCE))
|
||||||
|
actualEffectPoint = effectControlPoint;
|
||||||
|
};
|
||||||
|
|
||||||
|
gameplayClockContainer.Seek(expectedEffectPoint.Time - earlyActivationMilliseconds);
|
||||||
|
});
|
||||||
|
|
||||||
|
AddUntilStep("wait for effect point", () => actualEffectPoint != null);
|
||||||
|
|
||||||
|
AddAssert("effect has kiai", () => actualEffectPoint != null && ((EffectControlPoint)actualEffectPoint).KiaiMode);
|
||||||
|
}
|
||||||
|
|
||||||
private class TestBeatSyncedContainer : BeatSyncedContainer
|
private class TestBeatSyncedContainer : BeatSyncedContainer
|
||||||
{
|
{
|
||||||
private const int flash_layer_height = 150;
|
private const int flash_layer_height = 150;
|
||||||
@ -145,6 +174,12 @@ namespace osu.Game.Tests.Visual.UserInterface
|
|||||||
set => base.AllowMistimedEventFiring = value;
|
set => base.AllowMistimedEventFiring = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public new double EarlyActivationMilliseconds
|
||||||
|
{
|
||||||
|
get => base.EarlyActivationMilliseconds;
|
||||||
|
set => base.EarlyActivationMilliseconds = value;
|
||||||
|
}
|
||||||
|
|
||||||
private readonly InfoString timingPointCount;
|
private readonly InfoString timingPointCount;
|
||||||
private readonly InfoString currentTimingPoint;
|
private readonly InfoString currentTimingPoint;
|
||||||
private readonly InfoString beatCount;
|
private readonly InfoString beatCount;
|
||||||
|
@ -26,9 +26,6 @@ namespace osu.Game.Tests.Visual.UserInterface
|
|||||||
private BeatmapSetInfo testBeatmap;
|
private BeatmapSetInfo testBeatmap;
|
||||||
private IAPIProvider api;
|
private IAPIProvider api;
|
||||||
|
|
||||||
[Resolved]
|
|
||||||
private BeatmapManager beatmaps { get; set; }
|
|
||||||
|
|
||||||
[BackgroundDependencyLoader]
|
[BackgroundDependencyLoader]
|
||||||
private void load(OsuGameBase osu, IAPIProvider api, RulesetStore rulesets)
|
private void load(OsuGameBase osu, IAPIProvider api, RulesetStore rulesets)
|
||||||
{
|
{
|
||||||
|
@ -6,19 +6,20 @@ using osu.Framework.Graphics;
|
|||||||
using osu.Game.Online.API;
|
using osu.Game.Online.API;
|
||||||
using osu.Game.Online.API.Requests;
|
using osu.Game.Online.API.Requests;
|
||||||
using osu.Game.Online.API.Requests.Responses;
|
using osu.Game.Online.API.Requests.Responses;
|
||||||
using osu.Game.Rulesets;
|
using osu.Game.Tests.Visual;
|
||||||
using osu.Game.Tournament.Components;
|
using osu.Game.Tournament.Components;
|
||||||
|
|
||||||
namespace osu.Game.Tournament.Tests.Components
|
namespace osu.Game.Tournament.Tests.Components
|
||||||
{
|
{
|
||||||
public class TestSceneTournamentBeatmapPanel : TournamentTestScene
|
public class TestSceneTournamentBeatmapPanel : TournamentTestScene
|
||||||
{
|
{
|
||||||
|
/// <remarks>
|
||||||
|
/// Warning: the below API instance is actually the online API, rather than the dummy API provided by the test.
|
||||||
|
/// It cannot be trivially replaced because setting <see cref="OsuTestScene.UseOnlineAPI"/> to <see langword="true"/> causes <see cref="OsuTestScene.API"/> to no longer be usable.
|
||||||
|
/// </remarks>
|
||||||
[Resolved]
|
[Resolved]
|
||||||
private IAPIProvider api { get; set; }
|
private IAPIProvider api { get; set; }
|
||||||
|
|
||||||
[Resolved]
|
|
||||||
private RulesetStore rulesets { get; set; }
|
|
||||||
|
|
||||||
[BackgroundDependencyLoader]
|
[BackgroundDependencyLoader]
|
||||||
private void load()
|
private void load()
|
||||||
{
|
{
|
||||||
|
@ -19,7 +19,7 @@ namespace osu.Game.Tournament.Tests.Components
|
|||||||
private IAPIProvider api { get; set; }
|
private IAPIProvider api { get; set; }
|
||||||
|
|
||||||
[Resolved]
|
[Resolved]
|
||||||
private RulesetStore rulesets { get; set; }
|
private IRulesetStore rulesets { get; set; }
|
||||||
|
|
||||||
private FillFlowContainer<TournamentBeatmapPanel> fillFlow;
|
private FillFlowContainer<TournamentBeatmapPanel> fillFlow;
|
||||||
|
|
||||||
|
@ -96,7 +96,7 @@ namespace osu.Game.Tournament.Tests.NonVisual
|
|||||||
Directory.CreateDirectory(flagsPath);
|
Directory.CreateDirectory(flagsPath);
|
||||||
|
|
||||||
// Define testing files corresponding to the specific file migrations that are needed
|
// Define testing files corresponding to the specific file migrations that are needed
|
||||||
string bracketFile = Path.Combine(osuRoot, "bracket.json");
|
string bracketFile = Path.Combine(osuRoot, TournamentGameBase.BRACKET_FILENAME);
|
||||||
|
|
||||||
string drawingsConfig = Path.Combine(osuRoot, "drawings.ini");
|
string drawingsConfig = Path.Combine(osuRoot, "drawings.ini");
|
||||||
string drawingsFile = Path.Combine(osuRoot, "drawings.txt");
|
string drawingsFile = Path.Combine(osuRoot, "drawings.txt");
|
||||||
@ -133,7 +133,7 @@ namespace osu.Game.Tournament.Tests.NonVisual
|
|||||||
|
|
||||||
Assert.That(storage.GetFullPath("."), Is.EqualTo(migratedPath));
|
Assert.That(storage.GetFullPath("."), Is.EqualTo(migratedPath));
|
||||||
|
|
||||||
Assert.True(storage.Exists("bracket.json"));
|
Assert.True(storage.Exists(TournamentGameBase.BRACKET_FILENAME));
|
||||||
Assert.True(storage.Exists("drawings.txt"));
|
Assert.True(storage.Exists("drawings.txt"));
|
||||||
Assert.True(storage.Exists("drawings_results.txt"));
|
Assert.True(storage.Exists("drawings_results.txt"));
|
||||||
|
|
||||||
|
@ -21,7 +21,7 @@ namespace osu.Game.Tournament.Components
|
|||||||
private readonly string modAcronym;
|
private readonly string modAcronym;
|
||||||
|
|
||||||
[Resolved]
|
[Resolved]
|
||||||
private RulesetStore rulesets { get; set; }
|
private IRulesetStore rulesets { get; set; }
|
||||||
|
|
||||||
public TournamentModIcon(string modAcronym)
|
public TournamentModIcon(string modAcronym)
|
||||||
{
|
{
|
||||||
|
@ -86,7 +86,7 @@ namespace osu.Game.Tournament.IO
|
|||||||
DeleteRecursive(source);
|
DeleteRecursive(source);
|
||||||
}
|
}
|
||||||
|
|
||||||
moveFileIfExists("bracket.json", destination);
|
moveFileIfExists(TournamentGameBase.BRACKET_FILENAME, destination);
|
||||||
moveFileIfExists("drawings.txt", destination);
|
moveFileIfExists("drawings.txt", destination);
|
||||||
moveFileIfExists("drawings_results.txt", destination);
|
moveFileIfExists("drawings_results.txt", destination);
|
||||||
moveFileIfExists("drawings.ini", destination);
|
moveFileIfExists("drawings.ini", destination);
|
||||||
|
@ -28,7 +28,7 @@ namespace osu.Game.Tournament.IPC
|
|||||||
protected IAPIProvider API { get; private set; }
|
protected IAPIProvider API { get; private set; }
|
||||||
|
|
||||||
[Resolved]
|
[Resolved]
|
||||||
protected RulesetStore Rulesets { get; private set; }
|
protected IRulesetStore Rulesets { get; private set; }
|
||||||
|
|
||||||
[Resolved]
|
[Resolved]
|
||||||
private GameHost host { get; set; }
|
private GameHost host { get; set; }
|
||||||
|
@ -25,9 +25,6 @@ namespace osu.Game.Tournament.Screens.Editors
|
|||||||
|
|
||||||
protected override BindableList<SeedingResult> Storage => team.SeedingResults;
|
protected override BindableList<SeedingResult> Storage => team.SeedingResults;
|
||||||
|
|
||||||
[Resolved(canBeNull: true)]
|
|
||||||
private TournamentSceneManager sceneManager { get; set; }
|
|
||||||
|
|
||||||
public SeedingEditorScreen(TournamentTeam team, TournamentScreen parentScreen)
|
public SeedingEditorScreen(TournamentTeam team, TournamentScreen parentScreen)
|
||||||
: base(parentScreen)
|
: base(parentScreen)
|
||||||
{
|
{
|
||||||
@ -38,9 +35,6 @@ namespace osu.Game.Tournament.Screens.Editors
|
|||||||
{
|
{
|
||||||
public SeedingResult Model { get; }
|
public SeedingResult Model { get; }
|
||||||
|
|
||||||
[Resolved]
|
|
||||||
private LadderInfo ladderInfo { get; set; }
|
|
||||||
|
|
||||||
public SeedingResultRow(TournamentTeam team, SeedingResult round)
|
public SeedingResultRow(TournamentTeam team, SeedingResult round)
|
||||||
{
|
{
|
||||||
Model = round;
|
Model = round;
|
||||||
|
@ -21,9 +21,6 @@ namespace osu.Game.Tournament.Screens.Setup
|
|||||||
{
|
{
|
||||||
public class StablePathSelectScreen : TournamentScreen
|
public class StablePathSelectScreen : TournamentScreen
|
||||||
{
|
{
|
||||||
[Resolved]
|
|
||||||
private GameHost host { get; set; }
|
|
||||||
|
|
||||||
[Resolved(canBeNull: true)]
|
[Resolved(canBeNull: true)]
|
||||||
private TournamentSceneManager sceneManager { get; set; }
|
private TournamentSceneManager sceneManager { get; set; }
|
||||||
|
|
||||||
|
@ -71,7 +71,7 @@ namespace osu.Game.Tournament
|
|||||||
loadingSpinner.Expire();
|
loadingSpinner.Expire();
|
||||||
|
|
||||||
Logger.Error(t.Exception, "Couldn't load bracket with error");
|
Logger.Error(t.Exception, "Couldn't load bracket with error");
|
||||||
Add(new WarningBox("Your bracket.json file could not be parsed. Please check runtime.log for more details."));
|
Add(new WarningBox($"Your {BRACKET_FILENAME} file could not be parsed. Please check runtime.log for more details."));
|
||||||
});
|
});
|
||||||
|
|
||||||
return;
|
return;
|
||||||
|
@ -11,6 +11,7 @@ using osu.Framework.Graphics;
|
|||||||
using osu.Framework.Graphics.Textures;
|
using osu.Framework.Graphics.Textures;
|
||||||
using osu.Framework.Input;
|
using osu.Framework.Input;
|
||||||
using osu.Framework.IO.Stores;
|
using osu.Framework.IO.Stores;
|
||||||
|
using osu.Framework.Logging;
|
||||||
using osu.Framework.Platform;
|
using osu.Framework.Platform;
|
||||||
using osu.Game.Graphics;
|
using osu.Game.Graphics;
|
||||||
using osu.Game.Online.API.Requests;
|
using osu.Game.Online.API.Requests;
|
||||||
@ -26,15 +27,15 @@ namespace osu.Game.Tournament
|
|||||||
[Cached(typeof(TournamentGameBase))]
|
[Cached(typeof(TournamentGameBase))]
|
||||||
public class TournamentGameBase : OsuGameBase
|
public class TournamentGameBase : OsuGameBase
|
||||||
{
|
{
|
||||||
private const string bracket_filename = "bracket.json";
|
public const string BRACKET_FILENAME = @"bracket.json";
|
||||||
private LadderInfo ladder;
|
private LadderInfo ladder;
|
||||||
private TournamentStorage storage;
|
private TournamentStorage storage;
|
||||||
private DependencyContainer dependencies;
|
private DependencyContainer dependencies;
|
||||||
private FileBasedIPC ipc;
|
private FileBasedIPC ipc;
|
||||||
|
|
||||||
protected Task BracketLoadTask => taskCompletionSource.Task;
|
protected Task BracketLoadTask => bracketLoadTaskCompletionSource.Task;
|
||||||
|
|
||||||
private readonly TaskCompletionSource<bool> taskCompletionSource = new TaskCompletionSource<bool>();
|
private readonly TaskCompletionSource<bool> bracketLoadTaskCompletionSource = new TaskCompletionSource<bool>();
|
||||||
|
|
||||||
protected override IReadOnlyDependencyContainer CreateChildDependencies(IReadOnlyDependencyContainer parent)
|
protected override IReadOnlyDependencyContainer CreateChildDependencies(IReadOnlyDependencyContainer parent)
|
||||||
{
|
{
|
||||||
@ -71,9 +72,9 @@ namespace osu.Game.Tournament
|
|||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
if (storage.Exists(bracket_filename))
|
if (storage.Exists(BRACKET_FILENAME))
|
||||||
{
|
{
|
||||||
using (Stream stream = storage.GetStream(bracket_filename, FileAccess.Read, FileMode.Open))
|
using (Stream stream = storage.GetStream(BRACKET_FILENAME, FileAccess.Read, FileMode.Open))
|
||||||
using (var sr = new StreamReader(stream))
|
using (var sr = new StreamReader(stream))
|
||||||
ladder = JsonConvert.DeserializeObject<LadderInfo>(sr.ReadToEnd(), new JsonPointConverter());
|
ladder = JsonConvert.DeserializeObject<LadderInfo>(sr.ReadToEnd(), new JsonPointConverter());
|
||||||
}
|
}
|
||||||
@ -144,7 +145,7 @@ namespace osu.Game.Tournament
|
|||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
taskCompletionSource.SetException(e);
|
bracketLoadTaskCompletionSource.SetException(e);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -156,7 +157,7 @@ namespace osu.Game.Tournament
|
|||||||
dependencies.CacheAs<MatchIPCInfo>(ipc = new FileBasedIPC());
|
dependencies.CacheAs<MatchIPCInfo>(ipc = new FileBasedIPC());
|
||||||
Add(ipc);
|
Add(ipc);
|
||||||
|
|
||||||
taskCompletionSource.SetResult(true);
|
bracketLoadTaskCompletionSource.SetResult(true);
|
||||||
|
|
||||||
initialisationText.Expire();
|
initialisationText.Expire();
|
||||||
});
|
});
|
||||||
@ -292,6 +293,12 @@ namespace osu.Game.Tournament
|
|||||||
|
|
||||||
protected virtual void SaveChanges()
|
protected virtual void SaveChanges()
|
||||||
{
|
{
|
||||||
|
if (!bracketLoadTaskCompletionSource.Task.IsCompletedSuccessfully)
|
||||||
|
{
|
||||||
|
Logger.Log("Inhibiting bracket save as bracket parsing failed");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
foreach (var r in ladder.Rounds)
|
foreach (var r in ladder.Rounds)
|
||||||
r.Matches = ladder.Matches.Where(p => p.Round.Value == r).Select(p => p.ID).ToList();
|
r.Matches = ladder.Matches.Where(p => p.Round.Value == r).Select(p => p.ID).ToList();
|
||||||
|
|
||||||
@ -309,7 +316,7 @@ namespace osu.Game.Tournament
|
|||||||
Converters = new JsonConverter[] { new JsonPointConverter() }
|
Converters = new JsonConverter[] { new JsonPointConverter() }
|
||||||
});
|
});
|
||||||
|
|
||||||
using (var stream = storage.GetStream(bracket_filename, FileAccess.Write, FileMode.Create))
|
using (var stream = storage.GetStream(BRACKET_FILENAME, FileAccess.Write, FileMode.Create))
|
||||||
using (var sw = new StreamWriter(stream))
|
using (var sw = new StreamWriter(stream))
|
||||||
sw.Write(serialisedLadder);
|
sw.Write(serialisedLadder);
|
||||||
}
|
}
|
||||||
|
@ -18,9 +18,6 @@ namespace osu.Game.Audio
|
|||||||
|
|
||||||
private readonly BindableDouble muteBindable = new BindableDouble();
|
private readonly BindableDouble muteBindable = new BindableDouble();
|
||||||
|
|
||||||
[Resolved]
|
|
||||||
private AudioManager audio { get; set; }
|
|
||||||
|
|
||||||
private ITrackStore trackStore;
|
private ITrackStore trackStore;
|
||||||
|
|
||||||
protected TrackManagerPreviewTrack CurrentTrack;
|
protected TrackManagerPreviewTrack CurrentTrack;
|
||||||
|
@ -25,7 +25,7 @@ namespace osu.Game.Beatmaps
|
|||||||
private IAPIProvider api { get; set; }
|
private IAPIProvider api { get; set; }
|
||||||
|
|
||||||
[Resolved]
|
[Resolved]
|
||||||
private RulesetStore rulesets { get; set; }
|
private IRulesetStore rulesets { get; set; }
|
||||||
|
|
||||||
[Resolved]
|
[Resolved]
|
||||||
private Bindable<RulesetInfo> ruleset { get; set; }
|
private Bindable<RulesetInfo> ruleset { get; set; }
|
||||||
@ -35,7 +35,7 @@ namespace osu.Game.Beatmaps
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
private int? requestedUserId;
|
private int? requestedUserId;
|
||||||
|
|
||||||
private readonly Dictionary<RulesetInfo, double> recommendedDifficultyMapping = new Dictionary<RulesetInfo, double>();
|
private readonly Dictionary<IRulesetInfo, double> recommendedDifficultyMapping = new Dictionary<IRulesetInfo, double>();
|
||||||
|
|
||||||
private readonly IBindable<APIState> apiState = new Bindable<APIState>();
|
private readonly IBindable<APIState> apiState = new Bindable<APIState>();
|
||||||
|
|
||||||
@ -101,7 +101,7 @@ namespace osu.Game.Beatmaps
|
|||||||
/// Rulesets ordered descending by their respective recommended difficulties.
|
/// Rulesets ordered descending by their respective recommended difficulties.
|
||||||
/// The currently selected ruleset will always be first.
|
/// The currently selected ruleset will always be first.
|
||||||
/// </returns>
|
/// </returns>
|
||||||
private IEnumerable<RulesetInfo> orderedRulesets
|
private IEnumerable<IRulesetInfo> orderedRulesets
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
|
@ -86,7 +86,7 @@ namespace osu.Game.Beatmaps.Drawables
|
|||||||
}
|
}
|
||||||
|
|
||||||
[Resolved]
|
[Resolved]
|
||||||
private RulesetStore rulesets { get; set; }
|
private IRulesetStore rulesets { get; set; }
|
||||||
|
|
||||||
[BackgroundDependencyLoader]
|
[BackgroundDependencyLoader]
|
||||||
private void load(OsuColour colours)
|
private void load(OsuColour colours)
|
||||||
|
52
osu.Game/Beatmaps/FlatFileWorkingBeatmap.cs
Normal file
52
osu.Game/Beatmaps/FlatFileWorkingBeatmap.cs
Normal file
@ -0,0 +1,52 @@
|
|||||||
|
// 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.IO;
|
||||||
|
using osu.Framework.Audio.Track;
|
||||||
|
using osu.Framework.Graphics.Textures;
|
||||||
|
using osu.Game.Beatmaps.Formats;
|
||||||
|
using osu.Game.IO;
|
||||||
|
using osu.Game.Rulesets;
|
||||||
|
using osu.Game.Skinning;
|
||||||
|
|
||||||
|
namespace osu.Game.Beatmaps
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// A <see cref="WorkingBeatmap"/> which can be constructed directly from a .osu file, providing an implementation for
|
||||||
|
/// <see cref="WorkingBeatmap.GetPlayableBeatmap(osu.Game.Rulesets.IRulesetInfo,System.Collections.Generic.IReadOnlyList{osu.Game.Rulesets.Mods.Mod})"/>.
|
||||||
|
/// </summary>
|
||||||
|
public class FlatFileWorkingBeatmap : WorkingBeatmap
|
||||||
|
{
|
||||||
|
private readonly Beatmap beatmap;
|
||||||
|
|
||||||
|
public FlatFileWorkingBeatmap(string file, Func<int, Ruleset> rulesetProvider, int? beatmapId = null)
|
||||||
|
: this(readFromFile(file), rulesetProvider, beatmapId)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
private FlatFileWorkingBeatmap(Beatmap beatmap, Func<int, Ruleset> rulesetProvider, int? beatmapId = null)
|
||||||
|
: base(beatmap.BeatmapInfo, null)
|
||||||
|
{
|
||||||
|
this.beatmap = beatmap;
|
||||||
|
|
||||||
|
beatmap.BeatmapInfo.Ruleset = rulesetProvider(beatmap.BeatmapInfo.RulesetID).RulesetInfo;
|
||||||
|
|
||||||
|
if (beatmapId.HasValue)
|
||||||
|
beatmap.BeatmapInfo.OnlineID = beatmapId;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static Beatmap readFromFile(string filename)
|
||||||
|
{
|
||||||
|
using (var stream = File.OpenRead(filename))
|
||||||
|
using (var reader = new LineBufferedReader(stream))
|
||||||
|
return Decoder.GetDecoder<Beatmap>(reader).Decode(reader);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override IBeatmap GetBeatmap() => beatmap;
|
||||||
|
protected override Texture GetBackground() => throw new NotImplementedException();
|
||||||
|
protected override Track GetBeatmapTrack() => throw new NotImplementedException();
|
||||||
|
protected internal override ISkin GetSkin() => throw new NotImplementedException();
|
||||||
|
public override Stream GetStream(string storagePath) => throw new NotImplementedException();
|
||||||
|
}
|
||||||
|
}
|
@ -13,7 +13,6 @@ using osu.Framework.Graphics.UserInterface;
|
|||||||
using osu.Framework.Input.Events;
|
using osu.Framework.Input.Events;
|
||||||
using osu.Framework.Localisation;
|
using osu.Framework.Localisation;
|
||||||
using osu.Game.Beatmaps;
|
using osu.Game.Beatmaps;
|
||||||
using osu.Game.Graphics;
|
|
||||||
using osu.Game.Graphics.Containers;
|
using osu.Game.Graphics.Containers;
|
||||||
using osu.Game.Graphics.UserInterface;
|
using osu.Game.Graphics.UserInterface;
|
||||||
using osuTK;
|
using osuTK;
|
||||||
@ -193,9 +192,6 @@ namespace osu.Game.Collections
|
|||||||
[NotNull]
|
[NotNull]
|
||||||
protected new CollectionFilterMenuItem Item => ((DropdownMenuItem<CollectionFilterMenuItem>)base.Item).Value;
|
protected new CollectionFilterMenuItem Item => ((DropdownMenuItem<CollectionFilterMenuItem>)base.Item).Value;
|
||||||
|
|
||||||
[Resolved]
|
|
||||||
private OsuColour colours { get; set; }
|
|
||||||
|
|
||||||
[Resolved]
|
[Resolved]
|
||||||
private IBindable<WorkingBeatmap> beatmap { get; set; }
|
private IBindable<WorkingBeatmap> beatmap { get; set; }
|
||||||
|
|
||||||
|
@ -40,9 +40,6 @@ namespace osu.Game.Collections
|
|||||||
|
|
||||||
public readonly BindableList<BeatmapCollection> Collections = new BindableList<BeatmapCollection>();
|
public readonly BindableList<BeatmapCollection> Collections = new BindableList<BeatmapCollection>();
|
||||||
|
|
||||||
[Resolved]
|
|
||||||
private GameHost host { get; set; }
|
|
||||||
|
|
||||||
[Resolved]
|
[Resolved]
|
||||||
private BeatmapManager beatmaps { get; set; }
|
private BeatmapManager beatmaps { get; set; }
|
||||||
|
|
||||||
|
@ -111,7 +111,7 @@ namespace osu.Game.Graphics.Containers
|
|||||||
if (clock == null)
|
if (clock == null)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
double currentTrackTime = clock.CurrentTime;
|
double currentTrackTime = clock.CurrentTime + EarlyActivationMilliseconds;
|
||||||
|
|
||||||
if (Beatmap.Value.TrackLoaded && Beatmap.Value.BeatmapLoaded)
|
if (Beatmap.Value.TrackLoaded && Beatmap.Value.BeatmapLoaded)
|
||||||
{
|
{
|
||||||
@ -132,13 +132,11 @@ namespace osu.Game.Graphics.Containers
|
|||||||
{
|
{
|
||||||
// this may be the case where the beat syncing clock has been paused.
|
// this may be the case where the beat syncing clock has been paused.
|
||||||
// we still want to show an idle animation, so use this container's time instead.
|
// we still want to show an idle animation, so use this container's time instead.
|
||||||
currentTrackTime = Clock.CurrentTime;
|
currentTrackTime = Clock.CurrentTime + EarlyActivationMilliseconds;
|
||||||
timingPoint = TimingControlPoint.DEFAULT;
|
timingPoint = TimingControlPoint.DEFAULT;
|
||||||
effectPoint = EffectControlPoint.DEFAULT;
|
effectPoint = EffectControlPoint.DEFAULT;
|
||||||
}
|
}
|
||||||
|
|
||||||
currentTrackTime += EarlyActivationMilliseconds;
|
|
||||||
|
|
||||||
double beatLength = timingPoint.BeatLength / Divisor;
|
double beatLength = timingPoint.BeatLength / Divisor;
|
||||||
|
|
||||||
while (beatLength < MinimumBeatLength)
|
while (beatLength < MinimumBeatLength)
|
||||||
|
@ -18,6 +18,7 @@ namespace osu.Game.IPC
|
|||||||
: base(host)
|
: base(host)
|
||||||
{
|
{
|
||||||
this.importer = importer;
|
this.importer = importer;
|
||||||
|
|
||||||
MessageReceived += msg =>
|
MessageReceived += msg =>
|
||||||
{
|
{
|
||||||
Debug.Assert(importer != null);
|
Debug.Assert(importer != null);
|
||||||
@ -25,6 +26,8 @@ namespace osu.Game.IPC
|
|||||||
{
|
{
|
||||||
if (t.Exception != null) throw t.Exception;
|
if (t.Exception != null) throw t.Exception;
|
||||||
}, TaskContinuationOptions.OnlyOnFaulted);
|
}, TaskContinuationOptions.OnlyOnFaulted);
|
||||||
|
|
||||||
|
return null;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -35,9 +35,14 @@ namespace osu.Game.Localisation
|
|||||||
public static LocalisableString ConfineMouseMode => new TranslatableString(getKey(@"confine_mouse_mode"), @"Confine mouse cursor to window");
|
public static LocalisableString ConfineMouseMode => new TranslatableString(getKey(@"confine_mouse_mode"), @"Confine mouse cursor to window");
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// "Disable mouse wheel during gameplay"
|
/// "Disable mouse wheel adjusting volume during gameplay"
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public static LocalisableString DisableMouseWheel => new TranslatableString(getKey(@"disable_mouse_wheel"), @"Disable mouse wheel during gameplay");
|
public static LocalisableString DisableMouseWheelVolumeAdjust => new TranslatableString(getKey(@"disable_mouse_wheel_volume_adjust"), @"Disable mouse wheel adjusting volume during gameplay");
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// "Volume can still be adjusted using the mouse wheel by holding "Alt""
|
||||||
|
/// </summary>
|
||||||
|
public static LocalisableString DisableMouseWheelVolumeAdjustTooltip => new TranslatableString(getKey(@"disable_mouse_wheel_volume_adjust_tooltip"), @"Volume can still be adjusted using the mouse wheel by holding ""Alt""");
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// "Disable mouse buttons during gameplay"
|
/// "Disable mouse buttons during gameplay"
|
||||||
|
@ -50,6 +50,8 @@ namespace osu.Game.Models
|
|||||||
|
|
||||||
public bool Equals(RealmRuleset? other) => other != null && OnlineID == other.OnlineID && Available == other.Available && Name == other.Name && InstantiationInfo == other.InstantiationInfo;
|
public bool Equals(RealmRuleset? other) => other != null && OnlineID == other.OnlineID && Available == other.Available && Name == other.Name && InstantiationInfo == other.InstantiationInfo;
|
||||||
|
|
||||||
|
public bool Equals(IRulesetInfo? other) => other is RealmRuleset b && Equals(b);
|
||||||
|
|
||||||
public override string ToString() => Name;
|
public override string ToString() => Name;
|
||||||
|
|
||||||
public RealmRuleset Clone() => new RealmRuleset
|
public RealmRuleset Clone() => new RealmRuleset
|
||||||
|
@ -26,9 +26,12 @@ namespace osu.Game.Online.API.Requests
|
|||||||
{
|
{
|
||||||
var request = base.CreateWebRequest();
|
var request = base.CreateWebRequest();
|
||||||
|
|
||||||
request.AddParameter(@"id", beatmapInfo.OnlineID.ToString());
|
if (beatmapInfo.OnlineID > 0)
|
||||||
request.AddParameter(@"checksum", beatmapInfo.MD5Hash);
|
request.AddParameter(@"id", beatmapInfo.OnlineID.ToString());
|
||||||
request.AddParameter(@"filename", filename);
|
if (!string.IsNullOrEmpty(beatmapInfo.MD5Hash))
|
||||||
|
request.AddParameter(@"checksum", beatmapInfo.MD5Hash);
|
||||||
|
if (!string.IsNullOrEmpty(filename))
|
||||||
|
request.AddParameter(@"filename", filename);
|
||||||
|
|
||||||
return request;
|
return request;
|
||||||
}
|
}
|
||||||
|
@ -9,7 +9,7 @@ namespace osu.Game.Online.API.Requests
|
|||||||
public class GetUserRequest : APIRequest<APIUser>
|
public class GetUserRequest : APIRequest<APIUser>
|
||||||
{
|
{
|
||||||
public readonly string Lookup;
|
public readonly string Lookup;
|
||||||
public readonly RulesetInfo Ruleset;
|
public readonly IRulesetInfo Ruleset;
|
||||||
private readonly LookupType lookupType;
|
private readonly LookupType lookupType;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@ -24,7 +24,7 @@ namespace osu.Game.Online.API.Requests
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="userId">The user to get.</param>
|
/// <param name="userId">The user to get.</param>
|
||||||
/// <param name="ruleset">The ruleset to get the user's info for.</param>
|
/// <param name="ruleset">The ruleset to get the user's info for.</param>
|
||||||
public GetUserRequest(long? userId = null, RulesetInfo ruleset = null)
|
public GetUserRequest(long? userId = null, IRulesetInfo ruleset = null)
|
||||||
{
|
{
|
||||||
Lookup = userId.ToString();
|
Lookup = userId.ToString();
|
||||||
lookupType = LookupType.Id;
|
lookupType = LookupType.Id;
|
||||||
@ -36,7 +36,7 @@ namespace osu.Game.Online.API.Requests
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="username">The user to get.</param>
|
/// <param name="username">The user to get.</param>
|
||||||
/// <param name="ruleset">The ruleset to get the user's info for.</param>
|
/// <param name="ruleset">The ruleset to get the user's info for.</param>
|
||||||
public GetUserRequest(string username = null, RulesetInfo ruleset = null)
|
public GetUserRequest(string username = null, IRulesetInfo ruleset = null)
|
||||||
{
|
{
|
||||||
Lookup = username;
|
Lookup = username;
|
||||||
lookupType = LookupType.Username;
|
lookupType = LookupType.Username;
|
||||||
|
@ -65,9 +65,6 @@ namespace osu.Game.Online.Leaderboards
|
|||||||
[Resolved(CanBeNull = true)]
|
[Resolved(CanBeNull = true)]
|
||||||
private SongSelect songSelect { get; set; }
|
private SongSelect songSelect { get; set; }
|
||||||
|
|
||||||
[Resolved]
|
|
||||||
private ScoreManager scoreManager { get; set; }
|
|
||||||
|
|
||||||
[Resolved]
|
[Resolved]
|
||||||
private Storage storage { get; set; }
|
private Storage storage { get; set; }
|
||||||
|
|
||||||
|
@ -3,13 +3,11 @@
|
|||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
using osu.Framework.Allocation;
|
|
||||||
using osu.Framework.Bindables;
|
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.Graphics;
|
using osu.Game.Graphics;
|
||||||
using osu.Game.Graphics.Sprites;
|
using osu.Game.Graphics.Sprites;
|
||||||
using osu.Game.Rulesets;
|
|
||||||
using osuTK;
|
using osuTK;
|
||||||
|
|
||||||
namespace osu.Game.Online.Leaderboards
|
namespace osu.Game.Online.Leaderboards
|
||||||
@ -25,9 +23,6 @@ namespace osu.Game.Online.Leaderboards
|
|||||||
|
|
||||||
protected override bool StartHidden => true;
|
protected override bool StartHidden => true;
|
||||||
|
|
||||||
[Resolved]
|
|
||||||
private RulesetStore rulesets { get; set; }
|
|
||||||
|
|
||||||
public UserTopScoreContainer(Func<TScoreInfo, LeaderboardScore> createScoreDelegate)
|
public UserTopScoreContainer(Func<TScoreInfo, LeaderboardScore> createScoreDelegate)
|
||||||
{
|
{
|
||||||
this.createScoreDelegate = createScoreDelegate;
|
this.createScoreDelegate = createScoreDelegate;
|
||||||
|
@ -32,12 +32,36 @@ namespace osu.Game.Online.Multiplayer
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public event Action? RoomUpdated;
|
public event Action? RoomUpdated;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Invoked when a new user joins the room.
|
||||||
|
/// </summary>
|
||||||
public event Action<MultiplayerRoomUser>? UserJoined;
|
public event Action<MultiplayerRoomUser>? UserJoined;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Invoked when a user leaves the room of their own accord.
|
||||||
|
/// </summary>
|
||||||
public event Action<MultiplayerRoomUser>? UserLeft;
|
public event Action<MultiplayerRoomUser>? UserLeft;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Invoked when a user was kicked from the room forcefully.
|
||||||
|
/// </summary>
|
||||||
public event Action<MultiplayerRoomUser>? UserKicked;
|
public event Action<MultiplayerRoomUser>? UserKicked;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Invoked when a new item is added to the playlist.
|
||||||
|
/// </summary>
|
||||||
|
public event Action<MultiplayerPlaylistItem>? ItemAdded;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Invoked when a playlist item is removed from the playlist. The provided <c>long</c> is the playlist's item ID.
|
||||||
|
/// </summary>
|
||||||
|
public event Action<long>? ItemRemoved;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Invoked when a playlist item's details change.
|
||||||
|
/// </summary>
|
||||||
|
public event Action<MultiplayerPlaylistItem>? ItemChanged;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Invoked when the multiplayer server requests the current beatmap to be loaded into play.
|
/// Invoked when the multiplayer server requests the current beatmap to be loaded into play.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@ -94,7 +118,7 @@ namespace osu.Game.Online.Multiplayer
|
|||||||
protected IAPIProvider API { get; private set; } = null!;
|
protected IAPIProvider API { get; private set; } = null!;
|
||||||
|
|
||||||
[Resolved]
|
[Resolved]
|
||||||
protected RulesetStore Rulesets { get; private set; } = null!;
|
protected IRulesetStore Rulesets { get; private set; } = null!;
|
||||||
|
|
||||||
[Resolved]
|
[Resolved]
|
||||||
private UserLookupCache userLookupCache { get; set; } = null!;
|
private UserLookupCache userLookupCache { get; set; } = null!;
|
||||||
@ -617,6 +641,7 @@ namespace osu.Game.Online.Multiplayer
|
|||||||
Room.Playlist.Add(item);
|
Room.Playlist.Add(item);
|
||||||
APIRoom.Playlist.Add(playlistItem);
|
APIRoom.Playlist.Add(playlistItem);
|
||||||
|
|
||||||
|
ItemAdded?.Invoke(item);
|
||||||
RoomUpdated?.Invoke();
|
RoomUpdated?.Invoke();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -636,6 +661,7 @@ namespace osu.Game.Online.Multiplayer
|
|||||||
Room.Playlist.Remove(Room.Playlist.Single(existing => existing.ID == playlistItemId));
|
Room.Playlist.Remove(Room.Playlist.Single(existing => existing.ID == playlistItemId));
|
||||||
APIRoom.Playlist.RemoveAll(existing => existing.ID == playlistItemId);
|
APIRoom.Playlist.RemoveAll(existing => existing.ID == playlistItemId);
|
||||||
|
|
||||||
|
ItemRemoved?.Invoke(playlistItemId);
|
||||||
RoomUpdated?.Invoke();
|
RoomUpdated?.Invoke();
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -666,6 +692,7 @@ namespace osu.Game.Online.Multiplayer
|
|||||||
if (CurrentMatchPlayingItem.Value?.ID == playlistItem.ID)
|
if (CurrentMatchPlayingItem.Value?.ID == playlistItem.ID)
|
||||||
CurrentMatchPlayingItem.Value = playlistItem;
|
CurrentMatchPlayingItem.Value = playlistItem;
|
||||||
|
|
||||||
|
ItemChanged?.Invoke(item);
|
||||||
RoomUpdated?.Invoke();
|
RoomUpdated?.Invoke();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -706,6 +733,9 @@ namespace osu.Game.Online.Multiplayer
|
|||||||
var apiBeatmap = await GetAPIBeatmap(item.BeatmapID).ConfigureAwait(false);
|
var apiBeatmap = await GetAPIBeatmap(item.BeatmapID).ConfigureAwait(false);
|
||||||
|
|
||||||
var ruleset = Rulesets.GetRuleset(item.RulesetID);
|
var ruleset = Rulesets.GetRuleset(item.RulesetID);
|
||||||
|
|
||||||
|
Debug.Assert(ruleset != null);
|
||||||
|
|
||||||
var rulesetInstance = ruleset.CreateInstance();
|
var rulesetInstance = ruleset.CreateInstance();
|
||||||
|
|
||||||
var playlistItem = new PlaylistItem
|
var playlistItem = new PlaylistItem
|
||||||
@ -714,7 +744,9 @@ namespace osu.Game.Online.Multiplayer
|
|||||||
OwnerID = item.OwnerID,
|
OwnerID = item.OwnerID,
|
||||||
Beatmap = { Value = apiBeatmap },
|
Beatmap = { Value = apiBeatmap },
|
||||||
Ruleset = { Value = ruleset },
|
Ruleset = { Value = ruleset },
|
||||||
Expired = item.Expired
|
Expired = item.Expired,
|
||||||
|
PlaylistOrder = item.PlaylistOrder,
|
||||||
|
PlayedAt = item.PlayedAt
|
||||||
};
|
};
|
||||||
|
|
||||||
playlistItem.RequiredMods.AddRange(item.RequiredMods.Select(m => m.ToMod(rulesetInstance)));
|
playlistItem.RequiredMods.AddRange(item.RequiredMods.Select(m => m.ToMod(rulesetInstance)));
|
||||||
|
@ -39,6 +39,22 @@ namespace osu.Game.Online.Rooms
|
|||||||
[Key(7)]
|
[Key(7)]
|
||||||
public bool Expired { get; set; }
|
public bool Expired { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The order in which this <see cref="MultiplayerPlaylistItem"/> will be played relative to others.
|
||||||
|
/// Playlist items should be played in increasing order (lower values are played first).
|
||||||
|
/// </summary>
|
||||||
|
/// <remarks>
|
||||||
|
/// This is only valid for items which are not <see cref="Expired"/>. The value for expired items is undefined and should not be used.
|
||||||
|
/// </remarks>
|
||||||
|
[Key(8)]
|
||||||
|
public ushort PlaylistOrder { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The date when this <see cref="MultiplayerPlaylistItem"/> was played.
|
||||||
|
/// </summary>
|
||||||
|
[Key(9)]
|
||||||
|
public DateTimeOffset? PlayedAt { get; set; }
|
||||||
|
|
||||||
public MultiplayerPlaylistItem()
|
public MultiplayerPlaylistItem()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
@ -52,6 +68,8 @@ namespace osu.Game.Online.Rooms
|
|||||||
RequiredMods = item.RequiredMods.Select(m => new APIMod(m)).ToArray();
|
RequiredMods = item.RequiredMods.Select(m => new APIMod(m)).ToArray();
|
||||||
AllowedMods = item.AllowedMods.Select(m => new APIMod(m)).ToArray();
|
AllowedMods = item.AllowedMods.Select(m => new APIMod(m)).ToArray();
|
||||||
Expired = item.Expired;
|
Expired = item.Expired;
|
||||||
|
PlaylistOrder = item.PlaylistOrder ?? 0;
|
||||||
|
PlayedAt = item.PlayedAt;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
// 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 System;
|
||||||
|
using System.Diagnostics;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using Newtonsoft.Json;
|
using Newtonsoft.Json;
|
||||||
using osu.Framework.Bindables;
|
using osu.Framework.Bindables;
|
||||||
@ -33,6 +34,12 @@ namespace osu.Game.Online.Rooms
|
|||||||
[JsonProperty("expired")]
|
[JsonProperty("expired")]
|
||||||
public bool Expired { get; set; }
|
public bool Expired { get; set; }
|
||||||
|
|
||||||
|
[JsonProperty("playlist_order")]
|
||||||
|
public ushort? PlaylistOrder { get; set; }
|
||||||
|
|
||||||
|
[JsonProperty("played_at")]
|
||||||
|
public DateTimeOffset? PlayedAt { get; set; }
|
||||||
|
|
||||||
[JsonIgnore]
|
[JsonIgnore]
|
||||||
public IBindable<bool> Valid => valid;
|
public IBindable<bool> Valid => valid;
|
||||||
|
|
||||||
@ -79,11 +86,13 @@ namespace osu.Game.Online.Rooms
|
|||||||
|
|
||||||
public void MarkInvalid() => valid.Value = false;
|
public void MarkInvalid() => valid.Value = false;
|
||||||
|
|
||||||
public void MapObjects(RulesetStore rulesets)
|
public void MapObjects(IRulesetStore rulesets)
|
||||||
{
|
{
|
||||||
Beatmap.Value ??= apiBeatmap;
|
Beatmap.Value ??= apiBeatmap;
|
||||||
Ruleset.Value ??= rulesets.GetRuleset(RulesetID);
|
Ruleset.Value ??= rulesets.GetRuleset(RulesetID);
|
||||||
|
|
||||||
|
Debug.Assert(Ruleset.Value != null);
|
||||||
|
|
||||||
Ruleset rulesetInstance = Ruleset.Value.CreateInstance();
|
Ruleset rulesetInstance = Ruleset.Value.CreateInstance();
|
||||||
|
|
||||||
if (allowedModsBacking != null)
|
if (allowedModsBacking != null)
|
||||||
|
@ -196,6 +196,7 @@ namespace osu.Game
|
|||||||
runMigrations();
|
runMigrations();
|
||||||
|
|
||||||
dependencies.Cache(RulesetStore = new RulesetStore(contextFactory, Storage));
|
dependencies.Cache(RulesetStore = new RulesetStore(contextFactory, Storage));
|
||||||
|
dependencies.CacheAs<IRulesetStore>(RulesetStore);
|
||||||
|
|
||||||
dependencies.Cache(realmFactory = new RealmContextFactory(Storage, "client", contextFactory));
|
dependencies.Cache(realmFactory = new RealmContextFactory(Storage, "client", contextFactory));
|
||||||
|
|
||||||
|
@ -15,7 +15,6 @@ using osu.Framework.Threading;
|
|||||||
using osu.Game.Online.API;
|
using osu.Game.Online.API;
|
||||||
using osu.Game.Online.API.Requests;
|
using osu.Game.Online.API.Requests;
|
||||||
using osu.Game.Online.API.Requests.Responses;
|
using osu.Game.Online.API.Requests.Responses;
|
||||||
using osu.Game.Rulesets;
|
|
||||||
using osu.Game.Resources.Localisation.Web;
|
using osu.Game.Resources.Localisation.Web;
|
||||||
using osuTK;
|
using osuTK;
|
||||||
using osuTK.Graphics;
|
using osuTK.Graphics;
|
||||||
@ -61,9 +60,6 @@ namespace osu.Game.Overlays.BeatmapListing
|
|||||||
[Resolved]
|
[Resolved]
|
||||||
private IAPIProvider api { get; set; }
|
private IAPIProvider api { get; set; }
|
||||||
|
|
||||||
[Resolved]
|
|
||||||
private RulesetStore rulesets { get; set; }
|
|
||||||
|
|
||||||
public BeatmapListingFilterControl()
|
public BeatmapListingFilterControl()
|
||||||
{
|
{
|
||||||
RelativeSizeAxes = Axes.X;
|
RelativeSizeAxes = Axes.X;
|
||||||
|
@ -47,7 +47,7 @@ namespace osu.Game.Overlays.BeatmapSet
|
|||||||
}
|
}
|
||||||
|
|
||||||
[Resolved]
|
[Resolved]
|
||||||
private RulesetStore rulesets { get; set; }
|
private IRulesetStore rulesets { get; set; }
|
||||||
|
|
||||||
private void onRulesetChanged(ValueChangedEvent<IRulesetInfo> ruleset)
|
private void onRulesetChanged(ValueChangedEvent<IRulesetInfo> ruleset)
|
||||||
{
|
{
|
||||||
@ -57,8 +57,13 @@ namespace osu.Game.Overlays.BeatmapSet
|
|||||||
if (ruleset.NewValue == null)
|
if (ruleset.NewValue == null)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
var rulesetInstance = rulesets.GetRuleset(ruleset.NewValue.OnlineID)?.CreateInstance();
|
||||||
|
|
||||||
|
if (rulesetInstance == null)
|
||||||
|
return;
|
||||||
|
|
||||||
modsContainer.Add(new ModButton(new ModNoMod()));
|
modsContainer.Add(new ModButton(new ModNoMod()));
|
||||||
modsContainer.AddRange(rulesets.GetRuleset(ruleset.NewValue.OnlineID).CreateInstance().AllMods.Where(m => m.UserPlayable).Select(m => new ModButton(m)));
|
modsContainer.AddRange(rulesetInstance.AllMods.Where(m => m.UserPlayable).Select(m => new ModButton(m)));
|
||||||
|
|
||||||
modsContainer.ForEach(button =>
|
modsContainer.ForEach(button =>
|
||||||
{
|
{
|
||||||
|
@ -2,7 +2,6 @@
|
|||||||
// 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.Linq;
|
using System.Linq;
|
||||||
using osu.Framework.Allocation;
|
|
||||||
using osu.Framework.Bindables;
|
using osu.Framework.Bindables;
|
||||||
using osu.Framework.Graphics;
|
using osu.Framework.Graphics;
|
||||||
using osu.Framework.Graphics.Containers;
|
using osu.Framework.Graphics.Containers;
|
||||||
@ -12,7 +11,6 @@ using osu.Game.Online.API.Requests.Responses;
|
|||||||
using osu.Game.Overlays.BeatmapSet;
|
using osu.Game.Overlays.BeatmapSet;
|
||||||
using osu.Game.Overlays.BeatmapSet.Scores;
|
using osu.Game.Overlays.BeatmapSet.Scores;
|
||||||
using osu.Game.Overlays.Comments;
|
using osu.Game.Overlays.Comments;
|
||||||
using osu.Game.Rulesets;
|
|
||||||
using osuTK;
|
using osuTK;
|
||||||
using osuTK.Graphics;
|
using osuTK.Graphics;
|
||||||
|
|
||||||
@ -24,9 +22,6 @@ namespace osu.Game.Overlays
|
|||||||
public const float Y_PADDING = 25;
|
public const float Y_PADDING = 25;
|
||||||
public const float RIGHT_WIDTH = 275;
|
public const float RIGHT_WIDTH = 275;
|
||||||
|
|
||||||
[Resolved]
|
|
||||||
private RulesetStore rulesets { get; set; }
|
|
||||||
|
|
||||||
private readonly Bindable<APIBeatmapSet> beatmapSet = new Bindable<APIBeatmapSet>();
|
private readonly Bindable<APIBeatmapSet> beatmapSet = new Bindable<APIBeatmapSet>();
|
||||||
|
|
||||||
// receive input outside our bounds so we can trigger a close event on ourselves.
|
// receive input outside our bounds so we can trigger a close event on ourselves.
|
||||||
|
@ -43,9 +43,6 @@ namespace osu.Game.Overlays.Dashboard
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
[Resolved]
|
|
||||||
private IAPIProvider api { get; set; }
|
|
||||||
|
|
||||||
[Resolved]
|
[Resolved]
|
||||||
private UserLookupCache users { get; set; }
|
private UserLookupCache users { get; set; }
|
||||||
|
|
||||||
|
@ -1,21 +1,20 @@
|
|||||||
// 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 osuTK;
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Threading;
|
||||||
using osu.Framework.Allocation;
|
using osu.Framework.Allocation;
|
||||||
using osu.Framework.Bindables;
|
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.API;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Threading;
|
|
||||||
using osu.Game.Graphics.UserInterface;
|
|
||||||
using osu.Game.Rulesets;
|
|
||||||
using osu.Game.Graphics.Sprites;
|
|
||||||
using osu.Game.Graphics;
|
|
||||||
using osu.Framework.Localisation;
|
using osu.Framework.Localisation;
|
||||||
|
using osu.Game.Graphics;
|
||||||
|
using osu.Game.Graphics.Sprites;
|
||||||
|
using osu.Game.Graphics.UserInterface;
|
||||||
|
using osu.Game.Online.API;
|
||||||
using osu.Game.Online.API.Requests.Responses;
|
using osu.Game.Online.API.Requests.Responses;
|
||||||
|
using osuTK;
|
||||||
|
|
||||||
namespace osu.Game.Overlays.Profile.Sections
|
namespace osu.Game.Overlays.Profile.Sections
|
||||||
{
|
{
|
||||||
@ -24,9 +23,6 @@ namespace osu.Game.Overlays.Profile.Sections
|
|||||||
[Resolved]
|
[Resolved]
|
||||||
private IAPIProvider api { get; set; }
|
private IAPIProvider api { get; set; }
|
||||||
|
|
||||||
[Resolved]
|
|
||||||
protected RulesetStore Rulesets { get; private set; }
|
|
||||||
|
|
||||||
protected int VisiblePages;
|
protected int VisiblePages;
|
||||||
protected int ItemsPerPage;
|
protected int ItemsPerPage;
|
||||||
|
|
||||||
|
@ -25,7 +25,7 @@ namespace osu.Game.Overlays.Profile.Sections.Recent
|
|||||||
private IAPIProvider api { get; set; }
|
private IAPIProvider api { get; set; }
|
||||||
|
|
||||||
[Resolved]
|
[Resolved]
|
||||||
private RulesetStore rulesets { get; set; }
|
private IRulesetStore rulesets { get; set; }
|
||||||
|
|
||||||
private readonly APIRecentActivity activity;
|
private readonly APIRecentActivity activity;
|
||||||
|
|
||||||
|
@ -1,21 +1,21 @@
|
|||||||
// 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 osu.Framework.Graphics;
|
|
||||||
using osu.Framework.Bindables;
|
|
||||||
using osu.Game.Rulesets;
|
|
||||||
using osu.Framework.Graphics.Containers;
|
|
||||||
using osu.Game.Online.API.Requests.Responses;
|
|
||||||
using osuTK;
|
|
||||||
using osu.Framework.Allocation;
|
|
||||||
using osu.Game.Online.API;
|
|
||||||
using osu.Game.Online.API.Requests;
|
|
||||||
using osu.Game.Overlays.Rankings.Tables;
|
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
|
using osu.Framework.Allocation;
|
||||||
|
using osu.Framework.Bindables;
|
||||||
|
using osu.Framework.Graphics;
|
||||||
|
using osu.Framework.Graphics.Containers;
|
||||||
using osu.Game.Beatmaps.Drawables.Cards;
|
using osu.Game.Beatmaps.Drawables.Cards;
|
||||||
using osu.Game.Graphics.Containers;
|
using osu.Game.Graphics.Containers;
|
||||||
using osu.Game.Graphics.UserInterface;
|
using osu.Game.Graphics.UserInterface;
|
||||||
|
using osu.Game.Online.API;
|
||||||
|
using osu.Game.Online.API.Requests;
|
||||||
|
using osu.Game.Online.API.Requests.Responses;
|
||||||
|
using osu.Game.Overlays.Rankings.Tables;
|
||||||
|
using osu.Game.Rulesets;
|
||||||
|
using osuTK;
|
||||||
|
|
||||||
namespace osu.Game.Overlays.Rankings
|
namespace osu.Game.Overlays.Rankings
|
||||||
{
|
{
|
||||||
@ -29,9 +29,6 @@ namespace osu.Game.Overlays.Rankings
|
|||||||
[Resolved]
|
[Resolved]
|
||||||
private IAPIProvider api { get; set; }
|
private IAPIProvider api { get; set; }
|
||||||
|
|
||||||
[Resolved]
|
|
||||||
private RulesetStore rulesets { get; set; }
|
|
||||||
|
|
||||||
private CancellationTokenSource cancellationToken;
|
private CancellationTokenSource cancellationToken;
|
||||||
private GetSpotlightRankingsRequest getRankingsRequest;
|
private GetSpotlightRankingsRequest getRankingsRequest;
|
||||||
private GetSpotlightsRequest spotlightsRequest;
|
private GetSpotlightsRequest spotlightsRequest;
|
||||||
|
@ -67,7 +67,8 @@ namespace osu.Game.Overlays.Settings.Sections.Input
|
|||||||
},
|
},
|
||||||
new SettingsCheckbox
|
new SettingsCheckbox
|
||||||
{
|
{
|
||||||
LabelText = MouseSettingsStrings.DisableMouseWheel,
|
LabelText = MouseSettingsStrings.DisableMouseWheelVolumeAdjust,
|
||||||
|
TooltipText = MouseSettingsStrings.DisableMouseWheelVolumeAdjustTooltip,
|
||||||
Current = osuConfig.GetBindable<bool>(OsuSetting.MouseDisableWheel)
|
Current = osuConfig.GetBindable<bool>(OsuSetting.MouseDisableWheel)
|
||||||
},
|
},
|
||||||
new SettingsCheckbox
|
new SettingsCheckbox
|
||||||
|
@ -5,19 +5,14 @@ using System.Linq;
|
|||||||
using Markdig.Extensions.Yaml;
|
using Markdig.Extensions.Yaml;
|
||||||
using Markdig.Syntax;
|
using Markdig.Syntax;
|
||||||
using Markdig.Syntax.Inlines;
|
using Markdig.Syntax.Inlines;
|
||||||
using osu.Framework.Allocation;
|
|
||||||
using osu.Framework.Graphics.Containers;
|
using osu.Framework.Graphics.Containers;
|
||||||
using osu.Framework.Graphics.Containers.Markdown;
|
using osu.Framework.Graphics.Containers.Markdown;
|
||||||
using osu.Game.Graphics.Containers.Markdown;
|
using osu.Game.Graphics.Containers.Markdown;
|
||||||
using osu.Game.Online.API;
|
|
||||||
|
|
||||||
namespace osu.Game.Overlays.Wiki.Markdown
|
namespace osu.Game.Overlays.Wiki.Markdown
|
||||||
{
|
{
|
||||||
public class WikiMarkdownContainer : OsuMarkdownContainer
|
public class WikiMarkdownContainer : OsuMarkdownContainer
|
||||||
{
|
{
|
||||||
[Resolved]
|
|
||||||
private IAPIProvider api { get; set; }
|
|
||||||
|
|
||||||
public string CurrentPath
|
public string CurrentPath
|
||||||
{
|
{
|
||||||
set => DocumentUrl = value;
|
set => DocumentUrl = value;
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
// 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 osu.Game.Database;
|
using osu.Game.Database;
|
||||||
|
|
||||||
#nullable enable
|
#nullable enable
|
||||||
@ -10,7 +11,7 @@ namespace osu.Game.Rulesets
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// A representation of a ruleset's metadata.
|
/// A representation of a ruleset's metadata.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public interface IRulesetInfo : IHasOnlineID<int>
|
public interface IRulesetInfo : IHasOnlineID<int>, IEquatable<IRulesetInfo>
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The user-exposed name of this ruleset.
|
/// The user-exposed name of this ruleset.
|
||||||
|
31
osu.Game/Rulesets/IRulesetStore.cs
Normal file
31
osu.Game/Rulesets/IRulesetStore.cs
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
// 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.Collections.Generic;
|
||||||
|
|
||||||
|
#nullable enable
|
||||||
|
|
||||||
|
namespace osu.Game.Rulesets
|
||||||
|
{
|
||||||
|
public interface IRulesetStore
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Retrieve a ruleset using a known ID.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="id">The ruleset's internal ID.</param>
|
||||||
|
/// <returns>A ruleset, if available, else null.</returns>
|
||||||
|
IRulesetInfo? GetRuleset(int id);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Retrieve a ruleset using a known short name.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="shortName">The ruleset's short name.</param>
|
||||||
|
/// <returns>A ruleset, if available, else null.</returns>
|
||||||
|
IRulesetInfo? GetRuleset(string shortName);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// All available rulesets.
|
||||||
|
/// </summary>
|
||||||
|
IEnumerable<IRulesetInfo> AvailableRulesets { get; }
|
||||||
|
}
|
||||||
|
}
|
@ -49,6 +49,8 @@ namespace osu.Game.Rulesets
|
|||||||
|
|
||||||
public override bool Equals(object obj) => obj is RulesetInfo rulesetInfo && Equals(rulesetInfo);
|
public override bool Equals(object obj) => obj is RulesetInfo rulesetInfo && Equals(rulesetInfo);
|
||||||
|
|
||||||
|
public bool Equals(IRulesetInfo other) => other is RulesetInfo b && Equals(b);
|
||||||
|
|
||||||
[SuppressMessage("ReSharper", "NonReadonlyMemberInGetHashCode")]
|
[SuppressMessage("ReSharper", "NonReadonlyMemberInGetHashCode")]
|
||||||
public override int GetHashCode()
|
public override int GetHashCode()
|
||||||
{
|
{
|
||||||
|
@ -13,7 +13,7 @@ using osu.Game.Database;
|
|||||||
|
|
||||||
namespace osu.Game.Rulesets
|
namespace osu.Game.Rulesets
|
||||||
{
|
{
|
||||||
public class RulesetStore : DatabaseBackedStore, IDisposable
|
public class RulesetStore : DatabaseBackedStore, IRulesetStore, IDisposable
|
||||||
{
|
{
|
||||||
private const string ruleset_library_prefix = "osu.Game.Rulesets";
|
private const string ruleset_library_prefix = "osu.Game.Rulesets";
|
||||||
|
|
||||||
@ -236,5 +236,13 @@ namespace osu.Game.Rulesets
|
|||||||
{
|
{
|
||||||
AppDomain.CurrentDomain.AssemblyResolve -= resolveRulesetDependencyAssembly;
|
AppDomain.CurrentDomain.AssemblyResolve -= resolveRulesetDependencyAssembly;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#region Implementation of IRulesetStore
|
||||||
|
|
||||||
|
IRulesetInfo IRulesetStore.GetRuleset(int id) => GetRuleset(id);
|
||||||
|
IRulesetInfo IRulesetStore.GetRuleset(string shortName) => GetRuleset(shortName);
|
||||||
|
IEnumerable<IRulesetInfo> IRulesetStore.AvailableRulesets => AvailableRulesets;
|
||||||
|
|
||||||
|
#endregion
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -19,7 +19,6 @@ using osu.Game.Rulesets.Objects;
|
|||||||
using osu.Game.Skinning;
|
using osu.Game.Skinning;
|
||||||
using osuTK;
|
using osuTK;
|
||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
using osu.Framework.Audio.Sample;
|
|
||||||
|
|
||||||
namespace osu.Game.Rulesets.UI
|
namespace osu.Game.Rulesets.UI
|
||||||
{
|
{
|
||||||
@ -88,9 +87,6 @@ namespace osu.Game.Rulesets.UI
|
|||||||
[Resolved(CanBeNull = true)]
|
[Resolved(CanBeNull = true)]
|
||||||
private IReadOnlyList<Mod> mods { get; set; }
|
private IReadOnlyList<Mod> mods { get; set; }
|
||||||
|
|
||||||
[Resolved]
|
|
||||||
private ISampleStore sampleStore { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Creates a new <see cref="Playfield"/>.
|
/// Creates a new <see cref="Playfield"/>.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
@ -46,7 +46,7 @@ namespace osu.Game.Scoring.Legacy
|
|||||||
sw.Write(LATEST_VERSION);
|
sw.Write(LATEST_VERSION);
|
||||||
sw.Write(score.ScoreInfo.BeatmapInfo.MD5Hash);
|
sw.Write(score.ScoreInfo.BeatmapInfo.MD5Hash);
|
||||||
sw.Write(score.ScoreInfo.UserString);
|
sw.Write(score.ScoreInfo.UserString);
|
||||||
sw.Write($"lazer-{score.ScoreInfo.UserString}-{score.ScoreInfo.Date}".ComputeMD5Hash());
|
sw.Write(FormattableString.Invariant($"lazer-{score.ScoreInfo.UserString}-{score.ScoreInfo.Date}").ComputeMD5Hash());
|
||||||
sw.Write((ushort)(score.ScoreInfo.GetCount300() ?? 0));
|
sw.Write((ushort)(score.ScoreInfo.GetCount300() ?? 0));
|
||||||
sw.Write((ushort)(score.ScoreInfo.GetCount100() ?? 0));
|
sw.Write((ushort)(score.ScoreInfo.GetCount100() ?? 0));
|
||||||
sw.Write((ushort)(score.ScoreInfo.GetCount50() ?? 0));
|
sw.Write((ushort)(score.ScoreInfo.GetCount50() ?? 0));
|
||||||
@ -110,7 +110,9 @@ namespace osu.Game.Scoring.Legacy
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
replayData.AppendFormat(@"{0}|{1}|{2}|{3},", -12345, 0, 0, 0);
|
// Warning: this is purposefully hardcoded as a string rather than interpolating, as in some cultures the minus sign is not encoded as the standard ASCII U+00C2 codepoint,
|
||||||
|
// which then would break decoding.
|
||||||
|
replayData.Append(@"-12345|0|0|0");
|
||||||
return replayData.ToString();
|
return replayData.ToString();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,20 +1,15 @@
|
|||||||
// 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 osu.Framework.Allocation;
|
|
||||||
using osu.Framework.Bindables;
|
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.Beatmaps.ControlPoints;
|
using osu.Game.Beatmaps.ControlPoints;
|
||||||
using osu.Game.Graphics;
|
|
||||||
|
|
||||||
namespace osu.Game.Screens.Edit.Components.Timelines.Summary.Parts
|
namespace osu.Game.Screens.Edit.Components.Timelines.Summary.Parts
|
||||||
{
|
{
|
||||||
public class GroupVisualisation : CompositeDrawable
|
public class GroupVisualisation : CompositeDrawable
|
||||||
{
|
{
|
||||||
[Resolved]
|
|
||||||
private OsuColour colours { get; set; }
|
|
||||||
|
|
||||||
public readonly ControlPointGroup Group;
|
public readonly ControlPointGroup Group;
|
||||||
|
|
||||||
private readonly IBindableList<ControlPoint> controlPoints = new BindableList<ControlPoint>();
|
private readonly IBindableList<ControlPoint> controlPoints = new BindableList<ControlPoint>();
|
||||||
|
@ -279,9 +279,6 @@ namespace osu.Game.Screens.Edit.Compose.Components.Timeline
|
|||||||
editorClock.Start();
|
editorClock.Start();
|
||||||
}
|
}
|
||||||
|
|
||||||
[Resolved]
|
|
||||||
private EditorBeatmap beatmap { get; set; }
|
|
||||||
|
|
||||||
[Resolved]
|
[Resolved]
|
||||||
private IBeatSnapProvider beatSnapProvider { get; set; }
|
private IBeatSnapProvider beatSnapProvider { get; set; }
|
||||||
|
|
||||||
|
@ -1,12 +1,10 @@
|
|||||||
// 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 osu.Framework.Allocation;
|
|
||||||
using osu.Framework.Bindables;
|
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.Beatmaps.ControlPoints;
|
using osu.Game.Beatmaps.ControlPoints;
|
||||||
using osu.Game.Graphics;
|
|
||||||
|
|
||||||
namespace osu.Game.Screens.Edit.Compose.Components.Timeline
|
namespace osu.Game.Screens.Edit.Compose.Components.Timeline
|
||||||
{
|
{
|
||||||
@ -16,9 +14,6 @@ namespace osu.Game.Screens.Edit.Compose.Components.Timeline
|
|||||||
|
|
||||||
private readonly IBindableList<ControlPoint> controlPoints = new BindableList<ControlPoint>();
|
private readonly IBindableList<ControlPoint> controlPoints = new BindableList<ControlPoint>();
|
||||||
|
|
||||||
[Resolved]
|
|
||||||
private OsuColour colours { get; set; }
|
|
||||||
|
|
||||||
public TimelineControlPointGroup(ControlPointGroup group)
|
public TimelineControlPointGroup(ControlPointGroup group)
|
||||||
{
|
{
|
||||||
Group = group;
|
Group = group;
|
||||||
|
@ -184,9 +184,6 @@ namespace osu.Game.Screens.Edit.Compose.Components.Timeline
|
|||||||
private SamplePointPiece sampleOverrideDisplay;
|
private SamplePointPiece sampleOverrideDisplay;
|
||||||
private DifficultyPointPiece difficultyOverrideDisplay;
|
private DifficultyPointPiece difficultyOverrideDisplay;
|
||||||
|
|
||||||
[Resolved]
|
|
||||||
private EditorBeatmap beatmap { get; set; }
|
|
||||||
|
|
||||||
private DifficultyControlPoint difficultyControlPoint;
|
private DifficultyControlPoint difficultyControlPoint;
|
||||||
private SampleControlPoint sampleControlPoint;
|
private SampleControlPoint sampleControlPoint;
|
||||||
|
|
||||||
|
@ -109,9 +109,6 @@ namespace osu.Game.Screens.Edit
|
|||||||
[Resolved]
|
[Resolved]
|
||||||
private IAPIProvider api { get; set; }
|
private IAPIProvider api { get; set; }
|
||||||
|
|
||||||
[Resolved]
|
|
||||||
private MusicController music { get; set; }
|
|
||||||
|
|
||||||
[Cached]
|
[Cached]
|
||||||
public readonly EditorClipboard Clipboard = new EditorClipboard();
|
public readonly EditorClipboard Clipboard = new EditorClipboard();
|
||||||
|
|
||||||
|
@ -5,7 +5,6 @@ using osu.Framework.Allocation;
|
|||||||
using osu.Framework.Graphics;
|
using osu.Framework.Graphics;
|
||||||
using osu.Framework.Graphics.Containers;
|
using osu.Framework.Graphics.Containers;
|
||||||
using osu.Framework.Graphics.Shapes;
|
using osu.Framework.Graphics.Shapes;
|
||||||
using osu.Game.Graphics;
|
|
||||||
using osu.Game.Overlays;
|
using osu.Game.Overlays;
|
||||||
|
|
||||||
namespace osu.Game.Screens.Edit
|
namespace osu.Game.Screens.Edit
|
||||||
@ -14,9 +13,6 @@ namespace osu.Game.Screens.Edit
|
|||||||
{
|
{
|
||||||
public const int HORIZONTAL_PADDING = 100;
|
public const int HORIZONTAL_PADDING = 100;
|
||||||
|
|
||||||
[Resolved]
|
|
||||||
private OsuColour colours { get; set; }
|
|
||||||
|
|
||||||
private Container roundedContent;
|
private Container roundedContent;
|
||||||
|
|
||||||
protected override Container<Drawable> Content => roundedContent;
|
protected override Container<Drawable> Content => roundedContent;
|
||||||
|
@ -62,9 +62,6 @@ namespace osu.Game.Screens.Edit
|
|||||||
|
|
||||||
private readonly Box hoveredBackground;
|
private readonly Box hoveredBackground;
|
||||||
|
|
||||||
[Resolved]
|
|
||||||
private EditorClock clock { get; set; }
|
|
||||||
|
|
||||||
public RowBackground(object item)
|
public RowBackground(object item)
|
||||||
{
|
{
|
||||||
Item = item;
|
Item = item;
|
||||||
|
@ -15,7 +15,6 @@ using osu.Framework.Graphics.Cursor;
|
|||||||
using osu.Framework.Graphics.UserInterface;
|
using osu.Framework.Graphics.UserInterface;
|
||||||
using osu.Framework.Input.Events;
|
using osu.Framework.Input.Events;
|
||||||
using osu.Game.Database;
|
using osu.Game.Database;
|
||||||
using osu.Game.Graphics.Containers;
|
|
||||||
using osu.Game.Graphics.UserInterface;
|
using osu.Game.Graphics.UserInterface;
|
||||||
using osu.Game.Graphics.UserInterfaceV2;
|
using osu.Game.Graphics.UserInterfaceV2;
|
||||||
using osuTK;
|
using osuTK;
|
||||||
@ -36,9 +35,6 @@ namespace osu.Game.Screens.Edit.Setup
|
|||||||
[Resolved]
|
[Resolved]
|
||||||
private OsuGameBase game { get; set; }
|
private OsuGameBase game { get; set; }
|
||||||
|
|
||||||
[Resolved]
|
|
||||||
private SectionsContainer<SetupSection> sectionsContainer { get; set; }
|
|
||||||
|
|
||||||
public FileChooserLabelledTextBox(params string[] handledExtensions)
|
public FileChooserLabelledTextBox(params string[] handledExtensions)
|
||||||
{
|
{
|
||||||
this.handledExtensions = handledExtensions;
|
this.handledExtensions = handledExtensions;
|
||||||
|
@ -132,9 +132,6 @@ namespace osu.Game.Screens.Edit.Timing
|
|||||||
controlPoints.BindTo(group.ControlPoints);
|
controlPoints.BindTo(group.ControlPoints);
|
||||||
}
|
}
|
||||||
|
|
||||||
[Resolved]
|
|
||||||
private OsuColour colours { get; set; }
|
|
||||||
|
|
||||||
[BackgroundDependencyLoader]
|
[BackgroundDependencyLoader]
|
||||||
private void load()
|
private void load()
|
||||||
{
|
{
|
||||||
|
@ -23,9 +23,6 @@ namespace osu.Game.Screens.Edit.Verify
|
|||||||
{
|
{
|
||||||
private IssueTable table;
|
private IssueTable table;
|
||||||
|
|
||||||
[Resolved]
|
|
||||||
private EditorClock clock { get; set; }
|
|
||||||
|
|
||||||
[Resolved]
|
[Resolved]
|
||||||
private IBindable<WorkingBeatmap> workingBeatmap { get; set; }
|
private IBindable<WorkingBeatmap> workingBeatmap { get; set; }
|
||||||
|
|
||||||
|
@ -15,9 +15,6 @@ namespace osu.Game.Screens.Menu
|
|||||||
[Resolved]
|
[Resolved]
|
||||||
private DialogOverlay dialogOverlay { get; set; }
|
private DialogOverlay dialogOverlay { get; set; }
|
||||||
|
|
||||||
[Resolved]
|
|
||||||
private OsuGameBase osuGame { get; set; }
|
|
||||||
|
|
||||||
public StorageErrorDialog(OsuStorage storage, OsuStorageError error)
|
public StorageErrorDialog(OsuStorage storage, OsuStorageError error)
|
||||||
{
|
{
|
||||||
HeaderText = "osu! storage error";
|
HeaderText = "osu! storage error";
|
||||||
|
@ -9,7 +9,6 @@ using osu.Framework.Allocation;
|
|||||||
using osu.Framework.Bindables;
|
using osu.Framework.Bindables;
|
||||||
using osu.Framework.Graphics;
|
using osu.Framework.Graphics;
|
||||||
using osu.Framework.Logging;
|
using osu.Framework.Logging;
|
||||||
using osu.Game.Beatmaps;
|
|
||||||
using osu.Game.Online.API;
|
using osu.Game.Online.API;
|
||||||
using osu.Game.Online.Rooms;
|
using osu.Game.Online.Rooms;
|
||||||
using osu.Game.Rulesets;
|
using osu.Game.Rulesets;
|
||||||
@ -28,10 +27,7 @@ namespace osu.Game.Screens.OnlinePlay.Components
|
|||||||
private readonly Bindable<Room> joinedRoom = new Bindable<Room>();
|
private readonly Bindable<Room> joinedRoom = new Bindable<Room>();
|
||||||
|
|
||||||
[Resolved]
|
[Resolved]
|
||||||
private RulesetStore rulesets { get; set; }
|
private IRulesetStore rulesets { get; set; }
|
||||||
|
|
||||||
[Resolved]
|
|
||||||
private BeatmapManager beatmaps { get; set; }
|
|
||||||
|
|
||||||
[Resolved]
|
[Resolved]
|
||||||
private IAPIProvider api { get; set; }
|
private IAPIProvider api { get; set; }
|
||||||
|
@ -2,7 +2,6 @@
|
|||||||
// 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.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using osu.Framework.Allocation;
|
|
||||||
using osu.Game.Online.Rooms;
|
using osu.Game.Online.Rooms;
|
||||||
|
|
||||||
namespace osu.Game.Screens.OnlinePlay.Components
|
namespace osu.Game.Screens.OnlinePlay.Components
|
||||||
@ -12,9 +11,6 @@ namespace osu.Game.Screens.OnlinePlay.Components
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public class SelectionPollingComponent : RoomPollingComponent
|
public class SelectionPollingComponent : RoomPollingComponent
|
||||||
{
|
{
|
||||||
[Resolved]
|
|
||||||
private IRoomManager roomManager { get; set; }
|
|
||||||
|
|
||||||
private readonly Room room;
|
private readonly Room room;
|
||||||
|
|
||||||
public SelectionPollingComponent(Room room)
|
public SelectionPollingComponent(Room room)
|
||||||
|
@ -1,9 +1,7 @@
|
|||||||
// 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.Collections.Generic;
|
|
||||||
using System.Collections.Specialized;
|
using System.Collections.Specialized;
|
||||||
using System.Linq;
|
|
||||||
using osu.Framework.Bindables;
|
using osu.Framework.Bindables;
|
||||||
using osu.Framework.Extensions.IEnumerableExtensions;
|
using osu.Framework.Extensions.IEnumerableExtensions;
|
||||||
using osu.Framework.Graphics;
|
using osu.Framework.Graphics;
|
||||||
@ -22,13 +20,11 @@ namespace osu.Game.Screens.OnlinePlay
|
|||||||
private readonly bool allowSelection;
|
private readonly bool allowSelection;
|
||||||
private readonly bool showItemOwner;
|
private readonly bool showItemOwner;
|
||||||
|
|
||||||
public DrawableRoomPlaylist(bool allowEdit, bool allowSelection, bool reverse = false, bool showItemOwner = false)
|
public DrawableRoomPlaylist(bool allowEdit, bool allowSelection, bool showItemOwner = false)
|
||||||
{
|
{
|
||||||
this.allowEdit = allowEdit;
|
this.allowEdit = allowEdit;
|
||||||
this.allowSelection = allowSelection;
|
this.allowSelection = allowSelection;
|
||||||
this.showItemOwner = showItemOwner;
|
this.showItemOwner = showItemOwner;
|
||||||
|
|
||||||
((ReversibleFillFlowContainer)ListContainer).Reverse = reverse;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void LoadComplete()
|
protected override void LoadComplete()
|
||||||
@ -53,7 +49,7 @@ namespace osu.Game.Screens.OnlinePlay
|
|||||||
d.ScrollbarVisible = false;
|
d.ScrollbarVisible = false;
|
||||||
});
|
});
|
||||||
|
|
||||||
protected override FillFlowContainer<RearrangeableListItem<PlaylistItem>> CreateListFillFlowContainer() => new ReversibleFillFlowContainer
|
protected override FillFlowContainer<RearrangeableListItem<PlaylistItem>> CreateListFillFlowContainer() => new FillFlowContainer<RearrangeableListItem<PlaylistItem>>
|
||||||
{
|
{
|
||||||
Spacing = new Vector2(0, 2)
|
Spacing = new Vector2(0, 2)
|
||||||
};
|
};
|
||||||
@ -76,22 +72,5 @@ namespace osu.Game.Screens.OnlinePlay
|
|||||||
|
|
||||||
Items.Remove(item);
|
Items.Remove(item);
|
||||||
}
|
}
|
||||||
|
|
||||||
private class ReversibleFillFlowContainer : FillFlowContainer<RearrangeableListItem<PlaylistItem>>
|
|
||||||
{
|
|
||||||
private bool reverse;
|
|
||||||
|
|
||||||
public bool Reverse
|
|
||||||
{
|
|
||||||
get => reverse;
|
|
||||||
set
|
|
||||||
{
|
|
||||||
reverse = value;
|
|
||||||
Invalidate();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public override IEnumerable<Drawable> FlowingChildren => Reverse ? base.FlowingChildren.OrderBy(d => -GetLayoutPosition(d)) : base.FlowingChildren;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -30,9 +30,6 @@ namespace osu.Game.Screens.OnlinePlay.Lounge.Components
|
|||||||
|
|
||||||
public readonly Room Room;
|
public readonly Room Room;
|
||||||
|
|
||||||
[Resolved]
|
|
||||||
private BeatmapManager beatmaps { get; set; }
|
|
||||||
|
|
||||||
protected Container ButtonsContainer { get; private set; }
|
protected Container ButtonsContainer { get; private set; }
|
||||||
|
|
||||||
private readonly Bindable<MatchType> roomType = new Bindable<MatchType>();
|
private readonly Bindable<MatchType> roomType = new Bindable<MatchType>();
|
||||||
|
@ -33,9 +33,6 @@ namespace osu.Game.Screens.OnlinePlay.Lounge.Components
|
|||||||
[Resolved]
|
[Resolved]
|
||||||
private IRoomManager roomManager { get; set; }
|
private IRoomManager roomManager { get; set; }
|
||||||
|
|
||||||
[Resolved(CanBeNull = true)]
|
|
||||||
private LoungeSubScreen loungeSubScreen { get; set; }
|
|
||||||
|
|
||||||
// handle deselection
|
// handle deselection
|
||||||
public override bool ReceivePositionalInputAt(Vector2 screenSpacePos) => true;
|
public override bool ReceivePositionalInputAt(Vector2 screenSpacePos) => true;
|
||||||
|
|
||||||
|
@ -12,7 +12,6 @@ using osu.Framework.Graphics;
|
|||||||
using osu.Framework.Graphics.Containers;
|
using osu.Framework.Graphics.Containers;
|
||||||
using osu.Framework.Graphics.Shapes;
|
using osu.Framework.Graphics.Shapes;
|
||||||
using osu.Framework.Screens;
|
using osu.Framework.Screens;
|
||||||
using osu.Game.Beatmaps;
|
|
||||||
using osu.Game.Graphics;
|
using osu.Game.Graphics;
|
||||||
using osu.Game.Graphics.Containers;
|
using osu.Game.Graphics.Containers;
|
||||||
using osu.Game.Graphics.Sprites;
|
using osu.Game.Graphics.Sprites;
|
||||||
@ -20,7 +19,6 @@ 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.Overlays;
|
using osu.Game.Overlays;
|
||||||
using osu.Game.Rulesets;
|
|
||||||
using osu.Game.Screens.OnlinePlay.Match.Components;
|
using osu.Game.Screens.OnlinePlay.Match.Components;
|
||||||
using osuTK;
|
using osuTK;
|
||||||
|
|
||||||
@ -84,12 +82,6 @@ namespace osu.Game.Screens.OnlinePlay.Multiplayer.Match
|
|||||||
[Resolved]
|
[Resolved]
|
||||||
private MultiplayerClient client { get; set; }
|
private MultiplayerClient client { get; set; }
|
||||||
|
|
||||||
[Resolved]
|
|
||||||
private Bindable<WorkingBeatmap> beatmap { get; set; }
|
|
||||||
|
|
||||||
[Resolved]
|
|
||||||
private Bindable<RulesetInfo> ruleset { get; set; }
|
|
||||||
|
|
||||||
[Resolved]
|
[Resolved]
|
||||||
private OngoingOperationTracker ongoingOperationTracker { get; set; }
|
private OngoingOperationTracker ongoingOperationTracker { get; set; }
|
||||||
|
|
||||||
|
@ -11,7 +11,6 @@ using osu.Framework.Graphics;
|
|||||||
using osu.Framework.Threading;
|
using osu.Framework.Threading;
|
||||||
using osu.Game.Graphics;
|
using osu.Game.Graphics;
|
||||||
using osu.Game.Graphics.Backgrounds;
|
using osu.Game.Graphics.Backgrounds;
|
||||||
using osu.Game.Online.API;
|
|
||||||
using osu.Game.Online.Multiplayer;
|
using osu.Game.Online.Multiplayer;
|
||||||
using osu.Game.Screens.OnlinePlay.Components;
|
using osu.Game.Screens.OnlinePlay.Components;
|
||||||
using osuTK;
|
using osuTK;
|
||||||
@ -25,9 +24,6 @@ namespace osu.Game.Screens.OnlinePlay.Multiplayer.Match
|
|||||||
set => button.Action = value;
|
set => button.Action = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
[Resolved]
|
|
||||||
private IAPIProvider api { get; set; }
|
|
||||||
|
|
||||||
[Resolved]
|
[Resolved]
|
||||||
private OsuColour colours { get; set; }
|
private OsuColour colours { get; set; }
|
||||||
|
|
||||||
|
@ -0,0 +1,33 @@
|
|||||||
|
// 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.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using osu.Framework.Graphics;
|
||||||
|
using osu.Framework.Graphics.Containers;
|
||||||
|
using osu.Game.Online.Rooms;
|
||||||
|
using osuTK;
|
||||||
|
|
||||||
|
namespace osu.Game.Screens.OnlinePlay.Multiplayer.Match.Playlist
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// A historically-ordered list of <see cref="DrawableRoomPlaylistItem"/>s.
|
||||||
|
/// </summary>
|
||||||
|
public class MultiplayerHistoryList : DrawableRoomPlaylist
|
||||||
|
{
|
||||||
|
public MultiplayerHistoryList()
|
||||||
|
: base(false, false, true)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override FillFlowContainer<RearrangeableListItem<PlaylistItem>> CreateListFillFlowContainer() => new HistoryFillFlowContainer
|
||||||
|
{
|
||||||
|
Spacing = new Vector2(0, 2)
|
||||||
|
};
|
||||||
|
|
||||||
|
private class HistoryFillFlowContainer : FillFlowContainer<RearrangeableListItem<PlaylistItem>>
|
||||||
|
{
|
||||||
|
public override IEnumerable<Drawable> FlowingChildren => base.FlowingChildren.OfType<RearrangeableListItem<PlaylistItem>>().OrderByDescending(item => item.Model.PlayedAt);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,131 @@
|
|||||||
|
// 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 osu.Framework.Allocation;
|
||||||
|
using osu.Framework.Bindables;
|
||||||
|
using osu.Framework.Graphics;
|
||||||
|
using osu.Framework.Graphics.Containers;
|
||||||
|
using osu.Game.Graphics.UserInterface;
|
||||||
|
using osu.Game.Online.Multiplayer;
|
||||||
|
using osu.Game.Online.Rooms;
|
||||||
|
|
||||||
|
namespace osu.Game.Screens.OnlinePlay.Multiplayer.Match.Playlist
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// The multiplayer playlist, containing lists to show the items from a <see cref="MultiplayerRoom"/> in both gameplay-order and historical-order.
|
||||||
|
/// </summary>
|
||||||
|
public class MultiplayerPlaylist : MultiplayerRoomComposite
|
||||||
|
{
|
||||||
|
public readonly Bindable<MultiplayerPlaylistDisplayMode> DisplayMode = new Bindable<MultiplayerPlaylistDisplayMode>();
|
||||||
|
|
||||||
|
private MultiplayerQueueList queueList;
|
||||||
|
private MultiplayerHistoryList historyList;
|
||||||
|
private bool firstPopulation = true;
|
||||||
|
|
||||||
|
[BackgroundDependencyLoader]
|
||||||
|
private void load()
|
||||||
|
{
|
||||||
|
const float tab_control_height = 25;
|
||||||
|
|
||||||
|
InternalChildren = new Drawable[]
|
||||||
|
{
|
||||||
|
new OsuTabControl<MultiplayerPlaylistDisplayMode>
|
||||||
|
{
|
||||||
|
RelativeSizeAxes = Axes.X,
|
||||||
|
Height = tab_control_height,
|
||||||
|
Current = { BindTarget = DisplayMode }
|
||||||
|
},
|
||||||
|
new Container
|
||||||
|
{
|
||||||
|
RelativeSizeAxes = Axes.Both,
|
||||||
|
Padding = new MarginPadding { Top = tab_control_height + 5 },
|
||||||
|
Masking = true,
|
||||||
|
Children = new Drawable[]
|
||||||
|
{
|
||||||
|
queueList = new MultiplayerQueueList
|
||||||
|
{
|
||||||
|
RelativeSizeAxes = Axes.Both,
|
||||||
|
SelectedItem = { BindTarget = SelectedItem }
|
||||||
|
},
|
||||||
|
historyList = new MultiplayerHistoryList
|
||||||
|
{
|
||||||
|
RelativeSizeAxes = Axes.Both,
|
||||||
|
Alpha = 0,
|
||||||
|
SelectedItem = { BindTarget = SelectedItem }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void LoadComplete()
|
||||||
|
{
|
||||||
|
base.LoadComplete();
|
||||||
|
DisplayMode.BindValueChanged(onDisplayModeChanged, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void onDisplayModeChanged(ValueChangedEvent<MultiplayerPlaylistDisplayMode> mode)
|
||||||
|
{
|
||||||
|
historyList.FadeTo(mode.NewValue == MultiplayerPlaylistDisplayMode.History ? 1 : 0, 100);
|
||||||
|
queueList.FadeTo(mode.NewValue == MultiplayerPlaylistDisplayMode.Queue ? 1 : 0, 100);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void OnRoomUpdated()
|
||||||
|
{
|
||||||
|
base.OnRoomUpdated();
|
||||||
|
|
||||||
|
if (Room == null)
|
||||||
|
{
|
||||||
|
historyList.Items.Clear();
|
||||||
|
queueList.Items.Clear();
|
||||||
|
firstPopulation = true;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (firstPopulation)
|
||||||
|
{
|
||||||
|
foreach (var item in Room.Playlist)
|
||||||
|
addItemToLists(item);
|
||||||
|
|
||||||
|
firstPopulation = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void PlaylistItemAdded(MultiplayerPlaylistItem item)
|
||||||
|
{
|
||||||
|
base.PlaylistItemAdded(item);
|
||||||
|
addItemToLists(item);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void PlaylistItemRemoved(long item)
|
||||||
|
{
|
||||||
|
base.PlaylistItemRemoved(item);
|
||||||
|
removeItemFromLists(item);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void PlaylistItemChanged(MultiplayerPlaylistItem item)
|
||||||
|
{
|
||||||
|
base.PlaylistItemChanged(item);
|
||||||
|
|
||||||
|
removeItemFromLists(item.ID);
|
||||||
|
addItemToLists(item);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void addItemToLists(MultiplayerPlaylistItem item)
|
||||||
|
{
|
||||||
|
var apiItem = Playlist.Single(i => i.ID == item.ID);
|
||||||
|
|
||||||
|
if (item.Expired)
|
||||||
|
historyList.Items.Add(apiItem);
|
||||||
|
else
|
||||||
|
queueList.Items.Add(apiItem);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void removeItemFromLists(long item)
|
||||||
|
{
|
||||||
|
queueList.Items.RemoveAll(i => i.ID == item);
|
||||||
|
historyList.Items.RemoveAll(i => i.ID == item);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,14 @@
|
|||||||
|
// 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.
|
||||||
|
|
||||||
|
namespace osu.Game.Screens.OnlinePlay.Multiplayer.Match.Playlist
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// The type of list displayed in a <see cref="MultiplayerPlaylist"/>.
|
||||||
|
/// </summary>
|
||||||
|
public enum MultiplayerPlaylistDisplayMode
|
||||||
|
{
|
||||||
|
Queue,
|
||||||
|
History,
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,44 @@
|
|||||||
|
// 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.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using osu.Framework.Allocation;
|
||||||
|
using osu.Framework.Bindables;
|
||||||
|
using osu.Framework.Graphics;
|
||||||
|
using osu.Framework.Graphics.Containers;
|
||||||
|
using osu.Game.Online.Rooms;
|
||||||
|
using osuTK;
|
||||||
|
|
||||||
|
namespace osu.Game.Screens.OnlinePlay.Multiplayer.Match.Playlist
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// A gameplay-ordered list of <see cref="DrawableRoomPlaylistItem"/>s.
|
||||||
|
/// </summary>
|
||||||
|
public class MultiplayerQueueList : DrawableRoomPlaylist
|
||||||
|
{
|
||||||
|
public MultiplayerQueueList()
|
||||||
|
: base(false, false, true)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override FillFlowContainer<RearrangeableListItem<PlaylistItem>> CreateListFillFlowContainer() => new QueueFillFlowContainer
|
||||||
|
{
|
||||||
|
Spacing = new Vector2(0, 2)
|
||||||
|
};
|
||||||
|
|
||||||
|
private class QueueFillFlowContainer : FillFlowContainer<RearrangeableListItem<PlaylistItem>>
|
||||||
|
{
|
||||||
|
[Resolved(typeof(Room), nameof(Room.Playlist))]
|
||||||
|
private BindableList<PlaylistItem> roomPlaylist { get; set; }
|
||||||
|
|
||||||
|
protected override void LoadComplete()
|
||||||
|
{
|
||||||
|
base.LoadComplete();
|
||||||
|
roomPlaylist.BindCollectionChanged((_, __) => InvalidateLayout());
|
||||||
|
}
|
||||||
|
|
||||||
|
public override IEnumerable<Drawable> FlowingChildren => base.FlowingChildren.OfType<RearrangeableListItem<PlaylistItem>>().OrderBy(item => item.Model.PlaylistOrder);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -26,6 +26,7 @@ using osu.Game.Screens.OnlinePlay.Components;
|
|||||||
using osu.Game.Screens.OnlinePlay.Match;
|
using osu.Game.Screens.OnlinePlay.Match;
|
||||||
using osu.Game.Screens.OnlinePlay.Match.Components;
|
using osu.Game.Screens.OnlinePlay.Match.Components;
|
||||||
using osu.Game.Screens.OnlinePlay.Multiplayer.Match;
|
using osu.Game.Screens.OnlinePlay.Multiplayer.Match;
|
||||||
|
using osu.Game.Screens.OnlinePlay.Multiplayer.Match.Playlist;
|
||||||
using osu.Game.Screens.OnlinePlay.Multiplayer.Participants;
|
using osu.Game.Screens.OnlinePlay.Multiplayer.Participants;
|
||||||
using osu.Game.Screens.OnlinePlay.Multiplayer.Spectate;
|
using osu.Game.Screens.OnlinePlay.Multiplayer.Spectate;
|
||||||
using osu.Game.Screens.Play;
|
using osu.Game.Screens.Play;
|
||||||
@ -56,8 +57,6 @@ namespace osu.Game.Screens.OnlinePlay.Multiplayer
|
|||||||
[CanBeNull]
|
[CanBeNull]
|
||||||
private IDisposable readyClickOperation;
|
private IDisposable readyClickOperation;
|
||||||
|
|
||||||
private DrawableRoomPlaylist playlist;
|
|
||||||
|
|
||||||
public MultiplayerMatchSubScreen(Room room)
|
public MultiplayerMatchSubScreen(Room room)
|
||||||
: base(room)
|
: base(room)
|
||||||
{
|
{
|
||||||
@ -74,9 +73,6 @@ namespace osu.Game.Screens.OnlinePlay.Multiplayer
|
|||||||
BeatmapAvailability.BindValueChanged(updateBeatmapAvailability, true);
|
BeatmapAvailability.BindValueChanged(updateBeatmapAvailability, true);
|
||||||
UserMods.BindValueChanged(onUserModsChanged);
|
UserMods.BindValueChanged(onUserModsChanged);
|
||||||
|
|
||||||
playlist.Items.BindTo(Room.Playlist);
|
|
||||||
playlist.SelectedItem.BindTo(SelectedItem);
|
|
||||||
|
|
||||||
client.LoadRequested += onLoadRequested;
|
client.LoadRequested += onLoadRequested;
|
||||||
client.RoomUpdated += onRoomUpdated;
|
client.RoomUpdated += onRoomUpdated;
|
||||||
|
|
||||||
@ -153,10 +149,10 @@ namespace osu.Game.Screens.OnlinePlay.Multiplayer
|
|||||||
null,
|
null,
|
||||||
new Drawable[]
|
new Drawable[]
|
||||||
{
|
{
|
||||||
playlist = new DrawableRoomPlaylist(false, false, true, true)
|
new MultiplayerPlaylist
|
||||||
{
|
{
|
||||||
RelativeSizeAxes = Axes.Both,
|
RelativeSizeAxes = Axes.Both
|
||||||
},
|
}
|
||||||
},
|
},
|
||||||
new[]
|
new[]
|
||||||
{
|
{
|
||||||
|
@ -4,6 +4,7 @@
|
|||||||
using JetBrains.Annotations;
|
using JetBrains.Annotations;
|
||||||
using osu.Framework.Allocation;
|
using osu.Framework.Allocation;
|
||||||
using osu.Game.Online.Multiplayer;
|
using osu.Game.Online.Multiplayer;
|
||||||
|
using osu.Game.Online.Rooms;
|
||||||
|
|
||||||
namespace osu.Game.Screens.OnlinePlay.Multiplayer
|
namespace osu.Game.Screens.OnlinePlay.Multiplayer
|
||||||
{
|
{
|
||||||
@ -23,14 +24,20 @@ namespace osu.Game.Screens.OnlinePlay.Multiplayer
|
|||||||
Client.UserLeft += invokeUserLeft;
|
Client.UserLeft += invokeUserLeft;
|
||||||
Client.UserKicked += invokeUserKicked;
|
Client.UserKicked += invokeUserKicked;
|
||||||
Client.UserJoined += invokeUserJoined;
|
Client.UserJoined += invokeUserJoined;
|
||||||
|
Client.ItemAdded += invokeItemAdded;
|
||||||
|
Client.ItemRemoved += invokeItemRemoved;
|
||||||
|
Client.ItemChanged += invokeItemChanged;
|
||||||
|
|
||||||
OnRoomUpdated();
|
OnRoomUpdated();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void invokeOnRoomUpdated() => Scheduler.AddOnce(OnRoomUpdated);
|
private void invokeOnRoomUpdated() => Scheduler.AddOnce(OnRoomUpdated);
|
||||||
private void invokeUserJoined(MultiplayerRoomUser user) => Scheduler.AddOnce(UserJoined, user);
|
private void invokeUserJoined(MultiplayerRoomUser user) => Scheduler.Add(() => UserJoined(user));
|
||||||
private void invokeUserKicked(MultiplayerRoomUser user) => Scheduler.AddOnce(UserKicked, user);
|
private void invokeUserKicked(MultiplayerRoomUser user) => Scheduler.Add(() => UserKicked(user));
|
||||||
private void invokeUserLeft(MultiplayerRoomUser user) => Scheduler.AddOnce(UserLeft, user);
|
private void invokeUserLeft(MultiplayerRoomUser user) => Scheduler.Add(() => UserLeft(user));
|
||||||
|
private void invokeItemAdded(MultiplayerPlaylistItem item) => Schedule(() => PlaylistItemAdded(item));
|
||||||
|
private void invokeItemRemoved(long item) => Schedule(() => PlaylistItemRemoved(item));
|
||||||
|
private void invokeItemChanged(MultiplayerPlaylistItem item) => Schedule(() => PlaylistItemChanged(item));
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Invoked when a user has joined the room.
|
/// Invoked when a user has joined the room.
|
||||||
@ -56,6 +63,30 @@ namespace osu.Game.Screens.OnlinePlay.Multiplayer
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Invoked when a playlist item is added to the room.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="item">The added playlist item.</param>
|
||||||
|
protected virtual void PlaylistItemAdded(MultiplayerPlaylistItem item)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Invoked when a playlist item is removed from the room.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="item">The ID of the removed playlist item.</param>
|
||||||
|
protected virtual void PlaylistItemRemoved(long item)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Invoked when a playlist item is changed in the room.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="item">The new playlist item, with an existing item's ID.</param>
|
||||||
|
protected virtual void PlaylistItemChanged(MultiplayerPlaylistItem item)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Invoked when any change occurs to the multiplayer room.
|
/// Invoked when any change occurs to the multiplayer room.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@ -71,6 +102,9 @@ namespace osu.Game.Screens.OnlinePlay.Multiplayer
|
|||||||
Client.UserLeft -= invokeUserLeft;
|
Client.UserLeft -= invokeUserLeft;
|
||||||
Client.UserKicked -= invokeUserKicked;
|
Client.UserKicked -= invokeUserKicked;
|
||||||
Client.UserJoined -= invokeUserJoined;
|
Client.UserJoined -= invokeUserJoined;
|
||||||
|
Client.ItemAdded -= invokeItemAdded;
|
||||||
|
Client.ItemRemoved -= invokeItemRemoved;
|
||||||
|
Client.ItemChanged -= invokeItemChanged;
|
||||||
}
|
}
|
||||||
|
|
||||||
base.Dispose(isDisposing);
|
base.Dispose(isDisposing);
|
||||||
|
@ -35,7 +35,7 @@ namespace osu.Game.Screens.OnlinePlay.Multiplayer.Participants
|
|||||||
private IAPIProvider api { get; set; }
|
private IAPIProvider api { get; set; }
|
||||||
|
|
||||||
[Resolved]
|
[Resolved]
|
||||||
private RulesetStore rulesets { get; set; }
|
private IRulesetStore rulesets { get; set; }
|
||||||
|
|
||||||
private SpriteIcon crown;
|
private SpriteIcon crown;
|
||||||
|
|
||||||
@ -185,9 +185,9 @@ namespace osu.Game.Screens.OnlinePlay.Multiplayer.Participants
|
|||||||
const double fade_time = 50;
|
const double fade_time = 50;
|
||||||
|
|
||||||
// Todo: Should use the room's selected item to determine ruleset.
|
// Todo: Should use the room's selected item to determine ruleset.
|
||||||
var ruleset = rulesets.GetRuleset(0).CreateInstance();
|
var ruleset = rulesets.GetRuleset(0)?.CreateInstance();
|
||||||
|
|
||||||
int? currentModeRank = User.User?.RulesetsStatistics?.GetValueOrDefault(ruleset.ShortName)?.GlobalRank;
|
int? currentModeRank = ruleset != null ? User.User?.RulesetsStatistics?.GetValueOrDefault(ruleset.ShortName)?.GlobalRank : null;
|
||||||
userRankText.Text = currentModeRank != null ? $"#{currentModeRank.Value:N0}" : string.Empty;
|
userRankText.Text = currentModeRank != null ? $"#{currentModeRank.Value:N0}" : string.Empty;
|
||||||
|
|
||||||
userStateDisplay.UpdateStatus(User.State, User.BeatmapAvailability);
|
userStateDisplay.UpdateStatus(User.State, User.BeatmapAvailability);
|
||||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user