From 5cfcedeab82ecccb6a601be4fae6993e188c86ee Mon Sep 17 00:00:00 2001 From: boy0001 Date: Fri, 21 Nov 2014 14:11:41 +1100 Subject: [PATCH] NMS chunk sending (rather than using refresh chunk) --- .../intellectualcrafters/plot/PlotMain.java | 9 +++ .../plot/util/PlotHelper.java | 23 +++++- .../plot/util/SendChunk.java | 76 +++++++++++++++++++ .../plot/util/SetBlockFast.java | 29 ++++++- 4 files changed, 133 insertions(+), 4 deletions(-) create mode 100644 PlotSquared/src/main/java/com/intellectualcrafters/plot/util/SendChunk.java diff --git a/PlotSquared/src/main/java/com/intellectualcrafters/plot/PlotMain.java b/PlotSquared/src/main/java/com/intellectualcrafters/plot/PlotMain.java index c8024e3f3..3203180a8 100644 --- a/PlotSquared/src/main/java/com/intellectualcrafters/plot/PlotMain.java +++ b/PlotSquared/src/main/java/com/intellectualcrafters/plot/PlotMain.java @@ -42,8 +42,10 @@ import com.intellectualcrafters.plot.uuid.PlotUUIDSaver; import com.intellectualcrafters.plot.uuid.UUIDSaver; import com.sk89q.worldedit.bukkit.WorldEditPlugin; import com.sk89q.worldguard.bukkit.WorldGuardPlugin; + import me.confuser.barapi.BarAPI; import net.milkbowl.vault.economy.Economy; + import org.bukkit.*; import org.bukkit.command.PluginCommand; import org.bukkit.configuration.file.YamlConfiguration; @@ -1543,6 +1545,13 @@ public class PlotMain extends JavaPlugin { } catch (final Exception e) { PlotHelper.canSetFast = false; } + + try { + new SendChunk(); + PlotHelper.canSendChunk = true; + } catch (final Exception e) { + PlotHelper.canSendChunk = false; + } } // Setup the setup command { diff --git a/PlotSquared/src/main/java/com/intellectualcrafters/plot/util/PlotHelper.java b/PlotSquared/src/main/java/com/intellectualcrafters/plot/util/PlotHelper.java index 94229e43a..30c47d71f 100644 --- a/PlotSquared/src/main/java/com/intellectualcrafters/plot/util/PlotHelper.java +++ b/PlotSquared/src/main/java/com/intellectualcrafters/plot/util/PlotHelper.java @@ -47,6 +47,7 @@ import java.util.UUID; */ public class PlotHelper { public static boolean canSetFast = false; + public static boolean canSendChunk = false; public static ArrayList runners_p = new ArrayList(); public static HashMap runners = new HashMap(); static long state = 1; @@ -697,7 +698,6 @@ public class PlotHelper { if (canSetFast) { refreshPlotChunks(world, plot); - // SetBlockFast.update(requester); } } @@ -863,9 +863,28 @@ public class PlotHelper { final int minChunkZ = (int) Math.floor((double) bottomZ / 16); final int maxChunkZ = (int) Math.floor((double) topZ / 16); + ArrayList chunks = new ArrayList<>(); + for (int x = minChunkX; x <= maxChunkX; x++) { for (int z = minChunkZ; z <= maxChunkZ; z++) { - world.refreshChunk(x, z); + if (canSendChunk) { + Chunk chunk = world.getChunkAt(x, z); + chunks.add(chunk); + } + else { + world.refreshChunk(x, z); + } + } + } + try { + SendChunk.sendChunk(chunks); + } + catch (Throwable e) { + canSendChunk = false; + for (int x = minChunkX; x <= maxChunkX; x++) { + for (int z = minChunkZ; z <= maxChunkZ; z++) { + world.refreshChunk(x, z); + } } } } diff --git a/PlotSquared/src/main/java/com/intellectualcrafters/plot/util/SendChunk.java b/PlotSquared/src/main/java/com/intellectualcrafters/plot/util/SendChunk.java new file mode 100644 index 000000000..eda35422c --- /dev/null +++ b/PlotSquared/src/main/java/com/intellectualcrafters/plot/util/SendChunk.java @@ -0,0 +1,76 @@ +package com.intellectualcrafters.plot.util; + +import static com.intellectualcrafters.plot.util.ReflectionUtils.getRefClass; + +import java.util.ArrayList; +import java.util.List; + +import org.bukkit.Bukkit; +import org.bukkit.Chunk; + +import com.intellectualcrafters.plot.util.ReflectionUtils.RefClass; +import com.intellectualcrafters.plot.util.ReflectionUtils.RefConstructor; +import com.intellectualcrafters.plot.util.ReflectionUtils.RefField; +import com.intellectualcrafters.plot.util.ReflectionUtils.RefMethod; + +public class SendChunk { + + private static final RefClass classWorld = getRefClass("{nms}.World"); + private static final RefClass classEntityPlayer = getRefClass("{nms}.EntityPlayer"); + private static final RefClass classChunkCoordIntPair = getRefClass("{nms}.ChunkCoordIntPair"); + private static final RefClass classCraftChunk = getRefClass("{cb}.CraftChunk"); + private static final RefClass classChunk = getRefClass("{nms}.Chunk"); + + private static RefMethod methodGetHandle; + + + private static RefField chunkCoordIntPairQueue; + private static RefField players; + private static RefField locX; + private static RefField locZ; + private static RefField world; + + private static RefConstructor ChunkCoordIntPairCon; + + public SendChunk() throws NoSuchMethodException { + methodGetHandle = classCraftChunk.getMethod("getHandle"); + chunkCoordIntPairQueue = classEntityPlayer.getField("chunkCoordIntPairQueue"); + + players = classWorld.getField("players"); + locX = classEntityPlayer.getField("locX"); + locZ = classEntityPlayer.getField("locZ"); + + world = classChunk.getField("world"); + + ChunkCoordIntPairCon = classChunkCoordIntPair.getConstructor(int.class, int.class); + } + + public static void sendChunk(ArrayList chunks) { + int diffx, diffz; + int view = Bukkit.getServer().getViewDistance() << 4; + for (Chunk chunk : chunks) { + final Object c = methodGetHandle.of(chunk).call(); + + final Object w = world.of(c).get(); + final Object p = players.of(w).get(); + + for (Object ep : (List) p) { + int x = ((Double) locX.of(ep).get()).intValue(); + int z = ((Double) locZ.of(ep).get()).intValue(); + diffx = Math.abs(x - (chunk.getX() << 4)); + diffz = Math.abs(z - (chunk.getZ() << 4)); + if (diffx <= view && diffz <= view) { + System.out.print("PLAYER "); + Object pair = ChunkCoordIntPairCon.create(chunk.getX(), chunk.getZ()); + Object pq = chunkCoordIntPairQueue.of(ep).get(); + ((List) pq).add(pair); + } + else { + System.out.print("NOT P "+diffx+ " | "+diffz+" | "+view); + System.out.print("2 "+x+ " | "+z+" | "); + System.out.print("3 "+(chunk.getX() << 4)+ " | "+(chunk.getZ() << 4)+" | "); + } + } + } + } +} diff --git a/PlotSquared/src/main/java/com/intellectualcrafters/plot/util/SetBlockFast.java b/PlotSquared/src/main/java/com/intellectualcrafters/plot/util/SetBlockFast.java index 6d080f717..ad1b260aa 100644 --- a/PlotSquared/src/main/java/com/intellectualcrafters/plot/util/SetBlockFast.java +++ b/PlotSquared/src/main/java/com/intellectualcrafters/plot/util/SetBlockFast.java @@ -21,9 +21,13 @@ package com.intellectualcrafters.plot.util; +import java.util.ArrayList; + import com.intellectualcrafters.plot.util.ReflectionUtils.RefClass; import com.intellectualcrafters.plot.util.ReflectionUtils.RefMethod; + import org.bukkit.Bukkit; +import org.bukkit.Chunk; import static com.intellectualcrafters.plot.util.ReflectionUtils.getRefClass; @@ -60,11 +64,32 @@ public class SetBlockFast { } public static void update(final org.bukkit.entity.Player player) { - final int distance = Bukkit.getViewDistance() + 1; + if (!PlotHelper.canSendChunk) { + + final int distance = Bukkit.getViewDistance(); + for (int cx = -distance; cx < distance; cx++) { + for (int cz = -distance; cz < distance; cz++) { + player.getWorld().refreshChunk(player.getLocation().getChunk().getX() + cx, player.getLocation().getChunk().getZ() + cz); + } + } + + return; + } + ArrayList chunks = new ArrayList<>(); + + final int distance = Bukkit.getViewDistance(); for (int cx = -distance; cx < distance; cx++) { for (int cz = -distance; cz < distance; cz++) { - player.getWorld().refreshChunk(player.getLocation().getChunk().getX() + cx, player.getLocation().getChunk().getZ() + cz); + Chunk chunk = player.getWorld().getChunkAt(player.getLocation().getChunk().getX() + cx, player.getLocation().getChunk().getZ() + cz); + chunks.add(chunk); } } + + try { + SendChunk.sendChunk(chunks); + } + catch (Throwable e) { + PlotHelper.canSendChunk = false; + } } }