mirror of
https://github.com/exituser/Brewery.git
synced 2026-09-17 08:59:01 +00:00
Added XOR Scrambler for Brew data
Very fast obfuscator for brew data so that a client cant easily read it
This commit is contained in:
@@ -1,10 +1,7 @@
|
|||||||
package com.dre.brewery;
|
package com.dre.brewery;
|
||||||
|
|
||||||
import org.bukkit.Color;
|
import org.bukkit.Color;
|
||||||
import com.dre.brewery.lore.Base91DecoderStream;
|
import com.dre.brewery.lore.*;
|
||||||
import com.dre.brewery.lore.Base91EncoderStream;
|
|
||||||
import com.dre.brewery.lore.LoreLoadStream;
|
|
||||||
import com.dre.brewery.lore.LoreSaveStream;
|
|
||||||
import org.bukkit.Material;
|
import org.bukkit.Material;
|
||||||
import org.bukkit.configuration.ConfigurationSection;
|
import org.bukkit.configuration.ConfigurationSection;
|
||||||
import org.bukkit.inventory.BrewerInventory;
|
import org.bukkit.inventory.BrewerInventory;
|
||||||
@@ -20,6 +17,7 @@ import org.bukkit.potion.PotionType;
|
|||||||
import java.io.DataInputStream;
|
import java.io.DataInputStream;
|
||||||
import java.io.DataOutputStream;
|
import java.io.DataOutputStream;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
import java.security.SecureRandom;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
@@ -28,7 +26,7 @@ import java.util.Map;
|
|||||||
public class Brew {
|
public class Brew {
|
||||||
|
|
||||||
// represents the liquid in the brewed Potions
|
// represents the liquid in the brewed Potions
|
||||||
|
private static long saveSeed;
|
||||||
public static Map<Integer, Brew> legacyPotions = new HashMap<>();
|
public static Map<Integer, Brew> legacyPotions = new HashMap<>();
|
||||||
public static long installTime = System.currentTimeMillis(); // plugin install time in millis after epoch
|
public static long installTime = System.currentTimeMillis(); // plugin install time in millis after epoch
|
||||||
public static Boolean colorInBarrels; // color the Lore while in Barrels
|
public static Boolean colorInBarrels; // color the Lore while in Barrels
|
||||||
@@ -732,18 +730,26 @@ public class Brew {
|
|||||||
} catch (IllegalArgumentException ignored) {
|
} catch (IllegalArgumentException ignored) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
try (DataInputStream in = new DataInputStream(new Base91DecoderStream(loreStream))) {
|
XORUnscrambleStream unscrambler = new XORUnscrambleStream(new Base91DecoderStream(loreStream), saveSeed);
|
||||||
|
try (DataInputStream in = new DataInputStream(unscrambler)) {
|
||||||
|
boolean parityFailed = false;
|
||||||
if (in.readByte() != 86) {
|
if (in.readByte() != 86) {
|
||||||
P.p.errorLog("parity check failed on Brew while loading, trying to load anyways!");
|
P.p.errorLog("Parity check failed on Brew while loading, trying to load anyways!");
|
||||||
|
parityFailed = true;
|
||||||
}
|
}
|
||||||
Brew brew = new Brew();
|
Brew brew = new Brew();
|
||||||
byte ver = in.readByte();
|
byte ver = in.readByte();
|
||||||
switch (ver) {
|
switch (ver) {
|
||||||
case 1:
|
case 1:
|
||||||
|
unscrambler.start();
|
||||||
brew.loadFromStream(in);
|
brew.loadFromStream(in);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
P.p.errorLog("Brew has data stored in v" + ver + " this version supports up to v1");
|
if (parityFailed) {
|
||||||
|
P.p.errorLog("Failed to load Brew. Maybe something corrupted the Lore of the Item?");
|
||||||
|
} else {
|
||||||
|
P.p.errorLog("Brew has data stored in v" + ver + " this Plugin version supports up to v1");
|
||||||
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
return brew;
|
return brew;
|
||||||
@@ -779,7 +785,11 @@ public class Brew {
|
|||||||
|
|
||||||
// Save brew data into meta/lore
|
// Save brew data into meta/lore
|
||||||
public void save(ItemMeta meta) {
|
public void save(ItemMeta meta) {
|
||||||
try (DataOutputStream out = new DataOutputStream(new Base91EncoderStream(new LoreSaveStream(meta, 0)))) {
|
XORScrambleStream scrambler = new XORScrambleStream(new Base91EncoderStream(new LoreSaveStream(meta, 0)), saveSeed);
|
||||||
|
try (DataOutputStream out = new DataOutputStream(scrambler)) {
|
||||||
|
out.writeByte(86); // Parity/sanity
|
||||||
|
out.writeByte(1); // Version
|
||||||
|
scrambler.start();
|
||||||
saveToStream(out);
|
saveToStream(out);
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
P.p.errorLog("IO Error while saving Brew");
|
P.p.errorLog("IO Error while saving Brew");
|
||||||
@@ -801,8 +811,6 @@ public class Brew {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void saveToStream(DataOutputStream out) throws IOException {
|
public void saveToStream(DataOutputStream out) throws IOException {
|
||||||
out.writeByte(86); // Parity/sanity
|
|
||||||
out.writeByte(1); // Version
|
|
||||||
if (quality > 10) {
|
if (quality > 10) {
|
||||||
quality = 10;
|
quality = 10;
|
||||||
}
|
}
|
||||||
@@ -831,6 +839,20 @@ public class Brew {
|
|||||||
ingredients.save(out);
|
ingredients.save(out);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static void writeSeed(ConfigurationSection section) {
|
||||||
|
section.set("seed", saveSeed);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void loadSeed(ConfigurationSection section) {
|
||||||
|
if (section.contains("seed")) {
|
||||||
|
saveSeed = section.getLong("seed");
|
||||||
|
} else {
|
||||||
|
while (saveSeed == 0) {
|
||||||
|
saveSeed = new SecureRandom().nextLong();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Load potion data from data file for backwards compatibility
|
// Load potion data from data file for backwards compatibility
|
||||||
public static void loadLegacy(BIngredients ingredients, int uid, int quality, byte distillRuns, float ageTime, float wood, String recipe, boolean unlabeled, boolean persistent, boolean stat) {
|
public static void loadLegacy(BIngredients ingredients, int uid, int quality, byte distillRuns, float ageTime, float wood, String recipe, boolean unlabeled, boolean persistent, boolean stat) {
|
||||||
Brew brew = new Brew(ingredients, quality, distillRuns, ageTime, wood, recipe, unlabeled, stat);
|
Brew brew = new Brew(ingredients, quality, distillRuns, ageTime, wood, recipe, unlabeled, stat);
|
||||||
|
|||||||
@@ -86,6 +86,136 @@ public class P extends JavaPlugin {
|
|||||||
|
|
||||||
//P.p.log("§" + (use1_9 ? "a":"c") + "1.9 " + "§" + (use1_11 ? "a":"c") + "1.11 " + "§" + (use1_13 ? "a":"c") + "1.13 " + "§" + (use1_14 ? "a":"c") + "1.14");
|
//P.p.log("§" + (use1_9 ? "a":"c") + "1.9 " + "§" + (use1_11 ? "a":"c") + "1.11 " + "§" + (use1_13 ? "a":"c") + "1.13 " + "§" + (use1_14 ? "a":"c") + "1.14");
|
||||||
|
|
||||||
|
/*long master = new SecureRandom().nextLong();
|
||||||
|
ByteArrayOutputStream byteStream = new ByteArrayOutputStream();
|
||||||
|
XORScrambleStream scramble = new XORScrambleStream(new Base91EncoderStream(byteStream), master);
|
||||||
|
DataOutputStream data = new DataOutputStream(scramble);
|
||||||
|
DataInputStream dataIn = null;
|
||||||
|
try {
|
||||||
|
scramble.start();
|
||||||
|
data.writeLong(12345L);
|
||||||
|
scramble.stop();
|
||||||
|
data.writeInt(1);
|
||||||
|
data.writeInt(1);
|
||||||
|
scramble.start();
|
||||||
|
data.writeDouble(0.55555D);
|
||||||
|
data.writeInt(234323);
|
||||||
|
//data.writeUTF("Hallo Peter");
|
||||||
|
data.writeLong(5419L); // Skip
|
||||||
|
data.writeDouble(0.55555D);
|
||||||
|
|
||||||
|
data.close();
|
||||||
|
|
||||||
|
XORUnscrambleStream unscramble = new XORUnscrambleStream(new Base91DecoderStream(new ByteArrayInputStream(byteStream.toByteArray())), master);
|
||||||
|
dataIn = new DataInputStream(unscramble);
|
||||||
|
unscramble.start();
|
||||||
|
P.p.log(dataIn.readLong() + "");
|
||||||
|
unscramble.stop();
|
||||||
|
P.p.log(dataIn.readInt() + "");
|
||||||
|
P.p.log(dataIn.readInt() + "");
|
||||||
|
unscramble.start();
|
||||||
|
P.p.log(dataIn.readDouble() + "");
|
||||||
|
dataIn.mark(1000);
|
||||||
|
P.p.log(dataIn.readInt() + "");
|
||||||
|
//P.p.log(dataIn.readUTF());
|
||||||
|
dataIn.skip(8);
|
||||||
|
P.p.log(dataIn.readDouble() + "");
|
||||||
|
P.p.log("reset");
|
||||||
|
dataIn.reset();
|
||||||
|
P.p.log(dataIn.readInt() + "");
|
||||||
|
//P.p.log(dataIn.readUTF());
|
||||||
|
dataIn.skip(8);
|
||||||
|
P.p.log(dataIn.readDouble() + "");
|
||||||
|
|
||||||
|
dataIn.close();
|
||||||
|
|
||||||
|
*//*for (int i = 0; i < 10; i++) {
|
||||||
|
byteStream = new ByteArrayOutputStream();
|
||||||
|
scramble = new XORScrambleStream(new Base91EncoderStream(byteStream));
|
||||||
|
data = new DataOutputStream(scramble);
|
||||||
|
data.writeInt(i);
|
||||||
|
scramble.start();
|
||||||
|
data.writeLong(12345L);
|
||||||
|
data.writeLong(12345L);
|
||||||
|
scramble.stop();
|
||||||
|
data.writeInt(1);
|
||||||
|
data.writeInt(1);
|
||||||
|
scramble.start();
|
||||||
|
data.writeInt(234323);
|
||||||
|
data.writeDouble(0.55555D);
|
||||||
|
|
||||||
|
P.p.log(byteStream.toString());
|
||||||
|
data.close();
|
||||||
|
}*//*
|
||||||
|
|
||||||
|
|
||||||
|
long time = System.currentTimeMillis();
|
||||||
|
for (int i = 0; i < 100000; i++) {
|
||||||
|
unscramble = new XORUnscrambleStream(new Base91DecoderStream(new ByteArrayInputStream(byteStream.toByteArray())), master);
|
||||||
|
dataIn = new DataInputStream(unscramble);
|
||||||
|
unscramble.start();
|
||||||
|
dataIn.readLong();
|
||||||
|
unscramble.stop();
|
||||||
|
dataIn.readInt();
|
||||||
|
dataIn.readInt();
|
||||||
|
unscramble.start();
|
||||||
|
dataIn.readDouble();
|
||||||
|
dataIn.mark(1000);
|
||||||
|
dataIn.readInt();
|
||||||
|
//dataIn.readUTF();
|
||||||
|
dataIn.skip(8);
|
||||||
|
dataIn.readDouble();
|
||||||
|
dataIn.reset();
|
||||||
|
dataIn.readInt();
|
||||||
|
//dataIn.readUTF();
|
||||||
|
dataIn.skip(8);
|
||||||
|
dataIn.readDouble();
|
||||||
|
|
||||||
|
dataIn.close();
|
||||||
|
}
|
||||||
|
long time2 = System.currentTimeMillis();
|
||||||
|
|
||||||
|
for (int i = 0; i < 100000; i++) {
|
||||||
|
unscramble = new XORUnscrambleStream(new ByteArrayInputStream(byteStream.toByteArray()), master);
|
||||||
|
dataIn = new DataInputStream(unscramble);
|
||||||
|
unscramble.start();
|
||||||
|
dataIn.skip(2);
|
||||||
|
dataIn.readLong();
|
||||||
|
unscramble.stop();
|
||||||
|
dataIn.readInt();
|
||||||
|
dataIn.readInt();
|
||||||
|
unscramble.start();
|
||||||
|
dataIn.readDouble();
|
||||||
|
dataIn.mark(1000);
|
||||||
|
dataIn.readInt();
|
||||||
|
//dataIn.readUTF();
|
||||||
|
dataIn.skip(8);
|
||||||
|
dataIn.readDouble();
|
||||||
|
dataIn.reset();
|
||||||
|
dataIn.readInt();
|
||||||
|
//dataIn.readUTF();
|
||||||
|
dataIn.skip(8);
|
||||||
|
dataIn.readDouble();
|
||||||
|
|
||||||
|
dataIn.close();
|
||||||
|
}
|
||||||
|
long time3 = System.currentTimeMillis();
|
||||||
|
|
||||||
|
P.p.log("Time with base91: " + (time2 - time));
|
||||||
|
P.p.log("Time without base91: " + (time3 - time2));
|
||||||
|
|
||||||
|
} catch (IOException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
} finally {
|
||||||
|
try {
|
||||||
|
data.close();
|
||||||
|
if (dataIn != null) {
|
||||||
|
dataIn.close();
|
||||||
|
}
|
||||||
|
} catch (IOException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}*/
|
||||||
|
|
||||||
/*try {
|
/*try {
|
||||||
ItemMeta meta = new ItemStack(Material.POTION).getItemMeta();
|
ItemMeta meta = new ItemStack(Material.POTION).getItemMeta();
|
||||||
@@ -577,8 +707,11 @@ public class P extends JavaPlugin {
|
|||||||
FileConfiguration data = YamlConfiguration.loadConfiguration(file);
|
FileConfiguration data = YamlConfiguration.loadConfiguration(file);
|
||||||
|
|
||||||
Brew.installTime = data.getLong("installTime", System.currentTimeMillis());
|
Brew.installTime = data.getLong("installTime", System.currentTimeMillis());
|
||||||
|
|
||||||
MCBarrel.mcBarrelTime = data.getLong("MCBarrelTime", 0);
|
MCBarrel.mcBarrelTime = data.getLong("MCBarrelTime", 0);
|
||||||
|
|
||||||
|
Brew.loadSeed(data);
|
||||||
|
|
||||||
// Check if data is the newest version
|
// Check if data is the newest version
|
||||||
String version = data.getString("Version", null);
|
String version = data.getString("Version", null);
|
||||||
if (version != null) {
|
if (version != null) {
|
||||||
|
|||||||
@@ -62,8 +62,11 @@ public class DataSave extends BukkitRunnable {
|
|||||||
FileConfiguration configFile = new YamlConfiguration();
|
FileConfiguration configFile = new YamlConfiguration();
|
||||||
|
|
||||||
configFile.set("installTime", Brew.installTime);
|
configFile.set("installTime", Brew.installTime);
|
||||||
|
|
||||||
configFile.set("MCBarrelTime", MCBarrel.mcBarrelTime);
|
configFile.set("MCBarrelTime", MCBarrel.mcBarrelTime);
|
||||||
|
|
||||||
|
Brew.writeSeed(configFile);
|
||||||
|
|
||||||
if (!Brew.legacyPotions.isEmpty()) {
|
if (!Brew.legacyPotions.isEmpty()) {
|
||||||
Brew.save(configFile.createSection("Brew"));
|
Brew.save(configFile.createSection("Brew"));
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,94 @@
|
|||||||
|
package com.dre.brewery.lore;
|
||||||
|
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.util.Arrays;
|
||||||
|
|
||||||
|
public class SeedInputStream extends InputStream {
|
||||||
|
// From java.util.Random
|
||||||
|
private static final long multiplier = 0x5DEECE66DL;
|
||||||
|
private static final long addend = 0xBL;
|
||||||
|
private static final long mask = (1L << 48) - 1;
|
||||||
|
|
||||||
|
private long seed;
|
||||||
|
private byte[] buf = new byte[4];
|
||||||
|
private byte reader = 4;
|
||||||
|
private long markSeed;
|
||||||
|
private byte[] markbuf;
|
||||||
|
|
||||||
|
public SeedInputStream(long seed) {
|
||||||
|
this.seed = (seed ^ multiplier) & mask;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void calcSeed() {
|
||||||
|
seed = (seed * multiplier + addend) & mask;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void genNext() {
|
||||||
|
calcSeed();
|
||||||
|
int next = (int)(seed >>> 16);
|
||||||
|
buf[0] = (byte) (next >> 24);
|
||||||
|
buf[1] = (byte) (next >> 16);
|
||||||
|
buf[2] = (byte) (next >> 8);
|
||||||
|
buf[3] = (byte) next;
|
||||||
|
reader = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int read(byte[] b, int off, int len) {
|
||||||
|
for (int i = off; i < len; i++) {
|
||||||
|
if (reader >= 4) {
|
||||||
|
genNext();
|
||||||
|
}
|
||||||
|
b[i] = buf[reader++];
|
||||||
|
}
|
||||||
|
return len;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int read() {
|
||||||
|
if (reader == 4) {
|
||||||
|
genNext();
|
||||||
|
}
|
||||||
|
return buf[reader++];
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public long skip(long toSkip) {
|
||||||
|
long n = toSkip;
|
||||||
|
while (n > 0) {
|
||||||
|
if (reader < 4) {
|
||||||
|
reader++;
|
||||||
|
n--;
|
||||||
|
} else if (n >= 4) {
|
||||||
|
calcSeed();
|
||||||
|
n -= 4;
|
||||||
|
} else {
|
||||||
|
genNext();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return toSkip;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void close() {
|
||||||
|
buf = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean markSupported() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public synchronized void mark(int readlimit) {
|
||||||
|
markbuf = new byte[] {buf[0], buf[1], buf[2], buf[3], reader};
|
||||||
|
markSeed = seed;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public synchronized void reset() {
|
||||||
|
seed = markSeed;
|
||||||
|
buf = Arrays.copyOfRange(markbuf, 0, 4);
|
||||||
|
reader = markbuf[4];
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,67 @@
|
|||||||
|
package com.dre.brewery.lore;
|
||||||
|
|
||||||
|
|
||||||
|
import java.io.FilterOutputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.OutputStream;
|
||||||
|
import java.util.Random;
|
||||||
|
|
||||||
|
public class XORScrambleStream extends FilterOutputStream {
|
||||||
|
|
||||||
|
private final long seed;
|
||||||
|
private SeedInputStream xorStream;
|
||||||
|
private boolean running;
|
||||||
|
|
||||||
|
public XORScrambleStream(OutputStream out, long seed) {
|
||||||
|
super(out);
|
||||||
|
this.seed = seed;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void start() throws IOException {
|
||||||
|
running = true;
|
||||||
|
if (xorStream == null) {
|
||||||
|
short id = 0;
|
||||||
|
while (id == 0) {
|
||||||
|
id = (short) new Random().nextInt();
|
||||||
|
}
|
||||||
|
xorStream = new SeedInputStream(seed ^ id);
|
||||||
|
out.write((byte) (id >> 8));
|
||||||
|
out.write((byte) id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void stop() {
|
||||||
|
running = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void write(int b) throws IOException {
|
||||||
|
if (!running) {
|
||||||
|
out.write(b);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
out.write(b ^ xorStream.read());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void write(byte[] b, int off, int len) throws IOException {
|
||||||
|
if (!running) {
|
||||||
|
out.write(b, off, len);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
byte[] xored = new byte[len];
|
||||||
|
xorStream.read(xored);
|
||||||
|
int j = off;
|
||||||
|
for (int i = 0; i < len; i++) {
|
||||||
|
xored[i] ^= b[j++];
|
||||||
|
}
|
||||||
|
out.write(xored);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void close() throws IOException {
|
||||||
|
running = false;
|
||||||
|
xorStream = null;
|
||||||
|
super.close();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,100 @@
|
|||||||
|
package com.dre.brewery.lore;
|
||||||
|
|
||||||
|
import java.io.FilterInputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InputStream;
|
||||||
|
|
||||||
|
public class XORUnscrambleStream extends FilterInputStream {
|
||||||
|
|
||||||
|
private final long seed;
|
||||||
|
private SeedInputStream xorStream;
|
||||||
|
private boolean running;
|
||||||
|
private boolean markRunning;
|
||||||
|
private boolean markxor;
|
||||||
|
|
||||||
|
public XORUnscrambleStream(InputStream in, long seed) {
|
||||||
|
super(in);
|
||||||
|
this.seed = seed;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void start() throws IOException {
|
||||||
|
running = true;
|
||||||
|
if (xorStream == null) {
|
||||||
|
short id = (short) (in.read() << 8 | in.read());
|
||||||
|
if (id == 0) {
|
||||||
|
running = false;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
xorStream = new SeedInputStream(seed ^ id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void stop() {
|
||||||
|
running = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int read() throws IOException {
|
||||||
|
if (!running) {
|
||||||
|
return in.read();
|
||||||
|
}
|
||||||
|
return (in.read() ^ xorStream.read()) & 0xFF;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int read(byte[] b, int off, int len) throws IOException {
|
||||||
|
if (!running) {
|
||||||
|
return in.read(b, off, len);
|
||||||
|
}
|
||||||
|
len = in.read(b, off, len);
|
||||||
|
for (int i = off; i < len + off; i++) {
|
||||||
|
b[i] ^= xorStream.read();
|
||||||
|
}
|
||||||
|
return len;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public long skip(long n) throws IOException {
|
||||||
|
long skipped = in.skip(n);
|
||||||
|
if (running && skipped > 0) {
|
||||||
|
xorStream.skip(skipped);
|
||||||
|
}
|
||||||
|
return skipped;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void close() throws IOException {
|
||||||
|
if (xorStream != null) {
|
||||||
|
xorStream.close();
|
||||||
|
xorStream = null;
|
||||||
|
}
|
||||||
|
running = false;
|
||||||
|
super.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean markSupported() {
|
||||||
|
return in.markSupported();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public synchronized void reset() throws IOException {
|
||||||
|
in.reset();
|
||||||
|
if (markxor) {
|
||||||
|
xorStream.reset();
|
||||||
|
} else {
|
||||||
|
xorStream = null;
|
||||||
|
}
|
||||||
|
running = markRunning;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public synchronized void mark(int readlimit) {
|
||||||
|
in.mark(readlimit);
|
||||||
|
if (xorStream != null) {
|
||||||
|
xorStream.mark(readlimit);
|
||||||
|
markxor = true;
|
||||||
|
}
|
||||||
|
markRunning = running;
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user