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.FileNotFoundException;
import java.io.FileReader;
import java.lang.reflect.Constructor;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.bukkit.Bukkit;
import com.google.gson.JsonArray;
import com.google.gson.JsonElement;
@ -33,20 +28,19 @@ public class GoogleSheetsManager extends MiniPlugin
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())
{
Bukkit.broadcastMessage("No file");
return null;
}
Map<String, Set<T>> valuesMap = new HashMap<>();
Map<String, List<List<String>>> valuesMap = new HashMap<>();
try
{
@ -54,18 +48,16 @@ public class GoogleSheetsManager extends MiniPlugin
JsonElement data = parser.parse(new FileReader(file));
JsonArray parent = data.getAsJsonObject().getAsJsonArray("data");
Bukkit.broadcastMessage("p=" + parent.size());
for (int i = 0; i < parent.size(); i++)
{
JsonObject sheet = parent.get(i).getAsJsonObject();
String name = sheet.get("name").getAsString();
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++)
{
List<Object> list = new ArrayList<>();
List<String> list = new ArrayList<>();
Iterator<JsonElement> iterator = values.get(j).getAsJsonArray().iterator();
while (iterator.hasNext())
@ -77,44 +69,13 @@ public class GoogleSheetsManager extends MiniPlugin
valuesList.add(list);
}
valuesMap.put(name, toSet(valuesList, clazz));
valuesMap.put(name, valuesList);
}
}
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;
}
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 Color _color;
private short _data;
private short _durability;
private final HashMap<Enchantment, Integer> _enchants = new HashMap<Enchantment, Integer>();
private final List<String> _lore = new ArrayList<String>();
private Material _mat;
@ -90,6 +91,7 @@ public class ItemBuilder
_itemFlags.addAll(meta.getItemFlags());
_unbreakable = meta.spigot().isUnbreakable();
_durability = item.getDurability();
}
}
@ -108,6 +110,7 @@ public class ItemBuilder
_mat = mat;
_amount = amount;
_data = data;
_durability = 0;
}
public ItemBuilder(Material mat, short data)
@ -115,6 +118,13 @@ public class ItemBuilder
this(mat, 1, data);
}
public ItemBuilder setDurability(short durability)
{
_durability = durability;
return this;
}
public HashSet<ItemFlag> getItemFlags()
{
return _itemFlags;
@ -278,6 +288,7 @@ public class ItemBuilder
item.addUnsafeEnchantments(_enchants);
if (_glow) item.addEnchantment(UtilInv.getDullEnchantment(), 1);
if (_durability != 0) item.setDurability(_durability);
return item;
}
@ -298,6 +309,7 @@ public class ItemBuilder
newBuilder.setColor(_color);
// newBuilder.potion = potion;
newBuilder.setDurability(_durability);
return newBuilder;
}

View File

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

View File

@ -17,7 +17,6 @@ import mineplex.core.ReflectivelyCreateMiniPlugin;
import mineplex.core.common.currency.GlobalCurrency;
import mineplex.core.common.util.F;
import mineplex.core.google.GoogleSheetsManager;
import mineplex.gemhunters.loot.LootItem;
@ReflectivelyCreateMiniPlugin
public class EconomyModule extends MiniPlugin
@ -87,8 +86,7 @@ public class EconomyModule extends MiniPlugin
{
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
{
private ItemStack _itemStack;
private int _minAmount;
private int _maxAmount;
private double _probability;
private String _metadata;
public LootItem(String... strings)
{
}
private final ItemStack _itemStack;
private final int _minAmount;
private final int _maxAmount;
private final double _probability;
private final String _metadata;
public LootItem(ItemStack itemStack, int minAmount, int maxAmount, double probability, String metadata)
{

View File

@ -1,6 +1,7 @@
package mineplex.gemhunters.loot;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
@ -19,7 +20,6 @@ import org.bukkit.block.BlockFace;
import org.bukkit.block.BlockState;
import org.bukkit.block.Chest;
import org.bukkit.block.DoubleChest;
import org.bukkit.enchantments.Enchantment;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.inventory.InventoryClickEvent;
@ -32,41 +32,49 @@ import mineplex.core.MiniPlugin;
import mineplex.core.ReflectivelyCreateMiniPlugin;
import mineplex.core.common.util.UtilAlg;
import mineplex.core.common.util.UtilBlock;
import mineplex.core.common.util.UtilFirework;
import mineplex.core.common.util.UtilMath;
import mineplex.core.common.util.UtilTime;
import mineplex.core.common.util.UtilWorld;
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.event.UpdateEvent;
import mineplex.gemhunters.economy.PlayerCashOutCompleteEvent;
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.LootRankReward;
import mineplex.gemhunters.safezone.SafezoneModule;
import mineplex.gemhunters.world.WorldDataModule;
import net.md_5.bungee.api.ChatColor;
@ReflectivelyCreateMiniPlugin
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 MAXIMUM_CHEST_ITEMS = 6;
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 float MAX_CHESTS_FACTOR = 0.25F;
private static final int MAX_SEARCH_ATTEMPTS = 40;
private static final int MAX_CHEST_PLACEMENT_RANGE = 10;
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 SafezoneModule _safezone;
private final WorldDataModule _worldData;
private final Map<String, Set<LootItem>> _chestLoot;
private final Map<String, ChestProperties> _chestProperties;
private final List<SpawnedChest> _spawnedChest;
private final Map<String, Set<Integer>> _spawnedIndexes;
private final Set<LootItemReward> _itemRewards;
@ -79,11 +87,12 @@ public class LootModule extends MiniPlugin
_safezone = require(SafezoneModule.class);
_worldData = require(WorldDataModule.class);
_chestLoot = new HashMap<>();
_chestProperties = new HashMap<>();
_spawnedChest = new ArrayList<>(200);
_spawnedIndexes = new HashMap<>(15);
_itemRewards = new HashSet<>();
//updateChestLoot();
runSyncLater(() -> updateChestLoot(), 20);
}
@Override
@ -95,7 +104,7 @@ public class LootModule extends MiniPlugin
@EventHandler
public void updateSpawnChests(UpdateEvent event)
{
if (event.getType() != UpdateType.SLOWER)
if (event.getType() != UpdateType.SEC)
{
return;
}
@ -106,12 +115,13 @@ public class LootModule extends MiniPlugin
while (iterator.hasNext())
{
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)
{
_spawnedIndexes.get(chest.getColour()).remove(chest.getID());
_spawnedIndexes.get(properties.getDataKey()).remove(chest.getID());
}
Block block = chest.getLocation().getBlock();
@ -128,7 +138,7 @@ public class LootModule extends MiniPlugin
}
// 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
// supply drops.
@ -141,24 +151,26 @@ public class LootModule extends MiniPlugin
}
List<Location> locations = _worldData.getDataLocation(key);
ChestProperties properties = _chestProperties.get(key);
// 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;
for (SpawnedChest chest : _spawnedChest)
{
if (chest.getColour().equals(key))
if (chest.getProperties().getDataKey().equals(key))
{
spawned++;
}
}
// TODO fix this
// If there are too many chests of this type we can ignore it
if (spawned > max)
{
continue;
}
// if (spawned > max)
// {
// continue;
// }
Set<Integer> usedIndexes = _spawnedIndexes.get(key);
@ -209,9 +221,8 @@ public class LootModule extends MiniPlugin
continue;
}
//TODO remove debug message
Bukkit.broadcastMessage("Spawned at " + UtilWorld.blockToStrClean(block) + " with key=" + key + " and index=" + index);
_spawnedChest.add(new SpawnedChest(chestToPlace, key, index));
Bukkit.broadcastMessage("Spawned at " + UtilWorld.blockToStrClean(block) + " with key=" + key + " and index=" + index + " and max=" + max);
_spawnedChest.add(new SpawnedChest(chestToPlace, properties, index));
block.setType(Material.CHEST);
}
}
@ -231,108 +242,75 @@ public class LootModule extends MiniPlugin
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())
{
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<>();
List<List<Object>> grid = map.get(key);
int index = 0;
int row = 0;
for (List<String> rows : map.get(key))
{
row++;
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;
}
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);
}
catch (Exception e)
{
// TODO send slack message?
e.printStackTrace();
log("An error occured while parsing spreadsheet data! " + key);
continue;
}
}
log("Finished updating chest loot");
}
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)
{
Set<Integer> used = new HashSet<>();
Set<LootItem> items = _chestLoot.get(key);
ChestProperties properties = _chestProperties.get(key);
int sizeMultiplier = 1;
BlockState state = block.getState();
@ -348,16 +326,17 @@ public class LootModule extends MiniPlugin
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);
ItemStack itemStack = lootItem.getItemStack();
int index = getFreeIndex(inventory.getSize(), used);
if (lootItem.getMetadata() != null)
{
UtilFirework.playFirework(block.getLocation().add(0.5, 1, 0.5), UtilFirework.getRandomFireworkEffect(false, 2, 1));
}
// if (lootItem.getMetadata() != null)
// {
// UtilFirework.playFirework(block.getLocation().add(0.5, 1, 0.5),
// UtilFirework.getRandomFireworkEffect(false, 2, 1));
// }
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)
{
key = chest.getColour();
key = chest.getProperties().getDataKey();
chest.setOpened();
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 String _colour;
private ChestProperties _properties;
private int _id;
private long _spawnedAt;
private long _openedAt;
public SpawnedChest(Location location, String colour, int id)
public SpawnedChest(Location location, ChestProperties properties, int id)
{
_location = location;
_colour = colour;
_properties =properties;
_id = id;
_spawnedAt = System.currentTimeMillis();
_openedAt = 0;
@ -31,9 +31,9 @@ public class SpawnedChest
return _location;
}
public String getColour()
public ChestProperties getProperties()
{
return _colour;
return _properties;
}
public int getID()

View File

@ -2,12 +2,10 @@ package mineplex.gemhunters.loot.command;
import org.bukkit.entity.Player;
import mineplex.core.Managers;
import mineplex.core.command.CommandBase;
import mineplex.core.common.Rank;
import mineplex.core.common.util.F;
import mineplex.gemhunters.loot.LootModule;
import mineplex.gemhunters.shop.ShopModule;
/**
* 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
}
caller.sendMessage(F.main(Plugin.getName(), "Updating loot tables asynchronusly..."));
final ShopModule shop = Managers.require(ShopModule.class);
Plugin.runAsync(() -> {
Plugin.updateChestLoot();
shop.updateVillagerLoot();
});
caller.sendMessage(F.main(Plugin.getName(), "Finished!"));
caller.sendMessage(F.main(Plugin.getName(), "This command is currently disabled due to development issues."));
}
}

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;