diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index 6c683d614b..834b2b68a1 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -31,7 +31,7 @@ jobs:
run: dotnet tool restore
- name: Restore Packages
- run: dotnet restore
+ run: dotnet restore osu.Desktop.slnf
- name: Restore inspectcode cache
uses: actions/cache@v3
@@ -113,11 +113,11 @@ jobs:
with:
dotnet-version: "6.0.x"
- - name: Setup MSBuild
- uses: microsoft/setup-msbuild@v1
+ - name: Install .NET workloads
+ run: dotnet workload install android
- - name: Build
- run: msbuild osu.Android/osu.Android.csproj /restore /p:Configuration=Debug
+ - name: Compile
+ run: dotnet build -c Debug osu.Android.slnf
build-only-ios:
name: Build only (iOS)
diff --git a/appveyor.yml b/appveyor.yml
index 19ef6ae63f..3757cbf41f 100644
--- a/appveyor.yml
+++ b/appveyor.yml
@@ -11,6 +11,7 @@ dotnet_csproj:
before_build:
- cmd: dotnet --info # Useful when version mismatch between CI and local
+ - cmd: dotnet workload install android # Change to `dotnet workload restore` once there's no old projects
- cmd: dotnet workload install maui-ios # Change to `dotnet workload restore` once there's no old projects
- cmd: nuget restore -verbosity quiet # Only nuget.exe knows both new (.NET Core) and old (Xamarin) projects
diff --git a/global.json b/global.json
new file mode 100644
index 0000000000..f20ff84190
--- /dev/null
+++ b/global.json
@@ -0,0 +1,6 @@
+{
+ "sdk": {
+ "version": "6.0.300",
+ "rollForward": "major"
+ }
+}
diff --git a/osu.Android.props b/osu.Android.props
index 0e5714e90f..5da7eae380 100644
--- a/osu.Android.props
+++ b/osu.Android.props
@@ -1,57 +1,15 @@
- 8.0
- bin\$(Configuration)
- 4
- 2.0
- false
- false
- Library
- 512
- Off
- True
- Xamarin.Android.Net.AndroidClientHandler
- v10.0
- false
- true
- armeabi-v7a;x86;arm64-v8a
- true
- cjk,mideast,other,rare,west
- SdkOnly
- prompt
-
-
- True
- portable
- False
- DEBUG;TRACE
- false
- true
- false
-
-
- false
- None
- True
- false
- False
+ 21.0
+ android-x86;android-arm;android-arm64
+ apk
+ CJK;Mideast;Rare;West;Other;
+ Xamarin.Android.Net.AndroidMessageHandler
+
+ true
true
-
- osu.licenseheader
-
-
-
-
-
-
-
-
-
-
-
-
@@ -61,4 +19,9 @@
+
+
+ true
+
diff --git a/osu.Android/Properties/AndroidManifest.xml b/osu.Android/AndroidManifest.xml
similarity index 98%
rename from osu.Android/Properties/AndroidManifest.xml
rename to osu.Android/AndroidManifest.xml
index 165a64a424..be326be5eb 100644
--- a/osu.Android/Properties/AndroidManifest.xml
+++ b/osu.Android/AndroidManifest.xml
@@ -1,5 +1,5 @@
-
+
\ No newline at end of file
diff --git a/osu.Android/OsuGameActivity.cs b/osu.Android/OsuGameActivity.cs
index be40db7508..ca3d628447 100644
--- a/osu.Android/OsuGameActivity.cs
+++ b/osu.Android/OsuGameActivity.cs
@@ -7,6 +7,7 @@ using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
+using System.Reflection;
using System.Threading.Tasks;
using Android.App;
using Android.Content;
@@ -74,11 +75,23 @@ namespace osu.Android
Debug.Assert(Resources?.DisplayMetrics != null);
Point displaySize = new Point();
+#pragma warning disable 618 // GetSize is deprecated
WindowManager.DefaultDisplay.GetSize(displaySize);
+#pragma warning restore 618
float smallestWidthDp = Math.Min(displaySize.X, displaySize.Y) / Resources.DisplayMetrics.Density;
bool isTablet = smallestWidthDp >= 600f;
RequestedOrientation = DefaultOrientation = isTablet ? ScreenOrientation.FullUser : ScreenOrientation.SensorLandscape;
+
+ // Currently (SDK 6.0.200), BundleAssemblies is not runnable for net6-android.
+ // The assembly files are not available as files either after native AOT.
+ // Manually load them so that they can be loaded by RulesetStore.loadFromAppDomain.
+ // REMEMBER to fully uninstall previous version every time when investigating this!
+ // Don't forget osu.Game.Tests.Android too.
+ Assembly.Load("osu.Game.Rulesets.Osu");
+ Assembly.Load("osu.Game.Rulesets.Taiko");
+ Assembly.Load("osu.Game.Rulesets.Catch");
+ Assembly.Load("osu.Game.Rulesets.Mania");
}
protected override void OnNewIntent(Intent intent) => handleIntent(intent);
@@ -127,7 +140,7 @@ namespace osu.Android
cursor.MoveToFirst();
- int filenameColumn = cursor.GetColumnIndex(OpenableColumns.DisplayName);
+ int filenameColumn = cursor.GetColumnIndex(IOpenableColumns.DisplayName);
string filename = cursor.GetString(filenameColumn);
// SharpCompress requires archive streams to be seekable, which the stream opened by
diff --git a/osu.Android/OsuGameAndroid.cs b/osu.Android/OsuGameAndroid.cs
index 1c6f41a7ec..0227d2aec2 100644
--- a/osu.Android/OsuGameAndroid.cs
+++ b/osu.Android/OsuGameAndroid.cs
@@ -5,7 +5,7 @@
using System;
using Android.App;
-using Android.OS;
+using Microsoft.Maui.Devices;
using osu.Framework.Allocation;
using osu.Framework.Android.Input;
using osu.Framework.Input.Handlers;
@@ -14,7 +14,6 @@ using osu.Game;
using osu.Game.Overlays.Settings;
using osu.Game.Updater;
using osu.Game.Utils;
-using Xamarin.Essentials;
namespace osu.Android
{
@@ -48,7 +47,7 @@ namespace osu.Android
// https://stackoverflow.com/questions/52977079/android-sdk-28-versioncode-in-packageinfo-has-been-deprecated
string versionName = string.Empty;
- if (Build.VERSION.SdkInt >= BuildVersionCodes.P)
+ if (OperatingSystem.IsAndroidVersionAtLeast(28))
{
versionName = packageInfo.LongVersionCode.ToString();
// ensure we only read the trailing portion of long (the part we are interested in).
diff --git a/osu.Android/osu.Android.csproj b/osu.Android/osu.Android.csproj
index 004cc8c39c..de53e5dd59 100644
--- a/osu.Android/osu.Android.csproj
+++ b/osu.Android/osu.Android.csproj
@@ -1,73 +1,19 @@
-
-
+
- Debug
- AnyCPU
- 8.0.30703
- 2.0
- {D1D5F9A8-B40B-40E6-B02F-482D03346D3D}
- {EFBA0AD7-5A72-4C68-AF49-83D382785DCF};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}
- {122416d6-6b49-4ee2-a1e8-b825f31c79fe}
+ net6.0-android
+ Exe
osu.Android
osu.Android
- Properties\AndroidManifest.xml
- armeabi-v7a;x86;arm64-v8a
- false
-
-
- cjk;mideast;other;rare;west
- d8
- r8
-
-
- None
- cjk;mideast;other;rare;west
- true
+ true
+
+ false
-
-
-
-
-
-
+
+
+
+
+
-
-
-
-
-
- {58f6c80c-1253-4a0e-a465-b8c85ebeadf3}
- osu.Game.Rulesets.Catch
-
-
- {48f4582b-7687-4621-9cbe-5c24197cb536}
- osu.Game.Rulesets.Mania
-
-
- {c92a607b-1fdd-4954-9f92-03ff547d9080}
- osu.Game.Rulesets.Osu
-
-
- {f167e17a-7de6-4af5-b920-a5112296c695}
- osu.Game.Rulesets.Taiko
-
-
- {2a66dd92-adb1-4994-89e2-c94e04acda0d}
- osu.Game
-
-
-
-
-
-
-
- 5.0.0
-
-
-
-
-
-
-
\ No newline at end of file
+
diff --git a/osu.Game.Rulesets.Catch.Tests.Android/Properties/AndroidManifest.xml b/osu.Game.Rulesets.Catch.Tests.Android/AndroidManifest.xml
similarity index 98%
rename from osu.Game.Rulesets.Catch.Tests.Android/Properties/AndroidManifest.xml
rename to osu.Game.Rulesets.Catch.Tests.Android/AndroidManifest.xml
index f8c3fcd894..bf7c0bfeca 100644
--- a/osu.Game.Rulesets.Catch.Tests.Android/Properties/AndroidManifest.xml
+++ b/osu.Game.Rulesets.Catch.Tests.Android/AndroidManifest.xml
@@ -1,6 +1,6 @@
-
+
\ No newline at end of file
diff --git a/osu.Game.Rulesets.Catch.Tests.Android/osu.Game.Rulesets.Catch.Tests.Android.csproj b/osu.Game.Rulesets.Catch.Tests.Android/osu.Game.Rulesets.Catch.Tests.Android.csproj
index 94fdba4a3e..4ee3219442 100644
--- a/osu.Game.Rulesets.Catch.Tests.Android/osu.Game.Rulesets.Catch.Tests.Android.csproj
+++ b/osu.Game.Rulesets.Catch.Tests.Android/osu.Game.Rulesets.Catch.Tests.Android.csproj
@@ -1,49 +1,24 @@
-
-
+
- Debug
- AnyCPU
- 8.0.30703
- 2.0
- {C5379ECB-3A94-4D2F-AC3B-2615AC23EB0D}
- {EFBA0AD7-5A72-4C68-AF49-83D382785DCF};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}
- {122416d6-6b49-4ee2-a1e8-b825f31c79fe}
+ net6.0-android
+ Exe
osu.Game.Rulesets.Catch.Tests
osu.Game.Rulesets.Catch.Tests.Android
- Properties\AndroidManifest.xml
- armeabi-v7a;x86;arm64-v8a
-
-
- None
- cjk;mideast;other;rare;west
- true
-
-
-
-
-
-
-
+
%(RecursiveDir)%(Filename)%(Extension)
+
+
+ %(RecursiveDir)%(Filename)%(Extension)
+ Android\%(RecursiveDir)%(Filename)%(Extension)
+
-
- {58f6c80c-1253-4a0e-a465-b8c85ebeadf3}
- osu.Game.Rulesets.Catch
-
-
- {2A66DD92-ADB1-4994-89E2-C94E04ACDA0D}
- osu.Game
-
+
+
-
-
- 5.0.0
-
-
-
\ No newline at end of file
diff --git a/osu.Game.Rulesets.Mania.Tests.Android/Properties/AndroidManifest.xml b/osu.Game.Rulesets.Mania.Tests.Android/AndroidManifest.xml
similarity index 98%
rename from osu.Game.Rulesets.Mania.Tests.Android/Properties/AndroidManifest.xml
rename to osu.Game.Rulesets.Mania.Tests.Android/AndroidManifest.xml
index de7935b2ef..4a1545a423 100644
--- a/osu.Game.Rulesets.Mania.Tests.Android/Properties/AndroidManifest.xml
+++ b/osu.Game.Rulesets.Mania.Tests.Android/AndroidManifest.xml
@@ -1,5 +1,5 @@
-
+
\ No newline at end of file
diff --git a/osu.Game.Rulesets.Mania.Tests.Android/osu.Game.Rulesets.Mania.Tests.Android.csproj b/osu.Game.Rulesets.Mania.Tests.Android/osu.Game.Rulesets.Mania.Tests.Android.csproj
index 9674186039..25335754d2 100644
--- a/osu.Game.Rulesets.Mania.Tests.Android/osu.Game.Rulesets.Mania.Tests.Android.csproj
+++ b/osu.Game.Rulesets.Mania.Tests.Android/osu.Game.Rulesets.Mania.Tests.Android.csproj
@@ -1,49 +1,24 @@
-
-
+
- Debug
- AnyCPU
- 8.0.30703
- 2.0
- {531F1092-DB27-445D-AA33-2A77C7187C99}
- {EFBA0AD7-5A72-4C68-AF49-83D382785DCF};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}
- {122416d6-6b49-4ee2-a1e8-b825f31c79fe}
+ net6.0-android
+ Exe
osu.Game.Rulesets.Mania.Tests
osu.Game.Rulesets.Mania.Tests.Android
- Properties\AndroidManifest.xml
- armeabi-v7a;x86;arm64-v8a
-
-
- None
- cjk;mideast;other;rare;west
- true
-
-
-
-
-
-
-
+
%(RecursiveDir)%(Filename)%(Extension)
+
+
+ %(RecursiveDir)%(Filename)%(Extension)
+ Android\%(RecursiveDir)%(Filename)%(Extension)
+
-
- {48f4582b-7687-4621-9cbe-5c24197cb536}
- osu.Game.Rulesets.Mania
-
-
- {2A66DD92-ADB1-4994-89E2-C94E04ACDA0D}
- osu.Game
-
+
+
-
-
- 5.0.0
-
-
-
\ No newline at end of file
diff --git a/osu.Game.Rulesets.Osu.Tests.Android/Properties/AndroidManifest.xml b/osu.Game.Rulesets.Osu.Tests.Android/AndroidManifest.xml
similarity index 98%
rename from osu.Game.Rulesets.Osu.Tests.Android/Properties/AndroidManifest.xml
rename to osu.Game.Rulesets.Osu.Tests.Android/AndroidManifest.xml
index 3ce17ccc27..45d27dda70 100644
--- a/osu.Game.Rulesets.Osu.Tests.Android/Properties/AndroidManifest.xml
+++ b/osu.Game.Rulesets.Osu.Tests.Android/AndroidManifest.xml
@@ -1,5 +1,5 @@
-
+
\ No newline at end of file
diff --git a/osu.Game.Rulesets.Osu.Tests.Android/osu.Game.Rulesets.Osu.Tests.Android.csproj b/osu.Game.Rulesets.Osu.Tests.Android/osu.Game.Rulesets.Osu.Tests.Android.csproj
index f4b673f10b..e8a46a9828 100644
--- a/osu.Game.Rulesets.Osu.Tests.Android/osu.Game.Rulesets.Osu.Tests.Android.csproj
+++ b/osu.Game.Rulesets.Osu.Tests.Android/osu.Game.Rulesets.Osu.Tests.Android.csproj
@@ -1,49 +1,27 @@
-
-
+
- Debug
- AnyCPU
- 8.0.30703
- 2.0
- {90CAB706-39CB-4B93-9629-3218A6FF8E9B}
- {EFBA0AD7-5A72-4C68-AF49-83D382785DCF};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}
- {122416d6-6b49-4ee2-a1e8-b825f31c79fe}
+ net6.0-android
+ Exe
osu.Game.Rulesets.Osu.Tests
osu.Game.Rulesets.Osu.Tests.Android
- Properties\AndroidManifest.xml
- armeabi-v7a;x86;arm64-v8a
-
-
- None
- cjk;mideast;other;rare;west
- true
-
-
-
-
-
-
-
+
%(RecursiveDir)%(Filename)%(Extension)
+
+
+ %(RecursiveDir)%(Filename)%(Extension)
+ Android\%(RecursiveDir)%(Filename)%(Extension)
+
-
- {c92a607b-1fdd-4954-9f92-03ff547d9080}
- osu.Game.Rulesets.Osu
-
-
- {2a66dd92-adb1-4994-89e2-c94e04acda0d}
- osu.Game
-
+
+
-
- 5.0.0
-
+
-
\ No newline at end of file
diff --git a/osu.Game.Rulesets.Taiko.Tests.Android/Properties/AndroidManifest.xml b/osu.Game.Rulesets.Taiko.Tests.Android/AndroidManifest.xml
similarity index 98%
rename from osu.Game.Rulesets.Taiko.Tests.Android/Properties/AndroidManifest.xml
rename to osu.Game.Rulesets.Taiko.Tests.Android/AndroidManifest.xml
index d9de0fde4e..452b9683ec 100644
--- a/osu.Game.Rulesets.Taiko.Tests.Android/Properties/AndroidManifest.xml
+++ b/osu.Game.Rulesets.Taiko.Tests.Android/AndroidManifest.xml
@@ -1,5 +1,5 @@
-
+
\ No newline at end of file
diff --git a/osu.Game.Rulesets.Taiko.Tests.Android/osu.Game.Rulesets.Taiko.Tests.Android.csproj b/osu.Game.Rulesets.Taiko.Tests.Android/osu.Game.Rulesets.Taiko.Tests.Android.csproj
index 4d4dabebe6..a639326ebd 100644
--- a/osu.Game.Rulesets.Taiko.Tests.Android/osu.Game.Rulesets.Taiko.Tests.Android.csproj
+++ b/osu.Game.Rulesets.Taiko.Tests.Android/osu.Game.Rulesets.Taiko.Tests.Android.csproj
@@ -1,49 +1,24 @@
-
-
+
- Debug
- AnyCPU
- 8.0.30703
- 2.0
- {3701A0A1-8476-42C6-B5C4-D24129B4A484}
- {EFBA0AD7-5A72-4C68-AF49-83D382785DCF};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}
- {122416d6-6b49-4ee2-a1e8-b825f31c79fe}
+ net6.0-android
+ Exe
osu.Game.Rulesets.Taiko.Tests
osu.Game.Rulesets.Taiko.Tests.Android
- Properties\AndroidManifest.xml
- armeabi-v7a;x86;arm64-v8a
-
-
- None
- cjk;mideast;other;rare;west
- true
-
-
-
-
-
-
-
+
%(RecursiveDir)%(Filename)%(Extension)
+
+
+ %(RecursiveDir)%(Filename)%(Extension)
+ Android\%(RecursiveDir)%(Filename)%(Extension)
+
-
- {f167e17a-7de6-4af5-b920-a5112296c695}
- osu.Game.Rulesets.Taiko
-
-
- {2a66dd92-adb1-4994-89e2-c94e04acda0d}
- osu.Game
-
+
+
-
-
- 5.0.0
-
-
-
\ No newline at end of file
diff --git a/osu.Game.Tests.Android/Properties/AndroidManifest.xml b/osu.Game.Tests.Android/AndroidManifest.xml
similarity index 98%
rename from osu.Game.Tests.Android/Properties/AndroidManifest.xml
rename to osu.Game.Tests.Android/AndroidManifest.xml
index 4a63f0c357..f25b2e5328 100644
--- a/osu.Game.Tests.Android/Properties/AndroidManifest.xml
+++ b/osu.Game.Tests.Android/AndroidManifest.xml
@@ -1,5 +1,5 @@
-
+
\ No newline at end of file
diff --git a/osu.Game.Tests.Android/MainActivity.cs b/osu.Game.Tests.Android/MainActivity.cs
index 6c4f9bac58..bdb947fbb4 100644
--- a/osu.Game.Tests.Android/MainActivity.cs
+++ b/osu.Game.Tests.Android/MainActivity.cs
@@ -3,7 +3,9 @@
#nullable disable
+using System.Reflection;
using Android.App;
+using Android.OS;
using osu.Framework.Android;
namespace osu.Game.Tests.Android
@@ -12,5 +14,16 @@ namespace osu.Game.Tests.Android
public class MainActivity : AndroidGameActivity
{
protected override Framework.Game CreateGame() => new OsuTestBrowser();
+
+ protected override void OnCreate(Bundle savedInstanceState)
+ {
+ base.OnCreate(savedInstanceState);
+
+ // See the comment in OsuGameActivity
+ Assembly.Load("osu.Game.Rulesets.Osu");
+ Assembly.Load("osu.Game.Rulesets.Taiko");
+ Assembly.Load("osu.Game.Rulesets.Catch");
+ Assembly.Load("osu.Game.Rulesets.Mania");
+ }
}
}
diff --git a/osu.Game.Tests.Android/osu.Game.Tests.Android.csproj b/osu.Game.Tests.Android/osu.Game.Tests.Android.csproj
index afafec6b1f..b745d91980 100644
--- a/osu.Game.Tests.Android/osu.Game.Tests.Android.csproj
+++ b/osu.Game.Tests.Android/osu.Game.Tests.Android.csproj
@@ -1,88 +1,34 @@
-
-
+
- Debug
- AnyCPU
- 8.0.30703
- 2.0
- {5CC222DC-5716-4499-B897-DCBDDA4A5CF9}
- {EFBA0AD7-5A72-4C68-AF49-83D382785DCF};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}
- {122416d6-6b49-4ee2-a1e8-b825f31c79fe}
+ net6.0-android
+ Exe
osu.Game.Tests
osu.Game.Tests.Android
- Properties\AndroidManifest.xml
- armeabi-v7a;x86;arm64-v8a
-
-
-
-
-
-
$(NoWarn);CA2007
-
- None
- cjk;mideast;other;rare;west
- true
-
-
+
%(RecursiveDir)%(Filename)%(Extension)
-
-
+
+
%(RecursiveDir)%(Filename)%(Extension)
-
-
- %(RecursiveDir)%(Filename)%(Extension)
-
-
- %(RecursiveDir)%(Filename)%(Extension)
-
-
- %(RecursiveDir)%(Filename)%(Extension)
-
-
- %(RecursiveDir)%(Filename)%(Extension)
-
-
- %(RecursiveDir)%(Filename)%(Extension)
-
-
- %(RecursiveDir)%(Filename)%(Extension)
-
+ Android\%(RecursiveDir)%(Filename)%(Extension)
+
-
- {58f6c80c-1253-4a0e-a465-b8c85ebeadf3}
- osu.Game.Rulesets.Catch
-
-
- {48f4582b-7687-4621-9cbe-5c24197cb536}
- osu.Game.Rulesets.Mania
-
-
- {c92a607b-1fdd-4954-9f92-03ff547d9080}
- osu.Game.Rulesets.Osu
-
-
- {f167e17a-7de6-4af5-b920-a5112296c695}
- osu.Game.Rulesets.Taiko
-
-
- {2a66dd92-adb1-4994-89e2-c94e04acda0d}
- osu.Game
-
+
+
+
+
+
-
- 5.0.0
-
-
diff --git a/osu.Game.Tests/Visual/Online/TestSceneCommentActions.cs b/osu.Game.Tests/Visual/Online/TestSceneCommentActions.cs
index 8d82843134..d925141510 100644
--- a/osu.Game.Tests/Visual/Online/TestSceneCommentActions.cs
+++ b/osu.Game.Tests/Visual/Online/TestSceneCommentActions.cs
@@ -189,7 +189,7 @@ namespace osu.Game.Tests.Visual.Online
if (request is not CommentDeleteRequest req)
return false;
- req.TriggerFailure(new Exception());
+ req.TriggerFailure(new InvalidOperationException());
delete = true;
return false;
};
diff --git a/osu.Game.Tests/Visual/SongSelect/TestSceneUpdateBeatmapSetButton.cs b/osu.Game.Tests/Visual/SongSelect/TestSceneUpdateBeatmapSetButton.cs
index e47b7e25a8..11d55bc0bd 100644
--- a/osu.Game.Tests/Visual/SongSelect/TestSceneUpdateBeatmapSetButton.cs
+++ b/osu.Game.Tests/Visual/SongSelect/TestSceneUpdateBeatmapSetButton.cs
@@ -136,7 +136,7 @@ namespace osu.Game.Tests.Visual.SongSelect
if (testRequest.Progress >= 0.5f)
{
- testRequest.TriggerFailure(new Exception());
+ testRequest.TriggerFailure(new InvalidOperationException());
return true;
}
}
diff --git a/osu.Game/Rulesets/RulesetStore.cs b/osu.Game/Rulesets/RulesetStore.cs
index adebbe6181..4114a3ed1e 100644
--- a/osu.Game/Rulesets/RulesetStore.cs
+++ b/osu.Game/Rulesets/RulesetStore.cs
@@ -114,7 +114,10 @@ namespace osu.Game.Rulesets
{
try
{
- string[] files = Directory.GetFiles(RuntimeInfo.StartupDirectory, @$"{ruleset_library_prefix}.*.dll");
+ // On net6-android (Debug), StartupDirectory can be different from where assemblies are placed.
+ // Search sub-directories too.
+
+ string[] files = Directory.GetFiles(RuntimeInfo.StartupDirectory, @$"{ruleset_library_prefix}.*.dll", SearchOption.AllDirectories);
foreach (string file in files.Where(f => !Path.GetFileName(f).Contains("Tests")))
loadRulesetFromFile(file);
diff --git a/osu.sln b/osu.sln
index aeec0843be..5b23ff9ae6 100644
--- a/osu.sln
+++ b/osu.sln
@@ -63,6 +63,7 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution
CodeAnalysis\osu.ruleset = CodeAnalysis\osu.ruleset
osu.sln.DotSettings = osu.sln.DotSettings
osu.TestProject.props = osu.TestProject.props
+ global.json = global.json
EndProjectSection
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "osu.Game.Benchmarks", "osu.Game.Benchmarks\osu.Game.Benchmarks.csproj", "{93632F2D-2BB4-46C1-A7B8-F8CF2FB27118}"