Skip to content

API V2 changes #174

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Draft
wants to merge 4 commits into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
76 changes: 40 additions & 36 deletions src/main/java/com/botdetector/http/BotDetectorClient.java
Original file line number Diff line number Diff line change
Expand Up @@ -91,13 +91,12 @@ public class BotDetectorClient
@AllArgsConstructor
private enum ApiPath
{
DETECTION("v1/report"),
PLAYER_STATS_PASSIVE("v1/report/count"),
PLAYER_STATS_MANUAL("v1/report/manual/count"),
PLAYER_STATS_FEEDBACK("v1/feedback/count"),
PREDICTION("v1/prediction"),
FEEDBACK("v1/feedback/"),
VERIFY_DISCORD("site/discord_user/")
DETECTION("v2/report"),
PLAYER_STATS_REPORTS("v2/player/report/score"),
PLAYER_STATS_FEEDBACK("v2/player/feedback/score"),
PREDICTION("v2/player/prediction"),
FEEDBACK("v1/feedback/"), // Remove last forward slash when using v2!
VERIFY_DISCORD("site/discord_user")
;

final String path;
Expand Down Expand Up @@ -398,7 +397,15 @@ public void onResponse(Call call, Response response)
{
try
{
future.complete(processResponse(gson, response, Prediction.class));
Collection<Prediction> preds = processResponse(gson, response, new TypeToken<Collection<Prediction>>()
{
}.getType());
if (preds != null)
{
future.complete(preds.stream().findFirst().orElse(null));
return;
}
future.complete(null);
}
catch (IOException e)
{
Expand All @@ -422,18 +429,8 @@ public void onResponse(Call call, Response response)
*/
public CompletableFuture<Map<PlayerStatsType, PlayerStats>> requestPlayerStats(String playerName)
{
Gson bdGson = gson.newBuilder()
.registerTypeAdapter(boolean.class, new BooleanToZeroOneConverter())
.create();

Request requestP = new Request.Builder()
.url(getUrl(ApiPath.PLAYER_STATS_PASSIVE).newBuilder()
.addQueryParameter("name", playerName)
.build())
.build();

Request requestM = new Request.Builder()
.url(getUrl(ApiPath.PLAYER_STATS_MANUAL).newBuilder()
Request requestR = new Request.Builder()
.url(getUrl(ApiPath.PLAYER_STATS_REPORTS).newBuilder()
.addQueryParameter("name", playerName)
.build())
.build();
Expand All @@ -444,18 +441,16 @@ public CompletableFuture<Map<PlayerStatsType, PlayerStats>> requestPlayerStats(S
.build())
.build();

CompletableFuture<Collection<PlayerStatsAPIItem>> passiveFuture = new CompletableFuture<>();
CompletableFuture<Collection<PlayerStatsAPIItem>> manualFuture = new CompletableFuture<>();
CompletableFuture<Collection<PlayerStatsAPIItem>> reportsFuture = new CompletableFuture<>();
CompletableFuture<Collection<PlayerStatsAPIItem>> feedbackFuture = new CompletableFuture<>();

okHttpClient.newCall(requestP).enqueue(new PlayerStatsCallback(passiveFuture, bdGson));
okHttpClient.newCall(requestM).enqueue(new PlayerStatsCallback(manualFuture, bdGson));
okHttpClient.newCall(requestF).enqueue(new PlayerStatsCallback(feedbackFuture, bdGson));
okHttpClient.newCall(requestR).enqueue(new PlayerStatsCallback(reportsFuture, gson));
okHttpClient.newCall(requestF).enqueue(new PlayerStatsCallback(feedbackFuture, gson));

CompletableFuture<Map<PlayerStatsType, PlayerStats>> finalFuture = new CompletableFuture<>();

// Doing this so we log only the first future failing, not all 3 within the callback.
CompletableFuture.allOf(passiveFuture, manualFuture, feedbackFuture).whenComplete((v, e) ->
// Doing this so we log only the first future failing, not all 2 within the callback.
CompletableFuture.allOf(reportsFuture, feedbackFuture).whenComplete((v, e) ->
{
if (e != null)
{
Expand All @@ -465,8 +460,7 @@ public CompletableFuture<Map<PlayerStatsType, PlayerStats>> requestPlayerStats(S
}
else
{
finalFuture.complete(processPlayerStats(
passiveFuture.join(), manualFuture.join(), feedbackFuture.join()));
finalFuture.complete(processPlayerStats(reportsFuture.join(), feedbackFuture.join()));
}
});

Expand Down Expand Up @@ -592,20 +586,21 @@ private IOException getIOException(Response response)

/**
* Collects the given {@link PlayerStatsAPIItem} into a combined map that the plugin expects.
* @param passive The passive usage stats from the API.
* @param manual The manual flagging stats from the API.
* @param reports The reports usage stats from the API.
* @param feedback The feedback stats from the API.
* @return The combined processed map expected by the plugin.
*/
private Map<PlayerStatsType, PlayerStats> processPlayerStats(Collection<PlayerStatsAPIItem> passive, Collection<PlayerStatsAPIItem> manual, Collection<PlayerStatsAPIItem> feedback)
private Map<PlayerStatsType, PlayerStats> processPlayerStats(Collection<PlayerStatsAPIItem> reports, Collection<PlayerStatsAPIItem> feedback)
{
if (passive == null || manual == null || feedback == null)
if (reports == null || feedback == null)
{
return null;
}

PlayerStats passiveStats = countStats(passive, false);
PlayerStats manualStats = countStats(manual, true);
PlayerStats passiveStats = countStats(reports.stream().filter(
r -> r.getManual() != null && !r.getManual()).collect(Collectors.toList()), false);
PlayerStats manualStats = countStats(reports.stream().filter(
r -> r.getManual() != null && r.getManual()).collect(Collectors.toList()), true);
PlayerStats feedbackStats = countStats(feedback, false);

PlayerStats totalStats = PlayerStats.builder()
Expand All @@ -623,7 +618,7 @@ private Map<PlayerStatsType, PlayerStats> processPlayerStats(Collection<PlayerSt
}

/**
* Utility function for {@link BotDetectorClient#processPlayerStats(Collection, Collection, Collection)}.
* Utility function for {@link BotDetectorClient#processPlayerStats(Collection, Collection)}.
* Compile each element from the API into a {@link PlayerStats} object.
* @param fromAPI The returned collections of player stats from the API to accumulate.
* @param countIncorrect Intended for manual flagging stats. If true, count confirmed players into {@link PlayerStats#getIncorrectFlags()}.
Expand Down Expand Up @@ -711,7 +706,16 @@ private static class PlayerStatsAPIItem
boolean banned;
@SerializedName("confirmed_player")
boolean player;
/**
* Will be Null for feedbacks
*/
@SerializedName("manual_detect")
Boolean manual;
long count;
/**
* Will be Null for report counts
*/
Long vote;
}

/**
Expand Down
6 changes: 3 additions & 3 deletions src/main/java/com/botdetector/ui/BotDetectorPanel.java
Original file line number Diff line number Diff line change
Expand Up @@ -157,9 +157,9 @@ public enum WarningLabel
private static final int MAX_FEEDBACK_TEXT_CHARS = 250;
private static final Dimension FEEDBACK_TEXTBOX_PREFERRED_SIZE = new Dimension(0, 75);

private static final FeedbackPredictionLabel UNSURE_PREDICTION_LABEL = new FeedbackPredictionLabel("Unsure", null, FeedbackValue.NEUTRAL);
private static final FeedbackPredictionLabel SOMETHING_ELSE_PREDICTION_LABEL = new FeedbackPredictionLabel("Something_else", null, FeedbackValue.NEGATIVE);
private static final FeedbackPredictionLabel CORRECT_FALLBACK_PREDICTION_LABEL = new FeedbackPredictionLabel("Correct", null, FeedbackValue.POSITIVE);
private static final FeedbackPredictionLabel UNSURE_PREDICTION_LABEL = new FeedbackPredictionLabel("unsure", null, FeedbackValue.NEUTRAL);
private static final FeedbackPredictionLabel SOMETHING_ELSE_PREDICTION_LABEL = new FeedbackPredictionLabel("something_else", null, FeedbackValue.NEGATIVE);
private static final FeedbackPredictionLabel CORRECT_FALLBACK_PREDICTION_LABEL = new FeedbackPredictionLabel("correct", null, FeedbackValue.POSITIVE);

private static final PlayerStatsType[] PLAYER_STAT_TYPES = {
PlayerStatsType.TOTAL, PlayerStatsType.PASSIVE, PlayerStatsType.MANUAL
Expand Down