Kill & Death tables to player page

Affects issues:
- Close #918
This commit is contained in:
Rsl1122 2019-07-24 14:16:40 +03:00
parent f489264ca3
commit d7f5e18de3
8 changed files with 114 additions and 28 deletions

View File

@ -55,6 +55,9 @@ public class PlayerKeys {
public static final Key<WorldTimes> WORLD_TIMES = CommonKeys.WORLD_TIMES; public static final Key<WorldTimes> WORLD_TIMES = CommonKeys.WORLD_TIMES;
public static final Key<List<PlayerKill>> PLAYER_KILLS = CommonKeys.PLAYER_KILLS; public static final Key<List<PlayerKill>> PLAYER_KILLS = CommonKeys.PLAYER_KILLS;
public static final Key<List<PlayerKill>> PLAYER_DEATHS_KILLS = new Key<>(new Type<List<PlayerKill>>() {
}, "player_deaths_kills");
@Deprecated
public static final Key<List<PlayerDeath>> PLAYER_DEATHS = CommonKeys.PLAYER_DEATHS; public static final Key<List<PlayerDeath>> PLAYER_DEATHS = CommonKeys.PLAYER_DEATHS;
public static final Key<Integer> PLAYER_KILL_COUNT = CommonKeys.PLAYER_KILL_COUNT; public static final Key<Integer> PLAYER_KILL_COUNT = CommonKeys.PLAYER_KILL_COUNT;
public static final Key<Integer> MOB_KILL_COUNT = CommonKeys.MOB_KILL_COUNT; public static final Key<Integer> MOB_KILL_COUNT = CommonKeys.MOB_KILL_COUNT;

View File

@ -84,8 +84,8 @@ public class PlayerContainerQuery implements Query<PlayerContainer> {
}); });
container.putSupplier(PlayerKeys.LAST_SEEN, () -> SessionsMutator.forContainer(container).toLastSeen()); container.putSupplier(PlayerKeys.LAST_SEEN, () -> SessionsMutator.forContainer(container).toLastSeen());
container.putSupplier(PlayerKeys.PLAYER_KILLS, () -> db.query(KillQueries.fetchPlayerKillsOfPlayer(uuid)));
container.putSupplier(PlayerKeys.PLAYER_KILLS, () -> SessionsMutator.forContainer(container).toPlayerKillList()); container.putSupplier(PlayerKeys.PLAYER_DEATHS_KILLS, () -> db.query(KillQueries.fetchPlayerDeathsOfPlayer(uuid)));
container.putSupplier(PlayerKeys.PLAYER_DEATHS, () -> SessionsMutator.forContainer(container).toPlayerDeathList()); container.putSupplier(PlayerKeys.PLAYER_DEATHS, () -> SessionsMutator.forContainer(container).toPlayerDeathList());
container.putSupplier(PlayerKeys.PLAYER_KILL_COUNT, () -> container.getValue(PlayerKeys.PLAYER_KILLS).map(Collection::size).orElse(0)); container.putSupplier(PlayerKeys.PLAYER_KILL_COUNT, () -> container.getValue(PlayerKeys.PLAYER_KILLS).map(Collection::size).orElse(0));
container.putSupplier(PlayerKeys.MOB_KILL_COUNT, () -> SessionsMutator.forContainer(container).toMobKillCount()); container.putSupplier(PlayerKeys.MOB_KILL_COUNT, () -> SessionsMutator.forContainer(container).toMobKillCount());

View File

@ -44,7 +44,7 @@ public class KillQueries {
// Static method class // Static method class
} }
public static Query<List<PlayerKill>> fetchMostRecentPlayerKills(UUID serverUUID, int limit) { public static Query<List<PlayerKill>> fetchPlayerKillsOnServer(UUID serverUUID, int limit) {
String sql = SELECT + KillsTable.VICTIM_UUID + ", " + String sql = SELECT + KillsTable.VICTIM_UUID + ", " +
"v." + UsersTable.USER_NAME + " as victim_name, " + "v." + UsersTable.USER_NAME + " as victim_name, " +
"k." + UsersTable.USER_NAME + " as killer_name," + "k." + UsersTable.USER_NAME + " as killer_name," +
@ -74,6 +74,64 @@ public class KillQueries {
}; };
} }
public static Query<List<PlayerKill>> fetchPlayerKillsOfPlayer(UUID playerUUID) {
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.KILLER_UUID + "=?" +
ORDER_BY + KillsTable.DATE + " DESC";
return new QueryStatement<List<PlayerKill>>(sql, 100) {
@Override
public void prepare(PreparedStatement statement) throws SQLException {
statement.setString(1, playerUUID.toString());
}
@Override
public List<PlayerKill> processResults(ResultSet set) throws SQLException {
List<PlayerKill> kills = new ArrayList<>();
while (set.next()) {
extractKillFromResults(set).ifPresent(kills::add);
}
return kills;
}
};
}
public static Query<List<PlayerKill>> fetchPlayerDeathsOfPlayer(UUID playerUUID) {
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.VICTIM_UUID + "=?" +
ORDER_BY + KillsTable.DATE + " DESC";
return new QueryStatement<List<PlayerKill>>(sql, 100) {
@Override
public void prepare(PreparedStatement statement) throws SQLException {
statement.setString(1, playerUUID.toString());
}
@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 { private static Optional<PlayerKill> extractKillFromResults(ResultSet set) throws SQLException {
String victimName = set.getString("victim_name"); String victimName = set.getString("victim_name");
String killerName = set.getString("killer_name"); String killerName = set.getString("killer_name");
@ -185,7 +243,7 @@ public class KillQueries {
}; };
} }
public static Query<List<String>> topWeapons(long after, long before, UUID serverUUID, int limit) { public static Query<List<String>> topWeaponsOfServer(long after, long before, UUID serverUUID, int limit) {
String innerSQL = SELECT + KillsTable.WEAPON + ", COUNT(1) as kills" + String innerSQL = SELECT + KillsTable.WEAPON + ", COUNT(1) as kills" +
FROM + KillsTable.TABLE_NAME + FROM + KillsTable.TABLE_NAME +
WHERE + KillsTable.SERVER_UUID + "=?" + WHERE + KillsTable.SERVER_UUID + "=?" +
@ -213,4 +271,33 @@ public class KillQueries {
} }
}; };
} }
public static Query<List<String>> topWeaponsOfPlayer(long after, long before, UUID playerUUID, int limit) {
String innerSQL = SELECT + KillsTable.WEAPON + ", COUNT(1) as kills" +
FROM + KillsTable.TABLE_NAME +
WHERE + KillsTable.KILLER_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, playerUUID.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;
}
};
}
} }

View File

@ -89,7 +89,7 @@ public class JSONFactory {
public List<Map<String, Object>> serverPlayerKillsAsJSONMap(UUID serverUUID) { public List<Map<String, Object>> serverPlayerKillsAsJSONMap(UUID serverUUID) {
Database db = dbSystem.getDatabase(); Database db = dbSystem.getDatabase();
List<PlayerKill> kills = db.query(KillQueries.fetchMostRecentPlayerKills(serverUUID, 100)); List<PlayerKill> kills = db.query(KillQueries.fetchPlayerKillsOnServer(serverUUID, 100));
return new PlayerKillMutator(kills).toJSONAsMap(formatters); return new PlayerKillMutator(kills).toJSONAsMap(formatters);
} }
} }

View File

@ -89,7 +89,7 @@ public class PlayerJSONParser {
.map(geoInfo -> ConnectionInfo.fromGeoInfo(geoInfo, year)) .map(geoInfo -> ConnectionInfo.fromGeoInfo(geoInfo, year))
.orElse(Collections.emptyList())); .orElse(Collections.emptyList()));
data.put("player_kills", player.getValue(PlayerKeys.PLAYER_KILLS).orElse(Collections.emptyList())); data.put("player_kills", player.getValue(PlayerKeys.PLAYER_KILLS).orElse(Collections.emptyList()));
data.put("player_deaths", player.getValue(PlayerKeys.PLAYER_DEATHS).orElse(Collections.emptyList())); data.put("player_deaths", player.getValue(PlayerKeys.PLAYER_DEATHS_KILLS).orElse(Collections.emptyList()));
data.put("sessions", sessionsMutator.toServerNameJSONMaps(graphs, config.getWorldAliasSettings(), formatters)); data.put("sessions", sessionsMutator.toServerNameJSONMaps(graphs, config.getWorldAliasSettings(), formatters));
data.put("punchcard_series", graphs.special().punchCard(sessionsMutator).getDots()); data.put("punchcard_series", graphs.special().punchCard(sessionsMutator).getDots());
WorldPie worldPie = graphs.pie().worldPie(player.getValue(PlayerKeys.WORLD_TIMES).orElse(new WorldTimes())); WorldPie worldPie = graphs.pie().worldPie(player.getValue(PlayerKeys.WORLD_TIMES).orElse(new WorldTimes()));

View File

@ -110,7 +110,7 @@ public class PvPPvEJSONParser implements TabJSONParser<Map<String, Object>> {
Map<String, Object> insights = new HashMap<>(); Map<String, Object> insights = new HashMap<>();
List<String> top3Weapons = db.query(KillQueries.topWeapons(monthAgo, now, serverUUID, 3)); List<String> top3Weapons = db.query(KillQueries.topWeaponsOfPlayer(monthAgo, now, serverUUID, 3));
insights.put("weapon_1st", getWeapon(top3Weapons, 0).orElse("-")); insights.put("weapon_1st", getWeapon(top3Weapons, 0).orElse("-"));
insights.put("weapon_2nd", getWeapon(top3Weapons, 1).orElse("-")); insights.put("weapon_2nd", getWeapon(top3Weapons, 1).orElse("-"));
insights.put("weapon_3rd", getWeapon(top3Weapons, 2).orElse("-")); insights.put("weapon_3rd", getWeapon(top3Weapons, 2).orElse("-"));

View File

@ -35,6 +35,14 @@ function loadPlayerKills(json, error) {
$('#playerKillTable').replaceWith(createKillsTable(json.player_kills)); $('#playerKillTable').replaceWith(createKillsTable(json.player_kills));
} }
function loadPlayerDeaths(json, error) {
if (error) {
$('#playerDeathTable').replaceWith('<p>Failed to load player deaths: ' + error + '</p>');
return;
}
$('#playerDeathTable').replaceWith(createKillsTable(json.player_deaths));
}
function createAccordionTitle(i, session) { 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>' 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>' + session.name + '</td>'
@ -66,10 +74,10 @@ function createAccordionBody(i, session) {
} }
function createKillsTable(player_kills) { function createKillsTable(player_kills) {
var table = '<table class="table table-striped scrollbar"><tbody>'; var table = '<table class="table scrollbar"><tbody>';
if (player_kills.length === 0) { if (player_kills.length === 0) {
table += '<tr><td>No Kills</td><td>-</td><td>-</td></tr>' table += '<tr><td>None</td><td>-</td><td>-</td></tr>'
} }
for (var i = 0; i < player_kills.length; i++) { for (var i = 0; i < player_kills.length; i++) {

View File

@ -501,15 +501,7 @@
class="fas fa-fw fa-crosshairs col-red"></i> class="fas fa-fw fa-crosshairs col-red"></i>
Recent PvP Kills</h6> Recent PvP Kills</h6>
</div> </div>
<table class="table"> <table class="table" id="playerKillTable"></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>
</tbody>
</table>
</div> </div>
</div> </div>
<!-- Most Recent Deaths --> <!-- Most Recent Deaths -->
@ -521,15 +513,7 @@
class="fas fa-fw fa-skull col-red"></i> class="fas fa-fw fa-skull col-red"></i>
Recent PvP Deaths</h6> Recent PvP Deaths</h6>
</div> </div>
<table class="table"> <table class="table" id="playerDeathTable"></table>
<tbody>
<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>
</div> </div>
</div> </div>
</div> </div>
@ -1316,6 +1300,8 @@
jsonRequest("../v1/player?player=${playerName}", function (json, error) { jsonRequest("../v1/player?player=${playerName}", function (json, error) {
loadPlayerOverviewValues(json, error); loadPlayerOverviewValues(json, error);
loadSessionAccordion(json, error); loadSessionAccordion(json, error);
loadPlayerKills(json, error);
loadPlayerDeaths(json, error);
if (json) { if (json) {
var series = { var series = {
worldPie: { worldPie: {
@ -1334,7 +1320,9 @@
worldPie("worldPie", series.worldPie, series.worldPieGMs); worldPie("worldPie", series.worldPie, series.worldPieGMs);
sessionCalendar("#sessionCalendar", json.calendar_series, json.first_day); sessionCalendar("#sessionCalendar", json.calendar_series, json.first_day);
} else if (error) { } else if (error) {
$('#punchCard').text("Failed to load graph data: " + error) $('#punchCard').text("Failed to load graph data: " + error);
$('#worldPie').text("Failed to load graph data: " + error);
$('#sessionCalendar').text("Failed to load calendar data: " + error)
} }
}); });
setLoadingText('Rendering graphs..'); setLoadingText('Rendering graphs..');