diff --git a/core/pom.xml b/core/pom.xml
index 1c5f6f79..7811a1d1 100644
--- a/core/pom.xml
+++ b/core/pom.xml
@@ -8,7 +8,7 @@
fr.skytasul
beautyquests-parent
- 0.19.1
+ 0.19.2
@@ -89,10 +89,10 @@
maven-central
https://oss.sonatype.org/content/groups/public
-
- teamvk-repo
- https://raw.githubusercontent.com/TeamVK/maven-repository/master/release/
-
+
+ teamvk-repo
+ https://raw.githubusercontent.com/TeamVK/maven-repository/master/release/
+
lumine
https://mvn.lumine.io/repository/maven-public/
@@ -123,7 +123,7 @@
org.spigotmc
spigot
- 1.18-R0.1-SNAPSHOT
+ 1.18.2-R0.1-SNAPSHOT
provided
@@ -136,7 +136,7 @@
org.mcmonkey
sentinel
- 2.4.0-SNAPSHOT
+ 2.5.0-SNAPSHOT
provided
@@ -210,6 +210,12 @@
4.12.0
provided
+
+ io.lumine
+ Mythic-Dist
+ 5.0.1
+ provided
+
com.github.promcteam
proskillapi
@@ -234,6 +240,12 @@
18.37.1
provided
+
+ org.mariadb.jdbc
+ mariadb-java-client
+ 2.7.5
+ provided
+
diff --git a/core/src/main/java/fr/skytasul/quests/BeautyQuests.java b/core/src/main/java/fr/skytasul/quests/BeautyQuests.java
index 3105fcab..a6c0a5d7 100644
--- a/core/src/main/java/fr/skytasul/quests/BeautyQuests.java
+++ b/core/src/main/java/fr/skytasul/quests/BeautyQuests.java
@@ -35,7 +35,6 @@
import fr.skytasul.quests.api.QuestsAPI;
import fr.skytasul.quests.api.bossbar.BQBossBarImplementation;
-import fr.skytasul.quests.api.npcs.BQNPC;
import fr.skytasul.quests.commands.Commands;
import fr.skytasul.quests.commands.CommandsManager;
import fr.skytasul.quests.editors.Editor;
@@ -51,7 +50,6 @@
import fr.skytasul.quests.players.PlayersManagerDB;
import fr.skytasul.quests.players.PlayersManagerYAML;
import fr.skytasul.quests.scoreboards.ScoreboardManager;
-import fr.skytasul.quests.structure.NPCStarter;
import fr.skytasul.quests.structure.Quest;
import fr.skytasul.quests.structure.QuestsManager;
import fr.skytasul.quests.structure.pools.QuestPoolsManager;
@@ -84,11 +82,10 @@ public class BeautyQuests extends JavaPlugin {
private YamlConfiguration data;
private File dataFile;
- public static File saveFolder;
+ private File saveFolder;
/* --------- Datas --------- */
- private Map npcs = new HashMap<>();
private ScoreboardManager scoreboards;
private QuestsManager quests;
private QuestPoolsManager pools;
@@ -122,6 +119,8 @@ public void onLoad(){
@Override
public void onEnable(){
try {
+ logger.info("------------ BeautyQuests ------------");
+
dependencies.testCompatibilities();
Bukkit.getPluginManager().registerEvents(dependencies, this);
@@ -137,7 +136,7 @@ public void onEnable(){
try {
dependencies.initializeCompatibilities();
}catch (Exception ex) {
- logger.severe("Error when initializing compatibilities. Consider restarting.", ex);
+ logger.severe("An error occurred while initializing compatibilities. Consider restarting.", ex);
}
if (QuestsAPI.getNPCsManager() == null) {
@@ -161,7 +160,11 @@ public void run() {
if (!lastVersion.equals(pluginVersion)) { // maybe change in data structure : update of all quest files
DebugUtils.logMessage("Migrating from " + lastVersion + " to " + pluginVersion);
- for (Quest qu : quests) qu.saveToFile();
+ int updated = 0;
+ for (Quest qu : quests) {
+ if (qu.saveToFile()) updated++;
+ }
+ if (updated > 0) logger.info("Updated " + updated + " quests during migration.");
saveAllConfig(false);
}
}catch (Throwable e) {
@@ -169,7 +172,6 @@ public void run() {
}
}
}.runTaskLater(this, QuestsAPI.getNPCsManager().getTimeToWaitForNPCs());
-
// Start of non-essential systems
if (loggerHandler != null) loggerHandler.launchFlushTimer();
@@ -249,7 +251,7 @@ public void run() {
}
}
};
- logger.info("Periodic saves task started (" + cycle + " ticks). Task ID: " + saveTask.runTaskTimer(this, cycle, cycle).getTaskId());
+ logger.info("Periodic saves task started (" + cycle + " ticks). Task ID: " + saveTask.runTaskTimerAsynchronously(this, cycle, cycle).getTaskId());
}
}
@@ -294,7 +296,7 @@ private void launchMetrics(String pluginVersion) {
private void launchUpdateChecker(String pluginVersion) throws ReflectiveOperationException {
DebugUtils.logMessage("Starting Spigot updater");
if (pluginVersion.contains("_")) {
- Matcher matcher = Pattern.compile("_BUILD(.+)").matcher(pluginVersion);
+ Matcher matcher = Pattern.compile("_BUILD(\\d+)").matcher(pluginVersion);
if (matcher.find()) {
String build = matcher.group(1);
UpdateChecker.init(instance, "https://ci.codemc.io/job/SkytAsul/job/BeautyQuests/lastSuccessfulBuild/buildNumber")
@@ -330,13 +332,16 @@ private void loadConfigParameters(boolean init) throws LoadingException {
ConfigurationSection dbConfig = config.getConfig().getConfigurationSection("database");
if (dbConfig.getBoolean("enabled")) {
- db = new Database(dbConfig);
- if (db.openConnection()) {
+ try {
+ db = new Database(dbConfig);
+ db.testConnection();
logger.info("Connection to database etablished.");
- }else {
- db.closeConnection();
- db = null;
- throw new LoadingException("Connection to database has failed.");
+ }catch (Exception ex) {
+ if (db != null) {
+ db.closeConnection();
+ db = null;
+ }
+ throw new LoadingException("Connection to database has failed.", ex);
}
}
@@ -486,7 +491,7 @@ private void loadAllDatas() throws Throwable {
public void saveAllConfig(boolean unload) throws Exception {
if (unload) {
- quests.unloadQuests();
+ if (quests != null) quests.unloadQuests();
QuestsAPI.getQuestsHandlers().forEach(handler -> {
try {
@@ -498,6 +503,7 @@ public void saveAllConfig(boolean unload) throws Exception {
}
if (loaded) {
+ long time = System.currentTimeMillis();
data.set("lastID", quests.getLastID());
data.set("version", getDescription().getVersion());
@@ -508,18 +514,18 @@ public void saveAllConfig(boolean unload) throws Exception {
logger.severe("Error when saving player datas.", ex);
}
data.save(dataFile);
+ DebugUtils.logMessage("Saved datas (" + (((double) System.currentTimeMillis() - time) / 1000D) + "s)!");
}
if (unload){
+ QuestsAPI.getNPCsManager().unload();
resetDatas();
}
}
private void resetDatas(){
- npcs.values().forEach(NPCStarter::removeHolograms);
quests = null;
pools = null;
- npcs.clear();
if (db != null) db.closeConnection();
//HandlerList.unregisterAll(this);
loaded = false;
@@ -616,10 +622,6 @@ public void run() {
public QuestsConfiguration getConfiguration() {
return config;
}
-
- public Map getNPCs() {
- return npcs;
- }
public FileConfiguration getDataFile(){
return data;
diff --git a/core/src/main/java/fr/skytasul/quests/QuestsConfiguration.java b/core/src/main/java/fr/skytasul/quests/QuestsConfiguration.java
index b4a6ae6d..53d8bcd0 100644
--- a/core/src/main/java/fr/skytasul/quests/QuestsConfiguration.java
+++ b/core/src/main/java/fr/skytasul/quests/QuestsConfiguration.java
@@ -17,6 +17,7 @@
import com.google.common.collect.Sets;
import fr.skytasul.quests.api.QuestsAPI;
+import fr.skytasul.quests.gui.ItemUtils;
import fr.skytasul.quests.gui.quests.PlayerListGUI.Category;
import fr.skytasul.quests.structure.QuestBranch.Source;
import fr.skytasul.quests.structure.QuestDescription;
@@ -155,6 +156,7 @@ void init() {
}else if (config.isString("item")) {
item = XMaterial.matchXMaterial(config.getString("item")).orElse(XMaterial.BOOK).parseItem();
}else item = XMaterial.BOOK.parseItem();
+ item = ItemUtils.clearVisibleAttributes(item);
if (config.contains("pageItem")) pageItem = XMaterial.matchXMaterial(config.getString("pageItem")).orElse(XMaterial.ARROW);
if (pageItem == null) pageItem = XMaterial.ARROW;
startParticleDistance = config.getInt("startParticleDistance");
diff --git a/core/src/main/java/fr/skytasul/quests/QuestsListener.java b/core/src/main/java/fr/skytasul/quests/QuestsListener.java
index 7e419423..804b6896 100644
--- a/core/src/main/java/fr/skytasul/quests/QuestsListener.java
+++ b/core/src/main/java/fr/skytasul/quests/QuestsListener.java
@@ -38,9 +38,9 @@
import fr.skytasul.quests.players.PlayersManager;
import fr.skytasul.quests.players.events.PlayerAccountJoinEvent;
import fr.skytasul.quests.players.events.PlayerAccountLeaveEvent;
-import fr.skytasul.quests.structure.NPCStarter;
import fr.skytasul.quests.structure.Quest;
import fr.skytasul.quests.structure.pools.QuestPool;
+import fr.skytasul.quests.utils.DebugUtils;
import fr.skytasul.quests.utils.Lang;
import fr.skytasul.quests.utils.Utils;
import fr.skytasul.quests.utils.XMaterial;
@@ -57,67 +57,65 @@ public void onNPCClick(BQNPCClickEvent e) {
if (Inventories.isInSystem(p)) return;
- NPCStarter starter = BeautyQuests.getInstance().getNPCs().get(npc);
- if (starter != null) {
- PlayerAccount acc = PlayersManager.getPlayerAccount(p);
- if (acc == null) return;
-
- Set quests = starter.getQuests();
- quests = quests.stream().filter(qu -> !qu.hasStarted(acc) && (qu.isRepeatable() ? true : !qu.hasFinished(acc))).collect(Collectors.toSet());
- if (quests.isEmpty() && starter.getPools().isEmpty()) return;
-
- List launcheable = new ArrayList<>();
- List requirements = new ArrayList<>();
- List timer = new ArrayList<>();
- for (Quest qu : quests) {
- try {
- if (!qu.testRequirements(p, acc, false)) {
- requirements.add(qu);
- }else if (!qu.testTimer(acc, false)) {
- timer.add(qu);
- }else launcheable.add(qu);
- }catch (Exception ex) {
- BeautyQuests.logger.severe("An exception occured when checking requirements on the quest " + qu.getID() + " for player " + p.getName(), ex);
- }
+ PlayerAccount acc = PlayersManager.getPlayerAccount(p);
+ if (acc == null) return;
+
+ Set quests = npc.getQuests();
+ quests = quests.stream().filter(qu -> !qu.hasStarted(acc) && (qu.isRepeatable() ? true : !qu.hasFinished(acc))).collect(Collectors.toSet());
+ if (quests.isEmpty() && npc.getPools().isEmpty()) return;
+
+ List launcheable = new ArrayList<>();
+ List requirements = new ArrayList<>();
+ List timer = new ArrayList<>();
+ for (Quest qu : quests) {
+ try {
+ if (!qu.testRequirements(p, acc, false)) {
+ requirements.add(qu);
+ }else if (!qu.testTimer(acc, false)) {
+ timer.add(qu);
+ }else launcheable.add(qu);
+ }catch (Exception ex) {
+ BeautyQuests.logger.severe("An exception occured when checking requirements on the quest " + qu.getID() + " for player " + p.getName(), ex);
}
-
- Set startablePools = starter.getPools().stream().filter(pool -> {
- try {
- return pool.canGive(p, acc);
- }catch (Exception ex) {
- BeautyQuests.logger.severe("An exception occured when checking requirements on the pool " + pool.getID() + " for player " + p.getName(), ex);
- return false;
- }
- }).collect(Collectors.toSet());
-
- e.setCancelled(true);
- if (!launcheable.isEmpty()) {
- for (Quest quest : launcheable) {
- if (quest.isInDialog(p)) {
- quest.clickNPC(p);
- return;
- }
- }
- ChooseQuestGUI gui = new ChooseQuestGUI(launcheable, (quest) -> {
- if (quest == null) return;
+ }
+
+ Set startablePools = npc.getPools().stream().filter(pool -> {
+ try {
+ return pool.canGive(p, acc);
+ }catch (Exception ex) {
+ BeautyQuests.logger.severe("An exception occured when checking requirements on the pool " + pool.getID() + " for player " + p.getName(), ex);
+ return false;
+ }
+ }).collect(Collectors.toSet());
+
+ e.setCancelled(true);
+ if (!launcheable.isEmpty()) {
+ for (Quest quest : launcheable) {
+ if (quest.isInDialog(p)) {
quest.clickNPC(p);
- });
- gui.setValidate(__ -> {
- new PlayerListGUI(acc).create(p);
- }, ItemUtils.item(XMaterial.BOOKSHELF, Lang.questMenu.toString(), QuestOption.formatDescription(Lang.questMenuLore.toString())));
- gui.create(p);
- }else if (!startablePools.isEmpty()) {
- startablePools.iterator().next().give(p);
- }else {
- if (!timer.isEmpty()) {
- timer.get(0).testTimer(acc, true);
- }else if (!requirements.isEmpty()) {
- requirements.get(0).testRequirements(p, acc, true);
- }else {
- Utils.sendMessage(p, starter.getPools().iterator().next().give(p));
+ return;
}
- e.setCancelled(false);
}
+ ChooseQuestGUI gui = new ChooseQuestGUI(launcheable, (quest) -> {
+ if (quest == null) return;
+ quest.clickNPC(p);
+ });
+ gui.setValidate(__ -> {
+ new PlayerListGUI(acc).create(p);
+ }, ItemUtils.item(XMaterial.BOOKSHELF, Lang.questMenu.toString(), QuestOption.formatDescription(Lang.questMenuLore.toString())));
+ gui.create(p);
+ }else if (!startablePools.isEmpty()) {
+ QuestPool pool = startablePools.iterator().next();
+ DebugUtils.logMessage("NPC " + npc.getId() + ": " + startablePools.size() + " pools, result: " + pool.give(p));
+ }else {
+ if (!timer.isEmpty()) {
+ timer.get(0).testTimer(acc, true);
+ }else if (!requirements.isEmpty()) {
+ requirements.get(0).testRequirements(p, acc, true);
+ }else {
+ Utils.sendMessage(p, npc.getPools().iterator().next().give(p));
+ }
+ e.setCancelled(false);
}
}
diff --git a/core/src/main/java/fr/skytasul/quests/api/QuestsAPI.java b/core/src/main/java/fr/skytasul/quests/api/QuestsAPI.java
index de21a31e..5bb5579c 100644
--- a/core/src/main/java/fr/skytasul/quests/api/QuestsAPI.java
+++ b/core/src/main/java/fr/skytasul/quests/api/QuestsAPI.java
@@ -1,8 +1,6 @@
package fr.skytasul.quests.api;
-import java.util.ArrayList;
import java.util.Collection;
-import java.util.Collections;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
@@ -11,14 +9,12 @@
import org.apache.commons.lang.Validate;
import org.bukkit.Bukkit;
-import org.bukkit.entity.Player;
import org.bukkit.event.HandlerList;
import fr.skytasul.quests.BeautyQuests;
import fr.skytasul.quests.api.bossbar.BQBossBarManager;
import fr.skytasul.quests.api.comparison.ItemComparison;
import fr.skytasul.quests.api.mobs.MobFactory;
-import fr.skytasul.quests.api.npcs.BQNPC;
import fr.skytasul.quests.api.npcs.BQNPCsManager;
import fr.skytasul.quests.api.objects.QuestObjectsRegistry;
import fr.skytasul.quests.api.options.QuestOptionCreator;
@@ -28,16 +24,12 @@
import fr.skytasul.quests.api.rewards.RewardCreator;
import fr.skytasul.quests.api.stages.AbstractStage;
import fr.skytasul.quests.api.stages.StageType;
-import fr.skytasul.quests.players.PlayerAccount;
-import fr.skytasul.quests.players.PlayersManager;
-import fr.skytasul.quests.structure.NPCStarter;
-import fr.skytasul.quests.structure.Quest;
import fr.skytasul.quests.structure.QuestsManager;
import fr.skytasul.quests.structure.pools.QuestPoolsManager;
import fr.skytasul.quests.utils.DebugUtils;
import fr.skytasul.quests.utils.Lang;
-public class QuestsAPI {
+public final class QuestsAPI {
private static final QuestObjectsRegistry requirements = new QuestObjectsRegistry<>(Lang.INVENTORY_REQUIREMENTS.toString());
private static final QuestObjectsRegistry rewards = new QuestObjectsRegistry<>(Lang.INVENTORY_REWARDS.toString());
@@ -50,11 +42,11 @@ public class QuestsAPI {
private static final Set handlers = new HashSet<>();
+ private QuestsAPI() {}
+
/**
* Register new stage type into the plugin
- * @param type StageType object
- * @param item ItemStack shown in stages GUI when choosing stage type
- * @param runnables Instance of special runnables
+ * @param creator StageType instance
*/
public static void registerStage(StageType creator) {
stages.add(creator);
@@ -116,6 +108,7 @@ public static void setHologramsManager(AbstractHolograms> newHologramsManager)
Validate.notNull(newHologramsManager);
if (hologramsManager != null) BeautyQuests.logger.warning(newHologramsManager.getClass().getSimpleName() + " will replace " + hologramsManager.getClass().getSimpleName() + " as the new holograms manager.");
hologramsManager = newHologramsManager;
+ DebugUtils.logMessage("Holograms manager has been registered: " + newHologramsManager.getClass().getName());
}
public static boolean hasBossBarManager() {
@@ -130,6 +123,7 @@ public static void setBossBarManager(BQBossBarManager newBossBarManager) {
Validate.notNull(newBossBarManager);
if (bossBarManager != null) BeautyQuests.logger.warning(newBossBarManager.getClass().getSimpleName() + " will replace " + hologramsManager.getClass().getSimpleName() + " as the new boss bar manager.");
bossBarManager = newBossBarManager;
+ DebugUtils.logMessage("Bossbars manager has been registered: " + newBossBarManager.getClass().getName());
}
public static void registerQuestsHandler(QuestsHandler handler) {
@@ -155,24 +149,6 @@ public static void propagateQuestsHandlers(Consumer consumer) {
}
});
}
-
- public static List getQuestsAssigneds(BQNPC npc) {
- NPCStarter starter = BeautyQuests.getInstance().getNPCs().get(npc);
- return starter == null ? Collections.emptyList() : new ArrayList<>(starter.getQuests());
- }
-
- public static boolean isQuestStarter(BQNPC npc) {
- NPCStarter starter = BeautyQuests.getInstance().getNPCs().get(npc);
- return starter != null && !starter.getQuests().isEmpty();
- }
-
- public static boolean hasQuestStarted(Player p, BQNPC npc) {
- PlayerAccount acc = PlayersManager.getPlayerAccount(p);
- for (Quest qu : getQuestsAssigneds(npc)){
- if (qu.hasStarted(acc)) return true;
- }
- return false;
- }
public static QuestsManager getQuests() {
return BeautyQuests.getInstance().getQuestsManager();
diff --git a/core/src/main/java/fr/skytasul/quests/api/mobs/MobFactory.java b/core/src/main/java/fr/skytasul/quests/api/mobs/MobFactory.java
index 83efbfa6..8f32bf2c 100644
--- a/core/src/main/java/fr/skytasul/quests/api/mobs/MobFactory.java
+++ b/core/src/main/java/fr/skytasul/quests/api/mobs/MobFactory.java
@@ -25,7 +25,7 @@
/**
* This class implements {@link Listener} to permit the implementation to have at least one {@link EventHandler}.
- * This event method will be used to fire {@link #callEvent(Object, Entity, Player)}.
+ * This event method will be used to fire the {@link #callEvent(Event, Object, Entity, Player)}.
*
* @param object which should represents a mob type from whatever plugin
*/
diff --git a/core/src/main/java/fr/skytasul/quests/api/npcs/BQNPC.java b/core/src/main/java/fr/skytasul/quests/api/npcs/BQNPC.java
index 074bbc2b..0bc34aed 100644
--- a/core/src/main/java/fr/skytasul/quests/api/npcs/BQNPC.java
+++ b/core/src/main/java/fr/skytasul/quests/api/npcs/BQNPC.java
@@ -1,9 +1,62 @@
package fr.skytasul.quests.api.npcs;
+import java.util.*;
+import java.util.Map.Entry;
+import java.util.function.BiPredicate;
+
+import org.apache.commons.lang.StringUtils;
import org.bukkit.Location;
import org.bukkit.entity.Entity;
+import org.bukkit.entity.LivingEntity;
+import org.bukkit.entity.Player;
+import org.bukkit.inventory.ItemStack;
+import org.bukkit.scheduler.BukkitRunnable;
+import org.bukkit.scheduler.BukkitTask;
+
+import fr.skytasul.quests.BeautyQuests;
+import fr.skytasul.quests.QuestsConfiguration;
+import fr.skytasul.quests.api.AbstractHolograms;
+import fr.skytasul.quests.api.QuestsAPI;
+import fr.skytasul.quests.options.OptionHologramLaunch;
+import fr.skytasul.quests.options.OptionHologramLaunchNo;
+import fr.skytasul.quests.options.OptionHologramText;
+import fr.skytasul.quests.options.OptionStarterNPC;
+import fr.skytasul.quests.players.PlayerAccount;
+import fr.skytasul.quests.players.PlayersManager;
+import fr.skytasul.quests.structure.Quest;
+import fr.skytasul.quests.structure.pools.QuestPool;
+import fr.skytasul.quests.utils.DebugUtils;
+import fr.skytasul.quests.utils.Lang;
+import fr.skytasul.quests.utils.Utils;
-public interface BQNPC {
+public abstract class BQNPC {
+
+ private Set quests = new TreeSet<>();
+ private Set pools = new TreeSet<>();
+
+ private List> hiddenTickets = new ArrayList<>();
+ private Map