Jump to content

xCassyx

Members
  • Posts

    6
  • Joined

  • Last visited

xCassyx's Achievements

Tree Puncher

Tree Puncher (2/8)

1

Reputation

  1. Never mind, I misunderstood what you meant. Switching the side to Side.SERVER allowed the handler to run, and I can fix the bit with the thread task scheduler. Thank you, diesieben07!
  2. Yeah, HalestormXV, persistent UUIDs are always the way to go. I was a little confused by your code, because it looked like in some places you were using UUIDs and in others, player names. Always use UUIDs when an entity may need to be referenced over multiple sessions. Another thing to note is that you will need to store the locked chest data in the world folder somewhere so you can reapply the locks when the server loads. I would recommend a custom NBT file.
  3. They are registered on both sides. I have CommonProxy, and ClientProxy which extends CommonProxy. The packets are registered in CommonProxy#registerHandlers which is always called. I copied that documentation exactly first, but it did not work, and registering packets on only one side (regardless of the side) caused an error with something along the lines of "I don't know what discriminator 0 means." Also, the code in the handler does not run at all, because nothing is logged in the console, and I plan to move the code to IThreadListener#addScheduledTask later once I get the handler to run.
  4. Yeah, that's it. It seems all correct, but I would recommend testing your mod/plugin on single-player and on a server just to make sure.
  5. I've been trying to add custom packets to my mod, but I've been having trouble getting the handler of a custom packet to run. For now I'll just post the packet code and the registration code, and I can post more if necessary. Packet class & Handler: public class CPacketUpdateLuckyBlock implements IMessage { private BlockPos pos; private int luck; private int type; public CPacketUpdateLuckyBlock() { } public CPacketUpdateLuckyBlock(BlockPos pos, int luck, int type) { this.pos = pos; this.luck = luck; this.type = type; } @Override public void fromBytes(ByteBuf buf) { pos = new BlockPos(buf.readInt(), buf.readInt(), buf.readInt()); luck = buf.readByte(); type = buf.readByte(); } @Override public void toBytes(ByteBuf buf) { buf.writeInt(pos.getX()); buf.writeInt(pos.getY()); buf.writeInt(pos.getZ()); buf.writeByte(luck); buf.writeByte(type); } public static class Handler extends ServerMessageHandler<CPacketUpdateLuckyBlock> { @Override public IMessage handleServerMessage(EntityPlayer player, CPacketUpdateLuckyBlock message, MessageContext ctx) { System.out.println("here"); World world = ctx.getServerHandler().playerEntity.getEntityWorld(); TileEntity te = world.getTileEntity(message.pos); if(te instanceof TileEntityLuckyBlock) { TileEntityLuckyBlock telb = (TileEntityLuckyBlock)te; telb.setLuck(message.luck); telb.setType(message.type); } return null; } } } The handler tree: public abstract class MessageHandler<T extends IMessage> implements IMessageHandler<T, IMessage> { public abstract IMessage handleClientMessage(EntityPlayer player, T message, MessageContext ctx); public abstract IMessage handleServerMessage(EntityPlayer player, T message, MessageContext ctx); @Override public IMessage onMessage(T message, MessageContext ctx) { if(ctx.side.isClient()) return handleClientMessage(Minecraft.getMinecraft().player, message, ctx); else return handleServerMessage(ctx.getServerHandler().playerEntity, message, ctx); } } public abstract class ClientMessageHandler<T extends IMessage> extends MessageHandler<T> { public final IMessage handleServerMessage(EntityPlayer player, T message, MessageContext ctx) { return null; } } public abstract class ServerMessageHandler<T extends IMessage> extends MessageHandler<T> { public final IMessage handleClientMessage(EntityPlayer player, T message, MessageContext ctx) { return null; } } Registration: public final class PacketDispatcher { public static final SimpleNetworkWrapper DISPATCHER = NetworkRegistry.INSTANCE.newSimpleChannel(Reference.MOD_ID); private static int packetID = 0; private PacketDispatcher() { } public static void registerPackets() { DISPATCHER.registerMessage(CPacketUpdateLuckyBlock.Handler.class, CPacketUpdateLuckyBlock.class, packetID++, Side.CLIENT); DISPATCHER.registerMessage(CPacketGiveLuckyBlock.Handler.class, CPacketGiveLuckyBlock.class, packetID++, Side.CLIENT); } public static void sendTo(IMessage message, EntityPlayerMP player) { DISPATCHER.sendTo(message, player); } public static void sendToAll(IMessage message) { DISPATCHER.sendToAll(message); } public static void sendToAllAround(IMessage message, TargetPoint targetPoint) { DISPATCHER.sendToAllAround(message, targetPoint); } public static void sendToDimension(IMessage message, int dim) { DISPATCHER.sendToDimension(message, dim); } @SideOnly(Side.CLIENT) public static void sendToServer(IMessage message) { DISPATCHER.sendToServer(message); } } Where I send the packet (in Gui method on client side): blockLuck = blockLuck < -100 ? -100 : (blockLuck > 100 ? 100 : blockLuck); blockType = blockType < 0 ? 0 : (blockType > 1 ? 1 : blockType); PacketDispatcher.sendToServer(new CPacketUpdateLuckyBlock(luckyBlock.getPos(), blockLuck, blockType)); luckyBlock.setPlayerEditing(false); mc.displayGuiScreen(null); I invoke PacketDispatcher#registerPackets in preInit. I get no errors in chat, nothing. The trace of "System.out.println("here")" simply stops after I send the packet. I have a feeling I'm getting something wrong with the registering process.
  6. Alright, I spent hours figuring this one out. There are a myriad of methods you need to implement besides writeToNBT() and readFromNBT(NBTTagCompound). A working example of a luckyblock tileentity is: import net.minecraft.block.state.IBlockState; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.nbt.NBTTagCompound; import net.minecraft.network.NetworkManager; import net.minecraft.network.play.server.SPacketUpdateTileEntity; import net.minecraft.tileentity.TileEntity; import net.minecraft.util.math.BlockPos; import net.minecraft.world.World; public class TileEntityLuckyBlock extends TileEntity { public static final int MAX_TYPE = 1; private int luck; private int type; // 0: normal, 1: well private boolean isPlayerEditing; public TileEntityLuckyBlock() { this.luck = 0; this.type = 0; this.isPlayerEditing = false; } public int getLuck() { return luck; } public void setLuck(int newLuck) { luck = newLuck; markDirty(); // important } public int getType() { return type; } public void setType(int newType) { type = newType; markDirty(); // important } public boolean isPlayerEditing() { return isPlayerEditing; } public void setPlayerEditing(boolean editing) { isPlayerEditing = editing; // not marked because this field doesn't need to be persistent } public void executeDrop(World world, BlockPos pos, EntityPlayer breaker) { switch(type) { case 0: LBDrops.executeDrop(luck, world, pos, breaker); break; case 1: { EntityPlayer player = world.getClosestPlayer(pos.getX() + 0.5, pos.getY() + 0.5, pos.getZ() + 0.5, 16.0 * 16.0 * 32.0, false); if(player != null) LBDrops.executeWellDrop(luck, world, pos, player, false); break; } } } /** Everything below here is an absolute MUST have. **/ @Override public boolean shouldRefresh(World world, BlockPos pos, IBlockState oldState, IBlockState newSate) { return false; } @Override public NBTTagCompound getTileData() { return serializeNBT(); } @Override public SPacketUpdateTileEntity getUpdatePacket() { NBTTagCompound nbt = new NBTTagCompound(); writeToNBT(nbt); return new SPacketUpdateTileEntity(this.pos, 1, nbt); } @Override public NBTTagCompound getUpdateTag() { NBTTagCompound nbt = new NBTTagCompound(); writeToNBT(nbt); return nbt; } @Override public void onDataPacket(NetworkManager manager, SPacketUpdateTileEntity packet) { readFromNBT(packet.getNbtCompound()); } /** Obviously these mehtods will be different. **/ @Override public NBTTagCompound writeToNBT(NBTTagCompound nbt) { super.writeToNBT(nbt); nbt.setInteger("luck", luck); nbt.setInteger("type", type); return nbt; } @Override public void readFromNBT(NBTTagCompound nbt) { super.readFromNBT(nbt); luck = nbt.getInteger("luck"); type = nbt.getInteger("type"); isPlayerEditing = false; } } So basically try copying the implementations of shouldRefresh, getTileData, getUpdatePacket, getUpdateTag, and onDataPacket. You will also need to schedule a render update in onDataPacket if you're rendering your tile entity.
×
×
  • Create New...

Important Information

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