mirror of
https://github.com/ppy/osu.git
synced 2025-01-13 02:32:55 +08:00
Merge branch 'master' into open-profile-hotkey
This commit is contained in:
commit
11d480997a
@ -52,7 +52,7 @@
|
|||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="ppy.osu.Game.Resources" Version="2022.810.0" />
|
<PackageReference Include="ppy.osu.Game.Resources" Version="2022.810.0" />
|
||||||
<PackageReference Include="ppy.osu.Framework.Android" Version="2022.810.0" />
|
<PackageReference Include="ppy.osu.Framework.Android" Version="2022.810.2" />
|
||||||
</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. -->
|
||||||
|
@ -36,6 +36,23 @@ namespace osu.Game.Tests.NonVisual
|
|||||||
Assert.IsTrue(beatmapSetA.Beatmaps.Single().AudioEquals(beatmapSetB.Beatmaps.Single()));
|
Assert.IsTrue(beatmapSetA.Beatmaps.Single().AudioEquals(beatmapSetB.Beatmaps.Single()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void TestAudioEqualityCaseSensitivity()
|
||||||
|
{
|
||||||
|
var beatmapSetA = TestResources.CreateTestBeatmapSetInfo(1);
|
||||||
|
var beatmapSetB = TestResources.CreateTestBeatmapSetInfo(1);
|
||||||
|
|
||||||
|
// empty by default so let's set it..
|
||||||
|
beatmapSetA.Beatmaps.First().Metadata.AudioFile = "audio.mp3";
|
||||||
|
beatmapSetB.Beatmaps.First().Metadata.AudioFile = "audio.mp3";
|
||||||
|
|
||||||
|
addAudioFile(beatmapSetA, "abc", "AuDiO.mP3");
|
||||||
|
addAudioFile(beatmapSetB, "abc", "audio.mp3");
|
||||||
|
|
||||||
|
Assert.AreNotEqual(beatmapSetA, beatmapSetB);
|
||||||
|
Assert.IsTrue(beatmapSetA.Beatmaps.Single().AudioEquals(beatmapSetB.Beatmaps.Single()));
|
||||||
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
public void TestAudioEqualitySameHash()
|
public void TestAudioEqualitySameHash()
|
||||||
{
|
{
|
||||||
|
@ -199,8 +199,8 @@ namespace osu.Game.Beatmaps
|
|||||||
Debug.Assert(x.BeatmapSet != null);
|
Debug.Assert(x.BeatmapSet != null);
|
||||||
Debug.Assert(y.BeatmapSet != null);
|
Debug.Assert(y.BeatmapSet != null);
|
||||||
|
|
||||||
string? fileHashX = x.BeatmapSet.Files.FirstOrDefault(f => f.Filename == getFilename(x.Metadata))?.File.Hash;
|
string? fileHashX = x.BeatmapSet.GetFile(getFilename(x.Metadata))?.File.Hash;
|
||||||
string? fileHashY = y.BeatmapSet.Files.FirstOrDefault(f => f.Filename == getFilename(y.Metadata))?.File.Hash;
|
string? fileHashY = y.BeatmapSet.GetFile(getFilename(y.Metadata))?.File.Hash;
|
||||||
|
|
||||||
return fileHashX == fileHashY;
|
return fileHashX == fileHashY;
|
||||||
}
|
}
|
||||||
|
@ -1,8 +1,6 @@
|
|||||||
// 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.
|
||||||
|
|
||||||
#nullable disable
|
|
||||||
|
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using osu.Framework.Localisation;
|
using osu.Framework.Localisation;
|
||||||
|
|
||||||
|
@ -300,7 +300,7 @@ namespace osu.Game.Beatmaps
|
|||||||
stream.Seek(0, SeekOrigin.Begin);
|
stream.Seek(0, SeekOrigin.Begin);
|
||||||
|
|
||||||
// AddFile generally handles updating/replacing files, but this is a case where the filename may have also changed so let's delete for simplicity.
|
// AddFile generally handles updating/replacing files, but this is a case where the filename may have also changed so let's delete for simplicity.
|
||||||
var existingFileInfo = setInfo.Files.SingleOrDefault(f => string.Equals(f.Filename, beatmapInfo.Path, StringComparison.OrdinalIgnoreCase));
|
var existingFileInfo = beatmapInfo.Path != null ? setInfo.GetFile(beatmapInfo.Path) : null;
|
||||||
string targetFilename = createBeatmapFilenameFromMetadata(beatmapInfo);
|
string targetFilename = createBeatmapFilenameFromMetadata(beatmapInfo);
|
||||||
|
|
||||||
// ensure that two difficulties from the set don't point at the same beatmap file.
|
// ensure that two difficulties from the set don't point at the same beatmap file.
|
||||||
|
@ -84,13 +84,6 @@ namespace osu.Game.Beatmaps
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Returns the storage path for the file in this beatmapset with the given filename, if any exists, otherwise null.
|
|
||||||
/// The path returned is relative to the user file storage.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="filename">The name of the file to get the storage path of.</param>
|
|
||||||
public string? GetPathForFile(string filename) => Files.SingleOrDefault(f => string.Equals(f.Filename, filename, StringComparison.OrdinalIgnoreCase))?.File.GetStoragePath();
|
|
||||||
|
|
||||||
public bool Equals(BeatmapSetInfo? other)
|
public bool Equals(BeatmapSetInfo? other)
|
||||||
{
|
{
|
||||||
if (ReferenceEquals(this, other)) return true;
|
if (ReferenceEquals(this, other)) return true;
|
||||||
|
33
osu.Game/Beatmaps/BeatmapSetInfoExtensions.cs
Normal file
33
osu.Game/Beatmaps/BeatmapSetInfoExtensions.cs
Normal file
@ -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;
|
||||||
|
using System.Linq;
|
||||||
|
using osu.Game.Database;
|
||||||
|
using osu.Game.Extensions;
|
||||||
|
using osu.Game.Models;
|
||||||
|
|
||||||
|
namespace osu.Game.Beatmaps
|
||||||
|
{
|
||||||
|
public static class BeatmapSetInfoExtensions
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Returns the storage path for the file in this beatmapset with the given filename, if any exists, otherwise null.
|
||||||
|
/// The path returned is relative to the user file storage.
|
||||||
|
/// The lookup is case insensitive.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="model">The model to operate on.</param>
|
||||||
|
/// <param name="filename">The name of the file to get the storage path of.</param>
|
||||||
|
public static string? GetPathForFile(this IHasRealmFiles model, string filename) => model.GetFile(filename)?.File.GetStoragePath();
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Returns the file usage for the file in this beatmapset with the given filename, if any exists, otherwise null.
|
||||||
|
/// The path returned is relative to the user file storage.
|
||||||
|
/// The lookup is case insensitive.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="model">The model to operate on.</param>
|
||||||
|
/// <param name="filename">The name of the file to get the storage path of.</param>
|
||||||
|
public static RealmNamedFileUsage? GetFile(this IHasRealmFiles model, string filename) =>
|
||||||
|
model.Files.SingleOrDefault(f => string.Equals(f.Filename, filename, StringComparison.OrdinalIgnoreCase));
|
||||||
|
}
|
||||||
|
}
|
@ -3,16 +3,20 @@
|
|||||||
|
|
||||||
#nullable disable
|
#nullable disable
|
||||||
|
|
||||||
using System.ComponentModel;
|
using osu.Framework.Localisation;
|
||||||
|
using osu.Game.Localisation;
|
||||||
|
|
||||||
namespace osu.Game.Configuration
|
namespace osu.Game.Configuration
|
||||||
{
|
{
|
||||||
public enum BackgroundSource
|
public enum BackgroundSource
|
||||||
{
|
{
|
||||||
|
[LocalisableDescription(typeof(SkinSettingsStrings), nameof(SkinSettingsStrings.SkinSectionHeader))]
|
||||||
Skin,
|
Skin,
|
||||||
|
|
||||||
|
[LocalisableDescription(typeof(GameplaySettingsStrings), nameof(GameplaySettingsStrings.BeatmapHeader))]
|
||||||
Beatmap,
|
Beatmap,
|
||||||
|
|
||||||
[Description("Beatmap (with storyboard / video)")]
|
[LocalisableDescription(typeof(UserInterfaceStrings), nameof(UserInterfaceStrings.BeatmapWithStoryboard))]
|
||||||
BeatmapWithStoryboard,
|
BeatmapWithStoryboard,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3,17 +3,20 @@
|
|||||||
|
|
||||||
#nullable disable
|
#nullable disable
|
||||||
|
|
||||||
using System.ComponentModel;
|
using osu.Framework.Localisation;
|
||||||
|
using osu.Game.Localisation;
|
||||||
|
|
||||||
namespace osu.Game.Configuration
|
namespace osu.Game.Configuration
|
||||||
{
|
{
|
||||||
public enum DiscordRichPresenceMode
|
public enum DiscordRichPresenceMode
|
||||||
{
|
{
|
||||||
|
[LocalisableDescription(typeof(OnlineSettingsStrings), nameof(OnlineSettingsStrings.DiscordPresenceOff))]
|
||||||
Off,
|
Off,
|
||||||
|
|
||||||
[Description("Hide identifiable information")]
|
[LocalisableDescription(typeof(OnlineSettingsStrings), nameof(OnlineSettingsStrings.HideIdentifiableInformation))]
|
||||||
Limited,
|
Limited,
|
||||||
|
|
||||||
|
[LocalisableDescription(typeof(OnlineSettingsStrings), nameof(OnlineSettingsStrings.DiscordPresenceFull))]
|
||||||
Full
|
Full
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3,17 +3,20 @@
|
|||||||
|
|
||||||
#nullable disable
|
#nullable disable
|
||||||
|
|
||||||
using System.ComponentModel;
|
using osu.Framework.Localisation;
|
||||||
|
using osu.Game.Localisation;
|
||||||
|
|
||||||
namespace osu.Game.Configuration
|
namespace osu.Game.Configuration
|
||||||
{
|
{
|
||||||
public enum HUDVisibilityMode
|
public enum HUDVisibilityMode
|
||||||
{
|
{
|
||||||
|
[LocalisableDescription(typeof(GameplaySettingsStrings), nameof(GameplaySettingsStrings.NeverShowHUD))]
|
||||||
Never,
|
Never,
|
||||||
|
|
||||||
[Description("Hide during gameplay")]
|
[LocalisableDescription(typeof(GameplaySettingsStrings), nameof(GameplaySettingsStrings.HideDuringGameplay))]
|
||||||
HideDuringGameplay,
|
HideDuringGameplay,
|
||||||
|
|
||||||
|
[LocalisableDescription(typeof(GameplaySettingsStrings), nameof(GameplaySettingsStrings.AlwaysShowHUD))]
|
||||||
Always
|
Always
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3,16 +3,17 @@
|
|||||||
|
|
||||||
#nullable disable
|
#nullable disable
|
||||||
|
|
||||||
using System.ComponentModel;
|
using osu.Framework.Localisation;
|
||||||
|
using osu.Game.Localisation;
|
||||||
|
|
||||||
namespace osu.Game.Configuration
|
namespace osu.Game.Configuration
|
||||||
{
|
{
|
||||||
public enum RandomSelectAlgorithm
|
public enum RandomSelectAlgorithm
|
||||||
{
|
{
|
||||||
[Description("Never repeat")]
|
[LocalisableDescription(typeof(UserInterfaceStrings), nameof(UserInterfaceStrings.NeverRepeat))]
|
||||||
RandomPermutation,
|
RandomPermutation,
|
||||||
|
|
||||||
[Description("True Random")]
|
[LocalisableDescription(typeof(UserInterfaceStrings), nameof(UserInterfaceStrings.TrueRandom))]
|
||||||
Random
|
Random
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3,17 +3,23 @@
|
|||||||
|
|
||||||
#nullable disable
|
#nullable disable
|
||||||
|
|
||||||
using System.ComponentModel;
|
using osu.Framework.Localisation;
|
||||||
|
using osu.Game.Localisation;
|
||||||
|
|
||||||
namespace osu.Game.Configuration
|
namespace osu.Game.Configuration
|
||||||
{
|
{
|
||||||
public enum ScalingMode
|
public enum ScalingMode
|
||||||
{
|
{
|
||||||
|
[LocalisableDescription(typeof(LayoutSettingsStrings), nameof(LayoutSettingsStrings.ScalingOff))]
|
||||||
Off,
|
Off,
|
||||||
|
|
||||||
|
[LocalisableDescription(typeof(LayoutSettingsStrings), nameof(LayoutSettingsStrings.ScaleEverything))]
|
||||||
Everything,
|
Everything,
|
||||||
|
|
||||||
[Description("Excluding overlays")]
|
[LocalisableDescription(typeof(LayoutSettingsStrings), nameof(LayoutSettingsStrings.ScaleEverythingExcludingOverlays))]
|
||||||
ExcludeOverlays,
|
ExcludeOverlays,
|
||||||
|
|
||||||
|
[LocalisableDescription(typeof(LayoutSettingsStrings), nameof(LayoutSettingsStrings.ScaleGameplay))]
|
||||||
Gameplay,
|
Gameplay,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3,16 +3,17 @@
|
|||||||
|
|
||||||
#nullable disable
|
#nullable disable
|
||||||
|
|
||||||
using System.ComponentModel;
|
using osu.Framework.Localisation;
|
||||||
|
using osu.Game.Localisation;
|
||||||
|
|
||||||
namespace osu.Game.Configuration
|
namespace osu.Game.Configuration
|
||||||
{
|
{
|
||||||
public enum ScreenshotFormat
|
public enum ScreenshotFormat
|
||||||
{
|
{
|
||||||
[Description("JPG (web-friendly)")]
|
[LocalisableDescription(typeof(GraphicsSettingsStrings), nameof(GraphicsSettingsStrings.Jpg))]
|
||||||
Jpg = 1,
|
Jpg = 1,
|
||||||
|
|
||||||
[Description("PNG (lossless)")]
|
[LocalisableDescription(typeof(GraphicsSettingsStrings), nameof(GraphicsSettingsStrings.Png))]
|
||||||
Png = 2
|
Png = 2
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3,6 +3,9 @@
|
|||||||
|
|
||||||
#nullable disable
|
#nullable disable
|
||||||
|
|
||||||
|
using osu.Framework.Localisation;
|
||||||
|
using osu.Game.Localisation;
|
||||||
|
|
||||||
namespace osu.Game.Configuration
|
namespace osu.Game.Configuration
|
||||||
{
|
{
|
||||||
public enum SeasonalBackgroundMode
|
public enum SeasonalBackgroundMode
|
||||||
@ -10,16 +13,19 @@ namespace osu.Game.Configuration
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Seasonal backgrounds are shown regardless of season, if at all available.
|
/// Seasonal backgrounds are shown regardless of season, if at all available.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
[LocalisableDescription(typeof(UserInterfaceStrings), nameof(UserInterfaceStrings.AlwaysSeasonalBackground))]
|
||||||
Always,
|
Always,
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Seasonal backgrounds are shown only during their corresponding season.
|
/// Seasonal backgrounds are shown only during their corresponding season.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
[LocalisableDescription(typeof(UserInterfaceStrings), nameof(UserInterfaceStrings.SometimesSeasonalBackground))]
|
||||||
Sometimes,
|
Sometimes,
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Seasonal backgrounds are never shown.
|
/// Seasonal backgrounds are never shown.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
[LocalisableDescription(typeof(UserInterfaceStrings), nameof(UserInterfaceStrings.NeverSeasonalBackground))]
|
||||||
Never
|
Never
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using osu.Game.Beatmaps;
|
||||||
using osu.Game.Models;
|
using osu.Game.Models;
|
||||||
|
|
||||||
namespace osu.Game.Database
|
namespace osu.Game.Database
|
||||||
@ -11,8 +12,16 @@ namespace osu.Game.Database
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public interface IHasRealmFiles
|
public interface IHasRealmFiles
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Available files in this model, with locally filenames.
|
||||||
|
/// When performing lookups, consider using <see cref="BeatmapSetInfoExtensions.GetFile"/> or <see cref="BeatmapSetInfoExtensions.GetPathForFile"/> to do case-insensitive lookups.
|
||||||
|
/// </summary>
|
||||||
IList<RealmNamedFileUsage> Files { get; }
|
IList<RealmNamedFileUsage> Files { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// A combined hash representing the model, based on the files it contains.
|
||||||
|
/// Implementation specific.
|
||||||
|
/// </summary>
|
||||||
string Hash { get; set; }
|
string Hash { get; set; }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -42,7 +42,7 @@ namespace osu.Game.Database
|
|||||||
[Resolved]
|
[Resolved]
|
||||||
private RealmAccess realmAccess { get; set; } = null!;
|
private RealmAccess realmAccess { get; set; } = null!;
|
||||||
|
|
||||||
[Resolved]
|
[Resolved(canBeNull: true)] // canBeNull required while we remain on mono for mobile platforms.
|
||||||
private DesktopGameHost? desktopGameHost { get; set; }
|
private DesktopGameHost? desktopGameHost { get; set; }
|
||||||
|
|
||||||
[Resolved]
|
[Resolved]
|
||||||
|
@ -7,6 +7,7 @@ using System.Diagnostics;
|
|||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using osu.Framework.Platform;
|
using osu.Framework.Platform;
|
||||||
|
using osu.Game.Beatmaps;
|
||||||
using osu.Game.Extensions;
|
using osu.Game.Extensions;
|
||||||
using osu.Game.Models;
|
using osu.Game.Models;
|
||||||
using osu.Game.Overlays.Notifications;
|
using osu.Game.Overlays.Notifications;
|
||||||
@ -79,7 +80,7 @@ namespace osu.Game.Database
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public void AddFile(TModel item, Stream contents, string filename, Realm realm)
|
public void AddFile(TModel item, Stream contents, string filename, Realm realm)
|
||||||
{
|
{
|
||||||
var existing = item.Files.FirstOrDefault(f => string.Equals(f.Filename, filename, StringComparison.OrdinalIgnoreCase));
|
var existing = item.GetFile(filename);
|
||||||
|
|
||||||
if (existing != null)
|
if (existing != null)
|
||||||
{
|
{
|
||||||
|
@ -173,6 +173,11 @@ namespace osu.Game.Database
|
|||||||
if (!Filename.EndsWith(realm_extension, StringComparison.Ordinal))
|
if (!Filename.EndsWith(realm_extension, StringComparison.Ordinal))
|
||||||
Filename += realm_extension;
|
Filename += realm_extension;
|
||||||
|
|
||||||
|
#if DEBUG
|
||||||
|
if (!DebugUtils.IsNUnitRunning)
|
||||||
|
applyFilenameSchemaSuffix(ref Filename);
|
||||||
|
#endif
|
||||||
|
|
||||||
string newerVersionFilename = $"{Filename.Replace(realm_extension, string.Empty)}_newer_version{realm_extension}";
|
string newerVersionFilename = $"{Filename.Replace(realm_extension, string.Empty)}_newer_version{realm_extension}";
|
||||||
|
|
||||||
// Attempt to recover a newer database version if available.
|
// Attempt to recover a newer database version if available.
|
||||||
@ -212,6 +217,51 @@ namespace osu.Game.Database
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Some developers may be annoyed if a newer version migration (ie. caused by testing a pull request)
|
||||||
|
/// cause their test database to be unusable with previous versions.
|
||||||
|
/// To get around this, store development databases against their realm version.
|
||||||
|
/// Note that this means changes made on newer realm versions will disappear.
|
||||||
|
/// </summary>
|
||||||
|
private void applyFilenameSchemaSuffix(ref string filename)
|
||||||
|
{
|
||||||
|
string originalFilename = filename;
|
||||||
|
|
||||||
|
filename = getVersionedFilename(schema_version);
|
||||||
|
|
||||||
|
// First check if the current realm version already exists...
|
||||||
|
if (storage.Exists(filename))
|
||||||
|
return;
|
||||||
|
|
||||||
|
// Check for a previous version we can use as a base database to migrate from...
|
||||||
|
for (int i = schema_version - 1; i >= 0; i--)
|
||||||
|
{
|
||||||
|
string previousFilename = getVersionedFilename(i);
|
||||||
|
|
||||||
|
if (storage.Exists(previousFilename))
|
||||||
|
{
|
||||||
|
copyPreviousVersion(previousFilename, filename);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Finally, check for a non-versioned file exists (aka before this method was added)...
|
||||||
|
if (storage.Exists(originalFilename))
|
||||||
|
copyPreviousVersion(originalFilename, filename);
|
||||||
|
|
||||||
|
void copyPreviousVersion(string previousFilename, string newFilename)
|
||||||
|
{
|
||||||
|
using (var previous = storage.GetStream(previousFilename))
|
||||||
|
using (var current = storage.CreateFileSafely(newFilename))
|
||||||
|
{
|
||||||
|
Logger.Log(@$"Copying previous realm database {previousFilename} to {newFilename} for migration to schema version {schema_version}");
|
||||||
|
previous.CopyTo(current);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
string getVersionedFilename(int version) => originalFilename.Replace(realm_extension, $"_{version}{realm_extension}");
|
||||||
|
}
|
||||||
|
|
||||||
private void attemptRecoverFromFile(string recoveryFilename)
|
private void attemptRecoverFromFile(string recoveryFilename)
|
||||||
{
|
{
|
||||||
Logger.Log($@"Performing recovery from {recoveryFilename}", LoggingTarget.Database);
|
Logger.Log($@"Performing recovery from {recoveryFilename}", LoggingTarget.Database);
|
||||||
|
@ -1,8 +1,6 @@
|
|||||||
// 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.
|
||||||
|
|
||||||
#nullable disable
|
|
||||||
|
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using osu.Framework.Graphics;
|
using osu.Framework.Graphics;
|
||||||
@ -15,8 +13,9 @@ namespace osu.Game.Input.Bindings
|
|||||||
{
|
{
|
||||||
public class GlobalActionContainer : DatabasedKeyBindingContainer<GlobalAction>, IHandleGlobalKeyboardInput
|
public class GlobalActionContainer : DatabasedKeyBindingContainer<GlobalAction>, IHandleGlobalKeyboardInput
|
||||||
{
|
{
|
||||||
private readonly Drawable handler;
|
private readonly Drawable? handler;
|
||||||
private InputManager parentInputManager;
|
|
||||||
|
private InputManager? parentInputManager;
|
||||||
|
|
||||||
public GlobalActionContainer(OsuGameBase game)
|
public GlobalActionContainer(OsuGameBase game)
|
||||||
: base(matchingMode: KeyCombinationMatchingMode.Modifiers)
|
: base(matchingMode: KeyCombinationMatchingMode.Modifiers)
|
||||||
@ -32,7 +31,10 @@ namespace osu.Game.Input.Bindings
|
|||||||
parentInputManager = GetContainingInputManager();
|
parentInputManager = GetContainingInputManager();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// IMPORTANT: Do not change the order of key bindings in this list.
|
||||||
|
// It is used to decide the order of precedence (see note in DatabasedKeyBindingContainer).
|
||||||
public override IEnumerable<IKeyBinding> DefaultKeyBindings => GlobalKeyBindings
|
public override IEnumerable<IKeyBinding> DefaultKeyBindings => GlobalKeyBindings
|
||||||
|
.Concat(OverlayKeyBindings)
|
||||||
.Concat(EditorKeyBindings)
|
.Concat(EditorKeyBindings)
|
||||||
.Concat(InGameKeyBindings)
|
.Concat(InGameKeyBindings)
|
||||||
.Concat(SongSelectKeyBindings)
|
.Concat(SongSelectKeyBindings)
|
||||||
@ -40,26 +42,6 @@ namespace osu.Game.Input.Bindings
|
|||||||
|
|
||||||
public IEnumerable<KeyBinding> GlobalKeyBindings => new[]
|
public IEnumerable<KeyBinding> GlobalKeyBindings => new[]
|
||||||
{
|
{
|
||||||
new KeyBinding(InputKey.F6, GlobalAction.ToggleNowPlaying),
|
|
||||||
new KeyBinding(InputKey.F8, GlobalAction.ToggleChat),
|
|
||||||
new KeyBinding(InputKey.F9, GlobalAction.ToggleSocial),
|
|
||||||
new KeyBinding(InputKey.F10, GlobalAction.ToggleGameplayMouseButtons),
|
|
||||||
new KeyBinding(InputKey.F12, GlobalAction.TakeScreenshot),
|
|
||||||
new KeyBinding(new[] { InputKey.Control, InputKey.Shift, InputKey.F }, GlobalAction.ToggleFPSDisplay),
|
|
||||||
|
|
||||||
new KeyBinding(new[] { InputKey.Control, InputKey.Alt, InputKey.R }, GlobalAction.ResetInputSettings),
|
|
||||||
new KeyBinding(new[] { InputKey.Control, InputKey.T }, GlobalAction.ToggleToolbar),
|
|
||||||
new KeyBinding(new[] { InputKey.Control, InputKey.O }, GlobalAction.ToggleSettings),
|
|
||||||
new KeyBinding(new[] { InputKey.Control, InputKey.D }, GlobalAction.ToggleBeatmapListing),
|
|
||||||
new KeyBinding(new[] { InputKey.Control, InputKey.N }, GlobalAction.ToggleNotifications),
|
|
||||||
new KeyBinding(new[] { InputKey.Control, InputKey.P }, GlobalAction.ToggleProfile),
|
|
||||||
new KeyBinding(new[] { InputKey.Control, InputKey.Shift, InputKey.S }, GlobalAction.ToggleSkinEditor),
|
|
||||||
|
|
||||||
new KeyBinding(InputKey.Escape, GlobalAction.Back),
|
|
||||||
new KeyBinding(InputKey.ExtraMouseButton1, GlobalAction.Back),
|
|
||||||
|
|
||||||
new KeyBinding(new[] { InputKey.Alt, InputKey.Home }, GlobalAction.Home),
|
|
||||||
|
|
||||||
new KeyBinding(InputKey.Up, GlobalAction.SelectPrevious),
|
new KeyBinding(InputKey.Up, GlobalAction.SelectPrevious),
|
||||||
new KeyBinding(InputKey.Down, GlobalAction.SelectNext),
|
new KeyBinding(InputKey.Down, GlobalAction.SelectNext),
|
||||||
|
|
||||||
@ -70,7 +52,32 @@ namespace osu.Game.Input.Bindings
|
|||||||
new KeyBinding(InputKey.Enter, GlobalAction.Select),
|
new KeyBinding(InputKey.Enter, GlobalAction.Select),
|
||||||
new KeyBinding(InputKey.KeypadEnter, GlobalAction.Select),
|
new KeyBinding(InputKey.KeypadEnter, GlobalAction.Select),
|
||||||
|
|
||||||
|
new KeyBinding(InputKey.Escape, GlobalAction.Back),
|
||||||
|
new KeyBinding(InputKey.ExtraMouseButton1, GlobalAction.Back),
|
||||||
|
|
||||||
|
new KeyBinding(new[] { InputKey.Alt, InputKey.Home }, GlobalAction.Home),
|
||||||
|
|
||||||
|
new KeyBinding(new[] { InputKey.Control, InputKey.Shift, InputKey.F }, GlobalAction.ToggleFPSDisplay),
|
||||||
|
new KeyBinding(new[] { InputKey.Control, InputKey.T }, GlobalAction.ToggleToolbar),
|
||||||
|
new KeyBinding(new[] { InputKey.Control, InputKey.Shift, InputKey.S }, GlobalAction.ToggleSkinEditor),
|
||||||
|
new KeyBinding(new[] { InputKey.Control, InputKey.P }, GlobalAction.ToggleProfile),
|
||||||
|
|
||||||
|
new KeyBinding(new[] { InputKey.Control, InputKey.Alt, InputKey.R }, GlobalAction.ResetInputSettings),
|
||||||
|
|
||||||
new KeyBinding(new[] { InputKey.Control, InputKey.Shift, InputKey.R }, GlobalAction.RandomSkin),
|
new KeyBinding(new[] { InputKey.Control, InputKey.Shift, InputKey.R }, GlobalAction.RandomSkin),
|
||||||
|
|
||||||
|
new KeyBinding(InputKey.F10, GlobalAction.ToggleGameplayMouseButtons),
|
||||||
|
new KeyBinding(InputKey.F12, GlobalAction.TakeScreenshot),
|
||||||
|
};
|
||||||
|
|
||||||
|
public IEnumerable<KeyBinding> OverlayKeyBindings => new[]
|
||||||
|
{
|
||||||
|
new KeyBinding(InputKey.F8, GlobalAction.ToggleChat),
|
||||||
|
new KeyBinding(InputKey.F6, GlobalAction.ToggleNowPlaying),
|
||||||
|
new KeyBinding(InputKey.F9, GlobalAction.ToggleSocial),
|
||||||
|
new KeyBinding(new[] { InputKey.Control, InputKey.D }, GlobalAction.ToggleBeatmapListing),
|
||||||
|
new KeyBinding(new[] { InputKey.Control, InputKey.O }, GlobalAction.ToggleSettings),
|
||||||
|
new KeyBinding(new[] { InputKey.Control, InputKey.N }, GlobalAction.ToggleNotifications),
|
||||||
};
|
};
|
||||||
|
|
||||||
public IEnumerable<KeyBinding> EditorKeyBindings => new[]
|
public IEnumerable<KeyBinding> EditorKeyBindings => new[]
|
||||||
|
@ -3,8 +3,9 @@
|
|||||||
|
|
||||||
#nullable disable
|
#nullable disable
|
||||||
|
|
||||||
using System.ComponentModel;
|
|
||||||
using osu.Framework.Input;
|
using osu.Framework.Input;
|
||||||
|
using osu.Framework.Localisation;
|
||||||
|
using osu.Game.Localisation;
|
||||||
|
|
||||||
namespace osu.Game.Input
|
namespace osu.Game.Input
|
||||||
{
|
{
|
||||||
@ -17,18 +18,20 @@ namespace osu.Game.Input
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// The mouse cursor will be free to move outside the game window.
|
/// The mouse cursor will be free to move outside the game window.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
[LocalisableDescription(typeof(MouseSettingsStrings), nameof(MouseSettingsStrings.NeverConfine))]
|
||||||
Never,
|
Never,
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The mouse cursor will be locked to the window bounds during gameplay,
|
/// The mouse cursor will be locked to the window bounds during gameplay,
|
||||||
/// but may otherwise move freely.
|
/// but may otherwise move freely.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[Description("During Gameplay")]
|
[LocalisableDescription(typeof(MouseSettingsStrings), nameof(MouseSettingsStrings.ConfineDuringGameplay))]
|
||||||
DuringGameplay,
|
DuringGameplay,
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The mouse cursor will always be locked to the window bounds while the game has focus.
|
/// The mouse cursor will always be locked to the window bounds while the game has focus.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
[LocalisableDescription(typeof(MouseSettingsStrings), nameof(MouseSettingsStrings.AlwaysConfine))]
|
||||||
Always
|
Always
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -104,6 +104,31 @@ namespace osu.Game.Localisation
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public static LocalisableString IncreaseFirstObjectVisibility => new TranslatableString(getKey(@"increase_first_object_visibility"), @"Increase visibility of first object when visual impairment mods are enabled");
|
public static LocalisableString IncreaseFirstObjectVisibility => new TranslatableString(getKey(@"increase_first_object_visibility"), @"Increase visibility of first object when visual impairment mods are enabled");
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// "Hide during gameplay"
|
||||||
|
/// </summary>
|
||||||
|
public static LocalisableString HideDuringGameplay => new TranslatableString(getKey(@"hide_during_gameplay"), @"Hide during gameplay");
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// "Always"
|
||||||
|
/// </summary>
|
||||||
|
public static LocalisableString AlwaysShowHUD => new TranslatableString(getKey(@"always_show_hud"), @"Always");
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// "Never"
|
||||||
|
/// </summary>
|
||||||
|
public static LocalisableString NeverShowHUD => new TranslatableString(getKey(@"never_show_hud"), @"Never");
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// "Standardised"
|
||||||
|
/// </summary>
|
||||||
|
public static LocalisableString StandardisedScoreDisplay => new TranslatableString(getKey(@"standardised_score_display"), @"Standardised");
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// "Classic"
|
||||||
|
/// </summary>
|
||||||
|
public static LocalisableString ClassicScoreDisplay => new TranslatableString(getKey(@"classic_score_display"), @"Classic");
|
||||||
|
|
||||||
private static string getKey(string key) => $"{prefix}:{key}";
|
private static string getKey(string key) => $"{prefix}:{key}";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -129,6 +129,16 @@ namespace osu.Game.Localisation
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public static LocalisableString UseHardwareAcceleration => new TranslatableString(getKey(@"use_hardware_acceleration"), @"Use hardware acceleration");
|
public static LocalisableString UseHardwareAcceleration => new TranslatableString(getKey(@"use_hardware_acceleration"), @"Use hardware acceleration");
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// "JPG (web-friendly)"
|
||||||
|
/// </summary>
|
||||||
|
public static LocalisableString Jpg => new TranslatableString(getKey(@"jpg_web_friendly"), @"JPG (web-friendly)");
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// "PNG (lossless)"
|
||||||
|
/// </summary>
|
||||||
|
public static LocalisableString Png => new TranslatableString(getKey(@"png_lossless"), @"PNG (lossless)");
|
||||||
|
|
||||||
private static string getKey(string key) => $"{prefix}:{key}";
|
private static string getKey(string key) => $"{prefix}:{key}";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -19,6 +19,11 @@ namespace osu.Game.Localisation
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public static LocalisableString GlobalKeyBindingHeader => new TranslatableString(getKey(@"global_key_binding_header"), @"Global");
|
public static LocalisableString GlobalKeyBindingHeader => new TranslatableString(getKey(@"global_key_binding_header"), @"Global");
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// "Overlays"
|
||||||
|
/// </summary>
|
||||||
|
public static LocalisableString OverlaysSection => new TranslatableString(getKey(@"overlays_section"), @"Overlays");
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// "Song Select"
|
/// "Song Select"
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
@ -29,6 +29,26 @@ namespace osu.Game.Localisation
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public static LocalisableString FullscreenMacOSNote => new TranslatableString(getKey(@"fullscreen_macos_note"), @"Using fullscreen on macOS makes interacting with the menu bar and spaces no longer work, and may lead to freezes if a system dialog is presented. Using borderless is recommended.");
|
public static LocalisableString FullscreenMacOSNote => new TranslatableString(getKey(@"fullscreen_macos_note"), @"Using fullscreen on macOS makes interacting with the menu bar and spaces no longer work, and may lead to freezes if a system dialog is presented. Using borderless is recommended.");
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// "Excluding overlays"
|
||||||
|
/// </summary>
|
||||||
|
public static LocalisableString ScaleEverythingExcludingOverlays => new TranslatableString(getKey(@"scale_everything_excluding_overlays"), @"Excluding overlays");
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// "Everything"
|
||||||
|
/// </summary>
|
||||||
|
public static LocalisableString ScaleEverything => new TranslatableString(getKey(@"scale_everything"), @"Everything");
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// "Gameplay"
|
||||||
|
/// </summary>
|
||||||
|
public static LocalisableString ScaleGameplay => new TranslatableString(getKey(@"scale_gameplay"), @"Gameplay");
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// "Off"
|
||||||
|
/// </summary>
|
||||||
|
public static LocalisableString ScalingOff => new TranslatableString(getKey(@"scaling_off"), @"Off");
|
||||||
|
|
||||||
private static string getKey(string key) => $@"{prefix}:{key}";
|
private static string getKey(string key) => $@"{prefix}:{key}";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -64,6 +64,21 @@ namespace osu.Game.Localisation
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public static LocalisableString HighPrecisionPlatformWarning => new TranslatableString(getKey(@"high_precision_platform_warning"), @"This setting has known issues on your platform. If you encounter problems, it is recommended to adjust sensitivity externally and keep this disabled for now.");
|
public static LocalisableString HighPrecisionPlatformWarning => new TranslatableString(getKey(@"high_precision_platform_warning"), @"This setting has known issues on your platform. If you encounter problems, it is recommended to adjust sensitivity externally and keep this disabled for now.");
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// "Always"
|
||||||
|
/// </summary>
|
||||||
|
public static LocalisableString AlwaysConfine => new TranslatableString(getKey(@"always_confine"), @"Always");
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// "During Gameplay"
|
||||||
|
/// </summary>
|
||||||
|
public static LocalisableString ConfineDuringGameplay => new TranslatableString(getKey(@"confine_during_gameplay"), @"During Gameplay");
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// "Never"
|
||||||
|
/// </summary>
|
||||||
|
public static LocalisableString NeverConfine => new TranslatableString(getKey(@"never_confine"), @"Never");
|
||||||
|
|
||||||
private static string getKey(string key) => $@"{prefix}:{key}";
|
private static string getKey(string key) => $@"{prefix}:{key}";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -64,6 +64,21 @@ namespace osu.Game.Localisation
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public static LocalisableString ShowExplicitContent => new TranslatableString(getKey(@"show_explicit_content"), @"Show explicit content in search results");
|
public static LocalisableString ShowExplicitContent => new TranslatableString(getKey(@"show_explicit_content"), @"Show explicit content in search results");
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// "Hide identifiable information"
|
||||||
|
/// </summary>
|
||||||
|
public static LocalisableString HideIdentifiableInformation => new TranslatableString(getKey(@"hide_identifiable_information"), @"Hide identifiable information");
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// "Full"
|
||||||
|
/// </summary>
|
||||||
|
public static LocalisableString DiscordPresenceFull => new TranslatableString(getKey(@"discord_presence_full"), @"Full");
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// "Off"
|
||||||
|
/// </summary>
|
||||||
|
public static LocalisableString DiscordPresenceOff => new TranslatableString(getKey(@"discord_presence_off"), @"Off");
|
||||||
|
|
||||||
private static string getKey(string key) => $"{prefix}:{key}";
|
private static string getKey(string key) => $"{prefix}:{key}";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -14,6 +14,21 @@ namespace osu.Game.Localisation
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public static LocalisableString Rulesets => new TranslatableString(getKey(@"rulesets"), @"Rulesets");
|
public static LocalisableString Rulesets => new TranslatableString(getKey(@"rulesets"), @"Rulesets");
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// "None"
|
||||||
|
/// </summary>
|
||||||
|
public static LocalisableString BorderNone => new TranslatableString(getKey(@"no_borders"), @"None");
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// "Corners"
|
||||||
|
/// </summary>
|
||||||
|
public static LocalisableString BorderCorners => new TranslatableString(getKey(@"corner_borders"), @"Corners");
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// "Full"
|
||||||
|
/// </summary>
|
||||||
|
public static LocalisableString BorderFull => new TranslatableString(getKey(@"full_borders"), @"Full");
|
||||||
|
|
||||||
private static string getKey(string key) => $@"{prefix}:{key}";
|
private static string getKey(string key) => $@"{prefix}:{key}";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -114,6 +114,46 @@ namespace osu.Game.Localisation
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public static LocalisableString NoLimit => new TranslatableString(getKey(@"no_limit"), @"no limit");
|
public static LocalisableString NoLimit => new TranslatableString(getKey(@"no_limit"), @"no limit");
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// "Beatmap (with storyboard / video)"
|
||||||
|
/// </summary>
|
||||||
|
public static LocalisableString BeatmapWithStoryboard => new TranslatableString(getKey(@"beatmap_with_storyboard"), @"Beatmap (with storyboard / video)");
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// "Always"
|
||||||
|
/// </summary>
|
||||||
|
public static LocalisableString AlwaysSeasonalBackground => new TranslatableString(getKey(@"always_seasonal_backgrounds"), @"Always");
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// "Never"
|
||||||
|
/// </summary>
|
||||||
|
public static LocalisableString NeverSeasonalBackground => new TranslatableString(getKey(@"never_seasonal_backgrounds"), @"Never");
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// "Sometimes"
|
||||||
|
/// </summary>
|
||||||
|
public static LocalisableString SometimesSeasonalBackground => new TranslatableString(getKey(@"sometimes_seasonal_backgrounds"), @"Sometimes");
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// "Sequential"
|
||||||
|
/// </summary>
|
||||||
|
public static LocalisableString SequentialHotkeyStyle => new TranslatableString(getKey(@"mods_sequential_hotkeys"), @"Sequential");
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// "Classic"
|
||||||
|
/// </summary>
|
||||||
|
public static LocalisableString ClassicHotkeyStyle => new TranslatableString(getKey(@"mods_classic_hotkeys"), @"Classic");
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// "Never repeat"
|
||||||
|
/// </summary>
|
||||||
|
public static LocalisableString NeverRepeat => new TranslatableString(getKey(@"never_repeat_random"), @"Never repeat");
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// "True Random"
|
||||||
|
/// </summary>
|
||||||
|
public static LocalisableString TrueRandom => new TranslatableString(getKey(@"true_random"), @"True Random");
|
||||||
|
|
||||||
private static string getKey(string key) => $"{prefix}:{key}";
|
private static string getKey(string key) => $"{prefix}:{key}";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,7 +1,9 @@
|
|||||||
// 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.Localisation;
|
||||||
using osu.Game.Rulesets.Mods;
|
using osu.Game.Rulesets.Mods;
|
||||||
|
using osu.Game.Localisation;
|
||||||
|
|
||||||
namespace osu.Game.Overlays.Mods.Input
|
namespace osu.Game.Overlays.Mods.Input
|
||||||
{
|
{
|
||||||
@ -15,6 +17,7 @@ namespace osu.Game.Overlays.Mods.Input
|
|||||||
/// Individual letters in a row trigger the mods in a sequential fashion.
|
/// Individual letters in a row trigger the mods in a sequential fashion.
|
||||||
/// Uses <see cref="SequentialModHotkeyHandler"/>.
|
/// Uses <see cref="SequentialModHotkeyHandler"/>.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
[LocalisableDescription(typeof(UserInterfaceStrings), nameof(UserInterfaceStrings.SequentialHotkeyStyle))]
|
||||||
Sequential,
|
Sequential,
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@ -22,6 +25,7 @@ namespace osu.Game.Overlays.Mods.Input
|
|||||||
/// One keybinding can toggle between what used to be <see cref="MultiMod"/>s on stable,
|
/// One keybinding can toggle between what used to be <see cref="MultiMod"/>s on stable,
|
||||||
/// and some mods in a column may not have any hotkeys at all.
|
/// and some mods in a column may not have any hotkeys at all.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
[LocalisableDescription(typeof(UserInterfaceStrings), nameof(UserInterfaceStrings.ClassicHotkeyStyle))]
|
||||||
Classic
|
Classic
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,8 +1,6 @@
|
|||||||
// 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.
|
||||||
|
|
||||||
#nullable disable
|
|
||||||
|
|
||||||
using osu.Framework.Graphics;
|
using osu.Framework.Graphics;
|
||||||
using osu.Framework.Graphics.Sprites;
|
using osu.Framework.Graphics.Sprites;
|
||||||
using osu.Framework.Localisation;
|
using osu.Framework.Localisation;
|
||||||
@ -23,6 +21,7 @@ namespace osu.Game.Overlays.Settings.Sections.Input
|
|||||||
public GlobalKeyBindingsSection(GlobalActionContainer manager)
|
public GlobalKeyBindingsSection(GlobalActionContainer manager)
|
||||||
{
|
{
|
||||||
Add(new DefaultBindingsSubsection(manager));
|
Add(new DefaultBindingsSubsection(manager));
|
||||||
|
Add(new OverlayBindingsSubsection(manager));
|
||||||
Add(new AudioControlKeyBindingsSubsection(manager));
|
Add(new AudioControlKeyBindingsSubsection(manager));
|
||||||
Add(new SongSelectKeyBindingSubsection(manager));
|
Add(new SongSelectKeyBindingSubsection(manager));
|
||||||
Add(new InGameKeyBindingsSubsection(manager));
|
Add(new InGameKeyBindingsSubsection(manager));
|
||||||
@ -40,6 +39,17 @@ namespace osu.Game.Overlays.Settings.Sections.Input
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private class OverlayBindingsSubsection : KeyBindingsSubsection
|
||||||
|
{
|
||||||
|
protected override LocalisableString Header => InputSettingsStrings.OverlaysSection;
|
||||||
|
|
||||||
|
public OverlayBindingsSubsection(GlobalActionContainer manager)
|
||||||
|
: base(null)
|
||||||
|
{
|
||||||
|
Defaults = manager.OverlayKeyBindings;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private class SongSelectKeyBindingSubsection : KeyBindingsSubsection
|
private class SongSelectKeyBindingSubsection : KeyBindingsSubsection
|
||||||
{
|
{
|
||||||
protected override LocalisableString Header => InputSettingsStrings.SongSelectSection;
|
protected override LocalisableString Header => InputSettingsStrings.SongSelectSection;
|
||||||
|
@ -5,6 +5,7 @@
|
|||||||
|
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
|
using osu.Game.Beatmaps;
|
||||||
using osu.Game.IO.FileAbstraction;
|
using osu.Game.IO.FileAbstraction;
|
||||||
using osu.Game.Rulesets.Edit.Checks.Components;
|
using osu.Game.Rulesets.Edit.Checks.Components;
|
||||||
using osu.Game.Storyboards;
|
using osu.Game.Storyboards;
|
||||||
|
@ -5,6 +5,7 @@
|
|||||||
|
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
|
using osu.Game.Beatmaps;
|
||||||
using osu.Game.Rulesets.Edit.Checks.Components;
|
using osu.Game.Rulesets.Edit.Checks.Components;
|
||||||
|
|
||||||
namespace osu.Game.Rulesets.Edit.Checks
|
namespace osu.Game.Rulesets.Edit.Checks
|
||||||
|
@ -16,6 +16,8 @@ using osu.Game.Rulesets.Mods;
|
|||||||
using osu.Game.Rulesets.Objects;
|
using osu.Game.Rulesets.Objects;
|
||||||
using osu.Game.Rulesets.Replays;
|
using osu.Game.Rulesets.Replays;
|
||||||
using osu.Game.Scoring;
|
using osu.Game.Scoring;
|
||||||
|
using osu.Framework.Localisation;
|
||||||
|
using osu.Game.Localisation;
|
||||||
|
|
||||||
namespace osu.Game.Rulesets.Scoring
|
namespace osu.Game.Rulesets.Scoring
|
||||||
{
|
{
|
||||||
@ -636,7 +638,10 @@ namespace osu.Game.Rulesets.Scoring
|
|||||||
|
|
||||||
public enum ScoringMode
|
public enum ScoringMode
|
||||||
{
|
{
|
||||||
|
[LocalisableDescription(typeof(GameplaySettingsStrings), nameof(GameplaySettingsStrings.StandardisedScoreDisplay))]
|
||||||
Standardised,
|
Standardised,
|
||||||
|
|
||||||
|
[LocalisableDescription(typeof(GameplaySettingsStrings), nameof(GameplaySettingsStrings.ClassicScoreDisplay))]
|
||||||
Classic
|
Classic
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3,12 +3,20 @@
|
|||||||
|
|
||||||
#nullable disable
|
#nullable disable
|
||||||
|
|
||||||
|
using osu.Framework.Localisation;
|
||||||
|
using osu.Game.Localisation;
|
||||||
|
|
||||||
namespace osu.Game.Rulesets.UI
|
namespace osu.Game.Rulesets.UI
|
||||||
{
|
{
|
||||||
public enum PlayfieldBorderStyle
|
public enum PlayfieldBorderStyle
|
||||||
{
|
{
|
||||||
|
[LocalisableDescription(typeof(RulesetSettingsStrings), nameof(RulesetSettingsStrings.BorderNone))]
|
||||||
None,
|
None,
|
||||||
|
|
||||||
|
[LocalisableDescription(typeof(RulesetSettingsStrings), nameof(RulesetSettingsStrings.BorderCorners))]
|
||||||
Corners,
|
Corners,
|
||||||
|
|
||||||
|
[LocalisableDescription(typeof(RulesetSettingsStrings), nameof(RulesetSettingsStrings.BorderFull))]
|
||||||
Full
|
Full
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -4,7 +4,6 @@
|
|||||||
#nullable disable
|
#nullable disable
|
||||||
|
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Linq;
|
|
||||||
using osu.Framework.Allocation;
|
using osu.Framework.Allocation;
|
||||||
using osu.Framework.Bindables;
|
using osu.Framework.Bindables;
|
||||||
using osu.Framework.Graphics;
|
using osu.Framework.Graphics;
|
||||||
@ -78,7 +77,7 @@ namespace osu.Game.Screens.Edit.Setup
|
|||||||
|
|
||||||
// remove the previous background for now.
|
// remove the previous background for now.
|
||||||
// in the future we probably want to check if this is being used elsewhere (other difficulties?)
|
// in the future we probably want to check if this is being used elsewhere (other difficulties?)
|
||||||
var oldFile = set.Files.FirstOrDefault(f => f.Filename == working.Value.Metadata.BackgroundFile);
|
var oldFile = set.GetFile(working.Value.Metadata.BackgroundFile);
|
||||||
|
|
||||||
using (var stream = source.OpenRead())
|
using (var stream = source.OpenRead())
|
||||||
{
|
{
|
||||||
@ -107,7 +106,7 @@ namespace osu.Game.Screens.Edit.Setup
|
|||||||
|
|
||||||
// remove the previous audio track for now.
|
// remove the previous audio track for now.
|
||||||
// in the future we probably want to check if this is being used elsewhere (other difficulties?)
|
// in the future we probably want to check if this is being used elsewhere (other difficulties?)
|
||||||
var oldFile = set.Files.FirstOrDefault(f => f.Filename == working.Value.Metadata.AudioFile);
|
var oldFile = set.GetFile(working.Value.Metadata.AudioFile);
|
||||||
|
|
||||||
using (var stream = source.OpenRead())
|
using (var stream = source.OpenRead())
|
||||||
{
|
{
|
||||||
|
@ -10,6 +10,7 @@ using System.Threading;
|
|||||||
using Newtonsoft.Json;
|
using Newtonsoft.Json;
|
||||||
using osu.Framework.Logging;
|
using osu.Framework.Logging;
|
||||||
using osu.Framework.Platform;
|
using osu.Framework.Platform;
|
||||||
|
using osu.Game.Beatmaps;
|
||||||
using osu.Game.Database;
|
using osu.Game.Database;
|
||||||
using osu.Game.Extensions;
|
using osu.Game.Extensions;
|
||||||
using osu.Game.IO;
|
using osu.Game.IO;
|
||||||
@ -49,7 +50,7 @@ namespace osu.Game.Skinning
|
|||||||
|
|
||||||
protected override void Populate(SkinInfo model, ArchiveReader? archive, Realm realm, CancellationToken cancellationToken = default)
|
protected override void Populate(SkinInfo model, ArchiveReader? archive, Realm realm, CancellationToken cancellationToken = default)
|
||||||
{
|
{
|
||||||
var skinInfoFile = model.Files.SingleOrDefault(f => f.Filename == skin_info_file);
|
var skinInfoFile = model.GetFile(skin_info_file);
|
||||||
|
|
||||||
if (skinInfoFile != null)
|
if (skinInfoFile != null)
|
||||||
{
|
{
|
||||||
@ -129,7 +130,7 @@ namespace osu.Game.Skinning
|
|||||||
authorLine,
|
authorLine,
|
||||||
};
|
};
|
||||||
|
|
||||||
var existingFile = item.Files.SingleOrDefault(f => f.Filename.Equals(@"skin.ini", StringComparison.OrdinalIgnoreCase));
|
var existingFile = item.GetFile(@"skin.ini");
|
||||||
|
|
||||||
if (existingFile == null)
|
if (existingFile == null)
|
||||||
{
|
{
|
||||||
@ -163,7 +164,7 @@ namespace osu.Game.Skinning
|
|||||||
{
|
{
|
||||||
Logger.Log($"Skin {item}'s skin.ini had issues and has been removed. Please report this and provide the problematic skin.", LoggingTarget.Database, LogLevel.Important);
|
Logger.Log($"Skin {item}'s skin.ini had issues and has been removed. Please report this and provide the problematic skin.", LoggingTarget.Database, LogLevel.Important);
|
||||||
|
|
||||||
var existingIni = item.Files.SingleOrDefault(f => f.Filename.Equals(@"skin.ini", StringComparison.OrdinalIgnoreCase));
|
var existingIni = item.GetFile(@"skin.ini");
|
||||||
if (existingIni != null)
|
if (existingIni != null)
|
||||||
item.Files.Remove(existingIni);
|
item.Files.Remove(existingIni);
|
||||||
|
|
||||||
@ -248,7 +249,7 @@ namespace osu.Game.Skinning
|
|||||||
{
|
{
|
||||||
string filename = @$"{drawableInfo.Key}.json";
|
string filename = @$"{drawableInfo.Key}.json";
|
||||||
|
|
||||||
var oldFile = s.Files.FirstOrDefault(f => f.Filename == filename);
|
var oldFile = s.GetFile(filename);
|
||||||
|
|
||||||
if (oldFile != null)
|
if (oldFile != null)
|
||||||
modelManager.ReplaceFile(oldFile, streamContent, s.Realm);
|
modelManager.ReplaceFile(oldFile, streamContent, s.Realm);
|
||||||
|
@ -1,10 +1,6 @@
|
|||||||
// 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.
|
||||||
|
|
||||||
#nullable disable
|
|
||||||
|
|
||||||
using System;
|
|
||||||
using System.Linq;
|
|
||||||
using osu.Framework.Allocation;
|
using osu.Framework.Allocation;
|
||||||
using osu.Framework.Bindables;
|
using osu.Framework.Bindables;
|
||||||
using osu.Framework.Graphics;
|
using osu.Framework.Graphics;
|
||||||
@ -12,14 +8,14 @@ using osu.Framework.Graphics.Containers;
|
|||||||
using osu.Framework.Graphics.Textures;
|
using osu.Framework.Graphics.Textures;
|
||||||
using osu.Framework.Graphics.Video;
|
using osu.Framework.Graphics.Video;
|
||||||
using osu.Game.Beatmaps;
|
using osu.Game.Beatmaps;
|
||||||
using osu.Game.Extensions;
|
|
||||||
|
|
||||||
namespace osu.Game.Storyboards.Drawables
|
namespace osu.Game.Storyboards.Drawables
|
||||||
{
|
{
|
||||||
public class DrawableStoryboardVideo : CompositeDrawable
|
public class DrawableStoryboardVideo : CompositeDrawable
|
||||||
{
|
{
|
||||||
public readonly StoryboardVideo Video;
|
public readonly StoryboardVideo Video;
|
||||||
private Video video;
|
|
||||||
|
private Video? drawableVideo;
|
||||||
|
|
||||||
public override bool RemoveWhenNotAlive => false;
|
public override bool RemoveWhenNotAlive => false;
|
||||||
|
|
||||||
@ -33,7 +29,7 @@ namespace osu.Game.Storyboards.Drawables
|
|||||||
[BackgroundDependencyLoader(true)]
|
[BackgroundDependencyLoader(true)]
|
||||||
private void load(IBindable<WorkingBeatmap> beatmap, TextureStore textureStore)
|
private void load(IBindable<WorkingBeatmap> beatmap, TextureStore textureStore)
|
||||||
{
|
{
|
||||||
string path = beatmap.Value.BeatmapSetInfo?.Files.FirstOrDefault(f => f.Filename.Equals(Video.Path, StringComparison.OrdinalIgnoreCase))?.File.GetStoragePath();
|
string? path = beatmap.Value.BeatmapSetInfo?.GetPathForFile(Video.Path);
|
||||||
|
|
||||||
if (path == null)
|
if (path == null)
|
||||||
return;
|
return;
|
||||||
@ -43,7 +39,7 @@ namespace osu.Game.Storyboards.Drawables
|
|||||||
if (stream == null)
|
if (stream == null)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
InternalChild = video = new Video(stream, false)
|
InternalChild = drawableVideo = new Video(stream, false)
|
||||||
{
|
{
|
||||||
RelativeSizeAxes = Axes.Both,
|
RelativeSizeAxes = Axes.Both,
|
||||||
FillMode = FillMode.Fill,
|
FillMode = FillMode.Fill,
|
||||||
@ -57,12 +53,12 @@ namespace osu.Game.Storyboards.Drawables
|
|||||||
{
|
{
|
||||||
base.LoadComplete();
|
base.LoadComplete();
|
||||||
|
|
||||||
if (video == null) return;
|
if (drawableVideo == null) return;
|
||||||
|
|
||||||
using (video.BeginAbsoluteSequence(Video.StartTime))
|
using (drawableVideo.BeginAbsoluteSequence(Video.StartTime))
|
||||||
{
|
{
|
||||||
Schedule(() => video.PlaybackPosition = Time.Current - Video.StartTime);
|
Schedule(() => drawableVideo.PlaybackPosition = Time.Current - Video.StartTime);
|
||||||
video.FadeIn(500);
|
drawableVideo.FadeIn(500);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,14 +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.
|
||||||
|
|
||||||
#nullable disable
|
|
||||||
|
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using osu.Framework.Graphics.Textures;
|
using osu.Framework.Graphics.Textures;
|
||||||
using osu.Game.Beatmaps;
|
using osu.Game.Beatmaps;
|
||||||
using osu.Game.Extensions;
|
|
||||||
using osu.Game.Rulesets.Mods;
|
using osu.Game.Rulesets.Mods;
|
||||||
using osu.Game.Storyboards.Drawables;
|
using osu.Game.Storyboards.Drawables;
|
||||||
|
|
||||||
@ -90,12 +86,12 @@ namespace osu.Game.Storyboards
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public DrawableStoryboard CreateDrawable(IReadOnlyList<Mod> mods = null) =>
|
public DrawableStoryboard CreateDrawable(IReadOnlyList<Mod>? mods = null) =>
|
||||||
new DrawableStoryboard(this, mods);
|
new DrawableStoryboard(this, mods);
|
||||||
|
|
||||||
public Texture GetTextureFromPath(string path, TextureStore textureStore)
|
public Texture? GetTextureFromPath(string path, TextureStore textureStore)
|
||||||
{
|
{
|
||||||
string storyboardPath = BeatmapInfo.BeatmapSet?.Files.FirstOrDefault(f => f.Filename.Equals(path, StringComparison.OrdinalIgnoreCase))?.File.GetStoragePath();
|
string? storyboardPath = BeatmapInfo.BeatmapSet?.GetPathForFile(path);
|
||||||
|
|
||||||
if (!string.IsNullOrEmpty(storyboardPath))
|
if (!string.IsNullOrEmpty(storyboardPath))
|
||||||
return textureStore.Get(storyboardPath);
|
return textureStore.Get(storyboardPath);
|
||||||
|
@ -110,7 +110,7 @@ namespace osu.Game.Tests.Visual
|
|||||||
// Specific to tests, the player can be disposed without OnExiting() ever being called.
|
// Specific to tests, the player can be disposed without OnExiting() ever being called.
|
||||||
// We should make sure that the gameplay session has finished even in this case.
|
// We should make sure that the gameplay session has finished even in this case.
|
||||||
if (LoadedBeatmapSuccessfully)
|
if (LoadedBeatmapSuccessfully)
|
||||||
spectatorClient.EndPlaying(GameplayState);
|
spectatorClient?.EndPlaying(GameplayState);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -36,7 +36,7 @@
|
|||||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||||
</PackageReference>
|
</PackageReference>
|
||||||
<PackageReference Include="Realm" Version="10.14.0" />
|
<PackageReference Include="Realm" Version="10.14.0" />
|
||||||
<PackageReference Include="ppy.osu.Framework" Version="2022.810.0" />
|
<PackageReference Include="ppy.osu.Framework" Version="2022.810.2" />
|
||||||
<PackageReference Include="ppy.osu.Game.Resources" Version="2022.810.0" />
|
<PackageReference Include="ppy.osu.Game.Resources" Version="2022.810.0" />
|
||||||
<PackageReference Include="Sentry" Version="3.19.0" />
|
<PackageReference Include="Sentry" Version="3.19.0" />
|
||||||
<PackageReference Include="SharpCompress" Version="0.32.1" />
|
<PackageReference Include="SharpCompress" Version="0.32.1" />
|
||||||
|
@ -61,7 +61,7 @@
|
|||||||
<Reference Include="System.Net.Http" />
|
<Reference Include="System.Net.Http" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup Label="Package References">
|
<ItemGroup Label="Package References">
|
||||||
<PackageReference Include="ppy.osu.Framework.iOS" Version="2022.810.0" />
|
<PackageReference Include="ppy.osu.Framework.iOS" Version="2022.810.2" />
|
||||||
<PackageReference Include="ppy.osu.Game.Resources" Version="2022.810.0" />
|
<PackageReference Include="ppy.osu.Game.Resources" Version="2022.810.0" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<!-- See https://github.com/dotnet/runtime/issues/35988 (can be removed after Xamarin uses net6.0) -->
|
<!-- See https://github.com/dotnet/runtime/issues/35988 (can be removed after Xamarin uses net6.0) -->
|
||||||
@ -84,7 +84,7 @@
|
|||||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="5.0.14" />
|
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="5.0.14" />
|
||||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite.Core" Version="5.0.14" />
|
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite.Core" Version="5.0.14" />
|
||||||
<PackageReference Include="Newtonsoft.Json" Version="13.0.1" />
|
<PackageReference Include="Newtonsoft.Json" Version="13.0.1" />
|
||||||
<PackageReference Include="ppy.osu.Framework" Version="2022.810.0" />
|
<PackageReference Include="ppy.osu.Framework" Version="2022.810.2" />
|
||||||
<PackageReference Include="SharpCompress" Version="0.32.1" />
|
<PackageReference Include="SharpCompress" Version="0.32.1" />
|
||||||
<PackageReference Include="NUnit" Version="3.13.3" />
|
<PackageReference Include="NUnit" Version="3.13.3" />
|
||||||
<PackageReference Include="System.ComponentModel.Annotations" Version="5.0.0" />
|
<PackageReference Include="System.ComponentModel.Annotations" Version="5.0.0" />
|
||||||
|
Loading…
Reference in New Issue
Block a user