Skip to content

Commit

Permalink
Implement favourite users and levels on PSP (#190)
Browse files Browse the repository at this point in the history
  • Loading branch information
jvyden authored Oct 3, 2023
2 parents ae8094e + 66b18bb commit c8f77b4
Show file tree
Hide file tree
Showing 5 changed files with 77 additions and 23 deletions.
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
using System.Xml.Serialization;
using Refresh.GameServer.Authentication;
using Refresh.GameServer.Database;
using Refresh.GameServer.Endpoints.ApiV3.DataTypes;
using Refresh.GameServer.Types;
using Refresh.GameServer.Types.Levels;
using Refresh.GameServer.Types.Lists;
using Refresh.GameServer.Types.UserData;

namespace Refresh.GameServer.Endpoints.Game.DataTypes.Response;
Expand Down Expand Up @@ -39,12 +42,21 @@ public class GameUserResponse : IDataConvertableFrom<GameUserResponse, GameUser>
[XmlElement("lbp2PurchasedSlots")] public int PurchasedSlotsLBP2 { get; set; }
[XmlElement("lbp3PurchasedSlots")] public int PurchasedSlotsLBP3 { get; set; }

public static GameUserResponse? FromOldWithExtraData(GameUser? old, TokenGame gameVersion)
/// <summary>
/// The levels the user has favourited, only used by LBP PSP
/// </summary>
[XmlElement("favouriteSlots")] public SerializedMinimalFavouriteLevelList? FavouriteLevels { get; set; }
/// <summary>
/// The users the user has favourited, only used by LBP PSP
/// </summary>
[XmlElement("favouriteUsers")] public SerializedMinimalFavouriteUserList? FavouriteUsers { get; set; }

public static GameUserResponse? FromOldWithExtraData(GameUser? old, TokenGame gameVersion, GameDatabaseContext database)
{
if (old == null) return null;

GameUserResponse response = FromOld(old)!;
response.FillInExtraData(old, gameVersion);
response.FillInExtraData(old, gameVersion, database);

return response;
}
Expand Down Expand Up @@ -85,10 +97,10 @@ public class GameUserResponse : IDataConvertableFrom<GameUserResponse, GameUser>

public static IEnumerable<GameUserResponse> FromOldList(IEnumerable<GameUser> oldList) => oldList.Select(FromOld)!;

public static IEnumerable<GameUserResponse> FromOldListWithExtraData(IEnumerable<GameUser> oldList, TokenGame gameVersion)
=> oldList.Select(old => FromOldWithExtraData(old, gameVersion))!;
public static IEnumerable<GameUserResponse> FromOldListWithExtraData(IEnumerable<GameUser> oldList, TokenGame gameVersion, GameDatabaseContext database)
=> oldList.Select(old => FromOldWithExtraData(old, gameVersion, database))!;

private void FillInExtraData(GameUser old, TokenGame gameVersion)
private void FillInExtraData(GameUser old, TokenGame gameVersion, GameDatabaseContext database)
{
this.PlanetsHash = gameVersion switch
{
Expand Down Expand Up @@ -141,10 +153,18 @@ private void FillInExtraData(GameUser old, TokenGame gameVersion)
throw new ArgumentOutOfRangeException(nameof(gameVersion), gameVersion, null);
}

// Apply PSP-specific icon hashes
if (gameVersion == TokenGame.LittleBigPlanetPSP)
{
// Apply PSP-specific icon hashes
this.IconHash = old.PspIconHash;

//Fill out PSP favourite users
List<GameUser> users = database.GetUsersFavouritedByUser(old, 20, 0).ToList();
this.FavouriteUsers = new SerializedMinimalFavouriteUserList(users.Select(SerializedUserHandle.FromUser).ToList(), users.Count);

//Fill out PSP favourite levels
List<GameMinimalLevelResponse> favouriteLevels = old.FavouriteLevelRelations.Select(f => GameMinimalLevelResponse.FromOld(f.Level)).ToList()!;
this.FavouriteLevels = new SerializedMinimalFavouriteLevelList(new SerializedMinimalLevelList(favouriteLevels, favouriteLevels.Count));
}
}
}
6 changes: 5 additions & 1 deletion Refresh.GameServer/Endpoints/Game/Levels/LevelEndpoints.cs
Original file line number Diff line number Diff line change
Expand Up @@ -116,10 +116,14 @@ public SerializedMinimalLevelList GetLevelsFromCategory(RequestContext context,
=> this.GetLevels(context, database, categories, matchService, user, token, "newest");

[GameEndpoint("favouriteSlots/{username}", ContentType.Xml)]
[NullStatusCode(NotFound)]
[MinimumRole(GameUserRole.Restricted)]
public SerializedMinimalFavouriteLevelList? FavouriteLevels(RequestContext context, GameDatabaseContext database, CategoryService categories, MatchService matchService, Token token, string username)
{
SerializedMinimalLevelList? levels = this.GetLevels(context, database, categories, matchService, database.GetUserByUsername(username), token, "favouriteSlots");
GameUser? user = database.GetUserByUsername(username);
if (user == null) return null;

SerializedMinimalLevelList? levels = this.GetLevels(context, database, categories, matchService, user, token, "favouriteSlots");
if (levels == null) return null;

return new SerializedMinimalFavouriteLevelList(levels);
Expand Down
30 changes: 17 additions & 13 deletions Refresh.GameServer/Endpoints/Game/RelationEndpoints.cs
Original file line number Diff line number Diff line change
Expand Up @@ -20,55 +20,59 @@ public class RelationEndpoints : EndpointGroup
public Response FavouriteLevel(RequestContext context, GameDatabaseContext database, GameUser user, int id)
{
GameLevel? level = database.GetLevelById(id);
if (level == null) return NotFound;
// On PSP, we have to lie or else the client will begin spamming the server
// https://discord.com/channels/1049223665243389953/1049225857350254632/1153468991675838474
if (level == null) return context.IsPSP() ? OK : NotFound;

if (database.FavouriteLevel(level, user))
return OK;

// On PSP, we have to lie or else the client will begin spamming the server
// https://discord.com/channels/1049223665243389953/1049225857350254632/1153468991675838474
// See above comment about PSP
return context.IsPSP() ? OK : Unauthorized;
}

[GameEndpoint("unfavourite/slot/user/{id}", HttpMethods.Post)]
public Response UnfavouriteLevel(RequestContext context, GameDatabaseContext database, GameUser user, int id)
{
GameLevel? level = database.GetLevelById(id);
if (level == null) return NotFound;
// On PSP, we have to lie or else the client will begin spamming the server
// https://discord.com/channels/1049223665243389953/1049225857350254632/1153468991675838474
if (level == null) return context.IsPSP() ? OK : NotFound;

if (database.UnfavouriteLevel(level, user))
return OK;

// On PSP, we have to lie or else the client will begin spamming the server
// https://discord.com/channels/1049223665243389953/1049225857350254632/1153468991675838474
// See above comment about PSP
return context.IsPSP() ? OK : Unauthorized;
}

[GameEndpoint("favourite/user/{username}", HttpMethods.Post)]
public Response FavouriteUser(RequestContext context, GameDatabaseContext database, GameUser user, string username)
{
GameUser? userToFavourite = database.GetUserByUsername(username);
if (userToFavourite == null) return NotFound;
// On PSP, we have to lie or else the client will begin spamming the server
// https://discord.com/channels/1049223665243389953/1049225857350254632/1153468991675838474
if (userToFavourite == null) return context.IsPSP() ? OK : NotFound;

if (database.FavouriteUser(userToFavourite, user))
return OK;

// On PSP, we have to lie or else the client will begin spamming the server
// https://discord.com/channels/1049223665243389953/1049225857350254632/1153468991675838474
// See above comment about PSP
return context.IsPSP() ? OK : Unauthorized;
}

[GameEndpoint("unfavourite/user/{username}", HttpMethods.Post)]
public Response UnfavouriteUser(RequestContext context, GameDatabaseContext database, GameUser user, string username)
{
GameUser? userToFavourite = database.GetUserByUsername(username);
if (userToFavourite == null) return NotFound;
// On PSP, we have to lie or else the client will begin spamming the server
// https://discord.com/channels/1049223665243389953/1049225857350254632/1153468991675838474
if (userToFavourite == null) return context.IsPSP() ? OK : NotFound;

if (database.UnfavouriteUser(userToFavourite, user))
return OK;

// On PSP, we have to lie or else the client will begin spamming the server
// https://discord.com/channels/1049223665243389953/1049225857350254632/1153468991675838474
// See above comment about PSP
return context.IsPSP() ? OK : Unauthorized;
}

Expand All @@ -84,7 +88,7 @@ public Response UnfavouriteUser(RequestContext context, GameDatabaseContext data
List<GameUser> users = database.GetUsersFavouritedByUser(user, count, skip)
.ToList();

return new SerializedFavouriteUserList(GameUserResponse.FromOldListWithExtraData(users, token.TokenGame).ToList(), users.Count);
return new SerializedFavouriteUserList(GameUserResponse.FromOldListWithExtraData(users, token.TokenGame, database).ToList(), users.Count);
}

[GameEndpoint("lolcatftw/add/user/{id}", HttpMethods.Post)]
Expand Down
6 changes: 3 additions & 3 deletions Refresh.GameServer/Endpoints/Game/UserEndpoints.cs
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ public class UserEndpoints : EndpointGroup
[GameEndpoint("user/{name}", HttpMethods.Get, ContentType.Xml)]
[MinimumRole(GameUserRole.Restricted)]
public GameUserResponse? GetUser(RequestContext context, GameDatabaseContext database, string name, Token token)
=> GameUserResponse.FromOldWithExtraData(database.GetUserByUsername(name), token.TokenGame);
=> GameUserResponse.FromOldWithExtraData(database.GetUserByUsername(name), token.TokenGame, database);

[GameEndpoint("users", HttpMethods.Get, ContentType.Xml)]
[MinimumRole(GameUserRole.Restricted)]
Expand All @@ -35,7 +35,7 @@ public SerializedUserList GetMultipleUsers(RequestContext context, GameDatabaseC
GameUser? user = database.GetUserByUsername(username);
if (user == null) continue;

users.Add(GameUserResponse.FromOldWithExtraData(user, token.TokenGame)!);
users.Add(GameUserResponse.FromOldWithExtraData(user, token.TokenGame, database)!);
}

return new SerializedUserList
Expand All @@ -53,7 +53,7 @@ public SerializedUserList GetMultipleUsers(RequestContext context, GameDatabaseC
List<GameUser>? friends = friendService.GetUsersFriends(user, database)?.ToList();
if (friends == null) return null;

return new SerializedFriendsList(GameUserResponse.FromOldListWithExtraData(friends, token.TokenGame).ToList());
return new SerializedFriendsList(GameUserResponse.FromOldListWithExtraData(friends, token.TokenGame, database).ToList());
}

[GameEndpoint("updateUser", HttpMethods.Post, ContentType.Xml)]
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
using System.Xml.Serialization;
using Refresh.GameServer.Endpoints.Game.DataTypes.Response;
using Refresh.GameServer.Types.UserData;

namespace Refresh.GameServer.Types.Lists;

#nullable disable

/// <summary>
/// Minimal favourite user list, used only by LBP PSP, since it structures things a bit differently
/// </summary>
[XmlRoot("favouriteUsers")]
[XmlType("favouriteUsers")]
public class SerializedMinimalFavouriteUserList : SerializedList<SerializedUserHandle>
{
public SerializedMinimalFavouriteUserList() {}

public SerializedMinimalFavouriteUserList(List<SerializedUserHandle> list, int count)
{
this.Total = count;
this.Items = list;
}

[XmlElement("user")]
public override List<SerializedUserHandle> Items { get; set; }
}

0 comments on commit c8f77b4

Please sign in to comment.