mirror of
https://github.com/IntellectualSites/PlotSquared.git
synced 2024-11-25 06:36:44 +01:00
fix: correct reflected fields for chunk needs saving (#4111)
This commit is contained in:
parent
f6cbb3792f
commit
59be582c28
@ -26,6 +26,7 @@ import com.plotsquared.core.plot.Plot;
|
|||||||
import com.plotsquared.core.plot.PlotArea;
|
import com.plotsquared.core.plot.PlotArea;
|
||||||
import com.plotsquared.core.plot.world.PlotAreaManager;
|
import com.plotsquared.core.plot.world.PlotAreaManager;
|
||||||
import com.plotsquared.core.plot.world.SinglePlotArea;
|
import com.plotsquared.core.plot.world.SinglePlotArea;
|
||||||
|
import com.plotsquared.core.util.ReflectionUtils;
|
||||||
import com.plotsquared.core.util.ReflectionUtils.RefClass;
|
import com.plotsquared.core.util.ReflectionUtils.RefClass;
|
||||||
import com.plotsquared.core.util.ReflectionUtils.RefField;
|
import com.plotsquared.core.util.ReflectionUtils.RefField;
|
||||||
import com.plotsquared.core.util.ReflectionUtils.RefMethod;
|
import com.plotsquared.core.util.ReflectionUtils.RefMethod;
|
||||||
@ -64,9 +65,11 @@ public class ChunkListener implements Listener {
|
|||||||
private final PlotAreaManager plotAreaManager;
|
private final PlotAreaManager plotAreaManager;
|
||||||
private final int version;
|
private final int version;
|
||||||
|
|
||||||
|
private RefMethod methodSetUnsaved;
|
||||||
private RefMethod methodGetHandleChunk;
|
private RefMethod methodGetHandleChunk;
|
||||||
private RefMethod methodGetHandleWorld;
|
private RefMethod methodGetHandleWorld;
|
||||||
private RefField mustSave;
|
private RefField mustNotSave;
|
||||||
|
private Object objChunkStatusFull = null;
|
||||||
/*
|
/*
|
||||||
private RefMethod methodGetFullChunk;
|
private RefMethod methodGetFullChunk;
|
||||||
private RefMethod methodGetBukkitChunk;
|
private RefMethod methodGetBukkitChunk;
|
||||||
@ -79,7 +82,6 @@ public class ChunkListener implements Listener {
|
|||||||
*/
|
*/
|
||||||
private Chunk lastChunk;
|
private Chunk lastChunk;
|
||||||
private boolean ignoreUnload = false;
|
private boolean ignoreUnload = false;
|
||||||
private boolean isTrueForNotSave = true;
|
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
public ChunkListener(final @NonNull PlotAreaManager plotAreaManager) {
|
public ChunkListener(final @NonNull PlotAreaManager plotAreaManager) {
|
||||||
@ -90,22 +92,27 @@ public class ChunkListener implements Listener {
|
|||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
RefClass classCraftWorld = getRefClass("{cb}.CraftWorld");
|
RefClass classCraftWorld = getRefClass("{cb}.CraftWorld");
|
||||||
this.methodGetHandleWorld = classCraftWorld.getMethod("getHandle");
|
|
||||||
RefClass classCraftChunk = getRefClass("{cb}.CraftChunk");
|
RefClass classCraftChunk = getRefClass("{cb}.CraftChunk");
|
||||||
|
ReflectionUtils.RefClass classChunkAccess = getRefClass("net.minecraft.world.level.chunk.IChunkAccess");
|
||||||
|
this.methodSetUnsaved = classChunkAccess.getMethod("a", boolean.class);
|
||||||
|
try {
|
||||||
this.methodGetHandleChunk = classCraftChunk.getMethod("getHandle");
|
this.methodGetHandleChunk = classCraftChunk.getMethod("getHandle");
|
||||||
|
} catch (NoSuchMethodException ignored) {
|
||||||
|
try {
|
||||||
|
RefClass classChunkStatus = getRefClass("net.minecraft.world.level.chunk.ChunkStatus");
|
||||||
|
this.objChunkStatusFull = classChunkStatus.getRealClass().getField("n").get(null);
|
||||||
|
this.methodGetHandleChunk = classCraftChunk.getMethod("getHandle", classChunkStatus.getRealClass());
|
||||||
|
} catch (NoSuchMethodException ex) {
|
||||||
|
throw new RuntimeException(ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
try {
|
try {
|
||||||
if (version < 17) {
|
if (version < 17) {
|
||||||
RefClass classChunk = getRefClass("{nms}.Chunk");
|
RefClass classChunk = getRefClass("{nms}.Chunk");
|
||||||
if (version == 13) {
|
this.mustNotSave = classChunk.getField("mustNotSave");
|
||||||
this.mustSave = classChunk.getField("mustSave");
|
|
||||||
this.isTrueForNotSave = false;
|
|
||||||
} else {
|
|
||||||
this.mustSave = classChunk.getField("mustNotSave");
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
RefClass classChunk = getRefClass("net.minecraft.world.level.chunk.Chunk");
|
RefClass classChunk = getRefClass("net.minecraft.world.level.chunk.Chunk");
|
||||||
this.mustSave = classChunk.getField("mustNotSave");
|
this.mustNotSave = classChunk.getField("mustNotSave");
|
||||||
|
|
||||||
}
|
}
|
||||||
} catch (NoSuchFieldException e) {
|
} catch (NoSuchFieldException e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
@ -167,10 +174,13 @@ public class ChunkListener implements Listener {
|
|||||||
if (safe && shouldSave(world, chunk.getX(), chunk.getZ())) {
|
if (safe && shouldSave(world, chunk.getX(), chunk.getZ())) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
Object c = this.methodGetHandleChunk.of(chunk).call();
|
Object c = objChunkStatusFull != null
|
||||||
RefField.RefExecutor field = this.mustSave.of(c);
|
? this.methodGetHandleChunk.of(chunk).call(objChunkStatusFull)
|
||||||
if ((Boolean) field.get() != isTrueForNotSave) {
|
: this.methodGetHandleChunk.of(chunk).call();
|
||||||
field.set(isTrueForNotSave);
|
RefField.RefExecutor field = this.mustNotSave.of(c);
|
||||||
|
methodSetUnsaved.of(c).call(false);
|
||||||
|
if (!((Boolean) field.get())) {
|
||||||
|
field.set(true);
|
||||||
if (chunk.isLoaded()) {
|
if (chunk.isLoaded()) {
|
||||||
ignoreUnload = true;
|
ignoreUnload = true;
|
||||||
chunk.unload(false);
|
chunk.unload(false);
|
||||||
|
@ -31,45 +31,39 @@ import org.bukkit.event.Listener;
|
|||||||
import org.bukkit.event.world.ChunkEvent;
|
import org.bukkit.event.world.ChunkEvent;
|
||||||
import org.bukkit.event.world.ChunkLoadEvent;
|
import org.bukkit.event.world.ChunkLoadEvent;
|
||||||
|
|
||||||
import java.lang.reflect.Field;
|
|
||||||
import java.lang.reflect.Method;
|
import java.lang.reflect.Method;
|
||||||
|
|
||||||
import static com.plotsquared.core.util.ReflectionUtils.getRefClass;
|
import static com.plotsquared.core.util.ReflectionUtils.getRefClass;
|
||||||
|
|
||||||
public class SingleWorldListener implements Listener {
|
public class SingleWorldListener implements Listener {
|
||||||
|
|
||||||
private final Method methodGetHandleChunk;
|
private final Method methodSetUnsaved;
|
||||||
private Field shouldSave = null;
|
private Method methodGetHandleChunk;
|
||||||
|
private Object objChunkStatusFull = null;
|
||||||
|
|
||||||
public SingleWorldListener() throws Exception {
|
public SingleWorldListener() throws Exception {
|
||||||
ReflectionUtils.RefClass classCraftChunk = getRefClass("{cb}.CraftChunk");
|
ReflectionUtils.RefClass classCraftChunk = getRefClass("{cb}.CraftChunk");
|
||||||
this.methodGetHandleChunk = classCraftChunk.getMethod("getHandle").getRealMethod();
|
ReflectionUtils.RefClass classChunkAccess = getRefClass("net.minecraft.world.level.chunk.IChunkAccess");
|
||||||
|
this.methodSetUnsaved = classChunkAccess.getMethod("a", boolean.class).getRealMethod();
|
||||||
try {
|
try {
|
||||||
if (PlotSquared.platform().serverVersion()[1] < 17) {
|
this.methodGetHandleChunk = classCraftChunk.getMethod("getHandle").getRealMethod();
|
||||||
ReflectionUtils.RefClass classChunk = getRefClass("{nms}.Chunk");
|
} catch (NoSuchMethodException ignored) {
|
||||||
if (PlotSquared.platform().serverVersion()[1] == 13) {
|
try {
|
||||||
this.shouldSave = classChunk.getField("mustSave").getRealField();
|
ReflectionUtils.RefClass classChunkStatus = getRefClass("net.minecraft.world.level.chunk.ChunkStatus");
|
||||||
} else {
|
this.objChunkStatusFull = classChunkStatus.getRealClass().getField("n").get(null);
|
||||||
this.shouldSave = classChunk.getField("s").getRealField();
|
this.methodGetHandleChunk = classCraftChunk.getMethod("getHandle", classChunkStatus.getRealClass()).getRealMethod();
|
||||||
|
} catch (NoSuchMethodException ex) {
|
||||||
|
throw new RuntimeException(ex);
|
||||||
}
|
}
|
||||||
} else if (PlotSquared.platform().serverVersion()[1] == 17) {
|
|
||||||
ReflectionUtils.RefClass classChunk = getRefClass("net.minecraft.world.level.chunk.Chunk");
|
|
||||||
this.shouldSave = classChunk.getField("r").getRealField();
|
|
||||||
} else if (PlotSquared.platform().serverVersion()[1] == 18) {
|
|
||||||
ReflectionUtils.RefClass classChunk = getRefClass("net.minecraft.world.level.chunk.IChunkAccess");
|
|
||||||
this.shouldSave = classChunk.getField("b").getRealField();
|
|
||||||
}
|
|
||||||
} catch (NoSuchFieldException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void markChunkAsClean(Chunk chunk) {
|
public void markChunkAsClean(Chunk chunk) {
|
||||||
try {
|
try {
|
||||||
Object nmsChunk = methodGetHandleChunk.invoke(chunk);
|
Object nmsChunk = objChunkStatusFull != null
|
||||||
if (shouldSave != null) {
|
? this.methodGetHandleChunk.invoke(chunk, objChunkStatusFull)
|
||||||
this.shouldSave.set(nmsChunk, false);
|
: this.methodGetHandleChunk.invoke(chunk);
|
||||||
}
|
methodSetUnsaved.invoke(nmsChunk, false);
|
||||||
} catch (Throwable e) {
|
} catch (Throwable e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
@ -85,7 +79,12 @@ public class SingleWorldListener implements Listener {
|
|||||||
if (!SinglePlotArea.isSinglePlotWorld(name)) {
|
if (!SinglePlotArea.isSinglePlotWorld(name)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
int x = event.getChunk().getX();
|
||||||
|
int z = event.getChunk().getZ();
|
||||||
|
if (x < 16 && x > -16 && z < 16 && z > -16) {
|
||||||
|
// Allow spawn to generate
|
||||||
|
return;
|
||||||
|
}
|
||||||
markChunkAsClean(event.getChunk());
|
markChunkAsClean(event.getChunk());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user