diff options
Diffstat (limited to 'mod')
7 files changed, 170 insertions, 25 deletions
diff --git a/mod/build.gradle b/mod/build.gradle index 85b44238..33d028be 100644 --- a/mod/build.gradle +++ b/mod/build.gradle @@ -16,12 +16,20 @@ java { loom { launchConfigs { - "client" { + client { // probably will have to my own mixin tweaker, due to dungeonsguide's weird dynamic loading stuff // property("mixin.debug", "true") // property("asmhelper.verbose", "true") -// arg("--tweakClass", "org.spongepowered.asm.launch.MixinTweaker") + arg("--tweakClass", "kr.syeyoung.dungeonsguide.launcher.coremod.DGTweaker") // arg("--mixin", "mixins.examplemod.json") + + } + } + runs { + client { + runDir = 'runtime' + property('devauth.enabled','true') + client() } } forge { @@ -38,6 +46,7 @@ sourceSets.main { repositories { mavenCentral() maven { url "https://jitpack.io" } + maven {url "https://pkgs.dev.azure.com/djtheredstoner/DevAuth/_packaging/public/maven/v1"} } configurations { @@ -56,15 +65,16 @@ dependencies { implementation "org.json:json:20171018" implementation "com.twelvemonkeys.imageio:imageio-bmp:3.7.0" - compileOnly project(':loader') - - compileOnly "org.projectlombok:lombok:1.18.20" compileOnly files("../jars/Hychat-1.12.1-BETA.jar") annotationProcessor "org.projectlombok:lombok:1.18.16" testCompileOnly "org.projectlombok:lombok:1.18.20" testAnnotationProcessor "org.projectlombok:lombok:1.18.20" + + + compileOnly project(path: ":loader") + runtimeOnly project(path: ":loader") } tasks.withType(JavaCompile) { @@ -74,9 +84,6 @@ tasks.withType(JavaCompile) { tasks.withType(Jar) { archivesBaseName = "dungeonsguide" manifest { - attributes["FMLCorePluginContainsFMLMod"] = "true" - attributes["ForceLoadAsMod"] = "true" - // If you don't want mixins, remove these lines // this["TweakClass"] = "org.spongepowered.asm.launch.MixinTweaker" // this["MixinConfigs"] = "mixins.examplemod.json" diff --git a/mod/src/main/java/kr/syeyoung/dungeonsguide/mod/DungeonsGuide.java b/mod/src/main/java/kr/syeyoung/dungeonsguide/mod/DungeonsGuide.java index f45164e9..f3c600fc 100755 --- a/mod/src/main/java/kr/syeyoung/dungeonsguide/mod/DungeonsGuide.java +++ b/mod/src/main/java/kr/syeyoung/dungeonsguide/mod/DungeonsGuide.java @@ -28,6 +28,8 @@ import kr.syeyoung.dungeonsguide.mod.commands.CommandDungeonsGuide; import kr.syeyoung.dungeonsguide.mod.commands.CommandReparty; import kr.syeyoung.dungeonsguide.mod.config.Config; import kr.syeyoung.dungeonsguide.mod.cosmetics.CosmeticsManager; +import kr.syeyoung.dungeonsguide.mod.cosmetics.CustomNetworkPlayerInfo; +import kr.syeyoung.dungeonsguide.mod.discord.gamesdk.GameSDK; import kr.syeyoung.dungeonsguide.mod.discord.rpc.RichPresenceManager; import kr.syeyoung.dungeonsguide.mod.dungeon.DungeonFacade; import kr.syeyoung.dungeonsguide.mod.events.listener.DungeonListener; @@ -44,11 +46,21 @@ import kr.syeyoung.dungeonsguide.mod.utils.cursor.GLCursors; import kr.syeyoung.dungeonsguide.mod.wsresource.StaticResourceCache; import lombok.Getter; import net.minecraft.client.Minecraft; +import net.minecraft.client.entity.AbstractClientPlayer; +import net.minecraft.client.entity.EntityPlayerSP; import net.minecraft.client.gui.*; +import net.minecraft.client.network.NetHandlerPlayClient; +import net.minecraft.client.network.NetworkPlayerInfo; +import net.minecraft.client.renderer.entity.RenderManager; import net.minecraft.client.resources.IResourceManager; import net.minecraft.client.resources.IResourcePack; +import net.minecraft.command.CommandHandler; import net.minecraft.command.ICommand; +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.entity.player.EntityPlayerMP; import net.minecraft.launchwrapper.LaunchClassLoader; +import net.minecraft.network.play.server.S38PacketPlayerListItem; +import net.minecraft.world.World; import net.minecraftforge.client.ClientCommandHandler; import net.minecraftforge.client.event.GuiOpenEvent; import net.minecraftforge.common.MinecraftForge; @@ -60,9 +72,7 @@ import org.apache.logging.log4j.Logger; import java.io.File; import java.io.IOException; -import java.util.ArrayList; -import java.util.List; -import java.util.Set; +import java.util.*; import java.util.concurrent.ThreadFactory; import java.util.concurrent.atomic.AtomicInteger; @@ -139,10 +149,8 @@ public class DungeonsGuide implements DGInterface { } + private PacketListener packetListener; public void init(File f) { - ClassLoader orignalLoader = Thread.currentThread().getContextClassLoader(); - - Thread.currentThread().setContextClassLoader(getClass().getClassLoader()); ProgressManager.ProgressBar progressbar = ProgressManager.push("DungeonsGuide", 4); progressbar.step("Creating Configuration"); @@ -210,7 +218,7 @@ public class DungeonsGuide implements DGInterface { registerEventsForge(commandReparty = new CommandReparty()); registerEventsForge(new FeatureListener()); - registerEventsForge(new PacketListener()); + registerEventsForge(packetListener = new PacketListener()); registerEventsForge(new Keybinds()); registerEventsForge(PartyManager.INSTANCE); @@ -232,7 +240,7 @@ public class DungeonsGuide implements DGInterface { } if (FeatureRegistry.ETC_REPARTY.isEnabled()) { - ClientCommandHandler.instance.registerCommand(commandReparty); + registerCommands(commandReparty); } if (FeatureRegistry.DISCORD_DONOTUSE.isEnabled()) { @@ -244,7 +252,29 @@ public class DungeonsGuide implements DGInterface { ProgressManager.pop(progressbar); - Thread.currentThread().setContextClassLoader(orignalLoader); + } + + // hotswap fails in dev env due to intellij auto log collection or smth. it holds ref to stacktrace. + + private void transform(AbstractClientPlayer abstractClientPlayer) { + NetworkPlayerInfo uuidNetworkPlayerInfoEntry = ReflectionHelper.getPrivateValue(AbstractClientPlayer.class, + abstractClientPlayer, + "playerInfo", "field_175157_a", "a" + ); + if (uuidNetworkPlayerInfoEntry instanceof CustomNetworkPlayerInfo) { + S38PacketPlayerListItem s38PacketPlayerListItem = new S38PacketPlayerListItem(); + NetworkPlayerInfo newInfo = new NetworkPlayerInfo(s38PacketPlayerListItem.new AddPlayerData( + uuidNetworkPlayerInfoEntry.getGameProfile(), + uuidNetworkPlayerInfoEntry.getResponseTime(), + uuidNetworkPlayerInfoEntry.getGameType(), + ((CustomNetworkPlayerInfo)uuidNetworkPlayerInfoEntry).getOriginalDisplayName() + )); + ReflectionHelper.setPrivateValue(AbstractClientPlayer.class, + abstractClientPlayer, + newInfo, + "playerInfo", "field_175157_a", "a" + ); + } } @Override @@ -255,7 +285,7 @@ public class DungeonsGuide implements DGInterface { for (Object registeredListener : registeredListeners) { MinecraftForge.EVENT_BUS.unregister(registeredListener); } - Set<ICommand> commands = ReflectionHelper.getPrivateValue(ClientCommandHandler.class, ClientCommandHandler.instance, "commandSet"); + Set<ICommand> commands = ReflectionHelper.getPrivateValue(CommandHandler.class, ClientCommandHandler.instance, "commandSet"); for (ICommand registeredCommand : registeredCommands) { ClientCommandHandler.instance.getCommands().remove(registeredCommand.getCommandName()); @@ -264,13 +294,72 @@ public class DungeonsGuide implements DGInterface { } commands.remove(registeredCommand); } + + if (packetListener != null) packetListener.cleanup(); + + try { + EntityPlayerSP ep = (EntityPlayerSP) Minecraft.getMinecraft().getRenderManager().livingPlayer; + transform(ep); + } catch (Exception e) { + e.printStackTrace(); + } + + try { + if (Minecraft.getMinecraft().pointedEntity instanceof AbstractClientPlayer) { + AbstractClientPlayer ep = (AbstractClientPlayer) Minecraft.getMinecraft().pointedEntity; + transform(ep); + } + } catch (Exception e) { + e.printStackTrace(); + } + NetHandlerPlayClient netHandlerPlayClient = Minecraft.getMinecraft().getNetHandler(); + if (netHandlerPlayClient == null) + netHandlerPlayClient = ((EntityPlayerSP) Minecraft.getMinecraft().getRenderManager().livingPlayer).sendQueue; + + if (netHandlerPlayClient != null) { + Map<UUID, NetworkPlayerInfo> playerInfoMap = ReflectionHelper.getPrivateValue(NetHandlerPlayClient.class, + netHandlerPlayClient, "playerInfoMap", "field_147310_i", "i"); + for (Map.Entry<UUID, NetworkPlayerInfo> uuidNetworkPlayerInfoEntry : playerInfoMap.entrySet()) { + if (uuidNetworkPlayerInfoEntry.getValue() instanceof CustomNetworkPlayerInfo) { + S38PacketPlayerListItem s38PacketPlayerListItem = new S38PacketPlayerListItem(); + NetworkPlayerInfo newInfo = new NetworkPlayerInfo(s38PacketPlayerListItem.new AddPlayerData( + uuidNetworkPlayerInfoEntry.getValue().getGameProfile(), + uuidNetworkPlayerInfoEntry.getValue().getResponseTime(), + uuidNetworkPlayerInfoEntry.getValue().getGameType(), + ((CustomNetworkPlayerInfo) uuidNetworkPlayerInfoEntry.getValue()).getOriginalDisplayName() + )); + playerInfoMap.put(uuidNetworkPlayerInfoEntry.getKey(), newInfo); + } + } + } + + World world = Minecraft.getMinecraft().getRenderManager().worldObj; + if (world != null) { + for (AbstractClientPlayer entity : world.getEntities(AbstractClientPlayer.class, input -> true)) { + transform(entity); + } + for (AbstractClientPlayer player : world.getPlayers(AbstractClientPlayer.class, input -> true)) { + transform(player); + } + } + + try { + List<IResourcePack> resourcePackList = ReflectionHelper.getPrivateValue(Minecraft.class, Minecraft.getMinecraft(), "defaultResourcePacks", "aA", "field_110449_ao"); + resourcePackList.removeIf(a -> a instanceof DGTexturePack); + Minecraft.getMinecraft().refreshResources(); + } catch (Exception e) { + e.printStackTrace(); + } + + THREAD_GROUP.interrupt(); THREAD_GROUP.stop(); try { - Thread.sleep(1000); // This is requirement for all the threads to finish within 1 second. or reference leak. + Thread.sleep(2000); // This is requirement for all the threads to finish within 1 second. or reference leak. } catch (InterruptedException e) { } THREAD_GROUP.destroy(); + GameSDK.cleanup(); } @Override diff --git a/mod/src/main/java/kr/syeyoung/dungeonsguide/mod/commands/CommandDungeonsGuide.java b/mod/src/main/java/kr/syeyoung/dungeonsguide/mod/commands/CommandDungeonsGuide.java index 5c65424e..fa516bfd 100644 --- a/mod/src/main/java/kr/syeyoung/dungeonsguide/mod/commands/CommandDungeonsGuide.java +++ b/mod/src/main/java/kr/syeyoung/dungeonsguide/mod/commands/CommandDungeonsGuide.java @@ -32,8 +32,12 @@ import kr.syeyoung.dungeonsguide.mod.stomp.StompManager; import kr.syeyoung.dungeonsguide.mod.stomp.StompPayload; import kr.syeyoung.dungeonsguide.mod.wsresource.StaticResourceCache; import net.minecraft.client.Minecraft; +import net.minecraft.client.gui.GuiMainMenu; +import net.minecraft.client.gui.GuiMultiplayer; +import net.minecraft.client.multiplayer.WorldClient; import net.minecraft.command.CommandBase; import net.minecraft.command.ICommandSender; +import net.minecraft.realms.RealmsBridge; import net.minecraft.util.ChatComponentText; import net.minecraft.util.ChatStyle; import net.minecraftforge.fml.common.eventhandler.SubscribeEvent; @@ -141,7 +145,21 @@ public class CommandDungeonsGuide extends CommandBase { } } } else if (args[0].equals("reload")) { - Main.getMain().reloadWithoutStacktraceReference(Main.getMain().getCurrentLoader()); + Minecraft.getMinecraft().addScheduledTask(() -> { + boolean flag = Minecraft.getMinecraft().isIntegratedServerRunning(); + boolean flag1 = Minecraft.getMinecraft().isConnectedToRealms(); + Minecraft.getMinecraft().theWorld.sendQuittingDisconnectingPacket(); + Minecraft.getMinecraft().loadWorld((WorldClient)null); + if (flag) { + Minecraft.getMinecraft().displayGuiScreen(new GuiMainMenu()); + } else if (flag1) { + RealmsBridge realmsbridge = new RealmsBridge(); + realmsbridge.switchToRealms(new GuiMainMenu()); + } else { + Minecraft.getMinecraft().displayGuiScreen(new GuiMultiplayer(new GuiMainMenu())); + } + Main.getMain().reloadWithoutStacktraceReference(Main.getMain().getCurrentLoader()); + }); } else { sender.addChatMessage(new ChatComponentText("§eDungeons Guide §7:: §e/dg §7-§fOpens configuration gui")); sender.addChatMessage(new ChatComponentText("§eDungeons Guide §7:: §e/dg gui §7-§fOpens configuration gui")); diff --git a/mod/src/main/java/kr/syeyoung/dungeonsguide/mod/cosmetics/CustomNetworkPlayerInfo.java b/mod/src/main/java/kr/syeyoung/dungeonsguide/mod/cosmetics/CustomNetworkPlayerInfo.java index 7be9a1ca..a54efaf4 100644 --- a/mod/src/main/java/kr/syeyoung/dungeonsguide/mod/cosmetics/CustomNetworkPlayerInfo.java +++ b/mod/src/main/java/kr/syeyoung/dungeonsguide/mod/cosmetics/CustomNetworkPlayerInfo.java @@ -18,17 +18,24 @@ package kr.syeyoung.dungeonsguide.mod.cosmetics; +import com.google.common.base.Objects; import com.mojang.authlib.GameProfile; +import com.mojang.authlib.minecraft.MinecraftProfileTexture; import kr.syeyoung.dungeonsguide.mod.DungeonsGuide; import kr.syeyoung.dungeonsguide.mod.utils.TextUtils; +import net.minecraft.client.Minecraft; import net.minecraft.client.network.NetworkPlayerInfo; +import net.minecraft.client.resources.DefaultPlayerSkin; +import net.minecraft.client.resources.SkinManager; import net.minecraft.network.play.server.S38PacketPlayerListItem; import net.minecraft.scoreboard.ScorePlayerTeam; import net.minecraft.util.ChatComponentText; import net.minecraft.util.IChatComponent; +import net.minecraft.util.ResourceLocation; import java.util.List; +// Reimplement this using ASM. Removing reference to this is too painful. public class CustomNetworkPlayerInfo extends NetworkPlayerInfo { public CustomNetworkPlayerInfo(GameProfile gameProfile) { super(gameProfile); @@ -44,6 +51,10 @@ public class CustomNetworkPlayerInfo extends NetworkPlayerInfo { private String unformattedDisplayText; private String playerNameWithoutColor; + public IChatComponent getOriginalDisplayName() { + return displayName; + } + @Override public void setDisplayName(IChatComponent displayNameIn) { displayName = displayNameIn; @@ -66,6 +77,7 @@ public class CustomNetworkPlayerInfo extends NetworkPlayerInfo { } } + public IChatComponent getDisplayName() { diff --git a/mod/src/main/java/kr/syeyoung/dungeonsguide/mod/discord/gamesdk/GameSDK.java b/mod/src/main/java/kr/syeyoung/dungeonsguide/mod/discord/gamesdk/GameSDK.java index f66043b5..cde3f7e2 100644 --- a/mod/src/main/java/kr/syeyoung/dungeonsguide/mod/discord/gamesdk/GameSDK.java +++ b/mod/src/main/java/kr/syeyoung/dungeonsguide/mod/discord/gamesdk/GameSDK.java @@ -18,12 +18,11 @@ package kr.syeyoung.dungeonsguide.mod.discord.gamesdk; -import com.sun.jna.Library; -import com.sun.jna.Native; -import com.sun.jna.Platform; +import com.sun.jna.*; import kr.syeyoung.dungeonsguide.mod.discord.gamesdk.jna.GameSDKTypeMapper; import kr.syeyoung.dungeonsguide.mod.discord.gamesdk.jna.NativeGameSDK; import lombok.Getter; +import net.minecraftforge.fml.relauncher.ReflectionHelper; import java.io.File; import java.io.IOException; @@ -31,6 +30,7 @@ import java.io.InputStream; import java.nio.file.Files; import java.nio.file.StandardCopyOption; import java.util.Collections; +import java.util.Map; public class GameSDK { @Getter @@ -73,6 +73,20 @@ public class GameSDK { Collections.singletonMap(Library.OPTION_TYPE_MAPPER, GameSDKTypeMapper.INSTANCE)); } + public static void cleanup() { +// com.sun.jna.CallbackReference has reference of DiscordCallback. idk how i should approach fixing this -> I would better write native lib myself later. + if (System.getProperty("dg.safe") == null) return; + + Map infos = ReflectionHelper.getPrivateValue(Structure.class, null, "layoutInfo"); + infos.clear(); + Map options = ReflectionHelper.getPrivateValue(Native.class, null, "options"); + options.clear(); + Map alignments = ReflectionHelper.getPrivateValue(Native.class, null, "alignments"); + alignments.clear(); + Map<Class, TypeMapper> typeMapperMap = ReflectionHelper.getPrivateValue(Native.class, null, "typeMappers"); + typeMapperMap.clear(); + } + public static void writeString(byte[] bts, String str) { System.arraycopy(str.getBytes(), 0, bts, 0, str.getBytes().length); bts[str.getBytes().length] = 0; diff --git a/mod/src/main/java/kr/syeyoung/dungeonsguide/mod/events/listener/PacketListener.java b/mod/src/main/java/kr/syeyoung/dungeonsguide/mod/events/listener/PacketListener.java index acfffb7c..dcdc2c53 100644 --- a/mod/src/main/java/kr/syeyoung/dungeonsguide/mod/events/listener/PacketListener.java +++ b/mod/src/main/java/kr/syeyoung/dungeonsguide/mod/events/listener/PacketListener.java @@ -188,6 +188,11 @@ public class PacketListener extends ChannelDuplexHandler { } public void cleanup() { - thePipeline.remove("dg_packet_handler"); + try { + if (thePipeline != null) + thePipeline.remove("dg_packet_handler"); + } catch (Exception e) { + + } } } diff --git a/mod/src/main/java/kr/syeyoung/dungeonsguide/mod/utils/AhUtils.java b/mod/src/main/java/kr/syeyoung/dungeonsguide/mod/utils/AhUtils.java index 62b11d3d..b28b97a5 100644 --- a/mod/src/main/java/kr/syeyoung/dungeonsguide/mod/utils/AhUtils.java +++ b/mod/src/main/java/kr/syeyoung/dungeonsguide/mod/utils/AhUtils.java @@ -43,7 +43,7 @@ public class AhUtils { static Logger logger = LogManager.getLogger("AhUtils"); - public static Timer timer = new Timer(); +// public static Timer timer = new Timer(); public static int totalAuctions = 0; |