From 75d0f2f201218c0f32fc4678e0b5a8ea4679a198 Mon Sep 17 00:00:00 2001 From: Sn0wStorm Date: Sat, 28 May 2016 14:08:33 +0200 Subject: [PATCH 01/51] Started LoreOutputStream storing data with Base91 --- src/com/dre/brewery/P.java | 104 +++++++++++++ .../dre/brewery/lore/LoreOutputStream.java | 123 ++++++++++++++++ src/com/dre/brewery/lore/LoreWriter.java | 25 ++++ src/com/dre/brewery/lore/basE91.java | 139 ++++++++++++++++++ 4 files changed, 391 insertions(+) create mode 100644 src/com/dre/brewery/lore/LoreOutputStream.java create mode 100644 src/com/dre/brewery/lore/LoreWriter.java create mode 100644 src/com/dre/brewery/lore/basE91.java diff --git a/src/com/dre/brewery/P.java b/src/com/dre/brewery/P.java index f891907..e464b27 100644 --- a/src/com/dre/brewery/P.java +++ b/src/com/dre/brewery/P.java @@ -18,6 +18,7 @@ import org.bukkit.ChatColor; import org.bukkit.Location; import org.bukkit.Material; import org.bukkit.World; +import com.dre.brewery.lore.LoreOutputStream; import org.bukkit.block.Block; import org.bukkit.command.CommandSender; import org.bukkit.configuration.ConfigurationSection; @@ -85,6 +86,109 @@ 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"); + + try { + ItemMeta meta = new ItemStack(Material.POTION).getItemMeta(); + LoreOutputStream out = new LoreOutputStream(meta, 3); + DataOutputStream data = new DataOutputStream(out); + + data.writeInt(2); + data.writeLong(5); + + byte[] test = new byte[128]; + test[1] = 6; + test[2] = 12; + test[3] = 21; + data.write(test); + + data.writeInt(123324); + data.writeLong(12343843); + + data.close(); + meta.getLore(); + + + + /*basE91 basE91 = new basE91(); + int[] input = new int[] {12, 65, 324, 5, 12, 129459, 1234567, Integer.MIN_VALUE, Integer.MAX_VALUE}; + ByteArrayOutputStream stream = new ByteArrayOutputStream(); + DataOutputStream data = new DataOutputStream(stream); + for (int i = 0; i < input.length; i++) { + data.writeInt(input[i]); + } + data.flush(); + data.close(); + byte[] in = stream.toByteArray(); + byte[] out = new byte[4096]; + int lenght = basE91.encode(in, in.length, out); + basE91.encEnd(out); + String done = new String(out, 0, lenght); + + byte[] tin = done.getBytes(); + + byte[] tout = new byte[4096]; + lenght = basE91.decode(tin, tin.length, tout); + basE91.decEnd(tout); + + + ByteArrayInputStream tstream = new ByteArrayInputStream(tout, 0, lenght); + DataInputStream tdata = new DataInputStream(tstream); + int[] test = new int[4096]; + for (int j = 0; j < 6; j++) { + if (tstream.available() <= 0) break; + test[j] = tdata.readInt(); + + } + tdata.close(); + test = test;*/ + + + + /*basE91 basE91 = new basE91(); + int[] input = new int[] {12, 65, 324, 5, 12, 129459, 1234567, Integer.MIN_VALUE, Integer.MAX_VALUE}; + ByteArrayOutputStream stream = new ByteArrayOutputStream(); + DataOutputStream data = new DataOutputStream(stream); + for (int i = 0; i < input.length; i++) { + data.writeInt(input[i]); + } + data.flush(); + data.close(); + ByteArrayOutputStream out = new ByteArrayOutputStream(); + ByteArrayInputStream in = new ByteArrayInputStream(stream.toByteArray()); + + encode(in, out, in.available()); + + in.close(); + out.flush(); + out.close(); + + String done = new String(out.toByteArray()); + + ByteArrayInputStream tin = new ByteArrayInputStream(done.getBytes()); + ByteArrayOutputStream tout = new ByteArrayOutputStream(); + + decode(tin, tout, tin.available()); + + tin.close(); + tout.flush(); + tout.close(); + + ByteArrayInputStream tstream = new ByteArrayInputStream(tout.toByteArray()); + DataInputStream tdata = new DataInputStream(tstream); + int[] test = new int[4096]; + for (int j = 0; j < 9; j++) { + if (tstream.available() <= 0) break; + test[j] = tdata.readInt(); + + } + tdata.close(); + test = test;*/ + + } catch (IOException e) { + e.printStackTrace(); + } + + // load the Config try { if (!readConfig()) { diff --git a/src/com/dre/brewery/lore/LoreOutputStream.java b/src/com/dre/brewery/lore/LoreOutputStream.java new file mode 100644 index 0000000..128f460 --- /dev/null +++ b/src/com/dre/brewery/lore/LoreOutputStream.java @@ -0,0 +1,123 @@ +package com.dre.brewery.lore; + +import org.bukkit.inventory.meta.ItemMeta; + +import java.io.*; +import java.util.ArrayList; +import java.util.List; + +public class LoreOutputStream extends OutputStream { + + private static final basE91 ENCODER = new basE91(); + + private byte[] buf = new byte[16]; + private byte[] encBuf = new byte[24]; + 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; + } + + private void encFlush() { + encoded = ENCODER.encode(buf, writer, encBuf); + stream.write(encBuf, 0, encoded); + writer = 0; + } + + @Override + public void write(int b) throws IOException { + buf[writer++] = (byte) b; + if (writer >= buf.length) { + encFlush(); + } + } + + @Override + public void write(byte[] b, int off, int len) throws IOException { + if (len == 0) return; + if (b == null) throw new NullPointerException(); + if (len < 0 || off < 0 || (off + len) > b.length || off > b.length || (off + len) < 0) { + throw new IndexOutOfBoundsException(); + } + + if (buf.length - writer >= len) { + // Enough space in the buffer, copy it in + System.arraycopy(b, off, buf, writer, len); + writer += len; + if (writer >= buf.length) { + encFlush(); + } + return; + } + + if (off == 0 && buf.length >= len) { + // Buffer is too full, so flush and encode data directly + encFlush(); + encoded = ENCODER.encode(b, len, encBuf); + stream.write(encBuf, 0, encoded); + return; + } + + // More data than space in the Buffer + ByteArrayInputStream in = new ByteArrayInputStream(b, off, len); + while (true) { + writer += in.read(buf, writer, buf.length - writer); + if (writer >= buf.length) { + encFlush(); + } else { + break; + } + } + } + + @Override + public void flush() throws IOException { + super.flush(); + if (writer > 0) { + encFlush(); + } + + encoded = ENCODER.encEnd(encBuf); + if (encoded > 0) { + stream.write(encBuf, 0, encoded); + } + if (stream.size() <= 0) return; + + stream.flush(); + String s = stream.toString(); + + StringBuilder loreLineBuilder = new StringBuilder(s.length() * 2); + 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 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/LoreWriter.java b/src/com/dre/brewery/lore/LoreWriter.java new file mode 100644 index 0000000..1550ded --- /dev/null +++ b/src/com/dre/brewery/lore/LoreWriter.java @@ -0,0 +1,25 @@ +package com.dre.brewery.lore; + +import org.bukkit.inventory.meta.ItemMeta; + +import java.io.IOException; +import java.io.OutputStream; + +public class LoreWriter extends OutputStream { + + ItemMeta meta; + + public LoreWriter(ItemMeta meta) { + this.meta = meta; + } + + @Override + public void write(int b) throws IOException { + + } + + @Override + public void write(byte[] b, int off, int len) throws IOException { + + } +} diff --git a/src/com/dre/brewery/lore/basE91.java b/src/com/dre/brewery/lore/basE91.java new file mode 100644 index 0000000..be38b14 --- /dev/null +++ b/src/com/dre/brewery/lore/basE91.java @@ -0,0 +1,139 @@ +package com.dre.brewery.lore; + +/* + * basE91 encoding/decoding routines + * + * Copyright (c) 2000-2006 Joachim Henke + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * - Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * - Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * - Neither the name of Joachim Henke nor the names of his contributors may + * be used to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +public class basE91 +{ + private int ebq, en, dbq, dn, dv; + public final byte[] enctab; + private final byte[] dectab; + + public int encode(byte[] ib, int n, byte[] ob) + { + int i, c = 0; + + for (i = 0; i < n; ++i) { + ebq |= (ib[i] & 255) << en; + en += 8; + if (en > 13) { + int ev = ebq & 8191; + + if (ev > 88) { + ebq >>= 13; + en -= 13; + } else { + ev = ebq & 16383; + ebq >>= 14; + en -= 14; + } + ob[c++] = enctab[ev % 91]; + ob[c++] = enctab[ev / 91]; + } + } + return c; + } + + public int encEnd(byte[] ob) + { + int c = 0; + + if (en > 0) { + ob[c++] = enctab[ebq % 91]; + if (en > 7 || ebq > 90) + ob[c++] = enctab[ebq / 91]; + } + encReset(); + return c; + } + + public void encReset() + { + ebq = 0; + en = 0; + } + + public int decode(byte[] ib, int n, byte[] ob) + { + int i, c = 0; + + for (i = 0; i < n; ++i) { + if (dectab[ib[i]] == -1) + continue; + if (dv == -1) + dv = dectab[ib[i]]; + else { + dv += dectab[ib[i]] * 91; + dbq |= dv << dn; + dn += (dv & 8191) > 88 ? 13 : 14; + do { + ob[c++] = (byte) dbq; + dbq >>= 8; + dn -= 8; + } while (dn > 7); + dv = -1; + } + } + return c; + } + + public int decEnd(byte[] ob) + { + int c = 0; + + if (dv != -1) + ob[c++] = (byte) (dbq | dv << dn); + decReset(); + return c; + } + + public void decReset() + { + dbq = 0; + dn = 0; + dv = -1; + } + + public basE91() + { + int i; + String ts = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789!$%&()*+,-./:;<=>?@[\\]^_`{|}~"; + + enctab = ts.getBytes(); + dectab = new byte[256]; + for (i = 0; i < 256; ++i) + dectab[i] = -1; + for (i = 0; i < 91; ++i) + dectab[enctab[i]] = (byte) i; + encReset(); + decReset(); + } +} From 41fac3b08ad3d98e6e619b6063adaef8da272a31 Mon Sep 17 00:00:00 2001 From: Sn0wStorm Date: Sat, 28 May 2016 18:47:51 +0200 Subject: [PATCH 02/51] Created LoreInputStream --- src/com/dre/brewery/P.java | 15 ++ .../brewery/listeners/InventoryListener.java | 36 +++++ src/com/dre/brewery/lore/LoreInputStream.java | 140 ++++++++++++++++++ .../dre/brewery/lore/LoreOutputStream.java | 3 +- src/com/dre/brewery/lore/basE91.java | 12 ++ 5 files changed, 205 insertions(+), 1 deletion(-) create mode 100644 src/com/dre/brewery/lore/LoreInputStream.java diff --git a/src/com/dre/brewery/P.java b/src/com/dre/brewery/P.java index e464b27..af3c17a 100644 --- a/src/com/dre/brewery/P.java +++ b/src/com/dre/brewery/P.java @@ -11,6 +11,8 @@ 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 org.apache.commons.lang.math.NumberUtils; import org.bstats.bukkit.Metrics; import org.bukkit.Bukkit; @@ -99,6 +101,7 @@ public class P extends JavaPlugin { test[1] = 6; test[2] = 12; test[3] = 21; + test[127] = 99; data.write(test); data.writeInt(123324); @@ -107,6 +110,18 @@ public class P extends JavaPlugin { data.close(); meta.getLore(); + LoreInputStream in = new LoreInputStream(meta); + DataInputStream dataIn = new DataInputStream(in); + + 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]); + + P.p.log(dataIn.readInt() + ", " + dataIn.readLong() + ", "); + + dataIn.close(); + /*basE91 basE91 = new basE91(); diff --git a/src/com/dre/brewery/listeners/InventoryListener.java b/src/com/dre/brewery/listeners/InventoryListener.java index 7df7504..5564009 100644 --- a/src/com/dre/brewery/listeners/InventoryListener.java +++ b/src/com/dre/brewery/listeners/InventoryListener.java @@ -7,6 +7,8 @@ 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 org.bukkit.Bukkit; import org.bukkit.Material; import org.bukkit.Sound; @@ -34,6 +36,9 @@ import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.meta.PotionMeta; import org.bukkit.scheduler.BukkitRunnable; +import java.io.DataInputStream; +import java.io.DataOutputStream; +import java.io.IOException; import java.util.HashMap; import java.util.HashSet; import java.util.Iterator; @@ -298,6 +303,37 @@ public class InventoryListener implements Listener { } } brew.touch(); + + try { + LoreInputStream loreIn = new LoreInputStream(potion); + DataInputStream in = new DataInputStream(loreIn); + + if (in.readByte() == 27 && in.readUTF().equals("TESTHalloª∆Ω") && in.readInt() == 34834 && in.readLong() == Long.MAX_VALUE) { + P.p.log("true"); + } else { + P.p.log("false"); + } + in.close(); + } catch (IOException e) { + e.printStackTrace(); + } + + try { + + LoreOutputStream lore = new LoreOutputStream(potion, 3); + DataOutputStream out = new DataOutputStream(lore); + + out.writeByte(27); + out.writeUTF("TESTHalloª∆Ω"); + out.writeInt(34834); + out.writeLong(Long.MAX_VALUE); + + out.close(); + item.setItemMeta(potion); + + } catch (IOException e) { + e.printStackTrace(); + } } } } diff --git a/src/com/dre/brewery/lore/LoreInputStream.java b/src/com/dre/brewery/lore/LoreInputStream.java new file mode 100644 index 0000000..d346917 --- /dev/null +++ b/src/com/dre/brewery/lore/LoreInputStream.java @@ -0,0 +1,140 @@ +package com.dre.brewery.lore; + +import org.bukkit.inventory.meta.ItemMeta; + +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.util.List; + +public class LoreInputStream extends InputStream { + + private static final basE91 DECODER = new basE91(); + + private byte[] decbuf = new byte[18]; + private byte[] buf = new byte[16]; + private int reader = 0; + private int count = 0; + private ByteArrayInputStream readStream; + + 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"); + } + + private void decode() throws IOException { + reader = 0; + count = readStream.read(decbuf); + if (count < 1) { + count = DECODER.decEnd(buf); + if (count < 1) { + count = -1; + } + return; + } + count = DECODER.decode(decbuf, count, buf); + } + + @Override + public int read() throws IOException { + if (count == -1) return -1; + if (count == 0 || reader == count) { + decode(); + return read(); + } + return buf[reader++] & 0xFF; + } + + @Override + public int read(byte[] b, int off, int len) throws IOException { + if (b == null) throw new NullPointerException(); + if (off < 0 || len < 0 || len > b.length - off) throw new IndexOutOfBoundsException(); + if (len == 0) return 0; + + if (count == -1) return -1; + if (count == 0 || reader == count) { + decode(); + if (count == -1) return -1; + } + + if (count > 0 && count - reader >= len) { + // enough data in buffer, copy it out directly + System.arraycopy(buf, reader, b, off, len); + reader += len; + return len; + } + + int out = 0; + int writeSize; + while (count > 0) { + writeSize = Math.min(len, count - reader); + System.arraycopy(buf, reader, b, off + out, writeSize); + out += writeSize; + len -= writeSize; + if (len > 0) { + decode(); + } else { + reader += writeSize; + break; + } + } + return out; + } + + @Override + public long skip(long n) throws IOException { + return super.skip(n); + } + + @Override + public int available() throws IOException { + return Math.round(readStream.available() * 0.813F); // Ratio encoded to decoded with random data + } + + @Override + public void close() throws IOException { + count = -1; + DECODER.decReset(); + buf = null; + decbuf = null; + readStream = null; + } + + @Override + public synchronized void mark(int readlimit) { + if (!markSupported()) return; + readStream.mark(readlimit); + DECODER.decMark(); + } + + @Override + public synchronized void reset() throws IOException { + if (!markSupported()) super.reset(); + readStream.reset(); + DECODER.decUnmark(); + } + + @Override + public boolean markSupported() { + return readStream.markSupported(); + } +} diff --git a/src/com/dre/brewery/lore/LoreOutputStream.java b/src/com/dre/brewery/lore/LoreOutputStream.java index 128f460..6352c74 100644 --- a/src/com/dre/brewery/lore/LoreOutputStream.java +++ b/src/com/dre/brewery/lore/LoreOutputStream.java @@ -92,7 +92,8 @@ public class LoreOutputStream extends OutputStream { stream.flush(); String s = stream.toString(); - StringBuilder loreLineBuilder = new StringBuilder(s.length() * 2); + StringBuilder loreLineBuilder = new StringBuilder((s.length() * 2) + 6); + loreLineBuilder.append("§%"); for (char c : s.toCharArray()) { loreLineBuilder.append('§').append(c); } diff --git a/src/com/dre/brewery/lore/basE91.java b/src/com/dre/brewery/lore/basE91.java index be38b14..12a0b94 100644 --- a/src/com/dre/brewery/lore/basE91.java +++ b/src/com/dre/brewery/lore/basE91.java @@ -34,6 +34,7 @@ package com.dre.brewery.lore; public class basE91 { private int ebq, en, dbq, dn, dv; + private int[] marker = null; public final byte[] enctab; private final byte[] dectab; @@ -122,6 +123,17 @@ public class basE91 dv = -1; } + public void decMark() { + marker = new int[] {dbq, dn, dv}; + } + + public void decUnmark() { + if (marker == null) return; + dbq = marker[0]; + dn = marker[1]; + dv = marker[2]; + } + public basE91() { int i; From 6311b9ed150463dfccbcd92ca2b800366e390adb Mon Sep 17 00:00:00 2001 From: Sn0wStorm Date: Sat, 28 May 2016 22:18:03 +0200 Subject: [PATCH 03/51] Split LoreIn/OutputStream Implemented skip, mark and reset --- src/com/dre/brewery/P.java | 13 ++-- .../brewery/listeners/InventoryListener.java | 57 +++++++++----- ...utStream.java => Base91DecoderStream.java} | 78 ++++++++++--------- ...utStream.java => Base91EncoderStream.java} | 55 +++---------- src/com/dre/brewery/lore/LoreReader.java | 36 +++++++++ src/com/dre/brewery/lore/LoreWriter.java | 56 ++++++++++--- 6 files changed, 180 insertions(+), 115 deletions(-) rename src/com/dre/brewery/lore/{LoreInputStream.java => Base91DecoderStream.java} (63%) rename src/com/dre/brewery/lore/{LoreOutputStream.java => Base91EncoderStream.java} (59%) create mode 100644 src/com/dre/brewery/lore/LoreReader.java 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; } } From ed40a1f60877f0049644aa59aff090d1802842a6 Mon Sep 17 00:00:00 2001 From: Sn0wStorm Date: Mon, 30 May 2016 22:12:34 +0200 Subject: [PATCH 04/51] Test storing and loading a brew from lore --- src/com/dre/brewery/BIngredients.java | 34 +++++++++ src/com/dre/brewery/Brew.java | 76 +++++++++++++++++++ .../brewery/listeners/InventoryListener.java | 15 ++-- 3 files changed, 120 insertions(+), 5 deletions(-) diff --git a/src/com/dre/brewery/BIngredients.java b/src/com/dre/brewery/BIngredients.java index 1859824..d68d6f0 100644 --- a/src/com/dre/brewery/BIngredients.java +++ b/src/com/dre/brewery/BIngredients.java @@ -6,6 +6,9 @@ import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.meta.PotionMeta; import org.bukkit.potion.PotionEffectType; +import java.io.DataInputStream; +import java.io.DataOutputStream; +import java.io.IOException; import java.util.*; public class BIngredients { @@ -321,6 +324,37 @@ public class BIngredients { return copy; } + public void testStore(DataOutputStream out) throws IOException { + out.writeInt(cookedTime); + out.writeByte(ingredients.size()); + for (ItemStack item : ingredients) { + out.writeUTF(item.getType().name()); + out.writeShort(item.getDurability()); + out.writeShort(item.getAmount()); + } + } + + public void testLoad(DataInputStream in) throws IOException { + if (in.readInt() != cookedTime) { + P.p.log("cookedtime wrong"); + } + if (in.readUnsignedByte() != ingredients.size()) { + P.p.log("size wrong"); + return; + } + for (ItemStack item : ingredients) { + if (!in.readUTF().equals(item.getType().name())) { + P.p.log("name wrong"); + } + if (in.readShort() != item.getDurability()) { + P.p.log("dur wrong"); + } + if (in.readShort() != item.getAmount()) { + P.p.log("amount wrong"); + } + } + } + // saves data into main Ingredient section. Returns the save id public int save(ConfigurationSection config) { String path = "Ingredients." + id; diff --git a/src/com/dre/brewery/Brew.java b/src/com/dre/brewery/Brew.java index 60994b4..58f371a 100644 --- a/src/com/dre/brewery/Brew.java +++ b/src/com/dre/brewery/Brew.java @@ -12,6 +12,9 @@ import org.bukkit.potion.PotionEffect; import org.bukkit.potion.PotionEffectType; import org.bukkit.potion.PotionType; +import java.io.DataInputStream; +import java.io.DataOutputStream; +import java.io.IOException; import java.util.ArrayList; import java.util.HashMap; import java.util.List; @@ -649,6 +652,79 @@ public class Brew { return P.p.color(color); } + public void testStore(DataOutputStream out) throws IOException { + out.writeByte(1); // Version + out.writeByte(86); // Parity + out.writeInt(quality); + int bools = 0; + bools += (distillRuns != 0 ? 1 : 0); + bools += (ageTime > 0 ? 2 : 0); + bools += (wood != -1 ? 4 : 0); + bools += (currentRecipe != null ? 8 : 0); + bools += (unlabeled ? 16 : 0); + bools += (persistent ? 32 : 0); + bools += (stat ? 64 : 0); + out.writeByte(bools); + if (distillRuns != 0) { + out.writeByte(distillRuns); + } + if (ageTime > 0) { + out.writeFloat(ageTime); + } + if (wood != -1) { + out.writeFloat(wood); + } + if (currentRecipe != null) { + out.writeUTF(currentRecipe.getName(5)); + } + ingredients.testStore(out); + } + + public void testLoad(DataInputStream in) throws IOException { + if (in.readByte() != 1) { + P.p.log("unknown version"); + return; + } + if (in.readByte() != 86) { + P.p.log("parity check failed"); + return; + } + if (in.readInt() != quality) { + P.p.log("quality wrong"); + } + int bools = in.readUnsignedByte(); + if ((bools & 1) != 0) { + if (in.readByte() != distillRuns) { + P.p.log("distillruns wrong"); + } + } + if ((bools & 2) != 0) { + if (in.readFloat() != ageTime) { + P.p.log("agetime wrong"); + } + } + if ((bools & 4) != 0) { + if (in.readFloat() != wood) { + P.p.log("wood wrong"); + } + } + if ((bools & 8) != 0) { + if (!in.readUTF().equals(currentRecipe.getName(5))) { + P.p.log("currecipe wrong"); + } + } + if ((bools & 16) != 0 && !unlabeled) { + P.p.log("unlabeled wrong"); + } + if ((bools & 32) != 0 && !persistent) { + P.p.log("persistent wrong"); + } + if ((bools & 64) != 0 && !stat) { + P.p.log("stat wrong"); + } + ingredients.testLoad(in); + } + // Saves all data public static void save(ConfigurationSection config) { for (Map.Entry entry : potions.entrySet()) { diff --git a/src/com/dre/brewery/listeners/InventoryListener.java b/src/com/dre/brewery/listeners/InventoryListener.java index 1d7c286..094d75f 100644 --- a/src/com/dre/brewery/listeners/InventoryListener.java +++ b/src/com/dre/brewery/listeners/InventoryListener.java @@ -309,7 +309,9 @@ public class InventoryListener implements Listener { try { DataInputStream in = new DataInputStream(new Base91DecoderStream(new LoreReader(potion))); - if (in.readByte() == 27 && in.skip(48) > 0) { + brew.testLoad(in); + + /*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(); @@ -323,7 +325,7 @@ public class InventoryListener implements Listener { } } else { P.p.log("false1"); - } + }*/ in.close(); } catch (IOException e) { @@ -331,9 +333,12 @@ public class InventoryListener implements Listener { try { - DataOutputStream out = new DataOutputStream(new Base91EncoderStream(new LoreWriter(potion, 0))); + DataOutputStream out = new DataOutputStream(new Base91EncoderStream(new LoreWriter(potion, 2))); - out.writeByte(27); + brew.testStore(out); + + + /*out.writeByte(27); out.writeLong(1111); //skip out.writeLong(1111); //skip out.writeLong(1111); //skip @@ -343,7 +348,7 @@ public class InventoryListener implements Listener { out.writeUTF("TESTHalloª∆Ω"); out.writeInt(34834); out.writeInt(6436); //skip - out.writeLong(Long.MAX_VALUE); + out.writeLong(Long.MAX_VALUE);*/ out.close(); item.setItemMeta(potion); From 3b7e019de39aa3537d71624175fb927a9a86387b Mon Sep 17 00:00:00 2001 From: Sn0wStorm Date: Mon, 30 May 2016 23:13:31 +0200 Subject: [PATCH 05/51] Use " instead of \ for encoding --- src/com/dre/brewery/listeners/InventoryListener.java | 8 ++++++++ src/com/dre/brewery/lore/basE91.java | 2 +- 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/src/com/dre/brewery/listeners/InventoryListener.java b/src/com/dre/brewery/listeners/InventoryListener.java index 094d75f..0fac855 100644 --- a/src/com/dre/brewery/listeners/InventoryListener.java +++ b/src/com/dre/brewery/listeners/InventoryListener.java @@ -44,6 +44,7 @@ import java.io.IOException; import java.util.HashMap; import java.util.HashSet; import java.util.Iterator; +import java.util.List; import java.util.UUID; /** @@ -351,6 +352,13 @@ public class InventoryListener implements Listener { out.writeLong(Long.MAX_VALUE);*/ out.close(); + /*StringBuilder b = new StringBuilder(); + for (char c : "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789!$%&()*+,-./:;<=>?@[]^_`{|}~\"".toCharArray()) { + b.append('§').append(c); + } + List lore = potion.getLore(); + lore.add(b.toString()); + potion.setLore(lore);*/ item.setItemMeta(potion); } catch (IOException h) { diff --git a/src/com/dre/brewery/lore/basE91.java b/src/com/dre/brewery/lore/basE91.java index 12a0b94..ae05ea0 100644 --- a/src/com/dre/brewery/lore/basE91.java +++ b/src/com/dre/brewery/lore/basE91.java @@ -137,7 +137,7 @@ public class basE91 public basE91() { int i; - String ts = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789!$%&()*+,-./:;<=>?@[\\]^_`{|}~"; + String ts = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789!$%&()*+,-./:;<=>?@[]^_`{|}~\""; // Added '-' removed '#' enctab = ts.getBytes(); dectab = new byte[256]; From ca2c49ea084ffb93c28e4a9775f5d1b448300ef9 Mon Sep 17 00:00:00 2001 From: Sn0wStorm Date: Mon, 13 Jun 2016 22:54:20 +0200 Subject: [PATCH 06/51] Made En/Decode table static Create a new En/Decoder Instance for each Stream --- .../dre/brewery/lore/Base91DecoderStream.java | 19 +++++++++---------- .../dre/brewery/lore/Base91EncoderStream.java | 13 ++++++------- src/com/dre/brewery/lore/LoreWriter.java | 2 +- src/com/dre/brewery/lore/basE91.java | 12 ++++++++---- 4 files changed, 24 insertions(+), 22 deletions(-) diff --git a/src/com/dre/brewery/lore/Base91DecoderStream.java b/src/com/dre/brewery/lore/Base91DecoderStream.java index 9258705..d784ac2 100644 --- a/src/com/dre/brewery/lore/Base91DecoderStream.java +++ b/src/com/dre/brewery/lore/Base91DecoderStream.java @@ -6,10 +6,9 @@ import java.io.InputStream; public class Base91DecoderStream extends FilterInputStream { - private static final basE91 DECODER = new basE91(); - + private final basE91 decoder = new basE91(); private byte[] decbuf = new byte[18]; - private byte[] buf = new byte[16]; + private byte[] buf = new byte[18]; private int reader = 0; private int count = 0; private byte[] markBuf = null; @@ -22,13 +21,13 @@ public class Base91DecoderStream extends FilterInputStream { reader = 0; count = in.read(decbuf); if (count < 1) { - count = DECODER.decEnd(buf); + count = decoder.decEnd(buf); if (count < 1) { count = -1; } return; } - count = DECODER.decode(decbuf, count, buf); + count = decoder.decode(decbuf, count, buf); } @Override @@ -100,14 +99,14 @@ public class Base91DecoderStream extends FilterInputStream { @Override public int available() throws IOException { - return Math.round(in.available() * 0.813F); // Ratio encoded to decoded with random data + return (int) (in.available() * 0.813F); // Ratio encoded to decoded with random data } @Override public void close() throws IOException { in.close(); count = -1; - DECODER.decReset(); + decoder.decReset(); buf = null; decbuf = null; } @@ -117,7 +116,7 @@ public class Base91DecoderStream extends FilterInputStream { if (!markSupported()) return; if (count == -1) return; in.mark(readlimit); - DECODER.decMark(); + decoder.decMark(); if (count > 0 && reader < count) { markBuf = new byte[count - reader]; System.arraycopy(buf, reader, markBuf, 0, markBuf.length); @@ -128,9 +127,9 @@ public class Base91DecoderStream extends FilterInputStream { @Override public synchronized void reset() throws IOException { - if (!markSupported()) throw new IOException("mark and reset not supported"); + if (!markSupported()) throw new IOException("mark and reset not supported by underlying Stream"); in.reset(); - DECODER.decUnmark(); + decoder.decUnmark(); reader = 0; count = 0; if (markBuf != null) { diff --git a/src/com/dre/brewery/lore/Base91EncoderStream.java b/src/com/dre/brewery/lore/Base91EncoderStream.java index c1b60f3..224bc29 100644 --- a/src/com/dre/brewery/lore/Base91EncoderStream.java +++ b/src/com/dre/brewery/lore/Base91EncoderStream.java @@ -7,8 +7,7 @@ import java.io.OutputStream; public class Base91EncoderStream extends FilterOutputStream { - private static final basE91 ENCODER = new basE91(); - + private final basE91 encoder = new basE91(); private byte[] buf = new byte[16]; private byte[] encBuf = new byte[24]; private int writer = 0; @@ -19,7 +18,7 @@ public class Base91EncoderStream extends FilterOutputStream { } private void encFlush() throws IOException { - encoded = ENCODER.encode(buf, writer, encBuf); + encoded = encoder.encode(buf, writer, encBuf); out.write(encBuf, 0, encoded); writer = 0; } @@ -51,9 +50,9 @@ public class Base91EncoderStream extends FilterOutputStream { } if (off == 0 && buf.length >= len) { - // Buffer is too full, so flush and encode data directly + // Buffer is too full but it would fit, so flush and encode data directly encFlush(); - encoded = ENCODER.encode(b, len, encBuf); + encoded = encoder.encode(b, len, encBuf); out.write(encBuf, 0, encoded); return; } @@ -76,7 +75,7 @@ public class Base91EncoderStream extends FilterOutputStream { encFlush(); } - encoded = ENCODER.encEnd(encBuf); + encoded = encoder.encEnd(encBuf); if (encoded > 0) { out.write(encBuf, 0, encoded); } @@ -86,7 +85,7 @@ public class Base91EncoderStream extends FilterOutputStream { @Override public void close() throws IOException { super.close(); - ENCODER.encReset(); + encoder.encReset(); buf = null; encBuf = null; } diff --git a/src/com/dre/brewery/lore/LoreWriter.java b/src/com/dre/brewery/lore/LoreWriter.java index cdeab97..4d00247 100644 --- a/src/com/dre/brewery/lore/LoreWriter.java +++ b/src/com/dre/brewery/lore/LoreWriter.java @@ -25,7 +25,7 @@ public class LoreWriter extends ByteArrayOutputStream { public void flush() throws IOException { super.flush(); if (size() <= 0) return; - if (flushed) { + if (flushed || meta == null) { // Dont write twice return; } diff --git a/src/com/dre/brewery/lore/basE91.java b/src/com/dre/brewery/lore/basE91.java index ae05ea0..c564c71 100644 --- a/src/com/dre/brewery/lore/basE91.java +++ b/src/com/dre/brewery/lore/basE91.java @@ -33,10 +33,11 @@ package com.dre.brewery.lore; public class basE91 { + public static final byte[] enctab; + private static final byte[] dectab; + private int ebq, en, dbq, dn, dv; private int[] marker = null; - public final byte[] enctab; - private final byte[] dectab; public int encode(byte[] ib, int n, byte[] ob) { @@ -136,6 +137,11 @@ public class basE91 public basE91() { + encReset(); + decReset(); + } + + static { int i; String ts = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789!$%&()*+,-./:;<=>?@[]^_`{|}~\""; // Added '-' removed '#' @@ -145,7 +151,5 @@ public class basE91 dectab[i] = -1; for (i = 0; i < 91; ++i) dectab[enctab[i]] = (byte) i; - encReset(); - decReset(); } } From cdd50f8504f3a5c41a86001ed49214a632564c69 Mon Sep 17 00:00:00 2001 From: Sn0wStorm Date: Mon, 13 Jun 2016 23:26:10 +0200 Subject: [PATCH 07/51] Optimized LoreStreams --- src/com/dre/brewery/Brew.java | 11 ++-- src/com/dre/brewery/P.java | 8 +-- .../brewery/listeners/InventoryListener.java | 14 +++--- src/com/dre/brewery/lore/LoreLoadStream.java | 50 +++++++++++++++++++ src/com/dre/brewery/lore/LoreReader.java | 36 ------------- .../{LoreWriter.java => LoreSaveStream.java} | 25 ++++++++-- 6 files changed, 90 insertions(+), 54 deletions(-) create mode 100644 src/com/dre/brewery/lore/LoreLoadStream.java delete mode 100644 src/com/dre/brewery/lore/LoreReader.java rename src/com/dre/brewery/lore/{LoreWriter.java => LoreSaveStream.java} (70%) diff --git a/src/com/dre/brewery/Brew.java b/src/com/dre/brewery/Brew.java index 58f371a..cf65539 100644 --- a/src/com/dre/brewery/Brew.java +++ b/src/com/dre/brewery/Brew.java @@ -653,8 +653,8 @@ public class Brew { } public void testStore(DataOutputStream out) throws IOException { - out.writeByte(1); // Version out.writeByte(86); // Parity + out.writeByte(1); // Version out.writeInt(quality); int bools = 0; bools += (distillRuns != 0 ? 1 : 0); @@ -681,14 +681,14 @@ public class Brew { } public void testLoad(DataInputStream in) throws IOException { - if (in.readByte() != 1) { - P.p.log("unknown version"); - return; - } if (in.readByte() != 86) { P.p.log("parity check failed"); return; } + if (in.readByte() != 1) { + P.p.log("unknown version"); + return; + } if (in.readInt() != quality) { P.p.log("quality wrong"); } @@ -723,6 +723,7 @@ public class Brew { P.p.log("stat wrong"); } ingredients.testLoad(in); + P.p.log("load successful"); } // Saves all data diff --git a/src/com/dre/brewery/P.java b/src/com/dre/brewery/P.java index 75e603b..efee06f 100644 --- a/src/com/dre/brewery/P.java +++ b/src/com/dre/brewery/P.java @@ -13,8 +13,8 @@ import com.dre.brewery.integration.WGBarrelOld; import com.dre.brewery.listeners.*; 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 com.dre.brewery.lore.LoreLoadStream; +import com.dre.brewery.lore.LoreSaveStream; import org.apache.commons.lang.math.NumberUtils; import org.bstats.bukkit.Metrics; import org.bukkit.Bukkit; @@ -93,7 +93,7 @@ public class P extends JavaPlugin { try { ItemMeta meta = new ItemStack(Material.POTION).getItemMeta(); - DataOutputStream data = new DataOutputStream(new Base91EncoderStream(new LoreWriter(meta, 3))); + DataOutputStream data = new DataOutputStream(new Base91EncoderStream(new LoreSaveStream(meta, 3))); data.writeInt(2); data.writeLong(5); @@ -111,7 +111,7 @@ public class P extends JavaPlugin { data.close(); meta.getLore(); - DataInputStream dataIn = new DataInputStream(new Base91DecoderStream(new LoreReader(meta))); + DataInputStream dataIn = new DataInputStream(new Base91DecoderStream(new LoreLoadStream(meta))); P.p.log(dataIn.readInt() + ", " + dataIn.readLong() + ", "); diff --git a/src/com/dre/brewery/listeners/InventoryListener.java b/src/com/dre/brewery/listeners/InventoryListener.java index 0fac855..c6c069f 100644 --- a/src/com/dre/brewery/listeners/InventoryListener.java +++ b/src/com/dre/brewery/listeners/InventoryListener.java @@ -9,8 +9,8 @@ import com.dre.brewery.P; import com.dre.brewery.integration.LogBlockBarrel; 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 com.dre.brewery.lore.LoreLoadStream; +import com.dre.brewery.lore.LoreSaveStream; import org.bukkit.Bukkit; import org.bukkit.Material; import org.bukkit.Sound; @@ -308,7 +308,7 @@ public class InventoryListener implements Listener { brew.touch(); try { - DataInputStream in = new DataInputStream(new Base91DecoderStream(new LoreReader(potion))); + DataInputStream in = new DataInputStream(new Base91DecoderStream(new LoreLoadStream(potion))); brew.testLoad(in); @@ -329,12 +329,12 @@ public class InventoryListener implements Listener { }*/ in.close(); - } catch (IOException e) { - e.printStackTrace(); + } catch (IllegalArgumentException argExc) { + P.p.log("No Data in Lore"); try { - DataOutputStream out = new DataOutputStream(new Base91EncoderStream(new LoreWriter(potion, 2))); + DataOutputStream out = new DataOutputStream(new Base91EncoderStream(new LoreSaveStream(potion, 2))); brew.testStore(out); @@ -365,6 +365,8 @@ public class InventoryListener implements Listener { h.printStackTrace(); } + } catch (IOException e) { + e.printStackTrace(); } } } diff --git a/src/com/dre/brewery/lore/LoreLoadStream.java b/src/com/dre/brewery/lore/LoreLoadStream.java new file mode 100644 index 0000000..3d73889 --- /dev/null +++ b/src/com/dre/brewery/lore/LoreLoadStream.java @@ -0,0 +1,50 @@ +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 LoreLoadStream extends ByteArrayInputStream { + + public LoreLoadStream(ItemMeta meta) throws IllegalArgumentException { + this(meta, -1); + } + + public LoreLoadStream(ItemMeta meta, int line) throws IllegalArgumentException { + super(loreToBytes(meta, line)); + } + + private static byte[] loreToBytes(ItemMeta meta, int lineNum) throws IllegalArgumentException { + if (meta.hasLore()) { + List lore = meta.getLore(); + if (lineNum >= 0) { + String line = lore.get(lineNum); + if (line.startsWith("§%")) { + return loreLineToBytes(line); + } + } + for (String line : lore) { + if (line.startsWith("§%")) { + return loreLineToBytes(line); + } + } + } + throw new IllegalArgumentException("Meta has no data in lore"); + } + + private static byte[] loreLineToBytes(String line) { + 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(); + } +} diff --git a/src/com/dre/brewery/lore/LoreReader.java b/src/com/dre/brewery/lore/LoreReader.java deleted file mode 100644 index b12f2ec..0000000 --- a/src/com/dre/brewery/lore/LoreReader.java +++ /dev/null @@ -1,36 +0,0 @@ -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/LoreSaveStream.java similarity index 70% rename from src/com/dre/brewery/lore/LoreWriter.java rename to src/com/dre/brewery/lore/LoreSaveStream.java index 4d00247..a895691 100644 --- a/src/com/dre/brewery/lore/LoreWriter.java +++ b/src/com/dre/brewery/lore/LoreSaveStream.java @@ -5,15 +5,20 @@ import org.bukkit.inventory.meta.ItemMeta; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.util.ArrayList; +import java.util.Iterator; import java.util.List; -public class LoreWriter extends ByteArrayOutputStream { +public class LoreSaveStream extends ByteArrayOutputStream { private ItemMeta meta; private int line; private boolean flushed = false; - public LoreWriter(ItemMeta meta, int line) { + public LoreSaveStream(ItemMeta meta) { + this(meta, -1); + } + + public LoreSaveStream(ItemMeta meta, int line) { super(128); this.meta = meta; this.line = line; @@ -43,10 +48,24 @@ public class LoreWriter extends ByteArrayOutputStream { } else { lore = new ArrayList<>(); } + int prev = 0; + for (Iterator iterator = lore.iterator(); iterator.hasNext(); ) { + if (iterator.next().startsWith("§%")) { + iterator.remove(); + break; + } + prev++; + } + if (line < 0) { + if (prev >= 0) { + line = prev; + } else { + line = lore.size(); + } + } while (lore.size() < line) { lore.add(""); } - //TODO when existing data string in lore lore.add(line, loreLineBuilder.toString()); meta.setLore(lore); } From 4b18dceadae52fd0d2abf7316e18e753a4641a27 Mon Sep 17 00:00:00 2001 From: Sn0wStorm Date: Thu, 16 Jun 2016 22:13:21 +0200 Subject: [PATCH 08/51] Implemented Lore Save system --- src/com/dre/brewery/BIngredients.java | 79 +++- src/com/dre/brewery/BRecipe.java | 23 +- src/com/dre/brewery/Brew.java | 358 +++++++++++++----- src/com/dre/brewery/P.java | 26 +- src/com/dre/brewery/filedata/DataSave.java | 2 +- .../brewery/listeners/CommandListener.java | 10 +- .../dre/brewery/listeners/EntityListener.java | 10 +- .../brewery/listeners/InventoryListener.java | 79 ++-- .../dre/brewery/listeners/PlayerListener.java | 4 +- 9 files changed, 393 insertions(+), 198 deletions(-) diff --git a/src/com/dre/brewery/BIngredients.java b/src/com/dre/brewery/BIngredients.java index d68d6f0..592d2af 100644 --- a/src/com/dre/brewery/BIngredients.java +++ b/src/com/dre/brewery/BIngredients.java @@ -4,7 +4,6 @@ import org.bukkit.Material; import org.bukkit.configuration.ConfigurationSection; import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.meta.PotionMeta; -import org.bukkit.potion.PotionEffectType; import java.io.DataInputStream; import java.io.DataOutputStream; @@ -17,30 +16,39 @@ public class BIngredients { public static Map cookedNames = new HashMap<>(); private static int lastId = 0; - private int id; - private ArrayList ingredients = new ArrayList<>(); + private int id; // Legacy + private List ingredients = new ArrayList<>(); private Map materials = new HashMap<>(); // Merged List Of ingredients that doesnt consider Durability private int cookedTime; // Represents ingredients in Cauldron, Brew // Init a new BIngredients public BIngredients() { - this.id = lastId; - lastId++; + //this.id = lastId; + //lastId++; } // Load from File - public BIngredients(ArrayList ingredients, int cookedTime) { + public BIngredients(List ingredients, int cookedTime) { this.ingredients = ingredients; this.cookedTime = cookedTime; - this.id = lastId; - lastId++; + //this.id = lastId; + //lastId++; for (ItemStack item : ingredients) { addMaterial(item); } } + // Load from legacy Brew section + public BIngredients(List ingredients, int cookedTime, boolean legacy) { + this(ingredients, cookedTime); + if (legacy) { + this.id = lastId; + lastId++; + } + } + // Add an ingredient to this public void add(ItemStack ingredient) { addMaterial(ingredient); @@ -72,14 +80,15 @@ public class BIngredients { cookedTime = state; String cookedName = null; BRecipe cookRecipe = getCookRecipe(); + Brew brew; - int uid = Brew.generateUID(); + //int uid = Brew.generateUID(); if (cookRecipe != null) { // Potion is best with cooking only int quality = (int) Math.round((getIngredientQuality(cookRecipe) + getCookingQuality(cookRecipe, false)) / 2.0); P.p.debugLog("cooked potion has Quality: " + quality); - Brew brew = new Brew(uid, quality, cookRecipe, this); + brew = new Brew(quality, cookRecipe, this); Brew.addOrReplaceEffects(potionMeta, brew.getEffects(), brew.getQuality()); cookedName = cookRecipe.getName(quality); @@ -87,7 +96,7 @@ public class BIngredients { } else { // new base potion - new Brew(uid, this); + brew = new Brew(this); if (state <= 1) { cookedName = P.p.languageReader.get("Brew_ThickBrew"); @@ -117,14 +126,17 @@ public class BIngredients { uid *= 4; } // This effect stores the UID in its Duration - potionMeta.addCustomEffect((PotionEffectType.REGENERATION).createEffect(uid, 0), true); + //potionMeta.addCustomEffect((PotionEffectType.REGENERATION).createEffect((uid * 4), 0), true); + + brew.touch(); + brew.save(potionMeta); potion.setItemMeta(potionMeta); return potion; } // returns amount of ingredients - private int getIngredientsCount() { + public int getIngredientsCount() { int count = 0; for (ItemStack item : ingredients) { count += item.getAmount(); @@ -290,7 +302,7 @@ public class BIngredients { } // returns pseudo quality of distilling. 0 if doesnt match the need of the recipes distilling - public int getDistillQuality(BRecipe recipe, int distillRuns) { + public int getDistillQuality(BRecipe recipe, byte distillRuns) { if (recipe.needsDistilling() != distillRuns > 0) { return 0; } @@ -316,7 +328,12 @@ public class BIngredients { } // Creates a copy ingredients + @Override public BIngredients clone() { + try { + super.clone(); + } catch (CloneNotSupportedException ingored) { + } BIngredients copy = new BIngredients(); copy.ingredients.addAll(ingredients); copy.materials.putAll(materials); @@ -324,7 +341,14 @@ public class BIngredients { return copy; } - public void testStore(DataOutputStream out) throws IOException { + @Override + public String toString() { + return "BIngredients{" + + "cookedTime=" + cookedTime + + ", total ingedients: " + getIngredientsCount() + '}'; + } + + /*public void testStore(DataOutputStream out) throws IOException { out.writeInt(cookedTime); out.writeByte(ingredients.size()); for (ItemStack item : ingredients) { @@ -353,9 +377,34 @@ public class BIngredients { P.p.log("amount wrong"); } } + }*/ + + public void save(DataOutputStream out) throws IOException { + out.writeInt(cookedTime); + out.writeByte(ingredients.size()); + for (ItemStack item : ingredients) { + out.writeUTF(item.getType().name()); + out.writeShort(item.getAmount()); + out.writeShort(item.getDurability()); + } + } + + public static BIngredients load(DataInputStream in) throws IOException { + int cookedTime = in.readInt(); + byte size = in.readByte(); + List ing = new ArrayList<>(size); + for (; size > 0; size--) { + Material mat = Material.getMaterial(in.readUTF()); + if (mat != null) { + ing.add(new ItemStack(mat, in.readShort(), in.readShort())); + } + } + return new BIngredients(ing, cookedTime); } // saves data into main Ingredient section. Returns the save id + // Only needed for legacy potions + @Deprecated public int save(ConfigurationSection config) { String path = "Ingredients." + id; if (cookedTime != 0) { diff --git a/src/com/dre/brewery/BRecipe.java b/src/com/dre/brewery/BRecipe.java index f0d997b..25417f4 100644 --- a/src/com/dre/brewery/BRecipe.java +++ b/src/com/dre/brewery/BRecipe.java @@ -4,7 +4,6 @@ import org.bukkit.Material; import org.bukkit.configuration.ConfigurationSection; import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.meta.PotionMeta; -import org.bukkit.potion.PotionEffectType; import java.util.ArrayList; import java.util.List; @@ -14,7 +13,7 @@ public class BRecipe { private String[] name; private ArrayList ingredients = new ArrayList<>(); // material and amount private int cookingTime; // time to cook in cauldron - private int distillruns; // runs through the brewer + private byte distillruns; // runs through the brewer private int distillTime; // time for one distill run in seconds private byte wood; // type of wood the barrel has to consist of private int age; // time in minecraft days for the potions to age in barrels @@ -90,7 +89,12 @@ public class BRecipe { } } this.cookingTime = configSectionRecipes.getInt(recipeId + ".cookingtime", 1); - this.distillruns = configSectionRecipes.getInt(recipeId + ".distillruns", 0); + int dis = configSectionRecipes.getInt(recipeId + ".distillruns", 0); + if (dis > Byte.MAX_VALUE) { + this.distillruns = Byte.MAX_VALUE; + } else { + this.distillruns = (byte) dis; + } this.distillTime = configSectionRecipes.getInt(recipeId + ".distilltime", 0) * 20; this.wood = (byte) configSectionRecipes.getInt(recipeId + ".wood", 0); this.age = configSectionRecipes.getInt(recipeId + ".age", 0); @@ -247,8 +251,6 @@ public class BRecipe { ItemStack potion = new ItemStack(Material.POTION); PotionMeta potionMeta = (PotionMeta) potion.getItemMeta(); - int uid = Brew.generateUID(); - ArrayList list = new ArrayList<>(ingredients.size()); for (ItemStack item : ingredients) { if (item.getDurability() == -1) { @@ -260,7 +262,7 @@ public class BRecipe { BIngredients bIngredients = new BIngredients(list, cookingTime); - Brew brew = new Brew(uid, bIngredients, quality, distillruns, getAge(), wood, getName(5), false, false, true, 0); + Brew brew = new Brew(bIngredients, quality, distillruns, getAge(), wood, getName(5), false, false, true); Brew.PotionColor.fromString(getColor()).colorBrew(potionMeta, potion, false); potionMeta.setDisplayName(P.p.color("&f" + getName(quality))); @@ -270,11 +272,12 @@ public class BRecipe { uid *= 4; } // This effect stores the UID in its Duration - potionMeta.addCustomEffect((PotionEffectType.REGENERATION).createEffect(uid, 0), true); + //potionMeta.addCustomEffect((PotionEffectType.REGENERATION).createEffect((uid * 4), 0), true); brew.convertLore(potionMeta, false); Brew.addOrReplaceEffects(potionMeta, effects, quality); brew.touch(); + brew.save(potionMeta); potion.setItemMeta(potionMeta); return potion; @@ -322,7 +325,7 @@ public class BRecipe { return cookingTime; } - public int getDistillRuns() { + public byte getDistillRuns() { return distillruns; } @@ -358,4 +361,8 @@ public class BRecipe { return effects; } + @Override + public String toString() { + return "BRecipe{" + getName(5) + '}'; + } } diff --git a/src/com/dre/brewery/Brew.java b/src/com/dre/brewery/Brew.java index cf65539..f492046 100644 --- a/src/com/dre/brewery/Brew.java +++ b/src/com/dre/brewery/Brew.java @@ -1,11 +1,16 @@ package com.dre.brewery; import org.bukkit.Color; +import com.dre.brewery.lore.Base91DecoderStream; +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.configuration.ConfigurationSection; import org.bukkit.inventory.BrewerInventory; import org.bukkit.inventory.ItemFlag; import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.meta.ItemMeta; import org.bukkit.inventory.meta.PotionMeta; import org.bukkit.potion.PotionData; import org.bukkit.potion.PotionEffect; @@ -24,40 +29,35 @@ public class Brew { // represents the liquid in the brewed Potions - public static Map potions = new HashMap<>(); + public static Map legacyPotions = new HashMap<>(); 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 colorInBrewer; // color the Lore while in Brewer private BIngredients ingredients; private int quality; - private int distillRuns; + private byte distillRuns; private float ageTime; private float wood; private BRecipe currentRecipe; private boolean unlabeled; private boolean persistent; private boolean stat; // static potions should not be changed - private int lastUpdate; // last update in hours after install time + //private int lastUpdate; // last update in hours after install time - public Brew(int uid, BIngredients ingredients) { + public Brew(BIngredients ingredients) { this.ingredients = ingredients; - touch(); - potions.put(uid, this); } // quality already set - public Brew(int uid, int quality, BRecipe recipe, BIngredients ingredients) { + public Brew(int quality, BRecipe recipe, BIngredients ingredients) { this.ingredients = ingredients; this.quality = quality; this.currentRecipe = recipe; - touch(); - potions.put(uid, this); } - // loading from file - public Brew(int uid, BIngredients ingredients, int quality, int distillRuns, float ageTime, float wood, String recipe, boolean unlabeled, boolean persistent, boolean stat, int lastUpdate) { - potions.put(uid, this); + // loading with all values set + public Brew(BIngredients ingredients, int quality, byte distillRuns, float ageTime, float wood, String recipe, boolean unlabeled, boolean persistent, boolean stat) { this.ingredients = ingredients; this.quality = quality; this.distillRuns = distillRuns; @@ -66,44 +66,95 @@ public class Brew { this.unlabeled = unlabeled; this.persistent = persistent; this.stat = stat; - this.lastUpdate = lastUpdate; setRecipeFromString(recipe); } - // returns a Brew by its UID - public static Brew get(int uid) { - if (uid < -1) { - if (!potions.containsKey(uid)) { - P.p.errorLog("Database failure! unable to find UID " + uid + " of a custom Potion!"); - return null;// throw some exception? - } - } else { - return null; - } - return potions.get(uid); + // Loading from InputStream + private Brew() { } - // returns a Brew by PotionMeta - public static Brew get(PotionMeta meta) { - return get(getUID(meta)); + // returns a Brew by ItemMeta + public static Brew get(ItemMeta meta) { + if (meta.hasLore()) { + if (meta instanceof PotionMeta && ((PotionMeta) meta).hasCustomEffect(PotionEffectType.REGENERATION)) { + Brew brew = load(meta); + if (brew != null) { + brew = getFromPotionEffect(((PotionMeta) meta), false); + } + return brew; + } else { + return load(meta); + } + } + return null; } // returns a Brew by ItemStack public static Brew get(ItemStack item) { if (item.getType() == Material.POTION) { if (item.hasItemMeta()) { - return get((PotionMeta) item.getItemMeta()); + ItemMeta meta = item.getItemMeta(); + if (meta.hasLore()) { + if (meta instanceof PotionMeta && ((PotionMeta) meta).hasCustomEffect(PotionEffectType.REGENERATION)) { + Brew brew = load(meta); + if (brew != null) { + ((PotionMeta) meta).removeCustomEffect(PotionEffectType.REGENERATION); + } else { + brew = getFromPotionEffect(((PotionMeta) meta), true); + if (brew == null) return null; + brew.save(meta); + } + item.setItemMeta(meta); + return brew; + } else { + return load(meta); + } + } } } return null; } + private static Brew getFromPotionEffect(PotionMeta potionMeta, boolean remove) { + for (PotionEffect effect : potionMeta.getCustomEffects()) { + if (effect.getType().equals(PotionEffectType.REGENERATION)) { + if (effect.getDuration() < -1) { + if (remove) { + return legacyPotions.remove(effect.getDuration()); + } else { + return legacyPotions.get(effect.getDuration()); + } + } + } + } + return null; + } + + // returns a Brew by its UID + // Does not work anymore with new save system + @Deprecated + public static Brew get(int uid) { + if (uid < -1) { + if (!legacyPotions.containsKey(uid)) { + P.p.errorLog("Database failure! unable to find UID " + uid + " of a custom Potion!"); + return null;// throw some exception? + } + } else { + return null; + } + return legacyPotions.get(uid); + } + // returns UID of custom Potion item + // Does not work anymore with new save system + @Deprecated public static int getUID(ItemStack item) { return getUID((PotionMeta) item.getItemMeta()); } // returns UID of custom Potion meta + // Does not work anymore with new save system + @Deprecated public static int getUID(PotionMeta potionMeta) { if (potionMeta.hasCustomEffect(PotionEffectType.REGENERATION)) { for (PotionEffect effect : potionMeta.getCustomEffects()) { @@ -118,13 +169,13 @@ public class Brew { } // generate an UID - public static int generateUID() { + /*public static int generateUID() { int uid = -2; while (potions.containsKey(uid)) { uid -= 1; } return uid; - } + }*/ //returns the recipe with the given name, recalculates if not found public boolean setRecipeFromString(String name) { @@ -158,7 +209,8 @@ public class Brew { } // Copy a Brew with a new unique ID and return its item - public ItemStack copy(ItemStack item) { + // Not needed anymore + /*public ItemStack copy(ItemStack item) { ItemStack copy = item.clone(); int uid = generateUID(); clone(uid); @@ -170,11 +222,13 @@ public class Brew { meta.addCustomEffect((PotionEffectType.REGENERATION).createEffect(uid, 0), true); copy.setItemMeta(meta); return copy; - } + }*/ - // Clones this instance with a new unique ID - public Brew clone(int uid) { - Brew brew = new Brew(uid, quality, currentRecipe, ingredients); + // Clones this instance + @Override + public Brew clone() throws CloneNotSupportedException { + super.clone(); + Brew brew = new Brew(quality, currentRecipe, ingredients); brew.distillRuns = distillRuns; brew.ageTime = ageTime; brew.unlabeled = unlabeled; @@ -184,12 +238,28 @@ public class Brew { return brew; } + @Override + public String toString() { + return "Brew{" + + ingredients + " ingredients" + + ", quality=" + quality + + ", distillRuns=" + distillRuns + + ", ageTime=" + ageTime + + ", wood=" + wood + + ", currentRecipe=" + currentRecipe + + ", unlabeled=" + unlabeled + + ", persistent=" + persistent + + ", stat=" + stat + + '}'; + } + // remove potion from file (drinking, despawning, combusting, cmdDeleting, should be more!) - public void remove(ItemStack item) { + // Not needed anymore + /*public void remove(ItemStack item) { if (!persistent) { potions.remove(getUID(item)); } - } + }*/ // calculate alcohol from recipe public int calcAlcohol() { @@ -283,11 +353,12 @@ public class Brew { } // Do some regular updates + // Currently does nothing, but may be used to update something on this brew public void touch() { - lastUpdate = (int) ((double) (System.currentTimeMillis() - installTime) / 3600000D); + //lastUpdate = (int) ((double) (System.currentTimeMillis() - installTime) / 3600000D); } - public int getDistillRuns() { + public byte getDistillRuns() { return distillRuns; } @@ -299,16 +370,23 @@ public class Brew { return currentRecipe; } + // Not needed anymore + // TODO remove + @Deprecated public boolean isPersistent() { return persistent; } // Make a potion persistent to not delete it when drinking it + // Not needed anymore + @Deprecated public void makePersistent() { persistent = true; } // Remove the Persistence Flag from a brew, so it will be normally deleted when drinking it + // Not needed anymore + @Deprecated public void removePersistence() { persistent = false; } @@ -329,9 +407,9 @@ public class Brew { } } - public int getLastUpdate() { + /*public int getLastUpdate() { return lastUpdate; - } + }*/ // Distilling section --------------- @@ -382,6 +460,7 @@ public class Brew { } updateDistillLore(prefix, potionMeta); touch(); + save(potionMeta); slotItem.setItemMeta(potionMeta); } @@ -454,6 +533,7 @@ public class Brew { } } touch(); + save(potionMeta); item.setItemMeta(potionMeta); } @@ -607,14 +687,14 @@ public class Brew { } } - // Removes all effects except regeneration which stores data + // Removes all effects public static void removeEffects(PotionMeta meta) { if (meta.hasCustomEffects()) { for (PotionEffect effect : meta.getCustomEffects()) { PotionEffectType type = effect.getType(); - if (!type.equals(PotionEffectType.REGENERATION)) { + //if (!type.equals(PotionEffectType.REGENERATION)) { meta.removeCustomEffect(type); - } + //} } } } @@ -652,83 +732,153 @@ public class Brew { return P.p.color(color); } - public void testStore(DataOutputStream out) throws IOException { - out.writeByte(86); // Parity - out.writeByte(1); // Version - out.writeInt(quality); - int bools = 0; - bools += (distillRuns != 0 ? 1 : 0); - bools += (ageTime > 0 ? 2 : 0); - bools += (wood != -1 ? 4 : 0); - bools += (currentRecipe != null ? 8 : 0); - bools += (unlabeled ? 16 : 0); - bools += (persistent ? 32 : 0); - bools += (stat ? 64 : 0); - out.writeByte(bools); - if (distillRuns != 0) { - out.writeByte(distillRuns); + private static Brew load(ItemMeta meta) { + LoreLoadStream loreStream; + try { + loreStream = new LoreLoadStream(meta, 0); + } catch (IllegalArgumentException ignored) { + return null; } - if (ageTime > 0) { - out.writeFloat(ageTime); + DataInputStream in = new DataInputStream(new Base91DecoderStream(loreStream)); + try { + if (in.readByte() != 86) { + P.p.errorLog("parity check failed on Brew while loading, trying to load anyways!"); + } + Brew brew = new Brew(); + byte ver = in.readByte(); + switch (ver) { + case 1: + brew.loadFromStream(in); + break; + default: + P.p.errorLog("Brew has data stored in v" + ver + " this version supports up to v1"); + return null; + } + return brew; + } catch (IOException e) { + P.p.errorLog("IO Error while loading Brew"); + e.printStackTrace(); + } finally { + try { + in.close(); + } catch (IOException e) { + e.printStackTrace(); + } } - if (wood != -1) { - out.writeFloat(wood); - } - if (currentRecipe != null) { - out.writeUTF(currentRecipe.getName(5)); - } - ingredients.testStore(out); + return null; } - public void testLoad(DataInputStream in) throws IOException { - if (in.readByte() != 86) { - P.p.log("parity check failed"); - return; - } - if (in.readByte() != 1) { - P.p.log("unknown version"); - return; - } - if (in.readInt() != quality) { - P.p.log("quality wrong"); - } + // TODO load and save Ingredients + + private void loadFromStream(DataInputStream in) throws IOException { + quality = in.readByte(); int bools = in.readUnsignedByte(); if ((bools & 1) != 0) { - if (in.readByte() != distillRuns) { - P.p.log("distillruns wrong"); - } + distillRuns = in.readByte(); } if ((bools & 2) != 0) { - if (in.readFloat() != ageTime) { - P.p.log("agetime wrong"); - } + ageTime = in.readFloat(); } if ((bools & 4) != 0) { - if (in.readFloat() != wood) { - P.p.log("wood wrong"); - } + wood = in.readFloat(); } if ((bools & 8) != 0) { - if (!in.readUTF().equals(currentRecipe.getName(5))) { - P.p.log("currecipe wrong"); + setRecipeFromString(in.readUTF()); + } else { + setRecipeFromString(null); + } + unlabeled = (bools & 16) != 0; + persistent = (bools & 32) != 0; + stat = (bools & 64) != 0; + } + + // Save brew data into meta/lore + public void save(ItemMeta meta) { + LoreSaveStream loreStream = new LoreSaveStream(meta, 0); + saveToStream(new DataOutputStream(new Base91EncoderStream(loreStream))); + } + + // Save brew data into the meta/lore of the specified item + // The meta on the item changes, so to make further changes to the meta, item.getItemMeta() has to be called again after this + public void save(ItemStack item) { + ItemMeta meta; + if (!item.hasItemMeta()) { + meta = P.p.getServer().getItemFactory().getItemMeta(item.getType()); + } else { + meta = item.getItemMeta(); + } + save(meta); + item.setItemMeta(meta); + } + + public void saveToStream(DataOutputStream out) { + try { + out.writeByte(86); // Parity/sanity + out.writeByte(1); // Version + if (quality > 10) { + quality = 10; + } + out.writeByte((byte) quality); + int bools = 0; + bools |= ((distillRuns != 0) ? 1 : 0); + bools |= (ageTime > 0 ? 2 : 0); + bools |= (wood != -1 ? 4 : 0); + bools |= (currentRecipe != null ? 8 : 0); + bools |= (unlabeled ? 16 : 0); + bools |= (persistent ? 32 : 0); // TODO remove persistence + bools |= (stat ? 64 : 0); + out.writeByte(bools); + if (distillRuns != 0) { + out.writeByte(distillRuns); + } + if (ageTime > 0) { + out.writeFloat(ageTime); + } + if (wood != -1) { + out.writeFloat(wood); + } + if (currentRecipe != null) { + out.writeUTF(currentRecipe.getName(5)); + } + } catch (IOException e) { + P.p.errorLog("IO Error while saving Brew"); + e.printStackTrace(); + } finally { + try { + out.close(); + } catch (IOException e) { + e.printStackTrace(); } } - if ((bools & 16) != 0 && !unlabeled) { - P.p.log("unlabeled wrong"); + } + + // 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) { + Brew brew = new Brew(ingredients, quality, distillRuns, ageTime, wood, recipe, unlabeled, persistent, stat); + legacyPotions.put(uid, brew); + } + + // remove legacy potiondata from item + public static void removeLegacy(ItemStack item) { + if (legacyPotions.isEmpty()) return; + if (!item.hasItemMeta()) return; + ItemMeta meta = item.getItemMeta(); + if (!(meta instanceof PotionMeta)) return; + for (PotionEffect effect : ((PotionMeta) meta).getCustomEffects()) { + if (effect.getType().equals(PotionEffectType.REGENERATION)) { + if (effect.getDuration() < -1) { + legacyPotions.remove(effect.getDuration()); + return; + } + } } - if ((bools & 32) != 0 && !persistent) { - P.p.log("persistent wrong"); - } - if ((bools & 64) != 0 && !stat) { - P.p.log("stat wrong"); - } - ingredients.testLoad(in); - P.p.log("load successful"); } // Saves all data + // Legacy method to save to data file + @Deprecated public static void save(ConfigurationSection config) { - for (Map.Entry entry : potions.entrySet()) { + for (Map.Entry entry : legacyPotions.entrySet()) { int uid = entry.getKey(); Brew brew = entry.getValue(); ConfigurationSection idConfig = config.createSection("" + uid); @@ -757,9 +907,9 @@ public class Brew { if (brew.stat) { idConfig.set("stat", true); } - if (brew.lastUpdate > 0) { + /*if (brew.lastUpdate > 0) { idConfig.set("lastUpdate", brew.lastUpdate); - } + }*/ // save the ingredients idConfig.set("ingId", brew.ingredients.save(config.getParent())); } diff --git a/src/com/dre/brewery/P.java b/src/com/dre/brewery/P.java index efee06f..e37b855 100644 --- a/src/com/dre/brewery/P.java +++ b/src/com/dre/brewery/P.java @@ -11,10 +11,6 @@ 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.Base91DecoderStream; -import com.dre.brewery.lore.Base91EncoderStream; -import com.dre.brewery.lore.LoreLoadStream; -import com.dre.brewery.lore.LoreSaveStream; import org.apache.commons.lang.math.NumberUtils; import org.bstats.bukkit.Metrics; import org.bukkit.Bukkit; @@ -91,7 +87,7 @@ 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"); - try { + /*try { ItemMeta meta = new ItemStack(Material.POTION).getItemMeta(); DataOutputStream data = new DataOutputStream(new Base91EncoderStream(new LoreSaveStream(meta, 3))); @@ -125,7 +121,7 @@ public class P extends JavaPlugin { - /*basE91 basE91 = new basE91(); + basE91 basE91 = new basE91(); int[] input = new int[] {12, 65, 324, 5, 12, 129459, 1234567, Integer.MIN_VALUE, Integer.MAX_VALUE}; ByteArrayOutputStream stream = new ByteArrayOutputStream(); DataOutputStream data = new DataOutputStream(stream); @@ -198,11 +194,11 @@ public class P extends JavaPlugin { } tdata.close(); - test = test;*/ + test = test; } catch (IOException e) { e.printStackTrace(); - } + }*/ // load the Config @@ -338,7 +334,7 @@ public class P extends JavaPlugin { BIngredients.recipes.clear(); BIngredients.cookedNames.clear(); BPlayer.clear(); - Brew.potions.clear(); + Brew.legacyPotions.clear(); Wakeup.wakeups.clear(); Words.words.clear(); Words.ignoreText.clear(); @@ -387,7 +383,7 @@ public class P extends JavaPlugin { // Reload Recipes boolean successful = true; - for (Brew brew : Brew.potions.values()) { + for (Brew brew : Brew.legacyPotions.values()) { if (!brew.reloadRecipe()) { successful = false; } @@ -603,30 +599,30 @@ public class P extends JavaPlugin { if (matSection != null) { // matSection has all the materials + amount as Integers ArrayList ingredients = deserializeIngredients(matSection); - ingMap.put(id, new BIngredients(ingredients, section.getInt(id + ".cookedTime", 0))); + ingMap.put(id, new BIngredients(ingredients, section.getInt(id + ".cookedTime", 0), true)); } else { errorLog("Ingredient id: '" + id + "' incomplete in data.yml"); } } } - // loading Brew + // loading Brew legacy section = data.getConfigurationSection("Brew"); if (section != null) { // All sections have the UID as name for (String uid : section.getKeys(false)) { BIngredients ingredients = getIngredients(ingMap, section.getString(uid + ".ingId")); int quality = section.getInt(uid + ".quality", 0); - int distillRuns = section.getInt(uid + ".distillRuns", 0); + byte distillRuns = (byte) section.getInt(uid + ".distillRuns", 0); float ageTime = (float) section.getDouble(uid + ".ageTime", 0.0); float wood = (float) section.getDouble(uid + ".wood", -1.0); String recipe = section.getString(uid + ".recipe", null); boolean unlabeled = section.getBoolean(uid + ".unlabeled", false); boolean persistent = section.getBoolean(uid + ".persist", false); boolean stat = section.getBoolean(uid + ".stat", false); - int lastUpdate = section.getInt("lastUpdate", 0); + //int lastUpdate = section.getInt("lastUpdate", 0); - new Brew(parseInt(uid), ingredients, quality, distillRuns, ageTime, wood, recipe, unlabeled, persistent, stat, lastUpdate); + Brew.loadLegacy(ingredients, parseInt(uid), quality, distillRuns, ageTime, wood, recipe, unlabeled, persistent, stat); } } diff --git a/src/com/dre/brewery/filedata/DataSave.java b/src/com/dre/brewery/filedata/DataSave.java index ffd9043..6f1a3a0 100644 --- a/src/com/dre/brewery/filedata/DataSave.java +++ b/src/com/dre/brewery/filedata/DataSave.java @@ -64,7 +64,7 @@ public class DataSave extends BukkitRunnable { configFile.set("installTime", Brew.installTime); configFile.set("MCBarrelTime", MCBarrel.mcBarrelTime); - if (!Brew.potions.isEmpty()) { + if (!Brew.legacyPotions.isEmpty()) { Brew.save(configFile.createSection("Brew")); } diff --git a/src/com/dre/brewery/listeners/CommandListener.java b/src/com/dre/brewery/listeners/CommandListener.java index 60a6ece..bae7517 100644 --- a/src/com/dre/brewery/listeners/CommandListener.java +++ b/src/com/dre/brewery/listeners/CommandListener.java @@ -380,6 +380,7 @@ public class CommandListener implements CommandExecutor { } } + @Deprecated @SuppressWarnings("deprecation") public void cmdCopy(CommandSender sender, int count) { @@ -395,7 +396,7 @@ public class CommandListener implements CommandExecutor { Brew brew = Brew.get(hand); if (brew != null) { while (count > 0) { - ItemStack item = brew.copy(hand); + ItemStack item = hand.clone(); if (!(player.getInventory().addItem(item)).isEmpty()) { p.msg(sender, p.languageReader.get("CMD_Copy_Error", "" + count)); return; @@ -417,6 +418,7 @@ public class CommandListener implements CommandExecutor { } + @Deprecated @SuppressWarnings("deprecation") public void cmdDelete(CommandSender sender) { @@ -429,7 +431,7 @@ public class CommandListener implements CommandExecutor { if (brew.isPersistent()) { p.msg(sender, p.languageReader.get("CMD_PersistRemove")); } else { - brew.remove(hand); + //brew.remove(hand); player.setItemInHand(new ItemStack(Material.AIR)); } return; @@ -442,6 +444,7 @@ public class CommandListener implements CommandExecutor { } + @Deprecated @SuppressWarnings("deprecation") public void cmdPersist(CommandSender sender) { @@ -461,6 +464,7 @@ public class CommandListener implements CommandExecutor { p.msg(sender, p.languageReader.get("CMD_Persistent")); } brew.touch(); + brew.save(hand); return; } } @@ -492,6 +496,7 @@ public class CommandListener implements CommandExecutor { p.msg(sender, p.languageReader.get("CMD_Static")); } brew.touch(); + brew.save(hand); return; } } @@ -513,6 +518,7 @@ public class CommandListener implements CommandExecutor { if (brew != null) { brew.unLabel(hand); brew.touch(); + brew.save(hand); p.msg(sender, p.languageReader.get("CMD_UnLabel")); return; } diff --git a/src/com/dre/brewery/listeners/EntityListener.java b/src/com/dre/brewery/listeners/EntityListener.java index 0947802..c32fdc1 100644 --- a/src/com/dre/brewery/listeners/EntityListener.java +++ b/src/com/dre/brewery/listeners/EntityListener.java @@ -28,10 +28,7 @@ public class EntityListener implements Listener { public void onItemDespawn(ItemDespawnEvent event) { ItemStack item = event.getEntity().getItemStack(); if (item.getType() == Material.POTION) { - Brew brew = Brew.get(item); - if (brew != null) { - brew.remove(item); - } + Brew.removeLegacy(item); } } @@ -42,10 +39,7 @@ public class EntityListener implements Listener { if (entity instanceof Item) { ItemStack item = ((Item) entity).getItemStack(); if (item.getType() == Material.POTION) { - Brew brew = Brew.get(item); - if (brew != null) { - brew.remove(item); - } + Brew.removeLegacy(item); } } } diff --git a/src/com/dre/brewery/listeners/InventoryListener.java b/src/com/dre/brewery/listeners/InventoryListener.java index c6c069f..f74e6c4 100644 --- a/src/com/dre/brewery/listeners/InventoryListener.java +++ b/src/com/dre/brewery/listeners/InventoryListener.java @@ -7,10 +7,6 @@ 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.Base91DecoderStream; -import com.dre.brewery.lore.Base91EncoderStream; -import com.dre.brewery.lore.LoreLoadStream; -import com.dre.brewery.lore.LoreSaveStream; import org.bukkit.Bukkit; import org.bukkit.Material; import org.bukkit.Sound; @@ -38,9 +34,6 @@ import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.meta.PotionMeta; import org.bukkit.scheduler.BukkitRunnable; -import java.io.DataInputStream; -import java.io.DataOutputStream; -import java.io.IOException; import java.util.HashMap; import java.util.HashSet; import java.util.Iterator; @@ -209,25 +202,13 @@ public class InventoryListener implements Listener { for (int slot = 0; slot < 3; slot++) { item = inv.getItem(slot); if (item != null) { - contents[slot] = Brew.get(item); - } - } - return contents; - } - - private byte hasCustom(BrewerInventory brewer) { - ItemStack item = brewer.getItem(3); // ingredient - boolean glowstone = (item != null && Material.GLOWSTONE_DUST == item.getType()); // need dust in the top slot. - byte customFound = 0; - for (Brew brew : getDistillContents(brewer)) { - if (brew != null) { - if (!glowstone) { - return 1; - } - if (brew.canDistill()) { - return 2; - } else { - customFound = 1; + if (item.getType() == Material.POTION) { + if (item.hasItemMeta()) { + Brew pot = Brew.get(item); + if (pot != null && (!distill || pot.canDistill())) { // need at least one distillable potion. + return true; + } + } } } } @@ -249,14 +230,24 @@ public class InventoryListener implements Listener { private boolean runDistill(BrewerInventory inv) { boolean custom = false; - Brew[] contents = getDistillContents(inv); - for (int slot = 0; slot < 3; slot++) { - if (contents[slot] == null) continue; - if (contents[slot].canDistill()) { - // is further distillable - custom = true; - } else { - contents[slot] = null; + Boolean[] contents = new Boolean[3]; + while (slot < 3) { + item = inv.getItem(slot); + contents[slot] = false; + if (item != null) { + if (item.getType() == Material.POTION) { + if (item.hasItemMeta()) { + Brew brew = Brew.get(item); + if (brew != null) { + // has custom potion in "slot" + if (brew.canDistill()) { + // is further distillable + contents[slot] = true; + custom = true; + } + } + } + } } } if (custom) { @@ -305,14 +296,16 @@ public class InventoryListener implements Listener { item.setItemMeta(potion); } } - brew.touch(); + P.p.log(brew.toString()); + //P.p.log(potion.getLore().get(0)); + //brew.touch(); - try { + /*try { DataInputStream in = new DataInputStream(new Base91DecoderStream(new LoreLoadStream(potion))); brew.testLoad(in); - /*if (in.readByte() == 27 && in.skip(48) > 0) { + *//*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(); @@ -326,7 +319,7 @@ public class InventoryListener implements Listener { } } else { P.p.log("false1"); - }*/ + }*//* in.close(); } catch (IllegalArgumentException argExc) { @@ -339,7 +332,7 @@ public class InventoryListener implements Listener { brew.testStore(out); - /*out.writeByte(27); + *//*out.writeByte(27); out.writeLong(1111); //skip out.writeLong(1111); //skip out.writeLong(1111); //skip @@ -349,16 +342,16 @@ public class InventoryListener implements Listener { out.writeUTF("TESTHalloª∆Ω"); out.writeInt(34834); out.writeInt(6436); //skip - out.writeLong(Long.MAX_VALUE);*/ + out.writeLong(Long.MAX_VALUE);*//* out.close(); - /*StringBuilder b = new StringBuilder(); + *//*StringBuilder b = new StringBuilder(); for (char c : "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789!$%&()*+,-./:;<=>?@[]^_`{|}~\"".toCharArray()) { b.append('§').append(c); } List lore = potion.getLore(); lore.add(b.toString()); - potion.setLore(lore);*/ + potion.setLore(lore);*//* item.setItemMeta(potion); } catch (IOException h) { @@ -367,7 +360,7 @@ public class InventoryListener implements Listener { } catch (IOException e) { e.printStackTrace(); - } + }*/ } } } diff --git a/src/com/dre/brewery/listeners/PlayerListener.java b/src/com/dre/brewery/listeners/PlayerListener.java index e902122..a39a4ac 100644 --- a/src/com/dre/brewery/listeners/PlayerListener.java +++ b/src/com/dre/brewery/listeners/PlayerListener.java @@ -257,9 +257,9 @@ public class PlayerListener implements Listener { Brew brew = Brew.get(item); if (brew != null) { BPlayer.drink(brew, player); - if (player.getGameMode() != GameMode.CREATIVE) { + /*if (player.getGameMode() != org.bukkit.GameMode.CREATIVE) { brew.remove(item); - } + }*/ if (P.use1_9) { if (player.getGameMode() != GameMode.CREATIVE) { // replace the potion with an empty potion to avoid effects From cdb36b1736622b4025886a43b782be52df01c520 Mon Sep 17 00:00:00 2001 From: Sn0wStorm Date: Fri, 17 Jun 2016 00:04:41 +0200 Subject: [PATCH 09/51] Save ingredients of Brews --- src/com/dre/brewery/BRecipe.java | 2 +- src/com/dre/brewery/Brew.java | 132 ++++++++---------- .../brewery/listeners/InventoryListener.java | 2 +- 3 files changed, 58 insertions(+), 78 deletions(-) diff --git a/src/com/dre/brewery/BRecipe.java b/src/com/dre/brewery/BRecipe.java index 25417f4..10a4f2e 100644 --- a/src/com/dre/brewery/BRecipe.java +++ b/src/com/dre/brewery/BRecipe.java @@ -262,7 +262,7 @@ public class BRecipe { BIngredients bIngredients = new BIngredients(list, cookingTime); - Brew brew = new Brew(bIngredients, quality, distillruns, getAge(), wood, getName(5), false, false, true); + Brew brew = new Brew(bIngredients, quality, distillruns, getAge(), wood, getName(5), false, true); Brew.PotionColor.fromString(getColor()).colorBrew(potionMeta, potion, false); potionMeta.setDisplayName(P.p.color("&f" + getName(quality))); diff --git a/src/com/dre/brewery/Brew.java b/src/com/dre/brewery/Brew.java index f492046..df16169 100644 --- a/src/com/dre/brewery/Brew.java +++ b/src/com/dre/brewery/Brew.java @@ -41,8 +41,8 @@ public class Brew { private float wood; private BRecipe currentRecipe; private boolean unlabeled; - private boolean persistent; - private boolean stat; // static potions should not be changed + private boolean persistent; // Only for legacy + private boolean immutable; // static/immutable potions should not be changed //private int lastUpdate; // last update in hours after install time public Brew(BIngredients ingredients) { @@ -57,15 +57,14 @@ public class Brew { } // loading with all values set - public Brew(BIngredients ingredients, int quality, byte distillRuns, float ageTime, float wood, String recipe, boolean unlabeled, boolean persistent, boolean stat) { + public Brew(BIngredients ingredients, int quality, byte distillRuns, float ageTime, float wood, String recipe, boolean unlabeled, boolean immutable) { this.ingredients = ingredients; this.quality = quality; this.distillRuns = distillRuns; this.ageTime = ageTime; this.wood = wood; this.unlabeled = unlabeled; - this.persistent = persistent; - this.stat = stat; + this.immutable = immutable; setRecipeFromString(recipe); } @@ -191,7 +190,7 @@ public class Brew { if (quality > 0) { currentRecipe = ingredients.getBestRecipe(wood, ageTime, distillRuns > 0); if (currentRecipe != null) { - if (!stat) { + if (!immutable) { this.quality = calcQuality(); } P.p.log("Brew was made from Recipe: '" + name + "' which could not be found. '" + currentRecipe.getName(5) + "' used instead!"); @@ -232,9 +231,8 @@ public class Brew { brew.distillRuns = distillRuns; brew.ageTime = ageTime; brew.unlabeled = unlabeled; - if (!brew.persistent) { - brew.stat = stat; - } + brew.persistent = persistent; + brew.immutable = immutable; return brew; } @@ -248,8 +246,7 @@ public class Brew { ", wood=" + wood + ", currentRecipe=" + currentRecipe + ", unlabeled=" + unlabeled + - ", persistent=" + persistent + - ", stat=" + stat + + ", immutable=" + immutable + '}'; } @@ -321,7 +318,7 @@ public class Brew { } public boolean canDistill() { - if (stat) return false; + if (immutable) return false; if (currentRecipe != null) { return currentRecipe.getDistillRuns() > distillRuns; } else { @@ -392,14 +389,14 @@ public class Brew { } public boolean isStatic() { - return stat; + return immutable; } // Set the Static flag, so potion is unchangeable - public void setStatic(boolean stat, ItemStack potion) { - this.stat = stat; + public void setStatic(boolean immutable, ItemStack potion) { + this.immutable = immutable; if (currentRecipe != null && canDistill()) { - if (stat) { + if (immutable) { PotionColor.fromString(currentRecipe.getColor()).colorBrew(((PotionMeta) potion.getItemMeta()), potion, false); } else { PotionColor.fromString(currentRecipe.getColor()).colorBrew(((PotionMeta) potion.getItemMeta()), potion, true); @@ -426,9 +423,7 @@ public class Brew { // distill custom potion in given slot public void distillSlot(ItemStack slotItem, PotionMeta potionMeta) { - if (stat) { - return; - } + if (immutable) return; distillRuns += 1; BRecipe recipe = ingredients.getdistillRecipe(wood, ageTime); @@ -484,9 +479,7 @@ public class Brew { // Ageing Section ------------------ public void age(ItemStack item, float time, byte woodType) { - if (stat) { - return; - } + if (immutable) return; PotionMeta potionMeta = (PotionMeta) item.getItemMeta(); ageTime += time; @@ -739,8 +732,7 @@ public class Brew { } catch (IllegalArgumentException ignored) { return null; } - DataInputStream in = new DataInputStream(new Base91DecoderStream(loreStream)); - try { + try (DataInputStream in = new DataInputStream(new Base91DecoderStream(loreStream))) { if (in.readByte() != 86) { P.p.errorLog("parity check failed on Brew while loading, trying to load anyways!"); } @@ -758,18 +750,10 @@ public class Brew { } catch (IOException e) { P.p.errorLog("IO Error while loading Brew"); e.printStackTrace(); - } finally { - try { - in.close(); - } catch (IOException e) { - e.printStackTrace(); - } } return null; } - // TODO load and save Ingredients - private void loadFromStream(DataInputStream in) throws IOException { quality = in.readByte(); int bools = in.readUnsignedByte(); @@ -788,14 +772,19 @@ public class Brew { setRecipeFromString(null); } unlabeled = (bools & 16) != 0; - persistent = (bools & 32) != 0; - stat = (bools & 64) != 0; + //persistent = (bools & 32) != 0; + immutable = (bools & 32) != 0; + ingredients = BIngredients.load(in); } // Save brew data into meta/lore public void save(ItemMeta meta) { - LoreSaveStream loreStream = new LoreSaveStream(meta, 0); - saveToStream(new DataOutputStream(new Base91EncoderStream(loreStream))); + try (DataOutputStream out = new DataOutputStream(new Base91EncoderStream(new LoreSaveStream(meta, 0)))) { + saveToStream(out); + } catch (IOException e) { + P.p.errorLog("IO Error while saving Brew"); + e.printStackTrace(); + } } // Save brew data into the meta/lore of the specified item @@ -811,50 +800,41 @@ public class Brew { item.setItemMeta(meta); } - public void saveToStream(DataOutputStream out) { - try { - out.writeByte(86); // Parity/sanity - out.writeByte(1); // Version - if (quality > 10) { - quality = 10; - } - out.writeByte((byte) quality); - int bools = 0; - bools |= ((distillRuns != 0) ? 1 : 0); - bools |= (ageTime > 0 ? 2 : 0); - bools |= (wood != -1 ? 4 : 0); - bools |= (currentRecipe != null ? 8 : 0); - bools |= (unlabeled ? 16 : 0); - bools |= (persistent ? 32 : 0); // TODO remove persistence - bools |= (stat ? 64 : 0); - out.writeByte(bools); - if (distillRuns != 0) { - out.writeByte(distillRuns); - } - if (ageTime > 0) { - out.writeFloat(ageTime); - } - if (wood != -1) { - out.writeFloat(wood); - } - if (currentRecipe != null) { - out.writeUTF(currentRecipe.getName(5)); - } - } catch (IOException e) { - P.p.errorLog("IO Error while saving Brew"); - e.printStackTrace(); - } finally { - try { - out.close(); - } catch (IOException e) { - e.printStackTrace(); - } + public void saveToStream(DataOutputStream out) throws IOException { + out.writeByte(86); // Parity/sanity + out.writeByte(1); // Version + if (quality > 10) { + quality = 10; } + out.writeByte((byte) quality); + int bools = 0; + bools |= ((distillRuns != 0) ? 1 : 0); + bools |= (ageTime > 0 ? 2 : 0); + bools |= (wood != -1 ? 4 : 0); + bools |= (currentRecipe != null ? 8 : 0); + bools |= (unlabeled ? 16 : 0); + //bools |= (persistent ? 32 : 0); + bools |= (immutable ? 32 : 0); + out.writeByte(bools); + if (distillRuns != 0) { + out.writeByte(distillRuns); + } + if (ageTime > 0) { + out.writeFloat(ageTime); + } + if (wood != -1) { + out.writeFloat(wood); + } + if (currentRecipe != null) { + out.writeUTF(currentRecipe.getName(5)); + } + ingredients.save(out); } // 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) { - Brew brew = new Brew(ingredients, quality, distillRuns, ageTime, wood, recipe, unlabeled, persistent, stat); + Brew brew = new Brew(ingredients, quality, distillRuns, ageTime, wood, recipe, unlabeled, stat); + brew.persistent = persistent; legacyPotions.put(uid, brew); } @@ -904,7 +884,7 @@ public class Brew { if (brew.persistent) { idConfig.set("persist", true); } - if (brew.stat) { + if (brew.immutable) { idConfig.set("stat", true); } /*if (brew.lastUpdate > 0) { diff --git a/src/com/dre/brewery/listeners/InventoryListener.java b/src/com/dre/brewery/listeners/InventoryListener.java index f74e6c4..a55bb69 100644 --- a/src/com/dre/brewery/listeners/InventoryListener.java +++ b/src/com/dre/brewery/listeners/InventoryListener.java @@ -297,7 +297,7 @@ public class InventoryListener implements Listener { } } P.p.log(brew.toString()); - //P.p.log(potion.getLore().get(0)); + P.p.log(potion.getLore().get(0).replaceAll("§", "")); //brew.touch(); /*try { From 9bf3268fb429006956f83a267a57949f8136c44c Mon Sep 17 00:00:00 2001 From: Sn0wStorm Date: Wed, 29 Jun 2016 22:44:19 +0200 Subject: [PATCH 10/51] Added XOR Scrambler for Brew data Very fast obfuscator for brew data so that a client cant easily read it --- src/com/dre/brewery/Brew.java | 44 ++++-- src/com/dre/brewery/P.java | 133 ++++++++++++++++++ src/com/dre/brewery/filedata/DataSave.java | 3 + src/com/dre/brewery/lore/SeedInputStream.java | 94 +++++++++++++ .../dre/brewery/lore/XORScrambleStream.java | 67 +++++++++ .../dre/brewery/lore/XORUnscrambleStream.java | 100 +++++++++++++ 6 files changed, 430 insertions(+), 11 deletions(-) create mode 100644 src/com/dre/brewery/lore/SeedInputStream.java create mode 100644 src/com/dre/brewery/lore/XORScrambleStream.java create mode 100644 src/com/dre/brewery/lore/XORUnscrambleStream.java diff --git a/src/com/dre/brewery/Brew.java b/src/com/dre/brewery/Brew.java index df16169..6964fe1 100644 --- a/src/com/dre/brewery/Brew.java +++ b/src/com/dre/brewery/Brew.java @@ -1,10 +1,7 @@ package com.dre.brewery; import org.bukkit.Color; -import com.dre.brewery.lore.Base91DecoderStream; -import com.dre.brewery.lore.Base91EncoderStream; -import com.dre.brewery.lore.LoreLoadStream; -import com.dre.brewery.lore.LoreSaveStream; +import com.dre.brewery.lore.*; import org.bukkit.Material; import org.bukkit.configuration.ConfigurationSection; import org.bukkit.inventory.BrewerInventory; @@ -20,6 +17,7 @@ import org.bukkit.potion.PotionType; import java.io.DataInputStream; import java.io.DataOutputStream; import java.io.IOException; +import java.security.SecureRandom; import java.util.ArrayList; import java.util.HashMap; import java.util.List; @@ -28,7 +26,7 @@ import java.util.Map; public class Brew { // represents the liquid in the brewed Potions - + private static long saveSeed; public static Map legacyPotions = new HashMap<>(); public static long installTime = System.currentTimeMillis(); // plugin install time in millis after epoch public static Boolean colorInBarrels; // color the Lore while in Barrels @@ -732,18 +730,26 @@ public class Brew { } catch (IllegalArgumentException ignored) { 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) { - 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(); byte ver = in.readByte(); switch (ver) { case 1: + unscrambler.start(); brew.loadFromStream(in); break; 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 brew; @@ -779,7 +785,11 @@ public class Brew { // Save brew data into meta/lore 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); } catch (IOException e) { P.p.errorLog("IO Error while saving Brew"); @@ -801,8 +811,6 @@ public class Brew { } public void saveToStream(DataOutputStream out) throws IOException { - out.writeByte(86); // Parity/sanity - out.writeByte(1); // Version if (quality > 10) { quality = 10; } @@ -831,6 +839,20 @@ public class Brew { 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 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); diff --git a/src/com/dre/brewery/P.java b/src/com/dre/brewery/P.java index e37b855..c5e2e82 100644 --- a/src/com/dre/brewery/P.java +++ b/src/com/dre/brewery/P.java @@ -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"); + /*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 { ItemMeta meta = new ItemStack(Material.POTION).getItemMeta(); @@ -577,8 +707,11 @@ public class P extends JavaPlugin { FileConfiguration data = YamlConfiguration.loadConfiguration(file); Brew.installTime = data.getLong("installTime", System.currentTimeMillis()); + MCBarrel.mcBarrelTime = data.getLong("MCBarrelTime", 0); + Brew.loadSeed(data); + // Check if data is the newest version String version = data.getString("Version", null); if (version != null) { diff --git a/src/com/dre/brewery/filedata/DataSave.java b/src/com/dre/brewery/filedata/DataSave.java index 6f1a3a0..f3d9a6a 100644 --- a/src/com/dre/brewery/filedata/DataSave.java +++ b/src/com/dre/brewery/filedata/DataSave.java @@ -62,8 +62,11 @@ public class DataSave extends BukkitRunnable { FileConfiguration configFile = new YamlConfiguration(); configFile.set("installTime", Brew.installTime); + configFile.set("MCBarrelTime", MCBarrel.mcBarrelTime); + Brew.writeSeed(configFile); + if (!Brew.legacyPotions.isEmpty()) { Brew.save(configFile.createSection("Brew")); } diff --git a/src/com/dre/brewery/lore/SeedInputStream.java b/src/com/dre/brewery/lore/SeedInputStream.java new file mode 100644 index 0000000..c293297 --- /dev/null +++ b/src/com/dre/brewery/lore/SeedInputStream.java @@ -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]; + } +} diff --git a/src/com/dre/brewery/lore/XORScrambleStream.java b/src/com/dre/brewery/lore/XORScrambleStream.java new file mode 100644 index 0000000..da669c5 --- /dev/null +++ b/src/com/dre/brewery/lore/XORScrambleStream.java @@ -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(); + } +} diff --git a/src/com/dre/brewery/lore/XORUnscrambleStream.java b/src/com/dre/brewery/lore/XORUnscrambleStream.java new file mode 100644 index 0000000..44e49a6 --- /dev/null +++ b/src/com/dre/brewery/lore/XORUnscrambleStream.java @@ -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; + } +} From 2121bf5c8aa440ce8e6af10850716dd6911cc7ae Mon Sep 17 00:00:00 2001 From: Sn0wStorm Date: Wed, 29 Jun 2016 23:24:39 +0200 Subject: [PATCH 11/51] Added Parity/Sanity to Scrambling --- src/com/dre/brewery/Brew.java | 10 +++++++--- src/com/dre/brewery/P.java | 2 ++ src/com/dre/brewery/lore/XORScrambleStream.java | 2 +- src/com/dre/brewery/lore/XORUnscrambleStream.java | 6 +++++- 4 files changed, 15 insertions(+), 5 deletions(-) diff --git a/src/com/dre/brewery/Brew.java b/src/com/dre/brewery/Brew.java index 6964fe1..571fa49 100644 --- a/src/com/dre/brewery/Brew.java +++ b/src/com/dre/brewery/Brew.java @@ -17,6 +17,7 @@ import org.bukkit.potion.PotionType; import java.io.DataInputStream; import java.io.DataOutputStream; import java.io.IOException; +import java.security.InvalidKeyException; import java.security.SecureRandom; import java.util.ArrayList; import java.util.HashMap; @@ -756,6 +757,9 @@ public class Brew { } catch (IOException e) { P.p.errorLog("IO Error while loading Brew"); e.printStackTrace(); + } catch (InvalidKeyException e) { + P.p.errorLog("Failed to load Brew, has the data key 'BrewDataSeed' in the data.yml been changed?"); + e.printStackTrace(); } return null; } @@ -840,12 +844,12 @@ public class Brew { } public static void writeSeed(ConfigurationSection section) { - section.set("seed", saveSeed); + section.set("BrewDataSeed", saveSeed); } public static void loadSeed(ConfigurationSection section) { - if (section.contains("seed")) { - saveSeed = section.getLong("seed"); + if (section.contains("BrewDataSeed")) { + saveSeed = section.getLong("BrewDataSeed"); } else { while (saveSeed == 0) { saveSeed = new SecureRandom().nextLong(); diff --git a/src/com/dre/brewery/P.java b/src/com/dre/brewery/P.java index c5e2e82..6da5872 100644 --- a/src/com/dre/brewery/P.java +++ b/src/com/dre/brewery/P.java @@ -206,6 +206,8 @@ public class P extends JavaPlugin { } catch (IOException e) { e.printStackTrace(); + } catch (InvalidKeyException e) { + e.printStackTrace(); } finally { try { data.close(); diff --git a/src/com/dre/brewery/lore/XORScrambleStream.java b/src/com/dre/brewery/lore/XORScrambleStream.java index da669c5..c573b84 100644 --- a/src/com/dre/brewery/lore/XORScrambleStream.java +++ b/src/com/dre/brewery/lore/XORScrambleStream.java @@ -1,6 +1,5 @@ package com.dre.brewery.lore; - import java.io.FilterOutputStream; import java.io.IOException; import java.io.OutputStream; @@ -27,6 +26,7 @@ public class XORScrambleStream extends FilterOutputStream { xorStream = new SeedInputStream(seed ^ id); out.write((byte) (id >> 8)); out.write((byte) id); + write(209); // parity/sanity } } diff --git a/src/com/dre/brewery/lore/XORUnscrambleStream.java b/src/com/dre/brewery/lore/XORUnscrambleStream.java index 44e49a6..a7a6ed5 100644 --- a/src/com/dre/brewery/lore/XORUnscrambleStream.java +++ b/src/com/dre/brewery/lore/XORUnscrambleStream.java @@ -3,6 +3,7 @@ package com.dre.brewery.lore; import java.io.FilterInputStream; import java.io.IOException; import java.io.InputStream; +import java.security.InvalidKeyException; public class XORUnscrambleStream extends FilterInputStream { @@ -17,7 +18,7 @@ public class XORUnscrambleStream extends FilterInputStream { this.seed = seed; } - public void start() throws IOException { + public void start() throws IOException, InvalidKeyException { running = true; if (xorStream == null) { short id = (short) (in.read() << 8 | in.read()); @@ -26,6 +27,9 @@ public class XORUnscrambleStream extends FilterInputStream { return; } xorStream = new SeedInputStream(seed ^ id); + if (read() != 209) { // Parity/Sanity + throw new InvalidKeyException("Could not read scrambled data, is the seed wrong?"); + } } } From 562f96e4b1bbfd4901a1da8d76470b2dd699e4e5 Mon Sep 17 00:00:00 2001 From: Sn0wStorm Date: Thu, 30 Jun 2016 14:34:16 +0200 Subject: [PATCH 12/51] Slightly larger En/Decoder buffers, isSimilar for Brew --- src/com/dre/brewery/BIngredients.java | 10 +++++ src/com/dre/brewery/BRecipe.java | 38 +++++++++++++------ src/com/dre/brewery/Brew.java | 14 +++++++ .../brewery/listeners/InventoryListener.java | 2 + .../dre/brewery/lore/Base91DecoderStream.java | 8 ++-- .../dre/brewery/lore/Base91EncoderStream.java | 4 +- 6 files changed, 59 insertions(+), 17 deletions(-) diff --git a/src/com/dre/brewery/BIngredients.java b/src/com/dre/brewery/BIngredients.java index 592d2af..2f91db8 100644 --- a/src/com/dre/brewery/BIngredients.java +++ b/src/com/dre/brewery/BIngredients.java @@ -327,6 +327,16 @@ public class BIngredients { return Math.max(quality, 0); } + @Override + public boolean equals(Object obj) { + if (this == obj) return true; + if (!(obj instanceof BIngredients)) return false; + BIngredients other = ((BIngredients) obj); + return cookedTime == other.cookedTime && + ingredients.equals(other.ingredients) && + materials.equals(other.materials); + } + // Creates a copy ingredients @Override public BIngredients clone() { diff --git a/src/com/dre/brewery/BRecipe.java b/src/com/dre/brewery/BRecipe.java index 10a4f2e..30402ce 100644 --- a/src/com/dre/brewery/BRecipe.java +++ b/src/com/dre/brewery/BRecipe.java @@ -6,6 +6,7 @@ import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.meta.PotionMeta; import java.util.ArrayList; +import java.util.Arrays; import java.util.List; public class BRecipe { @@ -251,18 +252,7 @@ public class BRecipe { ItemStack potion = new ItemStack(Material.POTION); PotionMeta potionMeta = (PotionMeta) potion.getItemMeta(); - ArrayList list = new ArrayList<>(ingredients.size()); - for (ItemStack item : ingredients) { - if (item.getDurability() == -1) { - list.add(new ItemStack(item.getType(), item.getAmount())); - } else { - list.add(item.clone()); - } - } - - BIngredients bIngredients = new BIngredients(list, cookingTime); - - Brew brew = new Brew(bIngredients, quality, distillruns, getAge(), wood, getName(5), false, true); + Brew brew = createBrew(quality); Brew.PotionColor.fromString(getColor()).colorBrew(potionMeta, potion, false); potionMeta.setDisplayName(P.p.color("&f" + getName(quality))); @@ -283,6 +273,21 @@ public class BRecipe { return potion; } + public Brew createBrew(int quality) { + ArrayList list = new ArrayList<>(ingredients.size()); + for (ItemStack item : ingredients) { + if (item.getDurability() == -1) { + list.add(new ItemStack(item.getType(), item.getAmount())); + } else { + list.add(item.clone()); + } + } + + BIngredients bIngredients = new BIngredients(list, cookingTime); + + return new Brew(bIngredients, quality, distillruns, getAge(), wood, getName(5), false, true); + } + // Getter @@ -365,4 +370,13 @@ public class BRecipe { public String toString() { return "BRecipe{" + getName(5) + '}'; } + + public static BRecipe get(String name) { + for (BRecipe recipe : BIngredients.recipes) { + if (recipe.getName(5).equalsIgnoreCase(name)) { + return recipe; + } + } + return null; + } } diff --git a/src/com/dre/brewery/Brew.java b/src/com/dre/brewery/Brew.java index 571fa49..798545b 100644 --- a/src/com/dre/brewery/Brew.java +++ b/src/com/dre/brewery/Brew.java @@ -222,6 +222,20 @@ public class Brew { return copy; }*/ + public boolean isSimilar(Brew brew) { + if (brew == null) return false; + if (equals(brew)) return true; + return quality == brew.quality && + distillRuns == brew.distillRuns && + Float.compare(brew.ageTime, ageTime) == 0 && + Float.compare(brew.wood, wood) == 0 && + unlabeled == brew.unlabeled && + persistent == brew.persistent && + immutable == brew.immutable && + ingredients.equals(brew.ingredients) && + currentRecipe != null ? currentRecipe.equals(brew.currentRecipe) : brew.currentRecipe == null; + } + // Clones this instance @Override public Brew clone() throws CloneNotSupportedException { diff --git a/src/com/dre/brewery/listeners/InventoryListener.java b/src/com/dre/brewery/listeners/InventoryListener.java index a55bb69..dace63a 100644 --- a/src/com/dre/brewery/listeners/InventoryListener.java +++ b/src/com/dre/brewery/listeners/InventoryListener.java @@ -298,6 +298,8 @@ public class InventoryListener implements Listener { } P.p.log(brew.toString()); P.p.log(potion.getLore().get(0).replaceAll("§", "")); + P.p.log("similar to beispiel? " + BRecipe.get("Beispiel").createBrew(10).isSimilar(brew)); + //brew.touch(); /*try { diff --git a/src/com/dre/brewery/lore/Base91DecoderStream.java b/src/com/dre/brewery/lore/Base91DecoderStream.java index d784ac2..7dbbb1f 100644 --- a/src/com/dre/brewery/lore/Base91DecoderStream.java +++ b/src/com/dre/brewery/lore/Base91DecoderStream.java @@ -7,8 +7,8 @@ import java.io.InputStream; public class Base91DecoderStream extends FilterInputStream { private final basE91 decoder = new basE91(); - private byte[] decbuf = new byte[18]; - private byte[] buf = new byte[18]; + private byte[] decbuf = new byte[32]; + private byte[] buf = new byte[32]; private int reader = 0; private int count = 0; private byte[] markBuf = null; @@ -62,6 +62,7 @@ public class Base91DecoderStream extends FilterInputStream { int out = 0; int writeSize; while (count > 0) { + // Not enough data in buffer, write all out, decode and repeat writeSize = Math.min(len, count - reader); System.arraycopy(buf, reader, b, off + out, writeSize); out += writeSize; @@ -99,7 +100,8 @@ public class Base91DecoderStream extends FilterInputStream { @Override public int available() throws IOException { - return (int) (in.available() * 0.813F); // Ratio encoded to decoded with random data + if (count == -1) return 0; + return (int) (in.available() * 0.813F) + count - reader; // Ratio encoded to decoded with random data } @Override diff --git a/src/com/dre/brewery/lore/Base91EncoderStream.java b/src/com/dre/brewery/lore/Base91EncoderStream.java index 224bc29..0de1354 100644 --- a/src/com/dre/brewery/lore/Base91EncoderStream.java +++ b/src/com/dre/brewery/lore/Base91EncoderStream.java @@ -8,8 +8,8 @@ import java.io.OutputStream; public class Base91EncoderStream extends FilterOutputStream { private final basE91 encoder = new basE91(); - private byte[] buf = new byte[16]; - private byte[] encBuf = new byte[24]; + private byte[] buf = new byte[32]; + private byte[] encBuf = new byte[48]; private int writer = 0; private int encoded = 0; From 2fc0b321794215cdd7f379f59451232be6808d42 Mon Sep 17 00:00:00 2001 From: Sn0wStorm Date: Thu, 30 Jun 2016 15:32:10 +0200 Subject: [PATCH 13/51] Change Parity of Scrambler --- src/com/dre/brewery/lore/XORScrambleStream.java | 2 +- src/com/dre/brewery/lore/XORUnscrambleStream.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/com/dre/brewery/lore/XORScrambleStream.java b/src/com/dre/brewery/lore/XORScrambleStream.java index c573b84..f37dd43 100644 --- a/src/com/dre/brewery/lore/XORScrambleStream.java +++ b/src/com/dre/brewery/lore/XORScrambleStream.java @@ -26,7 +26,7 @@ public class XORScrambleStream extends FilterOutputStream { xorStream = new SeedInputStream(seed ^ id); out.write((byte) (id >> 8)); out.write((byte) id); - write(209); // parity/sanity + write((int) (seed >> 48) & 0xFF); // parity/sanity } } diff --git a/src/com/dre/brewery/lore/XORUnscrambleStream.java b/src/com/dre/brewery/lore/XORUnscrambleStream.java index a7a6ed5..25e45f5 100644 --- a/src/com/dre/brewery/lore/XORUnscrambleStream.java +++ b/src/com/dre/brewery/lore/XORUnscrambleStream.java @@ -27,7 +27,7 @@ public class XORUnscrambleStream extends FilterInputStream { return; } xorStream = new SeedInputStream(seed ^ id); - if (read() != 209) { // Parity/Sanity + if (read() != ((int) (seed >> 48) & 0xFF)) { // Parity/Sanity throw new InvalidKeyException("Could not read scrambled data, is the seed wrong?"); } } From 49fb0e3d82fd64376df6d8613fdfa7bfa494129c Mon Sep 17 00:00:00 2001 From: Sn0wStorm Date: Fri, 1 Jul 2016 22:01:35 +0200 Subject: [PATCH 14/51] Changed Lore Handling --- src/com/dre/brewery/BIngredients.java | 4 +- src/com/dre/brewery/BRecipe.java | 7 +- src/com/dre/brewery/BUtil.java | 28 ++ src/com/dre/brewery/Barrel.java | 7 +- src/com/dre/brewery/Brew.java | 260 ++++-------------- .../brewery/listeners/InventoryListener.java | 25 +- src/com/dre/brewery/lore/BrewLore.java | 221 +++++++++++++++ 7 files changed, 334 insertions(+), 218 deletions(-) create mode 100644 src/com/dre/brewery/BUtil.java create mode 100644 src/com/dre/brewery/lore/BrewLore.java diff --git a/src/com/dre/brewery/BIngredients.java b/src/com/dre/brewery/BIngredients.java index 2f91db8..2631374 100644 --- a/src/com/dre/brewery/BIngredients.java +++ b/src/com/dre/brewery/BIngredients.java @@ -1,5 +1,6 @@ package com.dre.brewery; +import com.dre.brewery.lore.BrewLore; import org.bukkit.Material; import org.bukkit.configuration.ConfigurationSection; import org.bukkit.inventory.ItemStack; @@ -89,7 +90,8 @@ public class BIngredients { int quality = (int) Math.round((getIngredientQuality(cookRecipe) + getCookingQuality(cookRecipe, false)) / 2.0); P.p.debugLog("cooked potion has Quality: " + quality); brew = new Brew(quality, cookRecipe, this); - Brew.addOrReplaceEffects(potionMeta, brew.getEffects(), brew.getQuality()); + BrewLore lore = new BrewLore(brew, potionMeta); + lore.addOrReplaceEffects(brew.getEffects(), brew.getQuality()); cookedName = cookRecipe.getName(quality); Brew.PotionColor.fromString(cookRecipe.getColor()).colorBrew(potionMeta, potion, false); diff --git a/src/com/dre/brewery/BRecipe.java b/src/com/dre/brewery/BRecipe.java index 30402ce..33c3e1a 100644 --- a/src/com/dre/brewery/BRecipe.java +++ b/src/com/dre/brewery/BRecipe.java @@ -1,5 +1,6 @@ package com.dre.brewery; +import com.dre.brewery.lore.BrewLore; import org.bukkit.Material; import org.bukkit.configuration.ConfigurationSection; import org.bukkit.inventory.ItemStack; @@ -264,8 +265,10 @@ public class BRecipe { // This effect stores the UID in its Duration //potionMeta.addCustomEffect((PotionEffectType.REGENERATION).createEffect((uid * 4), 0), true); - brew.convertLore(potionMeta, false); - Brew.addOrReplaceEffects(potionMeta, effects, quality); + BrewLore lore = new BrewLore(brew, potionMeta); + lore.convertLore(false); + lore.addOrReplaceEffects(effects, quality); + lore.write(); brew.touch(); brew.save(potionMeta); diff --git a/src/com/dre/brewery/BUtil.java b/src/com/dre/brewery/BUtil.java new file mode 100644 index 0000000..2864419 --- /dev/null +++ b/src/com/dre/brewery/BUtil.java @@ -0,0 +1,28 @@ +package com.dre.brewery; + +import java.util.List; + +public class BUtil { + + // Returns the Index of a String from the list that contains this substring + public static int indexOfSubstring(List list, String substring) { + if (list.isEmpty()) return -1; + for (int index = 0, size = list.size(); index < size; index++) { + String string = list.get(index); + if (string.contains(substring)) { + return index; + } + } + return -1; + } + + // Returns the index of a String from the list that starts with 'lineStart', returns -1 if not found; + public static int indexOfStart(List list, String lineStart) { + for (int i = 0, size = list.size(); i < size; i++) { + if (list.get(i).startsWith(lineStart)) { + return i; + } + } + return -1; + } +} diff --git a/src/com/dre/brewery/Barrel.java b/src/com/dre/brewery/Barrel.java index fb3d603..7cbd467 100644 --- a/src/com/dre/brewery/Barrel.java +++ b/src/com/dre/brewery/Barrel.java @@ -5,6 +5,7 @@ import com.dre.brewery.integration.GriefPreventionBarrel; import com.dre.brewery.integration.LWCBarrel; import com.dre.brewery.integration.LogBlockBarrel; import org.apache.commons.lang.ArrayUtils; +import com.dre.brewery.lore.BrewLore; import org.bukkit.Material; import org.bukkit.block.Block; import org.bukkit.configuration.ConfigurationSection; @@ -494,8 +495,10 @@ public class Barrel implements InventoryHolder { // Brew before throwing brew.age(item, time, getWood()); PotionMeta meta = (PotionMeta) item.getItemMeta(); - if (Brew.hasColorLore(meta)) { - brew.convertLore(meta, false); + if (BrewLore.hasColorLore(meta)) { + BrewLore lore = new BrewLore(brew, meta); + lore.convertLore(false); + lore.write(); item.setItemMeta(meta); } } diff --git a/src/com/dre/brewery/Brew.java b/src/com/dre/brewery/Brew.java index 798545b..1ff158d 100644 --- a/src/com/dre/brewery/Brew.java +++ b/src/com/dre/brewery/Brew.java @@ -21,7 +21,6 @@ import java.security.InvalidKeyException; import java.security.SecureRandom; import java.util.ArrayList; import java.util.HashMap; -import java.util.List; import java.util.Map; public class Brew { @@ -233,7 +232,7 @@ public class Brew { persistent == brew.persistent && immutable == brew.immutable && ingredients.equals(brew.ingredients) && - currentRecipe != null ? currentRecipe.equals(brew.currentRecipe) : brew.currentRecipe == null; + (currentRecipe != null ? currentRecipe.equals(brew.currentRecipe) : brew.currentRecipe == null); } // Clones this instance @@ -349,17 +348,19 @@ public class Brew { // Set unlabeled to true to hide the numbers in Lore public void unLabel(ItemStack item) { - PotionMeta meta = (PotionMeta) item.getItemMeta(); - if (meta.hasLore()) { + unlabeled = true; + ItemMeta meta = item.getItemMeta(); + if (meta instanceof PotionMeta && meta.hasLore()) { + BrewLore lore = new BrewLore(this, ((PotionMeta) meta)); if (distillRuns > 0) { - addOrReplaceLore(meta, P.p.color("&7"), P.p.languageReader.get("Brew_Distilled")); + lore.updateDistillLore(false); } if (ageTime >= 1) { - addOrReplaceLore(meta, P.p.color("&7"), P.p.languageReader.get("Brew_BarrelRiped")); + lore.updateAgeLore(false); } + lore.write(); item.setItemMeta(meta); } - unlabeled = true; } // Do some regular updates @@ -376,6 +377,18 @@ public class Brew { return ageTime; } + public float getWood() { + return wood; + } + + public BIngredients getIngredients() { + return ingredients; + } + + public boolean hasRecipe() { + return currentRecipe != null; + } + public BRecipe getCurrentRecipe() { return currentRecipe; } @@ -405,6 +418,14 @@ public class Brew { return immutable; } + public boolean isImmutable() { + return immutable; + } + + public boolean isUnlabeled() { + return unlabeled; + } + // Set the Static flag, so potion is unchangeable public void setStatic(boolean immutable, ItemStack potion) { this.immutable = immutable; @@ -439,34 +460,32 @@ public class Brew { if (immutable) return; distillRuns += 1; + BrewLore lore = new BrewLore(this, potionMeta); BRecipe recipe = ingredients.getdistillRecipe(wood, ageTime); if (recipe != null) { // distillRuns will have an effect on the amount of alcohol, not the quality currentRecipe = recipe; quality = calcQuality(); - addOrReplaceEffects(potionMeta, getEffects(), quality); + lore.addOrReplaceEffects(getEffects(), quality); potionMeta.setDisplayName(P.p.color("&f" + recipe.getName(quality))); PotionColor.fromString(recipe.getColor()).colorBrew(potionMeta, slotItem, canDistill()); } else { quality = 0; - removeEffects(potionMeta); + lore.removeEffects(); potionMeta.setDisplayName(P.p.color("&f" + P.p.languageReader.get("Brew_DistillUndefined"))); PotionColor.GREY.colorBrew(potionMeta, slotItem, canDistill()); } // Distill Lore if (currentRecipe != null) { - if (colorInBrewer != hasColorLore(potionMeta)) { - convertLore(potionMeta, colorInBrewer); + if (colorInBrewer != BrewLore.hasColorLore(potionMeta)) { + lore.convertLore(colorInBrewer); } } - String prefix = P.p.color("&7"); - if (colorInBrewer && currentRecipe != null) { - prefix = getQualityColor(ingredients.getDistillQuality(currentRecipe, distillRuns)); - } - updateDistillLore(prefix, potionMeta); + lore.updateDistillLore(colorInBrewer); + lore.write(); touch(); save(potionMeta); @@ -495,6 +514,7 @@ public class Brew { if (immutable) return; PotionMeta potionMeta = (PotionMeta) item.getItemMeta(); + BrewLore lore = new BrewLore(this, potionMeta); ageTime += time; // if younger than half a day, it shouldnt get aged form @@ -509,12 +529,12 @@ public class Brew { currentRecipe = recipe; quality = calcQuality(); - addOrReplaceEffects(potionMeta, getEffects(), quality); + lore.addOrReplaceEffects(getEffects(), quality); potionMeta.setDisplayName(P.p.color("&f" + recipe.getName(quality))); PotionColor.fromString(recipe.getColor()).colorBrew(potionMeta, item, canDistill()); } else { quality = 0; - removeEffects(potionMeta); + lore.removeEffects(); potionMeta.setDisplayName(P.p.color("&f" + P.p.languageReader.get("Brew_BadPotion"))); PotionColor.GREY.colorBrew(potionMeta, item, canDistill()); } @@ -522,22 +542,19 @@ public class Brew { // Lore if (currentRecipe != null) { - if (colorInBarrels != hasColorLore(potionMeta)) { - convertLore(potionMeta, colorInBarrels); + if (colorInBarrels != BrewLore.hasColorLore(potionMeta)) { + lore.convertLore(colorInBarrels); } } if (ageTime >= 1) { - String prefix = P.p.color("&7"); - if (colorInBarrels && currentRecipe != null) { - prefix = getQualityColor(ingredients.getAgeQuality(currentRecipe, ageTime)); - } - updateAgeLore(prefix, potionMeta); + lore.updateAgeLore(colorInBarrels); } if (ageTime > 0.5) { if (colorInBarrels && !unlabeled && currentRecipe != null) { - updateWoodLore(potionMeta); + lore.updateWoodLore(true); } } + lore.write(); touch(); save(potionMeta); item.setItemMeta(potionMeta); @@ -545,12 +562,12 @@ public class Brew { // Slowly shift the wood of the Brew to the new Type public void woodShift(float time, byte to) { - byte factor = 1; + float factor = 1; if (ageTime > 5) { factor = 2; } else if (ageTime > 10) { factor = 2; - factor += Math.round(ageTime / 10); + factor += (float) ageTime / 10F; } if (wood > to) { wood -= time / factor; @@ -565,179 +582,6 @@ public class Brew { } } - // Lore ----------- - - // Converts to/from qualitycolored Lore - public void convertLore(PotionMeta meta, Boolean toQuality) { - if (currentRecipe == null) { - return; - } - meta.setLore(null); - int quality; - String prefix = P.p.color("&7"); - String lore; - - // Ingredients - if (toQuality && !unlabeled) { - quality = ingredients.getIngredientQuality(currentRecipe); - prefix = getQualityColor(quality); - lore = P.p.languageReader.get("Brew_Ingredients"); - addOrReplaceLore(meta, prefix, lore); - } - - // Cooking - if (toQuality && !unlabeled) { - if (distillRuns > 0 == currentRecipe.needsDistilling()) { - quality = ingredients.getCookingQuality(currentRecipe, distillRuns > 0); - prefix = getQualityColor(quality) + ingredients.getCookedTime() + " " + P.p.languageReader.get("Brew_minute"); - if (ingredients.getCookedTime() > 1) { - prefix = prefix + P.p.languageReader.get("Brew_MinutePluralPostfix"); - } - lore = " " + P.p.languageReader.get("Brew_fermented"); - addOrReplaceLore(meta, prefix, lore); - } - } - - // Distilling - if (distillRuns > 0) { - if (toQuality) { - quality = ingredients.getDistillQuality(currentRecipe, distillRuns); - prefix = getQualityColor(quality); - } - updateDistillLore(prefix, meta); - } - - // Ageing - if (ageTime >= 1) { - if (toQuality) { - quality = ingredients.getAgeQuality(currentRecipe, ageTime); - prefix = getQualityColor(quality); - } - updateAgeLore(prefix, meta); - } - - // WoodType - if (toQuality && !unlabeled) { - if (ageTime > 0.5) { - updateWoodLore(meta); - } - } - } - - // sets the DistillLore. Prefix is the color to be used - public void updateDistillLore(String prefix, PotionMeta meta) { - if (!unlabeled) { - if (distillRuns > 1) { - prefix = prefix + distillRuns + P.p.languageReader.get("Brew_-times") + " "; - } - } - addOrReplaceLore(meta, prefix, P.p.languageReader.get("Brew_Distilled")); - } - - // sets the AgeLore. Prefix is the color to be used - public void updateAgeLore(String prefix, PotionMeta meta) { - if (!unlabeled) { - if (ageTime >= 1 && ageTime < 2) { - prefix = prefix + P.p.languageReader.get("Brew_OneYear") + " "; - } else if (ageTime < 201) { - prefix = prefix + (int) Math.floor(ageTime) + " " + P.p.languageReader.get("Brew_Years") + " "; - } else { - prefix = prefix + P.p.languageReader.get("Brew_HundredsOfYears") + " "; - } - } - addOrReplaceLore(meta, prefix, P.p.languageReader.get("Brew_BarrelRiped")); - } - - // updates/sets the color on WoodLore - public void updateWoodLore(PotionMeta meta) { - if (currentRecipe.getWood() > 0) { - int quality = ingredients.getWoodQuality(currentRecipe, wood); - addOrReplaceLore(meta, getQualityColor(quality), P.p.languageReader.get("Brew_Woodtype")); - } else if (meta.hasLore()) { - List existingLore = meta.getLore(); - int index = indexOfSubstring(existingLore, P.p.languageReader.get("Brew_Woodtype")); - if (index > -1) { - existingLore.remove(index); - meta.setLore(existingLore); - } - } - } - - // Adds or replaces a line of Lore. Searches for Substring lore and replaces it - public static void addOrReplaceLore(PotionMeta meta, String prefix, String lore) { - if (meta.hasLore()) { - List existingLore = meta.getLore(); - int index = indexOfSubstring(existingLore, lore); - if (index > -1) { - existingLore.set(index, prefix + lore); - } else { - existingLore.add(prefix + lore); - } - meta.setLore(existingLore); - return; - } - List newLore = new ArrayList<>(); - newLore.add(""); - newLore.add(prefix + lore); - meta.setLore(newLore); - } - - // Adds the Effect names to the Items description - public static void addOrReplaceEffects(PotionMeta meta, ArrayList effects, int quality) { - if (!P.use1_9 && effects != null) { - for (BEffect effect : effects) { - if (!effect.isHidden()) { - effect.writeInto(meta, quality); - } - } - } - } - - // Removes all effects - public static void removeEffects(PotionMeta meta) { - if (meta.hasCustomEffects()) { - for (PotionEffect effect : meta.getCustomEffects()) { - PotionEffectType type = effect.getType(); - //if (!type.equals(PotionEffectType.REGENERATION)) { - meta.removeCustomEffect(type); - //} - } - } - } - - // Returns the Index of a String from the list that contains this substring - public static int indexOfSubstring(List list, String substring) { - for (int index = 0; index < list.size(); index++) { - String string = list.get(index); - if (string.contains(substring)) { - return index; - } - } - return -1; - } - - // True if the PotionMeta has colored Lore - public static Boolean hasColorLore(PotionMeta meta) { - return meta.hasLore() && (meta.getLore().size() > 1 && !meta.getLore().get(1).startsWith(P.p.color("&7"))); - } - - // gets the Color that represents a quality in Lore - public static String getQualityColor(int quality) { - String color; - if (quality > 8) { - color = "&a"; - } else if (quality > 6) { - color = "&e"; - } else if (quality > 4) { - color = "&6"; - } else if (quality > 2) { - color = "&c"; - } else { - color = "&4"; - } - return P.p.color(color); - } - private static Brew load(ItemMeta meta) { LoreLoadStream loreStream; try { @@ -894,6 +738,20 @@ public class Brew { } } + public void convertLegacy(ItemStack item) { + removeLegacy(item); + PotionMeta potionMeta = ((PotionMeta) item.getItemMeta()); + if (hasRecipe()) { + BrewLore lore = new BrewLore(this, potionMeta); + lore.removeEffects(); + PotionColor.valueOf(currentRecipe.getColor()).colorBrew(potionMeta, item, canDistill()); + } else { + PotionColor.GREY.colorBrew(potionMeta, item, canDistill()); + } + save(potionMeta); + item.setItemMeta(potionMeta); + } + // Saves all data // Legacy method to save to data file @Deprecated diff --git a/src/com/dre/brewery/listeners/InventoryListener.java b/src/com/dre/brewery/listeners/InventoryListener.java index dace63a..43111d7 100644 --- a/src/com/dre/brewery/listeners/InventoryListener.java +++ b/src/com/dre/brewery/listeners/InventoryListener.java @@ -7,6 +7,7 @@ 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.BrewLore; import org.bukkit.Bukkit; import org.bukkit.Material; import org.bukkit.Sound; @@ -285,17 +286,15 @@ public class InventoryListener implements Listener { ItemStack item = event.getCurrentItem(); if (item.hasItemMeta()) { PotionMeta potion = ((PotionMeta) item.getItemMeta()); - Brew brew = Brew.get(potion); - if (brew != null) { - // convert potions from 1.8 to 1.9 for color and to remove effect descriptions - if (P.use1_9 && !potion.hasItemFlag(ItemFlag.HIDE_POTION_EFFECTS)) { - BRecipe recipe = brew.getCurrentRecipe(); - if (recipe != null) { - Brew.removeEffects(potion); - Brew.PotionColor.fromString(recipe.getColor()).colorBrew(potion, item, brew.canDistill()); - item.setItemMeta(potion); - } + // convert potions from 1.8 to 1.9 for color and to remove effect descriptions + if (P.use1_9 && !potion.hasItemFlag(ItemFlag.HIDE_POTION_EFFECTS)) { + Brew brew = Brew.get(potion); + if (brew != null) { + brew.convertLegacy(item); } + } + Brew brew = Brew.get(item); + if (brew != null) { P.p.log(brew.toString()); P.p.log(potion.getLore().get(0).replaceAll("§", "")); P.p.log("similar to beispiel? " + BRecipe.get("Beispiel").createBrew(10).isSimilar(brew)); @@ -386,8 +385,10 @@ public class InventoryListener implements Listener { PotionMeta meta = (PotionMeta) item.getItemMeta(); Brew brew = Brew.get(meta); if (brew != null) { - if (Brew.hasColorLore(meta)) { - brew.convertLore(meta, false); + if (BrewLore.hasColorLore(meta)) { + BrewLore lore = new BrewLore(brew, meta); + lore.convertLore(false); + lore.write(); item.setItemMeta(meta); } } diff --git a/src/com/dre/brewery/lore/BrewLore.java b/src/com/dre/brewery/lore/BrewLore.java new file mode 100644 index 0000000..5fe529c --- /dev/null +++ b/src/com/dre/brewery/lore/BrewLore.java @@ -0,0 +1,221 @@ +package com.dre.brewery.lore; + +import com.dre.brewery.*; +import org.bukkit.inventory.meta.PotionMeta; +import org.bukkit.potion.PotionEffect; +import org.bukkit.potion.PotionEffectType; + +import java.util.ArrayList; +import java.util.List; + +public class BrewLore { + + private static final String INGR = "§v"; + private static final String COOK = "§w"; + private static final String DISTILL = "§x"; + private static final String AGE = "§y"; + private static final String WOOD = "§z"; + + private Brew brew; + private PotionMeta meta; + private List lore; + + public BrewLore(Brew brew, PotionMeta meta) { + this.brew = brew; + this.meta = meta; + if (meta.hasLore()) { + lore = meta.getLore(); + } else { + lore = new ArrayList<>(); + } + } + + // Write the new lore into the Meta + public PotionMeta write() { + meta.setLore(lore); + return meta; + } + + public void updateIngredientLore(boolean qualityColor) { + if (qualityColor && brew.hasRecipe()) { + String prefix = getQualityColor(brew.getIngredients().getIngredientQuality(brew.getCurrentRecipe())); + addOrReplaceLore(INGR, prefix, P.p.languageReader.get("Brew_Ingredients")); + } else { + removeLore(INGR, P.p.languageReader.get("Brew_Ingredients")); + } + } + + public void updateCookLore(boolean qualityColor) { + if (qualityColor && brew.hasRecipe() && brew.getDistillRuns() > 0 == brew.getCurrentRecipe().needsDistilling()) { + BIngredients ingredients = brew.getIngredients(); + int quality = ingredients.getCookingQuality(brew.getCurrentRecipe(), brew.getDistillRuns() > 0); + String prefix = getQualityColor(quality) + ingredients.getCookedTime() + " " + P.p.languageReader.get("Brew_minute"); + if (ingredients.getCookedTime() > 1) { + prefix = prefix + P.p.languageReader.get("Brew_MinutePluralPostfix"); + } + addOrReplaceLore(COOK, prefix, " " + P.p.languageReader.get("Brew_fermented")); + } else { + removeLore(COOK, P.p.languageReader.get("Brew_fermented")); + } + } + + // sets the DistillLore. Prefix is the color to be used + public void updateDistillLore(boolean qualityColor) { + if (brew.getDistillRuns() <= 0) return; + String prefix; + byte distillRuns = brew.getDistillRuns(); + if (qualityColor && brew.hasRecipe()) { + prefix = getQualityColor(brew.getIngredients().getDistillQuality(brew.getCurrentRecipe(), distillRuns)); + } else { + prefix = "§7"; + } + if (!brew.isUnlabeled()) { + if (distillRuns > 1) { + prefix = prefix + distillRuns + P.p.languageReader.get("Brew_-times") + " "; + } + } + addOrReplaceLore(DISTILL, prefix, P.p.languageReader.get("Brew_Distilled")); + } + + // sets the AgeLore. Prefix is the color to be used + public void updateAgeLore(boolean qualityColor) { + String prefix; + float age = brew.getAgeTime(); + if (qualityColor && brew.hasRecipe()) { + prefix = getQualityColor(brew.getIngredients().getAgeQuality(brew.getCurrentRecipe(), age)); + } else { + prefix = "§7"; + } + if (!brew.isUnlabeled()) { + if (age >= 1 && age < 2) { + prefix = prefix + P.p.languageReader.get("Brew_OneYear") + " "; + } else if (age < 201) { + prefix = prefix + (int) Math.floor(age) + " " + P.p.languageReader.get("Brew_Years") + " "; + } else { + prefix = prefix + P.p.languageReader.get("Brew_HundredsOfYears") + " "; + } + } + addOrReplaceLore(AGE, prefix, P.p.languageReader.get("Brew_BarrelRiped")); + } + + // updates/sets the color on WoodLore + public void updateWoodLore(boolean qualityColor) { + if (qualityColor && brew.hasRecipe()) { + int quality = brew.getIngredients().getWoodQuality(brew.getCurrentRecipe(), brew.getWood()); + addOrReplaceLore(WOOD, getQualityColor(quality), P.p.languageReader.get("Brew_Woodtype")); + } else { + removeLore(WOOD, P.p.languageReader.get("Brew_Woodtype")); + } + } + + // Converts to/from qualitycolored Lore + public void convertLore(boolean toQuality) { + if (!brew.hasRecipe()) { + return; + } + + if (!brew.isUnlabeled()) { + // Ingredients + updateIngredientLore(toQuality); + + // Cooking + updateCookLore(toQuality); + } + + // Distilling + updateDistillLore(toQuality); + + // Ageing + if (brew.getAgeTime() >= 1) { + updateAgeLore(toQuality); + } + + // WoodType + if (!brew.isUnlabeled()) { + if (brew.getAgeTime() > 0.5) { + updateWoodLore(toQuality); + } + } + } + + // Adds or replaces a line of Lore. + // Searches for type and if not found for Substring lore and replaces it + public void addOrReplaceLore(String type, String prefix, String line) { + int index = BUtil.indexOfStart(lore, type); + if (index == -1) { + index = BUtil.indexOfSubstring(lore, line); + } + if (index > -1) { + lore.set(index, type + prefix + line); + } else { + lore.add(type + prefix + line); + } + } + + // Adds or replaces a line of Lore. + // Searches for type and if not found for Substring lore and replaces it + public void removeLore(String type, String line) { + int index = BUtil.indexOfStart(lore, type); + if (index == -1) { + index = BUtil.indexOfSubstring(lore, line); + } + if (index > -1) { + lore.remove(index); + } + } + + // Adds the Effect names to the Items description + public void addOrReplaceEffects(ArrayList effects, int quality) { + if (!P.use1_9 && effects != null) { + for (BEffect effect : effects) { + if (!effect.isHidden()) { + effect.writeInto(meta, quality); + } + } + } + } + + // Removes all effects + public void removeEffects() { + if (meta.hasCustomEffects()) { + for (PotionEffect effect : meta.getCustomEffects()) { + PotionEffectType type = effect.getType(); + //if (!type.equals(PotionEffectType.REGENERATION)) { + meta.removeCustomEffect(type); + //} + } + } + } + + // True if the PotionMeta has Lore in quality color + public static boolean hasColorLore(PotionMeta meta) { + if (!meta.hasLore()) return false; + List lore = meta.getLore(); + if (lore.size() < 2) { + return false; + } + if (BUtil.indexOfStart(lore, INGR) != -1) { + // Ingredient lore present, must be quality colored + return true; + } + return false; + //!meta.getLore().get(1).startsWith("§7"); + } + + // gets the Color that represents a quality in Lore + public static String getQualityColor(int quality) { + String color; + if (quality > 8) { + color = "&a"; + } else if (quality > 6) { + color = "&e"; + } else if (quality > 4) { + color = "&6"; + } else if (quality > 2) { + color = "&c"; + } else { + color = "&4"; + } + return P.p.color(color); + } +} From 519c4821d9d4a07b3db1b1be5e8df99bc1132afb Mon Sep 17 00:00:00 2001 From: Sn0wStorm Date: Sat, 9 Jul 2016 00:01:31 +0200 Subject: [PATCH 15/51] Started api and events --- src/com/dre/brewery/BCauldron.java | 33 ++- src/com/dre/brewery/BEffect.java | 14 +- src/com/dre/brewery/BIngredients.java | 6 + src/com/dre/brewery/BPlayer.java | 130 +++++++++-- src/com/dre/brewery/BUtil.java | 72 ++++++ src/com/dre/brewery/Barrel.java | 206 ++++++------------ src/com/dre/brewery/Brew.java | 7 + src/com/dre/brewery/P.java | 20 +- src/com/dre/brewery/api/BreweryApi.java | 150 +++++++++++++ .../brewery/api/events/IngedientAddEvent.java | 103 +++++++++ .../api/events/PlayerAlcEffectEvent.java | 54 +++++ .../api/events/PlayerDrinkEffectEvent.java | 52 +++++ .../brewery/api/events/PlayerPukeEvent.java | 60 +++++ .../brewery/api/events/PlayerPushEvent.java | 64 ++++++ .../api/events/barrel/BarrelAccessEvent.java | 54 +++++ .../api/events/barrel/BarrelCreateEvent.java | 44 ++++ .../api/events/barrel/BarrelDestroyEvent.java | 71 ++++++ .../api/events/barrel/BarrelEvent.java | 27 +++ .../api/events/barrel/BarrelRemoveEvent.java | 34 +++ .../api/events/brew/BrewDrinkEvent.java | 79 +++++++ .../brewery/api/events/brew/BrewEvent.java | 17 ++ .../api/events/brew/BrewModifyEvent.java | 53 +++++ .../integration/GriefPreventionBarrel.java | 12 +- .../integration/IntegrationListener.java | 122 +++++++++++ .../dre/brewery/integration/LWCBarrel.java | 40 ++-- .../dre/brewery/integration/WGBarrelNew.java | 14 +- .../dre/brewery/integration/WGBarrelOld.java | 1 - .../dre/brewery/listeners/BlockListener.java | 17 +- .../brewery/listeners/CommandListener.java | 11 + .../dre/brewery/listeners/EntityListener.java | 79 +++---- .../brewery/listeners/InventoryListener.java | 2 +- .../dre/brewery/listeners/PlayerListener.java | 16 +- 32 files changed, 1400 insertions(+), 264 deletions(-) create mode 100644 src/com/dre/brewery/api/BreweryApi.java create mode 100644 src/com/dre/brewery/api/events/IngedientAddEvent.java create mode 100644 src/com/dre/brewery/api/events/PlayerAlcEffectEvent.java create mode 100644 src/com/dre/brewery/api/events/PlayerDrinkEffectEvent.java create mode 100644 src/com/dre/brewery/api/events/PlayerPukeEvent.java create mode 100644 src/com/dre/brewery/api/events/PlayerPushEvent.java create mode 100644 src/com/dre/brewery/api/events/barrel/BarrelAccessEvent.java create mode 100644 src/com/dre/brewery/api/events/barrel/BarrelCreateEvent.java create mode 100644 src/com/dre/brewery/api/events/barrel/BarrelDestroyEvent.java create mode 100644 src/com/dre/brewery/api/events/barrel/BarrelEvent.java create mode 100644 src/com/dre/brewery/api/events/barrel/BarrelRemoveEvent.java create mode 100644 src/com/dre/brewery/api/events/brew/BrewDrinkEvent.java create mode 100644 src/com/dre/brewery/api/events/brew/BrewEvent.java create mode 100644 src/com/dre/brewery/api/events/brew/BrewModifyEvent.java create mode 100644 src/com/dre/brewery/integration/IntegrationListener.java diff --git a/src/com/dre/brewery/BCauldron.java b/src/com/dre/brewery/BCauldron.java index a5dc21f..11187fb 100644 --- a/src/com/dre/brewery/BCauldron.java +++ b/src/com/dre/brewery/BCauldron.java @@ -4,6 +4,7 @@ import java.util.concurrent.CopyOnWriteArrayList; import org.bukkit.block.data.BlockData; import org.bukkit.block.data.Levelled; +import com.dre.brewery.api.events.IngedientAddEvent; import org.bukkit.entity.Player; import org.bukkit.block.Block; import org.bukkit.block.BlockFace; @@ -12,16 +13,15 @@ import org.bukkit.Effect; import org.bukkit.configuration.ConfigurationSection; public class BCauldron { - public static CopyOnWriteArrayList bcauldrons = new CopyOnWriteArrayList<>(); + public static CopyOnWriteArrayList bcauldrons = new CopyOnWriteArrayList<>(); // TODO find best Collection private BIngredients ingredients = new BIngredients(); - private Block block; + private final Block block; private int state = 1; private boolean someRemoved = false; - public BCauldron(Block block, ItemStack ingredient) { + public BCauldron(Block block) { this.block = block; - add(ingredient); bcauldrons.add(this); } @@ -47,7 +47,8 @@ public class BCauldron { // add an ingredient to the cauldron public void add(ItemStack ingredient) { - if (someRemoved) { + if (ingredient == null || ingredient.getType() == Material.AIR) return; + if (someRemoved) { // TODO no need to clone ingredients = ingredients.clone(); someRemoved = false; } @@ -70,16 +71,22 @@ public class BCauldron { } // get cauldron from block and add given ingredient - public static boolean ingredientAdd(Block block, ItemStack ingredient) { + // Calls the IngredientAddEvent and may be cancelled or changed + public static boolean ingredientAdd(Block block, ItemStack ingredient, Player player) { // if not empty if (LegacyUtil.getFillLevel(block) != 0) { BCauldron bcauldron = get(block); - if (bcauldron != null) { - bcauldron.add(ingredient); - return true; + if (bcauldron == null) { + bcauldron = new BCauldron(block); + } + + IngedientAddEvent event = new IngedientAddEvent(player, block, bcauldron, ingredient); + P.p.getServer().getPluginManager().callEvent(event); + if (!event.isCancelled()) { + bcauldron.add(event.getIngredient()); + return event.shouldTakeItem(); } else { - new BCauldron(block, ingredient); - return true; + return false; } } return false; @@ -161,13 +168,15 @@ public class BCauldron { } // reset to normal cauldron - public static void remove(Block block) { + public static boolean remove(Block block) { if (LegacyUtil.getFillLevel(block) != 0) { BCauldron bcauldron = get(block); if (bcauldron != null) { bcauldrons.remove(bcauldron); + return true; } } + return false; } // unloads cauldrons that are in a unloading world diff --git a/src/com/dre/brewery/BEffect.java b/src/com/dre/brewery/BEffect.java index 7339f49..b439068 100644 --- a/src/com/dre/brewery/BEffect.java +++ b/src/com/dre/brewery/BEffect.java @@ -2,6 +2,7 @@ package com.dre.brewery; import org.bukkit.entity.Player; import org.bukkit.inventory.meta.PotionMeta; +import org.bukkit.potion.PotionEffect; import org.bukkit.potion.PotionEffectType; public class BEffect { @@ -81,19 +82,26 @@ public class BEffect { } } - public void apply(int quality, Player player) { + public PotionEffect generateEffect(int quality) { int duration = calcDuration(quality); int lvl = calcLvl(quality); if (lvl < 1 || (duration < 1 && !type.isInstant())) { - return; + return null; } duration *= 20; if (!P.use1_14) { duration /= type.getDurationModifier(); } - Util.reapplyPotionEffect(player, type.createEffect(duration, lvl - 1), true); + return type.createEffect(duration, lvl - 1); + } + + public void apply(int quality, Player player) { + PotionEffect effect = generateEffect(quality); + if (effect != null) { + Util.reapplyPotionEffect(player, effect, true); + } } public int calcDuration(float quality) { diff --git a/src/com/dre/brewery/BIngredients.java b/src/com/dre/brewery/BIngredients.java index 2631374..0132f50 100644 --- a/src/com/dre/brewery/BIngredients.java +++ b/src/com/dre/brewery/BIngredients.java @@ -1,5 +1,6 @@ package com.dre.brewery; +import com.dre.brewery.api.events.brew.BrewModifyEvent; import com.dre.brewery.lore.BrewLore; import org.bukkit.Material; import org.bukkit.configuration.ConfigurationSection; @@ -120,6 +121,11 @@ public class BIngredients { cookedName = P.p.languageReader.get("Brew_Undefined"); Brew.PotionColor.CYAN.colorBrew(potionMeta, potion, true); } + BrewModifyEvent modifyEvent = new BrewModifyEvent(brew, BrewModifyEvent.Type.FILL); + P.p.getServer().getPluginManager().callEvent(modifyEvent); + if (modifyEvent.isCancelled()) { + return null; + } potionMeta.setDisplayName(P.p.color("&f" + cookedName)); if (!P.use1_14) { diff --git a/src/com/dre/brewery/BPlayer.java b/src/com/dre/brewery/BPlayer.java index 14111b4..2f71e1a 100644 --- a/src/com/dre/brewery/BPlayer.java +++ b/src/com/dre/brewery/BPlayer.java @@ -1,5 +1,10 @@ package com.dre.brewery; +import com.dre.brewery.api.events.PlayerAlcEffectEvent; +import com.dre.brewery.api.events.PlayerDrinkEffectEvent; +import com.dre.brewery.api.events.PlayerPukeEvent; +import com.dre.brewery.api.events.PlayerPushEvent; +import com.dre.brewery.api.events.brew.BrewDrinkEvent; import org.apache.commons.lang.mutable.MutableInt; import org.bukkit.Location; import org.bukkit.Material; @@ -10,13 +15,20 @@ import org.bukkit.entity.Item; import org.bukkit.entity.Player; import org.bukkit.event.player.PlayerMoveEvent; import org.bukkit.inventory.ItemStack; +import org.bukkit.potion.PotionEffect; import org.bukkit.potion.PotionEffectType; import org.bukkit.util.Vector; import java.lang.reflect.Field; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; -import java.util.*; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.Random; +import java.util.UUID; public class BPlayer { private static Map players = new HashMap<>();// Players name/uuid and BPlayer @@ -124,9 +136,10 @@ public class BPlayer { } public void remove() { - for (Map.Entry entry : players.entrySet()) { + for (Iterator> iterator = players.entrySet().iterator(); iterator.hasNext(); ) { + Map.Entry entry = iterator.next(); if (entry.getValue() == this) { - players.remove(entry.getKey()); + iterator.remove(); return; } } @@ -137,32 +150,46 @@ public class BPlayer { } // Drink a brew and apply effects, etc. - public static void drink(Brew brew, Player player) { - int brewAlc = brew.calcAlcohol(); - if (brewAlc == 0) { - //no alcohol so we dont need to add a BPlayer - addBrewEffects(brew, player); - return; - } + public static boolean drink(Brew brew, Player player) { BPlayer bPlayer = get(player); if (bPlayer == null) { bPlayer = addPlayer(player); } + BrewDrinkEvent drinkEvent = new BrewDrinkEvent(brew, player, bPlayer); + P.p.getServer().getPluginManager().callEvent(drinkEvent); + if (drinkEvent.isCancelled()) { + if (bPlayer.drunkeness <= 0) { + bPlayer.remove(); + } + return false; + } + + int brewAlc = drinkEvent.getAddedAlcohol(); + int quality = drinkEvent.getQuality(); + List effects = getBrewEffects(brew.getEffects(), quality); + + if (brewAlc < 1) { + //no alcohol so we dont need to add a BPlayer + applyDrinkEffects(effects, player); + if (bPlayer.drunkeness <= 0) { + bPlayer.remove(); + } + return true; + } + + effects.addAll(getQualityEffects(drinkEvent.getQuality(), brewAlc)); bPlayer.drunkeness += brewAlc; - if (brew.getQuality() > 0) { - bPlayer.quality += brew.getQuality() * brewAlc; + if (quality > 0) { + bPlayer.quality += quality * brewAlc; } else { bPlayer.quality += brewAlc; } + applyDrinkEffects(effects, player); - if (bPlayer.drunkeness <= 100) { - - addBrewEffects(brew, player); - addQualityEffects(brew.getQuality(), brewAlc, player); - - } else { + if (bPlayer.drunkeness > 100) { bPlayer.drinkCap(player); } + return true; } // Player has drunken too much @@ -244,6 +271,13 @@ public class BPlayer { push.setX(Math.random() - 0.5); push.setZ(Math.random() - 0.5); } + PlayerPushEvent pushEvent = new PlayerPushEvent(player, push, this); + P.p.getServer().getPluginManager().callEvent(pushEvent); + push = pushEvent.getPush(); + if (pushEvent.isCancelled() || push.lengthSquared() <= 0) { + time = -10; + return; + } player.setVelocity(push); } else if (time < 0 && time > -10) { // push him some more in the same direction @@ -382,6 +416,12 @@ public class BPlayer { return; } + PlayerPukeEvent event = new PlayerPukeEvent(player, count); + P.p.getServer().getPluginManager().callEvent(event); + if (event.isCancelled() || event.getCount() < 1) { + return; + } + if (pTasks.isEmpty()) { taskId = P.p.getServer().getScheduler().scheduleSyncRepeatingTask(P.p, new Runnable() { public void run() { @@ -389,7 +429,7 @@ public class BPlayer { } }, 1L, 1L); } - pTasks.put(player, new MutableInt(count)); + pTasks.put(player, new MutableInt(event.getCount())); } public static void pukeTask() { @@ -466,6 +506,18 @@ public class BPlayer { // #### Effects #### + public static void applyDrinkEffects(List effects, Player player) { + PlayerDrinkEffectEvent event = new PlayerDrinkEffectEvent(player, effects); + P.p.getServer().getPluginManager().callEvent(event); + effects = event.getEffects(); + if (event.isCancelled() || effects == null) { + return; + } + for (PotionEffect effect : effects) { + Util.reapplyPotionEffect(player, effect, true); + } + } + public void drunkEffects(Player player) { int duration = 10 - getQuality(); duration += drunkeness / 2; @@ -478,10 +530,22 @@ public class BPlayer { if (!P.use1_14) { duration *= 4; } - PotionEffectType.CONFUSION.createEffect(duration, 0).apply(player); + List l = new ArrayList<>(1); + l.add(PotionEffectType.CONFUSION.createEffect(duration, 0)); + + PlayerAlcEffectEvent event = new PlayerAlcEffectEvent(player, l); + P.p.getServer().getPluginManager().callEvent(event); + l = event.getEffects(); + if (event.isCancelled() || l == null) { + return; + } + for (PotionEffect effect : l) { + effect.apply(player); + } } - public static void addQualityEffects(int quality, int brewAlc, Player player) { + public static List getQualityEffects(int quality, int brewAlc) { + List out = new ArrayList<>(2); int duration = 7 - quality; if (quality == 0) { duration *= 125; @@ -497,7 +561,7 @@ public class BPlayer { duration *= 4; } if (duration > 0) { - Util.reapplyPotionEffect(player, PotionEffectType.POISON.createEffect(duration, 0), true); + out.add(PotionEffectType.POISON.createEffect(duration, 0)); } if (brewAlc > 10) { @@ -511,8 +575,28 @@ public class BPlayer { if (!P.use1_14) { duration *= 4; } - Util.reapplyPotionEffect(player, PotionEffectType.BLINDNESS.createEffect(duration, 0), true); + out.add(PotionEffectType.BLINDNESS.createEffect(duration, 0)); } + return out; + } + + public static void addQualityEffects(int quality, int brewAlc, Player player) { + for (PotionEffect effect : getQualityEffects(quality, brewAlc)) { + Util.reapplyPotionEffect(player, effect, true); + } + } + + public static List getBrewEffects(List effects, int quality) { + List out = new ArrayList<>(); + if (effects != null) { + for (BEffect effect : effects) { + PotionEffect e = effect.generateEffect(quality); + if (e != null) { + out.add(e); + } + } + } + return out; } public static void addBrewEffects(Brew brew, Player player) { diff --git a/src/com/dre/brewery/BUtil.java b/src/com/dre/brewery/BUtil.java index 2864419..bbfcd6a 100644 --- a/src/com/dre/brewery/BUtil.java +++ b/src/com/dre/brewery/BUtil.java @@ -1,5 +1,9 @@ package com.dre.brewery; +import com.dre.brewery.api.events.barrel.BarrelDestroyEvent; +import org.bukkit.block.Block; +import org.bukkit.entity.Player; + import java.util.List; public class BUtil { @@ -25,4 +29,72 @@ public class BUtil { } return -1; } + + /* + ---- Barrel ---- + */ + + // Returns true if the Block can be destroyed by the Player or something else (null) + public static boolean blockDestroy(Block block, Player player, BarrelDestroyEvent.Reason reason) { + switch (block.getType()) { + case CAULDRON: + // will only remove when existing + BCauldron.remove(block); + return true; + case FENCE: + case NETHER_FENCE: + case ACACIA_FENCE: + case BIRCH_FENCE: + case DARK_OAK_FENCE: + case IRON_FENCE: + case JUNGLE_FENCE: + case SPRUCE_FENCE: + // remove barrel and throw potions on the ground + Barrel barrel = Barrel.getBySpigot(block); + if (barrel != null) { + if (barrel.hasPermsDestroy(player, block, reason)) { + barrel.remove(null, player); + return true; + } else { + return false; + } + } + return true; + case SIGN_POST: + case WALL_SIGN: + // remove small Barrels + Barrel barrel2 = Barrel.getBySpigot(block); + if (barrel2 != null) { + if (!barrel2.isLarge()) { + if (barrel2.hasPermsDestroy(player, block, reason)) { + barrel2.remove(null, player); + return true; + } else { + return false; + } + } else { + barrel2.destroySign(); + } + } + return true; + case WOOD: + case WOOD_STAIRS: + case BIRCH_WOOD_STAIRS: + case JUNGLE_WOOD_STAIRS: + case SPRUCE_WOOD_STAIRS: + case ACACIA_STAIRS: + case DARK_OAK_STAIRS: + Barrel barrel3 = Barrel.getByWood(block); + if (barrel3 != null) { + if (barrel3.hasPermsDestroy(player, block, reason)) { + barrel3.remove(block, player); + } else { + return false; + } + } + default: + break; + } + return true; + } } diff --git a/src/com/dre/brewery/Barrel.java b/src/com/dre/brewery/Barrel.java index 7cbd467..49418cc 100644 --- a/src/com/dre/brewery/Barrel.java +++ b/src/com/dre/brewery/Barrel.java @@ -1,12 +1,17 @@ package com.dre.brewery; +import com.dre.brewery.api.events.barrel.BarrelAccessEvent; +import com.dre.brewery.api.events.barrel.BarrelCreateEvent; +import com.dre.brewery.api.events.barrel.BarrelDestroyEvent; +import com.dre.brewery.api.events.barrel.BarrelRemoveEvent; import com.dre.brewery.integration.CitadelBarrel; import com.dre.brewery.integration.GriefPreventionBarrel; import com.dre.brewery.integration.LWCBarrel; import com.dre.brewery.integration.LogBlockBarrel; -import org.apache.commons.lang.ArrayUtils; import com.dre.brewery.lore.BrewLore; +import org.apache.commons.lang.ArrayUtils; import org.bukkit.Material; +import org.bukkit.TreeSpecies; import org.bukkit.block.Block; import org.bukkit.configuration.ConfigurationSection; import org.bukkit.entity.HumanEntity; @@ -16,6 +21,10 @@ import org.bukkit.inventory.Inventory; import org.bukkit.inventory.InventoryHolder; import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.meta.PotionMeta; +import org.bukkit.material.MaterialData; +import org.bukkit.material.Stairs; +import org.bukkit.material.Tree; +import org.bukkit.material.Wood; import org.bukkit.plugin.Plugin; import org.bukkit.scheduler.BukkitRunnable; @@ -26,7 +35,7 @@ import java.util.concurrent.CopyOnWriteArrayList; public class Barrel implements InventoryHolder { - public static CopyOnWriteArrayList barrels = new CopyOnWriteArrayList<>(); + public static CopyOnWriteArrayList barrels = new CopyOnWriteArrayList<>(); // TODO find best collection private static int check = 0; private Block spigot; @@ -47,9 +56,9 @@ public class Barrel implements InventoryHolder { this.spigot = spigot; this.signoffset = sign; if (isLarge()) { - this.inventory = org.bukkit.Bukkit.createInventory(this, 27, P.p.languageReader.get("Etc_Barrel")); + this.inventory = P.p.getServer().createInventory(this, 27, P.p.languageReader.get("Etc_Barrel")); } else { - this.inventory = org.bukkit.Bukkit.createInventory(this, 9, P.p.languageReader.get("Etc_Barrel")); + this.inventory = P.p.getServer().createInventory(this, 9, P.p.languageReader.get("Etc_Barrel")); } if (items != null) { for (String slot : items.keySet()) { @@ -119,49 +128,13 @@ public class Barrel implements InventoryHolder { } } - if (P.p.useWG) { - Plugin plugin = P.p.getServer().getPluginManager().getPlugin("WorldGuard"); - if (plugin != null) { - try { - if (!P.p.wg.checkAccess(player, spigot, plugin)) { - return false; - } - } catch (Throwable e) { - P.p.errorLog("Failed to Check WorldGuard for Barrel Open Permissions!"); - P.p.errorLog("Brewery was tested with version 5.8, 6.1 to 7.0 of WorldGuard!"); - P.p.errorLog("Disable the WorldGuard support in the config and do /brew reload"); - e.printStackTrace(); - if (player.hasPermission("brewery.admin") || player.hasPermission("brewery.mod")) { - P.p.msg(player, "&cWorldGuard check Error, Brewery was tested with up to v7.0 of Worldguard"); - P.p.msg(player, "&cSet &7useWorldGuard: false &cin the config and /brew reload"); - } else { - P.p.msg(player, "&cError opening Barrel, please report to an Admin!"); - } - return false; - } - } - } - - if (P.p.useGP) { - if (P.p.getServer().getPluginManager().isPluginEnabled("GriefPrevention")) { - try { - if (!GriefPreventionBarrel.checkAccess(player, spigot)) { - return false; - } - } catch (Throwable e) { - P.p.errorLog("Failed to Check GriefPrevention for Barrel Open Permissions!"); - P.p.errorLog("Brewery was tested with GriefPrevention v14.5 - v16.9"); - P.p.errorLog("Disable the GriefPrevention support in the config and do /brew reload"); - e.printStackTrace(); - if (player.hasPermission("brewery.admin") || player.hasPermission("brewery.mod")) { - P.p.msg(player, "&cGriefPrevention check Error, Brewery was tested with up to v16.9 of GriefPrevention"); - P.p.msg(player, "&cSet &7useGriefPrevention: false &cin the config and /brew reload"); - } else { - P.p.msg(player, "&cError opening Barrel, please report to an Admin!"); - } - return false; - } - } + // Call event + BarrelAccessEvent accessEvent = new BarrelAccessEvent(this, player, event.getClickedBlock()); + // Listened to by WGBarrelNew, WGBarrelOld, GriefPreventionBarrel (IntegrationListener) + P.p.getServer().getPluginManager().callEvent(accessEvent); + if (accessEvent.isCancelled()) { + P.p.msg(player, P.p.languageReader.get("Error_NoBarrelAccess")); + return false; } if (event != null && P.p.useLWC) { @@ -169,7 +142,7 @@ public class Barrel implements InventoryHolder { if (plugin != null) { // If the Clicked Block was the Sign, LWC already knows and we dont need to do anything here - if (!LegacyUtil.isSign(event.getClickedBlock().getType())) { + if (!isSign(event.getClickedBlock())) { Block sign = getSignOfSpigot(); // If the Barrel does not have a Sign, it cannot be locked if (!sign.equals(event.getClickedBlock())) { @@ -184,7 +157,7 @@ public class Barrel implements InventoryHolder { P.p.msg(player, "&cLWC check Error, Brewery was tested with up to v4.5.0 of LWC"); P.p.msg(player, "&cSet &7useLWC: false &cin the config and /brew reload"); } else { - P.p.msg(player, "&cError opening Barrel, please report to an Admin!"); + P.p.msg(player, "&cError breaking Barrel, please report to an Admin!"); } return false; } @@ -193,80 +166,24 @@ public class Barrel implements InventoryHolder { } } - if (event != null && P.p.useCitadel) { - Plugin plugin = P.p.getServer().getPluginManager().getPlugin("Citadel"); - if (plugin != null) { - try { - if (LegacyUtil.isSign(event.getClickedBlock().getType())) { - return CitadelBarrel.checkAccess(player, getSignOfSpigot()); - } else { - return CitadelBarrel.checkAccess(player, spigot); - } - } catch (Throwable e) { - P.p.errorLog("Failed to Check Citadel for Container Access Permissions!"); - P.p.errorLog("Brewery was tested with version 3.9.1 of Citadel!"); - P.p.errorLog("Disable Citadel support in the config and do /brew reload"); - e.printStackTrace(); - if (player.hasPermission("brewery.admin") || player.hasPermission("brewery.mod")) { - P.p.msg(player, "&cCitadel check Error, Brewery was tested with up to v3.9.1 of Citadel"); - } else { - P.p.msg(player, "&cError opening Barrel, please report to an Admin!"); - } - return false; - } - } - } - return true; } - // Ask for permission to destroy barrel, remove protection if has - public boolean hasPermsDestroy(Player player) { - if (player == null) { - willDestroy(); - return true; - } - if (P.p.useLWC) { - try { - return LWCBarrel.checkDestroy(player, this); - } catch (Throwable e) { - P.p.errorLog("Failed to Check LWC for Barrel Break Permissions!"); - P.p.errorLog("Brewery was tested with version 4.5.0 of LWC!"); - P.p.errorLog("Disable the LWC support in the config and do /brew reload"); - e.printStackTrace(); - if (player.hasPermission("brewery.admin") || player.hasPermission("brewery.mod")) { - P.p.msg(player, "&cLWC check Error, Brewery was tested with up to v4.5.0 of LWC"); - P.p.msg(player, "&cSet &7useLWC: false &cin the config and /brew reload"); - } else { - P.p.msg(player, "&cError breaking Barrel, please report to an Admin!"); - } - return false; - } - } - - return true; - } - - // If something other than the Player is destroying the barrel, inform protection plugins - public void willDestroy() { - if (P.p.useLWC) { - try { - LWCBarrel.remove(this); - } catch (Throwable e) { - P.p.errorLog("Failed to Remove LWC Lock from Barrel!"); - P.p.errorLog("Brewery was tested with version 4.5.0 of LWC!"); - e.printStackTrace(); - } - } + // Ask for permission to destroy barrel + public boolean hasPermsDestroy(Player player, Block block, BarrelDestroyEvent.Reason reason) { + // Listened to by LWCBarrel (IntegrationListener) + BarrelDestroyEvent destroyEvent = new BarrelDestroyEvent(this, block, reason, player); + P.p.getServer().getPluginManager().callEvent(destroyEvent); + return !destroyEvent.isCancelled(); } // player opens the barrel public void open(Player player) { if (inventory == null) { if (isLarge()) { - inventory = org.bukkit.Bukkit.createInventory(this, 27, P.p.languageReader.get("Etc_Barrel")); + inventory = P.p.getServer().createInventory(this, 27, P.p.languageReader.get("Etc_Barrel")); } else { - inventory = org.bukkit.Bukkit.createInventory(this, 9, P.p.languageReader.get("Etc_Barrel")); + inventory = P.p.getServer().createInventory(this, 9, P.p.languageReader.get("Etc_Barrel")); } } else { if (time > 0) { @@ -315,6 +232,10 @@ public class Barrel implements InventoryHolder { return spigot; } + public float getTime() { + return time; + } + // Returns true if this Block is part of this Barrel public boolean hasBlock(Block block) { if (block != null) { @@ -457,8 +378,12 @@ public class Barrel implements InventoryHolder { return false; } } - barrels.add(barrel); - return true; + BarrelCreateEvent createEvent = new BarrelCreateEvent(barrel, player); + P.p.getServer().getPluginManager().callEvent(createEvent); + if (!createEvent.isCancelled()) { + barrels.add(barrel); + return true; + } } } else { if (barrel.signoffset == 0 && signoffset != 0) { @@ -471,6 +396,10 @@ public class Barrel implements InventoryHolder { // removes a barrel, throwing included potions to the ground public void remove(Block broken, Player breaker) { + BarrelRemoveEvent event = new BarrelRemoveEvent(this); + // Listened to by LWCBarrel (IntegrationListener) + P.p.getServer().getPluginManager().callEvent(event); + if (inventory != null) { List viewers = new ArrayList(inventory.getViewers()); // Copy List to fix ConcModExc @@ -481,32 +410,34 @@ public class Barrel implements InventoryHolder { inventory.clear(); if (P.p.useLB && breaker != null) { try { - LogBlockBarrel.breakBarrel(breaker, items, spigot.getLocation()); + LogBlockBarrel.breakBarrel(breaker.getName(), items, spigot.getLocation()); } catch (Throwable e) { P.p.errorLog("Failed to Log Barrel-break to LogBlock!"); P.p.errorLog("Brewery was tested with version 1.94 of LogBlock!"); e.printStackTrace(); } } - for (ItemStack item : items) { - if (item != null) { - Brew brew = Brew.get(item); - if (brew != null) { - // Brew before throwing - brew.age(item, time, getWood()); - PotionMeta meta = (PotionMeta) item.getItemMeta(); - if (BrewLore.hasColorLore(meta)) { - BrewLore lore = new BrewLore(brew, meta); - lore.convertLore(false); - lore.write(); - item.setItemMeta(meta); + if (event.shouldItemsDrop()) { + for (ItemStack item : items) { + if (item != null) { + Brew brew = Brew.get(item); + if (brew != null) { + // Brew before throwing + brew.age(item, time, getWood()); + PotionMeta meta = (PotionMeta) item.getItemMeta(); + if (BrewLore.hasColorLore(meta)) { + BrewLore lore = new BrewLore(brew, meta); + lore.convertLore(false); + lore.write(); + item.setItemMeta(meta); + } + } + // "broken" is the block that destroyed, throw them there! + if (broken != null) { + broken.getWorld().dropItem(broken.getLocation(), item); + } else { + spigot.getWorld().dropItem(spigot.getLocation(), item); } - } - // "broken" is the block that destroyed, throw them there! - if (broken != null) { - broken.getWorld().dropItem(broken.getLocation(), item); - } else { - spigot.getWorld().dropItem(spigot.getLocation(), item); } } } @@ -638,6 +569,11 @@ public class Barrel implements InventoryHolder { // is this a Large barrel? public boolean isLarge() { + return !isSmall(); + } + + // is this a Small barrel? + public boolean isSmall() { return !LegacyUtil.isSign(spigot.getType()); } @@ -889,7 +825,7 @@ public class Barrel implements InventoryHolder { P.p.debugLog("Barrel at " + broken.getWorld().getName() + "/" + broken.getX() + "/" + broken.getY() + "/" + broken.getZ() + " has been destroyed unexpectedly, contents will drop"); // remove the barrel if it was destroyed - barrel.willDestroy(); + barrel.willDestroy(); // TODO Check if still needed barrel.remove(broken, null); } else { // Dont check this barrel again, its enough to check it once after every restart diff --git a/src/com/dre/brewery/Brew.java b/src/com/dre/brewery/Brew.java index 1ff158d..d35bea2 100644 --- a/src/com/dre/brewery/Brew.java +++ b/src/com/dre/brewery/Brew.java @@ -1,6 +1,7 @@ package com.dre.brewery; import org.bukkit.Color; +import com.dre.brewery.api.events.brew.BrewModifyEvent; import com.dre.brewery.lore.*; import org.bukkit.Material; import org.bukkit.configuration.ConfigurationSection; @@ -458,6 +459,9 @@ public class Brew { // distill custom potion in given slot public void distillSlot(ItemStack slotItem, PotionMeta potionMeta) { if (immutable) return; + BrewModifyEvent modifyEvent = new BrewModifyEvent(this, BrewModifyEvent.Type.DISTILL); + P.p.getServer().getPluginManager().callEvent(modifyEvent); + if (modifyEvent.isCancelled()) return; distillRuns += 1; BrewLore lore = new BrewLore(this, potionMeta); @@ -512,6 +516,9 @@ public class Brew { public void age(ItemStack item, float time, byte woodType) { if (immutable) return; + BrewModifyEvent modifyEvent = new BrewModifyEvent(this, BrewModifyEvent.Type.AGE); + P.p.getServer().getPluginManager().callEvent(modifyEvent); + if (modifyEvent.isCancelled()) return; PotionMeta potionMeta = (PotionMeta) item.getItemMeta(); BrewLore lore = new BrewLore(this, potionMeta); diff --git a/src/com/dre/brewery/P.java b/src/com/dre/brewery/P.java index 6da5872..54fc7e6 100644 --- a/src/com/dre/brewery/P.java +++ b/src/com/dre/brewery/P.java @@ -5,12 +5,19 @@ import com.dre.brewery.filedata.DataSave; import com.dre.brewery.filedata.DataUpdater; import com.dre.brewery.filedata.LanguageReader; import com.dre.brewery.filedata.UpdateChecker; +import com.dre.brewery.integration.IntegrationListener; import com.dre.brewery.integration.LogBlockBarrel; import com.dre.brewery.integration.WGBarrel; 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.listeners.BlockListener; +import com.dre.brewery.listeners.CauldronListener; +import com.dre.brewery.listeners.CommandListener; +import com.dre.brewery.listeners.EntityListener; +import com.dre.brewery.listeners.InventoryListener; +import com.dre.brewery.listeners.PlayerListener; +import com.dre.brewery.listeners.WorldListener; import org.apache.commons.lang.math.NumberUtils; import org.bstats.bukkit.Metrics; import org.bukkit.Bukkit; @@ -31,11 +38,14 @@ import org.bukkit.plugin.Plugin; import org.bukkit.plugin.java.JavaPlugin; import java.io.File; +import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; +import java.io.OutputStream; import java.util.ArrayList; import java.util.HashMap; import java.util.List; +import java.util.ListIterator; import java.util.Map; import java.util.UUID; @@ -65,6 +75,7 @@ public class P extends JavaPlugin { public EntityListener entityListener; public InventoryListener inventoryListener; public WorldListener worldListener; + public IntegrationListener integrationListener; // Language public String language; @@ -413,6 +424,7 @@ public class P extends JavaPlugin { entityListener = new EntityListener(); inventoryListener = new InventoryListener(); worldListener = new WorldListener(); + integrationListener = new IntegrationListener(); getCommand("Brewery").setExecutor(new CommandListener()); getCommand("Brewery").setTabCompleter(new TabListener()); @@ -421,6 +433,7 @@ public class P extends JavaPlugin { p.getServer().getPluginManager().registerEvents(entityListener, p); p.getServer().getPluginManager().registerEvents(inventoryListener, p); p.getServer().getPluginManager().registerEvents(worldListener, p); + p.getServer().getPluginManager().registerEvents(integrationListener, p); if (use1_9) { p.getServer().getPluginManager().registerEvents(new CauldronListener(), p); } @@ -579,6 +592,11 @@ public class P extends JavaPlugin { // Third-Party useWG = config.getBoolean("useWorldGuard", true) && getServer().getPluginManager().isPluginEnabled("WorldGuard"); + useLWC = config.getBoolean("useLWC", true) && getServer().getPluginManager().isPluginEnabled("LWC"); + useGP = config.getBoolean("useGriefPrevention", true) && getServer().getPluginManager().isPluginEnabled("GriefPrevention"); + useLB = config.getBoolean("useLogBlock", false) && getServer().getPluginManager().isPluginEnabled("LogBlock"); + hasVault = getServer().getPluginManager().isPluginEnabled("Vault"); + if (useWG) { Plugin plugin = Bukkit.getPluginManager().getPlugin("WorldEdit"); if (plugin != null) { diff --git a/src/com/dre/brewery/api/BreweryApi.java b/src/com/dre/brewery/api/BreweryApi.java new file mode 100644 index 0000000..ca75e72 --- /dev/null +++ b/src/com/dre/brewery/api/BreweryApi.java @@ -0,0 +1,150 @@ +package com.dre.brewery.api; + +import com.dre.brewery.BCauldron; +import com.dre.brewery.BRecipe; +import com.dre.brewery.Barrel; +import com.dre.brewery.Brew; +import org.apache.commons.lang.NotImplementedException; +import org.bukkit.block.Block; +import org.bukkit.entity.Player; +import org.bukkit.inventory.Inventory; +import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.meta.ItemMeta; + +public class BreweryApi { + +/* + * Convenience methods to get common objects or do common things + */ + + /* + * Remove any data that this Plugin may associate with the given Block + * Currently Cauldrons and Barrels (Cauldron, Wood, Woodstairs, Fence, Sign) + * Does not remove any actual Blocks + * Returns true if anything was removed + */ + public static boolean removeAny(Block block) { + if (removeCauldron(block)) return true; + return removeBarrel(block); + } + + /* + * Like removeAny() but removes data as if the given player broke the Block + * Currently only makes a difference for Logging + */ + public static boolean removeAnyByPlayer(Block block, Player player) { + if (removeCauldron(block)) return true; + return removeBarrelByPlayer(block, player); + } + + + // # # # # # Brew # # # # # + + /* + * Get a Brew from an ItemStack + * Reads the Brew data from the saved data on the item + * Checks if item is actually a Brew + * Returns null if item is not a Brew + */ + public static Brew getBrew(ItemStack item) { + return Brew.get(item); + } + + /* + * Get a Brew from an ItemMeta + * Reads the Brew data from the saved data in the Meta + * Checks if meta has a Brew saved + * Returns null if meta is not a Brew + */ + public static Brew getBrew(ItemMeta meta) { + return Brew.get(meta); + } + + + // # # # # # Barrel # # # # # + + /* + * Get a Barrel from a Block + * May be any Wood, Fence, Sign that is part of a Barrel + * Returns null if block is not part of a Barrel + */ + public static Barrel getBarrel(Block block) { + return Barrel.get(block); + } + + /* + * Get the Inventory of a Block part of a Barrel + * May be any Wood, Fence or Sign that is part of a Barrel + * Returns null if block is not part of a Barrel + */ + public static Inventory getBarrelInventory(Block block) { + Barrel barrel = Barrel.get(block); + if (barrel != null) { + return barrel.getInventory(); + } + return null; + } + + /* + * Remove any Barrel that this Block may be Part of + * Returns true if a Barrel was removed + * Does not remove any actual Block + */ + public static boolean removeBarrel(Block block) { // TODO add dropItems flag + return removeBarrelByPlayer(block, null); + } + + /* + * Remove any Barrel that this Block may be Part of, as if broken by the Player + * Returns true if a Barrel was removed + * Does not remove any actual Block + */ + public static boolean removeBarrelByPlayer(Block block, Player player) { + Barrel barrel = Barrel.get(block); + if (barrel != null) { + barrel.remove(block, player); + return true; + } + return false; + } + + + // # # # # # Cauldron # # # # # + + /* + * Get a BCauldron from a Block + * Returns null if block is not a BCauldron + */ + public static BCauldron getCauldron(Block block) { + return BCauldron.get(block); + } + + /* + * Remove any data associated with a Cauldron at that given Block + * Returns true if a Cauldron was removed + * Does not actually remove the Block + */ + public static boolean removeCauldron(Block block) { + return BCauldron.remove(block); + } + + + // # # # # # Recipe # # # # # + + /* + * Get a BRecipe by its name + * The name is the middle one of the three if three are set in the config + * Returns null if recipe with that name does not exist + */ + public static BRecipe getRecipe(String name) { + return BRecipe.get(name); + } + + /* + * Add a new recipe + * Not Implemented yet + */ + public static boolean addRecipe(BRecipe recipe) { + throw new NotImplementedException(); // TODO implement + } +} diff --git a/src/com/dre/brewery/api/events/IngedientAddEvent.java b/src/com/dre/brewery/api/events/IngedientAddEvent.java new file mode 100644 index 0000000..396e806 --- /dev/null +++ b/src/com/dre/brewery/api/events/IngedientAddEvent.java @@ -0,0 +1,103 @@ +package com.dre.brewery.api.events; + +import com.dre.brewery.BCauldron; +import org.bukkit.block.Block; +import org.bukkit.block.BlockState; +import org.bukkit.entity.Player; +import org.bukkit.event.Cancellable; +import org.bukkit.event.HandlerList; +import org.bukkit.event.player.PlayerEvent; +import org.bukkit.inventory.ItemStack; +import org.bukkit.material.Cauldron; +import org.bukkit.material.MaterialData; + +/* + * Player adding an ingredient to a cauldron + * Always one item added at a time + * If needed use the caudrons add method to manually add more Items + */ +public class IngedientAddEvent extends PlayerEvent implements Cancellable { + private static final HandlerList handlers = new HandlerList(); + private final Block block; + private final BCauldron cauldron; + private ItemStack ingredient; + private boolean cancelled; + private boolean takeItem = true; + + public IngedientAddEvent(Player who, Block block, BCauldron bCauldron, ItemStack ingredient) { + super(who); + this.block = block; + cauldron = bCauldron; + this.ingredient = ingredient.clone(); + } + + public Block getBlock() { + return block; + } + + public BCauldron getCauldron() { + return cauldron; + } + + // Get the item currently being added to the cauldron by the player + // Can be changed directly or with the setter + // The amount is ignored and always one added + public ItemStack getIngredient() { + return ingredient; + } + + // Set the ingredient added to the cauldron to something else + // Will always be accepted, even when not in a recipe or the cooked list + // The amount is ignored and always one added + public void setIngredient(ItemStack ingredient) { + this.ingredient = ingredient; + } + + // If the amount of the item in the players hand should be decreased + // Default true + public boolean shouldTakeItem() { + return takeItem; + } + + // Set if the amount of the item in the players hand should be decreased + public void setTakeItem(boolean takeItem) { + this.takeItem = takeItem; + } + + // Get the MaterialData of the Cauldron + // May be null if the Cauldron does not exist anymore + public Cauldron getCauldronData() { + BlockState state = block.getState(); + if (state != null) { + MaterialData data = state.getData(); + if (data instanceof Cauldron) { + return ((Cauldron) state); + } + } + return null; + } + + // 0 = empty, 1 = something in, 2 = full + public int getFillLevel() { + return BCauldron.getFillLevel(block); + } + + @Override + public boolean isCancelled() { + return cancelled; + } + + @Override + public void setCancelled(boolean cancelled) { + this.cancelled = cancelled; + } + + @Override + public HandlerList getHandlers() { + return handlers; + } + + public static HandlerList getHandlerList() { + return handlers; + } +} diff --git a/src/com/dre/brewery/api/events/PlayerAlcEffectEvent.java b/src/com/dre/brewery/api/events/PlayerAlcEffectEvent.java new file mode 100644 index 0000000..7d371e2 --- /dev/null +++ b/src/com/dre/brewery/api/events/PlayerAlcEffectEvent.java @@ -0,0 +1,54 @@ +package com.dre.brewery.api.events; + +import org.bukkit.entity.Player; +import org.bukkit.event.Cancellable; +import org.bukkit.event.HandlerList; +import org.bukkit.event.player.PlayerEvent; +import org.bukkit.potion.PotionEffect; + +import java.util.List; + +/* + * Called when the Alcohol in the Player demands its toll + * These effects are applied regularly to the Player depending on his alcohol level + * By default it is just one Confusion effect + * Can be changed or cancelled + */ +public class PlayerAlcEffectEvent extends PlayerEvent implements Cancellable { + private static final HandlerList handlers = new HandlerList(); + private List effects; + private boolean cancelled; + + public PlayerAlcEffectEvent(Player who, List effects) { + super(who); + this.effects = effects; + } + + public List getEffects() { + return effects; + } + + public void setEffects(List effects) { + this.effects = effects; + } + + @Override + public boolean isCancelled() { + return cancelled; + } + + @Override + public void setCancelled(boolean cancelled) { + this.cancelled = cancelled; + } + + @Override + public HandlerList getHandlers() { + return handlers; + } + + public static HandlerList getHandlerList() { + return handlers; + } + +} diff --git a/src/com/dre/brewery/api/events/PlayerDrinkEffectEvent.java b/src/com/dre/brewery/api/events/PlayerDrinkEffectEvent.java new file mode 100644 index 0000000..6b19e1f --- /dev/null +++ b/src/com/dre/brewery/api/events/PlayerDrinkEffectEvent.java @@ -0,0 +1,52 @@ +package com.dre.brewery.api.events; + +import org.bukkit.entity.Player; +import org.bukkit.event.Cancellable; +import org.bukkit.event.HandlerList; +import org.bukkit.event.player.PlayerEvent; +import org.bukkit.potion.PotionEffect; + +import java.util.List; + +/* + * Called when the Effects of a Brew are applied to the player (drinking the Brew) + * These depend on alcohol and quality of the brew + * Can be changed or cancelled + */ +public class PlayerDrinkEffectEvent extends PlayerEvent implements Cancellable { + private static final HandlerList handlers = new HandlerList(); + private List effects; + private boolean cancelled; + + public PlayerDrinkEffectEvent(Player who, List effects) { + super(who); + this.effects = effects; + } + + public List getEffects() { + return effects; + } + + public void setEffects(List effects) { + this.effects = effects; + } + + @Override + public boolean isCancelled() { + return cancelled; + } + + @Override + public void setCancelled(boolean cancelled) { + this.cancelled = cancelled; + } + + @Override + public HandlerList getHandlers() { + return handlers; + } + + public static HandlerList getHandlerList() { + return handlers; + } +} diff --git a/src/com/dre/brewery/api/events/PlayerPukeEvent.java b/src/com/dre/brewery/api/events/PlayerPukeEvent.java new file mode 100644 index 0000000..4a0e001 --- /dev/null +++ b/src/com/dre/brewery/api/events/PlayerPukeEvent.java @@ -0,0 +1,60 @@ +package com.dre.brewery.api.events; + +import com.dre.brewery.BPlayer; +import org.bukkit.entity.Player; +import org.bukkit.event.Cancellable; +import org.bukkit.event.HandlerList; +import org.bukkit.event.player.PlayerEvent; + +/* + * The player pukes (throws puke items to the ground) + * Those items can never be picked up and despawn after the time set in the config + * Number of items to drop can be changed with count + */ +public class PlayerPukeEvent extends PlayerEvent implements Cancellable { + private static final HandlerList handlers = new HandlerList(); + private int count; + private boolean cancelled; + private BPlayer bPlayer; + + + public PlayerPukeEvent(Player who, int count) { + super(who); + this.count = count; + } + + public int getCount() { + return count; + } + + public void setCount(int count) { + this.count = count; + } + + public BPlayer getBPlayer() { + if (bPlayer == null) { + bPlayer = BPlayer.get(player); + } + return bPlayer; + } + + @Override + public boolean isCancelled() { + return cancelled; + } + + @Override + public void setCancelled(boolean cancelled) { + this.cancelled = cancelled; + } + + @Override + public HandlerList getHandlers() { + return handlers; + } + + public static HandlerList getHandlerList() { + return handlers; + } + +} diff --git a/src/com/dre/brewery/api/events/PlayerPushEvent.java b/src/com/dre/brewery/api/events/PlayerPushEvent.java new file mode 100644 index 0000000..c939e15 --- /dev/null +++ b/src/com/dre/brewery/api/events/PlayerPushEvent.java @@ -0,0 +1,64 @@ +package com.dre.brewery.api.events; + +import com.dre.brewery.BPlayer; +import org.bukkit.entity.Player; +import org.bukkit.event.Cancellable; +import org.bukkit.event.HandlerList; +import org.bukkit.event.player.PlayerEvent; +import org.bukkit.util.Vector; + +/* + * The Players movement is hindered because of drunkeness + * Called each time before pushing the Player with the Vector push 10 times + * The Push Vector can be changed or multiplied + */ +public class PlayerPushEvent extends PlayerEvent implements Cancellable { + private static final HandlerList handlers = new HandlerList(); + private final BPlayer bPlayer; + private Vector push; + private boolean cancelled; + + public PlayerPushEvent(Player who, Vector push, BPlayer bPlayer) { + super(who); + this.push = push; + this.bPlayer = bPlayer; + } + + public BPlayer getbPlayer() { + return bPlayer; + } + + // The Vector in which direction and magnitude the player is Pushed + // Can be changed directly or through setPush + public Vector getPush() { + return push; + } + + // Set the Push vector, can not be null + public void setPush(Vector push) { + if (push == null) { + throw new NullPointerException("Push Vector is null"); + } + this.push = push; + } + + @Override + public boolean isCancelled() { + return cancelled; + } + + @Override + public void setCancelled(boolean cancelled) { + this.cancelled = cancelled; + } + + @Override + public HandlerList getHandlers() { + return handlers; + } + + public static HandlerList getHandlerList() { + return handlers; + } + +} diff --git a/src/com/dre/brewery/api/events/barrel/BarrelAccessEvent.java b/src/com/dre/brewery/api/events/barrel/BarrelAccessEvent.java new file mode 100644 index 0000000..2911ad2 --- /dev/null +++ b/src/com/dre/brewery/api/events/barrel/BarrelAccessEvent.java @@ -0,0 +1,54 @@ +package com.dre.brewery.api.events.barrel; + +import com.dre.brewery.Barrel; +import org.bukkit.block.Block; +import org.bukkit.entity.Player; +import org.bukkit.event.Cancellable; +import org.bukkit.event.HandlerList; + +/* + * A Player opens a Barrel by rightclicking it + * The PlayerInteractEvent on the Barrel may be cancelled. In that case this never gets called + * Can be cancelled to silently deny opening the Barrel + */ +public class BarrelAccessEvent extends BarrelEvent implements Cancellable { + private static final HandlerList handlers = new HandlerList(); + private final Player player; + private final Block clickedBlock; + private boolean isCancelled; + + public BarrelAccessEvent(Barrel barrel, Player player, Block clickedBlock) { + super(barrel); + this.player = player; + this.clickedBlock = clickedBlock; + } + + // Gets the Block that was actually clicked. + // For access Permissions getSpigot() should be used + public Block getClickedBlock() { + return clickedBlock; + } + + @Override + public boolean isCancelled() { + return isCancelled; + } + + @Override + public void setCancelled(boolean cancelled) { + isCancelled = cancelled; + } + + public Player getPlayer() { + return player; + } + + @Override + public HandlerList getHandlers() { + return handlers; + } + + public static HandlerList getHandlerList() { + return handlers; + } +} diff --git a/src/com/dre/brewery/api/events/barrel/BarrelCreateEvent.java b/src/com/dre/brewery/api/events/barrel/BarrelCreateEvent.java new file mode 100644 index 0000000..560d199 --- /dev/null +++ b/src/com/dre/brewery/api/events/barrel/BarrelCreateEvent.java @@ -0,0 +1,44 @@ +package com.dre.brewery.api.events.barrel; + +import com.dre.brewery.Barrel; +import org.bukkit.entity.Player; +import org.bukkit.event.Cancellable; +import org.bukkit.event.HandlerList; + +/* + * Called when a Barrel is created by a Player by placing a Sign + * Cancelling this will silently fail the Barrel creation + */ +public class BarrelCreateEvent extends BarrelEvent implements Cancellable { + private static final HandlerList handlers = new HandlerList(); + private final Player player; + private boolean cancelled; + + public BarrelCreateEvent(Barrel barrel, Player player) { + super(barrel); + this.player = player; + } + + public Player getPlayer() { + return player; + } + + @Override + public boolean isCancelled() { + return cancelled; + } + + @Override + public void setCancelled(boolean cancelled) { + this.cancelled = cancelled; + } + + @Override + public HandlerList getHandlers() { + return handlers; + } + + public static HandlerList getHandlerList() { + return handlers; + } +} diff --git a/src/com/dre/brewery/api/events/barrel/BarrelDestroyEvent.java b/src/com/dre/brewery/api/events/barrel/BarrelDestroyEvent.java new file mode 100644 index 0000000..53b0f94 --- /dev/null +++ b/src/com/dre/brewery/api/events/barrel/BarrelDestroyEvent.java @@ -0,0 +1,71 @@ +package com.dre.brewery.api.events.barrel; + +import com.dre.brewery.Barrel; +import org.bukkit.block.Block; +import org.bukkit.entity.Player; +import org.bukkit.event.Cancellable; +import org.bukkit.event.HandlerList; + +/* + * A Barrel is being destroyed by something, may not be by a Player + * A BarrelRemoveEvent will be called after this, if this is not cancelled + * Use the BarrelRemoveEvent to monitor any and all barrels being removed in a non cancellable way +*/ +public class BarrelDestroyEvent extends BarrelEvent implements Cancellable { + private static final HandlerList handlers = new HandlerList(); + private final Block broken; + private final Reason reason; + private final Player player; + private boolean cancelled; + + public BarrelDestroyEvent(Barrel barrel, Block broken, Reason reason, Player player) { + super(barrel); + this.broken = broken; + this.player = player; + this.reason = reason; + } + + @Override + public boolean isCancelled() { + return cancelled; + } + + @Override + public void setCancelled(boolean cancelled) { + this.cancelled = cancelled; + } + + public Block getBroken() { + return broken; + } + + public Reason getReason() { + return reason; + } + + public boolean hasPlayer() { + return player != null; + } + + // MAY BE NULL if no Player is involved + public Player getPlayerOptional() { + return player; + } + + @Override + public HandlerList getHandlers() { + return handlers; + } + + public static HandlerList getHandlerList() { + return handlers; + } + + public enum Reason { + PLAYER, // A Player Broke the Barrel + BROKEN, // A Block was broken by something + BURNED, // A Block burned away + EXPLODED, // The Barrel exploded somehow + UNKNOWN // The Barrel was broken somehow else + } +} diff --git a/src/com/dre/brewery/api/events/barrel/BarrelEvent.java b/src/com/dre/brewery/api/events/barrel/BarrelEvent.java new file mode 100644 index 0000000..2195274 --- /dev/null +++ b/src/com/dre/brewery/api/events/barrel/BarrelEvent.java @@ -0,0 +1,27 @@ +package com.dre.brewery.api.events.barrel; + +import com.dre.brewery.Barrel; +import org.bukkit.block.Block; +import org.bukkit.event.Event; +import org.bukkit.event.HandlerList; +import org.bukkit.inventory.Inventory; + +public abstract class BarrelEvent extends Event { + protected final Barrel barrel; + + public BarrelEvent(Barrel barrel) { + this.barrel = barrel; + } + + public Barrel getBarrel() { + return barrel; + } + + public Inventory getInventory() { + return barrel.getInventory(); + } + + public Block getSpigot() { + return barrel.getSpigot(); + } +} diff --git a/src/com/dre/brewery/api/events/barrel/BarrelRemoveEvent.java b/src/com/dre/brewery/api/events/barrel/BarrelRemoveEvent.java new file mode 100644 index 0000000..3bb5504 --- /dev/null +++ b/src/com/dre/brewery/api/events/barrel/BarrelRemoveEvent.java @@ -0,0 +1,34 @@ +package com.dre.brewery.api.events.barrel; + +import com.dre.brewery.Barrel; +import org.bukkit.event.HandlerList; + +/* + * A Barrel is being removed. There may have been a BarrelDestroyEvent before + * If not, Worldedit, other Plugins etc may be the cause for unexpected removal + */ +public class BarrelRemoveEvent extends BarrelEvent { + private static final HandlerList handlers = new HandlerList(); + private boolean itemsDrop = true; + + public BarrelRemoveEvent(Barrel barrel) { + super(barrel); + } + + public boolean shouldItemsDrop() { + return itemsDrop; + } + + public void setShouldItemsDrop(boolean itemsDrop) { + this.itemsDrop = itemsDrop; + } + + @Override + public HandlerList getHandlers() { + return handlers; + } + + public static HandlerList getHandlerList() { + return handlers; + } +} diff --git a/src/com/dre/brewery/api/events/brew/BrewDrinkEvent.java b/src/com/dre/brewery/api/events/brew/BrewDrinkEvent.java new file mode 100644 index 0000000..c0b06bc --- /dev/null +++ b/src/com/dre/brewery/api/events/brew/BrewDrinkEvent.java @@ -0,0 +1,79 @@ +package com.dre.brewery.api.events.brew; + +import com.dre.brewery.BEffect; +import com.dre.brewery.BPlayer; +import com.dre.brewery.Brew; +import org.bukkit.entity.Player; +import org.bukkit.event.Cancellable; +import org.bukkit.event.HandlerList; +import org.bukkit.potion.PotionEffect; + +import java.util.List; + +/* + * A Player Drinks a Brew + * The amount of alcohol and quality that will be added to the player can be get/set here + * If cancelled the drinking will fail silently + */ +public class BrewDrinkEvent extends BrewEvent implements Cancellable { + private static final HandlerList handlers = new HandlerList(); + private final Player player; + private final BPlayer bPlayer; + private int alc; + private int quality; + private boolean cancelled; + + public BrewDrinkEvent(Brew brew, Player player, BPlayer bPlayer) { + super(brew); + this.player = player; + this.bPlayer = bPlayer; + alc = brew.calcAlcohol(); + quality = brew.getQuality(); + } + + public Player getPlayer() { + return player; + } + + public BPlayer getbPlayer() { + return bPlayer; + } + + public int getAddedAlcohol() { + return alc; + } + + public void setAddedAlcohol(int alc) { + this.alc = alc; + } + + public int getQuality() { + return quality; + } + + public void setQuality(int quality) { + if (quality > 10 || quality < 0) { + throw new IllegalArgumentException("Quality must be in range from 0 to 10"); + } + this.quality = quality; + } + + @Override + public boolean isCancelled() { + return cancelled; + } + + @Override + public void setCancelled(boolean cancelled) { + this.cancelled = cancelled; + } + + @Override + public HandlerList getHandlers() { + return handlers; + } + + public static HandlerList getHandlerList() { + return handlers; + } +} diff --git a/src/com/dre/brewery/api/events/brew/BrewEvent.java b/src/com/dre/brewery/api/events/brew/BrewEvent.java new file mode 100644 index 0000000..e509af7 --- /dev/null +++ b/src/com/dre/brewery/api/events/brew/BrewEvent.java @@ -0,0 +1,17 @@ +package com.dre.brewery.api.events.brew; + +import com.dre.brewery.Brew; +import org.bukkit.event.Event; +import org.bukkit.event.HandlerList; + +public abstract class BrewEvent extends Event { + protected final Brew brew; + + public BrewEvent(Brew brew) { + this.brew = brew; + } + + public Brew getBrew() { + return brew; + } +} diff --git a/src/com/dre/brewery/api/events/brew/BrewModifyEvent.java b/src/com/dre/brewery/api/events/brew/BrewModifyEvent.java new file mode 100644 index 0000000..8f6bed5 --- /dev/null +++ b/src/com/dre/brewery/api/events/brew/BrewModifyEvent.java @@ -0,0 +1,53 @@ +package com.dre.brewery.api.events.brew; + +import com.dre.brewery.Brew; +import org.bukkit.event.Cancellable; +import org.bukkit.event.HandlerList; + +/* + * A Brew is created or modified + * Usually happens on Filling from cauldron, distilling and aging. + */ +public class BrewModifyEvent extends BrewEvent implements Cancellable { + private static final HandlerList handlers = new HandlerList(); + private final Type type; + private boolean cancelled; + + public BrewModifyEvent(Brew brew, Type type) { + super(brew); + this.type = type; + } + + public Type getType() { + return type; + } + + @Override + public boolean isCancelled() { + return cancelled; + } + + @Override + public void setCancelled(boolean cancelled) { + this.cancelled = cancelled; + } + + @Override + public HandlerList getHandlers() { + return handlers; + } + + public static HandlerList getHandlerList() { + return handlers; + } + + public enum Type { + //CREATE, // A new Brew is created with arbitrary ways, like the create command + FILL, // Filled from a Cauldron into a new Brew + DISTILL, // Distilled in the Brewing stand + AGE, // Aged in a Barrel + UNLABEL, // Unlabeling Brew with command + STATIC, // Making Brew static with command + UNKNOWN // Unknown modification, unused + } +} diff --git a/src/com/dre/brewery/integration/GriefPreventionBarrel.java b/src/com/dre/brewery/integration/GriefPreventionBarrel.java index 85edf76..ac91407 100644 --- a/src/com/dre/brewery/integration/GriefPreventionBarrel.java +++ b/src/com/dre/brewery/integration/GriefPreventionBarrel.java @@ -1,18 +1,19 @@ package com.dre.brewery.integration; import com.dre.brewery.P; +import com.dre.brewery.api.events.barrel.BarrelAccessEvent; import me.ryanhamshire.GriefPrevention.Claim; import me.ryanhamshire.GriefPrevention.GriefPrevention; import me.ryanhamshire.GriefPrevention.PlayerData; -import org.bukkit.block.Block; import org.bukkit.entity.Player; public class GriefPreventionBarrel { - static P brewery = P.p; - static GriefPrevention griefPrevention = GriefPrevention.instance; + private static P brewery = P.p; - public static boolean checkAccess(Player player, Block sign) { + public static boolean checkAccess(BarrelAccessEvent event) { + GriefPrevention griefPrevention = GriefPrevention.instance; + Player player = event.getPlayer(); PlayerData playerData = griefPrevention.dataStore.getPlayerData(player.getUniqueId()); if (!griefPrevention.claimsEnabledForWorld(player.getWorld()) || playerData.ignoreClaims || !griefPrevention.config_claims_preventTheft) { @@ -21,12 +22,11 @@ public class GriefPreventionBarrel { // block container use during pvp combat if (playerData.inPvpCombat()) { - brewery.msg(player, brewery.languageReader.get("Error_NoBarrelAccess")); return false; } // check permissions for the claim the Barrel is in - Claim claim = griefPrevention.dataStore.getClaimAt(sign.getLocation(), false, playerData.lastClaim); + Claim claim = griefPrevention.dataStore.getClaimAt(event.getSpigot().getLocation(), false, playerData.lastClaim); if (claim != null) { playerData.lastClaim = claim; String noContainersReason = claim.allowContainers(player); diff --git a/src/com/dre/brewery/integration/IntegrationListener.java b/src/com/dre/brewery/integration/IntegrationListener.java new file mode 100644 index 0000000..ebb5278 --- /dev/null +++ b/src/com/dre/brewery/integration/IntegrationListener.java @@ -0,0 +1,122 @@ +package com.dre.brewery.integration; + +import com.dre.brewery.Barrel; +import com.dre.brewery.P; +import com.dre.brewery.api.events.barrel.BarrelAccessEvent; +import com.dre.brewery.api.events.barrel.BarrelDestroyEvent; +import com.dre.brewery.api.events.barrel.BarrelRemoveEvent; +import org.bukkit.event.EventHandler; +import org.bukkit.event.EventPriority; +import org.bukkit.event.Listener; +import org.bukkit.event.inventory.InventoryCloseEvent; +import org.bukkit.plugin.Plugin; + +public class IntegrationListener implements Listener { + + @EventHandler(priority = EventPriority.LOWEST, ignoreCancelled = true) + public void onBarrelAccessLowest(BarrelAccessEvent event) { + if (P.p.useWG) { + Plugin plugin = P.p.getServer().getPluginManager().getPlugin("WorldGuard"); + if (plugin != null) { + try { + if (!P.p.wg.checkAccess(event.getPlayer(), event.getSpigot(), plugin)) { + event.setCancelled(true); + } + } catch (Throwable e) { + event.setCancelled(true); + P.p.errorLog("Failed to Check WorldGuard for Barrel Open Permissions!"); + P.p.errorLog("Brewery was tested with version 5.8 to 6.1 of WorldGuard!"); + P.p.errorLog("Disable the WorldGuard support in the config and do /brew reload"); + e.printStackTrace(); + P.p.msg(event.getPlayer(), "&cError opening Barrel, please report to an Admin!"); + } + } + } + } + + @EventHandler(priority = EventPriority.LOW, ignoreCancelled = true) + public void onBarrelAccess(BarrelAccessEvent event) { + if (P.p.useGP) { + if (P.p.getServer().getPluginManager().isPluginEnabled("GriefPrevention")) { + try { + if (!GriefPreventionBarrel.checkAccess(event)) { + event.setCancelled(true); + } + } catch (Throwable e) { + event.setCancelled(true); + P.p.errorLog("Failed to Check GriefPrevention for Barrel Open Permissions!"); + P.p.errorLog("Brewery was tested with GriefPrevention 14.5.4"); + P.p.errorLog("Disable the GriefPrevention support in the config and do /brew reload"); + e.printStackTrace(); + P.p.msg(event.getPlayer(), "&cError opening Barrel, please report to an Admin!"); + } + } + } + } + + @EventHandler(ignoreCancelled = true, priority = EventPriority.LOW) + public void onBarrelDestroy(BarrelDestroyEvent event) { + if (!P.p.useLWC) return; + + if (event.hasPlayer()) { + try { + if (LWCBarrel.denyDestroy(event.getPlayerOptional(), event.getBarrel())) { + event.setCancelled(true); + } + } catch (Throwable e) { + event.setCancelled(true); + P.p.errorLog("Failed to Check LWC for Barrel Break Permissions!"); + P.p.errorLog("Brewery was tested with version 4.5.0 of LWC!"); + P.p.errorLog("Disable the LWC support in the config and do /brew reload"); + e.printStackTrace(); + P.p.msg(event.getPlayerOptional(), "&cError breaking Barrel, please report to an Admin!"); + } + } else { + try { + if (event.getReason() == BarrelDestroyEvent.Reason.EXPLODED) { + if (LWCBarrel.denyExplosion(event.getBarrel())) { + event.setCancelled(true); + } + } else { + if (LWCBarrel.denyDestroyOther(event.getBarrel())) { + event.setCancelled(true); + } + } + } catch (Throwable e) { + event.setCancelled(true); + P.p.errorLog("Failed to Check LWC on Barrel Destruction!"); + P.p.errorLog("Brewery was tested with version 4.5.0 of LWC!"); + P.p.errorLog("Disable the LWC support in the config and do /brew reload"); + e.printStackTrace(); + } + } + } + + @EventHandler + public void onBarrelRemove(BarrelRemoveEvent event) { + if (!P.p.useLWC) return; + + try { + LWCBarrel.remove(event.getBarrel()); + } catch (Throwable e) { + P.p.errorLog("Failed to Remove LWC Lock from Barrel!"); + P.p.errorLog("Brewery was tested with version 4.5.0 of LWC!"); + e.printStackTrace(); + } + } + + @EventHandler + public void onInventoryClose(InventoryCloseEvent event) { + if (P.p.useLB) { + if (event.getInventory().getHolder() instanceof Barrel) { + try { + LogBlockBarrel.closeBarrel(event.getPlayer(), event.getInventory()); + } catch (Exception e) { + P.p.errorLog("Failed to Log Barrel to LogBlock!"); + P.p.errorLog("Brewery was tested with version 1.94 of LogBlock!"); + e.printStackTrace(); + } + } + } + } +} diff --git a/src/com/dre/brewery/integration/LWCBarrel.java b/src/com/dre/brewery/integration/LWCBarrel.java index b3ee6f5..695f87d 100644 --- a/src/com/dre/brewery/integration/LWCBarrel.java +++ b/src/com/dre/brewery/integration/LWCBarrel.java @@ -1,13 +1,5 @@ package com.dre.brewery.integration; -import org.bukkit.block.Block; -import org.bukkit.entity.Player; -import org.bukkit.event.EventException; -import org.bukkit.event.HandlerList; -import org.bukkit.event.player.PlayerInteractEvent; -import org.bukkit.plugin.Plugin; -import org.bukkit.plugin.RegisteredListener; - import com.dre.brewery.Barrel; import com.dre.brewery.P; import com.griefcraft.listeners.LWCPlayerListener; @@ -15,11 +7,18 @@ import com.griefcraft.lwc.LWC; import com.griefcraft.model.Flag; import com.griefcraft.model.Protection; import com.griefcraft.scripting.event.LWCProtectionDestroyEvent; +import org.bukkit.block.Block; +import org.bukkit.entity.Player; +import org.bukkit.event.EventException; +import org.bukkit.event.HandlerList; +import org.bukkit.event.player.PlayerInteractEvent; +import org.bukkit.plugin.Plugin; +import org.bukkit.plugin.RegisteredListener; public class LWCBarrel { - public static boolean checkDestroy(Player player, Barrel barrel) { + public static boolean denyDestroy(Player player, Barrel barrel) { LWC lwc = LWC.getInstance(); Block sign = barrel.getSignOfSpigot(); //if (!Boolean.parseBoolean(lwc.resolveProtectionConfiguration(sign, "ignoreBlockDestruction"))) { @@ -33,18 +32,18 @@ public class LWCBarrel { lwc.getModuleLoader().dispatchEvent(evt); if (evt.isCancelled()) { - return false; + return true; } } catch (Exception e) { lwc.sendLocale(player, "protection.internalerror", "id", "BLOCK_BREAK"); P.p.errorLog("Failed to dispatch LWCProtectionDestroyEvent"); e.printStackTrace(); - return false; + return true; } } //} - return true; + return false; } public static boolean checkAccess(Player player, Block sign, PlayerInteractEvent event, Plugin plugin) { @@ -86,19 +85,14 @@ public class LWCBarrel { } // Returns true if the block that exploded should not be removed - public static boolean blockExplosion(Barrel barrel, Block block) { + public static boolean denyExplosion(Barrel barrel) { Protection protection = LWC.getInstance().findProtection(barrel.getSignOfSpigot()); - if (protection == null) { - barrel.remove(block, null); - return false; - } + return protection != null && !protection.hasFlag(Flag.Type.ALLOWEXPLOSIONS); + } - if (protection.hasFlag(Flag.Type.ALLOWEXPLOSIONS)) { - protection.remove(); - barrel.remove(block, null); - return false; - } - return true; + // Returns true if the block that was destroyed should not be removed + public static boolean denyDestroyOther(Barrel barrel) { + return LWC.getInstance().findProtection(barrel.getSignOfSpigot()) != null; } } diff --git a/src/com/dre/brewery/integration/WGBarrelNew.java b/src/com/dre/brewery/integration/WGBarrelNew.java index 4503b3d..e5d876a 100644 --- a/src/com/dre/brewery/integration/WGBarrelNew.java +++ b/src/com/dre/brewery/integration/WGBarrelNew.java @@ -1,15 +1,13 @@ package com.dre.brewery.integration; -import org.bukkit.block.Block; -import org.bukkit.entity.Player; -import org.bukkit.plugin.Plugin; - -import com.dre.brewery.P; import com.sk89q.worldguard.bukkit.RegionQuery; import com.sk89q.worldguard.bukkit.WorldGuardPlugin; import com.sk89q.worldguard.bukkit.permission.RegionPermissionModel; import com.sk89q.worldguard.protection.flags.DefaultFlag; +import org.bukkit.block.Block; +import org.bukkit.entity.Player; +import org.bukkit.plugin.Plugin; public class WGBarrelNew implements WGBarrel { @@ -21,12 +19,8 @@ public class WGBarrelNew implements WGBarrel { RegionQuery query = wg.getRegionContainer().createQuery(); - if (!query.testBuild(spigot.getLocation(), player, DefaultFlag.USE, DefaultFlag.CHEST_ACCESS)) { - P.p.msg(player, P.p.languageReader.get("Error_NoBarrelAccess")); - return false; - } + return query.testBuild(spigot.getLocation(), player, DefaultFlag.USE, DefaultFlag.CHEST_ACCESS); - return true; } } diff --git a/src/com/dre/brewery/integration/WGBarrelOld.java b/src/com/dre/brewery/integration/WGBarrelOld.java index 8699a7a..5cbcb7f 100644 --- a/src/com/dre/brewery/integration/WGBarrelOld.java +++ b/src/com/dre/brewery/integration/WGBarrelOld.java @@ -48,7 +48,6 @@ public class WGBarrelOld implements WGBarrel { if (!(Boolean) allows.invoke(region, DefaultFlag.CHEST_ACCESS, localPlayer)) { if (!(Boolean) canBuild.invoke(region, localPlayer)) { - P.p.msg(player, P.p.languageReader.get("Error_NoBarrelAccess")); return false; } } diff --git a/src/com/dre/brewery/listeners/BlockListener.java b/src/com/dre/brewery/listeners/BlockListener.java index 8263d7b..f272cd8 100644 --- a/src/com/dre/brewery/listeners/BlockListener.java +++ b/src/com/dre/brewery/listeners/BlockListener.java @@ -1,20 +1,21 @@ package com.dre.brewery.listeners; +import com.dre.brewery.BPlayer; +import com.dre.brewery.BUtil; +import com.dre.brewery.Barrel; +import com.dre.brewery.P; +import com.dre.brewery.Words; +import com.dre.brewery.api.events.barrel.BarrelDestroyEvent; import org.bukkit.block.Block; import org.bukkit.entity.Player; import org.bukkit.event.EventHandler; import org.bukkit.event.EventPriority; import org.bukkit.event.Listener; +import org.bukkit.event.block.BlockBreakEvent; import org.bukkit.event.block.BlockBurnEvent; import org.bukkit.event.block.BlockPistonExtendEvent; import org.bukkit.event.block.BlockPistonRetractEvent; import org.bukkit.event.block.SignChangeEvent; -import org.bukkit.event.block.BlockBreakEvent; - -import com.dre.brewery.Barrel; -import com.dre.brewery.BPlayer; -import com.dre.brewery.Words; -import com.dre.brewery.P; public class BlockListener implements Listener { @@ -45,14 +46,14 @@ public class BlockListener implements Listener { @EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true) public void onBlockBreak(BlockBreakEvent event) { - if (!P.p.blockDestroy(event.getBlock(), event.getPlayer())) { + if (!BUtil.blockDestroy(event.getBlock(), event.getPlayer(), BarrelDestroyEvent.Reason.PLAYER)) { event.setCancelled(true); } } @EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true) public void onBlockBurn(BlockBurnEvent event) { - P.p.blockDestroy(event.getBlock(), null); + BUtil.blockDestroy(event.getBlock(), null, BarrelDestroyEvent.Reason.BURNED); } @EventHandler(priority = EventPriority.HIGH, ignoreCancelled = true) diff --git a/src/com/dre/brewery/listeners/CommandListener.java b/src/com/dre/brewery/listeners/CommandListener.java index bae7517..2b1be26 100644 --- a/src/com/dre/brewery/listeners/CommandListener.java +++ b/src/com/dre/brewery/listeners/CommandListener.java @@ -4,6 +4,7 @@ import java.util.ArrayList; import java.util.Locale; import com.dre.brewery.Util; +import com.dre.brewery.api.events.brew.BrewModifyEvent; import org.bukkit.Material; import org.bukkit.command.Command; import org.bukkit.command.CommandExecutor; @@ -484,6 +485,11 @@ public class CommandListener implements CommandExecutor { if (hand != null) { Brew brew = Brew.get(hand); if (brew != null) { + BrewModifyEvent modifyEvent = new BrewModifyEvent(brew, BrewModifyEvent.Type.STATIC); + P.p.getServer().getPluginManager().callEvent(modifyEvent); + if (modifyEvent.isCancelled()) { + return; + } if (brew.isStatic()) { if (!brew.isPersistent()) { brew.setStatic(false, hand); @@ -516,6 +522,11 @@ public class CommandListener implements CommandExecutor { if (hand != null) { Brew brew = Brew.get(hand); if (brew != null) { + BrewModifyEvent modifyEvent = new BrewModifyEvent(brew, BrewModifyEvent.Type.UNLABEL); + P.p.getServer().getPluginManager().callEvent(modifyEvent); + if (modifyEvent.isCancelled()) { + return; + } brew.unLabel(hand); brew.touch(); brew.save(hand); diff --git a/src/com/dre/brewery/listeners/EntityListener.java b/src/com/dre/brewery/listeners/EntityListener.java index c32fdc1..d7cd084 100644 --- a/src/com/dre/brewery/listeners/EntityListener.java +++ b/src/com/dre/brewery/listeners/EntityListener.java @@ -1,25 +1,26 @@ package com.dre.brewery.listeners; -import java.util.ListIterator; - -import org.bukkit.Material; -import org.bukkit.block.Block; -import org.bukkit.event.EventHandler; -import org.bukkit.event.EventPriority; -import org.bukkit.event.Listener; -import org.bukkit.event.entity.EntityChangeBlockEvent; -import org.bukkit.event.entity.EntityExplodeEvent; -import org.bukkit.event.entity.ItemDespawnEvent; -import org.bukkit.event.entity.EntityCombustEvent; -import org.bukkit.entity.Entity; -import org.bukkit.entity.EntityType; -import org.bukkit.entity.Item; -import org.bukkit.inventory.ItemStack; - import com.dre.brewery.Barrel; import com.dre.brewery.Brew; import com.dre.brewery.P; -import com.dre.brewery.integration.LWCBarrel; +import com.dre.brewery.api.events.barrel.BarrelDestroyEvent; +import org.bukkit.Material; +import org.bukkit.block.Block; +import org.bukkit.entity.Entity; +import org.bukkit.entity.EntityType; +import org.bukkit.entity.Item; +import org.bukkit.event.EventHandler; +import org.bukkit.event.EventPriority; +import org.bukkit.event.Listener; +import org.bukkit.event.entity.EntityChangeBlockEvent; +import org.bukkit.event.entity.EntityCombustEvent; +import org.bukkit.event.entity.EntityExplodeEvent; +import org.bukkit.event.entity.ItemDespawnEvent; +import org.bukkit.inventory.ItemStack; + +import java.util.HashSet; +import java.util.ListIterator; +import java.util.Set; public class EntityListener implements Listener { @@ -50,31 +51,33 @@ public class EntityListener implements Listener { @EventHandler(priority = EventPriority.HIGH, ignoreCancelled = true) public void onExplode(EntityExplodeEvent event) { ListIterator iter = event.blockList().listIterator(); - Barrel barrel = null; - boolean removedBarrel = false; - while (iter.hasNext()) { - Block block = iter.next(); - if (barrel == null || !barrel.hasBlock(block)) { - barrel = Barrel.get(block); - removedBarrel = false; - } - if (!removedBarrel) { - if (barrel != null) { - if (P.p.useLWC) { - try { - if (LWCBarrel.blockExplosion(barrel, block)) { - iter.remove(); - } else { - removedBarrel = true; - } - } catch (Exception e) { - P.p.errorLog("Failed to Check LWC on Barrel Explosion!"); - e.printStackTrace(); - removedBarrel = true; + if (!iter.hasNext()) return; + Set breakEvents = new HashSet<>(6); + Block block; + blocks: while (iter.hasNext()) { + block = iter.next(); + if (!breakEvents.isEmpty()) { + for (BarrelDestroyEvent breakEvent : breakEvents) { + if (breakEvent.getBarrel().hasBlock(block)) { + if (breakEvent.isCancelled()) { + iter.remove(); } + continue blocks; } } } + Barrel barrel = Barrel.get(block); + if (barrel != null) { + BarrelDestroyEvent breakEvent = new BarrelDestroyEvent(barrel, block, BarrelDestroyEvent.Reason.EXPLODED, null); + // Listened to by LWCBarrel (IntegrationListener) + P.p.getServer().getPluginManager().callEvent(breakEvent); + breakEvents.add(breakEvent); + if (breakEvent.isCancelled()) { + iter.remove(); + } else { + barrel.remove(block, null); + } + } } } diff --git a/src/com/dre/brewery/listeners/InventoryListener.java b/src/com/dre/brewery/listeners/InventoryListener.java index 43111d7..7828d4a 100644 --- a/src/com/dre/brewery/listeners/InventoryListener.java +++ b/src/com/dre/brewery/listeners/InventoryListener.java @@ -5,8 +5,8 @@ import com.dre.brewery.BRecipe; import com.dre.brewery.Barrel; 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.P; import com.dre.brewery.lore.BrewLore; import org.bukkit.Bukkit; import org.bukkit.Material; diff --git a/src/com/dre/brewery/listeners/PlayerListener.java b/src/com/dre/brewery/listeners/PlayerListener.java index a39a4ac..e6babea 100644 --- a/src/com/dre/brewery/listeners/PlayerListener.java +++ b/src/com/dre/brewery/listeners/PlayerListener.java @@ -1,6 +1,13 @@ package com.dre.brewery.listeners; -import com.dre.brewery.*; +import com.dre.brewery.BCauldron; +import com.dre.brewery.BIngredients; +import com.dre.brewery.BPlayer; +import com.dre.brewery.Barrel; +import com.dre.brewery.Brew; +import com.dre.brewery.P; +import com.dre.brewery.Wakeup; +import com.dre.brewery.Words; import com.dre.brewery.filedata.UpdateChecker; import org.bukkit.GameMode; import org.bukkit.Material; @@ -118,7 +125,7 @@ public class PlayerListener implements Listener { if (BIngredients.possibleIngredients.contains(materialInHand)) { if (player.hasPermission("brewery.cauldron.insert")) { - if (BCauldron.ingredientAdd(clickedBlock, item)) { + if (BCauldron.ingredientAdd(clickedBlock, item, player)) { boolean isBucket = item.getType().equals(Material.WATER_BUCKET) || item.getType().equals(Material.LAVA_BUCKET) || item.getType().equals(Material.MILK_BUCKET); @@ -256,7 +263,10 @@ public class PlayerListener implements Listener { if (item.getType() == Material.POTION) { Brew brew = Brew.get(item); if (brew != null) { - BPlayer.drink(brew, player); + if (!BPlayer.drink(brew, player)) { + event.setCancelled(true); + return; + } /*if (player.getGameMode() != org.bukkit.GameMode.CREATIVE) { brew.remove(item); }*/ From 4a1f606e99855472c50e4c6f6d669312a28b6590 Mon Sep 17 00:00:00 2001 From: Sn0wStorm Date: Sat, 12 Oct 2019 13:52:55 +0200 Subject: [PATCH 16/51] Finalized Merge of 2.0-StoreDataInLore Rebased onto Master Branch commit e5438e7ae3c0dbabe65d14af520a1cd6d47ee0b4 And moved to new branch v2.0 --- src/com/dre/brewery/BCauldron.java | 34 +-- src/com/dre/brewery/BEffect.java | 2 +- src/com/dre/brewery/BIngredients.java | 8 +- src/com/dre/brewery/BPlayer.java | 30 +- src/com/dre/brewery/BRecipe.java | 8 +- src/com/dre/brewery/BUtil.java | 263 ++++++++++++++---- src/com/dre/brewery/Barrel.java | 20 +- src/com/dre/brewery/Brew.java | 30 +- src/com/dre/brewery/LegacyUtil.java | 18 +- src/com/dre/brewery/P.java | 92 +----- src/com/dre/brewery/Util.java | 157 ----------- src/com/dre/brewery/Wakeup.java | 6 +- .../brewery/api/events/IngedientAddEvent.java | 26 +- .../brewery/api/events/PlayerPushEvent.java | 2 +- .../api/events/barrel/BarrelRemoveEvent.java | 2 +- .../api/events/brew/BrewModifyEvent.java | 5 + src/com/dre/brewery/filedata/DataSave.java | 4 +- .../integration/GriefPreventionBarrel.java | 1 - .../integration/IntegrationListener.java | 29 +- .../dre/brewery/integration/WGBarrel7.java | 7 +- .../brewery/listeners/CommandListener.java | 15 +- .../brewery/listeners/InventoryListener.java | 85 ++---- .../dre/brewery/listeners/PlayerListener.java | 9 +- .../dre/brewery/listeners/WorldListener.java | 4 +- 24 files changed, 380 insertions(+), 477 deletions(-) delete mode 100644 src/com/dre/brewery/Util.java diff --git a/src/com/dre/brewery/BCauldron.java b/src/com/dre/brewery/BCauldron.java index 11187fb..c0c0c5c 100644 --- a/src/com/dre/brewery/BCauldron.java +++ b/src/com/dre/brewery/BCauldron.java @@ -1,18 +1,20 @@ package com.dre.brewery; +import com.dre.brewery.api.events.IngedientAddEvent; +import org.bukkit.Effect; +import org.bukkit.Material; +import org.bukkit.block.Block; +import org.bukkit.block.BlockFace; +import org.bukkit.block.data.BlockData; +import org.bukkit.block.data.Levelled; +import org.bukkit.configuration.ConfigurationSection; +import org.bukkit.entity.Player; +import org.bukkit.inventory.ItemStack; + import java.util.concurrent.CopyOnWriteArrayList; -import org.bukkit.block.data.BlockData; -import org.bukkit.block.data.Levelled; -import com.dre.brewery.api.events.IngedientAddEvent; -import org.bukkit.entity.Player; -import org.bukkit.block.Block; -import org.bukkit.block.BlockFace; -import org.bukkit.inventory.ItemStack; -import org.bukkit.Effect; -import org.bukkit.configuration.ConfigurationSection; - public class BCauldron { + public static final byte EMPTY = 0, SOME = 1, FULL = 2; public static CopyOnWriteArrayList bcauldrons = new CopyOnWriteArrayList<>(); // TODO find best Collection private BIngredients ingredients = new BIngredients(); @@ -35,7 +37,7 @@ public class BCauldron { public void onUpdate() { // Check if fire still alive - if (!Util.isChunkLoaded(block) || LegacyUtil.isFireForCauldron(block.getRelative(BlockFace.DOWN))) { + if (!BUtil.isChunkLoaded(block) || LegacyUtil.isFireForCauldron(block.getRelative(BlockFace.DOWN))) { // add a minute to cooking time state++; if (someRemoved) { @@ -74,7 +76,7 @@ public class BCauldron { // Calls the IngredientAddEvent and may be cancelled or changed public static boolean ingredientAdd(Block block, ItemStack ingredient, Player player) { // if not empty - if (LegacyUtil.getFillLevel(block) != 0) { + if (LegacyUtil.getFillLevel(block) != EMPTY) { BCauldron bcauldron = get(block); if (bcauldron == null) { bcauldron = new BCauldron(block); @@ -84,7 +86,7 @@ public class BCauldron { P.p.getServer().getPluginManager().callEvent(event); if (!event.isCancelled()) { bcauldron.add(event.getIngredient()); - return event.shouldTakeItem(); + return event.willTakeItem(); } else { return false; } @@ -169,7 +171,7 @@ public class BCauldron { // reset to normal cauldron public static boolean remove(Block block) { - if (LegacyUtil.getFillLevel(block) != 0) { + if (LegacyUtil.getFillLevel(block) != EMPTY) { BCauldron bcauldron = get(block); if (bcauldron != null) { bcauldrons.remove(bcauldron); @@ -190,7 +192,7 @@ public class BCauldron { } public static void save(ConfigurationSection config, ConfigurationSection oldData) { - Util.createWorldSections(config); + BUtil.createWorldSections(config); if (!bcauldrons.isEmpty()) { int id = 0; @@ -199,7 +201,7 @@ public class BCauldron { String prefix; if (worldName.startsWith("DXL_")) { - prefix = Util.getDxlName(worldName) + "." + id; + prefix = BUtil.getDxlName(worldName) + "." + id; } else { prefix = cauldron.block.getWorld().getUID().toString() + "." + id; } diff --git a/src/com/dre/brewery/BEffect.java b/src/com/dre/brewery/BEffect.java index b439068..fe12836 100644 --- a/src/com/dre/brewery/BEffect.java +++ b/src/com/dre/brewery/BEffect.java @@ -100,7 +100,7 @@ public class BEffect { public void apply(int quality, Player player) { PotionEffect effect = generateEffect(quality); if (effect != null) { - Util.reapplyPotionEffect(player, effect, true); + BUtil.reapplyPotionEffect(player, effect, true); } } diff --git a/src/com/dre/brewery/BIngredients.java b/src/com/dre/brewery/BIngredients.java index 0132f50..c8b40ed 100644 --- a/src/com/dre/brewery/BIngredients.java +++ b/src/com/dre/brewery/BIngredients.java @@ -128,11 +128,11 @@ public class BIngredients { } potionMeta.setDisplayName(P.p.color("&f" + cookedName)); - if (!P.use1_14) { + //if (!P.use1_14) { // Before 1.14 the effects duration would strangely be only a quarter of what we tell it to be // This is due to the Duration Modifier, that is removed in 1.14 - uid *= 4; - } + // uid *= 4; + //} // This effect stores the UID in its Duration //potionMeta.addCustomEffect((PotionEffectType.REGENERATION).createEffect((uid * 4), 0), true); @@ -363,7 +363,7 @@ public class BIngredients { public String toString() { return "BIngredients{" + "cookedTime=" + cookedTime + - ", total ingedients: " + getIngredientsCount() + '}'; + ", total ingredients: " + getIngredientsCount() + '}'; } /*public void testStore(DataOutputStream out) throws IOException { diff --git a/src/com/dre/brewery/BPlayer.java b/src/com/dre/brewery/BPlayer.java index 2f71e1a..eaccc2a 100644 --- a/src/com/dre/brewery/BPlayer.java +++ b/src/com/dre/brewery/BPlayer.java @@ -22,13 +22,7 @@ import org.bukkit.util.Vector; import java.lang.reflect.Field; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.Iterator; -import java.util.List; -import java.util.Map; -import java.util.Random; -import java.util.UUID; +import java.util.*; public class BPlayer { private static Map players = new HashMap<>();// Players name/uuid and BPlayer @@ -69,7 +63,7 @@ public class BPlayer { public static BPlayer get(Player player) { if (!players.isEmpty()) { - return players.get(Util.playerString(player)); + return players.get(BUtil.playerString(player)); } return null; } @@ -117,18 +111,18 @@ public class BPlayer { } public static boolean hasPlayer(Player player) { - return players.containsKey(Util.playerString(player)); + return players.containsKey(BUtil.playerString(player)); } // Create a new BPlayer and add it to the list public static BPlayer addPlayer(Player player) { BPlayer bPlayer = new BPlayer(); - players.put(Util.playerString(player), bPlayer); + players.put(BUtil.playerString(player), bPlayer); return bPlayer; } public static void remove(Player player) { - players.remove(Util.playerString(player)); + players.remove(BUtil.playerString(player)); } public static int numDrunkPlayers() { @@ -353,7 +347,7 @@ public class BPlayer { } hangoverEffects(player); // wird der spieler noch gebraucht? - players.remove(Util.playerString(player)); + players.remove(BUtil.playerString(player)); } else if (offlineDrunk - drunkeness >= 30) { Location randomLoc = Wakeup.getRandom(player.getLocation()); @@ -514,7 +508,7 @@ public class BPlayer { return; } for (PotionEffect effect : effects) { - Util.reapplyPotionEffect(player, effect, true); + BUtil.reapplyPotionEffect(player, effect, true); } } @@ -582,7 +576,7 @@ public class BPlayer { public static void addQualityEffects(int quality, int brewAlc, Player player) { for (PotionEffect effect : getQualityEffects(quality, brewAlc)) { - Util.reapplyPotionEffect(player, effect, true); + BUtil.reapplyPotionEffect(player, effect, true); } } @@ -615,8 +609,8 @@ public class BPlayer { } int amplifier = getHangoverQuality() / 3; - Util.reapplyPotionEffect(player, PotionEffectType.SLOW.createEffect(duration, amplifier), true); - Util.reapplyPotionEffect(player, PotionEffectType.HUNGER.createEffect(duration, amplifier), true); + BUtil.reapplyPotionEffect(player, PotionEffectType.SLOW.createEffect(duration, amplifier), true); + BUtil.reapplyPotionEffect(player, PotionEffectType.HUNGER.createEffect(duration, amplifier), true); } @@ -629,7 +623,7 @@ public class BPlayer { if (bplayer.drunkeness > 30) { if (bplayer.offlineDrunk == 0) { - Player player = Util.getPlayerfromString(name); + Player player = BUtil.getPlayerfromString(name); if (player != null) { bplayer.drunkEffects(player); @@ -657,7 +651,7 @@ public class BPlayer { // Prevent 0 drunkeness soberPerMin++; } - if (bplayer.drain(Util.getPlayerfromString(name), soberPerMin)) { + if (bplayer.drain(BUtil.getPlayerfromString(name), soberPerMin)) { iter.remove(); } } diff --git a/src/com/dre/brewery/BRecipe.java b/src/com/dre/brewery/BRecipe.java index 33c3e1a..9c58cb0 100644 --- a/src/com/dre/brewery/BRecipe.java +++ b/src/com/dre/brewery/BRecipe.java @@ -257,11 +257,11 @@ public class BRecipe { Brew.PotionColor.fromString(getColor()).colorBrew(potionMeta, potion, false); potionMeta.setDisplayName(P.p.color("&f" + getName(quality))); - if (!P.use1_14) { + //if (!P.use1_14) { // Before 1.14 the effects duration would strangely be only a quarter of what we tell it to be // This is due to the Duration Modifier, that is removed in 1.14 - uid *= 4; - } + // uid *= 4; + //} // This effect stores the UID in its Duration //potionMeta.addCustomEffect((PotionEffectType.REGENERATION).createEffect((uid * 4), 0), true); @@ -288,7 +288,7 @@ public class BRecipe { BIngredients bIngredients = new BIngredients(list, cookingTime); - return new Brew(bIngredients, quality, distillruns, getAge(), wood, getName(5), false, true); + return new Brew(bIngredients, quality, distillruns, getAge(), wood, getName(5), false, true, 0); } diff --git a/src/com/dre/brewery/BUtil.java b/src/com/dre/brewery/BUtil.java index bbfcd6a..df62db1 100644 --- a/src/com/dre/brewery/BUtil.java +++ b/src/com/dre/brewery/BUtil.java @@ -1,13 +1,94 @@ package com.dre.brewery; import com.dre.brewery.api.events.barrel.BarrelDestroyEvent; +import org.bukkit.Bukkit; +import org.bukkit.ChatColor; +import org.bukkit.Material; +import org.bukkit.World; import org.bukkit.block.Block; +import org.bukkit.command.CommandSender; +import org.bukkit.configuration.ConfigurationSection; import org.bukkit.entity.Player; +import org.bukkit.potion.PotionEffect; +import org.bukkit.potion.PotionEffectType; +import java.io.File; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.util.ArrayList; import java.util.List; +import java.util.ListIterator; +import java.util.UUID; public class BUtil { + /******************************************/ + /********** **********/ + /********** Bukkit Utils **********/ + /********** **********/ + /******************************************/ + + // Check if the Chunk of a Block is loaded !without loading it in the process! + public static boolean isChunkLoaded(Block block) { + return block.getWorld().isChunkLoaded(block.getX() >> 4, block.getZ() >> 4); + } + + public static String color(String msg) { + if (msg != null) { + msg = ChatColor.translateAlternateColorCodes('&', msg); + } + return msg; + } + + // Returns either uuid or Name of player, depending on bukkit version + public static String playerString(Player player) { + if (P.useUUID) { + return player.getUniqueId().toString(); + } else { + return player.getName(); + } + } + + // returns the Player if online + public static Player getPlayerfromString(String name) { + if (P.useUUID) { + try { + return Bukkit.getPlayer(UUID.fromString(name)); + } catch (Exception e) { + return Bukkit.getPlayerExact(name); + } + } + return Bukkit.getPlayerExact(name); + } + + // Apply a Potion Effect, if player already has this effect, overwrite the existing effect. + // Optionally only overwrite if the new one is stronger, i.e. has higher level or longer duration + public static void reapplyPotionEffect(Player player, PotionEffect effect, boolean onlyIfStronger) { + final PotionEffectType type = effect.getType(); + if (player.hasPotionEffect(type)) { + PotionEffect plEffect; + if (P.use1_11) { + plEffect = player.getPotionEffect(type); + } else { + plEffect = player.getActivePotionEffects().stream().filter(e -> e.getType().equals(type)).findAny().get(); + } + if (plEffect.getAmplifier() < effect.getAmplifier() || (plEffect.getAmplifier() == effect.getAmplifier() && plEffect.getDuration() < effect.getDuration())) { + player.removePotionEffect(type); + } else { + return; + } + } + effect.apply(player); + } + + /******************************************/ + /********** **********/ + /********** String Utils **********/ + /********** **********/ + /******************************************/ + // Returns the Index of a String from the list that contains this substring public static int indexOfSubstring(List list, String substring) { if (list.isEmpty()) return -1; @@ -30,71 +111,143 @@ public class BUtil { return -1; } - /* - ---- Barrel ---- - */ + /******************************************/ + /********** **********/ + /********** Brewery Utils **********/ + /********** **********/ + /******************************************/ + + // create empty World save Sections + public static void createWorldSections(ConfigurationSection section) { + for (World world : P.p.getServer().getWorlds()) { + String worldName = world.getName(); + if (worldName.startsWith("DXL_")) { + worldName = getDxlName(worldName); + } else { + worldName = world.getUID().toString(); + } + section.createSection(worldName); + } + } // Returns true if the Block can be destroyed by the Player or something else (null) public static boolean blockDestroy(Block block, Player player, BarrelDestroyEvent.Reason reason) { - switch (block.getType()) { - case CAULDRON: - // will only remove when existing - BCauldron.remove(block); - return true; - case FENCE: - case NETHER_FENCE: - case ACACIA_FENCE: - case BIRCH_FENCE: - case DARK_OAK_FENCE: - case IRON_FENCE: - case JUNGLE_FENCE: - case SPRUCE_FENCE: - // remove barrel and throw potions on the ground - Barrel barrel = Barrel.getBySpigot(block); - if (barrel != null) { - if (barrel.hasPermsDestroy(player, block, reason)) { - barrel.remove(null, player); + Material type = block.getType(); + if (type == Material.CAULDRON) { + // will only remove when existing + BCauldron.remove(block); + return true; + + } else if (LegacyUtil.isFence(type)) { + // remove barrel and throw potions on the ground + Barrel barrel = Barrel.getBySpigot(block); + if (barrel != null) { + if (barrel.hasPermsDestroy(player, block, reason)) { + barrel.remove(null, player); + return true; + } else { + return false; + } + } + return true; + + } else if (LegacyUtil.isSign(type)) { + // remove small Barrels + Barrel barrel2 = Barrel.getBySpigot(block); + if (barrel2 != null) { + if (!barrel2.isLarge()) { + if (barrel2.hasPermsDestroy(player, block, reason)) { + barrel2.remove(null, player); return true; } else { return false; } + } else { + barrel2.destroySign(); } - return true; - case SIGN_POST: - case WALL_SIGN: - // remove small Barrels - Barrel barrel2 = Barrel.getBySpigot(block); - if (barrel2 != null) { - if (!barrel2.isLarge()) { - if (barrel2.hasPermsDestroy(player, block, reason)) { - barrel2.remove(null, player); - return true; - } else { - return false; - } - } else { - barrel2.destroySign(); - } + } + return true; + + } else if (LegacyUtil.isWoodPlanks(type) || LegacyUtil.isWoodStairs(type)){ + Barrel barrel3 = Barrel.getByWood(block); + if (barrel3 != null) { + if (barrel3.hasPermsDestroy(player, block, reason)) { + barrel3.remove(block, player); + } else { + return false; } - return true; - case WOOD: - case WOOD_STAIRS: - case BIRCH_WOOD_STAIRS: - case JUNGLE_WOOD_STAIRS: - case SPRUCE_WOOD_STAIRS: - case ACACIA_STAIRS: - case DARK_OAK_STAIRS: - Barrel barrel3 = Barrel.getByWood(block); - if (barrel3 != null) { - if (barrel3.hasPermsDestroy(player, block, reason)) { - barrel3.remove(block, player); - } else { - return false; - } - } - default: - break; + } } return true; } + + /******************************************/ + /********** **********/ + /********** Other Utils **********/ + /********** **********/ + /******************************************/ + + // prints a list of Strings at the specified page + public static void list(CommandSender sender, ArrayList strings, int page) { + int pages = (int) Math.ceil(strings.size() / 7F); + if (page > pages || page < 1) { + page = 1; + } + + sender.sendMessage(color("&7-------------- &f" + P.p.languageReader.get("Etc_Page") + " &6" + page + "&f/&6" + pages + " &7--------------")); + + ListIterator iter = strings.listIterator((page - 1) * 7); + + for (int i = 0; i < 7; i++) { + if (iter.hasNext()) { + sender.sendMessage(color(iter.next())); + } else { + break; + } + } + } + + // gets the Name of a DXL World + public static String getDxlName(String worldName) { + File dungeonFolder = new File(worldName); + if (dungeonFolder.isDirectory()) { + for (File file : dungeonFolder.listFiles()) { + if (!file.isDirectory()) { + if (file.getName().startsWith(".id_")) { + return file.getName().substring(1).toLowerCase(); + } + } + } + } + return worldName; + } + + @SuppressWarnings("ResultOfMethodCallIgnored") + public static void saveFile(InputStream in, File dest, String name, boolean overwrite) throws IOException { + if (in == null) return; + if (!dest.exists()) { + dest.mkdirs(); + } + File result = new File(dest, name); + if (result.exists()) { + if (overwrite) { + result.delete(); + } else { + return; + } + } + + OutputStream out = new FileOutputStream(result); + byte[] buffer = new byte[1024]; + + int length; + //copy the file content in bytes + while ((length = in.read(buffer)) > 0){ + out.write(buffer, 0, length); + } + + in.close(); + out.close(); + } + } diff --git a/src/com/dre/brewery/Barrel.java b/src/com/dre/brewery/Barrel.java index 49418cc..c14d447 100644 --- a/src/com/dre/brewery/Barrel.java +++ b/src/com/dre/brewery/Barrel.java @@ -4,14 +4,11 @@ import com.dre.brewery.api.events.barrel.BarrelAccessEvent; import com.dre.brewery.api.events.barrel.BarrelCreateEvent; import com.dre.brewery.api.events.barrel.BarrelDestroyEvent; import com.dre.brewery.api.events.barrel.BarrelRemoveEvent; -import com.dre.brewery.integration.CitadelBarrel; -import com.dre.brewery.integration.GriefPreventionBarrel; import com.dre.brewery.integration.LWCBarrel; import com.dre.brewery.integration.LogBlockBarrel; import com.dre.brewery.lore.BrewLore; import org.apache.commons.lang.ArrayUtils; import org.bukkit.Material; -import org.bukkit.TreeSpecies; import org.bukkit.block.Block; import org.bukkit.configuration.ConfigurationSection; import org.bukkit.entity.HumanEntity; @@ -21,10 +18,6 @@ import org.bukkit.inventory.Inventory; import org.bukkit.inventory.InventoryHolder; import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.meta.PotionMeta; -import org.bukkit.material.MaterialData; -import org.bukkit.material.Stairs; -import org.bukkit.material.Tree; -import org.bukkit.material.Wood; import org.bukkit.plugin.Plugin; import org.bukkit.scheduler.BukkitRunnable; @@ -142,7 +135,7 @@ public class Barrel implements InventoryHolder { if (plugin != null) { // If the Clicked Block was the Sign, LWC already knows and we dont need to do anything here - if (!isSign(event.getClickedBlock())) { + if (!LegacyUtil.isSign(event.getClickedBlock().getType())) { Block sign = getSignOfSpigot(); // If the Barrel does not have a Sign, it cannot be locked if (!sign.equals(event.getClickedBlock())) { @@ -410,14 +403,14 @@ public class Barrel implements InventoryHolder { inventory.clear(); if (P.p.useLB && breaker != null) { try { - LogBlockBarrel.breakBarrel(breaker.getName(), items, spigot.getLocation()); + LogBlockBarrel.breakBarrel(breaker, items, spigot.getLocation()); } catch (Throwable e) { P.p.errorLog("Failed to Log Barrel-break to LogBlock!"); P.p.errorLog("Brewery was tested with version 1.94 of LogBlock!"); e.printStackTrace(); } } - if (event.shouldItemsDrop()) { + if (event.willItemsDrop()) { for (ItemStack item : items) { if (item != null) { Brew brew = Brew.get(item); @@ -462,7 +455,7 @@ public class Barrel implements InventoryHolder { // Saves all data public static void save(ConfigurationSection config, ConfigurationSection oldData) { - Util.createWorldSections(config); + BUtil.createWorldSections(config); if (!barrels.isEmpty()) { int id = 0; @@ -472,7 +465,7 @@ public class Barrel implements InventoryHolder { String prefix; if (worldName.startsWith("DXL_")) { - prefix = Util.getDxlName(worldName) + "." + id; + prefix = BUtil.getDxlName(worldName) + "." + id; } else { prefix = barrel.spigot.getWorld().getUID().toString() + "." + id; } @@ -638,7 +631,7 @@ public class Barrel implements InventoryHolder { // the barrel needs to be formed correctly // flag force to also check if chunk is not loaded public Block getBrokenBlock(boolean force) { - if (force || Util.isChunkLoaded(spigot)) { + if (force || BUtil.isChunkLoaded(spigot)) { spigot = getSpigotOfSign(spigot); if (LegacyUtil.isSign(spigot.getType())) { return checkSBarrel(); @@ -825,7 +818,6 @@ public class Barrel implements InventoryHolder { P.p.debugLog("Barrel at " + broken.getWorld().getName() + "/" + broken.getX() + "/" + broken.getY() + "/" + broken.getZ() + " has been destroyed unexpectedly, contents will drop"); // remove the barrel if it was destroyed - barrel.willDestroy(); // TODO Check if still needed barrel.remove(broken, null); } else { // Dont check this barrel again, its enough to check it once after every restart diff --git a/src/com/dre/brewery/Brew.java b/src/com/dre/brewery/Brew.java index d35bea2..95c41dc 100644 --- a/src/com/dre/brewery/Brew.java +++ b/src/com/dre/brewery/Brew.java @@ -1,8 +1,8 @@ package com.dre.brewery; -import org.bukkit.Color; import com.dre.brewery.api.events.brew.BrewModifyEvent; import com.dre.brewery.lore.*; +import org.bukkit.Color; import org.bukkit.Material; import org.bukkit.configuration.ConfigurationSection; import org.bukkit.inventory.BrewerInventory; @@ -42,7 +42,7 @@ public class Brew { private boolean unlabeled; private boolean persistent; // Only for legacy private boolean immutable; // static/immutable potions should not be changed - //private int lastUpdate; // last update in hours after install time + private int lastUpdate; // last update in hours after install time public Brew(BIngredients ingredients) { this.ingredients = ingredients; @@ -56,7 +56,7 @@ public class Brew { } // loading with all values set - public Brew(BIngredients ingredients, int quality, byte distillRuns, float ageTime, float wood, String recipe, boolean unlabeled, boolean immutable) { + public Brew(BIngredients ingredients, int quality, byte distillRuns, float ageTime, float wood, String recipe, boolean unlabeled, boolean immutable, int lastUpdate) { this.ingredients = ingredients; this.quality = quality; this.distillRuns = distillRuns; @@ -64,6 +64,7 @@ public class Brew { this.wood = wood; this.unlabeled = unlabeled; this.immutable = immutable; + this.lastUpdate = lastUpdate; setRecipeFromString(recipe); } @@ -77,6 +78,7 @@ public class Brew { if (meta instanceof PotionMeta && ((PotionMeta) meta).hasCustomEffect(PotionEffectType.REGENERATION)) { Brew brew = load(meta); if (brew != null) { + // Load Legacy brew = getFromPotionEffect(((PotionMeta) meta), false); } return brew; @@ -98,6 +100,7 @@ public class Brew { if (brew != null) { ((PotionMeta) meta).removeCustomEffect(PotionEffectType.REGENERATION); } else { + // Load Legacy and convert brew = getFromPotionEffect(((PotionMeta) meta), true); if (brew == null) return null; brew.save(meta); @@ -113,6 +116,7 @@ public class Brew { return null; } + // Legacy Brew Loading private static Brew getFromPotionEffect(PotionMeta potionMeta, boolean remove) { for (PotionEffect effect : potionMeta.getCustomEffects()) { if (effect.getType().equals(PotionEffectType.REGENERATION)) { @@ -365,9 +369,8 @@ public class Brew { } // Do some regular updates - // Currently does nothing, but may be used to update something on this brew public void touch() { - //lastUpdate = (int) ((double) (System.currentTimeMillis() - installTime) / 3600000D); + lastUpdate = (int) ((double) (System.currentTimeMillis() - installTime) / 3600000D); } public byte getDistillRuns() { @@ -439,9 +442,9 @@ public class Brew { } } - /*public int getLastUpdate() { + public int getLastUpdate() { return lastUpdate; - }*/ + } // Distilling section --------------- @@ -459,6 +462,7 @@ public class Brew { // distill custom potion in given slot public void distillSlot(ItemStack slotItem, PotionMeta potionMeta) { if (immutable) return; + //List> fcts = new ArrayList<>(); BrewModifyEvent modifyEvent = new BrewModifyEvent(this, BrewModifyEvent.Type.DISTILL); P.p.getServer().getPluginManager().callEvent(modifyEvent); if (modifyEvent.isCancelled()) return; @@ -574,7 +578,7 @@ public class Brew { factor = 2; } else if (ageTime > 10) { factor = 2; - factor += (float) ageTime / 10F; + factor += ageTime / 10F; } if (wood > to) { wood -= time / factor; @@ -723,8 +727,8 @@ public class Brew { } // 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) { - Brew brew = new Brew(ingredients, quality, distillRuns, ageTime, wood, recipe, unlabeled, 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, int lastUpdate) { + Brew brew = new Brew(ingredients, quality, distillRuns, ageTime, wood, recipe, unlabeled, stat, lastUpdate); brew.persistent = persistent; legacyPotions.put(uid, brew); } @@ -751,7 +755,7 @@ public class Brew { if (hasRecipe()) { BrewLore lore = new BrewLore(this, potionMeta); lore.removeEffects(); - PotionColor.valueOf(currentRecipe.getColor()).colorBrew(potionMeta, item, canDistill()); + PotionColor.fromString(currentRecipe.getColor()).colorBrew(potionMeta, item, canDistill()); } else { PotionColor.GREY.colorBrew(potionMeta, item, canDistill()); } @@ -792,9 +796,9 @@ public class Brew { if (brew.immutable) { idConfig.set("stat", true); } - /*if (brew.lastUpdate > 0) { + if (brew.lastUpdate > 0) { idConfig.set("lastUpdate", brew.lastUpdate); - }*/ + } // save the ingredients idConfig.set("ingId", brew.ingredients.save(config.getParent())); } diff --git a/src/com/dre/brewery/LegacyUtil.java b/src/com/dre/brewery/LegacyUtil.java index 58129a3..f0f369a 100644 --- a/src/com/dre/brewery/LegacyUtil.java +++ b/src/com/dre/brewery/LegacyUtil.java @@ -18,6 +18,10 @@ import java.lang.reflect.Method; import java.util.ArrayList; import java.util.List; +import static com.dre.brewery.BCauldron.EMPTY; +import static com.dre.brewery.BCauldron.SOME; +import static com.dre.brewery.BCauldron.FULL; + @SuppressWarnings("JavaReflectionMemberAccess") public class LegacyUtil { @@ -190,27 +194,27 @@ public class LegacyUtil { // 0 = empty, 1 = something in, 2 = full public static byte getFillLevel(Block block) { if (block.getType() != Material.CAULDRON) { - return 0; + return EMPTY; } if (P.use1_13) { Levelled cauldron = ((Levelled) block.getBlockData()); if (cauldron.getLevel() == 0) { - return 0; + return EMPTY; } else if (cauldron.getLevel() == cauldron.getMaximumLevel()) { - return 2; + return FULL; } else { - return 1; + return SOME; } } else { Cauldron cauldron = (Cauldron) block.getState().getData(); if (cauldron.isEmpty()) { - return 0; + return EMPTY; } else if (cauldron.isFull()) { - return 2; + return FULL; } else { - return 1; + return SOME; } } } diff --git a/src/com/dre/brewery/P.java b/src/com/dre/brewery/P.java index 54fc7e6..53098ca 100644 --- a/src/com/dre/brewery/P.java +++ b/src/com/dre/brewery/P.java @@ -5,19 +5,8 @@ import com.dre.brewery.filedata.DataSave; import com.dre.brewery.filedata.DataUpdater; import com.dre.brewery.filedata.LanguageReader; import com.dre.brewery.filedata.UpdateChecker; -import com.dre.brewery.integration.IntegrationListener; -import com.dre.brewery.integration.LogBlockBarrel; -import com.dre.brewery.integration.WGBarrel; -import com.dre.brewery.integration.WGBarrel7; -import com.dre.brewery.integration.WGBarrelNew; -import com.dre.brewery.integration.WGBarrelOld; -import com.dre.brewery.listeners.BlockListener; -import com.dre.brewery.listeners.CauldronListener; -import com.dre.brewery.listeners.CommandListener; -import com.dre.brewery.listeners.EntityListener; -import com.dre.brewery.listeners.InventoryListener; -import com.dre.brewery.listeners.PlayerListener; -import com.dre.brewery.listeners.WorldListener; +import com.dre.brewery.integration.*; +import com.dre.brewery.listeners.*; import org.apache.commons.lang.math.NumberUtils; import org.bstats.bukkit.Metrics; import org.bukkit.Bukkit; @@ -25,7 +14,6 @@ import org.bukkit.ChatColor; import org.bukkit.Location; import org.bukkit.Material; import org.bukkit.World; -import com.dre.brewery.lore.LoreOutputStream; import org.bukkit.block.Block; import org.bukkit.command.CommandSender; import org.bukkit.configuration.ConfigurationSection; @@ -38,14 +26,11 @@ import org.bukkit.plugin.Plugin; import org.bukkit.plugin.java.JavaPlugin; import java.io.File; -import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; -import java.io.OutputStream; import java.util.ArrayList; import java.util.HashMap; import java.util.List; -import java.util.ListIterator; import java.util.Map; import java.util.UUID; @@ -360,7 +345,7 @@ public class P extends JavaPlugin { readData(); // Setup Metrics - try { + /*try { Metrics metrics = new Metrics(this); metrics.addCustomChart(new Metrics.SingleLineChart("drunk_players", BPlayer::numDrunkPlayers)); metrics.addCustomChart(new Metrics.SingleLineChart("brews_in_existence", () -> Brew.potions.size())); @@ -416,7 +401,7 @@ public class P extends JavaPlugin { })); } catch (Throwable e) { e.printStackTrace(); - } + }*/ // Listeners blockListener = new BlockListener(); @@ -592,9 +577,6 @@ public class P extends JavaPlugin { // Third-Party useWG = config.getBoolean("useWorldGuard", true) && getServer().getPluginManager().isPluginEnabled("WorldGuard"); - useLWC = config.getBoolean("useLWC", true) && getServer().getPluginManager().isPluginEnabled("LWC"); - useGP = config.getBoolean("useGriefPrevention", true) && getServer().getPluginManager().isPluginEnabled("GriefPrevention"); - useLB = config.getBoolean("useLogBlock", false) && getServer().getPluginManager().isPluginEnabled("LogBlock"); hasVault = getServer().getPluginManager().isPluginEnabled("Vault"); if (useWG) { @@ -773,9 +755,9 @@ public class P extends JavaPlugin { boolean unlabeled = section.getBoolean(uid + ".unlabeled", false); boolean persistent = section.getBoolean(uid + ".persist", false); boolean stat = section.getBoolean(uid + ".stat", false); - //int lastUpdate = section.getInt("lastUpdate", 0); + int lastUpdate = section.getInt("lastUpdate", 0); - Brew.loadLegacy(ingredients, parseInt(uid), quality, distillRuns, ageTime, wood, recipe, unlabeled, persistent, stat); + Brew.loadLegacy(ingredients, parseInt(uid), quality, distillRuns, ageTime, wood, recipe, unlabeled, persistent, stat, lastUpdate); } } @@ -806,7 +788,7 @@ public class P extends JavaPlugin { for (World world : p.getServer().getWorlds()) { if (world.getName().startsWith("DXL_")) { - loadWorldData(Util.getDxlName(world.getName()), world); + loadWorldData(BUtil.getDxlName(world.getName()), world); } else { loadWorldData(world.getUID().toString(), world); } @@ -967,7 +949,7 @@ public class P extends JavaPlugin { return false; } try { - Util.saveFile(defconf, getDataFolder(), "config.yml", false); + BUtil.saveFile(defconf, getDataFolder(), "config.yml", false); } catch (IOException e) { e.printStackTrace(); return false; @@ -988,8 +970,8 @@ public class P extends JavaPlugin { for (String l : new String[] {"de", "en", "fr", "it", "zh", "tw"}) { File lfold = new File(configs, l); try { - Util.saveFile(getResource("config/" + (use1_13 ? "v13/" : "v12/") + l + "/config.yml"), lfold, "config.yml", overwrite); - Util.saveFile(getResource("languages/" + l + ".yml"), languages, l + ".yml", false); // Never overwrite languages for now + BUtil.saveFile(getResource("config/" + (use1_13 ? "v13/" : "v12/") + l + "/config.yml"), lfold, "config.yml", overwrite); + BUtil.saveFile(getResource("languages/" + l + ".yml"), languages, l + ".yml", false); // Never overwrite languages for now } catch (IOException e) { if (!(l.equals("zh") || l.equals("tw"))) { e.printStackTrace(); @@ -1004,60 +986,8 @@ public class P extends JavaPlugin { return NumberUtils.toInt(string, 0); } - - // Returns true if the Block can be destroyed by the Player or something else (null) - public boolean blockDestroy(Block block, Player player) { - Material type = block.getType(); - if (type == Material.CAULDRON) { - // will only remove when existing - BCauldron.remove(block); - return true; - - } else if (LegacyUtil.isFence(type)) { - // remove barrel and throw potions on the ground - Barrel barrel = Barrel.getBySpigot(block); - if (barrel != null) { - if (barrel.hasPermsDestroy(player)) { - barrel.remove(null, player); - return true; - } else { - return false; - } - } - return true; - - } else if (LegacyUtil.isSign(type)) { - // remove small Barrels - Barrel barrel2 = Barrel.getBySpigot(block); - if (barrel2 != null) { - if (!barrel2.isLarge()) { - if (barrel2.hasPermsDestroy(player)) { - barrel2.remove(null, player); - return true; - } else { - return false; - } - } else { - barrel2.destroySign(); - } - } - return true; - - } else if (LegacyUtil.isWoodPlanks(type) || LegacyUtil.isWoodStairs(type)){ - Barrel barrel3 = Barrel.getByWood(block); - if (barrel3 != null) { - if (barrel3.hasPermsDestroy(player)) { - barrel3.remove(block, player); - } else { - return false; - } - } - } - return true; - } - public String color(String msg) { - return Util.color(msg); + return BUtil.color(msg); } diff --git a/src/com/dre/brewery/Util.java b/src/com/dre/brewery/Util.java deleted file mode 100644 index bc7cf4a..0000000 --- a/src/com/dre/brewery/Util.java +++ /dev/null @@ -1,157 +0,0 @@ -package com.dre.brewery; - -import org.bukkit.Bukkit; -import org.bukkit.ChatColor; -import org.bukkit.World; -import org.bukkit.block.Block; -import org.bukkit.command.CommandSender; -import org.bukkit.configuration.ConfigurationSection; -import org.bukkit.entity.Player; -import org.bukkit.potion.PotionEffect; -import org.bukkit.potion.PotionEffectType; - -import java.io.File; -import java.io.FileOutputStream; -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; -import java.util.ArrayList; -import java.util.ListIterator; -import java.util.UUID; - -public class Util { - - /********** Bukkit Utils **********/ - - // Check if the Chunk of a Block is loaded !without loading it in the process! - public static boolean isChunkLoaded(Block block) { - return block.getWorld().isChunkLoaded(block.getX() >> 4, block.getZ() >> 4); - } - - public static String color(String msg) { - if (msg != null) { - msg = ChatColor.translateAlternateColorCodes('&', msg); - } - return msg; - } - - // Returns either uuid or Name of player, depending on bukkit version - public static String playerString(Player player) { - if (P.useUUID) { - return player.getUniqueId().toString(); - } else { - return player.getName(); - } - } - - // returns the Player if online - public static Player getPlayerfromString(String name) { - if (P.useUUID) { - try { - return Bukkit.getPlayer(UUID.fromString(name)); - } catch (Exception e) { - return Bukkit.getPlayerExact(name); - } - } - return Bukkit.getPlayerExact(name); - } - - // Apply a Potion Effect, if player already has this effect, overwrite the existing effect. - // Optionally only overwrite if the new one is stronger, i.e. has higher level or longer duration - public static void reapplyPotionEffect(Player player, PotionEffect effect, boolean onlyIfStronger) { - final PotionEffectType type = effect.getType(); - if (player.hasPotionEffect(type)) { - PotionEffect plEffect; - if (P.use1_11) { - plEffect = player.getPotionEffect(type); - } else { - plEffect = player.getActivePotionEffects().stream().filter(e -> e.getType().equals(type)).findAny().get(); - } - if (plEffect.getAmplifier() < effect.getAmplifier() || (plEffect.getAmplifier() == effect.getAmplifier() && plEffect.getDuration() < effect.getDuration())) { - player.removePotionEffect(type); - } else { - return; - } - } - effect.apply(player); - } - - /********** Other Utils **********/ - - // prints a list of Strings at the specified page - public static void list(CommandSender sender, ArrayList strings, int page) { - int pages = (int) Math.ceil(strings.size() / 7F); - if (page > pages || page < 1) { - page = 1; - } - - sender.sendMessage(color("&7-------------- &f" + P.p.languageReader.get("Etc_Page") + " &6" + page + "&f/&6" + pages + " &7--------------")); - - ListIterator iter = strings.listIterator((page - 1) * 7); - - for (int i = 0; i < 7; i++) { - if (iter.hasNext()) { - sender.sendMessage(color(iter.next())); - } else { - break; - } - } - } - - // gets the Name of a DXL World - public static String getDxlName(String worldName) { - File dungeonFolder = new File(worldName); - if (dungeonFolder.isDirectory()) { - for (File file : dungeonFolder.listFiles()) { - if (!file.isDirectory()) { - if (file.getName().startsWith(".id_")) { - return file.getName().substring(1).toLowerCase(); - } - } - } - } - return worldName; - } - - // create empty World save Sections - public static void createWorldSections(ConfigurationSection section) { - for (World world : P.p.getServer().getWorlds()) { - String worldName = world.getName(); - if (worldName.startsWith("DXL_")) { - worldName = getDxlName(worldName); - } else { - worldName = world.getUID().toString(); - } - section.createSection(worldName); - } - } - - @SuppressWarnings("ResultOfMethodCallIgnored") - public static void saveFile(InputStream in, File dest, String name, boolean overwrite) throws IOException { - if (in == null) return; - if (!dest.exists()) { - dest.mkdirs(); - } - File result = new File(dest, name); - if (result.exists()) { - if (overwrite) { - result.delete(); - } else { - return; - } - } - - OutputStream out = new FileOutputStream(result); - byte[] buffer = new byte[1024]; - - int length; - //copy the file content in bytes - while ((length = in.read(buffer)) > 0){ - out.write(buffer, 0, length); - } - - in.close(); - out.close(); - } - -} diff --git a/src/com/dre/brewery/Wakeup.java b/src/com/dre/brewery/Wakeup.java index 78aed34..1ee50d8 100644 --- a/src/com/dre/brewery/Wakeup.java +++ b/src/com/dre/brewery/Wakeup.java @@ -140,7 +140,7 @@ public class Wakeup { locs.add("&6" + s + id + "&f" + s + ": " + world + " " + x + "," + y + "," + z); } } - Util.list(sender, locs, page); + BUtil.list(sender, locs, page); } public static void check(CommandSender sender, int id, boolean all) { @@ -228,7 +228,7 @@ public class Wakeup { public static void save(ConfigurationSection section, ConfigurationSection oldData) { - Util.createWorldSections(section); + BUtil.createWorldSections(section); // loc is saved as a String in world sections with format x/y/z/pitch/yaw if (!wakeups.isEmpty()) { @@ -245,7 +245,7 @@ public class Wakeup { String prefix; if (worldName.startsWith("DXL_")) { - prefix = Util.getDxlName(worldName) + "." + id; + prefix = BUtil.getDxlName(worldName) + "." + id; } else { prefix = wakeup.loc.getWorld().getUID().toString() + "." + id; } diff --git a/src/com/dre/brewery/api/events/IngedientAddEvent.java b/src/com/dre/brewery/api/events/IngedientAddEvent.java index 396e806..8008595 100644 --- a/src/com/dre/brewery/api/events/IngedientAddEvent.java +++ b/src/com/dre/brewery/api/events/IngedientAddEvent.java @@ -1,8 +1,11 @@ package com.dre.brewery.api.events; import com.dre.brewery.BCauldron; +import com.dre.brewery.LegacyUtil; import org.bukkit.block.Block; import org.bukkit.block.BlockState; +import org.bukkit.block.data.BlockData; +import org.bukkit.block.data.Levelled; import org.bukkit.entity.Player; import org.bukkit.event.Cancellable; import org.bukkit.event.HandlerList; @@ -40,7 +43,7 @@ public class IngedientAddEvent extends PlayerEvent implements Cancellable { } // Get the item currently being added to the cauldron by the player - // Can be changed directly or with the setter + // Can be changed directly (mutable) or with the setter Method // The amount is ignored and always one added public ItemStack getIngredient() { return ingredient; @@ -55,7 +58,7 @@ public class IngedientAddEvent extends PlayerEvent implements Cancellable { // If the amount of the item in the players hand should be decreased // Default true - public boolean shouldTakeItem() { + public boolean willTakeItem() { return takeItem; } @@ -64,22 +67,21 @@ public class IngedientAddEvent extends PlayerEvent implements Cancellable { this.takeItem = takeItem; } - // Get the MaterialData of the Cauldron + // Get the BlockData of the Cauldron // May be null if the Cauldron does not exist anymore - public Cauldron getCauldronData() { - BlockState state = block.getState(); - if (state != null) { - MaterialData data = state.getData(); - if (data instanceof Cauldron) { - return ((Cauldron) state); - } + public Levelled getCauldronData() { + BlockData data = block.getBlockData(); + if (data instanceof Levelled) { + return (Levelled) data; } return null; } + // Get the Water Fill level of the Cauldron // 0 = empty, 1 = something in, 2 = full - public int getFillLevel() { - return BCauldron.getFillLevel(block); + // Can use BCauldron.EMPTY, BCauldron.SOME, BCauldron.FULL + public byte getFillLevel() { + return LegacyUtil.getFillLevel(block); } @Override diff --git a/src/com/dre/brewery/api/events/PlayerPushEvent.java b/src/com/dre/brewery/api/events/PlayerPushEvent.java index c939e15..10f286b 100644 --- a/src/com/dre/brewery/api/events/PlayerPushEvent.java +++ b/src/com/dre/brewery/api/events/PlayerPushEvent.java @@ -24,7 +24,7 @@ public class PlayerPushEvent extends PlayerEvent implements Cancellable { this.bPlayer = bPlayer; } - public BPlayer getbPlayer() { + public BPlayer getBPlayer() { return bPlayer; } diff --git a/src/com/dre/brewery/api/events/barrel/BarrelRemoveEvent.java b/src/com/dre/brewery/api/events/barrel/BarrelRemoveEvent.java index 3bb5504..b846e6b 100644 --- a/src/com/dre/brewery/api/events/barrel/BarrelRemoveEvent.java +++ b/src/com/dre/brewery/api/events/barrel/BarrelRemoveEvent.java @@ -15,7 +15,7 @@ public class BarrelRemoveEvent extends BarrelEvent { super(barrel); } - public boolean shouldItemsDrop() { + public boolean willItemsDrop() { return itemsDrop; } diff --git a/src/com/dre/brewery/api/events/brew/BrewModifyEvent.java b/src/com/dre/brewery/api/events/brew/BrewModifyEvent.java index 8f6bed5..01ace63 100644 --- a/src/com/dre/brewery/api/events/brew/BrewModifyEvent.java +++ b/src/com/dre/brewery/api/events/brew/BrewModifyEvent.java @@ -12,6 +12,7 @@ public class BrewModifyEvent extends BrewEvent implements Cancellable { private static final HandlerList handlers = new HandlerList(); private final Type type; private boolean cancelled; + //private List> fcts; public BrewModifyEvent(Brew brew, Type type) { super(brew); @@ -22,6 +23,10 @@ public class BrewModifyEvent extends BrewEvent implements Cancellable { return type; } + /*public void addModification(Consumer predicate) { + fcts.add(predicate); + }*/ + @Override public boolean isCancelled() { return cancelled; diff --git a/src/com/dre/brewery/filedata/DataSave.java b/src/com/dre/brewery/filedata/DataSave.java index f3d9a6a..496bdba 100644 --- a/src/com/dre/brewery/filedata/DataSave.java +++ b/src/com/dre/brewery/filedata/DataSave.java @@ -4,7 +4,7 @@ package com.dre.brewery.filedata; import java.io.File; import com.dre.brewery.MCBarrel; -import com.dre.brewery.Util; +import com.dre.brewery.BUtil; import org.bukkit.World; import org.bukkit.configuration.ConfigurationSection; import org.bukkit.configuration.file.FileConfiguration; @@ -157,7 +157,7 @@ public class DataSave extends BukkitRunnable { for (World world : P.p.getServer().getWorlds()) { String worldName = world.getName(); if (worldName.startsWith("DXL_")) { - worldName = Util.getDxlName(worldName); + worldName = BUtil.getDxlName(worldName); root.set("Worlds." + worldName, 0); } else { worldName = world.getUID().toString(); diff --git a/src/com/dre/brewery/integration/GriefPreventionBarrel.java b/src/com/dre/brewery/integration/GriefPreventionBarrel.java index ac91407..ae05283 100644 --- a/src/com/dre/brewery/integration/GriefPreventionBarrel.java +++ b/src/com/dre/brewery/integration/GriefPreventionBarrel.java @@ -31,7 +31,6 @@ public class GriefPreventionBarrel { playerData.lastClaim = claim; String noContainersReason = claim.allowContainers(player); if (noContainersReason != null) { - brewery.msg(player, brewery.languageReader.get("Error_NoBarrelAccess") + " " + noContainersReason); return false; } } diff --git a/src/com/dre/brewery/integration/IntegrationListener.java b/src/com/dre/brewery/integration/IntegrationListener.java index ebb5278..5113366 100644 --- a/src/com/dre/brewery/integration/IntegrationListener.java +++ b/src/com/dre/brewery/integration/IntegrationListener.java @@ -5,6 +5,7 @@ import com.dre.brewery.P; import com.dre.brewery.api.events.barrel.BarrelAccessEvent; import com.dre.brewery.api.events.barrel.BarrelDestroyEvent; import com.dre.brewery.api.events.barrel.BarrelRemoveEvent; +import org.bukkit.entity.Player; import org.bukkit.event.EventHandler; import org.bukkit.event.EventPriority; import org.bukkit.event.Listener; @@ -25,10 +26,16 @@ public class IntegrationListener implements Listener { } catch (Throwable e) { event.setCancelled(true); P.p.errorLog("Failed to Check WorldGuard for Barrel Open Permissions!"); - P.p.errorLog("Brewery was tested with version 5.8 to 6.1 of WorldGuard!"); + P.p.errorLog("Brewery was tested with version 5.8, 6.1 to 7.0 of WorldGuard!"); P.p.errorLog("Disable the WorldGuard support in the config and do /brew reload"); e.printStackTrace(); - P.p.msg(event.getPlayer(), "&cError opening Barrel, please report to an Admin!"); + Player player = event.getPlayer(); + if (player.hasPermission("brewery.admin") || player.hasPermission("brewery.mod")) { + P.p.msg(player, "&cWorldGuard check Error, Brewery was tested with up to v7.0 of Worldguard"); + P.p.msg(player, "&cSet &7useWorldGuard: false &cin the config and /brew reload"); + } else { + P.p.msg(player, "&cError opening Barrel, please report to an Admin!"); + } } } } @@ -45,10 +52,16 @@ public class IntegrationListener implements Listener { } catch (Throwable e) { event.setCancelled(true); P.p.errorLog("Failed to Check GriefPrevention for Barrel Open Permissions!"); - P.p.errorLog("Brewery was tested with GriefPrevention 14.5.4"); + P.p.errorLog("Brewery was tested with GriefPrevention v14.5 - v16.9"); P.p.errorLog("Disable the GriefPrevention support in the config and do /brew reload"); e.printStackTrace(); - P.p.msg(event.getPlayer(), "&cError opening Barrel, please report to an Admin!"); + Player player = event.getPlayer(); + if (player.hasPermission("brewery.admin") || player.hasPermission("brewery.mod")) { + P.p.msg(player, "&cGriefPrevention check Error, Brewery was tested with up to v16.9 of GriefPrevention"); + P.p.msg(player, "&cSet &7useGriefPrevention: false &cin the config and /brew reload"); + } else { + P.p.msg(player, "&cError opening Barrel, please report to an Admin!"); + } } } } @@ -69,7 +82,13 @@ public class IntegrationListener implements Listener { P.p.errorLog("Brewery was tested with version 4.5.0 of LWC!"); P.p.errorLog("Disable the LWC support in the config and do /brew reload"); e.printStackTrace(); - P.p.msg(event.getPlayerOptional(), "&cError breaking Barrel, please report to an Admin!"); + Player player = event.getPlayerOptional(); + if (player.hasPermission("brewery.admin") || player.hasPermission("brewery.mod")) { + P.p.msg(player, "&cLWC check Error, Brewery was tested with up to v4.5.0 of LWC"); + P.p.msg(player, "&cSet &7useLWC: false &cin the config and /brew reload"); + } else { + P.p.msg(player, "&cError opening Barrel, please report to an Admin!"); + } } } else { try { diff --git a/src/com/dre/brewery/integration/WGBarrel7.java b/src/com/dre/brewery/integration/WGBarrel7.java index 7c2ef25..0d1de5d 100644 --- a/src/com/dre/brewery/integration/WGBarrel7.java +++ b/src/com/dre/brewery/integration/WGBarrel7.java @@ -55,12 +55,7 @@ public class WGBarrel7 implements WGBarrel { RegionQuery query = platform.getRegionContainer().createQuery(); - if (!query.testBuild(new Location(world, spigot.getX(), spigot.getY(), spigot.getZ()), wg.wrapPlayer(player), Flags.USE, Flags.CHEST_ACCESS)) { - P.p.msg(player, P.p.languageReader.get("Error_NoBarrelAccess")); - return false; - } - - return true; + return query.testBuild(new Location(world, spigot.getX(), spigot.getY(), spigot.getZ()), wg.wrapPlayer(player), Flags.USE, Flags.CHEST_ACCESS); } } diff --git a/src/com/dre/brewery/listeners/CommandListener.java b/src/com/dre/brewery/listeners/CommandListener.java index 2b1be26..feee66e 100644 --- a/src/com/dre/brewery/listeners/CommandListener.java +++ b/src/com/dre/brewery/listeners/CommandListener.java @@ -1,9 +1,6 @@ package com.dre.brewery.listeners; -import java.util.ArrayList; -import java.util.Locale; - -import com.dre.brewery.Util; +import com.dre.brewery.*; import com.dre.brewery.api.events.brew.BrewModifyEvent; import org.bukkit.Material; import org.bukkit.command.Command; @@ -12,12 +9,8 @@ import org.bukkit.command.CommandSender; import org.bukkit.entity.Player; import org.bukkit.inventory.ItemStack; -import com.dre.brewery.BIngredients; -import com.dre.brewery.BRecipe; -import com.dre.brewery.P; -import com.dre.brewery.Wakeup; -import com.dre.brewery.BPlayer; -import com.dre.brewery.Brew; +import java.util.ArrayList; +import java.util.Locale; public class CommandListener implements CommandExecutor { @@ -168,7 +161,7 @@ public class CommandListener implements CommandExecutor { p.msg(sender, "&6" + p.getDescription().getName() + " v" + p.getDescription().getVersion()); } - Util.list(sender, commands, page); + BUtil.list(sender, commands, page); } diff --git a/src/com/dre/brewery/listeners/InventoryListener.java b/src/com/dre/brewery/listeners/InventoryListener.java index 7828d4a..bd25039 100644 --- a/src/com/dre/brewery/listeners/InventoryListener.java +++ b/src/com/dre/brewery/listeners/InventoryListener.java @@ -1,12 +1,6 @@ package com.dre.brewery.listeners; -import com.dre.brewery.BPlayer; -import com.dre.brewery.BRecipe; -import com.dre.brewery.Barrel; -import com.dre.brewery.Brew; -import com.dre.brewery.MCBarrel; -import com.dre.brewery.integration.LogBlockBarrel; -import com.dre.brewery.P; +import com.dre.brewery.*; import com.dre.brewery.lore.BrewLore; import org.bukkit.Bukkit; import org.bukkit.Material; @@ -19,15 +13,7 @@ import org.bukkit.entity.HumanEntity; import org.bukkit.event.EventHandler; import org.bukkit.event.EventPriority; import org.bukkit.event.Listener; -import org.bukkit.event.inventory.BrewEvent; -import org.bukkit.event.inventory.ClickType; -import org.bukkit.event.inventory.InventoryAction; -import org.bukkit.event.inventory.InventoryClickEvent; -import org.bukkit.event.inventory.InventoryCloseEvent; -import org.bukkit.event.inventory.InventoryDragEvent; -import org.bukkit.event.inventory.InventoryOpenEvent; -import org.bukkit.event.inventory.InventoryPickupItemEvent; -import org.bukkit.event.inventory.InventoryType; +import org.bukkit.event.inventory.*; import org.bukkit.inventory.BrewerInventory; import org.bukkit.inventory.Inventory; import org.bukkit.inventory.ItemFlag; @@ -38,7 +24,6 @@ import org.bukkit.scheduler.BukkitRunnable; import java.util.HashMap; import java.util.HashSet; import java.util.Iterator; -import java.util.List; import java.util.UUID; /** @@ -203,13 +188,25 @@ public class InventoryListener implements Listener { for (int slot = 0; slot < 3; slot++) { item = inv.getItem(slot); if (item != null) { - if (item.getType() == Material.POTION) { - if (item.hasItemMeta()) { - Brew pot = Brew.get(item); - if (pot != null && (!distill || pot.canDistill())) { // need at least one distillable potion. - return true; - } - } + contents[slot] = Brew.get(item); + } + } + return contents; + } + + private byte hasCustom(BrewerInventory brewer) { + ItemStack item = brewer.getItem(3); // ingredient + boolean glowstone = (item != null && Material.GLOWSTONE_DUST == item.getType()); // need dust in the top slot. + byte customFound = 0; + for (Brew brew : getDistillContents(brewer)) { + if (brew != null) { + if (!glowstone) { + return 1; + } + if (brew.canDistill()) { + return 2; + } else { + customFound = 1; } } } @@ -231,24 +228,14 @@ public class InventoryListener implements Listener { private boolean runDistill(BrewerInventory inv) { boolean custom = false; - Boolean[] contents = new Boolean[3]; - while (slot < 3) { - item = inv.getItem(slot); - contents[slot] = false; - if (item != null) { - if (item.getType() == Material.POTION) { - if (item.hasItemMeta()) { - Brew brew = Brew.get(item); - if (brew != null) { - // has custom potion in "slot" - if (brew.canDistill()) { - // is further distillable - contents[slot] = true; - custom = true; - } - } - } - } + Brew[] contents = getDistillContents(inv); + for (int slot = 0; slot < 3; slot++) { + if (contents[slot] == null) continue; + if (contents[slot].canDistill()) { + // is further distillable + custom = true; + } else { + contents[slot] = null; } } if (custom) { @@ -299,7 +286,7 @@ public class InventoryListener implements Listener { P.p.log(potion.getLore().get(0).replaceAll("§", "")); P.p.log("similar to beispiel? " + BRecipe.get("Beispiel").createBrew(10).isSimilar(brew)); - //brew.touch(); + brew.touch(); /*try { DataInputStream in = new DataInputStream(new Base91DecoderStream(new LoreLoadStream(potion))); @@ -457,18 +444,6 @@ public class InventoryListener implements Listener { @EventHandler public void onInventoryClose(InventoryCloseEvent event) { - if (P.p.useLB) { - if (event.getInventory().getHolder() instanceof Barrel) { - try { - LogBlockBarrel.closeBarrel(event.getPlayer(), event.getInventory()); - } catch (Exception e) { - P.p.errorLog("Failed to Log Barrel to LogBlock!"); - P.p.errorLog("Brewery was tested with version 1.94 of LogBlock!"); - e.printStackTrace(); - } - } - } - if (!P.use1_14) return; // Barrel Closing Sound diff --git a/src/com/dre/brewery/listeners/PlayerListener.java b/src/com/dre/brewery/listeners/PlayerListener.java index e6babea..8146585 100644 --- a/src/com/dre/brewery/listeners/PlayerListener.java +++ b/src/com/dre/brewery/listeners/PlayerListener.java @@ -1,13 +1,6 @@ package com.dre.brewery.listeners; -import com.dre.brewery.BCauldron; -import com.dre.brewery.BIngredients; -import com.dre.brewery.BPlayer; -import com.dre.brewery.Barrel; -import com.dre.brewery.Brew; -import com.dre.brewery.P; -import com.dre.brewery.Wakeup; -import com.dre.brewery.Words; +import com.dre.brewery.*; import com.dre.brewery.filedata.UpdateChecker; import org.bukkit.GameMode; import org.bukkit.Material; diff --git a/src/com/dre/brewery/listeners/WorldListener.java b/src/com/dre/brewery/listeners/WorldListener.java index fde093c..0b887b3 100644 --- a/src/com/dre/brewery/listeners/WorldListener.java +++ b/src/com/dre/brewery/listeners/WorldListener.java @@ -3,7 +3,7 @@ package com.dre.brewery.listeners; import com.dre.brewery.BCauldron; import com.dre.brewery.Barrel; import com.dre.brewery.P; -import com.dre.brewery.Util; +import com.dre.brewery.BUtil; import com.dre.brewery.filedata.DataSave; import org.bukkit.World; import org.bukkit.event.EventHandler; @@ -19,7 +19,7 @@ public class WorldListener implements Listener { World world = event.getWorld(); if (world.getName().startsWith("DXL_")) { - P.p.loadWorldData(Util.getDxlName(world.getName()), world); + P.p.loadWorldData(BUtil.getDxlName(world.getName()), world); } else { P.p.loadWorldData(world.getUID().toString(), world); } From d355966d42e5b5755af7d768cb037b1d583f3d7f Mon Sep 17 00:00:00 2001 From: Sn0wStorm Date: Sat, 12 Oct 2019 14:47:01 +0200 Subject: [PATCH 17/51] Some more merge fixes --- src/com/dre/brewery/Barrel.java | 2 +- src/com/dre/brewery/Brew.java | 2 ++ src/com/dre/brewery/P.java | 2 -- src/com/dre/brewery/filedata/DataSave.java | 1 - 4 files changed, 3 insertions(+), 4 deletions(-) diff --git a/src/com/dre/brewery/Barrel.java b/src/com/dre/brewery/Barrel.java index c14d447..3f47a8c 100644 --- a/src/com/dre/brewery/Barrel.java +++ b/src/com/dre/brewery/Barrel.java @@ -123,7 +123,7 @@ public class Barrel implements InventoryHolder { // Call event BarrelAccessEvent accessEvent = new BarrelAccessEvent(this, player, event.getClickedBlock()); - // Listened to by WGBarrelNew, WGBarrelOld, GriefPreventionBarrel (IntegrationListener) + // Listened to by WGBarrel7, WGBarrelNew, WGBarrelOld, GriefPreventionBarrel (IntegrationListener) P.p.getServer().getPluginManager().callEvent(accessEvent); if (accessEvent.isCancelled()) { P.p.msg(player, P.p.languageReader.get("Error_NoBarrelAccess")); diff --git a/src/com/dre/brewery/Brew.java b/src/com/dre/brewery/Brew.java index 95c41dc..973e9a8 100644 --- a/src/com/dre/brewery/Brew.java +++ b/src/com/dre/brewery/Brew.java @@ -46,6 +46,7 @@ public class Brew { public Brew(BIngredients ingredients) { this.ingredients = ingredients; + touch(); } // quality already set @@ -53,6 +54,7 @@ public class Brew { this.ingredients = ingredients; this.quality = quality; this.currentRecipe = recipe; + touch(); } // loading with all values set diff --git a/src/com/dre/brewery/P.java b/src/com/dre/brewery/P.java index 53098ca..097fc15 100644 --- a/src/com/dre/brewery/P.java +++ b/src/com/dre/brewery/P.java @@ -577,7 +577,6 @@ public class P extends JavaPlugin { // Third-Party useWG = config.getBoolean("useWorldGuard", true) && getServer().getPluginManager().isPluginEnabled("WorldGuard"); - hasVault = getServer().getPluginManager().isPluginEnabled("Vault"); if (useWG) { Plugin plugin = Bukkit.getPluginManager().getPlugin("WorldEdit"); @@ -709,7 +708,6 @@ public class P extends JavaPlugin { FileConfiguration data = YamlConfiguration.loadConfiguration(file); Brew.installTime = data.getLong("installTime", System.currentTimeMillis()); - MCBarrel.mcBarrelTime = data.getLong("MCBarrelTime", 0); Brew.loadSeed(data); diff --git a/src/com/dre/brewery/filedata/DataSave.java b/src/com/dre/brewery/filedata/DataSave.java index 496bdba..8a63842 100644 --- a/src/com/dre/brewery/filedata/DataSave.java +++ b/src/com/dre/brewery/filedata/DataSave.java @@ -62,7 +62,6 @@ public class DataSave extends BukkitRunnable { FileConfiguration configFile = new YamlConfiguration(); configFile.set("installTime", Brew.installTime); - configFile.set("MCBarrelTime", MCBarrel.mcBarrelTime); Brew.writeSeed(configFile); From b761e838828905ea11dd044e8d51fb6e09fe23f1 Mon Sep 17 00:00:00 2001 From: Sn0wStorm Date: Sat, 12 Oct 2019 16:07:02 +0200 Subject: [PATCH 18/51] More features for BrewModifyEvent --- src/com/dre/brewery/BIngredients.java | 7 ++- src/com/dre/brewery/BPlayer.java | 5 +- src/com/dre/brewery/BRecipe.java | 10 ++++ src/com/dre/brewery/Brew.java | 16 ++++-- ...fyEvent.java => BrewBeginModifyEvent.java} | 16 +++--- .../api/events/brew/BrewDrinkEvent.java | 9 ++-- .../brewery/api/events/brew/BrewEvent.java | 10 +++- .../api/events/brew/BrewModifiedEvent.java | 50 +++++++++++++++++++ .../brewery/listeners/CommandListener.java | 25 +++++++--- .../dre/brewery/listeners/PlayerListener.java | 2 +- 10 files changed, 116 insertions(+), 34 deletions(-) rename src/com/dre/brewery/api/events/brew/{BrewModifyEvent.java => BrewBeginModifyEvent.java} (72%) create mode 100644 src/com/dre/brewery/api/events/brew/BrewModifiedEvent.java diff --git a/src/com/dre/brewery/BIngredients.java b/src/com/dre/brewery/BIngredients.java index c8b40ed..f887e89 100644 --- a/src/com/dre/brewery/BIngredients.java +++ b/src/com/dre/brewery/BIngredients.java @@ -1,6 +1,7 @@ package com.dre.brewery; -import com.dre.brewery.api.events.brew.BrewModifyEvent; +import com.dre.brewery.api.events.brew.BrewBeginModifyEvent; +import com.dre.brewery.api.events.brew.BrewModifiedEvent; import com.dre.brewery.lore.BrewLore; import org.bukkit.Material; import org.bukkit.configuration.ConfigurationSection; @@ -121,7 +122,7 @@ public class BIngredients { cookedName = P.p.languageReader.get("Brew_Undefined"); Brew.PotionColor.CYAN.colorBrew(potionMeta, potion, true); } - BrewModifyEvent modifyEvent = new BrewModifyEvent(brew, BrewModifyEvent.Type.FILL); + BrewBeginModifyEvent modifyEvent = new BrewBeginModifyEvent(brew, potionMeta, BrewBeginModifyEvent.Type.FILL); P.p.getServer().getPluginManager().callEvent(modifyEvent); if (modifyEvent.isCancelled()) { return null; @@ -137,6 +138,8 @@ public class BIngredients { //potionMeta.addCustomEffect((PotionEffectType.REGENERATION).createEffect((uid * 4), 0), true); brew.touch(); + BrewModifiedEvent modifiedEvent = new BrewModifiedEvent(brew, potionMeta, BrewModifiedEvent.Type.FILL); + P.p.getServer().getPluginManager().callEvent(modifiedEvent); brew.save(potionMeta); potion.setItemMeta(potionMeta); diff --git a/src/com/dre/brewery/BPlayer.java b/src/com/dre/brewery/BPlayer.java index eaccc2a..28c6e24 100644 --- a/src/com/dre/brewery/BPlayer.java +++ b/src/com/dre/brewery/BPlayer.java @@ -15,6 +15,7 @@ import org.bukkit.entity.Item; import org.bukkit.entity.Player; import org.bukkit.event.player.PlayerMoveEvent; import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.meta.ItemMeta; import org.bukkit.potion.PotionEffect; import org.bukkit.potion.PotionEffectType; import org.bukkit.util.Vector; @@ -144,12 +145,12 @@ public class BPlayer { } // Drink a brew and apply effects, etc. - public static boolean drink(Brew brew, Player player) { + public static boolean drink(Brew brew, ItemMeta meta, Player player) { BPlayer bPlayer = get(player); if (bPlayer == null) { bPlayer = addPlayer(player); } - BrewDrinkEvent drinkEvent = new BrewDrinkEvent(brew, player, bPlayer); + BrewDrinkEvent drinkEvent = new BrewDrinkEvent(brew, meta, player, bPlayer); P.p.getServer().getPluginManager().callEvent(drinkEvent); if (drinkEvent.isCancelled()) { if (bPlayer.drunkeness <= 0) { diff --git a/src/com/dre/brewery/BRecipe.java b/src/com/dre/brewery/BRecipe.java index 9c58cb0..35d01f1 100644 --- a/src/com/dre/brewery/BRecipe.java +++ b/src/com/dre/brewery/BRecipe.java @@ -1,5 +1,7 @@ package com.dre.brewery; +import com.dre.brewery.api.events.brew.BrewBeginModifyEvent; +import com.dre.brewery.api.events.brew.BrewModifiedEvent; import com.dre.brewery.lore.BrewLore; import org.bukkit.Material; import org.bukkit.configuration.ConfigurationSection; @@ -255,6 +257,12 @@ public class BRecipe { Brew brew = createBrew(quality); + BrewBeginModifyEvent modifyEvent = new BrewBeginModifyEvent(brew, potionMeta, BrewBeginModifyEvent.Type.CREATE); + P.p.getServer().getPluginManager().callEvent(modifyEvent); + if (modifyEvent.isCancelled()) { + return null; + } + Brew.PotionColor.fromString(getColor()).colorBrew(potionMeta, potion, false); potionMeta.setDisplayName(P.p.color("&f" + getName(quality))); //if (!P.use1_14) { @@ -269,6 +277,8 @@ public class BRecipe { lore.convertLore(false); lore.addOrReplaceEffects(effects, quality); lore.write(); + BrewModifiedEvent modifiedEvent = new BrewModifiedEvent(brew, potionMeta, BrewModifiedEvent.Type.CREATE); + P.p.getServer().getPluginManager().callEvent(modifiedEvent); brew.touch(); brew.save(potionMeta); diff --git a/src/com/dre/brewery/Brew.java b/src/com/dre/brewery/Brew.java index 973e9a8..c6db994 100644 --- a/src/com/dre/brewery/Brew.java +++ b/src/com/dre/brewery/Brew.java @@ -1,6 +1,7 @@ package com.dre.brewery; -import com.dre.brewery.api.events.brew.BrewModifyEvent; +import com.dre.brewery.api.events.brew.BrewBeginModifyEvent; +import com.dre.brewery.api.events.brew.BrewModifiedEvent; import com.dre.brewery.lore.*; import org.bukkit.Color; import org.bukkit.Material; @@ -22,7 +23,9 @@ import java.security.InvalidKeyException; import java.security.SecureRandom; import java.util.ArrayList; import java.util.HashMap; +import java.util.List; import java.util.Map; +import java.util.function.BiConsumer; public class Brew { @@ -464,8 +467,7 @@ public class Brew { // distill custom potion in given slot public void distillSlot(ItemStack slotItem, PotionMeta potionMeta) { if (immutable) return; - //List> fcts = new ArrayList<>(); - BrewModifyEvent modifyEvent = new BrewModifyEvent(this, BrewModifyEvent.Type.DISTILL); + BrewBeginModifyEvent modifyEvent = new BrewBeginModifyEvent(this, potionMeta, BrewBeginModifyEvent.Type.DISTILL); P.p.getServer().getPluginManager().callEvent(modifyEvent); if (modifyEvent.isCancelled()) return; @@ -497,6 +499,8 @@ public class Brew { lore.updateDistillLore(colorInBrewer); lore.write(); touch(); + BrewModifiedEvent modifiedEvent = new BrewModifiedEvent(this, potionMeta, BrewModifiedEvent.Type.DISTILL); + P.p.getServer().getPluginManager().callEvent(modifiedEvent); save(potionMeta); slotItem.setItemMeta(potionMeta); @@ -522,11 +526,11 @@ public class Brew { public void age(ItemStack item, float time, byte woodType) { if (immutable) return; - BrewModifyEvent modifyEvent = new BrewModifyEvent(this, BrewModifyEvent.Type.AGE); + PotionMeta potionMeta = (PotionMeta) item.getItemMeta(); + BrewBeginModifyEvent modifyEvent = new BrewBeginModifyEvent(this, potionMeta, BrewBeginModifyEvent.Type.AGE); P.p.getServer().getPluginManager().callEvent(modifyEvent); if (modifyEvent.isCancelled()) return; - PotionMeta potionMeta = (PotionMeta) item.getItemMeta(); BrewLore lore = new BrewLore(this, potionMeta); ageTime += time; @@ -569,6 +573,8 @@ public class Brew { } lore.write(); touch(); + BrewModifiedEvent modifiedEvent = new BrewModifiedEvent(this, potionMeta, BrewModifiedEvent.Type.AGE); + P.p.getServer().getPluginManager().callEvent(modifiedEvent); save(potionMeta); item.setItemMeta(potionMeta); } diff --git a/src/com/dre/brewery/api/events/brew/BrewModifyEvent.java b/src/com/dre/brewery/api/events/brew/BrewBeginModifyEvent.java similarity index 72% rename from src/com/dre/brewery/api/events/brew/BrewModifyEvent.java rename to src/com/dre/brewery/api/events/brew/BrewBeginModifyEvent.java index 01ace63..1d9297a 100644 --- a/src/com/dre/brewery/api/events/brew/BrewModifyEvent.java +++ b/src/com/dre/brewery/api/events/brew/BrewBeginModifyEvent.java @@ -3,19 +3,19 @@ package com.dre.brewery.api.events.brew; import com.dre.brewery.Brew; import org.bukkit.event.Cancellable; import org.bukkit.event.HandlerList; +import org.bukkit.inventory.meta.ItemMeta; /* - * A Brew is created or modified + * A Brew is starting to be created or modified * Usually happens on Filling from cauldron, distilling and aging. */ -public class BrewModifyEvent extends BrewEvent implements Cancellable { +public class BrewBeginModifyEvent extends BrewEvent implements Cancellable { private static final HandlerList handlers = new HandlerList(); private final Type type; private boolean cancelled; - //private List> fcts; - public BrewModifyEvent(Brew brew, Type type) { - super(brew); + public BrewBeginModifyEvent(Brew brew, ItemMeta meta, Type type) { + super(brew, meta); this.type = type; } @@ -23,10 +23,6 @@ public class BrewModifyEvent extends BrewEvent implements Cancellable { return type; } - /*public void addModification(Consumer predicate) { - fcts.add(predicate); - }*/ - @Override public boolean isCancelled() { return cancelled; @@ -47,7 +43,7 @@ public class BrewModifyEvent extends BrewEvent implements Cancellable { } public enum Type { - //CREATE, // A new Brew is created with arbitrary ways, like the create command + CREATE, // A new Brew is created with arbitrary ways, like the create command FILL, // Filled from a Cauldron into a new Brew DISTILL, // Distilled in the Brewing stand AGE, // Aged in a Barrel diff --git a/src/com/dre/brewery/api/events/brew/BrewDrinkEvent.java b/src/com/dre/brewery/api/events/brew/BrewDrinkEvent.java index c0b06bc..bbc526b 100644 --- a/src/com/dre/brewery/api/events/brew/BrewDrinkEvent.java +++ b/src/com/dre/brewery/api/events/brew/BrewDrinkEvent.java @@ -1,14 +1,11 @@ package com.dre.brewery.api.events.brew; -import com.dre.brewery.BEffect; import com.dre.brewery.BPlayer; import com.dre.brewery.Brew; import org.bukkit.entity.Player; import org.bukkit.event.Cancellable; import org.bukkit.event.HandlerList; -import org.bukkit.potion.PotionEffect; - -import java.util.List; +import org.bukkit.inventory.meta.ItemMeta; /* * A Player Drinks a Brew @@ -23,8 +20,8 @@ public class BrewDrinkEvent extends BrewEvent implements Cancellable { private int quality; private boolean cancelled; - public BrewDrinkEvent(Brew brew, Player player, BPlayer bPlayer) { - super(brew); + public BrewDrinkEvent(Brew brew, ItemMeta meta, Player player, BPlayer bPlayer) { + super(brew, meta); this.player = player; this.bPlayer = bPlayer; alc = brew.calcAlcohol(); diff --git a/src/com/dre/brewery/api/events/brew/BrewEvent.java b/src/com/dre/brewery/api/events/brew/BrewEvent.java index e509af7..e3ccd53 100644 --- a/src/com/dre/brewery/api/events/brew/BrewEvent.java +++ b/src/com/dre/brewery/api/events/brew/BrewEvent.java @@ -2,16 +2,22 @@ package com.dre.brewery.api.events.brew; import com.dre.brewery.Brew; import org.bukkit.event.Event; -import org.bukkit.event.HandlerList; +import org.bukkit.inventory.meta.ItemMeta; public abstract class BrewEvent extends Event { protected final Brew brew; + protected final ItemMeta meta; - public BrewEvent(Brew brew) { + public BrewEvent(Brew brew, ItemMeta meta) { this.brew = brew; + this.meta = meta; } public Brew getBrew() { return brew; } + + public ItemMeta getItemMeta() { + return meta; + } } diff --git a/src/com/dre/brewery/api/events/brew/BrewModifiedEvent.java b/src/com/dre/brewery/api/events/brew/BrewModifiedEvent.java new file mode 100644 index 0000000..f624395 --- /dev/null +++ b/src/com/dre/brewery/api/events/brew/BrewModifiedEvent.java @@ -0,0 +1,50 @@ +package com.dre.brewery.api.events.brew; + +import com.dre.brewery.Brew; +import com.dre.brewery.lore.BrewLore; +import org.bukkit.event.HandlerList; +import org.bukkit.inventory.meta.ItemMeta; +import org.bukkit.inventory.meta.PotionMeta; + +/* + * A Brew has been created or modified + * Usually happens on Filling from cauldron, distilling and aging. + * Final Modifications to the Brew or the PotionMeta can be done now + */ +public class BrewModifiedEvent extends BrewEvent { + private static final HandlerList handlers = new HandlerList(); + private final Type type; + + + public BrewModifiedEvent(Brew brew, ItemMeta meta, Type type) { + super(brew, meta); + this.type = type; + } + + public Type getType() { + return type; + } + + public BrewLore getLore() { + return new BrewLore(getBrew(), (PotionMeta) getItemMeta()); + } + + @Override + public HandlerList getHandlers() { + return handlers; + } + + public static HandlerList getHandlerList() { + return handlers; + } + + public enum Type { + CREATE, // A new Brew is created with arbitrary ways, like the create command + FILL, // Filled from a Cauldron into a new Brew + DISTILL, // Distilled in the Brewing stand + AGE, // Aged in a Barrel + UNLABEL, // Unlabeling Brew with command + STATIC, // Making Brew static with command + UNKNOWN // Unknown modification, unused + } +} diff --git a/src/com/dre/brewery/listeners/CommandListener.java b/src/com/dre/brewery/listeners/CommandListener.java index feee66e..535953f 100644 --- a/src/com/dre/brewery/listeners/CommandListener.java +++ b/src/com/dre/brewery/listeners/CommandListener.java @@ -1,13 +1,15 @@ package com.dre.brewery.listeners; import com.dre.brewery.*; -import com.dre.brewery.api.events.brew.BrewModifyEvent; +import com.dre.brewery.api.events.brew.BrewBeginModifyEvent; +import com.dre.brewery.api.events.brew.BrewModifiedEvent; import org.bukkit.Material; import org.bukkit.command.Command; import org.bukkit.command.CommandExecutor; import org.bukkit.command.CommandSender; import org.bukkit.entity.Player; import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.meta.ItemMeta; import java.util.ArrayList; import java.util.Locale; @@ -478,7 +480,8 @@ public class CommandListener implements CommandExecutor { if (hand != null) { Brew brew = Brew.get(hand); if (brew != null) { - BrewModifyEvent modifyEvent = new BrewModifyEvent(brew, BrewModifyEvent.Type.STATIC); + ItemMeta meta = hand.getItemMeta(); + BrewBeginModifyEvent modifyEvent = new BrewBeginModifyEvent(brew, meta, BrewBeginModifyEvent.Type.STATIC); P.p.getServer().getPluginManager().callEvent(modifyEvent); if (modifyEvent.isCancelled()) { return; @@ -495,7 +498,10 @@ public class CommandListener implements CommandExecutor { p.msg(sender, p.languageReader.get("CMD_Static")); } brew.touch(); - brew.save(hand); + BrewModifiedEvent modifiedEvent = new BrewModifiedEvent(brew, meta, BrewModifiedEvent.Type.STATIC); + P.p.getServer().getPluginManager().callEvent(modifiedEvent); + brew.save(meta); + hand.setItemMeta(meta); return; } } @@ -515,14 +521,18 @@ public class CommandListener implements CommandExecutor { if (hand != null) { Brew brew = Brew.get(hand); if (brew != null) { - BrewModifyEvent modifyEvent = new BrewModifyEvent(brew, BrewModifyEvent.Type.UNLABEL); + ItemMeta meta = hand.getItemMeta(); + BrewBeginModifyEvent modifyEvent = new BrewBeginModifyEvent(brew, meta, BrewBeginModifyEvent.Type.UNLABEL); P.p.getServer().getPluginManager().callEvent(modifyEvent); if (modifyEvent.isCancelled()) { return; } brew.unLabel(hand); brew.touch(); - brew.save(hand); + BrewModifiedEvent modifiedEvent = new BrewModifiedEvent(brew, meta, BrewModifiedEvent.Type.UNLABEL); + P.p.getServer().getPluginManager().callEvent(modifiedEvent); + brew.save(meta); + hand.setItemMeta(meta); p.msg(sender, p.languageReader.get("CMD_UnLabel")); return; } @@ -602,7 +612,10 @@ public class CommandListener implements CommandExecutor { } } if (recipe != null) { - player.getInventory().addItem(recipe.create(quality)); + ItemStack item = recipe.create(quality); + if (item != null) { + player.getInventory().addItem(item); + } } else { p.msg(sender, p.languageReader.get("Error_NoBrewName", name)); } diff --git a/src/com/dre/brewery/listeners/PlayerListener.java b/src/com/dre/brewery/listeners/PlayerListener.java index 8146585..6e6816a 100644 --- a/src/com/dre/brewery/listeners/PlayerListener.java +++ b/src/com/dre/brewery/listeners/PlayerListener.java @@ -256,7 +256,7 @@ public class PlayerListener implements Listener { if (item.getType() == Material.POTION) { Brew brew = Brew.get(item); if (brew != null) { - if (!BPlayer.drink(brew, player)) { + if (!BPlayer.drink(brew, item.getItemMeta(), player)) { event.setCancelled(true); return; } From 595df50ca587d869310110f722a6fd15e2cb5d2e Mon Sep 17 00:00:00 2001 From: Sn0wStorm Date: Mon, 14 Oct 2019 21:02:59 +0200 Subject: [PATCH 19/51] We only need one ModifyEvent Move PotionColor into its own Class --- src/com/dre/brewery/BIngredients.java | 23 +- src/com/dre/brewery/BRecipe.java | 84 +++----- src/com/dre/brewery/BUtil.java | 91 +++++--- src/com/dre/brewery/Brew.java | 197 +++++++----------- src/com/dre/brewery/PotionColor.java | 102 +++++++++ .../api/events/brew/BrewModifiedEvent.java | 50 ----- ...nModifyEvent.java => BrewModifyEvent.java} | 19 +- .../brewery/listeners/CommandListener.java | 33 ++- .../dre/brewery/listeners/EntityListener.java | 2 + 9 files changed, 315 insertions(+), 286 deletions(-) create mode 100644 src/com/dre/brewery/PotionColor.java delete mode 100644 src/com/dre/brewery/api/events/brew/BrewModifiedEvent.java rename src/com/dre/brewery/api/events/brew/{BrewBeginModifyEvent.java => BrewModifyEvent.java} (64%) diff --git a/src/com/dre/brewery/BIngredients.java b/src/com/dre/brewery/BIngredients.java index f887e89..8eca978 100644 --- a/src/com/dre/brewery/BIngredients.java +++ b/src/com/dre/brewery/BIngredients.java @@ -1,7 +1,6 @@ package com.dre.brewery; -import com.dre.brewery.api.events.brew.BrewBeginModifyEvent; -import com.dre.brewery.api.events.brew.BrewModifiedEvent; +import com.dre.brewery.api.events.brew.BrewModifyEvent; import com.dre.brewery.lore.BrewLore; import org.bukkit.Material; import org.bukkit.configuration.ConfigurationSection; @@ -96,7 +95,7 @@ public class BIngredients { lore.addOrReplaceEffects(brew.getEffects(), brew.getQuality()); cookedName = cookRecipe.getName(quality); - Brew.PotionColor.fromString(cookRecipe.getColor()).colorBrew(potionMeta, potion, false); + PotionColor.fromString(cookRecipe.getColor()).colorBrew(potionMeta, potion, false); } else { // new base potion @@ -104,14 +103,14 @@ public class BIngredients { if (state <= 1) { cookedName = P.p.languageReader.get("Brew_ThickBrew"); - Brew.PotionColor.BLUE.colorBrew(potionMeta, potion, false); + PotionColor.BLUE.colorBrew(potionMeta, potion, false); } else { for (Material ingredient : materials.keySet()) { if (cookedNames.containsKey(ingredient)) { // if more than half of the ingredients is of one kind if (materials.get(ingredient) > (getIngredientsCount() / 2)) { cookedName = cookedNames.get(ingredient); - Brew.PotionColor.CYAN.colorBrew(potionMeta, potion, true); + PotionColor.CYAN.colorBrew(potionMeta, potion, true); } } } @@ -120,12 +119,7 @@ public class BIngredients { if (cookedName == null) { // if no name could be found cookedName = P.p.languageReader.get("Brew_Undefined"); - Brew.PotionColor.CYAN.colorBrew(potionMeta, potion, true); - } - BrewBeginModifyEvent modifyEvent = new BrewBeginModifyEvent(brew, potionMeta, BrewBeginModifyEvent.Type.FILL); - P.p.getServer().getPluginManager().callEvent(modifyEvent); - if (modifyEvent.isCancelled()) { - return null; + PotionColor.CYAN.colorBrew(potionMeta, potion, true); } potionMeta.setDisplayName(P.p.color("&f" + cookedName)); @@ -138,8 +132,11 @@ public class BIngredients { //potionMeta.addCustomEffect((PotionEffectType.REGENERATION).createEffect((uid * 4), 0), true); brew.touch(); - BrewModifiedEvent modifiedEvent = new BrewModifiedEvent(brew, potionMeta, BrewModifiedEvent.Type.FILL); - P.p.getServer().getPluginManager().callEvent(modifiedEvent); + BrewModifyEvent modifyEvent = new BrewModifyEvent(brew, potionMeta, BrewModifyEvent.Type.FILL); + P.p.getServer().getPluginManager().callEvent(modifyEvent); + if (modifyEvent.isCancelled()) { + return null; + } brew.save(potionMeta); potion.setItemMeta(potionMeta); diff --git a/src/com/dre/brewery/BRecipe.java b/src/com/dre/brewery/BRecipe.java index 35d01f1..b764ceb 100644 --- a/src/com/dre/brewery/BRecipe.java +++ b/src/com/dre/brewery/BRecipe.java @@ -1,15 +1,10 @@ package com.dre.brewery; -import com.dre.brewery.api.events.brew.BrewBeginModifyEvent; -import com.dre.brewery.api.events.brew.BrewModifiedEvent; -import com.dre.brewery.lore.BrewLore; import org.bukkit.Material; import org.bukkit.configuration.ConfigurationSection; import org.bukkit.inventory.ItemStack; -import org.bukkit.inventory.meta.PotionMeta; import java.util.ArrayList; -import java.util.Arrays; import java.util.List; public class BRecipe { @@ -113,7 +108,7 @@ public class BRecipe { if (effect.isValid()) { effects.add(effect); } else { - P.p.errorLog("Error adding Effect to Recipe: " + getName(5)); + P.p.errorLog("Error adding Effect to Recipe: " + getRecipeName()); } } } @@ -125,45 +120,45 @@ public class BRecipe { P.p.errorLog("Recipe Name missing or invalid!"); return false; } - if (getName(5) == null || getName(5).length() < 1) { + if (getRecipeName() == null || getRecipeName().length() < 1) { P.p.errorLog("Recipe Name invalid"); return false; } if (ingredients == null || ingredients.isEmpty()) { - P.p.errorLog("No ingredients could be loaded for Recipe: " + getName(5)); + P.p.errorLog("No ingredients could be loaded for Recipe: " + getRecipeName()); return false; } if (cookingTime < 1) { - P.p.errorLog("Invalid cooking time '" + cookingTime + "' in Recipe: " + getName(5)); + P.p.errorLog("Invalid cooking time '" + cookingTime + "' in Recipe: " + getRecipeName()); return false; } if (distillruns < 0) { - P.p.errorLog("Invalid distillruns '" + distillruns + "' in Recipe: " + getName(5)); + P.p.errorLog("Invalid distillruns '" + distillruns + "' in Recipe: " + getRecipeName()); return false; } if (distillTime < 0) { - P.p.errorLog("Invalid distilltime '" + distillTime + "' in Recipe: " + getName(5)); + P.p.errorLog("Invalid distilltime '" + distillTime + "' in Recipe: " + getRecipeName()); return false; } if (wood < 0 || wood > 6) { - P.p.errorLog("Invalid wood type '" + wood + "' in Recipe: " + getName(5)); + P.p.errorLog("Invalid wood type '" + wood + "' in Recipe: " + getRecipeName()); return false; } if (age < 0) { - P.p.errorLog("Invalid age time '" + age + "' in Recipe: " + getName(5)); + P.p.errorLog("Invalid age time '" + age + "' in Recipe: " + getRecipeName()); return false; } String c = getColor(); - if (!c.equals("WATER") && Brew.PotionColor.fromString(c) == Brew.PotionColor.WATER) { - P.p.errorLog("Invalid Color '" + color + "' in Recipe: " + getName(5)); + if (!c.equals("WATER") && PotionColor.fromString(c) == PotionColor.WATER) { + P.p.errorLog("Invalid Color '" + color + "' in Recipe: " + getRecipeName()); return false; } if (difficulty < 0 || difficulty > 10) { - P.p.errorLog("Invalid difficulty '" + difficulty + "' in Recipe: " + getName(5)); + P.p.errorLog("Invalid difficulty '" + difficulty + "' in Recipe: " + getRecipeName()); return false; } if (alcohol < 0) { - P.p.errorLog("Invalid alcohol '" + alcohol + "' in Recipe: " + getName(5)); + P.p.errorLog("Invalid alcohol '" + alcohol + "' in Recipe: " + getRecipeName()); return false; } return true; @@ -250,42 +245,20 @@ public class BRecipe { return recipeItem.getDurability() == -1 || recipeItem.getDurability() == usedItem.getDurability(); } - // Create a Potion from this Recipe with best values. Quality can be set, but will reset to 10 if put in a barrel + /** + * Create a Potion from this Recipe with best values. Quality can be set, but will reset to 10 if put in a barrel + * @param quality The Quality of the Brew + * @return The Created Item + */ public ItemStack create(int quality) { - ItemStack potion = new ItemStack(Material.POTION); - PotionMeta potionMeta = (PotionMeta) potion.getItemMeta(); - - Brew brew = createBrew(quality); - - BrewBeginModifyEvent modifyEvent = new BrewBeginModifyEvent(brew, potionMeta, BrewBeginModifyEvent.Type.CREATE); - P.p.getServer().getPluginManager().callEvent(modifyEvent); - if (modifyEvent.isCancelled()) { - return null; - } - - Brew.PotionColor.fromString(getColor()).colorBrew(potionMeta, potion, false); - potionMeta.setDisplayName(P.p.color("&f" + getName(quality))); - //if (!P.use1_14) { - // Before 1.14 the effects duration would strangely be only a quarter of what we tell it to be - // This is due to the Duration Modifier, that is removed in 1.14 - // uid *= 4; - //} - // This effect stores the UID in its Duration - //potionMeta.addCustomEffect((PotionEffectType.REGENERATION).createEffect((uid * 4), 0), true); - - BrewLore lore = new BrewLore(brew, potionMeta); - lore.convertLore(false); - lore.addOrReplaceEffects(effects, quality); - lore.write(); - BrewModifiedEvent modifiedEvent = new BrewModifiedEvent(brew, potionMeta, BrewModifiedEvent.Type.CREATE); - P.p.getServer().getPluginManager().callEvent(modifiedEvent); - brew.touch(); - brew.save(potionMeta); - - potion.setItemMeta(potionMeta); - return potion; + return createBrew(quality).createItem(this); } + /** + * Create a Brew from this Recipe with best values. Quality can be set, but will reset to 10 if put in a barrel + * @param quality The Quality of the Brew + * @return The created Brew + */ public Brew createBrew(int quality) { ArrayList list = new ArrayList<>(ingredients.size()); for (ItemStack item : ingredients) { @@ -298,7 +271,7 @@ public class BRecipe { BIngredients bIngredients = new BIngredients(list, cookingTime); - return new Brew(bIngredients, quality, distillruns, getAge(), wood, getName(5), false, true, 0); + return new Brew(bIngredients, quality, distillruns, getAge(), wood, getRecipeName(), false, true, 0); } @@ -314,6 +287,11 @@ public class BRecipe { return 0; } + // Same as getName(5) + public String getRecipeName() { + return getName(5); + } + // name that fits the quality public String getName(int quality) { if (name.length > 2) { @@ -381,12 +359,12 @@ public class BRecipe { @Override public String toString() { - return "BRecipe{" + getName(5) + '}'; + return "BRecipe{" + getRecipeName() + '}'; } public static BRecipe get(String name) { for (BRecipe recipe : BIngredients.recipes) { - if (recipe.getName(5).equalsIgnoreCase(name)) { + if (recipe.getRecipeName().equalsIgnoreCase(name)) { return recipe; } } diff --git a/src/com/dre/brewery/BUtil.java b/src/com/dre/brewery/BUtil.java index df62db1..84ff2f3 100644 --- a/src/com/dre/brewery/BUtil.java +++ b/src/com/dre/brewery/BUtil.java @@ -24,13 +24,15 @@ import java.util.UUID; public class BUtil { - /******************************************/ - /********** **********/ - /********** Bukkit Utils **********/ - /********** **********/ - /******************************************/ + /* **************************************** */ + /* ********* ********* */ + /* ********* Bukkit Utils ********* */ + /* ********* ********* */ + /* **************************************** */ - // Check if the Chunk of a Block is loaded !without loading it in the process! + /** + * Check if the Chunk of a Block is loaded !without loading it in the process! + */ public static boolean isChunkLoaded(Block block) { return block.getWorld().isChunkLoaded(block.getX() >> 4, block.getZ() >> 4); } @@ -42,7 +44,9 @@ public class BUtil { return msg; } - // Returns either uuid or Name of player, depending on bukkit version + /** + * Returns either uuid or Name of player, depending on bukkit version + */ public static String playerString(Player player) { if (P.useUUID) { return player.getUniqueId().toString(); @@ -63,8 +67,11 @@ public class BUtil { return Bukkit.getPlayerExact(name); } - // Apply a Potion Effect, if player already has this effect, overwrite the existing effect. - // Optionally only overwrite if the new one is stronger, i.e. has higher level or longer duration + /** + * Apply a Potion Effect, if player already has this effect, overwrite the existing effect. + * + * @param onlyIfStronger Optionally only overwrite if the new one is stronger, i.e. has higher level or longer duration + */ public static void reapplyPotionEffect(Player player, PotionEffect effect, boolean onlyIfStronger) { final PotionEffectType type = effect.getType(); if (player.hasPotionEffect(type)) { @@ -74,7 +81,9 @@ public class BUtil { } else { plEffect = player.getActivePotionEffects().stream().filter(e -> e.getType().equals(type)).findAny().get(); } - if (plEffect.getAmplifier() < effect.getAmplifier() || (plEffect.getAmplifier() == effect.getAmplifier() && plEffect.getDuration() < effect.getDuration())) { + if (!onlyIfStronger || + plEffect.getAmplifier() < effect.getAmplifier() || + (plEffect.getAmplifier() == effect.getAmplifier() && plEffect.getDuration() < effect.getDuration())) { player.removePotionEffect(type); } else { return; @@ -83,13 +92,18 @@ public class BUtil { effect.apply(player); } - /******************************************/ - /********** **********/ - /********** String Utils **********/ - /********** **********/ - /******************************************/ + /* **************************************** */ + /* ********* ********* */ + /* ********* String Utils ********* */ + /* ********* ********* */ + /* **************************************** */ - // Returns the Index of a String from the list that contains this substring + /** + * Returns the Index of a String from the list that contains this substring + * + * @param list The List in which to search for a substring + * @param substring Part of the String to search for in each of list + */ public static int indexOfSubstring(List list, String substring) { if (list.isEmpty()) return -1; for (int index = 0, size = list.size(); index < size; index++) { @@ -101,7 +115,9 @@ public class BUtil { return -1; } - // Returns the index of a String from the list that starts with 'lineStart', returns -1 if not found; + /** + * Returns the index of a String from the list that starts with 'lineStart', returns -1 if not found; + */ public static int indexOfStart(List list, String lineStart) { for (int i = 0, size = list.size(); i < size; i++) { if (list.get(i).startsWith(lineStart)) { @@ -111,13 +127,15 @@ public class BUtil { return -1; } - /******************************************/ - /********** **********/ - /********** Brewery Utils **********/ - /********** **********/ - /******************************************/ + /* **************************************** */ + /* ********* ********* */ + /* ********* Brewery Utils ********* */ + /* ********* ********* */ + /* **************************************** */ - // create empty World save Sections + /** + * create empty World save Sections + */ public static void createWorldSections(ConfigurationSection section) { for (World world : P.p.getServer().getWorlds()) { String worldName = world.getName(); @@ -130,7 +148,12 @@ public class BUtil { } } - // Returns true if the Block can be destroyed by the Player or something else (null) + /** + * Returns true if the Block can be destroyed by the Player or something else (null) + * + * @param player The Player that destroyed a Block, Null if no Player involved + * @return True if the Block can be destroyed + */ public static boolean blockDestroy(Block block, Player player, BarrelDestroyEvent.Reason reason) { Material type = block.getType(); if (type == Material.CAULDRON) { @@ -181,13 +204,17 @@ public class BUtil { return true; } - /******************************************/ - /********** **********/ - /********** Other Utils **********/ - /********** **********/ - /******************************************/ + /* **************************************** */ + /* ********* ********* */ + /* ********* Other Utils ********* */ + /* ********* ********* */ + /* **************************************** */ - // prints a list of Strings at the specified page + /** + * prints a list of Strings at the specified page + * + * @param sender The CommandSender to send the Page to + */ public static void list(CommandSender sender, ArrayList strings, int page) { int pages = (int) Math.ceil(strings.size() / 7F); if (page > pages || page < 1) { @@ -207,7 +234,9 @@ public class BUtil { } } - // gets the Name of a DXL World + /** + * gets the Name of a DXL World + */ public static String getDxlName(String worldName) { File dungeonFolder = new File(worldName); if (dungeonFolder.isDirectory()) { diff --git a/src/com/dre/brewery/Brew.java b/src/com/dre/brewery/Brew.java index c6db994..9c4394d 100644 --- a/src/com/dre/brewery/Brew.java +++ b/src/com/dre/brewery/Brew.java @@ -1,20 +1,15 @@ package com.dre.brewery; -import com.dre.brewery.api.events.brew.BrewBeginModifyEvent; -import com.dre.brewery.api.events.brew.BrewModifiedEvent; +import com.dre.brewery.api.events.brew.BrewModifyEvent; import com.dre.brewery.lore.*; -import org.bukkit.Color; import org.bukkit.Material; import org.bukkit.configuration.ConfigurationSection; import org.bukkit.inventory.BrewerInventory; -import org.bukkit.inventory.ItemFlag; import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.meta.ItemMeta; import org.bukkit.inventory.meta.PotionMeta; -import org.bukkit.potion.PotionData; import org.bukkit.potion.PotionEffect; import org.bukkit.potion.PotionEffectType; -import org.bukkit.potion.PotionType; import java.io.DataInputStream; import java.io.DataOutputStream; @@ -23,9 +18,7 @@ import java.security.InvalidKeyException; import java.security.SecureRandom; import java.util.ArrayList; import java.util.HashMap; -import java.util.List; import java.util.Map; -import java.util.function.BiConsumer; public class Brew { @@ -41,7 +34,7 @@ public class Brew { private byte distillRuns; private float ageTime; private float wood; - private BRecipe currentRecipe; + private BRecipe currentRecipe; // Recipe this Brew is currently Based off. May change between modifications and is often null when not modifying private boolean unlabeled; private boolean persistent; // Only for legacy private boolean immutable; // static/immutable potions should not be changed @@ -189,7 +182,7 @@ public class Brew { currentRecipe = null; if (name != null && !name.equals("")) { for (BRecipe recipe : BIngredients.recipes) { - if (recipe.getName(5).equalsIgnoreCase(name)) { + if (recipe.getRecipeName().equalsIgnoreCase(name)) { currentRecipe = recipe; return true; } @@ -201,7 +194,7 @@ public class Brew { if (!immutable) { this.quality = calcQuality(); } - P.p.log("Brew was made from Recipe: '" + name + "' which could not be found. '" + currentRecipe.getName(5) + "' used instead!"); + P.p.log("Brew was made from Recipe: '" + name + "' which could not be found. '" + currentRecipe.getRecipeName() + "' used instead!"); return true; } else { P.p.errorLog("Brew was made from Recipe: '" + name + "' which could not be found!"); @@ -212,7 +205,7 @@ public class Brew { } public boolean reloadRecipe() { - return currentRecipe == null || setRecipeFromString(currentRecipe.getName(5)); + return currentRecipe == null || setRecipeFromString(currentRecipe.getRecipeName()); } // Copy a Brew with a new unique ID and return its item @@ -467,9 +460,6 @@ public class Brew { // distill custom potion in given slot public void distillSlot(ItemStack slotItem, PotionMeta potionMeta) { if (immutable) return; - BrewBeginModifyEvent modifyEvent = new BrewBeginModifyEvent(this, potionMeta, BrewBeginModifyEvent.Type.DISTILL); - P.p.getServer().getPluginManager().callEvent(modifyEvent); - if (modifyEvent.isCancelled()) return; distillRuns += 1; BrewLore lore = new BrewLore(this, potionMeta); @@ -499,8 +489,13 @@ public class Brew { lore.updateDistillLore(colorInBrewer); lore.write(); touch(); - BrewModifiedEvent modifiedEvent = new BrewModifiedEvent(this, potionMeta, BrewModifiedEvent.Type.DISTILL); - P.p.getServer().getPluginManager().callEvent(modifiedEvent); + BrewModifyEvent modifyEvent = new BrewModifyEvent(this, potionMeta, BrewModifyEvent.Type.DISTILL); + P.p.getServer().getPluginManager().callEvent(modifyEvent); + if (modifyEvent.isCancelled()) { + // As the brew and everything connected to it is only saved on the meta from now on, + // not saving the brew into potionMeta is enough to not change anything in case of cancel + return; + } save(potionMeta); slotItem.setItemMeta(potionMeta); @@ -527,9 +522,6 @@ public class Brew { public void age(ItemStack item, float time, byte woodType) { if (immutable) return; PotionMeta potionMeta = (PotionMeta) item.getItemMeta(); - BrewBeginModifyEvent modifyEvent = new BrewBeginModifyEvent(this, potionMeta, BrewBeginModifyEvent.Type.AGE); - P.p.getServer().getPluginManager().callEvent(modifyEvent); - if (modifyEvent.isCancelled()) return; BrewLore lore = new BrewLore(this, potionMeta); ageTime += time; @@ -573,8 +565,13 @@ public class Brew { } lore.write(); touch(); - BrewModifiedEvent modifiedEvent = new BrewModifiedEvent(this, potionMeta, BrewModifiedEvent.Type.AGE); - P.p.getServer().getPluginManager().callEvent(modifiedEvent); + BrewModifyEvent modifyEvent = new BrewModifyEvent(this, potionMeta, BrewModifyEvent.Type.AGE); + P.p.getServer().getPluginManager().callEvent(modifyEvent); + if (modifyEvent.isCancelled()) { + // As the brew and everything connected to it is only saved on the meta from now on, + // not saving the brew into potionMeta is enough to not change anything in case of cancel + return; + } save(potionMeta); item.setItemMeta(potionMeta); } @@ -601,6 +598,60 @@ public class Brew { } } + /** + * Create a new Item of this Brew. A BrewModifyEvent type CREATE will be called. + * + * @param recipe Recipe is required if the brew doesn't have a currentRecipe + * @return The created Item, null if the Event is cancelled + */ + public ItemStack createItem(BRecipe recipe) { + return createItem(recipe, true); + } + + /** + * Create a new Item of this Brew. + * + * @param recipe Recipe is required if the brew doesn't have a currentRecipe + * @param event Set event to true if a BrewModifyEvent type CREATE should be called and may be cancelled. Only then may this method return null + * @return The created Item, null if the Event is cancelled + */ + public ItemStack createItem(BRecipe recipe, boolean event) { + if (recipe == null) { + recipe = getCurrentRecipe(); + } + if (recipe == null) { + throw new IllegalArgumentException("Recipe can't be null if the brew doesn't have a currentRecipe"); + } + ItemStack potion = new ItemStack(Material.POTION); + PotionMeta potionMeta = (PotionMeta) potion.getItemMeta(); + + PotionColor.fromString(recipe.getColor()).colorBrew(potionMeta, potion, false); + potionMeta.setDisplayName(P.p.color("&f" + recipe.getName(quality))); + //if (!P.use1_14) { + // Before 1.14 the effects duration would strangely be only a quarter of what we tell it to be + // This is due to the Duration Modifier, that is removed in 1.14 + // uid *= 4; + //} + // This effect stores the UID in its Duration + //potionMeta.addCustomEffect((PotionEffectType.REGENERATION).createEffect((uid * 4), 0), true); + + BrewLore lore = new BrewLore(this, potionMeta); + lore.convertLore(false); + lore.addOrReplaceEffects(recipe.getEffects(), quality); + lore.write(); + touch(); + if (event) { + BrewModifyEvent modifyEvent = new BrewModifyEvent(this, potionMeta, BrewModifyEvent.Type.CREATE); + P.p.getServer().getPluginManager().callEvent(modifyEvent); + if (modifyEvent.isCancelled()) { + return null; + } + } + save(potionMeta); + potion.setItemMeta(potionMeta); + return potion; + } + private static Brew load(ItemMeta meta) { LoreLoadStream loreStream; try { @@ -715,7 +766,7 @@ public class Brew { out.writeFloat(wood); } if (currentRecipe != null) { - out.writeUTF(currentRecipe.getName(5)); + out.writeUTF(currentRecipe.getRecipeName()); } ingredients.save(out); } @@ -734,6 +785,10 @@ public class Brew { } } + public static boolean noLegacy() { + return legacyPotions.isEmpty(); + } + // 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, int lastUpdate) { Brew brew = new Brew(ingredients, quality, distillRuns, ageTime, wood, recipe, unlabeled, stat, lastUpdate); @@ -793,7 +848,7 @@ public class Brew { idConfig.set("wood", brew.wood); } if (brew.currentRecipe != null) { - idConfig.set("recipe", brew.currentRecipe.getName(5)); + idConfig.set("recipe", brew.currentRecipe.getRecipeName()); } if (brew.unlabeled) { idConfig.set("unlabeled", true); @@ -812,98 +867,4 @@ public class Brew { } } - public static class PotionColor { - public static final PotionColor PINK = new PotionColor(1, PotionType.REGEN, Color.FUCHSIA); - public static final PotionColor CYAN = new PotionColor(2, PotionType.SPEED, Color.AQUA); - public static final PotionColor ORANGE = new PotionColor(3, PotionType.FIRE_RESISTANCE, Color.ORANGE); - public static final PotionColor GREEN = new PotionColor(4, PotionType.POISON, Color.GREEN); - public static final PotionColor BRIGHT_RED = new PotionColor(5, PotionType.INSTANT_HEAL, Color.fromRGB(255,0,0)); - public static final PotionColor BLUE = new PotionColor(6, PotionType.NIGHT_VISION, Color.NAVY); - public static final PotionColor BLACK = new PotionColor(8, PotionType.WEAKNESS, Color.BLACK); - public static final PotionColor RED = new PotionColor(9, PotionType.STRENGTH, Color.fromRGB(196,0,0)); - public static final PotionColor GREY = new PotionColor(10, PotionType.SLOWNESS, Color.GRAY); - public static final PotionColor WATER = new PotionColor(11, P.use1_9 ? PotionType.WATER_BREATHING : null, Color.BLUE); - public static final PotionColor DARK_RED = new PotionColor(12, PotionType.INSTANT_DAMAGE, Color.fromRGB(128,0,0)); - public static final PotionColor BRIGHT_GREY = new PotionColor(14, PotionType.INVISIBILITY, Color.SILVER); - - private final int colorId; - private final PotionType type; - private final Color color; - - PotionColor(int colorId, PotionType type, Color color) { - this.colorId = colorId; - this.type = type; - this.color = color; - } - - public PotionColor(Color color) { - colorId = -1; - type = WATER.getType(); - this.color = color; - } - - // gets the Damage Value, that sets a color on the potion - // offset +32 is not accepted by brewer, so not further destillable - public short getColorId(boolean destillable) { - if (destillable) { - return (short) (colorId + 64); - } - return (short) (colorId + 32); - } - - public PotionType getType() { - return type; - } - - public Color getColor() { - return color; - } - - @SuppressWarnings("deprecation") - public void colorBrew(PotionMeta meta, ItemStack potion, boolean destillable) { - if (P.use1_9) { - meta.addItemFlags(ItemFlag.HIDE_POTION_EFFECTS); - if (P.use1_11) { - // BasePotionData was only used for the Color, so starting with 1.12 we can use setColor instead - meta.setColor(getColor()); - } else { - meta.setBasePotionData(new PotionData(getType())); - } - } else { - potion.setDurability(getColorId(destillable)); - } - } - - public static PotionColor fromString(String string) { - switch (string) { - case "PINK": return PINK; - case "CYAN": return CYAN; - case "ORANGE": return ORANGE; - case "GREEN": return GREEN; - case "BRIGHT_RED": return BRIGHT_RED; - case "BLUE": return BLUE; - case "BLACK": return BLACK; - case "RED": return RED; - case "GREY": return GREY; - case "WATER": return WATER; - case "DARK_RED": return DARK_RED; - case "BRIGHT_GREY": return BRIGHT_GREY; - default: - try{ - if (string.length() >= 7) { - string = string.substring(1); - } - return new PotionColor(Color.fromRGB( - Integer.parseInt(string.substring( 0, 2 ), 16 ), - Integer.parseInt(string.substring( 2, 4 ), 16 ), - Integer.parseInt(string.substring( 4, 6 ), 16 ) - )); - } catch (Exception e) { - return WATER; - } - } - } - - } - } diff --git a/src/com/dre/brewery/PotionColor.java b/src/com/dre/brewery/PotionColor.java new file mode 100644 index 0000000..8dd4359 --- /dev/null +++ b/src/com/dre/brewery/PotionColor.java @@ -0,0 +1,102 @@ +package com.dre.brewery; + +import org.bukkit.Color; +import org.bukkit.inventory.ItemFlag; +import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.meta.PotionMeta; +import org.bukkit.potion.PotionData; +import org.bukkit.potion.PotionType; + +public class PotionColor { + public static final PotionColor PINK = new PotionColor(1, PotionType.REGEN, Color.FUCHSIA); + public static final PotionColor CYAN = new PotionColor(2, PotionType.SPEED, Color.AQUA); + public static final PotionColor ORANGE = new PotionColor(3, PotionType.FIRE_RESISTANCE, Color.ORANGE); + public static final PotionColor GREEN = new PotionColor(4, PotionType.POISON, Color.GREEN); + public static final PotionColor BRIGHT_RED = new PotionColor(5, PotionType.INSTANT_HEAL, Color.fromRGB(255,0,0)); + public static final PotionColor BLUE = new PotionColor(6, PotionType.NIGHT_VISION, Color.NAVY); + public static final PotionColor BLACK = new PotionColor(8, PotionType.WEAKNESS, Color.BLACK); + public static final PotionColor RED = new PotionColor(9, PotionType.STRENGTH, Color.fromRGB(196,0,0)); + public static final PotionColor GREY = new PotionColor(10, PotionType.SLOWNESS, Color.GRAY); + public static final PotionColor WATER = new PotionColor(11, P.use1_9 ? PotionType.WATER_BREATHING : null, Color.BLUE); + public static final PotionColor DARK_RED = new PotionColor(12, PotionType.INSTANT_DAMAGE, Color.fromRGB(128,0,0)); + public static final PotionColor BRIGHT_GREY = new PotionColor(14, PotionType.INVISIBILITY, Color.SILVER); + + private final int colorId; + private final PotionType type; + private final Color color; + + PotionColor(int colorId, PotionType type, Color color) { + this.colorId = colorId; + this.type = type; + this.color = color; + } + + public PotionColor(Color color) { + colorId = -1; + type = WATER.getType(); + this.color = color; + } + + // gets the Damage Value, that sets a color on the potion + // offset +32 is not accepted by brewer, so not further destillable + public short getColorId(boolean destillable) { + if (destillable) { + return (short) (colorId + 64); + } + return (short) (colorId + 32); + } + + public PotionType getType() { + return type; + } + + public Color getColor() { + return color; + } + + @SuppressWarnings("deprecation") + public void colorBrew(PotionMeta meta, ItemStack potion, boolean destillable) { + if (P.use1_9) { + meta.addItemFlags(ItemFlag.HIDE_POTION_EFFECTS); + if (P.use1_11) { + // BasePotionData was only used for the Color, so starting with 1.12 we can use setColor instead + meta.setColor(getColor()); + } else { + meta.setBasePotionData(new PotionData(getType())); + } + } else { + potion.setDurability(getColorId(destillable)); + } + } + + public static PotionColor fromString(String string) { + switch (string) { + case "PINK": return PINK; + case "CYAN": return CYAN; + case "ORANGE": return ORANGE; + case "GREEN": return GREEN; + case "BRIGHT_RED": return BRIGHT_RED; + case "BLUE": return BLUE; + case "BLACK": return BLACK; + case "RED": return RED; + case "GREY": return GREY; + case "WATER": return WATER; + case "DARK_RED": return DARK_RED; + case "BRIGHT_GREY": return BRIGHT_GREY; + default: + try{ + if (string.length() >= 7) { + string = string.substring(1); + } + return new PotionColor(Color.fromRGB( + Integer.parseInt(string.substring( 0, 2 ), 16 ), + Integer.parseInt(string.substring( 2, 4 ), 16 ), + Integer.parseInt(string.substring( 4, 6 ), 16 ) + )); + } catch (Exception e) { + return WATER; + } + } + } + +} diff --git a/src/com/dre/brewery/api/events/brew/BrewModifiedEvent.java b/src/com/dre/brewery/api/events/brew/BrewModifiedEvent.java deleted file mode 100644 index f624395..0000000 --- a/src/com/dre/brewery/api/events/brew/BrewModifiedEvent.java +++ /dev/null @@ -1,50 +0,0 @@ -package com.dre.brewery.api.events.brew; - -import com.dre.brewery.Brew; -import com.dre.brewery.lore.BrewLore; -import org.bukkit.event.HandlerList; -import org.bukkit.inventory.meta.ItemMeta; -import org.bukkit.inventory.meta.PotionMeta; - -/* - * A Brew has been created or modified - * Usually happens on Filling from cauldron, distilling and aging. - * Final Modifications to the Brew or the PotionMeta can be done now - */ -public class BrewModifiedEvent extends BrewEvent { - private static final HandlerList handlers = new HandlerList(); - private final Type type; - - - public BrewModifiedEvent(Brew brew, ItemMeta meta, Type type) { - super(brew, meta); - this.type = type; - } - - public Type getType() { - return type; - } - - public BrewLore getLore() { - return new BrewLore(getBrew(), (PotionMeta) getItemMeta()); - } - - @Override - public HandlerList getHandlers() { - return handlers; - } - - public static HandlerList getHandlerList() { - return handlers; - } - - public enum Type { - CREATE, // A new Brew is created with arbitrary ways, like the create command - FILL, // Filled from a Cauldron into a new Brew - DISTILL, // Distilled in the Brewing stand - AGE, // Aged in a Barrel - UNLABEL, // Unlabeling Brew with command - STATIC, // Making Brew static with command - UNKNOWN // Unknown modification, unused - } -} diff --git a/src/com/dre/brewery/api/events/brew/BrewBeginModifyEvent.java b/src/com/dre/brewery/api/events/brew/BrewModifyEvent.java similarity index 64% rename from src/com/dre/brewery/api/events/brew/BrewBeginModifyEvent.java rename to src/com/dre/brewery/api/events/brew/BrewModifyEvent.java index 1d9297a..def9f4b 100644 --- a/src/com/dre/brewery/api/events/brew/BrewBeginModifyEvent.java +++ b/src/com/dre/brewery/api/events/brew/BrewModifyEvent.java @@ -1,20 +1,25 @@ package com.dre.brewery.api.events.brew; import com.dre.brewery.Brew; +import com.dre.brewery.lore.BrewLore; import org.bukkit.event.Cancellable; import org.bukkit.event.HandlerList; import org.bukkit.inventory.meta.ItemMeta; +import org.bukkit.inventory.meta.PotionMeta; /* - * A Brew is starting to be created or modified + * A Brew has been created or modified * Usually happens on Filling from cauldron, distilling and aging. + * Modifications to the Brew or the PotionMeta can be done now + * Cancelling reverts the Brew to the state it was before the modification */ -public class BrewBeginModifyEvent extends BrewEvent implements Cancellable { +public class BrewModifyEvent extends BrewEvent implements Cancellable { private static final HandlerList handlers = new HandlerList(); private final Type type; private boolean cancelled; - public BrewBeginModifyEvent(Brew brew, ItemMeta meta, Type type) { + + public BrewModifyEvent(Brew brew, ItemMeta meta, Type type) { super(brew, meta); this.type = type; } @@ -23,11 +28,19 @@ public class BrewBeginModifyEvent extends BrewEvent implements Cancellable { return type; } + public BrewLore getLore() { + return new BrewLore(getBrew(), (PotionMeta) getItemMeta()); + } + @Override public boolean isCancelled() { return cancelled; } + /* + * Setting the Event cancelled cancels all modificatons to the brew. + * Modifications to the Brew or ItemMeta will not be applied + */ @Override public void setCancelled(boolean cancelled) { this.cancelled = cancelled; diff --git a/src/com/dre/brewery/listeners/CommandListener.java b/src/com/dre/brewery/listeners/CommandListener.java index 535953f..f200c45 100644 --- a/src/com/dre/brewery/listeners/CommandListener.java +++ b/src/com/dre/brewery/listeners/CommandListener.java @@ -1,8 +1,7 @@ package com.dre.brewery.listeners; import com.dre.brewery.*; -import com.dre.brewery.api.events.brew.BrewBeginModifyEvent; -import com.dre.brewery.api.events.brew.BrewModifiedEvent; +import com.dre.brewery.api.events.brew.BrewModifyEvent; import org.bukkit.Material; import org.bukkit.command.Command; import org.bukkit.command.CommandExecutor; @@ -480,12 +479,6 @@ public class CommandListener implements CommandExecutor { if (hand != null) { Brew brew = Brew.get(hand); if (brew != null) { - ItemMeta meta = hand.getItemMeta(); - BrewBeginModifyEvent modifyEvent = new BrewBeginModifyEvent(brew, meta, BrewBeginModifyEvent.Type.STATIC); - P.p.getServer().getPluginManager().callEvent(modifyEvent); - if (modifyEvent.isCancelled()) { - return; - } if (brew.isStatic()) { if (!brew.isPersistent()) { brew.setStatic(false, hand); @@ -498,8 +491,12 @@ public class CommandListener implements CommandExecutor { p.msg(sender, p.languageReader.get("CMD_Static")); } brew.touch(); - BrewModifiedEvent modifiedEvent = new BrewModifiedEvent(brew, meta, BrewModifiedEvent.Type.STATIC); - P.p.getServer().getPluginManager().callEvent(modifiedEvent); + ItemMeta meta = hand.getItemMeta(); + BrewModifyEvent modifyEvent = new BrewModifyEvent(brew, meta, BrewModifyEvent.Type.STATIC); + P.p.getServer().getPluginManager().callEvent(modifyEvent); + if (modifyEvent.isCancelled()) { + return; + } brew.save(meta); hand.setItemMeta(meta); return; @@ -521,16 +518,16 @@ public class CommandListener implements CommandExecutor { if (hand != null) { Brew brew = Brew.get(hand); if (brew != null) { - ItemMeta meta = hand.getItemMeta(); - BrewBeginModifyEvent modifyEvent = new BrewBeginModifyEvent(brew, meta, BrewBeginModifyEvent.Type.UNLABEL); - P.p.getServer().getPluginManager().callEvent(modifyEvent); - if (modifyEvent.isCancelled()) { - return; - } + ItemMeta origMeta = hand.getItemMeta(); brew.unLabel(hand); brew.touch(); - BrewModifiedEvent modifiedEvent = new BrewModifiedEvent(brew, meta, BrewModifiedEvent.Type.UNLABEL); - P.p.getServer().getPluginManager().callEvent(modifiedEvent); + ItemMeta meta = hand.getItemMeta(); + BrewModifyEvent modifyEvent = new BrewModifyEvent(brew, meta, BrewModifyEvent.Type.UNLABEL); + P.p.getServer().getPluginManager().callEvent(modifyEvent); + if (modifyEvent.isCancelled()) { + hand.setItemMeta(origMeta); + return; + } brew.save(meta); hand.setItemMeta(meta); p.msg(sender, p.languageReader.get("CMD_UnLabel")); diff --git a/src/com/dre/brewery/listeners/EntityListener.java b/src/com/dre/brewery/listeners/EntityListener.java index d7cd084..b0ba0a4 100644 --- a/src/com/dre/brewery/listeners/EntityListener.java +++ b/src/com/dre/brewery/listeners/EntityListener.java @@ -27,6 +27,7 @@ public class EntityListener implements Listener { // Remove the Potion from Brew when it despawns @EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true) public void onItemDespawn(ItemDespawnEvent event) { + if (Brew.noLegacy()) return; ItemStack item = event.getEntity().getItemStack(); if (item.getType() == Material.POTION) { Brew.removeLegacy(item); @@ -35,6 +36,7 @@ public class EntityListener implements Listener { @EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true) public void onEntityCombust(EntityCombustEvent event) { + if (!Brew.noLegacy()) return; Entity entity = event.getEntity(); if (entity.getType() == EntityType.DROPPED_ITEM) { if (entity instanceof Item) { From 7c0dcefb1b2e9051fdc99f4f4e9fb1c2ae89d065 Mon Sep 17 00:00:00 2001 From: Sn0wStorm Date: Wed, 16 Oct 2019 17:21:04 +0200 Subject: [PATCH 20/51] Refractoring --- src/com/dre/brewery/BCauldron.java | 224 ++++++-- src/com/dre/brewery/BDistiller.java | 202 +++++++ src/com/dre/brewery/BPlayer.java | 36 +- src/com/dre/brewery/BRecipe.java | 5 +- src/com/dre/brewery/Barrel.java | 221 ++++---- src/com/dre/brewery/Brew.java | 78 ++- .../brewery/{Words.java => DistortChat.java} | 8 +- src/com/dre/brewery/MCBarrel.java | 40 +- src/com/dre/brewery/P.java | 511 +----------------- src/com/dre/brewery/Wakeup.java | 10 +- src/com/dre/brewery/filedata/BConfig.java | 257 +++++++++ src/com/dre/brewery/filedata/BData.java | 258 +++++++++ .../integration/IntegrationListener.java | 47 +- .../dre/brewery/integration/LWCBarrel.java | 8 +- .../dre/brewery/listeners/BlockListener.java | 158 +++--- .../brewery/listeners/CommandListener.java | 349 ++++++------ .../dre/brewery/listeners/EntityListener.java | 2 +- .../brewery/listeners/InventoryListener.java | 208 +------ .../dre/brewery/listeners/PlayerListener.java | 274 +++------- .../dre/brewery/listeners/WorldListener.java | 5 +- 20 files changed, 1501 insertions(+), 1400 deletions(-) create mode 100644 src/com/dre/brewery/BDistiller.java rename src/com/dre/brewery/{Words.java => DistortChat.java} (97%) create mode 100644 src/com/dre/brewery/filedata/BConfig.java create mode 100644 src/com/dre/brewery/filedata/BData.java diff --git a/src/com/dre/brewery/BCauldron.java b/src/com/dre/brewery/BCauldron.java index c0c0c5c..56c7311 100644 --- a/src/com/dre/brewery/BCauldron.java +++ b/src/com/dre/brewery/BCauldron.java @@ -9,12 +9,18 @@ import org.bukkit.block.data.BlockData; import org.bukkit.block.data.Levelled; import org.bukkit.configuration.ConfigurationSection; import org.bukkit.entity.Player; +import org.bukkit.event.player.PlayerInteractEvent; +import org.bukkit.inventory.EquipmentSlot; import org.bukkit.inventory.ItemStack; +import java.util.HashSet; +import java.util.Set; +import java.util.UUID; import java.util.concurrent.CopyOnWriteArrayList; public class BCauldron { public static final byte EMPTY = 0, SOME = 1, FULL = 2; + private static Set plInteracted = new HashSet<>(); public static CopyOnWriteArrayList bcauldrons = new CopyOnWriteArrayList<>(); // TODO find best Collection private BIngredients ingredients = new BIngredients(); @@ -95,62 +101,57 @@ public class BCauldron { } // fills players bottle with cooked brew - public static boolean fill(Player player, Block block) { - BCauldron bcauldron = get(block); - if (bcauldron != null) { - if (!player.hasPermission("brewery.cauldron.fill")) { - P.p.msg(player, P.p.languageReader.get("Perms_NoCauldronFill")); - return true; + public boolean fill(Player player, Block block) { + if (!player.hasPermission("brewery.cauldron.fill")) { + P.p.msg(player, P.p.languageReader.get("Perms_NoCauldronFill")); + return true; + } + ItemStack potion = ingredients.cook(state); + if (potion == null) return false; + + if (P.use1_13) { + BlockData data = block.getBlockData(); + Levelled cauldron = ((Levelled) data); + if (cauldron.getLevel() <= 0) { + bcauldrons.remove(this); + return false; } - ItemStack potion = bcauldron.ingredients.cook(bcauldron.state); - if (potion != null) { + cauldron.setLevel(cauldron.getLevel() - 1); + // Update the new Level to the Block + // We have to use the BlockData variable "data" here instead of the casted "cauldron" + // otherwise < 1.13 crashes on plugin load for not finding the BlockData Class + block.setBlockData(data); - if (P.use1_13) { - BlockData data = block.getBlockData(); - Levelled cauldron = ((Levelled) data); - if (cauldron.getLevel() <= 0) { - bcauldrons.remove(bcauldron); - return false; - } - cauldron.setLevel(cauldron.getLevel() - 1); - // Update the new Level to the Block - // We have to use the BlockData variable "data" here instead of the casted "cauldron" - // otherwise < 1.13 crashes on plugin load for not finding the BlockData Class - block.setBlockData(data); + if (cauldron.getLevel() <= 0) { + bcauldrons.remove(this); + } else { + someRemoved = true; + } - if (cauldron.getLevel() <= 0) { - bcauldrons.remove(bcauldron); - } else { - bcauldron.someRemoved = true; - } + } else { + byte data = block.getData(); + if (data > 3) { + data = 3; + } else if (data <= 0) { + bcauldrons.remove(this); + return false; + } + data -= 1; + LegacyUtil.setData(block, data); - } else { - byte data = block.getData(); - if (data > 3) { - data = 3; - } else if (data <= 0) { - bcauldrons.remove(bcauldron); - return false; - } - data -= 1; - LegacyUtil.setData(block, data); - - if (data == 0) { - bcauldrons.remove(bcauldron); - } else { - bcauldron.someRemoved = true; - } - } - // Bukkit Bug, inventory not updating while in event so this - // will delay the give - // but could also just use deprecated updateInventory() - giveItem(player, potion); - // player.getInventory().addItem(potion); - // player.getInventory().updateInventory(); - return true; + if (data == 0) { + bcauldrons.remove(this); + } else { + someRemoved = true; } } - return false; + // Bukkit Bug, inventory not updating while in event so this + // will delay the give + // but could also just use deprecated updateInventory() + giveItem(player, potion); + // player.getInventory().addItem(potion); + // player.getInventory().updateInventory(); + return true; } // prints the current cooking time to the player @@ -169,6 +170,129 @@ public class BCauldron { } } + public static void clickCauldron(PlayerInteractEvent event) { + Material materialInHand = event.getMaterial(); + ItemStack item = event.getItem(); + Player player = event.getPlayer(); + Block clickedBlock = event.getClickedBlock(); + + if (materialInHand == null || materialInHand == Material.AIR || materialInHand == Material.BUCKET) { + return; + + } else if (materialInHand == LegacyUtil.CLOCK) { + printTime(player, clickedBlock); + return; + + // fill a glass bottle with potion + } else if (materialInHand == Material.GLASS_BOTTLE) { + if (player.getInventory().firstEmpty() != -1 || item.getAmount() == 1) { + BCauldron bcauldron = get(clickedBlock); + if (bcauldron != null) { + if (bcauldron.fill(player, clickedBlock)) { + event.setCancelled(true); + if (player.hasPermission("brewery.cauldron.fill")) { + if (item.getAmount() > 1) { + item.setAmount(item.getAmount() - 1); + } else { + setItemInHand(event, Material.AIR, false); + } + } + } + } + } else { + event.setCancelled(true); + } + return; + + // reset cauldron when refilling to prevent unlimited source of potions + } else if (materialInHand == Material.WATER_BUCKET) { + if (!P.use1_9) { + // We catch >=1.9 cases in the Cauldron Listener + if (LegacyUtil.getFillLevel(clickedBlock) == 1) { + // will only remove when existing + BCauldron.remove(clickedBlock); + } + } + return; + } + + // Check if fire alive below cauldron when adding ingredients + Block down = clickedBlock.getRelative(BlockFace.DOWN); + if (LegacyUtil.isFireForCauldron(down)) { + + event.setCancelled(true); + boolean handSwap = false; + + // Interact event is called twice!!!?? in 1.9, once for each hand. + // Certain Items in Hand cause one of them to be cancelled or not called at all sometimes. + // We mark if a player had the event for the main hand + // If not, we handle the main hand in the event for the off hand + if (P.use1_9) { + if (event.getHand() == EquipmentSlot.HAND) { + final UUID id = player.getUniqueId(); + plInteracted.add(id); + P.p.getServer().getScheduler().runTask(P.p, new Runnable() { + @Override + public void run() { + plInteracted.remove(id); + } + }); + } else if (event.getHand() == EquipmentSlot.OFF_HAND) { + if (!plInteracted.remove(player.getUniqueId())) { + item = player.getInventory().getItemInMainHand(); + if (item != null && item.getType() != Material.AIR) { + materialInHand = item.getType(); + handSwap = true; + } else { + item = event.getItem(); + } + } + } + } + if (item == null) return; + + // add ingredient to cauldron that meet the previous conditions + if (BIngredients.possibleIngredients.contains(materialInHand)) { + + if (player.hasPermission("brewery.cauldron.insert")) { + if (ingredientAdd(clickedBlock, item, player)) { + boolean isBucket = item.getType().equals(Material.WATER_BUCKET) + || item.getType().equals(Material.LAVA_BUCKET) + || item.getType().equals(Material.MILK_BUCKET); + if (item.getAmount() > 1) { + item.setAmount(item.getAmount() - 1); + + if (isBucket) { + giveItem(player, new ItemStack(Material.BUCKET)); + } + } else { + if (isBucket) { + setItemInHand(event, Material.BUCKET, handSwap); + } else { + setItemInHand(event, Material.AIR, handSwap); + } + } + } + } else { + P.p.msg(player, P.p.languageReader.get("Perms_NoCauldronInsert")); + } + } + } + } + + @SuppressWarnings("deprecation") + public static void setItemInHand(PlayerInteractEvent event, Material mat, boolean swapped) { + if (P.use1_9) { + if ((event.getHand() == EquipmentSlot.OFF_HAND) != swapped) { + event.getPlayer().getInventory().setItemInOffHand(new ItemStack(mat)); + } else { + event.getPlayer().getInventory().setItemInMainHand(new ItemStack(mat)); + } + } else { + event.getPlayer().setItemInHand(new ItemStack(mat)); + } + } + // reset to normal cauldron public static boolean remove(Block block) { if (LegacyUtil.getFillLevel(block) != EMPTY) { diff --git a/src/com/dre/brewery/BDistiller.java b/src/com/dre/brewery/BDistiller.java new file mode 100644 index 0000000..595b90b --- /dev/null +++ b/src/com/dre/brewery/BDistiller.java @@ -0,0 +1,202 @@ +package com.dre.brewery; + +import org.bukkit.Bukkit; +import org.bukkit.Material; +import org.bukkit.block.Block; +import org.bukkit.block.BlockState; +import org.bukkit.block.BrewingStand; +import org.bukkit.event.inventory.InventoryClickEvent; +import org.bukkit.inventory.BrewerInventory; +import org.bukkit.inventory.ItemStack; +import org.bukkit.scheduler.BukkitRunnable; + +import java.util.HashMap; +import java.util.Map; + +/** + * Updated for 1.9 to replicate the "Brewing" process for distilling. + * Because of how metadata has changed, the brewer no longer triggers as previously described. + * So, I've added some event tracking and manual forcing of the brewing "animation" if the + * set of ingredients in the brewer can be distilled. + * Nothing here should interfere with vanilla brewing. + * + * @author ProgrammerDan (1.9 distillation update only) + */ +public class BDistiller { + + private static final int DISTILLTIME = 400; + private static Map trackedDistillers = new HashMap<>(); + + private int taskId; + private int runTime = -1; + private int brewTime = -1; + private Block standBlock; + private int fuel; + + public BDistiller(Block standBlock, int fuel) { + this.standBlock = standBlock; + this.fuel = fuel; + } + + public void cancelDistill() { + Bukkit.getScheduler().cancelTask(taskId); // cancel prior + } + + public void start() { + taskId = new DistillRunnable().runTaskTimer(P.p, 2L, 1L).getTaskId(); + } + + public static void distillerClick(InventoryClickEvent event) { + BrewerInventory standInv = (BrewerInventory) event.getInventory(); + final Block standBlock = standInv.getHolder().getBlock(); + + // If we were already tracking the brewer, cancel any ongoing event due to the click. + BDistiller distiller = trackedDistillers.get(standBlock); + if (distiller != null) { + distiller.cancelDistill(); + standInv.getHolder().setBrewingTime(0); // Fixes brewing continuing without fuel for normal potions + standInv.getHolder().update(); + } + final int fuel = standInv.getHolder().getFuelLevel(); + + // Now check if we should bother to track it. + trackedDistillers.put(standBlock, new BDistiller(standBlock, fuel)).start(); + } + + // Returns a Brew or null for every Slot in the BrewerInventory + public static Brew[] getDistillContents(BrewerInventory inv) { + ItemStack item; + Brew[] contents = new Brew[3]; + for (int slot = 0; slot < 3; slot++) { + item = inv.getItem(slot); + if (item != null) { + contents[slot] = Brew.get(item); + } + } + return contents; + } + + public static byte hasBrew(BrewerInventory brewer) { + ItemStack item = brewer.getItem(3); // ingredient + boolean glowstone = (item != null && Material.GLOWSTONE_DUST == item.getType()); // need dust in the top slot. + byte customFound = 0; + for (Brew brew : getDistillContents(brewer)) { + if (brew != null) { + if (!glowstone) { + return 1; + } + if (brew.canDistill()) { + return 2; + } else { + customFound = 1; + } + } + } + return customFound; + } + + public static boolean runDistill(BrewerInventory inv) { + boolean custom = false; + Brew[] contents = getDistillContents(inv); + for (int slot = 0; slot < 3; slot++) { + if (contents[slot] == null) continue; + if (contents[slot].canDistill()) { + // is further distillable + custom = true; + } else { + contents[slot] = null; + } + } + if (custom) { + Brew.distillAll(inv, contents); + return true; + } + return false; + } + + public static int getLongestDistillTime(BrewerInventory inv) { + int bestTime = 0; + int time; + Brew[] contents = getDistillContents(inv); + for (int slot = 0; slot < 3; slot++) { + if (contents[slot] == null) continue; + time = contents[slot].getDistillTimeNextRun(); + if (time == 0) { + // Undefined Potion needs 40 seconds + time = 800; + } + if (time > bestTime) { + bestTime = time; + } + } + if (bestTime > 0) { + return bestTime; + } + return 800; + } + + public class DistillRunnable extends BukkitRunnable { + + @Override + public void run() { + BlockState now = standBlock.getState(); + if (now instanceof BrewingStand) { + BrewingStand stand = (BrewingStand) now; + if (brewTime == -1) { // only check at the beginning (and end) for distillables + switch (hasBrew(stand.getInventory())) { + case 1: + // Custom potion but not for distilling. Stop any brewing and cancel this task + if (stand.getBrewingTime() > 0) { + if (P.use1_11) { + // The trick below doesnt work in 1.11, but we dont need it anymore + // This should only happen with older Brews that have been made with the old Potion Color System + stand.setBrewingTime(Short.MAX_VALUE); + } else { + // Brewing time is sent and stored as short + // This sends a negative short value to the Client + // In the client the Brewer will look like it is not doing anything + stand.setBrewingTime(Short.MAX_VALUE << 1); + } + stand.setFuelLevel(fuel); + stand.update(); + } + case 0: + // No custom potion, cancel and ignore + this.cancel(); + trackedDistillers.remove(standBlock); + P.p.debugLog("nothing to distill"); + return; + default: + runTime = getLongestDistillTime(stand.getInventory()); + brewTime = runTime; + P.p.debugLog("using brewtime: " + runTime); + + } + } + + brewTime--; // count down. + stand.setBrewingTime((int) ((float) brewTime / ((float) runTime / (float) DISTILLTIME)) + 1); + + if (brewTime <= 1) { // Done! + stand.setBrewingTime(0); + stand.update(); + BrewerInventory brewer = stand.getInventory(); + if (!runDistill(brewer)) { + this.cancel(); + trackedDistillers.remove(standBlock); + P.p.debugLog("All done distilling"); + } else { + brewTime = -1; // go again. + P.p.debugLog("Can distill more! Continuing."); + } + } else { + stand.update(); + } + } else { + this.cancel(); + trackedDistillers.remove(standBlock); + P.p.debugLog("The block was replaced; not a brewing stand."); + } + } + } +} diff --git a/src/com/dre/brewery/BPlayer.java b/src/com/dre/brewery/BPlayer.java index 28c6e24..bf133e5 100644 --- a/src/com/dre/brewery/BPlayer.java +++ b/src/com/dre/brewery/BPlayer.java @@ -5,6 +5,7 @@ import com.dre.brewery.api.events.PlayerDrinkEffectEvent; import com.dre.brewery.api.events.PlayerPukeEvent; import com.dre.brewery.api.events.PlayerPushEvent; import com.dre.brewery.api.events.brew.BrewDrinkEvent; +import com.dre.brewery.filedata.BConfig; import org.apache.commons.lang.mutable.MutableInt; import org.bukkit.Location; import org.bukkit.Material; @@ -34,17 +35,6 @@ public class BPlayer { private static Method gh; private static Field age; - // Settings - public static Map drainItems = new HashMap<>();// DrainItem Material and Strength - public static Material pukeItem; - public static int pukeDespawntime; - public static int hangoverTime; - public static boolean overdrinkKick; - public static boolean enableHome; - public static boolean enableLoginDisallow; - public static boolean enablePuke; - public static String homeType; - private int quality = 0;// = quality of drunkeness * drunkeness private int drunkeness = 0;// = amount of drunkeness private int offlineDrunk = 0;// drunkeness when gone offline @@ -191,7 +181,7 @@ public class BPlayer { public void drinkCap(Player player) { quality = getQuality() * 100; drunkeness = 100; - if (overdrinkKick && !player.hasPermission("brewery.bypass.overdrink")) { + if (BConfig.overdrinkKick && !player.hasPermission("brewery.bypass.overdrink")) { P.p.getServer().getScheduler().scheduleSyncDelayedTask(P.p, () -> passOut(player), 1); } else { addPuke(player, 60 + (int) (Math.random() * 60.0)); @@ -209,7 +199,7 @@ public class BPlayer { // Eat something to drain the drunkeness public void drainByItem(Player player, Material mat) { - int strength = drainItems.get(mat); + int strength = BConfig.drainItems.get(mat); if (drain(player, strength)) { remove(player); } @@ -233,7 +223,7 @@ public class BPlayer { } quality = getQuality(); if (drunkeness <= -offlineDrunk) { - return drunkeness <= -hangoverTime; + return drunkeness <= -BConfig.hangoverTime; } } return false; @@ -301,7 +291,7 @@ public class BPlayer { if (drunkeness <= 70) { return 0; } - if (!enableLoginDisallow) { + if (!BConfig.enableLoginDisallow) { if (drunkeness <= 100) { return 0; } else { @@ -342,7 +332,7 @@ public class BPlayer { public void login(final Player player) { if (drunkeness < 10) { if (offlineDrunk > 60) { - if (enableHome && !player.hasPermission("brewery.bypass.teleport")) { + if (BConfig.enableHome && !player.hasPermission("brewery.bypass.teleport")) { goHome(player); } } @@ -368,6 +358,7 @@ public class BPlayer { } public void goHome(final Player player) { + String homeType = BConfig.homeType; if (homeType != null) { Location home = null; if (homeType.equalsIgnoreCase("bed")) { @@ -407,7 +398,7 @@ public class BPlayer { // make a Player puke "count" items public static void addPuke(Player player, int count) { - if (!enablePuke) { + if (!BConfig.enablePuke) { return; } @@ -450,8 +441,8 @@ public class BPlayer { if (pukeRand == null) { pukeRand = new Random(); } - if (pukeItem == null || pukeItem == Material.AIR) { - pukeItem = Material.SOUL_SAND; + if (BConfig.pukeItem == null || BConfig.pukeItem == Material.AIR) { + BConfig.pukeItem = Material.SOUL_SAND; } Location loc = player.getLocation(); loc.setY(loc.getY() + 1.1); @@ -460,11 +451,12 @@ public class BPlayer { Vector direction = loc.getDirection(); direction.multiply(0.5); loc.add(direction); - Item item = player.getWorld().dropItem(loc, new ItemStack(pukeItem)); + Item item = player.getWorld().dropItem(loc, new ItemStack(BConfig.pukeItem)); item.setVelocity(direction); item.setPickupDelay(32767); // Item can never be picked up when pickup delay is 32767 //item.setTicksLived(6000 - pukeDespawntime); // Well this does not work... if (modAge) { + int pukeDespawntime = BConfig.pukeDespawntime; if (pukeDespawntime >= 5800) { return; } @@ -494,7 +486,7 @@ public class BPlayer { e.printStackTrace(); } modAge = false; - P.p.errorLog("Failed to set Despawn Time on item " + pukeItem.name()); + P.p.errorLog("Failed to set Despawn Time on item " + BConfig.pukeItem.name()); } } @@ -629,7 +621,7 @@ public class BPlayer { bplayer.drunkEffects(player); - if (enablePuke) { + if (BConfig.enablePuke) { bplayer.drunkPuke(player); } diff --git a/src/com/dre/brewery/BRecipe.java b/src/com/dre/brewery/BRecipe.java index b764ceb..c5644e6 100644 --- a/src/com/dre/brewery/BRecipe.java +++ b/src/com/dre/brewery/BRecipe.java @@ -1,5 +1,6 @@ package com.dre.brewery; +import com.dre.brewery.filedata.BConfig; import org.bukkit.Material; import org.bukkit.configuration.ConfigurationSection; import org.bukkit.inventory.ItemStack; @@ -54,7 +55,7 @@ public class BRecipe { if (matParts.length == 2) { durability = (short) P.p.parseInt(matParts[1]); } - if (mat == null && P.p.hasVault) { + if (mat == null && BConfig.hasVault) { try { net.milkbowl.vault.item.ItemInfo vaultItem = net.milkbowl.vault.item.Items.itemByString(matParts[0]); if (vaultItem != null) { @@ -247,6 +248,7 @@ public class BRecipe { /** * Create a Potion from this Recipe with best values. Quality can be set, but will reset to 10 if put in a barrel + * * @param quality The Quality of the Brew * @return The Created Item */ @@ -256,6 +258,7 @@ public class BRecipe { /** * Create a Brew from this Recipe with best values. Quality can be set, but will reset to 10 if put in a barrel + * * @param quality The Quality of the Brew * @return The created Brew */ diff --git a/src/com/dre/brewery/Barrel.java b/src/com/dre/brewery/Barrel.java index 3f47a8c..c583857 100644 --- a/src/com/dre/brewery/Barrel.java +++ b/src/com/dre/brewery/Barrel.java @@ -4,11 +4,14 @@ import com.dre.brewery.api.events.barrel.BarrelAccessEvent; import com.dre.brewery.api.events.barrel.BarrelCreateEvent; import com.dre.brewery.api.events.barrel.BarrelDestroyEvent; import com.dre.brewery.api.events.barrel.BarrelRemoveEvent; +import com.dre.brewery.filedata.BConfig; import com.dre.brewery.integration.LWCBarrel; import com.dre.brewery.integration.LogBlockBarrel; import com.dre.brewery.lore.BrewLore; import org.apache.commons.lang.ArrayUtils; import org.bukkit.Material; +import org.bukkit.Sound; +import org.bukkit.SoundCategory; import org.bukkit.block.Block; import org.bukkit.configuration.ConfigurationSection; import org.bukkit.entity.HumanEntity; @@ -130,35 +133,6 @@ public class Barrel implements InventoryHolder { return false; } - if (event != null && P.p.useLWC) { - Plugin plugin = P.p.getServer().getPluginManager().getPlugin("LWC"); - if (plugin != null) { - - // If the Clicked Block was the Sign, LWC already knows and we dont need to do anything here - if (!LegacyUtil.isSign(event.getClickedBlock().getType())) { - Block sign = getSignOfSpigot(); - // If the Barrel does not have a Sign, it cannot be locked - if (!sign.equals(event.getClickedBlock())) { - try { - return LWCBarrel.checkAccess(player, sign, event, plugin); - } catch (Throwable e) { - P.p.errorLog("Failed to Check LWC for Barrel Open Permissions!"); - P.p.errorLog("Brewery was tested with version 4.5.0 of LWC!"); - P.p.errorLog("Disable the LWC support in the config and do /brew reload"); - e.printStackTrace(); - if (player.hasPermission("brewery.admin") || player.hasPermission("brewery.mod")) { - P.p.msg(player, "&cLWC check Error, Brewery was tested with up to v4.5.0 of LWC"); - P.p.msg(player, "&cSet &7useLWC: false &cin the config and /brew reload"); - } else { - P.p.msg(player, "&cError breaking Barrel, please report to an Admin!"); - } - return false; - } - } - } - } - } - return true; } @@ -204,7 +178,7 @@ public class Barrel implements InventoryHolder { // reset barreltime, potions have new age time = 0; - if (P.p.useLB) { + if (BConfig.useLB) { try { LogBlockBarrel.openBarrel(player, inventory, spigot.getLocation()); } catch (Throwable e) { @@ -216,6 +190,27 @@ public class Barrel implements InventoryHolder { player.openInventory(inventory); } + public void playOpeningSound() { + float randPitch = (float) (Math.random() * 0.1); + if (isLarge()) { + getSpigot().getWorld().playSound(getSpigot().getLocation(), Sound.BLOCK_CHEST_OPEN, SoundCategory.BLOCKS, 0.4f, 0.55f + randPitch); + //getSpigot().getWorld().playSound(getSpigot().getLocation(), Sound.ITEM_BUCKET_EMPTY, SoundCategory.BLOCKS, 0.5f, 0.6f + randPitch); + getSpigot().getWorld().playSound(getSpigot().getLocation(), Sound.BLOCK_BREWING_STAND_BREW, SoundCategory.BLOCKS, 0.4f, 0.45f + randPitch); + } else { + getSpigot().getWorld().playSound(getSpigot().getLocation(), Sound.BLOCK_BARREL_OPEN, SoundCategory.BLOCKS, 0.5f, 0.8f + randPitch); + } + } + + public void playClosingSound() { + float randPitch = (float) (Math.random() * 0.1); + if (isLarge()) { + getSpigot().getWorld().playSound(getSpigot().getLocation(), Sound.BLOCK_BARREL_CLOSE, SoundCategory.BLOCKS, 0.5f, 0.5f + randPitch); + getSpigot().getWorld().playSound(getSpigot().getLocation(), Sound.ITEM_BUCKET_EMPTY, SoundCategory.BLOCKS, 0.2f, 0.6f + randPitch); + } else { + getSpigot().getWorld().playSound(getSpigot().getLocation(), Sound.BLOCK_BARREL_CLOSE, SoundCategory.BLOCKS, 0.5f, 0.8f + randPitch); + } + } + @Override public Inventory getInventory() { return inventory; @@ -401,7 +396,7 @@ public class Barrel implements InventoryHolder { } ItemStack[] items = inventory.getContents(); inventory.clear(); - if (P.p.useLB && breaker != null) { + if (BConfig.useLB && breaker != null) { try { LogBlockBarrel.breakBarrel(breaker, items, spigot.getLocation()); } catch (Throwable e) { @@ -439,93 +434,11 @@ public class Barrel implements InventoryHolder { barrels.remove(this); } - //unloads barrels that are in a unloading world - public static void onUnload(String name) { - for (Barrel barrel : barrels) { - if (barrel.spigot.getWorld().getName().equals(name)) { - barrels.remove(barrel); - } - } - } - // If the Sign of a Large Barrel gets destroyed, set signOffset to 0 public void destroySign() { signoffset = 0; } - // Saves all data - public static void save(ConfigurationSection config, ConfigurationSection oldData) { - BUtil.createWorldSections(config); - - if (!barrels.isEmpty()) { - int id = 0; - for (Barrel barrel : barrels) { - - String worldName = barrel.spigot.getWorld().getName(); - String prefix; - - if (worldName.startsWith("DXL_")) { - prefix = BUtil.getDxlName(worldName) + "." + id; - } else { - prefix = barrel.spigot.getWorld().getUID().toString() + "." + id; - } - - // block: x/y/z - config.set(prefix + ".spigot", barrel.spigot.getX() + "/" + barrel.spigot.getY() + "/" + barrel.spigot.getZ()); - - if (barrel.signoffset != 0) { - config.set(prefix + ".sign", barrel.signoffset); - } - if (barrel.stairsloc != null && barrel.stairsloc.length > 0) { - StringBuilder st = new StringBuilder(); - for (int i : barrel.stairsloc) { - st.append(i).append(","); - } - config.set(prefix + ".st", st.substring(0, st.length() - 1)); - } - if (barrel.woodsloc != null && barrel.woodsloc.length > 0) { - StringBuilder wo = new StringBuilder(); - for (int i : barrel.woodsloc) { - wo.append(i).append(","); - } - config.set(prefix + ".wo", wo.substring(0, wo.length() - 1)); - } - - if (barrel.inventory != null) { - int slot = 0; - ItemStack item; - ConfigurationSection invConfig = null; - while (slot < barrel.inventory.getSize()) { - item = barrel.inventory.getItem(slot); - if (item != null) { - if (invConfig == null) { - if (barrel.time != 0) { - config.set(prefix + ".time", barrel.time); - } - invConfig = config.createSection(prefix + ".inv"); - } - // ItemStacks are configurationSerializeable, makes them - // really easy to save - invConfig.set(slot + "", item); - } - - slot++; - } - } - - id++; - } - } - // also save barrels that are not loaded - if (oldData != null){ - for (String uuid : oldData.getKeys(false)) { - if (!config.contains(uuid)) { - config.set(uuid, oldData.get(uuid)); - } - } - } - } - // direction of the barrel from the spigot public static int getDirection(Block spigot) { int direction = 0;// 1=x+ 2=x- 3=z+ 4=z- @@ -805,6 +718,88 @@ public class Barrel implements InventoryHolder { return null; } + //unloads barrels that are in a unloading world + public static void onUnload(String name) { + for (Barrel barrel : barrels) { + if (barrel.spigot.getWorld().getName().equals(name)) { + barrels.remove(barrel); + } + } + } + + // Saves all data + public static void save(ConfigurationSection config, ConfigurationSection oldData) { + BUtil.createWorldSections(config); + + if (barrels.isEmpty()) { + int id = 0; + for (Barrel barrel : barrels) { + + String worldName = barrel.spigot.getWorld().getName(); + String prefix; + + if (worldName.startsWith("DXL_")) { + prefix = BUtil.getDxlName(worldName) + "." + id; + } else { + prefix = barrel.spigot.getWorld().getUID().toString() + "." + id; + } + + // block: x/y/z + config.set(prefix + ".spigot", barrel.spigot.getX() + "/" + barrel.spigot.getY() + "/" + barrel.spigot.getZ()); + + if (barrel.signoffset != 0) { + config.set(prefix + ".sign", barrel.signoffset); + } + if (barrel.stairsloc != null && barrel.stairsloc.length > 0) { + StringBuilder st = new StringBuilder(); + for (int i : barrel.stairsloc) { + st.append(i).append(","); + } + config.set(prefix + ".st", st.substring(0, st.length() - 1)); + } + if (barrel.woodsloc != null && barrel.woodsloc.length > 0) { + StringBuilder wo = new StringBuilder(); + for (int i : barrel.woodsloc) { + wo.append(i).append(","); + } + config.set(prefix + ".wo", wo.substring(0, wo.length() - 1)); + } + + if (barrel.inventory != null) { + int slot = 0; + ItemStack item; + ConfigurationSection invConfig = null; + while (slot < barrel.inventory.getSize()) { + item = barrel.inventory.getItem(slot); + if (item != null) { + if (invConfig == null) { + if (barrel.time != 0) { + config.set(prefix + ".time", barrel.time); + } + invConfig = config.createSection(prefix + ".inv"); + } + // ItemStacks are configurationSerializeable, makes them + // really easy to save + invConfig.set(slot + "", item); + } + + slot++; + } + } + + id++; + } + } + // also save barrels that are not loaded + if (oldData != null){ + for (String uuid : oldData.getKeys(false)) { + if (!config.contains(uuid)) { + config.set(uuid, oldData.get(uuid)); + } + } + } + } + public static class BarrelCheck extends BukkitRunnable { @Override public void run() { diff --git a/src/com/dre/brewery/Brew.java b/src/com/dre/brewery/Brew.java index 9c4394d..98b576b 100644 --- a/src/com/dre/brewery/Brew.java +++ b/src/com/dre/brewery/Brew.java @@ -1,6 +1,7 @@ package com.dre.brewery; import com.dre.brewery.api.events.brew.BrewModifyEvent; +import com.dre.brewery.filedata.BConfig; import com.dre.brewery.lore.*; import org.bukkit.Material; import org.bukkit.configuration.ConfigurationSection; @@ -26,8 +27,6 @@ public class Brew { private static long saveSeed; public static Map legacyPotions = new HashMap<>(); 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 colorInBrewer; // color the Lore while in Brewer private BIngredients ingredients; private int quality; @@ -72,46 +71,43 @@ public class Brew { // returns a Brew by ItemMeta public static Brew get(ItemMeta meta) { - if (meta.hasLore()) { - if (meta instanceof PotionMeta && ((PotionMeta) meta).hasCustomEffect(PotionEffectType.REGENERATION)) { - Brew brew = load(meta); - if (brew != null) { - // Load Legacy - brew = getFromPotionEffect(((PotionMeta) meta), false); - } - return brew; - } else { - return load(meta); + if (!meta.hasLore()) return null; + + if (meta instanceof PotionMeta && ((PotionMeta) meta).hasCustomEffect(PotionEffectType.REGENERATION)) { + Brew brew = load(meta); + if (brew != null) { + // Load Legacy + brew = getFromPotionEffect(((PotionMeta) meta), false); } + return brew; + } else { + return load(meta); } - return null; } // returns a Brew by ItemStack public static Brew get(ItemStack item) { - if (item.getType() == Material.POTION) { - if (item.hasItemMeta()) { - ItemMeta meta = item.getItemMeta(); - if (meta.hasLore()) { - if (meta instanceof PotionMeta && ((PotionMeta) meta).hasCustomEffect(PotionEffectType.REGENERATION)) { - Brew brew = load(meta); - if (brew != null) { - ((PotionMeta) meta).removeCustomEffect(PotionEffectType.REGENERATION); - } else { - // Load Legacy and convert - brew = getFromPotionEffect(((PotionMeta) meta), true); - if (brew == null) return null; - brew.save(meta); - } - item.setItemMeta(meta); - return brew; - } else { - return load(meta); - } - } + if (item.getType() != Material.POTION) return null; + if (!item.hasItemMeta()) return null; + + ItemMeta meta = item.getItemMeta(); + if (!meta.hasLore()) return null; + + if (meta instanceof PotionMeta && ((PotionMeta) meta).hasCustomEffect(PotionEffectType.REGENERATION)) { + Brew brew = load(meta); + if (brew != null) { + ((PotionMeta) meta).removeCustomEffect(PotionEffectType.REGENERATION); + } else { + // Load Legacy and convert + brew = getFromPotionEffect(((PotionMeta) meta), true); + if (brew == null) return null; + brew.save(meta); } + item.setItemMeta(meta); + return brew; + } else { + return load(meta); } - return null; } // Legacy Brew Loading @@ -482,11 +478,11 @@ public class Brew { // Distill Lore if (currentRecipe != null) { - if (colorInBrewer != BrewLore.hasColorLore(potionMeta)) { - lore.convertLore(colorInBrewer); + if (BConfig.colorInBrewer != BrewLore.hasColorLore(potionMeta)) { + lore.convertLore(BConfig.colorInBrewer); } } - lore.updateDistillLore(colorInBrewer); + lore.updateDistillLore(BConfig.colorInBrewer); lore.write(); touch(); BrewModifyEvent modifyEvent = new BrewModifyEvent(this, potionMeta, BrewModifyEvent.Type.DISTILL); @@ -551,15 +547,15 @@ public class Brew { // Lore if (currentRecipe != null) { - if (colorInBarrels != BrewLore.hasColorLore(potionMeta)) { - lore.convertLore(colorInBarrels); + if (BConfig.colorInBarrels != BrewLore.hasColorLore(potionMeta)) { + lore.convertLore(BConfig.colorInBarrels); } } if (ageTime >= 1) { - lore.updateAgeLore(colorInBarrels); + lore.updateAgeLore(BConfig.colorInBarrels); } if (ageTime > 0.5) { - if (colorInBarrels && !unlabeled && currentRecipe != null) { + if (BConfig.colorInBarrels && !unlabeled && currentRecipe != null) { lore.updateWoodLore(true); } } diff --git a/src/com/dre/brewery/Words.java b/src/com/dre/brewery/DistortChat.java similarity index 97% rename from src/com/dre/brewery/Words.java rename to src/com/dre/brewery/DistortChat.java index 8301cf7..eb0f2c9 100644 --- a/src/com/dre/brewery/Words.java +++ b/src/com/dre/brewery/DistortChat.java @@ -9,11 +9,11 @@ import java.util.HashMap; import java.util.List; import java.util.Map; -public class Words { +public class DistortChat { // represends Words and letters, that are replaced in drunk players messages - public static ArrayList words = new ArrayList<>(); + public static ArrayList words = new ArrayList<>(); public static List commands; public static List ignoreText = new ArrayList<>(); public static Boolean doSigns; @@ -27,7 +27,7 @@ public class Words { private int alcohol = 1; private int percentage = 100; - public Words(Map part) { + public DistortChat(Map part) { for (Map.Entry wordPart : part.entrySet()) { String key = (String) wordPart.getKey(); @@ -164,7 +164,7 @@ public class Words { // distorts a message without checking ignoreText letters private static String distortString(String message, int drunkeness) { if (message.length() > 1) { - for (Words word : words) { + for (DistortChat word : words) { if (word.alcohol <= drunkeness) { message = word.distort(message); } diff --git a/src/com/dre/brewery/MCBarrel.java b/src/com/dre/brewery/MCBarrel.java index 4374b3e..3dd0a37 100644 --- a/src/com/dre/brewery/MCBarrel.java +++ b/src/com/dre/brewery/MCBarrel.java @@ -97,6 +97,26 @@ public class MCBarrel { } } + public void countBrews() { + brews = 0; + for (ItemStack item : inv.getContents()) { + if (item != null) { + Brew brew = Brew.get(item); + if (brew != null) { + brews++; + } + } + } + } + + public Inventory getInventory() { + return inv; + } + + public static void onUpdate() { + mcBarrelTime++; + } + // Used to visually stop Players from placing more than 6 (configurable) brews in the MC Barrels. // There are still methods to place more Brews in that would be too tedious to catch. // This is only for direct visual Notification, the age routine above will never age more than 6 brews in any case. @@ -184,24 +204,4 @@ public class MCBarrel { } } - public void countBrews() { - brews = 0; - for (ItemStack item : inv.getContents()) { - if (item != null) { - Brew brew = Brew.get(item); - if (brew != null) { - brews++; - } - } - } - } - - public Inventory getInventory() { - return inv; - } - - public static void onUpdate() { - mcBarrelTime++; - } - } diff --git a/src/com/dre/brewery/P.java b/src/com/dre/brewery/P.java index 097fc15..d7cb911 100644 --- a/src/com/dre/brewery/P.java +++ b/src/com/dre/brewery/P.java @@ -1,58 +1,30 @@ package com.dre.brewery; -import com.dre.brewery.filedata.ConfigUpdater; +import com.dre.brewery.filedata.BConfig; +import com.dre.brewery.filedata.BData; import com.dre.brewery.filedata.DataSave; -import com.dre.brewery.filedata.DataUpdater; import com.dre.brewery.filedata.LanguageReader; import com.dre.brewery.filedata.UpdateChecker; -import com.dre.brewery.integration.*; +import com.dre.brewery.integration.IntegrationListener; +import com.dre.brewery.integration.LogBlockBarrel; import com.dre.brewery.listeners.*; import org.apache.commons.lang.math.NumberUtils; -import org.bstats.bukkit.Metrics; import org.bukkit.Bukkit; import org.bukkit.ChatColor; -import org.bukkit.Location; -import org.bukkit.Material; -import org.bukkit.World; -import org.bukkit.block.Block; import org.bukkit.command.CommandSender; -import org.bukkit.configuration.ConfigurationSection; -import org.bukkit.configuration.file.FileConfiguration; -import org.bukkit.configuration.file.YamlConfiguration; -import org.bukkit.entity.Player; import org.bukkit.event.HandlerList; -import org.bukkit.inventory.ItemStack; -import org.bukkit.plugin.Plugin; import org.bukkit.plugin.java.JavaPlugin; import java.io.File; -import java.io.IOException; -import java.io.InputStream; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.UUID; public class P extends JavaPlugin { public static P p; - public static final String configVersion = "1.8"; public static boolean debug; public static boolean useUUID; public static boolean use1_9; public static boolean use1_11; public static boolean use1_13; public static boolean use1_14; - public static boolean updateCheck; - - // Third Party Enabled - public boolean useWG; //WorldGuard - public WGBarrel wg; - public boolean useLWC; //LWC - public boolean useLB; //LogBlock - public boolean useGP; //GriefPrevention - public boolean hasVault; // Vault - public boolean useCitadel; // CivCraft/DevotedMC Citadel // Listeners public BlockListener blockListener; @@ -66,8 +38,6 @@ public class P extends JavaPlugin { public String language; public LanguageReader languageReader; - private CommandSender reloader; - @Override public void onEnable() { p = this; @@ -331,7 +301,7 @@ public class P extends JavaPlugin { // load the Config try { - if (!readConfig()) { + if (!BConfig.readConfig()) { p = null; getServer().getPluginManager().disablePlugin(this); return; @@ -342,7 +312,7 @@ public class P extends JavaPlugin { getServer().getPluginManager().disablePlugin(this); return; } - readData(); + BData.readData(); // Setup Metrics /*try { @@ -427,7 +397,7 @@ public class P extends JavaPlugin { p.getServer().getScheduler().runTaskTimer(p, new BreweryRunnable(), 650, 1200); p.getServer().getScheduler().runTaskTimer(p, new DrunkRunnable(), 120, 120); - if (updateCheck) { + if (BConfig.updateCheck) { try { p.getServer().getScheduler().runTaskLaterAsynchronously(p, new UpdateChecker(), 135); } catch (Exception e) { @@ -466,26 +436,26 @@ public class P extends JavaPlugin { BPlayer.clear(); Brew.legacyPotions.clear(); Wakeup.wakeups.clear(); - Words.words.clear(); - Words.ignoreText.clear(); - Words.commands = null; + DistortChat.words.clear(); + DistortChat.ignoreText.clear(); + DistortChat.commands = null; this.log(this.getDescription().getName() + " disabled!"); } public void reload(CommandSender sender) { if (sender != null && !sender.equals(getServer().getConsoleSender())) { - reloader = sender; + BConfig.reloader = sender; } // clear all existent config Data BIngredients.possibleIngredients.clear(); BIngredients.recipes.clear(); BIngredients.cookedNames.clear(); - Words.words.clear(); - Words.ignoreText.clear(); - Words.commands = null; - BPlayer.drainItems.clear(); - if (useLB) { + DistortChat.words.clear(); + DistortChat.ignoreText.clear(); + DistortChat.commands = null; + BConfig.drainItems.clear(); + if (BConfig.useLB) { try { LogBlockBarrel.clear(); } catch (Exception e) { @@ -495,7 +465,7 @@ public class P extends JavaPlugin { // load the Config try { - if (!readConfig()) { + if (!BConfig.readConfig()) { p = null; getServer().getPluginManager().disablePlugin(this); return; @@ -521,9 +491,11 @@ public class P extends JavaPlugin { if (!successful && sender != null) { msg(sender, p.languageReader.get("Error_Recipeload")); } - reloader = null; + BConfig.reloader = null; } + // Utility + public void msg(CommandSender sender, String msg) { sender.sendMessage(color("&2[Brewery] &f" + msg)); } @@ -540,446 +512,11 @@ public class P extends JavaPlugin { public void errorLog(String msg) { Bukkit.getConsoleSender().sendMessage(ChatColor.DARK_GREEN + "[Brewery] " + ChatColor.DARK_RED + "ERROR: " + ChatColor.RED + msg); - if (reloader != null) { - reloader.sendMessage(ChatColor.DARK_GREEN + "[Brewery] " + ChatColor.DARK_RED + "ERROR: " + ChatColor.RED + msg); + if (BConfig.reloader != null) { + BConfig.reloader.sendMessage(ChatColor.DARK_GREEN + "[Brewery] " + ChatColor.DARK_RED + "ERROR: " + ChatColor.RED + msg); } } - public boolean readConfig() { - File file = new File(p.getDataFolder(), "config.yml"); - if (!checkConfigs()) { - return false; - } - FileConfiguration config = YamlConfiguration.loadConfiguration(file); - - // Set the Language - language = config.getString("language", "en"); - - // Load LanguageReader - languageReader = new LanguageReader(new File(p.getDataFolder(), "languages/" + language + ".yml")); - - // Has to config still got old materials - boolean oldMat = config.getBoolean("oldMat", false); - - // Check if config is the newest version - String version = config.getString("version", null); - if (version != null) { - if (!version.equals(configVersion) || (oldMat && use1_13)) { - copyDefaultConfigs(true); - new ConfigUpdater(file).update(version, oldMat, language); - P.p.log("Config Updated to version: " + configVersion); - config = YamlConfiguration.loadConfiguration(file); - } - } - - // If the Update Checker should be enabled - updateCheck = config.getBoolean("updateCheck", false); - - // Third-Party - useWG = config.getBoolean("useWorldGuard", true) && getServer().getPluginManager().isPluginEnabled("WorldGuard"); - - if (useWG) { - Plugin plugin = Bukkit.getPluginManager().getPlugin("WorldEdit"); - if (plugin != null) { - String wgv = plugin.getDescription().getVersion(); - if (wgv.startsWith("6.")) { - wg = new WGBarrelNew(); - } else if (wgv.startsWith("5.")) { - wg = new WGBarrelOld(); - } else { - wg = new WGBarrel7(); - } - } - if (wg == null) { - P.p.errorLog("Failed loading WorldGuard Integration! Opening Barrels will NOT work!"); - P.p.errorLog("Brewery was tested with version 5.8, 6.1 and 7.0 of WorldGuard!"); - P.p.errorLog("Disable the WorldGuard support in the config and do /brew reload"); - } - } - useLWC = config.getBoolean("useLWC", true) && getServer().getPluginManager().isPluginEnabled("LWC"); - useGP = config.getBoolean("useGriefPrevention", true) && getServer().getPluginManager().isPluginEnabled("GriefPrevention"); - useLB = config.getBoolean("useLogBlock", false) && getServer().getPluginManager().isPluginEnabled("LogBlock"); - useCitadel = config.getBoolean("useCitadel", false) && getServer().getPluginManager().isPluginEnabled("Citadel"); - // The item util has been removed in Vault 1.7+ - hasVault = getServer().getPluginManager().isPluginEnabled("Vault") - && Integer.parseInt(getServer().getPluginManager().getPlugin("Vault").getDescription().getVersion().split("\\.")[1]) <= 6; - - // various Settings - DataSave.autosave = config.getInt("autosave", 3); - debug = config.getBoolean("debug", false); - BPlayer.pukeItem = Material.matchMaterial(config.getString("pukeItem", "SOUL_SAND")); - BPlayer.hangoverTime = config.getInt("hangoverDays", 0) * 24 * 60; - BPlayer.overdrinkKick = config.getBoolean("enableKickOnOverdrink", false); - BPlayer.enableHome = config.getBoolean("enableHome", false); - BPlayer.enableLoginDisallow = config.getBoolean("enableLoginDisallow", false); - BPlayer.enablePuke = config.getBoolean("enablePuke", false); - BPlayer.pukeDespawntime = config.getInt("pukeDespawntime", 60) * 20; - BPlayer.homeType = config.getString("homeType", null); - Brew.colorInBarrels = config.getBoolean("colorInBarrels", false); - Brew.colorInBrewer = config.getBoolean("colorInBrewer", false); - PlayerListener.openEverywhere = config.getBoolean("openLargeBarrelEverywhere", false); - MCBarrel.maxBrews = config.getInt("maxBrewsInMCBarrels", 6); - - // loading recipes - ConfigurationSection configSection = config.getConfigurationSection("recipes"); - if (configSection != null) { - for (String recipeId : configSection.getKeys(false)) { - BRecipe recipe = new BRecipe(configSection, recipeId); - if (recipe.isValid()) { - BIngredients.recipes.add(recipe); - } else { - errorLog("Loading the Recipe with id: '" + recipeId + "' failed!"); - } - } - } - - // loading cooked names and possible ingredients - configSection = config.getConfigurationSection("cooked"); - if (configSection != null) { - for (String ingredient : configSection.getKeys(false)) { - Material mat = Material.matchMaterial(ingredient); - if (mat == null && hasVault) { - try { - net.milkbowl.vault.item.ItemInfo vaultItem = net.milkbowl.vault.item.Items.itemByString(ingredient); - if (vaultItem != null) { - mat = vaultItem.getType(); - } - } catch (Exception e) { - P.p.errorLog("Could not check vault for Item Name"); - e.printStackTrace(); - } - } - if (mat != null) { - BIngredients.cookedNames.put(mat, (configSection.getString(ingredient, null))); - BIngredients.possibleIngredients.add(mat); - } else { - errorLog("Unknown Material: " + ingredient); - } - } - } - - // loading drainItems - List drainList = config.getStringList("drainItems"); - if (drainList != null) { - for (String drainString : drainList) { - String[] drainSplit = drainString.split("/"); - if (drainSplit.length > 1) { - Material mat = Material.matchMaterial(drainSplit[0]); - int strength = p.parseInt(drainSplit[1]); - if (mat == null && hasVault && strength > 0) { - try { - net.milkbowl.vault.item.ItemInfo vaultItem = net.milkbowl.vault.item.Items.itemByString(drainSplit[0]); - if (vaultItem != null) { - mat = vaultItem.getType(); - } - } catch (Exception e) { - P.p.errorLog("Could not check vault for Item Name"); - e.printStackTrace(); - } - } - if (mat != null && strength > 0) { - BPlayer.drainItems.put(mat, strength); - } - } - } - } - - // Loading Words - if (config.getBoolean("enableChatDistortion", false)) { - for (Map map : config.getMapList("words")) { - new Words(map); - } - for (String bypass : config.getStringList("distortBypass")) { - Words.ignoreText.add(bypass.split(",")); - } - Words.commands = config.getStringList("distortCommands"); - } - Words.log = config.getBoolean("logRealChat", false); - Words.doSigns = config.getBoolean("distortSignText", false); - - return true; - } - - // load all Data - public void readData() { - File file = new File(p.getDataFolder(), "data.yml"); - if (file.exists()) { - - FileConfiguration data = YamlConfiguration.loadConfiguration(file); - - Brew.installTime = data.getLong("installTime", System.currentTimeMillis()); - MCBarrel.mcBarrelTime = data.getLong("MCBarrelTime", 0); - - Brew.loadSeed(data); - - // Check if data is the newest version - String version = data.getString("Version", null); - if (version != null) { - if (!version.equals(DataSave.dataVersion)) { - P.p.log("Data File is being updated..."); - new DataUpdater(data, file).update(version); - data = YamlConfiguration.loadConfiguration(file); - P.p.log("Data Updated to version: " + DataSave.dataVersion); - } - } - - // loading Ingredients into ingMap - Map ingMap = new HashMap<>(); - ConfigurationSection section = data.getConfigurationSection("Ingredients"); - if (section != null) { - for (String id : section.getKeys(false)) { - ConfigurationSection matSection = section.getConfigurationSection(id + ".mats"); - if (matSection != null) { - // matSection has all the materials + amount as Integers - ArrayList ingredients = deserializeIngredients(matSection); - ingMap.put(id, new BIngredients(ingredients, section.getInt(id + ".cookedTime", 0), true)); - } else { - errorLog("Ingredient id: '" + id + "' incomplete in data.yml"); - } - } - } - - // loading Brew legacy - section = data.getConfigurationSection("Brew"); - if (section != null) { - // All sections have the UID as name - for (String uid : section.getKeys(false)) { - BIngredients ingredients = getIngredients(ingMap, section.getString(uid + ".ingId")); - int quality = section.getInt(uid + ".quality", 0); - byte distillRuns = (byte) section.getInt(uid + ".distillRuns", 0); - float ageTime = (float) section.getDouble(uid + ".ageTime", 0.0); - float wood = (float) section.getDouble(uid + ".wood", -1.0); - String recipe = section.getString(uid + ".recipe", null); - boolean unlabeled = section.getBoolean(uid + ".unlabeled", false); - boolean persistent = section.getBoolean(uid + ".persist", false); - boolean stat = section.getBoolean(uid + ".stat", false); - int lastUpdate = section.getInt("lastUpdate", 0); - - Brew.loadLegacy(ingredients, parseInt(uid), quality, distillRuns, ageTime, wood, recipe, unlabeled, persistent, stat, lastUpdate); - } - } - - // loading BPlayer - section = data.getConfigurationSection("Player"); - if (section != null) { - // keys have players name - for (String name : section.getKeys(false)) { - try { - //noinspection ResultOfMethodCallIgnored - UUID.fromString(name); - if (!useUUID) { - continue; - } - } catch (IllegalArgumentException e) { - if (useUUID) { - continue; - } - } - - int quality = section.getInt(name + ".quality"); - int drunk = section.getInt(name + ".drunk"); - int offDrunk = section.getInt(name + ".offDrunk", 0); - - new BPlayer(name, quality, drunk, offDrunk); - } - } - - for (World world : p.getServer().getWorlds()) { - if (world.getName().startsWith("DXL_")) { - loadWorldData(BUtil.getDxlName(world.getName()), world); - } else { - loadWorldData(world.getUID().toString(), world); - } - } - - } else { - errorLog("No data.yml found, will create new one!"); - } - } - - public ArrayList deserializeIngredients(ConfigurationSection matSection) { - ArrayList ingredients = new ArrayList<>(); - for (String mat : matSection.getKeys(false)) { - String[] matSplit = mat.split(","); - Material m = Material.getMaterial(matSplit[0]); - if (m == null && use1_13) { - if (matSplit[0].equals("LONG_GRASS")) { - m = Material.GRASS; - } else { - m = Material.matchMaterial(matSplit[0], true); - } - debugLog("converting Data Material from " + matSplit[0] + " to " + m); - } - if (m == null) continue; - ItemStack item = new ItemStack(m, matSection.getInt(mat)); - if (matSplit.length == 2) { - item.setDurability((short) P.p.parseInt(matSplit[1])); - } - ingredients.add(item); - } - return ingredients; - } - - // returns Ingredients by id from the specified ingMap - public BIngredients getIngredients(Map ingMap, String id) { - if (!ingMap.isEmpty()) { - if (ingMap.containsKey(id)) { - return ingMap.get(id); - } - } - errorLog("Ingredient id: '" + id + "' not found in data.yml"); - return new BIngredients(); - } - - // loads BIngredients from an ingredient section - public BIngredients loadIngredients(ConfigurationSection section) { - if (section != null) { - return new BIngredients(deserializeIngredients(section), 0); - } else { - errorLog("Cauldron is missing Ingredient Section"); - } - return new BIngredients(); - } - - // load Block locations of given world - public void loadWorldData(String uuid, World world) { - - File file = new File(p.getDataFolder(), "data.yml"); - if (file.exists()) { - - FileConfiguration data = YamlConfiguration.loadConfiguration(file); - - // loading BCauldron - if (data.contains("BCauldron." + uuid)) { - ConfigurationSection section = data.getConfigurationSection("BCauldron." + uuid); - for (String cauldron : section.getKeys(false)) { - // block is splitted into x/y/z - String block = section.getString(cauldron + ".block"); - if (block != null) { - String[] splitted = block.split("/"); - if (splitted.length == 3) { - - Block worldBlock = world.getBlockAt(parseInt(splitted[0]), parseInt(splitted[1]), parseInt(splitted[2])); - BIngredients ingredients = loadIngredients(section.getConfigurationSection(cauldron + ".ingredients")); - int state = section.getInt(cauldron + ".state", 1); - - new BCauldron(worldBlock, ingredients, state); - } else { - errorLog("Incomplete Block-Data in data.yml: " + section.getCurrentPath() + "." + cauldron); - } - } else { - errorLog("Missing Block-Data in data.yml: " + section.getCurrentPath() + "." + cauldron); - } - } - } - - // loading Barrel - if (data.contains("Barrel." + uuid)) { - ConfigurationSection section = data.getConfigurationSection("Barrel." + uuid); - for (String barrel : section.getKeys(false)) { - // block spigot is splitted into x/y/z - String spigot = section.getString(barrel + ".spigot"); - if (spigot != null) { - String[] splitted = spigot.split("/"); - if (splitted.length == 3) { - - // load itemStacks from invSection - ConfigurationSection invSection = section.getConfigurationSection(barrel + ".inv"); - Block block = world.getBlockAt(parseInt(splitted[0]), parseInt(splitted[1]), parseInt(splitted[2])); - float time = (float) section.getDouble(barrel + ".time", 0.0); - byte sign = (byte) section.getInt(barrel + ".sign", 0); - String[] st = section.getString(barrel + ".st", "").split(","); - String[] wo = section.getString(barrel + ".wo", "").split(","); - - if (invSection != null) { - new Barrel(block, sign, st, wo, invSection.getValues(true), time); - } else { - // Barrel has no inventory - new Barrel(block, sign, st, wo, null, time); - } - - } else { - errorLog("Incomplete Block-Data in data.yml: " + section.getCurrentPath() + "." + barrel); - } - } else { - errorLog("Missing Block-Data in data.yml: " + section.getCurrentPath() + "." + barrel); - } - } - } - - // loading Wakeup - if (data.contains("Wakeup." + uuid)) { - ConfigurationSection section = data.getConfigurationSection("Wakeup." + uuid); - for (String wakeup : section.getKeys(false)) { - // loc of wakeup is splitted into x/y/z/pitch/yaw - String loc = section.getString(wakeup); - if (loc != null) { - String[] splitted = loc.split("/"); - if (splitted.length == 5) { - - double x = NumberUtils.toDouble(splitted[0]); - double y = NumberUtils.toDouble(splitted[1]); - double z = NumberUtils.toDouble(splitted[2]); - float pitch = NumberUtils.toFloat(splitted[3]); - float yaw = NumberUtils.toFloat(splitted[4]); - Location location = new Location(world, x, y, z, yaw, pitch); - - Wakeup.wakeups.add(new Wakeup(location)); - - } else { - errorLog("Incomplete Location-Data in data.yml: " + section.getCurrentPath() + "." + wakeup); - } - } - } - } - - } - } - - private boolean checkConfigs() { - File cfg = new File(p.getDataFolder(), "config.yml"); - if (!cfg.exists()) { - errorLog("No config.yml found, creating default file! You may want to choose a config according to your language!"); - errorLog("You can find them in plugins/Brewery/configs/"); - InputStream defconf = getResource("config/" + (use1_13 ? "v13/" : "v12/") + "en/config.yml"); - if (defconf == null) { - errorLog("default config file not found, your jarfile may be corrupt. Disabling Brewery!"); - return false; - } - try { - BUtil.saveFile(defconf, getDataFolder(), "config.yml", false); - } catch (IOException e) { - e.printStackTrace(); - return false; - } - } - if (!cfg.exists()) { - errorLog("default config file could not be copied, your jarfile may be corrupt. Disabling Brewery!"); - return false; - } - - copyDefaultConfigs(false); - return true; - } - - private void copyDefaultConfigs(boolean overwrite) { - File configs = new File(getDataFolder(), "configs"); - File languages = new File(getDataFolder(), "languages"); - for (String l : new String[] {"de", "en", "fr", "it", "zh", "tw"}) { - File lfold = new File(configs, l); - try { - BUtil.saveFile(getResource("config/" + (use1_13 ? "v13/" : "v12/") + l + "/config.yml"), lfold, "config.yml", overwrite); - BUtil.saveFile(getResource("languages/" + l + ".yml"), languages, l + ".yml", false); // Never overwrite languages for now - } catch (IOException e) { - if (!(l.equals("zh") || l.equals("tw"))) { - e.printStackTrace(); - } - } - } - } - - // Utility - public int parseInt(String string) { return NumberUtils.toInt(string, 0); } @@ -991,7 +528,7 @@ public class P extends JavaPlugin { // Runnables - public class DrunkRunnable implements Runnable { + public static class DrunkRunnable implements Runnable { @Override public void run() { if (!BPlayer.isEmpty()) { @@ -1003,7 +540,7 @@ public class P extends JavaPlugin { public class BreweryRunnable implements Runnable { @Override public void run() { - reloader = null; + BConfig.reloader = null; for (BCauldron cauldron : BCauldron.bcauldrons) { cauldron.onUpdate();// runs every min to update cooking time } diff --git a/src/com/dre/brewery/Wakeup.java b/src/com/dre/brewery/Wakeup.java index 1ee50d8..e578957 100644 --- a/src/com/dre/brewery/Wakeup.java +++ b/src/com/dre/brewery/Wakeup.java @@ -1,13 +1,13 @@ package com.dre.brewery; +import org.bukkit.Location; +import org.bukkit.command.CommandSender; +import org.bukkit.configuration.ConfigurationSection; +import org.bukkit.entity.Player; + import java.util.ArrayList; import java.util.Iterator; -import org.bukkit.configuration.ConfigurationSection; -import org.bukkit.command.CommandSender; -import org.bukkit.Location; -import org.bukkit.entity.Player; - public class Wakeup { public static ArrayList wakeups = new ArrayList<>(); diff --git a/src/com/dre/brewery/filedata/BConfig.java b/src/com/dre/brewery/filedata/BConfig.java new file mode 100644 index 0000000..b06cae3 --- /dev/null +++ b/src/com/dre/brewery/filedata/BConfig.java @@ -0,0 +1,257 @@ +package com.dre.brewery.filedata; + +import com.dre.brewery.*; +import com.dre.brewery.integration.WGBarrel; +import com.dre.brewery.integration.WGBarrel7; +import com.dre.brewery.integration.WGBarrelNew; +import com.dre.brewery.integration.WGBarrelOld; +import org.bukkit.Bukkit; +import org.bukkit.Material; +import org.bukkit.command.CommandSender; +import org.bukkit.configuration.ConfigurationSection; +import org.bukkit.configuration.file.FileConfiguration; +import org.bukkit.configuration.file.YamlConfiguration; +import org.bukkit.plugin.Plugin; +import org.bukkit.plugin.PluginManager; + +import java.io.File; +import java.io.IOException; +import java.io.InputStream; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +public class BConfig { + + public static final String configVersion = "1.8"; + public static boolean updateCheck; + public static CommandSender reloader; + + // Third Party Enabled + public static boolean useWG; //WorldGuard + public static WGBarrel wg; + public static boolean useLWC; //LWC + public static boolean useLB; //LogBlock + public static boolean useGP; //GriefPrevention + public static boolean hasVault; // Vault + public static boolean useCitadel; // CivCraft/DevotedMC Citadel + + // Barrel + public static boolean openEverywhere; + + //BPlayer + public static Map drainItems = new HashMap<>();// DrainItem Material and Strength + public static Material pukeItem; + public static int pukeDespawntime; + public static int hangoverTime; + public static boolean overdrinkKick; + public static boolean enableHome; + public static boolean enableLoginDisallow; + public static boolean enablePuke; + public static String homeType; + + //Brew + public static boolean colorInBarrels; // color the Lore while in Barrels + public static boolean colorInBrewer; // color the Lore while in Brewer + + public static P p = P.p; + + private static boolean checkConfigs() { + File cfg = new File(p.getDataFolder(), "config.yml"); + if (!cfg.exists()) { + p.errorLog("No config.yml found, creating default file! You may want to choose a config according to your language!"); + p.errorLog("You can find them in plugins/Brewery/configs/"); + InputStream defconf = p.getResource("config/" + (P.use1_13 ? "v13/" : "v12/") + "en/config.yml"); + if (defconf == null) { + p.errorLog("default config file not found, your jarfile may be corrupt. Disabling Brewery!"); + return false; + } + try { + BUtil.saveFile(defconf, p.getDataFolder(), "config.yml", false); + } catch (IOException e) { + e.printStackTrace(); + return false; + } + } + if (!cfg.exists()) { + p.errorLog("default config file could not be copied, your jarfile may be corrupt. Disabling Brewery!"); + return false; + } + + copyDefaultConfigs(false); + return true; + } + + private static void copyDefaultConfigs(boolean overwrite) { + File configs = new File(p.getDataFolder(), "configs"); + File languages = new File(p.getDataFolder(), "languages"); + for (String l : new String[] {"de", "en", "fr", "it", "zh", "tw"}) { + File lfold = new File(configs, l); + try { + BUtil.saveFile(p.getResource("config/" + (P.use1_13 ? "v13/" : "v12/") + l + "/config.yml"), lfold, "config.yml", overwrite); + BUtil.saveFile(p.getResource("languages/" + l + ".yml"), languages, l + ".yml", false); // Never overwrite languages for now + } catch (IOException e) { + if (!(l.equals("zh") || l.equals("tw"))) { + e.printStackTrace(); + } + } + } + } + + public static boolean readConfig() { + File file = new File(P.p.getDataFolder(), "config.yml"); + if (!checkConfigs()) { + return false; + } + FileConfiguration config = YamlConfiguration.loadConfiguration(file); + + // Set the Language + p.language = config.getString("language", "en"); + + // Load LanguageReader + p.languageReader = new LanguageReader(new File(p.getDataFolder(), "languages/" + p.language + ".yml")); + + // Has to config still got old materials + boolean oldMat = config.getBoolean("oldMat", false); + + // Check if config is the newest version + String version = config.getString("version", null); + if (version != null) { + if (!version.equals(configVersion) || (oldMat && P.use1_13)) { + copyDefaultConfigs(true); + new ConfigUpdater(file).update(version, oldMat, p.language); + P.p.log("Config Updated to version: " + configVersion); + config = YamlConfiguration.loadConfiguration(file); + } + } + + // If the Update Checker should be enabled + updateCheck = config.getBoolean("updateCheck", false); + + PluginManager plMan = p.getServer().getPluginManager(); + + // Third-Party + useWG = config.getBoolean("useWorldGuard", true) && plMan.isPluginEnabled("WorldGuard"); + + if (useWG) { + Plugin plugin = Bukkit.getPluginManager().getPlugin("WorldEdit"); + if (plugin != null) { + String wgv = plugin.getDescription().getVersion(); + if (wgv.startsWith("6.")) { + wg = new WGBarrelNew(); + } else if (wgv.startsWith("5.")) { + wg = new WGBarrelOld(); + } else { + wg = new WGBarrel7(); + } + } + if (wg == null) { + P.p.errorLog("Failed loading WorldGuard Integration! Opening Barrels will NOT work!"); + P.p.errorLog("Brewery was tested with version 5.8, 6.1 and 7.0 of WorldGuard!"); + P.p.errorLog("Disable the WorldGuard support in the config and do /brew reload"); + } + } + useLWC = config.getBoolean("useLWC", true) && plMan.isPluginEnabled("LWC"); + useGP = config.getBoolean("useGriefPrevention", true) && plMan.isPluginEnabled("GriefPrevention"); + useLB = config.getBoolean("useLogBlock", false) && plMan.isPluginEnabled("LogBlock"); + useCitadel = config.getBoolean("useCitadel", false) && plMan.isPluginEnabled("Citadel"); + // The item util has been removed in Vault 1.7+ + hasVault = plMan.isPluginEnabled("Vault") + && Integer.parseInt(plMan.getPlugin("Vault").getDescription().getVersion().split("\\.")[1]) <= 6; + + // various Settings + DataSave.autosave = config.getInt("autosave", 3); + P.debug = config.getBoolean("debug", false); + pukeItem = Material.matchMaterial(config.getString("pukeItem", "SOUL_SAND")); + hangoverTime = config.getInt("hangoverDays", 0) * 24 * 60; + overdrinkKick = config.getBoolean("enableKickOnOverdrink", false); + enableHome = config.getBoolean("enableHome", false); + enableLoginDisallow = config.getBoolean("enableLoginDisallow", false); + enablePuke = config.getBoolean("enablePuke", false); + pukeDespawntime = config.getInt("pukeDespawntime", 60) * 20; + homeType = config.getString("homeType", null); + colorInBarrels = config.getBoolean("colorInBarrels", false); + colorInBrewer = config.getBoolean("colorInBrewer", false); + openEverywhere = config.getBoolean("openLargeBarrelEverywhere", false); + MCBarrel.maxBrews = config.getInt("maxBrewsInMCBarrels", 6); + + // loading recipes + ConfigurationSection configSection = config.getConfigurationSection("recipes"); + if (configSection != null) { + for (String recipeId : configSection.getKeys(false)) { + BRecipe recipe = new BRecipe(configSection, recipeId); + if (recipe.isValid()) { + BIngredients.recipes.add(recipe); + } else { + p.errorLog("Loading the Recipe with id: '" + recipeId + "' failed!"); + } + } + } + + // loading cooked names and possible ingredients + configSection = config.getConfigurationSection("cooked"); + if (configSection != null) { + for (String ingredient : configSection.getKeys(false)) { + Material mat = Material.matchMaterial(ingredient); + if (mat == null && hasVault) { + try { + net.milkbowl.vault.item.ItemInfo vaultItem = net.milkbowl.vault.item.Items.itemByString(ingredient); + if (vaultItem != null) { + mat = vaultItem.getType(); + } + } catch (Exception e) { + P.p.errorLog("Could not check vault for Item Name"); + e.printStackTrace(); + } + } + if (mat != null) { + BIngredients.cookedNames.put(mat, (configSection.getString(ingredient, null))); + BIngredients.possibleIngredients.add(mat); + } else { + p.errorLog("Unknown Material: " + ingredient); + } + } + } + + // loading drainItems + List drainList = config.getStringList("drainItems"); + if (drainList != null) { + for (String drainString : drainList) { + String[] drainSplit = drainString.split("/"); + if (drainSplit.length > 1) { + Material mat = Material.matchMaterial(drainSplit[0]); + int strength = p.parseInt(drainSplit[1]); + if (mat == null && hasVault && strength > 0) { + try { + net.milkbowl.vault.item.ItemInfo vaultItem = net.milkbowl.vault.item.Items.itemByString(drainSplit[0]); + if (vaultItem != null) { + mat = vaultItem.getType(); + } + } catch (Exception e) { + P.p.errorLog("Could not check vault for Item Name"); + e.printStackTrace(); + } + } + if (mat != null && strength > 0) { + drainItems.put(mat, strength); + } + } + } + } + + // Loading Words + if (config.getBoolean("enableChatDistortion", false)) { + for (Map map : config.getMapList("words")) { + new DistortChat(map); + } + for (String bypass : config.getStringList("distortBypass")) { + DistortChat.ignoreText.add(bypass.split(",")); + } + DistortChat.commands = config.getStringList("distortCommands"); + } + DistortChat.log = config.getBoolean("logRealChat", false); + DistortChat.doSigns = config.getBoolean("distortSignText", false); + + return true; + } +} diff --git a/src/com/dre/brewery/filedata/BData.java b/src/com/dre/brewery/filedata/BData.java new file mode 100644 index 0000000..06a1415 --- /dev/null +++ b/src/com/dre/brewery/filedata/BData.java @@ -0,0 +1,258 @@ +package com.dre.brewery.filedata; + +import com.dre.brewery.*; +import org.apache.commons.lang.math.NumberUtils; +import org.bukkit.Location; +import org.bukkit.Material; +import org.bukkit.World; +import org.bukkit.block.Block; +import org.bukkit.configuration.ConfigurationSection; +import org.bukkit.configuration.file.FileConfiguration; +import org.bukkit.configuration.file.YamlConfiguration; +import org.bukkit.inventory.ItemStack; + +import java.io.File; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Map; +import java.util.UUID; + +public class BData { + + + // load all Data + public static void readData() { + File file = new File(P.p.getDataFolder(), "data.yml"); + if (file.exists()) { + + FileConfiguration data = YamlConfiguration.loadConfiguration(file); + + Brew.installTime = data.getLong("installTime", System.currentTimeMillis()); + MCBarrel.mcBarrelTime = data.getLong("MCBarrelTime", 0); + + Brew.loadSeed(data); + + // Check if data is the newest version + String version = data.getString("Version", null); + if (version != null) { + if (!version.equals(DataSave.dataVersion)) { + P.p.log("Data File is being updated..."); + new DataUpdater(data, file).update(version); + data = YamlConfiguration.loadConfiguration(file); + P.p.log("Data Updated to version: " + DataSave.dataVersion); + } + } + + // loading Ingredients into ingMap + Map ingMap = new HashMap<>(); + ConfigurationSection section = data.getConfigurationSection("Ingredients"); + if (section != null) { + for (String id : section.getKeys(false)) { + ConfigurationSection matSection = section.getConfigurationSection(id + ".mats"); + if (matSection != null) { + // matSection has all the materials + amount as Integers + ArrayList ingredients = deserializeIngredients(matSection); + ingMap.put(id, new BIngredients(ingredients, section.getInt(id + ".cookedTime", 0), true)); + } else { + P.p.errorLog("Ingredient id: '" + id + "' incomplete in data.yml"); + } + } + } + + // loading Brew legacy + section = data.getConfigurationSection("Brew"); + if (section != null) { + // All sections have the UID as name + for (String uid : section.getKeys(false)) { + BIngredients ingredients = getIngredients(ingMap, section.getString(uid + ".ingId")); + int quality = section.getInt(uid + ".quality", 0); + byte distillRuns = (byte) section.getInt(uid + ".distillRuns", 0); + float ageTime = (float) section.getDouble(uid + ".ageTime", 0.0); + float wood = (float) section.getDouble(uid + ".wood", -1.0); + String recipe = section.getString(uid + ".recipe", null); + boolean unlabeled = section.getBoolean(uid + ".unlabeled", false); + boolean persistent = section.getBoolean(uid + ".persist", false); + boolean stat = section.getBoolean(uid + ".stat", false); + int lastUpdate = section.getInt("lastUpdate", 0); + + Brew.loadLegacy(ingredients, P.p.parseInt(uid), quality, distillRuns, ageTime, wood, recipe, unlabeled, persistent, stat, lastUpdate); + } + } + + // loading BPlayer + section = data.getConfigurationSection("Player"); + if (section != null) { + // keys have players name + for (String name : section.getKeys(false)) { + try { + //noinspection ResultOfMethodCallIgnored + UUID.fromString(name); + if (!P.useUUID) { + continue; + } + } catch (IllegalArgumentException e) { + if (P.useUUID) { + continue; + } + } + + int quality = section.getInt(name + ".quality"); + int drunk = section.getInt(name + ".drunk"); + int offDrunk = section.getInt(name + ".offDrunk", 0); + + new BPlayer(name, quality, drunk, offDrunk); + } + } + + for (World world : P.p.getServer().getWorlds()) { + if (world.getName().startsWith("DXL_")) { + loadWorldData(BUtil.getDxlName(world.getName()), world); + } else { + loadWorldData(world.getUID().toString(), world); + } + } + + } else { + P.p.errorLog("No data.yml found, will create new one!"); + } + } + + public static ArrayList deserializeIngredients(ConfigurationSection matSection) { + ArrayList ingredients = new ArrayList<>(); + for (String mat : matSection.getKeys(false)) { + String[] matSplit = mat.split(","); + Material m = Material.getMaterial(matSplit[0]); + if (m == null && P.use1_13) { + if (matSplit[0].equals("LONG_GRASS")) { + m = Material.GRASS; + } else { + m = Material.matchMaterial(matSplit[0], true); + } + P.p.debugLog("converting Data Material from " + matSplit[0] + " to " + m); + } + if (m == null) continue; + ItemStack item = new ItemStack(m, matSection.getInt(mat)); + if (matSplit.length == 2) { + item.setDurability((short) P.p.parseInt(matSplit[1])); + } + ingredients.add(item); + } + return ingredients; + } + + // returns Ingredients by id from the specified ingMap + public static BIngredients getIngredients(Map ingMap, String id) { + if (!ingMap.isEmpty()) { + if (ingMap.containsKey(id)) { + return ingMap.get(id); + } + } + P.p.errorLog("Ingredient id: '" + id + "' not found in data.yml"); + return new BIngredients(); + } + + // loads BIngredients from an ingredient section + public static BIngredients loadIngredients(ConfigurationSection section) { + if (section != null) { + return new BIngredients(deserializeIngredients(section), 0); + } else { + P.p.errorLog("Cauldron is missing Ingredient Section"); + } + return new BIngredients(); + } + + // load Block locations of given world + public static void loadWorldData(String uuid, World world) { + + File file = new File(P.p.getDataFolder(), "data.yml"); + if (file.exists()) { + + FileConfiguration data = YamlConfiguration.loadConfiguration(file); + + // loading BCauldron + if (data.contains("BCauldron." + uuid)) { + ConfigurationSection section = data.getConfigurationSection("BCauldron." + uuid); + for (String cauldron : section.getKeys(false)) { + // block is splitted into x/y/z + String block = section.getString(cauldron + ".block"); + if (block != null) { + String[] splitted = block.split("/"); + if (splitted.length == 3) { + + Block worldBlock = world.getBlockAt(P.p.parseInt(splitted[0]), P.p.parseInt(splitted[1]), P.p.parseInt(splitted[2])); + BIngredients ingredients = loadIngredients(section.getConfigurationSection(cauldron + ".ingredients")); + int state = section.getInt(cauldron + ".state", 1); + + new BCauldron(worldBlock, ingredients, state); + } else { + P.p.errorLog("Incomplete Block-Data in data.yml: " + section.getCurrentPath() + "." + cauldron); + } + } else { + P.p.errorLog("Missing Block-Data in data.yml: " + section.getCurrentPath() + "." + cauldron); + } + } + } + + // loading Barrel + if (data.contains("Barrel." + uuid)) { + ConfigurationSection section = data.getConfigurationSection("Barrel." + uuid); + for (String barrel : section.getKeys(false)) { + // block spigot is splitted into x/y/z + String spigot = section.getString(barrel + ".spigot"); + if (spigot != null) { + String[] splitted = spigot.split("/"); + if (splitted.length == 3) { + + // load itemStacks from invSection + ConfigurationSection invSection = section.getConfigurationSection(barrel + ".inv"); + Block block = world.getBlockAt(P.p.parseInt(splitted[0]), P.p.parseInt(splitted[1]), P.p.parseInt(splitted[2])); + float time = (float) section.getDouble(barrel + ".time", 0.0); + byte sign = (byte) section.getInt(barrel + ".sign", 0); + String[] st = section.getString(barrel + ".st", "").split(","); + String[] wo = section.getString(barrel + ".wo", "").split(","); + + if (invSection != null) { + new Barrel(block, sign, st, wo, invSection.getValues(true), time); + } else { + // Barrel has no inventory + new Barrel(block, sign, st, wo, null, time); + } + + } else { + P.p.errorLog("Incomplete Block-Data in data.yml: " + section.getCurrentPath() + "." + barrel); + } + } else { + P.p.errorLog("Missing Block-Data in data.yml: " + section.getCurrentPath() + "." + barrel); + } + } + } + + // loading Wakeup + if (data.contains("Wakeup." + uuid)) { + ConfigurationSection section = data.getConfigurationSection("Wakeup." + uuid); + for (String wakeup : section.getKeys(false)) { + // loc of wakeup is splitted into x/y/z/pitch/yaw + String loc = section.getString(wakeup); + if (loc != null) { + String[] splitted = loc.split("/"); + if (splitted.length == 5) { + + double x = NumberUtils.toDouble(splitted[0]); + double y = NumberUtils.toDouble(splitted[1]); + double z = NumberUtils.toDouble(splitted[2]); + float pitch = NumberUtils.toFloat(splitted[3]); + float yaw = NumberUtils.toFloat(splitted[4]); + Location location = new Location(world, x, y, z, yaw, pitch); + + Wakeup.wakeups.add(new Wakeup(location)); + + } else { + P.p.errorLog("Incomplete Location-Data in data.yml: " + section.getCurrentPath() + "." + wakeup); + } + } + } + } + + } + } +} diff --git a/src/com/dre/brewery/integration/IntegrationListener.java b/src/com/dre/brewery/integration/IntegrationListener.java index 5113366..ba485cc 100644 --- a/src/com/dre/brewery/integration/IntegrationListener.java +++ b/src/com/dre/brewery/integration/IntegrationListener.java @@ -1,10 +1,13 @@ package com.dre.brewery.integration; import com.dre.brewery.Barrel; +import com.dre.brewery.LegacyUtil; import com.dre.brewery.P; import com.dre.brewery.api.events.barrel.BarrelAccessEvent; import com.dre.brewery.api.events.barrel.BarrelDestroyEvent; import com.dre.brewery.api.events.barrel.BarrelRemoveEvent; +import com.dre.brewery.filedata.BConfig; +import org.bukkit.block.Block; import org.bukkit.entity.Player; import org.bukkit.event.EventHandler; import org.bukkit.event.EventPriority; @@ -16,11 +19,11 @@ public class IntegrationListener implements Listener { @EventHandler(priority = EventPriority.LOWEST, ignoreCancelled = true) public void onBarrelAccessLowest(BarrelAccessEvent event) { - if (P.p.useWG) { + if (BConfig.useWG) { Plugin plugin = P.p.getServer().getPluginManager().getPlugin("WorldGuard"); if (plugin != null) { try { - if (!P.p.wg.checkAccess(event.getPlayer(), event.getSpigot(), plugin)) { + if (!BConfig.wg.checkAccess(event.getPlayer(), event.getSpigot(), plugin)) { event.setCancelled(true); } } catch (Throwable e) { @@ -43,11 +46,12 @@ public class IntegrationListener implements Listener { @EventHandler(priority = EventPriority.LOW, ignoreCancelled = true) public void onBarrelAccess(BarrelAccessEvent event) { - if (P.p.useGP) { + if (BConfig.useGP) { if (P.p.getServer().getPluginManager().isPluginEnabled("GriefPrevention")) { try { if (!GriefPreventionBarrel.checkAccess(event)) { event.setCancelled(true); + return; } } catch (Throwable e) { event.setCancelled(true); @@ -65,11 +69,42 @@ public class IntegrationListener implements Listener { } } } + + if (BConfig.useLWC) { + Plugin plugin = P.p.getServer().getPluginManager().getPlugin("LWC"); + if (plugin != null) { + + // If the Clicked Block was the Sign, LWC already knows and we dont need to do anything here + if (!LegacyUtil.isSign(event.getClickedBlock().getType())) { + Block sign = event.getBarrel().getSignOfSpigot(); + // If the Barrel does not have a Sign, it cannot be locked + if (!sign.equals(event.getClickedBlock())) { + Player player = event.getPlayer(); + try { + if (!LWCBarrel.checkAccess(player, sign, plugin)) { + event.setCancelled(true); + } + } catch (Throwable e) { + P.p.errorLog("Failed to Check LWC for Barrel Open Permissions!"); + P.p.errorLog("Brewery was tested with version 4.5.0 of LWC!"); + P.p.errorLog("Disable the LWC support in the config and do /brew reload"); + e.printStackTrace(); + if (player.hasPermission("brewery.admin") || player.hasPermission("brewery.mod")) { + P.p.msg(player, "&cLWC check Error, Brewery was tested with up to v4.5.0 of LWC"); + P.p.msg(player, "&cSet &7useLWC: false &cin the config and /brew reload"); + } else { + P.p.msg(player, "&cError breaking Barrel, please report to an Admin!"); + } + } + } + } + } + } } @EventHandler(ignoreCancelled = true, priority = EventPriority.LOW) public void onBarrelDestroy(BarrelDestroyEvent event) { - if (!P.p.useLWC) return; + if (!BConfig.useLWC) return; if (event.hasPlayer()) { try { @@ -113,7 +148,7 @@ public class IntegrationListener implements Listener { @EventHandler public void onBarrelRemove(BarrelRemoveEvent event) { - if (!P.p.useLWC) return; + if (!BConfig.useLWC) return; try { LWCBarrel.remove(event.getBarrel()); @@ -126,7 +161,7 @@ public class IntegrationListener implements Listener { @EventHandler public void onInventoryClose(InventoryCloseEvent event) { - if (P.p.useLB) { + if (BConfig.useLB) { if (event.getInventory().getHolder() instanceof Barrel) { try { LogBlockBarrel.closeBarrel(event.getPlayer(), event.getInventory()); diff --git a/src/com/dre/brewery/integration/LWCBarrel.java b/src/com/dre/brewery/integration/LWCBarrel.java index 695f87d..7fcc274 100644 --- a/src/com/dre/brewery/integration/LWCBarrel.java +++ b/src/com/dre/brewery/integration/LWCBarrel.java @@ -7,11 +7,15 @@ import com.griefcraft.lwc.LWC; import com.griefcraft.model.Flag; import com.griefcraft.model.Protection; import com.griefcraft.scripting.event.LWCProtectionDestroyEvent; +import org.bukkit.Material; import org.bukkit.block.Block; +import org.bukkit.block.BlockFace; import org.bukkit.entity.Player; import org.bukkit.event.EventException; import org.bukkit.event.HandlerList; +import org.bukkit.event.block.Action; import org.bukkit.event.player.PlayerInteractEvent; +import org.bukkit.inventory.ItemStack; import org.bukkit.plugin.Plugin; import org.bukkit.plugin.RegisteredListener; @@ -46,7 +50,7 @@ public class LWCBarrel { return false; } - public static boolean checkAccess(Player player, Block sign, PlayerInteractEvent event, Plugin plugin) { + public static boolean checkAccess(Player player, Block sign, Plugin plugin) { LWC lwc = LWC.getInstance(); // Disallow Chest Access with these permissions @@ -56,7 +60,7 @@ public class LWCBarrel { } // We just fake a BlockInteractEvent on the Sign for LWC, it handles it nicely. Otherwise we could copy LWCs listener in here... - PlayerInteractEvent lwcEvent = new PlayerInteractEvent(player, event.getAction(), event.getItem(), sign, event.getBlockFace()); + PlayerInteractEvent lwcEvent = new PlayerInteractEvent(player, Action.RIGHT_CLICK_BLOCK, new ItemStack(Material.AIR), sign, BlockFace.EAST); for (RegisteredListener listener : HandlerList.getRegisteredListeners(plugin)) { if (listener.getListener() instanceof LWCPlayerListener) { try { diff --git a/src/com/dre/brewery/listeners/BlockListener.java b/src/com/dre/brewery/listeners/BlockListener.java index f272cd8..96bcd58 100644 --- a/src/com/dre/brewery/listeners/BlockListener.java +++ b/src/com/dre/brewery/listeners/BlockListener.java @@ -1,79 +1,79 @@ -package com.dre.brewery.listeners; - -import com.dre.brewery.BPlayer; -import com.dre.brewery.BUtil; -import com.dre.brewery.Barrel; -import com.dre.brewery.P; -import com.dre.brewery.Words; -import com.dre.brewery.api.events.barrel.BarrelDestroyEvent; -import org.bukkit.block.Block; -import org.bukkit.entity.Player; -import org.bukkit.event.EventHandler; -import org.bukkit.event.EventPriority; -import org.bukkit.event.Listener; -import org.bukkit.event.block.BlockBreakEvent; -import org.bukkit.event.block.BlockBurnEvent; -import org.bukkit.event.block.BlockPistonExtendEvent; -import org.bukkit.event.block.BlockPistonRetractEvent; -import org.bukkit.event.block.SignChangeEvent; - -public class BlockListener implements Listener { - - @EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true) - public void onSignChange(SignChangeEvent event) { - String[] lines = event.getLines(); - - if (lines[0].equalsIgnoreCase("Barrel") || lines[0].equalsIgnoreCase(P.p.languageReader.get("Etc_Barrel"))) { - Player player = event.getPlayer(); - if (!player.hasPermission("brewery.createbarrel.small") && !player.hasPermission("brewery.createbarrel.big")) { - P.p.msg(player, P.p.languageReader.get("Perms_NoBarrelCreate")); - return; - } - if (Barrel.create(event.getBlock(), player)) { - P.p.msg(player, P.p.languageReader.get("Player_BarrelCreated")); - } - } - } - - @EventHandler(priority = EventPriority.LOW, ignoreCancelled = true) - public void onSignChangeLow(SignChangeEvent event) { - if (Words.doSigns) { - if (BPlayer.hasPlayer(event.getPlayer())) { - Words.signWrite(event); - } - } - } - - @EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true) - public void onBlockBreak(BlockBreakEvent event) { - if (!BUtil.blockDestroy(event.getBlock(), event.getPlayer(), BarrelDestroyEvent.Reason.PLAYER)) { - event.setCancelled(true); - } - } - - @EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true) - public void onBlockBurn(BlockBurnEvent event) { - BUtil.blockDestroy(event.getBlock(), null, BarrelDestroyEvent.Reason.BURNED); - } - - @EventHandler(priority = EventPriority.HIGH, ignoreCancelled = true) - public void onPistonRetract(BlockPistonRetractEvent event) { - if (event.isSticky()) { - Block block = event.getRetractLocation().getBlock(); - - if (Barrel.get(block) != null) { - event.setCancelled(true); - } - } - } - - @EventHandler(priority = EventPriority.HIGH, ignoreCancelled = true) - public void onPistonExtend(BlockPistonExtendEvent event) { - for (Block block : event.getBlocks()) { - if (Barrel.get(block) != null) { - event.setCancelled(true); - return; - } - } - } -} +package com.dre.brewery.listeners; + +import com.dre.brewery.BPlayer; +import com.dre.brewery.BUtil; +import com.dre.brewery.Barrel; +import com.dre.brewery.P; +import com.dre.brewery.DistortChat; +import com.dre.brewery.api.events.barrel.BarrelDestroyEvent; +import org.bukkit.block.Block; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.EventPriority; +import org.bukkit.event.Listener; +import org.bukkit.event.block.BlockBreakEvent; +import org.bukkit.event.block.BlockBurnEvent; +import org.bukkit.event.block.BlockPistonExtendEvent; +import org.bukkit.event.block.BlockPistonRetractEvent; +import org.bukkit.event.block.SignChangeEvent; + +public class BlockListener implements Listener { + + @EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true) + public void onSignChange(SignChangeEvent event) { + String[] lines = event.getLines(); + + if (lines[0].equalsIgnoreCase("Barrel") || lines[0].equalsIgnoreCase(P.p.languageReader.get("Etc_Barrel"))) { + Player player = event.getPlayer(); + if (!player.hasPermission("brewery.createbarrel.small") && !player.hasPermission("brewery.createbarrel.big")) { + P.p.msg(player, P.p.languageReader.get("Perms_NoBarrelCreate")); + return; + } + if (Barrel.create(event.getBlock(), player)) { + P.p.msg(player, P.p.languageReader.get("Player_BarrelCreated")); + } + } + } + + @EventHandler(priority = EventPriority.LOW, ignoreCancelled = true) + public void onSignChangeLow(SignChangeEvent event) { + if (DistortChat.doSigns) { + if (BPlayer.hasPlayer(event.getPlayer())) { + DistortChat.signWrite(event); + } + } + } + + @EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true) + public void onBlockBreak(BlockBreakEvent event) { + if (!BUtil.blockDestroy(event.getBlock(), event.getPlayer(), BarrelDestroyEvent.Reason.PLAYER)) { + event.setCancelled(true); + } + } + + @EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true) + public void onBlockBurn(BlockBurnEvent event) { + BUtil.blockDestroy(event.getBlock(), null, BarrelDestroyEvent.Reason.BURNED); + } + + @EventHandler(priority = EventPriority.HIGH, ignoreCancelled = true) + public void onPistonRetract(BlockPistonRetractEvent event) { + if (event.isSticky()) { + Block block = event.getRetractLocation().getBlock(); + + if (Barrel.get(block) != null) { + event.setCancelled(true); + } + } + } + + @EventHandler(priority = EventPriority.HIGH, ignoreCancelled = true) + public void onPistonExtend(BlockPistonExtendEvent event) { + for (Block block : event.getBlocks()) { + if (Barrel.get(block) != null) { + event.setCancelled(true); + return; + } + } + } +} diff --git a/src/com/dre/brewery/listeners/CommandListener.java b/src/com/dre/brewery/listeners/CommandListener.java index f200c45..02f97a7 100644 --- a/src/com/dre/brewery/listeners/CommandListener.java +++ b/src/com/dre/brewery/listeners/CommandListener.java @@ -2,6 +2,7 @@ package com.dre.brewery.listeners; import com.dre.brewery.*; import com.dre.brewery.api.events.brew.BrewModifyEvent; +import com.dre.brewery.filedata.BConfig; import org.bukkit.Material; import org.bukkit.command.Command; import org.bukkit.command.CommandExecutor; @@ -323,7 +324,7 @@ public class CommandListener implements CommandExecutor { if (player != null) { bPlayer.drinkCap(player); } else { - if (!BPlayer.overdrinkKick) { + if (!BConfig.overdrinkKick) { bPlayer.setData(100, 0); } } @@ -360,82 +361,81 @@ public class CommandListener implements CommandExecutor { } public void cmdItemName(CommandSender sender) { - if (sender instanceof Player) { - - Player player = (Player) sender; - ItemStack hand = P.use1_9 ? player.getInventory().getItemInMainHand() : player.getItemInHand(); - if (hand != null) { - p.msg(sender, p.languageReader.get("CMD_Configname", hand.getType().name().toLowerCase(Locale.ENGLISH))); - } else { - p.msg(sender, p.languageReader.get("CMD_Configname_Error")); - } - - } else { + if (!(sender instanceof Player)) { p.msg(sender, p.languageReader.get("Error_PlayerCommand")); + return; } + + Player player = (Player) sender; + ItemStack hand = P.use1_9 ? player.getInventory().getItemInMainHand() : player.getItemInHand(); + if (hand != null) { + p.msg(sender, p.languageReader.get("CMD_Configname", hand.getType().name().toLowerCase(Locale.ENGLISH))); + } else { + p.msg(sender, p.languageReader.get("CMD_Configname_Error")); + } + } @Deprecated @SuppressWarnings("deprecation") public void cmdCopy(CommandSender sender, int count) { - if (sender instanceof Player) { - if (count < 1 || count > 36) { - p.msg(sender, p.languageReader.get("Etc_Usage")); - p.msg(sender, p.languageReader.get("Help_Copy")); + if (!(sender instanceof Player)) { + p.msg(sender, p.languageReader.get("Error_PlayerCommand")); + return; + } + if (count < 1 || count > 36) { + p.msg(sender, p.languageReader.get("Etc_Usage")); + p.msg(sender, p.languageReader.get("Help_Copy")); + return; + } + Player player = (Player) sender; + ItemStack hand = player.getItemInHand(); + if (hand != null) { + Brew brew = Brew.get(hand); + if (brew != null) { + while (count > 0) { + ItemStack item = hand.clone(); + if (!(player.getInventory().addItem(item)).isEmpty()) { + p.msg(sender, p.languageReader.get("CMD_Copy_Error", "" + count)); + return; + } + count--; + } + if (brew.isPersistent()) { + p.msg(sender, p.languageReader.get("CMD_CopyNotPersistent")); + } return; } - Player player = (Player) sender; - ItemStack hand = player.getItemInHand(); - if (hand != null) { - Brew brew = Brew.get(hand); - if (brew != null) { - while (count > 0) { - ItemStack item = hand.clone(); - if (!(player.getInventory().addItem(item)).isEmpty()) { - p.msg(sender, p.languageReader.get("CMD_Copy_Error", "" + count)); - return; - } - count--; - } - if (brew.isPersistent()) { - p.msg(sender, p.languageReader.get("CMD_CopyNotPersistent")); - } - return; - } - } - - p.msg(sender, p.languageReader.get("Error_ItemNotPotion")); - - } else { - p.msg(sender, p.languageReader.get("Error_PlayerCommand")); } + p.msg(sender, p.languageReader.get("Error_ItemNotPotion")); + } @Deprecated @SuppressWarnings("deprecation") public void cmdDelete(CommandSender sender) { - if (sender instanceof Player) { - Player player = (Player) sender; - ItemStack hand = player.getItemInHand(); - if (hand != null) { - Brew brew = Brew.get(hand); - if (brew != null) { - if (brew.isPersistent()) { - p.msg(sender, p.languageReader.get("CMD_PersistRemove")); - } else { - //brew.remove(hand); - player.setItemInHand(new ItemStack(Material.AIR)); - } - return; - } - } - p.msg(sender, p.languageReader.get("Error_ItemNotPotion")); - } else { + if (!(sender instanceof Player)) { p.msg(sender, p.languageReader.get("Error_PlayerCommand")); + return; } + Player player = (Player) sender; + ItemStack hand = player.getItemInHand(); + if (hand != null) { + Brew brew = Brew.get(hand); + if (brew != null) { + if (brew.isPersistent()) { + p.msg(sender, p.languageReader.get("CMD_PersistRemove")); + } else { + //brew.remove(hand); + player.setItemInHand(new ItemStack(Material.AIR)); + } + return; + } + } + p.msg(sender, p.languageReader.get("Error_ItemNotPotion")); } @@ -443,101 +443,101 @@ public class CommandListener implements CommandExecutor { @SuppressWarnings("deprecation") public void cmdPersist(CommandSender sender) { - if (sender instanceof Player) { - Player player = (Player) sender; - ItemStack hand = player.getItemInHand(); - if (hand != null) { - Brew brew = Brew.get(hand); - if (brew != null) { - if (brew.isPersistent()) { - brew.removePersistence(); - brew.setStatic(false, hand); - p.msg(sender, p.languageReader.get("CMD_UnPersist")); - } else { - brew.makePersistent(); - brew.setStatic(true, hand); - p.msg(sender, p.languageReader.get("CMD_Persistent")); - } - brew.touch(); - brew.save(hand); - return; - } - } - p.msg(sender, p.languageReader.get("Error_ItemNotPotion")); - } else { + if (!(sender instanceof Player)) { p.msg(sender, p.languageReader.get("Error_PlayerCommand")); + return; } + Player player = (Player) sender; + ItemStack hand = player.getItemInHand(); + if (hand != null) { + Brew brew = Brew.get(hand); + if (brew != null) { + if (brew.isPersistent()) { + brew.removePersistence(); + brew.setStatic(false, hand); + p.msg(sender, p.languageReader.get("CMD_UnPersist")); + } else { + brew.makePersistent(); + brew.setStatic(true, hand); + p.msg(sender, p.languageReader.get("CMD_Persistent")); + } + brew.touch(); + brew.save(hand); + return; + } + } + p.msg(sender, p.languageReader.get("Error_ItemNotPotion")); } @SuppressWarnings("deprecation") public void cmdStatic(CommandSender sender) { - if (sender instanceof Player) { - Player player = (Player) sender; - ItemStack hand = player.getItemInHand(); - if (hand != null) { - Brew brew = Brew.get(hand); - if (brew != null) { - if (brew.isStatic()) { - if (!brew.isPersistent()) { - brew.setStatic(false, hand); - p.msg(sender, p.languageReader.get("CMD_NonStatic")); - } else { - p.msg(sender, p.languageReader.get("Error_PersistStatic")); - } + if (!(sender instanceof Player)) { + p.msg(sender, p.languageReader.get("Error_PlayerCommand")); + return; + } + Player player = (Player) sender; + ItemStack hand = player.getItemInHand(); + if (hand != null) { + Brew brew = Brew.get(hand); + if (brew != null) { + if (brew.isStatic()) { + if (!brew.isPersistent()) { + brew.setStatic(false, hand); + p.msg(sender, p.languageReader.get("CMD_NonStatic")); } else { - brew.setStatic(true, hand); - p.msg(sender, p.languageReader.get("CMD_Static")); + p.msg(sender, p.languageReader.get("Error_PersistStatic")); } - brew.touch(); - ItemMeta meta = hand.getItemMeta(); - BrewModifyEvent modifyEvent = new BrewModifyEvent(brew, meta, BrewModifyEvent.Type.STATIC); - P.p.getServer().getPluginManager().callEvent(modifyEvent); - if (modifyEvent.isCancelled()) { - return; - } - brew.save(meta); - hand.setItemMeta(meta); + } else { + brew.setStatic(true, hand); + p.msg(sender, p.languageReader.get("CMD_Static")); + } + brew.touch(); + ItemMeta meta = hand.getItemMeta(); + BrewModifyEvent modifyEvent = new BrewModifyEvent(brew, meta, BrewModifyEvent.Type.STATIC); + P.p.getServer().getPluginManager().callEvent(modifyEvent); + if (modifyEvent.isCancelled()) { return; } + brew.save(meta); + hand.setItemMeta(meta); + return; } - p.msg(sender, p.languageReader.get("Error_ItemNotPotion")); - } else { - p.msg(sender, p.languageReader.get("Error_PlayerCommand")); } + p.msg(sender, p.languageReader.get("Error_ItemNotPotion")); } @SuppressWarnings("deprecation") public void cmdUnlabel(CommandSender sender) { - if (sender instanceof Player) { - Player player = (Player) sender; - ItemStack hand = player.getItemInHand(); - if (hand != null) { - Brew brew = Brew.get(hand); - if (brew != null) { - ItemMeta origMeta = hand.getItemMeta(); - brew.unLabel(hand); - brew.touch(); - ItemMeta meta = hand.getItemMeta(); - BrewModifyEvent modifyEvent = new BrewModifyEvent(brew, meta, BrewModifyEvent.Type.UNLABEL); - P.p.getServer().getPluginManager().callEvent(modifyEvent); - if (modifyEvent.isCancelled()) { - hand.setItemMeta(origMeta); - return; - } - brew.save(meta); - hand.setItemMeta(meta); - p.msg(sender, p.languageReader.get("CMD_UnLabel")); + if (!(sender instanceof Player)) { + p.msg(sender, p.languageReader.get("Error_PlayerCommand")); + return; + } + Player player = (Player) sender; + ItemStack hand = player.getItemInHand(); + if (hand != null) { + Brew brew = Brew.get(hand); + if (brew != null) { + ItemMeta origMeta = hand.getItemMeta(); + brew.unLabel(hand); + brew.touch(); + ItemMeta meta = hand.getItemMeta(); + BrewModifyEvent modifyEvent = new BrewModifyEvent(brew, meta, BrewModifyEvent.Type.UNLABEL); + P.p.getServer().getPluginManager().callEvent(modifyEvent); + if (modifyEvent.isCancelled()) { + hand.setItemMeta(origMeta); return; } + brew.save(meta); + hand.setItemMeta(meta); + p.msg(sender, p.languageReader.get("CMD_UnLabel")); + return; } - p.msg(sender, p.languageReader.get("Error_ItemNotPotion")); - } else { - p.msg(sender, p.languageReader.get("Error_PlayerCommand")); } + p.msg(sender, p.languageReader.get("Error_ItemNotPotion")); } @@ -572,54 +572,55 @@ public class CommandListener implements CommandExecutor { player = p.getServer().getPlayer(pName); } - if (sender instanceof Player || player != null) { - if (player == null) { - player = ((Player) sender); - } - int stringLength = args.length - 1; - if (pName != null) { - stringLength--; - } - if (hasQuality) { - stringLength--; - } - - String name; - if (stringLength > 1) { - StringBuilder builder = new StringBuilder(args[1]); - - for (int i = 2; i < stringLength + 1; i++) { - builder.append(" ").append(args[i]); - } - name = builder.toString(); - } else { - name = args[1]; - } - - if (player.getInventory().firstEmpty() == -1) { - p.msg(sender, p.languageReader.get("CMD_Copy_Error", "1")); - return; - } - - BRecipe recipe = null; - for (BRecipe r : BIngredients.recipes) { - if (r.hasName(name)) { - recipe = r; - break; - } - } - if (recipe != null) { - ItemStack item = recipe.create(quality); - if (item != null) { - player.getInventory().addItem(item); - } - } else { - p.msg(sender, p.languageReader.get("Error_NoBrewName", name)); - } - - } else { + if (!(sender instanceof Player) && player == null) { p.msg(sender, p.languageReader.get("Error_PlayerCommand")); + return; } + + if (player == null) { + player = ((Player) sender); + } + int stringLength = args.length - 1; + if (pName != null) { + stringLength--; + } + if (hasQuality) { + stringLength--; + } + + String name; + if (stringLength > 1) { + StringBuilder builder = new StringBuilder(args[1]); + + for (int i = 2; i < stringLength + 1; i++) { + builder.append(" ").append(args[i]); + } + name = builder.toString(); + } else { + name = args[1]; + } + + if (player.getInventory().firstEmpty() == -1) { + p.msg(sender, p.languageReader.get("CMD_Copy_Error", "1")); + return; + } + + BRecipe recipe = null; + for (BRecipe r : BIngredients.recipes) { + if (r.hasName(name)) { + recipe = r; + break; + } + } + if (recipe != null) { + ItemStack item = recipe.create(quality); + if (item != null) { + player.getInventory().addItem(item); + } + } else { + p.msg(sender, p.languageReader.get("Error_NoBrewName", name)); + } + } } diff --git a/src/com/dre/brewery/listeners/EntityListener.java b/src/com/dre/brewery/listeners/EntityListener.java index b0ba0a4..43fde74 100644 --- a/src/com/dre/brewery/listeners/EntityListener.java +++ b/src/com/dre/brewery/listeners/EntityListener.java @@ -36,7 +36,7 @@ public class EntityListener implements Listener { @EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true) public void onEntityCombust(EntityCombustEvent event) { - if (!Brew.noLegacy()) return; + if (Brew.noLegacy()) return; Entity entity = event.getEntity(); if (entity.getType() == EntityType.DROPPED_ITEM) { if (entity instanceof Item) { diff --git a/src/com/dre/brewery/listeners/InventoryListener.java b/src/com/dre/brewery/listeners/InventoryListener.java index bd25039..b180a48 100644 --- a/src/com/dre/brewery/listeners/InventoryListener.java +++ b/src/com/dre/brewery/listeners/InventoryListener.java @@ -1,14 +1,9 @@ package com.dre.brewery.listeners; import com.dre.brewery.*; +import com.dre.brewery.filedata.BConfig; import com.dre.brewery.lore.BrewLore; -import org.bukkit.Bukkit; import org.bukkit.Material; -import org.bukkit.Sound; -import org.bukkit.SoundCategory; -import org.bukkit.block.Block; -import org.bukkit.block.BlockState; -import org.bukkit.block.BrewingStand; import org.bukkit.entity.HumanEntity; import org.bukkit.event.EventHandler; import org.bukkit.event.EventPriority; @@ -19,28 +14,15 @@ import org.bukkit.inventory.Inventory; import org.bukkit.inventory.ItemFlag; import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.meta.PotionMeta; -import org.bukkit.scheduler.BukkitRunnable; -import java.util.HashMap; import java.util.HashSet; import java.util.Iterator; import java.util.UUID; -/** - * Updated for 1.9 to replicate the "Brewing" process for distilling. - * Because of how metadata has changed, the brewer no longer triggers as previously described. - * So, I've added some event tracking and manual forcing of the brewing "animation" if the - * set of ingredients in the brewer can be distilled. - * Nothing here should interfere with vanilla brewing. - * - * @author ProgrammerDan (1.9 distillation update only) - */ public class InventoryListener implements Listener { /* === Recreating manually the prior BrewEvent behavior. === */ private HashSet trackedBrewmen = new HashSet<>(); - private HashMap trackedBrewers = new HashMap<>(); - private static final int DISTILLTIME = 400; /** * Start tracking distillation for a person when they open the brewer window. @@ -91,6 +73,7 @@ public class InventoryListener implements Listener { @EventHandler(priority = EventPriority.HIGH, ignoreCancelled = true) public void onBrewerClick(InventoryClickEvent event) { if (!P.use1_9) return; + HumanEntity player = event.getWhoClicked(); Inventory inv = event.getInventory(); if (player == null || !(inv instanceof BrewerInventory)) return; @@ -101,171 +84,22 @@ public class InventoryListener implements Listener { if (InventoryType.BREWING != inv.getType()) return; if (event.getAction() == InventoryAction.NOTHING) return; // Ignore clicks that do nothing - BrewerInventory brewer = (BrewerInventory) inv; - final Block brewery = brewer.getHolder().getBlock(); - - // If we were already tracking the brewer, cancel any ongoing event due to the click. - Integer curTask = trackedBrewers.get(brewery); - if (curTask != null) { - Bukkit.getScheduler().cancelTask(curTask); // cancel prior - brewer.getHolder().setBrewingTime(0); // Fixes brewing continuing without fuel for normal potions - brewer.getHolder().update(); - } - final int fuel = brewer.getHolder().getFuelLevel(); - - // Now check if we should bother to track it. - trackedBrewers.put(brewery, new BukkitRunnable() { - private int runTime = -1; - private int brewTime = -1; - @Override - public void run() { - BlockState now = brewery.getState(); - if (now instanceof BrewingStand) { - BrewingStand stand = (BrewingStand) now; - if (brewTime == -1) { // only check at the beginning (and end) for distillables - switch (hasCustom(stand.getInventory())) { - case 1: - // Custom potion but not for distilling. Stop any brewing and cancel this task - if (stand.getBrewingTime() > 0) { - if (P.use1_11) { - // The trick below doesnt work in 1.11, but we dont need it anymore - // This should only happen with older Brews that have been made with the old Potion Color System - stand.setBrewingTime(Short.MAX_VALUE); - } else { - // Brewing time is sent and stored as short - // This sends a negative short value to the Client - // In the client the Brewer will look like it is not doing anything - stand.setBrewingTime(Short.MAX_VALUE << 1); - } - stand.setFuelLevel(fuel); - stand.update(); - } - case 0: - // No custom potion, cancel and ignore - this.cancel(); - trackedBrewers.remove(brewery); - P.p.debugLog("nothing to distill"); - return; - default: - runTime = getLongestDistillTime(stand.getInventory()); - brewTime = runTime; - P.p.debugLog("using brewtime: " + runTime); - - } - } - - brewTime--; // count down. - stand.setBrewingTime((int) ((float) brewTime / ((float) runTime / (float) DISTILLTIME)) + 1); - - if (brewTime <= 1) { // Done! - stand.setBrewingTime(0); - stand.update(); - BrewerInventory brewer = stand.getInventory(); - if (!runDistill(brewer)) { - this.cancel(); - trackedBrewers.remove(brewery); - P.p.debugLog("All done distilling"); - } else { - brewTime = -1; // go again. - P.p.debugLog("Can distill more! Continuing."); - } - } else { - stand.update(); - } - } else { - this.cancel(); - trackedBrewers.remove(brewery); - P.p.debugLog("The block was replaced; not a brewing stand."); - } - } - }.runTaskTimer(P.p, 2L, 1L).getTaskId()); - } - - // Returns a Brew or null for every Slot in the BrewerInventory - private Brew[] getDistillContents(BrewerInventory inv) { - ItemStack item; - Brew[] contents = new Brew[3]; - for (int slot = 0; slot < 3; slot++) { - item = inv.getItem(slot); - if (item != null) { - contents[slot] = Brew.get(item); - } - } - return contents; - } - - private byte hasCustom(BrewerInventory brewer) { - ItemStack item = brewer.getItem(3); // ingredient - boolean glowstone = (item != null && Material.GLOWSTONE_DUST == item.getType()); // need dust in the top slot. - byte customFound = 0; - for (Brew brew : getDistillContents(brewer)) { - if (brew != null) { - if (!glowstone) { - return 1; - } - if (brew.canDistill()) { - return 2; - } else { - customFound = 1; - } - } - } - return customFound; + BDistiller.distillerClick(event); } @EventHandler(priority = EventPriority.LOW, ignoreCancelled = true) public void onBrew(BrewEvent event) { if (P.use1_9) { - if (hasCustom(event.getContents()) != 0) { + if (BDistiller.hasBrew(event.getContents()) != 0) { event.setCancelled(true); } return; } - if (runDistill(event.getContents())) { + if (BDistiller.runDistill(event.getContents())) { event.setCancelled(true); } } - private boolean runDistill(BrewerInventory inv) { - boolean custom = false; - Brew[] contents = getDistillContents(inv); - for (int slot = 0; slot < 3; slot++) { - if (contents[slot] == null) continue; - if (contents[slot].canDistill()) { - // is further distillable - custom = true; - } else { - contents[slot] = null; - } - } - if (custom) { - Brew.distillAll(inv, contents); - return true; - } - return false; - } - - private int getLongestDistillTime(BrewerInventory inv) { - int bestTime = 0; - int time; - Brew[] contents = getDistillContents(inv); - for (int slot = 0; slot < 3; slot++) { - if (contents[slot] == null) continue; - time = contents[slot].getDistillTimeNextRun(); - if (time == 0) { - // Undefined Potion needs 40 seconds - time = 800; - } - if (time > bestTime) { - bestTime = time; - } - } - if (bestTime > 0) { - return bestTime; - } - return 800; - } - // Clicked a Brew somewhere, do some updating @EventHandler(priority = EventPriority.LOW, ignoreCancelled = false) public void onInventoryClickLow(InventoryClickEvent event) { @@ -366,19 +200,15 @@ public class InventoryListener implements Listener { } ItemStack item = event.getCurrentItem(); - if (item != null) { - if (item.getType() == Material.POTION) { - if (item.hasItemMeta()) { - PotionMeta meta = (PotionMeta) item.getItemMeta(); - Brew brew = Brew.get(meta); - if (brew != null) { - if (BrewLore.hasColorLore(meta)) { - BrewLore lore = new BrewLore(brew, meta); - lore.convertLore(false); - lore.write(); - item.setItemMeta(meta); - } - } + if (item != null && item.getType() == Material.POTION && item.hasItemMeta()) { + PotionMeta meta = (PotionMeta) item.getItemMeta(); + Brew brew = Brew.get(meta); + if (brew != null) { + if (BrewLore.hasColorLore(meta)) { + BrewLore lore = new BrewLore(brew, meta); + lore.convertLore(false); + lore.write(); + item.setItemMeta(meta); } } } @@ -437,7 +267,7 @@ public class InventoryListener implements Listener { // block the pickup of items where getPickupDelay is > 1000 (puke) @EventHandler(ignoreCancelled = true) public void onInventoryPickupItem(InventoryPickupItemEvent event){ - if (event.getItem().getPickupDelay() > 1000 && event.getItem().getItemStack().getType() == BPlayer.pukeItem) { + if (event.getItem().getPickupDelay() > 1000 && event.getItem().getItemStack().getType() == BConfig.pukeItem) { event.setCancelled(true); } } @@ -449,13 +279,7 @@ public class InventoryListener implements Listener { // Barrel Closing Sound if (event.getInventory().getHolder() instanceof Barrel) { Barrel barrel = ((Barrel) event.getInventory().getHolder()); - float randPitch = (float) (Math.random() * 0.1); - if (barrel.isLarge()) { - barrel.getSpigot().getWorld().playSound(barrel.getSpigot().getLocation(), Sound.BLOCK_BARREL_CLOSE, SoundCategory.BLOCKS, 0.5f, 0.5f + randPitch); - barrel.getSpigot().getWorld().playSound(barrel.getSpigot().getLocation(), Sound.ITEM_BUCKET_EMPTY, SoundCategory.BLOCKS, 0.2f, 0.6f + randPitch); - } else { - barrel.getSpigot().getWorld().playSound(barrel.getSpigot().getLocation(), Sound.BLOCK_BARREL_CLOSE, SoundCategory.BLOCKS, 0.5f, 0.8f + randPitch); - } + barrel.playClosingSound(); } // Check for MC Barrel diff --git a/src/com/dre/brewery/listeners/PlayerListener.java b/src/com/dre/brewery/listeners/PlayerListener.java index 6e6816a..67e9cf9 100644 --- a/src/com/dre/brewery/listeners/PlayerListener.java +++ b/src/com/dre/brewery/listeners/PlayerListener.java @@ -1,13 +1,11 @@ package com.dre.brewery.listeners; import com.dre.brewery.*; +import com.dre.brewery.filedata.BConfig; import com.dre.brewery.filedata.UpdateChecker; import org.bukkit.GameMode; import org.bukkit.Material; -import org.bukkit.Sound; -import org.bukkit.SoundCategory; import org.bukkit.block.Block; -import org.bukkit.block.BlockFace; import org.bukkit.entity.Player; import org.bukkit.event.EventHandler; import org.bukkit.event.EventPriority; @@ -18,219 +16,93 @@ import org.bukkit.inventory.EquipmentSlot; import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.PlayerInventory; -import java.util.HashSet; -import java.util.Set; -import java.util.UUID; - public class PlayerListener implements Listener { - public static boolean openEverywhere; - private static Set interacted = new HashSet<>(); @EventHandler(priority = EventPriority.HIGH, ignoreCancelled = true) public void onPlayerInteract(PlayerInteractEvent event) { Block clickedBlock = event.getClickedBlock(); + if (clickedBlock == null) return; - if (clickedBlock != null) { - if (event.getAction() == Action.RIGHT_CLICK_BLOCK) { - Player player = event.getPlayer(); - if (!player.isSneaking()) { - Material type = clickedBlock.getType(); + if (event.getAction() != Action.RIGHT_CLICK_BLOCK) return; - // Interacting with a Cauldron - if (type == Material.CAULDRON) { - Material materialInHand = event.getMaterial(); - ItemStack item = event.getItem(); + Player player = event.getPlayer(); + if (player.isSneaking()) return; - if (materialInHand == null || materialInHand == Material.BUCKET) { - return; + Material type = clickedBlock.getType(); - } else if (materialInHand == LegacyUtil.CLOCK) { - BCauldron.printTime(player, clickedBlock); - return; + // Interacting with a Cauldron + if (type == Material.CAULDRON) { + // Handle the Cauldron Interact + // The Event might get cancelled in here + BCauldron.clickCauldron(event); + return; + } - // fill a glass bottle with potion - } else if (materialInHand == Material.GLASS_BOTTLE) { - if (player.getInventory().firstEmpty() != -1 || item.getAmount() == 1) { - if (BCauldron.fill(player, clickedBlock)) { - event.setCancelled(true); - if (player.hasPermission("brewery.cauldron.fill")) { - if (item.getAmount() > 1) { - item.setAmount(item.getAmount() - 1); - } else { - setItemInHand(event, Material.AIR, false); - } - } - } - } else { - event.setCancelled(true); - } - return; + // Do not process Off Hand for Barrel interaction + if (P.use1_9 && event.getHand() != EquipmentSlot.HAND) { + return; + } - // reset cauldron when refilling to prevent unlimited source of potions - } else if (materialInHand == Material.WATER_BUCKET) { - if (!P.use1_9) { - // We catch >=1.9 cases in the Cauldron Listener - if (LegacyUtil.getFillLevel(clickedBlock) == 1) { - // will only remove when existing - BCauldron.remove(clickedBlock); - } - } - return; - } - - // Check if fire alive below cauldron when adding ingredients - Block down = clickedBlock.getRelative(BlockFace.DOWN); - if (LegacyUtil.isFireForCauldron(down)) { - - event.setCancelled(true); - boolean handSwap = false; - - // Interact event is called twice!!!?? in 1.9, once for each hand. - // Certain Items in Hand cause one of them to be cancelled or not called at all sometimes. - // We mark if a player had the event for the main hand - // If not, we handle the main hand in the event for the off hand - if (P.use1_9) { - if (event.getHand() == EquipmentSlot.HAND) { - final UUID id = player.getUniqueId(); - interacted.add(id); - P.p.getServer().getScheduler().runTask(P.p, new Runnable() { - @Override - public void run() { - interacted.remove(id); - } - }); - } else if (event.getHand() == EquipmentSlot.OFF_HAND) { - if (!interacted.remove(player.getUniqueId())) { - item = player.getInventory().getItemInMainHand(); - if (item != null && item.getType() != Material.AIR) { - materialInHand = item.getType(); - handSwap = true; - } else { - item = event.getItem(); - } - } - } - } - if (item == null) return; - - // add ingredient to cauldron that meet the previous conditions - if (BIngredients.possibleIngredients.contains(materialInHand)) { - - if (player.hasPermission("brewery.cauldron.insert")) { - if (BCauldron.ingredientAdd(clickedBlock, item, player)) { - boolean isBucket = item.getType().equals(Material.WATER_BUCKET) - || item.getType().equals(Material.LAVA_BUCKET) - || item.getType().equals(Material.MILK_BUCKET); - if (item.getAmount() > 1) { - item.setAmount(item.getAmount() - 1); - - if (isBucket) { - BCauldron.giveItem(player, new ItemStack(Material.BUCKET)); - } - } else { - if (isBucket) { - setItemInHand(event, Material.BUCKET, handSwap); - } else { - setItemInHand(event, Material.AIR, handSwap); - } - } - } - } else { - P.p.msg(player, P.p.languageReader.get("Perms_NoCauldronInsert")); - } - } - } - return; - } - - if (P.use1_9 && event.getHand() != EquipmentSlot.HAND) { - return; - } - - // Access a Barrel - Barrel barrel = null; - if (LegacyUtil.isWoodPlanks(type)) { - if (openEverywhere) { - barrel = Barrel.get(clickedBlock); - } - } else if (LegacyUtil.isWoodStairs(type)) { - for (Barrel barrel2 : Barrel.barrels) { - if (barrel2.hasStairsBlock(clickedBlock)) { - if (openEverywhere || !barrel2.isLarge()) { - barrel = barrel2; - } - break; - } - } - } else if (LegacyUtil.isFence(type) || LegacyUtil.isSign(type)) { - barrel = Barrel.getBySpigot(clickedBlock); - } - - if (barrel != null) { - event.setCancelled(true); - - if (!barrel.hasPermsOpen(player, event)) { - return; - } - - barrel.open(player); - - if (P.use1_14) { - - // When right clicking a normal Block in 1.14 with a potion or any edible item in hand, - // even when cancelled the consume animation will continue playing while opening the Barrel inventory. - // The Animation and sound will play endlessly while the inventory is open, though no item is consumed. - // This seems to be a client bug. - // This workaround switches the currently selected slot to another for a short time, it needs to be a slot with a different item in it. - // This seems to make the client stop animating a consumption - // If there is a better way to do this please let me know - Material hand = event.getMaterial(); - if ((hand == Material.POTION || hand.isEdible()) && !LegacyUtil.isSign(type)) { - PlayerInventory inv = player.getInventory(); - final int held = inv.getHeldItemSlot(); - int useSlot = -1; - for (int i = 0; i < 9; i++) { - ItemStack item = inv.getItem(i); - if (item == null || item.getType() == Material.AIR) { - useSlot = i; - break; - } else if (useSlot == -1 && item.getType() != hand) { - useSlot = i; - } - } - if (useSlot != -1) { - inv.setHeldItemSlot(useSlot); - P.p.getServer().getScheduler().scheduleSyncDelayedTask(P.p, () -> player.getInventory().setHeldItemSlot(held), 2); - } - } - - // Barrel opening Sound - float randPitch = (float) (Math.random() * 0.1); - if (barrel.isLarge()) { - barrel.getSpigot().getWorld().playSound(barrel.getSpigot().getLocation(), Sound.BLOCK_CHEST_OPEN, SoundCategory.BLOCKS, 0.4f, 0.55f + randPitch); - //barrel.getSpigot().getWorld().playSound(barrel.getSpigot().getLocation(), Sound.ITEM_BUCKET_EMPTY, SoundCategory.BLOCKS, 0.5f, 0.6f + randPitch); - barrel.getSpigot().getWorld().playSound(barrel.getSpigot().getLocation(), Sound.BLOCK_BREWING_STAND_BREW, SoundCategory.BLOCKS, 0.4f, 0.45f + randPitch); - } else { - barrel.getSpigot().getWorld().playSound(barrel.getSpigot().getLocation(), Sound.BLOCK_BARREL_OPEN, SoundCategory.BLOCKS, 0.5f, 0.8f + randPitch); - } - } + // Access a Barrel + Barrel barrel = null; + if (LegacyUtil.isWoodPlanks(type)) { + if (BConfig.openEverywhere) { + barrel = Barrel.get(clickedBlock); + } + } else if (LegacyUtil.isWoodStairs(type)) { + for (Barrel barrel2 : Barrel.barrels) { + if (barrel2.hasStairsBlock(clickedBlock)) { + if (BConfig.openEverywhere || !barrel2.isLarge()) { + barrel = barrel2; } + break; } } + } else if (LegacyUtil.isFence(type) || LegacyUtil.isSign(type)) { + barrel = Barrel.getBySpigot(clickedBlock); } - } - @SuppressWarnings("deprecation") - public void setItemInHand(PlayerInteractEvent event, Material mat, boolean swapped) { - if (P.use1_9) { - if ((event.getHand() == EquipmentSlot.OFF_HAND) != swapped) { - event.getPlayer().getInventory().setItemInOffHand(new ItemStack(mat)); - } else { - event.getPlayer().getInventory().setItemInMainHand(new ItemStack(mat)); + if (barrel != null) { + event.setCancelled(true); + + if (!barrel.hasPermsOpen(player, event)) { + return; + } + + barrel.open(player); + + if (P.use1_14) { + + // When right clicking a normal Block in 1.14 with a potion or any edible item in hand, + // even when cancelled, the consume animation will continue playing while opening the Barrel inventory. + // The Animation and sound will play endlessly while the inventory is open, though no item is consumed. + // This seems to be a client bug. + // This workaround switches the currently selected slot to another for a short time, it needs to be a slot with a different item in it. + // This seems to make the client stop animating a consumption + // If there is a better way to do this please let me know + Material hand = event.getMaterial(); + if ((hand == Material.POTION || hand.isEdible()) && !LegacyUtil.isSign(type)) { + PlayerInventory inv = player.getInventory(); + final int held = inv.getHeldItemSlot(); + int useSlot = -1; + for (int i = 0; i < 9; i++) { + ItemStack item = inv.getItem(i); + if (item == null || item.getType() == Material.AIR) { + useSlot = i; + break; + } else if (useSlot == -1 && item.getType() != hand) { + useSlot = i; + } + } + if (useSlot != -1) { + inv.setHeldItemSlot(useSlot); + P.p.getServer().getScheduler().scheduleSyncDelayedTask(P.p, () -> player.getInventory().setHeldItemSlot(held), 2); + } + } + + barrel.playOpeningSound(); } - } else { - event.getPlayer().setItemInHand(new ItemStack(mat)); } } @@ -273,7 +145,7 @@ public class PlayerListener implements Listener { } } } - } else if (BPlayer.drainItems.containsKey(item.getType())) { + } else if (BConfig.drainItems.containsKey(item.getType())) { BPlayer bplayer = BPlayer.get(player); if (bplayer != null) { bplayer.drainByItem(player, item.getType()); @@ -306,13 +178,13 @@ public class PlayerListener implements Listener { // player talks while drunk, but he cant speak very well @EventHandler(priority = EventPriority.LOWEST) public void onPlayerChat(AsyncPlayerChatEvent event) { - Words.playerChat(event); + DistortChat.playerChat(event); } // player commands while drunk, distort chat commands @EventHandler(priority = EventPriority.LOWEST) public void onCommandPreProcess(PlayerCommandPreprocessEvent event) { - Words.playerCommand(event); + DistortChat.playerCommand(event); } // player joins while passed out diff --git a/src/com/dre/brewery/listeners/WorldListener.java b/src/com/dre/brewery/listeners/WorldListener.java index 0b887b3..48cea50 100644 --- a/src/com/dre/brewery/listeners/WorldListener.java +++ b/src/com/dre/brewery/listeners/WorldListener.java @@ -4,6 +4,7 @@ import com.dre.brewery.BCauldron; import com.dre.brewery.Barrel; import com.dre.brewery.P; import com.dre.brewery.BUtil; +import com.dre.brewery.filedata.BData; import com.dre.brewery.filedata.DataSave; import org.bukkit.World; import org.bukkit.event.EventHandler; @@ -19,9 +20,9 @@ public class WorldListener implements Listener { World world = event.getWorld(); if (world.getName().startsWith("DXL_")) { - P.p.loadWorldData(BUtil.getDxlName(world.getName()), world); + BData.loadWorldData(BUtil.getDxlName(world.getName()), world); } else { - P.p.loadWorldData(world.getUID().toString(), world); + BData.loadWorldData(world.getUID().toString(), world); } } From 7d177a3d9f7c72b341fe2fc736a57311b287d787 Mon Sep 17 00:00:00 2001 From: Sn0wStorm Date: Wed, 16 Oct 2019 19:35:29 +0200 Subject: [PATCH 21/51] Refractor Barrel --- src/com/dre/brewery/BUtil.java | 2 +- src/com/dre/brewery/Barrel.java | 429 ++--------------- src/com/dre/brewery/BarrelBody.java | 453 ++++++++++++++++++ src/com/dre/brewery/filedata/BData.java | 10 +- .../integration/IntegrationListener.java | 2 +- .../dre/brewery/integration/LWCBarrel.java | 8 +- .../dre/brewery/listeners/PlayerListener.java | 2 +- 7 files changed, 509 insertions(+), 397 deletions(-) create mode 100644 src/com/dre/brewery/BarrelBody.java diff --git a/src/com/dre/brewery/BUtil.java b/src/com/dre/brewery/BUtil.java index 84ff2f3..50c0dca 100644 --- a/src/com/dre/brewery/BUtil.java +++ b/src/com/dre/brewery/BUtil.java @@ -186,7 +186,7 @@ public class BUtil { return false; } } else { - barrel2.destroySign(); + barrel2.getBody().destroySign(); } } return true; diff --git a/src/com/dre/brewery/Barrel.java b/src/com/dre/brewery/Barrel.java index c583857..8135511 100644 --- a/src/com/dre/brewery/Barrel.java +++ b/src/com/dre/brewery/Barrel.java @@ -5,10 +5,9 @@ import com.dre.brewery.api.events.barrel.BarrelCreateEvent; import com.dre.brewery.api.events.barrel.BarrelDestroyEvent; import com.dre.brewery.api.events.barrel.BarrelRemoveEvent; import com.dre.brewery.filedata.BConfig; -import com.dre.brewery.integration.LWCBarrel; import com.dre.brewery.integration.LogBlockBarrel; import com.dre.brewery.lore.BrewLore; -import org.apache.commons.lang.ArrayUtils; +import org.bukkit.Location; import org.bukkit.Material; import org.bukkit.Sound; import org.bukkit.SoundCategory; @@ -21,7 +20,6 @@ import org.bukkit.inventory.Inventory; import org.bukkit.inventory.InventoryHolder; import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.meta.PotionMeta; -import org.bukkit.plugin.Plugin; import org.bukkit.scheduler.BukkitRunnable; import java.util.ArrayList; @@ -34,23 +32,20 @@ public class Barrel implements InventoryHolder { public static CopyOnWriteArrayList barrels = new CopyOnWriteArrayList<>(); // TODO find best collection private static int check = 0; - private Block spigot; - private int[] woodsloc = null; // location of wood Blocks - private int[] stairsloc = null; // location of stair Blocks - private byte signoffset; - private boolean checked; + private final Block spigot; + private final BarrelBody body; // The Blocks that make up a Barrel in the World + private boolean checked; // Checked by the random BarrelCheck routine private Inventory inventory; private float time; public Barrel(Block spigot, byte signoffset) { this.spigot = spigot; - this.signoffset = signoffset; + body = new BarrelBody(this, signoffset); } // load from file public Barrel(Block spigot, byte sign, String[] st, String[] wo, Map items, float time) { this.spigot = spigot; - this.signoffset = sign; if (isLarge()) { this.inventory = P.p.getServer().createInventory(this, 27, P.p.languageReader.get("Etc_Barrel")); } else { @@ -65,34 +60,7 @@ public class Barrel implements InventoryHolder { } this.time = time; - int i = 0; - if (wo.length > 1) { - woodsloc = new int[wo.length]; - for (String wos : wo) { - woodsloc[i] = P.p.parseInt(wos); - i++; - } - i = 0; - } - if (st.length > 1) { - stairsloc = new int[st.length]; - for (String sts : st) { - stairsloc[i] = P.p.parseInt(sts); - i++; - } - } - - if (woodsloc == null && stairsloc == null) { - // If loading from old data, or block locations are missing, regenerate them - // This will only be done in those extreme cases. - Block broken = getBrokenBlock(true); - if (broken != null) { - remove(broken, null); - return; - } - } - - barrels.add(this); + body = new BarrelBody(this, sign, st, wo); } public static void onUpdate() { @@ -158,7 +126,7 @@ public class Barrel implements InventoryHolder { if (inventory.getViewers().isEmpty()) { // if inventory contains potions if (inventory.contains(Material.POTION)) { - byte wood = getWood(); + byte wood = body.getWood(); long loadTime = System.nanoTime(); for (ItemStack item : inventory.getContents()) { if (item != null) { @@ -192,22 +160,24 @@ public class Barrel implements InventoryHolder { public void playOpeningSound() { float randPitch = (float) (Math.random() * 0.1); + Location location = getSpigot().getLocation(); if (isLarge()) { - getSpigot().getWorld().playSound(getSpigot().getLocation(), Sound.BLOCK_CHEST_OPEN, SoundCategory.BLOCKS, 0.4f, 0.55f + randPitch); + location.getWorld().playSound(location, Sound.BLOCK_CHEST_OPEN, SoundCategory.BLOCKS, 0.4f, 0.55f + randPitch); //getSpigot().getWorld().playSound(getSpigot().getLocation(), Sound.ITEM_BUCKET_EMPTY, SoundCategory.BLOCKS, 0.5f, 0.6f + randPitch); - getSpigot().getWorld().playSound(getSpigot().getLocation(), Sound.BLOCK_BREWING_STAND_BREW, SoundCategory.BLOCKS, 0.4f, 0.45f + randPitch); + location.getWorld().playSound(location, Sound.BLOCK_BREWING_STAND_BREW, SoundCategory.BLOCKS, 0.4f, 0.45f + randPitch); } else { - getSpigot().getWorld().playSound(getSpigot().getLocation(), Sound.BLOCK_BARREL_OPEN, SoundCategory.BLOCKS, 0.5f, 0.8f + randPitch); + location.getWorld().playSound(location, Sound.BLOCK_BARREL_OPEN, SoundCategory.BLOCKS, 0.5f, 0.8f + randPitch); } } public void playClosingSound() { float randPitch = (float) (Math.random() * 0.1); + Location location = getSpigot().getLocation(); if (isLarge()) { - getSpigot().getWorld().playSound(getSpigot().getLocation(), Sound.BLOCK_BARREL_CLOSE, SoundCategory.BLOCKS, 0.5f, 0.5f + randPitch); - getSpigot().getWorld().playSound(getSpigot().getLocation(), Sound.ITEM_BUCKET_EMPTY, SoundCategory.BLOCKS, 0.2f, 0.6f + randPitch); + location.getWorld().playSound(location, Sound.BLOCK_BARREL_CLOSE, SoundCategory.BLOCKS, 0.5f, 0.5f + randPitch); + location.getWorld().playSound(location, Sound.ITEM_BUCKET_EMPTY, SoundCategory.BLOCKS, 0.2f, 0.6f + randPitch); } else { - getSpigot().getWorld().playSound(getSpigot().getLocation(), Sound.BLOCK_BARREL_CLOSE, SoundCategory.BLOCKS, 0.5f, 0.8f + randPitch); + location.getWorld().playSound(location, Sound.BLOCK_BARREL_CLOSE, SoundCategory.BLOCKS, 0.5f, 0.8f + randPitch); } } @@ -220,70 +190,25 @@ public class Barrel implements InventoryHolder { return spigot; } + public BarrelBody getBody() { + return body; + } + public float getTime() { return time; } // Returns true if this Block is part of this Barrel public boolean hasBlock(Block block) { - if (block != null) { - if (LegacyUtil.isWoodPlanks(block.getType())) { - return hasWoodBlock(block); - } else if (LegacyUtil.isWoodStairs(block.getType())) { - return hasStairsBlock(block); - } - } - return false; + return body.hasBlock(block); } public boolean hasWoodBlock(Block block) { - if (woodsloc != null) { - if (spigot.getWorld() != null && spigot.getWorld().equals(block.getWorld())) { - if (woodsloc.length > 2) { - int x = block.getX(); - if (Math.abs(x - woodsloc[0]) < 10) { - for (int i = 0; i < woodsloc.length - 2; i += 3) { - if (woodsloc[i] == x) { - if (woodsloc[i + 1] == block.getY()) { - if (woodsloc[i + 2] == block.getZ()) { - return true; - } - } - } - } - } - } - } - } - return false; + return body.hasWoodBlock(block); } public boolean hasStairsBlock(Block block) { - if (stairsloc != null) { - if (spigot.getWorld() != null && spigot.getWorld().equals(block.getWorld())) { - if (stairsloc.length > 2) { - int x = block.getX(); - if (Math.abs(x - stairsloc[0]) < 10) { - for (int i = 0; i < stairsloc.length - 2; i += 3) { - if (stairsloc[i] == x) { - if (stairsloc[i + 1] == block.getY()) { - if (stairsloc[i + 2] == block.getZ()) { - return true; - } - } - } - } - } - } - } - } - return false; - } - - // Returns true if the Offset of the clicked Sign matches the Barrel. - // This prevents adding another sign to the barrel and clicking that. - public boolean isSignOfBarrel(byte offset) { - return offset == 0 || signoffset == 0 || signoffset == offset; + return body.hasStairsBlock(block); } // Get the Barrel by Block, null if that block is not part of a barrel @@ -303,7 +228,7 @@ public class Barrel implements InventoryHolder { // Get the Barrel by Sign or Spigot (Fastest) public static Barrel getBySpigot(Block sign) { // convert spigot if neccessary - Block spigot = getSpigotOfSign(sign); + Block spigot = BarrelBody.getSpigotOfSign(sign); byte signoffset = 0; if (!spigot.equals(sign)) { @@ -311,11 +236,11 @@ public class Barrel implements InventoryHolder { } for (Barrel barrel : barrels) { - if (barrel.isSignOfBarrel(signoffset)) { - if (barrel.spigot.equals(spigot)) { - if (barrel.signoffset == 0 && signoffset != 0) { + if (barrel.body.isSignOfBarrel(signoffset)) { + if (barrel.body.equals(spigot)) { + if (barrel.body.getSignoffset() == 0 && signoffset != 0) { // Barrel has no signOffset even though we clicked a sign, may be old - barrel.signoffset = signoffset; + barrel.body.setSignoffset(signoffset); } return barrel; } @@ -328,13 +253,13 @@ public class Barrel implements InventoryHolder { public static Barrel getByWood(Block wood) { if (LegacyUtil.isWoodPlanks(wood.getType())) { for (Barrel barrel : barrels) { - if (barrel.hasWoodBlock(wood)) { + if (barrel.body.hasWoodBlock(wood)) { return barrel; } } } else if (LegacyUtil.isWoodStairs(wood.getType())) { for (Barrel barrel : Barrel.barrels) { - if (barrel.hasStairsBlock(wood)) { + if (barrel.body.hasStairsBlock(wood)) { return barrel; } } @@ -344,7 +269,7 @@ public class Barrel implements InventoryHolder { // creates a new Barrel out of a sign public static boolean create(Block sign, Player player) { - Block spigot = getSpigotOfSign(sign); + Block spigot = BarrelBody.getSpigotOfSign(sign); byte signoffset = 0; if (!spigot.equals(sign)) { @@ -354,7 +279,7 @@ public class Barrel implements InventoryHolder { Barrel barrel = getBySpigot(spigot); if (barrel == null) { barrel = new Barrel(spigot, signoffset); - if (barrel.getBrokenBlock(true) == null) { + if (barrel.body.getBrokenBlock(true) == null) { if (LegacyUtil.isSign(spigot.getType())) { if (!player.hasPermission("brewery.createbarrel.small")) { P.p.msg(player, P.p.languageReader.get("Perms_NoSmallBarrelCreate")); @@ -374,8 +299,8 @@ public class Barrel implements InventoryHolder { } } } else { - if (barrel.signoffset == 0 && signoffset != 0) { - barrel.signoffset = signoffset; + if (barrel.body.getSignoffset() == 0 && signoffset != 0) { + barrel.body.setSignoffset(signoffset); return true; } } @@ -411,7 +336,7 @@ public class Barrel implements InventoryHolder { Brew brew = Brew.get(item); if (brew != null) { // Brew before throwing - brew.age(item, time, getWood()); + brew.age(item, time, body.getWood()); PotionMeta meta = (PotionMeta) item.getItemMeta(); if (BrewLore.hasColorLore(meta)) { BrewLore lore = new BrewLore(brew, meta); @@ -434,45 +359,6 @@ public class Barrel implements InventoryHolder { barrels.remove(this); } - // If the Sign of a Large Barrel gets destroyed, set signOffset to 0 - public void destroySign() { - signoffset = 0; - } - - // direction of the barrel from the spigot - public static int getDirection(Block spigot) { - int direction = 0;// 1=x+ 2=x- 3=z+ 4=z- - Material type = spigot.getRelative(0, 0, 1).getType(); - if (LegacyUtil.isWoodPlanks(type) || LegacyUtil.isWoodStairs(type)) { - direction = 3; - } - type = spigot.getRelative(0, 0, -1).getType(); - if (LegacyUtil.isWoodPlanks(type) || LegacyUtil.isWoodStairs(type)) { - if (direction == 0) { - direction = 4; - } else { - return 0; - } - } - type = spigot.getRelative(1, 0, 0).getType(); - if (LegacyUtil.isWoodPlanks(type) || LegacyUtil.isWoodStairs(type)) { - if (direction == 0) { - direction = 1; - } else { - return 0; - } - } - type = spigot.getRelative(-1, 0, 0).getType(); - if (LegacyUtil.isWoodPlanks(type) || LegacyUtil.isWoodStairs(type)) { - if (direction == 0) { - direction = 2; - } else { - return 0; - } - } - return direction; - } - // is this a Large barrel? public boolean isLarge() { return !isSmall(); @@ -483,239 +369,21 @@ public class Barrel implements InventoryHolder { return !LegacyUtil.isSign(spigot.getType()); } - // woodtype of the block the spigot is attached to - public byte getWood() { - Block wood; - switch (getDirection(spigot)) { // 1=x+ 2=x- 3=z+ 4=z- - case 0: - return 0; - case 1: - wood = spigot.getRelative(1, 0, 0); - break; - case 2: - wood = spigot.getRelative(-1, 0, 0); - break; - case 3: - wood = spigot.getRelative(0, 0, 1); - break; - default: - wood = spigot.getRelative(0, 0, -1); - } - try { - return LegacyUtil.getWoodType(wood); - } catch (NoSuchFieldError | NoClassDefFoundError noSuchFieldError) { - // Using older minecraft versions some fields and classes do not exist - return 0; - } - } - // returns the Sign of a large barrel, the spigot if there is none public Block getSignOfSpigot() { - if (signoffset != 0) { - if (LegacyUtil.isSign(spigot.getType())) { - return spigot; - } - - if (LegacyUtil.isSign(spigot.getRelative(0, signoffset, 0).getType())) { - return spigot.getRelative(0, signoffset, 0); - } else { - signoffset = 0; - } - } - return spigot; + return body.getSignOfSpigot(); } // returns the fence above/below a block, itself if there is none public static Block getSpigotOfSign(Block block) { - - int y = -2; - while (y <= 1) { - // Fence and Netherfence - Block relative = block.getRelative(0, y, 0); - if (LegacyUtil.isFence(relative.getType())) { - return (relative); - } - y++; - } - return block; + return BarrelBody.getSpigotOfSign(block); } // returns null if Barrel is correctly placed; the block that is missing when not // the barrel needs to be formed correctly // flag force to also check if chunk is not loaded public Block getBrokenBlock(boolean force) { - if (force || BUtil.isChunkLoaded(spigot)) { - spigot = getSpigotOfSign(spigot); - if (LegacyUtil.isSign(spigot.getType())) { - return checkSBarrel(); - } else { - return checkLBarrel(); - } - } - return null; - } - - public Block checkSBarrel() { - int direction = getDirection(spigot);// 1=x+ 2=x- 3=z+ 4=z- - if (direction == 0) { - return spigot; - } - int startX; - int startZ; - int endX; - int endZ; - - ArrayList stairs = new ArrayList<>(); - - if (direction == 1) { - startX = 1; - endX = startX + 1; - startZ = -1; - endZ = 0; - } else if (direction == 2) { - startX = -2; - endX = startX + 1; - startZ = 0; - endZ = 1; - } else if (direction == 3) { - startX = 0; - endX = 1; - startZ = 1; - endZ = startZ + 1; - } else { - startX = -1; - endX = 0; - startZ = -2; - endZ = startZ + 1; - } - - Material type; - int x = startX; - int y = 0; - int z = startZ; - while (y <= 1) { - while (x <= endX) { - while (z <= endZ) { - Block block = spigot.getRelative(x, y, z); - type = block.getType(); - - if (LegacyUtil.isWoodStairs(type)) { - if (y == 0) { - // stairs have to be upside down - if (!LegacyUtil.areStairsInverted(block)) { - return block; - } - } - stairs.add(block.getX()); - stairs.add(block.getY()); - stairs.add(block.getZ()); - z++; - } else { - return spigot.getRelative(x, y, z); - } - } - z = startZ; - x++; - } - z = startZ; - x = startX; - y++; - } - stairsloc = ArrayUtils.toPrimitive(stairs.toArray(new Integer[0])); - return null; - } - - public Block checkLBarrel() { - int direction = getDirection(spigot);// 1=x+ 2=x- 3=z+ 4=z- - if (direction == 0) { - return spigot; - } - int startX; - int startZ; - int endX; - int endZ; - - ArrayList stairs = new ArrayList<>(); - ArrayList woods = new ArrayList<>(); - - if (direction == 1) { - startX = 1; - endX = startX + 3; - startZ = -1; - endZ = 1; - } else if (direction == 2) { - startX = -4; - endX = startX + 3; - startZ = -1; - endZ = 1; - } else if (direction == 3) { - startX = -1; - endX = 1; - startZ = 1; - endZ = startZ + 3; - } else { - startX = -1; - endX = 1; - startZ = -4; - endZ = startZ + 3; - } - - Material type; - int x = startX; - int y = 0; - int z = startZ; - while (y <= 2) { - while (x <= endX) { - while (z <= endZ) { - Block block = spigot.getRelative(x, y, z); - type = block.getType(); - if (direction == 1 || direction == 2) { - if (y == 1 && z == 0) { - if (x == -1 || x == -4 || x == 1 || x == 4) { - woods.add(block.getX()); - woods.add(block.getY()); - woods.add(block.getZ()); - } - z++; - continue; - } - } else { - if (y == 1 && x == 0) { - if (z == -1 || z == -4 || z == 1 || z == 4) { - woods.add(block.getX()); - woods.add(block.getY()); - woods.add(block.getZ()); - } - z++; - continue; - } - } - if (LegacyUtil.isWoodPlanks(type) || LegacyUtil.isWoodStairs(type)) { - if (LegacyUtil.isWoodPlanks(type)) { - woods.add(block.getX()); - woods.add(block.getY()); - woods.add(block.getZ()); - } else { - stairs.add(block.getX()); - stairs.add(block.getY()); - stairs.add(block.getZ()); - } - z++; - } else { - return block; - } - } - z = startZ; - x++; - } - z = startZ; - x = startX; - y++; - } - stairsloc = ArrayUtils.toPrimitive(stairs.toArray(new Integer[0])); - woodsloc = ArrayUtils.toPrimitive(woods.toArray(new Integer[0])); - - return null; + return body.getBrokenBlock(force); } //unloads barrels that are in a unloading world @@ -731,7 +399,7 @@ public class Barrel implements InventoryHolder { public static void save(ConfigurationSection config, ConfigurationSection oldData) { BUtil.createWorldSections(config); - if (barrels.isEmpty()) { + if (!barrels.isEmpty()) { int id = 0; for (Barrel barrel : barrels) { @@ -747,23 +415,8 @@ public class Barrel implements InventoryHolder { // block: x/y/z config.set(prefix + ".spigot", barrel.spigot.getX() + "/" + barrel.spigot.getY() + "/" + barrel.spigot.getZ()); - if (barrel.signoffset != 0) { - config.set(prefix + ".sign", barrel.signoffset); - } - if (barrel.stairsloc != null && barrel.stairsloc.length > 0) { - StringBuilder st = new StringBuilder(); - for (int i : barrel.stairsloc) { - st.append(i).append(","); - } - config.set(prefix + ".st", st.substring(0, st.length() - 1)); - } - if (barrel.woodsloc != null && barrel.woodsloc.length > 0) { - StringBuilder wo = new StringBuilder(); - for (int i : barrel.woodsloc) { - wo.append(i).append(","); - } - config.set(prefix + ".wo", wo.substring(0, wo.length() - 1)); - } + // save the body data into the section as well + barrel.body.save(config, prefix); if (barrel.inventory != null) { int slot = 0; @@ -808,7 +461,7 @@ public class Barrel implements InventoryHolder { if (check < barrels.size()) { Barrel barrel = barrels.get(check); if (!barrel.checked) { - Block broken = barrel.getBrokenBlock(false); + Block broken = barrel.body.getBrokenBlock(false); if (broken != null) { P.p.debugLog("Barrel at " + broken.getWorld().getName() + "/" + broken.getX() + "/" + broken.getY() + "/" + broken.getZ() + " has been destroyed unexpectedly, contents will drop"); diff --git a/src/com/dre/brewery/BarrelBody.java b/src/com/dre/brewery/BarrelBody.java new file mode 100644 index 0000000..1f3ad3f --- /dev/null +++ b/src/com/dre/brewery/BarrelBody.java @@ -0,0 +1,453 @@ +package com.dre.brewery; + +import org.apache.commons.lang.ArrayUtils; +import org.bukkit.Material; +import org.bukkit.block.Block; +import org.bukkit.configuration.ConfigurationSection; + +import java.util.ArrayList; + +// The Blocks that make up a Barrel in the World +public class BarrelBody { + + private final Barrel barrel; + private final Block spigot; + private int[] woodsloc = null; // location of wood Blocks + private int[] stairsloc = null; // location of stair Blocks + private byte signoffset; + + public BarrelBody(Barrel barrel, byte signoffset) { + this.barrel = barrel; + this.signoffset = signoffset; + spigot = barrel.getSpigot(); + } + + // Loading from file + public BarrelBody(Barrel barrel, byte signoffset, String[] st, String[] wo) { + this(barrel, signoffset); + + int i = 0; + if (wo.length > 1) { + woodsloc = new int[wo.length]; + for (String wos : wo) { + woodsloc[i] = P.p.parseInt(wos); + i++; + } + i = 0; + } + if (st.length > 1) { + stairsloc = new int[st.length]; + for (String sts : st) { + stairsloc[i] = P.p.parseInt(sts); + i++; + } + } + + if (woodsloc == null && stairsloc == null) { + // If loading from old data, or block locations are missing, regenerate them + // This will only be done in those extreme cases. + Block broken = getBrokenBlock(true); + if (broken != null) { + barrel.remove(broken, null); + } + } + } + + public Barrel getBarrel() { + return barrel; + } + + public Block getSpigot() { + return spigot; + } + + public int[] getWoodsloc() { + return woodsloc; + } + + public void setWoodsloc(int[] woodsloc) { + this.woodsloc = woodsloc; + } + + public int[] getStairsloc() { + return stairsloc; + } + + public void setStairsloc(int[] stairsloc) { + this.stairsloc = stairsloc; + } + + public byte getSignoffset() { + return signoffset; + } + + public void setSignoffset(byte signoffset) { + this.signoffset = signoffset; + } + + // If the Sign of a Large Barrel gets destroyed, set signOffset to 0 + public void destroySign() { + signoffset = 0; + } + + // direction of the barrel from the spigot + public static int getDirection(Block spigot) { + int direction = 0;// 1=x+ 2=x- 3=z+ 4=z- + Material type = spigot.getRelative(0, 0, 1).getType(); + if (LegacyUtil.isWoodPlanks(type) || LegacyUtil.isWoodStairs(type)) { + direction = 3; + } + type = spigot.getRelative(0, 0, -1).getType(); + if (LegacyUtil.isWoodPlanks(type) || LegacyUtil.isWoodStairs(type)) { + if (direction == 0) { + direction = 4; + } else { + return 0; + } + } + type = spigot.getRelative(1, 0, 0).getType(); + if (LegacyUtil.isWoodPlanks(type) || LegacyUtil.isWoodStairs(type)) { + if (direction == 0) { + direction = 1; + } else { + return 0; + } + } + type = spigot.getRelative(-1, 0, 0).getType(); + if (LegacyUtil.isWoodPlanks(type) || LegacyUtil.isWoodStairs(type)) { + if (direction == 0) { + direction = 2; + } else { + return 0; + } + } + return direction; + } + + // is this a Large barrel? + public boolean isLarge() { + return barrel.isLarge(); + } + + // is this a Small barrel? + public boolean isSmall() { + return barrel.isSmall(); + } + + // woodtype of the block the spigot is attached to + public byte getWood() { + Block wood; + switch (getDirection(spigot)) { // 1=x+ 2=x- 3=z+ 4=z- + case 0: + return 0; + case 1: + wood = spigot.getRelative(1, 0, 0); + break; + case 2: + wood = spigot.getRelative(-1, 0, 0); + break; + case 3: + wood = spigot.getRelative(0, 0, 1); + break; + default: + wood = spigot.getRelative(0, 0, -1); + } + try { + return LegacyUtil.getWoodType(wood); + } catch (NoSuchFieldError | NoClassDefFoundError noSuchFieldError) { + // Using older minecraft versions some fields and classes do not exist + return 0; + } + } + + // Returns true if this Block is part of this Barrel + public boolean hasBlock(Block block) { + if (block != null) { + if (LegacyUtil.isWoodPlanks(block.getType())) { + return hasWoodBlock(block); + } else if (LegacyUtil.isWoodStairs(block.getType())) { + return hasStairsBlock(block); + } + } + return false; + } + + public boolean hasWoodBlock(Block block) { + if (woodsloc != null) { + if (spigot.getWorld() != null && spigot.getWorld().equals(block.getWorld())) { + if (woodsloc.length > 2) { + int x = block.getX(); + if (Math.abs(x - woodsloc[0]) < 10) { + for (int i = 0; i < woodsloc.length - 2; i += 3) { + if (woodsloc[i] == x) { + if (woodsloc[i + 1] == block.getY()) { + if (woodsloc[i + 2] == block.getZ()) { + return true; + } + } + } + } + } + } + } + } + return false; + } + + public boolean hasStairsBlock(Block block) { + if (stairsloc != null) { + if (spigot.getWorld() != null && spigot.getWorld().equals(block.getWorld())) { + if (stairsloc.length > 2) { + int x = block.getX(); + if (Math.abs(x - stairsloc[0]) < 10) { + for (int i = 0; i < stairsloc.length - 2; i += 3) { + if (stairsloc[i] == x) { + if (stairsloc[i + 1] == block.getY()) { + if (stairsloc[i + 2] == block.getZ()) { + return true; + } + } + } + } + } + } + } + } + return false; + } + + // Returns true if the Offset of the clicked Sign matches the Barrel. + // This prevents adding another sign to the barrel and clicking that. + public boolean isSignOfBarrel(byte offset) { + return offset == 0 || signoffset == 0 || signoffset == offset; + } + + // returns the Sign of a large barrel, the spigot if there is none + public Block getSignOfSpigot() { + if (signoffset != 0) { + if (LegacyUtil.isSign(spigot.getType())) { + return spigot; + } + + if (LegacyUtil.isSign(spigot.getRelative(0, signoffset, 0).getType())) { + return spigot.getRelative(0, signoffset, 0); + } else { + signoffset = 0; + } + } + return spigot; + } + + // returns the fence above/below a block, itself if there is none + public static Block getSpigotOfSign(Block block) { + + int y = -2; + while (y <= 1) { + // Fence and Netherfence + Block relative = block.getRelative(0, y, 0); + if (LegacyUtil.isFence(relative.getType())) { + return (relative); + } + y++; + } + return block; + } + + // returns null if Barrel is correctly placed; the block that is missing when not + // the barrel needs to be formed correctly + // flag force to also check if chunk is not loaded + public Block getBrokenBlock(boolean force) { + if (force || BUtil.isChunkLoaded(spigot)) { + //spigot = getSpigotOfSign(spigot); + if (LegacyUtil.isSign(spigot.getType())) { + return checkSBarrel(); + } else { + return checkLBarrel(); + } + } + return null; + } + + public Block checkSBarrel() { + int direction = getDirection(spigot);// 1=x+ 2=x- 3=z+ 4=z- + if (direction == 0) { + return spigot; + } + int startX; + int startZ; + int endX; + int endZ; + + ArrayList stairs = new ArrayList<>(); + + if (direction == 1) { + startX = 1; + endX = startX + 1; + startZ = -1; + endZ = 0; + } else if (direction == 2) { + startX = -2; + endX = startX + 1; + startZ = 0; + endZ = 1; + } else if (direction == 3) { + startX = 0; + endX = 1; + startZ = 1; + endZ = startZ + 1; + } else { + startX = -1; + endX = 0; + startZ = -2; + endZ = startZ + 1; + } + + Material type; + int x = startX; + int y = 0; + int z = startZ; + while (y <= 1) { + while (x <= endX) { + while (z <= endZ) { + Block block = spigot.getRelative(x, y, z); + type = block.getType(); + + if (LegacyUtil.isWoodStairs(type)) { + if (y == 0) { + // stairs have to be upside down + if (!LegacyUtil.areStairsInverted(block)) { + return block; + } + } + stairs.add(block.getX()); + stairs.add(block.getY()); + stairs.add(block.getZ()); + z++; + } else { + return spigot.getRelative(x, y, z); + } + } + z = startZ; + x++; + } + z = startZ; + x = startX; + y++; + } + stairsloc = ArrayUtils.toPrimitive(stairs.toArray(new Integer[0])); + return null; + } + + public Block checkLBarrel() { + int direction = getDirection(spigot);// 1=x+ 2=x- 3=z+ 4=z- + if (direction == 0) { + return spigot; + } + int startX; + int startZ; + int endX; + int endZ; + + ArrayList stairs = new ArrayList<>(); + ArrayList woods = new ArrayList<>(); + + if (direction == 1) { + startX = 1; + endX = startX + 3; + startZ = -1; + endZ = 1; + } else if (direction == 2) { + startX = -4; + endX = startX + 3; + startZ = -1; + endZ = 1; + } else if (direction == 3) { + startX = -1; + endX = 1; + startZ = 1; + endZ = startZ + 3; + } else { + startX = -1; + endX = 1; + startZ = -4; + endZ = startZ + 3; + } + + Material type; + int x = startX; + int y = 0; + int z = startZ; + while (y <= 2) { + while (x <= endX) { + while (z <= endZ) { + Block block = spigot.getRelative(x, y, z); + type = block.getType(); + if (direction == 1 || direction == 2) { + if (y == 1 && z == 0) { + if (x == -1 || x == -4 || x == 1 || x == 4) { + woods.add(block.getX()); + woods.add(block.getY()); + woods.add(block.getZ()); + } + z++; + continue; + } + } else { + if (y == 1 && x == 0) { + if (z == -1 || z == -4 || z == 1 || z == 4) { + woods.add(block.getX()); + woods.add(block.getY()); + woods.add(block.getZ()); + } + z++; + continue; + } + } + if (LegacyUtil.isWoodPlanks(type) || LegacyUtil.isWoodStairs(type)) { + if (LegacyUtil.isWoodPlanks(type)) { + woods.add(block.getX()); + woods.add(block.getY()); + woods.add(block.getZ()); + } else { + stairs.add(block.getX()); + stairs.add(block.getY()); + stairs.add(block.getZ()); + } + z++; + } else { + return block; + } + } + z = startZ; + x++; + } + z = startZ; + x = startX; + y++; + } + stairsloc = ArrayUtils.toPrimitive(stairs.toArray(new Integer[0])); + woodsloc = ArrayUtils.toPrimitive(woods.toArray(new Integer[0])); + + return null; + } + + public void save(ConfigurationSection config, String prefix) { + if (signoffset != 0) { + config.set(prefix + ".sign", signoffset); + } + if (stairsloc != null && stairsloc.length > 0) { + StringBuilder st = new StringBuilder(); + for (int i : stairsloc) { + st.append(i).append(","); + } + config.set(prefix + ".st", st.substring(0, st.length() - 1)); + } + if (woodsloc != null && woodsloc.length > 0) { + StringBuilder wo = new StringBuilder(); + for (int i : woodsloc) { + wo.append(i).append(","); + } + config.set(prefix + ".wo", wo.substring(0, wo.length() - 1)); + } + } +} diff --git a/src/com/dre/brewery/filedata/BData.java b/src/com/dre/brewery/filedata/BData.java index 06a1415..afc9355 100644 --- a/src/com/dre/brewery/filedata/BData.java +++ b/src/com/dre/brewery/filedata/BData.java @@ -211,11 +211,17 @@ public class BData { String[] st = section.getString(barrel + ".st", "").split(","); String[] wo = section.getString(barrel + ".wo", "").split(","); + Barrel b; if (invSection != null) { - new Barrel(block, sign, st, wo, invSection.getValues(true), time); + b = new Barrel(block, sign, st, wo, invSection.getValues(true), time); } else { // Barrel has no inventory - new Barrel(block, sign, st, wo, null, time); + b = new Barrel(block, sign, st, wo, null, time); + } + + // In case Barrel Block locations were missing and could not be recreated: do not add the barrel + if (b.getBody().getStairsloc() != null || b.getBody().getWoodsloc() != null) { + Barrel.barrels.add(b); } } else { diff --git a/src/com/dre/brewery/integration/IntegrationListener.java b/src/com/dre/brewery/integration/IntegrationListener.java index ba485cc..8523137 100644 --- a/src/com/dre/brewery/integration/IntegrationListener.java +++ b/src/com/dre/brewery/integration/IntegrationListener.java @@ -76,7 +76,7 @@ public class IntegrationListener implements Listener { // If the Clicked Block was the Sign, LWC already knows and we dont need to do anything here if (!LegacyUtil.isSign(event.getClickedBlock().getType())) { - Block sign = event.getBarrel().getSignOfSpigot(); + Block sign = event.getBarrel().getBody().getSignOfSpigot(); // If the Barrel does not have a Sign, it cannot be locked if (!sign.equals(event.getClickedBlock())) { Player player = event.getPlayer(); diff --git a/src/com/dre/brewery/integration/LWCBarrel.java b/src/com/dre/brewery/integration/LWCBarrel.java index 7fcc274..7831527 100644 --- a/src/com/dre/brewery/integration/LWCBarrel.java +++ b/src/com/dre/brewery/integration/LWCBarrel.java @@ -24,7 +24,7 @@ public class LWCBarrel { public static boolean denyDestroy(Player player, Barrel barrel) { LWC lwc = LWC.getInstance(); - Block sign = barrel.getSignOfSpigot(); + Block sign = barrel.getBody().getSignOfSpigot(); //if (!Boolean.parseBoolean(lwc.resolveProtectionConfiguration(sign, "ignoreBlockDestruction"))) { Protection protection = lwc.findProtection(sign); if (protection != null) { @@ -82,7 +82,7 @@ public class LWCBarrel { // If a Barrel is destroyed without player public static void remove(Barrel barrel) { - Protection protection = LWC.getInstance().findProtection(barrel.getSignOfSpigot()); + Protection protection = LWC.getInstance().findProtection(barrel.getBody().getSignOfSpigot()); if (protection != null) { protection.remove(); } @@ -90,13 +90,13 @@ public class LWCBarrel { // Returns true if the block that exploded should not be removed public static boolean denyExplosion(Barrel barrel) { - Protection protection = LWC.getInstance().findProtection(barrel.getSignOfSpigot()); + Protection protection = LWC.getInstance().findProtection(barrel.getBody().getSignOfSpigot()); return protection != null && !protection.hasFlag(Flag.Type.ALLOWEXPLOSIONS); } // Returns true if the block that was destroyed should not be removed public static boolean denyDestroyOther(Barrel barrel) { - return LWC.getInstance().findProtection(barrel.getSignOfSpigot()) != null; + return LWC.getInstance().findProtection(barrel.getBody().getSignOfSpigot()) != null; } } diff --git a/src/com/dre/brewery/listeners/PlayerListener.java b/src/com/dre/brewery/listeners/PlayerListener.java index 67e9cf9..7d9800d 100644 --- a/src/com/dre/brewery/listeners/PlayerListener.java +++ b/src/com/dre/brewery/listeners/PlayerListener.java @@ -52,7 +52,7 @@ public class PlayerListener implements Listener { } } else if (LegacyUtil.isWoodStairs(type)) { for (Barrel barrel2 : Barrel.barrels) { - if (barrel2.hasStairsBlock(clickedBlock)) { + if (barrel2.getBody().hasStairsBlock(clickedBlock)) { if (BConfig.openEverywhere || !barrel2.isLarge()) { barrel = barrel2; } From 437f521a9b2a7ec110ba7c0f253cc79aaff2d52e Mon Sep 17 00:00:00 2001 From: Sn0wStorm Date: Wed, 16 Oct 2019 20:07:09 +0200 Subject: [PATCH 22/51] Refractor Utility --- src/com/dre/brewery/BCauldron.java | 2 + src/com/dre/brewery/BEffect.java | 1 + src/com/dre/brewery/BIngredients.java | 1 + src/com/dre/brewery/BPlayer.java | 1 + src/com/dre/brewery/BRecipe.java | 1 + src/com/dre/brewery/Barrel.java | 2 + src/com/dre/brewery/BarrelBody.java | 2 + src/com/dre/brewery/Brew.java | 1 + src/com/dre/brewery/P.java | 1 + src/com/dre/brewery/Wakeup.java | 1 + .../brewery/api/events/IngedientAddEvent.java | 5 +- src/com/dre/brewery/filedata/BConfig.java | 9 +- src/com/dre/brewery/filedata/BData.java | 1 + .../dre/brewery/filedata/ConfigUpdater.java | 2 +- src/com/dre/brewery/filedata/DataSave.java | 2 +- src/com/dre/brewery/filedata/DataUpdater.java | 213 +++++++++--------- .../integration/IntegrationListener.java | 2 +- .../brewery/integration/LogBlockBarrel.java | 2 +- .../{WGBarrelOld.java => WGBarrel5.java} | 4 +- .../{WGBarrelNew.java => WGBarrel6.java} | 2 +- .../dre/brewery/listeners/BlockListener.java | 2 +- .../brewery/listeners/CommandListener.java | 1 + .../dre/brewery/listeners/PlayerListener.java | 1 + .../dre/brewery/listeners/WorldListener.java | 3 +- src/com/dre/brewery/lore/BrewLore.java | 1 + src/com/dre/brewery/{ => utility}/BUtil.java | 5 +- .../dre/brewery/{ => utility}/LegacyUtil.java | 3 +- .../brewery/{ => utility}/PotionColor.java | 4 +- 28 files changed, 147 insertions(+), 128 deletions(-) rename src/com/dre/brewery/integration/{WGBarrelOld.java => WGBarrel5.java} (96%) rename src/com/dre/brewery/integration/{WGBarrelNew.java => WGBarrel6.java} (95%) rename src/com/dre/brewery/{ => utility}/BUtil.java (98%) rename src/com/dre/brewery/{ => utility}/LegacyUtil.java (99%) rename src/com/dre/brewery/{ => utility}/PotionColor.java (97%) diff --git a/src/com/dre/brewery/BCauldron.java b/src/com/dre/brewery/BCauldron.java index 56c7311..b8cd460 100644 --- a/src/com/dre/brewery/BCauldron.java +++ b/src/com/dre/brewery/BCauldron.java @@ -1,6 +1,8 @@ package com.dre.brewery; import com.dre.brewery.api.events.IngedientAddEvent; +import com.dre.brewery.utility.BUtil; +import com.dre.brewery.utility.LegacyUtil; import org.bukkit.Effect; import org.bukkit.Material; import org.bukkit.block.Block; diff --git a/src/com/dre/brewery/BEffect.java b/src/com/dre/brewery/BEffect.java index fe12836..4d516bd 100644 --- a/src/com/dre/brewery/BEffect.java +++ b/src/com/dre/brewery/BEffect.java @@ -1,5 +1,6 @@ package com.dre.brewery; +import com.dre.brewery.utility.BUtil; import org.bukkit.entity.Player; import org.bukkit.inventory.meta.PotionMeta; import org.bukkit.potion.PotionEffect; diff --git a/src/com/dre/brewery/BIngredients.java b/src/com/dre/brewery/BIngredients.java index 8eca978..fc44e07 100644 --- a/src/com/dre/brewery/BIngredients.java +++ b/src/com/dre/brewery/BIngredients.java @@ -2,6 +2,7 @@ package com.dre.brewery; import com.dre.brewery.api.events.brew.BrewModifyEvent; import com.dre.brewery.lore.BrewLore; +import com.dre.brewery.utility.PotionColor; import org.bukkit.Material; import org.bukkit.configuration.ConfigurationSection; import org.bukkit.inventory.ItemStack; diff --git a/src/com/dre/brewery/BPlayer.java b/src/com/dre/brewery/BPlayer.java index bf133e5..857e57c 100644 --- a/src/com/dre/brewery/BPlayer.java +++ b/src/com/dre/brewery/BPlayer.java @@ -6,6 +6,7 @@ import com.dre.brewery.api.events.PlayerPukeEvent; import com.dre.brewery.api.events.PlayerPushEvent; import com.dre.brewery.api.events.brew.BrewDrinkEvent; import com.dre.brewery.filedata.BConfig; +import com.dre.brewery.utility.BUtil; import org.apache.commons.lang.mutable.MutableInt; import org.bukkit.Location; import org.bukkit.Material; diff --git a/src/com/dre/brewery/BRecipe.java b/src/com/dre/brewery/BRecipe.java index c5644e6..4263f78 100644 --- a/src/com/dre/brewery/BRecipe.java +++ b/src/com/dre/brewery/BRecipe.java @@ -1,6 +1,7 @@ package com.dre.brewery; import com.dre.brewery.filedata.BConfig; +import com.dre.brewery.utility.PotionColor; import org.bukkit.Material; import org.bukkit.configuration.ConfigurationSection; import org.bukkit.inventory.ItemStack; diff --git a/src/com/dre/brewery/Barrel.java b/src/com/dre/brewery/Barrel.java index 8135511..e5cc718 100644 --- a/src/com/dre/brewery/Barrel.java +++ b/src/com/dre/brewery/Barrel.java @@ -7,6 +7,8 @@ import com.dre.brewery.api.events.barrel.BarrelRemoveEvent; import com.dre.brewery.filedata.BConfig; import com.dre.brewery.integration.LogBlockBarrel; import com.dre.brewery.lore.BrewLore; +import com.dre.brewery.utility.BUtil; +import com.dre.brewery.utility.LegacyUtil; import org.bukkit.Location; import org.bukkit.Material; import org.bukkit.Sound; diff --git a/src/com/dre/brewery/BarrelBody.java b/src/com/dre/brewery/BarrelBody.java index 1f3ad3f..c1cb350 100644 --- a/src/com/dre/brewery/BarrelBody.java +++ b/src/com/dre/brewery/BarrelBody.java @@ -1,5 +1,7 @@ package com.dre.brewery; +import com.dre.brewery.utility.BUtil; +import com.dre.brewery.utility.LegacyUtil; import org.apache.commons.lang.ArrayUtils; import org.bukkit.Material; import org.bukkit.block.Block; diff --git a/src/com/dre/brewery/Brew.java b/src/com/dre/brewery/Brew.java index 98b576b..df4ee1e 100644 --- a/src/com/dre/brewery/Brew.java +++ b/src/com/dre/brewery/Brew.java @@ -3,6 +3,7 @@ package com.dre.brewery; import com.dre.brewery.api.events.brew.BrewModifyEvent; import com.dre.brewery.filedata.BConfig; import com.dre.brewery.lore.*; +import com.dre.brewery.utility.PotionColor; import org.bukkit.Material; import org.bukkit.configuration.ConfigurationSection; import org.bukkit.inventory.BrewerInventory; diff --git a/src/com/dre/brewery/P.java b/src/com/dre/brewery/P.java index d7cb911..2203109 100644 --- a/src/com/dre/brewery/P.java +++ b/src/com/dre/brewery/P.java @@ -8,6 +8,7 @@ import com.dre.brewery.filedata.UpdateChecker; import com.dre.brewery.integration.IntegrationListener; import com.dre.brewery.integration.LogBlockBarrel; import com.dre.brewery.listeners.*; +import com.dre.brewery.utility.BUtil; import org.apache.commons.lang.math.NumberUtils; import org.bukkit.Bukkit; import org.bukkit.ChatColor; diff --git a/src/com/dre/brewery/Wakeup.java b/src/com/dre/brewery/Wakeup.java index e578957..371d169 100644 --- a/src/com/dre/brewery/Wakeup.java +++ b/src/com/dre/brewery/Wakeup.java @@ -1,5 +1,6 @@ package com.dre.brewery; +import com.dre.brewery.utility.BUtil; import org.bukkit.Location; import org.bukkit.command.CommandSender; import org.bukkit.configuration.ConfigurationSection; diff --git a/src/com/dre/brewery/api/events/IngedientAddEvent.java b/src/com/dre/brewery/api/events/IngedientAddEvent.java index 8008595..60bde23 100644 --- a/src/com/dre/brewery/api/events/IngedientAddEvent.java +++ b/src/com/dre/brewery/api/events/IngedientAddEvent.java @@ -1,9 +1,8 @@ package com.dre.brewery.api.events; import com.dre.brewery.BCauldron; -import com.dre.brewery.LegacyUtil; +import com.dre.brewery.utility.LegacyUtil; import org.bukkit.block.Block; -import org.bukkit.block.BlockState; import org.bukkit.block.data.BlockData; import org.bukkit.block.data.Levelled; import org.bukkit.entity.Player; @@ -11,8 +10,6 @@ import org.bukkit.event.Cancellable; import org.bukkit.event.HandlerList; import org.bukkit.event.player.PlayerEvent; import org.bukkit.inventory.ItemStack; -import org.bukkit.material.Cauldron; -import org.bukkit.material.MaterialData; /* * Player adding an ingredient to a cauldron diff --git a/src/com/dre/brewery/filedata/BConfig.java b/src/com/dre/brewery/filedata/BConfig.java index b06cae3..63a40c2 100644 --- a/src/com/dre/brewery/filedata/BConfig.java +++ b/src/com/dre/brewery/filedata/BConfig.java @@ -3,8 +3,9 @@ package com.dre.brewery.filedata; import com.dre.brewery.*; import com.dre.brewery.integration.WGBarrel; import com.dre.brewery.integration.WGBarrel7; -import com.dre.brewery.integration.WGBarrelNew; -import com.dre.brewery.integration.WGBarrelOld; +import com.dre.brewery.integration.WGBarrel6; +import com.dre.brewery.integration.WGBarrel5; +import com.dre.brewery.utility.BUtil; import org.bukkit.Bukkit; import org.bukkit.Material; import org.bukkit.command.CommandSender; @@ -138,9 +139,9 @@ public class BConfig { if (plugin != null) { String wgv = plugin.getDescription().getVersion(); if (wgv.startsWith("6.")) { - wg = new WGBarrelNew(); + wg = new WGBarrel6(); } else if (wgv.startsWith("5.")) { - wg = new WGBarrelOld(); + wg = new WGBarrel5(); } else { wg = new WGBarrel7(); } diff --git a/src/com/dre/brewery/filedata/BData.java b/src/com/dre/brewery/filedata/BData.java index afc9355..0d4bed5 100644 --- a/src/com/dre/brewery/filedata/BData.java +++ b/src/com/dre/brewery/filedata/BData.java @@ -1,6 +1,7 @@ package com.dre.brewery.filedata; import com.dre.brewery.*; +import com.dre.brewery.utility.BUtil; import org.apache.commons.lang.math.NumberUtils; import org.bukkit.Location; import org.bukkit.Material; diff --git a/src/com/dre/brewery/filedata/ConfigUpdater.java b/src/com/dre/brewery/filedata/ConfigUpdater.java index ed2d0af..60b1f71 100644 --- a/src/com/dre/brewery/filedata/ConfigUpdater.java +++ b/src/com/dre/brewery/filedata/ConfigUpdater.java @@ -1,6 +1,6 @@ package com.dre.brewery.filedata; -import com.dre.brewery.LegacyUtil; +import com.dre.brewery.utility.LegacyUtil; import com.dre.brewery.P; import org.bukkit.Material; diff --git a/src/com/dre/brewery/filedata/DataSave.java b/src/com/dre/brewery/filedata/DataSave.java index 8a63842..0cd86ed 100644 --- a/src/com/dre/brewery/filedata/DataSave.java +++ b/src/com/dre/brewery/filedata/DataSave.java @@ -4,7 +4,7 @@ package com.dre.brewery.filedata; import java.io.File; import com.dre.brewery.MCBarrel; -import com.dre.brewery.BUtil; +import com.dre.brewery.utility.BUtil; import org.bukkit.World; import org.bukkit.configuration.ConfigurationSection; import org.bukkit.configuration.file.FileConfiguration; diff --git a/src/com/dre/brewery/filedata/DataUpdater.java b/src/com/dre/brewery/filedata/DataUpdater.java index 0bacfe1..fc84159 100644 --- a/src/com/dre/brewery/filedata/DataUpdater.java +++ b/src/com/dre/brewery/filedata/DataUpdater.java @@ -1,107 +1,106 @@ -package com.dre.brewery.filedata; - -import com.dre.brewery.LegacyUtil; -import java.io.File; -import java.io.IOException; -import java.util.HashMap; -import java.util.Map; - -import org.bukkit.Material; -import org.bukkit.configuration.ConfigurationSection; -import org.bukkit.configuration.file.FileConfiguration; - -import com.dre.brewery.P; - -public class DataUpdater { - - private FileConfiguration data; - private File file; - - public DataUpdater(FileConfiguration data, File file) { - this.data = data; - this.file = file; - } - - - - public void update(String fromVersion) { - if (fromVersion.equalsIgnoreCase("1.0")) { - update10(); - //fromVersion = "1.1"; - } - - try { - data.save(file); - } catch (IOException e) { - e.printStackTrace(); - } - } - - - - - @SuppressWarnings("deprecation") - public void update10() { - - data.set("Version", DataSave.dataVersion); - - ConfigurationSection section = data.getConfigurationSection("Ingredients"); - try { - if (section != null) { - for (String id : section.getKeys(false)) { - ConfigurationSection matSection = section.getConfigurationSection(id + ".mats"); - if (matSection != null) { - // matSection has all the materials + amount as Integers - Map ingredients = new HashMap<>(); - for (String ingredient : matSection.getKeys(false)) { - // convert to Material - Material mat = LegacyUtil.getMaterial(P.p.parseInt(ingredient)); - if (mat != null) { - ingredients.put(mat.name(), matSection.getInt(ingredient)); - } - } - section.set(id + ".mats", ingredients); - } else { - P.p.errorLog("Ingredient id: '" + id + "' incomplete in data.yml"); - } - } - } - } catch (Exception e) { - // Getting Material by id may not work in the future - P.p.errorLog("Error Converting Ingredient Section of the Data File, newer versions of Bukkit may not support the old Save File anymore:"); - e.printStackTrace(); - } - - section = data.getConfigurationSection("BCauldron"); - if (section != null) { - try { - for (String uuid : section.getKeys(false)) { - ConfigurationSection cauldrons = section.getConfigurationSection(uuid); - if (cauldrons != null) { - for (String id : cauldrons.getKeys(false)) { - ConfigurationSection ingredientSection = cauldrons.getConfigurationSection(id + ".ingredients"); - if (ingredientSection != null) { - // has all the materials + amount as Integers - Map ingredients = new HashMap<>(); - for (String ingredient : ingredientSection.getKeys(false)) { - // convert to Material - Material mat = LegacyUtil.getMaterial(P.p.parseInt(ingredient)); - if (mat != null) { - ingredients.put(mat.name(), ingredientSection.getInt(ingredient)); - } - } - cauldrons.set(id + ".ingredients", ingredients); - } else { - P.p.errorLog("BCauldron " + id + " is missing Ingredient Section"); - } - } - } - } - } catch (Exception e) { - // Getting Material by id may not work in the future - P.p.errorLog("Error Converting Ingredient Section of Cauldrons, newer versions of Bukkit may not support the old Save File anymore:"); - e.printStackTrace(); - } - } - } -} +package com.dre.brewery.filedata; + +import com.dre.brewery.utility.LegacyUtil; +import com.dre.brewery.P; +import org.bukkit.Material; +import org.bukkit.configuration.ConfigurationSection; +import org.bukkit.configuration.file.FileConfiguration; + +import java.io.File; +import java.io.IOException; +import java.util.HashMap; +import java.util.Map; + +public class DataUpdater { + + private FileConfiguration data; + private File file; + + public DataUpdater(FileConfiguration data, File file) { + this.data = data; + this.file = file; + } + + + + public void update(String fromVersion) { + if (fromVersion.equalsIgnoreCase("1.0")) { + update10(); + //fromVersion = "1.1"; + } + + try { + data.save(file); + } catch (IOException e) { + e.printStackTrace(); + } + } + + + + + @SuppressWarnings("deprecation") + public void update10() { + + data.set("Version", DataSave.dataVersion); + + ConfigurationSection section = data.getConfigurationSection("Ingredients"); + try { + if (section != null) { + for (String id : section.getKeys(false)) { + ConfigurationSection matSection = section.getConfigurationSection(id + ".mats"); + if (matSection != null) { + // matSection has all the materials + amount as Integers + Map ingredients = new HashMap<>(); + for (String ingredient : matSection.getKeys(false)) { + // convert to Material + Material mat = LegacyUtil.getMaterial(P.p.parseInt(ingredient)); + if (mat != null) { + ingredients.put(mat.name(), matSection.getInt(ingredient)); + } + } + section.set(id + ".mats", ingredients); + } else { + P.p.errorLog("Ingredient id: '" + id + "' incomplete in data.yml"); + } + } + } + } catch (Exception e) { + // Getting Material by id may not work in the future + P.p.errorLog("Error Converting Ingredient Section of the Data File, newer versions of Bukkit may not support the old Save File anymore:"); + e.printStackTrace(); + } + + section = data.getConfigurationSection("BCauldron"); + if (section != null) { + try { + for (String uuid : section.getKeys(false)) { + ConfigurationSection cauldrons = section.getConfigurationSection(uuid); + if (cauldrons != null) { + for (String id : cauldrons.getKeys(false)) { + ConfigurationSection ingredientSection = cauldrons.getConfigurationSection(id + ".ingredients"); + if (ingredientSection != null) { + // has all the materials + amount as Integers + Map ingredients = new HashMap<>(); + for (String ingredient : ingredientSection.getKeys(false)) { + // convert to Material + Material mat = LegacyUtil.getMaterial(P.p.parseInt(ingredient)); + if (mat != null) { + ingredients.put(mat.name(), ingredientSection.getInt(ingredient)); + } + } + cauldrons.set(id + ".ingredients", ingredients); + } else { + P.p.errorLog("BCauldron " + id + " is missing Ingredient Section"); + } + } + } + } + } catch (Exception e) { + // Getting Material by id may not work in the future + P.p.errorLog("Error Converting Ingredient Section of Cauldrons, newer versions of Bukkit may not support the old Save File anymore:"); + e.printStackTrace(); + } + } + } +} diff --git a/src/com/dre/brewery/integration/IntegrationListener.java b/src/com/dre/brewery/integration/IntegrationListener.java index 8523137..5d69e2d 100644 --- a/src/com/dre/brewery/integration/IntegrationListener.java +++ b/src/com/dre/brewery/integration/IntegrationListener.java @@ -1,7 +1,7 @@ package com.dre.brewery.integration; import com.dre.brewery.Barrel; -import com.dre.brewery.LegacyUtil; +import com.dre.brewery.utility.LegacyUtil; import com.dre.brewery.P; import com.dre.brewery.api.events.barrel.BarrelAccessEvent; import com.dre.brewery.api.events.barrel.BarrelDestroyEvent; diff --git a/src/com/dre/brewery/integration/LogBlockBarrel.java b/src/com/dre/brewery/integration/LogBlockBarrel.java index 4d368a8..371c0bf 100644 --- a/src/com/dre/brewery/integration/LogBlockBarrel.java +++ b/src/com/dre/brewery/integration/LogBlockBarrel.java @@ -1,6 +1,6 @@ package com.dre.brewery.integration; -import com.dre.brewery.LegacyUtil; +import com.dre.brewery.utility.LegacyUtil; import com.dre.brewery.P; import de.diddiz.LogBlock.Actor; diff --git a/src/com/dre/brewery/integration/WGBarrelOld.java b/src/com/dre/brewery/integration/WGBarrel5.java similarity index 96% rename from src/com/dre/brewery/integration/WGBarrelOld.java rename to src/com/dre/brewery/integration/WGBarrel5.java index 5cbcb7f..a71666a 100644 --- a/src/com/dre/brewery/integration/WGBarrelOld.java +++ b/src/com/dre/brewery/integration/WGBarrel5.java @@ -17,13 +17,13 @@ import com.sk89q.worldguard.protection.flags.StateFlag; import com.sk89q.worldguard.protection.managers.RegionManager; -public class WGBarrelOld implements WGBarrel { +public class WGBarrel5 implements WGBarrel { private Method allows; private Method canBuild; private Method getApplicableRegions; - public WGBarrelOld() { + public WGBarrel5() { try { allows = ApplicableRegionSet.class.getMethod("allows", StateFlag.class, LocalPlayer.class); canBuild = ApplicableRegionSet.class.getMethod("canBuild", LocalPlayer.class); diff --git a/src/com/dre/brewery/integration/WGBarrelNew.java b/src/com/dre/brewery/integration/WGBarrel6.java similarity index 95% rename from src/com/dre/brewery/integration/WGBarrelNew.java rename to src/com/dre/brewery/integration/WGBarrel6.java index e5d876a..f89fa53 100644 --- a/src/com/dre/brewery/integration/WGBarrelNew.java +++ b/src/com/dre/brewery/integration/WGBarrel6.java @@ -9,7 +9,7 @@ import org.bukkit.block.Block; import org.bukkit.entity.Player; import org.bukkit.plugin.Plugin; -public class WGBarrelNew implements WGBarrel { +public class WGBarrel6 implements WGBarrel { public boolean checkAccess(Player player, Block spigot, Plugin plugin) { WorldGuardPlugin wg = (WorldGuardPlugin) plugin; diff --git a/src/com/dre/brewery/listeners/BlockListener.java b/src/com/dre/brewery/listeners/BlockListener.java index 96bcd58..8f1a6df 100644 --- a/src/com/dre/brewery/listeners/BlockListener.java +++ b/src/com/dre/brewery/listeners/BlockListener.java @@ -1,7 +1,7 @@ package com.dre.brewery.listeners; import com.dre.brewery.BPlayer; -import com.dre.brewery.BUtil; +import com.dre.brewery.utility.BUtil; import com.dre.brewery.Barrel; import com.dre.brewery.P; import com.dre.brewery.DistortChat; diff --git a/src/com/dre/brewery/listeners/CommandListener.java b/src/com/dre/brewery/listeners/CommandListener.java index 02f97a7..12dbf7d 100644 --- a/src/com/dre/brewery/listeners/CommandListener.java +++ b/src/com/dre/brewery/listeners/CommandListener.java @@ -3,6 +3,7 @@ package com.dre.brewery.listeners; import com.dre.brewery.*; import com.dre.brewery.api.events.brew.BrewModifyEvent; import com.dre.brewery.filedata.BConfig; +import com.dre.brewery.utility.BUtil; import org.bukkit.Material; import org.bukkit.command.Command; import org.bukkit.command.CommandExecutor; diff --git a/src/com/dre/brewery/listeners/PlayerListener.java b/src/com/dre/brewery/listeners/PlayerListener.java index 7d9800d..f30e0fd 100644 --- a/src/com/dre/brewery/listeners/PlayerListener.java +++ b/src/com/dre/brewery/listeners/PlayerListener.java @@ -3,6 +3,7 @@ package com.dre.brewery.listeners; import com.dre.brewery.*; import com.dre.brewery.filedata.BConfig; import com.dre.brewery.filedata.UpdateChecker; +import com.dre.brewery.utility.LegacyUtil; import org.bukkit.GameMode; import org.bukkit.Material; import org.bukkit.block.Block; diff --git a/src/com/dre/brewery/listeners/WorldListener.java b/src/com/dre/brewery/listeners/WorldListener.java index 48cea50..a945622 100644 --- a/src/com/dre/brewery/listeners/WorldListener.java +++ b/src/com/dre/brewery/listeners/WorldListener.java @@ -2,8 +2,7 @@ package com.dre.brewery.listeners; import com.dre.brewery.BCauldron; import com.dre.brewery.Barrel; -import com.dre.brewery.P; -import com.dre.brewery.BUtil; +import com.dre.brewery.utility.BUtil; import com.dre.brewery.filedata.BData; import com.dre.brewery.filedata.DataSave; import org.bukkit.World; diff --git a/src/com/dre/brewery/lore/BrewLore.java b/src/com/dre/brewery/lore/BrewLore.java index 5fe529c..07cd4b5 100644 --- a/src/com/dre/brewery/lore/BrewLore.java +++ b/src/com/dre/brewery/lore/BrewLore.java @@ -1,6 +1,7 @@ package com.dre.brewery.lore; import com.dre.brewery.*; +import com.dre.brewery.utility.BUtil; import org.bukkit.inventory.meta.PotionMeta; import org.bukkit.potion.PotionEffect; import org.bukkit.potion.PotionEffectType; diff --git a/src/com/dre/brewery/BUtil.java b/src/com/dre/brewery/utility/BUtil.java similarity index 98% rename from src/com/dre/brewery/BUtil.java rename to src/com/dre/brewery/utility/BUtil.java index 50c0dca..50edb94 100644 --- a/src/com/dre/brewery/BUtil.java +++ b/src/com/dre/brewery/utility/BUtil.java @@ -1,5 +1,8 @@ -package com.dre.brewery; +package com.dre.brewery.utility; +import com.dre.brewery.BCauldron; +import com.dre.brewery.Barrel; +import com.dre.brewery.P; import com.dre.brewery.api.events.barrel.BarrelDestroyEvent; import org.bukkit.Bukkit; import org.bukkit.ChatColor; diff --git a/src/com/dre/brewery/LegacyUtil.java b/src/com/dre/brewery/utility/LegacyUtil.java similarity index 99% rename from src/com/dre/brewery/LegacyUtil.java rename to src/com/dre/brewery/utility/LegacyUtil.java index f0f369a..37e173b 100644 --- a/src/com/dre/brewery/LegacyUtil.java +++ b/src/com/dre/brewery/utility/LegacyUtil.java @@ -1,5 +1,6 @@ -package com.dre.brewery; +package com.dre.brewery.utility; +import com.dre.brewery.P; import org.bukkit.Bukkit; import org.bukkit.Location; import org.bukkit.Material; diff --git a/src/com/dre/brewery/PotionColor.java b/src/com/dre/brewery/utility/PotionColor.java similarity index 97% rename from src/com/dre/brewery/PotionColor.java rename to src/com/dre/brewery/utility/PotionColor.java index 8dd4359..2218061 100644 --- a/src/com/dre/brewery/PotionColor.java +++ b/src/com/dre/brewery/utility/PotionColor.java @@ -1,5 +1,6 @@ -package com.dre.brewery; +package com.dre.brewery.utility; +import com.dre.brewery.P; import org.bukkit.Color; import org.bukkit.inventory.ItemFlag; import org.bukkit.inventory.ItemStack; @@ -39,6 +40,7 @@ public class PotionColor { // gets the Damage Value, that sets a color on the potion // offset +32 is not accepted by brewer, so not further destillable + // Only for minecraft pre 1.9 public short getColorId(boolean destillable) { if (destillable) { return (short) (colorId + 64); From f431c13100ce0f6fd29ae2ad2478e0e30aef2095 Mon Sep 17 00:00:00 2001 From: Sn0wStorm Date: Fri, 18 Oct 2019 16:30:03 +0200 Subject: [PATCH 23/51] Load Scramble Seed key from Config Remember all used Scramble seeds to unscramble potions --- pom.xml | 6 + resources/config/v12/de/config.yml | 12 +- resources/config/v12/en/config.yml | 9 +- resources/config/v12/fr/config.yml | 9 +- resources/config/v12/it/config.yml | 9 +- resources/config/v13/de/config.yml | 12 +- resources/config/v13/en/config.yml | 9 +- resources/config/v13/fr/config.yml | 9 +- resources/config/v13/it/config.yml | 9 +- resources/config/v13/zh/config.yml | 8 ++ src/com/dre/brewery/BPlayer.java | 3 + src/com/dre/brewery/Barrel.java | 17 ++- src/com/dre/brewery/Brew.java | 112 +++++++++++------- src/com/dre/brewery/api/BreweryApi.java | 7 ++ .../brewery/api/events/brew/BrewEvent.java | 5 +- .../api/events/brew/BrewModifyEvent.java | 6 +- src/com/dre/brewery/filedata/BConfig.java | 4 + src/com/dre/brewery/filedata/BData.java | 2 +- .../dre/brewery/filedata/ConfigUpdater.java | 25 ++++ src/com/dre/brewery/filedata/DataSave.java | 2 +- .../brewery/listeners/InventoryListener.java | 4 +- src/com/dre/brewery/lore/BrewLore.java | 9 +- src/com/dre/brewery/lore/SeedInputStream.java | 4 +- .../dre/brewery/lore/XORScrambleStream.java | 36 ++++++ .../dre/brewery/lore/XORUnscrambleStream.java | 68 ++++++++++- 25 files changed, 327 insertions(+), 69 deletions(-) diff --git a/pom.xml b/pom.xml index 09a7613..2e5246f 100644 --- a/pom.xml +++ b/pom.xml @@ -232,6 +232,12 @@ 1.5 compile + + org.jetbrains + annotations + 16.0.2 + compile + diff --git a/resources/config/v12/de/config.yml b/resources/config/v12/de/config.yml index 8be0305..ac799da 100644 --- a/resources/config/v12/de/config.yml +++ b/resources/config/v12/de/config.yml @@ -3,7 +3,6 @@ # -- Verschiedene Einstellungen -- # Standardeinstellungen sind in [] angegeben -# Löschen einzelner Einstellungen deaktiviert sie # Sprachedatei die genutzt werden sollte (befindet sich in plugins/Brewery/languages) language: de @@ -57,8 +56,12 @@ openLargeBarrelEverywhere: true # Wie viele Brewery Getränke in die Minecraft Fässer getan werden können [6] maxBrewsInMCBarrels: 6 -# In den Serverlog loggen was der Spieler tatsächlich geschrieben hat, bevor seine Worte verändert wurden [false] -logRealChat: false +# Benutzte Zutaten und andere Brau-Daten werden in allen Brewery Tränken gespeichert. Um zu verhindern, +# dass gehackte clients diese Daten auslesen um Rezepte herauszufinden, können diese encodiert werden. +# Einziger Nachteil: Tränke können nur auf Servern mit dem gleichen encodeKey benutzt werden. +# Dies kann also aktiviert werden um Rezept-cheating schwerer zu machen, aber keine Tränke per World Download, Schematic, o.ä. geteilt werden. [false] +enableEncode: false +encodeKey: 0 # Aktiviert das Suchen nach Updates für Brewery mit der curseforge api [true] # Wenn ein Update gefunden wurde, wird dies bei Serverstart im log angezeigt, sowie OPs benachrichtigt @@ -286,6 +289,9 @@ useLogBlock: true # Unten kann noch eingestellt werden wie und was verändert wird enableChatDistortion: true +# In den Serverlog loggen was der Spieler tatsächlich geschrieben hat, bevor seine Worte verändert wurden [false] +logRealChat: false + # Text nach den angegebenen Kommandos wird bei Trunkenheit ebenfalls Verändert (Liste) [- /gl] distortCommands: - /gl diff --git a/resources/config/v12/en/config.yml b/resources/config/v12/en/config.yml index 38eadb4..1845a69 100644 --- a/resources/config/v12/en/config.yml +++ b/resources/config/v12/en/config.yml @@ -3,7 +3,6 @@ # -- Settings -- # Defaults are written in [] -# Deleting of single settings disables them # Languagefile to be used (found in plugins/Brewery/languages) language: en @@ -57,6 +56,14 @@ openLargeBarrelEverywhere: true # How many Brewery drinks can be put into the Minecraft barrels [6] maxBrewsInMCBarrels: 6 +# The used Ingredients and other brewing-data is saved to all Brewery Items. To prevent +# hacked clients from reading what exactly was used to brew an item, the data can be encoded/scrambled. +# This is a fast process to stop players from hacking out recipes, once they get hold of a brew. +# Only drawback: brew items can only be used on another server with the same encodeKey. +# So enable this if you want to make recipe cheating harder, but don't share any brews by world download, schematics, or other means. [false] +enableEncode: false +encodeKey: 0 + # Enable checking for Updates, Checks the curseforge api for updates to Brewery [true] # If an Update is found a Message is logged on Server-start and displayed to OPs joining the game updateCheck: true diff --git a/resources/config/v12/fr/config.yml b/resources/config/v12/fr/config.yml index e7673d6..82cd49e 100644 --- a/resources/config/v12/fr/config.yml +++ b/resources/config/v12/fr/config.yml @@ -3,7 +3,6 @@ # -- Paramètres -- # Les paramètres par défaut sont entre [] -# Supprimer un paramètre le désactive # Fichier de langage utilisé (trouvable dans plugins/Brewery/languages) language: fr @@ -57,6 +56,14 @@ openLargeBarrelEverywhere: true # How many Brewery drinks can be put into the Minecraft barrels [6] maxBrewsInMCBarrels: 6 +# The used Ingredients and other brewing-data is saved to all Brewery Items. To prevent +# hacked clients from reading what exactly was used to brew an item, the data can be encoded/scrambled. +# This is a fast process to stop players from hacking out recipes, once they get hold of a brew. +# Only drawback: brew items can only be used on another server with the same encodeKey. +# So enable this if you want to make recipe cheating harder, but don't share any brews by world download, schematics, or other means. [false] +enableEncode: false +encodeKey: 0 + # Enable checking for Updates, Checks the curseforge api for updates to Brewery [true] # If an Update is found a Message is logged on Server-start and displayed to OPs joining the game updateCheck: true diff --git a/resources/config/v12/it/config.yml b/resources/config/v12/it/config.yml index 70af3f2..335cf03 100644 --- a/resources/config/v12/it/config.yml +++ b/resources/config/v12/it/config.yml @@ -3,7 +3,6 @@ # -- Opzioni -- # I valori di default sono scritti fra [] -# Cancellare una voce la disabilita # Lingua da usare (fra quelle in plugins/Brewery/languages) language: it @@ -57,6 +56,14 @@ openLargeBarrelEverywhere: true # How many Brewery drinks can be put into the Minecraft barrels [6] maxBrewsInMCBarrels: 6 +# The used Ingredients and other brewing-data is saved to all Brewery Items. To prevent +# hacked clients from reading what exactly was used to brew an item, the data can be encoded/scrambled. +# This is a fast process to stop players from hacking out recipes, once they get hold of a brew. +# Only drawback: brew items can only be used on another server with the same encodeKey. +# So enable this if you want to make recipe cheating harder, but don't share any brews by world download, schematics, or other means. [false] +enableEncode: false +encodeKey: 0 + # Abilita il controllo degli aggiornamenti, controlla l'API di CurseForge per eventuali aggiornamenti di Brewery [true] # Se quando un aggiornamento viene trovato un messaggio è loggato e mostrato agli OPs quando entrano in gioco. updateCheck: true diff --git a/resources/config/v13/de/config.yml b/resources/config/v13/de/config.yml index f46df44..681e8fb 100644 --- a/resources/config/v13/de/config.yml +++ b/resources/config/v13/de/config.yml @@ -3,7 +3,6 @@ # -- Verschiedene Einstellungen -- # Standardeinstellungen sind in [] angegeben -# Löschen einzelner Einstellungen deaktiviert sie # Sprachedatei die genutzt werden sollte (befindet sich in plugins/Brewery/languages) language: de @@ -57,8 +56,12 @@ openLargeBarrelEverywhere: true # Wie viele Brewery Getränke in die Minecraft Fässer getan werden können [6] maxBrewsInMCBarrels: 6 -# In den Serverlog loggen was der Spieler tatsächlich geschrieben hat, bevor seine Worte verändert wurden [false] -logRealChat: false +# Benutzte Zutaten und andere Brau-Daten werden in allen Brewery Tränken gespeichert. Um zu verhindern, +# dass gehackte clients diese Daten auslesen um Rezepte herauszufinden, können diese encodiert werden. +# Einziger Nachteil: Tränke können nur auf Servern mit dem gleichen encodeKey benutzt werden. +# Dies kann also aktiviert werden um Rezept-cheating schwerer zu machen, aber keine Tränke per World Download, Schematic, o.ä. geteilt werden. [false] +enableEncode: false +encodeKey: 0 # Aktiviert das Suchen nach Updates für Brewery mit der curseforge api [true] # Wenn ein Update gefunden wurde, wird dies bei Serverstart im log angezeigt, sowie OPs benachrichtigt @@ -277,6 +280,9 @@ useLogBlock: true # Unten kann noch eingestellt werden wie und was verändert wird enableChatDistortion: true +# In den Serverlog loggen was der Spieler tatsächlich geschrieben hat, bevor seine Worte verändert wurden [false] +logRealChat: false + # Text nach den angegebenen Kommandos wird bei Trunkenheit ebenfalls Verändert (Liste) [- /gl] distortCommands: - /gl diff --git a/resources/config/v13/en/config.yml b/resources/config/v13/en/config.yml index cc68467..376d920 100644 --- a/resources/config/v13/en/config.yml +++ b/resources/config/v13/en/config.yml @@ -3,7 +3,6 @@ # -- Settings -- # Defaults are written in [] -# Deleting of single settings disables them # Languagefile to be used (found in plugins/Brewery/languages) language: en @@ -57,6 +56,14 @@ openLargeBarrelEverywhere: true # How many Brewery drinks can be put into the Minecraft barrels [6] maxBrewsInMCBarrels: 6 +# The used Ingredients and other brewing-data is saved to all Brewery Items. To prevent +# hacked clients from reading what exactly was used to brew an item, the data can be encoded/scrambled. +# This is a fast process to stop players from hacking out recipes, once they get hold of a brew. +# Only drawback: brew items can only be used on another server with the same encodeKey. +# So enable this if you want to make recipe cheating harder, but don't share any brews by world download, schematics, or other means. [false] +enableEncode: false +encodeKey: 0 + # Enable checking for Updates, Checks the curseforge api for updates to Brewery [true] # If an Update is found a Message is logged on Server-start and displayed to OPs joining the game updateCheck: true diff --git a/resources/config/v13/fr/config.yml b/resources/config/v13/fr/config.yml index cc000f0..98f15cf 100644 --- a/resources/config/v13/fr/config.yml +++ b/resources/config/v13/fr/config.yml @@ -3,7 +3,6 @@ # -- Paramètres -- # Les paramètres par défaut sont entre [] -# Supprimer un paramètre le désactive # Fichier de langage utilisé (trouvable dans plugins/Brewery/languages) language: fr @@ -57,6 +56,14 @@ openLargeBarrelEverywhere: true # How many Brewery drinks can be put into the Minecraft barrels [6] maxBrewsInMCBarrels: 6 +# The used Ingredients and other brewing-data is saved to all Brewery Items. To prevent +# hacked clients from reading what exactly was used to brew an item, the data can be encoded/scrambled. +# This is a fast process to stop players from hacking out recipes, once they get hold of a brew. +# Only drawback: brew items can only be used on another server with the same encodeKey. +# So enable this if you want to make recipe cheating harder, but don't share any brews by world download, schematics, or other means. [false] +enableEncode: false +encodeKey: 0 + # Enable checking for Updates, Checks the curseforge api for updates to Brewery [true] # If an Update is found a Message is logged on Server-start and displayed to OPs joining the game updateCheck: true diff --git a/resources/config/v13/it/config.yml b/resources/config/v13/it/config.yml index 55649f8..64895cd 100644 --- a/resources/config/v13/it/config.yml +++ b/resources/config/v13/it/config.yml @@ -3,7 +3,6 @@ # -- Opzioni -- # I valori di default sono scritti fra [] -# Cancellare una voce la disabilita # Lingua da usare (fra quelle in plugins/Brewery/languages) language: it @@ -57,6 +56,14 @@ openLargeBarrelEverywhere: true # How many Brewery drinks can be put into the Minecraft barrels [6] maxBrewsInMCBarrels: 6 +# The used Ingredients and other brewing-data is saved to all Brewery Items. To prevent +# hacked clients from reading what exactly was used to brew an item, the data can be encoded/scrambled. +# This is a fast process to stop players from hacking out recipes, once they get hold of a brew. +# Only drawback: brew items can only be used on another server with the same encodeKey. +# So enable this if you want to make recipe cheating harder, but don't share any brews by world download, schematics, or other means. [false] +enableEncode: false +encodeKey: 0 + # Abilita il controllo degli aggiornamenti, controlla l'API di CurseForge per eventuali aggiornamenti di Brewery [true] # Se quando un aggiornamento viene trovato un messaggio è loggato e mostrato agli OPs quando entrano in gioco. updateCheck: true diff --git a/resources/config/v13/zh/config.yml b/resources/config/v13/zh/config.yml index ad157f0..b1dfda5 100644 --- a/resources/config/v13/zh/config.yml +++ b/resources/config/v13/zh/config.yml @@ -58,6 +58,14 @@ openLargeBarrelEverywhere: false # MC自带的桶内可以存放多少饮品 [6] maxBrewsInMCBarrels: 6 +# The used Ingredients and other brewing-data is saved to all Brewery Items. To prevent +# hacked clients from reading what exactly was used to brew an item, the data can be encoded/scrambled. +# This is a fast process to stop players from hacking out recipes, once they get hold of a brew. +# Only drawback: brew items can only be used on another server with the same encodeKey. +# So enable this if you want to make recipe cheating harder, but don't share any brews by world download, schematics, or other means. [false] +enableEncode: false +encodeKey: 0 + # 是否检查更新.[true] # 若有更新, 服务端后台与上线时的管理员会收到通知. updateCheck: true diff --git a/src/com/dre/brewery/BPlayer.java b/src/com/dre/brewery/BPlayer.java index 857e57c..7db9de3 100644 --- a/src/com/dre/brewery/BPlayer.java +++ b/src/com/dre/brewery/BPlayer.java @@ -21,6 +21,7 @@ import org.bukkit.inventory.meta.ItemMeta; import org.bukkit.potion.PotionEffect; import org.bukkit.potion.PotionEffectType; import org.bukkit.util.Vector; +import org.jetbrains.annotations.Nullable; import java.lang.reflect.Field; import java.lang.reflect.InvocationTargetException; @@ -53,6 +54,7 @@ public class BPlayer { players.put(name, this); } + @Nullable public static BPlayer get(Player player) { if (!players.isEmpty()) { return players.get(BUtil.playerString(player)); @@ -61,6 +63,7 @@ public class BPlayer { } // This method may be slow and should not be used if not needed + @Nullable public static BPlayer getByName(String playerName) { if (P.useUUID) { for (Map.Entry entry : players.entrySet()) { diff --git a/src/com/dre/brewery/Barrel.java b/src/com/dre/brewery/Barrel.java index e5cc718..f42bb90 100644 --- a/src/com/dre/brewery/Barrel.java +++ b/src/com/dre/brewery/Barrel.java @@ -23,6 +23,7 @@ import org.bukkit.inventory.InventoryHolder; import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.meta.PotionMeta; import org.bukkit.scheduler.BukkitRunnable; +import org.jetbrains.annotations.NotNull; import java.util.ArrayList; import java.util.List; @@ -42,6 +43,11 @@ public class Barrel implements InventoryHolder { public Barrel(Block spigot, byte signoffset) { this.spigot = spigot; + if (isLarge()) { + inventory = P.p.getServer().createInventory(this, 27, P.p.languageReader.get("Etc_Barrel")); + } else { + inventory = P.p.getServer().createInventory(this, 9, P.p.languageReader.get("Etc_Barrel")); + } body = new BarrelBody(this, signoffset); } @@ -163,6 +169,7 @@ public class Barrel implements InventoryHolder { public void playOpeningSound() { float randPitch = (float) (Math.random() * 0.1); Location location = getSpigot().getLocation(); + if (location.getWorld() == null) return; if (isLarge()) { location.getWorld().playSound(location, Sound.BLOCK_CHEST_OPEN, SoundCategory.BLOCKS, 0.4f, 0.55f + randPitch); //getSpigot().getWorld().playSound(getSpigot().getLocation(), Sound.ITEM_BUCKET_EMPTY, SoundCategory.BLOCKS, 0.5f, 0.6f + randPitch); @@ -175,6 +182,7 @@ public class Barrel implements InventoryHolder { public void playClosingSound() { float randPitch = (float) (Math.random() * 0.1); Location location = getSpigot().getLocation(); + if (location.getWorld() == null) return; if (isLarge()) { location.getWorld().playSound(location, Sound.BLOCK_BARREL_CLOSE, SoundCategory.BLOCKS, 0.5f, 0.5f + randPitch); location.getWorld().playSound(location, Sound.ITEM_BUCKET_EMPTY, SoundCategory.BLOCKS, 0.2f, 0.6f + randPitch); @@ -184,14 +192,17 @@ public class Barrel implements InventoryHolder { } @Override + @NotNull public Inventory getInventory() { return inventory; } + @NotNull public Block getSpigot() { return spigot; } + @NotNull public BarrelBody getBody() { return body; } @@ -239,7 +250,7 @@ public class Barrel implements InventoryHolder { for (Barrel barrel : barrels) { if (barrel.body.isSignOfBarrel(signoffset)) { - if (barrel.body.equals(spigot)) { + if (barrel.spigot.equals(spigot)) { if (barrel.body.getSignoffset() == 0 && signoffset != 0) { // Barrel has no signOffset even though we clicked a sign, may be old barrel.body.setSignoffset(signoffset); @@ -316,7 +327,7 @@ public class Barrel implements InventoryHolder { P.p.getServer().getPluginManager().callEvent(event); if (inventory != null) { - List viewers = new ArrayList(inventory.getViewers()); + List viewers = new ArrayList<>(inventory.getViewers()); // Copy List to fix ConcModExc for (HumanEntity viewer : viewers) { viewer.closeInventory(); @@ -368,7 +379,7 @@ public class Barrel implements InventoryHolder { // is this a Small barrel? public boolean isSmall() { - return !LegacyUtil.isSign(spigot.getType()); + return LegacyUtil.isSign(spigot.getType()); } // returns the Sign of a large barrel, the spigot if there is none diff --git a/src/com/dre/brewery/Brew.java b/src/com/dre/brewery/Brew.java index df4ee1e..ff76efe 100644 --- a/src/com/dre/brewery/Brew.java +++ b/src/com/dre/brewery/Brew.java @@ -2,6 +2,7 @@ package com.dre.brewery; import com.dre.brewery.api.events.brew.BrewModifyEvent; import com.dre.brewery.filedata.BConfig; +import com.dre.brewery.filedata.ConfigUpdater; import com.dre.brewery.lore.*; import com.dre.brewery.utility.PotionColor; import org.bukkit.Material; @@ -12,20 +13,24 @@ import org.bukkit.inventory.meta.ItemMeta; import org.bukkit.inventory.meta.PotionMeta; import org.bukkit.potion.PotionEffect; import org.bukkit.potion.PotionEffectType; +import org.jetbrains.annotations.Contract; +import org.jetbrains.annotations.Nullable; import java.io.DataInputStream; import java.io.DataOutputStream; +import java.io.File; import java.io.IOException; import java.security.InvalidKeyException; import java.security.SecureRandom; import java.util.ArrayList; import java.util.HashMap; +import java.util.List; import java.util.Map; public class Brew { - // represents the liquid in the brewed Potions private static long saveSeed; + private static List prevSaveSeeds = new ArrayList<>(); // Save Seeds that have been used in the past, stored to decode brews made at that time public static Map legacyPotions = new HashMap<>(); public static long installTime = System.currentTimeMillis(); // plugin install time in millis after epoch @@ -71,22 +76,21 @@ public class Brew { } // returns a Brew by ItemMeta + @Nullable public static Brew get(ItemMeta meta) { if (!meta.hasLore()) return null; - if (meta instanceof PotionMeta && ((PotionMeta) meta).hasCustomEffect(PotionEffectType.REGENERATION)) { - Brew brew = load(meta); - if (brew != null) { - // Load Legacy - brew = getFromPotionEffect(((PotionMeta) meta), false); - } - return brew; - } else { - return load(meta); + Brew brew = load(meta); + + if (brew == null && meta instanceof PotionMeta && ((PotionMeta) meta).hasCustomEffect(PotionEffectType.REGENERATION)) { + // Load Legacy + return getFromPotionEffect(((PotionMeta) meta), false); } + return brew; } // returns a Brew by ItemStack + @Nullable public static Brew get(ItemStack item) { if (item.getType() != Material.POTION) return null; if (!item.hasItemMeta()) return null; @@ -94,21 +98,17 @@ public class Brew { ItemMeta meta = item.getItemMeta(); if (!meta.hasLore()) return null; - if (meta instanceof PotionMeta && ((PotionMeta) meta).hasCustomEffect(PotionEffectType.REGENERATION)) { - Brew brew = load(meta); - if (brew != null) { - ((PotionMeta) meta).removeCustomEffect(PotionEffectType.REGENERATION); - } else { - // Load Legacy and convert - brew = getFromPotionEffect(((PotionMeta) meta), true); - if (brew == null) return null; - brew.save(meta); - } + Brew brew = load(meta); + + if (brew == null && meta instanceof PotionMeta && ((PotionMeta) meta).hasCustomEffect(PotionEffectType.REGENERATION)) { + // Load Legacy and convert + brew = getFromPotionEffect(((PotionMeta) meta), true); + if (brew == null) return null; + new BrewLore(brew, ((PotionMeta) meta)).removeLegacySpacing(); + brew.save(meta); item.setItemMeta(meta); - return brew; - } else { - return load(meta); } + return brew; } // Legacy Brew Loading @@ -117,7 +117,16 @@ public class Brew { if (effect.getType().equals(PotionEffectType.REGENERATION)) { if (effect.getDuration() < -1) { if (remove) { - return legacyPotions.remove(effect.getDuration()); + Brew b = legacyPotions.get(effect.getDuration()); + if (b != null) { + potionMeta.removeCustomEffect(PotionEffectType.REGENERATION); + if (b.persistent) { + return b; + } else { + return legacyPotions.remove(effect.getDuration()); + } + } + return null; } else { return legacyPotions.get(effect.getDuration()); } @@ -612,6 +621,7 @@ public class Brew { * @param event Set event to true if a BrewModifyEvent type CREATE should be called and may be cancelled. Only then may this method return null * @return The created Item, null if the Event is cancelled */ + @Contract("_, false -> !null") public ItemStack createItem(BRecipe recipe, boolean event) { if (recipe == null) { recipe = getCurrentRecipe(); @@ -654,9 +664,10 @@ public class Brew { try { loreStream = new LoreLoadStream(meta, 0); } catch (IllegalArgumentException ignored) { + // No Brew data found in Meta return null; } - XORUnscrambleStream unscrambler = new XORUnscrambleStream(new Base91DecoderStream(loreStream), saveSeed); + XORUnscrambleStream unscrambler = new XORUnscrambleStream(new Base91DecoderStream(loreStream), saveSeed, prevSaveSeeds); try (DataInputStream in = new DataInputStream(unscrambler)) { boolean parityFailed = false; if (in.readByte() != 86) { @@ -683,7 +694,7 @@ public class Brew { P.p.errorLog("IO Error while loading Brew"); e.printStackTrace(); } catch (InvalidKeyException e) { - P.p.errorLog("Failed to load Brew, has the data key 'BrewDataSeed' in the data.yml been changed?"); + P.p.errorLog("Failed to load Brew, has the data key 'encodeKey' in the config.yml been changed?"); e.printStackTrace(); } return null; @@ -718,7 +729,11 @@ public class Brew { try (DataOutputStream out = new DataOutputStream(scrambler)) { out.writeByte(86); // Parity/sanity out.writeByte(1); // Version - scrambler.start(); + if (BConfig.enableEncode) { + scrambler.start(); + } else { + scrambler.startUnscrambled(); + } saveToStream(out); } catch (IOException e) { P.p.errorLog("IO Error while saving Brew"); @@ -768,17 +783,33 @@ public class Brew { ingredients.save(out); } - public static void writeSeed(ConfigurationSection section) { - section.set("BrewDataSeed", saveSeed); + public static void loadPrevSeeds(ConfigurationSection section) { + if (section.contains("prevSaveSeeds")) { + prevSaveSeeds = section.getLongList("prevSaveSeeds"); + if (!prevSaveSeeds.contains(saveSeed)) { + prevSaveSeeds.add(saveSeed); + } + } } - public static void loadSeed(ConfigurationSection section) { - if (section.contains("BrewDataSeed")) { - saveSeed = section.getLong("BrewDataSeed"); - } else { + public static void writePrevSeeds(ConfigurationSection section) { + if (!prevSaveSeeds.isEmpty()) { + section.set("prevSaveSeeds", prevSaveSeeds); + } + } + + public static void loadSeed(ConfigurationSection config, File file) { + saveSeed = config.getLong("encodeKey", 0); + if (saveSeed == 0) { while (saveSeed == 0) { saveSeed = new SecureRandom().nextLong(); } + ConfigUpdater updater = new ConfigUpdater(file); + updater.setEncodeKey(saveSeed); + updater.saveConfig(); + } + if (!prevSaveSeeds.contains(saveSeed)) { + prevSaveSeeds.add(saveSeed); } } @@ -793,31 +824,26 @@ public class Brew { legacyPotions.put(uid, brew); } - // remove legacy potiondata from item + // remove legacy potiondata for an item public static void removeLegacy(ItemStack item) { if (legacyPotions.isEmpty()) return; if (!item.hasItemMeta()) return; ItemMeta meta = item.getItemMeta(); if (!(meta instanceof PotionMeta)) return; - for (PotionEffect effect : ((PotionMeta) meta).getCustomEffects()) { - if (effect.getType().equals(PotionEffectType.REGENERATION)) { - if (effect.getDuration() < -1) { - legacyPotions.remove(effect.getDuration()); - return; - } - } - } + getFromPotionEffect(((PotionMeta) meta), true); } - public void convertLegacy(ItemStack item) { + public void convertPre19(ItemStack item) { removeLegacy(item); PotionMeta potionMeta = ((PotionMeta) item.getItemMeta()); if (hasRecipe()) { BrewLore lore = new BrewLore(this, potionMeta); lore.removeEffects(); PotionColor.fromString(currentRecipe.getColor()).colorBrew(potionMeta, item, canDistill()); + lore.removeLegacySpacing(); } else { PotionColor.GREY.colorBrew(potionMeta, item, canDistill()); + new BrewLore(this, potionMeta).removeLegacySpacing(); } save(potionMeta); item.setItemMeta(potionMeta); diff --git a/src/com/dre/brewery/api/BreweryApi.java b/src/com/dre/brewery/api/BreweryApi.java index ca75e72..0a4d536 100644 --- a/src/com/dre/brewery/api/BreweryApi.java +++ b/src/com/dre/brewery/api/BreweryApi.java @@ -10,6 +10,7 @@ import org.bukkit.entity.Player; import org.bukkit.inventory.Inventory; import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.meta.ItemMeta; +import org.jetbrains.annotations.Nullable; public class BreweryApi { @@ -46,6 +47,7 @@ public class BreweryApi { * Checks if item is actually a Brew * Returns null if item is not a Brew */ + @Nullable public static Brew getBrew(ItemStack item) { return Brew.get(item); } @@ -56,6 +58,7 @@ public class BreweryApi { * Checks if meta has a Brew saved * Returns null if meta is not a Brew */ + @Nullable public static Brew getBrew(ItemMeta meta) { return Brew.get(meta); } @@ -68,6 +71,7 @@ public class BreweryApi { * May be any Wood, Fence, Sign that is part of a Barrel * Returns null if block is not part of a Barrel */ + @Nullable public static Barrel getBarrel(Block block) { return Barrel.get(block); } @@ -77,6 +81,7 @@ public class BreweryApi { * May be any Wood, Fence or Sign that is part of a Barrel * Returns null if block is not part of a Barrel */ + @Nullable public static Inventory getBarrelInventory(Block block) { Barrel barrel = Barrel.get(block); if (barrel != null) { @@ -115,6 +120,7 @@ public class BreweryApi { * Get a BCauldron from a Block * Returns null if block is not a BCauldron */ + @Nullable public static BCauldron getCauldron(Block block) { return BCauldron.get(block); } @@ -136,6 +142,7 @@ public class BreweryApi { * The name is the middle one of the three if three are set in the config * Returns null if recipe with that name does not exist */ + @Nullable public static BRecipe getRecipe(String name) { return BRecipe.get(name); } diff --git a/src/com/dre/brewery/api/events/brew/BrewEvent.java b/src/com/dre/brewery/api/events/brew/BrewEvent.java index e3ccd53..c6fee36 100644 --- a/src/com/dre/brewery/api/events/brew/BrewEvent.java +++ b/src/com/dre/brewery/api/events/brew/BrewEvent.java @@ -3,20 +3,23 @@ package com.dre.brewery.api.events.brew; import com.dre.brewery.Brew; import org.bukkit.event.Event; import org.bukkit.inventory.meta.ItemMeta; +import org.jetbrains.annotations.NotNull; public abstract class BrewEvent extends Event { protected final Brew brew; protected final ItemMeta meta; - public BrewEvent(Brew brew, ItemMeta meta) { + public BrewEvent(@NotNull Brew brew, @NotNull ItemMeta meta) { this.brew = brew; this.meta = meta; } + @NotNull public Brew getBrew() { return brew; } + @NotNull public ItemMeta getItemMeta() { return meta; } diff --git a/src/com/dre/brewery/api/events/brew/BrewModifyEvent.java b/src/com/dre/brewery/api/events/brew/BrewModifyEvent.java index def9f4b..12c3c07 100644 --- a/src/com/dre/brewery/api/events/brew/BrewModifyEvent.java +++ b/src/com/dre/brewery/api/events/brew/BrewModifyEvent.java @@ -6,6 +6,7 @@ import org.bukkit.event.Cancellable; import org.bukkit.event.HandlerList; import org.bukkit.inventory.meta.ItemMeta; import org.bukkit.inventory.meta.PotionMeta; +import org.jetbrains.annotations.NotNull; /* * A Brew has been created or modified @@ -19,15 +20,17 @@ public class BrewModifyEvent extends BrewEvent implements Cancellable { private boolean cancelled; - public BrewModifyEvent(Brew brew, ItemMeta meta, Type type) { + public BrewModifyEvent(@NotNull Brew brew, @NotNull ItemMeta meta, @NotNull Type type) { super(brew, meta); this.type = type; } + @NotNull public Type getType() { return type; } + @NotNull public BrewLore getLore() { return new BrewLore(getBrew(), (PotionMeta) getItemMeta()); } @@ -46,6 +49,7 @@ public class BrewModifyEvent extends BrewEvent implements Cancellable { this.cancelled = cancelled; } + @NotNull @Override public HandlerList getHandlers() { return handlers; diff --git a/src/com/dre/brewery/filedata/BConfig.java b/src/com/dre/brewery/filedata/BConfig.java index 63a40c2..5e6dd2d 100644 --- a/src/com/dre/brewery/filedata/BConfig.java +++ b/src/com/dre/brewery/filedata/BConfig.java @@ -54,6 +54,7 @@ public class BConfig { //Brew public static boolean colorInBarrels; // color the Lore while in Barrels public static boolean colorInBrewer; // color the Lore while in Brewer + public static boolean enableEncode; public static P p = P.p; @@ -173,9 +174,12 @@ public class BConfig { homeType = config.getString("homeType", null); colorInBarrels = config.getBoolean("colorInBarrels", false); colorInBrewer = config.getBoolean("colorInBrewer", false); + enableEncode = config.getBoolean("enableEncode", false); openEverywhere = config.getBoolean("openLargeBarrelEverywhere", false); MCBarrel.maxBrews = config.getInt("maxBrewsInMCBarrels", 6); + Brew.loadSeed(config, file); + // loading recipes ConfigurationSection configSection = config.getConfigurationSection("recipes"); if (configSection != null) { diff --git a/src/com/dre/brewery/filedata/BData.java b/src/com/dre/brewery/filedata/BData.java index 0d4bed5..6d4a29a 100644 --- a/src/com/dre/brewery/filedata/BData.java +++ b/src/com/dre/brewery/filedata/BData.java @@ -31,7 +31,7 @@ public class BData { Brew.installTime = data.getLong("installTime", System.currentTimeMillis()); MCBarrel.mcBarrelTime = data.getLong("MCBarrelTime", 0); - Brew.loadSeed(data); + Brew.loadPrevSeeds(data); // Check if data is the newest version String version = data.getString("Version", null); diff --git a/src/com/dre/brewery/filedata/ConfigUpdater.java b/src/com/dre/brewery/filedata/ConfigUpdater.java index 60b1f71..b03e232 100644 --- a/src/com/dre/brewery/filedata/ConfigUpdater.java +++ b/src/com/dre/brewery/filedata/ConfigUpdater.java @@ -82,6 +82,31 @@ public class ConfigUpdater { + // ---- Updating Scramble Seed ---- + + public void setEncodeKey(long key) { + int index = indexOfStart("encodeKey:"); + if (index != -1) { + setLine(index, "encodeKey: " + key); + return; + } + + // Old key not present + index = indexOfStart("enableEncode:"); + if (index == -1) { + index = indexOfStart("# So enable this if you want to make recipe cheating harder"); + } + if (index == -1) { + index = indexOfStart("version:"); + } + if (index != -1) { + addLines(index + 1, "encodeKey: " + key); + } else { + addLines(1, "encodeKey: " + key); + } + + } + // ---- Updating to newer Versions ---- // Update from a specified Config version and language to the newest version diff --git a/src/com/dre/brewery/filedata/DataSave.java b/src/com/dre/brewery/filedata/DataSave.java index 0cd86ed..579f93e 100644 --- a/src/com/dre/brewery/filedata/DataSave.java +++ b/src/com/dre/brewery/filedata/DataSave.java @@ -64,7 +64,7 @@ public class DataSave extends BukkitRunnable { configFile.set("installTime", Brew.installTime); configFile.set("MCBarrelTime", MCBarrel.mcBarrelTime); - Brew.writeSeed(configFile); + Brew.writePrevSeeds(configFile); if (!Brew.legacyPotions.isEmpty()) { Brew.save(configFile.createSection("Brew")); diff --git a/src/com/dre/brewery/listeners/InventoryListener.java b/src/com/dre/brewery/listeners/InventoryListener.java index b180a48..bcc53b0 100644 --- a/src/com/dre/brewery/listeners/InventoryListener.java +++ b/src/com/dre/brewery/listeners/InventoryListener.java @@ -111,14 +111,14 @@ public class InventoryListener implements Listener { if (P.use1_9 && !potion.hasItemFlag(ItemFlag.HIDE_POTION_EFFECTS)) { Brew brew = Brew.get(potion); if (brew != null) { - brew.convertLegacy(item); + brew.convertPre19(item); } } Brew brew = Brew.get(item); if (brew != null) { P.p.log(brew.toString()); P.p.log(potion.getLore().get(0).replaceAll("§", "")); - P.p.log("similar to beispiel? " + BRecipe.get("Beispiel").createBrew(10).isSimilar(brew)); + //P.p.log("similar to beispiel? " + BRecipe.get("Beispiel").createBrew(10).isSimilar(brew)); brew.touch(); diff --git a/src/com/dre/brewery/lore/BrewLore.java b/src/com/dre/brewery/lore/BrewLore.java index 07cd4b5..0213911 100644 --- a/src/com/dre/brewery/lore/BrewLore.java +++ b/src/com/dre/brewery/lore/BrewLore.java @@ -179,7 +179,7 @@ public class BrewLore { // Removes all effects public void removeEffects() { if (meta.hasCustomEffects()) { - for (PotionEffect effect : meta.getCustomEffects()) { + for (PotionEffect effect : new ArrayList<>(meta.getCustomEffects())) { PotionEffectType type = effect.getType(); //if (!type.equals(PotionEffectType.REGENERATION)) { meta.removeCustomEffect(type); @@ -188,6 +188,13 @@ public class BrewLore { } } + public void removeLegacySpacing() { + if (lore.size() > 0 && lore.get(0).equals("")) { + lore.remove(0); + write(); + } + } + // True if the PotionMeta has Lore in quality color public static boolean hasColorLore(PotionMeta meta) { if (!meta.hasLore()) return false; diff --git a/src/com/dre/brewery/lore/SeedInputStream.java b/src/com/dre/brewery/lore/SeedInputStream.java index c293297..2d892c1 100644 --- a/src/com/dre/brewery/lore/SeedInputStream.java +++ b/src/com/dre/brewery/lore/SeedInputStream.java @@ -1,5 +1,7 @@ package com.dre.brewery.lore; +import org.jetbrains.annotations.NotNull; + import java.io.InputStream; import java.util.Arrays; @@ -34,7 +36,7 @@ public class SeedInputStream extends InputStream { } @Override - public int read(byte[] b, int off, int len) { + public int read(@NotNull byte[] b, int off, int len) { for (int i = off; i < len; i++) { if (reader >= 4) { genNext(); diff --git a/src/com/dre/brewery/lore/XORScrambleStream.java b/src/com/dre/brewery/lore/XORScrambleStream.java index f37dd43..d860088 100644 --- a/src/com/dre/brewery/lore/XORScrambleStream.java +++ b/src/com/dre/brewery/lore/XORScrambleStream.java @@ -5,17 +5,35 @@ import java.io.IOException; import java.io.OutputStream; import java.util.Random; +/** + * A Scramble Stream that uses XOR operations to scramble an outputstream. + * a byte generator feeded with the seed is used as xor source + * The resulting data can be unscrambled by the XORUnscrambleStream + */ public class XORScrambleStream extends FilterOutputStream { private final long seed; private SeedInputStream xorStream; private boolean running; + /** + * Create a new instance of an XORScrambler, scrambling the given outputstream + * + * @param out The Outputstream to be scrambled + * @param seed The seed used for scrambling + */ public XORScrambleStream(OutputStream out, long seed) { super(out); this.seed = seed; } + /** + * To start the scrambling process this has to be called before writing any data to this stream. + * Before starting the scrambler, any data will just be passed through unscrambled to the underlying stream. + * The Scrambling can be started and stopped arbitrarily at any point, allowing for parts of unscrambled data in the stream. + * + * @throws IOException IOException + */ public void start() throws IOException { running = true; if (xorStream == null) { @@ -30,10 +48,28 @@ public class XORScrambleStream extends FilterOutputStream { } } + /** + * Stop the scrambling, any following data will be passed through unscrambled. + * The scrambling can be started again at any point after calling this + */ public void stop() { running = false; } + /** + * Mark the stream as unscrambled, any effort of unscrambing the data later will automatically read the already unscrambled data + * Useful if a stream may be scrambled or unscrambled, the unscrambler will automatically identify either way. + * + * @throws IOException IOException + * @throws IllegalStateException If the Scrambler was started in normal scrambling mode before + */ + public void startUnscrambled() throws IOException, IllegalStateException { + if (xorStream != null) throw new IllegalStateException("The Scrambler was started in scrambling mode before"); + short id = 0; + out.write((byte) (id >> 8)); + out.write((byte) id); + } + @Override public void write(int b) throws IOException { if (!running) { diff --git a/src/com/dre/brewery/lore/XORUnscrambleStream.java b/src/com/dre/brewery/lore/XORUnscrambleStream.java index 25e45f5..f409cf3 100644 --- a/src/com/dre/brewery/lore/XORUnscrambleStream.java +++ b/src/com/dre/brewery/lore/XORUnscrambleStream.java @@ -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 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 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); From 4909e59c90899dd550fde51d313935356a06de3b Mon Sep 17 00:00:00 2001 From: Sn0wStorm Date: Sun, 20 Oct 2019 21:06:35 +0200 Subject: [PATCH 24/51] Implemented NBT Saving 1.13: CustomItemTagContainer 1.14: PersistentDataContainer --- pom.xml | 4 +- src/com/dre/brewery/BDistiller.java | 4 +- src/com/dre/brewery/Brew.java | 78 +++++++++++++++---- src/com/dre/brewery/P.java | 9 +++ src/com/dre/brewery/lore/BrewLore.java | 12 +++ src/com/dre/brewery/lore/LoreLoadStream.java | 6 +- src/com/dre/brewery/lore/LoreSaveStream.java | 6 +- src/com/dre/brewery/lore/NBTLoadStream.java | 28 +++++++ src/com/dre/brewery/lore/NBTSaveStream.java | 26 +++++++ .../dre/brewery/lore/XORUnscrambleStream.java | 25 +++++- src/com/dre/brewery/utility/LegacyUtil.java | 53 +++++++++++-- 11 files changed, 222 insertions(+), 29 deletions(-) create mode 100644 src/com/dre/brewery/lore/NBTLoadStream.java create mode 100644 src/com/dre/brewery/lore/NBTSaveStream.java diff --git a/pom.xml b/pom.xml index 2e5246f..1a66a85 100644 --- a/pom.xml +++ b/pom.xml @@ -76,7 +76,7 @@ spigot-repo - https://hub.spigotmc.org/nexus/content/groups/public/ + https://hub.spigotmc.org/nexus/content/repositories/snapshots/ vault-repo @@ -111,7 +111,7 @@ org.bukkit bukkit - 1.14-R0.1-SNAPSHOT + 1.14.4-R0.1-SNAPSHOT provided diff --git a/src/com/dre/brewery/BDistiller.java b/src/com/dre/brewery/BDistiller.java index 595b90b..6f344d7 100644 --- a/src/com/dre/brewery/BDistiller.java +++ b/src/com/dre/brewery/BDistiller.java @@ -60,7 +60,9 @@ public class BDistiller { final int fuel = standInv.getHolder().getFuelLevel(); // Now check if we should bother to track it. - trackedDistillers.put(standBlock, new BDistiller(standBlock, fuel)).start(); + distiller = new BDistiller(standBlock, fuel); + trackedDistillers.put(standBlock, distiller); + distiller.start(); } // Returns a Brew or null for every Slot in the BrewerInventory diff --git a/src/com/dre/brewery/Brew.java b/src/com/dre/brewery/Brew.java index ff76efe..32e9189 100644 --- a/src/com/dre/brewery/Brew.java +++ b/src/com/dre/brewery/Brew.java @@ -16,10 +16,7 @@ import org.bukkit.potion.PotionEffectType; import org.jetbrains.annotations.Contract; import org.jetbrains.annotations.Nullable; -import java.io.DataInputStream; -import java.io.DataOutputStream; -import java.io.File; -import java.io.IOException; +import java.io.*; import java.security.InvalidKeyException; import java.security.SecureRandom; import java.util.ArrayList; @@ -44,6 +41,7 @@ public class Brew { private boolean persistent; // Only for legacy private boolean immutable; // static/immutable potions should not be changed private int lastUpdate; // last update in hours after install time + private boolean needsSave; // There was a change that has not yet been saved public Brew(BIngredients ingredients) { this.ingredients = ingredients; @@ -78,7 +76,7 @@ public class Brew { // returns a Brew by ItemMeta @Nullable public static Brew get(ItemMeta meta) { - if (!meta.hasLore()) return null; + if (!P.useNBT && !meta.hasLore()) return null; Brew brew = load(meta); @@ -96,7 +94,7 @@ public class Brew { if (!item.hasItemMeta()) return null; ItemMeta meta = item.getItemMeta(); - if (!meta.hasLore()) return null; + if (!P.useNBT && !meta.hasLore()) return null; Brew brew = load(meta); @@ -104,7 +102,16 @@ public class Brew { // Load Legacy and convert brew = getFromPotionEffect(((PotionMeta) meta), true); if (brew == null) return null; - new BrewLore(brew, ((PotionMeta) meta)).removeLegacySpacing(); + new BrewLore(brew, (PotionMeta) meta).removeLegacySpacing(); + brew.save(meta); + item.setItemMeta(meta); + } else if (brew != null && brew.needsSave) { + // Brew needs saving from a previous format + P.p.debugLog("Brew needs saving from previous format"); + if (P.useNBT) { + new BrewLore(brew, (PotionMeta) meta).removeLoreData(); + P.p.debugLog("removed Data from Lore"); + } brew.save(meta); item.setItemMeta(meta); } @@ -434,6 +441,14 @@ public class Brew { return unlabeled; } + public boolean needsSave() { + return needsSave; + } + + public void setNeedsSave(boolean needsSave) { + this.needsSave = needsSave; + } + // Set the Static flag, so potion is unchangeable public void setStatic(boolean immutable, ItemStack potion) { this.immutable = immutable; @@ -660,14 +675,25 @@ public class Brew { } private static Brew load(ItemMeta meta) { - LoreLoadStream loreStream; - try { - loreStream = new LoreLoadStream(meta, 0); - } catch (IllegalArgumentException ignored) { - // No Brew data found in Meta - return null; + InputStream itemLoadStream = null; + if (P.useNBT) { + // Try loading the Item Data from PersistentDataContainer + NBTLoadStream nbtStream = new NBTLoadStream(meta); + if (nbtStream.hasData()) { + itemLoadStream = nbtStream; + } } - XORUnscrambleStream unscrambler = new XORUnscrambleStream(new Base91DecoderStream(loreStream), saveSeed, prevSaveSeeds); + if (itemLoadStream == null) { + // If either NBT is not supported or no data was found in NBT, try loading from Lore + try { + itemLoadStream = new Base91DecoderStream(new LoreLoadStream(meta, 0)); + } catch (IllegalArgumentException ignored) { + // No Brew data found in Meta + return null; + } + } + + XORUnscrambleStream unscrambler = new XORUnscrambleStream(itemLoadStream, saveSeed, prevSaveSeeds); try (DataInputStream in = new DataInputStream(unscrambler)) { boolean parityFailed = false; if (in.readByte() != 86) { @@ -678,8 +704,10 @@ public class Brew { byte ver = in.readByte(); switch (ver) { case 1: + unscrambler.start(); brew.loadFromStream(in); + break; default: if (parityFailed) { @@ -689,6 +717,18 @@ public class Brew { } return null; } + + XORUnscrambleStream.SuccessType successType = unscrambler.getSuccessType(); + if (successType == XORUnscrambleStream.SuccessType.PREV_SEED) { + brew.setNeedsSave(true); + } else if (BConfig.enableEncode != (successType == XORUnscrambleStream.SuccessType.MAIN_SEED)) { + // We have either enabled encode and the data was not encoded or the other way round + brew.setNeedsSave(true); + } else if (P.useNBT && itemLoadStream instanceof Base91DecoderStream) { + // We are on a version that supports nbt but the data is still in the lore of the item + // Just save it again so that it gets saved to nbt + brew.setNeedsSave(true); + } return brew; } catch (IOException e) { P.p.errorLog("IO Error while loading Brew"); @@ -723,9 +763,15 @@ public class Brew { ingredients = BIngredients.load(in); } - // Save brew data into meta/lore + // Save brew data into meta: lore/nbt public void save(ItemMeta meta) { - XORScrambleStream scrambler = new XORScrambleStream(new Base91EncoderStream(new LoreSaveStream(meta, 0)), saveSeed); + OutputStream itemSaveStream; + if (P.useNBT) { + itemSaveStream = new NBTSaveStream(meta); + } else { + itemSaveStream = new Base91EncoderStream(new LoreSaveStream(meta, 0)); + } + XORScrambleStream scrambler = new XORScrambleStream(itemSaveStream, saveSeed); try (DataOutputStream out = new DataOutputStream(scrambler)) { out.writeByte(86); // Parity/sanity out.writeByte(1); // Version diff --git a/src/com/dre/brewery/P.java b/src/com/dre/brewery/P.java index 2203109..57e5782 100644 --- a/src/com/dre/brewery/P.java +++ b/src/com/dre/brewery/P.java @@ -9,6 +9,7 @@ import com.dre.brewery.integration.IntegrationListener; import com.dre.brewery.integration.LogBlockBarrel; import com.dre.brewery.listeners.*; import com.dre.brewery.utility.BUtil; +import com.dre.brewery.utility.LegacyUtil; import org.apache.commons.lang.math.NumberUtils; import org.bukkit.Bukkit; import org.bukkit.ChatColor; @@ -22,6 +23,7 @@ public class P extends JavaPlugin { public static P p; public static boolean debug; public static boolean useUUID; + public static boolean useNBT; public static boolean use1_9; public static boolean use1_11; public static boolean use1_13; @@ -51,6 +53,13 @@ public class P extends JavaPlugin { use1_13 = !v.matches("(^|.*[^.\\d])1\\.1[0-2]([^\\d].*|$)") && !v.matches("(^|.*[^.\\d])1\\.[0-9]([^\\d].*|$)"); use1_14 = !v.matches("(^|.*[^.\\d])1\\.1[0-3]([^\\d].*|$)") && !v.matches("(^|.*[^.\\d])1\\.[0-9]([^\\d].*|$)"); + //MC 1.13 uses a different NBT API than the newer versions.. + // We decide here which to use, the new or the old or none at all + P.debug = true; + if (LegacyUtil.initNbt()) { + useNBT = true; + } + //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(); diff --git a/src/com/dre/brewery/lore/BrewLore.java b/src/com/dre/brewery/lore/BrewLore.java index 0213911..7891db2 100644 --- a/src/com/dre/brewery/lore/BrewLore.java +++ b/src/com/dre/brewery/lore/BrewLore.java @@ -189,12 +189,24 @@ public class BrewLore { } public void removeLegacySpacing() { + if (P.useNBT) { + // Using NBT we don't get the invisible line, so we keep our spacing + return; + } if (lore.size() > 0 && lore.get(0).equals("")) { lore.remove(0); write(); } } + public void removeLoreData() { + int index = BUtil.indexOfStart(lore, LoreSaveStream.IDENTIFIER); + if (index != -1) { + lore.set(index, ""); + write(); + } + } + // True if the PotionMeta has Lore in quality color public static boolean hasColorLore(PotionMeta meta) { if (!meta.hasLore()) return false; diff --git a/src/com/dre/brewery/lore/LoreLoadStream.java b/src/com/dre/brewery/lore/LoreLoadStream.java index 3d73889..4ad7ab2 100644 --- a/src/com/dre/brewery/lore/LoreLoadStream.java +++ b/src/com/dre/brewery/lore/LoreLoadStream.java @@ -8,6 +8,8 @@ import java.util.List; public class LoreLoadStream extends ByteArrayInputStream { + public static final String IDENTIFIER = "§%"; + public LoreLoadStream(ItemMeta meta) throws IllegalArgumentException { this(meta, -1); } @@ -21,12 +23,12 @@ public class LoreLoadStream extends ByteArrayInputStream { List lore = meta.getLore(); if (lineNum >= 0) { String line = lore.get(lineNum); - if (line.startsWith("§%")) { + if (line.startsWith(IDENTIFIER)) { return loreLineToBytes(line); } } for (String line : lore) { - if (line.startsWith("§%")) { + if (line.startsWith(IDENTIFIER)) { return loreLineToBytes(line); } } diff --git a/src/com/dre/brewery/lore/LoreSaveStream.java b/src/com/dre/brewery/lore/LoreSaveStream.java index a895691..de127d3 100644 --- a/src/com/dre/brewery/lore/LoreSaveStream.java +++ b/src/com/dre/brewery/lore/LoreSaveStream.java @@ -10,6 +10,8 @@ import java.util.List; public class LoreSaveStream extends ByteArrayOutputStream { + public static final String IDENTIFIER = "§%"; + private ItemMeta meta; private int line; private boolean flushed = false; @@ -38,7 +40,7 @@ public class LoreSaveStream extends ByteArrayOutputStream { String s = toString(); StringBuilder loreLineBuilder = new StringBuilder((s.length() * 2) + 6); - loreLineBuilder.append("§%"); + loreLineBuilder.append(IDENTIFIER); for (char c : s.toCharArray()) { loreLineBuilder.append('§').append(c); } @@ -50,7 +52,7 @@ public class LoreSaveStream extends ByteArrayOutputStream { } int prev = 0; for (Iterator iterator = lore.iterator(); iterator.hasNext(); ) { - if (iterator.next().startsWith("§%")) { + if (iterator.next().startsWith(IDENTIFIER)) { iterator.remove(); break; } diff --git a/src/com/dre/brewery/lore/NBTLoadStream.java b/src/com/dre/brewery/lore/NBTLoadStream.java new file mode 100644 index 0000000..36eea63 --- /dev/null +++ b/src/com/dre/brewery/lore/NBTLoadStream.java @@ -0,0 +1,28 @@ +package com.dre.brewery.lore; + +import com.dre.brewery.P; +import com.dre.brewery.utility.LegacyUtil; +import org.bukkit.NamespacedKey; +import org.bukkit.inventory.meta.ItemMeta; + +import java.io.ByteArrayInputStream; + +public class NBTLoadStream extends ByteArrayInputStream { + private static final String TAG = "brewdata"; + + public NBTLoadStream(ItemMeta meta) { + super(getNBTBytes(meta)); + } + + private static byte[] getNBTBytes(ItemMeta meta) { + byte[] bytes = LegacyUtil.readBytesItem(meta, new NamespacedKey(P.p, TAG)); + if (bytes == null) { + return new byte[0]; + } + return bytes; + } + + public boolean hasData() { + return count > 0; + } +} diff --git a/src/com/dre/brewery/lore/NBTSaveStream.java b/src/com/dre/brewery/lore/NBTSaveStream.java new file mode 100644 index 0000000..4cfd5a5 --- /dev/null +++ b/src/com/dre/brewery/lore/NBTSaveStream.java @@ -0,0 +1,26 @@ +package com.dre.brewery.lore; + +import com.dre.brewery.P; +import com.dre.brewery.utility.LegacyUtil; +import org.bukkit.NamespacedKey; +import org.bukkit.inventory.meta.ItemMeta; + +import java.io.ByteArrayOutputStream; +import java.io.IOException; + +public class NBTSaveStream extends ByteArrayOutputStream { + private static final String TAG = "brewdata"; + private final ItemMeta meta; + + public NBTSaveStream(ItemMeta meta) { + super(128); + this.meta = meta; + } + + @Override + public void flush() throws IOException { + super.flush(); + if (size() <= 0) return; + LegacyUtil.writeBytesItem(toByteArray(), meta, new NamespacedKey(P.p, TAG)); + } +} diff --git a/src/com/dre/brewery/lore/XORUnscrambleStream.java b/src/com/dre/brewery/lore/XORUnscrambleStream.java index f409cf3..e418eb1 100644 --- a/src/com/dre/brewery/lore/XORUnscrambleStream.java +++ b/src/com/dre/brewery/lore/XORUnscrambleStream.java @@ -23,6 +23,8 @@ public class XORUnscrambleStream extends FilterInputStream { private boolean markRunning; private boolean markxor; + private SuccessType successType = SuccessType.NONE; + /** * Create a new instance of an XORUnscrambler, unscrambling the given inputstream * @@ -62,19 +64,24 @@ public class XORUnscrambleStream extends FilterInputStream { short id = (short) (in.read() << 8 | in.read()); if (id == 0) { running = false; + successType = SuccessType.UNSCRAMBLED; P.p.debugLog("Unscrambled data"); return; } int parity = in.read(); xorStream = new SeedInputStream(seed ^ id); boolean success = checkParity(parity); - if (success) P.p.debugLog("Using main Seed to unscramble"); + if (success) { + successType = SuccessType.MAIN_SEED; + 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)) { + successType = SuccessType.PREV_SEED; P.p.debugLog("Had to use prevSeed to unscramble"); break; } @@ -118,6 +125,15 @@ public class XORUnscrambleStream extends FilterInputStream { return len; } + /** + * What was used to unscramble the stream, it was already unscrambled, Main Seed, Prev Seed + * + * @return The Type of Seed used to unscramble this, if any + */ + public SuccessType getSuccessType() { + return successType; + } + @SuppressWarnings("ResultOfMethodCallIgnored") @Override public long skip(long n) throws IOException { @@ -163,4 +179,11 @@ public class XORUnscrambleStream extends FilterInputStream { } markRunning = running; } + + public static enum SuccessType { + UNSCRAMBLED, + MAIN_SEED, + PREV_SEED, + NONE; + } } diff --git a/src/com/dre/brewery/utility/LegacyUtil.java b/src/com/dre/brewery/utility/LegacyUtil.java index 37e173b..d981883 100644 --- a/src/com/dre/brewery/utility/LegacyUtil.java +++ b/src/com/dre/brewery/utility/LegacyUtil.java @@ -1,14 +1,11 @@ package com.dre.brewery.utility; import com.dre.brewery.P; -import org.bukkit.Bukkit; -import org.bukkit.Location; -import org.bukkit.Material; -import org.bukkit.TreeSpecies; -import org.bukkit.World; +import org.bukkit.*; import org.bukkit.block.Block; import org.bukkit.block.data.BlockData; import org.bukkit.block.data.Levelled; +import org.bukkit.inventory.meta.ItemMeta; import org.bukkit.material.Cauldron; import org.bukkit.material.MaterialData; import org.bukkit.material.Tree; @@ -30,6 +27,8 @@ public class LegacyUtil { private static Method GET_BLOCK_TYPE_ID_AT; private static Method SET_DATA; + public static boolean NewNbtVer; + static { // <= 1.12.2 methods // These will be rarely used @@ -248,4 +247,48 @@ public class LegacyUtil { } } + /** + * MC 1.13 uses a different NBT API than the newer versions.. + * We decide here which to use, the new or the old + * + * @return true if we can use nbt at all + */ + public static boolean initNbt() { + try { + Class.forName("org.bukkit.persistence.PersistentDataContainer"); + NewNbtVer = true; + P.p.debugLog("Using the NEW nbt api"); + return true; + } catch (ClassNotFoundException e) { + try { + Class.forName("org.bukkit.inventory.meta.tags.CustomItemTagContainer"); + NewNbtVer = false; + P.p.debugLog("Using the OLD nbt api"); + return true; + } catch (ClassNotFoundException ex) { + NewNbtVer = false; + P.p.debugLog("No nbt api found, using Lore Save System"); + return false; + } + } + } + + @SuppressWarnings("deprecation") + public static void writeBytesItem(byte[] bytes, ItemMeta meta, NamespacedKey key) { + if (NewNbtVer) { + meta.getPersistentDataContainer().set(key, org.bukkit.persistence.PersistentDataType.BYTE_ARRAY, bytes); + } else { + meta.getCustomTagContainer().setCustomTag(key, org.bukkit.inventory.meta.tags.ItemTagType.BYTE_ARRAY, bytes); + } + } + + @SuppressWarnings("deprecation") + public static byte[] readBytesItem(ItemMeta meta, NamespacedKey key) { + if (NewNbtVer) { + return meta.getPersistentDataContainer().get(key, org.bukkit.persistence.PersistentDataType.BYTE_ARRAY); + } else { + return meta.getCustomTagContainer().getCustomTag(key, org.bukkit.inventory.meta.tags.ItemTagType.BYTE_ARRAY); + } + } + } From 2d3e5dfbac0b3cdd266ea5a4406a270f9a979571 Mon Sep 17 00:00:00 2001 From: Sn0wStorm Date: Mon, 21 Oct 2019 12:44:26 +0200 Subject: [PATCH 25/51] Implemented Custom Lore --- resources/config/v12/de/config.yml | 21 ++ resources/config/v13/de/config.yml | 82 +++-- resources/config/v13/en/config.yml | 23 ++ src/com/dre/brewery/BIngredients.java | 1 + src/com/dre/brewery/BRecipe.java | 67 ++++ src/com/dre/brewery/Brew.java | 2 + .../brewery/listeners/InventoryListener.java | 2 +- src/com/dre/brewery/lore/BrewLore.java | 327 +++++++++++++++--- src/com/dre/brewery/utility/Tuple.java | 80 +++++ 9 files changed, 534 insertions(+), 71 deletions(-) create mode 100644 src/com/dre/brewery/utility/Tuple.java diff --git a/resources/config/v12/de/config.yml b/resources/config/v12/de/config.yml index ac799da..aa2e05b 100644 --- a/resources/config/v12/de/config.yml +++ b/resources/config/v12/de/config.yml @@ -96,6 +96,8 @@ oldMat: true # Oder RGB Farben (Hex: also zB '99FF33') (Ohne #) (mit '') (Einfach nach "HTML color" im Internet suchen) # difficulty: 1-10 Genauigkeit der Einhaltung der Vorgaben (1 = ungenau/einfach 10 = sehr genau/schwer) # alcohol: Alkoholgehalt 0-100 in absoluter Menge bei perfektem Getränk (wird dem Spieler hinzugefügt, bei 100 = tot) +# lore: Auflistung von zusätzlichem Text auf dem fertigen Trank. (Farbcodes möglich: z.b. &6) +# Lore nur für bestimmte Qualität möglich mit + Schlecht, ++ Mittel, +++ Gut, vorne anhängen. # effects: Auflistung Effekt/Level/Dauer Besonderere Trank-Effekte beim Trinken, Dauer in sek. # Ein 'X' an den Namen anhängen, um ihn zu verbergen. Bsp: 'POISONX/2/10' (WEAKNESS, INCREASE_DAMAGE, SLOW und SPEED sind immer verborgen.) # Effekte sind ab der 1.9 immer verborgen, wegen Änderungen an den Tränken. @@ -124,6 +126,14 @@ recipes: color: DARK_RED difficulty: 3 alcohol: 23 + lore: + - Dies ist ein Beispiel Trank + - ++Ganz normales Beispiel + - Man kann ihn nicht brauen + - Aber dies würde auf dem Trank stehen + - + Riecht eklig + - ++ Riecht ganz ok + - +++ Riecht richtig gut effects: - FIRE_RESISTANCE/20 - HEAL/1 @@ -162,6 +172,8 @@ recipes: color: BLACK difficulty: 2 alcohol: 7 + lore: + - +++ &8Perlt wunderschön 4: name: Scheußlicher Met/Met/&6Goldener Met ingredients: @@ -173,6 +185,8 @@ recipes: color: ORANGE difficulty: 2 alcohol: 9 + lore: + - +++ Hat einen goldenen Schein 5: name: Apfelmet/Süßer Apfelmet/&6Goldensüßer Apfelmet ingredients: @@ -185,6 +199,10 @@ recipes: color: ORANGE difficulty: 4 alcohol: 12 + lore: + - + Ist da wirklich Apfel drin? + - ++ Schmeckt nach süßem Apfel + - +++ Hat eine wunderbare Apfelnote effects: - WATER_BREATHINGX/1-2/150 6: @@ -212,6 +230,8 @@ recipes: color: BRIGHT_GREY difficulty: 4 alcohol: 20 + lore: + - + &8Fast nicht trinkbar effects: - WEAKNESS/15 - POISON/10 @@ -245,6 +265,7 @@ recipes: cookingtime: 2 color: BLACK difficulty: 3 + lore: + &8Bestimmt schon eine Woche alt effects: - REGENERATION/1/2-5 - SPEED/1/30-140 diff --git a/resources/config/v13/de/config.yml b/resources/config/v13/de/config.yml index 681e8fb..f55c7f8 100644 --- a/resources/config/v13/de/config.yml +++ b/resources/config/v13/de/config.yml @@ -92,6 +92,8 @@ version: '1.8' # Oder RGB Farben (Hex: also zB '99FF33') (Ohne #) (mit '') (Einfach nach "HTML color" im Internet suchen) # difficulty: 1-10 Genauigkeit der Einhaltung der Vorgaben (1 = ungenau/einfach 10 = sehr genau/schwer) # alcohol: Alkoholgehalt 0-100 in absoluter Menge bei perfektem Getränk (wird dem Spieler hinzugefügt, bei 100 = tot) +# lore: Auflistung von zusätzlichem Text auf dem fertigen Trank. (Farbcodes möglich: z.b. &6) +# Lore nur für bestimmte Qualität möglich mit + Schlecht, ++ Mittel, +++ Gut, vorne anhängen. # effects: Auflistung Effekt/Level/Dauer Besonderere Trank-Effekte beim Trinken, Dauer in sek. # Mögliche Effekte: https://hub.spigotmc.org/javadocs/spigot/org/bukkit/potion/PotionEffectType.html # Minimale und Maximale Level/Dauer können durch "-" festgelegt werden, Bsp: 'SPEED/1-2/30-40' = Level 1 und 30 sek minimal, Level 2 und 40 sek maximal @@ -103,11 +105,11 @@ recipes: 0: name: Schlechtes Beispiel/Beispiel/Gutes Beispiel ingredients: - - Sugar_Cane/5 - - Diamond/1 - - Cocoa_Beans/20 - - Spruce_Planks/8 - - Bedrock/1 + - Sugar_Cane/5 + - Diamond/1 + - Cocoa_Beans/20 + - Spruce_Planks/8 + - Bedrock/1 cookingtime: 3 distillruns: 2 distilltime: 60 @@ -116,15 +118,22 @@ recipes: color: DARK_RED difficulty: 3 alcohol: 23 + lore: + - Dies ist ein Beispiel Trank + - ++Ganz normales Beispiel + - Dies würde auf dem Trank stehen + - + Riecht eklig + - ++ Riecht ganz ok + - +++ Riecht richtig gut effects: - - FIRE_RESISTANCE/20 - - HEAL/1 - - WEAKNESS/2-3/50-60 - - POISON/1-0/20-0 + - FIRE_RESISTANCE/20 + - HEAL/1 + - WEAKNESS/2-3/50-60 + - POISON/1-0/20-0 1: name: Ranziges Weißbier/Weißbier/Feines Weißbier ingredients: - - Wheat/3 + - Wheat/3 cookingtime: 8 distillruns: 0 wood: 1 @@ -135,18 +144,20 @@ recipes: 2: name: Ranziges Bier/Bier/Feines Bier ingredients: - - Wheat/6 + - Wheat/6 cookingtime: 8 distillruns: 0 wood: 0 age: 3 color: ORANGE difficulty: 1 + lore: + - +++ &8Perlt wunderschön alcohol: 6 3: name: Ranziges Dunkelbier/Dunkelbier/Feines Dunkelbier ingredients: - - Wheat/6 + - Wheat/6 cookingtime: 8 distillruns: 0 wood: 4 @@ -157,7 +168,7 @@ recipes: 4: name: Scheußlicher Met/Met/&6Goldener Met ingredients: - - Sugar_Cane/6 + - Sugar_Cane/6 cookingtime: 3 distillruns: 0 wood: 2 @@ -165,11 +176,13 @@ recipes: color: ORANGE difficulty: 2 alcohol: 9 + lore: + - +++ Hat einen goldenen Schein 5: name: Apfelmet/Süßer Apfelmet/&6Goldensüßer Apfelmet ingredients: - - Sugar_Cane/6 - - Apple/2 + - Sugar_Cane/6 + - Apple/2 cookingtime: 4 distillruns: 0 wood: 2 @@ -177,12 +190,16 @@ recipes: color: ORANGE difficulty: 4 alcohol: 12 + lore: + - + Ist da wirklich Apfel drin? + - ++ Schmeckt nach süßem Apfel + - +++ Hat eine wunderbare Apfelnote effects: - - WATER_BREATHING/1-2/150 + - WATER_BREATHING/1-2/150 6: name: Bitterer Rum/Würziger Rum/&6Goldener Rum ingredients: - - Sugar_Cane/14 + - Sugar_Cane/14 cookingtime: 5 distillruns: 2 distilltime: 30 @@ -192,25 +209,27 @@ recipes: difficulty: 6 alcohol: 30 effects: - - FIRE_RESISTANCE/1/20-100 - - POISON/1-0/30-0 + - FIRE_RESISTANCE/1/20-100 + - POISON/1-0/30-0 7: name: Abgeranzter Vodka/Vodka/Russischer Vodka ingredients: - - Potato/10 + - Potato/10 cookingtime: 15 distillruns: 3 age: 0 color: BRIGHT_GREY difficulty: 4 alcohol: 20 + lore: + - + &8Fast nicht trinkbar effects: - - WEAKNESS/15 - - POISON/10 + - WEAKNESS/15 + - POISON/10 8: name: minderwertiger Absinth/Absinth/Starker Absinth ingredients: - - Grass/15 + - Grass/15 cookingtime: 3 distillruns: 6 distilltime: 80 @@ -218,28 +237,29 @@ recipes: difficulty: 8 alcohol: 45 effects: - - POISON/20-30 + - POISON/20-30 9: name: Kartoffelsuppe ingredients: - - Potato/5 - - Grass/3 + - Potato/5 + - Grass/3 cookingtime: 3 color: PINK difficulty: 1 effects: - - HEAL/0-1 + - HEAL/0-1 10: name: Fader Kaffee/Kaffee/Starker Kaffee ingredients: - - Cocoa_Beans/12 - - Milk_Bucket/2 + - Cocoa_Beans/12 + - Milk_Bucket/2 cookingtime: 2 color: BLACK difficulty: 3 + lore: + &8Bestimmt schon eine Woche alt effects: - - REGENERATION/1/2-5 - - SPEED/1/30-140 + - REGENERATION/1/2-5 + - SPEED/1/30-140 # Mehr Ideen für Rezepte: Cachaca, Gin, Whiskey, Tequila, Cidre, etc, sowie Rezeptvarianten wie Goldener Vodka etc. # Ich werde keine weiteren Rezepte zu dieser Standardconfig hinzufügen, da diese öffentlich und für Spieler zum Abschauen einsehbar wären diff --git a/resources/config/v13/en/config.yml b/resources/config/v13/en/config.yml index 376d920..2829bf9 100644 --- a/resources/config/v13/en/config.yml +++ b/resources/config/v13/en/config.yml @@ -93,6 +93,10 @@ version: '1.8' # Or RGB colors (hex: for example '99FF33') (with '') (search for "HTML color" on the internet) # difficulty: 1-10 accuracy needed to get good quality (1 = unaccurate/easy, 10 = very precise/hard) # alcohol: Absolute amount of alcohol 0-100 in a perfect potion (will be added directly to the player, where 100 means fainting) +# lore: List of additional text on the finished brew. (Formatting codes possible: such as &6) +# Specific lore for quality possible, using + bad, ++ normal, ++ good, added to the front of the line. +# lore: Auflistung von zusätzlichem Text auf dem fertigen Trank. (Farbcodes möglich: z.b. &6) +# Lore nur für bestimmte Qualität möglich mit + Schlecht, ++ Mittel, +++ Gut, vorne anhängen. # effects: List of effect/level/duration Special potion-effect when drinking, duration in sek. # Possible Effects: https://hub.spigotmc.org/javadocs/spigot/org/bukkit/potion/PotionEffectType.html # Level or Duration ranges may be specified with a "-", ex. 'SPEED/1-2/30-40' = lvl 1 and 30 sec at worst and lvl 2 and 40 sec at best @@ -117,6 +121,13 @@ recipes: color: DARK_RED difficulty: 3 alcohol: 23 + lore: + - This is an examble brew + - ++Just a normal Example + - This text would be on the brew + - + Smells disgusting + - ++ Smells alright + - +++ Smells really good effects: - FIRE_RESISTANCE/20 - HEAL/1 @@ -143,6 +154,8 @@ recipes: age: 3 color: ORANGE difficulty: 1 + lore: + - +++ &8Crisp taste alcohol: 6 3: name: Skunky Darkbeer/Darkbeer/Fine Darkbeer @@ -154,6 +167,8 @@ recipes: age: 8 color: BLACK difficulty: 2 + lore: + - +++ &8Roasted taste alcohol: 7 4: name: Awkward Mead/Mead/&6Golden Mead @@ -165,6 +180,8 @@ recipes: age: 4 color: ORANGE difficulty: 2 + lore: + - +++ Has a golden shine alcohol: 9 5: name: Apple Mead/Sweet Apple Mead/&6Sweet Golden Apple Mead @@ -178,6 +195,10 @@ recipes: color: ORANGE difficulty: 4 alcohol: 12 + lore: + - +Is there any Apple in this? + - ++Refreshing taste of Apple + - +++Sweetest hint of Apple effects: - WATER_BREATHING/1-2/150 6: @@ -205,6 +226,7 @@ recipes: color: BRIGHT_GREY difficulty: 4 alcohol: 20 + lore: +&8Almost undrinkable effects: - WEAKNESS/15 - POISON/10 @@ -238,6 +260,7 @@ recipes: cookingtime: 2 color: BLACK difficulty: 3 + lore: + &8Probably a week old effects: - REGENERATION/1/2-5 - SPEED/1/30-140 diff --git a/src/com/dre/brewery/BIngredients.java b/src/com/dre/brewery/BIngredients.java index fc44e07..9dbffed 100644 --- a/src/com/dre/brewery/BIngredients.java +++ b/src/com/dre/brewery/BIngredients.java @@ -93,6 +93,7 @@ public class BIngredients { P.p.debugLog("cooked potion has Quality: " + quality); brew = new Brew(quality, cookRecipe, this); BrewLore lore = new BrewLore(brew, potionMeta); + lore.updateCustomLore(); lore.addOrReplaceEffects(brew.getEffects(), brew.getQuality()); cookedName = cookRecipe.getName(quality); diff --git a/src/com/dre/brewery/BRecipe.java b/src/com/dre/brewery/BRecipe.java index 4263f78..6ce49e9 100644 --- a/src/com/dre/brewery/BRecipe.java +++ b/src/com/dre/brewery/BRecipe.java @@ -2,9 +2,13 @@ package com.dre.brewery; import com.dre.brewery.filedata.BConfig; import com.dre.brewery.utility.PotionColor; +import com.dre.brewery.utility.Tuple; import org.bukkit.Material; import org.bukkit.configuration.ConfigurationSection; +import org.bukkit.craftbukkit.libs.jline.internal.Nullable; import org.bukkit.inventory.ItemStack; +import org.jetbrains.annotations.Contract; +import org.jetbrains.annotations.NotNull; import java.util.ArrayList; import java.util.List; @@ -21,6 +25,7 @@ public class BRecipe { private String color; // color of the destilled/finished potion private int difficulty; // difficulty to brew the potion, how exact the instruction has to be followed private int alcohol; // Alcohol in perfect potion + private List> lore; // Custom Lore on the Potion. The int is for Quality Lore, 0 = any, 1,2,3 = Bad,Middle,Good private ArrayList effects = new ArrayList<>(); // Special Effects when drinking public BRecipe(ConfigurationSection configSectionRecipes, String recipeId) { @@ -103,6 +108,38 @@ public class BRecipe { this.difficulty = configSectionRecipes.getInt(recipeId + ".difficulty", 0); this.alcohol = configSectionRecipes.getInt(recipeId + ".alcohol", 0); + List load = null; + if (configSectionRecipes.isString(recipeId + ".lore")) { + load = new ArrayList<>(1); + load.add(configSectionRecipes.getString(recipeId + ".lore")); + } else if (configSectionRecipes.isList(recipeId + ".lore")) { + load = configSectionRecipes.getStringList(recipeId + ".lore"); + } + if (load != null) { + for (String line : load) { + line = P.p.color(line); + int plus = 0; + if (line.startsWith("+++")) { + plus = 3; + line = line.substring(3); + } else if (line.startsWith("++")) { + plus = 2; + line = line.substring(2); + } else if (line.startsWith("+")) { + plus = 1; + line = line.substring(1); + } + if (line.startsWith(" ")) { + line = line.substring(1); + } + if (!line.startsWith("§")) { + line = "§9" + line; + } + if (lore == null) lore = new ArrayList<>(); + lore.add(new Tuple<>(plus, line)); + } + } + List effectStringList = configSectionRecipes.getStringList(recipeId + ".effects"); if (effectStringList != null) { for (String effectString : effectStringList) { @@ -333,6 +370,7 @@ public class BRecipe { return distillTime; } + @NotNull public String getColor() { if (color != null) { return color.toUpperCase(); @@ -357,6 +395,35 @@ public class BRecipe { return alcohol; } + public boolean hasLore() { + return lore != null && !lore.isEmpty(); + } + + @Nullable + public List> getLore() { + return lore; + } + + @Nullable + public List getLoreForQuality(int quality) { + if (lore == null) return null; + int plus; + if (quality <= 3) { + plus = 1; + } else if (quality <= 7) { + plus = 2; + } else { + plus = 3; + } + List list = new ArrayList<>(lore.size()); + for (Tuple line : lore) { + if (line.first() == 0 || line.first() == plus) { + list.add(line.second()); + } + } + return list; + } + public ArrayList getEffects() { return effects; } diff --git a/src/com/dre/brewery/Brew.java b/src/com/dre/brewery/Brew.java index 32e9189..036374f 100644 --- a/src/com/dre/brewery/Brew.java +++ b/src/com/dre/brewery/Brew.java @@ -490,6 +490,7 @@ public class Brew { currentRecipe = recipe; quality = calcQuality(); + lore.updateCustomLore(); lore.addOrReplaceEffects(getEffects(), quality); potionMeta.setDisplayName(P.p.color("&f" + recipe.getName(quality))); PotionColor.fromString(recipe.getColor()).colorBrew(potionMeta, slotItem, canDistill()); @@ -559,6 +560,7 @@ public class Brew { currentRecipe = recipe; quality = calcQuality(); + lore.updateCustomLore(); lore.addOrReplaceEffects(getEffects(), quality); potionMeta.setDisplayName(P.p.color("&f" + recipe.getName(quality))); PotionColor.fromString(recipe.getColor()).colorBrew(potionMeta, item, canDistill()); diff --git a/src/com/dre/brewery/listeners/InventoryListener.java b/src/com/dre/brewery/listeners/InventoryListener.java index bcc53b0..57a3023 100644 --- a/src/com/dre/brewery/listeners/InventoryListener.java +++ b/src/com/dre/brewery/listeners/InventoryListener.java @@ -117,7 +117,7 @@ public class InventoryListener implements Listener { Brew brew = Brew.get(item); if (brew != null) { P.p.log(brew.toString()); - P.p.log(potion.getLore().get(0).replaceAll("§", "")); + //P.p.log(potion.getLore().get(0).replaceAll("§", "")); //P.p.log("similar to beispiel? " + BRecipe.get("Beispiel").createBrew(10).isSimilar(brew)); brew.touch(); diff --git a/src/com/dre/brewery/lore/BrewLore.java b/src/com/dre/brewery/lore/BrewLore.java index 7891db2..23819ea 100644 --- a/src/com/dre/brewery/lore/BrewLore.java +++ b/src/com/dre/brewery/lore/BrewLore.java @@ -5,21 +5,16 @@ import com.dre.brewery.utility.BUtil; import org.bukkit.inventory.meta.PotionMeta; import org.bukkit.potion.PotionEffect; import org.bukkit.potion.PotionEffectType; +import org.jetbrains.annotations.Nullable; import java.util.ArrayList; import java.util.List; public class BrewLore { - - private static final String INGR = "§v"; - private static final String COOK = "§w"; - private static final String DISTILL = "§x"; - private static final String AGE = "§y"; - private static final String WOOD = "§z"; - private Brew brew; private PotionMeta meta; private List lore; + private boolean lineAddedOrRem = false; public BrewLore(Brew brew, PotionMeta meta) { this.brew = brew; @@ -31,21 +26,79 @@ public class BrewLore { } } - // Write the new lore into the Meta + /** + * Write the new lore into the Meta + * Should be called at the end of operation on this Brew Lore + */ public PotionMeta write() { + if (lineAddedOrRem) { + updateSpacer(); + } meta.setLore(lore); return meta; } - public void updateIngredientLore(boolean qualityColor) { - if (qualityColor && brew.hasRecipe()) { - String prefix = getQualityColor(brew.getIngredients().getIngredientQuality(brew.getCurrentRecipe())); - addOrReplaceLore(INGR, prefix, P.p.languageReader.get("Brew_Ingredients")); - } else { - removeLore(INGR, P.p.languageReader.get("Brew_Ingredients")); + /** + * adds or removes an empty line in lore to space out the text a bit + */ + public void updateSpacer() { + boolean hasCustom = false; + boolean hasSpace = false; + for (int i = 0; i < lore.size(); i++) { + Type t = Type.get(lore.get(i)); + if (t == Type.CUSTOM) { + hasCustom = true; + } else if (t == Type.SPACE) { + hasSpace = true; + } else if (t != null && t.isAfter(Type.SPACE)) { + if (hasSpace) return; + + if (hasCustom || P.useNBT) { + // We want to add the spacer if we have Custom Lore, to have a space between custom and brew lore. + // Also add a space if there is no Custom Lore but we don't already have a invisible data line + lore.add(i, Type.SPACE.id); + } + return; + } + } + if (hasSpace) { + // There was a space but nothing after the space + removeLore(Type.SPACE); } } + /*private void addSpacer() { + if (!P.useNBT) return; + + for (int i = 0; i < lore.size(); i++) { + if (Type.get(lore.get(i)) != null) { + if (i == 0 || !lore.get(i - 1).equals("")) { + lore.add(i, ""); + } + break; + } + } + }*/ + + /** + * updates the IngredientLore + * + * @param qualityColor If the lore should have colors according to quality + */ + public void updateIngredientLore(boolean qualityColor) { + if (qualityColor && brew.hasRecipe()) { + String prefix = getQualityColor(brew.getIngredients().getIngredientQuality(brew.getCurrentRecipe())); + addOrReplaceLore(Type.INGR, prefix, P.p.languageReader.get("Brew_Ingredients")); + } else { + removeLore(Type.INGR, P.p.languageReader.get("Brew_Ingredients")); + } + } + + /** + * updates the CookLore + * + * @param qualityColor If the lore should have colors according to quality + */ public void updateCookLore(boolean qualityColor) { if (qualityColor && brew.hasRecipe() && brew.getDistillRuns() > 0 == brew.getCurrentRecipe().needsDistilling()) { BIngredients ingredients = brew.getIngredients(); @@ -54,13 +107,17 @@ public class BrewLore { if (ingredients.getCookedTime() > 1) { prefix = prefix + P.p.languageReader.get("Brew_MinutePluralPostfix"); } - addOrReplaceLore(COOK, prefix, " " + P.p.languageReader.get("Brew_fermented")); + addOrReplaceLore(Type.COOK, prefix, " " + P.p.languageReader.get("Brew_fermented")); } else { - removeLore(COOK, P.p.languageReader.get("Brew_fermented")); + removeLore(Type.COOK, P.p.languageReader.get("Brew_fermented")); } } - // sets the DistillLore. Prefix is the color to be used + /** + * updates the DistillLore + * + * @param qualityColor If the lore should have colors according to quality + */ public void updateDistillLore(boolean qualityColor) { if (brew.getDistillRuns() <= 0) return; String prefix; @@ -75,10 +132,14 @@ public class BrewLore { prefix = prefix + distillRuns + P.p.languageReader.get("Brew_-times") + " "; } } - addOrReplaceLore(DISTILL, prefix, P.p.languageReader.get("Brew_Distilled")); + addOrReplaceLore(Type.DISTILL, prefix, P.p.languageReader.get("Brew_Distilled")); } - // sets the AgeLore. Prefix is the color to be used + /** + * updates the AgeLore + * + * @param qualityColor If the lore should have colors according to quality + */ public void updateAgeLore(boolean qualityColor) { String prefix; float age = brew.getAgeTime(); @@ -96,25 +157,64 @@ public class BrewLore { prefix = prefix + P.p.languageReader.get("Brew_HundredsOfYears") + " "; } } - addOrReplaceLore(AGE, prefix, P.p.languageReader.get("Brew_BarrelRiped")); + addOrReplaceLore(Type.AGE, prefix, P.p.languageReader.get("Brew_BarrelRiped")); } - // updates/sets the color on WoodLore + /** + * updates the WoodLore + * + * @param qualityColor If the lore should have colors according to quality + */ public void updateWoodLore(boolean qualityColor) { if (qualityColor && brew.hasRecipe()) { int quality = brew.getIngredients().getWoodQuality(brew.getCurrentRecipe(), brew.getWood()); - addOrReplaceLore(WOOD, getQualityColor(quality), P.p.languageReader.get("Brew_Woodtype")); + addOrReplaceLore(Type.WOOD, getQualityColor(quality), P.p.languageReader.get("Brew_Woodtype")); } else { - removeLore(WOOD, P.p.languageReader.get("Brew_Woodtype")); + removeLore(Type.WOOD, P.p.languageReader.get("Brew_Woodtype")); } } - // Converts to/from qualitycolored Lore + /** + * updates the Custom Lore + */ + public void updateCustomLore() { + int index = Type.CUSTOM.findInLore(lore); + + while (index > -1) { + lore.remove(index); + index = Type.CUSTOM.findInLore(lore); + } + + BRecipe recipe = brew.getCurrentRecipe(); + if (recipe != null && recipe.hasLore()) { + index = -1; + for (String line : recipe.getLoreForQuality(brew.getQuality())) { + if (index == -1) { + index = addLore(Type.CUSTOM, "", line); + index++; + } else { + lore.add(index, Type.CUSTOM.id + line); + index++; + } + } + + /*if (index < lore.size()) { + // If there are more lines after this, add a spacer + lore.add(index, Type.SPACE.id); + }*/ + } + } + + /** + * Converts to/from qualitycolored Lore + */ public void convertLore(boolean toQuality) { if (!brew.hasRecipe()) { return; } + updateCustomLore(); + if (!brew.isUnlabeled()) { // Ingredients updateIngredientLore(toQuality); @@ -139,33 +239,87 @@ public class BrewLore { } } - // Adds or replaces a line of Lore. - // Searches for type and if not found for Substring lore and replaces it - public void addOrReplaceLore(String type, String prefix, String line) { - int index = BUtil.indexOfStart(lore, type); + /** + * Adds or replaces a line of Lore. + * Searches for type and if not found for Substring lore and replaces it + * + * @param type The Type of BrewLore to replace + * @param prefix The Prefix to add to the line of lore + * @param line The Line of Lore to add or replace + */ + public int addOrReplaceLore(Type type, String prefix, String line) { + int index = type.findInLore(lore); if (index == -1) { index = BUtil.indexOfSubstring(lore, line); } if (index > -1) { - lore.set(index, type + prefix + line); + lore.set(index, type.id + prefix + line); + return index; } else { - lore.add(type + prefix + line); + return addLore(type, prefix, line); } } - // Adds or replaces a line of Lore. - // Searches for type and if not found for Substring lore and replaces it - public void removeLore(String type, String line) { - int index = BUtil.indexOfStart(lore, type); + /** + * Adds a line of Lore in the correct ordering + * + * @param type The Type of BrewLore to add + * @param prefix The Prefix to add to the line of lore + * @param line The Line of Lore to add or add + */ + public int addLore(Type type, String prefix, String line) { + lineAddedOrRem = true; + for (int i = 0; i < lore.size(); i++) { + Type existing = Type.get(lore.get(i)); + if (existing != null && existing.isAfter(type)) { + lore.add(i, type.id + prefix + line); + return i; + } + } + lore.add(type.id + prefix + line); + return lore.size() - 1; + } + + /** + * Searches for type and if not found for Substring lore and removes it + */ + public void removeLore(Type type, String line) { + int index = type.findInLore(lore); if (index == -1) { index = BUtil.indexOfSubstring(lore, line); } if (index > -1) { + lineAddedOrRem = true; lore.remove(index); } } - // Adds the Effect names to the Items description + /** + * Searches for type and removes it + */ + public void removeLore(Type type) { + int index = type.findInLore(lore); + if (index > -1) { + lineAddedOrRem = true; + lore.remove(index); + } + } + + /** + * Removes all Brew Lore lines + */ + public void removeAll() { + for (Type t : Type.values()) { + int index = t.findInLore(lore); + if (index > -1) { + lore.remove(index); + } + } + } + + /** + * Adds the Effect names to the Items description + */ public void addOrReplaceEffects(ArrayList effects, int quality) { if (!P.use1_9 && effects != null) { for (BEffect effect : effects) { @@ -176,7 +330,19 @@ public class BrewLore { } } - // Removes all effects + /** + * If the Lore Line at index is a Brew Lore line + * + * @param index the index in lore to check + * @return true if the line at index is of any Brew Lore type + */ + public boolean isBrewLore(int index) { + return index < lore.size() && Type.get(lore.get(index)) != null; + } + + /** + * Removes all effects + */ public void removeEffects() { if (meta.hasCustomEffects()) { for (PotionEffect effect : new ArrayList<>(meta.getCustomEffects())) { @@ -188,6 +354,9 @@ public class BrewLore { } } + /** + * Remove the Old Spacer from the legacy potion data system + */ public void removeLegacySpacing() { if (P.useNBT) { // Using NBT we don't get the invisible line, so we keep our spacing @@ -199,6 +368,9 @@ public class BrewLore { } } + /** + * Remove any Brew Data from Lore + */ public void removeLoreData() { int index = BUtil.indexOfStart(lore, LoreSaveStream.IDENTIFIER); if (index != -1) { @@ -207,14 +379,16 @@ public class BrewLore { } } - // True if the PotionMeta has Lore in quality color + /** + * True if the PotionMeta has Lore in quality color + */ public static boolean hasColorLore(PotionMeta meta) { if (!meta.hasLore()) return false; List lore = meta.getLore(); if (lore.size() < 2) { return false; } - if (BUtil.indexOfStart(lore, INGR) != -1) { + if (Type.INGR.findInLore(lore) != -1) { // Ingredient lore present, must be quality colored return true; } @@ -222,7 +396,12 @@ public class BrewLore { //!meta.getLore().get(1).startsWith("§7"); } - // gets the Color that represents a quality in Lore + /** + * gets the Color that represents a quality in Lore + * + * @param quality The Quality for which to find the color code + * @return Color Code for given Quality + */ public static String getQualityColor(int quality) { String color; if (quality > 8) { @@ -238,4 +417,74 @@ public class BrewLore { } return P.p.color(color); } + + public enum Type { + CUSTOM("§t", 0), + SPACE("§u", 1), + + INGR("§v", 2), + COOK("§w", 3), + DISTILL("§x", 4), + AGE("§y", 5), + WOOD("§z", 6); + + public final String id; + public final int ordering; + + /** + * @param id Identifier as Prefix of the Loreline + * @param ordering Ordering of the Brew Lore + */ + Type(String id, int ordering) { + this.id = id; + this.ordering = ordering; + } + + /** + * Find this type in the Lore + * + * @param lore The lore to search in + * @return index of this type in the lore, -1 if not found + */ + public int findInLore(List lore) { + return BUtil.indexOfStart(lore, id); + } + + /** + * Is this type after the other in lore + * + * @param other the other type + * @return true if this type should be after the other type in lore + */ + public boolean isAfter(Type other) { + return other.ordering <= ordering; + } + + /** + * Get the Type of the given line of Lore + */ + @Nullable + public static Type get(String loreLine) { + if (loreLine.length() >= 2) { + loreLine = loreLine.substring(0, 2); + return getById(loreLine); + } else { + return null; + } + } + + /** + * Get the Type of the given Identifier, prefix of a line of lore + */ + @Nullable + public static Type getById(String id) { + for (Type t : values()) { + if (t.id.equals(id)) { + return t; + } + } + return null; + } + + } } diff --git a/src/com/dre/brewery/utility/Tuple.java b/src/com/dre/brewery/utility/Tuple.java new file mode 100644 index 0000000..2d50c92 --- /dev/null +++ b/src/com/dre/brewery/utility/Tuple.java @@ -0,0 +1,80 @@ +/* + * Copyright 2011 Tyler Blair. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ''AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and contributors and should not be interpreted as representing official policies, + * either expressed or implied, of anybody else. + */ +package com.dre.brewery.utility; + +public class Tuple { + + /** + * The first value in the tuple + */ + private final X x; + + /** + * The second value in the tuple + */ + private final Y y; + + public Tuple(X x, Y y) { + this.x = x; + this.y = y; + } + + /** + * Gets the first value in the tuple + * + * @return + */ + public X first() { + return x; + } + + /** + * Gets the second value in the tuple + * + * @return + */ + public Y second() { + return y; + } + + @Override + public boolean equals(Object object) { + if (!(object instanceof Tuple)) { + return false; + } + + Tuple tuple = (Tuple) object; + return tuple.x == x && tuple.y == y; + } + + @Override + public int hashCode() { + return x.hashCode() ^ y.hashCode(); + } + +} From 185f3d9b9b2413335a19def0f9c86ae746db5e0f Mon Sep 17 00:00:00 2001 From: Sn0wStorm Date: Mon, 21 Oct 2019 18:47:19 +0200 Subject: [PATCH 26/51] Find Barrel Blocks by BoundingBox --- src/com/dre/brewery/Barrel.java | 34 ++-- src/com/dre/brewery/BarrelBody.java | 191 +++++------------- src/com/dre/brewery/filedata/BData.java | 34 +++- .../dre/brewery/listeners/PlayerListener.java | 6 +- src/com/dre/brewery/utility/BoundingBox.java | 64 ++++++ 5 files changed, 164 insertions(+), 165 deletions(-) create mode 100644 src/com/dre/brewery/utility/BoundingBox.java diff --git a/src/com/dre/brewery/Barrel.java b/src/com/dre/brewery/Barrel.java index f42bb90..0c07086 100644 --- a/src/com/dre/brewery/Barrel.java +++ b/src/com/dre/brewery/Barrel.java @@ -8,6 +8,7 @@ import com.dre.brewery.filedata.BConfig; import com.dre.brewery.integration.LogBlockBarrel; import com.dre.brewery.lore.BrewLore; import com.dre.brewery.utility.BUtil; +import com.dre.brewery.utility.BoundingBox; import com.dre.brewery.utility.LegacyUtil; import org.bukkit.Location; import org.bukkit.Material; @@ -24,6 +25,7 @@ import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.meta.PotionMeta; import org.bukkit.scheduler.BukkitRunnable; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; import java.util.ArrayList; import java.util.List; @@ -52,7 +54,7 @@ public class Barrel implements InventoryHolder { } // load from file - public Barrel(Block spigot, byte sign, String[] st, String[] wo, Map items, float time) { + public Barrel(Block spigot, byte sign, BoundingBox bounds, Map items, float time) { this.spigot = spigot; if (isLarge()) { this.inventory = P.p.getServer().createInventory(this, 27, P.p.languageReader.get("Etc_Barrel")); @@ -68,7 +70,7 @@ public class Barrel implements InventoryHolder { } this.time = time; - body = new BarrelBody(this, sign, st, wo); + body = new BarrelBody(this, sign, bounds); } public static void onUpdate() { @@ -216,15 +218,24 @@ public class Barrel implements InventoryHolder { return body.hasBlock(block); } + /** + * Deprecated, just use hasBlock + */ + @Deprecated public boolean hasWoodBlock(Block block) { - return body.hasWoodBlock(block); + return body.hasBlock(block); } + /** + * Deprecated, just use hasBlock + */ + @Deprecated public boolean hasStairsBlock(Block block) { - return body.hasStairsBlock(block); + return body.hasBlock(block); } // Get the Barrel by Block, null if that block is not part of a barrel + @Nullable public static Barrel get(Block block) { if (block == null) { return null; @@ -232,13 +243,13 @@ public class Barrel implements InventoryHolder { Material type = block.getType(); if (LegacyUtil.isFence(type) || LegacyUtil.isSign(type) ) { return getBySpigot(block); - } else if (LegacyUtil.isWoodPlanks(type) || LegacyUtil.isWoodStairs(type)) { + } else { return getByWood(block); } - return null; } // Get the Barrel by Sign or Spigot (Fastest) + @Nullable public static Barrel getBySpigot(Block sign) { // convert spigot if neccessary Block spigot = BarrelBody.getSpigotOfSign(sign); @@ -263,16 +274,11 @@ public class Barrel implements InventoryHolder { } // Get the barrel by its corpus (Wood Planks, Stairs) + @Nullable public static Barrel getByWood(Block wood) { - if (LegacyUtil.isWoodPlanks(wood.getType())) { + if (LegacyUtil.isWoodPlanks(wood.getType()) || LegacyUtil.isWoodStairs(wood.getType())) { for (Barrel barrel : barrels) { - if (barrel.body.hasWoodBlock(wood)) { - return barrel; - } - } - } else if (LegacyUtil.isWoodStairs(wood.getType())) { - for (Barrel barrel : Barrel.barrels) { - if (barrel.body.hasStairsBlock(wood)) { + if (barrel.getSpigot().getWorld().equals(wood.getWorld()) && barrel.body.getBounds().contains(wood)) { return barrel; } } diff --git a/src/com/dre/brewery/BarrelBody.java b/src/com/dre/brewery/BarrelBody.java index c1cb350..88795a9 100644 --- a/src/com/dre/brewery/BarrelBody.java +++ b/src/com/dre/brewery/BarrelBody.java @@ -1,57 +1,43 @@ package com.dre.brewery; import com.dre.brewery.utility.BUtil; +import com.dre.brewery.utility.BoundingBox; import com.dre.brewery.utility.LegacyUtil; -import org.apache.commons.lang.ArrayUtils; import org.bukkit.Material; import org.bukkit.block.Block; import org.bukkit.configuration.ConfigurationSection; +import org.jetbrains.annotations.NotNull; -import java.util.ArrayList; +import java.util.Objects; // The Blocks that make up a Barrel in the World public class BarrelBody { private final Barrel barrel; private final Block spigot; - private int[] woodsloc = null; // location of wood Blocks - private int[] stairsloc = null; // location of stair Blocks + private BoundingBox bounds; private byte signoffset; public BarrelBody(Barrel barrel, byte signoffset) { this.barrel = barrel; this.signoffset = signoffset; spigot = barrel.getSpigot(); + this.bounds = new BoundingBox(0, 0, 0, 0, 0, 0); } // Loading from file - public BarrelBody(Barrel barrel, byte signoffset, String[] st, String[] wo) { + public BarrelBody(Barrel barrel, byte signoffset, BoundingBox bounds) { this(barrel, signoffset); - int i = 0; - if (wo.length > 1) { - woodsloc = new int[wo.length]; - for (String wos : wo) { - woodsloc[i] = P.p.parseInt(wos); - i++; - } - i = 0; - } - if (st.length > 1) { - stairsloc = new int[st.length]; - for (String sts : st) { - stairsloc[i] = P.p.parseInt(sts); - i++; - } - } - - if (woodsloc == null && stairsloc == null) { - // If loading from old data, or block locations are missing, regenerate them + if (bounds == null || bounds.area() > 64 ) { + // If loading from old data, or block locations are missing, or other error, regenerate BoundingBox // This will only be done in those extreme cases. Block broken = getBrokenBlock(true); if (broken != null) { barrel.remove(broken, null); } + } else { + this.bounds = bounds; } } @@ -63,20 +49,14 @@ public class BarrelBody { return spigot; } - public int[] getWoodsloc() { - return woodsloc; + @NotNull + public BoundingBox getBounds() { + return bounds; } - public void setWoodsloc(int[] woodsloc) { - this.woodsloc = woodsloc; - } - - public int[] getStairsloc() { - return stairsloc; - } - - public void setStairsloc(int[] stairsloc) { - this.stairsloc = stairsloc; + public void setBounds(@NotNull BoundingBox bounds) { + Objects.requireNonNull(bounds); + this.bounds = bounds; } public byte getSignoffset() { @@ -162,57 +142,16 @@ public class BarrelBody { } } - // Returns true if this Block is part of this Barrel + /** + * Returns true if this Block is part of this Barrel + * + * @param block the block to check + * @return true if the given block is part of this Barrel + */ public boolean hasBlock(Block block) { if (block != null) { - if (LegacyUtil.isWoodPlanks(block.getType())) { - return hasWoodBlock(block); - } else if (LegacyUtil.isWoodStairs(block.getType())) { - return hasStairsBlock(block); - } - } - return false; - } - - public boolean hasWoodBlock(Block block) { - if (woodsloc != null) { - if (spigot.getWorld() != null && spigot.getWorld().equals(block.getWorld())) { - if (woodsloc.length > 2) { - int x = block.getX(); - if (Math.abs(x - woodsloc[0]) < 10) { - for (int i = 0; i < woodsloc.length - 2; i += 3) { - if (woodsloc[i] == x) { - if (woodsloc[i + 1] == block.getY()) { - if (woodsloc[i + 2] == block.getZ()) { - return true; - } - } - } - } - } - } - } - } - return false; - } - - public boolean hasStairsBlock(Block block) { - if (stairsloc != null) { - if (spigot.getWorld() != null && spigot.getWorld().equals(block.getWorld())) { - if (stairsloc.length > 2) { - int x = block.getX(); - if (Math.abs(x - stairsloc[0]) < 10) { - for (int i = 0; i < stairsloc.length - 2; i += 3) { - if (stairsloc[i] == x) { - if (stairsloc[i + 1] == block.getY()) { - if (stairsloc[i + 2] == block.getZ()) { - return true; - } - } - } - } - } - } + if (spigot.getWorld().equals(block.getWorld())) { + return bounds != null && bounds.contains(block.getX(), block.getY(), block.getZ()); } } return false; @@ -280,29 +219,21 @@ public class BarrelBody { int endX; int endZ; - ArrayList stairs = new ArrayList<>(); - if (direction == 1) { startX = 1; - endX = startX + 1; startZ = -1; - endZ = 0; } else if (direction == 2) { startX = -2; - endX = startX + 1; startZ = 0; - endZ = 1; } else if (direction == 3) { startX = 0; - endX = 1; startZ = 1; - endZ = startZ + 1; } else { startX = -1; - endX = 0; startZ = -2; - endZ = startZ + 1; } + endX = startX + 1; + endZ = startZ + 1; Material type; int x = startX; @@ -321,9 +252,6 @@ public class BarrelBody { return block; } } - stairs.add(block.getX()); - stairs.add(block.getY()); - stairs.add(block.getZ()); z++; } else { return spigot.getRelative(x, y, z); @@ -336,7 +264,13 @@ public class BarrelBody { x = startX; y++; } - stairsloc = ArrayUtils.toPrimitive(stairs.toArray(new Integer[0])); + bounds = new BoundingBox( + spigot.getX() + startX, + spigot.getY(), + spigot.getZ() + startZ, + spigot.getX() + endX, + spigot.getY() + 1, + spigot.getZ() + endZ); return null; } @@ -350,28 +284,24 @@ public class BarrelBody { int endX; int endZ; - ArrayList stairs = new ArrayList<>(); - ArrayList woods = new ArrayList<>(); - if (direction == 1) { startX = 1; - endX = startX + 3; startZ = -1; - endZ = 1; } else if (direction == 2) { startX = -4; - endX = startX + 3; startZ = -1; - endZ = 1; } else if (direction == 3) { startX = -1; - endX = 1; startZ = 1; - endZ = startZ + 3; } else { startX = -1; - endX = 1; startZ = -4; + } + if (direction == 1 || direction == 2) { + endX = startX + 3; + endZ = startZ + 2; + } else { + endX = startX + 2; endZ = startZ + 3; } @@ -386,35 +316,16 @@ public class BarrelBody { type = block.getType(); if (direction == 1 || direction == 2) { if (y == 1 && z == 0) { - if (x == -1 || x == -4 || x == 1 || x == 4) { - woods.add(block.getX()); - woods.add(block.getY()); - woods.add(block.getZ()); - } z++; continue; } } else { if (y == 1 && x == 0) { - if (z == -1 || z == -4 || z == 1 || z == 4) { - woods.add(block.getX()); - woods.add(block.getY()); - woods.add(block.getZ()); - } z++; continue; } } if (LegacyUtil.isWoodPlanks(type) || LegacyUtil.isWoodStairs(type)) { - if (LegacyUtil.isWoodPlanks(type)) { - woods.add(block.getX()); - woods.add(block.getY()); - woods.add(block.getZ()); - } else { - stairs.add(block.getX()); - stairs.add(block.getY()); - stairs.add(block.getZ()); - } z++; } else { return block; @@ -427,8 +338,13 @@ public class BarrelBody { x = startX; y++; } - stairsloc = ArrayUtils.toPrimitive(stairs.toArray(new Integer[0])); - woodsloc = ArrayUtils.toPrimitive(woods.toArray(new Integer[0])); + bounds = new BoundingBox( + spigot.getX() + startX, + spigot.getY(), + spigot.getZ() + startZ, + spigot.getX() + endX, + spigot.getY() + 2, + spigot.getZ() + endZ); return null; } @@ -437,19 +353,6 @@ public class BarrelBody { if (signoffset != 0) { config.set(prefix + ".sign", signoffset); } - if (stairsloc != null && stairsloc.length > 0) { - StringBuilder st = new StringBuilder(); - for (int i : stairsloc) { - st.append(i).append(","); - } - config.set(prefix + ".st", st.substring(0, st.length() - 1)); - } - if (woodsloc != null && woodsloc.length > 0) { - StringBuilder wo = new StringBuilder(); - for (int i : woodsloc) { - wo.append(i).append(","); - } - config.set(prefix + ".wo", wo.substring(0, wo.length() - 1)); - } + config.set(prefix + ".bounds", bounds.serialize()); } } diff --git a/src/com/dre/brewery/filedata/BData.java b/src/com/dre/brewery/filedata/BData.java index 6d4a29a..96209eb 100644 --- a/src/com/dre/brewery/filedata/BData.java +++ b/src/com/dre/brewery/filedata/BData.java @@ -2,6 +2,8 @@ package com.dre.brewery.filedata; import com.dre.brewery.*; import com.dre.brewery.utility.BUtil; +import com.dre.brewery.utility.BoundingBox; +import org.apache.commons.lang.ArrayUtils; import org.apache.commons.lang.math.NumberUtils; import org.bukkit.Location; import org.bukkit.Material; @@ -14,6 +16,7 @@ import org.bukkit.inventory.ItemStack; import java.io.File; import java.util.ArrayList; +import java.util.Arrays; import java.util.HashMap; import java.util.Map; import java.util.UUID; @@ -209,19 +212,40 @@ public class BData { Block block = world.getBlockAt(P.p.parseInt(splitted[0]), P.p.parseInt(splitted[1]), P.p.parseInt(splitted[2])); float time = (float) section.getDouble(barrel + ".time", 0.0); byte sign = (byte) section.getInt(barrel + ".sign", 0); - String[] st = section.getString(barrel + ".st", "").split(","); - String[] wo = section.getString(barrel + ".wo", "").split(","); + + BoundingBox box = null; + if (section.contains(barrel + ".bounds")) { + String[] bds = section.getString(barrel + ".bounds", "").split(","); + if (bds.length == 6) { + box = new BoundingBox(P.p.parseInt(bds[0]), P.p.parseInt(bds[1]), P.p.parseInt(bds[2]), P.p.parseInt(bds[3]), P.p.parseInt(bds[4]), P.p.parseInt(bds[5])); + } + } else if (section.contains(barrel + ".st")) { + // Convert from Stair and Wood Locations to BoundingBox + String[] st = section.getString(barrel + ".st", "").split(","); + String[] wo = section.getString(barrel + ".wo", "").split(","); + int woLength = wo.length; + if (woLength <= 1) { + woLength = 0; + } + String[] points = new String[st.length + woLength]; + System.arraycopy(st, 0, points, 0, st.length); + if (woLength > 1) { + System.arraycopy(wo, 0, points, st.length, woLength); + } + int[] locs = ArrayUtils.toPrimitive(Arrays.stream(points).map(s -> P.p.parseInt(s)).toArray(Integer[]::new)); + box = BoundingBox.fromPoints(locs); + } Barrel b; if (invSection != null) { - b = new Barrel(block, sign, st, wo, invSection.getValues(true), time); + b = new Barrel(block, sign, box, invSection.getValues(true), time); } else { // Barrel has no inventory - b = new Barrel(block, sign, st, wo, null, time); + b = new Barrel(block, sign, box, null, time); } // In case Barrel Block locations were missing and could not be recreated: do not add the barrel - if (b.getBody().getStairsloc() != null || b.getBody().getWoodsloc() != null) { + if (b.getBody().getBounds() != null) { Barrel.barrels.add(b); } diff --git a/src/com/dre/brewery/listeners/PlayerListener.java b/src/com/dre/brewery/listeners/PlayerListener.java index f30e0fd..70bf2cd 100644 --- a/src/com/dre/brewery/listeners/PlayerListener.java +++ b/src/com/dre/brewery/listeners/PlayerListener.java @@ -49,11 +49,11 @@ public class PlayerListener implements Listener { Barrel barrel = null; if (LegacyUtil.isWoodPlanks(type)) { if (BConfig.openEverywhere) { - barrel = Barrel.get(clickedBlock); + barrel = Barrel.getByWood(clickedBlock); } } else if (LegacyUtil.isWoodStairs(type)) { for (Barrel barrel2 : Barrel.barrels) { - if (barrel2.getBody().hasStairsBlock(clickedBlock)) { + if (barrel2.getBody().hasBlock(clickedBlock)) { if (BConfig.openEverywhere || !barrel2.isLarge()) { barrel = barrel2; } @@ -67,6 +67,8 @@ public class PlayerListener implements Listener { if (barrel != null) { event.setCancelled(true); + P.p.debugLog("Barrel has area of: " + barrel.getBody().getBounds().area()); + if (!barrel.hasPermsOpen(player, event)) { return; } diff --git a/src/com/dre/brewery/utility/BoundingBox.java b/src/com/dre/brewery/utility/BoundingBox.java new file mode 100644 index 0000000..e5fe831 --- /dev/null +++ b/src/com/dre/brewery/utility/BoundingBox.java @@ -0,0 +1,64 @@ +package com.dre.brewery.utility; + +import org.bukkit.Location; +import org.bukkit.block.Block; + +public class BoundingBox { + + private final int x1; + private final int y1; + private final int z1; + private final int x2; + private final int y2; + private final int z2; + + public BoundingBox(int x1, int y1, int z1, int x2, int y2, int z2) { + this.x1 = Math.min(x1, x2); + this.y1 = Math.min(y1, y2); + this.z1 = Math.min(z1, z2); + this.x2 = Math.max(x2, x1); + this.y2 = Math.max(y2, y1); + this.z2 = Math.max(z2, z1); + } + + public boolean contains(int x, int y, int z) { + return (x >= x1 && x <= x2) && (y >= y1 && y <= y2) && (z >= z1 && z <= z2); + } + + public boolean contains(Location loc) { + return contains(loc.getBlockX(), loc.getBlockY(), loc.getBlockZ()); + } + + public boolean contains(Block block) { + return contains(block.getX(), block.getY(), block.getZ()); + } + + public int area() { + return (x2 - x1 + 1) * (y2 - y1 + 1) * (z2 - z1 + 1); + } + + public String serialize() { + return x1 + "," + y1 + "," + z1 + "," + x2 + "," + y2 + "," + z2; + } + + public static BoundingBox fromPoints(int[] locations) { + if (locations.length % 3 != 0) throw new IllegalArgumentException("Locations has to be pairs of three"); + + int length = locations.length / 3; + int minx = Integer.MAX_VALUE, + miny = Integer.MAX_VALUE, + minz = Integer.MAX_VALUE, + maxx = Integer.MIN_VALUE, + maxy = Integer.MIN_VALUE, + maxz = Integer.MIN_VALUE; + for (int i = 0; i < length; i++) { + minx = Math.min(locations[i], minx); + miny = Math.min(locations[i + 1], miny); + minz = Math.min(locations[i + 2], minz); + maxx = Math.max(locations[i], maxx); + maxy = Math.max(locations[i + 1], maxy); + maxz = Math.max(locations[i + 2], maxz); + } + return new BoundingBox(minx, miny, minz, maxx, maxy, maxz); + } +} From 7a6e361a8cd6cebe013168af6c644b2bab2ed42a Mon Sep 17 00:00:00 2001 From: Sn0wStorm Date: Mon, 21 Oct 2019 20:39:31 +0200 Subject: [PATCH 27/51] Show stars in lore according to quality --- src/com/dre/brewery/Brew.java | 3 ++ src/com/dre/brewery/lore/BrewLore.java | 38 +++++++++++++++++++++----- 2 files changed, 34 insertions(+), 7 deletions(-) diff --git a/src/com/dre/brewery/Brew.java b/src/com/dre/brewery/Brew.java index 036374f..b265fd3 100644 --- a/src/com/dre/brewery/Brew.java +++ b/src/com/dre/brewery/Brew.java @@ -374,6 +374,7 @@ public class Brew { if (ageTime >= 1) { lore.updateAgeLore(false); } + lore.updateQualityStars(false); lore.write(); item.setItemMeta(meta); } @@ -507,6 +508,7 @@ public class Brew { if (BConfig.colorInBrewer != BrewLore.hasColorLore(potionMeta)) { lore.convertLore(BConfig.colorInBrewer); } + lore.updateQualityStars(BConfig.colorInBrewer); } lore.updateDistillLore(BConfig.colorInBrewer); lore.write(); @@ -585,6 +587,7 @@ public class Brew { if (BConfig.colorInBarrels && !unlabeled && currentRecipe != null) { lore.updateWoodLore(true); } + lore.updateQualityStars(BConfig.colorInBarrels); } lore.write(); touch(); diff --git a/src/com/dre/brewery/lore/BrewLore.java b/src/com/dre/brewery/lore/BrewLore.java index 23819ea..d9d549c 100644 --- a/src/com/dre/brewery/lore/BrewLore.java +++ b/src/com/dre/brewery/lore/BrewLore.java @@ -205,6 +205,28 @@ public class BrewLore { } } + public void updateQualityStars(boolean qualityColor) { + if (brew.hasRecipe() && brew.getCurrentRecipe().needsToAge() && brew.getAgeTime() < 0.5) { + return; + } + if (!brew.isUnlabeled()) { + int stars = (brew.getQuality() + 1) / 2; + StringBuilder b = new StringBuilder(stars); + for (; stars > 0; stars--) { + b.append("⭑"); + } + String color; + if (qualityColor) { + color = getQualityColor(brew.getQuality()); + } else { + color = brew.getQuality() >= 10 ? "§6" : "§8"; + } + addOrReplaceLore(Type.STARS, color, b.toString()); + } else { + removeLore(Type.STARS); + } + } + /** * Converts to/from qualitycolored Lore */ @@ -214,6 +236,7 @@ public class BrewLore { } updateCustomLore(); + updateQualityStars(toQuality); if (!brew.isUnlabeled()) { // Ingredients @@ -419,14 +442,15 @@ public class BrewLore { } public enum Type { - CUSTOM("§t", 0), - SPACE("§u", 1), + STARS("§s", 0), + CUSTOM("§t", 1), + SPACE("§u", 2), - INGR("§v", 2), - COOK("§w", 3), - DISTILL("§x", 4), - AGE("§y", 5), - WOOD("§z", 6); + INGR("§v", 3), + COOK("§w", 4), + DISTILL("§x", 5), + AGE("§y", 6), + WOOD("§z", 7); public final String id; public final int ordering; From 92977d2c8e3b630da6645eb542a5554f85c7d666 Mon Sep 17 00:00:00 2001 From: Sn0wStorm Date: Tue, 22 Oct 2019 10:32:48 +0200 Subject: [PATCH 28/51] Show the Alc content in the distiller/always --- resources/config/v12/de/config.yml | 10 +++- resources/config/v13/de/config.yml | 8 +++- resources/config/v13/en/config.yml | 6 +++ resources/languages/de.yml | 1 + resources/languages/en.yml | 1 + src/com/dre/brewery/BDistiller.java | 18 +++++++ src/com/dre/brewery/BIngredients.java | 3 ++ src/com/dre/brewery/Brew.java | 9 +++- src/com/dre/brewery/MCBarrel.java | 2 +- src/com/dre/brewery/filedata/BConfig.java | 4 ++ .../dre/brewery/filedata/LanguageReader.java | 1 + .../brewery/listeners/InventoryListener.java | 19 +++++++- src/com/dre/brewery/lore/BrewLore.java | 48 +++++++++++-------- 13 files changed, 102 insertions(+), 28 deletions(-) diff --git a/resources/config/v12/de/config.yml b/resources/config/v12/de/config.yml index aa2e05b..c232ab4 100644 --- a/resources/config/v12/de/config.yml +++ b/resources/config/v12/de/config.yml @@ -50,6 +50,12 @@ hangoverDays: 7 colorInBarrels: true colorInBrewer: true +# Ob in den Iteminformationen immer 1-5 Sterne für die Qualität angezeigt werden sollen, oder nur beim brauen [true] +alwaysShowQuality: true + +# Ob in den Iteminformationen immer der Alkoholgehalt angezeigt weden soll, oder nur im Braustand [false] +alwaysShowAlc: false + # Ob große Fässer an jedem Block geöffnet werden können, nicht nur an Zapfhahn und Schild. Bei kleinen Fässern geht dies immer. [true] openLargeBarrelEverywhere: true @@ -160,6 +166,8 @@ recipes: age: 3 color: ORANGE difficulty: 1 + lore: + - +++ &8Das perlt alcohol: 6 3: name: Ranziges Dunkelbier/Dunkelbier/Feines Dunkelbier @@ -172,8 +180,6 @@ recipes: color: BLACK difficulty: 2 alcohol: 7 - lore: - - +++ &8Perlt wunderschön 4: name: Scheußlicher Met/Met/&6Goldener Met ingredients: diff --git a/resources/config/v13/de/config.yml b/resources/config/v13/de/config.yml index f55c7f8..d7079c9 100644 --- a/resources/config/v13/de/config.yml +++ b/resources/config/v13/de/config.yml @@ -50,6 +50,12 @@ hangoverDays: 7 colorInBarrels: true colorInBrewer: true +# Ob in den Iteminformationen immer 1-5 Sterne für die Qualität angezeigt werden sollen, oder nur beim brauen [true] +alwaysShowQuality: true + +# Ob in den Iteminformationen immer der Alkoholgehalt angezeigt weden soll, oder nur im Braustand [false] +alwaysShowAlc: false + # Ob große Fässer an jedem Block geöffnet werden können, nicht nur an Zapfhahn und Schild. Bei kleinen Fässern geht dies immer. [true] openLargeBarrelEverywhere: true @@ -152,7 +158,7 @@ recipes: color: ORANGE difficulty: 1 lore: - - +++ &8Perlt wunderschön + - +++ &8Das perlt alcohol: 6 3: name: Ranziges Dunkelbier/Dunkelbier/Feines Dunkelbier diff --git a/resources/config/v13/en/config.yml b/resources/config/v13/en/config.yml index 2829bf9..7227b2d 100644 --- a/resources/config/v13/en/config.yml +++ b/resources/config/v13/en/config.yml @@ -50,6 +50,12 @@ hangoverDays: 7 colorInBarrels: true colorInBrewer: true +# Always show the 1-5 stars on the item depending on the quality. If false, they will only appear when brewing [true] +alwaysShowQuality: true + +# Always show the alcohol content on the item. If false, it will only show in the brewing stand [false] +alwaysShowAlc: false + # If a Large Barrel can be opened by clicking on any of its blocks, not just Spigot or Sign. This is always true for Small Barrels. [true] openLargeBarrelEverywhere: true diff --git a/resources/languages/de.yml b/resources/languages/de.yml index 991e8d3..565791a 100644 --- a/resources/languages/de.yml +++ b/resources/languages/de.yml @@ -14,6 +14,7 @@ Brew_Woodtype: Holzart Brew_Years: Jahre Brew_fermented: gegärt Brew_minute: minute +Brew_Alc: Alc &v1ml # CMD CMD_Copy_Error: '&6&v1 &cTränke haben nicht mehr in das Inventar gepasst' diff --git a/resources/languages/en.yml b/resources/languages/en.yml index 84db0f4..9fa105c 100644 --- a/resources/languages/en.yml +++ b/resources/languages/en.yml @@ -14,6 +14,7 @@ Brew_Woodtype: Woodtype Brew_Years: Years Brew_fermented: fermented Brew_minute: minute +Brew_Alc: Alc &v1ml # CMD CMD_CopyNotPersistent: '&eThese copies of this Brew will not be persistent or static!' diff --git a/src/com/dre/brewery/BDistiller.java b/src/com/dre/brewery/BDistiller.java index 6f344d7..c65ae09 100644 --- a/src/com/dre/brewery/BDistiller.java +++ b/src/com/dre/brewery/BDistiller.java @@ -1,5 +1,6 @@ package com.dre.brewery; +import com.dre.brewery.lore.BrewLore; import org.bukkit.Bukkit; import org.bukkit.Material; import org.bukkit.block.Block; @@ -8,6 +9,7 @@ import org.bukkit.block.BrewingStand; import org.bukkit.event.inventory.InventoryClickEvent; import org.bukkit.inventory.BrewerInventory; import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.meta.PotionMeta; import org.bukkit.scheduler.BukkitRunnable; import java.util.HashMap; @@ -137,6 +139,21 @@ public class BDistiller { return 800; } + public static void showAlc(BrewerInventory inv) { + Brew[] contents = getDistillContents(inv); + for (int slot = 0; slot < 3; slot++) { + if (contents[slot] != null) { + // Show Alc in lore + ItemStack item = inv.getItem(slot); + PotionMeta meta = (PotionMeta) item.getItemMeta(); + BrewLore brewLore = new BrewLore(contents[slot], meta); + brewLore.updateAlc(true); + brewLore.write(); + item.setItemMeta(meta); + } + } + } + public class DistillRunnable extends BukkitRunnable { @Override @@ -166,6 +183,7 @@ public class BDistiller { // No custom potion, cancel and ignore this.cancel(); trackedDistillers.remove(standBlock); + showAlc(stand.getInventory()); P.p.debugLog("nothing to distill"); return; default: diff --git a/src/com/dre/brewery/BIngredients.java b/src/com/dre/brewery/BIngredients.java index 9dbffed..873dcc5 100644 --- a/src/com/dre/brewery/BIngredients.java +++ b/src/com/dre/brewery/BIngredients.java @@ -93,7 +93,10 @@ public class BIngredients { P.p.debugLog("cooked potion has Quality: " + quality); brew = new Brew(quality, cookRecipe, this); BrewLore lore = new BrewLore(brew, potionMeta); + lore.updateQualityStars(false); lore.updateCustomLore(); + lore.updateAlc(false); + lore.addOrReplaceEffects(brew.getEffects(), brew.getQuality()); cookedName = cookRecipe.getName(quality); diff --git a/src/com/dre/brewery/Brew.java b/src/com/dre/brewery/Brew.java index b265fd3..69b4e6d 100644 --- a/src/com/dre/brewery/Brew.java +++ b/src/com/dre/brewery/Brew.java @@ -287,6 +287,7 @@ public class Brew { }*/ // calculate alcohol from recipe + @Contract(pure = true) public int calcAlcohol() { if (quality == 0) { // Give bad potions some alc @@ -329,6 +330,7 @@ public class Brew { } // calculating quality + @Contract(pure = true) public int calcQuality() { // calculate quality from all of the factors float quality = ingredients.getIngredientQuality(currentRecipe) + ingredients.getCookingQuality(currentRecipe, distillRuns > 0); @@ -375,6 +377,7 @@ public class Brew { lore.updateAgeLore(false); } lore.updateQualityStars(false); + lore.updateAlc(false); lore.write(); item.setItemMeta(meta); } @@ -491,7 +494,6 @@ public class Brew { currentRecipe = recipe; quality = calcQuality(); - lore.updateCustomLore(); lore.addOrReplaceEffects(getEffects(), quality); potionMeta.setDisplayName(P.p.color("&f" + recipe.getName(quality))); PotionColor.fromString(recipe.getColor()).colorBrew(potionMeta, slotItem, canDistill()); @@ -509,8 +511,10 @@ public class Brew { lore.convertLore(BConfig.colorInBrewer); } lore.updateQualityStars(BConfig.colorInBrewer); + lore.updateCustomLore(); } lore.updateDistillLore(BConfig.colorInBrewer); + lore.updateAlc(true); lore.write(); touch(); BrewModifyEvent modifyEvent = new BrewModifyEvent(this, potionMeta, BrewModifyEvent.Type.DISTILL); @@ -562,7 +566,6 @@ public class Brew { currentRecipe = recipe; quality = calcQuality(); - lore.updateCustomLore(); lore.addOrReplaceEffects(getEffects(), quality); potionMeta.setDisplayName(P.p.color("&f" + recipe.getName(quality))); PotionColor.fromString(recipe.getColor()).colorBrew(potionMeta, item, canDistill()); @@ -588,6 +591,8 @@ public class Brew { lore.updateWoodLore(true); } lore.updateQualityStars(BConfig.colorInBarrels); + lore.updateCustomLore(); + lore.updateAlc(false); } lore.write(); touch(); diff --git a/src/com/dre/brewery/MCBarrel.java b/src/com/dre/brewery/MCBarrel.java index 3dd0a37..a0f4019 100644 --- a/src/com/dre/brewery/MCBarrel.java +++ b/src/com/dre/brewery/MCBarrel.java @@ -81,7 +81,7 @@ public class MCBarrel { for (ItemStack item : inv.getContents()) { if (item != null) { Brew brew = Brew.get(item); - if (brew != null) { + if (brew != null) { // TODO replace this and others with isBrew // We found a brew, so set time on this Barrel if (inv.getHolder() instanceof org.bukkit.block.Barrel) { Barrel barrel = (Barrel) inv.getHolder(); diff --git a/src/com/dre/brewery/filedata/BConfig.java b/src/com/dre/brewery/filedata/BConfig.java index 5e6dd2d..f7ea235 100644 --- a/src/com/dre/brewery/filedata/BConfig.java +++ b/src/com/dre/brewery/filedata/BConfig.java @@ -55,6 +55,8 @@ public class BConfig { public static boolean colorInBarrels; // color the Lore while in Barrels public static boolean colorInBrewer; // color the Lore while in Brewer public static boolean enableEncode; + public static boolean alwaysShowQuality; // Always show quality stars + public static boolean alwaysShowAlc; // Always show alc% public static P p = P.p; @@ -174,6 +176,8 @@ public class BConfig { homeType = config.getString("homeType", null); colorInBarrels = config.getBoolean("colorInBarrels", false); colorInBrewer = config.getBoolean("colorInBrewer", false); + alwaysShowQuality = config.getBoolean("alwaysShowQuality", false); + alwaysShowAlc = config.getBoolean("alwaysShowAlc", false); enableEncode = config.getBoolean("enableEncode", false); openEverywhere = config.getBoolean("openLargeBarrelEverywhere", false); MCBarrel.maxBrews = config.getInt("maxBrewsInMCBarrels", 6); diff --git a/src/com/dre/brewery/filedata/LanguageReader.java b/src/com/dre/brewery/filedata/LanguageReader.java index e1cb2f1..b523be9 100644 --- a/src/com/dre/brewery/filedata/LanguageReader.java +++ b/src/com/dre/brewery/filedata/LanguageReader.java @@ -75,6 +75,7 @@ public class LanguageReader { defaults.put("Brew_HundredsOfYears", "Hundreds of Years"); defaults.put("Brew_Woodtype", "Woodtype"); defaults.put("Brew_ThickBrew", "Muddy Brew"); + defaults.put("Brew_Alc", "Alc &v1ml"); /* Commands */ defaults.put("CMD_Reload", "&aConfig was successfully reloaded"); diff --git a/src/com/dre/brewery/listeners/InventoryListener.java b/src/com/dre/brewery/listeners/InventoryListener.java index 57a3023..6f62baa 100644 --- a/src/com/dre/brewery/listeners/InventoryListener.java +++ b/src/com/dre/brewery/listeners/InventoryListener.java @@ -5,6 +5,7 @@ import com.dre.brewery.filedata.BConfig; import com.dre.brewery.lore.BrewLore; import org.bukkit.Material; import org.bukkit.entity.HumanEntity; +import org.bukkit.entity.Player; import org.bukkit.event.EventHandler; import org.bukkit.event.EventPriority; import org.bukkit.event.Listener; @@ -204,18 +205,32 @@ public class InventoryListener implements Listener { PotionMeta meta = (PotionMeta) item.getItemMeta(); Brew brew = Brew.get(meta); if (brew != null) { + BrewLore lore = null; if (BrewLore.hasColorLore(meta)) { - BrewLore lore = new BrewLore(brew, meta); + lore = new BrewLore(brew, meta); lore.convertLore(false); + } else if (!BConfig.alwaysShowAlc && event.getInventory().getType() == InventoryType.BREWING) { + lore = new BrewLore(brew, meta); + lore.updateAlc(false); + } + if (lore != null) { lore.write(); item.setItemMeta(meta); + if (event.getWhoClicked() instanceof Player) { + switch (event.getAction()) { + case MOVE_TO_OTHER_INVENTORY: + case HOTBAR_SWAP: + // Fix a Graphical glitch of item still showing colors until clicking it + P.p.getServer().getScheduler().runTask(P.p, () -> ((Player) event.getWhoClicked()).updateInventory()); + } + } } } } } // Check if the player tries to add more than the allowed amount of brews into an mc-barrel - @EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true) + @EventHandler(priority = EventPriority.HIGH, ignoreCancelled = true) public void onInventoryClickMCBarrel(InventoryClickEvent event) { if (!P.use1_14) return; if (event.getInventory().getType() != InventoryType.BARREL) return; diff --git a/src/com/dre/brewery/lore/BrewLore.java b/src/com/dre/brewery/lore/BrewLore.java index d9d549c..293cab6 100644 --- a/src/com/dre/brewery/lore/BrewLore.java +++ b/src/com/dre/brewery/lore/BrewLore.java @@ -1,6 +1,7 @@ package com.dre.brewery.lore; import com.dre.brewery.*; +import com.dre.brewery.filedata.BConfig; import com.dre.brewery.utility.BUtil; import org.bukkit.inventory.meta.PotionMeta; import org.bukkit.potion.PotionEffect; @@ -209,7 +210,7 @@ public class BrewLore { if (brew.hasRecipe() && brew.getCurrentRecipe().needsToAge() && brew.getAgeTime() < 0.5) { return; } - if (!brew.isUnlabeled()) { + if (!brew.isUnlabeled() && brew.getQuality() > 0 && (qualityColor || BConfig.alwaysShowQuality)) { int stars = (brew.getQuality() + 1) / 2; StringBuilder b = new StringBuilder(stars); for (; stars > 0; stars--) { @@ -227,6 +228,15 @@ public class BrewLore { } } + public void updateAlc(boolean inDistiller) { + if (!brew.isUnlabeled() && (inDistiller || BConfig.alwaysShowAlc)) { + int alc = brew.calcAlcohol(); + addOrReplaceLore(Type.ALC, "§8", P.p.languageReader.get("Brew_Alc", alc + "")); + } else { + removeLore(Type.ALC); + } + } + /** * Converts to/from qualitycolored Lore */ @@ -260,6 +270,8 @@ public class BrewLore { updateWoodLore(toQuality); } } + + updateAlc(false); } /** @@ -332,10 +344,9 @@ public class BrewLore { * Removes all Brew Lore lines */ public void removeAll() { - for (Type t : Type.values()) { - int index = t.findInLore(lore); - if (index > -1) { - lore.remove(index); + for (int i = lore.size() - 1; i >= 0; i--) { + if (Type.get(lore.get(i)) != null) { + lore.remove(i); } } } @@ -442,26 +453,24 @@ public class BrewLore { } public enum Type { - STARS("§s", 0), - CUSTOM("§t", 1), - SPACE("§u", 2), + STARS("§s"), + CUSTOM("§t"), + SPACE("§u"), - INGR("§v", 3), - COOK("§w", 4), - DISTILL("§x", 5), - AGE("§y", 6), - WOOD("§z", 7); + INGR("§v"), + COOK("§w"), + DISTILL("§x"), + AGE("§y"), + WOOD("§z"), + ALC("§k"); public final String id; - public final int ordering; /** * @param id Identifier as Prefix of the Loreline - * @param ordering Ordering of the Brew Lore */ - Type(String id, int ordering) { + Type(String id) { this.id = id; - this.ordering = ordering; } /** @@ -481,7 +490,7 @@ public class BrewLore { * @return true if this type should be after the other type in lore */ public boolean isAfter(Type other) { - return other.ordering <= ordering; + return other.ordinal() <= ordinal(); } /** @@ -490,8 +499,7 @@ public class BrewLore { @Nullable public static Type get(String loreLine) { if (loreLine.length() >= 2) { - loreLine = loreLine.substring(0, 2); - return getById(loreLine); + return getById(loreLine.substring(0, 2)); } else { return null; } From d0263c611c721bb3c1b7dd11dbfbb9264b4aa5ef Mon Sep 17 00:00:00 2001 From: Sn0wStorm Date: Tue, 29 Oct 2019 16:20:32 +0100 Subject: [PATCH 29/51] Added Custom Items and Cauldron-Recipes --- resources/config/v13/de/config.yml | 451 +++++++++++------- resources/config/v13/en/config.yml | 415 +++++++++------- src/com/dre/brewery/BCauldron.java | 52 +- src/com/dre/brewery/BCauldronRecipe.java | 141 ++++++ src/com/dre/brewery/BIngredients.java | 98 ++-- src/com/dre/brewery/BRecipe.java | 298 ++++++------ src/com/dre/brewery/Brew.java | 60 ++- src/com/dre/brewery/P.java | 14 +- src/com/dre/brewery/filedata/BConfig.java | 56 ++- .../brewery/listeners/CommandListener.java | 7 +- src/com/dre/brewery/lore/BrewLore.java | 57 ++- src/com/dre/brewery/utility/CustomItem.java | 329 +++++++++++++ src/com/dre/brewery/utility/Tuple.java | 42 +- test/com/dre/brewery/RecipeTests.java | 50 ++ 14 files changed, 1420 insertions(+), 650 deletions(-) create mode 100644 src/com/dre/brewery/BCauldronRecipe.java create mode 100644 src/com/dre/brewery/utility/CustomItem.java create mode 100644 test/com/dre/brewery/RecipeTests.java diff --git a/resources/config/v13/de/config.yml b/resources/config/v13/de/config.yml index d7079c9..fb0f925 100644 --- a/resources/config/v13/de/config.yml +++ b/resources/config/v13/de/config.yml @@ -40,8 +40,8 @@ pukeDespawntime: 60 # Konsumierbares Item/Stärke. Senkt den Alkoholpegel um wenn konsumiert. drainItems: -- Bread/4 -- Milk_Bucket/2 + - Bread/4 + - Milk_Bucket/2 # Zeit (in Tagen) die Trunkenheitsdaten nach offlinegehen eines Spielers im Speicher verbleiben, um z.B. Kater-Effekte anzuwenden. [7] hangoverDays: 7 @@ -80,6 +80,111 @@ autosave: 3 version: '1.8' +# -- Eigene Items Definieren -- +# Die festgelegte id kann dann in einem Rezept verwendet werden + +# matchAny: true wenn es schon reicht wenn eine der Angaben zutrifft +# material: Welche Art das Item haben muss +# name: Welchen Namen das Item haben muss (Farbcodes möglich: z.b. &6) +# lore: Was in der Lore des Items stehen muss + +customItems: + bsp-item: +# Ein Barriere Item das Mauer heißt und in der Lore die angegebene Zeile hat + material: Barrier + name: 'Mauer' + lore: + - '&7Besonders gut geschützt' + + bsp-item2: +# Mit matchAny muss nur eine der Angaben zutreffen. +# Hier also eine der Türarten, oder ein Item namens Buchenholztür, oder ein Item mit 'Eine Tür' in der Lore + matchAny: true + material: + - Acacia_Door + - Oak_Door + - Spruce_Door + name: + - 'Buchenholztür' + lore: + - 'Eine Tür' + + himbeere: + name: '&cHimbeere' + + +# -- Zutaten im Kessel -- +# Hier kann angegeben werden welche Zutaten in den Kessel getan werden können und was mit ihnen geschieht. + +# name: Name des Basistrankes der aus dem Kessel kommt (Farbcodes möglich: z.b. &6) +# ingredients: Auflistung von 'Material/Anzahl' +# Halte ein Item in der Hand und benutze /brew ItemName um dessen Material herauszufinden und für ein Rezept zu benutzen +# (Item-ids anstatt Material können in Bukkit nicht mehr benutzt werden) +# Eine Liste von allen Materialien kann hier gefunden werden: https://hub.spigotmc.org/javadocs/spigot/org/bukkit/Material.html +# color: Farbe des Trankes der aus dem Kessel kommt +# Benutzbare Farben: DARK_RED, RED, BRIGHT_RED, ORANGE, PINK, BLUE, CYAN, WATER, GREEN, BLACK, GREY, BRIGHT_GREY +# Oder RGB Farben (Hex: also zB '99FF33') (Ohne #) (mit '') (Einfach nach "HTML color" im Internet suchen) +# lore: Auflistung von zusätzlichem Text auf dem Trank. (Farbcodes möglich: z.b. &6) + + +cauldron: + bsp: + name: Beispiel + ingredients: + - Bedrock/2 + - Diamond + color: BLACK + lore: + - Ein Beispiel für einen Basistrank + - So kommt er aus dem Kessel + +# -- Eine Zutat: -- + wheat: + name: Getreideferment + ingredients: Wheat + + sugarcane: + name: Zuckersud + ingredients: Sugar_Cane + color: 'f1ffad' # gelbliches grün + + apple: + name: Apfelmost + ingredients: Apple + + potato: + name: Kartoffelmaische + ingredients: Potato + + grass: + name: Kräuterbrühe + ingredients: Grass + color: '99ff66' # helles grün + + rmushroom: + name: Pilzsud + ingredients: Red_Mushroom + color: 'ff5c33' # bernsteinrot + + cocoa: + name: Kakaobrühe + ingredients: Cocoa_Beans + color: '804600' # mokka + + milk: + name: Milchiges Wasser + ingredients: Milk_Bucket + color: BRIGHT_GREY + + # -- Mehrere Zutaten: -- + apfelmet_basis: + name: Apfel-Zuckersud + ingredients: + - Sugar_Cane/3 + - Apple + color: 'e1ff4d' # grünliches gelb + + # -- Rezepte für Getränke -- # name: Verschiedene Namen für schlecht/mittel/gut (Farbcodes möglich: z.b. &6) @@ -108,185 +213,181 @@ version: '1.8' recipes: # Ein vollständiges Beispiel zuerst: - 0: - name: Schlechtes Beispiel/Beispiel/Gutes Beispiel - ingredients: - - Sugar_Cane/5 - - Diamond/1 - - Cocoa_Beans/20 - - Spruce_Planks/8 - - Bedrock/1 - cookingtime: 3 - distillruns: 2 - distilltime: 60 - wood: 4 - age: 11 - color: DARK_RED - difficulty: 3 - alcohol: 23 - lore: - - Dies ist ein Beispiel Trank - - ++Ganz normales Beispiel - - Dies würde auf dem Trank stehen - - + Riecht eklig - - ++ Riecht ganz ok - - +++ Riecht richtig gut - effects: - - FIRE_RESISTANCE/20 - - HEAL/1 - - WEAKNESS/2-3/50-60 - - POISON/1-0/20-0 - 1: - name: Ranziges Weißbier/Weißbier/Feines Weißbier - ingredients: - - Wheat/3 - cookingtime: 8 - distillruns: 0 - wood: 1 - age: 2 - color: BRIGHT_GREY - difficulty: 1 - alcohol: 5 - 2: - name: Ranziges Bier/Bier/Feines Bier - ingredients: - - Wheat/6 - cookingtime: 8 - distillruns: 0 - wood: 0 - age: 3 - color: ORANGE - difficulty: 1 - lore: - - +++ &8Das perlt - alcohol: 6 - 3: - name: Ranziges Dunkelbier/Dunkelbier/Feines Dunkelbier - ingredients: - - Wheat/6 - cookingtime: 8 - distillruns: 0 - wood: 4 - age: 8 - color: BLACK - difficulty: 2 - alcohol: 7 - 4: - name: Scheußlicher Met/Met/&6Goldener Met - ingredients: - - Sugar_Cane/6 - cookingtime: 3 - distillruns: 0 - wood: 2 - age: 4 - color: ORANGE - difficulty: 2 - alcohol: 9 - lore: - - +++ Hat einen goldenen Schein - 5: - name: Apfelmet/Süßer Apfelmet/&6Goldensüßer Apfelmet - ingredients: - - Sugar_Cane/6 - - Apple/2 - cookingtime: 4 - distillruns: 0 - wood: 2 - age: 4 - color: ORANGE - difficulty: 4 - alcohol: 12 - lore: - - + Ist da wirklich Apfel drin? - - ++ Schmeckt nach süßem Apfel - - +++ Hat eine wunderbare Apfelnote - effects: - - WATER_BREATHING/1-2/150 - 6: - name: Bitterer Rum/Würziger Rum/&6Goldener Rum - ingredients: - - Sugar_Cane/14 - cookingtime: 5 - distillruns: 2 - distilltime: 30 - wood: 2 - age: 14 - color: DARK_RED - difficulty: 6 - alcohol: 30 - effects: - - FIRE_RESISTANCE/1/20-100 - - POISON/1-0/30-0 - 7: - name: Abgeranzter Vodka/Vodka/Russischer Vodka - ingredients: - - Potato/10 - cookingtime: 15 - distillruns: 3 - age: 0 - color: BRIGHT_GREY - difficulty: 4 - alcohol: 20 - lore: - - + &8Fast nicht trinkbar - effects: - - WEAKNESS/15 - - POISON/10 - 8: - name: minderwertiger Absinth/Absinth/Starker Absinth - ingredients: - - Grass/15 - cookingtime: 3 - distillruns: 6 - distilltime: 80 - color: GREEN - difficulty: 8 - alcohol: 45 - effects: - - POISON/20-30 - 9: - name: Kartoffelsuppe - ingredients: - - Potato/5 - - Grass/3 - cookingtime: 3 - color: PINK - difficulty: 1 - effects: - - HEAL/0-1 - 10: - name: Fader Kaffee/Kaffee/Starker Kaffee - ingredients: - - Cocoa_Beans/12 - - Milk_Bucket/2 - cookingtime: 2 - color: BLACK - difficulty: 3 - lore: + &8Bestimmt schon eine Woche alt - effects: - - REGENERATION/1/2-5 - - SPEED/1/30-140 + bsp: + name: Schlechtes Beispiel/Beispiel/Gutes Beispiel + ingredients: + - Diamond/1 + - Spruce_Planks/8 + - Bedrock/1 +# - Brewery:Weißbier/2 +# - ExoticGarden:Grape/3 + - bsp-item/1 + cookingtime: 3 + distillruns: 2 + distilltime: 60 + wood: 4 + age: 11 + color: DARK_RED + difficulty: 3 + alcohol: 23 + lore: + - Dies ist ein Beispiel Trank + - ++Ganz normales Beispiel + - Dies würde auf dem Trank stehen + - + Riecht eklig + - ++ Riecht ganz ok + - +++ Riecht richtig gut + effects: + - FIRE_RESISTANCE/20 + - HEAL/1 + - WEAKNESS/2-3/50-60 + - POISON/1-0/20-0 + + weißbier: + name: Ranziges Weißbier/Weißbier/Feines Weißbier + ingredients: + - Wheat/3 + cookingtime: 8 + distillruns: 0 + wood: 1 + age: 2 + color: BRIGHT_GREY + difficulty: 1 + alcohol: 5 + + bier: + name: Ranziges Bier/Bier/Feines Bier + ingredients: + - Wheat/6 + cookingtime: 8 + distillruns: 0 + wood: 0 + age: 3 + color: ORANGE + difficulty: 1 + lore: + - +++ &8Das perlt + alcohol: 6 + + dunkelbier: + name: Ranziges Dunkelbier/Dunkelbier/Feines Dunkelbier + ingredients: + - Wheat/6 + cookingtime: 8 + distillruns: 0 + wood: 4 + age: 8 + color: BLACK + difficulty: 2 + alcohol: 7 + + met: + name: Scheußlicher Met/Met/&6Goldener Met + ingredients: + - Sugar_Cane/6 + cookingtime: 3 + distillruns: 0 + wood: 2 + age: 4 + color: ORANGE + difficulty: 2 + alcohol: 9 + lore: + - +++ Hat einen goldenen Schein + + apfelmet: + name: Apfelmet/Süßer Apfelmet/&6Goldensüßer Apfelmet + ingredients: + - Sugar_Cane/6 + - Apple/2 + cookingtime: 4 + distillruns: 0 + wood: 2 + age: 4 + color: ORANGE + difficulty: 4 + alcohol: 12 + lore: + - + Ist da wirklich Apfel drin? + - ++ Schmeckt nach süßem Apfel + - +++ Hat eine wunderbare Apfelnote + effects: + - WATER_BREATHING/1-2/150 + + rum: + name: Bitterer Rum/Würziger Rum/&6Goldener Rum + ingredients: + - Sugar_Cane/14 + cookingtime: 5 + distillruns: 2 + distilltime: 30 + wood: 2 + age: 14 + color: DARK_RED + difficulty: 6 + alcohol: 30 + effects: + - FIRE_RESISTANCE/1/20-100 + - POISON/1-0/30-0 + + vodka: + name: Abgeranzter Vodka/Vodka/Russischer Vodka + ingredients: + - Potato/10 + cookingtime: 15 + distillruns: 3 + age: 0 + color: BRIGHT_GREY + difficulty: 4 + alcohol: 20 + lore: + - + &8Fast nicht trinkbar + effects: + - WEAKNESS/15 + - POISON/10 + + absinth: + name: minderwertiger Absinth/Absinth/Starker Absinth + ingredients: + - Grass/15 + cookingtime: 3 + distillruns: 6 + distilltime: 80 + color: GREEN + difficulty: 8 + alcohol: 45 + effects: + - POISON/20-30 + + kartoffelsuppe: + name: Kartoffelsuppe + ingredients: + - Potato/5 + - Grass/3 + cookingtime: 3 + color: PINK + difficulty: 1 + effects: + - HEAL/0-1 + + kaffee: + name: Fader Kaffee/Kaffee/Starker Kaffee + ingredients: + - Cocoa_Beans/12 + - Milk_Bucket/2 + cookingtime: 2 + color: BLACK + difficulty: 3 + lore: + &8Bestimmt schon eine Woche alt + effects: + - REGENERATION/1/2-5 + - SPEED/1/30-140 # Mehr Ideen für Rezepte: Cachaca, Gin, Whiskey, Tequila, Cidre, etc, sowie Rezeptvarianten wie Goldener Vodka etc. # Ich werde keine weiteren Rezepte zu dieser Standardconfig hinzufügen, da diese öffentlich und für Spieler zum Abschauen einsehbar wären # Der Serveradmin kann neue Rezepte hinzufügen und bestehende ändern, um das Abschauen aus der Standardconfig zu verhindern. -# cooked: ALLE möglichen Zutaten und die nach dem Gähren daraus entstehenden Tranknamen: -# [Beispiel] MATERIAL: Name nach Gähren - -cooked: - Wheat: Getreideferment - Sugar_Cane: Zuckersud - Apple: Apfelmost - Potato: Kartoffelmaische - Grass: Kräuterbrühe - Red_Mushroom: Pilzsud - Cocoa_Beans: Farbige Brühe - Milk_Bucket: Milchiges Wasser - - - # -- Plugin Kompatiblität -- # Andere Plugins (wenn installiert) nach Rechten zum öffnen von Fässern checken [true] diff --git a/resources/config/v13/en/config.yml b/resources/config/v13/en/config.yml index 7227b2d..3e5050f 100644 --- a/resources/config/v13/en/config.yml +++ b/resources/config/v13/en/config.yml @@ -40,8 +40,8 @@ pukeDespawntime: 60 # Consumable Item/strength. Decreases the alcohol level by when consumed. (list) drainItems: -- Bread/4 -- Milk_Bucket/2 + - Bread/4 + - Milk_Bucket/2 # Time (in days) that drunkeness-data stays in memory after a player goes offline, to apply hangover etc. [7] hangoverDays: 7 @@ -81,6 +81,111 @@ autosave: 3 version: '1.8' +# -- Define custom items -- +# The defined id can then be used in recipes + +# matchAny: true if it is already enough if one of the info matches +# material: Which type the item has to be +# name: Which name the item has to be (Formatting codes possible: such as &6) +# lore: What has to be in the lore of the item + +customItems: + ex-item: + # A Barrier item called Wall and has the given line in its lore + material: Barrier + name: 'Wall' + lore: + - '&7Very well protected' + + ex-item2: + # Using matchAny only one of the following has to match. + # In this case on of the door types, or an item called Beechwood Door, or an item with 'A door' in its lore + matchAny: true + material: + - Acacia_Door + - Oak_Door + - Spruce_Door + name: + - 'Beechwood Door' + lore: + - 'A door' + + rasp: + name: '&cRaspberry' + + +# -- Ingredients in the Cauldron -- +# Which Ingredients are accepted by the Cauldron and the base potion resulting from them + +# name: Name of the base potion coming out of the Cauldron (Formatting codes possible: such as &6) +# ingredients: List of 'material/amount' +# With an item in your hand, use /brew ItemName to get its material for use in a recipe +# (Item-ids instead of material are not supported by bukkit anymore and will not work) +# A list of materials can be found here: https://hub.spigotmc.org/javadocs/spigot/org/bukkit/Material.html +# color: Color of the potion from a cauldron. +# Usable Colors: DARK_RED, RED, BRIGHT_RED, ORANGE, PINK, BLUE, CYAN, WATER, GREEN, BLACK, GREY, BRIGHT_GREY +# Or RGB colors (hex: for example '99FF33') (with '') (search for "HTML color" on the internet) +# lore: List of additional text on the base potion. (Formatting codes possible: such as &6) + +cauldron: + ex: + name: Example + ingredients: + - Bedrock/2 + - Diamond + color: BLACK + lore: + - An example for a Base Potion + - This is how it comes out of a Cauldron + + # -- One Ingredient: -- + wheat: + name: Fermented wheat + ingredients: Wheat + + sugarcane: + name: Sugar brew + ingredients: Sugar_Cane + color: 'f1ffad' # yellowish green + + apple: + name: Apple cider + ingredients: Apple + + potato: + name: Potatomash + ingredients: Potato + + grass: + name: Boiled herbs + ingredients: Grass + color: '99ff66' # bright green + + rmushroom: + name: Mushroom brew + ingredients: Red_Mushroom + color: 'ff5c33' # amber red + + cocoa: + name: Chocolately brew + ingredients: Cocoa_Beans + color: '804600' # mocca + + milk: + name: Milky water + ingredients: Milk_Bucket + color: BRIGHT_GREY + + # -- Multiple Ingredients: -- + apfelmet_base: + name: Apple-Sugar brew + ingredients: + - Sugar_Cane/3 + - Apple + color: 'e1ff4d' # greenish yellow + + + # -- Recipes for Potions -- # name: Different names for bad/normal/good (Formatting codes possible: such as &6) @@ -101,8 +206,6 @@ version: '1.8' # alcohol: Absolute amount of alcohol 0-100 in a perfect potion (will be added directly to the player, where 100 means fainting) # lore: List of additional text on the finished brew. (Formatting codes possible: such as &6) # Specific lore for quality possible, using + bad, ++ normal, ++ good, added to the front of the line. -# lore: Auflistung von zusätzlichem Text auf dem fertigen Trank. (Farbcodes möglich: z.b. &6) -# Lore nur für bestimmte Qualität möglich mit + Schlecht, ++ Mittel, +++ Gut, vorne anhängen. # effects: List of effect/level/duration Special potion-effect when drinking, duration in sek. # Possible Effects: https://hub.spigotmc.org/javadocs/spigot/org/bukkit/potion/PotionEffectType.html # Level or Duration ranges may be specified with a "-", ex. 'SPEED/1-2/30-40' = lvl 1 and 30 sec at worst and lvl 2 and 40 sec at best @@ -110,188 +213,180 @@ version: '1.8' # Highest possible Duration: 1638 sec. Instant Effects dont need any duration specified. recipes: -# Example Recipe with every possible entry first: - 0: - name: Bad Example/Example/Good Example - ingredients: - - Sugar_Cane/5 + # Example Recipe with every possible entry first: + ex: + name: Bad Example/Example/Good Example + ingredients: - Diamond/1 - - Cocoa_Beans/20 - Spruce_Planks/8 - Bedrock/1 - cookingtime: 3 - distillruns: 2 - distilltime: 60 - wood: 4 - age: 11 - color: DARK_RED - difficulty: 3 - alcohol: 23 - lore: - - This is an examble brew - - ++Just a normal Example - - This text would be on the brew - - + Smells disgusting - - ++ Smells alright - - +++ Smells really good - effects: + cookingtime: 3 + distillruns: 2 + distilltime: 60 + wood: 4 + age: 11 + color: DARK_RED + difficulty: 3 + alcohol: 23 + lore: + - This is an examble brew + - ++Just a normal Example + - This text would be on the brew + - + Smells disgusting + - ++ Smells alright + - +++ Smells really good + effects: - FIRE_RESISTANCE/20 - HEAL/1 - WEAKNESS/2-3/50-60 - POISON/1-0/20-0 - 1: - name: Skunky Wheatbeer/Wheatbeer/Fine Wheatbeer - ingredients: + + wheatbeer: + name: Skunky Wheatbeer/Wheatbeer/Fine Wheatbeer + ingredients: - Wheat/3 - cookingtime: 8 - distillruns: 0 - wood: 1 - age: 2 - color: BRIGHT_GREY - difficulty: 1 - alcohol: 5 - 2: - name: Skunky Beer/Beer/Fine Beer - ingredients: + cookingtime: 8 + distillruns: 0 + wood: 1 + age: 2 + color: BRIGHT_GREY + difficulty: 1 + alcohol: 5 + + beer: + name: Skunky Beer/Beer/Fine Beer + ingredients: - Wheat/6 - cookingtime: 8 - distillruns: 0 - wood: 0 - age: 3 - color: ORANGE - difficulty: 1 - lore: - - +++ &8Crisp taste - alcohol: 6 - 3: - name: Skunky Darkbeer/Darkbeer/Fine Darkbeer - ingredients: + cookingtime: 8 + distillruns: 0 + wood: 0 + age: 3 + color: ORANGE + difficulty: 1 + lore: + - +++ &8Crisp taste + alcohol: 6 + + darkbeer: + name: Skunky Darkbeer/Darkbeer/Fine Darkbeer + ingredients: - Wheat/6 - cookingtime: 8 - distillruns: 0 - wood: 4 - age: 8 - color: BLACK - difficulty: 2 - lore: - - +++ &8Roasted taste - alcohol: 7 - 4: - name: Awkward Mead/Mead/&6Golden Mead - ingredients: + cookingtime: 8 + distillruns: 0 + wood: 4 + age: 8 + color: BLACK + difficulty: 2 + lore: + - +++ &8Roasted taste + alcohol: 7 + + mead: + name: Awkward Mead/Mead/&6Golden Mead + ingredients: - Sugar_Cane/6 - cookingtime: 3 - distillruns: 0 - wood: 2 - age: 4 - color: ORANGE - difficulty: 2 - lore: - - +++ Has a golden shine - alcohol: 9 - 5: - name: Apple Mead/Sweet Apple Mead/&6Sweet Golden Apple Mead - ingredients: + cookingtime: 3 + distillruns: 0 + wood: 2 + age: 4 + color: ORANGE + difficulty: 2 + lore: + - +++ Has a golden shine + alcohol: 9 + + ap_mead: + name: Apple Mead/Sweet Apple Mead/&6Sweet Golden Apple Mead + ingredients: - Sugar_Cane/6 - Apple/2 - cookingtime: 4 - distillruns: 0 - wood: 2 - age: 4 - color: ORANGE - difficulty: 4 - alcohol: 12 - lore: - - +Is there any Apple in this? - - ++Refreshing taste of Apple - - +++Sweetest hint of Apple - effects: + cookingtime: 4 + distillruns: 0 + wood: 2 + age: 4 + color: ORANGE + difficulty: 4 + alcohol: 12 + lore: + - +Is there any Apple in this? + - ++Refreshing taste of Apple + - +++Sweetest hint of Apple + effects: - WATER_BREATHING/1-2/150 - 6: - name: Bitter Rum/Spicy Rum/&6Golden Rum - ingredients: + + rum: + name: Bitter Rum/Spicy Rum/&6Golden Rum + ingredients: - Sugar_Cane/14 - cookingtime: 5 - distillruns: 2 - distilltime: 30 - wood: 2 - age: 14 - color: DARK_RED - difficulty: 6 - alcohol: 30 - effects: + cookingtime: 5 + distillruns: 2 + distilltime: 30 + wood: 2 + age: 14 + color: DARK_RED + difficulty: 6 + alcohol: 30 + effects: - FIRE_RESISTANCE/1/20-100 - POISON/1-0/30-0 - 7: - name: Lousy Vodka/Vodka/Russian Vodka - ingredients: + + vodka: + name: Lousy Vodka/Vodka/Russian Vodka + ingredients: - Potato/10 - cookingtime: 15 - distillruns: 3 - age: 0 - color: BRIGHT_GREY - difficulty: 4 - alcohol: 20 - lore: +&8Almost undrinkable - effects: + cookingtime: 15 + distillruns: 3 + age: 0 + color: BRIGHT_GREY + difficulty: 4 + alcohol: 20 + lore: +&8Almost undrinkable + effects: - WEAKNESS/15 - POISON/10 - 8: - name: Poor Absinthe/Absinthe/Strong Absinthe - ingredients: - - Grass/15 - cookingtime: 3 - distillruns: 6 - distilltime: 80 - color: GREEN - difficulty: 8 - alcohol: 45 - effects: - - POISON/20-30 - 9: - name: Potato soup - ingredients: - - Potato/5 - - Grass/3 - cookingtime: 3 - color: PINK - difficulty: 1 - effects: - - HEAL/0-1 - 10: - name: Stale Coffee/Coffee/Strong Coffee - ingredients: - - Cocoa_Beans/12 - - Milk_Bucket/2 - cookingtime: 2 - color: BLACK - difficulty: 3 - lore: + &8Probably a week old - effects: - - REGENERATION/1/2-5 - - SPEED/1/30-140 + + absinthe: + name: Poor Absinthe/Absinthe/Strong Absinthe + ingredients: + - Grass/15 + cookingtime: 3 + distillruns: 6 + distilltime: 80 + color: GREEN + difficulty: 8 + alcohol: 45 + effects: + - POISON/20-30 + + potato_soup: + name: Potato soup + ingredients: + - Potato/5 + - Grass/3 + cookingtime: 3 + color: PINK + difficulty: 1 + effects: + - HEAL/0-1 + + coffee: + name: Stale Coffee/Coffee/Strong Coffee + ingredients: + - Cocoa_Beans/12 + - Milk_Bucket/2 + cookingtime: 2 + color: BLACK + difficulty: 3 + lore: + &8Probably a week old + effects: + - REGENERATION/1/2-5 + - SPEED/1/30-140 # More Recipes ideas: Cachaca, Gin, Whiskey, Tequila, Cider, etc. as well as high quality abbreviations like golden vodka etc. # I will not add more Recipes to the default config, as they would be public and viewable by users to cheat. # It is up to the Serveradmin to change and add Recipes, so players cannot cheat from the default config. - -# cooked: EVERY possible ingredient and the names for the originating potions after fermenting: -# [Example] MATERIAL: Name after cooking - -cooked: - Wheat: Fermented wheat - Sugar_Cane: Sugar brew - Apple: Apple cider - Potato: Potatomash - Grass: Boiled herbs - Red_Mushroom: Mushroom brew - Cocoa_Beans: Colored brew - Milk_Bucket: Milky water - - - # -- Plugin Compatibility -- # Enable checking of other Plugins (if installed) for Barrel Permissions [true] diff --git a/src/com/dre/brewery/BCauldron.java b/src/com/dre/brewery/BCauldron.java index b8cd460..3552f66 100644 --- a/src/com/dre/brewery/BCauldron.java +++ b/src/com/dre/brewery/BCauldron.java @@ -177,6 +177,7 @@ public class BCauldron { ItemStack item = event.getItem(); Player player = event.getPlayer(); Block clickedBlock = event.getClickedBlock(); + assert clickedBlock != null; if (materialInHand == null || materialInHand == Material.AIR || materialInHand == Material.BUCKET) { return; @@ -187,6 +188,7 @@ public class BCauldron { // fill a glass bottle with potion } else if (materialInHand == Material.GLASS_BOTTLE) { + assert item != null; if (player.getInventory().firstEmpty() != -1 || item.getAmount() == 1) { BCauldron bcauldron = get(clickedBlock); if (bcauldron != null) { @@ -233,12 +235,7 @@ public class BCauldron { if (event.getHand() == EquipmentSlot.HAND) { final UUID id = player.getUniqueId(); plInteracted.add(id); - P.p.getServer().getScheduler().runTask(P.p, new Runnable() { - @Override - public void run() { - plInteracted.remove(id); - } - }); + P.p.getServer().getScheduler().runTask(P.p, () -> plInteracted.remove(id)); } else if (event.getHand() == EquipmentSlot.OFF_HAND) { if (!plInteracted.remove(player.getUniqueId())) { item = player.getInventory().getItemInMainHand(); @@ -254,29 +251,30 @@ public class BCauldron { if (item == null) return; // add ingredient to cauldron that meet the previous conditions - if (BIngredients.possibleIngredients.contains(materialInHand)) { + if (BCauldronRecipe.acceptedMaterials.contains(materialInHand)) { - if (player.hasPermission("brewery.cauldron.insert")) { - if (ingredientAdd(clickedBlock, item, player)) { - boolean isBucket = item.getType().equals(Material.WATER_BUCKET) - || item.getType().equals(Material.LAVA_BUCKET) - || item.getType().equals(Material.MILK_BUCKET); - if (item.getAmount() > 1) { - item.setAmount(item.getAmount() - 1); + if (!player.hasPermission("brewery.cauldron.insert")) { + P.p.msg(player, P.p.languageReader.get("Perms_NoCauldronInsert")); + return; + } - if (isBucket) { - giveItem(player, new ItemStack(Material.BUCKET)); - } + if (ingredientAdd(clickedBlock, item, player)) { + boolean isBucket = item.getType().equals(Material.WATER_BUCKET) + || item.getType().equals(Material.LAVA_BUCKET) + || item.getType().equals(Material.MILK_BUCKET); + if (item.getAmount() > 1) { + item.setAmount(item.getAmount() - 1); + + if (isBucket) { + giveItem(player, new ItemStack(Material.BUCKET)); + } + } else { + if (isBucket) { + setItemInHand(event, Material.BUCKET, handSwap); } else { - if (isBucket) { - setItemInHand(event, Material.BUCKET, handSwap); - } else { - setItemInHand(event, Material.AIR, handSwap); - } + setItemInHand(event, Material.AIR, handSwap); } } - } else { - P.p.msg(player, P.p.languageReader.get("Perms_NoCauldronInsert")); } } } @@ -353,11 +351,7 @@ public class BCauldron { // bukkit bug not updating the inventory while executing event, have to // schedule the give public static void giveItem(final Player player, final ItemStack item) { - P.p.getServer().getScheduler().runTaskLater(P.p, new Runnable() { - public void run() { - player.getInventory().addItem(item); - } - }, 1L); + P.p.getServer().getScheduler().runTaskLater(P.p, () -> player.getInventory().addItem(item), 1L); } } diff --git a/src/com/dre/brewery/BCauldronRecipe.java b/src/com/dre/brewery/BCauldronRecipe.java new file mode 100644 index 0000000..6968829 --- /dev/null +++ b/src/com/dre/brewery/BCauldronRecipe.java @@ -0,0 +1,141 @@ +package com.dre.brewery; + +import com.dre.brewery.utility.CustomItem; +import com.dre.brewery.utility.PotionColor; +import com.dre.brewery.utility.Tuple; +import org.bukkit.Material; +import org.bukkit.configuration.ConfigurationSection; +import org.bukkit.inventory.ItemStack; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.util.ArrayList; +import java.util.EnumSet; +import java.util.List; +import java.util.Set; +import java.util.stream.Collectors; + +public class BCauldronRecipe { + public static List recipes = new ArrayList<>(); + public static Set acceptedMaterials = EnumSet.noneOf(Material.class); + + private String name; + private List> ingredients; // Item and amount + //private List particles + private PotionColor color; + private List lore; + + + @Nullable + public static BCauldronRecipe fromConfig(ConfigurationSection cfg, String id) { + BCauldronRecipe recipe = new BCauldronRecipe(); + + recipe.name = cfg.getString(id + ".name"); + if (recipe.name != null) { + recipe.name = P.p.color(recipe.name); + } else { + P.p.errorLog("Missing name for Cauldron-Recipe: " + id); + return null; + } + + recipe.ingredients = BRecipe.loadIngredients(cfg, id); + if (recipe.ingredients == null || recipe.ingredients.isEmpty()) { + P.p.errorLog("No ingredients for Cauldron-Recipe: " + recipe.name); + return null; + } + + String col = cfg.getString(id + ".color"); + if (col != null) { + recipe.color = PotionColor.fromString(col); + } else { + recipe.color = PotionColor.CYAN; + } + if (recipe.color == PotionColor.WATER && !col.equals("WATER")) { + recipe.color = PotionColor.CYAN; + // Don't throw error here as old mc versions will not know even the default colors + //P.p.errorLog("Invalid Color '" + col + "' in Cauldron-Recipe: " + recipe.name); + //return null; + } + + + List> lore = BRecipe.loadLore(cfg, id + ".lore"); + if (lore != null && !lore.isEmpty()) { + recipe.lore = lore.stream().map(Tuple::second).collect(Collectors.toList()); + } + + return recipe; + } + + @NotNull + public String getName() { + return name; + } + + @NotNull + public List> getIngredients() { + return ingredients; + } + + @NotNull + public PotionColor getColor() { + return color; + } + + @Nullable + public List getLore() { + return lore; + } + + /** + * Find how much these ingredients match the given ones from 0-10. + * If any ingredient is missing, returns 0 + * If all Ingredients and their amounts are equal, returns 10 + * Returns something between 0 and 10 if all ingredients present, but differing amounts, depending on how much the amount differs. + */ + public float getIngredientMatch(List items) { + if (items.size() < ingredients.size()) { + return 0; + } + float match = 10; + search: for (Tuple ing : ingredients) { + for (ItemStack item : items) { + if (ing.a().matches(item)) { + double difference = Math.abs(ing.b() - item.getAmount()); + if (difference >= 1000) { + return 0; + } + // The Item Amount is the determining part here, the higher the better. + // But let the difference in amount to what the recipe expects have a tiny factor as well. + // This way for the same amount, the recipe with the lower difference wins. + double factor = item.getAmount() * (1.0 - (difference / 1000.0)) ; + //double mod = 0.1 + (0.9 * Math.exp(-0.03 * difference)); // logarithmic curve from 1 to 0.1 + double mod = 1 + (0.9 * -Math.exp(-0.03 * factor)); // logarithmic curve from 0.1 to 1, small for a low factor + + P.p.debugLog("Mod for " + ing.a() + "/" + ing.b() + ": " + mod); + assert mod >= 0.1; + assert mod <= 1; // TODO Test + + + + + match *= mod; + continue search; + } + } + return 0; + } + if (items.size() > ingredients.size()) { + // If there are too many items in the List, multiply the match by 0.1 per Item thats too much + float tooMuch = items.size() - ingredients.size(); + float mod = 0.1f / tooMuch; + match *= mod; + } + P.p.debugLog("Match for Cauldron Recipe " + name + ": " + match); + return match; + } + + @Override + public String toString() { + return "BCauldronRecipe{" + name + '}'; + } +} diff --git a/src/com/dre/brewery/BIngredients.java b/src/com/dre/brewery/BIngredients.java index 873dcc5..9d3b0fd 100644 --- a/src/com/dre/brewery/BIngredients.java +++ b/src/com/dre/brewery/BIngredients.java @@ -7,21 +7,21 @@ import org.bukkit.Material; import org.bukkit.configuration.ConfigurationSection; import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.meta.PotionMeta; +import org.jetbrains.annotations.Nullable; import java.io.DataInputStream; import java.io.DataOutputStream; import java.io.IOException; -import java.util.*; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; public class BIngredients { - public static Set possibleIngredients = new HashSet<>(); - public static ArrayList recipes = new ArrayList<>(); - public static Map cookedNames = new HashMap<>(); private static int lastId = 0; private int id; // Legacy private List ingredients = new ArrayList<>(); - private Map materials = new HashMap<>(); // Merged List Of ingredients that doesnt consider Durability private int cookedTime; // Represents ingredients in Cauldron, Brew @@ -37,10 +37,6 @@ public class BIngredients { this.cookedTime = cookedTime; //this.id = lastId; //lastId++; - - for (ItemStack item : ingredients) { - addMaterial(item); - } } // Load from legacy Brew section @@ -54,7 +50,6 @@ public class BIngredients { // Add an ingredient to this public void add(ItemStack ingredient) { - addMaterial(ingredient); for (ItemStack item : ingredients) { if (item.isSimilar(ingredient)) { item.setAmount(item.getAmount() + ingredient.getAmount()); @@ -64,20 +59,12 @@ public class BIngredients { ingredients.add(ingredient); } - private void addMaterial(ItemStack ingredient) { - if (materials.containsKey(ingredient.getType())) { - int newAmount = materials.get(ingredient.getType()) + ingredient.getAmount(); - materials.put(ingredient.getType(), newAmount); - } else { - materials.put(ingredient.getType(), ingredient.getAmount()); - } - } - // returns an Potion item with cooked ingredients public ItemStack cook(int state) { ItemStack potion = new ItemStack(Material.POTION); PotionMeta potionMeta = (PotionMeta) potion.getItemMeta(); + assert potionMeta != null; // cookedTime is always time in minutes, state may differ with number of ticks cookedTime = state; @@ -96,11 +83,11 @@ public class BIngredients { lore.updateQualityStars(false); lore.updateCustomLore(); lore.updateAlc(false); - lore.addOrReplaceEffects(brew.getEffects(), brew.getQuality()); + lore.write(); cookedName = cookRecipe.getName(quality); - PotionColor.fromString(cookRecipe.getColor()).colorBrew(potionMeta, potion, false); + cookRecipe.getColor().colorBrew(potionMeta, potion, false); } else { // new base potion @@ -110,14 +97,16 @@ public class BIngredients { cookedName = P.p.languageReader.get("Brew_ThickBrew"); PotionColor.BLUE.colorBrew(potionMeta, potion, false); } else { - for (Material ingredient : materials.keySet()) { - if (cookedNames.containsKey(ingredient)) { - // if more than half of the ingredients is of one kind - if (materials.get(ingredient) > (getIngredientsCount() / 2)) { - cookedName = cookedNames.get(ingredient); - PotionColor.CYAN.colorBrew(potionMeta, potion, true); - } + BCauldronRecipe cauldronRecipe = getCauldronRecipe(); + if (cauldronRecipe != null) { + P.p.debugLog("Found Cauldron Recipe: " + cauldronRecipe.getName()); + cookedName = cauldronRecipe.getName(); + if (cauldronRecipe.getLore() != null) { + BrewLore lore = new BrewLore(brew, potionMeta); + lore.addCauldronLore(cauldronRecipe.getLore()); + lore.write(); } + cauldronRecipe.getColor().colorBrew(potionMeta, potion, true); } } } @@ -174,7 +163,7 @@ public class BIngredients { int woodQuality; int ageQuality; BRecipe bestRecipe = null; - for (BRecipe recipe : recipes) { + for (BRecipe recipe : BRecipe.recipes) { ingredientQuality = getIngredientQuality(recipe); cookingQuality = getCookingQuality(recipe, distilled); @@ -221,9 +210,29 @@ public class BIngredients { return null; } - // returns the currently best matching recipe for distilling for the - // ingredients and cooking time - public BRecipe getdistillRecipe(float wood, float time) { + /** + * Get Cauldron Recipe that matches the contents of the cauldron + */ + @Nullable + public BCauldronRecipe getCauldronRecipe() { + BCauldronRecipe best = null; + float bestMatch = 0; + float match; + for (BCauldronRecipe recipe : BCauldronRecipe.recipes) { + match = recipe.getIngredientMatch(ingredients); + if (match >= 10) { + return recipe; + } + if (match > bestMatch) { + best = recipe; + bestMatch = match; + } + } + return best; + } + + // returns the currently best matching recipe for distilling for the ingredients and cooking time + public BRecipe getDistillRecipe(float wood, float time) { BRecipe bestRecipe = getBestRecipe(wood, time, true); // Check if best recipe needs to be destilled @@ -235,8 +244,7 @@ public class BIngredients { return null; } - // returns currently best matching recipe for ingredients, cooking- and - // ageingtime + // returns currently best matching recipe for ingredients, cooking- and ageingtime public BRecipe getAgeRecipe(float wood, float time, boolean distilled) { BRecipe bestRecipe = getBestRecipe(wood, time, distilled); @@ -248,8 +256,7 @@ public class BIngredients { return null; } - // returns the quality of the ingredients conditioning given recipe, -1 if - // no recipe is near them + // returns the quality of the ingredients conditioning given recipe, -1 if no recipe is near them public int getIngredientQuality(BRecipe recipe) { float quality = 10; int count; @@ -258,20 +265,9 @@ public class BIngredients { // when ingredients are not complete return -1; } - ArrayList mergedChecked = new ArrayList<>(); for (ItemStack ingredient : ingredients) { - if (mergedChecked.contains(ingredient.getType())) { - // This ingredient type was already checked as part of a merged material - continue; - } int amountInRecipe = recipe.amountOf(ingredient); - // If we dont consider durability for this ingredient, check the merged material - if (recipe.hasExactData(ingredient)) { - count = ingredient.getAmount(); - } else { - mergedChecked.add(ingredient.getType()); - count = materials.get(ingredient.getType()); - } + count = ingredient.getAmount(); if (amountInRecipe == 0) { // this ingredient doesnt belong into the recipe if (count > (getIngredientsCount() / 2)) { @@ -346,8 +342,7 @@ public class BIngredients { if (!(obj instanceof BIngredients)) return false; BIngredients other = ((BIngredients) obj); return cookedTime == other.cookedTime && - ingredients.equals(other.ingredients) && - materials.equals(other.materials); + ingredients.equals(other.ingredients); } // Creates a copy ingredients @@ -355,11 +350,10 @@ public class BIngredients { public BIngredients clone() { try { super.clone(); - } catch (CloneNotSupportedException ingored) { + } catch (CloneNotSupportedException ignored) { } BIngredients copy = new BIngredients(); copy.ingredients.addAll(ingredients); - copy.materials.putAll(materials); copy.cookedTime = cookedTime; return copy; } diff --git a/src/com/dre/brewery/BRecipe.java b/src/com/dre/brewery/BRecipe.java index 6ce49e9..2e107ce 100644 --- a/src/com/dre/brewery/BRecipe.java +++ b/src/com/dre/brewery/BRecipe.java @@ -1,121 +1,195 @@ package com.dre.brewery; import com.dre.brewery.filedata.BConfig; +import com.dre.brewery.utility.CustomItem; import com.dre.brewery.utility.PotionColor; import com.dre.brewery.utility.Tuple; import org.bukkit.Material; import org.bukkit.configuration.ConfigurationSection; -import org.bukkit.craftbukkit.libs.jline.internal.Nullable; import org.bukkit.inventory.ItemStack; -import org.jetbrains.annotations.Contract; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; import java.util.ArrayList; import java.util.List; +import java.util.stream.Collectors; public class BRecipe { + public static List recipes = new ArrayList<>(); + private String[] name; - private ArrayList ingredients = new ArrayList<>(); // material and amount + private List> ingredients = new ArrayList<>(); // Items and amounts private int cookingTime; // time to cook in cauldron private byte distillruns; // runs through the brewer private int distillTime; // time for one distill run in seconds private byte wood; // type of wood the barrel has to consist of private int age; // time in minecraft days for the potions to age in barrels - private String color; // color of the destilled/finished potion + private PotionColor color; // color of the destilled/finished potion private int difficulty; // difficulty to brew the potion, how exact the instruction has to be followed private int alcohol; // Alcohol in perfect potion private List> lore; // Custom Lore on the Potion. The int is for Quality Lore, 0 = any, 1,2,3 = Bad,Middle,Good private ArrayList effects = new ArrayList<>(); // Special Effects when drinking - public BRecipe(ConfigurationSection configSectionRecipes, String recipeId) { + public BRecipe() { + } + + @Nullable + public static BRecipe fromConfig(ConfigurationSection configSectionRecipes, String recipeId) { + BRecipe recipe = new BRecipe(); String nameList = configSectionRecipes.getString(recipeId + ".name"); if (nameList != null) { String[] name = nameList.split("/"); if (name.length > 2) { - this.name = name; + recipe.name = name; } else { - this.name = new String[1]; - this.name[0] = name[0]; + recipe.name = new String[1]; + recipe.name[0] = name[0]; } } else { - return; + P.p.errorLog(recipeId + ": Recipe Name missing or invalid!"); + return null; } - List ingredientsList = configSectionRecipes.getStringList(recipeId + ".ingredients"); - if (ingredientsList != null) { - for (String item : ingredientsList) { - String[] ingredParts = item.split("/"); - if (ingredParts.length == 2) { - String[] matParts; - if (ingredParts[0].contains(",")) { - matParts = ingredParts[0].split(","); - } else if (ingredParts[0].contains(":")) { - matParts = ingredParts[0].split(":"); - } else if (ingredParts[0].contains(";")) { - matParts = ingredParts[0].split(";"); - } else { - matParts = ingredParts[0].split("\\."); - } - Material mat = Material.matchMaterial(matParts[0]); - short durability = -1; - if (matParts.length == 2) { - durability = (short) P.p.parseInt(matParts[1]); - } - if (mat == null && BConfig.hasVault) { - try { - net.milkbowl.vault.item.ItemInfo vaultItem = net.milkbowl.vault.item.Items.itemByString(matParts[0]); - if (vaultItem != null) { - mat = vaultItem.getType(); - if (durability == -1 && vaultItem.getSubTypeId() != 0) { - durability = vaultItem.getSubTypeId(); - } - if (mat.name().contains("LEAVES")) { - if (durability > 3) { - durability -= 4; // Vault has leaves with higher durability - } - } - } - } catch (Exception e) { - P.p.errorLog("Could not check vault for Item Name"); - e.printStackTrace(); - } - } - if (mat != null) { - ItemStack stack = new ItemStack(mat, P.p.parseInt(ingredParts[1]), durability); - this.ingredients.add(stack); - BIngredients.possibleIngredients.add(mat); - } else { - P.p.errorLog("Unknown Material: " + ingredParts[0]); - this.ingredients = null; - return; - } + if (recipe.getRecipeName() == null || recipe.getRecipeName().length() < 1) { + P.p.errorLog(recipeId + ": Recipe Name invalid"); + return null; + } + + recipe.ingredients = loadIngredients(configSectionRecipes, recipeId); + if (recipe.ingredients == null || recipe.ingredients.isEmpty()) { + P.p.errorLog("No ingredients for: " + recipe.getRecipeName()); + return null; + } + recipe.cookingTime = configSectionRecipes.getInt(recipeId + ".cookingtime", 1); + int dis = configSectionRecipes.getInt(recipeId + ".distillruns", 0); + if (dis > Byte.MAX_VALUE) { + recipe.distillruns = Byte.MAX_VALUE; + } else { + recipe.distillruns = (byte) dis; + } + recipe.distillTime = configSectionRecipes.getInt(recipeId + ".distilltime", 0) * 20; + recipe.wood = (byte) configSectionRecipes.getInt(recipeId + ".wood", 0); + recipe.age = configSectionRecipes.getInt(recipeId + ".age", 0); + recipe.difficulty = configSectionRecipes.getInt(recipeId + ".difficulty", 0); + recipe.alcohol = configSectionRecipes.getInt(recipeId + ".alcohol", 0); + + String col = configSectionRecipes.getString(recipeId + ".color", "BLUE"); + recipe.color = PotionColor.fromString(col); + if (recipe.color == PotionColor.WATER && !col.equals("WATER")) { + P.p.errorLog("Invalid Color '" + col + "' in Recipe: " + recipe.getRecipeName()); + return null; + } + + recipe.lore = loadLore(configSectionRecipes, recipeId + ".lore"); + + List effectStringList = configSectionRecipes.getStringList(recipeId + ".effects"); + if (effectStringList != null) { + for (String effectString : effectStringList) { + BEffect effect = new BEffect(effectString); + if (effect.isValid()) { + recipe.effects.add(effect); } else { - return; + P.p.errorLog("Error adding Effect to Recipe: " + recipe.getRecipeName()); } } } - this.cookingTime = configSectionRecipes.getInt(recipeId + ".cookingtime", 1); - int dis = configSectionRecipes.getInt(recipeId + ".distillruns", 0); - if (dis > Byte.MAX_VALUE) { - this.distillruns = Byte.MAX_VALUE; - } else { - this.distillruns = (byte) dis; - } - this.distillTime = configSectionRecipes.getInt(recipeId + ".distilltime", 0) * 20; - this.wood = (byte) configSectionRecipes.getInt(recipeId + ".wood", 0); - this.age = configSectionRecipes.getInt(recipeId + ".age", 0); - this.color = configSectionRecipes.getString(recipeId + ".color"); - this.difficulty = configSectionRecipes.getInt(recipeId + ".difficulty", 0); - this.alcohol = configSectionRecipes.getInt(recipeId + ".alcohol", 0); + return recipe; + } + public static List> loadIngredients(ConfigurationSection cfg, String recipeId) { + List ingredientsList; + if (cfg.isString(recipeId + ".ingredients")) { + ingredientsList = new ArrayList<>(1); + ingredientsList.add(cfg.getString(recipeId + ".ingredients", "x")); + } else { + ingredientsList = cfg.getStringList(recipeId + ".ingredients"); + } + if (ingredientsList == null) { + return null; + } + List> ingredients = new ArrayList<>(ingredientsList.size()); + listLoop: for (String item : ingredientsList) { + String[] ingredParts = item.split("/"); + int amount = 1; + if (ingredParts.length == 2) { + amount = P.p.parseInt(ingredParts[1]); + if (amount < 1) { + P.p.errorLog(recipeId + ": Invalid Item Amount: " + ingredParts[1]); + return null; + } + } + String[] matParts; + if (ingredParts[0].contains(",")) { + matParts = ingredParts[0].split(","); + } else if (ingredParts[0].contains(":")) { + matParts = ingredParts[0].split(":"); + } else if (ingredParts[0].contains(";")) { + matParts = ingredParts[0].split(";"); + } else { + matParts = ingredParts[0].split("\\."); + } + + // Try to find this Ingredient as Custom Item + for (CustomItem custom : BConfig.customItems) { + if (custom.getId().equalsIgnoreCase(matParts[0])) { + ingredients.add(new Tuple<>(custom, amount)); + BCauldronRecipe.acceptedMaterials.addAll(custom.getMaterials()); + continue listLoop; + } + } + + Material mat = Material.matchMaterial(matParts[0]); + short durability = -1; + if (matParts.length == 2) { + durability = (short) P.p.parseInt(matParts[1]); + } + if (mat == null && BConfig.hasVault) { + try { + net.milkbowl.vault.item.ItemInfo vaultItem = net.milkbowl.vault.item.Items.itemByString(matParts[0]); + if (vaultItem != null) { + mat = vaultItem.getType(); + if (durability == -1 && vaultItem.getSubTypeId() != 0) { + durability = vaultItem.getSubTypeId(); + } + if (mat.name().contains("LEAVES")) { + if (durability > 3) { + durability -= 4; // Vault has leaves with higher durability + } + } + } + } catch (Exception e) { + P.p.errorLog("Could not check vault for Item Name"); + e.printStackTrace(); + } + } + if (mat != null) { + CustomItem custom; + if (durability > -1) { + custom = CustomItem.asSimpleItem(mat, durability); + } else { + custom = CustomItem.asSimpleItem(mat); + } + ingredients.add(new Tuple<>(custom, amount)); + BCauldronRecipe.acceptedMaterials.add(mat); + } else { + P.p.errorLog(recipeId + ": Unknown Material: " + ingredParts[0]); + return null; + } + } + return ingredients; + } + + @Nullable + public static List> loadLore(ConfigurationSection cfg, String path) { List load = null; - if (configSectionRecipes.isString(recipeId + ".lore")) { + if (cfg.isString(path)) { load = new ArrayList<>(1); - load.add(configSectionRecipes.getString(recipeId + ".lore")); - } else if (configSectionRecipes.isList(recipeId + ".lore")) { - load = configSectionRecipes.getStringList(recipeId + ".lore"); + load.add(cfg.getString(path)); + } else if (cfg.isList(path)) { + load = cfg.getStringList(path); } if (load != null) { + List> lore = new ArrayList<>(load.size()); for (String line : load) { line = P.p.color(line); int plus = 0; @@ -135,34 +209,15 @@ public class BRecipe { if (!line.startsWith("§")) { line = "§9" + line; } - if (lore == null) lore = new ArrayList<>(); lore.add(new Tuple<>(plus, line)); } + return lore; } - - List effectStringList = configSectionRecipes.getStringList(recipeId + ".effects"); - if (effectStringList != null) { - for (String effectString : effectStringList) { - BEffect effect = new BEffect(effectString); - if (effect.isValid()) { - effects.add(effect); - } else { - P.p.errorLog("Error adding Effect to Recipe: " + getRecipeName()); - } - } - } + return null; } // check every part of the recipe for validity public boolean isValid() { - if (name == null || name.length < 1) { - P.p.errorLog("Recipe Name missing or invalid!"); - return false; - } - if (getRecipeName() == null || getRecipeName().length() < 1) { - P.p.errorLog("Recipe Name invalid"); - return false; - } if (ingredients == null || ingredients.isEmpty()) { P.p.errorLog("No ingredients could be loaded for Recipe: " + getRecipeName()); return false; @@ -187,11 +242,6 @@ public class BRecipe { P.p.errorLog("Invalid age time '" + age + "' in Recipe: " + getRecipeName()); return false; } - String c = getColor(); - if (!c.equals("WATER") && PotionColor.fromString(c) == PotionColor.WATER) { - P.p.errorLog("Invalid Color '" + color + "' in Recipe: " + getRecipeName()); - return false; - } if (difficulty < 0 || difficulty > 10) { P.p.errorLog("Invalid difficulty '" + difficulty + "' in Recipe: " + getRecipeName()); return false; @@ -251,10 +301,10 @@ public class BRecipe { if (list.size() < ingredients.size()) { return true; } - for (ItemStack ingredient : ingredients) { + for (Tuple ingredient : ingredients) { boolean matches = false; for (ItemStack used : list) { - if (ingredientsMatch(used, ingredient)) { + if (ingredient.a().matches(used)) { matches = true; break; } @@ -266,24 +316,6 @@ public class BRecipe { return false; } - // Returns true if this ingredient cares about durability - public boolean hasExactData(ItemStack item) { - for (ItemStack ingredient : ingredients) { - if (ingredient.getType().equals(item.getType())) { - return ingredient.getDurability() != -1; - } - } - return true; - } - - // Returns true if this item matches the item from a recipe - public static boolean ingredientsMatch(ItemStack usedItem, ItemStack recipeItem) { - if (!recipeItem.getType().equals(usedItem.getType())) { - return false; - } - return recipeItem.getDurability() == -1 || recipeItem.getDurability() == usedItem.getDurability(); - } - /** * Create a Potion from this Recipe with best values. Quality can be set, but will reset to 10 if put in a barrel * @@ -301,14 +333,7 @@ public class BRecipe { * @return The created Brew */ public Brew createBrew(int quality) { - ArrayList list = new ArrayList<>(ingredients.size()); - for (ItemStack item : ingredients) { - if (item.getDurability() == -1) { - list.add(new ItemStack(item.getType(), item.getAmount())); - } else { - list.add(item.clone()); - } - } + List list = ingredients.stream().map(ing -> ing.a().createDummy(ing.b())).collect(Collectors.toList()); BIngredients bIngredients = new BIngredients(list, cookingTime); @@ -320,9 +345,9 @@ public class BRecipe { // how many of a specific ingredient in the recipe public int amountOf(ItemStack item) { - for (ItemStack ingredient : ingredients) { - if (ingredientsMatch(item, ingredient)) { - return ingredient.getAmount(); + for (Tuple ingredient : ingredients) { + if (ingredient.a().matches(item)) { + return ingredient.b(); } } return 0; @@ -371,11 +396,8 @@ public class BRecipe { } @NotNull - public String getColor() { - if (color != null) { - return color.toUpperCase(); - } - return "BLUE"; + public PotionColor getColor() { + return color; } // get the woodtype @@ -434,7 +456,7 @@ public class BRecipe { } public static BRecipe get(String name) { - for (BRecipe recipe : BIngredients.recipes) { + for (BRecipe recipe : recipes) { if (recipe.getRecipeName().equalsIgnoreCase(name)) { return recipe; } diff --git a/src/com/dre/brewery/Brew.java b/src/com/dre/brewery/Brew.java index 69b4e6d..d23ef3e 100644 --- a/src/com/dre/brewery/Brew.java +++ b/src/com/dre/brewery/Brew.java @@ -194,7 +194,7 @@ public class Brew { public boolean setRecipeFromString(String name) { currentRecipe = null; if (name != null && !name.equals("")) { - for (BRecipe recipe : BIngredients.recipes) { + for (BRecipe recipe : BRecipe.recipes) { if (recipe.getRecipeName().equalsIgnoreCase(name)) { currentRecipe = recipe; return true; @@ -458,9 +458,9 @@ public class Brew { this.immutable = immutable; if (currentRecipe != null && canDistill()) { if (immutable) { - PotionColor.fromString(currentRecipe.getColor()).colorBrew(((PotionMeta) potion.getItemMeta()), potion, false); + currentRecipe.getColor().colorBrew(((PotionMeta) potion.getItemMeta()), potion, false); } else { - PotionColor.fromString(currentRecipe.getColor()).colorBrew(((PotionMeta) potion.getItemMeta()), potion, true); + currentRecipe.getColor().colorBrew(((PotionMeta) potion.getItemMeta()), potion, true); } } } @@ -488,7 +488,7 @@ public class Brew { distillRuns += 1; BrewLore lore = new BrewLore(this, potionMeta); - BRecipe recipe = ingredients.getdistillRecipe(wood, ageTime); + BRecipe recipe = ingredients.getDistillRecipe(wood, ageTime); if (recipe != null) { // distillRuns will have an effect on the amount of alcohol, not the quality currentRecipe = recipe; @@ -496,7 +496,7 @@ public class Brew { lore.addOrReplaceEffects(getEffects(), quality); potionMeta.setDisplayName(P.p.color("&f" + recipe.getName(quality))); - PotionColor.fromString(recipe.getColor()).colorBrew(potionMeta, slotItem, canDistill()); + recipe.getColor().colorBrew(potionMeta, slotItem, canDistill()); } else { quality = 0; @@ -506,14 +506,13 @@ public class Brew { } // Distill Lore - if (currentRecipe != null) { - if (BConfig.colorInBrewer != BrewLore.hasColorLore(potionMeta)) { - lore.convertLore(BConfig.colorInBrewer); - } + if (currentRecipe != null && BConfig.colorInBrewer != BrewLore.hasColorLore(potionMeta)) { + lore.convertLore(BConfig.colorInBrewer); + } else { lore.updateQualityStars(BConfig.colorInBrewer); lore.updateCustomLore(); + lore.updateDistillLore(BConfig.colorInBrewer); } - lore.updateDistillLore(BConfig.colorInBrewer); lore.updateAlc(true); lore.write(); touch(); @@ -538,7 +537,7 @@ public class Brew { return currentRecipe.getDistillTime(); } - BRecipe recipe = ingredients.getdistillRecipe(wood, ageTime); + BRecipe recipe = ingredients.getDistillRecipe(wood, ageTime); if (recipe != null) { return recipe.getDistillTime(); } @@ -568,7 +567,7 @@ public class Brew { lore.addOrReplaceEffects(getEffects(), quality); potionMeta.setDisplayName(P.p.color("&f" + recipe.getName(quality))); - PotionColor.fromString(recipe.getColor()).colorBrew(potionMeta, item, canDistill()); + recipe.getColor().colorBrew(potionMeta, item, canDistill()); } else { quality = 0; lore.removeEffects(); @@ -578,21 +577,20 @@ public class Brew { } // Lore - if (currentRecipe != null) { - if (BConfig.colorInBarrels != BrewLore.hasColorLore(potionMeta)) { - lore.convertLore(BConfig.colorInBarrels); + if (currentRecipe != null && BConfig.colorInBarrels != BrewLore.hasColorLore(potionMeta)) { + lore.convertLore(BConfig.colorInBarrels); + } else { + if (ageTime >= 1) { + lore.updateAgeLore(BConfig.colorInBarrels); } - } - if (ageTime >= 1) { - lore.updateAgeLore(BConfig.colorInBarrels); - } - if (ageTime > 0.5) { - if (BConfig.colorInBarrels && !unlabeled && currentRecipe != null) { - lore.updateWoodLore(true); + if (ageTime > 0.5) { + if (BConfig.colorInBarrels && !unlabeled && currentRecipe != null) { + lore.updateWoodLore(true); + } + lore.updateQualityStars(BConfig.colorInBarrels); + lore.updateCustomLore(); + lore.updateAlc(false); } - lore.updateQualityStars(BConfig.colorInBarrels); - lore.updateCustomLore(); - lore.updateAlc(false); } lore.write(); touch(); @@ -652,12 +650,12 @@ public class Brew { recipe = getCurrentRecipe(); } if (recipe == null) { - throw new IllegalArgumentException("Recipe can't be null if the brew doesn't have a currentRecipe"); + throw new IllegalArgumentException("Argument recipe can't be null if the brew doesn't have a currentRecipe"); } ItemStack potion = new ItemStack(Material.POTION); PotionMeta potionMeta = (PotionMeta) potion.getItemMeta(); - PotionColor.fromString(recipe.getColor()).colorBrew(potionMeta, potion, false); + recipe.getColor().colorBrew(potionMeta, potion, false); potionMeta.setDisplayName(P.p.color("&f" + recipe.getName(quality))); //if (!P.use1_14) { // Before 1.14 the effects duration would strangely be only a quarter of what we tell it to be @@ -762,15 +760,15 @@ public class Brew { if ((bools & 4) != 0) { wood = in.readFloat(); } + String recipe = null; if ((bools & 8) != 0) { - setRecipeFromString(in.readUTF()); - } else { - setRecipeFromString(null); + recipe = in.readUTF(); } unlabeled = (bools & 16) != 0; //persistent = (bools & 32) != 0; immutable = (bools & 32) != 0; ingredients = BIngredients.load(in); + setRecipeFromString(recipe); } // Save brew data into meta: lore/nbt @@ -895,7 +893,7 @@ public class Brew { if (hasRecipe()) { BrewLore lore = new BrewLore(this, potionMeta); lore.removeEffects(); - PotionColor.fromString(currentRecipe.getColor()).colorBrew(potionMeta, item, canDistill()); + currentRecipe.getColor().colorBrew(potionMeta, item, canDistill()); lore.removeLegacySpacing(); } else { PotionColor.GREY.colorBrew(potionMeta, item, canDistill()); diff --git a/src/com/dre/brewery/P.java b/src/com/dre/brewery/P.java index 57e5782..1a9cf2b 100644 --- a/src/com/dre/brewery/P.java +++ b/src/com/dre/brewery/P.java @@ -440,9 +440,10 @@ public class P extends JavaPlugin { // delete Data from Ram Barrel.barrels.clear(); BCauldron.bcauldrons.clear(); - BIngredients.possibleIngredients.clear(); - BIngredients.recipes.clear(); - BIngredients.cookedNames.clear(); + BRecipe.recipes.clear(); + BCauldronRecipe.acceptedMaterials.clear(); + BCauldronRecipe.recipes.clear(); + BConfig.customItems.clear(); BPlayer.clear(); Brew.legacyPotions.clear(); Wakeup.wakeups.clear(); @@ -458,9 +459,10 @@ public class P extends JavaPlugin { BConfig.reloader = sender; } // clear all existent config Data - BIngredients.possibleIngredients.clear(); - BIngredients.recipes.clear(); - BIngredients.cookedNames.clear(); + BRecipe.recipes.clear(); + BCauldronRecipe.acceptedMaterials.clear(); + BCauldronRecipe.recipes.clear(); + BConfig.customItems.clear(); DistortChat.words.clear(); DistortChat.ignoreText.clear(); DistortChat.commands = null; diff --git a/src/com/dre/brewery/filedata/BConfig.java b/src/com/dre/brewery/filedata/BConfig.java index f7ea235..03fe142 100644 --- a/src/com/dre/brewery/filedata/BConfig.java +++ b/src/com/dre/brewery/filedata/BConfig.java @@ -2,10 +2,11 @@ package com.dre.brewery.filedata; import com.dre.brewery.*; import com.dre.brewery.integration.WGBarrel; -import com.dre.brewery.integration.WGBarrel7; -import com.dre.brewery.integration.WGBarrel6; import com.dre.brewery.integration.WGBarrel5; +import com.dre.brewery.integration.WGBarrel6; +import com.dre.brewery.integration.WGBarrel7; import com.dre.brewery.utility.BUtil; +import com.dre.brewery.utility.CustomItem; import org.bukkit.Bukkit; import org.bukkit.Material; import org.bukkit.command.CommandSender; @@ -18,6 +19,7 @@ import org.bukkit.plugin.PluginManager; import java.io.File; import java.io.IOException; import java.io.InputStream; +import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; @@ -58,6 +60,9 @@ public class BConfig { public static boolean alwaysShowQuality; // Always show quality stars public static boolean alwaysShowAlc; // Always show alc% + //Item + public static List customItems = new ArrayList<>(); + public static P p = P.p; private static boolean checkConfigs() { @@ -184,40 +189,41 @@ public class BConfig { Brew.loadSeed(config, file); + // Loading custom items + ConfigurationSection configSection = config.getConfigurationSection("customItems"); + if (configSection != null) { + for (String custId : configSection.getKeys(false)) { + CustomItem custom = CustomItem.fromConfig(configSection, custId); + if (custom != null) { + customItems.add(custom); + } else { + p.errorLog("Loading the Custom Item with id: '" + custId + "' failed!"); + } + } + } + // loading recipes - ConfigurationSection configSection = config.getConfigurationSection("recipes"); + configSection = config.getConfigurationSection("recipes"); if (configSection != null) { for (String recipeId : configSection.getKeys(false)) { - BRecipe recipe = new BRecipe(configSection, recipeId); - if (recipe.isValid()) { - BIngredients.recipes.add(recipe); + BRecipe recipe = BRecipe.fromConfig(configSection, recipeId); + if (recipe != null && recipe.isValid()) { + BRecipe.recipes.add(recipe); } else { p.errorLog("Loading the Recipe with id: '" + recipeId + "' failed!"); } } } - // loading cooked names and possible ingredients - configSection = config.getConfigurationSection("cooked"); + // Loading Cauldron Recipes + configSection = config.getConfigurationSection("cauldron"); if (configSection != null) { - for (String ingredient : configSection.getKeys(false)) { - Material mat = Material.matchMaterial(ingredient); - if (mat == null && hasVault) { - try { - net.milkbowl.vault.item.ItemInfo vaultItem = net.milkbowl.vault.item.Items.itemByString(ingredient); - if (vaultItem != null) { - mat = vaultItem.getType(); - } - } catch (Exception e) { - P.p.errorLog("Could not check vault for Item Name"); - e.printStackTrace(); - } - } - if (mat != null) { - BIngredients.cookedNames.put(mat, (configSection.getString(ingredient, null))); - BIngredients.possibleIngredients.add(mat); + for (String id : configSection.getKeys(false)) { + BCauldronRecipe recipe = BCauldronRecipe.fromConfig(configSection, id); + if (recipe != null) { + BCauldronRecipe.recipes.add(recipe); } else { - p.errorLog("Unknown Material: " + ingredient); + p.errorLog("Loading the Cauldron-Recipe with id: '" + id + "' failed!"); } } } diff --git a/src/com/dre/brewery/listeners/CommandListener.java b/src/com/dre/brewery/listeners/CommandListener.java index 12dbf7d..be9f50c 100644 --- a/src/com/dre/brewery/listeners/CommandListener.java +++ b/src/com/dre/brewery/listeners/CommandListener.java @@ -378,7 +378,6 @@ public class CommandListener implements CommandExecutor { } @Deprecated - @SuppressWarnings("deprecation") public void cmdCopy(CommandSender sender, int count) { if (!(sender instanceof Player)) { @@ -415,7 +414,6 @@ public class CommandListener implements CommandExecutor { } @Deprecated - @SuppressWarnings("deprecation") public void cmdDelete(CommandSender sender) { if (!(sender instanceof Player)) { @@ -441,7 +439,6 @@ public class CommandListener implements CommandExecutor { } @Deprecated - @SuppressWarnings("deprecation") public void cmdPersist(CommandSender sender) { if (!(sender instanceof Player)) { @@ -496,6 +493,7 @@ public class CommandListener implements CommandExecutor { } brew.touch(); ItemMeta meta = hand.getItemMeta(); + assert meta != null; BrewModifyEvent modifyEvent = new BrewModifyEvent(brew, meta, BrewModifyEvent.Type.STATIC); P.p.getServer().getPluginManager().callEvent(modifyEvent); if (modifyEvent.isCancelled()) { @@ -526,6 +524,7 @@ public class CommandListener implements CommandExecutor { brew.unLabel(hand); brew.touch(); ItemMeta meta = hand.getItemMeta(); + assert meta != null; BrewModifyEvent modifyEvent = new BrewModifyEvent(brew, meta, BrewModifyEvent.Type.UNLABEL); P.p.getServer().getPluginManager().callEvent(modifyEvent); if (modifyEvent.isCancelled()) { @@ -607,7 +606,7 @@ public class CommandListener implements CommandExecutor { } BRecipe recipe = null; - for (BRecipe r : BIngredients.recipes) { + for (BRecipe r : BRecipe.recipes) { if (r.hasName(name)) { recipe = r; break; diff --git a/src/com/dre/brewery/lore/BrewLore.java b/src/com/dre/brewery/lore/BrewLore.java index 293cab6..8251fa8 100644 --- a/src/com/dre/brewery/lore/BrewLore.java +++ b/src/com/dre/brewery/lore/BrewLore.java @@ -1,6 +1,10 @@ package com.dre.brewery.lore; -import com.dre.brewery.*; +import com.dre.brewery.BEffect; +import com.dre.brewery.BIngredients; +import com.dre.brewery.BRecipe; +import com.dre.brewery.Brew; +import com.dre.brewery.P; import com.dre.brewery.filedata.BConfig; import com.dre.brewery.utility.BUtil; import org.bukkit.inventory.meta.PotionMeta; @@ -81,6 +85,22 @@ public class BrewLore { } }*/ + /** + * Add the list of strings as custom lore for the base potion coming out of the cauldron + */ + public void addCauldronLore(List l) { + int index = -1; + for (String line : l) { + if (index == -1) { + index = addLore(Type.CUSTOM, "", line); + index++; + } else { + lore.add(index, Type.CUSTOM.id + line); + index++; + } + } + } + /** * updates the IngredientLore * @@ -179,16 +199,11 @@ public class BrewLore { * updates the Custom Lore */ public void updateCustomLore() { - int index = Type.CUSTOM.findInLore(lore); - - while (index > -1) { - lore.remove(index); - index = Type.CUSTOM.findInLore(lore); - } + removeLore(Type.CUSTOM); BRecipe recipe = brew.getCurrentRecipe(); if (recipe != null && recipe.hasLore()) { - index = -1; + int index = -1; for (String line : recipe.getLoreForQuality(brew.getQuality())) { if (index == -1) { index = addLore(Type.CUSTOM, "", line); @@ -198,11 +213,6 @@ public class BrewLore { index++; } } - - /*if (index < lore.size()) { - // If there are more lines after this, add a spacer - lore.add(index, Type.SPACE.id); - }*/ } } @@ -229,7 +239,7 @@ public class BrewLore { } public void updateAlc(boolean inDistiller) { - if (!brew.isUnlabeled() && (inDistiller || BConfig.alwaysShowAlc)) { + if (!brew.isUnlabeled() && (inDistiller || BConfig.alwaysShowAlc) && (!brew.hasRecipe() || brew.getCurrentRecipe().getAlcohol() > 0)) { int alc = brew.calcAlcohol(); addOrReplaceLore(Type.ALC, "§8", P.p.languageReader.get("Brew_Alc", alc + "")); } else { @@ -333,10 +343,20 @@ public class BrewLore { * Searches for type and removes it */ public void removeLore(Type type) { - int index = type.findInLore(lore); - if (index > -1) { - lineAddedOrRem = true; - lore.remove(index); + if (type != Type.CUSTOM) { + int index = type.findInLore(lore); + if (index > -1) { + lineAddedOrRem = true; + lore.remove(index); + } + } else { + // Lore could have multiple lines of this type + for (int i = lore.size() - 1; i >= 0; i--) { + if (Type.get(lore.get(i)) == type) { + lore.remove(i); + lineAddedOrRem = true; + } + } } } @@ -347,6 +367,7 @@ public class BrewLore { for (int i = lore.size() - 1; i >= 0; i--) { if (Type.get(lore.get(i)) != null) { lore.remove(i); + lineAddedOrRem = true; } } } diff --git a/src/com/dre/brewery/utility/CustomItem.java b/src/com/dre/brewery/utility/CustomItem.java new file mode 100644 index 0000000..8ec6849 --- /dev/null +++ b/src/com/dre/brewery/utility/CustomItem.java @@ -0,0 +1,329 @@ +package com.dre.brewery.utility; + +import com.dre.brewery.P; +import com.dre.brewery.filedata.BConfig; +import org.bukkit.ChatColor; +import org.bukkit.Material; +import org.bukkit.configuration.ConfigurationSection; +import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.meta.ItemMeta; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.util.ArrayList; +import java.util.List; +import java.util.stream.Collectors; + +public class CustomItem { + private String id; + private boolean simple; // Simple Custom Item is just materials.get(0) and durability for old mc + private boolean matchAny; // If only one of the values needs to match + private short dur; // Old Mc + private List materials; + private List names; + private List lore; + + public static CustomItem asSimpleItem(Material mat) { + return asSimpleItem(mat, (short) 0); + } + + public static CustomItem asSimpleItem(Material mat, short dur) { + CustomItem it = new CustomItem(); + it.simple = true; + it.dur = dur; + it.materials = new ArrayList<>(1); + it.materials.add(mat); + return it; + } + + @Nullable + public static CustomItem fromConfig(ConfigurationSection cfg, String id) { + CustomItem custom = new CustomItem(); + + custom.id = id; + custom.matchAny = cfg.getBoolean(id + ".matchAny", false); + + List load = null; + String path = id + ".material"; + if (cfg.isString(path)) { + load = new ArrayList<>(1); + load.add(cfg.getString(path)); + } else if (cfg.isList(path)) { + load = cfg.getStringList(path); + } + if (load != null && !load.isEmpty()) { + custom.materials = new ArrayList<>(load.size()); + if (!custom.loadMaterials(load)) { + return null; + } + } else { + custom.materials = new ArrayList<>(0); + } + + load = null; + path = id + ".name"; + if (cfg.isString(path)) { + load = new ArrayList<>(1); + load.add(cfg.getString(path)); + } else if (cfg.isList(path)) { + load = cfg.getStringList(path); + } + if (load != null && !load.isEmpty()) { + custom.names = load.stream().map(l -> P.p.color(l)).collect(Collectors.toList()); + if (P.use1_13) { + // In 1.13 trailing Color white is removed from display names + custom.names = custom.names.stream().map(l -> l.startsWith("§f") ? l.substring(2) : l).collect(Collectors.toList()); + } + } else { + custom.names = new ArrayList<>(0); + } + + load = null; + path = id + ".lore"; + if (cfg.isString(path)) { + load = new ArrayList<>(1); + load.add(cfg.getString(path)); + } else if (cfg.isList(path)) { + load = cfg.getStringList(path); + } + if (load != null && !load.isEmpty()) { + custom.lore = load.stream().map(l -> P.p.color(l)).collect(Collectors.toList()); + } else { + custom.lore = new ArrayList<>(0); + } + + if (custom.materials.isEmpty() && custom.names.isEmpty() && custom.lore.isEmpty()) { + P.p.errorLog("No Config Entries found for Custom Item"); + return null; + } + + return custom; + } + + private boolean loadMaterials(List ingredientsList) { + for (String item : ingredientsList) { + String[] ingredParts = item.split("/"); + if (ingredParts.length == 2) { + P.p.errorLog("Item Amount can not be specified for Custom Items: " + item); + return false; + } + Material mat = Material.matchMaterial(ingredParts[0]); + + if (mat == null && BConfig.hasVault) { + try { + net.milkbowl.vault.item.ItemInfo vaultItem = net.milkbowl.vault.item.Items.itemByString(ingredParts[0]); + if (vaultItem != null) { + mat = vaultItem.getType(); + } + } catch (Exception e) { + P.p.errorLog("Could not check vault for Item Name"); + e.printStackTrace(); + } + } + if (mat != null) { + materials.add(mat); + } else { + P.p.errorLog("Unknown Material: " + ingredParts[0]); + return false; + } + } + return true; + } + + public String getId() { + return id; + } + + public boolean isSimple() { + return simple; + } + + public boolean isMatchAny() { + return matchAny; + } + + public List getMaterials() { + return materials; + } + + public Material getSimpleMaterial() { + return materials.get(0); + } + + public List getNames() { + return names; + } + + public List getLore() { + return lore; + } + + public boolean matches(ItemStack usedItem) { + if (simple) { + return matchSimple(usedItem); + } else if (matchAny){ + return matchAny(usedItem); + } else { + return matchOne(usedItem); + } + } + + private boolean matchSimple(ItemStack usedItem) { + if (!materials.get(0).equals(usedItem.getType())) { + return false; + } + //noinspection deprecation + return P.use1_13 || dur == usedItem.getDurability(); + } + + private boolean matchAny(ItemStack usedItem) { + Material usedMat = usedItem.getType(); + for (Material mat : materials) { + if (usedMat == mat) { + return true; + } + } + if (!usedItem.hasItemMeta()) { + return false; + } + ItemMeta meta = usedItem.getItemMeta(); + assert meta != null; + if (meta.hasDisplayName()) { + String usedName = meta.getDisplayName(); + for (String name : names) { + if (name.equalsIgnoreCase(usedName)) { + return true; + } + } + } + + if (meta.hasLore()) { + List usedLore = meta.getLore(); + assert usedLore != null; + for (String line : this.lore) { + for (String usedLine : usedLore) { + if (line.equalsIgnoreCase(usedLine) || line.equalsIgnoreCase(ChatColor.stripColor(usedLine))) { + return true; + } + } + } + } + return false; + } + + private boolean matchOne(ItemStack item) { + if (!materials.isEmpty()) { + if (item.getType() != materials.get(0)) { + return false; + } + } + if (names.isEmpty() && lore.isEmpty()) { + return true; + } + if (!item.hasItemMeta()) { + return false; + } + ItemMeta meta = item.getItemMeta(); + assert meta != null; + if (!names.isEmpty()) { + if (!meta.hasDisplayName() || !names.get(0).equalsIgnoreCase(meta.getDisplayName())) { + return false; + } + } + + + if (!lore.isEmpty()) { + if (!meta.hasLore()) { + return false; + } + + int lastIndex = 0; + List usedLore = meta.getLore(); + assert usedLore != null; + boolean foundFirst = false; + for (String line : lore) { + do { + if (lastIndex == usedLore.size()) { + // There is more in lore than in usedLore, bad + return false; + } + String usedLine = usedLore.get(lastIndex); + if (line.equalsIgnoreCase(usedLine) || line.equalsIgnoreCase(ChatColor.stripColor(usedLine))) { + // If the line is correct, we have found our first and we want all consecutive lines to also equal + foundFirst = true; + } else if (foundFirst) { + // If a consecutive line is not equal, thats bad + return false; + } + lastIndex++; + // If we once found one correct line, iterate over 'lore' consecutively + } while (!foundFirst); + } + } + return true; + } + + @NotNull + public ItemStack createDummy(int amount) { + if (simple) { + if (P.use1_13) { + return new ItemStack(getSimpleMaterial(), amount); + } else { + //noinspection deprecation + return new ItemStack(getSimpleMaterial(), amount, dur); + } + } else if (matchAny) { + if (!materials.isEmpty()) { + return new ItemStack(materials.get(0), amount); + } else if (!names.isEmpty()) { + ItemStack item = new ItemStack(Material.DIAMOND_HOE, amount); + ItemMeta meta = item.hasItemMeta() ? item.getItemMeta() : P.p.getServer().getItemFactory().getItemMeta(Material.DIAMOND_HOE); + assert meta != null; + meta.setDisplayName(names.get(0)); + item.setItemMeta(meta); + return item; + } else if (!lore.isEmpty()) { + ItemStack item = new ItemStack(Material.DIAMOND_HOE, amount); + ItemMeta meta = item.hasItemMeta() ? item.getItemMeta() : P.p.getServer().getItemFactory().getItemMeta(Material.DIAMOND_HOE); + assert meta != null; + List l = new ArrayList<>(); + l.add(lore.get(0)); + meta.setLore(l); + item.setItemMeta(meta); + return item; + } + return new ItemStack(Material.DIAMOND_HOE, amount); + } else { + ItemStack item; + ItemMeta meta; + if (!materials.isEmpty()) { + item = new ItemStack(materials.get(0), amount); + meta = item.hasItemMeta() ? item.getItemMeta() : P.p.getServer().getItemFactory().getItemMeta(materials.get(0)); + } else { + item = new ItemStack(Material.DIAMOND_HOE, amount); + meta = item.hasItemMeta() ? item.getItemMeta() : P.p.getServer().getItemFactory().getItemMeta(Material.DIAMOND_HOE); + } + assert meta != null; + if (!names.isEmpty()) { + meta.setDisplayName(names.get(0)); + item.setItemMeta(meta); + } + if (!lore.isEmpty()) { + meta.setLore(lore); + item.setItemMeta(meta); + } + return item; + } + } + + @Override + public String toString() { + if (simple) { + return "CustomItem{Simple: " + getSimpleMaterial().name().toLowerCase() + "}"; + } + if (materials == null || names == null || lore == null) { + return "CustomItem{" + id + "}"; + } + return "CustomItem{" + id + ": " + (matchAny ? "MatchAny, " : "MatchOne, ") + materials.size() + " Materials, " + names.size() + " Names, " + lore.size() + " Lore}"; + } +} diff --git a/src/com/dre/brewery/utility/Tuple.java b/src/com/dre/brewery/utility/Tuple.java index 2d50c92..e388de5 100644 --- a/src/com/dre/brewery/utility/Tuple.java +++ b/src/com/dre/brewery/utility/Tuple.java @@ -27,21 +27,21 @@ */ package com.dre.brewery.utility; -public class Tuple { +public class Tuple { /** * The first value in the tuple */ - private final X x; + private final A a; /** * The second value in the tuple */ - private final Y y; + private final B b; - public Tuple(X x, Y y) { - this.x = x; - this.y = y; + public Tuple(A a, B b) { + this.a = a; + this.b = b; } /** @@ -49,8 +49,8 @@ public class Tuple { * * @return */ - public X first() { - return x; + public A first() { + return a; } /** @@ -58,8 +58,26 @@ public class Tuple { * * @return */ - public Y second() { - return y; + public B second() { + return b; + } + + /** + * Gets the first value in the tuple, Synonym for first() + * + * @return + */ + public A a() { + return a; + } + + /** + * Gets the second value in the tuple, Synonym for second() + * + * @return + */ + public B b() { + return b; } @Override @@ -69,12 +87,12 @@ public class Tuple { } Tuple tuple = (Tuple) object; - return tuple.x == x && tuple.y == y; + return tuple.a == a && tuple.b == b; } @Override public int hashCode() { - return x.hashCode() ^ y.hashCode(); + return a.hashCode() ^ b.hashCode(); } } diff --git a/test/com/dre/brewery/RecipeTests.java b/test/com/dre/brewery/RecipeTests.java new file mode 100644 index 0000000..284d325 --- /dev/null +++ b/test/com/dre/brewery/RecipeTests.java @@ -0,0 +1,50 @@ +package com.dre.brewery; + +import org.bukkit.Material; +import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.meta.ItemMeta; + +import java.util.ArrayList; +import java.util.List; + +public class RecipeTests { + + public static void testCauldronRecipe() { + ItemStack item = new ItemStack(Material.BARRIER); + ItemMeta itemMeta = item.getItemMeta(); + List l = new ArrayList<>(); + l.add("Eine Tür"); + l.add("§6Besonders gut geschützt"); + itemMeta.setLore(l); + itemMeta.setDisplayName("Mauer"); + item.setItemMeta(itemMeta); + + BRecipe recipe = BRecipe.get("Beispiel"); + int x = recipe.amountOf(item); + int y = recipe.amountOf(new ItemStack(Material.NETHER_BRICK)); + + + List list = new ArrayList<>(); + list.add(new ItemStack(Material.DIAMOND_HOE, 3)); + list.add(new ItemStack(Material.RED_MUSHROOM, 1)); + for (int i = 1; i < 20; i++) { + list.get(0).setAmount(i + 3); + list.get(1).setAmount(i); + BCauldronRecipe best = null; + float bestMatch = 0; + float match; + for (BCauldronRecipe r : BCauldronRecipe.recipes) { + match = r.getIngredientMatch(list); + if (match >= 10) { + P.p.debugLog("Found match 10 Recipe: " + r); + return; + } + if (match > bestMatch) { + best = r; + bestMatch = match; + } + } + P.p.debugLog("Found best for i:" + i + " " + best); + } + } +} From 7f2f9d75dd1cf99d73646682e32e3e5347d5ab6a Mon Sep 17 00:00:00 2001 From: Sn0wStorm Date: Wed, 6 Nov 2019 19:44:52 +0100 Subject: [PATCH 30/51] Rewrite of the Custom item into RecipeItem and Ingredient with subclasses Implemented adding custom items to Ingredients Added support for plugin-items --- pom.xml | 16 +- resources/config/v13/de/config.yml | 6 +- resources/config/v13/en/config.yml | 4 + src/com/dre/brewery/BCauldron.java | 79 +++-- src/com/dre/brewery/BIngredients.java | 97 ++++-- src/com/dre/brewery/BPlayer.java | 1 + src/com/dre/brewery/Barrel.java | 2 +- src/com/dre/brewery/Brew.java | 23 +- src/com/dre/brewery/P.java | 12 +- src/com/dre/brewery/api/BreweryApi.java | 2 +- .../brewery/api/events/IngedientAddEvent.java | 19 +- src/com/dre/brewery/filedata/BConfig.java | 35 +- src/com/dre/brewery/filedata/BData.java | 319 +++++++++-------- src/com/dre/brewery/filedata/DataSave.java | 2 +- .../integration/IntegrationListener.java | 46 ++- .../{ => barrel}/CitadelBarrel.java | 12 +- .../{ => barrel}/GriefPreventionBarrel.java | 2 +- .../integration/{ => barrel}/LWCBarrel.java | 2 +- .../{ => barrel}/LogBlockBarrel.java | 2 +- .../integration/{ => barrel}/WGBarrel.java | 2 +- .../integration/{ => barrel}/WGBarrel5.java | 2 +- .../integration/{ => barrel}/WGBarrel6.java | 2 +- .../integration/{ => barrel}/WGBarrel7.java | 2 +- .../integration/item/BreweryPluginItem.java | 30 ++ .../integration/item/MMOItemsPluginItem.java | 32 ++ .../integration/item/SlimefunPluginItem.java | 35 ++ .../brewery/listeners/CommandListener.java | 1 + .../dre/brewery/listeners/WorldListener.java | 4 +- src/com/dre/brewery/lore/BrewLore.java | 4 +- .../brewery/{ => recipe}/BCauldronRecipe.java | 65 +++- src/com/dre/brewery/{ => recipe}/BEffect.java | 3 +- src/com/dre/brewery/{ => recipe}/BRecipe.java | 101 ++++-- src/com/dre/brewery/recipe/CustomItem.java | 291 ++++++++++++++++ .../brewery/recipe/CustomMatchAnyItem.java | 231 ++++++++++++ src/com/dre/brewery/recipe/Ingredient.java | 88 +++++ src/com/dre/brewery/recipe/ItemLoader.java | 28 ++ src/com/dre/brewery/recipe/PluginItem.java | 213 ++++++++++++ src/com/dre/brewery/recipe/RecipeItem.java | 314 +++++++++++++++++ src/com/dre/brewery/recipe/SimpleItem.java | 151 ++++++++ src/com/dre/brewery/utility/CustomItem.java | 329 ------------------ test/com/dre/brewery/RecipeTests.java | 25 +- 41 files changed, 2010 insertions(+), 624 deletions(-) rename src/com/dre/brewery/integration/{ => barrel}/CitadelBarrel.java (95%) rename src/com/dre/brewery/integration/{ => barrel}/GriefPreventionBarrel.java (96%) rename src/com/dre/brewery/integration/{ => barrel}/LWCBarrel.java (98%) rename src/com/dre/brewery/integration/{ => barrel}/LogBlockBarrel.java (99%) rename src/com/dre/brewery/integration/{ => barrel}/WGBarrel.java (81%) rename src/com/dre/brewery/integration/{ => barrel}/WGBarrel5.java (97%) rename src/com/dre/brewery/integration/{ => barrel}/WGBarrel6.java (95%) rename src/com/dre/brewery/integration/{ => barrel}/WGBarrel7.java (98%) create mode 100644 src/com/dre/brewery/integration/item/BreweryPluginItem.java create mode 100644 src/com/dre/brewery/integration/item/MMOItemsPluginItem.java create mode 100644 src/com/dre/brewery/integration/item/SlimefunPluginItem.java rename src/com/dre/brewery/{ => recipe}/BCauldronRecipe.java (67%) rename src/com/dre/brewery/{ => recipe}/BEffect.java (98%) rename src/com/dre/brewery/{ => recipe}/BRecipe.java (80%) create mode 100644 src/com/dre/brewery/recipe/CustomItem.java create mode 100644 src/com/dre/brewery/recipe/CustomMatchAnyItem.java create mode 100644 src/com/dre/brewery/recipe/Ingredient.java create mode 100644 src/com/dre/brewery/recipe/ItemLoader.java create mode 100644 src/com/dre/brewery/recipe/PluginItem.java create mode 100644 src/com/dre/brewery/recipe/RecipeItem.java create mode 100644 src/com/dre/brewery/recipe/SimpleItem.java delete mode 100644 src/com/dre/brewery/utility/CustomItem.java diff --git a/pom.xml b/pom.xml index 1a66a85..fd2ea62 100644 --- a/pom.xml +++ b/pom.xml @@ -14,6 +14,7 @@ src + test @@ -87,7 +88,7 @@ http://maven.sk89q.com/repo/ - + jitpack.io https://jitpack.io @@ -226,6 +227,19 @@ + + com.github.TheBusyBiscuit + Slimefun4 + 4bb9abd247 + provided + + + + com.dre + ExtPluginBridge + 1.0 + provided + org.bstats bstats-bukkit diff --git a/resources/config/v13/de/config.yml b/resources/config/v13/de/config.yml index fb0f925..686080d 100644 --- a/resources/config/v13/de/config.yml +++ b/resources/config/v13/de/config.yml @@ -192,6 +192,8 @@ cauldron: # Halte ein Item in der Hand und benutze /brew ItemName um dessen Material herauszufinden und für ein Rezept zu benutzen # (Item-ids anstatt Material können in Bukkit nicht mehr benutzt werden) # Eine Liste von allen Materialien kann hier gefunden werden: https://hub.spigotmc.org/javadocs/spigot/org/bukkit/Material.html +# Plugin Items mit 'Plugin:Id' (Im Moment ExoticGarden, Slimefun, MMOItems, Brewery) +# Oder ein oben definiertes Custom Item # cookingtime: Zeit in Echtminuten die die Zutaten kochen müssen # distillruns: Wie oft destilliert werden muss für vollen Alkoholgehalt (0=ohne Destillieren) # distilltime: Wie lange (in sekunden) ein Destillations-Durchlauf braucht (0=Standard Zeit von 40 sek) MC Standard wäre 20 sek @@ -219,8 +221,8 @@ recipes: - Diamond/1 - Spruce_Planks/8 - Bedrock/1 -# - Brewery:Weißbier/2 -# - ExoticGarden:Grape/3 + - Brewery:Weißbier/2 +# - ExoticGarden:Grape/3 - bsp-item/1 cookingtime: 3 distillruns: 2 diff --git a/resources/config/v13/en/config.yml b/resources/config/v13/en/config.yml index 3e5050f..fdd0ed9 100644 --- a/resources/config/v13/en/config.yml +++ b/resources/config/v13/en/config.yml @@ -193,6 +193,8 @@ cauldron: # With an item in your hand, use /brew ItemName to get its material for use in a recipe # (Item-ids instead of material are not supported by bukkit anymore and will not work) # A list of materials can be found here: https://hub.spigotmc.org/javadocs/spigot/org/bukkit/Material.html +# Plugin items with 'plugin:id' (Currently supporting ExoticGarden, Slimefun, MMOItems, Brewery) +# Or a custom item defined above # cookingtime: Time in real minutes ingredients have to boil # distillruns: How often it has to be distilled for full alcohol (0=without distilling) # distilltime: How long (in seconds) one distill-run takes (0=Default time of 40 sec) MC Default would be 20 sec @@ -220,6 +222,8 @@ recipes: - Diamond/1 - Spruce_Planks/8 - Bedrock/1 + - Brewery:Wheatbeer/2 +# - ExoticGarden:Grape/3 cookingtime: 3 distillruns: 2 distilltime: 60 diff --git a/src/com/dre/brewery/BCauldron.java b/src/com/dre/brewery/BCauldron.java index 3552f66..b8558f2 100644 --- a/src/com/dre/brewery/BCauldron.java +++ b/src/com/dre/brewery/BCauldron.java @@ -1,6 +1,8 @@ package com.dre.brewery; import com.dre.brewery.api.events.IngedientAddEvent; +import com.dre.brewery.recipe.BCauldronRecipe; +import com.dre.brewery.recipe.RecipeItem; import com.dre.brewery.utility.BUtil; import com.dre.brewery.utility.LegacyUtil; import org.bukkit.Effect; @@ -28,7 +30,7 @@ public class BCauldron { private BIngredients ingredients = new BIngredients(); private final Block block; private int state = 1; - private boolean someRemoved = false; + private boolean changed = false; public BCauldron(Block block) { this.block = block; @@ -48,22 +50,22 @@ public class BCauldron { if (!BUtil.isChunkLoaded(block) || LegacyUtil.isFireForCauldron(block.getRelative(BlockFace.DOWN))) { // add a minute to cooking time state++; - if (someRemoved) { - ingredients = ingredients.clone(); - someRemoved = false; + if (changed) { + ingredients = ingredients.copy(); + changed = false; } } } // add an ingredient to the cauldron - public void add(ItemStack ingredient) { + public void add(ItemStack ingredient, RecipeItem rItem) { if (ingredient == null || ingredient.getType() == Material.AIR) return; - if (someRemoved) { // TODO no need to clone - ingredients = ingredients.clone(); - someRemoved = false; + if (changed) { + ingredients = ingredients.copy(); + changed = false; } - ingredient = new ItemStack(ingredient.getType(), 1, ingredient.getDurability()); - ingredients.add(ingredient); + + ingredients.add(ingredient, rItem); block.getWorld().playEffect(block.getLocation(), Effect.EXTINGUISH, 0); if (state > 1) { state--; @@ -90,10 +92,20 @@ public class BCauldron { bcauldron = new BCauldron(block); } - IngedientAddEvent event = new IngedientAddEvent(player, block, bcauldron, ingredient); + if (!BCauldronRecipe.acceptedMaterials.contains(ingredient.getType()) && !ingredient.hasItemMeta()) { + // Extremely fast way to check for most items + return false; + } + // If the Item is on the list, or customized, we have to do more checks + RecipeItem rItem = RecipeItem.getMatchingRecipeItem(ingredient, false); + if (rItem == null) { + return false; + } + + IngedientAddEvent event = new IngedientAddEvent(player, block, bcauldron, ingredient.clone(), rItem); P.p.getServer().getPluginManager().callEvent(event); if (!event.isCancelled()) { - bcauldron.add(event.getIngredient()); + bcauldron.add(event.getIngredient(), event.getRecipeItem()); return event.willTakeItem(); } else { return false; @@ -127,7 +139,7 @@ public class BCauldron { if (cauldron.getLevel() <= 0) { bcauldrons.remove(this); } else { - someRemoved = true; + changed = true; } } else { @@ -144,7 +156,7 @@ public class BCauldron { if (data == 0) { bcauldrons.remove(this); } else { - someRemoved = true; + changed = true; } } // Bukkit Bug, inventory not updating while in event so this @@ -250,30 +262,25 @@ public class BCauldron { } if (item == null) return; - // add ingredient to cauldron that meet the previous conditions - if (BCauldronRecipe.acceptedMaterials.contains(materialInHand)) { + if (!player.hasPermission("brewery.cauldron.insert")) { + P.p.msg(player, P.p.languageReader.get("Perms_NoCauldronInsert")); + return; + } + if (ingredientAdd(clickedBlock, item, player)) { + boolean isBucket = item.getType().equals(Material.WATER_BUCKET) + || item.getType().equals(Material.LAVA_BUCKET) + || item.getType().equals(Material.MILK_BUCKET); + if (item.getAmount() > 1) { + item.setAmount(item.getAmount() - 1); - if (!player.hasPermission("brewery.cauldron.insert")) { - P.p.msg(player, P.p.languageReader.get("Perms_NoCauldronInsert")); - return; - } - - if (ingredientAdd(clickedBlock, item, player)) { - boolean isBucket = item.getType().equals(Material.WATER_BUCKET) - || item.getType().equals(Material.LAVA_BUCKET) - || item.getType().equals(Material.MILK_BUCKET); - if (item.getAmount() > 1) { - item.setAmount(item.getAmount() - 1); - - if (isBucket) { - giveItem(player, new ItemStack(Material.BUCKET)); - } + if (isBucket) { + giveItem(player, new ItemStack(Material.BUCKET)); + } + } else { + if (isBucket) { + setItemInHand(event, Material.BUCKET, handSwap); } else { - if (isBucket) { - setItemInHand(event, Material.BUCKET, handSwap); - } else { - setItemInHand(event, Material.AIR, handSwap); - } + setItemInHand(event, Material.AIR, handSwap); } } } diff --git a/src/com/dre/brewery/BIngredients.java b/src/com/dre/brewery/BIngredients.java index 9d3b0fd..e301a52 100644 --- a/src/com/dre/brewery/BIngredients.java +++ b/src/com/dre/brewery/BIngredients.java @@ -1,7 +1,13 @@ package com.dre.brewery; import com.dre.brewery.api.events.brew.BrewModifyEvent; +import com.dre.brewery.lore.Base91EncoderStream; import com.dre.brewery.lore.BrewLore; +import com.dre.brewery.recipe.BCauldronRecipe; +import com.dre.brewery.recipe.BRecipe; +import com.dre.brewery.recipe.Ingredient; +import com.dre.brewery.recipe.ItemLoader; +import com.dre.brewery.recipe.RecipeItem; import com.dre.brewery.utility.PotionColor; import org.bukkit.Material; import org.bukkit.configuration.ConfigurationSection; @@ -9,19 +15,18 @@ import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.meta.PotionMeta; import org.jetbrains.annotations.Nullable; +import java.io.ByteArrayOutputStream; import java.io.DataInputStream; import java.io.DataOutputStream; import java.io.IOException; import java.util.ArrayList; -import java.util.HashMap; import java.util.List; -import java.util.Map; public class BIngredients { - private static int lastId = 0; + private static int lastId = 0; // Legacy private int id; // Legacy - private List ingredients = new ArrayList<>(); + private List ingredients = new ArrayList<>(); private int cookedTime; // Represents ingredients in Cauldron, Brew @@ -32,7 +37,7 @@ public class BIngredients { } // Load from File - public BIngredients(List ingredients, int cookedTime) { + public BIngredients(List ingredients, int cookedTime) { this.ingredients = ingredients; this.cookedTime = cookedTime; //this.id = lastId; @@ -40,7 +45,7 @@ public class BIngredients { } // Load from legacy Brew section - public BIngredients(List ingredients, int cookedTime, boolean legacy) { + public BIngredients(List ingredients, int cookedTime, boolean legacy) { this(ingredients, cookedTime); if (legacy) { this.id = lastId; @@ -48,15 +53,32 @@ public class BIngredients { } } - // Add an ingredient to this + // Force add an ingredient to this + // Will not check if item is acceptable public void add(ItemStack ingredient) { - for (ItemStack item : ingredients) { - if (item.isSimilar(ingredient)) { - item.setAmount(item.getAmount() + ingredient.getAmount()); + for (Ingredient existing : ingredients) { + if (existing.matches(ingredient)) { + existing.setAmount(existing.getAmount() + 1); return; } } - ingredients.add(ingredient); + + Ingredient ing = RecipeItem.getMatchingRecipeItem(ingredient, true).toIngredient(ingredient); + ing.setAmount(1); + ingredients.add(ing); + } + + // Add an ingredient to this with corresponding RecipeItem + public void add(ItemStack ingredient, RecipeItem rItem) { + Ingredient ingredientItem = rItem.toIngredient(ingredient); + for (Ingredient existing : ingredients) { + if (existing.isSimilar(ingredientItem)) { + existing.setAmount(existing.getAmount() + 1); + return; + } + } + ingredientItem.setAmount(1); + ingredients.add(ingredientItem); } // returns an Potion item with cooked ingredients @@ -140,8 +162,8 @@ public class BIngredients { // returns amount of ingredients public int getIngredientsCount() { int count = 0; - for (ItemStack item : ingredients) { - count += item.getAmount(); + for (Ingredient ing : ingredients) { + count += ing.getAmount(); } return count; } @@ -265,7 +287,7 @@ public class BIngredients { // when ingredients are not complete return -1; } - for (ItemStack ingredient : ingredients) { + for (Ingredient ingredient : ingredients) { int amountInRecipe = recipe.amountOf(ingredient); count = ingredient.getAmount(); if (amountInRecipe == 0) { @@ -346,12 +368,7 @@ public class BIngredients { } // Creates a copy ingredients - @Override - public BIngredients clone() { - try { - super.clone(); - } catch (CloneNotSupportedException ignored) { - } + public BIngredients copy() { BIngredients copy = new BIngredients(); copy.ingredients.addAll(ingredients); copy.cookedTime = cookedTime; @@ -399,21 +416,25 @@ public class BIngredients { public void save(DataOutputStream out) throws IOException { out.writeInt(cookedTime); out.writeByte(ingredients.size()); - for (ItemStack item : ingredients) { - out.writeUTF(item.getType().name()); - out.writeShort(item.getAmount()); - out.writeShort(item.getDurability()); + for (Ingredient ing : ingredients) { + ing.saveTo(out); + out.writeShort(Math.min(ing.getAmount(), Short.MAX_VALUE)); } } - public static BIngredients load(DataInputStream in) throws IOException { + public static BIngredients load(DataInputStream in, short dataVersion) throws IOException { int cookedTime = in.readInt(); byte size = in.readByte(); - List ing = new ArrayList<>(size); + List ing = new ArrayList<>(size); for (; size > 0; size--) { - Material mat = Material.getMaterial(in.readUTF()); - if (mat != null) { - ing.add(new ItemStack(mat, in.readShort(), in.readShort())); + ItemLoader itemLoader = new ItemLoader(dataVersion, in, in.readUTF()); + if (Ingredient.LOADERS.containsKey(itemLoader.getSaveID())) { + Ingredient loaded = Ingredient.LOADERS.get(itemLoader.getSaveID()).apply(itemLoader); + int amount = in.readShort(); + if (loaded != null) { + loaded.setAmount(amount); + ing.add(loaded); + } } } return new BIngredients(ing, cookedTime); @@ -421,8 +442,7 @@ public class BIngredients { // saves data into main Ingredient section. Returns the save id // Only needed for legacy potions - @Deprecated - public int save(ConfigurationSection config) { + public int saveLegacy(ConfigurationSection config) { String path = "Ingredients." + id; if (cookedTime != 0) { config.set(path + ".cookedTime", cookedTime); @@ -432,13 +452,26 @@ public class BIngredients { } //convert the ingredient Material to String - public Map serializeIngredients() { + /*public Map serializeIngredients() { Map mats = new HashMap<>(); for (ItemStack item : ingredients) { String mat = item.getType().name() + "," + item.getDurability(); mats.put(mat, item.getAmount()); } return mats; + }*/ + + // Serialize Ingredients to String for storing in yml, ie for Cauldrons + public String serializeIngredients() { + ByteArrayOutputStream byteStream = new ByteArrayOutputStream(); + try (DataOutputStream out = new DataOutputStream(new Base91EncoderStream(byteStream))) { + out.writeByte(Brew.SAVE_VER); + save(out); + } catch (IOException e) { + e.printStackTrace(); + return ""; + } + return byteStream.toString(); } } diff --git a/src/com/dre/brewery/BPlayer.java b/src/com/dre/brewery/BPlayer.java index 7db9de3..cecfcc5 100644 --- a/src/com/dre/brewery/BPlayer.java +++ b/src/com/dre/brewery/BPlayer.java @@ -6,6 +6,7 @@ import com.dre.brewery.api.events.PlayerPukeEvent; import com.dre.brewery.api.events.PlayerPushEvent; import com.dre.brewery.api.events.brew.BrewDrinkEvent; import com.dre.brewery.filedata.BConfig; +import com.dre.brewery.recipe.BEffect; import com.dre.brewery.utility.BUtil; import org.apache.commons.lang.mutable.MutableInt; import org.bukkit.Location; diff --git a/src/com/dre/brewery/Barrel.java b/src/com/dre/brewery/Barrel.java index 0c07086..7f06861 100644 --- a/src/com/dre/brewery/Barrel.java +++ b/src/com/dre/brewery/Barrel.java @@ -5,7 +5,7 @@ import com.dre.brewery.api.events.barrel.BarrelCreateEvent; import com.dre.brewery.api.events.barrel.BarrelDestroyEvent; import com.dre.brewery.api.events.barrel.BarrelRemoveEvent; import com.dre.brewery.filedata.BConfig; -import com.dre.brewery.integration.LogBlockBarrel; +import com.dre.brewery.integration.barrel.LogBlockBarrel; import com.dre.brewery.lore.BrewLore; import com.dre.brewery.utility.BUtil; import com.dre.brewery.utility.BoundingBox; diff --git a/src/com/dre/brewery/Brew.java b/src/com/dre/brewery/Brew.java index d23ef3e..b882c63 100644 --- a/src/com/dre/brewery/Brew.java +++ b/src/com/dre/brewery/Brew.java @@ -4,6 +4,8 @@ import com.dre.brewery.api.events.brew.BrewModifyEvent; import com.dre.brewery.filedata.BConfig; import com.dre.brewery.filedata.ConfigUpdater; import com.dre.brewery.lore.*; +import com.dre.brewery.recipe.BEffect; +import com.dre.brewery.recipe.BRecipe; import com.dre.brewery.utility.PotionColor; import org.bukkit.Material; import org.bukkit.configuration.ConfigurationSection; @@ -26,6 +28,7 @@ import java.util.Map; public class Brew { // represents the liquid in the brewed Potions + public static final byte SAVE_VER = 1; private static long saveSeed; private static List prevSaveSeeds = new ArrayList<>(); // Save Seeds that have been used in the past, stored to decode brews made at that time public static Map legacyPotions = new HashMap<>(); @@ -207,10 +210,10 @@ public class Brew { if (!immutable) { this.quality = calcQuality(); } - P.p.log("Brew was made from Recipe: '" + name + "' which could not be found. '" + currentRecipe.getRecipeName() + "' used instead!"); + P.p.log("A Brew was made from Recipe: '" + name + "' which could not be found. '" + currentRecipe.getRecipeName() + "' used instead!"); return true; } else { - P.p.errorLog("Brew was made from Recipe: '" + name + "' which could not be found!"); + P.p.errorLog("A Brew was made from Recipe: '" + name + "' which could not be found!"); } } } @@ -570,7 +573,9 @@ public class Brew { recipe.getColor().colorBrew(potionMeta, item, canDistill()); } else { quality = 0; + lore.convertLore(false); lore.removeEffects(); + currentRecipe = null; potionMeta.setDisplayName(P.p.color("&f" + P.p.languageReader.get("Brew_BadPotion"))); PotionColor.GREY.colorBrew(potionMeta, item, canDistill()); } @@ -714,7 +719,7 @@ public class Brew { case 1: unscrambler.start(); - brew.loadFromStream(in); + brew.loadFromStream(in, ver); break; default: @@ -748,7 +753,7 @@ public class Brew { return null; } - private void loadFromStream(DataInputStream in) throws IOException { + private void loadFromStream(DataInputStream in, byte dataVersion) throws IOException { quality = in.readByte(); int bools = in.readUnsignedByte(); if ((bools & 1) != 0) { @@ -767,7 +772,7 @@ public class Brew { unlabeled = (bools & 16) != 0; //persistent = (bools & 32) != 0; immutable = (bools & 32) != 0; - ingredients = BIngredients.load(in); + ingredients = BIngredients.load(in, dataVersion); setRecipeFromString(recipe); } @@ -782,7 +787,7 @@ public class Brew { XORScrambleStream scrambler = new XORScrambleStream(itemSaveStream, saveSeed); try (DataOutputStream out = new DataOutputStream(scrambler)) { out.writeByte(86); // Parity/sanity - out.writeByte(1); // Version + out.writeByte(SAVE_VER); // Version if (BConfig.enableEncode) { scrambler.start(); } else { @@ -890,6 +895,7 @@ public class Brew { public void convertPre19(ItemStack item) { removeLegacy(item); PotionMeta potionMeta = ((PotionMeta) item.getItemMeta()); + assert potionMeta != null; if (hasRecipe()) { BrewLore lore = new BrewLore(this, potionMeta); lore.removeEffects(); @@ -905,8 +911,7 @@ public class Brew { // Saves all data // Legacy method to save to data file - @Deprecated - public static void save(ConfigurationSection config) { + public static void saveLegacy(ConfigurationSection config) { for (Map.Entry entry : legacyPotions.entrySet()) { int uid = entry.getKey(); Brew brew = entry.getValue(); @@ -940,7 +945,7 @@ public class Brew { idConfig.set("lastUpdate", brew.lastUpdate); } // save the ingredients - idConfig.set("ingId", brew.ingredients.save(config.getParent())); + idConfig.set("ingId", brew.ingredients.saveLegacy(config.getParent())); } } diff --git a/src/com/dre/brewery/P.java b/src/com/dre/brewery/P.java index 1a9cf2b..ca744a9 100644 --- a/src/com/dre/brewery/P.java +++ b/src/com/dre/brewery/P.java @@ -6,8 +6,10 @@ import com.dre.brewery.filedata.DataSave; import com.dre.brewery.filedata.LanguageReader; import com.dre.brewery.filedata.UpdateChecker; import com.dre.brewery.integration.IntegrationListener; -import com.dre.brewery.integration.LogBlockBarrel; +import com.dre.brewery.integration.barrel.LogBlockBarrel; import com.dre.brewery.listeners.*; +import com.dre.brewery.recipe.BCauldronRecipe; +import com.dre.brewery.recipe.BRecipe; import com.dre.brewery.utility.BUtil; import com.dre.brewery.utility.LegacyUtil; import org.apache.commons.lang.math.NumberUtils; @@ -442,8 +444,12 @@ public class P extends JavaPlugin { BCauldron.bcauldrons.clear(); BRecipe.recipes.clear(); BCauldronRecipe.acceptedMaterials.clear(); + BCauldronRecipe.acceptedCustom.clear(); + BCauldronRecipe.acceptedSimple.clear(); BCauldronRecipe.recipes.clear(); BConfig.customItems.clear(); + BConfig.hasSlimefun = null; + BConfig.hasMMOItems = null; BPlayer.clear(); Brew.legacyPotions.clear(); Wakeup.wakeups.clear(); @@ -461,8 +467,12 @@ public class P extends JavaPlugin { // clear all existent config Data BRecipe.recipes.clear(); BCauldronRecipe.acceptedMaterials.clear(); + BCauldronRecipe.acceptedCustom.clear(); + BCauldronRecipe.acceptedSimple.clear(); BCauldronRecipe.recipes.clear(); BConfig.customItems.clear(); + BConfig.hasSlimefun = null; + BConfig.hasMMOItems = null; DistortChat.words.clear(); DistortChat.ignoreText.clear(); DistortChat.commands = null; diff --git a/src/com/dre/brewery/api/BreweryApi.java b/src/com/dre/brewery/api/BreweryApi.java index 0a4d536..2f829ab 100644 --- a/src/com/dre/brewery/api/BreweryApi.java +++ b/src/com/dre/brewery/api/BreweryApi.java @@ -1,7 +1,7 @@ package com.dre.brewery.api; import com.dre.brewery.BCauldron; -import com.dre.brewery.BRecipe; +import com.dre.brewery.recipe.BRecipe; import com.dre.brewery.Barrel; import com.dre.brewery.Brew; import org.apache.commons.lang.NotImplementedException; diff --git a/src/com/dre/brewery/api/events/IngedientAddEvent.java b/src/com/dre/brewery/api/events/IngedientAddEvent.java index 60bde23..ecedda3 100644 --- a/src/com/dre/brewery/api/events/IngedientAddEvent.java +++ b/src/com/dre/brewery/api/events/IngedientAddEvent.java @@ -1,6 +1,7 @@ package com.dre.brewery.api.events; import com.dre.brewery.BCauldron; +import com.dre.brewery.recipe.RecipeItem; import com.dre.brewery.utility.LegacyUtil; import org.bukkit.block.Block; import org.bukkit.block.data.BlockData; @@ -21,14 +22,16 @@ public class IngedientAddEvent extends PlayerEvent implements Cancellable { private final Block block; private final BCauldron cauldron; private ItemStack ingredient; + private RecipeItem rItem; private boolean cancelled; private boolean takeItem = true; - public IngedientAddEvent(Player who, Block block, BCauldron bCauldron, ItemStack ingredient) { + public IngedientAddEvent(Player who, Block block, BCauldron bCauldron, ItemStack ingredient, RecipeItem rItem) { super(who); this.block = block; cauldron = bCauldron; - this.ingredient = ingredient.clone(); + this.rItem = rItem; + this.ingredient = ingredient; } public Block getBlock() { @@ -39,6 +42,15 @@ public class IngedientAddEvent extends PlayerEvent implements Cancellable { return cauldron; } + /** + * The Recipe item that matches the ingredient. + * This might not be the only recipe item that will match the ingredient + * Will be recalculated if the Ingredient is changed with the setIngredient Method + */ + public RecipeItem getRecipeItem() { + return rItem; + } + // Get the item currently being added to the cauldron by the player // Can be changed directly (mutable) or with the setter Method // The amount is ignored and always one added @@ -49,8 +61,11 @@ public class IngedientAddEvent extends PlayerEvent implements Cancellable { // Set the ingredient added to the cauldron to something else // Will always be accepted, even when not in a recipe or the cooked list // The amount is ignored and always one added + // This also recalculates the recipeItem! public void setIngredient(ItemStack ingredient) { this.ingredient = ingredient; + // The Ingredient has been changed. Recalculate RecipeItem! + rItem = RecipeItem.getMatchingRecipeItem(ingredient, true); } // If the amount of the item in the players hand should be decreased diff --git a/src/com/dre/brewery/filedata/BConfig.java b/src/com/dre/brewery/filedata/BConfig.java index 03fe142..8d6e60a 100644 --- a/src/com/dre/brewery/filedata/BConfig.java +++ b/src/com/dre/brewery/filedata/BConfig.java @@ -1,18 +1,29 @@ package com.dre.brewery.filedata; -import com.dre.brewery.*; -import com.dre.brewery.integration.WGBarrel; -import com.dre.brewery.integration.WGBarrel5; -import com.dre.brewery.integration.WGBarrel6; -import com.dre.brewery.integration.WGBarrel7; +import com.dre.brewery.Brew; +import com.dre.brewery.DistortChat; +import com.dre.brewery.MCBarrel; +import com.dre.brewery.P; +import com.dre.brewery.integration.barrel.WGBarrel; +import com.dre.brewery.integration.barrel.WGBarrel5; +import com.dre.brewery.integration.barrel.WGBarrel6; +import com.dre.brewery.integration.barrel.WGBarrel7; +import com.dre.brewery.integration.item.BreweryPluginItem; +import com.dre.brewery.integration.item.MMOItemsPluginItem; +import com.dre.brewery.integration.item.SlimefunPluginItem; +import com.dre.brewery.recipe.BCauldronRecipe; +import com.dre.brewery.recipe.BRecipe; +import com.dre.brewery.recipe.PluginItem; +import com.dre.brewery.recipe.RecipeItem; import com.dre.brewery.utility.BUtil; -import com.dre.brewery.utility.CustomItem; import org.bukkit.Bukkit; import org.bukkit.Material; import org.bukkit.command.CommandSender; import org.bukkit.configuration.ConfigurationSection; import org.bukkit.configuration.file.FileConfiguration; import org.bukkit.configuration.file.YamlConfiguration; +import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.meta.ItemMeta; import org.bukkit.plugin.Plugin; import org.bukkit.plugin.PluginManager; @@ -38,6 +49,8 @@ public class BConfig { public static boolean useGP; //GriefPrevention public static boolean hasVault; // Vault public static boolean useCitadel; // CivCraft/DevotedMC Citadel + public static Boolean hasSlimefun = null; // Slimefun ; Null if not checked + public static Boolean hasMMOItems = null; // MMOItems ; Null if not checked // Barrel public static boolean openEverywhere; @@ -61,7 +74,7 @@ public class BConfig { public static boolean alwaysShowAlc; // Always show alc% //Item - public static List customItems = new ArrayList<>(); + public static List customItems = new ArrayList<>(); public static P p = P.p; @@ -189,12 +202,18 @@ public class BConfig { Brew.loadSeed(config, file); + PluginItem.registerForConfig("brewery", BreweryPluginItem::new); + PluginItem.registerForConfig("mmoitems", MMOItemsPluginItem::new); + PluginItem.registerForConfig("slimefun", SlimefunPluginItem::new); + PluginItem.registerForConfig("exoticgarden", SlimefunPluginItem::new); + // Loading custom items ConfigurationSection configSection = config.getConfigurationSection("customItems"); if (configSection != null) { for (String custId : configSection.getKeys(false)) { - CustomItem custom = CustomItem.fromConfig(configSection, custId); + RecipeItem custom = RecipeItem.fromConfigCustom(configSection, custId); if (custom != null) { + custom.makeImmutable(); customItems.add(custom); } else { p.errorLog("Loading the Custom Item with id: '" + custId + "' failed!"); diff --git a/src/com/dre/brewery/filedata/BData.java b/src/com/dre/brewery/filedata/BData.java index 96209eb..3f4d6f7 100644 --- a/src/com/dre/brewery/filedata/BData.java +++ b/src/com/dre/brewery/filedata/BData.java @@ -1,6 +1,11 @@ package com.dre.brewery.filedata; import com.dre.brewery.*; +import com.dre.brewery.lore.Base91DecoderStream; +import com.dre.brewery.recipe.CustomItem; +import com.dre.brewery.recipe.Ingredient; +import com.dre.brewery.recipe.PluginItem; +import com.dre.brewery.recipe.SimpleItem; import com.dre.brewery.utility.BUtil; import com.dre.brewery.utility.BoundingBox; import org.apache.commons.lang.ArrayUtils; @@ -12,14 +17,12 @@ import org.bukkit.block.Block; import org.bukkit.configuration.ConfigurationSection; import org.bukkit.configuration.file.FileConfiguration; import org.bukkit.configuration.file.YamlConfiguration; -import org.bukkit.inventory.ItemStack; +import java.io.ByteArrayInputStream; +import java.io.DataInputStream; import java.io.File; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.HashMap; -import java.util.Map; -import java.util.UUID; +import java.io.IOException; +import java.util.*; public class BData { @@ -47,18 +50,30 @@ public class BData { } } + // Register Item Loaders + CustomItem.registerItemLoader(); + SimpleItem.registerItemLoader(); + PluginItem.registerItemLoader(); + // loading Ingredients into ingMap + // Only for Legacy Brews Map ingMap = new HashMap<>(); ConfigurationSection section = data.getConfigurationSection("Ingredients"); if (section != null) { for (String id : section.getKeys(false)) { - ConfigurationSection matSection = section.getConfigurationSection(id + ".mats"); - if (matSection != null) { - // matSection has all the materials + amount as Integers - ArrayList ingredients = deserializeIngredients(matSection); - ingMap.put(id, new BIngredients(ingredients, section.getInt(id + ".cookedTime", 0), true)); + if (section.isConfigurationSection(id + ".mats")) { + // Old way of saving + ConfigurationSection matSection = section.getConfigurationSection(id + ".mats"); + if (matSection != null) { + // matSection has all the materials + amount as Integers + List ingredients = oldDeserializeIngredients(matSection); + ingMap.put(id, new BIngredients(ingredients, section.getInt(id + ".cookedTime", 0), true)); + } else { + P.p.errorLog("Ingredient id: '" + id + "' incomplete in data.yml"); + } } else { - P.p.errorLog("Ingredient id: '" + id + "' incomplete in data.yml"); + // New way of saving ingredients + ingMap.put(id, deserializeIngredients(section.getString(id + ".mats"))); } } } @@ -110,9 +125,9 @@ public class BData { for (World world : P.p.getServer().getWorlds()) { if (world.getName().startsWith("DXL_")) { - loadWorldData(BUtil.getDxlName(world.getName()), world); + loadWorldData(BUtil.getDxlName(world.getName()), world, data); } else { - loadWorldData(world.getUID().toString(), world); + loadWorldData(world.getUID().toString(), world, data); } } @@ -121,8 +136,19 @@ public class BData { } } - public static ArrayList deserializeIngredients(ConfigurationSection matSection) { - ArrayList ingredients = new ArrayList<>(); + public static BIngredients deserializeIngredients(String mat) { + try (DataInputStream in = new DataInputStream(new Base91DecoderStream(new ByteArrayInputStream(mat.getBytes())))) { + byte ver = in.readByte(); + return BIngredients.load(in, ver); + } catch (IOException e) { + e.printStackTrace(); + return new BIngredients(); + } + } + + // Loading from the old way of saving ingredients + public static List oldDeserializeIngredients(ConfigurationSection matSection) { + List ingredients = new ArrayList<>(); for (String mat : matSection.getKeys(false)) { String[] matSplit = mat.split(","); Material m = Material.getMaterial(matSplit[0]); @@ -135,10 +161,13 @@ public class BData { P.p.debugLog("converting Data Material from " + matSplit[0] + " to " + m); } if (m == null) continue; - ItemStack item = new ItemStack(m, matSection.getInt(mat)); + SimpleItem item; if (matSplit.length == 2) { - item.setDurability((short) P.p.parseInt(matSplit[1])); + item = new SimpleItem(m, (short) P.p.parseInt(matSplit[1])); + } else { + item = new SimpleItem(m); } + item.setAmount(matSection.getInt(mat)); ingredients.add(item); } return ingredients; @@ -156,134 +185,146 @@ public class BData { } // loads BIngredients from an ingredient section - public static BIngredients loadIngredients(ConfigurationSection section) { - if (section != null) { - return new BIngredients(deserializeIngredients(section), 0); + public static BIngredients loadCauldronIng(ConfigurationSection section, String path) { + if (section.isConfigurationSection(path)) { + // Old way of saving + ConfigurationSection matSection = section.getConfigurationSection(path); + if (matSection != null) { + // matSection has all the materials + amount as Integers + return new BIngredients(oldDeserializeIngredients(section), 0); + } else { + P.p.errorLog("Cauldron is missing Ingredient Section"); + return new BIngredients(); + } } else { - P.p.errorLog("Cauldron is missing Ingredient Section"); + // New way of saving ingredients + return deserializeIngredients(section.getString(path)); } - return new BIngredients(); } // load Block locations of given world - public static void loadWorldData(String uuid, World world) { + public static void loadWorldData(String uuid, World world, FileConfiguration data) { - File file = new File(P.p.getDataFolder(), "data.yml"); - if (file.exists()) { - - FileConfiguration data = YamlConfiguration.loadConfiguration(file); - - // loading BCauldron - if (data.contains("BCauldron." + uuid)) { - ConfigurationSection section = data.getConfigurationSection("BCauldron." + uuid); - for (String cauldron : section.getKeys(false)) { - // block is splitted into x/y/z - String block = section.getString(cauldron + ".block"); - if (block != null) { - String[] splitted = block.split("/"); - if (splitted.length == 3) { - - Block worldBlock = world.getBlockAt(P.p.parseInt(splitted[0]), P.p.parseInt(splitted[1]), P.p.parseInt(splitted[2])); - BIngredients ingredients = loadIngredients(section.getConfigurationSection(cauldron + ".ingredients")); - int state = section.getInt(cauldron + ".state", 1); - - new BCauldron(worldBlock, ingredients, state); - } else { - P.p.errorLog("Incomplete Block-Data in data.yml: " + section.getCurrentPath() + "." + cauldron); - } - } else { - P.p.errorLog("Missing Block-Data in data.yml: " + section.getCurrentPath() + "." + cauldron); - } - } + if (data == null) { + File file = new File(P.p.getDataFolder(), "data.yml"); + if (file.exists()) { + data = YamlConfiguration.loadConfiguration(file); + } else { + return; } - - // loading Barrel - if (data.contains("Barrel." + uuid)) { - ConfigurationSection section = data.getConfigurationSection("Barrel." + uuid); - for (String barrel : section.getKeys(false)) { - // block spigot is splitted into x/y/z - String spigot = section.getString(barrel + ".spigot"); - if (spigot != null) { - String[] splitted = spigot.split("/"); - if (splitted.length == 3) { - - // load itemStacks from invSection - ConfigurationSection invSection = section.getConfigurationSection(barrel + ".inv"); - Block block = world.getBlockAt(P.p.parseInt(splitted[0]), P.p.parseInt(splitted[1]), P.p.parseInt(splitted[2])); - float time = (float) section.getDouble(barrel + ".time", 0.0); - byte sign = (byte) section.getInt(barrel + ".sign", 0); - - BoundingBox box = null; - if (section.contains(barrel + ".bounds")) { - String[] bds = section.getString(barrel + ".bounds", "").split(","); - if (bds.length == 6) { - box = new BoundingBox(P.p.parseInt(bds[0]), P.p.parseInt(bds[1]), P.p.parseInt(bds[2]), P.p.parseInt(bds[3]), P.p.parseInt(bds[4]), P.p.parseInt(bds[5])); - } - } else if (section.contains(barrel + ".st")) { - // Convert from Stair and Wood Locations to BoundingBox - String[] st = section.getString(barrel + ".st", "").split(","); - String[] wo = section.getString(barrel + ".wo", "").split(","); - int woLength = wo.length; - if (woLength <= 1) { - woLength = 0; - } - String[] points = new String[st.length + woLength]; - System.arraycopy(st, 0, points, 0, st.length); - if (woLength > 1) { - System.arraycopy(wo, 0, points, st.length, woLength); - } - int[] locs = ArrayUtils.toPrimitive(Arrays.stream(points).map(s -> P.p.parseInt(s)).toArray(Integer[]::new)); - box = BoundingBox.fromPoints(locs); - } - - Barrel b; - if (invSection != null) { - b = new Barrel(block, sign, box, invSection.getValues(true), time); - } else { - // Barrel has no inventory - b = new Barrel(block, sign, box, null, time); - } - - // In case Barrel Block locations were missing and could not be recreated: do not add the barrel - if (b.getBody().getBounds() != null) { - Barrel.barrels.add(b); - } - - } else { - P.p.errorLog("Incomplete Block-Data in data.yml: " + section.getCurrentPath() + "." + barrel); - } - } else { - P.p.errorLog("Missing Block-Data in data.yml: " + section.getCurrentPath() + "." + barrel); - } - } - } - - // loading Wakeup - if (data.contains("Wakeup." + uuid)) { - ConfigurationSection section = data.getConfigurationSection("Wakeup." + uuid); - for (String wakeup : section.getKeys(false)) { - // loc of wakeup is splitted into x/y/z/pitch/yaw - String loc = section.getString(wakeup); - if (loc != null) { - String[] splitted = loc.split("/"); - if (splitted.length == 5) { - - double x = NumberUtils.toDouble(splitted[0]); - double y = NumberUtils.toDouble(splitted[1]); - double z = NumberUtils.toDouble(splitted[2]); - float pitch = NumberUtils.toFloat(splitted[3]); - float yaw = NumberUtils.toFloat(splitted[4]); - Location location = new Location(world, x, y, z, yaw, pitch); - - Wakeup.wakeups.add(new Wakeup(location)); - - } else { - P.p.errorLog("Incomplete Location-Data in data.yml: " + section.getCurrentPath() + "." + wakeup); - } - } - } - } - } + + // loading BCauldron + if (data.contains("BCauldron." + uuid)) { + ConfigurationSection section = data.getConfigurationSection("BCauldron." + uuid); + for (String cauldron : section.getKeys(false)) { + // block is splitted into x/y/z + String block = section.getString(cauldron + ".block"); + if (block != null) { + String[] splitted = block.split("/"); + if (splitted.length == 3) { + + Block worldBlock = world.getBlockAt(P.p.parseInt(splitted[0]), P.p.parseInt(splitted[1]), P.p.parseInt(splitted[2])); + BIngredients ingredients = loadCauldronIng(section, cauldron + ".ingredients"); + int state = section.getInt(cauldron + ".state", 1); + + new BCauldron(worldBlock, ingredients, state); + } else { + P.p.errorLog("Incomplete Block-Data in data.yml: " + section.getCurrentPath() + "." + cauldron); + } + } else { + P.p.errorLog("Missing Block-Data in data.yml: " + section.getCurrentPath() + "." + cauldron); + } + } + } + + // loading Barrel + if (data.contains("Barrel." + uuid)) { + ConfigurationSection section = data.getConfigurationSection("Barrel." + uuid); + for (String barrel : section.getKeys(false)) { + // block spigot is splitted into x/y/z + String spigot = section.getString(barrel + ".spigot"); + if (spigot != null) { + String[] splitted = spigot.split("/"); + if (splitted.length == 3) { + + // load itemStacks from invSection + ConfigurationSection invSection = section.getConfigurationSection(barrel + ".inv"); + Block block = world.getBlockAt(P.p.parseInt(splitted[0]), P.p.parseInt(splitted[1]), P.p.parseInt(splitted[2])); + float time = (float) section.getDouble(barrel + ".time", 0.0); + byte sign = (byte) section.getInt(barrel + ".sign", 0); + + BoundingBox box = null; + if (section.contains(barrel + ".bounds")) { + String[] bds = section.getString(barrel + ".bounds", "").split(","); + if (bds.length == 6) { + box = new BoundingBox(P.p.parseInt(bds[0]), P.p.parseInt(bds[1]), P.p.parseInt(bds[2]), P.p.parseInt(bds[3]), P.p.parseInt(bds[4]), P.p.parseInt(bds[5])); + } + } else if (section.contains(barrel + ".st")) { + // Convert from Stair and Wood Locations to BoundingBox + String[] st = section.getString(barrel + ".st", "").split(","); + String[] wo = section.getString(barrel + ".wo", "").split(","); + int woLength = wo.length; + if (woLength <= 1) { + woLength = 0; + } + String[] points = new String[st.length + woLength]; + System.arraycopy(st, 0, points, 0, st.length); + if (woLength > 1) { + System.arraycopy(wo, 0, points, st.length, woLength); + } + int[] locs = ArrayUtils.toPrimitive(Arrays.stream(points).map(s -> P.p.parseInt(s)).toArray(Integer[]::new)); + box = BoundingBox.fromPoints(locs); + } + + Barrel b; + if (invSection != null) { + b = new Barrel(block, sign, box, invSection.getValues(true), time); + } else { + // Barrel has no inventory + b = new Barrel(block, sign, box, null, time); + } + + // In case Barrel Block locations were missing and could not be recreated: do not add the barrel + + if (b.getBody().getBounds() != null) { + Barrel.barrels.add(b); + } + + } else { + P.p.errorLog("Incomplete Block-Data in data.yml: " + section.getCurrentPath() + "." + barrel); + } + } else { + P.p.errorLog("Missing Block-Data in data.yml: " + section.getCurrentPath() + "." + barrel); + } + } + } + + // loading Wakeup + if (data.contains("Wakeup." + uuid)) { + ConfigurationSection section = data.getConfigurationSection("Wakeup." + uuid); + for (String wakeup : section.getKeys(false)) { + // loc of wakeup is splitted into x/y/z/pitch/yaw + String loc = section.getString(wakeup); + if (loc != null) { + String[] splitted = loc.split("/"); + if (splitted.length == 5) { + + double x = NumberUtils.toDouble(splitted[0]); + double y = NumberUtils.toDouble(splitted[1]); + double z = NumberUtils.toDouble(splitted[2]); + float pitch = NumberUtils.toFloat(splitted[3]); + float yaw = NumberUtils.toFloat(splitted[4]); + Location location = new Location(world, x, y, z, yaw, pitch); + + Wakeup.wakeups.add(new Wakeup(location)); + + } else { + P.p.errorLog("Incomplete Location-Data in data.yml: " + section.getCurrentPath() + "." + wakeup); + } + } + } + } + } } diff --git a/src/com/dre/brewery/filedata/DataSave.java b/src/com/dre/brewery/filedata/DataSave.java index 579f93e..303c14e 100644 --- a/src/com/dre/brewery/filedata/DataSave.java +++ b/src/com/dre/brewery/filedata/DataSave.java @@ -67,7 +67,7 @@ public class DataSave extends BukkitRunnable { Brew.writePrevSeeds(configFile); if (!Brew.legacyPotions.isEmpty()) { - Brew.save(configFile.createSection("Brew")); + Brew.saveLegacy(configFile.createSection("Brew")); } if (!BCauldron.bcauldrons.isEmpty() || oldData.contains("BCauldron")) { diff --git a/src/com/dre/brewery/integration/IntegrationListener.java b/src/com/dre/brewery/integration/IntegrationListener.java index 5d69e2d..7b77de1 100644 --- a/src/com/dre/brewery/integration/IntegrationListener.java +++ b/src/com/dre/brewery/integration/IntegrationListener.java @@ -1,18 +1,30 @@ package com.dre.brewery.integration; import com.dre.brewery.Barrel; -import com.dre.brewery.utility.LegacyUtil; import com.dre.brewery.P; import com.dre.brewery.api.events.barrel.BarrelAccessEvent; import com.dre.brewery.api.events.barrel.BarrelDestroyEvent; import com.dre.brewery.api.events.barrel.BarrelRemoveEvent; import com.dre.brewery.filedata.BConfig; +import com.dre.brewery.integration.barrel.GriefPreventionBarrel; +import com.dre.brewery.integration.barrel.LWCBarrel; +import com.dre.brewery.integration.barrel.LogBlockBarrel; +import com.dre.brewery.integration.item.MMOItemsPluginItem; +import com.dre.brewery.recipe.BCauldronRecipe; +import com.dre.brewery.recipe.RecipeItem; +import com.dre.brewery.utility.LegacyUtil; +import net.Indyuce.mmoitems.MMOItems; +import net.Indyuce.mmoitems.api.item.NBTItem; +import org.bukkit.Material; import org.bukkit.block.Block; import org.bukkit.entity.Player; import org.bukkit.event.EventHandler; import org.bukkit.event.EventPriority; import org.bukkit.event.Listener; +import org.bukkit.event.block.Action; import org.bukkit.event.inventory.InventoryCloseEvent; +import org.bukkit.event.player.PlayerInteractEvent; +import org.bukkit.inventory.EquipmentSlot; import org.bukkit.plugin.Plugin; public class IntegrationListener implements Listener { @@ -173,4 +185,36 @@ public class IntegrationListener implements Listener { } } } + + @EventHandler(priority = EventPriority.LOW, ignoreCancelled = true) + public void onInteract(PlayerInteractEvent event) { + // Cancel the Interact Event early, so MMOItems does not act before us and consume the item when trying to add item to Cauldron + if (!P.use1_9) return; + if (BConfig.hasMMOItems == null) { + BConfig.hasMMOItems = P.p.getServer().getPluginManager().isPluginEnabled("MMOItems"); + } + if (!BConfig.hasMMOItems) return; + try { + if (event.getAction() == Action.RIGHT_CLICK_BLOCK && event.hasItem() && event.getHand() == EquipmentSlot.HAND) { + if (event.getClickedBlock() != null && event.getClickedBlock().getType() == Material.CAULDRON) { + NBTItem item = MMOItems.plugin.getNMS().getNBTItem(event.getItem()); + if (item.hasType()) { + for (RecipeItem rItem : BCauldronRecipe.acceptedCustom) { + if (rItem instanceof MMOItemsPluginItem) { + MMOItemsPluginItem mmo = ((MMOItemsPluginItem) rItem); + if (mmo.matches(event.getItem())) { + event.setCancelled(true); + P.p.playerListener.onPlayerInteract(event); + return; + } + } + } + } + } + } + } catch (Throwable e) { + P.p.errorLog("Could not check MMOItems for Item"); + e.printStackTrace(); + } + } } diff --git a/src/com/dre/brewery/integration/CitadelBarrel.java b/src/com/dre/brewery/integration/barrel/CitadelBarrel.java similarity index 95% rename from src/com/dre/brewery/integration/CitadelBarrel.java rename to src/com/dre/brewery/integration/barrel/CitadelBarrel.java index cb36a80..c519baf 100644 --- a/src/com/dre/brewery/integration/CitadelBarrel.java +++ b/src/com/dre/brewery/integration/barrel/CitadelBarrel.java @@ -1,4 +1,4 @@ -package com.dre.brewery.integration; +package com.dre.brewery.integration.barrel; import org.bukkit.block.Block; import org.bukkit.entity.Player; @@ -13,7 +13,7 @@ import vg.civcraft.mc.citadel.reinforcement.Reinforcement; /** * Basic Citadel support to prevent randos from stealing your barrel aging brews - * + * * @author ProgrammerDan */ public class CitadelBarrel { @@ -21,11 +21,11 @@ public class CitadelBarrel { public static boolean checkAccess(Player player, Block sign) { ReinforcementManager manager = Citadel.getReinforcementManager(); - + Reinforcement rein = manager.getReinforcement(sign); - + if (rein == null) return true; // no protections in place. - + if (rein instanceof PlayerReinforcement) { PlayerReinforcement prein = (PlayerReinforcement) rein; if (prein.canAccessChests(player)) { @@ -35,7 +35,7 @@ public class CitadelBarrel { return true; } // no support for multiblock atm, would require namelayer support. - + // special locked, or no access. brewery.msg(player, brewery.languageReader.get("Error_NoBarrelAccess")); return false; diff --git a/src/com/dre/brewery/integration/GriefPreventionBarrel.java b/src/com/dre/brewery/integration/barrel/GriefPreventionBarrel.java similarity index 96% rename from src/com/dre/brewery/integration/GriefPreventionBarrel.java rename to src/com/dre/brewery/integration/barrel/GriefPreventionBarrel.java index ae05283..9337bed 100644 --- a/src/com/dre/brewery/integration/GriefPreventionBarrel.java +++ b/src/com/dre/brewery/integration/barrel/GriefPreventionBarrel.java @@ -1,4 +1,4 @@ -package com.dre.brewery.integration; +package com.dre.brewery.integration.barrel; import com.dre.brewery.P; import com.dre.brewery.api.events.barrel.BarrelAccessEvent; diff --git a/src/com/dre/brewery/integration/LWCBarrel.java b/src/com/dre/brewery/integration/barrel/LWCBarrel.java similarity index 98% rename from src/com/dre/brewery/integration/LWCBarrel.java rename to src/com/dre/brewery/integration/barrel/LWCBarrel.java index 7831527..cad18b5 100644 --- a/src/com/dre/brewery/integration/LWCBarrel.java +++ b/src/com/dre/brewery/integration/barrel/LWCBarrel.java @@ -1,4 +1,4 @@ -package com.dre.brewery.integration; +package com.dre.brewery.integration.barrel; import com.dre.brewery.Barrel; import com.dre.brewery.P; diff --git a/src/com/dre/brewery/integration/LogBlockBarrel.java b/src/com/dre/brewery/integration/barrel/LogBlockBarrel.java similarity index 99% rename from src/com/dre/brewery/integration/LogBlockBarrel.java rename to src/com/dre/brewery/integration/barrel/LogBlockBarrel.java index 371c0bf..6602d66 100644 --- a/src/com/dre/brewery/integration/LogBlockBarrel.java +++ b/src/com/dre/brewery/integration/barrel/LogBlockBarrel.java @@ -1,4 +1,4 @@ -package com.dre.brewery.integration; +package com.dre.brewery.integration.barrel; import com.dre.brewery.utility.LegacyUtil; import com.dre.brewery.P; diff --git a/src/com/dre/brewery/integration/WGBarrel.java b/src/com/dre/brewery/integration/barrel/WGBarrel.java similarity index 81% rename from src/com/dre/brewery/integration/WGBarrel.java rename to src/com/dre/brewery/integration/barrel/WGBarrel.java index 25e29b9..033124b 100644 --- a/src/com/dre/brewery/integration/WGBarrel.java +++ b/src/com/dre/brewery/integration/barrel/WGBarrel.java @@ -1,4 +1,4 @@ -package com.dre.brewery.integration; +package com.dre.brewery.integration.barrel; import org.bukkit.block.Block; import org.bukkit.entity.Player; diff --git a/src/com/dre/brewery/integration/WGBarrel5.java b/src/com/dre/brewery/integration/barrel/WGBarrel5.java similarity index 97% rename from src/com/dre/brewery/integration/WGBarrel5.java rename to src/com/dre/brewery/integration/barrel/WGBarrel5.java index a71666a..0d0ebd1 100644 --- a/src/com/dre/brewery/integration/WGBarrel5.java +++ b/src/com/dre/brewery/integration/barrel/WGBarrel5.java @@ -1,4 +1,4 @@ -package com.dre.brewery.integration; +package com.dre.brewery.integration.barrel; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; diff --git a/src/com/dre/brewery/integration/WGBarrel6.java b/src/com/dre/brewery/integration/barrel/WGBarrel6.java similarity index 95% rename from src/com/dre/brewery/integration/WGBarrel6.java rename to src/com/dre/brewery/integration/barrel/WGBarrel6.java index f89fa53..d3b243b 100644 --- a/src/com/dre/brewery/integration/WGBarrel6.java +++ b/src/com/dre/brewery/integration/barrel/WGBarrel6.java @@ -1,4 +1,4 @@ -package com.dre.brewery.integration; +package com.dre.brewery.integration.barrel; import com.sk89q.worldguard.bukkit.RegionQuery; diff --git a/src/com/dre/brewery/integration/WGBarrel7.java b/src/com/dre/brewery/integration/barrel/WGBarrel7.java similarity index 98% rename from src/com/dre/brewery/integration/WGBarrel7.java rename to src/com/dre/brewery/integration/barrel/WGBarrel7.java index 0d1de5d..e06dc29 100644 --- a/src/com/dre/brewery/integration/WGBarrel7.java +++ b/src/com/dre/brewery/integration/barrel/WGBarrel7.java @@ -1,4 +1,4 @@ -package com.dre.brewery.integration; +package com.dre.brewery.integration.barrel; import org.bukkit.block.Block; diff --git a/src/com/dre/brewery/integration/item/BreweryPluginItem.java b/src/com/dre/brewery/integration/item/BreweryPluginItem.java new file mode 100644 index 0000000..a815612 --- /dev/null +++ b/src/com/dre/brewery/integration/item/BreweryPluginItem.java @@ -0,0 +1,30 @@ +package com.dre.brewery.integration.item; + +import com.dre.brewery.Brew; +import com.dre.brewery.recipe.BRecipe; +import com.dre.brewery.recipe.PluginItem; +import org.bukkit.ChatColor; +import org.bukkit.inventory.ItemStack; + +/** + * For recipes that use Brewery Items as input + */ +public class BreweryPluginItem extends PluginItem { + +// When implementing this, put Brewery as softdepend in your plugin.yml! +// We're calling this as server start: +// PluginItem.registerForConfig("brewery", BreweryPluginItem::new); + + @Override + public boolean matches(ItemStack item) { + Brew brew = Brew.get(item); + if (brew != null) { + BRecipe recipe = brew.getCurrentRecipe(); + if (recipe != null) { + return recipe.getRecipeName().equalsIgnoreCase(getItemId()) || recipe.getName(10).equalsIgnoreCase(getItemId()); + } + return ChatColor.stripColor(item.getItemMeta().getDisplayName()).equalsIgnoreCase(getItemId()); + } + return false; + } +} diff --git a/src/com/dre/brewery/integration/item/MMOItemsPluginItem.java b/src/com/dre/brewery/integration/item/MMOItemsPluginItem.java new file mode 100644 index 0000000..d4df22e --- /dev/null +++ b/src/com/dre/brewery/integration/item/MMOItemsPluginItem.java @@ -0,0 +1,32 @@ +package com.dre.brewery.integration.item; + +import com.dre.brewery.P; +import com.dre.brewery.filedata.BConfig; +import com.dre.brewery.recipe.PluginItem; +import net.Indyuce.mmoitems.MMOItems; +import net.Indyuce.mmoitems.api.item.NBTItem; +import org.bukkit.inventory.ItemStack; + +public class MMOItemsPluginItem extends PluginItem { + +// When implementing this, put Brewery as softdepend in your plugin.yml! +// We're calling this as server start: +// PluginItem.registerForConfig("mmoitems", MMOItemsPluginItem::new); + + @Override + public boolean matches(ItemStack item) { + if (BConfig.hasMMOItems == null) { + BConfig.hasMMOItems = P.p.getServer().getPluginManager().isPluginEnabled("MMOItems"); + } + if (!BConfig.hasMMOItems) return false; + + try { + NBTItem nbtItem = MMOItems.plugin.getNMS().getNBTItem(item); + return nbtItem.hasType() && nbtItem.getString("MMOITEMS_ITEM_ID").equalsIgnoreCase(getItemId()); + } catch (Throwable e) { + e.printStackTrace(); + P.p.errorLog("Could not check MMOItems for Item ID"); + return false; + } + } +} diff --git a/src/com/dre/brewery/integration/item/SlimefunPluginItem.java b/src/com/dre/brewery/integration/item/SlimefunPluginItem.java new file mode 100644 index 0000000..fe33094 --- /dev/null +++ b/src/com/dre/brewery/integration/item/SlimefunPluginItem.java @@ -0,0 +1,35 @@ +package com.dre.brewery.integration.item; + +import com.dre.brewery.P; +import com.dre.brewery.filedata.BConfig; +import com.dre.brewery.recipe.PluginItem; +import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.SlimefunItem; +import org.bukkit.inventory.ItemStack; + +public class SlimefunPluginItem extends PluginItem { + +// When implementing this, put Brewery as softdepend in your plugin.yml! +// We're calling this as server start: +// PluginItem.registerForConfig("slimefun", SlimefunPluginItem::new); +// PluginItem.registerForConfig("exoticgarden", SlimefunPluginItem::new); + + @Override + public boolean matches(ItemStack item) { + if (BConfig.hasSlimefun == null) { + BConfig.hasSlimefun = P.p.getServer().getPluginManager().isPluginEnabled("Slimefun"); + } + if (!BConfig.hasSlimefun) return false; + + try { + SlimefunItem sfItem = SlimefunItem.getByItem(item); + if (sfItem != null) { + return sfItem.getID().equalsIgnoreCase(getItemId()); + } + } catch (Throwable e) { + e.printStackTrace(); + P.p.errorLog("Could not check Slimefun for Item ID"); + return false; + } + return false; + } +} diff --git a/src/com/dre/brewery/listeners/CommandListener.java b/src/com/dre/brewery/listeners/CommandListener.java index be9f50c..9ff7c1b 100644 --- a/src/com/dre/brewery/listeners/CommandListener.java +++ b/src/com/dre/brewery/listeners/CommandListener.java @@ -3,6 +3,7 @@ package com.dre.brewery.listeners; import com.dre.brewery.*; import com.dre.brewery.api.events.brew.BrewModifyEvent; import com.dre.brewery.filedata.BConfig; +import com.dre.brewery.recipe.BRecipe; import com.dre.brewery.utility.BUtil; import org.bukkit.Material; import org.bukkit.command.Command; diff --git a/src/com/dre/brewery/listeners/WorldListener.java b/src/com/dre/brewery/listeners/WorldListener.java index a945622..b19b03c 100644 --- a/src/com/dre/brewery/listeners/WorldListener.java +++ b/src/com/dre/brewery/listeners/WorldListener.java @@ -19,9 +19,9 @@ public class WorldListener implements Listener { World world = event.getWorld(); if (world.getName().startsWith("DXL_")) { - BData.loadWorldData(BUtil.getDxlName(world.getName()), world); + BData.loadWorldData(BUtil.getDxlName(world.getName()), world, null); } else { - BData.loadWorldData(world.getUID().toString(), world); + BData.loadWorldData(world.getUID().toString(), world, null); } } diff --git a/src/com/dre/brewery/lore/BrewLore.java b/src/com/dre/brewery/lore/BrewLore.java index 8251fa8..a7bf2eb 100644 --- a/src/com/dre/brewery/lore/BrewLore.java +++ b/src/com/dre/brewery/lore/BrewLore.java @@ -1,8 +1,8 @@ package com.dre.brewery.lore; -import com.dre.brewery.BEffect; +import com.dre.brewery.recipe.BEffect; import com.dre.brewery.BIngredients; -import com.dre.brewery.BRecipe; +import com.dre.brewery.recipe.BRecipe; import com.dre.brewery.Brew; import com.dre.brewery.P; import com.dre.brewery.filedata.BConfig; diff --git a/src/com/dre/brewery/BCauldronRecipe.java b/src/com/dre/brewery/recipe/BCauldronRecipe.java similarity index 67% rename from src/com/dre/brewery/BCauldronRecipe.java rename to src/com/dre/brewery/recipe/BCauldronRecipe.java index 6968829..de8cc6b 100644 --- a/src/com/dre/brewery/BCauldronRecipe.java +++ b/src/com/dre/brewery/recipe/BCauldronRecipe.java @@ -1,11 +1,10 @@ -package com.dre.brewery; +package com.dre.brewery.recipe; -import com.dre.brewery.utility.CustomItem; +import com.dre.brewery.P; import com.dre.brewery.utility.PotionColor; import com.dre.brewery.utility.Tuple; import org.bukkit.Material; import org.bukkit.configuration.ConfigurationSection; -import org.bukkit.inventory.ItemStack; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -17,10 +16,12 @@ import java.util.stream.Collectors; public class BCauldronRecipe { public static List recipes = new ArrayList<>(); - public static Set acceptedMaterials = EnumSet.noneOf(Material.class); + public static List acceptedCustom = new ArrayList<>(); // All accepted custom and other items + public static Set acceptedSimple = EnumSet.noneOf(Material.class); // All accepted simple items + public static Set acceptedMaterials = EnumSet.noneOf(Material.class); // Fast cache for all accepted Materials private String name; - private List> ingredients; // Item and amount + private List ingredients; //private List particles private PotionColor color; private List lore; @@ -72,7 +73,7 @@ public class BCauldronRecipe { } @NotNull - public List> getIngredients() { + public List getIngredients() { return ingredients; } @@ -92,28 +93,26 @@ public class BCauldronRecipe { * If all Ingredients and their amounts are equal, returns 10 * Returns something between 0 and 10 if all ingredients present, but differing amounts, depending on how much the amount differs. */ - public float getIngredientMatch(List items) { + public float getIngredientMatch(List items) { if (items.size() < ingredients.size()) { return 0; } float match = 10; - search: for (Tuple ing : ingredients) { - for (ItemStack item : items) { - if (ing.a().matches(item)) { - double difference = Math.abs(ing.b() - item.getAmount()); + search: for (RecipeItem recipeIng : ingredients) { + for (Ingredient ing : items) { + if (recipeIng.matches(ing)) { + double difference = Math.abs(recipeIng.getAmount() - ing.getAmount()); if (difference >= 1000) { return 0; } // The Item Amount is the determining part here, the higher the better. // But let the difference in amount to what the recipe expects have a tiny factor as well. // This way for the same amount, the recipe with the lower difference wins. - double factor = item.getAmount() * (1.0 - (difference / 1000.0)) ; + double factor = ing.getAmount() * (1.0 - (difference / 1000.0)) ; //double mod = 0.1 + (0.9 * Math.exp(-0.03 * difference)); // logarithmic curve from 1 to 0.1 double mod = 1 + (0.9 * -Math.exp(-0.03 * factor)); // logarithmic curve from 0.1 to 1, small for a low factor - P.p.debugLog("Mod for " + ing.a() + "/" + ing.b() + ": " + mod); - assert mod >= 0.1; - assert mod <= 1; // TODO Test + P.p.debugLog("Mod for " + recipeIng + ": " + mod); @@ -138,4 +137,40 @@ public class BCauldronRecipe { public String toString() { return "BCauldronRecipe{" + name + '}'; } + + /*public static boolean acceptItem(ItemStack item) { + if (acceptedMaterials.contains(item.getType())) { + // Extremely fast way to check for most items + return true; + } + if (!item.hasItemMeta()) { + return false; + } + // If the Item is not on the list, but customized, we have to do more checks + ItemMeta meta = item.getItemMeta(); + assert meta != null; + if (meta.hasDisplayName() || meta.hasLore()) { + for (BItem bItem : acceptedCustom) { + if (bItem.matches(item)) { + return true; + } + } + } + return false; + } + + @Nullable + public static RecipeItem acceptItem(ItemStack item) { + if (!acceptedMaterials.contains(item.getType()) && !item.hasItemMeta()) { + // Extremely fast way to check for most items + return null; + } + // If the Item is on the list, or customized, we have to do more checks + for (RecipeItem rItem : acceptedItems) { + if (rItem.matches(item)) { + return rItem; + } + } + return null; + }*/ } diff --git a/src/com/dre/brewery/BEffect.java b/src/com/dre/brewery/recipe/BEffect.java similarity index 98% rename from src/com/dre/brewery/BEffect.java rename to src/com/dre/brewery/recipe/BEffect.java index 4d516bd..0dc282e 100644 --- a/src/com/dre/brewery/BEffect.java +++ b/src/com/dre/brewery/recipe/BEffect.java @@ -1,5 +1,6 @@ -package com.dre.brewery; +package com.dre.brewery.recipe; +import com.dre.brewery.P; import com.dre.brewery.utility.BUtil; import org.bukkit.entity.Player; import org.bukkit.inventory.meta.PotionMeta; diff --git a/src/com/dre/brewery/BRecipe.java b/src/com/dre/brewery/recipe/BRecipe.java similarity index 80% rename from src/com/dre/brewery/BRecipe.java rename to src/com/dre/brewery/recipe/BRecipe.java index 2e107ce..8d99f42 100644 --- a/src/com/dre/brewery/BRecipe.java +++ b/src/com/dre/brewery/recipe/BRecipe.java @@ -1,7 +1,9 @@ -package com.dre.brewery; +package com.dre.brewery.recipe; +import com.dre.brewery.BIngredients; +import com.dre.brewery.Brew; +import com.dre.brewery.P; import com.dre.brewery.filedata.BConfig; -import com.dre.brewery.utility.CustomItem; import com.dre.brewery.utility.PotionColor; import com.dre.brewery.utility.Tuple; import org.bukkit.Material; @@ -12,14 +14,13 @@ import org.jetbrains.annotations.Nullable; import java.util.ArrayList; import java.util.List; -import java.util.stream.Collectors; public class BRecipe { public static List recipes = new ArrayList<>(); private String[] name; - private List> ingredients = new ArrayList<>(); // Items and amounts + private List ingredients = new ArrayList<>(); // Items and amounts private int cookingTime; // time to cook in cauldron private byte distillruns; // runs through the brewer private int distillTime; // time for one distill run in seconds @@ -96,7 +97,7 @@ public class BRecipe { return recipe; } - public static List> loadIngredients(ConfigurationSection cfg, String recipeId) { + public static List loadIngredients(ConfigurationSection cfg, String recipeId) { List ingredientsList; if (cfg.isString(recipeId + ".ingredients")) { ingredientsList = new ArrayList<>(1); @@ -107,7 +108,7 @@ public class BRecipe { if (ingredientsList == null) { return null; } - List> ingredients = new ArrayList<>(ingredientsList.size()); + List ingredients = new ArrayList<>(ingredientsList.size()); listLoop: for (String item : ingredientsList) { String[] ingredParts = item.split("/"); int amount = 1; @@ -121,19 +122,51 @@ public class BRecipe { String[] matParts; if (ingredParts[0].contains(",")) { matParts = ingredParts[0].split(","); - } else if (ingredParts[0].contains(":")) { - matParts = ingredParts[0].split(":"); } else if (ingredParts[0].contains(";")) { matParts = ingredParts[0].split(";"); } else { matParts = ingredParts[0].split("\\."); } + // Check if this is a Plugin Item + String[] pluginItem = matParts[0].split(":"); + if (pluginItem.length > 1) { + RecipeItem custom = PluginItem.fromConfig(pluginItem[0], pluginItem[1]); + if (custom != null) { + custom.setAmount(amount); + custom.makeImmutable(); + ingredients.add(custom); + BCauldronRecipe.acceptedCustom.add(custom); + continue; + } else { + // TODO Maybe load later ie on first use of recipe? + P.p.errorLog(recipeId + ": Could not Find Plugin: " + ingredParts[1]); + return null; + } + } + // Try to find this Ingredient as Custom Item - for (CustomItem custom : BConfig.customItems) { - if (custom.getId().equalsIgnoreCase(matParts[0])) { - ingredients.add(new Tuple<>(custom, amount)); - BCauldronRecipe.acceptedMaterials.addAll(custom.getMaterials()); + for (RecipeItem custom : BConfig.customItems) { + if (custom.getConfigId().equalsIgnoreCase(matParts[0])) { + custom = custom.getMutableCopy(); + custom.setAmount(amount); + custom.makeImmutable(); + ingredients.add(custom); + if (custom.hasMaterials()) { + BCauldronRecipe.acceptedMaterials.addAll(custom.getMaterials()); + } + // Add it as acceptedCustom + if (!BCauldronRecipe.acceptedCustom.contains(custom)) { + BCauldronRecipe.acceptedCustom.add(custom); + /*if (custom instanceof PluginItem || !custom.hasMaterials()) { + BCauldronRecipe.acceptedCustom.add(custom); + } else if (custom instanceof CustomMatchAnyItem) { + CustomMatchAnyItem ma = (CustomMatchAnyItem) custom; + if (ma.hasNames() || ma.hasLore()) { + BCauldronRecipe.acceptedCustom.add(ma); + } + }*/ + } continue listLoop; } } @@ -163,14 +196,17 @@ public class BRecipe { } } if (mat != null) { - CustomItem custom; + RecipeItem rItem; if (durability > -1) { - custom = CustomItem.asSimpleItem(mat, durability); + rItem = new SimpleItem(mat, durability); } else { - custom = CustomItem.asSimpleItem(mat); + rItem = new SimpleItem(mat); } - ingredients.add(new Tuple<>(custom, amount)); + rItem.setAmount(amount); + rItem.makeImmutable(); + ingredients.add(rItem); BCauldronRecipe.acceptedMaterials.add(mat); + BCauldronRecipe.acceptedSimple.add(mat); } else { P.p.errorLog(recipeId + ": Unknown Material: " + ingredParts[0]); return null; @@ -297,14 +333,14 @@ public class BRecipe { } // true if given list misses an ingredient - public boolean isMissingIngredients(List list) { + public boolean isMissingIngredients(List list) { if (list.size() < ingredients.size()) { return true; } - for (Tuple ingredient : ingredients) { + for (RecipeItem rItem : ingredients) { boolean matches = false; - for (ItemStack used : list) { - if (ingredient.a().matches(used)) { + for (Ingredient used : list) { + if (rItem.matches(used)) { matches = true; break; } @@ -327,13 +363,18 @@ public class BRecipe { } /** - * Create a Brew from this Recipe with best values. Quality can be set, but will reset to 10 if put in a barrel + * Create a Brew from this Recipe with best values. Quality can be set, but will reset to 10 if unset immutable and put in a barrel * * @param quality The Quality of the Brew * @return The created Brew */ public Brew createBrew(int quality) { - List list = ingredients.stream().map(ing -> ing.a().createDummy(ing.b())).collect(Collectors.toList()); + List list = new ArrayList<>(ingredients.size()); + for (RecipeItem rItem : ingredients) { + Ingredient ing = rItem.toIngredientGeneric(); + ing.setAmount(rItem.getAmount()); + list.add(ing); + } BIngredients bIngredients = new BIngredients(list, cookingTime); @@ -343,11 +384,21 @@ public class BRecipe { // Getter + // how many of a specific ingredient in the recipe + public int amountOf(Ingredient ing) { + for (RecipeItem rItem : ingredients) { + if (rItem.matches(ing)) { + return rItem.getAmount(); + } + } + return 0; + } + // how many of a specific ingredient in the recipe public int amountOf(ItemStack item) { - for (Tuple ingredient : ingredients) { - if (ingredient.a().matches(item)) { - return ingredient.b(); + for (RecipeItem rItem : ingredients) { + if (rItem.matches(item)) { + return rItem.getAmount(); } } return 0; diff --git a/src/com/dre/brewery/recipe/CustomItem.java b/src/com/dre/brewery/recipe/CustomItem.java new file mode 100644 index 0000000..dd83ab5 --- /dev/null +++ b/src/com/dre/brewery/recipe/CustomItem.java @@ -0,0 +1,291 @@ +package com.dre.brewery.recipe; + +import org.bukkit.ChatColor; +import org.bukkit.Material; +import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.meta.ItemMeta; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.io.DataInputStream; +import java.io.DataOutputStream; +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; +import java.util.Objects; + +/** + * Minecraft Item with custon name and lore. + * Mostly used for Custom Items of the Config, but also for general custom items + */ +public class CustomItem extends RecipeItem implements Ingredient { + + private Material mat; + private String name; + private List lore; + + public CustomItem() { + } + + public CustomItem(Material mat) { + this.mat = mat; + } + + public CustomItem(Material mat, String name, List lore) { + this.mat = mat; + this.name = name; + this.lore = lore; + } + + public CustomItem(ItemStack item) { + mat = item.getType(); + if (!item.hasItemMeta()) { + return; + } + ItemMeta itemMeta = item.getItemMeta(); + assert itemMeta != null; + if (itemMeta.hasDisplayName()) { + name = itemMeta.getDisplayName(); + } + if (itemMeta.hasLore()) { + lore = itemMeta.getLore(); + } + } + + @Override + public boolean hasMaterials() { + return mat != null; + } + + public boolean hasName() { + return name != null; + } + + public boolean hasLore() { + return lore != null && !lore.isEmpty(); + } + + @Override + public List getMaterials() { + List l = new ArrayList<>(1); + l.add(mat); + return l; + } + + @Nullable + public Material getMaterial() { + return mat; + } + + protected void setMat(Material mat) { + this.mat = mat; + } + + @Nullable + public String getName() { + return name; + } + + protected void setName(String name) { + this.name = name; + } + + @Nullable + public List getLore() { + return lore; + } + + protected void setLore(List lore) { + this.lore = lore; + } + + @NotNull + @Override + public Ingredient toIngredient(ItemStack forItem) { + return ((CustomItem) getMutableCopy()); + } + + @NotNull + @Override + public Ingredient toIngredientGeneric() { + return ((CustomItem) getMutableCopy()); + } + + @Override + public boolean matches(Ingredient ingredient) { + if (isSimilar(ingredient)) { + return true; + } + if (ingredient instanceof RecipeItem) { + RecipeItem rItem = ((RecipeItem) ingredient); + if (rItem instanceof SimpleItem) { + // If the recipe item is just a simple item, only match if we also only define material + // If this is a custom item with more info, we don't want to match a simple item + return hasMaterials() && !hasLore() && !hasName() && getMaterial() == ((SimpleItem) rItem).getMaterial(); + } else if (rItem instanceof CustomItem) { + // If the other is a CustomItem as well and not Similar to ours, it might have more data and we still match + CustomItem other = ((CustomItem) rItem); + if (mat == null || mat == other.mat) { + if (!hasName() || (other.name != null && name.equalsIgnoreCase(other.name))) { + return !hasLore() || lore == other.lore || (other.hasLore() && matchLore(other.lore)); + } + } + } + } + return false; + } + + @Override + public boolean matches(ItemStack item) { + if (mat != null) { + if (item.getType() != mat) { + return false; + } + } + if (name == null && !hasLore()) { + return true; + } + if (!item.hasItemMeta()) { + return false; + } + ItemMeta meta = item.getItemMeta(); + assert meta != null; + if (name != null) { + if (!meta.hasDisplayName() || !name.equalsIgnoreCase(meta.getDisplayName())) { + return false; + } + } + + if (hasLore()) { + if (!meta.hasLore()) { + return false; + } + return matchLore(meta.getLore()); + } + return true; + } + + /** + * If this item has lore that matches the given lore. + * It matches if our lore is contained in the given lore consecutively, ignoring color of the given lore. + * + * @param usedLore The given lore to match + * @return True if the given lore contains our lore consecutively + */ + public boolean matchLore(List usedLore) { + if (lore == null) return true; + int lastIndex = 0; + boolean foundFirst = false; + for (String line : lore) { + do { + if (lastIndex == usedLore.size()) { + // There is more in lore than in usedLore, bad + return false; + } + String usedLine = usedLore.get(lastIndex); + if (line.equalsIgnoreCase(usedLine) || line.equalsIgnoreCase(ChatColor.stripColor(usedLine))) { + // If the line is correct, we have found our first and we want all consecutive lines to also equal + foundFirst = true; + } else if (foundFirst) { + // If a consecutive line is not equal, thats bad + return false; + } + lastIndex++; + // If we once found one correct line, iterate over 'lore' consecutively + } while (!foundFirst); + } + return true; + } + + // We don't compare id here + @Override + public boolean isSimilar(Ingredient item) { + if (this == item) { + return true; + } + if (item instanceof CustomItem) { + CustomItem ci = ((CustomItem) item); + return mat == ci.mat && Objects.equals(name, ci.name) && Objects.equals(lore, ci.lore); + } + return false; + } + + @Override + public boolean equals(Object obj) { + if (!super.equals(obj)) return false; + if (obj instanceof CustomItem) { + return isSimilar(((CustomItem) obj)); + } + return false; + } + + @Override + public int hashCode() { + return Objects.hash(super.hashCode(), mat, name, lore); + } + + @Override + public String toString() { + return "CustomItem{" + + "id=" + getConfigId() + + ", mat=" + (mat != null ? mat.name().toLowerCase() : "null") + + ", name='" + name + '\'' + + ", loresize: " + (lore != null ? lore.size() : 0) + + '}'; + } + + @Override + public void saveTo(DataOutputStream out) throws IOException { + out.writeUTF("CI"); + if (mat != null) { + out.writeBoolean(true); + out.writeUTF(mat.name()); + } else { + out.writeBoolean(false); + } + if (name != null) { + out.writeBoolean(true); + out.writeUTF(name); + } else { + out.writeBoolean(false); + } + if (lore != null) { + short size = (short) Math.min(lore.size(), Short.MAX_VALUE); + out.writeShort(size); + for (int i = 0; i < size; i++) { + out.writeUTF(lore.get(i)); + } + } else { + out.writeShort(0); + } + } + + public static CustomItem loadFrom(ItemLoader loader) { + try { + DataInputStream in = loader.getInputStream(); + CustomItem item = new CustomItem(); + if (in.readBoolean()) { + item.mat = Material.getMaterial(in.readUTF()); + } + if (in.readBoolean()) { + item.name = in.readUTF(); + } + short size = in.readShort(); + if (size > 0) { + item.lore = new ArrayList<>(size); + for (short i = 0; i < size; i++) { + item.lore.add(in.readUTF()); + } + } + return item; + } catch (IOException e) { + e.printStackTrace(); + return null; + } + } + + // Needs to be called at Server start + public static void registerItemLoader() { + Ingredient.registerForItemLoader("CI", CustomItem::loadFrom); + } +} diff --git a/src/com/dre/brewery/recipe/CustomMatchAnyItem.java b/src/com/dre/brewery/recipe/CustomMatchAnyItem.java new file mode 100644 index 0000000..840747d --- /dev/null +++ b/src/com/dre/brewery/recipe/CustomMatchAnyItem.java @@ -0,0 +1,231 @@ +package com.dre.brewery.recipe; + +import org.bukkit.ChatColor; +import org.bukkit.Material; +import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.meta.ItemMeta; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.util.ArrayList; +import java.util.List; +import java.util.Objects; + +/** + * Custom Item that matches any one of the given info. + * Does not implement Ingredient, as it can not directly be added to an ingredient + */ +public class CustomMatchAnyItem extends RecipeItem { + + private List materials; + private List names; + private List lore; + + + @Override + public boolean hasMaterials() { + return materials != null && !materials.isEmpty(); + } + + public boolean hasNames() { + return names != null && !names.isEmpty(); + } + + public boolean hasLore() { + return lore != null && !lore.isEmpty(); + } + + @Override + @Nullable + public List getMaterials() { + return materials; + } + + protected void setMaterials(List materials) { + this.materials = materials; + } + + @Nullable + public List getNames() { + return names; + } + + protected void setNames(List names) { + this.names = names; + } + + @Nullable + public List getLore() { + return lore; + } + + protected void setLore(List lore) { + this.lore = lore; + } + + @NotNull + @Override + public Ingredient toIngredient(ItemStack forItem) { + // We only use the one part of this item that actually matched the given item to add to ingredients + Material mat = getMaterialMatch(forItem); + if (mat != null) { + return new CustomItem(mat); + } + String name = getNameMatch(forItem); + if (name != null) { + return new CustomItem(null, name, null); + } + String l = getLoreMatch(forItem); + if (l != null) { + List lore = new ArrayList<>(1); + lore.add(l); + return new CustomItem(null, null, lore); + } + + // Shouldnt happen + return new SimpleItem(Material.GOLDEN_HOE); + } + + @NotNull + @Override + public Ingredient toIngredientGeneric() { + if (hasMaterials()) { + return new CustomItem(materials.get(0)); + } + if (hasNames()) { + return new CustomItem(null, names.get(0), null); + } + if (hasLore()) { + List l = new ArrayList<>(1); + l.add(lore.get(0)); + return new CustomItem(null, null, l); + } + + // Shouldnt happen + return new SimpleItem(Material.GOLDEN_HOE); + } + + public Material getMaterialMatch(ItemStack item) { + if (!hasMaterials()) return null; + + Material usedMat = item.getType(); + for (Material mat : materials) { + if (usedMat == mat) { + return mat; + } + } + return null; + } + + public String getNameMatch(ItemStack item) { + if (!item.hasItemMeta() || !hasNames()) { + return null; + } + ItemMeta meta = item.getItemMeta(); + assert meta != null; + if (meta.hasDisplayName()) { + return getNameMatch(meta.getDisplayName()); + } + return null; + } + + public String getNameMatch(String usedName) { + if (!hasNames()) return null; + + for (String name : names) { + if (name.equalsIgnoreCase(usedName)) { + return name; + } + } + return null; + } + + public String getLoreMatch(ItemStack item) { + if (!item.hasItemMeta() || !hasLore()) { + return null; + } + ItemMeta meta = item.getItemMeta(); + assert meta != null; + if (meta.hasLore()) { + return getLoreMatch(meta.getLore()); + } + return null; + } + + public String getLoreMatch(List usedLore) { + if (!hasLore()) return null; + + for (String line : this.lore) { + for (String usedLine : usedLore) { + if (line.equalsIgnoreCase(usedLine) || line.equalsIgnoreCase(ChatColor.stripColor(usedLine))) { + return line; + } + } + } + return null; + } + + @Override + public boolean matches(ItemStack item) { + if (getMaterialMatch(item) != null) { + return true; + } + if (getNameMatch(item) != null) { + return true; + } + return getLoreMatch(item) != null; + } + + @Override + public boolean matches(Ingredient ingredient) { + // Ingredient can not be CustomMatchAnyItem, so we don't need to/can't check for similarity. + if (ingredient instanceof CustomItem) { + // If the custom item has any of our data, we match + CustomItem ci = ((CustomItem) ingredient); + if (hasMaterials() && ci.hasMaterials()) { + if (materials.contains(ci.getMaterial())) { + return true; + } + } + if (hasNames() && ci.hasName()) { + if (getNameMatch(ci.getName()) != null) { + return true; + } + } + if (hasLore() && ci.hasLore()) { + return getLoreMatch(ci.getLore()) != null; + } + } else if (ingredient instanceof SimpleItem) { + // If we contain the Material of the Simple Item, we match + SimpleItem si = (SimpleItem) ingredient; + return hasMaterials() && materials.contains(si.getMaterial()); + } + return false; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + if (!super.equals(o)) return false; + CustomMatchAnyItem that = (CustomMatchAnyItem) o; + return Objects.equals(materials, that.materials) && + Objects.equals(names, that.names) && + Objects.equals(lore, that.lore); + } + + @Override + public int hashCode() { + return Objects.hash(super.hashCode(), materials, names, lore); + } + + @Override + public String toString() { + return "CustomMatchAnyItem{" + + "id=" + getConfigId() + + ", materials: " + (materials != null ? materials.size() : 0) + + ", names:" + (names != null ? names.size() : 0) + + ", loresize: " + (lore != null ? lore.size() : 0) + + '}'; + } +} diff --git a/src/com/dre/brewery/recipe/Ingredient.java b/src/com/dre/brewery/recipe/Ingredient.java new file mode 100644 index 0000000..9d8ab64 --- /dev/null +++ b/src/com/dre/brewery/recipe/Ingredient.java @@ -0,0 +1,88 @@ +package com.dre.brewery.recipe; + +import org.bukkit.inventory.ItemStack; + +import java.io.DataOutputStream; +import java.io.IOException; +import java.util.HashMap; +import java.util.Map; +import java.util.function.Function; + +/** + * Item used in a BIngredients, inside BCauldron or Brew. + * Represents the Items used as ingredients in the Brewing process + * Can be a copy of a recipe item + * Will be saved and loaded with a DataStream + * Each implementing class needs to register a static function as Item Loader + */ +public interface Ingredient { + + Map> LOADERS = new HashMap<>(); + + /** + * Register a Static function as function that takes an ItemLoader, containing a DataInputStream. + * Using the Stream it constructs a corresponding Ingredient for the chosen SaveID + * + * @param saveID The SaveID should be a small identifier like "AB" + * @param loadFct The Static Function that loads the Item, i.e. + * public static AItem loadFrom(ItemLoader loader) + */ + static void registerForItemLoader(String saveID, Function loadFct) { + LOADERS.put(saveID, loadFct); + } + + /** + * Unregister the ItemLoader + * + * @param saveID the chosen SaveID + */ + static void unRegisterItemLoader(String saveID) { + LOADERS.remove(saveID); + } + + + /** + * Saves this Ingredient to the DataOutputStream. + * The first data HAS to be storing the SaveID like: + * out.writeUTF("AB"); + * Amount will be saved automatically and does not have to be saved here. + * Saving is done to Brew or for BCauldron into data.yml + * + * @param out The outputstream to write to + * @throws IOException Any IOException + */ + void saveTo(DataOutputStream out) throws IOException; + + int getAmount(); + + void setAmount(int amount); + + /** + * Does this Ingredient match the given ItemStack + * + * @param item The given ItemStack to match + * @return true if all required data is contained on the item + */ + boolean matches(ItemStack item); + + /* + * Does this Item match the given RecipeItem. + * An IngredientItem matches a RecipeItem if all required info of the RecipeItem are fulfilled on this IngredientItem + * This does not imply that the same holds the other way round, as this item might have more info than needed + * + * + * @param recipeItem The recipeItem whose requirements need to be fulfilled + * @return True if this matches the required info of the recipeItem + */ + //boolean matches(RecipeItem recipeItem); + + /** + * The other Ingredient is Similar if it is equal except amount + * + * @param item The item to check similarity with + * @return True if this is equal to item except for amount + */ + boolean isSimilar(Ingredient item); + + +} diff --git a/src/com/dre/brewery/recipe/ItemLoader.java b/src/com/dre/brewery/recipe/ItemLoader.java new file mode 100644 index 0000000..720a63e --- /dev/null +++ b/src/com/dre/brewery/recipe/ItemLoader.java @@ -0,0 +1,28 @@ +package com.dre.brewery.recipe; + +import java.io.DataInputStream; + +public class ItemLoader { + + private final int version; + private final DataInputStream in; + private final String saveID; + + public ItemLoader(int version, DataInputStream in, String saveID) { + this.version = version; + this.in = in; + this.saveID = saveID; + } + + public int getVersion() { + return version; + } + + public DataInputStream getInputStream() { + return in; + } + + public String getSaveID() { + return saveID; + } +} diff --git a/src/com/dre/brewery/recipe/PluginItem.java b/src/com/dre/brewery/recipe/PluginItem.java new file mode 100644 index 0000000..8234e87 --- /dev/null +++ b/src/com/dre/brewery/recipe/PluginItem.java @@ -0,0 +1,213 @@ +package com.dre.brewery.recipe; + +import org.bukkit.Material; +import org.bukkit.inventory.ItemStack; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.io.DataInputStream; +import java.io.DataOutputStream; +import java.io.IOException; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Objects; +import java.util.function.Supplier; + +/** + * An Item of a Recipe or as Ingredient in a Brew that corresponds to an item from another plugin. + * See /integration/item for examples on how to extend this class. + * This class stores items as name of the plugin and item id + */ +public abstract class PluginItem extends RecipeItem implements Ingredient { + + private static Map> constructors = new HashMap<>(); + + private String plugin; + private String itemId; + + /** + * New Empty PluginItem + */ + public PluginItem() { + } + + /** + * New PluginItem with both fields already set + * + * @param plugin The name of the Plugin + * @param itemId The ItemID + */ + public PluginItem(String plugin, String itemId) { + this.plugin = plugin; + this.itemId = itemId; + } + + + @Override + public boolean hasMaterials() { + return false; + } + + @Override + public List getMaterials() { + return null; + } + + public String getPlugin() { + return plugin; + } + + public String getItemId() { + return itemId; + } + + protected void setPlugin(String plugin) { + this.plugin = plugin; + } + + protected void setItemId(String itemId) { + this.itemId = itemId; + } + + /** + * Called after Loading this Plugin Item from Config, or (by default) from Ingredients. + * Allows Override to define custom actions after an Item was constructed + */ + protected void onConstruct() { + } + + /** + * Does this PluginItem Match the other Ingredient. + * By default it matches exactly when they are similar, i.e. also a PluginItem with same parameters + * + * @param ingredient The ingredient that needs to fulfill the requirements + * @return True if the ingredient matches the required info of this + */ + @Override + public boolean matches(Ingredient ingredient) { + return isSimilar(ingredient); + } + + @NotNull + @Override + public Ingredient toIngredient(ItemStack forItem) { + return ((PluginItem) getMutableCopy()); + } + + @NotNull + @Override + public Ingredient toIngredientGeneric() { + return ((PluginItem) getMutableCopy()); + } + + @Override + public boolean isSimilar(Ingredient item) { + if (item instanceof PluginItem) { + return Objects.equals(plugin, ((PluginItem) item).plugin) && Objects.equals(itemId, ((PluginItem) item).itemId); + } + return false; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + if (!super.equals(o)) return false; + PluginItem item = (PluginItem) o; + return Objects.equals(plugin, item.plugin) && + Objects.equals(itemId, item.itemId); + } + + @Override + public int hashCode() { + return Objects.hash(super.hashCode(), plugin, itemId); + } + + @Override + public void saveTo(DataOutputStream out) throws IOException { + out.writeUTF("PI"); + out.writeUTF(plugin); + out.writeUTF(itemId); + } + + /** + * Called when loading this Plugin Item from Ingredients (of a Brew) + * The default loading is the same as loading from Config + * + * @param loader The ItemLoader from which to load the data, use loader.getInputStream() + * @return The constructed PluginItem + */ + public static PluginItem loadFrom(ItemLoader loader) { + try { + DataInputStream in = loader.getInputStream(); + String plugin = in.readUTF(); + String itemId = in.readUTF(); + PluginItem item = fromConfig(plugin, itemId); + if (item == null) { + // Plugin not found when loading from Item, use a generic PluginItem that never matches other items + item = new PluginItem(plugin, itemId) { + @Override + public boolean matches(ItemStack item) { + return false; + } + }; + } + return item; + } catch (IOException e) { + e.printStackTrace(); + return null; + } + } + + /** + * Needs to be called at Server start + * Registers the chosen SaveID and the loading Method for loading from Brew or BCauldron + */ + public static void registerItemLoader() { + Ingredient.registerForItemLoader("PI", PluginItem::loadFrom); + } + + + /** + * Called when loading trying to find a config defined Plugin Item, or by default also when loading from ingredients + * Will call a registered constructor matching the given plugin identifier + * + * @param plugin The Identifier of the Plugin used in the config + * @param itemId The Identifier of the Item belonging to this Plugin used in the config + * @return The Plugin Item if found, or null if there is no plugin for the given String + */ + @Nullable + public static PluginItem fromConfig(String plugin, String itemId) { + plugin = plugin.toLowerCase(); + if (constructors.containsKey(plugin)) { + PluginItem item = constructors.get(plugin).get(); + item.setPlugin(plugin); + item.setItemId(itemId); + item.onConstruct(); + return item; + } + return null; + } + + + /** + * This needs to be called at Server Start before Brewery loads its data. + * When implementing this, put Brewery as softdepend in your plugin.yml! + * Registers a Constructor that returns a new or cloned instance of a PluginItem + * This Constructor will be called when loading a Plugin Item from Config or by default from ingredients + * After the Constructor is called, the plugin and itemid will be set on the new instance + * Finally the onConstruct is called. + * + * @param pluginId The ID to use in the config + * @param constructor The constructor i.e. YourPluginItem::new + */ + public static void registerForConfig(String pluginId, Supplier constructor) { + constructors.put(pluginId.toLowerCase(), constructor); + } + + public static void unRegisterForConfig(String pluginId) { + constructors.remove(pluginId.toLowerCase()); + } + +} diff --git a/src/com/dre/brewery/recipe/RecipeItem.java b/src/com/dre/brewery/recipe/RecipeItem.java new file mode 100644 index 0000000..6ff6d67 --- /dev/null +++ b/src/com/dre/brewery/recipe/RecipeItem.java @@ -0,0 +1,314 @@ +package com.dre.brewery.recipe; + +import com.dre.brewery.P; +import com.dre.brewery.filedata.BConfig; +import org.bukkit.Material; +import org.bukkit.configuration.ConfigurationSection; +import org.bukkit.inventory.ItemStack; +import org.jetbrains.annotations.Contract; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.util.ArrayList; +import java.util.List; +import java.util.Objects; +import java.util.stream.Collectors; + +/** + * Item that can be used in a Recipe. + * They are not necessarily only loaded from config + * They are immutable if used in a recipe. If one implements Ingredient, + * it can be used as mutable copy directly in a + * BIngredients. Otherwise it needs to be converted to an Ingredient + */ +public abstract class RecipeItem implements Cloneable { + + private String cfgId; + private int amount; + private boolean immutable = false; + + + /** + * Does this RecipeItem match the given ItemStack? + * Used to determine if the given item corresponds to this recipeitem + * + * @param item The ItemStack for comparison + * @return True if the given item matches this recipeItem + */ + public abstract boolean matches(ItemStack item); + + /** + * Does this Item match the given Ingredient. + * A RecipeItem matches an Ingredient if all required info of the RecipeItem are fulfilled on the Ingredient + * This does not imply that the same holds the other way round, as the ingredient item might have more info than needed + * + * + * @param ingredient The ingredient that needs to fulfill the requirements + * @return True if the ingredient matches the required info of this + */ + public abstract boolean matches(Ingredient ingredient); + + /** + * Get the Corresponding Ingredient Item. For Items implementing Ingredient, just getMutableCopy() + * This is called when this recipe item is added to a BIngredients + * + * @param forItem The ItemStack that has previously matched this RecipeItem. Used if the resulting Ingredient needs more info from the ItemStack + * @return The IngredientItem corresponding to this RecipeItem + */ + @NotNull + public abstract Ingredient toIngredient(ItemStack forItem); + + /** + * Gets a Generic Ingredient for this recipe item + */ + @NotNull + public abstract Ingredient toIngredientGeneric(); + + /** + * @return True if this recipeItem has one or more materials that could classify an item. if true, getMaterials() is NotNull + */ + public abstract boolean hasMaterials(); + + /** + * @return List of one or more Materials this recipeItem uses. + */ + @Nullable + public abstract List getMaterials(); + + /** + * @return The Id this Item uses in the config in the custom-items section + */ + @Nullable + public String getConfigId() { + return cfgId; + } + + /** + * @return The Amount of this Item in a Recipe + */ + public int getAmount() { + return amount; + } + + /** + * Set the Amount of this Item in a Recipe + * The amount can not be set on an existing item in a recipe or existing custom item. + * To change amount you need to use getMutableCopy() and change the amount on the copy + * + * @param amount The new amount + */ + public void setAmount(int amount) { + if (immutable) throw new IllegalStateException("Setting amount only possible on mutable copy"); + this.amount = amount; + } + + /** + * Makes this Item immutable, for example when loaded from config. Used so if this is added to BIngredients, + * it needs to be cloned before changing anything like amount + */ + public void makeImmutable() { + immutable = true; + } + + /** + * Gets a shallow clone of this RecipeItem whose fields like amount can be changed. + * + * @return A mutable copy of this + */ + public RecipeItem getMutableCopy() { + try { + RecipeItem i = (RecipeItem) super.clone(); + i.immutable = false; + return i; + } catch (CloneNotSupportedException e) { + throw new InternalError(e); + } + } + + /** + * Tries to find a matching RecipeItem for this item. It checks custom items and if it has found a unique custom item + * it will return that. If there are multiple matching custom items, a new CustomItem with all item info is returned + * If there is no matching CustomItem, it will return a SimpleItem with the items type + * + * @param item The Item for which to find a matching RecipeItem + * @param acceptAll If true it will accept any item and return a SimpleItem even if not on the accepted list + * If false it will return null if the item is not acceptable by the Cauldron + * @return The Matched CustomItem, new CustomItem with all item info or SimpleItem + */ + @Nullable + @Contract("_, true -> !null") + public static RecipeItem getMatchingRecipeItem(ItemStack item, boolean acceptAll) { + RecipeItem rItem = null; + boolean multiMatch = false; + for (RecipeItem ri : BCauldronRecipe.acceptedCustom) { + // If we already have a multi match, only check if there is a PluginItem that matches more strictly + if (!multiMatch || (ri instanceof PluginItem)) { + if (ri.matches(item)) { + // If we match a plugin item, thats a very strict match, so immediately return it + if (ri instanceof PluginItem) { + return ri; + } + if (rItem == null) { + rItem = ri; + } else { + multiMatch = true; + } + } + } + } + if (multiMatch) { + // We have multiple Custom Items matching, so just store all item info + return new CustomItem(item); + } + if (rItem == null && (acceptAll || BCauldronRecipe.acceptedSimple.contains(item.getType()))) { + // No Custom item found + if (P.use1_13) { + return new SimpleItem(item.getType()); + } else { + //noinspection deprecation + return new SimpleItem(item.getType(), item.getDurability()); + } + } + return rItem; + } + + @Nullable + public static RecipeItem fromConfigCustom(ConfigurationSection cfg, String id) { + RecipeItem rItem; + if (cfg.getBoolean(id + ".matchAny", false)) { + rItem = new CustomMatchAnyItem(); + } else { + rItem = new CustomItem(); + } + + rItem.cfgId = id; + rItem.immutable = true; + + List materials; + List names; + List lore; + + List load = null; + String path = id + ".material"; + if (cfg.isString(path)) { + load = new ArrayList<>(1); + load.add(cfg.getString(path)); + } else if (cfg.isList(path)) { + load = cfg.getStringList(path); + } + if (load != null && !load.isEmpty()) { + if ((materials = loadMaterials(load)) == null) { + return null; + } + } else { + materials = new ArrayList<>(0); + } + + load = null; + path = id + ".name"; + if (cfg.isString(path)) { + load = new ArrayList<>(1); + load.add(cfg.getString(path)); + } else if (cfg.isList(path)) { + load = cfg.getStringList(path); + } + if (load != null && !load.isEmpty()) { + names = load.stream().map(l -> P.p.color(l)).collect(Collectors.toList()); + if (P.use1_13) { + // In 1.13 trailing Color white is removed from display names + names = names.stream().map(l -> l.startsWith("§f") ? l.substring(2) : l).collect(Collectors.toList()); + } + } else { + names = new ArrayList<>(0); + } + + load = null; + path = id + ".lore"; + if (cfg.isString(path)) { + load = new ArrayList<>(1); + load.add(cfg.getString(path)); + } else if (cfg.isList(path)) { + load = cfg.getStringList(path); + } + if (load != null && !load.isEmpty()) { + lore = load.stream().map(l -> P.p.color(l)).collect(Collectors.toList()); + } else { + lore = new ArrayList<>(0); + } + + if (materials.isEmpty() && names.isEmpty() && lore.isEmpty()) { + P.p.errorLog("No Config Entries found for Custom Item"); + return null; + } + + if (rItem instanceof CustomItem) { + CustomItem cItem = ((CustomItem) rItem); + if (!materials.isEmpty()) { + cItem.setMat(materials.get(0)); + } + if (!names.isEmpty()) { + cItem.setName(names.get(0)); + } + cItem.setLore(lore); + } else { + CustomMatchAnyItem maItem = (CustomMatchAnyItem) rItem; + maItem.setMaterials(materials); + maItem.setNames(names); + maItem.setLore(lore); + } + + return rItem; + } + + @Nullable + protected static List loadMaterials(List ingredientsList) { + List materials = new ArrayList<>(ingredientsList.size()); + for (String item : ingredientsList) { + String[] ingredParts = item.split("/"); + if (ingredParts.length == 2) { + P.p.errorLog("Item Amount can not be specified for Custom Items: " + item); + return null; + } + Material mat = Material.matchMaterial(ingredParts[0]); + + if (mat == null && BConfig.hasVault) { + try { + net.milkbowl.vault.item.ItemInfo vaultItem = net.milkbowl.vault.item.Items.itemByString(ingredParts[0]); + if (vaultItem != null) { + mat = vaultItem.getType(); + } + } catch (Exception e) { + P.p.errorLog("Could not check vault for Item Name"); + e.printStackTrace(); + } + } + if (mat != null) { + materials.add(mat); + } else { + P.p.errorLog("Unknown Material: " + ingredParts[0]); + return null; + } + } + return materials; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (!(o instanceof RecipeItem)) return false; + RecipeItem that = (RecipeItem) o; + return amount == that.amount && + immutable == that.immutable && + Objects.equals(cfgId, that.cfgId); + } + + @Override + public int hashCode() { + return Objects.hash(cfgId, amount, immutable); + } + + @Override + public String toString() { + return "RecipeItem{(" + getClass().getSimpleName() + ") ID: " + getConfigId() + " Materials: " + (hasMaterials() ? getMaterials().size() : 0) + " Amount: " + getAmount(); + } +} diff --git a/src/com/dre/brewery/recipe/SimpleItem.java b/src/com/dre/brewery/recipe/SimpleItem.java new file mode 100644 index 0000000..db3a7a4 --- /dev/null +++ b/src/com/dre/brewery/recipe/SimpleItem.java @@ -0,0 +1,151 @@ +package com.dre.brewery.recipe; + +import com.dre.brewery.P; +import org.bukkit.Material; +import org.bukkit.inventory.ItemStack; +import org.jetbrains.annotations.NotNull; + +import java.io.DataInputStream; +import java.io.DataOutputStream; +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; +import java.util.Objects; + +/** + * Simple Minecraft Item with just Material + */ +public class SimpleItem extends RecipeItem implements Ingredient { + + private Material mat; + private short dur; // Old Mc + + + public SimpleItem(Material mat) { + this(mat, (short) 0); + } + + public SimpleItem(Material mat, short dur) { + this.mat = mat; + this.dur = dur; + } + + @Override + public boolean hasMaterials() { + return mat != null; + } + + public Material getMaterial() { + return mat; + } + + @Override + public List getMaterials() { + List l = new ArrayList<>(1); + l.add(mat); + return l; + } + + @NotNull + @Override + public Ingredient toIngredient(ItemStack forItem) { + return ((SimpleItem) getMutableCopy()); + } + + @NotNull + @Override + public Ingredient toIngredientGeneric() { + return ((SimpleItem) getMutableCopy()); + } + + @Override + public boolean matches(ItemStack item) { + if (!mat.equals(item.getType())) { + return false; + } + //noinspection deprecation + return P.use1_13 || dur == item.getDurability(); + } + + @Override + public boolean matches(Ingredient ingredient) { + if (isSimilar(ingredient)) { + return true; + } + if (ingredient instanceof RecipeItem) { + if (!((RecipeItem) ingredient).hasMaterials()) { + return false; + } + if (ingredient instanceof CustomItem) { + // Only match if the Custom Item also only defines material + // If the custom item has more info like name and lore, it is not supposed to match a simple item + CustomItem ci = (CustomItem) ingredient; + return !ci.hasLore() && !ci.hasName() && mat == ci.getMaterial(); + } + } + return false; + } + + @Override + public boolean isSimilar(Ingredient item) { + if (this == item) { + return true; + } + if (item instanceof SimpleItem) { + SimpleItem si = ((SimpleItem) item); + return si.mat == mat && si.dur == dur; + } + return false; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + if (!super.equals(o)) return false; + SimpleItem item = (SimpleItem) o; + return dur == item.dur && + mat == item.mat; + } + + @Override + public int hashCode() { + return Objects.hash(super.hashCode(), mat, dur); + } + + @Override + public String toString() { + return "SimpleItem{" + + "mat=" + mat.name().toLowerCase() + + " amount=" + getAmount() + + '}'; + } + + @Override + public void saveTo(DataOutputStream out) throws IOException { + out.writeUTF("SI"); + out.writeUTF(mat.name()); + out.writeShort(dur); + } + + public static SimpleItem loadFrom(ItemLoader loader) { + try { + DataInputStream in = loader.getInputStream(); + Material mat = Material.getMaterial(in.readUTF()); + if (mat != null) { + SimpleItem item = new SimpleItem(mat, in.readShort()); + return item; + } + } catch (IOException e) { + e.printStackTrace(); + } + return null; + } + + // Needs to be called at Server start + public static void registerItemLoader() { + Ingredient.registerForItemLoader("SI", SimpleItem::loadFrom); + } + +} + diff --git a/src/com/dre/brewery/utility/CustomItem.java b/src/com/dre/brewery/utility/CustomItem.java deleted file mode 100644 index 8ec6849..0000000 --- a/src/com/dre/brewery/utility/CustomItem.java +++ /dev/null @@ -1,329 +0,0 @@ -package com.dre.brewery.utility; - -import com.dre.brewery.P; -import com.dre.brewery.filedata.BConfig; -import org.bukkit.ChatColor; -import org.bukkit.Material; -import org.bukkit.configuration.ConfigurationSection; -import org.bukkit.inventory.ItemStack; -import org.bukkit.inventory.meta.ItemMeta; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; - -import java.util.ArrayList; -import java.util.List; -import java.util.stream.Collectors; - -public class CustomItem { - private String id; - private boolean simple; // Simple Custom Item is just materials.get(0) and durability for old mc - private boolean matchAny; // If only one of the values needs to match - private short dur; // Old Mc - private List materials; - private List names; - private List lore; - - public static CustomItem asSimpleItem(Material mat) { - return asSimpleItem(mat, (short) 0); - } - - public static CustomItem asSimpleItem(Material mat, short dur) { - CustomItem it = new CustomItem(); - it.simple = true; - it.dur = dur; - it.materials = new ArrayList<>(1); - it.materials.add(mat); - return it; - } - - @Nullable - public static CustomItem fromConfig(ConfigurationSection cfg, String id) { - CustomItem custom = new CustomItem(); - - custom.id = id; - custom.matchAny = cfg.getBoolean(id + ".matchAny", false); - - List load = null; - String path = id + ".material"; - if (cfg.isString(path)) { - load = new ArrayList<>(1); - load.add(cfg.getString(path)); - } else if (cfg.isList(path)) { - load = cfg.getStringList(path); - } - if (load != null && !load.isEmpty()) { - custom.materials = new ArrayList<>(load.size()); - if (!custom.loadMaterials(load)) { - return null; - } - } else { - custom.materials = new ArrayList<>(0); - } - - load = null; - path = id + ".name"; - if (cfg.isString(path)) { - load = new ArrayList<>(1); - load.add(cfg.getString(path)); - } else if (cfg.isList(path)) { - load = cfg.getStringList(path); - } - if (load != null && !load.isEmpty()) { - custom.names = load.stream().map(l -> P.p.color(l)).collect(Collectors.toList()); - if (P.use1_13) { - // In 1.13 trailing Color white is removed from display names - custom.names = custom.names.stream().map(l -> l.startsWith("§f") ? l.substring(2) : l).collect(Collectors.toList()); - } - } else { - custom.names = new ArrayList<>(0); - } - - load = null; - path = id + ".lore"; - if (cfg.isString(path)) { - load = new ArrayList<>(1); - load.add(cfg.getString(path)); - } else if (cfg.isList(path)) { - load = cfg.getStringList(path); - } - if (load != null && !load.isEmpty()) { - custom.lore = load.stream().map(l -> P.p.color(l)).collect(Collectors.toList()); - } else { - custom.lore = new ArrayList<>(0); - } - - if (custom.materials.isEmpty() && custom.names.isEmpty() && custom.lore.isEmpty()) { - P.p.errorLog("No Config Entries found for Custom Item"); - return null; - } - - return custom; - } - - private boolean loadMaterials(List ingredientsList) { - for (String item : ingredientsList) { - String[] ingredParts = item.split("/"); - if (ingredParts.length == 2) { - P.p.errorLog("Item Amount can not be specified for Custom Items: " + item); - return false; - } - Material mat = Material.matchMaterial(ingredParts[0]); - - if (mat == null && BConfig.hasVault) { - try { - net.milkbowl.vault.item.ItemInfo vaultItem = net.milkbowl.vault.item.Items.itemByString(ingredParts[0]); - if (vaultItem != null) { - mat = vaultItem.getType(); - } - } catch (Exception e) { - P.p.errorLog("Could not check vault for Item Name"); - e.printStackTrace(); - } - } - if (mat != null) { - materials.add(mat); - } else { - P.p.errorLog("Unknown Material: " + ingredParts[0]); - return false; - } - } - return true; - } - - public String getId() { - return id; - } - - public boolean isSimple() { - return simple; - } - - public boolean isMatchAny() { - return matchAny; - } - - public List getMaterials() { - return materials; - } - - public Material getSimpleMaterial() { - return materials.get(0); - } - - public List getNames() { - return names; - } - - public List getLore() { - return lore; - } - - public boolean matches(ItemStack usedItem) { - if (simple) { - return matchSimple(usedItem); - } else if (matchAny){ - return matchAny(usedItem); - } else { - return matchOne(usedItem); - } - } - - private boolean matchSimple(ItemStack usedItem) { - if (!materials.get(0).equals(usedItem.getType())) { - return false; - } - //noinspection deprecation - return P.use1_13 || dur == usedItem.getDurability(); - } - - private boolean matchAny(ItemStack usedItem) { - Material usedMat = usedItem.getType(); - for (Material mat : materials) { - if (usedMat == mat) { - return true; - } - } - if (!usedItem.hasItemMeta()) { - return false; - } - ItemMeta meta = usedItem.getItemMeta(); - assert meta != null; - if (meta.hasDisplayName()) { - String usedName = meta.getDisplayName(); - for (String name : names) { - if (name.equalsIgnoreCase(usedName)) { - return true; - } - } - } - - if (meta.hasLore()) { - List usedLore = meta.getLore(); - assert usedLore != null; - for (String line : this.lore) { - for (String usedLine : usedLore) { - if (line.equalsIgnoreCase(usedLine) || line.equalsIgnoreCase(ChatColor.stripColor(usedLine))) { - return true; - } - } - } - } - return false; - } - - private boolean matchOne(ItemStack item) { - if (!materials.isEmpty()) { - if (item.getType() != materials.get(0)) { - return false; - } - } - if (names.isEmpty() && lore.isEmpty()) { - return true; - } - if (!item.hasItemMeta()) { - return false; - } - ItemMeta meta = item.getItemMeta(); - assert meta != null; - if (!names.isEmpty()) { - if (!meta.hasDisplayName() || !names.get(0).equalsIgnoreCase(meta.getDisplayName())) { - return false; - } - } - - - if (!lore.isEmpty()) { - if (!meta.hasLore()) { - return false; - } - - int lastIndex = 0; - List usedLore = meta.getLore(); - assert usedLore != null; - boolean foundFirst = false; - for (String line : lore) { - do { - if (lastIndex == usedLore.size()) { - // There is more in lore than in usedLore, bad - return false; - } - String usedLine = usedLore.get(lastIndex); - if (line.equalsIgnoreCase(usedLine) || line.equalsIgnoreCase(ChatColor.stripColor(usedLine))) { - // If the line is correct, we have found our first and we want all consecutive lines to also equal - foundFirst = true; - } else if (foundFirst) { - // If a consecutive line is not equal, thats bad - return false; - } - lastIndex++; - // If we once found one correct line, iterate over 'lore' consecutively - } while (!foundFirst); - } - } - return true; - } - - @NotNull - public ItemStack createDummy(int amount) { - if (simple) { - if (P.use1_13) { - return new ItemStack(getSimpleMaterial(), amount); - } else { - //noinspection deprecation - return new ItemStack(getSimpleMaterial(), amount, dur); - } - } else if (matchAny) { - if (!materials.isEmpty()) { - return new ItemStack(materials.get(0), amount); - } else if (!names.isEmpty()) { - ItemStack item = new ItemStack(Material.DIAMOND_HOE, amount); - ItemMeta meta = item.hasItemMeta() ? item.getItemMeta() : P.p.getServer().getItemFactory().getItemMeta(Material.DIAMOND_HOE); - assert meta != null; - meta.setDisplayName(names.get(0)); - item.setItemMeta(meta); - return item; - } else if (!lore.isEmpty()) { - ItemStack item = new ItemStack(Material.DIAMOND_HOE, amount); - ItemMeta meta = item.hasItemMeta() ? item.getItemMeta() : P.p.getServer().getItemFactory().getItemMeta(Material.DIAMOND_HOE); - assert meta != null; - List l = new ArrayList<>(); - l.add(lore.get(0)); - meta.setLore(l); - item.setItemMeta(meta); - return item; - } - return new ItemStack(Material.DIAMOND_HOE, amount); - } else { - ItemStack item; - ItemMeta meta; - if (!materials.isEmpty()) { - item = new ItemStack(materials.get(0), amount); - meta = item.hasItemMeta() ? item.getItemMeta() : P.p.getServer().getItemFactory().getItemMeta(materials.get(0)); - } else { - item = new ItemStack(Material.DIAMOND_HOE, amount); - meta = item.hasItemMeta() ? item.getItemMeta() : P.p.getServer().getItemFactory().getItemMeta(Material.DIAMOND_HOE); - } - assert meta != null; - if (!names.isEmpty()) { - meta.setDisplayName(names.get(0)); - item.setItemMeta(meta); - } - if (!lore.isEmpty()) { - meta.setLore(lore); - item.setItemMeta(meta); - } - return item; - } - } - - @Override - public String toString() { - if (simple) { - return "CustomItem{Simple: " + getSimpleMaterial().name().toLowerCase() + "}"; - } - if (materials == null || names == null || lore == null) { - return "CustomItem{" + id + "}"; - } - return "CustomItem{" + id + ": " + (matchAny ? "MatchAny, " : "MatchOne, ") + materials.size() + " Materials, " + names.size() + " Names, " + lore.size() + " Lore}"; - } -} diff --git a/test/com/dre/brewery/RecipeTests.java b/test/com/dre/brewery/RecipeTests.java index 284d325..6b9e63c 100644 --- a/test/com/dre/brewery/RecipeTests.java +++ b/test/com/dre/brewery/RecipeTests.java @@ -1,5 +1,10 @@ package com.dre.brewery; +import com.dre.brewery.recipe.BCauldronRecipe; +import com.dre.brewery.recipe.BRecipe; +import com.dre.brewery.recipe.Ingredient; +import com.dre.brewery.recipe.RecipeItem; +import com.dre.brewery.recipe.SimpleItem; import org.bukkit.Material; import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.meta.ItemMeta; @@ -24,9 +29,12 @@ public class RecipeTests { int y = recipe.amountOf(new ItemStack(Material.NETHER_BRICK)); - List list = new ArrayList<>(); - list.add(new ItemStack(Material.DIAMOND_HOE, 3)); - list.add(new ItemStack(Material.RED_MUSHROOM, 1)); + List list = new ArrayList<>(); + Ingredient ing = new SimpleItem(Material.DIAMOND_HOE); + ing.setAmount(3); + list.add(ing); + ing = new SimpleItem(Material.RED_MUSHROOM); + list.add(ing); for (int i = 1; i < 20; i++) { list.get(0).setAmount(i + 3); list.get(1).setAmount(i); @@ -46,5 +54,16 @@ public class RecipeTests { } P.p.debugLog("Found best for i:" + i + " " + best); } + + item = new ItemStack(Material.BARRIER); + itemMeta = item.getItemMeta(); + l = new ArrayList<>(); + l.add("Eine Tür"); + l.add("§6Besonders gut geschützt"); + itemMeta.setLore(l); + itemMeta.setDisplayName("Mauer"); + item.setItemMeta(itemMeta); + + RecipeItem.getMatchingRecipeItem(item, false); } } From 4c77944eb8e8803fe772295b629fff86c5419680 Mon Sep 17 00:00:00 2001 From: Sn0wStorm Date: Fri, 8 Nov 2019 16:22:58 +0100 Subject: [PATCH 31/51] Find more suitable Data Structures --- src/com/dre/brewery/BCauldron.java | 50 ++--- src/com/dre/brewery/BIngredients.java | 33 ++- src/com/dre/brewery/BPlayer.java | 26 +-- src/com/dre/brewery/Barrel.java | 9 +- src/com/dre/brewery/Brew.java | 4 +- src/com/dre/brewery/DistortChat.java | 4 +- src/com/dre/brewery/P.java | 10 +- src/com/dre/brewery/Wakeup.java | 3 +- src/com/dre/brewery/filedata/BConfig.java | 4 +- .../dre/brewery/filedata/LanguageReader.java | 208 +++++++++--------- .../dre/brewery/listeners/EntityListener.java | 6 +- src/com/dre/brewery/lore/BrewLore.java | 2 +- .../dre/brewery/recipe/BCauldronRecipe.java | 1 - src/com/dre/brewery/recipe/BRecipe.java | 5 +- .../{utility => recipe}/PotionColor.java | 2 +- src/com/dre/brewery/utility/BoundingBox.java | 7 +- src/com/dre/brewery/utility/LegacyUtil.java | 14 +- 17 files changed, 191 insertions(+), 197 deletions(-) rename src/com/dre/brewery/{utility => recipe}/PotionColor.java (99%) diff --git a/src/com/dre/brewery/BCauldron.java b/src/com/dre/brewery/BCauldron.java index b8558f2..148589c 100644 --- a/src/com/dre/brewery/BCauldron.java +++ b/src/com/dre/brewery/BCauldron.java @@ -16,16 +16,18 @@ import org.bukkit.entity.Player; import org.bukkit.event.player.PlayerInteractEvent; import org.bukkit.inventory.EquipmentSlot; import org.bukkit.inventory.ItemStack; +import org.jetbrains.annotations.Nullable; +import java.util.HashMap; import java.util.HashSet; +import java.util.Map; import java.util.Set; import java.util.UUID; -import java.util.concurrent.CopyOnWriteArrayList; public class BCauldron { public static final byte EMPTY = 0, SOME = 1, FULL = 2; private static Set plInteracted = new HashSet<>(); - public static CopyOnWriteArrayList bcauldrons = new CopyOnWriteArrayList<>(); // TODO find best Collection + public static Map bcauldrons = new HashMap<>(); // All active cauldrons. Mapped to their block for fast retrieve private BIngredients ingredients = new BIngredients(); private final Block block; @@ -34,7 +36,7 @@ public class BCauldron { public BCauldron(Block block) { this.block = block; - bcauldrons.add(this); + bcauldrons.put(block, this); } // loading from file @@ -42,7 +44,7 @@ public class BCauldron { this.block = block; this.state = state; this.ingredients = ingredients; - bcauldrons.add(this); + bcauldrons.put(block, this); } public void onUpdate() { @@ -73,13 +75,9 @@ public class BCauldron { } // get cauldron by Block + @Nullable public static BCauldron get(Block block) { - for (BCauldron bcauldron : bcauldrons) { - if (bcauldron.block.equals(block)) { - return bcauldron; - } - } - return null; + return bcauldrons.get(block); } // get cauldron from block and add given ingredient @@ -87,10 +85,6 @@ public class BCauldron { public static boolean ingredientAdd(Block block, ItemStack ingredient, Player player) { // if not empty if (LegacyUtil.getFillLevel(block) != EMPTY) { - BCauldron bcauldron = get(block); - if (bcauldron == null) { - bcauldron = new BCauldron(block); - } if (!BCauldronRecipe.acceptedMaterials.contains(ingredient.getType()) && !ingredient.hasItemMeta()) { // Extremely fast way to check for most items @@ -102,10 +96,16 @@ public class BCauldron { return false; } + BCauldron bcauldron = get(block); + if (bcauldron == null) { + bcauldron = new BCauldron(block); + } + IngedientAddEvent event = new IngedientAddEvent(player, block, bcauldron, ingredient.clone(), rItem); P.p.getServer().getPluginManager().callEvent(event); if (!event.isCancelled()) { bcauldron.add(event.getIngredient(), event.getRecipeItem()); + //P.p.debugLog("Cauldron add: t2 " + ((t2 - t1) / 1000) + " t3: " + ((t3 - t2) / 1000) + " t4: " + ((t4 - t3) / 1000) + " t5: " + ((t5 - t4) / 1000) + "µs"); return event.willTakeItem(); } else { return false; @@ -127,7 +127,7 @@ public class BCauldron { BlockData data = block.getBlockData(); Levelled cauldron = ((Levelled) data); if (cauldron.getLevel() <= 0) { - bcauldrons.remove(this); + bcauldrons.remove(block); return false; } cauldron.setLevel(cauldron.getLevel() - 1); @@ -137,7 +137,7 @@ public class BCauldron { block.setBlockData(data); if (cauldron.getLevel() <= 0) { - bcauldrons.remove(this); + bcauldrons.remove(block); } else { changed = true; } @@ -147,14 +147,14 @@ public class BCauldron { if (data > 3) { data = 3; } else if (data <= 0) { - bcauldrons.remove(this); + bcauldrons.remove(block); return false; } data -= 1; LegacyUtil.setData(block, data); if (data == 0) { - bcauldrons.remove(this); + bcauldrons.remove(block); } else { changed = true; } @@ -303,11 +303,7 @@ public class BCauldron { // reset to normal cauldron public static boolean remove(Block block) { if (LegacyUtil.getFillLevel(block) != EMPTY) { - BCauldron bcauldron = get(block); - if (bcauldron != null) { - bcauldrons.remove(bcauldron); - return true; - } + return bcauldrons.remove(block) != null; } return false; } @@ -315,11 +311,7 @@ public class BCauldron { // unloads cauldrons that are in a unloading world // as they were written to file just before, this is safe to do public static void onUnload(String name) { - for (BCauldron bcauldron : bcauldrons) { - if (bcauldron.block.getWorld().getName().equals(name)) { - bcauldrons.remove(bcauldron); - } - } + bcauldrons.keySet().removeIf(block -> block.getWorld().getName().equals(name)); } public static void save(ConfigurationSection config, ConfigurationSection oldData) { @@ -327,7 +319,7 @@ public class BCauldron { if (!bcauldrons.isEmpty()) { int id = 0; - for (BCauldron cauldron : bcauldrons) { + for (BCauldron cauldron : bcauldrons.values()) { String worldName = cauldron.block.getWorld().getName(); String prefix; diff --git a/src/com/dre/brewery/BIngredients.java b/src/com/dre/brewery/BIngredients.java index e301a52..721cb37 100644 --- a/src/com/dre/brewery/BIngredients.java +++ b/src/com/dre/brewery/BIngredients.java @@ -8,7 +8,7 @@ import com.dre.brewery.recipe.BRecipe; import com.dre.brewery.recipe.Ingredient; import com.dre.brewery.recipe.ItemLoader; import com.dre.brewery.recipe.RecipeItem; -import com.dre.brewery.utility.PotionColor; +import com.dre.brewery.recipe.PotionColor; import org.bukkit.Material; import org.bukkit.configuration.ConfigurationSection; import org.bukkit.inventory.ItemStack; @@ -22,6 +22,9 @@ import java.io.IOException; import java.util.ArrayList; import java.util.List; +/** + * Represents ingredients in Cauldron, Brew + */ public class BIngredients { private static int lastId = 0; // Legacy @@ -29,14 +32,17 @@ public class BIngredients { private List ingredients = new ArrayList<>(); private int cookedTime; - // Represents ingredients in Cauldron, Brew - // Init a new BIngredients + /** + * Init a new BIngredients + */ public BIngredients() { //this.id = lastId; //lastId++; } - // Load from File + /** + * Load from File + */ public BIngredients(List ingredients, int cookedTime) { this.ingredients = ingredients; this.cookedTime = cookedTime; @@ -44,7 +50,9 @@ public class BIngredients { //lastId++; } - // Load from legacy Brew section + /** + * Load from legacy Brew section + */ public BIngredients(List ingredients, int cookedTime, boolean legacy) { this(ingredients, cookedTime); if (legacy) { @@ -53,8 +61,12 @@ public class BIngredients { } } - // Force add an ingredient to this - // Will not check if item is acceptable + /** + * Force add an ingredient to this + * Will not check if item is acceptable + * + * @param ingredient the item to add + */ public void add(ItemStack ingredient) { for (Ingredient existing : ingredients) { if (existing.matches(ingredient)) { @@ -68,7 +80,12 @@ public class BIngredients { ingredients.add(ing); } - // Add an ingredient to this with corresponding RecipeItem + /** + * Add an ingredient to this with corresponding RecipeItem + * + * @param ingredient the item to add + * @param rItem the RecipeItem that matches the ingredient + */ public void add(ItemStack ingredient, RecipeItem rItem) { Ingredient ingredientItem = rItem.toIngredient(ingredient); for (Ingredient existing : ingredients) { diff --git a/src/com/dre/brewery/BPlayer.java b/src/com/dre/brewery/BPlayer.java index cecfcc5..0e8a338 100644 --- a/src/com/dre/brewery/BPlayer.java +++ b/src/com/dre/brewery/BPlayer.java @@ -35,7 +35,7 @@ public class BPlayer { private static int taskId; private static boolean modAge = true; private static Random pukeRand; - private static Method gh; + private static Method itemHandle; private static Field age; private int quality = 0;// = quality of drunkeness * drunkeness @@ -326,11 +326,7 @@ public class BPlayer { return; } // delayed login event as the player is not fully accessible pre login - P.p.getServer().getScheduler().runTaskLater(P.p, new Runnable() { - public void run() { - login(player); - } - }, 1L); + P.p.getServer().getScheduler().runTaskLater(P.p, () -> login(player), 1L); } // he may be having a hangover @@ -390,11 +386,11 @@ public class BPlayer { public void drunkPuke(Player player) { if (drunkeness >= 80) { if (drunkeness >= 90) { - if (Math.random() < 0.15 - (getQuality() / 100)) { + if (Math.random() < 0.15f - (getQuality() / 100f)) { addPuke(player, 20 + (int) (Math.random() * 40)); } } else { - if (Math.random() < 0.08 - (getQuality() / 100)) { + if (Math.random() < 0.08f - (getQuality() / 100f)) { addPuke(player, 10 + (int) (Math.random() * 30)); } } @@ -414,11 +410,7 @@ public class BPlayer { } if (pTasks.isEmpty()) { - taskId = P.p.getServer().getScheduler().scheduleSyncRepeatingTask(P.p, new Runnable() { - public void run() { - pukeTask(); - } - }, 1L, 1L); + taskId = P.p.getServer().getScheduler().scheduleSyncRepeatingTask(P.p, BPlayer::pukeTask, 1L, 1L); } pTasks.put(player, new MutableInt(event.getCount())); } @@ -466,10 +458,10 @@ public class BPlayer { return; } try { - if (gh == null) { - gh = Class.forName(P.p.getServer().getClass().getPackage().getName() + ".entity.CraftItem").getMethod("getHandle", (Class[]) null); + if (itemHandle == null) { + itemHandle = Class.forName(P.p.getServer().getClass().getPackage().getName() + ".entity.CraftItem").getMethod("getHandle", (Class[]) null); } - Object entityItem = gh.invoke(item, (Object[]) null); + Object entityItem = itemHandle.invoke(item, (Object[]) null); if (age == null) { age = entityItem.getClass().getDeclaredField("age"); age.setAccessible(true); @@ -592,7 +584,7 @@ public class BPlayer { } public static void addBrewEffects(Brew brew, Player player) { - ArrayList effects = brew.getEffects(); + List effects = brew.getEffects(); if (effects != null) { for (BEffect effect : effects) { effect.apply(brew.getQuality(), player); diff --git a/src/com/dre/brewery/Barrel.java b/src/com/dre/brewery/Barrel.java index 7f06861..3178f3d 100644 --- a/src/com/dre/brewery/Barrel.java +++ b/src/com/dre/brewery/Barrel.java @@ -30,11 +30,10 @@ import org.jetbrains.annotations.Nullable; import java.util.ArrayList; import java.util.List; import java.util.Map; -import java.util.concurrent.CopyOnWriteArrayList; public class Barrel implements InventoryHolder { - public static CopyOnWriteArrayList barrels = new CopyOnWriteArrayList<>(); // TODO find best collection + public static List barrels = new ArrayList<>(); private static int check = 0; private final Block spigot; @@ -407,11 +406,7 @@ public class Barrel implements InventoryHolder { //unloads barrels that are in a unloading world public static void onUnload(String name) { - for (Barrel barrel : barrels) { - if (barrel.spigot.getWorld().getName().equals(name)) { - barrels.remove(barrel); - } - } + barrels.removeIf(barrel -> barrel.spigot.getWorld().getName().equals(name)); } // Saves all data diff --git a/src/com/dre/brewery/Brew.java b/src/com/dre/brewery/Brew.java index b882c63..45c383a 100644 --- a/src/com/dre/brewery/Brew.java +++ b/src/com/dre/brewery/Brew.java @@ -6,7 +6,7 @@ import com.dre.brewery.filedata.ConfigUpdater; import com.dre.brewery.lore.*; import com.dre.brewery.recipe.BEffect; import com.dre.brewery.recipe.BRecipe; -import com.dre.brewery.utility.PotionColor; +import com.dre.brewery.recipe.PotionColor; import org.bukkit.Material; import org.bukkit.configuration.ConfigurationSection; import org.bukkit.inventory.BrewerInventory; @@ -360,7 +360,7 @@ public class Brew { } // return special effect - public ArrayList getEffects() { + public List getEffects() { if (currentRecipe != null && quality > 0) { return currentRecipe.getEffects(); } diff --git a/src/com/dre/brewery/DistortChat.java b/src/com/dre/brewery/DistortChat.java index eb0f2c9..9fb091e 100644 --- a/src/com/dre/brewery/DistortChat.java +++ b/src/com/dre/brewery/DistortChat.java @@ -13,7 +13,7 @@ public class DistortChat { // represends Words and letters, that are replaced in drunk players messages - public static ArrayList words = new ArrayList<>(); + public static List words = new ArrayList<>(); public static List commands; public static List ignoreText = new ArrayList<>(); public static Boolean doSigns; @@ -164,6 +164,8 @@ public class DistortChat { // distorts a message without checking ignoreText letters private static String distortString(String message, int drunkeness) { if (message.length() > 1) { + // Create our own reference to the words list, in case of config reload + List words = DistortChat.words; for (DistortChat word : words) { if (word.alcohol <= drunkeness) { message = word.distort(message); diff --git a/src/com/dre/brewery/P.java b/src/com/dre/brewery/P.java index ca744a9..f7715b8 100644 --- a/src/com/dre/brewery/P.java +++ b/src/com/dre/brewery/P.java @@ -436,9 +436,6 @@ public class P extends JavaPlugin { // save Data to Disk DataSave.save(true); - // save LanguageReader - languageReader.save(); - // delete Data from Ram Barrel.barrels.clear(); BCauldron.bcauldrons.clear(); @@ -473,8 +470,6 @@ public class P extends JavaPlugin { BConfig.customItems.clear(); BConfig.hasSlimefun = null; BConfig.hasMMOItems = null; - DistortChat.words.clear(); - DistortChat.ignoreText.clear(); DistortChat.commands = null; BConfig.drainItems.clear(); if (BConfig.useLB) { @@ -499,8 +494,7 @@ public class P extends JavaPlugin { return; } - // save and load LanguageReader - languageReader.save(); + // load LanguageReader languageReader = new LanguageReader(new File(p.getDataFolder(), "languages/" + language + ".yml")); // Reload Recipes @@ -563,7 +557,7 @@ public class P extends JavaPlugin { @Override public void run() { BConfig.reloader = null; - for (BCauldron cauldron : BCauldron.bcauldrons) { + for (BCauldron cauldron : BCauldron.bcauldrons.values()) { cauldron.onUpdate();// runs every min to update cooking time } Barrel.onUpdate();// runs every min to check and update ageing time diff --git a/src/com/dre/brewery/Wakeup.java b/src/com/dre/brewery/Wakeup.java index 371d169..46e2906 100644 --- a/src/com/dre/brewery/Wakeup.java +++ b/src/com/dre/brewery/Wakeup.java @@ -8,10 +8,11 @@ import org.bukkit.entity.Player; import java.util.ArrayList; import java.util.Iterator; +import java.util.List; public class Wakeup { - public static ArrayList wakeups = new ArrayList<>(); + public static List wakeups = new ArrayList<>(); public static P p = P.p; public static int checkId = -1; public static Player checkPlayer = null; diff --git a/src/com/dre/brewery/filedata/BConfig.java b/src/com/dre/brewery/filedata/BConfig.java index 8d6e60a..c38349e 100644 --- a/src/com/dre/brewery/filedata/BConfig.java +++ b/src/com/dre/brewery/filedata/BConfig.java @@ -22,8 +22,6 @@ import org.bukkit.command.CommandSender; import org.bukkit.configuration.ConfigurationSection; import org.bukkit.configuration.file.FileConfiguration; import org.bukkit.configuration.file.YamlConfiguration; -import org.bukkit.inventory.ItemStack; -import org.bukkit.inventory.meta.ItemMeta; import org.bukkit.plugin.Plugin; import org.bukkit.plugin.PluginManager; @@ -274,6 +272,8 @@ public class BConfig { } // Loading Words + DistortChat.words = new ArrayList<>(); + DistortChat.ignoreText = new ArrayList<>(); if (config.getBoolean("enableChatDistortion", false)) { for (Map map : config.getMapList("words")) { new DistortChat(map); diff --git a/src/com/dre/brewery/filedata/LanguageReader.java b/src/com/dre/brewery/filedata/LanguageReader.java index b523be9..bd44779 100644 --- a/src/com/dre/brewery/filedata/LanguageReader.java +++ b/src/com/dre/brewery/filedata/LanguageReader.java @@ -2,22 +2,24 @@ package com.dre.brewery.filedata; import java.io.File; import java.io.IOException; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; import java.util.Map; import java.util.Set; -import java.util.TreeMap; +import com.dre.brewery.utility.Tuple; import org.bukkit.configuration.file.FileConfiguration; import org.bukkit.configuration.file.YamlConfiguration; public class LanguageReader { - private Map entries = new TreeMap<>(); - private Map defaults = new TreeMap<>(); + private Map entries = new HashMap<>(128); private File file; private boolean changed; public LanguageReader(File file) { - this.setDefaults(); + List> defaults = getDefaults(); /* Load */ this.file = file; @@ -30,126 +32,132 @@ public class LanguageReader { } /* Check */ - this.check(); + check(defaults); + if (changed) { + save(); + } } - private void setDefaults() { + private List> getDefaults() { + List> defaults = new ArrayList<>(128); /* Player */ - defaults.put("Player_BarrelCreated", "Barrel created"); - defaults.put("Player_BarrelFull", "&cThis barrel can''t hold any more drinks"); - defaults.put("Player_CauldronInfo1", "This cauldron has been boiling for &v1 minutes."); - defaults.put("Player_CauldronInfo2", "This cauldron has just started boiling."); - defaults.put("Player_CantDrink", "You can't drink any more."); - defaults.put("Player_DrunkPassOut", "You drank too much and passed out."); - defaults.put("Player_LoginDeny", "Your character tries to log in, but is too drunk to find the server. Try again!"); - defaults.put("Player_LoginDenyLong", "Your character is really drunk and has passed out. Try again in 10 minutes!"); - defaults.put("Player_Wake", "Ohh no! I cannot remember how I got here..."); - defaults.put("Player_WakeCreated", "&aWakeup Point with id: &6&v1 &awas created successfully!"); - defaults.put("Player_WakeNotExist", "&cThe Wakeup Point with the id: &6&v1 &cdoesn't exist!"); - defaults.put("Player_WakeDeleted", "&aThe Wakeup Point with the id: &6&v1 &awas successfully deleted!"); - defaults.put("Player_WakeAlreadyDeleted", "&cThe Wakeup Point with the id: &6&v1 &chas already been deleted!"); - defaults.put("Player_WakeFilled", "&cThe Wakeup Point with the id: &6&v1&c at position &6&v2 &v3, &v4, &v5&c is filled with Blocks!"); - defaults.put("Player_WakeNoPoints", "&cThere are no Wakeup Points!"); - defaults.put("Player_WakeLast", "&aThis was the last Wakeup Point"); - defaults.put("Player_WakeTeleport", "Teleport to Wakeup Point with the id: &6&v1&f At position: &6&v2 &v3, &v4, &v5"); - defaults.put("Player_WakeHint1", "To Next Wakeup Point: Punch your fist in the air"); - defaults.put("Player_WakeHint2", "To Cancel: &9/br wakeup cancel"); - defaults.put("Player_WakeCancel", "&6Wakeup Point Check was cancelled"); - defaults.put("Player_WakeNoCheck", "&cNo Wakeup Point Check is currently active"); - defaults.put("Player_TriedToSay", "&v1 tried to say: &0&v2"); + defaults.add(new Tuple<>("Player_BarrelCreated", "Barrel created")); + defaults.add(new Tuple<>("Player_BarrelFull", "&cThis barrel can''t hold any more drinks")); + defaults.add(new Tuple<>("Player_CauldronInfo1", "This cauldron has been boiling for &v1 minutes.")); + defaults.add(new Tuple<>("Player_CauldronInfo2", "This cauldron has just started boiling.")); + defaults.add(new Tuple<>("Player_CantDrink", "You can't drink any more.")); + defaults.add(new Tuple<>("Player_DrunkPassOut", "You drank too much and passed out.")); + defaults.add(new Tuple<>("Player_LoginDeny", "Your character tries to log in, but is too drunk to find the server. Try again!")); + defaults.add(new Tuple<>("Player_LoginDenyLong", "Your character is really drunk and has passed out. Try again in 10 minutes!")); + defaults.add(new Tuple<>("Player_Wake", "Ohh no! I cannot remember how I got here...")); + defaults.add(new Tuple<>("Player_WakeCreated", "&aWakeup Point with id: &6&v1 &awas created successfully!")); + defaults.add(new Tuple<>("Player_WakeNotExist", "&cThe Wakeup Point with the id: &6&v1 &cdoesn't exist!")); + defaults.add(new Tuple<>("Player_WakeDeleted", "&aThe Wakeup Point with the id: &6&v1 &awas successfully deleted!")); + defaults.add(new Tuple<>("Player_WakeAlreadyDeleted", "&cThe Wakeup Point with the id: &6&v1 &chas already been deleted!")); + defaults.add(new Tuple<>("Player_WakeFilled", "&cThe Wakeup Point with the id: &6&v1&c at position &6&v2 &v3, &v4, &v5&c is filled with Blocks!")); + defaults.add(new Tuple<>("Player_WakeNoPoints", "&cThere are no Wakeup Points!")); + defaults.add(new Tuple<>("Player_WakeLast", "&aThis was the last Wakeup Point")); + defaults.add(new Tuple<>("Player_WakeTeleport", "Teleport to Wakeup Point with the id: &6&v1&f At position: &6&v2 &v3, &v4, &v5")); + defaults.add(new Tuple<>("Player_WakeHint1", "To Next Wakeup Point: Punch your fist in the air")); + defaults.add(new Tuple<>("Player_WakeHint2", "To Cancel: &9/br wakeup cancel")); + defaults.add(new Tuple<>("Player_WakeCancel", "&6Wakeup Point Check was cancelled")); + defaults.add(new Tuple<>("Player_WakeNoCheck", "&cNo Wakeup Point Check is currently active")); + defaults.add(new Tuple<>("Player_TriedToSay", "&v1 tried to say: &0&v2")); /* Brew */ - defaults.put("Brew_Distilled", "Distilled"); - defaults.put("Brew_BarrelRiped", "Barrel aged"); - defaults.put("Brew_Undefined", "Indefinable Brew"); - defaults.put("Brew_DistillUndefined", "Indefinable Distillate"); - defaults.put("Brew_BadPotion", "Ruined Potion"); - defaults.put("Brew_Ingredients", "Ingredients"); - defaults.put("Brew_minute", "minute"); - defaults.put("Brew_MinutePluralPostfix", "s"); - defaults.put("Brew_fermented", "fermented"); - defaults.put("Brew_-times", "-times"); - defaults.put("Brew_OneYear", "One Year"); - defaults.put("Brew_Years", "Years"); - defaults.put("Brew_HundredsOfYears", "Hundreds of Years"); - defaults.put("Brew_Woodtype", "Woodtype"); - defaults.put("Brew_ThickBrew", "Muddy Brew"); - defaults.put("Brew_Alc", "Alc &v1ml"); + defaults.add(new Tuple<>("Brew_Distilled", "Distilled")); + defaults.add(new Tuple<>("Brew_BarrelRiped", "Barrel aged")); + defaults.add(new Tuple<>("Brew_Undefined", "Indefinable Brew")); + defaults.add(new Tuple<>("Brew_DistillUndefined", "Indefinable Distillate")); + defaults.add(new Tuple<>("Brew_BadPotion", "Ruined Potion")); + defaults.add(new Tuple<>("Brew_Ingredients", "Ingredients")); + defaults.add(new Tuple<>("Brew_minute", "minute")); + defaults.add(new Tuple<>("Brew_MinutePluralPostfix", "s")); + defaults.add(new Tuple<>("Brew_fermented", "fermented")); + defaults.add(new Tuple<>("Brew_-times", "-times")); + defaults.add(new Tuple<>("Brew_OneYear", "One Year")); + defaults.add(new Tuple<>("Brew_Years", "Years")); + defaults.add(new Tuple<>("Brew_HundredsOfYears", "Hundreds of Years")); + defaults.add(new Tuple<>("Brew_Woodtype", "Woodtype")); + defaults.add(new Tuple<>("Brew_ThickBrew", "Muddy Brew")); + defaults.add(new Tuple<>("Brew_Alc", "Alc &v1ml")); /* Commands */ - defaults.put("CMD_Reload", "&aConfig was successfully reloaded"); - defaults.put("CMD_Configname", "&aName for the Config is: &f&v1"); - defaults.put("CMD_Configname_Error", "&cCould not find item in your hand"); - defaults.put("CMD_Player", "&a&v1 is now &6&v2% &adrunk, with a quality of &6&v3"); - defaults.put("CMD_Player_Error", "&cThe quality has to be between 1 and 10!"); - defaults.put("CMD_Info_NotDrunk", "&v1 is not drunk"); - defaults.put("CMD_Info_Drunk", "&v1 is &6&v2% &fdrunk, with a quality of &6&v3"); - defaults.put("CMD_UnLabel", "&aLabel removed!"); - defaults.put("CMD_Persistent", "&aPotion is now Persistent and Static and may now be copied like any other item. You can remove the persistence with the same command."); - defaults.put("CMD_PersistRemove", "&cPersistent Brews cannot be removed from the Database. It would render any copies of them useless!"); - defaults.put("CMD_UnPersist", "&aPersistence and static Removed. &eEvery Potential copy NOT made with '/brew copy' could become useless now!"); - defaults.put("CMD_Copy_Error", "&6&v1 &cPotions did not fit into your inventory"); - defaults.put("CMD_CopyNotPersistent", "&eThese copies of this Brew will not be persistent or static!"); - defaults.put("CMD_Static", "&aPotion is now static and will not change in barrels or brewing stands."); - defaults.put("CMD_NonStatic", "&ePotion is not static anymore and will normally age in barrels."); + defaults.add(new Tuple<>("CMD_Reload", "&aConfig was successfully reloaded")); + defaults.add(new Tuple<>("CMD_Configname", "&aName for the Config is: &f&v1")); + defaults.add(new Tuple<>("CMD_Configname_Error", "&cCould not find item in your hand")); + defaults.add(new Tuple<>("CMD_Player", "&a&v1 is now &6&v2% &adrunk, with a quality of &6&v3")); + defaults.add(new Tuple<>("CMD_Player_Error", "&cThe quality has to be between 1 and 10!")); + defaults.add(new Tuple<>("CMD_Info_NotDrunk", "&v1 is not drunk")); + defaults.add(new Tuple<>("CMD_Info_Drunk", "&v1 is &6&v2% &fdrunk, with a quality of &6&v3")); + defaults.add(new Tuple<>("CMD_UnLabel", "&aLabel removed!")); + defaults.add(new Tuple<>("CMD_Persistent", "&aPotion is now Persistent and Static and may now be copied like any other item. You can remove the persistence with the same command.")); + defaults.add(new Tuple<>("CMD_PersistRemove", "&cPersistent Brews cannot be removed from the Database. It would render any copies of them useless!")); + defaults.add(new Tuple<>("CMD_UnPersist", "&aPersistence and static Removed. &eEvery Potential copy NOT made with '/brew copy' could become useless now!")); + defaults.add(new Tuple<>("CMD_Copy_Error", "&6&v1 &cPotions did not fit into your inventory")); + defaults.add(new Tuple<>("CMD_CopyNotPersistent", "&eThese copies of this Brew will not be persistent or static!")); + defaults.add(new Tuple<>("CMD_Static", "&aPotion is now static and will not change in barrels or brewing stands.")); + defaults.add(new Tuple<>("CMD_NonStatic", "&ePotion is not static anymore and will normally age in barrels.")); /* Error */ - defaults.put("Error_UnknownCommand", "Unknown Command"); - defaults.put("Error_ShowHelp", "Use &6/brew help &fto display the help"); - defaults.put("Error_PlayerCommand", "&cThis command can only be executed as a player!"); - defaults.put("Error_ItemNotPotion", "&cThe item in your hand could not be identified as a potion!"); - defaults.put("Error_NoBrewName", "&cNo Recipe with Name: '&v1&c' found!"); - defaults.put("Error_Recipeload", "&cNot all recipes could be restored: More information in the server log!"); - defaults.put("Error_ConfigUpdate", "Unknown Brewery config version: v&v1, config was not updated!"); - defaults.put("Error_PersistStatic", "&cPersistent potions are always static!"); + defaults.add(new Tuple<>("Error_UnknownCommand", "Unknown Command")); + defaults.add(new Tuple<>("Error_ShowHelp", "Use &6/brew help &fto display the help")); + defaults.add(new Tuple<>("Error_PlayerCommand", "&cThis command can only be executed as a player!")); + defaults.add(new Tuple<>("Error_ItemNotPotion", "&cThe item in your hand could not be identified as a potion!")); + defaults.add(new Tuple<>("Error_NoBrewName", "&cNo Recipe with Name: '&v1&c' found!")); + defaults.add(new Tuple<>("Error_Recipeload", "&cNot all recipes could be restored: More information in the server log!")); + defaults.add(new Tuple<>("Error_ConfigUpdate", "Unknown Brewery config version: v&v1, config was not updated!")); + defaults.add(new Tuple<>("Error_PersistStatic", "&cPersistent potions are always static!")); /* Permissions */ - defaults.put("Error_NoPermissions", "&cYou don't have permissions to do this!"); - defaults.put("Error_NoBarrelAccess", "&cYou don't have permissions to access this barrel!"); - defaults.put("Perms_NoBarrelCreate", "&cYou don't have permissions to create barrels!"); - defaults.put("Perms_NoSmallBarrelCreate", "&cYou don't have permissions to create small barrels!"); - defaults.put("Perms_NoBigBarrelCreate", "&cYou don't have permissions to create big barrels!"); - defaults.put("Perms_NoCauldronInsert", "&cYou don't have permissions to put ingredients into cauldrons!"); - defaults.put("Perms_NoCauldronFill", "&cYou don't have permissions to fill bottles from this cauldron!"); + defaults.add(new Tuple<>("Error_NoPermissions", "&cYou don't have permissions to do this!")); + defaults.add(new Tuple<>("Error_NoBarrelAccess", "&cYou don't have permissions to access this barrel!")); + defaults.add(new Tuple<>("Perms_NoBarrelCreate", "&cYou don't have permissions to create barrels!")); + defaults.add(new Tuple<>("Perms_NoSmallBarrelCreate", "&cYou don't have permissions to create small barrels!")); + defaults.add(new Tuple<>("Perms_NoBigBarrelCreate", "&cYou don't have permissions to create big barrels!")); + defaults.add(new Tuple<>("Perms_NoCauldronInsert", "&cYou don't have permissions to put ingredients into cauldrons!")); + defaults.add(new Tuple<>("Perms_NoCauldronFill", "&cYou don't have permissions to fill bottles from this cauldron!")); /* Help */ - defaults.put("Help_Help", "&6/brew help [Page] &9Shows a specific help-page"); - defaults.put("Help_Player", "&6/brew <%Drunkeness> [Quality]&9 Sets Drunkeness (and Quality) of a Player"); - defaults.put("Help_Info", "&6/brew info&9 Displays your current Drunkeness and Quality"); - defaults.put("Help_UnLabel", "&6/brew unlabel &9Removes the detailled label of a potion"); - defaults.put("Help_Copy", "&6/brew copy [Quantity]>&9 Copies the potion in your hand"); - defaults.put("Help_Delete", "&6/brew delete &9Deletes the potion in your hand"); - defaults.put("Help_InfoOther", "&6/brew info [Player]&9 Displays the current Drunkeness and Quality of [Player]"); - defaults.put("Help_Wakeup", "&6/brew wakeup list &9 Lists all wakeup points"); - defaults.put("Help_WakeupList", "&6/brew wakeup list [World]&9 Lists all wakeup points of [world]"); - defaults.put("Help_WakeupCheck", "&6/brew wakeup check &9Teleports to all wakeup points"); - defaults.put("Help_WakeupCheckSpecific", "&6/brew wakeup check &9Teleports to the wakeup point with "); - defaults.put("Help_WakeupAdd", "&6/brew wakeup add &9Adds a wakeup point at your current position"); - defaults.put("Help_WakeupRemove", "&6/brew wakeup remove &9Removes the wakeup point with "); - defaults.put("Help_Reload", "&6/brew reload &9Reload config"); - defaults.put("Help_Configname", "&6/brew ItemName &9Display name of item in hand for the config"); - defaults.put("Help_Persist", "&6/brew persist &9Make Brew persistent -> copyable by any plugin and technique"); - defaults.put("Help_Static", "&6/brew static &9Make Brew static -> No further ageing or distilling"); - defaults.put("Help_Create", "&6/brew create [Quality] [Player] &9Create a Brew with optional quality (1-10)"); + defaults.add(new Tuple<>("Help_Help", "&6/brew help [Page] &9Shows a specific help-page")); + defaults.add(new Tuple<>("Help_Player", "&6/brew <%Drunkeness> [Quality]&9 Sets Drunkeness (and Quality) of a Player")); + defaults.add(new Tuple<>("Help_Info", "&6/brew info&9 Displays your current Drunkeness and Quality")); + defaults.add(new Tuple<>("Help_UnLabel", "&6/brew unlabel &9Removes the detailled label of a potion")); + defaults.add(new Tuple<>("Help_Copy", "&6/brew copy [Quantity]>&9 Copies the potion in your hand")); + defaults.add(new Tuple<>("Help_Delete", "&6/brew delete &9Deletes the potion in your hand")); + defaults.add(new Tuple<>("Help_InfoOther", "&6/brew info [Player]&9 Displays the current Drunkeness and Quality of [Player]")); + defaults.add(new Tuple<>("Help_Wakeup", "&6/brew wakeup list &9 Lists all wakeup points")); + defaults.add(new Tuple<>("Help_WakeupList", "&6/brew wakeup list [World]&9 Lists all wakeup points of [world]")); + defaults.add(new Tuple<>("Help_WakeupCheck", "&6/brew wakeup check &9Teleports to all wakeup points")); + defaults.add(new Tuple<>("Help_WakeupCheckSpecific", "&6/brew wakeup check &9Teleports to the wakeup point with ")); + defaults.add(new Tuple<>("Help_WakeupAdd", "&6/brew wakeup add &9Adds a wakeup point at your current position")); + defaults.add(new Tuple<>("Help_WakeupRemove", "&6/brew wakeup remove &9Removes the wakeup point with ")); + defaults.add(new Tuple<>("Help_Reload", "&6/brew reload &9Reload config")); + defaults.add(new Tuple<>("Help_Configname", "&6/brew ItemName &9Display name of item in hand for the config")); + defaults.add(new Tuple<>("Help_Persist", "&6/brew persist &9Make Brew persistent -> copyable by any plugin and technique")); + defaults.add(new Tuple<>("Help_Static", "&6/brew static &9Make Brew static -> No further ageing or distilling")); + defaults.add(new Tuple<>("Help_Create", "&6/brew create [Quality] [Player] &9Create a Brew with optional quality (1-10)")); /* Etc. */ - defaults.put("Etc_Usage", "Usage:"); - defaults.put("Etc_Page", "Page"); - defaults.put("Etc_Barrel", "Barrel"); + defaults.add(new Tuple<>("Etc_Usage", "Usage:")); + defaults.add(new Tuple<>("Etc_Page", "Page")); + defaults.add(new Tuple<>("Etc_Barrel", "Barrel")); + + return defaults; } - private void check() { - for (String defaultEntry : defaults.keySet()) { - if (!entries.containsKey(defaultEntry)) { - entries.put(defaultEntry, defaults.get(defaultEntry)); + private void check(List> defaults) { + for (Tuple def : defaults) { + if (!entries.containsKey(def.a())) { + entries.put(def.a(), def.b()); changed = true; } } } @SuppressWarnings("ResultOfMethodCallIgnored") - public void save() { + private void save() { if (changed) { /* Copy old File */ File source = new File(file.getPath()); diff --git a/src/com/dre/brewery/listeners/EntityListener.java b/src/com/dre/brewery/listeners/EntityListener.java index 43fde74..ff1c3cb 100644 --- a/src/com/dre/brewery/listeners/EntityListener.java +++ b/src/com/dre/brewery/listeners/EntityListener.java @@ -18,9 +18,9 @@ import org.bukkit.event.entity.EntityExplodeEvent; import org.bukkit.event.entity.ItemDespawnEvent; import org.bukkit.inventory.ItemStack; -import java.util.HashSet; +import java.util.ArrayList; +import java.util.List; import java.util.ListIterator; -import java.util.Set; public class EntityListener implements Listener { @@ -54,7 +54,7 @@ public class EntityListener implements Listener { public void onExplode(EntityExplodeEvent event) { ListIterator iter = event.blockList().listIterator(); if (!iter.hasNext()) return; - Set breakEvents = new HashSet<>(6); + List breakEvents = new ArrayList<>(6); Block block; blocks: while (iter.hasNext()) { block = iter.next(); diff --git a/src/com/dre/brewery/lore/BrewLore.java b/src/com/dre/brewery/lore/BrewLore.java index a7bf2eb..91d76b5 100644 --- a/src/com/dre/brewery/lore/BrewLore.java +++ b/src/com/dre/brewery/lore/BrewLore.java @@ -375,7 +375,7 @@ public class BrewLore { /** * Adds the Effect names to the Items description */ - public void addOrReplaceEffects(ArrayList effects, int quality) { + public void addOrReplaceEffects(List effects, int quality) { if (!P.use1_9 && effects != null) { for (BEffect effect : effects) { if (!effect.isHidden()) { diff --git a/src/com/dre/brewery/recipe/BCauldronRecipe.java b/src/com/dre/brewery/recipe/BCauldronRecipe.java index de8cc6b..534b6e5 100644 --- a/src/com/dre/brewery/recipe/BCauldronRecipe.java +++ b/src/com/dre/brewery/recipe/BCauldronRecipe.java @@ -1,7 +1,6 @@ package com.dre.brewery.recipe; import com.dre.brewery.P; -import com.dre.brewery.utility.PotionColor; import com.dre.brewery.utility.Tuple; import org.bukkit.Material; import org.bukkit.configuration.ConfigurationSection; diff --git a/src/com/dre/brewery/recipe/BRecipe.java b/src/com/dre/brewery/recipe/BRecipe.java index 8d99f42..e35d87d 100644 --- a/src/com/dre/brewery/recipe/BRecipe.java +++ b/src/com/dre/brewery/recipe/BRecipe.java @@ -4,7 +4,6 @@ import com.dre.brewery.BIngredients; import com.dre.brewery.Brew; import com.dre.brewery.P; import com.dre.brewery.filedata.BConfig; -import com.dre.brewery.utility.PotionColor; import com.dre.brewery.utility.Tuple; import org.bukkit.Material; import org.bukkit.configuration.ConfigurationSection; @@ -30,7 +29,7 @@ public class BRecipe { private int difficulty; // difficulty to brew the potion, how exact the instruction has to be followed private int alcohol; // Alcohol in perfect potion private List> lore; // Custom Lore on the Potion. The int is for Quality Lore, 0 = any, 1,2,3 = Bad,Middle,Good - private ArrayList effects = new ArrayList<>(); // Special Effects when drinking + private List effects = new ArrayList<>(); // Special Effects when drinking public BRecipe() { } @@ -497,7 +496,7 @@ public class BRecipe { return list; } - public ArrayList getEffects() { + public List getEffects() { return effects; } diff --git a/src/com/dre/brewery/utility/PotionColor.java b/src/com/dre/brewery/recipe/PotionColor.java similarity index 99% rename from src/com/dre/brewery/utility/PotionColor.java rename to src/com/dre/brewery/recipe/PotionColor.java index 2218061..8561ea4 100644 --- a/src/com/dre/brewery/utility/PotionColor.java +++ b/src/com/dre/brewery/recipe/PotionColor.java @@ -1,4 +1,4 @@ -package com.dre.brewery.utility; +package com.dre.brewery.recipe; import com.dre.brewery.P; import org.bukkit.Color; diff --git a/src/com/dre/brewery/utility/BoundingBox.java b/src/com/dre/brewery/utility/BoundingBox.java index e5fe831..a9160b7 100644 --- a/src/com/dre/brewery/utility/BoundingBox.java +++ b/src/com/dre/brewery/utility/BoundingBox.java @@ -5,12 +5,7 @@ import org.bukkit.block.Block; public class BoundingBox { - private final int x1; - private final int y1; - private final int z1; - private final int x2; - private final int y2; - private final int z2; + private final int x1, y1, z1, x2, y2, z2; public BoundingBox(int x1, int y1, int z1, int x2, int y2, int z2) { this.x1 = Math.min(x1, x2); diff --git a/src/com/dre/brewery/utility/LegacyUtil.java b/src/com/dre/brewery/utility/LegacyUtil.java index d981883..8e3c862 100644 --- a/src/com/dre/brewery/utility/LegacyUtil.java +++ b/src/com/dre/brewery/utility/LegacyUtil.java @@ -13,12 +13,12 @@ import org.bukkit.material.Wood; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; -import java.util.ArrayList; -import java.util.List; +import java.util.EnumSet; +import java.util.Set; import static com.dre.brewery.BCauldron.EMPTY; -import static com.dre.brewery.BCauldron.SOME; import static com.dre.brewery.BCauldron.FULL; +import static com.dre.brewery.BCauldron.SOME; @SuppressWarnings("JavaReflectionMemberAccess") public class LegacyUtil { @@ -42,7 +42,7 @@ public class LegacyUtil { } catch (ClassNotFoundException | NoSuchMethodException | SecurityException ignored) { } - List planks = new ArrayList<>(6); + Set planks = EnumSet.noneOf(Material.class); for (Material m : Material.values()) { if (m.name().endsWith("PLANKS")) { planks.add(m); @@ -50,7 +50,7 @@ public class LegacyUtil { } PLANKS = planks; - List fences = new ArrayList<>(7); + Set fences = EnumSet.noneOf(Material.class); for (Material m : Material.values()) { if (m.name().endsWith("FENCE")) { fences.add(m); @@ -68,8 +68,8 @@ public class LegacyUtil { public static final Material JUNGLE_STAIRS = get("JUNGLE_STAIRS", "JUNGLE_WOOD_STAIRS"); public static final Material ACACIA_STAIRS = get("ACACIA_STAIRS"); public static final Material DARK_OAK_STAIRS = get("DARK_OAK_STAIRS"); - public static final List PLANKS; - public static final List FENCES; + public static final Set PLANKS; + public static final Set FENCES; // Materials removed in 1.13 public static final Material STATIONARY_LAVA = get("STATIONARY_LAVA"); From 81ea014e4503a669acf1d08a3f8189f310414216 Mon Sep 17 00:00:00 2001 From: Sn0wStorm Date: Sat, 9 Nov 2019 11:46:34 +0100 Subject: [PATCH 32/51] Save Alc content on the Brew --- src/com/dre/brewery/BIngredients.java | 5 +- src/com/dre/brewery/Brew.java | 46 +++++++++++++++---- .../api/events/brew/BrewDrinkEvent.java | 2 +- src/com/dre/brewery/filedata/BData.java | 3 +- src/com/dre/brewery/lore/BrewLore.java | 2 +- src/com/dre/brewery/recipe/BRecipe.java | 2 +- 6 files changed, 44 insertions(+), 16 deletions(-) diff --git a/src/com/dre/brewery/BIngredients.java b/src/com/dre/brewery/BIngredients.java index 721cb37..28d650e 100644 --- a/src/com/dre/brewery/BIngredients.java +++ b/src/com/dre/brewery/BIngredients.java @@ -116,8 +116,9 @@ public class BIngredients { if (cookRecipe != null) { // Potion is best with cooking only int quality = (int) Math.round((getIngredientQuality(cookRecipe) + getCookingQuality(cookRecipe, false)) / 2.0); - P.p.debugLog("cooked potion has Quality: " + quality); - brew = new Brew(quality, cookRecipe, this); + int alc = (int) Math.round(cookRecipe.getAlcohol() * ((float) quality / 10.0f)); + P.p.debugLog("cooked potion has Quality: " + quality + ", Alc: " + alc); + brew = new Brew(quality, alc, cookRecipe, this); BrewLore lore = new BrewLore(brew, potionMeta); lore.updateQualityStars(false); lore.updateCustomLore(); diff --git a/src/com/dre/brewery/Brew.java b/src/com/dre/brewery/Brew.java index 45c383a..b9edf7d 100644 --- a/src/com/dre/brewery/Brew.java +++ b/src/com/dre/brewery/Brew.java @@ -36,6 +36,7 @@ public class Brew { private BIngredients ingredients; private int quality; + private int alc; private byte distillRuns; private float ageTime; private float wood; @@ -52,17 +53,19 @@ public class Brew { } // quality already set - public Brew(int quality, BRecipe recipe, BIngredients ingredients) { + public Brew(int quality, int alc, BRecipe recipe, BIngredients ingredients) { this.ingredients = ingredients; this.quality = quality; + this.alc = alc; this.currentRecipe = recipe; touch(); } // loading with all values set - public Brew(BIngredients ingredients, int quality, byte distillRuns, float ageTime, float wood, String recipe, boolean unlabeled, boolean immutable, int lastUpdate) { + public Brew(BIngredients ingredients, int quality, int alc, byte distillRuns, float ageTime, float wood, String recipe, boolean unlabeled, boolean immutable, int lastUpdate) { this.ingredients = ingredients; this.quality = quality; + this.alc = alc; this.distillRuns = distillRuns; this.ageTime = ageTime; this.wood = wood; @@ -97,6 +100,7 @@ public class Brew { if (!item.hasItemMeta()) return null; ItemMeta meta = item.getItemMeta(); + assert meta != null; if (!P.useNBT && !meta.hasLore()) return null; Brew brew = load(meta); @@ -207,9 +211,9 @@ public class Brew { if (quality > 0) { currentRecipe = ingredients.getBestRecipe(wood, ageTime, distillRuns > 0); if (currentRecipe != null) { - if (!immutable) { + /*if (!immutable) { this.quality = calcQuality(); - } + }*/ P.p.log("A Brew was made from Recipe: '" + name + "' which could not be found. '" + currentRecipe.getRecipeName() + "' used instead!"); return true; } else { @@ -244,6 +248,7 @@ public class Brew { if (brew == null) return false; if (equals(brew)) return true; return quality == brew.quality && + alc == brew.alc && distillRuns == brew.distillRuns && Float.compare(brew.ageTime, ageTime) == 0 && Float.compare(brew.wood, wood) == 0 && @@ -258,7 +263,7 @@ public class Brew { @Override public Brew clone() throws CloneNotSupportedException { super.clone(); - Brew brew = new Brew(quality, currentRecipe, ingredients); + Brew brew = new Brew(quality, alc, currentRecipe, ingredients); brew.distillRuns = distillRuns; brew.ageTime = ageTime; brew.unlabeled = unlabeled; @@ -272,6 +277,7 @@ public class Brew { return "Brew{" + ingredients + " ingredients" + ", quality=" + quality + + ", alc=" + alc + ", distillRuns=" + distillRuns + ", ageTime=" + ageTime + ", wood=" + wood + @@ -317,13 +323,13 @@ public class Brew { return 0; } // bad quality can decrease alc by up to 40% - alc *= 1 - ((float) (10 - quality) * 0.04); + alc *= 1 - ((float) (10 - quality) * 0.04f); // distillable Potions should have half alc after one and full alc after all needed distills alc /= 2; alc *= 1.0F + ((float) distillRuns / currentRecipe.getDistillRuns()); } else { // quality decides 10% - 100% - alc *= ((float) quality / 10.0); + alc *= ((float) quality / 10.0f); } if (alc > 0) { return alc; @@ -391,6 +397,14 @@ public class Brew { lastUpdate = (int) ((double) (System.currentTimeMillis() - installTime) / 3600000D); } + public int getOrCalcAlc() { + return alc > 0 ? alc : (alc = calcAlcohol()); + } + + public void setAlc(int alc) { + this.alc = alc; + } + public byte getDistillRuns() { return distillRuns; } @@ -507,6 +521,7 @@ public class Brew { potionMeta.setDisplayName(P.p.color("&f" + P.p.languageReader.get("Brew_DistillUndefined"))); PotionColor.GREY.colorBrew(potionMeta, slotItem, canDistill()); } + alc = calcAlcohol(); // Distill Lore if (currentRecipe != null && BConfig.colorInBrewer != BrewLore.hasColorLore(potionMeta)) { @@ -580,6 +595,7 @@ public class Brew { PotionColor.GREY.colorBrew(potionMeta, item, canDistill()); } } + alc = calcAlcohol(); // Lore if (currentRecipe != null && BConfig.colorInBarrels != BrewLore.hasColorLore(potionMeta)) { @@ -756,6 +772,9 @@ public class Brew { private void loadFromStream(DataInputStream in, byte dataVersion) throws IOException { quality = in.readByte(); int bools = in.readUnsignedByte(); + if ((bools & 64) != 0) { + alc = in.readShort(); + } if ((bools & 1) != 0) { distillRuns = in.readByte(); } @@ -817,6 +836,7 @@ public class Brew { if (quality > 10) { quality = 10; } + alc = Math.min(alc, Short.MAX_VALUE); out.writeByte((byte) quality); int bools = 0; bools |= ((distillRuns != 0) ? 1 : 0); @@ -824,9 +844,12 @@ public class Brew { bools |= (wood != -1 ? 4 : 0); bools |= (currentRecipe != null ? 8 : 0); bools |= (unlabeled ? 16 : 0); - //bools |= (persistent ? 32 : 0); bools |= (immutable ? 32 : 0); + bools |= (alc > 0 ? 64 : 0); out.writeByte(bools); + if (alc > 0) { + out.writeShort(alc); + } if (distillRuns != 0) { out.writeByte(distillRuns); } @@ -877,8 +900,8 @@ public class Brew { } // 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, int lastUpdate) { - Brew brew = new Brew(ingredients, quality, distillRuns, ageTime, wood, recipe, unlabeled, stat, lastUpdate); + public static void loadLegacy(BIngredients ingredients, int uid, int quality, int alc, byte distillRuns, float ageTime, float wood, String recipe, boolean unlabeled, boolean persistent, boolean stat, int lastUpdate) { + Brew brew = new Brew(ingredients, quality, alc, distillRuns, ageTime, wood, recipe, unlabeled, stat, lastUpdate); brew.persistent = persistent; legacyPotions.put(uid, brew); } @@ -920,6 +943,9 @@ public class Brew { if (brew.quality != 0) { idConfig.set("quality", brew.quality); } + if (brew.alc > 0) { + idConfig.set("alc", brew.alc); + } if (brew.distillRuns != 0) { idConfig.set("distillRuns", brew.distillRuns); } diff --git a/src/com/dre/brewery/api/events/brew/BrewDrinkEvent.java b/src/com/dre/brewery/api/events/brew/BrewDrinkEvent.java index bbc526b..de6b7f1 100644 --- a/src/com/dre/brewery/api/events/brew/BrewDrinkEvent.java +++ b/src/com/dre/brewery/api/events/brew/BrewDrinkEvent.java @@ -24,7 +24,7 @@ public class BrewDrinkEvent extends BrewEvent implements Cancellable { super(brew, meta); this.player = player; this.bPlayer = bPlayer; - alc = brew.calcAlcohol(); + alc = brew.getOrCalcAlc(); quality = brew.getQuality(); } diff --git a/src/com/dre/brewery/filedata/BData.java b/src/com/dre/brewery/filedata/BData.java index 3f4d6f7..823d95a 100644 --- a/src/com/dre/brewery/filedata/BData.java +++ b/src/com/dre/brewery/filedata/BData.java @@ -85,6 +85,7 @@ public class BData { for (String uid : section.getKeys(false)) { BIngredients ingredients = getIngredients(ingMap, section.getString(uid + ".ingId")); int quality = section.getInt(uid + ".quality", 0); + int alc = section.getInt(uid + ".alc", 0); byte distillRuns = (byte) section.getInt(uid + ".distillRuns", 0); float ageTime = (float) section.getDouble(uid + ".ageTime", 0.0); float wood = (float) section.getDouble(uid + ".wood", -1.0); @@ -94,7 +95,7 @@ public class BData { boolean stat = section.getBoolean(uid + ".stat", false); int lastUpdate = section.getInt("lastUpdate", 0); - Brew.loadLegacy(ingredients, P.p.parseInt(uid), quality, distillRuns, ageTime, wood, recipe, unlabeled, persistent, stat, lastUpdate); + Brew.loadLegacy(ingredients, P.p.parseInt(uid), quality, alc, distillRuns, ageTime, wood, recipe, unlabeled, persistent, stat, lastUpdate); } } diff --git a/src/com/dre/brewery/lore/BrewLore.java b/src/com/dre/brewery/lore/BrewLore.java index 91d76b5..7da480f 100644 --- a/src/com/dre/brewery/lore/BrewLore.java +++ b/src/com/dre/brewery/lore/BrewLore.java @@ -240,7 +240,7 @@ public class BrewLore { public void updateAlc(boolean inDistiller) { if (!brew.isUnlabeled() && (inDistiller || BConfig.alwaysShowAlc) && (!brew.hasRecipe() || brew.getCurrentRecipe().getAlcohol() > 0)) { - int alc = brew.calcAlcohol(); + int alc = brew.getOrCalcAlc(); addOrReplaceLore(Type.ALC, "§8", P.p.languageReader.get("Brew_Alc", alc + "")); } else { removeLore(Type.ALC); diff --git a/src/com/dre/brewery/recipe/BRecipe.java b/src/com/dre/brewery/recipe/BRecipe.java index e35d87d..dc59c5c 100644 --- a/src/com/dre/brewery/recipe/BRecipe.java +++ b/src/com/dre/brewery/recipe/BRecipe.java @@ -377,7 +377,7 @@ public class BRecipe { BIngredients bIngredients = new BIngredients(list, cookingTime); - return new Brew(bIngredients, quality, distillruns, getAge(), wood, getRecipeName(), false, true, 0); + return new Brew(bIngredients, quality, 0, distillruns, getAge(), wood, getRecipeName(), false, true, 0); } From 318963b379448e3c7855690e88ad8c2d6be4d7c5 Mon Sep 17 00:00:00 2001 From: Sn0wStorm Date: Sat, 9 Nov 2019 17:02:48 +0100 Subject: [PATCH 33/51] Add/change recipes by plugin --- src/com/dre/brewery/BIngredients.java | 4 +- src/com/dre/brewery/Brew.java | 2 +- src/com/dre/brewery/P.java | 12 +- src/com/dre/brewery/api/BreweryApi.java | 165 +++++++++-- .../brewery/api/events/ConfigLoadEvent.java | 42 +++ src/com/dre/brewery/filedata/BConfig.java | 21 +- .../brewery/listeners/CommandListener.java | 2 +- .../dre/brewery/recipe/BCauldronRecipe.java | 173 ++++++++++- src/com/dre/brewery/recipe/BEffect.java | 9 + src/com/dre/brewery/recipe/BRecipe.java | 271 +++++++++++++++++- src/com/dre/brewery/recipe/PotionColor.java | 4 + test/com/dre/brewery/RecipeTests.java | 33 ++- 12 files changed, 697 insertions(+), 41 deletions(-) create mode 100644 src/com/dre/brewery/api/events/ConfigLoadEvent.java diff --git a/src/com/dre/brewery/BIngredients.java b/src/com/dre/brewery/BIngredients.java index 28d650e..660f4d4 100644 --- a/src/com/dre/brewery/BIngredients.java +++ b/src/com/dre/brewery/BIngredients.java @@ -203,7 +203,7 @@ public class BIngredients { int woodQuality; int ageQuality; BRecipe bestRecipe = null; - for (BRecipe recipe : BRecipe.recipes) { + for (BRecipe recipe : BRecipe.getAllRecipes()) { ingredientQuality = getIngredientQuality(recipe); cookingQuality = getCookingQuality(recipe, distilled); @@ -258,7 +258,7 @@ public class BIngredients { BCauldronRecipe best = null; float bestMatch = 0; float match; - for (BCauldronRecipe recipe : BCauldronRecipe.recipes) { + for (BCauldronRecipe recipe : BCauldronRecipe.getAllRecipes()) { match = recipe.getIngredientMatch(ingredients); if (match >= 10) { return recipe; diff --git a/src/com/dre/brewery/Brew.java b/src/com/dre/brewery/Brew.java index b9edf7d..78c6691 100644 --- a/src/com/dre/brewery/Brew.java +++ b/src/com/dre/brewery/Brew.java @@ -201,7 +201,7 @@ public class Brew { public boolean setRecipeFromString(String name) { currentRecipe = null; if (name != null && !name.equals("")) { - for (BRecipe recipe : BRecipe.recipes) { + for (BRecipe recipe : BRecipe.getAllRecipes()) { if (recipe.getRecipeName().equalsIgnoreCase(name)) { currentRecipe = recipe; return true; diff --git a/src/com/dre/brewery/P.java b/src/com/dre/brewery/P.java index f7715b8..bd7c860 100644 --- a/src/com/dre/brewery/P.java +++ b/src/com/dre/brewery/P.java @@ -439,11 +439,13 @@ public class P extends JavaPlugin { // delete Data from Ram Barrel.barrels.clear(); BCauldron.bcauldrons.clear(); - BRecipe.recipes.clear(); + BRecipe.getConfigRecipes().clear(); + BRecipe.numConfigRecipes = 0; BCauldronRecipe.acceptedMaterials.clear(); BCauldronRecipe.acceptedCustom.clear(); BCauldronRecipe.acceptedSimple.clear(); - BCauldronRecipe.recipes.clear(); + BCauldronRecipe.getConfigRecipes().clear(); + BCauldronRecipe.numConfigRecipes = 0; BConfig.customItems.clear(); BConfig.hasSlimefun = null; BConfig.hasMMOItems = null; @@ -462,11 +464,13 @@ public class P extends JavaPlugin { BConfig.reloader = sender; } // clear all existent config Data - BRecipe.recipes.clear(); + BRecipe.getConfigRecipes().clear(); + BRecipe.numConfigRecipes = 0; BCauldronRecipe.acceptedMaterials.clear(); BCauldronRecipe.acceptedCustom.clear(); BCauldronRecipe.acceptedSimple.clear(); - BCauldronRecipe.recipes.clear(); + BCauldronRecipe.getConfigRecipes().clear(); + BCauldronRecipe.numConfigRecipes = 0; BConfig.customItems.clear(); BConfig.hasSlimefun = null; BConfig.hasMMOItems = null; diff --git a/src/com/dre/brewery/api/BreweryApi.java b/src/com/dre/brewery/api/BreweryApi.java index 2f829ab..4f8d229 100644 --- a/src/com/dre/brewery/api/BreweryApi.java +++ b/src/com/dre/brewery/api/BreweryApi.java @@ -1,6 +1,7 @@ package com.dre.brewery.api; import com.dre.brewery.BCauldron; +import com.dre.brewery.recipe.BCauldronRecipe; import com.dre.brewery.recipe.BRecipe; import com.dre.brewery.Barrel; import com.dre.brewery.Brew; @@ -12,13 +13,14 @@ import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.meta.ItemMeta; import org.jetbrains.annotations.Nullable; -public class BreweryApi { +import java.util.List; -/* +/** * Convenience methods to get common objects or do common things */ +public class BreweryApi { - /* + /** * Remove any data that this Plugin may associate with the given Block * Currently Cauldrons and Barrels (Cauldron, Wood, Woodstairs, Fence, Sign) * Does not remove any actual Blocks @@ -29,7 +31,7 @@ public class BreweryApi { return removeBarrel(block); } - /* + /** * Like removeAny() but removes data as if the given player broke the Block * Currently only makes a difference for Logging */ @@ -39,9 +41,11 @@ public class BreweryApi { } + // # # # # # # # # # # # # // # # # # # Brew # # # # # + // # # # # # # # # # # # # - /* + /** * Get a Brew from an ItemStack * Reads the Brew data from the saved data on the item * Checks if item is actually a Brew @@ -52,7 +56,7 @@ public class BreweryApi { return Brew.get(item); } - /* + /** * Get a Brew from an ItemMeta * Reads the Brew data from the saved data in the Meta * Checks if meta has a Brew saved @@ -64,9 +68,11 @@ public class BreweryApi { } + // # # # # # # # # # # # # // # # # # # Barrel # # # # # + // # # # # # # # # # # # # - /* + /** * Get a Barrel from a Block * May be any Wood, Fence, Sign that is part of a Barrel * Returns null if block is not part of a Barrel @@ -76,7 +82,7 @@ public class BreweryApi { return Barrel.get(block); } - /* + /** * Get the Inventory of a Block part of a Barrel * May be any Wood, Fence or Sign that is part of a Barrel * Returns null if block is not part of a Barrel @@ -90,7 +96,7 @@ public class BreweryApi { return null; } - /* + /** * Remove any Barrel that this Block may be Part of * Returns true if a Barrel was removed * Does not remove any actual Block @@ -99,10 +105,10 @@ public class BreweryApi { return removeBarrelByPlayer(block, null); } - /* + /** * Remove any Barrel that this Block may be Part of, as if broken by the Player * Returns true if a Barrel was removed - * Does not remove any actual Block + * Does not remove any actual Block from the World */ public static boolean removeBarrelByPlayer(Block block, Player player) { Barrel barrel = Barrel.get(block); @@ -113,10 +119,11 @@ public class BreweryApi { return false; } - + // # # # # # # # # # # # # // # # # # # Cauldron # # # # # + // # # # # # # # # # # # # - /* + /** * Get a BCauldron from a Block * Returns null if block is not a BCauldron */ @@ -125,19 +132,21 @@ public class BreweryApi { return BCauldron.get(block); } - /* + /** * Remove any data associated with a Cauldron at that given Block * Returns true if a Cauldron was removed - * Does not actually remove the Block + * Does not remove the Block from the World */ public static boolean removeCauldron(Block block) { return BCauldron.remove(block); } + // # # # # # # # # # # # # // # # # # # Recipe # # # # # + // # # # # # # # # # # # # - /* + /** * Get a BRecipe by its name * The name is the middle one of the three if three are set in the config * Returns null if recipe with that name does not exist @@ -147,11 +156,125 @@ public class BreweryApi { return BRecipe.get(name); } - /* - * Add a new recipe - * Not Implemented yet + /** + * Add a New Recipe. + * Brews can be made out of this Recipe. + * The recipe can be changed or removed later. + * + * @param recipe The Recipe to add + * @param saveForever If the recipe should be saved forever, even after the Server restarts + * If True: Recipe will be saved until removed manually + * If False: Recipe will be removed when the Server restarts, existing potions using + * this Recipe will become bad after continued aging, if the recipe is not added again. */ - public static boolean addRecipe(BRecipe recipe) { - throw new NotImplementedException(); // TODO implement + public static void addRecipe(BRecipe recipe, boolean saveForever) { + //recipe.setSaveInData(saveForever); + if (saveForever) { + throw new NotImplementedException(); + } + BRecipe.getAddedRecipes().add(recipe); + recipe.updateAcceptedLists(); } + + /** + * Removes a Recipe from the List of all Recipes. + * This can also remove Recipes that were loaded from config, though these will be readded when reloading the config + * + * @param name The name of the recipe to remove + * @return The Recipe that was removed, null if none was removed + */ + @Nullable + public static BRecipe removeRecipe(String name) { + List recipes = BRecipe.getAllRecipes(); + for (int i = 0; i < recipes.size(); i++) { + if (recipes.get(i).getRecipeName().equalsIgnoreCase(name)) { + BRecipe remove = recipes.remove(i); + if (i < BRecipe.numConfigRecipes) { + // We removed one of the Config Recipes + BRecipe.numConfigRecipes--; + } + return remove; + } + } + return null; + } + + /** + * Create a New Recipe with a Recipe Builder. + * + * @param recipeNames Either 1 or 3 names. Sets the Name for Quality (Bad, Normal, Good) + * @return A Recipe Builder + */ + public static BRecipe.Builder recipeBuilder(String... recipeNames) { + return new BRecipe.Builder(recipeNames); + } + + + + // # # # # # # # # # # # # + // # # # # # Cauldron Recipe # # # # # + // # # # # # # # # # # # # + + /** + * Get A BCauldronRecipe by its name + * Returns null if recipe with that name does not exist + */ + @Nullable + public static BCauldronRecipe getCauldronRecipe(String name) { + return BCauldronRecipe.get(name); + } + + /** + * Add a New Cauldron Recipe. + * Base Brews coming out of the Cauldron can be made from this recipe + * The recipe can be changed or removed later. + * + * @param recipe The Cauldron Recipe to add + * @param saveForever If the recipe should be saved forever, even after the Server restarts + * If True: Recipe will be saved until removed manually + * If False: Recipe will be removed when the Server restarts + */ + public static void addCauldronRecipe(BCauldronRecipe recipe, boolean saveForever) { + //recipe.setSaveInData(saveForever); + if (saveForever) { + throw new NotImplementedException(); + } + BCauldronRecipe.getAddedRecipes().add(recipe); + recipe.updateAcceptedLists(); + } + + /** + * Removes a Cauldron Recipe from the List of all Cauldron Recipes. + * This can also remove Cauldron Recipes that were loaded from config, though these will be readded when reloading the config + * + * @param name The name of the cauldron recipe to remove + * @return The Cauldron Recipe that was removed, null if none was removed + */ + @Nullable + public static BCauldronRecipe removeCauldronRecipe(String name) { + List recipes = BCauldronRecipe.getAllRecipes(); + for (int i = 0; i < recipes.size(); i++) { + if (recipes.get(i).getName().equalsIgnoreCase(name)) { + BCauldronRecipe remove = recipes.remove(i); + if (i < BCauldronRecipe.numConfigRecipes) { + // We removed one of the Config Recipes + BCauldronRecipe.numConfigRecipes--; + } + return remove; + } + } + return null; + } + + /** + * Create a New Cauldron Recipe with a Recipe Builder. + * + * @param name The name of the new Cauldron Recipe + * @return A Cauldron Recipe Builder + */ + public static BCauldronRecipe.Builder cauldronRecipeBuilder(String name) { + return new BCauldronRecipe.Builder(name); + } + + } diff --git a/src/com/dre/brewery/api/events/ConfigLoadEvent.java b/src/com/dre/brewery/api/events/ConfigLoadEvent.java new file mode 100644 index 0000000..c3fec33 --- /dev/null +++ b/src/com/dre/brewery/api/events/ConfigLoadEvent.java @@ -0,0 +1,42 @@ +package com.dre.brewery.api.events; + +import com.dre.brewery.api.BreweryApi; +import com.dre.brewery.recipe.BCauldronRecipe; +import com.dre.brewery.recipe.BRecipe; +import org.bukkit.event.Event; +import org.bukkit.event.HandlerList; +import org.jetbrains.annotations.NotNull; + +import java.util.List; + +public class ConfigLoadEvent extends Event { + private static final HandlerList handlers = new HandlerList(); + + /** + * One of the things one might need to do after reloading + * Removes a Recipe, can also remove config recipes + * + * @param name Name of the Recipe to remove + * @return The Recipe that was removed, null if none was removed + */ + public BRecipe removeRecipe(String name) { + return BreweryApi.removeRecipe(name); + } + + /** + * One of the things one might need to do after reloading + * Removes a Cauldron Recipe, can also remove config recipes + * + * @param name Name of the Cauldron Recipe to remove + * @return The Cauldron Recipe that was removed, null if none was removed + */ + public BCauldronRecipe removeCauldronRecipe(String name) { + return BreweryApi.removeCauldronRecipe(name); + } + + @NotNull + @Override + public HandlerList getHandlers() { + return handlers; + } +} diff --git a/src/com/dre/brewery/filedata/BConfig.java b/src/com/dre/brewery/filedata/BConfig.java index c38349e..7ea44d9 100644 --- a/src/com/dre/brewery/filedata/BConfig.java +++ b/src/com/dre/brewery/filedata/BConfig.java @@ -4,6 +4,7 @@ import com.dre.brewery.Brew; import com.dre.brewery.DistortChat; import com.dre.brewery.MCBarrel; import com.dre.brewery.P; +import com.dre.brewery.api.events.ConfigLoadEvent; import com.dre.brewery.integration.barrel.WGBarrel; import com.dre.brewery.integration.barrel.WGBarrel5; import com.dre.brewery.integration.barrel.WGBarrel6; @@ -222,27 +223,39 @@ public class BConfig { // loading recipes configSection = config.getConfigurationSection("recipes"); if (configSection != null) { + List configRecipes = BRecipe.getConfigRecipes(); for (String recipeId : configSection.getKeys(false)) { BRecipe recipe = BRecipe.fromConfig(configSection, recipeId); if (recipe != null && recipe.isValid()) { - BRecipe.recipes.add(recipe); + configRecipes.add(recipe); } else { p.errorLog("Loading the Recipe with id: '" + recipeId + "' failed!"); } } + BRecipe.numConfigRecipes = configRecipes.size(); } // Loading Cauldron Recipes configSection = config.getConfigurationSection("cauldron"); if (configSection != null) { + List configRecipes = BCauldronRecipe.getConfigRecipes(); for (String id : configSection.getKeys(false)) { BCauldronRecipe recipe = BCauldronRecipe.fromConfig(configSection, id); if (recipe != null) { - BCauldronRecipe.recipes.add(recipe); + configRecipes.add(recipe); } else { p.errorLog("Loading the Cauldron-Recipe with id: '" + id + "' failed!"); } } + BCauldronRecipe.numConfigRecipes = configRecipes.size(); + } + + // Recalculating Cauldron-Accepted Items for non-config recipes + for (BRecipe recipe : BRecipe.getAddedRecipes()) { + recipe.updateAcceptedLists(); + } + for (BCauldronRecipe recipe : BCauldronRecipe.getAddedRecipes()) { + recipe.updateAcceptedLists(); } // loading drainItems @@ -286,6 +299,10 @@ public class BConfig { DistortChat.log = config.getBoolean("logRealChat", false); DistortChat.doSigns = config.getBoolean("distortSignText", false); + // The Config was reloaded, call Event + ConfigLoadEvent event = new ConfigLoadEvent(); + P.p.getServer().getPluginManager().callEvent(event); + return true; } } diff --git a/src/com/dre/brewery/listeners/CommandListener.java b/src/com/dre/brewery/listeners/CommandListener.java index 9ff7c1b..8ab4463 100644 --- a/src/com/dre/brewery/listeners/CommandListener.java +++ b/src/com/dre/brewery/listeners/CommandListener.java @@ -607,7 +607,7 @@ public class CommandListener implements CommandExecutor { } BRecipe recipe = null; - for (BRecipe r : BRecipe.recipes) { + for (BRecipe r : BRecipe.getAllRecipes()) { if (r.hasName(name)) { recipe = r; break; diff --git a/src/com/dre/brewery/recipe/BCauldronRecipe.java b/src/com/dre/brewery/recipe/BCauldronRecipe.java index 534b6e5..a724a30 100644 --- a/src/com/dre/brewery/recipe/BCauldronRecipe.java +++ b/src/com/dre/brewery/recipe/BCauldronRecipe.java @@ -2,12 +2,15 @@ package com.dre.brewery.recipe; import com.dre.brewery.P; import com.dre.brewery.utility.Tuple; +import org.bukkit.Color; import org.bukkit.Material; import org.bukkit.configuration.ConfigurationSection; +import org.bukkit.inventory.ItemStack; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import java.util.ArrayList; +import java.util.Collections; import java.util.EnumSet; import java.util.List; import java.util.Set; @@ -15,6 +18,7 @@ import java.util.stream.Collectors; public class BCauldronRecipe { public static List recipes = new ArrayList<>(); + public static int numConfigRecipes; public static List acceptedCustom = new ArrayList<>(); // All accepted custom and other items public static Set acceptedSimple = EnumSet.noneOf(Material.class); // All accepted simple items public static Set acceptedMaterials = EnumSet.noneOf(Material.class); // Fast cache for all accepted Materials @@ -24,20 +28,33 @@ public class BCauldronRecipe { //private List particles private PotionColor color; private List lore; + private boolean saveInData; // If this recipe should be saved in data and loaded again when the server restarts. Applicable to non-config recipes + /** + * A New Cauldron Recipe with the given name + * Use new BCauldronRecipe.Builder() for easier Cauldron Recipe Creation + * + * @param name Name of the Cauldron Recipe + */ + public BCauldronRecipe(String name) { + this.name = name; + color = PotionColor.CYAN; + } + @Nullable public static BCauldronRecipe fromConfig(ConfigurationSection cfg, String id) { - BCauldronRecipe recipe = new BCauldronRecipe(); - recipe.name = cfg.getString(id + ".name"); - if (recipe.name != null) { - recipe.name = P.p.color(recipe.name); + String name = cfg.getString(id + ".name"); + if (name != null) { + name = P.p.color(name); } else { P.p.errorLog("Missing name for Cauldron-Recipe: " + id); return null; } + BCauldronRecipe recipe = new BCauldronRecipe(name); + recipe.ingredients = BRecipe.loadIngredients(cfg, id); if (recipe.ingredients == null || recipe.ingredients.isEmpty()) { P.p.errorLog("No ingredients for Cauldron-Recipe: " + recipe.name); @@ -66,6 +83,9 @@ public class BCauldronRecipe { return recipe; } + + // Getter + @NotNull public String getName() { return name; @@ -86,6 +106,32 @@ public class BCauldronRecipe { return lore; } + public boolean isSaveInData() { + return saveInData; + } + + + // Setter + + /** + * When Changing ingredients, Accepted Lists have to be updated in BCauldronRecipe + */ + public void setIngredients(@NotNull List ingredients) { + this.ingredients = ingredients; + } + + public void setColor(@NotNull PotionColor color) { + this.color = color; + } + + public void setLore(List lore) { + this.lore = lore; + } + + public void setSaveInData(boolean saveInData) { + this.saveInData = saveInData; + } + /** * Find how much these ingredients match the given ones from 0-10. * If any ingredient is missing, returns 0 @@ -132,11 +178,64 @@ public class BCauldronRecipe { return match; } + public void updateAcceptedLists() { + for (RecipeItem ingredient : getIngredients()) { + if (ingredient.hasMaterials()) { + BCauldronRecipe.acceptedMaterials.addAll(ingredient.getMaterials()); + } + if (ingredient instanceof SimpleItem) { + BCauldronRecipe.acceptedSimple.add(((SimpleItem) ingredient).getMaterial()); + } else { + // Add it as acceptedCustom + if (!BCauldronRecipe.acceptedCustom.contains(ingredient)) { + BCauldronRecipe.acceptedCustom.add(ingredient); + } + } + } + } + @Override public String toString() { return "BCauldronRecipe{" + name + '}'; } + @Nullable + public static BCauldronRecipe get(String name) { + for (BCauldronRecipe recipe : recipes) { + if (recipe.name.equalsIgnoreCase(name)) { + return recipe; + } + } + return null; + } + + /** + * Gets a Modifiable Sublist of the CauldronRecipes that are loaded by config + * Changes are directly reflected by the main list of all recipes + * Changes to the main List of all CauldronRecipes will make the reference to this sublist invalid + * + * After adding or removing elements, CauldronRecipes.numConfigRecipes MUST be updated! + */ + public static List getConfigRecipes() { + return recipes.subList(0, numConfigRecipes); + } + + /** + * Gets a Modifiable Sublist of the CauldronRecipes that are added by plugins + * Changes are directly reflected by the main list of all recipes + * Changes to the main List of all CauldronRecipes will make the reference to this sublist invalid + */ + public static List getAddedRecipes() { + return recipes.subList(numConfigRecipes, recipes.size()); + } + + /** + * Gets the main List of all CauldronRecipes + */ + public static List getAllRecipes() { + return recipes; + } + /*public static boolean acceptItem(ItemStack item) { if (acceptedMaterials.contains(item.getType())) { // Extremely fast way to check for most items @@ -172,4 +271,70 @@ public class BCauldronRecipe { } return null; }*/ + + public static class Builder { + private BCauldronRecipe recipe; + + public Builder(String name) { + recipe = new BCauldronRecipe(name); + } + + + public Builder addIngredient(RecipeItem... item) { + if (recipe.ingredients == null) { + recipe.ingredients = new ArrayList<>(); + } + Collections.addAll(recipe.ingredients, item); + return this; + } + + public Builder addIngredient(ItemStack... item) { + if (recipe.ingredients == null) { + recipe.ingredients = new ArrayList<>(); + } + for (ItemStack i : item) { + recipe.ingredients.add(new CustomItem(i)); + } + return this; + } + + public Builder color(String colorString) { + recipe.color = PotionColor.fromString(colorString); + return this; + } + + public Builder color(PotionColor color) { + recipe.color = color; + return this; + } + + public Builder color(Color color) { + recipe.color = PotionColor.fromColor(color); + return this; + } + + public Builder addLore(String line) { + if (recipe.lore == null) { + recipe.lore = new ArrayList<>(); + } + recipe.lore.add(line); + return this; + } + + public BCauldronRecipe get() { + if (recipe.name == null) { + throw new IllegalArgumentException("CauldronRecipe name is null"); + } + if (BCauldronRecipe.get(recipe.getName()) != null) { + throw new IllegalArgumentException("CauldronRecipe with name " + recipe.getName() + " already exists"); + } + if (recipe.color == null) { + throw new IllegalArgumentException("CauldronRecipe has no color"); + } + if (recipe.ingredients == null || recipe.ingredients.isEmpty()) { + throw new IllegalArgumentException("CauldronRecipe has no ingredients"); + } + return recipe; + } + } } diff --git a/src/com/dre/brewery/recipe/BEffect.java b/src/com/dre/brewery/recipe/BEffect.java index 0dc282e..edb99cc 100644 --- a/src/com/dre/brewery/recipe/BEffect.java +++ b/src/com/dre/brewery/recipe/BEffect.java @@ -17,6 +17,15 @@ public class BEffect { private boolean hidden = false; + public BEffect(PotionEffectType type, short minlvl, short maxlvl, short minduration, short maxduration, boolean hidden) { + this.type = type; + this.minlvl = minlvl; + this.maxlvl = maxlvl; + this.minduration = minduration; + this.maxduration = maxduration; + this.hidden = hidden; + } + public BEffect(String effectString) { String[] effectSplit = effectString.split("/"); String effect = effectSplit[0]; diff --git a/src/com/dre/brewery/recipe/BRecipe.java b/src/com/dre/brewery/recipe/BRecipe.java index dc59c5c..e3dab3f 100644 --- a/src/com/dre/brewery/recipe/BRecipe.java +++ b/src/com/dre/brewery/recipe/BRecipe.java @@ -5,6 +5,8 @@ import com.dre.brewery.Brew; import com.dre.brewery.P; import com.dre.brewery.filedata.BConfig; import com.dre.brewery.utility.Tuple; +import org.apache.commons.lang.NotImplementedException; +import org.bukkit.Color; import org.bukkit.Material; import org.bukkit.configuration.ConfigurationSection; import org.bukkit.inventory.ItemStack; @@ -12,11 +14,13 @@ import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import java.util.ArrayList; +import java.util.Collections; import java.util.List; public class BRecipe { public static List recipes = new ArrayList<>(); + public static int numConfigRecipes; // The number of recipes in the list that are from config private String[] name; private List ingredients = new ArrayList<>(); // Items and amounts @@ -30,8 +34,33 @@ public class BRecipe { private int alcohol; // Alcohol in perfect potion private List> lore; // Custom Lore on the Potion. The int is for Quality Lore, 0 = any, 1,2,3 = Bad,Middle,Good private List effects = new ArrayList<>(); // Special Effects when drinking + private boolean saveInData; // If this recipe should be saved in data and loaded again when the server restarts. Applicable to non-config recipes - public BRecipe() { + private BRecipe() { + } + + /** + * New BRecipe with Name + * Use new BRecipe.Builder() for easier Recipe Creation + * + * @param name The name for all qualities + */ + public BRecipe(String name, @NotNull PotionColor color) { + this.name = new String[] {name}; + this.color = color; + difficulty = 5; + } + + /** + * New BRecipe with Names + * Use new BRecipe.Builder() for easier Recipe Creation + * + * @param names {name bad, name normal, name good} + */ + public BRecipe(String[] names, @NotNull PotionColor color) { + this.name = names; + this.color = color; + difficulty = 5; } @Nullable @@ -380,6 +409,22 @@ public class BRecipe { return new Brew(bIngredients, quality, 0, distillruns, getAge(), wood, getRecipeName(), false, true, 0); } + public void updateAcceptedLists() { + for (RecipeItem ingredient : getIngredients()) { + if (ingredient.hasMaterials()) { + BCauldronRecipe.acceptedMaterials.addAll(ingredient.getMaterials()); + } + if (ingredient instanceof SimpleItem) { + BCauldronRecipe.acceptedSimple.add(((SimpleItem) ingredient).getMaterial()); + } else { + // Add it as acceptedCustom + if (!BCauldronRecipe.acceptedCustom.contains(ingredient)) { + BCauldronRecipe.acceptedCustom.add(ingredient); + } + } + } + } + // Getter @@ -433,6 +478,13 @@ public class BRecipe { return false; } + + // Getters + + public List getIngredients() { + return ingredients; + } + public int getCookingTime() { return cookingTime; } @@ -500,11 +552,97 @@ public class BRecipe { return effects; } + public boolean isSaveInData() { + return saveInData; + } + + // Setters + + /** + * When Changing ingredients, Accepted Lists have to be updated in BCauldronRecipe + */ + public void setIngredients(List ingredients) { + this.ingredients = ingredients; + } + + public void setCookingTime(int cookingTime) { + this.cookingTime = cookingTime; + } + + public void setDistillruns(byte distillruns) { + this.distillruns = distillruns; + } + + public void setDistillTime(int distillTime) { + this.distillTime = distillTime; + } + + public void setWood(byte wood) { + this.wood = wood; + } + + public void setAge(int age) { + this.age = age; + } + + public void setColor(@NotNull PotionColor color) { + this.color = color; + } + + public void setDifficulty(int difficulty) { + this.difficulty = difficulty; + } + + public void setAlcohol(int alcohol) { + this.alcohol = alcohol; + } + + public void setLore(List> lore) { + this.lore = lore; + } + + public void setEffects(List effects) { + this.effects = effects; + } + + public void setSaveInData(boolean saveInData) { + throw new NotImplementedException(); + //this.saveInData = saveInData; + } + + @Override public String toString() { return "BRecipe{" + getRecipeName() + '}'; } + /** + * Gets a Modifiable Sublist of the Recipes that are loaded by config + * Changes are directly reflected by the main list of all recipes + * Changes to the main List of all recipes will make the reference to this sublist invalid + * + * After adding or removing elements, BRecipe.numConfigRecipes MUST be updated! + */ + public static List getConfigRecipes() { + return recipes.subList(0, numConfigRecipes); + } + + /** + * Gets a Modifiable Sublist of the Recipes that are added by plugins + * Changes are directly reflected by the main list of all recipes + * Changes to the main List of all recipes will make the reference to this sublist invalid + */ + public static List getAddedRecipes() { + return recipes.subList(numConfigRecipes, recipes.size()); + } + + /** + * Gets the main List of all recipes + */ + public static List getAllRecipes() { + return recipes; + } + public static BRecipe get(String name) { for (BRecipe recipe : recipes) { if (recipe.getRecipeName().equalsIgnoreCase(name)) { @@ -513,4 +651,135 @@ public class BRecipe { } return null; } + + /*public static void saveAddedRecipes(ConfigurationSection cfg) { + int i = 0; + for (BRecipe recipe : getAddedRecipes()) { + if (recipe.isSaveInData()) { + cfg.set(i + ".name", recipe.name); + } + } + }*/ + + + public static class Builder { + private BRecipe recipe; + + public Builder(String name) { + recipe = new BRecipe(name, PotionColor.WATER); + } + + public Builder(String... names) { + recipe = new BRecipe(names, PotionColor.WATER); + } + + + public Builder addIngredient(RecipeItem... item) { + Collections.addAll(recipe.ingredients, item); + return this; + } + + public Builder addIngredient(ItemStack... item) { + for (ItemStack i : item) { + CustomItem customItem = new CustomItem(i); + customItem.setAmount(i.getAmount()); + recipe.ingredients.add(customItem); + } + return this; + } + + public Builder difficulty(int difficulty) { + recipe.difficulty = difficulty; + return this; + } + + public Builder color(String colorString) { + recipe.color = PotionColor.fromString(colorString); + return this; + } + + public Builder color(PotionColor color) { + recipe.color = color; + return this; + } + + public Builder color(Color color) { + recipe.color = PotionColor.fromColor(color); + return this; + } + + public Builder cook(int cookTime) { + recipe.cookingTime = cookTime; + return this; + } + + public Builder distill(byte distillRuns, int distillTime) { + recipe.distillruns = distillRuns; + recipe.distillTime = distillTime; + return this; + } + + public Builder age(int age, byte wood) { + recipe.age = age; + recipe.wood = wood; + return this; + } + + public Builder alcohol(int alcohol) { + recipe.alcohol = alcohol; + return this; + } + + public Builder addLore(String line) { + return addLore(0, line); + } + + /** + * Add a Line of Lore + * + * @param quality 0 for any quality, 1: bad, 2: normal, 3: good + * @param line The Line for custom lore to add + * @return this + */ + public Builder addLore(int quality, String line) { + if (quality < 0 || quality > 3) { + throw new IllegalArgumentException("Lore Quality must be 0 - 3"); + } + if (recipe.lore == null) { + recipe.lore = new ArrayList<>(); + } + recipe.lore.add(new Tuple<>(quality, line)); + return this; + } + + public Builder addEffects(BEffect... effects) { + Collections.addAll(recipe.effects, effects); + return this; + } + + public BRecipe get() { + if (recipe.name == null) { + throw new IllegalArgumentException("Recipe name is null"); + } + if (recipe.name.length != 1 && recipe.name.length != 3) { + throw new IllegalArgumentException("Recipe name neither 1 nor 3"); + } + if (BRecipe.get(recipe.getRecipeName()) != null) { + throw new IllegalArgumentException("Recipe with name " + recipe.getRecipeName() + " already exists"); + } + if (recipe.color == null) { + throw new IllegalArgumentException("Recipe has no color"); + } + if (recipe.ingredients == null || recipe.ingredients.isEmpty()) { + throw new IllegalArgumentException("Recipe has no ingredients"); + } + if (!recipe.isValid()) { + throw new IllegalArgumentException("Recipe has not valid"); + } + for (RecipeItem ingredient : recipe.ingredients) { + ingredient.makeImmutable(); + } + return recipe; + } + } } diff --git a/src/com/dre/brewery/recipe/PotionColor.java b/src/com/dre/brewery/recipe/PotionColor.java index 8561ea4..bfeee7b 100644 --- a/src/com/dre/brewery/recipe/PotionColor.java +++ b/src/com/dre/brewery/recipe/PotionColor.java @@ -101,4 +101,8 @@ public class PotionColor { } } + public static PotionColor fromColor(Color color) { + return new PotionColor(color); + } + } diff --git a/test/com/dre/brewery/RecipeTests.java b/test/com/dre/brewery/RecipeTests.java index 6b9e63c..e7efb04 100644 --- a/test/com/dre/brewery/RecipeTests.java +++ b/test/com/dre/brewery/RecipeTests.java @@ -1,10 +1,7 @@ package com.dre.brewery; -import com.dre.brewery.recipe.BCauldronRecipe; -import com.dre.brewery.recipe.BRecipe; -import com.dre.brewery.recipe.Ingredient; -import com.dre.brewery.recipe.RecipeItem; -import com.dre.brewery.recipe.SimpleItem; +import com.dre.brewery.api.BreweryApi; +import com.dre.brewery.recipe.*; import org.bukkit.Material; import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.meta.ItemMeta; @@ -66,4 +63,30 @@ public class RecipeTests { RecipeItem.getMatchingRecipeItem(item, false); } + + public static void testCustomRecipe() { + BreweryApi.removeRecipe("Good Build"); + BRecipe recipe = BreweryApi.recipeBuilder("Bad Build", "Good Build", "Uber Build") + .color(PotionColor.PINK) + .addIngredient(new ItemStack(Material.FLOWER_POT)) + .alcohol(32) + .cook(3) + .difficulty(4) + .age(3, (byte) 0) + .get(); + BreweryApi.addRecipe(recipe, false); + + P.p.log(BRecipe.getConfigRecipes().size() + ""); + + BreweryApi.removeRecipe("Bier"); + + P.p.log(BRecipe.getConfigRecipes().size() + ""); + + BCauldronRecipe r = BreweryApi.cauldronRecipeBuilder("Cooler Trank") + .color(PotionColor.PINK) + .addIngredient(new SimpleItem(Material.FLOWER_POT)) + .addLore("Schmeckt nAcH TOn?!") + .get(); + BreweryApi.addCauldronRecipe(r, false); + } } From 48a15a0e82210419e42e43852bb2836a21224efb Mon Sep 17 00:00:00 2001 From: Sn0wStorm Date: Tue, 12 Nov 2019 17:02:01 +0100 Subject: [PATCH 34/51] Convert on Chest Open, delete lost legacy brews --- src/com/dre/brewery/Brew.java | 4 ++ src/com/dre/brewery/filedata/BData.java | 23 +++++++++- .../integration/barrel/CitadelBarrel.java | 43 ------------------- .../brewery/listeners/InventoryListener.java | 21 +++++++++ 4 files changed, 46 insertions(+), 45 deletions(-) delete mode 100644 src/com/dre/brewery/integration/barrel/CitadelBarrel.java diff --git a/src/com/dre/brewery/Brew.java b/src/com/dre/brewery/Brew.java index 78c6691..68aca17 100644 --- a/src/com/dre/brewery/Brew.java +++ b/src/com/dre/brewery/Brew.java @@ -903,6 +903,10 @@ public class Brew { public static void loadLegacy(BIngredients ingredients, int uid, int quality, int alc, byte distillRuns, float ageTime, float wood, String recipe, boolean unlabeled, boolean persistent, boolean stat, int lastUpdate) { Brew brew = new Brew(ingredients, quality, alc, distillRuns, ageTime, wood, recipe, unlabeled, stat, lastUpdate); brew.persistent = persistent; + if (brew.lastUpdate <= 0) { + // We failed to save the lastUpdate, restart the countdown + brew.touch(); + } legacyPotions.put(uid, brew); } diff --git a/src/com/dre/brewery/filedata/BData.java b/src/com/dre/brewery/filedata/BData.java index 823d95a..6ac1cfc 100644 --- a/src/com/dre/brewery/filedata/BData.java +++ b/src/com/dre/brewery/filedata/BData.java @@ -93,12 +93,31 @@ public class BData { boolean unlabeled = section.getBoolean(uid + ".unlabeled", false); boolean persistent = section.getBoolean(uid + ".persist", false); boolean stat = section.getBoolean(uid + ".stat", false); - int lastUpdate = section.getInt("lastUpdate", 0); + int lastUpdate = section.getInt(uid + ".lastUpdate", 0); Brew.loadLegacy(ingredients, P.p.parseInt(uid), quality, alc, distillRuns, ageTime, wood, recipe, unlabeled, persistent, stat, lastUpdate); } } + // Remove Legacy Potions that haven't been touched in a long time, these may have been lost + if (!Brew.noLegacy()) { + int currentHoursAfterInstall = (int) ((double) (System.currentTimeMillis() - Brew.installTime) / 3600000D); + int purgeTime = currentHoursAfterInstall - (24 * 30 * 4); // Purge Time is 4 Months ago + if (purgeTime > 0) { + int removed = 0; + for (Iterator iterator = Brew.legacyPotions.values().iterator(); iterator.hasNext(); ) { + Brew brew = iterator.next(); + if (brew.getLastUpdate() < purgeTime) { + iterator.remove(); + removed++; + } + } + if (removed > 0) { + P.p.log("Removed " + removed + " Legacy Brews older than 3 months"); + } + } + } + // loading BPlayer section = data.getConfigurationSection("Player"); if (section != null) { @@ -133,7 +152,7 @@ public class BData { } } else { - P.p.errorLog("No data.yml found, will create new one!"); + P.p.log("No data.yml found, will create new one!"); } } diff --git a/src/com/dre/brewery/integration/barrel/CitadelBarrel.java b/src/com/dre/brewery/integration/barrel/CitadelBarrel.java deleted file mode 100644 index c519baf..0000000 --- a/src/com/dre/brewery/integration/barrel/CitadelBarrel.java +++ /dev/null @@ -1,43 +0,0 @@ -package com.dre.brewery.integration.barrel; - -import org.bukkit.block.Block; -import org.bukkit.entity.Player; - -import com.dre.brewery.P; - -import vg.civcraft.mc.citadel.Citadel; -import vg.civcraft.mc.citadel.ReinforcementManager; -import vg.civcraft.mc.citadel.reinforcement.NullReinforcement; -import vg.civcraft.mc.citadel.reinforcement.PlayerReinforcement; -import vg.civcraft.mc.citadel.reinforcement.Reinforcement; - -/** - * Basic Citadel support to prevent randos from stealing your barrel aging brews - * - * @author ProgrammerDan - */ -public class CitadelBarrel { - static P brewery = P.p; - - public static boolean checkAccess(Player player, Block sign) { - ReinforcementManager manager = Citadel.getReinforcementManager(); - - Reinforcement rein = manager.getReinforcement(sign); - - if (rein == null) return true; // no protections in place. - - if (rein instanceof PlayerReinforcement) { - PlayerReinforcement prein = (PlayerReinforcement) rein; - if (prein.canAccessChests(player)) { - return true; - } - } else if (rein instanceof NullReinforcement) { - return true; - } - // no support for multiblock atm, would require namelayer support. - - // special locked, or no access. - brewery.msg(player, brewery.languageReader.get("Error_NoBarrelAccess")); - return false; - } -} diff --git a/src/com/dre/brewery/listeners/InventoryListener.java b/src/com/dre/brewery/listeners/InventoryListener.java index 6f62baa..5fd6622 100644 --- a/src/com/dre/brewery/listeners/InventoryListener.java +++ b/src/com/dre/brewery/listeners/InventoryListener.java @@ -249,6 +249,27 @@ public class InventoryListener implements Listener { //public static boolean opening = false; + @SuppressWarnings("deprecation") + @EventHandler(ignoreCancelled = false) + public void onInventoryOpenLegacyConvert(InventoryOpenEvent event) { + if (Brew.noLegacy()) { + return; + } + if (event.getInventory().getType() == InventoryType.PLAYER) { + return; + } + for (ItemStack item : event.getInventory().getContents()) { + if (item != null && item.getType() == Material.POTION) { + int uid = Brew.getUID(item); + // Check if the uid exists first, otherwise it will log that it can't find the id + if (uid < 0 && Brew.legacyPotions.containsKey(uid)) { + // This will convert the Brew + Brew.get(item); + } + } + } + } + @EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true) public void onInventoryOpen(InventoryOpenEvent event) { if (!P.use1_14) return; From 3332354846cf614a540e0d309fc7e272523b41b1 Mon Sep 17 00:00:00 2001 From: Sn0wStorm Date: Wed, 13 Nov 2019 22:07:22 +0100 Subject: [PATCH 35/51] Added more API and features for Events --- src/com/dre/brewery/BPlayer.java | 39 +++-- src/com/dre/brewery/Barrel.java | 16 +- src/com/dre/brewery/BarrelBody.java | 5 +- src/com/dre/brewery/Brew.java | 156 ++++++++++++++---- src/com/dre/brewery/DistortChat.java | 35 +++- src/com/dre/brewery/P.java | 4 + src/com/dre/brewery/api/BreweryApi.java | 98 ++++++++++- .../brewery/api/events/ConfigLoadEvent.java | 8 + .../brewery/api/events/IngedientAddEvent.java | 62 +++++-- .../api/events/PlayerAlcEffectEvent.java | 54 ------ .../api/events/PlayerChatDistortEvent.java | 95 +++++++++++ .../api/events/PlayerDrinkEffectEvent.java | 52 ------ .../brewery/api/events/PlayerEffectEvent.java | 94 +++++++++++ .../brewery/api/events/PlayerPukeEvent.java | 11 +- .../brewery/api/events/PlayerPushEvent.java | 20 ++- .../api/events/barrel/BarrelAccessEvent.java | 11 +- .../api/events/barrel/BarrelCreateEvent.java | 5 +- .../api/events/barrel/BarrelDestroyEvent.java | 54 +++++- .../api/events/barrel/BarrelEvent.java | 4 +- .../api/events/barrel/BarrelRemoveEvent.java | 23 ++- .../api/events/brew/BrewDrinkEvent.java | 5 +- .../api/events/brew/BrewModifyEvent.java | 5 +- .../dre/brewery/listeners/BlockListener.java | 4 +- .../dre/brewery/listeners/EntityListener.java | 4 +- .../brewery/listeners/InventoryListener.java | 6 +- src/com/dre/brewery/lore/NBTLoadStream.java | 7 +- src/com/dre/brewery/lore/NBTSaveStream.java | 4 +- src/com/dre/brewery/utility/BUtil.java | 6 +- src/com/dre/brewery/utility/LegacyUtil.java | 9 + 29 files changed, 672 insertions(+), 224 deletions(-) delete mode 100644 src/com/dre/brewery/api/events/PlayerAlcEffectEvent.java create mode 100644 src/com/dre/brewery/api/events/PlayerChatDistortEvent.java delete mode 100644 src/com/dre/brewery/api/events/PlayerDrinkEffectEvent.java create mode 100644 src/com/dre/brewery/api/events/PlayerEffectEvent.java diff --git a/src/com/dre/brewery/BPlayer.java b/src/com/dre/brewery/BPlayer.java index 0e8a338..cb73347 100644 --- a/src/com/dre/brewery/BPlayer.java +++ b/src/com/dre/brewery/BPlayer.java @@ -1,7 +1,6 @@ package com.dre.brewery; -import com.dre.brewery.api.events.PlayerAlcEffectEvent; -import com.dre.brewery.api.events.PlayerDrinkEffectEvent; +import com.dre.brewery.api.events.PlayerEffectEvent; import com.dre.brewery.api.events.PlayerPukeEvent; import com.dre.brewery.api.events.PlayerPushEvent; import com.dre.brewery.api.events.brew.BrewDrinkEvent; @@ -160,21 +159,21 @@ public class BPlayer { if (brewAlc < 1) { //no alcohol so we dont need to add a BPlayer - applyDrinkEffects(effects, player); + applyEffects(effects, player, PlayerEffectEvent.EffectType.DRINK); if (bPlayer.drunkeness <= 0) { bPlayer.remove(); } return true; } - effects.addAll(getQualityEffects(drinkEvent.getQuality(), brewAlc)); bPlayer.drunkeness += brewAlc; if (quality > 0) { bPlayer.quality += quality * brewAlc; } else { bPlayer.quality += brewAlc; } - applyDrinkEffects(effects, player); + applyEffects(effects, player, PlayerEffectEvent.EffectType.DRINK); + applyEffects(getQualityEffects(drinkEvent.getQuality(), brewAlc), player, PlayerEffectEvent.EffectType.QUALITY); if (bPlayer.drunkeness > 100) { bPlayer.drinkCap(player); @@ -490,8 +489,8 @@ public class BPlayer { // #### Effects #### - public static void applyDrinkEffects(List effects, Player player) { - PlayerDrinkEffectEvent event = new PlayerDrinkEffectEvent(player, effects); + public static void applyEffects(List effects, Player player, PlayerEffectEvent.EffectType effectType) { + PlayerEffectEvent event = new PlayerEffectEvent(player, effectType, effects); P.p.getServer().getPluginManager().callEvent(event); effects = event.getEffects(); if (event.isCancelled() || effects == null) { @@ -517,7 +516,7 @@ public class BPlayer { List l = new ArrayList<>(1); l.add(PotionEffectType.CONFUSION.createEffect(duration, 0)); - PlayerAlcEffectEvent event = new PlayerAlcEffectEvent(player, l); + PlayerEffectEvent event = new PlayerEffectEvent(player, PlayerEffectEvent.EffectType.ALCOHOL, l); P.p.getServer().getPluginManager().callEvent(event); l = event.getEffects(); if (event.isCancelled() || l == null) { @@ -565,7 +564,14 @@ public class BPlayer { } public static void addQualityEffects(int quality, int brewAlc, Player player) { - for (PotionEffect effect : getQualityEffects(quality, brewAlc)) { + List list = getQualityEffects(quality, brewAlc); + PlayerEffectEvent event = new PlayerEffectEvent(player, PlayerEffectEvent.EffectType.QUALITY, list); + P.p.getServer().getPluginManager().callEvent(event); + list = event.getEffects(); + if (event.isCancelled() || list == null) { + return; + } + for (PotionEffect effect : list) { BUtil.reapplyPotionEffect(player, effect, true); } } @@ -599,8 +605,19 @@ public class BPlayer { } int amplifier = getHangoverQuality() / 3; - BUtil.reapplyPotionEffect(player, PotionEffectType.SLOW.createEffect(duration, amplifier), true); - BUtil.reapplyPotionEffect(player, PotionEffectType.HUNGER.createEffect(duration, amplifier), true); + List list = new ArrayList<>(2); + list.add(PotionEffectType.SLOW.createEffect(duration, amplifier)); + list.add(PotionEffectType.HUNGER.createEffect(duration, amplifier)); + + PlayerEffectEvent event = new PlayerEffectEvent(player, PlayerEffectEvent.EffectType.HANGOVER, list); + P.p.getServer().getPluginManager().callEvent(event); + list = event.getEffects(); + if (event.isCancelled() || list == null) { + return; + } + for (PotionEffect effect : list) { + BUtil.reapplyPotionEffect(player, effect, true); + } } diff --git a/src/com/dre/brewery/Barrel.java b/src/com/dre/brewery/Barrel.java index 3178f3d..a2e9f99 100644 --- a/src/com/dre/brewery/Barrel.java +++ b/src/com/dre/brewery/Barrel.java @@ -325,9 +325,15 @@ public class Barrel implements InventoryHolder { return false; } - // removes a barrel, throwing included potions to the ground - public void remove(Block broken, Player breaker) { - BarrelRemoveEvent event = new BarrelRemoveEvent(this); + /** + * Removes a barrel, throwing included potions to the ground + * + * @param broken The Block that was broken + * @param breaker The Player that broke it, or null if not known + * @param dropItems If the items in the barrels inventory should drop to the ground + */ + public void remove(@Nullable Block broken, @Nullable Player breaker, boolean dropItems) { + BarrelRemoveEvent event = new BarrelRemoveEvent(this, dropItems); // Listened to by LWCBarrel (IntegrationListener) P.p.getServer().getPluginManager().callEvent(event); @@ -348,7 +354,7 @@ public class Barrel implements InventoryHolder { e.printStackTrace(); } } - if (event.willItemsDrop()) { + if (event.willDropItems()) { for (ItemStack item : items) { if (item != null) { Brew brew = Brew.get(item); @@ -480,7 +486,7 @@ public class Barrel implements InventoryHolder { P.p.debugLog("Barrel at " + broken.getWorld().getName() + "/" + broken.getX() + "/" + broken.getY() + "/" + broken.getZ() + " has been destroyed unexpectedly, contents will drop"); // remove the barrel if it was destroyed - barrel.remove(broken, null); + barrel.remove(broken, null, true); } else { // Dont check this barrel again, its enough to check it once after every restart // as now this is only the backup if we dont register the barrel breaking, as sample diff --git a/src/com/dre/brewery/BarrelBody.java b/src/com/dre/brewery/BarrelBody.java index 88795a9..c3c9efa 100644 --- a/src/com/dre/brewery/BarrelBody.java +++ b/src/com/dre/brewery/BarrelBody.java @@ -34,7 +34,7 @@ public class BarrelBody { // This will only be done in those extreme cases. Block broken = getBrokenBlock(true); if (broken != null) { - barrel.remove(broken, null); + barrel.remove(broken, null, true); } } else { this.bounds = bounds; @@ -150,6 +150,9 @@ public class BarrelBody { */ public boolean hasBlock(Block block) { if (block != null) { + if (spigot.equals(block)) { + return true; + } if (spigot.getWorld().equals(block.getWorld())) { return bounds != null && bounds.contains(block.getX(), block.getY(), block.getZ()); } diff --git a/src/com/dre/brewery/Brew.java b/src/com/dre/brewery/Brew.java index 68aca17..cf9011f 100644 --- a/src/com/dre/brewery/Brew.java +++ b/src/com/dre/brewery/Brew.java @@ -7,6 +7,7 @@ import com.dre.brewery.lore.*; import com.dre.brewery.recipe.BEffect; import com.dre.brewery.recipe.BRecipe; import com.dre.brewery.recipe.PotionColor; +import com.dre.brewery.utility.BUtil; import org.bukkit.Material; import org.bukkit.configuration.ConfigurationSection; import org.bukkit.inventory.BrewerInventory; @@ -25,9 +26,12 @@ import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; +import java.util.Objects; -public class Brew { - // represents the liquid in the brewed Potions +/** + * Represents the liquid in the brewed Potions + */ +public class Brew implements Cloneable { public static final byte SAVE_VER = 1; private static long saveSeed; private static List prevSaveSeeds = new ArrayList<>(); // Save Seeds that have been used in the past, stored to decode brews made at that time @@ -47,12 +51,17 @@ public class Brew { private int lastUpdate; // last update in hours after install time private boolean needsSave; // There was a change that has not yet been saved + /** + * A new Brew with only ingredients + */ public Brew(BIngredients ingredients) { this.ingredients = ingredients; touch(); } - // quality already set + /** + * A Brew with quality, alc and recipe already set + */ public Brew(int quality, int alc, BRecipe recipe, BIngredients ingredients) { this.ingredients = ingredients; this.quality = quality; @@ -61,7 +70,9 @@ public class Brew { touch(); } - // loading with all values set + /** + * Loading a Brew with all values set + */ public Brew(BIngredients ingredients, int quality, int alc, byte distillRuns, float ageTime, float wood, String recipe, boolean unlabeled, boolean immutable, int lastUpdate) { this.ingredients = ingredients; this.quality = quality; @@ -79,7 +90,12 @@ public class Brew { private Brew() { } - // returns a Brew by ItemMeta + /** + * returns a Brew by ItemMeta + * + * @param meta The meta to get the brew from + * @return The Brew if meta is a brew, null if not + */ @Nullable public static Brew get(ItemMeta meta) { if (!P.useNBT && !meta.hasLore()) return null; @@ -93,7 +109,12 @@ public class Brew { return brew; } - // returns a Brew by ItemStack + /** + * returns a Brew by ItemStack + * + * @param item The Item to get the brew from + * @return The Brew if item is a brew, null if not + */ @Nullable public static Brew get(ItemStack item) { if (item.getType() != Material.POTION) return null; @@ -197,7 +218,9 @@ public class Brew { return uid; }*/ - //returns the recipe with the given name, recalculates if not found + /** + * returns the recipe with the given name, recalculates if not found + */ public boolean setRecipeFromString(String name) { currentRecipe = null; if (name != null && !name.equals("")) { @@ -256,20 +279,21 @@ public class Brew { persistent == brew.persistent && immutable == brew.immutable && ingredients.equals(brew.ingredients) && - (currentRecipe != null ? currentRecipe.equals(brew.currentRecipe) : brew.currentRecipe == null); + (Objects.equals(currentRecipe, brew.currentRecipe)); } - // Clones this instance + /** + * Clones this instance + */ @Override - public Brew clone() throws CloneNotSupportedException { - super.clone(); - Brew brew = new Brew(quality, alc, currentRecipe, ingredients); - brew.distillRuns = distillRuns; - brew.ageTime = ageTime; - brew.unlabeled = unlabeled; - brew.persistent = persistent; - brew.immutable = immutable; - return brew; + public Brew clone() { + try { + Brew brew = (Brew) super.clone(); + brew.ingredients = ingredients.copy(); + return brew; + } catch (CloneNotSupportedException e) { + throw new InternalError(e); + } } @Override @@ -295,7 +319,9 @@ public class Brew { } }*/ - // calculate alcohol from recipe + /** + * calculate alcohol from recipe + */ @Contract(pure = true) public int calcAlcohol() { if (quality == 0) { @@ -338,7 +364,9 @@ public class Brew { return 0; } - // calculating quality + /** + * calculating quality + */ @Contract(pure = true) public int calcQuality() { // calculate quality from all of the factors @@ -373,7 +401,11 @@ public class Brew { return null; } - // Set unlabeled to true to hide the numbers in Lore + /** + * Set unlabeled to true to hide the numbers in Lore + * + * @param item The Item this Brew is on + */ public void unLabel(ItemStack item) { unlabeled = true; ItemMeta meta = item.getItemMeta(); @@ -392,7 +424,9 @@ public class Brew { } } - // Do some regular updates + /** + * Do some regular updates + */ public void touch() { lastUpdate = (int) ((double) (System.currentTimeMillis() - installTime) / 3600000D); } @@ -470,7 +504,9 @@ public class Brew { this.needsSave = needsSave; } - // Set the Static flag, so potion is unchangeable + /** + * Set the Static flag, so potion is unchangeable + */ public void setStatic(boolean immutable, ItemStack potion) { this.immutable = immutable; if (currentRecipe != null && canDistill()) { @@ -488,7 +524,12 @@ public class Brew { // Distilling section --------------- - // distill all custom potions in the brewer + /** + * distill all custom potions in the brewer + * + * @param inv The Inventory of the Distiller + * @param contents The Brews in the 3 slots of the Inventory + */ public static void distillAll(BrewerInventory inv, Brew[] contents) { for (int slot = 0; slot < 3; slot++) { if (contents[slot] != null) { @@ -499,7 +540,12 @@ public class Brew { } } - // distill custom potion in given slot + /** + * distill custom potion in a distiller slot + * + * @param slotItem The item in the slot + * @param potionMeta The meta of the item + */ public void distillSlot(ItemStack slotItem, PotionMeta potionMeta) { if (immutable) return; @@ -626,7 +672,9 @@ public class Brew { item.setItemMeta(potionMeta); } - // Slowly shift the wood of the Brew to the new Type + /** + * Slowly shift the wood of the Brew to the new Type + */ public void woodShift(float time, byte to) { float factor = 1; if (ageTime > 5) { @@ -703,6 +751,35 @@ public class Brew { return potion; } + /** + * Performant way of checking if this item is a Brew + * Does not give any guarantees that get() will return notnull for this item, i.e. if it is a brew but the data is corrupt + * + * @param item The Item to check + * @return True if the item is a brew + */ + public static boolean isBrew(ItemStack item) { + if (item == null || item.getType() != Material.POTION) return false; + if (!item.hasItemMeta()) return false; + + ItemMeta meta = item.getItemMeta(); + assert meta != null; + if (!P.useNBT && !meta.hasLore()) return false; + + if (P.useNBT) { + // Check for Data on PersistentDataContainer + if (NBTLoadStream.hasDataInMeta(meta)) { + return true; + } + } + // If either NBT is not supported or no data was found in NBT, try finding data in lore + if (meta.hasLore()) { + // Find the Data Identifier in Lore + return BUtil.indexOfStart(meta.getLore(), LoreLoadStream.IDENTIFIER) > -1; + } + return false; + } + private static Brew load(ItemMeta meta) { InputStream itemLoadStream = null; if (P.useNBT) { @@ -795,7 +872,10 @@ public class Brew { setRecipeFromString(recipe); } - // Save brew data into meta: lore/nbt + /** + * Save brew data into meta: lore/nbt + * Should be called after any changes made to the brew + */ public void save(ItemMeta meta) { OutputStream itemSaveStream; if (P.useNBT) { @@ -819,8 +899,12 @@ public class Brew { } } - // Save brew data into the meta/lore of the specified item - // The meta on the item changes, so to make further changes to the meta, item.getItemMeta() has to be called again after this + /** + * Save brew data into the meta/lore of the specified item + * The meta on the item changes, so to make further changes to the meta, item.getItemMeta() has to be called again after this + * + * @param item The item to save this brew into + */ public void save(ItemStack item) { ItemMeta meta; if (!item.hasItemMeta()) { @@ -899,7 +983,9 @@ public class Brew { return legacyPotions.isEmpty(); } - // 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, int alc, byte distillRuns, float ageTime, float wood, String recipe, boolean unlabeled, boolean persistent, boolean stat, int lastUpdate) { Brew brew = new Brew(ingredients, quality, alc, distillRuns, ageTime, wood, recipe, unlabeled, stat, lastUpdate); brew.persistent = persistent; @@ -910,7 +996,9 @@ public class Brew { legacyPotions.put(uid, brew); } - // remove legacy potiondata for an item + /** + * remove legacy potiondata for an item + */ public static void removeLegacy(ItemStack item) { if (legacyPotions.isEmpty()) return; if (!item.hasItemMeta()) return; @@ -936,8 +1024,10 @@ public class Brew { item.setItemMeta(potionMeta); } - // Saves all data - // Legacy method to save to data file + /** + * Saves all data + * Legacy method to save to data file + */ public static void saveLegacy(ConfigurationSection config) { for (Map.Entry entry : legacyPotions.entrySet()) { int uid = entry.getKey(); diff --git a/src/com/dre/brewery/DistortChat.java b/src/com/dre/brewery/DistortChat.java index 9fb091e..362faab 100644 --- a/src/com/dre/brewery/DistortChat.java +++ b/src/com/dre/brewery/DistortChat.java @@ -1,5 +1,6 @@ package com.dre.brewery; +import com.dre.brewery.api.events.PlayerChatDistortEvent; import org.bukkit.event.block.SignChangeEvent; import org.bukkit.event.player.AsyncPlayerChatEvent; import org.bukkit.event.player.PlayerCommandPreprocessEvent; @@ -79,9 +80,15 @@ public class DistortChat { P.p.log(P.p.languageReader.get("Player_TriedToSay", name, chat)); } String message = chat.substring(command.length() + 1); - message = distortMessage(message, bPlayer.getDrunkeness()); + String distorted = distortMessage(message, bPlayer.getDrunkeness()); + PlayerChatDistortEvent call = new PlayerChatDistortEvent(event.isAsynchronous(), event.getPlayer(), bPlayer, message, distorted); + P.p.getServer().getPluginManager().callEvent(call); + if (call.isCancelled()) { + return; + } + distorted = call.getDistortedMessage(); - event.setMessage(chat.substring(0, command.length() + 1) + message); + event.setMessage(chat.substring(0, command.length() + 1) + distorted); waitPlayers.put(name, System.currentTimeMillis()); return; } @@ -101,12 +108,17 @@ public class DistortChat { int index = 0; for (String message : event.getLines()) { if (message.length() > 1) { - message = distortMessage(message, bPlayer.getDrunkeness()); + String distorted = distortMessage(message, bPlayer.getDrunkeness()); + PlayerChatDistortEvent call = new PlayerChatDistortEvent(event.isAsynchronous(), event.getPlayer(), bPlayer, message, distorted); + P.p.getServer().getPluginManager().callEvent(call); + if (!call.isCancelled()) { + distorted = call.getDistortedMessage(); - if (message.length() > 15) { - message = message.substring(0, 14); + if (distorted.length() > 15) { + distorted = distorted.substring(0, 14); + } + event.setLine(index, distorted); } - event.setLine(index, message); } index++; } @@ -123,7 +135,16 @@ public class DistortChat { if (log) { P.p.log(P.p.languageReader.get("Player_TriedToSay", event.getPlayer().getName(), message)); } - event.setMessage(distortMessage(message, bPlayer.getDrunkeness())); + + String distorted = distortMessage(message, bPlayer.getDrunkeness()); + PlayerChatDistortEvent call = new PlayerChatDistortEvent(event.isAsynchronous(), event.getPlayer(), bPlayer, message, distorted); + P.p.getServer().getPluginManager().callEvent(call); + if (call.isCancelled()) { + return; + } + distorted = call.getDistortedMessage(); + + event.setMessage(distorted); } } } diff --git a/src/com/dre/brewery/P.java b/src/com/dre/brewery/P.java index bd7c860..fd177b4 100644 --- a/src/com/dre/brewery/P.java +++ b/src/com/dre/brewery/P.java @@ -514,6 +514,10 @@ public class P extends JavaPlugin { BConfig.reloader = null; } + public P getInstance() { + return p; + } + // Utility public void msg(CommandSender sender, String msg) { diff --git a/src/com/dre/brewery/api/BreweryApi.java b/src/com/dre/brewery/api/BreweryApi.java index 4f8d229..5b256aa 100644 --- a/src/com/dre/brewery/api/BreweryApi.java +++ b/src/com/dre/brewery/api/BreweryApi.java @@ -1,10 +1,13 @@ package com.dre.brewery.api; import com.dre.brewery.BCauldron; +import com.dre.brewery.BPlayer; +import com.dre.brewery.filedata.BConfig; import com.dre.brewery.recipe.BCauldronRecipe; import com.dre.brewery.recipe.BRecipe; import com.dre.brewery.Barrel; import com.dre.brewery.Brew; +import com.dre.brewery.utility.Tuple; import org.apache.commons.lang.NotImplementedException; import org.bukkit.block.Block; import org.bukkit.entity.Player; @@ -28,7 +31,7 @@ public class BreweryApi { */ public static boolean removeAny(Block block) { if (removeCauldron(block)) return true; - return removeBarrel(block); + return removeBarrel(block, true); } /** @@ -37,7 +40,59 @@ public class BreweryApi { */ public static boolean removeAnyByPlayer(Block block, Player player) { if (removeCauldron(block)) return true; - return removeBarrelByPlayer(block, player); + return removeBarrelByPlayer(block, player, true); + } + + + // # # # # # # # # # # # # + // # # # # # Player # # # # # + // # # # # # # # # # # # # + + public static BPlayer getBPlayer(Player player) { + return BPlayer.get(player); + } + + /** + * Set the Players drunkeness state + * + * @param player The Player to set the drunkeness on + * @param drunkeness The amount of drunkeness 0-100 to apply to the player + * @param quality The Quality 1-10 the drunkeness of the player should have + * zero Quality keeps the players current quality + */ + public static void setPlayerDrunk(Player player, int drunkeness, int quality) { + if (drunkeness < 0) { + throw new IllegalArgumentException("Drunkeness can not be <0"); + } + if (quality > 10) { + throw new IllegalArgumentException("Quality can not be >10"); + } + BPlayer bPlayer = BPlayer.get(player); + if (bPlayer == null && player != null) { + if (drunkeness == 0) { + return; + } + bPlayer = BPlayer.addPlayer(player); + } + if (bPlayer == null) { + return; + } + + if (drunkeness == 0) { + bPlayer.remove(); + } else { + bPlayer.setData(drunkeness, quality); + } + + if (drunkeness > 100) { + if (player != null) { + bPlayer.drinkCap(player); + } else { + if (!BConfig.overdrinkKick) { + bPlayer.setData(100, 0); + } + } + } } @@ -67,6 +122,24 @@ public class BreweryApi { return Brew.get(meta); } + /** + * Performant way to check if an item is a brew. + * Does not give any guarantees that getBrew() will return notnull for this item, i.e. if it is a brew but couldn't be loaded + */ + public static boolean isBrew(ItemStack item) { + return Brew.isBrew(item); + } + + /** + * Create a Brew from the given Recipe + * + * @param recipe The Recipe to create a brew from + * @return The Brew that was created. Can use brew.createItem() to get an ItemStack + */ + public static Brew createBrew(BRecipe recipe, int quality) { + return recipe.createBrew(quality); + } + // # # # # # # # # # # # # // # # # # # Barrel # # # # # @@ -98,22 +171,29 @@ public class BreweryApi { /** * Remove any Barrel that this Block may be Part of - * Returns true if a Barrel was removed * Does not remove any actual Block + * + * @param block The Block thats part of the barrel, potions will drop there + * @param dropItems If the items in the barrels inventory should drop to the ground + * @return True if a Barrel was removed */ - public static boolean removeBarrel(Block block) { // TODO add dropItems flag - return removeBarrelByPlayer(block, null); + public static boolean removeBarrel(Block block, boolean dropItems) { + return removeBarrelByPlayer(block, null, dropItems); } /** * Remove any Barrel that this Block may be Part of, as if broken by the Player - * Returns true if a Barrel was removed * Does not remove any actual Block from the World + * + * @param block The Block thats part of the barrel, potions will drop there + * @param player The Player that broke the Block + * @param dropItems If the items in the barrels inventory should drop to the ground + * @return True if a Barrel was removed */ - public static boolean removeBarrelByPlayer(Block block, Player player) { + public static boolean removeBarrelByPlayer(Block block, Player player, boolean dropItems) { Barrel barrel = Barrel.get(block); if (barrel != null) { - barrel.remove(block, player); + barrel.remove(block, player, dropItems); return true; } return false; @@ -170,7 +250,7 @@ public class BreweryApi { public static void addRecipe(BRecipe recipe, boolean saveForever) { //recipe.setSaveInData(saveForever); if (saveForever) { - throw new NotImplementedException(); + throw new NotImplementedException("SaveForever is not implemented yet"); } BRecipe.getAddedRecipes().add(recipe); recipe.updateAcceptedLists(); diff --git a/src/com/dre/brewery/api/events/ConfigLoadEvent.java b/src/com/dre/brewery/api/events/ConfigLoadEvent.java index c3fec33..5af5893 100644 --- a/src/com/dre/brewery/api/events/ConfigLoadEvent.java +++ b/src/com/dre/brewery/api/events/ConfigLoadEvent.java @@ -9,6 +9,9 @@ import org.jetbrains.annotations.NotNull; import java.util.List; +/** + * The Brewery Config was reloaded + */ public class ConfigLoadEvent extends Event { private static final HandlerList handlers = new HandlerList(); @@ -39,4 +42,9 @@ public class ConfigLoadEvent extends Event { public HandlerList getHandlers() { return handlers; } + + // Required by Bukkit + public static HandlerList getHandlerList() { + return handlers; + } } diff --git a/src/com/dre/brewery/api/events/IngedientAddEvent.java b/src/com/dre/brewery/api/events/IngedientAddEvent.java index ecedda3..d576f51 100644 --- a/src/com/dre/brewery/api/events/IngedientAddEvent.java +++ b/src/com/dre/brewery/api/events/IngedientAddEvent.java @@ -11,8 +11,10 @@ import org.bukkit.event.Cancellable; import org.bukkit.event.HandlerList; import org.bukkit.event.player.PlayerEvent; import org.bukkit.inventory.ItemStack; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; -/* +/** * Player adding an ingredient to a cauldron * Always one item added at a time * If needed use the caudrons add method to manually add more Items @@ -51,36 +53,55 @@ public class IngedientAddEvent extends PlayerEvent implements Cancellable { return rItem; } - // Get the item currently being added to the cauldron by the player - // Can be changed directly (mutable) or with the setter Method - // The amount is ignored and always one added + /** + * Get the item currently being added to the cauldron by the player + * Can be changed directly (mutable) or with the setter Method + * The amount is ignored and always one added + * + * @return The item being added + */ public ItemStack getIngredient() { return ingredient; } - // Set the ingredient added to the cauldron to something else - // Will always be accepted, even when not in a recipe or the cooked list - // The amount is ignored and always one added - // This also recalculates the recipeItem! + /** + * Set the ingredient added to the cauldron to something else + * Will always be accepted, even when not in a recipe or the cooked lis + * The amount is ignored and always one added + * This also recalculates the recipeItem! + * + * @param ingredient The item to add instead + */ public void setIngredient(ItemStack ingredient) { this.ingredient = ingredient; // The Ingredient has been changed. Recalculate RecipeItem! rItem = RecipeItem.getMatchingRecipeItem(ingredient, true); } - // If the amount of the item in the players hand should be decreased - // Default true + /** + * If the amount of the item in the players hand should be decreased + * Default true + */ public boolean willTakeItem() { return takeItem; } - // Set if the amount of the item in the players hand should be decreased + /** + * Set if the amount of the item in the players hand should be decreased + * + * @param takeItem if the item amount in the hand should be decreased + */ public void setTakeItem(boolean takeItem) { this.takeItem = takeItem; } - // Get the BlockData of the Cauldron - // May be null if the Cauldron does not exist anymore + /** + * Get the BlockData of the Cauldron + * May be null if the Cauldron does not exist anymore + * + * @return The BlockData of the cauldron + */ + @Nullable public Levelled getCauldronData() { BlockData data = block.getBlockData(); if (data instanceof Levelled) { @@ -89,9 +110,13 @@ public class IngedientAddEvent extends PlayerEvent implements Cancellable { return null; } - // Get the Water Fill level of the Cauldron - // 0 = empty, 1 = something in, 2 = full - // Can use BCauldron.EMPTY, BCauldron.SOME, BCauldron.FULL + /** + * Get the water fill level of the Cauldron + * 0 = empty, 1 = something in, 2 = full + * Can use BCauldron.EMPTY, BCauldron.SOME, BCauldron.FULL + * + * @return The fill level as a byte 0-2 + */ public byte getFillLevel() { return LegacyUtil.getFillLevel(block); } @@ -101,16 +126,21 @@ public class IngedientAddEvent extends PlayerEvent implements Cancellable { return cancelled; } + /** + * If the event is cancelled, no item will be added or taken from the player + */ @Override public void setCancelled(boolean cancelled) { this.cancelled = cancelled; } + @NotNull @Override public HandlerList getHandlers() { return handlers; } + // Required by Bukkit public static HandlerList getHandlerList() { return handlers; } diff --git a/src/com/dre/brewery/api/events/PlayerAlcEffectEvent.java b/src/com/dre/brewery/api/events/PlayerAlcEffectEvent.java deleted file mode 100644 index 7d371e2..0000000 --- a/src/com/dre/brewery/api/events/PlayerAlcEffectEvent.java +++ /dev/null @@ -1,54 +0,0 @@ -package com.dre.brewery.api.events; - -import org.bukkit.entity.Player; -import org.bukkit.event.Cancellable; -import org.bukkit.event.HandlerList; -import org.bukkit.event.player.PlayerEvent; -import org.bukkit.potion.PotionEffect; - -import java.util.List; - -/* - * Called when the Alcohol in the Player demands its toll - * These effects are applied regularly to the Player depending on his alcohol level - * By default it is just one Confusion effect - * Can be changed or cancelled - */ -public class PlayerAlcEffectEvent extends PlayerEvent implements Cancellable { - private static final HandlerList handlers = new HandlerList(); - private List effects; - private boolean cancelled; - - public PlayerAlcEffectEvent(Player who, List effects) { - super(who); - this.effects = effects; - } - - public List getEffects() { - return effects; - } - - public void setEffects(List effects) { - this.effects = effects; - } - - @Override - public boolean isCancelled() { - return cancelled; - } - - @Override - public void setCancelled(boolean cancelled) { - this.cancelled = cancelled; - } - - @Override - public HandlerList getHandlers() { - return handlers; - } - - public static HandlerList getHandlerList() { - return handlers; - } - -} diff --git a/src/com/dre/brewery/api/events/PlayerChatDistortEvent.java b/src/com/dre/brewery/api/events/PlayerChatDistortEvent.java new file mode 100644 index 0000000..107ad10 --- /dev/null +++ b/src/com/dre/brewery/api/events/PlayerChatDistortEvent.java @@ -0,0 +1,95 @@ +package com.dre.brewery.api.events; + +import com.dre.brewery.BPlayer; +import org.bukkit.entity.Player; +import org.bukkit.event.Cancellable; +import org.bukkit.event.Event; +import org.bukkit.event.HandlerList; +import org.bukkit.event.player.PlayerEvent; +import org.jetbrains.annotations.NotNull; + +import java.util.Objects; + +/** + * The Player writes something in Chat or on a Sign and his words are distorted. + * + * This Event may be Async if the Chat Event is Async! + */ +public class PlayerChatDistortEvent extends Event implements Cancellable { + private static final HandlerList handlers = new HandlerList(); + + private final Player player; + private final BPlayer bPlayer; + private final String prevMsg; + private String distortMsg; + private boolean cancelled; + + public PlayerChatDistortEvent(boolean async, Player player, BPlayer bPlayer, String prevMsg, String distortMsg) { + super(async); + this.player = player; + this.bPlayer = bPlayer; + this.prevMsg = prevMsg; + this.distortMsg = distortMsg; + } + + @NotNull + public Player getPlayer() { + return player; + } + + @NotNull + public BPlayer getbPlayer() { + return bPlayer; + } + + /** + * @return The Message the Player had actually written + */ + @NotNull + public String getWrittenMessage() { + return prevMsg; + } + + /** + * @return The message after it was distorted + */ + @NotNull + public String getDistortedMessage() { + return distortMsg; + } + + /** + * @return The drunkeness of the player that is writing the message + */ + public int getDrunkeness() { + return bPlayer.getDrunkeness(); + } + + /** + * Set the Message that the player will say instead of what he wrote + */ + public void setDistortedMessage(String distortMsg) { + this.distortMsg = Objects.requireNonNull(distortMsg); + } + + @Override + public boolean isCancelled() { + return cancelled; + } + + @Override + public void setCancelled(boolean cancelled) { + this.cancelled = cancelled; + } + + @NotNull + @Override + public HandlerList getHandlers() { + return handlers; + } + + // Required by Bukkit + public static HandlerList getHandlerList() { + return handlers; + } +} diff --git a/src/com/dre/brewery/api/events/PlayerDrinkEffectEvent.java b/src/com/dre/brewery/api/events/PlayerDrinkEffectEvent.java deleted file mode 100644 index 6b19e1f..0000000 --- a/src/com/dre/brewery/api/events/PlayerDrinkEffectEvent.java +++ /dev/null @@ -1,52 +0,0 @@ -package com.dre.brewery.api.events; - -import org.bukkit.entity.Player; -import org.bukkit.event.Cancellable; -import org.bukkit.event.HandlerList; -import org.bukkit.event.player.PlayerEvent; -import org.bukkit.potion.PotionEffect; - -import java.util.List; - -/* - * Called when the Effects of a Brew are applied to the player (drinking the Brew) - * These depend on alcohol and quality of the brew - * Can be changed or cancelled - */ -public class PlayerDrinkEffectEvent extends PlayerEvent implements Cancellable { - private static final HandlerList handlers = new HandlerList(); - private List effects; - private boolean cancelled; - - public PlayerDrinkEffectEvent(Player who, List effects) { - super(who); - this.effects = effects; - } - - public List getEffects() { - return effects; - } - - public void setEffects(List effects) { - this.effects = effects; - } - - @Override - public boolean isCancelled() { - return cancelled; - } - - @Override - public void setCancelled(boolean cancelled) { - this.cancelled = cancelled; - } - - @Override - public HandlerList getHandlers() { - return handlers; - } - - public static HandlerList getHandlerList() { - return handlers; - } -} diff --git a/src/com/dre/brewery/api/events/PlayerEffectEvent.java b/src/com/dre/brewery/api/events/PlayerEffectEvent.java new file mode 100644 index 0000000..b980b8b --- /dev/null +++ b/src/com/dre/brewery/api/events/PlayerEffectEvent.java @@ -0,0 +1,94 @@ +package com.dre.brewery.api.events; + +import org.bukkit.entity.Player; +import org.bukkit.event.Cancellable; +import org.bukkit.event.HandlerList; +import org.bukkit.event.player.PlayerEvent; +import org.bukkit.potion.PotionEffect; +import org.jetbrains.annotations.NotNull; + +import java.util.List; + +/** + * A List of effects is applied to the player. + * This happens for various reasons like Alcohol level, Brew quality, Brew effects, etc. + * Can be changed or cancelled + */ +public class PlayerEffectEvent extends PlayerEvent implements Cancellable { + private static final HandlerList handlers = new HandlerList(); + private final EffectType effectType; + private List effects; + private boolean cancelled; + + public PlayerEffectEvent(Player who, EffectType effectType, List effects) { + super(who); + this.effectType = effectType; + this.effects = effects; + } + + /** + * @return The effects being applied. Effects can be added or removed from this list. + */ + public List getEffects() { + return effects; + } + + public void setEffects(List effects) { + this.effects = effects; + } + + /** + * @return What type of effects are applied, sie EffectType + */ + public EffectType getEffectType() { + return effectType; + } + + @Override + public boolean isCancelled() { + return cancelled; + } + + @Override + public void setCancelled(boolean cancelled) { + this.cancelled = cancelled; + } + + @NotNull + @Override + public HandlerList getHandlers() { + return handlers; + } + + // Required by Bukkit + public static HandlerList getHandlerList() { + return handlers; + } + + + public enum EffectType { + /** + * The Alcohol level demands its toll. + * Regularly applied depending on the players alcohol level + * By default it is just one Confusion effect + */ + ALCOHOL, + + /** + * Effects of a Brew are applied to the player (drinking the Brew) + * These depend on alcohol and quality of the brew + */ + DRINK, + + /** + * When drinking a Brew with low Quality, these effects are applied + */ + QUALITY, + + /** + * When logging in after drinking, Hangover Effects are applied + */ + HANGOVER + + } +} diff --git a/src/com/dre/brewery/api/events/PlayerPukeEvent.java b/src/com/dre/brewery/api/events/PlayerPukeEvent.java index 4a0e001..d4b8da6 100644 --- a/src/com/dre/brewery/api/events/PlayerPukeEvent.java +++ b/src/com/dre/brewery/api/events/PlayerPukeEvent.java @@ -5,8 +5,9 @@ import org.bukkit.entity.Player; import org.bukkit.event.Cancellable; import org.bukkit.event.HandlerList; import org.bukkit.event.player.PlayerEvent; +import org.jetbrains.annotations.NotNull; -/* +/** * The player pukes (throws puke items to the ground) * Those items can never be picked up and despawn after the time set in the config * Number of items to drop can be changed with count @@ -23,10 +24,16 @@ public class PlayerPukeEvent extends PlayerEvent implements Cancellable { this.count = count; } + /** + * @return The Amount of items being dropped this time + */ public int getCount() { return count; } + /** + * @param count Set the amount of items being dropped this time + */ public void setCount(int count) { this.count = count; } @@ -48,11 +55,13 @@ public class PlayerPukeEvent extends PlayerEvent implements Cancellable { this.cancelled = cancelled; } + @NotNull @Override public HandlerList getHandlers() { return handlers; } + // Required by Bukkit public static HandlerList getHandlerList() { return handlers; } diff --git a/src/com/dre/brewery/api/events/PlayerPushEvent.java b/src/com/dre/brewery/api/events/PlayerPushEvent.java index 10f286b..f7406bd 100644 --- a/src/com/dre/brewery/api/events/PlayerPushEvent.java +++ b/src/com/dre/brewery/api/events/PlayerPushEvent.java @@ -6,8 +6,9 @@ import org.bukkit.event.Cancellable; import org.bukkit.event.HandlerList; import org.bukkit.event.player.PlayerEvent; import org.bukkit.util.Vector; +import org.jetbrains.annotations.NotNull; -/* +/** * The Players movement is hindered because of drunkeness * Called each time before pushing the Player with the Vector push 10 times * The Push Vector can be changed or multiplied @@ -30,12 +31,23 @@ public class PlayerPushEvent extends PlayerEvent implements Cancellable { // The Vector in which direction and magnitude the player is Pushed // Can be changed directly or through setPush + + /** + * Get the Vector in which direction and magnitude the player is pushed + * Can be changed directly or through setPush + * + * @return The current push vector + */ public Vector getPush() { return push; } - // Set the Push vector, can not be null - public void setPush(Vector push) { + /** + * Set the Push vector + * + * @param push The new push vector, not null + */ + public void setPush(@NotNull Vector push) { if (push == null) { throw new NullPointerException("Push Vector is null"); } @@ -52,11 +64,13 @@ public class PlayerPushEvent extends PlayerEvent implements Cancellable { this.cancelled = cancelled; } + @NotNull @Override public HandlerList getHandlers() { return handlers; } + // Required by Bukkit public static HandlerList getHandlerList() { return handlers; } diff --git a/src/com/dre/brewery/api/events/barrel/BarrelAccessEvent.java b/src/com/dre/brewery/api/events/barrel/BarrelAccessEvent.java index 2911ad2..256da96 100644 --- a/src/com/dre/brewery/api/events/barrel/BarrelAccessEvent.java +++ b/src/com/dre/brewery/api/events/barrel/BarrelAccessEvent.java @@ -5,8 +5,9 @@ import org.bukkit.block.Block; import org.bukkit.entity.Player; import org.bukkit.event.Cancellable; import org.bukkit.event.HandlerList; +import org.jetbrains.annotations.NotNull; -/* +/** * A Player opens a Barrel by rightclicking it * The PlayerInteractEvent on the Barrel may be cancelled. In that case this never gets called * Can be cancelled to silently deny opening the Barrel @@ -23,8 +24,10 @@ public class BarrelAccessEvent extends BarrelEvent implements Cancellable { this.clickedBlock = clickedBlock; } - // Gets the Block that was actually clicked. - // For access Permissions getSpigot() should be used + /** + * Gets the Block that was actually clicked. + * For access Permissions getSpigot() should be used + */ public Block getClickedBlock() { return clickedBlock; } @@ -43,11 +46,13 @@ public class BarrelAccessEvent extends BarrelEvent implements Cancellable { return player; } + @NotNull @Override public HandlerList getHandlers() { return handlers; } + // Required by Bukkit public static HandlerList getHandlerList() { return handlers; } diff --git a/src/com/dre/brewery/api/events/barrel/BarrelCreateEvent.java b/src/com/dre/brewery/api/events/barrel/BarrelCreateEvent.java index 560d199..81be00d 100644 --- a/src/com/dre/brewery/api/events/barrel/BarrelCreateEvent.java +++ b/src/com/dre/brewery/api/events/barrel/BarrelCreateEvent.java @@ -4,8 +4,9 @@ import com.dre.brewery.Barrel; import org.bukkit.entity.Player; import org.bukkit.event.Cancellable; import org.bukkit.event.HandlerList; +import org.jetbrains.annotations.NotNull; -/* +/** * Called when a Barrel is created by a Player by placing a Sign * Cancelling this will silently fail the Barrel creation */ @@ -33,11 +34,13 @@ public class BarrelCreateEvent extends BarrelEvent implements Cancellable { this.cancelled = cancelled; } + @NotNull @Override public HandlerList getHandlers() { return handlers; } + // Required by Bukkit public static HandlerList getHandlerList() { return handlers; } diff --git a/src/com/dre/brewery/api/events/barrel/BarrelDestroyEvent.java b/src/com/dre/brewery/api/events/barrel/BarrelDestroyEvent.java index 53b0f94..6ec802d 100644 --- a/src/com/dre/brewery/api/events/barrel/BarrelDestroyEvent.java +++ b/src/com/dre/brewery/api/events/barrel/BarrelDestroyEvent.java @@ -5,11 +5,14 @@ import org.bukkit.block.Block; import org.bukkit.entity.Player; import org.bukkit.event.Cancellable; import org.bukkit.event.HandlerList; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; -/* +/** * A Barrel is being destroyed by something, may not be by a Player * A BarrelRemoveEvent will be called after this, if this is not cancelled * Use the BarrelRemoveEvent to monitor any and all barrels being removed in a non cancellable way + * Cancelling the Event will stop the barrel from being destroyed */ public class BarrelDestroyEvent extends BarrelEvent implements Cancellable { private static final HandlerList handlers = new HandlerList(); @@ -30,42 +33,79 @@ public class BarrelDestroyEvent extends BarrelEvent implements Cancellable { return cancelled; } + /** + * Cancelling the Event will stop the barrel from being destroyed. + * Any Blocks that are part of the barrel will not be destroyed + */ @Override public void setCancelled(boolean cancelled) { this.cancelled = cancelled; } + /** + * @return The Block of the Barrel that was broken + */ public Block getBroken() { return broken; } + /** + * @return The Reason of destruction of this barrel, see Reason + */ public Reason getReason() { return reason; } + /** + * If a Player was recorded destroying the barrel + */ public boolean hasPlayer() { return player != null; } - // MAY BE NULL if no Player is involved + /** + * @return The Player, Null if no Player is involved + */ + @Nullable public Player getPlayerOptional() { return player; } + @NotNull @Override public HandlerList getHandlers() { return handlers; } + // Required by Bukkit public static HandlerList getHandlerList() { return handlers; } public enum Reason { - PLAYER, // A Player Broke the Barrel - BROKEN, // A Block was broken by something - BURNED, // A Block burned away - EXPLODED, // The Barrel exploded somehow - UNKNOWN // The Barrel was broken somehow else + /** + * A Player Broke the Barrel + */ + PLAYER, + + /** + * A Block was broken by something + */ + BROKEN, + + /** + * A Block burned away + */ + BURNED, + + /** + * The Barrel exploded somehow + */ + EXPLODED, + + /** + * The Barrel was broken somehow else + */ + UNKNOWN } } diff --git a/src/com/dre/brewery/api/events/barrel/BarrelEvent.java b/src/com/dre/brewery/api/events/barrel/BarrelEvent.java index 2195274..871b085 100644 --- a/src/com/dre/brewery/api/events/barrel/BarrelEvent.java +++ b/src/com/dre/brewery/api/events/barrel/BarrelEvent.java @@ -3,7 +3,6 @@ package com.dre.brewery.api.events.barrel; import com.dre.brewery.Barrel; import org.bukkit.block.Block; import org.bukkit.event.Event; -import org.bukkit.event.HandlerList; import org.bukkit.inventory.Inventory; public abstract class BarrelEvent extends Event { @@ -21,6 +20,9 @@ public abstract class BarrelEvent extends Event { return barrel.getInventory(); } + /** + * @return The Spigot Block of the Barrel, usually Sign or a Fence + */ public Block getSpigot() { return barrel.getSpigot(); } diff --git a/src/com/dre/brewery/api/events/barrel/BarrelRemoveEvent.java b/src/com/dre/brewery/api/events/barrel/BarrelRemoveEvent.java index b846e6b..d2b0f84 100644 --- a/src/com/dre/brewery/api/events/barrel/BarrelRemoveEvent.java +++ b/src/com/dre/brewery/api/events/barrel/BarrelRemoveEvent.java @@ -2,32 +2,39 @@ package com.dre.brewery.api.events.barrel; import com.dre.brewery.Barrel; import org.bukkit.event.HandlerList; +import org.jetbrains.annotations.NotNull; -/* - * A Barrel is being removed. There may have been a BarrelDestroyEvent before +/** + * A Barrel is being removed. There may have been a BarrelDestroyEvent before this * If not, Worldedit, other Plugins etc may be the cause for unexpected removal */ public class BarrelRemoveEvent extends BarrelEvent { private static final HandlerList handlers = new HandlerList(); - private boolean itemsDrop = true; + private boolean dropItems; - public BarrelRemoveEvent(Barrel barrel) { + public BarrelRemoveEvent(Barrel barrel, boolean dropItems) { super(barrel); + this.dropItems = dropItems; } - public boolean willItemsDrop() { - return itemsDrop; + public boolean willDropItems() { + return dropItems; } - public void setShouldItemsDrop(boolean itemsDrop) { - this.itemsDrop = itemsDrop; + /** + * @param dropItems Should the Items contained in this Barrel drop to the ground? + */ + public void setShouldDropItems(boolean dropItems) { + this.dropItems = dropItems; } + @NotNull @Override public HandlerList getHandlers() { return handlers; } + // Required by Bukkit public static HandlerList getHandlerList() { return handlers; } diff --git a/src/com/dre/brewery/api/events/brew/BrewDrinkEvent.java b/src/com/dre/brewery/api/events/brew/BrewDrinkEvent.java index de6b7f1..56a6f8b 100644 --- a/src/com/dre/brewery/api/events/brew/BrewDrinkEvent.java +++ b/src/com/dre/brewery/api/events/brew/BrewDrinkEvent.java @@ -6,8 +6,9 @@ import org.bukkit.entity.Player; import org.bukkit.event.Cancellable; import org.bukkit.event.HandlerList; import org.bukkit.inventory.meta.ItemMeta; +import org.jetbrains.annotations.NotNull; -/* +/** * A Player Drinks a Brew * The amount of alcohol and quality that will be added to the player can be get/set here * If cancelled the drinking will fail silently @@ -65,11 +66,13 @@ public class BrewDrinkEvent extends BrewEvent implements Cancellable { this.cancelled = cancelled; } + @NotNull @Override public HandlerList getHandlers() { return handlers; } + // Required by Bukkit public static HandlerList getHandlerList() { return handlers; } diff --git a/src/com/dre/brewery/api/events/brew/BrewModifyEvent.java b/src/com/dre/brewery/api/events/brew/BrewModifyEvent.java index 12c3c07..5a21187 100644 --- a/src/com/dre/brewery/api/events/brew/BrewModifyEvent.java +++ b/src/com/dre/brewery/api/events/brew/BrewModifyEvent.java @@ -8,7 +8,7 @@ import org.bukkit.inventory.meta.ItemMeta; import org.bukkit.inventory.meta.PotionMeta; import org.jetbrains.annotations.NotNull; -/* +/** * A Brew has been created or modified * Usually happens on Filling from cauldron, distilling and aging. * Modifications to the Brew or the PotionMeta can be done now @@ -40,7 +40,7 @@ public class BrewModifyEvent extends BrewEvent implements Cancellable { return cancelled; } - /* + /** * Setting the Event cancelled cancels all modificatons to the brew. * Modifications to the Brew or ItemMeta will not be applied */ @@ -55,6 +55,7 @@ public class BrewModifyEvent extends BrewEvent implements Cancellable { return handlers; } + // Required by Bukkit public static HandlerList getHandlerList() { return handlers; } diff --git a/src/com/dre/brewery/listeners/BlockListener.java b/src/com/dre/brewery/listeners/BlockListener.java index 8f1a6df..37a5a4a 100644 --- a/src/com/dre/brewery/listeners/BlockListener.java +++ b/src/com/dre/brewery/listeners/BlockListener.java @@ -53,7 +53,9 @@ public class BlockListener implements Listener { @EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true) public void onBlockBurn(BlockBurnEvent event) { - BUtil.blockDestroy(event.getBlock(), null, BarrelDestroyEvent.Reason.BURNED); + if (!BUtil.blockDestroy(event.getBlock(), null, BarrelDestroyEvent.Reason.BURNED)) { + event.setCancelled(true); + } } @EventHandler(priority = EventPriority.HIGH, ignoreCancelled = true) diff --git a/src/com/dre/brewery/listeners/EntityListener.java b/src/com/dre/brewery/listeners/EntityListener.java index ff1c3cb..6fd00b9 100644 --- a/src/com/dre/brewery/listeners/EntityListener.java +++ b/src/com/dre/brewery/listeners/EntityListener.java @@ -24,7 +24,7 @@ import java.util.ListIterator; public class EntityListener implements Listener { - // Remove the Potion from Brew when it despawns + // Legacy Brew removal @EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true) public void onItemDespawn(ItemDespawnEvent event) { if (Brew.noLegacy()) return; @@ -77,7 +77,7 @@ public class EntityListener implements Listener { if (breakEvent.isCancelled()) { iter.remove(); } else { - barrel.remove(block, null); + barrel.remove(block, null, true); } } } diff --git a/src/com/dre/brewery/listeners/InventoryListener.java b/src/com/dre/brewery/listeners/InventoryListener.java index 5fd6622..f3f33a5 100644 --- a/src/com/dre/brewery/listeners/InventoryListener.java +++ b/src/com/dre/brewery/listeners/InventoryListener.java @@ -1,6 +1,10 @@ package com.dre.brewery.listeners; -import com.dre.brewery.*; +import com.dre.brewery.BDistiller; +import com.dre.brewery.Barrel; +import com.dre.brewery.Brew; +import com.dre.brewery.MCBarrel; +import com.dre.brewery.P; import com.dre.brewery.filedata.BConfig; import com.dre.brewery.lore.BrewLore; import org.bukkit.Material; diff --git a/src/com/dre/brewery/lore/NBTLoadStream.java b/src/com/dre/brewery/lore/NBTLoadStream.java index 36eea63..46dccd0 100644 --- a/src/com/dre/brewery/lore/NBTLoadStream.java +++ b/src/com/dre/brewery/lore/NBTLoadStream.java @@ -9,13 +9,14 @@ import java.io.ByteArrayInputStream; public class NBTLoadStream extends ByteArrayInputStream { private static final String TAG = "brewdata"; + private static final NamespacedKey KEY = new NamespacedKey(P.p, TAG); public NBTLoadStream(ItemMeta meta) { super(getNBTBytes(meta)); } private static byte[] getNBTBytes(ItemMeta meta) { - byte[] bytes = LegacyUtil.readBytesItem(meta, new NamespacedKey(P.p, TAG)); + byte[] bytes = LegacyUtil.readBytesItem(meta, KEY); if (bytes == null) { return new byte[0]; } @@ -25,4 +26,8 @@ public class NBTLoadStream extends ByteArrayInputStream { public boolean hasData() { return count > 0; } + + public static boolean hasDataInMeta(ItemMeta meta) { + return LegacyUtil.hasBytesItem(meta, KEY); + } } diff --git a/src/com/dre/brewery/lore/NBTSaveStream.java b/src/com/dre/brewery/lore/NBTSaveStream.java index 4cfd5a5..457018d 100644 --- a/src/com/dre/brewery/lore/NBTSaveStream.java +++ b/src/com/dre/brewery/lore/NBTSaveStream.java @@ -10,6 +10,8 @@ import java.io.IOException; public class NBTSaveStream extends ByteArrayOutputStream { private static final String TAG = "brewdata"; + private static final NamespacedKey KEY = new NamespacedKey(P.p, TAG); + private final ItemMeta meta; public NBTSaveStream(ItemMeta meta) { @@ -21,6 +23,6 @@ public class NBTSaveStream extends ByteArrayOutputStream { public void flush() throws IOException { super.flush(); if (size() <= 0) return; - LegacyUtil.writeBytesItem(toByteArray(), meta, new NamespacedKey(P.p, TAG)); + LegacyUtil.writeBytesItem(toByteArray(), meta, KEY); } } diff --git a/src/com/dre/brewery/utility/BUtil.java b/src/com/dre/brewery/utility/BUtil.java index 50edb94..8ba4ee5 100644 --- a/src/com/dre/brewery/utility/BUtil.java +++ b/src/com/dre/brewery/utility/BUtil.java @@ -169,7 +169,7 @@ public class BUtil { Barrel barrel = Barrel.getBySpigot(block); if (barrel != null) { if (barrel.hasPermsDestroy(player, block, reason)) { - barrel.remove(null, player); + barrel.remove(null, player, true); return true; } else { return false; @@ -183,7 +183,7 @@ public class BUtil { if (barrel2 != null) { if (!barrel2.isLarge()) { if (barrel2.hasPermsDestroy(player, block, reason)) { - barrel2.remove(null, player); + barrel2.remove(null, player, true); return true; } else { return false; @@ -198,7 +198,7 @@ public class BUtil { Barrel barrel3 = Barrel.getByWood(block); if (barrel3 != null) { if (barrel3.hasPermsDestroy(player, block, reason)) { - barrel3.remove(block, player); + barrel3.remove(block, player, true); } else { return false; } diff --git a/src/com/dre/brewery/utility/LegacyUtil.java b/src/com/dre/brewery/utility/LegacyUtil.java index 8e3c862..f19aa93 100644 --- a/src/com/dre/brewery/utility/LegacyUtil.java +++ b/src/com/dre/brewery/utility/LegacyUtil.java @@ -291,4 +291,13 @@ public class LegacyUtil { } } + @SuppressWarnings("deprecation") + public static boolean hasBytesItem(ItemMeta meta, NamespacedKey key) { + if (NewNbtVer) { + return meta.getPersistentDataContainer().has(key, org.bukkit.persistence.PersistentDataType.BYTE_ARRAY); + } else { + return meta.getCustomTagContainer().hasCustomTag(key, org.bukkit.inventory.meta.tags.ItemTagType.BYTE_ARRAY); + } + } + } From f483f03560b65d088343718b496b6e17d387786b Mon Sep 17 00:00:00 2001 From: Sn0wStorm Date: Thu, 14 Nov 2019 15:46:15 +0100 Subject: [PATCH 36/51] Handle Hoppers for Distillers and MCBarrels Removed most mentions of Persistent --- resources/languages/de.yml | 6 -- resources/languages/en.yml | 6 -- resources/languages/fr.yml | 6 -- resources/languages/it.yml | 6 -- resources/languages/tw.yml | 6 -- resources/languages/zh.yml | 6 -- resources/plugin.yml | 3 - src/com/dre/brewery/BDistiller.java | 4 + src/com/dre/brewery/Brew.java | 22 ----- src/com/dre/brewery/MCBarrel.java | 22 ++--- .../dre/brewery/filedata/LanguageReader.java | 6 -- .../brewery/listeners/CommandListener.java | 96 ++++--------------- .../brewery/listeners/InventoryListener.java | 38 +++++++- 13 files changed, 65 insertions(+), 162 deletions(-) diff --git a/resources/languages/de.yml b/resources/languages/de.yml index 565791a..00dee9c 100644 --- a/resources/languages/de.yml +++ b/resources/languages/de.yml @@ -26,10 +26,6 @@ CMD_Reload: '&aConfig wurde neu eingelesen' CMD_Configname: '&aName für Config ist: &f&v1' CMD_Configname_Error: '&cDu hast kein Item in der Hand' CMD_UnLabel: '&aDas Label wurde entfernt' -CMD_Persistent: '&aTrankdaten sind nun permanent und unveränderlich und so kann der Trank nun wie jedes andere Item kopiert werden' -CMD_PersistRemove: '&cPermanente Tränke können nicht aus der Datenbank gelöscht werden, evtl. Kopien würden sonst unbrauchbar werden!' -CMD_UnPersist: '&aTrankdaten nicht mehr permanent und unveränderlich. &ePotentielle Kopien dieses Trankes, die nicht mit "/brew copy" gemacht wurden, könnten nun unbrauchbar werden!' -CMD_CopyNotPersistent: '&eDiese Kopien dieses Trankes werden nicht die permanenten und unveränderlichen Trankdaten haben!' CMD_Static: '&aTrank ist nun unveränderlich und kann nicht weiter gereift oder destilliert werden.' CMD_NonStatic: '&eTrank ist wieder veränderlich und kann normal gereift oder destilliert werden' @@ -41,7 +37,6 @@ Error_Recipeload: '&cEs konnten nicht alle Rezepte wiederhergesellt werden: Sieh Error_ShowHelp: 'Benutze &6/brew help &fum die Hilfe anzuzeigen' Error_UnknownCommand: Unbekannter Befehl Error_ConfigUpdate: 'Unbekannte Brewery Config Version: v&v1, Config wurde nicht geupdated!' -Error_PersistStatic: '&cTränke mit permanenten Trankdaten sind immer unveränderlich!' # Permission Error_NoPermissions: '&cDu hast keine Rechte dies zu tun!' @@ -73,7 +68,6 @@ Help_WakeupCheck: '&6/brew Wakeup Check &9Teleportiert zu allen Aufwachpunkten' Help_WakeupCheckSpecific: '&6/brew Wakeup Check &9Teleportiert zu einem Aufwachpunkt' Help_WakeupList: '&6/brew Wakeup List [Welt]&9 Listet die Aufwachpunkte einer Welt auf' Help_WakeupRemove: '&6/brew Wakeup Remove &9Entfernt einen Aufwachpunkt' -Help_Persist: '&6/brew Persist &9Trankdaten permanent machen -> Kopierbar durch andere Plugins' Help_Static: '&6/brew Static &9Trank unveränderlich machen -> Kein weiteres reifen oder destillieren möglich' Help_Create: '&6/brew Create [Qualität] [Spieler] &9Erstellt einen Trank mit optionaler Qualität (1-10)' diff --git a/resources/languages/en.yml b/resources/languages/en.yml index 9fa105c..ae8d8bb 100644 --- a/resources/languages/en.yml +++ b/resources/languages/en.yml @@ -17,13 +17,10 @@ Brew_minute: minute Brew_Alc: Alc &v1ml # CMD -CMD_CopyNotPersistent: '&eThese copies of this Brew will not be persistent or static!' CMD_Copy_Error: '&6&v1 &cPotions did not fit into your inventory' CMD_Info_Drunk: '&v1 is &6&v2% &fdrunk, with a quality of &6&v3' CMD_Info_NotDrunk: '&v1 is not drunk' CMD_NonStatic: '&ePotion is not static anymore and will normally age in barrels.' -CMD_PersistRemove: '&cPersistent Brews cannot be removed from the Database. It would render any copies of them useless!' -CMD_Persistent: '&aPotion is now Persistent and Static and may now be copied like any other item. You can remove the persistence with the same command.' CMD_Player: '&a&v1 is now &6&v2% &adrunk, with a quality of &6&v3' CMD_Player_Error: '&cThe quality has to be between 1 and 10!' CMD_Reload: '&aConfig was successfully reloaded' @@ -31,7 +28,6 @@ CMD_Configname: '&aName for the Config is: &f&v1' CMD_Configname_Error: '&cCould not find item in your hand' CMD_Static: '&aPotion is now static and will not change in barrels or brewing stands.' CMD_UnLabel: '&aLabel removed!' -CMD_UnPersist: '&aPersistence and static Removed. &eEvery Potential copy NOT made with ''/brew copy'' could become useless now!' # Error Error_ConfigUpdate: 'Unknown Brewery config version: v&v1, config was not updated!' @@ -39,7 +35,6 @@ Error_ItemNotPotion: '&cThe item in your hand could not be identified as a potio Error_NoBarrelAccess: '&cYou don''t have permissions to access this barrel!' Error_NoBrewName: '&cNo Recipe with Name: ''&v1&c'' found!' Error_NoPermissions: '&cYou don''t have permissions to do this!' -Error_PersistStatic: '&cPersistent potions are always static!' Error_PlayerCommand: '&cThis command can only be executed as a player!' Error_Recipeload: '&cNot all recipes could be restored: More information in the server log!' Error_ShowHelp: Use &6/brew help &fto display the help @@ -57,7 +52,6 @@ Help_Delete: '&6/brew delete &9Deletes the potion in your hand' Help_Help: '&6/brew help [Page] &9Shows a specific help-page' Help_Info: '&6/brew info&9 Displays your current Drunkeness and Quality' Help_InfoOther: '&6/brew info [Player]&9 Displays the current Drunkeness and Quality of [Player]' -Help_Persist: '&6/brew persist &9Make Brew persistent -> copyable by any plugin and technique' Help_Player: '&6/brew <%Drunkeness> [Quality]&9 Sets Drunkeness (and Quality) of a Player' Help_Reload: '&6/brew reload &9Reload config' Help_Configname: '&6/brew ItemName &9Display name of item in hand for the config' diff --git a/resources/languages/fr.yml b/resources/languages/fr.yml index 22fe764..ac42766 100644 --- a/resources/languages/fr.yml +++ b/resources/languages/fr.yml @@ -16,13 +16,10 @@ Brew_fermented: fermenté Brew_minute: minute # CMD -CMD_CopyNotPersistent: '&eLes copies de cette boisson ne seront pas persistantes ou statiques!' CMD_Copy_Error: '&6&v1 &cCes potions ne rentrent pas dans votre inventaire.' CMD_Info_Drunk: '&v1 est &6&v2% &fivre, avec une qualité de &6&v3' CMD_Info_NotDrunk: '&v1 nest pas ivre' CMD_NonStatic: '&eLa boisson n´est plus statique et vieillira normalement dans les barils.' -CMD_PersistRemove: '&cLes boissons persisitantes ne peuvent pas être supprimées de la base de donnée. Cela rendrait toute copie inutile!' -CMD_Persistent: '&aLa boisson est maintenant Persistante et Statique et peut être copiée comme n´importe quel autre objet. Vous pouvez enlever la persistance avec la même commande.' CMD_Player: '&a&v1 est maintenant &6&v2% &aivre, avec une qualité de &6&v3' CMD_Player_Error: '&cLa qualité doit être comprise entre 1 et 10 !' CMD_Reload: '&aLa config a été reload avec succès.' @@ -30,7 +27,6 @@ CMD_Configname: '&aName for the Config is: &f&v1' CMD_Configname_Error: '&cCould not find item in your hand' CMD_Static: '&aLa boisson est maintenant statique et ne changera pas dans les barils ou les stands d´alchimie.' CMD_UnLabel: '&aLabel supprimé!' -CMD_UnPersist: '&aPersistance et staticité supprimées. &eChaque copie potentionelle NON crée avec /brew copy deviendra inutile maintenant!' # Erreurs Error_ConfigUpdate: 'La version de la configuration de Brewery est inconnue: v&v1, la config n´a pas été mise à jour !' @@ -38,7 +34,6 @@ Error_ItemNotPotion: '&cL´item dans votre main n´a pas pu être identifié com Error_NoBarrelAccess: '&cVous n´avez pas la permission d´acceder à ce baril !' Error_NoBrewName: '&cAucune recette avec le nom: &v1&c n´a été trouvée!' Error_NoPermissions: '&cVous ne pouvez pas faire ça !' -Error_PersistStatic: '&cLes boissons persistantes sont toujours statiques!' Error_PlayerCommand: '&cCette commande ne peut être executée que par un joueur !' Error_Recipeload: '&cToutes les recettes n´ont pu être restaurées: Plus d´informations dans les logs du serveur !' Error_ShowHelp: Utilisez &6/brew help &fpour regarder l´aide @@ -56,7 +51,6 @@ Help_Delete: '&6/brew delete &9Supprime la potion qui est dans votre main' Help_Help: '&6/brew help [Page] &9Affiche une page spécifique de l´aide' Help_Info: '&6/brew info&9 Affiche votre ivresse actuelle ainsi que sa qualité' Help_InfoOther: '&6/brew info [Player]&9 Affiche l´ivresse actuelle de , cette commande affiche aussi sa qualité.' -Help_Persist: '&6/brew persist &9Crée une boisson persistante -> peut être copiée par n´importe quel plugin et technique' Help_Player: '&6/brew <%Drunkeness> [Quality]&9 Définit l´ivresse (et la qualité) du joueur' Help_Reload: '&6/brew reload &9Reload la config' Help_Configname: '&6/brew ItemName &9Display name of item in hand for the config' diff --git a/resources/languages/it.yml b/resources/languages/it.yml index 952fe33..4a2a003 100755 --- a/resources/languages/it.yml +++ b/resources/languages/it.yml @@ -16,13 +16,10 @@ Brew_fermented: fermentata Brew_minute: minuto # Comandi -CMD_CopyNotPersistent: '&eLe copie di questa miscela non saranno né persistenti né statiche!' CMD_Copy_Error: '&6&v1 &cLe copie di questa pozione non stavano nell''inventario.' CMD_Info_Drunk: '&v1 è &6&v2% &fsbronzo, con una qualità di &6&v3' CMD_Info_NotDrunk: '&v1 non è sbronzo' CMD_NonStatic: '&eLa pozione non è più statica ed invecchierà normalmente nei barili' -CMD_PersistRemove: '&cLe miscele persistenti non possono essere rimosse dal Database. Renderebbe le loro copie inutili!' -CMD_Persistent: '&aLa pozione è ora persistente e statica e può essere copiata come qualunque altro oggetto. Puoi rimuovere la persistenza con lo stesso comando.' CMD_Player: '&a&v1 è ora &6&v2% &asbronzo, con una qualità di &6&v3' CMD_Player_Error: '&cLa qualità deve essere fra 1 e 10!' CMD_Reload: '&aLa configurazione è stata ricaricata con successo' @@ -30,7 +27,6 @@ CMD_Configname: '&aName for the Config is: &f&v1' CMD_Configname_Error: '&cCould not find item in your hand' CMD_Static: '&aLa pozione è ora statica e non cambierà né nei barili né negli alambicchi.' CMD_UnLabel: '&aEtichetta rimossa!' -CMD_UnPersist: '&aPersistenza e staticità rimosse. &eOgni copia non fatta con ''/brew copy'' potrebbe diventare inutile ora!' # Errori Error_ConfigUpdate: 'Versione della configurazione di Brewery sconosciuta: v&v1, la configurazione non è stato aggiornata!' @@ -38,7 +34,6 @@ Error_ItemNotPotion: '&cL''oggetto nella tua mano non è una pozione!' Error_NoBarrelAccess: '&cNon hai il permesso di aprire questo barile!' Error_NoBrewName: '&cNon è stata trovata nessuna ricetta chiamata ''&v1&c''!' Error_NoPermissions: '&cNon hai il permesso di farlo!' -Error_PersistStatic: '&cLe pozioni persistenti sono sempre statiche!' Error_PlayerCommand: '&cQuesto comando può essere eseguito solo da un giocatore!' Error_Recipeload: '&cNon è stato possibile recuperare tutte le ricette: ulteriori informazioni nel file log!' Error_ShowHelp: Usa &6/brew help &fper visualizzare l''aiuto @@ -56,7 +51,6 @@ Help_Delete: '&6/brew delete &9Elimina la pozione nella tua mano' Help_Help: '&6/brew help &9Mostra una specifica pagina dell''aiuto' Help_Info: '&6/brew info&9 Mostra il tuo livello di sbronza attuale e la qualità' Help_InfoOther: '&6/brew info [Giocatore]&9 Mostra l''attuale livello di sbronza e la qualità di [Giocatore]' -Help_Persist: '&6/brew persist &9Rendi una miscela persistente quindi copiabile normalmente in ogni modo e da ogni plugin.' Help_Player: '&6/brew <%Sbronza> [Qualità]&9 Imposta livello di sbronza (e qualità) di un giocatore.' Help_Reload: '&6/brew reload &9Ricarica la configurazione' Help_Configname: '&6/brew ItemName &9Display name of item in hand for the config' diff --git a/resources/languages/tw.yml b/resources/languages/tw.yml index 7dfd0f7..d6707d4 100644 --- a/resources/languages/tw.yml +++ b/resources/languages/tw.yml @@ -16,13 +16,10 @@ Brew_fermented: 發酵 Brew_minute: 分鐘 # CMD -CMD_CopyNotPersistent: '&e這個釀造的副本不會持久或靜態!' CMD_Copy_Error: '&6&v1 &c藥水不適合你的庫存' CMD_Info_Drunk: '&v1 是 &6&v2% &f醉酒,酒的品質為 &6&v3' CMD_Info_NotDrunk: '&v1 沒有醉酒' CMD_NonStatic: '&e藥水不再是靜止的,會在桶木中老化.' -CMD_PersistRemove: '&c無法從數據庫中刪除持久性釀造.它會使任何副本無用!' -CMD_Persistent: '&a藥水現在是持久性和靜態,現在可以像任何其他項一樣被複製.您可以使用相同的命令刪除持久性.' CMD_Player: '&a&v1 現在是 &6&v2% &a醉酒,酒的品質為 &6&v3' CMD_Player_Error: '&c酒的品質必須在1到10之間!' CMD_Reload: '&a設定檔已成功重新加載' @@ -30,7 +27,6 @@ CMD_Configname: '&aName for the Config is: &f&v1' CMD_Configname_Error: '&cCould not find item in your hand' CMD_Static: '&a藥水現在是靜止的,不會在桶或釀造台上變化.' CMD_UnLabel: '&a標籤已刪除!' -CMD_UnPersist: '&a持久性和靜態刪除.&e每個隱藏的副本都不用''/brew copy'',現在可能變得無用了!' # Error Error_ConfigUpdate: '未知 釀酒 設定檔版本: v&v1,設定檔沒有更新!' @@ -38,7 +34,6 @@ Error_ItemNotPotion: '&c你手上的物品不能確定為藥水' Error_NoBarrelAccess: '&c你沒有權限存取!' Error_NoBrewName: '&c沒有這個配方: ''&v1&c'' 找到!' Error_NoPermissions: '&c你沒有權限這樣做!' -Error_PersistStatic: '&c持久藥水總是靜止的!' Error_PlayerCommand: '&c這個指令只能由玩家執行!' Error_Recipeload: '&c並非所有配方都可以有用:服務器日誌中的更多信息!' Error_ShowHelp: 使用 &6/brew help &f顯示幫助 @@ -56,7 +51,6 @@ Help_Delete: '&6/brew delete &9刪除你手中的藥水' Help_Help: '&6/brew help [頁數] &9顯示幫助的頁面' Help_Info: '&6/brew info&9 顯示您當前的醉酒和酒的品質' Help_InfoOther: '&6/brew info [玩家]&9 顯示 [玩家] 當前醉酒程度和酒的品質程度' -Help_Persist: '&6/brew persist &9使釀造持久化 - >可通過任何插件和技術進行複制' Help_Player: '&6/brew <玩家> <%醉酒> [數量]&9 設置玩家的醉酒度(和酒的品質)' Help_Reload: '&6/brew reload &9重新加載設定檔' Help_Configname: '&6/brew ItemName &9Display name of item in hand for the config' diff --git a/resources/languages/zh.yml b/resources/languages/zh.yml index 41b8fdb..ea7780f 100644 --- a/resources/languages/zh.yml +++ b/resources/languages/zh.yml @@ -16,13 +16,10 @@ Brew_fermented: 炖煮发酵 Brew_minute: 分钟 # CMD -CMD_CopyNotPersistent: '&e复制饮品的数据并未静滞或固定! 请多加注意!' CMD_Copy_Error: '&6&v1&r, &c你的背包塞不下了.' CMD_Info_Drunk: '&v1醉酒程度为&6&v2%&f, 醉酒质量为&6&v3.' CMD_Info_NotDrunk: '&v1没醉.' CMD_NonStatic: '&e饮品已被取消静滞, 现在可以正常地进行蒸馏或进行木桶熟成了.' -CMD_PersistRemove: '&c当前饮品的数据已被固定, 无法从数据库中移除, 否则将使得任何该饮品的复制品无效!' -CMD_Persistent: '&a当前饮品的数据已被固定. 现在你可以正常地对该饮品进行复制. 再执行一次该命令将会撤销固定.' CMD_Player: '&a&v1醉酒程度为&6&v2%&f, 醉酒质量为&6&v3.' CMD_Player_Error: '&c醉酒质量必须在1到10之间.' CMD_Reload: '&a配置文件重载成功.' @@ -30,7 +27,6 @@ CMD_Configname: '配置文件中&aName的名字是: &f&v1' CMD_Configname_Error: '&c无法找到物品名称' CMD_Static: '&a饮品已被静滞, 现在其无法被蒸馏或进行木桶熟成.' CMD_UnLabel: '&a标签已被去除!' -CMD_UnPersist: '&a当前饮品的数据已被撤销固定, 通过非指令方式(/brew copy)复制的饮品将可能无效!' # Error Error_ConfigUpdate: '未知的配置版本:v&v1, 插件配置未更新!' @@ -38,7 +34,6 @@ Error_ItemNotPotion: '&c你手上的物品并未成功地被认定为饮品!' Error_NoBarrelAccess: '&c你没有权限与该木桶互动!' Error_NoBrewName: '&c未找到名字为''&v1&c''的饮品!' Error_NoPermissions: '&c你没有权限这样做.' -Error_PersistStatic: '&c数据固定的饮品一定是静滞化饮品!' Error_PlayerCommand: '&c该命令必须由玩家执行.' Error_Recipeload: '&c加载饮品配方时出现问题, 请查看控制台以获得详细信息!' Error_ShowHelp: 使用&6/brew help&f以查看帮助 @@ -56,7 +51,6 @@ Help_Delete: '&6/brew delete &9删除手中的饮品.' Help_Help: '&6/brew help [页数] &9显示某一页的帮助.' Help_Info: '&6/brew info &9显示你目前的醉酒程度与质量, 醉酒质量将会影响宿醉程度.' Help_InfoOther: '&6/brew info [指定玩家] &9显示指定玩家目前的醉酒程度与质量.' -Help_Persist: '&6/brew persist &9将手中的饮品数据固定在服务端, 这将允许其被任何手段复制并饮用而不影响原饮品本体.' Help_Player: '&6/brew <目标玩家> <%醉酒程度> [醉酒质量] &9设定目标玩家的醉酒程度与质量.' Help_Reload: '&6/brew reload &9重载插件配置, 可用以重载饮品配方.' Help_Configname: '&6/brew ItemName &9显示手中物品的配置名称' diff --git a/resources/plugin.yml b/resources/plugin.yml index f08207a..116b6a4 100644 --- a/resources/plugin.yml +++ b/resources/plugin.yml @@ -41,7 +41,6 @@ permissions: brewery.cmd.create: true brewery.cmd.copy: true brewery.cmd.delete: true - brewery.cmd.persist: true brewery.cmd.static: true brewery.cmd.reload: true # * @@ -69,8 +68,6 @@ permissions: description: Copy Potions brewery.cmd.delete: description: Delete Potions - brewery.cmd.persist: - description: Make Potions Persistent brewery.cmd.static: description: Make Potions Static brewery.cmd.reload: diff --git a/src/com/dre/brewery/BDistiller.java b/src/com/dre/brewery/BDistiller.java index c65ae09..0c0c757 100644 --- a/src/com/dre/brewery/BDistiller.java +++ b/src/com/dre/brewery/BDistiller.java @@ -67,6 +67,10 @@ public class BDistiller { distiller.start(); } + public static boolean isTrackingDistiller(Block block) { + return trackedDistillers.containsKey(block); + } + // Returns a Brew or null for every Slot in the BrewerInventory public static Brew[] getDistillContents(BrewerInventory inv) { ItemStack item; diff --git a/src/com/dre/brewery/Brew.java b/src/com/dre/brewery/Brew.java index cf9011f..d5964ca 100644 --- a/src/com/dre/brewery/Brew.java +++ b/src/com/dre/brewery/Brew.java @@ -463,27 +463,6 @@ public class Brew implements Cloneable { return currentRecipe; } - // Not needed anymore - // TODO remove - @Deprecated - public boolean isPersistent() { - return persistent; - } - - // Make a potion persistent to not delete it when drinking it - // Not needed anymore - @Deprecated - public void makePersistent() { - persistent = true; - } - - // Remove the Persistence Flag from a brew, so it will be normally deleted when drinking it - // Not needed anymore - @Deprecated - public void removePersistence() { - persistent = false; - } - public boolean isStatic() { return immutable; } @@ -866,7 +845,6 @@ public class Brew implements Cloneable { recipe = in.readUTF(); } unlabeled = (bools & 16) != 0; - //persistent = (bools & 32) != 0; immutable = (bools & 32) != 0; ingredients = BIngredients.load(in, dataVersion); setRecipeFromString(recipe); diff --git a/src/com/dre/brewery/MCBarrel.java b/src/com/dre/brewery/MCBarrel.java index a0f4019..6fda3c3 100644 --- a/src/com/dre/brewery/MCBarrel.java +++ b/src/com/dre/brewery/MCBarrel.java @@ -80,8 +80,7 @@ public class MCBarrel { // This is the last viewer for (ItemStack item : inv.getContents()) { if (item != null) { - Brew brew = Brew.get(item); - if (brew != null) { // TODO replace this and others with isBrew + if (Brew.isBrew(item)) { // We found a brew, so set time on this Barrel if (inv.getHolder() instanceof org.bukkit.block.Barrel) { Barrel barrel = (Barrel) inv.getHolder(); @@ -101,8 +100,7 @@ public class MCBarrel { brews = 0; for (ItemStack item : inv.getContents()) { if (item != null) { - Brew brew = Brew.get(item); - if (brew != null) { + if (Brew.isBrew(item)) { brews++; } } @@ -113,6 +111,7 @@ public class MCBarrel { return inv; } + public static void onUpdate() { mcBarrelTime++; } @@ -133,11 +132,9 @@ public class MCBarrel { case SWAP_WITH_CURSOR: // Placing Brew in MC Barrel if (event.getCursor() != null && event.getClickedInventory() != null && event.getClickedInventory().getType() == InventoryType.BARREL && event.getCursor().getType() == Material.POTION) { - Brew b = Brew.get(event.getCursor()); - if (b != null) { + if (Brew.isBrew(event.getCursor())) { if (event.getAction() == InventoryAction.SWAP_WITH_CURSOR && event.getCurrentItem() != null && event.getCurrentItem().getType() == Material.POTION) { - Brew bb = Brew.get(event.getCurrentItem()); - if (bb != null) { + if (Brew.isBrew(event.getCurrentItem())) { // The item we are swapping with is also a brew, dont change the count and allow break; } @@ -150,8 +147,7 @@ public class MCBarrel { if (event.getCurrentItem() != null && event.getCurrentItem().getType() == Material.POTION && event.getClickedInventory() != null) { if (event.getClickedInventory().getType() == InventoryType.BARREL) { // Moving Brew out of MC Barrel - Brew b = Brew.get(event.getCurrentItem()); - if (b != null) { + if (Brew.isBrew(event.getCurrentItem())) { if (brews == -1) { countBrews(); } @@ -160,8 +156,7 @@ public class MCBarrel { break; } else if (event.getClickedInventory().getType() == InventoryType.PLAYER) { // Moving Brew into MC Barrel - Brew b = Brew.get(event.getCurrentItem()); - if (b != null) { + if (Brew.isBrew(event.getCurrentItem())) { adding = true; } } @@ -175,8 +170,7 @@ public class MCBarrel { case COLLECT_TO_CURSOR: // Pickup Brew from MC Barrel if (event.getCurrentItem() != null && event.getClickedInventory() != null && event.getClickedInventory().getType() == InventoryType.BARREL && event.getCurrentItem().getType() == Material.POTION) { - Brew b = Brew.get(event.getCurrentItem()); - if (b != null) { + if (Brew.isBrew(event.getCurrentItem())) { if (brews == -1) { countBrews(); } diff --git a/src/com/dre/brewery/filedata/LanguageReader.java b/src/com/dre/brewery/filedata/LanguageReader.java index bd44779..ba9105b 100644 --- a/src/com/dre/brewery/filedata/LanguageReader.java +++ b/src/com/dre/brewery/filedata/LanguageReader.java @@ -92,11 +92,7 @@ public class LanguageReader { defaults.add(new Tuple<>("CMD_Info_NotDrunk", "&v1 is not drunk")); defaults.add(new Tuple<>("CMD_Info_Drunk", "&v1 is &6&v2% &fdrunk, with a quality of &6&v3")); defaults.add(new Tuple<>("CMD_UnLabel", "&aLabel removed!")); - defaults.add(new Tuple<>("CMD_Persistent", "&aPotion is now Persistent and Static and may now be copied like any other item. You can remove the persistence with the same command.")); - defaults.add(new Tuple<>("CMD_PersistRemove", "&cPersistent Brews cannot be removed from the Database. It would render any copies of them useless!")); - defaults.add(new Tuple<>("CMD_UnPersist", "&aPersistence and static Removed. &eEvery Potential copy NOT made with '/brew copy' could become useless now!")); defaults.add(new Tuple<>("CMD_Copy_Error", "&6&v1 &cPotions did not fit into your inventory")); - defaults.add(new Tuple<>("CMD_CopyNotPersistent", "&eThese copies of this Brew will not be persistent or static!")); defaults.add(new Tuple<>("CMD_Static", "&aPotion is now static and will not change in barrels or brewing stands.")); defaults.add(new Tuple<>("CMD_NonStatic", "&ePotion is not static anymore and will normally age in barrels.")); @@ -108,7 +104,6 @@ public class LanguageReader { defaults.add(new Tuple<>("Error_NoBrewName", "&cNo Recipe with Name: '&v1&c' found!")); defaults.add(new Tuple<>("Error_Recipeload", "&cNot all recipes could be restored: More information in the server log!")); defaults.add(new Tuple<>("Error_ConfigUpdate", "Unknown Brewery config version: v&v1, config was not updated!")); - defaults.add(new Tuple<>("Error_PersistStatic", "&cPersistent potions are always static!")); /* Permissions */ defaults.add(new Tuple<>("Error_NoPermissions", "&cYou don't have permissions to do this!")); @@ -135,7 +130,6 @@ public class LanguageReader { defaults.add(new Tuple<>("Help_WakeupRemove", "&6/brew wakeup remove &9Removes the wakeup point with ")); defaults.add(new Tuple<>("Help_Reload", "&6/brew reload &9Reload config")); defaults.add(new Tuple<>("Help_Configname", "&6/brew ItemName &9Display name of item in hand for the config")); - defaults.add(new Tuple<>("Help_Persist", "&6/brew persist &9Make Brew persistent -> copyable by any plugin and technique")); defaults.add(new Tuple<>("Help_Static", "&6/brew static &9Make Brew static -> No further ageing or distilling")); defaults.add(new Tuple<>("Help_Create", "&6/brew create [Quality] [Player] &9Create a Brew with optional quality (1-10)")); diff --git a/src/com/dre/brewery/listeners/CommandListener.java b/src/com/dre/brewery/listeners/CommandListener.java index 8ab4463..0a88b60 100644 --- a/src/com/dre/brewery/listeners/CommandListener.java +++ b/src/com/dre/brewery/listeners/CommandListener.java @@ -101,14 +101,6 @@ public class CommandListener implements CommandExecutor { p.msg(sender, p.languageReader.get("Error_NoPermissions")); } - } else if (cmd.equalsIgnoreCase("persist") || cmd.equalsIgnoreCase("persistent")) { - - if (sender.hasPermission("brewery.cmd.persist")) { - cmdPersist(sender); - } else { - p.msg(sender, p.languageReader.get("Error_NoPermissions")); - } - } else if (cmd.equalsIgnoreCase("static")) { if (sender.hasPermission("brewery.cmd.static")) { @@ -186,18 +178,19 @@ public class CommandListener implements CommandExecutor { cmds.add (p.languageReader.get("Help_UnLabel")); } - if (sender.hasPermission("brewery.cmd.copy")) { - cmds.add (p.languageReader.get("Help_Copy")); - } - - if (sender.hasPermission("brewery.cmd.delete")) { - cmds.add (p.languageReader.get("Help_Delete")); - } - if (sender.hasPermission("brewery.cmd.infoOther")) { cmds.add (p.languageReader.get("Help_InfoOther")); } + if (sender.hasPermission("brewery.cmd.create")) { + cmds.add(p.languageReader.get("Help_Create")); + } + + if (sender.hasPermission("brewery.cmd.reload")) { + cmds.add(p.languageReader.get("Help_Configname")); + cmds.add(p.languageReader.get("Help_Reload")); + } + if (sender.hasPermission("brewery.cmd.wakeup")) { cmds.add(p.languageReader.get("Help_Wakeup")); cmds.add(p.languageReader.get("Help_WakeupList")); @@ -207,21 +200,16 @@ public class CommandListener implements CommandExecutor { cmds.add(p.languageReader.get("Help_WakeupRemove")); } - if (sender.hasPermission("brewery.cmd.reload")) { - cmds.add(p.languageReader.get("Help_Configname")); - cmds.add(p.languageReader.get("Help_Reload")); - } - - if (sender.hasPermission("brewery.cmd.persist")) { - cmds.add(p.languageReader.get("Help_Persist")); - } - if (sender.hasPermission("brewery.cmd.static")) { cmds.add(p.languageReader.get("Help_Static")); } - if (sender.hasPermission("brewery.cmd.create")) { - cmds.add(p.languageReader.get("Help_Create")); + if (sender.hasPermission("brewery.cmd.copy")) { + cmds.add (p.languageReader.get("Help_Copy")); + } + + if (sender.hasPermission("brewery.cmd.delete")) { + cmds.add (p.languageReader.get("Help_Delete")); } return cmds; @@ -393,8 +381,7 @@ public class CommandListener implements CommandExecutor { Player player = (Player) sender; ItemStack hand = player.getItemInHand(); if (hand != null) { - Brew brew = Brew.get(hand); - if (brew != null) { + if (Brew.isBrew(hand)) { while (count > 0) { ItemStack item = hand.clone(); if (!(player.getInventory().addItem(item)).isEmpty()) { @@ -403,9 +390,6 @@ public class CommandListener implements CommandExecutor { } count--; } - if (brew.isPersistent()) { - p.msg(sender, p.languageReader.get("CMD_CopyNotPersistent")); - } return; } } @@ -424,44 +408,8 @@ public class CommandListener implements CommandExecutor { Player player = (Player) sender; ItemStack hand = player.getItemInHand(); if (hand != null) { - Brew brew = Brew.get(hand); - if (brew != null) { - if (brew.isPersistent()) { - p.msg(sender, p.languageReader.get("CMD_PersistRemove")); - } else { - //brew.remove(hand); - player.setItemInHand(new ItemStack(Material.AIR)); - } - return; - } - } - p.msg(sender, p.languageReader.get("Error_ItemNotPotion")); - - } - - @Deprecated - public void cmdPersist(CommandSender sender) { - - if (!(sender instanceof Player)) { - p.msg(sender, p.languageReader.get("Error_PlayerCommand")); - return; - } - Player player = (Player) sender; - ItemStack hand = player.getItemInHand(); - if (hand != null) { - Brew brew = Brew.get(hand); - if (brew != null) { - if (brew.isPersistent()) { - brew.removePersistence(); - brew.setStatic(false, hand); - p.msg(sender, p.languageReader.get("CMD_UnPersist")); - } else { - brew.makePersistent(); - brew.setStatic(true, hand); - p.msg(sender, p.languageReader.get("CMD_Persistent")); - } - brew.touch(); - brew.save(hand); + if (Brew.isBrew(hand)) { + player.setItemInHand(new ItemStack(Material.AIR)); return; } } @@ -482,12 +430,8 @@ public class CommandListener implements CommandExecutor { Brew brew = Brew.get(hand); if (brew != null) { if (brew.isStatic()) { - if (!brew.isPersistent()) { - brew.setStatic(false, hand); - p.msg(sender, p.languageReader.get("CMD_NonStatic")); - } else { - p.msg(sender, p.languageReader.get("Error_PersistStatic")); - } + brew.setStatic(false, hand); + p.msg(sender, p.languageReader.get("CMD_NonStatic")); } else { brew.setStatic(true, hand); p.msg(sender, p.languageReader.get("CMD_Static")); diff --git a/src/com/dre/brewery/listeners/InventoryListener.java b/src/com/dre/brewery/listeners/InventoryListener.java index f3f33a5..f27b9ae 100644 --- a/src/com/dre/brewery/listeners/InventoryListener.java +++ b/src/com/dre/brewery/listeners/InventoryListener.java @@ -31,7 +31,6 @@ public class InventoryListener implements Listener { /** * Start tracking distillation for a person when they open the brewer window. - * @param event */ @EventHandler(priority = EventPriority.HIGH, ignoreCancelled = true) public void onBrewerOpen(InventoryOpenEvent event) { @@ -46,7 +45,6 @@ public class InventoryListener implements Listener { /** * Stop tracking distillation for a person when they close the brewer window. - * @param event */ @EventHandler(priority = EventPriority.HIGH, ignoreCancelled = true) public void onBrewerClose(InventoryCloseEvent event) { @@ -72,8 +70,6 @@ public class InventoryListener implements Listener { * Clicking can either start or stop the new brew distillation tracking. * Note that server restart will halt any ongoing brewing processes and * they will _not_ restart until a new click event. - * - * @param event the Click event. */ @EventHandler(priority = EventPriority.HIGH, ignoreCancelled = true) public void onBrewerClick(InventoryClickEvent event) { @@ -306,12 +302,44 @@ public class InventoryListener implements Listener { // block the pickup of items where getPickupDelay is > 1000 (puke) @EventHandler(ignoreCancelled = true) - public void onInventoryPickupItem(InventoryPickupItemEvent event){ + public void onHopperPickupPuke(InventoryPickupItemEvent event){ if (event.getItem().getPickupDelay() > 1000 && event.getItem().getItemStack().getType() == BConfig.pukeItem) { event.setCancelled(true); } } + // Block taking out items from running distillers, + // Convert Color Lore from MC Barrels back into normal color on taking out + @EventHandler(ignoreCancelled = true, priority = EventPriority.HIGH) + public void onHopperMove(InventoryMoveItemEvent event){ + if (event.getSource() instanceof BrewerInventory) { + if (BDistiller.isTrackingDistiller(((BrewerInventory) event.getSource()).getHolder().getBlock())) { + event.setCancelled(true); + } + return; + } + + if (!P.use1_14) return; + + if (event.getSource().getType() == InventoryType.BARREL) { + ItemStack item = event.getItem(); + if (item.getType() == Material.POTION && Brew.isBrew(item)) { + PotionMeta meta = (PotionMeta) item.getItemMeta(); + if (BrewLore.hasColorLore(meta)) { + // has color lore, convert lore back to normal + Brew brew = Brew.get(meta); + if (brew != null) { + BrewLore lore = new BrewLore(brew, meta); + lore.convertLore(false); + lore.write(); + item.setItemMeta(meta); + event.setItem(item); + } + } + } + } + } + @EventHandler public void onInventoryClose(InventoryCloseEvent event) { if (!P.use1_14) return; From 036657747c864c6b982abfad16acad473ddb3ec7 Mon Sep 17 00:00:00 2001 From: Sn0wStorm Date: Thu, 14 Nov 2019 16:16:12 +0100 Subject: [PATCH 37/51] Only reload config if valid yml --- resources/languages/de.yml | 1 + resources/languages/en.yml | 1 + resources/languages/fr.yml | 1 + resources/languages/it.yml | 1 + resources/languages/tw.yml | 1 + resources/languages/zh.yml | 1 + src/com/dre/brewery/P.java | 14 ++++++++-- src/com/dre/brewery/filedata/BConfig.java | 27 ++++++++++++++++--- .../dre/brewery/filedata/LanguageReader.java | 1 + .../brewery/listeners/CommandListener.java | 1 - 10 files changed, 42 insertions(+), 7 deletions(-) diff --git a/resources/languages/de.yml b/resources/languages/de.yml index 00dee9c..f2ea098 100644 --- a/resources/languages/de.yml +++ b/resources/languages/de.yml @@ -37,6 +37,7 @@ Error_Recipeload: '&cEs konnten nicht alle Rezepte wiederhergesellt werden: Sieh Error_ShowHelp: 'Benutze &6/brew help &fum die Hilfe anzuzeigen' Error_UnknownCommand: Unbekannter Befehl Error_ConfigUpdate: 'Unbekannte Brewery Config Version: v&v1, Config wurde nicht geupdated!' +Error_YmlRead: 'config.yml konnte nicht gelesen werden, ist die Datei im korrekten yml-Format (korrekte Leerzeichen usw.)?' # Permission Error_NoPermissions: '&cDu hast keine Rechte dies zu tun!' diff --git a/resources/languages/en.yml b/resources/languages/en.yml index ae8d8bb..6baef83 100644 --- a/resources/languages/en.yml +++ b/resources/languages/en.yml @@ -39,6 +39,7 @@ Error_PlayerCommand: '&cThis command can only be executed as a player!' Error_Recipeload: '&cNot all recipes could be restored: More information in the server log!' Error_ShowHelp: Use &6/brew help &fto display the help Error_UnknownCommand: Unknown Command +Error_YmlRead: 'Could not read file config.yml, please make sure the file is in valid yml format (correct spaces etc.)' # Etc Etc_Barrel: Barrel diff --git a/resources/languages/fr.yml b/resources/languages/fr.yml index ac42766..4a57aca 100644 --- a/resources/languages/fr.yml +++ b/resources/languages/fr.yml @@ -38,6 +38,7 @@ Error_PlayerCommand: '&cCette commande ne peut être executée que par un joueur Error_Recipeload: '&cToutes les recettes n´ont pu être restaurées: Plus d´informations dans les logs du serveur !' Error_ShowHelp: Utilisez &6/brew help &fpour regarder l´aide Error_UnknownCommand: Commande inconnue +Error_YmlRead: 'Could not read file config.yml, please make sure the file is in valid yml format (correct spaces etc.)' # Etc Etc_Barrel: Baril diff --git a/resources/languages/it.yml b/resources/languages/it.yml index 4a2a003..136de93 100755 --- a/resources/languages/it.yml +++ b/resources/languages/it.yml @@ -38,6 +38,7 @@ Error_PlayerCommand: '&cQuesto comando può essere eseguito solo da un giocatore Error_Recipeload: '&cNon è stato possibile recuperare tutte le ricette: ulteriori informazioni nel file log!' Error_ShowHelp: Usa &6/brew help &fper visualizzare l''aiuto Error_UnknownCommand: Comando sconosciuto +Error_YmlRead: 'Could not read file config.yml, please make sure the file is in valid yml format (correct spaces etc.)' # Varie Etc_Barrel: Barile diff --git a/resources/languages/tw.yml b/resources/languages/tw.yml index d6707d4..2ba1665 100644 --- a/resources/languages/tw.yml +++ b/resources/languages/tw.yml @@ -38,6 +38,7 @@ Error_PlayerCommand: '&c這個指令只能由玩家執行!' Error_Recipeload: '&c並非所有配方都可以有用:服務器日誌中的更多信息!' Error_ShowHelp: 使用 &6/brew help &f顯示幫助 Error_UnknownCommand: 未知的指令 +Error_YmlRead: 'Could not read file config.yml, please make sure the file is in valid yml format (correct spaces etc.)' # Etc Etc_Barrel: 釀造桶 diff --git a/resources/languages/zh.yml b/resources/languages/zh.yml index ea7780f..36f7891 100644 --- a/resources/languages/zh.yml +++ b/resources/languages/zh.yml @@ -38,6 +38,7 @@ Error_PlayerCommand: '&c该命令必须由玩家执行.' Error_Recipeload: '&c加载饮品配方时出现问题, 请查看控制台以获得详细信息!' Error_ShowHelp: 使用&6/brew help&f以查看帮助 Error_UnknownCommand: 未知命令. +Error_YmlRead: 'Could not read file config.yml, please make sure the file is in valid yml format (correct spaces etc.)' # Etc Etc_Barrel: 木桶 diff --git a/src/com/dre/brewery/P.java b/src/com/dre/brewery/P.java index fd177b4..54a68f6 100644 --- a/src/com/dre/brewery/P.java +++ b/src/com/dre/brewery/P.java @@ -16,6 +16,7 @@ import org.apache.commons.lang.math.NumberUtils; import org.bukkit.Bukkit; import org.bukkit.ChatColor; import org.bukkit.command.CommandSender; +import org.bukkit.configuration.file.FileConfiguration; import org.bukkit.event.HandlerList; import org.bukkit.plugin.java.JavaPlugin; @@ -313,7 +314,8 @@ public class P extends JavaPlugin { // load the Config try { - if (!BConfig.readConfig()) { + FileConfiguration cfg = BConfig.loadConfigFile(); + if (cfg == null || !BConfig.readConfig(cfg)) { p = null; getServer().getPluginManager().disablePlugin(this); return; @@ -463,6 +465,12 @@ public class P extends JavaPlugin { if (sender != null && !sender.equals(getServer().getConsoleSender())) { BConfig.reloader = sender; } + FileConfiguration cfg = BConfig.loadConfigFile(); + if (cfg == null) { + // Could not read yml file, do not proceed + return; + } + // clear all existent config Data BRecipe.getConfigRecipes().clear(); BRecipe.numConfigRecipes = 0; @@ -486,7 +494,7 @@ public class P extends JavaPlugin { // load the Config try { - if (!BConfig.readConfig()) { + if (!BConfig.readConfig(cfg)) { p = null; getServer().getPluginManager().disablePlugin(this); return; @@ -510,6 +518,8 @@ public class P extends JavaPlugin { } if (!successful && sender != null) { msg(sender, p.languageReader.get("Error_Recipeload")); + } else { + p.msg(sender, p.languageReader.get("CMD_Reload")); } BConfig.reloader = null; } diff --git a/src/com/dre/brewery/filedata/BConfig.java b/src/com/dre/brewery/filedata/BConfig.java index 7ea44d9..970a890 100644 --- a/src/com/dre/brewery/filedata/BConfig.java +++ b/src/com/dre/brewery/filedata/BConfig.java @@ -119,13 +119,31 @@ public class BConfig { } } - public static boolean readConfig() { + public static FileConfiguration loadConfigFile() { File file = new File(P.p.getDataFolder(), "config.yml"); if (!checkConfigs()) { - return false; + return null; } - FileConfiguration config = YamlConfiguration.loadConfiguration(file); + try { + YamlConfiguration cfg = YamlConfiguration.loadConfiguration(file); + if (cfg.contains("version") && cfg.contains("language")) { + return cfg; + } + } catch (Exception e) { + e.printStackTrace(); + } + + // Failed to load + if (p.languageReader != null) { + P.p.errorLog(p.languageReader.get("Error_YmlRead")); + } else { + P.p.errorLog("Could not read file config.yml, please make sure the file is in valid yml format (correct spaces etc.)"); + } + return null; + } + + public static boolean readConfig(FileConfiguration config) { // Set the Language p.language = config.getString("language", "en"); @@ -139,6 +157,7 @@ public class BConfig { String version = config.getString("version", null); if (version != null) { if (!version.equals(configVersion) || (oldMat && P.use1_13)) { + File file = new File(P.p.getDataFolder(), "config.yml"); copyDefaultConfigs(true); new ConfigUpdater(file).update(version, oldMat, p.language); P.p.log("Config Updated to version: " + configVersion); @@ -199,7 +218,7 @@ public class BConfig { openEverywhere = config.getBoolean("openLargeBarrelEverywhere", false); MCBarrel.maxBrews = config.getInt("maxBrewsInMCBarrels", 6); - Brew.loadSeed(config, file); + Brew.loadSeed(config, new File(P.p.getDataFolder(), "config.yml")); PluginItem.registerForConfig("brewery", BreweryPluginItem::new); PluginItem.registerForConfig("mmoitems", MMOItemsPluginItem::new); diff --git a/src/com/dre/brewery/filedata/LanguageReader.java b/src/com/dre/brewery/filedata/LanguageReader.java index ba9105b..c9a8811 100644 --- a/src/com/dre/brewery/filedata/LanguageReader.java +++ b/src/com/dre/brewery/filedata/LanguageReader.java @@ -104,6 +104,7 @@ public class LanguageReader { defaults.add(new Tuple<>("Error_NoBrewName", "&cNo Recipe with Name: '&v1&c' found!")); defaults.add(new Tuple<>("Error_Recipeload", "&cNot all recipes could be restored: More information in the server log!")); defaults.add(new Tuple<>("Error_ConfigUpdate", "Unknown Brewery config version: v&v1, config was not updated!")); + defaults.add(new Tuple<>("Error_YmlRead", "Could not read File config.yml, please make sure the file is in valid yml format (correct spaces etc.)")); /* Permissions */ defaults.add(new Tuple<>("Error_NoPermissions", "&cYou don't have permissions to do this!")); diff --git a/src/com/dre/brewery/listeners/CommandListener.java b/src/com/dre/brewery/listeners/CommandListener.java index 0a88b60..e757533 100644 --- a/src/com/dre/brewery/listeners/CommandListener.java +++ b/src/com/dre/brewery/listeners/CommandListener.java @@ -36,7 +36,6 @@ public class CommandListener implements CommandExecutor { if (sender.hasPermission("brewery.cmd.reload")) { p.reload(sender); - p.msg(sender, p.languageReader.get("CMD_Reload")); } else { p.msg(sender, p.languageReader.get("Error_NoPermissions")); } From d0198c9f0489efe846973621f25c1cbc23293590 Mon Sep 17 00:00:00 2001 From: Sn0wStorm Date: Fri, 15 Nov 2019 14:43:26 +0100 Subject: [PATCH 38/51] Convert pre 1.11 Brews (cosmetic) --- src/com/dre/brewery/Brew.java | 33 ++++++++++++++++--- .../brewery/listeners/InventoryListener.java | 23 ++++++++++--- src/com/dre/brewery/recipe/BRecipe.java | 2 +- src/com/dre/brewery/recipe/PotionColor.java | 1 + 4 files changed, 48 insertions(+), 11 deletions(-) diff --git a/src/com/dre/brewery/Brew.java b/src/com/dre/brewery/Brew.java index d5964ca..f28f411 100644 --- a/src/com/dre/brewery/Brew.java +++ b/src/com/dre/brewery/Brew.java @@ -14,8 +14,10 @@ import org.bukkit.inventory.BrewerInventory; import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.meta.ItemMeta; import org.bukkit.inventory.meta.PotionMeta; +import org.bukkit.potion.PotionData; import org.bukkit.potion.PotionEffect; import org.bukkit.potion.PotionEffectType; +import org.bukkit.potion.PotionType; import org.jetbrains.annotations.Contract; import org.jetbrains.annotations.Nullable; @@ -985,19 +987,40 @@ public class Brew implements Cloneable { getFromPotionEffect(((PotionMeta) meta), true); } - public void convertPre19(ItemStack item) { + public void convertPre1_9(ItemStack item) { removeLegacy(item); PotionMeta potionMeta = ((PotionMeta) item.getItemMeta()); assert potionMeta != null; + + BrewLore lore = new BrewLore(this, potionMeta); + lore.removeEffects(); + if (hasRecipe()) { - BrewLore lore = new BrewLore(this, potionMeta); - lore.removeEffects(); currentRecipe.getColor().colorBrew(potionMeta, item, canDistill()); - lore.removeLegacySpacing(); } else { PotionColor.GREY.colorBrew(potionMeta, item, canDistill()); - new BrewLore(this, potionMeta).removeLegacySpacing(); } + lore.removeLegacySpacing(); + save(potionMeta); + item.setItemMeta(potionMeta); + } + + public void convertPre1_11(ItemStack item) { + removeLegacy(item); + PotionMeta potionMeta = ((PotionMeta) item.getItemMeta()); + assert potionMeta != null; + + potionMeta.setBasePotionData(new PotionData(PotionType.UNCRAFTABLE)); + BrewLore lore = new BrewLore(this, potionMeta); + lore.removeEffects(); + + if (hasRecipe()) { + lore.addOrReplaceEffects(currentRecipe.getEffects(), getQuality()); + currentRecipe.getColor().colorBrew(potionMeta, item, canDistill()); + } else { + PotionColor.GREY.colorBrew(potionMeta, item, canDistill()); + } + lore.removeLegacySpacing(); save(potionMeta); item.setItemMeta(potionMeta); } diff --git a/src/com/dre/brewery/listeners/InventoryListener.java b/src/com/dre/brewery/listeners/InventoryListener.java index f27b9ae..de8b5dc 100644 --- a/src/com/dre/brewery/listeners/InventoryListener.java +++ b/src/com/dre/brewery/listeners/InventoryListener.java @@ -108,11 +108,22 @@ public class InventoryListener implements Listener { ItemStack item = event.getCurrentItem(); if (item.hasItemMeta()) { PotionMeta potion = ((PotionMeta) item.getItemMeta()); - // convert potions from 1.8 to 1.9 for color and to remove effect descriptions - if (P.use1_9 && !potion.hasItemFlag(ItemFlag.HIDE_POTION_EFFECTS)) { - Brew brew = Brew.get(potion); - if (brew != null) { - brew.convertPre19(item); + assert potion != null; + if (P.use1_11) { + // Convert potions from 1.10 to 1.11 for new color + if (potion.getColor() == null) { + Brew brew = Brew.get(potion); + if (brew != null) { + brew.convertPre1_11(item); + } + } + } else { + // convert potions from 1.8 to 1.9 for color and to remove effect descriptions + if (P.use1_9 && !potion.hasItemFlag(ItemFlag.HIDE_POTION_EFFECTS)) { + Brew brew = Brew.get(potion); + if (brew != null) { + brew.convertPre1_9(item); + } } } Brew brew = Brew.get(item); @@ -203,6 +214,7 @@ public class InventoryListener implements Listener { ItemStack item = event.getCurrentItem(); if (item != null && item.getType() == Material.POTION && item.hasItemMeta()) { PotionMeta meta = (PotionMeta) item.getItemMeta(); + assert meta != null; Brew brew = Brew.get(meta); if (brew != null) { BrewLore lore = null; @@ -325,6 +337,7 @@ public class InventoryListener implements Listener { ItemStack item = event.getItem(); if (item.getType() == Material.POTION && Brew.isBrew(item)) { PotionMeta meta = (PotionMeta) item.getItemMeta(); + assert meta != null; if (BrewLore.hasColorLore(meta)) { // has color lore, convert lore back to normal Brew brew = Brew.get(meta); diff --git a/src/com/dre/brewery/recipe/BRecipe.java b/src/com/dre/brewery/recipe/BRecipe.java index e3dab3f..6c620f1 100644 --- a/src/com/dre/brewery/recipe/BRecipe.java +++ b/src/com/dre/brewery/recipe/BRecipe.java @@ -19,7 +19,7 @@ import java.util.List; public class BRecipe { - public static List recipes = new ArrayList<>(); + private static List recipes = new ArrayList<>(); public static int numConfigRecipes; // The number of recipes in the list that are from config private String[] name; diff --git a/src/com/dre/brewery/recipe/PotionColor.java b/src/com/dre/brewery/recipe/PotionColor.java index bfeee7b..59aac49 100644 --- a/src/com/dre/brewery/recipe/PotionColor.java +++ b/src/com/dre/brewery/recipe/PotionColor.java @@ -59,6 +59,7 @@ public class PotionColor { @SuppressWarnings("deprecation") public void colorBrew(PotionMeta meta, ItemStack potion, boolean destillable) { if (P.use1_9) { + // We need to Hide Potion Effects even in 1.12, as it would otherwise show "No Effects" meta.addItemFlags(ItemFlag.HIDE_POTION_EFFECTS); if (P.use1_11) { // BasePotionData was only used for the Color, so starting with 1.12 we can use setColor instead From fa2a4974d8d7690496a392d87611df693b569a23 Mon Sep 17 00:00:00 2001 From: Sn0wStorm Date: Fri, 22 Nov 2019 20:00:05 +0100 Subject: [PATCH 39/51] Added Messages and Commands when drinking --- resources/config/v13/de/config.yml | 12 +- resources/config/v13/en/config.yml | 11 ++ src/com/dre/brewery/BPlayer.java | 6 +- src/com/dre/brewery/P.java | 2 +- src/com/dre/brewery/recipe/BRecipe.java | 127 ++++++++++++++++++--- src/com/dre/brewery/recipe/RecipeItem.java | 28 +---- src/com/dre/brewery/utility/BUtil.java | 32 ++++++ 7 files changed, 178 insertions(+), 40 deletions(-) diff --git a/resources/config/v13/de/config.yml b/resources/config/v13/de/config.yml index 686080d..e8821a8 100644 --- a/resources/config/v13/de/config.yml +++ b/resources/config/v13/de/config.yml @@ -207,6 +207,10 @@ cauldron: # alcohol: Alkoholgehalt 0-100 in absoluter Menge bei perfektem Getränk (wird dem Spieler hinzugefügt, bei 100 = tot) # lore: Auflistung von zusätzlichem Text auf dem fertigen Trank. (Farbcodes möglich: z.b. &6) # Lore nur für bestimmte Qualität möglich mit + Schlecht, ++ Mittel, +++ Gut, vorne anhängen. +# servercommands: Liste von Befehlen ausgeführt vom Server wenn der Trank getrunken wird +# playercommands: Liste von Befehlen ausgeführt vom Spieler wenn der Trank getrunken wird +# drinkmessage: Nachricht im Chat beim trinken des Trankes +# drinktitle: Nachricht als Titel auf dem Bildschirm an den Spieler beim trinken des Trankes # effects: Auflistung Effekt/Level/Dauer Besonderere Trank-Effekte beim Trinken, Dauer in sek. # Mögliche Effekte: https://hub.spigotmc.org/javadocs/spigot/org/bukkit/potion/PotionEffectType.html # Minimale und Maximale Level/Dauer können durch "-" festgelegt werden, Bsp: 'SPEED/1-2/30-40' = Level 1 und 30 sek minimal, Level 2 und 40 sek maximal @@ -223,7 +227,7 @@ recipes: - Bedrock/1 - Brewery:Weißbier/2 # - ExoticGarden:Grape/3 - - bsp-item/1 + - bsp-item/4 cookingtime: 3 distillruns: 2 distilltime: 60 @@ -239,6 +243,12 @@ recipes: - + Riecht eklig - ++ Riecht ganz ok - +++ Riecht richtig gut + servercommands: + - weather clear + playercommands: + - homes + drinkmessage: Schmeckt toll + drinktitle: Wärmt dich von innen effects: - FIRE_RESISTANCE/20 - HEAL/1 diff --git a/resources/config/v13/en/config.yml b/resources/config/v13/en/config.yml index fdd0ed9..4da7fce 100644 --- a/resources/config/v13/en/config.yml +++ b/resources/config/v13/en/config.yml @@ -208,6 +208,10 @@ cauldron: # alcohol: Absolute amount of alcohol 0-100 in a perfect potion (will be added directly to the player, where 100 means fainting) # lore: List of additional text on the finished brew. (Formatting codes possible: such as &6) # Specific lore for quality possible, using + bad, ++ normal, ++ good, added to the front of the line. +# servercommands: List of Commands executed by the Server when drinking the brew +# playercommands: List of Commands executed by the Player when drinking the brew +# drinkmessage: Chat-message to the Player when drinking the Brew +# drinktitle: Title on Screen to the Player when drinking the Brew # effects: List of effect/level/duration Special potion-effect when drinking, duration in sek. # Possible Effects: https://hub.spigotmc.org/javadocs/spigot/org/bukkit/potion/PotionEffectType.html # Level or Duration ranges may be specified with a "-", ex. 'SPEED/1-2/30-40' = lvl 1 and 30 sec at worst and lvl 2 and 40 sec at best @@ -224,6 +228,7 @@ recipes: - Bedrock/1 - Brewery:Wheatbeer/2 # - ExoticGarden:Grape/3 + - ex-item/4 cookingtime: 3 distillruns: 2 distilltime: 60 @@ -239,6 +244,12 @@ recipes: - + Smells disgusting - ++ Smells alright - +++ Smells really good + servercommands: + - weather clear + playercommands: + - homes + drinkmessage: Tastes good + drinktitle: Warms you from inside effects: - FIRE_RESISTANCE/20 - HEAL/1 diff --git a/src/com/dre/brewery/BPlayer.java b/src/com/dre/brewery/BPlayer.java index cb73347..77e0d16 100644 --- a/src/com/dre/brewery/BPlayer.java +++ b/src/com/dre/brewery/BPlayer.java @@ -153,6 +153,10 @@ public class BPlayer { return false; } + if (brew.hasRecipe()) { + brew.getCurrentRecipe().applyDrinkFeatures(player); + } + int brewAlc = drinkEvent.getAddedAlcohol(); int quality = drinkEvent.getQuality(); List effects = getBrewEffects(brew.getEffects(), quality); @@ -173,7 +177,7 @@ public class BPlayer { bPlayer.quality += brewAlc; } applyEffects(effects, player, PlayerEffectEvent.EffectType.DRINK); - applyEffects(getQualityEffects(drinkEvent.getQuality(), brewAlc), player, PlayerEffectEvent.EffectType.QUALITY); + applyEffects(getQualityEffects(quality, brewAlc), player, PlayerEffectEvent.EffectType.QUALITY); if (bPlayer.drunkeness > 100) { bPlayer.drinkCap(player); diff --git a/src/com/dre/brewery/P.java b/src/com/dre/brewery/P.java index 54a68f6..d1c2d4e 100644 --- a/src/com/dre/brewery/P.java +++ b/src/com/dre/brewery/P.java @@ -524,7 +524,7 @@ public class P extends JavaPlugin { BConfig.reloader = null; } - public P getInstance() { + public static P getInstance() { return p; } diff --git a/src/com/dre/brewery/recipe/BRecipe.java b/src/com/dre/brewery/recipe/BRecipe.java index 6c620f1..00ac4b1 100644 --- a/src/com/dre/brewery/recipe/BRecipe.java +++ b/src/com/dre/brewery/recipe/BRecipe.java @@ -4,11 +4,13 @@ import com.dre.brewery.BIngredients; import com.dre.brewery.Brew; import com.dre.brewery.P; import com.dre.brewery.filedata.BConfig; +import com.dre.brewery.utility.BUtil; import com.dre.brewery.utility.Tuple; import org.apache.commons.lang.NotImplementedException; import org.bukkit.Color; import org.bukkit.Material; import org.bukkit.configuration.ConfigurationSection; +import org.bukkit.entity.Player; import org.bukkit.inventory.ItemStack; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -16,25 +18,37 @@ import org.jetbrains.annotations.Nullable; import java.util.ArrayList; import java.util.Collections; import java.util.List; +import java.util.ListIterator; public class BRecipe { private static List recipes = new ArrayList<>(); public static int numConfigRecipes; // The number of recipes in the list that are from config + // info private String[] name; + private boolean saveInData; // If this recipe should be saved in data and loaded again when the server restarts. Applicable to non-config recipes + + // brewing private List ingredients = new ArrayList<>(); // Items and amounts + private int difficulty; // difficulty to brew the potion, how exact the instruction has to be followed private int cookingTime; // time to cook in cauldron private byte distillruns; // runs through the brewer private int distillTime; // time for one distill run in seconds private byte wood; // type of wood the barrel has to consist of private int age; // time in minecraft days for the potions to age in barrels - private PotionColor color; // color of the destilled/finished potion - private int difficulty; // difficulty to brew the potion, how exact the instruction has to be followed + + // outcome + private PotionColor color; // color of the distilled/finished potion private int alcohol; // Alcohol in perfect potion private List> lore; // Custom Lore on the Potion. The int is for Quality Lore, 0 = any, 1,2,3 = Bad,Middle,Good + + // drinking private List effects = new ArrayList<>(); // Special Effects when drinking - private boolean saveInData; // If this recipe should be saved in data and loaded again when the server restarts. Applicable to non-config recipes + private List playercmds; // Commands executed as the player when drinking + private List servercmds; // Commands executed as the server when drinking + private String drinkMsg; // Message when drinking + private String drinkTitle; // Title to show when drinking private BRecipe() { } @@ -111,6 +125,29 @@ public class BRecipe { recipe.lore = loadLore(configSectionRecipes, recipeId + ".lore"); + recipe.servercmds = BUtil.loadCfgStringList(configSectionRecipes, recipeId + ".servercommands"); + recipe.playercmds = BUtil.loadCfgStringList(configSectionRecipes, recipeId + ".playercommands"); + + if (recipe.servercmds != null && !recipe.servercmds.isEmpty()) { + for (ListIterator iter = recipe.servercmds.listIterator(); iter.hasNext(); ) { + String cmd = iter.next(); + if (cmd.startsWith("/")) { + iter.set(cmd.substring(1)); + } + } + } + if (recipe.playercmds != null && !recipe.playercmds.isEmpty()) { + for (ListIterator iter = recipe.playercmds.listIterator(); iter.hasNext(); ) { + String cmd = iter.next(); + if (cmd.startsWith("/")) { + iter.set(cmd.substring(1)); + } + } + } + + recipe.drinkMsg = P.p.color(BUtil.loadCfgString(configSectionRecipes, recipeId + ".drinkmessage")); + recipe.drinkTitle = P.p.color(BUtil.loadCfgString(configSectionRecipes, recipeId + ".drinktitle")); + List effectStringList = configSectionRecipes.getStringList(recipeId + ".effects"); if (effectStringList != null) { for (String effectString : effectStringList) { @@ -245,13 +282,7 @@ public class BRecipe { @Nullable public static List> loadLore(ConfigurationSection cfg, String path) { - List load = null; - if (cfg.isString(path)) { - load = new ArrayList<>(1); - load.add(cfg.getString(path)); - } else if (cfg.isList(path)) { - load = cfg.getStringList(path); - } + List load = BUtil.loadCfgStringList(cfg, path); if (load != null) { List> lore = new ArrayList<>(load.size()); for (String line : load) { @@ -380,6 +411,25 @@ public class BRecipe { return false; } + public void applyDrinkFeatures(Player player) { + if (playercmds != null && !playercmds.isEmpty()) { + for (String cmd : playercmds) { + player.performCommand(cmd.replaceAll("%player_name%", player.getName())); + } + } + if (servercmds != null && !servercmds.isEmpty()) { + for (String cmd : servercmds) { + P.p.getServer().dispatchCommand(P.p.getServer().getConsoleSender(), cmd.replaceAll("%player_name%", player.getName())); + } + } + if (drinkMsg != null) { + player.sendMessage(drinkMsg.replaceAll("%player_name%", player.getName())); + } + if (drinkTitle != null) { + player.sendTitle("", drinkTitle.replaceAll("%player_name%", player.getName()), 10, 90, 30); + } + } + /** * Create a Potion from this Recipe with best values. Quality can be set, but will reset to 10 if put in a barrel * @@ -478,9 +528,6 @@ public class BRecipe { return false; } - - // Getters - public List getIngredients() { return ingredients; } @@ -548,6 +595,22 @@ public class BRecipe { return list; } + public List getPlayercmds() { + return playercmds; + } + + public List getServercmds() { + return servercmds; + } + + public String getDrinkMsg() { + return drinkMsg; + } + + public String getDrinkTitle() { + return drinkTitle; + } + public List getEffects() { return effects; } @@ -752,6 +815,44 @@ public class BRecipe { return this; } + /** + * Add Commands that are executed by the player on drinking + */ + public Builder addPlayerCmds(String... cmds) { + if (recipe.playercmds == null) { + recipe.playercmds = new ArrayList<>(cmds.length); + } + Collections.addAll(recipe.playercmds, cmds); + return this; + } + + /** + * Add Commands that are executed by the server on drinking + */ + public Builder addServerCmds(String... cmds) { + if (recipe.servercmds == null) { + recipe.servercmds = new ArrayList<>(cmds.length); + } + Collections.addAll(recipe.servercmds, cmds); + return this; + } + + /** + * Add Message that is sent to the player in chat when he drinks the brew + */ + public Builder drinkMsg(String msg) { + recipe.drinkMsg = msg; + return this; + } + + /** + * Add Message that is sent to the player as a small title when he drinks the brew + */ + public Builder drinkTitle(String title) { + recipe.drinkTitle = title; + return this; + } + public Builder addEffects(BEffect... effects) { Collections.addAll(recipe.effects, effects); return this; diff --git a/src/com/dre/brewery/recipe/RecipeItem.java b/src/com/dre/brewery/recipe/RecipeItem.java index 6ff6d67..9f1b216 100644 --- a/src/com/dre/brewery/recipe/RecipeItem.java +++ b/src/com/dre/brewery/recipe/RecipeItem.java @@ -2,6 +2,7 @@ package com.dre.brewery.recipe; import com.dre.brewery.P; import com.dre.brewery.filedata.BConfig; +import com.dre.brewery.utility.BUtil; import org.bukkit.Material; import org.bukkit.configuration.ConfigurationSection; import org.bukkit.inventory.ItemStack; @@ -188,14 +189,7 @@ public abstract class RecipeItem implements Cloneable { List names; List lore; - List load = null; - String path = id + ".material"; - if (cfg.isString(path)) { - load = new ArrayList<>(1); - load.add(cfg.getString(path)); - } else if (cfg.isList(path)) { - load = cfg.getStringList(path); - } + List load = BUtil.loadCfgStringList(cfg, id + ".material"); if (load != null && !load.isEmpty()) { if ((materials = loadMaterials(load)) == null) { return null; @@ -204,14 +198,7 @@ public abstract class RecipeItem implements Cloneable { materials = new ArrayList<>(0); } - load = null; - path = id + ".name"; - if (cfg.isString(path)) { - load = new ArrayList<>(1); - load.add(cfg.getString(path)); - } else if (cfg.isList(path)) { - load = cfg.getStringList(path); - } + load = BUtil.loadCfgStringList(cfg, id + ".name"); if (load != null && !load.isEmpty()) { names = load.stream().map(l -> P.p.color(l)).collect(Collectors.toList()); if (P.use1_13) { @@ -222,14 +209,7 @@ public abstract class RecipeItem implements Cloneable { names = new ArrayList<>(0); } - load = null; - path = id + ".lore"; - if (cfg.isString(path)) { - load = new ArrayList<>(1); - load.add(cfg.getString(path)); - } else if (cfg.isList(path)) { - load = cfg.getStringList(path); - } + load = BUtil.loadCfgStringList(cfg, id + ".lore"); if (load != null && !load.isEmpty()) { lore = load.stream().map(l -> P.p.color(l)).collect(Collectors.toList()); } else { diff --git a/src/com/dre/brewery/utility/BUtil.java b/src/com/dre/brewery/utility/BUtil.java index 8ba4ee5..9ce5ad2 100644 --- a/src/com/dre/brewery/utility/BUtil.java +++ b/src/com/dre/brewery/utility/BUtil.java @@ -14,6 +14,7 @@ import org.bukkit.configuration.ConfigurationSection; import org.bukkit.entity.Player; import org.bukkit.potion.PotionEffect; import org.bukkit.potion.PotionEffectType; +import org.jetbrains.annotations.Nullable; import java.io.File; import java.io.FileOutputStream; @@ -95,6 +96,37 @@ public class BUtil { effect.apply(player); } + /** + * Load A List of Strings from config. If found a single String, will convert to List + */ + @Nullable + public static List loadCfgStringList(ConfigurationSection cfg, String path) { + if (cfg.isString(path)) { + List list = new ArrayList<>(1); + list.add(cfg.getString(path)); + return list; + } else if (cfg.isList(path)) { + return cfg.getStringList(path); + } + return null; + } + + /** + * Load a String from config. If found a List, will return the first String + */ + @Nullable + public static String loadCfgString(ConfigurationSection cfg, String path) { + if (cfg.isString(path)) { + return cfg.getString(path); + } else if (cfg.isList(path)) { + List list = cfg.getStringList(path); + if (!list.isEmpty()) { + return list.get(0); + } + } + return null; + } + /* **************************************** */ /* ********* ********* */ /* ********* String Utils ********* */ From a1c01166501f1aec606efc6c4ac437bef552781d Mon Sep 17 00:00:00 2001 From: Sn0wStorm Date: Sat, 23 Nov 2019 19:59:53 +0100 Subject: [PATCH 40/51] Make Metrics work again --- src/com/dre/brewery/BIngredients.java | 1 + src/com/dre/brewery/Brew.java | 1 + src/com/dre/brewery/P.java | 43 +++++++++++----------- src/com/dre/brewery/filedata/BData.java | 29 +++++++++++++++ src/com/dre/brewery/filedata/DataSave.java | 13 +++++++ 5 files changed, 66 insertions(+), 21 deletions(-) diff --git a/src/com/dre/brewery/BIngredients.java b/src/com/dre/brewery/BIngredients.java index 660f4d4..ad0198a 100644 --- a/src/com/dre/brewery/BIngredients.java +++ b/src/com/dre/brewery/BIngredients.java @@ -173,6 +173,7 @@ public class BIngredients { } brew.save(potionMeta); potion.setItemMeta(potionMeta); + P.p.metricsForCreate(brew); return potion; } diff --git a/src/com/dre/brewery/Brew.java b/src/com/dre/brewery/Brew.java index f28f411..1a921f3 100644 --- a/src/com/dre/brewery/Brew.java +++ b/src/com/dre/brewery/Brew.java @@ -729,6 +729,7 @@ public class Brew implements Cloneable { } save(potionMeta); potion.setItemMeta(potionMeta); + P.p.metricsForCreate(this); return potion; } diff --git a/src/com/dre/brewery/P.java b/src/com/dre/brewery/P.java index d1c2d4e..aa9dbc7 100644 --- a/src/com/dre/brewery/P.java +++ b/src/com/dre/brewery/P.java @@ -44,6 +44,10 @@ public class P extends JavaPlugin { public String language; public LanguageReader languageReader; + // Metrics + public int brewsCreated; + public int exc, good, norm, bad, terr; + @Override public void onEnable() { p = this; @@ -332,30 +336,11 @@ public class P extends JavaPlugin { /*try { Metrics metrics = new Metrics(this); metrics.addCustomChart(new Metrics.SingleLineChart("drunk_players", BPlayer::numDrunkPlayers)); - metrics.addCustomChart(new Metrics.SingleLineChart("brews_in_existence", () -> Brew.potions.size())); + metrics.addCustomChart(new Metrics.SingleLineChart("brews_in_existence", () -> brewsCreated)); metrics.addCustomChart(new Metrics.SingleLineChart("barrels_built", () -> Barrel.barrels.size())); metrics.addCustomChart(new Metrics.SingleLineChart("cauldrons_boiling", () -> BCauldron.bcauldrons.size())); metrics.addCustomChart(new Metrics.AdvancedPie("brew_quality", () -> { Map map = new HashMap<>(5); - int exc = 0; - int good = 0; - int norm = 0; - int bad = 0; - int terr = 0; - for (Brew brew : Brew.potions.values()) { - if (brew.getQuality() >= 9) { - exc++; - } else if (brew.getQuality() >= 7) { - good++; - } else if (brew.getQuality() >= 5) { - norm++; - } else if (brew.getQuality() >= 3) { - bad++; - } else { - terr++; - } - } - map.put("excellent", exc); map.put("good", good); map.put("normal", norm); @@ -364,7 +349,7 @@ public class P extends JavaPlugin { return map; })); metrics.addCustomChart(new Metrics.SimplePie("number_of_recipes", () -> { - int recipes = BIngredients.recipes.size(); + int recipes = BRecipe.getAllRecipes().size(); if (recipes < 7) { return "Less than 7"; } else if (recipes < 11) { @@ -528,6 +513,22 @@ public class P extends JavaPlugin { return p; } + public void metricsForCreate(Brew brew) { + if (brewsCreated == Integer.MAX_VALUE) return; + brewsCreated++; + if (brew.getQuality() >= 9) { + exc++; + } else if (brew.getQuality() >= 7) { + good++; + } else if (brew.getQuality() >= 5) { + norm++; + } else if (brew.getQuality() >= 3) { + bad++; + } else { + terr++; + } + } + // Utility public void msg(CommandSender sender, String msg) { diff --git a/src/com/dre/brewery/filedata/BData.java b/src/com/dre/brewery/filedata/BData.java index 6ac1cfc..f65e92f 100644 --- a/src/com/dre/brewery/filedata/BData.java +++ b/src/com/dre/brewery/filedata/BData.java @@ -39,6 +39,20 @@ public class BData { Brew.loadPrevSeeds(data); + List brewsCreated = data.getIntegerList("brewsCreated"); + if (brewsCreated != null && brewsCreated.size() == 6) { + int hash = data.getInt("brewsCreatedH"); + // Check the hash to prevent tampering with statistics + if (brewsCreated.hashCode() == hash) { + P.p.brewsCreated = brewsCreated.get(0); + P.p.exc = brewsCreated.get(1); + P.p.good = brewsCreated.get(2); + P.p.norm = brewsCreated.get(3); + P.p.bad = brewsCreated.get(4); + P.p.terr = brewsCreated.get(5); + } + } + // Check if data is the newest version String version = data.getString("Version", null); if (version != null) { @@ -99,6 +113,21 @@ public class BData { } } + // Store how many legacy brews were created + if (P.p.brewsCreated <= 0) { + P.p.brewsCreated = 0; + P.p.exc = 0; + P.p.good = 0; + P.p.norm = 0; + P.p.bad = 0; + P.p.terr = 0; + if (!Brew.noLegacy()) { + for (Brew brew : Brew.legacyPotions.values()) { + P.p.metricsForCreate(brew); + } + } + } + // Remove Legacy Potions that haven't been touched in a long time, these may have been lost if (!Brew.noLegacy()) { int currentHoursAfterInstall = (int) ((double) (System.currentTimeMillis() - Brew.installTime) / 3600000D); diff --git a/src/com/dre/brewery/filedata/DataSave.java b/src/com/dre/brewery/filedata/DataSave.java index 303c14e..fe62e4d 100644 --- a/src/com/dre/brewery/filedata/DataSave.java +++ b/src/com/dre/brewery/filedata/DataSave.java @@ -2,6 +2,9 @@ package com.dre.brewery.filedata; import java.io.File; +import java.util.ArrayList; +import java.util.List; +import java.util.Objects; import com.dre.brewery.MCBarrel; import com.dre.brewery.utility.BUtil; @@ -66,6 +69,16 @@ public class DataSave extends BukkitRunnable { Brew.writePrevSeeds(configFile); + List brewsCreated = new ArrayList<>(6); + brewsCreated.add(P.p.brewsCreated); + brewsCreated.add(P.p.exc); + brewsCreated.add(P.p.good); + brewsCreated.add(P.p.norm); + brewsCreated.add(P.p.bad); + brewsCreated.add(P.p.terr); + configFile.set("brewsCreated", brewsCreated); + configFile.set("brewsCreatedH", brewsCreated.hashCode()); + if (!Brew.legacyPotions.isEmpty()) { Brew.saveLegacy(configFile.createSection("Brew")); } From 32b6c3c4b125a694ccef4f75c2b2974dbeaa9b0b Mon Sep 17 00:00:00 2001 From: Sn0wStorm Date: Sun, 24 Nov 2019 16:06:17 +0100 Subject: [PATCH 41/51] Tweaked performance of data save and campfire check --- src/com/dre/brewery/BCauldron.java | 2 +- src/com/dre/brewery/P.java | 21 +++++++++ src/com/dre/brewery/filedata/BData.java | 10 +++++ src/com/dre/brewery/filedata/DataSave.java | 43 +++++++------------ src/com/dre/brewery/filedata/ReadOldData.java | 6 +++ src/com/dre/brewery/filedata/WriteData.java | 3 ++ 6 files changed, 56 insertions(+), 29 deletions(-) diff --git a/src/com/dre/brewery/BCauldron.java b/src/com/dre/brewery/BCauldron.java index 148589c..f798934 100644 --- a/src/com/dre/brewery/BCauldron.java +++ b/src/com/dre/brewery/BCauldron.java @@ -26,7 +26,7 @@ import java.util.UUID; public class BCauldron { public static final byte EMPTY = 0, SOME = 1, FULL = 2; - private static Set plInteracted = new HashSet<>(); + private static Set plInteracted = new HashSet<>(); // Interact Event helper public static Map bcauldrons = new HashMap<>(); // All active cauldrons. Mapped to their block for fast retrieve private BIngredients ingredients = new BIngredients(); diff --git a/src/com/dre/brewery/P.java b/src/com/dre/brewery/P.java index aa9dbc7..a801b2b 100644 --- a/src/com/dre/brewery/P.java +++ b/src/com/dre/brewery/P.java @@ -15,6 +15,7 @@ import com.dre.brewery.utility.LegacyUtil; import org.apache.commons.lang.math.NumberUtils; import org.bukkit.Bukkit; import org.bukkit.ChatColor; +import org.bukkit.Material; import org.bukkit.command.CommandSender; import org.bukkit.configuration.file.FileConfiguration; import org.bukkit.event.HandlerList; @@ -315,6 +316,11 @@ public class P extends JavaPlugin { e.printStackTrace(); }*/ + if (use1_14) { + // Campfires are weird + // Initialize once now so it doesn't lag later when we check for campfires under Cauldrons + getServer().createBlockData(Material.CAMPFIRE); + } // load the Config try { @@ -575,17 +581,32 @@ public class P extends JavaPlugin { public class BreweryRunnable implements Runnable { @Override public void run() { + //long t1 = System.nanoTime(); BConfig.reloader = null; for (BCauldron cauldron : BCauldron.bcauldrons.values()) { cauldron.onUpdate();// runs every min to update cooking time } + //long t2 = System.nanoTime(); Barrel.onUpdate();// runs every min to check and update ageing time + //long t3 = System.nanoTime(); if (use1_14) MCBarrel.onUpdate(); + //long t4 = System.nanoTime(); BPlayer.onUpdate();// updates players drunkeness + //long t5 = System.nanoTime(); debugLog("Update"); + //long t6 = System.nanoTime(); DataSave.autoSave(); + //long t7 = System.nanoTime(); + + /*P.p.log("BreweryRunnable: " + + "t1: " + (t2 - t1) / 1000000.0 + "ms" + + " | t2: " + (t3 - t2) / 1000000.0 + "ms" + + " | t3: " + (t4 - t3) / 1000000.0 + "ms" + + " | t4: " + (t5 - t4) / 1000000.0 + "ms" + + " | t5: " + (t6 - t5) / 1000000.0 + "ms" + + " | t6: " + (t7 - t6) / 1000000.0 + "ms" );*/ } } diff --git a/src/com/dre/brewery/filedata/BData.java b/src/com/dre/brewery/filedata/BData.java index f65e92f..750291b 100644 --- a/src/com/dre/brewery/filedata/BData.java +++ b/src/com/dre/brewery/filedata/BData.java @@ -32,8 +32,18 @@ public class BData { File file = new File(P.p.getDataFolder(), "data.yml"); if (file.exists()) { + long t1 = System.currentTimeMillis(); + FileConfiguration data = YamlConfiguration.loadConfiguration(file); + long t2 = System.currentTimeMillis(); + + if (t2 - t1 > 5000) { + // Spigot is very slow at loading inventories from yml. Notify Admin that loading Data took long + P.p.log("Bukkit took " + (t2 - t1) / 1000.0 + "s to load the Data File,"); + P.p.log("consider switching to Paper, or have less items in Barrels"); + } + Brew.installTime = data.getLong("installTime", System.currentTimeMillis()); MCBarrel.mcBarrelTime = data.getLong("MCBarrelTime", 0); diff --git a/src/com/dre/brewery/filedata/DataSave.java b/src/com/dre/brewery/filedata/DataSave.java index fe62e4d..5a10a7d 100644 --- a/src/com/dre/brewery/filedata/DataSave.java +++ b/src/com/dre/brewery/filedata/DataSave.java @@ -1,12 +1,7 @@ package com.dre.brewery.filedata; -import java.io.File; -import java.util.ArrayList; -import java.util.List; -import java.util.Objects; - -import com.dre.brewery.MCBarrel; +import com.dre.brewery.*; import com.dre.brewery.utility.BUtil; import org.bukkit.World; import org.bukkit.configuration.ConfigurationSection; @@ -14,12 +9,8 @@ import org.bukkit.configuration.file.FileConfiguration; import org.bukkit.configuration.file.YamlConfiguration; import org.bukkit.scheduler.BukkitRunnable; -import com.dre.brewery.BCauldron; -import com.dre.brewery.BPlayer; -import com.dre.brewery.Barrel; -import com.dre.brewery.Brew; -import com.dre.brewery.P; -import com.dre.brewery.Wakeup; +import java.util.ArrayList; +import java.util.List; public class DataSave extends BukkitRunnable { @@ -42,6 +33,7 @@ public class DataSave extends BukkitRunnable { @Override public void run() { + long saveTime = System.nanoTime(); FileConfiguration oldData; if (read != null) { if (!read.done) { @@ -103,6 +95,9 @@ public class DataSave extends BukkitRunnable { configFile.set("Version", dataVersion); collected = true; + + P.p.debugLog("saving: " + ((System.nanoTime() - saveTime) / 1000000.0) + "ms"); + if (P.p.isEnabled()) { P.p.getServer().getScheduler().runTaskAsynchronously(P.p, new WriteData(configFile)); } else { @@ -126,7 +121,6 @@ public class DataSave extends BukkitRunnable { // Save all data. Takes a boolean whether all data should be collected in instantly public static void save(boolean collectInstant) { - long time = System.nanoTime(); if (running != null) { P.p.log("Another Save was started while a Save was in Progress"); if (collectInstant) { @@ -134,24 +128,17 @@ public class DataSave extends BukkitRunnable { } return; } - File datafile = new File(P.p.getDataFolder(), "data.yml"); - if (datafile.exists()) { - ReadOldData read = new ReadOldData(); - if (collectInstant) { - read.run(); - running = new DataSave(read); - running.run(); - } else { - read.runTaskAsynchronously(P.p); - running = new DataSave(read); - running.runTaskTimer(P.p, 1, 2); - } - } else { - running = new DataSave(null); + ReadOldData read = new ReadOldData(); + if (collectInstant) { + read.run(); + running = new DataSave(read); running.run(); + } else { + read.runTaskAsynchronously(P.p); + running = new DataSave(read); + running.runTaskTimer(P.p, 1, 2); } - P.p.debugLog("saving: " + ((System.nanoTime() - time) / 1000000.0) + "ms"); } public static void autoSave() { diff --git a/src/com/dre/brewery/filedata/ReadOldData.java b/src/com/dre/brewery/filedata/ReadOldData.java index ef04b7e..e24e065 100644 --- a/src/com/dre/brewery/filedata/ReadOldData.java +++ b/src/com/dre/brewery/filedata/ReadOldData.java @@ -18,6 +18,12 @@ public class ReadOldData extends BukkitRunnable { @Override public void run() { File datafile = new File(P.p.getDataFolder(), "data.yml"); + if (!datafile.exists()) { + data = new YamlConfiguration(); + done = true; + return; + } + data = YamlConfiguration.loadConfiguration(datafile); if (DataSave.lastBackup > 10) { diff --git a/src/com/dre/brewery/filedata/WriteData.java b/src/com/dre/brewery/filedata/WriteData.java index c624851..a1f5a44 100644 --- a/src/com/dre/brewery/filedata/WriteData.java +++ b/src/com/dre/brewery/filedata/WriteData.java @@ -8,6 +8,9 @@ import org.bukkit.configuration.file.FileConfiguration; import com.dre.brewery.P; +/** + * Writes the collected Data to file in Async Thread + */ public class WriteData implements Runnable { private FileConfiguration data; From 3b9f9ae26d56d5e456c0b54746ede5cd5d0e6fde Mon Sep 17 00:00:00 2001 From: Sn0wStorm Date: Sun, 24 Nov 2019 19:06:35 +0100 Subject: [PATCH 42/51] Added some more Custom Metrics Charts --- src/com/dre/brewery/BIngredients.java | 2 +- src/com/dre/brewery/BPlayer.java | 1 + src/com/dre/brewery/Brew.java | 2 +- src/com/dre/brewery/P.java | 81 +++++++++++++++++++++- src/com/dre/brewery/filedata/BData.java | 16 +++-- src/com/dre/brewery/filedata/DataSave.java | 3 +- 6 files changed, 92 insertions(+), 13 deletions(-) diff --git a/src/com/dre/brewery/BIngredients.java b/src/com/dre/brewery/BIngredients.java index ad0198a..5d56e49 100644 --- a/src/com/dre/brewery/BIngredients.java +++ b/src/com/dre/brewery/BIngredients.java @@ -173,7 +173,7 @@ public class BIngredients { } brew.save(potionMeta); potion.setItemMeta(potionMeta); - P.p.metricsForCreate(brew); + P.p.metricsForCreate(false); return potion; } diff --git a/src/com/dre/brewery/BPlayer.java b/src/com/dre/brewery/BPlayer.java index 77e0d16..289fd7c 100644 --- a/src/com/dre/brewery/BPlayer.java +++ b/src/com/dre/brewery/BPlayer.java @@ -156,6 +156,7 @@ public class BPlayer { if (brew.hasRecipe()) { brew.getCurrentRecipe().applyDrinkFeatures(player); } + P.p.metricsForDrink(brew); int brewAlc = drinkEvent.getAddedAlcohol(); int quality = drinkEvent.getQuality(); diff --git a/src/com/dre/brewery/Brew.java b/src/com/dre/brewery/Brew.java index 1a921f3..5b0d811 100644 --- a/src/com/dre/brewery/Brew.java +++ b/src/com/dre/brewery/Brew.java @@ -729,7 +729,7 @@ public class Brew implements Cloneable { } save(potionMeta); potion.setItemMeta(potionMeta); - P.p.metricsForCreate(this); + P.p.metricsForCreate(true); return potion; } diff --git a/src/com/dre/brewery/P.java b/src/com/dre/brewery/P.java index a801b2b..c5632ad 100644 --- a/src/com/dre/brewery/P.java +++ b/src/com/dre/brewery/P.java @@ -13,6 +13,7 @@ import com.dre.brewery.recipe.BRecipe; import com.dre.brewery.utility.BUtil; import com.dre.brewery.utility.LegacyUtil; import org.apache.commons.lang.math.NumberUtils; +import org.bstats.bukkit.Metrics; import org.bukkit.Bukkit; import org.bukkit.ChatColor; import org.bukkit.Material; @@ -22,6 +23,8 @@ import org.bukkit.event.HandlerList; import org.bukkit.plugin.java.JavaPlugin; import java.io.File; +import java.util.HashMap; +import java.util.Map; public class P extends JavaPlugin { public static P p; @@ -47,7 +50,8 @@ public class P extends JavaPlugin { // Metrics public int brewsCreated; - public int exc, good, norm, bad, terr; + public int brewsCreatedCmd; // Created by command + public int exc, good, norm, bad, terr; // Brews drunken with quality @Override public void onEnable() { @@ -346,7 +350,7 @@ public class P extends JavaPlugin { metrics.addCustomChart(new Metrics.SingleLineChart("barrels_built", () -> Barrel.barrels.size())); metrics.addCustomChart(new Metrics.SingleLineChart("cauldrons_boiling", () -> BCauldron.bcauldrons.size())); metrics.addCustomChart(new Metrics.AdvancedPie("brew_quality", () -> { - Map map = new HashMap<>(5); + Map map = new HashMap<>(8); map.put("excellent", exc); map.put("good", good); map.put("normal", norm); @@ -354,6 +358,13 @@ public class P extends JavaPlugin { map.put("terrible", terr); return map; })); + metrics.addCustomChart(new Metrics.AdvancedPie("brews_created", () -> { + Map map = new HashMap<>(4); + map.put("by command", brewsCreatedCmd); + map.put("brewing", brewsCreated - brewsCreatedCmd); + return map; + })); + metrics.addCustomChart(new Metrics.SimplePie("number_of_recipes", () -> { int recipes = BRecipe.getAllRecipes().size(); if (recipes < 7) { @@ -374,6 +385,63 @@ public class P extends JavaPlugin { } })); + metrics.addCustomChart(new Metrics.SimplePie("v2_mc_version", () -> { + String mcv = Bukkit.getBukkitVersion(); + mcv = mcv.substring(0, mcv.indexOf('.', 2)); + if (mcv.matches("^\\d\\.\\d{1,2}$")) { + // Start, digit, dot, 1-2 digits, end + return mcv; + } else { + return "undef"; + } + })); + metrics.addCustomChart(new Metrics.DrilldownPie("plugin_mc_version", () -> { + Map> map = new HashMap<>(3); + String mcv = Bukkit.getBukkitVersion(); + mcv = mcv.substring(0, mcv.indexOf('.', 2)); + if (mcv.matches("^\\d\\.\\d{1,2}$")) { + // Start, digit, dot, 1-2 digits, end + mcv = "MC " + mcv; + } else { + mcv = "undef"; + } + Map innerMap = new HashMap<>(3); + innerMap.put(mcv, 1); + map.put(getDescription().getVersion(), innerMap); + return map; + })); + metrics.addCustomChart(new Metrics.SimplePie("language", () -> language)); + metrics.addCustomChart(new Metrics.SimplePie("config_scramble", () -> BConfig.enableEncode ? "enabled" : "disabled")); + metrics.addCustomChart(new Metrics.SimplePie("config_lore_color", () -> { + if (BConfig.colorInBarrels) { + if (BConfig.colorInBrewer) { + return "both"; + } else { + return "in barrels"; + } + } else { + if (BConfig.colorInBrewer) { + return "in distiller"; + } else { + return "none"; + } + } + })); + metrics.addCustomChart(new Metrics.SimplePie("config_always_show", () -> { + if (BConfig.alwaysShowQuality) { + if (BConfig.alwaysShowAlc) { + return "both"; + } else { + return "quality stars"; + } + } else { + if (BConfig.alwaysShowAlc) { + return "alc content"; + } else { + return "none"; + } + } + })); } catch (Throwable e) { e.printStackTrace(); }*/ @@ -519,9 +587,16 @@ public class P extends JavaPlugin { return p; } - public void metricsForCreate(Brew brew) { + public void metricsForCreate(boolean byCmd) { if (brewsCreated == Integer.MAX_VALUE) return; brewsCreated++; + if (byCmd) { + if (brewsCreatedCmd == Integer.MAX_VALUE) return; + brewsCreatedCmd++; + } + } + + public void metricsForDrink(Brew brew) { if (brew.getQuality() >= 9) { exc++; } else if (brew.getQuality() >= 7) { diff --git a/src/com/dre/brewery/filedata/BData.java b/src/com/dre/brewery/filedata/BData.java index 750291b..0ddb8b9 100644 --- a/src/com/dre/brewery/filedata/BData.java +++ b/src/com/dre/brewery/filedata/BData.java @@ -50,16 +50,17 @@ public class BData { Brew.loadPrevSeeds(data); List brewsCreated = data.getIntegerList("brewsCreated"); - if (brewsCreated != null && brewsCreated.size() == 6) { + if (brewsCreated != null && brewsCreated.size() == 7) { int hash = data.getInt("brewsCreatedH"); // Check the hash to prevent tampering with statistics if (brewsCreated.hashCode() == hash) { P.p.brewsCreated = brewsCreated.get(0); - P.p.exc = brewsCreated.get(1); - P.p.good = brewsCreated.get(2); - P.p.norm = brewsCreated.get(3); - P.p.bad = brewsCreated.get(4); - P.p.terr = brewsCreated.get(5); + P.p.brewsCreatedCmd = brewsCreated.get(1); + P.p.exc = brewsCreated.get(2); + P.p.good = brewsCreated.get(3); + P.p.norm = brewsCreated.get(4); + P.p.bad = brewsCreated.get(5); + P.p.terr = brewsCreated.get(6); } } @@ -126,6 +127,7 @@ public class BData { // Store how many legacy brews were created if (P.p.brewsCreated <= 0) { P.p.brewsCreated = 0; + P.p.brewsCreatedCmd = 0; P.p.exc = 0; P.p.good = 0; P.p.norm = 0; @@ -133,7 +135,7 @@ public class BData { P.p.terr = 0; if (!Brew.noLegacy()) { for (Brew brew : Brew.legacyPotions.values()) { - P.p.metricsForCreate(brew); + P.p.metricsForCreate(false); } } } diff --git a/src/com/dre/brewery/filedata/DataSave.java b/src/com/dre/brewery/filedata/DataSave.java index 5a10a7d..5c3dfa3 100644 --- a/src/com/dre/brewery/filedata/DataSave.java +++ b/src/com/dre/brewery/filedata/DataSave.java @@ -61,8 +61,9 @@ public class DataSave extends BukkitRunnable { Brew.writePrevSeeds(configFile); - List brewsCreated = new ArrayList<>(6); + List brewsCreated = new ArrayList<>(7); brewsCreated.add(P.p.brewsCreated); + brewsCreated.add(P.p.brewsCreatedCmd); brewsCreated.add(P.p.exc); brewsCreated.add(P.p.good); brewsCreated.add(P.p.norm); From a5f73ceacc76346281ee1f71463f86d8b13d8670 Mon Sep 17 00:00:00 2001 From: Sn0wStorm Date: Mon, 25 Nov 2019 15:36:48 +0100 Subject: [PATCH 43/51] Inline updater for Language file --- resources/languages/de.yml | 7 +- resources/languages/en.yml | 5 +- src/com/dre/brewery/P.java | 3 - src/com/dre/brewery/filedata/BConfig.java | 2 +- .../dre/brewery/filedata/LanguageReader.java | 203 +++++------------- .../brewery/listeners/CommandListener.java | 4 +- 6 files changed, 65 insertions(+), 159 deletions(-) diff --git a/resources/languages/de.yml b/resources/languages/de.yml index f2ea098..366ba89 100644 --- a/resources/languages/de.yml +++ b/resources/languages/de.yml @@ -1,15 +1,15 @@ # Brew Brew_-times: -fach -Brew_BadPotion: Verdorbenes Getränk +Brew_BadPotion: Verdorbenes Gebräu Brew_BarrelRiped: Fassgereift -Brew_DistillUndefined: Undefinierbares Destillat +Brew_DistillUndefined: Graues Destillat Brew_Distilled: Destilliert Brew_HundredsOfYears: Hunderte Jahre Brew_Ingredients: Zutaten Brew_MinutePluralPostfix: n Brew_OneYear: Ein Jahr Brew_ThickBrew: Schlammiger Sud -Brew_Undefined: Undefinierbarer Sud +Brew_Undefined: Kesselsud Brew_Woodtype: Holzart Brew_Years: Jahre Brew_fermented: gegärt @@ -23,6 +23,7 @@ CMD_Info_NotDrunk: '&v1 ist nicht betrunken' CMD_Player: '&a&v1 ist nun &6&v2% &abetrunken, mit einer Qualität von &6&v3' CMD_Player_Error: '&cDie Qualität muss zwischen 1 und 10 liegen!' CMD_Reload: '&aConfig wurde neu eingelesen' +CMD_Created: '&aTrank erstellt' CMD_Configname: '&aName für Config ist: &f&v1' CMD_Configname_Error: '&cDu hast kein Item in der Hand' CMD_UnLabel: '&aDas Label wurde entfernt' diff --git a/resources/languages/en.yml b/resources/languages/en.yml index 6baef83..b328e82 100644 --- a/resources/languages/en.yml +++ b/resources/languages/en.yml @@ -2,14 +2,14 @@ Brew_-times: -times Brew_BadPotion: Ruined Potion Brew_BarrelRiped: Barrel aged -Brew_DistillUndefined: Indefinable Distillate +Brew_DistillUndefined: Murky Distillate Brew_Distilled: Distilled Brew_HundredsOfYears: Hundreds of Years Brew_Ingredients: Ingredients Brew_MinutePluralPostfix: s Brew_OneYear: One Year Brew_ThickBrew: Muddy Brew -Brew_Undefined: Indefinable Brew +Brew_Undefined: Cauldron Brew Brew_Woodtype: Woodtype Brew_Years: Years Brew_fermented: fermented @@ -24,6 +24,7 @@ CMD_NonStatic: '&ePotion is not static anymore and will normally age in barrels. CMD_Player: '&a&v1 is now &6&v2% &adrunk, with a quality of &6&v3' CMD_Player_Error: '&cThe quality has to be between 1 and 10!' CMD_Reload: '&aConfig was successfully reloaded' +CMD_Created: '&aBrew Created' CMD_Configname: '&aName for the Config is: &f&v1' CMD_Configname_Error: '&cCould not find item in your hand' CMD_Static: '&aPotion is now static and will not change in barrels or brewing stands.' diff --git a/src/com/dre/brewery/P.java b/src/com/dre/brewery/P.java index c5632ad..e48ba79 100644 --- a/src/com/dre/brewery/P.java +++ b/src/com/dre/brewery/P.java @@ -565,9 +565,6 @@ public class P extends JavaPlugin { return; } - // load LanguageReader - languageReader = new LanguageReader(new File(p.getDataFolder(), "languages/" + language + ".yml")); - // Reload Recipes boolean successful = true; for (Brew brew : Brew.legacyPotions.values()) { diff --git a/src/com/dre/brewery/filedata/BConfig.java b/src/com/dre/brewery/filedata/BConfig.java index 970a890..e63def2 100644 --- a/src/com/dre/brewery/filedata/BConfig.java +++ b/src/com/dre/brewery/filedata/BConfig.java @@ -148,7 +148,7 @@ public class BConfig { p.language = config.getString("language", "en"); // Load LanguageReader - p.languageReader = new LanguageReader(new File(p.getDataFolder(), "languages/" + p.language + ".yml")); + p.languageReader = new LanguageReader(new File(p.getDataFolder(), "languages/" + p.language + ".yml"), "languages/" + p.language + ".yml"); // Has to config still got old materials boolean oldMat = config.getBoolean("oldMat", false); diff --git a/src/com/dre/brewery/filedata/LanguageReader.java b/src/com/dre/brewery/filedata/LanguageReader.java index c9a8811..2b2655b 100644 --- a/src/com/dre/brewery/filedata/LanguageReader.java +++ b/src/com/dre/brewery/filedata/LanguageReader.java @@ -1,26 +1,26 @@ package com.dre.brewery.filedata; -import java.io.File; -import java.io.IOException; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.Set; - -import com.dre.brewery.utility.Tuple; +import com.dre.brewery.P; +import org.bukkit.configuration.InvalidConfigurationException; import org.bukkit.configuration.file.FileConfiguration; import org.bukkit.configuration.file.YamlConfiguration; +import java.io.BufferedReader; +import java.io.File; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.util.HashMap; +import java.util.Map; +import java.util.Objects; +import java.util.Set; + public class LanguageReader { private Map entries = new HashMap<>(128); private File file; - private boolean changed; - - public LanguageReader(File file) { - List> defaults = getDefaults(); + public LanguageReader(File file, String defaultPath) { /* Load */ this.file = file; @@ -32,151 +32,56 @@ public class LanguageReader { } /* Check */ - check(defaults); - if (changed) { - save(); - } + check(defaultPath); } - private List> getDefaults() { - List> defaults = new ArrayList<>(128); - - /* Player */ - defaults.add(new Tuple<>("Player_BarrelCreated", "Barrel created")); - defaults.add(new Tuple<>("Player_BarrelFull", "&cThis barrel can''t hold any more drinks")); - defaults.add(new Tuple<>("Player_CauldronInfo1", "This cauldron has been boiling for &v1 minutes.")); - defaults.add(new Tuple<>("Player_CauldronInfo2", "This cauldron has just started boiling.")); - defaults.add(new Tuple<>("Player_CantDrink", "You can't drink any more.")); - defaults.add(new Tuple<>("Player_DrunkPassOut", "You drank too much and passed out.")); - defaults.add(new Tuple<>("Player_LoginDeny", "Your character tries to log in, but is too drunk to find the server. Try again!")); - defaults.add(new Tuple<>("Player_LoginDenyLong", "Your character is really drunk and has passed out. Try again in 10 minutes!")); - defaults.add(new Tuple<>("Player_Wake", "Ohh no! I cannot remember how I got here...")); - defaults.add(new Tuple<>("Player_WakeCreated", "&aWakeup Point with id: &6&v1 &awas created successfully!")); - defaults.add(new Tuple<>("Player_WakeNotExist", "&cThe Wakeup Point with the id: &6&v1 &cdoesn't exist!")); - defaults.add(new Tuple<>("Player_WakeDeleted", "&aThe Wakeup Point with the id: &6&v1 &awas successfully deleted!")); - defaults.add(new Tuple<>("Player_WakeAlreadyDeleted", "&cThe Wakeup Point with the id: &6&v1 &chas already been deleted!")); - defaults.add(new Tuple<>("Player_WakeFilled", "&cThe Wakeup Point with the id: &6&v1&c at position &6&v2 &v3, &v4, &v5&c is filled with Blocks!")); - defaults.add(new Tuple<>("Player_WakeNoPoints", "&cThere are no Wakeup Points!")); - defaults.add(new Tuple<>("Player_WakeLast", "&aThis was the last Wakeup Point")); - defaults.add(new Tuple<>("Player_WakeTeleport", "Teleport to Wakeup Point with the id: &6&v1&f At position: &6&v2 &v3, &v4, &v5")); - defaults.add(new Tuple<>("Player_WakeHint1", "To Next Wakeup Point: Punch your fist in the air")); - defaults.add(new Tuple<>("Player_WakeHint2", "To Cancel: &9/br wakeup cancel")); - defaults.add(new Tuple<>("Player_WakeCancel", "&6Wakeup Point Check was cancelled")); - defaults.add(new Tuple<>("Player_WakeNoCheck", "&cNo Wakeup Point Check is currently active")); - defaults.add(new Tuple<>("Player_TriedToSay", "&v1 tried to say: &0&v2")); - - /* Brew */ - defaults.add(new Tuple<>("Brew_Distilled", "Distilled")); - defaults.add(new Tuple<>("Brew_BarrelRiped", "Barrel aged")); - defaults.add(new Tuple<>("Brew_Undefined", "Indefinable Brew")); - defaults.add(new Tuple<>("Brew_DistillUndefined", "Indefinable Distillate")); - defaults.add(new Tuple<>("Brew_BadPotion", "Ruined Potion")); - defaults.add(new Tuple<>("Brew_Ingredients", "Ingredients")); - defaults.add(new Tuple<>("Brew_minute", "minute")); - defaults.add(new Tuple<>("Brew_MinutePluralPostfix", "s")); - defaults.add(new Tuple<>("Brew_fermented", "fermented")); - defaults.add(new Tuple<>("Brew_-times", "-times")); - defaults.add(new Tuple<>("Brew_OneYear", "One Year")); - defaults.add(new Tuple<>("Brew_Years", "Years")); - defaults.add(new Tuple<>("Brew_HundredsOfYears", "Hundreds of Years")); - defaults.add(new Tuple<>("Brew_Woodtype", "Woodtype")); - defaults.add(new Tuple<>("Brew_ThickBrew", "Muddy Brew")); - defaults.add(new Tuple<>("Brew_Alc", "Alc &v1ml")); - - /* Commands */ - defaults.add(new Tuple<>("CMD_Reload", "&aConfig was successfully reloaded")); - defaults.add(new Tuple<>("CMD_Configname", "&aName for the Config is: &f&v1")); - defaults.add(new Tuple<>("CMD_Configname_Error", "&cCould not find item in your hand")); - defaults.add(new Tuple<>("CMD_Player", "&a&v1 is now &6&v2% &adrunk, with a quality of &6&v3")); - defaults.add(new Tuple<>("CMD_Player_Error", "&cThe quality has to be between 1 and 10!")); - defaults.add(new Tuple<>("CMD_Info_NotDrunk", "&v1 is not drunk")); - defaults.add(new Tuple<>("CMD_Info_Drunk", "&v1 is &6&v2% &fdrunk, with a quality of &6&v3")); - defaults.add(new Tuple<>("CMD_UnLabel", "&aLabel removed!")); - defaults.add(new Tuple<>("CMD_Copy_Error", "&6&v1 &cPotions did not fit into your inventory")); - defaults.add(new Tuple<>("CMD_Static", "&aPotion is now static and will not change in barrels or brewing stands.")); - defaults.add(new Tuple<>("CMD_NonStatic", "&ePotion is not static anymore and will normally age in barrels.")); - - /* Error */ - defaults.add(new Tuple<>("Error_UnknownCommand", "Unknown Command")); - defaults.add(new Tuple<>("Error_ShowHelp", "Use &6/brew help &fto display the help")); - defaults.add(new Tuple<>("Error_PlayerCommand", "&cThis command can only be executed as a player!")); - defaults.add(new Tuple<>("Error_ItemNotPotion", "&cThe item in your hand could not be identified as a potion!")); - defaults.add(new Tuple<>("Error_NoBrewName", "&cNo Recipe with Name: '&v1&c' found!")); - defaults.add(new Tuple<>("Error_Recipeload", "&cNot all recipes could be restored: More information in the server log!")); - defaults.add(new Tuple<>("Error_ConfigUpdate", "Unknown Brewery config version: v&v1, config was not updated!")); - defaults.add(new Tuple<>("Error_YmlRead", "Could not read File config.yml, please make sure the file is in valid yml format (correct spaces etc.)")); - - /* Permissions */ - defaults.add(new Tuple<>("Error_NoPermissions", "&cYou don't have permissions to do this!")); - defaults.add(new Tuple<>("Error_NoBarrelAccess", "&cYou don't have permissions to access this barrel!")); - defaults.add(new Tuple<>("Perms_NoBarrelCreate", "&cYou don't have permissions to create barrels!")); - defaults.add(new Tuple<>("Perms_NoSmallBarrelCreate", "&cYou don't have permissions to create small barrels!")); - defaults.add(new Tuple<>("Perms_NoBigBarrelCreate", "&cYou don't have permissions to create big barrels!")); - defaults.add(new Tuple<>("Perms_NoCauldronInsert", "&cYou don't have permissions to put ingredients into cauldrons!")); - defaults.add(new Tuple<>("Perms_NoCauldronFill", "&cYou don't have permissions to fill bottles from this cauldron!")); - - /* Help */ - defaults.add(new Tuple<>("Help_Help", "&6/brew help [Page] &9Shows a specific help-page")); - defaults.add(new Tuple<>("Help_Player", "&6/brew <%Drunkeness> [Quality]&9 Sets Drunkeness (and Quality) of a Player")); - defaults.add(new Tuple<>("Help_Info", "&6/brew info&9 Displays your current Drunkeness and Quality")); - defaults.add(new Tuple<>("Help_UnLabel", "&6/brew unlabel &9Removes the detailled label of a potion")); - defaults.add(new Tuple<>("Help_Copy", "&6/brew copy [Quantity]>&9 Copies the potion in your hand")); - defaults.add(new Tuple<>("Help_Delete", "&6/brew delete &9Deletes the potion in your hand")); - defaults.add(new Tuple<>("Help_InfoOther", "&6/brew info [Player]&9 Displays the current Drunkeness and Quality of [Player]")); - defaults.add(new Tuple<>("Help_Wakeup", "&6/brew wakeup list &9 Lists all wakeup points")); - defaults.add(new Tuple<>("Help_WakeupList", "&6/brew wakeup list [World]&9 Lists all wakeup points of [world]")); - defaults.add(new Tuple<>("Help_WakeupCheck", "&6/brew wakeup check &9Teleports to all wakeup points")); - defaults.add(new Tuple<>("Help_WakeupCheckSpecific", "&6/brew wakeup check &9Teleports to the wakeup point with ")); - defaults.add(new Tuple<>("Help_WakeupAdd", "&6/brew wakeup add &9Adds a wakeup point at your current position")); - defaults.add(new Tuple<>("Help_WakeupRemove", "&6/brew wakeup remove &9Removes the wakeup point with ")); - defaults.add(new Tuple<>("Help_Reload", "&6/brew reload &9Reload config")); - defaults.add(new Tuple<>("Help_Configname", "&6/brew ItemName &9Display name of item in hand for the config")); - defaults.add(new Tuple<>("Help_Static", "&6/brew static &9Make Brew static -> No further ageing or distilling")); - defaults.add(new Tuple<>("Help_Create", "&6/brew create [Quality] [Player] &9Create a Brew with optional quality (1-10)")); - - /* Etc. */ - defaults.add(new Tuple<>("Etc_Usage", "Usage:")); - defaults.add(new Tuple<>("Etc_Page", "Page")); - defaults.add(new Tuple<>("Etc_Barrel", "Barrel")); - - return defaults; - } - - private void check(List> defaults) { - for (Tuple def : defaults) { - if (!entries.containsKey(def.a())) { - entries.put(def.a(), def.b()); - changed = true; + private void check(String defaultPath) { + FileConfiguration defaults = null; + ConfigUpdater updater = null; + int i = 0; + String line; + InputStream resource = P.p.getResource(defaultPath); + if (resource == null) return; + try (BufferedReader reader = new BufferedReader(new InputStreamReader(resource))) { + while ((line = reader.readLine()) != null) { + int index = line.indexOf(':'); + if (index != -1) { + line = line.substring(0, index); + if (!entries.containsKey(line)) { + if (defaults == null) { + defaults = new YamlConfiguration(); + defaults.load(new BufferedReader(new InputStreamReader(Objects.requireNonNull(P.p.getResource(defaultPath))))); + updater = new ConfigUpdater(file); + } + entries.put(line, defaults.getString(line)); + updater.addLines(i, line + ": '" + entries.get(line) + "'"); + } + } + i++; } + if (updater != null) { + createBackup(); + updater.saveConfig(); + P.p.log("Language file updated"); + } + } catch (IOException | InvalidConfigurationException e) { + e.printStackTrace(); + P.p.errorLog("Language File could not be updated"); } } @SuppressWarnings("ResultOfMethodCallIgnored") - private void save() { - if (changed) { - /* Copy old File */ - File source = new File(file.getPath()); - String filePath = file.getPath(); - File temp = new File(filePath.substring(0, filePath.length() - 4) + "_old.yml"); + private void createBackup() { + /* Copy old File */ + File source = new File(file.getPath()); + String filePath = file.getPath(); + File backup = new File(filePath.substring(0, filePath.length() - 4) + "_old.yml"); - if (temp.exists()) - temp.delete(); - - source.renameTo(temp); - - /* Save */ - FileConfiguration configFile = new YamlConfiguration(); - - for (String key : entries.keySet()) { - configFile.set(key, entries.get(key)); - } - - try { - configFile.save(file); - } catch (IOException e) { - e.printStackTrace(); - } + if (backup.exists()) { + backup.delete(); } + + source.renameTo(backup); } public String get(String key, String... args) { diff --git a/src/com/dre/brewery/listeners/CommandListener.java b/src/com/dre/brewery/listeners/CommandListener.java index e757533..9a3c3c7 100644 --- a/src/com/dre/brewery/listeners/CommandListener.java +++ b/src/com/dre/brewery/listeners/CommandListener.java @@ -12,6 +12,7 @@ import org.bukkit.command.CommandSender; import org.bukkit.entity.Player; import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.meta.ItemMeta; +import org.jetbrains.annotations.NotNull; import java.util.ArrayList; import java.util.Locale; @@ -21,7 +22,7 @@ public class CommandListener implements CommandExecutor { public P p = P.p; @Override - public boolean onCommand(CommandSender sender, Command command, String label, String[] args) { + public boolean onCommand(@NotNull CommandSender sender, @NotNull Command command, @NotNull String label, @NotNull String[] args) { String cmd = "help"; if (args.length > 0) { @@ -560,6 +561,7 @@ public class CommandListener implements CommandExecutor { ItemStack item = recipe.create(quality); if (item != null) { player.getInventory().addItem(item); + p.msg(sender, p.languageReader.get("CMD_Created")); } } else { p.msg(sender, p.languageReader.get("Error_NoBrewName", name)); From c287b6350ff6687791cb950910cb8af917b45523 Mon Sep 17 00:00:00 2001 From: Sn0wStorm Date: Mon, 25 Nov 2019 20:28:08 +0100 Subject: [PATCH 44/51] Moved some test code, optimized Distiller --- resources/config/v13/de/config.yml | 3 + resources/config/v13/en/config.yml | 3 + src/com/dre/brewery/BDistiller.java | 42 +- src/com/dre/brewery/P.java | 476 +++++------------- src/com/dre/brewery/api/BreweryApi.java | 7 +- src/com/dre/brewery/filedata/BData.java | 4 +- .../brewery/listeners/InventoryListener.java | 72 +-- test/com/dre/brewery/RecipeTests.java | 314 ++++++++++++ 8 files changed, 476 insertions(+), 445 deletions(-) diff --git a/resources/config/v13/de/config.yml b/resources/config/v13/de/config.yml index e8821a8..be39ba1 100644 --- a/resources/config/v13/de/config.yml +++ b/resources/config/v13/de/config.yml @@ -76,6 +76,9 @@ updateCheck: true # Autosave Intervall in Minuten [3] autosave: 3 +# Debug Nachrichten im Log anzeigen [false] +debug: false + # Config Version version: '1.8' diff --git a/resources/config/v13/en/config.yml b/resources/config/v13/en/config.yml index 4da7fce..2704767 100644 --- a/resources/config/v13/en/config.yml +++ b/resources/config/v13/en/config.yml @@ -77,6 +77,9 @@ updateCheck: true # Autosave interval in minutes [3] autosave: 3 +# Debug Nachrichten im Log anzeigen [false] +debug: false + # Config Version version: '1.8' diff --git a/src/com/dre/brewery/BDistiller.java b/src/com/dre/brewery/BDistiller.java index 0c0c757..da7e2ba 100644 --- a/src/com/dre/brewery/BDistiller.java +++ b/src/com/dre/brewery/BDistiller.java @@ -84,11 +84,23 @@ public class BDistiller { return contents; } - public static byte hasBrew(BrewerInventory brewer) { + public static void checkContents(BrewerInventory inv, Brew[] contents) { + ItemStack item; + for (int slot = 0; slot < 3; slot++) { + if (contents[slot] != null) { + item = inv.getItem(slot); + if (item == null || !Brew.isBrew(item)) { + contents[slot] = null; + } + } + } + } + + public static byte hasBrew(BrewerInventory brewer, Brew[] contents) { ItemStack item = brewer.getItem(3); // ingredient boolean glowstone = (item != null && Material.GLOWSTONE_DUST == item.getType()); // need dust in the top slot. byte customFound = 0; - for (Brew brew : getDistillContents(brewer)) { + for (Brew brew : contents) { if (brew != null) { if (!glowstone) { return 1; @@ -103,9 +115,8 @@ public class BDistiller { return customFound; } - public static boolean runDistill(BrewerInventory inv) { + public static boolean runDistill(BrewerInventory inv, Brew[] contents) { boolean custom = false; - Brew[] contents = getDistillContents(inv); for (int slot = 0; slot < 3; slot++) { if (contents[slot] == null) continue; if (contents[slot].canDistill()) { @@ -122,10 +133,9 @@ public class BDistiller { return false; } - public static int getLongestDistillTime(BrewerInventory inv) { + public static int getLongestDistillTime(Brew[] contents) { int bestTime = 0; int time; - Brew[] contents = getDistillContents(inv); for (int slot = 0; slot < 3; slot++) { if (contents[slot] == null) continue; time = contents[slot].getDistillTimeNextRun(); @@ -143,8 +153,7 @@ public class BDistiller { return 800; } - public static void showAlc(BrewerInventory inv) { - Brew[] contents = getDistillContents(inv); + public static void showAlc(BrewerInventory inv, Brew[] contents) { for (int slot = 0; slot < 3; slot++) { if (contents[slot] != null) { // Show Alc in lore @@ -159,6 +168,7 @@ public class BDistiller { } public class DistillRunnable extends BukkitRunnable { + Brew[] contents = null; @Override public void run() { @@ -166,7 +176,13 @@ public class BDistiller { if (now instanceof BrewingStand) { BrewingStand stand = (BrewingStand) now; if (brewTime == -1) { // only check at the beginning (and end) for distillables - switch (hasBrew(stand.getInventory())) { + BrewerInventory inventory = stand.getInventory(); + if (contents == null) { + contents = getDistillContents(inventory); + } else { + checkContents(inventory, contents); + } + switch (hasBrew(inventory, contents)) { case 1: // Custom potion but not for distilling. Stop any brewing and cancel this task if (stand.getBrewingTime() > 0) { @@ -187,11 +203,11 @@ public class BDistiller { // No custom potion, cancel and ignore this.cancel(); trackedDistillers.remove(standBlock); - showAlc(stand.getInventory()); + showAlc(inventory, contents); P.p.debugLog("nothing to distill"); return; default: - runTime = getLongestDistillTime(stand.getInventory()); + runTime = getLongestDistillTime(contents); brewTime = runTime; P.p.debugLog("using brewtime: " + runTime); @@ -202,10 +218,10 @@ public class BDistiller { stand.setBrewingTime((int) ((float) brewTime / ((float) runTime / (float) DISTILLTIME)) + 1); if (brewTime <= 1) { // Done! + checkContents(stand.getInventory(), contents); stand.setBrewingTime(0); stand.update(); - BrewerInventory brewer = stand.getInventory(); - if (!runDistill(brewer)) { + if (!runDistill(stand.getInventory(), contents)) { this.cancel(); trackedDistillers.remove(standBlock); P.p.debugLog("All done distilling"); diff --git a/src/com/dre/brewery/P.java b/src/com/dre/brewery/P.java index e48ba79..64c882e 100644 --- a/src/com/dre/brewery/P.java +++ b/src/com/dre/brewery/P.java @@ -72,254 +72,6 @@ public class P extends JavaPlugin { useNBT = true; } - //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(); - } catch (InvalidKeyException e) { - e.printStackTrace(); - } finally { - try { - data.close(); - if (dataIn != null) { - dataIn.close(); - } - } catch (IOException e) { - e.printStackTrace(); - } - }*/ - - /*try { - ItemMeta meta = new ItemStack(Material.POTION).getItemMeta(); - DataOutputStream data = new DataOutputStream(new Base91EncoderStream(new LoreSaveStream(meta, 3))); - - data.writeInt(2); - data.writeLong(5); - - byte[] test = new byte[128]; - test[1] = 6; - test[2] = 12; - test[3] = 21; - test[127] = 99; - data.write(test); - - data.writeInt(123324); - data.writeLong(12343843); - - data.close(); - meta.getLore(); - - DataInputStream dataIn = new DataInputStream(new Base91DecoderStream(new LoreLoadStream(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]); - - P.p.log(dataIn.readInt() + ", " + dataIn.readLong() + ", "); - - dataIn.close(); - - - - basE91 basE91 = new basE91(); - int[] input = new int[] {12, 65, 324, 5, 12, 129459, 1234567, Integer.MIN_VALUE, Integer.MAX_VALUE}; - ByteArrayOutputStream stream = new ByteArrayOutputStream(); - DataOutputStream data = new DataOutputStream(stream); - for (int i = 0; i < input.length; i++) { - data.writeInt(input[i]); - } - data.flush(); - data.close(); - byte[] in = stream.toByteArray(); - byte[] out = new byte[4096]; - int lenght = basE91.encode(in, in.length, out); - basE91.encEnd(out); - String done = new String(out, 0, lenght); - - byte[] tin = done.getBytes(); - - byte[] tout = new byte[4096]; - lenght = basE91.decode(tin, tin.length, tout); - basE91.decEnd(tout); - - - ByteArrayInputStream tstream = new ByteArrayInputStream(tout, 0, lenght); - DataInputStream tdata = new DataInputStream(tstream); - int[] test = new int[4096]; - for (int j = 0; j < 6; j++) { - if (tstream.available() <= 0) break; - test[j] = tdata.readInt(); - - } - tdata.close(); - test = test;*/ - - - - /*basE91 basE91 = new basE91(); - int[] input = new int[] {12, 65, 324, 5, 12, 129459, 1234567, Integer.MIN_VALUE, Integer.MAX_VALUE}; - ByteArrayOutputStream stream = new ByteArrayOutputStream(); - DataOutputStream data = new DataOutputStream(stream); - for (int i = 0; i < input.length; i++) { - data.writeInt(input[i]); - } - data.flush(); - data.close(); - ByteArrayOutputStream out = new ByteArrayOutputStream(); - ByteArrayInputStream in = new ByteArrayInputStream(stream.toByteArray()); - - encode(in, out, in.available()); - - in.close(); - out.flush(); - out.close(); - - String done = new String(out.toByteArray()); - - ByteArrayInputStream tin = new ByteArrayInputStream(done.getBytes()); - ByteArrayOutputStream tout = new ByteArrayOutputStream(); - - decode(tin, tout, tin.available()); - - tin.close(); - tout.flush(); - tout.close(); - - ByteArrayInputStream tstream = new ByteArrayInputStream(tout.toByteArray()); - DataInputStream tdata = new DataInputStream(tstream); - int[] test = new int[4096]; - for (int j = 0; j < 9; j++) { - if (tstream.available() <= 0) break; - test[j] = tdata.readInt(); - - } - tdata.close(); - test = test; - - } catch (IOException e) { - e.printStackTrace(); - }*/ - if (use1_14) { // Campfires are weird // Initialize once now so it doesn't lag later when we check for campfires under Cauldrons @@ -343,108 +95,7 @@ public class P extends JavaPlugin { BData.readData(); // Setup Metrics - /*try { - Metrics metrics = new Metrics(this); - metrics.addCustomChart(new Metrics.SingleLineChart("drunk_players", BPlayer::numDrunkPlayers)); - metrics.addCustomChart(new Metrics.SingleLineChart("brews_in_existence", () -> brewsCreated)); - metrics.addCustomChart(new Metrics.SingleLineChart("barrels_built", () -> Barrel.barrels.size())); - metrics.addCustomChart(new Metrics.SingleLineChart("cauldrons_boiling", () -> BCauldron.bcauldrons.size())); - metrics.addCustomChart(new Metrics.AdvancedPie("brew_quality", () -> { - Map map = new HashMap<>(8); - map.put("excellent", exc); - map.put("good", good); - map.put("normal", norm); - map.put("bad", bad); - map.put("terrible", terr); - return map; - })); - metrics.addCustomChart(new Metrics.AdvancedPie("brews_created", () -> { - Map map = new HashMap<>(4); - map.put("by command", brewsCreatedCmd); - map.put("brewing", brewsCreated - brewsCreatedCmd); - return map; - })); - - metrics.addCustomChart(new Metrics.SimplePie("number_of_recipes", () -> { - int recipes = BRecipe.getAllRecipes().size(); - if (recipes < 7) { - return "Less than 7"; - } else if (recipes < 11) { - return "7-10"; - } else if (recipes == 11) { - // There are 11 default recipes, so show this as its own slice - return "11"; - } else if (recipes <= 31) { - if (recipes % 2 == 0) { - return recipes + "-" + (recipes + 1); - } else { - return (recipes - 1) + "-" + recipes; - } - } else { - return "More than 31"; - } - - })); - metrics.addCustomChart(new Metrics.SimplePie("v2_mc_version", () -> { - String mcv = Bukkit.getBukkitVersion(); - mcv = mcv.substring(0, mcv.indexOf('.', 2)); - if (mcv.matches("^\\d\\.\\d{1,2}$")) { - // Start, digit, dot, 1-2 digits, end - return mcv; - } else { - return "undef"; - } - })); - metrics.addCustomChart(new Metrics.DrilldownPie("plugin_mc_version", () -> { - Map> map = new HashMap<>(3); - String mcv = Bukkit.getBukkitVersion(); - mcv = mcv.substring(0, mcv.indexOf('.', 2)); - if (mcv.matches("^\\d\\.\\d{1,2}$")) { - // Start, digit, dot, 1-2 digits, end - mcv = "MC " + mcv; - } else { - mcv = "undef"; - } - Map innerMap = new HashMap<>(3); - innerMap.put(mcv, 1); - map.put(getDescription().getVersion(), innerMap); - return map; - })); - metrics.addCustomChart(new Metrics.SimplePie("language", () -> language)); - metrics.addCustomChart(new Metrics.SimplePie("config_scramble", () -> BConfig.enableEncode ? "enabled" : "disabled")); - metrics.addCustomChart(new Metrics.SimplePie("config_lore_color", () -> { - if (BConfig.colorInBarrels) { - if (BConfig.colorInBrewer) { - return "both"; - } else { - return "in barrels"; - } - } else { - if (BConfig.colorInBrewer) { - return "in distiller"; - } else { - return "none"; - } - } - })); - metrics.addCustomChart(new Metrics.SimplePie("config_always_show", () -> { - if (BConfig.alwaysShowQuality) { - if (BConfig.alwaysShowAlc) { - return "both"; - } else { - return "quality stars"; - } - } else { - if (BConfig.alwaysShowAlc) { - return "alc content"; - } else { - return "none"; - } - } - })); - } catch (Throwable e) { - e.printStackTrace(); - }*/ + setupMetrics(); // Listeners blockListener = new BlockListener(); @@ -584,6 +235,111 @@ public class P extends JavaPlugin { return p; } + private void setupMetrics() { + /*try { + Metrics metrics = new Metrics(this); + metrics.addCustomChart(new Metrics.SingleLineChart("drunk_players", BPlayer::numDrunkPlayers)); + metrics.addCustomChart(new Metrics.SingleLineChart("brews_in_existence", () -> brewsCreated)); + metrics.addCustomChart(new Metrics.SingleLineChart("barrels_built", () -> Barrel.barrels.size())); + metrics.addCustomChart(new Metrics.SingleLineChart("cauldrons_boiling", () -> BCauldron.bcauldrons.size())); + metrics.addCustomChart(new Metrics.AdvancedPie("brew_quality", () -> { + Map map = new HashMap<>(8); + map.put("excellent", exc); + map.put("good", good); + map.put("normal", norm); + map.put("bad", bad); + map.put("terrible", terr); + return map; + })); + metrics.addCustomChart(new Metrics.AdvancedPie("brews_created", () -> { + Map map = new HashMap<>(4); + map.put("by command", brewsCreatedCmd); + map.put("brewing", brewsCreated - brewsCreatedCmd); + return map; + })); + + metrics.addCustomChart(new Metrics.SimplePie("number_of_recipes", () -> { + int recipes = BRecipe.getAllRecipes().size(); + if (recipes < 7) { + return "Less than 7"; + } else if (recipes < 11) { + return "7-10"; + } else if (recipes == 11) { + // There are 11 default recipes, so show this as its own slice + return "11"; + } else if (recipes <= 31) { + if (recipes % 2 == 0) { + return recipes + "-" + (recipes + 1); + } else { + return (recipes - 1) + "-" + recipes; + } + } else { + return "More than 31"; + } + + })); + metrics.addCustomChart(new Metrics.SimplePie("v2_mc_version", () -> { + String mcv = Bukkit.getBukkitVersion(); + mcv = mcv.substring(0, mcv.indexOf('.', 2)); + if (mcv.matches("^\\d\\.\\d{1,2}$")) { + // Start, digit, dot, 1-2 digits, end + return mcv; + } else { + return "undef"; + } + })); + metrics.addCustomChart(new Metrics.DrilldownPie("plugin_mc_version", () -> { + Map> map = new HashMap<>(3); + String mcv = Bukkit.getBukkitVersion(); + mcv = mcv.substring(0, mcv.indexOf('.', 2)); + if (mcv.matches("^\\d\\.\\d{1,2}$")) { + // Start, digit, dot, 1-2 digits, end + mcv = "MC " + mcv; + } else { + mcv = "undef"; + } + Map innerMap = new HashMap<>(3); + innerMap.put(mcv, 1); + map.put(getDescription().getVersion(), innerMap); + return map; + })); + metrics.addCustomChart(new Metrics.SimplePie("language", () -> language)); + metrics.addCustomChart(new Metrics.SimplePie("config_scramble", () -> BConfig.enableEncode ? "enabled" : "disabled")); + metrics.addCustomChart(new Metrics.SimplePie("config_lore_color", () -> { + if (BConfig.colorInBarrels) { + if (BConfig.colorInBrewer) { + return "both"; + } else { + return "in barrels"; + } + } else { + if (BConfig.colorInBrewer) { + return "in distiller"; + } else { + return "none"; + } + } + })); + metrics.addCustomChart(new Metrics.SimplePie("config_always_show", () -> { + if (BConfig.alwaysShowQuality) { + if (BConfig.alwaysShowAlc) { + return "both"; + } else { + return "quality stars"; + } + } else { + if (BConfig.alwaysShowAlc) { + return "alc content"; + } else { + return "none"; + } + } + })); + } catch (Throwable e) { + e.printStackTrace(); + }*/ + } + public void metricsForCreate(boolean byCmd) { if (brewsCreated == Integer.MAX_VALUE) return; brewsCreated++; @@ -653,32 +409,28 @@ public class P extends JavaPlugin { public class BreweryRunnable implements Runnable { @Override public void run() { - //long t1 = System.nanoTime(); + long t1 = System.nanoTime(); BConfig.reloader = null; for (BCauldron cauldron : BCauldron.bcauldrons.values()) { cauldron.onUpdate();// runs every min to update cooking time } - //long t2 = System.nanoTime(); + long t2 = System.nanoTime(); Barrel.onUpdate();// runs every min to check and update ageing time - //long t3 = System.nanoTime(); + long t3 = System.nanoTime(); if (use1_14) MCBarrel.onUpdate(); - //long t4 = System.nanoTime(); + long t4 = System.nanoTime(); BPlayer.onUpdate();// updates players drunkeness - //long t5 = System.nanoTime(); - debugLog("Update"); - - //long t6 = System.nanoTime(); + long t5 = System.nanoTime(); DataSave.autoSave(); - //long t7 = System.nanoTime(); + long t6 = System.nanoTime(); - /*P.p.log("BreweryRunnable: " + + debugLog("BreweryRunnable: " + "t1: " + (t2 - t1) / 1000000.0 + "ms" + " | t2: " + (t3 - t2) / 1000000.0 + "ms" + " | t3: " + (t4 - t3) / 1000000.0 + "ms" + " | t4: " + (t5 - t4) / 1000000.0 + "ms" + - " | t5: " + (t6 - t5) / 1000000.0 + "ms" + - " | t6: " + (t7 - t6) / 1000000.0 + "ms" );*/ + " | t5: " + (t6 - t5) / 1000000.0 + "ms" ); } } diff --git a/src/com/dre/brewery/api/BreweryApi.java b/src/com/dre/brewery/api/BreweryApi.java index 5b256aa..6748ce8 100644 --- a/src/com/dre/brewery/api/BreweryApi.java +++ b/src/com/dre/brewery/api/BreweryApi.java @@ -7,7 +7,6 @@ import com.dre.brewery.recipe.BCauldronRecipe; import com.dre.brewery.recipe.BRecipe; import com.dre.brewery.Barrel; import com.dre.brewery.Brew; -import com.dre.brewery.utility.Tuple; import org.apache.commons.lang.NotImplementedException; import org.bukkit.block.Block; import org.bukkit.entity.Player; @@ -242,7 +241,8 @@ public class BreweryApi { * The recipe can be changed or removed later. * * @param recipe The Recipe to add - * @param saveForever If the recipe should be saved forever, even after the Server restarts + * @param saveForever Not Implemented yet + * If the recipe should be saved forever, even after the Server restarts * If True: Recipe will be saved until removed manually * If False: Recipe will be removed when the Server restarts, existing potions using * this Recipe will become bad after continued aging, if the recipe is not added again. @@ -310,7 +310,8 @@ public class BreweryApi { * The recipe can be changed or removed later. * * @param recipe The Cauldron Recipe to add - * @param saveForever If the recipe should be saved forever, even after the Server restarts + * @param saveForever Not Implemented yet + * If the recipe should be saved forever, even after the Server restarts * If True: Recipe will be saved until removed manually * If False: Recipe will be removed when the Server restarts */ diff --git a/src/com/dre/brewery/filedata/BData.java b/src/com/dre/brewery/filedata/BData.java index 0ddb8b9..37e4263 100644 --- a/src/com/dre/brewery/filedata/BData.java +++ b/src/com/dre/brewery/filedata/BData.java @@ -38,10 +38,12 @@ public class BData { long t2 = System.currentTimeMillis(); - if (t2 - t1 > 5000) { + if (t2 - t1 > 8000) { // Spigot is very slow at loading inventories from yml. Notify Admin that loading Data took long P.p.log("Bukkit took " + (t2 - t1) / 1000.0 + "s to load the Data File,"); P.p.log("consider switching to Paper, or have less items in Barrels"); + } else { + P.p.debugLog("Loading data.yml: " + (t2 - t1) + "ms"); } Brew.installTime = data.getLong("installTime", System.currentTimeMillis()); diff --git a/src/com/dre/brewery/listeners/InventoryListener.java b/src/com/dre/brewery/listeners/InventoryListener.java index de8b5dc..b30d6e7 100644 --- a/src/com/dre/brewery/listeners/InventoryListener.java +++ b/src/com/dre/brewery/listeners/InventoryListener.java @@ -91,12 +91,12 @@ public class InventoryListener implements Listener { @EventHandler(priority = EventPriority.LOW, ignoreCancelled = true) public void onBrew(BrewEvent event) { if (P.use1_9) { - if (BDistiller.hasBrew(event.getContents()) != 0) { + if (BDistiller.hasBrew(event.getContents(), BDistiller.getDistillContents(event.getContents())) != 0) { event.setCancelled(true); } return; } - if (BDistiller.runDistill(event.getContents())) { + if (BDistiller.runDistill(event.getContents(), BDistiller.getDistillContents(event.getContents()))) { event.setCancelled(true); } } @@ -126,75 +126,15 @@ public class InventoryListener implements Listener { } } } + //long t1 = System.nanoTime(); Brew brew = Brew.get(item); + //long t2 = System.nanoTime(); if (brew != null) { P.p.log(brew.toString()); - //P.p.log(potion.getLore().get(0).replaceAll("§", "")); - //P.p.log("similar to beispiel? " + BRecipe.get("Beispiel").createBrew(10).isSimilar(brew)); - brew.touch(); + //P.p.log("Brew.get(): " + (t2 - t1) / 1000000.0 + "ms"); - /*try { - DataInputStream in = new DataInputStream(new Base91DecoderStream(new LoreLoadStream(potion))); - - brew.testLoad(in); - - *//*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("false1"); - }*//* - - in.close(); - } catch (IllegalArgumentException argExc) { - P.p.log("No Data in Lore"); - - try { - - DataOutputStream out = new DataOutputStream(new Base91EncoderStream(new LoreSaveStream(potion, 2))); - - brew.testStore(out); - - - *//*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(); - *//*StringBuilder b = new StringBuilder(); - for (char c : "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789!$%&()*+,-./:;<=>?@[]^_`{|}~\"".toCharArray()) { - b.append('§').append(c); - } - List lore = potion.getLore(); - lore.add(b.toString()); - potion.setLore(lore);*//* - item.setItemMeta(potion); - - } catch (IOException h) { - h.printStackTrace(); - } - - } catch (IOException e) { - e.printStackTrace(); - }*/ + //brew.touch(); } } } diff --git a/test/com/dre/brewery/RecipeTests.java b/test/com/dre/brewery/RecipeTests.java index e7efb04..1edc82f 100644 --- a/test/com/dre/brewery/RecipeTests.java +++ b/test/com/dre/brewery/RecipeTests.java @@ -89,4 +89,318 @@ public class RecipeTests { .get(); BreweryApi.addCauldronRecipe(r, false); } + + public static void onClick() { + /*try { + DataInputStream in = new DataInputStream(new Base91DecoderStream(new LoreLoadStream(potion))); + + brew.testLoad(in); + + *//*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("false1"); + }*//* + + in.close(); + } catch (IllegalArgumentException argExc) { + P.p.log("No Data in Lore"); + + try { + + DataOutputStream out = new DataOutputStream(new Base91EncoderStream(new LoreSaveStream(potion, 2))); + + brew.testStore(out); + + + *//*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(); + *//*StringBuilder b = new StringBuilder(); + for (char c : "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789!$%&()*+,-./:;<=>?@[]^_`{|}~\"".toCharArray()) { + b.append('§').append(c); + } + List lore = potion.getLore(); + lore.add(b.toString()); + potion.setLore(lore);*//* + item.setItemMeta(potion); + + } catch (IOException h) { + h.printStackTrace(); + } + + } catch (IOException e) { + e.printStackTrace(); + }*/ + } + + public static void onLoad() { + //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(); + } catch (InvalidKeyException e) { + e.printStackTrace(); + } finally { + try { + data.close(); + if (dataIn != null) { + dataIn.close(); + } + } catch (IOException e) { + e.printStackTrace(); + } + }*/ + + /*try { + ItemMeta meta = new ItemStack(Material.POTION).getItemMeta(); + DataOutputStream data = new DataOutputStream(new Base91EncoderStream(new LoreSaveStream(meta, 3))); + + data.writeInt(2); + data.writeLong(5); + + byte[] test = new byte[128]; + test[1] = 6; + test[2] = 12; + test[3] = 21; + test[127] = 99; + data.write(test); + + data.writeInt(123324); + data.writeLong(12343843); + + data.close(); + meta.getLore(); + + DataInputStream dataIn = new DataInputStream(new Base91DecoderStream(new LoreLoadStream(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]); + + P.p.log(dataIn.readInt() + ", " + dataIn.readLong() + ", "); + + dataIn.close(); + + + + basE91 basE91 = new basE91(); + int[] input = new int[] {12, 65, 324, 5, 12, 129459, 1234567, Integer.MIN_VALUE, Integer.MAX_VALUE}; + ByteArrayOutputStream stream = new ByteArrayOutputStream(); + DataOutputStream data = new DataOutputStream(stream); + for (int i = 0; i < input.length; i++) { + data.writeInt(input[i]); + } + data.flush(); + data.close(); + byte[] in = stream.toByteArray(); + byte[] out = new byte[4096]; + int lenght = basE91.encode(in, in.length, out); + basE91.encEnd(out); + String done = new String(out, 0, lenght); + + byte[] tin = done.getBytes(); + + byte[] tout = new byte[4096]; + lenght = basE91.decode(tin, tin.length, tout); + basE91.decEnd(tout); + + + ByteArrayInputStream tstream = new ByteArrayInputStream(tout, 0, lenght); + DataInputStream tdata = new DataInputStream(tstream); + int[] test = new int[4096]; + for (int j = 0; j < 6; j++) { + if (tstream.available() <= 0) break; + test[j] = tdata.readInt(); + + } + tdata.close(); + test = test;*/ + + + + /*basE91 basE91 = new basE91(); + int[] input = new int[] {12, 65, 324, 5, 12, 129459, 1234567, Integer.MIN_VALUE, Integer.MAX_VALUE}; + ByteArrayOutputStream stream = new ByteArrayOutputStream(); + DataOutputStream data = new DataOutputStream(stream); + for (int i = 0; i < input.length; i++) { + data.writeInt(input[i]); + } + data.flush(); + data.close(); + ByteArrayOutputStream out = new ByteArrayOutputStream(); + ByteArrayInputStream in = new ByteArrayInputStream(stream.toByteArray()); + + encode(in, out, in.available()); + + in.close(); + out.flush(); + out.close(); + + String done = new String(out.toByteArray()); + + ByteArrayInputStream tin = new ByteArrayInputStream(done.getBytes()); + ByteArrayOutputStream tout = new ByteArrayOutputStream(); + + decode(tin, tout, tin.available()); + + tin.close(); + tout.flush(); + tout.close(); + + ByteArrayInputStream tstream = new ByteArrayInputStream(tout.toByteArray()); + DataInputStream tdata = new DataInputStream(tstream); + int[] test = new int[4096]; + for (int j = 0; j < 9; j++) { + if (tstream.available() <= 0) break; + test[j] = tdata.readInt(); + + } + tdata.close(); + test = test; + + } catch (IOException e) { + e.printStackTrace(); + }*/ + } } From 16c03f9da14f86493133d48c3c9b21afc3ef185e Mon Sep 17 00:00:00 2001 From: Sn0wStorm Date: Mon, 25 Nov 2019 22:16:16 +0100 Subject: [PATCH 45/51] Added and Fixed lots of JavaDocs --- src/com/dre/brewery/BIngredients.java | 50 +++++--- src/com/dre/brewery/Barrel.java | 72 ++++++++--- src/com/dre/brewery/BarrelBody.java | 51 +++++--- src/com/dre/brewery/Brew.java | 43 ++++--- src/com/dre/brewery/api/BreweryApi.java | 117 ++++++++++-------- .../brewery/api/events/ConfigLoadEvent.java | 12 +- .../brewery/api/events/IngedientAddEvent.java | 42 +++---- .../api/events/PlayerChatDistortEvent.java | 2 +- .../brewery/api/events/PlayerEffectEvent.java | 22 ++-- .../brewery/api/events/PlayerPukeEvent.java | 10 +- .../brewery/api/events/PlayerPushEvent.java | 15 +-- .../api/events/barrel/BarrelAccessEvent.java | 8 +- .../api/events/barrel/BarrelCreateEvent.java | 4 +- .../api/events/barrel/BarrelDestroyEvent.java | 11 +- .../api/events/barrel/BarrelRemoveEvent.java | 3 +- .../api/events/brew/BrewDrinkEvent.java | 6 +- .../brewery/api/events/brew/BrewEvent.java | 3 + .../api/events/brew/BrewModifyEvent.java | 61 +++++++-- .../brewery/listeners/InventoryListener.java | 2 +- src/com/dre/brewery/lore/BrewLore.java | 13 +- .../dre/brewery/lore/XORScrambleStream.java | 14 +-- .../dre/brewery/lore/XORUnscrambleStream.java | 37 ++++-- .../dre/brewery/recipe/BCauldronRecipe.java | 32 +++-- src/com/dre/brewery/recipe/BRecipe.java | 80 ++++++++---- src/com/dre/brewery/recipe/CustomItem.java | 4 +- .../brewery/recipe/CustomMatchAnyItem.java | 2 +- src/com/dre/brewery/recipe/Ingredient.java | 25 ++-- src/com/dre/brewery/recipe/PluginItem.java | 30 ++--- src/com/dre/brewery/recipe/RecipeItem.java | 26 ++-- src/com/dre/brewery/utility/BUtil.java | 8 +- src/com/dre/brewery/utility/LegacyUtil.java | 8 +- src/com/dre/brewery/utility/Tuple.java | 8 -- 32 files changed, 513 insertions(+), 308 deletions(-) diff --git a/src/com/dre/brewery/BIngredients.java b/src/com/dre/brewery/BIngredients.java index 5d56e49..f5e59ec 100644 --- a/src/com/dre/brewery/BIngredients.java +++ b/src/com/dre/brewery/BIngredients.java @@ -62,8 +62,8 @@ public class BIngredients { } /** - * Force add an ingredient to this - * Will not check if item is acceptable + * Force add an ingredient to this. + *

Will not check if item is acceptable * * @param ingredient the item to add */ @@ -98,7 +98,9 @@ public class BIngredients { ingredients.add(ingredientItem); } - // returns an Potion item with cooked ingredients + /** + * returns an Potion item with cooked ingredients + */ public ItemStack cook(int state) { ItemStack potion = new ItemStack(Material.POTION); @@ -178,7 +180,9 @@ public class BIngredients { return potion; } - // returns amount of ingredients + /** + * returns amount of ingredients + */ public int getIngredientsCount() { int count = 0; for (Ingredient ing : ingredients) { @@ -195,8 +199,9 @@ public class BIngredients { return cookedTime; } - // best recipe for current state of potion, STILL not always returns the - // correct one... + /** + * best recipe for current state of potion, STILL not always returns the correct one... + */ public BRecipe getBestRecipe(float wood, float time, boolean distilled) { float quality = 0; int ingredientQuality; @@ -237,8 +242,9 @@ public class BIngredients { return bestRecipe; } - // returns recipe that is cooking only and matches the ingredients and - // cooking time + /** + * returns recipe that is cooking only and matches the ingredients and cooking time + */ public BRecipe getCookRecipe() { BRecipe bestRecipe = getBestRecipe(0, 0, false); @@ -272,7 +278,9 @@ public class BIngredients { return best; } - // returns the currently best matching recipe for distilling for the ingredients and cooking time + /** + * returns the currently best matching recipe for distilling for the ingredients and cooking time + */ public BRecipe getDistillRecipe(float wood, float time) { BRecipe bestRecipe = getBestRecipe(wood, time, true); @@ -285,7 +293,9 @@ public class BIngredients { return null; } - // returns currently best matching recipe for ingredients, cooking- and ageingtime + /** + * returns currently best matching recipe for ingredients, cooking- and ageingtime + */ public BRecipe getAgeRecipe(float wood, float time, boolean distilled) { BRecipe bestRecipe = getBestRecipe(wood, time, distilled); @@ -297,7 +307,9 @@ public class BIngredients { return null; } - // returns the quality of the ingredients conditioning given recipe, -1 if no recipe is near them + /** + * returns the quality of the ingredients conditioning given recipe, -1 if no recipe is near them + */ public int getIngredientQuality(BRecipe recipe) { float quality = 10; int count; @@ -335,7 +347,9 @@ public class BIngredients { return -1; } - // returns the quality regarding the cooking-time conditioning given Recipe + /** + * returns the quality regarding the cooking-time conditioning given Recipe + */ public int getCookingQuality(BRecipe recipe, boolean distilled) { if (!recipe.needsDistilling() == distilled) { return -1; @@ -351,7 +365,9 @@ public class BIngredients { return -1; } - // returns pseudo quality of distilling. 0 if doesnt match the need of the recipes distilling + /** + * returns pseudo quality of distilling. 0 if doesnt match the need of the recipes distilling + */ public int getDistillQuality(BRecipe recipe, byte distillRuns) { if (recipe.needsDistilling() != distillRuns > 0) { return 0; @@ -359,7 +375,9 @@ public class BIngredients { return 10 - Math.abs(recipe.getDistillRuns() - distillRuns); } - // returns the quality regarding the barrel wood conditioning given Recipe + /** + * returns the quality regarding the barrel wood conditioning given Recipe + */ public int getWoodQuality(BRecipe recipe, float wood) { if (recipe.getWood() == 0) { // type of wood doesnt matter @@ -370,7 +388,9 @@ public class BIngredients { return Math.max(quality, 0); } - // returns the quality regarding the ageing time conditioning given Recipe + /** + * returns the quality regarding the ageing time conditioning given Recipe + */ public int getAgeQuality(BRecipe recipe, float time) { int quality = 10 - Math.round(Math.abs(time - recipe.getAge()) * ((float) recipe.getDifficulty() / 2)); diff --git a/src/com/dre/brewery/Barrel.java b/src/com/dre/brewery/Barrel.java index a2e9f99..a547285 100644 --- a/src/com/dre/brewery/Barrel.java +++ b/src/com/dre/brewery/Barrel.java @@ -31,6 +31,9 @@ import java.util.ArrayList; import java.util.List; import java.util.Map; +/** + * A Multi Block Barrel with Inventory + */ public class Barrel implements InventoryHolder { public static List barrels = new ArrayList<>(); @@ -52,7 +55,9 @@ public class Barrel implements InventoryHolder { body = new BarrelBody(this, signoffset); } - // load from file + /** + * load from file + */ public Barrel(Block spigot, byte sign, BoundingBox bounds, Map items, float time) { this.spigot = spigot; if (isLarge()) { @@ -113,7 +118,9 @@ public class Barrel implements InventoryHolder { return true; } - // Ask for permission to destroy barrel + /** + * Ask for permission to destroy barrel + */ public boolean hasPermsDestroy(Player player, Block block, BarrelDestroyEvent.Reason reason) { // Listened to by LWCBarrel (IntegrationListener) BarrelDestroyEvent destroyEvent = new BarrelDestroyEvent(this, block, reason, player); @@ -121,7 +128,9 @@ public class Barrel implements InventoryHolder { return !destroyEvent.isCancelled(); } - // player opens the barrel + /** + * player opens the barrel + */ public void open(Player player) { if (inventory == null) { if (isLarge()) { @@ -212,13 +221,15 @@ public class Barrel implements InventoryHolder { return time; } - // Returns true if this Block is part of this Barrel + /** + * Returns true if this Block is part of this Barrel + */ public boolean hasBlock(Block block) { return body.hasBlock(block); } /** - * Deprecated, just use hasBlock + * @deprecated just use hasBlock */ @Deprecated public boolean hasWoodBlock(Block block) { @@ -226,14 +237,16 @@ public class Barrel implements InventoryHolder { } /** - * Deprecated, just use hasBlock + * @deprecated just use hasBlock */ @Deprecated public boolean hasStairsBlock(Block block) { return body.hasBlock(block); } - // Get the Barrel by Block, null if that block is not part of a barrel + /** + * Get the Barrel by Block, null if that block is not part of a barrel + */ @Nullable public static Barrel get(Block block) { if (block == null) { @@ -247,7 +260,9 @@ public class Barrel implements InventoryHolder { } } - // Get the Barrel by Sign or Spigot (Fastest) + /** + * Get the Barrel by Sign or Spigot (Fastest) + */ @Nullable public static Barrel getBySpigot(Block sign) { // convert spigot if neccessary @@ -272,7 +287,9 @@ public class Barrel implements InventoryHolder { return null; } - // Get the barrel by its corpus (Wood Planks, Stairs) + /** + * Get the barrel by its corpus (Wood Planks, Stairs) + */ @Nullable public static Barrel getByWood(Block wood) { if (LegacyUtil.isWoodPlanks(wood.getType()) || LegacyUtil.isWoodStairs(wood.getType())) { @@ -285,7 +302,9 @@ public class Barrel implements InventoryHolder { return null; } - // creates a new Barrel out of a sign + /** + * creates a new Barrel out of a sign + */ public static boolean create(Block sign, Player player) { Block spigot = BarrelBody.getSpigotOfSign(sign); @@ -383,39 +402,54 @@ public class Barrel implements InventoryHolder { barrels.remove(this); } - // is this a Large barrel? + /** + * is this a Large barrel? + */ public boolean isLarge() { return !isSmall(); } - // is this a Small barrel? + /** + * is this a Small barrel? + */ public boolean isSmall() { return LegacyUtil.isSign(spigot.getType()); } - // returns the Sign of a large barrel, the spigot if there is none + /** + * returns the Sign of a large barrel, the spigot if there is none + */ public Block getSignOfSpigot() { return body.getSignOfSpigot(); } - // returns the fence above/below a block, itself if there is none + /** + * returns the fence above/below a block, itself if there is none + */ public static Block getSpigotOfSign(Block block) { return BarrelBody.getSpigotOfSign(block); } - // returns null if Barrel is correctly placed; the block that is missing when not - // the barrel needs to be formed correctly - // flag force to also check if chunk is not loaded + /** + * returns null if Barrel is correctly placed; the block that is missing when not. + *

The barrel needs to be formed correctly + * + * @param force to also check even if chunk is not loaded + */ public Block getBrokenBlock(boolean force) { return body.getBrokenBlock(force); } - //unloads barrels that are in a unloading world + /** + * unloads barrels that are in a unloading world + */ public static void onUnload(String name) { barrels.removeIf(barrel -> barrel.spigot.getWorld().getName().equals(name)); } - // Saves all data + /** + * Saves all data + */ public static void save(ConfigurationSection config, ConfigurationSection oldData) { BUtil.createWorldSections(config); diff --git a/src/com/dre/brewery/BarrelBody.java b/src/com/dre/brewery/BarrelBody.java index c3c9efa..da0c617 100644 --- a/src/com/dre/brewery/BarrelBody.java +++ b/src/com/dre/brewery/BarrelBody.java @@ -10,7 +10,9 @@ import org.jetbrains.annotations.NotNull; import java.util.Objects; -// The Blocks that make up a Barrel in the World +/** + * The Blocks that make up a Barrel in the World + */ public class BarrelBody { private final Barrel barrel; @@ -25,7 +27,9 @@ public class BarrelBody { this.bounds = new BoundingBox(0, 0, 0, 0, 0, 0); } - // Loading from file + /** + * Loading from file + */ public BarrelBody(Barrel barrel, byte signoffset, BoundingBox bounds) { this(barrel, signoffset); @@ -67,12 +71,16 @@ public class BarrelBody { this.signoffset = signoffset; } - // If the Sign of a Large Barrel gets destroyed, set signOffset to 0 + /** + * If the Sign of a Large Barrel gets destroyed, set signOffset to 0 + */ public void destroySign() { signoffset = 0; } - // direction of the barrel from the spigot + /** + * direction of the barrel from the spigot + */ public static int getDirection(Block spigot) { int direction = 0;// 1=x+ 2=x- 3=z+ 4=z- Material type = spigot.getRelative(0, 0, 1).getType(); @@ -106,17 +114,23 @@ public class BarrelBody { return direction; } - // is this a Large barrel? + /** + * is this a Large barrel? + */ public boolean isLarge() { return barrel.isLarge(); } - // is this a Small barrel? + /** + * is this a Small barrel? + */ public boolean isSmall() { return barrel.isSmall(); } - // woodtype of the block the spigot is attached to + /** + * woodtype of the block the spigot is attached to + */ public byte getWood() { Block wood; switch (getDirection(spigot)) { // 1=x+ 2=x- 3=z+ 4=z- @@ -160,13 +174,17 @@ public class BarrelBody { return false; } - // Returns true if the Offset of the clicked Sign matches the Barrel. - // This prevents adding another sign to the barrel and clicking that. + /** + * Returns true if the Offset of the clicked Sign matches the Barrel. + *

This prevents adding another sign to the barrel and clicking that. + */ public boolean isSignOfBarrel(byte offset) { return offset == 0 || signoffset == 0 || signoffset == offset; } - // returns the Sign of a large barrel, the spigot if there is none + /** + * returns the Sign of a large barrel, the spigot if there is none + */ public Block getSignOfSpigot() { if (signoffset != 0) { if (LegacyUtil.isSign(spigot.getType())) { @@ -182,7 +200,9 @@ public class BarrelBody { return spigot; } - // returns the fence above/below a block, itself if there is none + /** + * returns the fence above/below a block, itself if there is none + */ public static Block getSpigotOfSign(Block block) { int y = -2; @@ -197,9 +217,12 @@ public class BarrelBody { return block; } - // returns null if Barrel is correctly placed; the block that is missing when not - // the barrel needs to be formed correctly - // flag force to also check if chunk is not loaded + /** + * returns null if Barrel is correctly placed; the block that is missing when not. + *

the barrel needs to be formed correctly + * + * @param force to also check even if chunk is not loaded + */ public Block getBrokenBlock(boolean force) { if (force || BUtil.isChunkLoaded(spigot)) { //spigot = getSpigotOfSign(spigot); diff --git a/src/com/dre/brewery/Brew.java b/src/com/dre/brewery/Brew.java index 5b0d811..3620397 100644 --- a/src/com/dre/brewery/Brew.java +++ b/src/com/dre/brewery/Brew.java @@ -173,8 +173,11 @@ public class Brew implements Cloneable { return null; } - // returns a Brew by its UID - // Does not work anymore with new save system + /** + * returns a Brew by its UID + * + * @deprecated Does not work anymore with new save system + */ @Deprecated public static Brew get(int uid) { if (uid < -1) { @@ -188,8 +191,11 @@ public class Brew implements Cloneable { return legacyPotions.get(uid); } - // returns UID of custom Potion item - // Does not work anymore with new save system + /** + * returns UID of custom Potion item + * + * @deprecated Does not work anymore with new save system + */ @Deprecated public static int getUID(ItemStack item) { return getUID((PotionMeta) item.getItemMeta()); @@ -197,6 +203,12 @@ public class Brew implements Cloneable { // returns UID of custom Potion meta // Does not work anymore with new save system + + /** + * returns UID of custom Potion meta + * + * @deprecated Does not work anymore with new save system + */ @Deprecated public static int getUID(PotionMeta potionMeta) { if (potionMeta.hasCustomEffect(PotionEffectType.REGENERATION)) { @@ -395,7 +407,9 @@ public class Brew implements Cloneable { } } - // return special effect + /** + * Get Special Drink Effects + */ public List getEffects() { if (currentRecipe != null && quality > 0) { return currentRecipe.getEffects(); @@ -427,7 +441,8 @@ public class Brew implements Cloneable { } /** - * Do some regular updates + * Do some regular updates. + *

Not really used, apart from legacy potion timed purge */ public void touch() { lastUpdate = (int) ((double) (System.currentTimeMillis() - installTime) / 3600000D); @@ -734,8 +749,8 @@ public class Brew implements Cloneable { } /** - * Performant way of checking if this item is a Brew - * Does not give any guarantees that get() will return notnull for this item, i.e. if it is a brew but the data is corrupt + * Performant way of checking if this item is a Brew. + *

Does not give any guarantees that get() will return notnull for this item, i.e. if it is a brew but the data is corrupt * * @param item The Item to check * @return True if the item is a brew @@ -854,8 +869,8 @@ public class Brew implements Cloneable { } /** - * Save brew data into meta: lore/nbt - * Should be called after any changes made to the brew + * Save brew data into meta: lore/nbt. + *

Should be called after any changes made to the brew */ public void save(ItemMeta meta) { OutputStream itemSaveStream; @@ -881,8 +896,8 @@ public class Brew implements Cloneable { } /** - * Save brew data into the meta/lore of the specified item - * The meta on the item changes, so to make further changes to the meta, item.getItemMeta() has to be called again after this + * Save brew data into the meta/lore of the specified item. + *

The meta on the item changes, so to make further changes to the meta, item.getItemMeta() has to be called again after this * * @param item The item to save this brew into */ @@ -1027,8 +1042,8 @@ public class Brew implements Cloneable { } /** - * Saves all data - * Legacy method to save to data file + * Saves all data, + * Legacy method to save to data file. */ public static void saveLegacy(ConfigurationSection config) { for (Map.Entry entry : legacyPotions.entrySet()) { diff --git a/src/com/dre/brewery/api/BreweryApi.java b/src/com/dre/brewery/api/BreweryApi.java index 6748ce8..b53def9 100644 --- a/src/com/dre/brewery/api/BreweryApi.java +++ b/src/com/dre/brewery/api/BreweryApi.java @@ -18,15 +18,22 @@ import org.jetbrains.annotations.Nullable; import java.util.List; /** - * Convenience methods to get common objects or do common things + * Convenience methods to get common objects or do common things. + *

Contains shortcuts and collects of some of the main functions of this Plugin + * + *

Next to this there are lots of public Methods in many Objects + * like Brew, Barrel, BCauldron, BRecipe, etc + *

In the api package, you can also find custom Events. */ public class BreweryApi { /** - * Remove any data that this Plugin may associate with the given Block - * Currently Cauldrons and Barrels (Cauldron, Wood, Woodstairs, Fence, Sign) - * Does not remove any actual Blocks - * Returns true if anything was removed + * Remove any data that this Plugin may associate with the given Block. + *

Currently Cauldrons and Barrels (Cauldron, Wood, Woodstairs, Fence, Sign) + *

Does not remove any actual Blocks + *

Returns true if anything was removed + * + * @return true if anything was removed */ public static boolean removeAny(Block block) { if (removeCauldron(block)) return true; @@ -34,8 +41,8 @@ public class BreweryApi { } /** - * Like removeAny() but removes data as if the given player broke the Block - * Currently only makes a difference for Logging + *

Like removeAny() but removes data as if the given player broke the Block. + *

Currently only makes a difference for Logging */ public static boolean removeAnyByPlayer(Block block, Player player) { if (removeCauldron(block)) return true; @@ -47,17 +54,20 @@ public class BreweryApi { // # # # # # Player # # # # # // # # # # # # # # # # # # + /** + * Get the BPlayer for the given Player, containing drunkeness and hangover data. + */ public static BPlayer getBPlayer(Player player) { return BPlayer.get(player); } /** - * Set the Players drunkeness state + * Set the Players drunkeness state. * * @param player The Player to set the drunkeness on * @param drunkeness The amount of drunkeness 0-100 to apply to the player - * @param quality The Quality 1-10 the drunkeness of the player should have - * zero Quality keeps the players current quality + * @param quality The Quality 1-10 the drunkeness of the player should have. + *
zero Quality keeps the players current quality */ public static void setPlayerDrunk(Player player, int drunkeness, int quality) { if (drunkeness < 0) { @@ -100,10 +110,10 @@ public class BreweryApi { // # # # # # # # # # # # # /** - * Get a Brew from an ItemStack - * Reads the Brew data from the saved data on the item - * Checks if item is actually a Brew - * Returns null if item is not a Brew + * Get a Brew from an ItemStack. + *

Reads the Brew data from the saved data on the item + *

Checks if item is actually a Brew + *

Returns null if item is not a Brew */ @Nullable public static Brew getBrew(ItemStack item) { @@ -111,10 +121,10 @@ public class BreweryApi { } /** - * Get a Brew from an ItemMeta - * Reads the Brew data from the saved data in the Meta - * Checks if meta has a Brew saved - * Returns null if meta is not a Brew + * Get a Brew from an ItemMeta. + *

Reads the Brew data from the saved data in the Meta + *

Checks if meta has a Brew saved + *

Returns null if meta is not a Brew */ @Nullable public static Brew getBrew(ItemMeta meta) { @@ -123,14 +133,14 @@ public class BreweryApi { /** * Performant way to check if an item is a brew. - * Does not give any guarantees that getBrew() will return notnull for this item, i.e. if it is a brew but couldn't be loaded + *

Does not give any guarantees that getBrew() will return notnull for this item, i.e. if it is a brew but couldn't be loaded */ public static boolean isBrew(ItemStack item) { return Brew.isBrew(item); } /** - * Create a Brew from the given Recipe + * Create a Brew from the given Recipe. * * @param recipe The Recipe to create a brew from * @return The Brew that was created. Can use brew.createItem() to get an ItemStack @@ -145,9 +155,9 @@ public class BreweryApi { // # # # # # # # # # # # # /** - * Get a Barrel from a Block - * May be any Wood, Fence, Sign that is part of a Barrel - * Returns null if block is not part of a Barrel + * Get a Barrel from a Block. + *

May be any Wood, Fence, Sign that is part of a Barrel + *

Returns null if block is not part of a Barrel */ @Nullable public static Barrel getBarrel(Block block) { @@ -155,9 +165,9 @@ public class BreweryApi { } /** - * Get the Inventory of a Block part of a Barrel - * May be any Wood, Fence or Sign that is part of a Barrel - * Returns null if block is not part of a Barrel + * Get the Inventory of a Block part of a Barrel. + *

May be any Wood, Fence or Sign that is part of a Barrel + *

Returns null if block is not part of a Barrel */ @Nullable public static Inventory getBarrelInventory(Block block) { @@ -169,7 +179,7 @@ public class BreweryApi { } /** - * Remove any Barrel that this Block may be Part of + * Remove any Barrel that this Block may be Part of. * Does not remove any actual Block * * @param block The Block thats part of the barrel, potions will drop there @@ -181,7 +191,7 @@ public class BreweryApi { } /** - * Remove any Barrel that this Block may be Part of, as if broken by the Player + * Remove any Barrel that this Block may be Part of, as if broken by the Player. * Does not remove any actual Block from the World * * @param block The Block thats part of the barrel, potions will drop there @@ -203,8 +213,8 @@ public class BreweryApi { // # # # # # # # # # # # # /** - * Get a BCauldron from a Block - * Returns null if block is not a BCauldron + * Get a BCauldron from a Block. + *

Returns null if block is not a BCauldron */ @Nullable public static BCauldron getCauldron(Block block) { @@ -212,9 +222,9 @@ public class BreweryApi { } /** - * Remove any data associated with a Cauldron at that given Block - * Returns true if a Cauldron was removed - * Does not remove the Block from the World + * Remove any data associated with a Cauldron at that given Block. + *

Returns true if a Cauldron was removed + *

Does not remove the Block from the World */ public static boolean removeCauldron(Block block) { return BCauldron.remove(block); @@ -226,9 +236,9 @@ public class BreweryApi { // # # # # # # # # # # # # /** - * Get a BRecipe by its name - * The name is the middle one of the three if three are set in the config - * Returns null if recipe with that name does not exist + * Get a BRecipe by its name. + *

The name is the middle one of the three if three are set in the config + *

Returns null if recipe with that name does not exist */ @Nullable public static BRecipe getRecipe(String name) { @@ -237,15 +247,15 @@ public class BreweryApi { /** * Add a New Recipe. - * Brews can be made out of this Recipe. - * The recipe can be changed or removed later. + *

Brews can be made out of this Recipe. + *

The recipe can be changed or removed later. * * @param recipe The Recipe to add - * @param saveForever Not Implemented yet - * If the recipe should be saved forever, even after the Server restarts - * If True: Recipe will be saved until removed manually - * If False: Recipe will be removed when the Server restarts, existing potions using - * this Recipe will become bad after continued aging, if the recipe is not added again. + * @param saveForever Not Implemented yet. + *
If the recipe should be saved forever, even after the Server restarts + *
If True: Recipe will be saved until removed manually + *
If False: Recipe will be removed when the Server restarts, existing potions using + *
this Recipe will become bad after continued aging, if the recipe is not added again. */ public static void addRecipe(BRecipe recipe, boolean saveForever) { //recipe.setSaveInData(saveForever); @@ -258,7 +268,7 @@ public class BreweryApi { /** * Removes a Recipe from the List of all Recipes. - * This can also remove Recipes that were loaded from config, though these will be readded when reloading the config + *

This can also remove Recipes that were loaded from config, though these will be readded when reloading the config * * @param name The name of the recipe to remove * @return The Recipe that was removed, null if none was removed @@ -296,8 +306,8 @@ public class BreweryApi { // # # # # # # # # # # # # /** - * Get A BCauldronRecipe by its name - * Returns null if recipe with that name does not exist + * Get A BCauldronRecipe by its name. + *

Returns null if recipe with that name does not exist */ @Nullable public static BCauldronRecipe getCauldronRecipe(String name) { @@ -306,14 +316,14 @@ public class BreweryApi { /** * Add a New Cauldron Recipe. - * Base Brews coming out of the Cauldron can be made from this recipe - * The recipe can be changed or removed later. + *

Base Brews coming out of the Cauldron can be made from this recipe + *

The recipe can be changed or removed later. * * @param recipe The Cauldron Recipe to add - * @param saveForever Not Implemented yet - * If the recipe should be saved forever, even after the Server restarts - * If True: Recipe will be saved until removed manually - * If False: Recipe will be removed when the Server restarts + * @param saveForever Not Implemented yet. + *
If the recipe should be saved forever, even after the Server restarts + *
If True: Recipe will be saved until removed manually + *
If False: Recipe will be removed when the Server restarts */ public static void addCauldronRecipe(BCauldronRecipe recipe, boolean saveForever) { //recipe.setSaveInData(saveForever); @@ -326,7 +336,8 @@ public class BreweryApi { /** * Removes a Cauldron Recipe from the List of all Cauldron Recipes. - * This can also remove Cauldron Recipes that were loaded from config, though these will be readded when reloading the config + *

This can also remove Cauldron Recipes that were loaded from config, + * though these will be readded when reloading the config * * @param name The name of the cauldron recipe to remove * @return The Cauldron Recipe that was removed, null if none was removed diff --git a/src/com/dre/brewery/api/events/ConfigLoadEvent.java b/src/com/dre/brewery/api/events/ConfigLoadEvent.java index 5af5893..3c4e615 100644 --- a/src/com/dre/brewery/api/events/ConfigLoadEvent.java +++ b/src/com/dre/brewery/api/events/ConfigLoadEvent.java @@ -7,17 +7,15 @@ import org.bukkit.event.Event; import org.bukkit.event.HandlerList; import org.jetbrains.annotations.NotNull; -import java.util.List; - /** - * The Brewery Config was reloaded + * The Brewery Config was reloaded. */ public class ConfigLoadEvent extends Event { private static final HandlerList handlers = new HandlerList(); /** - * One of the things one might need to do after reloading - * Removes a Recipe, can also remove config recipes + * Removes a Recipe, can also remove config recipes. + * One of the things one might need to do after reloading. * * @param name Name of the Recipe to remove * @return The Recipe that was removed, null if none was removed @@ -27,8 +25,8 @@ public class ConfigLoadEvent extends Event { } /** - * One of the things one might need to do after reloading - * Removes a Cauldron Recipe, can also remove config recipes + * Removes a Cauldron Recipe, can also remove config recipes. + * One of the things one might need to do after reloading. * * @param name Name of the Cauldron Recipe to remove * @return The Cauldron Recipe that was removed, null if none was removed diff --git a/src/com/dre/brewery/api/events/IngedientAddEvent.java b/src/com/dre/brewery/api/events/IngedientAddEvent.java index d576f51..37461f3 100644 --- a/src/com/dre/brewery/api/events/IngedientAddEvent.java +++ b/src/com/dre/brewery/api/events/IngedientAddEvent.java @@ -15,9 +15,9 @@ import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; /** - * Player adding an ingredient to a cauldron - * Always one item added at a time - * If needed use the caudrons add method to manually add more Items + * Player adding an ingredient to a cauldron. + *

Always one item added at a time. + *

If needed use the caudrons add method to manually add more Items */ public class IngedientAddEvent extends PlayerEvent implements Cancellable { private static final HandlerList handlers = new HandlerList(); @@ -46,17 +46,17 @@ public class IngedientAddEvent extends PlayerEvent implements Cancellable { /** * The Recipe item that matches the ingredient. - * This might not be the only recipe item that will match the ingredient - * Will be recalculated if the Ingredient is changed with the setIngredient Method + *

This might not be the only recipe item that will match the ingredient + *

Will be recalculated if the Ingredient is changed with the setIngredient Method */ public RecipeItem getRecipeItem() { return rItem; } /** - * Get the item currently being added to the cauldron by the player - * Can be changed directly (mutable) or with the setter Method - * The amount is ignored and always one added + * Get the item currently being added to the cauldron by the player. + *

Can be changed directly (mutable) or with the setter Method + *

The amount is ignored and always one added * * @return The item being added */ @@ -65,10 +65,10 @@ public class IngedientAddEvent extends PlayerEvent implements Cancellable { } /** - * Set the ingredient added to the cauldron to something else - * Will always be accepted, even when not in a recipe or the cooked lis - * The amount is ignored and always one added - * This also recalculates the recipeItem! + * Set the ingredient added to the cauldron to something else. + *

Will always be accepted, even when not in a recipe or the cooked lis + *

The amount is ignored and always one added + *

This also recalculates the recipeItem! * * @param ingredient The item to add instead */ @@ -79,15 +79,15 @@ public class IngedientAddEvent extends PlayerEvent implements Cancellable { } /** - * If the amount of the item in the players hand should be decreased - * Default true + * If the amount of the item in the players hand should be decreased. + * (Default true) */ public boolean willTakeItem() { return takeItem; } /** - * Set if the amount of the item in the players hand should be decreased + * Set if the amount of the item in the players hand should be decreased. * * @param takeItem if the item amount in the hand should be decreased */ @@ -96,8 +96,8 @@ public class IngedientAddEvent extends PlayerEvent implements Cancellable { } /** - * Get the BlockData of the Cauldron - * May be null if the Cauldron does not exist anymore + * Get the BlockData of the Cauldron. + *

May be null if the Cauldron does not exist anymore * * @return The BlockData of the cauldron */ @@ -111,9 +111,9 @@ public class IngedientAddEvent extends PlayerEvent implements Cancellable { } /** - * Get the water fill level of the Cauldron - * 0 = empty, 1 = something in, 2 = full - * Can use BCauldron.EMPTY, BCauldron.SOME, BCauldron.FULL + * Get the water fill level of the Cauldron. + *

0 = empty, 1 = something in, 2 = full + *

Can use BCauldron.EMPTY, BCauldron.SOME, BCauldron.FULL * * @return The fill level as a byte 0-2 */ @@ -127,7 +127,7 @@ public class IngedientAddEvent extends PlayerEvent implements Cancellable { } /** - * If the event is cancelled, no item will be added or taken from the player + * If the event is cancelled, no item will be added or taken from the player. */ @Override public void setCancelled(boolean cancelled) { diff --git a/src/com/dre/brewery/api/events/PlayerChatDistortEvent.java b/src/com/dre/brewery/api/events/PlayerChatDistortEvent.java index 107ad10..15e7dfc 100644 --- a/src/com/dre/brewery/api/events/PlayerChatDistortEvent.java +++ b/src/com/dre/brewery/api/events/PlayerChatDistortEvent.java @@ -13,7 +13,7 @@ import java.util.Objects; /** * The Player writes something in Chat or on a Sign and his words are distorted. * - * This Event may be Async if the Chat Event is Async! + *

This Event may be Async if the Chat Event is Async! */ public class PlayerChatDistortEvent extends Event implements Cancellable { private static final HandlerList handlers = new HandlerList(); diff --git a/src/com/dre/brewery/api/events/PlayerEffectEvent.java b/src/com/dre/brewery/api/events/PlayerEffectEvent.java index b980b8b..3d1b432 100644 --- a/src/com/dre/brewery/api/events/PlayerEffectEvent.java +++ b/src/com/dre/brewery/api/events/PlayerEffectEvent.java @@ -11,8 +11,9 @@ import java.util.List; /** * A List of effects is applied to the player. - * This happens for various reasons like Alcohol level, Brew quality, Brew effects, etc. - * Can be changed or cancelled + *

This happens for various reasons like Alcohol level, Brew quality, Brew effects, etc. + * + *

Can be changed or cancelled */ public class PlayerEffectEvent extends PlayerEvent implements Cancellable { private static final HandlerList handlers = new HandlerList(); @@ -38,7 +39,7 @@ public class PlayerEffectEvent extends PlayerEvent implements Cancellable { } /** - * @return What type of effects are applied, sie EffectType + * @return What type of effects are applied, see EffectType */ public EffectType getEffectType() { return effectType; @@ -66,27 +67,30 @@ public class PlayerEffectEvent extends PlayerEvent implements Cancellable { } + /** + * The Type of Effect, or why an effect is being added to the player. + */ public enum EffectType { /** * The Alcohol level demands its toll. - * Regularly applied depending on the players alcohol level - * By default it is just one Confusion effect + *

Regularly applied depending on the players alcohol level + *

By default it is just one Confusion effect */ ALCOHOL, /** - * Effects of a Brew are applied to the player (drinking the Brew) - * These depend on alcohol and quality of the brew + * Effects of a Brew are applied to the player (drinking the Brew). + *

These depend on alcohol and quality of the brew */ DRINK, /** - * When drinking a Brew with low Quality, these effects are applied + * When drinking a Brew with low Quality, these effects are applied. */ QUALITY, /** - * When logging in after drinking, Hangover Effects are applied + * When logging in after drinking, Hangover Effects are applied. */ HANGOVER diff --git a/src/com/dre/brewery/api/events/PlayerPukeEvent.java b/src/com/dre/brewery/api/events/PlayerPukeEvent.java index d4b8da6..05f3bbc 100644 --- a/src/com/dre/brewery/api/events/PlayerPukeEvent.java +++ b/src/com/dre/brewery/api/events/PlayerPukeEvent.java @@ -8,9 +8,9 @@ import org.bukkit.event.player.PlayerEvent; import org.jetbrains.annotations.NotNull; /** - * The player pukes (throws puke items to the ground) - * Those items can never be picked up and despawn after the time set in the config - * Number of items to drop can be changed with count + * The player pukes (throws puke items to the ground). + *

Those items can never be picked up and despawn after the time set in the config + *

Number of items to drop can be changed with count */ public class PlayerPukeEvent extends PlayerEvent implements Cancellable { private static final HandlerList handlers = new HandlerList(); @@ -25,14 +25,14 @@ public class PlayerPukeEvent extends PlayerEvent implements Cancellable { } /** - * @return The Amount of items being dropped this time + * Get the Amount of items being dropped this time */ public int getCount() { return count; } /** - * @param count Set the amount of items being dropped this time + * Set the amount of items being dropped this time */ public void setCount(int count) { this.count = count; diff --git a/src/com/dre/brewery/api/events/PlayerPushEvent.java b/src/com/dre/brewery/api/events/PlayerPushEvent.java index f7406bd..03290fe 100644 --- a/src/com/dre/brewery/api/events/PlayerPushEvent.java +++ b/src/com/dre/brewery/api/events/PlayerPushEvent.java @@ -9,9 +9,9 @@ import org.bukkit.util.Vector; import org.jetbrains.annotations.NotNull; /** - * The Players movement is hindered because of drunkeness - * Called each time before pushing the Player with the Vector push 10 times - * The Push Vector can be changed or multiplied + * The Players movement is hindered because of drunkeness. + *

Called each time before pushing the Player with the Vector push 10 times + *

The Push Vector can be changed or multiplied */ public class PlayerPushEvent extends PlayerEvent implements Cancellable { private static final HandlerList handlers = new HandlerList(); @@ -29,12 +29,9 @@ public class PlayerPushEvent extends PlayerEvent implements Cancellable { return bPlayer; } - // The Vector in which direction and magnitude the player is Pushed - // Can be changed directly or through setPush - /** - * Get the Vector in which direction and magnitude the player is pushed - * Can be changed directly or through setPush + * Get the Vector in which direction and magnitude the player is pushed. + *

Can be changed directly or through setPush * * @return The current push vector */ @@ -43,7 +40,7 @@ public class PlayerPushEvent extends PlayerEvent implements Cancellable { } /** - * Set the Push vector + * Set the Push vector. * * @param push The new push vector, not null */ diff --git a/src/com/dre/brewery/api/events/barrel/BarrelAccessEvent.java b/src/com/dre/brewery/api/events/barrel/BarrelAccessEvent.java index 256da96..b3c853d 100644 --- a/src/com/dre/brewery/api/events/barrel/BarrelAccessEvent.java +++ b/src/com/dre/brewery/api/events/barrel/BarrelAccessEvent.java @@ -8,9 +8,9 @@ import org.bukkit.event.HandlerList; import org.jetbrains.annotations.NotNull; /** - * A Player opens a Barrel by rightclicking it - * The PlayerInteractEvent on the Barrel may be cancelled. In that case this never gets called - * Can be cancelled to silently deny opening the Barrel + * A Player opens a Barrel by rightclicking it. + *

The PlayerInteractEvent on the Barrel may be cancelled. In that case this never gets called + *

Can be cancelled to silently deny opening the Barrel */ public class BarrelAccessEvent extends BarrelEvent implements Cancellable { private static final HandlerList handlers = new HandlerList(); @@ -26,7 +26,7 @@ public class BarrelAccessEvent extends BarrelEvent implements Cancellable { /** * Gets the Block that was actually clicked. - * For access Permissions getSpigot() should be used + *

For access Permissions getSpigot() should be used */ public Block getClickedBlock() { return clickedBlock; diff --git a/src/com/dre/brewery/api/events/barrel/BarrelCreateEvent.java b/src/com/dre/brewery/api/events/barrel/BarrelCreateEvent.java index 81be00d..ef9129e 100644 --- a/src/com/dre/brewery/api/events/barrel/BarrelCreateEvent.java +++ b/src/com/dre/brewery/api/events/barrel/BarrelCreateEvent.java @@ -7,8 +7,8 @@ import org.bukkit.event.HandlerList; import org.jetbrains.annotations.NotNull; /** - * Called when a Barrel is created by a Player by placing a Sign - * Cancelling this will silently fail the Barrel creation + * Called when a Barrel is created by a Player by placing a Sign. + *

Cancelling this will silently fail the Barrel creation */ public class BarrelCreateEvent extends BarrelEvent implements Cancellable { private static final HandlerList handlers = new HandlerList(); diff --git a/src/com/dre/brewery/api/events/barrel/BarrelDestroyEvent.java b/src/com/dre/brewery/api/events/barrel/BarrelDestroyEvent.java index 6ec802d..45ee763 100644 --- a/src/com/dre/brewery/api/events/barrel/BarrelDestroyEvent.java +++ b/src/com/dre/brewery/api/events/barrel/BarrelDestroyEvent.java @@ -9,10 +9,10 @@ import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; /** - * A Barrel is being destroyed by something, may not be by a Player - * A BarrelRemoveEvent will be called after this, if this is not cancelled - * Use the BarrelRemoveEvent to monitor any and all barrels being removed in a non cancellable way - * Cancelling the Event will stop the barrel from being destroyed + * A Barrel is being destroyed by something, may not be by a Player. + *

A BarrelRemoveEvent will be called after this, if this is not cancelled + *

Use the BarrelRemoveEvent to monitor any and all barrels being removed in a non cancellable way + *

Cancelling the Event will stop the barrel from being destroyed */ public class BarrelDestroyEvent extends BarrelEvent implements Cancellable { private static final HandlerList handlers = new HandlerList(); @@ -82,6 +82,9 @@ public class BarrelDestroyEvent extends BarrelEvent implements Cancellable { return handlers; } + /** + * The Reason why the Barrel is being destroyed. + */ public enum Reason { /** * A Player Broke the Barrel diff --git a/src/com/dre/brewery/api/events/barrel/BarrelRemoveEvent.java b/src/com/dre/brewery/api/events/barrel/BarrelRemoveEvent.java index d2b0f84..827d6de 100644 --- a/src/com/dre/brewery/api/events/barrel/BarrelRemoveEvent.java +++ b/src/com/dre/brewery/api/events/barrel/BarrelRemoveEvent.java @@ -5,7 +5,8 @@ import org.bukkit.event.HandlerList; import org.jetbrains.annotations.NotNull; /** - * A Barrel is being removed. There may have been a BarrelDestroyEvent before this + * A Barrel is being removed. + *

There may have been a BarrelDestroyEvent before this. * If not, Worldedit, other Plugins etc may be the cause for unexpected removal */ public class BarrelRemoveEvent extends BarrelEvent { diff --git a/src/com/dre/brewery/api/events/brew/BrewDrinkEvent.java b/src/com/dre/brewery/api/events/brew/BrewDrinkEvent.java index 56a6f8b..49f3378 100644 --- a/src/com/dre/brewery/api/events/brew/BrewDrinkEvent.java +++ b/src/com/dre/brewery/api/events/brew/BrewDrinkEvent.java @@ -9,9 +9,9 @@ import org.bukkit.inventory.meta.ItemMeta; import org.jetbrains.annotations.NotNull; /** - * A Player Drinks a Brew - * The amount of alcohol and quality that will be added to the player can be get/set here - * If cancelled the drinking will fail silently + * A Player Drinks a Brew. + *

The amount of alcohol and quality that will be added to the player can be get/set here + *

If cancelled the drinking will fail silently */ public class BrewDrinkEvent extends BrewEvent implements Cancellable { private static final HandlerList handlers = new HandlerList(); diff --git a/src/com/dre/brewery/api/events/brew/BrewEvent.java b/src/com/dre/brewery/api/events/brew/BrewEvent.java index c6fee36..aa76e7e 100644 --- a/src/com/dre/brewery/api/events/brew/BrewEvent.java +++ b/src/com/dre/brewery/api/events/brew/BrewEvent.java @@ -19,6 +19,9 @@ public abstract class BrewEvent extends Event { return brew; } + /** + * Gets the Meta of the Item this Brew is attached to + */ @NotNull public ItemMeta getItemMeta() { return meta; diff --git a/src/com/dre/brewery/api/events/brew/BrewModifyEvent.java b/src/com/dre/brewery/api/events/brew/BrewModifyEvent.java index 5a21187..74bed88 100644 --- a/src/com/dre/brewery/api/events/brew/BrewModifyEvent.java +++ b/src/com/dre/brewery/api/events/brew/BrewModifyEvent.java @@ -9,10 +9,10 @@ import org.bukkit.inventory.meta.PotionMeta; import org.jetbrains.annotations.NotNull; /** - * A Brew has been created or modified - * Usually happens on Filling from cauldron, distilling and aging. - * Modifications to the Brew or the PotionMeta can be done now - * Cancelling reverts the Brew to the state it was before the modification + * A Brew has been created or modified. + *

Usually happens on filling from cauldron, distilling and aging. + *

Modifications to the Brew or the PotionMeta can be done now + *

Cancelling reverts the Brew to the state it was before the modification */ public class BrewModifyEvent extends BrewEvent implements Cancellable { private static final HandlerList handlers = new HandlerList(); @@ -25,11 +25,17 @@ public class BrewModifyEvent extends BrewEvent implements Cancellable { this.type = type; } + /** + * Get the Type of modification being applied to the Brew. + */ @NotNull public Type getType() { return type; } + /** + * Get the BrewLore to modify lore on the Brew + */ @NotNull public BrewLore getLore() { return new BrewLore(getBrew(), (PotionMeta) getItemMeta()); @@ -42,7 +48,7 @@ public class BrewModifyEvent extends BrewEvent implements Cancellable { /** * Setting the Event cancelled cancels all modificatons to the brew. - * Modifications to the Brew or ItemMeta will not be applied + *

Modifications to the Brew or ItemMeta will not be applied */ @Override public void setCancelled(boolean cancelled) { @@ -60,13 +66,44 @@ public class BrewModifyEvent extends BrewEvent implements Cancellable { return handlers; } + /** + * The Type of Modification being applied to the Brew. + */ public enum Type { - CREATE, // A new Brew is created with arbitrary ways, like the create command - FILL, // Filled from a Cauldron into a new Brew - DISTILL, // Distilled in the Brewing stand - AGE, // Aged in a Barrel - UNLABEL, // Unlabeling Brew with command - STATIC, // Making Brew static with command - UNKNOWN // Unknown modification, unused + /** + * A new Brew is created with arbitrary ways, like the create command. + *

Cancelling this will disallow the creation + */ + CREATE, + + /** + * Filled from a Cauldron into a new Brew. + */ + FILL, + + /** + * Distilled in the Brewing stand. + */ + DISTILL, + + /** + * Aged in a Barrel. + */ + AGE, + + /** + * Unlabeling Brew with command. + */ + UNLABEL, + + /** + * Making Brew static with command. + */ + STATIC, + + /** + * Unknown modification, unused. + */ + UNKNOWN } } diff --git a/src/com/dre/brewery/listeners/InventoryListener.java b/src/com/dre/brewery/listeners/InventoryListener.java index b30d6e7..a27283f 100644 --- a/src/com/dre/brewery/listeners/InventoryListener.java +++ b/src/com/dre/brewery/listeners/InventoryListener.java @@ -68,7 +68,7 @@ public class InventoryListener implements Listener { /** * Clicking can either start or stop the new brew distillation tracking. - * Note that server restart will halt any ongoing brewing processes and + *

Note that server restart will halt any ongoing brewing processes and * they will _not_ restart until a new click event. */ @EventHandler(priority = EventPriority.HIGH, ignoreCancelled = true) diff --git a/src/com/dre/brewery/lore/BrewLore.java b/src/com/dre/brewery/lore/BrewLore.java index 7da480f..163fce2 100644 --- a/src/com/dre/brewery/lore/BrewLore.java +++ b/src/com/dre/brewery/lore/BrewLore.java @@ -15,6 +15,10 @@ import org.jetbrains.annotations.Nullable; import java.util.ArrayList; import java.util.List; +/** + * Represents the Lore on a Brew under Modification. + *

Can efficiently replace certain lines of lore, to update brew information on an item. + */ public class BrewLore { private Brew brew; private PotionMeta meta; @@ -32,8 +36,8 @@ public class BrewLore { } /** - * Write the new lore into the Meta - * Should be called at the end of operation on this Brew Lore + * Write the new lore into the Meta. + *

Should be called at the end of operation on this Brew Lore */ public PotionMeta write() { if (lineAddedOrRem) { @@ -286,7 +290,7 @@ public class BrewLore { /** * Adds or replaces a line of Lore. - * Searches for type and if not found for Substring lore and replaces it + *

Searches for type and if not found for Substring lore and replaces it * * @param type The Type of BrewLore to replace * @param prefix The Prefix to add to the line of lore @@ -473,6 +477,9 @@ public class BrewLore { return P.p.color(color); } + /** + * Type of Lore Line + */ public enum Type { STARS("§s"), CUSTOM("§t"), diff --git a/src/com/dre/brewery/lore/XORScrambleStream.java b/src/com/dre/brewery/lore/XORScrambleStream.java index d860088..0072375 100644 --- a/src/com/dre/brewery/lore/XORScrambleStream.java +++ b/src/com/dre/brewery/lore/XORScrambleStream.java @@ -7,8 +7,8 @@ import java.util.Random; /** * A Scramble Stream that uses XOR operations to scramble an outputstream. - * a byte generator feeded with the seed is used as xor source - * The resulting data can be unscrambled by the XORUnscrambleStream + *

a byte generator feeded with the seed is used as xor source + *

The resulting data can be unscrambled by the XORUnscrambleStream */ public class XORScrambleStream extends FilterOutputStream { @@ -29,8 +29,8 @@ public class XORScrambleStream extends FilterOutputStream { /** * To start the scrambling process this has to be called before writing any data to this stream. - * Before starting the scrambler, any data will just be passed through unscrambled to the underlying stream. - * The Scrambling can be started and stopped arbitrarily at any point, allowing for parts of unscrambled data in the stream. + *
Before starting the scrambler, any data will just be passed through unscrambled to the underlying stream. + *
The Scrambling can be started and stopped arbitrarily at any point, allowing for parts of unscrambled data in the stream. * * @throws IOException IOException */ @@ -50,15 +50,15 @@ public class XORScrambleStream extends FilterOutputStream { /** * Stop the scrambling, any following data will be passed through unscrambled. - * The scrambling can be started again at any point after calling this + *
The scrambling can be started again at any point after calling this */ public void stop() { running = false; } /** - * Mark the stream as unscrambled, any effort of unscrambing the data later will automatically read the already unscrambled data - * Useful if a stream may be scrambled or unscrambled, the unscrambler will automatically identify either way. + * Mark the stream as unscrambled, any effort of unscrambing the data later will automatically read the already unscrambled data. + *

Useful if a stream may be scrambled or unscrambled, the unscrambler will automatically identify either way. * * @throws IOException IOException * @throws IllegalStateException If the Scrambler was started in normal scrambling mode before diff --git a/src/com/dre/brewery/lore/XORUnscrambleStream.java b/src/com/dre/brewery/lore/XORUnscrambleStream.java index e418eb1..38a7123 100644 --- a/src/com/dre/brewery/lore/XORUnscrambleStream.java +++ b/src/com/dre/brewery/lore/XORUnscrambleStream.java @@ -11,8 +11,8 @@ 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 + *

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 { @@ -26,7 +26,7 @@ public class XORUnscrambleStream extends FilterInputStream { private SuccessType successType = SuccessType.NONE; /** - * Create a new instance of an XORUnscrambler, unscrambling the given inputstream + * 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 @@ -38,11 +38,12 @@ public class XORUnscrambleStream extends FilterInputStream { } /** - * 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. + * 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 + * @param prevSeeds List of previously used seeds */ public XORUnscrambleStream(InputStream in, long seed, List prevSeeds) { super(in); @@ -52,8 +53,8 @@ public class XORUnscrambleStream extends FilterInputStream { /** * 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. + *
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. @@ -99,7 +100,7 @@ public class XORUnscrambleStream extends FilterInputStream { /** * Stop the unscrambling, any following data will be passed through unmodified. - * The unscrambling can be started again at any point after calling this + *

The unscrambling can be started again at any point after calling this */ public void stop() { running = false; @@ -126,7 +127,7 @@ public class XORUnscrambleStream extends FilterInputStream { } /** - * What was used to unscramble the stream, it was already unscrambled, Main Seed, Prev Seed + * What was used to unscramble the stream: it was already unscrambled | Main Seed | Prev Seed * * @return The Type of Seed used to unscramble this, if any */ @@ -180,10 +181,28 @@ public class XORUnscrambleStream extends FilterInputStream { markRunning = running; } + /** + * What succeeded in unscrambling the Stream. + */ public static enum SuccessType { + /** + * The Stream was already unscrambled. + */ UNSCRAMBLED, + + /** + * The Main Seed was used to unscramble the Stream. + */ MAIN_SEED, + + /** + * One of the Previous Seeds was used to unscramble the Stream. + */ PREV_SEED, + + /** + * It was not successful. + */ NONE; } } diff --git a/src/com/dre/brewery/recipe/BCauldronRecipe.java b/src/com/dre/brewery/recipe/BCauldronRecipe.java index a724a30..c3143e6 100644 --- a/src/com/dre/brewery/recipe/BCauldronRecipe.java +++ b/src/com/dre/brewery/recipe/BCauldronRecipe.java @@ -16,6 +16,9 @@ import java.util.List; import java.util.Set; import java.util.stream.Collectors; +/** + * A Recipe for the Base Potion coming out of the Cauldron. + */ public class BCauldronRecipe { public static List recipes = new ArrayList<>(); public static int numConfigRecipes; @@ -32,8 +35,8 @@ public class BCauldronRecipe { /** - * A New Cauldron Recipe with the given name - * Use new BCauldronRecipe.Builder() for easier Cauldron Recipe Creation + * A New Cauldron Recipe with the given name. + *

Use new BCauldronRecipe.Builder() for easier Cauldron Recipe Creation * * @param name Name of the Cauldron Recipe */ @@ -134,9 +137,9 @@ public class BCauldronRecipe { /** * Find how much these ingredients match the given ones from 0-10. - * If any ingredient is missing, returns 0 - * If all Ingredients and their amounts are equal, returns 10 - * Returns something between 0 and 10 if all ingredients present, but differing amounts, depending on how much the amount differs. + *

If any ingredient is missing, returns 0 + *
If all Ingredients and their amounts are equal, returns 10 + *
Returns something between 0 and 10 if all ingredients present, but differing amounts, depending on how much the amount differs. */ public float getIngredientMatch(List items) { if (items.size() < ingredients.size()) { @@ -210,27 +213,27 @@ public class BCauldronRecipe { } /** - * Gets a Modifiable Sublist of the CauldronRecipes that are loaded by config - * Changes are directly reflected by the main list of all recipes - * Changes to the main List of all CauldronRecipes will make the reference to this sublist invalid + * Gets a Modifiable Sublist of the CauldronRecipes that are loaded by config. + *

Changes are directly reflected by the main list of all recipes + *
Changes to the main List of all CauldronRecipes will make the reference to this sublist invalid * - * After adding or removing elements, CauldronRecipes.numConfigRecipes MUST be updated! + *

After adding or removing elements, CauldronRecipes.numConfigRecipes MUST be updated! */ public static List getConfigRecipes() { return recipes.subList(0, numConfigRecipes); } /** - * Gets a Modifiable Sublist of the CauldronRecipes that are added by plugins - * Changes are directly reflected by the main list of all recipes - * Changes to the main List of all CauldronRecipes will make the reference to this sublist invalid + * Gets a Modifiable Sublist of the CauldronRecipes that are added by plugins. + *

Changes are directly reflected by the main list of all recipes + *
Changes to the main List of all CauldronRecipes will make the reference to this sublist invalid */ public static List getAddedRecipes() { return recipes.subList(numConfigRecipes, recipes.size()); } /** - * Gets the main List of all CauldronRecipes + * Gets the main List of all CauldronRecipes. */ public static List getAllRecipes() { return recipes; @@ -272,6 +275,9 @@ public class BCauldronRecipe { return null; }*/ + /** + * Builder to easily create BCauldron recipes. + */ public static class Builder { private BCauldronRecipe recipe; diff --git a/src/com/dre/brewery/recipe/BRecipe.java b/src/com/dre/brewery/recipe/BRecipe.java index 00ac4b1..753ce66 100644 --- a/src/com/dre/brewery/recipe/BRecipe.java +++ b/src/com/dre/brewery/recipe/BRecipe.java @@ -20,6 +20,9 @@ import java.util.Collections; import java.util.List; import java.util.ListIterator; +/** + * A Recipe used to Brew a Brewery Potion. + */ public class BRecipe { private static List recipes = new ArrayList<>(); @@ -54,8 +57,8 @@ public class BRecipe { } /** - * New BRecipe with Name - * Use new BRecipe.Builder() for easier Recipe Creation + * New BRecipe with Name. + *

Use new BRecipe.Builder() for easier Recipe Creation * * @param name The name for all qualities */ @@ -66,8 +69,8 @@ public class BRecipe { } /** - * New BRecipe with Names - * Use new BRecipe.Builder() for easier Recipe Creation + * New BRecipe with Names. + *

Use new BRecipe.Builder() for easier Recipe Creation * * @param names {name bad, name normal, name good} */ @@ -311,7 +314,9 @@ public class BRecipe { return null; } - // check every part of the recipe for validity + /** + * check every part of the recipe for validity. + */ public boolean isValid() { if (ingredients == null || ingredients.isEmpty()) { P.p.errorLog("No ingredients could be loaded for Recipe: " + getRecipeName()); @@ -348,7 +353,9 @@ public class BRecipe { return true; } - // allowed deviation to the recipes count of ingredients at the given difficulty + /** + * allowed deviation to the recipes count of ingredients at the given difficulty + */ public int allowedCountDiff(int count) { if (count < 8) { count = 8; @@ -361,7 +368,9 @@ public class BRecipe { return allowedCountDiff; } - // allowed deviation to the recipes cooking-time at the given difficulty + /** + * allowed deviation to the recipes cooking-time at the given difficulty + */ public int allowedTimeDiff(int time) { if (time < 8) { time = 8; @@ -374,7 +383,9 @@ public class BRecipe { return allowedTimeDiff; } - // difference between given and recipe-wanted woodtype + /** + * difference between given and recipe-wanted woodtype + */ public float getWoodDiff(float wood) { return Math.abs(wood - this.wood); } @@ -391,7 +402,9 @@ public class BRecipe { return age != 0; } - // true if given list misses an ingredient + /** + * true if given list misses an ingredient + */ public boolean isMissingIngredients(List list) { if (list.size() < ingredients.size()) { return true; @@ -431,7 +444,8 @@ public class BRecipe { } /** - * Create a Potion from this Recipe with best values. Quality can be set, but will reset to 10 if put in a barrel + * Create a Potion from this Recipe with best values. + * Quality can be set, but will reset to 10 if unset immutable and put in a barrel * * @param quality The Quality of the Brew * @return The Created Item @@ -441,7 +455,8 @@ public class BRecipe { } /** - * Create a Brew from this Recipe with best values. Quality can be set, but will reset to 10 if unset immutable and put in a barrel + * Create a Brew from this Recipe with best values. + * Quality can be set, but will reset to 10 if unset immutable and put in a barrel * * @param quality The Quality of the Brew * @return The created Brew @@ -478,7 +493,9 @@ public class BRecipe { // Getter - // how many of a specific ingredient in the recipe + /** + * how many of a specific ingredient in the recipe + */ public int amountOf(Ingredient ing) { for (RecipeItem rItem : ingredients) { if (rItem.matches(ing)) { @@ -488,7 +505,9 @@ public class BRecipe { return 0; } - // how many of a specific ingredient in the recipe + /** + * how many of a specific ingredient in the recipe + */ public int amountOf(ItemStack item) { for (RecipeItem rItem : ingredients) { if (rItem.matches(item)) { @@ -498,12 +517,16 @@ public class BRecipe { return 0; } - // Same as getName(5) + /** + * Same as getName(5) + */ public String getRecipeName() { return getName(5); } - // name that fits the quality + /** + * name that fits the quality + */ public String getName(int quality) { if (name.length > 2) { if (quality <= 3) { @@ -518,7 +541,9 @@ public class BRecipe { } } - // If one of the quality names equalIgnoreCase given name + /** + * If one of the quality names equalIgnoreCase given name + */ public boolean hasName(String name) { for (String test : this.name) { if (test.equalsIgnoreCase(name)) { @@ -549,7 +574,9 @@ public class BRecipe { return color; } - // get the woodtype + /** + * get the woodtype + */ public byte getWood() { return wood; } @@ -680,27 +707,27 @@ public class BRecipe { } /** - * Gets a Modifiable Sublist of the Recipes that are loaded by config - * Changes are directly reflected by the main list of all recipes - * Changes to the main List of all recipes will make the reference to this sublist invalid + * Gets a Modifiable Sublist of the Recipes that are loaded by config. + *

Changes are directly reflected by the main list of all recipes + *
Changes to the main List of all recipes will make the reference to this sublist invalid * - * After adding or removing elements, BRecipe.numConfigRecipes MUST be updated! + *

After adding or removing elements, BRecipe.numConfigRecipes MUST be updated! */ public static List getConfigRecipes() { return recipes.subList(0, numConfigRecipes); } /** - * Gets a Modifiable Sublist of the Recipes that are added by plugins - * Changes are directly reflected by the main list of all recipes - * Changes to the main List of all recipes will make the reference to this sublist invalid + * Gets a Modifiable Sublist of the Recipes that are added by plugins. + *

Changes are directly reflected by the main list of all recipes + *
Changes to the main List of all recipes will make the reference to this sublist invalid */ public static List getAddedRecipes() { return recipes.subList(numConfigRecipes, recipes.size()); } /** - * Gets the main List of all recipes + * Gets the main List of all recipes. */ public static List getAllRecipes() { return recipes; @@ -725,6 +752,9 @@ public class BRecipe { }*/ + /** + * Builder to easily create Recipes + */ public static class Builder { private BRecipe recipe; diff --git a/src/com/dre/brewery/recipe/CustomItem.java b/src/com/dre/brewery/recipe/CustomItem.java index dd83ab5..9ec3d30 100644 --- a/src/com/dre/brewery/recipe/CustomItem.java +++ b/src/com/dre/brewery/recipe/CustomItem.java @@ -16,7 +16,7 @@ import java.util.Objects; /** * Minecraft Item with custon name and lore. - * Mostly used for Custom Items of the Config, but also for general custom items + *

Mostly used for Custom Items of the Config, but also for general custom items */ public class CustomItem extends RecipeItem implements Ingredient { @@ -167,7 +167,7 @@ public class CustomItem extends RecipeItem implements Ingredient { /** * If this item has lore that matches the given lore. - * It matches if our lore is contained in the given lore consecutively, ignoring color of the given lore. + *

It matches if our lore is contained in the given lore consecutively, ignoring color of the given lore. * * @param usedLore The given lore to match * @return True if the given lore contains our lore consecutively diff --git a/src/com/dre/brewery/recipe/CustomMatchAnyItem.java b/src/com/dre/brewery/recipe/CustomMatchAnyItem.java index 840747d..99dc570 100644 --- a/src/com/dre/brewery/recipe/CustomMatchAnyItem.java +++ b/src/com/dre/brewery/recipe/CustomMatchAnyItem.java @@ -13,7 +13,7 @@ import java.util.Objects; /** * Custom Item that matches any one of the given info. - * Does not implement Ingredient, as it can not directly be added to an ingredient + *

Does not implement Ingredient, as it can not directly be added to an ingredient */ public class CustomMatchAnyItem extends RecipeItem { diff --git a/src/com/dre/brewery/recipe/Ingredient.java b/src/com/dre/brewery/recipe/Ingredient.java index 9d8ab64..3d27118 100644 --- a/src/com/dre/brewery/recipe/Ingredient.java +++ b/src/com/dre/brewery/recipe/Ingredient.java @@ -9,11 +9,11 @@ import java.util.Map; import java.util.function.Function; /** - * Item used in a BIngredients, inside BCauldron or Brew. - * Represents the Items used as ingredients in the Brewing process - * Can be a copy of a recipe item - * Will be saved and loaded with a DataStream - * Each implementing class needs to register a static function as Item Loader + * Item used in a BIngredients, inside BCauldron or Brew, + * Represents the Items used as ingredients in the Brewing process. + *

Can be a copy of a recipe item + *

Will be saved and loaded with a DataStream + *

Each implementing class needs to register a static function as Item Loader */ public interface Ingredient { @@ -21,7 +21,7 @@ public interface Ingredient { /** * Register a Static function as function that takes an ItemLoader, containing a DataInputStream. - * Using the Stream it constructs a corresponding Ingredient for the chosen SaveID + *

Using the Stream it constructs a corresponding Ingredient for the chosen SaveID * * @param saveID The SaveID should be a small identifier like "AB" * @param loadFct The Static Function that loads the Item, i.e. @@ -43,10 +43,10 @@ public interface Ingredient { /** * Saves this Ingredient to the DataOutputStream. - * The first data HAS to be storing the SaveID like: + *

The first data HAS to be storing the SaveID like: * out.writeUTF("AB"); - * Amount will be saved automatically and does not have to be saved here. - * Saving is done to Brew or for BCauldron into data.yml + *

Amount will be saved automatically and does not have to be saved here. + *

Saving is done to Brew or for BCauldron into data.yml * * @param out The outputstream to write to * @throws IOException Any IOException @@ -67,9 +67,8 @@ public interface Ingredient { /* * Does this Item match the given RecipeItem. - * An IngredientItem matches a RecipeItem if all required info of the RecipeItem are fulfilled on this IngredientItem - * This does not imply that the same holds the other way round, as this item might have more info than needed - * + *

An IngredientItem matches a RecipeItem if all required info of the RecipeItem are fulfilled on this IngredientItem + *

This does not imply that the same holds the other way round, as this item might have more info than needed * * @param recipeItem The recipeItem whose requirements need to be fulfilled * @return True if this matches the required info of the recipeItem @@ -77,7 +76,7 @@ public interface Ingredient { //boolean matches(RecipeItem recipeItem); /** - * The other Ingredient is Similar if it is equal except amount + * The other Ingredient is Similar if it is equal except amount. * * @param item The item to check similarity with * @return True if this is equal to item except for amount diff --git a/src/com/dre/brewery/recipe/PluginItem.java b/src/com/dre/brewery/recipe/PluginItem.java index 8234e87..3a02a1a 100644 --- a/src/com/dre/brewery/recipe/PluginItem.java +++ b/src/com/dre/brewery/recipe/PluginItem.java @@ -16,8 +16,8 @@ import java.util.function.Supplier; /** * An Item of a Recipe or as Ingredient in a Brew that corresponds to an item from another plugin. - * See /integration/item for examples on how to extend this class. - * This class stores items as name of the plugin and item id + *

See /integration/item for examples on how to extend this class. + *

This class stores items as name of the plugin and item id */ public abstract class PluginItem extends RecipeItem implements Ingredient { @@ -72,14 +72,14 @@ public abstract class PluginItem extends RecipeItem implements Ingredient { /** * Called after Loading this Plugin Item from Config, or (by default) from Ingredients. - * Allows Override to define custom actions after an Item was constructed + *

Allows Override to define custom actions after an Item was constructed */ protected void onConstruct() { } /** * Does this PluginItem Match the other Ingredient. - * By default it matches exactly when they are similar, i.e. also a PluginItem with same parameters + *

By default it matches exactly when they are similar, i.e. also a PluginItem with same parameters * * @param ingredient The ingredient that needs to fulfill the requirements * @return True if the ingredient matches the required info of this @@ -132,8 +132,8 @@ public abstract class PluginItem extends RecipeItem implements Ingredient { } /** - * Called when loading this Plugin Item from Ingredients (of a Brew) - * The default loading is the same as loading from Config + * Called when loading this Plugin Item from Ingredients (of a Brew). + *

The default loading is the same as loading from Config * * @param loader The ItemLoader from which to load the data, use loader.getInputStream() * @return The constructed PluginItem @@ -161,8 +161,8 @@ public abstract class PluginItem extends RecipeItem implements Ingredient { } /** - * Needs to be called at Server start - * Registers the chosen SaveID and the loading Method for loading from Brew or BCauldron + * Registers the chosen SaveID and the loading Method for loading from Brew or BCauldron. + *

Needs to be called at Server start. */ public static void registerItemLoader() { Ingredient.registerForItemLoader("PI", PluginItem::loadFrom); @@ -170,8 +170,8 @@ public abstract class PluginItem extends RecipeItem implements Ingredient { /** - * Called when loading trying to find a config defined Plugin Item, or by default also when loading from ingredients - * Will call a registered constructor matching the given plugin identifier + * Called when loading trying to find a config defined Plugin Item. By default also when loading from ingredients + *

Will call a registered constructor matching the given plugin identifier * * @param plugin The Identifier of the Plugin used in the config * @param itemId The Identifier of the Item belonging to this Plugin used in the config @@ -193,11 +193,11 @@ public abstract class PluginItem extends RecipeItem implements Ingredient { /** * This needs to be called at Server Start before Brewery loads its data. - * When implementing this, put Brewery as softdepend in your plugin.yml! - * Registers a Constructor that returns a new or cloned instance of a PluginItem - * This Constructor will be called when loading a Plugin Item from Config or by default from ingredients - * After the Constructor is called, the plugin and itemid will be set on the new instance - * Finally the onConstruct is called. + *

When implementing this, put Brewery as softdepend in your plugin.yml! + *

Registers a Constructor that returns a new or cloned instance of a PluginItem + *
This Constructor will be called when loading a Plugin Item from Config or by default from ingredients + *
After the Constructor is called, the plugin and itemid will be set on the new instance + *

Finally the onConstruct is called. * * @param pluginId The ID to use in the config * @param constructor The constructor i.e. YourPluginItem::new diff --git a/src/com/dre/brewery/recipe/RecipeItem.java b/src/com/dre/brewery/recipe/RecipeItem.java index 9f1b216..48bf510 100644 --- a/src/com/dre/brewery/recipe/RecipeItem.java +++ b/src/com/dre/brewery/recipe/RecipeItem.java @@ -17,8 +17,8 @@ import java.util.stream.Collectors; /** * Item that can be used in a Recipe. - * They are not necessarily only loaded from config - * They are immutable if used in a recipe. If one implements Ingredient, + *

They are not necessarily only loaded from config + *

They are immutable if used in a recipe. If one implements Ingredient, * it can be used as mutable copy directly in a * BIngredients. Otherwise it needs to be converted to an Ingredient */ @@ -31,7 +31,7 @@ public abstract class RecipeItem implements Cloneable { /** * Does this RecipeItem match the given ItemStack? - * Used to determine if the given item corresponds to this recipeitem + *

Used to determine if the given item corresponds to this recipeitem * * @param item The ItemStack for comparison * @return True if the given item matches this recipeItem @@ -39,9 +39,9 @@ public abstract class RecipeItem implements Cloneable { public abstract boolean matches(ItemStack item); /** - * Does this Item match the given Ingredient. - * A RecipeItem matches an Ingredient if all required info of the RecipeItem are fulfilled on the Ingredient - * This does not imply that the same holds the other way round, as the ingredient item might have more info than needed + * Does this Item match the given Ingredient? + *

A RecipeItem matches an Ingredient if all required info of the RecipeItem are fulfilled on the Ingredient + *
This does not imply that the same holds the other way round, as the ingredient item might have more info than needed * * * @param ingredient The ingredient that needs to fulfill the requirements @@ -51,7 +51,7 @@ public abstract class RecipeItem implements Cloneable { /** * Get the Corresponding Ingredient Item. For Items implementing Ingredient, just getMutableCopy() - * This is called when this recipe item is added to a BIngredients + *

This is called when this recipe item is added to a BIngredients * * @param forItem The ItemStack that has previously matched this RecipeItem. Used if the resulting Ingredient needs more info from the ItemStack * @return The IngredientItem corresponding to this RecipeItem @@ -92,9 +92,9 @@ public abstract class RecipeItem implements Cloneable { } /** - * Set the Amount of this Item in a Recipe - * The amount can not be set on an existing item in a recipe or existing custom item. - * To change amount you need to use getMutableCopy() and change the amount on the copy + * Set the Amount of this Item in a Recipe. + *

The amount can not be set on an existing item in a recipe or existing custom item. + *
To change amount you need to use getMutableCopy() and change the amount on the copy * * @param amount The new amount */ @@ -128,12 +128,12 @@ public abstract class RecipeItem implements Cloneable { /** * Tries to find a matching RecipeItem for this item. It checks custom items and if it has found a unique custom item - * it will return that. If there are multiple matching custom items, a new CustomItem with all item info is returned - * If there is no matching CustomItem, it will return a SimpleItem with the items type + * it will return that. If there are multiple matching custom items, a new CustomItem with all item info is returned. + *
If there is no matching CustomItem, it will return a SimpleItem with the items type * * @param item The Item for which to find a matching RecipeItem * @param acceptAll If true it will accept any item and return a SimpleItem even if not on the accepted list - * If false it will return null if the item is not acceptable by the Cauldron + *
If false it will return null if the item is not acceptable by the Cauldron * @return The Matched CustomItem, new CustomItem with all item info or SimpleItem */ @Nullable diff --git a/src/com/dre/brewery/utility/BUtil.java b/src/com/dre/brewery/utility/BUtil.java index 9ce5ad2..64c7563 100644 --- a/src/com/dre/brewery/utility/BUtil.java +++ b/src/com/dre/brewery/utility/BUtil.java @@ -59,7 +59,9 @@ public class BUtil { } } - // returns the Player if online + /** + * returns the Player if online + */ public static Player getPlayerfromString(String name) { if (P.useUUID) { try { @@ -97,7 +99,7 @@ public class BUtil { } /** - * Load A List of Strings from config. If found a single String, will convert to List + * Load A List of Strings from config, if found a single String, will convert to List */ @Nullable public static List loadCfgStringList(ConfigurationSection cfg, String path) { @@ -112,7 +114,7 @@ public class BUtil { } /** - * Load a String from config. If found a List, will return the first String + * Load a String from config, if found a List, will return the first String */ @Nullable public static String loadCfgString(ConfigurationSection cfg, String path) { diff --git a/src/com/dre/brewery/utility/LegacyUtil.java b/src/com/dre/brewery/utility/LegacyUtil.java index f19aa93..13f039e 100644 --- a/src/com/dre/brewery/utility/LegacyUtil.java +++ b/src/com/dre/brewery/utility/LegacyUtil.java @@ -191,7 +191,11 @@ public class LegacyUtil { } } - // 0 = empty, 1 = something in, 2 = full + /** + * Get The Fill Level of a Cauldron Block, 0 = empty, 1 = something in, 2 = full + * + * @return 0 = empty, 1 = something in, 2 = full + */ public static byte getFillLevel(Block block) { if (block.getType() != Material.CAULDRON) { return EMPTY; @@ -219,7 +223,7 @@ public class LegacyUtil { } } - /* + /** * only used to convert a very old Datafile or config from a very old version */ public static Material getMaterial(int id) { diff --git a/src/com/dre/brewery/utility/Tuple.java b/src/com/dre/brewery/utility/Tuple.java index e388de5..95ac019 100644 --- a/src/com/dre/brewery/utility/Tuple.java +++ b/src/com/dre/brewery/utility/Tuple.java @@ -46,8 +46,6 @@ public class Tuple { /** * Gets the first value in the tuple - * - * @return */ public A first() { return a; @@ -55,8 +53,6 @@ public class Tuple { /** * Gets the second value in the tuple - * - * @return */ public B second() { return b; @@ -64,8 +60,6 @@ public class Tuple { /** * Gets the first value in the tuple, Synonym for first() - * - * @return */ public A a() { return a; @@ -73,8 +67,6 @@ public class Tuple { /** * Gets the second value in the tuple, Synonym for second() - * - * @return */ public B b() { return b; From 40da30bf8e725df23b7fab6576b6fc25ea76399e Mon Sep 17 00:00:00 2001 From: Sn0wStorm Date: Tue, 26 Nov 2019 21:29:41 +0100 Subject: [PATCH 46/51] Optimizing Barrel retrieve --- src/com/dre/brewery/Barrel.java | 40 +++++++++++++++---- .../dre/brewery/listeners/PlayerListener.java | 10 ++--- 2 files changed, 36 insertions(+), 14 deletions(-) diff --git a/src/com/dre/brewery/Barrel.java b/src/com/dre/brewery/Barrel.java index a547285..a25468d 100644 --- a/src/com/dre/brewery/Barrel.java +++ b/src/com/dre/brewery/Barrel.java @@ -82,13 +82,21 @@ public class Barrel implements InventoryHolder { // Minecraft day is 20 min, so add 1/20 to the time every minute barrel.time += (1.0 / 20.0); } - if (check == 0 && barrels.size() > 0) { - Barrel random = barrels.get((int) Math.floor(Math.random() * barrels.size())); + int numBarrels = barrels.size(); + if (check == 0 && numBarrels > 0) { + Barrel random = barrels.get((int) Math.floor(Math.random() * numBarrels)); if (random != null) { // You have been selected for a random search // We want to check at least one barrel every time random.checked = false; } + if (numBarrels > 50) { + Barrel randomInTheBack = barrels.get(numBarrels - 1 - (int) (Math.random() * (numBarrels >>> 2))); + if (randomInTheBack != null) { + // Prioritize checking one of the less recently used barrels as well + randomInTheBack.checked = false; + } + } new BarrelCheck().runTaskTimer(P.p, 1, 1); } } @@ -273,6 +281,7 @@ public class Barrel implements InventoryHolder { signoffset = (byte) (sign.getY() - spigot.getY()); } + int i = 0; for (Barrel barrel : barrels) { if (barrel.body.isSignOfBarrel(signoffset)) { if (barrel.spigot.equals(spigot)) { @@ -280,9 +289,11 @@ public class Barrel implements InventoryHolder { // Barrel has no signOffset even though we clicked a sign, may be old barrel.body.setSignoffset(signoffset); } + moveMRU(i); return barrel; } } + i++; } return null; } @@ -293,15 +304,27 @@ public class Barrel implements InventoryHolder { @Nullable public static Barrel getByWood(Block wood) { if (LegacyUtil.isWoodPlanks(wood.getType()) || LegacyUtil.isWoodStairs(wood.getType())) { + int i = 0; for (Barrel barrel : barrels) { if (barrel.getSpigot().getWorld().equals(wood.getWorld()) && barrel.body.getBounds().contains(wood)) { + moveMRU(i); return barrel; } + i++; } } return null; } + // Move Barrel that was recently used more towards the front of the List + // Optimizes retrieve by Block over time + private static void moveMRU(int index) { + if (index > 0) { + // Swap entry at the index with the one next to it + barrels.set(index - 1, barrels.set(index, barrels.get(index - 1))); + } + } + /** * creates a new Barrel out of a sign */ @@ -331,7 +354,7 @@ public class Barrel implements InventoryHolder { BarrelCreateEvent createEvent = new BarrelCreateEvent(barrel, player); P.p.getServer().getPluginManager().callEvent(createEvent); if (!createEvent.isCancelled()) { - barrels.add(barrel); + barrels.add(0, barrel); return true; } } @@ -517,14 +540,15 @@ public class Barrel implements InventoryHolder { if (!barrel.checked) { Block broken = barrel.body.getBrokenBlock(false); if (broken != null) { - P.p.debugLog("Barrel at " + broken.getWorld().getName() + "/" + broken.getX() + "/" + broken.getY() + "/" + broken.getZ() - + " has been destroyed unexpectedly, contents will drop"); + P.p.debugLog("Barrel at " + + broken.getWorld().getName() + "/" + broken.getX() + "/" + broken.getY() + "/" + broken.getZ() + + " has been destroyed unexpectedly, contents will drop"); // remove the barrel if it was destroyed barrel.remove(broken, null, true); } else { - // Dont check this barrel again, its enough to check it once after every restart - // as now this is only the backup if we dont register the barrel breaking, as sample - // when removing it with some world editor + // Dont check this barrel again, its enough to check it once after every restart (and when randomly chosen) + // as now this is only the backup if we dont register the barrel breaking, + // for example when removing it with some world editor barrel.checked = true; } repeat = false; diff --git a/src/com/dre/brewery/listeners/PlayerListener.java b/src/com/dre/brewery/listeners/PlayerListener.java index 70bf2cd..ab1d99c 100644 --- a/src/com/dre/brewery/listeners/PlayerListener.java +++ b/src/com/dre/brewery/listeners/PlayerListener.java @@ -52,12 +52,10 @@ public class PlayerListener implements Listener { barrel = Barrel.getByWood(clickedBlock); } } else if (LegacyUtil.isWoodStairs(type)) { - for (Barrel barrel2 : Barrel.barrels) { - if (barrel2.getBody().hasBlock(clickedBlock)) { - if (BConfig.openEverywhere || !barrel2.isLarge()) { - barrel = barrel2; - } - break; + barrel = Barrel.getByWood(clickedBlock); + if (barrel != null) { + if (!BConfig.openEverywhere && barrel.isLarge()) { + barrel = null; } } } else if (LegacyUtil.isFence(type) || LegacyUtil.isSign(type)) { From 6577cbf62858c9658ff442b647c4bc2ae5a3e3ed Mon Sep 17 00:00:00 2001 From: Sn0wStorm Date: Wed, 27 Nov 2019 13:52:19 +0100 Subject: [PATCH 47/51] Added Barrel Check for GamemodeInventories --- resources/config/v13/de/config.yml | 1 + resources/config/v13/en/config.yml | 1 + src/com/dre/brewery/Barrel.java | 1 - src/com/dre/brewery/filedata/BConfig.java | 2 ++ .../integration/IntegrationListener.java | 35 +++++++++++++++++-- 5 files changed, 37 insertions(+), 3 deletions(-) diff --git a/resources/config/v13/de/config.yml b/resources/config/v13/de/config.yml index be39ba1..cbd5763 100644 --- a/resources/config/v13/de/config.yml +++ b/resources/config/v13/de/config.yml @@ -409,6 +409,7 @@ recipes: useWorldGuard: true useLWC: true useGriefPrevention: true +useGMInventories: true # Änderungen an Fassinventaren mit LogBlock aufzeichen [true] useLogBlock: true diff --git a/resources/config/v13/en/config.yml b/resources/config/v13/en/config.yml index 2704767..5717cce 100644 --- a/resources/config/v13/en/config.yml +++ b/resources/config/v13/en/config.yml @@ -411,6 +411,7 @@ recipes: useWorldGuard: true useLWC: true useGriefPrevention: true +useGMInventories: true # Enable the Logging of Barrel Inventories to LogBlock [true] useLogBlock: true diff --git a/src/com/dre/brewery/Barrel.java b/src/com/dre/brewery/Barrel.java index a25468d..caf3314 100644 --- a/src/com/dre/brewery/Barrel.java +++ b/src/com/dre/brewery/Barrel.java @@ -119,7 +119,6 @@ public class Barrel implements InventoryHolder { // Listened to by WGBarrel7, WGBarrelNew, WGBarrelOld, GriefPreventionBarrel (IntegrationListener) P.p.getServer().getPluginManager().callEvent(accessEvent); if (accessEvent.isCancelled()) { - P.p.msg(player, P.p.languageReader.get("Error_NoBarrelAccess")); return false; } diff --git a/src/com/dre/brewery/filedata/BConfig.java b/src/com/dre/brewery/filedata/BConfig.java index e63def2..3c698dd 100644 --- a/src/com/dre/brewery/filedata/BConfig.java +++ b/src/com/dre/brewery/filedata/BConfig.java @@ -48,6 +48,7 @@ public class BConfig { public static boolean useGP; //GriefPrevention public static boolean hasVault; // Vault public static boolean useCitadel; // CivCraft/DevotedMC Citadel + public static boolean useGMInventories; // GamemodeInventories public static Boolean hasSlimefun = null; // Slimefun ; Null if not checked public static Boolean hasMMOItems = null; // MMOItems ; Null if not checked @@ -194,6 +195,7 @@ public class BConfig { useLWC = config.getBoolean("useLWC", true) && plMan.isPluginEnabled("LWC"); useGP = config.getBoolean("useGriefPrevention", true) && plMan.isPluginEnabled("GriefPrevention"); useLB = config.getBoolean("useLogBlock", false) && plMan.isPluginEnabled("LogBlock"); + useGMInventories = config.getBoolean("useGMInventories", false); useCitadel = config.getBoolean("useCitadel", false) && plMan.isPluginEnabled("Citadel"); // The item util has been removed in Vault 1.7+ hasVault = plMan.isPluginEnabled("Vault") diff --git a/src/com/dre/brewery/integration/IntegrationListener.java b/src/com/dre/brewery/integration/IntegrationListener.java index 7b77de1..c4c8a19 100644 --- a/src/com/dre/brewery/integration/IntegrationListener.java +++ b/src/com/dre/brewery/integration/IntegrationListener.java @@ -15,6 +15,7 @@ import com.dre.brewery.recipe.RecipeItem; import com.dre.brewery.utility.LegacyUtil; import net.Indyuce.mmoitems.MMOItems; import net.Indyuce.mmoitems.api.item.NBTItem; +import org.bukkit.GameMode; import org.bukkit.Material; import org.bukkit.block.Block; import org.bukkit.entity.Player; @@ -37,6 +38,7 @@ public class IntegrationListener implements Listener { try { if (!BConfig.wg.checkAccess(event.getPlayer(), event.getSpigot(), plugin)) { event.setCancelled(true); + P.p.msg(event.getPlayer(), P.p.languageReader.get("Error_NoBarrelAccess")); } } catch (Throwable e) { event.setCancelled(true); @@ -58,10 +60,37 @@ public class IntegrationListener implements Listener { @EventHandler(priority = EventPriority.LOW, ignoreCancelled = true) public void onBarrelAccess(BarrelAccessEvent event) { + if (BConfig.useGMInventories) { + Plugin pl = P.p.getServer().getPluginManager().getPlugin("GameModeInventories"); + if (pl != null && pl.isEnabled()) { + try { + if (pl.getConfig().getBoolean("restrict_creative")) { + Player player = event.getPlayer(); + if (player.getGameMode() == GameMode.CREATIVE) { + if (!pl.getConfig().getBoolean("bypass.inventories") || (!player.hasPermission("gamemodeinventories.bypass") && !player.isOp())) { + event.setCancelled(true); + if (!pl.getConfig().getBoolean("dont_spam_chat")) { + P.p.msg(event.getPlayer(), P.p.languageReader.get("Error_NoBarrelAccess")); + } + return; + } + } + } + } catch (Throwable e) { + P.p.errorLog("Failed to Check GameModeInventories for Barrel Open Permissions!"); + P.p.errorLog("Players will be able to open Barrel with GameMode Creative"); + e.printStackTrace(); + BConfig.useGMInventories = false; + } + } else { + BConfig.useGMInventories = false; + } + } if (BConfig.useGP) { if (P.p.getServer().getPluginManager().isPluginEnabled("GriefPrevention")) { try { if (!GriefPreventionBarrel.checkAccess(event)) { + P.p.msg(event.getPlayer(), P.p.languageReader.get("Error_NoBarrelAccess")); event.setCancelled(true); return; } @@ -94,9 +123,11 @@ public class IntegrationListener implements Listener { Player player = event.getPlayer(); try { if (!LWCBarrel.checkAccess(player, sign, plugin)) { + P.p.msg(event.getPlayer(), P.p.languageReader.get("Error_NoBarrelAccess")); event.setCancelled(true); } } catch (Throwable e) { + event.setCancelled(true); P.p.errorLog("Failed to Check LWC for Barrel Open Permissions!"); P.p.errorLog("Brewery was tested with version 4.5.0 of LWC!"); P.p.errorLog("Disable the LWC support in the config and do /brew reload"); @@ -105,7 +136,7 @@ public class IntegrationListener implements Listener { P.p.msg(player, "&cLWC check Error, Brewery was tested with up to v4.5.0 of LWC"); P.p.msg(player, "&cSet &7useLWC: false &cin the config and /brew reload"); } else { - P.p.msg(player, "&cError breaking Barrel, please report to an Admin!"); + P.p.msg(player, "&cError opening Barrel, please report to an Admin!"); } } } @@ -134,7 +165,7 @@ public class IntegrationListener implements Listener { P.p.msg(player, "&cLWC check Error, Brewery was tested with up to v4.5.0 of LWC"); P.p.msg(player, "&cSet &7useLWC: false &cin the config and /brew reload"); } else { - P.p.msg(player, "&cError opening Barrel, please report to an Admin!"); + P.p.msg(player, "&cError breaking Barrel, please report to an Admin!"); } } } else { From c6ea0cd49384b48b00470da124af69692535066b Mon Sep 17 00:00:00 2001 From: Sn0wStorm Date: Fri, 29 Nov 2019 18:00:49 +0100 Subject: [PATCH 48/51] Updated other Config and Language variations --- resources/config/v12/de/config.yml | 173 +++++++-- resources/config/v12/en/config.yml | 200 ++++++++-- resources/config/v12/fr/config.yml | 206 +++++++++-- resources/config/v12/it/config.yml | 166 ++++++++- resources/config/v13/de/config.yml | 1 + resources/config/v13/en/config.yml | 8 +- resources/config/v13/fr/config.yml | 421 ++++++++++++++-------- resources/config/v13/it/config.yml | 389 +++++++++++++------- resources/config/v13/zh/config.yml | 391 +++++++++++++------- resources/languages/de.yml | 20 +- resources/languages/fr.yml | 6 +- resources/languages/it.yml | 2 + resources/languages/tw.yml | 2 + resources/languages/zh.yml | 2 + src/com/dre/brewery/filedata/BConfig.java | 8 +- 15 files changed, 1459 insertions(+), 536 deletions(-) diff --git a/resources/config/v12/de/config.yml b/resources/config/v12/de/config.yml index c232ab4..7d2b47d 100644 --- a/resources/config/v12/de/config.yml +++ b/resources/config/v12/de/config.yml @@ -76,11 +76,119 @@ updateCheck: true # Autosave Intervall in Minuten [3] autosave: 3 +# Debug Nachrichten im Log anzeigen [false] +debug: false + # Config Version version: '1.8' oldMat: true + +# -- Eigene Items Definieren -- +# Die festgelegte id kann dann in einem Rezept verwendet werden + +# matchAny: true wenn es schon reicht wenn eine der Angaben zutrifft +# material: Welche Art das Item haben muss +# name: Welchen Namen das Item haben muss (Farbcodes möglich: z.b. &6) +# lore: Was in der Lore des Items stehen muss + +customItems: + bsp-item: + # Ein Bedrock Item das Mauer heißt und in der Lore die angegebene Zeile hat + material: BEDROCK + name: 'Mauer' + lore: + - '&7Besonders gut geschützt' + + bsp-item2: + # Mit matchAny muss nur eine der Angaben zutreffen. + # Hier also eine der Türarten, oder ein Item namens Buchenholztür, oder ein Item mit 'Eine Tür' in der Lore + matchAny: true + material: + - WOODEN_DOOR + - IRON_DOOR + name: + - 'Buchenholztür' + lore: + - 'Eine Tür' + + himbeere: + name: '&cHimbeere' + + +# -- Zutaten im Kessel -- +# Hier kann angegeben werden welche Zutaten in den Kessel getan werden können und was mit ihnen geschieht. + +# name: Name des Basistrankes der aus dem Kessel kommt (Farbcodes möglich: z.b. &6) +# ingredients: Auflistung von 'Material/Anzahl' +# Halte ein Item in der Hand und benutze /brew ItemName um dessen Material herauszufinden und für ein Rezept zu benutzen +# (Item-ids anstatt Material können in Bukkit nicht mehr benutzt werden) +# Eine Liste von allen Materialien kann hier gefunden werden: https://hub.spigotmc.org/javadocs/spigot/org/bukkit/Material.html +# color: Farbe des Trankes der aus dem Kessel kommt +# Benutzbare Farben: DARK_RED, RED, BRIGHT_RED, ORANGE, PINK, BLUE, CYAN, WATER, GREEN, BLACK, GREY, BRIGHT_GREY +# Oder RGB Farben (Hex: also zB '99FF33') (Ohne #) (mit '') (Einfach nach "HTML color" im Internet suchen) +# lore: Auflistung von zusätzlichem Text auf dem Trank. (Farbcodes möglich: z.b. &6) + + +cauldron: + bsp: + name: Beispiel + ingredients: + - BEDROCK/2 + - DIAMOND + color: BLACK + lore: + - Ein Beispiel für einen Basistrank + - So kommt er aus dem Kessel + +# -- Eine Zutat: -- + wheat: + name: Getreideferment + ingredients: WHEAT + + sugarcane: + name: Zuckersud + ingredients: SUGAR_CANE + color: 'f1ffad' # gelbliches grün + + apple: + name: Apfelmost + ingredients: APPLE + + potato: + name: Kartoffelmaische + ingredients: POTATO_ITEM + + grass: + name: Kräuterbrühe + ingredients: LONG_GRASS + color: '99ff66' # helles grün + + rmushroom: + name: Pilzsud + ingredients: RED_MUSHROOM + color: 'ff5c33' # bernsteinrot + + cocoa: + name: Kakaobrühe + ingredients: INK_SACK + color: '804600' # mokka + + milk: + name: Milchiges Wasser + ingredients: MILK_BUCKET + color: BRIGHT_GREY + + # -- Mehrere Zutaten: -- + apfelmet_basis: + name: Apfel-Zuckersud + ingredients: + - SUGAR_CANE/3 + - APPLE + color: 'e1ff4d' # grünliches gelb + + # -- Rezepte für Getränke -- # name: Verschiedene Namen für schlecht/mittel/gut (Farbcodes möglich: z.b. &6) @@ -104,6 +212,10 @@ oldMat: true # alcohol: Alkoholgehalt 0-100 in absoluter Menge bei perfektem Getränk (wird dem Spieler hinzugefügt, bei 100 = tot) # lore: Auflistung von zusätzlichem Text auf dem fertigen Trank. (Farbcodes möglich: z.b. &6) # Lore nur für bestimmte Qualität möglich mit + Schlecht, ++ Mittel, +++ Gut, vorne anhängen. +# servercommands: Liste von Befehlen ausgeführt vom Server wenn der Trank getrunken wird +# playercommands: Liste von Befehlen ausgeführt vom Spieler wenn der Trank getrunken wird +# drinkmessage: Nachricht im Chat beim trinken des Trankes +# drinktitle: Nachricht als Titel auf dem Bildschirm an den Spieler beim trinken des Trankes # effects: Auflistung Effekt/Level/Dauer Besonderere Trank-Effekte beim Trinken, Dauer in sek. # Ein 'X' an den Namen anhängen, um ihn zu verbergen. Bsp: 'POISONX/2/10' (WEAKNESS, INCREASE_DAMAGE, SLOW und SPEED sind immer verborgen.) # Effekte sind ab der 1.9 immer verborgen, wegen Änderungen an den Tränken. @@ -114,7 +226,7 @@ oldMat: true recipes: # Ein vollständiges Beispiel zuerst: - 0: + bsp: name: Schlechtes Beispiel/Beispiel/Gutes Beispiel ingredients: - SUGAR_CANE/5 @@ -123,7 +235,9 @@ recipes: - WOOD,1/8 - BEDROCK/1 # - Jungle Leaves/64 # Nur mit Vault -# - Green Dye/6 # Nur mit Vault + - Brewery:Weißbier/2 +# - ExoticGarden:Grape/3 + - bsp-item/4 cookingtime: 3 distillruns: 2 distilltime: 60 @@ -135,17 +249,23 @@ recipes: lore: - Dies ist ein Beispiel Trank - ++Ganz normales Beispiel - - Man kann ihn nicht brauen - - Aber dies würde auf dem Trank stehen + - Dies würde auf dem Trank stehen - + Riecht eklig - ++ Riecht ganz ok - +++ Riecht richtig gut + servercommands: + - weather clear + playercommands: + - homes + drinkmessage: Schmeckt toll + drinktitle: Wärmt dich von innen effects: - FIRE_RESISTANCE/20 - HEAL/1 - WEAKNESS/2-3/50-60 - POISONX/1-0/20-0 - 1: + + weißbier: name: Ranziges Weißbier/Weißbier/Feines Weißbier ingredients: - WHEAT/3 @@ -156,7 +276,8 @@ recipes: color: BRIGHT_GREY difficulty: 1 alcohol: 5 - 2: + + bier: name: Ranziges Bier/Bier/Feines Bier ingredients: - WHEAT/6 @@ -169,7 +290,8 @@ recipes: lore: - +++ &8Das perlt alcohol: 6 - 3: + + dunkelbier: name: Ranziges Dunkelbier/Dunkelbier/Feines Dunkelbier ingredients: - WHEAT/6 @@ -180,7 +302,8 @@ recipes: color: BLACK difficulty: 2 alcohol: 7 - 4: + + met: name: Scheußlicher Met/Met/&6Goldener Met ingredients: - SUGAR_CANE/6 @@ -193,7 +316,8 @@ recipes: alcohol: 9 lore: - +++ Hat einen goldenen Schein - 5: + + apfelmet: name: Apfelmet/Süßer Apfelmet/&6Goldensüßer Apfelmet ingredients: - SUGAR_CANE/6 @@ -211,7 +335,8 @@ recipes: - +++ Hat eine wunderbare Apfelnote effects: - WATER_BREATHINGX/1-2/150 - 6: + + rum: name: Bitterer Rum/Würziger Rum/&6Goldener Rum ingredients: - SUGAR_CANE/14 @@ -226,7 +351,8 @@ recipes: effects: - FIRE_RESISTANCE/1/20-100 - POISONX/1-0/30-0 - 7: + + vodka: name: Abgeranzter Vodka/Vodka/Russischer Vodka ingredients: - POTATO_ITEM/10 @@ -241,7 +367,8 @@ recipes: effects: - WEAKNESS/15 - POISON/10 - 8: + + absinth: name: minderwertiger Absinth/Absinth/Starker Absinth ingredients: - LONG_GRASS/15 @@ -253,7 +380,8 @@ recipes: alcohol: 45 effects: - POISON/20-30 - 9: + + kartoffelsuppe: name: Kartoffelsuppe ingredients: - POTATO_ITEM/5 @@ -263,7 +391,8 @@ recipes: difficulty: 1 effects: - HEAL/0-1 - 10: + + kaffee: name: Fader Kaffee/Kaffee/Starker Kaffee ingredients: - INK_SACK,3/12 @@ -281,27 +410,13 @@ recipes: # Der Serveradmin kann neue Rezepte hinzufügen und bestehende ändern, um das Abschauen aus der Standardconfig zu verhindern. -# cooked: ALLE möglichen Zutaten und die nach dem Gähren daraus entstehenden Tranknamen: -# [Beispiel] MATERIAL: Name nach Gähren - -cooked: - WHEAT: Getreideferment - SUGAR_CANE: Zuckersud - APPLE: Apfelmost - POTATO_ITEM: Kartoffelmaische - LONG_GRASS: Kräuterbrühe - RED_MUSHROOM: Pilzsud - INK_SACK: Farbige Brühe - MILK_BUCKET: Milchiges Wasser - - - # -- Plugin Kompatiblität -- # Andere Plugins (wenn installiert) nach Rechten zum öffnen von Fässern checken [true] useWorldGuard: true useLWC: true useGriefPrevention: true +useGMInventories: true useCitadel: true # Änderungen an Fassinventaren mit LogBlock aufzeichen [true] diff --git a/resources/config/v12/en/config.yml b/resources/config/v12/en/config.yml index 1845a69..d16df4b 100644 --- a/resources/config/v12/en/config.yml +++ b/resources/config/v12/en/config.yml @@ -50,6 +50,12 @@ hangoverDays: 7 colorInBarrels: true colorInBrewer: true +# Always show the 1-5 stars on the item depending on the quality. If false, they will only appear when brewing [true] +alwaysShowQuality: true + +# Always show the alcohol content on the item. If false, it will only show in the brewing stand [false] +alwaysShowAlc: false + # If a Large Barrel can be opened by clicking on any of its blocks, not just Spigot or Sign. This is always true for Small Barrels. [true] openLargeBarrelEverywhere: true @@ -71,11 +77,119 @@ updateCheck: true # Autosave interval in minutes [3] autosave: 3 +# Show debug messages in log [false] +debug: false + # Config Version version: '1.8' oldMat: true + +# -- Define custom items -- +# The defined id can then be used in recipes + +# matchAny: true if it is already enough if one of the info matches +# material: Which type the item has to be +# name: Which name the item has to be (Formatting codes possible: such as &6) +# lore: What has to be in the lore of the item + +customItems: + ex-item: + # A Bedrock item called Wall and has the given line in its lore + material: BEDROCK + name: 'Wall' + lore: + - '&7Very well protected' + + ex-item2: + # Using matchAny only one of the following has to match. + # In this case on of the door types, or an item called Beechwood Door, or an item with 'A door' in its lore + matchAny: true + material: + - WOODEN_DOOR + - IRON_DOOR + name: + - 'Beechwood Door' + lore: + - 'A door' + + rasp: + name: '&cRaspberry' + + +# -- Ingredients in the Cauldron -- +# Which Ingredients are accepted by the Cauldron and the base potion resulting from them + +# name: Name of the base potion coming out of the Cauldron (Formatting codes possible: such as &6) +# ingredients: List of 'material/amount' +# With an item in your hand, use /brew ItemName to get its material for use in a recipe +# (Item-ids instead of material are not supported by bukkit anymore and will not work) +# A list of materials can be found here: https://hub.spigotmc.org/javadocs/spigot/org/bukkit/Material.html +# color: Color of the potion from a cauldron. +# Usable Colors: DARK_RED, RED, BRIGHT_RED, ORANGE, PINK, BLUE, CYAN, WATER, GREEN, BLACK, GREY, BRIGHT_GREY +# Or RGB colors (hex: for example '99FF33') (with '') (search for "HTML color" on the internet) +# lore: List of additional text on the base potion. (Formatting codes possible: such as &6) + +cauldron: + ex: + name: Example + ingredients: + - BEDROCK/2 + - DIAMOND + color: BLACK + lore: + - An example for a Base Potion + - This is how it comes out of a Cauldron + + # -- One Ingredient: -- + wheat: + name: Fermented wheat + ingredients: WHEAT + + sugarcane: + name: Sugar brew + ingredients: SUGAR_CANE + color: 'f1ffad' # yellowish green + + apple: + name: Apple cider + ingredients: APPLE + + potato: + name: Potatomash + ingredients: POTATO_ITEM + + grass: + name: Boiled herbs + ingredients: LONG_GRASS + color: '99ff66' # bright green + + rmushroom: + name: Mushroom brew + ingredients: RED_MUSHROOM + color: 'ff5c33' # amber red + + cocoa: + name: Chocolately brew + ingredients: INK_SACK + color: '804600' # mocca + + milk: + name: Milky water + ingredients: MILK_BUCKET + color: BRIGHT_GREY + + # -- Multiple Ingredients: -- + apfelmet_base: + name: Apple-Sugar brew + ingredients: + - SUGAR_CANE/3 + - APPLE + color: 'e1ff4d' # greenish yellow + + + # -- Recipes for Potions -- # name: Different names for bad/normal/good (Formatting codes possible: such as &6) @@ -97,6 +211,12 @@ oldMat: true # Or RGB colors (hex: for example '99FF33') (with '') (search for "HTML color" on the internet) # difficulty: 1-10 accuracy needed to get good quality (1 = unaccurate/easy, 10 = very precise/hard) # alcohol: Absolute amount of alcohol 0-100 in a perfect potion (will be added directly to the player, where 100 means fainting) +# lore: List of additional text on the finished brew. (Formatting codes possible: such as &6) +# Specific lore for quality possible, using + bad, ++ normal, +++ good, added to the front of the line. +# servercommands: List of Commands executed by the Server when drinking the brew +# playercommands: List of Commands executed by the Player when drinking the brew +# drinkmessage: Chat-message to the Player when drinking the Brew +# drinktitle: Title on Screen to the Player when drinking the Brew # effects: List of effect/level/duration Special potion-effect when drinking, duration in sek. # Suffix name with 'X' to hide effect from label. Sample: 'POISONX/2/10' (WEAKNESS, INCREASE_DAMAGE, SLOW and SPEED are always hidden.) # Effects are always hidden in 1.9 and newer, because of changes in the potion mechanics. @@ -107,13 +227,14 @@ oldMat: true recipes: # Example Recipe with every possible entry first: - 0: + ex: name: Bad Example/Example/Good Example ingredients: - - SUGAR_CANE/5 - DIAMOND/1 - INK_SACK,3/20 - WOOD,1/8 + - Brewery:Wheatbeer/2 +# - ExoticGarden:Grape/3 - BEDROCK/1 # - Jungle Leaves/64 # Only with Vault # - Green Dye/6 # Only with Vault @@ -125,12 +246,26 @@ recipes: color: DARK_RED difficulty: 3 alcohol: 23 + lore: + - This is an examble brew + - ++Just a normal Example + - This text would be on the brew + - + Smells disgusting + - ++ Smells alright + - +++ Smells really good + servercommands: + - weather clear + playercommands: + - homes + drinkmessage: Tastes good + drinktitle: Warms you from inside effects: - FIRE_RESISTANCE/20 - HEAL/1 - WEAKNESS/2-3/50-60 - POISONX/1-0/20-0 - 1: + + wheatbeer: name: Skunky Wheatbeer/Wheatbeer/Fine Wheatbeer ingredients: - WHEAT/3 @@ -141,7 +276,8 @@ recipes: color: BRIGHT_GREY difficulty: 1 alcohol: 5 - 2: + + beer: name: Skunky Beer/Beer/Fine Beer ingredients: - WHEAT/6 @@ -151,8 +287,11 @@ recipes: age: 3 color: ORANGE difficulty: 1 + lore: + - +++ &8Crisp taste alcohol: 6 - 3: + + darkbeer: name: Skunky Darkbeer/Darkbeer/Fine Darkbeer ingredients: - WHEAT/6 @@ -162,8 +301,11 @@ recipes: age: 8 color: BLACK difficulty: 2 + lore: + - +++ &8Roasted taste alcohol: 7 - 4: + + mead: name: Awkward Mead/Mead/&6Golden Mead ingredients: - SUGAR_CANE/6 @@ -173,8 +315,11 @@ recipes: age: 4 color: ORANGE difficulty: 2 + lore: + - +++ Has a golden shine alcohol: 9 - 5: + + ap_mead: name: Apple Mead/Sweet Apple Mead/&6Sweet Golden Apple Mead ingredients: - SUGAR_CANE/6 @@ -186,9 +331,14 @@ recipes: color: ORANGE difficulty: 4 alcohol: 12 + lore: + - +Is there any Apple in this? + - ++Refreshing taste of Apple + - +++Sweetest hint of Apple effects: - WATER_BREATHINGX/1-2/150 - 6: + + rum: name: Bitter Rum/Spicy Rum/&6Golden Rum ingredients: - SUGAR_CANE/14 @@ -203,7 +353,8 @@ recipes: effects: - FIRE_RESISTANCE/1/20-100 - POISONX/1-0/30-0 - 7: + + vodka: name: Lousy Vodka/Vodka/Russian Vodka ingredients: - POTATO_ITEM/10 @@ -213,10 +364,12 @@ recipes: color: BRIGHT_GREY difficulty: 4 alcohol: 20 + lore: +&8Almost undrinkable effects: - WEAKNESS/15 - POISON/10 - 8: + + absinthe: name: Poor Absinthe/Absinthe/Strong Absinthe ingredients: - LONG_GRASS/15 @@ -228,7 +381,8 @@ recipes: alcohol: 45 effects: - POISON/20-30 - 9: + + potato_soup: name: Potato soup ingredients: - POTATO_ITEM/5 @@ -238,7 +392,8 @@ recipes: difficulty: 1 effects: - HEAL/0-1 - 10: + + coffee: name: Stale Coffee/Coffee/Strong Coffee ingredients: - INK_SACK,3/12 @@ -246,6 +401,7 @@ recipes: cookingtime: 2 color: BLACK difficulty: 3 + lore: + &8Probably a week old effects: - REGENERATION/1/2-5 - SPEED/1/30-140 @@ -255,28 +411,13 @@ recipes: # It is up to the Serveradmin to change and add Recipes, so players cannot cheat from the default config. - -# cooked: EVERY possible ingredient and the names for the originating potions after fermenting: -# [Example] MATERIAL: Name after cooking - -cooked: - WHEAT: Fermented wheat - SUGAR_CANE: Sugar brew - APPLE: Apple cider - POTATO_ITEM: Potatomash - LONG_GRASS: Boiled herbs - RED_MUSHROOM: Mushroom brew - INK_SACK: Colored brew - MILK_BUCKET: Milky water - - - # -- Plugin Compatibility -- # Enable checking of other Plugins (if installed) for Barrel Permissions [true] useWorldGuard: true useLWC: true useGriefPrevention: true +useGMInventories: true useCitadel: true # Enable the Logging of Barrel Inventories to LogBlock [true] @@ -285,8 +426,7 @@ useLogBlock: true # -- Chat Distortion Settings -- -# If written Chat is distorted when the Player is Drunk, -# so that it looks like drunk writing +# If written Chat is distorted when the Player is Drunk, so that it looks like drunk writing # How much the chat is distorted depends on how drunk the Player is # Below are settings for what and how changes in chat occur enableChatDistortion: true diff --git a/resources/config/v12/fr/config.yml b/resources/config/v12/fr/config.yml index 82cd49e..5015706 100644 --- a/resources/config/v12/fr/config.yml +++ b/resources/config/v12/fr/config.yml @@ -1,6 +1,7 @@ # config for Brewery.jar +# Quelques traductions en français ont été faites avec DeepL # -- Paramètres -- # Les paramètres par défaut sont entre [] @@ -50,17 +51,23 @@ hangoverDays: 7 colorInBarrels: true colorInBrewer: true +# Toujours montrer les 1-5 étoiles sur les objets en fonction de leur qualité. S'ils sont faux, ils n'apparaîtront que lors de l'infusion. [true] +alwaysShowQuality: true + +# Toujours indiquer la teneur en alcool sur les objets. S'il est false, il n'apparaîtra que dans le stand de brassage. [false] +alwaysShowAlc: false + # Si le grand tonneau peut être ouvert en cliquant sur n'importe quel bloc, non seulement le robinet ou le panneau. Toujours "true" pour les petits tonneaux. [true] openLargeBarrelEverywhere: true -# How many Brewery drinks can be put into the Minecraft barrels [6] +# Combien de boissons de brasserie peuvent être mises dans les barils Minecraft [6] maxBrewsInMCBarrels: 6 -# The used Ingredients and other brewing-data is saved to all Brewery Items. To prevent -# hacked clients from reading what exactly was used to brew an item, the data can be encoded/scrambled. -# This is a fast process to stop players from hacking out recipes, once they get hold of a brew. -# Only drawback: brew items can only be used on another server with the same encodeKey. -# So enable this if you want to make recipe cheating harder, but don't share any brews by world download, schematics, or other means. [false] +# Les ingrédients et autres données de brassage utilisés sont sauvegardés dans tous les articles de brasserie. [false] +# Pour empêcher les clients piratés de lire exactement ce qui a été utilisé pour infuser un élément, les données peuvent être encodées/brouillées. +# Il s'agit d'un processus rapide pour empêcher les joueurs de pirater des recettes, une fois qu'ils mettent la main sur une bière. +# Seul inconvénient: Les boissons brassicoles ne peuvent être utilisés que sur un autre serveur avec la même clé de chiffrement. +# Activez cette option si vous voulez rendre la tricherie des recettes plus difficile, mais ne partagez pas les infusions par téléchargement mondial, schémas ou autres moyens. enableEncode: false encodeKey: 0 @@ -71,33 +78,150 @@ updateCheck: true # Intervale de la sauvegarde automatique en minutes [3] autosave: 3 +# Show debug messages in log [false] +debug: false + # Version de configuration version: '1.8' oldMat: true + +# -- Définir des objets personnalisés -- +# L'id défini peut ensuite être utilisé dans les recettes + +# matchAny: si c'est déjà assez si l'une des infos correspond +# material: le type d'article à utiliser +# name: Quel nom l'article doit porter (codes de formatage possibles : tels que &6) +# lore: Ce qui doit être dans la lore de l'objet + +customItems: + ex-item: + # Un objet Barrière appelé "Wall" et qui a la ligne donnée dans sa lore + material: BEDROCK + name: 'Wall' + lore: + - '&7Very well protected' + + ex-item2: + # En utilisant matchAny, un seul des éléments suivants doit correspondre. + # Dans ce cas, l'un des types de porte, ou un article appelé "Beechwood Door", ou un objet avec "A door" dans sa lore. + matchAny: true + material: + - WOODEN_DOOR + - IRON_DOOR + name: + - 'Beechwood Door' + lore: + - 'A door' + + rasp: + name: '&cRaspberry' + + +# -- Ingrédients dans le chaudron -- +# Quels sont les ingrédients acceptés par le chaudron et la potion de base qui en résulte + +# name: Nom de la potion de base qui sort du chaudron (codes de formatage possibles : tels que &6) +# ingredients: Liste des 'matériaux/montant' +# Avec un objet en main, utilisez /brew ItemName pour obtenir son matériau pour une recette de cuisine +# (Les id d'objets à la place des matériaux sont obsolètes pour bukkit) +# Une liste des matériaux peuvent-être trouvés ici: https://hub.spigotmc.org/javadocs/spigot/org/bukkit/Material.html +# color : Couleur de la potion provenant d'un chaudron. +# Couleurs disponibles : DARK_RED, RED, BRIGHT_RED, ORANGE, PINK, BLUE, CYAN, WATER, GREEN, BLACK, GREY, BRIGHT_GREY +# (Dans l'ordre : Rouge foncé, Rouge, Rouge clair, Orange, Rose, Bleu, Cyan, Eau, Vert, Noir, Gris, Gris clair) +# Ou couleurs RGB (hex: par exemple '99FF33') (avec '') (recherche de "HTML color" sur internet) +# lore: Liste de texte supplémentaire sur la potion de base. (Formatting codes possible: such as &6) + +cauldron: + ex: + name: Exemple + ingredients: + - BEDROCK/2 + - DIAMOND + color: BLACK + lore: + - Un exemple pour une potion de base + - Voici comment il sort d'un chaudron + + # -- Un ingrédient: -- + wheat: + name: Blé fermenté + ingredients: WHEAT + + sugarcane: + name: Sucre fermenté + ingredients: SUGAR_CANE + color: 'f1ffad' # yellowish green + + apple: + name: Cidre de pommes + ingredients: APPLE + + potato: + name: Purée de Pommes de Terre + ingredients: POTATO_ITEM + + grass: + name: Herbes bouillies + ingredients: LONG_GRASS + color: '99ff66' # bright green + + rmushroom: + name: Champignons fermentés + ingredients: RED_MUSHROOM + color: 'ff5c33' # amber red + + cocoa: + name: Infusion au chocolat + ingredients: INK_SACK + color: '804600' # mocca + + milk: + name: Eau laiteuse + ingredients: MILK_BUCKET + color: BRIGHT_GREY + + # -- Ingrédients multiples: -- + apfelmet_base: + name: Brassée pomme-sucre + ingredients: + - SUGAR_CANE/3 + - APPLE + color: 'e1ff4d' # greenish yellow + + # -- Recette pour les boissons -- # name: Différents noms pour la mauvaise/moyen/bonne qualité (Les codes de mise en forme sont pris en charge: comme par exemple &6 pour la couleur Or.) -# ingredients: Liste des 'matériaux,data/montant' -# With an item in your hand, use /brew ItemName to get its material for use in a recipe -# (Les id d'objets à la place des matériaux sont obsolètes pour bukkit et pourraient ne pas fonctionner dans le futur!) -# Ex: 'SUGAR_CANE' +# ingredients: Liste des 'matériaux/montant' +# Avec un objet en main, utilisez /brew ItemName pour obtenir son matériau pour une recette de cuisine +# (Les id d'objets à la place des matériaux sont obsolètes pour bukkit) +# Ex: 'Sugar_Cane' # Une liste des matériaux peuvent-être trouvés ici: https://hub.spigotmc.org/javadocs/spigot/org/bukkit/Material.html # Vous pouvez spécifier une data (Ex: 5,3 -> Planche de bois de jungle), si vous ne le faites pas la data ne sera pas prise en compte (Ex : 5 -> Bois en général) # If Vault is installed normal names can be used instead of material or id, so using Vault is highly recommended. # Vault will recognize things like "Jungle Leaves" instead of "5,3" +# Plugin items avec 'plugin:id' (Actuellement supporté ExoticGarden, Slimefun, MMOItems, Brewery) +# Ou un élément personnalisé défini ci-dessus # cookingtime: Temps en minutes réelles durant lesquelles les ingrédients devront bouillir # distillruns: Combien de fois le breuvage devra être distillé pour un alcool de qualité (0=Ne pas distiller) -# distilltime: How long (in seconds) one distill-run takes (0=Default time of 40 sec) MC Default would be 20 sec +# distilltime: Combien de temps (en secondes) dure une distillation (0=Temps par défaut de 40 secondes) MC Par défaut serait de 20 secondes # wood: Type de bois du baril 0=aucun 1=Bouleau 2=Chêne 3=Jungle 4=Pin 5=Acacia 6=Chêne Noir -# The Minecraft barrel is made of oak +# Le tonneau Minecraft est en chêne. # age: Temps en jours de Minecraft, la potion devra être âgée dans un baril. 0=Pas besoin d'âge # color: Couleur de la potion après distillation/avoir laissé vieillir. -# Couleurs disponibles: DARK_RED, RED, BRIGHT_RED, ORANGE, PINK, BLUE, CYAN, WATER, GREEN, BLACK, GREY, BRIGHT_GREY (Dans l'ordre : Rouge foncé, Rouge, Rouge clair, Orange, Rose, Bleu, Cyan, Eau, Vert, Noir, Gris, Gris clair) -# Or RGB colors (hex: for example '99FF33') (with '') (search for "HTML color" on the internet) +# Couleurs disponibles: DARK_RED, RED, BRIGHT_RED, ORANGE, PINK, BLUE, CYAN, WATER, GREEN, BLACK, GREY, BRIGHT_GREY +# (Dans l'ordre : Rouge foncé, Rouge, Rouge clair, Orange, Rose, Bleu, Cyan, Eau, Vert, Noir, Gris, Gris clair) +# Ou couleurs RGB (hex: par exemple '99FF33') (avec '') (recherche de "HTML color" sur internet) # difficulty: 1-10 précision nécessaire pour obtenir une bonne qualité (1 = imprécis/facile, 10 = très précis/difficile) # alcohol: Le montant d'alcool absolu dans une boisson parfaite (cela sera ajouté directement au joueur, où 100% entraînera l'évanouissement), un degré d'alcooléisme en fait +# lore: Liste des textes supplémentaires sur le breuvage fini. (Codes de formatage possibles : tels que &6) +# Texte spécifique de qualité possible, en utilisant + mauvais, ++ normal, +++ bon, ajouté à l'avant de la ligne. +# servercommands: Liste des commandes exécutées par le serveur lors de la consommation de la potion +# playercommands: Liste des commandes exécutées par le joueur lors de la consommation de la potion +# drinkmessage: Chat-message au joueur lorsqu'il boit la potion +# drinktitle: Titre à l'écran du joueur lorsqu'il boit la potion # effects: Liste des effets/durée en secondes lors de la consommation. # Rajouter le suffixe 'X' pour le cacher du label. Exemple: POISONX/10 # (WEAKNESS, INCREASE_DAMAGE, SLOW et SPEED sont toujours cachés.) @@ -115,10 +239,11 @@ recipes: 0: name: Mauvais Exemple/Exemple/Bonne Exemple ingredients: - - SUGAR_CANE/5 - - 264/1 + - DIAMOND/1 - INK_SACK,3/20 - - 5,1/8 + - WOOD,1/8 + - Brewery:Wheatbeer/2 +# - ExoticGarden:Grape/3 - BEDROCK/1 # - Jungle Leaves/64 # Only with Vault # - Green Dye/6 # Only with Vault @@ -130,11 +255,25 @@ recipes: color: DARK_RED difficulty: 3 alcohol: 23 + lore: + - C'est un breuvage d'exemple + - ++Juste un exemple normal + - Ce texte serait sur le breuvage + - + Ça sent dégueulasse. + - ++ Ça sent bon + - +++ Ça sent vraiment bon + servercommands: + - weather clear + playercommands: + - homes + drinkmessage: C'est bon au goût + drinktitle: vous réchauffe à l'intérieur effects: - FIRE_RESISTANCE/20 - HEAL/1 - WEAKNESS/2-3/50-60 - POISONX/1-0/20-0 + 1: name: Bière Blanche Fade/Bière Blanche/Bonne Bière Blanche ingredients: @@ -146,6 +285,7 @@ recipes: color: BRIGHT_GREY difficulty: 1 alcohol: 5 + 2: name: Bière Fade/Bière/Bonne Bière ingredients: @@ -157,6 +297,7 @@ recipes: color: ORANGE difficulty: 1 alcohol: 6 + 3: name: Bière Brune Fade/Bière Brune/Bonne Bière Brune ingredients: @@ -168,6 +309,7 @@ recipes: color: BLACK difficulty: 2 alcohol: 7 + 4: name: Hydromel Bizarre/Hydromel/&6Hydromel Doré ingredients: @@ -179,6 +321,7 @@ recipes: color: ORANGE difficulty: 2 alcohol: 9 + 5: name: Hydromel de Pommes/Doux Hydromel de Pommes/&6Doux Hydromel de Pommes Dorées ingredients: @@ -193,6 +336,7 @@ recipes: alcohol: 12 effects: - WATER_BREATHINGX/1-2/150 + 6: name: Rhum Amer/Rhum Epicé/&6Rhum Doré ingredients: @@ -208,6 +352,7 @@ recipes: effects: - FIRE_RESISTANCE/1/20-100 - POISONX/1-0/30-0 + 7: name: Vodka Sale/Vodka/Vodka Russe ingredients: @@ -221,6 +366,7 @@ recipes: effects: - WEAKNESS/15 - POISON/10 + 8: name: Absinthe pauvre/Absinthe/Absinthe forte ingredients: @@ -233,6 +379,7 @@ recipes: alcohol: 45 effects: - POISON/20-30 + 9: name: Potato soup ingredients: @@ -243,6 +390,7 @@ recipes: difficulty: 1 effects: - HEAL/0-1 + 10: name: Café fétide/Café/Café fort ingredients: @@ -260,28 +408,13 @@ recipes: # Ce sera aux Admins des serveurs de changer et d'ajouter les recettes, ainsi les joueurs ne pourront pas tricher avec les configuration de base. - -# cooked: CHAQUE ingrédient possible avec le nom donné après la fermentation (la cuisson): -# [Exemple] MATERIEL: Nom après la cuisson - -cooked: - WHEAT: Blé fermenté - SUGAR_CANE: Sucre fermenté - APPLE: Cidre de pommes - POTATO_ITEM: Purée de Pommes de Terre - LONG_GRASS: Herbes bouillies - RED_MUSHROOM: Champignons fermentés - INK_SACK: Fermentation colorée - MILK_BUCKET: Eau laiteuse - - - # -- Compatibilité entre Plugins -- # Activer la vérification des autres plugins (si installés) pour les permissions des tonneaux. [true] useWorldGuard: true useLWC: true useGriefPrevention: true +useGMInventories: true useCitadel: true # Activer l'historique du contenu des tonneaux avec LogBlock [true] @@ -290,10 +423,9 @@ useLogBlock: true # -- Paramètres de la distorsion du Chat -- -# If written Chat is distorted when the Player is Drunk, -# so that it looks like drunk writing -# How much the chat is distorted depends on how drunk the Player is -# Below are settings for what and how changes in chat occur +# Si le Chat écrit est déformé quand le joueur est ivre, de sorte qu'il ressemble à un chat bourré en train d'écrire +# Le degré de distorsion du chat dépend de l'état d'ébriété du joueur +# Ci-dessous sont les paramètres pour ce qui et comment les changements dans le chat se produisent enableChatDistortion: true # Ecrire dans les "logs" du serveur ce que le joueur devrait dire, à la place de la distorsion. [false] diff --git a/resources/config/v12/it/config.yml b/resources/config/v12/it/config.yml index 335cf03..bc84f0a 100644 --- a/resources/config/v12/it/config.yml +++ b/resources/config/v12/it/config.yml @@ -50,6 +50,12 @@ hangoverDays: 7 colorInBarrels: true colorInBrewer: true +# Always show the 1-5 stars on the item depending on the quality. If false, they will only appear when brewing [true] +alwaysShowQuality: true + +# Always show the alcohol content on the item. If false, it will only show in the brewing stand [false] +alwaysShowAlc: false + # Se un barile grande può essere aperto cliccandoci sopra, non solo sul cartello e sulla staccionata. Questo è sempre true per i barili piccoli. [true] openLargeBarrelEverywhere: true @@ -71,11 +77,117 @@ updateCheck: true # Intervallo di autosalvataggio in minuti [3] autosave: 3 +# Show debug messages in log [false] +debug: false + # Versione del config version: '1.8' oldMat: true + +# -- Define custom items -- +# The defined id can then be used in recipes + +# matchAny: true if it is already enough if one of the info matches +# material: Which type the item has to be +# name: Which name the item has to be (Formatting codes possible: such as &6) +# lore: What has to be in the lore of the item + +customItems: + ex-item: + # A Bedrock item called Wall and has the given line in its lore + material: BEDROCK + name: 'Wall' + lore: + - '&7Very well protected' + + ex-item2: + # Using matchAny only one of the following has to match. + # In this case on of the door types, or an item called Beechwood Door, or an item with 'A door' in its lore + matchAny: true + material: + - WOODEN_DOOR + - IRON_DOOR + name: + - 'Beechwood Door' + lore: + - 'A door' + + rasp: + name: '&cRaspberry' + + +# -- Ingredients in the Cauldron -- +# Which Ingredients are accepted by the Cauldron and the base potion resulting from them + +# name: Name of the base potion coming out of the Cauldron (Formatting codes possible: such as &6) +# ingredients: List of 'material/amount' +# With an item in your hand, use /brew ItemName to get its material for use in a recipe +# (Item-ids instead of material are not supported by bukkit anymore and will not work) +# A list of materials can be found here: https://hub.spigotmc.org/javadocs/spigot/org/bukkit/Material.html +# color: Color of the potion from a cauldron. +# Usable Colors: DARK_RED, RED, BRIGHT_RED, ORANGE, PINK, BLUE, CYAN, WATER, GREEN, BLACK, GREY, BRIGHT_GREY +# Or RGB colors (hex: for example '99FF33') (with '') (search for "HTML color" on the internet) +# lore: List of additional text on the base potion. (Formatting codes possible: such as &6) + +cauldron: + ex: + name: Example + ingredients: + - BEDROCK/2 + - DIAMOND + color: BLACK + lore: + - An example for a Base Potion + - This is how it comes out of a Cauldron + + # -- One Ingredient: -- + wheat: + name: Fermented wheat + ingredients: WHEAT + + sugarcane: + name: Sugar brew + ingredients: SUGAR_CANE + color: 'f1ffad' # yellowish green + + apple: + name: Apple cider + ingredients: APPLE + + potato: + name: Potatomash + ingredients: POTATO_ITEM + + grass: + name: Boiled herbs + ingredients: LONG_GRASS + color: '99ff66' # bright green + + rmushroom: + name: Mushroom brew + ingredients: RED_MUSHROOM + color: 'ff5c33' # amber red + + cocoa: + name: Chocolately brew + ingredients: INK_SACK + color: '804600' # mocca + + milk: + name: Milky water + ingredients: MILK_BUCKET + color: BRIGHT_GREY + + # -- Multiple Ingredients: -- + apfelmet_base: + name: Apple-Sugar brew + ingredients: + - SUGAR_CANE/3 + - APPLE + color: 'e1ff4d' # greenish yellow + # -- Ricette per pozioni -- # name: Tre nomi diversi per diverse qualità (cattivo/normale/buono). I codici come &6 possono essere usati. @@ -86,6 +198,8 @@ oldMat: true # Puoi specificare dei dati dell'oggetto, ma se omesso sarà semplicemente ignorato. # Se Vault è installato i nomi normali possono essere usati invece del materiale o dell'id quindi l'uso di Vault è fortemente consigliato. # Vault riconoscerà cose come "Jungle Leaves" invece di "LEAVES,3". +# Plugin items with 'plugin:id' (Currently supporting ExoticGarden, Slimefun, MMOItems, Brewery) +# Or a custom item defined above # cookingtime: Tempo in minuti richiesto dagli ingredienti per bollire # distillruns: Quanto spesso deve essere distillato per ottenere la versione perfetta con il volume alcolico impostato (0=non serve distillare). # distilltime: How long (in seconds) one distill-run takes (0=Default time of 40 sec) MC Default would be 20 sec @@ -97,6 +211,12 @@ oldMat: true # Or RGB colors (hex: for example '99FF33') (with '') (search for "HTML color" on the internet) # difficoltà: Precisione richiesta per avere la migliore qualità da 1 a 10(1 = spreciso/più facile, 10 = molto preciso/più difficile) # alcohol: Volume alcolico da 0 a 100 nella versione perfetta (sarà aggiunta direttamente al giocatore, dove 100 è la quantità massima di alcohol assorbibile. +# lore: List of additional text on the finished brew. (Formatting codes possible: such as &6) +# Specific lore for quality possible, using + bad, ++ normal, +++ good, added to the front of the line. +# servercommands: List of Commands executed by the Server when drinking the brew +# playercommands: List of Commands executed by the Player when drinking the brew +# drinkmessage: Chat-message to the Player when drinking the Brew +# drinktitle: Title on Screen to the Player when drinking the Brew # effects: Eventuali effetti come quelli delle pozioni nel formato di effetto/livello/durata. # Aggiungere il suffisso 'X' per nascondere l'effetto dalla descrizione. Esempio: 'POISONX/2/10' (gli effetti WEAKNESS, INCREASE_DAMAGE, SLOW and SPEED sono sempre nascosti). # Gli effetti sono sempre nascosti dalla 1.9 in poi, per via dei cambiamenti nelle meccaniche delle pozioni. @@ -110,10 +230,11 @@ recipes: 0: name: Cattivo esempio/Esempio/Buon esempio ingredients: - - SUGAR_CANE/5 - - 264/1 + - DIAMOND/1 - INK_SACK,3/20 - - 5,1/8 + - WOOD,1/8 + - Brewery:Wheatbeer/2 +# - ExoticGarden:Grape/3 - BEDROCK/1 # - Jungle Leaves/64 # Solo con Vault # - Green Dye/6 # Solo con Vault @@ -125,11 +246,25 @@ recipes: color: DARK_RED difficulty: 3 alcohol: 23 + lore: + - This is an examble brew + - ++Just a normal Example + - This text would be on the brew + - + Smells disgusting + - ++ Smells alright + - +++ Smells really good + servercommands: + - weather clear + playercommands: + - homes + drinkmessage: Tastes good + drinktitle: Warms you from inside effects: - FIRE_RESISTANCE/20 - HEAL/1 - WEAKNESS/2-3/50-60 - POISONX/1-0/20-0 + 1: name: Birra di frumento puzzolente/Birra di frumento/Birra di frumento pregiata ingredients: @@ -141,6 +276,7 @@ recipes: color: BRIGHT_GREY difficulty: 1 alcohol: 5 + 2: name: Birra puzzolente/Birra/Birra pregiata ingredients: @@ -152,6 +288,7 @@ recipes: color: ORANGE difficulty: 1 alcohol: 6 + 3: name: Birra scura puzzolente/Birra scura/Birra scura pregiata ingredients: @@ -163,6 +300,7 @@ recipes: color: BLACK difficulty: 2 alcohol: 7 + 4: name: Idromele scarso/Idromele/&6Idromele dorato ingredients: @@ -174,6 +312,7 @@ recipes: color: ORANGE difficulty: 2 alcohol: 9 + 5: name: Idromele di mele/Idromele di mele dolci/&6Idromele di mele dolci dorato ingredients: @@ -188,6 +327,7 @@ recipes: alcohol: 12 effects: - WATER_BREATHINGX/1-2/150 + 6: name: Rum amaro/Rum speziato/&6Rum dorato ingredients: @@ -203,6 +343,7 @@ recipes: effects: - FIRE_RESISTANCE/1/20-100 - POISONX/1-0/30-0 + 7: name: Vodka schifosa/Vodka/Vodka russa ingredients: @@ -216,6 +357,7 @@ recipes: effects: - WEAKNESS/15 - POISON/10 + 8: name: Assenzio scarso/Assenzio/Assenzio forte ingredients: @@ -228,6 +370,7 @@ recipes: alcohol: 45 effects: - POISON/20-30 + 9: name: Zuppa di patate ingredients: @@ -238,6 +381,7 @@ recipes: difficulty: 1 effects: - HEAL/0-1 + 10: name: Caffè stantio/Caffè/Caffè forte ingredients: @@ -256,27 +400,13 @@ recipes: -# cooked: OGNI possibile ingrediente e i nomi per la pozione originatasi dopo la fermentazione. -# (Esempio) MATERIALE: Nome dopo la cottura - -cooked: - WHEAT: Frumento fermentato - SUGAR_CANE: Miscela zuccherata - APPLE: Sidro di mele - POTATO_ITEM: Purè di patate - LONG_GRASS: Erbe bollite - RED_MUSHROOM: Miscela ai funghi - INK_SACK: Miscela colorata - MILK_BUCKET: Acqua lattea - - - # -- Compatibilità con altri plugin -- # Abilita il controllo della presenza di altri plugin per i permessi relativi ai barili[true] useWorldGuard: true useLWC: true useGriefPrevention: true +useGMInventories: true useCitadel: true # Abilita il logging degli inventari dei barili [true] diff --git a/resources/config/v13/de/config.yml b/resources/config/v13/de/config.yml index cbd5763..38a6d9e 100644 --- a/resources/config/v13/de/config.yml +++ b/resources/config/v13/de/config.yml @@ -83,6 +83,7 @@ debug: false version: '1.8' + # -- Eigene Items Definieren -- # Die festgelegte id kann dann in einem Rezept verwendet werden diff --git a/resources/config/v13/en/config.yml b/resources/config/v13/en/config.yml index 5717cce..2cef828 100644 --- a/resources/config/v13/en/config.yml +++ b/resources/config/v13/en/config.yml @@ -77,13 +77,14 @@ updateCheck: true # Autosave interval in minutes [3] autosave: 3 -# Debug Nachrichten im Log anzeigen [false] +# Show debug messages in log [false] debug: false # Config Version version: '1.8' + # -- Define custom items -- # The defined id can then be used in recipes @@ -210,7 +211,7 @@ cauldron: # difficulty: 1-10 accuracy needed to get good quality (1 = unaccurate/easy, 10 = very precise/hard) # alcohol: Absolute amount of alcohol 0-100 in a perfect potion (will be added directly to the player, where 100 means fainting) # lore: List of additional text on the finished brew. (Formatting codes possible: such as &6) -# Specific lore for quality possible, using + bad, ++ normal, ++ good, added to the front of the line. +# Specific lore for quality possible, using + bad, ++ normal, +++ good, added to the front of the line. # servercommands: List of Commands executed by the Server when drinking the brew # playercommands: List of Commands executed by the Player when drinking the brew # drinkmessage: Chat-message to the Player when drinking the Brew @@ -419,8 +420,7 @@ useLogBlock: true # -- Chat Distortion Settings -- -# If written Chat is distorted when the Player is Drunk, -# so that it looks like drunk writing +# If written Chat is distorted when the Player is Drunk, so that it looks like drunk writing # How much the chat is distorted depends on how drunk the Player is # Below are settings for what and how changes in chat occur enableChatDistortion: true diff --git a/resources/config/v13/fr/config.yml b/resources/config/v13/fr/config.yml index 98f15cf..6dac476 100644 --- a/resources/config/v13/fr/config.yml +++ b/resources/config/v13/fr/config.yml @@ -1,6 +1,7 @@ # config for Brewery.jar +# Quelques traductions en français ont été faites avec DeepL # -- Paramètres -- # Les paramètres par défaut sont entre [] @@ -40,8 +41,8 @@ pukeDespawntime: 60 # Consommables Objet/Force. Réduit le montant d'alcool par lors de la consommation. (list) drainItems: -- Bread/4 -- Milk_Bucket/2 + - Bread/4 + - Milk_Bucket/2 # Temps (en jours) pour que les données d'ivresse restent sauvergardées lorsque le joueur est déconnecté, pour appliquer les effets. [7] hangoverDays: 7 @@ -50,17 +51,23 @@ hangoverDays: 7 colorInBarrels: true colorInBrewer: true +# Toujours montrer les 1-5 étoiles sur les objets en fonction de leur qualité. S'ils sont faux, ils n'apparaîtront que lors de l'infusion. [true] +alwaysShowQuality: true + +# Toujours indiquer la teneur en alcool sur les objets. S'il est false, il n'apparaîtra que dans le stand de brassage. [false] +alwaysShowAlc: false + # Si le grand tonneau peut être ouvert en cliquant sur n'importe quel bloc, non seulement le robinet ou le panneau. Toujours "true" pour les petits tonneaux. [true] openLargeBarrelEverywhere: true -# How many Brewery drinks can be put into the Minecraft barrels [6] +# Combien de boissons de brasserie peuvent être mises dans les barils Minecraft [6] maxBrewsInMCBarrels: 6 -# The used Ingredients and other brewing-data is saved to all Brewery Items. To prevent -# hacked clients from reading what exactly was used to brew an item, the data can be encoded/scrambled. -# This is a fast process to stop players from hacking out recipes, once they get hold of a brew. -# Only drawback: brew items can only be used on another server with the same encodeKey. -# So enable this if you want to make recipe cheating harder, but don't share any brews by world download, schematics, or other means. [false] +# Les ingrédients et autres données de brassage utilisés sont sauvegardés dans tous les articles de brasserie. [false] +# Pour empêcher les clients piratés de lire exactement ce qui a été utilisé pour infuser un élément, les données peuvent être encodées/brouillées. +# Il s'agit d'un processus rapide pour empêcher les joueurs de pirater des recettes, une fois qu'ils mettent la main sur une bière. +# Seul inconvénient: Les boissons brassicoles ne peuvent être utilisés que sur un autre serveur avec la même clé de chiffrement. +# Activez cette option si vous voulez rendre la tricherie des recettes plus difficile, mais ne partagez pas les infusions par téléchargement mondial, schémas ou autres moyens. enableEncode: false encodeKey: 0 @@ -71,29 +78,147 @@ updateCheck: true # Intervale de la sauvegarde automatique en minutes [3] autosave: 3 +# Show debug messages in log [false] +debug: false + # Version de configuration version: '1.8' + +# -- Définir des objets personnalisés -- +# L'id défini peut ensuite être utilisé dans les recettes + +# matchAny: si c'est déjà assez si l'une des infos correspond +# material: le type d'article à utiliser +# name: Quel nom l'article doit porter (codes de formatage possibles : tels que &6) +# lore: Ce qui doit être dans la lore de l'objet + +customItems: + ex-item: + # Un objet Barrière appelé "Wall" et qui a la ligne donnée dans sa lore + material: Barrier + name: 'Wall' + lore: + - '&7Very well protected' + + ex-item2: + # En utilisant matchAny, un seul des éléments suivants doit correspondre. + # Dans ce cas, l'un des types de porte, ou un article appelé "Beechwood Door", ou un objet avec "A door" dans sa lore. + matchAny: true + material: + - Acacia_Door + - Oak_Door + - Spruce_Door + name: + - 'Beechwood Door' + lore: + - 'A door' + + rasp: + name: '&cRaspberry' + + +# -- Ingrédients dans le chaudron -- +# Quels sont les ingrédients acceptés par le chaudron et la potion de base qui en résulte + +# name: Nom de la potion de base qui sort du chaudron (codes de formatage possibles : tels que &6) +# ingredients: Liste des 'matériaux/montant' +# Avec un objet en main, utilisez /brew ItemName pour obtenir son matériau pour une recette de cuisine +# (Les id d'objets à la place des matériaux sont obsolètes pour bukkit) +# Une liste des matériaux peuvent-être trouvés ici: https://hub.spigotmc.org/javadocs/spigot/org/bukkit/Material.html +# color : Couleur de la potion provenant d'un chaudron. +# Couleurs disponibles : DARK_RED, RED, BRIGHT_RED, ORANGE, PINK, BLUE, CYAN, WATER, GREEN, BLACK, GREY, BRIGHT_GREY +# (Dans l'ordre : Rouge foncé, Rouge, Rouge clair, Orange, Rose, Bleu, Cyan, Eau, Vert, Noir, Gris, Gris clair) +# Ou couleurs RGB (hex: par exemple '99FF33') (avec '') (recherche de "HTML color" sur internet) +# lore: Liste de texte supplémentaire sur la potion de base. (Formatting codes possible: such as &6) + +cauldron: + ex: + name: Exemple + ingredients: + - Bedrock/2 + - Diamond + color: BLACK + lore: + - Un exemple pour une potion de base + - Voici comment il sort d'un chaudron + + # -- Un ingrédient: -- + wheat: + name: Blé fermenté + ingredients: Wheat + + sugarcane: + name: Sucre fermenté + ingredients: Sugar_Cane + color: 'f1ffad' # yellowish green + + apple: + name: Cidre de pommes + ingredients: Apple + + potato: + name: Purée de Pommes de Terre + ingredients: Potato + + grass: + name: Herbes bouillies + ingredients: Grass + color: '99ff66' # bright green + + rmushroom: + name: Champignons fermentés + ingredients: Red_Mushroom + color: 'ff5c33' # amber red + + cocoa: + name: Infusion au chocolat + ingredients: Cocoa_Beans + color: '804600' # mocca + + milk: + name: Eau laiteuse + ingredients: Milk_Bucket + color: BRIGHT_GREY + + # -- Ingrédients multiples: -- + apfelmet_base: + name: Brassée pomme-sucre + ingredients: + - Sugar_Cane/3 + - Apple + color: 'e1ff4d' # greenish yellow + + # -- Recette pour les boissons -- # name: Différents noms pour la mauvaise/moyen/bonne qualité (Les codes de mise en forme sont pris en charge: comme par exemple &6 pour la couleur Or.) # ingredients: Liste des 'matériaux/montant' -# With an item in your hand, use /brew ItemName to get its material for use in a recipe +# Avec un objet en main, utilisez /brew ItemName pour obtenir son matériau pour une recette de cuisine # (Les id d'objets à la place des matériaux sont obsolètes pour bukkit) # Ex: 'Sugar_Cane' # Une liste des matériaux peuvent-être trouvés ici: https://hub.spigotmc.org/javadocs/spigot/org/bukkit/Material.html +# Plugin items avec 'plugin:id' (Actuellement supporté ExoticGarden, Slimefun, MMOItems, Brewery) +# Ou un élément personnalisé défini ci-dessus # cookingtime: Temps en minutes réelles durant lesquelles les ingrédients devront bouillir # distillruns: Combien de fois le breuvage devra être distillé pour un alcool de qualité (0=Ne pas distiller) -# distilltime: How long (in seconds) one distill-run takes (0=Default time of 40 sec) MC Default would be 20 sec +# distilltime: Combien de temps (en secondes) dure une distillation (0=Temps par défaut de 40 secondes) MC Par défaut serait de 20 secondes # wood: Type de bois du baril 0=aucun 1=Bouleau 2=Chêne 3=Jungle 4=Pin 5=Acacia 6=Chêne Noir -# The Minecraft barrel is made of oak +# Le tonneau Minecraft est en chêne. # age: Temps en jours de Minecraft, la potion devra être âgée dans un baril. 0=Pas besoin d'âge # color: Couleur de la potion après distillation/avoir laissé vieillir. -# Couleurs disponibles: DARK_RED, RED, BRIGHT_RED, ORANGE, PINK, BLUE, CYAN, WATER, GREEN, BLACK, GREY, BRIGHT_GREY (Dans l'ordre : Rouge foncé, Rouge, Rouge clair, Orange, Rose, Bleu, Cyan, Eau, Vert, Noir, Gris, Gris clair) -# Or RGB colors (hex: for example '99FF33') (with '') (search for "HTML color" on the internet) +# Couleurs disponibles: DARK_RED, RED, BRIGHT_RED, ORANGE, PINK, BLUE, CYAN, WATER, GREEN, BLACK, GREY, BRIGHT_GREY +# (Dans l'ordre : Rouge foncé, Rouge, Rouge clair, Orange, Rose, Bleu, Cyan, Eau, Vert, Noir, Gris, Gris clair) +# Ou couleurs RGB (hex: par exemple '99FF33') (avec '') (recherche de "HTML color" sur internet) # difficulty: 1-10 précision nécessaire pour obtenir une bonne qualité (1 = imprécis/facile, 10 = très précis/difficile) # alcohol: Le montant d'alcool absolu dans une boisson parfaite (cela sera ajouté directement au joueur, où 100% entraînera l'évanouissement), un degré d'alcooléisme en fait +# lore: Liste des textes supplémentaires sur le breuvage fini. (Codes de formatage possibles : tels que &6) +# Texte spécifique de qualité possible, en utilisant + mauvais, ++ normal, +++ bon, ajouté à l'avant de la ligne. +# servercommands: Liste des commandes exécutées par le serveur lors de la consommation de la potion +# playercommands: Liste des commandes exécutées par le joueur lors de la consommation de la potion +# drinkmessage: Chat-message au joueur lorsqu'il boit la potion +# drinktitle: Titre à l'écran du joueur lorsqu'il boit la potion # effects: Liste des effets/durée en secondes lors de la consommation. # Effets posssible: https://hub.spigotmc.org/javadocs/spigot/org/bukkit/potion/PotionEffectType.html # POUR LES EFFETS EN FONCTIONS DE LA QUALITE : Les Niveaux (I ou II) ou les Intervalles de durées d'effets doivent être spécifiés avec un "-". @@ -105,144 +230,168 @@ version: '1.8' recipes: # Exemple de recette avec tous les paramètres possibles : - 0: - name: Mauvais Exemple/Exemple/Bonne Exemple - ingredients: - - Sugar_Cane/5 + 0: + name: Mauvais Exemple/Exemple/Bonne Exemple + ingredients: - Diamond/1 - - Cocoa_Beans/20 - Spruce_Planks/8 - Bedrock/1 - cookingtime: 3 - distillruns: 2 - distilltime: 60 - wood: 4 - age: 11 - color: DARK_RED - difficulty: 3 - alcohol: 23 - effects: + - Brewery:Bière Blanche/2 +# - ExoticGarden:Grape/3 + - ex-item/4 + cookingtime: 3 + distillruns: 2 + distilltime: 60 + wood: 4 + age: 11 + color: DARK_RED + difficulty: 3 + alcohol: 23 + lore: + - C'est un breuvage d'exemple + - ++Juste un exemple normal + - Ce texte serait sur le breuvage + - + Ça sent dégueulasse. + - ++ Ça sent bon + - +++ Ça sent vraiment bon + servercommands: + - weather clear + playercommands: + - homes + drinkmessage: C'est bon au goût + drinktitle: vous réchauffe à l'intérieur + effects: - FIRE_RESISTANCE/20 - HEAL/1 - WEAKNESS/2-3/50-60 - POISON/1-0/20-0 - 1: - name: Bière Blanche Fade/Bière Blanche/Bonne Bière Blanche - ingredients: + + 1: + name: Bière Blanche Fade/Bière Blanche/Bonne Bière Blanche + ingredients: - Wheat/3 - cookingtime: 8 - distillruns: 0 - wood: 1 - age: 2 - color: BRIGHT_GREY - difficulty: 1 - alcohol: 5 - 2: - name: Bière Fade/Bière/Bonne Bière - ingredients: + cookingtime: 8 + distillruns: 0 + wood: 1 + age: 2 + color: BRIGHT_GREY + difficulty: 1 + alcohol: 5 + + 2: + name: Bière Fade/Bière/Bonne Bière + ingredients: - Wheat/6 - cookingtime: 8 - distillruns: 0 - wood: 0 - age: 3 - color: ORANGE - difficulty: 1 - alcohol: 6 - 3: - name: Bière Brune Fade/Bière Brune/Bonne Bière Brune - ingredients: + cookingtime: 8 + distillruns: 0 + wood: 0 + age: 3 + color: ORANGE + difficulty: 1 + alcohol: 6 + + 3: + name: Bière Brune Fade/Bière Brune/Bonne Bière Brune + ingredients: - Wheat/6 - cookingtime: 8 - distillruns: 0 - wood: 4 - age: 8 - color: BLACK - difficulty: 2 - alcohol: 7 - 4: - name: Hydromel Bizarre/Hydromel/&6Hydromel Doré - ingredients: + cookingtime: 8 + distillruns: 0 + wood: 4 + age: 8 + color: BLACK + difficulty: 2 + alcohol: 7 + + 4: + name: Hydromel Bizarre/Hydromel/&6Hydromel Doré + ingredients: - Sugar_Cane/6 - cookingtime: 3 - distillruns: 0 - wood: 2 - age: 4 - color: ORANGE - difficulty: 2 - alcohol: 9 - 5: - name: Hydromel de Pommes/Doux Hydromel de Pommes/&6Doux Hydromel de Pommes Dorées - ingredients: + cookingtime: 3 + distillruns: 0 + wood: 2 + age: 4 + color: ORANGE + difficulty: 2 + alcohol: 9 + + 5: + name: Hydromel de Pommes/Doux Hydromel de Pommes/&6Doux Hydromel de Pommes Dorées + ingredients: - Sugar_Cane/6 - Apple/2 - cookingtime: 4 - distillruns: 0 - wood: 2 - age: 4 - color: ORANGE - difficulty: 4 - alcohol: 12 - effects: + cookingtime: 4 + distillruns: 0 + wood: 2 + age: 4 + color: ORANGE + difficulty: 4 + alcohol: 12 + effects: - WATER_BREATHING/1-2/150 - 6: - name: Rhum Amer/Rhum Epicé/&6Rhum Doré - ingredients: + + 6: + name: Rhum Amer/Rhum Epicé/&6Rhum Doré + ingredients: - Sugar_Cane/14 - cookingtime: 5 - distillruns: 2 - distilltime: 30 - wood: 2 - age: 14 - color: DARK_RED - difficulty: 6 - alcohol: 30 - effects: + cookingtime: 5 + distillruns: 2 + distilltime: 30 + wood: 2 + age: 14 + color: DARK_RED + difficulty: 6 + alcohol: 30 + effects: - FIRE_RESISTANCE/1/20-100 - POISON/1-0/30-0 - 7: - name: Vodka Sale/Vodka/Vodka Russe - ingredients: + + 7: + name: Vodka Sale/Vodka/Vodka Russe + ingredients: - Potato/10 - cookingtime: 15 - distillruns: 3 - age: 0 - color: BRIGHT_GREY - difficulty: 4 - alcohol: 20 - effects: + cookingtime: 15 + distillruns: 3 + age: 0 + color: BRIGHT_GREY + difficulty: 4 + alcohol: 20 + effects: - WEAKNESS/15 - POISON/10 - 8: - name: Absinthe pauvre/Absinthe/Absinthe forte - ingredients: + + 8: + name: Absinthe pauvre/Absinthe/Absinthe forte + ingredients: - Grass/15 - cookingtime: 3 - distillruns: 6 - distilltime: 80 - color: GREEN - difficulty: 8 - alcohol: 45 - effects: + cookingtime: 3 + distillruns: 6 + distilltime: 80 + color: GREEN + difficulty: 8 + alcohol: 45 + effects: - POISON/20-30 - 9: - name: Potato soup - ingredients: + + 9: + name: Potato soup + ingredients: - Potato/5 - Grass/3 - cookingtime: 3 - color: PINK - difficulty: 1 - effects: + cookingtime: 3 + color: PINK + difficulty: 1 + effects: - HEAL/0-1 - 10: - name: Café fétide/Café/Café fort - ingredients: + + 10: + name: Café fétide/Café/Café fort + ingredients: - Cocoa_Beans/12 - Milk_Bucket/2 - cookingtime: 2 - color: BLACK - difficulty: 3 - effects: + cookingtime: 2 + color: BLACK + difficulty: 3 + effects: - REGENERATION/1/2-5 - SPEED/1/30-140 @@ -251,28 +400,13 @@ recipes: # Ce sera aux Admins des serveurs de changer et d'ajouter les recettes, ainsi les joueurs ne pourront pas tricher avec les configuration de base. - -# cooked: CHAQUE ingrédient possible avec le nom donné après la fermentation (la cuisson): -# [Exemple] MATERIEL: Nom après la cuisson - -cooked: - Wheat: Blé fermenté - Sugar_Cane: Sucre fermenté - Apple: Cidre de pommes - Potato: Purée de Pommes de Terre - Grass: Herbes bouillies - Red_Mushroom: Champignons fermentés - Cocoa_Beans: Fermentation colorée - Milk_Bucket: Eau laiteuse - - - # -- Compatibilité entre Plugins -- # Activer la vérification des autres plugins (si installés) pour les permissions des tonneaux. [true] useWorldGuard: true useLWC: true useGriefPrevention: true +useGMInventories: true # Activer l'historique du contenu des tonneaux avec LogBlock [true] useLogBlock: true @@ -280,10 +414,9 @@ useLogBlock: true # -- Paramètres de la distorsion du Chat -- -# If written Chat is distorted when the Player is Drunk, -# so that it looks like drunk writing -# How much the chat is distorted depends on how drunk the Player is -# Below are settings for what and how changes in chat occur +# Si le Chat écrit est déformé quand le joueur est ivre, de sorte qu'il ressemble à un chat bourré en train d'écrire +# Le degré de distorsion du chat dépend de l'état d'ébriété du joueur +# Ci-dessous sont les paramètres pour ce qui et comment les changements dans le chat se produisent enableChatDistortion: true # Ecrire dans les "logs" du serveur ce que le joueur devrait dire, à la place de la distorsion. [false] diff --git a/resources/config/v13/it/config.yml b/resources/config/v13/it/config.yml index 64895cd..a32eac1 100644 --- a/resources/config/v13/it/config.yml +++ b/resources/config/v13/it/config.yml @@ -40,8 +40,8 @@ pukeDespawntime: 60 # Oggetto consumabile/forza. Questi oggetti se consumati calano il livello di alcool (della "forza" che avevi impsotato) (list) drainItems: -- Bread/4 -- Milk_Bucket/2 + - Bread/4 + - Milk_Bucket/2 # Tempo in giorni che la sbronza resta in memoria dopo che il giocatore va offline, cioè il tempo per cui i postumi della sbornia durano. [7] hangoverDays: 7 @@ -50,6 +50,12 @@ hangoverDays: 7 colorInBarrels: true colorInBrewer: true +# Always show the 1-5 stars on the item depending on the quality. If false, they will only appear when brewing [true] +alwaysShowQuality: true + +# Always show the alcohol content on the item. If false, it will only show in the brewing stand [false] +alwaysShowAlc: false + # Se un barile grande può essere aperto cliccandoci sopra, non solo sul cartello e sulla staccionata. Questo è sempre true per i barili piccoli. [true] openLargeBarrelEverywhere: true @@ -71,10 +77,117 @@ updateCheck: true # Intervallo di autosalvataggio in minuti [3] autosave: 3 +# Show debug messages in log [false] +debug: false + # Versione del config version: '1.8' + +# -- Define custom items -- +# The defined id can then be used in recipes + +# matchAny: true if it is already enough if one of the info matches +# material: Which type the item has to be +# name: Which name the item has to be (Formatting codes possible: such as &6) +# lore: What has to be in the lore of the item + +customItems: + ex-item: + # A Barrier item called Wall and has the given line in its lore + material: Barrier + name: 'Wall' + lore: + - '&7Very well protected' + + ex-item2: + # Using matchAny only one of the following has to match. + # In this case on of the door types, or an item called Beechwood Door, or an item with 'A door' in its lore + matchAny: true + material: + - Acacia_Door + - Oak_Door + - Spruce_Door + name: + - 'Beechwood Door' + lore: + - 'A door' + + rasp: + name: '&cRaspberry' + + +# -- Ingredients in the Cauldron -- +# Which Ingredients are accepted by the Cauldron and the base potion resulting from them + +# name: Name of the base potion coming out of the Cauldron (Formatting codes possible: such as &6) +# ingredients: List of 'material/amount' +# With an item in your hand, use /brew ItemName to get its material for use in a recipe +# (Item-ids instead of material are not supported by bukkit anymore and will not work) +# A list of materials can be found here: https://hub.spigotmc.org/javadocs/spigot/org/bukkit/Material.html +# color: Color of the potion from a cauldron. +# Usable Colors: DARK_RED, RED, BRIGHT_RED, ORANGE, PINK, BLUE, CYAN, WATER, GREEN, BLACK, GREY, BRIGHT_GREY +# Or RGB colors (hex: for example '99FF33') (with '') (search for "HTML color" on the internet) +# lore: List of additional text on the base potion. (Formatting codes possible: such as &6) + +cauldron: + ex: + name: Example + ingredients: + - Bedrock/2 + - Diamond + color: BLACK + lore: + - An example for a Base Potion + - This is how it comes out of a Cauldron + + # -- One Ingredient: -- + wheat: + name: Fermented wheat + ingredients: Wheat + + sugarcane: + name: Sugar brew + ingredients: Sugar_Cane + color: 'f1ffad' # yellowish green + + apple: + name: Apple cider + ingredients: Apple + + potato: + name: Potatomash + ingredients: Potato + + grass: + name: Boiled herbs + ingredients: Grass + color: '99ff66' # bright green + + rmushroom: + name: Mushroom brew + ingredients: Red_Mushroom + color: 'ff5c33' # amber red + + cocoa: + name: Chocolately brew + ingredients: Cocoa_Beans + color: '804600' # mocca + + milk: + name: Milky water + ingredients: Milk_Bucket + color: BRIGHT_GREY + + # -- Multiple Ingredients: -- + apfelmet_base: + name: Apple-Sugar brew + ingredients: + - Sugar_Cane/3 + - Apple + color: 'e1ff4d' # greenish yellow + # -- Ricette per pozioni -- # name: Tre nomi diversi per diverse qualità (cattivo/normale/buono). I codici come &6 possono essere usati. @@ -82,6 +195,8 @@ version: '1.8' # With an item in your hand, use /brew ItemName to get its material for use in a recipe # (Gli id invece dei materiali sono "disapprovati" da Bukkit) # Una lista di materiali può essere trovata qui: https://hub.spigotmc.org/javadocs/spigot/org/bukkit/Material.html +# Plugin items with 'plugin:id' (Currently supporting ExoticGarden, Slimefun, MMOItems, Brewery) +# Or a custom item defined above # cookingtime: Tempo in minuti richiesto dagli ingredienti per bollire # distillruns: Quanto spesso deve essere distillato per ottenere la versione perfetta con il volume alcolico impostato (0=non serve distillare). # distilltime: How long (in seconds) one distill-run takes (0=Default time of 40 sec) MC Default would be 20 sec @@ -93,6 +208,12 @@ version: '1.8' # Or RGB colors (hex: for example '99FF33') (with '') (search for "HTML color" on the internet) # difficoltà: Precisione richiesta per avere la migliore qualità da 1 a 10(1 = spreciso/più facile, 10 = molto preciso/più difficile) # alcohol: Volume alcolico da 0 a 100 nella versione perfetta (sarà aggiunta direttamente al giocatore, dove 100 è la quantità massima di alcohol assorbibile. +# lore: List of additional text on the finished brew. (Formatting codes possible: such as &6) +# Specific lore for quality possible, using + bad, ++ normal, +++ good, added to the front of the line. +# servercommands: List of Commands executed by the Server when drinking the brew +# playercommands: List of Commands executed by the Player when drinking the brew +# drinkmessage: Chat-message to the Player when drinking the Brew +# drinktitle: Title on Screen to the Player when drinking the Brew # effects: Eventuali effetti come quelli delle pozioni nel formato di effetto/livello/durata. # Lista di effetti possibili: https://hub.spigotmc.org/javadocs/spigot/org/bukkit/potion/PotionEffectType.html # Intervalli di livelli o durate possono essere specificati con un "-", per esempio 'SPEED/1-2/30-40'. Ciò significa nel peggior caso livello 1 e 30 secondi di durata e livello 2 e 40 secondi nel migliore. @@ -100,145 +221,169 @@ version: '1.8' # La durata massima possibile è 1638 secondi. Gli effetti instantaner non hanno bisogno che la durata sia specificata. recipes: -# Ricetta di esempio con ogni opzione possibile: - 0: - name: Cattivo esempio/Esempio/Buon esempio - ingredients: - - Sugar_Cane/5 + # Ricetta di esempio con ogni opzione possibile: + 0: + name: Cattivo esempio/Esempio/Buon esempio + ingredients: - Diamond/1 - - Cocoa_Beans/20 - Spruce_Planks/8 - Bedrock/1 - cookingtime: 3 - distillruns: 2 - distilltime: 60 - wood: 4 - age: 11 - color: DARK_RED - difficulty: 3 - alcohol: 23 - effects: + - Brewery:Wheatbeer/2 + # - ExoticGarden:Grape/3 + - ex-item/4 + cookingtime: 3 + distillruns: 2 + distilltime: 60 + wood: 4 + age: 11 + color: DARK_RED + difficulty: 3 + alcohol: 23 + lore: + - This is an examble brew + - ++Just a normal Example + - This text would be on the brew + - + Smells disgusting + - ++ Smells alright + - +++ Smells really good + servercommands: + - weather clear + playercommands: + - homes + drinkmessage: Tastes good + drinktitle: Warms you from inside + effects: - FIRE_RESISTANCE/20 - HEAL/1 - WEAKNESS/2-3/50-60 - POISON/1-0/20-0 - 1: - name: Birra di frumento puzzolente/Birra di frumento/Birra di frumento pregiata - ingredients: + + 1: + name: Birra di frumento puzzolente/Birra di frumento/Birra di frumento pregiata + ingredients: - Wheat/3 - cookingtime: 8 - distillruns: 0 - wood: 1 - age: 2 - color: BRIGHT_GREY - difficulty: 1 - alcohol: 5 - 2: - name: Birra puzzolente/Birra/Birra pregiata - ingredients: + cookingtime: 8 + distillruns: 0 + wood: 1 + age: 2 + color: BRIGHT_GREY + difficulty: 1 + alcohol: 5 + + 2: + name: Birra puzzolente/Birra/Birra pregiata + ingredients: - Wheat/6 - cookingtime: 8 - distillruns: 0 - wood: 0 - age: 3 - color: ORANGE - difficulty: 1 - alcohol: 6 - 3: - name: Birra scura puzzolente/Birra scura/Birra scura pregiata - ingredients: + cookingtime: 8 + distillruns: 0 + wood: 0 + age: 3 + color: ORANGE + difficulty: 1 + alcohol: 6 + + 3: + name: Birra scura puzzolente/Birra scura/Birra scura pregiata + ingredients: - Wheat/6 - cookingtime: 8 - distillruns: 0 - wood: 4 - age: 8 - color: BLACK - difficulty: 2 - alcohol: 7 - 4: - name: Idromele scarso/Idromele/&6Idromele dorato - ingredients: + cookingtime: 8 + distillruns: 0 + wood: 4 + age: 8 + color: BLACK + difficulty: 2 + alcohol: 7 + + 4: + name: Idromele scarso/Idromele/&6Idromele dorato + ingredients: - Sugar_Cane/6 - cookingtime: 3 - distillruns: 0 - wood: 2 - age: 4 - color: ORANGE - difficulty: 2 - alcohol: 9 - 5: - name: Idromele di mele/Idromele di mele dolci/&6Idromele di mele dolci dorato - ingredients: + cookingtime: 3 + distillruns: 0 + wood: 2 + age: 4 + color: ORANGE + difficulty: 2 + alcohol: 9 + + 5: + name: Idromele di mele/Idromele di mele dolci/&6Idromele di mele dolci dorato + ingredients: - Sugar_Cane/6 - Apple/2 - cookingtime: 4 - distillruns: 0 - wood: 2 - age: 4 - color: ORANGE - difficulty: 4 - alcohol: 12 - effects: + cookingtime: 4 + distillruns: 0 + wood: 2 + age: 4 + color: ORANGE + difficulty: 4 + alcohol: 12 + effects: - WATER_BREATHING/1-2/150 - 6: - name: Rum amaro/Rum speziato/&6Rum dorato - ingredients: + + 6: + name: Rum amaro/Rum speziato/&6Rum dorato + ingredients: - Sugar_Cane/14 - cookingtime: 5 - distillruns: 2 - distilltime: 30 - wood: 2 - age: 14 - color: DARK_RED - difficulty: 6 - alcohol: 30 - effects: + cookingtime: 5 + distillruns: 2 + distilltime: 30 + wood: 2 + age: 14 + color: DARK_RED + difficulty: 6 + alcohol: 30 + effects: - FIRE_RESISTANCE/1/20-100 - POISON/1-0/30-0 - 7: - name: Vodka schifosa/Vodka/Vodka russa - ingredients: + + 7: + name: Vodka schifosa/Vodka/Vodka russa + ingredients: - Potato/10 - cookingtime: 15 - distillruns: 3 - age: 0 - color: BRIGHT_GREY - difficulty: 4 - alcohol: 20 - effects: + cookingtime: 15 + distillruns: 3 + age: 0 + color: BRIGHT_GREY + difficulty: 4 + alcohol: 20 + effects: - WEAKNESS/15 - POISON/10 - 8: - name: Assenzio scarso/Assenzio/Assenzio forte - ingredients: + + 8: + name: Assenzio scarso/Assenzio/Assenzio forte + ingredients: - Grass/15 - cookingtime: 3 - distillruns: 6 - distilltime: 80 - color: GREEN - difficulty: 8 - alcohol: 45 - effects: + cookingtime: 3 + distillruns: 6 + distilltime: 80 + color: GREEN + difficulty: 8 + alcohol: 45 + effects: - POISON/20-30 - 9: - name: Zuppa di patate - ingredients: + + 9: + name: Zuppa di patate + ingredients: - Potato/5 - Grass/3 - cookingtime: 3 - color: PINK - difficulty: 1 - effects: + cookingtime: 3 + color: PINK + difficulty: 1 + effects: - HEAL/0-1 - 10: - name: Caffè stantio/Caffè/Caffè forte - ingredients: + + 10: + name: Caffè stantio/Caffè/Caffè forte + ingredients: - Cocoa_Beans,3/12 - Milk_Bucket/2 - cookingtime: 2 - color: BLACK - difficulty: 3 - effects: + cookingtime: 2 + color: BLACK + difficulty: 3 + effects: - REGENERATION/1/2-5 - SPEED/1/30-140 @@ -248,27 +393,13 @@ recipes: -# cooked: OGNI possibile ingrediente e i nomi per la pozione originatasi dopo la fermentazione. -# (Esempio) MATERIALE: Nome dopo la cottura - -cooked: - Wheat: Frumento fermentato - Sugar_Cane: Miscela zuccherata - Apple: Sidro di mele - Potato: Purè di patate - Grass: Erbe bollite - Red_Mushroom: Miscela ai funghi - Cocoa_Beans: Miscela colorata - Milk_Bucket: Acqua lattea - - - # -- Compatibilità con altri plugin -- # Abilita il controllo della presenza di altri plugin per i permessi relativi ai barili[true] useWorldGuard: true useLWC: true useGriefPrevention: true +useGMInventories: true # Abilita il logging degli inventari dei barili [true] useLogBlock: true diff --git a/resources/config/v13/zh/config.yml b/resources/config/v13/zh/config.yml index b1dfda5..8c5d79a 100644 --- a/resources/config/v13/zh/config.yml +++ b/resources/config/v13/zh/config.yml @@ -52,6 +52,12 @@ hangoverDays: 7 colorInBarrels: true colorInBrewer: true +# Always show the 1-5 stars on the item depending on the quality. If false, they will only appear when brewing [true] +alwaysShowQuality: true + +# Always show the alcohol content on the item. If false, it will only show in the brewing stand [false] +alwaysShowAlc: false + # 大型熟成木桶可以通过右击桶身任意一个位置来打开, 而不需要专门右击其龙头. 这一操作对小型酒桶总为真.[true] openLargeBarrelEverywhere: false @@ -73,10 +79,119 @@ updateCheck: true # 自动保存时间间隔, 单位:分钟.[3] autosave: 3 +# Show debug messages in log [false] +debug: false + # 配置文件版本 version: '1.8' + +# -- Define custom items -- +# The defined id can then be used in recipes + +# matchAny: true if it is already enough if one of the info matches +# material: Which type the item has to be +# name: Which name the item has to be (Formatting codes possible: such as &6) +# lore: What has to be in the lore of the item + +customItems: + ex-item: + # A Barrier item called Wall and has the given line in its lore + material: Barrier + name: 'Wall' + lore: + - '&7Very well protected' + + ex-item2: + # Using matchAny only one of the following has to match. + # In this case on of the door types, or an item called Beechwood Door, or an item with 'A door' in its lore + matchAny: true + material: + - Acacia_Door + - Oak_Door + - Spruce_Door + name: + - 'Beechwood Door' + lore: + - 'A door' + + rasp: + name: '&cRaspberry' + + +# -- Ingredients in the Cauldron -- +# Which Ingredients are accepted by the Cauldron and the base potion resulting from them + +# name: Name of the base potion coming out of the Cauldron (Formatting codes possible: such as &6) +# ingredients: List of 'material/amount' +# With an item in your hand, use /brew ItemName to get its material for use in a recipe +# (Item-ids instead of material are not supported by bukkit anymore and will not work) +# A list of materials can be found here: https://hub.spigotmc.org/javadocs/spigot/org/bukkit/Material.html +# color: Color of the potion from a cauldron. +# Usable Colors: DARK_RED, RED, BRIGHT_RED, ORANGE, PINK, BLUE, CYAN, WATER, GREEN, BLACK, GREY, BRIGHT_GREY +# Or RGB colors (hex: for example '99FF33') (with '') (search for "HTML color" on the internet) +# lore: List of additional text on the base potion. (Formatting codes possible: such as &6) + +cauldron: + ex: + name: Example + ingredients: + - Bedrock/2 + - Diamond + color: BLACK + lore: + - An example for a Base Potion + - This is how it comes out of a Cauldron + + # -- One Ingredient: -- + wheat: + name: 发酵麦汁 + ingredients: Wheat + + sugarcane: + name: 糖浆 + ingredients: Sugar_Cane + color: 'f1ffad' # yellowish green + + apple: + name: 苹果汁 + ingredients: Apple + + potato: + name: 土豆泥 + ingredients: Potato + + grass: + name: 蒸煮过的药草 + ingredients: Grass + color: '99ff66' # bright green + + rmushroom: + name: 蘑菇酿 + ingredients: Red_Mushroom + color: 'ff5c33' # amber red + + cocoa: + name: 上了色的水 + ingredients: Cocoa_Beans + color: '804600' # mocca + + milk: + name: 乳浊液体 + ingredients: Milk_Bucket + color: BRIGHT_GREY + + # -- Multiple Ingredients: -- + apfelmet_base: + name: Apple-Sugar brew + ingredients: + - Sugar_Cane/3 + - Apple + color: 'e1ff4d' # greenish yellow + + + # -- 饮品配方列表 -- # name: 饮品名称, 可以为 劣质/普通/优质 三种质量的饮品命名(可插入样式代码, 如:&6). @@ -84,6 +199,8 @@ version: '1.8' # 手中持有物品的时候, 可以使用/brew ItemName来获取其物品id, 便于增改配方 # (请勿使用物品ID, 物品ID已被弃用, 使用材料名称是唯一支持的做法.) # 材料名称列表详见此处: https://hub.spigotmc.org/javadocs/spigot/org/bukkit/Material.html (可能需要挂梯子进行浏览) +# Plugin items with 'plugin:id' (Currently supporting ExoticGarden, Slimefun, MMOItems, Brewery) +# Or a custom item defined above # cookingtime: 原料需要在炼药锅内烹制发酵的时间, 单位为现实分钟. # distillruns: 饮品需要在酿造台上蒸馏的次数(0=无需蒸馏). # distilltime: 每次蒸馏所需要耗费的时间(0=默认值, 即40秒), MC默认则为20秒/ @@ -96,6 +213,12 @@ version: '1.8' # 也可以使用RGB颜色(十六进制, 如'99FF33', 必须包含两个单引号)(在线搜索"HTML 颜色"或者其他颜色库即刻获得你需要的颜色的十六进制表示) # difficulty: 酿制难度, 1 = 不需要非常精确的操作就可以制出优质饮品, 10 = 需要非常精确的操作才可以制出优质饮品. # alcohol: 完美质量的饮品所含有的酒精度(百分数, 会被直接添加到玩家身上, 100意为直接昏迷) +# lore: List of additional text on the finished brew. (Formatting codes possible: such as &6) +# Specific lore for quality possible, using + bad, ++ normal, +++ good, added to the front of the line. +# servercommands: List of Commands executed by the Server when drinking the brew +# playercommands: List of Commands executed by the Player when drinking the brew +# drinkmessage: Chat-message to the Player when drinking the Brew +# drinktitle: Title on Screen to the Player when drinking the Brew # effects: 饮用后能够获得的药效的列表. 格式为"药效/强度/时长(秒)". # 药效列表: https://hub.spigotmc.org/javadocs/spigot/org/bukkit/potion/PotionEffectType.html # 药效强度与时长可以用"-"划分区间, 如: "SPEED/1-2/30-40" = 最劣质情况下的饮品会给予速度1三十秒, 最优质则会给予速度2四十秒. @@ -103,145 +226,170 @@ version: '1.8' # 时长极限为1638秒. 药效强度极限为255级. 瞬间型药效无需附加时长. recipes: -# 例: - 0: - name: 劣质的 范例饮品/范例饮品/优质的 范例饮品 - ingredients: - - Sugar_Cane/5 + # 例: + + 0: + name: 劣质的 范例饮品/范例饮品/优质的 范例饮品 + ingredients: - Diamond/1 - - Cocoa_Beans/20 - Spruce_Planks/8 - Bedrock/1 - cookingtime: 3 - distillruns: 2 - distilltime: 60 - wood: 4 - age: 11 - color: DARK_RED - difficulty: 3 - alcohol: 23 - effects: + - Brewery:Wheatbeer/2 +# - ExoticGarden:Grape/3 + - ex-item/4 + cookingtime: 3 + distillruns: 2 + distilltime: 60 + wood: 4 + age: 11 + color: DARK_RED + difficulty: 3 + alcohol: 23 + lore: + - This is an examble brew + - ++Just a normal Example + - This text would be on the brew + - + Smells disgusting + - ++ Smells alright + - +++ Smells really good + servercommands: + - weather clear + playercommands: + - homes + drinkmessage: Tastes good + drinktitle: Warms you from inside + effects: - FIRE_RESISTANCE/20 - HEAL/1 - WEAKNESS/2-3/50-60 - POISON/1-0/20-0 - 1: - name: 劣质麦啤/麦啤/优质麦啤 - ingredients: + + 1: + name: 劣质麦啤/麦啤/优质麦啤 + ingredients: - Wheat/3 - cookingtime: 8 - distillruns: 0 - wood: 1 - age: 2 - color: BRIGHT_GREY - difficulty: 1 - alcohol: 5 - 2: - name: 劣质啤酒/啤酒/鲜啤 - ingredients: + cookingtime: 8 + distillruns: 0 + wood: 1 + age: 2 + color: BRIGHT_GREY + difficulty: 1 + alcohol: 5 + + 2: + name: 劣质啤酒/啤酒/鲜啤 + ingredients: - Wheat/6 - cookingtime: 8 - distillruns: 0 - wood: 0 - age: 3 - color: ORANGE - difficulty: 1 - alcohol: 6 - 3: - name: 劣质黑啤/黑啤/精制黑啤 - ingredients: + cookingtime: 8 + distillruns: 0 + wood: 0 + age: 3 + color: ORANGE + difficulty: 1 + alcohol: 6 + + 3: + name: 劣质黑啤/黑啤/精制黑啤 + ingredients: - Wheat/6 - cookingtime: 8 - distillruns: 0 - wood: 4 - age: 8 - color: BLACK - difficulty: 2 - alcohol: 7 - 4: - name: 粗制蜜酒/蜜酒/黄金蜜酒 - ingredients: + cookingtime: 8 + distillruns: 0 + wood: 4 + age: 8 + color: BLACK + difficulty: 2 + alcohol: 7 + + 4: + name: 粗制蜜酒/蜜酒/黄金蜜酒 + ingredients: - Sugar_Cane/6 - cookingtime: 3 - distillruns: 0 - wood: 2 - age: 4 - color: ORANGE - difficulty: 2 - alcohol: 9 - 5: - name: 苹果蜜酒/甜苹果蜜酒/甘醇黄金苹果蜜酒 - ingredients: + cookingtime: 3 + distillruns: 0 + wood: 2 + age: 4 + color: ORANGE + difficulty: 2 + alcohol: 9 + + 5: + name: 苹果蜜酒/甜苹果蜜酒/甘醇黄金苹果蜜酒 + ingredients: - Sugar_Cane/6 - Apple/2 - cookingtime: 4 - distillruns: 0 - wood: 2 - age: 4 - color: ORANGE - difficulty: 4 - alcohol: 12 - effects: + cookingtime: 4 + distillruns: 0 + wood: 2 + age: 4 + color: ORANGE + difficulty: 4 + alcohol: 12 + effects: - WATER_BREATHING/1-2/150 - 6: - name: 苦涩的朗姆/辛辣的朗姆/金品朗姆 - ingredients: + + 6: + name: 苦涩的朗姆/辛辣的朗姆/金品朗姆 + ingredients: - Sugar_Cane/14 - cookingtime: 5 - distillruns: 2 - distilltime: 30 - wood: 2 - age: 14 - color: DARK_RED - difficulty: 6 - alcohol: 30 - effects: + cookingtime: 5 + distillruns: 2 + distilltime: 30 + wood: 2 + age: 14 + color: DARK_RED + difficulty: 6 + alcohol: 30 + effects: - FIRE_RESISTANCE/1/20-100 - POISON/1-0/30-0 - 7: - name: 劣质伏特加/伏特加/纯正俄式风味伏特加 - ingredients: + + 7: + name: 劣质伏特加/伏特加/纯正俄式风味伏特加 + ingredients: - Potato/10 - cookingtime: 15 - distillruns: 3 - age: 0 - color: BRIGHT_GREY - difficulty: 4 - alcohol: 20 - effects: + cookingtime: 15 + distillruns: 3 + age: 0 + color: BRIGHT_GREY + difficulty: 4 + alcohol: 20 + effects: - WEAKNESS/15 - POISON/10 - 8: - name: 劣质苦艾酒/苦艾酒/劲猛苦艾酒 - ingredients: + + 8: + name: 劣质苦艾酒/苦艾酒/劲猛苦艾酒 + ingredients: - Grass/15 - cookingtime: 3 - distillruns: 6 - distilltime: 80 - color: GREEN - difficulty: 8 - alcohol: 45 - effects: + cookingtime: 3 + distillruns: 6 + distilltime: 80 + color: GREEN + difficulty: 8 + alcohol: 45 + effects: - POISON/20-30 - 9: - name: 土豆汤 - ingredients: + + 9: + name: 土豆汤 + ingredients: - Potato/5 - Grass/3 - cookingtime: 3 - color: PINK - difficulty: 1 - effects: + cookingtime: 3 + color: PINK + difficulty: 1 + effects: - HEAL/0-1 - 10: - name: 平淡的咖啡/咖啡/浓苦黑咖 - ingredients: + + 10: + name: 平淡的咖啡/咖啡/浓苦黑咖 + ingredients: - Cocoa_Beans/12 - Milk_Bucket/2 - cookingtime: 2 - color: BLACK - difficulty: 3 - effects: + cookingtime: 2 + color: BLACK + difficulty: 3 + effects: - REGENERATION/1/2-5 - SPEED/1/30-140 @@ -250,30 +398,13 @@ recipes: # 插件的本意是让玩家自行实验饮品制造配方, 所以未来的新配方由服管决定是否加入. - - -# cooked: 炼药锅中烹制发酵过后的液体名称, 由一个饮品中的第一个原料决定. -# [例] 原料名称: 烹制后的名称 - -cooked: - Wheat: 发酵麦汁 - Sugar_Cane: 糖浆 - Apple: 苹果汁 - Potato: 土豆泥 - Grass: 蒸煮过的药草 - Red_Mushroom: 蘑菇酿 - Cocoa_Beans: 上了色的水 - Milk_Bucket: 乳浊液体 - - - - # -- 插件兼容性 -- # 检查插件以进行权限配置[true] useWorldGuard: true useLWC: true useGriefPrevention: true +useGMInventories: true # 对LogBlock启用方块数据录入[true] useLogBlock: true diff --git a/resources/languages/de.yml b/resources/languages/de.yml index 366ba89..b4f009a 100644 --- a/resources/languages/de.yml +++ b/resources/languages/de.yml @@ -31,24 +31,17 @@ CMD_Static: '&aTrank ist nun unveränderlich und kann nicht weiter gereift oder CMD_NonStatic: '&eTrank ist wieder veränderlich und kann normal gereift oder destilliert werden' # Error +Error_ConfigUpdate: 'Unbekannte Brewery Config Version: v&v1, Config wurde nicht geupdated!' Error_ItemNotPotion: '&cDas Item in deiner Hand konnte nicht als Trank identifiziert werden' +Error_NoBarrelAccess: '&cDu hast keine Rechte dieses Fass zu öffnen!' Error_NoBrewName: '&cKein Rezept mit Namen: "&v1&c" gefunden!' +Error_NoPermissions: '&cDu hast keine Rechte dies zu tun!' Error_PlayerCommand: '&cDieser Befehl kann nur als Spieler ausgeführt werden' Error_Recipeload: '&cEs konnten nicht alle Rezepte wiederhergesellt werden: Siehe Serverlog!' Error_ShowHelp: 'Benutze &6/brew help &fum die Hilfe anzuzeigen' Error_UnknownCommand: Unbekannter Befehl -Error_ConfigUpdate: 'Unbekannte Brewery Config Version: v&v1, Config wurde nicht geupdated!' Error_YmlRead: 'config.yml konnte nicht gelesen werden, ist die Datei im korrekten yml-Format (korrekte Leerzeichen usw.)?' -# Permission -Error_NoPermissions: '&cDu hast keine Rechte dies zu tun!' -Error_NoBarrelAccess: '&cDu hast keine Rechte dieses Fass zu öffnen!' -Perms_NoBarrelCreate: '&cDu hast keine Rechte Fässer zu erstellen!' -Perms_NoSmallBarrelCreate: '&cDu kast keine Rechte kleine Fässer zu erstellen!' -Perms_NoBigBarrelCreate: '&cDu kast keine Rechte große Fässer zu erstellen!' -Perms_NoCauldronInsert: '&cDu hast keine Rechte Zutaten in Bottiche zu tun!' -Perms_NoCauldronFill: '&cDu hast keine Rechte Flaschen von diesem Bottich abzufüllen!' - # Etc Etc_Page: Seite Etc_Usage: 'Benutzung:' @@ -73,6 +66,13 @@ Help_WakeupRemove: '&6/brew Wakeup Remove &9Entfernt einen Aufwachpunkt' Help_Static: '&6/brew Static &9Trank unveränderlich machen -> Kein weiteres reifen oder destillieren möglich' Help_Create: '&6/brew Create [Qualität] [Spieler] &9Erstellt einen Trank mit optionaler Qualität (1-10)' +# Permission +Perms_NoBarrelCreate: '&cDu hast keine Rechte Fässer zu erstellen!' +Perms_NoSmallBarrelCreate: '&cDu kast keine Rechte kleine Fässer zu erstellen!' +Perms_NoBigBarrelCreate: '&cDu kast keine Rechte große Fässer zu erstellen!' +Perms_NoCauldronInsert: '&cDu hast keine Rechte Zutaten in Bottiche zu tun!' +Perms_NoCauldronFill: '&cDu hast keine Rechte Flaschen von diesem Bottich abzufüllen!' + # Player Player_BarrelCreated: Fass erfolgreich erstellt Player_BarrelFull: '&cHier passen nicht mehr Getränke hinein' diff --git a/resources/languages/fr.yml b/resources/languages/fr.yml index 4a57aca..8a5ecb1 100644 --- a/resources/languages/fr.yml +++ b/resources/languages/fr.yml @@ -5,7 +5,7 @@ Brew_BarrelRiped: Baril âgé Brew_DistillUndefined: Distillation indéfinie Brew_Distilled: Distillé Brew_HundredsOfYears: Centaines d´années -Brew_Ingredients: Ingredients +Brew_Ingredients: Ingrédients Brew_MinutePluralPostfix: s Brew_OneYear: Un an Brew_ThickBrew: Breuvage boueux @@ -14,6 +14,7 @@ Brew_Woodtype: Type de bois Brew_Years: Années Brew_fermented: fermenté Brew_minute: minute +Brew_Alc: Alc &v1ml # CMD CMD_Copy_Error: '&6&v1 &cCes potions ne rentrent pas dans votre inventaire.' @@ -23,8 +24,9 @@ CMD_NonStatic: '&eLa boisson n´est plus statique et vieillira normalement dans CMD_Player: '&a&v1 est maintenant &6&v2% &aivre, avec une qualité de &6&v3' CMD_Player_Error: '&cLa qualité doit être comprise entre 1 et 10 !' CMD_Reload: '&aLa config a été reload avec succès.' +CMD_Created: '&aBrew créé' CMD_Configname: '&aName for the Config is: &f&v1' -CMD_Configname_Error: '&cCould not find item in your hand' +CMD_Configname_Error: '&cN´a pas pu trouver d´objet dans votre main' CMD_Static: '&aLa boisson est maintenant statique et ne changera pas dans les barils ou les stands d´alchimie.' CMD_UnLabel: '&aLabel supprimé!' diff --git a/resources/languages/it.yml b/resources/languages/it.yml index 136de93..524571b 100755 --- a/resources/languages/it.yml +++ b/resources/languages/it.yml @@ -14,6 +14,7 @@ Brew_Woodtype: Tipo di legno Brew_Years: Anni Brew_fermented: fermentata Brew_minute: minuto +Brew_Alc: Alc &v1ml # Comandi CMD_Copy_Error: '&6&v1 &cLe copie di questa pozione non stavano nell''inventario.' @@ -23,6 +24,7 @@ CMD_NonStatic: '&eLa pozione non è più statica ed invecchierà normalmente nei CMD_Player: '&a&v1 è ora &6&v2% &asbronzo, con una qualità di &6&v3' CMD_Player_Error: '&cLa qualità deve essere fra 1 e 10!' CMD_Reload: '&aLa configurazione è stata ricaricata con successo' +CMD_Created: '&aBrew Created' CMD_Configname: '&aName for the Config is: &f&v1' CMD_Configname_Error: '&cCould not find item in your hand' CMD_Static: '&aLa pozione è ora statica e non cambierà né nei barili né negli alambicchi.' diff --git a/resources/languages/tw.yml b/resources/languages/tw.yml index 2ba1665..39c5298 100644 --- a/resources/languages/tw.yml +++ b/resources/languages/tw.yml @@ -14,6 +14,7 @@ Brew_Woodtype: 木材質 Brew_Years: 年 Brew_fermented: 發酵 Brew_minute: 分鐘 +Brew_Alc: Alc &v1ml # CMD CMD_Copy_Error: '&6&v1 &c藥水不適合你的庫存' @@ -23,6 +24,7 @@ CMD_NonStatic: '&e藥水不再是靜止的,會在桶木中老化.' CMD_Player: '&a&v1 現在是 &6&v2% &a醉酒,酒的品質為 &6&v3' CMD_Player_Error: '&c酒的品質必須在1到10之間!' CMD_Reload: '&a設定檔已成功重新加載' +CMD_Created: '&aBrew Created' CMD_Configname: '&aName for the Config is: &f&v1' CMD_Configname_Error: '&cCould not find item in your hand' CMD_Static: '&a藥水現在是靜止的,不會在桶或釀造台上變化.' diff --git a/resources/languages/zh.yml b/resources/languages/zh.yml index 36f7891..c64a3cb 100644 --- a/resources/languages/zh.yml +++ b/resources/languages/zh.yml @@ -14,6 +14,7 @@ Brew_Woodtype: 木头种类 Brew_Years: 年 Brew_fermented: 炖煮发酵 Brew_minute: 分钟 +Brew_Alc: Alc &v1ml # CMD CMD_Copy_Error: '&6&v1&r, &c你的背包塞不下了.' @@ -23,6 +24,7 @@ CMD_NonStatic: '&e饮品已被取消静滞, 现在可以正常地进行蒸馏或 CMD_Player: '&a&v1醉酒程度为&6&v2%&f, 醉酒质量为&6&v3.' CMD_Player_Error: '&c醉酒质量必须在1到10之间.' CMD_Reload: '&a配置文件重载成功.' +CMD_Created: '&aBrew Created' CMD_Configname: '配置文件中&aName的名字是: &f&v1' CMD_Configname_Error: '&c无法找到物品名称' CMD_Static: '&a饮品已被静滞, 现在其无法被蒸馏或进行木桶熟成.' diff --git a/src/com/dre/brewery/filedata/BConfig.java b/src/com/dre/brewery/filedata/BConfig.java index 3c698dd..7a9dc9f 100644 --- a/src/com/dre/brewery/filedata/BConfig.java +++ b/src/com/dre/brewery/filedata/BConfig.java @@ -81,8 +81,9 @@ public class BConfig { private static boolean checkConfigs() { File cfg = new File(p.getDataFolder(), "config.yml"); if (!cfg.exists()) { - p.errorLog("No config.yml found, creating default file! You may want to choose a config according to your language!"); - p.errorLog("You can find them in plugins/Brewery/configs/"); + p.log("§1§lNo config.yml found, creating default file! You may want to choose a config according to your language!"); + p.log("§1§lYou can find them in plugins/Brewery/configs/"); + p.log("§1§lJust copy the config for your language into the Brewery folder and /brew reload"); InputStream defconf = p.getResource("config/" + (P.use1_13 ? "v13/" : "v12/") + "en/config.yml"); if (defconf == null) { p.errorLog("default config file not found, your jarfile may be corrupt. Disabling Brewery!"); @@ -111,9 +112,10 @@ public class BConfig { File lfold = new File(configs, l); try { BUtil.saveFile(p.getResource("config/" + (P.use1_13 ? "v13/" : "v12/") + l + "/config.yml"), lfold, "config.yml", overwrite); - BUtil.saveFile(p.getResource("languages/" + l + ".yml"), languages, l + ".yml", false); // Never overwrite languages for now + BUtil.saveFile(p.getResource("languages/" + l + ".yml"), languages, l + ".yml", false); // Never overwrite languages, they get updated with their updater } catch (IOException e) { if (!(l.equals("zh") || l.equals("tw"))) { + // zh and tw not available for some versions e.printStackTrace(); } } From 4f0b56e2dcc3c8709b3e15b69cab92286fb9e899 Mon Sep 17 00:00:00 2001 From: Sn0wStorm Date: Sun, 1 Dec 2019 23:50:56 +0100 Subject: [PATCH 49/51] Config updater for 2.0 + config fixes & fix for unlabeled --- resources/config/patches/de18.txt | 58 +++ resources/config/patches/en18.txt | 58 +++ resources/config/patches/fr18.txt | 59 +++ resources/config/v12/de/config.yml | 34 +- resources/config/v12/en/config.yml | 35 +- resources/config/v12/fr/config.yml | 35 +- resources/config/v12/it/config.yml | 49 +- resources/config/v13/de/config.yml | 29 +- resources/config/v13/en/config.yml | 94 ++-- resources/config/v13/fr/config.yml | 30 +- resources/config/v13/it/config.yml | 44 +- resources/config/v13/zh/config.yml | 28 +- src/com/dre/brewery/Brew.java | 2 +- src/com/dre/brewery/P.java | 98 ++-- .../brewery/api/events/ConfigLoadEvent.java | 1 + src/com/dre/brewery/filedata/BConfig.java | 8 +- .../dre/brewery/filedata/ConfigUpdater.java | 454 ++++++++++++++++-- src/com/dre/brewery/lore/BrewLore.java | 25 +- src/com/dre/brewery/utility/LegacyUtil.java | 6 +- 19 files changed, 845 insertions(+), 302 deletions(-) create mode 100644 resources/config/patches/de18.txt create mode 100644 resources/config/patches/en18.txt create mode 100644 resources/config/patches/fr18.txt diff --git a/resources/config/patches/de18.txt b/resources/config/patches/de18.txt new file mode 100644 index 0000000..d123be4 --- /dev/null +++ b/resources/config/patches/de18.txt @@ -0,0 +1,58 @@ + + + +# -- Eigene Items Definieren -- +# Die festgelegte id kann dann in einem Rezept verwendet werden + +# matchAny: true wenn es schon reicht wenn eine der Angaben zutrifft +# material: Welche Art das Item haben muss +# name: Welchen Namen das Item haben muss (Farbcodes möglich: z.b. &6) +# lore: Was in der Lore des Items stehen muss + +customItems: + bsp-item: +# Ein Barriere Item das Mauer heißt und in der Lore die angegebene Zeile hat +%%%%MAT1%%%% + name: 'Mauer' + lore: + - '&7Besonders gut geschützt' + + bsp-item2: +# Mit matchAny muss nur eine der Angaben zutreffen. +# Hier also eine der Türarten, oder ein Item namens Buchenholztür, oder ein Item mit 'Eine Tür' in der Lore + matchAny: true +%%%%MAT2%%%% + name: + - 'Buchenholztür' + lore: + - 'Eine Tür' + + himbeere: + name: '&cHimbeere' + + +# -- Zutaten im Kessel -- +# Hier kann angegeben werden welche Zutaten in den Kessel getan werden können und was mit ihnen geschieht. + + # name: Name des Basistrankes der aus dem Kessel kommt (Farbcodes möglich: z.b. &6) + # ingredients: Auflistung von 'Material/Anzahl' + # Halte ein Item in der Hand und benutze /brew ItemName um dessen Material herauszufinden und für ein Rezept zu benutzen + # (Item-ids anstatt Material können in Bukkit nicht mehr benutzt werden) + # Eine Liste von allen Materialien kann hier gefunden werden: https://hub.spigotmc.org/javadocs/spigot/org/bukkit/Material.html + # color: Farbe des Trankes der aus dem Kessel kommt + # Benutzbare Farben: DARK_RED, RED, BRIGHT_RED, ORANGE, PINK, BLUE, CYAN, WATER, GREEN, BLACK, GREY, BRIGHT_GREY + # Oder RGB Farben (Hex: also zB '99FF33') (Ohne #) (mit '') (Einfach nach "HTML color" im Internet suchen) + # lore: Auflistung von zusätzlichem Text auf dem Trank. (Farbcodes möglich: z.b. &6) + +cauldron: + bsp: + name: Beispiel + ingredients: + - Bedrock/2 + - Diamond + color: BLACK + lore: + - Ein Beispiel für einen Basistrank + - So kommt er aus dem Kessel + +# -- Eine Zutat: -- diff --git a/resources/config/patches/en18.txt b/resources/config/patches/en18.txt new file mode 100644 index 0000000..5e34330 --- /dev/null +++ b/resources/config/patches/en18.txt @@ -0,0 +1,58 @@ + + + +# -- Define custom items -- +# The defined id can then be used in recipes + +# matchAny: true if it is already enough if one of the info matches +# material: Which type the item has to be +# name: Which name the item has to be (Formatting codes possible: such as &6) +# lore: What has to be in the lore of the item + +customItems: + ex-item: + # A Barrier item called Wall and has the given line in its lore +%%%%MAT1%%%% + name: 'Wall' + lore: + - '&7Very well protected' + + ex-item2: + # Using matchAny only one of the following has to match. + # In this case on of the door types, or an item called Beechwood Door, or an item with 'A door' in its lore + matchAny: true +%%%%MAT2%%%% + name: + - 'Beechwood Door' + lore: + - 'A door' + + rasp: + name: '&cRaspberry' + + +# -- Ingredients in the Cauldron -- +# Which Ingredients are accepted by the Cauldron and the base potion resulting from them + + # name: Name of the base potion coming out of the Cauldron (Formatting codes possible: such as &6) + # ingredients: List of 'material/amount' + # With an item in your hand, use /brew ItemName to get its material for use in a recipe + # (Item-ids instead of material are not supported by bukkit anymore and will not work) + # A list of materials can be found here: https://hub.spigotmc.org/javadocs/spigot/org/bukkit/Material.html + # color: Color of the potion from a cauldron. + # Usable Colors: DARK_RED, RED, BRIGHT_RED, ORANGE, PINK, BLUE, CYAN, WATER, GREEN, BLACK, GREY, BRIGHT_GREY + # Or RGB colors (hex: for example '99FF33') (with '') (search for "HTML color" on the internet) + # lore: List of additional text on the base potion. (Formatting codes possible: such as &6) + +cauldron: + ex: + name: Example + ingredients: + - Bedrock/2 + - Diamond + color: BLACK + lore: + - An example for a Base Potion + - This is how it comes out of a Cauldron + + # -- One Ingredient: -- diff --git a/resources/config/patches/fr18.txt b/resources/config/patches/fr18.txt new file mode 100644 index 0000000..f2bda51 --- /dev/null +++ b/resources/config/patches/fr18.txt @@ -0,0 +1,59 @@ + + + +# -- Définir des objets personnalisés -- +# L'id défini peut ensuite être utilisé dans les recettes + +# matchAny: si c'est déjà assez si l'une des infos correspond +# material: le type d'article à utiliser +# name: Quel nom l'article doit porter (codes de formatage possibles : tels que &6) +# lore: Ce qui doit être dans la lore de l'objet + +customItems: + ex-item: + # Un objet Barrière appelé "Wall" et qui a la ligne donnée dans sa lore +%%%%MAT1%%%% + name: 'Wall' + lore: + - '&7Very well protected' + + ex-item2: + # En utilisant matchAny, un seul des éléments suivants doit correspondre. + # Dans ce cas, l'un des types de porte, ou un article appelé "Beechwood Door", ou un objet avec "A door" dans sa lore. + matchAny: true +%%%%MAT2%%%% + name: + - 'Beechwood Door' + lore: + - 'A door' + + rasp: + name: '&cRaspberry' + + +# -- Ingrédients dans le chaudron -- +# Quels sont les ingrédients acceptés par le chaudron et la potion de base qui en résulte + + # name: Nom de la potion de base qui sort du chaudron (codes de formatage possibles : tels que &6) + # ingredients: Liste des 'matériaux/montant' + # Avec un objet en main, utilisez /brew ItemName pour obtenir son matériau pour une recette de cuisine + # (Les id d'objets à la place des matériaux sont obsolètes pour bukkit) + # Une liste des matériaux peuvent-être trouvés ici: https://hub.spigotmc.org/javadocs/spigot/org/bukkit/Material.html + # color : Couleur de la potion provenant d'un chaudron. + # Couleurs disponibles : DARK_RED, RED, BRIGHT_RED, ORANGE, PINK, BLUE, CYAN, WATER, GREEN, BLACK, GREY, BRIGHT_GREY + # (Dans l'ordre : Rouge foncé, Rouge, Rouge clair, Orange, Rose, Bleu, Cyan, Eau, Vert, Noir, Gris, Gris clair) + # Ou couleurs RGB (hex: par exemple '99FF33') (avec '') (recherche de "HTML color" sur internet) + # lore: Liste de texte supplémentaire sur la potion de base. (Formatting codes possible: such as &6) + +cauldron: + ex: + name: Exemple + ingredients: + - Bedrock/2 + - Diamond + color: BLACK + lore: + - Un exemple pour une potion de base + - Voici comment il sort d'un chaudron + + # -- Un ingrédient: -- diff --git a/resources/config/v12/de/config.yml b/resources/config/v12/de/config.yml index 7d2b47d..ab2c9ea 100644 --- a/resources/config/v12/de/config.yml +++ b/resources/config/v12/de/config.yml @@ -80,7 +80,7 @@ autosave: 3 debug: false # Config Version -version: '1.8' +version: '2.0' oldMat: true @@ -88,10 +88,10 @@ oldMat: true # -- Eigene Items Definieren -- # Die festgelegte id kann dann in einem Rezept verwendet werden -# matchAny: true wenn es schon reicht wenn eine der Angaben zutrifft -# material: Welche Art das Item haben muss -# name: Welchen Namen das Item haben muss (Farbcodes möglich: z.b. &6) -# lore: Was in der Lore des Items stehen muss +# matchAny: true wenn es schon reicht wenn eine der Angaben zutrifft +# material: Welche Art das Item haben muss +# name: Welchen Namen das Item haben muss (Farbcodes möglich: z.b. &6) +# lore: Was in der Lore des Items stehen muss customItems: bsp-item: @@ -120,15 +120,15 @@ customItems: # -- Zutaten im Kessel -- # Hier kann angegeben werden welche Zutaten in den Kessel getan werden können und was mit ihnen geschieht. -# name: Name des Basistrankes der aus dem Kessel kommt (Farbcodes möglich: z.b. &6) -# ingredients: Auflistung von 'Material/Anzahl' -# Halte ein Item in der Hand und benutze /brew ItemName um dessen Material herauszufinden und für ein Rezept zu benutzen -# (Item-ids anstatt Material können in Bukkit nicht mehr benutzt werden) -# Eine Liste von allen Materialien kann hier gefunden werden: https://hub.spigotmc.org/javadocs/spigot/org/bukkit/Material.html -# color: Farbe des Trankes der aus dem Kessel kommt -# Benutzbare Farben: DARK_RED, RED, BRIGHT_RED, ORANGE, PINK, BLUE, CYAN, WATER, GREEN, BLACK, GREY, BRIGHT_GREY -# Oder RGB Farben (Hex: also zB '99FF33') (Ohne #) (mit '') (Einfach nach "HTML color" im Internet suchen) -# lore: Auflistung von zusätzlichem Text auf dem Trank. (Farbcodes möglich: z.b. &6) + # name: Name des Basistrankes der aus dem Kessel kommt (Farbcodes möglich: z.b. &6) + # ingredients: Auflistung von 'Material/Anzahl' + # Halte ein Item in der Hand und benutze /brew ItemName um dessen Material herauszufinden und für ein Rezept zu benutzen + # (Item-ids anstatt Material können in Bukkit nicht mehr benutzt werden) + # Eine Liste von allen Materialien kann hier gefunden werden: https://hub.spigotmc.org/javadocs/spigot/org/bukkit/Material.html + # color: Farbe des Trankes der aus dem Kessel kommt + # Benutzbare Farben: DARK_RED, RED, BRIGHT_RED, ORANGE, PINK, BLUE, CYAN, WATER, GREEN, BLACK, GREY, BRIGHT_GREY + # Oder RGB Farben (Hex: also zB '99FF33') (Ohne #) (mit '') (Einfach nach "HTML color" im Internet suchen) + # lore: Auflistung von zusätzlichem Text auf dem Trank. (Farbcodes möglich: z.b. &6) cauldron: @@ -197,8 +197,8 @@ cauldron: # (Item-ids anstatt Material können in Bukkit nicht mehr benutzt werden) # Eine Liste von allen Materialien kann hier gefunden werden: https://hub.spigotmc.org/javadocs/spigot/org/bukkit/Material.html # Es kann ein Data-Wert (durability) angegeben werden, weglassen ignoriert diesen beim hinzufügen einer Zutat -# Wenn Vault installiert ist können normale englische Item Namen verwendet werden, anstatt Material, ID und Data! -# Vault erkennt Namen wie "Jungle Leaves" anstatt "LEAVES,3". Dies macht es viel einfacher! +# Plugin Items mit 'Plugin:Id' (Im Moment ExoticGarden, Slimefun, MMOItems, Brewery) +# Oder ein oben definiertes Custom Item # cookingtime: Zeit in Echtminuten die die Zutaten kochen müssen # distillruns: Wie oft destilliert werden muss für vollen Alkoholgehalt (0=ohne Destillieren) # distilltime: Wie lange (in sekunden) ein Destillations-Durchlauf braucht (0=Standard Zeit von 40 sek) MC Standard wäre 20 sek @@ -229,12 +229,10 @@ recipes: bsp: name: Schlechtes Beispiel/Beispiel/Gutes Beispiel ingredients: - - SUGAR_CANE/5 - DIAMOND/1 - INK_SACK,3/20 - WOOD,1/8 - BEDROCK/1 -# - Jungle Leaves/64 # Nur mit Vault - Brewery:Weißbier/2 # - ExoticGarden:Grape/3 - bsp-item/4 diff --git a/resources/config/v12/en/config.yml b/resources/config/v12/en/config.yml index d16df4b..746130e 100644 --- a/resources/config/v12/en/config.yml +++ b/resources/config/v12/en/config.yml @@ -81,7 +81,7 @@ autosave: 3 debug: false # Config Version -version: '1.8' +version: '2.0' oldMat: true @@ -89,10 +89,10 @@ oldMat: true # -- Define custom items -- # The defined id can then be used in recipes -# matchAny: true if it is already enough if one of the info matches -# material: Which type the item has to be -# name: Which name the item has to be (Formatting codes possible: such as &6) -# lore: What has to be in the lore of the item +# matchAny: true if it is already enough if one of the info matches +# material: Which type the item has to be +# name: Which name the item has to be (Formatting codes possible: such as &6) +# lore: What has to be in the lore of the item customItems: ex-item: @@ -121,15 +121,15 @@ customItems: # -- Ingredients in the Cauldron -- # Which Ingredients are accepted by the Cauldron and the base potion resulting from them -# name: Name of the base potion coming out of the Cauldron (Formatting codes possible: such as &6) -# ingredients: List of 'material/amount' -# With an item in your hand, use /brew ItemName to get its material for use in a recipe -# (Item-ids instead of material are not supported by bukkit anymore and will not work) -# A list of materials can be found here: https://hub.spigotmc.org/javadocs/spigot/org/bukkit/Material.html -# color: Color of the potion from a cauldron. -# Usable Colors: DARK_RED, RED, BRIGHT_RED, ORANGE, PINK, BLUE, CYAN, WATER, GREEN, BLACK, GREY, BRIGHT_GREY -# Or RGB colors (hex: for example '99FF33') (with '') (search for "HTML color" on the internet) -# lore: List of additional text on the base potion. (Formatting codes possible: such as &6) + # name: Name of the base potion coming out of the Cauldron (Formatting codes possible: such as &6) + # ingredients: List of 'material/amount' + # With an item in your hand, use /brew ItemName to get its material for use in a recipe + # (Item-ids instead of material are not supported by bukkit anymore and will not work) + # A list of materials can be found here: https://hub.spigotmc.org/javadocs/spigot/org/bukkit/Material.html + # color: Color of the potion from a cauldron. + # Usable Colors: DARK_RED, RED, BRIGHT_RED, ORANGE, PINK, BLUE, CYAN, WATER, GREEN, BLACK, GREY, BRIGHT_GREY + # Or RGB colors (hex: for example '99FF33') (with '') (search for "HTML color" on the internet) + # lore: List of additional text on the base potion. (Formatting codes possible: such as &6) cauldron: ex: @@ -198,8 +198,8 @@ cauldron: # (Item-ids instead of material are not supported by bukkit anymore and will not work) # A list of materials can be found here: https://hub.spigotmc.org/javadocs/spigot/org/bukkit/Material.html # You can specify a data (durability) value, omitting it will ignore the data value of the added ingredient -# If Vault is installed normal names can be used instead of material or id, so using Vault is highly recommended. -# Vault will recognize things like "Jungle Leaves" instead of "LEAVES,3" +# Plugin items with 'plugin:id' (Currently supporting ExoticGarden, Slimefun, MMOItems, Brewery) +# Or a custom item defined above # cookingtime: Time in real minutes ingredients have to boil # distillruns: How often it has to be distilled for full alcohol (0=without distilling) # distilltime: How long (in seconds) one distill-run takes (0=Default time of 40 sec) MC Default would be 20 sec @@ -236,8 +236,7 @@ recipes: - Brewery:Wheatbeer/2 # - ExoticGarden:Grape/3 - BEDROCK/1 -# - Jungle Leaves/64 # Only with Vault -# - Green Dye/6 # Only with Vault + - ex-item/4 cookingtime: 3 distillruns: 2 distilltime: 60 diff --git a/resources/config/v12/fr/config.yml b/resources/config/v12/fr/config.yml index 5015706..5ff25d1 100644 --- a/resources/config/v12/fr/config.yml +++ b/resources/config/v12/fr/config.yml @@ -82,7 +82,7 @@ autosave: 3 debug: false # Version de configuration -version: '1.8' +version: '2.0' oldMat: true @@ -90,10 +90,10 @@ oldMat: true # -- Définir des objets personnalisés -- # L'id défini peut ensuite être utilisé dans les recettes -# matchAny: si c'est déjà assez si l'une des infos correspond -# material: le type d'article à utiliser -# name: Quel nom l'article doit porter (codes de formatage possibles : tels que &6) -# lore: Ce qui doit être dans la lore de l'objet +# matchAny: si c'est déjà assez si l'une des infos correspond +# material: le type d'article à utiliser +# name: Quel nom l'article doit porter (codes de formatage possibles : tels que &6) +# lore: Ce qui doit être dans la lore de l'objet customItems: ex-item: @@ -122,16 +122,16 @@ customItems: # -- Ingrédients dans le chaudron -- # Quels sont les ingrédients acceptés par le chaudron et la potion de base qui en résulte -# name: Nom de la potion de base qui sort du chaudron (codes de formatage possibles : tels que &6) -# ingredients: Liste des 'matériaux/montant' -# Avec un objet en main, utilisez /brew ItemName pour obtenir son matériau pour une recette de cuisine -# (Les id d'objets à la place des matériaux sont obsolètes pour bukkit) -# Une liste des matériaux peuvent-être trouvés ici: https://hub.spigotmc.org/javadocs/spigot/org/bukkit/Material.html -# color : Couleur de la potion provenant d'un chaudron. -# Couleurs disponibles : DARK_RED, RED, BRIGHT_RED, ORANGE, PINK, BLUE, CYAN, WATER, GREEN, BLACK, GREY, BRIGHT_GREY -# (Dans l'ordre : Rouge foncé, Rouge, Rouge clair, Orange, Rose, Bleu, Cyan, Eau, Vert, Noir, Gris, Gris clair) -# Ou couleurs RGB (hex: par exemple '99FF33') (avec '') (recherche de "HTML color" sur internet) -# lore: Liste de texte supplémentaire sur la potion de base. (Formatting codes possible: such as &6) + # name: Nom de la potion de base qui sort du chaudron (codes de formatage possibles : tels que &6) + # ingredients: Liste des 'matériaux/montant' + # Avec un objet en main, utilisez /brew ItemName pour obtenir son matériau pour une recette de cuisine + # (Les id d'objets à la place des matériaux sont obsolètes pour bukkit) + # Une liste des matériaux peuvent-être trouvés ici: https://hub.spigotmc.org/javadocs/spigot/org/bukkit/Material.html + # color : Couleur de la potion provenant d'un chaudron. + # Couleurs disponibles : DARK_RED, RED, BRIGHT_RED, ORANGE, PINK, BLUE, CYAN, WATER, GREEN, BLACK, GREY, BRIGHT_GREY + # (Dans l'ordre : Rouge foncé, Rouge, Rouge clair, Orange, Rose, Bleu, Cyan, Eau, Vert, Noir, Gris, Gris clair) + # Ou couleurs RGB (hex: par exemple '99FF33') (avec '') (recherche de "HTML color" sur internet) + # lore: Liste de texte supplémentaire sur la potion de base. (Formatting codes possible: such as &6) cauldron: ex: @@ -200,8 +200,6 @@ cauldron: # Ex: 'Sugar_Cane' # Une liste des matériaux peuvent-être trouvés ici: https://hub.spigotmc.org/javadocs/spigot/org/bukkit/Material.html # Vous pouvez spécifier une data (Ex: 5,3 -> Planche de bois de jungle), si vous ne le faites pas la data ne sera pas prise en compte (Ex : 5 -> Bois en général) -# If Vault is installed normal names can be used instead of material or id, so using Vault is highly recommended. -# Vault will recognize things like "Jungle Leaves" instead of "5,3" # Plugin items avec 'plugin:id' (Actuellement supporté ExoticGarden, Slimefun, MMOItems, Brewery) # Ou un élément personnalisé défini ci-dessus # cookingtime: Temps en minutes réelles durant lesquelles les ingrédients devront bouillir @@ -245,8 +243,7 @@ recipes: - Brewery:Wheatbeer/2 # - ExoticGarden:Grape/3 - BEDROCK/1 -# - Jungle Leaves/64 # Only with Vault -# - Green Dye/6 # Only with Vault + - ex-item/4 cookingtime: 3 distillruns: 2 distilltime: 60 diff --git a/resources/config/v12/it/config.yml b/resources/config/v12/it/config.yml index bc84f0a..99bb64b 100644 --- a/resources/config/v12/it/config.yml +++ b/resources/config/v12/it/config.yml @@ -81,7 +81,7 @@ autosave: 3 debug: false # Versione del config -version: '1.8' +version: '2.0' oldMat: true @@ -89,10 +89,10 @@ oldMat: true # -- Define custom items -- # The defined id can then be used in recipes -# matchAny: true if it is already enough if one of the info matches -# material: Which type the item has to be -# name: Which name the item has to be (Formatting codes possible: such as &6) -# lore: What has to be in the lore of the item +# matchAny: true if it is already enough if one of the info matches +# material: Which type the item has to be +# name: Which name the item has to be (Formatting codes possible: such as &6) +# lore: What has to be in the lore of the item customItems: ex-item: @@ -121,15 +121,15 @@ customItems: # -- Ingredients in the Cauldron -- # Which Ingredients are accepted by the Cauldron and the base potion resulting from them -# name: Name of the base potion coming out of the Cauldron (Formatting codes possible: such as &6) -# ingredients: List of 'material/amount' -# With an item in your hand, use /brew ItemName to get its material for use in a recipe -# (Item-ids instead of material are not supported by bukkit anymore and will not work) -# A list of materials can be found here: https://hub.spigotmc.org/javadocs/spigot/org/bukkit/Material.html -# color: Color of the potion from a cauldron. -# Usable Colors: DARK_RED, RED, BRIGHT_RED, ORANGE, PINK, BLUE, CYAN, WATER, GREEN, BLACK, GREY, BRIGHT_GREY -# Or RGB colors (hex: for example '99FF33') (with '') (search for "HTML color" on the internet) -# lore: List of additional text on the base potion. (Formatting codes possible: such as &6) + # name: Name of the base potion coming out of the Cauldron (Formatting codes possible: such as &6) + # ingredients: List of 'material/amount' + # With an item in your hand, use /brew ItemName to get its material for use in a recipe + # (Item-ids instead of material are not supported by bukkit anymore and will not work) + # A list of materials can be found here: https://hub.spigotmc.org/javadocs/spigot/org/bukkit/Material.html + # color: Color of the potion from a cauldron. + # Usable Colors: DARK_RED, RED, BRIGHT_RED, ORANGE, PINK, BLUE, CYAN, WATER, GREEN, BLACK, GREY, BRIGHT_GREY + # Or RGB colors (hex: for example '99FF33') (with '') (search for "HTML color" on the internet) + # lore: List of additional text on the base potion. (Formatting codes possible: such as &6) cauldron: ex: @@ -144,39 +144,39 @@ cauldron: # -- One Ingredient: -- wheat: - name: Fermented wheat + name: Frumento fermentato ingredients: WHEAT sugarcane: - name: Sugar brew + name: Miscela zuccherata ingredients: SUGAR_CANE color: 'f1ffad' # yellowish green apple: - name: Apple cider + name: Sidro di mele ingredients: APPLE potato: - name: Potatomash + name: Purè di patate ingredients: POTATO_ITEM grass: - name: Boiled herbs + name: Erbe bollite ingredients: LONG_GRASS color: '99ff66' # bright green rmushroom: - name: Mushroom brew + name: Miscela ai funghi ingredients: RED_MUSHROOM color: 'ff5c33' # amber red cocoa: - name: Chocolately brew + name: Miscela colorata ingredients: INK_SACK color: '804600' # mocca milk: - name: Milky water + name: Acqua lattea ingredients: MILK_BUCKET color: BRIGHT_GREY @@ -196,8 +196,6 @@ cauldron: # (Gli id invece dei materiali sono "disapprovati" da Bukkit e potrebbero non funzionare in futuro!) # Una lista di materiali può essere trovata qui: https://hub.spigotmc.org/javadocs/spigot/org/bukkit/Material.html # Puoi specificare dei dati dell'oggetto, ma se omesso sarà semplicemente ignorato. -# Se Vault è installato i nomi normali possono essere usati invece del materiale o dell'id quindi l'uso di Vault è fortemente consigliato. -# Vault riconoscerà cose come "Jungle Leaves" invece di "LEAVES,3". # Plugin items with 'plugin:id' (Currently supporting ExoticGarden, Slimefun, MMOItems, Brewery) # Or a custom item defined above # cookingtime: Tempo in minuti richiesto dagli ingredienti per bollire @@ -236,8 +234,7 @@ recipes: - Brewery:Wheatbeer/2 # - ExoticGarden:Grape/3 - BEDROCK/1 -# - Jungle Leaves/64 # Solo con Vault -# - Green Dye/6 # Solo con Vault + - ex-item/4 cookingtime: 3 distillruns: 2 distilltime: 60 diff --git a/resources/config/v13/de/config.yml b/resources/config/v13/de/config.yml index 38a6d9e..7c9c1bb 100644 --- a/resources/config/v13/de/config.yml +++ b/resources/config/v13/de/config.yml @@ -80,17 +80,17 @@ autosave: 3 debug: false # Config Version -version: '1.8' +version: '2.0' # -- Eigene Items Definieren -- # Die festgelegte id kann dann in einem Rezept verwendet werden -# matchAny: true wenn es schon reicht wenn eine der Angaben zutrifft -# material: Welche Art das Item haben muss -# name: Welchen Namen das Item haben muss (Farbcodes möglich: z.b. &6) -# lore: Was in der Lore des Items stehen muss +# matchAny: true wenn es schon reicht wenn eine der Angaben zutrifft +# material: Welche Art das Item haben muss +# name: Welchen Namen das Item haben muss (Farbcodes möglich: z.b. &6) +# lore: Was in der Lore des Items stehen muss customItems: bsp-item: @@ -120,16 +120,15 @@ customItems: # -- Zutaten im Kessel -- # Hier kann angegeben werden welche Zutaten in den Kessel getan werden können und was mit ihnen geschieht. -# name: Name des Basistrankes der aus dem Kessel kommt (Farbcodes möglich: z.b. &6) -# ingredients: Auflistung von 'Material/Anzahl' -# Halte ein Item in der Hand und benutze /brew ItemName um dessen Material herauszufinden und für ein Rezept zu benutzen -# (Item-ids anstatt Material können in Bukkit nicht mehr benutzt werden) -# Eine Liste von allen Materialien kann hier gefunden werden: https://hub.spigotmc.org/javadocs/spigot/org/bukkit/Material.html -# color: Farbe des Trankes der aus dem Kessel kommt -# Benutzbare Farben: DARK_RED, RED, BRIGHT_RED, ORANGE, PINK, BLUE, CYAN, WATER, GREEN, BLACK, GREY, BRIGHT_GREY -# Oder RGB Farben (Hex: also zB '99FF33') (Ohne #) (mit '') (Einfach nach "HTML color" im Internet suchen) -# lore: Auflistung von zusätzlichem Text auf dem Trank. (Farbcodes möglich: z.b. &6) - + # name: Name des Basistrankes der aus dem Kessel kommt (Farbcodes möglich: z.b. &6) + # ingredients: Auflistung von 'Material/Anzahl' + # Halte ein Item in der Hand und benutze /brew ItemName um dessen Material herauszufinden und für ein Rezept zu benutzen + # (Item-ids anstatt Material können in Bukkit nicht mehr benutzt werden) + # Eine Liste von allen Materialien kann hier gefunden werden: https://hub.spigotmc.org/javadocs/spigot/org/bukkit/Material.html + # color: Farbe des Trankes der aus dem Kessel kommt + # Benutzbare Farben: DARK_RED, RED, BRIGHT_RED, ORANGE, PINK, BLUE, CYAN, WATER, GREEN, BLACK, GREY, BRIGHT_GREY + # Oder RGB Farben (Hex: also zB '99FF33') (Ohne #) (mit '') (Einfach nach "HTML color" im Internet suchen) + # lore: Auflistung von zusätzlichem Text auf dem Trank. (Farbcodes möglich: z.b. &6) cauldron: bsp: diff --git a/resources/config/v13/en/config.yml b/resources/config/v13/en/config.yml index 2cef828..92b636b 100644 --- a/resources/config/v13/en/config.yml +++ b/resources/config/v13/en/config.yml @@ -81,17 +81,17 @@ autosave: 3 debug: false # Config Version -version: '1.8' +version: '2.0' # -- Define custom items -- # The defined id can then be used in recipes -# matchAny: true if it is already enough if one of the info matches -# material: Which type the item has to be -# name: Which name the item has to be (Formatting codes possible: such as &6) -# lore: What has to be in the lore of the item +# matchAny: true if it is already enough if one of the info matches +# material: Which type the item has to be +# name: Which name the item has to be (Formatting codes possible: such as &6) +# lore: What has to be in the lore of the item customItems: ex-item: @@ -121,15 +121,15 @@ customItems: # -- Ingredients in the Cauldron -- # Which Ingredients are accepted by the Cauldron and the base potion resulting from them -# name: Name of the base potion coming out of the Cauldron (Formatting codes possible: such as &6) -# ingredients: List of 'material/amount' -# With an item in your hand, use /brew ItemName to get its material for use in a recipe -# (Item-ids instead of material are not supported by bukkit anymore and will not work) -# A list of materials can be found here: https://hub.spigotmc.org/javadocs/spigot/org/bukkit/Material.html -# color: Color of the potion from a cauldron. -# Usable Colors: DARK_RED, RED, BRIGHT_RED, ORANGE, PINK, BLUE, CYAN, WATER, GREEN, BLACK, GREY, BRIGHT_GREY -# Or RGB colors (hex: for example '99FF33') (with '') (search for "HTML color" on the internet) -# lore: List of additional text on the base potion. (Formatting codes possible: such as &6) + # name: Name of the base potion coming out of the Cauldron (Formatting codes possible: such as &6) + # ingredients: List of 'material/amount' + # With an item in your hand, use /brew ItemName to get its material for use in a recipe + # (Item-ids instead of material are not supported by bukkit anymore and will not work) + # A list of materials can be found here: https://hub.spigotmc.org/javadocs/spigot/org/bukkit/Material.html + # color: Color of the potion from a cauldron. + # Usable Colors: DARK_RED, RED, BRIGHT_RED, ORANGE, PINK, BLUE, CYAN, WATER, GREEN, BLACK, GREY, BRIGHT_GREY + # Or RGB colors (hex: for example '99FF33') (with '') (search for "HTML color" on the internet) + # lore: List of additional text on the base potion. (Formatting codes possible: such as &6) cauldron: ex: @@ -365,41 +365,41 @@ recipes: - POISON/10 absinthe: - name: Poor Absinthe/Absinthe/Strong Absinthe - ingredients: - - Grass/15 - cookingtime: 3 - distillruns: 6 - distilltime: 80 - color: GREEN - difficulty: 8 - alcohol: 45 - effects: - - POISON/20-30 + name: Poor Absinthe/Absinthe/Strong Absinthe + ingredients: + - Grass/15 + cookingtime: 3 + distillruns: 6 + distilltime: 80 + color: GREEN + difficulty: 8 + alcohol: 45 + effects: + - POISON/20-30 - potato_soup: - name: Potato soup - ingredients: - - Potato/5 - - Grass/3 - cookingtime: 3 - color: PINK - difficulty: 1 - effects: - - HEAL/0-1 + potato_soup: + name: Potato soup + ingredients: + - Potato/5 + - Grass/3 + cookingtime: 3 + color: PINK + difficulty: 1 + effects: + - HEAL/0-1 - coffee: - name: Stale Coffee/Coffee/Strong Coffee - ingredients: - - Cocoa_Beans/12 - - Milk_Bucket/2 - cookingtime: 2 - color: BLACK - difficulty: 3 - lore: + &8Probably a week old - effects: - - REGENERATION/1/2-5 - - SPEED/1/30-140 + coffee: + name: Stale Coffee/Coffee/Strong Coffee + ingredients: + - Cocoa_Beans/12 + - Milk_Bucket/2 + cookingtime: 2 + color: BLACK + difficulty: 3 + lore: + &8Probably a week old + effects: + - REGENERATION/1/2-5 + - SPEED/1/30-140 # More Recipes ideas: Cachaca, Gin, Whiskey, Tequila, Cider, etc. as well as high quality abbreviations like golden vodka etc. # I will not add more Recipes to the default config, as they would be public and viewable by users to cheat. diff --git a/resources/config/v13/fr/config.yml b/resources/config/v13/fr/config.yml index 6dac476..f622d0b 100644 --- a/resources/config/v13/fr/config.yml +++ b/resources/config/v13/fr/config.yml @@ -82,17 +82,17 @@ autosave: 3 debug: false # Version de configuration -version: '1.8' +version: '2.0' # -- Définir des objets personnalisés -- # L'id défini peut ensuite être utilisé dans les recettes -# matchAny: si c'est déjà assez si l'une des infos correspond -# material: le type d'article à utiliser -# name: Quel nom l'article doit porter (codes de formatage possibles : tels que &6) -# lore: Ce qui doit être dans la lore de l'objet +# matchAny: si c'est déjà assez si l'une des infos correspond +# material: le type d'article à utiliser +# name: Quel nom l'article doit porter (codes de formatage possibles : tels que &6) +# lore: Ce qui doit être dans la lore de l'objet customItems: ex-item: @@ -122,16 +122,16 @@ customItems: # -- Ingrédients dans le chaudron -- # Quels sont les ingrédients acceptés par le chaudron et la potion de base qui en résulte -# name: Nom de la potion de base qui sort du chaudron (codes de formatage possibles : tels que &6) -# ingredients: Liste des 'matériaux/montant' -# Avec un objet en main, utilisez /brew ItemName pour obtenir son matériau pour une recette de cuisine -# (Les id d'objets à la place des matériaux sont obsolètes pour bukkit) -# Une liste des matériaux peuvent-être trouvés ici: https://hub.spigotmc.org/javadocs/spigot/org/bukkit/Material.html -# color : Couleur de la potion provenant d'un chaudron. -# Couleurs disponibles : DARK_RED, RED, BRIGHT_RED, ORANGE, PINK, BLUE, CYAN, WATER, GREEN, BLACK, GREY, BRIGHT_GREY -# (Dans l'ordre : Rouge foncé, Rouge, Rouge clair, Orange, Rose, Bleu, Cyan, Eau, Vert, Noir, Gris, Gris clair) -# Ou couleurs RGB (hex: par exemple '99FF33') (avec '') (recherche de "HTML color" sur internet) -# lore: Liste de texte supplémentaire sur la potion de base. (Formatting codes possible: such as &6) + # name: Nom de la potion de base qui sort du chaudron (codes de formatage possibles : tels que &6) + # ingredients: Liste des 'matériaux/montant' + # Avec un objet en main, utilisez /brew ItemName pour obtenir son matériau pour une recette de cuisine + # (Les id d'objets à la place des matériaux sont obsolètes pour bukkit) + # Une liste des matériaux peuvent-être trouvés ici: https://hub.spigotmc.org/javadocs/spigot/org/bukkit/Material.html + # color : Couleur de la potion provenant d'un chaudron. + # Couleurs disponibles : DARK_RED, RED, BRIGHT_RED, ORANGE, PINK, BLUE, CYAN, WATER, GREEN, BLACK, GREY, BRIGHT_GREY + # (Dans l'ordre : Rouge foncé, Rouge, Rouge clair, Orange, Rose, Bleu, Cyan, Eau, Vert, Noir, Gris, Gris clair) + # Ou couleurs RGB (hex: par exemple '99FF33') (avec '') (recherche de "HTML color" sur internet) + # lore: Liste de texte supplémentaire sur la potion de base. (Formatting codes possible: such as &6) cauldron: ex: diff --git a/resources/config/v13/it/config.yml b/resources/config/v13/it/config.yml index a32eac1..c94df82 100644 --- a/resources/config/v13/it/config.yml +++ b/resources/config/v13/it/config.yml @@ -81,17 +81,17 @@ autosave: 3 debug: false # Versione del config -version: '1.8' +version: '2.0' # -- Define custom items -- # The defined id can then be used in recipes -# matchAny: true if it is already enough if one of the info matches -# material: Which type the item has to be -# name: Which name the item has to be (Formatting codes possible: such as &6) -# lore: What has to be in the lore of the item +# matchAny: true if it is already enough if one of the info matches +# material: Which type the item has to be +# name: Which name the item has to be (Formatting codes possible: such as &6) +# lore: What has to be in the lore of the item customItems: ex-item: @@ -121,15 +121,15 @@ customItems: # -- Ingredients in the Cauldron -- # Which Ingredients are accepted by the Cauldron and the base potion resulting from them -# name: Name of the base potion coming out of the Cauldron (Formatting codes possible: such as &6) -# ingredients: List of 'material/amount' -# With an item in your hand, use /brew ItemName to get its material for use in a recipe -# (Item-ids instead of material are not supported by bukkit anymore and will not work) -# A list of materials can be found here: https://hub.spigotmc.org/javadocs/spigot/org/bukkit/Material.html -# color: Color of the potion from a cauldron. -# Usable Colors: DARK_RED, RED, BRIGHT_RED, ORANGE, PINK, BLUE, CYAN, WATER, GREEN, BLACK, GREY, BRIGHT_GREY -# Or RGB colors (hex: for example '99FF33') (with '') (search for "HTML color" on the internet) -# lore: List of additional text on the base potion. (Formatting codes possible: such as &6) + # name: Name of the base potion coming out of the Cauldron (Formatting codes possible: such as &6) + # ingredients: List of 'material/amount' + # With an item in your hand, use /brew ItemName to get its material for use in a recipe + # (Item-ids instead of material are not supported by bukkit anymore and will not work) + # A list of materials can be found here: https://hub.spigotmc.org/javadocs/spigot/org/bukkit/Material.html + # color: Color of the potion from a cauldron. + # Usable Colors: DARK_RED, RED, BRIGHT_RED, ORANGE, PINK, BLUE, CYAN, WATER, GREEN, BLACK, GREY, BRIGHT_GREY + # Or RGB colors (hex: for example '99FF33') (with '') (search for "HTML color" on the internet) + # lore: List of additional text on the base potion. (Formatting codes possible: such as &6) cauldron: ex: @@ -144,39 +144,39 @@ cauldron: # -- One Ingredient: -- wheat: - name: Fermented wheat + name: Frumento fermentato ingredients: Wheat sugarcane: - name: Sugar brew + name: Miscela zuccherata ingredients: Sugar_Cane color: 'f1ffad' # yellowish green apple: - name: Apple cider + name: Sidro di mele ingredients: Apple potato: - name: Potatomash + name: Purè di patate ingredients: Potato grass: - name: Boiled herbs + name: Erbe bollite ingredients: Grass color: '99ff66' # bright green rmushroom: - name: Mushroom brew + name: Miscela ai funghi ingredients: Red_Mushroom color: 'ff5c33' # amber red cocoa: - name: Chocolately brew + name: Miscela colorata ingredients: Cocoa_Beans color: '804600' # mocca milk: - name: Milky water + name: Acqua lattea ingredients: Milk_Bucket color: BRIGHT_GREY diff --git a/resources/config/v13/zh/config.yml b/resources/config/v13/zh/config.yml index 8c5d79a..3703208 100644 --- a/resources/config/v13/zh/config.yml +++ b/resources/config/v13/zh/config.yml @@ -83,17 +83,17 @@ autosave: 3 debug: false # 配置文件版本 -version: '1.8' +version: '2.0' # -- Define custom items -- # The defined id can then be used in recipes -# matchAny: true if it is already enough if one of the info matches -# material: Which type the item has to be -# name: Which name the item has to be (Formatting codes possible: such as &6) -# lore: What has to be in the lore of the item +# matchAny: true if it is already enough if one of the info matches +# material: Which type the item has to be +# name: Which name the item has to be (Formatting codes possible: such as &6) +# lore: What has to be in the lore of the item customItems: ex-item: @@ -123,15 +123,15 @@ customItems: # -- Ingredients in the Cauldron -- # Which Ingredients are accepted by the Cauldron and the base potion resulting from them -# name: Name of the base potion coming out of the Cauldron (Formatting codes possible: such as &6) -# ingredients: List of 'material/amount' -# With an item in your hand, use /brew ItemName to get its material for use in a recipe -# (Item-ids instead of material are not supported by bukkit anymore and will not work) -# A list of materials can be found here: https://hub.spigotmc.org/javadocs/spigot/org/bukkit/Material.html -# color: Color of the potion from a cauldron. -# Usable Colors: DARK_RED, RED, BRIGHT_RED, ORANGE, PINK, BLUE, CYAN, WATER, GREEN, BLACK, GREY, BRIGHT_GREY -# Or RGB colors (hex: for example '99FF33') (with '') (search for "HTML color" on the internet) -# lore: List of additional text on the base potion. (Formatting codes possible: such as &6) + # name: Name of the base potion coming out of the Cauldron (Formatting codes possible: such as &6) + # ingredients: List of 'material/amount' + # With an item in your hand, use /brew ItemName to get its material for use in a recipe + # (Item-ids instead of material are not supported by bukkit anymore and will not work) + # A list of materials can be found here: https://hub.spigotmc.org/javadocs/spigot/org/bukkit/Material.html + # color: Color of the potion from a cauldron. + # Usable Colors: DARK_RED, RED, BRIGHT_RED, ORANGE, PINK, BLUE, CYAN, WATER, GREEN, BLACK, GREY, BRIGHT_GREY + # Or RGB colors (hex: for example '99FF33') (with '') (search for "HTML color" on the internet) + # lore: List of additional text on the base potion. (Formatting codes possible: such as &6) cauldron: ex: diff --git a/src/com/dre/brewery/Brew.java b/src/com/dre/brewery/Brew.java index 3620397..4dbacd7 100644 --- a/src/com/dre/brewery/Brew.java +++ b/src/com/dre/brewery/Brew.java @@ -647,7 +647,7 @@ public class Brew implements Cloneable { lore.updateAgeLore(BConfig.colorInBarrels); } if (ageTime > 0.5) { - if (BConfig.colorInBarrels && !unlabeled && currentRecipe != null) { + if (BConfig.colorInBarrels) { lore.updateWoodLore(true); } lore.updateQualityStars(BConfig.colorInBarrels); diff --git a/src/com/dre/brewery/P.java b/src/com/dre/brewery/P.java index 64c882e..26ccc6f 100644 --- a/src/com/dre/brewery/P.java +++ b/src/com/dre/brewery/P.java @@ -13,19 +13,15 @@ import com.dre.brewery.recipe.BRecipe; import com.dre.brewery.utility.BUtil; import com.dre.brewery.utility.LegacyUtil; import org.apache.commons.lang.math.NumberUtils; -import org.bstats.bukkit.Metrics; import org.bukkit.Bukkit; import org.bukkit.ChatColor; import org.bukkit.Material; import org.bukkit.command.CommandSender; +import org.bukkit.command.PluginCommand; import org.bukkit.configuration.file.FileConfiguration; import org.bukkit.event.HandlerList; import org.bukkit.plugin.java.JavaPlugin; -import java.io.File; -import java.util.HashMap; -import java.util.Map; - public class P extends JavaPlugin { public static P p; public static boolean debug; @@ -67,7 +63,6 @@ public class P extends JavaPlugin { //MC 1.13 uses a different NBT API than the newer versions.. // We decide here which to use, the new or the old or none at all - P.debug = true; if (LegacyUtil.initNbt()) { useNBT = true; } @@ -81,11 +76,12 @@ public class P extends JavaPlugin { // load the Config try { FileConfiguration cfg = BConfig.loadConfigFile(); - if (cfg == null || !BConfig.readConfig(cfg)) { + if (cfg == null) { p = null; getServer().getPluginManager().disablePlugin(this); return; } + BConfig.readConfig(cfg); } catch (Exception e) { e.printStackTrace(); p = null; @@ -104,8 +100,11 @@ public class P extends JavaPlugin { inventoryListener = new InventoryListener(); worldListener = new WorldListener(); integrationListener = new IntegrationListener(); - getCommand("Brewery").setExecutor(new CommandListener()); - getCommand("Brewery").setTabCompleter(new TabListener()); + PluginCommand c = getCommand("Brewery"); + if (c != null) { + c.setExecutor(new CommandListener()); + c.setTabCompleter(new TabListener()); + } p.getServer().getPluginManager().registerEvents(blockListener, p); p.getServer().getPluginManager().registerEvents(playerListener, p); @@ -148,25 +147,8 @@ public class P extends JavaPlugin { // save Data to Disk DataSave.save(true); - // delete Data from Ram - Barrel.barrels.clear(); - BCauldron.bcauldrons.clear(); - BRecipe.getConfigRecipes().clear(); - BRecipe.numConfigRecipes = 0; - BCauldronRecipe.acceptedMaterials.clear(); - BCauldronRecipe.acceptedCustom.clear(); - BCauldronRecipe.acceptedSimple.clear(); - BCauldronRecipe.getConfigRecipes().clear(); - BCauldronRecipe.numConfigRecipes = 0; - BConfig.customItems.clear(); - BConfig.hasSlimefun = null; - BConfig.hasMMOItems = null; - BPlayer.clear(); - Brew.legacyPotions.clear(); - Wakeup.wakeups.clear(); - DistortChat.words.clear(); - DistortChat.ignoreText.clear(); - DistortChat.commands = null; + // delete config data, in case this is a reload and to clear up some ram + clearConfigData(); this.log(this.getDescription().getName() + " disabled!"); } @@ -177,11 +159,41 @@ public class P extends JavaPlugin { } FileConfiguration cfg = BConfig.loadConfigFile(); if (cfg == null) { - // Could not read yml file, do not proceed + // Could not read yml file, do not proceed, error was printed return; } // clear all existent config Data + clearConfigData(); + + // load the Config + try { + BConfig.readConfig(cfg); + } catch (Exception e) { + e.printStackTrace(); + p = null; + getServer().getPluginManager().disablePlugin(this); + return; + } + + // Reload Recipes + boolean successful = true; + for (Brew brew : Brew.legacyPotions.values()) { + if (!brew.reloadRecipe()) { + successful = false; + } + } + if (sender != null) { + if (!successful) { + msg(sender, p.languageReader.get("Error_Recipeload")); + } else { + p.msg(sender, p.languageReader.get("CMD_Reload")); + } + } + BConfig.reloader = null; + } + + private void clearConfigData() { BRecipe.getConfigRecipes().clear(); BRecipe.numConfigRecipes = 0; BCauldronRecipe.acceptedMaterials.clear(); @@ -201,34 +213,6 @@ public class P extends JavaPlugin { e.printStackTrace(); } } - - // load the Config - try { - if (!BConfig.readConfig(cfg)) { - p = null; - getServer().getPluginManager().disablePlugin(this); - return; - } - } catch (Exception e) { - e.printStackTrace(); - p = null; - getServer().getPluginManager().disablePlugin(this); - return; - } - - // Reload Recipes - boolean successful = true; - for (Brew brew : Brew.legacyPotions.values()) { - if (!brew.reloadRecipe()) { - successful = false; - } - } - if (!successful && sender != null) { - msg(sender, p.languageReader.get("Error_Recipeload")); - } else { - p.msg(sender, p.languageReader.get("CMD_Reload")); - } - BConfig.reloader = null; } public static P getInstance() { diff --git a/src/com/dre/brewery/api/events/ConfigLoadEvent.java b/src/com/dre/brewery/api/events/ConfigLoadEvent.java index 3c4e615..e4ea2af 100644 --- a/src/com/dre/brewery/api/events/ConfigLoadEvent.java +++ b/src/com/dre/brewery/api/events/ConfigLoadEvent.java @@ -9,6 +9,7 @@ import org.jetbrains.annotations.NotNull; /** * The Brewery Config was reloaded. + *

The Recipes added by a Plugin to the Added Recipes will not be reloaded and stay where they are. */ public class ConfigLoadEvent extends Event { private static final HandlerList handlers = new HandlerList(); diff --git a/src/com/dre/brewery/filedata/BConfig.java b/src/com/dre/brewery/filedata/BConfig.java index 7a9dc9f..5588440 100644 --- a/src/com/dre/brewery/filedata/BConfig.java +++ b/src/com/dre/brewery/filedata/BConfig.java @@ -36,7 +36,7 @@ import java.util.Map; public class BConfig { - public static final String configVersion = "1.8"; + public static final String configVersion = "2.0"; public static boolean updateCheck; public static CommandSender reloader; @@ -146,7 +146,7 @@ public class BConfig { return null; } - public static boolean readConfig(FileConfiguration config) { + public static void readConfig(FileConfiguration config) { // Set the Language p.language = config.getString("language", "en"); @@ -162,7 +162,7 @@ public class BConfig { if (!version.equals(configVersion) || (oldMat && P.use1_13)) { File file = new File(P.p.getDataFolder(), "config.yml"); copyDefaultConfigs(true); - new ConfigUpdater(file).update(version, oldMat, p.language); + new ConfigUpdater(file).update(version, oldMat, p.language, config); P.p.log("Config Updated to version: " + configVersion); config = YamlConfiguration.loadConfiguration(file); } @@ -326,6 +326,6 @@ public class BConfig { ConfigLoadEvent event = new ConfigLoadEvent(); P.p.getServer().getPluginManager().callEvent(event); - return true; + } } diff --git a/src/com/dre/brewery/filedata/ConfigUpdater.java b/src/com/dre/brewery/filedata/ConfigUpdater.java index b03e232..2e955fd 100644 --- a/src/com/dre/brewery/filedata/ConfigUpdater.java +++ b/src/com/dre/brewery/filedata/ConfigUpdater.java @@ -1,17 +1,16 @@ package com.dre.brewery.filedata; -import com.dre.brewery.utility.LegacyUtil; import com.dre.brewery.P; +import com.dre.brewery.utility.LegacyUtil; import org.bukkit.Material; +import org.bukkit.configuration.ConfigurationSection; +import org.bukkit.configuration.file.FileConfiguration; -import java.io.BufferedReader; -import java.io.BufferedWriter; -import java.io.File; -import java.io.FileReader; -import java.io.FileWriter; -import java.io.IOException; +import java.io.*; import java.util.ArrayList; import java.util.Arrays; +import java.util.List; +import java.util.Objects; public class ConfigUpdater { @@ -49,6 +48,25 @@ public class ConfigUpdater { config.addAll(index, Arrays.asList(newLines)); } + public void removeLine(int index) { + config.remove(index); + } + + public void addLinesAt(String[] search, int offset, String... newLines) { + int index = indexOfStart(search[0]); + int s = 1; + while (index == -1 && s < search.length) { + index = indexOfStart(search[s]); + s++; + } + + if (index != -1) { + addLines(index + offset, newLines); + } else { + appendLines(newLines); + } + } + public void saveConfig() { StringBuilder stringBuilder = new StringBuilder(); for (String line : config) { @@ -110,7 +128,7 @@ public class ConfigUpdater { // ---- Updating to newer Versions ---- // Update from a specified Config version and language to the newest version - public void update(String fromVersion, boolean oldMat, String lang) { + public void update(String fromVersion, boolean oldMat, String lang, FileConfiguration yml) { if (fromVersion.equals("0.5")) { // Version 0.5 was only released for de, but with en as setting, so default to de if (!lang.equals("de")) { @@ -187,12 +205,24 @@ public class ConfigUpdater { fromVersion = "1.8"; } + if (fromVersion.equals("1.8")) { + if (de) { + update18de(yml); + } else if (lang.equals("fr")) { + update18fr(yml); + } else { + update18en(yml); + } + updateVersion(BConfig.configVersion); + fromVersion = BConfig.configVersion; + } + if (P.use1_13 && oldMat) { updateMaterials(true); updateMaterialDescriptions(de); } - if (!fromVersion.equals("1.8")) { + if (!fromVersion.equals(BConfig.configVersion)) { P.p.log(P.p.languageReader.get("Error_ConfigUpdate", fromVersion)); return; } @@ -551,12 +581,12 @@ public class ConfigUpdater { if (index != -1) { index = indexOfStart("# (WEAKNESS, INCREASE_DAMAGE, SLOW und SPEED sind immer verborgen.) Mögliche Effekte:"); if (index != -1) { - config.remove(index); + removeLine(index); } } index = indexOfStart("# Bei Effekten mit sofortiger Wirkung "); if (index != -1) { - config.remove(index); + removeLine(index); } } @@ -650,12 +680,12 @@ public class ConfigUpdater { if (index != -1) { index = indexOfStart("# (WEAKNESS, INCREASE_DAMAGE, SLOW and SPEED are always hidden.) Possible Effects:"); if (index != -1) { - config.remove(index); + removeLine(index); } } index = indexOfStart("# instant effects "); if (index != -1) { - config.remove(index); + removeLine(index); } } @@ -718,7 +748,7 @@ public class ConfigUpdater { int index = indexOfStart("# SamplePlugin = installiertes home plugin. Unterstützt: ManagerXL."); if (index != -1) { - config.remove(index); + removeLine(index); } index = indexOfStart("# Ob der Spieler nach etwas kürzerem Ausloggen an einem zufälligen Ort \"aufwacht\" (diese müssen durch '/br Wakeup add"); @@ -840,7 +870,7 @@ public class ConfigUpdater { int index = indexOfStart("# SamplePlugin = installed home plugin. Supports: ManagerXL."); if (index != -1) { - config.remove(index); + removeLine(index); } index = indexOfStart("# If the player \"wakes up\" at a random place when offline for some time while drinking (the places have to be defined with '/br Wakeup add'"); @@ -1246,13 +1276,354 @@ public class ConfigUpdater { if (P.use1_13) updateMaterialDescriptions(false); } + private void update18de(FileConfiguration yml) { + int index = indexOfStart("# Löschen einzelner Einstellungen"); + if (index != -1) { + removeLine(index); + } + + addLinesAt(new String[] {"colorInBrewer:", "colorInBarrels:", "hangoverDays:", "language:"}, 1, "", + "# Ob in den Iteminformationen immer 1-5 Sterne für die Qualität angezeigt werden sollen, oder nur beim brauen [true]", + "alwaysShowQuality: true", + "", + "# Ob in den Iteminformationen immer der Alkoholgehalt angezeigt weden soll, oder nur im Braustand [false]", + "alwaysShowAlc: false"); + + addLinesAt(new String[] {"maxBrewsInMCBarrels:", "openLargeBarrelEverywhere:", "language:"}, 1, "", + "# Benutzte Zutaten und andere Brau-Daten werden in allen Brewery Tränken gespeichert. Um zu verhindern,", + "# dass gehackte clients diese Daten auslesen um Rezepte herauszufinden, können diese encodiert werden.", + "# Einziger Nachteil: Tränke können nur auf Servern mit dem gleichen encodeKey benutzt werden.", + "# Dies kann also aktiviert werden um Rezept-cheating schwerer zu machen, aber keine Tränke per World Download, Schematic, o.ä. geteilt werden. [false]", + "enableEncode: false", + "encodeKey: 0"); + + addLinesAt(new String[] {"autosave:", "version:"}, 1, "", + "# Debug Nachrichten im Log anzeigen [false]", + "debug: false"); + + index = indexOfStart("oldMat:") + 1; + if (index == 0) { + index = indexOfStart("version:") + 1; + if (index == 0) { + index = 2; + } + } + // Custom Items and start of cauldron section + applyPatch("config/patches/de18.txt", index); + + index = indexOfStart("%%%%MAT1%%%%"); + if (index != -1) { + if (P.use1_13) { + setLine(index, " material: Barrier"); + } else { + setLine(index, " material: BEDROCK"); + } + } + index = indexOfStart("%%%%MAT2%%%%"); + if (index != -1) { + removeLine(index); + if (P.use1_13) { + addLines(index, " material:", + " - Acacia_Door", + " - Oak_Door", + " - Spruce_Door"); + } else { + addLines(index, " material:", + " - WOODEN_DOOR", + " - IRON_DOOR"); + } + } + + index = indexOfStart("# -- Eine Zutat:"); + if (index == -1) { + index = indexOfStart("cauldron:"); + if (index == -1) { + // Patch failed + index = indexOfStart("version:"); + if (index == -1) { + index = 0; + } + addLines(index + 1, "cauldron:"); + index ++; + } + } + convertCookedSection(yml, index + 1); + + addLinesAt(new String[]{"# Eine Liste von allen Materialien", "# ingredients:"}, 1, + "# Plugin Items mit 'Plugin:Id' (Im Moment ExoticGarden, Slimefun, MMOItems, Brewery)", + "# Oder ein oben definiertes Custom Item"); + + addLinesAt(new String[]{"# alcohol:", "# difficulty:", "# ingredients:", "# -- Rezepte"}, 1, + "# lore: Auflistung von zusätzlichem Text auf dem fertigen Trank. (Farbcodes möglich: z.b. &6)", + "# Lore nur für bestimmte Qualität möglich mit + Schlecht, ++ Mittel, +++ Gut, vorne anhängen.", + "# servercommands: Liste von Befehlen ausgeführt vom Server wenn der Trank getrunken wird", + "# playercommands: Liste von Befehlen ausgeführt vom Spieler wenn der Trank getrunken wird", + "# drinkmessage: Nachricht im Chat beim trinken des Trankes", + "# drinktitle: Nachricht als Titel auf dem Bildschirm an den Spieler beim trinken des Trankes"); + + addLinesAt(new String[]{"useGriefPrevention:", "useWorldGuard:", "# -- Plugin Kompatiblit"}, 1, "useGMInventories: true"); + + index = indexOfStart("# cooked:"); + if (index != -1) { + removeLine(index); + } + index = indexOfStart("# [Beispiel] MATERIAL:"); + if (index != -1) { + removeLine(index); + } + + } + + private void update18fr(FileConfiguration yml) { + int index = indexOfStart("# Supprimer un para"); + if (index != -1) { + removeLine(index); + } + + addLinesAt(new String[] {"colorInBrewer:", "colorInBarrels:", "hangoverDays:", "language:"}, 1, "\n" + + "# Toujours montrer les 1-5 étoiles sur les objets en fonction de leur qualité. S'ils sont faux, ils n'apparaîtront que lors de l'infusion. [true]", + "alwaysShowQuality: true", + "", + "# Toujours indiquer la teneur en alcool sur les objets. S'il est false, il n'apparaîtra que dans le stand de brassage. [false]", + "alwaysShowAlc: false"); + + addLinesAt(new String[] {"maxBrewsInMCBarrels:", "openLargeBarrelEverywhere:", "language:"}, 1, "", + "# Les ingrédients et autres données de brassage utilisés sont sauvegardés dans tous les articles de brasserie. [false]", + "# Pour empêcher les clients piratés de lire exactement ce qui a été utilisé pour infuser un élément, les données peuvent être encodées/brouillées.", + "# Il s'agit d'un processus rapide pour empêcher les joueurs de pirater des recettes, une fois qu'ils mettent la main sur une bière.", + "# Seul inconvénient: Les boissons brassicoles ne peuvent être utilisés que sur un autre serveur avec la même clé de chiffrement.", + "# Activez cette option si vous voulez rendre la tricherie des recettes plus difficile, mais ne partagez pas les infusions par téléchargement mondial, schémas ou autres moyens.", + "enableEncode: false", + "encodeKey: 0"); + + addLinesAt(new String[] {"autosave:", "version:"}, 1, "", + "# Show debug messages in log [false]", + "debug: false"); + + index = indexOfStart("oldMat:") + 1; + if (index == 0) { + index = indexOfStart("version:") + 1; + if (index == 0) { + index = 2; + } + } + // Custom Items and start of cauldron section + applyPatch("config/patches/fr18.txt", index); + + index = indexOfStart("%%%%MAT1%%%%"); + if (index != -1) { + if (P.use1_13) { + setLine(index, " material: Barrier"); + } else { + setLine(index, " material: BEDROCK"); + } + } + index = indexOfStart("%%%%MAT2%%%%"); + if (index != -1) { + removeLine(index); + if (P.use1_13) { + addLines(index, " material:", + " - Acacia_Door", + " - Oak_Door", + " - Spruce_Door"); + } else { + addLines(index, " material:", + " - WOODEN_DOOR", + " - IRON_DOOR"); + } + } + + index = indexOfStart(" # -- Un ingr"); + if (index == -1) { + index = indexOfStart("cauldron:"); + if (index == -1) { + // Patch failed + index = indexOfStart("version:"); + if (index == -1) { + index = 0; + } + addLines(index + 1, "cauldron:"); + index ++; + } + } + convertCookedSection(yml, index + 1); + + addLinesAt(new String[]{"# Une liste des mat", "# ingredients:"}, 1, + "# Plugin items avec 'plugin:id' (Actuellement supporté ExoticGarden, Slimefun, MMOItems, Brewery)", + "# Ou un élément personnalisé défini ci-dessus"); + + addLinesAt(new String[]{"# alcohol:", "# difficulty:", "# ingredients:", "# -- Recette "}, 1, + "# lore: Liste des textes supplémentaires sur le breuvage fini. (Codes de formatage possibles : tels que &6)", + "# Texte spécifique de qualité possible, en utilisant + mauvais, ++ normal, +++ bon, ajouté à l'avant de la ligne.", + "# servercommands: Liste des commandes exécutées par le serveur lors de la consommation de la potion", + "# playercommands: Liste des commandes exécutées par le joueur lors de la consommation de la potion", + "# drinkmessage: Chat-message au joueur lorsqu'il boit la potion", + "# drinktitle: Titre à l'écran du joueur lorsqu'il boit la potion"); + + addLinesAt(new String[]{"useGriefPrevention:", "useWorldGuard:", "# -- Plugin Compatibility"}, 1, "useGMInventories: true"); + + index = indexOfStart("# cooked:"); + if (index != -1) { + removeLine(index); + } + index = indexOfStart("# [Exemple] MATERIEL"); + if (index != -1) { + removeLine(index); + } + + } + + private void update18en(FileConfiguration yml) { + int index = indexOfStart("# Deleting of single settings"); + if (index != -1) { + removeLine(index); + } + + addLinesAt(new String[] {"colorInBrewer:", "colorInBarrels:", "hangoverDays:", "language:"}, 1, "", + "# Always show the 1-5 stars on the item depending on the quality. If false, they will only appear when brewing [true]", + "alwaysShowQuality: true", + "", + "# Always show the alcohol content on the item. If false, it will only show in the brewing stand [false]", + "alwaysShowAlc: false"); + + addLinesAt(new String[] {"maxBrewsInMCBarrels:", "openLargeBarrelEverywhere:", "language:"}, 1, "", + "# The used Ingredients and other brewing-data is saved to all Brewery Items. To prevent", + "# hacked clients from reading what exactly was used to brew an item, the data can be encoded/scrambled.", + "# This is a fast process to stop players from hacking out recipes, once they get hold of a brew.", + "# Only drawback: brew items can only be used on another server with the same encodeKey.", + "# So enable this if you want to make recipe cheating harder, but don't share any brews by world download, schematics, or other means. [false]", + "enableEncode: false", + "encodeKey: 0"); + + addLinesAt(new String[] {"autosave:", "version:"}, 1, "", + "# Show debug messages in log [false]", + "debug: false"); + + index = indexOfStart("oldMat:") + 1; + if (index == 0) { + index = indexOfStart("version:") + 1; + if (index == 0) { + index = 2; + } + } + // Custom Items and start of cauldron section + applyPatch("config/patches/en18.txt", index); + + index = indexOfStart("%%%%MAT1%%%%"); + if (index != -1) { + if (P.use1_13) { + setLine(index, " material: Barrier"); + } else { + setLine(index, " material: BEDROCK"); + } + } + index = indexOfStart("%%%%MAT2%%%%"); + if (index != -1) { + removeLine(index); + if (P.use1_13) { + addLines(index, " material:", + " - Acacia_Door", + " - Oak_Door", + " - Spruce_Door"); + } else { + addLines(index, " material:", + " - WOODEN_DOOR", + " - IRON_DOOR"); + } + } + + index = indexOfStart(" # -- One Ingredient"); + if (index == -1) { + index = indexOfStart("cauldron:"); + if (index == -1) { + // Patch failed + index = indexOfStart("version:"); + if (index == -1) { + index = 0; + } + addLines(index + 1, "cauldron:"); + index ++; + } + } + convertCookedSection(yml, index + 1); + + addLinesAt(new String[]{"# A list of materials", "# ingredients:"}, 1, + "# Plugin items with 'plugin:id' (Currently supporting ExoticGarden, Slimefun, MMOItems, Brewery)", + "# Or a custom item defined above"); + + addLinesAt(new String[]{"# alcohol:", "# difficulty:", "# ingredients:", "# -- Recipes"}, 1, + "# lore: List of additional text on the finished brew. (Formatting codes possible: such as &6)", + "# Specific lore for quality possible, using + bad, ++ normal, +++ good, added to the front of the line.", + "# servercommands: List of Commands executed by the Server when drinking the brew", + "# playercommands: List of Commands executed by the Player when drinking the brew", + "# drinkmessage: Chat-message to the Player when drinking the Brew", + "# drinktitle: Title on Screen to the Player when drinking the Brew"); + + addLinesAt(new String[]{"useGriefPrevention:", "useWorldGuard:", "# -- Plugin Compatibility"}, 1, "useGMInventories: true"); + + index = indexOfStart("# cooked:"); + if (index != -1) { + removeLine(index); + } + index = indexOfStart("# [Example] MATERIAL:"); + if (index != -1) { + removeLine(index); + } + + } + + + + private void convertCookedSection(FileConfiguration yml, int toLine) { + ConfigurationSection cookedSection = yml.getConfigurationSection("cooked"); + if (cookedSection != null) { + for (String ing : cookedSection.getKeys(false)) { + String name = cookedSection.getString(ing); + addLines(toLine, + " " + ing.toLowerCase() + ":", + " name: " + name, + " ingredients:", + " - " + ing, + ""); + toLine += 5; + } + + int index = indexOfStart("cooked:"); + if (index != -1) { + int size = cookedSection.getKeys(false).size(); + while (size >= 0) { + removeLine(index); + size--; + } + } + } + + + } + + public void applyPatch(String resourcePath, int toLine) { + try { + List patch = new ArrayList<>(); + BufferedReader reader = new BufferedReader(new InputStreamReader(Objects.requireNonNull(P.p.getResource(resourcePath), "Resource not found"))); + String currentLine; + while((currentLine = reader.readLine()) != null) { + patch.add(currentLine); + } + reader.close(); + config.addAll(toLine, patch); + } catch (IOException | NullPointerException e) { + P.p.errorLog("Could not apply Patch: " + resourcePath); + e.printStackTrace(); + } + } + // Update all Materials to Minecraft 1.13 private void updateMaterials(boolean toMC113) { int index; if (toMC113) { index = indexOfStart("oldMat:"); if (index != -1) { - config.remove(index); + removeLine(index); } } else { index = indexOfStart("version:"); @@ -1311,6 +1682,29 @@ public class ConfigUpdater { index++; } } + + index = indexOfStart("cauldron:"); + if (index != -1) { + index++; + int endIndex = indexOfStart("recipes:"); + if (endIndex < index) { + endIndex = indexOfStart(" cookingtime:"); + } + if (endIndex < index) { + endIndex = indexOfStart("useWorldGuard:"); + } + while (index < endIndex) { + if (config.get(index).matches("^\\s+ingredients:.*")) { + index++; + while (config.get(index).matches("^\\s+- .+")) { + line = config.get(index); + setLine(index, convertMaterial(line, "^\\s+- ", "(,.*|)/.*", toMC113)); + index++; + } + } + index++; + } + } } private String convertMaterial(String line, String regexPrefix, String regexPostfix, boolean toMC113) { @@ -1362,33 +1756,33 @@ public class ConfigUpdater { index = indexOfStart("# Es kann ein Data-Wert (durability) angegeben werden"); if (index != -1) { - config.remove(index); + removeLine(index); } index = indexOfStart("# Wenn Vault installiert ist"); if (index != -1) { - config.remove(index); + removeLine(index); } index = indexOfStart("# Vault erkennt Namen wie"); if (index != -1) { - config.remove(index); + removeLine(index); } index = indexOfStart("# - Jungle Leaves/64 # Nur mit Vault"); if (index != -1) { - config.remove(index); + removeLine(index); } index = indexOfStart("# - Green Dye/6 # Nur mit Vault"); if (index != -1) { - config.remove(index); + removeLine(index); } index = indexOfStart("# Ein 'X' an den Namen"); if (index != -1) { - config.remove(index); + removeLine(index); } index = indexOfStart("# Effekte sind ab der 1.9 immer verborgen"); if (index != -1) { - config.remove(index); + removeLine(index); } } else { index = indexOfStart("# ingredients: List of 'material,data/amount'"); @@ -1398,33 +1792,33 @@ public class ConfigUpdater { index = indexOfStart("# You can specify a data (durability) value"); if (index != -1) { - config.remove(index); + removeLine(index); } index = indexOfStart("# If Vault is installed normal names can be used"); if (index != -1) { - config.remove(index); + removeLine(index); } index = indexOfStart("# Vault will recognize things"); if (index != -1) { - config.remove(index); + removeLine(index); } index = indexOfStart("# - Jungle Leaves/64 # Only with Vault"); if (index != -1) { - config.remove(index); + removeLine(index); } index = indexOfStart("# - Green Dye/6 # Only with Vault"); if (index != -1) { - config.remove(index); + removeLine(index); } index = indexOfStart("# Suffix name with 'X' to hide effect"); if (index != -1) { - config.remove(index); + removeLine(index); } index = indexOfStart("# Effects are always hidden in 1.9 and newer"); if (index != -1) { - config.remove(index); + removeLine(index); } } } diff --git a/src/com/dre/brewery/lore/BrewLore.java b/src/com/dre/brewery/lore/BrewLore.java index 163fce2..c81fa94 100644 --- a/src/com/dre/brewery/lore/BrewLore.java +++ b/src/com/dre/brewery/lore/BrewLore.java @@ -147,7 +147,7 @@ public class BrewLore { if (brew.getDistillRuns() <= 0) return; String prefix; byte distillRuns = brew.getDistillRuns(); - if (qualityColor && brew.hasRecipe()) { + if (qualityColor && !brew.isUnlabeled() && brew.hasRecipe()) { prefix = getQualityColor(brew.getIngredients().getDistillQuality(brew.getCurrentRecipe(), distillRuns)); } else { prefix = "§7"; @@ -168,7 +168,7 @@ public class BrewLore { public void updateAgeLore(boolean qualityColor) { String prefix; float age = brew.getAgeTime(); - if (qualityColor && brew.hasRecipe()) { + if (qualityColor && !brew.isUnlabeled() && brew.hasRecipe()) { prefix = getQualityColor(brew.getIngredients().getAgeQuality(brew.getCurrentRecipe(), age)); } else { prefix = "§7"; @@ -191,7 +191,7 @@ public class BrewLore { * @param qualityColor If the lore should have colors according to quality */ public void updateWoodLore(boolean qualityColor) { - if (qualityColor && brew.hasRecipe()) { + if (qualityColor && brew.hasRecipe() && !brew.isUnlabeled()) { int quality = brew.getIngredients().getWoodQuality(brew.getCurrentRecipe(), brew.getWood()); addOrReplaceLore(Type.WOOD, getQualityColor(quality), P.p.languageReader.get("Brew_Woodtype")); } else { @@ -260,15 +260,16 @@ public class BrewLore { } updateCustomLore(); + if (toQuality && brew.isUnlabeled()) { + return; + } updateQualityStars(toQuality); - if (!brew.isUnlabeled()) { - // Ingredients - updateIngredientLore(toQuality); + // Ingredients + updateIngredientLore(toQuality); - // Cooking - updateCookLore(toQuality); - } + // Cooking + updateCookLore(toQuality); // Distilling updateDistillLore(toQuality); @@ -279,10 +280,8 @@ public class BrewLore { } // WoodType - if (!brew.isUnlabeled()) { - if (brew.getAgeTime() > 0.5) { - updateWoodLore(toQuality); - } + if (brew.getAgeTime() > 0.5) { + updateWoodLore(toQuality); } updateAlc(false); diff --git a/src/com/dre/brewery/utility/LegacyUtil.java b/src/com/dre/brewery/utility/LegacyUtil.java index 13f039e..33a09f1 100644 --- a/src/com/dre/brewery/utility/LegacyUtil.java +++ b/src/com/dre/brewery/utility/LegacyUtil.java @@ -261,17 +261,17 @@ public class LegacyUtil { try { Class.forName("org.bukkit.persistence.PersistentDataContainer"); NewNbtVer = true; - P.p.debugLog("Using the NEW nbt api"); + P.p.log("Using the NEW nbt api"); return true; } catch (ClassNotFoundException e) { try { Class.forName("org.bukkit.inventory.meta.tags.CustomItemTagContainer"); NewNbtVer = false; - P.p.debugLog("Using the OLD nbt api"); + P.p.log("Using the OLD nbt api"); return true; } catch (ClassNotFoundException ex) { NewNbtVer = false; - P.p.debugLog("No nbt api found, using Lore Save System"); + P.p.log("No nbt api found, using Lore Save System"); return false; } } From 55200608c13ac6d99ed35b779f187832cf1126c7 Mon Sep 17 00:00:00 2001 From: Sn0wStorm Date: Mon, 2 Dec 2019 15:56:30 +0100 Subject: [PATCH 50/51] Language Updater: Put new lines at the end --- pom.xml | 4 ++-- resources/plugin.yml | 2 +- src/com/dre/brewery/Barrel.java | 2 +- src/com/dre/brewery/Brew.java | 4 +++- src/com/dre/brewery/P.java | 8 +++++-- .../dre/brewery/filedata/ConfigUpdater.java | 24 ++++++++++++------- .../dre/brewery/filedata/LanguageReader.java | 11 ++++----- 7 files changed, 33 insertions(+), 22 deletions(-) diff --git a/pom.xml b/pom.xml index fd2ea62..3e214a7 100644 --- a/pom.xml +++ b/pom.xml @@ -3,8 +3,8 @@ 4.0.0 com.dre - brewery - 1.8.2 + Brewery + 1.8.3 Brewery diff --git a/resources/plugin.yml b/resources/plugin.yml index 116b6a4..312b86c 100644 --- a/resources/plugin.yml +++ b/resources/plugin.yml @@ -1,5 +1,5 @@ name: Brewery -version: 1.8.2 +version: 1.8.3 main: com.dre.brewery.P softdepend: [LWC, LogBlock, WorldGuard, GriefPrevention, Vault, Citadel] authors: [Milan Albrecht, Frank Baumann, ProgrammerDan, Daniel Saukel] diff --git a/src/com/dre/brewery/Barrel.java b/src/com/dre/brewery/Barrel.java index caf3314..e94a680 100644 --- a/src/com/dre/brewery/Barrel.java +++ b/src/com/dre/brewery/Barrel.java @@ -37,7 +37,7 @@ import java.util.Map; public class Barrel implements InventoryHolder { public static List barrels = new ArrayList<>(); - private static int check = 0; + private static int check = 0; // Which Barrel was last checked private final Block spigot; private final BarrelBody body; // The Blocks that make up a Barrel in the World diff --git a/src/com/dre/brewery/Brew.java b/src/com/dre/brewery/Brew.java index 4dbacd7..429d9dc 100644 --- a/src/com/dre/brewery/Brew.java +++ b/src/com/dre/brewery/Brew.java @@ -137,7 +137,6 @@ public class Brew implements Cloneable { item.setItemMeta(meta); } else if (brew != null && brew.needsSave) { // Brew needs saving from a previous format - P.p.debugLog("Brew needs saving from previous format"); if (P.useNBT) { new BrewLore(brew, (PotionMeta) meta).removeLoreData(); P.p.debugLog("removed Data from Lore"); @@ -823,13 +822,16 @@ public class Brew implements Cloneable { XORUnscrambleStream.SuccessType successType = unscrambler.getSuccessType(); if (successType == XORUnscrambleStream.SuccessType.PREV_SEED) { + P.p.debugLog("Converting Brew from previous Seed"); brew.setNeedsSave(true); } else if (BConfig.enableEncode != (successType == XORUnscrambleStream.SuccessType.MAIN_SEED)) { // We have either enabled encode and the data was not encoded or the other way round + P.p.debugLog("Converting Brew to new encode setting"); brew.setNeedsSave(true); } else if (P.useNBT && itemLoadStream instanceof Base91DecoderStream) { // We are on a version that supports nbt but the data is still in the lore of the item // Just save it again so that it gets saved to nbt + P.p.debugLog("Converting Brew to NBT"); brew.setNeedsSave(true); } return brew; diff --git a/src/com/dre/brewery/P.java b/src/com/dre/brewery/P.java index 26ccc6f..e3020f5 100644 --- a/src/com/dre/brewery/P.java +++ b/src/com/dre/brewery/P.java @@ -13,6 +13,7 @@ import com.dre.brewery.recipe.BRecipe; import com.dre.brewery.utility.BUtil; import com.dre.brewery.utility.LegacyUtil; import org.apache.commons.lang.math.NumberUtils; +import org.bstats.bukkit.Metrics; import org.bukkit.Bukkit; import org.bukkit.ChatColor; import org.bukkit.Material; @@ -22,6 +23,9 @@ import org.bukkit.configuration.file.FileConfiguration; import org.bukkit.event.HandlerList; import org.bukkit.plugin.java.JavaPlugin; +import java.util.HashMap; +import java.util.Map; + public class P extends JavaPlugin { public static P p; public static boolean debug; @@ -220,7 +224,7 @@ public class P extends JavaPlugin { } private void setupMetrics() { - /*try { + try { Metrics metrics = new Metrics(this); metrics.addCustomChart(new Metrics.SingleLineChart("drunk_players", BPlayer::numDrunkPlayers)); metrics.addCustomChart(new Metrics.SingleLineChart("brews_in_existence", () -> brewsCreated)); @@ -321,7 +325,7 @@ public class P extends JavaPlugin { })); } catch (Throwable e) { e.printStackTrace(); - }*/ + } } public void metricsForCreate(boolean byCmd) { diff --git a/src/com/dre/brewery/filedata/ConfigUpdater.java b/src/com/dre/brewery/filedata/ConfigUpdater.java index 2e955fd..d4fbba7 100644 --- a/src/com/dre/brewery/filedata/ConfigUpdater.java +++ b/src/com/dre/brewery/filedata/ConfigUpdater.java @@ -1297,9 +1297,11 @@ public class ConfigUpdater { "enableEncode: false", "encodeKey: 0"); - addLinesAt(new String[] {"autosave:", "version:"}, 1, "", - "# Debug Nachrichten im Log anzeigen [false]", - "debug: false"); + if (indexOfStart("debug:") == -1) { + addLinesAt(new String[]{"autosave:", "version:"}, 1, "", + "# Debug Nachrichten im Log anzeigen [false]", + "debug: false"); + } index = indexOfStart("oldMat:") + 1; if (index == 0) { @@ -1396,9 +1398,11 @@ public class ConfigUpdater { "enableEncode: false", "encodeKey: 0"); - addLinesAt(new String[] {"autosave:", "version:"}, 1, "", - "# Show debug messages in log [false]", - "debug: false"); + if (indexOfStart("debug:") == -1) { + addLinesAt(new String[]{"autosave:", "version:"}, 1, "", + "# Show debug messages in log [false]", + "debug: false"); + } index = indexOfStart("oldMat:") + 1; if (index == 0) { @@ -1495,9 +1499,11 @@ public class ConfigUpdater { "enableEncode: false", "encodeKey: 0"); - addLinesAt(new String[] {"autosave:", "version:"}, 1, "", - "# Show debug messages in log [false]", - "debug: false"); + if (indexOfStart("debug:") == -1) { + addLinesAt(new String[]{"autosave:", "version:"}, 1, "", + "# Show debug messages in log [false]", + "debug: false"); + } index = indexOfStart("oldMat:") + 1; if (index == 0) { diff --git a/src/com/dre/brewery/filedata/LanguageReader.java b/src/com/dre/brewery/filedata/LanguageReader.java index 2b2655b..2f5e2a7 100644 --- a/src/com/dre/brewery/filedata/LanguageReader.java +++ b/src/com/dre/brewery/filedata/LanguageReader.java @@ -38,7 +38,6 @@ public class LanguageReader { private void check(String defaultPath) { FileConfiguration defaults = null; ConfigUpdater updater = null; - int i = 0; String line; InputStream resource = P.p.getResource(defaultPath); if (resource == null) return; @@ -46,18 +45,18 @@ public class LanguageReader { while ((line = reader.readLine()) != null) { int index = line.indexOf(':'); if (index != -1) { - line = line.substring(0, index); - if (!entries.containsKey(line)) { + String key = line.substring(0, index); + if (!entries.containsKey(key)) { if (defaults == null) { defaults = new YamlConfiguration(); defaults.load(new BufferedReader(new InputStreamReader(Objects.requireNonNull(P.p.getResource(defaultPath))))); updater = new ConfigUpdater(file); + updater.appendLines("", "# Updated"); } - entries.put(line, defaults.getString(line)); - updater.addLines(i, line + ": '" + entries.get(line) + "'"); + entries.put(key, defaults.getString(key)); + updater.appendLines(line); } } - i++; } if (updater != null) { createBackup(); From 27652b511ffa0c2633d18920efc47d6d65f9755e Mon Sep 17 00:00:00 2001 From: Sn0wStorm Date: Mon, 2 Dec 2019 20:24:14 +0100 Subject: [PATCH 51/51] Include config patches is pom build --- pom.xml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 3e214a7..f6b4965 100644 --- a/pom.xml +++ b/pom.xml @@ -4,7 +4,7 @@ com.dre Brewery - 1.8.3 + 2.0-beta1 Brewery @@ -23,6 +23,7 @@ ${project.basedir}/resources **/*.yml + **/*.txt target/**