mirror of
https://github.com/plan-player-analytics/Plan.git
synced 2024-10-27 13:59:56 +01:00
Player counts
This commit is contained in:
parent
ad55ed338e
commit
7e420aaf91
@ -130,9 +130,8 @@ public class Session extends DataContainer implements DateHolder {
|
||||
*
|
||||
* @return Long in ms.
|
||||
*/
|
||||
@Deprecated
|
||||
public long getLength() {
|
||||
return getUnsafe(SessionKeys.LENGTH);
|
||||
return getValue(SessionKeys.LENGTH).orElse(0L);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -132,14 +132,58 @@ public class AnalysisContainer extends DataContainer {
|
||||
putSupplier(AnalysisKeys.PLAYERS_TABLE, () ->
|
||||
PlayersTable.forServerPage(getUnsafe(AnalysisKeys.PLAYERS_MUTATOR).all()).parseHtml()
|
||||
);
|
||||
|
||||
newAndUniquePlayerCounts();
|
||||
}
|
||||
|
||||
private void newAndUniquePlayerCounts() {
|
||||
Key<PlayersMutator> newDay = new Key<>(PlayersMutator.class, "NEW_DAY");
|
||||
Key<PlayersMutator> newWeek = new Key<>(PlayersMutator.class, "NEW_WEEK");
|
||||
Key<PlayersMutator> newMonth = new Key<>(PlayersMutator.class, "NEW_MONTH");
|
||||
Key<PlayersMutator> uniqueDay = new Key<>(PlayersMutator.class, "NEW_DAY");
|
||||
Key<PlayersMutator> uniqueWeek = new Key<>(PlayersMutator.class, "NEW_WEEK");
|
||||
Key<PlayersMutator> uniqueMonth = new Key<>(PlayersMutator.class, "NEW_MONTH");
|
||||
putSupplier(newDay, () -> PlayersMutator.copyOf(getUnsafe(AnalysisKeys.PLAYERS_MUTATOR))
|
||||
.filterRegisteredBetween(getUnsafe(AnalysisKeys.ANALYSIS_TIME_DAY_AGO), getUnsafe(AnalysisKeys.ANALYSIS_TIME))
|
||||
);
|
||||
putSupplier(newWeek, () -> PlayersMutator.copyOf(getUnsafe(AnalysisKeys.PLAYERS_MUTATOR))
|
||||
.filterRegisteredBetween(getUnsafe(AnalysisKeys.ANALYSIS_TIME_WEEK_AGO), getUnsafe(AnalysisKeys.ANALYSIS_TIME))
|
||||
);
|
||||
putSupplier(newMonth, () -> PlayersMutator.copyOf(getUnsafe(AnalysisKeys.PLAYERS_MUTATOR))
|
||||
.filterRegisteredBetween(getUnsafe(AnalysisKeys.ANALYSIS_TIME_MONTH_AGO), getUnsafe(AnalysisKeys.ANALYSIS_TIME))
|
||||
);
|
||||
putSupplier(uniqueDay, () -> PlayersMutator.copyOf(getUnsafe(AnalysisKeys.PLAYERS_MUTATOR))
|
||||
.filterRegisteredBetween(getUnsafe(AnalysisKeys.ANALYSIS_TIME_DAY_AGO), getUnsafe(AnalysisKeys.ANALYSIS_TIME))
|
||||
);
|
||||
putSupplier(uniqueWeek, () -> PlayersMutator.copyOf(getUnsafe(AnalysisKeys.PLAYERS_MUTATOR))
|
||||
.filterRegisteredBetween(getUnsafe(AnalysisKeys.ANALYSIS_TIME_WEEK_AGO), getUnsafe(AnalysisKeys.ANALYSIS_TIME))
|
||||
);
|
||||
putSupplier(uniqueMonth, () -> PlayersMutator.copyOf(getUnsafe(AnalysisKeys.PLAYERS_MUTATOR))
|
||||
.filterRegisteredBetween(getUnsafe(AnalysisKeys.ANALYSIS_TIME_MONTH_AGO), getUnsafe(AnalysisKeys.ANALYSIS_TIME))
|
||||
);
|
||||
|
||||
putSupplier(AnalysisKeys.PLAYERS_NEW_DAY, () -> getUnsafe(newDay).count());
|
||||
putSupplier(AnalysisKeys.PLAYERS_NEW_WEEK, () -> getUnsafe(newWeek).count());
|
||||
putSupplier(AnalysisKeys.PLAYERS_NEW_MONTH, () -> getUnsafe(newMonth).count());
|
||||
putSupplier(AnalysisKeys.PLAYERS_DAY, () -> getUnsafe(uniqueDay).count());
|
||||
putSupplier(AnalysisKeys.PLAYERS_WEEK, () -> getUnsafe(uniqueWeek).count());
|
||||
putSupplier(AnalysisKeys.PLAYERS_MONTH, () -> getUnsafe(uniqueMonth).count());
|
||||
putSupplier(AnalysisKeys.AVG_PLAYERS_NEW, () -> getUnsafe(AnalysisKeys.PLAYERS_MUTATOR).newPerDay());
|
||||
putSupplier(AnalysisKeys.AVG_PLAYERS_NEW_DAY, () -> getUnsafe(uniqueDay).newPerDay());
|
||||
putSupplier(AnalysisKeys.AVG_PLAYERS_NEW_WEEK, () -> getUnsafe(uniqueWeek).newPerDay());
|
||||
putSupplier(AnalysisKeys.AVG_PLAYERS_NEW_MONTH, () -> getUnsafe(uniqueMonth).newPerDay());
|
||||
}
|
||||
|
||||
private void addSessionSuppliers() {
|
||||
putSupplier(AnalysisKeys.SESSION_ACCORDION, () -> SessionAccordion.forServer(
|
||||
Key<SessionAccordion> sessionAccordion = new Key<>(SessionAccordion.class, "SESSION_ACCORDION");
|
||||
putSupplier(sessionAccordion, () -> SessionAccordion.forServer(
|
||||
getUnsafe(AnalysisKeys.SESSIONS_MUTATOR).all(),
|
||||
() -> Database.getActive().fetch().getServerNames(),
|
||||
() -> getUnsafe(AnalysisKeys.PLAYER_NAMES)
|
||||
));
|
||||
putSupplier(AnalysisKeys.SESSION_ACCORDION_HTML, () -> getUnsafe(sessionAccordion).toHtml());
|
||||
putSupplier(AnalysisKeys.SESSION_ACCORDION_FUNCTIONS, () -> getUnsafe(sessionAccordion).toViewScript());
|
||||
|
||||
putSupplier(AnalysisKeys.RECENT_LOGINS, () -> new RecentLoginList(
|
||||
serverContainer.getValue(ServerKeys.PLAYERS).orElse(new ArrayList<>())
|
||||
).toHtml()
|
||||
@ -147,8 +191,6 @@ public class AnalysisContainer extends DataContainer {
|
||||
putSupplier(AnalysisKeys.SESSION_TABLE, () -> new ServerSessionTable(
|
||||
getUnsafe(AnalysisKeys.PLAYER_NAMES), getUnsafe(AnalysisKeys.SESSIONS_MUTATOR).all()).parseHtml()
|
||||
);
|
||||
putSupplier(AnalysisKeys.SESSION_ACCORDION_HTML, () -> getUnsafe(AnalysisKeys.SESSION_ACCORDION).toHtml());
|
||||
putSupplier(AnalysisKeys.SESSION_ACCORDION_FUNCTIONS, () -> getUnsafe(AnalysisKeys.SESSION_ACCORDION).toViewScript());
|
||||
|
||||
putSupplier(AnalysisKeys.AVERAGE_SESSION_LENGTH_F, () -> Formatters.timeAmount()
|
||||
.apply(getUnsafe(AnalysisKeys.SESSIONS_MUTATOR).toAverageSessionLength())
|
||||
@ -167,13 +209,25 @@ public class AnalysisContainer extends DataContainer {
|
||||
putSupplier(AnalysisKeys.AVERAGE_SESSION_LENGTH_F, () -> Formatters.timeAmount()
|
||||
.apply(getUnsafe(AnalysisKeys.SESSIONS_MUTATOR).toAverageSessionLength())
|
||||
);
|
||||
putSupplier(AnalysisKeys.PUNCHCARD_SERIES, () -> new PunchCardGraph(
|
||||
SessionsMutator.copyOf(getUnsafe(AnalysisKeys.SESSIONS_MUTATOR)
|
||||
.filterSessionsBetween(
|
||||
getUnsafe(AnalysisKeys.ANALYSIS_TIME_MONTH_AGO),
|
||||
getUnsafe(AnalysisKeys.ANALYSIS_TIME))
|
||||
).all()).toHighChartsSeries()
|
||||
|
||||
Key<SessionsMutator> sessionsDay = new Key<>(SessionsMutator.class, "SESSIONS_DAY");
|
||||
Key<SessionsMutator> sessionsWeek = new Key<>(SessionsMutator.class, "SESSIONS_WEEK");
|
||||
Key<SessionsMutator> sessionsMonth = new Key<>(SessionsMutator.class, "SESSIONS_MONTH");
|
||||
putSupplier(sessionsDay, () -> SessionsMutator.copyOf(getUnsafe(AnalysisKeys.SESSIONS_MUTATOR))
|
||||
.filterSessionsBetween(getUnsafe(AnalysisKeys.ANALYSIS_TIME_DAY_AGO), getUnsafe(AnalysisKeys.ANALYSIS_TIME))
|
||||
);
|
||||
putSupplier(sessionsWeek, () -> SessionsMutator.copyOf(getUnsafe(AnalysisKeys.SESSIONS_MUTATOR))
|
||||
.filterSessionsBetween(getUnsafe(AnalysisKeys.ANALYSIS_TIME_WEEK_AGO), getUnsafe(AnalysisKeys.ANALYSIS_TIME))
|
||||
);
|
||||
putSupplier(sessionsMonth, () -> SessionsMutator.copyOf(getUnsafe(AnalysisKeys.SESSIONS_MUTATOR))
|
||||
.filterSessionsBetween(getUnsafe(AnalysisKeys.ANALYSIS_TIME_MONTH_AGO), getUnsafe(AnalysisKeys.ANALYSIS_TIME))
|
||||
);
|
||||
|
||||
putSupplier(AnalysisKeys.PUNCHCARD_SERIES, () -> new PunchCardGraph(getUnsafe(sessionsMonth).all()).toHighChartsSeries());
|
||||
putSupplier(AnalysisKeys.AVG_PLAYERS, () -> getUnsafe(AnalysisKeys.SESSIONS_MUTATOR).toUniqueJoinsPerDay());
|
||||
putSupplier(AnalysisKeys.AVG_PLAYERS_DAY, () -> getUnsafe(sessionsDay).toUniqueJoinsPerDay());
|
||||
putSupplier(AnalysisKeys.AVG_PLAYERS_WEEK, () -> getUnsafe(sessionsWeek).toUniqueJoinsPerDay());
|
||||
putSupplier(AnalysisKeys.AVG_PLAYERS_MONTH, () -> getUnsafe(sessionsMonth).toUniqueJoinsPerDay());
|
||||
}
|
||||
|
||||
private void addGraphSuppliers() {
|
||||
|
@ -6,7 +6,6 @@ import com.djrapitops.plan.data.store.Type;
|
||||
import com.djrapitops.plan.data.store.mutators.PlayersMutator;
|
||||
import com.djrapitops.plan.data.store.mutators.SessionsMutator;
|
||||
import com.djrapitops.plan.data.store.mutators.TPSMutator;
|
||||
import com.djrapitops.plan.utilities.html.structure.SessionAccordion;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
@ -136,7 +135,6 @@ public class AnalysisKeys {
|
||||
public static final Key<Long> ANALYSIS_TIME_DAY_AGO = new Key<>(Long.class, "ANALYSIS_TIME_DAY_AGO");
|
||||
public static final Key<Long> ANALYSIS_TIME_WEEK_AGO = new Key<>(Long.class, "ANALYSIS_TIME_WEEK_AGO");
|
||||
public static final Key<Long> ANALYSIS_TIME_MONTH_AGO = new Key<>(Long.class, "ANALYSIS_TIME_MONTH_AGO");
|
||||
public static final Key<SessionAccordion> SESSION_ACCORDION = new Key<>(SessionAccordion.class, "SESSION_ACCORDION");
|
||||
public static final Key<Map<UUID, String>> PLAYER_NAMES = new Key<>(new Type<Map<UUID, String>>() {}, "PLAYER_NAMES");
|
||||
public static final Key<TreeMap<Long, Map<String, Set<UUID>>>> ACTIVITY_DATA = new Key<>(new Type<TreeMap<Long, Map<String, Set<UUID>>>>() {}, "ACTIVITY_DATA");
|
||||
|
||||
|
@ -6,9 +6,13 @@ import com.djrapitops.plan.data.store.containers.DataContainer;
|
||||
import com.djrapitops.plan.data.store.containers.PlayerContainer;
|
||||
import com.djrapitops.plan.data.store.keys.PlayerKeys;
|
||||
import com.djrapitops.plan.data.store.keys.ServerKeys;
|
||||
import com.djrapitops.plan.data.store.keys.SessionKeys;
|
||||
import com.djrapitops.plan.data.store.mutators.formatting.Formatters;
|
||||
import com.djrapitops.plugin.api.TimeAmount;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.function.Function;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* Mutator for a bunch of {@link com.djrapitops.plan.data.store.containers.PlayerContainer}s.
|
||||
@ -31,10 +35,37 @@ public class PlayersMutator {
|
||||
return new PlayersMutator(container.getValue(ServerKeys.PLAYERS).orElse(new ArrayList<>()));
|
||||
}
|
||||
|
||||
public PlayersMutator filterPlayedBetween(long after, long before) {
|
||||
players = players.stream().filter(player ->
|
||||
player.getValue(PlayerKeys.SESSIONS)
|
||||
.map(sessions -> sessions.stream().anyMatch(session -> {
|
||||
long start = session.getValue(SessionKeys.START).orElse(-1L);
|
||||
long end = session.getValue(SessionKeys.END).orElse(-1L);
|
||||
return (after <= start && start <= before) || (after <= end && end <= before);
|
||||
})).orElse(false)
|
||||
).collect(Collectors.toList());
|
||||
return this;
|
||||
}
|
||||
|
||||
public PlayersMutator filterRegisteredBetween(long after, long before) {
|
||||
players = players.stream().filter(player ->
|
||||
player.getValue(PlayerKeys.REGISTERED).map(date -> after <= date && date <= before).orElse(false)
|
||||
).collect(Collectors.toList());
|
||||
return this;
|
||||
}
|
||||
|
||||
public List<PlayerContainer> all() {
|
||||
return players;
|
||||
}
|
||||
|
||||
public List<Long> registerDates() {
|
||||
List<Long> registerDates = new ArrayList<>();
|
||||
for (PlayerContainer player : players) {
|
||||
registerDates.add(player.getValue(PlayerKeys.REGISTERED).orElse(-1L));
|
||||
}
|
||||
return registerDates;
|
||||
}
|
||||
|
||||
public List<String> getGeolocations() {
|
||||
List<String> geolocations = new ArrayList<>();
|
||||
|
||||
@ -64,4 +95,26 @@ public class PlayersMutator {
|
||||
}
|
||||
return activityData;
|
||||
}
|
||||
|
||||
public int count() {
|
||||
return players.size();
|
||||
}
|
||||
|
||||
public int newPerDay() {
|
||||
List<Long> registerDates = registerDates();
|
||||
int total = 0;
|
||||
Function<Long, Integer> formatter = Formatters.dayOfYear();
|
||||
Set<Integer> days = new HashSet<>();
|
||||
for (Long date : registerDates) {
|
||||
int day = formatter.apply(date);
|
||||
days.add(day);
|
||||
total++;
|
||||
}
|
||||
int numberOfDays = days.size();
|
||||
|
||||
if (numberOfDays == 0) {
|
||||
return 0;
|
||||
}
|
||||
return total / numberOfDays;
|
||||
}
|
||||
}
|
@ -4,9 +4,13 @@ import com.djrapitops.plan.data.container.PlayerKill;
|
||||
import com.djrapitops.plan.data.container.Session;
|
||||
import com.djrapitops.plan.data.store.containers.DataContainer;
|
||||
import com.djrapitops.plan.data.store.keys.CommonKeys;
|
||||
import com.djrapitops.plan.data.store.keys.SessionKeys;
|
||||
import com.djrapitops.plan.data.store.mutators.formatting.Formatters;
|
||||
import com.djrapitops.plan.data.time.WorldTimes;
|
||||
import com.djrapitops.plan.utilities.analysis.MathUtils;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.function.Function;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
@ -38,7 +42,8 @@ public class SessionsMutator {
|
||||
|
||||
public SessionsMutator filterSessionsBetween(long after, long before) {
|
||||
sessions = sessions.stream()
|
||||
.filter(session -> session.getSessionEnd() >= after && session.getSessionStart() <= before)
|
||||
.filter(session -> after <= session.getValue(SessionKeys.END).orElse(System.currentTimeMillis())
|
||||
&& session.getUnsafe(SessionKeys.START) <= before)
|
||||
.collect(Collectors.toList());
|
||||
return this;
|
||||
}
|
||||
@ -47,8 +52,7 @@ public class SessionsMutator {
|
||||
WorldTimes total = new WorldTimes(new HashMap<>());
|
||||
|
||||
for (Session session : sessions) {
|
||||
WorldTimes worldTimes = session.getWorldTimes();
|
||||
total.add(worldTimes);
|
||||
session.getValue(SessionKeys.WORLD_TIMES).ifPresent(total::add);
|
||||
}
|
||||
|
||||
return total;
|
||||
@ -56,20 +60,20 @@ public class SessionsMutator {
|
||||
|
||||
public List<PlayerKill> toPlayerKillList() {
|
||||
return sessions.stream()
|
||||
.map(Session::getPlayerKills)
|
||||
.map(session -> session.getValue(SessionKeys.PLAYER_KILLS).orElse(new ArrayList<>()))
|
||||
.flatMap(Collection::stream)
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
public int toMobKillCount() {
|
||||
return sessions.stream()
|
||||
.mapToInt(Session::getMobKills)
|
||||
.mapToInt(session -> session.getValue(SessionKeys.MOB_KILL_COUNT).orElse(0))
|
||||
.sum();
|
||||
}
|
||||
|
||||
public int toDeathCount() {
|
||||
return sessions.stream()
|
||||
.mapToInt(Session::getDeaths)
|
||||
.mapToInt(session -> session.getValue(SessionKeys.DEATH_COUNT).orElse(0))
|
||||
.sum();
|
||||
}
|
||||
|
||||
@ -81,20 +85,22 @@ public class SessionsMutator {
|
||||
|
||||
public long toAfkTime() {
|
||||
return sessions.stream()
|
||||
.mapToLong(Session::getAfkLength)
|
||||
.mapToLong(session -> session.getValue(SessionKeys.AFK_TIME).orElse(0L))
|
||||
.sum();
|
||||
}
|
||||
|
||||
public long toActivePlaytime() {
|
||||
return sessions.stream()
|
||||
.mapToLong(Session::getActiveLength)
|
||||
.mapToLong(session -> session.getValue(SessionKeys.ACTIVE_TIME).orElse(0L))
|
||||
.sum();
|
||||
}
|
||||
|
||||
public long toLastSeen() {
|
||||
return sessions.stream()
|
||||
.mapToLong(session -> Math.max(session.getSessionStart(), session.getSessionEnd()))
|
||||
.max().orElse(-1);
|
||||
.mapToLong(session -> Math.max(session.getUnsafe(
|
||||
SessionKeys.START),
|
||||
session.getValue(SessionKeys.END).orElse(System.currentTimeMillis()))
|
||||
).max().orElse(-1);
|
||||
}
|
||||
|
||||
public long toLongestSessionLength() {
|
||||
@ -125,6 +131,32 @@ public class SessionsMutator {
|
||||
return sessionLengths.get(sessionLengths.size() / 2);
|
||||
}
|
||||
|
||||
public int toUniqueJoinsPerDay() {
|
||||
Map<Integer, Set<UUID>> uniqueJoins = new HashMap<>();
|
||||
Function<Long, Integer> function = Formatters.dayOfYear();
|
||||
|
||||
for (Session session : sessions) {
|
||||
Optional<UUID> uuidValue = session.getValue(SessionKeys.UUID);
|
||||
if (!uuidValue.isPresent()) {
|
||||
continue;
|
||||
}
|
||||
UUID uuid = uuidValue.get();
|
||||
int day = function.apply(session.getUnsafe(SessionKeys.START));
|
||||
|
||||
uniqueJoins.computeIfAbsent(day, computedDay -> new HashSet<>());
|
||||
uniqueJoins.get(day).add(uuid);
|
||||
}
|
||||
|
||||
int total = MathUtils.sumInt(uniqueJoins.values().stream().map(Set::size));
|
||||
int numberOfDays = uniqueJoins.size();
|
||||
|
||||
if (numberOfDays == 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return total / numberOfDays;
|
||||
}
|
||||
|
||||
public int count() {
|
||||
return sessions.size();
|
||||
}
|
||||
|
@ -3,6 +3,9 @@ package com.djrapitops.plan.data.store.mutators.formatting;
|
||||
import com.djrapitops.plan.data.store.objects.DateHolder;
|
||||
import com.djrapitops.plan.utilities.FormatUtils;
|
||||
|
||||
import java.util.Calendar;
|
||||
import java.util.function.Function;
|
||||
|
||||
/**
|
||||
* Class that holds static methods for getting new instances of different {@link Formatter}s.
|
||||
*
|
||||
@ -55,4 +58,12 @@ public class Formatters {
|
||||
public static Formatter<Long> timeAmount() {
|
||||
return new TimeAmountFormatter();
|
||||
}
|
||||
|
||||
public static Function<Long, Integer> dayOfYear() {
|
||||
return date -> {
|
||||
Calendar day = Calendar.getInstance();
|
||||
day.setTimeInMillis(date);
|
||||
return day.get(Calendar.DAY_OF_YEAR);
|
||||
};
|
||||
}
|
||||
}
|
@ -54,6 +54,7 @@ public class AnalysisUtils {
|
||||
return uuids.size();
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
public static int getUniqueJoinsPerDay(Map<UUID, List<Session>> sessions, long after) {
|
||||
Map<Integer, Set<UUID>> uniqueJoins = new HashMap<>();
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user