From 28274b76fdbfe242a1e2bcf70d6e4f581de39c67 Mon Sep 17 00:00:00 2001 From: Sollace Date: Sun, 3 Jun 2018 11:57:22 +0200 Subject: [PATCH 01/10] Clear the pony cache alongside the skin cache, and fixed windows appearing behind the client --- .../voxelmodpack/hdskins/HDSkinManager.java | 21 +++++++++++ .../hdskins/ISkinCacheClearListener.java | 6 +++ .../java/com/voxelmodpack/hdskins/Later.java | 27 ++++++++++++++ .../voxelmodpack/hdskins/gui/GuiSkins.java | 34 ++++++++++++----- .../hdskins/upload/awt/ThreadOpenFile.java | 37 ++++++++++++++++++- .../com/minelittlepony/MineLittlePony.java | 2 + .../java/com/minelittlepony/PonyManager.java | 12 ++++-- .../hdskins/gui/GuiSkinsMineLP.java | 8 ---- 8 files changed, 125 insertions(+), 22 deletions(-) create mode 100644 src/hdskins/java/com/voxelmodpack/hdskins/ISkinCacheClearListener.java create mode 100644 src/hdskins/java/com/voxelmodpack/hdskins/Later.java diff --git a/src/hdskins/java/com/voxelmodpack/hdskins/HDSkinManager.java b/src/hdskins/java/com/voxelmodpack/hdskins/HDSkinManager.java index ac9358ac..c623d0bc 100644 --- a/src/hdskins/java/com/voxelmodpack/hdskins/HDSkinManager.java +++ b/src/hdskins/java/com/voxelmodpack/hdskins/HDSkinManager.java @@ -45,6 +45,8 @@ import java.util.UUID; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.TimeUnit; +import java.util.stream.Collectors; + import javax.annotation.Nonnull; import javax.annotation.Nullable; @@ -62,6 +64,8 @@ public final class HDSkinManager implements IResourceManagerReloadListener { private boolean enabled = true; + private List clearListeners = Lists.newArrayList(); + private List skinServers = Lists.newArrayList(); private Map> skinCache = Maps.newHashMap(); @@ -223,6 +227,10 @@ public final class HDSkinManager implements IResourceManagerReloadListener { } + public void addClearListener(ISkinCacheClearListener listener) { + clearListeners.add(listener); + } + public static void clearSkinCache() { LiteLoaderLogger.info("Clearing local player skin cache"); @@ -238,6 +246,19 @@ public final class HDSkinManager implements IResourceManagerReloadListener { var1.printStackTrace(); } + INSTANCE.clearListeners = INSTANCE.clearListeners.stream() + .filter(HDSkinManager::onSkinCacheCleared) + .collect(Collectors.toList()); + } + + private static boolean onSkinCacheCleared(ISkinCacheClearListener callback) { + try { + return callback.onSkinCacheCleared(); + } catch (Exception e) { + LiteLoaderLogger.warning("Exception ancountered calling skin listener '{}'. It will be removed.", callback.getClass().getName()); + e.printStackTrace(); + return false; + } } public void addSkinModifier(ISkinModifier modifier) { diff --git a/src/hdskins/java/com/voxelmodpack/hdskins/ISkinCacheClearListener.java b/src/hdskins/java/com/voxelmodpack/hdskins/ISkinCacheClearListener.java new file mode 100644 index 00000000..d1a21d0f --- /dev/null +++ b/src/hdskins/java/com/voxelmodpack/hdskins/ISkinCacheClearListener.java @@ -0,0 +1,6 @@ +package com.voxelmodpack.hdskins; + +@FunctionalInterface +public interface ISkinCacheClearListener { + boolean onSkinCacheCleared(); +} diff --git a/src/hdskins/java/com/voxelmodpack/hdskins/Later.java b/src/hdskins/java/com/voxelmodpack/hdskins/Later.java new file mode 100644 index 00000000..8503de38 --- /dev/null +++ b/src/hdskins/java/com/voxelmodpack/hdskins/Later.java @@ -0,0 +1,27 @@ +package com.voxelmodpack.hdskins; + +public final class Later extends Thread { + + private final int delay; + + protected Later(int delay, Runnable runnable) { + super(runnable); + this.delay = delay; + } + + public static void performLater(int delay, Runnable callable) { + new Later(delay, callable).start(); + } + + public static void performNow(Runnable callable) { + new Later(0, callable).start(); + } + + @Override + public void run() { + try { + if (delay > 0) sleep(delay); + } catch (InterruptedException e) {} + super.run(); + } +} diff --git a/src/hdskins/java/com/voxelmodpack/hdskins/gui/GuiSkins.java b/src/hdskins/java/com/voxelmodpack/hdskins/gui/GuiSkins.java index a1f232dc..7e8fe3ac 100644 --- a/src/hdskins/java/com/voxelmodpack/hdskins/gui/GuiSkins.java +++ b/src/hdskins/java/com/voxelmodpack/hdskins/gui/GuiSkins.java @@ -10,6 +10,7 @@ import com.mojang.authlib.GameProfile; import com.mojang.authlib.minecraft.MinecraftProfileTexture; import com.mumfrey.liteloader.util.log.LiteLoaderLogger; import com.voxelmodpack.hdskins.HDSkinManager; +import com.voxelmodpack.hdskins.Later; import com.voxelmodpack.hdskins.skins.SkinUploadResponse; import com.voxelmodpack.hdskins.upload.awt.ThreadOpenFilePNG; import net.minecraft.client.Minecraft; @@ -34,6 +35,7 @@ import net.minecraft.util.text.TextFormatting; import org.apache.commons.io.FilenameUtils; import org.apache.logging.log4j.LogManager; import org.lwjgl.BufferUtils; +import org.lwjgl.opengl.Display; import org.lwjgl.opengl.GL11; import org.lwjgl.util.glu.GLU; @@ -88,7 +90,8 @@ public class GuiSkins extends GuiScreen implements FutureCallback files.stream().findFirst().ifPresent(this::loadLocalFile)); fileDrop.setVisible(true); + fileDrop.requestFocusInWindow(); } catch (Exception e) { e.printStackTrace(); } @@ -227,10 +237,16 @@ public class GuiSkins extends GuiScreen implements FutureCallback { + if (!(Minecraft.getMinecraft().currentScreen instanceof GuiSkins)) { + if (fileDrop != null) { + fileDrop.setVisible(false); + } + GuiSkins.this.localPlayer.releaseTextures(); + GuiSkins.this.remotePlayer.releaseTextures(); + HDSkinManager.clearSkinCache(); + } + }); } private void onFileOpenDialogClosed(JFileChooser fileDialog, int dialogResult) { @@ -283,7 +299,7 @@ public class GuiSkins extends GuiScreen implements FutureCallback poniesCache = Maps.newHashMap(); - private Map backgroudPoniesCache = Maps.newHashMap(); public PonyManager(PonyConfig config) { this.config = config; @@ -149,7 +149,6 @@ public class PonyManager implements IResourceManagerReloadListener { @Override public void onResourceManagerReload(IResourceManager resourceManager) { poniesCache.clear(); - backgroudPoniesCache.clear(); backgroundPonyList.clear(); try { for (IResource res : resourceManager.getAllResources(BGPONIES_JSON)) { @@ -202,4 +201,11 @@ public class PonyManager implements IResourceManagerReloadListener { return ponies.stream().map(this::apply).collect(Collectors.toList()); } } + + @Override + public boolean onSkinCacheCleared() { + MineLittlePony.logger.info("Flushed {} cached ponies.", poniesCache.size()); + poniesCache.clear(); + return true; + } } diff --git a/src/main/java/com/minelittlepony/hdskins/gui/GuiSkinsMineLP.java b/src/main/java/com/minelittlepony/hdskins/gui/GuiSkinsMineLP.java index 1a540e88..87b434c2 100644 --- a/src/main/java/com/minelittlepony/hdskins/gui/GuiSkinsMineLP.java +++ b/src/main/java/com/minelittlepony/hdskins/gui/GuiSkinsMineLP.java @@ -40,12 +40,4 @@ public class GuiSkinsMineLP extends GuiSkins { ponyManager.removePony(resource); } } - - @Override - public void onGuiClosed() { - super.onGuiClosed(); - ponyManager.removePony(localPlayer.getSkinTexture()); - ponyManager.removePony(remotePlayer.getSkinTexture()); - - } } From 086ff5a6771bd74d7f35e75617a46fe5bcccaf88 Mon Sep 17 00:00:00 2001 From: Sollace Date: Sun, 3 Jun 2018 14:28:59 +0200 Subject: [PATCH 02/10] Fixed UI thread not being updated with new file drops --- .../java/com/voxelmodpack/hdskins/gui/GuiSkins.java | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/hdskins/java/com/voxelmodpack/hdskins/gui/GuiSkins.java b/src/hdskins/java/com/voxelmodpack/hdskins/gui/GuiSkins.java index 7e8fe3ac..4ccb085b 100644 --- a/src/hdskins/java/com/voxelmodpack/hdskins/gui/GuiSkins.java +++ b/src/hdskins/java/com/voxelmodpack/hdskins/gui/GuiSkins.java @@ -93,6 +93,8 @@ public class GuiSkins extends GuiScreen implements FutureCallback files.stream().findFirst().ifPresent(this::loadLocalFile)); + dt.addDropTargetListener((FileDropListener) files -> { + files.stream().findFirst().ifPresent(instance::loadLocalFile); + }); fileDrop.setVisible(true); fileDrop.requestFocusInWindow(); } catch (Exception e) { From 5f8b0cf3952f51cf7d7ed82b09728456f4d8089b Mon Sep 17 00:00:00 2001 From: Sollace Date: Sun, 3 Jun 2018 17:47:21 +0200 Subject: [PATCH 03/10] Naming collusion between MCP:ModelRenderer.render and MLP:IModelPart.render --- .../java/com/minelittlepony/model/AbstractPonyModel.java | 2 +- .../com/minelittlepony/model/capabilities/IModelPart.java | 2 +- .../com/minelittlepony/model/components/PegasusWings.java | 2 +- .../java/com/minelittlepony/model/components/PonyTail.java | 5 +++++ .../com/minelittlepony/model/components/SeaponyTail.java | 2 +- .../java/com/minelittlepony/model/player/ModelAlicorn.java | 2 +- .../java/com/minelittlepony/model/player/ModelPegasus.java | 2 +- .../java/com/minelittlepony/model/ponies/ModelSeapony.java | 2 +- 8 files changed, 12 insertions(+), 7 deletions(-) diff --git a/src/main/java/com/minelittlepony/model/AbstractPonyModel.java b/src/main/java/com/minelittlepony/model/AbstractPonyModel.java index e534f8a4..66c1c166 100644 --- a/src/main/java/com/minelittlepony/model/AbstractPonyModel.java +++ b/src/main/java/com/minelittlepony/model/AbstractPonyModel.java @@ -778,7 +778,7 @@ public abstract class AbstractPonyModel extends ModelPlayer implements IModel { } upperTorso.render(scale); bipedBody.postRender(scale); - tail.render(scale); + tail.renderPart(scale); } protected void renderLegs() { diff --git a/src/main/java/com/minelittlepony/model/capabilities/IModelPart.java b/src/main/java/com/minelittlepony/model/capabilities/IModelPart.java index f1bddfe3..44fc636e 100644 --- a/src/main/java/com/minelittlepony/model/capabilities/IModelPart.java +++ b/src/main/java/com/minelittlepony/model/capabilities/IModelPart.java @@ -18,7 +18,7 @@ public interface IModelPart { /** * Renders this model component. */ - void render(float scale); + void renderPart(float scale); /** * Sets whether this part should be rendered. diff --git a/src/main/java/com/minelittlepony/model/components/PegasusWings.java b/src/main/java/com/minelittlepony/model/components/PegasusWings.java index 0d3b69c9..3dccc7b3 100644 --- a/src/main/java/com/minelittlepony/model/components/PegasusWings.java +++ b/src/main/java/com/minelittlepony/model/components/PegasusWings.java @@ -63,7 +63,7 @@ public class PegasusWings implements IModelPart { } @Override - public void render(float scale) { + public void renderPart(float scale) { boolean standing = pegasus.wingsAreOpen(); leftWing.render(standing, scale); rightWing.render(standing, scale); diff --git a/src/main/java/com/minelittlepony/model/components/PonyTail.java b/src/main/java/com/minelittlepony/model/components/PonyTail.java index c7a50f41..421724e2 100644 --- a/src/main/java/com/minelittlepony/model/components/PonyTail.java +++ b/src/main/java/com/minelittlepony/model/components/PonyTail.java @@ -79,6 +79,11 @@ public class PonyTail extends PlaneRenderer implements IModelPart { isHidden = !visible; } + + public void renderPart(float scale) { + render(scale); + } + private class TailSegment extends PlaneRenderer { private final int index; diff --git a/src/main/java/com/minelittlepony/model/components/SeaponyTail.java b/src/main/java/com/minelittlepony/model/components/SeaponyTail.java index af6fbf49..0cdc1d9f 100644 --- a/src/main/java/com/minelittlepony/model/components/SeaponyTail.java +++ b/src/main/java/com/minelittlepony/model/components/SeaponyTail.java @@ -53,7 +53,7 @@ public class SeaponyTail implements IModelPart { } @Override - public void render(float scale) { + public void renderPart(float scale) { GlStateManager.enableBlend(); tailBase.render(scale); GlStateManager.disableBlend(); diff --git a/src/main/java/com/minelittlepony/model/player/ModelAlicorn.java b/src/main/java/com/minelittlepony/model/player/ModelAlicorn.java index 0ee19fd8..675cecb6 100644 --- a/src/main/java/com/minelittlepony/model/player/ModelAlicorn.java +++ b/src/main/java/com/minelittlepony/model/player/ModelAlicorn.java @@ -32,7 +32,7 @@ public class ModelAlicorn extends ModelUnicorn implements IModelPegasus { protected void renderBody(Entity entity, float move, float swing, float ticks, float headYaw, float headPitch, float scale) { super.renderBody(entity, move, swing, ticks, headYaw, headPitch, scale); if (canFly()) { - wings.render(scale); + wings.renderPart(scale); } } } diff --git a/src/main/java/com/minelittlepony/model/player/ModelPegasus.java b/src/main/java/com/minelittlepony/model/player/ModelPegasus.java index cae65052..dc8e8aed 100644 --- a/src/main/java/com/minelittlepony/model/player/ModelPegasus.java +++ b/src/main/java/com/minelittlepony/model/player/ModelPegasus.java @@ -28,6 +28,6 @@ public class ModelPegasus extends ModelEarthPony implements IModelPegasus { @Override protected void renderBody(Entity entity, float move, float swing, float ticks, float headYaw, float headPitch, float scale) { super.renderBody(entity, move, swing, ticks, headYaw, headPitch, scale); - wings.render(scale); + wings.renderPart(scale); } } diff --git a/src/main/java/com/minelittlepony/model/ponies/ModelSeapony.java b/src/main/java/com/minelittlepony/model/ponies/ModelSeapony.java index cab34a7d..14732fb3 100644 --- a/src/main/java/com/minelittlepony/model/ponies/ModelSeapony.java +++ b/src/main/java/com/minelittlepony/model/ponies/ModelSeapony.java @@ -114,7 +114,7 @@ public class ModelSeapony extends ModelUnicorn { bodyCenter.render(scale); bipedBody.postRender(scale); - tail.render(scale); + tail.renderPart(scale); GlStateManager.enableBlend(); From 0710d51b23e347ff21fad96103ff53d03b819a6f Mon Sep 17 00:00:00 2001 From: Sollace Date: Wed, 6 Jun 2018 19:28:53 +0200 Subject: [PATCH 04/10] Properly delete both mojang's and _our_ skin cache --- src/hdskins/java/com/voxelmodpack/hdskins/HDSkinManager.java | 1 + 1 file changed, 1 insertion(+) diff --git a/src/hdskins/java/com/voxelmodpack/hdskins/HDSkinManager.java b/src/hdskins/java/com/voxelmodpack/hdskins/HDSkinManager.java index c623d0bc..f4e94ff7 100644 --- a/src/hdskins/java/com/voxelmodpack/hdskins/HDSkinManager.java +++ b/src/hdskins/java/com/voxelmodpack/hdskins/HDSkinManager.java @@ -236,6 +236,7 @@ public final class HDSkinManager implements IResourceManagerReloadListener { try { FileUtils.deleteDirectory(new File(LiteLoader.getAssetsDirectory(), "skins")); + FileUtils.deleteDirectory(new File(LiteLoader.getAssetsDirectory(), "hd")); TextureManager textures = Minecraft.getMinecraft().getTextureManager(); INSTANCE.skinCache.values().stream() .flatMap(m -> m.values().stream()) From 44e38c0329d461474d7d3e4c0e5a91d8d334a5fb Mon Sep 17 00:00:00 2001 From: Sollace Date: Wed, 6 Jun 2018 19:51:56 +0200 Subject: [PATCH 05/10] Fixed GLContext is not defined. --- .../java/com/voxelmodpack/hdskins/gui/GuiSkins.java | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/hdskins/java/com/voxelmodpack/hdskins/gui/GuiSkins.java b/src/hdskins/java/com/voxelmodpack/hdskins/gui/GuiSkins.java index 4ccb085b..22b08264 100644 --- a/src/hdskins/java/com/voxelmodpack/hdskins/gui/GuiSkins.java +++ b/src/hdskins/java/com/voxelmodpack/hdskins/gui/GuiSkins.java @@ -244,14 +244,15 @@ public class GuiSkins extends GuiScreen implements FutureCallback { if (!(Minecraft.getMinecraft().currentScreen instanceof GuiSkins)) { if (fileDrop != null) { fileDrop.setVisible(false); } - GuiSkins.this.localPlayer.releaseTextures(); - GuiSkins.this.remotePlayer.releaseTextures(); - HDSkinManager.clearSkinCache(); } }); } From d338a4ddb6ed4303042d877152982d44df27a0e5 Mon Sep 17 00:00:00 2001 From: Sollace Date: Wed, 6 Jun 2018 20:02:26 +0200 Subject: [PATCH 06/10] HDSkins has player data loaded when fetching a pony. --- src/main/java/com/minelittlepony/PonyManager.java | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/main/java/com/minelittlepony/PonyManager.java b/src/main/java/com/minelittlepony/PonyManager.java index 0ad3a6f2..d92b2c46 100644 --- a/src/main/java/com/minelittlepony/PonyManager.java +++ b/src/main/java/com/minelittlepony/PonyManager.java @@ -7,6 +7,7 @@ import com.google.gson.JsonParseException; import com.minelittlepony.model.PMAPI; import com.minelittlepony.pony.data.Pony; import com.minelittlepony.pony.data.PonyLevel; +import com.voxelmodpack.hdskins.HDSkinManager; import com.voxelmodpack.hdskins.ISkinCacheClearListener; import net.minecraft.client.Minecraft; @@ -83,6 +84,9 @@ public class PonyManager implements IResourceManagerReloadListener, ISkinCacheCl } public Pony getPony(NetworkPlayerInfo playerInfo) { + // force load HDSkins if they're not available + HDSkinManager.INSTANCE.getProfileData(playerInfo.getGameProfile()); + ResourceLocation skin = playerInfo.getLocationSkin(); UUID uuid = playerInfo.getGameProfile().getId(); From eba85899635d7b15de4d21e2c4a1d222c34c002c Mon Sep 17 00:00:00 2001 From: Sollace Date: Wed, 6 Jun 2018 20:53:24 +0200 Subject: [PATCH 07/10] Add protocol to the minelp server urls --- src/main/java/com/minelittlepony/MineLittlePony.java | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/main/java/com/minelittlepony/MineLittlePony.java b/src/main/java/com/minelittlepony/MineLittlePony.java index ecf9b9ff..7ab8e845 100644 --- a/src/main/java/com/minelittlepony/MineLittlePony.java +++ b/src/main/java/com/minelittlepony/MineLittlePony.java @@ -27,8 +27,7 @@ public class MineLittlePony { public static final String MOD_NAME = "Mine Little Pony"; public static final String MOD_VERSION = "@VERSION@"; - private static final String SKIN_SERVER_URL = "minelpskins.voxelmodpack.com"; - private static final String GATEWAY_URL = "minelpskinmanager.voxelmodpack.com"; + private static final String MINELP_LEGACY_SERVER = "legacy:http://minelpskins.voxelmodpack.com;http://minelpskinmanager.voxelmodpack.com"; private static final KeyBinding SETTINGS_GUI = new KeyBinding("Settings", Keyboard.KEY_F9, "Mine Little Pony"); @@ -58,7 +57,7 @@ public class MineLittlePony { ms.registerMetadataSectionType(new PonyDataSerialzier(), IPonyData.class); // This also makes it the default gateway server. - SkinServer.defaultServers.add("legacy:" + SKIN_SERVER_URL + ";" + GATEWAY_URL); + SkinServer.defaultServers.add(MINELP_LEGACY_SERVER); } /** From b5d8492b3171c615bf6e40290e7ec06afe496172 Mon Sep 17 00:00:00 2001 From: Sollace Date: Wed, 6 Jun 2018 21:05:38 +0200 Subject: [PATCH 08/10] Cache bust misbehaving servers --- .../java/com/voxelmodpack/hdskins/HDSkinManager.java | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/hdskins/java/com/voxelmodpack/hdskins/HDSkinManager.java b/src/hdskins/java/com/voxelmodpack/hdskins/HDSkinManager.java index f4e94ff7..220fd555 100644 --- a/src/hdskins/java/com/voxelmodpack/hdskins/HDSkinManager.java +++ b/src/hdskins/java/com/voxelmodpack/hdskins/HDSkinManager.java @@ -38,6 +38,7 @@ import java.awt.image.BufferedImage; import java.io.File; import java.io.IOException; import java.util.Collections; +import java.util.Date; import java.util.List; import java.util.Map; import java.util.Optional; @@ -127,6 +128,10 @@ public final class HDSkinManager implements IResourceManagerReloadListener { return skin == LOADING ? Optional.empty() : Optional.of(skin); } + private String bustCache(String url) { + return (url.indexOf('?') > -1 ? '&' : '?') + Long.toString(new Date().getTime()/1000); + } + private void loadTexture(GameProfile profile, final Type type, final SkinAvailableCallback callback) { if (profile.getId() != null) { Map data = getProfileData(profile); @@ -138,7 +143,7 @@ public final class HDSkinManager implements IResourceManagerReloadListener { final IImageBuffer imagebufferdownload = type == Type.SKIN ? new ImageBufferDownloadHD() : null; - ITextureObject texObject = new ThreadDownloadImageETag(file2, texture.getUrl(), + ITextureObject texObject = new ThreadDownloadImageETag(file2, bustCache(texture.getUrl()), DefaultPlayerSkin.getDefaultSkinLegacy(), new IImageBuffer() { @Nonnull From f39d55826c3ac6b3e5535a833334158a0821446f Mon Sep 17 00:00:00 2001 From: Sollace Date: Wed, 6 Jun 2018 21:49:12 +0200 Subject: [PATCH 09/10] Derpiderderderp --- src/hdskins/java/com/voxelmodpack/hdskins/HDSkinManager.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/hdskins/java/com/voxelmodpack/hdskins/HDSkinManager.java b/src/hdskins/java/com/voxelmodpack/hdskins/HDSkinManager.java index 220fd555..965aba4d 100644 --- a/src/hdskins/java/com/voxelmodpack/hdskins/HDSkinManager.java +++ b/src/hdskins/java/com/voxelmodpack/hdskins/HDSkinManager.java @@ -129,7 +129,7 @@ public final class HDSkinManager implements IResourceManagerReloadListener { } private String bustCache(String url) { - return (url.indexOf('?') > -1 ? '&' : '?') + Long.toString(new Date().getTime()/1000); + return url + (url.indexOf('?') > -1 ? '&' : '?') + Long.toString(new Date().getTime()/1000); } private void loadTexture(GameProfile profile, final Type type, final SkinAvailableCallback callback) { From 6cc976f1f86847d59167d0894b5488d4d966436d Mon Sep 17 00:00:00 2001 From: Sollace Date: Thu, 7 Jun 2018 19:56:34 +0200 Subject: [PATCH 10/10] Handle file drop events directly into the client --- .../java/com/voxelmodpack/hdskins/Later.java | 2 + .../voxelmodpack/hdskins/gui/GLWindow.java | 184 ++++++++++++++++++ .../voxelmodpack/hdskins/gui/GuiSkins.java | 60 +----- .../hdskins/mixin/MixinMinecraft.java | 29 +++ src/hdskins/resources/hdskins.mixin.json | 1 + 5 files changed, 222 insertions(+), 54 deletions(-) create mode 100644 src/hdskins/java/com/voxelmodpack/hdskins/gui/GLWindow.java create mode 100644 src/hdskins/java/com/voxelmodpack/hdskins/mixin/MixinMinecraft.java diff --git a/src/hdskins/java/com/voxelmodpack/hdskins/Later.java b/src/hdskins/java/com/voxelmodpack/hdskins/Later.java index 8503de38..2e979663 100644 --- a/src/hdskins/java/com/voxelmodpack/hdskins/Later.java +++ b/src/hdskins/java/com/voxelmodpack/hdskins/Later.java @@ -7,6 +7,8 @@ public final class Later extends Thread { protected Later(int delay, Runnable runnable) { super(runnable); this.delay = delay; + setDaemon(true); + setName("Later#" + getId()); } public static void performLater(int delay, Runnable callable) { diff --git a/src/hdskins/java/com/voxelmodpack/hdskins/gui/GLWindow.java b/src/hdskins/java/com/voxelmodpack/hdskins/gui/GLWindow.java new file mode 100644 index 00000000..25059878 --- /dev/null +++ b/src/hdskins/java/com/voxelmodpack/hdskins/gui/GLWindow.java @@ -0,0 +1,184 @@ +package com.voxelmodpack.hdskins.gui; + +import java.awt.Canvas; +import java.awt.Frame; +import java.awt.dnd.DropTarget; +import java.awt.dnd.DropTargetListener; +import java.awt.event.ComponentAdapter; +import java.awt.event.ComponentEvent; +import java.awt.event.WindowAdapter; +import java.awt.event.WindowEvent; +import java.awt.event.WindowStateListener; +import java.io.Closeable; +import java.io.IOException; +import java.util.TooManyListenersException; + +import javax.imageio.ImageIO; +import javax.swing.JFrame; + +import org.lwjgl.LWJGLException; +import org.lwjgl.opengl.Display; +import org.lwjgl.opengl.DisplayMode; + +import com.google.common.collect.Lists; +import com.voxelmodpack.hdskins.Later; + +import net.minecraft.client.Minecraft; +import net.minecraft.util.ResourceLocation; + +public class GLWindow implements Closeable { + + static GLWindow instance = null; + + public static GLWindow current() { + if (instance == null) { + instance = new GLWindow(); + } + return instance; + } + + private final DropTarget dt; + + private final JFrame frame; + + private DropTargetListener saved = null; + + private final int frameX = 15; + private final int frameY = 36; + + private final Minecraft mc = Minecraft.getMinecraft(); + + private int state = 0; + + private GLWindow() { + int x = Display.getX(); + int y = Display.getY(); + + int w = Display.getWidth() + frameX; + + int h = Display.getHeight() + frameY; + + Canvas canvas = new Canvas(); + + frame = new JFrame(Display.getTitle()); + frame.setResizable(Display.isResizable()); + frame.setLocation(x, y); + frame.setSize(w, h); + frame.getContentPane().setLayout(null); + frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE); + frame.addWindowListener(new WindowAdapter() { + @Override + public void windowClosing(WindowEvent windowEvent) { + Minecraft.getMinecraft().shutdown(); + } + }); + frame.addComponentListener(new ComponentAdapter() { + @Override + public void componentResized(ComponentEvent componentEvent) { + canvas.setBounds(0, 0, frame.getWidth() - frameX, frame.getHeight() - frameY); + } + }); + frame.addWindowStateListener(new WindowStateListener() { + @Override + public void windowStateChanged(WindowEvent event) { + state = event.getNewState(); + Later.performLater(1, () -> { + canvas.setBounds(0, 0, frame.getWidth() - frameX, frame.getHeight() - frameY); + }); + } + }); + setIcons(frame); + + frame.getContentPane().add(canvas); + frame.setVisible(true); + + try { + Display.setParent(canvas); + } catch (LWJGLException e) { + e.printStackTrace(); + } + + if (Display.getWidth() == Display.getDesktopDisplayMode().getWidth()) { + frame.setExtendedState(Frame.MAXIMIZED_BOTH); + } + + state = frame.getExtendedState(); + + if (mc.isFullScreen()) { + try { + Display.setFullscreen(true); + } catch (LWJGLException e) { + e.printStackTrace(); + } + } + + dt = new DropTarget(); + canvas.setDropTarget(dt); + } + + private final void setIcons(JFrame frame) { + try { + frame.setIconImages(Lists.newArrayList( + ImageIO.read(mc.getResourceManager().getResource(new ResourceLocation("icons/icon_16x16.png")).getInputStream()), + ImageIO.read(mc.getResourceManager().getResource(new ResourceLocation("icons/icon_32x32.png")).getInputStream()) + )); + } catch (IOException e) { + e.printStackTrace(); + } + } + + public void setDropTargetListener(DropTargetListener dtl) { + if (saved != null) { + dt.removeDropTargetListener(saved); + } + if (dtl != null) { + try { + dt.addDropTargetListener(dtl); + } catch (TooManyListenersException e) { } + saved = dtl; + } + } + + public static void dispose() { + if (instance != null) { + try { + instance.close(); + } catch (IOException ignored) { + } + } + } + + @Override + public void close() throws IOException { + mc.addScheduledTask(() -> { + try { + Display.setParent(null); + } catch (LWJGLException e) { + e.printStackTrace(); + } + + try { + if (mc.isFullScreen()) { + Display.setFullscreen(true); + } else { + if ((state & JFrame.MAXIMIZED_BOTH) == JFrame.MAXIMIZED_BOTH) { + Display.setLocation(0, 0); + Display.setDisplayMode(Display.getDesktopDisplayMode()); + } else { + Display.setDisplayMode(new DisplayMode(mc.displayWidth, mc.displayHeight)); + Display.setLocation(frame.getX(), frame.getY()); + } + Display.setResizable(false); + Display.setResizable(true); + } + } catch (LWJGLException e) { + e.printStackTrace(); + } + + frame.setVisible(false); + frame.dispose(); + + instance = null; + }); + } +} diff --git a/src/hdskins/java/com/voxelmodpack/hdskins/gui/GuiSkins.java b/src/hdskins/java/com/voxelmodpack/hdskins/gui/GuiSkins.java index 22b08264..9ab9853a 100644 --- a/src/hdskins/java/com/voxelmodpack/hdskins/gui/GuiSkins.java +++ b/src/hdskins/java/com/voxelmodpack/hdskins/gui/GuiSkins.java @@ -35,18 +35,15 @@ import net.minecraft.util.text.TextFormatting; import org.apache.commons.io.FilenameUtils; import org.apache.logging.log4j.LogManager; import org.lwjgl.BufferUtils; -import org.lwjgl.opengl.Display; import org.lwjgl.opengl.GL11; import org.lwjgl.util.glu.GLU; -import java.awt.Color; -import java.awt.Window.Type; -import java.awt.dnd.DropTarget; import java.awt.image.BufferedImage; import java.io.File; import java.io.IOException; import java.nio.DoubleBuffer; import java.nio.file.Path; + import javax.annotation.Nullable; import javax.imageio.ImageIO; import javax.swing.*; @@ -91,8 +88,6 @@ public class GuiSkins extends GuiScreen implements FutureCallback { - files.stream().findFirst().ifPresent(instance::loadLocalFile); - }); - fileDrop.setVisible(true); - fileDrop.requestFocusInWindow(); - } catch (Exception e) { - e.printStackTrace(); - } + GLWindow.current().setDropTargetListener((FileDropListener) files -> { + files.stream().findFirst().ifPresent(instance::loadLocalFile); + }); } private void initPanoramaRenderer() { @@ -247,14 +207,6 @@ public class GuiSkins extends GuiScreen implements FutureCallback { - if (!(Minecraft.getMinecraft().currentScreen instanceof GuiSkins)) { - if (fileDrop != null) { - fileDrop.setVisible(false); - } - } - }); } private void onFileOpenDialogClosed(JFileChooser fileDialog, int dialogResult) { @@ -307,7 +259,7 @@ public class GuiSkins extends GuiScreen implements FutureCallback