Compare commits
6 Commits
c37f72f567
...
2025.822.0
| Author | SHA1 | Date | |
|---|---|---|---|
| 490137405f | |||
| f3c6f53f70 | |||
| 8cb5c682b4 | |||
| c3d79295d3 | |||
| f31d310135 | |||
| 26029de27d |
1
.gitignore
vendored
1
.gitignore
vendored
@@ -19,6 +19,7 @@ bld/
|
||||
[Bb]in/
|
||||
[Oo]bj/
|
||||
[Ll]og/
|
||||
[Pp]ub/
|
||||
|
||||
# Visual Studio 2015 cache/options directory
|
||||
.vs/
|
||||
|
||||
36
.vscode/launch.json
vendored
36
.vscode/launch.json
vendored
@@ -7,9 +7,9 @@
|
||||
"request": "launch",
|
||||
"program": "dotnet",
|
||||
"args": [
|
||||
"${workspaceRoot}/osu.Desktop/bin/Debug/net8.0/osu!.dll"
|
||||
"${workspaceFolder}/osu.Desktop/bin/Debug/net8.0/osu!.dll"
|
||||
],
|
||||
"cwd": "${workspaceRoot}",
|
||||
"cwd": "${workspaceFolder}",
|
||||
"preLaunchTask": "Build osu! (Debug)",
|
||||
"console": "internalConsole"
|
||||
},
|
||||
@@ -19,9 +19,9 @@
|
||||
"request": "launch",
|
||||
"program": "dotnet",
|
||||
"args": [
|
||||
"${workspaceRoot}/osu.Desktop/bin/Release/net8.0/osu!.dll"
|
||||
"${workspaceFolder}/osu.Desktop/bin/Release/net8.0/osu!.dll"
|
||||
],
|
||||
"cwd": "${workspaceRoot}",
|
||||
"cwd": "${workspaceFolder}",
|
||||
"preLaunchTask": "Build osu! (Release)",
|
||||
"console": "internalConsole"
|
||||
},
|
||||
@@ -31,9 +31,9 @@
|
||||
"request": "launch",
|
||||
"program": "dotnet",
|
||||
"args": [
|
||||
"${workspaceRoot}/osu.Game.Tests/bin/Debug/net8.0/osu.Game.Tests.dll"
|
||||
"${workspaceFolder}/osu.Game.Tests/bin/Debug/net8.0/osu.Game.Tests.dll"
|
||||
],
|
||||
"cwd": "${workspaceRoot}",
|
||||
"cwd": "${workspaceFolder}",
|
||||
"preLaunchTask": "Build tests (Debug)",
|
||||
"console": "internalConsole"
|
||||
},
|
||||
@@ -43,9 +43,9 @@
|
||||
"request": "launch",
|
||||
"program": "dotnet",
|
||||
"args": [
|
||||
"${workspaceRoot}/osu.Game.Tests/bin/Release/net8.0/osu.Game.Tests.dll"
|
||||
"${workspaceFolder}/osu.Game.Tests/bin/Release/net8.0/osu.Game.Tests.dll"
|
||||
],
|
||||
"cwd": "${workspaceRoot}",
|
||||
"cwd": "${workspaceFolder}",
|
||||
"preLaunchTask": "Build tests (Release)",
|
||||
"console": "internalConsole"
|
||||
},
|
||||
@@ -55,10 +55,10 @@
|
||||
"request": "launch",
|
||||
"program": "dotnet",
|
||||
"args": [
|
||||
"${workspaceRoot}/osu.Desktop/bin/Debug/net8.0/osu!.dll",
|
||||
"${workspaceFolder}/osu.Desktop/bin/Debug/net8.0/osu!.dll",
|
||||
"--tournament"
|
||||
],
|
||||
"cwd": "${workspaceRoot}",
|
||||
"cwd": "${workspaceFolder}",
|
||||
"preLaunchTask": "Build osu! (Debug)",
|
||||
"console": "internalConsole"
|
||||
},
|
||||
@@ -68,10 +68,10 @@
|
||||
"request": "launch",
|
||||
"program": "dotnet",
|
||||
"args": [
|
||||
"${workspaceRoot}/osu.Desktop/bin/Release/net8.0/osu!.dll",
|
||||
"${workspaceFolder}/osu.Desktop/bin/Release/net8.0/osu!.dll",
|
||||
"--tournament"
|
||||
],
|
||||
"cwd": "${workspaceRoot}",
|
||||
"cwd": "${workspaceFolder}",
|
||||
"preLaunchTask": "Build osu! (Release)",
|
||||
"console": "internalConsole"
|
||||
},
|
||||
@@ -81,10 +81,10 @@
|
||||
"request": "launch",
|
||||
"program": "dotnet",
|
||||
"args": [
|
||||
"${workspaceRoot}/osu.Game.Tournament.Tests/bin/Debug/net8.0/osu.Game.Tournament.Tests.dll",
|
||||
"${workspaceFolder}/osu.Game.Tournament.Tests/bin/Debug/net8.0/osu.Game.Tournament.Tests.dll",
|
||||
"--tournament"
|
||||
],
|
||||
"cwd": "${workspaceRoot}",
|
||||
"cwd": "${workspaceFolder}",
|
||||
"preLaunchTask": "Build tournament tests (Debug)",
|
||||
"console": "internalConsole"
|
||||
},
|
||||
@@ -94,10 +94,10 @@
|
||||
"request": "launch",
|
||||
"program": "dotnet",
|
||||
"args": [
|
||||
"${workspaceRoot}/osu.Game.Tournament.Tests/bin/Debug/net8.0/osu.Game.Tournament.Tests.dll",
|
||||
"${workspaceFolder}/osu.Game.Tournament.Tests/bin/Debug/net8.0/osu.Game.Tournament.Tests.dll",
|
||||
"--tournament"
|
||||
],
|
||||
"cwd": "${workspaceRoot}",
|
||||
"cwd": "${workspaceFolder}",
|
||||
"preLaunchTask": "Build tournament tests (Release)",
|
||||
"console": "internalConsole"
|
||||
},
|
||||
@@ -105,12 +105,12 @@
|
||||
"name": "Benchmark",
|
||||
"type": "coreclr",
|
||||
"request": "launch",
|
||||
"program": "${workspaceRoot}/osu.Game.Benchmarks/bin/Release/net8.0/osu.Game.Benchmarks.dll",
|
||||
"program": "${workspaceFolder}/osu.Game.Benchmarks/bin/Release/net8.0/osu.Game.Benchmarks.dll",
|
||||
"args": [
|
||||
"--filter",
|
||||
"*"
|
||||
],
|
||||
"cwd": "${workspaceRoot}",
|
||||
"cwd": "${workspaceFolder}",
|
||||
"preLaunchTask": "Build benchmarks",
|
||||
"console": "internalConsole"
|
||||
}
|
||||
|
||||
19
MakeInstaller.ps1
Normal file
19
MakeInstaller.ps1
Normal file
@@ -0,0 +1,19 @@
|
||||
#!/usr/bin/env powershell
|
||||
param (
|
||||
[string]$Version,
|
||||
[string]$BuildConfig = "Release"
|
||||
)
|
||||
|
||||
if ($Version -eq "") {
|
||||
Write-Host "Usage: .\MakeInstaller.ps1 <VERSION_NUMBER> [-BuildConfig <BUILD_CONFIG>]"
|
||||
Write-Host "Example: .\MakeInstaller.ps1 2025.823.0 -BuildConfig Debug"
|
||||
exit
|
||||
}
|
||||
|
||||
$tmpPub = ".\pub"
|
||||
if (-not (Test-Path -Path $tmpPub)) {
|
||||
New-Item -ItemType Directory -path $tmpPub
|
||||
}
|
||||
|
||||
dotnet publish -c $BuildConfig osu.Desktop --self-contained -r win-x64 -o $tmpPub -verbosity:m /p:Version=$Version
|
||||
vpk pack --packId jvnkosu.Client --packTitle "jvnkosu!lazer" --packVersion $Version --packDir ./pub --mainExe="osu!.exe"
|
||||
@@ -115,10 +115,12 @@ namespace osu.Desktop
|
||||
if (IsFirstRun)
|
||||
LocalConfig.SetValue(OsuSetting.ReleaseStream, ReleaseStream.Lazer);
|
||||
|
||||
if (IsPackageManaged)
|
||||
return new NoActionUpdateManager();
|
||||
// if (IsPackageManaged)
|
||||
// return new NoActionUpdateManager();
|
||||
|
||||
return new VelopackUpdateManager();
|
||||
// return new VelopackUpdateManager();
|
||||
|
||||
return new NoActionUpdateManager(); // for now, APIs are useless for actually downloading the releases. TODO: adapt UpdateManager for gitea
|
||||
}
|
||||
|
||||
public override bool RestartAppWhenExited()
|
||||
|
||||
@@ -92,7 +92,7 @@ namespace osu.Game.Configuration
|
||||
|
||||
SetDefault(OsuSetting.ExternalLinkWarning, true);
|
||||
SetDefault(OsuSetting.PreferNoVideo, false);
|
||||
|
||||
SetDefault(OsuSetting.BackgroundCategory, "Default");
|
||||
SetDefault(OsuSetting.ShowOnlineExplicitContent, false);
|
||||
|
||||
SetDefault(OsuSetting.NotifyOnUsernameMentioned, true);
|
||||
@@ -193,7 +193,7 @@ namespace osu.Game.Configuration
|
||||
SetDefault(OsuSetting.IntroSequence, IntroSequence.Triangles);
|
||||
|
||||
SetDefault(OsuSetting.MenuBackgroundSource, BackgroundSource.Skin);
|
||||
SetDefault(OsuSetting.SeasonalBackgroundMode, SeasonalBackgroundMode.Sometimes);
|
||||
SetDefault(OsuSetting.SeasonalBackgroundMode, SeasonalBackgroundMode.Never);
|
||||
|
||||
SetDefault(OsuSetting.DiscordRichPresence, DiscordRichPresenceMode.Full);
|
||||
|
||||
@@ -436,6 +436,7 @@ namespace osu.Game.Configuration
|
||||
MenuBackgroundSource,
|
||||
GameplayDisableWinKey,
|
||||
SeasonalBackgroundMode,
|
||||
BackgroundCategory,
|
||||
EditorWaveformOpacity,
|
||||
EditorShowHitMarkers,
|
||||
EditorAutoSeekOnPlacement,
|
||||
|
||||
@@ -14,12 +14,6 @@ namespace osu.Game.Configuration
|
||||
[LocalisableDescription(typeof(UserInterfaceStrings), nameof(UserInterfaceStrings.AlwaysSeasonalBackground))]
|
||||
Always,
|
||||
|
||||
/// <summary>
|
||||
/// Seasonal backgrounds are shown only during their corresponding season.
|
||||
/// </summary>
|
||||
[LocalisableDescription(typeof(UserInterfaceStrings), nameof(UserInterfaceStrings.SometimesSeasonalBackground))]
|
||||
Sometimes,
|
||||
|
||||
/// <summary>
|
||||
/// Seasonal backgrounds are never shown.
|
||||
/// </summary>
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
#nullable disable
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using osu.Framework.Allocation;
|
||||
using osu.Framework.Bindables;
|
||||
@@ -19,79 +20,120 @@ namespace osu.Game.Graphics.Backgrounds
|
||||
{
|
||||
public partial class SeasonalBackgroundLoader : Component
|
||||
{
|
||||
public event Action<Exception> OnLoadFailure;
|
||||
public event Action BackgroundChanged;
|
||||
|
||||
/// <summary>
|
||||
/// Fired when background should be changed due to receiving backgrounds from API
|
||||
/// or when the user setting is changed (as it might require unloading the seasonal background).
|
||||
/// Fired when categories have been successfully refreshed from the server.
|
||||
/// </summary>
|
||||
public event Action SeasonalBackgroundChanged;
|
||||
public event Action OnCategoriesRefreshed;
|
||||
|
||||
public readonly Bindable<IEnumerable<string>> AvailableCategories = new Bindable<IEnumerable<string>>(new List<string>());
|
||||
|
||||
[Resolved]
|
||||
private IAPIProvider api { get; set; }
|
||||
|
||||
private Bindable<SeasonalBackgroundMode> seasonalBackgroundMode;
|
||||
private Bindable<APISeasonalBackgrounds> seasonalBackgrounds;
|
||||
private Bindable<SeasonalBackgroundMode> backgroundMode;
|
||||
private Bindable<string> selectedCategory;
|
||||
private Bindable<APISeasonalBackgrounds> currentBackgrounds;
|
||||
|
||||
private int current;
|
||||
private int currentBackgroundIndex;
|
||||
|
||||
private bool shouldShowCustomBackgrounds => backgroundMode.Value != SeasonalBackgroundMode.Never;
|
||||
|
||||
[BackgroundDependencyLoader]
|
||||
private void load(OsuConfigManager config, SessionStatics sessionStatics)
|
||||
{
|
||||
seasonalBackgroundMode = config.GetBindable<SeasonalBackgroundMode>(OsuSetting.SeasonalBackgroundMode);
|
||||
seasonalBackgroundMode.BindValueChanged(_ => SeasonalBackgroundChanged?.Invoke());
|
||||
backgroundMode = config.GetBindable<SeasonalBackgroundMode>(OsuSetting.SeasonalBackgroundMode);
|
||||
backgroundMode.BindValueChanged(_ => BackgroundChanged?.Invoke());
|
||||
|
||||
seasonalBackgrounds = sessionStatics.GetBindable<APISeasonalBackgrounds>(Static.SeasonalBackgrounds);
|
||||
seasonalBackgrounds.BindValueChanged(_ =>
|
||||
{
|
||||
if (shouldShowSeasonal)
|
||||
SeasonalBackgroundChanged?.Invoke();
|
||||
});
|
||||
selectedCategory = config.GetBindable<string>(OsuSetting.BackgroundCategory);
|
||||
selectedCategory.BindValueChanged(_ => fetchBackgroundsForSelectedCategory());
|
||||
|
||||
fetchSeasonalBackgrounds();
|
||||
currentBackgrounds = sessionStatics.GetBindable<APISeasonalBackgrounds>(Static.SeasonalBackgrounds);
|
||||
|
||||
if (shouldShowCustomBackgrounds)
|
||||
fetchCategories();
|
||||
}
|
||||
|
||||
private void fetchSeasonalBackgrounds()
|
||||
/// <summary>
|
||||
/// Public method to trigger a refresh of categories from the UI.
|
||||
/// </summary>
|
||||
public void RefreshCategories()
|
||||
{
|
||||
if (seasonalBackgrounds.Value != null)
|
||||
return;
|
||||
fetchCategories();
|
||||
}
|
||||
|
||||
private void fetchCategories()
|
||||
{
|
||||
if (!shouldShowCustomBackgrounds) return;
|
||||
|
||||
var request = new GetBackgroundCategoriesRequest();
|
||||
|
||||
var request = new GetSeasonalBackgroundsRequest();
|
||||
request.Success += response =>
|
||||
{
|
||||
seasonalBackgrounds.Value = response;
|
||||
current = RNG.Next(0, response.Backgrounds?.Count ?? 0);
|
||||
var serverCategories = response.Categories ?? Enumerable.Empty<string>();
|
||||
|
||||
AvailableCategories.Value = new[] { "Default" }.Concat(serverCategories)
|
||||
.Distinct(StringComparer.OrdinalIgnoreCase).ToList();
|
||||
|
||||
if (!AvailableCategories.Value.Contains(selectedCategory.Value))
|
||||
selectedCategory.Value = "Default";
|
||||
else
|
||||
fetchBackgroundsForSelectedCategory();
|
||||
|
||||
OnCategoriesRefreshed?.Invoke();
|
||||
};
|
||||
|
||||
request.Failure += exception =>
|
||||
{
|
||||
AvailableCategories.Value = new[] { "Íå óäàëîñü çàãðóçèòü..." };
|
||||
OnLoadFailure?.Invoke(exception);
|
||||
};
|
||||
|
||||
api.PerformAsync(request);
|
||||
}
|
||||
|
||||
public SeasonalBackground LoadNextBackground()
|
||||
private void fetchBackgroundsForSelectedCategory()
|
||||
{
|
||||
if (!shouldShowSeasonal)
|
||||
if (!shouldShowCustomBackgrounds) return;
|
||||
|
||||
if (AvailableCategories.Value.Count() == 1 && AvailableCategories.Value.First().Contains("Íå óäàëîñü"))
|
||||
{
|
||||
currentBackgrounds.Value = new APISeasonalBackgrounds { Backgrounds = new List<APISeasonalBackground>() };
|
||||
BackgroundChanged?.Invoke();
|
||||
return;
|
||||
}
|
||||
|
||||
string categoryToFetch = selectedCategory.Value == "Default" ? null : selectedCategory.Value;
|
||||
var request = new GetSeasonalBackgroundsRequest(categoryToFetch);
|
||||
|
||||
request.Success += response =>
|
||||
{
|
||||
currentBackgrounds.Value = response;
|
||||
currentBackgroundIndex = RNG.Next(0, response.Backgrounds?.Count ?? 0);
|
||||
BackgroundChanged?.Invoke();
|
||||
};
|
||||
|
||||
request.Failure += exception =>
|
||||
{
|
||||
OnLoadFailure?.Invoke(exception);
|
||||
};
|
||||
|
||||
api.PerformAsync(request);
|
||||
}
|
||||
|
||||
public Background LoadNextBackground()
|
||||
{
|
||||
if (!shouldShowCustomBackgrounds || currentBackgrounds.Value?.Backgrounds?.Any() != true)
|
||||
return null;
|
||||
|
||||
var backgrounds = seasonalBackgrounds.Value.Backgrounds;
|
||||
|
||||
current = (current + 1) % backgrounds.Count;
|
||||
string url = backgrounds[current].Url;
|
||||
var backgrounds = currentBackgrounds.Value.Backgrounds;
|
||||
currentBackgroundIndex = (currentBackgroundIndex + 1) % backgrounds.Count;
|
||||
string url = backgrounds[currentBackgroundIndex].Url;
|
||||
|
||||
return new SeasonalBackground(url);
|
||||
}
|
||||
|
||||
private bool shouldShowSeasonal
|
||||
{
|
||||
get
|
||||
{
|
||||
if (seasonalBackgroundMode.Value == SeasonalBackgroundMode.Never)
|
||||
return false;
|
||||
|
||||
if (seasonalBackgroundMode.Value == SeasonalBackgroundMode.Sometimes && !isInSeason)
|
||||
return false;
|
||||
|
||||
return seasonalBackgrounds.Value?.Backgrounds?.Any() == true;
|
||||
}
|
||||
}
|
||||
|
||||
private bool isInSeason => seasonalBackgrounds.Value != null && DateTimeOffset.Now < seasonalBackgrounds.Value.EndDate;
|
||||
}
|
||||
|
||||
[LongRunningLoad]
|
||||
|
||||
@@ -78,6 +78,20 @@ Your experience will not be perfect, and may even feel subpar compared to games
|
||||
|
||||
Please bear with us as we continue to improve the game for you!");
|
||||
|
||||
/// <summary>
|
||||
/// "Welcome to jvnkosu!lazer!"
|
||||
/// </summary>
|
||||
public static LocalisableString GreetingNotification => new TranslatableString(getKey(@"greeting_notification"), @"Welcome to jvnkosu!lazer!");
|
||||
|
||||
/// <summary>
|
||||
/// "Failed to load backgrounds!\nCheck your internet connection"
|
||||
/// </summary>
|
||||
public static LocalisableString SeasonalBackgroundsFail => new TranslatableString(getKey(@"seasonal_backgrounds_fail"), @"Failed to load backgrounds!\nCheck your internet connection"); // TODO: implement l10n in osu-resources
|
||||
|
||||
/// <summary>
|
||||
/// "Successfully refreshed background categories!"
|
||||
/// </summary>
|
||||
public static LocalisableString SeasonalBackgroundsRefreshed => new TranslatableString(getKey(@"seasonal_backgrounds_refreshed"), @"Successfully refreshed background categories!");
|
||||
private static string getKey(string key) => $@"{prefix}:{key}";
|
||||
}
|
||||
}
|
||||
|
||||
@@ -64,11 +64,26 @@ namespace osu.Game.Localisation
|
||||
/// </summary>
|
||||
public static LocalisableString BackgroundSource => new TranslatableString(getKey(@"background_source"), @"Background source");
|
||||
|
||||
/// <summary>
|
||||
/// "Use custom backgrounds from server"
|
||||
/// </summary>
|
||||
public static LocalisableString UseSeasonalBackgrounds => new TranslatableString(getKey(@"use_seasonal_backgrounds"), @"Use custom backgrounds from server");
|
||||
|
||||
/// <summary>
|
||||
/// "Seasonal backgrounds"
|
||||
/// </summary>
|
||||
public static LocalisableString SeasonalBackgrounds => new TranslatableString(getKey(@"seasonal_backgrounds"), @"Seasonal backgrounds");
|
||||
|
||||
/// <summary>
|
||||
/// "Background categories"
|
||||
/// </summary>
|
||||
public static LocalisableString SeasonalBackgroundsCategories => new TranslatableString(getKey(@"seasonal_backgrounds_categories"), @"Background categories");
|
||||
|
||||
/// <summary>
|
||||
/// "Refresh categories"
|
||||
/// </summary>
|
||||
public static LocalisableString SeasonalBackgroundsRefresh => new TranslatableString(getKey(@"seasonal_backgrounds_refresh"), @"Refresh categories");
|
||||
|
||||
/// <summary>
|
||||
/// "Changes to this setting will only apply with an active osu!supporter tag."
|
||||
/// </summary>
|
||||
|
||||
@@ -0,0 +1,12 @@
|
||||
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
||||
// See the LICENCE file in the repository root for full licence text.
|
||||
|
||||
using osu.Game.Online.API.Requests.Responses;
|
||||
|
||||
namespace osu.Game.Online.API.Requests
|
||||
{
|
||||
public class GetBackgroundCategoriesRequest : APIRequest<APIBackgroundCategories>
|
||||
{
|
||||
protected override string Target => @"seasonal-backgrounds-categories";
|
||||
}
|
||||
}
|
||||
@@ -8,7 +8,7 @@ namespace osu.Game.Online.API.Requests
|
||||
public class GetMenuContentRequest : OsuJsonWebRequest<APIMenuContent>
|
||||
{
|
||||
public GetMenuContentRequest()
|
||||
: base(@"https://assets.ppy.sh/menu-content.json")
|
||||
: base(@"https://osu.jvnko.boats/uploads/menu-content.json") // TODO: backend
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,12 +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.
|
||||
#nullable enable
|
||||
|
||||
using System.Net;
|
||||
using osu.Game.Online.API.Requests.Responses;
|
||||
|
||||
namespace osu.Game.Online.API.Requests
|
||||
{
|
||||
public class GetSeasonalBackgroundsRequest : APIRequest<APISeasonalBackgrounds>
|
||||
{
|
||||
protected override string Target => @"seasonal-backgrounds";
|
||||
private readonly string? category;
|
||||
|
||||
public GetSeasonalBackgroundsRequest()
|
||||
{
|
||||
}
|
||||
|
||||
public GetSeasonalBackgroundsRequest(string? category)
|
||||
{
|
||||
this.category = category;
|
||||
}
|
||||
|
||||
protected override string Target => getPath();
|
||||
|
||||
private string getPath()
|
||||
{
|
||||
if (string.IsNullOrEmpty(category))
|
||||
return @"seasonal-backgrounds";
|
||||
|
||||
return $@"seasonal-backgrounds?category={WebUtility.UrlEncode(category)}";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,14 @@
|
||||
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
||||
// See the LICENCE file in the repository root for full licence text.
|
||||
|
||||
using System.Collections.Generic;
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace osu.Game.Online.API.Requests.Responses
|
||||
{
|
||||
public class APIBackgroundCategories
|
||||
{
|
||||
[JsonProperty("categories")]
|
||||
public List<string>? Categories { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -11,11 +11,11 @@ namespace osu.Game.Online
|
||||
{
|
||||
protected override string GetLookupUrl(string url)
|
||||
{
|
||||
/* if (!Uri.TryCreate(url, UriKind.Absolute, out Uri? uri) || !uri.Host.EndsWith(@".ppy.sh", StringComparison.OrdinalIgnoreCase))
|
||||
if (!Uri.TryCreate(url, UriKind.Absolute, out Uri? uri) || !uri.Host.EndsWith(@".jvnko.boats", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
Logger.Log($@"Blocking resource lookup from external website: {url}", LoggingTarget.Network, LogLevel.Important);
|
||||
return string.Empty;
|
||||
}*/
|
||||
}
|
||||
|
||||
return url;
|
||||
}
|
||||
|
||||
@@ -38,6 +38,7 @@ using osu.Game.Configuration;
|
||||
using osu.Game.Database;
|
||||
using osu.Game.Extensions;
|
||||
using osu.Game.Graphics;
|
||||
using osu.Game.Graphics.Backgrounds;
|
||||
using osu.Game.Graphics.Containers;
|
||||
using osu.Game.Graphics.UserInterface;
|
||||
using osu.Game.Input;
|
||||
@@ -169,6 +170,9 @@ namespace osu.Game
|
||||
[Cached]
|
||||
private readonly ScreenshotManager screenshotManager = new ScreenshotManager();
|
||||
|
||||
[Cached]
|
||||
private readonly SeasonalBackgroundLoader backgroundLoader;
|
||||
|
||||
protected SentryLogger SentryLogger;
|
||||
|
||||
public virtual StableStorage GetStorageForStableInstall() => null;
|
||||
@@ -249,6 +253,10 @@ namespace osu.Game
|
||||
|
||||
public OsuGame(string[] args = null)
|
||||
{
|
||||
backgroundLoader = new SeasonalBackgroundLoader();
|
||||
backgroundLoader.OnLoadFailure += handleBackgroundLoadFailure;
|
||||
backgroundLoader.OnCategoriesRefreshed += handleCategoriesRefreshed;
|
||||
|
||||
this.args = args;
|
||||
|
||||
Logger.NewEntry += forwardGeneralLogToNotifications;
|
||||
@@ -401,6 +409,18 @@ namespace osu.Game
|
||||
}
|
||||
}
|
||||
}
|
||||
private void handleCategoriesRefreshed()
|
||||
{
|
||||
Schedule(() =>
|
||||
{
|
||||
Notifications?.Post(new SimpleNotification
|
||||
{
|
||||
Text = ButtonSystemStrings.SeasonalBackgroundsRefreshed,
|
||||
Icon = FontAwesome.Solid.CheckCircle,
|
||||
Transient = true
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
[BackgroundDependencyLoader]
|
||||
private void load()
|
||||
@@ -927,7 +947,7 @@ namespace osu.Game
|
||||
|
||||
protected virtual Loader CreateLoader() => new Loader();
|
||||
|
||||
protected virtual UpdateManager CreateUpdateManager() => new UpdateManager();
|
||||
protected virtual UpdateManager CreateUpdateManager() => new NoActionUpdateManager();
|
||||
|
||||
/// <summary>
|
||||
/// Adjust the globally applied <see cref="DrawSizePreservingFillContainer.TargetDrawSize"/> in every <see cref="ScalingContainer"/>.
|
||||
@@ -1186,8 +1206,8 @@ namespace osu.Game
|
||||
Margin = new MarginPadding(5),
|
||||
}, topMostOverlayContent.Add);
|
||||
|
||||
if (!IsDeployedBuild)
|
||||
loadComponentSingleFile(devBuildBanner = new DevBuildBanner(), ScreenContainer.Add);
|
||||
// if (!IsDeployedBuild) // we're going to have the "developer build" banner for a while
|
||||
loadComponentSingleFile(devBuildBanner = new DevBuildBanner(), ScreenContainer.Add);
|
||||
|
||||
loadComponentSingleFile(osuLogo, _ =>
|
||||
{
|
||||
@@ -1232,6 +1252,8 @@ namespace osu.Game
|
||||
|
||||
loadComponentSingleFile(screenshotManager, Add);
|
||||
|
||||
loadComponentSingleFile(backgroundLoader, Add);
|
||||
|
||||
// dependency on notification overlay, dependent by settings overlay
|
||||
loadComponentSingleFile(CreateUpdateManager(), Add, true);
|
||||
|
||||
@@ -1333,6 +1355,18 @@ namespace osu.Game
|
||||
handleStartupImport();
|
||||
}
|
||||
|
||||
private void handleBackgroundLoadFailure(Exception exception)
|
||||
{
|
||||
Schedule(() =>
|
||||
{
|
||||
Notifications?.Post(new SimpleErrorNotification
|
||||
{
|
||||
Text = ButtonSystemStrings.SeasonalBackgroundsFail,
|
||||
Icon = FontAwesome.Solid.ExclamationTriangle,
|
||||
Transient = true
|
||||
});
|
||||
});
|
||||
}
|
||||
private void handleBackButton()
|
||||
{
|
||||
// TODO: this is SUPER SUPER bad.
|
||||
@@ -1701,6 +1735,12 @@ namespace osu.Game
|
||||
{
|
||||
case IntroScreen intro:
|
||||
introScreen = intro;
|
||||
SimpleNotification notification = new SimpleNotification
|
||||
{
|
||||
Text = ButtonSystemStrings.GreetingNotification,
|
||||
Transient = true,
|
||||
};
|
||||
Notifications?.Post(notification);
|
||||
devBuildBanner?.Show();
|
||||
break;
|
||||
|
||||
|
||||
@@ -32,7 +32,7 @@ namespace osu.Game.Overlays
|
||||
Origin = Anchor.BottomCentre,
|
||||
Font = OsuFont.Torus.With(size: 12),
|
||||
Colour = colours.GrayF,
|
||||
Text = "jvnkosu! development build",
|
||||
Text = $@"jvnkosu! " + game.Version,
|
||||
Y = -12,
|
||||
},
|
||||
new OsuSpriteText
|
||||
|
||||
@@ -8,9 +8,11 @@ using osu.Framework.Bindables;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Framework.Localisation;
|
||||
using osu.Game.Configuration;
|
||||
using osu.Game.Graphics.Backgrounds;
|
||||
using osu.Game.Localisation;
|
||||
using osu.Game.Online.API;
|
||||
using osu.Game.Online.API.Requests.Responses;
|
||||
using osu.Game.Overlays.Settings;
|
||||
|
||||
namespace osu.Game.Overlays.Settings.Sections.UserInterface
|
||||
{
|
||||
@@ -18,6 +20,9 @@ namespace osu.Game.Overlays.Settings.Sections.UserInterface
|
||||
{
|
||||
protected override LocalisableString Header => UserInterfaceStrings.MainMenuHeader;
|
||||
|
||||
[Resolved]
|
||||
private SeasonalBackgroundLoader backgroundLoader { get; set; }
|
||||
|
||||
private IBindable<APIUser> user;
|
||||
|
||||
private SettingsEnumDropdown<BackgroundSource> backgroundSourceDropdown;
|
||||
@@ -27,6 +32,46 @@ namespace osu.Game.Overlays.Settings.Sections.UserInterface
|
||||
{
|
||||
user = api.LocalUser.GetBoundCopy();
|
||||
|
||||
var backgroundModeBindable = config.GetBindable<SeasonalBackgroundMode>(OsuSetting.SeasonalBackgroundMode);
|
||||
var enabledProxyBindable = new Bindable<bool>();
|
||||
|
||||
backgroundModeBindable.BindValueChanged(mode => enabledProxyBindable.Value = mode.NewValue == SeasonalBackgroundMode.Always, true);
|
||||
enabledProxyBindable.BindValueChanged(enabled => backgroundModeBindable.Value = enabled.NewValue ? SeasonalBackgroundMode.Always : SeasonalBackgroundMode.Never);
|
||||
|
||||
var backgroundToggle = new SettingsCheckbox
|
||||
{
|
||||
LabelText = UserInterfaceStrings.UseSeasonalBackgrounds,
|
||||
Current = enabledProxyBindable
|
||||
};
|
||||
|
||||
var categoryDropdown = new SettingsDropdown<string>
|
||||
{
|
||||
LabelText = UserInterfaceStrings.SeasonalBackgroundsCategories,
|
||||
Current = config.GetBindable<string>(OsuSetting.BackgroundCategory)
|
||||
};
|
||||
|
||||
var refreshButton = new SettingsButton
|
||||
{
|
||||
Text = UserInterfaceStrings.SeasonalBackgroundsRefresh,
|
||||
Action = () => backgroundLoader.RefreshCategories()
|
||||
};
|
||||
|
||||
backgroundLoader.AvailableCategories.BindValueChanged(categories => categoryDropdown.Items = categories.NewValue, true);
|
||||
|
||||
backgroundModeBindable.BindValueChanged(mode =>
|
||||
{
|
||||
if (mode.NewValue == SeasonalBackgroundMode.Always)
|
||||
{
|
||||
categoryDropdown.Show();
|
||||
refreshButton.Show();
|
||||
}
|
||||
else
|
||||
{
|
||||
categoryDropdown.Hide();
|
||||
refreshButton.Hide();
|
||||
}
|
||||
}, true);
|
||||
|
||||
Children = new Drawable[]
|
||||
{
|
||||
new SettingsCheckbox
|
||||
@@ -56,11 +101,9 @@ namespace osu.Game.Overlays.Settings.Sections.UserInterface
|
||||
LabelText = UserInterfaceStrings.BackgroundSource,
|
||||
Current = config.GetBindable<BackgroundSource>(OsuSetting.MenuBackgroundSource),
|
||||
},
|
||||
new SettingsEnumDropdown<SeasonalBackgroundMode>
|
||||
{
|
||||
LabelText = UserInterfaceStrings.SeasonalBackgrounds,
|
||||
Current = config.GetBindable<SeasonalBackgroundMode>(OsuSetting.SeasonalBackgroundMode),
|
||||
}
|
||||
backgroundToggle,
|
||||
categoryDropdown,
|
||||
refreshButton,
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -62,7 +62,7 @@ namespace osu.Game.Screens.Backgrounds
|
||||
source.ValueChanged += _ => Scheduler.AddOnce(next);
|
||||
beatmap.ValueChanged += _ => Scheduler.AddOnce(next);
|
||||
introSequence.ValueChanged += _ => Scheduler.AddOnce(next);
|
||||
seasonalBackgroundLoader.SeasonalBackgroundChanged += () => Scheduler.AddOnce(next);
|
||||
seasonalBackgroundLoader.BackgroundChanged += () => Scheduler.AddOnce(next);
|
||||
|
||||
currentDisplay = RNG.Next(0, background_count);
|
||||
Next();
|
||||
|
||||
@@ -36,7 +36,7 @@ namespace osu.Game.Updater
|
||||
ReleaseStream stream = externalReleaseStream ?? ReleaseStream.Value;
|
||||
bool includePrerelease = stream == Configuration.ReleaseStream.Tachyon;
|
||||
|
||||
OsuJsonWebRequest<GitHubRelease[]> releasesRequest = new OsuJsonWebRequest<GitHubRelease[]>("https://api.github.com/repos/ppy/osu/releases?per_page=10&page=1");
|
||||
OsuJsonWebRequest<GitHubRelease[]> releasesRequest = new OsuJsonWebRequest<GitHubRelease[]>("https://gitea.jvnko.boats/api/v1/repos/jvnkosu/client/releases?limit=10&page=1");
|
||||
await releasesRequest.PerformAsync(cancellationToken).ConfigureAwait(false);
|
||||
|
||||
GitHubRelease[] releases = releasesRequest.ResponseObject;
|
||||
|
||||
@@ -69,9 +69,10 @@ namespace osu.Game.Updater
|
||||
if (FixedReleaseStream != null)
|
||||
config.SetValue(OsuSetting.ReleaseStream, FixedReleaseStream.Value);
|
||||
|
||||
// notify the user if they're using a build that is not officially sanctioned.
|
||||
if (RuntimeInfo.EntryAssembly.GetCustomAttribute<OfficialBuildAttribute>() == null)
|
||||
Notifications.Post(new SimpleNotification { Text = NotificationsStrings.NotOfficialBuild });
|
||||
// nope, doesn't matter, we're already not official
|
||||
// // notify the user if they're using a build that is not officially sanctioned.
|
||||
// if (RuntimeInfo.EntryAssembly.GetCustomAttribute<OfficialBuildAttribute>() == null)
|
||||
// Notifications.Post(new SimpleNotification { Text = NotificationsStrings.NotOfficialBuild });
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
@@ -36,7 +36,7 @@ namespace osu.Game.Users.Drawables
|
||||
if (user != null && user.OnlineID > 1)
|
||||
// TODO: The fallback here should not need to exist. Users should be looked up and populated via UserLookupCache or otherwise
|
||||
// in remaining cases where this is required (chat tabs, local leaderboard), at which point this should be removed.
|
||||
Texture = textures.Get((user as APIUser)?.AvatarUrl ?? $@"https://a.ppy.sh/{user.OnlineID}");
|
||||
Texture = textures.Get((user as APIUser)?.AvatarUrl ?? $@"https://osu.jvnko.boats/uploads-avatar/{user.OnlineID}");
|
||||
|
||||
Texture ??= textures.Get(@"Online/avatar-guest");
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user