Google Sheets v2 finally

This commit is contained in:
Sam 2017-01-20 20:08:24 +00:00
parent 8a9a3cb2ac
commit a16acedb14
13 changed files with 369 additions and 187 deletions

View File

@ -3,16 +3,11 @@ package mineplex.core.google;
import java.io.File; import java.io.File;
import java.io.FileNotFoundException; import java.io.FileNotFoundException;
import java.io.FileReader; import java.io.FileReader;
import java.lang.reflect.Constructor;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.HashMap; import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator; import java.util.Iterator;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Set;
import org.bukkit.Bukkit;
import com.google.gson.JsonArray; import com.google.gson.JsonArray;
import com.google.gson.JsonElement; import com.google.gson.JsonElement;
@ -33,20 +28,19 @@ public class GoogleSheetsManager extends MiniPlugin
super("Google Sheets"); super("Google Sheets");
} }
public <T> Map<String, Set<T>> getSheetData(String name, Class<T> clazz) public Map<String, List<List<String>>> getSheetData(String name)
{ {
return getSheetData(new File(DATA_STORE_DIR + File.separator + name + ".json"), clazz); return getSheetData(new File(DATA_STORE_DIR + File.separator + name + ".json"));
} }
public <T> Map<String, Set<T>> getSheetData(File file, Class<T> clazz) public Map<String, List<List<String>>> getSheetData(File file)
{ {
if (!file.exists()) if (!file.exists())
{ {
Bukkit.broadcastMessage("No file");
return null; return null;
} }
Map<String, Set<T>> valuesMap = new HashMap<>(); Map<String, List<List<String>>> valuesMap = new HashMap<>();
try try
{ {
@ -54,18 +48,16 @@ public class GoogleSheetsManager extends MiniPlugin
JsonElement data = parser.parse(new FileReader(file)); JsonElement data = parser.parse(new FileReader(file));
JsonArray parent = data.getAsJsonObject().getAsJsonArray("data"); JsonArray parent = data.getAsJsonObject().getAsJsonArray("data");
Bukkit.broadcastMessage("p=" + parent.size());
for (int i = 0; i < parent.size(); i++) for (int i = 0; i < parent.size(); i++)
{ {
JsonObject sheet = parent.get(i).getAsJsonObject(); JsonObject sheet = parent.get(i).getAsJsonObject();
String name = sheet.get("name").getAsString(); String name = sheet.get("name").getAsString();
JsonArray values = sheet.getAsJsonArray("values"); JsonArray values = sheet.getAsJsonArray("values");
List<List<Object>> valuesList = new ArrayList<>(values.size()); List<List<String>> valuesList = new ArrayList<>(values.size());
for (int j = 0; j < values.size(); j++) for (int j = 0; j < values.size(); j++)
{ {
List<Object> list = new ArrayList<>(); List<String> list = new ArrayList<>();
Iterator<JsonElement> iterator = values.get(j).getAsJsonArray().iterator(); Iterator<JsonElement> iterator = values.get(j).getAsJsonArray().iterator();
while (iterator.hasNext()) while (iterator.hasNext())
@ -77,44 +69,13 @@ public class GoogleSheetsManager extends MiniPlugin
valuesList.add(list); valuesList.add(list);
} }
valuesMap.put(name, toSet(valuesList, clazz)); valuesMap.put(name, valuesList);
} }
} }
catch (FileNotFoundException e) catch (FileNotFoundException e)
{ {
e.printStackTrace();
}
for (String key : valuesMap.keySet())
{
Set<T> set = valuesMap.get(key);
for (T t : set)
{
Bukkit.broadcastMessage(t.toString());
}
} }
return valuesMap; return valuesMap;
} }
public <T> Set<T> toSet(List<List<Object>> values, Class<T> clazz)
{
Set<T> result = new HashSet<>();
Constructor<?> constructor = clazz.getConstructors()[0];
for (List<Object> objects : values)
{
try
{
result.add(clazz.cast(constructor.newInstance(objects)));
}
catch (Exception e)
{
continue;
}
}
return result;
}
} }

View File

@ -0,0 +1,8 @@
package mineplex.core.google;
public interface SheetObjectDeserialiser<T>
{
public T deserialise(String[] values) throws ArrayIndexOutOfBoundsException;
}

View File

@ -53,6 +53,7 @@ public class ItemBuilder
private int _amount; private int _amount;
private Color _color; private Color _color;
private short _data; private short _data;
private short _durability;
private final HashMap<Enchantment, Integer> _enchants = new HashMap<Enchantment, Integer>(); private final HashMap<Enchantment, Integer> _enchants = new HashMap<Enchantment, Integer>();
private final List<String> _lore = new ArrayList<String>(); private final List<String> _lore = new ArrayList<String>();
private Material _mat; private Material _mat;
@ -90,6 +91,7 @@ public class ItemBuilder
_itemFlags.addAll(meta.getItemFlags()); _itemFlags.addAll(meta.getItemFlags());
_unbreakable = meta.spigot().isUnbreakable(); _unbreakable = meta.spigot().isUnbreakable();
_durability = item.getDurability();
} }
} }
@ -108,6 +110,7 @@ public class ItemBuilder
_mat = mat; _mat = mat;
_amount = amount; _amount = amount;
_data = data; _data = data;
_durability = 0;
} }
public ItemBuilder(Material mat, short data) public ItemBuilder(Material mat, short data)
@ -115,6 +118,13 @@ public class ItemBuilder
this(mat, 1, data); this(mat, 1, data);
} }
public ItemBuilder setDurability(short durability)
{
_durability = durability;
return this;
}
public HashSet<ItemFlag> getItemFlags() public HashSet<ItemFlag> getItemFlags()
{ {
return _itemFlags; return _itemFlags;
@ -278,6 +288,7 @@ public class ItemBuilder
item.addUnsafeEnchantments(_enchants); item.addUnsafeEnchantments(_enchants);
if (_glow) item.addEnchantment(UtilInv.getDullEnchantment(), 1); if (_glow) item.addEnchantment(UtilInv.getDullEnchantment(), 1);
if (_durability != 0) item.setDurability(_durability);
return item; return item;
} }
@ -298,6 +309,7 @@ public class ItemBuilder
newBuilder.setColor(_color); newBuilder.setColor(_color);
// newBuilder.potion = potion; // newBuilder.potion = potion;
newBuilder.setDurability(_durability);
return newBuilder; return newBuilder;
} }

View File

@ -172,7 +172,7 @@ public class TwoFactorAuth extends MiniClientPlugin<TwoFactorData>
player.sendMessage(F.main("2FA", "Setting up two-factor authentication.")); player.sendMessage(F.main("2FA", "Setting up two-factor authentication."));
} }
@EventHandler //@EventHandler
public void onJoin(PlayerJoinEvent event) public void onJoin(PlayerJoinEvent event)
{ {
Player player = event.getPlayer(); Player player = event.getPlayer();

View File

@ -17,7 +17,6 @@ import mineplex.core.ReflectivelyCreateMiniPlugin;
import mineplex.core.common.currency.GlobalCurrency; import mineplex.core.common.currency.GlobalCurrency;
import mineplex.core.common.util.F; import mineplex.core.common.util.F;
import mineplex.core.google.GoogleSheetsManager; import mineplex.core.google.GoogleSheetsManager;
import mineplex.gemhunters.loot.LootItem;
@ReflectivelyCreateMiniPlugin @ReflectivelyCreateMiniPlugin
public class EconomyModule extends MiniPlugin public class EconomyModule extends MiniPlugin
@ -87,8 +86,7 @@ public class EconomyModule extends MiniPlugin
{ {
event.setCancelled(true); event.setCancelled(true);
require(GoogleSheetsManager.class).getSheetData("GEM_HUNTERS_CHESTS", LootItem.class); addToStore(event.getPlayer(), "Testing", 100);
//addToStore(event.getPlayer(), "Testing", 100);
} }
} }

View File

@ -0,0 +1,90 @@
package mineplex.gemhunters.loot;
import org.bukkit.Material;
public class ChestProperties
{
private final String _name;
private final Material _blockMaterial;
private final String _dataKey;
private final int _minAmount;
private final int _maxAmount;
private final int _spawnRate;
private final int _expireRate;
private final int _spawnRadius;
private final double _percentile;
private long _lastSpawn;
public ChestProperties(String name, Material blockMaterial, String dataKey, int minAmount, int maxAmount, int spawnRate, int expireRate, int spawnRadius, double percentile)
{
_name = name;
_blockMaterial = blockMaterial;
_dataKey = dataKey;
_minAmount = minAmount;
_maxAmount = maxAmount;
_spawnRate = spawnRate;
_expireRate = expireRate;
_spawnRadius = spawnRadius;
_percentile = percentile;
setLastSpawn();
}
public final String getName()
{
return _name;
}
public final Material getBlockMaterial()
{
return _blockMaterial;
}
public final String getDataKey()
{
return _dataKey;
}
public final int getMinAmount()
{
return _minAmount;
}
public final int getMaxAmount()
{
return _maxAmount;
}
public final int getSpawnRate()
{
return _spawnRate;
}
public final int getExpireRate()
{
return _expireRate;
}
public final int getSpawnRadius()
{
return _spawnRadius;
}
public final double getPercentile()
{
return _percentile;
}
public void setLastSpawn()
{
_lastSpawn = System.currentTimeMillis();
}
public long getLastSpawn()
{
return _lastSpawn;
}
}

View File

@ -13,16 +13,11 @@ import mineplex.core.common.util.UtilMath;
public class LootItem public class LootItem
{ {
private ItemStack _itemStack; private final ItemStack _itemStack;
private int _minAmount; private final int _minAmount;
private int _maxAmount; private final int _maxAmount;
private double _probability; private final double _probability;
private String _metadata; private final String _metadata;
public LootItem(String... strings)
{
}
public LootItem(ItemStack itemStack, int minAmount, int maxAmount, double probability, String metadata) public LootItem(ItemStack itemStack, int minAmount, int maxAmount, double probability, String metadata)
{ {

View File

@ -1,6 +1,7 @@
package mineplex.gemhunters.loot; package mineplex.gemhunters.loot;
import java.io.IOException; import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.HashMap; import java.util.HashMap;
import java.util.HashSet; import java.util.HashSet;
@ -19,7 +20,6 @@ import org.bukkit.block.BlockFace;
import org.bukkit.block.BlockState; import org.bukkit.block.BlockState;
import org.bukkit.block.Chest; import org.bukkit.block.Chest;
import org.bukkit.block.DoubleChest; import org.bukkit.block.DoubleChest;
import org.bukkit.enchantments.Enchantment;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler; import org.bukkit.event.EventHandler;
import org.bukkit.event.inventory.InventoryClickEvent; import org.bukkit.event.inventory.InventoryClickEvent;
@ -32,41 +32,49 @@ import mineplex.core.MiniPlugin;
import mineplex.core.ReflectivelyCreateMiniPlugin; import mineplex.core.ReflectivelyCreateMiniPlugin;
import mineplex.core.common.util.UtilAlg; import mineplex.core.common.util.UtilAlg;
import mineplex.core.common.util.UtilBlock; import mineplex.core.common.util.UtilBlock;
import mineplex.core.common.util.UtilFirework;
import mineplex.core.common.util.UtilMath; import mineplex.core.common.util.UtilMath;
import mineplex.core.common.util.UtilTime; import mineplex.core.common.util.UtilTime;
import mineplex.core.common.util.UtilWorld; import mineplex.core.common.util.UtilWorld;
import mineplex.core.google.GoogleSheetsManager; import mineplex.core.google.GoogleSheetsManager;
import mineplex.core.itemstack.ItemBuilder; import mineplex.core.slack.SlackAPI;
import mineplex.core.slack.SlackMessage;
import mineplex.core.slack.SlackTeam;
import mineplex.core.updater.UpdateType; import mineplex.core.updater.UpdateType;
import mineplex.core.updater.event.UpdateEvent; import mineplex.core.updater.event.UpdateEvent;
import mineplex.gemhunters.economy.PlayerCashOutCompleteEvent; import mineplex.gemhunters.economy.PlayerCashOutCompleteEvent;
import mineplex.gemhunters.loot.command.UpdateLootCommand; import mineplex.gemhunters.loot.command.UpdateLootCommand;
import mineplex.gemhunters.loot.deserialisers.ChestPropertiesDeserialiser;
import mineplex.gemhunters.loot.deserialisers.LootItemDeserialiser;
import mineplex.gemhunters.loot.rewards.LootItemReward; import mineplex.gemhunters.loot.rewards.LootItemReward;
import mineplex.gemhunters.loot.rewards.LootRankReward; import mineplex.gemhunters.loot.rewards.LootRankReward;
import mineplex.gemhunters.safezone.SafezoneModule; import mineplex.gemhunters.safezone.SafezoneModule;
import mineplex.gemhunters.world.WorldDataModule; import mineplex.gemhunters.world.WorldDataModule;
import net.md_5.bungee.api.ChatColor;
@ReflectivelyCreateMiniPlugin @ReflectivelyCreateMiniPlugin
public class LootModule extends MiniPlugin public class LootModule extends MiniPlugin
{ {
private static final String SHEET_FILE_NAME = "GEM_HUNTERS_CHESTS";
private static final String CHEST_MASTER_SHEET_NAME = "CHEST_MASTER";
private static final int MINIMUM_CHEST_ITEMS = 3; private static final int MINIMUM_CHEST_ITEMS = 3;
private static final int MAXIMUM_CHEST_ITEMS = 6; private static final int MAXIMUM_CHEST_ITEMS = 6;
private static final long CHEST_DESPAWN_TIME_OPENED = TimeUnit.SECONDS.toMillis(15); private static final long CHEST_DESPAWN_TIME_OPENED = TimeUnit.SECONDS.toMillis(15);
private static final long CHEST_DESPAWN_TIME_NATURAL = TimeUnit.MINUTES.toMillis(30);
private static final String[] IGNORED_COLOURS = { "RED" }; private static final String[] IGNORED_COLOURS = { "RED" };
private static final float MAX_CHESTS_FACTOR = 0.25F;
private static final int MAX_SEARCH_ATTEMPTS = 40; private static final int MAX_SEARCH_ATTEMPTS = 40;
private static final int MAX_CHEST_PLACEMENT_RANGE = 10; private static final int MAX_CHEST_PLACEMENT_RANGE = 10;
private static final int MAX_CHEST_CHECK_DISTANCE_SQUARED = 4; private static final int MAX_CHEST_CHECK_DISTANCE_SQUARED = 4;
private static final LootItemDeserialiser DESERIALISER = new LootItemDeserialiser();
private static final ChestPropertiesDeserialiser CHEST_DESERIALISER = new ChestPropertiesDeserialiser();
private static final String SLACK_CHANNEL_NAME = "#google-sheet-errors";
private static final String SLACK_USERNAME = "Google Sheets";
private static final String SLACK_ICON = "http://moppletop.github.io/mineplex/google-sheets-image.png";
private final GoogleSheetsManager _sheets; private final GoogleSheetsManager _sheets;
private final SafezoneModule _safezone; private final SafezoneModule _safezone;
private final WorldDataModule _worldData; private final WorldDataModule _worldData;
private final Map<String, Set<LootItem>> _chestLoot; private final Map<String, Set<LootItem>> _chestLoot;
private final Map<String, ChestProperties> _chestProperties;
private final List<SpawnedChest> _spawnedChest; private final List<SpawnedChest> _spawnedChest;
private final Map<String, Set<Integer>> _spawnedIndexes; private final Map<String, Set<Integer>> _spawnedIndexes;
private final Set<LootItemReward> _itemRewards; private final Set<LootItemReward> _itemRewards;
@ -79,11 +87,12 @@ public class LootModule extends MiniPlugin
_safezone = require(SafezoneModule.class); _safezone = require(SafezoneModule.class);
_worldData = require(WorldDataModule.class); _worldData = require(WorldDataModule.class);
_chestLoot = new HashMap<>(); _chestLoot = new HashMap<>();
_chestProperties = new HashMap<>();
_spawnedChest = new ArrayList<>(200); _spawnedChest = new ArrayList<>(200);
_spawnedIndexes = new HashMap<>(15); _spawnedIndexes = new HashMap<>(15);
_itemRewards = new HashSet<>(); _itemRewards = new HashSet<>();
//updateChestLoot(); runSyncLater(() -> updateChestLoot(), 20);
} }
@Override @Override
@ -95,7 +104,7 @@ public class LootModule extends MiniPlugin
@EventHandler @EventHandler
public void updateSpawnChests(UpdateEvent event) public void updateSpawnChests(UpdateEvent event)
{ {
if (event.getType() != UpdateType.SLOWER) if (event.getType() != UpdateType.SEC)
{ {
return; return;
} }
@ -106,12 +115,13 @@ public class LootModule extends MiniPlugin
while (iterator.hasNext()) while (iterator.hasNext())
{ {
SpawnedChest chest = iterator.next(); SpawnedChest chest = iterator.next();
ChestProperties properties = chest.getProperties();
if (chest.isOpened() && UtilTime.elapsed(chest.getOpenedAt(), CHEST_DESPAWN_TIME_OPENED) || UtilTime.elapsed(chest.getSpawnedAt(), CHEST_DESPAWN_TIME_NATURAL)) if (chest.isOpened() && UtilTime.elapsed(chest.getOpenedAt(), CHEST_DESPAWN_TIME_OPENED) || UtilTime.elapsed(chest.getSpawnedAt(), properties.getExpireRate()))
{ {
if (chest.getID() != -1) if (chest.getID() != -1)
{ {
_spawnedIndexes.get(chest.getColour()).remove(chest.getID()); _spawnedIndexes.get(properties.getDataKey()).remove(chest.getID());
} }
Block block = chest.getLocation().getBlock(); Block block = chest.getLocation().getBlock();
@ -128,7 +138,7 @@ public class LootModule extends MiniPlugin
} }
// Spawn new chests // Spawn new chests
dataPointLoop: for (String key : _worldData.getAllDataLocations().keySet()) dataPointLoop: for (String key : _chestProperties.keySet())
{ {
// Some data points are ignored like the chest loot related to // Some data points are ignored like the chest loot related to
// supply drops. // supply drops.
@ -141,24 +151,26 @@ public class LootModule extends MiniPlugin
} }
List<Location> locations = _worldData.getDataLocation(key); List<Location> locations = _worldData.getDataLocation(key);
ChestProperties properties = _chestProperties.get(key);
// Only spawn more chests if we need to // Only spawn more chests if we need to
int max = (int) (locations.size() * MAX_CHESTS_FACTOR); int max = (int) (_spawnedChest.size() * properties.getPercentile());
int spawned = 0; int spawned = 0;
for (SpawnedChest chest : _spawnedChest) for (SpawnedChest chest : _spawnedChest)
{ {
if (chest.getColour().equals(key)) if (chest.getProperties().getDataKey().equals(key))
{ {
spawned++; spawned++;
} }
} }
// TODO fix this
// If there are too many chests of this type we can ignore it // If there are too many chests of this type we can ignore it
if (spawned > max) // if (spawned > max)
{ // {
continue; // continue;
} // }
Set<Integer> usedIndexes = _spawnedIndexes.get(key); Set<Integer> usedIndexes = _spawnedIndexes.get(key);
@ -209,9 +221,8 @@ public class LootModule extends MiniPlugin
continue; continue;
} }
//TODO remove debug message Bukkit.broadcastMessage("Spawned at " + UtilWorld.blockToStrClean(block) + " with key=" + key + " and index=" + index + " and max=" + max);
Bukkit.broadcastMessage("Spawned at " + UtilWorld.blockToStrClean(block) + " with key=" + key + " and index=" + index); _spawnedChest.add(new SpawnedChest(chestToPlace, properties, index));
_spawnedChest.add(new SpawnedChest(chestToPlace, key, index));
block.setType(Material.CHEST); block.setType(Material.CHEST);
} }
} }
@ -231,108 +242,75 @@ public class LootModule extends MiniPlugin
public void updateChestLoot() public void updateChestLoot()
{ {
Map<String, List<List<Object>>> map = null; log("Updating chest loot");
Map<String, List<List<String>>> map = _sheets.getSheetData(SHEET_FILE_NAME);
for (String key : map.keySet()) for (String key : map.keySet())
{ {
if (key.equals(CHEST_MASTER_SHEET_NAME))
{
int row = 0;
for (List<String> rows : map.get(key))
{
row++;
try
{
ChestProperties properties = CHEST_DESERIALISER.deserialise(rows.toArray(new String[0]));
_chestProperties.put(properties.getDataKey(), properties);
}
catch (Exception e)
{
if (row != 1)
{
reportParsingError(e, key, row);
}
continue;
}
}
continue;
}
Set<LootItem> items = new HashSet<>(); Set<LootItem> items = new HashSet<>();
List<List<Object>> grid = map.get(key);
int index = 0;
int row = 0;
for (List<String> rows : map.get(key))
{
row++;
try try
{ {
for (List<Object> values : grid) items.add(DESERIALISER.deserialise(rows.toArray(new String[0])));
}
catch (Exception e)
{ {
if (index++ < 2) if (row != 1)
{ {
reportParsingError(e, key, row);
}
continue; continue;
} }
Material material = Material.valueOf(String.valueOf(values.get(0)));
byte data = Byte.parseByte(String.valueOf(values.get(1)));
int minAmount = 1;
int maxAmount = 1;
try
{
String[] numbers = String.valueOf(values.get(2)).split("-");
if (numbers.length < 2)
{
minAmount = Integer.parseInt(String.valueOf(values.get(2)));
maxAmount = minAmount;
}
else
{
minAmount = Integer.parseInt(numbers[0]);
maxAmount = Integer.parseInt(numbers[1]);
}
}
catch (NumberFormatException e)
{
continue;
}
ItemBuilder builder = new ItemBuilder(material, data);
String title = ChatColor.translateAlternateColorCodes('&', String.valueOf(values.get(3)));
String[] lore = String.valueOf(values.get(4)).split(":");
String[] colouredLore = new String[lore.length];
int loreIndex = 0;
for (String line : lore)
{
colouredLore[loreIndex++] = ChatColor.translateAlternateColorCodes('&', line);
}
builder.setTitle(title);
builder.setLore(colouredLore);
String[] enchants = String.valueOf(values.get(5)).split(",");
for (String enchant : enchants)
{
String[] enchantData = enchant.split(":");
if (enchantData.length < 2)
{
continue;
}
builder.addEnchantment(Enchantment.getByName(enchantData[0]), Integer.parseInt(enchantData[1]));
}
double probability = Double.parseDouble(String.valueOf(values.get(6)));
String metadata = null;
if (values.size() > 7)
{
metadata = String.valueOf(values.get(7));
}
items.add(new LootItem(builder.build(), minAmount, maxAmount, probability, metadata));
} }
_chestLoot.put(key, items); _chestLoot.put(key, items);
} }
catch (Exception e)
{ log("Finished updating chest loot");
// TODO send slack message?
e.printStackTrace();
log("An error occured while parsing spreadsheet data! " + key);
continue;
}
}
} }
public void addSpawnedChest(Location location, String colour) public void addSpawnedChest(Location location, String colour)
{ {
_spawnedChest.add(new SpawnedChest(location, colour, -1)); _spawnedChest.add(new SpawnedChest(location, _chestProperties.get(colour), -1));
} }
public void fillChest(Player player, Block block, String key) public void fillChest(Player player, Block block, String key)
{ {
Set<Integer> used = new HashSet<>(); Set<Integer> used = new HashSet<>();
Set<LootItem> items = _chestLoot.get(key); Set<LootItem> items = _chestLoot.get(key);
ChestProperties properties = _chestProperties.get(key);
int sizeMultiplier = 1; int sizeMultiplier = 1;
BlockState state = block.getState(); BlockState state = block.getState();
@ -348,16 +326,17 @@ public class LootModule extends MiniPlugin
inventory.clear(); inventory.clear();
for (int i = 0; i < (MINIMUM_CHEST_ITEMS + UtilMath.r(MAXIMUM_CHEST_ITEMS - MINIMUM_CHEST_ITEMS + 1)) * sizeMultiplier; i++) for (int i = 0; i < UtilMath.rRange(properties.getMinAmount(), properties.getMaxAmount()) * sizeMultiplier; i++)
{ {
LootItem lootItem = getRandomItem(items); LootItem lootItem = getRandomItem(items);
ItemStack itemStack = lootItem.getItemStack(); ItemStack itemStack = lootItem.getItemStack();
int index = getFreeIndex(inventory.getSize(), used); int index = getFreeIndex(inventory.getSize(), used);
if (lootItem.getMetadata() != null) // if (lootItem.getMetadata() != null)
{ // {
UtilFirework.playFirework(block.getLocation().add(0.5, 1, 0.5), UtilFirework.getRandomFireworkEffect(false, 2, 1)); // UtilFirework.playFirework(block.getLocation().add(0.5, 1, 0.5),
} // UtilFirework.getRandomFireworkEffect(false, 2, 1));
// }
inventory.setItem(index, itemStack); inventory.setItem(index, itemStack);
} }
@ -455,7 +434,7 @@ public class LootModule extends MiniPlugin
{ {
if (UtilMath.offset(chest.getLocation(), block.getLocation()) < MAX_CHEST_CHECK_DISTANCE_SQUARED) if (UtilMath.offset(chest.getLocation(), block.getLocation()) < MAX_CHEST_CHECK_DISTANCE_SQUARED)
{ {
key = chest.getColour(); key = chest.getProperties().getDataKey();
chest.setOpened(); chest.setOpened();
break; break;
} }
@ -553,4 +532,16 @@ public class LootModule extends MiniPlugin
} }
} }
} }
private final void reportParsingError(Exception exception, String sheetName, int row)
{
try
{
SlackAPI.getInstance().sendMessage(SlackTeam.DEVELOPER, SLACK_CHANNEL_NAME, new SlackMessage(SLACK_USERNAME, new URL(SLACK_ICON), "A parsing error has occured on sheet *" + sheetName + "* at row *" + row + "*.\n Details: " + exception.getMessage()), true);
}
catch (MalformedURLException e)
{
e.printStackTrace();
}
}
} }

View File

@ -6,16 +6,16 @@ public class SpawnedChest
{ {
private Location _location; private Location _location;
private String _colour; private ChestProperties _properties;
private int _id; private int _id;
private long _spawnedAt; private long _spawnedAt;
private long _openedAt; private long _openedAt;
public SpawnedChest(Location location, String colour, int id) public SpawnedChest(Location location, ChestProperties properties, int id)
{ {
_location = location; _location = location;
_colour = colour; _properties =properties;
_id = id; _id = id;
_spawnedAt = System.currentTimeMillis(); _spawnedAt = System.currentTimeMillis();
_openedAt = 0; _openedAt = 0;
@ -31,9 +31,9 @@ public class SpawnedChest
return _location; return _location;
} }
public String getColour() public ChestProperties getProperties()
{ {
return _colour; return _properties;
} }
public int getID() public int getID()

View File

@ -2,12 +2,10 @@ package mineplex.gemhunters.loot.command;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import mineplex.core.Managers;
import mineplex.core.command.CommandBase; import mineplex.core.command.CommandBase;
import mineplex.core.common.Rank; import mineplex.core.common.Rank;
import mineplex.core.common.util.F; import mineplex.core.common.util.F;
import mineplex.gemhunters.loot.LootModule; import mineplex.gemhunters.loot.LootModule;
import mineplex.gemhunters.shop.ShopModule;
/** /**
* An ADMIN command that allows users to retrieve the latest data from the * An ADMIN command that allows users to retrieve the latest data from the
@ -31,16 +29,7 @@ public class UpdateLootCommand extends CommandBase<LootModule>
// TODO send redis message // TODO send redis message
} }
caller.sendMessage(F.main(Plugin.getName(), "Updating loot tables asynchronusly...")); caller.sendMessage(F.main(Plugin.getName(), "This command is currently disabled due to development issues."));
final ShopModule shop = Managers.require(ShopModule.class);
Plugin.runAsync(() -> {
Plugin.updateChestLoot();
shop.updateVillagerLoot();
});
caller.sendMessage(F.main(Plugin.getName(), "Finished!"));
} }
} }

View File

@ -0,0 +1,42 @@
package mineplex.gemhunters.loot.deserialisers;
import org.bukkit.Material;
import mineplex.core.google.SheetObjectDeserialiser;
import mineplex.gemhunters.loot.ChestProperties;
public class ChestPropertiesDeserialiser implements SheetObjectDeserialiser<ChestProperties>
{
@Override
public ChestProperties deserialise(String[] values) throws ArrayIndexOutOfBoundsException
{
String name = values[0];
Material blockMaterial = Material.valueOf(values[1]);
String dataKey = values[2];
int minAmount = 1;
int maxAmount = 1;
String[] numbers = values[3].split("-");
if (numbers.length != 2)
{
minAmount = Integer.parseInt(String.valueOf(values[3]));
maxAmount = minAmount;
}
else
{
minAmount = Integer.parseInt(numbers[0]);
maxAmount = Integer.parseInt(numbers[1]);
}
int spawnRate = Integer.parseInt(values[4]);
int expireRate = Integer.parseInt(values[5]);
int spawnRadius = Integer.parseInt(values[6]);
double percentile = (double) Integer.parseInt(values.length > 7 ? values[7] : "0") / 100;
return new ChestProperties(name, blockMaterial, dataKey, minAmount, maxAmount, spawnRate, expireRate, spawnRadius, percentile);
}
}

View File

@ -0,0 +1,96 @@
package mineplex.gemhunters.loot.deserialisers;
import org.bukkit.Material;
import org.bukkit.enchantments.Enchantment;
import mineplex.core.google.SheetObjectDeserialiser;
import mineplex.core.itemstack.ItemBuilder;
import mineplex.gemhunters.loot.LootItem;
import net.md_5.bungee.api.ChatColor;
/**
* This is a {@link LootItem} deserialiser for Google Sheet interpretation.<br>
* <br>
* Arguments should follow the form:<br>
* <ul>
* <li>Material</li>
* <li>Material Data</li>
* <li>Max Durability</li>
* <li>Amount</li>
* <li>Item Name <i>(optional)</i></li>
* <li>Item Lore <i>(optional) each line separated by colons</i></li>
* <li>Enchantments <i>(optional) Has a NAME:LEVEL format with multiple
* enchantments being separated by commas</i></li>
* <li>Probability</li>
* <li>Metadata <i>(optional)</i></li>
* </ul>
* Thus derserialise is guaranteed to have at least 8 strings passed in.<br>
* If an illegal argument is passed in, derserialise will throw an exception,
* these should be handled by the caller.
*
* @see SheetObjectDeserialiser
*/
public class LootItemDeserialiser implements SheetObjectDeserialiser<LootItem>
{
@Override
public LootItem deserialise(String[] values) throws ArrayIndexOutOfBoundsException, IllegalArgumentException, NumberFormatException
{
Material material = Material.valueOf(values[0]);
byte data = values[1].equals("") ? 0 : Byte.parseByte(values[1]);
int minAmount = 1;
int maxAmount = 1;
short durability = values[2].equals("") ? 0 : Short.valueOf(values[3]);
String[] numbers = values[3].split("-");
if (numbers.length != 2)
{
minAmount = Integer.parseInt(values[3].equals("") ? "1" : values[3]);
maxAmount = minAmount;
}
else
{
minAmount = Integer.parseInt(numbers[0]);
maxAmount = Integer.parseInt(numbers[1]);
}
ItemBuilder builder = new ItemBuilder(material, data);
builder.setDurability(durability);
String title = ChatColor.translateAlternateColorCodes('&', values[4]);
String[] lore = values[5].split(":");
String[] colouredLore = new String[lore.length];
int loreIndex = 0;
for (String line : lore)
{
colouredLore[loreIndex++] = ChatColor.translateAlternateColorCodes('&', line);
}
builder.setTitle(title);
builder.setLore(colouredLore);
String[] enchants = String.valueOf(values[6]).split(",");
for (String enchant : enchants)
{
String[] enchantData = enchant.split(":");
if (enchantData.length < 2)
{
continue;
}
builder.addEnchantment(Enchantment.getByName(enchantData[0]), Integer.parseInt(enchantData[1]));
}
double proability = Double.parseDouble(values[7]);
String metadata = values.length > 8 ? values[8] : null;
return new LootItem(builder.build(), minAmount, maxAmount, proability, metadata);
}
}

View File

@ -192,7 +192,7 @@ public class SupplyDropModule extends MiniPlugin
} }
} }
_locationKeys = supplyDropKeys.toArray(new String[supplyDropKeys.size()]); _locationKeys = supplyDropKeys.toArray(new String[0]);
} }
return _locationKeys; return _locationKeys;