1.3.8
This commit is contained in:
parent
d1fc0be07f
commit
228725300e
|
@ -13,7 +13,6 @@ import com.yaohun.demonskills.gui.SkillsGui;
|
||||||
import com.yaohun.demonskills.listener.PlayerListener;
|
import com.yaohun.demonskills.listener.PlayerListener;
|
||||||
import com.yaohun.demonskills.listener.SkillKeyListener;
|
import com.yaohun.demonskills.listener.SkillKeyListener;
|
||||||
import com.yaohun.demonskills.manage.PlayerManager;
|
import com.yaohun.demonskills.manage.PlayerManager;
|
||||||
import com.yaohun.demonskills.util.AsyncPlayerDataSaver;
|
|
||||||
import com.yaohun.demonskills.util.CDTimeAPI;
|
import com.yaohun.demonskills.util.CDTimeAPI;
|
||||||
import me.Demon.DemonPlugin.DemonAPI;
|
import me.Demon.DemonPlugin.DemonAPI;
|
||||||
import org.bukkit.Bukkit;
|
import org.bukkit.Bukkit;
|
||||||
|
@ -50,8 +49,6 @@ public class SkillsMain extends JavaPlugin {
|
||||||
}
|
}
|
||||||
Bukkit.getConsoleSender().sendMessage("§b[魂式技能] §a插件成功载入Server!");
|
Bukkit.getConsoleSender().sendMessage("§b[魂式技能] §a插件成功载入Server!");
|
||||||
Bukkit.getConsoleSender().sendMessage("§b[魂式技能] §a妖魂QQ: §b1763917516");
|
Bukkit.getConsoleSender().sendMessage("§b[魂式技能] §a妖魂QQ: §b1763917516");
|
||||||
|
|
||||||
new AsyncPlayerDataSaver(this);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -1,10 +1,8 @@
|
||||||
package com.yaohun.demonskills.data;
|
package com.yaohun.demonskills.data;
|
||||||
|
|
||||||
import com.yaohun.demonskills.SkillsMain;
|
|
||||||
import com.yaohun.demonskills.core.Skill;
|
import com.yaohun.demonskills.core.Skill;
|
||||||
import me.Demon.DemonPlugin.DemonAPI;
|
import me.Demon.DemonPlugin.DemonAPI;
|
||||||
import me.Demon.DemonPlugin.data.NbtItem;
|
import me.Demon.DemonPlugin.data.NbtItem;
|
||||||
import org.bukkit.Bukkit;
|
|
||||||
import org.bukkit.configuration.ConfigurationSection;
|
import org.bukkit.configuration.ConfigurationSection;
|
||||||
import org.bukkit.configuration.file.FileConfiguration;
|
import org.bukkit.configuration.file.FileConfiguration;
|
||||||
import org.bukkit.configuration.file.YamlConfiguration;
|
import org.bukkit.configuration.file.YamlConfiguration;
|
||||||
|
@ -13,7 +11,6 @@ import org.bukkit.inventory.ItemStack;
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
public class PlayerData {
|
public class PlayerData {
|
||||||
|
|
||||||
|
@ -63,38 +60,20 @@ public class PlayerData {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void SavePlayerData() {
|
public void SavePlayerData(){
|
||||||
// ✅ 1. 主线程内抓取快照,避免异步直接访问成员变量
|
this.configuration.set("Magic",this.magicMax);
|
||||||
int magicMaxSnapshot = this.magicMax;
|
this.configuration.set("KeyBoard",null);
|
||||||
|
for (Integer keyBoard : keyBoardStackMap.keySet()) {
|
||||||
// 复制键盘映射(注意深拷贝 ItemStack)
|
ItemStack keyBoardStack = keyBoardStackMap.get(keyBoard);
|
||||||
Map<Integer, ItemStack> keyboardSnapshot = new HashMap<>();
|
this.configuration.set("KeyBoard."+keyBoard,keyBoardStack);
|
||||||
for (Map.Entry<Integer, ItemStack> entry : this.keyBoardStackMap.entrySet()) {
|
}
|
||||||
keyboardSnapshot.put(entry.getKey(), entry.getValue().clone());
|
try {
|
||||||
|
this.configuration.save(this.file);
|
||||||
|
} catch (IOException e) {
|
||||||
|
throw new RuntimeException(e);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 创建配置快照
|
|
||||||
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<Integer, ItemStack> entry : keyboardSnapshot.entrySet()) {
|
|
||||||
configSnapshot.set("KeyBoard." + entry.getKey(), entry.getValue());
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
configSnapshot.save(fileSnapshot);
|
|
||||||
} catch (IOException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public String getPlayerName() {
|
public String getPlayerName() {
|
||||||
return name;
|
return name;
|
||||||
}
|
}
|
||||||
|
|
|
@ -72,7 +72,8 @@ public class StoneEquipGui implements Listener {
|
||||||
player.closeInventory();
|
player.closeInventory();
|
||||||
PlayerManager playerManager = SkillsMain.getPlayerManager();
|
PlayerManager playerManager = SkillsMain.getPlayerManager();
|
||||||
PlayerData playerData = playerManager.getPlayerData(playerName);
|
PlayerData playerData = playerManager.getPlayerData(playerName);
|
||||||
|
// 设置完成后保存玩家数据
|
||||||
|
playerData.SavePlayerData();
|
||||||
SkillsGui.checkItemSetBindKeyBoard(playerData, skillStone, rawSlot);
|
SkillsGui.checkItemSetBindKeyBoard(playerData, skillStone, rawSlot);
|
||||||
player.playSound(player.getLocation(), Sound.BLOCK_COMPARATOR_CLICK,1,1);
|
player.playSound(player.getLocation(), Sound.BLOCK_COMPARATOR_CLICK,1,1);
|
||||||
new BukkitRunnable() {
|
new BukkitRunnable() {
|
||||||
|
|
|
@ -68,44 +68,44 @@ public class Skill_赤焰旋风斩 {
|
||||||
new DelayComponent(8L, Arrays.asList(
|
new DelayComponent(8L, Arrays.asList(
|
||||||
new PotionEffectComponent(PotionEffectType.SLOW,70,2),
|
new PotionEffectComponent(PotionEffectType.SLOW,70,2),
|
||||||
new DamageComponent(damage*0.2,new NearestEnemiesSelector(5)),
|
new DamageComponent(damage*0.2,new NearestEnemiesSelector(5)),
|
||||||
new ProjectileAdvanceComponent(0.5,0.2,new NearestEnemiesSelector(5)),
|
new ProjectileAdvanceComponent(0.5,0.2,new NearestEnemiesSelector(5,true)),
|
||||||
new SoundComponent("战士音效/旋风斩音效.ogg", 0.5f, 1.0f,10),
|
new SoundComponent("战士音效/旋风斩音效.ogg", 0.5f, 1.0f,10),
|
||||||
new DelayComponent(10L, Arrays.asList(
|
new DelayComponent(10L, Arrays.asList(
|
||||||
|
|
||||||
new DamageComponent(damage*0.2,new NearestEnemiesSelector(5)),
|
new DamageComponent(damage*0.2,new NearestEnemiesSelector(5)),
|
||||||
new ProjectileAdvanceComponent(0.5,0.2,new NearestEnemiesSelector(5)),
|
new ProjectileAdvanceComponent(0.5,0.2,new NearestEnemiesSelector(5,true)),
|
||||||
new SoundComponent("战士音效/旋风斩音效.ogg", 0.5f, 1.0f,10),
|
new SoundComponent("战士音效/旋风斩音效.ogg", 0.5f, 1.0f,10),
|
||||||
new DelayComponent(10L, Arrays.asList(
|
new DelayComponent(10L, Arrays.asList(
|
||||||
|
|
||||||
new DamageComponent(damage*0.2,new NearestEnemiesSelector(5)),
|
new DamageComponent(damage*0.2,new NearestEnemiesSelector(5)),
|
||||||
new ProjectileAdvanceComponent(0.5,0.2,new NearestEnemiesSelector(5)),
|
new ProjectileAdvanceComponent(0.5,0.2,new NearestEnemiesSelector(5,true)),
|
||||||
new SoundComponent("战士音效/旋风斩音效.ogg", 0.5f, 1.0f,10),
|
new SoundComponent("战士音效/旋风斩音效.ogg", 0.5f, 1.0f,10),
|
||||||
new DelayComponent(10L, Arrays.asList(
|
new DelayComponent(10L, Arrays.asList(
|
||||||
|
|
||||||
new DamageComponent(damage*0.2,new NearestEnemiesSelector(5)),
|
new DamageComponent(damage*0.2,new NearestEnemiesSelector(5)),
|
||||||
new ProjectileAdvanceComponent(0.5,0.2,new NearestEnemiesSelector(5)),
|
new ProjectileAdvanceComponent(0.5,0.2,new NearestEnemiesSelector(5,true)),
|
||||||
new SoundComponent("战士音效/旋风斩音效.ogg", 0.5f, 1.0f,10),
|
new SoundComponent("战士音效/旋风斩音效.ogg", 0.5f, 1.0f,10),
|
||||||
new DelayComponent(10L, Arrays.asList(
|
new DelayComponent(10L, Arrays.asList(
|
||||||
|
|
||||||
new DamageComponent(damage*0.2,new NearestEnemiesSelector(5)),
|
new DamageComponent(damage*0.2,new NearestEnemiesSelector(5)),
|
||||||
new ProjectileAdvanceComponent(0.5,0.2,new NearestEnemiesSelector(5)),
|
new ProjectileAdvanceComponent(0.5,0.2,new NearestEnemiesSelector(5,true)),
|
||||||
new SoundComponent("战士音效/旋风斩音效.ogg", 0.5f, 1.0f,10),
|
new SoundComponent("战士音效/旋风斩音效.ogg", 0.5f, 1.0f,10),
|
||||||
new DelayComponent(10L,Arrays.asList(
|
new DelayComponent(10L,Arrays.asList(
|
||||||
|
|
||||||
new DamageComponent(damage*0.2,new NearestEnemiesSelector(5)),
|
new DamageComponent(damage*0.2,new NearestEnemiesSelector(5)),
|
||||||
new ProjectileAdvanceComponent(0.5,0.2,new NearestEnemiesSelector(5)),
|
new ProjectileAdvanceComponent(0.5,0.2,new NearestEnemiesSelector(5,true)),
|
||||||
new SoundComponent("战士音效/旋风斩音效.ogg", 0.5f, 1.0f,10),
|
new SoundComponent("战士音效/旋风斩音效.ogg", 0.5f, 1.0f,10),
|
||||||
new DelayComponent(10L,Arrays.asList(
|
new DelayComponent(10L,Arrays.asList(
|
||||||
|
|
||||||
new DamageComponent(damage*0.2,new NearestEnemiesSelector(5)),
|
new DamageComponent(damage*0.2,new NearestEnemiesSelector(5)),
|
||||||
new ProjectileAdvanceComponent(0.5,0.2,new NearestEnemiesSelector(5)),
|
new ProjectileAdvanceComponent(0.5,0.2,new NearestEnemiesSelector(5,true)),
|
||||||
new SoundComponent("战士音效/旋风斩音效.ogg", 0.5f, 1.0f,10),
|
new SoundComponent("战士音效/旋风斩音效.ogg", 0.5f, 1.0f,10),
|
||||||
new DelayComponent(10L,Arrays.asList(
|
new DelayComponent(10L,Arrays.asList(
|
||||||
// 播放爆炸音效
|
// 播放爆炸音效
|
||||||
new SoundComponent("ENTITY_GENERIC_EXPLODE",1.0f,1.0f),
|
new SoundComponent("ENTITY_GENERIC_EXPLODE",1.0f,1.0f),
|
||||||
// 播放 跟随岩浆粒子 5次
|
// 播放 跟随岩浆粒子 5次
|
||||||
new ParticlesComponent(Particle.LAVA,5,0.2,5),
|
new ParticlesComponent(Particle.LAVA,5,0.2,5),
|
||||||
new ProjectileAdvanceComponent(0.6,0.8,new NearestEnemiesSelector(3))
|
new ProjectileAdvanceComponent(0.6,0.8,new NearestEnemiesSelector(3,true))
|
||||||
))
|
))
|
||||||
))
|
))
|
||||||
))
|
))
|
||||||
|
|
|
@ -9,7 +9,6 @@ import com.yaohun.demonskills.component.dragoncore.ParticleSpawnCommponent;
|
||||||
import com.yaohun.demonskills.component.dragoncore.PlayerAnimationComponent;
|
import com.yaohun.demonskills.component.dragoncore.PlayerAnimationComponent;
|
||||||
import com.yaohun.demonskills.component.dragoncore.StandAnimationComponent;
|
import com.yaohun.demonskills.component.dragoncore.StandAnimationComponent;
|
||||||
import com.yaohun.demonskills.component.particles.ParticlesComponent;
|
import com.yaohun.demonskills.component.particles.ParticlesComponent;
|
||||||
import com.yaohun.demonskills.component.projectile.ProjectileAdvanceComponent;
|
|
||||||
import com.yaohun.demonskills.core.Skill;
|
import com.yaohun.demonskills.core.Skill;
|
||||||
import com.yaohun.demonskills.data.PlayerData;
|
import com.yaohun.demonskills.data.PlayerData;
|
||||||
import com.yaohun.demonskills.manage.PlayerManager;
|
import com.yaohun.demonskills.manage.PlayerManager;
|
||||||
|
|
|
@ -92,7 +92,7 @@ public class Skill_逐影破空斩 {
|
||||||
new PotionEffectComponent(PotionEffectType.SLOW,10,5,new ConeEnemiesSelector(10.0,45)),
|
new PotionEffectComponent(PotionEffectType.SLOW,10,5,new ConeEnemiesSelector(10.0,45)),
|
||||||
new SoundComponent("挥舞剑气1.ogg", 0.6f, 1.0f),
|
new SoundComponent("挥舞剑气1.ogg", 0.6f, 1.0f),
|
||||||
new DelayComponent(8L,Arrays.asList(
|
new DelayComponent(8L,Arrays.asList(
|
||||||
new ProjectileAdvanceComponent(-2,0.2,new ConeEnemiesSelector(10.0,45)),
|
new ProjectileAdvanceComponent(-2,0.2,new ConeEnemiesSelector(10.0,45,true)),
|
||||||
new DamageComponent(damage * 0.2,new ConeEnemiesSelector(10.0,45))
|
new DamageComponent(damage * 0.2,new ConeEnemiesSelector(10.0,45))
|
||||||
))
|
))
|
||||||
))
|
))
|
||||||
|
|
|
@ -18,12 +18,19 @@ public class ConeEnemiesSelector implements TargetSelector {
|
||||||
private final double radius; // 范围
|
private final double radius; // 范围
|
||||||
private final double angle; // 角度(如 60°)
|
private final double angle; // 角度(如 60°)
|
||||||
private int limit = -1;
|
private int limit = -1;
|
||||||
|
private boolean playerImmune = false;
|
||||||
|
|
||||||
public ConeEnemiesSelector(double radius, double angle) {
|
public ConeEnemiesSelector(double radius, double angle) {
|
||||||
this.radius = radius;
|
this.radius = radius;
|
||||||
this.angle = angle;
|
this.angle = angle;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public ConeEnemiesSelector(double radius, double angle,boolean playerImmune) {
|
||||||
|
this.radius = radius;
|
||||||
|
this.angle = angle;
|
||||||
|
this.playerImmune = playerImmune;
|
||||||
|
}
|
||||||
|
|
||||||
public ConeEnemiesSelector(double radius, double angle, int limit) {
|
public ConeEnemiesSelector(double radius, double angle, int limit) {
|
||||||
this.radius = radius;
|
this.radius = radius;
|
||||||
this.angle = angle;
|
this.angle = angle;
|
||||||
|
@ -40,6 +47,11 @@ public class ConeEnemiesSelector implements TargetSelector {
|
||||||
if (!(entity instanceof LivingEntity) || entity.equals(caster)) continue;
|
if (!(entity instanceof LivingEntity) || entity.equals(caster)) continue;
|
||||||
if (entity instanceof ArmorStand) continue;
|
if (entity instanceof ArmorStand) continue;
|
||||||
if (CitizensAPI.getNPCRegistry().isNPC(entity)) continue;
|
if (CitizensAPI.getNPCRegistry().isNPC(entity)) continue;
|
||||||
|
if(playerImmune){
|
||||||
|
if(entity instanceof Player){
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Vector toTarget = entity.getLocation().toVector().subtract(eyeVec);
|
Vector toTarget = entity.getLocation().toVector().subtract(eyeVec);
|
||||||
toTarget.setY(0);
|
toTarget.setY(0);
|
||||||
|
|
|
@ -10,15 +10,23 @@ import org.bukkit.entity.Player;
|
||||||
import java.util.Comparator;
|
import java.util.Comparator;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
import java.util.stream.Stream;
|
||||||
|
|
||||||
public class NearestEnemiesSelector implements TargetSelector {
|
public class NearestEnemiesSelector implements TargetSelector {
|
||||||
private final double radius;
|
private final double radius;
|
||||||
private int limit = 0;
|
private int limit = 0;
|
||||||
|
// 是否让玩家免疫(不作为目标)
|
||||||
|
private boolean playerImmune = false;
|
||||||
|
|
||||||
public NearestEnemiesSelector(double radius) {
|
public NearestEnemiesSelector(double radius) {
|
||||||
this.radius = radius;
|
this.radius = radius;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public NearestEnemiesSelector(double radius,boolean playerImmune) {
|
||||||
|
this.radius = radius;
|
||||||
|
this.playerImmune = playerImmune;
|
||||||
|
}
|
||||||
|
|
||||||
public NearestEnemiesSelector(double radius, int limit) {
|
public NearestEnemiesSelector(double radius, int limit) {
|
||||||
this.radius = radius;
|
this.radius = radius;
|
||||||
this.limit = limit;
|
this.limit = limit;
|
||||||
|
@ -26,20 +34,20 @@ public class NearestEnemiesSelector implements TargetSelector {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<Entity> selectTargets(Player caster) {
|
public List<Entity> selectTargets(Player caster) {
|
||||||
if(limit != 0) {
|
Stream<Entity> stream = caster.getNearbyEntities(radius, radius, radius).stream()
|
||||||
return caster.getNearbyEntities(radius, radius, radius).stream()
|
.filter(e -> !(e instanceof ArmorStand))
|
||||||
.filter(e -> !(e instanceof ArmorStand))
|
.filter(e -> e instanceof LivingEntity && !e.equals(caster))
|
||||||
.filter(e -> e instanceof LivingEntity && !e.equals(caster))
|
.filter(e -> !CitizensAPI.getNPCRegistry().isNPC(e)); // 排除NPC
|
||||||
.filter(e -> !CitizensAPI.getNPCRegistry().isNPC(e)) // 排除NPC
|
|
||||||
.sorted(Comparator.comparingDouble(e -> e.getLocation().distanceSquared(caster.getLocation())))
|
if (playerImmune) {
|
||||||
.limit(limit)
|
stream = stream.filter(e -> !(e instanceof Player)); // 玩家免疫
|
||||||
.collect(Collectors.toList());
|
|
||||||
} else {
|
|
||||||
return caster.getNearbyEntities(radius, radius, radius).stream()
|
|
||||||
.filter(e -> !(e instanceof ArmorStand))
|
|
||||||
.filter(e -> !CitizensAPI.getNPCRegistry().isNPC(e)) // 排除NPC
|
|
||||||
.filter(e -> e instanceof LivingEntity && !e.equals(caster))
|
|
||||||
.collect(Collectors.toList());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
stream = stream.sorted(Comparator.comparingDouble(e -> e.getLocation().distanceSquared(caster.getLocation())));
|
||||||
|
|
||||||
|
if (limit > 0) {
|
||||||
|
stream = stream.limit(limit);
|
||||||
|
}
|
||||||
|
return stream.collect(Collectors.toList());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,61 +0,0 @@
|
||||||
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<Player> 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,只处理内存数据快照
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
name: DemonSkills
|
name: DemonSkills
|
||||||
main: com.yaohun.demonskills.SkillsMain
|
main: com.yaohun.demonskills.SkillsMain
|
||||||
version: 1.3.6
|
version: 1.3.8
|
||||||
depend:
|
depend:
|
||||||
- DemonAPI
|
- DemonAPI
|
||||||
commands:
|
commands:
|
||||||
|
|
Loading…
Reference in New Issue
Block a user