ProtocolLib

3M Downloads

Trying To Create a simple fake DROPPED_ITEM

dniym opened this issue ยท 3 comments

commented

Make sure you're doing the following

  • You're using the latest build for your server version
  • This isn't an issue caused by another plugin
  • You've checked for duplicate issues
  • You didn't use /reload

Describe the question
I am working on spawning a fake item that only a specific player can see. I can spawn/despawn pretty much any other EntityType but I would like to use a DROPPED_ITEM which requires a second packet ENTITY_METADATA to be sent. Here's what I have so far.

API method(s) used
`
public void spawn(Location loc, Player player) {

    final ThreadLocalRandom random = ThreadLocalRandom.current();

    final ProtocolManager manager = ProtocolLibrary.getProtocolManager();
    final PacketContainer itemPacket = manager.createPacket(PacketType.Play.Server.SPAWN_ENTITY);

    itemPacket.getEntityTypeModifier().write(0, EntityType.DROPPED_ITEM);
 
 
 
 
    //final int entityID = random.nextInt();
    entityID = random.nextInt();
    final int entityType = 50;
    final int extraData = 1;

    final StructureModifier<Integer> itemInts = itemPacket.getIntegers();
    itemInts.write(0, entityID);
    itemInts.write(1, entityType);
    itemInts.write(2, extraData);

    final StructureModifier<UUID> itemIDs = itemPacket.getUUIDs();
    UUID entityUUID = UUID.randomUUID();
    itemIDs.write(0, entityUUID);

 
    //final StructureModifier<Double> itemDoubles = itemPacket.getDoubles();
 
    Location location = loc.clone().add(0.5, 0.5, 0.5);
    itemPacket.getDoubles().write(0, location.getX()).write(1, location.getY()).write(2, location.getZ());
 
        manager.sendServerPacket(player, itemPacket);

    spawned = true;

}

`
Up to this point it will spawn and (later) remove an invisible dropped_item, now I would like to send a metadata packet to render it correctly to the client.

PacketContainer fakePacket = manager.createPacket(PacketType.Play.Server.ENTITY_METADATA); fakePacket.getModifier().writeDefaults(); fakePacket.getIntegers().write(0, entityID); final WrappedWatchableObject itemMeta = new WrappedWatchableObject(10, is); final List<WrappedWatchableObject> entityMetaList = new ArrayList<>(1); entityMetaList.add(itemMeta); fakePacket.getWatchableCollectionModifier().writeSafely(0, entityMetaList); // fakePacket.getWatchableCollectionModifier().write(0, entityMetaList); manager.sendServerPacket(player, fakePacket);
Once I add in and send this packet the client gets disconnected for the following reason:
23.09 12:55:35 [Disconnect] User dniym has disconnected, reason: Internal Exception: io.netty.handler.codec.EncoderException: java.lang.NullPointerException: Cannot invoke "net.minecraft.network.syncher.DataWatcherSerializer.a(net.minecraft.network.PacketDataSerializer, Object)" because the return value of "net.minecraft.network.syncher.DataWatcherObject.b()" is null

Additional context
I have tried about every single other way I could find on 5 pages of google searches with similarish issues. Could someone please explain what I am doing wrong? I always struggle with protocollib projects but I really need a fake dropped item of a specific itemstack type that ONLY one player can see. I suppose I could spawn a real item then possibly destroy it for every other player on the server but this seems like a bad workaround.

commented

Might I suggest a different approach: (which by the way I used to achieve similar results in a plugin I made)

Spawn in a REAL item, but instead, cancel the entity spawn packets being sent to individual players for that item to control who can see it.

commented

This is kinda what I've ended up doing as a workaround, I also cancel the entitypickupitemevent for everyone except the player that can see it.

I just send the destroy entity packet to all other players instead of the spawn packet idea

Just feel like there is a way to do this it's just a closely guarded secret for some reason lol.

Thanks for the suggestion though, it was definitely the route I ended up taking.