diff --git a/src/main/java/com/yaohun/demonskills/SkillsMain.java b/src/main/java/com/yaohun/demonskills/SkillsMain.java index e38c0cc..29b5e88 100644 --- a/src/main/java/com/yaohun/demonskills/SkillsMain.java +++ b/src/main/java/com/yaohun/demonskills/SkillsMain.java @@ -13,6 +13,7 @@ import com.yaohun.demonskills.gui.SkillsGui; import com.yaohun.demonskills.listener.PlayerListener; import com.yaohun.demonskills.listener.SkillKeyListener; import com.yaohun.demonskills.manage.PlayerManager; +import com.yaohun.demonskills.util.AsyncPlayerDataSaver; import com.yaohun.demonskills.util.CDTimeAPI; import me.Demon.DemonPlugin.DemonAPI; import org.bukkit.Bukkit; @@ -49,6 +50,8 @@ public class SkillsMain extends JavaPlugin { } Bukkit.getConsoleSender().sendMessage("§b[魂式技能] §a插件成功载入Server!"); Bukkit.getConsoleSender().sendMessage("§b[魂式技能] §a妖魂QQ: §b1763917516"); + + new AsyncPlayerDataSaver(this); } @Override diff --git a/src/main/java/com/yaohun/demonskills/data/PlayerData.java b/src/main/java/com/yaohun/demonskills/data/PlayerData.java index 50ba5f9..5eb7bd0 100644 --- a/src/main/java/com/yaohun/demonskills/data/PlayerData.java +++ b/src/main/java/com/yaohun/demonskills/data/PlayerData.java @@ -1,8 +1,10 @@ package com.yaohun.demonskills.data; +import com.yaohun.demonskills.SkillsMain; import com.yaohun.demonskills.core.Skill; import me.Demon.DemonPlugin.DemonAPI; import me.Demon.DemonPlugin.data.NbtItem; +import org.bukkit.Bukkit; import org.bukkit.configuration.ConfigurationSection; import org.bukkit.configuration.file.FileConfiguration; import org.bukkit.configuration.file.YamlConfiguration; @@ -11,6 +13,7 @@ import org.bukkit.inventory.ItemStack; import java.io.File; import java.io.IOException; import java.util.HashMap; +import java.util.Map; public class PlayerData { @@ -60,20 +63,38 @@ public class PlayerData { } } - public void SavePlayerData(){ - this.configuration.set("Magic",this.magicMax); - this.configuration.set("KeyBoard",null); - for (Integer keyBoard : keyBoardStackMap.keySet()) { - ItemStack keyBoardStack = keyBoardStackMap.get(keyBoard); - this.configuration.set("KeyBoard."+keyBoard,keyBoardStack); - } - try { - this.configuration.save(this.file); - } catch (IOException e) { - throw new RuntimeException(e); + public void SavePlayerData() { + // ✅ 1. 主线程内抓取快照,避免异步直接访问成员变量 + int magicMaxSnapshot = this.magicMax; + + // 复制键盘映射(注意深拷贝 ItemStack) + Map keyboardSnapshot = new HashMap<>(); + for (Map.Entry entry : this.keyBoardStackMap.entrySet()) { + keyboardSnapshot.put(entry.getKey(), entry.getValue().clone()); } + + // 创建配置快照 + File fileSnapshot = this.file; + YamlConfiguration configSnapshot = new YamlConfiguration(); + + // ✅ 2. 异步保存,使用快照对象,避免线程冲突 + Bukkit.getScheduler().runTaskAsynchronously(SkillsMain.inst(), () -> { + configSnapshot.set("Magic", magicMaxSnapshot); + configSnapshot.set("KeyBoard", null); + + for (Map.Entry entry : keyboardSnapshot.entrySet()) { + configSnapshot.set("KeyBoard." + entry.getKey(), entry.getValue()); + } + + try { + configSnapshot.save(fileSnapshot); + } catch (IOException e) { + e.printStackTrace(); + } + }); } + public String getPlayerName() { return name; } diff --git a/src/main/java/com/yaohun/demonskills/listener/PlayerListener.java b/src/main/java/com/yaohun/demonskills/listener/PlayerListener.java index d0f992b..397942f 100644 --- a/src/main/java/com/yaohun/demonskills/listener/PlayerListener.java +++ b/src/main/java/com/yaohun/demonskills/listener/PlayerListener.java @@ -1,6 +1,8 @@ package com.yaohun.demonskills.listener; +import com.yaohun.demonskills.SkillsMain; import com.yaohun.demonskills.gui.SkillsGui; +import com.yaohun.demonskills.manage.PlayerManager; import com.yaohun.demonskills.util.CDTimeAPI; import eos.moe.dragoncore.api.event.KeyPressEvent; import eos.moe.dragoncore.api.event.KeyReleaseEvent; @@ -17,8 +19,10 @@ import org.bukkit.event.entity.EntityDamageByEntityEvent; import org.bukkit.event.entity.EntityDamageEvent; import org.bukkit.event.player.PlayerInteractEvent; import org.bukkit.event.player.PlayerMoveEvent; +import org.bukkit.event.player.PlayerQuitEvent; import org.bukkit.inventory.EquipmentSlot; import org.bukkit.inventory.ItemStack; +import org.serverct.ersha.jd.S; import java.util.UUID; @@ -65,4 +69,12 @@ public class PlayerListener implements Listener { } } } + + @EventHandler + public void onQuieSave(PlayerQuitEvent e){ + Player player = e.getPlayer(); + String playerName = player.getName(); + PlayerManager playerManager = SkillsMain.getPlayerManager(); + playerManager.getPlayerData(playerName).SavePlayerData(); + } } diff --git a/src/main/java/com/yaohun/demonskills/util/AsyncPlayerDataSaver.java b/src/main/java/com/yaohun/demonskills/util/AsyncPlayerDataSaver.java new file mode 100644 index 0000000..6df5a68 --- /dev/null +++ b/src/main/java/com/yaohun/demonskills/util/AsyncPlayerDataSaver.java @@ -0,0 +1,61 @@ +package com.yaohun.demonskills.util; + +import com.yaohun.demonskills.SkillsMain; +import org.bukkit.Bukkit; +import org.bukkit.entity.Player; +import org.bukkit.scheduler.BukkitRunnable; + +import java.util.ArrayList; +import java.util.List; + +public class AsyncPlayerDataSaver { + + private final SkillsMain plugin; + private final int batchSize = 5; + private final int delayBetweenBatches = 20; // 每批延迟1秒(20tick) + + public AsyncPlayerDataSaver(SkillsMain plugin) { + this.plugin = plugin; + startAutoSave(); + } + + public void startAutoSave() { + new BukkitRunnable() { + @Override + public void run() { + List onlinePlayers = new ArrayList<>(Bukkit.getOnlinePlayers()); + if (onlinePlayers.isEmpty()) { + return; + } + + int total = onlinePlayers.size(); + int batches = (int) Math.ceil((double) total / batchSize); + + for (int i = 0; i < batches; i++) { + final int batchIndex = i; + + new BukkitRunnable() { + @Override + public void run() { + int start = batchIndex * batchSize; + int end = Math.min(start + batchSize, total); + + for (int j = start; j < end; j++) { + Player p = onlinePlayers.get(j); + Bukkit.getScheduler().runTaskAsynchronously(SkillsMain.inst(), () -> { + savePlayerData(p); // 你的保存方法(异步安全) + }); + } + } + }.runTaskLater(SkillsMain.inst(), (long) delayBetweenBatches * i); + } + } + }.runTaskTimer(SkillsMain.inst(), 20 * 60 * 10, 20 * 60 * 10); // 每5分钟执行一次 + } + + private void savePlayerData(Player player) { + // TODO: 将你的数据写入YAML或数据库 + // 注意线程安全,例如避免直接操作 Bukkit API,只处理内存数据快照 + } +} + diff --git a/src/main/resources/plugin.yml b/src/main/resources/plugin.yml index fe89b71..edcbccc 100644 --- a/src/main/resources/plugin.yml +++ b/src/main/resources/plugin.yml @@ -1,8 +1,8 @@ name: DemonSkills main: com.yaohun.demonskills.SkillsMain -version: 1.3.4 +version: 1.3.6 depend: - DemonAPI commands: dskills: - castskill: \ No newline at end of file + castskill: