mirror of
https://github.com/AppleDash/SaneEconomy.git
synced 2024-11-22 18:16:11 +01:00
Switch flatfile storage to use JSON and improve sign shops
This commit is contained in:
parent
b78c353093
commit
af1752b85c
@ -18,6 +18,11 @@
|
||||
<artifactId>SaneEconomyCore</artifactId>
|
||||
<version>0.10.1-SNAPSHOT</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.appledash</groupId>
|
||||
<artifactId>SaneEconomyCore</artifactId>
|
||||
<version>0.10.1-SNAPSHOT</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
|
@ -5,7 +5,7 @@ import org.appledash.saneeconomysignshop.listeners.BreakListener;
|
||||
import org.appledash.saneeconomysignshop.listeners.InteractListener;
|
||||
import org.appledash.saneeconomysignshop.listeners.SignChangeListener;
|
||||
import org.appledash.saneeconomysignshop.signshop.SignShopManager;
|
||||
import org.appledash.saneeconomysignshop.signshop.storage.SignShopStorageFlatfile;
|
||||
import org.appledash.saneeconomysignshop.signshop.storage.SignShopStorageJSON;
|
||||
import org.appledash.saneeconomysignshop.util.ItemDatabase;
|
||||
import org.appledash.saneeconomysignshop.util.LimitManager;
|
||||
import org.bukkit.configuration.file.YamlConfiguration;
|
||||
@ -20,7 +20,7 @@ import java.io.File;
|
||||
*/
|
||||
public class SaneEconomySignShop extends JavaPlugin {
|
||||
private ISaneEconomy saneEconomy;
|
||||
private final SignShopManager signShopManager = new SignShopManager(new SignShopStorageFlatfile(new File(getDataFolder(), "shops.db")));
|
||||
private final SignShopManager signShopManager = new SignShopManager(new SignShopStorageJSON(new File(getDataFolder(), "shops.json")));
|
||||
private final LimitManager limitManager = new LimitManager();
|
||||
|
||||
@Override
|
||||
|
@ -7,14 +7,12 @@ import org.appledash.saneeconomysignshop.SaneEconomySignShop;
|
||||
import org.appledash.saneeconomysignshop.signshop.SignShop;
|
||||
import org.appledash.saneeconomysignshop.util.ItemDatabase;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.Listener;
|
||||
import org.bukkit.event.block.SignChangeEvent;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
|
||||
import java.util.Optional;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
@ -92,8 +90,8 @@ public class SignChangeListener implements Listener {
|
||||
|
||||
ItemStack itemStack;
|
||||
try {
|
||||
itemStack = parseGive(itemName);
|
||||
} catch (InvalidItemException e) {
|
||||
itemStack = ItemDatabase.parseGive(itemName);
|
||||
} catch (ItemDatabase.InvalidItemException e) {
|
||||
return new ParsedSignShop("Invalid item name or ID specified.");
|
||||
}
|
||||
|
||||
@ -141,65 +139,4 @@ public class SignChangeListener implements Listener {
|
||||
this.shop = shop;
|
||||
}
|
||||
}
|
||||
|
||||
private ItemStack parseGive(String rawItemName) throws InvalidItemException {
|
||||
String itemName;
|
||||
short damage;
|
||||
|
||||
if (rawItemName.contains(":")) {
|
||||
String[] splitItemName = rawItemName.split(":");
|
||||
itemName = splitItemName[0];
|
||||
if (splitItemName.length == 1) { // They just typed 'tnt:'
|
||||
damage = 0;
|
||||
} else { // They typed 'tnt:something'
|
||||
try {
|
||||
damage = Short.valueOf(splitItemName[1]);
|
||||
} catch (NumberFormatException e) {
|
||||
throw new InvalidItemException("Damage value must be a number.");
|
||||
}
|
||||
}
|
||||
} else { // No damage value
|
||||
itemName = rawItemName;
|
||||
damage = 0;
|
||||
}
|
||||
|
||||
Optional<Material> materialOptional = parseMaterialFromName(itemName);
|
||||
|
||||
if (!materialOptional.isPresent()) {
|
||||
Optional<ItemDatabase.Pair<Integer, Short>> parsedItem = ItemDatabase.getIDAndDamageForName(normalizeItemName(itemName));
|
||||
if (!parsedItem.isPresent()) {
|
||||
throw new InvalidItemException("Item by that name does not exist.");
|
||||
}
|
||||
return new ItemStack(parsedItem.get().getLeft(), 1, parsedItem.get().getRight());
|
||||
}
|
||||
|
||||
return new ItemStack(materialOptional.get(), 1, damage);
|
||||
|
||||
}
|
||||
|
||||
private Optional<Material> parseMaterialFromName(String materialName) {
|
||||
// Try to parse an integral item ID first, for legacy reasons.
|
||||
try {
|
||||
Material mat = Material.getMaterial(Integer.valueOf(materialName));
|
||||
return Optional.ofNullable(mat);
|
||||
} catch (NumberFormatException ignored) { }
|
||||
|
||||
for (Material mat : Material.values()) {
|
||||
if (normalizeItemName(mat.name()).equals(normalizeItemName(materialName))) {
|
||||
return Optional.of(mat);
|
||||
}
|
||||
}
|
||||
|
||||
return Optional.empty();
|
||||
}
|
||||
|
||||
private String normalizeItemName(String itemName) {
|
||||
return itemName.toLowerCase().replace("_", "").replace(" ", "");
|
||||
}
|
||||
|
||||
private class InvalidItemException extends Exception {
|
||||
public InvalidItemException(String message) {
|
||||
super(message);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,83 +0,0 @@
|
||||
package org.appledash.saneeconomysignshop.signshop.storage;
|
||||
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import org.appledash.saneeconomysignshop.signshop.SignShop;
|
||||
import org.appledash.saneeconomysignshop.util.SerializableLocation;
|
||||
import org.bukkit.Location;
|
||||
|
||||
import java.io.*;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
/**
|
||||
* Created by appledash on 10/6/16.
|
||||
* Blackjack is best pony.
|
||||
*/
|
||||
public class SignShopStorageFlatfile implements SignShopStorage {
|
||||
private Map<Location, SignShop> cachedSignShops;
|
||||
private File file;
|
||||
|
||||
public SignShopStorageFlatfile(File file) {
|
||||
this.file = file;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void loadSignShops() {
|
||||
readSignShops();
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized void putSignShop(SignShop signShop) {
|
||||
cachedSignShops.put(signShop.getLocation(), signShop);
|
||||
writeSignShops();
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized void removeSignShop(SignShop signShop) {
|
||||
cachedSignShops.remove(signShop.getLocation());
|
||||
writeSignShops();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<Location, SignShop> getSignShops() {
|
||||
return ImmutableMap.copyOf(cachedSignShops);
|
||||
}
|
||||
|
||||
private void readSignShops() {
|
||||
cachedSignShops = new ConcurrentHashMap<>();
|
||||
|
||||
if (!file.exists()) {
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
ObjectInput ois = new ObjectInputStream(new FileInputStream(file));
|
||||
Map<SerializableLocation, SignShop> tempMap = ((Map<SerializableLocation, SignShop>) ois.readObject());
|
||||
tempMap.forEach((sLoc, shop) -> {
|
||||
cachedSignShops.put(sLoc.getBukkitLocation(), shop);
|
||||
});
|
||||
ois.close();
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException("Failed to load sign shop date!", e);
|
||||
}
|
||||
}
|
||||
|
||||
private void writeSignShops() {
|
||||
if (file.exists()) {
|
||||
file.delete();
|
||||
}
|
||||
|
||||
try {
|
||||
ObjectOutput oos = new ObjectOutputStream(new FileOutputStream(file));
|
||||
Map<SerializableLocation, SignShop> tempMap = new HashMap<>();
|
||||
cachedSignShops.forEach((loc, shop) -> {
|
||||
tempMap.put(new SerializableLocation(loc), shop);
|
||||
});
|
||||
oos.writeObject(tempMap);
|
||||
oos.close();
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException("Failed to save sign shop date!", e);
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,71 @@
|
||||
package org.appledash.saneeconomysignshop.signshop.storage;
|
||||
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import com.google.common.reflect.TypeToken;
|
||||
import com.google.gson.Gson;
|
||||
import com.google.gson.GsonBuilder;
|
||||
import org.appledash.saneeconomysignshop.signshop.SignShop;
|
||||
import org.bukkit.Location;
|
||||
|
||||
import java.io.*;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* Created by appledash on 1/18/17.
|
||||
* Blackjack is still best pony.
|
||||
*/
|
||||
public class SignShopStorageJSON implements SignShopStorage {
|
||||
private final Gson gson = new GsonBuilder().setPrettyPrinting().serializeNulls().create();
|
||||
private final File storageFile;
|
||||
private Map<Location, SignShop> cachedSignShops = new HashMap<>();
|
||||
|
||||
public SignShopStorageJSON(File storageFile) {
|
||||
this.storageFile = storageFile;
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("unchecked")
|
||||
public void loadSignShops() {
|
||||
if (!storageFile.exists()) {
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
List<SignShop> tempShops = gson.fromJson(new FileReader(storageFile), new TypeToken<List<SignShop>>(){}.getType());
|
||||
tempShops.forEach((shop) -> cachedSignShops.put(shop.getLocation(), shop));
|
||||
} catch (FileNotFoundException e) {
|
||||
throw new IllegalStateException("This shouldn't happen - the file " + storageFile.getAbsolutePath() + " disappeared while we were trying to read it!", e);
|
||||
}
|
||||
|
||||
saveSignShops();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void putSignShop(SignShop signShop) {
|
||||
cachedSignShops.put(signShop.getLocation(), signShop);
|
||||
saveSignShops();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeSignShop(SignShop signShop) {
|
||||
cachedSignShops.remove(signShop.getLocation());
|
||||
saveSignShops();
|
||||
}
|
||||
|
||||
private synchronized void saveSignShops() {
|
||||
try (BufferedWriter bufferedWriter = new BufferedWriter(new FileWriter(storageFile, false))) {
|
||||
bufferedWriter.write(gson.toJson(ImmutableList.copyOf(cachedSignShops.values())));
|
||||
bufferedWriter.close();
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException("Failed to save sign shops!", e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<Location, SignShop> getSignShops() {
|
||||
return ImmutableMap.copyOf(cachedSignShops);
|
||||
}
|
||||
}
|
@ -2,6 +2,7 @@ package org.appledash.saneeconomysignshop.util;
|
||||
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.IOException;
|
||||
@ -47,6 +48,66 @@ public class ItemDatabase {
|
||||
return Optional.ofNullable(itemMap.get(name.toLowerCase()));
|
||||
}
|
||||
|
||||
public static ItemStack parseGive(String rawItemName) throws InvalidItemException {
|
||||
String itemName;
|
||||
short damage;
|
||||
|
||||
if (rawItemName.contains(":")) {
|
||||
String[] splitItemName = rawItemName.split(":");
|
||||
itemName = splitItemName[0];
|
||||
if (splitItemName.length == 1) { // They just typed 'tnt:'
|
||||
damage = 0;
|
||||
} else { // They typed 'tnt:something'
|
||||
try {
|
||||
damage = Short.valueOf(splitItemName[1]);
|
||||
} catch (NumberFormatException e) {
|
||||
throw new InvalidItemException("Damage value must be a number.");
|
||||
}
|
||||
}
|
||||
} else { // No damage value
|
||||
itemName = rawItemName;
|
||||
damage = 0;
|
||||
}
|
||||
|
||||
Optional<Material> materialOptional = parseMaterialFromName(itemName);
|
||||
|
||||
if (!materialOptional.isPresent()) {
|
||||
Optional<Pair<Integer, Short>> parsedItem = getIDAndDamageForName(normalizeItemName(itemName));
|
||||
if (!parsedItem.isPresent()) {
|
||||
throw new InvalidItemException("Item by that name does not exist.");
|
||||
}
|
||||
|
||||
if (damage == 0) {
|
||||
damage = parsedItem.get().getRight();
|
||||
}
|
||||
|
||||
return new ItemStack(parsedItem.get().getLeft(), 1, damage);
|
||||
}
|
||||
|
||||
return new ItemStack(materialOptional.get(), 1, damage);
|
||||
|
||||
}
|
||||
|
||||
private static Optional<Material> parseMaterialFromName(String materialName) {
|
||||
// Try to parse an integral item ID first, for legacy reasons.
|
||||
try {
|
||||
Material mat = Material.getMaterial(Integer.valueOf(materialName));
|
||||
return Optional.ofNullable(mat);
|
||||
} catch (NumberFormatException ignored) { }
|
||||
|
||||
for (Material mat : Material.values()) {
|
||||
if (normalizeItemName(mat.name()).equals(normalizeItemName(materialName))) {
|
||||
return Optional.of(mat);
|
||||
}
|
||||
}
|
||||
|
||||
return Optional.empty();
|
||||
}
|
||||
|
||||
private static String normalizeItemName(String itemName) {
|
||||
return itemName.toLowerCase().replace("_", "").replace(" ", "");
|
||||
}
|
||||
|
||||
public static class Pair<K, V> {
|
||||
private K k;
|
||||
private V v;
|
||||
@ -67,4 +128,10 @@ public class ItemDatabase {
|
||||
return new Pair<>(k, v);
|
||||
}
|
||||
}
|
||||
|
||||
public static class InvalidItemException extends Exception {
|
||||
public InvalidItemException(String message) {
|
||||
super(message);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -8,7 +8,6 @@ import org.bukkit.inventory.ItemStack;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
import java.util.UUID;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
@ -80,15 +79,17 @@ public class LimitManager {
|
||||
String itemName = String.valueOf(map.get("item"));
|
||||
int sellLimit = Integer.valueOf(String.valueOf(map.get("limit")));
|
||||
int hourlyGain = Integer.valueOf(String.valueOf(map.get("gain")));
|
||||
ItemStack stack;
|
||||
|
||||
Optional<ItemDatabase.Pair<Integer, Short>> pair = ItemDatabase.getIDAndDamageForName(itemName);
|
||||
|
||||
if (!pair.isPresent()) {
|
||||
try {
|
||||
stack = ItemDatabase.parseGive(itemName);
|
||||
} catch (ItemDatabase.InvalidItemException e) {
|
||||
LOGGER.warning(String.format("You tried to load the item '%s' in limits.yml, but I have no idea what that is.", map.get("item")));
|
||||
continue;
|
||||
}
|
||||
|
||||
ItemInfo itemInfo = new ItemInfo(new ItemStack(pair.get().getLeft(), pair.get().getRight()));
|
||||
|
||||
ItemInfo itemInfo = new ItemInfo(stack);
|
||||
|
||||
sellItemLimits.put(itemInfo, new ItemLimits(sellLimit, hourlyGain));
|
||||
}
|
||||
|
@ -53,7 +53,7 @@ sell:
|
||||
- item: PORKCHOP
|
||||
limit: 1280
|
||||
gain: 128
|
||||
- item: CHICKEN
|
||||
- item: RAW_CHICKEN
|
||||
limit: 1280
|
||||
gain: 128
|
||||
- item: DYE:3
|
||||
@ -162,7 +162,7 @@ sell:
|
||||
- item: CACTUS
|
||||
limit: 1600
|
||||
gain: 160
|
||||
- item: WHEAT_SEEDS
|
||||
- item: SEEDS
|
||||
limit: 1600
|
||||
gain: 160
|
||||
- item: PUMPKIN_SEEDS
|
||||
@ -399,51 +399,51 @@ sell:
|
||||
- item: WOOL:15
|
||||
limit: 1600
|
||||
gain: 80
|
||||
- item: STAINED_HARDENED_CLAY:14
|
||||
- item: STAINED_CLAY:14
|
||||
limit: 1600
|
||||
gain: 80
|
||||
- item: STAINED_HARDENED_CLAY:1
|
||||
- item: STAINED_CLAY:1
|
||||
limit: 1600
|
||||
gain: 80
|
||||
- item: STAINED_HARDENED_CLAY:4
|
||||
- item: STAINED_CLAY:4
|
||||
limit: 1600
|
||||
gain: 80
|
||||
- item: STAINED_HARDENED_CLAY:5
|
||||
- item: STAINED_CLAY:5
|
||||
limit: 1600
|
||||
gain: 80
|
||||
- item: STAINED_HARDENED_CLAY:13
|
||||
- item: STAINED_CLAY:13
|
||||
limit: 1600
|
||||
gain: 80
|
||||
- item: STAINED_HARDENED_CLAY:9
|
||||
- item: STAINED_CLAY:9
|
||||
limit: 1600
|
||||
gain: 80
|
||||
- item: STAINED_HARDENED_CLAY:3
|
||||
- item: STAINED_CLAY:3
|
||||
limit: 1600
|
||||
gain: 80
|
||||
- item: STAINED_HARDENED_CLAY:11
|
||||
- item: STAINED_CLAY:11
|
||||
limit: 1600
|
||||
gain: 80
|
||||
- item: STAINED_HARDENED_CLAY:10
|
||||
- item: STAINED_CLAY:10
|
||||
limit: 1600
|
||||
gain: 80
|
||||
- item: STAINED_HARDENED_CLAY:2
|
||||
- item: STAINED_CLAY:2
|
||||
limit: 1600
|
||||
gain: 80
|
||||
- item: STAINED_HARDENED_CLAY:6
|
||||
- item: STAINED_CLAY:6
|
||||
limit: 1600
|
||||
gain: 80
|
||||
- item: STAINED_HARDENED_CLAY:12
|
||||
- item: STAINED_CLAY:12
|
||||
limit: 1600
|
||||
gain: 80
|
||||
- item: STAINED_HARDENED_CLAY:0
|
||||
- item: STAINED_CLAY:0
|
||||
limit: 1600
|
||||
gain: 80
|
||||
- item: STAINED_HARDENED_CLAY:8
|
||||
- item: STAINED_CLAY:8
|
||||
limit: 1600
|
||||
gain: 80
|
||||
- item: STAINED_HARDENED_CLAY:7
|
||||
- item: STAINED_CLAY:7
|
||||
limit: 1600
|
||||
gain: 80
|
||||
- item: STAINED_HARDENED_CLAY:15
|
||||
- item: STAINED_CLAY:15
|
||||
limit: 1600
|
||||
gain: 80
|
||||
|
Loading…
Reference in New Issue
Block a user