mirror of
https://github.com/plan-player-analytics/Plan.git
synced 2025-01-23 16:41:22 +01:00
Implemented PvP&PvE tab & endpoint
This commit is contained in:
parent
25b036aff2
commit
9240a4e4fa
@ -120,9 +120,10 @@ public class KillQueries {
|
||||
AND + KillsTable.DATE + ">=?" +
|
||||
AND + KillsTable.DATE + "<=?" +
|
||||
GROUP_BY + KillsTable.VICTIM_UUID;
|
||||
String sql = SELECT + "AVG(kills/deaths) as kdr" +
|
||||
String sql = SELECT + "AVG(CAST(kills AS FLOAT)/CAST(deaths AS FLOAT)) as kdr" +
|
||||
FROM + '(' + selectKillCounts + ") q1" +
|
||||
INNER_JOIN + '(' + selectDeathCounts + ") q2 on q1." + KillsTable.KILLER_UUID + "=q2." + KillsTable.VICTIM_UUID;
|
||||
INNER_JOIN + '(' + selectDeathCounts + ") q2 on q1." + KillsTable.KILLER_UUID + "=q2." + KillsTable.VICTIM_UUID +
|
||||
WHERE + "deaths!=0";
|
||||
|
||||
return new QueryStatement<Double>(sql) {
|
||||
@Override
|
||||
@ -183,4 +184,33 @@ public class KillQueries {
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
public static Query<List<String>> topWeapons(long after, long before, UUID serverUUID, int limit) {
|
||||
String innerSQL = SELECT + KillsTable.WEAPON + ", COUNT(1) as kills" +
|
||||
FROM + KillsTable.TABLE_NAME +
|
||||
WHERE + KillsTable.SERVER_UUID + "=?" +
|
||||
AND + KillsTable.DATE + ">=?" +
|
||||
AND + KillsTable.DATE + "<=?" +
|
||||
GROUP_BY + KillsTable.WEAPON;
|
||||
String sql = SELECT + KillsTable.WEAPON +
|
||||
FROM + '(' + innerSQL + ')' +
|
||||
ORDER_BY + "kills DESC LIMIT ?";
|
||||
|
||||
return new QueryStatement<List<String>>(sql, limit) {
|
||||
@Override
|
||||
public void prepare(PreparedStatement statement) throws SQLException {
|
||||
statement.setString(1, serverUUID.toString());
|
||||
statement.setLong(2, after);
|
||||
statement.setLong(3, before);
|
||||
statement.setInt(4, limit);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> processResults(ResultSet set) throws SQLException {
|
||||
List<String> weapons = new ArrayList<>();
|
||||
while (set.next()) weapons.add(set.getString(KillsTable.WEAPON));
|
||||
return weapons;
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
@ -0,0 +1,124 @@
|
||||
/*
|
||||
* 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.objects.KillQueries;
|
||||
import com.djrapitops.plan.system.database.DBSystem;
|
||||
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.*;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
/**
|
||||
* Parses JSON payload for /server-page PvP & PvE tab.
|
||||
*
|
||||
* @author Rsl1122
|
||||
*/
|
||||
@Singleton
|
||||
public class PvPPvEJSONParser {
|
||||
|
||||
private DBSystem dbSystem;
|
||||
|
||||
private Formatter<Double> decimalFormatter;
|
||||
|
||||
@Inject
|
||||
public PvPPvEJSONParser(
|
||||
DBSystem dbSystem,
|
||||
Formatters formatters
|
||||
) {
|
||||
this.dbSystem = dbSystem;
|
||||
|
||||
decimalFormatter = formatters.decimals();
|
||||
}
|
||||
|
||||
public Map<String, Object> createJSONAsMap(UUID serverUUID) {
|
||||
Map<String, Object> serverOverview = new HashMap<>();
|
||||
serverOverview.put("numbers", createNumbersMap(serverUUID));
|
||||
serverOverview.put("insights", createInsightsMap(serverUUID));
|
||||
return serverOverview;
|
||||
}
|
||||
|
||||
private Map<String, Object> createNumbersMap(UUID serverUUID) {
|
||||
Database db = dbSystem.getDatabase();
|
||||
long now = System.currentTimeMillis();
|
||||
long weekAgo = now - TimeUnit.DAYS.toMillis(7L);
|
||||
long monthAgo = now - TimeUnit.DAYS.toMillis(30L);
|
||||
|
||||
Map<String, Object> numbers = new HashMap<>();
|
||||
Long pks = db.query(KillQueries.playerKillCount(0L, now, serverUUID));
|
||||
Long pks7d = db.query(KillQueries.playerKillCount(weekAgo, now, serverUUID));
|
||||
Long pks30d = db.query(KillQueries.playerKillCount(monthAgo, now, serverUUID));
|
||||
numbers.put("player_kills_total", pks);
|
||||
numbers.put("player_kills_30d", pks30d);
|
||||
numbers.put("player_kills_7d", pks7d);
|
||||
|
||||
numbers.put("player_kdr_avg", decimalFormatter.apply(db.query(KillQueries.averageKDR(0L, now, serverUUID))));
|
||||
numbers.put("player_kdr_avg_30d", decimalFormatter.apply(db.query(KillQueries.averageKDR(monthAgo, now, serverUUID))));
|
||||
numbers.put("player_kdr_avg_7d", decimalFormatter.apply(db.query(KillQueries.averageKDR(weekAgo, now, serverUUID))));
|
||||
|
||||
Long mobKills = db.query(KillQueries.mobKillCount(0L, now, serverUUID));
|
||||
Long mobKills30d = db.query(KillQueries.mobKillCount(monthAgo, now, serverUUID));
|
||||
Long mobKills7d = db.query(KillQueries.mobKillCount(weekAgo, now, serverUUID));
|
||||
numbers.put("mob_kills_total", mobKills);
|
||||
numbers.put("mob_kills_30d", mobKills30d);
|
||||
numbers.put("mob_kills_7d", mobKills7d);
|
||||
|
||||
Long deaths = db.query(KillQueries.deathCount(0L, now, serverUUID));
|
||||
Long deaths30d = db.query(KillQueries.deathCount(monthAgo, now, serverUUID));
|
||||
Long deaths7d = db.query(KillQueries.deathCount(weekAgo, now, serverUUID));
|
||||
numbers.put("deaths_total", deaths);
|
||||
numbers.put("deaths_30d", deaths30d);
|
||||
numbers.put("deaths_7d", deaths7d);
|
||||
|
||||
long mobDeaths = deaths - pks;
|
||||
long mobDeaths30d = deaths30d - pks30d;
|
||||
long mobDeaths7d = deaths7d - pks7d;
|
||||
|
||||
numbers.put("mob_deaths_total", mobDeaths);
|
||||
numbers.put("mob_deaths_30d", mobDeaths30d);
|
||||
numbers.put("mob_deaths_7d", mobDeaths7d);
|
||||
|
||||
numbers.put("mob_kdr_total", mobDeaths != 0 ? mobKills * 1.0 / mobDeaths : mobKills);
|
||||
numbers.put("mob_kdr_30d", mobDeaths30d != 0 ? mobKills30d * 1.0 / mobDeaths30d : mobKills30d);
|
||||
numbers.put("mob_kdr_7d", mobDeaths7d != 0 ? mobKills7d * 1.0 / mobDeaths7d : mobKills7d);
|
||||
|
||||
return numbers;
|
||||
}
|
||||
|
||||
private Map<String, Object> createInsightsMap(UUID serverUUID) {
|
||||
Database db = dbSystem.getDatabase();
|
||||
long now = System.currentTimeMillis();
|
||||
long monthAgo = now - TimeUnit.DAYS.toMillis(30L);
|
||||
|
||||
Map<String, Object> insights = new HashMap<>();
|
||||
|
||||
List<String> top3Weapons = db.query(KillQueries.topWeapons(monthAgo, now, serverUUID, 3));
|
||||
insights.put("weapon_1st", getWeapon(top3Weapons, 0).orElse("-"));
|
||||
insights.put("weapon_2nd", getWeapon(top3Weapons, 1).orElse("-"));
|
||||
insights.put("weapon_3rd", getWeapon(top3Weapons, 2).orElse("-"));
|
||||
|
||||
return insights;
|
||||
}
|
||||
|
||||
private <T> Optional<T> getWeapon(List<T> list, int index) {
|
||||
return list.size() <= index ? Optional.empty() : Optional.of(list.get(index));
|
||||
}
|
||||
}
|
@ -0,0 +1,64 @@
|
||||
/*
|
||||
* 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;
|
||||
}
|
||||
}
|
@ -42,7 +42,8 @@ public class RootJSONHandler extends TreePageHandler {
|
||||
ServerOverviewJSONHandler serverOverviewJSONHandler,
|
||||
OnlineActivityOverviewJSONHandler onlineActivityOverviewJSONHandler,
|
||||
SessionsOverviewJSONHandler sessionsOverviewJSONHandler,
|
||||
PlayerKillsJSONHandler playerKillsJSONHandler
|
||||
PlayerKillsJSONHandler playerKillsJSONHandler,
|
||||
PvPPvEJSONHandler pvppveJSONHandler
|
||||
) {
|
||||
super(responseFactory);
|
||||
|
||||
@ -53,6 +54,7 @@ public class RootJSONHandler extends TreePageHandler {
|
||||
registerPage("serverOverview", serverOverviewJSONHandler);
|
||||
registerPage("onlineOverview", onlineActivityOverviewJSONHandler);
|
||||
registerPage("sessionsOverview", sessionsOverviewJSONHandler);
|
||||
registerPage("playerVersus", pvppveJSONHandler);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -212,9 +212,9 @@ function loadPvPPvEValues(json, error) {
|
||||
$(element).find('#data_player_kills_30d').text(data.player_kills_30d);
|
||||
$(element).find('#data_player_kills_7d').text(data.player_kills_7d);
|
||||
|
||||
$(element).find('#data_player_deaths_total').text(data.player_deaths_total);
|
||||
$(element).find('#data_player_deaths_30d').text(data.player_deaths_30d);
|
||||
$(element).find('#data_player_deaths_7d').text(data.player_deaths_7d);
|
||||
$(element).find('#data_player_kdr_avg').text(data.player_kdr_avg);
|
||||
$(element).find('#data_player_kdr_avg_30d').text(data.player_kdr_avg_30d);
|
||||
$(element).find('#data_player_kdr_avg_7d').text(data.player_kdr_avg_7d);
|
||||
|
||||
$(element).find('#data_mob_kills_total').text(data.mob_kills_total);
|
||||
$(element).find('#data_mob_kills_30d').text(data.mob_kills_30d);
|
||||
@ -224,6 +224,10 @@ function loadPvPPvEValues(json, error) {
|
||||
$(element).find('#data_mob_deaths_30d').text(data.mob_deaths_30d);
|
||||
$(element).find('#data_mob_deaths_7d').text(data.mob_deaths_7d);
|
||||
|
||||
$(element).find('#data_mob_kdr_total').text(data.mob_kdr_total);
|
||||
$(element).find('#data_mob_kdr_30d').text(data.mob_kdr_30d);
|
||||
$(element).find('#data_mob_kdr_7d').text(data.mob_kdr_7d);
|
||||
|
||||
$(element).find('#data_deaths_total').text(data.deaths_total);
|
||||
$(element).find('#data_deaths_30d').text(data.deaths_30d);
|
||||
$(element).find('#data_deaths_7d').text(data.deaths_7d);
|
||||
@ -235,7 +239,6 @@ function loadPvPPvEValues(json, error) {
|
||||
$(element).find('#data_weapon_1st').text(data.weapon_1st);
|
||||
$(element).find('#data_weapon_2nd').text(data.weapon_2nd);
|
||||
$(element).find('#data_weapon_3rd').text(data.weapon_3rd);
|
||||
$(element).find('#data_rage_quits').text(data.rage_quits)
|
||||
}
|
||||
|
||||
/* This function loads Playerbase Overview tab */
|
||||
|
@ -600,20 +600,27 @@
|
||||
<th>Last 7 days</th>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td><b><i class="col-red fa fa-fw fa-crosshairs"></i></b> Average KDR / Player
|
||||
</td>
|
||||
<td id="data_player_kdr_avg"></td>
|
||||
<td id="data_player_kdr_avg_30d"></td>
|
||||
<td id="data_player_kdr_avg_7d"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><i class="col-red fa fa-fw fa-crosshairs"></i> Player Kills</td>
|
||||
<td id="data_player_kills_total"></td>
|
||||
<td id="data_player_kills_30d"></td>
|
||||
<td id="data_player_kills_7d"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><i class="col-red fa fa-fw fa-skull"></i> Player Caused Deaths</td>
|
||||
<td id="data_player_deaths_total"></td>
|
||||
<td id="data_player_deaths_30d"></td>
|
||||
<td id="data_player_deaths_7d"></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td><b><i class="col-green fa fa-fw fa-crosshairs"></i></b> Average Mob KDR</td>
|
||||
<td id="data_mob_kdr_total"></td>
|
||||
<td id="data_mob_kdr_30d"></td>
|
||||
<td id="data_mob_kdr_7d"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><i class="col-green fa fa-fw fa-crosshairs"></i> Mob Kills</td>
|
||||
<td id="data_mob_kills_total"></td>
|
||||
@ -653,8 +660,6 @@
|
||||
<span class="float-right"><b id="data_weapon_2nd"></b></span></p>
|
||||
<p><i class="col-brown fa fa-fw fa-khanda"></i> 3rd PvP Weapon
|
||||
<span class="float-right"><b id="data_weapon_3rd"></b></span></p>
|
||||
<p><i class="col-red fa fa-fw fa-skull"></i> Rage Quits
|
||||
<span class="float-right"><b id="data_rage_quits"></b></span></p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@ -1411,33 +1416,7 @@
|
||||
jsonRequest("../v1/serverOverview?serverName=${serverName}", loadServerOverviewValues);
|
||||
jsonRequest("../v1/onlineOverview?serverName=${serverName}", loadOnlineActivityOverviewValues);
|
||||
jsonRequest("../v1/sessionsOverview?serverName=${serverName}", loadSessionValues);
|
||||
loadPvPPvEValues(
|
||||
{
|
||||
numbers: {
|
||||
player_kills_total: 342,
|
||||
player_kills_30d: 234,
|
||||
player_kills_7d: 34,
|
||||
player_deaths_total: 40,
|
||||
player_deaths_30d: 34,
|
||||
player_deaths_7d: 32,
|
||||
mob_kills_total: 1232,
|
||||
mob_kills_30d: 332,
|
||||
mob_kills_7d: 32,
|
||||
mob_deaths_total: 34,
|
||||
mob_deaths_30d: 11,
|
||||
mob_deaths_7d: 5,
|
||||
deaths_total: 74,
|
||||
deaths_30d: 44,
|
||||
deaths_7d: 39
|
||||
},
|
||||
insights: {
|
||||
weapon_1st: 'Diamond Sword',
|
||||
weapon_2nd: 'Diamond Axe',
|
||||
weapon_3rd: 'Iron Sword',
|
||||
rage_quits: 4
|
||||
}
|
||||
}, null
|
||||
);
|
||||
jsonRequest("../v1/playerVersus?serverName=${serverName}", loadPvPPvEValues);
|
||||
loadPlayerbaseOverviewValues(
|
||||
{
|
||||
trends: {
|
||||
|
@ -48,6 +48,17 @@ 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/players`
|
||||
|
||||
Obtain data for `/server` player list.
|
||||
|
Loading…
Reference in New Issue
Block a user