Skip to content

Commit 3dbdda0

Browse files
committed
LBP1 photo spam, also remembered about LBP PSP
1 parent 84820c6 commit 3dbdda0

6 files changed

Lines changed: 35 additions & 26 deletions

File tree

Refresh.Core/RateLimits/Leaderboard/ScoreListEndpointLimits.cs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,9 @@ namespace Refresh.Core.RateLimits.Leaderboard;
33
public static class ScoreListEndpointLimits
44
{
55
public const int TimeoutDuration = 420;
6-
public const int RequestAmount = 90;
6+
public const int ApiRequestAmount = 70;
7+
public const int GameRequestAmount = 130; // apparently LBP PSP likes spamming story level leaderboards in certain cases
78
public const int BlockDuration = 300;
8-
public const string RequestBucket = "score-list";
9+
public const string ApiRequestBucket = "score-list-api";
10+
public const string GameRequestBucket = "score-list-game";
911
}

Refresh.Core/RateLimits/Photos/PhotoListEndpointLimits.cs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,9 @@ namespace Refresh.Core.RateLimits.Photos;
33
public static class PhotoListEndpointLimits
44
{
55
public const int TimeoutDuration = 300;
6-
public const int RequestAmount = 30;
6+
public const int ApiRequestAmount = 25;
7+
public const int GameRequestAmount = 60; // LBP1 likes spamming single level + photos for level requests for story levels
78
public const int BlockDuration = 240;
8-
public const string RequestBucket = "photo-list";
9+
public const string ApiRequestBucket = "photo-list-api";
10+
public const string GameRequestBucket = "photo-list-game";
911
}

Refresh.Interfaces.APIv3/Endpoints/LeaderboardApiEndpoints.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,8 +24,8 @@ public class LeaderboardApiEndpoints : EndpointGroup
2424
"If true, all scores will be shown no matter what. False by default.")]
2525
[DocError(typeof(ApiNotFoundError), ApiNotFoundError.LevelMissingErrorWhen)]
2626
[DocError(typeof(ApiValidationError), "The boolean 'showAll' could not be parsed by the server.")]
27-
[RateLimitSettings(ScoreListEndpointLimits.TimeoutDuration, ScoreListEndpointLimits.RequestAmount,
28-
ScoreListEndpointLimits.BlockDuration, ScoreListEndpointLimits.RequestBucket)]
27+
[RateLimitSettings(ScoreListEndpointLimits.TimeoutDuration, ScoreListEndpointLimits.ApiRequestAmount,
28+
ScoreListEndpointLimits.BlockDuration, ScoreListEndpointLimits.ApiRequestBucket)]
2929
public ApiListResponse<ApiGameScoreResponse> GetTopScoresForLevel(RequestContext context,
3030
GameDatabaseContext database, IDataStore dataStore,
3131
[DocSummary("The ID of the level")] int id,

Refresh.Interfaces.APIv3/Endpoints/PhotoApiEndpoints.cs

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,8 @@ public ApiResponse<ApiEmptyResponse> DeletePhoto(RequestContext context, GameDat
4040
[ApiV3Endpoint("photos/by/{userIdType}/{id}"), Authentication(false)]
4141
[DocUsesPageData, DocSummary("Gets photos uploaded by a user specified by their username or UUID")]
4242
[DocError(typeof(ApiNotFoundError), "The user cannot be found")]
43-
[RateLimitSettings(PhotoListEndpointLimits.TimeoutDuration, PhotoListEndpointLimits.RequestAmount, PhotoListEndpointLimits.BlockDuration, PhotoListEndpointLimits.RequestBucket)]
43+
[RateLimitSettings(PhotoListEndpointLimits.TimeoutDuration, PhotoListEndpointLimits.ApiRequestAmount,
44+
PhotoListEndpointLimits.BlockDuration, PhotoListEndpointLimits.ApiRequestBucket)]
4445
public ApiListResponse<ApiGamePhotoResponse> PhotosByUser(RequestContext context, GameDatabaseContext database,
4546
[DocSummary(SharedParamDescriptions.UserIdParam)] string id,
4647
[DocSummary(SharedParamDescriptions.UserIdTypeParam)] string userIdType, DataContext dataContext)
@@ -58,7 +59,8 @@ public ApiListResponse<ApiGamePhotoResponse> PhotosByUser(RequestContext context
5859
[ApiV3Endpoint("photos/with/{userIdType}/{id}"), Authentication(false)]
5960
[DocUsesPageData, DocSummary("Gets photos depicting a user specified by their username or UUID")]
6061
[DocError(typeof(ApiNotFoundError), "The user cannot be found")]
61-
[RateLimitSettings(PhotoListEndpointLimits.TimeoutDuration, PhotoListEndpointLimits.RequestAmount, PhotoListEndpointLimits.BlockDuration, PhotoListEndpointLimits.RequestBucket)]
62+
[RateLimitSettings(PhotoListEndpointLimits.TimeoutDuration, PhotoListEndpointLimits.ApiRequestAmount,
63+
PhotoListEndpointLimits.BlockDuration, PhotoListEndpointLimits.ApiRequestBucket)]
6264
public ApiListResponse<ApiGamePhotoResponse> PhotosWithUser(RequestContext context,
6365
GameDatabaseContext database, DataContext dataContext,
6466
[DocSummary(SharedParamDescriptions.UserIdParam)] string id,
@@ -77,7 +79,8 @@ public ApiListResponse<ApiGamePhotoResponse> PhotosWithUser(RequestContext conte
7779
[ApiV3Endpoint("levels/id/{id}/photos"), Authentication(false)]
7880
[DocUsesPageData, DocSummary("Gets photos taken in a level by its id")]
7981
[DocError(typeof(ApiNotFoundError), "The level cannot be found")]
80-
[RateLimitSettings(PhotoListEndpointLimits.TimeoutDuration, PhotoListEndpointLimits.RequestAmount, PhotoListEndpointLimits.BlockDuration, PhotoListEndpointLimits.RequestBucket)]
82+
[RateLimitSettings(PhotoListEndpointLimits.TimeoutDuration, PhotoListEndpointLimits.ApiRequestAmount,
83+
PhotoListEndpointLimits.BlockDuration, PhotoListEndpointLimits.ApiRequestBucket)]
8184
public ApiListResponse<ApiGamePhotoResponse> PhotosInLevelById(RequestContext context, GameDatabaseContext database,
8285
IDataStore dataStore,
8386
[DocSummary("The ID of the level")] int id, DataContext dataContext)
@@ -94,7 +97,8 @@ public ApiListResponse<ApiGamePhotoResponse> PhotosInLevelById(RequestContext co
9497

9598
[ApiV3Endpoint("photos"), Authentication(false)]
9699
[DocUsesPageData, DocSummary("Get all photos taken recently")]
97-
[RateLimitSettings(PhotoListEndpointLimits.TimeoutDuration, PhotoListEndpointLimits.RequestAmount, PhotoListEndpointLimits.BlockDuration, PhotoListEndpointLimits.RequestBucket)]
100+
[RateLimitSettings(PhotoListEndpointLimits.TimeoutDuration, PhotoListEndpointLimits.ApiRequestAmount,
101+
PhotoListEndpointLimits.BlockDuration, PhotoListEndpointLimits.ApiRequestBucket)]
98102
public ApiListResponse<ApiGamePhotoResponse> RecentPhotos(RequestContext context, GameDatabaseContext database,
99103
IDataStore dataStore, DataContext dataContext)
100104
{
@@ -108,7 +112,8 @@ public ApiListResponse<ApiGamePhotoResponse> RecentPhotos(RequestContext context
108112
[ApiV3Endpoint("photos/id/{id}"), Authentication(false)]
109113
[DocUsesPageData, DocSummary("Get an individual photo by the photo's id")]
110114
[DocError(typeof(ApiNotFoundError), "The photo cannot be found")]
111-
[RateLimitSettings(450, 20, 300, "single-photo-api")]
115+
[RateLimitSettings(SinglePhotoEndpointLimits.TimeoutDuration, SinglePhotoEndpointLimits.RequestAmount,
116+
SinglePhotoEndpointLimits.BlockDuration, SinglePhotoEndpointLimits.RequestBucket)]
112117
public ApiResponse<ApiGamePhotoResponse> PhotoById(RequestContext context, GameDatabaseContext database,
113118
IDataStore dataStore, [DocSummary("The ID of the photo")] int id, DataContext dataContext)
114119
{

Refresh.Interfaces.Game/Endpoints/Levels/LeaderboardEndpoints.cs

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ namespace Refresh.Interfaces.Game.Endpoints.Levels;
2525
public class LeaderboardEndpoints : EndpointGroup
2626
{
2727
private const int RequestTimeoutDuration = 300;
28-
private const int MaxScoreSubmissionAmount = 10;
28+
private const int MaxScoreSubmissionAmount = 20; // 10 should be enough normally, but LBP PSP exists...
2929
private const int RequestBlockDuration = 300;
3030
private const string ScoreSubmissionBucketName = "score-submission";
3131

@@ -66,8 +66,8 @@ public Response PlayLevel(RequestContext context, GameUser user, GameDatabaseCon
6666

6767
[GameEndpoint("scoreboard/{slotType}/{id}", HttpMethods.Get, ContentType.Xml)]
6868
[MinimumRole(GameUserRole.Restricted)]
69-
[RateLimitSettings(ScoreListEndpointLimits.TimeoutDuration, ScoreListEndpointLimits.RequestAmount,
70-
ScoreListEndpointLimits.BlockDuration, ScoreListEndpointLimits.RequestBucket)]
69+
[RateLimitSettings(ScoreListEndpointLimits.TimeoutDuration, ScoreListEndpointLimits.GameRequestAmount,
70+
ScoreListEndpointLimits.BlockDuration, ScoreListEndpointLimits.GameRequestBucket)]
7171
public Response GetUserScores(RequestContext context, GameUser user, GameDatabaseContext database, string slotType,
7272
int id, Token token, DataContext dataContext)
7373
{
@@ -82,8 +82,8 @@ public Response GetUserScores(RequestContext context, GameUser user, GameDatabas
8282

8383
[GameEndpoint("scoreboard/friends/{slotType}/{id}", HttpMethods.Post, ContentType.Xml)]
8484
[MinimumRole(GameUserRole.Restricted)]
85-
[RateLimitSettings(ScoreListEndpointLimits.TimeoutDuration, ScoreListEndpointLimits.RequestAmount,
86-
ScoreListEndpointLimits.BlockDuration, ScoreListEndpointLimits.RequestBucket)]
85+
[RateLimitSettings(ScoreListEndpointLimits.TimeoutDuration, ScoreListEndpointLimits.GameRequestAmount,
86+
ScoreListEndpointLimits.BlockDuration, ScoreListEndpointLimits.GameRequestBucket)]
8787
[NullStatusCode(NotFound)]
8888
public SerializedScoreLeaderboardList? GetLevelFriendLeaderboard(RequestContext context,
8989
GameUser user,
@@ -255,8 +255,8 @@ private void AwardScoreboardPins(DatabaseList<ScoreWithRank> scores, DataContext
255255
[GameEndpoint("topscores/{slotType}/{id}/{type}", ContentType.Xml)]
256256
[MinimumRole(GameUserRole.Restricted)]
257257
[NullStatusCode(NotFound)]
258-
[RateLimitSettings(ScoreListEndpointLimits.TimeoutDuration, ScoreListEndpointLimits.RequestAmount,
259-
ScoreListEndpointLimits.BlockDuration, ScoreListEndpointLimits.RequestBucket)]
258+
[RateLimitSettings(ScoreListEndpointLimits.TimeoutDuration, ScoreListEndpointLimits.GameRequestAmount,
259+
ScoreListEndpointLimits.BlockDuration, ScoreListEndpointLimits.GameRequestBucket)]
260260
public SerializedScoreList? GetTopScoresForLevel(RequestContext context, GameDatabaseContext database, string slotType, int id,
261261
int type, DataContext dataContext, GameUser user, IDateTimeProvider dateTimeProvider)
262262
{
@@ -273,8 +273,8 @@ private void AwardScoreboardPins(DatabaseList<ScoreWithRank> scores, DataContext
273273
[GameEndpoint("friendscores/{slotType}/{id}/{type}", ContentType.Xml)]
274274
[MinimumRole(GameUserRole.Restricted)]
275275
[NullStatusCode(NotFound)]
276-
[RateLimitSettings(ScoreListEndpointLimits.TimeoutDuration, ScoreListEndpointLimits.RequestAmount,
277-
ScoreListEndpointLimits.BlockDuration, ScoreListEndpointLimits.RequestBucket)]
276+
[RateLimitSettings(ScoreListEndpointLimits.TimeoutDuration, ScoreListEndpointLimits.GameRequestAmount,
277+
ScoreListEndpointLimits.BlockDuration, ScoreListEndpointLimits.GameRequestBucket)]
278278
public SerializedScoreList? GetFriendTopScoresForLevel(RequestContext context, GameDatabaseContext database, string slotType, int id,
279279
int type, DataContext dataContext, GameUser user, IDateTimeProvider dateTimeProvider)
280280
{

Refresh.Interfaces.Game/Endpoints/PhotoEndpoints.cs

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -101,23 +101,23 @@ private static Response GetPhotos(RequestContext context, GameDatabaseContext da
101101
[GameEndpoint("photos/with", ContentType.Xml)]
102102
[Authentication(false)]
103103
[MinimumRole(GameUserRole.Restricted)]
104-
[RateLimitSettings(PhotoListEndpointLimits.TimeoutDuration, PhotoListEndpointLimits.RequestAmount,
105-
PhotoListEndpointLimits.BlockDuration, PhotoListEndpointLimits.RequestBucket)]
104+
[RateLimitSettings(PhotoListEndpointLimits.TimeoutDuration, PhotoListEndpointLimits.GameRequestAmount,
105+
PhotoListEndpointLimits.BlockDuration, PhotoListEndpointLimits.GameRequestBucket)]
106106
public Response PhotosWithUser(RequestContext context, GameDatabaseContext database, DataContext dataContext)
107107
=> GetPhotos(context, database, dataContext, database.GetPhotosWithUser);
108108

109109
[GameEndpoint("photos/by", ContentType.Xml)]
110110
[Authentication(false)]
111111
[MinimumRole(GameUserRole.Restricted)]
112-
[RateLimitSettings(PhotoListEndpointLimits.TimeoutDuration, PhotoListEndpointLimits.RequestAmount,
113-
PhotoListEndpointLimits.BlockDuration, PhotoListEndpointLimits.RequestBucket)]
112+
[RateLimitSettings(PhotoListEndpointLimits.TimeoutDuration, PhotoListEndpointLimits.GameRequestAmount,
113+
PhotoListEndpointLimits.BlockDuration, PhotoListEndpointLimits.GameRequestBucket)]
114114
public Response PhotosByUser(RequestContext context, GameDatabaseContext database, DataContext dataContext)
115115
=> GetPhotos(context, database, dataContext, database.GetPhotosByUser);
116116

117117
[GameEndpoint("photos/{slotType}/{levelId}", ContentType.Xml)]
118118
[MinimumRole(GameUserRole.Restricted)]
119-
[RateLimitSettings(PhotoListEndpointLimits.TimeoutDuration, PhotoListEndpointLimits.RequestAmount,
120-
PhotoListEndpointLimits.BlockDuration, PhotoListEndpointLimits.RequestBucket)]
119+
[RateLimitSettings(PhotoListEndpointLimits.TimeoutDuration, PhotoListEndpointLimits.GameRequestAmount,
120+
PhotoListEndpointLimits.BlockDuration, PhotoListEndpointLimits.GameRequestBucket)]
121121
public SerializedPhotoList? GetPhotosOnLevel(RequestContext context, DataContext dataContext, string slotType, int levelId)
122122
{
123123
GameLevel? level = dataContext.Database.GetLevelByIdAndType(slotType, levelId);

0 commit comments

Comments
 (0)