package net.lax1dude.eaglercraft.v1_8; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.function.Consumer; import net.lax1dude.eaglercraft.v1_8.log4j.LogManager; import net.lax1dude.eaglercraft.v1_8.log4j.Logger; import net.lax1dude.eaglercraft.v1_8.opengl.ImageData; import net.lax1dude.eaglercraft.v1_8.profile.EaglerSkinTexture; import net.lax1dude.eaglercraft.v1_8.socket.protocol.pkt.server.SPacketCustomizePauseMenuV4EAG; import net.lax1dude.eaglercraft.v1_8.socket.protocol.util.PacketImageData; import net.minecraft.client.Minecraft; import net.minecraft.client.renderer.texture.TextureManager; import net.minecraft.util.ResourceLocation; /** * Copyright (c) 2024 lax1dude. All Rights Reserved. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. * */ public class PauseMenuCustomizeState { private static final Logger logger = LogManager.getLogger("PauseMenuCustomizeState"); public static ResourceLocation icon_title_L; public static float icon_title_L_aspect = 1.0f; public static ResourceLocation icon_title_R; public static float icon_title_R_aspect = 1.0f; public static ResourceLocation icon_backToGame_L; public static float icon_backToGame_L_aspect = 1.0f; public static ResourceLocation icon_backToGame_R; public static float icon_backToGame_R_aspect = 1.0f; public static ResourceLocation icon_achievements_L; public static float icon_achievements_L_aspect = 1.0f; public static ResourceLocation icon_achievements_R; public static float icon_achievements_R_aspect = 1.0f; public static ResourceLocation icon_statistics_L; public static float icon_statistics_L_aspect = 1.0f; public static ResourceLocation icon_statistics_R; public static float icon_statistics_R_aspect = 1.0f; public static ResourceLocation icon_serverInfo_L; public static float icon_serverInfo_L_aspect = 1.0f; public static ResourceLocation icon_serverInfo_R; public static float icon_serverInfo_R_aspect = 1.0f; public static ResourceLocation icon_options_L; public static float icon_options_L_aspect = 1.0f; public static ResourceLocation icon_options_R; public static float icon_options_R_aspect = 1.0f; public static ResourceLocation icon_discord_L; public static float icon_discord_L_aspect = 1.0f; public static ResourceLocation icon_discord_R; public static float icon_discord_R_aspect = 1.0f; public static ResourceLocation icon_disconnect_L; public static float icon_disconnect_L_aspect = 1.0f; public static ResourceLocation icon_disconnect_R; public static float icon_disconnect_R_aspect = 1.0f; public static ResourceLocation icon_background_pause; public static float icon_background_pause_aspect = 1.0f; public static ResourceLocation icon_background_all; public static float icon_background_all_aspect = 1.0f; public static ResourceLocation icon_watermark_pause; public static float icon_watermark_pause_aspect = 1.0f; public static ResourceLocation icon_watermark_all; public static float icon_watermark_all_aspect = 1.0f; public static final int SERVER_INFO_MODE_NONE = SPacketCustomizePauseMenuV4EAG.SERVER_INFO_MODE_NONE; public static final int SERVER_INFO_MODE_EXTERNAL_URL = SPacketCustomizePauseMenuV4EAG.SERVER_INFO_MODE_EXTERNAL_URL; public static final int SERVER_INFO_MODE_SHOW_EMBED_OVER_HTTP = SPacketCustomizePauseMenuV4EAG.SERVER_INFO_MODE_SHOW_EMBED_OVER_HTTP; public static final int SERVER_INFO_MODE_SHOW_EMBED_OVER_WS = SPacketCustomizePauseMenuV4EAG.SERVER_INFO_MODE_SHOW_EMBED_OVER_WS; public static final int SERVER_INFO_EMBED_PERMS_JAVASCRIPT = SPacketCustomizePauseMenuV4EAG.SERVER_INFO_EMBED_PERMS_JAVASCRIPT; public static final int SERVER_INFO_EMBED_PERMS_MESSAGE_API = SPacketCustomizePauseMenuV4EAG.SERVER_INFO_EMBED_PERMS_MESSAGE_API; public static final int SERVER_INFO_EMBED_PERMS_STRICT_CSP = SPacketCustomizePauseMenuV4EAG.SERVER_INFO_EMBED_PERMS_STRICT_CSP; public static final int DISCORD_MODE_NONE = SPacketCustomizePauseMenuV4EAG.DISCORD_MODE_NONE; public static final int DISCORD_MODE_INVITE_URL = SPacketCustomizePauseMenuV4EAG.DISCORD_MODE_INVITE_URL; public static int serverInfoMode; public static int serverInfoEmbedPerms = SERVER_INFO_EMBED_PERMS_STRICT_CSP; public static String serverInfoEmbedTitle; public static String serverInfoButtonText; public static String serverInfoURL; public static byte[] serverInfoHash; public static int discordButtonMode; public static String discordButtonText; public static String discordInviteURL; private static final List toFree = new ArrayList<>(); private static int textureId = 0; private static class PauseMenuSprite { private final ResourceLocation loc; private final EaglerSkinTexture tex; public PauseMenuSprite(EaglerSkinTexture tex) { this.loc = newLoc(); this.tex = tex; } } public static void loadPacket(SPacketCustomizePauseMenuV4EAG packet) { reset(); serverInfoMode = packet.serverInfoMode; switch(packet.serverInfoMode) { case SERVER_INFO_MODE_NONE: default: serverInfoButtonText = null; serverInfoURL = null; serverInfoHash = null; break; case SERVER_INFO_MODE_EXTERNAL_URL: serverInfoButtonText = packet.serverInfoButtonText; serverInfoURL = packet.serverInfoURL; break; case SERVER_INFO_MODE_SHOW_EMBED_OVER_HTTP: serverInfoButtonText = packet.serverInfoButtonText; serverInfoEmbedPerms = packet.serverInfoEmbedPerms; serverInfoURL = packet.serverInfoURL; serverInfoEmbedTitle = packet.serverInfoEmbedTitle; break; case SERVER_INFO_MODE_SHOW_EMBED_OVER_WS: serverInfoButtonText = packet.serverInfoButtonText; serverInfoEmbedPerms = packet.serverInfoEmbedPerms; serverInfoHash = packet.serverInfoHash; serverInfoEmbedTitle = packet.serverInfoEmbedTitle; break; } discordButtonMode = packet.discordButtonMode; switch(packet.discordButtonMode) { case DISCORD_MODE_NONE: default: discordButtonText = null; serverInfoURL = null; serverInfoHash = null; break; case DISCORD_MODE_INVITE_URL: discordButtonText = packet.discordButtonText; discordInviteURL = packet.discordInviteURL; break; } if(packet.imageMappings != null) { Map spriteCache = new HashMap<>(); icon_title_L = cacheLoadHelperFunction("icon_title_L", packet.imageMappings, spriteCache, packet.imageData, (a) -> icon_title_L_aspect = a); icon_title_R = cacheLoadHelperFunction("icon_title_R", packet.imageMappings, spriteCache, packet.imageData, (a) -> icon_title_R_aspect = a); icon_backToGame_L = cacheLoadHelperFunction("icon_backToGame_L", packet.imageMappings, spriteCache, packet.imageData, (a) -> icon_backToGame_L_aspect = a); icon_backToGame_R = cacheLoadHelperFunction("icon_backToGame_R", packet.imageMappings, spriteCache, packet.imageData, (a) -> icon_backToGame_R_aspect = a); icon_achievements_L = cacheLoadHelperFunction("icon_achievements_L", packet.imageMappings, spriteCache, packet.imageData, (a) -> icon_achievements_L_aspect = a); icon_achievements_R = cacheLoadHelperFunction("icon_achievements_R", packet.imageMappings, spriteCache, packet.imageData, (a) -> icon_achievements_R_aspect = a); icon_statistics_L = cacheLoadHelperFunction("icon_statistics_L", packet.imageMappings, spriteCache, packet.imageData, (a) -> icon_statistics_L_aspect = a); icon_statistics_R = cacheLoadHelperFunction("icon_statistics_R", packet.imageMappings, spriteCache, packet.imageData, (a) -> icon_statistics_R_aspect = a); icon_serverInfo_L = cacheLoadHelperFunction("icon_serverInfo_L", packet.imageMappings, spriteCache, packet.imageData, (a) -> icon_serverInfo_L_aspect = a); icon_serverInfo_R = cacheLoadHelperFunction("icon_serverInfo_R", packet.imageMappings, spriteCache, packet.imageData, (a) -> icon_serverInfo_R_aspect = a); icon_options_L = cacheLoadHelperFunction("icon_options_L", packet.imageMappings, spriteCache, packet.imageData, (a) -> icon_options_L_aspect = a); icon_options_R = cacheLoadHelperFunction("icon_options_R", packet.imageMappings, spriteCache, packet.imageData, (a) -> icon_options_R_aspect = a); icon_discord_L = cacheLoadHelperFunction("icon_discord_L", packet.imageMappings, spriteCache, packet.imageData, (a) -> icon_discord_L_aspect = a); icon_discord_R = cacheLoadHelperFunction("icon_discord_R", packet.imageMappings, spriteCache, packet.imageData, (a) -> icon_discord_R_aspect = a); icon_disconnect_L = cacheLoadHelperFunction("icon_disconnect_L", packet.imageMappings, spriteCache, packet.imageData, (a) -> icon_disconnect_L_aspect = a); icon_disconnect_R = cacheLoadHelperFunction("icon_disconnect_R", packet.imageMappings, spriteCache, packet.imageData, (a) -> icon_disconnect_R_aspect = a); icon_background_pause = cacheLoadHelperFunction("icon_background_pause", packet.imageMappings, spriteCache, packet.imageData, (a) -> icon_background_pause_aspect = a); icon_background_all = cacheLoadHelperFunction("icon_background_all", packet.imageMappings, spriteCache, packet.imageData, (a) -> icon_background_all_aspect = a); icon_watermark_pause = cacheLoadHelperFunction("icon_watermark_pause", packet.imageMappings, spriteCache, packet.imageData, (a) -> icon_watermark_pause_aspect = a); icon_watermark_all = cacheLoadHelperFunction("icon_watermark_all", packet.imageMappings, spriteCache, packet.imageData, (a) -> icon_watermark_all_aspect = a); } } private static ResourceLocation cacheLoadHelperFunction(String name, Map lookup, Map spriteCache, List sourceData, Consumer aspectCB) { Integer i = lookup.get(name); if(i == null) { return null; } PauseMenuSprite ret = spriteCache.get(i); if(ret != null) { if(name.startsWith("icon_background_") && ImageData.isNPOTStatic(ret.tex.getWidth(), ret.tex.getHeight())) { logger.warn("An NPOT (non-power-of-two) texture was used for \"{}\", this texture's width and height must be powers of two for this texture to display properly on all hardware"); } aspectCB.accept((float)ret.tex.getWidth() / ret.tex.getHeight()); return ret.loc; } int ii = i.intValue(); if(ii < 0 || ii >= sourceData.size()) { return null; } PacketImageData data = sourceData.get(ii); ret = new PauseMenuSprite(new EaglerSkinTexture(ImageData.swapRB(data.rgba), data.width, data.height)); Minecraft.getMinecraft().getTextureManager().loadTexture(ret.loc, ret.tex); spriteCache.put(i, ret); toFree.add(ret); aspectCB.accept((float)data.width / data.height); return ret.loc; } private static ResourceLocation newLoc() { return new ResourceLocation("eagler:gui/server/custom_pause_menu/tex_" + textureId++); } public static void reset() { icon_title_L = icon_title_R = null; icon_backToGame_L = icon_backToGame_R = null; icon_achievements_L = icon_achievements_R = null; icon_statistics_L = icon_statistics_R = null; icon_serverInfo_L = icon_serverInfo_R = null; icon_options_L = icon_options_R = null; icon_discord_L = icon_discord_R = null; icon_disconnect_L = icon_disconnect_R = null; icon_background_pause = icon_background_all = null; icon_watermark_pause = icon_watermark_all = null; icon_title_L_aspect = icon_title_R_aspect = 1.0f; icon_backToGame_L_aspect = icon_backToGame_R_aspect = 1.0f; icon_achievements_L_aspect = icon_achievements_R_aspect = 1.0f; icon_statistics_L_aspect = icon_statistics_R_aspect = 1.0f; icon_serverInfo_L_aspect = icon_serverInfo_R_aspect = 1.0f; icon_options_L_aspect = icon_options_R_aspect = 1.0f; icon_discord_L_aspect = icon_discord_R_aspect = 1.0f; icon_disconnect_L_aspect = icon_disconnect_R_aspect = 1.0f; icon_background_pause_aspect = icon_background_all_aspect = 1.0f; icon_watermark_pause_aspect = icon_watermark_all_aspect = 1.0f; serverInfoMode = 0; serverInfoEmbedPerms = SERVER_INFO_EMBED_PERMS_STRICT_CSP; serverInfoButtonText = null; serverInfoURL = null; serverInfoHash = null; serverInfoEmbedTitle = null; discordButtonMode = 0; discordButtonText = null; discordInviteURL = null; if(!toFree.isEmpty()) { TextureManager mgr = Minecraft.getMinecraft().getTextureManager(); for(PauseMenuSprite rc : toFree) { mgr.deleteTexture(rc.loc); } toFree.clear(); } } }