aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCow <cow@volloeko.de>2020-12-21 17:39:35 +0100
committerCow <cow@volloeko.de>2020-12-21 17:39:35 +0100
commit1f58cab966b15f12f4dd979f48e047c936c5841a (patch)
tree93a0a739e1f6611797811cb9d8787c10e922bcf6
parent35fda52e2f38a66fb864f8f6a7552ef2078d3dea (diff)
downloadCowlection-1f58cab966b15f12f4dd979f48e047c936c5841a.tar.gz
Cowlection-1f58cab966b15f12f4dd979f48e047c936c5841a.tar.bz2
Cowlection-1f58cab966b15f12f4dd979f48e047c936c5841a.zip
Added server freshness-indicators
- ≈ when server was last restarted - cmd: `/moo worldage` - notifications when switching worlds (toggleable via config)
-rw-r--r--CHANGELOG.md4
-rw-r--r--README.md1
-rw-r--r--src/main/java/de/cowtipper/cowlection/command/MooCommand.java34
-rw-r--r--src/main/java/de/cowtipper/cowlection/config/MooConfig.java16
-rw-r--r--src/main/java/de/cowtipper/cowlection/listener/PlayerListener.java51
-rw-r--r--src/main/resources/assets/cowlection/lang/en_US.lang4
6 files changed, 109 insertions, 1 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md
index b96f2f0..73c6627 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -10,6 +10,10 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
- Short alias `/m` for `/moo` command
- Copy inventories to clipboard as JSON with <kbd>CTRL</kbd> + <kbd>C</kbs>
- Added sound when a best friend comes online (deactivated by default)
+- Check how long current world has been loaded
+ - ≈ when server was last restarted
+ - via command `/moo worldage`
+ - notification when joining a recently loaded or a very old server (toggleable via config)
### Changed
- Item age: show timestamp in the local timezone instead of "SkyBlock"-timezone (Eastern Time; also fixed the incorrect 12h ↔ 24h clock conversion)
diff --git a/README.md b/README.md
index 1661b74..54ade8d 100644
--- a/README.md
+++ b/README.md
@@ -28,6 +28,7 @@ It is a collection of different features mainly focused on Hypixel SkyBlock.
| Analyze minions on a private island | `/moo analyzeIsland` |
| Dungeon interfaces enhancements (normalize dungeon item stats, improved party finder) | Hold <kbd>shift</kbd> (configurable) while viewing a dungeon item tooltip |
| Dungeon performance tracker and overlay: Skill score calculation, class milestone tracker, destroyed crypts tracker, and elapsed time indicator | automatically; or with `/moo dungeon` |
+| Check how long current world has been loaded (≈ when the server was last restarted) | `/moo worldage` + `/moo config` &rarr; SkyBlock |
## Download
You can download the compiled .jar files from the [release section](https://github.com/cow-mc/Cowlection/releases).
diff --git a/src/main/java/de/cowtipper/cowlection/command/MooCommand.java b/src/main/java/de/cowtipper/cowlection/command/MooCommand.java
index d2f433d..51a14fe 100644
--- a/src/main/java/de/cowtipper/cowlection/command/MooCommand.java
+++ b/src/main/java/de/cowtipper/cowlection/command/MooCommand.java
@@ -16,6 +16,7 @@ import de.cowtipper.cowlection.search.GuiSearch;
import de.cowtipper.cowlection.util.*;
import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.GuiScreen;
+import net.minecraft.client.multiplayer.WorldClient;
import net.minecraft.client.settings.GameSettings;
import net.minecraft.command.*;
import net.minecraft.entity.Entity;
@@ -121,6 +122,36 @@ public class MooCommand extends CommandBase {
} else if (args[0].equalsIgnoreCase("whatyearisit") || args[0].equalsIgnoreCase("year")) {
long year = ((System.currentTimeMillis() - 1560275700000L) / (TimeUnit.HOURS.toMillis(124))) + 1;
main.getChatHelper().sendMessage(EnumChatFormatting.YELLOW, "It is SkyBlock year " + EnumChatFormatting.GOLD + year + EnumChatFormatting.YELLOW + ".");
+ } else if (args[0].equalsIgnoreCase("worldage")) {
+ long worldTime = Minecraft.getMinecraft().theWorld.getWorldTime();
+ new TickDelay(() -> {
+ WorldClient world = Minecraft.getMinecraft().theWorld;
+ if (world == null) {
+ return;
+ }
+ String msgPrefix;
+ long worldTime2 = world.getWorldTime();
+ if (worldTime > worldTime2 || (worldTime2 - worldTime) < 15) {
+ // time is frozen
+ worldTime2 = world.getTotalWorldTime();
+ msgPrefix = "World time seems to be frozen at around " + worldTime + " ticks. ";
+ if (worldTime2 > 24 * 60 * 60 * 20) {
+ // total world time >24h
+ main.getChatHelper().sendMessage(EnumChatFormatting.GOLD, msgPrefix + "However, how long this world is loaded cannot be determined.");
+ return;
+ }
+ msgPrefix += "However, this world is probably";
+ } else {
+ msgPrefix = "This world is";
+ }
+ long days = worldTime2 / 24000L + 1;
+ long minutes = days * 20;
+ long hours = minutes / 60;
+ minutes -= hours * 60;
+
+ main.getChatHelper().sendMessage(EnumChatFormatting.YELLOW, msgPrefix + " loaded around " + EnumChatFormatting.GOLD + days + " ingame days "
+ + EnumChatFormatting.YELLOW + "(= less than " + EnumChatFormatting.GOLD + (hours > 0 ? hours + " hours " : "") + (minutes > 0 ? minutes + " mins " : "") + ")");
+ }, 20);
}
//endregion
//region sub-commands: update mod
@@ -795,6 +826,7 @@ public class MooCommand extends CommandBase {
.appendSibling(createCmdHelpEntry("dungeon party", "SkyBlock Dungeons: Shows armor and dungeon info about current party members " + EnumChatFormatting.GRAY + "(alias: " + EnumChatFormatting.WHITE + "/" + getCommandName() + " dp" + EnumChatFormatting.GRAY + ") §d§l⚷"))
.appendSibling(createCmdHelpSection(3, "Miscellaneous"))
.appendSibling(createCmdHelpEntry("search", "Open Minecraft log search"))
+ .appendSibling(createCmdHelpEntry("worldage", "Check how long the current world is loaded"))
.appendSibling(createCmdHelpEntry("guiScale", "Change GUI scale"))
.appendSibling(createCmdHelpEntry("rr", "Alias for /r without auto-replacement to /msg"))
.appendSibling(createCmdHelpEntry("shrug", "¯\\_(ツ)_/¯"))
@@ -828,7 +860,7 @@ public class MooCommand extends CommandBase {
return getListOfStringsMatchingLastWord(args,
/* Best friends, friends & other players */ "stalk", "add", "remove", "list", "online", "nameChangeCheck",
/* SkyBlock */ "stalkskyblock", "skyblockstalk", "analyzeIsland", "dungeon",
- /* miscellaneous */ "config", "search", "guiscale", "rr", "shrug", "apikey",
+ /* miscellaneous */ "config", "search", "worldage", "guiscale", "rr", "shrug", "apikey",
/* update mod */ "update", "updateHelp", "version", "directory",
/* help */ "help",
/* rarely used aliases */ "askPolitelyWhereTheyAre", "askPolitelyAboutTheirSkyBlockProgress", "year", "whatyearisit");
diff --git a/src/main/java/de/cowtipper/cowlection/config/MooConfig.java b/src/main/java/de/cowtipper/cowlection/config/MooConfig.java
index 6922c2e..5266438 100644
--- a/src/main/java/de/cowtipper/cowlection/config/MooConfig.java
+++ b/src/main/java/de/cowtipper/cowlection/config/MooConfig.java
@@ -64,6 +64,8 @@ public class MooConfig {
public static boolean doBestFriendsOnlineCheck;
// Category: SkyBlock
private static String enableSkyBlockOnlyFeatures;
+ public static int notifyFreshServer;
+ public static int notifyOldServer;
public static int tooltipToggleKeyBinding;
private static String tooltipAuctionHousePriceEach;
private static String tooltipItemAge;
@@ -295,6 +297,16 @@ public class MooConfig {
Property propEnableSkyBlockOnlyFeatures = subCat.addConfigEntry(cfg.get(configCat.getConfigName(),
"enableSkyBlockOnlyFeatures", "on SkyBlock", "Enable SkyBlock-only features?", new String[]{"on SkyBlock", "always", "never"}));
+ // Sub-Category: Server age notifications
+ subCat = configCat.addSubCategory("Server age notifications");
+ subCat.addExplanations("Servers usually restart once they exceed " + EnumChatFormatting.YELLOW + "30-38 ingame days " + EnumChatFormatting.RESET + "(10-13 hours)",
+ "Use the command " + EnumChatFormatting.YELLOW + "/moo worldage " + EnumChatFormatting.RESET + "to check how long the current world is loaded.",
+ EnumChatFormatting.ITALIC + "Set a value to 0 to disable that notification.");
+ Property propNotifyFreshServer = subCat.addConfigEntry(cfg.get(configCat.getConfigName(),
+ "notifyFreshServer", 1, "Notify when a world is loaded <X ingame days", 0, 40));
+ Property propNotifyOldServer = subCat.addConfigEntry(cfg.get(configCat.getConfigName(),
+ "notifyOldServer", 30, "Notify when a world is loaded >X ingame days", 0, 40));
+
// Sub-Category: Tooltip enhancements
subCat = configCat.addSubCategory("Tooltip enhancements");
@@ -454,6 +466,8 @@ public class MooConfig {
doBestFriendsOnlineCheck = propDoBestFriendsOnlineCheck.getBoolean();
// Category: SkyBlock
enableSkyBlockOnlyFeatures = propEnableSkyBlockOnlyFeatures.getString();
+ notifyFreshServer = propNotifyFreshServer.getInt();
+ notifyOldServer = propNotifyOldServer.getInt();
tooltipToggleKeyBinding = propTooltipToggleKeyBinding.getInt();
tooltipAuctionHousePriceEach = propTooltipAuctionHousePriceEach.getString();
tooltipItemAge = propTooltipItemAge.getString();
@@ -503,6 +517,8 @@ public class MooConfig {
propDoBestFriendsOnlineCheck.set(doBestFriendsOnlineCheck);
// Category: SkyBlock
propEnableSkyBlockOnlyFeatures.set(enableSkyBlockOnlyFeatures);
+ propNotifyFreshServer.set(notifyFreshServer);
+ propNotifyOldServer.set(notifyOldServer);
propTooltipToggleKeyBinding.set(tooltipToggleKeyBinding);
propTooltipAuctionHousePriceEach.set(tooltipAuctionHousePriceEach);
propTooltipItemAge.set(tooltipItemAge);
diff --git a/src/main/java/de/cowtipper/cowlection/listener/PlayerListener.java b/src/main/java/de/cowtipper/cowlection/listener/PlayerListener.java
index dcf3bbf..a6f3660 100644
--- a/src/main/java/de/cowtipper/cowlection/listener/PlayerListener.java
+++ b/src/main/java/de/cowtipper/cowlection/listener/PlayerListener.java
@@ -8,12 +8,14 @@ import de.cowtipper.cowlection.listener.skyblock.DungeonsListener;
import de.cowtipper.cowlection.listener.skyblock.SkyBlockListener;
import de.cowtipper.cowlection.util.AbortableRunnable;
import de.cowtipper.cowlection.util.GsonUtils;
+import de.cowtipper.cowlection.util.MooChatComponent;
import de.cowtipper.cowlection.util.TickDelay;
import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.GuiChat;
import net.minecraft.client.gui.GuiScreen;
import net.minecraft.client.gui.inventory.GuiChest;
import net.minecraft.client.gui.inventory.GuiInventory;
+import net.minecraft.client.multiplayer.WorldClient;
import net.minecraft.client.settings.KeyBinding;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.inventory.ContainerChest;
@@ -116,6 +118,7 @@ public class PlayerListener {
main.getLogger().info("Registering SkyBlock listeners");
isOnSkyBlock = true;
registerSkyBlockListeners();
+ checkWorldAge();
} else if (MooConfig.getEnableSkyBlockOnlyFeatures() == MooConfig.Setting.SPECIAL) { // only on SkyBlock
stopScoreboardChecker();
@@ -147,10 +150,14 @@ public class PlayerListener {
// player wasn't on SkyBlock before but now is on SkyBlock
main.getLogger().info("Entered SkyBlock! Registering SkyBlock listeners");
registerSkyBlockListeners();
+ checkWorldAge();
} else if (wasOnSkyBlock && !isOnSkyBlock) {
// player was on SkyBlock before and is now in another gamemode
unregisterSkyBlockListeners();
main.getLogger().info("Leaving SkyBlock! Un-registering SkyBlock listeners");
+ } else if (wasOnSkyBlock /* && isOnSkyBlock */) {
+ // player is still on SkyBlock
+ checkWorldAge();
}
stop();
}
@@ -179,6 +186,50 @@ public class PlayerListener {
}
}
+ private void checkWorldAge() {
+ WorldClient theWorld = Minecraft.getMinecraft().theWorld;
+ if (MooConfig.notifyFreshServer == 0 && MooConfig.notifyOldServer == 0 || theWorld == null) {
+ return;
+ }
+ long worldTime = theWorld.getWorldTime();
+ new TickDelay(() -> {
+ WorldClient world = Minecraft.getMinecraft().theWorld;
+
+ if (world == null || theWorld != world || main.getDungeonCache().isInDungeon()) {
+ // no longer in a world, or not in the same world as before, or inside dungeons
+ return;
+ }
+ long worldTime2 = world.getWorldTime();
+
+ String infix = "";
+ if (worldTime > worldTime2 || (worldTime2 - worldTime) < 30) {
+ // time is frozen
+ worldTime2 = world.getTotalWorldTime();
+ if (worldTime2 > 24 * 60 * 60 * 20) {
+ // total world time >24h
+ return;
+ }
+ infix = "probably ";
+ }
+
+ long days = worldTime2 / 24000L + 1;
+ if (MooConfig.notifyFreshServer > 0 && days <= MooConfig.notifyFreshServer) {
+ // fresh server
+ long minutes = days * 20;
+ long hours = minutes / 60;
+ minutes -= hours * 60;
+ main.getChatHelper().sendMessage(new MooChatComponent("⚠ ").darkGreen()
+ .appendSibling(new MooChatComponent("This world is " + infix + "loaded around " + EnumChatFormatting.DARK_GREEN + days + " ingame days.").green()
+ .setHover(new MooChatComponent("= less than " + EnumChatFormatting.DARK_GREEN + (hours > 0 ? hours + " hours " : "") + (minutes > 0 ? minutes + " mins " : "")).green())));
+ } else if (MooConfig.notifyOldServer > 0 && days > MooConfig.notifyOldServer) {
+ // old server
+ main.getChatHelper().sendMessage(new MooChatComponent("⚠ ").red()
+ .appendSibling(new MooChatComponent("This server has not been restarted for " + EnumChatFormatting.RED + days + "+ ingame days!").gold()
+ .setHover(new MooChatComponent("Servers usually restart once they exceed 30-38 ingame days (10-13 hours)").yellow())));
+ }
+ }, 40);
+ }
+
private void stopScoreboardChecker() {
if (checkScoreboard != null) {
// there is still a scoreboard-checker running, stop it
diff --git a/src/main/resources/assets/cowlection/lang/en_US.lang b/src/main/resources/assets/cowlection/lang/en_US.lang
index ba15568..c1c7be5 100644
--- a/src/main/resources/assets/cowlection/lang/en_US.lang
+++ b/src/main/resources/assets/cowlection/lang/en_US.lang
@@ -32,6 +32,10 @@ cowlection.config.doBestFriendsOnlineCheck=Do best friends online check §d§l
cowlection.config.doBestFriendsOnlineCheck.tooltip=Set to true to check best friends' online status when joining a server, set to false to disable.\n§fDoes §dnot §fwork for staff members and players hiding their online status.\n§d§l⚷ §eRequires a valid API key!
cowlection.config.enableSkyBlockOnlyFeatures=Enable SkyBlock-only features
cowlection.config.enableSkyBlockOnlyFeatures.tooltip=§6When should SkyBlock-only features be active?\n§7§o(relog or change worlds after changing this option)\n §d➊ §fonly while being on SkyBlock §e(= disabled on other servers and in other gamemodes\n §d➋ §falways §e(= including other servers and gamemodes)\n §d➌ §fnever §e(§cNone §eof the SkyBlock-only features will work!)
+cowlection.config.notifyFreshServer=Notify when world is loaded <X days
+cowlection.config.notifyFreshServer.tooltip=Notify when entering a world that has been loaded less than X ingame days ago.\n§eSet to 0 to disable notifications!
+cowlection.config.notifyOldServer=Notify when server restarted ≥X days ago
+cowlection.config.notifyOldServer.tooltip=Notify when joining a server that hasn't restarted for X ingame days.\n§eSet to 0 to disable notifications!
cowlection.config.tooltipToggleKeyBinding=Key binding: toggle tooltip
cowlection.config.tooltipToggleKeyBinding.tooltip=Hold down this key to toggle tooltip if one of the following settings is set to 'key press'
cowlection.config.tooltipAuctionHousePriceEach=Auction house: price per item