Skip to content

Commit

Permalink
Change the way how (most) API request are done
Browse files Browse the repository at this point in the history
  • Loading branch information
flustix committed Oct 29, 2023
1 parent 2cc6812 commit 4987630
Show file tree
Hide file tree
Showing 18 changed files with 310 additions and 155 deletions.
1 change: 1 addition & 0 deletions fluXis.Game/FluXisGame.cs
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ private void load()
{
Children = new Drawable[]
{
Fluxel,
AudioClock,
Samples,
NotificationManager,
Expand Down
13 changes: 4 additions & 9 deletions fluXis.Game/Map/MapStore.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@
using fluXis.Game.Database.Maps;
using fluXis.Game.Graphics.Background;
using fluXis.Game.Graphics.Background.Cropped;
using fluXis.Game.Online.API;
using fluXis.Game.Online.API.Models.Maps;
using fluXis.Game.Online.API.Requests.Maps;
using fluXis.Game.Online.Fluxel;
using fluXis.Game.Overlay.Notifications;
using fluXis.Game.Overlay.Notifications.Types.Loading;
Expand Down Expand Up @@ -202,14 +202,9 @@ public string Export(RealmMapSet set, LoadingNotificationData notification, bool
[CanBeNull]
public APIMap LookUpHash(string hash)
{
var req = fluxel.CreateAPIRequest($"/map/hash/{hash}");
req.Perform();
var json = req.GetResponseString();
if (json == null) return null;

var map = JsonConvert.DeserializeObject<APIResponse<APIMap>>(json);

return map.Status != 200 ? null : map.Data;
var req = new MapHashLookupRequest(hash);
req.Perform(fluxel);
return req.Response.Status != 200 ? null : req.Response.Data;
}

public RealmMap CreateNew()
Expand Down
57 changes: 57 additions & 0 deletions fluXis.Game/Online/API/APIRequest.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
using System;
using System.Net.Http;
using System.Threading.Tasks;
using osu.Framework.IO.Network;

namespace fluXis.Game.Online.API;

public class APIRequest<T> where T : class
{
protected virtual string Path => string.Empty;
protected virtual HttpMethod Method => HttpMethod.Get;

public event Action<APIResponse<T>> Success;
public event Action<Exception> Failure;
public event Action<long, long> Progress;

public APIResponse<T> Response { get; private set; }

private Fluxel.Fluxel fluxel;
private APIEndpointConfig config => fluxel.Endpoint;

public void Perform(Fluxel.Fluxel fluxel)
{
this.fluxel = fluxel;

var request = new JsonWebRequest<APIResponse<T>>($"{config.APIUrl}{Path}", Method);
request.AllowInsecureRequests = true;
request.UploadProgress += (current, total) => Progress?.Invoke(current, total);

if (!string.IsNullOrEmpty(fluxel.Token))
request.AddHeader("Authorization", fluxel.Token);

try
{
CreatePostData(request);
request.Perform();
Response = request.ResponseObject;
}
catch (Exception e)
{
Response = new APIResponse<T>(400, e.Message, null);
Failure?.Invoke(e);
}

if (Response != null)
fluxel.Schedule(() => Success?.Invoke(Response));
}

public Task PerformAsync(Fluxel.Fluxel fluxel)
{
var task = new Task(() => Perform(fluxel));
task.Start();
return task;
}

protected virtual void CreatePostData(JsonWebRequest<APIResponse<T>> request) { }
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
using System.Net.Http;
using osu.Framework.IO.Network;

namespace fluXis.Game.Online.API.Requests.Account;

public class DisplayNameUpdateRequest : APIRequest<dynamic>
{
protected override string Path => "/account/update/displayname";
protected override HttpMethod Method => HttpMethod.Post;

private string displayName { get; }

public DisplayNameUpdateRequest(string displayName)
{
this.displayName = displayName;
}

protected override void CreatePostData(JsonWebRequest<APIResponse<dynamic>> request)
{
request.AddRaw(displayName);
}
}
36 changes: 36 additions & 0 deletions fluXis.Game/Online/API/Requests/Account/SocialUpdateRequest.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
using System.Collections.Generic;
using System.Net.Http;
using Newtonsoft.Json;
using osu.Framework.IO.Network;

namespace fluXis.Game.Online.API.Requests.Account;

public class SocialUpdateRequest : APIRequest<dynamic>
{
protected override string Path => "/account/update/socials";
protected override HttpMethod Method => HttpMethod.Post;

private string twitter { get; }
private string youtube { get; }
private string twitch { get; }
private string discord { get; }

public SocialUpdateRequest(string twitter, string youtube, string twitch, string discord)
{
this.twitter = twitter;
this.youtube = youtube;
this.twitch = twitch;
this.discord = discord;
}

protected override void CreatePostData(JsonWebRequest<APIResponse<dynamic>> request)
{
request.AddRaw(JsonConvert.SerializeObject(new Dictionary<string, string>
{
{ "twitter", twitter },
{ "youtube", youtube },
{ "twitch", twitch },
{ "discord", discord }
}));
}
}
9 changes: 9 additions & 0 deletions fluXis.Game/Online/API/Requests/MapSets/MapSetsRequest.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
using System.Collections.Generic;
using fluXis.Game.Online.API.Models.Maps;

namespace fluXis.Game.Online.API.Requests.MapSets;

public class MapSetsRequest : APIRequest<List<APIMapSet>>
{
protected override string Path => "/mapsets";
}
15 changes: 15 additions & 0 deletions fluXis.Game/Online/API/Requests/Maps/MapHashLookupRequest.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
using fluXis.Game.Online.API.Models.Maps;

namespace fluXis.Game.Online.API.Requests.Maps;

public class MapHashLookupRequest : APIRequest<APIMap>
{
protected override string Path => $"/map/hash/{hash}";

private string hash { get; }

public MapHashLookupRequest(string hash)
{
this.hash = hash;
}
}
26 changes: 26 additions & 0 deletions fluXis.Game/Online/API/Requests/Maps/MapLeaderboardRequest.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
using System;
using fluXis.Game.Online.API.Models.Scores;
using fluXis.Game.Screens.Select.Info.Scores;

namespace fluXis.Game.Online.API.Requests.Maps;

public class MapLeaderboardRequest : APIRequest<APIScores>
{
protected override string Path => type switch
{
ScoreListType.Global => $"/map/{id}/scores",
ScoreListType.Country => $"/map/{id}/scores/country",
ScoreListType.Friends => $"/map/{id}/scores/friends",
ScoreListType.Club => $"/map/{id}/scores/club",
_ => throw new ArgumentOutOfRangeException()
};

private ScoreListType type { get; }
private int id { get; }

public MapLeaderboardRequest(ScoreListType type, int id)
{
this.type = type;
this.id = id;
}
}
26 changes: 26 additions & 0 deletions fluXis.Game/Online/API/Requests/Maps/MapSetUploadRequest.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
using System.Net.Http;
using fluXis.Game.Database.Maps;
using fluXis.Game.Online.API.Models.Maps;
using osu.Framework.IO.Network;

namespace fluXis.Game.Online.API.Requests.Maps;

public class MapSetUploadRequest : APIRequest<APIMapSet>
{
protected override string Path => map.OnlineID != -1 ? $"/map/{map.OnlineID}/update" : "/maps";
protected override HttpMethod Method => HttpMethod.Post;

private byte[] file { get; }
private RealmMapSet map { get; }

public MapSetUploadRequest(byte[] file, RealmMapSet map)
{
this.file = file;
this.map = map;
}

protected override void CreatePostData(JsonWebRequest<APIResponse<APIMapSet>> request)
{
request.AddFile("file", file);
}
}
39 changes: 39 additions & 0 deletions fluXis.Game/Online/API/Requests/Scores/ScoreSubmitRequest.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
using System.Net.Http;
using fluXis.Game.Online.API.Models.Scores;
using fluXis.Game.Scoring;
using Newtonsoft.Json;
using osu.Framework.IO.Network;

namespace fluXis.Game.Online.API.Requests.Scores;

public class ScoreSubmitRequest : APIRequest<APIScoreResponse>
{
protected override string Path => "/scores/upload";
protected override HttpMethod Method => HttpMethod.Post;

private ScoreInfo score { get; }
private float scrollspeed { get; }

public ScoreSubmitRequest(ScoreInfo score, float scrollspeed)
{
this.score = score;
this.scrollspeed = scrollspeed;
}

protected override void CreatePostData(JsonWebRequest<APIResponse<APIScoreResponse>> request)
{
request.AddRaw(JsonConvert.SerializeObject(new
{
hash = score.MapHash,
mods = score.Mods,
scrollSpeed = scrollspeed,
maxCombo = score.MaxCombo,
flawless = score.Flawless,
perfect = score.Perfect,
great = score.Great,
alright = score.Alright,
okay = score.Okay,
miss = score.Miss
}));
}
}
8 changes: 8 additions & 0 deletions fluXis.Game/Online/API/Requests/Users/OnlineUsersRequest.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
using fluXis.Game.Online.API.Models.Users;

namespace fluXis.Game.Online.API.Requests.Users;

public class OnlineUsersRequest : APIRequest<APIOnlineUsers>
{
protected override string Path => "/users/online";
}
2 changes: 2 additions & 0 deletions fluXis.Game/Online/Fluxel/Fluxel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -355,6 +355,8 @@ public WebRequest CreateAPIRequest(string url, HttpMethod method = null)
return request;
}

internal new void Schedule(Action action) => base.Schedule(action);

private void onAuthResponse(FluxelResponse<string> response)
{
if (response.Status == 200)
Expand Down
27 changes: 5 additions & 22 deletions fluXis.Game/Online/Scores/OnlineScores.cs
Original file line number Diff line number Diff line change
@@ -1,11 +1,10 @@
using System;
using System.Linq;
using System.Net.Http;
using fluXis.Game.Configuration;
using fluXis.Game.Online.API;
using fluXis.Game.Online.API.Models.Scores;
using fluXis.Game.Online.API.Requests.Scores;
using fluXis.Game.Scoring;
using Newtonsoft.Json;

namespace fluXis.Game.Online.Scores;

Expand All @@ -15,7 +14,7 @@ public static async void UploadScore(Fluxel.Fluxel fluxel, ScoreInfo score, Acti
{
if (fluxel.Token == null)
{
callback(new APIResponse<APIScoreResponse>(401, "No token", null));
callback(new APIResponse<APIScoreResponse>(401, "Not logged in.", null));
return;
}

Expand All @@ -25,24 +24,8 @@ public static async void UploadScore(Fluxel.Fluxel fluxel, ScoreInfo score, Acti
return;
}

var submitScore = new
{
hash = score.MapHash,
mods = score.Mods,
scrollSpeed = fluxel.Config.Get<float>(FluXisSetting.ScrollSpeed),
maxCombo = score.MaxCombo,
flawless = score.Flawless,
perfect = score.Perfect,
great = score.Great,
alright = score.Alright,
okay = score.Okay,
miss = score.Miss
};

var req = fluxel.CreateAPIRequest("/scores/upload", HttpMethod.Post);
req.AddRaw(JsonConvert.SerializeObject(submitScore));
await req.PerformAsync();

callback(JsonConvert.DeserializeObject<APIResponse<APIScoreResponse>>(req.GetResponseString()));
var req = new ScoreSubmitRequest(score, fluxel.Config.Get<float>(FluXisSetting.ScrollSpeed));
await req.PerformAsync(fluxel);
callback(req.Response);
}
}
Loading

0 comments on commit 4987630

Please sign in to comment.