diff --git a/Plugin/pom.xml b/Plugin/pom.xml
index 089c0a6c..15de6253 100644
--- a/Plugin/pom.xml
+++ b/Plugin/pom.xml
@@ -27,7 +27,7 @@
com.comphenix.protocol
ProtocolLib-API
- 4.0
+ 4.4.0
provided
true
@@ -49,6 +49,13 @@
compile
true
+
+ net.openhft
+ zero-allocation-hashing
+ 0.8
+ jar
+ compile
+
com.lishid
orebfuscator-v1_9_R1
diff --git a/Plugin/src/main/java/com/lishid/orebfuscator/config/WorldConfig.java b/Plugin/src/main/java/com/lishid/orebfuscator/config/WorldConfig.java
index 8cbb9f91..c2692a50 100644
--- a/Plugin/src/main/java/com/lishid/orebfuscator/config/WorldConfig.java
+++ b/Plugin/src/main/java/com/lishid/orebfuscator/config/WorldConfig.java
@@ -12,26 +12,31 @@
import java.util.*;
public class WorldConfig {
- private String name;
+ private String name;
private Boolean enabled;
private Boolean darknessHideBlocks;
private Boolean antiTexturePackAndFreecam;
private Boolean bypassObfuscationForSignsWithText;
- private Integer airGeneratorMaxChance;
+ private Integer airGeneratorMaxChance;
private HashSet obfuscateBlocks;
private HashSet darknessBlocks;
- private byte[] obfuscateAndProximityBlocks;
+ private byte[] obfuscateAndProximityBlocks;
private Integer[] randomBlocks;
private Integer[] randomBlocks2;
private Integer mode1BlockId;
private int[] paletteBlocks;
private ProximityHiderConfig proximityHiderConfig;
private boolean initialized;
-
+
+ /**
+ * Added in 1.13 patchset to allow faster, less determinstic random shuffles.
+ */
+ private static final Random random = new Random();
+
public WorldConfig() {
this.proximityHiderConfig = new ProximityHiderConfig();
}
-
+
public void setDefaults() {
this.enabled = true;
this.darknessHideBlocks = false;
@@ -47,31 +52,31 @@ public void setDefaults() {
this.randomBlocks = new Integer[0];
this.randomBlocks2 = this.randomBlocks;
-
+
this.mode1BlockId = NmsInstance.current.getConfigDefaults().defaultMode1BlockId;
this.paletteBlocks = null;
this.proximityHiderConfig.setDefaults();
}
-
+
public void init(WorldConfig baseWorld) {
if(this.initialized) {
return;
}
-
+
if(baseWorld != null) {
if(this.enabled == null) {
this.enabled = baseWorld.enabled;
}
-
+
if(this.darknessHideBlocks == null) {
this.darknessHideBlocks = baseWorld.darknessHideBlocks;
}
-
+
if(this.antiTexturePackAndFreecam == null) {
this.antiTexturePackAndFreecam = baseWorld.antiTexturePackAndFreecam;
}
-
+
if(this.bypassObfuscationForSignsWithText == null) {
this.bypassObfuscationForSignsWithText = baseWorld.bypassObfuscationForSignsWithText;
}
@@ -79,33 +84,33 @@ public void init(WorldConfig baseWorld) {
if(this.airGeneratorMaxChance == null) {
this.airGeneratorMaxChance = baseWorld.airGeneratorMaxChance;
}
-
+
if(this.obfuscateBlocks == null) {
this.obfuscateBlocks = baseWorld.obfuscateBlocks != null ? (HashSet)baseWorld.obfuscateBlocks.clone(): null;
}
-
+
if(this.darknessBlocks == null) {
this.darknessBlocks = baseWorld.darknessBlocks != null ? (HashSet)baseWorld.darknessBlocks.clone(): null;
}
-
+
if(this.randomBlocks == null) {
this.randomBlocks = baseWorld.randomBlocks != null ? baseWorld.randomBlocks.clone(): null;
this.randomBlocks2 = baseWorld.randomBlocks2 != null ? baseWorld.randomBlocks2.clone(): null;
}
-
+
if(this.mode1BlockId == null) {
this.mode1BlockId = baseWorld.mode1BlockId;
}
-
+
this.proximityHiderConfig.init(baseWorld.proximityHiderConfig);
setObfuscateAndProximityBlocks();
}
-
+
setPaletteBlocks();
-
+
this.initialized = true;
}
-
+
public boolean isInitialized() {
return this.initialized;
}
@@ -117,19 +122,19 @@ public String getName() {
public void setName(String value) {
this.name = value;
}
-
+
public Boolean isEnabled() {
return this.enabled;
}
-
+
public void setEnabled(Boolean value) {
this.enabled = value;
}
-
+
public Boolean isDarknessHideBlocks() {
return this.darknessHideBlocks;
}
-
+
public void setDarknessHideBlocks(Boolean value) {
this.darknessHideBlocks = value;
}
@@ -137,7 +142,7 @@ public void setDarknessHideBlocks(Boolean value) {
public Boolean isAntiTexturePackAndFreecam() {
return this.antiTexturePackAndFreecam;
}
-
+
public void setAntiTexturePackAndFreecam(Boolean value) {
this.antiTexturePackAndFreecam = value;
}
@@ -145,7 +150,7 @@ public void setAntiTexturePackAndFreecam(Boolean value) {
public Boolean isBypassObfuscationForSignsWithText() {
return this.bypassObfuscationForSignsWithText;
}
-
+
public void setBypassObfuscationForSignsWithText(Boolean value) {
this.bypassObfuscationForSignsWithText = value;
}
@@ -153,11 +158,11 @@ public void setBypassObfuscationForSignsWithText(Boolean value) {
public Integer getAirGeneratorMaxChance() {
return this.airGeneratorMaxChance;
}
-
+
public void setAirGeneratorMaxChance(Integer value) {
this.airGeneratorMaxChance = value;
}
-
+
public HashSet getObfuscateBlocks() {
return this.obfuscateBlocks;
}
@@ -211,11 +216,11 @@ private void setObfuscateMask(Set blockIds, boolean isDarknessBlock, bo
public byte[] getObfuscateAndProximityBlocks() {
return this.obfuscateAndProximityBlocks;
}
-
+
public HashSet getDarknessBlocks() {
return this.darknessBlocks;
}
-
+
public void setDarknessBlocks(HashSet values) {
this.darknessBlocks = values;
}
@@ -228,14 +233,36 @@ public void setRandomBlocks(Integer[] values) {
this.randomBlocks = values;
this.randomBlocks2 = values;
}
-
+
public void shuffleRandomBlocks() {
- synchronized (this.randomBlocks) {
- Collections.shuffle(Arrays.asList(this.randomBlocks));
- Collections.shuffle(Arrays.asList(this.randomBlocks2));
- }
+ // Use a Fisher-Yates shuffle over Collections.shuffle().
+ // Both are O(N) time, however with Collections.shuffle() we have
+ // to copy into a list to shuffle, and Collections.shuffle under the
+ // hood copies to an array shuffles, and then writes back.
+ //
+ // By performing fisher-yates directly we save the Copying back and forth.
+ if (this.randomBlocks.length != 0) {
+ synchronized (this.randomBlocks) {
+ for (int idx = 1; idx < this.randomBlocks.length; ++idx) {
+ int rand = random.nextInt(idx);
+ Integer save = this.randomBlocks[idx];
+ this.randomBlocks[idx] = this.randomBlocks[rand];
+ this.randomBlocks[rand] = save;
+ }
+ }
+ }
+ if (this.randomBlocks2.length != 0) {
+ synchronized (this.randomBlocks2) {
+ for (int idx = 1; idx < this.randomBlocks2.length; ++idx) {
+ int rand = random.nextInt(idx);
+ Integer save = this.randomBlocks2[idx];
+ this.randomBlocks2[idx] = this.randomBlocks2[rand];
+ this.randomBlocks2[rand] = save;
+ }
+ }
+ }
}
-
+
public Integer getMode1BlockId() {
return this.mode1BlockId;
}
@@ -247,43 +274,43 @@ public void setMode1BlockId(Integer value) {
public int[] getPaletteBlocks() {
return this.paletteBlocks;
}
-
+
private void setPaletteBlocks() {
if(this.randomBlocks == null) {
return;
}
-
+
HashSet map = new HashSet();
map.add(NmsInstance.current.getCaveAirBlockId());
map.add(this.mode1BlockId);
-
+
if(this.proximityHiderConfig.isUseSpecialBlock()) {
map.add(this.proximityHiderConfig.getSpecialBlockID());
}
-
+
for(Integer id : this.randomBlocks) {
if(id != null) {
map.add(id);
}
}
-
+
int[] paletteBlocks = new int[map.size()];
int index = 0;
-
+
for(Integer id : map) {
paletteBlocks[index++] = id;
}
-
+
this.paletteBlocks = paletteBlocks;
}
public ProximityHiderConfig getProximityHiderConfig() {
return this.proximityHiderConfig;
}
-
+
// Helper methods
-
+
public int getObfuscatedBits(int id) {
return this.obfuscateAndProximityBlocks[id];
}
diff --git a/Plugin/src/main/java/com/lishid/orebfuscator/obfuscation/Calculations.java b/Plugin/src/main/java/com/lishid/orebfuscator/obfuscation/Calculations.java
index 74b004f0..d59c94a9 100644
--- a/Plugin/src/main/java/com/lishid/orebfuscator/obfuscation/Calculations.java
+++ b/Plugin/src/main/java/com/lishid/orebfuscator/obfuscation/Calculations.java
@@ -351,7 +351,7 @@ private static ObfuscatedCachedChunk tryUseCache(ChunkData chunkData, Player pla
chunkData.useCache = true;
// Hash the chunk
- long hash = CalculationsUtil.Hash(chunkData.data, chunkData.data.length);
+ long hash = CalculationsUtil.Hash(chunkData.data);
// Get cache folder
File cacheFolder = new File(ObfuscatedDataCache.getCacheFolder(), player.getWorld().getName());
// Create cache objects
diff --git a/Plugin/src/main/java/com/lishid/orebfuscator/obfuscation/CalculationsUtil.java b/Plugin/src/main/java/com/lishid/orebfuscator/obfuscation/CalculationsUtil.java
index c89fbb19..b849473c 100644
--- a/Plugin/src/main/java/com/lishid/orebfuscator/obfuscation/CalculationsUtil.java
+++ b/Plugin/src/main/java/com/lishid/orebfuscator/obfuscation/CalculationsUtil.java
@@ -16,14 +16,11 @@
package com.lishid.orebfuscator.obfuscation;
-import java.util.zip.CRC32;
+import net.openhft.hashing.LongHashFunction;
public class CalculationsUtil {
- public static long Hash(byte[] data, int length) {
- CRC32 crc = new CRC32();
- crc.reset();
- crc.update(data, 0, length);
- return crc.getValue();
+ public static long Hash(byte[] data) {
+ return LongHashFunction.xx().hashBytes(data);
}
public static int increment(int current, int max) {
diff --git a/pom.xml b/pom.xml
index c1b53230..ef3b0522 100644
--- a/pom.xml
+++ b/pom.xml
@@ -17,7 +17,7 @@
dmulloy2-repo
- http://repo.dmulloy2.net/content/groups/public/
+ http://repo.dmulloy2.net/nexus/repository/public/
spigot-repo