ProtocolLib

3M Downloads

How To manipulate the packet MAP_CHUNK?

FREE2WIN2 opened this issue ยท 4 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 want to manipulate the NBT-Data of the Packet.Play.Server.Map_Chunk packet.

API method(s) used
see code

Expected behavior
I want to override specific blocks to another material(e.g. dirt to stone)
In cause of many blockupdates per tick per chunk Minecraft fires the PacketPlayOutMapChunk, which I want to manipulate with Protocollib

Code

protocolManager.addPacketListener( new PacketAdapter(Main.getMain(), ListenerPriority.HIGHEST, PacketType.Play.Server.MAP_CHUNK) {
 @Override
 public void onPacketSending(PacketEvent event) {
   Player p = event.getPlayer();
   if (event.getPacketType().equals(PacketType.Play.Server.MAP_CHUNK)) {
	PacketContainer packet = event.getPacket();
	PacketContainer clone = packet.shallowClone();
	List<NbtBase<?>> listout = new ArrayList<>();
	int zaehler = -1;
	for (List<NbtBase<?>> listNBT : packet.getListNbtModifier().getValues()) {
		zaehler++;
		for (NbtBase<?> base : listNBT) {
	        	NbtCompound nbt = NbtFactory.asCompound(base);
			int x = nbt.getInteger("x");
			int y = nbt.getInteger("y");
			int z = nbt.getInteger("z");
			List<String> apllRegions = regions.getApplicableRegionsIDs(BlockVector3.at(x, y, z));
									Material m = Material.getMaterial(nbt.getString("id").replace("minecraft:", "").toUpperCase());
			if (materials.contains(m)) {
			       if (apllRegions.contains("south")) {
					if (Main.aWdlWhitelist.contains(p.getName()) || Main.teamSmembers.contains(p.getName())) {
						event.setPacket(packet);
						return;
					} else {
                                       //here manipulate the packet					
					listout.add((NbtBase<?>) nbt);
					}
				}else if (apllRegions.contains("north")) {
					if (Main.aWdlWhitelist.contains(p.getName())|| Main.teamSmembers.contains(p.getName())) {
						event.setPacket(packet);
						return;
					} else {
                                            //here manipulate the packet
					 listout.add((NbtBase<?>) nbt.);
					}
				}
			}
		}
		clone.getListNbtModifier().write(zaehler, listout);
	}
	event.setPacket(clone);
}
}
});```
commented

well, you already get the nbt stuff, just set the modified versions?

commented

Yeah, but it doesnt work...

commented

Even if I try to set complete new NBT-Data it doesnt work..

NbtCompound out = NbtFactory.ofCompound(null);
out.put("x", x);
out.put("y", y);
out.put("z", z);
out.put("id", "minecraft:endstone");
commented

I'm not sure I entirely understand your code here:

                                if (apllRegions.contains("south")) {
					if (Main.aWdlWhitelist.contains(p.getName()) || Main.teamSmembers.contains(p.getName())) {
						event.setPacket(packet);
						return;
					} else {
                                       //here manipulate the packet					
					listout.add((NbtBase<?>) nbt);
					}
				}else if (apllRegions.contains("north")) {
					if (Main.aWdlWhitelist.contains(p.getName())|| Main.teamSmembers.contains(p.getName())) {
						event.setPacket(packet);
						return;
					} else {
                                            //here manipulate the packet
					 listout.add((NbtBase<?>) nbt.);
					}
				}

It seems like this should be at the beginning, outside the loop.

And I guess what do you mean by "doesn't work" like does nothing happen or is the world not displaying correctly?