From 04763619a9b0b0f54851cd1a141e717fbe053af8 Mon Sep 17 00:00:00 2001 From: ILikePlayingGames <22475143+ILikePlayingGames@users.noreply.github.com> Date: Mon, 25 Dec 2023 02:59:07 -0500 Subject: [PATCH] Bug Fixes - Fix close window packet not being sent when the fancy warp menu is closed in certain situations - Convert SkyBlockJoinListener to chat-based detection for slight performance improvement - Settings and regular warp menu button logic fixes --- .../fancywarpmenu/FancyWarpMenu.java | 4 - .../fancywarpmenu/GameState.java | 23 ++- .../data/skyblockconstants/Menu.java | 44 ++++++ .../skyblockconstants/SkyBlockConstants.java | 14 ++ .../fancywarpmenu/gui/GuiFastTravel.java | 1 + .../gui/buttons/GuiButtonConfig.java | 17 +-- .../hooks/EntityPlayerSPHook.java | 3 +- .../listeners/SkyBlockJoinListener.java | 99 +++++-------- .../listeners/WarpMenuListener.java | 139 +++++++++--------- .../fancywarpmenu/data/skyBlockConstants.json | 3 +- 10 files changed, 200 insertions(+), 147 deletions(-) create mode 100644 src/main/java/ca/tirelesstraveler/fancywarpmenu/data/skyblockconstants/Menu.java diff --git a/src/main/java/ca/tirelesstraveler/fancywarpmenu/FancyWarpMenu.java b/src/main/java/ca/tirelesstraveler/fancywarpmenu/FancyWarpMenu.java index 5a1ca71..73ca333 100644 --- a/src/main/java/ca/tirelesstraveler/fancywarpmenu/FancyWarpMenu.java +++ b/src/main/java/ca/tirelesstraveler/fancywarpmenu/FancyWarpMenu.java @@ -140,10 +140,6 @@ public WarpMenuListener getWarpMenuListener() { return warpMenuListener; } - public boolean isPlayerOnSkyBlock() { - return skyblockJoinListener.isOnSkyBlock(); - } - public void reloadResources() { Minecraft.getMinecraft().refreshResources(); reloadSkyBlockConstants(); diff --git a/src/main/java/ca/tirelesstraveler/fancywarpmenu/GameState.java b/src/main/java/ca/tirelesstraveler/fancywarpmenu/GameState.java index 1a66526..7574dc7 100644 --- a/src/main/java/ca/tirelesstraveler/fancywarpmenu/GameState.java +++ b/src/main/java/ca/tirelesstraveler/fancywarpmenu/GameState.java @@ -22,18 +22,29 @@ package ca.tirelesstraveler.fancywarpmenu; +import ca.tirelesstraveler.fancywarpmenu.data.Settings; +import ca.tirelesstraveler.fancywarpmenu.data.skyblockconstants.Menu; + /** - * This class stores the state of the SkyBlock server the player is on. This information is used for the conditional hiding of warps. + * This class stores information about the state of the SkyBlock game the player is currently in. */ public class GameState { + /** + * Whether the player is currently on SkyBlock + */ private static boolean onSkyBlock; /** * Whether the current SkyBlock season is Late Winter */ private static boolean lateWinter; + /** + * Current in-game menu the player has open + */ + private static Menu currentMenu; + public static boolean isOnSkyBlock() { - return onSkyBlock; + return onSkyBlock || Settings.shouldSkipSkyBlockCheck(); } public static void setOnSkyBlock(boolean onSkyBlock) { @@ -47,4 +58,12 @@ public static boolean isLateWinter() { public static void setLateWinter(boolean lateWinter) { GameState.lateWinter = lateWinter; } + + public static Menu getCurrentMenu() { + return currentMenu; + } + + public static void setCurrentMenu(Menu currentMenu) { + GameState.currentMenu = currentMenu; + } } diff --git a/src/main/java/ca/tirelesstraveler/fancywarpmenu/data/skyblockconstants/Menu.java b/src/main/java/ca/tirelesstraveler/fancywarpmenu/data/skyblockconstants/Menu.java new file mode 100644 index 0000000..ab56f30 --- /dev/null +++ b/src/main/java/ca/tirelesstraveler/fancywarpmenu/data/skyblockconstants/Menu.java @@ -0,0 +1,44 @@ +/* + * Copyright (c) 2023. TirelessTraveler + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, + * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR + * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE + * OR OTHER DEALINGS IN THE SOFTWARE. + */ + +package ca.tirelesstraveler.fancywarpmenu.data.skyblockconstants; + +/** + * In-game menus, not serialized + */ +public enum Menu { + /** Value used when player is not in a menu or in an unknown or irrelevant menu */ + NONE("None"), + SKYBLOCK_MENU("SkyBlock Menu"), + FAST_TRAVEL("Fast Travel"), + PORHTAL("Porhtal"); + + /** Title of menu as it appears on the top of the {@code GuiChest}*/ + private final String MENU_TITLE; + Menu(String menuTitle) { + MENU_TITLE = menuTitle; + } + + public String getMenuTitle() { + return MENU_TITLE; + } +} diff --git a/src/main/java/ca/tirelesstraveler/fancywarpmenu/data/skyblockconstants/SkyBlockConstants.java b/src/main/java/ca/tirelesstraveler/fancywarpmenu/data/skyblockconstants/SkyBlockConstants.java index c8cfb2e..ad5aff5 100644 --- a/src/main/java/ca/tirelesstraveler/fancywarpmenu/data/skyblockconstants/SkyBlockConstants.java +++ b/src/main/java/ca/tirelesstraveler/fancywarpmenu/data/skyblockconstants/SkyBlockConstants.java @@ -22,6 +22,8 @@ package ca.tirelesstraveler.fancywarpmenu.data.skyblockconstants; +import org.apache.commons.lang3.StringUtils; + import java.util.List; import static ca.tirelesstraveler.fancywarpmenu.data.DataCommon.gson; @@ -31,8 +33,12 @@ public class SkyBlockConstants { private SkyBlockConstants() { } + /** Chat messages sent by the server when a warp attempt succeeds or fails */ private WarpMessages warpMessages; + /** Names of the warp command and its aliases */ private List warpCommandVariants; + /** Chat messages are checked to see if they start with this string in order to see if the player joined SkyBlock */ + private String skyBlockJoinMessage; public WarpMessages getWarpMessages() { return warpMessages; @@ -42,6 +48,10 @@ public List getWarpCommandVariants() { return warpCommandVariants; } + public String getSkyBlockJoinMessage() { + return skyBlockJoinMessage; + } + @Override public String toString() { return gson.toJson(this); @@ -61,5 +71,9 @@ public static void validateSkyBlockConstants(SkyBlockConstants skyBlockConstants for (WarpCommandVariant warpCommandVariant : skyBlockConstants.warpCommandVariants) { WarpCommandVariant.validateWarpCommandVariant(warpCommandVariant); } + + if (StringUtils.isEmpty(skyBlockConstants.skyBlockJoinMessage)) { + throw new IllegalArgumentException("SkyBlock join message cannot be null or empty."); + } } } diff --git a/src/main/java/ca/tirelesstraveler/fancywarpmenu/gui/GuiFastTravel.java b/src/main/java/ca/tirelesstraveler/fancywarpmenu/gui/GuiFastTravel.java index 915899e..d1a96ed 100644 --- a/src/main/java/ca/tirelesstraveler/fancywarpmenu/gui/GuiFastTravel.java +++ b/src/main/java/ca/tirelesstraveler/fancywarpmenu/gui/GuiFastTravel.java @@ -71,6 +71,7 @@ protected void actionPerformed(GuiButton button) { } else if (button instanceof GuiButtonConfig) { mc.displayGuiScreen(new FancyWarpMenuConfigScreen(this)); } else if (button instanceof GuiButtonRegularWarpMenu) { + Settings.setWarpMenuEnabled(false); sendCommand("/warp"); } } diff --git a/src/main/java/ca/tirelesstraveler/fancywarpmenu/gui/buttons/GuiButtonConfig.java b/src/main/java/ca/tirelesstraveler/fancywarpmenu/gui/buttons/GuiButtonConfig.java index 78d8512..c0a5dd7 100644 --- a/src/main/java/ca/tirelesstraveler/fancywarpmenu/gui/buttons/GuiButtonConfig.java +++ b/src/main/java/ca/tirelesstraveler/fancywarpmenu/gui/buttons/GuiButtonConfig.java @@ -23,13 +23,14 @@ package ca.tirelesstraveler.fancywarpmenu.gui.buttons; import ca.tirelesstraveler.fancywarpmenu.FancyWarpMenu; +import ca.tirelesstraveler.fancywarpmenu.data.Settings; import ca.tirelesstraveler.fancywarpmenu.data.layout.ConfigButton; import ca.tirelesstraveler.fancywarpmenu.data.layout.Island; -import ca.tirelesstraveler.fancywarpmenu.data.Settings; -import ca.tirelesstraveler.fancywarpmenu.gui.GuiFancyWarp; +import ca.tirelesstraveler.fancywarpmenu.data.skyblockconstants.Menu; import ca.tirelesstraveler.fancywarpmenu.gui.grid.GridRectangle; import ca.tirelesstraveler.fancywarpmenu.gui.grid.ScaledGrid; import ca.tirelesstraveler.fancywarpmenu.gui.transitions.ScaleTransition; +import ca.tirelesstraveler.fancywarpmenu.listeners.WarpMenuListener; import net.minecraft.client.Minecraft; import net.minecraft.client.gui.ScaledResolution; import net.minecraft.client.resources.I18n; @@ -83,15 +84,13 @@ public void drawButton(Minecraft mc, int mouseX, int mouseY) { @Override public boolean mousePressed(Minecraft mc, int mouseX, int mouseY) { + WarpMenuListener warpMenuListener = FancyWarpMenu.getInstance().getWarpMenuListener(); boolean clicked = super.mousePressed(mc, mouseX, mouseY); - if (clicked && !(mc.currentScreen instanceof GuiFancyWarp)) { - if (!Settings.isWarpMenuEnabled()) { - Settings.setWarpMenuEnabled(true); - mc.thePlayer.addChatMessage(new ChatComponentTranslation("fancywarpmenu.messages.fancyWarpMenuEnabled").setChatStyle(new ChatStyle().setColor(EnumChatFormatting.GREEN))); - } - - FancyWarpMenu.getInstance().getWarpMenuListener().createFastTravelMenu(true); + if (clicked && !Settings.isWarpMenuEnabled()) { + Settings.setWarpMenuEnabled(true); + mc.thePlayer.addChatMessage(new ChatComponentTranslation("fancywarpmenu.messages.fancyWarpMenuEnabled").setChatStyle(new ChatStyle().setColor(EnumChatFormatting.GREEN))); + warpMenuListener.createFastTravelMenu(Menu.FAST_TRAVEL, false); } return clicked; diff --git a/src/main/java/ca/tirelesstraveler/fancywarpmenu/hooks/EntityPlayerSPHook.java b/src/main/java/ca/tirelesstraveler/fancywarpmenu/hooks/EntityPlayerSPHook.java index 9d92f75..1e28e8c 100644 --- a/src/main/java/ca/tirelesstraveler/fancywarpmenu/hooks/EntityPlayerSPHook.java +++ b/src/main/java/ca/tirelesstraveler/fancywarpmenu/hooks/EntityPlayerSPHook.java @@ -1,6 +1,7 @@ package ca.tirelesstraveler.fancywarpmenu.hooks; import ca.tirelesstraveler.fancywarpmenu.FancyWarpMenu; +import ca.tirelesstraveler.fancywarpmenu.GameState; import ca.tirelesstraveler.fancywarpmenu.LogHelper; import ca.tirelesstraveler.fancywarpmenu.data.Settings; import ca.tirelesstraveler.fancywarpmenu.data.skyblockconstants.WarpCommandVariant; @@ -11,7 +12,7 @@ public class EntityPlayerSPHook { public static void onSendChatMessage(String message, CallbackInfo ci) { - if (Settings.isWarpMenuEnabled() && FancyWarpMenu.getInstance().isPlayerOnSkyBlock() && message.startsWith("/")) { + if (Settings.isWarpMenuEnabled() && GameState.isOnSkyBlock() && message.startsWith("/")) { WarpCommandVariant warpCommandVariant = WarpMenuListener.getWarpCommandVariant(message); LogHelper.logDebug("Caught sent command: {}", message); diff --git a/src/main/java/ca/tirelesstraveler/fancywarpmenu/listeners/SkyBlockJoinListener.java b/src/main/java/ca/tirelesstraveler/fancywarpmenu/listeners/SkyBlockJoinListener.java index e84f37e..48e6da6 100644 --- a/src/main/java/ca/tirelesstraveler/fancywarpmenu/listeners/SkyBlockJoinListener.java +++ b/src/main/java/ca/tirelesstraveler/fancywarpmenu/listeners/SkyBlockJoinListener.java @@ -24,13 +24,13 @@ import ca.tirelesstraveler.fancywarpmenu.FancyWarpMenu; import ca.tirelesstraveler.fancywarpmenu.GameState; -import ca.tirelesstraveler.fancywarpmenu.data.Settings; import io.netty.channel.ChannelHandler; -import io.netty.channel.ChannelHandlerContext; -import io.netty.channel.SimpleChannelInboundHandler; import net.minecraft.client.Minecraft; import net.minecraft.client.entity.EntityPlayerSP; -import net.minecraft.network.play.server.S3DPacketDisplayScoreboard; +import net.minecraft.client.gui.GuiDownloadTerrain; +import net.minecraft.scoreboard.Scoreboard; +import net.minecraftforge.client.event.ClientChatReceivedEvent; +import net.minecraftforge.client.event.GuiOpenEvent; import net.minecraftforge.fml.common.eventhandler.SubscribeEvent; import net.minecraftforge.fml.common.network.FMLNetworkEvent; import org.apache.logging.log4j.LogManager; @@ -40,86 +40,61 @@ * Forge event and packet listener that detects when the player joins/leaves SkyBlock */ @ChannelHandler.Sharable -public class SkyBlockJoinListener extends SimpleChannelInboundHandler { +public class SkyBlockJoinListener { private static final String SERVER_BRAND_START = "Hypixel BungeeCord"; - private static final String PACKET_LISTENER_NAME = String.format("%s:skyblock_join_listener", - FancyWarpMenu.getInstance().getModId()); private static final Logger logger = LogManager.getLogger(); private boolean serverBrandChecked; private boolean onHypixel; - public SkyBlockJoinListener() { - super(false); - } - - @SubscribeEvent - public void onClientConnectedToServer(FMLNetworkEvent.ClientConnectedToServerEvent e) { - if (e.manager.channel().pipeline().get(PACKET_LISTENER_NAME) == null) { - e.manager.channel().pipeline().addBefore("packet_handler", PACKET_LISTENER_NAME, this); - } - } - @SubscribeEvent public void onClientDisconnect(FMLNetworkEvent.ClientDisconnectionFromServerEvent e) { if (onHypixel) { serverBrandChecked = false; onHypixel = false; GameState.setOnSkyBlock(false); - logger.info("Disconnected from Hypixel."); + logger.debug("Disconnected from Hypixel."); } } - /** - * This method listens for {@link S3DPacketDisplayScoreboard} packets. These are sent once per world join/switch - * and contain the name of the game mode, thus making them excellent for checking whether the player is on SkyBlock. - */ - @Override - protected void channelRead0(ChannelHandlerContext channelHandlerContext, S3DPacketDisplayScoreboard packet) { - if (channelHandlerContext.channel().isOpen()) { - EntityPlayerSP thePlayer = Minecraft.getMinecraft().thePlayer; - - try { - logger.debug("Received S3DPacketDisplayScoreboard packet with title \"{}\"", packet.func_149370_d()); - - // Player hasn't been spawned yet, skip this packet. - if (thePlayer != null && thePlayer.getClientBrand() != null) { - if (!serverBrandChecked) { - onHypixel = thePlayer.getClientBrand().startsWith(SERVER_BRAND_START); - serverBrandChecked = true; + @SubscribeEvent + public void onGuiOpen(GuiOpenEvent event) { + // Reset on world switch + if (event.gui instanceof GuiDownloadTerrain) { + GameState.setOnSkyBlock(false); + } + } - if (onHypixel) { - logger.info("Player joined Hypixel."); - } + @SubscribeEvent + public void onChatMessageReceived(ClientChatReceivedEvent event) { + if (!serverBrandChecked || onHypixel) { + // type 0 is a standard chat message + if (event.type == 0 && event.message.getUnformattedText().startsWith( + FancyWarpMenu.getSkyBlockConstants().getSkyBlockJoinMessage())) { + EntityPlayerSP thePlayer = Minecraft.getMinecraft().thePlayer; + + if (!serverBrandChecked) { + onHypixel = thePlayer.getClientBrand().startsWith(SERVER_BRAND_START); + serverBrandChecked = true; + + if (onHypixel) { + logger.debug("Player joined Hypixel."); } + } - // 1 is the sidebar objective slot. - if (onHypixel && packet.func_149371_c() == 1) { - String objectiveName = packet.func_149370_d(); - boolean newSkyBlockState = objectiveName.equals("SBScoreboard"); - - if (newSkyBlockState && !GameState.isOnSkyBlock()) { - logger.info("Player joined SkyBlock."); - } else if (!newSkyBlockState && GameState.isOnSkyBlock()) { - logger.info("Player left SkyBlock."); - } + if (onHypixel) { + Scoreboard scoreboard = thePlayer.getWorldScoreboard(); + boolean newSkyBlockState = scoreboard != null && scoreboard.getObjective("SBScoreboard") != null; - GameState.setOnSkyBlock(newSkyBlockState); + if (newSkyBlockState && !GameState.isOnSkyBlock()) { + logger.debug("Player joined SkyBlock."); + } else if (!newSkyBlockState && GameState.isOnSkyBlock()) { + logger.debug("Player left SkyBlock."); } + + GameState.setOnSkyBlock(newSkyBlockState); } - } catch (RuntimeException e) { - logger.error(String.format("SkyBlock Join Check Failed: %s" + - "\nBrand: %s" + - "\nPacket contents:" + - "\n Position: %s" + - "\n Score Name: %s", e.getMessage(), thePlayer.getClientBrand(), packet.func_149371_c(), packet.func_149370_d()), e); } } - - channelHandlerContext.fireChannelRead(packet); - } - - public boolean isOnSkyBlock() { - return (Settings.isDebugModeEnabled() && Settings.shouldSkipSkyBlockCheck()) || GameState.isOnSkyBlock(); } } diff --git a/src/main/java/ca/tirelesstraveler/fancywarpmenu/listeners/WarpMenuListener.java b/src/main/java/ca/tirelesstraveler/fancywarpmenu/listeners/WarpMenuListener.java index 34c1495..43f87d3 100644 --- a/src/main/java/ca/tirelesstraveler/fancywarpmenu/listeners/WarpMenuListener.java +++ b/src/main/java/ca/tirelesstraveler/fancywarpmenu/listeners/WarpMenuListener.java @@ -26,13 +26,13 @@ import ca.tirelesstraveler.fancywarpmenu.GameState; import ca.tirelesstraveler.fancywarpmenu.OpenConfigCommand; import ca.tirelesstraveler.fancywarpmenu.data.Settings; +import ca.tirelesstraveler.fancywarpmenu.data.skyblockconstants.Menu; import ca.tirelesstraveler.fancywarpmenu.data.skyblockconstants.WarpCommandVariant; -import ca.tirelesstraveler.fancywarpmenu.data.skyblockconstants.WarpMessages; import ca.tirelesstraveler.fancywarpmenu.gui.FancyWarpMenuConfigScreen; -import ca.tirelesstraveler.fancywarpmenu.gui.GuiRiftFastTravel; -import ca.tirelesstraveler.fancywarpmenu.gui.buttons.GuiButtonConfig; import ca.tirelesstraveler.fancywarpmenu.gui.GuiFancyWarp; import ca.tirelesstraveler.fancywarpmenu.gui.GuiFastTravel; +import ca.tirelesstraveler.fancywarpmenu.gui.GuiRiftFastTravel; +import ca.tirelesstraveler.fancywarpmenu.gui.buttons.GuiButtonConfig; import io.netty.channel.ChannelHandler; import io.netty.channel.ChannelOutboundHandlerAdapter; import net.minecraft.client.Minecraft; @@ -42,12 +42,12 @@ import net.minecraft.client.resources.IResourceManager; import net.minecraft.client.resources.IResourceManagerReloadListener; import net.minecraft.inventory.ContainerChest; +import net.minecraft.inventory.IInventory; import net.minecraft.scoreboard.Score; import net.minecraft.scoreboard.Scoreboard; import net.minecraft.util.ChatComponentTranslation; import net.minecraft.util.ChatStyle; import net.minecraft.util.EnumChatFormatting; -import net.minecraft.util.StringUtils; import net.minecraftforge.client.event.ClientChatReceivedEvent; import net.minecraftforge.client.event.GuiOpenEvent; import net.minecraftforge.client.event.GuiScreenEvent; @@ -57,12 +57,10 @@ import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import org.lwjgl.input.Keyboard; -import org.lwjgl.input.Mouse; import java.io.IOException; import java.util.ArrayList; import java.util.Locale; -import java.util.Map; /** * General purpose event listener @@ -92,61 +90,75 @@ public void onChatMessageReceived(ClientChatReceivedEvent event) { if (FancyWarpMenu.getSkyBlockConstants().getWarpMessages().getWarpSuccessMessages().contains(unformattedText)) { mc.displayGuiScreen(null); } else if (FancyWarpMenu.getSkyBlockConstants().getWarpMessages().getWarpFailMessages().containsKey(unformattedText)) { - WarpMessages warpMessages = FancyWarpMenu.getSkyBlockConstants().getWarpMessages(); - Map warpFailMessages = warpMessages.getWarpFailMessages(); - String failMessageKey = warpFailMessages.get(unformattedText); + String failMessageKey = FancyWarpMenu.getSkyBlockConstants().getWarpMessages().getWarpFailMessages().get(unformattedText); warpScreen.onWarpFail(failMessageKey); } } } - /** - * Minecraft closes the current screen after executing a command, - * meaning any {@code GuiScreen} opened by the command is closed. - * This method interrupts the closing of the current screen to get around this behavior. - */ @SubscribeEvent public void onGuiOpen(GuiOpenEvent event) { + if (warpScreen != null && (mc.currentScreen == warpScreen || mc.currentScreen instanceof GuiChest)) { + warpScreen = null; + return; + } + + /* + Minecraft closes the current screen after executing a command, meaning any GuiScreen opened by the command is closed. + This section interrupts the closing of the current screen to get around this behavior. + */ if (event.gui == null) { if (openMenuRequested) { - createFastTravelMenu(false); + createFastTravelMenu(Menu.FAST_TRAVEL, false); event.gui = warpScreen; openMenuRequested = false; } else if (openConfigMenuRequested) { event.gui = new FancyWarpMenuConfigScreen(null); openConfigMenuRequested = false; } - } + } else if (event.gui instanceof GuiChest) { + IInventory chestInventory = ((ContainerChest) ((GuiChest) event.gui).inventorySlots).getLowerChestInventory(); + + if (chestInventory.hasCustomName()) { + /* + Guess which in-game GuiChest menu the player is in based on its title. + This is not accurate and should be used with more specific checks. + */ + String containerTitle = chestInventory.getDisplayName().getUnformattedText(); + + for (Menu menu : Menu.values()) { + if (containerTitle.equals(menu.getMenuTitle())) { + GameState.setCurrentMenu(menu); + return; + } + } + } - if (warpScreen != null && (mc.currentScreen == warpScreen || mc.currentScreen instanceof GuiChest)) { - warpScreen = null; + GameState.setCurrentMenu(Menu.NONE); } } - /** - * Add a button to the regular warp menu for players to enable the fancy warp menu or switch to it. - */ @SubscribeEvent public void afterGuiInit(GuiScreenEvent.InitGuiEvent.Post e) { - if (Settings.isWarpMenuEnabled() - && modInstance.isPlayerOnSkyBlock() - && e.gui instanceof GuiChest) { - GuiChest guiChest = (GuiChest) e.gui; - ContainerChest containerChest = (ContainerChest) guiChest.inventorySlots; - String containerName = containerChest.getLowerChestInventory().getName(); - - if (containerName.equals("Fast Travel")) { - e.buttonList.add(new GuiButtonConfig(e.buttonList.size(), new ScaledResolution(mc))); - } else if (containerName.equals("Porhtal")) { - warpScreen = new GuiRiftFastTravel(FancyWarpMenu.getRiftLayout()); - warpScreen.setWorldAndResolution(mc, guiChest.width, guiChest.height); + if (GameState.isOnSkyBlock() && e.gui instanceof GuiChest) { + Menu currentMenu = GameState.getCurrentMenu(); + + if (currentMenu == Menu.FAST_TRAVEL) { + if (Settings.isWarpMenuEnabled()) { + createFastTravelMenu(Menu.FAST_TRAVEL, false); + } else { + // Add a button to the regular warp menu for players to enable the fancy warp menu or switch to it. + e.buttonList.add(new GuiButtonConfig(e.buttonList.size(), new ScaledResolution(mc))); + } + } else if (currentMenu == Menu.PORHTAL) { + createFastTravelMenu(Menu.PORHTAL, false); } } } @SubscribeEvent public void beforeGuiDraw(GuiScreenEvent.DrawScreenEvent.Pre e) { - if (warpScreen instanceof GuiRiftFastTravel) { + if (isFancyWarpMenuOpen()) { warpScreen.drawScreen(e.mouseX, e.mouseY, e.renderPartialTicks); e.setCanceled(true); } @@ -158,50 +170,24 @@ public void beforeGuiDraw(GuiScreenEvent.DrawScreenEvent.Pre e) { @SubscribeEvent public void onKeyboardInput(InputEvent.KeyInputEvent event) { if (Settings.isWarpMenuEnabled() - && modInstance.isPlayerOnSkyBlock() + && GameState.isOnSkyBlock() && FancyWarpMenu.getKeyBindingOpenWarpMenu().isPressed()) { - createFastTravelMenu(true); + createFastTravelMenu(Menu.FAST_TRAVEL, true); } } - /** - * Redirect to the fancy warp menu when the player attempts to access the warp menu from the SkyBlock menu - */ @SubscribeEvent public void beforeGuiMouseInput(GuiScreenEvent.MouseInputEvent.Pre event) throws IOException { - if (warpScreen instanceof GuiRiftFastTravel) { + if (isFancyWarpMenuOpen()) { warpScreen.handleMouseInput(); event.setCanceled(true); } - - // Redirect the player to the Fancy Warp Menu if they click on the fast travel button in the SkyBlock menu - if (Settings.isWarpMenuEnabled() - && modInstance.isPlayerOnSkyBlock() - && Mouse.getEventButton() == 0 - && Mouse.getEventButtonState() - && event.gui instanceof GuiChest) { - GuiChest guiChest = (GuiChest) event.gui; - - if (guiChest.inventorySlots instanceof ContainerChest) { - ContainerChest container = (ContainerChest) guiChest.inventorySlots; - - if (container.getLowerChestInventory() != null - && container.getLowerChestInventory().hasCustomName() - && container.getLowerChestInventory().getName().equals("SkyBlock Menu") - && guiChest.getSlotUnderMouse() != null - && guiChest.getSlotUnderMouse().getSlotIndex() == 47 - // Rift SkyBlock Menu has a return to hub button in slot 47 - && StringUtils.stripControlCodes(guiChest.getSlotUnderMouse().getStack().getDisplayName()).equals("Fast Travel")) { - createFastTravelMenu(true); - event.setCanceled(true); - } - } - } } @SubscribeEvent public void beforeGuiKeyboardInput(GuiScreenEvent.KeyboardInputEvent.Pre e) throws IOException { - if (warpScreen instanceof GuiRiftFastTravel) { + if (isFancyWarpMenuOpen()) { + // Pass requests to close the chest to the underlying GuiChest to make sure it is closed properly if (Keyboard.getEventKey() != Keyboard.KEY_ESCAPE && Keyboard.getEventKey() != mc.gameSettings.keyBindInventory.getKeyCode()) { warpScreen.handleKeyboardInput(); e.setCanceled(true); @@ -233,7 +219,7 @@ public void onWarpCommand() { if (mc.currentScreen instanceof GuiChat) { openMenuRequested = true; } else { - createFastTravelMenu(true); + createFastTravelMenu(Menu.FAST_TRAVEL, true); } } @@ -244,15 +230,32 @@ public void onOpenConfigMenuCommand() { openConfigMenuRequested = true; } - public void createFastTravelMenu(boolean display) { + public void createFastTravelMenu(Menu menuType, boolean display) { + if (menuType == null) { + throw new NullPointerException("menuType cannot be null"); + } else if (menuType != Menu.FAST_TRAVEL && menuType != Menu.PORHTAL) { + throw new IllegalArgumentException(menuType + " is not a valid menu type"); + } + checkLateWinter(); - warpScreen = new GuiFastTravel(FancyWarpMenu.getLayout()); + warpScreen = menuType == Menu.FAST_TRAVEL ? + new GuiFastTravel(FancyWarpMenu.getLayout()) : + new GuiRiftFastTravel(FancyWarpMenu.getRiftLayout()); if (display) { mc.displayGuiScreen(warpScreen); + } else if (mc.currentScreen instanceof GuiChest) { + /* + If drawing over a GuiChest, setup the dimensions of the GuiFancyWarp manually since the normal setup process is skipped + */ + warpScreen.setWorldAndResolution(mc, mc.currentScreen.width, mc.currentScreen.height); } } + private boolean isFancyWarpMenuOpen() { + return warpScreen != null && mc.currentScreen != warpScreen; + } + /** * Checks if the SkyBlock season is Late Winter, used for hiding Jerry's Workshop when it's closed */ diff --git a/src/main/resources/assets/fancywarpmenu/data/skyBlockConstants.json b/src/main/resources/assets/fancywarpmenu/data/skyBlockConstants.json index c6d6fe1..b487eda 100644 --- a/src/main/resources/assets/fancywarpmenu/data/skyBlockConstants.json +++ b/src/main/resources/assets/fancywarpmenu/data/skyBlockConstants.json @@ -35,5 +35,6 @@ "command": "savethejerrys", "type": "WARP" } - ] + ], + "skyBlockJoinMessage": "Profile ID:" } \ No newline at end of file