Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions osu.Desktop/OsuGameDesktop.cs
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
using osu.Game.IPC;
using osu.Game.Online.Multiplayer;
using osu.Game.Performance;
using osu.Game.Platform;
using osu.Game.Utils;

namespace osu.Desktop
Expand All @@ -34,11 +35,18 @@ internal partial class OsuGameDesktop : OsuGame
[Cached(typeof(IHighPerformanceSessionManager))]
private readonly HighPerformanceSessionManager highPerformanceSessionManager = new HighPerformanceSessionManager();

[Cached(typeof(IAssociationManager))]
private readonly IAssociationManager? associationManager;

public bool IsFirstRun { get; init; }

public OsuGameDesktop(string[]? args = null)
: base(args)
{
if (OperatingSystem.IsWindows())
{
associationManager = new WindowsAssociationManagerAdapter();
}
}

public override StableStorage? GetStorageForStableInstall()
Expand Down
6 changes: 3 additions & 3 deletions osu.Desktop/Windows/WindowsAssociationManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -37,11 +37,11 @@ public static class WindowsAssociationManager
/// Program ID prefix used for file associations. Should be relatively short since the full program ID has a 39 character limit,
/// see https://learn.microsoft.com/en-us/windows/win32/com/-progid--key.
/// </summary>
private const string program_id_file_prefix = "osu.File";
private const string program_id_file_prefix = "g0v0.osu.File";

private const string program_id_protocol_prefix = "osu.Uri";
private const string program_id_protocol_prefix = "g0v0.osu.Uri";

private static readonly ApplicationCapability application_capability = new ApplicationCapability(@"osu", @"Software\ppy\osu\Capabilities", "osu!(lazer)");
private static readonly ApplicationCapability application_capability = new ApplicationCapability(@"osu-gu", @"Software\g0v0\osu\Capabilities", "osu!(lazer) (g0v0)");

private static readonly FileAssociation[] file_associations =
{
Expand Down
18 changes: 18 additions & 0 deletions osu.Desktop/Windows/WindowsAssociationManagerAdapter.cs
Original file line number Diff line number Diff line change
@@ -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.

using System.Runtime.Versioning;
using osu.Game.Platform;

namespace osu.Desktop.Windows
{
[SupportedOSPlatform("windows")]
public class WindowsAssociationManagerAdapter : IAssociationManager
{
public void InstallAssociations() => WindowsAssociationManager.InstallAssociations();

public void UpdateAssociations() => WindowsAssociationManager.UpdateAssociations();

public void UninstallAssociations() => WindowsAssociationManager.UninstallAssociations();
}
}
14 changes: 14 additions & 0 deletions osu.Game/Localisation/DebugSettingsStrings.cs
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,20 @@ public static class DebugSettingsStrings
/// </summary>
public static LocalisableString RunLatencyCertifier => new TranslatableString(getKey(@"run_latency_certifier"), @"Run latency certifier");

/// <summary>
/// "Set application association"
/// </summary>
public static LocalisableString SetApplicationAssociation => new TranslatableString(getKey(@"set_application_association"), @"Set application association");

/// <summary>
/// "Association Update"
/// </summary>
public static LocalisableString AssociationDialogHeader => new TranslatableString(getKey(@"association_dialog_header"), @"Association Update");

public static LocalisableString AssociationDialogText => new TranslatableString(getKey(@"association_dialog_text"),
"Setting up a separate association for osu!gu client."
+ "\nPlease be aware that associations for the official client won't be changed. You may need to reinstall or update it to fix them.");

private static string getKey(string key) => $"{prefix}:{key}";
}
}
Original file line number Diff line number Diff line change
@@ -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 osu.Framework.Graphics.Sprites;
using osu.Game.Localisation;
using osu.Game.Overlays.Dialog;

namespace osu.Game.Overlays.Settings.Sections.Maintenance
{
public partial class AssociationPrePromptDialog : PopupDialog
{
public AssociationPrePromptDialog(Action setAssociation)
{
HeaderText = DebugSettingsStrings.AssociationDialogHeader;
BodyText = DebugSettingsStrings.AssociationDialogText;
Icon = FontAwesome.Solid.InfoCircle;

Buttons = new PopupDialogButton[]
{
new PopupDialogOkButton
{
Text = DialogStrings.Confirm,
Action = setAssociation,
},
new PopupDialogCancelButton
{
Text = DialogStrings.Cancel,
},
};
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,14 @@

using System.Linq;
using System.Threading.Tasks;
using osu.Framework;
using osu.Framework.Allocation;
using osu.Framework.Graphics;
using osu.Framework.Localisation;
using osu.Framework.Platform;
using osu.Framework.Screens;
using osu.Game.Localisation;
using osu.Game.Platform;
using osu.Game.Screens;
using osu.Game.Screens.Import;
using osu.Game.Screens.Utility;
Expand All @@ -22,7 +24,8 @@ public partial class GeneralSettings : SettingsSubsection
private ISystemFileSelector? selector;

[BackgroundDependencyLoader]
private void load(OsuGameBase game, GameHost host, IPerformFromScreenRunner? performer)
private void load(OsuGameBase game, GameHost host, IPerformFromScreenRunner? performer,
IAssociationManager? associationManager, IDialogOverlay? dialogOverlay)
{
if ((selector = host.CreateSystemFileSelector(game.HandledExtensions.ToArray())) != null)
selector.Selected += f => Task.Run(() => game.Import(f.FullName));
Expand All @@ -46,6 +49,15 @@ private void load(OsuGameBase game, GameHost host, IPerformFromScreenRunner? per
Action = () => performer?.PerformFromScreen(menu => menu.Push(new LatencyCertifierScreen()))
}
});

if (RuntimeInfo.OS is RuntimeInfo.Platform.Windows && associationManager != null)
{
Add(new SettingsButton
{
Text = DebugSettingsStrings.SetApplicationAssociation,
Action = () => dialogOverlay?.Push(new AssociationPrePromptDialog(associationManager.InstallAssociations)),
});
}
}
}
}
23 changes: 23 additions & 0 deletions osu.Game/Platform/IAssociationManager.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.

namespace osu.Game.Platform
{
public interface IAssociationManager
{
/// <summary>
/// Installs or refreshes file and URI protocol associations for this client.
/// </summary>
void InstallAssociations();

/// <summary>
/// Updates associations with latest definitions.
/// </summary>
void UpdateAssociations();

/// <summary>
/// Remove all associations with the client.
/// </summary>
void UninstallAssociations();
}
}