diff options
5 files changed, 106 insertions, 17 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md index a2b5987..4cc8fd8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,9 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). ## [1.8.9-0.12.0] - unreleased ### Changed - Item age: show timestamp in the local timezone instead of "SkyBlock"-timezone (Eastern Time; also fixed the incorrect 12h ↔ 24h clock conversion) +- Improved 'being on SkyBlock' detection + - gave scoreboard more time to get detected + - also added config option to always (or never) enable SkyBlock event listeners ### Fixed - Fixed some possible problems with bad server connection diff --git a/src/main/java/de/cowtipper/cowlection/config/MooConfig.java b/src/main/java/de/cowtipper/cowlection/config/MooConfig.java index 8dadc83..b89f4de 100644 --- a/src/main/java/de/cowtipper/cowlection/config/MooConfig.java +++ b/src/main/java/de/cowtipper/cowlection/config/MooConfig.java @@ -57,6 +57,7 @@ public class MooConfig { public static boolean showGuildNotifications; public static boolean doBestFriendsOnlineCheck; // Category: SkyBlock + private static String enableSkyBlockOnlyFeatures; public static int tooltipToggleKeyBinding; private static String tooltipAuctionHousePriceEach; private static String tooltipItemAge; @@ -267,6 +268,11 @@ public class MooConfig { configCat = new MooConfigCategory("SkyBlock", "skyblock"); configCategories.add(configCat); + // Sub-Category: SkyBlock-only features + subCat = configCat.addSubCategory("SkyBlock-only features"); + Property propEnableSkyBlockOnlyFeatures = subCat.addConfigEntry(cfg.get(configCat.getConfigName(), + "enableSkyBlockOnlyFeatures", "on SkyBlock", "Enable SkyBlock-only features?", new String[]{"on SkyBlock", "always", "never"})); + // Sub-Category: Tooltip enhancements subCat = configCat.addSubCategory("Tooltip enhancements"); @@ -419,6 +425,7 @@ public class MooConfig { showGuildNotifications = propShowGuildNotifications.getBoolean(); doBestFriendsOnlineCheck = propDoBestFriendsOnlineCheck.getBoolean(); // Category: SkyBlock + enableSkyBlockOnlyFeatures = propEnableSkyBlockOnlyFeatures.getString(); tooltipToggleKeyBinding = propTooltipToggleKeyBinding.getInt(); tooltipAuctionHousePriceEach = propTooltipAuctionHousePriceEach.getString(); tooltipItemAge = propTooltipItemAge.getString(); @@ -460,6 +467,7 @@ public class MooConfig { propShowGuildNotifications.set(showGuildNotifications); propDoBestFriendsOnlineCheck.set(doBestFriendsOnlineCheck); // Category: SkyBlock + propEnableSkyBlockOnlyFeatures.set(enableSkyBlockOnlyFeatures); propTooltipToggleKeyBinding.set(tooltipToggleKeyBinding); propTooltipAuctionHousePriceEach.set(tooltipAuctionHousePriceEach); propTooltipItemAge.set(tooltipItemAge); @@ -561,6 +569,10 @@ public class MooConfig { } // Category: SkyBlock + public static Setting getEnableSkyBlockOnlyFeatures() { + return Setting.get(MooConfig.enableSkyBlockOnlyFeatures); + } + public static Setting getTooltipAuctionHousePriceEachDisplay() { return Setting.get(tooltipAuctionHousePriceEach); } @@ -674,6 +686,7 @@ public class MooConfig { case "never": case "disabled": return DISABLED; + case "on SkyBlock": case "key press": case "as tooltip ①§0⬛": return SPECIAL; diff --git a/src/main/java/de/cowtipper/cowlection/listener/PlayerListener.java b/src/main/java/de/cowtipper/cowlection/listener/PlayerListener.java index d92dd6f..b62782d 100644 --- a/src/main/java/de/cowtipper/cowlection/listener/PlayerListener.java +++ b/src/main/java/de/cowtipper/cowlection/listener/PlayerListener.java @@ -6,6 +6,7 @@ import de.cowtipper.cowlection.config.MooConfig; import de.cowtipper.cowlection.event.ApiErrorEvent; 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.TickDelay; import net.minecraft.client.Minecraft; @@ -27,6 +28,7 @@ import net.minecraftforge.common.MinecraftForge; import net.minecraftforge.event.entity.player.PlayerSetSpawnEvent; import net.minecraftforge.fml.common.eventhandler.SubscribeEvent; import net.minecraftforge.fml.common.gameevent.InputEvent; +import net.minecraftforge.fml.common.gameevent.TickEvent; import net.minecraftforge.fml.common.network.FMLNetworkEvent; import org.lwjgl.input.Keyboard; @@ -36,6 +38,7 @@ public class PlayerListener { private static SkyBlockListener skyBlockListener; private boolean isPlayerJoiningServer; private boolean isOnSkyBlock; + private AbortableRunnable checkScoreboard; public PlayerListener(Cowlection main) { this.main = main; @@ -108,22 +111,80 @@ public class PlayerListener { @SubscribeEvent public void onWorldEnter(PlayerSetSpawnEvent e) { isPlayerJoiningServer = false; - // check if player is on SkyBlock or on another gamemode - new TickDelay(() -> { - ScoreObjective scoreboardSidebar = e.entityPlayer.worldObj.getScoreboard().getObjectiveInDisplaySlot(1); - boolean wasOnSkyBlock = isOnSkyBlock; - isOnSkyBlock = (scoreboardSidebar != null && EnumChatFormatting.getTextWithoutFormattingCodes(scoreboardSidebar.getDisplayName()).startsWith("SKYBLOCK")); - - if (!wasOnSkyBlock && isOnSkyBlock) { - // player wasn't on SkyBlock before but now is on SkyBlock - main.getLogger().info("Entered SkyBlock! Registering SkyBlock listeners"); - registerSkyBlockListeners(); - } 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"); - } - }, 40); // 2 second delay, making sure scoreboard got sent + + if (MooConfig.getEnableSkyBlockOnlyFeatures() == MooConfig.Setting.ALWAYS) { + main.getLogger().info("Registering SkyBlock listeners"); + isOnSkyBlock = true; + registerSkyBlockListeners(); + } else if (MooConfig.getEnableSkyBlockOnlyFeatures() == MooConfig.Setting.SPECIAL) { // only on SkyBlock + stopScoreboardChecker(); + + // check if player is on SkyBlock or on another gamemode + checkScoreboard = new AbortableRunnable() { + private int retries = 20 * 20; // retry for up to 20 seconds + + @SubscribeEvent + public void onTickCheckScoreboard(TickEvent.ClientTickEvent e) { + if (!stopped && e.phase == TickEvent.Phase.END) { + if (Minecraft.getMinecraft().theWorld == null || retries <= 0) { + // already stopped; or world gone, probably disconnected; or no retries left (took too long [20 seconds not enough?] or is not on SkyBlock): stop! + stop(); + return; + } + retries--; + ScoreObjective scoreboardSidebar = Minecraft.getMinecraft().theWorld.getScoreboard().getObjectiveInDisplaySlot(1); + if (scoreboardSidebar == null && retries >= 0) { + // scoreboard hasn't loaded yet, retry next tick + return; + } + + // ... either scoreboard has loaded now or no more retries left + + boolean wasOnSkyBlock = isOnSkyBlock; + isOnSkyBlock = (scoreboardSidebar != null && EnumChatFormatting.getTextWithoutFormattingCodes(scoreboardSidebar.getDisplayName()).startsWith("SKYBLOCK")); + + if (!wasOnSkyBlock && isOnSkyBlock) { + // player wasn't on SkyBlock before but now is on SkyBlock + main.getLogger().info("Entered SkyBlock! Registering SkyBlock listeners"); + registerSkyBlockListeners(); + } 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"); + } + stop(); + } + } + + @Override + public void stop() { + if (!stopped) { + stopped = true; + retries = -1; + MinecraftForge.EVENT_BUS.unregister(this); + stopScoreboardChecker(); + } + } + + @Override + public void run() { + MinecraftForge.EVENT_BUS.register(this); + } + }; + + new TickDelay(checkScoreboard, 40); // 2 second delay + retrying for 20 seconds, making sure scoreboard got sent + } else if (MooConfig.getEnableSkyBlockOnlyFeatures() == MooConfig.Setting.DISABLED) { + isOnSkyBlock = false; + unregisterSkyBlockListeners(); + } + } + + private void stopScoreboardChecker() { + if (checkScoreboard != null) { + // there is still a scoreboard-checker running, stop it + checkScoreboard.stop(); + checkScoreboard = null; + } } public static boolean registerSkyBlockListeners() { @@ -142,7 +203,6 @@ public class PlayerListener { dungeonsListener = null; MinecraftForge.EVENT_BUS.unregister(skyBlockListener); skyBlockListener = null; - Cowlection.getInstance().getLogger().info("Left SkyBlock"); } } diff --git a/src/main/java/de/cowtipper/cowlection/util/AbortableRunnable.java b/src/main/java/de/cowtipper/cowlection/util/AbortableRunnable.java new file mode 100644 index 0000000..735a4d2 --- /dev/null +++ b/src/main/java/de/cowtipper/cowlection/util/AbortableRunnable.java @@ -0,0 +1,11 @@ +package de.cowtipper.cowlection.util; + +public abstract class AbortableRunnable implements Runnable { + protected boolean stopped = false; + + public abstract void run(); + + public void stop() { + stopped = true; + } +} diff --git a/src/main/resources/assets/cowlection/lang/en_US.lang b/src/main/resources/assets/cowlection/lang/en_US.lang index 516d997..1699e2f 100644 --- a/src/main/resources/assets/cowlection/lang/en_US.lang +++ b/src/main/resources/assets/cowlection/lang/en_US.lang @@ -22,6 +22,8 @@ cowlection.config.showGuildNotifications=Show guild notifications cowlection.config.showGuildNotifications.tooltip=Set to true to receive guild members' login/logout messages, set to false hide them. 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.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 |