Skip to content

Instantly share code, notes, and snippets.

@aadnk
Last active December 15, 2015 01:59
Show Gist options
  • Save aadnk/5183579 to your computer and use it in GitHub Desktop.
Save aadnk/5183579 to your computer and use it in GitHub Desktop.
Determine whether or not ChunkLoadEvent is reliable or not.
package com.comphenix.example;
import java.util.Collections;
import java.util.List;
import java.util.Set;
import net.minecraft.server.v1_7_R1.ChunkCoordIntPair;
import static com.comphenix.protocol.PacketType.Play.Server.*;
import org.bukkit.Chunk;
import org.bukkit.command.Command;
import org.bukkit.command.CommandSender;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.world.ChunkLoadEvent;
import org.bukkit.plugin.java.JavaPlugin;
import com.comphenix.protocol.ProtocolLibrary;
import com.comphenix.protocol.events.PacketAdapter;
import com.comphenix.protocol.events.PacketContainer;
import com.comphenix.protocol.events.PacketEvent;
import com.google.common.collect.Lists;
import com.google.common.collect.Sets;
public class TestChunkLoadEvent extends JavaPlugin implements Listener {
private Set<ChunkCoordIntPair> loadedChunks = Sets.newHashSet();
private Set<ChunkCoordIntPair> sentChunks = Sets.newHashSet();
@Override
public void onEnable() {
getServer().getPluginManager().registerEvents(this, this);
ProtocolLibrary.getProtocolManager().addPacketListener(
new PacketAdapter(this, MAP_CHUNK, MAP_CHUNK_BULK) {
@Override
public void onPacketSending(PacketEvent event) {
List<ChunkCoordIntPair> chunks = getChunkCoordIntPair(event.getPacket());
for (ChunkCoordIntPair pair : chunks) {
sentChunks.add(pair);
}
}
});
}
private List<ChunkCoordIntPair> getChunkCoordIntPair(PacketContainer packet) {
if (packet.getType() == MAP_CHUNK) {
// Get the single chunk coordinate
return Collections.singletonList(
new ChunkCoordIntPair(
packet.getIntegers().read(0),
packet.getIntegers().read(1))
);
} else {
List<ChunkCoordIntPair> chunks = Lists.newArrayList();
int[] x = packet.getIntegerArrays().read(0); // getPrivateField(packet, "c");
int[] z = packet.getIntegerArrays().read(1); // getPrivateField(packet, "d");
if (x.length != z.length)
throw new IllegalStateException("Lenght of X was different from Z.");
// Multiple chunk coordinates
for (int i = 0; i < x.length; i++) {
chunks.add(new ChunkCoordIntPair(x[i], z[i]));
}
return chunks;
}
}
@Override
public boolean onCommand(CommandSender sender, Command command, String label, String[] args) {
// Print the differences
if (command.getName().equals("performaction")) {
Set<ChunkCoordIntPair> missing = Sets.newHashSet(sentChunks);
missing.removeAll(loadedChunks);
System.out.println("Sent chunks: " + sentChunks.size());
System.out.println("Loaded chunks: " + loadedChunks.size());
System.out.println("Missing chunks: ");
for (ChunkCoordIntPair pair : missing) {
System.out.println(pair);
}
return true;
}
return false;
}
@EventHandler
public void onChunkLoad(ChunkLoadEvent e) {
Chunk chunk = e.getChunk();
loadedChunks.add(new ChunkCoordIntPair(chunk.getX(), chunk.getZ()));
}
}
@aadnk
Copy link
Author

aadnk commented Dec 24, 2013

Good news, this appears to have been fixed in 1.7.2:

[16:16:29] [Server thread/INFO]: Sent chunks: 848
[16:16:29] [Server thread/INFO]: Loaded chunks: 1890
[16:16:29] [Server thread/INFO]: Missing chunks: 
[16:16:31] [Server thread/INFO]: ***** lost connection: Disconnected

The load event also counts chunks that are loaded from the MCRegion, but not within range of a player.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment