mirror of
https://github.com/PikaMug/Quests.git
synced 2025-02-15 03:51:22 +01:00
Add optional MySQL implementation, part 1. See #312
This commit is contained in:
parent
6d5d3deff6
commit
ce9b24fe3a
@ -13,7 +13,6 @@
|
|||||||
package me.blackvein.quests;
|
package me.blackvein.quests;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.IOException;
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.Comparator;
|
import java.util.Comparator;
|
||||||
@ -36,7 +35,6 @@ import org.bukkit.Location;
|
|||||||
import org.bukkit.Material;
|
import org.bukkit.Material;
|
||||||
import org.bukkit.OfflinePlayer;
|
import org.bukkit.OfflinePlayer;
|
||||||
import org.bukkit.configuration.ConfigurationSection;
|
import org.bukkit.configuration.ConfigurationSection;
|
||||||
import org.bukkit.configuration.InvalidConfigurationException;
|
|
||||||
import org.bukkit.configuration.file.FileConfiguration;
|
import org.bukkit.configuration.file.FileConfiguration;
|
||||||
import org.bukkit.configuration.file.YamlConfiguration;
|
import org.bukkit.configuration.file.YamlConfiguration;
|
||||||
import org.bukkit.conversations.Conversable;
|
import org.bukkit.conversations.Conversable;
|
||||||
@ -61,6 +59,7 @@ import me.blackvein.quests.events.quest.QuestTakeEvent;
|
|||||||
import me.blackvein.quests.events.quester.QuesterPostStartQuestEvent;
|
import me.blackvein.quests.events.quester.QuesterPostStartQuestEvent;
|
||||||
import me.blackvein.quests.events.quester.QuesterPreOpenGUIEvent;
|
import me.blackvein.quests.events.quester.QuesterPreOpenGUIEvent;
|
||||||
import me.blackvein.quests.events.quester.QuesterPreStartQuestEvent;
|
import me.blackvein.quests.events.quester.QuesterPreStartQuestEvent;
|
||||||
|
import me.blackvein.quests.storage.Storage;
|
||||||
import me.blackvein.quests.tasks.StageTimer;
|
import me.blackvein.quests.tasks.StageTimer;
|
||||||
import me.blackvein.quests.util.ConfigUtil;
|
import me.blackvein.quests.util.ConfigUtil;
|
||||||
import me.blackvein.quests.util.InventoryUtil;
|
import me.blackvein.quests.util.InventoryUtil;
|
||||||
@ -2833,14 +2832,13 @@ public class Quester implements Comparable<Quester> {
|
|||||||
* @return true if successful
|
* @return true if successful
|
||||||
*/
|
*/
|
||||||
public boolean saveData() {
|
public boolean saveData() {
|
||||||
final FileConfiguration data = getBaseData();
|
|
||||||
try {
|
try {
|
||||||
data.save(new File(plugin.getDataFolder(), "data" + File.separator + id + ".yml"));
|
final Storage storage = plugin.getStorage();
|
||||||
return true;
|
storage.saveQuesterData(this);
|
||||||
} catch (final IOException e) {
|
} catch (final Exception e) {
|
||||||
e.printStackTrace();
|
return false;
|
||||||
}
|
}
|
||||||
return false;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -3200,7 +3198,7 @@ public class Quester implements Comparable<Quester> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Check whether data file for this Quester exists
|
* Get data file for this Quester
|
||||||
*
|
*
|
||||||
* @return file if exists, otherwise null
|
* @return file if exists, otherwise null
|
||||||
*/
|
*/
|
||||||
@ -3221,386 +3219,8 @@ public class Quester implements Comparable<Quester> {
|
|||||||
*
|
*
|
||||||
* @return true if successful
|
* @return true if successful
|
||||||
*/
|
*/
|
||||||
@SuppressWarnings("deprecation")
|
|
||||||
public boolean loadData() {
|
public boolean loadData() {
|
||||||
final FileConfiguration data = new YamlConfiguration();
|
return plugin.getStorage().loadQuesterData(id) != null;
|
||||||
try {
|
|
||||||
final File dataFile = getDataFile();
|
|
||||||
if (dataFile != null) {
|
|
||||||
data.load(dataFile);
|
|
||||||
} else {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
} catch (final IOException e) {
|
|
||||||
return false;
|
|
||||||
} catch (final InvalidConfigurationException e) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
hardClear();
|
|
||||||
if (data.contains("completedRedoableQuests")) {
|
|
||||||
final List<String> redoNames = data.getStringList("completedRedoableQuests");
|
|
||||||
final List<Long> redoTimes = data.getLongList("completedQuestTimes");
|
|
||||||
for (final String s : redoNames) {
|
|
||||||
for (final Quest q : plugin.getQuests()) {
|
|
||||||
if (q.getName().equalsIgnoreCase(s)) {
|
|
||||||
completedTimes.put(q.getName(), redoTimes.get(redoNames.indexOf(s)));
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (data.contains("amountsCompletedQuests")) {
|
|
||||||
final List<String> list1 = data.getStringList("amountsCompletedQuests");
|
|
||||||
final List<Integer> list2 = data.getIntegerList("amountsCompleted");
|
|
||||||
for (int i = 0; i < list1.size(); i++) {
|
|
||||||
amountsCompleted.put(list1.get(i), list2.get(i));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
questPoints = data.getInt("quest-points");
|
|
||||||
hasJournal = data.getBoolean("hasJournal");
|
|
||||||
if (data.isList("completed-Quests")) {
|
|
||||||
for (final String s : data.getStringList("completed-Quests")) {
|
|
||||||
for (final Quest q : plugin.getQuests()) {
|
|
||||||
if (q.getName().equalsIgnoreCase(s)) {
|
|
||||||
if (!completedQuests.contains(q.getName())) {
|
|
||||||
completedQuests.add(q.getName());
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
completedQuests.clear();
|
|
||||||
}
|
|
||||||
if (data.isString("currentQuests") == false) {
|
|
||||||
final List<String> questNames = data.getStringList("currentQuests");
|
|
||||||
final List<Integer> questStages = data.getIntegerList("currentStages");
|
|
||||||
// These appear to differ sometimes? That seems bad.
|
|
||||||
final int maxSize = Math.min(questNames.size(), questStages.size());
|
|
||||||
for (int i = 0; i < maxSize; i++) {
|
|
||||||
if (plugin.getQuest(questNames.get(i)) != null) {
|
|
||||||
currentQuests.put(plugin.getQuest(questNames.get(i)), questStages.get(i));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
final ConfigurationSection dataSec = data.getConfigurationSection("questData");
|
|
||||||
if (dataSec == null || dataSec.getKeys(false).isEmpty()) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
for (final String key : dataSec.getKeys(false)) {
|
|
||||||
final ConfigurationSection questSec = dataSec.getConfigurationSection(key);
|
|
||||||
final Quest quest = plugin.getQuest(key);
|
|
||||||
Stage stage;
|
|
||||||
if (quest == null || currentQuests.containsKey(quest) == false) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
stage = getCurrentStage(quest);
|
|
||||||
if (stage == null) {
|
|
||||||
quest.completeQuest(this);
|
|
||||||
plugin.getLogger().severe("[Quests] Invalid stage number for player: \"" + id + "\" on Quest \""
|
|
||||||
+ quest.getName() + "\". Quest ended.");
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
addEmptiesFor(quest, currentQuests.get(quest));
|
|
||||||
if (questSec == null)
|
|
||||||
continue;
|
|
||||||
if (questSec.contains("blocks-broken-names")) {
|
|
||||||
final List<String> names = questSec.getStringList("blocks-broken-names");
|
|
||||||
final List<Integer> amounts = questSec.getIntegerList("blocks-broken-amounts");
|
|
||||||
final List<Short> durability = questSec.getShortList("blocks-broken-durability");
|
|
||||||
int index = 0;
|
|
||||||
for (final String s : names) {
|
|
||||||
ItemStack is;
|
|
||||||
try {
|
|
||||||
is = new ItemStack(Material.matchMaterial(s), amounts.get(index), durability.get(index));
|
|
||||||
} catch (final IndexOutOfBoundsException e) {
|
|
||||||
// Legacy
|
|
||||||
is = new ItemStack(Material.matchMaterial(s), amounts.get(index), (short) 0);
|
|
||||||
}
|
|
||||||
if (getQuestData(quest).blocksBroken.size() > 0) {
|
|
||||||
getQuestData(quest).blocksBroken.set(index, is);
|
|
||||||
}
|
|
||||||
index++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (questSec.contains("blocks-damaged-names")) {
|
|
||||||
final List<String> names = questSec.getStringList("blocks-damaged-names");
|
|
||||||
final List<Integer> amounts = questSec.getIntegerList("blocks-damaged-amounts");
|
|
||||||
final List<Short> durability = questSec.getShortList("blocks-damaged-durability");
|
|
||||||
int index = 0;
|
|
||||||
for (final String s : names) {
|
|
||||||
ItemStack is;
|
|
||||||
try {
|
|
||||||
is = new ItemStack(Material.matchMaterial(s), amounts.get(index), durability.get(index));
|
|
||||||
} catch (final IndexOutOfBoundsException e) {
|
|
||||||
// Legacy
|
|
||||||
is = new ItemStack(Material.matchMaterial(s), amounts.get(index), (short) 0);
|
|
||||||
}
|
|
||||||
if (getQuestData(quest).blocksDamaged.size() > 0) {
|
|
||||||
getQuestData(quest).blocksDamaged.set(index, is);
|
|
||||||
}
|
|
||||||
index++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (questSec.contains("blocks-placed-names")) {
|
|
||||||
final List<String> names = questSec.getStringList("blocks-placed-names");
|
|
||||||
final List<Integer> amounts = questSec.getIntegerList("blocks-placed-amounts");
|
|
||||||
final List<Short> durability = questSec.getShortList("blocks-placed-durability");
|
|
||||||
int index = 0;
|
|
||||||
for (final String s : names) {
|
|
||||||
ItemStack is;
|
|
||||||
try {
|
|
||||||
is = new ItemStack(Material.matchMaterial(s), amounts.get(index), durability.get(index));
|
|
||||||
} catch (final IndexOutOfBoundsException e) {
|
|
||||||
// Legacy
|
|
||||||
is = new ItemStack(Material.matchMaterial(s), amounts.get(index), (short) 0);
|
|
||||||
}
|
|
||||||
if (getQuestData(quest).blocksPlaced.size() > 0) {
|
|
||||||
getQuestData(quest).blocksPlaced.set(index, is);
|
|
||||||
}
|
|
||||||
index++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (questSec.contains("blocks-used-names")) {
|
|
||||||
final List<String> names = questSec.getStringList("blocks-used-names");
|
|
||||||
final List<Integer> amounts = questSec.getIntegerList("blocks-used-amounts");
|
|
||||||
final List<Short> durability = questSec.getShortList("blocks-used-durability");
|
|
||||||
int index = 0;
|
|
||||||
for (final String s : names) {
|
|
||||||
ItemStack is;
|
|
||||||
try {
|
|
||||||
is = new ItemStack(Material.matchMaterial(s), amounts.get(index), durability.get(index));
|
|
||||||
} catch (final IndexOutOfBoundsException e) {
|
|
||||||
// Legacy
|
|
||||||
is = new ItemStack(Material.matchMaterial(s), amounts.get(index), (short) 0);
|
|
||||||
}
|
|
||||||
if (getQuestData(quest).blocksUsed.size() > 0) {
|
|
||||||
getQuestData(quest).blocksUsed.set(index, is);
|
|
||||||
}
|
|
||||||
index++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (questSec.contains("blocks-cut-names")) {
|
|
||||||
final List<String> names = questSec.getStringList("blocks-cut-names");
|
|
||||||
final List<Integer> amounts = questSec.getIntegerList("blocks-cut-amounts");
|
|
||||||
final List<Short> durability = questSec.getShortList("blocks-cut-durability");
|
|
||||||
int index = 0;
|
|
||||||
for (final String s : names) {
|
|
||||||
ItemStack is;
|
|
||||||
try {
|
|
||||||
is = new ItemStack(Material.matchMaterial(s), amounts.get(index), durability.get(index));
|
|
||||||
} catch (final IndexOutOfBoundsException e) {
|
|
||||||
// Legacy
|
|
||||||
is = new ItemStack(Material.matchMaterial(s), amounts.get(index), (short) 0);
|
|
||||||
}
|
|
||||||
if (getQuestData(quest).blocksCut.size() > 0) {
|
|
||||||
getQuestData(quest).blocksCut.set(index, is);
|
|
||||||
}
|
|
||||||
index++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (questSec.contains("item-craft-amounts")) {
|
|
||||||
final List<Integer> craftAmounts = questSec.getIntegerList("item-craft-amounts");
|
|
||||||
for (int i = 0; i < craftAmounts.size(); i++) {
|
|
||||||
if (i < getCurrentStage(quest).itemsToCraft.size()) {
|
|
||||||
getQuestData(quest).itemsCrafted.put(getCurrentStage(quest).itemsToCraft
|
|
||||||
.get(i), craftAmounts.get(i));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (questSec.contains("item-smelt-amounts")) {
|
|
||||||
final List<Integer> smeltAmounts = questSec.getIntegerList("item-smelt-amounts");
|
|
||||||
for (int i = 0; i < smeltAmounts.size(); i++) {
|
|
||||||
if (i < getCurrentStage(quest).itemsToSmelt.size()) {
|
|
||||||
getQuestData(quest).itemsSmelted.put(getCurrentStage(quest).itemsToSmelt
|
|
||||||
.get(i), smeltAmounts.get(i));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (questSec.contains("item-enchant-amounts")) {
|
|
||||||
final List<Integer> enchantAmounts = questSec.getIntegerList("item-enchant-amounts");
|
|
||||||
for (int i = 0; i < enchantAmounts.size(); i++) {
|
|
||||||
if (i < getCurrentStage(quest).itemsToEnchant.size()) {
|
|
||||||
getQuestData(quest).itemsEnchanted.put(getCurrentStage(quest).itemsToEnchant
|
|
||||||
.get(i), enchantAmounts.get(i));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (questSec.contains("item-brew-amounts")) {
|
|
||||||
final List<Integer> brewAmounts = questSec.getIntegerList("item-brew-amounts");
|
|
||||||
for (int i = 0; i < brewAmounts.size(); i++) {
|
|
||||||
if (i < getCurrentStage(quest).itemsToBrew.size()) {
|
|
||||||
getQuestData(quest).itemsBrewed.put(getCurrentStage(quest).itemsToBrew
|
|
||||||
.get(i), brewAmounts.get(i));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (questSec.contains("item-consume-amounts")) {
|
|
||||||
final List<Integer> consumeAmounts = questSec.getIntegerList("item-consume-amounts");
|
|
||||||
for (int i = 0; i < consumeAmounts.size(); i++) {
|
|
||||||
if (i < getCurrentStage(quest).itemsToConsume.size()) {
|
|
||||||
getQuestData(quest).itemsConsumed.put(getCurrentStage(quest).itemsToConsume
|
|
||||||
.get(i), consumeAmounts.get(i));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (questSec.contains("cows-milked")) {
|
|
||||||
getQuestData(quest).setCowsMilked(questSec.getInt("cows-milked"));
|
|
||||||
}
|
|
||||||
if (questSec.contains("fish-caught")) {
|
|
||||||
getQuestData(quest).setFishCaught(questSec.getInt("fish-caught"));
|
|
||||||
}
|
|
||||||
if (questSec.contains("players-killed")) {
|
|
||||||
getQuestData(quest).setPlayersKilled(questSec.getInt("players-killed"));
|
|
||||||
}
|
|
||||||
if (questSec.contains("mobs-killed")) {
|
|
||||||
final LinkedList<EntityType> mobs = new LinkedList<EntityType>();
|
|
||||||
final List<Integer> amounts = questSec.getIntegerList("mobs-killed-amounts");
|
|
||||||
for (final String s : questSec.getStringList("mobs-killed")) {
|
|
||||||
final EntityType mob = MiscUtil.getProperMobType(s);
|
|
||||||
if (mob != null) {
|
|
||||||
mobs.add(mob);
|
|
||||||
}
|
|
||||||
getQuestData(quest).mobsKilled.clear();
|
|
||||||
getQuestData(quest).mobNumKilled.clear();
|
|
||||||
for (final EntityType e : mobs) {
|
|
||||||
getQuestData(quest).mobsKilled.add(e);
|
|
||||||
getQuestData(quest).mobNumKilled.add(amounts.get(mobs.indexOf(e)));
|
|
||||||
}
|
|
||||||
if (questSec.contains("mob-kill-locations")) {
|
|
||||||
final LinkedList<Location> locations = new LinkedList<Location>();
|
|
||||||
final List<Integer> radii = questSec.getIntegerList("mob-kill-location-radii");
|
|
||||||
for (final String loc : questSec.getStringList("mob-kill-locations")) {
|
|
||||||
if (ConfigUtil.getLocation(loc) != null) {
|
|
||||||
locations.add(ConfigUtil.getLocation(loc));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
getQuestData(quest).locationsToKillWithin = locations;
|
|
||||||
getQuestData(quest).radiiToKillWithin.clear();
|
|
||||||
for (final int i : radii) {
|
|
||||||
getQuestData(quest).radiiToKillWithin.add(i);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (questSec.contains("item-delivery-amounts")) {
|
|
||||||
final List<Integer> deliveryAmounts = questSec.getIntegerList("item-delivery-amounts");
|
|
||||||
int index = 0;
|
|
||||||
for (final int amt : deliveryAmounts) {
|
|
||||||
final ItemStack is = getCurrentStage(quest).itemsToDeliver.get(index);
|
|
||||||
final ItemStack temp = new ItemStack(is.getType(), amt, is.getDurability());
|
|
||||||
try {
|
|
||||||
temp.addEnchantments(is.getEnchantments());
|
|
||||||
} catch (final Exception e) {
|
|
||||||
plugin.getLogger().warning("Unable to add enchantment(s) " + is.getEnchantments().toString()
|
|
||||||
+ " to delivery item " + is.getType().name() + " x " + amt + " for quest "
|
|
||||||
+ quest.getName());
|
|
||||||
}
|
|
||||||
temp.setItemMeta(is.getItemMeta());
|
|
||||||
if (getQuestData(quest).itemsDelivered.size() > 0) {
|
|
||||||
getQuestData(quest).itemsDelivered.set(index, temp);
|
|
||||||
}
|
|
||||||
index++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (questSec.contains("citizen-ids-to-talk-to")) {
|
|
||||||
final List<Integer> ids = questSec.getIntegerList("citizen-ids-to-talk-to");
|
|
||||||
final List<Boolean> has = questSec.getBooleanList("has-talked-to");
|
|
||||||
for (final int i : ids) {
|
|
||||||
getQuestData(quest).citizensInteracted.put(i, has.get(ids.indexOf(i)));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (questSec.contains("citizen-ids-killed")) {
|
|
||||||
final List<Integer> ids = questSec.getIntegerList("citizen-ids-killed");
|
|
||||||
final List<Integer> num = questSec.getIntegerList("citizen-amounts-killed");
|
|
||||||
getQuestData(quest).citizensKilled.clear();
|
|
||||||
getQuestData(quest).citizenNumKilled.clear();
|
|
||||||
for (final int i : ids) {
|
|
||||||
getQuestData(quest).citizensKilled.add(i);
|
|
||||||
getQuestData(quest).citizenNumKilled.add(num.get(ids.indexOf(i)));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (questSec.contains("locations-to-reach")) {
|
|
||||||
final LinkedList<Location> locations = new LinkedList<Location>();
|
|
||||||
final List<Boolean> has = questSec.getBooleanList("has-reached-location");
|
|
||||||
while (has.size() < locations.size()) {
|
|
||||||
// TODO - Find proper cause of Github issues #646 and #825
|
|
||||||
plugin.getLogger().info("Added missing has-reached-location data for Quester " + id);
|
|
||||||
has.add(false);
|
|
||||||
}
|
|
||||||
final List<Integer> radii = questSec.getIntegerList("radii-to-reach-within");
|
|
||||||
for (final String loc : questSec.getStringList("locations-to-reach")) {
|
|
||||||
if (ConfigUtil.getLocation(loc) != null) {
|
|
||||||
locations.add(ConfigUtil.getLocation(loc));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
getQuestData(quest).locationsReached = locations;
|
|
||||||
getQuestData(quest).hasReached.clear();
|
|
||||||
getQuestData(quest).radiiToReachWithin.clear();
|
|
||||||
for (final boolean b : has) {
|
|
||||||
getQuestData(quest).hasReached.add(b);
|
|
||||||
}
|
|
||||||
for (final int i : radii) {
|
|
||||||
getQuestData(quest).radiiToReachWithin.add(i);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (questSec.contains("mobs-to-tame")) {
|
|
||||||
final List<String> mobs = questSec.getStringList("mobs-to-tame");
|
|
||||||
final List<Integer> amounts = questSec.getIntegerList("mob-tame-amounts");
|
|
||||||
for (final String mob : mobs) {
|
|
||||||
getQuestData(quest).mobsTamed.put(EntityType.valueOf(mob.toUpperCase()), amounts
|
|
||||||
.get(mobs.indexOf(mob)));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (questSec.contains("sheep-to-shear")) {
|
|
||||||
final List<String> colors = questSec.getStringList("sheep-to-shear");
|
|
||||||
final List<Integer> amounts = questSec.getIntegerList("sheep-sheared");
|
|
||||||
for (final String color : colors) {
|
|
||||||
getQuestData(quest).sheepSheared.put(MiscUtil.getProperDyeColor(color), amounts.get(colors
|
|
||||||
.indexOf(color)));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (questSec.contains("passwords")) {
|
|
||||||
final List<String> passwords = questSec.getStringList("passwords");
|
|
||||||
final List<Boolean> said = questSec.getBooleanList("passwords-said");
|
|
||||||
for (int i = 0; i < passwords.size(); i++) {
|
|
||||||
getQuestData(quest).passwordsSaid.put(passwords.get(i), said.get(i));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (questSec.contains("custom-objectives")) {
|
|
||||||
final List<String> customObj = questSec.getStringList("custom-objectives");
|
|
||||||
final List<Integer> customObjCount = questSec.getIntegerList("custom-objective-counts");
|
|
||||||
for (int i = 0; i < customObj.size(); i++) {
|
|
||||||
getQuestData(quest).customObjectiveCounts.put(customObj.get(i), customObjCount.get(i));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (questSec.contains("stage-delay")) {
|
|
||||||
getQuestData(quest).setDelayTimeLeft(questSec.getLong("stage-delay"));
|
|
||||||
}
|
|
||||||
if (getCurrentStage(quest).chatActions.isEmpty() == false) {
|
|
||||||
for (final String chatTrig : getCurrentStage(quest).chatActions.keySet()) {
|
|
||||||
getQuestData(quest).actionFired.put(chatTrig, false);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (questSec.contains("chat-triggers")) {
|
|
||||||
final List<String> chatTriggers = questSec.getStringList("chat-triggers");
|
|
||||||
for (final String s : chatTriggers) {
|
|
||||||
getQuestData(quest).actionFired.put(s, true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (getCurrentStage(quest).commandActions.isEmpty() == false) {
|
|
||||||
for (final String commandTrig : getCurrentStage(quest).commandActions.keySet()) {
|
|
||||||
getQuestData(quest).actionFired.put(commandTrig, false);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (questSec.contains("command-triggers")) {
|
|
||||||
final List<String> commandTriggers = questSec.getStringList("command-triggers");
|
|
||||||
for (final String s : commandTriggers) {
|
|
||||||
getQuestData(quest).actionFired.put(s, true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -95,6 +95,8 @@ import me.blackvein.quests.listeners.ItemListener;
|
|||||||
import me.blackvein.quests.listeners.NpcListener;
|
import me.blackvein.quests.listeners.NpcListener;
|
||||||
import me.blackvein.quests.listeners.PartiesListener;
|
import me.blackvein.quests.listeners.PartiesListener;
|
||||||
import me.blackvein.quests.listeners.PlayerListener;
|
import me.blackvein.quests.listeners.PlayerListener;
|
||||||
|
import me.blackvein.quests.storage.Storage;
|
||||||
|
import me.blackvein.quests.storage.StorageFactory;
|
||||||
import me.blackvein.quests.tasks.NpcEffectThread;
|
import me.blackvein.quests.tasks.NpcEffectThread;
|
||||||
import me.blackvein.quests.tasks.PlayerMoveThread;
|
import me.blackvein.quests.tasks.PlayerMoveThread;
|
||||||
import me.blackvein.quests.util.ConfigUtil;
|
import me.blackvein.quests.util.ConfigUtil;
|
||||||
@ -136,6 +138,7 @@ public class Quests extends JavaPlugin implements ConversationAbandonedListener
|
|||||||
private PartiesListener partiesListener;
|
private PartiesListener partiesListener;
|
||||||
private DenizenTrigger trigger;
|
private DenizenTrigger trigger;
|
||||||
private LocaleQuery localeQuery;
|
private LocaleQuery localeQuery;
|
||||||
|
private Storage storage;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onEnable() {
|
public void onEnable() {
|
||||||
@ -186,6 +189,8 @@ public class Quests extends JavaPlugin implements ConversationAbandonedListener
|
|||||||
// 7 - Save config with any new options
|
// 7 - Save config with any new options
|
||||||
getConfig().options().copyDefaults(true);
|
getConfig().options().copyDefaults(true);
|
||||||
saveConfig();
|
saveConfig();
|
||||||
|
final StorageFactory storageFactory = new StorageFactory(this);
|
||||||
|
storage = storageFactory.getInstance();
|
||||||
|
|
||||||
// 8 - Setup commands
|
// 8 - Setup commands
|
||||||
getCommand("quests").setExecutor(cmdExecutor);
|
getCommand("quests").setExecutor(cmdExecutor);
|
||||||
@ -418,6 +423,10 @@ public class Quests extends JavaPlugin implements ConversationAbandonedListener
|
|||||||
public LocaleQuery getLocaleQuery() {
|
public LocaleQuery getLocaleQuery() {
|
||||||
return localeQuery;
|
return localeQuery;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Storage getStorage() {
|
||||||
|
return storage;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void conversationAbandoned(final ConversationAbandonedEvent abandonedEvent) {
|
public void conversationAbandoned(final ConversationAbandonedEvent abandonedEvent) {
|
||||||
|
@ -1380,7 +1380,7 @@ public class CmdExecutor implements CommandExecutor {
|
|||||||
}
|
}
|
||||||
final UUID id = target.getUniqueId();
|
final UUID id = target.getUniqueId();
|
||||||
final ConcurrentSkipListSet<Quester> temp = (ConcurrentSkipListSet<Quester>) plugin.getOfflineQuesters();
|
final ConcurrentSkipListSet<Quester> temp = (ConcurrentSkipListSet<Quester>) plugin.getOfflineQuesters();
|
||||||
for(final Iterator<Quester> itr = temp.iterator(); itr.hasNext();) {
|
for (final Iterator<Quester> itr = temp.iterator(); itr.hasNext();) {
|
||||||
if (itr.next().getUUID().equals(id)) {
|
if (itr.next().getUUID().equals(id)) {
|
||||||
itr.remove();
|
itr.remove();
|
||||||
}
|
}
|
||||||
|
121
main/src/main/java/me/blackvein/quests/storage/Storage.java
Normal file
121
main/src/main/java/me/blackvein/quests/storage/Storage.java
Normal file
@ -0,0 +1,121 @@
|
|||||||
|
/*******************************************************************************************************
|
||||||
|
* Continued by PikaMug (formerly HappyPikachu) with permission from _Blackvein_. All rights reserved.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
||||||
|
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
|
||||||
|
* NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||||
|
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||||
|
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
|
||||||
|
* OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||||
|
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*******************************************************************************************************/
|
||||||
|
|
||||||
|
package me.blackvein.quests.storage;
|
||||||
|
|
||||||
|
import java.util.Collection;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.UUID;
|
||||||
|
import java.util.concurrent.Callable;
|
||||||
|
import java.util.concurrent.CompletableFuture;
|
||||||
|
import java.util.concurrent.CompletionException;
|
||||||
|
|
||||||
|
import me.blackvein.quests.Quester;
|
||||||
|
import me.blackvein.quests.Quests;
|
||||||
|
import me.blackvein.quests.storage.implementation.StorageImplementation;
|
||||||
|
|
||||||
|
public class Storage {
|
||||||
|
private final Quests plugin;
|
||||||
|
private final StorageImplementation implementation;
|
||||||
|
|
||||||
|
public Storage(final Quests plugin, final StorageImplementation implementation) {
|
||||||
|
this.plugin = plugin;
|
||||||
|
this.implementation = implementation;
|
||||||
|
}
|
||||||
|
|
||||||
|
public StorageImplementation getImplementation() {
|
||||||
|
return implementation;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Collection<StorageImplementation> getImplementations() {
|
||||||
|
return Collections.singleton(implementation);
|
||||||
|
}
|
||||||
|
|
||||||
|
private <T> CompletableFuture<T> makeFuture(final Callable<T> supplier) {
|
||||||
|
return CompletableFuture.supplyAsync(() -> {
|
||||||
|
try {
|
||||||
|
return supplier.call();
|
||||||
|
} catch (final Exception e) {
|
||||||
|
if (e instanceof RuntimeException) {
|
||||||
|
throw (RuntimeException) e;
|
||||||
|
}
|
||||||
|
throw new CompletionException(e);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private CompletableFuture<Void> makeFuture(final Runnable runnable) {
|
||||||
|
return CompletableFuture.runAsync(() -> {
|
||||||
|
try {
|
||||||
|
runnable.run();
|
||||||
|
} catch (final Exception e) {
|
||||||
|
if (e instanceof RuntimeException) {
|
||||||
|
throw (RuntimeException) e;
|
||||||
|
}
|
||||||
|
throw new CompletionException(e);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getName() {
|
||||||
|
return implementation.getImplementationName();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void init() {
|
||||||
|
try {
|
||||||
|
implementation.init();
|
||||||
|
} catch (final Exception e) {
|
||||||
|
plugin.getLogger().severe("Failed to initialize storage implementation");
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void close() {
|
||||||
|
try {
|
||||||
|
implementation.close();
|
||||||
|
} catch (final Exception e) {
|
||||||
|
plugin.getLogger().severe("Failed to close storage implementation");
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public CompletableFuture<Quester> loadQuesterData(final UUID uniqueId) {
|
||||||
|
return makeFuture(() -> {
|
||||||
|
final Quester quester = implementation.loadQuesterData(uniqueId);
|
||||||
|
return quester;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public CompletableFuture<Void> saveQuesterData(final Quester quester) {
|
||||||
|
return makeFuture(() -> {
|
||||||
|
try {
|
||||||
|
implementation.saveQuesterData(quester);
|
||||||
|
} catch (final Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public CompletableFuture<Void> deletePlayerData(final UUID uniqueId) {
|
||||||
|
return makeFuture(() -> {
|
||||||
|
try {
|
||||||
|
implementation.deleteQuesterData(uniqueId);
|
||||||
|
} catch (final Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public CompletableFuture<String> getQuesterLastKnownName(final UUID uniqueId) {
|
||||||
|
return makeFuture(() -> implementation.getQuesterLastKnownName(uniqueId));
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,84 @@
|
|||||||
|
/*******************************************************************************************************
|
||||||
|
* Continued by PikaMug (formerly HappyPikachu) with permission from _Blackvein_. All rights reserved.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
||||||
|
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
|
||||||
|
* NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||||
|
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||||
|
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
|
||||||
|
* OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||||
|
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*******************************************************************************************************/
|
||||||
|
|
||||||
|
package me.blackvein.quests.storage;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
import org.bukkit.configuration.file.FileConfiguration;
|
||||||
|
|
||||||
|
import com.google.common.collect.ImmutableSet;
|
||||||
|
|
||||||
|
import me.blackvein.quests.Quests;
|
||||||
|
import me.blackvein.quests.storage.implementation.StorageImplementation;
|
||||||
|
import me.blackvein.quests.storage.implementation.custom.CustomStorageProviders;
|
||||||
|
import me.blackvein.quests.storage.implementation.file.SeparatedYamlStorage;
|
||||||
|
import me.blackvein.quests.storage.implementation.sql.SqlStorage;
|
||||||
|
import me.blackvein.quests.storage.implementation.sql.connection.hikari.MySqlConnectionFactory;
|
||||||
|
import me.blackvein.quests.storage.misc.StorageCredentials;
|
||||||
|
|
||||||
|
public class StorageFactory {
|
||||||
|
private final Quests plugin;
|
||||||
|
|
||||||
|
public StorageFactory(final Quests plugin) {
|
||||||
|
this.plugin = plugin;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Set<StorageType> getRequiredTypes() {
|
||||||
|
return ImmutableSet.of(StorageType.parse(plugin.getConfig().getString("storage-method", "yaml"), StorageType.YAML));
|
||||||
|
}
|
||||||
|
|
||||||
|
public Storage getInstance() {
|
||||||
|
Storage storage;
|
||||||
|
|
||||||
|
final StorageType type = StorageType.parse(plugin.getConfig().getString("storage-method", "yaml"), StorageType.YAML);
|
||||||
|
plugin.getLogger().info("Loading storage implementation: " + type.name());
|
||||||
|
storage = new Storage(plugin, createNewImplementation(type));
|
||||||
|
|
||||||
|
storage.init();
|
||||||
|
return storage;
|
||||||
|
}
|
||||||
|
|
||||||
|
private StorageImplementation createNewImplementation(final StorageType method) {
|
||||||
|
switch (method) {
|
||||||
|
case CUSTOM:
|
||||||
|
return CustomStorageProviders.getProvider().provide(plugin);
|
||||||
|
case MYSQL:
|
||||||
|
return new SqlStorage(
|
||||||
|
plugin,
|
||||||
|
new MySqlConnectionFactory(getDatabaseValues(plugin.getConfig())),
|
||||||
|
plugin.getConfig().getString("storage-data.table_prefix")
|
||||||
|
);
|
||||||
|
case YAML:
|
||||||
|
return new SeparatedYamlStorage(plugin, plugin.getDataFolder() + File.separator + "data");
|
||||||
|
default:
|
||||||
|
throw new RuntimeException("Unknown method: " + method);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private StorageCredentials getDatabaseValues(final FileConfiguration fc) {
|
||||||
|
final int maxPoolSize = fc.getInt("storage-data.pool-settings.max-pool-size", fc.getInt("storage-data.pool-size", 10));
|
||||||
|
final int minIdle = fc.getInt("storage-data.pool-settings.min-idle", maxPoolSize);
|
||||||
|
final int maxLifetime = fc.getInt("storage-data.pool-settings.max-lifetime", 1800000);
|
||||||
|
final int connectionTimeout = fc.getInt("storage-data.pool-settings.connection-timeout", 5000);
|
||||||
|
|
||||||
|
return new StorageCredentials(
|
||||||
|
fc.getString("storage-data.address", null),
|
||||||
|
fc.getString("storage-data.database", null),
|
||||||
|
fc.getString("storage-data.username", null),
|
||||||
|
fc.getString("storage-data.password", null),
|
||||||
|
maxPoolSize, minIdle, maxLifetime, connectionTimeout, Collections.singletonMap("true", "utf8")
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,57 @@
|
|||||||
|
/*******************************************************************************************************
|
||||||
|
* Continued by PikaMug (formerly HappyPikachu) with permission from _Blackvein_. All rights reserved.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
||||||
|
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
|
||||||
|
* NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||||
|
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||||
|
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
|
||||||
|
* OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||||
|
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*******************************************************************************************************/
|
||||||
|
|
||||||
|
package me.blackvein.quests.storage;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import com.google.common.collect.ImmutableList;
|
||||||
|
|
||||||
|
public enum StorageType {
|
||||||
|
|
||||||
|
// Local file
|
||||||
|
YAML("YAML", "yaml", "yml"),
|
||||||
|
|
||||||
|
// Remote database
|
||||||
|
MYSQL("MySQL", "mysql"),
|
||||||
|
|
||||||
|
// Custom
|
||||||
|
CUSTOM("Custom", "custom");
|
||||||
|
|
||||||
|
private final String name;
|
||||||
|
|
||||||
|
private final List<String> identifiers;
|
||||||
|
|
||||||
|
StorageType(final String name, final String... identifiers) {
|
||||||
|
this.name = name;
|
||||||
|
this.identifiers = ImmutableList.copyOf(identifiers);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static StorageType parse(final String name, final StorageType def) {
|
||||||
|
for (final StorageType t : values()) {
|
||||||
|
for (final String id : t.getIdentifiers()) {
|
||||||
|
if (id.equalsIgnoreCase(name)) {
|
||||||
|
return t;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return def;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getName() {
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<String> getIdentifiers() {
|
||||||
|
return identifiers;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,36 @@
|
|||||||
|
/*******************************************************************************************************
|
||||||
|
* Continued by PikaMug (formerly HappyPikachu) with permission from _Blackvein_. All rights reserved.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
||||||
|
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
|
||||||
|
* NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||||
|
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||||
|
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
|
||||||
|
* OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||||
|
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*******************************************************************************************************/
|
||||||
|
|
||||||
|
package me.blackvein.quests.storage.implementation;
|
||||||
|
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
import me.blackvein.quests.Quester;
|
||||||
|
import me.blackvein.quests.Quests;
|
||||||
|
|
||||||
|
public interface StorageImplementation {
|
||||||
|
Quests getPlugin();
|
||||||
|
|
||||||
|
String getImplementationName();
|
||||||
|
|
||||||
|
void init() throws Exception;
|
||||||
|
|
||||||
|
void close();
|
||||||
|
|
||||||
|
Quester loadQuesterData(UUID uniqueId) throws Exception;
|
||||||
|
|
||||||
|
void saveQuesterData(Quester quester) throws Exception;
|
||||||
|
|
||||||
|
void deleteQuesterData(UUID uniqueId) throws Exception;
|
||||||
|
|
||||||
|
String getQuesterLastKnownName(UUID uniqueId) throws Exception;
|
||||||
|
}
|
@ -0,0 +1,20 @@
|
|||||||
|
/*******************************************************************************************************
|
||||||
|
* Continued by PikaMug (formerly HappyPikachu) with permission from _Blackvein_. All rights reserved.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
||||||
|
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
|
||||||
|
* NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||||
|
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||||
|
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
|
||||||
|
* OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||||
|
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*******************************************************************************************************/
|
||||||
|
|
||||||
|
package me.blackvein.quests.storage.implementation.custom;
|
||||||
|
|
||||||
|
import me.blackvein.quests.Quests;
|
||||||
|
import me.blackvein.quests.storage.implementation.StorageImplementation;
|
||||||
|
|
||||||
|
public interface CustomStorageProvider {
|
||||||
|
StorageImplementation provide(Quests plugin);
|
||||||
|
}
|
@ -0,0 +1,31 @@
|
|||||||
|
/*******************************************************************************************************
|
||||||
|
* Continued by PikaMug (formerly HappyPikachu) with permission from _Blackvein_. All rights reserved.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
||||||
|
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
|
||||||
|
* NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||||
|
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||||
|
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
|
||||||
|
* OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||||
|
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*******************************************************************************************************/
|
||||||
|
|
||||||
|
package me.blackvein.quests.storage.implementation.custom;
|
||||||
|
|
||||||
|
public final class CustomStorageProviders {
|
||||||
|
private CustomStorageProviders() {}
|
||||||
|
|
||||||
|
private static CustomStorageProvider provider = null;
|
||||||
|
|
||||||
|
public static void register(final CustomStorageProvider provider) {
|
||||||
|
CustomStorageProviders.provider = provider;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static CustomStorageProvider getProvider() {
|
||||||
|
if (provider == null) {
|
||||||
|
throw new IllegalStateException("Provider not found.");
|
||||||
|
}
|
||||||
|
|
||||||
|
return provider;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,498 @@
|
|||||||
|
/*******************************************************************************************************
|
||||||
|
* Continued by PikaMug (formerly HappyPikachu) with permission from _Blackvein_. All rights reserved.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
||||||
|
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
|
||||||
|
* NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||||
|
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||||
|
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
|
||||||
|
* OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||||
|
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*******************************************************************************************************/
|
||||||
|
|
||||||
|
package me.blackvein.quests.storage.implementation.file;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.LinkedList;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.UUID;
|
||||||
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
|
|
||||||
|
import org.bukkit.Location;
|
||||||
|
import org.bukkit.Material;
|
||||||
|
import org.bukkit.configuration.ConfigurationSection;
|
||||||
|
import org.bukkit.configuration.InvalidConfigurationException;
|
||||||
|
import org.bukkit.configuration.file.FileConfiguration;
|
||||||
|
import org.bukkit.configuration.file.YamlConfiguration;
|
||||||
|
import org.bukkit.entity.EntityType;
|
||||||
|
import org.bukkit.inventory.ItemStack;
|
||||||
|
|
||||||
|
import me.blackvein.quests.Quest;
|
||||||
|
import me.blackvein.quests.Quester;
|
||||||
|
import me.blackvein.quests.Quests;
|
||||||
|
import me.blackvein.quests.Stage;
|
||||||
|
import me.blackvein.quests.storage.implementation.StorageImplementation;
|
||||||
|
import me.blackvein.quests.util.ConfigUtil;
|
||||||
|
import me.blackvein.quests.util.MiscUtil;
|
||||||
|
|
||||||
|
public class SeparatedYamlStorage implements StorageImplementation {
|
||||||
|
private final Quests plugin;
|
||||||
|
private final String directoryPath;
|
||||||
|
|
||||||
|
public SeparatedYamlStorage(final Quests plugin, final String directoryPath) {
|
||||||
|
this.plugin = plugin;
|
||||||
|
this.directoryPath = directoryPath;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Quests getPlugin() {
|
||||||
|
return plugin;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getImplementationName() {
|
||||||
|
return "YAML";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void init() throws Exception {
|
||||||
|
// TODO Auto-generated method stub
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void close() {
|
||||||
|
// TODO Auto-generated method stub
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("deprecation")
|
||||||
|
@Override
|
||||||
|
public Quester loadQuesterData(final UUID uniqueId) throws Exception {
|
||||||
|
final FileConfiguration data = new YamlConfiguration();
|
||||||
|
Quester quester = plugin.getQuester(uniqueId);
|
||||||
|
if (quester != null) {
|
||||||
|
quester.hardClear();
|
||||||
|
} else {
|
||||||
|
quester = new Quester(plugin, uniqueId);
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
final File dataFile = quester.getDataFile();
|
||||||
|
if (dataFile != null) {
|
||||||
|
data.load(dataFile);
|
||||||
|
} else {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
} catch (final IOException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
return null;
|
||||||
|
} catch (final InvalidConfigurationException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
if (data.contains("completedRedoableQuests")) {
|
||||||
|
final List<String> redoNames = data.getStringList("completedRedoableQuests");
|
||||||
|
final List<Long> redoTimes = data.getLongList("completedQuestTimes");
|
||||||
|
for (final String s : redoNames) {
|
||||||
|
for (final Quest q : plugin.getQuests()) {
|
||||||
|
if (q.getName().equalsIgnoreCase(s)) {
|
||||||
|
final Map<String, Long> completedTimes = quester.getCompletedTimes();
|
||||||
|
completedTimes.put(q.getName(), redoTimes.get(redoNames.indexOf(s)));
|
||||||
|
quester.setCompletedTimes(completedTimes);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (data.contains("amountsCompletedQuests")) {
|
||||||
|
final List<String> list1 = data.getStringList("amountsCompletedQuests");
|
||||||
|
final List<Integer> list2 = data.getIntegerList("amountsCompleted");
|
||||||
|
for (int i = 0; i < list1.size(); i++) {
|
||||||
|
final Map<String, Integer> amountsCompleted = quester.getAmountsCompleted();
|
||||||
|
amountsCompleted.put(list1.get(i), list2.get(i));
|
||||||
|
quester.setAmountsCompleted(amountsCompleted);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
int questPoints = quester.getQuestPoints();
|
||||||
|
questPoints = data.getInt("quest-points");
|
||||||
|
quester.setQuestPoints(questPoints);
|
||||||
|
quester.hasJournal = data.getBoolean("hasJournal");
|
||||||
|
if (data.isList("completed-Quests")) {
|
||||||
|
for (final String s : data.getStringList("completed-Quests")) {
|
||||||
|
for (final Quest q : plugin.getQuests()) {
|
||||||
|
if (q.getName().equalsIgnoreCase(s)) {
|
||||||
|
if (!quester.getCompletedQuests().contains(q.getName())) {
|
||||||
|
final LinkedList<String> completedQuests = quester.getCompletedQuests();
|
||||||
|
completedQuests.add(q.getName());
|
||||||
|
quester.setCompletedQuests(completedQuests);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
quester.setCompletedQuests(new LinkedList<String>());
|
||||||
|
}
|
||||||
|
if (data.isString("currentQuests") == false) {
|
||||||
|
final List<String> questNames = data.getStringList("currentQuests");
|
||||||
|
final List<Integer> questStages = data.getIntegerList("currentStages");
|
||||||
|
// These appear to differ sometimes? That seems bad.
|
||||||
|
final int maxSize = Math.min(questNames.size(), questStages.size());
|
||||||
|
for (int i = 0; i < maxSize; i++) {
|
||||||
|
if (plugin.getQuest(questNames.get(i)) != null) {
|
||||||
|
final ConcurrentHashMap<Quest, Integer> currentQuests = quester.getCurrentQuests();
|
||||||
|
currentQuests.put(plugin.getQuest(questNames.get(i)), questStages.get(i));
|
||||||
|
quester.setCurrentQuests(currentQuests);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
final ConfigurationSection dataSec = data.getConfigurationSection("questData");
|
||||||
|
if (dataSec == null || dataSec.getKeys(false).isEmpty()) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
for (final String key : dataSec.getKeys(false)) {
|
||||||
|
final ConfigurationSection questSec = dataSec.getConfigurationSection(key);
|
||||||
|
final Quest quest = plugin.getQuest(key);
|
||||||
|
Stage stage;
|
||||||
|
if (quest == null || quester.getCurrentQuests().containsKey(quest) == false) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
stage = quester.getCurrentStage(quest);
|
||||||
|
if (stage == null) {
|
||||||
|
quest.completeQuest(quester);
|
||||||
|
plugin.getLogger().severe("[Quests] Invalid stage number for player: \"" + uniqueId + "\" on Quest \""
|
||||||
|
+ quest.getName() + "\". Quest ended.");
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
quester.addEmptiesFor(quest, quester.getCurrentQuests().get(quest));
|
||||||
|
if (questSec == null)
|
||||||
|
continue;
|
||||||
|
if (questSec.contains("blocks-broken-names")) {
|
||||||
|
final List<String> names = questSec.getStringList("blocks-broken-names");
|
||||||
|
final List<Integer> amounts = questSec.getIntegerList("blocks-broken-amounts");
|
||||||
|
final List<Short> durability = questSec.getShortList("blocks-broken-durability");
|
||||||
|
int index = 0;
|
||||||
|
for (final String s : names) {
|
||||||
|
ItemStack is;
|
||||||
|
try {
|
||||||
|
is = new ItemStack(Material.matchMaterial(s), amounts.get(index), durability.get(index));
|
||||||
|
} catch (final IndexOutOfBoundsException e) {
|
||||||
|
// Legacy
|
||||||
|
is = new ItemStack(Material.matchMaterial(s), amounts.get(index), (short) 0);
|
||||||
|
}
|
||||||
|
if (quester.getQuestData(quest).blocksBroken.size() > 0) {
|
||||||
|
quester.getQuestData(quest).blocksBroken.set(index, is);
|
||||||
|
}
|
||||||
|
index++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (questSec.contains("blocks-damaged-names")) {
|
||||||
|
final List<String> names = questSec.getStringList("blocks-damaged-names");
|
||||||
|
final List<Integer> amounts = questSec.getIntegerList("blocks-damaged-amounts");
|
||||||
|
final List<Short> durability = questSec.getShortList("blocks-damaged-durability");
|
||||||
|
int index = 0;
|
||||||
|
for (final String s : names) {
|
||||||
|
ItemStack is;
|
||||||
|
try {
|
||||||
|
is = new ItemStack(Material.matchMaterial(s), amounts.get(index), durability.get(index));
|
||||||
|
} catch (final IndexOutOfBoundsException e) {
|
||||||
|
// Legacy
|
||||||
|
is = new ItemStack(Material.matchMaterial(s), amounts.get(index), (short) 0);
|
||||||
|
}
|
||||||
|
if (quester.getQuestData(quest).blocksDamaged.size() > 0) {
|
||||||
|
quester.getQuestData(quest).blocksDamaged.set(index, is);
|
||||||
|
}
|
||||||
|
index++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (questSec.contains("blocks-placed-names")) {
|
||||||
|
final List<String> names = questSec.getStringList("blocks-placed-names");
|
||||||
|
final List<Integer> amounts = questSec.getIntegerList("blocks-placed-amounts");
|
||||||
|
final List<Short> durability = questSec.getShortList("blocks-placed-durability");
|
||||||
|
int index = 0;
|
||||||
|
for (final String s : names) {
|
||||||
|
ItemStack is;
|
||||||
|
try {
|
||||||
|
is = new ItemStack(Material.matchMaterial(s), amounts.get(index), durability.get(index));
|
||||||
|
} catch (final IndexOutOfBoundsException e) {
|
||||||
|
// Legacy
|
||||||
|
is = new ItemStack(Material.matchMaterial(s), amounts.get(index), (short) 0);
|
||||||
|
}
|
||||||
|
if (quester.getQuestData(quest).blocksPlaced.size() > 0) {
|
||||||
|
quester.getQuestData(quest).blocksPlaced.set(index, is);
|
||||||
|
}
|
||||||
|
index++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (questSec.contains("blocks-used-names")) {
|
||||||
|
final List<String> names = questSec.getStringList("blocks-used-names");
|
||||||
|
final List<Integer> amounts = questSec.getIntegerList("blocks-used-amounts");
|
||||||
|
final List<Short> durability = questSec.getShortList("blocks-used-durability");
|
||||||
|
int index = 0;
|
||||||
|
for (final String s : names) {
|
||||||
|
ItemStack is;
|
||||||
|
try {
|
||||||
|
is = new ItemStack(Material.matchMaterial(s), amounts.get(index), durability.get(index));
|
||||||
|
} catch (final IndexOutOfBoundsException e) {
|
||||||
|
// Legacy
|
||||||
|
is = new ItemStack(Material.matchMaterial(s), amounts.get(index), (short) 0);
|
||||||
|
}
|
||||||
|
if (quester.getQuestData(quest).blocksUsed.size() > 0) {
|
||||||
|
quester.getQuestData(quest).blocksUsed.set(index, is);
|
||||||
|
}
|
||||||
|
index++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (questSec.contains("blocks-cut-names")) {
|
||||||
|
final List<String> names = questSec.getStringList("blocks-cut-names");
|
||||||
|
final List<Integer> amounts = questSec.getIntegerList("blocks-cut-amounts");
|
||||||
|
final List<Short> durability = questSec.getShortList("blocks-cut-durability");
|
||||||
|
int index = 0;
|
||||||
|
for (final String s : names) {
|
||||||
|
ItemStack is;
|
||||||
|
try {
|
||||||
|
is = new ItemStack(Material.matchMaterial(s), amounts.get(index), durability.get(index));
|
||||||
|
} catch (final IndexOutOfBoundsException e) {
|
||||||
|
// Legacy
|
||||||
|
is = new ItemStack(Material.matchMaterial(s), amounts.get(index), (short) 0);
|
||||||
|
}
|
||||||
|
if (quester.getQuestData(quest).blocksCut.size() > 0) {
|
||||||
|
quester.getQuestData(quest).blocksCut.set(index, is);
|
||||||
|
}
|
||||||
|
index++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (questSec.contains("item-craft-amounts")) {
|
||||||
|
final List<Integer> craftAmounts = questSec.getIntegerList("item-craft-amounts");
|
||||||
|
for (int i = 0; i < craftAmounts.size(); i++) {
|
||||||
|
if (i < quester.getCurrentStage(quest).getItemsToCraft().size()) {
|
||||||
|
quester.getQuestData(quest).itemsCrafted.put(quester.getCurrentStage(quest)
|
||||||
|
.getItemsToCraft().get(i), craftAmounts.get(i));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (questSec.contains("item-smelt-amounts")) {
|
||||||
|
final List<Integer> smeltAmounts = questSec.getIntegerList("item-smelt-amounts");
|
||||||
|
for (int i = 0; i < smeltAmounts.size(); i++) {
|
||||||
|
if (i < quester.getCurrentStage(quest).getItemsToSmelt().size()) {
|
||||||
|
quester.getQuestData(quest).itemsSmelted.put(quester.getCurrentStage(quest)
|
||||||
|
.getItemsToSmelt().get(i), smeltAmounts.get(i));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (questSec.contains("item-enchant-amounts")) {
|
||||||
|
final List<Integer> enchantAmounts = questSec.getIntegerList("item-enchant-amounts");
|
||||||
|
for (int i = 0; i < enchantAmounts.size(); i++) {
|
||||||
|
if (i < quester.getCurrentStage(quest).getItemsToEnchant().size()) {
|
||||||
|
quester.getQuestData(quest).itemsEnchanted.put(quester.getCurrentStage(quest)
|
||||||
|
.getItemsToEnchant().get(i), enchantAmounts.get(i));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (questSec.contains("item-brew-amounts")) {
|
||||||
|
final List<Integer> brewAmounts = questSec.getIntegerList("item-brew-amounts");
|
||||||
|
for (int i = 0; i < brewAmounts.size(); i++) {
|
||||||
|
if (i < quester.getCurrentStage(quest).getItemsToBrew().size()) {
|
||||||
|
quester.getQuestData(quest).itemsBrewed.put(quester.getCurrentStage(quest)
|
||||||
|
.getItemsToBrew().get(i), brewAmounts.get(i));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (questSec.contains("item-consume-amounts")) {
|
||||||
|
final List<Integer> consumeAmounts = questSec.getIntegerList("item-consume-amounts");
|
||||||
|
for (int i = 0; i < consumeAmounts.size(); i++) {
|
||||||
|
if (i < quester.getCurrentStage(quest).getItemsToConsume().size()) {
|
||||||
|
quester.getQuestData(quest).itemsConsumed.put(quester.getCurrentStage(quest)
|
||||||
|
.getItemsToConsume().get(i), consumeAmounts.get(i));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (questSec.contains("cows-milked")) {
|
||||||
|
quester.getQuestData(quest).setCowsMilked(questSec.getInt("cows-milked"));
|
||||||
|
}
|
||||||
|
if (questSec.contains("fish-caught")) {
|
||||||
|
quester.getQuestData(quest).setFishCaught(questSec.getInt("fish-caught"));
|
||||||
|
}
|
||||||
|
if (questSec.contains("players-killed")) {
|
||||||
|
quester.getQuestData(quest).setPlayersKilled(questSec.getInt("players-killed"));
|
||||||
|
}
|
||||||
|
if (questSec.contains("mobs-killed")) {
|
||||||
|
final LinkedList<EntityType> mobs = new LinkedList<EntityType>();
|
||||||
|
final List<Integer> amounts = questSec.getIntegerList("mobs-killed-amounts");
|
||||||
|
for (final String s : questSec.getStringList("mobs-killed")) {
|
||||||
|
final EntityType mob = MiscUtil.getProperMobType(s);
|
||||||
|
if (mob != null) {
|
||||||
|
mobs.add(mob);
|
||||||
|
}
|
||||||
|
quester.getQuestData(quest).mobsKilled.clear();
|
||||||
|
quester.getQuestData(quest).mobNumKilled.clear();
|
||||||
|
for (final EntityType e : mobs) {
|
||||||
|
quester.getQuestData(quest).mobsKilled.add(e);
|
||||||
|
quester.getQuestData(quest).mobNumKilled.add(amounts.get(mobs.indexOf(e)));
|
||||||
|
}
|
||||||
|
if (questSec.contains("mob-kill-locations")) {
|
||||||
|
final LinkedList<Location> locations = new LinkedList<Location>();
|
||||||
|
final List<Integer> radii = questSec.getIntegerList("mob-kill-location-radii");
|
||||||
|
for (final String loc : questSec.getStringList("mob-kill-locations")) {
|
||||||
|
if (ConfigUtil.getLocation(loc) != null) {
|
||||||
|
locations.add(ConfigUtil.getLocation(loc));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
quester.getQuestData(quest).locationsToKillWithin = locations;
|
||||||
|
quester.getQuestData(quest).radiiToKillWithin.clear();
|
||||||
|
for (final int i : radii) {
|
||||||
|
quester.getQuestData(quest).radiiToKillWithin.add(i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (questSec.contains("item-delivery-amounts")) {
|
||||||
|
final List<Integer> deliveryAmounts = questSec.getIntegerList("item-delivery-amounts");
|
||||||
|
int index = 0;
|
||||||
|
for (final int amt : deliveryAmounts) {
|
||||||
|
final ItemStack is = quester.getCurrentStage(quest).getItemsToDeliver().get(index);
|
||||||
|
final ItemStack temp = new ItemStack(is.getType(), amt, is.getDurability());
|
||||||
|
try {
|
||||||
|
temp.addEnchantments(is.getEnchantments());
|
||||||
|
} catch (final Exception e) {
|
||||||
|
plugin.getLogger().warning("Unable to add enchantment(s) " + is.getEnchantments().toString()
|
||||||
|
+ " to delivery item " + is.getType().name() + " x " + amt + " for quest "
|
||||||
|
+ quest.getName());
|
||||||
|
}
|
||||||
|
temp.setItemMeta(is.getItemMeta());
|
||||||
|
if (quester.getQuestData(quest).itemsDelivered.size() > 0) {
|
||||||
|
quester.getQuestData(quest).itemsDelivered.set(index, temp);
|
||||||
|
}
|
||||||
|
index++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (questSec.contains("citizen-ids-to-talk-to")) {
|
||||||
|
final List<Integer> ids = questSec.getIntegerList("citizen-ids-to-talk-to");
|
||||||
|
final List<Boolean> has = questSec.getBooleanList("has-talked-to");
|
||||||
|
for (final int i : ids) {
|
||||||
|
quester.getQuestData(quest).citizensInteracted.put(i, has.get(ids.indexOf(i)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (questSec.contains("citizen-ids-killed")) {
|
||||||
|
final List<Integer> ids = questSec.getIntegerList("citizen-ids-killed");
|
||||||
|
final List<Integer> num = questSec.getIntegerList("citizen-amounts-killed");
|
||||||
|
quester.getQuestData(quest).citizensKilled.clear();
|
||||||
|
quester.getQuestData(quest).citizenNumKilled.clear();
|
||||||
|
for (final int i : ids) {
|
||||||
|
quester.getQuestData(quest).citizensKilled.add(i);
|
||||||
|
quester.getQuestData(quest).citizenNumKilled.add(num.get(ids.indexOf(i)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (questSec.contains("locations-to-reach")) {
|
||||||
|
final LinkedList<Location> locations = new LinkedList<Location>();
|
||||||
|
final List<Boolean> has = questSec.getBooleanList("has-reached-location");
|
||||||
|
while (has.size() < locations.size()) {
|
||||||
|
// TODO - Find proper cause of Github issues #646 and #825
|
||||||
|
plugin.getLogger().info("Added missing has-reached-location data for Quester " + uniqueId);
|
||||||
|
has.add(false);
|
||||||
|
}
|
||||||
|
final List<Integer> radii = questSec.getIntegerList("radii-to-reach-within");
|
||||||
|
for (final String loc : questSec.getStringList("locations-to-reach")) {
|
||||||
|
if (ConfigUtil.getLocation(loc) != null) {
|
||||||
|
locations.add(ConfigUtil.getLocation(loc));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
quester.getQuestData(quest).locationsReached = locations;
|
||||||
|
quester.getQuestData(quest).hasReached.clear();
|
||||||
|
quester.getQuestData(quest).radiiToReachWithin.clear();
|
||||||
|
for (final boolean b : has) {
|
||||||
|
quester.getQuestData(quest).hasReached.add(b);
|
||||||
|
}
|
||||||
|
for (final int i : radii) {
|
||||||
|
quester.getQuestData(quest).radiiToReachWithin.add(i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (questSec.contains("mobs-to-tame")) {
|
||||||
|
final List<String> mobs = questSec.getStringList("mobs-to-tame");
|
||||||
|
final List<Integer> amounts = questSec.getIntegerList("mob-tame-amounts");
|
||||||
|
for (final String mob : mobs) {
|
||||||
|
quester.getQuestData(quest).mobsTamed.put(EntityType.valueOf(mob.toUpperCase()), amounts
|
||||||
|
.get(mobs.indexOf(mob)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (questSec.contains("sheep-to-shear")) {
|
||||||
|
final List<String> colors = questSec.getStringList("sheep-to-shear");
|
||||||
|
final List<Integer> amounts = questSec.getIntegerList("sheep-sheared");
|
||||||
|
for (final String color : colors) {
|
||||||
|
quester.getQuestData(quest).sheepSheared.put(MiscUtil.getProperDyeColor(color), amounts.get(colors
|
||||||
|
.indexOf(color)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (questSec.contains("passwords")) {
|
||||||
|
final List<String> passwords = questSec.getStringList("passwords");
|
||||||
|
final List<Boolean> said = questSec.getBooleanList("passwords-said");
|
||||||
|
for (int i = 0; i < passwords.size(); i++) {
|
||||||
|
quester.getQuestData(quest).passwordsSaid.put(passwords.get(i), said.get(i));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (questSec.contains("custom-objectives")) {
|
||||||
|
final List<String> customObj = questSec.getStringList("custom-objectives");
|
||||||
|
final List<Integer> customObjCount = questSec.getIntegerList("custom-objective-counts");
|
||||||
|
for (int i = 0; i < customObj.size(); i++) {
|
||||||
|
quester.getQuestData(quest).customObjectiveCounts.put(customObj.get(i), customObjCount.get(i));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (questSec.contains("stage-delay")) {
|
||||||
|
quester.getQuestData(quest).setDelayTimeLeft(questSec.getLong("stage-delay"));
|
||||||
|
}
|
||||||
|
if (quester.getCurrentStage(quest).getChatActions().isEmpty() == false) {
|
||||||
|
for (final String chatTrig : quester.getCurrentStage(quest).getChatActions().keySet()) {
|
||||||
|
quester.getQuestData(quest).actionFired.put(chatTrig, false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (questSec.contains("chat-triggers")) {
|
||||||
|
final List<String> chatTriggers = questSec.getStringList("chat-triggers");
|
||||||
|
for (final String s : chatTriggers) {
|
||||||
|
quester.getQuestData(quest).actionFired.put(s, true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (quester.getCurrentStage(quest).getCommandActions().isEmpty() == false) {
|
||||||
|
for (final String commandTrig : quester.getCurrentStage(quest).getCommandActions().keySet()) {
|
||||||
|
quester.getQuestData(quest).actionFired.put(commandTrig, false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (questSec.contains("command-triggers")) {
|
||||||
|
final List<String> commandTriggers = questSec.getStringList("command-triggers");
|
||||||
|
for (final String s : commandTriggers) {
|
||||||
|
quester.getQuestData(quest).actionFired.put(s, true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return quester;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void saveQuesterData(final Quester quester) throws Exception {
|
||||||
|
final FileConfiguration data = quester.getBaseData();
|
||||||
|
try {
|
||||||
|
data.save(new File(directoryPath + File.separator + quester.getUUID() + ".yml"));
|
||||||
|
} catch (final IOException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void deleteQuesterData(final UUID uniqueId) throws Exception {
|
||||||
|
final File f = new File(directoryPath + File.separator + uniqueId + ".yml");
|
||||||
|
f.delete();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getQuesterLastKnownName(final UUID uniqueId) throws Exception {
|
||||||
|
final FileConfiguration data = new YamlConfiguration();
|
||||||
|
Quester quester = plugin.getQuester(uniqueId);
|
||||||
|
if (quester != null) {
|
||||||
|
quester.hardClear();
|
||||||
|
} else {
|
||||||
|
quester = new Quester(plugin, uniqueId);
|
||||||
|
}
|
||||||
|
return data.getString("lastKnownName");
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,149 @@
|
|||||||
|
/*******************************************************************************************************
|
||||||
|
* Continued by PikaMug (formerly HappyPikachu) with permission from _Blackvein_. All rights reserved.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
||||||
|
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
|
||||||
|
* NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||||
|
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||||
|
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
|
||||||
|
* OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||||
|
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*******************************************************************************************************/
|
||||||
|
|
||||||
|
package me.blackvein.quests.storage.implementation.sql;
|
||||||
|
|
||||||
|
import java.sql.Connection;
|
||||||
|
import java.sql.PreparedStatement;
|
||||||
|
import java.sql.ResultSet;
|
||||||
|
import java.util.UUID;
|
||||||
|
import java.util.function.Function;
|
||||||
|
|
||||||
|
import me.blackvein.quests.Quester;
|
||||||
|
import me.blackvein.quests.Quests;
|
||||||
|
import me.blackvein.quests.storage.implementation.StorageImplementation;
|
||||||
|
import me.blackvein.quests.storage.implementation.sql.connection.ConnectionFactory;
|
||||||
|
|
||||||
|
public class SqlStorage implements StorageImplementation {
|
||||||
|
private static final String PLAYER_SELECT = "SELECT id, hasjournal, FROM '{prefix}players' WHERE uuid=?";
|
||||||
|
private static final String PLAYER_SELECT_USERNAME_BY_UUID = "SELECT username FROM '{prefix}players' WHERE uuid=? LIMIT 1";
|
||||||
|
private static final String PLAYER_UPDATE_USERNAME_FOR_UUID = "UPDATE '{prefix}players' SET username=? WHERE uuid=?";
|
||||||
|
private static final String PLAYER_INSERT = "INSERT INTO '{prefix}players' (uuid, username, hasjournal) VALUES(?, ?, ?) ON DUPLICATE KEY UPDATE";
|
||||||
|
private static final String PLAYER_DELETE = "DELETE FROM '{prefix}players' WHERE uuid=?";
|
||||||
|
|
||||||
|
private final Quests plugin;
|
||||||
|
|
||||||
|
private final ConnectionFactory connectionFactory;
|
||||||
|
private final Function<String, String> statementProcessor;
|
||||||
|
|
||||||
|
public SqlStorage(final Quests plugin, final ConnectionFactory connectionFactory, final String tablePrefix) {
|
||||||
|
this.plugin = plugin;
|
||||||
|
this.connectionFactory = connectionFactory;
|
||||||
|
this.statementProcessor = connectionFactory.getStatementProcessor().compose(s -> s.replace("{prefix}", tablePrefix));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Quests getPlugin() {
|
||||||
|
return plugin;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getImplementationName() {
|
||||||
|
return connectionFactory.getImplementationName();
|
||||||
|
}
|
||||||
|
|
||||||
|
public ConnectionFactory getConnectionFactory() {
|
||||||
|
return connectionFactory;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Function<String, String> getStatementProcessor() {
|
||||||
|
return statementProcessor;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void init() throws Exception {
|
||||||
|
connectionFactory.init(plugin);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void close() {
|
||||||
|
try {
|
||||||
|
connectionFactory.close();
|
||||||
|
} catch (final Exception e) {
|
||||||
|
this.plugin.getLogger().severe("Problem occurred while closing SQL storage");
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Quester loadQuesterData(final UUID uniqueId) throws Exception {
|
||||||
|
final Quester quester = new Quester(plugin, uniqueId);
|
||||||
|
try (Connection c = connectionFactory.getConnection()) {
|
||||||
|
if (uniqueId != null) {
|
||||||
|
try (PreparedStatement ps = c.prepareStatement(this.statementProcessor.apply(PLAYER_SELECT))) {
|
||||||
|
ps.setString(1, uniqueId.toString());
|
||||||
|
try (ResultSet rs = ps.executeQuery()) {
|
||||||
|
while (rs.next()) {
|
||||||
|
final boolean hasJournal = rs.getBoolean("hasjournal");
|
||||||
|
quester.hasJournal = hasJournal;
|
||||||
|
// TODO the rest
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return quester;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void saveQuesterData(final Quester quester) throws Exception {
|
||||||
|
final UUID uniqueId = quester.getUUID();
|
||||||
|
final String username = quester.getPlayer().getName();
|
||||||
|
final String oldUsername = getQuesterLastKnownName(uniqueId);
|
||||||
|
|
||||||
|
try (Connection c = connectionFactory.getConnection()) {
|
||||||
|
if (oldUsername != null && !username.equals(oldUsername)) {
|
||||||
|
try (PreparedStatement ps = c.prepareStatement(this.statementProcessor.apply(PLAYER_UPDATE_USERNAME_FOR_UUID))) {
|
||||||
|
ps.setString(1, username);
|
||||||
|
ps.setString(2, uniqueId.toString());
|
||||||
|
ps.execute();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
try (PreparedStatement ps = c.prepareStatement(this.statementProcessor.apply(PLAYER_INSERT))) {
|
||||||
|
ps.setString(1, uniqueId.toString());
|
||||||
|
ps.setString(2, username);
|
||||||
|
ps.setBoolean(3, quester.hasJournal);
|
||||||
|
ps.execute();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!username.equals(oldUsername)) {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void deleteQuesterData(final UUID uniqueId) throws Exception {
|
||||||
|
try (Connection c = connectionFactory.getConnection()) {
|
||||||
|
try (PreparedStatement ps = c.prepareStatement(this.statementProcessor.apply(PLAYER_DELETE))) {
|
||||||
|
ps.setString(1, uniqueId.toString());
|
||||||
|
ps.execute();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getQuesterLastKnownName(final UUID uniqueId) throws Exception {
|
||||||
|
try (Connection c = connectionFactory.getConnection()) {
|
||||||
|
try (PreparedStatement ps = c.prepareStatement(this.statementProcessor.apply(PLAYER_SELECT_USERNAME_BY_UUID))) {
|
||||||
|
ps.setString(1, uniqueId.toString());
|
||||||
|
try (ResultSet rs = ps.executeQuery()) {
|
||||||
|
if (rs.next()) {
|
||||||
|
return rs.getString("username");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,37 @@
|
|||||||
|
/*******************************************************************************************************
|
||||||
|
* Continued by PikaMug (formerly HappyPikachu) with permission from _Blackvein_. All rights reserved.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
||||||
|
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
|
||||||
|
* NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||||
|
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||||
|
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
|
||||||
|
* OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||||
|
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*******************************************************************************************************/
|
||||||
|
|
||||||
|
package me.blackvein.quests.storage.implementation.sql.connection;
|
||||||
|
|
||||||
|
import java.sql.Connection;
|
||||||
|
import java.sql.SQLException;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.function.Function;
|
||||||
|
|
||||||
|
import me.blackvein.quests.Quests;
|
||||||
|
|
||||||
|
public interface ConnectionFactory {
|
||||||
|
String getImplementationName();
|
||||||
|
|
||||||
|
void init(Quests plugin);
|
||||||
|
|
||||||
|
void close() throws Exception;
|
||||||
|
|
||||||
|
default Map<String, String> getMeta() {
|
||||||
|
return Collections.emptyMap();
|
||||||
|
}
|
||||||
|
|
||||||
|
Function<String, String> getStatementProcessor();
|
||||||
|
|
||||||
|
Connection getConnection() throws SQLException;
|
||||||
|
}
|
@ -0,0 +1,141 @@
|
|||||||
|
/*******************************************************************************************************
|
||||||
|
* Continued by PikaMug (formerly HappyPikachu) with permission from _Blackvein_. All rights reserved.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
||||||
|
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
|
||||||
|
* NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||||
|
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||||
|
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
|
||||||
|
* OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||||
|
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*******************************************************************************************************/
|
||||||
|
|
||||||
|
package me.blackvein.quests.storage.implementation.sql.connection.hikari;
|
||||||
|
|
||||||
|
import java.lang.reflect.Method;
|
||||||
|
import java.sql.Connection;
|
||||||
|
import java.sql.SQLException;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
|
import org.bukkit.plugin.java.JavaPlugin;
|
||||||
|
|
||||||
|
import com.zaxxer.hikari.HikariConfig;
|
||||||
|
import com.zaxxer.hikari.HikariDataSource;
|
||||||
|
|
||||||
|
import me.blackvein.quests.Quests;
|
||||||
|
import me.blackvein.quests.storage.implementation.sql.connection.ConnectionFactory;
|
||||||
|
import me.blackvein.quests.storage.misc.StorageCredentials;
|
||||||
|
|
||||||
|
public abstract class HikariConnectionFactory implements ConnectionFactory {
|
||||||
|
private final StorageCredentials configuration;
|
||||||
|
private HikariDataSource hikari;
|
||||||
|
|
||||||
|
public HikariConnectionFactory(final StorageCredentials configuration) {
|
||||||
|
this.configuration = configuration;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the default port used by the database
|
||||||
|
*
|
||||||
|
* @return the default port
|
||||||
|
*/
|
||||||
|
protected abstract String defaultPort();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Configures the {@link HikariConfig} with the relevant database properties.
|
||||||
|
*
|
||||||
|
* <p>Each driver does this slightly differently.</p>
|
||||||
|
*
|
||||||
|
* @param config the hikari config
|
||||||
|
* @param address the database address
|
||||||
|
* @param port the database port
|
||||||
|
* @param databaseName the database name
|
||||||
|
* @param username the database username
|
||||||
|
* @param password the database password
|
||||||
|
*/
|
||||||
|
protected abstract void configureDatabase(HikariConfig config, String address, String port, String databaseName,
|
||||||
|
String username, String password);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Allows the connection factory instance to override certain properties before they are set.
|
||||||
|
*
|
||||||
|
* @param properties the current properties
|
||||||
|
*/
|
||||||
|
protected void overrideProperties(final Map<String, String> properties) {
|
||||||
|
// https://github.com/brettwooldridge/HikariCP/wiki/Rapid-Recovery
|
||||||
|
properties.putIfAbsent("socketTimeout", String.valueOf(TimeUnit.SECONDS.toMillis(30)));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the given connection properties onto the config.
|
||||||
|
*
|
||||||
|
* @param config the hikari config
|
||||||
|
* @param properties the properties
|
||||||
|
*/
|
||||||
|
protected void setProperties(final HikariConfig config, final Map<String, String> properties) {
|
||||||
|
for (final Map.Entry<String, String> property : properties.entrySet()) {
|
||||||
|
config.addDataSourceProperty(property.getKey(), property.getValue());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void init(final Quests plugin) {
|
||||||
|
final HikariConfig config = new HikariConfig();
|
||||||
|
config.setPoolName("quests-hikari");
|
||||||
|
|
||||||
|
final String[] addressSplit = configuration.getAddress().split(":");
|
||||||
|
final String address = addressSplit[0];
|
||||||
|
final String port = addressSplit.length > 1 ? addressSplit[1] : defaultPort();
|
||||||
|
|
||||||
|
configureDatabase(config, address, port, configuration.getDatabase(), configuration.getUsername(),
|
||||||
|
configuration.getPassword());
|
||||||
|
|
||||||
|
final Map<String, String> properties = new HashMap<>(this.configuration.getProperties());
|
||||||
|
|
||||||
|
overrideProperties(properties);
|
||||||
|
|
||||||
|
setProperties(config, properties);
|
||||||
|
|
||||||
|
config.setMaximumPoolSize(this.configuration.getMaxPoolSize());
|
||||||
|
config.setMinimumIdle(this.configuration.getMinIdleConnections());
|
||||||
|
config.setMaxLifetime(this.configuration.getMaxLifetime());
|
||||||
|
config.setConnectionTimeout(this.configuration.getConnectionTimeout());
|
||||||
|
|
||||||
|
hikari = new HikariDataSource(config);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void close() {
|
||||||
|
if (hikari != null) {
|
||||||
|
hikari.close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Connection getConnection() throws SQLException {
|
||||||
|
if (hikari == null) {
|
||||||
|
throw new SQLException("Unable to get a connection from the pool because hikari is null");
|
||||||
|
}
|
||||||
|
|
||||||
|
final Connection connection = hikari.getConnection();
|
||||||
|
if (connection == null) {
|
||||||
|
throw new SQLException("Unable to get a connection from the pool because getConnection returned null");
|
||||||
|
}
|
||||||
|
|
||||||
|
return connection;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String identifyClassLoader(final ClassLoader classLoader) throws ReflectiveOperationException {
|
||||||
|
final Class<?> pluginClassLoaderClass = Class.forName("org.bukkit.plugin.java.PluginClassLoader");
|
||||||
|
if (pluginClassLoaderClass.isInstance(classLoader)) {
|
||||||
|
final Method getPluginMethod = pluginClassLoaderClass.getDeclaredMethod("getPlugin");
|
||||||
|
getPluginMethod.setAccessible(true);
|
||||||
|
|
||||||
|
final JavaPlugin plugin = (JavaPlugin) getPluginMethod.invoke(classLoader);
|
||||||
|
return plugin.getName();
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,72 @@
|
|||||||
|
/*******************************************************************************************************
|
||||||
|
* Continued by PikaMug (formerly HappyPikachu) with permission from _Blackvein_. All rights reserved.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
||||||
|
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
|
||||||
|
* NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||||
|
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||||
|
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
|
||||||
|
* OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||||
|
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*******************************************************************************************************/
|
||||||
|
|
||||||
|
package me.blackvein.quests.storage.implementation.sql.connection.hikari;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.function.Function;
|
||||||
|
|
||||||
|
import com.zaxxer.hikari.HikariConfig;
|
||||||
|
|
||||||
|
import me.blackvein.quests.storage.misc.StorageCredentials;
|
||||||
|
|
||||||
|
public class MySqlConnectionFactory extends HikariConnectionFactory {
|
||||||
|
public MySqlConnectionFactory(final StorageCredentials configuration) {
|
||||||
|
super(configuration);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getImplementationName() {
|
||||||
|
return "MySQL";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected String defaultPort() {
|
||||||
|
return "3306";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void configureDatabase(final HikariConfig config, final String address, final String port,
|
||||||
|
final String databaseName, final String username, final String password) {
|
||||||
|
config.setDriverClassName("com.mysql.cj.jdbc.NonRegisteringDriver");
|
||||||
|
config.setJdbcUrl("jdbc:mysql://" + address + ":" + port + "/" + databaseName);
|
||||||
|
config.setUsername(username);
|
||||||
|
config.setPassword(password);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void overrideProperties(final Map<String, String> properties) {
|
||||||
|
// https://github.com/brettwooldridge/HikariCP/wiki/MySQL-Configuration
|
||||||
|
properties.putIfAbsent("cachePrepStmts", "true");
|
||||||
|
properties.putIfAbsent("prepStmtCacheSize", "250");
|
||||||
|
properties.putIfAbsent("prepStmtCacheSqlLimit", "2048");
|
||||||
|
properties.putIfAbsent("useServerPrepStmts", "true");
|
||||||
|
properties.putIfAbsent("useLocalSessionState", "true");
|
||||||
|
properties.putIfAbsent("rewriteBatchedStatements", "true");
|
||||||
|
properties.putIfAbsent("cacheResultSetMetadata", "true");
|
||||||
|
properties.putIfAbsent("cacheServerConfiguration", "true");
|
||||||
|
properties.putIfAbsent("elideSetAutoCommits", "true");
|
||||||
|
properties.putIfAbsent("maintainTimeStats", "false");
|
||||||
|
properties.putIfAbsent("alwaysSendSetIsolation", "false");
|
||||||
|
properties.putIfAbsent("cacheCallableStmts", "true");
|
||||||
|
|
||||||
|
// https://stackoverflow.com/a/54256150
|
||||||
|
properties.putIfAbsent("serverTimezone", "UTC");
|
||||||
|
|
||||||
|
super.overrideProperties(properties);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Function<String, String> getStatementProcessor() {
|
||||||
|
return s -> s.replace("'", "`");
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,79 @@
|
|||||||
|
/*******************************************************************************************************
|
||||||
|
* Continued by PikaMug (formerly HappyPikachu) with permission from _Blackvein_. All rights reserved.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
||||||
|
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
|
||||||
|
* NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||||
|
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||||
|
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
|
||||||
|
* OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||||
|
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*******************************************************************************************************/
|
||||||
|
|
||||||
|
package me.blackvein.quests.storage.misc;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Objects;
|
||||||
|
|
||||||
|
public class StorageCredentials {
|
||||||
|
|
||||||
|
private final String address;
|
||||||
|
private final String database;
|
||||||
|
private final String username;
|
||||||
|
private final String password;
|
||||||
|
private final int maxPoolSize;
|
||||||
|
private final int minIdleConnections;
|
||||||
|
private final int maxLifetime;
|
||||||
|
private final int connectionTimeout;
|
||||||
|
private final Map<String, String> properties;
|
||||||
|
|
||||||
|
public StorageCredentials(final String address, final String database, final String username, final String password,
|
||||||
|
final int maxPoolSize, final int minIdleConnections, final int maxLifetime, final int connectionTimeout,
|
||||||
|
final Map<String, String> properties) {
|
||||||
|
this.address = address;
|
||||||
|
this.database = database;
|
||||||
|
this.username = username;
|
||||||
|
this.password = password;
|
||||||
|
this.maxPoolSize = maxPoolSize;
|
||||||
|
this.minIdleConnections = minIdleConnections;
|
||||||
|
this.maxLifetime = maxLifetime;
|
||||||
|
this.connectionTimeout = connectionTimeout;
|
||||||
|
this.properties = properties;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getAddress() {
|
||||||
|
return Objects.requireNonNull(address, "address");
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getDatabase() {
|
||||||
|
return Objects.requireNonNull(database, "database");
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getUsername() {
|
||||||
|
return Objects.requireNonNull(username, "username");
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getPassword() {
|
||||||
|
return Objects.requireNonNull(password, "password");
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getMaxPoolSize() {
|
||||||
|
return maxPoolSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getMinIdleConnections() {
|
||||||
|
return minIdleConnections;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getMaxLifetime() {
|
||||||
|
return maxLifetime;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getConnectionTimeout() {
|
||||||
|
return connectionTimeout;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Map<String, String> getProperties() {
|
||||||
|
return properties;
|
||||||
|
}
|
||||||
|
}
|
@ -19,6 +19,18 @@ npc-effects:
|
|||||||
show-requirements: true
|
show-requirements: true
|
||||||
show-titles: true
|
show-titles: true
|
||||||
strict-player-movement: 0
|
strict-player-movement: 0
|
||||||
|
storage-data:
|
||||||
|
address: localhost
|
||||||
|
database: minecraft
|
||||||
|
username: root
|
||||||
|
password: ''
|
||||||
|
table_prefix: 'quests_'
|
||||||
|
pool-settings:
|
||||||
|
max-pool-size: 10
|
||||||
|
min-idle: 10
|
||||||
|
max-lifetime: 1800000
|
||||||
|
connection-timeout: 5000
|
||||||
|
storage-method: yaml
|
||||||
top-limit: 150
|
top-limit: 150
|
||||||
translate-names: true
|
translate-names: true
|
||||||
translate-subcommands: false
|
translate-subcommands: false
|
Loading…
Reference in New Issue
Block a user