mirror of
https://gitlab.com/phoenix-dvpmt/mmocore.git
synced 2024-11-26 00:35:17 +01:00
Merge remote-tracking branch 'origin/master'
# Conflicts: # MMOCore-API/src/main/java/net/Indyuce/mmocore/comp/placeholder/RPGPlaceholders.java
This commit is contained in:
commit
4d98b8b307
@ -139,6 +139,14 @@
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>fr.phoenixdevt</groupId>
|
||||
<artifactId>Profile-API</artifactId>
|
||||
<version>1.0</version>
|
||||
<scope>provided</scope>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>me.clip</groupId>
|
||||
<artifactId>placeholderapi</artifactId>
|
||||
|
@ -2,6 +2,7 @@ package net.Indyuce.mmocore;
|
||||
|
||||
import io.lumine.mythic.lib.MythicLib;
|
||||
import io.lumine.mythic.lib.UtilityMethods;
|
||||
import io.lumine.mythic.lib.data.sql.SQLDataSource;
|
||||
import io.lumine.mythic.lib.metrics.bukkit.Metrics;
|
||||
import io.lumine.mythic.lib.version.SpigotPlugin;
|
||||
import net.Indyuce.mmocore.api.player.PlayerData;
|
||||
@ -28,10 +29,13 @@ import net.Indyuce.mmocore.guild.GuildModuleType;
|
||||
import net.Indyuce.mmocore.guild.GuildRelationHandler;
|
||||
import net.Indyuce.mmocore.guild.provided.Guild;
|
||||
import net.Indyuce.mmocore.guild.provided.MMOCoreGuildModule;
|
||||
import net.Indyuce.mmocore.guild.provided.YAMLGuildDataManager;
|
||||
import net.Indyuce.mmocore.manager.*;
|
||||
import net.Indyuce.mmocore.manager.data.DataProvider;
|
||||
import net.Indyuce.mmocore.manager.data.mysql.MySQLDataProvider;
|
||||
import net.Indyuce.mmocore.manager.data.yaml.YAMLDataProvider;
|
||||
import net.Indyuce.mmocore.manager.data.GuildDataManager;
|
||||
import net.Indyuce.mmocore.manager.data.LegacyDataProvider;
|
||||
import net.Indyuce.mmocore.manager.data.PlayerDataManager;
|
||||
import net.Indyuce.mmocore.manager.data.sql.SQLDataHandler;
|
||||
import net.Indyuce.mmocore.manager.profession.*;
|
||||
import net.Indyuce.mmocore.manager.social.BoosterManager;
|
||||
import net.Indyuce.mmocore.manager.social.PartyManager;
|
||||
@ -48,6 +52,7 @@ import net.Indyuce.mmocore.skill.cast.SkillCastingMode;
|
||||
import org.apache.commons.lang.Validate;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.ChatColor;
|
||||
import org.bukkit.event.EventPriority;
|
||||
import org.bukkit.plugin.java.JavaPlugin;
|
||||
import org.bukkit.scheduler.BukkitRunnable;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
@ -76,6 +81,10 @@ public class MMOCore extends JavaPlugin {
|
||||
public final RestrictionManager restrictionManager = new RestrictionManager();
|
||||
public final SkillTreeManager skillTreeManager = new SkillTreeManager();
|
||||
public final StatManager statManager = new StatManager();
|
||||
public final GuildDataManager nativeGuildManager = new YAMLGuildDataManager();
|
||||
public final PlayerDataManager playerDataManager = new PlayerDataManager(this);
|
||||
@Deprecated
|
||||
public final DataProvider dataProvider = new LegacyDataProvider();
|
||||
|
||||
// Profession managers
|
||||
public final CustomBlockManager mineManager = new CustomBlockManager();
|
||||
@ -89,7 +98,6 @@ public class MMOCore extends JavaPlugin {
|
||||
public VaultEconomy economy;
|
||||
public RegionHandler regionHandler = new DefaultRegionHandler();
|
||||
public PlaceholderParser placeholderParser = new DefaultParser();
|
||||
public DataProvider dataProvider = new YAMLDataProvider();
|
||||
|
||||
// Modules
|
||||
@NotNull
|
||||
@ -102,6 +110,7 @@ public class MMOCore extends JavaPlugin {
|
||||
|
||||
@Override
|
||||
public void onLoad() {
|
||||
getLogger().log(Level.INFO, "Plugin file is called '" + getFile().getName() + "'");
|
||||
|
||||
// Register MMOCore-specific objects
|
||||
MythicLib.plugin.getEntities().registerRelationHandler(new PartyRelationHandler());
|
||||
@ -140,8 +149,10 @@ public class MMOCore extends JavaPlugin {
|
||||
getLogger().warning("(Your config version: '" + configVersion + "' | Expected config version: '" + defConfigVersion + "')");
|
||||
}
|
||||
|
||||
if (getConfig().isConfigurationSection("mysql") && getConfig().getBoolean("mysql.enabled"))
|
||||
dataProvider = new MySQLDataProvider(getConfig());
|
||||
if (getConfig().isConfigurationSection("mysql") && getConfig().getBoolean("mysql.enabled")) {
|
||||
final SQLDataSource dataSource = new SQLDataSource(this);
|
||||
playerDataManager.setDataHandler(new SQLDataHandler(dataSource));
|
||||
}
|
||||
|
||||
if (getConfig().isConfigurationSection("default-playerdata"))
|
||||
dataProvider.getDataManager().loadDefaultData(getConfig().getConfigurationSection("default-playerdata"));
|
||||
@ -228,7 +239,8 @@ public class MMOCore extends JavaPlugin {
|
||||
// Skill casting
|
||||
try {
|
||||
SkillCastingMode mode = SkillCastingMode.valueOf(UtilityMethods.enumName(getConfig().getString("skill-casting.mode")));
|
||||
Bukkit.getPluginManager().registerEvents(mode.loadFromConfig(getConfig().getConfigurationSection("skill-casting")), this);
|
||||
mode.setCurrent(getConfig().getConfigurationSection("skill-casting"));
|
||||
|
||||
} catch (RuntimeException exception) {
|
||||
getLogger().log(Level.WARNING, "Could not load skill casting: " + exception.getMessage());
|
||||
}
|
||||
@ -237,6 +249,7 @@ public class MMOCore extends JavaPlugin {
|
||||
try {
|
||||
Class.forName("net.Indyuce.mmocore.MMOCoreBukkit").getConstructor(MMOCore.class).newInstance(this);
|
||||
} catch (Throwable exception) {
|
||||
exception.printStackTrace();
|
||||
throw new RuntimeException("Cannot run an API build on Spigot!");
|
||||
}
|
||||
|
||||
@ -245,7 +258,7 @@ public class MMOCore extends JavaPlugin {
|
||||
* that after registering all the professses otherwise the player datas can't
|
||||
* recognize what profess the player has and professes will be lost
|
||||
*/
|
||||
Bukkit.getOnlinePlayers().forEach(player -> dataProvider.getDataManager().setup(player.getUniqueId()));
|
||||
playerDataManager.initialize(EventPriority.NORMAL, EventPriority.NORMAL);
|
||||
|
||||
// load guild data after loading player data
|
||||
dataProvider.getGuildManager().load();
|
||||
@ -257,23 +270,6 @@ public class MMOCore extends JavaPlugin {
|
||||
MMOCoreCommandTreeRoot mmoCoreCommand = new MMOCoreCommandTreeRoot();
|
||||
getCommand("mmocore").setExecutor(mmoCoreCommand);
|
||||
getCommand("mmocore").setTabCompleter(mmoCoreCommand);
|
||||
|
||||
if (getConfig().getBoolean("auto-save.enabled")) {
|
||||
int autosave = getConfig().getInt("auto-save.interval") * 20;
|
||||
new BukkitRunnable() {
|
||||
public void run() {
|
||||
|
||||
// Save player data
|
||||
for (PlayerData data : PlayerData.getAll())
|
||||
if (data.isFullyLoaded())
|
||||
dataProvider.getDataManager().saveData(data, false);
|
||||
|
||||
// Save guild info
|
||||
for (Guild guild : dataProvider.getGuildManager().getAll())
|
||||
dataProvider.getGuildManager().save(guild);
|
||||
}
|
||||
}.runTaskTimerAsynchronously(MMOCore.plugin, autosave, autosave);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -288,11 +284,9 @@ public class MMOCore extends JavaPlugin {
|
||||
|
||||
// Save player data
|
||||
for (PlayerData data : PlayerData.getAll())
|
||||
if (data.isFullyLoaded()) {
|
||||
if (data.isSynchronized()) {
|
||||
data.close();
|
||||
//Saves player health before saveData as the player will be considered offline into it if it is async.
|
||||
data.setHealth(data.getPlayer().getHealth());
|
||||
dataProvider.getDataManager().saveData(data, true);
|
||||
dataProvider.getDataManager().getDataHandler().saveData(data, true);
|
||||
}
|
||||
|
||||
// Save guild info
|
||||
@ -300,8 +294,7 @@ public class MMOCore extends JavaPlugin {
|
||||
dataProvider.getGuildManager().save(guild);
|
||||
|
||||
// Close MySQL data provider (memory leaks)
|
||||
if (dataProvider instanceof MySQLDataProvider)
|
||||
((MySQLDataProvider) dataProvider).close();
|
||||
playerDataManager.getDataHandler().close();
|
||||
|
||||
// Reset active blocks
|
||||
mineManager.resetRemainingBlocks();
|
||||
|
@ -6,7 +6,6 @@ public enum SoundEvent {
|
||||
WARP_CANCELLED,
|
||||
WARP_CHARGE,
|
||||
WARP_UNLOCK,
|
||||
HOTBAR_SWAP,
|
||||
SPELL_CAST_BEGIN,
|
||||
SPELL_CAST_END,
|
||||
CANT_SELECT_CLASS,
|
||||
|
@ -1,29 +0,0 @@
|
||||
package net.Indyuce.mmocore.api.event;
|
||||
|
||||
import net.Indyuce.mmocore.api.player.PlayerData;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.Event;
|
||||
|
||||
/**
|
||||
* In order to create bukkit async events we must call
|
||||
* the right constructor:
|
||||
* <p>
|
||||
* {@link Event#Event(boolean)} and have the boolean set to true
|
||||
*/
|
||||
public abstract class AsyncPlayerDataEvent extends Event {
|
||||
private final PlayerData playerData;
|
||||
|
||||
public AsyncPlayerDataEvent(PlayerData playerData) {
|
||||
super(true);
|
||||
|
||||
this.playerData = playerData;
|
||||
}
|
||||
|
||||
public PlayerData getData() {
|
||||
return playerData;
|
||||
}
|
||||
|
||||
public Player getPlayer() {
|
||||
return playerData.getPlayer();
|
||||
}
|
||||
}
|
@ -1,27 +0,0 @@
|
||||
package net.Indyuce.mmocore.api.event;
|
||||
|
||||
import net.Indyuce.mmocore.api.player.PlayerData;
|
||||
import org.bukkit.event.HandlerList;
|
||||
|
||||
public class AsyncPlayerDataLoadEvent extends AsyncPlayerDataEvent {
|
||||
private static final HandlerList handlers = new HandlerList();
|
||||
|
||||
/**
|
||||
* Called when a player data is being loaded into the game.
|
||||
* This event is called async.
|
||||
*
|
||||
* @param playerData Player data being loaded
|
||||
*/
|
||||
public AsyncPlayerDataLoadEvent(PlayerData playerData) {
|
||||
super(playerData);
|
||||
}
|
||||
|
||||
@Override
|
||||
public HandlerList getHandlers() {
|
||||
return handlers;
|
||||
}
|
||||
|
||||
public static HandlerList getHandlerList() {
|
||||
return handlers;
|
||||
}
|
||||
}
|
@ -1,32 +0,0 @@
|
||||
package net.Indyuce.mmocore.api.player;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
import net.Indyuce.mmocore.MMOCore;
|
||||
import net.Indyuce.mmocore.api.player.profess.PlayerClass;
|
||||
|
||||
public abstract class OfflinePlayerData {
|
||||
private final UUID uuid;
|
||||
|
||||
public OfflinePlayerData(UUID uuid) {
|
||||
this.uuid = uuid;
|
||||
}
|
||||
|
||||
public UUID getUniqueId() {
|
||||
return uuid;
|
||||
}
|
||||
|
||||
public abstract void removeFriend(UUID uuid);
|
||||
|
||||
public abstract boolean hasFriend(UUID uuid);
|
||||
|
||||
public abstract PlayerClass getProfess();
|
||||
|
||||
public abstract int getLevel();
|
||||
|
||||
public abstract long getLastLogin();
|
||||
|
||||
public static OfflinePlayerData get(UUID uuid) {
|
||||
return MMOCore.plugin.dataProvider.getDataManager().getOffline(uuid);
|
||||
}
|
||||
}
|
@ -4,6 +4,7 @@ import io.lumine.mythic.lib.MythicLib;
|
||||
import io.lumine.mythic.lib.api.player.MMOPlayerData;
|
||||
import io.lumine.mythic.lib.api.stat.StatInstance;
|
||||
import io.lumine.mythic.lib.api.stat.modifier.StatModifier;
|
||||
import io.lumine.mythic.lib.data.SynchronizedDataHolder;
|
||||
import io.lumine.mythic.lib.player.cooldown.CooldownMap;
|
||||
import net.Indyuce.mmocore.MMOCore;
|
||||
import net.Indyuce.mmocore.api.ConfigMessage;
|
||||
@ -34,6 +35,7 @@ import net.Indyuce.mmocore.experience.droptable.ExperienceItem;
|
||||
import net.Indyuce.mmocore.experience.droptable.ExperienceTable;
|
||||
import net.Indyuce.mmocore.guild.provided.Guild;
|
||||
import net.Indyuce.mmocore.loot.chest.particle.SmallParticleEffect;
|
||||
import net.Indyuce.mmocore.manager.data.OfflinePlayerData;
|
||||
import net.Indyuce.mmocore.party.AbstractParty;
|
||||
import net.Indyuce.mmocore.party.provided.MMOCorePartyModule;
|
||||
import net.Indyuce.mmocore.party.provided.Party;
|
||||
@ -44,7 +46,8 @@ import net.Indyuce.mmocore.skill.ClassSkill;
|
||||
import net.Indyuce.mmocore.skill.RegisteredSkill;
|
||||
import net.Indyuce.mmocore.skill.binding.BoundSkillInfo;
|
||||
import net.Indyuce.mmocore.skill.binding.SkillSlot;
|
||||
import net.Indyuce.mmocore.skill.cast.SkillCastingHandler;
|
||||
import net.Indyuce.mmocore.skill.cast.SkillCastingInstance;
|
||||
import net.Indyuce.mmocore.skill.cast.SkillCastingMode;
|
||||
import net.Indyuce.mmocore.skilltree.NodeStatus;
|
||||
import net.Indyuce.mmocore.skilltree.SkillTreeNode;
|
||||
import net.Indyuce.mmocore.skilltree.tree.SkillTree;
|
||||
@ -66,14 +69,7 @@ import java.util.*;
|
||||
import java.util.logging.Level;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
public class PlayerData extends OfflinePlayerData implements Closable, ExperienceTableClaimer, ClassDataContainer {
|
||||
|
||||
/**
|
||||
* Corresponds to the MythicLib player data. It is used to keep
|
||||
* track of the Player instance corresponding to that player data,
|
||||
* as well as other things like the last time the player logged in/out
|
||||
*/
|
||||
private final MMOPlayerData mmoData;
|
||||
public class PlayerData extends SynchronizedDataHolder implements OfflinePlayerData, Closable, ExperienceTableClaimer, ClassDataContainer {
|
||||
|
||||
/**
|
||||
* Can be null, the {@link #getProfess()} method will return the
|
||||
@ -90,7 +86,7 @@ public class PlayerData extends OfflinePlayerData implements Closable, Experienc
|
||||
*/
|
||||
private double health;
|
||||
private Guild guild;
|
||||
private SkillCastingHandler skillCasting;
|
||||
private SkillCastingInstance skillCasting;
|
||||
private final PlayerQuests questData;
|
||||
private final PlayerStats playerStats;
|
||||
private final List<UUID> friends = new ArrayList<>();
|
||||
@ -101,7 +97,6 @@ public class PlayerData extends OfflinePlayerData implements Closable, Experienc
|
||||
@Deprecated
|
||||
private final Set<String> waypoints = new HashSet<>();
|
||||
private final Map<String, Integer> skills = new HashMap<>();
|
||||
// TODO change it to an array....... Map<Integer, BoundSkillInfo> is just BoundSkillInfo[]
|
||||
private final Map<Integer, BoundSkillInfo> boundSkills = new HashMap<>();
|
||||
private final PlayerProfessions collectSkills = new PlayerProfessions(this);
|
||||
private final PlayerAttributes attributes = new PlayerAttributes(this);
|
||||
@ -138,16 +133,9 @@ public class PlayerData extends OfflinePlayerData implements Closable, Experienc
|
||||
// NON-FINAL player data stuff made public to facilitate field change
|
||||
public boolean noCooldown;
|
||||
|
||||
/**
|
||||
* Player data is stored in the data map before it's actually fully loaded
|
||||
* so that external plugins don't necessarily have to listen to the PlayerDataLoadEvent.
|
||||
*/
|
||||
private boolean fullyLoaded = false;
|
||||
|
||||
public PlayerData(MMOPlayerData mmoData) {
|
||||
super(mmoData.getUniqueId());
|
||||
super(mmoData);
|
||||
|
||||
this.mmoData = mmoData;
|
||||
questData = new PlayerQuests(this);
|
||||
playerStats = new PlayerStats(this);
|
||||
}
|
||||
@ -168,19 +156,19 @@ public class PlayerData extends OfflinePlayerData implements Closable, Experienc
|
||||
MMOCore.log(Level.SEVERE, "[Userdata] Could not find class " + getProfess().getId() + " while refreshing player data.");
|
||||
}
|
||||
//We remove all the stats and buffs associated to triggers.
|
||||
mmoData.getStatMap().getInstances().forEach(statInstance -> statInstance.removeIf(key -> key.startsWith(Trigger.TRIGGER_PREFIX)));
|
||||
mmoData.getSkillModifierMap().getInstances().forEach(skillModifierInstance -> skillModifierInstance.removeIf(key -> key.startsWith(Trigger.TRIGGER_PREFIX)));
|
||||
Map<Integer, BoundSkillInfo> boundSkillsToRemove = new HashMap<>(boundSkills);
|
||||
for (int slot : boundSkillsToRemove.keySet())
|
||||
getMMOPlayerData().getStatMap().getInstances().forEach(statInstance -> statInstance.removeIf(key -> key.startsWith(Trigger.TRIGGER_PREFIX)));
|
||||
getMMOPlayerData().getSkillModifierMap().getInstances().forEach(skillModifierInstance -> skillModifierInstance.removeIf(key -> key.startsWith(Trigger.TRIGGER_PREFIX)));
|
||||
final Iterator<Map.Entry<Integer, BoundSkillInfo>> ite = boundSkills.entrySet().iterator();
|
||||
while (ite.hasNext())
|
||||
try {
|
||||
final BoundSkillInfo info = boundSkills.get(slot);
|
||||
final @Nullable SkillSlot skillSlot = getProfess().getSkillSlot(slot);
|
||||
final String skillId = info.getClassSkill().getSkill().getHandler().getId();
|
||||
final Map.Entry<Integer, BoundSkillInfo> entry = ite.next();
|
||||
final @Nullable SkillSlot skillSlot = getProfess().getSkillSlot(entry.getKey());
|
||||
final String skillId = entry.getValue().getClassSkill().getSkill().getHandler().getId();
|
||||
final @Nullable ClassSkill classSkill = getProfess().getSkill(skillId);
|
||||
Validate.notNull(skillSlot, "Could not find skill slot n" + slot);
|
||||
Validate.notNull(skillSlot, "Could not find skill slot n" + entry.getKey());
|
||||
Validate.notNull(classSkill, "Could not find skill with ID '" + skillId + "'");
|
||||
unbindSkill(slot);
|
||||
bindSkill(slot, classSkill);
|
||||
unbindSkill(entry.getKey());
|
||||
bindSkill(entry.getKey(), classSkill);
|
||||
} catch (Exception exception) {
|
||||
MMOCore.plugin.getLogger().log(Level.WARNING, "Could not reload data of '" + getPlayer().getName() + "': " + exception.getMessage());
|
||||
}
|
||||
@ -253,7 +241,7 @@ public class PlayerData extends OfflinePlayerData implements Closable, Experienc
|
||||
}
|
||||
|
||||
public void resetTriggerStats() {
|
||||
for (StatInstance instance : mmoData.getStatMap().getInstances()) {
|
||||
for (StatInstance instance : getMMOPlayerData().getStatMap().getInstances()) {
|
||||
Iterator<StatModifier> iter = instance.getModifiers().iterator();
|
||||
while (iter.hasNext()) {
|
||||
StatModifier modifier = iter.next();
|
||||
@ -417,6 +405,7 @@ public class PlayerData extends OfflinePlayerData implements Closable, Experienc
|
||||
@Override
|
||||
public void close() {
|
||||
|
||||
// Saves player health before saveData as the player will be considered offline into it if it is async
|
||||
health = getPlayer().getHealth();
|
||||
|
||||
// Remove from party if it is MMO Party Module
|
||||
@ -438,10 +427,6 @@ public class PlayerData extends OfflinePlayerData implements Closable, Experienc
|
||||
if (isCasting()) leaveSkillCasting();
|
||||
}
|
||||
|
||||
public MMOPlayerData getMMOPlayerData() {
|
||||
return mmoData;
|
||||
}
|
||||
|
||||
public List<UUID> getFriends() {
|
||||
return friends;
|
||||
}
|
||||
@ -454,10 +439,6 @@ public class PlayerData extends OfflinePlayerData implements Closable, Experienc
|
||||
return questData;
|
||||
}
|
||||
|
||||
public Player getPlayer() {
|
||||
return mmoData.getPlayer();
|
||||
}
|
||||
|
||||
public long getLastActivity(PlayerActivity activity) {
|
||||
return this.lastActivity.getOrDefault(activity, 0l);
|
||||
}
|
||||
@ -476,7 +457,7 @@ public class PlayerData extends OfflinePlayerData implements Closable, Experienc
|
||||
|
||||
@Override
|
||||
public long getLastLogin() {
|
||||
return mmoData.getLastLogActivity();
|
||||
return getMMOPlayerData().getLastLogActivity();
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -571,7 +552,7 @@ public class PlayerData extends OfflinePlayerData implements Closable, Experienc
|
||||
}
|
||||
|
||||
public boolean isOnline() {
|
||||
return mmoData.isOnline();
|
||||
return getMMOPlayerData().isOnline();
|
||||
}
|
||||
|
||||
public boolean inGuild() {
|
||||
@ -666,7 +647,11 @@ public class PlayerData extends OfflinePlayerData implements Closable, Experienc
|
||||
}
|
||||
|
||||
public void unloadClassInfo(PlayerClass profess) {
|
||||
classSlots.remove(profess.getId());
|
||||
unloadClassInfo(profess.getId());
|
||||
}
|
||||
|
||||
public void unloadClassInfo(String profess) {
|
||||
classSlots.remove(profess);
|
||||
}
|
||||
|
||||
public Set<String> getWaypoints() {
|
||||
@ -1005,25 +990,35 @@ public class PlayerData extends OfflinePlayerData implements Closable, Experienc
|
||||
stellium = Math.max(0, Math.min(amount, getStats().getStat("MAX_STELLIUM")));
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
public boolean isFullyLoaded() {
|
||||
return fullyLoaded;
|
||||
return isSynchronized();
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
public void setFullyLoaded() {
|
||||
this.fullyLoaded = true;
|
||||
markAsSynchronized();
|
||||
}
|
||||
|
||||
public boolean isCasting() {
|
||||
return skillCasting != null;
|
||||
}
|
||||
|
||||
public void setSkillCasting(SkillCastingHandler skillCasting) {
|
||||
public void setSkillCasting(@NotNull SkillCastingInstance skillCasting) {
|
||||
Validate.isTrue(!isCasting(), "Player already in casting mode");
|
||||
this.skillCasting = skillCasting;
|
||||
}
|
||||
|
||||
/**
|
||||
* API Method
|
||||
*/
|
||||
public void setSkillCasting() {
|
||||
Validate.isTrue(!isCasting(), "Player already in casting mode");
|
||||
setSkillCasting(SkillCastingMode.getCurrent().newInstance(this));
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public SkillCastingHandler getSkillCasting() {
|
||||
public SkillCastingInstance getSkillCasting() {
|
||||
return Objects.requireNonNull(skillCasting, "Player not in casting mode");
|
||||
}
|
||||
|
||||
@ -1075,11 +1070,11 @@ public class PlayerData extends OfflinePlayerData implements Closable, Experienc
|
||||
return getProfess().hasSkill(skill.getHandler().getId()) && hasSkillUnlocked(getProfess().getSkill(skill.getHandler().getId()));
|
||||
}
|
||||
|
||||
|
||||
@Deprecated
|
||||
public boolean hasSkillUnlocked(ClassSkill skill) {
|
||||
return hasUnlockedLevel(skill);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks for the player's level and compares it to the skill unlock level.
|
||||
* <p>
|
||||
@ -1123,7 +1118,7 @@ public class PlayerData extends OfflinePlayerData implements Closable, Experienc
|
||||
}
|
||||
|
||||
public CooldownMap getCooldownMap() {
|
||||
return mmoData.getCooldownMap();
|
||||
return getMMOPlayerData().getCooldownMap();
|
||||
}
|
||||
|
||||
public void setClass(@Nullable PlayerClass profess) {
|
||||
@ -1216,12 +1211,12 @@ public class PlayerData extends OfflinePlayerData implements Closable, Experienc
|
||||
if (this == o) return true;
|
||||
if (o == null || getClass() != o.getClass()) return false;
|
||||
PlayerData that = (PlayerData) o;
|
||||
return getUniqueId().equals(that.mmoData.getUniqueId());
|
||||
return getUniqueId().equals(that.getUniqueId());
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return mmoData.hashCode();
|
||||
return getMMOPlayerData().hashCode();
|
||||
}
|
||||
|
||||
public static PlayerData get(OfflinePlayer player) {
|
||||
|
@ -128,6 +128,11 @@ public class PlayerAttributes {
|
||||
return spent;
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
public int getSpent() {
|
||||
return getBase();
|
||||
}
|
||||
|
||||
public void setBase(int value) {
|
||||
spent = Math.max(0, value);
|
||||
|
||||
@ -165,10 +170,6 @@ public class PlayerAttributes {
|
||||
return (int) d;
|
||||
}
|
||||
|
||||
public int getSpent() {
|
||||
return spent;
|
||||
}
|
||||
|
||||
public AttributeModifier getModifier(String key) {
|
||||
return map.get(key);
|
||||
}
|
||||
|
@ -38,6 +38,7 @@ public class PlayerQuests implements Closable {
|
||||
bossbarNamespacedKey = new NamespacedKey(MMOCore.plugin, "mmocore_quest_progress_" + playerData.getUniqueId().toString());
|
||||
bossbar = Bukkit.createBossBar(bossbarNamespacedKey, "", BarColor.PURPLE, BarStyle.SEGMENTED_20);
|
||||
bossbar.addPlayer(playerData.getPlayer());
|
||||
bossbar.setVisible(false); // Safety
|
||||
|
||||
// Bossbar is disabled
|
||||
} else {
|
||||
|
@ -2,9 +2,10 @@ package net.Indyuce.mmocore.command.rpg.admin;
|
||||
|
||||
import io.lumine.mythic.lib.api.player.MMOPlayerData;
|
||||
import io.lumine.mythic.lib.command.api.CommandTreeNode;
|
||||
import io.lumine.mythic.lib.data.sql.SQLDataSource;
|
||||
import net.Indyuce.mmocore.MMOCore;
|
||||
import net.Indyuce.mmocore.api.player.PlayerData;
|
||||
import net.Indyuce.mmocore.manager.data.mysql.MySQLDataProvider;
|
||||
import net.Indyuce.mmocore.manager.data.sql.SQLDataHandler;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.scheduler.BukkitRunnable;
|
||||
|
||||
@ -51,9 +52,9 @@ public class ExportDataTreeNode extends CommandTreeNode {
|
||||
.map(file -> UUID.fromString(file.getName().replace(".yml", ""))).collect(Collectors.toList());
|
||||
|
||||
// Initialize fake SQL data provider
|
||||
final MySQLDataProvider sqlProvider;
|
||||
final SQLDataHandler sqlHandler;
|
||||
try {
|
||||
sqlProvider = new MySQLDataProvider(MMOCore.plugin.getConfig());
|
||||
sqlHandler = new SQLDataHandler(new SQLDataSource(MMOCore.plugin));
|
||||
} catch (RuntimeException exception) {
|
||||
sender.sendMessage("Could not initialize SQL provider (see console for stack trace): " + exception.getMessage());
|
||||
return CommandResult.FAILURE;
|
||||
@ -80,7 +81,7 @@ public class ExportDataTreeNode extends CommandTreeNode {
|
||||
if (index >= playerIds.size()) {
|
||||
cancel();
|
||||
|
||||
sqlProvider.close();
|
||||
sqlHandler.close();
|
||||
MMOCore.plugin.getLogger().log(Level.WARNING, "Exported " + playerIds.size() + " player datas to SQL database. Total errors: " + errorCount);
|
||||
return;
|
||||
}
|
||||
@ -88,10 +89,10 @@ public class ExportDataTreeNode extends CommandTreeNode {
|
||||
final UUID playerId = playerIds.get(index);
|
||||
try {
|
||||
final PlayerData offlinePlayerData = new PlayerData(new MMOPlayerData(playerId));
|
||||
MMOCore.plugin.dataProvider.getDataManager().loadData(offlinePlayerData);
|
||||
MMOCore.plugin.dataProvider.getDataManager().getDataHandler().loadData(offlinePlayerData);
|
||||
|
||||
// Player data is loaded, now it gets saved through SQL
|
||||
sqlProvider.getDataManager().saveData(offlinePlayerData, true);
|
||||
sqlHandler.saveData(offlinePlayerData, true);
|
||||
} catch (RuntimeException exception) {
|
||||
errorCount++;
|
||||
exception.printStackTrace();
|
||||
|
@ -30,7 +30,7 @@ public class SaveDataTreeNode extends CommandTreeNode {
|
||||
return CommandResult.FAILURE;
|
||||
}
|
||||
|
||||
MMOCore.plugin.dataProvider.getDataManager().saveData(PlayerData.get(player), false);
|
||||
MMOCore.plugin.dataProvider.getDataManager().getDataHandler().saveData(PlayerData.get(player), false);
|
||||
|
||||
return CommandResult.SUCCESS;
|
||||
}
|
||||
|
@ -12,7 +12,6 @@ import net.Indyuce.mmocore.api.quest.PlayerQuests;
|
||||
import net.Indyuce.mmocore.experience.PlayerProfessions;
|
||||
import net.Indyuce.mmocore.experience.Profession;
|
||||
import net.Indyuce.mmocore.party.AbstractParty;
|
||||
import net.Indyuce.mmocore.skill.ClassSkill;
|
||||
import net.Indyuce.mmocore.skill.RegisteredSkill;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.ChatColor;
|
||||
@ -27,47 +26,47 @@ import java.util.UUID;
|
||||
|
||||
|
||||
public class RPGPlaceholders extends PlaceholderExpansion {
|
||||
@Override
|
||||
public boolean persist() {
|
||||
return true;
|
||||
}
|
||||
@Override
|
||||
public boolean persist() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canRegister() {
|
||||
return true;
|
||||
}
|
||||
@Override
|
||||
public boolean canRegister() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getAuthor() {
|
||||
return "Indyuce";
|
||||
}
|
||||
@Override
|
||||
public String getAuthor() {
|
||||
return "Indyuce";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getIdentifier() {
|
||||
return "mmocore";
|
||||
}
|
||||
@Override
|
||||
public String getIdentifier() {
|
||||
return "mmocore";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getVersion() {
|
||||
return MMOCore.plugin.getDescription().getVersion();
|
||||
}
|
||||
@Override
|
||||
public String getVersion() {
|
||||
return MMOCore.plugin.getDescription().getVersion();
|
||||
}
|
||||
|
||||
private static final String ERROR_PLACEHOLDER = " ";
|
||||
|
||||
@SuppressWarnings("DuplicateExpressions")
|
||||
@Override
|
||||
public String onRequest(OfflinePlayer player, String identifier) {
|
||||
if (!PlayerData.has(player.getUniqueId()))
|
||||
return null;
|
||||
@SuppressWarnings("DuplicateExpressions")
|
||||
@Override
|
||||
public String onRequest(OfflinePlayer player, String identifier) {
|
||||
if (!PlayerData.has(player.getUniqueId()))
|
||||
return null;
|
||||
|
||||
PlayerData playerData = PlayerData.get(player);
|
||||
if (identifier.equals("mana_icon"))
|
||||
return playerData.getProfess().getManaDisplay().getIcon();
|
||||
if (identifier.equals("mana_name"))
|
||||
return playerData.getProfess().getManaDisplay().getName();
|
||||
PlayerData playerData = PlayerData.get(player);
|
||||
if (identifier.equals("mana_icon"))
|
||||
return playerData.getProfess().getManaDisplay().getIcon();
|
||||
if (identifier.equals("mana_name"))
|
||||
return playerData.getProfess().getManaDisplay().getName();
|
||||
|
||||
if (identifier.equals("level"))
|
||||
return String.valueOf(playerData.getLevel());
|
||||
if (identifier.equals("level"))
|
||||
return String.valueOf(playerData.getLevel());
|
||||
|
||||
else if (identifier.startsWith("skill_level_")) {
|
||||
String id = identifier.substring(12);
|
||||
@ -81,7 +80,7 @@ public class RPGPlaceholders extends PlaceholderExpansion {
|
||||
ClassSkill classSkill = playerData.getProfess().getSkill(skill);
|
||||
double value = classSkill.toCastable(playerData).getModifier(modifierId);
|
||||
return MythicLib.plugin.getMMOConfig().decimal.format(value);
|
||||
} else if (identifier.startsWith("mmocore_attribute_points_spent_")) {
|
||||
} else if (identifier.startsWith("attribute_points_spent_")) {
|
||||
String attributeId = identifier.substring(31);
|
||||
PlayerAttributes.AttributeInstance attributeInstance = Objects.requireNonNull(playerData.getAttributes().getInstance(attributeId), "Could not find attribute with ID '" + attributeId + "'");
|
||||
return String.valueOf(attributeInstance.getSpent());
|
||||
@ -91,60 +90,62 @@ public class RPGPlaceholders extends PlaceholderExpansion {
|
||||
} else if (identifier.equals("health"))
|
||||
return StatManager.format("MAX_HEALTH", player.getPlayer().getHealth());
|
||||
|
||||
else if (identifier.equals("max_health"))
|
||||
return StatManager.format("MAX_HEALTH", player.getPlayer().getAttribute(Attribute.GENERIC_MAX_HEALTH).getValue());
|
||||
else if (identifier.equals("max_health"))
|
||||
return StatManager.format("MAX_HEALTH", player.getPlayer().getAttribute(Attribute.GENERIC_MAX_HEALTH).getValue());
|
||||
|
||||
else if (identifier.equals("health_bar") && player.isOnline()) {
|
||||
StringBuilder format = new StringBuilder();
|
||||
double ratio = 20 * player.getPlayer().getHealth() / player.getPlayer().getAttribute(Attribute.GENERIC_MAX_HEALTH).getValue();
|
||||
for (double j = 1; j < 20; j++)
|
||||
format.append(ratio >= j ? ChatColor.RED : ratio >= j - .5 ? ChatColor.DARK_RED : ChatColor.DARK_GRAY).append(AltChar.listSquare);
|
||||
return format.toString();
|
||||
} else if (identifier.equals("class"))
|
||||
return playerData.getProfess().getName();
|
||||
else if (identifier.equals("health_bar") && player.isOnline()) {
|
||||
StringBuilder format = new StringBuilder();
|
||||
double ratio = 20 * player.getPlayer().getHealth() / player.getPlayer().getAttribute(Attribute.GENERIC_MAX_HEALTH).getValue();
|
||||
for (double j = 1; j < 20; j++)
|
||||
format.append(ratio >= j ? ChatColor.RED : ratio >= j - .5 ? ChatColor.DARK_RED : ChatColor.DARK_GRAY).append(AltChar.listSquare);
|
||||
return format.toString();
|
||||
} else if (identifier.equals("class"))
|
||||
return playerData.getProfess().getName();
|
||||
|
||||
else if (identifier.startsWith("profession_percent_")) {
|
||||
PlayerProfessions professions = playerData.getCollectionSkills();
|
||||
String name = identifier.substring(19).replace(" ", "-").replace("_", "-").toLowerCase();
|
||||
Profession profession = MMOCore.plugin.professionManager.get(name);
|
||||
double current = professions.getExperience(profession), next = professions.getLevelUpExperience(profession);
|
||||
return MythicLib.plugin.getMMOConfig().decimal.format(current / next * 100);
|
||||
else if (identifier.startsWith("profession_percent_")) {
|
||||
PlayerProfessions professions = playerData.getCollectionSkills();
|
||||
String name = identifier.substring(19).replace(" ", "-").replace("_", "-").toLowerCase();
|
||||
Profession profession = MMOCore.plugin.professionManager.get(name);
|
||||
double current = professions.getExperience(profession), next = professions.getLevelUpExperience(profession);
|
||||
return MythicLib.plugin.getMMOConfig().decimal.format(current / next * 100);
|
||||
|
||||
} else if (identifier.equals("is_casting"))
|
||||
return String.valueOf(playerData.isCasting());
|
||||
} else if (identifier.equals("is_casting"))
|
||||
return String.valueOf(playerData.isCasting());
|
||||
|
||||
else if (identifier.equals("in_combat"))
|
||||
return String.valueOf(playerData.isInCombat());
|
||||
else if (identifier.equals("in_combat"))
|
||||
return String.valueOf(playerData.isInCombat());
|
||||
|
||||
else if (identifier.equals("pvp_mode"))
|
||||
return String.valueOf(playerData.getCombat().isInPvpMode());
|
||||
else if (identifier.equals("pvp_mode"))
|
||||
return String.valueOf(playerData.getCombat().isInPvpMode());
|
||||
|
||||
else if (identifier.startsWith("since_enter_combat"))
|
||||
return playerData.isInCombat() ? MythicLib.plugin.getMMOConfig().decimal.format((System.currentTimeMillis() - playerData.getCombat().getLastEntry()) / 1000.) : "-1";
|
||||
else if (identifier.startsWith("since_enter_combat"))
|
||||
return playerData.isInCombat() ? MythicLib.plugin.getMMOConfig().decimal.format((System.currentTimeMillis() - playerData.getCombat().getLastEntry()) / 1000.) : "-1";
|
||||
|
||||
else if (identifier.startsWith("invulnerability_left"))
|
||||
return MythicLib.plugin.getMMOConfig().decimal.format(Math.max(0, (playerData.getCombat().getInvulnerableTill() - System.currentTimeMillis()) / 1000.));
|
||||
else if (identifier.startsWith("invulnerability_left"))
|
||||
return MythicLib.plugin.getMMOConfig().decimal.format(Math.max(0, (playerData.getCombat().getInvulnerableTill() - System.currentTimeMillis()) / 1000.));
|
||||
|
||||
else if (identifier.startsWith("since_last_hit"))
|
||||
return playerData.isInCombat() ? MythicLib.plugin.getMMOConfig().decimal.format((System.currentTimeMillis() - playerData.getCombat().getLastHit()) / 1000.) : "-1";
|
||||
else if (identifier.startsWith("since_last_hit"))
|
||||
return playerData.isInCombat() ? MythicLib.plugin.getMMOConfig().decimal.format((System.currentTimeMillis() - playerData.getCombat().getLastHit()) / 1000.) : "-1";
|
||||
|
||||
else if (identifier.startsWith("bound_")) {
|
||||
int slot = Math.max(0, Integer.parseInt(identifier.substring(6)));
|
||||
return playerData.hasSkillBound(slot) ? playerData.getBoundSkill(slot).getSkill().getName()
|
||||
: MMOCore.plugin.configManager.noSkillBoundPlaceholder;
|
||||
else if (identifier.startsWith("bound_")) {
|
||||
int slot = Math.max(0, Integer.parseInt(identifier.substring(6)));
|
||||
return playerData.hasSkillBound(slot) ? playerData.getBoundSkill(slot).getSkill().getName()
|
||||
: MMOCore.plugin.configManager.noSkillBoundPlaceholder;
|
||||
|
||||
} else if (identifier.startsWith("profession_experience_"))
|
||||
return MythicLib.plugin.getMMOConfig().decimal.format(
|
||||
playerData.getCollectionSkills().getExperience(identifier.substring(22).replace(" ", "-").replace("_", "-").toLowerCase()));
|
||||
} else if (identifier.startsWith("profession_experience_"))
|
||||
return MythicLib.plugin.getMMOConfig().decimal.format(
|
||||
playerData.getCollectionSkills().getExperience(identifier.substring(22).replace(" ", "-").replace("_", "-").toLowerCase()));
|
||||
|
||||
else if (identifier.startsWith("profession_next_level_"))
|
||||
return String.valueOf(PlayerData.get(player).getCollectionSkills()
|
||||
.getLevelUpExperience(identifier.substring(22).replace(" ", "-").replace("_", "-").toLowerCase()));
|
||||
else if (identifier.startsWith("profession_next_level_"))
|
||||
return String.valueOf(PlayerData.get(player).getCollectionSkills()
|
||||
.getLevelUpExperience(identifier.substring(22).replace(" ", "-").replace("_", "-").toLowerCase()));
|
||||
|
||||
else if (identifier.startsWith("party_count")) {
|
||||
final @Nullable AbstractParty party = playerData.getParty();
|
||||
return party == null ? "0" : String.valueOf(party.countMembers());
|
||||
} else if (identifier.startsWith("party_member_")) {
|
||||
else if (identifier.startsWith("party_count")) {
|
||||
final @Nullable AbstractParty party = playerData.getParty();
|
||||
return party == null ? "0" : String.valueOf(party.countMembers());
|
||||
}
|
||||
|
||||
else if (identifier.startsWith("party_member_")) {
|
||||
final int n = Integer.parseInt(identifier.substring(13)) - 1;
|
||||
final @Nullable AbstractParty party = playerData.getParty();
|
||||
if (party == null) return ERROR_PLACEHOLDER;
|
||||
@ -152,107 +153,129 @@ public class RPGPlaceholders extends PlaceholderExpansion {
|
||||
final @Nullable PlayerData member = party.getMember(n);
|
||||
if (member == null) return ERROR_PLACEHOLDER;
|
||||
return member.getPlayer().getName();
|
||||
} else if (identifier.equals("online_friends")) {
|
||||
}
|
||||
|
||||
else if (identifier.equals("online_friends")) {
|
||||
int count = 0;
|
||||
for (UUID friendId : playerData.getFriends())
|
||||
if (Bukkit.getPlayer(friendId) != null) count++;
|
||||
return String.valueOf(count);
|
||||
} else if (identifier.startsWith("online_friend_")) {
|
||||
}
|
||||
|
||||
else if (identifier.startsWith("online_friend_")) {
|
||||
final int n = Integer.parseInt(identifier.substring(14)) - 1;
|
||||
if (n >= playerData.getFriends().size()) return ERROR_PLACEHOLDER;
|
||||
final @Nullable Player friend = Bukkit.getPlayer(playerData.getFriends().get(n));
|
||||
if (friend == null) return ERROR_PLACEHOLDER;
|
||||
return friend.getName();
|
||||
} else if (identifier.startsWith("profession_"))
|
||||
return String
|
||||
.valueOf(playerData.getCollectionSkills().getLevel(identifier.substring(11).replace(" ", "-").replace("_", "-").toLowerCase()));
|
||||
|
||||
else if (identifier.equals("experience"))
|
||||
return MythicLib.plugin.getMMOConfig().decimal.format(playerData.getExperience());
|
||||
|
||||
else if (identifier.equals("next_level"))
|
||||
return String.valueOf(playerData.getLevelUpExperience());
|
||||
|
||||
else if (identifier.equals("class_points"))
|
||||
return String.valueOf(playerData.getClassPoints());
|
||||
|
||||
else if (identifier.equals("skill_points"))
|
||||
return String.valueOf(playerData.getSkillPoints());
|
||||
|
||||
else if (identifier.equals("attribute_points"))
|
||||
return String.valueOf(playerData.getAttributePoints());
|
||||
|
||||
else if (identifier.equals("attribute_reallocation_points"))
|
||||
return String.valueOf(playerData.getAttributeReallocationPoints());
|
||||
|
||||
else if (identifier.startsWith("attribute_"))
|
||||
return String.valueOf(playerData.getAttributes()
|
||||
.getAttribute(MMOCore.plugin.attributeManager.get(identifier.substring(10).toLowerCase().replace("_", "-"))));
|
||||
|
||||
else if (identifier.equals("mana"))
|
||||
return MythicLib.plugin.getMMOConfig().decimal.format(playerData.getMana());
|
||||
|
||||
else if (identifier.equals("mana_bar"))
|
||||
return playerData.getProfess().getManaDisplay().generateBar(playerData.getMana(), playerData.getStats().getStat("MAX_MANA"));
|
||||
|
||||
else if (identifier.startsWith("exp_multiplier_")) {
|
||||
String format = identifier.substring(15).toLowerCase().replace("_", "-").replace(" ", "-");
|
||||
Profession profession = format.equals("main") ? null : MMOCore.plugin.professionManager.get(format);
|
||||
return MythicLib.plugin.getMMOConfig().decimal.format(MMOCore.plugin.boosterManager.getMultiplier(profession) * 100);
|
||||
} else if (identifier.startsWith("exp_boost_")) {
|
||||
String format = identifier.substring(10).toLowerCase().replace("_", "-").replace(" ", "-");
|
||||
Profession profession = format.equals("main") ? null : MMOCore.plugin.professionManager.get(format);
|
||||
return MythicLib.plugin.getMMOConfig().decimal.format((MMOCore.plugin.boosterManager.getMultiplier(profession) - 1) * 100);
|
||||
} else if (identifier.equals("stamina"))
|
||||
return MythicLib.plugin.getMMOConfig().decimal.format(playerData.getStamina());
|
||||
|
||||
else if (identifier.equals("stamina_bar")) {
|
||||
StringBuilder format = new StringBuilder();
|
||||
double ratio = 20 * playerData.getStamina() / playerData.getStats().getStat("MAX_STAMINA");
|
||||
for (double j = 1; j < 20; j++)
|
||||
format.append(ratio >= j ? MMOCore.plugin.configManager.staminaFull
|
||||
: ratio >= j - .5 ? MMOCore.plugin.configManager.staminaHalf : MMOCore.plugin.configManager.staminaEmpty)
|
||||
.append(AltChar.listSquare);
|
||||
return format.toString();
|
||||
} else if (identifier.startsWith("stat_")) {
|
||||
final String stat = UtilityMethods.enumName(identifier.substring(5));
|
||||
return StatManager.format(stat, playerData.getMMOPlayerData());
|
||||
} else if (identifier.equals("stellium"))
|
||||
return MythicLib.plugin.getMMOConfig().decimal.format(playerData.getStellium());
|
||||
|
||||
else if (identifier.equals("stellium_bar")) {
|
||||
StringBuilder format = new StringBuilder();
|
||||
double ratio = 20 * playerData.getStellium() / playerData.getStats().getStat("MAX_STELLIUM");
|
||||
for (double j = 1; j < 20; j++)
|
||||
format.append(ratio >= j ? ChatColor.BLUE : ratio >= j - .5 ? ChatColor.AQUA : ChatColor.WHITE).append(AltChar.listSquare);
|
||||
return format.toString();
|
||||
} else if (identifier.equals("quest")) {
|
||||
PlayerQuests data = playerData.getQuestData();
|
||||
return data.hasCurrent() ? data.getCurrent().getQuest().getName() : "None";
|
||||
} else if (identifier.equals("quest_progress")) {
|
||||
PlayerQuests data = playerData.getQuestData();
|
||||
return data.hasCurrent() ? MythicLib.plugin.getMMOConfig().decimal
|
||||
.format((double) data.getCurrent().getObjectiveNumber() / data.getCurrent().getQuest().getObjectives().size() * 100L) : "0";
|
||||
} else if (identifier.equals("quest_objective")) {
|
||||
PlayerQuests data = playerData.getQuestData();
|
||||
return data.hasCurrent() ? data.getCurrent().getFormattedLore() : "None";
|
||||
} else if (identifier.startsWith("guild_")) {
|
||||
String placeholder = identifier.substring(6);
|
||||
if (playerData.getGuild() == null)
|
||||
return "";
|
||||
|
||||
if (placeholder.equalsIgnoreCase("name"))
|
||||
return playerData.getGuild().getName();
|
||||
else if (placeholder.equalsIgnoreCase("tag"))
|
||||
return playerData.getGuild().getTag();
|
||||
else if (placeholder.equalsIgnoreCase("leader"))
|
||||
return Bukkit.getOfflinePlayer(playerData.getGuild().getOwner()).getName();
|
||||
else if (placeholder.equalsIgnoreCase("members"))
|
||||
return String.valueOf(playerData.getGuild().countMembers());
|
||||
else if (placeholder.equalsIgnoreCase("online_members"))
|
||||
return String.valueOf(playerData.getGuild().countOnlineMembers());
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
else if (identifier.startsWith("profession_"))
|
||||
return String
|
||||
.valueOf(playerData.getCollectionSkills().getLevel(identifier.substring(11).replace(" ", "-").replace("_", "-").toLowerCase()));
|
||||
|
||||
else if (identifier.equals("experience"))
|
||||
return MythicLib.plugin.getMMOConfig().decimal.format(playerData.getExperience());
|
||||
|
||||
else if (identifier.equals("next_level"))
|
||||
return String.valueOf(playerData.getLevelUpExperience());
|
||||
|
||||
else if (identifier.equals("class_points"))
|
||||
return String.valueOf(playerData.getClassPoints());
|
||||
|
||||
else if (identifier.equals("skill_points"))
|
||||
return String.valueOf(playerData.getSkillPoints());
|
||||
|
||||
else if (identifier.equals("attribute_points"))
|
||||
return String.valueOf(playerData.getAttributePoints());
|
||||
|
||||
else if (identifier.equals("attribute_reallocation_points"))
|
||||
return String.valueOf(playerData.getAttributeReallocationPoints());
|
||||
|
||||
else if (identifier.startsWith("attribute_"))
|
||||
return String.valueOf(playerData.getAttributes()
|
||||
.getAttribute(MMOCore.plugin.attributeManager.get(identifier.substring(10).toLowerCase().replace("_", "-"))));
|
||||
|
||||
else if (identifier.equals("mana"))
|
||||
return MythicLib.plugin.getMMOConfig().decimal.format(playerData.getMana());
|
||||
|
||||
else if (identifier.equals("mana_bar"))
|
||||
return playerData.getProfess().getManaDisplay().generateBar(playerData.getMana(), playerData.getStats().getStat("MAX_MANA"));
|
||||
|
||||
else if (identifier.startsWith("exp_multiplier_")) {
|
||||
String format = identifier.substring(15).toLowerCase().replace("_", "-").replace(" ", "-");
|
||||
Profession profession = format.equals("main") ? null : MMOCore.plugin.professionManager.get(format);
|
||||
return MythicLib.plugin.getMMOConfig().decimal.format(MMOCore.plugin.boosterManager.getMultiplier(profession) * 100);
|
||||
}
|
||||
|
||||
else if (identifier.startsWith("exp_boost_")) {
|
||||
String format = identifier.substring(10).toLowerCase().replace("_", "-").replace(" ", "-");
|
||||
Profession profession = format.equals("main") ? null : MMOCore.plugin.professionManager.get(format);
|
||||
return MythicLib.plugin.getMMOConfig().decimal.format((MMOCore.plugin.boosterManager.getMultiplier(profession) - 1) * 100);
|
||||
}
|
||||
|
||||
else if (identifier.equals("stamina"))
|
||||
return MythicLib.plugin.getMMOConfig().decimal.format(playerData.getStamina());
|
||||
|
||||
else if (identifier.equals("stamina_bar")) {
|
||||
StringBuilder format = new StringBuilder();
|
||||
double ratio = 20 * playerData.getStamina() / playerData.getStats().getStat("MAX_STAMINA");
|
||||
for (double j = 1; j < 20; j++)
|
||||
format.append(ratio >= j ? MMOCore.plugin.configManager.staminaFull
|
||||
: ratio >= j - .5 ? MMOCore.plugin.configManager.staminaHalf : MMOCore.plugin.configManager.staminaEmpty)
|
||||
.append(AltChar.listSquare);
|
||||
return format.toString();
|
||||
}
|
||||
|
||||
else if (identifier.startsWith("stat_")) {
|
||||
final String stat = UtilityMethods.enumName(identifier.substring(5));
|
||||
return StatManager.format(stat, playerData.getMMOPlayerData());
|
||||
}
|
||||
|
||||
else if (identifier.equals("stellium"))
|
||||
return MythicLib.plugin.getMMOConfig().decimal.format(playerData.getStellium());
|
||||
|
||||
else if (identifier.equals("stellium_bar")) {
|
||||
StringBuilder format = new StringBuilder();
|
||||
double ratio = 20 * playerData.getStellium() / playerData.getStats().getStat("MAX_STELLIUM");
|
||||
for (double j = 1; j < 20; j++)
|
||||
format.append(ratio >= j ? ChatColor.BLUE : ratio >= j - .5 ? ChatColor.AQUA : ChatColor.WHITE).append(AltChar.listSquare);
|
||||
return format.toString();
|
||||
}
|
||||
|
||||
else if (identifier.equals("quest")) {
|
||||
PlayerQuests data = playerData.getQuestData();
|
||||
return data.hasCurrent() ? data.getCurrent().getQuest().getName() : "None";
|
||||
}
|
||||
|
||||
else if (identifier.equals("quest_progress")) {
|
||||
PlayerQuests data = playerData.getQuestData();
|
||||
return data.hasCurrent() ? MythicLib.plugin.getMMOConfig().decimal
|
||||
.format( (double) data.getCurrent().getObjectiveNumber() / data.getCurrent().getQuest().getObjectives().size() * 100L) : "0";
|
||||
}
|
||||
|
||||
else if (identifier.equals("quest_objective")) {
|
||||
PlayerQuests data = playerData.getQuestData();
|
||||
return data.hasCurrent() ? data.getCurrent().getFormattedLore() : "None";
|
||||
}
|
||||
|
||||
else if (identifier.startsWith("guild_")) {
|
||||
String placeholder = identifier.substring(6);
|
||||
if (playerData.getGuild() == null)
|
||||
return "";
|
||||
|
||||
if (placeholder.equalsIgnoreCase("name"))
|
||||
return playerData.getGuild().getName();
|
||||
else if (placeholder.equalsIgnoreCase("tag"))
|
||||
return playerData.getGuild().getTag();
|
||||
else if (placeholder.equalsIgnoreCase("leader"))
|
||||
return Bukkit.getOfflinePlayer(playerData.getGuild().getOwner()).getName();
|
||||
else if (placeholder.equalsIgnoreCase("members"))
|
||||
return String.valueOf(playerData.getGuild().countMembers());
|
||||
else if (placeholder.equalsIgnoreCase("online_members"))
|
||||
return String.valueOf(playerData.getGuild().countOnlineMembers());
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,79 @@
|
||||
package net.Indyuce.mmocore.comp.profile;
|
||||
|
||||
import fr.phoenixdevt.profile.ProfileDataModule;
|
||||
import fr.phoenixdevt.profile.ProfileProvider;
|
||||
import fr.phoenixdevt.profile.event.ProfileCreateEvent;
|
||||
import fr.phoenixdevt.profile.event.ProfileRemoveEvent;
|
||||
import fr.phoenixdevt.profile.event.ProfileSelectEvent;
|
||||
import fr.phoenixdevt.profile.event.ProfileUnloadEvent;
|
||||
import fr.phoenixdevt.profile.placeholder.PlaceholderRequest;
|
||||
import io.lumine.mythic.lib.api.event.SynchronizedDataLoadEvent;
|
||||
import net.Indyuce.mmocore.MMOCore;
|
||||
import net.Indyuce.mmocore.api.player.PlayerData;
|
||||
import net.Indyuce.mmocore.manager.InventoryManager;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.Listener;
|
||||
import org.bukkit.plugin.java.JavaPlugin;
|
||||
|
||||
public class ForceClassProfileDataModule implements ProfileDataModule, Listener {
|
||||
public ForceClassProfileDataModule() {
|
||||
final ProfileProvider<?> provider = Bukkit.getServicesManager().getRegistration(ProfileProvider.class).getProvider();
|
||||
provider.registerModule(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public JavaPlugin getOwningPlugin() {
|
||||
return MMOCore.plugin;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasPlaceholders() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getIdentifier() {
|
||||
return "mmocore_force_class";
|
||||
}
|
||||
|
||||
@Override
|
||||
public void processPlaceholderRequest(PlaceholderRequest placeholderRequest) {
|
||||
throw new RuntimeException("Not supported");
|
||||
}
|
||||
|
||||
/**
|
||||
* Force class before profile creation
|
||||
*/
|
||||
@EventHandler
|
||||
public void onProfileCreate(ProfileCreateEvent event) {
|
||||
final PlayerData playerData = PlayerData.get(event.getPlayerData().getUniqueId());
|
||||
InventoryManager.CLASS_SELECT.newInventory(playerData, () -> event.validate(this)).open();
|
||||
}
|
||||
|
||||
/**
|
||||
* Force class before profile selection once MMOCore loaded its data
|
||||
*/
|
||||
@EventHandler
|
||||
public void onDataLoad(SynchronizedDataLoadEvent event) {
|
||||
if (event.getManager().getOwningPlugin().equals(MMOCore.plugin)) {
|
||||
final PlayerData playerData = (PlayerData) event.getHolder();
|
||||
final ProfileSelectEvent event1 = (ProfileSelectEvent) event.getProfileEvent();
|
||||
|
||||
// Validate if necessary
|
||||
if (playerData.getProfess().equals(MMOCore.plugin.classManager.getDefaultClass()))
|
||||
InventoryManager.CLASS_SELECT.newInventory(playerData, () -> event1.validate(this)).open();
|
||||
else event1.validate(this);
|
||||
}
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void onProfileRemove(ProfileRemoveEvent event) {
|
||||
event.validate(this);
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void onProfileUnload(ProfileUnloadEvent event) {
|
||||
event.validate(this);
|
||||
}
|
||||
}
|
@ -0,0 +1,63 @@
|
||||
package net.Indyuce.mmocore.comp.profile;
|
||||
|
||||
import fr.phoenixdevt.profile.ProfileDataModule;
|
||||
import fr.phoenixdevt.profile.event.ProfileCreateEvent;
|
||||
import fr.phoenixdevt.profile.event.ProfileRemoveEvent;
|
||||
import fr.phoenixdevt.profile.placeholder.PlaceholderRequest;
|
||||
import io.lumine.mythic.lib.MythicLib;
|
||||
import io.lumine.mythic.lib.api.player.MMOPlayerData;
|
||||
import net.Indyuce.mmocore.MMOCore;
|
||||
import net.Indyuce.mmocore.api.player.PlayerData;
|
||||
import net.Indyuce.mmocore.api.player.attribute.PlayerAttribute;
|
||||
import net.Indyuce.mmocore.experience.Profession;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.Listener;
|
||||
import org.bukkit.plugin.java.JavaPlugin;
|
||||
|
||||
public class MMOCoreProfileDataModule implements ProfileDataModule, Listener {
|
||||
|
||||
@Override
|
||||
public JavaPlugin getOwningPlugin() {
|
||||
return MMOCore.plugin;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasPlaceholders() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getIdentifier() {
|
||||
return "mmocore";
|
||||
}
|
||||
|
||||
@Override
|
||||
public void processPlaceholderRequest(PlaceholderRequest placeholderRequest) {
|
||||
final PlayerData fictiveData = new PlayerData(new MMOPlayerData(placeholderRequest.getProfile().getUniqueId()));
|
||||
MMOCore.plugin.playerDataManager.getDataHandler().loadData(fictiveData).thenRun(() -> {
|
||||
placeholderRequest.addPlaceholder("class", fictiveData.getProfess().getName());
|
||||
placeholderRequest.addPlaceholder("level", fictiveData.getLevel());
|
||||
|
||||
for (PlayerAttribute attribute : MMOCore.plugin.attributeManager.getAll())
|
||||
placeholderRequest.addPlaceholder("attribute_" + attribute.getId().replace("-", "_"), fictiveData.getAttributes().getInstance(attribute).getBase());
|
||||
|
||||
for (Profession profession : MMOCore.plugin.professionManager.getAll())
|
||||
placeholderRequest.addPlaceholder("profession_" + profession.getId().replace("-", "_"), fictiveData.getCollectionSkills().getLevel(profession));
|
||||
|
||||
placeholderRequest.addPlaceholder("exp", MythicLib.plugin.getMMOConfig().decimal.format(fictiveData.getExperience()));
|
||||
placeholderRequest.addPlaceholder("exp_next_level", MythicLib.plugin.getMMOConfig().decimal.format(fictiveData.getLevelUpExperience()));
|
||||
|
||||
placeholderRequest.validate();
|
||||
});
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void onProfileCreate(ProfileCreateEvent event) {
|
||||
event.validate(this);
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void onProfileDelete(ProfileRemoveEvent event) {
|
||||
event.validate(this);
|
||||
}
|
||||
}
|
@ -26,7 +26,9 @@ public class VaultEconomy {
|
||||
|
||||
/**
|
||||
* @return If an economy plugin was found
|
||||
* @deprecated Not needed. {@link MMOCore#economy} could be null and that's all
|
||||
*/
|
||||
@Deprecated
|
||||
public boolean isValid() {
|
||||
return economy != null;
|
||||
}
|
||||
|
@ -20,8 +20,11 @@ import org.bukkit.Bukkit;
|
||||
import org.bukkit.ChatColor;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.configuration.ConfigurationSection;
|
||||
import org.bukkit.event.inventory.InventoryCloseEvent;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
public class ClassConfirmation extends EditableInventory {
|
||||
private final PlayerClass playerClass;
|
||||
|
||||
@ -36,8 +39,12 @@ public class ClassConfirmation extends EditableInventory {
|
||||
return function.equalsIgnoreCase("yes") ? new YesItem(config) : new SimplePlaceholderItem(config);
|
||||
}
|
||||
|
||||
public GeneratedInventory newInventory(PlayerData data, PluginInventory last, boolean subclass) {
|
||||
return new ClassConfirmationInventory(data, this, playerClass, last, subclass);
|
||||
public GeneratedInventory newInventory(PlayerData data, PluginInventory last, boolean setClass) {
|
||||
return newInventory(data, last, setClass, null);
|
||||
}
|
||||
|
||||
public GeneratedInventory newInventory(PlayerData data, PluginInventory last, boolean setClass, @Nullable Runnable profileRunnable) {
|
||||
return new ClassConfirmationInventory(data, this, playerClass, last, setClass, profileRunnable);
|
||||
}
|
||||
|
||||
public class UnlockedItem extends InventoryItem<ClassConfirmationInventory> {
|
||||
@ -105,26 +112,33 @@ public class ClassConfirmation extends EditableInventory {
|
||||
private final PluginInventory last;
|
||||
private final boolean subclass;
|
||||
|
||||
public ClassConfirmationInventory(PlayerData playerData, EditableInventory editable, PlayerClass profess, PluginInventory last, boolean subclass) {
|
||||
@Nullable
|
||||
private final Runnable profileRunnable;
|
||||
|
||||
private boolean canClose;
|
||||
|
||||
public ClassConfirmationInventory(PlayerData playerData, EditableInventory editable, PlayerClass profess, PluginInventory last, boolean subclass, @Nullable Runnable profileRunnable) {
|
||||
super(playerData, editable);
|
||||
|
||||
this.profess = profess;
|
||||
this.last = last;
|
||||
this.subclass = subclass;
|
||||
this.profileRunnable = profileRunnable;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void whenClicked(InventoryClickContext context, InventoryItem item) {
|
||||
if (item.getFunction().equals("back"))
|
||||
if (item.getFunction().equals("back")) {
|
||||
canClose = true;
|
||||
last.open();
|
||||
|
||||
else if (item.getFunction().equals("yes")) {
|
||||
} else if (item.getFunction().equals("yes")) {
|
||||
|
||||
PlayerChangeClassEvent called = new PlayerChangeClassEvent(playerData, profess);
|
||||
Bukkit.getPluginManager().callEvent(called);
|
||||
if (called.isCancelled())
|
||||
return;
|
||||
|
||||
canClose = true;
|
||||
playerData.giveClassPoints(-1);
|
||||
if (subclass)
|
||||
playerData.setClass(profess);
|
||||
@ -134,9 +148,22 @@ public class ClassConfirmation extends EditableInventory {
|
||||
MMOCore.plugin.configManager.getSimpleMessage("class-select", "class", profess.getName()).send(player);
|
||||
MMOCore.plugin.soundManager.getSound(SoundEvent.SELECT_CLASS).playTo(player);
|
||||
player.closeInventory();
|
||||
if (profileRunnable != null) profileRunnable.run();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void open() {
|
||||
canClose = false;
|
||||
super.open();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void whenClosed(InventoryCloseEvent event) {
|
||||
if (profileRunnable != null && !canClose)
|
||||
Bukkit.getScheduler().runTaskLater(MMOCore.plugin, () -> open(), 2 * 20);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String calculateName() {
|
||||
return getName().replace("{class}", profess.getName());
|
||||
|
@ -16,14 +16,17 @@ import net.Indyuce.mmocore.gui.api.item.InventoryItem;
|
||||
import net.Indyuce.mmocore.gui.api.item.SimplePlaceholderItem;
|
||||
import net.Indyuce.mmocore.manager.InventoryManager;
|
||||
import org.apache.commons.lang.Validate;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.NamespacedKey;
|
||||
import org.bukkit.configuration.ConfigurationSection;
|
||||
import org.bukkit.event.inventory.InventoryCloseEvent;
|
||||
import org.bukkit.inventory.ItemFlag;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.bukkit.inventory.meta.ItemMeta;
|
||||
import org.bukkit.persistence.PersistentDataType;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Comparator;
|
||||
import java.util.List;
|
||||
@ -41,7 +44,11 @@ public class ClassSelect extends EditableInventory {
|
||||
}
|
||||
|
||||
public GeneratedInventory newInventory(PlayerData data) {
|
||||
return new ProfessSelectionInventory(data, this);
|
||||
return newInventory(data, null);
|
||||
}
|
||||
|
||||
public GeneratedInventory newInventory(PlayerData data, @Nullable Runnable profileRunnable) {
|
||||
return new ProfessSelectionInventory(data, this, profileRunnable);
|
||||
}
|
||||
|
||||
public class ClassItem extends SimplePlaceholderItem<ProfessSelectionInventory> {
|
||||
@ -51,9 +58,10 @@ public class ClassSelect extends EditableInventory {
|
||||
|
||||
public ClassItem(ConfigurationSection config) {
|
||||
super(Material.BARRIER, config);
|
||||
Validate.isTrue(config.getString("function").length()>6,"Couldn't find the class associated to: "+config.getString("function"));
|
||||
|
||||
Validate.isTrue(config.getString("function").length() > 6, "Couldn't find the class associated to: " + config.getString("function"));
|
||||
String classId = UtilityMethods.enumName(config.getString("function").substring(6));
|
||||
this.playerClass = Objects.requireNonNull(MMOCore.plugin.classManager.get(classId),classId+" does not correspond to any classId.");
|
||||
this.playerClass = Objects.requireNonNull(MMOCore.plugin.classManager.get(classId), classId + " does not correspond to any classId.");
|
||||
this.name = config.getString("name");
|
||||
this.lore = config.getStringList("lore");
|
||||
}
|
||||
@ -93,8 +101,16 @@ public class ClassSelect extends EditableInventory {
|
||||
}
|
||||
|
||||
public class ProfessSelectionInventory extends GeneratedInventory {
|
||||
public ProfessSelectionInventory(PlayerData playerData, EditableInventory editable) {
|
||||
|
||||
@Nullable
|
||||
private final Runnable profileRunnable;
|
||||
|
||||
private boolean canClose;
|
||||
|
||||
public ProfessSelectionInventory(PlayerData playerData, EditableInventory editable, @Nullable Runnable profileRunnable) {
|
||||
super(playerData, editable);
|
||||
|
||||
this.profileRunnable = profileRunnable;
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -107,7 +123,7 @@ public class ClassSelect extends EditableInventory {
|
||||
if (item instanceof ClassItem) {
|
||||
PlayerClass profess = ((ClassItem) item).playerClass;
|
||||
|
||||
if (playerData.getClassPoints() < 1) {
|
||||
if (profileRunnable == null && playerData.getClassPoints() < 1) {
|
||||
MMOCore.plugin.soundManager.getSound(SoundEvent.CANT_SELECT_CLASS).playTo(player);
|
||||
new ConfigMessage("cant-choose-new-class").send(player);
|
||||
return;
|
||||
@ -125,10 +141,23 @@ public class ClassSelect extends EditableInventory {
|
||||
return;
|
||||
}
|
||||
|
||||
canClose = true;
|
||||
final PlayerClass playerClass = findDeepestSubclass(playerData, profess);
|
||||
InventoryManager.CLASS_CONFIRM.get(MMOCoreUtils.ymlName(playerClass.getId())).newInventory(playerData, this, false).open();
|
||||
InventoryManager.CLASS_CONFIRM.get(MMOCoreUtils.ymlName(playerClass.getId())).newInventory(playerData, this, profileRunnable != null, profileRunnable).open();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void open() {
|
||||
canClose = false;
|
||||
super.open();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void whenClosed(InventoryCloseEvent event) {
|
||||
if (profileRunnable != null && !canClose)
|
||||
Bukkit.getScheduler().runTaskLater(MMOCore.plugin, () -> open(), 2 * 20);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -127,7 +127,7 @@ public class SubclassSelect extends EditableInventory {
|
||||
return;
|
||||
}
|
||||
|
||||
InventoryManager.CLASS_CONFIRM.get(classId).newInventory(playerData, this, true).open();
|
||||
InventoryManager.CLASS_CONFIRM.get(classId).newInventory(playerData, this, true, null).open();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -22,6 +22,7 @@ public abstract class GeneratedInventory extends PluginInventory {
|
||||
|
||||
public GeneratedInventory(PlayerData playerData, EditableInventory editable) {
|
||||
super(playerData);
|
||||
|
||||
this.editable = editable;
|
||||
this.adaptor = editable.getAdaptorType().supply(this);
|
||||
}
|
||||
@ -66,6 +67,8 @@ public abstract class GeneratedInventory extends PluginInventory {
|
||||
|
||||
@Override
|
||||
public void open() {
|
||||
if (!getPlayerData().isOnline()) return;
|
||||
|
||||
/*
|
||||
* Very important, in order to prevent ghost items, the loaded items map
|
||||
* must be cleared when the inventory is updated or open at least twice
|
||||
|
@ -5,7 +5,7 @@ import net.Indyuce.mmocore.api.player.PlayerData;
|
||||
import net.Indyuce.mmocore.gui.api.InventoryClickContext;
|
||||
import net.Indyuce.mmocore.gui.api.GeneratedInventory;
|
||||
import net.Indyuce.mmocore.gui.api.item.InventoryItem;
|
||||
import net.Indyuce.mmocore.api.player.OfflinePlayerData;
|
||||
import net.Indyuce.mmocore.manager.data.OfflinePlayerData;
|
||||
import net.Indyuce.mmocore.gui.api.EditableInventory;
|
||||
import net.Indyuce.mmocore.gui.api.item.Placeholders;
|
||||
import org.bukkit.OfflinePlayer;
|
||||
|
@ -9,7 +9,7 @@ import net.Indyuce.mmocore.api.util.input.PlayerInput;
|
||||
import net.Indyuce.mmocore.gui.api.GeneratedInventory;
|
||||
import net.Indyuce.mmocore.gui.api.item.InventoryItem;
|
||||
import net.Indyuce.mmocore.gui.api.item.SimplePlaceholderItem;
|
||||
import net.Indyuce.mmocore.api.player.OfflinePlayerData;
|
||||
import net.Indyuce.mmocore.manager.data.OfflinePlayerData;
|
||||
import net.Indyuce.mmocore.gui.api.EditableInventory;
|
||||
import net.Indyuce.mmocore.gui.api.item.Placeholders;
|
||||
import org.apache.commons.lang.Validate;
|
||||
|
@ -1,4 +1,4 @@
|
||||
package net.Indyuce.mmocore.manager.data.yaml;
|
||||
package net.Indyuce.mmocore.guild.provided;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.ArrayList;
|
@ -28,7 +28,7 @@ public class ConfigManager {
|
||||
public final CommandVerbose commandVerbose = new CommandVerbose();
|
||||
|
||||
public boolean overrideVanillaExp, canCreativeCast, passiveSkillNeedBound, cobbleGeneratorXP, saveDefaultClassInfo, splitMainExp, splitProfessionExp, disableQuestBossBar,
|
||||
pvpModeEnabled, pvpModeInvulnerabilityCanDamage;
|
||||
pvpModeEnabled, pvpModeInvulnerabilityCanDamage, forceClassSelection;
|
||||
public String partyChatPrefix, noSkillBoundPlaceholder;
|
||||
public ChatColor staminaFull, staminaHalf, staminaEmpty;
|
||||
public long combatLogTimer, lootChestExpireTime, lootChestPlayerCooldown, globalSkillCooldown;
|
||||
@ -133,6 +133,7 @@ public class ConfigManager {
|
||||
splitMainExp = MMOCore.plugin.getConfig().getBoolean("party.main-exp-split");
|
||||
splitProfessionExp = MMOCore.plugin.getConfig().getBoolean("party.profession-exp-split");
|
||||
disableQuestBossBar = MMOCore.plugin.getConfig().getBoolean("mmocore-quests.disable-boss-bar");
|
||||
forceClassSelection = MMOCore.plugin.getConfig().getBoolean("force-class-selection");
|
||||
|
||||
// Combat
|
||||
pvpModeEnabled = config.getBoolean("pvp_mode.enabled");
|
||||
|
@ -1,15 +1,22 @@
|
||||
package net.Indyuce.mmocore.manager.data;
|
||||
|
||||
import net.Indyuce.mmocore.MMOCore;
|
||||
|
||||
/**
|
||||
* Used to separate MySQL data storage from YAML data storage.
|
||||
* <p>
|
||||
* There is one data provider per storage mecanism (one for YAML, one for MySQL).
|
||||
* A data provider provides corresponding MMOManagers to correctly save and load
|
||||
* data
|
||||
*
|
||||
* @deprecated Not being used anymore, see {@link MMOCore#nativeGuildManager} and {@link MMOCore#playerDataManager}
|
||||
*/
|
||||
@Deprecated
|
||||
public interface DataProvider {
|
||||
|
||||
@Deprecated
|
||||
PlayerDataManager getDataManager();
|
||||
|
||||
@Deprecated
|
||||
GuildDataManager getGuildManager();
|
||||
}
|
||||
|
@ -14,117 +14,121 @@ import net.Indyuce.mmocore.guild.provided.Guild;
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
public abstract class GuildDataManager {
|
||||
protected final Map<String, Guild> guilds = new HashMap<>();
|
||||
protected final Map<String, Guild> guilds = new HashMap<>();
|
||||
|
||||
public Guild newRegisteredGuild(UUID owner, String name, String tag) {
|
||||
Guild guild = new Guild(owner, name, tag);
|
||||
registerGuild(guild);
|
||||
return guild;
|
||||
}
|
||||
public Guild newRegisteredGuild(UUID owner, String name, String tag) {
|
||||
Guild guild = new Guild(owner, name, tag);
|
||||
registerGuild(guild);
|
||||
return guild;
|
||||
}
|
||||
|
||||
public void registerGuild(Guild guild) {
|
||||
guilds.put(guild.getId(), guild);
|
||||
}
|
||||
public void registerGuild(Guild guild) {
|
||||
guilds.put(guild.getId(), guild);
|
||||
}
|
||||
|
||||
public boolean isRegistered(Guild guild) {
|
||||
return guilds.containsValue(guild);
|
||||
}
|
||||
public boolean isRegistered(Guild guild) {
|
||||
return guilds.containsValue(guild);
|
||||
}
|
||||
|
||||
public boolean isRegistered(String tag) {
|
||||
return guilds.containsKey(tag);
|
||||
}
|
||||
public boolean isRegistered(String tag) {
|
||||
return guilds.containsKey(tag);
|
||||
}
|
||||
|
||||
public void unregisterGuild(Guild guild) {
|
||||
guild.forEachMember(member -> guild.removeMember(member, true));
|
||||
// guild.getMembers().clear();
|
||||
guilds.remove(guild.getId());
|
||||
delete(guild);
|
||||
}
|
||||
public void unregisterGuild(Guild guild) {
|
||||
guild.forEachMember(member -> guild.removeMember(member, true));
|
||||
// guild.getMembers().clear();
|
||||
guilds.remove(guild.getId());
|
||||
delete(guild);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public Guild getGuild(String guild) {
|
||||
return guilds.get(guild);
|
||||
}
|
||||
public void saveAll() {
|
||||
for (Guild guild : guilds.values()) save(guild);
|
||||
}
|
||||
|
||||
public Collection<Guild> getAll() {
|
||||
return guilds.values();
|
||||
}
|
||||
@Nullable
|
||||
public Guild getGuild(String guild) {
|
||||
return guilds.get(guild);
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
public void reload() {
|
||||
for (Guild guild : guilds.values())
|
||||
save(guild);
|
||||
guilds.clear();
|
||||
load();
|
||||
config = new GuildConfiguration();
|
||||
}
|
||||
public Collection<Guild> getAll() {
|
||||
return guilds.values();
|
||||
}
|
||||
|
||||
public abstract void save(Guild guild);
|
||||
@Deprecated
|
||||
public void reload() {
|
||||
for (Guild guild : guilds.values())
|
||||
save(guild);
|
||||
guilds.clear();
|
||||
load();
|
||||
config = new GuildConfiguration();
|
||||
}
|
||||
|
||||
// TODO move to constructor, useless to handle vie abstract method
|
||||
public abstract void load();
|
||||
public abstract void save(Guild guild);
|
||||
|
||||
public abstract void delete(Guild guild);
|
||||
// TODO move to constructor, useless to handle vie abstract method
|
||||
public abstract void load();
|
||||
|
||||
// TODO fix this
|
||||
// Shitty code for loading config values for guilds.
|
||||
private GuildConfiguration config;
|
||||
public abstract void delete(Guild guild);
|
||||
|
||||
public GuildConfiguration getConfig() {
|
||||
return config == null ? config = new GuildConfiguration() : config;
|
||||
}
|
||||
// TODO fix this
|
||||
// Shitty code for loading config values for guilds.
|
||||
private GuildConfiguration config;
|
||||
|
||||
public static class GuildConfiguration {
|
||||
private final String prefix;
|
||||
private final boolean uppercaseTags;
|
||||
private final NamingRules tagRules, nameRules;
|
||||
public GuildConfiguration getConfig() {
|
||||
return config == null ? config = new GuildConfiguration() : config;
|
||||
}
|
||||
|
||||
public GuildConfiguration() {
|
||||
FileConfiguration config = new ConfigFile("guilds").getConfig();
|
||||
public static class GuildConfiguration {
|
||||
private final String prefix;
|
||||
private final boolean uppercaseTags;
|
||||
private final NamingRules tagRules, nameRules;
|
||||
|
||||
this.prefix = config.getString("chat-prefix", "*");
|
||||
this.uppercaseTags = config.getBoolean("uppercase-tags", true);
|
||||
this.tagRules = new NamingRules(config.getConfigurationSection("rules.tag"));
|
||||
this.nameRules = new NamingRules(config.getConfigurationSection("rules.name"));
|
||||
}
|
||||
public GuildConfiguration() {
|
||||
FileConfiguration config = new ConfigFile("guilds").getConfig();
|
||||
|
||||
public String getPrefix() {
|
||||
return prefix;
|
||||
}
|
||||
this.prefix = config.getString("chat-prefix", "*");
|
||||
this.uppercaseTags = config.getBoolean("uppercase-tags", true);
|
||||
this.tagRules = new NamingRules(config.getConfigurationSection("rules.tag"));
|
||||
this.nameRules = new NamingRules(config.getConfigurationSection("rules.name"));
|
||||
}
|
||||
|
||||
public boolean shouldUppercaseTags() {
|
||||
return uppercaseTags;
|
||||
}
|
||||
public String getPrefix() {
|
||||
return prefix;
|
||||
}
|
||||
|
||||
public NamingRules getTagRules() {
|
||||
return tagRules;
|
||||
}
|
||||
public boolean shouldUppercaseTags() {
|
||||
return uppercaseTags;
|
||||
}
|
||||
|
||||
public NamingRules getNameRules() {
|
||||
return nameRules;
|
||||
}
|
||||
public NamingRules getTagRules() {
|
||||
return tagRules;
|
||||
}
|
||||
|
||||
public static class NamingRules {
|
||||
private final String regex;
|
||||
private final int min, max;
|
||||
public NamingRules getNameRules() {
|
||||
return nameRules;
|
||||
}
|
||||
|
||||
public NamingRules(ConfigurationSection config) {
|
||||
regex = config.getString("matches", "[a-zA-Z-_!?]+");
|
||||
min = config.getInt("min-length", 3);
|
||||
max = config.getInt("max-length", 5);
|
||||
}
|
||||
public static class NamingRules {
|
||||
private final String regex;
|
||||
private final int min, max;
|
||||
|
||||
public String getRegex() {
|
||||
return regex;
|
||||
}
|
||||
public NamingRules(ConfigurationSection config) {
|
||||
regex = config.getString("matches", "[a-zA-Z-_!?]+");
|
||||
min = config.getInt("min-length", 3);
|
||||
max = config.getInt("max-length", 5);
|
||||
}
|
||||
|
||||
public int getMin() {
|
||||
return min;
|
||||
}
|
||||
public String getRegex() {
|
||||
return regex;
|
||||
}
|
||||
|
||||
public int getMax() {
|
||||
return max;
|
||||
}
|
||||
}
|
||||
}
|
||||
public int getMin() {
|
||||
return min;
|
||||
}
|
||||
|
||||
public int getMax() {
|
||||
return max;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,18 @@
|
||||
package net.Indyuce.mmocore.manager.data;
|
||||
|
||||
|
||||
import net.Indyuce.mmocore.MMOCore;
|
||||
|
||||
@Deprecated
|
||||
public class LegacyDataProvider implements DataProvider {
|
||||
|
||||
@Override
|
||||
public PlayerDataManager getDataManager() {
|
||||
return MMOCore.plugin.playerDataManager;
|
||||
}
|
||||
|
||||
@Override
|
||||
public GuildDataManager getGuildManager() {
|
||||
return MMOCore.plugin.nativeGuildManager;
|
||||
}
|
||||
}
|
@ -0,0 +1,24 @@
|
||||
package net.Indyuce.mmocore.manager.data;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
import io.lumine.mythic.lib.data.OfflineDataHolder;
|
||||
import net.Indyuce.mmocore.MMOCore;
|
||||
import net.Indyuce.mmocore.api.player.profess.PlayerClass;
|
||||
|
||||
public interface OfflinePlayerData extends OfflineDataHolder {
|
||||
|
||||
public abstract void removeFriend(UUID uuid);
|
||||
|
||||
public abstract boolean hasFriend(UUID uuid);
|
||||
|
||||
public abstract PlayerClass getProfess();
|
||||
|
||||
public abstract int getLevel();
|
||||
|
||||
public abstract long getLastLogin();
|
||||
|
||||
public static OfflinePlayerData get(UUID uuid) {
|
||||
return MMOCore.plugin.dataProvider.getDataManager().getOffline(uuid);
|
||||
}
|
||||
}
|
@ -1,102 +1,29 @@
|
||||
package net.Indyuce.mmocore.manager.data;
|
||||
|
||||
import io.lumine.mythic.lib.api.player.MMOPlayerData;
|
||||
import io.lumine.mythic.lib.data.SynchronizedDataManager;
|
||||
import net.Indyuce.mmocore.MMOCore;
|
||||
import net.Indyuce.mmocore.api.event.AsyncPlayerDataLoadEvent;
|
||||
import net.Indyuce.mmocore.api.event.PlayerDataLoadEvent;
|
||||
import net.Indyuce.mmocore.api.player.OfflinePlayerData;
|
||||
import net.Indyuce.mmocore.api.player.PlayerData;
|
||||
import net.Indyuce.mmocore.comp.profile.MMOCoreProfileDataModule;
|
||||
import net.Indyuce.mmocore.manager.data.yaml.YAMLPlayerDataHandler;
|
||||
import net.Indyuce.mmocore.player.DefaultPlayerData;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.OfflinePlayer;
|
||||
import org.bukkit.configuration.ConfigurationSection;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
public abstract class PlayerDataManager {
|
||||
private final static Map<UUID, PlayerData> data = Collections.synchronizedMap(new HashMap<>());
|
||||
|
||||
public class PlayerDataManager extends SynchronizedDataManager<PlayerData, OfflinePlayerData> {
|
||||
private DefaultPlayerData defaultData = DefaultPlayerData.DEFAULT;
|
||||
|
||||
public PlayerData get(OfflinePlayer player) {
|
||||
return get(player.getUniqueId());
|
||||
public PlayerDataManager(MMOCore plugin) {
|
||||
super(plugin, new YAMLPlayerDataHandler(plugin));
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the player data, or throws an exception if not found.
|
||||
* The player data should be loaded when the player logs in
|
||||
* so it's really bad practice to setup the player data if it's not loaded.
|
||||
*
|
||||
* @param uuid Player UUID
|
||||
* @return Player data, if it's loaded
|
||||
*/
|
||||
public PlayerData get(UUID uuid) {
|
||||
return Objects.requireNonNull(data.get(uuid), "Player data is not loaded");
|
||||
@Override
|
||||
public PlayerData newPlayerData(MMOPlayerData playerData) {
|
||||
return new PlayerData(playerData);
|
||||
}
|
||||
|
||||
/**
|
||||
* Safely unregisters the player data from the map.
|
||||
* This saves the player data either through SQL or YAML,
|
||||
* then closes the player data and clears it from the data map.
|
||||
*
|
||||
* @param playerData PLayer data to unregister
|
||||
*/
|
||||
public void unregisterSafe(PlayerData playerData) {
|
||||
|
||||
// Close and unregister data instantly if no error occured
|
||||
playerData.close();
|
||||
data.remove(playerData.getUniqueId());
|
||||
|
||||
// Save data async if required
|
||||
if (playerData.isFullyLoaded())
|
||||
Bukkit.getScheduler().runTaskAsynchronously(MMOCore.plugin, () -> saveData(playerData, true));
|
||||
}
|
||||
|
||||
/**
|
||||
* Offline player data is used to handle processes like friend removal
|
||||
* which can still occur if one of the two players is offline.
|
||||
* <p>
|
||||
* Unlike {@link #get(UUID)} this method never returns a null instance
|
||||
*
|
||||
* @param uuid Player unique id
|
||||
* @return Offline player data
|
||||
*/
|
||||
@NotNull
|
||||
public abstract OfflinePlayerData getOffline(UUID uuid);
|
||||
|
||||
/**
|
||||
* Called when a player logs in, loading the player data inside the map.
|
||||
* <p>
|
||||
* For YAML configs or SQL databases, data is loaded as not to overload
|
||||
* the main thread with SQL requests. Therefore, the player data returned
|
||||
* by that method, when the player joined for the first time, is not
|
||||
* fully loaded YET.
|
||||
*
|
||||
* @param uniqueId Player UUID
|
||||
* @return The loaded player data.
|
||||
*/
|
||||
public PlayerData setup(UUID uniqueId) {
|
||||
|
||||
// Load player data if it does not exist
|
||||
final @Nullable PlayerData current = data.get(uniqueId);
|
||||
if (current != null)
|
||||
return current;
|
||||
|
||||
final PlayerData newData = new PlayerData(MMOPlayerData.get(uniqueId));
|
||||
|
||||
// Schedule async data loading
|
||||
Bukkit.getScheduler().runTaskAsynchronously(MMOCore.plugin, () -> {
|
||||
loadData(newData);
|
||||
newData.getStats().updateStats();
|
||||
Bukkit.getPluginManager().callEvent(new AsyncPlayerDataLoadEvent(newData));
|
||||
Bukkit.getScheduler().runTask(MMOCore.plugin, () -> Bukkit.getPluginManager().callEvent(new PlayerDataLoadEvent(newData)));
|
||||
});
|
||||
|
||||
// Update data map and return
|
||||
data.put(uniqueId, newData);
|
||||
return newData;
|
||||
@Override
|
||||
public Object newProfileDataModule() {
|
||||
return new MMOCoreProfileDataModule();
|
||||
}
|
||||
|
||||
public DefaultPlayerData getDefaultData() {
|
||||
@ -107,25 +34,8 @@ public abstract class PlayerDataManager {
|
||||
defaultData = new DefaultPlayerData(config);
|
||||
}
|
||||
|
||||
public boolean isLoaded(UUID uuid) {
|
||||
return data.containsKey(uuid);
|
||||
@Override
|
||||
public void whenAutoSaved() {
|
||||
MMOCore.plugin.nativeGuildManager.saveAll();
|
||||
}
|
||||
|
||||
public Collection<PlayerData> getLoaded() {
|
||||
return data.values();
|
||||
}
|
||||
|
||||
public abstract void loadData(PlayerData data);
|
||||
|
||||
/**
|
||||
* Called when player data must be saved in configs or database.
|
||||
* This method should always be called sync because it DOES register
|
||||
* an async task in case MySQL storage is used.
|
||||
*
|
||||
* @param data Player data to save
|
||||
* @param logout When logging out, is_saved is switched back to 1. This parameter
|
||||
* must be turned off when auto-saving because the player doesn't
|
||||
* actually leave the server.
|
||||
*/
|
||||
public abstract void saveData(PlayerData data, boolean logout);
|
||||
}
|
||||
|
@ -1,154 +0,0 @@
|
||||
package net.Indyuce.mmocore.manager.data.mysql;
|
||||
|
||||
import com.google.gson.*;
|
||||
import io.lumine.mythic.lib.UtilityMethods;
|
||||
import io.lumine.mythic.lib.sql.DataSynchronizer;
|
||||
import net.Indyuce.mmocore.MMOCore;
|
||||
import net.Indyuce.mmocore.api.player.PlayerData;
|
||||
import net.Indyuce.mmocore.api.player.profess.PlayerClass;
|
||||
import net.Indyuce.mmocore.api.player.profess.SavedClassInformation;
|
||||
import net.Indyuce.mmocore.api.util.MMOCoreUtils;
|
||||
import net.Indyuce.mmocore.guild.provided.Guild;
|
||||
import net.Indyuce.mmocore.skilltree.SkillTreeNode;
|
||||
import net.Indyuce.mmocore.skilltree.tree.SkillTree;
|
||||
import org.apache.commons.lang.Validate;
|
||||
import org.bukkit.attribute.Attribute;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
import java.util.*;
|
||||
import java.util.logging.Level;
|
||||
|
||||
public class MMOCoreDataSynchronizer extends DataSynchronizer {
|
||||
private final PlayerData data;
|
||||
private final MySQLPlayerDataManager manager;
|
||||
|
||||
public MMOCoreDataSynchronizer(MySQLPlayerDataManager manager, PlayerData data) {
|
||||
super("mmocore_playerdata", "uuid", manager.getProvider(), data.getUniqueId());
|
||||
|
||||
this.manager = manager;
|
||||
this.data = data;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void loadData(ResultSet result) throws SQLException {
|
||||
//Reset stats linked to triggers
|
||||
data.resetTriggerStats();
|
||||
|
||||
data.setClassPoints(result.getInt("class_points"));
|
||||
data.setSkillPoints(result.getInt("skill_points"));
|
||||
data.setSkillReallocationPoints(result.getInt("skill_reallocation_points"));
|
||||
data.setSkillTreeReallocationPoints(result.getInt("skill_tree_reallocation_points"));
|
||||
data.setAttributePoints(result.getInt("attribute_points"));
|
||||
data.setAttributeReallocationPoints(result.getInt("attribute_realloc_points"));
|
||||
data.setLevel(result.getInt("level"));
|
||||
data.setExperience(result.getInt("experience"));
|
||||
|
||||
if (!isEmpty(result.getString("class")))
|
||||
data.setClass(MMOCore.plugin.classManager.get(result.getString("class")));
|
||||
|
||||
if (!isEmpty(result.getString("times_claimed"))) {
|
||||
JsonObject json = new JsonParser().parse(result.getString("times_claimed")).getAsJsonObject();
|
||||
json.entrySet().forEach(entry -> data.getItemClaims().put(entry.getKey(), entry.getValue().getAsInt()));
|
||||
}
|
||||
if (!isEmpty(result.getString("skill_tree_points"))) {
|
||||
JsonObject json = new JsonParser().parse(result.getString("skill_tree_points")).getAsJsonObject();
|
||||
for (SkillTree skillTree : MMOCore.plugin.skillTreeManager.getAll()) {
|
||||
data.setSkillTreePoints(skillTree.getId(), json.has(skillTree.getId()) ? json.get(skillTree.getId()).getAsInt() : 0);
|
||||
}
|
||||
data.setSkillTreePoints("global", json.has("global") ? json.get("global").getAsInt() : 0);
|
||||
}
|
||||
|
||||
if (!isEmpty(result.getString("skill_tree_levels"))) {
|
||||
JsonObject json = new JsonParser().parse(result.getString("skill_tree_levels")).getAsJsonObject();
|
||||
for (SkillTreeNode skillTreeNode : MMOCore.plugin.skillTreeManager.getAllNodes()) {
|
||||
data.setNodeLevel(skillTreeNode, json.has(skillTreeNode.getFullId()) ? json.get(skillTreeNode.getFullId()).getAsInt() : 0);
|
||||
}
|
||||
}
|
||||
data.setupSkillTree();
|
||||
Set<String> unlockedItems = new HashSet<>();
|
||||
if (!isEmpty(result.getString("unlocked_items"))) {
|
||||
JsonArray unlockedItemsArray = new JsonParser().parse(result.getString("unlocked_items")).getAsJsonArray();
|
||||
for (JsonElement item : unlockedItemsArray)
|
||||
unlockedItems.add(item.getAsString());
|
||||
}
|
||||
data.setUnlockedItems(unlockedItems);
|
||||
if (!isEmpty(result.getString("guild"))) {
|
||||
final Guild guild = MMOCore.plugin.dataProvider.getGuildManager().getGuild(result.getString("guild"));
|
||||
if (guild != null)
|
||||
data.setGuild(guild.hasMember(data.getUniqueId()) ? guild : null);
|
||||
}
|
||||
if (!isEmpty(result.getString("attributes")))
|
||||
data.getAttributes().load(result.getString("attributes"));
|
||||
if (!isEmpty(result.getString("professions")))
|
||||
data.getCollectionSkills().load(result.getString("professions"));
|
||||
if (!isEmpty(result.getString("quests")))
|
||||
data.getQuestData().load(result.getString("quests"));
|
||||
data.getQuestData().updateBossBar();
|
||||
if (!isEmpty(result.getString("waypoints")))
|
||||
data.getWaypoints().addAll(MMOCoreUtils.jsonArrayToList(result.getString("waypoints")));
|
||||
if (!isEmpty(result.getString("friends")))
|
||||
MMOCoreUtils.jsonArrayToList(result.getString("friends")).forEach(str -> data.getFriends().add(UUID.fromString(str)));
|
||||
if (!isEmpty(result.getString("skills"))) {
|
||||
JsonObject object = new Gson().fromJson(result.getString("skills"), JsonObject.class);
|
||||
for (Map.Entry<String, JsonElement> entry : object.entrySet())
|
||||
data.setSkillLevel(entry.getKey(), entry.getValue().getAsInt());
|
||||
}
|
||||
if (!isEmpty(result.getString("bound_skills"))) {
|
||||
JsonObject object = new Gson().fromJson(result.getString("bound_skills"), JsonObject.class);
|
||||
for (Map.Entry<String, JsonElement> entry : object.entrySet())
|
||||
data.bindSkill(Integer.parseInt(entry.getKey()), data.getProfess().getSkill(entry.getValue().getAsString()));
|
||||
}
|
||||
if (!isEmpty(result.getString("class_info"))) {
|
||||
JsonObject object = new Gson().fromJson(result.getString("class_info"), JsonObject.class);
|
||||
for (Map.Entry<String, JsonElement> entry : object.entrySet()) {
|
||||
try {
|
||||
PlayerClass profess = MMOCore.plugin.classManager.get(entry.getKey());
|
||||
Validate.notNull(profess, "Could not find class '" + entry.getKey() + "'");
|
||||
data.applyClassInfo(profess, new SavedClassInformation(entry.getValue().getAsJsonObject()));
|
||||
} catch (IllegalArgumentException exception) {
|
||||
MMOCore.log(Level.WARNING, "Could not load class info '" + entry.getKey() + "': " + exception.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* These should be loaded after to make sure that the
|
||||
* MAX_MANA, MAX_STAMINA & MAX_STELLIUM stats are already loaded.
|
||||
*/
|
||||
data.setHealth(result.getDouble("health"));
|
||||
data.setMana(result.getDouble("mana"));
|
||||
data.setStamina(result.getDouble("stamina"));
|
||||
data.setStellium(result.getDouble("stellium"));
|
||||
|
||||
if (data.isOnline()) {
|
||||
double health = data.getHealth();
|
||||
health = health == 0 ? data.getPlayer().getAttribute(Attribute.GENERIC_MAX_HEALTH).getValue() : health;
|
||||
health = Math.max(Math.min(health, data.getPlayer().getAttribute(Attribute.GENERIC_MAX_HEALTH).getValue()), 0);
|
||||
data.getPlayer().setHealth(health);
|
||||
}
|
||||
|
||||
UtilityMethods.debug(MMOCore.plugin, "SQL", String.format("{ class: %s, level: %d }", data.getProfess().getId(), data.getLevel()));
|
||||
data.setFullyLoaded();
|
||||
}
|
||||
|
||||
private boolean isEmpty(@Nullable String str) {
|
||||
return str == null || str.equalsIgnoreCase("null") || str.equalsIgnoreCase("{}") || str.equalsIgnoreCase("[]") || str.equalsIgnoreCase("");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void loadEmptyData() {
|
||||
data.setLevel(manager.getDefaultData().getLevel());
|
||||
data.setClassPoints(manager.getDefaultData().getClassPoints());
|
||||
data.setSkillPoints(manager.getDefaultData().getSkillPoints());
|
||||
data.setSkillReallocationPoints(manager.getDefaultData().getSkillReallocationPoints());
|
||||
data.setAttributePoints(manager.getDefaultData().getAttributePoints());
|
||||
data.setAttributeReallocationPoints(manager.getDefaultData().getAttributeReallocationPoints());
|
||||
data.setExperience(0);
|
||||
data.getQuestData().updateBossBar();
|
||||
|
||||
data.setFullyLoaded();
|
||||
UtilityMethods.debug(MMOCore.plugin, "SQL", "Loaded DEFAULT data for: '" + data.getUniqueId() + "' as no saved data was found.");
|
||||
}
|
||||
}
|
@ -1,94 +0,0 @@
|
||||
package net.Indyuce.mmocore.manager.data.mysql;
|
||||
|
||||
import io.lumine.mythic.lib.sql.MMODataSource;
|
||||
import net.Indyuce.mmocore.MMOCore;
|
||||
import net.Indyuce.mmocore.manager.data.DataProvider;
|
||||
import net.Indyuce.mmocore.manager.data.GuildDataManager;
|
||||
import net.Indyuce.mmocore.manager.data.PlayerDataManager;
|
||||
import net.Indyuce.mmocore.manager.data.yaml.YAMLGuildDataManager;
|
||||
import org.bukkit.configuration.file.FileConfiguration;
|
||||
|
||||
import java.sql.SQLException;
|
||||
|
||||
public class MySQLDataProvider extends MMODataSource implements DataProvider {
|
||||
private final MySQLPlayerDataManager playerManager = new MySQLPlayerDataManager(this);
|
||||
private final YAMLGuildDataManager guildManager = new YAMLGuildDataManager();
|
||||
|
||||
private static final String[] NEW_COLUMNS = new String[]{
|
||||
"times_claimed", "LONGTEXT",
|
||||
"is_saved", "TINYINT",
|
||||
"skill_reallocation_points", "INT(11)",
|
||||
"skill_tree_reallocation_points", "INT(11)",
|
||||
"skill_tree_points", "LONGTEXT",
|
||||
"skill_tree_levels", "LONGTEXT",
|
||||
"unlocked_items","LONGTEXT",
|
||||
"health", "FLOAT",
|
||||
"mana", "FLOAT",
|
||||
"stamina", "FLOAT",
|
||||
"stellium", "FLOAT"};
|
||||
|
||||
public MySQLDataProvider(FileConfiguration config) {
|
||||
super(MMOCore.plugin);
|
||||
|
||||
this.setup(config);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void load() {
|
||||
|
||||
// Fully create table
|
||||
executeUpdateAsync("CREATE TABLE IF NOT EXISTS mmocore_playerdata(uuid VARCHAR(36)," +
|
||||
"class_points INT(11) DEFAULT 0," +
|
||||
"skill_points INT(11) DEFAULT 0," +
|
||||
"attribute_points INT(11) DEFAULT 0," +
|
||||
"attribute_realloc_points INT(11) DEFAULT 0," +
|
||||
"skill_reallocation_points INT(11) DEFAULT 0," +
|
||||
"skill_tree_reallocation_points INT(11) DEFAULT 0," +
|
||||
"skill_tree_points LONGTEXT," +
|
||||
"skill_tree_levels LONGTEXT," +
|
||||
"level INT(11) DEFAULT 1," +
|
||||
"experience INT(11) DEFAULT 0," +
|
||||
"class VARCHAR(20),guild VARCHAR(20)," +
|
||||
"last_login LONG," +
|
||||
"attributes LONGTEXT," +
|
||||
"professions LONGTEXT," +
|
||||
"times_claimed LONGTEXT," +
|
||||
"quests LONGTEXT," +
|
||||
"waypoints LONGTEXT," +
|
||||
"friends LONGTEXT," +
|
||||
"skills LONGTEXT," +
|
||||
"bound_skills LONGTEXT," +
|
||||
"health FLOAT," +
|
||||
"mana FLOAT," +
|
||||
"stamina FLOAT," +
|
||||
"stellium FLOAT," +
|
||||
"unlocked_items LONGTEXT," +
|
||||
"class_info LONGTEXT," +
|
||||
"is_saved TINYINT," +
|
||||
"PRIMARY KEY (uuid));");
|
||||
|
||||
// Add columns that might not be here by default
|
||||
for (int i = 0; i < NEW_COLUMNS.length; i += 2) {
|
||||
final String columnName = NEW_COLUMNS[i];
|
||||
final String dataType = NEW_COLUMNS[i + 1];
|
||||
getResultAsync("SELECT * FROM information_schema.COLUMNS WHERE TABLE_NAME = 'mmocore_playerdata' AND COLUMN_NAME = '" + columnName + "'", result -> {
|
||||
try {
|
||||
if (!result.next())
|
||||
executeUpdate("ALTER TABLE mmocore_playerdata ADD COLUMN " + columnName + " " + dataType);
|
||||
} catch (SQLException exception) {
|
||||
exception.printStackTrace();
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public PlayerDataManager getDataManager() {
|
||||
return playerManager;
|
||||
}
|
||||
|
||||
@Override
|
||||
public GuildDataManager getGuildManager() {
|
||||
return guildManager;
|
||||
}
|
||||
}
|
@ -0,0 +1,147 @@
|
||||
package net.Indyuce.mmocore.manager.data.sql;
|
||||
|
||||
import com.google.gson.JsonArray;
|
||||
import com.google.gson.JsonElement;
|
||||
import com.google.gson.JsonObject;
|
||||
import com.google.gson.JsonParser;
|
||||
import io.lumine.mythic.lib.MythicLib;
|
||||
import io.lumine.mythic.lib.UtilityMethods;
|
||||
import io.lumine.mythic.lib.data.sql.SQLDataSynchronizer;
|
||||
import net.Indyuce.mmocore.MMOCore;
|
||||
import net.Indyuce.mmocore.api.player.PlayerData;
|
||||
import net.Indyuce.mmocore.api.player.profess.PlayerClass;
|
||||
import net.Indyuce.mmocore.api.player.profess.SavedClassInformation;
|
||||
import net.Indyuce.mmocore.api.util.MMOCoreUtils;
|
||||
import net.Indyuce.mmocore.guild.provided.Guild;
|
||||
import net.Indyuce.mmocore.manager.data.PlayerDataManager;
|
||||
import net.Indyuce.mmocore.skilltree.SkillTreeNode;
|
||||
import net.Indyuce.mmocore.skilltree.tree.SkillTree;
|
||||
import org.apache.commons.lang.Validate;
|
||||
import org.bukkit.attribute.Attribute;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
import java.util.HashSet;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
import java.util.logging.Level;
|
||||
|
||||
public class MMOCoreDataSynchronizer extends SQLDataSynchronizer<PlayerData> {
|
||||
public MMOCoreDataSynchronizer(SQLDataHandler handler, PlayerData data) {
|
||||
super("mmocore_playerdata", "uuid", handler.getDataSource(), data);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void loadData(ResultSet result) throws SQLException {
|
||||
|
||||
// Reset stats linked to triggers
|
||||
getData().resetTriggerStats();
|
||||
|
||||
getData().setClassPoints(result.getInt("class_points"));
|
||||
getData().setSkillPoints(result.getInt("skill_points"));
|
||||
getData().setSkillReallocationPoints(result.getInt("skill_reallocation_points"));
|
||||
getData().setSkillTreeReallocationPoints(result.getInt("skill_tree_reallocation_points"));
|
||||
getData().setAttributePoints(result.getInt("attribute_points"));
|
||||
getData().setAttributeReallocationPoints(result.getInt("attribute_realloc_points"));
|
||||
getData().setLevel(result.getInt("level"));
|
||||
getData().setExperience(result.getInt("experience"));
|
||||
|
||||
if (!isEmpty(result.getString("class")))
|
||||
getData().setClass(MMOCore.plugin.classManager.get(result.getString("class")));
|
||||
|
||||
if (!isEmpty(result.getString("times_claimed"))) {
|
||||
JsonObject json = new JsonParser().parse(result.getString("times_claimed")).getAsJsonObject();
|
||||
json.entrySet().forEach(entry -> getData().getItemClaims().put(entry.getKey(), entry.getValue().getAsInt()));
|
||||
}
|
||||
if (!isEmpty(result.getString("skill_tree_points"))) {
|
||||
JsonObject json = new JsonParser().parse(result.getString("skill_tree_points")).getAsJsonObject();
|
||||
for (SkillTree skillTree : MMOCore.plugin.skillTreeManager.getAll()) {
|
||||
getData().setSkillTreePoints(skillTree.getId(), json.has(skillTree.getId()) ? json.get(skillTree.getId()).getAsInt() : 0);
|
||||
}
|
||||
getData().setSkillTreePoints("global", json.has("global") ? json.get("global").getAsInt() : 0);
|
||||
}
|
||||
|
||||
if (!isEmpty(result.getString("skill_tree_levels"))) {
|
||||
JsonObject json = new JsonParser().parse(result.getString("skill_tree_levels")).getAsJsonObject();
|
||||
for (SkillTreeNode skillTreeNode : MMOCore.plugin.skillTreeManager.getAllNodes()) {
|
||||
getData().setNodeLevel(skillTreeNode, json.has(skillTreeNode.getFullId()) ? json.get(skillTreeNode.getFullId()).getAsInt() : 0);
|
||||
}
|
||||
}
|
||||
getData().setupSkillTree();
|
||||
Set<String> unlockedItems = new HashSet<>();
|
||||
if (!isEmpty(result.getString("unlocked_items"))) {
|
||||
JsonArray unlockedItemsArray = new JsonParser().parse(result.getString("unlocked_items")).getAsJsonArray();
|
||||
for (JsonElement item : unlockedItemsArray)
|
||||
unlockedItems.add(item.getAsString());
|
||||
}
|
||||
getData().setUnlockedItems(unlockedItems);
|
||||
if (!isEmpty(result.getString("guild"))) {
|
||||
final Guild guild = MMOCore.plugin.dataProvider.getGuildManager().getGuild(result.getString("guild"));
|
||||
if (guild != null)
|
||||
getData().setGuild(guild.hasMember(getData().getUniqueId()) ? guild : null);
|
||||
}
|
||||
if (!isEmpty(result.getString("attributes")))
|
||||
getData().getAttributes().load(result.getString("attributes"));
|
||||
if (!isEmpty(result.getString("professions")))
|
||||
getData().getCollectionSkills().load(result.getString("professions"));
|
||||
if (!isEmpty(result.getString("quests")))
|
||||
getData().getQuestData().load(result.getString("quests"));
|
||||
getData().getQuestData().updateBossBar();
|
||||
if (!isEmpty(result.getString("waypoints")))
|
||||
getData().getWaypoints().addAll(MMOCoreUtils.jsonArrayToList(result.getString("waypoints")));
|
||||
if (!isEmpty(result.getString("friends")))
|
||||
MMOCoreUtils.jsonArrayToList(result.getString("friends")).forEach(str -> getData().getFriends().add(UUID.fromString(str)));
|
||||
if (!isEmpty(result.getString("skills"))) {
|
||||
JsonObject object = MythicLib.plugin.getGson().fromJson(result.getString("skills"), JsonObject.class);
|
||||
for (Map.Entry<String, JsonElement> entry : object.entrySet())
|
||||
getData().setSkillLevel(entry.getKey(), entry.getValue().getAsInt());
|
||||
}
|
||||
if (!isEmpty(result.getString("bound_skills"))) {
|
||||
JsonObject object = MythicLib.plugin.getGson().fromJson(result.getString("bound_skills"), JsonObject.class);
|
||||
for (Map.Entry<String, JsonElement> entry : object.entrySet())
|
||||
getData().bindSkill(Integer.parseInt(entry.getKey()), getData().getProfess().getSkill(entry.getValue().getAsString()));
|
||||
}
|
||||
if (!isEmpty(result.getString("class_info"))) {
|
||||
JsonObject object = MythicLib.plugin.getGson().fromJson(result.getString("class_info"), JsonObject.class);
|
||||
for (Map.Entry<String, JsonElement> entry : object.entrySet()) {
|
||||
try {
|
||||
PlayerClass profess = MMOCore.plugin.classManager.get(entry.getKey());
|
||||
Validate.notNull(profess, "Could not find class '" + entry.getKey() + "'");
|
||||
getData().applyClassInfo(profess, new SavedClassInformation(entry.getValue().getAsJsonObject()));
|
||||
} catch (IllegalArgumentException exception) {
|
||||
MMOCore.log(Level.WARNING, "Could not load class info '" + entry.getKey() + "': " + exception.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* These should be loaded after to make sure that the
|
||||
* MAX_MANA, MAX_STAMINA & MAX_STELLIUM stats are already loaded.
|
||||
*/
|
||||
getData().setHealth(result.getDouble("health"));
|
||||
getData().setMana(result.getDouble("mana"));
|
||||
getData().setStamina(result.getDouble("stamina"));
|
||||
getData().setStellium(result.getDouble("stellium"));
|
||||
|
||||
if (getData().isOnline()) {
|
||||
double health = getData().getHealth();
|
||||
health = health == 0 ? getData().getPlayer().getAttribute(Attribute.GENERIC_MAX_HEALTH).getValue() : health;
|
||||
health = Math.max(Math.min(health, getData().getPlayer().getAttribute(Attribute.GENERIC_MAX_HEALTH).getValue()), 0);
|
||||
getData().getPlayer().setHealth(health);
|
||||
}
|
||||
|
||||
UtilityMethods.debug(MMOCore.plugin, "SQL", String.format("{ class: %s, level: %d }", getData().getProfess().getId(), getData().getLevel()));
|
||||
}
|
||||
|
||||
private boolean isEmpty(@Nullable String str) {
|
||||
return str == null || str.equalsIgnoreCase("null") || str.equalsIgnoreCase("{}") || str.equalsIgnoreCase("[]") || str.equalsIgnoreCase("");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void loadEmptyData() {
|
||||
MMOCore.plugin.playerDataManager.getDefaultData().apply(getData());
|
||||
UtilityMethods.debug(MMOCore.plugin, "SQL", "Loaded DEFAULT data for: '" + getData().getUniqueId() + "' as no saved data was found.");
|
||||
}
|
||||
}
|
@ -1,10 +1,11 @@
|
||||
package net.Indyuce.mmocore.manager.data.mysql;
|
||||
package net.Indyuce.mmocore.manager.data.sql;
|
||||
|
||||
import com.google.gson.JsonArray;
|
||||
import com.google.gson.JsonObject;
|
||||
import io.lumine.mythic.lib.data.sql.SQLDataSource;
|
||||
import net.Indyuce.mmocore.MMOCore;
|
||||
import net.Indyuce.mmocore.api.player.PlayerData;
|
||||
import net.Indyuce.mmocore.manager.data.yaml.YAMLPlayerDataManager;
|
||||
import net.Indyuce.mmocore.manager.data.yaml.YAMLPlayerDataHandler;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
@ -17,19 +18,23 @@ import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.logging.Level;
|
||||
|
||||
/**
|
||||
* @deprecated Not implemented yet
|
||||
*/
|
||||
@Deprecated
|
||||
public class PlayerDataTableUpdater {
|
||||
private final PlayerData playerData;
|
||||
private final MySQLDataProvider provider;
|
||||
private final SQLDataSource provider;
|
||||
private final Map<String, String> requestMap = new HashMap<>();
|
||||
|
||||
public PlayerDataTableUpdater(MySQLDataProvider provider, PlayerData playerData) {
|
||||
public PlayerDataTableUpdater(SQLDataSource provider, PlayerData playerData) {
|
||||
this.playerData = playerData;
|
||||
this.provider = provider;
|
||||
}
|
||||
|
||||
public void executeRequest(boolean logout) {
|
||||
public void executeRequest(boolean autosave) {
|
||||
final String request = "INSERT INTO mmocore_playerdata(uuid, " + formatCollection(requestMap.keySet(), false)
|
||||
+ ") VALUES('" + playerData.getUniqueId() + "'," + formatCollection(requestMap.values(), true) + ")" +
|
||||
+ ") VALUES('" + playerData.getProfileId() + "'," + formatCollection(requestMap.values(), true) + ")" +
|
||||
" ON DUPLICATE KEY UPDATE " + formatMap() + ";";
|
||||
|
||||
try {
|
||||
@ -39,22 +44,22 @@ public class PlayerDataTableUpdater {
|
||||
try {
|
||||
statement.executeUpdate();
|
||||
} catch (SQLException exception) {
|
||||
MMOCore.log(Level.WARNING, "Could not save player data of " + playerData.getUniqueId() + ", saving through YAML instead");
|
||||
new YAMLPlayerDataManager(provider).saveData(playerData, logout);
|
||||
MMOCore.log(Level.WARNING, "Could not save player data of " + playerData.getProfileId() + ", saving through YAML instead");
|
||||
new YAMLPlayerDataHandler(MMOCore.plugin).saveData(playerData, autosave);
|
||||
exception.printStackTrace();
|
||||
} finally {
|
||||
statement.close();
|
||||
}
|
||||
} catch (SQLException exception) {
|
||||
MMOCore.log(Level.WARNING, "Could not save player data of " + playerData.getUniqueId() + ", saving through YAML instead");
|
||||
new YAMLPlayerDataManager(provider).saveData(playerData, logout);
|
||||
MMOCore.log(Level.WARNING, "Could not save player data of " + playerData.getProfileId() + ", saving through YAML instead");
|
||||
new YAMLPlayerDataHandler(MMOCore.plugin).saveData(playerData, autosave);
|
||||
exception.printStackTrace();
|
||||
} finally {
|
||||
connection.close();
|
||||
}
|
||||
} catch (SQLException exception) {
|
||||
MMOCore.log(Level.WARNING, "Could not save player data of " + playerData.getUniqueId() + ", saving through YAML instead");
|
||||
new YAMLPlayerDataManager(provider).saveData(playerData, logout);
|
||||
MMOCore.log(Level.WARNING, "Could not save player data of " + playerData.getProfileId() + ", saving through YAML instead");
|
||||
new YAMLPlayerDataHandler(MMOCore.plugin).saveData(playerData, autosave);
|
||||
exception.printStackTrace();
|
||||
}
|
||||
}
|
||||
@ -95,7 +100,7 @@ public class PlayerDataTableUpdater {
|
||||
addData(key, json.toString());
|
||||
}
|
||||
|
||||
public <T,V> void addJSONObject(String key, Set<Map.Entry<T, V>> collection) {
|
||||
public <T, V> void addJSONObject(String key, Set<Map.Entry<T, V>> collection) {
|
||||
JsonObject json = new JsonObject();
|
||||
for (Map.Entry<T, V> entry : collection)
|
||||
json.addProperty(entry.getKey().toString(), entry.getValue().toString());
|
@ -1,42 +1,100 @@
|
||||
package net.Indyuce.mmocore.manager.data.mysql;
|
||||
package net.Indyuce.mmocore.manager.data.sql;
|
||||
|
||||
import com.google.gson.JsonArray;
|
||||
import com.google.gson.JsonObject;
|
||||
import io.lumine.mythic.lib.UtilityMethods;
|
||||
import io.lumine.mythic.lib.data.sql.SQLDataSource;
|
||||
import io.lumine.mythic.lib.data.sql.SQLSynchronizedDataHandler;
|
||||
import net.Indyuce.mmocore.MMOCore;
|
||||
import net.Indyuce.mmocore.api.player.OfflinePlayerData;
|
||||
import net.Indyuce.mmocore.manager.data.OfflinePlayerData;
|
||||
import net.Indyuce.mmocore.api.player.PlayerData;
|
||||
import net.Indyuce.mmocore.api.player.profess.PlayerClass;
|
||||
import net.Indyuce.mmocore.api.player.profess.SavedClassInformation;
|
||||
import net.Indyuce.mmocore.manager.data.PlayerDataManager;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.sql.SQLException;
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
public class MySQLPlayerDataManager extends PlayerDataManager {
|
||||
private final MySQLDataProvider provider;
|
||||
|
||||
public MySQLPlayerDataManager(MySQLDataProvider provider) {
|
||||
this.provider = provider;
|
||||
public class SQLDataHandler extends SQLSynchronizedDataHandler<PlayerData, OfflinePlayerData, MMOCoreDataSynchronizer> {
|
||||
public SQLDataHandler(SQLDataSource dataSource) {
|
||||
super(dataSource);
|
||||
}
|
||||
|
||||
public MySQLDataProvider getProvider() {
|
||||
return provider;
|
||||
private static final String[] NEW_COLUMNS = new String[]{
|
||||
"times_claimed", "LONGTEXT",
|
||||
"is_saved", "TINYINT",
|
||||
"skill_reallocation_points", "INT(11)",
|
||||
"skill_tree_reallocation_points", "INT(11)",
|
||||
"skill_tree_points", "LONGTEXT",
|
||||
"skill_tree_levels", "LONGTEXT",
|
||||
"unlocked_items", "LONGTEXT",
|
||||
"health", "FLOAT",
|
||||
"mana", "FLOAT",
|
||||
"stamina", "FLOAT",
|
||||
"stellium", "FLOAT"};
|
||||
|
||||
@Override
|
||||
public void setup() {
|
||||
|
||||
// Fully create table
|
||||
getDataSource().executeUpdateAsync("CREATE TABLE IF NOT EXISTS mmocore_playerdata(uuid VARCHAR(36)," +
|
||||
"class_points INT(11) DEFAULT 0," +
|
||||
"skill_points INT(11) DEFAULT 0," +
|
||||
"attribute_points INT(11) DEFAULT 0," +
|
||||
"attribute_realloc_points INT(11) DEFAULT 0," +
|
||||
"skill_reallocation_points INT(11) DEFAULT 0," +
|
||||
"skill_tree_reallocation_points INT(11) DEFAULT 0," +
|
||||
"skill_tree_points LONGTEXT," +
|
||||
"skill_tree_levels LONGTEXT," +
|
||||
"level INT(11) DEFAULT 1," +
|
||||
"experience INT(11) DEFAULT 0," +
|
||||
"class VARCHAR(20),guild VARCHAR(20)," +
|
||||
"last_login LONG," +
|
||||
"attributes LONGTEXT," +
|
||||
"professions LONGTEXT," +
|
||||
"times_claimed LONGTEXT," +
|
||||
"quests LONGTEXT," +
|
||||
"waypoints LONGTEXT," +
|
||||
"friends LONGTEXT," +
|
||||
"skills LONGTEXT," +
|
||||
"bound_skills LONGTEXT," +
|
||||
"health FLOAT," +
|
||||
"mana FLOAT," +
|
||||
"stamina FLOAT," +
|
||||
"stellium FLOAT," +
|
||||
"unlocked_items LONGTEXT," +
|
||||
"class_info LONGTEXT," +
|
||||
"is_saved TINYINT," +
|
||||
"PRIMARY KEY (uuid));");
|
||||
|
||||
// Add columns that might not be here by default
|
||||
for (int i = 0; i < NEW_COLUMNS.length; i += 2) {
|
||||
final String columnName = NEW_COLUMNS[i];
|
||||
final String dataType = NEW_COLUMNS[i + 1];
|
||||
getDataSource().getResultAsync("SELECT * FROM information_schema.COLUMNS WHERE TABLE_NAME = 'mmocore_playerdata' AND COLUMN_NAME = '" + columnName + "'", result -> {
|
||||
try {
|
||||
if (!result.next())
|
||||
getDataSource().executeUpdate("ALTER TABLE mmocore_playerdata ADD COLUMN " + columnName + " " + dataType);
|
||||
} catch (SQLException exception) {
|
||||
exception.printStackTrace();
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void loadData(PlayerData data) {
|
||||
new MMOCoreDataSynchronizer(this, data).fetch();
|
||||
public MMOCoreDataSynchronizer newDataSynchronizer(PlayerData playerData) {
|
||||
return new MMOCoreDataSynchronizer(this, playerData);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void saveData(PlayerData data, boolean logout) {
|
||||
UtilityMethods.debug(MMOCore.plugin, "SQL", "Saving data for: '" + data.getUniqueId() + "'...");
|
||||
public void saveData(PlayerData data, boolean autosave) {
|
||||
UtilityMethods.debug(MMOCore.plugin, "SQL", "Saving data for: '" + data.getProfileId() + "'...");
|
||||
|
||||
final PlayerDataTableUpdater updater = new PlayerDataTableUpdater(provider, data);
|
||||
final PlayerDataTableUpdater updater = new PlayerDataTableUpdater(getDataSource(), data);
|
||||
updater.addData("class_points", data.getClassPoints());
|
||||
updater.addData("skill_points", data.getSkillPoints());
|
||||
updater.addData("skill_reallocation_points", data.getSkillReallocationPoints());
|
||||
@ -44,7 +102,7 @@ public class MySQLPlayerDataManager extends PlayerDataManager {
|
||||
updater.addData("attribute_realloc_points", data.getAttributeReallocationPoints());
|
||||
updater.addJSONArray("waypoints", data.getWaypoints());
|
||||
updater.addData("skill_tree_reallocation_points", data.getSkillTreeReallocationPoints());
|
||||
updater.addData("health",data.getHealth());
|
||||
updater.addData("health", data.getHealth());
|
||||
updater.addData("mana", data.getMana());
|
||||
updater.addData("stellium", data.getStellium());
|
||||
updater.addData("stamina", data.getStamina());
|
||||
@ -65,12 +123,12 @@ public class MySQLPlayerDataManager extends PlayerDataManager {
|
||||
updater.addData("quests", data.getQuestData().toJsonString());
|
||||
updater.addData("class_info", createClassInfoData(data).toString());
|
||||
updater.addJSONArray("unlocked_items", data.getUnlockedItems());
|
||||
if (logout)
|
||||
if (!autosave)
|
||||
updater.addData("is_saved", 1);
|
||||
|
||||
updater.executeRequest(logout);
|
||||
updater.executeRequest(autosave);
|
||||
|
||||
UtilityMethods.debug(MMOCore.plugin, "SQL", "Saved data for: " + data.getUniqueId());
|
||||
UtilityMethods.debug(MMOCore.plugin, "SQL", "Saved data for: " + data.getProfileId());
|
||||
UtilityMethods.debug(MMOCore.plugin, "SQL", String.format("{ class: %s, level: %d }", data.getProfess().getId(), data.getLevel()));
|
||||
}
|
||||
|
||||
@ -132,68 +190,7 @@ public class MySQLPlayerDataManager extends PlayerDataManager {
|
||||
@NotNull
|
||||
@Override
|
||||
public OfflinePlayerData getOffline(UUID uuid) {
|
||||
return isLoaded(uuid) ? get(uuid) : new MySQLOfflinePlayerData(uuid);
|
||||
}
|
||||
|
||||
public class MySQLOfflinePlayerData extends OfflinePlayerData {
|
||||
private int level;
|
||||
private long lastLogin;
|
||||
private PlayerClass profess;
|
||||
private List<UUID> friends;
|
||||
|
||||
public MySQLOfflinePlayerData(UUID uuid) {
|
||||
super(uuid);
|
||||
/*
|
||||
provider.getResult("SELECT * FROM mmocore_playerdata WHERE uuid = '" + uuid + "';", (result) -> {
|
||||
try {
|
||||
MythicLib.debug("MMOCoreSQL", "Loading OFFLINE data for '" + uuid + "'.");
|
||||
if (!result.next()) {
|
||||
level = 0;
|
||||
lastLogin = 0;
|
||||
profess = MMOCore.plugin.classManager.getDefaultClass();
|
||||
friends = new ArrayList<>();
|
||||
MythicLib.debug("MMOCoreSQL", "Default OFFLINE data loaded.");
|
||||
} else {
|
||||
level = result.getInt("level");
|
||||
lastLogin = result.getLong("last_login");
|
||||
profess = isEmpty(result.getString("class")) ? MMOCore.plugin.classManager.getDefaultClass() : MMOCore.plugin.classManager.get(result.getString("class"));
|
||||
if (!isEmpty(result.getString("friends")))
|
||||
MMOCoreUtils.jsonArrayToList(result.getString("friends")).forEach(str -> friends.add(UUID.fromString(str)));
|
||||
else friends = new ArrayList<>();
|
||||
MythicLib.debug("MMOCoreSQL", "Saved OFFLINE data loaded.");
|
||||
}
|
||||
} catch (SQLException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}); */
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeFriend(UUID uuid) {
|
||||
// TODO recode
|
||||
// friends.remove(uuid);
|
||||
// new PlayerDataTableUpdater(provider, uuid).updateData("friends", friends.stream().map(UUID::toString).collect(Collectors.toList()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasFriend(UUID uuid) {
|
||||
return friends.contains(uuid);
|
||||
}
|
||||
|
||||
@Override
|
||||
public PlayerClass getProfess() {
|
||||
return profess;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getLevel() {
|
||||
return level;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getLastLogin() {
|
||||
return lastLogin;
|
||||
}
|
||||
return new SQLOfflinePlayerData(uuid);
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,81 @@
|
||||
package net.Indyuce.mmocore.manager.data.sql;
|
||||
|
||||
import net.Indyuce.mmocore.api.player.profess.PlayerClass;
|
||||
import net.Indyuce.mmocore.manager.data.OfflinePlayerData;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
* @deprecated Not implemented yet
|
||||
*/
|
||||
@Deprecated
|
||||
public class SQLOfflinePlayerData implements OfflinePlayerData {
|
||||
private final UUID uuid;
|
||||
private int level;
|
||||
private long lastLogin;
|
||||
private PlayerClass profess;
|
||||
private List<UUID> friends;
|
||||
|
||||
@Deprecated
|
||||
public SQLOfflinePlayerData(UUID uuid) {
|
||||
this.uuid = uuid;
|
||||
/*
|
||||
provider.getResult("SELECT * FROM mmocore_playerdata WHERE uuid = '" + uuid + "';", (result) -> {
|
||||
try {
|
||||
MythicLib.debug("MMOCoreSQL", "Loading OFFLINE data for '" + uuid + "'.");
|
||||
if (!result.next()) {
|
||||
level = 0;
|
||||
lastLogin = 0;
|
||||
profess = MMOCore.plugin.classManager.getDefaultClass();
|
||||
friends = new ArrayList<>();
|
||||
MythicLib.debug("MMOCoreSQL", "Default OFFLINE data loaded.");
|
||||
} else {
|
||||
level = result.getInt("level");
|
||||
lastLogin = result.getLong("last_login");
|
||||
profess = isEmpty(result.getString("class")) ? MMOCore.plugin.classManager.getDefaultClass() : MMOCore.plugin.classManager.get(result.getString("class"));
|
||||
if (!isEmpty(result.getString("friends")))
|
||||
MMOCoreUtils.jsonArrayToList(result.getString("friends")).forEach(str -> friends.add(UUID.fromString(str)));
|
||||
else friends = new ArrayList<>();
|
||||
MythicLib.debug("MMOCoreSQL", "Saved OFFLINE data loaded.");
|
||||
}
|
||||
} catch (SQLException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}); */
|
||||
}
|
||||
|
||||
@Override
|
||||
@NotNull
|
||||
public UUID getUniqueId() {
|
||||
return uuid;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeFriend(UUID uuid) {
|
||||
// TODO recode
|
||||
// friends.remove(uuid);
|
||||
// new PlayerDataTableUpdater(provider, uuid).updateData("friends", friends.stream().map(UUID::toString).collect(Collectors.toList()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasFriend(UUID uuid) {
|
||||
return friends.contains(uuid);
|
||||
}
|
||||
|
||||
@Override
|
||||
public PlayerClass getProfess() {
|
||||
return profess;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getLevel() {
|
||||
return level;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getLastLogin() {
|
||||
return lastLogin;
|
||||
}
|
||||
}
|
@ -1,20 +0,0 @@
|
||||
package net.Indyuce.mmocore.manager.data.yaml;
|
||||
|
||||
import net.Indyuce.mmocore.manager.data.DataProvider;
|
||||
import net.Indyuce.mmocore.manager.data.GuildDataManager;
|
||||
import net.Indyuce.mmocore.manager.data.PlayerDataManager;
|
||||
|
||||
public class YAMLDataProvider implements DataProvider {
|
||||
private final YAMLPlayerDataManager playerManager = new YAMLPlayerDataManager(this);
|
||||
private final YAMLGuildDataManager guildManager = new YAMLGuildDataManager();
|
||||
|
||||
@Override
|
||||
public PlayerDataManager getDataManager() {
|
||||
return playerManager;
|
||||
}
|
||||
|
||||
@Override
|
||||
public GuildDataManager getGuildManager() {
|
||||
return guildManager;
|
||||
}
|
||||
}
|
@ -6,46 +6,58 @@ import java.util.UUID;
|
||||
import net.Indyuce.mmocore.MMOCore;
|
||||
import net.Indyuce.mmocore.api.player.profess.PlayerClass;
|
||||
import net.Indyuce.mmocore.api.ConfigFile;
|
||||
import net.Indyuce.mmocore.api.player.OfflinePlayerData;
|
||||
import net.Indyuce.mmocore.manager.data.OfflinePlayerData;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
public class YAMLOfflinePlayerData extends OfflinePlayerData {
|
||||
private final ConfigFile config;
|
||||
/**
|
||||
* @deprecated Not implemented yet
|
||||
*/
|
||||
@Deprecated
|
||||
public class YAMLOfflinePlayerData implements OfflinePlayerData {
|
||||
private final UUID uuid;
|
||||
private final ConfigFile config;
|
||||
|
||||
/**
|
||||
* Supports offline player data operations like friend removals which can't
|
||||
* be handled when their player data is not loaded in the data map.
|
||||
*/
|
||||
public YAMLOfflinePlayerData(UUID uuid) {
|
||||
super(uuid);
|
||||
/**
|
||||
* Supports offline player data operations like friend removals which can't
|
||||
* be handled when their player data is not loaded in the data map.
|
||||
*/
|
||||
@Deprecated
|
||||
public YAMLOfflinePlayerData(UUID uuid) {
|
||||
this.uuid = uuid;
|
||||
config = new ConfigFile(uuid);
|
||||
}
|
||||
|
||||
config = new ConfigFile(uuid);
|
||||
}
|
||||
@Override
|
||||
@NotNull
|
||||
public UUID getUniqueId() {
|
||||
return uuid;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeFriend(UUID uuid) {
|
||||
List<String> friends = config.getConfig().getStringList("friends");
|
||||
friends.remove(uuid.toString());
|
||||
config.getConfig().set("friends", friends);
|
||||
config.save();
|
||||
}
|
||||
@Override
|
||||
public void removeFriend(UUID uuid) {
|
||||
List<String> friends = config.getConfig().getStringList("friends");
|
||||
friends.remove(uuid.toString());
|
||||
config.getConfig().set("friends", friends);
|
||||
config.save();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasFriend(UUID uuid) {
|
||||
return config.getConfig().getStringList("friends").contains(uuid.toString());
|
||||
}
|
||||
@Override
|
||||
public boolean hasFriend(UUID uuid) {
|
||||
return config.getConfig().getStringList("friends").contains(uuid.toString());
|
||||
}
|
||||
|
||||
@Override
|
||||
public PlayerClass getProfess() {
|
||||
return config.getConfig().contains("class") ? MMOCore.plugin.classManager.get(config.getConfig().getString("class")) : MMOCore.plugin.classManager.getDefaultClass();
|
||||
}
|
||||
@Override
|
||||
public PlayerClass getProfess() {
|
||||
return config.getConfig().contains("class") ? MMOCore.plugin.classManager.get(config.getConfig().getString("class")) : MMOCore.plugin.classManager.getDefaultClass();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getLevel() {
|
||||
return config.getConfig().getInt("level");
|
||||
}
|
||||
@Override
|
||||
public int getLevel() {
|
||||
return config.getConfig().getInt("level");
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getLastLogin() {
|
||||
return config.getConfig().getLong("last-login");
|
||||
}
|
||||
@Override
|
||||
public long getLastLogin() {
|
||||
return config.getConfig().getLong("last-login");
|
||||
}
|
||||
}
|
||||
|
@ -1,54 +1,65 @@
|
||||
package net.Indyuce.mmocore.manager.data.yaml;
|
||||
|
||||
import io.lumine.mythic.lib.data.yaml.YAMLSynchronizedDataHandler;
|
||||
import net.Indyuce.mmocore.MMOCore;
|
||||
import net.Indyuce.mmocore.api.ConfigFile;
|
||||
import net.Indyuce.mmocore.api.player.OfflinePlayerData;
|
||||
import net.Indyuce.mmocore.api.player.PlayerData;
|
||||
import net.Indyuce.mmocore.api.player.profess.PlayerClass;
|
||||
import net.Indyuce.mmocore.api.player.profess.SavedClassInformation;
|
||||
import net.Indyuce.mmocore.api.util.MMOCoreUtils;
|
||||
import net.Indyuce.mmocore.guild.provided.Guild;
|
||||
import net.Indyuce.mmocore.manager.data.DataProvider;
|
||||
import net.Indyuce.mmocore.manager.data.PlayerDataManager;
|
||||
import net.Indyuce.mmocore.manager.data.OfflinePlayerData;
|
||||
import net.Indyuce.mmocore.skill.ClassSkill;
|
||||
import net.Indyuce.mmocore.skilltree.SkillTreeNode;
|
||||
import org.apache.commons.lang.Validate;
|
||||
import org.bukkit.attribute.Attribute;
|
||||
import org.bukkit.configuration.ConfigurationSection;
|
||||
import org.bukkit.configuration.file.FileConfiguration;
|
||||
import org.bukkit.plugin.Plugin;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.ArrayList;
|
||||
import java.util.UUID;
|
||||
import java.util.logging.Level;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
public class YAMLPlayerDataManager extends PlayerDataManager {
|
||||
private final DataProvider provider;
|
||||
|
||||
public YAMLPlayerDataManager(DataProvider provider) {
|
||||
this.provider = provider;
|
||||
public class YAMLPlayerDataHandler extends YAMLSynchronizedDataHandler<PlayerData, OfflinePlayerData> {
|
||||
public YAMLPlayerDataHandler(Plugin owning) {
|
||||
super(owning);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void loadData(PlayerData data) {
|
||||
FileConfiguration config = new ConfigFile(data.getUniqueId()).getConfig();
|
||||
public void setup() {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void loadFromSection(PlayerData data, ConfigurationSection config) {
|
||||
|
||||
// Reset stats linked to triggers.
|
||||
data.resetTriggerStats();
|
||||
|
||||
data.setClassPoints(config.getInt("class-points", getDefaultData().getClassPoints()));
|
||||
data.setSkillPoints(config.getInt("skill-points", getDefaultData().getSkillPoints()));
|
||||
data.setSkillReallocationPoints(config.getInt("skill-reallocation-points", getDefaultData().getSkillReallocationPoints()));
|
||||
data.setSkillTreeReallocationPoints(config.getInt("skill-tree-reallocation-points", getDefaultData().getSkillTreeReallocationPoints()));
|
||||
data.setAttributePoints(config.getInt("attribute-points", getDefaultData().getAttributePoints()));
|
||||
data.setAttributeReallocationPoints(config.getInt("attribute-realloc-points", getDefaultData().getAttributeReallocationPoints()));
|
||||
data.setLevel(config.getInt("level", getDefaultData().getLevel()));
|
||||
// Load default data
|
||||
if (!config.contains("class-points")) {
|
||||
MMOCore.plugin.playerDataManager.getDefaultData().apply(data);
|
||||
return;
|
||||
}
|
||||
|
||||
data.setClassPoints(config.getInt("class-points"));
|
||||
data.setSkillPoints(config.getInt("skill-points"));
|
||||
data.setSkillReallocationPoints(config.getInt("skill-reallocation-points"));
|
||||
data.setSkillTreeReallocationPoints(config.getInt("skill-tree-reallocation-points"));
|
||||
data.setAttributePoints(config.getInt("attribute-points"));
|
||||
data.setAttributeReallocationPoints(config.getInt("attribute-realloc-points"));
|
||||
data.setLevel(config.getInt("level"));
|
||||
data.setExperience(config.getInt("experience"));
|
||||
if (config.contains("class"))
|
||||
data.setClass(MMOCore.plugin.classManager.get(config.getString("class")));
|
||||
if (config.contains("class")) data.setClass(MMOCore.plugin.classManager.get(config.getString("class")));
|
||||
|
||||
if (config.contains("guild")) {
|
||||
Guild guild = provider.getGuildManager().getGuild(config.getString("guild"));
|
||||
Guild guild = MMOCore.plugin.nativeGuildManager.getGuild(config.getString("guild"));
|
||||
data.setGuild(guild.hasMember(data.getUniqueId()) ? guild : null);
|
||||
}
|
||||
if (config.contains("attribute"))
|
||||
@ -67,7 +78,8 @@ public class YAMLPlayerDataManager extends PlayerDataManager {
|
||||
if (config.isConfigurationSection("bound-skills"))
|
||||
for (String key : config.getConfigurationSection("bound-skills").getKeys(false)) {
|
||||
ClassSkill skill = data.getProfess().getSkill(config.getString("bound-skills." + key));
|
||||
data.bindSkill(Integer.parseInt(key), skill);
|
||||
if (skill != null)
|
||||
data.bindSkill(Integer.parseInt(key), skill);
|
||||
}
|
||||
|
||||
for (String key : MMOCore.plugin.skillTreeManager.getAll().
|
||||
@ -124,14 +136,10 @@ public class YAMLPlayerDataManager extends PlayerDataManager {
|
||||
|
||||
if (data.isOnline())
|
||||
data.getPlayer().setHealth(MMOCoreUtils.fixResource(config.getDouble("health"), data.getPlayer().getAttribute(Attribute.GENERIC_MAX_HEALTH).getValue()));
|
||||
|
||||
data.setFullyLoaded();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void saveData(PlayerData data, boolean logout) {
|
||||
ConfigFile file = new ConfigFile(data.getUniqueId());
|
||||
FileConfiguration config = file.getConfig();
|
||||
public void saveInSection(PlayerData data, ConfigurationSection config) {
|
||||
|
||||
config.set("class-points", data.getClassPoints());
|
||||
config.set("skill-points", data.getSkillPoints());
|
||||
@ -149,11 +157,11 @@ public class YAMLPlayerDataManager extends PlayerDataManager {
|
||||
data.mapSkillTreePoints().forEach((key1, value) -> config.set("skill-tree-points." + key1, value));
|
||||
config.set("skill-tree-reallocation-points", data.getSkillTreeReallocationPoints());
|
||||
config.set("skill", null);
|
||||
config.set("health",data.getHealth());
|
||||
config.set("health", data.getHealth());
|
||||
config.set("mana", data.getMana());
|
||||
config.set("stellium", data.getStellium());
|
||||
config.set("stamina", data.getStamina());
|
||||
//Saves the nodes levels
|
||||
// Saves the nodes levels
|
||||
MMOCore.plugin.skillTreeManager.getAllNodes().forEach(node -> config.set("skill-tree-level." + node.getFullId(), data.getNodeLevel(node)));
|
||||
data.mapSkillLevels().forEach((key1, value) -> config.set("skill." + key1, value));
|
||||
data.getItemClaims().forEach((key, times) -> config.set("times-claimed." + key, times));
|
||||
@ -194,14 +202,12 @@ public class YAMLPlayerDataManager extends PlayerDataManager {
|
||||
info.mapBoundSkills().forEach((slot, skill) -> config.set("class-info." + key + ".bound-skills." + slot, skill));
|
||||
config.set("class-info." + key + ".unlocked-items", new ArrayList<>(info.getUnlockedItems()));
|
||||
}
|
||||
|
||||
file.save();
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public OfflinePlayerData getOffline(UUID uuid) {
|
||||
return isLoaded(uuid) ? get(uuid) : new YAMLOfflinePlayerData(uuid);
|
||||
return new YAMLOfflinePlayerData(uuid);
|
||||
}
|
||||
}
|
||||
|
@ -1,6 +1,7 @@
|
||||
package net.Indyuce.mmocore.player;
|
||||
|
||||
import net.Indyuce.mmocore.api.player.PlayerData;
|
||||
import net.Indyuce.mmocore.manager.data.PlayerDataManager;
|
||||
import net.Indyuce.mmocore.skilltree.SkillTreeNode;
|
||||
import org.bukkit.attribute.Attribute;
|
||||
import org.bukkit.configuration.ConfigurationSection;
|
||||
@ -136,13 +137,15 @@ public class DefaultPlayerData implements ClassDataContainer {
|
||||
|
||||
public void apply(PlayerData player) {
|
||||
player.setLevel(level);
|
||||
player.setExperience(0);
|
||||
player.setClassPoints(classPoints);
|
||||
player.setSkillPoints(skillPoints);
|
||||
player.setAttributePoints(attributePoints);
|
||||
player.setAttributeReallocationPoints(attrReallocPoints);
|
||||
player.setSkillTreeReallocationPoints(skillTreeReallocPoints);
|
||||
player.setSkillReallocationPoints(skillReallocPoints);
|
||||
player.getPlayer().setHealth(Math.min(health, player.getPlayer().getAttribute(Attribute.GENERIC_MAX_HEALTH).getValue()));
|
||||
if (player.isOnline())
|
||||
player.getPlayer().setHealth(Math.min(health, player.getPlayer().getAttribute(Attribute.GENERIC_MAX_HEALTH).getValue()));
|
||||
player.setMana(mana);
|
||||
player.setStamina(stamina);
|
||||
player.setStellium(stellium);
|
||||
|
@ -6,7 +6,6 @@ import net.Indyuce.mmocore.api.quest.trigger.SkillModifierTrigger;
|
||||
import net.Indyuce.mmocore.api.util.Closable;
|
||||
import net.Indyuce.mmocore.skill.ClassSkill;
|
||||
import org.apache.commons.lang.Validate;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
@ -65,9 +64,7 @@ public class BoundSkillInfo implements Closable {
|
||||
open = false;
|
||||
|
||||
// Unregister skill if passive
|
||||
if (isPassive()) {
|
||||
registered.unregister(playerData.getMMOPlayerData());
|
||||
}
|
||||
if (isPassive()) registered.unregister(playerData.getMMOPlayerData());
|
||||
|
||||
// Remove skill buffs associated to the slot
|
||||
skillSlot.getSkillBuffTriggers().forEach(skillBuffTrigger -> skillBuffTrigger.remove(playerData, classSkill.getSkill().getHandler()));
|
||||
|
@ -8,13 +8,13 @@ import org.bukkit.event.HandlerList;
|
||||
import org.bukkit.event.Listener;
|
||||
import org.bukkit.scheduler.BukkitRunnable;
|
||||
|
||||
public abstract class SkillCastingHandler extends BukkitRunnable implements Listener {
|
||||
public abstract class SkillCastingInstance extends BukkitRunnable implements Listener {
|
||||
private final PlayerData caster;
|
||||
|
||||
private boolean open = true;
|
||||
private int j;
|
||||
|
||||
public SkillCastingHandler(PlayerData caster, int runnablePeriod) {
|
||||
public SkillCastingInstance(PlayerData caster, int runnablePeriod) {
|
||||
this.caster = caster;
|
||||
|
||||
runTaskTimer(MMOCore.plugin, 0, runnablePeriod);
|
@ -0,0 +1,18 @@
|
||||
package net.Indyuce.mmocore.skill.cast;
|
||||
|
||||
|
||||
import net.Indyuce.mmocore.api.player.PlayerData;
|
||||
import org.bukkit.event.Listener;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
/**
|
||||
* @apiNote Purely for API
|
||||
*/
|
||||
public interface SkillCastingListener extends Listener {
|
||||
|
||||
@NotNull
|
||||
public SkillCastingMode getCastingMode();
|
||||
|
||||
@NotNull
|
||||
public SkillCastingInstance newInstance(@NotNull PlayerData player);
|
||||
}
|
@ -1,11 +1,16 @@
|
||||
package net.Indyuce.mmocore.skill.cast;
|
||||
|
||||
import net.Indyuce.mmocore.MMOCore;
|
||||
import net.Indyuce.mmocore.skill.cast.listener.SkillBar;
|
||||
import net.Indyuce.mmocore.skill.cast.listener.KeyCombos;
|
||||
import net.Indyuce.mmocore.skill.cast.listener.SkillCastingDisabled;
|
||||
import net.Indyuce.mmocore.skill.cast.listener.SkillScroller;
|
||||
import org.apache.commons.lang.Validate;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.configuration.ConfigurationSection;
|
||||
import org.bukkit.event.Listener;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.Objects;
|
||||
import java.util.function.Function;
|
||||
|
||||
public enum SkillCastingMode {
|
||||
@ -23,7 +28,7 @@ public enum SkillCastingMode {
|
||||
* to navigate through the entire castable skill list. Then press
|
||||
* one key to cast the one selected.
|
||||
*/
|
||||
SKILL_SCROLL(config -> new SkillScroller(config)),
|
||||
SKILL_SCROLLER(config -> new SkillScroller(config)),
|
||||
|
||||
/**
|
||||
* Initialize your skill combo by pressing some key.
|
||||
@ -37,8 +42,7 @@ public enum SkillCastingMode {
|
||||
/**
|
||||
* Entirely disables skill casting.
|
||||
*/
|
||||
NONE(config -> new Listener() {
|
||||
});
|
||||
NONE(config -> new SkillCastingDisabled());
|
||||
|
||||
/**
|
||||
* Not implemented yet.
|
||||
@ -59,13 +63,25 @@ public enum SkillCastingMode {
|
||||
|
||||
;
|
||||
|
||||
private final Function<ConfigurationSection, Listener> listenerLoader;
|
||||
private final Function<ConfigurationSection, SkillCastingListener> listenerLoader;
|
||||
|
||||
SkillCastingMode(Function<ConfigurationSection, Listener> listenerLoader) {
|
||||
private static SkillCastingListener current;
|
||||
|
||||
SkillCastingMode(Function<ConfigurationSection, SkillCastingListener> listenerLoader) {
|
||||
this.listenerLoader = listenerLoader;
|
||||
}
|
||||
|
||||
public Listener loadFromConfig(ConfigurationSection config) {
|
||||
return listenerLoader.apply(config);
|
||||
public void setCurrent(@NotNull ConfigurationSection config) {
|
||||
Validate.isTrue(current == null, "Skill casting mode already initialized");
|
||||
current = listenerLoader.apply(config);
|
||||
if (this == NONE) return;
|
||||
|
||||
// Register listener
|
||||
Bukkit.getPluginManager().registerEvents(current, MMOCore.plugin);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static SkillCastingListener getCurrent() {
|
||||
return Objects.requireNonNull(current, "Skill casting mode hasn't been initialized yet");
|
||||
}
|
||||
}
|
||||
|
@ -11,10 +11,7 @@ import net.Indyuce.mmocore.api.SoundObject;
|
||||
import net.Indyuce.mmocore.api.event.PlayerKeyPressEvent;
|
||||
import net.Indyuce.mmocore.api.player.PlayerData;
|
||||
import net.Indyuce.mmocore.gui.api.item.Placeholders;
|
||||
import net.Indyuce.mmocore.skill.cast.ComboMap;
|
||||
import net.Indyuce.mmocore.skill.cast.KeyCombo;
|
||||
import net.Indyuce.mmocore.skill.cast.PlayerKey;
|
||||
import net.Indyuce.mmocore.skill.cast.SkillCastingHandler;
|
||||
import net.Indyuce.mmocore.skill.cast.*;
|
||||
import org.bukkit.configuration.ConfigurationSection;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.EventHandler;
|
||||
@ -24,7 +21,7 @@ import org.jetbrains.annotations.NotNull;
|
||||
import javax.annotation.Nullable;
|
||||
import java.util.*;
|
||||
|
||||
public class KeyCombos implements Listener {
|
||||
public class KeyCombos implements SkillCastingListener {
|
||||
|
||||
private final ComboMap comboMap;
|
||||
|
||||
@ -56,8 +53,17 @@ public class KeyCombos implements Listener {
|
||||
failComboSound = config.contains("sound.fail-combo") ? new SoundObject(config.getConfigurationSection("sound.fail-combo")) : null;
|
||||
|
||||
// Find initializer key
|
||||
initializerKey = config.contains("initializer-key") ? PlayerKey.valueOf(UtilityMethods.enumName(Objects.requireNonNull(
|
||||
config.getString("initializer-key"), "Could not find initializer key"))) : null;
|
||||
initializerKey = config.contains("initializer-key") ? PlayerKey.valueOf(UtilityMethods.enumName(Objects.requireNonNull(config.getString("initializer-key"), "Could not find initializer key"))) : null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public SkillCastingInstance newInstance(@NotNull PlayerData player) {
|
||||
return new CustomSkillCastingInstance(player);
|
||||
}
|
||||
|
||||
@Override
|
||||
public SkillCastingMode getCastingMode() {
|
||||
return SkillCastingMode.KEY_COMBOS;
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
@ -70,46 +76,39 @@ public class KeyCombos implements Listener {
|
||||
if (event.getPressed() == initializerKey) {
|
||||
|
||||
// Cancel event if necessary
|
||||
if (event.getPressed().shouldCancelEvent())
|
||||
event.setCancelled(true);
|
||||
if (event.getPressed().shouldCancelEvent()) event.setCancelled(true);
|
||||
|
||||
// Start combo
|
||||
playerData.setSkillCasting(new CustomSkillCastingHandler(playerData));
|
||||
if (beginComboSound != null)
|
||||
beginComboSound.playTo(player);
|
||||
playerData.setSkillCasting(new CustomSkillCastingInstance(playerData));
|
||||
if (beginComboSound != null) beginComboSound.playTo(player);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
@Nullable CustomSkillCastingHandler casting = null;
|
||||
@Nullable CustomSkillCastingInstance casting = null;
|
||||
|
||||
// Player is already casting
|
||||
if (event.getData().isCasting())
|
||||
casting = (CustomSkillCastingHandler) playerData.getSkillCasting();
|
||||
if (event.getData().isCasting()) casting = (CustomSkillCastingInstance) playerData.getSkillCasting();
|
||||
|
||||
// Start combo when there is NO initializer key
|
||||
else {
|
||||
final @NotNull ComboMap comboMap = Objects.requireNonNullElse(playerData.getProfess().getComboMap(), this.comboMap);
|
||||
if (comboMap.isComboStart(event.getPressed())) {
|
||||
casting = new CustomSkillCastingHandler(playerData);
|
||||
casting = new CustomSkillCastingInstance(playerData);
|
||||
playerData.setSkillCasting(casting);
|
||||
if (beginComboSound != null)
|
||||
beginComboSound.playTo(player);
|
||||
if (beginComboSound != null) beginComboSound.playTo(player);
|
||||
}
|
||||
}
|
||||
|
||||
if (casting == null)
|
||||
return;
|
||||
if (casting == null) return;
|
||||
|
||||
// Adding pressed key
|
||||
casting.current.registerKey(event.getPressed());
|
||||
casting.onTick();
|
||||
if (comboClickSound != null)
|
||||
comboClickSound.playTo(player);
|
||||
if (comboClickSound != null) comboClickSound.playTo(player);
|
||||
|
||||
// Cancel event if necessary
|
||||
if (event.getPressed().shouldCancelEvent())
|
||||
event.setCancelled(true);
|
||||
if (event.getPressed().shouldCancelEvent()) event.setCancelled(true);
|
||||
|
||||
// Hash current combo and check
|
||||
if (casting.combos.getCombos().containsKey(casting.current)) {
|
||||
@ -127,8 +126,7 @@ public class KeyCombos implements Listener {
|
||||
// Check if current combo is too large
|
||||
if (casting.current.countKeys() >= casting.combos.getLongest()) {
|
||||
playerData.leaveSkillCasting();
|
||||
if (failComboSound != null)
|
||||
failComboSound.playTo(player);
|
||||
if (failComboSound != null) failComboSound.playTo(player);
|
||||
}
|
||||
}
|
||||
|
||||
@ -157,13 +155,14 @@ public class KeyCombos implements Listener {
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads the player current combos & the combos applicable to the player (combos defined in its class or the default combos of the config.yml)
|
||||
* Loads the player current combos & the combos applicable to the player
|
||||
* (combos defined in its class or the default combos of the config.yml)
|
||||
*/
|
||||
private class CustomSkillCastingHandler extends SkillCastingHandler {
|
||||
public class CustomSkillCastingInstance extends SkillCastingInstance {
|
||||
private final KeyCombo current = new KeyCombo();
|
||||
private final ComboMap combos;
|
||||
|
||||
CustomSkillCastingHandler(PlayerData caster) {
|
||||
CustomSkillCastingInstance(PlayerData caster) {
|
||||
super(caster, 10);
|
||||
|
||||
combos = Objects.requireNonNullElse(caster.getProfess().getComboMap(), comboMap);
|
||||
@ -171,11 +170,9 @@ public class KeyCombos implements Listener {
|
||||
|
||||
@Override
|
||||
public void onTick() {
|
||||
if (actionBarOptions != null)
|
||||
if (actionBarOptions.isSubtitle)
|
||||
getCaster().getPlayer().sendTitle(" ", actionBarOptions.format(this), 0, 20, 0);
|
||||
else
|
||||
getCaster().displayActionBar(actionBarOptions.format(this));
|
||||
if (actionBarOptions != null) if (actionBarOptions.isSubtitle)
|
||||
getCaster().getPlayer().sendTitle(" ", actionBarOptions.format(this), 0, 20, 0);
|
||||
else getCaster().displayActionBar(actionBarOptions.format(this));
|
||||
}
|
||||
}
|
||||
|
||||
@ -199,7 +196,7 @@ public class KeyCombos implements Listener {
|
||||
keyNames.put(key, Objects.requireNonNull(config.getString("key-name." + key.name()), "Could not find translation for key " + key.name()));
|
||||
}
|
||||
|
||||
public String format(CustomSkillCastingHandler casting) {
|
||||
public String format(CustomSkillCastingInstance casting) {
|
||||
StringBuilder builder = new StringBuilder();
|
||||
Placeholders holders = MMOCore.plugin.actionBarManager.getActionBarPlaceholders(casting.getCaster());
|
||||
|
||||
|
@ -10,8 +10,9 @@ import net.Indyuce.mmocore.api.event.PlayerKeyPressEvent;
|
||||
import net.Indyuce.mmocore.api.player.PlayerData;
|
||||
import net.Indyuce.mmocore.skill.ClassSkill;
|
||||
import net.Indyuce.mmocore.skill.cast.PlayerKey;
|
||||
import net.Indyuce.mmocore.skill.cast.SkillCastingHandler;
|
||||
import org.bukkit.Bukkit;
|
||||
import net.Indyuce.mmocore.skill.cast.SkillCastingInstance;
|
||||
import net.Indyuce.mmocore.skill.cast.SkillCastingListener;
|
||||
import net.Indyuce.mmocore.skill.cast.SkillCastingMode;
|
||||
import org.bukkit.GameMode;
|
||||
import org.bukkit.configuration.ConfigurationSection;
|
||||
import org.bukkit.entity.Player;
|
||||
@ -19,10 +20,11 @@ import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.Listener;
|
||||
import org.bukkit.event.player.PlayerItemHeldEvent;
|
||||
import org.bukkit.scheduler.BukkitRunnable;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
public class SkillBar implements Listener {
|
||||
public class SkillBar implements SkillCastingListener {
|
||||
private final PlayerKey mainKey;
|
||||
private final boolean disableSneak;
|
||||
|
||||
@ -31,6 +33,16 @@ public class SkillBar implements Listener {
|
||||
disableSneak = config.getBoolean("disable-sneak");
|
||||
}
|
||||
|
||||
@Override
|
||||
public SkillCastingInstance newInstance(@NotNull PlayerData player) {
|
||||
return new CustomSkillCastingInstance(player);
|
||||
}
|
||||
|
||||
@Override
|
||||
public SkillCastingMode getCastingMode() {
|
||||
return SkillCastingMode.SKILL_BAR;
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void enterSkillCasting(PlayerKeyPressEvent event) {
|
||||
if (event.getPressed() != mainKey) return;
|
||||
@ -44,14 +56,13 @@ public class SkillBar implements Listener {
|
||||
|
||||
// Enter spell casting
|
||||
final PlayerData playerData = event.getData();
|
||||
if (player.getGameMode() != GameMode.SPECTATOR && (MMOCore.plugin.configManager.canCreativeCast || player.getGameMode() != GameMode.CREATIVE) && !playerData.isCasting() && !playerData.getBoundSkills()
|
||||
.isEmpty()) {
|
||||
playerData.setSkillCasting(new CustomSkillCastingHandler(playerData));
|
||||
if (player.getGameMode() != GameMode.SPECTATOR && (MMOCore.plugin.configManager.canCreativeCast || player.getGameMode() != GameMode.CREATIVE) && !playerData.isCasting() && !playerData.getBoundSkills().isEmpty()) {
|
||||
playerData.setSkillCasting(new CustomSkillCastingInstance(playerData));
|
||||
MMOCore.plugin.soundManager.getSound(SoundEvent.SPELL_CAST_BEGIN).playTo(player);
|
||||
}
|
||||
}
|
||||
|
||||
private class CustomSkillCastingHandler extends SkillCastingHandler {
|
||||
public class CustomSkillCastingInstance extends SkillCastingInstance {
|
||||
private final String ready = MMOCore.plugin.configManager.getSimpleMessage("casting.action-bar.ready").message();
|
||||
private final String onCooldown = MMOCore.plugin.configManager.getSimpleMessage("casting.action-bar.on-cooldown").message();
|
||||
private final String noMana = MMOCore.plugin.configManager.getSimpleMessage("casting.action-bar.no-mana").message();
|
||||
@ -60,7 +71,7 @@ public class SkillBar implements Listener {
|
||||
|
||||
private int j;
|
||||
|
||||
CustomSkillCastingHandler(PlayerData playerData) {
|
||||
CustomSkillCastingInstance(PlayerData playerData) {
|
||||
super(playerData, 1);
|
||||
}
|
||||
|
||||
@ -115,16 +126,17 @@ public class SkillBar implements Listener {
|
||||
}
|
||||
|
||||
private String getFormat(PlayerData data) {
|
||||
StringBuilder str = new StringBuilder();
|
||||
final StringBuilder str = new StringBuilder();
|
||||
if (!data.isOnline()) return str.toString();
|
||||
for (int slot : data.mapBoundSkills().keySet()) {
|
||||
ClassSkill skill = data.getBoundSkill(slot);
|
||||
if (!skill.getSkill().getTrigger().isPassive())
|
||||
str.append(str.isEmpty() ? "" : split).append((onCooldown(data, skill) ? onCooldown.replace("{cooldown}",
|
||||
String.valueOf(data.getCooldownMap().getInfo(skill).getRemaining() / 1000)) : noMana(data, skill) ? noMana : (noStamina(
|
||||
data, skill) ? noStamina : ready)).replace("{index}",
|
||||
String.valueOf(slot + (data.getPlayer().getInventory().getHeldItemSlot() < slot ? 1 : 0)))
|
||||
.replace("{skill}", data.getBoundSkill(slot).getSkill().getName()));
|
||||
final ClassSkill skill = data.getBoundSkill(slot);
|
||||
if (skill.getSkill().getTrigger().isPassive()) continue;
|
||||
|
||||
str.append(str.isEmpty() ? "" : split).append((onCooldown(data, skill) ? onCooldown.replace("{cooldown}",
|
||||
String.valueOf(data.getCooldownMap().getInfo(skill).getRemaining() / 1000)) : noMana(data, skill) ? noMana : (noStamina(
|
||||
data, skill) ? noStamina : ready)).replace("{index}",
|
||||
String.valueOf(slot + (data.getPlayer().getInventory().getHeldItemSlot() < slot ? 1 : 0)))
|
||||
.replace("{skill}", data.getBoundSkill(slot).getSkill().getName()));
|
||||
}
|
||||
return MMOCore.plugin.placeholderParser.parse(data.getPlayer(), str.toString());
|
||||
}
|
||||
@ -143,8 +155,7 @@ public class SkillBar implements Listener {
|
||||
}
|
||||
|
||||
private boolean noStamina(PlayerData data, ClassSkill skill) {
|
||||
return skill.getSkill().hasModifier("stamina") && skill.getModifier("stamina",
|
||||
data.getSkillLevel(skill.getSkill())) > data.getStamina();
|
||||
return skill.getSkill().hasModifier("stamina") && skill.getModifier("stamina", data.getSkillLevel(skill.getSkill())) > data.getStamina();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -0,0 +1,20 @@
|
||||
package net.Indyuce.mmocore.skill.cast.listener;
|
||||
|
||||
import net.Indyuce.mmocore.api.player.PlayerData;
|
||||
import net.Indyuce.mmocore.skill.cast.SkillCastingInstance;
|
||||
import net.Indyuce.mmocore.skill.cast.SkillCastingListener;
|
||||
import net.Indyuce.mmocore.skill.cast.SkillCastingMode;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
public class SkillCastingDisabled implements SkillCastingListener {
|
||||
|
||||
@Override
|
||||
public SkillCastingInstance newInstance(@NotNull PlayerData player) {
|
||||
throw new RuntimeException("Skill casting is disabled");
|
||||
}
|
||||
|
||||
@Override
|
||||
public SkillCastingMode getCastingMode() {
|
||||
return SkillCastingMode.NONE;
|
||||
}
|
||||
}
|
@ -8,17 +8,19 @@ import net.Indyuce.mmocore.api.SoundObject;
|
||||
import net.Indyuce.mmocore.api.event.PlayerKeyPressEvent;
|
||||
import net.Indyuce.mmocore.api.player.PlayerData;
|
||||
import net.Indyuce.mmocore.skill.cast.PlayerKey;
|
||||
import net.Indyuce.mmocore.skill.cast.SkillCastingHandler;
|
||||
import net.Indyuce.mmocore.skill.cast.SkillCastingInstance;
|
||||
import net.Indyuce.mmocore.skill.cast.SkillCastingListener;
|
||||
import net.Indyuce.mmocore.skill.cast.SkillCastingMode;
|
||||
import org.bukkit.configuration.ConfigurationSection;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.Listener;
|
||||
import org.bukkit.event.player.PlayerItemHeldEvent;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import java.util.Objects;
|
||||
|
||||
public class SkillScroller implements Listener {
|
||||
public class SkillScroller implements SkillCastingListener {
|
||||
|
||||
/**
|
||||
* Key players need to press to start casting
|
||||
@ -40,6 +42,16 @@ public class SkillScroller implements Listener {
|
||||
castKey = PlayerKey.valueOf(UtilityMethods.enumName(Objects.requireNonNull(config.getString("cast-key"), "Could not find cast key")));
|
||||
}
|
||||
|
||||
@Override
|
||||
public SkillCastingInstance newInstance(@NotNull PlayerData player) {
|
||||
return new CustomSkillCastingInstance(player);
|
||||
}
|
||||
|
||||
@Override
|
||||
public SkillCastingMode getCastingMode() {
|
||||
return SkillCastingMode.SKILL_SCROLLER;
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void whenPressingKey(PlayerKeyPressEvent event) {
|
||||
PlayerData playerData = event.getData();
|
||||
@ -51,36 +63,30 @@ public class SkillScroller implements Listener {
|
||||
if (playerData.isCasting()) {
|
||||
|
||||
// Cancel event if necessary
|
||||
if (event.getPressed().shouldCancelEvent())
|
||||
event.setCancelled(true);
|
||||
if (event.getPressed().shouldCancelEvent()) event.setCancelled(true);
|
||||
|
||||
playerData.leaveSkillCasting();
|
||||
if (leaveSound != null)
|
||||
leaveSound.playTo(player);
|
||||
if (leaveSound != null) leaveSound.playTo(player);
|
||||
return;
|
||||
}
|
||||
|
||||
// Check if there are skills bound
|
||||
if (playerData.getBoundSkills().isEmpty())
|
||||
return;
|
||||
if (playerData.getBoundSkills().isEmpty()) return;
|
||||
|
||||
// Cancel event if necessary
|
||||
if (event.getPressed().shouldCancelEvent())
|
||||
event.setCancelled(true);
|
||||
if (event.getPressed().shouldCancelEvent()) event.setCancelled(true);
|
||||
|
||||
// Enter casting mode
|
||||
playerData.setSkillCasting(new CustomSkillCastingHandler(playerData));
|
||||
if (enterSound != null)
|
||||
enterSound.playTo(player);
|
||||
playerData.setSkillCasting(new CustomSkillCastingInstance(playerData));
|
||||
if (enterSound != null) enterSound.playTo(player);
|
||||
}
|
||||
|
||||
if (event.getPressed() == castKey && playerData.isCasting()) {
|
||||
|
||||
// Cancel event if necessary
|
||||
if (event.getPressed().shouldCancelEvent())
|
||||
event.setCancelled(true);
|
||||
if (event.getPressed().shouldCancelEvent()) event.setCancelled(true);
|
||||
|
||||
CustomSkillCastingHandler casting = (CustomSkillCastingHandler) playerData.getSkillCasting();
|
||||
CustomSkillCastingInstance casting = (CustomSkillCastingInstance) playerData.getSkillCasting();
|
||||
PlayerMetadata caster = playerData.getMMOPlayerData().getStatMap().cache(EquipmentSlot.MAIN_HAND);
|
||||
playerData.getBoundSkill(casting.index).toCastable(playerData).cast(new TriggerMetadata(caster, null, null));
|
||||
}
|
||||
@ -89,8 +95,7 @@ public class SkillScroller implements Listener {
|
||||
@EventHandler
|
||||
public void onScroll(PlayerItemHeldEvent event) {
|
||||
PlayerData playerData = PlayerData.get(event.getPlayer());
|
||||
if (!playerData.isCasting())
|
||||
return;
|
||||
if (!playerData.isCasting()) return;
|
||||
|
||||
if (playerData.getBoundSkills().isEmpty()) {
|
||||
playerData.leaveSkillCasting();
|
||||
@ -104,29 +109,26 @@ public class SkillScroller implements Listener {
|
||||
int change = Math.abs(dist1) < Math.abs(dist2) ? (Math.abs(dist1) < Math.abs(dist3) ? dist1 : dist3) : (Math.abs(dist3) < Math.abs(dist2) ? dist3 : dist2);
|
||||
|
||||
// Scroll trough items
|
||||
CustomSkillCastingHandler casting = (CustomSkillCastingHandler) playerData.getSkillCasting();
|
||||
CustomSkillCastingInstance casting = (CustomSkillCastingInstance) playerData.getSkillCasting();
|
||||
casting.index = mod(casting.index + change, playerData.getBoundSkills().size());
|
||||
casting.onTick();
|
||||
|
||||
if (changeSound != null)
|
||||
changeSound.playTo(event.getPlayer());
|
||||
if (changeSound != null) changeSound.playTo(event.getPlayer());
|
||||
}
|
||||
|
||||
private int mod(int x, int n) {
|
||||
|
||||
while (x < 0)
|
||||
x += n;
|
||||
while (x < 0) x += n;
|
||||
|
||||
while (x >= n)
|
||||
x -= n;
|
||||
while (x >= n) x -= n;
|
||||
|
||||
return x;
|
||||
}
|
||||
|
||||
private class CustomSkillCastingHandler extends SkillCastingHandler {
|
||||
public class CustomSkillCastingInstance extends SkillCastingInstance {
|
||||
private int index = 0;
|
||||
|
||||
CustomSkillCastingHandler(PlayerData caster) {
|
||||
CustomSkillCastingInstance(PlayerData caster) {
|
||||
super(caster, 10);
|
||||
}
|
||||
|
||||
|
@ -1,5 +1,7 @@
|
||||
package net.Indyuce.mmocore;
|
||||
|
||||
import io.lumine.mythic.lib.MythicLib;
|
||||
import net.Indyuce.mmocore.comp.profile.ForceClassProfileDataModule;
|
||||
import net.Indyuce.mmocore.listener.*;
|
||||
import net.Indyuce.mmocore.listener.event.PlayerPressKeyListener;
|
||||
import net.Indyuce.mmocore.listener.option.*;
|
||||
@ -31,6 +33,9 @@ public class MMOCoreBukkit {
|
||||
if (plugin.getConfig().getBoolean("vanilla-exp-redirection.enabled"))
|
||||
Bukkit.getPluginManager().registerEvents(new RedirectVanillaExp(plugin.getConfig().getDouble("vanilla-exp-redirection.ratio")), plugin);
|
||||
|
||||
if (plugin.getConfig().getBoolean("force-class-selection") && MythicLib.plugin.hasProfiles())
|
||||
new ForceClassProfileDataModule();
|
||||
|
||||
Bukkit.getPluginManager().registerEvents(new WaypointsListener(), plugin);
|
||||
Bukkit.getPluginManager().registerEvents(new PlayerListener(), plugin);
|
||||
Bukkit.getPluginManager().registerEvents(new GoldPouchesListener(), plugin);
|
||||
|
@ -18,22 +18,9 @@ import org.bukkit.event.entity.EntityRegainHealthEvent;
|
||||
import org.bukkit.event.entity.EntityRegainHealthEvent.RegainReason;
|
||||
import org.bukkit.event.inventory.InventoryClickEvent;
|
||||
import org.bukkit.event.inventory.InventoryCloseEvent;
|
||||
import org.bukkit.event.player.PlayerJoinEvent;
|
||||
import org.bukkit.event.player.PlayerQuitEvent;
|
||||
|
||||
public class PlayerListener implements Listener {
|
||||
|
||||
/**
|
||||
* Load player data. Event priority is set to LOW as most plugins
|
||||
* do not change their priority which is NORMAL by default. Making
|
||||
* it low is important because MMOCore is a core plugin so other plugins
|
||||
* might rely on its data on startup.
|
||||
*/
|
||||
@EventHandler(priority = EventPriority.LOW)
|
||||
public void loadPlayerData(PlayerJoinEvent event) {
|
||||
MMOCore.plugin.dataProvider.getDataManager().setup(event.getPlayer().getUniqueId());
|
||||
}
|
||||
|
||||
/**
|
||||
* Register custom inventory clicks
|
||||
*/
|
||||
@ -70,16 +57,6 @@ public class PlayerListener implements Listener {
|
||||
PlayerData.get(event.getEntity().getUniqueId()).getCombat().update();
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void saveDataOnQuit(PlayerQuitEvent event) {
|
||||
PlayerData playerData = PlayerData.get(event.getPlayer());
|
||||
/**
|
||||
* We save player health as it won't be accessible anymore when saving the player data (player will be offline).
|
||||
*/
|
||||
playerData.setHealth(event.getPlayer().getHealth());
|
||||
MMOCore.plugin.dataProvider.getDataManager().unregisterSafe(playerData);
|
||||
}
|
||||
|
||||
/**
|
||||
* Using the Bukkit health update event is not a good way of
|
||||
* interacting with MMOCore health regeneration. The
|
||||
|
@ -7,6 +7,7 @@ config-version: 9
|
||||
auto-save:
|
||||
enabled: true
|
||||
interval: 1800 # In seconds (1800 = 30 minutes)
|
||||
log: true
|
||||
|
||||
# MySQL Support
|
||||
mysql:
|
||||
@ -192,7 +193,15 @@ vanilla-exp-redirection:
|
||||
# Requires a SERVER reload when changed.
|
||||
override-vanilla-exp: true
|
||||
|
||||
# Check the target player's RPG profile when shift when shift right clicking.
|
||||
# When enabled and when using a profile plugin, MMOCore will
|
||||
# force the user to choose a class. The profile will not be
|
||||
# created until they choose a class. Similarly, a player cannot
|
||||
# log into a profile with default class before choosing another class
|
||||
#
|
||||
# This option is useless unless you have installed a profile plugin.
|
||||
force-class-selection: true
|
||||
|
||||
# Check the target player's RPG profile on shift-right click.
|
||||
shift-click-player-profile-check: false
|
||||
|
||||
# If main class experience holograms should be displayed
|
||||
@ -211,7 +220,8 @@ max-skill-slots: 8
|
||||
|
||||
# When set to true, passive skills must be bound in order to take effect.
|
||||
# When set to false, unlocked skills will take effect right away.
|
||||
passive-skill-need-bound: true
|
||||
# Disabled for now.
|
||||
# passive-skill-need-bound: true
|
||||
|
||||
# Set this to true to allow players in
|
||||
# creative mode to enter casting mode
|
||||
|
@ -9,8 +9,6 @@ warp-teleport: ENTITY_ENDERMAN_TELEPORT,1,0.5
|
||||
warp-charge: BLOCK_NOTE_BLOCK_BELL #Uses a special pitch method, so pitch and volume is not changeable
|
||||
warp-unlock: UI_TOAST_CHALLENGE_COMPLETE,1,1.2
|
||||
|
||||
hotbar-swap: ITEM_ARMOR_EQUIP_LEATHER
|
||||
|
||||
spell-cast-begin: BLOCK_END_PORTAL_FRAME_FILL,1,2
|
||||
spell-cast-end: BLOCK_FIRE_EXTINGUISH,1,2
|
||||
|
||||
|
@ -5,7 +5,7 @@ author: Indyuce
|
||||
description: ${project.description}
|
||||
loadbefore: [ MMOItems,MythicDungeons ]
|
||||
depend: [ MythicLib ]
|
||||
softdepend: [ Vault,MythicMobs,PlaceholderAPI,Residence,Citizens,ProtocolLib,OBTeam ]
|
||||
softdepend: [ Vault,MythicMobs,MMOProfiles,PlaceholderAPI,Residence,Citizens,ProtocolLib,OBTeam ]
|
||||
api-version: 1.13
|
||||
commands:
|
||||
mmocore:
|
||||
|
Loading…
Reference in New Issue
Block a user