NMS chunk sending (rather than using refresh chunk)

This commit is contained in:
boy0001 2014-11-21 14:11:41 +11:00
parent a00f38e91f
commit 5cfcedeab8
4 changed files with 133 additions and 4 deletions

View File

@ -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
{

View File

@ -47,6 +47,7 @@ import java.util.UUID;
*/
public class PlotHelper {
public static boolean canSetFast = false;
public static boolean canSendChunk = false;
public static ArrayList<String> runners_p = new ArrayList<String>();
public static HashMap<Plot, Integer> runners = new HashMap<Plot, Integer>();
static long state = 1;
@ -697,7 +698,6 @@ public class PlotHelper {
if (canSetFast) {
refreshPlotChunks(world, plot);
// SetBlockFast.update(requester);
}
}
@ -863,12 +863,31 @@ public class PlotHelper {
final int minChunkZ = (int) Math.floor((double) bottomZ / 16);
final int maxChunkZ = (int) Math.floor((double) topZ / 16);
ArrayList<Chunk> chunks = new ArrayList<>();
for (int x = minChunkX; x <= maxChunkX; x++) {
for (int z = minChunkZ; z <= maxChunkZ; 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);
}
}
}
}
/**
* Gets the top plot location of a plot (all plots are treated as small

View File

@ -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<Chunk> 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<Object>) 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)+" | ");
}
}
}
}
}

View File

@ -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<Chunk> chunks = new ArrayList<>();
final int distance = Bukkit.getViewDistance();
for (int cx = -distance; cx < distance; cx++) {
for (int cz = -distance; cz < distance; 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;
}
}
}