Player counts

This commit is contained in:
Rsl1122 2018-06-19 21:50:47 +03:00
parent ad55ed338e
commit 7e420aaf91
7 changed files with 171 additions and 23 deletions

View File

@ -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

View File

@ -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() {

View File

@ -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");

View File

@ -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;
}
}

View File

@ -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();
}

View File

@ -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);
};
}
}

View File

@ -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<>();