Implemented Playerbase endpoint

This commit is contained in:
Rsl1122 2019-07-07 23:27:38 +03:00
parent 5f25330b12
commit f9bfb35a94
16 changed files with 354 additions and 387 deletions

View File

@ -20,6 +20,7 @@ import com.djrapitops.plan.data.store.mutators.ActivityIndex;
import com.djrapitops.plan.db.access.Query;
import com.djrapitops.plan.db.access.QueryStatement;
import com.djrapitops.plan.db.sql.tables.SessionsTable;
import com.djrapitops.plan.db.sql.tables.UserInfoTable;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
@ -69,7 +70,7 @@ public class ActivityIndexQueries {
return fetchActivityGroupCount(date, serverUUID, playtimeThreshold, ActivityIndex.REGULAR, 5.1);
}
public static Query<Integer> fetchActivityGroupCount(long date, UUID serverUUID, long playtimeThreshold, double above, double below) {
private static String selectActivityIndexSQL() {
String selectActivePlaytimeSQL = SELECT +
SessionsTable.USER_UUID +
",SUM(" +
@ -83,11 +84,30 @@ public class ActivityIndexQueries {
String selectThreeWeeks = selectActivePlaytimeSQL + UNION + selectActivePlaytimeSQL + UNION + selectActivePlaytimeSQL;
String selectActivityIndex = SELECT +
return SELECT +
"5.0 - 5.0 * AVG(1 / (?/2 * (q1.active_playtime/?) +1)) as activity_index," +
"q1." + SessionsTable.USER_UUID +
FROM + '(' + selectThreeWeeks + ") q1" +
GROUP_BY + "q1." + SessionsTable.USER_UUID;
}
private static void setSelectActivityIndexSQLParameters(PreparedStatement statement, int index, long playtimeThreshold, UUID serverUUID, long date) throws SQLException {
statement.setDouble(index, Math.PI);
statement.setLong(index + 1, playtimeThreshold);
statement.setString(index + 2, serverUUID.toString());
statement.setLong(index + 3, date - TimeUnit.DAYS.toMillis(7L));
statement.setLong(index + 4, date);
statement.setString(index + 5, serverUUID.toString());
statement.setLong(index + 6, date - TimeUnit.DAYS.toMillis(14L));
statement.setLong(index + 7, date - TimeUnit.DAYS.toMillis(7L));
statement.setString(index + 8, serverUUID.toString());
statement.setLong(index + 9, date - TimeUnit.DAYS.toMillis(21L));
statement.setLong(index + 10, date - TimeUnit.DAYS.toMillis(14L));
}
public static Query<Integer> fetchActivityGroupCount(long date, UUID serverUUID, long playtimeThreshold, double above, double below) {
String selectActivityIndex = selectActivityIndexSQL();
// TODO Include users with 0 sessions in Inactive group
// TODO Take into account player's register date
@ -99,19 +119,7 @@ public class ActivityIndexQueries {
return new QueryStatement<Integer>(selectActivePlayerCount) {
@Override
public void prepare(PreparedStatement statement) throws SQLException {
statement.setDouble(1, Math.PI);
statement.setLong(2, playtimeThreshold);
statement.setString(3, serverUUID.toString());
statement.setLong(4, date - TimeUnit.DAYS.toMillis(7L));
statement.setLong(5, date);
statement.setString(6, serverUUID.toString());
statement.setLong(7, date - TimeUnit.DAYS.toMillis(14L));
statement.setLong(8, date - TimeUnit.DAYS.toMillis(7L));
statement.setString(9, serverUUID.toString());
statement.setLong(10, date - TimeUnit.DAYS.toMillis(21L));
statement.setLong(11, date - TimeUnit.DAYS.toMillis(14L));
setSelectActivityIndexSQLParameters(statement, 1, playtimeThreshold, serverUUID, date);
statement.setDouble(12, above);
statement.setDouble(13, below);
}
@ -134,4 +142,72 @@ public class ActivityIndexQueries {
return groups;
};
}
public static Query<Integer> countNewPlayersTurnedRegular(long after, long before, UUID serverUUID, Long threshold) {
String selectActivityIndex = selectActivityIndexSQL();
String selectActivePlayerCount = SELECT + "COUNT(1) as count" +
FROM + '(' + selectActivityIndex + ") q2" +
INNER_JOIN + UserInfoTable.TABLE_NAME + " u on u." + UserInfoTable.USER_UUID + "=q2." + SessionsTable.USER_UUID +
WHERE + "u." + UserInfoTable.SERVER_UUID + "=?" +
AND + "u." + UserInfoTable.REGISTERED + ">=?" +
AND + "u." + UserInfoTable.REGISTERED + "<=?" +
AND + "q2.activity_index>=?" +
AND + "q2.activity_index<?";
return new QueryStatement<Integer>(selectActivePlayerCount) {
@Override
public void prepare(PreparedStatement statement) throws SQLException {
setSelectActivityIndexSQLParameters(statement, 1, threshold, serverUUID, before);
statement.setString(12, serverUUID.toString());
statement.setLong(13, after);
statement.setLong(14, before);
statement.setDouble(15, ActivityIndex.REGULAR);
statement.setDouble(16, 5.1);
}
@Override
public Integer processResults(ResultSet set) throws SQLException {
return set.next() ? set.getInt("count") : 0;
}
};
}
/**
* @param start Start of the tracking, those regular will be counted here.
* @param end End of the tracking, those inactive will be count here.
* @param serverUUID UUID of the server.
* @param threshold Playtime threshold
* @return Query how many players went from regular to inactive in a span of time.
*/
public static Query<Integer> countRegularPlayersTurnedInactive(long start, long end, UUID serverUUID, Long threshold) {
String selectActivityIndex = selectActivityIndexSQL();
String selectActivePlayerCount = SELECT + "COUNT(1) as count" +
FROM + '(' + selectActivityIndex + ") q2" +
// Join two select activity index queries together to query Regular and Inactive players
INNER_JOIN + '(' + selectActivityIndex.replace("q1", "q3") + ") q4" +
" on q2." + SessionsTable.USER_UUID + "=q4." + SessionsTable.USER_UUID +
WHERE + "q2.activity_index>=?" +
AND + "q2.activity_index<?" +
AND + "q4.activity_index>=?" +
AND + "q4.activity_index<?";
return new QueryStatement<Integer>(selectActivePlayerCount) {
@Override
public void prepare(PreparedStatement statement) throws SQLException {
setSelectActivityIndexSQLParameters(statement, 1, threshold, serverUUID, end);
setSelectActivityIndexSQLParameters(statement, 12, threshold, serverUUID, start);
statement.setDouble(22, ActivityIndex.REGULAR);
statement.setDouble(23, 5.1);
statement.setDouble(24, -0.1);
statement.setDouble(25, ActivityIndex.IRREGULAR);
}
@Override
public Integer processResults(ResultSet set) throws SQLException {
return set.next() ? set.getInt("count") : 0;
}
};
}
}

View File

@ -46,7 +46,7 @@ import java.util.concurrent.TimeUnit;
* @author Rsl1122
*/
@Singleton
public class OnlineActivityOverviewJSONParser {
public class OnlineActivityOverviewJSONParser implements TabJSONParser<Map<String, Object>> {
private PlanConfig config;
private DBSystem dbSystem;

View File

@ -0,0 +1,145 @@
/*
* This file is part of Player Analytics (Plan).
*
* Plan is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License v3 as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Plan is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Plan. If not, see <https://www.gnu.org/licenses/>.
*/
package com.djrapitops.plan.system.json;
import com.djrapitops.plan.db.Database;
import com.djrapitops.plan.db.access.queries.analysis.ActivityIndexQueries;
import com.djrapitops.plan.db.access.queries.analysis.PlayerCountQueries;
import com.djrapitops.plan.db.access.queries.objects.SessionQueries;
import com.djrapitops.plan.system.database.DBSystem;
import com.djrapitops.plan.system.settings.config.PlanConfig;
import com.djrapitops.plan.system.settings.paths.TimeSettings;
import com.djrapitops.plan.utilities.formatting.Formatter;
import com.djrapitops.plan.utilities.formatting.Formatters;
import javax.inject.Inject;
import javax.inject.Singleton;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;
import java.util.concurrent.TimeUnit;
/**
* Parses JSON payload for /server-page Playerbase Overview tab.
*
* @author Rsl1122
*/
@Singleton
public class PlayerBaseOverviewJSONParser implements TabJSONParser<Map<String, Object>> {
private PlanConfig config;
private DBSystem dbSystem;
private Formatter<Long> timeAmountFormatter;
private Formatter<Double> percentageFormatter;
@Inject
public PlayerBaseOverviewJSONParser(
PlanConfig config,
DBSystem dbSystem,
Formatters formatters
) {
this.config = config;
this.dbSystem = dbSystem;
timeAmountFormatter = formatters.timeAmount();
percentageFormatter = formatters.percentage();
}
public Map<String, Object> createJSONAsMap(UUID serverUUID) {
Map<String, Object> serverOverview = new HashMap<>();
serverOverview.put("trends", createTrendsMap(serverUUID));
serverOverview.put("insights", createInsightsMap(serverUUID));
return serverOverview;
}
private Map<String, Object> createTrendsMap(UUID serverUUID) {
Database db = dbSystem.getDatabase();
long now = System.currentTimeMillis();
long monthAgo = now - TimeUnit.DAYS.toMillis(30L);
long twoMonthsAgo = now - TimeUnit.DAYS.toMillis(60L);
Long playThreshold = config.get(TimeSettings.ACTIVE_PLAY_THRESHOLD);
Map<String, Object> trends = new HashMap<>();
Integer playersBefore = db.query(PlayerCountQueries.uniquePlayerCount(0L, monthAgo, serverUUID));
Integer playersAfter = db.query(PlayerCountQueries.uniquePlayerCount(0L, now, serverUUID));
trends.put("total_players_then", playersBefore);
trends.put("total_players_now", playersAfter);
trends.put("total_players_trend", new Trend(playersBefore, playersAfter, false));
Integer regularBefore = db.query(ActivityIndexQueries.fetchRegularPlayerCount(monthAgo, serverUUID, playThreshold));
Integer regularAfter = db.query(ActivityIndexQueries.fetchRegularPlayerCount(now, serverUUID, playThreshold));
trends.put("regular_players_then", regularBefore);
trends.put("regular_players_now", regularAfter);
trends.put("regular_players_trend", new Trend(regularBefore, regularAfter, false));
// TODO
trends.put("playtime_avg_then", "Not implemented");
trends.put("playtime_avg_now", "Not implemented");
trends.put("playtime_avg_trend", new Trend(0, 0, false, timeAmountFormatter));
Long playtimeBefore = db.query(SessionQueries.playtime(twoMonthsAgo, monthAgo, serverUUID));
Long playtimeAfter = db.query(SessionQueries.playtime(monthAgo, now, serverUUID));
Long afkBefore = db.query(SessionQueries.afkTime(twoMonthsAgo, monthAgo, serverUUID));
Long afkAfter = db.query(SessionQueries.afkTime(monthAgo, now, serverUUID));
double afkPercBefore = playersBefore != 0 ? (double) afkBefore / playtimeBefore : 0;
double afkPercAfter = playersBefore != 0 ? (double) afkAfter / playtimeAfter : 0;
trends.put("afk_then", percentageFormatter.apply(afkPercBefore));
trends.put("afk_now", percentageFormatter.apply(afkPercAfter));
trends.put("afk_trend", new Trend(afkPercBefore, afkPercAfter, Trend.REVERSED, percentageFormatter));
// TODO
trends.put("regular_playtime_avg_then", "Not implemented");
trends.put("regular_playtime_avg_now", "Not implemented");
trends.put("regular_playtime_avg_trend", new Trend(0, 0, false, timeAmountFormatter));
// TODO
trends.put("regular_session_avg_then", "Not implemented");
trends.put("regular_session_avg_now", "Not implemented");
trends.put("regular_session_avg_trend", new Trend(0, 0, false, timeAmountFormatter));
// TODO
trends.put("regular_afk_avg_then", "Not implemented");
trends.put("regular_afk_avg_now", "Not implemented");
trends.put("regular_afk_avg_trend", new Trend(0, 0, Trend.REVERSED, percentageFormatter));
return trends;
}
private Map<String, Object> createInsightsMap(UUID serverUUID) {
Database db = dbSystem.getDatabase();
long now = System.currentTimeMillis();
long halfMonthAgo = now - TimeUnit.DAYS.toMillis(30L);
long monthAgo = now - TimeUnit.DAYS.toMillis(30L);
Long playThreshold = config.get(TimeSettings.ACTIVE_PLAY_THRESHOLD);
Map<String, Object> insights = new HashMap<>();
int newToRegular = db.query(ActivityIndexQueries.countNewPlayersTurnedRegular(monthAgo, now, serverUUID, playThreshold));
Integer newToRegularBefore = db.query(ActivityIndexQueries.countNewPlayersTurnedRegular(monthAgo, halfMonthAgo, serverUUID, playThreshold));
Integer newToRegularAfter = db.query(ActivityIndexQueries.countNewPlayersTurnedRegular(halfMonthAgo, now, serverUUID, playThreshold));
insights.put("new_to_regular", newToRegular);
insights.put("new_to_regular_trend", new Trend(newToRegularBefore, newToRegularAfter, false));
Integer regularToInactive = db.query(ActivityIndexQueries.countRegularPlayersTurnedInactive(monthAgo, now, serverUUID, playThreshold));
Integer regularToInactiveBefore = db.query(ActivityIndexQueries.countRegularPlayersTurnedInactive(monthAgo, halfMonthAgo, serverUUID, playThreshold));
Integer regularToInactiveAfter = db.query(ActivityIndexQueries.countRegularPlayersTurnedInactive(halfMonthAgo, now, serverUUID, playThreshold));
insights.put("regular_to_inactive", regularToInactive);
insights.put("regular_to_inactive_trend", new Trend(regularToInactiveBefore, regularToInactiveAfter, Trend.REVERSED));
return insights;
}
}

View File

@ -33,7 +33,7 @@ import java.util.concurrent.TimeUnit;
* @author Rsl1122
*/
@Singleton
public class PvPPvEJSONParser {
public class PvPPvEJSONParser implements TabJSONParser<Map<String, Object>> {
private DBSystem dbSystem;

View File

@ -49,7 +49,7 @@ import java.util.concurrent.TimeUnit;
* @author Rsl1122
*/
@Singleton
public class ServerOverviewJSONParser {
public class ServerOverviewJSONParser implements TabJSONParser<Map<String, Object>> {
private PlanConfig config;
private DBSystem dbSystem;

View File

@ -18,15 +18,12 @@ package com.djrapitops.plan.system.json;
import com.djrapitops.plan.data.container.TPS;
import com.djrapitops.plan.data.store.mutators.TPSMutator;
import com.djrapitops.plan.data.store.objects.DateHolder;
import com.djrapitops.plan.data.time.GMTimes;
import com.djrapitops.plan.db.Database;
import com.djrapitops.plan.db.access.queries.objects.SessionQueries;
import com.djrapitops.plan.db.access.queries.objects.TPSQueries;
import com.djrapitops.plan.db.access.queries.objects.WorldTimesQueries;
import com.djrapitops.plan.system.database.DBSystem;
import com.djrapitops.plan.system.info.server.ServerInfo;
import com.djrapitops.plan.system.settings.config.PlanConfig;
import com.djrapitops.plan.utilities.formatting.Formatter;
import com.djrapitops.plan.utilities.formatting.Formatters;
import org.apache.commons.text.WordUtils;
@ -42,31 +39,21 @@ import java.util.concurrent.TimeUnit;
* @author Rsl1122
*/
@Singleton
public class SessionsOverviewJSONParser {
public class SessionsOverviewJSONParser implements TabJSONParser<Map<String, Object>> {
private PlanConfig config;
private DBSystem dbSystem;
private ServerInfo serverInfo;
private Formatter<Long> timeAmountFormatter;
private Formatter<Double> decimalFormatter;
private Formatter<Double> percentageFormatter;
private Formatter<DateHolder> dateFormatter;
@Inject
public SessionsOverviewJSONParser(
PlanConfig config,
DBSystem dbSystem,
ServerInfo serverInfo,
Formatters formatters
) {
this.config = config;
this.dbSystem = dbSystem;
this.serverInfo = serverInfo;
dateFormatter = formatters.day();
timeAmountFormatter = formatters.timeAmount();
decimalFormatter = formatters.decimals();
percentageFormatter = formatters.percentage();
}

View File

@ -0,0 +1,35 @@
/*
* This file is part of Player Analytics (Plan).
*
* Plan is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License v3 as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Plan is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Plan. If not, see <https://www.gnu.org/licenses/>.
*/
package com.djrapitops.plan.system.json;
import java.util.UUID;
import java.util.function.Function;
/**
* Interface for different tab JSON parsers.
*
* @author Rsl1122
*/
public interface TabJSONParser<T> extends Function<UUID, T> {
T createJSONAsMap(UUID serverUUID);
@Override
default T apply(UUID uuid) {
return createJSONAsMap(uuid);
}
}

View File

@ -25,6 +25,11 @@ import com.djrapitops.plan.utilities.formatting.Formatter;
*/
public class Trend {
/**
* When a trend is reversed increase is "bad" (red) and decrease is "good" (green)
*/
public static final boolean REVERSED = true;
private String text;
private String direction;
private boolean reversed;

View File

@ -1,64 +0,0 @@
/*
* This file is part of Player Analytics (Plan).
*
* Plan is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License v3 as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Plan is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Plan. If not, see <https://www.gnu.org/licenses/>.
*/
package com.djrapitops.plan.system.webserver.pages.json;
import com.djrapitops.plan.api.exceptions.WebUserAuthException;
import com.djrapitops.plan.api.exceptions.connection.WebException;
import com.djrapitops.plan.system.Identifiers;
import com.djrapitops.plan.system.json.OnlineActivityOverviewJSONParser;
import com.djrapitops.plan.system.webserver.Request;
import com.djrapitops.plan.system.webserver.RequestTarget;
import com.djrapitops.plan.system.webserver.auth.Authentication;
import com.djrapitops.plan.system.webserver.pages.PageHandler;
import com.djrapitops.plan.system.webserver.response.Response;
import com.djrapitops.plan.system.webserver.response.data.JSONResponse;
import javax.inject.Inject;
import javax.inject.Singleton;
import java.util.UUID;
/**
* JSON handler for Online Activity Overview tab JSON requests.
*
* @author Rsl1122
*/
@Singleton
public class OnlineActivityOverviewJSONHandler implements PageHandler {
private final Identifiers identifiers;
private final OnlineActivityOverviewJSONParser jsonParser;
@Inject
public OnlineActivityOverviewJSONHandler(
Identifiers identifiers,
OnlineActivityOverviewJSONParser jsonParser
) {
this.identifiers = identifiers;
this.jsonParser = jsonParser;
}
@Override
public Response getResponse(Request request, RequestTarget target) throws WebException {
UUID serverUUID = identifiers.getServerUUID(target); // Can throw BadRequestException
return new JSONResponse<>(jsonParser.createJSONAsMap(serverUUID));
}
@Override
public boolean isAuthorized(Authentication auth, RequestTarget target) throws WebUserAuthException {
return auth.getWebUser().getPermLevel() <= 0;
}
}

View File

@ -1,64 +0,0 @@
/*
* This file is part of Player Analytics (Plan).
*
* Plan is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License v3 as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Plan is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Plan. If not, see <https://www.gnu.org/licenses/>.
*/
package com.djrapitops.plan.system.webserver.pages.json;
import com.djrapitops.plan.api.exceptions.WebUserAuthException;
import com.djrapitops.plan.api.exceptions.connection.WebException;
import com.djrapitops.plan.system.Identifiers;
import com.djrapitops.plan.system.json.PvPPvEJSONParser;
import com.djrapitops.plan.system.webserver.Request;
import com.djrapitops.plan.system.webserver.RequestTarget;
import com.djrapitops.plan.system.webserver.auth.Authentication;
import com.djrapitops.plan.system.webserver.pages.PageHandler;
import com.djrapitops.plan.system.webserver.response.Response;
import com.djrapitops.plan.system.webserver.response.data.JSONResponse;
import javax.inject.Inject;
import javax.inject.Singleton;
import java.util.UUID;
/**
* JSON handler for PvP & PvE tab JSON requests.
*
* @author Rsl1122
*/
@Singleton
public class PvPPvEJSONHandler implements PageHandler {
private final Identifiers identifiers;
private final PvPPvEJSONParser jsonParser;
@Inject
public PvPPvEJSONHandler(
Identifiers identifiers,
PvPPvEJSONParser jsonParser
) {
this.identifiers = identifiers;
this.jsonParser = jsonParser;
}
@Override
public Response getResponse(Request request, RequestTarget target) throws WebException {
UUID serverUUID = identifiers.getServerUUID(target); // Can throw BadRequestException
return new JSONResponse<>(jsonParser.createJSONAsMap(serverUUID));
}
@Override
public boolean isAuthorized(Authentication auth, RequestTarget target) throws WebUserAuthException {
return auth.getWebUser().getPermLevel() <= 0;
}
}

View File

@ -17,6 +17,8 @@
package com.djrapitops.plan.system.webserver.pages.json;
import com.djrapitops.plan.api.exceptions.WebUserAuthException;
import com.djrapitops.plan.system.Identifiers;
import com.djrapitops.plan.system.json.*;
import com.djrapitops.plan.system.webserver.RequestTarget;
import com.djrapitops.plan.system.webserver.auth.Authentication;
import com.djrapitops.plan.system.webserver.pages.TreePageHandler;
@ -33,28 +35,42 @@ import javax.inject.Singleton;
@Singleton
public class RootJSONHandler extends TreePageHandler {
private Identifiers identifiers;
@Inject
public RootJSONHandler(
ResponseFactory responseFactory,
Identifiers identifiers,
JSONFactory jsonFactory,
GraphsJSONHandler graphsJSONHandler,
SessionsJSONHandler sessionsJSONHandler,
PlayersTableJSONHandler playersTableJSONHandler,
ServerOverviewJSONHandler serverOverviewJSONHandler,
OnlineActivityOverviewJSONHandler onlineActivityOverviewJSONHandler,
SessionsOverviewJSONHandler sessionsOverviewJSONHandler,
ServerOverviewJSONParser serverOverviewJSONParser,
OnlineActivityOverviewJSONParser onlineActivityOverviewJSONParser,
SessionsOverviewJSONParser sessionsOverviewJSONParser,
PlayerKillsJSONHandler playerKillsJSONHandler,
PvPPvEJSONHandler pvppveJSONHandler
PvPPvEJSONParser pvPPvEJSONParser,
PlayerBaseOverviewJSONParser playerBaseOverviewJSONParser
) {
super(responseFactory);
this.identifiers = identifiers;
registerPage("players", playersTableJSONHandler);
registerPage("sessions", sessionsJSONHandler);
registerPage("kills", playerKillsJSONHandler);
registerPage("graph", graphsJSONHandler);
registerPage("serverOverview", serverOverviewJSONHandler);
registerPage("onlineOverview", onlineActivityOverviewJSONHandler);
registerPage("sessionsOverview", sessionsOverviewJSONHandler);
registerPage("playerVersus", pvppveJSONHandler);
registerPage("serverOverview", serverOverviewJSONParser);
registerPage("onlineOverview", onlineActivityOverviewJSONParser);
registerPage("sessionsOverview", sessionsOverviewJSONParser);
registerPage("playerVersus", pvPPvEJSONParser);
registerPage("playerbaseOverview", playerBaseOverviewJSONParser);
}
private <T> void registerPage(String identifier, TabJSONParser<T> tabJSONParser) {
registerPage(identifier, new ServerTabJSONHandler<>(identifiers, tabJSONParser));
}
@Override

View File

@ -1,64 +0,0 @@
/*
* This file is part of Player Analytics (Plan).
*
* Plan is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License v3 as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Plan is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Plan. If not, see <https://www.gnu.org/licenses/>.
*/
package com.djrapitops.plan.system.webserver.pages.json;
import com.djrapitops.plan.api.exceptions.WebUserAuthException;
import com.djrapitops.plan.api.exceptions.connection.WebException;
import com.djrapitops.plan.system.Identifiers;
import com.djrapitops.plan.system.json.ServerOverviewJSONParser;
import com.djrapitops.plan.system.webserver.Request;
import com.djrapitops.plan.system.webserver.RequestTarget;
import com.djrapitops.plan.system.webserver.auth.Authentication;
import com.djrapitops.plan.system.webserver.pages.PageHandler;
import com.djrapitops.plan.system.webserver.response.Response;
import com.djrapitops.plan.system.webserver.response.data.JSONResponse;
import javax.inject.Inject;
import javax.inject.Singleton;
import java.util.UUID;
/**
* JSON handler for Server Overview tab JSON requests.
*
* @author Rsl1122
*/
@Singleton
public class ServerOverviewJSONHandler implements PageHandler {
private final Identifiers identifiers;
private final ServerOverviewJSONParser jsonParser;
@Inject
public ServerOverviewJSONHandler(
Identifiers identifiers,
ServerOverviewJSONParser jsonParser
) {
this.identifiers = identifiers;
this.jsonParser = jsonParser;
}
@Override
public Response getResponse(Request request, RequestTarget target) throws WebException {
UUID serverUUID = identifiers.getServerUUID(target); // Can throw BadRequestException
return new JSONResponse<>(jsonParser.createJSONAsMap(serverUUID));
}
@Override
public boolean isAuthorized(Authentication auth, RequestTarget target) throws WebUserAuthException {
return auth.getWebUser().getPermLevel() <= 0;
}
}

View File

@ -0,0 +1,42 @@
package com.djrapitops.plan.system.webserver.pages.json;
import com.djrapitops.plan.api.exceptions.WebUserAuthException;
import com.djrapitops.plan.api.exceptions.connection.WebException;
import com.djrapitops.plan.system.Identifiers;
import com.djrapitops.plan.system.json.TabJSONParser;
import com.djrapitops.plan.system.webserver.Request;
import com.djrapitops.plan.system.webserver.RequestTarget;
import com.djrapitops.plan.system.webserver.auth.Authentication;
import com.djrapitops.plan.system.webserver.pages.PageHandler;
import com.djrapitops.plan.system.webserver.response.Response;
import com.djrapitops.plan.system.webserver.response.data.JSONResponse;
import java.util.UUID;
import java.util.function.Function;
/**
* Generic Tab JSON handler for any tab's data.
*
* @author Rsl1122
*/
public class ServerTabJSONHandler<T> implements PageHandler {
private final Identifiers identifiers;
private final Function<UUID, T> jsonParser;
public ServerTabJSONHandler(Identifiers identifiers, TabJSONParser<T> jsonParser) {
this.identifiers = identifiers;
this.jsonParser = jsonParser;
}
@Override
public Response getResponse(Request request, RequestTarget target) throws WebException {
UUID serverUUID = identifiers.getServerUUID(target); // Can throw BadRequestException
return new JSONResponse<>(jsonParser.apply(serverUUID));
}
@Override
public boolean isAuthorized(Authentication auth, RequestTarget target) throws WebUserAuthException {
return auth.getWebUser().getPermLevel() <= 0;
}
}

View File

@ -1,64 +0,0 @@
/*
* This file is part of Player Analytics (Plan).
*
* Plan is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License v3 as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Plan is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Plan. If not, see <https://www.gnu.org/licenses/>.
*/
package com.djrapitops.plan.system.webserver.pages.json;
import com.djrapitops.plan.api.exceptions.WebUserAuthException;
import com.djrapitops.plan.api.exceptions.connection.WebException;
import com.djrapitops.plan.system.Identifiers;
import com.djrapitops.plan.system.json.SessionsOverviewJSONParser;
import com.djrapitops.plan.system.webserver.Request;
import com.djrapitops.plan.system.webserver.RequestTarget;
import com.djrapitops.plan.system.webserver.auth.Authentication;
import com.djrapitops.plan.system.webserver.pages.PageHandler;
import com.djrapitops.plan.system.webserver.response.Response;
import com.djrapitops.plan.system.webserver.response.data.JSONResponse;
import javax.inject.Inject;
import javax.inject.Singleton;
import java.util.UUID;
/**
* JSON handler for Sessions tab JSON requests.
*
* @author Rsl1122
*/
@Singleton
public class SessionsOverviewJSONHandler implements PageHandler {
private final Identifiers identifiers;
private final SessionsOverviewJSONParser jsonParser;
@Inject
public SessionsOverviewJSONHandler(
Identifiers identifiers,
SessionsOverviewJSONParser jsonParser
) {
this.identifiers = identifiers;
this.jsonParser = jsonParser;
}
@Override
public Response getResponse(Request request, RequestTarget target) throws WebException {
UUID serverUUID = identifiers.getServerUUID(target); // Can throw BadRequestException
return new JSONResponse<>(jsonParser.createJSONAsMap(serverUUID));
}
@Override
public boolean isAuthorized(Authentication auth, RequestTarget target) throws WebUserAuthException {
return auth.getWebUser().getPermLevel() <= 0;
}
}

View File

@ -1415,67 +1415,7 @@
jsonRequest("../v1/onlineOverview?serverName=${serverName}", loadOnlineActivityOverviewValues);
jsonRequest("../v1/sessionsOverview?serverName=${serverName}", loadSessionValues);
jsonRequest("../v1/playerVersus?serverName=${serverName}", loadPvPPvEValues);
loadPlayerbaseOverviewValues(
{
trends: {
total_players_then: 4532,
total_players_now: 5043,
total_players_trend: {
text: 511,
direction: '+'
},
regular_players_then: 467,
regular_players_now: 483,
regular_players_trend: {
text: 16,
direction: '+'
},
playtime_avg_then: '8h 5m 56s',
playtime_avg_now: '8h 53m 24s',
playtime_avg_trend: {
text: '47m 32s',
direction: '+'
},
afk_then: '34.5%',
afk_now: '42.4%',
afk_trend: {
text: '7.9%',
direction: '+',
reversed: true
},
regular_playtime_avg_then: '8h 5m 56s',
regular_playtime_avg_now: '8h 53m 24s',
regular_playtime_avg_trend: {
text: '47m 32s',
direction: '+'
},
regular_session_avg_then: '8h 5m 56s',
regular_session_avg_now: '8h 53m 24s',
regular_session_avg_trend: {
text: '47m 32s',
direction: '+'
},
regular_afk_then: '34.5%',
regular_afk_now: '42.4%',
regular_afk_trend: {
text: '7.9%',
direction: '+',
reversed: true
}
},
insights: {
new_to_regular: 32,
new_to_regular_trend: {
direction: '+'
},
regular_to_inactive: 45,
regular_to_inactive_trend: {
direction: '+',
reversed: true
}
}
}, null
);
jsonRequest("../v1/playerbaseOverview?serverName=${serverName}", loadPlayerbaseOverviewValues);
loadPerformanceValues(
{
numbers: {

View File

@ -15,9 +15,9 @@ The body of the response is the error message
Obtain all data in the database for a player.
### `GET /v1/serverOverview`
### Tab endpoints
Obtain data for Server Overview tab (The first tab on `/server`-page)
Endpoints for tab specific number data, processed for display.
Required parameters: `serverName` or `serverUUID`
@ -26,38 +26,15 @@ Parameter|Expected value|Description
`serverName` | Name of a Plan server | Used for identifying Plan server that the data should be about
`serverUUID` | UUID of a Plan server | Used for identifying Plan server that the data should be about
### `GET /v1/onlineOverview`
#### `GET /v1/serverOverview` - Server Overview tab
Obtain data for Online Activity Overview tab.
#### `GET /v1/onlineOverview` - Online Activity Overview tab.
Required parameters: `serverName` or `serverUUID`
#### `GET /v1/sessionsOverview` - Sessions tab.
Parameter|Expected value|Description
--|--|--
`serverName` | Name of a Plan server | Used for identifying Plan server that the data should be about
`serverUUID` | UUID of a Plan server | Used for identifying Plan server that the data should be about
#### `GET /v1/playerVersus` - PvP & PvE tab.
### `GET /v1/sessionsOverview`
Obtain data for Sessions tab.
Required parameters: `serverName` or `serverUUID`
Parameter|Expected value|Description
--|--|--
`serverName` | Name of a Plan server | Used for identifying Plan server that the data should be about
`serverUUID` | UUID of a Plan server | Used for identifying Plan server that the data should be about
### `GET /v1/playerVersus`
Obtain data for PvP & PvE tab.
Required parameters: `serverName` or `serverUUID`
Parameter|Expected value|Description
--|--|--
`serverName` | Name of a Plan server | Used for identifying Plan server that the data should be about
`serverUUID` | UUID of a Plan server | Used for identifying Plan server that the data should be about
#### `GET /v1/playerbaseOverview` - Playerbase Overview tab.
### `GET /v1/players`