Skip to content

Commit 330af7e

Browse files
committed
Handle osu:// scheme links via IPC in desktop game
1 parent 9201112 commit 330af7e

File tree

3 files changed

+65
-23
lines changed

3 files changed

+65
-23
lines changed

osu.Desktop/OsuGameDesktop.cs

+20-11
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,6 @@
11
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
22
// See the LICENCE file in the repository root for full licence text.
33

4-
#nullable disable
5-
64
using System;
75
using System.Collections.Generic;
86
using System.Diagnostics;
@@ -22,23 +20,26 @@
2220
using osu.Desktop.Windows;
2321
using osu.Framework.Threading;
2422
using osu.Game.IO;
23+
using osu.Game.IPC;
2524

2625
namespace osu.Desktop
2726
{
2827
internal class OsuGameDesktop : OsuGame
2928
{
30-
public OsuGameDesktop(string[] args = null)
29+
private OsuSchemeLinkIPCChannel? osuSchemeLinkIPCChannel;
30+
31+
public OsuGameDesktop(string[]? args = null)
3132
: base(args)
3233
{
3334
}
3435

35-
public override StableStorage GetStorageForStableInstall()
36+
public override StableStorage? GetStorageForStableInstall()
3637
{
3738
try
3839
{
3940
if (Host is DesktopGameHost desktopHost)
4041
{
41-
string stablePath = getStableInstallPath();
42+
string? stablePath = getStableInstallPath();
4243
if (!string.IsNullOrEmpty(stablePath))
4344
return new StableStorage(stablePath, desktopHost);
4445
}
@@ -51,11 +52,11 @@ public override StableStorage GetStorageForStableInstall()
5152
return null;
5253
}
5354

54-
private string getStableInstallPath()
55+
private string? getStableInstallPath()
5556
{
5657
static bool checkExists(string p) => Directory.Exists(Path.Combine(p, "Songs")) || File.Exists(Path.Combine(p, "osu!.cfg"));
5758

58-
string stableInstallPath;
59+
string? stableInstallPath;
5960

6061
if (OperatingSystem.IsWindows())
6162
{
@@ -83,15 +84,15 @@ private string getStableInstallPath()
8384
}
8485

8586
[SupportedOSPlatform("windows")]
86-
private string getStableInstallPathFromRegistry()
87+
private string? getStableInstallPathFromRegistry()
8788
{
88-
using (RegistryKey key = Registry.ClassesRoot.OpenSubKey("osu"))
89+
using (RegistryKey? key = Registry.ClassesRoot.OpenSubKey("osu"))
8990
return key?.OpenSubKey(@"shell\open\command")?.GetValue(string.Empty)?.ToString()?.Split('"')[1].Replace("osu!.exe", "");
9091
}
9192

9293
protected override UpdateManager CreateUpdateManager()
9394
{
94-
string packageManaged = Environment.GetEnvironmentVariable("OSU_EXTERNAL_UPDATE_PROVIDER");
95+
string? packageManaged = Environment.GetEnvironmentVariable("OSU_EXTERNAL_UPDATE_PROVIDER");
9596

9697
if (!string.IsNullOrEmpty(packageManaged))
9798
return new NoActionUpdateManager();
@@ -118,6 +119,8 @@ protected override void LoadComplete()
118119
LoadComponentAsync(new GameplayWinKeyBlocker(), Add);
119120

120121
LoadComponentAsync(new ElevatedPrivilegesChecker(), Add);
122+
123+
osuSchemeLinkIPCChannel = new OsuSchemeLinkIPCChannel(Host, this);
121124
}
122125

123126
public override void SetHost(GameHost host)
@@ -135,7 +138,7 @@ public override void SetHost(GameHost host)
135138
}
136139

137140
private readonly List<string> importableFiles = new List<string>();
138-
private ScheduledDelegate importSchedule;
141+
private ScheduledDelegate? importSchedule;
139142

140143
private void fileDrop(string[] filePaths)
141144
{
@@ -168,5 +171,11 @@ private void handlePendingImports()
168171
Task.Factory.StartNew(() => Import(paths), TaskCreationOptions.LongRunning);
169172
}
170173
}
174+
175+
protected override void Dispose(bool isDisposing)
176+
{
177+
base.Dispose(isDisposing);
178+
osuSchemeLinkIPCChannel?.Dispose();
179+
}
171180
}
172181
}

osu.Desktop/Program.cs

+30-12
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
using osu.Framework.Development;
1212
using osu.Framework.Logging;
1313
using osu.Framework.Platform;
14+
using osu.Game;
1415
using osu.Game.IPC;
1516
using osu.Game.Tournament;
1617
using Squirrel;
@@ -65,19 +66,8 @@ public static void Main(string[] args)
6566
{
6667
if (!host.IsPrimaryInstance)
6768
{
68-
if (args.Length > 0 && args[0].Contains('.')) // easy way to check for a file import in args
69-
{
70-
var importer = new ArchiveImportIPCChannel(host);
71-
72-
foreach (string file in args)
73-
{
74-
Console.WriteLine(@"Importing {0}", file);
75-
if (!importer.ImportAsync(Path.GetFullPath(file, cwd)).Wait(3000))
76-
throw new TimeoutException(@"IPC took too long to send");
77-
}
78-
69+
if (trySendIPCMessage(host, cwd, args))
7970
return;
80-
}
8171

8272
// we want to allow multiple instances to be started when in debug.
8373
if (!DebugUtils.IsDebugBuild)
@@ -108,6 +98,34 @@ public static void Main(string[] args)
10898
}
10999
}
110100

101+
private static bool trySendIPCMessage(IIpcHost host, string cwd, string[] args)
102+
{
103+
if (args.Length == 1 && args[0].StartsWith(OsuGameBase.OSU_PROTOCOL, StringComparison.Ordinal))
104+
{
105+
var osuSchemeLinkHandler = new OsuSchemeLinkIPCChannel(host);
106+
if (!osuSchemeLinkHandler.HandleLinkAsync(args[0]).Wait(3000))
107+
throw new IPCTimeoutException(osuSchemeLinkHandler.GetType());
108+
109+
return true;
110+
}
111+
112+
if (args.Length > 0 && args[0].Contains('.')) // easy way to check for a file import in args
113+
{
114+
var importer = new ArchiveImportIPCChannel(host);
115+
116+
foreach (string file in args)
117+
{
118+
Console.WriteLine(@"Importing {0}", file);
119+
if (!importer.ImportAsync(Path.GetFullPath(file, cwd)).Wait(3000))
120+
throw new IPCTimeoutException(importer.GetType());
121+
}
122+
123+
return true;
124+
}
125+
126+
return false;
127+
}
128+
111129
[SupportedOSPlatform("windows")]
112130
private static void setupSquirrel()
113131
{

osu.Game/IPC/IPCTimeoutException.cs

+15
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
2+
// See the LICENCE file in the repository root for full licence text.
3+
4+
using System;
5+
6+
namespace osu.Game.IPC
7+
{
8+
public class IPCTimeoutException : TimeoutException
9+
{
10+
public IPCTimeoutException(Type channelType)
11+
: base($@"IPC took too long to send message via channel {channelType}")
12+
{
13+
}
14+
}
15+
}

0 commit comments

Comments
 (0)