Repository navigation
Auto saving mysql lost data. #14
Description
Activity
Can you make autosaving without save fake user account until load data ?
I found api. Its has only save all players its not save per player.
If its has save per player . I will use repeat async auto save after player join server Playerjoinevent
Can you recode it?
I found api. Its has only save all players its not save per player.
I think its has save single player every time they join, i found these in source code, in MainListener at package com.sucy.skill.listener:
/** * Saves player data when they log out and stops passives * * @param event event details */ @EventHandler(priority = EventPriority.MONITOR) public void onQuit(PlayerQuitEvent event) { unload(event.getPlayer()); } /** * Unloads a player's data from the server * * @param player player to unload */ public static void unload(Player player) { if (CitizensHook.isNPC(player)) return; boolean skipSaving = false; if (loadingPlayers.containsKey(player.getUniqueId())) { loadingPlayers.remove(player.getUniqueId()).cancel(); skipSaving = true; } PlayerData data = SkillAPI.getPlayerData(player); if (SkillAPI.getSettings().isWorldEnabled(player.getWorld())) { data.record(player); data.stopPassives(player); } FlagManager.clearFlags(player); BuffManager.clearData(player); Combat.clearData(player); DynamicSkill.clearCastData(player); player.setDisplayName(player.getName()); if (VersionManager.isVersionAtLeast(VersionManager.V1_9_0)) { player.getAttribute(Attribute.GENERIC_MAX_HEALTH).setBaseValue(20); } else { player.setMaxHealth(20); } player.setWalkSpeed(0.2f); SkillAPI.unloadPlayerData(player, skipSaving); }
skipSaving should be false if this player is not loading data, so go to SkillAPI.unloadPlayerData(OfflinePlayer, boolean) in com.sucy.skill:
/** * Unloads player data from memory, saving it to the config * first and then removing it from the map. * * @param player player to unload data for */ public static void unloadPlayerData(final OfflinePlayer player) { unloadPlayerData(player, false); } public static void unloadPlayerData(final OfflinePlayer player, final boolean skipSaving) { if (singleton == null || player == null || singleton.disabling || !singleton.players.containsKey(new VersionPlayer(player).getIdString())) { return; } singleton.getServer().getScheduler().runTaskAsynchronously(singleton, () -> { PlayerAccounts accounts = getPlayerAccountData(player); if (!skipSaving) { singleton.io.saveData(accounts); } singleton.players.remove(new VersionPlayer(player).getIdString()); }); }
singleton is instance of SkillApi class, and io feild is instance of abstract class IOManager in com.sucy.skill.data.io, saveData(OfflinePlayer) is a abstract method, and i think if we use mysql then the IOManager will be SQLIO class's instance in com.sucy.skill.data.io, see saveData(OfflinePlayer) in SQLIO:
@Override public void saveData(PlayerAccounts data) { SQLConnection connection = openConnection(); saveSingle(connection, data); connection.database.closeConnection(); }
every thing seems normal, i can't find the key of the problem, same with when player join:
/** * Starts passives and applies class data when a player logs in. */ @EventHandler public void onJoin(final PlayerJoinEvent event) { final Player player = event.getPlayer(); if (player.hasMetadata("NPC") || !SkillAPI.getSettings().isWorldEnabled(player.getWorld())) return; final int delay = SkillAPI.getSettings().getSqlDelay(); if (SkillAPI.getSettings().isUseSql() && delay > 0) { final BukkitTask task = SkillAPI.schedule(() -> { try { SkillAPI.reloadPlayerData(player); init(player); } finally { loadingPlayers.remove(event.getPlayer().getUniqueId()); } }, delay); loadingPlayers.put(event.getPlayer().getUniqueId(), task); } else { init(player); } }
and in SkillAPI.reloadPlayerData(OfflinePlayer) method:
/** * Do not use this method outside of onJoin. This will delete any progress a player * has made since joining. */ public static void reloadPlayerData(final Player player) { doLoad(player); }
see doLoad(OfflinePlayer):
private static PlayerAccounts doLoad(OfflinePlayer player) { // Load the data PlayerAccounts data = singleton.io.loadData(player); singleton.players.put(player.getUniqueId().toString(), data); return data; }
see loadData(OfflinePlayer) in SQLIO:
@Override public PlayerAccounts loadData(OfflinePlayer player) { if (player == null) return null; SQLConnection connection = openConnection(); PlayerAccounts result = load(connection, player); connection.database.closeConnection(); return result; }
Reacted by chocolatecraftIts normally for auto save when quit. But auto save period in config its save all player data. I got bug if enabled it some player join while auto save runing. They lost data (if I disable period auto save its worked but when server crash or closed server some player level rollback)
I'am not sure about this I dont have java skill.
What method or api can I use with playerjoinevent for repeat async auto save single player?
Reference sucy.skill.task savetask.javaI read this whole thread and still can't understand what the issue is due to the broken english :P
Auto saving mysql lost data.
When I enabled this function some player got lost all data.
I find many time for check this problem. I got know it right now.
When I enabled config delay load data for sync multi server. its will lost data from auto save.
I set delay "100" From config
100 = 5 sec
Example.
When I join to server and then config will check delay for load sync data from mysql.
And While delay loading... skillapi saving In the moment. it causing data loss.
if skillapi autosave when player join in 5 sec that player still lost data. Saving will save fake user account.