Skip to content
View in the app

A better way to browse. Learn more.

Forge Forums

A full-screen app on your home screen with push notifications, badges and more.

To install this app on iOS and iPadOS
  1. Tap the Share icon in Safari
  2. Scroll the menu and tap Add to Home Screen.
  3. Tap Add in the top-right corner.
To install this app on Android
  1. Tap the 3-dot menu (⋮) in the top-right corner of the browser.
  2. Tap Add to Home screen or Install app.
  3. Confirm by tapping Install.

libarclite

Members
  • Joined

  • Last visited

Posts posted by libarclite

  1. Thanks, that worked. Here's what I ended up doing:

     

                    if (tileEntity != null && tileEntity instanceof IInventory) {

                        IInventory inventory = (IInventory)tileEntity;

                        int count = inventory.getSizeInventory();

                        for (int i = 0; i < count; ++i) {

                            ItemStack itemStack = inventory.getStackInSlot(i);

                            if (itemStack != null) {

                                inventory.decrStackSize(i, itemStack.stackSize);

                            }

                        }

                    }

     

    I do this AFTER serializing all the TileEntity objects I find, but before destroying the objects containing them.

  2. I've implemented a command in my mod that lets the user move all of the blocks in a selected volume (represented as a cuboid). If the volume contains a chest, I correctly save the chests contents, but when the chest is moved, the contents spill out into the world (as if the user had destroyed the chest), and the chest is moved and still has its contents.

     

    I'm wondering if there's a way to inhibit the contents spilling behavior. My mod currently runs in 1.5.2, 1.6.4, and 1.7.2 (hooray for git cherry-pick). I'm primarily looking for a solution for 1.7.2, but anything that works across all versions would be great too.

  3. I started dabbling with mods in 1.6.4, ported my mods (a couple of server commands) to 1.7.2, and recently got interested in making my commands work in 1.5.2 to have them in Hexxit. My mods are simple enough to make the port from 1.6.4 pretty fast. Here's what I had to do.

     

    1. In my mod main class, I had to change @EventHandler annotations to:

     

    @PreInit

    public void load(FMLInitializationEvent event) {}

     

    @PostInit

    public void postInit(FMLPostInitializationEvent event) {}

     

    @ServerStarting

    public void serverLoad(FMLServerStartingEvent event) {}

     

    2. In my commands I had to change all calls of ICommandSender.getEntityWorld() to Entity.worldObj (after suitable casting).

     

    3. I also had to change the type I pass to ICommandSender.sendChatToPlayer() from ChatMessageComponent to String.

     

    4. In my custom block, I had to remove calls to Block.setTextureName() which didn't exist in 1.5.2.

     

    5. In my custom block's override of onBlockPlacedBy(), the type of the player parameter changed from EntityLivingBase to EntityLiving.

     

    Lastly, my mod uses the GSON code that is bundled with MinecraftForge for 1.6.4 and later. So, I had to explicitly include the contents of that jar file in my mod's jar file. Is there a better way to handle dependencies like this? I would prefer sticking to JDK-classes if possible, but I don't believe Sun's JSON support is bundled by default in the 1.6 JDK, which I am targeting.

  4. My advice would be to first build a mod for 1.6.4, since the tutorials exist, and the code will be much easier for you to understand. Once you get it working to your satisfaction, then try porting to 1.7.2. Many names have changed, even class names, so it really will be a port. Another piece of advice, use git and maintain your versions in branches.

     

    I've been playing a lot with the Technic launcher and specifically Hexxit, and am now considering backporting my mods to 1.5.2 because they will be so useful in the Hexxit mod collection.

  5. Thanks for writing this tutorial. That's a lot of boilerplate to understand. One conceptual question I have is about thread-safety. Is it safe to call

     

        public void sendToAll(AbstractPacket message) {

            this.channels.get(Side.SERVER).attr(FMLOutboundHandler.FML_MESSAGETARGET).set(FMLOutboundHandler.OutboundTarget.ALL);

            this.channels.get(Side.SERVER).writeAndFlush(message);

        }

     

    from multiple threads? I assume this.channels.get(Side.SERVER).attr() is returning an object, whose value affects the behavior of writeAndFlush().

  6. Not that difficult to find

    [embed=425,349]

    FMLEventChannel event = NetworkRegistry.INSTANCE.newEventDrivenChannel("YourChannelName");

    event.register(new YourPacketHandler());

    [/embed]

    Then in your packet handler you have two functions

     

    [embed=425,349]

    @SubscribeEvent

    public void onServerPacket(ServerCustomPacketEvent event) {

     

    }

    @SubscribeEvent

    public void onClientPacket(ClientCustomPacketEvent event) {

     

    }

    [/embed]

     

    How does one send the packet then? In my code above, I'm writing:

     

            ByteBuf data = buffer(4);

            data.writeInt(42);

            C17PacketCustomPayload packet = new C17PacketCustomPayload("NetworkExample", data);

            EntityClientPlayerMP player = (EntityClientPlayerMP)updateEvent.entityLiving;

            player.sendQueue.func_147297_a(packet);

     

    Would I just change the packet class to ServerCustomPacketEvent when sending from client to server?

  7. I have written a couple of mods that do pretty much what you're asking (both teleportation and volume manipulation). However, the approach I'm taking is more like 3D copy & paste. But others have pointed out that I'm doing both character and matter teleportation in a sense. I also provide a way to archive an arbitrary volume as a JSON file that you can reload later, perhaps into another world.

     

    My approach to copying is to define a boundary cuboid, and copy all of the blocks I find in that cuboid into an internal representation. I use JSON serialization to save, and deserialization to load. To save the contents of chests, etc. you have to serialize the contents of TileEntity objects. Generalizing to a sphere is certainly doable, but a cuboid is usually good enough.

  8. That would be very usefull, i've tried to send a packet but i need to tell the server which player sent it and with the example above you can just send a packet and i don't know how to execute it in the server .

    In 1.6.4 i had done a complete network handling as showed in the forge tutorials and it worked perfectly, but i don't know how to do the same with netty.

     

    Here's how I identify the player on the client side:

     

        @SubscribeEvent(priority = EventPriority.NORMAL)

        public void onEntityUpdated(LivingEvent.LivingUpdateEvent updateEvent) {

            EntityClientPlayerMP player = (EntityClientPlayerMP)updateEvent.entityLiving;

            ByteBuf data = buffer(4);

            data.writeInt(player.func_145782_y());  // Entity.getEntityID()

            data.writeInt(42);

            C17PacketCustomPayload packet = new C17PacketCustomPayload("NetworkExample", data);

            player.sendQueue.func_147297_a(packet);

        }

     

    On the server side I simply use that entity ID to look up something in a hash table to do the player matching.

  9. Looking further at the core commands (e.g. /help), it looks like each line has to be a sent as a separate call to ICommandSender.func_145747_a() (e.g. ICommandSender.sendChatToPlayer()). So, I simply wrote a line-breaking routine that my code calls to send chat messages:

     

    public static void sendMessageToPlayer(EntityPlayer player, String message) {

        ArrayIterator<String> lines = new ArrayIterator<String>(message.split("\n"));

        while (lines.hasNext())

            player.func_145747_a(new ChatComponentText(lines.next()));

    }

     

  10. Just today, I started to see the following exceptions being thrown while running gradle setupForge:

     

    java.lang.IllegalArgumentException: object is not an instance of declaring class

    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)

    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)

    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)

    at java.lang.reflect.Method.invoke(Method.java:606)

    at net.minecraftforge.gradle.tasks.abstractutil.CachedTask$Annotated.getValue(CachedTask.java:281)

    at net.minecraftforge.gradle.tasks.abstractutil.CachedTask$1.getFile(CachedTask.java:137)

    at net.minecraftforge.gradle.tasks.abstractutil.CachedTask$1.call(CachedTask.java:92)

    at net.minecraftforge.gradle.tasks.abstractutil.CachedTask$1.call(CachedTask.java:72)

    at groovy.lang.Closure.call(Closure.java:425)

    at org.gradle.api.specs.internal.ClosureSpec.isSatisfiedBy(ClosureSpec.java:32)

    at org.gradle.api.specs.AndSpec.isSatisfiedBy(AndSpec.java:42)

    at org.gradle.api.internal.tasks.execution.SkipOnlyIfTaskExecuter.execute(SkipOnlyIfTaskExecuter.java:41)

    at org.gradle.api.internal.tasks.execution.ExecuteAtMostOnceTaskExecuter.execute(ExecuteAtMostOnceTaskExecuter.java:43)

    at org.gradle.api.internal.AbstractTask.executeWithoutThrowingTaskFailure(AbstractTask.java:289)

    at org.gradle.execution.taskgraph.AbstractTaskPlanExecutor$TaskExecutorWorker.executeTask(AbstractTaskPlanExecutor.java:79)

    at org.gradle.execution.taskgraph.AbstractTaskPlanExecutor$TaskExecutorWorker.processTask(AbstractTaskPlanExecutor.java:63)

    at org.gradle.execution.taskgraph.AbstractTaskPlanExecutor$TaskExecutorWorker.run(AbstractTaskPlanExecutor.java:51)

    at org.gradle.execution.taskgraph.DefaultTaskPlanExecutor$1.run(DefaultTaskPlanExecutor.java:33)

    at org.gradle.internal.Factories$1.create(Factories.java:22)

    at org.gradle.cache.internal.DefaultCacheAccess.longRunningOperation(DefaultCacheAccess.java:198)

    at org.gradle.cache.internal.DefaultCacheAccess.longRunningOperation(DefaultCacheAccess.java:266)

    at org.gradle.cache.internal.DefaultPersistentDirectoryStore.longRunningOperation(DefaultPersistentDirectoryStore.java:135)

    at org.gradle.api.internal.changedetection.state.DefaultTaskArtifactStateCacheAccess.longRunningOperation(DefaultTaskArtifactStateCacheAccess.java:95)

    at org.gradle.execution.taskgraph.DefaultTaskPlanExecutor.process(DefaultTaskPlanExecutor.java:31)

    at org.gradle.execution.taskgraph.DefaultTaskGraphExecuter.execute(DefaultTaskGraphExecuter.java:86)

    at org.gradle.execution.SelectedTaskExecutionAction.execute(SelectedTaskExecutionAction.java:29)

    at org.gradle.execution.DefaultBuildExecuter.execute(DefaultBuildExecuter.java:61)

    at org.gradle.execution.DefaultBuildExecuter.access$200(DefaultBuildExecuter.java:23)

    at org.gradle.execution.DefaultBuildExecuter$2.proceed(DefaultBuildExecuter.java:67)

    at org.gradle.execution.DryRunBuildExecutionAction.execute(DryRunBuildExecutionAction.java:32)

    at org.gradle.execution.DefaultBuildExecuter.execute(DefaultBuildExecuter.java:61)

    at org.gradle.execution.DefaultBuildExecuter.execute(DefaultBuildExecuter.java:54)

    at org.gradle.initialization.DefaultGradleLauncher.doBuildStages(DefaultGradleLauncher.java:166)

    at org.gradle.initialization.DefaultGradleLauncher.doBuild(DefaultGradleLauncher.java:113)

    at org.gradle.initialization.DefaultGradleLauncher.run(DefaultGradleLauncher.java:81)

    at org.gradle.launcher.exec.InProcessBuildActionExecuter$DefaultBuildController.run(InProcessBuildActionExecuter.java:64)

    at org.gradle.launcher.cli.ExecuteBuildAction.run(ExecuteBuildAction.java:33)

    at org.gradle.launcher.cli.ExecuteBuildAction.run(ExecuteBuildAction.java:24)

    at org.gradle.launcher.exec.InProcessBuildActionExecuter.execute(InProcessBuildActionExecuter.java:35)

    at org.gradle.launcher.exec.InProcessBuildActionExecuter.execute(InProcessBuildActionExecuter.java:26)

    at org.gradle.launcher.cli.RunBuildAction.run(RunBuildAction.java:50)

    at org.gradle.internal.Actions$RunnableActionAdapter.execute(Actions.java:171)

    at org.gradle.launcher.cli.CommandLineActionFactory$ParseAndBuildAction.execute(CommandLineActionFactory.java:201)

    at org.gradle.launcher.cli.CommandLineActionFactory$ParseAndBuildAction.execute(CommandLineActionFactory.java:174)

    at org.gradle.launcher.cli.CommandLineActionFactory$WithLogging.execute(CommandLineActionFactory.java:170)

    at org.gradle.launcher.cli.CommandLineActionFactory$WithLogging.execute(CommandLineActionFactory.java:139)

    at org.gradle.launcher.cli.ExceptionReportingAction.execute(ExceptionReportingAction.java:33)

    at org.gradle.launcher.cli.ExceptionReportingAction.execute(ExceptionReportingAction.java:22)

    at org.gradle.launcher.Main.doAction(Main.java:46)

    at org.gradle.launcher.bootstrap.EntryPoint.run(EntryPoint.java:45)

    at org.gradle.launcher.Main.main(Main.java:37)

    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)

    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)

    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)

    at java.lang.reflect.Method.invoke(Method.java:606)

    at org.gradle.launcher.bootstrap.ProcessBootstrap.runNoExit(ProcessBootstrap.java:50)

    at org.gradle.launcher.bootstrap.ProcessBootstrap.run(ProcessBootstrap.java:32)

    at org.gradle.launcher.GradleMain.main(GradleMain.java:23)

     

    I've tried lots of things, such as

     

    gradle --recompile-scripts --refresh-dependencies setupForge

     

    Any idea what's causing this?

     

    Poking around in my ~/.gradle directory, I found the classes in question here:

     

    strings -- ./caches/modules-2/files-2.1/net.minecraftforge.gradle/ForgeGradle/1.1-SNAPSHOT/9ea951d3ffbe791b762e203b2027d76afd1dd625/ForgeGradle-1.1-SNAPSHOT.jar

    strings -- ./caches/modules-2/files-2.1/net.minecraftforge.gradle/ForgeGradle/1.1-SNAPSHOT/de2903f5bc25b324ac65c0ab38032746c79a4643/ForgeGradle-1.1-SNAPSHOT.jar

     

    The referenced classes are in there. So, there's some kind of problem with these new snapshots.

  11. In v1.6.4, when I want to format a chat message across multiple lines, I just include a '\n' character in the string. In 1.7.2, this now renders as a special glyph rather than generating a new line. I've glanced over the code a bit and have yet to find a solution. Has anybody else figured this out?

  12. The solution?  After you've run gradle setupDecompWorkspace (or eclipse) there should be a file build/dev.json.  In it is a listing of dependencies for gradle to gather.  Three of them have to do with lwjgl and end in '-nightly-131017'.  Just edit the file to remove the ending from those three, and then rerun gradle setupDecompWorkspace.  I would recommend making a backup of he dev.json though, because it seems to get overridden with the -nightly-131017 stuff every time, and you have to get rid of it every time before you use any gradle command.

     

    Let me know how it goes!

     

    Awesome, it worked! I've had an issue with dev.json before with it pointing towards a URL that returned a 403. Ended up being the same kind of fix.

     

    Thank you, mercrutio!

     

    I also have been using this workaround. If you switch to using the github repository for getting updates, you can commit this workaround in your local copy by changing the file jsons/1.7.2-dev.json:

     

    diff --git a/jsons/1.7.2-dev.json b/jsons/1.7.2-dev.json

    index 2f0c5e7..93d6b2c 100644

    --- a/jsons/1.7.2-dev.json

    +++ b/jsons/1.7.2-dev.json

    @@ -144,7 +144,7 @@

          }

        },

        {

    -      "name": "org.lwjgl.lwjgl:lwjgl:2.9.1-nightly-20131017",

    +      "name": "org.lwjgl.lwjgl:lwjgl:2.9.1",

          "rules": [

            {

              "action": "allow",

    @@ -155,7 +155,7 @@

          ]

        },

        {

    -      "name": "org.lwjgl.lwjgl:lwjgl_util:2.9.1-nightly-20131017",

    +      "name": "org.lwjgl.lwjgl:lwjgl_util:2.9.1",

          "rules": [

            {

              "action": "allow",

    @@ -166,7 +166,7 @@

          ]

        },

        {

    -      "name": "org.lwjgl.lwjgl:lwjgl-platform:2.9.1-nightly-20131017",

    +      "name": "org.lwjgl.lwjgl:lwjgl-platform:2.9.1",

          "rules": [

            {

              "action": "allow",

     

    Is there any good reason for using the 2.9.1-nightly-20131017 vs. just plain 2.9.1? If this change were committed to fml, this would make things run a bit smoother at least for OSX modders.

     

    [i submitted this change as https://github.com/MinecraftForge/FML/pull/347 for those following along.]

  13. Im still learning netty as well, cpw seems to have a grasp on it. And he's written a nice layer on top of the MC protocol that'll let you pass custom information back and forth using standard netty procedures.

    https://github.com/MinecraftForge/MinecraftForge/blob/95c12b6c20a456de7c24707388d4cb9cedc1cc44/src/main/java/net/minecraftforge/common/network/ForgeNetworkHandler.java

    It would be nice if someone wrote a comprehensive tutorial on the net system cuz god knows I suck at tutorials.

     

    See my reply here:

     

    http://www.minecraftforge.net/forum/index.php/topic,15403.msg78805.html#msg78805

  14. How do I send a packet to a server with the netty system?

     

    Figured this out just now. Here's the client code I'm using:

     

    import static io.netty.buffer.Unpooled.buffer;

    import io.netty.buffer.ByteBuf;

     

    @Mod(modid = "NetworkExample", name = "NetworkExample", version = "0.1")

    public class NetworkExample {

        @EventHandler

        public void serverLoad(FMLServerStartingEvent event) {

            // create our mod's channel.

            NetworkRegistry.INSTANCE.newChannel("NetworkExample", new PacketHandler());

        }

     

        @SubscribeEvent(priority = EventPriority.NORMAL)

        public void onEntityUpdated(LivingEvent.LivingUpdateEvent updateEvent) {

            ByteBuf data = buffer(4);

            data.writeInt(42);

            C17PacketCustomPayload packet = new C17PacketCustomPayload("NetworkExample", data);

            EntityClientPlayerMP player = (EntityClientPlayerMP)updateEvent.entityLiving;

            player.sendQueue.func_147297_a(packet);

        }

    }

     

    And here's the server-side packet handler:

     

    import io.netty.buffer.ByteBuf;

    import io.netty.channel.ChannelHandler.Sharable;

    import io.netty.channel.ChannelHandlerContext;

    import io.netty.channel.SimpleChannelInboundHandler;

    import cpw.mods.fml.common.network.internal.FMLProxyPacket;

     

    @Sharable

    public class PacketHandler extends SimpleChannelInboundHandler<FMLProxyPacket> {

        @Override

        protected void channelRead0(ChannelHandlerContext ctx, FMLProxyPacket packet) throws Exception {

            if (packet.channel().equals("NetworkExample")) {

                ByteBuf payload = packet.payload();

                if (payload.readableBytes() == 4) {

                    int number = payload.readInt();

                    System.out.println("number = " + number);

                }

            }

        }

    }

     

  15. Are you properly reobfuscating your mod? From this:

     

    java.lang.AbstractMethodError

    at net.minecraft.command.CommandHandler.func_71560_a(CommandHandler.java:119)

     

    I'm guessing that either your mod wasn't reobfuscated, or you're not implementing all of the required ICommand methods. Since your code compiles in eclipse, it's more likely that your mod wasn't property reobfuscated. I've used this code myself to successfully register server commands. In my mod, my commands extend CommandBase, because it implements a few useful methods for you.

  16. My client side needs to periodically report which block each player is currently selecting, and which direction he's facing. In 1.6.4 I used a network mod channel. Now I am contemplating sending a packet through a netty channel.

     

    I did the the time server tutorial, so I get the basics of netty now. What I'm wondering is how to discover the address of the server the game is connected to.

  17. Fuck the language registry.  You shouldn't need it at all.

     

    Create a new text file in /assets/MODID/lang called "en_US.lang" and do this:

     

    tile.test.name=test

     

    This works for me, but how do you package this file in the .jar file when you distribute the mod? Or is it still too early in the 1.7 forge for that?

Important Information

By using this site, you agree to our Terms of Use.

Account

Navigation

Search

Search

Configure browser push notifications

Chrome (Android)
  1. Tap the lock icon next to the address bar.
  2. Tap Permissions → Notifications.
  3. Adjust your preference.
Chrome (Desktop)
  1. Click the padlock icon in the address bar.
  2. Select Site settings.
  3. Find Notifications and adjust your preference.