mirror of
https://github.com/DieReicheErethons/Brewery.git
synced 2025-02-01 22:51:20 +01:00
Load Scramble Seed key from Config
Remember all used Scramble seeds to unscramble potions
This commit is contained in:
parent
437f521a9b
commit
f431c13100
6
pom.xml
6
pom.xml
@ -232,6 +232,12 @@
|
||||
<version>1.5</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.jetbrains</groupId>
|
||||
<artifactId>annotations</artifactId>
|
||||
<version>16.0.2</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<distributionManagement>
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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<String, BPlayer> entry : players.entrySet()) {
|
||||
|
@ -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<HumanEntity> viewers = new ArrayList(inventory.getViewers());
|
||||
List<HumanEntity> 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
|
||||
|
@ -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<Long> prevSaveSeeds = new ArrayList<>(); // Save Seeds that have been used in the past, stored to decode brews made at that time
|
||||
public static Map<Integer, Brew> 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);
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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) {
|
||||
|
@ -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);
|
||||
|
@ -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
|
||||
|
@ -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"));
|
||||
|
@ -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();
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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();
|
||||
|
@ -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) {
|
||||
|
@ -1,38 +1,99 @@
|
||||
package com.dre.brewery.lore;
|
||||
|
||||
import com.dre.brewery.P;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.io.FilterInputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.security.InvalidKeyException;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* A Scramble Stream that uses XOR operations to unscramble an inputstream.
|
||||
* a byte generator feeded with the seed is used as xor source
|
||||
* Used to unscramble data generated by the XORScrambleStream
|
||||
*/
|
||||
public class XORUnscrambleStream extends FilterInputStream {
|
||||
|
||||
private final long seed;
|
||||
private long seed;
|
||||
private final List<Long> prevSeeds;
|
||||
private SeedInputStream xorStream;
|
||||
private boolean running;
|
||||
private boolean markRunning;
|
||||
private boolean markxor;
|
||||
|
||||
/**
|
||||
* Create a new instance of an XORUnscrambler, unscrambling the given inputstream
|
||||
*
|
||||
* @param in The Inputstream to be unscrambled
|
||||
* @param seed The seed used for unscrambling
|
||||
*/
|
||||
public XORUnscrambleStream(InputStream in, long seed) {
|
||||
super(in);
|
||||
this.seed = seed;
|
||||
prevSeeds = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new instance of an XORUnscrambler, unscrambling the given inputstream
|
||||
* If given a List of previous Seeds, the unscrambler will try all of them for unscrambling the stream in case the seed fails.
|
||||
*
|
||||
* @param in The Inputstream to be unscrambled
|
||||
* @param seed The seed used for unscrambling
|
||||
*/
|
||||
public XORUnscrambleStream(InputStream in, long seed, List<Long> prevSeeds) {
|
||||
super(in);
|
||||
this.seed = seed;
|
||||
this.prevSeeds = prevSeeds;
|
||||
}
|
||||
|
||||
/**
|
||||
* Before unscrambling, this has to be called to tell the unscrambler that scrambled data will follow.
|
||||
* Before starting the unscrambler, any data will just be passed through unmodified to the underlying stream.
|
||||
* The Unscrambling can be started and stopped arbitrarily at any point, allowing for parts of already unscrambled data in the stream.
|
||||
*
|
||||
* @throws IOException IOException
|
||||
* @throws InvalidKeyException If the scrambled data could not be read, very likely caused by a wrong seed. Thrown after checking all previous seeds.
|
||||
*/
|
||||
public void start() throws IOException, InvalidKeyException {
|
||||
running = true;
|
||||
if (xorStream == null) {
|
||||
short id = (short) (in.read() << 8 | in.read());
|
||||
if (id == 0) {
|
||||
running = false;
|
||||
P.p.debugLog("Unscrambled data");
|
||||
return;
|
||||
}
|
||||
int parity = in.read();
|
||||
xorStream = new SeedInputStream(seed ^ id);
|
||||
if (read() != ((int) (seed >> 48) & 0xFF)) { // Parity/Sanity
|
||||
boolean success = checkParity(parity);
|
||||
if (success) P.p.debugLog("Using main Seed to unscramble");
|
||||
|
||||
if (!success && prevSeeds != null) {
|
||||
for (int i = prevSeeds.size() - 1; i >= 0; i--) {
|
||||
seed = prevSeeds.get(i);
|
||||
xorStream = new SeedInputStream(seed ^ id);
|
||||
if (success = checkParity(parity)) {
|
||||
P.p.debugLog("Had to use prevSeed to unscramble");
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!success) {
|
||||
throw new InvalidKeyException("Could not read scrambled data, is the seed wrong?");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private boolean checkParity(int parity) {
|
||||
return ((parity ^ xorStream.read()) & 0xFF) == ((int) (seed >> 48) & 0xFF); // Parity/Sanity
|
||||
}
|
||||
|
||||
/**
|
||||
* Stop the unscrambling, any following data will be passed through unmodified.
|
||||
* The unscrambling can be started again at any point after calling this
|
||||
*/
|
||||
public void stop() {
|
||||
running = false;
|
||||
}
|
||||
@ -46,7 +107,7 @@ public class XORUnscrambleStream extends FilterInputStream {
|
||||
}
|
||||
|
||||
@Override
|
||||
public int read(byte[] b, int off, int len) throws IOException {
|
||||
public int read(@NotNull byte[] b, int off, int len) throws IOException {
|
||||
if (!running) {
|
||||
return in.read(b, off, len);
|
||||
}
|
||||
@ -57,6 +118,7 @@ public class XORUnscrambleStream extends FilterInputStream {
|
||||
return len;
|
||||
}
|
||||
|
||||
@SuppressWarnings("ResultOfMethodCallIgnored")
|
||||
@Override
|
||||
public long skip(long n) throws IOException {
|
||||
long skipped = in.skip(n);
|
||||
|
Loading…
Reference in New Issue
Block a user