From d7e921769578296e04eb8f9b47ee174f5f7959da Mon Sep 17 00:00:00 2001 From: cpw Date: Tue, 4 Sep 2018 20:23:45 -0400 Subject: [PATCH] Network init --- build.gradle | 19 + .../net/minecraft/client/Minecraft.java.patch | 34 ++ .../client/gui/GuiMainMenu.java.patch | 34 ++ .../NetHandlerHandshakeMemory.java.patch | 10 + .../network/NetHandlerLoginClient.java.patch | 12 + .../network/NetHandlerPlayClient.java.patch | 10 + .../network/NetHandlerPlayServer.java.patch | 10 + .../CPacketCustomPayloadLogin.java.patch | 11 + .../SPacketCustomPayloadLogin.java.patch | 11 + .../server/SPacketCustomPayload.java.patch | 11 + .../server/MinecraftServer.java.patch | 37 ++ .../dedicated/DedicatedServer.java.patch | 18 + .../integrated/IntegratedServer.java.patch | 14 + .../network/NetHandlerHandshakeTCP.java.patch | 10 + .../network/NetHandlerLoginServer.java.patch | 55 +++ .../minecraft/tileentity/IChestLid.java.patch | 11 + .../text/translation/LanguageMap.java.patch | 42 ++ .../net/minecraftforge/common/ForgeMod.java | 3 +- .../minecraftforge/common/ForgeVersion.java | 4 +- .../net/minecraftforge/fml/LaunchTesting.java | 4 +- .../net/minecraftforge/fml/UnsafeHacks.java | 34 +- .../fml/client/ClientModLoader.java | 6 +- .../fml/client/ResourcePackLoader.java | 26 +- .../fml/client/gui/GuiModList.java | 374 +++++++---------- .../fml/client/gui/GuiScrollingList.java | 395 ------------------ .../fml/client/gui/GuiSlotModList.java | 84 ++-- .../event/FMLServerAboutToStartEvent.java | 3 +- .../common/event/FMLServerStartingEvent.java | 6 + .../fml/common/registry/VillagerRegistry.java | 38 +- .../fml/loading/moddiscovery/ModInfo.java | 8 +- .../fml/network/FMLNetworking.java | 178 ++++++++ .../fml/network/ICustomPacket.java | 48 ++- .../fml/network/NetworkDirection.java | 31 +- .../fml/network/NetworkEvent.java | 72 +++- .../fml/network/NetworkHooks.java | 27 +- .../fml/network/NetworkInstance.java | 6 +- .../fml/network/NetworkRegistry.java | 2 - .../network/simple/IndexedMessageCodec.java | 46 +- .../fml/network/simple/SimpleChannel.java | 50 ++- .../fml/server/ServerLifecycleHooks.java | 2 +- .../minecraftforge/registries/GameData.java | 2 - .../server/command/ForgeCommand.java | 48 +-- .../server/command/TextComponentHelper.java | 12 +- 43 files changed, 1064 insertions(+), 794 deletions(-) create mode 100644 patches/minecraft/net/minecraft/client/Minecraft.java.patch create mode 100644 patches/minecraft/net/minecraft/client/gui/GuiMainMenu.java.patch create mode 100644 patches/minecraft/net/minecraft/client/network/NetHandlerHandshakeMemory.java.patch create mode 100644 patches/minecraft/net/minecraft/client/network/NetHandlerLoginClient.java.patch create mode 100644 patches/minecraft/net/minecraft/client/network/NetHandlerPlayClient.java.patch create mode 100644 patches/minecraft/net/minecraft/network/NetHandlerPlayServer.java.patch create mode 100644 patches/minecraft/net/minecraft/network/login/client/CPacketCustomPayloadLogin.java.patch create mode 100644 patches/minecraft/net/minecraft/network/login/server/SPacketCustomPayloadLogin.java.patch create mode 100644 patches/minecraft/net/minecraft/network/play/server/SPacketCustomPayload.java.patch create mode 100644 patches/minecraft/net/minecraft/server/MinecraftServer.java.patch create mode 100644 patches/minecraft/net/minecraft/server/integrated/IntegratedServer.java.patch create mode 100644 patches/minecraft/net/minecraft/server/network/NetHandlerHandshakeTCP.java.patch create mode 100644 patches/minecraft/net/minecraft/server/network/NetHandlerLoginServer.java.patch create mode 100644 patches/minecraft/net/minecraft/tileentity/IChestLid.java.patch create mode 100644 patches/minecraft/net/minecraft/util/text/translation/LanguageMap.java.patch delete mode 100644 src/main/java/net/minecraftforge/fml/client/gui/GuiScrollingList.java create mode 100644 src/main/java/net/minecraftforge/fml/network/FMLNetworking.java diff --git a/build.gradle b/build.gradle index d355854fe..6a3fa0f3d 100644 --- a/build.gradle +++ b/build.gradle @@ -36,6 +36,15 @@ project(':clean') { mappings channel: 'snapshot', version: '20180813-1.12' mcVersion = '1.13' } + task runclient(type: JavaExec) { + doFirst { + mkdir 'runclient' + } + classpath sourceSets.main.runtimeClasspath + args = ['--accessToken', '0', '--version', '1.13'] + main 'net.minecraft.client.main.Main' + workingDir 'runclient' + } } project(':forge') { @@ -94,7 +103,17 @@ project(':forge') { jvmArgs = ['-classpath', project.configurations.ecj.asPath, 'org.eclipse.jdt.internal.compiler.batch.Main', '-nowarn'] } } + task runclient(type: JavaExec) { + doFirst { + mkdir 'runclient' + } + doFirst { + copy { + from sourceSets.main.resources + into "$buildDir/classes/java/main" + } + } classpath sourceSets.main.runtimeClasspath main 'net.minecraftforge.fml.LaunchTesting' systemProperties target:'fmldevclient' diff --git a/patches/minecraft/net/minecraft/client/Minecraft.java.patch b/patches/minecraft/net/minecraft/client/Minecraft.java.patch new file mode 100644 index 000000000..8da6dd68a --- /dev/null +++ b/patches/minecraft/net/minecraft/client/Minecraft.java.patch @@ -0,0 +1,34 @@ +--- a/net/minecraft/client/Minecraft.java ++++ b/net/minecraft/client/Minecraft.java +@@ -413,6 +413,7 @@ + this.languageManager = new LanguageManager(this.gameSettings.language); + this.resourceManager.func_199006_a(this.languageManager); + this.gameSettings.func_198017_a(this.resourcePackRepository); ++ net.minecraftforge.fml.client.ClientModLoader.begin(this, this.resourcePackRepository, this.resourceManager, this.field_195554_ax); + this.refreshResources(); + this.renderEngine = new TextureManager(this.resourceManager); + this.resourceManager.func_199006_a(this.renderEngine); +@@ -469,6 +470,7 @@ + this.resourceManager.func_199006_a(this.searchTreeManager); + GlStateManager.viewport(0, 0, this.field_195558_d.func_198109_k(), this.field_195558_d.func_198091_l()); + this.effectRenderer = new ParticleManager(this.world, this.renderEngine); ++ net.minecraftforge.fml.client.ClientModLoader.end(); + this.ingameGUI = new GuiIngame(this); + if (this.serverName != null) { + this.displayGuiScreen(new GuiConnecting(new GuiMainMenu(), this, this.serverName, this.serverPort)); +@@ -478,6 +480,7 @@ + + this.debugRenderer = new DebugRenderer(this); + GLFW.glfwSetErrorCallback(this::func_195545_a).free(); ++ net.minecraftforge.fml.client.ClientModLoader.complete(); + if (this.gameSettings.fullScreen && !this.field_195558_d.func_198113_j()) { + this.field_195558_d.func_198077_g(); + } +@@ -1404,6 +1407,7 @@ + NetworkManager networkmanager = NetworkManager.provideLocalClient(socketaddress); + networkmanager.setNetHandler(new NetHandlerLoginClient(networkmanager, this, (GuiScreen)null, (p_209507_0_) -> { + })); ++ net.minecraftforge.fml.network.NetworkHooks.registerClientLoginChannel(networkmanager); + networkmanager.sendPacket(new CPacketHandshake(socketaddress.toString(), 0, EnumConnectionState.LOGIN)); + networkmanager.sendPacket(new CPacketLoginStart(this.getSession().getProfile())); + this.networkManager = networkmanager; diff --git a/patches/minecraft/net/minecraft/client/gui/GuiMainMenu.java.patch b/patches/minecraft/net/minecraft/client/gui/GuiMainMenu.java.patch new file mode 100644 index 000000000..24f53b916 --- /dev/null +++ b/patches/minecraft/net/minecraft/client/gui/GuiMainMenu.java.patch @@ -0,0 +1,34 @@ +--- a/net/minecraft/client/gui/GuiMainMenu.java ++++ b/net/minecraft/client/gui/GuiMainMenu.java +@@ -192,12 +192,18 @@ + GuiMainMenu.this.mc.displayGuiScreen(new GuiMultiplayer(GuiMainMenu.this)); + } + }); +- this.addButton(new GuiButton(14, this.width / 2 - 100, p_73969_1_ + p_73969_2_ * 2, I18n.format("menu.online")) { ++ this.addButton(new GuiButton(14, this.width / 2 + 2, p_73969_1_ + p_73969_2_ * 2, 98, 20, I18n.format("menu.online")) { + public void func_194829_a(double p_194829_1_, double p_194829_3_) { + GuiMainMenu.this.switchToRealms(); + } + }); ++ this.addButton(new GuiButton(6, this.width / 2 - 100, p_73969_1_ + p_73969_2_ * 2, 98, 20, I18n.format("fml.menu.mods")) { ++ @Override ++ public void func_194829_a(double x, double y) { ++ GuiMainMenu.this.mc.displayGuiScreen(new net.minecraftforge.fml.client.gui.GuiModList(GuiMainMenu.this)); + } ++ }); ++ } + + private void addDemoButtons(int p_73972_1_, int p_73972_2_) { + this.addButton(new GuiButton(11, this.width / 2 - 100, p_73972_1_, I18n.format("menu.playdemo")) { +@@ -283,7 +289,10 @@ + s = s + ("release".equalsIgnoreCase(this.mc.getVersionType()) ? "" : "/" + this.mc.getVersionType()); + } + +- this.drawString(this.fontRenderer, s, 2, this.height - 10, -1); ++ net.minecraftforge.fml.BrandingControl.forEachLine(true, true, (brdline, brd) -> ++ this.drawString(this.fontRenderer, brd, 2, this.height - ( 10 + brdline * (this.fontRenderer.FONT_HEIGHT + 1)), 16777215) ++ ); ++ + this.drawString(this.fontRenderer, "Copyright Mojang AB. Do not distribute!", this.widthCopyrightRest, this.height - 10, -1); + if (mouseX > this.widthCopyrightRest && mouseX < this.widthCopyrightRest + this.widthCopyright && mouseY > this.height - 10 && mouseY < this.height) { + drawRect(this.widthCopyrightRest, this.height - 1, this.widthCopyrightRest + this.widthCopyright, this.height, -1); diff --git a/patches/minecraft/net/minecraft/client/network/NetHandlerHandshakeMemory.java.patch b/patches/minecraft/net/minecraft/client/network/NetHandlerHandshakeMemory.java.patch new file mode 100644 index 000000000..248198255 --- /dev/null +++ b/patches/minecraft/net/minecraft/client/network/NetHandlerHandshakeMemory.java.patch @@ -0,0 +1,10 @@ +--- a/net/minecraft/client/network/NetHandlerHandshakeMemory.java ++++ b/net/minecraft/client/network/NetHandlerHandshakeMemory.java +@@ -20,6 +20,7 @@ + } + + public void processHandshake(CPacketHandshake packetIn) { ++ if (!net.minecraftforge.fml.server.ServerLifecycleHooks.handleServerLogin(packetIn, this.networkManager)) return; + this.networkManager.setConnectionState(packetIn.getRequestedState()); + this.networkManager.setNetHandler(new NetHandlerLoginServer(this.server, this.networkManager)); + } diff --git a/patches/minecraft/net/minecraft/client/network/NetHandlerLoginClient.java.patch b/patches/minecraft/net/minecraft/client/network/NetHandlerLoginClient.java.patch new file mode 100644 index 000000000..60f78e78f --- /dev/null +++ b/patches/minecraft/net/minecraft/client/network/NetHandlerLoginClient.java.patch @@ -0,0 +1,12 @@ +--- a/net/minecraft/client/network/NetHandlerLoginClient.java ++++ b/net/minecraft/client/network/NetHandlerLoginClient.java +@@ -123,7 +123,9 @@ + } + + public void func_209521_a(SPacketCustomPayloadLogin p_209521_1_) { ++ if (!net.minecraftforge.fml.network.NetworkHooks.onCustomPayload(p_209521_1_, this.networkManager)) { + this.field_209525_d.accept(new TextComponentTranslation("connect.negotiating", new Object[0])); + this.networkManager.sendPacket(new CPacketCustomPayloadLogin(p_209521_1_.func_209918_a(), (PacketBuffer)null)); + } + } ++} diff --git a/patches/minecraft/net/minecraft/client/network/NetHandlerPlayClient.java.patch b/patches/minecraft/net/minecraft/client/network/NetHandlerPlayClient.java.patch new file mode 100644 index 000000000..ad77e2103 --- /dev/null +++ b/patches/minecraft/net/minecraft/client/network/NetHandlerPlayClient.java.patch @@ -0,0 +1,10 @@ +--- a/net/minecraft/client/network/NetHandlerPlayClient.java ++++ b/net/minecraft/client/network/NetHandlerPlayClient.java +@@ -1615,6 +1615,7 @@ + ((DebugRendererWorldGenAttempts)this.client.debugRenderer.field_201750_j).func_201734_a(packetbuffer.readBlockPos(), packetbuffer.readFloat(), packetbuffer.readFloat(), packetbuffer.readFloat(), packetbuffer.readFloat(), packetbuffer.readFloat()); + LOGGER.warn("Unknown custom packed identifier: {}", (Object)resourcelocation); + } else { ++ if (!net.minecraftforge.fml.network.NetworkHooks.onCustomPayload(packetIn, this.netManager)) + LOGGER.warn("Unknown custom packed identifier: {}", (Object)resourcelocation); + } + } finally { diff --git a/patches/minecraft/net/minecraft/network/NetHandlerPlayServer.java.patch b/patches/minecraft/net/minecraft/network/NetHandlerPlayServer.java.patch new file mode 100644 index 000000000..878bd6b3f --- /dev/null +++ b/patches/minecraft/net/minecraft/network/NetHandlerPlayServer.java.patch @@ -0,0 +1,10 @@ +--- a/net/minecraft/network/NetHandlerPlayServer.java ++++ b/net/minecraft/network/NetHandlerPlayServer.java +@@ -1267,5 +1267,7 @@ + } + + public void processCustomPayload(CPacketCustomPayload packetIn) { ++ PacketThreadUtil.checkThreadAndEnqueue(packetIn, this, this.player.getServerWorld()); ++ net.minecraftforge.fml.network.NetworkHooks.onCustomPayload(packetIn, this.netManager); + } + } diff --git a/patches/minecraft/net/minecraft/network/login/client/CPacketCustomPayloadLogin.java.patch b/patches/minecraft/net/minecraft/network/login/client/CPacketCustomPayloadLogin.java.patch new file mode 100644 index 000000000..5bee70098 --- /dev/null +++ b/patches/minecraft/net/minecraft/network/login/client/CPacketCustomPayloadLogin.java.patch @@ -0,0 +1,11 @@ +--- a/net/minecraft/network/login/client/CPacketCustomPayloadLogin.java ++++ b/net/minecraft/network/login/client/CPacketCustomPayloadLogin.java +@@ -8,7 +8,7 @@ + import net.minecraftforge.api.distmarker.Dist; + import net.minecraftforge.api.distmarker.OnlyIn; + +-public class CPacketCustomPayloadLogin implements Packet { ++public class CPacketCustomPayloadLogin implements Packet, net.minecraftforge.fml.network.ICustomPacket { + private int field_209922_a; + private PacketBuffer field_209923_b; + diff --git a/patches/minecraft/net/minecraft/network/login/server/SPacketCustomPayloadLogin.java.patch b/patches/minecraft/net/minecraft/network/login/server/SPacketCustomPayloadLogin.java.patch new file mode 100644 index 000000000..1dbd9abf7 --- /dev/null +++ b/patches/minecraft/net/minecraft/network/login/server/SPacketCustomPayloadLogin.java.patch @@ -0,0 +1,11 @@ +--- a/net/minecraft/network/login/server/SPacketCustomPayloadLogin.java ++++ b/net/minecraft/network/login/server/SPacketCustomPayloadLogin.java +@@ -8,7 +8,7 @@ + import net.minecraftforge.api.distmarker.Dist; + import net.minecraftforge.api.distmarker.OnlyIn; + +-public class SPacketCustomPayloadLogin implements Packet { ++public class SPacketCustomPayloadLogin implements Packet, net.minecraftforge.fml.network.ICustomPacket { + private int field_209919_a; + private ResourceLocation field_209920_b; + private PacketBuffer field_209921_c; diff --git a/patches/minecraft/net/minecraft/network/play/server/SPacketCustomPayload.java.patch b/patches/minecraft/net/minecraft/network/play/server/SPacketCustomPayload.java.patch new file mode 100644 index 000000000..7b7203acf --- /dev/null +++ b/patches/minecraft/net/minecraft/network/play/server/SPacketCustomPayload.java.patch @@ -0,0 +1,11 @@ +--- a/net/minecraft/network/play/server/SPacketCustomPayload.java ++++ b/net/minecraft/network/play/server/SPacketCustomPayload.java +@@ -8,7 +8,7 @@ + import net.minecraftforge.api.distmarker.Dist; + import net.minecraftforge.api.distmarker.OnlyIn; + +-public class SPacketCustomPayload implements Packet { ++public class SPacketCustomPayload implements Packet, net.minecraftforge.fml.network.ICustomPacket { + public static final ResourceLocation field_209910_a = new ResourceLocation("minecraft:trader_list"); + public static final ResourceLocation field_209911_b = new ResourceLocation("minecraft:brand"); + public static final ResourceLocation field_209912_c = new ResourceLocation("minecraft:book_open"); diff --git a/patches/minecraft/net/minecraft/server/MinecraftServer.java.patch b/patches/minecraft/net/minecraft/server/MinecraftServer.java.patch new file mode 100644 index 000000000..6b19f34e4 --- /dev/null +++ b/patches/minecraft/net/minecraft/server/MinecraftServer.java.patch @@ -0,0 +1,37 @@ +--- a/net/minecraft/server/MinecraftServer.java ++++ b/net/minecraft/server/MinecraftServer.java +@@ -528,6 +528,7 @@ + public void run() { + try { + if (this.init()) { ++ net.minecraftforge.fml.server.ServerLifecycleHooks.handleServerStarted(this); + this.field_211151_aa = Util.func_211177_b(); + this.statusResponse.setServerDescription(new TextComponentString(this.motd)); + this.statusResponse.setVersion(new ServerStatusResponse.Version("1.13", 393)); +@@ -551,7 +552,10 @@ + + this.serverIsRunning = true; + } ++ net.minecraftforge.fml.server.ServerLifecycleHooks.handleServerStopping(this); ++ net.minecraftforge.fml.server.ServerLifecycleHooks.expectServerStopped(); // has to come before finalTick to avoid race conditions + } else { ++ net.minecraftforge.fml.server.ServerLifecycleHooks.expectServerStopped(); // has to come before finalTick to avoid race conditions + this.finalTick((CrashReport)null); + } + } catch (Throwable throwable1) { +@@ -570,6 +574,7 @@ + LOGGER.error("We were unable to save this crash report to disk."); + } + ++ net.minecraftforge.fml.server.ServerLifecycleHooks.expectServerStopped(); // has to come before finalTick to avoid race conditions + this.finalTick(crashreport); + } finally { + try { +@@ -578,6 +583,7 @@ + } catch (Throwable throwable) { + LOGGER.error("Exception stopping the server", throwable); + } finally { ++ net.minecraftforge.fml.server.ServerLifecycleHooks.handleServerStopped(this); + this.systemExitNow(); + } + diff --git a/patches/minecraft/net/minecraft/server/dedicated/DedicatedServer.java.patch b/patches/minecraft/net/minecraft/server/dedicated/DedicatedServer.java.patch index 7f0315512..aafbb296d 100644 --- a/patches/minecraft/net/minecraft/server/dedicated/DedicatedServer.java.patch +++ b/patches/minecraft/net/minecraft/server/dedicated/DedicatedServer.java.patch @@ -16,3 +16,21 @@ this.setPlayerList(new DedicatedPlayerList(this)); long j = Util.func_211178_c(); if (this.getFolderName() == null) { +@@ -219,6 +221,7 @@ + TileEntitySkull.setProfileCache(this.getPlayerProfileCache()); + TileEntitySkull.setSessionService(this.getMinecraftSessionService()); + PlayerProfileCache.setOnlineMode(this.isServerInOnlineMode()); ++ if (!net.minecraftforge.fml.server.ServerLifecycleHooks.handleServerAboutToStart(this)) return false; + LOGGER.info("Preparing level \"{}\"", (Object)this.getFolderName()); + JsonObject jsonobject = new JsonObject(); + if (worldtype == WorldType.FLAT) { +@@ -258,7 +261,8 @@ + } + + Items.AIR.getSubItems(ItemGroup.SEARCH, NonNullList.create()); +- return true; ++ // <3 you Grum for this, saves us ~30 patch files! --^ ++ return net.minecraftforge.fml.server.ServerLifecycleHooks.handleServerStarting(this); + } + } + } diff --git a/patches/minecraft/net/minecraft/server/integrated/IntegratedServer.java.patch b/patches/minecraft/net/minecraft/server/integrated/IntegratedServer.java.patch new file mode 100644 index 000000000..63bd0e4bb --- /dev/null +++ b/patches/minecraft/net/minecraft/server/integrated/IntegratedServer.java.patch @@ -0,0 +1,14 @@ +--- a/net/minecraft/server/integrated/IntegratedServer.java ++++ b/net/minecraft/server/integrated/IntegratedServer.java +@@ -122,9 +122,10 @@ + this.setAllowFlight(true); + LOGGER.info("Generating keypair"); + this.setKeyPair(CryptManager.generateKeyPair()); ++ if (!net.minecraftforge.fml.server.ServerLifecycleHooks.handleServerAboutToStart(this)) return false; + this.loadAllWorlds(this.getFolderName(), this.getWorldName(), this.worldSettings.getSeed(), this.worldSettings.getTerrainType(), this.worldSettings.func_205391_j()); + this.setMOTD(this.getServerOwner() + " - " + this.worlds[0].getWorldInfo().getWorldName()); +- return true; ++ return net.minecraftforge.fml.server.ServerLifecycleHooks.handleServerStarting(this); + } + + public void tick() { diff --git a/patches/minecraft/net/minecraft/server/network/NetHandlerHandshakeTCP.java.patch b/patches/minecraft/net/minecraft/server/network/NetHandlerHandshakeTCP.java.patch new file mode 100644 index 000000000..3a8f07dfe --- /dev/null +++ b/patches/minecraft/net/minecraft/server/network/NetHandlerHandshakeTCP.java.patch @@ -0,0 +1,10 @@ +--- a/net/minecraft/server/network/NetHandlerHandshakeTCP.java ++++ b/net/minecraft/server/network/NetHandlerHandshakeTCP.java +@@ -19,6 +19,7 @@ + } + + public void processHandshake(CPacketHandshake packetIn) { ++ if (!net.minecraftforge.fml.server.ServerLifecycleHooks.handleServerLogin(packetIn, this.networkManager)) return; + switch(packetIn.getRequestedState()) { + case LOGIN: + this.networkManager.setConnectionState(EnumConnectionState.LOGIN); diff --git a/patches/minecraft/net/minecraft/server/network/NetHandlerLoginServer.java.patch b/patches/minecraft/net/minecraft/server/network/NetHandlerLoginServer.java.patch new file mode 100644 index 000000000..d5eb3ea6a --- /dev/null +++ b/patches/minecraft/net/minecraft/server/network/NetHandlerLoginServer.java.patch @@ -0,0 +1,55 @@ +--- a/net/minecraft/server/network/NetHandlerLoginServer.java ++++ b/net/minecraft/server/network/NetHandlerLoginServer.java +@@ -56,6 +56,12 @@ + } + + public void update() { ++ if (this.currentLoginState == LoginState.NEGOTIATING) { ++ // We force the state into "NEGOTIATING" which is otherwise unused. Once we're completed we move the negotiation onto "READY_TO_ACCEPT" ++ // Might want to promote player object creation to here as well.. ++ boolean negotiationComplete = net.minecraftforge.fml.network.NetworkHooks.tickNegotiation(this, this.networkManager, this.player); ++ if (negotiationComplete) this.currentLoginState = LoginState.READY_TO_ACCEPT; ++ } else + if (this.currentLoginState == NetHandlerLoginServer.LoginState.READY_TO_ACCEPT) { + this.tryAcceptPlayer(); + } else if (this.currentLoginState == NetHandlerLoginServer.LoginState.DELAY_ACCEPT) { +@@ -127,7 +133,7 @@ + this.currentLoginState = NetHandlerLoginServer.LoginState.KEY; + this.networkManager.sendPacket(new SPacketEncryptionRequest("", this.server.getKeyPair().getPublic(), this.verifyToken)); + } else { +- this.currentLoginState = NetHandlerLoginServer.LoginState.READY_TO_ACCEPT; ++ this.currentLoginState = LoginState.NEGOTIATING; + } + + } +@@ -150,11 +156,11 @@ + NetHandlerLoginServer.this.loginGameProfile = NetHandlerLoginServer.this.server.getMinecraftSessionService().hasJoinedServer(new GameProfile((UUID)null, gameprofile.getName()), s, this.getAddress()); + if (NetHandlerLoginServer.this.loginGameProfile != null) { + NetHandlerLoginServer.LOGGER.info("UUID of player {} is {}", NetHandlerLoginServer.this.loginGameProfile.getName(), NetHandlerLoginServer.this.loginGameProfile.getId()); +- NetHandlerLoginServer.this.currentLoginState = NetHandlerLoginServer.LoginState.READY_TO_ACCEPT; ++ NetHandlerLoginServer.this.currentLoginState = LoginState.NEGOTIATING; + } else if (NetHandlerLoginServer.this.server.isSinglePlayer()) { + NetHandlerLoginServer.LOGGER.warn("Failed to verify username but will let them in anyway!"); + NetHandlerLoginServer.this.loginGameProfile = NetHandlerLoginServer.this.getOfflineProfile(gameprofile); +- NetHandlerLoginServer.this.currentLoginState = NetHandlerLoginServer.LoginState.READY_TO_ACCEPT; ++ NetHandlerLoginServer.this.currentLoginState = LoginState.NEGOTIATING; + } else { + NetHandlerLoginServer.this.disconnect(new TextComponentTranslation("multiplayer.disconnect.unverified_username", new Object[0])); + NetHandlerLoginServer.LOGGER.error("Username '{}' tried to join with an invalid session", (Object)gameprofile.getName()); +@@ -163,7 +169,7 @@ + if (NetHandlerLoginServer.this.server.isSinglePlayer()) { + NetHandlerLoginServer.LOGGER.warn("Authentication servers are down but will let them in anyway!"); + NetHandlerLoginServer.this.loginGameProfile = NetHandlerLoginServer.this.getOfflineProfile(gameprofile); +- NetHandlerLoginServer.this.currentLoginState = NetHandlerLoginServer.LoginState.READY_TO_ACCEPT; ++ NetHandlerLoginServer.this.currentLoginState = LoginState.NEGOTIATING; + } else { + NetHandlerLoginServer.this.disconnect(new TextComponentTranslation("multiplayer.disconnect.authservers_down", new Object[0])); + NetHandlerLoginServer.LOGGER.error("Couldn't verify username because servers are unavailable"); +@@ -184,6 +190,7 @@ + } + + public void func_209526_a(CPacketCustomPayloadLogin p_209526_1_) { ++ if (!net.minecraftforge.fml.network.NetworkHooks.onCustomPayload(p_209526_1_, this.networkManager)) + this.disconnect(new TextComponentTranslation("multiplayer.disconnect.unexpected_query_response", new Object[0])); + } + diff --git a/patches/minecraft/net/minecraft/tileentity/IChestLid.java.patch b/patches/minecraft/net/minecraft/tileentity/IChestLid.java.patch new file mode 100644 index 000000000..4664150e3 --- /dev/null +++ b/patches/minecraft/net/minecraft/tileentity/IChestLid.java.patch @@ -0,0 +1,11 @@ +--- a/net/minecraft/tileentity/IChestLid.java ++++ b/net/minecraft/tileentity/IChestLid.java +@@ -3,7 +3,7 @@ + import net.minecraftforge.api.distmarker.Dist; + import net.minecraftforge.api.distmarker.OnlyIn; + +-@OnlyIn(Dist.CLIENT) + public interface IChestLid { ++ @OnlyIn(Dist.CLIENT) + float func_195480_a(float p_195480_1_); + } diff --git a/patches/minecraft/net/minecraft/util/text/translation/LanguageMap.java.patch b/patches/minecraft/net/minecraft/util/text/translation/LanguageMap.java.patch new file mode 100644 index 000000000..6cf839273 --- /dev/null +++ b/patches/minecraft/net/minecraft/util/text/translation/LanguageMap.java.patch @@ -0,0 +1,42 @@ +--- a/net/minecraft/util/text/translation/LanguageMap.java ++++ b/net/minecraft/util/text/translation/LanguageMap.java +@@ -26,21 +26,34 @@ + private long lastUpdateTimeInMilliseconds; + + public LanguageMap() { +- try { + InputStream inputstream = LanguageMap.class.getResourceAsStream("/assets/minecraft/lang/en_us.json"); ++ injectLanguage(this, inputstream); ++ } ++ ++ public static void injectLanguage(InputStream inputStream){ ++ injectLanguage(field_197636_c, inputStream); ++ } ++ ++ private static void injectLanguage(LanguageMap inst, InputStream inputStream){ ++ final Map map = parseLanguageFile(inputStream); ++ inst.languageList.putAll(map); ++ inst.lastUpdateTimeInMilliseconds = System.currentTimeMillis(); ++ } ++ ++ private static Map parseLanguageFile(InputStream inputstream) { ++ Map languageList = Maps.newHashMap(); ++ try { + JsonElement jsonelement = (JsonElement)(new Gson()).fromJson(new InputStreamReader(inputstream, StandardCharsets.UTF_8), JsonElement.class); + JsonObject jsonobject = JsonUtils.getJsonObject(jsonelement, "strings"); + + for(Entry entry : jsonobject.entrySet()) { + String s = NUMERIC_VARIABLE_PATTERN.matcher(JsonUtils.getString(entry.getValue(), entry.getKey())).replaceAll("%$1s"); +- this.languageList.put(entry.getKey(), s); ++ languageList.put(entry.getKey(), s); + } +- +- this.lastUpdateTimeInMilliseconds = Util.func_211177_b(); + } catch (JsonParseException jsonparseexception) { + field_201045_a.error("Couldn't read strings from /assets/minecraft/lang/en_us.json", (Throwable)jsonparseexception); + } +- ++ return languageList; + } + + public static LanguageMap getInstance() { diff --git a/src/main/java/net/minecraftforge/common/ForgeMod.java b/src/main/java/net/minecraftforge/common/ForgeMod.java index 6273ec006..2f24f339e 100644 --- a/src/main/java/net/minecraftforge/common/ForgeMod.java +++ b/src/main/java/net/minecraftforge/common/ForgeMod.java @@ -35,6 +35,7 @@ import net.minecraftforge.fml.VersionChecker; import net.minecraftforge.fml.WorldPersistenceHooks; import net.minecraftforge.fml.common.event.FMLServerStartingEvent; import net.minecraftforge.fml.javafmlmod.FMLModLoadingContext; +import net.minecraftforge.server.command.ForgeCommand; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; @@ -410,7 +411,7 @@ public class ForgeMod implements WorldPersistenceHooks.WorldPersistenceHook public void serverStarting(FMLServerStartingEvent evt) { - + new ForgeCommand(evt.getCommandDispatcher()); } public void serverStopping(FMLServerStoppingEvent evt) diff --git a/src/main/java/net/minecraftforge/common/ForgeVersion.java b/src/main/java/net/minecraftforge/common/ForgeVersion.java index dd5b2fa4e..4020ca7f3 100644 --- a/src/main/java/net/minecraftforge/common/ForgeVersion.java +++ b/src/main/java/net/minecraftforge/common/ForgeVersion.java @@ -38,11 +38,11 @@ public class ForgeVersion //This number is incremented every time Jenkins builds Forge, and never reset. Should always be 0 in the repo code. public static final int buildVersion = 0; // This is the minecraft version we're building for - used in various places in Forge/FML code - public static final String mcVersion = "1.12.2"; + public static final String mcVersion = "1.13"; // This is the MCP data version we're using public static final String mcpVersion = "9.42"; - private static final Logger log = LogManager.getLogger("ForgeVersionCheck"); + private static final Logger log = LogManager.getLogger(); public static int getMajorVersion() { diff --git a/src/main/java/net/minecraftforge/fml/LaunchTesting.java b/src/main/java/net/minecraftforge/fml/LaunchTesting.java index 167de278b..739d177f9 100644 --- a/src/main/java/net/minecraftforge/fml/LaunchTesting.java +++ b/src/main/java/net/minecraftforge/fml/LaunchTesting.java @@ -48,8 +48,8 @@ public class LaunchTesting System.setProperty("fml.explodedDir", "/home/cpw/projects/mods/inventorysorter/classes"); hackNatives(); Launcher.main("--launchTarget", System.getProperty("target"),"--gameDir", ".", - "--accessToken", "blah", "--version", "FMLDev", "--assetIndex", "1.12", - "--assetsDir","/home/cpw/.gradle/caches/minecraft/assets", + "--accessToken", "blah", "--version", "FMLDev", "--assetIndex", "1.13", + "--assetsDir","/home/cpw/MultiMC/assets", "--userProperties", "{}"); Thread.sleep(10000); } diff --git a/src/main/java/net/minecraftforge/fml/UnsafeHacks.java b/src/main/java/net/minecraftforge/fml/UnsafeHacks.java index 966a4007f..7361db580 100644 --- a/src/main/java/net/minecraftforge/fml/UnsafeHacks.java +++ b/src/main/java/net/minecraftforge/fml/UnsafeHacks.java @@ -1,5 +1,8 @@ package net.minecraftforge.fml; +import net.minecraft.network.Packet; +import net.minecraft.network.PacketBuffer; +import net.minecraftforge.fml.network.ICustomPacket; import sun.misc.Unsafe; import java.lang.reflect.Field; @@ -20,13 +23,40 @@ public class UnsafeHacks } } + @SuppressWarnings("unchecked") + public static T newInstance(Class packetClass) + { + try + { + return (T) UNSAFE.allocateInstance(packetClass); + } + catch (InstantiationException e) + { + throw new RuntimeException(e); + } + } + @SuppressWarnings("unchecked") public static T getField(Field field, Object object) { final long l = UNSAFE.objectFieldOffset(field); return (T) UNSAFE.getObject(object, l); } - public static T getField(Object object) { - UNSAFE.staticFieldBase() + public static void setField(Field data, Object object, Object buffer) + { + long offset = UNSAFE.objectFieldOffset(data); + UNSAFE.putObject(object, offset, buffer); + } + + public static int getIntField(Field f, Object obj) + { + long offset = UNSAFE.objectFieldOffset(f); + return UNSAFE.getInt(obj, offset); + } + + public static void setIntField(Field data, Object object, int value) + { + long offset = UNSAFE.objectFieldOffset(data); + UNSAFE.putInt(object, offset, value); } } diff --git a/src/main/java/net/minecraftforge/fml/client/ClientModLoader.java b/src/main/java/net/minecraftforge/fml/client/ClientModLoader.java index 81714f4a0..ac91548b2 100644 --- a/src/main/java/net/minecraftforge/fml/client/ClientModLoader.java +++ b/src/main/java/net/minecraftforge/fml/client/ClientModLoader.java @@ -21,8 +21,11 @@ package net.minecraftforge.fml.client; import net.minecraft.client.Minecraft; import net.minecraft.client.renderer.GlStateManager; +import net.minecraft.client.resources.DownloadingPackFinder; +import net.minecraft.client.resources.ResourcePackInfoClient; import net.minecraft.resources.IReloadableResourceManager; import net.minecraft.resources.IResourcePack; +import net.minecraft.resources.ResourcePackList; import net.minecraft.resources.data.IMetadataSectionSerializer; import net.minecraftforge.api.distmarker.Dist; import net.minecraftforge.api.distmarker.OnlyIn; @@ -42,7 +45,7 @@ public class ClientModLoader private static boolean loading; private static Minecraft mc; - public static void begin(final Minecraft minecraft, final List defaultResourcePacks, final IReloadableResourceManager mcResourceManager, IMetadataSectionSerializer metadataSerializer) + public static void begin(final Minecraft minecraft, final ResourcePackList defaultResourcePacks, final IReloadableResourceManager mcResourceManager, DownloadingPackFinder metadataSerializer) { loading = true; ClientModLoader.mc = minecraft; @@ -50,7 +53,6 @@ public class ClientModLoader LogicalSidedProvider.setClient(()->minecraft); ModLoader.get().loadMods(); ResourcePackLoader.loadResourcePacks(defaultResourcePacks); - minecraft.refreshResources(); } public static void end() diff --git a/src/main/java/net/minecraftforge/fml/client/ResourcePackLoader.java b/src/main/java/net/minecraftforge/fml/client/ResourcePackLoader.java index be81bc848..1be4373f7 100644 --- a/src/main/java/net/minecraftforge/fml/client/ResourcePackLoader.java +++ b/src/main/java/net/minecraftforge/fml/client/ResourcePackLoader.java @@ -19,10 +19,15 @@ package net.minecraftforge.fml.client; +import net.minecraft.client.resources.ResourcePackInfoClient; import net.minecraft.resources.AbstractResourcePack; import net.minecraft.resources.FilePack; import net.minecraft.resources.FolderPack; +import net.minecraft.resources.IPackFinder; +import net.minecraft.resources.IReloadableResourceManager; import net.minecraft.resources.IResourcePack; +import net.minecraft.resources.ResourcePackInfo; +import net.minecraft.resources.ResourcePackList; import net.minecraftforge.fml.ModList; import net.minecraftforge.fml.loading.FMLLoader; import net.minecraftforge.fml.loading.moddiscovery.ModFile; @@ -37,20 +42,35 @@ public class ResourcePackLoader { private static Map modResourcePacks; private static AbstractResourcePack forgePack; + private static ResourcePackList resourcePackList; public static IResourcePack getResourcePackFor(String modId) { return modResourcePacks.get(ModList.get().getModFileById(modId).getFile()); } - public static void loadResourcePacks(List resourcePacks) { + @SuppressWarnings("unchecked") + public static T getResourcePackInfo(String modId) { + return (T)resourcePackList.func_198981_a(modId); + } + + public static void loadResourcePacks(ResourcePackList resourcePacks) { + resourcePackList = resourcePacks; modResourcePacks = ModList.get().getModFiles().stream(). map(mf -> new ModFileResourcePack(mf.getFile())). collect(Collectors.toMap(ModFileResourcePack::getModFile, Function.identity())); forgePack = Files.isDirectory(FMLLoader.getForgePath()) ? new FolderPack(FMLLoader.getForgePath().toFile()) : new FilePack(FMLLoader.getForgePath().toFile()); - resourcePacks.add(forgePack); - resourcePacks.addAll(modResourcePacks.values()); + resourcePacks.func_198982_a(new ModPackFinder()); + } + + private static class ModPackFinder implements net.minecraft.resources.IPackFinder + { + @Override + public void func_195730_a(Map packList, ResourcePackInfo.IFactory factory) + { + packList.put("forge", ResourcePackInfo.func_195793_a("forge", true, ()->forgePack, factory, ResourcePackInfo.Priority.BOTTOM)); + } } } diff --git a/src/main/java/net/minecraftforge/fml/client/gui/GuiModList.java b/src/main/java/net/minecraftforge/fml/client/gui/GuiModList.java index 4e58d84b6..b32a4743e 100644 --- a/src/main/java/net/minecraftforge/fml/client/gui/GuiModList.java +++ b/src/main/java/net/minecraftforge/fml/client/gui/GuiModList.java @@ -20,7 +20,6 @@ package net.minecraftforge.fml.client.gui; import java.awt.Dimension; -import java.awt.image.BufferedImage; import java.io.IOException; import java.io.InputStream; import java.util.ArrayList; @@ -29,14 +28,17 @@ import java.util.Comparator; import java.util.List; import java.util.Map.Entry; import java.util.Optional; +import java.util.function.Consumer; +import java.util.function.Function; import java.util.stream.Collectors; import javax.annotation.Nullable; -import javax.imageio.ImageIO; import net.minecraft.client.Minecraft; import net.minecraft.client.gui.FontRenderer; +import net.minecraft.client.gui.Gui; import net.minecraft.client.gui.GuiButton; +import net.minecraft.client.gui.GuiListExtended; import net.minecraft.client.gui.GuiScreen; import net.minecraft.client.gui.GuiTextField; import net.minecraft.client.gui.GuiUtilRenderComponents; @@ -44,14 +46,14 @@ import net.minecraft.client.renderer.GlStateManager; import net.minecraft.client.renderer.Tessellator; import net.minecraft.client.renderer.BufferBuilder; import net.minecraft.client.renderer.texture.DynamicTexture; +import net.minecraft.client.renderer.texture.NativeImage; import net.minecraft.client.renderer.texture.TextureManager; import net.minecraft.client.renderer.vertex.DefaultVertexFormats; import net.minecraft.client.resources.I18n; -import net.minecraft.client.resources.IResourcePack; +import net.minecraft.client.resources.ResourcePackInfoClient; import net.minecraft.util.text.ITextComponent; import net.minecraft.util.text.TextComponentString; import net.minecraft.util.ResourceLocation; -import net.minecraftforge.common.ForgeHooks; import net.minecraftforge.fml.ModList; import net.minecraftforge.fml.VersionChecker; import net.minecraftforge.fml.client.ConfigGuiHandler; @@ -67,9 +69,6 @@ import net.minecraftforge.fml.loading.moddiscovery.ModInfo; import org.apache.commons.lang3.tuple.Pair; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; -import org.lwjgl.input.Mouse; - -import org.lwjgl.opengl.GL11; /** * @author cpw @@ -78,7 +77,6 @@ import org.lwjgl.opengl.GL11; public class GuiModList extends GuiScreen { private static final Logger LOGGER = LogManager.getLogger(); - private enum SortType implements Comparator { NORMAL(24), @@ -86,27 +84,15 @@ public class GuiModList extends GuiScreen Z_TO_A(26){ @Override protected int compare(String name1, String name2){ return name2.compareTo(name1); }}; + + GuiButton button; + private int buttonID; private SortType(int buttonID) { this.buttonID = buttonID; } - - @Nullable - public static SortType getTypeForButton(GuiButton button) - { - for (SortType t : values()) - { - if (t.buttonID == button.id) - { - return t; - } - } - return null; - } - protected int compare(String name1, String name2){ return 0; } - @Override public int compare(ModInfo o1, ModInfo o2) { @@ -115,95 +101,142 @@ public class GuiModList extends GuiScreen return compare(name1, name2); } + String getButtonText() { + return I18n.format("fml.menu.mods."+StringUtils.toLowerCase(name())); + } + + + } + private class SortButton extends GuiButton { + private final SortType type; + public SortButton(int buttonId, int x, int y, int width, int height, SortType type) + { + super(buttonId, x, y, width, height, type.getButtonText()); + this.type = type; + } + + @Override + public void func_194829_a(double p_194829_1_, double p_194829_3_) + { + GuiModList.this.sortType = this.type; + resortMods(); + } } private GuiScreen mainMenu; + private GuiSlotModList modList; - private GuiScrollingList modInfo; + private InfoPanel modInfo; private int selected = -1; private ModInfo selectedMod; private int listWidth; private List mods; - private GuiButton configModButton; - private final List unsortedMods; + private GuiButton configButton; + private int buttonMargin = 1; private int numButtons = SortType.values().length; - private String lastFilterText = ""; private GuiTextField search; + private boolean sorted = false; private SortType sortType = SortType.NORMAL; - /** * @param mainMenu */ public GuiModList(GuiScreen mainMenu) { this.mainMenu = mainMenu; - this.mods = ModList.get().getModFiles().stream(). - map(mf -> mf.getMods().stream().findFirst()). - map(Optional::get). - map(ModInfo.class::cast). - collect(Collectors.toList()); + this.mods = Collections.unmodifiableList(ModList.get().getMods()); this.unsortedMods = Collections.unmodifiableList(this.mods); } + class InfoPanel extends GuiListExtended { + InfoPanel(Minecraft mcIn, int widthIn, int heightIn, int topIn, int bottomIn, int slotHeightIn) + { + super(mcIn, widthIn, heightIn, topIn, bottomIn, slotHeightIn); + } + + @Override + protected int getScrollBarX() + { + return this.width - 6; + } + + void setInfo(Info info) + { + this.func_195086_c(); + this.func_195085_a(info); + } + + public void clear() + { + this.func_195086_c(); + } + } @Override public void initGui() { - int slotHeight = 35; for (ModInfo mod : mods) { listWidth = Math.max(listWidth,getFontRenderer().getStringWidth(mod.getDisplayName()) + 10); - listWidth = Math.max(listWidth,getFontRenderer().getStringWidth(mod.getVersion().getVersionString()) + 5 + slotHeight); + listWidth = Math.max(listWidth,getFontRenderer().getStringWidth(mod.getVersion().getVersionString()) + 5); } listWidth = Math.min(listWidth, 150); - this.modList = new GuiSlotModList(this, mods, listWidth, slotHeight); + this.modList = new GuiSlotModList(this, listWidth); + this.modList.setSlotXBoundsFromLeft(6); + this.modInfo = new InfoPanel(this.mc, this.width - this.listWidth - 30, this.height, 32, this.height - 88 + 4, 1); + this.modInfo.setSlotXBoundsFromLeft(this.listWidth + 24); - this.buttonList.add(new GuiButton(6, ((modList.right + this.width) / 2) - 100, this.height - 38, I18n.format("gui.done"))); - configModButton = new GuiButton(20, 10, this.height - 49, this.listWidth, 20, "Config"); - this.buttonList.add(configModButton); + this.addButton(new GuiButton(6, ((modList.right + this.width) / 2) - 100, this.height - 38, I18n.format("gui.done")){ + @Override + public void func_194829_a(double p_194829_1_, double p_194829_3_) + { + GuiModList.this.mc.displayGuiScreen(GuiModList.this.mainMenu); + } + }); + this.addButton(this.configButton = new GuiButton(20, 10, this.height - 49, this.listWidth, 20, I18n.format("fml.menu.mods.config")){ + @Override + public void func_194829_a(double p_194829_1_, double p_194829_3_) + { + GuiModList.this.displayModConfig(); + } + }); - search = new GuiTextField(0, getFontRenderer(), 12, modList.bottom + 17, modList.listWidth - 4, 14); + search = new GuiTextField(0, getFontRenderer(), 12, modList.bottom + 17, modList.width - 4, 14); + field_195124_j.add(search); + field_195124_j.add(modList); search.setFocused(true); search.setCanLoseFocus(true); - int width = (modList.listWidth / numButtons); + final int width = (modList.width / numButtons); int x = 10, y = 10; - GuiButton normalSort = new GuiButton(SortType.NORMAL.buttonID, x, y, width - buttonMargin, 20, I18n.format("fml.menu.mods.normal")); - normalSort.enabled = false; - buttonList.add(normalSort); + addButton(SortType.NORMAL.button = new SortButton(SortType.NORMAL.buttonID, x, y, width - buttonMargin, 20, SortType.NORMAL)); x += width + buttonMargin; - buttonList.add(new GuiButton(SortType.A_TO_Z.buttonID, x, y, width - buttonMargin, 20, "A-Z")); + addButton(SortType.A_TO_Z.button = new SortButton(SortType.NORMAL.buttonID, x, y, width - buttonMargin, 20, SortType.A_TO_Z)); x += width + buttonMargin; - buttonList.add(new GuiButton(SortType.Z_TO_A.buttonID, x, y, width - buttonMargin, 20, "Z-A")); - + addButton(SortType.Z_TO_A.button = new SortButton(SortType.NORMAL.buttonID, x, y, width - buttonMargin, 20, SortType.Z_TO_A)); + resortMods(); updateCache(); } - @Override - protected void mouseClicked(int x, int y, int button) throws IOException + private void displayModConfig() { - super.mouseClicked(x, y, button); - search.mouseClicked(x, y, button); - if (button == 1 && x >= search.x && x < search.x + search.width && y >= search.y && y < search.y + search.height) { - search.setText(""); + if (selectedMod == null) return; + try + { + ConfigGuiHandler.getGuiFactoryFor(selectedMod).map(f->f.apply(this.mc, this)).ifPresent(newScreen -> this.mc.displayGuiScreen(newScreen)); + } + catch (final Exception e) + { + LOGGER.error("There was a critical issue trying to build the config GUI for {}", selectedMod.getModId(), e); } - } - - @Override - protected void keyTyped(char c, int keyCode) throws IOException - { - super.keyTyped(c, keyCode); - search.textboxKeyTyped(c, keyCode); } @Override public void updateScreen() { - super.updateScreen(); search.updateCursorCounter(); if (!search.getText().equals(lastFilterText)) @@ -216,11 +249,17 @@ public class GuiModList extends GuiScreen { reloadMods(); mods.sort(sortType); - selected = modList.selectedIndex = mods.indexOf(selectedMod); + selected = mods.indexOf(selectedMod); + modList.refreshList(); sorted = true; } } + public > void buildModList(Consumer modListViewConsumer, Function newEntry) + { + mods.forEach(mod->modListViewConsumer.accept(newEntry.apply(mod))); + } + private void reloadMods() { this.mods = this.unsortedMods.stream(). @@ -228,89 +267,30 @@ public class GuiModList extends GuiScreen lastFilterText = search.getText(); } - @Override - protected void actionPerformed(GuiButton button) throws IOException + private void resortMods() { - if (button.enabled) + for (GuiButton b : buttonList) { - SortType type = SortType.getTypeForButton(button); - - if (type != null) - { - for (GuiButton b : buttonList) - { - if (SortType.getTypeForButton(b) != null) - { - b.enabled = true; - } - } - button.enabled = false; - sorted = false; - sortType = type; - Collections.copy(this.mods, this.unsortedMods); - } - else - { - switch (button.id) - { - case 6: - { - this.mc.displayGuiScreen(this.mainMenu); - return; - } - case 20: - { - try - { - ConfigGuiHandler.getGuiFactoryFor(selectedMod). - map(f->f.apply(this.mc, this)). - ifPresent(newScreen -> this.mc.displayGuiScreen(newScreen)); - } - catch (final Exception e) - { - LOGGER.error("There was a critical issue trying to build the config GUI for {}", selectedMod.getModId(), e); - } - return; - } - } + if (b instanceof SortButton) { + b.enabled = sortType.button != b; } } - super.actionPerformed(button); - } - - public int drawLine(String line, int offset, int shifty) - { - this.fontRenderer.drawString(line, offset, shifty, 0xd7edea); - return shifty + 10; + sorted = false; } @Override public void drawScreen(int mouseX, int mouseY, float partialTicks) { this.modList.drawScreen(mouseX, mouseY, partialTicks); - if (this.modInfo != null) - this.modInfo.drawScreen(mouseX, mouseY, partialTicks); + this.modInfo.drawScreen(mouseX, mouseY, partialTicks); int left = ((this.width - this.listWidth - 38) / 2) + this.listWidth + 30; - this.drawCenteredString(this.fontRenderer, "Mod List", left, 16, 0xFFFFFF); super.drawScreen(mouseX, mouseY, partialTicks); String text = I18n.format("fml.menu.mods.search"); int x = ((10 + modList.right) / 2) - (getFontRenderer().getStringWidth(text) / 2); - getFontRenderer().drawString(text, x, modList.bottom + 5, 0xFFFFFF); - search.drawTextBox(); - } - - @Override - public void handleMouseInput() throws IOException - { - int mouseX = Mouse.getEventX() * this.width / this.mc.displayWidth; - int mouseY = this.height - Mouse.getEventY() * this.height / this.mc.displayHeight - 1; - - super.handleMouseInput(); - if (this.modInfo != null) - this.modInfo.handleMouseInput(mouseX, mouseY); - this.modList.handleMouseInput(mouseX, mouseY); + getFontRenderer().func_211126_b(text, x, modList.bottom + 5, 0xFFFFFF); + this.search.func_195608_a(mouseX, mouseY, partialTicks); } Minecraft getMinecraftInstance() @@ -325,10 +305,13 @@ public class GuiModList extends GuiScreen public void selectModIndex(int index) { - if (index == this.selected) - return; - this.selected = index; - this.selectedMod = (index >= 0 && index < mods.size()) ? mods.get(selected) : null; + if (index == this.selected) { + this.selected = -1; + } else + { + this.selected = index; + } + this.selectedMod = (this.selected >= 0 && this.selected< mods.size()) ? mods.get(this.selected) : null; updateCache(); } @@ -340,43 +323,34 @@ public class GuiModList extends GuiScreen private void updateCache() { - configModButton.visible = false; - modInfo = null; - - if (selectedMod == null) + if (selectedMod == null) { + modInfo.clear(); return; + } + this.configButton.enabled = selectedMod.hasConfigUI(); List lines = new ArrayList<>(); VersionChecker.CheckResult vercheck = VersionChecker.getResult(selectedMod); Pair logoData = selectedMod.getLogoFile().map(logoFile-> { TextureManager tm = mc.getTextureManager(); - IResourcePack pack = ResourcePackLoader.getResourcePackFor(selectedMod.getModId()); + ResourcePackInfoClient pack = ResourcePackLoader.getResourcePackInfo(selectedMod.getModId()); try { - BufferedImage logo = null; - if (pack != null) - { - logo = pack.getPackImage(); - } - else - { - InputStream logoResource = getClass().getResourceAsStream(logoFile); - if (logoResource != null) - logo = ImageIO.read(logoResource); - } + NativeImage logo = null; + InputStream logoResource = getClass().getResourceAsStream(logoFile); + if (logoResource != null) + logo = NativeImage.func_195713_a(logoResource); if (logo != null) { - return Pair.of(tm.getDynamicTextureLocation("modlogo", new DynamicTexture(logo)), new Dimension(logo.getWidth(), logo.getHeight())); + return Pair.of(tm.getDynamicTextureLocation("modlogo", new DynamicTexture(logo)), new Dimension(logo.func_195702_a(), logo.func_195714_b())); } } catch (IOException e) { } return Pair.of(null, new Dimension(0, 0)); }).orElse(Pair.of(null, new Dimension(0, 0))); - configModButton.visible = true; - configModButton.enabled = true; lines.add(selectedMod.getDisplayName()); lines.add(String.format("Version: %s", selectedMod.getVersion().getVersionString())); lines.add(String.format("Mod ID: '%s' Mod State: %s", selectedMod.getModId(), ModList.get().getModContainerById(selectedMod.getModId()). @@ -388,7 +362,7 @@ public class GuiModList extends GuiScreen lines.add("Authors: " + authors)); selectedMod.getModConfig().getOptional("displayURL").ifPresent(displayURL -> lines.add("URL: " + displayURL)); - if (selectedMod.getOwningFile().getMods().size()==1) + if (selectedMod.getOwningFile() == null || selectedMod.getOwningFile().getMods().size()==1) lines.add("No child mods for this mod"); else lines.add("Child mods: " + selectedMod.getOwningFile().getMods().stream().map(IModInfo::getDisplayName).collect(Collectors.joining(","))); @@ -411,38 +385,23 @@ public class GuiModList extends GuiScreen } } - modInfo = new Info(this.width - this.listWidth - 30, lines, logoData.getLeft(), logoData.getRight()); + modInfo.setInfo(new Info(modInfo, lines, logoData.getLeft(), logoData.getRight())); } - private class Info extends GuiScrollingList + class Info extends GuiListExtended.IGuiListEntry { - @Nullable private ResourceLocation logoPath; private Dimension logoDims; private List lines = null; - public Info(int width, List lines, @Nullable ResourceLocation logoPath, Dimension logoDims) + public Info(GuiListExtended parent, List lines, @Nullable ResourceLocation logoPath, Dimension logoDims) { - super(GuiModList.this.getMinecraftInstance(), - width, - GuiModList.this.height, - 32, GuiModList.this.height - 88 + 4, - GuiModList.this.listWidth + 20, 60, - GuiModList.this.width, - GuiModList.this.height); + this.field_195004_a = parent; this.lines = resizeContent(lines); this.logoPath = logoPath; this.logoDims = logoDims; - - this.setHeaderInfo(true, getHeaderHeight()); } - @Override protected int getSize() { return 0; } - @Override protected void elementClicked(int index, boolean doubleClick) { } - @Override protected boolean isSelected(int index) { return false; } - @Override protected void drawBackground() {} - @Override protected void drawSlot(int slotIdx, int entryRight, int slotTop, int slotBuffer, Tessellator tess) { } - private List resizeContent(List lines) { List ret = new ArrayList(); @@ -454,8 +413,9 @@ public class GuiModList extends GuiScreen continue; } - ITextComponent chat = ForgeHooks.newChatWithLinks(line, false); - int maxTextLength = this.listWidth - 8; +// ITextComponent chat = ForgeHooks.newChatWithLinks(line, false); + ITextComponent chat = new TextComponentString(line); + int maxTextLength = this.func_195002_d() - 8; if (maxTextLength >= 0) { ret.addAll(GuiUtilRenderComponents.splitText(chat, maxTextLength, GuiModList.this.fontRenderer, false, true)); @@ -464,39 +424,20 @@ public class GuiModList extends GuiScreen return ret; } - private int getHeaderHeight() - { - int height = 0; - if (logoPath != null) - { - double scaleX = logoDims.width / 200.0; - double scaleY = logoDims.height / 65.0; - double scale = 1.0; - if (scaleX > 1 || scaleY > 1) - { - scale = 1.0 / Math.max(scaleX, scaleY); - } - logoDims.width *= scale; - logoDims.height *= scale; - - height += logoDims.height; - height += 10; - } - height += (lines.size() * 10); - if (height < this.bottom - this.top - 8) height = this.bottom - this.top - 8; - return height; - } - @Override - protected void drawHeader(int entryRight, int relativeY, Tessellator tess) + public void func_194999_a(int p_194999_1_, int p_194999_2_, int p_194999_3_, int p_194999_4_, boolean p_194999_5_, float p_194999_6_) { - int top = relativeY; + int top = this.func_195001_c(); + int left = this.func_195002_d(); +/* + int top = this. if (logoPath != null) { GlStateManager.enableBlend(); GuiModList.this.mc.renderEngine.bindTexture(logoPath); + GlStateManager.draw BufferBuilder wr = tess.getBuffer(); int offset = (this.left + this.listWidth/2) - (logoDims.width / 2); wr.begin(GL11.GL_QUADS, DefaultVertexFormats.POSITION_TEX); @@ -509,48 +450,19 @@ public class GuiModList extends GuiScreen top += logoDims.height + 10; } +*/ for (ITextComponent line : lines) { if (line != null) { GlStateManager.enableBlend(); - GuiModList.this.fontRenderer.drawStringWithShadow(line.getFormattedText(), this.left + 4, top, 0xFFFFFF); + GuiModList.this.fontRenderer.drawStringWithShadow(line.getFormattedText(), left + 4, top, 0xFFFFFF); GlStateManager.disableAlpha(); GlStateManager.disableBlend(); } - top += 10; + top += fontRenderer.FONT_HEIGHT + 1; } - } - @Override - protected void clickHeader(int x, int y) - { - int offset = y; - if (logoPath != null) { - offset -= logoDims.height + 10; - } - if (offset <= 0) - return; - - int lineIdx = offset / 10; - if (lineIdx >= lines.size()) - return; - - ITextComponent line = lines.get(lineIdx); - if (line != null) - { - int k = -4; - for (ITextComponent part : line) { - if (!(part instanceof TextComponentString)) - continue; - k += GuiModList.this.fontRenderer.getStringWidth(((TextComponentString)part).getText()); - if (k >= x) - { - GuiModList.this.handleComponentClick(part); - break; - } - } - } } } } diff --git a/src/main/java/net/minecraftforge/fml/client/gui/GuiScrollingList.java b/src/main/java/net/minecraftforge/fml/client/gui/GuiScrollingList.java deleted file mode 100644 index 526953c80..000000000 --- a/src/main/java/net/minecraftforge/fml/client/gui/GuiScrollingList.java +++ /dev/null @@ -1,395 +0,0 @@ -/* - * Minecraft Forge - * Copyright (c) 2016-2018. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation version 2.1 - * of the License. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -package net.minecraftforge.fml.client.gui; - -import net.minecraft.client.Minecraft; -import net.minecraft.client.gui.Gui; -import net.minecraft.client.gui.GuiButton; -import net.minecraft.client.gui.ScaledResolution; -import net.minecraft.client.renderer.BufferBuilder; -import net.minecraft.client.renderer.GlStateManager; -import net.minecraft.client.renderer.Tessellator; -import net.minecraft.client.renderer.vertex.DefaultVertexFormats; -import net.minecraftforge.fml.client.config.GuiUtils; -import org.lwjgl.input.Mouse; -import org.lwjgl.opengl.GL11; - -import java.io.IOException; -import java.util.List; - -public abstract class GuiScrollingList -{ - private final Minecraft client; - protected final int listWidth; - protected final int listHeight; - protected final int screenWidth; - protected final int screenHeight; - protected final int top; - protected final int bottom; - protected final int right; - protected final int left; - protected final int slotHeight; - private int scrollUpActionId; - private int scrollDownActionId; - protected int mouseX; - protected int mouseY; - private float initialMouseClickY = -2.0F; - private float scrollFactor; - private float scrollDistance; - protected int selectedIndex = -1; - private long lastClickTime = 0L; - private boolean highlightSelected = true; - private boolean hasHeader; - private int headerHeight; - protected boolean captureMouse = true; - - @Deprecated // We need to know screen size. - public GuiScrollingList(Minecraft client, int width, int height, int top, int bottom, int left, int entryHeight) - { - this(client, width, height, top, bottom, left, entryHeight, width, height); - } - public GuiScrollingList(Minecraft client, int width, int height, int top, int bottom, int left, int entryHeight, int screenWidth, int screenHeight) - { - this.client = client; - this.listWidth = width; - this.listHeight = height; - this.top = top; - this.bottom = bottom; - this.slotHeight = entryHeight; - this.left = left; - this.right = width + this.left; - this.screenWidth = screenWidth; - this.screenHeight = screenHeight; - } - - @Deprecated // Unused, remove in 1.9.3? - public void func_27258_a(boolean p_27258_1_) - { - this.highlightSelected = p_27258_1_; - } - - @Deprecated protected void func_27259_a(boolean hasFooter, int footerHeight){ setHeaderInfo(hasFooter, footerHeight); } - protected void setHeaderInfo(boolean hasHeader, int headerHeight) - { - this.hasHeader = hasHeader; - this.headerHeight = headerHeight; - if (!hasHeader) this.headerHeight = 0; - } - - protected abstract int getSize(); - - protected abstract void elementClicked(int index, boolean doubleClick); - - protected abstract boolean isSelected(int index); - - protected int getContentHeight() - { - return this.getSize() * this.slotHeight + this.headerHeight; - } - - protected abstract void drawBackground(); - - /** - * Draw anything special on the screen. GL_SCISSOR is enabled for anything that - * is rendered outside of the view box. Do not mess with SCISSOR unless you support this. - */ - protected abstract void drawSlot(int slotIdx, int entryRight, int slotTop, int slotBuffer, Tessellator tess); - - @Deprecated protected void func_27260_a(int entryRight, int relativeY, Tessellator tess) {} - /** - * Draw anything special on the screen. GL_SCISSOR is enabled for anything that - * is rendered outside of the view box. Do not mess with SCISSOR unless you support this. - */ - protected void drawHeader(int entryRight, int relativeY, Tessellator tess) { func_27260_a(entryRight, relativeY, tess); } - - @Deprecated protected void func_27255_a(int x, int y) {} - protected void clickHeader(int x, int y) { func_27255_a(x, y); } - - @Deprecated protected void func_27257_b(int mouseX, int mouseY) {} - /** - * Draw anything special on the screen. GL_SCISSOR is enabled for anything that - * is rendered outside of the view box. Do not mess with SCISSOR unless you support this. - */ - protected void drawScreen(int mouseX, int mouseY) { func_27257_b(mouseX, mouseY); } - - @Deprecated // Unused, Remove in 1.9.3? - public int func_27256_c(int x, int y) - { - int left = this.left + 1; - int right = this.left + this.listWidth - 7; - int relativeY = y - this.top - this.headerHeight + (int)this.scrollDistance - 4; - int entryIndex = relativeY / this.slotHeight; - return x >= left && x <= right && entryIndex >= 0 && relativeY >= 0 && entryIndex < this.getSize() ? entryIndex : -1; - } - - // FIXME: is this correct/still needed? - public void registerScrollButtons(List buttons, int upActionID, int downActionID) - { - this.scrollUpActionId = upActionID; - this.scrollDownActionId = downActionID; - } - - private void applyScrollLimits() - { - int listHeight = this.getContentHeight() - (this.bottom - this.top - 4); - - if (listHeight < 0) - { - listHeight /= 2; - } - - if (this.scrollDistance < 0.0F) - { - this.scrollDistance = 0.0F; - } - - if (this.scrollDistance > (float)listHeight) - { - this.scrollDistance = (float)listHeight; - } - } - - public void actionPerformed(GuiButton button) - { - if (button.enabled) - { - if (button.id == this.scrollUpActionId) - { - this.scrollDistance -= (float)(this.slotHeight * 2 / 3); - this.initialMouseClickY = -2.0F; - this.applyScrollLimits(); - } - else if (button.id == this.scrollDownActionId) - { - this.scrollDistance += (float)(this.slotHeight * 2 / 3); - this.initialMouseClickY = -2.0F; - this.applyScrollLimits(); - } - } - } - - - public void handleMouseInput(int mouseX, int mouseY) throws IOException - { - boolean isHovering = mouseX >= this.left && mouseX <= this.left + this.listWidth && - mouseY >= this.top && mouseY <= this.bottom; - if (!isHovering) - return; - - int scroll = Mouse.getEventDWheel(); - if (scroll != 0) - { - this.scrollDistance += (float)((-1 * scroll / 120.0F) * this.slotHeight / 2); - } - } - - public void drawScreen(int mouseX, int mouseY, float partialTicks) - { - this.mouseX = mouseX; - this.mouseY = mouseY; - this.drawBackground(); - - boolean isHovering = mouseX >= this.left && mouseX <= this.left + this.listWidth && - mouseY >= this.top && mouseY <= this.bottom; - int listLength = this.getSize(); - int scrollBarWidth = 6; - int scrollBarRight = this.left + this.listWidth; - int scrollBarLeft = scrollBarRight - scrollBarWidth; - int entryLeft = this.left; - int entryRight = scrollBarLeft - 1; - int viewHeight = this.bottom - this.top; - int border = 4; - - if (Mouse.isButtonDown(0)) - { - if (this.initialMouseClickY == -1.0F) - { - if (isHovering) - { - int mouseListY = mouseY - this.top - this.headerHeight + (int)this.scrollDistance - border; - int slotIndex = mouseListY / this.slotHeight; - - if (mouseX >= entryLeft && mouseX <= entryRight && slotIndex >= 0 && mouseListY >= 0 && slotIndex < listLength) - { - this.elementClicked(slotIndex, slotIndex == this.selectedIndex && System.currentTimeMillis() - this.lastClickTime < 250L); - this.selectedIndex = slotIndex; - this.lastClickTime = System.currentTimeMillis(); - } - else if (mouseX >= entryLeft && mouseX <= entryRight && mouseListY < 0) - { - this.clickHeader(mouseX - entryLeft, mouseY - this.top + (int)this.scrollDistance - border); - } - - if (mouseX >= scrollBarLeft && mouseX <= scrollBarRight) - { - this.scrollFactor = -1.0F; - int scrollHeight = this.getContentHeight() - viewHeight - border; - if (scrollHeight < 1) scrollHeight = 1; - - int var13 = (int)((float)(viewHeight * viewHeight) / (float)this.getContentHeight()); - - if (var13 < 32) var13 = 32; - if (var13 > viewHeight - border*2) - var13 = viewHeight - border*2; - - this.scrollFactor /= (float)(viewHeight - var13) / (float)scrollHeight; - } - else - { - this.scrollFactor = 1.0F; - } - - this.initialMouseClickY = mouseY; - } - else - { - this.initialMouseClickY = -2.0F; - } - } - else if (this.initialMouseClickY >= 0.0F) - { - this.scrollDistance -= ((float)mouseY - this.initialMouseClickY) * this.scrollFactor; - this.initialMouseClickY = (float)mouseY; - } - } - else - { - this.initialMouseClickY = -1.0F; - } - - this.applyScrollLimits(); - - Tessellator tess = Tessellator.getInstance(); - BufferBuilder worldr = tess.getBuffer(); - - ScaledResolution res = new ScaledResolution(client); - double scaleW = client.displayWidth / res.getScaledWidth_double(); - double scaleH = client.displayHeight / res.getScaledHeight_double(); - GL11.glEnable(GL11.GL_SCISSOR_TEST); - GL11.glScissor((int)(left * scaleW), (int)(client.displayHeight - (bottom * scaleH)), - (int)(listWidth * scaleW), (int)(viewHeight * scaleH)); - - if (this.client.world != null) - { - this.drawGradientRect(this.left, this.top, this.right, this.bottom, 0xC0101010, 0xD0101010); - } - else // Draw dark dirt background - { - GlStateManager.disableLighting(); - GlStateManager.disableFog(); - this.client.renderEngine.bindTexture(Gui.OPTIONS_BACKGROUND); - GlStateManager.color(1.0F, 1.0F, 1.0F, 1.0F); - final float scale = 32.0F; - worldr.begin(GL11.GL_QUADS, DefaultVertexFormats.POSITION_TEX_COLOR); - worldr.pos(this.left, this.bottom, 0.0D).tex(this.left / scale, (this.bottom + (int)this.scrollDistance) / scale).color(0x20, 0x20, 0x20, 0xFF).endVertex(); - worldr.pos(this.right, this.bottom, 0.0D).tex(this.right / scale, (this.bottom + (int)this.scrollDistance) / scale).color(0x20, 0x20, 0x20, 0xFF).endVertex(); - worldr.pos(this.right, this.top, 0.0D).tex(this.right / scale, (this.top + (int)this.scrollDistance) / scale).color(0x20, 0x20, 0x20, 0xFF).endVertex(); - worldr.pos(this.left, this.top, 0.0D).tex(this.left / scale, (this.top + (int)this.scrollDistance) / scale).color(0x20, 0x20, 0x20, 0xFF).endVertex(); - tess.draw(); - } - - int baseY = this.top + border - (int)this.scrollDistance; - - if (this.hasHeader) { - this.drawHeader(entryRight, baseY, tess); - } - - for (int slotIdx = 0; slotIdx < listLength; ++slotIdx) - { - int slotTop = baseY + slotIdx * this.slotHeight + this.headerHeight; - int slotBuffer = this.slotHeight - border; - - if (slotTop <= this.bottom && slotTop + slotBuffer >= this.top) - { - if (this.highlightSelected && this.isSelected(slotIdx)) - { - int min = this.left; - int max = entryRight; - GlStateManager.color(1.0F, 1.0F, 1.0F, 1.0F); - GlStateManager.disableTexture2D(); - worldr.begin(GL11.GL_QUADS, DefaultVertexFormats.POSITION_TEX_COLOR); - worldr.pos(min, slotTop + slotBuffer + 2, 0).tex(0, 1).color(0x80, 0x80, 0x80, 0xFF).endVertex(); - worldr.pos(max, slotTop + slotBuffer + 2, 0).tex(1, 1).color(0x80, 0x80, 0x80, 0xFF).endVertex(); - worldr.pos(max, slotTop - 2, 0).tex(1, 0).color(0x80, 0x80, 0x80, 0xFF).endVertex(); - worldr.pos(min, slotTop - 2, 0).tex(0, 0).color(0x80, 0x80, 0x80, 0xFF).endVertex(); - worldr.pos(min + 1, slotTop + slotBuffer + 1, 0).tex(0, 1).color(0x00, 0x00, 0x00, 0xFF).endVertex(); - worldr.pos(max - 1, slotTop + slotBuffer + 1, 0).tex(1, 1).color(0x00, 0x00, 0x00, 0xFF).endVertex(); - worldr.pos(max - 1, slotTop - 1, 0).tex(1, 0).color(0x00, 0x00, 0x00, 0xFF).endVertex(); - worldr.pos(min + 1, slotTop - 1, 0).tex(0, 0).color(0x00, 0x00, 0x00, 0xFF).endVertex(); - tess.draw(); - GlStateManager.enableTexture2D(); - } - - this.drawSlot(slotIdx, entryRight, slotTop, slotBuffer, tess); - } - } - - GlStateManager.disableDepth(); - - int extraHeight = (this.getContentHeight() + border) - viewHeight; - if (extraHeight > 0) - { - int height = (viewHeight * viewHeight) / this.getContentHeight(); - - if (height < 32) height = 32; - - if (height > viewHeight - border*2) - height = viewHeight - border*2; - - int barTop = (int)this.scrollDistance * (viewHeight - height) / extraHeight + this.top; - if (barTop < this.top) - { - barTop = this.top; - } - - GlStateManager.disableTexture2D(); - worldr.begin(GL11.GL_QUADS, DefaultVertexFormats.POSITION_TEX_COLOR); - worldr.pos(scrollBarLeft, this.bottom, 0.0D).tex(0.0D, 1.0D).color(0x00, 0x00, 0x00, 0xFF).endVertex(); - worldr.pos(scrollBarRight, this.bottom, 0.0D).tex(1.0D, 1.0D).color(0x00, 0x00, 0x00, 0xFF).endVertex(); - worldr.pos(scrollBarRight, this.top, 0.0D).tex(1.0D, 0.0D).color(0x00, 0x00, 0x00, 0xFF).endVertex(); - worldr.pos(scrollBarLeft, this.top, 0.0D).tex(0.0D, 0.0D).color(0x00, 0x00, 0x00, 0xFF).endVertex(); - tess.draw(); - worldr.begin(GL11.GL_QUADS, DefaultVertexFormats.POSITION_TEX_COLOR); - worldr.pos(scrollBarLeft, barTop + height, 0.0D).tex(0.0D, 1.0D).color(0x80, 0x80, 0x80, 0xFF).endVertex(); - worldr.pos(scrollBarRight, barTop + height, 0.0D).tex(1.0D, 1.0D).color(0x80, 0x80, 0x80, 0xFF).endVertex(); - worldr.pos(scrollBarRight, barTop, 0.0D).tex(1.0D, 0.0D).color(0x80, 0x80, 0x80, 0xFF).endVertex(); - worldr.pos(scrollBarLeft, barTop, 0.0D).tex(0.0D, 0.0D).color(0x80, 0x80, 0x80, 0xFF).endVertex(); - tess.draw(); - worldr.begin(GL11.GL_QUADS, DefaultVertexFormats.POSITION_TEX_COLOR); - worldr.pos(scrollBarLeft, barTop + height - 1, 0.0D).tex(0.0D, 1.0D).color(0xC0, 0xC0, 0xC0, 0xFF).endVertex(); - worldr.pos(scrollBarRight - 1, barTop + height - 1, 0.0D).tex(1.0D, 1.0D).color(0xC0, 0xC0, 0xC0, 0xFF).endVertex(); - worldr.pos(scrollBarRight - 1, barTop, 0.0D).tex(1.0D, 0.0D).color(0xC0, 0xC0, 0xC0, 0xFF).endVertex(); - worldr.pos(scrollBarLeft, barTop, 0.0D).tex(0.0D, 0.0D).color(0xC0, 0xC0, 0xC0, 0xFF).endVertex(); - tess.draw(); - } - - this.drawScreen(mouseX, mouseY); - GlStateManager.enableTexture2D(); - GlStateManager.shadeModel(GL11.GL_FLAT); - GlStateManager.enableAlpha(); - GlStateManager.disableBlend(); - GL11.glDisable(GL11.GL_SCISSOR_TEST); - } - - protected void drawGradientRect(int left, int top, int right, int bottom, int color1, int color2) - { - GuiUtils.drawGradientRect(0, left, top, right, bottom, color1, color2); - } -} diff --git a/src/main/java/net/minecraftforge/fml/client/gui/GuiSlotModList.java b/src/main/java/net/minecraftforge/fml/client/gui/GuiSlotModList.java index 2653ccb42..b296e9588 100644 --- a/src/main/java/net/minecraftforge/fml/client/gui/GuiSlotModList.java +++ b/src/main/java/net/minecraftforge/fml/client/gui/GuiSlotModList.java @@ -24,6 +24,7 @@ import java.util.List; import net.minecraft.client.Minecraft; import net.minecraft.client.gui.FontRenderer; import net.minecraft.client.gui.Gui; +import net.minecraft.client.gui.GuiListExtended; import net.minecraft.client.renderer.GlStateManager; import net.minecraft.client.renderer.Tessellator; import net.minecraft.util.ResourceLocation; @@ -37,31 +38,36 @@ import static net.minecraft.util.StringUtils.stripControlCodes; * @author cpw * */ -public class GuiSlotModList extends GuiScrollingList +public class GuiSlotModList extends GuiListExtended { - private static final ResourceLocation VERSION_CHECK_ICONS = new ResourceLocation(ForgeVersion.MOD_ID, "textures/gui/version_check_icons.png"); - + private final int listWidth; + private GuiModList parent; - private List mods; - public GuiSlotModList(GuiModList parent, List mods, int listWidth, int slotHeight) + public GuiSlotModList(GuiModList parent, int listWidth) { - super(parent.getMinecraftInstance(), listWidth, parent.height, 32, parent.height - 88 + 4, 10, slotHeight, parent.width, parent.height); + super(parent.getMinecraftInstance(), listWidth, parent.height, 32, parent.height - 88 + 4, parent.getFontRenderer().FONT_HEIGHT * 2 + 8); this.parent = parent; - this.mods = mods; + this.listWidth = listWidth; + this.refreshList(); } @Override - protected int getSize() + protected int getScrollBarX() { - return mods.size(); + return this.listWidth + 6; } @Override - protected void elementClicked(int index, boolean doubleClick) + public int getListWidth() { - this.parent.selectModIndex(index); + return this.listWidth; + } + + void refreshList() { + this.func_195086_c(); + parent.buildModList(this::func_195085_a, mod->new ModEntry(mod, this.parent)); } @Override @@ -76,32 +82,42 @@ public class GuiSlotModList extends GuiScrollingList this.parent.drawDefaultBackground(); } - @Override - protected int getContentHeight() - { - return (this.getSize()) * 35 + 1; - } + class ModEntry extends GuiListExtended.IGuiListEntry { + private final ModInfo modInfo; + private final GuiModList parent; - @Override - protected void drawSlot(int idx, int right, int top, int height, Tessellator tess) - { - ModInfo mc = mods.get(idx); - String name = stripControlCodes(mc.getDisplayName()); - String version = stripControlCodes(mc.getVersion().getVersionString()); - FontRenderer font = this.parent.getFontRenderer(); - VersionChecker.CheckResult vercheck = VersionChecker.getResult(mc); + ModEntry(ModInfo info, GuiModList parent) { + this.modInfo = info; + this.parent = parent; + } - font.drawString(font.trimStringToWidth(name, listWidth - 10), this.left + 3 , top + 2, 0xFFFFFF); - font.drawString(font.trimStringToWidth(version, listWidth - (5 + height)), this.left + 3 , top + 12, 0xCCCCCC); - - if (vercheck.status.shouldDraw()) + @Override + public void func_194999_a(int p_194999_1_, int p_194999_2_, int p_194999_3_, int p_194999_4_, boolean p_194999_5_, float p_194999_6_) { - //TODO: Consider adding more icons for visualization - Minecraft.getMinecraft().getTextureManager().bindTexture(VERSION_CHECK_ICONS); - GlStateManager.color(1, 1, 1, 1); - GlStateManager.pushMatrix(); - Gui.drawModalRectWithCustomSizedTexture(right - (height / 2 + 4), top + (height / 2 - 4), vercheck.status.getSheetOffset() * 8, (vercheck.status.isAnimated() && ((System.currentTimeMillis() / 800 & 1)) == 1) ? 8 : 0, 8, 8, 64, 16); - GlStateManager.popMatrix(); + int top = this.func_195001_c(); + int left = this.func_195002_d(); + String name = stripControlCodes(modInfo.getDisplayName()); + String version = stripControlCodes(modInfo.getVersion().getVersionString()); + VersionChecker.CheckResult vercheck = VersionChecker.getResult(modInfo); + FontRenderer font = this.parent.getFontRenderer(); + font.func_211126_b(font.trimStringToWidth(name, listWidth),left + 3, top + 2, 0xFFFFFF); + font.func_211126_b(font.trimStringToWidth(version, listWidth), left + 3 , top + 2 + font.FONT_HEIGHT, 0xCCCCCC); + if (vercheck.status.shouldDraw()) + { + //TODO: Consider adding more icons for visualization + Minecraft.getMinecraft().getTextureManager().bindTexture(VERSION_CHECK_ICONS); + GlStateManager.color(1, 1, 1, 1); + GlStateManager.pushMatrix(); + Gui.drawModalRectWithCustomSizedTexture(right - (height / 2 + 4), GuiSlotModList.this.top + (height / 2 - 4), vercheck.status.getSheetOffset() * 8, (vercheck.status.isAnimated() && ((System.currentTimeMillis() / 800 & 1)) == 1) ? 8 : 0, 8, 8, 64, 16); + GlStateManager.popMatrix(); + } + } + + @Override + public boolean mouseClicked(double p_mouseClicked_1_, double p_mouseClicked_3_, int p_mouseClicked_5_) + { + parent.selectModIndex(this.func_195003_b()); + return false; } } } diff --git a/src/main/java/net/minecraftforge/fml/common/event/FMLServerAboutToStartEvent.java b/src/main/java/net/minecraftforge/fml/common/event/FMLServerAboutToStartEvent.java index b4e9786b4..8a73f0d81 100644 --- a/src/main/java/net/minecraftforge/fml/common/event/FMLServerAboutToStartEvent.java +++ b/src/main/java/net/minecraftforge/fml/common/event/FMLServerAboutToStartEvent.java @@ -19,6 +19,8 @@ package net.minecraftforge.fml.common.event; +import com.mojang.brigadier.CommandDispatcher; +import net.minecraft.command.CommandSource; import net.minecraft.server.MinecraftServer; /** @@ -34,5 +36,4 @@ public class FMLServerAboutToStartEvent extends ServerLifecycleEvent { { super(server); } - } diff --git a/src/main/java/net/minecraftforge/fml/common/event/FMLServerStartingEvent.java b/src/main/java/net/minecraftforge/fml/common/event/FMLServerStartingEvent.java index 559fa196c..95d35dddf 100644 --- a/src/main/java/net/minecraftforge/fml/common/event/FMLServerStartingEvent.java +++ b/src/main/java/net/minecraftforge/fml/common/event/FMLServerStartingEvent.java @@ -19,6 +19,8 @@ package net.minecraftforge.fml.common.event; +import com.mojang.brigadier.CommandDispatcher; +import net.minecraft.command.CommandSource; import net.minecraft.server.MinecraftServer; /** @@ -34,4 +36,8 @@ public class FMLServerStartingEvent extends ServerLifecycleEvent { super(server); } + + public CommandDispatcher getCommandDispatcher() { + return server.func_195571_aL().func_197054_a(); + } } diff --git a/src/main/java/net/minecraftforge/fml/common/registry/VillagerRegistry.java b/src/main/java/net/minecraftforge/fml/common/registry/VillagerRegistry.java index c8a37a5c4..890d751dd 100644 --- a/src/main/java/net/minecraftforge/fml/common/registry/VillagerRegistry.java +++ b/src/main/java/net/minecraftforge/fml/common/registry/VillagerRegistry.java @@ -43,6 +43,7 @@ import javax.annotation.Nullable; */ public class VillagerRegistry { +/* public static final RegistryObject FARMER = RegistryObject.of("minecraft:farmer", ()->VillagerProfession.class); private static final VillagerRegistry INSTANCE = new VillagerRegistry(); @@ -53,29 +54,36 @@ public class VillagerRegistry init(); } - /** + */ +/** * Allow access to the {@link net.minecraft.world.gen.structure.StructureVillagePieces} array controlling new village * creation so you can insert your own new village pieces * * @author cpw - */ + *//* + public interface IVillageCreationHandler { - /** + */ +/** * Called when {@link net.minecraft.world.gen.structure.MapGenVillage} is creating a new village * * @param random * @param i - */ + *//* + StructureVillagePieces.PieceWeight getVillagePieceWeight(Random random, int i); - /** + */ +/** * The class of the root structure component to add to the village - */ + *//* + Class getComponentClass(); - /** + */ +/** * Build an instance of the village component {@link net.minecraft.world.gen.structure.StructureVillagePieces} * * @param villagePiece @@ -87,7 +95,8 @@ public class VillagerRegistry * @param p3 * @param facing * @param p5 - */ + *//* + Village buildComponent(StructureVillagePieces.PieceWeight villagePiece, StructureVillagePieces.Start startPiece, List pieces, Random random, int p1, int p2, int p3, EnumFacing facing, int p5); } @@ -97,11 +106,13 @@ public class VillagerRegistry return INSTANCE; } - /** + */ +/** * Register a new village creation handler * * @param handler - */ + *//* + public void registerVillageCreationHandler(IVillageCreationHandler handler) { villageCreationHandlers.put(handler.getComponentClass(), handler); @@ -301,12 +312,14 @@ public class VillagerRegistry } } - /** + */ +/** * Hook called when spawning a Villager, sets it's profession to a random registered profession. * * @param entity The new entity * @param rand The world's RNG - */ + *//* + public static void setRandomProfession(EntityVillager entity, Random rand) { entity.setProfession(INSTANCE.REGISTRY.getRandomObject(rand)); @@ -356,4 +369,5 @@ public class VillagerRegistry //It is nasty I know but it's vanilla. private static final ITradeList[][][][] trades = EntityVillager.GET_TRADES_DONT_USE(); } +*/ } diff --git a/src/main/java/net/minecraftforge/fml/loading/moddiscovery/ModInfo.java b/src/main/java/net/minecraftforge/fml/loading/moddiscovery/ModInfo.java index 2d61232b0..99e95ae06 100644 --- a/src/main/java/net/minecraftforge/fml/loading/moddiscovery/ModInfo.java +++ b/src/main/java/net/minecraftforge/fml/loading/moddiscovery/ModInfo.java @@ -63,7 +63,6 @@ public class ModInfo implements IModInfo this.dependencies = Collections.emptyList(); this.properties = Collections.emptyMap(); } - } @Override @@ -104,6 +103,11 @@ public class ModInfo implements IModInfo public Optional getLogoFile() { - return this.owningFile.getConfig().getOptional("logoFile"); + return this.owningFile != null ? this.owningFile.getConfig().getOptional("logoFile") : Optional.empty(); + } + + public boolean hasConfigUI() + { + return false; } } diff --git a/src/main/java/net/minecraftforge/fml/network/FMLNetworking.java b/src/main/java/net/minecraftforge/fml/network/FMLNetworking.java new file mode 100644 index 000000000..dbfdfc487 --- /dev/null +++ b/src/main/java/net/minecraftforge/fml/network/FMLNetworking.java @@ -0,0 +1,178 @@ +package net.minecraftforge.fml.network; + +import io.netty.util.AttributeKey; +import net.minecraft.nbt.INBTBase; +import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.nbt.NBTTagList; +import net.minecraft.nbt.NBTTagString; +import net.minecraft.network.NetworkManager; +import net.minecraft.network.PacketBuffer; +import net.minecraftforge.fml.ModList; +import net.minecraftforge.fml.loading.moddiscovery.ModInfo; +import net.minecraftforge.fml.network.simple.SimpleChannel; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; +import org.apache.logging.log4j.Marker; +import org.apache.logging.log4j.MarkerManager; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.function.Supplier; +import java.util.stream.Collectors; + +public class FMLNetworking +{ + private static final Logger LOGGER = LogManager.getLogger(); + private static final Marker FMLHSMARKER = MarkerManager.getMarker("FMLHSMARKER"); + static final AttributeKey FML_MARKER = AttributeKey.valueOf("fml:marker"); + private static final AttributeKey FML_HANDSHAKE = AttributeKey.newInstance("fml:handshake"); + + static void registerHandshake(NetworkManager manager, NetworkDirection direction) { + manager.channel().attr(FML_HANDSHAKE).compareAndSet(null, new FMLHandshake(manager, direction)); + } + + private static FMLHandshake getHandshake(Supplier contextSupplier) { + final NetworkManager networkManager = contextSupplier.get().getNetworkManager(); + return getHandshake(networkManager); + } + + private static FMLHandshake getHandshake(NetworkManager manager) + { + return manager.channel().attr(FML_HANDSHAKE).get(); + } + + static boolean dispatch(NetworkManager networkManager) + { + return getHandshake(networkManager).tickServer(); + } + + public static class FMLHandshake { + private static SimpleChannel channel; + private static List> messages = Arrays.asList(HandshakeMessage.S2CModList::new); + private List sentMessages = new ArrayList<>(); + static { + channel = NetworkRegistry.ChannelBuilder.named(NetworkHooks.FMLHANDSHAKE). + clientAcceptedVersions(a -> true). + serverAcceptedVersions(a -> true). + networkProtocolVersion(() -> NetworkHooks.NETVERSION). + simpleChannel(); + channel.messageBuilder(HandshakeMessage.S2CModList.class, 1). + decoder(HandshakeMessage.S2CModList::decode). + encoder(HandshakeMessage.S2CModList::encode). + loginIndex(HandshakeMessage.S2CModList::setPacketIndexSequence). + consumer((m,c)->getHandshake(c).handleServerModListOnClient(m, c)). + add(); + channel.messageBuilder(HandshakeMessage.C2SModListReply.class, 2). + loginIndex(HandshakeMessage::setPacketIndexSequence). + decoder(HandshakeMessage.C2SModListReply::decode). + encoder(HandshakeMessage.C2SModListReply::encode). + consumer((m,c) -> getHandshake(c).handleClientModListOnServer(m,c)). + add(); + } + + private final NetworkDirection direction; + + private final NetworkManager manager; + private int packetPosition; + + public FMLHandshake(NetworkManager networkManager, NetworkDirection side) + { + this.direction = side; + this.manager = networkManager; + } + + public void handleServerModListOnClient(HandshakeMessage.S2CModList serverModList, Supplier c) + { + LOGGER.debug(FMLHSMARKER, "Received S2CModList packet with index {}", serverModList.getPacketIndexSequence()); + c.get().setPacketHandled(true); + final HandshakeMessage.C2SModListReply reply = new HandshakeMessage.C2SModListReply(); + channel.sendLogin(reply, c.get().getNetworkManager(), c.get().getDirection().reply(), reply.getPacketIndexSequence()); + LOGGER.debug(FMLHSMARKER, "Sent C2SModListReply packet with index {}", reply.getPacketIndexSequence()); + } + + private void handleClientModListOnServer(HandshakeMessage.C2SModListReply m, Supplier c) + { + LOGGER.debug(FMLHSMARKER, "Received C2SModListReply with index {}", m.getPacketIndexSequence()); + final HandshakeMessage message = this.sentMessages.stream().filter(ob -> ob.getPacketIndexSequence() == m.getPacketIndexSequence()).findFirst().orElseThrow(() -> new RuntimeException("Unexpected reply from client")); + boolean removed = this.sentMessages.remove(message); + c.get().setPacketHandled(true); + LOGGER.debug(FMLHSMARKER, "Cleared original message {}", removed); + } + + public boolean tickServer() + { + if (packetPosition < messages.size()) { + final HandshakeMessage message = messages.get(packetPosition).get(); + LOGGER.debug(FMLHSMARKER, "Sending ticking packet {} index {}", message.getClass().getName(), message.getPacketIndexSequence()); + channel.sendLogin(message, this.manager, this.direction, packetPosition); + sentMessages.add(message); + packetPosition++; + } + + // we're done when sentMessages is empty + if (sentMessages.isEmpty()) { + // clear ourselves - we're done! + this.manager.channel().attr(FML_HANDSHAKE).set(null); + return true; + } + return false; + } + } + + + static class HandshakeMessage + { + private int index; + public void setPacketIndexSequence(int i) + { + this.index = i; + } + + public int getPacketIndexSequence() + { + return index; + } + + static class S2CModList extends HandshakeMessage + { + private List modList; + + private int index; + S2CModList() { + this.modList = ModList.get().getMods().stream().map(ModInfo::getModId).collect(Collectors.toList()); + } + + S2CModList(NBTTagCompound nbtTagCompound) + { + this.modList = nbtTagCompound.getTagList("list", 8).stream().map(INBTBase::getString).collect(Collectors.toList()); + } + + public static S2CModList decode(PacketBuffer packetBuffer) + { + final NBTTagCompound nbtTagCompound = packetBuffer.readCompoundTag(); + return new S2CModList(nbtTagCompound); + } + + public void encode(PacketBuffer packetBuffer) + { + NBTTagCompound tag = new NBTTagCompound(); + tag.setTag("list",modList.stream().map(NBTTagString::new).collect(Collectors.toCollection(NBTTagList::new))); + packetBuffer.writeCompoundTag(tag); + } + } + + static class C2SModListReply extends HandshakeMessage + { + public static C2SModListReply decode(PacketBuffer buffer) + { + return new C2SModListReply(); + } + + public void encode(PacketBuffer buffer) + { + + } + } + } +} diff --git a/src/main/java/net/minecraftforge/fml/network/ICustomPacket.java b/src/main/java/net/minecraftforge/fml/network/ICustomPacket.java index 85a91640a..7f7031728 100644 --- a/src/main/java/net/minecraftforge/fml/network/ICustomPacket.java +++ b/src/main/java/net/minecraftforge/fml/network/ICustomPacket.java @@ -1,23 +1,32 @@ package net.minecraftforge.fml.network; +import io.netty.buffer.Unpooled; import it.unimi.dsi.fastutil.objects.Reference2ReferenceArrayMap; import net.minecraft.network.Packet; import net.minecraft.network.PacketBuffer; +import net.minecraft.network.login.client.CPacketCustomPayloadLogin; +import net.minecraft.network.login.server.SPacketCustomPayloadLogin; import net.minecraft.network.play.client.CPacketCustomPayload; import net.minecraft.network.play.server.SPacketCustomPayload; import net.minecraft.util.ResourceLocation; import net.minecraftforge.fml.UnsafeHacks; import java.lang.reflect.Field; +import java.lang.reflect.Modifier; +import java.util.Arrays; +import java.util.Optional; import java.util.function.Function; import java.util.function.Supplier; import java.util.stream.Collectors; import java.util.stream.Stream; public interface ICustomPacket> { + @SuppressWarnings("OptionalUsedAsFieldOrParameterType") enum Fields { CPACKETCUSTOMPAYLOAD(CPacketCustomPayload.class), SPACKETCUSTOMPAYLOAD(SPacketCustomPayload.class), + CPACKETCUSTOMLOGIN(CPacketCustomPayloadLogin.class), + SPACKETCUSTOMLOGIN(SPacketCustomPayloadLogin.class), ; static final Reference2ReferenceArrayMap, Fields> lookup; @@ -28,20 +37,17 @@ public interface ICustomPacket> { private final Class clazz; - public final Field data; - public final Field channel; + final Optional data; + final Optional channel; + final Optional index; + Fields(Class customPacketClass) { this.clazz = customPacketClass; - try - { - data = customPacketClass.getDeclaredField("data"); - channel = customPacketClass.getDeclaredField("channel"); - } - catch (NoSuchFieldException e) - { - throw new RuntimeException("BARF?"); - } + Field[] fields = customPacketClass.getDeclaredFields(); + data = Arrays.stream(fields).filter(f-> !Modifier.isStatic(f.getModifiers()) && f.getType() == PacketBuffer.class).findFirst(); + channel = Arrays.stream(fields).filter(f->!Modifier.isStatic(f.getModifiers()) && f.getType() == ResourceLocation.class).findFirst(); + index = Arrays.stream(fields).filter(f->!Modifier.isStatic(f.getModifiers()) && f.getType() == int.class).findFirst(); } private Class getClazz() @@ -51,11 +57,27 @@ public interface ICustomPacket> { } default PacketBuffer getData() { - return UnsafeHacks.getField(Fields.lookup.get(this.getClass()).data, this); + return Fields.lookup.get(this.getClass()).data.map(f->UnsafeHacks.getField(f, this)).orElse(null); } default ResourceLocation getName() { - return UnsafeHacks.getField(Fields.lookup.get(this.getClass()).channel, this); + return Fields.lookup.get(this.getClass()).channel.map(f->UnsafeHacks.getField(f, this)).orElse(NetworkHooks.FMLHANDSHAKE); + } + + default int getIndex() { + return Fields.lookup.get(this.getClass()).index.map(f->UnsafeHacks.getIntField(f, this)).orElse(Integer.MIN_VALUE); + } + + default void setData(PacketBuffer buffer) { + Fields.lookup.get(this.getClass()).data.ifPresent(f->UnsafeHacks.setField(f, this, buffer)); + } + + default void setName(ResourceLocation channelName) { + Fields.lookup.get(this.getClass()).channel.ifPresent(f->UnsafeHacks.setField(f, this, channelName)); + } + + default void setIndex(int index) { + Fields.lookup.get(this.getClass()).index.ifPresent(f->UnsafeHacks.setIntField(f, this, index)); } default NetworkDirection getDirection() { diff --git a/src/main/java/net/minecraftforge/fml/network/NetworkDirection.java b/src/main/java/net/minecraftforge/fml/network/NetworkDirection.java index abfc760ac..bf55c7590 100644 --- a/src/main/java/net/minecraftforge/fml/network/NetworkDirection.java +++ b/src/main/java/net/minecraftforge/fml/network/NetworkDirection.java @@ -26,7 +26,9 @@ import net.minecraft.network.login.client.CPacketCustomPayloadLogin; import net.minecraft.network.login.server.SPacketCustomPayloadLogin; import net.minecraft.network.play.client.CPacketCustomPayload; import net.minecraft.network.play.server.SPacketCustomPayload; +import net.minecraft.util.ResourceLocation; import net.minecraftforge.fml.LogicalSide; +import net.minecraftforge.fml.UnsafeHacks; import java.util.function.BiFunction; import java.util.function.Function; @@ -36,14 +38,15 @@ import java.util.stream.Stream; public enum NetworkDirection { - PLAY_TO_SERVER(NetworkEvent.ClientCustomPayloadEvent::new, LogicalSide.CLIENT, CPacketCustomPayload.class), - PLAY_TO_CLIENT(NetworkEvent.ServerCustomPayloadEvent::new, LogicalSide.SERVER, SPacketCustomPayload.class), - LOGIN_TO_SERVER(NetworkEvent.ClientCustomPayloadEvent::new, LogicalSide.CLIENT, CPacketCustomPayloadLogin.class), - LOGIN_TO_CLIENT(NetworkEvent.ServerCustomPayloadEvent::new, LogicalSide.SERVER, SPacketCustomPayloadLogin.class); + PLAY_TO_SERVER(NetworkEvent.ClientCustomPayloadEvent::new, LogicalSide.CLIENT, CPacketCustomPayload.class, 1), + PLAY_TO_CLIENT(NetworkEvent.ServerCustomPayloadEvent::new, LogicalSide.SERVER, SPacketCustomPayload.class, 0), + LOGIN_TO_SERVER(NetworkEvent.ClientCustomPayloadLoginEvent::new, LogicalSide.CLIENT, CPacketCustomPayloadLogin.class, 3), + LOGIN_TO_CLIENT(NetworkEvent.ServerCustomPayloadLoginEvent::new, LogicalSide.SERVER, SPacketCustomPayloadLogin.class, 2); - private final BiFunction, NetworkEvent> eventSupplier; + private final BiFunction, Supplier, NetworkEvent> eventSupplier; private final LogicalSide logicalSide; private final Class packetClass; + private final int otherWay; private static final Reference2ReferenceArrayMap, NetworkDirection> packetLookup; @@ -52,11 +55,12 @@ public enum NetworkDirection collect(Collectors.toMap(NetworkDirection::getPacketClass, Function.identity(), (m1,m2)->m1, Reference2ReferenceArrayMap::new)); } - NetworkDirection(BiFunction, NetworkEvent> eventSupplier, LogicalSide logicalSide, Class clazz) + NetworkDirection(BiFunction, Supplier, NetworkEvent> eventSupplier, LogicalSide logicalSide, Class clazz, int i) { this.eventSupplier = eventSupplier; this.logicalSide = logicalSide; this.packetClass = clazz; + this.otherWay = i; } private Class getPacketClass() { @@ -67,7 +71,10 @@ public enum NetworkDirection return packetLookup.get(customPacket); } - public NetworkEvent getEvent(final PacketBuffer buffer, final Supplier manager) { + public NetworkDirection reply() { + return NetworkDirection.values()[this.otherWay]; + } + public NetworkEvent getEvent(final ICustomPacket buffer, final Supplier manager) { return this.eventSupplier.apply(buffer, manager); } @@ -75,4 +82,14 @@ public enum NetworkDirection { return logicalSide; } + + @SuppressWarnings("unchecked") + public > ICustomPacket buildPacket(PacketBuffer packetBuffer, ResourceLocation channelName, int index) + { + ICustomPacket packet = (ICustomPacket)UnsafeHacks.newInstance(getPacketClass()); + packet.setName(channelName); + packet.setData(packetBuffer); + packet.setIndex(index); + return packet; + } } diff --git a/src/main/java/net/minecraftforge/fml/network/NetworkEvent.java b/src/main/java/net/minecraftforge/fml/network/NetworkEvent.java index c452fa653..5c129be8f 100644 --- a/src/main/java/net/minecraftforge/fml/network/NetworkEvent.java +++ b/src/main/java/net/minecraftforge/fml/network/NetworkEvent.java @@ -20,9 +20,6 @@ package net.minecraftforge.fml.network; import com.google.common.util.concurrent.ListenableFuture; -import net.minecraft.client.network.NetHandlerPlayClient; -import net.minecraft.network.INetHandler; -import net.minecraft.network.NetHandlerPlayServer; import net.minecraft.network.NetworkManager; import net.minecraft.network.PacketBuffer; import net.minecraft.util.IThreadListener; @@ -35,10 +32,9 @@ public class NetworkEvent extends Event { private final PacketBuffer payload; private final Supplier source; - - private NetworkEvent(PacketBuffer payload, Supplier source) + private NetworkEvent(ICustomPacket payload, Supplier source) { - this.payload = payload; + this.payload = payload.getData(); this.source = source; } @@ -54,56 +50,92 @@ public class NetworkEvent extends Event public static class ServerCustomPayloadEvent extends NetworkEvent { - ServerCustomPayloadEvent(final PacketBuffer payload, final Supplier source) { + + ServerCustomPayloadEvent(final ICustomPacket payload, final Supplier source) { super(payload, source); } } public static class ClientCustomPayloadEvent extends NetworkEvent { - ClientCustomPayloadEvent(final PacketBuffer payload, final Supplier source) { + ClientCustomPayloadEvent(final ICustomPacket payload, final Supplier source) { super(payload, source); } } + public static class ServerCustomPayloadLoginEvent extends ServerCustomPayloadEvent implements ILoginIndex { + private final int index; + ServerCustomPayloadLoginEvent(ICustomPacket payload, Supplier source) + { + super(payload, source); + this.index = payload.getIndex(); + } + + public int getIndex() + { + return index; + } + } + + public static class ClientCustomPayloadLoginEvent extends ClientCustomPayloadEvent implements ILoginIndex { + private final int index; + + ClientCustomPayloadLoginEvent(ICustomPacket payload, Supplier source) + { + super(payload, source); + this.index = payload.getIndex(); + } + + public int getIndex() + { + return index; + } + } + + public interface ILoginIndex { + int getIndex(); + } /** * Context for {@link NetworkEvent} */ public static class Context { /** - * The {@link INetHandler} for this message. It could be a client or server handler, depending - * on the {@link #side} received. + * The {@link NetworkManager} for this message. */ - private final INetHandler netHandler; + private final NetworkManager networkManager; /** - * The {@link NetworkDirection} this message has been received on + * The {@link NetworkDirection} this message has been received on. */ private final NetworkDirection side; + private boolean packetHandled; Context(NetworkManager netHandler, NetworkDirection side) { - this.netHandler = netHandler.getNetHandler(); + this.networkManager = netHandler; this.side = side; } - public NetworkDirection getSide() { + public NetworkDirection getDirection() { return side; } - public NetHandlerPlayServer getServerHandler() - { - return (NetHandlerPlayServer) netHandler; + public NetworkManager getNetworkManager() { + return networkManager; } - public NetHandlerPlayClient getClientHandler() + public void setPacketHandled(boolean packetHandled) { + this.packetHandled = packetHandled; + } + + public boolean getPacketHandled() { - return (NetHandlerPlayClient) netHandler; + return packetHandled; } @SuppressWarnings("unchecked") public ListenableFuture enqueueWork(Runnable runnable) { - return (ListenableFuture)LogicalSidedProvider.WORKQUEUE.get(getSide().getLogicalSide()).addScheduledTask(runnable); + return (ListenableFuture)LogicalSidedProvider.WORKQUEUE.get(getDirection().getLogicalSide()).addScheduledTask(runnable); } } } diff --git a/src/main/java/net/minecraftforge/fml/network/NetworkHooks.java b/src/main/java/net/minecraftforge/fml/network/NetworkHooks.java index 7941be159..97b121fc3 100644 --- a/src/main/java/net/minecraftforge/fml/network/NetworkHooks.java +++ b/src/main/java/net/minecraftforge/fml/network/NetworkHooks.java @@ -20,10 +20,14 @@ package net.minecraftforge.fml.network; import net.minecraft.entity.Entity; +import net.minecraft.entity.player.EntityPlayerMP; import net.minecraft.network.NetHandlerPlayServer; import net.minecraft.network.NetworkManager; import net.minecraft.network.Packet; import net.minecraft.network.handshake.client.CPacketHandshake; +import net.minecraft.network.login.client.CPacketCustomPayloadLogin; +import net.minecraft.server.network.NetHandlerLoginServer; +import net.minecraft.util.ResourceLocation; import java.util.Objects; @@ -31,6 +35,7 @@ public class NetworkHooks { public static final String NETVERSION = "FML1"; public static final String NOVERSION = "NONE"; + static final ResourceLocation FMLHANDSHAKE = new ResourceLocation("fml", "handshake"); public static String getFMLVersion(final String ip) { return ip.contains("\0") ? Objects.equals(ip.split("\0")[1], NETVERSION) ? NETVERSION : ip.split("\0")[1] : NOVERSION; @@ -43,7 +48,7 @@ public class NetworkHooks public static ConnectionType getConnectionType(final NetHandlerPlayServer connection) { - return ConnectionType.forVersionFlag(connection.netManager.channel().attr(NetworkRegistry.FML_MARKER).get()); + return ConnectionType.forVersionFlag(connection.netManager.channel().attr(FMLNetworking.FML_MARKER).get()); } public static Packet getEntitySpawningPacket(Entity entity) @@ -51,15 +56,25 @@ public class NetworkHooks return null; } - public static void onCustomPayload(final ICustomPacket packet, final NetworkManager manager) { - NetworkRegistry.findTarget(packet.getName()). - ifPresent(ni->ni.dispatch(packet.getDirection(), packet.getData(), manager)); + public static boolean onCustomPayload(final ICustomPacket packet, final NetworkManager manager) { + return NetworkRegistry.findTarget(packet.getName()). + map(ni->ni.dispatch(packet.getDirection(), packet, manager)).orElse(Boolean.FALSE); } - public static void registerServerChannel(NetworkManager manager, CPacketHandshake packet) + public static void registerServerLoginChannel(NetworkManager manager, CPacketHandshake packet) { - manager.channel().attr(NetworkRegistry.FML_MARKER).set(packet.getFMLVersion()); + manager.channel().attr(FMLNetworking.FML_MARKER).set(packet.getFMLVersion()); + FMLNetworking.registerHandshake(manager, NetworkDirection.LOGIN_TO_CLIENT); } + public static void registerClientLoginChannel(NetworkManager manager) + { + manager.channel().attr(FMLNetworking.FML_MARKER).set(NETVERSION); + FMLNetworking.registerHandshake(manager, NetworkDirection.LOGIN_TO_SERVER); + } + public static boolean tickNegotiation(NetHandlerLoginServer netHandlerLoginServer, NetworkManager networkManager, EntityPlayerMP player) + { + return FMLNetworking.dispatch(networkManager); + } } diff --git a/src/main/java/net/minecraftforge/fml/network/NetworkInstance.java b/src/main/java/net/minecraftforge/fml/network/NetworkInstance.java index 70efcf124..f71cc23aa 100644 --- a/src/main/java/net/minecraftforge/fml/network/NetworkInstance.java +++ b/src/main/java/net/minecraftforge/fml/network/NetworkInstance.java @@ -70,9 +70,11 @@ public class NetworkInstance this.networkEventBus.unregister(object); } - void dispatch(final NetworkDirection side, final PacketBuffer bufferData, final NetworkManager manager) + boolean dispatch(final NetworkDirection side, final ICustomPacket packet, final NetworkManager manager) { - this.networkEventBus.post(side.getEvent(bufferData,()->new NetworkEvent.Context(manager, side))); + final NetworkEvent.Context context = new NetworkEvent.Context(manager, side); + this.networkEventBus.post(side.getEvent(packet, () -> context)); + return context.getPacketHandled(); } diff --git a/src/main/java/net/minecraftforge/fml/network/NetworkRegistry.java b/src/main/java/net/minecraftforge/fml/network/NetworkRegistry.java index 4fa6b7490..4629fba41 100644 --- a/src/main/java/net/minecraftforge/fml/network/NetworkRegistry.java +++ b/src/main/java/net/minecraftforge/fml/network/NetworkRegistry.java @@ -41,8 +41,6 @@ public class NetworkRegistry private static final Logger LOGGER = LogManager.getLogger(); private static final Marker NETREGISTRY = MarkerManager.getMarker("NETREGISTRY"); - public static final AttributeKey FML_MARKER = AttributeKey.valueOf("fml:versionMarker"); - private static Map instances = new HashMap<>(); public static List getNonVanillaNetworkMods() { diff --git a/src/main/java/net/minecraftforge/fml/network/simple/IndexedMessageCodec.java b/src/main/java/net/minecraftforge/fml/network/simple/IndexedMessageCodec.java index 1a08fb1a6..1a7854387 100644 --- a/src/main/java/net/minecraftforge/fml/network/simple/IndexedMessageCodec.java +++ b/src/main/java/net/minecraftforge/fml/network/simple/IndexedMessageCodec.java @@ -21,7 +21,9 @@ package net.minecraftforge.fml.network.simple; import it.unimi.dsi.fastutil.objects.Object2ObjectArrayMap; import it.unimi.dsi.fastutil.shorts.Short2ObjectArrayMap; +import net.minecraft.network.Packet; import net.minecraft.network.PacketBuffer; +import net.minecraftforge.fml.network.ICustomPacket; import net.minecraftforge.fml.network.NetworkEvent; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; @@ -30,6 +32,7 @@ import org.apache.logging.log4j.MarkerManager; import java.util.Optional; import java.util.function.BiConsumer; +import java.util.function.BiFunction; import java.util.function.Function; import java.util.function.Supplier; @@ -49,6 +52,8 @@ public class IndexedMessageCodec private final int index; private final BiConsumer> messageConsumer; private final Class messageType; + private Optional> loginIndexFunction; + public CodecIndex(int index, Class messageType, BiConsumer encoder, Function decoder, BiConsumer> messageConsumer) { this.index = index; @@ -56,23 +61,39 @@ public class IndexedMessageCodec this.encoder = Optional.ofNullable(encoder); this.decoder = Optional.ofNullable(decoder); this.messageConsumer = messageConsumer; + this.loginIndexFunction = Optional.empty(); indicies.put((short)(index & 0xff), this); types.put(messageType, this); } + public void setLoginIndexFunction(BiConsumer loginIndexFunction) + { + this.loginIndexFunction = Optional.of(loginIndexFunction); + } + public Optional> getLoginIndexFunction() { + return this.loginIndexFunction; + } } private static void tryDecode(PacketBuffer payload, Supplier context, CodecIndex codec) { codec.decoder.map(d->d.apply(payload)).ifPresent(m->codec.messageConsumer.accept(m, context)); } + private static void tryDecode(PacketBuffer payload, Supplier context, int payloadIndex, CodecIndex codec) + { + codec.decoder.map(d->d.apply(payload)). + map(p->{ codec.getLoginIndexFunction().ifPresent(f-> f.accept(p, payloadIndex)); return p; }). + ifPresent(m->codec.messageConsumer.accept(m, context)); + } + private static void tryEncode(PacketBuffer target, M message, CodecIndex codec) { codec.encoder.ifPresent(encoder->{ target.writeByte(codec.index & 0xff); encoder.accept(message, target); }); } + public void build(MSG message, PacketBuffer target) { @SuppressWarnings("unchecked") @@ -84,7 +105,26 @@ public class IndexedMessageCodec tryEncode(target, message, codecIndex); } - void consume(final PacketBuffer payload, Supplier context) { + void consume(PacketBuffer payload, int payloadIndex, Supplier context) { + if (payload == null) { + LOGGER.error(SIMPLENET, "Received empty payload"); + return; + } + short discriminator = payload.readUnsignedByte(); + final CodecIndex codecIndex = indicies.get(discriminator); + if (codecIndex == null) { + LOGGER.error(SIMPLENET, "Received invalid discriminator byte {}", discriminator); + return; + } + tryDecode(payload, context, payloadIndex, codecIndex); + } + + void consume(PacketBuffer payload, Supplier context) { + // no data in empty payload + if (payload == null) { + LOGGER.error(SIMPLENET, "Received empty payload"); + return; + } short discriminator = payload.readUnsignedByte(); final CodecIndex codecIndex = indicies.get(discriminator); if (codecIndex == null) { @@ -94,7 +134,7 @@ public class IndexedMessageCodec tryDecode(payload, context, codecIndex); } - void addCodecIndex(int index, Class messageType, BiConsumer encoder, Function decoder, BiConsumer> messageConsumer) { - new CodecIndex<>(index, messageType, encoder, decoder, messageConsumer); + CodecIndex addCodecIndex(int index, Class messageType, BiConsumer encoder, Function decoder, BiConsumer> messageConsumer) { + return new CodecIndex<>(index, messageType, encoder, decoder, messageConsumer); } } diff --git a/src/main/java/net/minecraftforge/fml/network/simple/SimpleChannel.java b/src/main/java/net/minecraftforge/fml/network/simple/SimpleChannel.java index 373d1408b..984e8b79f 100644 --- a/src/main/java/net/minecraftforge/fml/network/simple/SimpleChannel.java +++ b/src/main/java/net/minecraftforge/fml/network/simple/SimpleChannel.java @@ -21,13 +21,21 @@ package net.minecraftforge.fml.network.simple; import io.netty.buffer.Unpooled; import net.minecraft.client.Minecraft; +import net.minecraft.network.NetworkManager; +import net.minecraft.network.Packet; import net.minecraft.network.PacketBuffer; import net.minecraft.network.play.client.CPacketCustomPayload; +import net.minecraftforge.fml.network.ICustomPacket; +import net.minecraftforge.fml.network.NetworkDirection; import net.minecraftforge.fml.network.NetworkEvent; import net.minecraftforge.fml.network.NetworkInstance; import java.util.function.BiConsumer; +import java.util.function.BinaryOperator; import java.util.function.Function; +import java.util.function.IntBinaryOperator; +import java.util.function.IntConsumer; +import java.util.function.IntFunction; import java.util.function.Supplier; public class SimpleChannel @@ -44,24 +52,42 @@ public class SimpleChannel private void networkEventListener(final NetworkEvent networkEvent) { - this.indexedCodec.consume(networkEvent.getPayload(),networkEvent.getSource()); + if (networkEvent instanceof NetworkEvent.ILoginIndex) + { + this.indexedCodec.consume(networkEvent.getPayload(), ((NetworkEvent.ILoginIndex)networkEvent).getIndex(), networkEvent.getSource()); + } + else + { + this.indexedCodec.consume(networkEvent.getPayload(), networkEvent.getSource()); + } } public void encodeMessage(MSG message, final PacketBuffer target) { this.indexedCodec.build(message, target); } - public void registerMessage(int index, Class messageType, BiConsumer encoder, Function decoder, BiConsumer> messageConsumer) { - this.indexedCodec.addCodecIndex(index, messageType, encoder, decoder, messageConsumer); + public IndexedMessageCodec.CodecIndex registerMessage(int index, Class messageType, BiConsumer encoder, Function decoder, BiConsumer> messageConsumer) { + return this.indexedCodec.addCodecIndex(index, messageType, encoder, decoder, messageConsumer); } + private PacketBuffer toBuffer(MSG msg) { + final PacketBuffer bufIn = new PacketBuffer(Unpooled.buffer()); + encodeMessage(msg, bufIn); + return bufIn; + } public void sendToServer(MSG message) { - final PacketBuffer bufIn = new PacketBuffer(Unpooled.buffer()); - encodeMessage(message, bufIn); - final CPacketCustomPayload payload = new CPacketCustomPayload(instance.getChannelName(), bufIn); - Minecraft.getMinecraft().getConnection().sendPacket(payload); + sendTo(message, Minecraft.getMinecraft().getConnection().getNetworkManager(), NetworkDirection.PLAY_TO_SERVER); } + public void sendTo(MSG message, NetworkManager manager, NetworkDirection direction) { + ICustomPacket> payload = direction.buildPacket(toBuffer(message), instance.getChannelName(), -1); + manager.sendPacket(payload.getThis()); + } + + public void sendLogin(MSG message, NetworkManager manager, NetworkDirection direction, int packetIndex) { + ICustomPacket> payload = direction.buildPacket(toBuffer(message), instance.getChannelName(), packetIndex); + manager.sendPacket(payload.getThis()); + } public MessageBuilder messageBuilder(final Class type, int id) { return MessageBuilder.forType(this, type, id); } @@ -73,6 +99,7 @@ public class SimpleChannel private BiConsumer encoder; private Function decoder; private BiConsumer> consumer; + private BiConsumer loginIndexFunction; private static MessageBuilder forType(final SimpleChannel channel, final Class type, int id) { MessageBuilder builder = new MessageBuilder<>(); @@ -92,13 +119,20 @@ public class SimpleChannel return this; } + public MessageBuilder loginIndex(BiConsumer loginIndexFunction) { + this.loginIndexFunction = loginIndexFunction; + return this; + } public MessageBuilder consumer(BiConsumer> consumer) { this.consumer = consumer; return this; } public void add() { - this.channel.registerMessage(this.id, this.type, this.encoder, this.decoder, this.consumer); + final IndexedMessageCodec.CodecIndex message = this.channel.registerMessage(this.id, this.type, this.encoder, this.decoder, this.consumer); + if (this.loginIndexFunction != null) { + message.setLoginIndexFunction(this.loginIndexFunction); + } } } } diff --git a/src/main/java/net/minecraftforge/fml/server/ServerLifecycleHooks.java b/src/main/java/net/minecraftforge/fml/server/ServerLifecycleHooks.java index 0e1520b1b..fd7ab0452 100644 --- a/src/main/java/net/minecraftforge/fml/server/ServerLifecycleHooks.java +++ b/src/main/java/net/minecraftforge/fml/server/ServerLifecycleHooks.java @@ -119,7 +119,7 @@ public class ServerLifecycleHooks return false; } - NetworkHooks.registerServerChannel(manager, packet); + NetworkHooks.registerServerLoginChannel(manager, packet); return true; } diff --git a/src/main/java/net/minecraftforge/registries/GameData.java b/src/main/java/net/minecraftforge/registries/GameData.java index c616bf7dd..ccb08cd6e 100644 --- a/src/main/java/net/minecraftforge/registries/GameData.java +++ b/src/main/java/net/minecraftforge/registries/GameData.java @@ -50,12 +50,10 @@ import net.minecraftforge.event.RegistryEvent; import net.minecraftforge.event.RegistryEvent.MissingMappings; import net.minecraftforge.fml.common.EnhancedRuntimeException; import net.minecraftforge.fml.StartupQuery; -import net.minecraftforge.fml.common.registry.VillagerRegistry.VillagerProfession; import com.google.common.collect.ArrayListMultimap; import com.google.common.collect.BiMap; -import java.io.IOException; import java.lang.reflect.Field; import java.util.Collection; import java.util.Collections; diff --git a/src/main/java/net/minecraftforge/server/command/ForgeCommand.java b/src/main/java/net/minecraftforge/server/command/ForgeCommand.java index 95373f0a9..bcae49453 100644 --- a/src/main/java/net/minecraftforge/server/command/ForgeCommand.java +++ b/src/main/java/net/minecraftforge/server/command/ForgeCommand.java @@ -19,15 +19,20 @@ package net.minecraftforge.server.command; -import net.minecraft.command.ICommand; +import com.mojang.brigadier.CommandDispatcher; +import com.mojang.brigadier.builder.LiteralArgumentBuilder; +import net.minecraft.command.CommandSource; +import net.minecraft.util.text.TextComponentString; -import net.minecraft.command.ICommandSender; -import net.minecraft.server.MinecraftServer; - -public class ForgeCommand extends CommandTreeBase +public class ForgeCommand { - public ForgeCommand() + public ForgeCommand(CommandDispatcher dispatcher) { + dispatcher.register(LiteralArgumentBuilder.literal("forge"). + requires(cs->cs.func_197034_c(2)). + then(LiteralArgumentBuilder.literal("tps")). + executes(c->{c.getSource().func_197021_a(new TextComponentString("command.forge.tps.summary")); return 1;})); +/* super.addSubcommand(new CommandTps()); super.addSubcommand(new CommandTrack()); super.addSubcommand(new CommandGenerate()); @@ -35,35 +40,6 @@ public class ForgeCommand extends CommandTreeBase super.addSubcommand(new CommandSetDimension()); super.addSubcommand(new CommandDimensions()); super.addSubcommand(new CommandTreeHelp(this)); - } - - @Override - public String getName() - { - return "forge"; - } - - @Override - public void addSubcommand(ICommand command) - { - throw new UnsupportedOperationException("Don't add sub-commands to /forge, create your own command."); - } - - @Override - public int getRequiredPermissionLevel() - { - return 0; - } - - @Override - public boolean checkPermission(MinecraftServer server, ICommandSender sender) - { - return true; - } - - @Override - public String getUsage(ICommandSender icommandsender) - { - return "commands.forge.usage"; +*/ } } diff --git a/src/main/java/net/minecraftforge/server/command/TextComponentHelper.java b/src/main/java/net/minecraftforge/server/command/TextComponentHelper.java index 53bfb3924..e2e3688ff 100644 --- a/src/main/java/net/minecraftforge/server/command/TextComponentHelper.java +++ b/src/main/java/net/minecraftforge/server/command/TextComponentHelper.java @@ -19,15 +19,13 @@ package net.minecraftforge.server.command; -import io.netty.channel.Channel; -import net.minecraft.command.ICommandSender; +import net.minecraft.command.ICommandSource; import net.minecraft.entity.player.EntityPlayerMP; import net.minecraft.network.NetHandlerPlayServer; import net.minecraft.util.text.TextComponentBase; import net.minecraft.util.text.TextComponentString; import net.minecraft.util.text.TextComponentTranslation; -import net.minecraft.util.text.translation.I18n; -import net.minecraftforge.fml.common.network.NetworkRegistry; +import net.minecraft.util.text.translation.LanguageMap; import net.minecraftforge.fml.network.ConnectionType; import net.minecraftforge.fml.network.NetworkHooks; @@ -39,11 +37,11 @@ public class TextComponentHelper * Detects when sending to a vanilla client and falls back to sending english, * since they don't have the lang data necessary to translate on the client. */ - public static TextComponentBase createComponentTranslation(ICommandSender sender, final String translation, final Object... args) + public static TextComponentBase createComponentTranslation(ICommandSource source, final String translation, final Object... args) { - if (isVanillaClient(sender)) + if (isVanillaClient(source)) { - return new TextComponentString(I18n.translateToLocalFormatted(translation, args)); + return new TextComponentString(LanguageMap.getInstance().translateKey(translation, args)); } return new TextComponentTranslation(translation, args); }