Closed satoshinm closed 7 years ago
ThinkMap has two methods to get chunk data, getChunkBytes()
first tries to fetch a ChunkSnapshot
using the Bukkit API, if null then getChunkData()
reads and parses the actual chunk file on disk! Since it is a world map, this may not be too unreasonable. But for this kind of plugin, where web players would necessarily be in the chunks they visit, and to avoid interdependence on non-Bukkit API, may want to only use the first approach. The blocks need to translated, packed, compressed, then possibly encoded for sending over the wire in Craft's protocol.
https://hub.spigotmc.org/javadocs/bukkit/org/bukkit/ChunkSnapshot.html only has useful deprecated methods? This is the entirety of the interface:
public interface ChunkSnapshot {
int getX();
int getZ();
String getWorldName();
/** @deprecated */
@Deprecated
int getBlockTypeId(int var1, int var2, int var3);
/** @deprecated */
@Deprecated
int getBlockData(int var1, int var2, int var3);
int getBlockSkyLight(int var1, int var2, int var3);
int getBlockEmittedLight(int var1, int var2, int var3);
int getHighestBlockYAt(int var1, int var2);
Biome getBiome(int var1, int var2);
double getRawBiomeTemperature(int var1, int var2);
double getRawBiomeRainfall(int var1, int var2);
long getCaptureFullTime();
boolean isSectionEmpty(int var1);
}
ChunkSnapshot may not be needed or useful. Iterate over a cube of World and translate BlockStates into a ByteBuf array then gzip it?
Testing block order on a test world versus compression size, to determine compression efficiency (radius=+/-16, so (216)(216)(216)2=65536 bytes, short):
axis order (outer to inner) | deflated size | code |
---|---|---|
y, z, x | 3163 bytes | Block block = world.getBlockAt(k + x_center, j + y_center, i + z_center); |
z, y, x | 3163 bytes | Block block = world.getBlockAt(k + x_center, j + y_center, i + z_center); |
x, y, z | 3022 bytes | Block block = world.getBlockAt(i + x_center, j + y_center, k + z_center); |
x, z, y | 2871 bytes | Block block = world.getBlockAt(k + x_center, i + y_center, j + z_center); |
y, x, z | 2947 bytes | Block block = world.getBlockAt(j + x_center, k + y_center, i + z_center); |
z, x, y | 2790 bytes | Block block = world.getBlockAt(j + x_center, i + y_center, k + z_center); |
z, x, y (or from inner to outer: y, x, z) is the winner - this makes sense given runs of air. Flipped on side:
For https://github.com/satoshinm/NetCraft/issues/136