Split LoreIn/OutputStream

Implemented skip, mark and reset
This commit is contained in:
Sn0wStorm 2016-05-28 22:18:03 +02:00
parent c43c9b1203
commit 26b607c17a
6 changed files with 180 additions and 115 deletions

View File

@ -6,8 +6,10 @@ import com.dre.brewery.integration.WGBarrel;
import com.dre.brewery.integration.WGBarrelNew;
import com.dre.brewery.integration.WGBarrelOld;
import com.dre.brewery.listeners.*;
import com.dre.brewery.lore.LoreInputStream;
import com.dre.brewery.lore.LoreOutputStream;
import com.dre.brewery.lore.Base91DecoderStream;
import com.dre.brewery.lore.Base91EncoderStream;
import com.dre.brewery.lore.LoreReader;
import com.dre.brewery.lore.LoreWriter;
import org.apache.commons.lang.math.NumberUtils;
import org.bukkit.*;
import org.bukkit.block.Block;
@ -66,8 +68,7 @@ public class P extends JavaPlugin {
try {
ItemMeta meta = new ItemStack(Material.POTION).getItemMeta();
LoreOutputStream out = new LoreOutputStream(meta, 3);
DataOutputStream data = new DataOutputStream(out);
DataOutputStream data = new DataOutputStream(new Base91EncoderStream(new LoreWriter(meta, 3)));
data.writeInt(2);
data.writeLong(5);
@ -85,10 +86,10 @@ public class P extends JavaPlugin {
data.close();
meta.getLore();
LoreInputStream in = new LoreInputStream(meta);
DataInputStream dataIn = new DataInputStream(in);
DataInputStream dataIn = new DataInputStream(new Base91DecoderStream(new LoreReader(meta)));
P.p.log(dataIn.readInt() + ", " + dataIn.readLong() + ", ");
byte[] testIn = new byte[128];
dataIn.read(testIn);
P.p.log(testIn[1] + ", " + testIn[2] + ", " + testIn[3] + ", " + testIn[127]);

View File

@ -2,8 +2,10 @@ package com.dre.brewery.listeners;
import com.dre.brewery.*;
import com.dre.brewery.integration.LogBlockBarrel;
import com.dre.brewery.lore.LoreInputStream;
import com.dre.brewery.lore.LoreOutputStream;
import com.dre.brewery.lore.Base91DecoderStream;
import com.dre.brewery.lore.Base91EncoderStream;
import com.dre.brewery.lore.LoreReader;
import com.dre.brewery.lore.LoreWriter;
import org.bukkit.Bukkit;
import org.bukkit.Material;
import org.bukkit.block.Block;
@ -237,34 +239,51 @@ public class InventoryListener implements Listener {
brew.touch();
try {
LoreInputStream loreIn = new LoreInputStream(potion);
DataInputStream in = new DataInputStream(loreIn);
DataInputStream in = new DataInputStream(new Base91DecoderStream(new LoreReader(potion)));
if (in.readByte() == 27 && in.readUTF().equals("TESTHalloª∆Ω") && in.readInt() == 34834 && in.readLong() == Long.MAX_VALUE) {
P.p.log("true");
if (in.readByte() == 27 && in.skip(48) > 0) {
in.mark(100);
if (in.readUTF().equals("TESTHalloª∆Ω") && in.readInt() == 34834 && in.skip(4) > 0 && in.readLong() == Long.MAX_VALUE) {
in.reset();
if (in.readUTF().equals("TESTHalloª∆Ω")) {
P.p.log("true");
} else {
P.p.log("false3");
}
} else {
P.p.log("false2");
}
} else {
P.p.log("false");
P.p.log("false1");
}
in.close();
} catch (IOException e) {
e.printStackTrace();
}
try {
try {
LoreOutputStream lore = new LoreOutputStream(potion, 3);
DataOutputStream out = new DataOutputStream(lore);
DataOutputStream out = new DataOutputStream(new Base91EncoderStream(new LoreWriter(potion, 0)));
out.writeByte(27);
out.writeUTF("TESTHalloª∆Ω");
out.writeInt(34834);
out.writeLong(Long.MAX_VALUE);
out.writeByte(27);
out.writeLong(1111); //skip
out.writeLong(1111); //skip
out.writeLong(1111); //skip
out.writeLong(1111); //skip
out.writeLong(1111); //skip
out.writeLong(1111); //skip
out.writeUTF("TESTHalloª∆Ω");
out.writeInt(34834);
out.writeInt(6436); //skip
out.writeLong(Long.MAX_VALUE);
out.close();
item.setItemMeta(potion);
out.close();
item.setItemMeta(potion);
} catch (IOException h) {
h.printStackTrace();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}

View File

@ -1,14 +1,10 @@
package com.dre.brewery.lore;
import org.bukkit.inventory.meta.ItemMeta;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.FilterInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.List;
public class LoreInputStream extends InputStream {
public class Base91DecoderStream extends FilterInputStream {
private static final basE91 DECODER = new basE91();
@ -16,34 +12,15 @@ public class LoreInputStream extends InputStream {
private byte[] buf = new byte[16];
private int reader = 0;
private int count = 0;
private ByteArrayInputStream readStream;
private byte[] markBuf = null;
public LoreInputStream(ItemMeta meta) throws IOException {
if (meta.hasLore()) {
List<String> lore = meta.getLore();
for (String line : lore) {
if (line.startsWith("§%")) {
StringBuilder build = new StringBuilder((int) (line.length() / 2F));
byte skip = 2;
for (char c : line.toCharArray()) {
if (skip > 0) {
skip--;
continue;
}
if (c == '§') continue;
build.append(c);
}
readStream = new ByteArrayInputStream(build.toString().getBytes());
break;
}
}
}
if (readStream == null) throw new IOException("Meta has no data in lore");
public Base91DecoderStream(InputStream in) {
super(in);
}
private void decode() throws IOException {
reader = 0;
count = readStream.read(decbuf);
count = in.read(decbuf);
if (count < 1) {
count = DECODER.decEnd(buf);
if (count < 1) {
@ -102,39 +79,68 @@ public class LoreInputStream extends InputStream {
@Override
public long skip(long n) throws IOException {
return super.skip(n);
if (count == -1) return 0;
if (count > 0 && count - reader >= n) {
reader += n;
return n;
}
long skipped = count - reader;
decode();
while (count > 0) {
if (count > n - skipped) {
reader = (int) (n - skipped);
return n;
}
skipped += count;
decode();
}
return skipped;
}
@Override
public int available() throws IOException {
return Math.round(readStream.available() * 0.813F); // Ratio encoded to decoded with random data
return Math.round(in.available() * 0.813F); // Ratio encoded to decoded with random data
}
@Override
public void close() throws IOException {
in.close();
count = -1;
DECODER.decReset();
buf = null;
decbuf = null;
readStream = null;
}
@Override
public synchronized void mark(int readlimit) {
if (!markSupported()) return;
readStream.mark(readlimit);
if (count == -1) return;
in.mark(readlimit);
DECODER.decMark();
if (count > 0 && reader < count) {
markBuf = new byte[count - reader];
System.arraycopy(buf, reader, markBuf, 0, markBuf.length);
} else {
markBuf = null;
}
}
@Override
public synchronized void reset() throws IOException {
if (!markSupported()) super.reset();
readStream.reset();
if (!markSupported()) throw new IOException("mark and reset not supported");
in.reset();
DECODER.decUnmark();
reader = 0;
count = 0;
if (markBuf != null) {
System.arraycopy(markBuf, 0, buf, 0, markBuf.length);
count = markBuf.length;
}
}
@Override
public boolean markSupported() {
return readStream.markSupported();
return in.markSupported();
}
}

View File

@ -1,12 +1,11 @@
package com.dre.brewery.lore;
import org.bukkit.inventory.meta.ItemMeta;
import java.io.ByteArrayInputStream;
import java.io.FilterOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.io.*;
import java.util.ArrayList;
import java.util.List;
public class LoreOutputStream extends OutputStream {
public class Base91EncoderStream extends FilterOutputStream {
private static final basE91 ENCODER = new basE91();
@ -15,18 +14,13 @@ public class LoreOutputStream extends OutputStream {
private int writer = 0;
private int encoded = 0;
private ItemMeta meta;
private final int line;
private ByteArrayOutputStream stream = new ByteArrayOutputStream(128);
public LoreOutputStream(ItemMeta meta, int line) {
this.meta = meta;
this.line = line;
public Base91EncoderStream(OutputStream out) {
super(out);
}
private void encFlush() {
private void encFlush() throws IOException {
encoded = ENCODER.encode(buf, writer, encBuf);
stream.write(encBuf, 0, encoded);
out.write(encBuf, 0, encoded);
writer = 0;
}
@ -60,7 +54,7 @@ public class LoreOutputStream extends OutputStream {
// Buffer is too full, so flush and encode data directly
encFlush();
encoded = ENCODER.encode(b, len, encBuf);
stream.write(encBuf, 0, encoded);
out.write(encBuf, 0, encoded);
return;
}
@ -78,47 +72,22 @@ public class LoreOutputStream extends OutputStream {
@Override
public void flush() throws IOException {
super.flush();
if (writer > 0) {
encFlush();
}
encoded = ENCODER.encEnd(encBuf);
if (encoded > 0) {
stream.write(encBuf, 0, encoded);
out.write(encBuf, 0, encoded);
}
if (stream.size() <= 0) return;
stream.flush();
String s = stream.toString();
StringBuilder loreLineBuilder = new StringBuilder((s.length() * 2) + 6);
loreLineBuilder.append("§%");
for (char c : s.toCharArray()) {
loreLineBuilder.append('§').append(c);
}
List<String> lore;
if (meta.hasLore()) {
lore = meta.getLore();
} else {
lore = new ArrayList<>();
}
while (lore.size() < line) {
lore.add("");
}
//TODO when existing data string in lore
lore.add(line, loreLineBuilder.toString());
meta.setLore(lore);
super.flush();
}
@Override
public void close() throws IOException {
super.close();
stream.close();
ENCODER.encReset();
buf = null;
encBuf = null;
meta = null;
stream = null;
}
}

View File

@ -0,0 +1,36 @@
package com.dre.brewery.lore;
import org.bukkit.inventory.meta.ItemMeta;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.util.List;
public class LoreReader extends ByteArrayInputStream {
public LoreReader(ItemMeta meta) throws IOException {
super(loreToBytes(meta));
}
private static byte[] loreToBytes(ItemMeta meta) throws IOException {
if (meta.hasLore()) {
List<String> lore = meta.getLore();
for (String line : lore) {
if (line.startsWith("§%")) {
StringBuilder build = new StringBuilder((int) (line.length() / 2F));
byte skip = 2;
for (char c : line.toCharArray()) {
if (skip > 0) {
skip--;
continue;
}
if (c == '§') continue;
build.append(c);
}
return build.toString().getBytes();
}
}
}
throw new IOException("Meta has no data in lore");
}
}

View File

@ -2,24 +2,58 @@ package com.dre.brewery.lore;
import org.bukkit.inventory.meta.ItemMeta;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.List;
public class LoreWriter extends OutputStream {
public class LoreWriter extends ByteArrayOutputStream {
ItemMeta meta;
private ItemMeta meta;
private int line;
private boolean flushed = false;
public LoreWriter(ItemMeta meta) {
public LoreWriter(ItemMeta meta, int line) {
super(128);
this.meta = meta;
this.line = line;
}
// Writes to the Lore
// Without calling this, the ItemMeta remains unchanged
@Override
public void flush() throws IOException {
super.flush();
if (size() <= 0) return;
if (flushed) {
// Dont write twice
return;
}
flushed = true;
String s = toString();
StringBuilder loreLineBuilder = new StringBuilder((s.length() * 2) + 6);
loreLineBuilder.append("§%");
for (char c : s.toCharArray()) {
loreLineBuilder.append('§').append(c);
}
List<String> lore;
if (meta.hasLore()) {
lore = meta.getLore();
} else {
lore = new ArrayList<>();
}
while (lore.size() < line) {
lore.add("");
}
//TODO when existing data string in lore
lore.add(line, loreLineBuilder.toString());
meta.setLore(lore);
}
@Override
public void write(int b) throws IOException {
}
@Override
public void write(byte[] b, int off, int len) throws IOException {
public void close() throws IOException {
super.close();
meta = null;
}
}