mirror of
https://github.com/plan-player-analytics/Plan.git
synced 2024-12-28 03:57:33 +01:00
Refactored ActivityIndex to a new class.
This commit is contained in:
parent
96def3ddbb
commit
cd95a0a68e
@ -2,9 +2,10 @@ package com.djrapitops.plan.command.commands;
|
||||
|
||||
import com.djrapitops.plan.PlanPlugin;
|
||||
import com.djrapitops.plan.data.PlayerProfile;
|
||||
import com.djrapitops.plan.system.settings.Permissions;
|
||||
import com.djrapitops.plan.data.element.ActivityIndex;
|
||||
import com.djrapitops.plan.settings.locale.Locale;
|
||||
import com.djrapitops.plan.settings.locale.Msg;
|
||||
import com.djrapitops.plan.system.settings.Permissions;
|
||||
import com.djrapitops.plan.utilities.Condition;
|
||||
import com.djrapitops.plan.utilities.FormatUtils;
|
||||
import com.djrapitops.plan.utilities.MiscUtils;
|
||||
@ -100,9 +101,9 @@ public class QInspectCommand extends SubCommand {
|
||||
|
||||
sender.sendMessage(Locale.get(Msg.CMD_HEADER_INSPECT).toString() + ": " + colT + profile.getName());
|
||||
|
||||
double activityIndex = profile.getActivityIndex(now);
|
||||
ActivityIndex activityIndex = profile.getActivityIndex(now);
|
||||
|
||||
sender.sendMessage(colT + ball + " " + colM + " Activity Index: " + colS + FormatUtils.cutDecimals(activityIndex) + " | " + FormatUtils.readableActivityIndex(activityIndex)[1]);
|
||||
sender.sendMessage(colT + ball + " " + colM + " Activity Index: " + colS + activityIndex.getFormattedValue() + " | " + activityIndex.getColor());
|
||||
sender.sendMessage(colT + ball + " " + colM + " Registered: " + colS + FormatUtils.formatTimeStampYear(profile.getRegistered()));
|
||||
sender.sendMessage(colT + ball + " " + colM + " Last Seen: " + colS + FormatUtils.formatTimeStampYear(profile.getLastSeen()));
|
||||
sender.sendMessage(colT + ball + " " + colM + " Logged in from: " + colS + profile.getMostRecentGeoInfo().getGeolocation());
|
||||
|
@ -4,16 +4,16 @@
|
||||
*/
|
||||
package com.djrapitops.plan.data;
|
||||
|
||||
import com.djrapitops.plan.PlanPlugin;
|
||||
import com.djrapitops.plan.data.container.Action;
|
||||
import com.djrapitops.plan.data.container.GeoInfo;
|
||||
import com.djrapitops.plan.data.container.PlayerKill;
|
||||
import com.djrapitops.plan.data.container.Session;
|
||||
import com.djrapitops.plan.data.element.ActivityIndex;
|
||||
import com.djrapitops.plan.data.time.WorldTimes;
|
||||
import com.djrapitops.plan.system.settings.Settings;
|
||||
import com.djrapitops.plan.utilities.MiscUtils;
|
||||
import com.djrapitops.plan.utilities.comparators.ActionComparator;
|
||||
import com.djrapitops.plan.utilities.comparators.GeoInfoComparator;
|
||||
import com.djrapitops.plugin.api.TimeAmount;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.OfflinePlayer;
|
||||
@ -57,7 +57,7 @@ public class PlayerProfile implements OfflinePlayer {
|
||||
private Map<String, String> pluginReplaceMap;
|
||||
|
||||
// Value that requires lot of processing
|
||||
private Map<Long, Double> activityIndex;
|
||||
private Map<Long, ActivityIndex> activityIndexCache;
|
||||
|
||||
public PlayerProfile(UUID uuid, String name, long registered) {
|
||||
this.uuid = uuid;
|
||||
@ -76,88 +76,17 @@ public class PlayerProfile implements OfflinePlayer {
|
||||
geoInformation = new ArrayList<>();
|
||||
|
||||
pluginReplaceMap = new HashMap<>();
|
||||
activityIndex = new HashMap<>();
|
||||
activityIndexCache = new HashMap<>();
|
||||
}
|
||||
|
||||
// Calculating Getters
|
||||
public double getActivityIndex(long date) {
|
||||
Double activityIndx = activityIndex.get(date);
|
||||
if (activityIndx != null) {
|
||||
return activityIndx;
|
||||
public ActivityIndex getActivityIndex(long date) {
|
||||
ActivityIndex index = activityIndexCache.get(date);
|
||||
if (index == null) {
|
||||
index = new ActivityIndex(this, date);
|
||||
activityIndexCache.put(date, index);
|
||||
}
|
||||
|
||||
long week = TimeAmount.WEEK.ms();
|
||||
long weekAgo = date - week;
|
||||
long twoWeeksAgo = date - 2L * week;
|
||||
long threeWeeksAgo = date - 3L * week;
|
||||
|
||||
long activePlayThreshold = Settings.ACTIVE_PLAY_THRESHOLD.getNumber() * TimeAmount.MINUTE.ms();
|
||||
if (activePlayThreshold <= 0) {
|
||||
activePlayThreshold = 1;
|
||||
}
|
||||
int activeLoginThreshold = Settings.ACTIVE_LOGIN_THRESHOLD.getNumber();
|
||||
if (activeLoginThreshold <= 0) {
|
||||
activeLoginThreshold = 1;
|
||||
}
|
||||
|
||||
List<Session> sessionsWeek = getSessions(weekAgo, date).collect(Collectors.toList());
|
||||
List<Session> sessionsWeek2 = getSessions(twoWeeksAgo, weekAgo).collect(Collectors.toList());
|
||||
List<Session> sessionsWeek3 = getSessions(threeWeeksAgo, twoWeeksAgo).collect(Collectors.toList());
|
||||
|
||||
// Playtime per week multipliers, max out to avoid too high values.
|
||||
double max = 4.0;
|
||||
|
||||
long playtimeWeek = PlayerProfile.getPlaytime(sessionsWeek.stream());
|
||||
double weekPlay = (playtimeWeek * 1.0 / activePlayThreshold);
|
||||
if (weekPlay > max) {
|
||||
weekPlay = max;
|
||||
}
|
||||
long playtimeWeek2 = PlayerProfile.getPlaytime(sessionsWeek2.stream());
|
||||
double week2Play = (playtimeWeek2 * 1.0 / activePlayThreshold);
|
||||
if (week2Play > max) {
|
||||
week2Play = max;
|
||||
}
|
||||
long playtimeWeek3 = PlayerProfile.getPlaytime(sessionsWeek3.stream());
|
||||
double week3Play = (playtimeWeek3 * 1.0 / activePlayThreshold);
|
||||
if (week3Play > max) {
|
||||
week3Play = max;
|
||||
}
|
||||
|
||||
double playtimeMultiplier = 1.0;
|
||||
if (playtimeWeek + playtimeWeek2 + playtimeWeek3 > activeLoginThreshold * 3.0) {
|
||||
playtimeMultiplier = 1.25;
|
||||
}
|
||||
|
||||
// Reduce the harshness for new players and players who have had a vacation
|
||||
if (weekPlay > 1 && week3Play > 1 && week2Play == 0.0) {
|
||||
week2Play = 0.5;
|
||||
}
|
||||
if (weekPlay > 1 && week2Play == 0.0) {
|
||||
week2Play = 0.6;
|
||||
}
|
||||
if (weekPlay > 1 && week3Play == 0.0) {
|
||||
week3Play = 0.75;
|
||||
}
|
||||
|
||||
double playAvg = (weekPlay + week2Play + week3Play) / 3.0;
|
||||
|
||||
double weekLogin = sessionsWeek.size() >= activeLoginThreshold ? 1.0 : 0.5;
|
||||
double week2Login = sessionsWeek2.size() >= activeLoginThreshold ? 1.0 : 0.5;
|
||||
double week3Login = sessionsWeek3.size() >= activeLoginThreshold ? 1.0 : 0.5;
|
||||
|
||||
double loginMultiplier = 1.0;
|
||||
double loginTotal = weekLogin + week2Login + week3Login;
|
||||
double loginAvg = loginTotal / 3.0;
|
||||
|
||||
if (loginTotal <= 2.0) {
|
||||
// Reduce index for players that have not logged in the threshold amount for 2 weeks
|
||||
loginMultiplier = 0.75;
|
||||
}
|
||||
|
||||
activityIndx = playAvg * loginAvg * loginMultiplier * playtimeMultiplier;
|
||||
activityIndex.put(date, activityIndx);
|
||||
|
||||
return activityIndx;
|
||||
return index;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -15,7 +15,7 @@ public class StickyData {
|
||||
private Integer onlineOnJoin;
|
||||
|
||||
public StickyData(PlayerProfile player) {
|
||||
activityIndex = player.getActivityIndex(player.getRegistered() + TimeAmount.DAY.ms());
|
||||
activityIndex = player.getActivityIndex(player.getRegistered() + TimeAmount.DAY.ms()).getValue();
|
||||
for (Action action : player.getActions()) {
|
||||
if (messagesSent == null && action.getDoneAction() == Actions.FIRST_LOGOUT) {
|
||||
String additionalInfo = action.getAdditionalInfo();
|
||||
|
@ -0,0 +1,131 @@
|
||||
package com.djrapitops.plan.data.element;
|
||||
|
||||
import com.djrapitops.plan.data.PlayerProfile;
|
||||
import com.djrapitops.plan.data.container.Session;
|
||||
import com.djrapitops.plan.system.settings.Settings;
|
||||
import com.djrapitops.plan.utilities.FormatUtils;
|
||||
import com.djrapitops.plugin.api.TimeAmount;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
public class ActivityIndex {
|
||||
|
||||
private static long loadSetting(long value) {
|
||||
return value < 0 ? 1 : value;
|
||||
}
|
||||
|
||||
private final double value;
|
||||
|
||||
public ActivityIndex(PlayerProfile player, long date) {
|
||||
value = calculate(player, date);
|
||||
}
|
||||
|
||||
private double calculate(PlayerProfile player, long date) {
|
||||
long week = TimeAmount.WEEK.ms();
|
||||
long weekAgo = date - week;
|
||||
long twoWeeksAgo = date - 2L * week;
|
||||
long threeWeeksAgo = date - 3L * week;
|
||||
|
||||
long activePlayThreshold = Settings.ACTIVE_PLAY_THRESHOLD.getNumber() * TimeAmount.MINUTE.ms();
|
||||
if (activePlayThreshold <= 0) {
|
||||
activePlayThreshold = 1;
|
||||
}
|
||||
int activeLoginThreshold = Settings.ACTIVE_LOGIN_THRESHOLD.getNumber();
|
||||
if (activeLoginThreshold <= 0) {
|
||||
activeLoginThreshold = 1;
|
||||
}
|
||||
|
||||
List<Session> sessionsWeek = player.getSessions(weekAgo, date).collect(Collectors.toList());
|
||||
List<Session> sessionsWeek2 = player.getSessions(twoWeeksAgo, weekAgo).collect(Collectors.toList());
|
||||
List<Session> sessionsWeek3 = player.getSessions(threeWeeksAgo, twoWeeksAgo).collect(Collectors.toList());
|
||||
|
||||
// Playtime per week multipliers, max out to avoid too high values.
|
||||
double max = 4.0;
|
||||
|
||||
long playtimeWeek = PlayerProfile.getPlaytime(sessionsWeek.stream());
|
||||
double weekPlay = (playtimeWeek * 1.0 / activePlayThreshold);
|
||||
if (weekPlay > max) {
|
||||
weekPlay = max;
|
||||
}
|
||||
long playtimeWeek2 = PlayerProfile.getPlaytime(sessionsWeek2.stream());
|
||||
double week2Play = (playtimeWeek2 * 1.0 / activePlayThreshold);
|
||||
if (week2Play > max) {
|
||||
week2Play = max;
|
||||
}
|
||||
long playtimeWeek3 = PlayerProfile.getPlaytime(sessionsWeek3.stream());
|
||||
double week3Play = (playtimeWeek3 * 1.0 / activePlayThreshold);
|
||||
if (week3Play > max) {
|
||||
week3Play = max;
|
||||
}
|
||||
|
||||
double playtimeMultiplier = 1.0;
|
||||
if (playtimeWeek + playtimeWeek2 + playtimeWeek3 > activePlayThreshold * 3.0) {
|
||||
playtimeMultiplier = 1.25;
|
||||
}
|
||||
|
||||
// Reduce the harshness for new players and players who have had a vacation
|
||||
if (weekPlay > 1 && week3Play > 1 && week2Play == 0.0) {
|
||||
week2Play = 0.5;
|
||||
}
|
||||
if (weekPlay > 1 && week2Play == 0.0) {
|
||||
week2Play = 0.6;
|
||||
}
|
||||
if (weekPlay > 1 && week3Play == 0.0) {
|
||||
week3Play = 0.75;
|
||||
}
|
||||
|
||||
double playAvg = (weekPlay + week2Play + week3Play) / 3.0;
|
||||
|
||||
double weekLogin = sessionsWeek.size() >= activeLoginThreshold ? 1.0 : 0.5;
|
||||
double week2Login = sessionsWeek2.size() >= activeLoginThreshold ? 1.0 : 0.5;
|
||||
double week3Login = sessionsWeek3.size() >= activeLoginThreshold ? 1.0 : 0.5;
|
||||
|
||||
double loginMultiplier = 1.0;
|
||||
double loginTotal = weekLogin + week2Login + week3Login;
|
||||
double loginAvg = loginTotal / 3.0;
|
||||
|
||||
if (loginTotal <= 2.0) {
|
||||
// Reduce index for players that have not logged in the threshold amount for 2 weeks
|
||||
loginMultiplier = 0.75;
|
||||
}
|
||||
|
||||
return playAvg * loginAvg * loginMultiplier * playtimeMultiplier;
|
||||
}
|
||||
|
||||
public double getValue() {
|
||||
return value;
|
||||
}
|
||||
|
||||
public String getFormattedValue() {
|
||||
return FormatUtils.cutDecimals(value);
|
||||
}
|
||||
|
||||
public String getGroup() {
|
||||
if (value >= 3.5) {
|
||||
return "Very Active";
|
||||
} else if (value >= 1.75) {
|
||||
return "Active";
|
||||
} else if (value >= 1.0) {
|
||||
return "Regular";
|
||||
} else if (value >= 0.5) {
|
||||
return "Irregular";
|
||||
} else {
|
||||
return "Inactive";
|
||||
}
|
||||
}
|
||||
|
||||
public String getColor() {
|
||||
if (value >= 3.5) {
|
||||
return "green";
|
||||
} else if (value >= 1.75) {
|
||||
return "green";
|
||||
} else if (value >= 1.0) {
|
||||
return "lime";
|
||||
} else if (value >= 0.5) {
|
||||
return "amber";
|
||||
} else {
|
||||
return "blue-gray";
|
||||
}
|
||||
}
|
||||
}
|
@ -155,7 +155,7 @@ public class HealthNotes {
|
||||
|
||||
private void activePlayerPlaytimeChange() {
|
||||
List<PlayerProfile> currentActivePlayers = analysisData.getPlayers().stream()
|
||||
.filter(player -> player.getActivityIndex(now) >= 1.75)
|
||||
.filter(player -> player.getActivityIndex(now).getValue() >= 1.75)
|
||||
.collect(Collectors.toList());
|
||||
|
||||
long twoWeeksAgo = now - TimeAmount.WEEK.ms() * 2L;
|
||||
|
@ -9,11 +9,12 @@ import com.djrapitops.plan.api.exceptions.ParseException;
|
||||
import com.djrapitops.plan.data.PlayerProfile;
|
||||
import com.djrapitops.plan.data.container.Action;
|
||||
import com.djrapitops.plan.data.container.Session;
|
||||
import com.djrapitops.plan.data.element.ActivityIndex;
|
||||
import com.djrapitops.plan.data.time.WorldTimes;
|
||||
import com.djrapitops.plan.database.Database;
|
||||
import com.djrapitops.plan.system.settings.Settings;
|
||||
import com.djrapitops.plan.settings.theme.Theme;
|
||||
import com.djrapitops.plan.settings.theme.ThemeVal;
|
||||
import com.djrapitops.plan.system.settings.Settings;
|
||||
import com.djrapitops.plan.utilities.FormatUtils;
|
||||
import com.djrapitops.plan.utilities.MiscUtils;
|
||||
import com.djrapitops.plan.utilities.analysis.AnalysisUtils;
|
||||
@ -225,12 +226,11 @@ public class InspectPageParser extends PageParser {
|
||||
addValue("mobKillCount", mobKillCount);
|
||||
addValue("deathCount", deathCount);
|
||||
|
||||
double activityIndex = profile.getActivityIndex(now);
|
||||
String[] activityIndexFormat = FormatUtils.readableActivityIndex(activityIndex);
|
||||
ActivityIndex activityIndex = profile.getActivityIndex(now);
|
||||
|
||||
addValue("activityIndexNumber", FormatUtils.cutDecimals(activityIndex));
|
||||
addValue("activityIndexColor", activityIndexFormat[0]);
|
||||
addValue("activityIndex", activityIndexFormat[1]);
|
||||
addValue("activityIndexNumber", activityIndex.getFormattedValue());
|
||||
addValue("activityIndexColor", activityIndex.getColor());
|
||||
addValue("activityIndex", activityIndex.getGroup());
|
||||
|
||||
addValue("playerStatus", HtmlStructure.playerStatus(online, profile.getBannedOnServers(), profile.isOp()));
|
||||
|
||||
|
@ -212,20 +212,6 @@ public class FormatUtils {
|
||||
return df.format(d);
|
||||
}
|
||||
|
||||
public static String[] readableActivityIndex(double activityIndex) {
|
||||
if (activityIndex >= 3.5) {
|
||||
return new String[]{"green", "Very Active"};
|
||||
} else if (activityIndex >= 1.75) {
|
||||
return new String[]{"green", "Active"};
|
||||
} else if (activityIndex >= 1.0) {
|
||||
return new String[]{"lime", "Regular"};
|
||||
} else if (activityIndex >= 0.5) {
|
||||
return new String[]{"amber", "Irregular"};
|
||||
} else {
|
||||
return new String[]{"blue-gray", "Inactive"};
|
||||
}
|
||||
}
|
||||
|
||||
public static String formatIP(String ip) {
|
||||
StringBuilder b = new StringBuilder();
|
||||
int i = 0;
|
||||
|
@ -4,10 +4,9 @@ import com.djrapitops.plan.PlanPlugin;
|
||||
import com.djrapitops.plan.data.PlayerProfile;
|
||||
import com.djrapitops.plan.data.container.Session;
|
||||
import com.djrapitops.plan.data.container.StickyData;
|
||||
import com.djrapitops.plan.data.element.ActivityIndex;
|
||||
import com.djrapitops.plan.data.time.GMTimes;
|
||||
import com.djrapitops.plan.data.time.WorldTimes;
|
||||
import com.djrapitops.plan.utilities.FormatUtils;
|
||||
import com.djrapitops.plan.utilities.MiscUtils;
|
||||
import com.djrapitops.plugin.api.TimeAmount;
|
||||
import com.djrapitops.plugin.api.utility.log.Log;
|
||||
|
||||
@ -219,13 +218,13 @@ public class AnalysisUtils {
|
||||
if (!players.isEmpty()) {
|
||||
for (PlayerProfile player : players) {
|
||||
for (long date = time; date >= time - TimeAmount.MONTH.ms() * 2L; date -= TimeAmount.WEEK.ms()) {
|
||||
double activityIndex = player.getActivityIndex(date);
|
||||
String index = FormatUtils.readableActivityIndex(activityIndex)[1];
|
||||
ActivityIndex activityIndex = player.getActivityIndex(date);
|
||||
String activityGroup = activityIndex.getGroup();
|
||||
|
||||
Map<String, Set<UUID>> map = activityData.getOrDefault(date, new HashMap<>());
|
||||
Set<UUID> uuids = map.getOrDefault(index, new HashSet<>());
|
||||
Set<UUID> uuids = map.getOrDefault(activityGroup, new HashSet<>());
|
||||
uuids.add(player.getUuid());
|
||||
map.put(index, uuids);
|
||||
map.put(activityGroup, uuids);
|
||||
activityData.put(date, map);
|
||||
}
|
||||
}
|
||||
|
@ -1,7 +1,9 @@
|
||||
package com.djrapitops.plan.utilities.html.tables;
|
||||
|
||||
import com.djrapitops.plan.Plan;
|
||||
import com.djrapitops.plan.PlanPlugin;
|
||||
import com.djrapitops.plan.data.PlayerProfile;
|
||||
import com.djrapitops.plan.data.element.ActivityIndex;
|
||||
import com.djrapitops.plan.data.element.AnalysisContainer;
|
||||
import com.djrapitops.plan.data.element.TableContainer;
|
||||
import com.djrapitops.plan.data.plugin.PluginData;
|
||||
@ -55,10 +57,10 @@ public class PlayersTableCreator {
|
||||
|
||||
long lastSeen = profile.getLastSeen();
|
||||
|
||||
double activityIndex = profile.getActivityIndex(now);
|
||||
String readableIndex = FormatUtils.readableActivityIndex(activityIndex)[1];
|
||||
String activityString = FormatUtils.cutDecimals(activityIndex)
|
||||
+ (isBanned ? " (<b>Banned</b>)" : " (" + readableIndex + ")");
|
||||
ActivityIndex activityIndex = profile.getActivityIndex(now);
|
||||
String activityGroup = activityIndex.getGroup();
|
||||
String activityString = activityIndex.getFormattedValue()
|
||||
+ (isBanned ? " (<b>Banned</b>)" : " (" + activityGroup + ")");
|
||||
|
||||
String geoLocation = profile.getMostRecentGeoInfo().getGeolocation();
|
||||
html.append(Html.TABLELINE_PLAYERS.parse(
|
||||
|
@ -53,7 +53,7 @@ public class PlayerProfileTest {
|
||||
}
|
||||
p.setSessions(null, sessions);
|
||||
|
||||
assertEquals(5.0, p.getActivityIndex(date));
|
||||
assertEquals(5.0, p.getActivityIndex(date).getValue());
|
||||
}
|
||||
|
||||
@Test
|
||||
@ -77,7 +77,7 @@ public class PlayerProfileTest {
|
||||
}
|
||||
p.setSessions(null, sessions);
|
||||
|
||||
assertEquals(5.0, p.getActivityIndex(date));
|
||||
assertEquals(5.0, p.getActivityIndex(date).getValue());
|
||||
}
|
||||
|
||||
@Test
|
||||
@ -101,7 +101,7 @@ public class PlayerProfileTest {
|
||||
}
|
||||
p.setSessions(null, sessions);
|
||||
|
||||
assertTrue(2.0 <= p.getActivityIndex(date));
|
||||
assertTrue(2.0 <= p.getActivityIndex(date).getValue());
|
||||
}
|
||||
|
||||
@Test(timeout = 500)
|
||||
|
Loading…
Reference in New Issue
Block a user