Refactored ActivityIndex to a new class.

This commit is contained in:
Rsl1122 2018-01-13 12:54:37 +02:00
parent 96def3ddbb
commit cd95a0a68e
10 changed files with 167 additions and 119 deletions

View File

@ -2,9 +2,10 @@ package com.djrapitops.plan.command.commands;
import com.djrapitops.plan.PlanPlugin; import com.djrapitops.plan.PlanPlugin;
import com.djrapitops.plan.data.PlayerProfile; 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.Locale;
import com.djrapitops.plan.settings.locale.Msg; 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.Condition;
import com.djrapitops.plan.utilities.FormatUtils; import com.djrapitops.plan.utilities.FormatUtils;
import com.djrapitops.plan.utilities.MiscUtils; 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()); 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 + " Registered: " + colS + FormatUtils.formatTimeStampYear(profile.getRegistered()));
sender.sendMessage(colT + ball + " " + colM + " Last Seen: " + colS + FormatUtils.formatTimeStampYear(profile.getLastSeen())); sender.sendMessage(colT + ball + " " + colM + " Last Seen: " + colS + FormatUtils.formatTimeStampYear(profile.getLastSeen()));
sender.sendMessage(colT + ball + " " + colM + " Logged in from: " + colS + profile.getMostRecentGeoInfo().getGeolocation()); sender.sendMessage(colT + ball + " " + colM + " Logged in from: " + colS + profile.getMostRecentGeoInfo().getGeolocation());

View File

@ -4,16 +4,16 @@
*/ */
package com.djrapitops.plan.data; package com.djrapitops.plan.data;
import com.djrapitops.plan.PlanPlugin;
import com.djrapitops.plan.data.container.Action; import com.djrapitops.plan.data.container.Action;
import com.djrapitops.plan.data.container.GeoInfo; import com.djrapitops.plan.data.container.GeoInfo;
import com.djrapitops.plan.data.container.PlayerKill; 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.element.ActivityIndex;
import com.djrapitops.plan.data.time.WorldTimes; 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.MiscUtils;
import com.djrapitops.plan.utilities.comparators.ActionComparator; import com.djrapitops.plan.utilities.comparators.ActionComparator;
import com.djrapitops.plan.utilities.comparators.GeoInfoComparator; import com.djrapitops.plan.utilities.comparators.GeoInfoComparator;
import com.djrapitops.plugin.api.TimeAmount;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
import org.bukkit.Location; import org.bukkit.Location;
import org.bukkit.OfflinePlayer; import org.bukkit.OfflinePlayer;
@ -57,7 +57,7 @@ public class PlayerProfile implements OfflinePlayer {
private Map<String, String> pluginReplaceMap; private Map<String, String> pluginReplaceMap;
// Value that requires lot of processing // Value that requires lot of processing
private Map<Long, Double> activityIndex; private Map<Long, ActivityIndex> activityIndexCache;
public PlayerProfile(UUID uuid, String name, long registered) { public PlayerProfile(UUID uuid, String name, long registered) {
this.uuid = uuid; this.uuid = uuid;
@ -76,88 +76,17 @@ public class PlayerProfile implements OfflinePlayer {
geoInformation = new ArrayList<>(); geoInformation = new ArrayList<>();
pluginReplaceMap = new HashMap<>(); pluginReplaceMap = new HashMap<>();
activityIndex = new HashMap<>(); activityIndexCache = new HashMap<>();
} }
// Calculating Getters // Calculating Getters
public double getActivityIndex(long date) { public ActivityIndex getActivityIndex(long date) {
Double activityIndx = activityIndex.get(date); ActivityIndex index = activityIndexCache.get(date);
if (activityIndx != null) { if (index == null) {
return activityIndx; index = new ActivityIndex(this, date);
activityIndexCache.put(date, index);
} }
return 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;
} }
/** /**

View File

@ -15,7 +15,7 @@ public class StickyData {
private Integer onlineOnJoin; private Integer onlineOnJoin;
public StickyData(PlayerProfile player) { 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()) { for (Action action : player.getActions()) {
if (messagesSent == null && action.getDoneAction() == Actions.FIRST_LOGOUT) { if (messagesSent == null && action.getDoneAction() == Actions.FIRST_LOGOUT) {
String additionalInfo = action.getAdditionalInfo(); String additionalInfo = action.getAdditionalInfo();

View File

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

View File

@ -155,7 +155,7 @@ public class HealthNotes {
private void activePlayerPlaytimeChange() { private void activePlayerPlaytimeChange() {
List<PlayerProfile> currentActivePlayers = analysisData.getPlayers().stream() List<PlayerProfile> currentActivePlayers = analysisData.getPlayers().stream()
.filter(player -> player.getActivityIndex(now) >= 1.75) .filter(player -> player.getActivityIndex(now).getValue() >= 1.75)
.collect(Collectors.toList()); .collect(Collectors.toList());
long twoWeeksAgo = now - TimeAmount.WEEK.ms() * 2L; long twoWeeksAgo = now - TimeAmount.WEEK.ms() * 2L;

View File

@ -9,11 +9,12 @@ import com.djrapitops.plan.api.exceptions.ParseException;
import com.djrapitops.plan.data.PlayerProfile; import com.djrapitops.plan.data.PlayerProfile;
import com.djrapitops.plan.data.container.Action; import com.djrapitops.plan.data.container.Action;
import com.djrapitops.plan.data.container.Session; 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.data.time.WorldTimes;
import com.djrapitops.plan.database.Database; 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.Theme;
import com.djrapitops.plan.settings.theme.ThemeVal; 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.FormatUtils;
import com.djrapitops.plan.utilities.MiscUtils; import com.djrapitops.plan.utilities.MiscUtils;
import com.djrapitops.plan.utilities.analysis.AnalysisUtils; import com.djrapitops.plan.utilities.analysis.AnalysisUtils;
@ -225,12 +226,11 @@ public class InspectPageParser extends PageParser {
addValue("mobKillCount", mobKillCount); addValue("mobKillCount", mobKillCount);
addValue("deathCount", deathCount); addValue("deathCount", deathCount);
double activityIndex = profile.getActivityIndex(now); ActivityIndex activityIndex = profile.getActivityIndex(now);
String[] activityIndexFormat = FormatUtils.readableActivityIndex(activityIndex);
addValue("activityIndexNumber", FormatUtils.cutDecimals(activityIndex)); addValue("activityIndexNumber", activityIndex.getFormattedValue());
addValue("activityIndexColor", activityIndexFormat[0]); addValue("activityIndexColor", activityIndex.getColor());
addValue("activityIndex", activityIndexFormat[1]); addValue("activityIndex", activityIndex.getGroup());
addValue("playerStatus", HtmlStructure.playerStatus(online, profile.getBannedOnServers(), profile.isOp())); addValue("playerStatus", HtmlStructure.playerStatus(online, profile.getBannedOnServers(), profile.isOp()));

View File

@ -212,20 +212,6 @@ public class FormatUtils {
return df.format(d); 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) { public static String formatIP(String ip) {
StringBuilder b = new StringBuilder(); StringBuilder b = new StringBuilder();
int i = 0; int i = 0;

View File

@ -4,10 +4,9 @@ import com.djrapitops.plan.PlanPlugin;
import com.djrapitops.plan.data.PlayerProfile; import com.djrapitops.plan.data.PlayerProfile;
import com.djrapitops.plan.data.container.Session; import com.djrapitops.plan.data.container.Session;
import com.djrapitops.plan.data.container.StickyData; 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.GMTimes;
import com.djrapitops.plan.data.time.WorldTimes; 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.TimeAmount;
import com.djrapitops.plugin.api.utility.log.Log; import com.djrapitops.plugin.api.utility.log.Log;
@ -219,13 +218,13 @@ public class AnalysisUtils {
if (!players.isEmpty()) { if (!players.isEmpty()) {
for (PlayerProfile player : players) { for (PlayerProfile player : players) {
for (long date = time; date >= time - TimeAmount.MONTH.ms() * 2L; date -= TimeAmount.WEEK.ms()) { for (long date = time; date >= time - TimeAmount.MONTH.ms() * 2L; date -= TimeAmount.WEEK.ms()) {
double activityIndex = player.getActivityIndex(date); ActivityIndex activityIndex = player.getActivityIndex(date);
String index = FormatUtils.readableActivityIndex(activityIndex)[1]; String activityGroup = activityIndex.getGroup();
Map<String, Set<UUID>> map = activityData.getOrDefault(date, new HashMap<>()); 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()); uuids.add(player.getUuid());
map.put(index, uuids); map.put(activityGroup, uuids);
activityData.put(date, map); activityData.put(date, map);
} }
} }

View File

@ -1,7 +1,9 @@
package com.djrapitops.plan.utilities.html.tables; package com.djrapitops.plan.utilities.html.tables;
import com.djrapitops.plan.Plan; import com.djrapitops.plan.Plan;
import com.djrapitops.plan.PlanPlugin;
import com.djrapitops.plan.data.PlayerProfile; 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.AnalysisContainer;
import com.djrapitops.plan.data.element.TableContainer; import com.djrapitops.plan.data.element.TableContainer;
import com.djrapitops.plan.data.plugin.PluginData; import com.djrapitops.plan.data.plugin.PluginData;
@ -55,10 +57,10 @@ public class PlayersTableCreator {
long lastSeen = profile.getLastSeen(); long lastSeen = profile.getLastSeen();
double activityIndex = profile.getActivityIndex(now); ActivityIndex activityIndex = profile.getActivityIndex(now);
String readableIndex = FormatUtils.readableActivityIndex(activityIndex)[1]; String activityGroup = activityIndex.getGroup();
String activityString = FormatUtils.cutDecimals(activityIndex) String activityString = activityIndex.getFormattedValue()
+ (isBanned ? " (<b>Banned</b>)" : " (" + readableIndex + ")"); + (isBanned ? " (<b>Banned</b>)" : " (" + activityGroup + ")");
String geoLocation = profile.getMostRecentGeoInfo().getGeolocation(); String geoLocation = profile.getMostRecentGeoInfo().getGeolocation();
html.append(Html.TABLELINE_PLAYERS.parse( html.append(Html.TABLELINE_PLAYERS.parse(

View File

@ -53,7 +53,7 @@ public class PlayerProfileTest {
} }
p.setSessions(null, sessions); p.setSessions(null, sessions);
assertEquals(5.0, p.getActivityIndex(date)); assertEquals(5.0, p.getActivityIndex(date).getValue());
} }
@Test @Test
@ -77,7 +77,7 @@ public class PlayerProfileTest {
} }
p.setSessions(null, sessions); p.setSessions(null, sessions);
assertEquals(5.0, p.getActivityIndex(date)); assertEquals(5.0, p.getActivityIndex(date).getValue());
} }
@Test @Test
@ -101,7 +101,7 @@ public class PlayerProfileTest {
} }
p.setSessions(null, sessions); p.setSessions(null, sessions);
assertTrue(2.0 <= p.getActivityIndex(date)); assertTrue(2.0 <= p.getActivityIndex(date).getValue());
} }
@Test(timeout = 500) @Test(timeout = 500)