Load Scramble Seed key from Config

Remember all used Scramble seeds to unscramble potions
This commit is contained in:
Sn0wStorm
2019-10-18 16:30:03 +02:00
parent 437f521a9b
commit f431c13100
25 changed files with 327 additions and 69 deletions
@@ -1,38 +1,99 @@
package com.dre.brewery.lore;
import com.dre.brewery.P;
import org.jetbrains.annotations.NotNull;
import java.io.FilterInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.security.InvalidKeyException;
import java.util.List;
/**
* A Scramble Stream that uses XOR operations to unscramble an inputstream.
* a byte generator feeded with the seed is used as xor source
* Used to unscramble data generated by the XORScrambleStream
*/
public class XORUnscrambleStream extends FilterInputStream {
private final long seed;
private long seed;
private final List<Long> prevSeeds;
private SeedInputStream xorStream;
private boolean running;
private boolean markRunning;
private boolean markxor;
/**
* Create a new instance of an XORUnscrambler, unscrambling the given inputstream
*
* @param in The Inputstream to be unscrambled
* @param seed The seed used for unscrambling
*/
public XORUnscrambleStream(InputStream in, long seed) {
super(in);
this.seed = seed;
prevSeeds = null;
}
/**
* Create a new instance of an XORUnscrambler, unscrambling the given inputstream
* If given a List of previous Seeds, the unscrambler will try all of them for unscrambling the stream in case the seed fails.
*
* @param in The Inputstream to be unscrambled
* @param seed The seed used for unscrambling
*/
public XORUnscrambleStream(InputStream in, long seed, List<Long> prevSeeds) {
super(in);
this.seed = seed;
this.prevSeeds = prevSeeds;
}
/**
* Before unscrambling, this has to be called to tell the unscrambler that scrambled data will follow.
* Before starting the unscrambler, any data will just be passed through unmodified to the underlying stream.
* The Unscrambling can be started and stopped arbitrarily at any point, allowing for parts of already unscrambled data in the stream.
*
* @throws IOException IOException
* @throws InvalidKeyException If the scrambled data could not be read, very likely caused by a wrong seed. Thrown after checking all previous seeds.
*/
public void start() throws IOException, InvalidKeyException {
running = true;
if (xorStream == null) {
short id = (short) (in.read() << 8 | in.read());
if (id == 0) {
running = false;
P.p.debugLog("Unscrambled data");
return;
}
int parity = in.read();
xorStream = new SeedInputStream(seed ^ id);
if (read() != ((int) (seed >> 48) & 0xFF)) { // Parity/Sanity
boolean success = checkParity(parity);
if (success) P.p.debugLog("Using main Seed to unscramble");
if (!success && prevSeeds != null) {
for (int i = prevSeeds.size() - 1; i >= 0; i--) {
seed = prevSeeds.get(i);
xorStream = new SeedInputStream(seed ^ id);
if (success = checkParity(parity)) {
P.p.debugLog("Had to use prevSeed to unscramble");
break;
}
}
}
if (!success) {
throw new InvalidKeyException("Could not read scrambled data, is the seed wrong?");
}
}
}
private boolean checkParity(int parity) {
return ((parity ^ xorStream.read()) & 0xFF) == ((int) (seed >> 48) & 0xFF); // Parity/Sanity
}
/**
* Stop the unscrambling, any following data will be passed through unmodified.
* The unscrambling can be started again at any point after calling this
*/
public void stop() {
running = false;
}
@@ -46,7 +107,7 @@ public class XORUnscrambleStream extends FilterInputStream {
}
@Override
public int read(byte[] b, int off, int len) throws IOException {
public int read(@NotNull byte[] b, int off, int len) throws IOException {
if (!running) {
return in.read(b, off, len);
}
@@ -57,6 +118,7 @@ public class XORUnscrambleStream extends FilterInputStream {
return len;
}
@SuppressWarnings("ResultOfMethodCallIgnored")
@Override
public long skip(long n) throws IOException {
long skipped = in.skip(n);