Added average ping to sessions on /player page

- This might increase memory usage when viewing player page by a little
- This might increase time it takes to get player page json
- 'avg_ping' is not always present for a session

Affects issues:
- Close #864
This commit is contained in:
Rsl1122 2019-11-07 13:41:53 +02:00
parent 4bcf2141d9
commit cafcb61cf5
6 changed files with 104 additions and 5 deletions

View File

@ -57,6 +57,7 @@ public class SessionKeys {
*/
@Deprecated
public static final Key<String> LONGEST_WORLD_PLAYED = new Key<>(String.class, "longest_world_played");
public static final Key<Double> AVERAGE_PING = new Key<>(Double.class, "averagePing");
private SessionKeys() {
/* Static variable class */

View File

@ -16,14 +16,15 @@
*/
package com.djrapitops.plan.delivery.domain.mutators;
import com.djrapitops.plan.delivery.domain.DateHolder;
import com.djrapitops.plan.delivery.domain.container.DataContainer;
import com.djrapitops.plan.delivery.domain.keys.CommonKeys;
import com.djrapitops.plan.delivery.domain.keys.SessionKeys;
import com.djrapitops.plan.gathering.domain.Ping;
import com.djrapitops.plan.gathering.domain.Session;
import com.djrapitops.plan.utilities.comparators.DateHolderOldestComparator;
import java.util.Collections;
import java.util.List;
import java.util.SortedMap;
import java.util.UUID;
import java.util.*;
import java.util.function.Predicate;
import java.util.stream.Collectors;
@ -60,6 +61,52 @@ public class PingMutator {
}).collect(Collectors.toList()));
}
public static Map<UUID, SortedMap<Long, Ping>> sortByServers(List<Ping> pings) {
Map<UUID, SortedMap<Long, Ping>> sorted = new HashMap<>();
for (Ping ping : pings) {
UUID serverUUID = ping.getServerUUID();
SortedMap<Long, Ping> serverSessions = sorted.getOrDefault(serverUUID, new TreeMap<>());
serverSessions.put(ping.getDate(), ping);
sorted.put(serverUUID, serverSessions);
}
return sorted;
}
public void addPingToSessions(List<Session> sessions) {
if (sessions.isEmpty()) return;
Comparator<DateHolder> comparator = new DateHolderOldestComparator();
sessions.sort(comparator);
pings.sort(comparator);
Map<UUID, SortedMap<Long, Ping>> pingByServer = sortByServers(pings);
Map<UUID, List<Session>> sessionsByServer = SessionsMutator.sortByServers(sessions);
for (Map.Entry<UUID, SortedMap<Long, Ping>> entry : pingByServer.entrySet()) {
UUID serverUUID = entry.getKey();
SortedMap<Long, Ping> pingOfServer = entry.getValue();
if (pingOfServer.isEmpty()) continue;
List<Session> sessionsOfServer = sessionsByServer.getOrDefault(serverUUID, Collections.emptyList());
double pingCount = 0.0;
int pingEntries = 0;
for (Session session : sessionsOfServer) {
long start = session.getDate();
Long end = session.getValue(SessionKeys.END).orElseGet(System::currentTimeMillis);
// Calcuclate average ping for each session with a Ping submap
SortedMap<Long, Ping> duringSession = pingOfServer.subMap(start, end);
for (Ping ping : duringSession.values()) {
pingCount += ping.getAverage();
pingEntries++;
}
if (pingEntries != 0) {
session.putRawData(SessionKeys.AVERAGE_PING, pingCount / pingEntries);
}
pingCount = 0.0;
pingEntries = 0;
}
}
}
public List<Ping> all() {
return pings;
}

View File

@ -210,6 +210,17 @@ public class SessionsMutator {
return sorted;
}
public static Map<UUID, TreeMap<Long, Session>> sortByServersToMaps(List<Session> sessions) {
Map<UUID, TreeMap<Long, Session>> sorted = new HashMap<>();
for (Session session : sessions) {
UUID serverUUID = session.getUnsafe(SessionKeys.SERVER_UUID);
TreeMap<Long, Session> serverSessions = sorted.getOrDefault(serverUUID, new TreeMap<>());
serverSessions.put(session.getDate(), session);
sorted.put(serverUUID, serverSessions);
}
return sorted;
}
public int toPlayerDeathCount() {
return sessions.stream().mapToInt(session -> session.getValue(SessionKeys.DEATH_COUNT).orElse(0)).sum();
}
@ -281,6 +292,10 @@ public class SessionsMutator {
WorldPie worldPie = graphs.pie().worldPie(session.getValue(SessionKeys.WORLD_TIMES).orElse(new WorldTimes()));
sessionMap.put("world_series", worldPie.getSlices());
sessionMap.put("gm_series", worldPie.toHighChartsDrillDownMaps());
session.getValue(SessionKeys.AVERAGE_PING).ifPresent(averagePing ->
sessionMap.put("avg_ping", formatters.decimals().apply(averagePing) + " ms")
);
return sessionMap;
}).collect(Collectors.toList());
}

View File

@ -96,6 +96,8 @@ public class PlayerJSONParser {
List<PlayerKill> kills = player.getValue(PlayerKeys.PLAYER_KILLS).orElse(Collections.emptyList());
List<PlayerKill> deaths = player.getValue(PlayerKeys.PLAYER_DEATHS_KILLS).orElse(Collections.emptyList());
PingMutator.forContainer(player).addPingToSessions(sessionsMutator.all());
Map<String, Object> data = new HashMap<>();
data.put("info", createInfoJSONMap(player, serverNames));
data.put("online_activity", createOnlineActivityJSONMap(sessionsMutator));

View File

@ -0,0 +1,32 @@
/*
* 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.utilities.comparators;
import com.djrapitops.plan.delivery.domain.DateHolder;
/**
* Compares DateHolder objects so that most recent is last.
*
* @author Rsl1122
*/
public class DateHolderOldestComparator extends DateHolderRecentComparator {
@Override
public int compare(DateHolder one, DateHolder two) {
return -super.compare(one, two);
}
}

View File

@ -81,7 +81,9 @@ function createAccordionBody(i, session) {
'<p><i class="col-teal far fa-fw fa-clock"></i> Ended<span class="float-right"><b>' + session.end + '</b></span></p>' +
'<p><i class="col-green far fa-fw fa-clock"></i> Length<span class="float-right"><b>' + session.length + '</b></span></p>' +
'<p><i class="col-grey far fa-fw fa-clock"></i> AFK Time<span class="float-right"><b>' + session.afk_time + '</b></span></p>' +
'<p><i class="col-green fa fa-fw fa-server"></i> Server<span class="float-right"><b>' + session.server_name + '</b></span></p><br>' +
'<p><i class="col-green fa fa-fw fa-server"></i> Server<span class="float-right"><b>' + session.server_name + '</b></span></p>' +
(session.avg_ping ? '<p><i class="col-amber fa fa-fw fa-signal"></i> Average Ping<span class="float-right"><b>' + session.avg_ping + '</b></span></p>' : '') +
'<br>' +
'<p><i class="col-red fa fa-fw fa-crosshairs"></i> Player Kills<span class="float-right"><b>' + session.player_kills.length + '</b></span></p>' +
'<p><i class="col-green fa fa-fw fa-crosshairs"></i> Mob Kills<span class="float-right"><b>' + session.mob_kills + '</b></span></p>' +
'<p><i class=" fa fa-fw fa-skull"></i> Deaths<span class="float-right"><b>' + session.deaths + '</b></span></p><hr>' +