Data sync fix

This commit is contained in:
Jules 2023-01-22 23:07:41 +01:00
parent 30bf4b0e99
commit 47f7517d48
7 changed files with 220 additions and 278 deletions

View File

@ -278,12 +278,13 @@ public class MMOCore extends JavaPlugin {
@Override @Override
public void onDisable() { public void onDisable() {
//Executes all the pending asynchronous task (like saving the playerData) // Executes all the pending asynchronous task (like saving the playerData)
Bukkit.getScheduler().getPendingTasks().forEach(worker -> { Bukkit.getScheduler().getPendingTasks().forEach(worker -> {
if (worker.getOwner().equals(this)) { if (worker.getOwner().equals(this)) {
((Runnable) worker).run(); ((Runnable) worker).run();
} }
}); });
// Save player data // Save player data
for (PlayerData data : PlayerData.getAll()) for (PlayerData data : PlayerData.getAll())
if (data.isFullyLoaded()) { if (data.isFullyLoaded()) {
@ -369,9 +370,4 @@ public class MMOCore extends JavaPlugin {
public boolean hasEconomy() { public boolean hasEconomy() {
return economy != null && economy.isValid(); return economy != null && economy.isValid();
} }
public static void sqlDebug(String s) {
if (!MMOCore.plugin.configManager.sqlDebug) return;
MMOCore.plugin.getLogger().warning("- [SQL Debug] " + s);
}
} }

View File

@ -27,7 +27,7 @@ import java.util.logging.Level;
public class ConfigManager { public class ConfigManager {
public final CommandVerbose commandVerbose = new CommandVerbose(); public final CommandVerbose commandVerbose = new CommandVerbose();
public boolean overrideVanillaExp, canCreativeCast, passiveSkillNeedBound, cobbleGeneratorXP, saveDefaultClassInfo, attributesAsClassInfo, splitProfessionExp, disableQuestBossBar, pvpModeEnabled, sqlDebug; public boolean overrideVanillaExp, canCreativeCast, passiveSkillNeedBound, cobbleGeneratorXP, saveDefaultClassInfo, attributesAsClassInfo, splitProfessionExp, disableQuestBossBar, pvpModeEnabled;
public String partyChatPrefix, noSkillBoundPlaceholder; public String partyChatPrefix, noSkillBoundPlaceholder;
public ChatColor staminaFull, staminaHalf, staminaEmpty; public ChatColor staminaFull, staminaHalf, staminaEmpty;
public long combatLogTimer, lootChestExpireTime, lootChestPlayerCooldown, globalSkillCooldown; public long combatLogTimer, lootChestExpireTime, lootChestPlayerCooldown, globalSkillCooldown;
@ -37,9 +37,8 @@ public class ConfigManager {
private final FileConfiguration messages; private final FileConfiguration messages;
/* /*
* the instance must be created after the other managers since all it does * The instance must be created after the other managers since all it does
* is to update them based on the config except for the classes which are * is to update them based on the config except for the classes which are
* already loaded based on the config * already loaded based on the config
*/ */
@ -131,7 +130,6 @@ public class ConfigManager {
partyMaxExpSplitRange = MMOCore.plugin.getConfig().getDouble("party.max-exp-split-range"); partyMaxExpSplitRange = MMOCore.plugin.getConfig().getDouble("party.max-exp-split-range");
splitProfessionExp = MMOCore.plugin.getConfig().getBoolean("party.profession-exp-split"); splitProfessionExp = MMOCore.plugin.getConfig().getBoolean("party.profession-exp-split");
disableQuestBossBar = MMOCore.plugin.getConfig().getBoolean("mmocore-quests.disable-boss-bar"); disableQuestBossBar = MMOCore.plugin.getConfig().getBoolean("mmocore-quests.disable-boss-bar");
sqlDebug = MMOCore.plugin.getConfig().getBoolean("mysql.debug");
// Combat // Combat
pvpModeEnabled = config.getBoolean("pvp_mode.enabled"); pvpModeEnabled = config.getBoolean("pvp_mode.enabled");

View File

@ -0,0 +1,143 @@
package net.Indyuce.mmocore.manager.data.mysql;
import com.google.gson.Gson;
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.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.skill.ClassSkill;
import net.Indyuce.mmocore.skilltree.SkillTreeNode;
import net.Indyuce.mmocore.skilltree.tree.SkillTree;
import org.apache.commons.lang.Validate;
import org.jetbrains.annotations.Nullable;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.Map;
import java.util.UUID;
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 {
// Initialize custom resources
data.setMana(result.getFloat("mana"));
data.setStellium(result.getFloat("stellium"));
data.setStamina(result.getFloat("stamina"));
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();
if (!isEmpty(result.getString("guild"))) {
Guild guild = MMOCore.plugin.dataProvider.getGuildManager().getGuild(result.getString("guild"));
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")))
for (String id : MMOCoreUtils.jsonArrayToList(result.getString("bound_skills")))
if (data.getProfess().hasSkill(id)) {
ClassSkill skill = data.getProfess().getSkill(id);
if (skill.getSkill().getTrigger().isPassive())
data.bindPassiveSkill(-1, skill.toPassive(data));
else
data.getBoundSkills().add(skill);
}
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());
}
}
}
MythicLib.debug("MMOCoreSQL", 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();
MythicLib.debug("MMOCoreSQL", "Loaded DEFAULT data for: '" + data.getUniqueId() + "' as no saved data was found.");
}
}

View File

@ -1,30 +1,21 @@
package net.Indyuce.mmocore.manager.data.mysql; package net.Indyuce.mmocore.manager.data.mysql;
import com.google.gson.Gson;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject; import com.google.gson.JsonObject;
import com.google.gson.JsonParser; import io.lumine.mythic.lib.MythicLib;
import net.Indyuce.mmocore.MMOCore; import net.Indyuce.mmocore.MMOCore;
import net.Indyuce.mmocore.api.player.OfflinePlayerData; import net.Indyuce.mmocore.api.player.OfflinePlayerData;
import net.Indyuce.mmocore.api.player.PlayerData; import net.Indyuce.mmocore.api.player.PlayerData;
import net.Indyuce.mmocore.api.player.profess.PlayerClass; import net.Indyuce.mmocore.api.player.profess.PlayerClass;
import net.Indyuce.mmocore.api.player.profess.SavedClassInformation; import net.Indyuce.mmocore.api.player.profess.SavedClassInformation;
import net.Indyuce.mmocore.api.util.MMOCoreUtils; 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.manager.data.PlayerDataManager;
import net.Indyuce.mmocore.skill.ClassSkill;
import net.Indyuce.mmocore.skilltree.SkillTreeNode;
import net.Indyuce.mmocore.skilltree.tree.SkillTree;
import org.apache.commons.lang.Validate;
import org.bukkit.scheduler.BukkitRunnable;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.sql.SQLException; import java.sql.SQLException;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.Map.Entry;
import java.util.UUID; import java.util.UUID;
import java.util.logging.Level;
import java.util.stream.Collectors; import java.util.stream.Collectors;
public class MySQLPlayerDataManager extends PlayerDataManager { public class MySQLPlayerDataManager extends PlayerDataManager {
@ -34,189 +25,55 @@ public class MySQLPlayerDataManager extends PlayerDataManager {
this.provider = provider; this.provider = provider;
} }
public MySQLDataProvider getProvider() {
return provider;
}
@Override @Override
public void loadData(PlayerData data) { public void loadData(PlayerData data) {
long startTime = System.currentTimeMillis(); new MMOCoreDataSynchronizer(this, data).fetch();
BukkitRunnable runnable = new BukkitRunnable() {
@Override
public void run() {
//To prevent infinite loops
if (System.currentTimeMillis() - startTime > 6000) {
cancel();
return;
}
provider.getResult("SELECT * FROM mmocore_playerdata WHERE uuid = '" + data.getUniqueId() + "';", (result) -> {
try {
if (result.next()) {
//If the data couldn't be loaded for more than 2 seconds its probably due to a server crash and we load the old data
//If it the status is is_saved we load the data
if (System.currentTimeMillis() - startTime > 4000 || result.getInt("is_saved") == 1) {
MMOCore.sqlDebug("Time waited: " + (System.currentTimeMillis() - startTime));
MMOCore.sqlDebug("Loading data for: '" + data.getUniqueId() + "'...");
// Initialize custom resources
data.setMana(result.getFloat("mana"));
data.setStellium(result.getFloat("stellium"));
data.setStamina(result.getFloat("stamina"));
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();
if (!isEmpty(result.getString("guild"))) {
Guild guild = MMOCore.plugin.dataProvider.getGuildManager().getGuild(result.getString("guild"));
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 (Entry<String, JsonElement> entry : object.entrySet())
data.setSkillLevel(entry.getKey(), entry.getValue().getAsInt());
}
if (!isEmpty(result.getString("bound_skills")))
for (String id : MMOCoreUtils.jsonArrayToList(result.getString("bound_skills")))
if (data.getProfess().hasSkill(id)) {
ClassSkill skill = data.getProfess().getSkill(id);
if (skill.getSkill().getTrigger().isPassive())
data.bindPassiveSkill(-1, skill.toPassive(data));
else
data.getBoundSkills().add(skill);
}
if (!isEmpty(result.getString("class_info"))) {
JsonObject object = new Gson().fromJson(result.getString("class_info"), JsonObject.class);
for (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());
}
}
}
//We now change the saved status to false because the data on SQL won't be the same as in the RAM
new MySQLTableEditor(MySQLTableEditor.Table.PLAYERDATA, data.getUniqueId(), provider).updateData("is_saved", 0);
data.setFullyLoaded();
this.cancel();
MMOCore.sqlDebug("Loaded saved data for: '" + data.getUniqueId() + "'!");
MMOCore.sqlDebug(String.format("{ class: %s, level: %d }", data.getProfess().getId(), data.getLevel()));
return;
} else {
MMOCore.sqlDebug("Failed to load data because is_saved is false.");
}
} else {
data.setLevel(getDefaultData().getLevel());
data.setClassPoints(getDefaultData().getClassPoints());
data.setSkillPoints(getDefaultData().getSkillPoints());
data.setSkillReallocationPoints(getDefaultData().getSkillReallocationPoints());
data.setAttributePoints(getDefaultData().getAttributePoints());
data.setAttributeReallocationPoints(getDefaultData().getAttributeReallocationPoints());
data.setExperience(0);
data.getQuestData().updateBossBar();
//We now change the saved status to false because the data on SQL won't be the same as in the RAM
new MySQLTableEditor(MySQLTableEditor.Table.PLAYERDATA, data.getUniqueId(), provider).updateData("is_saved", 0);
data.setFullyLoaded();
this.cancel();
MMOCore.sqlDebug("Loaded DEFAULT data for: '" + data.getUniqueId() + "' as no saved data was found.");
return;
}
} catch (SQLException e) {
e.printStackTrace();
cancel();
}
});
}
};
runnable.runTaskTimerAsynchronously(MMOCore.plugin, 0L, 20L);
} }
@Override @Override
public void saveData(PlayerData data, boolean logout) { public void saveData(PlayerData data, boolean logout) {
MythicLib.debug("MMOCoreSQL", "Saving data for: '" + data.getUniqueId() + "'...");
MySQLTableEditor sql = new MySQLTableEditor(MySQLTableEditor.Table.PLAYERDATA, data.getUniqueId(), provider); final PlayerDataTableUpdater updater = new PlayerDataTableUpdater(provider, data.getUniqueId());
MMOCore.sqlDebug("Saving data for: '" + data.getUniqueId() + "'..."); updater.addData("class_points", data.getClassPoints());
MySQLRequest request = new MySQLRequest(data.getUniqueId()); updater.addData("skill_points", data.getSkillPoints());
request.addData("class_points", data.getClassPoints()); updater.addData("skill_reallocation_points", data.getSkillReallocationPoints());
request.addData("skill_points", data.getSkillPoints()); updater.addData("attribute_points", data.getAttributePoints());
request.addData("skill_reallocation_points", data.getSkillReallocationPoints()); updater.addData("attribute_realloc_points", data.getAttributeReallocationPoints());
request.addData("attribute_points", data.getAttributePoints()); updater.addJSONArray("waypoints", data.getWaypoints());
request.addData("attribute_realloc_points", data.getAttributeReallocationPoints()); updater.addData("skill_tree_reallocation_points", data.getSkillTreeReallocationPoints());
request.addJSONArray("waypoints", data.getWaypoints()); updater.addData("mana", data.getMana());
request.addData("skill_tree_reallocation_points", data.getSkillTreeReallocationPoints()); updater.addData("stellium", data.getStellium());
request.addData("mana", data.getMana()); updater.addData("stamina", data.getStamina());
request.addData("stellium", data.getStellium()); updater.addData("level", data.getLevel());
request.addData("stamina", data.getStamina()); updater.addData("experience", data.getExperience());
request.addData("level", data.getLevel()); updater.addData("class", data.getProfess().getId());
request.addData("experience", data.getExperience()); updater.addData("last_login", data.getLastLogin());
request.addData("class", data.getProfess().getId()); updater.addData("guild", data.hasGuild() ? data.getGuild().getId() : null);
request.addData("last_login", data.getLastLogin()); updater.addJSONArray("waypoints", data.getWaypoints());
request.addData("guild", data.hasGuild() ? data.getGuild().getId() : null); updater.addJSONArray("friends", data.getFriends().stream().map(UUID::toString).collect(Collectors.toList()));
request.addJSONArray("waypoints", data.getWaypoints());
request.addJSONArray("friends", data.getFriends().stream().map(UUID::toString).collect(Collectors.toList()));
List<String> boundSkills = new ArrayList<>(); List<String> boundSkills = new ArrayList<>();
data.getBoundSkills().forEach(skill -> boundSkills.add(skill.getSkill().getHandler().getId())); data.getBoundSkills().forEach(skill -> boundSkills.add(skill.getSkill().getHandler().getId()));
data.getBoundPassiveSkills().forEach(skill -> boundSkills.add(skill.getTriggeredSkill().getHandler().getId())); data.getBoundPassiveSkills().forEach(skill -> boundSkills.add(skill.getTriggeredSkill().getHandler().getId()));
request.addJSONArray("bound_skills", boundSkills); updater.addJSONArray("bound_skills", boundSkills);
request.addJSONObject("skills", data.mapSkillLevels().entrySet()); updater.addJSONObject("skills", data.mapSkillLevels().entrySet());
request.addJSONObject("times_claimed", data.getItemClaims().entrySet()); updater.addJSONObject("times_claimed", data.getItemClaims().entrySet());
request.addJSONObject("skill_tree_points", data.mapSkillTreePoints().entrySet()); updater.addJSONObject("skill_tree_points", data.mapSkillTreePoints().entrySet());
request.addJSONObject("skill_tree_levels", data.getNodeLevelsEntrySet()); updater.addJSONObject("skill_tree_levels", data.getNodeLevelsEntrySet());
request.addData("attributes", data.getAttributes().toJsonString()); updater.addData("attributes", data.getAttributes().toJsonString());
request.addData("professions", data.getCollectionSkills().toJsonString()); updater.addData("professions", data.getCollectionSkills().toJsonString());
request.addData("quests", data.getQuestData().toJsonString()); updater.addData("quests", data.getQuestData().toJsonString());
request.addData("class_info", createClassInfoData(data).toString()); updater.addData("class_info", createClassInfoData(data).toString());
if (logout) if (logout)
request.addData("is_saved", 1); updater.addData("is_saved", 1);
sql.updateData(request); updater.executeRequest();
MMOCore.sqlDebug("Saved data for: " + data.getUniqueId());
MMOCore.sqlDebug(String.format("{ class: %s, level: %d }", data.getProfess().getId(), data.getLevel())); MythicLib.debug("MMOCoreSQL", "Saved data for: " + data.getUniqueId());
MythicLib.debug("MMOCoreSQL", String.format("{ class: %s, level: %d }", data.getProfess().getId(), data.getLevel()));
} }
private JsonObject createClassInfoData(PlayerData playerData) { private JsonObject createClassInfoData(PlayerData playerData) {
@ -257,8 +114,8 @@ public class MySQLPlayerDataManager extends PlayerDataManager {
return json; return json;
} }
private boolean isEmpty(String s) { private boolean isEmpty(@Nullable String str) {
return s == null || s.equalsIgnoreCase("null") || s.equalsIgnoreCase("{}") || s.equalsIgnoreCase("[]") || s.equalsIgnoreCase(""); return str == null || str.equalsIgnoreCase("null") || str.equalsIgnoreCase("{}") || str.equalsIgnoreCase("[]") || str.equalsIgnoreCase("");
} }
@NotNull @NotNull
@ -278,13 +135,13 @@ public class MySQLPlayerDataManager extends PlayerDataManager {
provider.getResult("SELECT * FROM mmocore_playerdata WHERE uuid = '" + uuid + "';", (result) -> { provider.getResult("SELECT * FROM mmocore_playerdata WHERE uuid = '" + uuid + "';", (result) -> {
try { try {
MMOCore.sqlDebug("Loading OFFLINE data for '" + uuid + "'."); MythicLib.debug("MMOCoreSQL", "Loading OFFLINE data for '" + uuid + "'.");
if (!result.next()) { if (!result.next()) {
level = 0; level = 0;
lastLogin = 0; lastLogin = 0;
profess = MMOCore.plugin.classManager.getDefaultClass(); profess = MMOCore.plugin.classManager.getDefaultClass();
friends = new ArrayList<>(); friends = new ArrayList<>();
MMOCore.sqlDebug("Default OFFLINE data loaded."); MythicLib.debug("MMOCoreSQL", "Default OFFLINE data loaded.");
} else { } else {
level = result.getInt("level"); level = result.getInt("level");
lastLogin = result.getLong("last_login"); lastLogin = result.getLong("last_login");
@ -292,7 +149,7 @@ public class MySQLPlayerDataManager extends PlayerDataManager {
if (!isEmpty(result.getString("friends"))) if (!isEmpty(result.getString("friends")))
MMOCoreUtils.jsonArrayToList(result.getString("friends")).forEach(str -> friends.add(UUID.fromString(str))); MMOCoreUtils.jsonArrayToList(result.getString("friends")).forEach(str -> friends.add(UUID.fromString(str)));
else friends = new ArrayList<>(); else friends = new ArrayList<>();
MMOCore.sqlDebug("Saved OFFLINE data loaded."); MythicLib.debug("MMOCoreSQL", "Saved OFFLINE data loaded.");
} }
} catch (SQLException e) { } catch (SQLException e) {
e.printStackTrace(); e.printStackTrace();
@ -303,7 +160,7 @@ public class MySQLPlayerDataManager extends PlayerDataManager {
@Override @Override
public void removeFriend(UUID uuid) { public void removeFriend(UUID uuid) {
friends.remove(uuid); friends.remove(uuid);
new MySQLTableEditor(MySQLTableEditor.Table.PLAYERDATA, uuid, provider).updateData("friends", friends.stream().map(UUID::toString).collect(Collectors.toList())); new PlayerDataTableUpdater(provider, uuid).updateData("friends", friends.stream().map(UUID::toString).collect(Collectors.toList()));
} }
@Override @Override

View File

@ -1,48 +0,0 @@
package net.Indyuce.mmocore.manager.data.mysql;
import com.google.gson.JsonArray;
import com.google.gson.JsonObject;
import org.denizen.dungeons.requests.RequestDataKey;
import java.util.Collection;
import java.util.Map.Entry;
import java.util.Set;
import java.util.UUID;
public class MySQLTableEditor {
private final Table table;
private final UUID uuid;
private final MySQLDataProvider provider;
public MySQLTableEditor(Table table, UUID uuid, MySQLDataProvider provider) {
this.table = table;
this.uuid = uuid;
this.provider = provider;
}
public void updateData(String key, Object value) {
provider.executeUpdate("INSERT INTO " + table + "(uuid, " + key
+ ") VALUES('" + uuid + "', '" + value + "') ON DUPLICATE KEY UPDATE " + key + "='" + value + "';");
}
public void updateData(MySQLRequest request) {
provider.executeUpdate("INSERT INTO " + table + request.getRequestString());
}
public enum Table {
PLAYERDATA("mmocore_playerdata"), GUILDDATA("mmocore_guilddata");
final String tableName;
Table(String tN) {
tableName = tN;
}
@Override
public String toString() {
return tableName;
}
}
}

View File

@ -2,20 +2,36 @@ package net.Indyuce.mmocore.manager.data.mysql;
import com.google.gson.JsonArray; import com.google.gson.JsonArray;
import com.google.gson.JsonObject; import com.google.gson.JsonObject;
import net.Indyuce.mmocore.MMOCore; import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.*; import java.util.*;
public class MySQLRequest { public class PlayerDataTableUpdater {
private final Map<String, String> requestMap = new HashMap<>();
private final UUID uuid; private final UUID uuid;
private final MySQLDataProvider provider;
private final Map<String, String> requestMap = new HashMap<>();
public MySQLRequest(UUID uuid) { public PlayerDataTableUpdater(MySQLDataProvider provider, UUID uuid) {
this.uuid = uuid; this.uuid = uuid;
this.provider = provider;
} }
public void addData(String key, Object value) { public void updateData(String key, Object value) {
requestMap.put(key, "" + value); addData(key, value);
executeRequest();
requestMap.clear();
}
public void executeRequest() {
final String request = "INSERT INTO mmocore_playerdata(uuid, " + formatCollection(requestMap.keySet(), false)
+ ") VALUES('" + uuid + "'," + formatCollection(requestMap.values(), true) + ")" +
" ON DUPLICATE KEY UPDATE " + formatMap() + ";";
provider.executeUpdate(request);
}
public void addData(@NotNull String key, @Nullable Object value) {
requestMap.put(key, String.valueOf(value));
} }
public String formatCollection(Collection<String> strings, boolean withComma) { public String formatCollection(Collection<String> strings, boolean withComma) {
@ -34,31 +50,15 @@ public class MySQLRequest {
} }
public String formatMap() { public String formatMap() {
StringBuilder values = new StringBuilder(); final StringBuilder values = new StringBuilder();
for (String key : requestMap.keySet()) { for (String key : requestMap.keySet())
//values.append("'"); values.append(key).append("='").append(requestMap.get(key)).append("',");
values.append(key);
//values.append("'"); // Remove the last comma
values.append("=");
values.append("'");
values.append(requestMap.get(key));
values.append("'");
values.append(",");
}
//Remove the last coma
values.deleteCharAt(values.length() - 1); values.deleteCharAt(values.length() - 1);
return values.toString(); return values.toString();
} }
public String getRequestString() {
String result = "(uuid, " + formatCollection(requestMap.keySet(),false)
+ ") VALUES('" + uuid + "'," + formatCollection(requestMap.values(),true) + ")" +
" ON DUPLICATE KEY UPDATE " + formatMap() + ";";
return result;
}
public void addJSONArray(String key, Collection<String> collection) { public void addJSONArray(String key, Collection<String> collection) {
JsonArray json = new JsonArray(); JsonArray json = new JsonArray();
for (String s : collection) for (String s : collection)
@ -72,5 +72,4 @@ public class MySQLRequest {
json.addProperty(entry.getKey(), entry.getValue()); json.addProperty(entry.getKey(), entry.getValue());
addData(key, json.toString()); addData(key, json.toString());
} }
} }

View File

@ -20,9 +20,6 @@ mysql:
cachePrepStmts: true cachePrepStmts: true
prepStmtCacheSize: 250 prepStmtCacheSize: 250
prepStmtCacheSqlLimit: 2048 prepStmtCacheSqlLimit: 2048
# Will verbose to the console whenever
# data is saved/loaded from the SQL database.
debug: false
# The default values for all playerdata # The default values for all playerdata
# All new players will start with these values # All new players will start with these values