diff --git a/src/com/dre/brewery/P.java b/src/com/dre/brewery/P.java index af3c17a..75e603b 100644 --- a/src/com/dre/brewery/P.java +++ b/src/com/dre/brewery/P.java @@ -11,8 +11,10 @@ import com.dre.brewery.integration.WGBarrel7; 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.bstats.bukkit.Metrics; import org.bukkit.Bukkit; @@ -91,8 +93,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); @@ -110,10 +111,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]); diff --git a/src/com/dre/brewery/listeners/InventoryListener.java b/src/com/dre/brewery/listeners/InventoryListener.java index 5564009..1d7c286 100644 --- a/src/com/dre/brewery/listeners/InventoryListener.java +++ b/src/com/dre/brewery/listeners/InventoryListener.java @@ -7,8 +7,10 @@ import com.dre.brewery.Brew; import com.dre.brewery.MCBarrel; import com.dre.brewery.P; 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.Sound; @@ -305,34 +307,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(); } } } diff --git a/src/com/dre/brewery/lore/LoreInputStream.java b/src/com/dre/brewery/lore/Base91DecoderStream.java similarity index 63% rename from src/com/dre/brewery/lore/LoreInputStream.java rename to src/com/dre/brewery/lore/Base91DecoderStream.java index d346917..9258705 100644 --- a/src/com/dre/brewery/lore/LoreInputStream.java +++ b/src/com/dre/brewery/lore/Base91DecoderStream.java @@ -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 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(); } } diff --git a/src/com/dre/brewery/lore/LoreOutputStream.java b/src/com/dre/brewery/lore/Base91EncoderStream.java similarity index 59% rename from src/com/dre/brewery/lore/LoreOutputStream.java rename to src/com/dre/brewery/lore/Base91EncoderStream.java index 6352c74..c1b60f3 100644 --- a/src/com/dre/brewery/lore/LoreOutputStream.java +++ b/src/com/dre/brewery/lore/Base91EncoderStream.java @@ -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 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; } } diff --git a/src/com/dre/brewery/lore/LoreReader.java b/src/com/dre/brewery/lore/LoreReader.java new file mode 100644 index 0000000..b12f2ec --- /dev/null +++ b/src/com/dre/brewery/lore/LoreReader.java @@ -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 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"); + } +} diff --git a/src/com/dre/brewery/lore/LoreWriter.java b/src/com/dre/brewery/lore/LoreWriter.java index 1550ded..cdeab97 100644 --- a/src/com/dre/brewery/lore/LoreWriter.java +++ b/src/com/dre/brewery/lore/LoreWriter.java @@ -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 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; } }