aboutsummaryrefslogtreecommitdiff
path: root/src/main/java/eu/olli
diff options
context:
space:
mode:
authorCow <cow@volloeko.de>2020-04-26 03:43:30 +0200
committerCow <cow@volloeko.de>2020-04-26 03:43:30 +0200
commit35553dceb9c683000095ce1a62b4e094234304bc (patch)
tree8ed09cd69ba877be4defe9583007333c8164f8f0 /src/main/java/eu/olli
parentf0686a8e45528e3dd682a6f7a69dd904730f6fb1 (diff)
downloadCowlection-35553dceb9c683000095ce1a62b4e094234304bc.tar.gz
Cowlection-35553dceb9c683000095ce1a62b4e094234304bc.tar.bz2
Cowlection-35553dceb9c683000095ce1a62b4e094234304bc.zip
Improved output of player stalking feature
- offline players now include 'offline for <duration>' - better handling of special cases (e.g. nicked players) - also: simplified API requests and config handling
Diffstat (limited to 'src/main/java/eu/olli')
-rw-r--r--src/main/java/eu/olli/cowmoonication/command/MooCommand.java20
-rw-r--r--src/main/java/eu/olli/cowmoonication/config/MooConfig.java53
-rw-r--r--src/main/java/eu/olli/cowmoonication/util/ApiUtils.java13
-rw-r--r--src/main/java/eu/olli/cowmoonication/util/SlothStalking.java22
-rw-r--r--src/main/java/eu/olli/cowmoonication/util/Utils.java30
5 files changed, 99 insertions, 39 deletions
diff --git a/src/main/java/eu/olli/cowmoonication/command/MooCommand.java b/src/main/java/eu/olli/cowmoonication/command/MooCommand.java
index a38eec7..58d01a5 100644
--- a/src/main/java/eu/olli/cowmoonication/command/MooCommand.java
+++ b/src/main/java/eu/olli/cowmoonication/command/MooCommand.java
@@ -1,5 +1,6 @@
package eu.olli.cowmoonication.command;
+import com.mojang.realmsclient.util.Pair;
import eu.olli.cowmoonication.Cowmoonication;
import eu.olli.cowmoonication.config.MooConfig;
import eu.olli.cowmoonication.config.MooGuiConfig;
@@ -15,7 +16,6 @@ import net.minecraft.command.ICommandSender;
import net.minecraft.event.ClickEvent;
import net.minecraft.event.HoverEvent;
import net.minecraft.util.*;
-import org.apache.commons.lang3.time.DurationFormatUtils;
import java.awt.*;
import java.io.IOException;
@@ -179,12 +179,24 @@ public class MooCommand extends CommandBase {
ApiUtils.fetchPlayerOfflineStatus(stalkedPlayer, slothStalking -> {
if (slothStalking == null) {
main.getChatHelper().sendMessage(EnumChatFormatting.RED, "Something went wrong contacting the Slothpixel API. Couldn't stalk " + EnumChatFormatting.DARK_RED + stalkedPlayer.getName() + EnumChatFormatting.RED + " but they appear to be offline currently.");
- } else if (slothStalking.getLastLogout() < 1) { // last_logout == null in API response
+ } else if (slothStalking.hasNeverJoinedHypixel()) {
+ main.getChatHelper().sendMessage(EnumChatFormatting.YELLOW, stalkedPlayer.getName() + EnumChatFormatting.YELLOW + " has " + EnumChatFormatting.GOLD + "never " + EnumChatFormatting.YELLOW + "been on Hypixel (or might be nicked).");
+ } else if (slothStalking.isHidingOnlineStatus()) {
main.getChatHelper().sendMessage(EnumChatFormatting.YELLOW, slothStalking.getPlayerNameFormatted() + EnumChatFormatting.YELLOW + " is hiding their online status.");
+ } else if (slothStalking.hasNeverLoggedOut()) {
+ Pair<String, String> lastOnline = Utils.getLastOnlineWords(slothStalking.getLastLogin());
+
+ main.getChatHelper().sendMessage(EnumChatFormatting.YELLOW, slothStalking.getPlayerNameFormatted() + EnumChatFormatting.YELLOW + " was last online " + EnumChatFormatting.GOLD + lastOnline.first() + EnumChatFormatting.YELLOW + " ago"
+ + (lastOnline.second() != null ? " (" + EnumChatFormatting.GOLD + lastOnline.second() + EnumChatFormatting.YELLOW + ")" : "") + ".");
} else {
- String offlineSince = DurationFormatUtils.formatDurationWords(System.currentTimeMillis() - slothStalking.getLastLogout(), true, true);
+ Pair<String, String> lastOnline = Utils.getLastOnlineWords(slothStalking.getLastLogout());
- main.getChatHelper().sendMessage(EnumChatFormatting.YELLOW, slothStalking.getPlayerNameFormatted() + EnumChatFormatting.YELLOW + " is " + EnumChatFormatting.GOLD + "offline" + EnumChatFormatting.YELLOW + " since " + EnumChatFormatting.GOLD + offlineSince + EnumChatFormatting.YELLOW + (slothStalking.getLastGame() != null ? " (last played gamemode: " + EnumChatFormatting.GOLD + slothStalking.getLastGame() + EnumChatFormatting.YELLOW + ")" : "") + ".");
+ main.getChatHelper().sendMessage(EnumChatFormatting.YELLOW, slothStalking.getPlayerNameFormatted() + EnumChatFormatting.YELLOW + " is " + EnumChatFormatting.GOLD + "offline" + EnumChatFormatting.YELLOW + " for " + EnumChatFormatting.GOLD + lastOnline.first() + EnumChatFormatting.YELLOW
+ + ((lastOnline.second() != null || slothStalking.getLastGame() != null) ? (" ("
+ + (lastOnline.second() != null ? EnumChatFormatting.GOLD + lastOnline.second() + EnumChatFormatting.YELLOW : "") // = last online date
+ + (lastOnline.second() != null && slothStalking.getLastGame() != null ? "; " : "") // = delimiter
+ + (slothStalking.getLastGame() != null ? "last played gamemode: " + EnumChatFormatting.GOLD + slothStalking.getLastGame() + EnumChatFormatting.YELLOW : "") // = last gamemode
+ + ")") : "") + ".");
}
});
}
diff --git a/src/main/java/eu/olli/cowmoonication/config/MooConfig.java b/src/main/java/eu/olli/cowmoonication/config/MooConfig.java
index a401dbb..41cec89 100644
--- a/src/main/java/eu/olli/cowmoonication/config/MooConfig.java
+++ b/src/main/java/eu/olli/cowmoonication/config/MooConfig.java
@@ -19,6 +19,7 @@ public class MooConfig {
public static boolean showGuildNotifications;
public static String moo;
private static Configuration cfg = null;
+ private List<String> propOrderGeneral;
public MooConfig(Configuration configuration) {
cfg = configuration;
@@ -68,36 +69,26 @@ public class MooConfig {
if (loadConfigFromFile) {
cfg.load();
}
+ propOrderGeneral = new ArrayList<>();
+
+ Property propDoUpdateCheck = addConfigEntry(cfg.get(Configuration.CATEGORY_CLIENT,
+ "doUpdateCheck", true, "Check for mod updates?"), true);
+ Property propShowBestFriendNotifications = addConfigEntry(cfg.get(Configuration.CATEGORY_CLIENT,
+ "showBestFriendNotifications", true, "Set to true to receive best friends' login/logout messages, set to false hide them."), true);
+ Property propShowFriendNotifications = addConfigEntry(cfg.get(Configuration.CATEGORY_CLIENT,
+ "showFriendNotifications", false, "Set to true to receive friends' login/logout messages, set to false hide them."), true);
+ Property propShowGuildNotifications = addConfigEntry(cfg.get(Configuration.CATEGORY_CLIENT,
+ "showGuildNotifications", false, "Set to true to receive guild members' login/logout messages, set to false hide them."), true);
+ Property propMoo = addConfigEntry(cfg.get(Configuration.CATEGORY_CLIENT,
+ "moo", "", "The answer to life the universe and everything. Don't edit this entry manually!", Utils.VALID_UUID_PATTERN), false);
- final boolean DO_UPDATE_CHECK = true;
- Property propDoUpdateCheck = cfg.get(Configuration.CATEGORY_CLIENT, "doUpdateCheck", DO_UPDATE_CHECK, "Check for mod updates?");
-
- final boolean SHOW_BEST_FRIEND_NOTIFICATIONS = true;
- Property propShowBestFriendNotifications = cfg.get(Configuration.CATEGORY_CLIENT, "showBestFriendNotifications", SHOW_BEST_FRIEND_NOTIFICATIONS, "Set to true to receive best friends' login/logout messages, set to false hide them.");
-
- final boolean SHOW_FRIEND_NOTIFICATIONS = false;
- Property propShowFriendNotifications = cfg.get(Configuration.CATEGORY_CLIENT, "showFriendNotifications", SHOW_FRIEND_NOTIFICATIONS, "Set to true to receive friends' login/logout messages, set to false hide them.");
-
- final boolean SHOW_GUILD_NOTIFICATIONS = false;
- Property propShowGuildNotifications = cfg.get(Configuration.CATEGORY_CLIENT, "showGuildNotifications", SHOW_GUILD_NOTIFICATIONS, "Set to true to receive guild members' login/logout messages, set to false hide them.");
-
- final String MOO = "";
- Property propMoo = cfg.get(Configuration.CATEGORY_CLIENT, "moo", MOO, "The answer to life the universe and everything. Don't edit this entry manually!", Utils.VALID_UUID_PATTERN);
- propMoo.setShowInGui(false);
-
- List<String> propOrderGeneral = new ArrayList<>();
- propOrderGeneral.add(propDoUpdateCheck.getName());
- propOrderGeneral.add(propShowBestFriendNotifications.getName());
- propOrderGeneral.add(propShowFriendNotifications.getName());
- propOrderGeneral.add(propShowGuildNotifications.getName());
- propOrderGeneral.add(propMoo.getName());
cfg.setCategoryPropertyOrder(Configuration.CATEGORY_CLIENT, propOrderGeneral);
if (readFieldsFromConfig) {
- doUpdateCheck = propDoUpdateCheck.getBoolean(DO_UPDATE_CHECK);
- showBestFriendNotifications = propShowBestFriendNotifications.getBoolean(SHOW_BEST_FRIEND_NOTIFICATIONS);
- showFriendNotifications = propShowFriendNotifications.getBoolean(SHOW_FRIEND_NOTIFICATIONS);
- showGuildNotifications = propShowGuildNotifications.getBoolean(SHOW_GUILD_NOTIFICATIONS);
+ doUpdateCheck = propDoUpdateCheck.getBoolean();
+ showBestFriendNotifications = propShowBestFriendNotifications.getBoolean();
+ showFriendNotifications = propShowFriendNotifications.getBoolean();
+ showGuildNotifications = propShowGuildNotifications.getBoolean();
moo = propMoo.getString();
}
@@ -112,6 +103,16 @@ public class MooConfig {
}
}
+ private Property addConfigEntry(Property property, boolean showInGui) {
+ if (showInGui) {
+ property.setLanguageKey(Cowmoonication.MODID + ".config." + property.getName());
+ } else {
+ property.setShowInGui(false);
+ }
+ propOrderGeneral.add(property.getName());
+ return property;
+ }
+
/**
* Should login/logout notifications be modified and thus monitored?
*
diff --git a/src/main/java/eu/olli/cowmoonication/util/ApiUtils.java b/src/main/java/eu/olli/cowmoonication/util/ApiUtils.java
index 2a62153..650c56d 100644
--- a/src/main/java/eu/olli/cowmoonication/util/ApiUtils.java
+++ b/src/main/java/eu/olli/cowmoonication/util/ApiUtils.java
@@ -37,8 +37,7 @@ public class ApiUtils {
}
private static Friend getFriend(String name) {
- try {
- BufferedReader reader = makeApiCall(NAME_TO_UUID_URL + name);
+ try (BufferedReader reader = makeApiCall(NAME_TO_UUID_URL + name)) {
if (reader == null) {
return Friend.FRIEND_NOT_FOUND;
} else {
@@ -55,8 +54,7 @@ public class ApiUtils {
}
private static String getCurrentName(Friend friend) {
- try {
- BufferedReader reader = makeApiCall(String.format(UUID_TO_NAME_URL, UUIDTypeAdapter.fromUUID(friend.getUuid())));
+ try (BufferedReader reader = makeApiCall(String.format(UUID_TO_NAME_URL, UUIDTypeAdapter.fromUUID(friend.getUuid())))) {
if (reader == null) {
return UUID_NOT_FOUND;
} else {
@@ -76,8 +74,7 @@ public class ApiUtils {
}
private static HyStalking stalkPlayer(Friend friend) {
- try {
- BufferedReader reader = makeApiCall(String.format(STALKING_URL_OFFICIAL, MooConfig.moo, UUIDTypeAdapter.fromUUID(friend.getUuid())));
+ try (BufferedReader reader = makeApiCall(String.format(STALKING_URL_OFFICIAL, MooConfig.moo, UUIDTypeAdapter.fromUUID(friend.getUuid())))) {
if (reader != null) {
return gson.fromJson(reader, HyStalking.class);
}
@@ -92,8 +89,7 @@ public class ApiUtils {
}
private static SlothStalking stalkOfflinePlayer(Friend stalkedPlayer) {
- try {
- BufferedReader reader = makeApiCall(String.format(STALKING_URL_UNOFFICIAL, UUIDTypeAdapter.fromUUID(stalkedPlayer.getUuid())));
+ try (BufferedReader reader = makeApiCall(String.format(STALKING_URL_UNOFFICIAL, UUIDTypeAdapter.fromUUID(stalkedPlayer.getUuid())))) {
if (reader != null) {
return gson.fromJson(reader, SlothStalking.class);
}
@@ -105,6 +101,7 @@ public class ApiUtils {
private static BufferedReader makeApiCall(String url) throws IOException {
HttpURLConnection connection = (HttpURLConnection) new URL(url).openConnection();
+ connection.setConnectTimeout(5000);
connection.setReadTimeout(5000);
connection.addRequestProperty("User-Agent", "Forge Mod " + Cowmoonication.MODNAME + "/" + Cowmoonication.VERSION + " (https://github.com/cow-mc/Cowmoonication/)");
diff --git a/src/main/java/eu/olli/cowmoonication/util/SlothStalking.java b/src/main/java/eu/olli/cowmoonication/util/SlothStalking.java
index bcd0e01..1cc7c22 100644
--- a/src/main/java/eu/olli/cowmoonication/util/SlothStalking.java
+++ b/src/main/java/eu/olli/cowmoonication/util/SlothStalking.java
@@ -2,9 +2,10 @@ package eu.olli.cowmoonication.util;
public class SlothStalking {
private String username;
+ private String rank;
private String rank_formatted;
// private boolean online;
- // private long last_login;
+ private long last_login;
private long last_logout;
private String last_game;
@@ -15,6 +16,10 @@ public class SlothStalking {
return rank_formatted.replace('&', 'ยง') + " " + username;
}
+ public long getLastLogin() {
+ return last_login;
+ }
+
public long getLastLogout() {
return last_logout;
}
@@ -22,4 +27,19 @@ public class SlothStalking {
public String getLastGame() {
return last_game;
}
+
+ public boolean hasNeverJoinedHypixel() {
+ // example player that has never joined Hypixel (as of April 2020): Joe
+ return rank == null && last_login == 0;
+ }
+
+ public boolean hasNeverLoggedOut() {
+ // example player that has no logout value (as of April 2020): Pig (in general accounts that haven't logged in for a few years)
+ return last_login != 0 && last_logout == 0;
+ }
+
+ public boolean isHidingOnlineStatus() {
+ // example players: any higher ranked player (mods, admins, ...)
+ return last_login == 0 && last_logout == 0;
+ }
}
diff --git a/src/main/java/eu/olli/cowmoonication/util/Utils.java b/src/main/java/eu/olli/cowmoonication/util/Utils.java
index dd68cc3..0ff4010 100644
--- a/src/main/java/eu/olli/cowmoonication/util/Utils.java
+++ b/src/main/java/eu/olli/cowmoonication/util/Utils.java
@@ -1,7 +1,11 @@
package eu.olli.cowmoonication.util;
+import com.mojang.realmsclient.util.Pair;
import org.apache.commons.lang3.text.WordUtils;
+import org.apache.commons.lang3.time.DateFormatUtils;
+import org.apache.commons.lang3.time.DurationFormatUtils;
+import java.util.concurrent.TimeUnit;
import java.util.regex.Pattern;
public final class Utils {
@@ -22,4 +26,30 @@ public final class Utils {
public static String fancyCase(String string) {
return WordUtils.capitalizeFully(string.replace('_', ' '));
}
+
+ /**
+ * Turn timestamp into pretty-formatted duration and date details.
+ *
+ * @param timestamp last login/logout
+ * @return 1st: duration between timestamp and now in words; 2nd: formatted date if time differences is >24h, otherwise null
+ */
+ public static Pair<String, String> getLastOnlineWords(long timestamp) {
+ long duration = System.currentTimeMillis() - timestamp;
+ long daysPast = TimeUnit.MILLISECONDS.toDays(duration);
+
+ String dateFormatted = null;
+ if (daysPast > 1) {
+ dateFormatted = DateFormatUtils.format(timestamp, "dd-MMM-yyyy");
+ }
+
+ if (daysPast > 31) {
+ return Pair.of(
+ DurationFormatUtils.formatPeriod(timestamp, System.currentTimeMillis(), (daysPast > 365 ? "y 'years' " : "") + "M 'months' d 'days'"),
+ dateFormatted);
+ } else {
+ return Pair.of(
+ DurationFormatUtils.formatDurationWords(duration, true, true),
+ dateFormatted);
+ }
+ }
}