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