@@ -85,22 +85,24 @@ public class BotDetectorClient
85
85
private static final String API_VERSION_FALLBACK_WORD = "latest" ;
86
86
private static final HttpUrl BASE_HTTP_URL = HttpUrl .parse (
87
87
System .getProperty ("BotDetectorAPIPath" , "https://api.prd.osrsbotdetector.com" ));
88
+ private static final HttpUrl BASE_HTTP_URL_V2 = HttpUrl .parse (
89
+ System .getProperty ("BotDetectorAPIPathV2" , "https://api-v2.prd.osrsbotdetector.com" ));
88
90
private static final Supplier <String > CURRENT_EPOCH_SUPPLIER = () -> String .valueOf (Instant .now ().getEpochSecond ());
89
91
90
92
@ Getter
91
93
@ AllArgsConstructor
92
94
private enum ApiPath
93
95
{
94
- DETECTION ("v1/report" ),
95
- PLAYER_STATS_PASSIVE ("v1/report/count" ),
96
- PLAYER_STATS_MANUAL ("v1/report/manual/count" ),
97
- PLAYER_STATS_FEEDBACK ("v1/feedback/count" ),
98
- PREDICTION ("v1/prediction" ),
99
- FEEDBACK ("v1/feedback/" ),
100
- VERIFY_DISCORD ("site/discord_user/" )
96
+ DETECTION ("v2/report" , true ),
97
+ PLAYER_STATS_REPORTS ("v2/player/report/score" , true ),
98
+ PLAYER_STATS_FEEDBACK ("v2/player/feedback/score" , true ),
99
+ PREDICTION ("v2/player/prediction" , true ),
100
+ FEEDBACK ("v1/feedback/" , false ),
101
+ VERIFY_DISCORD ("site/discord_user/" , false )
101
102
;
102
103
103
104
final String path ;
105
+ final boolean v2 ;
104
106
}
105
107
106
108
public OkHttpClient okHttpClient ;
@@ -123,7 +125,7 @@ private enum ApiPath
123
125
*/
124
126
private HttpUrl getUrl (ApiPath path , boolean addVersion )
125
127
{
126
- HttpUrl .Builder builder = BASE_HTTP_URL .newBuilder ();
128
+ HttpUrl .Builder builder = ( path . isV2 () ? BASE_HTTP_URL_V2 : BASE_HTTP_URL ) .newBuilder ();
127
129
128
130
if (addVersion )
129
131
{
@@ -398,7 +400,15 @@ public void onResponse(Call call, Response response)
398
400
{
399
401
try
400
402
{
401
- future .complete (processResponse (gson , response , Prediction .class ));
403
+ Collection <Prediction > preds = processResponse (gson , response , new TypeToken <Collection <Prediction >>()
404
+ {
405
+ }.getType ());
406
+ if (preds != null )
407
+ {
408
+ future .complete (preds .stream ().findFirst ().orElse (null ));
409
+ return ;
410
+ }
411
+ future .complete (null );
402
412
}
403
413
catch (IOException e )
404
414
{
@@ -422,18 +432,8 @@ public void onResponse(Call call, Response response)
422
432
*/
423
433
public CompletableFuture <Map <PlayerStatsType , PlayerStats >> requestPlayerStats (String playerName )
424
434
{
425
- Gson bdGson = gson .newBuilder ()
426
- .registerTypeAdapter (boolean .class , new BooleanToZeroOneConverter ())
427
- .create ();
428
-
429
- Request requestP = new Request .Builder ()
430
- .url (getUrl (ApiPath .PLAYER_STATS_PASSIVE ).newBuilder ()
431
- .addQueryParameter ("name" , playerName )
432
- .build ())
433
- .build ();
434
-
435
- Request requestM = new Request .Builder ()
436
- .url (getUrl (ApiPath .PLAYER_STATS_MANUAL ).newBuilder ()
435
+ Request requestR = new Request .Builder ()
436
+ .url (getUrl (ApiPath .PLAYER_STATS_REPORTS ).newBuilder ()
437
437
.addQueryParameter ("name" , playerName )
438
438
.build ())
439
439
.build ();
@@ -444,18 +444,16 @@ public CompletableFuture<Map<PlayerStatsType, PlayerStats>> requestPlayerStats(S
444
444
.build ())
445
445
.build ();
446
446
447
- CompletableFuture <Collection <PlayerStatsAPIItem >> passiveFuture = new CompletableFuture <>();
448
- CompletableFuture <Collection <PlayerStatsAPIItem >> manualFuture = new CompletableFuture <>();
447
+ CompletableFuture <Collection <PlayerStatsAPIItem >> reportsFuture = new CompletableFuture <>();
449
448
CompletableFuture <Collection <PlayerStatsAPIItem >> feedbackFuture = new CompletableFuture <>();
450
449
451
- okHttpClient .newCall (requestP ).enqueue (new PlayerStatsCallback (passiveFuture , bdGson ));
452
- okHttpClient .newCall (requestM ).enqueue (new PlayerStatsCallback (manualFuture , bdGson ));
453
- okHttpClient .newCall (requestF ).enqueue (new PlayerStatsCallback (feedbackFuture , bdGson ));
450
+ okHttpClient .newCall (requestR ).enqueue (new PlayerStatsCallback (reportsFuture , gson ));
451
+ okHttpClient .newCall (requestF ).enqueue (new PlayerStatsCallback (feedbackFuture , gson ));
454
452
455
453
CompletableFuture <Map <PlayerStatsType , PlayerStats >> finalFuture = new CompletableFuture <>();
456
454
457
- // Doing this so we log only the first future failing, not all 3 within the callback.
458
- CompletableFuture .allOf (passiveFuture , manualFuture , feedbackFuture ).whenComplete ((v , e ) ->
455
+ // Doing this so we log only the first future failing, not all 2 within the callback.
456
+ CompletableFuture .allOf (reportsFuture , feedbackFuture ).whenComplete ((v , e ) ->
459
457
{
460
458
if (e != null )
461
459
{
@@ -465,8 +463,7 @@ public CompletableFuture<Map<PlayerStatsType, PlayerStats>> requestPlayerStats(S
465
463
}
466
464
else
467
465
{
468
- finalFuture .complete (processPlayerStats (
469
- passiveFuture .join (), manualFuture .join (), feedbackFuture .join ()));
466
+ finalFuture .complete (processPlayerStats (reportsFuture .join (), feedbackFuture .join ()));
470
467
}
471
468
});
472
469
@@ -592,20 +589,21 @@ private IOException getIOException(Response response)
592
589
593
590
/**
594
591
* Collects the given {@link PlayerStatsAPIItem} into a combined map that the plugin expects.
595
- * @param passive The passive usage stats from the API.
596
- * @param manual The manual flagging stats from the API.
592
+ * @param reports The reports usage stats from the API.
597
593
* @param feedback The feedback stats from the API.
598
594
* @return The combined processed map expected by the plugin.
599
595
*/
600
- private Map <PlayerStatsType , PlayerStats > processPlayerStats (Collection <PlayerStatsAPIItem > passive , Collection < PlayerStatsAPIItem > manual , Collection <PlayerStatsAPIItem > feedback )
596
+ private Map <PlayerStatsType , PlayerStats > processPlayerStats (Collection <PlayerStatsAPIItem > reports , Collection <PlayerStatsAPIItem > feedback )
601
597
{
602
- if (passive == null || manual == null || feedback == null )
598
+ if (reports == null || feedback == null )
603
599
{
604
600
return null ;
605
601
}
606
602
607
- PlayerStats passiveStats = countStats (passive , false );
608
- PlayerStats manualStats = countStats (manual , true );
603
+ PlayerStats passiveStats = countStats (reports .stream ().filter (
604
+ r -> r .getManual () != null && !r .getManual ()).collect (Collectors .toList ()), false );
605
+ PlayerStats manualStats = countStats (reports .stream ().filter (
606
+ r -> r .getManual () != null && r .getManual ()).collect (Collectors .toList ()), true );
609
607
PlayerStats feedbackStats = countStats (feedback , false );
610
608
611
609
PlayerStats totalStats = PlayerStats .builder ()
@@ -623,7 +621,7 @@ private Map<PlayerStatsType, PlayerStats> processPlayerStats(Collection<PlayerSt
623
621
}
624
622
625
623
/**
626
- * Utility function for {@link BotDetectorClient#processPlayerStats(Collection, Collection, Collection )}.
624
+ * Utility function for {@link BotDetectorClient#processPlayerStats(Collection, Collection)}.
627
625
* Compile each element from the API into a {@link PlayerStats} object.
628
626
* @param fromAPI The returned collections of player stats from the API to accumulate.
629
627
* @param countIncorrect Intended for manual flagging stats. If true, count confirmed players into {@link PlayerStats#getIncorrectFlags()}.
@@ -711,7 +709,16 @@ private static class PlayerStatsAPIItem
711
709
boolean banned ;
712
710
@ SerializedName ("confirmed_player" )
713
711
boolean player ;
712
+ /**
713
+ * Will be Null for feedbacks
714
+ */
715
+ @ SerializedName ("manual_detect" )
716
+ Boolean manual ;
714
717
long count ;
718
+ /**
719
+ * Will be Null for report counts
720
+ */
721
+ Long vote ;
715
722
}
716
723
717
724
/**
0 commit comments