From 706dce8031f6eadb431fd5ac93e3176ed24bf5fa Mon Sep 17 00:00:00 2001 From: kirillsaint Date: Wed, 1 May 2024 03:49:36 +0600 Subject: [PATCH] (feature) emote binding --- .../java/net/silentclient/client/Client.java | 6 ++ .../client/emotes/EmoteManager.java | 7 -- .../silentclient/client/emotes/EmotesMod.java | 41 ++++++++++++ .../client/emotes/config/EmotesConfig.java | 64 +++++++++++++++++++ .../emotes/config/EmotesConfigType.java | 59 +++++++++++++++++ .../client/emotes/ui/EmoteMenuGui.java | 58 +++++++++++++++-- .../client/gui/elements/Input.java | 2 +- .../client/mods/hypixel/QuickPlayMod.java | 55 ++++++++++------ .../client/mods/player/AutoTextMod.java | 43 ++++++++----- 9 files changed, 287 insertions(+), 48 deletions(-) create mode 100644 src/main/java/net/silentclient/client/emotes/config/EmotesConfigType.java diff --git a/src/main/java/net/silentclient/client/Client.java b/src/main/java/net/silentclient/client/Client.java index 1b39d41..323558c 100644 --- a/src/main/java/net/silentclient/client/Client.java +++ b/src/main/java/net/silentclient/client/Client.java @@ -12,6 +12,7 @@ import net.minecraft.util.ResourceLocation; import net.minecraft.util.Session; import net.silentclient.client.config.ConfigManager; import net.silentclient.client.cosmetics.Cosmetics; +import net.silentclient.client.emotes.EmotesMod; import net.silentclient.client.event.EventManager; import net.silentclient.client.event.EventTarget; import net.silentclient.client.event.impl.*; @@ -589,6 +590,11 @@ public class Client { Server.setRuHypixel(Server.checkIsRuHypixel()); } + @EventTarget + public void onClick(KeyEvent event) { + EmotesMod.onClick(event); + } + // Instances public String getApiUrl() { return "http://localhost:" + getUserData().server_port; diff --git a/src/main/java/net/silentclient/client/emotes/EmoteManager.java b/src/main/java/net/silentclient/client/emotes/EmoteManager.java index 50234ad..0a6bbbf 100644 --- a/src/main/java/net/silentclient/client/emotes/EmoteManager.java +++ b/src/main/java/net/silentclient/client/emotes/EmoteManager.java @@ -3,7 +3,6 @@ package net.silentclient.client.emotes; import net.minecraft.client.Minecraft; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.world.World; -import net.silentclient.client.Client; import net.silentclient.client.emotes.emoticons.Emote; public class EmoteManager { @@ -19,11 +18,7 @@ public class EmoteManager { Emote emote = PlayerModelManager.get().registry.get(s); if (EmoteControllerManager.controllers.get(entityPlayer.getName()) != null) { EmoteControllerManager.controllers.get(entityPlayer.getName()).setEmote(entityPlayer, emote); - } else { - Client.logger.info("emote player controller is null"); } - } else { - Client.logger.info("entity player or emote is null"); } } } @@ -45,8 +40,6 @@ public class EmoteManager { { EntityPlayer entityplayer = (EntityPlayer)world.playerEntities.get(i); - Client.logger.info(entityplayer.getName()); - if (name.equalsIgnoreCase(entityplayer.getName())) { return entityplayer; diff --git a/src/main/java/net/silentclient/client/emotes/EmotesMod.java b/src/main/java/net/silentclient/client/emotes/EmotesMod.java index 1fec7d6..ec4fc52 100644 --- a/src/main/java/net/silentclient/client/emotes/EmotesMod.java +++ b/src/main/java/net/silentclient/client/emotes/EmotesMod.java @@ -1,7 +1,12 @@ package net.silentclient.client.emotes; +import net.minecraft.client.Minecraft; import net.silentclient.client.Client; +import net.silentclient.client.emotes.config.EmotesConfig; +import net.silentclient.client.emotes.config.EmotesConfigType; import net.silentclient.client.emotes.socket.EmoteSocket; +import net.silentclient.client.event.EventManager; +import net.silentclient.client.event.impl.KeyEvent; import net.silentclient.client.mods.Mod; import net.silentclient.client.mods.ModCategory; import net.silentclient.client.mods.Setting; @@ -10,6 +15,8 @@ import org.lwjgl.input.Keyboard; import java.util.ArrayList; public class EmotesMod extends Mod { + public static boolean sending = false; + public EmotesMod() { super("Emotes", ModCategory.SETTINGS, "silentclient/emotes/icons/default.png"); } @@ -26,6 +33,12 @@ public class EmotesMod extends Mod { perspectives.add("Third Person"); this.addModeSetting("Default Emote Perspective", this, "Second Person", perspectives); + + try { + EmotesConfig.init(); + } catch (Exception err) { + Client.logger.catching(err); + } } @Override @@ -38,14 +51,42 @@ public class EmotesMod extends Mod { } } + public static void onClick(KeyEvent event) { + if(!Client.getInstance().getSettingsManager().getSettingByClass(EmotesMod.class, "Emotes").getValBoolean()) { + return; + } + if(Minecraft.getMinecraft().thePlayer != null && Minecraft.getMinecraft().theWorld != null && Minecraft.getMinecraft().currentScreen == null && !sending) { + EmotesConfigType.Bind bind = EmotesConfig.getBinds().get(event.getKey()); + if(bind != null) { + EmotesMod.sending = true; + (new Thread("EMOTES BIND:" + bind.emoteId) { + public void run() { + Client.logger.info("bind found"); + EmoteSocket.get().startEmote(bind.emoteId); + try { + Thread.sleep(2000L); + } catch (InterruptedException e) { + Client.logger.catching(e); + } + EmotesMod.sending = false; + } + }).start(); + } else { + Client.logger.info("bind not found"); + } + } + } + @Override public void onChangeSettingValue(Setting setting) { super.onChangeSettingValue(setting); if(setting.getName().equals("Emotes")) { if(setting.getValBoolean()) { EmoteSocket.get().connect(); + EventManager.register(this); } else { EmoteSocket.get().disconnect(); + EventManager.unregister(this); } } } diff --git a/src/main/java/net/silentclient/client/emotes/config/EmotesConfig.java b/src/main/java/net/silentclient/client/emotes/config/EmotesConfig.java index 1326396..9662468 100644 --- a/src/main/java/net/silentclient/client/emotes/config/EmotesConfig.java +++ b/src/main/java/net/silentclient/client/emotes/config/EmotesConfig.java @@ -1,4 +1,68 @@ package net.silentclient.client.emotes.config; +import net.minecraft.client.Minecraft; +import net.silentclient.client.Client; + +import java.io.*; +import java.nio.file.Files; +import java.util.HashMap; + public class EmotesConfig { + public static File configFile; + public static EmotesConfigType config; + public static HashMap binds; + + public static void init() throws IOException { + configFile = new File(Minecraft.getMinecraft().mcDataDir, "slc-emotes.json"); + if(!configFile.exists()) { + configFile.createNewFile(); + config = EmotesConfigType.getDefault(); + save(); + } else { + try { + InputStream in = Files.newInputStream(configFile.toPath()); + BufferedReader reader = new BufferedReader(new InputStreamReader(in)); + StringBuilder content = new StringBuilder(); + String inputLine; + while ((inputLine = reader.readLine()) != null) { + content.append(inputLine); + } + config = Client.getInstance().getGson().fromJson(content.toString(), EmotesConfigType.class); + in.close(); + } catch (Exception err) { + Client.logger.catching(err); + config = EmotesConfigType.getDefault(); + save(); + } + } + updateHashMap(); + } + + public static void save() { + try { + FileOutputStream outputStream = new FileOutputStream(configFile); + byte[] strToBytes = Client.getInstance().getGson().toJson(config).toString().getBytes(); + outputStream.write(strToBytes); + + outputStream.close(); + } catch (Exception err) { + Client.logger.catching(err); + } + } + + public static void updateHashMap() { + HashMap map = new HashMap<>(); + for (EmotesConfigType.Bind bind : config.getBinds()) { + map.put(bind.keyId, bind); + } + binds = map; + } + + public static HashMap getBinds() { + return binds; + } + + public static EmotesConfigType getConfig() { + return config; + } } diff --git a/src/main/java/net/silentclient/client/emotes/config/EmotesConfigType.java b/src/main/java/net/silentclient/client/emotes/config/EmotesConfigType.java new file mode 100644 index 0000000..461a469 --- /dev/null +++ b/src/main/java/net/silentclient/client/emotes/config/EmotesConfigType.java @@ -0,0 +1,59 @@ +package net.silentclient.client.emotes.config; + +import java.util.ArrayList; + +public class EmotesConfigType { + public ArrayList binds; + + public ArrayList getBinds() { + return binds; + } + + public void addBind(int emoteId, int keyId) { + int removeIndex = findBindByEmoteId(emoteId); + if(removeIndex >= 0) { + binds.remove(removeIndex); + } + if(keyId == -1) { + removeBind(emoteId); + return; + } + EmotesConfigType.Bind bind = new Bind(); + bind.emoteId = emoteId; + bind.keyId = keyId; + + binds.add(bind); + EmotesConfig.updateHashMap(); + } + + public void removeBind(int emoteId) { + int removeIndex = findBindByEmoteId(emoteId); + if(removeIndex >= 0) { + binds.remove(removeIndex); + } + EmotesConfig.updateHashMap(); + } + + public int findBindByEmoteId(int emoteId) { + int index = -1; + for (Bind bind : binds) { + index++; + if (bind.emoteId == emoteId) { + return index; + } + } + return -1; // Если элемент не найден + } + + public class Bind { + public int emoteId; + public int keyId; + } + + public static EmotesConfigType getDefault() { + EmotesConfigType config = new EmotesConfigType(); + config.binds = new ArrayList<>(); + + return config; + } +} diff --git a/src/main/java/net/silentclient/client/emotes/ui/EmoteMenuGui.java b/src/main/java/net/silentclient/client/emotes/ui/EmoteMenuGui.java index 2d874a8..c3d7f3c 100644 --- a/src/main/java/net/silentclient/client/emotes/ui/EmoteMenuGui.java +++ b/src/main/java/net/silentclient/client/emotes/ui/EmoteMenuGui.java @@ -6,13 +6,17 @@ import net.minecraft.client.gui.ScaledResolution; import net.minecraft.util.ResourceLocation; import net.silentclient.client.Client; import net.silentclient.client.emotes.PlayerModelManager; +import net.silentclient.client.emotes.config.EmotesConfig; +import net.silentclient.client.emotes.config.EmotesConfigType; import net.silentclient.client.emotes.emoticons.Emote; import net.silentclient.client.emotes.socket.EmoteSocket; import net.silentclient.client.gui.SilentScreen; import net.silentclient.client.gui.elements.IconButton; +import net.silentclient.client.gui.elements.Input; import net.silentclient.client.gui.font.SilentFontRenderer; import net.silentclient.client.gui.lite.clickgui.utils.MouseUtils; import net.silentclient.client.gui.theme.Theme; +import net.silentclient.client.gui.theme.input.DefaultInputTheme; import net.silentclient.client.gui.util.RenderUtil; import net.silentclient.client.utils.MenuBlurUtils; import net.silentclient.client.utils.MouseCursorHandler; @@ -24,6 +28,7 @@ import org.lwjgl.opengl.GL11; import java.awt.*; import java.io.IOException; import java.util.ArrayList; +import java.util.HashMap; public class EmoteMenuGui extends SilentScreen { private ScrollHelper scrollHelper = new ScrollHelper(); @@ -41,6 +46,12 @@ public class EmoteMenuGui extends SilentScreen { int y = this.height / 2 - (height / 2); this.buttonList.add(new IconButton(0, x + width - 14 - 3, y + 3, 14, 14, 8, 8, new ResourceLocation("silentclient/icons/exit.png"))); + HashMap emoteBinds = new HashMap<>(); + + for(EmotesConfigType.Bind bind : EmotesConfig.getConfig().getBinds()) { + emoteBinds.put(bind.emoteId, bind); + } + for(PlayerResponse.Account.Cosmetics.CosmeticItem emote : Client.getInstance().getCosmetics().getMyEmotes()) { String emoteName = PlayerModelManager.get().map.get(emote.id); if(emoteName == null) { @@ -50,6 +61,8 @@ public class EmoteMenuGui extends SilentScreen { if(emoteInstance == null) { continue; } + EmotesConfigType.Bind bind = emoteBinds.get(emote.id); + this.silentInputs.add(new Input(emote.name, bind != null ? bind.keyId : -1)); } } @@ -80,6 +93,7 @@ public class EmoteMenuGui extends SilentScreen { int emoteX = x + 3; float emoteY = y + 20 + scrollY; int emoteIndex = 0; + int realEmoteIndex = 0; for(PlayerResponse.Account.Cosmetics.CosmeticItem emote : Client.getInstance().getCosmetics().getMyEmotes()) { String emoteName = PlayerModelManager.get().map.get(emote.id); if(emoteName == null) { @@ -90,7 +104,11 @@ public class EmoteMenuGui extends SilentScreen { continue; } - boolean isHovered = MouseUtils.isInside(mouseX, mouseY, emoteX, emoteY, 80, 80) && !MouseUtils.isInside(mouseX, mouseY, emoteX + 80 - 3 - 10, emoteY + 3, 10, 10); + Input input = this.silentInputs.get(realEmoteIndex); + + input.render(mouseX, mouseY, emoteX + 3, emoteY + 80 - 3 - 15, 74, true, new DefaultInputTheme(), true); + + boolean isHovered = MouseUtils.isInside(mouseX, mouseY, emoteX, emoteY, 80, 80) && !MouseUtils.isInside(mouseX, mouseY, emoteX + 80 - 3 - 10, emoteY + 3, 10, 10) && !input.isHovered(); if(isHovered) { cursorType = MouseCursorHandler.CursorType.POINTER; RenderUtil.drawRoundedRect(emoteX, emoteY, 80, 80, 3, new Color(255, 255, 255, 30).getRGB()); @@ -110,9 +128,10 @@ public class EmoteMenuGui extends SilentScreen { RenderUtil.drawImage(new ResourceLocation(favorite ? "silentclient/icons/star.png" : "silentclient/icons/star_outline.png"), emoteX + 80 - 3 - 10, emoteY + 3, 10, 10); - RenderUtil.drawImage(emoteInstance.icon.icon, emoteX + 3 + 37 - 28 , emoteY + 16, 56, 56); + RenderUtil.drawImage(emoteInstance.icon.icon, emoteX + 3 + 37 - 19, emoteY + 16, 39, 39); emoteIndex += 1; + realEmoteIndex++; if(emoteIndex == 3) { emoteIndex = 0; emoteX = x + 3; @@ -145,6 +164,7 @@ public class EmoteMenuGui extends SilentScreen { int emoteX = x + 3; float emoteY = (int) (y + 20 + scrollHelper.getScroll()); int emoteIndex = 0; + int realEmoteIndex = 0; for(PlayerResponse.Account.Cosmetics.CosmeticItem emote : Client.getInstance().getCosmetics().getMyEmotes()) { String emoteName = PlayerModelManager.get().map.get(emote.id); if(emoteName == null) { @@ -154,8 +174,9 @@ public class EmoteMenuGui extends SilentScreen { if(emoteInstance == null) { continue; } - boolean isHovered = MouseUtils.isInside(mouseX, mouseY, emoteX, emoteY, 80, 80) && !MouseUtils.isInside(mouseX, mouseY, emoteX + 80 - 3 - 10, emoteY + 3, 10, 10); - + Input input = this.silentInputs.get(realEmoteIndex); + input.onClick(mouseX, mouseY, emoteX + 3, (int) (emoteY + 80 - 3 - 15), 74, true); + boolean isHovered = MouseUtils.isInside(mouseX, mouseY, emoteX, emoteY, 80, 80) && !MouseUtils.isInside(mouseX, mouseY, emoteX + 80 - 3 - 10, emoteY + 3, 10, 10) && !input.isHovered(); if(isHovered) { EmoteSocket.get().startEmote(emote.getId()); mc.displayGuiScreen(null); @@ -168,6 +189,7 @@ public class EmoteMenuGui extends SilentScreen { } emoteIndex += 1; + realEmoteIndex++; if(emoteIndex == 3) { emoteIndex = 0; emoteX = x + 3; @@ -188,9 +210,33 @@ public class EmoteMenuGui extends SilentScreen { @Override protected void keyTyped(char typedChar, int keyCode) throws IOException { - if (keyCode == Keyboard.KEY_ESCAPE) { - mc.displayGuiScreen(null); + int inputIndex = 0; + boolean neededKeyCheck = true; + + for(PlayerResponse.Account.Cosmetics.CosmeticItem emote : Client.getInstance().getCosmetics().getMyEmotes()) { + String emoteName = PlayerModelManager.get().map.get(emote.id); + if(emoteName == null) { + continue; + } + Emote emoteInstance = PlayerModelManager.get().getEmote(emoteName); + if(emoteInstance == null) { + continue; + } + if(silentInputs.get(inputIndex).isFocused()) { + this.silentInputs.get(inputIndex).onKeyTyped(typedChar, keyCode); + EmotesConfig.getConfig().addBind(emote.id, this.silentInputs.get(inputIndex).getKey()); + EmotesConfig.save(); + if(keyCode == Keyboard.KEY_ESCAPE) { + neededKeyCheck = false; + break; + } + } + inputIndex++; } + + if (neededKeyCheck && keyCode == Keyboard.KEY_ESCAPE) { + mc.displayGuiScreen(null); + }; } @Override diff --git a/src/main/java/net/silentclient/client/gui/elements/Input.java b/src/main/java/net/silentclient/client/gui/elements/Input.java index 71fc4b2..e7b49b9 100644 --- a/src/main/java/net/silentclient/client/gui/elements/Input.java +++ b/src/main/java/net/silentclient/client/gui/elements/Input.java @@ -71,7 +71,7 @@ public class Input { public void render(int mouseX, int mouseY, float x, float y, int width, boolean small, IInputTheme theme, boolean center) { int borderColor = theme.getBorderColor().getRGB(); - if(MouseUtils.isInside(mouseX, mouseY, x, y, width, 20)) { + if(MouseUtils.isInside(mouseX, mouseY, x, y, width, small ? 15 : 20)) { borderColor = theme.getHoveredBorderColor().getRGB(); this.hovered = true; } else { diff --git a/src/main/java/net/silentclient/client/mods/hypixel/QuickPlayMod.java b/src/main/java/net/silentclient/client/mods/hypixel/QuickPlayMod.java index 60515bd..d32bc26 100644 --- a/src/main/java/net/silentclient/client/mods/hypixel/QuickPlayMod.java +++ b/src/main/java/net/silentclient/client/mods/hypixel/QuickPlayMod.java @@ -17,11 +17,13 @@ import java.io.InputStream; import java.io.InputStreamReader; import java.lang.reflect.Type; import java.util.ArrayList; +import java.util.HashMap; public class QuickPlayMod extends Mod { public static ArrayList hypixelQuickplayModes; public static ArrayList ruhypixelQuickplayModes; public static boolean sending = false; + public static HashMap hashMap; public QuickPlayMod() { super("Quickplay", ModCategory.MODS, "silentclient/icons/mods/quickplay.png"); @@ -46,14 +48,15 @@ public class QuickPlayMod extends Mod { content.append(inputLine); } - Type listType = new TypeToken>(){}.getType(); + Type listType = new TypeToken>() { + }.getType(); hypixelQuickplayModes = Client.getInstance().getGson().fromJson(content.toString(), listType); - for(QuickplayModeType mode : hypixelQuickplayModes) { + for (QuickplayModeType mode : hypixelQuickplayModes) { Client.logger.info(String.format("Initialising Hypixel Quickplay Mode (%s)", mode.name)); mode.modes.forEach((command) -> { Client.logger.info(String.format("Initialising Hypixel Quickplay Mode (%s) Command (%s)", mode.name, command.name)); - this.addKeybindSetting("Quickplay Mode&Hypixel&"+command.command, this, -1); + this.addKeybindSetting("Quickplay Mode&Hypixel&" + command.command, this, -1); }); } } catch (Exception err) { @@ -61,6 +64,23 @@ public class QuickPlayMod extends Mod { } } + public void updateHashMap() { + HashMap map = new HashMap<>(); + for(Setting setting : Client.getInstance().getSettingsManager().getSettingByMod(this)) { + if (setting.isKeybind()) { + map.put(setting.getKeybind(), setting); + } + } + + hashMap = map; + } + + @Override + public void onChangeSettingValue(Setting setting) { + super.onChangeSettingValue(setting); + updateHashMap(); + } + private void initRuHypixelModes() { try { Client.logger.info("Initialising RuHypixel Quickplay Modes"); @@ -108,21 +128,20 @@ public class QuickPlayMod extends Mod { @EventTarget public void onClick(KeyEvent event) { if(mc.thePlayer != null && mc.theWorld != null && mc.currentScreen == null) { - for(Setting setting : Client.getInstance().getSettingsManager().getSettingByMod(this)) { - if(setting.isKeybind()) { - if(setting.getName().equals("Open Menu")) { - // Open Menu - if(setting.isKeyDown() && (Server.isHypixel() || Server.isRuHypixel())) { - mc.displayGuiScreen(new QuickplayGui()); - } - } else { - if(sending) { - return; - } - String[] args = setting.getName().split("&"); - if(((args[1].equals("Hypixel") && Server.isHypixel()) || (args[1].equals("RuHypixel") && Server.isRuHypixel())) && setting.isKeyDown()) { - runCommand(args[2]); - } + Setting setting = hashMap.get(event.getKey()); + if(setting != null) { + if(setting.getName().equals("Open Menu")) { + // Open Menu + if(setting.isKeyDown() && (Server.isHypixel() || Server.isRuHypixel())) { + mc.displayGuiScreen(new QuickplayGui()); + } + } else { + if(sending) { + return; + } + String[] args = setting.getName().split("&"); + if(((args[1].equals("Hypixel") && Server.isHypixel()) || (args[1].equals("RuHypixel") && Server.isRuHypixel())) && setting.isKeyDown()) { + runCommand(args[2]); } } } diff --git a/src/main/java/net/silentclient/client/mods/player/AutoTextMod.java b/src/main/java/net/silentclient/client/mods/player/AutoTextMod.java index 98641ed..d567d6d 100644 --- a/src/main/java/net/silentclient/client/mods/player/AutoTextMod.java +++ b/src/main/java/net/silentclient/client/mods/player/AutoTextMod.java @@ -27,11 +27,13 @@ import org.lwjgl.input.Keyboard; import java.awt.*; import java.io.IOException; import java.util.ArrayList; +import java.util.HashMap; import java.util.regex.Pattern; public class AutoTextMod extends Mod { public ArrayList commands = new ArrayList(); + public HashMap commandsMap = new HashMap<>(); public boolean sending = false; private int componentHeight = 0; @@ -182,33 +184,33 @@ public class AutoTextMod extends Mod { } this.commands = newCommands; + updateHashMap(); } @EventTarget public void onClick(KeyEvent event) { if(mc.thePlayer != null && mc.theWorld != null && mc.currentScreen == null && !sending && !isForceDisabled()) { - for(AutoTextCommand command : commands) { - if(command.getKey() == event.getKey()) { - Client.getInstance().getModInstances().getAutoText().sending = true; - (new Thread("ATC: " + command.getCommand()) { - public void run() { - mc.thePlayer.sendChatMessage(command.getCommand()); - try { - Thread.sleep(2000L); - } catch (InterruptedException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } - Client.getInstance().getModInstances().getAutoText().sending = false; - } - }).start(); - } + AutoTextCommand command = commandsMap.get(event.getKey()); + if(command != null) { + Client.getInstance().getModInstances().getAutoText().sending = true; + (new Thread("ATC: " + command.getCommand()) { + public void run() { + mc.thePlayer.sendChatMessage(command.getCommand()); + try { + Thread.sleep(2000L); + } catch (InterruptedException e) { + Client.logger.catching(e); + } + Client.getInstance().getModInstances().getAutoText().sending = false; + } + }).start(); } } } public void addCommand(String command, int key) { this.commands.add(new AutoTextCommand(command, key)); + updateHashMap(); } public ArrayList getCommands() { @@ -234,6 +236,14 @@ public class AutoTextMod extends Mod { } } + + public void updateHashMap() { + HashMap map = new HashMap<>(); + for (AutoTextCommand bind : commands) { + map.put(bind.key, bind); + } + commandsMap = map; + } public class AutoTextAddCommandGui extends SilentScreen { private final GuiScreen parentScreen; @@ -311,6 +321,7 @@ public class AutoTextMod extends Mod { this.silentInputs.get(1).onClick(mouseX, mouseY, x + 3, y + 46, this.modalWidth - 6); } + @Override public void onGuiClosed() { MenuBlurUtils.unloadBlur();