Skip to content

Commit

Permalink
1.1.0
Browse files Browse the repository at this point in the history
  • Loading branch information
wode490390 committed Aug 14, 2019
1 parent 509418f commit 560cfac
Show file tree
Hide file tree
Showing 5 changed files with 637 additions and 296 deletions.
18 changes: 13 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,19 +1,27 @@
# AntiXray
[![](http://i.loli.net/2019/01/27/5c4d21504445e.png)](http://www.mcbbs.net/thread-838490-1-1.html "假矿")

Anti X-Ray cheat plugin for Nukkit
Anti X-Ray plugin for Nukkit.

This plugin is used to counter X-RAY Client add-ons.

It modifies data that are sent to clients to hide blocks.

It does not manipulate blocks in the level file, thus is safe to use.

Please see [mcbbs](http://www.mcbbs.net/thread-838490-1-1.html) for more information.
## Permissions
| Permission | Description |
| - | - |
| antixray.whitelist | Allow player to cheat with X-Ray |
| Permission | Description | Default |
| - | - | - |
| antixray.whitelist | Allow player to cheat with X-Ray | `OP` |
## config.yml
```yaml
# The smaller the value, the higher the performance (1~255)
scan-height-limit: 64
# Save a serialized copy of the chunk in memory for faster sending
cache-chunks: true
memory-cache: true
# Save a serialized copy of the chunk blocks in disk for faster sending
local-cache: true
# Set this to false to use hidden mode
obfuscator-mode: true
# The fake block is used to replace ores in different dimensions (hidden mode only)
Expand Down
32 changes: 31 additions & 1 deletion pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
<modelVersion>4.0.0</modelVersion>
<groupId>cn.wode490390.nukkit</groupId>
<artifactId>antixray</artifactId>
<version>1.0.9</version>
<version>1.1.0</version>
<name>AntiXray</name>
<description>Anti X-Ray cheat plugin for Nukkit</description>
<inceptionYear>2018</inceptionYear>
Expand Down Expand Up @@ -34,6 +34,12 @@
<version>1.0-SNAPSHOT</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>net.openhft</groupId>
<artifactId>zero-allocation-hashing</artifactId>
<version>0.9</version>
<scope>compile</scope>
</dependency>
</dependencies>
<build>
<defaultGoal>clean package</defaultGoal>
Expand All @@ -48,5 +54,29 @@
</includes>
</resource>
</resources>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>3.2.1</version>
<configuration>
<artifactSet>
<includes>
<include>*:*</include>
</includes>
</artifactSet>
<createDependencyReducedPom>false</createDependencyReducedPom>
<minimizeJar>true</minimizeJar>
</configuration>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
186 changes: 159 additions & 27 deletions src/main/java/cn/wode490390/nukkit/antixray/AntiXray.java
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,20 @@
import cn.nukkit.level.Position;
import cn.nukkit.level.format.FullChunk;
import cn.nukkit.math.Vector3;
import cn.nukkit.nbt.stream.FastByteArrayOutputStream;
import cn.nukkit.network.protocol.UpdateBlockPacket;
import cn.nukkit.plugin.PluginBase;
import cn.nukkit.scheduler.AsyncTask;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.ByteArrayInputStream;
import java.io.EOFException;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashSet;
Expand All @@ -22,14 +34,24 @@
import java.util.NoSuchElementException;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.zip.Deflater;
import java.util.zip.DeflaterOutputStream;
import java.util.zip.Inflater;
import java.util.zip.InflaterInputStream;
import net.openhft.hashing.LongHashFunction;

public class AntiXray extends PluginBase implements Listener {

public final static String PERMISSION_WHITELIST = "antixray.whitelist";

static LongHashFunction XX64;

static File CACHE_DIR;

int height;
boolean mode;
boolean cache;
boolean memoryCache;
boolean localCache;
int fake_o;
int fake_n;
List<Integer> ores;
Expand All @@ -46,70 +68,99 @@ public void onEnable() {

}
this.saveDefaultConfig();
String t = "scan-height-limit";
String node = "scan-height-limit";
try {
this.height = this.getConfig().getInt(t, 64);
this.height = this.getConfig().getInt(node, 64);
} catch (Exception e) {
this.height = 64;
this.logLoadException(t);
this.logLoadException(node);
}
if (this.height < 1) {
this.height = 1;
} else if (this.height > 255) {
this.height = 255;
}
t = "cache-chunks";
node = "memory-cache";
try {
this.memoryCache = this.getConfig().getBoolean(node, true);
} catch (Exception e) {
this.memoryCache = true;
this.logLoadException(node);
}
node = "cache-chunks"; //compatible
try {
this.cache = this.getConfig().getBoolean(t, true);
this.memoryCache = this.getConfig().getBoolean(node, true);
} catch (Exception e) {
this.cache = true;
this.logLoadException(t);
this.memoryCache = true;
this.logLoadException(node);
}
t = "obfuscator-mode";
node = "local-cache";
try {
this.mode = this.getConfig().getBoolean(t, true);
this.localCache = this.getConfig().getBoolean(node, true);
} catch (Exception e) {
this.localCache = true;
this.logLoadException(node);
}
node = "obfuscator-mode";
try {
this.mode = this.getConfig().getBoolean(node, true);
} catch (Exception e) {
this.mode = true;
this.logLoadException(t);
this.logLoadException(node);
}
t = "overworld-fake-block";
node = "overworld-fake-block";
try {
this.fake_o = this.getConfig().getInt(t, 1);
this.fake_o = this.getConfig().getInt(node, 1);
} catch (Exception e) {
this.fake_o = 1;
this.logLoadException(t);
this.logLoadException(node);
}
t = "nether-fake-block";
node = "nether-fake-block";
try {
this.fake_n = this.getConfig().getInt(t, 87);
this.fake_n = this.getConfig().getInt(node, 87);
} catch (Exception e) {
this.fake_n = 87;
this.logLoadException(t);
this.logLoadException(node);
}
t = "protect-worlds";
node = "protect-worlds";
try {
this.worlds = this.getConfig().getStringList(t);
this.worlds = this.getConfig().getStringList(node);
} catch (Exception e) {
this.worlds = new ArrayList<>();
this.logLoadException(t);
this.logLoadException(node);
}
t = "ores";
node = "ores";
try {
this.ores = this.getConfig().getIntegerList(t);
this.ores = this.getConfig().getIntegerList(node);
} catch (Exception e) {
this.ores = new ArrayList<>();
this.logLoadException(t);
this.logLoadException(node);
}
t = "filters";
node = "filters";
try {
this.filters = this.getConfig().getIntegerList(t);
this.filters = this.getConfig().getIntegerList(node);
} catch (Exception e) {
this.filters = new ArrayList<>();
this.logLoadException(t);
this.logLoadException(node);
}
if (!this.worlds.isEmpty() && !this.ores.isEmpty()) {
if (this.localCache) {
CACHE_DIR = new File(this.getDataFolder(), "cache");
if (!CACHE_DIR.exists()) {
CACHE_DIR.mkdirs();
} else if (!CACHE_DIR.isDirectory()) {
CACHE_DIR.delete();
CACHE_DIR.mkdirs();
}
if (!CACHE_DIR.exists() || !CACHE_DIR.isDirectory()) {
this.localCache = false;
this.getLogger().warning("Failed to initialize cache! Disabled cache.");
} else {
XX64 = LongHashFunction.xx();
}
}
this.getServer().getPluginManager().registerEvents(this, this);
if (this.cache) {
if (this.memoryCache) {
this.getServer().getPluginManager().registerEvents(new CleanerListener(), this);
}
}
Expand Down Expand Up @@ -176,10 +227,57 @@ public void onBlockUpdate(BlockUpdateEvent event) {
}
}

long getCacheHash(byte[] buffer) {
return XX64.hashBytes(buffer);
}

boolean hasCache(long hash) {
File file = new File(CACHE_DIR, String.valueOf(hash));
return file.exists() && !file.isDirectory();
}

void createCache(long hash, byte[] buffer) {
this.getServer().getScheduler().scheduleAsyncTask(this, new CacheWriteTask(hash, buffer));
}

byte[] readCache(long hash) {
File file = new File(CACHE_DIR, String.valueOf(hash));
try {
if (!file.exists() || file.isDirectory()) {
throw new FileNotFoundException();
} else if (file.length() == 0) {
throw new EOFException();
}
try (InputStream inputStream = new InflaterInputStream(new BufferedInputStream(new FileInputStream(file)), new Inflater(true)); FastByteArrayOutputStream outputStream = new FastByteArrayOutputStream(1024)) {
byte[] temp = new byte[1024];
int length;
while ((length = inputStream.read(temp)) != -1) {
outputStream.write(temp, 0, length);
}
return outputStream.toByteArray();
}
} catch (IOException e) {
this.getLogger().debug("Unable to read cache file", e);
}
return null;
}

private void logLoadException(String node) {
this.getLogger().alert("An error occurred while reading the configuration '" + node + "'. Use the default value.");
}

private static boolean deleteFolder(File file) {
if (file.isDirectory()) {
for (String children : file.list()) {
boolean success = deleteFolder(new File(file, children));
if (!success) {
return false;
}
}
}
return file.delete();
}

public class CleanerListener implements Listener {

private CleanerListener() {
Expand All @@ -198,4 +296,38 @@ public void onChunkUnload(ChunkUnloadEvent event) {
}
}
}

private class CacheWriteTask extends AsyncTask {

private final long hash;
private final byte[] buffer;

private CacheWriteTask(long hash, byte[] buffer) {
this.hash = hash;
this.buffer = buffer;
}

@Override
public void onRun() {
try {
File file = new File(CACHE_DIR, String.valueOf(hash));
if (!file.exists()) {
file.createNewFile();
} else if (file.isDirectory()) {
deleteFolder(file);
file.createNewFile();
}
try (DeflaterOutputStream outputStream = new DeflaterOutputStream(new BufferedOutputStream(new FileOutputStream(file)), new Deflater(Deflater.BEST_COMPRESSION, true)); InputStream inputStream = new ByteArrayInputStream(this.buffer)) {
byte[] temp = new byte[1024];
int length;
while ((length = inputStream.read(temp)) != -1) {
outputStream.write(temp, 0, length);
}
outputStream.finish();
}
} catch (IOException e) {
getLogger().debug("Unable to save cache file", e);
}
}
}
}
Loading

0 comments on commit 560cfac

Please sign in to comment.