1
0
mirror of https://github.com/ppy/osu.git synced 2025-02-15 11:43:21 +08:00

Merge pull request #31804 from bdach/bss/api-setup

Add API request & response structures for beatmap submission
This commit is contained in:
Dean Herbert 2025-02-07 17:43:38 +09:00 committed by GitHub
commit cf4b501214
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
37 changed files with 312 additions and 75 deletions

View File

@ -173,7 +173,7 @@ namespace osu.Desktop
new Button
{
Label = "View beatmap",
Url = $@"{api.WebsiteRootUrl}/beatmaps/{beatmapId}?mode={ruleset.Value.ShortName}"
Url = $@"{api.Endpoints.WebsiteUrl}/beatmaps/{beatmapId}?mode={ruleset.Value.ShortName}"
}
};
}

View File

@ -80,7 +80,7 @@ namespace osu.Game.Tests.Visual.Menus
new APIMenuImage
{
Image = @"https://assets.ppy.sh/main-menu/project-loved-2@2x.png",
Url = $@"{API.WebsiteRootUrl}/home/news/2023-12-21-project-loved-december-2023",
Url = $@"{API.Endpoints.WebsiteUrl}/home/news/2023-12-21-project-loved-december-2023",
}
}
});

View File

@ -67,19 +67,19 @@ namespace osu.Game.Tests.Visual.Online
[Test]
public void TestLink()
{
AddStep("set current path", () => markdownContainer.CurrentPath = $"{API.WebsiteRootUrl}/wiki/Article_styling_criteria/");
AddStep("set current path", () => markdownContainer.CurrentPath = $"{API.Endpoints.WebsiteUrl}/wiki/Article_styling_criteria/");
AddStep("set '/wiki/Main_page''", () => markdownContainer.Text = "[wiki main page](/wiki/Main_page)");
AddAssert("check url", () => markdownContainer.Link.Url == $"{API.WebsiteRootUrl}/wiki/Main_page");
AddAssert("check url", () => markdownContainer.Link.Url == $"{API.Endpoints.WebsiteUrl}/wiki/Main_page");
AddStep("set '../FAQ''", () => markdownContainer.Text = "[FAQ](../FAQ)");
AddAssert("check url", () => markdownContainer.Link.Url == $"{API.WebsiteRootUrl}/wiki/FAQ");
AddAssert("check url", () => markdownContainer.Link.Url == $"{API.Endpoints.WebsiteUrl}/wiki/FAQ");
AddStep("set './Writing''", () => markdownContainer.Text = "[wiki writing guidline](./Writing)");
AddAssert("check url", () => markdownContainer.Link.Url == $"{API.WebsiteRootUrl}/wiki/Article_styling_criteria/Writing");
AddAssert("check url", () => markdownContainer.Link.Url == $"{API.Endpoints.WebsiteUrl}/wiki/Article_styling_criteria/Writing");
AddStep("set 'Formatting''", () => markdownContainer.Text = "[wiki formatting guidline](Formatting)");
AddAssert("check url", () => markdownContainer.Link.Url == $"{API.WebsiteRootUrl}/wiki/Article_styling_criteria/Formatting");
AddAssert("check url", () => markdownContainer.Link.Url == $"{API.Endpoints.WebsiteUrl}/wiki/Article_styling_criteria/Formatting");
}
[Test]

View File

@ -59,7 +59,7 @@ namespace osu.Game.Beatmaps
if (beatmapInfo.OnlineID <= 0 || beatmapInfo.BeatmapSet == null)
return null;
return $@"{api.WebsiteRootUrl}/beatmapsets/{beatmapInfo.BeatmapSet.OnlineID}#{ruleset?.ShortName ?? beatmapInfo.Ruleset.ShortName}/{beatmapInfo.OnlineID}";
return $@"{api.Endpoints.WebsiteUrl}/beatmapsets/{beatmapInfo.BeatmapSet.OnlineID}#{ruleset?.ShortName ?? beatmapInfo.Ruleset.ShortName}/{beatmapInfo.OnlineID}";
}
}
}

View File

@ -41,9 +41,9 @@ namespace osu.Game.Beatmaps
return null;
if (ruleset != null)
return $@"{api.WebsiteRootUrl}/beatmapsets/{beatmapSetInfo.OnlineID}#{ruleset.ShortName}";
return $@"{api.Endpoints.WebsiteUrl}/beatmapsets/{beatmapSetInfo.OnlineID}#{ruleset.ShortName}";
return $@"{api.WebsiteRootUrl}/beatmapsets/{beatmapSetInfo.OnlineID}";
return $@"{api.Endpoints.WebsiteUrl}/beatmapsets/{beatmapSetInfo.OnlineID}";
}
}
}

View File

@ -40,9 +40,7 @@ namespace osu.Game.Online.API
private readonly Queue<APIRequest> queue = new Queue<APIRequest>();
public string APIEndpointUrl { get; }
public string WebsiteRootUrl { get; }
public EndpointConfiguration Endpoints { get; }
/// <summary>
/// The API response version.
@ -75,7 +73,7 @@ namespace osu.Game.Online.API
private readonly CancellationTokenSource cancellationToken = new CancellationTokenSource();
private readonly Logger log;
public APIAccess(OsuGameBase game, OsuConfigManager config, EndpointConfiguration endpointConfiguration, string versionHash)
public APIAccess(OsuGameBase game, OsuConfigManager config, EndpointConfiguration endpoints, string versionHash)
{
this.game = game;
this.config = config;
@ -89,14 +87,13 @@ namespace osu.Game.Online.API
APIVersion = now.Year * 10000 + now.Month * 100 + now.Day;
}
APIEndpointUrl = endpointConfiguration.APIEndpointUrl;
WebsiteRootUrl = endpointConfiguration.WebsiteRootUrl;
Endpoints = endpoints;
NotificationsClient = setUpNotificationsClient();
authentication = new OAuth(endpointConfiguration.APIClientID, endpointConfiguration.APIClientSecret, APIEndpointUrl);
authentication = new OAuth(endpoints.APIClientID, endpoints.APIClientSecret, Endpoints.APIUrl);
log = Logger.GetLogger(LoggingTarget.Network);
log.Add($@"API endpoint root: {APIEndpointUrl}");
log.Add($@"API endpoint root: {Endpoints.APIUrl}");
log.Add($@"API request version: {APIVersion}");
ProvidedUsername = config.Get<string>(OsuSetting.Username);
@ -408,7 +405,7 @@ namespace osu.Game.Online.API
var req = new RegistrationRequest
{
Url = $@"{APIEndpointUrl}/users",
Url = $@"{Endpoints.APIUrl}/users",
Method = HttpMethod.Post,
Username = username,
Email = email,

View File

@ -71,7 +71,7 @@ namespace osu.Game.Online.API
protected virtual WebRequest CreateWebRequest() => new OsuWebRequest(Uri);
protected virtual string Uri => $@"{API!.APIEndpointUrl}/api/v2/{Target}";
protected virtual string Uri => $@"{API!.Endpoints.APIUrl}/api/v2/{Target}";
protected IAPIProvider? API;

View File

@ -41,9 +41,11 @@ namespace osu.Game.Online.API
public string ProvidedUsername => LocalUser.Value.Username;
public string APIEndpointUrl => "http://localhost";
public string WebsiteRootUrl => "http://localhost";
public EndpointConfiguration Endpoints { get; } = new EndpointConfiguration
{
APIUrl = "http://localhost",
WebsiteUrl = "http://localhost",
};
public int APIVersion => int.Parse(DateTime.Now.ToString("yyyyMMdd"));

View File

@ -51,14 +51,9 @@ namespace osu.Game.Online.API
string ProvidedUsername { get; }
/// <summary>
/// The URL endpoint for this API. Does not include a trailing slash.
/// Holds configuration for online endpoints.
/// </summary>
string APIEndpointUrl { get; }
/// <summary>
/// The root URL of the website, excluding the trailing slash.
/// </summary>
string WebsiteRootUrl { get; }
EndpointConfiguration Endpoints { get; }
/// <summary>
/// The version of the API.

View File

@ -0,0 +1,26 @@
// 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.Diagnostics;
using osu.Framework.IO.Network;
namespace osu.Game.Online.API.Requests
{
public abstract class APIUploadRequest : APIRequest
{
protected override WebRequest CreateWebRequest()
{
var request = base.CreateWebRequest();
request.UploadProgress += onUploadProgress;
return request;
}
private void onUploadProgress(long current, long total)
{
Debug.Assert(API != null);
API.Schedule(() => Progressed?.Invoke(current, total));
}
public event APIProgressHandler? Progressed;
}
}

View File

@ -0,0 +1,55 @@
// 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.Collections.Generic;
using System.Net.Http;
using osu.Framework.IO.Network;
namespace osu.Game.Online.API.Requests
{
public class PatchBeatmapPackageRequest : APIUploadRequest
{
protected override string Uri
{
get
{
// can be removed once the service has been successfully deployed to production
if (API!.Endpoints.BeatmapSubmissionServiceUrl == null)
throw new NotSupportedException("Beatmap submission not supported in this configuration!");
return $@"{API!.Endpoints.BeatmapSubmissionServiceUrl!}/beatmapsets/{BeatmapSetID}";
}
}
protected override string Target => throw new NotSupportedException();
public uint BeatmapSetID { get; }
// ReSharper disable once CollectionNeverUpdated.Global
public Dictionary<string, byte[]> FilesChanged { get; } = new Dictionary<string, byte[]>();
// ReSharper disable once CollectionNeverUpdated.Global
public HashSet<string> FilesDeleted { get; } = new HashSet<string>();
public PatchBeatmapPackageRequest(uint beatmapSetId)
{
BeatmapSetID = beatmapSetId;
}
protected override WebRequest CreateWebRequest()
{
var request = base.CreateWebRequest();
request.Method = HttpMethod.Patch;
foreach ((string filename, byte[] content) in FilesChanged)
request.AddFile(@"filesChanged", content, filename);
foreach (string filename in FilesDeleted)
request.AddParameter(@"filesDeleted", filename, RequestParameterType.Form);
request.Timeout = 60_000;
return request;
}
}
}

View File

@ -0,0 +1,82 @@
// 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.Collections.Generic;
using System.Linq;
using System.Net.Http;
using Newtonsoft.Json;
using Newtonsoft.Json.Converters;
using osu.Framework.IO.Network;
using osu.Framework.Localisation;
using osu.Game.Localisation;
using osu.Game.Online.API.Requests.Responses;
namespace osu.Game.Online.API.Requests
{
public class PutBeatmapSetRequest : APIRequest<PutBeatmapSetResponse>
{
protected override string Uri
{
get
{
// can be removed once the service has been successfully deployed to production
if (API!.Endpoints.BeatmapSubmissionServiceUrl == null)
throw new NotSupportedException("Beatmap submission not supported in this configuration!");
return $@"{API!.Endpoints.BeatmapSubmissionServiceUrl}/beatmapsets";
}
}
protected override string Target => throw new NotSupportedException();
[JsonProperty("beatmapset_id")]
public uint? BeatmapSetID { get; init; }
[JsonProperty("beatmaps_to_create")]
public uint BeatmapsToCreate { get; init; }
[JsonProperty("beatmaps_to_keep")]
public uint[] BeatmapsToKeep { get; init; } = [];
[JsonProperty("target")]
public BeatmapSubmissionTarget SubmissionTarget { get; init; }
private PutBeatmapSetRequest()
{
}
public static PutBeatmapSetRequest CreateNew(uint beatmapCount, BeatmapSubmissionTarget target) => new PutBeatmapSetRequest
{
BeatmapsToCreate = beatmapCount,
SubmissionTarget = target,
};
public static PutBeatmapSetRequest UpdateExisting(uint beatmapSetId, IEnumerable<uint> beatmapsToKeep, uint beatmapsToCreate, BeatmapSubmissionTarget target) => new PutBeatmapSetRequest
{
BeatmapSetID = beatmapSetId,
BeatmapsToKeep = beatmapsToKeep.ToArray(),
BeatmapsToCreate = beatmapsToCreate,
SubmissionTarget = target,
};
protected override WebRequest CreateWebRequest()
{
var req = base.CreateWebRequest();
req.Method = HttpMethod.Put;
req.ContentType = @"application/json";
req.AddRaw(JsonConvert.SerializeObject(this));
return req;
}
}
[JsonConverter(typeof(StringEnumConverter))]
public enum BeatmapSubmissionTarget
{
[LocalisableDescription(typeof(BeatmapSubmissionStrings), nameof(BeatmapSubmissionStrings.BeatmapSubmissionTargetWIP))]
WIP,
[LocalisableDescription(typeof(BeatmapSubmissionStrings), nameof(BeatmapSubmissionStrings.BeatmapSubmissionTargetPending))]
Pending,
}
}

View File

@ -0,0 +1,45 @@
// 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.Net.Http;
using osu.Framework.IO.Network;
namespace osu.Game.Online.API.Requests
{
public class ReplaceBeatmapPackageRequest : APIUploadRequest
{
protected override string Uri
{
get
{
// can be removed once the service has been successfully deployed to production
if (API!.Endpoints.BeatmapSubmissionServiceUrl == null)
throw new NotSupportedException("Beatmap submission not supported in this configuration!");
return $@"{API!.Endpoints.BeatmapSubmissionServiceUrl}/beatmapsets/{BeatmapSetID}";
}
}
protected override string Target => throw new NotSupportedException();
public uint BeatmapSetID { get; }
private readonly byte[] oszPackage;
public ReplaceBeatmapPackageRequest(uint beatmapSetID, byte[] oszPackage)
{
this.oszPackage = oszPackage;
BeatmapSetID = beatmapSetID;
}
protected override WebRequest CreateWebRequest()
{
var request = base.CreateWebRequest();
request.AddFile(@"beatmapArchive", oszPackage);
request.Method = HttpMethod.Put;
request.Timeout = 60_000;
return request;
}
}
}

View File

@ -0,0 +1,30 @@
// 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.Collections.Generic;
using Newtonsoft.Json;
namespace osu.Game.Online.API.Requests.Responses
{
public class PutBeatmapSetResponse
{
[JsonProperty("beatmapset_id")]
public uint BeatmapSetId { get; set; }
[JsonProperty("beatmap_ids")]
public ICollection<uint> BeatmapIds { get; set; } = Array.Empty<uint>();
[JsonProperty("files")]
public ICollection<BeatmapSetFile> Files { get; set; } = Array.Empty<BeatmapSetFile>();
}
public struct BeatmapSetFile
{
[JsonProperty("filename")]
public string Filename { get; set; }
[JsonProperty("sha2_hash")]
public string SHA2Hash { get; set; }
}
}

View File

@ -49,12 +49,12 @@ namespace osu.Game.Online.Chat
if (url.StartsWith('/'))
{
url = $"{api.WebsiteRootUrl}{url}";
url = $"{api.Endpoints.WebsiteUrl}{url}";
isTrustedDomain = true;
}
else
{
isTrustedDomain = url.StartsWith(api.WebsiteRootUrl, StringComparison.Ordinal);
isTrustedDomain = url.StartsWith(api.Endpoints.WebsiteUrl, StringComparison.Ordinal);
}
if (!url.CheckIsValidUrl())

View File

@ -95,7 +95,7 @@ namespace osu.Game.Online.Chat
string getBeatmapPart()
{
return beatmapOnlineID > 0 ? $"[{api.WebsiteRootUrl}/b/{beatmapOnlineID} {beatmapDisplayTitle}]" : beatmapDisplayTitle;
return beatmapOnlineID > 0 ? $"[{api.Endpoints.WebsiteUrl}/b/{beatmapOnlineID} {beatmapDisplayTitle}]" : beatmapDisplayTitle;
}
string getRulesetPart()

View File

@ -7,12 +7,12 @@ namespace osu.Game.Online
{
public DevelopmentEndpointConfiguration()
{
WebsiteRootUrl = APIEndpointUrl = @"https://dev.ppy.sh";
WebsiteUrl = APIUrl = @"https://dev.ppy.sh";
APIClientSecret = @"3LP2mhUrV89xxzD1YKNndXHEhWWCRLPNKioZ9ymT";
APIClientID = "5";
SpectatorEndpointUrl = $@"{APIEndpointUrl}/signalr/spectator";
MultiplayerEndpointUrl = $@"{APIEndpointUrl}/signalr/multiplayer";
MetadataEndpointUrl = $@"{APIEndpointUrl}/signalr/metadata";
SpectatorUrl = $@"{APIUrl}/signalr/spectator";
MultiplayerUrl = $@"{APIUrl}/signalr/multiplayer";
MetadataUrl = $@"{APIUrl}/signalr/metadata";
}
}
}

View File

@ -8,16 +8,6 @@ namespace osu.Game.Online
/// </summary>
public class EndpointConfiguration
{
/// <summary>
/// The base URL for the website.
/// </summary>
public string WebsiteRootUrl { get; set; } = string.Empty;
/// <summary>
/// The endpoint for the main (osu-web) API.
/// </summary>
public string APIEndpointUrl { get; set; } = string.Empty;
/// <summary>
/// The OAuth client secret.
/// </summary>
@ -28,19 +18,34 @@ namespace osu.Game.Online
/// </summary>
public string APIClientID { get; set; } = string.Empty;
/// <summary>
/// The base URL for the website. Does not include a trailing slash.
/// </summary>
public string WebsiteUrl { get; set; } = string.Empty;
/// <summary>
/// The endpoint for the main (osu-web) API. Does not include a trailing slash.
/// </summary>
public string APIUrl { get; set; } = string.Empty;
/// <summary>
/// The root URL for the service handling beatmap submission. Does not include a trailing slash.
/// </summary>
public string? BeatmapSubmissionServiceUrl { get; set; }
/// <summary>
/// The endpoint for the SignalR spectator server.
/// </summary>
public string SpectatorEndpointUrl { get; set; } = string.Empty;
public string SpectatorUrl { get; set; } = string.Empty;
/// <summary>
/// The endpoint for the SignalR multiplayer server.
/// </summary>
public string MultiplayerEndpointUrl { get; set; } = string.Empty;
public string MultiplayerUrl { get; set; } = string.Empty;
/// <summary>
/// The endpoint for the SignalR metadata server.
/// </summary>
public string MetadataEndpointUrl { get; set; } = string.Empty;
public string MetadataUrl { get; set; } = string.Empty;
}
}

View File

@ -436,7 +436,7 @@ namespace osu.Game.Online.Leaderboards
items.Add(new OsuMenuItem("Use these mods", MenuItemType.Highlighted, () => songSelect.Mods.Value = Score.Mods));
if (Score.OnlineID > 0)
items.Add(new OsuMenuItem(CommonStrings.CopyLink, MenuItemType.Standard, () => clipboard?.SetText($@"{api.WebsiteRootUrl}/scores/{Score.OnlineID}")));
items.Add(new OsuMenuItem(CommonStrings.CopyLink, MenuItemType.Standard, () => clipboard?.SetText($@"{api.Endpoints.WebsiteUrl}/scores/{Score.OnlineID}")));
if (Score.Files.Count > 0)
{

View File

@ -47,7 +47,7 @@ namespace osu.Game.Online.Metadata
public OnlineMetadataClient(EndpointConfiguration endpoints)
{
endpoint = endpoints.MetadataEndpointUrl;
endpoint = endpoints.MetadataUrl;
}
[BackgroundDependencyLoader]

View File

@ -32,7 +32,7 @@ namespace osu.Game.Online.Multiplayer
public OnlineMultiplayerClient(EndpointConfiguration endpoints)
{
endpoint = endpoints.MultiplayerEndpointUrl;
endpoint = endpoints.MultiplayerUrl;
}
[BackgroundDependencyLoader]

View File

@ -7,12 +7,12 @@ namespace osu.Game.Online
{
public ProductionEndpointConfiguration()
{
WebsiteRootUrl = APIEndpointUrl = @"https://osu.ppy.sh";
WebsiteUrl = APIUrl = @"https://osu.ppy.sh";
APIClientSecret = @"FGc9GAtyHzeQDshWP5Ah7dega8hJACAJpQtw6OXk";
APIClientID = "5";
SpectatorEndpointUrl = "https://spectator.ppy.sh/spectator";
MultiplayerEndpointUrl = "https://spectator.ppy.sh/multiplayer";
MetadataEndpointUrl = "https://spectator.ppy.sh/metadata";
SpectatorUrl = "https://spectator.ppy.sh/spectator";
MultiplayerUrl = "https://spectator.ppy.sh/multiplayer";
MetadataUrl = "https://spectator.ppy.sh/metadata";
}
}
}

View File

@ -24,7 +24,7 @@ namespace osu.Game.Online.Spectator
public OnlineSpectatorClient(EndpointConfiguration endpoints)
{
endpoint = endpoints.SpectatorEndpointUrl;
endpoint = endpoints.SpectatorUrl;
}
[BackgroundDependencyLoader]

View File

@ -295,7 +295,7 @@ namespace osu.Game
EndpointConfiguration endpoints = CreateEndpoints();
MessageFormatter.WebsiteRootUrl = endpoints.WebsiteRootUrl;
MessageFormatter.WebsiteRootUrl = endpoints.WebsiteUrl;
frameworkLocale = frameworkConfig.GetBindable<string>(FrameworkSetting.Locale);
frameworkLocale.BindValueChanged(_ => updateLanguage());

View File

@ -419,7 +419,7 @@ namespace osu.Game.Overlays.Comments
private void copyUrl()
{
clipboard.SetText($@"{api.APIEndpointUrl}/comments/{Comment.Id}");
clipboard.SetText($@"{api.Endpoints.APIUrl}/comments/{Comment.Id}");
onScreenDisplay?.Display(new CopyUrlToast());
}

View File

@ -129,7 +129,7 @@ namespace osu.Game.Overlays.Login
}
};
forgottenPasswordLink.AddLink(LayoutStrings.PopupLoginLoginForgot, $"{api.WebsiteRootUrl}/home/password-reset");
forgottenPasswordLink.AddLink(LayoutStrings.PopupLoginLoginForgot, $"{api.Endpoints.WebsiteUrl}/home/password-reset");
password.OnCommit += (_, _) => performLogin();

View File

@ -98,7 +98,7 @@ namespace osu.Game.Overlays.Login
explainText.AddParagraph(UserVerificationStrings.BoxInfoCheckSpam);
// We can't support localisable strings with nested links yet. Not sure if we even can (probably need to allow markdown link formatting or something).
explainText.AddParagraph("If you can't access your email or have forgotten what you used, please follow the ");
explainText.AddLink(UserVerificationStrings.BoxInfoRecoverLink, $"{api.WebsiteRootUrl}/home/password-reset");
explainText.AddLink(UserVerificationStrings.BoxInfoRecoverLink, $"{api.Endpoints.WebsiteUrl}/home/password-reset");
explainText.AddText(". You can also ");
explainText.AddLink(UserVerificationStrings.BoxInfoReissueLink, () =>
{

View File

@ -124,12 +124,12 @@ namespace osu.Game.Overlays.Profile.Header
}
topLinkContainer.AddText("Contributed ");
topLinkContainer.AddLink("forum post".ToQuantity(user.PostCount, "#,##0"), $"{api.WebsiteRootUrl}/users/{user.Id}/posts", creationParameters: embolden);
topLinkContainer.AddLink("forum post".ToQuantity(user.PostCount, "#,##0"), $"{api.Endpoints.WebsiteUrl}/users/{user.Id}/posts", creationParameters: embolden);
addSpacer(topLinkContainer);
topLinkContainer.AddText("Posted ");
topLinkContainer.AddLink("comment".ToQuantity(user.CommentsCount, "#,##0"), $"{api.WebsiteRootUrl}/comments?user_id={user.Id}", creationParameters: embolden);
topLinkContainer.AddLink("comment".ToQuantity(user.CommentsCount, "#,##0"), $"{api.Endpoints.WebsiteUrl}/comments?user_id={user.Id}", creationParameters: embolden);
string websiteWithoutProtocol = user.Website;

View File

@ -33,7 +33,7 @@ namespace osu.Game.Overlays.Profile.Header.Components
Texture = textures.Get(banner.Image),
};
Action = () => game?.OpenUrlExternally($@"{api.WebsiteRootUrl}/community/tournaments/{banner.TournamentId}");
Action = () => game?.OpenUrlExternally($@"{api.Endpoints.WebsiteUrl}/community/tournaments/{banner.TournamentId}");
}
protected override void LoadComplete()

View File

@ -213,7 +213,7 @@ namespace osu.Game.Overlays.Profile.Header
cover.User = user;
avatar.User = user;
usernameText.Text = user?.Username ?? string.Empty;
openUserExternally.Link = $@"{api.WebsiteRootUrl}/users/{user?.Id ?? 0}";
openUserExternally.Link = $@"{api.Endpoints.WebsiteUrl}/users/{user?.Id ?? 0}";
userFlag.CountryCode = user?.CountryCode ?? default;
userCountryText.Text = (user?.CountryCode ?? default).GetDescription();
userCountryContainer.Action = () => rankingsOverlay?.ShowCountry(user?.CountryCode ?? default);

View File

@ -223,7 +223,7 @@ namespace osu.Game.Overlays.Profile.Sections.Recent
private void addBeatmapsetLink()
=> content.AddLink(activity.Beatmapset.AsNonNull().Title, LinkAction.OpenBeatmapSet, getLinkArgument(activity.Beatmapset.AsNonNull().Url), creationParameters: t => t.Font = getLinkFont());
private object getLinkArgument(string url) => MessageFormatter.GetLinkDetails($"{api.WebsiteRootUrl}{url}").Argument.AsNonNull();
private object getLinkArgument(string url) => MessageFormatter.GetLinkDetails($"{api.Endpoints.WebsiteUrl}{url}").Argument.AsNonNull();
private FontUsage getLinkFont(FontWeight fontWeight = FontWeight.Regular)
=> OsuFont.GetFont(size: font_size, weight: fontWeight, italics: true);

View File

@ -54,7 +54,7 @@ namespace osu.Game.Overlays.Wiki
Padding = new MarginPadding(padding),
Child = new WikiPanelMarkdownContainer(isFullWidth)
{
CurrentPath = $@"{api.WebsiteRootUrl}/wiki/",
CurrentPath = $@"{api.Endpoints.WebsiteUrl}/wiki/",
Text = text,
RelativeSizeAxes = Axes.X,
AutoSizeAxes = Axes.Y

View File

@ -167,7 +167,7 @@ namespace osu.Game.Overlays
}
else
{
LoadDisplay(articlePage = new WikiArticlePage($@"{api.WebsiteRootUrl}/wiki/{path.Value}/", response.Markdown));
LoadDisplay(articlePage = new WikiArticlePage($@"{api.Endpoints.WebsiteUrl}/wiki/{path.Value}/", response.Markdown));
}
}
@ -176,7 +176,7 @@ namespace osu.Game.Overlays
wikiData.Value = null;
path.Value = "error";
LoadDisplay(articlePage = new WikiArticlePage($@"{api.WebsiteRootUrl}/wiki/",
LoadDisplay(articlePage = new WikiArticlePage($@"{api.Endpoints.WebsiteUrl}/wiki/",
$"Something went wrong when trying to fetch page \"{originalPath}\".\n\n[Return to the main page]({INDEX_PATH})."));
}

View File

@ -46,14 +46,14 @@ namespace osu.Game.Screens.Edit.Submission
RelativeSizeAxes = Axes.X,
Caption = BeatmapSubmissionStrings.MappingHelpForumDescription,
ButtonText = BeatmapSubmissionStrings.MappingHelpForum,
Action = () => game?.OpenUrlExternally($@"{api.WebsiteRootUrl}/community/forums/56"),
Action = () => game?.OpenUrlExternally($@"{api.Endpoints.WebsiteUrl}/community/forums/56"),
},
new FormButton
{
RelativeSizeAxes = Axes.X,
Caption = BeatmapSubmissionStrings.ModdingQueuesForumDescription,
ButtonText = BeatmapSubmissionStrings.ModdingQueuesForum,
Action = () => game?.OpenUrlExternally($@"{api.WebsiteRootUrl}/community/forums/60"),
Action = () => game?.OpenUrlExternally($@"{api.Endpoints.WebsiteUrl}/community/forums/60"),
},
},
});

View File

@ -361,7 +361,7 @@ namespace osu.Game.Screens.OnlinePlay.Lounge.Components
return items.ToArray();
string formatRoomUrl(long id) => $@"{api.WebsiteRootUrl}/multiplayer/rooms/{id}";
string formatRoomUrl(long id) => $@"{api.Endpoints.WebsiteUrl}/multiplayer/rooms/{id}";
}
}

View File

@ -778,7 +778,7 @@ namespace osu.Game.Screens.SelectV2.Leaderboards
items.Add(new OsuMenuItem("Use these mods", MenuItemType.Highlighted, () => SelectedMods.Value = score.Mods.Where(m => IsValidMod.Invoke(m)).ToArray()));
if (score.OnlineID > 0)
items.Add(new OsuMenuItem(CommonStrings.CopyLink, MenuItemType.Standard, () => clipboard?.SetText($@"{api.WebsiteRootUrl}/scores/{score.OnlineID}")));
items.Add(new OsuMenuItem(CommonStrings.CopyLink, MenuItemType.Standard, () => clipboard?.SetText($@"{api.Endpoints.WebsiteUrl}/scores/{score.OnlineID}")));
if (score.Files.Count <= 0) return items.ToArray();

View File

@ -41,7 +41,7 @@ namespace osu.Game.Utils
{
this.game = game;
if (!game.IsDeployedBuild || !game.CreateEndpoints().WebsiteRootUrl.EndsWith(@".ppy.sh", StringComparison.Ordinal))
if (!game.IsDeployedBuild || !game.CreateEndpoints().WebsiteUrl.EndsWith(@".ppy.sh", StringComparison.Ordinal))
return;
sentrySession = SentrySdk.Init(options =>