Jump to content

libarclite

Members
  • Posts

    42
  • Joined

  • Last visited

Everything 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. My technique of diffing the old and new sources works reasonably well. Although names have changed, a lot still seems to be same.
  4. 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.
  5. I did try to generate some queries with the mcp bot. The IRC experience has never been my cup of tea. I'd much prefer having a git repository somewhere that holds the mappings. If that's not practical, sigh.
  6. 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.
  7. I have sort of been expecting to see fewer obfuscated symbols as new versions of MinecraftForge and FML come out. Am I missing something? I'd really like to get out of the business of coding using obfuscated names.
  8. 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().
  9. 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?
  10. 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.
  11. 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.
  12. 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())); }
  13. Tossing all those ForgeGradle-1.1-SNAPSHOT.jar files apparently fixed the problem for me.
  14. 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.
  15. No, this produces the same results. String.format("foo%n") generates the string "foo\n" on my platform. I'm guess that they've done something that requires structuring chat messages with some kind of markup.
  16. 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?
  17. 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.]
  18. See my reply here: http://www.minecraftforge.net/forum/index.php/topic,15403.msg78805.html#msg78805
  19. 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); } } } }
  20. 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.
  21. 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.
  22. 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?
  23. I too am interested in this. Guess it's time to study http://netty.io/wiki/user-guide-for-4.x.html
  24. build/tmp/decompile/forge-1.7.2-10.12.0.993-srg.jar build/tmp/reobf/reobf.srg build/unpacked/conf/mcp-notch.srg build/unpacked/conf/mcp-srg.srg build/unpacked/conf/notch-mcp.srg build/unpacked/conf/packaged.srg
×
×
  • Create New...

Important Information

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