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. * @return Long in ms.
*/ */
@Deprecated
public long getLength() { public long getLength() {
return getUnsafe(SessionKeys.LENGTH); return getValue(SessionKeys.LENGTH).orElse(0L);
} }
@Override @Override

View File

@ -132,14 +132,58 @@ public class AnalysisContainer extends DataContainer {
putSupplier(AnalysisKeys.PLAYERS_TABLE, () -> putSupplier(AnalysisKeys.PLAYERS_TABLE, () ->
PlayersTable.forServerPage(getUnsafe(AnalysisKeys.PLAYERS_MUTATOR).all()).parseHtml() 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() { 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(), getUnsafe(AnalysisKeys.SESSIONS_MUTATOR).all(),
() -> Database.getActive().fetch().getServerNames(), () -> Database.getActive().fetch().getServerNames(),
() -> getUnsafe(AnalysisKeys.PLAYER_NAMES) () -> 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( putSupplier(AnalysisKeys.RECENT_LOGINS, () -> new RecentLoginList(
serverContainer.getValue(ServerKeys.PLAYERS).orElse(new ArrayList<>()) serverContainer.getValue(ServerKeys.PLAYERS).orElse(new ArrayList<>())
).toHtml() ).toHtml()
@ -147,8 +191,6 @@ public class AnalysisContainer extends DataContainer {
putSupplier(AnalysisKeys.SESSION_TABLE, () -> new ServerSessionTable( putSupplier(AnalysisKeys.SESSION_TABLE, () -> new ServerSessionTable(
getUnsafe(AnalysisKeys.PLAYER_NAMES), getUnsafe(AnalysisKeys.SESSIONS_MUTATOR).all()).parseHtml() 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() putSupplier(AnalysisKeys.AVERAGE_SESSION_LENGTH_F, () -> Formatters.timeAmount()
.apply(getUnsafe(AnalysisKeys.SESSIONS_MUTATOR).toAverageSessionLength()) .apply(getUnsafe(AnalysisKeys.SESSIONS_MUTATOR).toAverageSessionLength())
@ -167,13 +209,25 @@ public class AnalysisContainer extends DataContainer {
putSupplier(AnalysisKeys.AVERAGE_SESSION_LENGTH_F, () -> Formatters.timeAmount() putSupplier(AnalysisKeys.AVERAGE_SESSION_LENGTH_F, () -> Formatters.timeAmount()
.apply(getUnsafe(AnalysisKeys.SESSIONS_MUTATOR).toAverageSessionLength()) .apply(getUnsafe(AnalysisKeys.SESSIONS_MUTATOR).toAverageSessionLength())
); );
putSupplier(AnalysisKeys.PUNCHCARD_SERIES, () -> new PunchCardGraph(
SessionsMutator.copyOf(getUnsafe(AnalysisKeys.SESSIONS_MUTATOR) Key<SessionsMutator> sessionsDay = new Key<>(SessionsMutator.class, "SESSIONS_DAY");
.filterSessionsBetween( Key<SessionsMutator> sessionsWeek = new Key<>(SessionsMutator.class, "SESSIONS_WEEK");
getUnsafe(AnalysisKeys.ANALYSIS_TIME_MONTH_AGO), Key<SessionsMutator> sessionsMonth = new Key<>(SessionsMutator.class, "SESSIONS_MONTH");
getUnsafe(AnalysisKeys.ANALYSIS_TIME)) putSupplier(sessionsDay, () -> SessionsMutator.copyOf(getUnsafe(AnalysisKeys.SESSIONS_MUTATOR))
).all()).toHighChartsSeries() .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() { 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.PlayersMutator;
import com.djrapitops.plan.data.store.mutators.SessionsMutator; import com.djrapitops.plan.data.store.mutators.SessionsMutator;
import com.djrapitops.plan.data.store.mutators.TPSMutator; import com.djrapitops.plan.data.store.mutators.TPSMutator;
import com.djrapitops.plan.utilities.html.structure.SessionAccordion;
import java.util.Map; import java.util.Map;
import java.util.Set; 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_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_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<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<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"); 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.containers.PlayerContainer;
import com.djrapitops.plan.data.store.keys.PlayerKeys; import com.djrapitops.plan.data.store.keys.PlayerKeys;
import com.djrapitops.plan.data.store.keys.ServerKeys; 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 com.djrapitops.plugin.api.TimeAmount;
import java.util.*; 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. * 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<>())); 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() { public List<PlayerContainer> all() {
return players; 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() { public List<String> getGeolocations() {
List<String> geolocations = new ArrayList<>(); List<String> geolocations = new ArrayList<>();
@ -64,4 +95,26 @@ public class PlayersMutator {
} }
return activityData; 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.container.Session;
import com.djrapitops.plan.data.store.containers.DataContainer; import com.djrapitops.plan.data.store.containers.DataContainer;
import com.djrapitops.plan.data.store.keys.CommonKeys; 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.data.time.WorldTimes;
import com.djrapitops.plan.utilities.analysis.MathUtils;
import java.util.*; import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors; import java.util.stream.Collectors;
/** /**
@ -38,7 +42,8 @@ public class SessionsMutator {
public SessionsMutator filterSessionsBetween(long after, long before) { public SessionsMutator filterSessionsBetween(long after, long before) {
sessions = sessions.stream() 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()); .collect(Collectors.toList());
return this; return this;
} }
@ -47,8 +52,7 @@ public class SessionsMutator {
WorldTimes total = new WorldTimes(new HashMap<>()); WorldTimes total = new WorldTimes(new HashMap<>());
for (Session session : sessions) { for (Session session : sessions) {
WorldTimes worldTimes = session.getWorldTimes(); session.getValue(SessionKeys.WORLD_TIMES).ifPresent(total::add);
total.add(worldTimes);
} }
return total; return total;
@ -56,20 +60,20 @@ public class SessionsMutator {
public List<PlayerKill> toPlayerKillList() { public List<PlayerKill> toPlayerKillList() {
return sessions.stream() return sessions.stream()
.map(Session::getPlayerKills) .map(session -> session.getValue(SessionKeys.PLAYER_KILLS).orElse(new ArrayList<>()))
.flatMap(Collection::stream) .flatMap(Collection::stream)
.collect(Collectors.toList()); .collect(Collectors.toList());
} }
public int toMobKillCount() { public int toMobKillCount() {
return sessions.stream() return sessions.stream()
.mapToInt(Session::getMobKills) .mapToInt(session -> session.getValue(SessionKeys.MOB_KILL_COUNT).orElse(0))
.sum(); .sum();
} }
public int toDeathCount() { public int toDeathCount() {
return sessions.stream() return sessions.stream()
.mapToInt(Session::getDeaths) .mapToInt(session -> session.getValue(SessionKeys.DEATH_COUNT).orElse(0))
.sum(); .sum();
} }
@ -81,20 +85,22 @@ public class SessionsMutator {
public long toAfkTime() { public long toAfkTime() {
return sessions.stream() return sessions.stream()
.mapToLong(Session::getAfkLength) .mapToLong(session -> session.getValue(SessionKeys.AFK_TIME).orElse(0L))
.sum(); .sum();
} }
public long toActivePlaytime() { public long toActivePlaytime() {
return sessions.stream() return sessions.stream()
.mapToLong(Session::getActiveLength) .mapToLong(session -> session.getValue(SessionKeys.ACTIVE_TIME).orElse(0L))
.sum(); .sum();
} }
public long toLastSeen() { public long toLastSeen() {
return sessions.stream() return sessions.stream()
.mapToLong(session -> Math.max(session.getSessionStart(), session.getSessionEnd())) .mapToLong(session -> Math.max(session.getUnsafe(
.max().orElse(-1); SessionKeys.START),
session.getValue(SessionKeys.END).orElse(System.currentTimeMillis()))
).max().orElse(-1);
} }
public long toLongestSessionLength() { public long toLongestSessionLength() {
@ -125,6 +131,32 @@ public class SessionsMutator {
return sessionLengths.get(sessionLengths.size() / 2); 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() { public int count() {
return sessions.size(); 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.data.store.objects.DateHolder;
import com.djrapitops.plan.utilities.FormatUtils; 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. * 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() { public static Formatter<Long> timeAmount() {
return new TimeAmountFormatter(); 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(); return uuids.size();
} }
@Deprecated
public static int getUniqueJoinsPerDay(Map<UUID, List<Session>> sessions, long after) { public static int getUniqueJoinsPerDay(Map<UUID, List<Session>> sessions, long after) {
Map<Integer, Set<UUID>> uniqueJoins = new HashMap<>(); Map<Integer, Set<UUID>> uniqueJoins = new HashMap<>();