acadus Posted January 5, 2018 Share Posted January 5, 2018 I'm trying to make it so that when a player right clicks on a block, it opens a GUI (no inventory) for them, but the packet I am using gives a NullPointerException when I try and send the packet. The error only highlights the line in the block activation code and does not say what variable is null, presumably due to the threading process. Here is my code: Packet & Handler public class PacketOpenGui implements IMessage { public PacketOpenGui(int guiid, BlockPos pos) { this.guiID = guiid; this.blockPos = pos; } private int guiID; private BlockPos blockPos; @Override public void fromBytes(ByteBuf buf) { guiID = buf.readInt(); blockPos = BlockPos.fromLong(buf.readLong()); } @Override public void toBytes(ByteBuf buf) { buf.writeInt(guiID); buf.writeLong(blockPos.toLong()); } public static class Handler implements IMessageHandler<PacketOpenGui, IMessage> { @Override public IMessage onMessage(PacketOpenGui message, MessageContext ctx) { FMLCommonHandler.instance().getWorldThread(ctx.netHandler).addScheduledTask(() -> handle(message, ctx)); return null; } private void handle(PacketOpenGui message, MessageContext ctx) { if(message.guiID == 0) { ModTest.proxy.openGui(new GuiExample(new V3(message.blockPos.getX(), message.blockPos.getY(), message.blockPos.getZ()), "-x", null, (EntityPlayer)ctx.getServerHandler().player)); } } } } Packet Registry public class PacketHandler { private static int packetId = 0; public static SimpleNetworkWrapper INSTANCE = null; public PacketHandler() { } public static int nextID() { return packetId++; } public static void registerMessages(String channelName) { INSTANCE = NetworkRegistry.INSTANCE.newSimpleChannel(channelName); registerMessages(); } public static void registerMessages() { INSTANCE.registerMessage(PacketOpenGui.Handler.class, PacketOpenGui.class, nextID(), Side.SERVER); } } Client Proxy Exert public class ClientProxy extends CommonProxy { @Override //Override from empty function in CommonProxy public void openGui(@Nullable GuiScreen gui) { Minecraft.getMinecraft().displayGuiScreen(gui); } } Block Activation @Override public boolean onBlockActivated(World worldIn, BlockPos pos, IBlockState state, EntityPlayer playerIn, EnumHand hand, EnumFacing facing, float hitX, float hitY, float hitZ) { if (!worldIn.isRemote) { PacketHandler.INSTANCE.sendTo(new PacketOpenGui(0, pos), (EntityPlayerMP)playerIn); //Error occurs on this line without any explanation } return true; } Quote Link to comment Share on other sites More sharing options...
Draco18s Posted January 6, 2018 Share Posted January 6, 2018 The Side parameter is which side is the receiver. Quote Apparently I'm a complete and utter jerk and come to this forum just like to make fun of people, be confrontational, and make your personal life miserable. If you think this is the case, JUST REPORT ME. Otherwise you're just going to get reported when you reply to my posts and point it out, because odds are, I was trying to be nice. Exception: If you do not understand Java, I WILL NOT HELP YOU and your thread will get locked. DO NOT PM ME WITH PROBLEMS. No help will be given. Link to comment Share on other sites More sharing options...
acadus Posted January 6, 2018 Author Share Posted January 6, 2018 15 hours ago, Draco18s said: The Side parameter is which side is the receiver. Ah sorry, my bad. I corrected it but the error still persists. Is there any way I can get more information on the error so that you can better help me? Quote Link to comment Share on other sites More sharing options...
acadus Posted January 6, 2018 Author Share Posted January 6, 2018 (edited) 18 minutes ago, diesieben07 said: Your IMessage class needs a no-argument constructor. Putting openGui in your proxy like that doesn't help. You are still creating the GuiScreen itself outside of the client proxy in common code. This will crash a server. You never change this to any other value. Okay, I've removed the constructor arguments and moved the creation of the GuiScreen instance into the client proxy. I have actually registered the instance in the preInit of my common proxy which is then called in the mod file proxy, but I forgot to include this in the original post. However, the same NullPointerException keeps occuring at the same line in the Block Activation. Here are the updated classes: Packet and Handler public class PacketOpenGui implements IMessage { public PacketOpenGui() {} private BlockPos blockPos; @Override public void fromBytes(ByteBuf buf) { blockPos = BlockPos.fromLong(buf.readLong()); } @Override public void toBytes(ByteBuf buf) { buf.writeLong(blockPos.toLong()); } public static class Handler implements IMessageHandler<PacketOpenGui, IMessage> { @Override public IMessage onMessage(PacketOpenGui message, MessageContext ctx) { try{ FMLCommonHandler.instance().getWorldThread(ctx.netHandler).addScheduledTask(() -> handle(message, ctx)); } catch(Exception e) { e.printStackTrace(); } return null; } private void handle(PacketOpenGui message, MessageContext ctx) { ModTest.proxy.openGui(); } } } Packet Registry public class PacketHandler { private static int packetId = 0; public static SimpleNetworkWrapper INSTANCE = null; public PacketHandler() { } public static int nextID() { return packetId++; } public static void registerMessages(String channelName) { INSTANCE = NetworkRegistry.INSTANCE.newSimpleChannel(channelName); //Called in common proxy registerMessages(); } public static void registerMessages() { INSTANCE.registerMessage(PacketOpenGui.Handler.class, PacketOpenGui.class, nextID(), Side.CLIENT); } } Client Proxy Exert @Override public void openGui() { Minecraft.getMinecraft().displayGuiScreen(new GuiExample(new V3(1,1,1), "-x", null, (EntityPlayer)Minecraft.getMinecraft().player)); } Block Activation @Override public boolean onBlockActivated(World worldIn, BlockPos pos, IBlockState state, EntityPlayer playerIn, EnumHand hand, EnumFacing facing, float hitX, float hitY, float hitZ) { if (!worldIn.isRemote) { PacketHandler.INSTANCE.sendTo(new PacketOpenGui(), (EntityPlayerMP)playerIn); } return true; } Edit: I just removed the use of blockPos for the time being to make things simpler. Edited January 6, 2018 by acadus Quote Link to comment Share on other sites More sharing options...
acadus Posted January 6, 2018 Author Share Posted January 6, 2018 19 minutes ago, diesieben07 said: You can keep them. You just need to also have a no-argument constructor. Code style, issue 1. Please clarify what a "mod file proxy" is. Show your main mod class and proxies. Common Proxy: @Mod.EventBusSubscriber public class CommonProxy { public void registerItemRenderer(Item item, int meta, String id) { } public String localize(String unlocalized, Object... args) { return I18n.translateToLocalFormatted(unlocalized, args); } public void registerRenderers() { } public void preInit(FMLPreInitializationEvent e) { PacketHandler.registerMessages("packettests"); } public void init(FMLInitializationEvent e) { } public void postInit(FMLPostInitializationEvent e) { } public void openGui() { } } Client Proxy: @Mod.EventBusSubscriber(Side.CLIENT) public class ClientProxy extends CommonProxy { @Override public void registerItemRenderer(Item item, int meta, String id) { ModelLoader.setCustomModelResourceLocation(item, meta, new ModelResourceLocation(ModTest.MODID + ":" + id, "inventory")); } @Override public String localize(String unlocalized, Object... args) { return I18n.format(unlocalized, args); } @Override public void registerRenderers() { } @Override public void preInit(FMLPreInitializationEvent e) { } @Override public void init(FMLInitializationEvent e) { } @Override public void postInit(FMLPostInitializationEvent e) { } @Override public void openGui() { Minecraft.getMinecraft().displayGuiScreen(new GuiExample(new V3(1,1,1), "-x", null, (EntityPlayer)Minecraft.getMinecraft().player)); } } Mod File: @Mod(modid = ModTest.MODID, name = ModTest.MODNAME, version = ModTest.VERISON, useMetadata = true) public class ModTest { public static final String MODID = "modtest"; public static final String MODNAME = "Mod Test"; public static final String VERISON = "1.0.0"; @SidedProxy(clientSide = "acadus.modtest.proxy.ClientProxy", serverSide = "acadus.modtest.proxy.ServerProxy") public static CommonProxy proxy; @Mod.Instance public static ModTest instance; public static Logger log; @Mod.EventHandler public void preInit(FMLPreInitializationEvent event) { log = event.getModLog(); proxy.preInit(event); } @Mod.EventHandler public void init(FMLInitializationEvent event) { proxy.init(event); } @Mod.EventHandler public void postInit(FMLPostInitializationEvent event) { proxy.postInit(event); } @Mod.EventBusSubscriber public static class RegsitrationHandler { @SubscribeEvent public static void registerItems(RegistryEvent.Register<Item> event) { //ModItems.register(event.getRegistry()); ModBlocks.registerItemBlocks(event.getRegistry()); } @SubscribeEvent public static void registerBlocks(RegistryEvent.Register<Block> event) { ModBlocks.register(event.getRegistry()); } @SubscribeEvent public static void registerModels(ModelRegistryEvent event) { //ModItems.registerModels(); ModBlocks.registerModels(); } } } Quote Link to comment Share on other sites More sharing options...
acadus Posted January 6, 2018 Author Share Posted January 6, 2018 23 minutes ago, diesieben07 said: Your client proxy overrides preInit to do nothing, so the packet handler is not initialized. Why do you have a "common proxy"? This code should go in your main mod class. Ah, of course, I can't believe I overlooked it. Should I create an instance for my client and server proxy in the mod file and then remove the common proxy? Quote Link to comment Share on other sites More sharing options...
acadus Posted January 6, 2018 Author Share Posted January 6, 2018 2 minutes ago, diesieben07 said: No. What you now have as "common proxy" should be an interface simply called "proxy". It should not contain any code and simply act as the interface (duh) to the client and server proxy implementation. Got it, thank you very much Quote Link to comment Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.