diff --git a/phider.iml b/phider.iml
new file mode 100644
index 0000000..5cd848e
--- /dev/null
+++ b/phider.iml
@@ -0,0 +1,38 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/pom.xml b/pom.xml
new file mode 100644
index 0000000..0e08f65
--- /dev/null
+++ b/pom.xml
@@ -0,0 +1,87 @@
+
+
+ 4.0.0
+ com.boydti
+ phider
+ 1
+ jar
+
+ PlotHider
+
+
+
+
+ src/main/resources
+
+ true
+
+ plugin.yml
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-compiler-plugin
+ 3.8.0
+
+ 1.8
+ 1.8
+
+
+
+
+
+
+ UTF-8
+
+
+
+
+ spigot-repo
+ https://hub.spigotmc.org/nexus/content/repositories/snapshots/
+
+
+ p2-repo
+ https://incendo.org/mvn/
+
+
+ dmulloy2-repo
+ http://repo.dmulloy2.net/nexus/repository/public/
+
+
+ sk89q-repo
+ http://maven.sk89q.com/artifactory/repo/
+
+
+
+
+
+ org.spigotmc
+ spigot-api
+ 1.13.2-R0.1-SNAPSHOT
+
+
+ org.bukkit
+ craftbukkit
+ 1.13.2-R0.1-SNAPSHOT
+
+
+ com.github.intellectualsites.plotsquared
+ PlotSquared
+ 4
+
+
+ com.github.intellectualsites.plotsquared
+ PlotSquared
+ Bukkit
+ 4
+
+
+ com.comphenix.protocol
+ ProtocolLib
+ 4.4.0
+
+
+
diff --git a/src/com/boydti/phider/FlexibleStorage.java b/src/com/boydti/phider/FlexibleStorage.java
deleted file mode 100644
index 3cf9a8b..0000000
--- a/src/com/boydti/phider/FlexibleStorage.java
+++ /dev/null
@@ -1,105 +0,0 @@
-package com.boydti.phider;
-
-import java.util.Arrays;
-
-public class FlexibleStorage {
- private final long[] data;
- private final int bitsPerEntry;
- private final int size;
- private final long maxEntryValue;
-
- public FlexibleStorage(int bitsPerEntry, int size) {
- this(bitsPerEntry, new long[roundToNearest(size * bitsPerEntry, 64) / 64]);
- }
-
- public FlexibleStorage(int bitsPerEntry, long[] data) {
- if (bitsPerEntry < 1 || bitsPerEntry > 32) {
- throw new IllegalArgumentException("BitsPerEntry cannot be outside of accepted range.");
- }
-
- this.bitsPerEntry = bitsPerEntry;
- this.data = data;
-
- this.size = this.data.length * 64 / this.bitsPerEntry;
- this.maxEntryValue = (1L << this.bitsPerEntry) - 1;
- }
-
- public long[] getData() {
- return this.data;
- }
-
- public int getBitsPerEntry() {
- return this.bitsPerEntry;
- }
-
- public int getSize() {
- return this.size;
- }
-
- public int get(int index) {
- if (index < 0 || index > this.size - 1) {
- throw new IndexOutOfBoundsException();
- }
-
- int bitIndex = index * this.bitsPerEntry;
- int startIndex = bitIndex / 64;
- int endIndex = ((index + 1) * this.bitsPerEntry - 1) / 64;
- int startBitSubIndex = bitIndex % 64;
- if (startIndex == endIndex) {
- return (int) (this.data[startIndex] >>> startBitSubIndex & this.maxEntryValue);
- } else {
- int endBitSubIndex = 64 - startBitSubIndex;
- return (int) ((this.data[startIndex] >>> startBitSubIndex | this.data[endIndex] << endBitSubIndex) & this.maxEntryValue);
- }
- }
-
- public void set(int index, int value) {
- if (index < 0 || index > this.size - 1) {
- throw new IndexOutOfBoundsException();
- }
-
- if (value < 0 || value > this.maxEntryValue) {
- throw new IllegalArgumentException("Value cannot be outside of accepted range.");
- }
-
- int bitIndex = index * this.bitsPerEntry;
- int startIndex = bitIndex / 64;
- int endIndex = ((index + 1) * this.bitsPerEntry - 1) / 64;
- int startBitSubIndex = bitIndex % 64;
- this.data[startIndex] = this.data[startIndex] & ~(this.maxEntryValue << startBitSubIndex) | (value & this.maxEntryValue) << startBitSubIndex;
- if (startIndex != endIndex) {
- int endBitSubIndex = 64 - startBitSubIndex;
- this.data[endIndex] = this.data[endIndex] >>> endBitSubIndex << endBitSubIndex | (value & this.maxEntryValue) >> endBitSubIndex;
- }
- }
-
- private static int roundToNearest(int value, int roundTo) {
- if (roundTo == 0) {
- return 0;
- } else if (value == 0) {
- return roundTo;
- } else {
- if (value < 0) {
- roundTo *= -1;
- }
-
- int remainder = value % roundTo;
- return remainder != 0 ? value + roundTo - remainder : value;
- }
- }
-
- @Override
- public boolean equals(Object o) {
- return this == o
- || (o instanceof FlexibleStorage && Arrays.equals(this.data, ((FlexibleStorage) o).data) && this.bitsPerEntry == ((FlexibleStorage) o).bitsPerEntry && this.size == ((FlexibleStorage) o).size && this.maxEntryValue == ((FlexibleStorage) o).maxEntryValue);
- }
-
- @Override
- public int hashCode() {
- int result = Arrays.hashCode(this.data);
- result = 31 * result + this.bitsPerEntry;
- result = 31 * result + this.size;
- result = 31 * result + (int) this.maxEntryValue;
- return result;
- }
-}
diff --git a/src/com/boydti/phider/PacketHandler.java b/src/com/boydti/phider/PacketHandler.java
deleted file mode 100644
index 6990135..0000000
--- a/src/com/boydti/phider/PacketHandler.java
+++ /dev/null
@@ -1,220 +0,0 @@
-package com.boydti.phider;
-
-import java.io.ByteArrayOutputStream;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Iterator;
-import java.util.List;
-
-import org.bukkit.entity.Player;
-
-import com.comphenix.protocol.PacketType;
-import com.comphenix.protocol.ProtocolLibrary;
-import com.comphenix.protocol.ProtocolManager;
-import com.comphenix.protocol.events.ListenerPriority;
-import com.comphenix.protocol.events.PacketAdapter;
-import com.comphenix.protocol.events.PacketContainer;
-import com.comphenix.protocol.events.PacketEvent;
-import com.comphenix.protocol.reflect.StructureModifier;
-import com.comphenix.protocol.wrappers.BlockPosition;
-import com.comphenix.protocol.wrappers.ChunkCoordIntPair;
-import com.comphenix.protocol.wrappers.MultiBlockChangeInfo;
-import com.intellectualcrafters.plot.PS;
-import com.intellectualcrafters.plot.object.Location;
-import com.intellectualcrafters.plot.object.Plot;
-import com.intellectualcrafters.plot.object.PlotArea;
-import com.intellectualcrafters.plot.object.PlotBlock;
-import com.intellectualcrafters.plot.object.PlotPlayer;
-import com.intellectualcrafters.plot.util.Permissions;
-import com.plotsquared.bukkit.util.BukkitUtil;
-
-public class PacketHandler {
- public static ProtocolManager manager;
-
- public PacketHandler(Main main) {
- manager = ProtocolLibrary.getProtocolManager();
- manager.addPacketListener(new PacketAdapter(main, ListenerPriority.NORMAL, PacketType.Play.Server.BLOCK_CHANGE) {
- @Override
- public void onPacketSending(PacketEvent event) {
- Player player = event.getPlayer();
- PlotPlayer pp = BukkitUtil.getPlayer(player);
- if (Permissions.hasPermission(pp, "plots.plothider.bypass")) { // Admin bypass
- return;
- }
- String world = pp.getLocation().getWorld();
- if (!PS.get().hasPlotArea(world)) { // Not a plot area
- return;
- }
- PacketContainer packet = event.getPacket();
- StructureModifier positions = packet.getBlockPositionModifier();
- BlockPosition position = positions.read(0);
- Location loc = new Location(world, position.getX(), 0, position.getZ());
- Plot plot = loc.getOwnedPlot();
- if (plot != null && (plot.isDenied(pp.getUUID()) || (!plot.isAdded(pp.getUUID()) && Main.HIDE_FLAG.isTrue(plot)))) {
- event.setCancelled(true);
- }
- }
- });
-
- manager.addPacketListener(new PacketAdapter(main, ListenerPriority.NORMAL, PacketType.Play.Server.MULTI_BLOCK_CHANGE) {
- @Override
- public void onPacketSending(PacketEvent event) {
- Player player = event.getPlayer();
- PlotPlayer pp = BukkitUtil.getPlayer(player);
- if (Permissions.hasPermission(pp, "plots.plothider.bypass")) { // Admin bypass
- return;
- }
- String world = pp.getLocation().getWorld();
- if (!PS.get().hasPlotArea(world)) { // Not a plot area
- return;
- }
- PacketContainer packet = event.getPacket();
- StructureModifier chunkArray = packet.getChunkCoordIntPairs();
- ChunkCoordIntPair chunk = chunkArray.read(0);
- int cx = chunk.getChunkX();
- int cz = chunk.getChunkZ();
- int bx = cx << 4;
- int bz = cz << 4;
- Location corner1 = new Location(world, bx, 0, bz);
- Location corner2 = new Location(world, bx + 15, 0, bz);
- Location corner3 = new Location(world, bx, 0, bz + 15);
- Location corner4 = new Location(world, bx + 15, 0, bz + 15);
- Plot plot1 = corner1.getOwnedPlot();
- Plot plot2 = corner2.getOwnedPlot();
- Plot plot3 = corner3.getOwnedPlot();
- Plot plot4 = corner4.getOwnedPlot();
- plot1 = (plot1 != null && (plot1.isDenied(pp.getUUID()) || (!plot1.isAdded(pp.getUUID()) && Main.HIDE_FLAG.isTrue(plot1)))) ? plot1 : null;
- plot2 = (plot2 != null && (plot2.isDenied(pp.getUUID()) || (!plot2.isAdded(pp.getUUID()) && Main.HIDE_FLAG.isTrue(plot2)))) ? plot2 : null;
- plot3 = (plot3 != null && (plot3.isDenied(pp.getUUID()) || (!plot3.isAdded(pp.getUUID()) && Main.HIDE_FLAG.isTrue(plot3)))) ? plot3 : null;
- plot4 = (plot4 != null && (plot4.isDenied(pp.getUUID()) || (!plot4.isAdded(pp.getUUID()) && Main.HIDE_FLAG.isTrue(plot4)))) ? plot4 : null;
- if (plot1 == null && plot2 == null && plot3 == null && plot4 == null) { // No plots to hide
- return;
- }
- StructureModifier changeArray = packet.getMultiBlockChangeInfoArrays();
- if (plot1 == plot4 && plot1 != null) { // Not allowed to see the entire chunk
- event.setCancelled(true);
- return;
- }
- // Hide some of the blocks (but maybe not all)
- List changes = new ArrayList<>(Arrays.asList(changeArray.read(0)));
- Iterator iter = changes.iterator();
- Plot denied = plot1 != null ? plot1 : plot2 != null ? plot2 : plot3 != null ? plot3 : plot4;
- PlotArea area = denied.getArea();
- while (iter.hasNext()) {
- MultiBlockChangeInfo change = iter.next();
- int x = change.getAbsoluteX();
- int z = change.getAbsoluteZ();
- Plot current = area.getOwnedPlot(new Location(world, x, 0, z));
- if (current == null) {
- continue;
- }
- if (current == plot1 || current == plot2 || current == plot3 || current == plot4) {
- iter.remove();
- }
- }
- if (changes.size() == 0) {
- event.setCancelled(true);
- return;
- }
- changeArray.write(0, changes.toArray(new MultiBlockChangeInfo[changes.size()]));
- event.setPacket(packet);
- }
- });
-
- manager.addPacketListener(new PacketAdapter(main, ListenerPriority.NORMAL, PacketType.Play.Server.MAP_CHUNK) {
- @Override
- public void onPacketSending(PacketEvent event) {
- Player player = event.getPlayer();
- PlotPlayer pp = BukkitUtil.getPlayer(player);
- if (Permissions.hasPermission(pp, "plots.plothider.bypass")) { // Admin bypass
- return;
- }
- String world = pp.getLocation().getWorld();
- if (!PS.get().hasPlotArea(world)) { // Not a plot area
- return;
- }
- PacketContainer packet = event.getPacket();
- StructureModifier ints = packet.getIntegers();
- StructureModifier byteArray = packet.getByteArrays();
- int cx = ints.read(0);
- int cz = ints.read(1);
- int bx = cx << 4;
- int bz = cz << 4;
- Location corner1 = new Location(world, bx, 0, bz);
- Location corner2 = new Location(world, bx + 15, 0, bz);
- Location corner3 = new Location(world, bx, 0, bz + 15);
- Location corner4 = new Location(world, bx + 15, 0, bz + 15);
- Plot plot1 = corner1.getOwnedPlot();
- Plot plot2 = corner2.getOwnedPlot();
- Plot plot3 = corner3.getOwnedPlot();
- Plot plot4 = corner4.getOwnedPlot();
- plot1 = (plot1 != null && (plot1.isDenied(pp.getUUID()) || (!plot1.isAdded(pp.getUUID()) && Main.HIDE_FLAG.isTrue(plot1)))) ? plot1 : null;
- plot2 = (plot2 != null && (plot2.isDenied(pp.getUUID()) || (!plot2.isAdded(pp.getUUID()) && Main.HIDE_FLAG.isTrue(plot2)))) ? plot2 : null;
- plot3 = (plot3 != null && (plot3.isDenied(pp.getUUID()) || (!plot3.isAdded(pp.getUUID()) && Main.HIDE_FLAG.isTrue(plot3)))) ? plot3 : null;
- plot4 = (plot4 != null && (plot4.isDenied(pp.getUUID()) || (!plot4.isAdded(pp.getUUID()) && Main.HIDE_FLAG.isTrue(plot4)))) ? plot4 : null;
- if (plot1 == null && plot2 == null && plot3 == null && plot4 == null) { // No plots to hide
- return;
- }
- if (plot1 == plot4 && plot1 != null) { // Not allowed to see the entire chunk
- byteArray.write(0, new byte[0]);
- event.setPacket(packet);
- return;
- }
- // Not allowed to see part of the chunk
- Plot denied = plot1 != null ? plot1 : plot2 != null ? plot2 : plot3 != null ? plot3 : plot4;
- PlotArea area = denied.getArea();
- PlotBlock AIR = new PlotBlock((short) 0, (byte) 0);
- byte[] sections = byteArray.read(0);
- int size = sections.length;
- try {
- byte[] biomes = Arrays.copyOfRange(sections, sections.length - 256, sections.length);
- sections = Arrays.copyOfRange(sections, 0, sections.length - 256);
- List array = new ArrayList<>();
- while (sections.length > 0) {
- if (sections[0] < 0) {
- break;
- }
- BlockStorage storage = new BlockStorage(sections);
- array.add(storage);
- sections = Arrays.copyOfRange(sections, Math.min(storage.getSize() + storage.getLight().length, sections.length), sections.length);
- }
- // Trim chunk
- for (int x = 0; x < 16; x++) {
- for (int z = 0; z < 16; z++) {
- Location loc = new Location(world, bx + x, 0, bz + z);
- Plot current = area.getOwnedPlot(loc);
- if (current == null) {
- continue;
- }
- if (current == plot1 || current == plot2 || current == plot3 || current == plot4) {
- for (BlockStorage section : array) {
- for (int y = 0; y < 16; y++) {
- if (section.get(x, y, z).id != 0) {
- section.set(x, y, z, AIR);
- }
- }
- }
- }
- }
- }
- // Write
- {
- ByteArrayOutputStream baos = new ByteArrayOutputStream(size);
- for (BlockStorage section : array) {
- section.write(baos);
- }
- baos.write(sections);
- baos.write(biomes);
- byteArray.write(0, baos.toByteArray());
- event.setPacket(packet);
- }
-
- } catch (Throwable e) {
- e.printStackTrace();
- }
-
-
- }
- });
- }
-}
diff --git a/src/com/boydti/phider/BlockStorage.java b/src/main/java/com/boydti/phider/BlockStorage.java
similarity index 69%
rename from src/com/boydti/phider/BlockStorage.java
rename to src/main/java/com/boydti/phider/BlockStorage.java
index db3d397..ead9e2d 100644
--- a/src/com/boydti/phider/BlockStorage.java
+++ b/src/main/java/com/boydti/phider/BlockStorage.java
@@ -5,48 +5,43 @@
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
+import java.util.LinkedList;
import java.util.List;
import org.apache.commons.lang.mutable.MutableInt;
-import com.intellectualcrafters.plot.object.PlotBlock;
-
public class BlockStorage {
- private static final PlotBlock AIR = new PlotBlock((short) 0, (byte) 0);
-
+ private static final Integer AIR = 0x00;
+
private int bitsPerEntry;
-
- private final List states;
+
+ private final List states;
private FlexibleStorage storage;
private final byte[] light;
private final int size;
-
- public BlockStorage(byte[] in) throws IOException {
+
+ public BlockStorage(byte[] in, boolean sky) {
MutableInt mut = new MutableInt();
this.bitsPerEntry = readUnsigned(in, mut);
-
- this.states = new ArrayList();
-
+
+ this.states = new LinkedList<>();
+
int stateCount = readVarInt(in, mut);
-
+
for (int i = 0; i < stateCount; i++) {
- this.states.add(readPlotBlock(in, mut));
+ this.states.add(readVarInt(in, mut));
}
-
+
int expected = readVarInt(in, mut);
this.storage = new FlexibleStorage(this.bitsPerEntry, readLongs(in, mut, expected));
- if (in[mut.intValue()] == 0) {
- this.light = Arrays.copyOfRange(in, mut.intValue(), mut.intValue() + 4096);
- } else {
- this.light = new byte[0];
- }
+ this.light = Arrays.copyOfRange(in, mut.intValue(), in.length);
this.size = mut.intValue();
}
-
+
public byte[] getLight() {
return light;
}
-
+
public int getSize() {
return size;
}
@@ -56,89 +51,81 @@ public byte[] write() throws IOException {
write(out);
return out.toByteArray();
}
-
+
public void write(ByteArrayOutputStream out) throws IOException {
long[] data = this.storage.getData();
out.write(this.bitsPerEntry);
writeVarInt(out, this.states.size());
- for (PlotBlock state : this.states) {
- writeBlockState(out, state);
+ for (int state : this.states) {
+ writeVarInt(out, state);
}
writeVarInt(out, data.length);
writeLongs(out, data);
out.write(light);
}
-
+
public int getBitsPerEntry() {
return this.bitsPerEntry;
}
-
- public List getStates() {
+
+ public List getStates() {
return Collections.unmodifiableList(this.states);
}
-
+
public FlexibleStorage getStorage() {
return this.storage;
}
-
- public PlotBlock get(int x, int y, int z) {
+
+ public int get(int x, int y, int z) {
int id = this.storage.get(index(x, y, z));
- return this.bitsPerEntry <= 8 ? (id >= 0 && id < this.states.size() ? this.states.get(id) : AIR) : rawToState(id);
+ return this.bitsPerEntry <= 8 ? (id >= 0 && id < this.states.size() ? this.states.get(id) : AIR) : id;
}
-
- public void set(int x, int y, int z, PlotBlock state) {
- int id = this.bitsPerEntry <= 8 ? (state.id == 0 ? 0 : this.states.indexOf(state)) : stateToRaw(state);
+
+ public void set(int x, int y, int z, int state) {
+ int id = this.bitsPerEntry <= 8 ? (state == 0 ? 0 : this.states.indexOf(state)) : state;
if (id == -1) {
this.states.add(state);
if (this.states.size() > 1 << this.bitsPerEntry) {
this.bitsPerEntry++;
-
- List oldStates = this.states;
+
+ List oldStates = this.states;
if (this.bitsPerEntry > 8) {
- oldStates = new ArrayList(this.states);
+ oldStates = new ArrayList<>(this.states);
this.states.clear();
- this.bitsPerEntry = 13;
+ this.bitsPerEntry = 14;
}
-
+
FlexibleStorage oldStorage = this.storage;
this.storage = new FlexibleStorage(this.bitsPerEntry, this.storage.getSize());
for (int index = 0; index < this.storage.getSize(); index++) {
- this.storage.set(index, this.bitsPerEntry <= 8 ? oldStorage.get(index) : stateToRaw(oldStates.get(index)));
+ this.storage.set(index, this.bitsPerEntry <= 8 ? oldStorage.get(index) : oldStates.get(index));
}
}
-
- id = this.bitsPerEntry <= 8 ? this.states.indexOf(state) : stateToRaw(state);
+
+ id = this.bitsPerEntry <= 8 ? this.states.indexOf(state) : state;
}
this.storage.set(index(x, y, z), id);
}
-
+
public boolean isEmpty() {
for (int index = 0; index < this.storage.getSize(); index++) {
if (this.storage.get(index) != 0) {
return false;
}
}
-
+
return true;
}
-
+
private static int index(int x, int y, int z) {
return y << 8 | z << 4 | (x);
}
-
- private static PlotBlock rawToState(int raw) {
- return new PlotBlock((short) (raw >> 4), (byte) (raw & 0xF));
- }
-
- private static int stateToRaw(PlotBlock state) {
- return (state.id << 4) | (state.data & 0xF);
- }
-
+
@Override
public boolean equals(Object o) {
return o instanceof BlockStorage && this.bitsPerEntry == ((BlockStorage) o).bitsPerEntry && this.states.equals(((BlockStorage) o).states) && this.storage.equals(((BlockStorage) o).storage);
}
-
+
@Override
public int hashCode() {
int result = this.bitsPerEntry;
@@ -146,19 +133,19 @@ public int hashCode() {
result = 31 * result + this.storage.hashCode();
return result;
}
-
+
public byte read(byte[] bytes, MutableInt index) {
byte value = bytes[index.intValue()];
index.increment();
return value;
}
-
+
public int readUnsigned(byte[] bytes, MutableInt index) {
byte value = bytes[index.intValue()];
index.increment();
return value & 0xFF;
}
-
+
public long readLong(byte[] bytes, MutableInt index) {
long value = 0;
for (int i = 0, j = 56; i < 8; i++, j -= 8) {
@@ -167,7 +154,7 @@ public long readLong(byte[] bytes, MutableInt index) {
index.add(8);
return value;
}
-
+
public int readVarInt(byte[] bytes, MutableInt index) {
int value = 0;
int size = 0;
@@ -178,48 +165,39 @@ public int readVarInt(byte[] bytes, MutableInt index) {
return 1 / 0;
}
}
-
+
return value | ((b & 0x7F) << (size * 7));
}
-
- public long[] readLongs(byte[] bytes, MutableInt mut, int length) throws IOException {
+
+ public long[] readLongs(byte[] bytes, MutableInt mut, int length) {
if (length < 0) {
throw new IllegalArgumentException("Array cannot have length less than 0.");
}
-
+
long l[] = new long[length];
for (int index = 0; index < length; index++) {
l[index] = readLong(bytes, mut);
}
-
+
return l;
}
- public PlotBlock readPlotBlock(byte[] bytes, MutableInt index) {
- int rawId = readVarInt(bytes, index);
- return new PlotBlock((short) (rawId >> 4), (byte) (rawId & 0xF));
- }
-
- public void writeVarInt(ByteArrayOutputStream out, int i) throws IOException {
+ public void writeVarInt(ByteArrayOutputStream out, int i) {
while ((i & ~0x7F) != 0) {
out.write((i & 0x7F) | 0x80);
i >>>= 7;
}
-
+
out.write(i);
}
-
- public void writeBlockState(ByteArrayOutputStream out, PlotBlock blockState) throws IOException {
- writeVarInt(out, (blockState.id << 4) | (blockState.data & 0xF));
- }
-
- public void writeLongs(ByteArrayOutputStream out, long[] l) throws IOException {
+
+ public void writeLongs(ByteArrayOutputStream out, long[] l) {
for (int index = 0; index < l.length; index++) {
writeLong(out, l[index]);
}
}
-
- public void writeLong(ByteArrayOutputStream out, long l) throws IOException {
+
+ public void writeLong(ByteArrayOutputStream out, long l) {
out.write((byte) (l >>> 56));
out.write((byte) (l >>> 48));
out.write((byte) (l >>> 40));
diff --git a/src/main/java/com/boydti/phider/FlexibleStorage.java b/src/main/java/com/boydti/phider/FlexibleStorage.java
new file mode 100644
index 0000000..55f3c58
--- /dev/null
+++ b/src/main/java/com/boydti/phider/FlexibleStorage.java
@@ -0,0 +1,101 @@
+package com.boydti.phider;
+
+import java.util.Arrays;
+
+public class FlexibleStorage {
+ private final long[] data;
+ private final int bitsPerEntry;
+ private final int size;
+ private final long maxEntryValue;
+
+ FlexibleStorage(int bitsPerEntry, int size) {
+ this(bitsPerEntry, new long[roundToNearest(size * bitsPerEntry, 64) / 64]);
+ }
+
+ FlexibleStorage(int bitsPerEntry, long[] data) {
+ if ((bitsPerEntry < 1) || (bitsPerEntry > 32)) {
+ throw new IllegalArgumentException(
+ "BitsPerEntry cannot be outside of accepted range. " + bitsPerEntry);
+ }
+ this.bitsPerEntry = bitsPerEntry;
+ this.data = data;
+
+ this.size = (this.data.length * 64 / this.bitsPerEntry);
+ this.maxEntryValue = ((1L << this.bitsPerEntry) - 1L);
+ }
+
+ private static int roundToNearest(int value, int roundTo) {
+ if (roundTo == 0) {
+ return 0;
+ }
+ if (value == 0) {
+ return roundTo;
+ }
+ if (value < 0) {
+ roundTo *= -1;
+ }
+ int remainder = value % roundTo;
+ return remainder != 0 ? value + roundTo - remainder : value;
+ }
+
+ long[] getData() {
+ return this.data;
+ }
+
+ int getSize() {
+ return this.size;
+ }
+
+ int get(int index) {
+ if ((index < 0) || (index > this.size - 1)) {
+ throw new IndexOutOfBoundsException();
+ }
+ int bitIndex = index * this.bitsPerEntry;
+ int startIndex = bitIndex / 64;
+ int endIndex = ((index + 1) * this.bitsPerEntry - 1) / 64;
+ int startBitSubIndex = bitIndex % 64;
+ if (startIndex == endIndex) {
+ return (int) (this.data[startIndex] >>> startBitSubIndex & this.maxEntryValue);
+ }
+ int endBitSubIndex = 64 - startBitSubIndex;
+ return (int) (
+ (this.data[startIndex] >>> startBitSubIndex | this.data[endIndex] << endBitSubIndex)
+ & this.maxEntryValue);
+ }
+
+ void set(int index, int value) {
+ if ((index < 0) || (index > this.size - 1)) {
+ throw new IndexOutOfBoundsException();
+ }
+ if ((value < 0) || (value > this.maxEntryValue)) {
+ throw new IllegalArgumentException("Value cannot be outside of accepted range.");
+ }
+ int bitIndex = index * this.bitsPerEntry;
+ int startIndex = bitIndex / 64;
+ int endIndex = ((index + 1) * this.bitsPerEntry - 1) / 64;
+ int startBitSubIndex = bitIndex % 64;
+ this.data[startIndex] =
+ (this.data[startIndex] & ~(this.maxEntryValue << startBitSubIndex)
+ | (value & this.maxEntryValue) << startBitSubIndex);
+ if (startIndex != endIndex) {
+ int endBitSubIndex = 64 - startBitSubIndex;
+ this.data[endIndex] = (this.data[endIndex] >>> endBitSubIndex << endBitSubIndex
+ | (value & this.maxEntryValue) >> endBitSubIndex);
+ }
+ }
+
+ public boolean equals(Object o) {
+ return (this == o) || (((o instanceof FlexibleStorage)) && (Arrays
+ .equals(this.data, ((FlexibleStorage) o).data)) && (this.bitsPerEntry
+ == ((FlexibleStorage) o).bitsPerEntry) && (this.size == ((FlexibleStorage) o).size) && (
+ this.maxEntryValue == ((FlexibleStorage) o).maxEntryValue));
+ }
+
+ public int hashCode() {
+ int result = Arrays.hashCode(this.data);
+ result = 31 * result + this.bitsPerEntry;
+ result = 31 * result + this.size;
+ result = 31 * result + (int) this.maxEntryValue;
+ return result;
+ }
+}
diff --git a/src/com/boydti/phider/Main.java b/src/main/java/com/boydti/phider/Main.java
similarity index 54%
rename from src/com/boydti/phider/Main.java
rename to src/main/java/com/boydti/phider/Main.java
index 86bc7c0..acec655 100644
--- a/src/com/boydti/phider/Main.java
+++ b/src/main/java/com/boydti/phider/Main.java
@@ -1,5 +1,11 @@
package com.boydti.phider;
+import com.github.intellectualsites.plotsquared.bukkit.util.BukkitUtil;
+import com.github.intellectualsites.plotsquared.plot.flag.BooleanFlag;
+import com.github.intellectualsites.plotsquared.plot.flag.Flags;
+import com.github.intellectualsites.plotsquared.plot.object.Plot;
+import com.github.intellectualsites.plotsquared.plot.object.PlotPlayer;
+import com.github.intellectualsites.plotsquared.plot.util.Permissions;
import org.bukkit.Bukkit;
import org.bukkit.Location;
import org.bukkit.entity.Player;
@@ -8,42 +14,32 @@
import org.bukkit.event.player.PlayerTeleportEvent;
import org.bukkit.plugin.java.JavaPlugin;
-import com.intellectualcrafters.plot.flag.BooleanFlag;
-import com.intellectualcrafters.plot.flag.Flags;
-import com.intellectualcrafters.plot.object.Plot;
-import com.intellectualcrafters.plot.object.PlotPlayer;
-import com.intellectualcrafters.plot.util.Permissions;
-import com.plotsquared.bukkit.util.BukkitUtil;
-
public class Main extends JavaPlugin implements Listener {
-
+
public static BooleanFlag HIDE_FLAG = new BooleanFlag("hide");
- @Override
public void onEnable() {
new PacketHandler(this);
Bukkit.getPluginManager().registerEvents(this, this);
Flags.registerFlag(HIDE_FLAG);
}
-
- @EventHandler
- public void onTeleport(PlayerTeleportEvent event) {
- final Player player = event.getPlayer();
- final PlotPlayer pp = BukkitUtil.getPlayer(player);
- if (Permissions.hasPermission(pp, "plots.plothider.bypass")) { // Admin bypass
+
+ @EventHandler public void onTeleport(PlayerTeleportEvent event) {
+ Player player = event.getPlayer();
+ PlotPlayer pp = BukkitUtil.getPlayer(player);
+ if (Permissions.hasPermission(pp, "plots.plothider.bypass")) {
return;
}
Plot plot = pp.getCurrentPlot();
- if (plot != null && (plot.isDenied(pp.getUUID()) || (!plot.isAdded(pp.getUUID()) && HIDE_FLAG.isTrue(plot)))) {
+ if ((plot != null) && ((plot.isDenied(pp.getUUID())) || ((!plot.isAdded(pp.getUUID()))
+ && (HIDE_FLAG.isTrue(plot))))) {
Location to = event.getTo();
Location from = event.getFrom();
- if (to.getWorld().equals(from.getWorld()) && to.distanceSquared(from) < 8) {
+ if ((to.getWorld().equals(from.getWorld())) && (to.distanceSquared(from) < 8.0D)) {
event.setTo(player.getLocation());
event.setCancelled(true);
player.setVelocity(player.getVelocity());
}
}
}
-
-
}
diff --git a/src/main/java/com/boydti/phider/PacketHandler.java b/src/main/java/com/boydti/phider/PacketHandler.java
new file mode 100644
index 0000000..22cb3fc
--- /dev/null
+++ b/src/main/java/com/boydti/phider/PacketHandler.java
@@ -0,0 +1,278 @@
+package com.boydti.phider;
+
+import com.comphenix.protocol.PacketType;
+import com.comphenix.protocol.ProtocolLibrary;
+import com.comphenix.protocol.ProtocolManager;
+import com.comphenix.protocol.events.ListenerPriority;
+import com.comphenix.protocol.events.PacketAdapter;
+import com.comphenix.protocol.events.PacketContainer;
+import com.comphenix.protocol.events.PacketEvent;
+import com.comphenix.protocol.reflect.StructureModifier;
+import com.comphenix.protocol.wrappers.BlockPosition;
+import com.comphenix.protocol.wrappers.ChunkCoordIntPair;
+import com.comphenix.protocol.wrappers.MultiBlockChangeInfo;
+import com.comphenix.protocol.wrappers.nbt.NbtBase;
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Iterator;
+import java.util.List;
+
+import com.github.intellectualsites.plotsquared.bukkit.util.BukkitUtil;
+import com.github.intellectualsites.plotsquared.plot.PlotSquared;
+import com.github.intellectualsites.plotsquared.plot.object.Location;
+import com.github.intellectualsites.plotsquared.plot.object.Plot;
+import com.github.intellectualsites.plotsquared.plot.object.PlotArea;
+import com.github.intellectualsites.plotsquared.plot.object.PlotPlayer;
+import com.github.intellectualsites.plotsquared.plot.util.Permissions;
+import org.bukkit.Bukkit;
+import org.bukkit.World;
+import org.bukkit.entity.Player;
+
+public class PacketHandler {
+ PacketHandler(Main main) {
+ ProtocolManager manager = ProtocolLibrary.getProtocolManager();
+ manager.addPacketListener(
+ new PacketAdapter(main, ListenerPriority.NORMAL, PacketType.Play.Server.BLOCK_CHANGE) {
+ public void onPacketSending(PacketEvent event) {
+ Player player = event.getPlayer();
+ PlotPlayer pp = BukkitUtil.getPlayer(player);
+ if (Permissions.hasPermission(pp, "plots.plothider.bypass")) { // Admin bypass
+ return;
+ }
+ String world = pp.getLocation().getWorld();
+ if (!PlotSquared.get().hasPlotArea(world)) { // Not a plot area
+ return;
+ }
+ PacketContainer packet = event.getPacket();
+ StructureModifier positions = packet.getBlockPositionModifier();
+ BlockPosition position = positions.read(0);
+ Location loc = new Location(world, position.getX(), 0, position.getZ());
+ Plot plot = loc.getOwnedPlot();
+ if (plot != null && (plot.isDenied(pp.getUUID()) || (!plot.isAdded(pp.getUUID()) && Main.HIDE_FLAG.isTrue(plot)))) {
+ event.setCancelled(true);
+ }
+ }
+ });
+
+ manager.addPacketListener(new PacketAdapter(main, ListenerPriority.NORMAL,
+ PacketType.Play.Server.MULTI_BLOCK_CHANGE) {
+ @Override
+ public void onPacketSending(PacketEvent event) {
+ Player player = event.getPlayer();
+ PlotPlayer pp = BukkitUtil.getPlayer(player);
+ if (Permissions.hasPermission(pp, "plots.plothider.bypass")) { // Admin bypass
+ return;
+ }
+ String world = pp.getLocation().getWorld();
+ if (!PlotSquared.get().hasPlotArea(world)) { // Not a plot area
+ return;
+ }
+ PacketContainer packet = event.getPacket();
+ StructureModifier chunkArray = packet.getChunkCoordIntPairs();
+ ChunkCoordIntPair chunk = chunkArray.read(0);
+ int cx = chunk.getChunkX();
+ int cz = chunk.getChunkZ();
+ int bx = cx << 4;
+ int bz = cz << 4;
+ Location corner1 = new Location(world, bx, 0, bz);
+ Location corner2 = new Location(world, bx + 15, 0, bz);
+ Location corner3 = new Location(world, bx, 0, bz + 15);
+ Location corner4 = new Location(world, bx + 15, 0, bz + 15);
+ Plot plot1 = corner1.getOwnedPlot();
+ Plot plot2 = corner2.getOwnedPlot();
+ Plot plot3 = corner3.getOwnedPlot();
+ Plot plot4 = corner4.getOwnedPlot();
+ plot1 = (plot1 != null && (plot1.isDenied(pp.getUUID()) || (!plot1.isAdded(pp.getUUID()) && Main.HIDE_FLAG.isTrue(plot1)))) ? plot1 : null;
+ plot2 = (plot2 != null && (plot2.isDenied(pp.getUUID()) || (!plot2.isAdded(pp.getUUID()) && Main.HIDE_FLAG.isTrue(plot2)))) ? plot2 : null;
+ plot3 = (plot3 != null && (plot3.isDenied(pp.getUUID()) || (!plot3.isAdded(pp.getUUID()) && Main.HIDE_FLAG.isTrue(plot3)))) ? plot3 : null;
+ plot4 = (plot4 != null && (plot4.isDenied(pp.getUUID()) || (!plot4.isAdded(pp.getUUID()) && Main.HIDE_FLAG.isTrue(plot4)))) ? plot4 : null;
+ if (plot1 == null && plot2 == null && plot3 == null && plot4 == null) { // No plots to hide
+ return;
+ }
+ StructureModifier changeArray = packet.getMultiBlockChangeInfoArrays();
+ if (plot1 == plot4 && plot1 != null) { // Not allowed to see the entire chunk
+ event.setCancelled(true);
+ return;
+ }
+ // Hide some of the blocks (but maybe not all)
+ List changes = new ArrayList(Arrays.asList((Object[]) changeArray.read(0)));
+ Iterator iter = changes.iterator();
+ Plot denied = plot1 != null ? plot1 : plot2 != null ? plot2 : plot3 != null ? plot3 : plot4;
+ PlotArea area = denied.getArea();
+ while (iter.hasNext()) {
+ MultiBlockChangeInfo change = iter.next();
+ int x = change.getAbsoluteX();
+ int z = change.getAbsoluteZ();
+ Plot current = area.getOwnedPlot(new Location(world, x, 0, z));
+ if (current == null) {
+ continue;
+ }
+ if (current == plot1 || current == plot2 || current == plot3 || current == plot4) {
+ iter.remove();
+ }
+ }
+ if (changes.size() == 0) {
+ event.setCancelled(true);
+ return;
+ }
+// changeArray.write(0, changes.toArray(new MultiBlockChangeInfo[changes.size()]));
+ changeArray.write(0, changes.toArray(new MultiBlockChangeInfo[0]));
+ event.setPacket(packet);
+ }
+ });
+
+ manager.addPacketListener(
+ new PacketAdapter(main, ListenerPriority.NORMAL, PacketType.Play.Server.MAP_CHUNK) {
+ public void onPacketSending(PacketEvent event) {
+ Player player = event.getPlayer();
+ PlotPlayer pp = BukkitUtil.getPlayer(player);
+ if (Permissions.hasPermission(pp, "plots.plothider.bypass")) { // Admin bypass
+ return;
+ }
+ String world = pp.getLocation().getWorld();
+ if (!PlotSquared.get().hasPlotArea(world)) { // Not a plot area
+ return;
+ }
+ PacketContainer packet = event.getPacket();
+ StructureModifier ints = packet.getIntegers();
+ StructureModifier byteArray = packet.getByteArrays();
+ StructureModifier booleans = packet.getBooleans();
+ int cx = ints.read(0);
+ int cz = ints.read(1);
+ int bx = cx << 4;
+ int bz = cz << 4;
+ boolean biomes = booleans.read(0);
+ Location corner1 = new Location(world, bx, 0, bz);
+ Location corner2 = new Location(world, bx + 15, 0, bz);
+ Location corner3 = new Location(world, bx, 0, bz + 15);
+ Location corner4 = new Location(world, bx + 15, 0, bz + 15);
+ Plot plot1 = corner1.getOwnedPlot();
+ Plot plot2 = corner2.getOwnedPlot();
+ Plot plot3 = corner3.getOwnedPlot();
+ Plot plot4 = corner4.getOwnedPlot();
+ plot1 = (plot1 != null && (plot1.isDenied(pp.getUUID()) || (!plot1.isAdded(pp.getUUID()) && Main.HIDE_FLAG.isTrue(plot1)))) ? plot1 : null;
+ plot2 = (plot2 != null && (plot2.isDenied(pp.getUUID()) || (!plot2.isAdded(pp.getUUID()) && Main.HIDE_FLAG.isTrue(plot2)))) ? plot2 : null;
+ plot3 = (plot3 != null && (plot3.isDenied(pp.getUUID()) || (!plot3.isAdded(pp.getUUID()) && Main.HIDE_FLAG.isTrue(plot3)))) ? plot3 : null;
+ plot4 = (plot4 != null && (plot4.isDenied(pp.getUUID()) || (!plot4.isAdded(pp.getUUID()) && Main.HIDE_FLAG.isTrue(plot4)))) ? plot4 : null;
+ if (plot1 == null && plot2 == null && plot3 == null && plot4 == null) { // No plots to hide
+ return;
+ }
+ if (plot1 == plot4 && plot1 != null) { // Not allowed to see the entire chunk
+ byteArray.write(0, new byte[byteArray.read(0).length]);
+ StructureModifier>> list = packet.getListNbtModifier();
+ list.write(0, new ArrayList<>());
+ event.setPacket(packet);
+ return;
+ }
+ // Not allowed to see part of the chunk
+ Plot denied = plot1 != null ? plot1 : plot2 != null ? plot2 : plot3 != null ? plot3 : plot4;
+ PlotArea area = denied.getArea();
+ int AIR = 0;
+ byte[] sections = byteArray.read(0);
+ int size = sections.length;
+ int datasize = sections.length;
+ List array = new ArrayList<>();
+ int layer = 0;
+ byte[] biomearray;
+ ByteArrayInputStream buffer;
+ int bitMask = ints.read(2);
+ if (biomes) {
+ buffer = new ByteArrayInputStream(Arrays.copyOfRange(sections, 0,
+ sections.length - 256 * Integer.bitCount(bitMask)));
+ biomearray = Arrays.copyOfRange(sections,
+ sections.length - 256 * Integer.bitCount(bitMask), sections.length);
+ datasize -= 256 * Integer.bitCount(bitMask);
+ } else {
+ buffer = new ByteArrayInputStream(sections);
+ biomearray = null;
+ }
+
+ try {
+ boolean sky =
+ Bukkit.getWorld(world).getEnvironment() == World.Environment.NORMAL;
+
+ byte[] section;
+ for (layer = 0; layer < 16; layer++) {
+ if ((bitMask >> layer & 0x1) == 1) {
+ int start = datasize - buffer.available();
+
+ int bitsperBlock = readVarInt(buffer);
+
+ int paletteLength = readVarInt(buffer);
+
+ for (int i = 0; i < paletteLength; i++) {
+ readVarInt(buffer);
+ }
+
+ int dataArrayLength = readVarInt(buffer);
+
+ for (int i = 0; i < bitsperBlock * 512; i++) {
+ readVarInt(buffer);
+ }
+
+ buffer.skip(sky ? 4096 : 2048);
+
+ int end = datasize - buffer.available();
+
+ section = Arrays.copyOfRange(sections, start, end);
+
+ BlockStorage storage = new BlockStorage(section, sky);
+ array.add(storage);
+ }
+ }
+ int z;
+ for (int x = 0; x < 16; x++) {
+ for (z = 0; z < 16; z++) {
+ Location loc = new Location(world, bx + x, 0, bz + z);
+ Plot current = area.getOwnedPlot(loc);
+ if (current != null) {
+ if ((current == plot1) || (current == plot2) || (current
+ == plot3) || (current == plot4)) {
+ for (BlockStorage section1 : array) {
+ for (int y = 0; y < 16; y++) {
+ if (section1.get(x, y, z) != 0) {
+ section1.set(x, y, z, AIR);
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ ByteArrayOutputStream baos = new ByteArrayOutputStream(size);
+ for (BlockStorage section1 : array) {
+ section1.write(baos);
+ }
+ if (biomearray != null) {
+ baos.write(biomearray);
+ }
+ byteArray.write(0, baos.toByteArray());
+
+ event.setPacket(packet);
+ } catch (Throwable e) {
+ e.printStackTrace();
+ }
+ }
+ });
+ }
+
+ private int readVarInt(InputStream stream) throws IOException {
+ int i = 0;
+ int j = 0;
+
+ byte b0;
+ do {
+ b0 = (byte) stream.read();
+ i |= (b0 & 127) << j++ * 7;
+ if(j > 5) {
+ throw new RuntimeException("VarInt too big");
+ }
+ } while((b0 & 128) == 128);
+
+ return i;
+ }
+}
diff --git a/plugin.yml b/src/main/resources/plugin.yml
similarity index 72%
rename from plugin.yml
rename to src/main/resources/plugin.yml
index bccb571..e5d1b3a 100644
--- a/plugin.yml
+++ b/src/main/resources/plugin.yml
@@ -1,6 +1,6 @@
name: PlotHider
main: com.boydti.phider.Main
-version: 3.4.0
+version: 4.0.0
description: Hide plots from other players
-authors: [Empire92]
+authors: [Empire92, dordsor21]
depend: [PlotSquared,ProtocolLib]
\ No newline at end of file