Jump to content
  • Home
  • Files
  • Docs
  • Merch
Topics
  • All Content

  • This Topic
  • This Forum

  • Advanced Search
  • Existing user? Sign In  

    Sign In



    • Not recommended on shared computers


    • Forgot your password?

  • Sign Up
  • All Activity
  • Home
  • Mod Developer Central
  • Modder Support
  • [1.8] Packets? Don't think I did it right
1.13 Update Notes for Mod Creators
Sign in to follow this  
Followers 0
gummby8

[1.8] Packets? Don't think I did it right

By gummby8, January 21, 2016 in Modder Support

  • Reply to this topic
  • Start new topic

Recommended Posts

gummby8    26

gummby8

gummby8    26

  • Diamond Finder
  • gummby8
  • Members
  • 26
  • 479 posts
Posted January 21, 2016

What am I trying to do?

 

Make a block that, when right clicked, will pop up a gui with at least 1 text field (for now). The player will enter a monster name, and a few integers for when and where to spawn the monster.

 

According to what I read, I have to setup custom packets to send the string and ints setup by the player in the gui. After pouring over many tutorials I decided to go out and find a mod that already has a similarly working gui and packet system that I need and work to understand it. Enter CoolAlias with Zelda Sword Skills. He has a block that once placed pops up a simple gui where the player inputs some text. The player inputs the text, hits done, if they right click the block with a specified helm equipped the block spits back the text the player input.

 

Ok I can work with that, block, gui, save and read back 1 line of text.

 

Putting the classes together and fixing up the subsiquent red underscored lines of text in Eclipse taught me quite a bit about how packets work. In my mind they are less like magic and more like SciFi now.

 

Long story short, still not working

 

Item that should pop up the GUI

 

public class ItemControlBlock extends ItemBlockUnbreakable {

public ItemControlBlock(Block block) {
	super(block);
	setMaxStackSize(16);
}

@Override
public boolean onItemUse(ItemStack stack, EntityPlayer player, World world, BlockPos pos, EnumFacing face, float hitX, float hitY, float hitZ) {
	if (!super.onItemUse(stack, player, world, pos, face, hitX, hitY, hitZ)) {
		return false;
	} else if (player instanceof EntityPlayerMP) {
		System.out.println("GUI?");	
		PacketDispatcher.sendTo(new OpenControlBlockEditorPacket(pos.offset(face)), (EntityPlayerMP) player);
	}
	return true;
}
}

 

 

 

Packet

 

public class OpenControlBlockEditorPacket extends AbstractClientMessage<OpenControlBlockEditorPacket>
{
private BlockPos pos;

public OpenControlBlockEditorPacket() {}

/**
 * Constructor taking just the block position - TileEntity validated when opening GUI
 */
public OpenControlBlockEditorPacket(BlockPos pos) {
	this.pos = pos;
}

@Override
protected void read(PacketBuffer buffer) throws IOException {
	this.pos = BlockPos.fromLong(buffer.readLong());
}

@Override
protected void write(PacketBuffer buffer) throws IOException {
	buffer.writeLong(pos.toLong());
}

@Override
protected void process(EntityPlayer player, Side side) {
	// TileEntity checked in IGuiHandler, so no need to do so here
	player.openGui(ModularBosses.instance, GuiHandler.GUI_EDIT_CONTROL_BLOCK, player.worldObj, pos.getX(), pos.getY(), pos.getZ());
}
}

 

 

 

CoolAlias's Packet Dispatcher

 

public class PacketDispatcher
{
private static byte packetId = 0;

private static final SimpleNetworkWrapper dispatcher = NetworkRegistry.INSTANCE.newSimpleChannel(Reference.CHANNEL);

/**
 *  Registers all packets and handlers - call this during {@link FMLPreInitializationEvent}
 */
public static final void preInit() {
	// Bidirectional packets


	// Packets handled on CLIENT

	registerMessage(OpenControlBlockEditorPacket.class);


	// Packets handled on SERVER

	registerMessage(SetControlBlockMessagePacket.class);

}

/**
 * Registers an {@link AbstractMessage} to the appropriate side(s)
 */
private static final <T extends AbstractMessage<T> & IMessageHandler<T, IMessage>> void registerMessage(Class<T> clazz) {
	if (AbstractMessage.AbstractClientMessage.class.isAssignableFrom(clazz)) {
		PacketDispatcher.dispatcher.registerMessage(clazz, clazz, packetId++, Side.CLIENT);
	} else if (AbstractMessage.AbstractServerMessage.class.isAssignableFrom(clazz)) {
		PacketDispatcher.dispatcher.registerMessage(clazz, clazz, packetId++, Side.SERVER);
	} else {
		PacketDispatcher.dispatcher.registerMessage(clazz, clazz, packetId, Side.CLIENT);
		PacketDispatcher.dispatcher.registerMessage(clazz, clazz, packetId++, Side.SERVER);
	}
}

/**
 * Send this message to the specified player's client-side counterpart.
 * See {@link SimpleNetworkWrapper#sendTo(IMessage, EntityPlayerMP)}
 */
public static final void sendTo(IMessage message, EntityPlayerMP player) {
	PacketDispatcher.dispatcher.sendTo(message, player);
}

/**
 * Sends this message to players provided. SERVER->CLIENT only.
 */
public static void sendToPlayers(IMessage message, Collection<EntityPlayer> players) {
	for (EntityPlayer player : players) {
		if (player instanceof EntityPlayerMP) {
			PacketDispatcher.dispatcher.sendTo(message, (EntityPlayerMP) player);
		}
	}
}

/**
 * Send this message to everyone.
 * See {@link SimpleNetworkWrapper#sendToAll(IMessage)}
 */
public static void sendToAll(IMessage message) {
	PacketDispatcher.dispatcher.sendToAll(message);
}

/**
 * Send this message to everyone within a certain range of a point.
 * See {@link SimpleNetworkWrapper#sendToAllAround(IMessage, NetworkRegistry.TargetPoint)}
 */
public static final void sendToAllAround(IMessage message, NetworkRegistry.TargetPoint point) {
	PacketDispatcher.dispatcher.sendToAllAround(message, point);
}

/**
 * Sends a message to everyone within a certain range of the coordinates in the same dimension.
 * Shortcut to {@link SimpleNetworkWrapper#sendToAllAround(IMessage, NetworkRegistry.TargetPoint)}
 */
public static final void sendToAllAround(IMessage message, int dimension, double x, double y, double z, double range) {
	PacketDispatcher.sendToAllAround(message, new NetworkRegistry.TargetPoint(dimension, x, y, z, range));
}

/**
 * Sends a message to everyone within a certain range of the entity provided.
 * Shortcut to {@link SimpleNetworkWrapper#sendToAllAround(IMessage, NetworkRegistry.TargetPoint)}
 */
public static final void sendToAllAround(IMessage message, Entity entity, double range) {
	PacketDispatcher.sendToAllAround(message, entity.worldObj.provider.getDimensionId(), entity.posX, entity.posY, entity.posZ, range);
}

/**
 * Send this message to everyone within the supplied dimension.
 * See {@link SimpleNetworkWrapper#sendToDimension(IMessage, int)}
 */
public static final void sendToDimension(IMessage message, int dimensionId) {
	PacketDispatcher.dispatcher.sendToDimension(message, dimensionId);
}

/**
 * Send this message to the server.
 * See {@link SimpleNetworkWrapper#sendToServer(IMessage)}
 */
public static final void sendToServer(IMessage message) {
	PacketDispatcher.dispatcher.sendToServer(message);
}

/**
 * Sends a vanilla Packet to a player. SERVER->CLIENT only.
 */
public static void sendTo(Packet packet, EntityPlayer player) {
	if (player instanceof EntityPlayerMP) {
		((EntityPlayerMP) player).playerNetServerHandler.sendPacket(packet);
	}
}

/**
 * Sends a vanilla Packet to players provided. SERVER->CLIENT only.
 */
public static void sendToPlayers(Packet packet, Collection<EntityPlayer> players) {
	for (EntityPlayer player : players) {
		if (player instanceof EntityPlayerMP) {
			((EntityPlayerMP) player).playerNetServerHandler.sendPacket(packet);
		}
	}
}

/**
 * Sends a vanilla Packet to all players in the list except for the one player. SERVER->CLIENT only.
 */
public static void sendToPlayersExcept(Packet packet, EntityPlayer player, Collection<EntityPlayer> players) {
	for (EntityPlayer p : players) {
		if (p != player && p instanceof EntityPlayerMP) {
			((EntityPlayerMP) p).playerNetServerHandler.sendPacket(packet);
		}
	}
}

/**
 * Sends a vanilla Packet to all players in the same dimension. SERVER->CLIENT only.
 */
public static void sendToAll(Packet packet, World world) {
	if (world instanceof WorldServer) {
		for (Object o : ((WorldServer) world).playerEntities) {
			if (o instanceof EntityPlayerMP) {
				((EntityPlayerMP) o).playerNetServerHandler.sendPacket(packet);
			}
		}
	}
}

/**
 * Sends a vanilla Packet to all players within the given range of an entity. SERVER->CLIENT only.
 */
public static void sendToAllAround(Packet packet, Entity entity, int range) {
	int rangeSq = (range * range);
	if (entity.worldObj instanceof WorldServer) {
		for (Object o : ((WorldServer) entity.worldObj).playerEntities) {
			if (o instanceof EntityPlayerMP) {
				EntityPlayerMP player = (EntityPlayerMP) o;
				if (player.getDistanceSqToEntity(entity) <= rangeSq) {
					((EntityPlayerMP) o).playerNetServerHandler.sendPacket(packet);
				}
			}
		}
	}
}
}

 

 

I register the packets in the Packet Dispatcher in my main class

 

@EventHandler
public void preInit(FMLPreInitializationEvent event)
{
	ModularBossesBlocks.preInit();
	ModularBossesItems.init();
	ModularBossesItems.registerItems();
	ModularBossesEntities.init();
	PacketDispatcher.preInit();
}

 

 

 

 

And finally the error I get that completely crashes minecraft causing me to need to end task it

 

 

[16:52:43] [server thread/INFO] [sTDOUT]: [com.Splosions.ModularBosses.items.ItemControlBlock:onItemUse:27]: GUI?
[16:52:43] [Netty Local Client IO #0/INFO] [sTDOUT]: 
[16:52:43] [Netty Local Client IO #0/ERROR] [FML]: SimpleChannelHandlerWrapper exception
java.lang.ClassCastException: net.minecraft.client.network.NetHandlerPlayClient cannot be cast to net.minecraft.network.NetHandlerPlayServer
at net.minecraftforge.fml.common.network.simpleimpl.MessageContext.getServerHandler(Unknown Source) ~[MessageContext.class:?]
at com.Splosions.ModularBosses.proxy.CommonProxy.getThreadFromContext(CommonProxy.java:27) ~[CommonProxy.class:?]
at com.Splosions.ModularBosses.network.AbstractMessage.checkThreadAndEnqueue(AbstractMessage.java:97) ~[AbstractMessage.class:?]
at com.Splosions.ModularBosses.network.AbstractMessage.onMessage(AbstractMessage.java:86) ~[AbstractMessage.class:?]
at com.Splosions.ModularBosses.network.AbstractMessage.onMessage(AbstractMessage.java:1) ~[AbstractMessage.class:?]
at net.minecraftforge.fml.common.network.simpleimpl.SimpleChannelHandlerWrapper.channelRead0(Unknown Source) ~[simpleChannelHandlerWrapper.class:?]
at net.minecraftforge.fml.common.network.simpleimpl.SimpleChannelHandlerWrapper.channelRead0(Unknown Source) ~[simpleChannelHandlerWrapper.class:?]
at io.netty.channel.SimpleChannelInboundHandler.channelRead(SimpleChannelInboundHandler.java:103) ~[simpleChannelInboundHandler.class:4.0.15.Final]
at io.netty.channel.DefaultChannelHandlerContext.invokeChannelRead(DefaultChannelHandlerContext.java:338) [DefaultChannelHandlerContext.class:4.0.15.Final]
at io.netty.channel.DefaultChannelHandlerContext.fireChannelRead(DefaultChannelHandlerContext.java:324) [DefaultChannelHandlerContext.class:4.0.15.Final]
at io.netty.handler.codec.MessageToMessageDecoder.channelRead(MessageToMessageDecoder.java:103) [MessageToMessageDecoder.class:4.0.15.Final]
at io.netty.handler.codec.MessageToMessageCodec.channelRead(MessageToMessageCodec.java:111) [MessageToMessageCodec.class:4.0.15.Final]
at io.netty.channel.DefaultChannelHandlerContext.invokeChannelRead(DefaultChannelHandlerContext.java:338) [DefaultChannelHandlerContext.class:4.0.15.Final]
at io.netty.channel.DefaultChannelHandlerContext.fireChannelRead(DefaultChannelHandlerContext.java:324) [DefaultChannelHandlerContext.class:4.0.15.Final]
at io.netty.channel.DefaultChannelPipeline.fireChannelRead(DefaultChannelPipeline.java:785) [DefaultChannelPipeline.class:4.0.15.Final]
at io.netty.channel.embedded.EmbeddedChannel.writeInbound(EmbeddedChannel.java:169) [EmbeddedChannel.class:4.0.15.Final]
at net.minecraftforge.fml.common.network.internal.FMLProxyPacket.processPacket(Unknown Source) [FMLProxyPacket.class:?]
at net.minecraft.network.NetworkManager.channelRead0(Unknown Source) [NetworkManager.class:?]
at net.minecraft.network.NetworkManager.channelRead0(Unknown Source) [NetworkManager.class:?]
at io.netty.channel.SimpleChannelInboundHandler.channelRead(SimpleChannelInboundHandler.java:103) [simpleChannelInboundHandler.class:4.0.15.Final]
at io.netty.channel.DefaultChannelHandlerContext.invokeChannelRead(DefaultChannelHandlerContext.java:338) [DefaultChannelHandlerContext.class:4.0.15.Final]
at io.netty.channel.DefaultChannelHandlerContext.fireChannelRead(DefaultChannelHandlerContext.java:324) [DefaultChannelHandlerContext.class:4.0.15.Final]
at net.minecraftforge.fml.common.network.handshake.NetworkDispatcher.handleClientSideCustomPacket(Unknown Source) [NetworkDispatcher.class:?]
at net.minecraftforge.fml.common.network.handshake.NetworkDispatcher.channelRead0(Unknown Source) [NetworkDispatcher.class:?]
at net.minecraftforge.fml.common.network.handshake.NetworkDispatcher.channelRead0(Unknown Source) [NetworkDispatcher.class:?]
at io.netty.channel.SimpleChannelInboundHandler.channelRead(SimpleChannelInboundHandler.java:103) [simpleChannelInboundHandler.class:4.0.15.Final]
at io.netty.channel.DefaultChannelHandlerContext.invokeChannelRead(DefaultChannelHandlerContext.java:338) [DefaultChannelHandlerContext.class:4.0.15.Final]
at io.netty.channel.DefaultChannelHandlerContext.fireChannelRead(DefaultChannelHandlerContext.java:324) [DefaultChannelHandlerContext.class:4.0.15.Final]
at io.netty.channel.DefaultChannelPipeline.fireChannelRead(DefaultChannelPipeline.java:785) [DefaultChannelPipeline.class:4.0.15.Final]
at io.netty.channel.local.LocalChannel.finishPeerRead(LocalChannel.java:312) [LocalChannel.class:4.0.15.Final]
at io.netty.channel.local.LocalChannel.access$400(LocalChannel.java:44) [LocalChannel.class:4.0.15.Final]
at io.netty.channel.local.LocalChannel$6.run(LocalChannel.java:298) [LocalChannel$6.class:4.0.15.Final]
at io.netty.channel.local.LocalEventLoop.run(LocalEventLoop.java:33) [LocalEventLoop.class:4.0.15.Final]
at io.netty.util.concurrent.SingleThreadEventExecutor$2.run(SingleThreadEventExecutor.java:101) [singleThreadEventExecutor$2.class:4.0.15.Final]
at java.lang.Thread.run(Unknown Source) [?:1.8.0_66]
[16:52:43] [Netty Local Client IO #0/ERROR] [FML]: There was a critical exception handling a packet on channel mb_channel
java.lang.ClassCastException: net.minecraft.client.network.NetHandlerPlayClient cannot be cast to net.minecraft.network.NetHandlerPlayServer
at net.minecraftforge.fml.common.network.simpleimpl.MessageContext.getServerHandler(Unknown Source) ~[MessageContext.class:?]
at com.Splosions.ModularBosses.proxy.CommonProxy.getThreadFromContext(CommonProxy.java:27) ~[CommonProxy.class:?]
at com.Splosions.ModularBosses.network.AbstractMessage.checkThreadAndEnqueue(AbstractMessage.java:97) ~[AbstractMessage.class:?]
at com.Splosions.ModularBosses.network.AbstractMessage.onMessage(AbstractMessage.java:86) ~[AbstractMessage.class:?]
at com.Splosions.ModularBosses.network.AbstractMessage.onMessage(AbstractMessage.java:1) ~[AbstractMessage.class:?]
at net.minecraftforge.fml.common.network.simpleimpl.SimpleChannelHandlerWrapper.channelRead0(Unknown Source) ~[simpleChannelHandlerWrapper.class:?]
at net.minecraftforge.fml.common.network.simpleimpl.SimpleChannelHandlerWrapper.channelRead0(Unknown Source) ~[simpleChannelHandlerWrapper.class:?]
at io.netty.channel.SimpleChannelInboundHandler.channelRead(SimpleChannelInboundHandler.java:103) ~[simpleChannelInboundHandler.class:4.0.15.Final]
at io.netty.channel.DefaultChannelHandlerContext.invokeChannelRead(DefaultChannelHandlerContext.java:338) ~[DefaultChannelHandlerContext.class:4.0.15.Final]
at io.netty.channel.DefaultChannelHandlerContext.fireChannelRead(DefaultChannelHandlerContext.java:324) ~[DefaultChannelHandlerContext.class:4.0.15.Final]
at io.netty.handler.codec.MessageToMessageDecoder.channelRead(MessageToMessageDecoder.java:103) ~[MessageToMessageDecoder.class:4.0.15.Final]
at io.netty.handler.codec.MessageToMessageCodec.channelRead(MessageToMessageCodec.java:111) ~[MessageToMessageCodec.class:4.0.15.Final]
at io.netty.channel.DefaultChannelHandlerContext.invokeChannelRead(DefaultChannelHandlerContext.java:338) ~[DefaultChannelHandlerContext.class:4.0.15.Final]
at io.netty.channel.DefaultChannelHandlerContext.fireChannelRead(DefaultChannelHandlerContext.java:324) ~[DefaultChannelHandlerContext.class:4.0.15.Final]
at io.netty.channel.DefaultChannelPipeline.fireChannelRead(DefaultChannelPipeline.java:785) ~[DefaultChannelPipeline.class:4.0.15.Final]
at io.netty.channel.embedded.EmbeddedChannel.writeInbound(EmbeddedChannel.java:169) ~[EmbeddedChannel.class:4.0.15.Final]
at net.minecraftforge.fml.common.network.internal.FMLProxyPacket.processPacket(Unknown Source) [FMLProxyPacket.class:?]
at net.minecraft.network.NetworkManager.channelRead0(Unknown Source) [NetworkManager.class:?]
at net.minecraft.network.NetworkManager.channelRead0(Unknown Source) [NetworkManager.class:?]
at io.netty.channel.SimpleChannelInboundHandler.channelRead(SimpleChannelInboundHandler.java:103) [simpleChannelInboundHandler.class:4.0.15.Final]
at io.netty.channel.DefaultChannelHandlerContext.invokeChannelRead(DefaultChannelHandlerContext.java:338) [DefaultChannelHandlerContext.class:4.0.15.Final]
at io.netty.channel.DefaultChannelHandlerContext.fireChannelRead(DefaultChannelHandlerContext.java:324) [DefaultChannelHandlerContext.class:4.0.15.Final]
at net.minecraftforge.fml.common.network.handshake.NetworkDispatcher.handleClientSideCustomPacket(Unknown Source) [NetworkDispatcher.class:?]
at net.minecraftforge.fml.common.network.handshake.NetworkDispatcher.channelRead0(Unknown Source) [NetworkDispatcher.class:?]
at net.minecraftforge.fml.common.network.handshake.NetworkDispatcher.channelRead0(Unknown Source) [NetworkDispatcher.class:?]
at io.netty.channel.SimpleChannelInboundHandler.channelRead(SimpleChannelInboundHandler.java:103) [simpleChannelInboundHandler.class:4.0.15.Final]
at io.netty.channel.DefaultChannelHandlerContext.invokeChannelRead(DefaultChannelHandlerContext.java:338) [DefaultChannelHandlerContext.class:4.0.15.Final]
at io.netty.channel.DefaultChannelHandlerContext.fireChannelRead(DefaultChannelHandlerContext.java:324) [DefaultChannelHandlerContext.class:4.0.15.Final]
at io.netty.channel.DefaultChannelPipeline.fireChannelRead(DefaultChannelPipeline.java:785) [DefaultChannelPipeline.class:4.0.15.Final]
at io.netty.channel.local.LocalChannel.finishPeerRead(LocalChannel.java:312) [LocalChannel.class:4.0.15.Final]
at io.netty.channel.local.LocalChannel.access$400(LocalChannel.java:44) [LocalChannel.class:4.0.15.Final]
at io.netty.channel.local.LocalChannel$6.run(LocalChannel.java:298) [LocalChannel$6.class:4.0.15.Final]
at io.netty.channel.local.LocalEventLoop.run(LocalEventLoop.java:33) [LocalEventLoop.class:4.0.15.Final]
at io.netty.util.concurrent.SingleThreadEventExecutor$2.run(SingleThreadEventExecutor.java:101) [singleThreadEventExecutor$2.class:4.0.15.Final]
at java.lang.Thread.run(Unknown Source) [?:1.8.0_66]
[16:52:43] [server thread/INFO]: Player905 lost connection: TextComponent{text='Disconnected', siblings=[], style=Style{hasParent=false, color=null, bold=null, italic=null, underlined=null, obfuscated=null, clickEvent=null, hoverEvent=null, insertion=null}}
[16:52:43] [server thread/INFO]: Player905 left the game

 

 

 

According to teh error the packet is being sent to the server, which is wrong it is supposed to be sent to the client. But I can't find where I messed up.

  • Quote

Share this post


Link to post
Share on other sites

jabelar    591

jabelar

jabelar    591

  • Reality Controller
  • jabelar
  • Members
  • 591
  • 3266 posts
Posted January 21, 2016

If you're lucky, CoolAlias will weigh in directly on this one.

 

Anyway, well the error fairly clearly explains what is going wrong -- you're trying (i.e. your code makes the compiler try) to cast the nethandler from the wrong side. In the crash report, the last part of your code that executes before the crash is your CommonProxy.getThreadFromContext() method. So can you post that code as well?

 

Another thing to consider is you mentioned clearing out all the red Eclipse warnings. Sometimes people do this in a way that can cause trouble -- not every suggestion made by Eclipse is the best. Like maybe it suggested you cast something and you said "yes" without really understanding whether that was the right thing to do.

  • Quote

Share this post


Link to post
Share on other sites

Ernio    597

Ernio

Ernio    597

  • Reality Controller
  • Ernio
  • Forge Modder
  • 597
  • 2638 posts
Posted January 21, 2016

You have no idea what you are doing... :D

 

In other thread you asked about IGuiHanlder - I answered, so use it.

 

I don't understand why you state that you want:

Make a block that, when right clicked, will pop up a gui

And then give me Item's code, but I can roll with that.

 

Intro: Since I just finished writing some other shit, have a quote:

If you don't know yet about this topic, I recommend reading:

http://www.minecraftforge.net/forum/index.php/topic,22764.0.html

Also some of my shit-talk: http://www.minecraftforge.net/forum/index.php/topic,33918.msg178740.html#msg178740

Which might come in handy if you have no idea how things work.

 

1. Both Item and Block right-click method (onBlockSomething and onItemUsed) are called on both server and client thread.

- If you want to open a GUI you can do it from client's thread (world.isRemote) without server knowing about it.

- If you want to open GUI with CONTAINER (meaning it can hold items) you will need to either open gui from server or notify server that client opened gui. First option is better.

1.1. Regardelss:

Implementing IGuiHandler allows you to:

IGuiHandler is nothing more than super-simple call-do system. It handles only opening of gui, nothing more.

 

Every mod can have one IGuiHandler implementation. Whenever you call "player.openGui" you will be passing Mod's instance.

If called on client - your client will open GUI.

If called on server - the server will attempt to open container and if succesful - it will send packet to client that will call opening Gui for given container.

Packet that opens gui on client can have 3 integers shipped within. They are called x/y/z but can ship any kind of data. That's it.

I will add that if "the server will attempt to open container" will not be successful (there is no container to be opened), the packet will not be sent to client (will not open gui).

 

1.2. Okay, so you open your gui from client (since you don't need container). Yes, you will use "if(world.isRemote) player.openGui(...)".

- You do your shit in this gui.

- Now you click button.

- You want to send packet to server that will containt some data.

- Server will analise data and do something (spawn monster?).

 

2. Make SimpleNetworkWrapper and packets.

http://www.minecraftforge.net/forum/index.php/topic,20135.0.html

 

Now, you want to register packet with "Side.SERVER" since it is the side that will RECEIVE packet.

 

Note: If you do not understand Java (or minecraft in that matter) (as it seems you don't), do not try to replicate coolAliase's abstraction layer over packets. 1st try to make a simple implementation.

 

3. Actually sending packet.

3.1. In your gui's button-pressing call you will send packet that will contain e.g x/y/z and some string you input to gui. You need to encode that data into packet (toBytes) and then read it on server (fromBytes). After reading it - you are now on server. You will analise data and do something - e.g spawn entity.

 

Simple as that.

 

Useful things:

- ByteBufUtil

- PacketBuffer

PacketBuffer pb = new PacketBuffer(buffer); // this in is toBytes method
pb.writeString(string);

There is also writeUTF8String (or something like that).

  • Quote

Share this post


Link to post
Share on other sites

gummby8    26

gummby8

gummby8    26

  • Diamond Finder
  • gummby8
  • Members
  • 26
  • 479 posts
Posted January 21, 2016

I definitely know what casting means, pretty sure I got yelled at here a year or two ago for not knowing what it meant. So I am pretty sure I didn't accidentally cast anything.

 

When I mean no red lines. I replaced the import references from CoolAliases code to the proper imports for my own workspace.

 

Here is my common proxy

 

 

public class CommonProxy {
public void preInit() {}
public void registerRenders() {}




/**
 * Returns a side-appropriate EntityPlayer for use during message handling
 */
public EntityPlayer getPlayerEntity(MessageContext ctx) {
	return ctx.getServerHandler().playerEntity;
}

/**
 * Returns the current thread based on side during message handling,
 * used for ensuring that the message is being handled by the main thread
 */
public IThreadListener getThreadFromContext(MessageContext ctx) {
	return ctx.getServerHandler().playerEntity.getServerForPlayer();
}

}

 

  • Quote

Share this post


Link to post
Share on other sites

jabelar    591

jabelar

jabelar    591

  • Reality Controller
  • jabelar
  • Members
  • 591
  • 3266 posts
Posted January 21, 2016

First thing is that I'm not sure you can write a BlockPos directly to a byte buffer like that. I think it is safer to take each of the x, y and z from the BlockPos and convert to int.

 

Also, I think the register message method is a little overly fancy. CoolAlias did a lot of work with the packet system and wanted to generalize it (there are some pain points related to the side context), but it also got a bit trickier.

 

The way I register packets is more straight forward without checking for assignable and such:

        System.out.println("registering simple networking");
        MagicBeans.network = NetworkRegistry.INSTANCE.newSimpleChannel(MagicBeans.NETWORK_CHANNEL_NAME);

        int packetId = 0;
        // register messages from client to server
        MagicBeans.network.registerMessage(MessageToServer.Handler.class, MessageToServer.class, packetId++, Side.SERVER);
        MagicBeans.network.registerMessage(MessageGiveItemMagicBeansToServer.Handler.class, MessageGiveItemMagicBeansToServer.class, packetId++, Side.SERVER);
        MagicBeans.network.registerMessage(MessageGiveItemLeadToServer.Handler.class, MessageGiveItemLeadToServer.class, packetId++, Side.SERVER);
        MagicBeans.network.registerMessage(MessageGiantSpecialAttackToServer.Handler.class, MessageGiantSpecialAttackToServer.class, packetId++, Side.SERVER);
        // register messages from server to client
        MagicBeans.network.registerMessage(MessageToClient.Handler.class, MessageToClient.class, packetId++, Side.CLIENT);
        MagicBeans.network.registerMessage(MessageSyncEntityToClient.Handler.class, MessageSyncEntityToClient.class, packetId++, Side.CLIENT);
    }

 

You'll notice that the classes passed are not exactly the same, whereas CoolAlias was passing both as clazz parameter.

 

Another thing is that packets in 1.8 need to be thread-safe.

 

Here is my packet class related to the registration above:

{
    
    private EntityFamilyCow entityFamilyCow;
    private static int entityID;

    public MessageGiveItemMagicBeansToServer() 
    { 
    	// need this constructor
    }

    public MessageGiveItemMagicBeansToServer(EntityFamilyCow parCowMagicBeans) 
    {
        entityFamilyCow = parCowMagicBeans;
        // DEBUG
        System.out.println("MessageGiveItemToServer constructor");
    }

    @Override
    public void fromBytes(ByteBuf buf) 
    {
    	entityID = ByteBufUtils.readVarInt(buf, 4);
    }

    @Override
    public void toBytes(ByteBuf buf) 
    {
    	entityID = entityFamilyCow.getEntityId();
    	ByteBufUtils.writeVarInt(buf, entityID, 4);
    }

    public static class Handler implements IMessageHandler<MessageGiveItemMagicBeansToServer, IMessage> 
    {
        
        @Override
        public IMessage onMessage(MessageGiveItemMagicBeansToServer message, MessageContext ctx) 
        {
            // Know it will be on the server so make it thread-safe
            final EntityPlayerMP thePlayer = (EntityPlayerMP) MagicBeans.proxy.getPlayerEntityFromContext(ctx);
            thePlayer.getServerForPlayer().addScheduledTask(
                    new Runnable()
                    {
                        @Override
                        public void run() 
                        {
                            if (thePlayer.inventory.getFirstEmptyStack() != -1) // check for room in inventory
                            {
                                thePlayer.inventory.addItemStackToInventory(new ItemStack(MagicBeans.magicBeans, 1));
                                Entity theEntity = thePlayer.worldObj.getEntityByID(entityID);
                                theEntity.setDead();            
                            }
                            else
                            {
                                thePlayer.addChatMessage(new ChatComponentText("Your inventory is full!  Come back for your "
                                        +Utilities.stringToRainbow("Magic Beans")+" later."));
                            }
                            return; 
                        }
                }
            );
            return null; // no response in this case
        }
    }
}

 

  • Quote

Share this post


Link to post
Share on other sites

coolAlias    745

coolAlias

coolAlias    745

  • Reality Controller
  • coolAlias
  • Members
  • 745
  • 2805 posts
Posted January 21, 2016

I'm not sure where that error is coming from (double-check your imports, perhaps? what version of Forge are you using?), but as Ernio pointed out, you have some very illogical things in your code:

 

1. If you want the GUI to open when a certain BLOCK is right-clicked, then do it from the Block#onBlockActivated or Block#onBlockClicked methods, not from an Item

 

2. You don't need to send a packet to open a client-side GUI - just open it directly if the world is remote (i.e. block activated client side, open client side gui); the only reason to send a packet for opening a GUI is when it also has a Container (server-side) and you want to open it from a client-side interaction such as a key press.

 

The reason I had to do mine that way is because I wanted the GUI to open when the block is placed, well that happens for sure on the server, so I needed a packet; you don't, unless you don't have a custom block.

 

@jabelar Vanilla also sends BlockPos by converting it to and from a long - it's also how it is generally saved to NBT ;)

  • Quote

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

  • Insert image from URL
×
  • Desktop
  • Tablet
  • Phone
Sign in to follow this  
Followers 0
Go To Topic Listing



  • Recently Browsing

    No registered users viewing this page.

  • Posts

    • jgfarrell
      I'm having trouble with Java on !MAC!

      By jgfarrell · Posted 34 minutes ago

      Sorry Junior.   I thought I was going to be a hero!   Good luck.
    • diesieben07
      [1.14.4] [Solved] Trouble With Packets

      By diesieben07 · Posted 1 hour ago

      If you do this, then there is no point having the capability. Just store it in the stack's NBT tag directly at that point...
    • Cerandior
      [1.14.4] [Solved] Trouble With Packets

      By Cerandior · Posted 1 hour ago

      Yeah, I registered the entity and everything is fine now.
    • Cerandior
      [1.14.4] [Solved] Trouble With Packets

      By Cerandior · Posted 1 hour ago

      I have no idea man. I tried setting the breakpoints at different parts of the class because intelliJ displays a tree of all the methods called at that point and I never found any of the shareTags methods where I expected them to be. And I know, what I did doesn't really make too much sense because the stack should call the readShareTag and getShareTag automatically (I did look into a lot of methods related to itemstacks), but for some reason nothing was working as expected for me. I just tried that and everything works fine now, if I get rid of that line of code nothing works again.   As for the entity, that is probably caused by the "unique" type of zombie that my staff spawns. I forgot to register that in my registry events. I am surprised the entity was spawning considering I haven't registered them actually. I will register them right now, and check if the error will persist. Thank you for your help.
    • diesieben07
      on/off button for custom furnace

      By diesieben07 · Posted 2 hours ago

      Any GUI that has a button on it. MainMenuScreen for example.
  • Topics

    • Junior240
      4
      I'm having trouble with Java on !MAC!

      By Junior240
      Started November 9

    • Cerandior
      10
      [1.14.4] [Solved] Trouble With Packets

      By Cerandior
      Started 23 hours ago

    • plugsmustard
      18
      on/off button for custom furnace

      By plugsmustard
      Started Yesterday at 03:11 PM

    • AkosM
      3
      Increase target's damage via usable item

      By AkosM
      Started 18 hours ago

    • leesj
      3
      How to Give potion effect to entity

      By leesj
      Started Yesterday at 03:01 PM

  • Who's Online (See full list)

    • Narcato
    • Zimphire
    • zlappedx3
    • loordgek
    • diesieben07
    • Draco18s
  • All Activity
  • Home
  • Mod Developer Central
  • Modder Support
  • [1.8] Packets? Don't think I did it right
  • Theme
  • Contact Us
  • Discord

Copyright © 2019 ForgeDevelopment LLC · Ads by Curse Powered by Invision Community