From 7a08098b03749305830b8117f30f11d9e41cbc88 Mon Sep 17 00:00:00 2001 From: Matthew Miller Date: Sat, 15 Dec 2018 22:13:13 +1000 Subject: [PATCH] Further work on Forge 1.13 compat. --- worldedit-forge/build.gradle | 32 ++++++------ .../worldedit/forge/ForgeBlockMaterial.java | 6 +-- .../forge/ForgeEntityProperties.java | 2 +- .../sk89q/worldedit/forge/ForgeWorldEdit.java | 46 ++++++++++-------- .../forge/InternalPacketHandler.java | 11 +++-- .../com/sk89q/worldedit/forge/KeyHandler.java | 4 +- .../worldedit/forge/ThreadSafeCache.java | 3 +- .../worldedit/forge/TileEntityUtils.java | 6 +-- .../worldedit/forge/WECUIPacketHandler.java | 2 +- .../src/main/resources/META-INF/mods.toml | 30 ++++++++++++ worldedit-forge/src/main/resources/mcmod.info | 21 -------- .../src/main/resources/worldedit-icon.png | Bin 0 -> 5636 bytes 12 files changed, 89 insertions(+), 74 deletions(-) create mode 100644 worldedit-forge/src/main/resources/META-INF/mods.toml delete mode 100644 worldedit-forge/src/main/resources/mcmod.info create mode 100644 worldedit-forge/src/main/resources/worldedit-icon.png diff --git a/worldedit-forge/build.gradle b/worldedit-forge/build.gradle index 229f4447b..3885ff369 100644 --- a/worldedit-forge/build.gradle +++ b/worldedit-forge/build.gradle @@ -2,7 +2,7 @@ buildscript { repositories { mavenLocal() mavenCentral() - maven { url = "http://files.minecraftforge.net/maven" } + maven { url = "https://files.minecraftforge.net/maven" } jcenter() } @@ -14,7 +14,7 @@ buildscript { apply plugin: 'net.minecraftforge.gradle' def minecraftVersion = "1.13" -def forgeVersion = "24.0.16-1.13-pre" +def forgeVersion = "24.0.32-1.13-pre" dependencies { compile project(':worldedit-core') @@ -28,26 +28,28 @@ sourceCompatibility = 1.8 targetCompatibility = 1.8 minecraft { - mappings channel: 'snapshot', version: '20181215' -// runDir = 'run' - -// replaceIn "com/sk89q/worldedit/forge/ForgeWorldEdit.java" -// replace "%VERSION%", project.version + mappings channel: 'snapshot', version: '20180921-1.13' } project.archivesBaseName = "${project.archivesBaseName}-mc${minecraftVersion}" processResources { - from (sourceSets.main.resources.srcDirs) { - expand 'version': project.version, - 'mcVersion': minecraftVersion, - 'forgeVersion': forgeVersion, - 'internalVersion': project.internalVersion - include 'mcmod.info' + // this will ensure that this task is redone when the versions change. + inputs.property 'version', project.version + inputs.property 'mcversion', minecraftVersion + inputs.property 'internalVersion', internalVersion + + // replace stuff in mcmod.info, nothing else + from(sourceSets.main.resources.srcDirs) { + include 'META_INF/mods.toml' + + // replace version and mcversion + expand 'version':project.version, 'mcversion': minecraftVersion, 'internalVersion': internalVersion } - from (sourceSets.main.resources.srcDirs) { - exclude 'mcmod.info' + // copy everything else except the mcmod.info + from(sourceSets.main.resources.srcDirs) { + exclude 'META_INF/mods.toml' } } diff --git a/worldedit-forge/src/main/java/com/sk89q/worldedit/forge/ForgeBlockMaterial.java b/worldedit-forge/src/main/java/com/sk89q/worldedit/forge/ForgeBlockMaterial.java index 9d98f39ef..5f15a683b 100644 --- a/worldedit-forge/src/main/java/com/sk89q/worldedit/forge/ForgeBlockMaterial.java +++ b/worldedit-forge/src/main/java/com/sk89q/worldedit/forge/ForgeBlockMaterial.java @@ -63,12 +63,12 @@ public class ForgeBlockMaterial extends PassthroughBlockMaterial { @Override public boolean isFragileWhenPushed() { - return delegate.getMobilityFlag() == EnumPushReaction.DESTROY; + return delegate.getPushReaction() == EnumPushReaction.DESTROY; } @Override public boolean isUnpushable() { - return delegate.getMobilityFlag() == EnumPushReaction.BLOCK; + return delegate.getPushReaction() == EnumPushReaction.BLOCK; } @Override @@ -78,7 +78,7 @@ public class ForgeBlockMaterial extends PassthroughBlockMaterial { @Override public boolean isBurnable() { - return delegate.getCanBurn(); + return delegate.isFlammable(); } @Override diff --git a/worldedit-forge/src/main/java/com/sk89q/worldedit/forge/ForgeEntityProperties.java b/worldedit-forge/src/main/java/com/sk89q/worldedit/forge/ForgeEntityProperties.java index bf6a16ae2..6e07e18ad 100644 --- a/worldedit-forge/src/main/java/com/sk89q/worldedit/forge/ForgeEntityProperties.java +++ b/worldedit-forge/src/main/java/com/sk89q/worldedit/forge/ForgeEntityProperties.java @@ -136,7 +136,7 @@ public class ForgeEntityProperties implements EntityProperties { @Override public boolean isTagged() { - return entity instanceof EntityLiving && ((EntityLiving) entity).hasCustomName(); + return entity.hasCustomName(); } @Override diff --git a/worldedit-forge/src/main/java/com/sk89q/worldedit/forge/ForgeWorldEdit.java b/worldedit-forge/src/main/java/com/sk89q/worldedit/forge/ForgeWorldEdit.java index 5a5a217ad..9d182c32e 100644 --- a/worldedit-forge/src/main/java/com/sk89q/worldedit/forge/ForgeWorldEdit.java +++ b/worldedit-forge/src/main/java/com/sk89q/worldedit/forge/ForgeWorldEdit.java @@ -44,10 +44,10 @@ import net.minecraftforge.common.MinecraftForge; import net.minecraftforge.event.CommandEvent; import net.minecraftforge.event.entity.player.PlayerInteractEvent; import net.minecraftforge.event.entity.player.PlayerInteractEvent.LeftClickEmpty; +import net.minecraftforge.eventbus.api.Event; +import net.minecraftforge.eventbus.api.SubscribeEvent; import net.minecraftforge.fml.common.Loader; import net.minecraftforge.fml.common.Mod; -import net.minecraftforge.fml.common.Mod.EventHandler; -import net.minecraftforge.fml.common.Mod.Instance; import net.minecraftforge.fml.common.SidedProxy; import net.minecraftforge.fml.common.event.FMLInitializationEvent; import net.minecraftforge.fml.common.event.FMLPostInitializationEvent; @@ -56,7 +56,8 @@ import net.minecraftforge.fml.common.event.FMLServerAboutToStartEvent; import net.minecraftforge.fml.common.event.FMLServerStartedEvent; import net.minecraftforge.fml.common.event.FMLServerStoppingEvent; import net.minecraftforge.fml.common.eventhandler.Event.Result; -import net.minecraftforge.fml.common.eventhandler.SubscribeEvent; +import net.minecraftforge.fml.javafmlmod.FMLModLoadingContext; +import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import java.io.File; @@ -64,16 +65,15 @@ import java.io.File; /** * The Forge implementation of WorldEdit. */ -@Mod(modid = ForgeWorldEdit.MOD_ID, name = "WorldEdit", version = "%VERSION%", acceptableRemoteVersions = "*") +@Mod(ForgeWorldEdit.MOD_ID) public class ForgeWorldEdit { - public static Logger logger; + private static final Logger LOGGER = LogManager.getLogger(); public static final String MOD_ID = "worldedit"; public static final String CUI_PLUGIN_CHANNEL = "worldedit:cui"; private ForgePermissionsProvider provider; - @Instance(MOD_ID) public static ForgeWorldEdit inst; @SidedProxy(serverSide = "com.sk89q.worldedit.forge.CommonProxy", clientSide = "com.sk89q.worldedit.forge.ClientProxy") @@ -83,36 +83,42 @@ public class ForgeWorldEdit { private ForgeConfiguration config; private File workingDir; - @EventHandler + public ForgeWorldEdit() { + inst = this; + + FMLModLoadingContext.get().getModEventBus().addListener(this::preInit); + FMLModLoadingContext.get().getModEventBus().addListener(this::init); + FMLModLoadingContext.get().getModEventBus().addListener(this::postInit); + FMLModLoadingContext.get().getModEventBus().addListener(this::serverAboutToStart); + FMLModLoadingContext.get().getModEventBus().addListener(this::serverStopping); + FMLModLoadingContext.get().getModEventBus().addListener(this::serverStarted); + + MinecraftForge.EVENT_BUS.register(ThreadSafeCache.getInstance()); + MinecraftForge.EVENT_BUS.register(this); + } + public void preInit(FMLPreInitializationEvent event) { - logger = event.getModLog(); // Setup working directory workingDir = new File(event.getModConfigurationDirectory() + File.separator + "worldedit"); workingDir.mkdir(); config = new ForgeConfiguration(this); config.load(); - - MinecraftForge.EVENT_BUS.register(ThreadSafeCache.getInstance()); } - @EventHandler public void init(FMLInitializationEvent event) { - MinecraftForge.EVENT_BUS.register(this); WECUIPacketHandler.init(); InternalPacketHandler.init(); proxy.registerHandlers(); } - @EventHandler public void postInit(FMLPostInitializationEvent event) { - logger.info("WorldEdit for Forge (version " + getInternalVersion() + ") is loaded"); + LOGGER.info("WorldEdit for Forge (version " + getInternalVersion() + ") is loaded"); } - @EventHandler public void serverAboutToStart(FMLServerAboutToStartEvent event) { if (this.platform != null) { - logger.warn("FMLServerStartingEvent occurred when FMLServerStoppingEvent hasn't"); + LOGGER.warn("FMLServerStartingEvent occurred when FMLServerStoppingEvent hasn't"); WorldEdit.getInstance().getPlatformManager().unregister(platform); } @@ -141,14 +147,12 @@ public class ForgeWorldEdit { } } - @EventHandler public void serverStopping(FMLServerStoppingEvent event) { WorldEdit worldEdit = WorldEdit.getInstance(); worldEdit.getSessionManager().unload(); worldEdit.getPlatformManager().unregister(platform); } - @EventHandler public void serverStarted(FMLServerStartedEvent event) { WorldEdit.getInstance().getEventBus().post(new PlatformReadyEvent()); } @@ -183,11 +187,11 @@ public class ForgeWorldEdit { boolean isLeftDeny = event instanceof PlayerInteractEvent.LeftClickBlock && ((PlayerInteractEvent.LeftClickBlock) event) - .getUseItem() == Result.DENY; + .getUseItem() == Event.Result.DENY; boolean isRightDeny = event instanceof PlayerInteractEvent.RightClickBlock && ((PlayerInteractEvent.RightClickBlock) event) - .getUseItem() == Result.DENY; + .getUseItem() == Event.Result.DENY; if (isLeftDeny || isRightDeny || event.getEntity().world.isRemote) { return; } @@ -233,7 +237,7 @@ public class ForgeWorldEdit { if (item.getNbtData() != null) { forgeCompound = NBTConverter.toNative(item.getNbtData()); } - return new ItemStack(Item.getByNameOrId(item.getType().getId()), item.getAmount(), 0, forgeCompound); + return new ItemStack(Item.REGISTRY.get(new ResourceLocation(item.getType().getId())), item.getAmount(), 0, forgeCompound); } /** diff --git a/worldedit-forge/src/main/java/com/sk89q/worldedit/forge/InternalPacketHandler.java b/worldedit-forge/src/main/java/com/sk89q/worldedit/forge/InternalPacketHandler.java index afac351ac..c81062121 100644 --- a/worldedit-forge/src/main/java/com/sk89q/worldedit/forge/InternalPacketHandler.java +++ b/worldedit-forge/src/main/java/com/sk89q/worldedit/forge/InternalPacketHandler.java @@ -20,18 +20,19 @@ package com.sk89q.worldedit.forge; import com.sk89q.worldedit.forge.net.LeftClickAirEventMessage; -import net.minecraftforge.fml.common.network.NetworkRegistry; -import net.minecraftforge.fml.common.network.simpleimpl.SimpleNetworkWrapper; -import net.minecraftforge.fml.relauncher.Side; +import javafx.geometry.Side; +import net.minecraft.util.ResourceLocation; +import net.minecraftforge.fml.network.NetworkRegistry; +import net.minecraftforge.fml.network.simple.SimpleChannel; import java.nio.charset.Charset; public class InternalPacketHandler { public static final Charset UTF_8_CHARSET = Charset.forName("UTF-8"); - public static SimpleNetworkWrapper CHANNEL; + public static SimpleChannel CHANNEL; public static void init() { - CHANNEL = NetworkRegistry.INSTANCE.newSimpleChannel(ForgeWorldEdit.MOD_ID); + CHANNEL = NetworkRegistry.newSimpleChannel(new ResourceLocation(ForgeWorldEdit.MOD_ID, "worldedit"), () -> "1", check -> true, check -> true); CHANNEL.registerMessage(LeftClickAirEventMessage.Handler.class, LeftClickAirEventMessage.class, 0, Side.SERVER); } diff --git a/worldedit-forge/src/main/java/com/sk89q/worldedit/forge/KeyHandler.java b/worldedit-forge/src/main/java/com/sk89q/worldedit/forge/KeyHandler.java index 76e726884..1395beb87 100644 --- a/worldedit-forge/src/main/java/com/sk89q/worldedit/forge/KeyHandler.java +++ b/worldedit-forge/src/main/java/com/sk89q/worldedit/forge/KeyHandler.java @@ -22,14 +22,14 @@ package com.sk89q.worldedit.forge; import com.sk89q.worldedit.forge.gui.GuiHandler; import net.minecraft.client.Minecraft; import net.minecraft.client.settings.KeyBinding; +import net.minecraftforge.eventbus.api.SubscribeEvent; import net.minecraftforge.fml.client.registry.ClientRegistry; -import net.minecraftforge.fml.common.eventhandler.SubscribeEvent; import net.minecraftforge.fml.common.gameevent.InputEvent.KeyInputEvent; import org.lwjgl.input.Keyboard; public class KeyHandler { - private static Minecraft mc = Minecraft.getMinecraft(); + private static Minecraft mc = Minecraft.getInstance(); private static KeyBinding mainKey = new KeyBinding("WorldEdit Reference", Keyboard.KEY_L, "WorldEdit"); public KeyHandler() { diff --git a/worldedit-forge/src/main/java/com/sk89q/worldedit/forge/ThreadSafeCache.java b/worldedit-forge/src/main/java/com/sk89q/worldedit/forge/ThreadSafeCache.java index a52233564..91fdc3fcd 100644 --- a/worldedit-forge/src/main/java/com/sk89q/worldedit/forge/ThreadSafeCache.java +++ b/worldedit-forge/src/main/java/com/sk89q/worldedit/forge/ThreadSafeCache.java @@ -21,8 +21,7 @@ package com.sk89q.worldedit.forge; import net.minecraft.entity.player.EntityPlayerMP; import net.minecraft.server.MinecraftServer; -import net.minecraftforge.fml.common.FMLCommonHandler; -import net.minecraftforge.fml.common.eventhandler.SubscribeEvent; +import net.minecraftforge.eventbus.api.SubscribeEvent; import net.minecraftforge.fml.common.gameevent.TickEvent; import java.util.Collections; diff --git a/worldedit-forge/src/main/java/com/sk89q/worldedit/forge/TileEntityUtils.java b/worldedit-forge/src/main/java/com/sk89q/worldedit/forge/TileEntityUtils.java index 4147d835c..8a65feaf4 100644 --- a/worldedit-forge/src/main/java/com/sk89q/worldedit/forge/TileEntityUtils.java +++ b/worldedit-forge/src/main/java/com/sk89q/worldedit/forge/TileEntityUtils.java @@ -81,7 +81,7 @@ final class TileEntityUtils { if (tag != null) { // Set X, Y, Z updateForSet(tag, position); - tileEntity.readFromNBT(tag); + tileEntity.read(tag); } world.setTileEntity(new BlockPos(position.getBlockX(), position.getBlockY(), position.getBlockZ()), tileEntity); @@ -98,7 +98,7 @@ final class TileEntityUtils { static void setTileEntity(World world, BlockVector3 position, @Nullable NBTTagCompound tag) { if (tag != null) { updateForSet(tag, position); - TileEntity tileEntity = TileEntity.create(world, tag); + TileEntity tileEntity = TileEntity.create(tag); if (tileEntity != null) { world.setTileEntity(new BlockPos(position.getBlockX(), position.getBlockY(), position.getBlockZ()), tileEntity); } @@ -143,7 +143,7 @@ final class TileEntityUtils { public static NBTTagCompound copyNbtData(TileEntity tile) { NBTTagCompound tag = new NBTTagCompound(); - tile.writeToNBT(tag); + tile.write(tag); return tag; } } diff --git a/worldedit-forge/src/main/java/com/sk89q/worldedit/forge/WECUIPacketHandler.java b/worldedit-forge/src/main/java/com/sk89q/worldedit/forge/WECUIPacketHandler.java index c6cf673e4..276eadcc6 100644 --- a/worldedit-forge/src/main/java/com/sk89q/worldedit/forge/WECUIPacketHandler.java +++ b/worldedit-forge/src/main/java/com/sk89q/worldedit/forge/WECUIPacketHandler.java @@ -25,7 +25,7 @@ import net.minecraft.network.NetHandlerPlayServer; import net.minecraft.network.PacketBuffer; import net.minecraft.network.ThreadQuickExitException; import net.minecraft.network.play.server.SPacketCustomPayload; -import net.minecraftforge.fml.common.eventhandler.SubscribeEvent; +import net.minecraftforge.eventbus.api.SubscribeEvent; import net.minecraftforge.fml.common.network.FMLEventChannel; import net.minecraftforge.fml.common.network.FMLNetworkEvent.ClientCustomPacketEvent; import net.minecraftforge.fml.common.network.FMLNetworkEvent.ServerCustomPacketEvent; diff --git a/worldedit-forge/src/main/resources/META-INF/mods.toml b/worldedit-forge/src/main/resources/META-INF/mods.toml new file mode 100644 index 000000000..7a8a52407 --- /dev/null +++ b/worldedit-forge/src/main/resources/META-INF/mods.toml @@ -0,0 +1,30 @@ +# The name of the mod loader type to load - for regular FML @Mod mods it should be javafml +modLoader="javafml" +# A version range to match for said mod loader - for regular FML @Mod it will be the minecraft version (without the 1.) +loaderVersion="[13,)" +# A URL to refer people to when problems occur with this mod +issueTrackerURL="https://discord.gg/YKbmj7V" +# A URL for the "homepage" for this mod, displayed in the mod UI +displayURL="http://wiki.sk89q.com/wiki/WorldEdit/" +# A file name (in the root of the mod JAR) containing a logo for display +logoFile="worldedit-icon.png" +# A text field displayed in the mod UI +authors="sk89q, wizjany, TomyLobo, kenzierocks, Me4502" +# A list of mods - how many allowed here is determined by the individual mod loader +[[worldedit]] +# The modid of the mod +modId="worldedit" +# The version number of the mod - there's a few well known ${} variables useable here or just hardcode it +version="${internalVersion}" + # A display name for the mod +displayName="WorldEdit" +# The description text for the mod (multi line!) +description=''' +WorldEdit is an easy-to-use in-game world editor for Minecraft, supporting both single player and multiplayer. +''' +[[dependencies.sponge]] + modId="sponge" + mandatory=false + versionRange="[1.13]" + ordering="NONE" + side="BOTH" \ No newline at end of file diff --git a/worldedit-forge/src/main/resources/mcmod.info b/worldedit-forge/src/main/resources/mcmod.info deleted file mode 100644 index bcee1cd4a..000000000 --- a/worldedit-forge/src/main/resources/mcmod.info +++ /dev/null @@ -1,21 +0,0 @@ -[{ - "modid": "worldedit", - "name": "WorldEdit", - "description": "WorldEdit is an easy-to-use in-game world editor for Minecraft, supporting both single player and multiplayer.", - "version": "${internalVersion}", - "mcversion": "${mcVersion}", - "url": "http://wiki.sk89q.com/wiki/WorldEdit", - "updateUrl": "", - "authors": [ "sk89q", "wizjany", "TomyLobo", "kenzierocks", "Me4502" ], - "credits": "", - "logoFile": "", - "screenshots": [], - "requiredMods": [ - "Forge@[${forgeVersion},)" - ], - "dependencies": [ - "Forge@[${forgeVersion},)", - "sponge" - ], - "dependants": [] -}] diff --git a/worldedit-forge/src/main/resources/worldedit-icon.png b/worldedit-forge/src/main/resources/worldedit-icon.png new file mode 100644 index 0000000000000000000000000000000000000000..dc269dcf7b17ffb3d5b4ba950c2dda74a3b5c26b GIT binary patch literal 5636 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�v@D{EVq36fj3OY$AQ03_h`Fl*CG)v2XGC^PGR=7O z{$l^i#c2V&AD3yLVqie&B=8xu%U4jf+165lxYgek4iT(jrc#V-Ck8NxjE#~Ra0MX1 zNxCHW_h2+9hq0tdHwv;w#PNt^ZV|vRQ@aibo3H!*qYnjup;TwWRW^mhIWp8iXK-!S zr%Wgmzz9Jm7~vT3U~KncaMy^rQz}qYGZ+RijNJr;p(sV;a;{o79GFT408r!M>~DY+ ztHlp&8bF1n!c-Fw){Hgz{uPUx1+w{!ZCaqHrW1hSGj=BsHedg#04DUiYQ8mbZ<+o6 zoFP-!sr?Tg+kWn)#r}Jjr9iqUfhPy3okubtW`#3#*k|45<48O9^`4fd~G>cI#X z%`nV?nTKJlw>aqAvpYGo+tyWXbKB`L&M0|&0Z(=gh_XJFt!4~8c$MHZ#?yYR;ZJ) z{g?OU`|nxOtQ~j+hN&G~Xad85*9Q=mwVt$jvJx6(%KGUL zhEcB@nBC*arTii5Q8;bhd+W6s)`colTNeL}6NL@13FZ<{HfcDSdIch~?F7;lp`K>M z2nbU%z}F1+84a^5>4TnZ^W;%an(IyqG zVi?@jA`FeecwfU0u>=Nnx24+fm-OI=OWseq4$Y_fD6r z)qf94wXN5cYY8BWm3n-+DVtfu#tax*Zzur6Cd~w3!XTX}WS{Zz`j)ngC4P&DC-ge* zZxmshz;KHv`ciRq6$=rQR2ruOhCmF5L4=kEn3cYd?H5a?1wPZBvc5||vQlatjn!8e z5`ksm^(DN~i_ky?#uXqd`;3nv5SEM(k7sS`Tt%Ri5u6cF1O~)zgkx%xF|DrH=fyr_ z^vj949DFYjpx@vfWWoh6g9z=n7#$cBPO5NK&zu18ZmB+ulMSEovD6R~%Br-5rzn5{ z#SL-Bwy(7f);Ps59yVZ%0x|qWClP&1DGy4}RTBA9Vyc3Lp;cN+2L4!X#k6;hnyktR z$?r*mhlxn=GA`7oyyg+BG(Z3a*W5b=l(5n_sv#^E!XpCU0tKK{c=@mv3SApJS#t`6 zwWGwstn`g)NMa~>msGS(0o@M-%{mhpPC{xFrimhB2{KXbmA+9REWc0$IYM|0h%!D7 zp*tQcG&{3)7;F02OpO8=nXDHCXG?&GfCz(}3O8nB$ekOSQ40ECC&Cy70s?U@5lxT) zw~-HpgFt@H5f~cIdR}^Lj!~yRGAMTdz-$RXQZJ(PMS+&!nmgis7&|}C7}XFK1h`EA ze54etM4;x-N-hnD09+!vLkRpa01PsKQ6RfSY{Ulz!gGU)W-EXbkl+A~WTS7Qi0F13 e@il_R8-E89rZjGhc4GJd0000