mirror of
https://github.com/plan-player-analytics/Plan.git
synced 2024-11-03 01:10:17 +01:00
Playtime & Sessions per day queries
This commit is contained in:
parent
7a2636f5b2
commit
63c2db3cb2
@ -141,7 +141,7 @@ public class NetworkContainer extends DynamicDataContainer {
|
|||||||
config.get(TimeSettings.ACTIVE_PLAY_THRESHOLD),
|
config.get(TimeSettings.ACTIVE_PLAY_THRESHOLD),
|
||||||
config.get(TimeSettings.ACTIVE_LOGIN_THRESHOLD),
|
config.get(TimeSettings.ACTIVE_LOGIN_THRESHOLD),
|
||||||
formatters.timeAmount(), formatters.decimals(), formatters.percentage(),
|
formatters.timeAmount(), formatters.decimals(), formatters.percentage(),
|
||||||
config.get(TimeSettings.USE_SERVER_TIME) ? TimeZone.getDefault() : TimeZone.getTimeZone("GMT")
|
config.getTimeZone()
|
||||||
));
|
));
|
||||||
putCachingSupplier(NetworkKeys.HEALTH_INDEX, () -> getUnsafe(healthInformation).getServerHealth());
|
putCachingSupplier(NetworkKeys.HEALTH_INDEX, () -> getUnsafe(healthInformation).getServerHealth());
|
||||||
putCachingSupplier(NetworkKeys.HEALTH_NOTES, () -> getUnsafe(healthInformation).toHtml());
|
putCachingSupplier(NetworkKeys.HEALTH_NOTES, () -> getUnsafe(healthInformation).toHtml());
|
||||||
|
@ -19,6 +19,7 @@ package com.djrapitops.plan.db;
|
|||||||
import com.djrapitops.plan.api.exceptions.database.DBInitException;
|
import com.djrapitops.plan.api.exceptions.database.DBInitException;
|
||||||
import com.djrapitops.plan.db.access.Query;
|
import com.djrapitops.plan.db.access.Query;
|
||||||
import com.djrapitops.plan.db.access.transactions.Transaction;
|
import com.djrapitops.plan.db.access.transactions.Transaction;
|
||||||
|
import com.djrapitops.plan.db.sql.parsing.Sql;
|
||||||
|
|
||||||
import java.util.concurrent.Future;
|
import java.util.concurrent.Future;
|
||||||
|
|
||||||
@ -67,6 +68,10 @@ public interface Database {
|
|||||||
*/
|
*/
|
||||||
DBType getType();
|
DBType getType();
|
||||||
|
|
||||||
|
default Sql getSql() {
|
||||||
|
return getType().getSql();
|
||||||
|
}
|
||||||
|
|
||||||
State getState();
|
State getState();
|
||||||
|
|
||||||
enum State {
|
enum State {
|
||||||
|
@ -79,7 +79,7 @@ public class PlayerCountQueries {
|
|||||||
*/
|
*/
|
||||||
public static Query<NavigableMap<Long, Integer>> uniquePlayerCounts(long after, long before, long timeZoneOffset, UUID serverUUID) {
|
public static Query<NavigableMap<Long, Integer>> uniquePlayerCounts(long after, long before, long timeZoneOffset, UUID serverUUID) {
|
||||||
return database -> {
|
return database -> {
|
||||||
Sql sql = database.getType().getSql();
|
Sql sql = database.getSql();
|
||||||
String selectUniquePlayersPerDay = SELECT +
|
String selectUniquePlayersPerDay = SELECT +
|
||||||
sql.dateToEpochSecond(sql.dateToDayStamp(sql.epochSecondToDate('(' + SessionsTable.SESSION_START + "+?)/1000"))) +
|
sql.dateToEpochSecond(sql.dateToDayStamp(sql.epochSecondToDate('(' + SessionsTable.SESSION_START + "+?)/1000"))) +
|
||||||
"*1000 as date," +
|
"*1000 as date," +
|
||||||
@ -113,7 +113,7 @@ public class PlayerCountQueries {
|
|||||||
|
|
||||||
public static Query<Integer> averageUniquePlayerCount(long after, long before, long timeZoneOffset, UUID serverUUID) {
|
public static Query<Integer> averageUniquePlayerCount(long after, long before, long timeZoneOffset, UUID serverUUID) {
|
||||||
return database -> {
|
return database -> {
|
||||||
Sql sql = database.getType().getSql();
|
Sql sql = database.getSql();
|
||||||
String selectUniquePlayersPerDay = SELECT +
|
String selectUniquePlayersPerDay = SELECT +
|
||||||
sql.dateToEpochSecond(sql.dateToDayStamp(sql.epochSecondToDate('(' + SessionsTable.SESSION_START + "+?)/1000"))) +
|
sql.dateToEpochSecond(sql.dateToDayStamp(sql.epochSecondToDate('(' + SessionsTable.SESSION_START + "+?)/1000"))) +
|
||||||
"*1000 as date," +
|
"*1000 as date," +
|
||||||
@ -163,7 +163,7 @@ public class PlayerCountQueries {
|
|||||||
*/
|
*/
|
||||||
public static Query<NavigableMap<Long, Integer>> newPlayerCounts(long after, long before, long timeZoneOffset, UUID serverUUID) {
|
public static Query<NavigableMap<Long, Integer>> newPlayerCounts(long after, long before, long timeZoneOffset, UUID serverUUID) {
|
||||||
return database -> {
|
return database -> {
|
||||||
Sql sql = database.getType().getSql();
|
Sql sql = database.getSql();
|
||||||
String selectNewPlayersQuery = SELECT +
|
String selectNewPlayersQuery = SELECT +
|
||||||
sql.dateToEpochSecond(sql.dateToDayStamp(sql.epochSecondToDate('(' + UserInfoTable.REGISTERED + "+?)/1000"))) +
|
sql.dateToEpochSecond(sql.dateToDayStamp(sql.epochSecondToDate('(' + UserInfoTable.REGISTERED + "+?)/1000"))) +
|
||||||
"*1000 as date," +
|
"*1000 as date," +
|
||||||
@ -197,7 +197,7 @@ public class PlayerCountQueries {
|
|||||||
|
|
||||||
public static Query<Integer> averageNewPlayerCount(long after, long before, long timeZoneOffset, UUID serverUUID) {
|
public static Query<Integer> averageNewPlayerCount(long after, long before, long timeZoneOffset, UUID serverUUID) {
|
||||||
return database -> {
|
return database -> {
|
||||||
Sql sql = database.getType().getSql();
|
Sql sql = database.getSql();
|
||||||
String selectNewPlayersQuery = SELECT +
|
String selectNewPlayersQuery = SELECT +
|
||||||
sql.dateToEpochSecond(sql.dateToDayStamp(sql.epochSecondToDate('(' + UserInfoTable.REGISTERED + "+?)/1000"))) +
|
sql.dateToEpochSecond(sql.dateToDayStamp(sql.epochSecondToDate('(' + UserInfoTable.REGISTERED + "+?)/1000"))) +
|
||||||
"*1000 as date," +
|
"*1000 as date," +
|
||||||
|
@ -26,6 +26,7 @@ import com.djrapitops.plan.data.time.WorldTimes;
|
|||||||
import com.djrapitops.plan.db.access.Query;
|
import com.djrapitops.plan.db.access.Query;
|
||||||
import com.djrapitops.plan.db.access.QueryAllStatement;
|
import com.djrapitops.plan.db.access.QueryAllStatement;
|
||||||
import com.djrapitops.plan.db.access.QueryStatement;
|
import com.djrapitops.plan.db.access.QueryStatement;
|
||||||
|
import com.djrapitops.plan.db.sql.parsing.Sql;
|
||||||
import com.djrapitops.plan.db.sql.tables.*;
|
import com.djrapitops.plan.db.sql.tables.*;
|
||||||
import com.djrapitops.plan.utilities.comparators.DateHolderRecentComparator;
|
import com.djrapitops.plan.utilities.comparators.DateHolderRecentComparator;
|
||||||
|
|
||||||
@ -370,6 +371,40 @@ public class SessionQueries {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static Query<NavigableMap<Long, Integer>> sessionCountPerDay(long after, long before, long timeZoneOffset, UUID serverUUID) {
|
||||||
|
return database -> {
|
||||||
|
Sql sql = database.getSql();
|
||||||
|
String selectSessionsPerDay = SELECT +
|
||||||
|
sql.dateToEpochSecond(sql.dateToDayStamp(sql.epochSecondToDate('(' + SessionsTable.SESSION_START + "+?)/1000"))) +
|
||||||
|
"*1000 as date," +
|
||||||
|
"COUNT(1) as session_count" +
|
||||||
|
FROM + SessionsTable.TABLE_NAME +
|
||||||
|
WHERE + SessionsTable.SESSION_END + "<=?" +
|
||||||
|
AND + SessionsTable.SESSION_START + ">=?" +
|
||||||
|
AND + SessionsTable.SERVER_UUID + "=?" +
|
||||||
|
GROUP_BY + "date";
|
||||||
|
|
||||||
|
return database.query(new QueryStatement<NavigableMap<Long, Integer>>(selectSessionsPerDay, 100) {
|
||||||
|
@Override
|
||||||
|
public void prepare(PreparedStatement statement) throws SQLException {
|
||||||
|
statement.setLong(1, timeZoneOffset);
|
||||||
|
statement.setLong(2, before);
|
||||||
|
statement.setLong(3, after);
|
||||||
|
statement.setString(4, serverUUID.toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public NavigableMap<Long, Integer> processResults(ResultSet set) throws SQLException {
|
||||||
|
NavigableMap<Long, Integer> uniquePerDay = new TreeMap<>();
|
||||||
|
while (set.next()) {
|
||||||
|
uniquePerDay.put(set.getLong("date"), set.getInt("session_count"));
|
||||||
|
}
|
||||||
|
return uniquePerDay;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
public static Query<Long> playtime(long after, long before, UUID serverUUID) {
|
public static Query<Long> playtime(long after, long before, UUID serverUUID) {
|
||||||
String sql = SELECT + "SUM(" + SessionsTable.SESSION_END + '-' + SessionsTable.SESSION_START + ") as playtime" +
|
String sql = SELECT + "SUM(" + SessionsTable.SESSION_END + '-' + SessionsTable.SESSION_START + ") as playtime" +
|
||||||
FROM + SessionsTable.TABLE_NAME +
|
FROM + SessionsTable.TABLE_NAME +
|
||||||
@ -391,6 +426,71 @@ public class SessionQueries {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static Query<NavigableMap<Long, Long>> playtimePerDay(long after, long before, long timeZoneOffset, UUID serverUUID) {
|
||||||
|
return database -> {
|
||||||
|
Sql sql = database.getSql();
|
||||||
|
String selectPlaytimePerDay = SELECT +
|
||||||
|
sql.dateToEpochSecond(sql.dateToDayStamp(sql.epochSecondToDate('(' + SessionsTable.SESSION_START + "+?)/1000"))) +
|
||||||
|
"*1000 as date," +
|
||||||
|
"SUM(" + SessionsTable.SESSION_END + '-' + SessionsTable.SESSION_START + ") as playtime" +
|
||||||
|
FROM + SessionsTable.TABLE_NAME +
|
||||||
|
WHERE + SessionsTable.SESSION_END + "<=?" +
|
||||||
|
AND + SessionsTable.SESSION_START + ">=?" +
|
||||||
|
AND + SessionsTable.SERVER_UUID + "=?" +
|
||||||
|
GROUP_BY + "date";
|
||||||
|
|
||||||
|
return database.query(new QueryStatement<NavigableMap<Long, Long>>(selectPlaytimePerDay, 100) {
|
||||||
|
@Override
|
||||||
|
public void prepare(PreparedStatement statement) throws SQLException {
|
||||||
|
statement.setLong(1, timeZoneOffset);
|
||||||
|
statement.setLong(2, before);
|
||||||
|
statement.setLong(3, after);
|
||||||
|
statement.setString(4, serverUUID.toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public NavigableMap<Long, Long> processResults(ResultSet set) throws SQLException {
|
||||||
|
NavigableMap<Long, Long> uniquePerDay = new TreeMap<>();
|
||||||
|
while (set.next()) {
|
||||||
|
uniquePerDay.put(set.getLong("date"), set.getLong("playtime"));
|
||||||
|
}
|
||||||
|
return uniquePerDay;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Query<Long> averagePlaytimePerDay(long after, long before, long timeZoneOffset, UUID serverUUID) {
|
||||||
|
return database -> {
|
||||||
|
Sql sql = database.getSql();
|
||||||
|
String selectPlaytimePerDay = SELECT +
|
||||||
|
sql.dateToEpochSecond(sql.dateToDayStamp(sql.epochSecondToDate('(' + SessionsTable.SESSION_START + "+?)/1000"))) +
|
||||||
|
"*1000 as date," +
|
||||||
|
"SUM(" + SessionsTable.SESSION_END + '-' + SessionsTable.SESSION_START + ") as playtime" +
|
||||||
|
FROM + SessionsTable.TABLE_NAME +
|
||||||
|
WHERE + SessionsTable.SESSION_END + "<=?" +
|
||||||
|
AND + SessionsTable.SESSION_START + ">=?" +
|
||||||
|
AND + SessionsTable.SERVER_UUID + "=?" +
|
||||||
|
GROUP_BY + "date";
|
||||||
|
String selectAverage = SELECT + "AVG(playtime) as average" + FROM + '(' + selectPlaytimePerDay + ") q1";
|
||||||
|
|
||||||
|
return database.query(new QueryStatement<Long>(selectAverage, 100) {
|
||||||
|
@Override
|
||||||
|
public void prepare(PreparedStatement statement) throws SQLException {
|
||||||
|
statement.setLong(1, timeZoneOffset);
|
||||||
|
statement.setLong(2, before);
|
||||||
|
statement.setLong(3, after);
|
||||||
|
statement.setString(4, serverUUID.toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Long processResults(ResultSet set) throws SQLException {
|
||||||
|
return set.next() ? set.getLong("average") : 0;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
public static Query<Long> afkTime(long after, long before, UUID serverUUID) {
|
public static Query<Long> afkTime(long after, long before, UUID serverUUID) {
|
||||||
String sql = SELECT + "SUM(" + SessionsTable.AFK_TIME + ") as afk_time" +
|
String sql = SELECT + "SUM(" + SessionsTable.AFK_TIME + ") as afk_time" +
|
||||||
FROM + SessionsTable.TABLE_NAME +
|
FROM + SessionsTable.TABLE_NAME +
|
||||||
|
@ -67,7 +67,7 @@ public class GraphJSONParser {
|
|||||||
this.config = config;
|
this.config = config;
|
||||||
this.dbSystem = dbSystem;
|
this.dbSystem = dbSystem;
|
||||||
this.graphs = graphs;
|
this.graphs = graphs;
|
||||||
this.timeZone = config.get(TimeSettings.USE_SERVER_TIME) ? TimeZone.getDefault() : TimeZone.getTimeZone("GMT");
|
this.timeZone = config.getTimeZone();
|
||||||
}
|
}
|
||||||
|
|
||||||
public String performanceGraphJSON(UUID serverUUID) {
|
public String performanceGraphJSON(UUID serverUUID) {
|
||||||
@ -121,10 +121,18 @@ public class GraphJSONParser {
|
|||||||
NavigableMap<Long, Integer> newPerDay = db.query(
|
NavigableMap<Long, Integer> newPerDay = db.query(
|
||||||
PlayerCountQueries.newPlayerCounts(twoYearsAgo, now, timeZone.getOffset(now), serverUUID)
|
PlayerCountQueries.newPlayerCounts(twoYearsAgo, now, timeZone.getOffset(now), serverUUID)
|
||||||
);
|
);
|
||||||
|
NavigableMap<Long, Long> playtimePerDay = db.query(
|
||||||
|
SessionQueries.playtimePerDay(twoYearsAgo, now, timeZone.getOffset(now), serverUUID)
|
||||||
|
);
|
||||||
|
NavigableMap<Long, Integer> sessionsPerDay = db.query(
|
||||||
|
SessionQueries.sessionCountPerDay(twoYearsAgo, now, timeZone.getOffset(now), serverUUID)
|
||||||
|
);
|
||||||
return "{\"data\":" +
|
return "{\"data\":" +
|
||||||
graphs.calendar().serverCalendar(
|
graphs.calendar().serverCalendar(
|
||||||
uniquePerDay,
|
uniquePerDay,
|
||||||
newPerDay
|
newPerDay,
|
||||||
|
playtimePerDay,
|
||||||
|
sessionsPerDay
|
||||||
).toCalendarSeries() +
|
).toCalendarSeries() +
|
||||||
",\"firstDay\":" + 1 + '}';
|
",\"firstDay\":" + 1 + '}';
|
||||||
}
|
}
|
||||||
|
@ -29,7 +29,6 @@ import com.djrapitops.plan.db.access.queries.objects.UserInfoQueries;
|
|||||||
import com.djrapitops.plan.system.database.DBSystem;
|
import com.djrapitops.plan.system.database.DBSystem;
|
||||||
import com.djrapitops.plan.system.settings.config.PlanConfig;
|
import com.djrapitops.plan.system.settings.config.PlanConfig;
|
||||||
import com.djrapitops.plan.system.settings.paths.DisplaySettings;
|
import com.djrapitops.plan.system.settings.paths.DisplaySettings;
|
||||||
import com.djrapitops.plan.system.settings.paths.TimeSettings;
|
|
||||||
import com.djrapitops.plan.utilities.formatting.Formatter;
|
import com.djrapitops.plan.utilities.formatting.Formatter;
|
||||||
import com.djrapitops.plan.utilities.formatting.Formatters;
|
import com.djrapitops.plan.utilities.formatting.Formatters;
|
||||||
|
|
||||||
@ -66,7 +65,7 @@ public class OnlineActivityOverviewJSONParser implements TabJSONParser<Map<Strin
|
|||||||
timeAmountFormatter = formatters.timeAmount();
|
timeAmountFormatter = formatters.timeAmount();
|
||||||
decimalFormatter = formatters.decimals();
|
decimalFormatter = formatters.decimals();
|
||||||
percentageFormatter = formatters.percentage();
|
percentageFormatter = formatters.percentage();
|
||||||
this.timeZone = config.get(TimeSettings.USE_SERVER_TIME) ? TimeZone.getDefault() : TimeZone.getTimeZone("GMT");
|
this.timeZone = config.getTimeZone();
|
||||||
}
|
}
|
||||||
|
|
||||||
public Map<String, Object> createJSONAsMap(UUID serverUUID) {
|
public Map<String, Object> createJSONAsMap(UUID serverUUID) {
|
||||||
@ -146,16 +145,15 @@ public class OnlineActivityOverviewJSONParser implements TabJSONParser<Map<Strin
|
|||||||
numbers.put("playtime_7d", timeAmountFormatter.apply(playtimeWeek));
|
numbers.put("playtime_7d", timeAmountFormatter.apply(playtimeWeek));
|
||||||
numbers.put("playtime_24h", timeAmountFormatter.apply(playtimeDay));
|
numbers.put("playtime_24h", timeAmountFormatter.apply(playtimeDay));
|
||||||
|
|
||||||
// TODO
|
numbers.put("playtime_30d_avg", timeAmountFormatter.apply(db.query(SessionQueries.averagePlaytimePerDay(monthAgo, now, timeZoneOffset, serverUUID))));
|
||||||
numbers.put("playtime_30d_avg", timeAmountFormatter.apply(-1L));
|
|
||||||
numbers.put("playtime_30d_avg_trend", new Trend(
|
numbers.put("playtime_30d_avg_trend", new Trend(
|
||||||
-1,
|
db.query(SessionQueries.averagePlaytimePerDay(monthAgo, halfMonthAgo, timeZoneOffset, serverUUID)),
|
||||||
-1,
|
db.query(SessionQueries.averagePlaytimePerDay(halfMonthAgo, now, timeZoneOffset, serverUUID)),
|
||||||
false,
|
false,
|
||||||
timeAmountFormatter
|
timeAmountFormatter
|
||||||
));
|
));
|
||||||
numbers.put("playtime_7d_avg", timeAmountFormatter.apply(-1L));
|
numbers.put("playtime_7d_avg", timeAmountFormatter.apply(db.query(SessionQueries.averagePlaytimePerDay(weekAgo, now, timeZoneOffset, serverUUID))));
|
||||||
numbers.put("playtime_24h_avg", timeAmountFormatter.apply(-1L));
|
numbers.put("playtime_24h_avg", timeAmountFormatter.apply(db.query(SessionQueries.playtime(dayAgo, now, serverUUID))));
|
||||||
|
|
||||||
Long sessionsMonth = db.query(SessionQueries.sessionCount(monthAgo, now, serverUUID));
|
Long sessionsMonth = db.query(SessionQueries.sessionCount(monthAgo, now, serverUUID));
|
||||||
Long sessionsWeek = db.query(SessionQueries.sessionCount(weekAgo, now, serverUUID));
|
Long sessionsWeek = db.query(SessionQueries.sessionCount(weekAgo, now, serverUUID));
|
||||||
|
@ -75,7 +75,7 @@ public class ServerOverviewJSONParser implements TabJSONParser<Map<String, Objec
|
|||||||
timeAmount = formatters.timeAmount();
|
timeAmount = formatters.timeAmount();
|
||||||
decimals = formatters.decimals();
|
decimals = formatters.decimals();
|
||||||
percentage = formatters.percentage();
|
percentage = formatters.percentage();
|
||||||
this.timeZone = config.get(TimeSettings.USE_SERVER_TIME) ? TimeZone.getDefault() : TimeZone.getTimeZone("GMT");
|
this.timeZone = config.getTimeZone();
|
||||||
}
|
}
|
||||||
|
|
||||||
public Map<String, Object> createJSONAsMap(UUID serverUUID) {
|
public Map<String, Object> createJSONAsMap(UUID serverUUID) {
|
||||||
|
@ -121,6 +121,10 @@ public class PlanConfig extends Config {
|
|||||||
set(setting.getPath(), value);
|
set(setting.getPath(), value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public TimeZone getTimeZone() {
|
||||||
|
return get(TimeSettings.USE_SERVER_TIME) ? TimeZone.getDefault() : TimeZone.getTimeZone("GMT");
|
||||||
|
}
|
||||||
|
|
||||||
public PluginsConfigSection getPluginsConfigSection() {
|
public PluginsConfigSection getPluginsConfigSection() {
|
||||||
return pluginsConfigSection;
|
return pluginsConfigSection;
|
||||||
}
|
}
|
||||||
|
@ -18,14 +18,13 @@ package com.djrapitops.plan.utilities.html.graphs.calendar;
|
|||||||
|
|
||||||
import com.djrapitops.plan.data.store.containers.PlayerContainer;
|
import com.djrapitops.plan.data.store.containers.PlayerContainer;
|
||||||
import com.djrapitops.plan.system.settings.config.PlanConfig;
|
import com.djrapitops.plan.system.settings.config.PlanConfig;
|
||||||
import com.djrapitops.plan.system.settings.paths.TimeSettings;
|
|
||||||
import com.djrapitops.plan.system.settings.theme.Theme;
|
import com.djrapitops.plan.system.settings.theme.Theme;
|
||||||
import com.djrapitops.plan.utilities.formatting.Formatters;
|
import com.djrapitops.plan.utilities.formatting.Formatters;
|
||||||
|
|
||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
import javax.inject.Singleton;
|
import javax.inject.Singleton;
|
||||||
|
import java.util.NavigableMap;
|
||||||
import java.util.SortedMap;
|
import java.util.SortedMap;
|
||||||
import java.util.TimeZone;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Factory class for different objects representing HTML calendars.
|
* Factory class for different objects representing HTML calendars.
|
||||||
@ -53,18 +52,20 @@ public class CalendarFactory {
|
|||||||
return new PlayerCalendar(
|
return new PlayerCalendar(
|
||||||
player,
|
player,
|
||||||
formatters.timeAmount(), formatters.yearLong(), formatters.iso8601NoClockLong(), theme,
|
formatters.timeAmount(), formatters.yearLong(), formatters.iso8601NoClockLong(), theme,
|
||||||
config.get(TimeSettings.USE_SERVER_TIME) ? TimeZone.getDefault() : TimeZone.getTimeZone("GMT")
|
config.getTimeZone()
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
public ServerCalendar serverCalendar(
|
public ServerCalendar serverCalendar(
|
||||||
SortedMap<Long, Integer> uniquePerDay,
|
SortedMap<Long, Integer> uniquePerDay,
|
||||||
SortedMap<Long, Integer> newPerDay
|
SortedMap<Long, Integer> newPerDay,
|
||||||
|
SortedMap<Long, Long> playtimePerDay,
|
||||||
|
NavigableMap<Long, Integer> sessionsPerDay
|
||||||
) {
|
) {
|
||||||
return new ServerCalendar(
|
return new ServerCalendar(
|
||||||
uniquePerDay, newPerDay,
|
uniquePerDay, newPerDay, playtimePerDay, sessionsPerDay,
|
||||||
formatters.iso8601NoClockLong(), formatters.timeAmount(), theme,
|
formatters.iso8601NoClockLong(), formatters.timeAmount(), theme,
|
||||||
config.get(TimeSettings.USE_SERVER_TIME) ? TimeZone.getDefault() : TimeZone.getTimeZone("GMT")
|
config.getTimeZone()
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -20,7 +20,10 @@ import com.djrapitops.plan.system.settings.theme.Theme;
|
|||||||
import com.djrapitops.plan.system.settings.theme.ThemeVal;
|
import com.djrapitops.plan.system.settings.theme.ThemeVal;
|
||||||
import com.djrapitops.plan.utilities.formatting.Formatter;
|
import com.djrapitops.plan.utilities.formatting.Formatter;
|
||||||
|
|
||||||
import java.util.*;
|
import java.util.Map;
|
||||||
|
import java.util.NavigableMap;
|
||||||
|
import java.util.SortedMap;
|
||||||
|
import java.util.TimeZone;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Utility for creating FullCalendar calendar event array on Player page.
|
* Utility for creating FullCalendar calendar event array on Player page.
|
||||||
@ -40,7 +43,10 @@ public class ServerCalendar {
|
|||||||
private final TimeZone timeZone;
|
private final TimeZone timeZone;
|
||||||
|
|
||||||
ServerCalendar(
|
ServerCalendar(
|
||||||
SortedMap<Long, Integer> uniquePerDay, SortedMap<Long, Integer> newPerDay,
|
SortedMap<Long, Integer> uniquePerDay,
|
||||||
|
SortedMap<Long, Integer> newPerDay,
|
||||||
|
SortedMap<Long, Long> playtimePerDay,
|
||||||
|
NavigableMap<Long, Integer> sessionsPerDay,
|
||||||
Formatter<Long> iso8601Formatter,
|
Formatter<Long> iso8601Formatter,
|
||||||
Formatter<Long> timeAmountFormatter,
|
Formatter<Long> timeAmountFormatter,
|
||||||
Theme theme,
|
Theme theme,
|
||||||
@ -50,8 +56,8 @@ public class ServerCalendar {
|
|||||||
this.newPerDay = newPerDay;
|
this.newPerDay = newPerDay;
|
||||||
this.iso8601Formatter = iso8601Formatter;
|
this.iso8601Formatter = iso8601Formatter;
|
||||||
this.timeAmountFormatter = timeAmountFormatter;
|
this.timeAmountFormatter = timeAmountFormatter;
|
||||||
sessionsPerDay = new TreeMap<>(); // TODO
|
this.sessionsPerDay = sessionsPerDay;
|
||||||
playtimePerDay = new TreeMap<>(); // TODO
|
this.playtimePerDay = playtimePerDay;
|
||||||
this.theme = theme;
|
this.theme = theme;
|
||||||
this.timeZone = timeZone;
|
this.timeZone = timeZone;
|
||||||
}
|
}
|
||||||
@ -60,57 +66,45 @@ public class ServerCalendar {
|
|||||||
StringBuilder series = new StringBuilder("[");
|
StringBuilder series = new StringBuilder("[");
|
||||||
|
|
||||||
series.append("{\"title\": \"badcode\",\"start\":0}");
|
series.append("{\"title\": \"badcode\",\"start\":0}");
|
||||||
appendSessionRelatedData(series);
|
appendTimeZoneOffsetData(series);
|
||||||
appendRegistered(series);
|
|
||||||
|
|
||||||
return series.append("]").toString();
|
return series.append("]").toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void appendRegistered(StringBuilder series) {
|
private void appendTimeZoneOffsetData(StringBuilder series) {
|
||||||
Map<String, Integer> registeredByDay = getRegisteredByDay();
|
// Has a timezone offset
|
||||||
|
appendUniquePlayers(series);
|
||||||
|
appendNewPlayers(series);
|
||||||
|
appendSessionCounts(series);
|
||||||
|
appendPlaytime(series);
|
||||||
|
}
|
||||||
|
|
||||||
for (Map.Entry<String, Integer> entry : registeredByDay.entrySet()) {
|
private void appendNewPlayers(StringBuilder series) {
|
||||||
Integer newPlayers = entry.getValue();
|
for (Map.Entry<Long, Integer> entry : newPerDay.entrySet()) {
|
||||||
|
int newPlayers = entry.getValue();
|
||||||
if (newPlayers <= 0) {
|
if (newPlayers <= 0) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
String day = entry.getKey();
|
Long key = entry.getKey();
|
||||||
|
String day = iso8601Formatter.apply(key - timeZone.getOffset(key));// Remove the timezone offset since Calendar uses UTC
|
||||||
|
|
||||||
series.append(",{\"title\": \"New: ").append(newPlayers)
|
series.append(",{\"title\": \"New: ").append(newPlayers)
|
||||||
.append("\",\"start\":\"").append(day)
|
.append("\",\"start\":\"").append(day)
|
||||||
.append("\",\"color\": \"").append(theme.getValue(ThemeVal.LIGHT_GREEN)).append('"')
|
.append("\",\"color\": \"").append(theme.getValue(ThemeVal.LIGHT_GREEN)).append('"')
|
||||||
.append("}");
|
.append("}");
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void appendSessionRelatedData(StringBuilder series) {
|
private void appendUniquePlayers(StringBuilder series) {
|
||||||
// Has a timezone offset
|
|
||||||
for (Map.Entry<Long, Integer> entry : uniquePerDay.entrySet()) {
|
for (Map.Entry<Long, Integer> entry : uniquePerDay.entrySet()) {
|
||||||
if (entry.getValue() <= 0) {
|
long uniquePlayers = entry.getValue();
|
||||||
|
if (uniquePlayers <= 0) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
Long key = entry.getKey();
|
Long key = entry.getKey();
|
||||||
String day = iso8601Formatter.apply(key - timeZone.getOffset(entry.getKey()));// Remove the timezone offset since Calendar uses UTC
|
String day = iso8601Formatter.apply(key - timeZone.getOffset(key));// Remove the timezone offset since Calendar uses UTC
|
||||||
|
|
||||||
Integer sessionCount = sessionsPerDay.getOrDefault(key, 0);
|
|
||||||
Long playtime = playtimePerDay.getOrDefault(key, 0L);
|
|
||||||
long uniquePlayers = entry.getValue();
|
|
||||||
|
|
||||||
if (playtime > 0) {
|
|
||||||
series.append(",{\"title\": \"Playtime: ").append(timeAmountFormatter.apply(playtime))
|
|
||||||
.append("\",\"start\":\"").append(day)
|
|
||||||
.append("\",\"color\": \"").append(theme.getValue(ThemeVal.GREEN)).append('"')
|
|
||||||
.append("}");
|
|
||||||
}
|
|
||||||
if (sessionCount > 0) {
|
|
||||||
series.append(",{\"title\": \"Sessions: ").append(sessionCount)
|
|
||||||
.append("\",\"start\":\"").append(day)
|
|
||||||
.append("\",\"color\": \"").append(theme.getValue(ThemeVal.TEAL)).append('"')
|
|
||||||
.append("}");
|
|
||||||
}
|
|
||||||
|
|
||||||
series.append(",{\"title\": \"Unique: ").append(uniquePlayers)
|
series.append(",{\"title\": \"Unique: ").append(uniquePlayers)
|
||||||
.append("\",\"start\":\"").append(day)
|
.append("\",\"start\":\"").append(day)
|
||||||
@ -119,12 +113,35 @@ public class ServerCalendar {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private Map<String, Integer> getRegisteredByDay() {
|
private void appendPlaytime(StringBuilder series) {
|
||||||
Map<String, Integer> registeredByDay = new HashMap<>();
|
for (Map.Entry<Long, Long> entry : playtimePerDay.entrySet()) {
|
||||||
for (Map.Entry<Long, Integer> entry : newPerDay.entrySet()) {
|
long playtime = entry.getValue();
|
||||||
String day = iso8601Formatter.apply(entry.getKey());
|
if (playtime <= 0) {
|
||||||
registeredByDay.put(day, entry.getValue());
|
continue;
|
||||||
|
}
|
||||||
|
Long key = entry.getKey();
|
||||||
|
String day = iso8601Formatter.apply(key - timeZone.getOffset(key));// Remove the timezone offset since Calendar uses UTC
|
||||||
|
|
||||||
|
series.append(",{\"title\": \"Playtime: ").append(timeAmountFormatter.apply(playtime))
|
||||||
|
.append("\",\"start\":\"").append(day)
|
||||||
|
.append("\",\"color\": \"").append(theme.getValue(ThemeVal.GREEN)).append('"')
|
||||||
|
.append("}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void appendSessionCounts(StringBuilder series) {
|
||||||
|
for (Map.Entry<Long, Integer> entry : sessionsPerDay.entrySet()) {
|
||||||
|
int sessionCount = entry.getValue();
|
||||||
|
if (sessionCount <= 0) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
Long key = entry.getKey();
|
||||||
|
String day = iso8601Formatter.apply(key - timeZone.getOffset(key));// Remove the timezone offset since Calendar uses UTC
|
||||||
|
|
||||||
|
series.append(",{\"title\": \"Sessions: ").append(sessionCount)
|
||||||
|
.append("\",\"start\":\"").append(day)
|
||||||
|
.append("\",\"color\": \"").append(theme.getValue(ThemeVal.TEAL)).append('"')
|
||||||
|
.append("}");
|
||||||
}
|
}
|
||||||
return registeredByDay;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -454,7 +454,7 @@
|
|||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td><i class="col-green far fa-fw fa-clock"></i> Average Playtime /
|
<td><i class="col-green far fa-fw fa-clock"></i> Average Playtime /
|
||||||
Player
|
Day
|
||||||
</td>
|
</td>
|
||||||
<td id="data_playtime_30d_avg"></td>
|
<td id="data_playtime_30d_avg"></td>
|
||||||
<td id="data_playtime_7d_avg"></td>
|
<td id="data_playtime_7d_avg"></td>
|
||||||
|
Loading…
Reference in New Issue
Block a user