mirror of
https://github.com/plan-player-analytics/Plan.git
synced 2024-11-20 09:35:47 +01:00
Implemented player kill endpoint
This commit is contained in:
parent
882b1a8b6a
commit
0b74d53918
@ -35,6 +35,7 @@ public class PlayerKill implements DateHolder {
|
||||
private final long date;
|
||||
|
||||
private String victimName;
|
||||
private String killerName;
|
||||
|
||||
/**
|
||||
* Creates a PlayerKill object with given parameters.
|
||||
@ -50,12 +51,15 @@ public class PlayerKill implements DateHolder {
|
||||
}
|
||||
|
||||
public PlayerKill(UUID victim, String weapon, long date, String victimName) {
|
||||
this.victim = victim;
|
||||
this.date = date;
|
||||
this.weapon = weapon;
|
||||
this(victim, weapon, date);
|
||||
this.victimName = victimName;
|
||||
}
|
||||
|
||||
public PlayerKill(UUID victim, String weapon, long date, String victimName, String killerName) {
|
||||
this(victim, weapon, date, victimName);
|
||||
this.killerName = killerName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the victim's UUID.
|
||||
*
|
||||
@ -69,6 +73,10 @@ public class PlayerKill implements DateHolder {
|
||||
return Optional.ofNullable(victimName);
|
||||
}
|
||||
|
||||
public Optional<String> getKillerName() {
|
||||
return Optional.ofNullable(killerName);
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getDate() {
|
||||
return date;
|
||||
|
@ -0,0 +1,52 @@
|
||||
/*
|
||||
* 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.data.store.mutators;
|
||||
|
||||
import com.djrapitops.plan.data.container.PlayerKill;
|
||||
import com.djrapitops.plan.utilities.formatting.Formatters;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* Mutator functions for {@link com.djrapitops.plan.data.container.PlayerKill} objects.
|
||||
*
|
||||
* @author Rsl1122
|
||||
*/
|
||||
public class PlayerKillMutator {
|
||||
|
||||
private final List<PlayerKill> kills;
|
||||
|
||||
public PlayerKillMutator(List<PlayerKill> kills) {
|
||||
this.kills = kills;
|
||||
}
|
||||
|
||||
public List<Map<String, Object>> toJSONAsMap(Formatters formatters) {
|
||||
return kills.stream().map(
|
||||
kill -> {
|
||||
Map<String, Object> killMap = new HashMap<>();
|
||||
killMap.put("date", formatters.secondLong().apply(kill.getDate()));
|
||||
killMap.put("victim", kill.getVictimName().orElse(kill.getVictim().toString()));
|
||||
killMap.put("killer", kill.getKillerName().orElse("Missing UUID")); // TODO Kills should support killer UUID
|
||||
killMap.put("weapon", kill.getWeapon());
|
||||
return killMap;
|
||||
}
|
||||
).collect(Collectors.toList());
|
||||
}
|
||||
}
|
@ -0,0 +1,87 @@
|
||||
/*
|
||||
* 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.db.access.queries.objects;
|
||||
|
||||
import com.djrapitops.plan.data.container.PlayerKill;
|
||||
import com.djrapitops.plan.db.access.Query;
|
||||
import com.djrapitops.plan.db.access.QueryStatement;
|
||||
import com.djrapitops.plan.db.sql.tables.KillsTable;
|
||||
import com.djrapitops.plan.db.sql.tables.UsersTable;
|
||||
|
||||
import java.sql.PreparedStatement;
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import java.util.UUID;
|
||||
|
||||
import static com.djrapitops.plan.db.sql.parsing.Sql.*;
|
||||
|
||||
/**
|
||||
* Queries for {@link com.djrapitops.plan.data.container.PlayerKill} and {@link com.djrapitops.plan.data.container.PlayerDeath} objects.
|
||||
*
|
||||
* @author Rsl1122
|
||||
*/
|
||||
public class PlayerKillQueries {
|
||||
|
||||
private PlayerKillQueries() {
|
||||
// Static method class
|
||||
}
|
||||
|
||||
public static Query<List<PlayerKill>> fetchMostRecentPlayerKills(UUID serverUUID, int limit) {
|
||||
String sql = SELECT + KillsTable.VICTIM_UUID + ", " +
|
||||
"v." + UsersTable.USER_NAME + " as victim_name, " +
|
||||
"k." + UsersTable.USER_NAME + " as killer_name," +
|
||||
KillsTable.DATE + ", " +
|
||||
KillsTable.WEAPON +
|
||||
FROM + KillsTable.TABLE_NAME +
|
||||
INNER_JOIN + UsersTable.TABLE_NAME + " v on v." + UsersTable.USER_UUID + "=" + KillsTable.VICTIM_UUID +
|
||||
INNER_JOIN + UsersTable.TABLE_NAME + " k on k." + UsersTable.USER_UUID + "=" + KillsTable.KILLER_UUID +
|
||||
WHERE + KillsTable.TABLE_NAME + '.' + KillsTable.SERVER_UUID + "=?" +
|
||||
ORDER_BY + KillsTable.DATE + " DESC LIMIT ?";
|
||||
|
||||
return new QueryStatement<List<PlayerKill>>(sql, limit) {
|
||||
@Override
|
||||
public void prepare(PreparedStatement statement) throws SQLException {
|
||||
statement.setString(1, serverUUID.toString());
|
||||
statement.setInt(2, limit);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<PlayerKill> processResults(ResultSet set) throws SQLException {
|
||||
List<PlayerKill> kills = new ArrayList<>();
|
||||
while (set.next()) {
|
||||
extractKillFromResults(set).ifPresent(kills::add);
|
||||
}
|
||||
return kills;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
private static Optional<PlayerKill> extractKillFromResults(ResultSet set) throws SQLException {
|
||||
String victimName = set.getString("victim_name");
|
||||
String killerName = set.getString("killer_name");
|
||||
if (victimName != null && killerName != null) {
|
||||
UUID victim = UUID.fromString(set.getString(KillsTable.VICTIM_UUID));
|
||||
long date = set.getLong(KillsTable.DATE);
|
||||
String weapon = set.getString(KillsTable.WEAPON);
|
||||
return Optional.of(new PlayerKill(victim, weapon, date, victimName, killerName));
|
||||
}
|
||||
return Optional.empty();
|
||||
}
|
||||
}
|
@ -16,10 +16,13 @@
|
||||
*/
|
||||
package com.djrapitops.plan.system.json;
|
||||
|
||||
import com.djrapitops.plan.data.container.PlayerKill;
|
||||
import com.djrapitops.plan.data.container.Session;
|
||||
import com.djrapitops.plan.data.store.mutators.PlayerKillMutator;
|
||||
import com.djrapitops.plan.data.store.mutators.SessionsMutator;
|
||||
import com.djrapitops.plan.db.Database;
|
||||
import com.djrapitops.plan.db.access.queries.containers.ServerPlayersTableContainersQuery;
|
||||
import com.djrapitops.plan.db.access.queries.objects.PlayerKillQueries;
|
||||
import com.djrapitops.plan.db.access.queries.objects.SessionQueries;
|
||||
import com.djrapitops.plan.extension.implementation.storage.queries.ExtensionServerPlayerDataTableQuery;
|
||||
import com.djrapitops.plan.system.database.DBSystem;
|
||||
@ -84,4 +87,10 @@ public class JSONFactory {
|
||||
));
|
||||
return new SessionsMutator(sessions).toPlayerJSONMaps(graphs, config.getWorldAliasSettings(), formatters);
|
||||
}
|
||||
|
||||
public List<Map<String, Object>> serverPlayerKillsAsJSONMap(UUID serverUUID) {
|
||||
Database db = dbSystem.getDatabase();
|
||||
List<PlayerKill> kills = db.query(PlayerKillQueries.fetchMostRecentPlayerKills(serverUUID, 100));
|
||||
return new PlayerKillMutator(kills).toJSONAsMap(formatters);
|
||||
}
|
||||
}
|
@ -0,0 +1,65 @@
|
||||
/*
|
||||
* 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.JSONFactory;
|
||||
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.Collections;
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
* Performs parameter parsing for PvP kills JSON requests.
|
||||
*
|
||||
* @author Rsl1122
|
||||
*/
|
||||
@Singleton
|
||||
public class PlayerKillsJSONHandler implements PageHandler {
|
||||
|
||||
private final Identifiers identifiers;
|
||||
private final JSONFactory jsonFactory;
|
||||
|
||||
@Inject
|
||||
public PlayerKillsJSONHandler(
|
||||
Identifiers identifiers,
|
||||
JSONFactory jsonFactory
|
||||
) {
|
||||
this.identifiers = identifiers;
|
||||
this.jsonFactory = jsonFactory;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Response getResponse(Request request, RequestTarget target) throws WebException {
|
||||
UUID serverUUID = identifiers.getServerUUID(target);
|
||||
return new JSONResponse<>(Collections.singletonMap("player_kills", jsonFactory.serverPlayerKillsAsJSONMap(serverUUID)));
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isAuthorized(Authentication auth, RequestTarget target) throws WebUserAuthException {
|
||||
return auth.getWebUser().getPermLevel() <= 0;
|
||||
}
|
||||
}
|
@ -41,12 +41,14 @@ public class RootJSONHandler extends TreePageHandler {
|
||||
PlayersTableJSONHandler playersTableJSONHandler,
|
||||
ServerOverviewJSONHandler serverOverviewJSONHandler,
|
||||
OnlineActivityOverviewJSONHandler onlineActivityOverviewJSONHandler,
|
||||
SessionsOverviewJSONHandler sessionsOverviewJSONHandler
|
||||
SessionsOverviewJSONHandler sessionsOverviewJSONHandler,
|
||||
PlayerKillsJSONHandler playerKillsJSONHandler
|
||||
) {
|
||||
super(responseFactory);
|
||||
|
||||
registerPage("players", playersTableJSONHandler);
|
||||
registerPage("sessions", sessionsJSONHandler);
|
||||
registerPage("kills", playerKillsJSONHandler);
|
||||
registerPage("graph", graphsJSONHandler);
|
||||
registerPage("serverOverview", serverOverviewJSONHandler);
|
||||
registerPage("onlineOverview", onlineActivityOverviewJSONHandler);
|
||||
|
@ -6,9 +6,12 @@ function loadSessionAccordion(json, error) {
|
||||
|
||||
sessionTable = $("#sessions-overview").find("#tableAccordion").find("tbody");
|
||||
|
||||
if (!sessionTable) throw new Error("Session table not found with ids #session-overview #tableAccordion");
|
||||
|
||||
var sessions = json.sessions;
|
||||
|
||||
if (!sessions.length) {
|
||||
sessionTable.append('<tr><td>No Sessions</td><td>-</td><td>-</td><td>-</td></tr>')
|
||||
}
|
||||
|
||||
for (var i = 0; i < sessions.length; i++) {
|
||||
var session = sessions[i];
|
||||
var title = createAccordionTitle(i, session);
|
||||
@ -24,6 +27,14 @@ function loadSessionAccordion(json, error) {
|
||||
}
|
||||
}
|
||||
|
||||
function loadPlayerKills(json, error) {
|
||||
if (error) {
|
||||
$('#playerKillTable').replaceWith('<p>Failed to load player kills: ' + error + '</p>');
|
||||
return;
|
||||
}
|
||||
$('#playerKillTable').replaceWith(createKillsTable(json.player_kills));
|
||||
}
|
||||
|
||||
function createAccordionTitle(i, session) {
|
||||
return '<tr aria-controls="session_t_' + i + '" aria-expanded="false" class="clickable collapsed bg-teal" data-target="#session_t_' + i + '" data-toggle="collapse"><td>'
|
||||
+ session.name + '</td>'
|
||||
@ -58,14 +69,14 @@ function createKillsTable(player_kills) {
|
||||
var table = '<table class="table table-striped scrollbar"><tbody>';
|
||||
|
||||
if (player_kills.length === 0) {
|
||||
table += '<td>No Kills</td><td>-</td><td>-</td>'
|
||||
table += '<tr><td>No Kills</td><td>-</td><td>-</td></tr>'
|
||||
}
|
||||
|
||||
for (var i = 0; i < player_kills.length; i++) {
|
||||
var kill = player_kills[i];
|
||||
table += '<td>' + kill.date + '</td>' +
|
||||
table += '<tr><td>' + kill.date + '</td>' +
|
||||
'<td>' + kill.killer + '<i class="fa fa-fw fa-angle-right col-red"></i>' + kill.victim + '</td>' +
|
||||
'<td>' + kill.weapon + '</td>'
|
||||
'<td>' + kill.weapon + '</td></tr>'
|
||||
}
|
||||
|
||||
table += '</tbody></table>';
|
||||
|
@ -670,19 +670,7 @@
|
||||
class="fas fa-fw fa-crosshairs col-red"></i>
|
||||
Recent Kills</h6>
|
||||
</div>
|
||||
<table class="table">
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>Today, 21:54</td>
|
||||
<td>Rsl1122 <i class="fa fa-fw fa-angle-right col-red"></i> Bill</td>
|
||||
<td>Diamond Sword</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Yesterday, 9:32</td>
|
||||
<td>Bill <i class="fa fa-fw fa-angle-right col-red"></i> Rsl1122</td>
|
||||
<td>Diamond Sword</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
<table class="table" id="playerKillTable">
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
@ -1766,6 +1754,8 @@
|
||||
})
|
||||
}
|
||||
});
|
||||
jsonRequest("../v1/kills?serverName=${serverName}", loadPlayerKills);
|
||||
|
||||
setLoadingText('Almost done..');
|
||||
var navButtons = document.getElementsByClassName("nav-button");
|
||||
var tabs = document.getElementsByClassName("tab");
|
||||
|
@ -70,6 +70,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/kills`
|
||||
|
||||
Obtain data for `/server` kills table. Returns 100 most recent kills.
|
||||
|
||||
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/graph`
|
||||
|
||||
Obtain data for graphs.
|
||||
|
Loading…
Reference in New Issue
Block a user