From 63ca5bb41351bb30da5ee799b1c477aea0aae326 Mon Sep 17 00:00:00 2001 From: Jules Date: Sun, 2 Apr 2023 00:52:00 +0200 Subject: [PATCH] Now supports multiple RPG cores at the same time --- .../java/net/Indyuce/mmoitems/MMOItems.java | 87 +++++++++++-------- .../mmoitems/api/player/PlayerData.java | 7 +- .../mmoitems/comp/rpg/AureliumSkillsHook.java | 1 - .../mmoitems/comp/rpg/ProSkillAPIHook.java | 28 +++--- .../mmoitems/comp/rpg/SkillAPIHook.java | 30 ++++--- MMOItems-Dist/src/main/resources/config.yml | 26 ++++-- 6 files changed, 108 insertions(+), 71 deletions(-) diff --git a/MMOItems-API/src/main/java/net/Indyuce/mmoitems/MMOItems.java b/MMOItems-API/src/main/java/net/Indyuce/mmoitems/MMOItems.java index c4b542fa..5823bc53 100644 --- a/MMOItems-API/src/main/java/net/Indyuce/mmoitems/MMOItems.java +++ b/MMOItems-API/src/main/java/net/Indyuce/mmoitems/MMOItems.java @@ -47,6 +47,7 @@ import org.bukkit.entity.Player; import org.bukkit.event.HandlerList; import org.bukkit.event.Listener; import org.bukkit.inventory.ItemStack; +import org.bukkit.plugin.Plugin; import org.bukkit.plugin.java.JavaPlugin; import org.bukkit.scheduler.BukkitRunnable; import org.jetbrains.annotations.NotNull; @@ -54,6 +55,7 @@ import org.jetbrains.annotations.NotNull; import javax.annotation.Nullable; import java.io.File; import java.util.ArrayList; +import java.util.Collections; import java.util.List; import java.util.logging.Level; @@ -83,7 +85,7 @@ public class MMOItems extends JavaPlugin { private SetManager setManager; private VaultSupport vaultSupport; - private RPGHandler rpgPlugin; + private final List rpgPlugins = new ArrayList<>(); /** * Startup issues usually prevent the plugin from loading and just @@ -152,7 +154,7 @@ public class MMOItems extends JavaPlugin { }); PluginUtils.hookDependencyIfPresent("MMOInventory", unused -> new MMOInventorySupport()); - findRpgPlugin(); + findRpgPlugins(); /* * After tiers, sets and upgrade templates are loaded, MI template data @@ -293,8 +295,19 @@ public class MMOItems extends JavaPlugin { return setManager; } + @Deprecated public RPGHandler getRPG() { - return rpgPlugin; + return getMainRPG(); + } + + @Nullable + public RPGHandler getMainRPG() { + Validate.isTrue(!rpgPlugins.isEmpty(), "No RPG plugin was found"); + return rpgPlugins.get(0); + } + + public List getRPGs() { + return rpgPlugins; } /** @@ -306,21 +319,38 @@ public class MMOItems extends JavaPlugin { * provider in the main plugin config. If it can't be found, it will look for RPG * plugins in the installed plugin list. */ - public void findRpgPlugin() { - if (rpgPlugin != null) return; + public void findRpgPlugins() { + Validate.isTrue(rpgPlugins.isEmpty(), "RPG hooks have already been computed"); - // Preferred rpg provider - String preferred = plugin.getConfig().getString("preferred-rpg-provider", null); - if (preferred != null && setRPG(RPGHandler.PluginEnum.valueOf(preferred.toUpperCase()))) - return; + // Default hook + rpgPlugins.add(new DefaultHook()); + + // Find preferred provider + final @NotNull String preferredName = plugin.getConfig().getString("preferred-rpg-provider"); // Look through installed plugins - for (RPGHandler.PluginEnum pluginEnum : RPGHandler.PluginEnum.values()) - if (Bukkit.getPluginManager().getPlugin(pluginEnum.getName()) != null && setRPG(pluginEnum)) - return; + for (RPGHandler.PluginEnum enumPlugin : RPGHandler.PluginEnum.values()) + if (Bukkit.getPluginManager().getPlugin(enumPlugin.getName()) != null) + try { + final RPGHandler handler = enumPlugin.load(); + rpgPlugins.add(handler); + getLogger().log(Level.INFO, "Hooked onto " + enumPlugin.getName()); - // Just use the default - setRPG(new DefaultHook()); + // Register as main RPG plugin + if (preferredName.equalsIgnoreCase(enumPlugin.name())) { + Collections.swap(rpgPlugins, 0, rpgPlugins.size() - 1); + getLogger().log(Level.INFO, "Now using " + enumPlugin.getName() + " as RPG core plugin"); + } + + } catch (Exception exception) { + MMOItems.plugin.getLogger().log(Level.WARNING, "Could not initialize RPG plugin compatibility with " + enumPlugin.getName() + ":"); + exception.printStackTrace(); + } + + // Register listener for preferred provider + final @NotNull RPGHandler preferred = rpgPlugins.get(0); + if (rpgPlugins.get(0) instanceof Listener) + Bukkit.getPluginManager().registerEvents((Listener) preferred, this); } /** @@ -330,14 +360,14 @@ public class MMOItems extends JavaPlugin { * * @param handler Your RPGHandler instance */ - public void setRPG(RPGHandler handler) { + public void setRPG(@NotNull RPGHandler handler) { Validate.notNull(handler, "RPGHandler cannot be null"); - // Unregister events from current RPGPlugin instance - if (rpgPlugin != null && rpgPlugin instanceof Listener && isEnabled()) - HandlerList.unregisterAll((Listener) rpgPlugin); + // Unregister old events + if (getMainRPG() instanceof Listener && isEnabled()) + HandlerList.unregisterAll((Plugin) getMainRPG()); - rpgPlugin = handler; + rpgPlugins.add(0, handler); getLogger().log(Level.INFO, "Now using " + handler.getClass().getSimpleName() + " as RPG provider"); // Register new events @@ -345,25 +375,6 @@ public class MMOItems extends JavaPlugin { Bukkit.getPluginManager().registerEvents((Listener) handler, this); } - /** - * @param potentialPlugin Some plugin that the user wants compatibility with - * @return If it worked - */ - public boolean setRPG(RPGHandler.PluginEnum potentialPlugin) { - - try { - Validate.notNull(Bukkit.getPluginManager().getPlugin(potentialPlugin.getName()), "Plugin is not installed"); - setRPG(potentialPlugin.load()); - return true; - - // Some loading issue - } catch (Exception exception) { - MMOItems.plugin.getLogger().log(Level.WARNING, "Could not initialize RPG plugin compatibility with " + potentialPlugin.getName() + ":"); - exception.printStackTrace(); - return false; - } - } - public PluginUpdateManager getUpdates() { return pluginUpdateManager; } diff --git a/MMOItems-API/src/main/java/net/Indyuce/mmoitems/api/player/PlayerData.java b/MMOItems-API/src/main/java/net/Indyuce/mmoitems/api/player/PlayerData.java index 45204eb6..f7c30dbb 100644 --- a/MMOItems-API/src/main/java/net/Indyuce/mmoitems/api/player/PlayerData.java +++ b/MMOItems-API/src/main/java/net/Indyuce/mmoitems/api/player/PlayerData.java @@ -63,7 +63,7 @@ public class PlayerData { private PlayerData(@NotNull MMOPlayerData mmoData) { this.mmoData = mmoData; - rpgPlayer = MMOItems.plugin.getRPG().getInfo(this); + rpgPlayer = MMOItems.plugin.getMainRPG().getInfo(this); stats = new PlayerStats(this); load(new ConfigFile("/userdata", getUniqueId().toString()).getConfig()); @@ -305,7 +305,7 @@ public class PlayerData { stats.updateStats(); // Update stats from external plugins - MMOItems.plugin.getRPG().refreshStats(this); + MMOItems.plugin.getRPGs().forEach(rpg -> rpg.refreshStats(this)); // Actually update cached player inventory so the task doesn't infinitely loop inventory.helmet = getPlayer().getInventory().getHelmet(); @@ -443,6 +443,7 @@ public class PlayerData { * Called when the corresponding MMOPlayerData has already been initialized. */ public static PlayerData load(@NotNull UUID player) { + /* * Double check they are online, for some reason even if this is fired * from the join event the player can be offline if they left in the @@ -460,7 +461,7 @@ public class PlayerData { * data of other rpg plugins */ PlayerData playerData = data.get(player); - playerData.rpgPlayer = MMOItems.plugin.getRPG().getInfo(playerData); + playerData.rpgPlayer = MMOItems.plugin.getMainRPG().getInfo(playerData); return playerData; } diff --git a/MMOItems-API/src/main/java/net/Indyuce/mmoitems/comp/rpg/AureliumSkillsHook.java b/MMOItems-API/src/main/java/net/Indyuce/mmoitems/comp/rpg/AureliumSkillsHook.java index 262c993e..9884c054 100644 --- a/MMOItems-API/src/main/java/net/Indyuce/mmoitems/comp/rpg/AureliumSkillsHook.java +++ b/MMOItems-API/src/main/java/net/Indyuce/mmoitems/comp/rpg/AureliumSkillsHook.java @@ -32,7 +32,6 @@ public class AureliumSkillsHook implements RPGHandler, Listener { private final Map statExtra = new HashMap<>(); - public AureliumSkillsHook() { aSkills = (AureliumSkills) Bukkit.getPluginManager().getPlugin("AureliumSkills"); diff --git a/MMOItems-API/src/main/java/net/Indyuce/mmoitems/comp/rpg/ProSkillAPIHook.java b/MMOItems-API/src/main/java/net/Indyuce/mmoitems/comp/rpg/ProSkillAPIHook.java index 32094687..e704690d 100644 --- a/MMOItems-API/src/main/java/net/Indyuce/mmoitems/comp/rpg/ProSkillAPIHook.java +++ b/MMOItems-API/src/main/java/net/Indyuce/mmoitems/comp/rpg/ProSkillAPIHook.java @@ -11,7 +11,9 @@ import io.lumine.mythic.lib.damage.AttackHandler; import io.lumine.mythic.lib.damage.AttackMetadata; import io.lumine.mythic.lib.damage.DamageMetadata; import io.lumine.mythic.lib.damage.DamageType; +import net.Indyuce.mmoitems.MMOItems; import net.Indyuce.mmoitems.api.player.RPGPlayer; +import org.bukkit.Bukkit; import org.bukkit.entity.Player; import org.bukkit.event.EventHandler; import org.bukkit.event.EventPriority; @@ -28,6 +30,7 @@ public class ProSkillAPIHook implements RPGHandler, Listener, AttackHandler { public ProSkillAPIHook() { MythicLib.plugin.getDamage().registerHandler(this); + Bukkit.getPluginManager().registerEvents(new InnerListener(), MMOItems.plugin); } @Override @@ -41,19 +44,22 @@ public class ProSkillAPIHook implements RPGHandler, Listener, AttackHandler { return damageInfo.get(event.getEntity().getEntityId()); } - @EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true) - public void a(SkillDamageEvent event) { - if (!(event.getDamager() instanceof Player)) - return; + class InnerListener implements Listener { - DamageMetadata damageMeta = new DamageMetadata(event.getDamage(), DamageType.SKILL); - AttackMetadata attackMeta = new AttackMetadata(damageMeta, event.getTarget(), MMOPlayerData.get(event.getDamager().getUniqueId()).getStatMap().cache(EquipmentSlot.MAIN_HAND)); - damageInfo.put(event.getTarget().getEntityId(), attackMeta); - } + @EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true) + public void a(SkillDamageEvent event) { + if (!(event.getDamager() instanceof Player)) + return; - @EventHandler(priority = EventPriority.MONITOR) - public void c(EntityDamageByEntityEvent event) { - damageInfo.remove(event.getEntity().getEntityId()); + DamageMetadata damageMeta = new DamageMetadata(event.getDamage(), DamageType.SKILL); + AttackMetadata attackMeta = new AttackMetadata(damageMeta, event.getTarget(), MMOPlayerData.get(event.getDamager().getUniqueId()).getStatMap().cache(EquipmentSlot.MAIN_HAND)); + damageInfo.put(event.getTarget().getEntityId(), attackMeta); + } + + @EventHandler(priority = EventPriority.MONITOR) + public void c(EntityDamageByEntityEvent event) { + damageInfo.remove(event.getEntity().getEntityId()); + } } @EventHandler diff --git a/MMOItems-API/src/main/java/net/Indyuce/mmoitems/comp/rpg/SkillAPIHook.java b/MMOItems-API/src/main/java/net/Indyuce/mmoitems/comp/rpg/SkillAPIHook.java index cb0db8c0..b04150ba 100644 --- a/MMOItems-API/src/main/java/net/Indyuce/mmoitems/comp/rpg/SkillAPIHook.java +++ b/MMOItems-API/src/main/java/net/Indyuce/mmoitems/comp/rpg/SkillAPIHook.java @@ -11,7 +11,9 @@ import io.lumine.mythic.lib.damage.AttackHandler; import io.lumine.mythic.lib.damage.AttackMetadata; import io.lumine.mythic.lib.damage.DamageMetadata; import io.lumine.mythic.lib.damage.DamageType; +import net.Indyuce.mmoitems.MMOItems; import net.Indyuce.mmoitems.api.player.RPGPlayer; +import org.bukkit.Bukkit; import org.bukkit.entity.Player; import org.bukkit.event.EventHandler; import org.bukkit.event.EventPriority; @@ -23,11 +25,12 @@ import org.jetbrains.annotations.Nullable; import java.util.HashMap; import java.util.Map; -public class SkillAPIHook implements RPGHandler, Listener, AttackHandler { +public class SkillAPIHook implements RPGHandler, AttackHandler { private final Map damageInfo = new HashMap<>(); public SkillAPIHook() { MythicLib.plugin.getDamage().registerHandler(this); + Bukkit.getPluginManager().registerEvents(new InnerListener(), MMOItems.plugin); } @Override @@ -41,19 +44,22 @@ public class SkillAPIHook implements RPGHandler, Listener, AttackHandler { return damageInfo.get(event.getEntity().getEntityId()); } - @EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true) - public void a(SkillDamageEvent event) { - if (!(event.getDamager() instanceof Player)) - return; + class InnerListener implements Listener { - DamageMetadata damageMeta = new DamageMetadata(event.getDamage(), DamageType.SKILL); - AttackMetadata attackMeta = new AttackMetadata(damageMeta, event.getTarget(), MMOPlayerData.get(event.getDamager().getUniqueId()).getStatMap().cache(EquipmentSlot.MAIN_HAND)); - damageInfo.put(event.getTarget().getEntityId(), attackMeta); - } + @EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true) + public void a(SkillDamageEvent event) { + if (!(event.getDamager() instanceof Player)) + return; - @EventHandler(priority = EventPriority.MONITOR) - public void c(EntityDamageByEntityEvent event) { - damageInfo.remove(event.getEntity().getEntityId()); + DamageMetadata damageMeta = new DamageMetadata(event.getDamage(), DamageType.SKILL); + AttackMetadata attackMeta = new AttackMetadata(damageMeta, event.getTarget(), MMOPlayerData.get(event.getDamager().getUniqueId()).getStatMap().cache(EquipmentSlot.MAIN_HAND)); + damageInfo.put(event.getTarget().getEntityId(), attackMeta); + } + + @EventHandler(priority = EventPriority.MONITOR) + public void b(EntityDamageByEntityEvent event) { + damageInfo.remove(event.getEntity().getEntityId()); + } } @EventHandler diff --git a/MMOItems-Dist/src/main/resources/config.yml b/MMOItems-Dist/src/main/resources/config.yml index cb094211..8c389625 100644 --- a/MMOItems-Dist/src/main/resources/config.yml +++ b/MMOItems-Dist/src/main/resources/config.yml @@ -15,6 +15,23 @@ iterate-whole-inventory: false # When this is set to true, skins can only be applied to an item ONCE. locked-skins: true +# Since 6.9.3 dev builds, MMOItems supports the use of multiple +# RPG core plugins at the same time. However, MMOItems needs one +# specific plugin to hook onto level, class, etc. +# +# Available plugins: +# - MMOCORE (level, class, mana, stamina) +# - HEROES (level, class, mana, stamina) +# - SKILLAPI or PROSKILLAPI (level, class, mana) +# - RPGPLAYERLEVELING (level, mana, power) +# - RACESANDCLASSES (level, class, mana) +# - BATTLELEVELS (level) +# - MCMMO (power level) +# - MCRPG (power level) +# - SKILLS or SKILLSPRO (class, level, mana) +# - AURELIUM_SKILLS (power level, mana) +preferred-rpg-provider: MMOCORE + # By default, all player inventories will be updated every # 10 ticks which corresponds to 2 inventory updates a second. inventory-update-delay: 10 @@ -103,11 +120,11 @@ soulbound: damage: base: 1 per-lvl: 1 - + # Whether or not soulbound items should be # kept when a player dies. keep-on-death: true - + # Whether or not soulbound item can be # dropped by the player can-drop: true @@ -194,7 +211,7 @@ action-bar-display: item-break: false recipes: - + # Enables the vanilla recipe book for MMOItems recipes use-recipe-book: true @@ -381,6 +398,3 @@ gem-upgrade-default: 'NEVER' # This option allows you to disable the ability to # use MMOItems that have been removed from your config. disable-removed-items: true - -# When I was a kid, I saw the Mona Lisa in my school art book... -# The fist time I saw her, with her hands on her knee... how do I say this... \ No newline at end of file