Add AntiXray layered obfuscation mode
Changes
- Removes code duplication from
obfuscateLayer - Adds a 3rd engine mode (layered obfuscation), this mode works the same as engine mode 2, but instead of randomizing every block, only randomizes blocks per chunk layer. This helps a lot with chunk packet compression and can reduce the network load when joining by a factor of ~2 (from very basic testing)
Testing The tests have been run on a plain new paper server by joining three times in the same spot in spawn chunks. After every test, the server has been rebooted, and these results have shown to be reproducible. Results: imgur
- Removes code duplication from
obfuscateLayer
The code duplication is very much intended. You are touching the hottest code in Anti-Xray and with your changes you are introducing lots of branches into that code.
Also your changes can be implemented without even touching the obfuscateLayer method and avoiding the additional engineMode == EngineMode.OBFUSCATE_LAYER ? condition in the hot code. There's a reason why the random object is passed to this method.
I like the idea. The implementation of it should be a matter of changing like 2 or 3 lines tho.
This will do it (not tested):
LayeredIntSupplier random = numberOfBlocks == 1 ? (() -> 0) : engineMode == EngineMode.OBFUSCATE_LAYER ? new LayeredIntSupplier() {
// ##################
// # engine-mode: 3 #
// ##################
private int state;
private int next;
{
while ((state = ThreadLocalRandom.current().nextInt()) == 0) ;
}
@Override
public void nextLayer() {
// https://en.wikipedia.org/wiki/Xorshift
state ^= state << 13;
state ^= state >>> 17;
state ^= state << 5;
// https://www.pcg-random.org/posts/bounded-rands.html
next = (int) ((Integer.toUnsignedLong(state) * numberOfBlocks) >>> 32);
}
@Override
public int getAsInt() {
return next;
}
} : new LayeredIntSupplier() {
// ##################
// # engine-mode: 2 #
// ##################
private int state;
{
while ((state = ThreadLocalRandom.current().nextInt()) == 0) ;
}
@Override
public int getAsInt() {
// https://en.wikipedia.org/wiki/Xorshift
state ^= state << 13;
state ^= state >>> 17;
state ^= state << 5;
// https://www.pcg-random.org/posts/bounded-rands.html
return (int) ((Integer.toUnsignedLong(state) * numberOfBlocks) >>> 32);
}
};
@FunctionalInterface
private static interface LayeredIntSupplier extends IntSupplier {
default void nextLayer() {
}
}
Then call random.nextLayer() before each obfuscateLayer(...). No additional branches and even faster than engine-mode: 2.