Merge pull request #11 from iXanadu13/v2.4.0

V2.4.0
This commit is contained in:
Xanadu13
2023-12-30 11:00:08 +08:00
committed by GitHub
31 changed files with 494 additions and 225 deletions
@@ -246,6 +246,7 @@ public final class EnderDragon extends JavaPlugin {
catch (Exception ignored) {}
}
}
private void fixWorldBossBar(){
new BukkitRunnable(){
@Override
@@ -15,7 +15,7 @@ import pers.xanadu.enderdragon.maven.DependencyManager;
import pers.xanadu.enderdragon.reward.Chance;
import pers.xanadu.enderdragon.config.FileUpdater;
import pers.xanadu.enderdragon.task.DragonRespawnTimer;
import pers.xanadu.enderdragon.util.MyDragon;
import pers.xanadu.enderdragon.metadata.MyDragon;
import org.jetbrains.annotations.NotNull;
import java.io.IOException;
@@ -248,7 +248,7 @@ public class MainCommand implements CommandExecutor {
}
if(args.length == 3){
String key = args[2];
MyDragon dragon = DragonManager.mp.get(key);
MyDragon dragon = DragonManager.get_dragon_config(key);
if(dragon == null){
Lang.sendFeedback(sender, Lang.dragon_not_found);
return false;
@@ -349,74 +349,3 @@ public class MainCommand implements CommandExecutor {
}
// long st=System.currentTimeMillis(),ed;
// for(int i=0;i<1;i++) {
// try {
// ItemStack item = p.getItemInHand();
// Class<?> CraftItemStackClass = Class.forName("org.bukkit.craftbukkit.v1_13_R1.inventory.CraftItemStack");
// Object ci = CraftItemStackClass.cast(item);
// Method asNMSCopy = CraftItemStackClass.getDeclaredMethod("asNMSCopy", ItemStack.class);
// Object ei = asNMSCopy.invoke(ci, item);
// Class<?> NBTTagCompoundClass = Class.forName("net.minecraft.server.v1_13_R1.NBTTagCompound");
// Method save = ei.getClass().getDeclaredMethod("save", NBTTagCompoundClass);
// Object cpd = save.invoke(ei, NBTTagCompoundClass.newInstance());
// String str = cpd.toString();
// p.sendMessage(cpd.toString());
// } catch (ReflectiveOperationException e) {
// e.printStackTrace();
// }
// }
// ed=System.currentTimeMillis();
// Bukkit.broadcastMessage("test #1: "+(ed-st)+"ms");
// st=System.currentTimeMillis();
// for(int i=0;i<1e5;i++) {
// ItemStack item = p.getItemInHand();
// net.minecraft.server.v1_13_R1.ItemStack ni = CraftItemStack.asNMSCopy(item);
// NBTTagCompound cpd = ni.save(new NBTTagCompound());
// String str = cpd.toString();
// }
// ed=System.currentTimeMillis();
// Bukkit.broadcastMessage("test #2: "+(ed-st)+"ms");
//
// try {
// CraftItemStackClass=Class.forName("org.bukkit.craftbukkit.v1_13_R1.inventory.CraftItemStack");
// asNMSCopy = CraftItemStackClass.getDeclaredMethod("asNMSCopy", ItemStack.class);
// NBTTagCompoundClass = Class.forName("net.minecraft.server.v1_13_R1.NBTTagCompound");
// ItemStackClass_e = Class.forName("net.minecraft.server.v1_13_R1.ItemStack");
// save = ItemStackClass_e.getDeclaredMethod("save", NBTTagCompoundClass);
// } catch (ReflectiveOperationException e) {
// e.printStackTrace();
// }
// for(int i=0;i<1e5;i++) {
// try {
// ItemStack item = p.getItemInHand();
// Object ci = CraftItemStackClass.cast(item);
// Object ei = asNMSCopy.invoke(ci, item);
// Object cpd = save.invoke(ei, NBTTagCompoundClass.newInstance());
// String str = cpd.toString();
// //p.sendMessage(cpd.toString());
// } catch (ReflectiveOperationException e) {
// e.printStackTrace();
// }
// }
// ed=System.currentTimeMillis();
// Bukkit.broadcastMessage("test #3: "+(ed-st)+"ms");
// st=System.currentTimeMillis();
//
// for(int i=0;i<1;i++) {
// ItemStack item = p.getItemInHand();
// String str = new NbtItemStack(item).getOrCreateTag().toString();
// //Bukkit.broadcastMessage(str);
// p.sendMessage(str);
// }
// ed=System.currentTimeMillis();
// Bukkit.broadcastMessage("test #3: "+(ed-st)+"ms");
// net.minecraft.server.v1_16_R3.ItemStack nmsItem = CraftItemStack.asNMSCopy(item);
// NBTTagCompound cpd = nmsItem.save(new NBTTagCompound());
// net.minecraft.world.item.ItemStack nmsItem = CraftItemStack.asNMSCopy(item);
// NBTTagCompound cpd = nmsItem.b(new NBTTagCompound());
// p.sendMessage(cpd.toString());
@@ -9,40 +9,104 @@ import static pers.xanadu.enderdragon.EnderDragon.*;
public class FileUpdater {
public static void update() throws IOException {
FileConfiguration config_old = plugin.getConfig();
if("2.2.0".equals(config_old.getString("version"))){
Config.saveResource("config.yml","new/config.yml",true);
File config_new_F = new File(plugin.getDataFolder(),"new/config.yml");
FileConfiguration config_new = YamlConfiguration.loadConfiguration(config_new_F);
config_new.set("lang",config_old.getString("lang"));
config_new.set("damage_visible_mode",config_old.getString("damage_visible_mode"));
config_new.set("damage_statistics.limit",config_old.getInt("damage_statistics.limit"));
String judge_mode = config_old.getString("special_dragon_jude_mode");
if("edge".equals(judge_mode)) judge_mode = "weight";//"edge" is deprecated
config_new.set("special_dragon_jude_mode",judge_mode);
config_new.set("dragon_setting_file",config_old.getStringList("dragon_setting_file"));
// auto_respawn
config_new.set("auto_respawn",config_old.getConfigurationSection("auto_respawn"));
config_new.set("respawn_cd.enable",config_old.getBoolean("respawn_cd.enable"));
config_new.set("crystal_invulnerable",config_old.getBoolean("crystal_invulnerable"));
config_new.set("resist_player_respawn",config_old.getBoolean("resist_player_respawn"));
config_new.set("resist_dragon_breath_gather",config_old.getBoolean("resist_dragon_breath_gather"));
config_new.set("main_gui",config_old.getString("main_gui"));
config_new.set("blacklist_worlds",config_old.getStringList("blacklist_worlds"));
config_new.set("item_format.reward",config_old.getString("item_format.reward"));
config_new.set("hook_plugins.MythicLib",config_old.getBoolean("hook_plugins.MythicLib"));
config_new.set("expansion.groovy",config_old.getBoolean("expansion.groovy"));
config_new.set("debug",config_old.getBoolean("debug"));
config_new.set("advanced_setting.world_env_fix",config_old.getBoolean("advanced_setting.world_env_fix"));
config_new.set("advanced_setting.save_respawn_status",config_old.getBoolean("advanced_setting.save_respawn_status"));
config_new.set("save_bossbar",config_old.getBoolean("save_bossbar"));
config_new.set("backslash_split.reward",config_old.getBoolean("backslash_split.reward"));
config_new.save(config_new_F);
boolean chinese = "Chinese".equals(config_old.getString("lang"));
File folder = new File(plugin.getDataFolder(),"setting");
if(folder.exists()){
File[] files = folder.listFiles();
if(files != null){
for(File file : files){
FileConfiguration config = YamlConfiguration.loadConfiguration(file);
String ver = config.getString("version");
if(!"2.2.0".equals(ver)) {
Lang.error("The version of setting/"+file.getName()+" is not supported!");
continue;
}
String name = file.getName();
Config.copyFile("setting/"+name,"new/setting/"+name,true);
}
File new_folder = new File(plugin.getDataFolder(),"new/setting/");
files = new_folder.listFiles();
if(files != null){
for(File file : files){
FileOutputStream out = new FileOutputStream(file,true);
if (chinese){
out.write(("\n\n" +
"# 一些特殊的战利品\n" +
"special_loot:\n" +
" # 你可以按格式添加更多条目,但是名称不能重复\n" +
" # 如果找不到执行目标(target),所在战利品条目会被忽略\n" +
" # 目前支持的type: exp(经验), command(执行指令,可解析伤害排名)\n" +
" loot1:\n" +
" # [true/false]\n" +
" enable: false\n" +
" type: command\n" +
" # %attacker% -> 所有参与屠龙的玩家\n" +
" target: \"%attacker%\"\n" +
" # %player% -> 目标, %damage% -> 该玩家造成的总伤害\n" +
" data:\n" +
" - 'give %player% stone 1'\n" +
" - 'ed action %player% tell: 你获得了保底奖励.'\n" +
" loot2:\n" +
" enable: false\n" +
" type: command\n" +
" # %attacker_top_<rank>% -> 在屠龙中取得此排名的玩家\n" +
" target: \"%attacker_top_1%\"\n" +
" data:\n" +
" - 'ed action %player% tell: 你的伤害占比是最高的!'\n" +
" - 'ed action %player% tell: 你造成的伤害: %damage%'\n" +
" loot_exp1:\n" +
" enable: false\n" +
" type: exp\n" +
" target: \"%attacker_top_2%\"\n" +
" data:\n" +
" # 给予排名第二的玩家20点经验\n" +
" amount: 20\n" +
"\n\n"
).getBytes());
}
else{
out.write(("\n\n" +
"special_loot:\n" +
" # You can add more entries with DIFFERENT name according to the format.\n" +
" # If such target not exists, this option will be ignored.\n" +
" # type: exp, command\n" +
" loot1:\n" +
" # [true/false]\n" +
" enable: false\n" +
" type: command\n" +
" # %attacker% -> all participants in dragon slaying\n" +
" target: \"%attacker%\"\n" +
" # %player% -> target, %damage% -> this player's damage to EnderDragon\n" +
" data:\n" +
" - 'give %player% stone 1'\n" +
" - 'ed action %player% tell: This is a guaranteed reward.'\n" +
" loot2:\n" +
" enable: false\n" +
" type: command\n" +
" # %attacker_top_<rank>% -> the player with exactly this rank\n" +
" target: \"%attacker_top_1%\"\n" +
" data:\n" +
" - 'ed action %player% tell: You are the one who causes the highest damage!'\n" +
" - 'ed action %player% tell: Your damage: %damage%'\n" +
" loot_exp1:\n" +
" enable: false\n" +
" type: exp\n" +
" target: \"%attacker_top_2%\"\n" +
" data:\n" +
" # add 20 exp for the rank_2 player\n" +
" amount: 20\n" +
"\n\n"
).getBytes());
}
out.close();
FileConfiguration fc = YamlConfiguration.loadConfiguration(file);
fc.set("version","2.4.0");
fc.save(file);
}
}
}
}
else Lang.error("The version of config.yml is not supported!");
Lang.info("New config files are generated in plugins/EnderDragon/new.");
Lang.warn("Attention: Please confirm the accuracy before using new config!");
}
@@ -6,7 +6,8 @@ import org.bukkit.entity.EnderDragon;
import org.bukkit.event.HandlerList;
import org.bukkit.event.entity.CreatureSpawnEvent;
import pers.xanadu.enderdragon.manager.DragonManager;
import pers.xanadu.enderdragon.util.MyDragon;
import pers.xanadu.enderdragon.metadata.DragonInfo;
/**
* Called when a dragon is spawned, filtered through blacklist.
* <p>
@@ -16,11 +17,11 @@ public final class DragonRespawnPostEvent extends CreatureSpawnEvent {
private static final HandlerList handlers = new HandlerList();
private boolean cancel = false;
private final World world;
private final MyDragon myDragon;
public DragonRespawnPostEvent(final EnderDragon dragon, final SpawnReason reason, final MyDragon myDragon) {
private final DragonInfo info;
public DragonRespawnPostEvent(final EnderDragon dragon, final SpawnReason reason, final DragonInfo dragonInfo) {
super(dragon,reason);
world = dragon.getWorld();
this.myDragon = myDragon;
this.info = dragonInfo;
}
public EnderDragon getEnderDragon(){
@@ -30,11 +31,8 @@ public final class DragonRespawnPostEvent extends CreatureSpawnEvent {
public Location getEndPortalLocation(){
return DragonManager.getEndPortalLocation(world);
}
public MyDragon getDragonConfiguration(){
return myDragon;
}
public String getDragonUniqueId(){
return myDragon.unique_name;
public DragonInfo getDragonInformation(){
return info;
}
public static HandlerList getHandlerList() {
return handlers;
@@ -12,8 +12,9 @@ import pers.xanadu.enderdragon.manager.DragonManager;
import pers.xanadu.enderdragon.manager.ItemManager;
import pers.xanadu.enderdragon.gui.slot.EmptySlot;
import pers.xanadu.enderdragon.gui.slot.ItemSlot;
import pers.xanadu.enderdragon.manager.RewardManager;
import pers.xanadu.enderdragon.reward.Reward;
import pers.xanadu.enderdragon.util.MyDragon;
import pers.xanadu.enderdragon.metadata.MyDragon;
import java.util.ArrayList;
import java.util.HashSet;
@@ -117,7 +118,7 @@ public class GUI {
resetPagedItem(key,cmd);
}
else if(type == 2){
for(MyDragon myDragon : DragonManager.dragons){
for(MyDragon myDragon : DragonManager.get_dragons()){
this.addDragon(myDragon.icon.clone(),myDragon.unique_name);
}
}
@@ -125,9 +126,9 @@ public class GUI {
}
public void resetPagedItem(String key,boolean cmd){
this.pagedItems.clear();
MyDragon dragon = DragonManager.mp.get(key);
if(dragon == null) return;
for(Reward reward : dragon.datum){
List<Reward> rewards = RewardManager.getRewards(key);
if(rewards == null) return;
for(Reward reward : rewards){
if(Config.debug) Bukkit.getLogger().info(reward.toString());
//if(ItemManager.isEmpty(reward.getItem())) continue;
ItemStack item = reward.getItem().clone();
@@ -8,7 +8,7 @@ import org.bukkit.event.entity.EntityDamageByEntityEvent;
import org.bukkit.potion.PotionEffect;
import pers.xanadu.enderdragon.manager.DragonManager;
import pers.xanadu.enderdragon.util.ExtraPotionEffect;
import pers.xanadu.enderdragon.util.MyDragon;
import pers.xanadu.enderdragon.metadata.MyDragon;
public class DragonAttackListener implements Listener {
@EventHandler(priority = EventPriority.LOW)
@@ -19,7 +19,7 @@ public class DragonAttackListener implements Listener {
EnderDragon dragon = (EnderDragon) attack;
String unique_name = DragonManager.getSpecialKey(dragon);
if(unique_name == null) return;
MyDragon myDragon = DragonManager.mp.get(unique_name);
MyDragon myDragon = DragonManager.get_dragon_config(unique_name);
if(myDragon == null) return;
e.setDamage(Math.max(0.1, e.getDamage() + myDragon.attack_damage_modify));
if(victim instanceof Player){
@@ -19,12 +19,15 @@ import pers.xanadu.enderdragon.config.Lang;
import pers.xanadu.enderdragon.manager.DamageManager;
import pers.xanadu.enderdragon.manager.DragonManager;
import pers.xanadu.enderdragon.manager.TimerManager;
import pers.xanadu.enderdragon.util.MyDragon;
import pers.xanadu.enderdragon.metadata.MyDragon;
import pers.xanadu.enderdragon.reward.SpecialLoot;
import pers.xanadu.enderdragon.util.Pair;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.concurrent.ThreadLocalRandom;
import static pers.xanadu.enderdragon.EnderDragon.*;
@@ -36,7 +39,7 @@ public class DragonDeathListener implements Listener {
EnderDragon dragon = (EnderDragon) e.getEntity();
String unique_name = DragonManager.getSpecialKey(dragon);
if(unique_name == null) return;
MyDragon myDragon = DragonManager.mp.get(unique_name);
MyDragon myDragon = DragonManager.get_dragon_config(unique_name);
if(myDragon == null) return;
int times = data.getInt("times");
data.set("times",times+1);
@@ -80,6 +83,7 @@ public class DragonDeathListener implements Listener {
}
}
handleBroadcast(processed,myDragon,dragon);
handleSpecialLoot(myDragon,dragon);
}
DamageManager.data.remove(dragon.getUniqueId());
Lang.runCommands(myDragon.death_cmd,p);
@@ -90,6 +94,27 @@ public class DragonDeathListener implements Listener {
}
TimerManager.startTimer(dragon.getWorld().getName());
}
private static void handleSpecialLoot(final MyDragon myDragon, final EnderDragon dragon){
List<Pair<String,Double>> list = DamageManager.getDamageList(dragon.getUniqueId());
list.sort(DamageManager::sortByDamage);
Set<String> online_players = new HashSet<>();
Bukkit.getOnlinePlayers().forEach(player -> online_players.add(player.getName()));
List<SpecialLoot> participants = myDragon.lootMap.get(0);
boolean tag = participants != null;
int size = list.size();
for(int i=0;i<size;i++){
Pair<String,Double> pair = list.get(i);
String name = pair.first;
//玩家不在线
if(!online_players.contains(name)) continue;
String damage = String.format("%.2f",pair.second);
//所有参与者
if(tag) participants.forEach(loot -> loot.accept(name,damage));
//针对特殊名次
List<SpecialLoot> loots = myDragon.lootMap.get(i+1);
if(loots!=null) loots.forEach(loot -> loot.accept(name,damage));
}
}
public static void handleBroadcast(final List<String> list,final MyDragon myDragon,final EnderDragon dragon){
boolean find = false;
for(String str : list){
@@ -1,24 +1,18 @@
package pers.xanadu.enderdragon.listener;
import org.bukkit.Bukkit;
import org.bukkit.Color;
import org.bukkit.Particle;
import org.bukkit.entity.AreaEffectCloud;
import org.bukkit.entity.DragonFireball;
import org.bukkit.entity.EnderDragon;
import org.bukkit.entity.Projectile;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.Listener;
import org.bukkit.event.entity.EnderDragonChangePhaseEvent;
import org.bukkit.event.entity.EntitySpawnEvent;
import org.bukkit.event.entity.ProjectileLaunchEvent;
import org.bukkit.potion.PotionEffect;
import org.bukkit.projectiles.ProjectileSource;
import pers.xanadu.enderdragon.util.MyDragon;
import pers.xanadu.enderdragon.manager.DragonManager;
import pers.xanadu.enderdragon.metadata.MyDragon;
import static pers.xanadu.enderdragon.manager.DragonManager.getSpecialKey;
import static pers.xanadu.enderdragon.manager.DragonManager.mp;
public class DragonFireballListener implements Listener {
@@ -49,7 +43,7 @@ public class DragonFireballListener implements Listener {
EnderDragon dragon = (EnderDragon) effectCloud.getSource();
String unique_name = getSpecialKey(dragon);
if(unique_name == null) return;
MyDragon myDragon = mp.get(unique_name);
MyDragon myDragon = DragonManager.get_dragon_config(unique_name);
if(myDragon == null) return;
effectCloud.setRadius((float) myDragon.effect_cloud_original_radius);
effectCloud.setRadiusPerTick((float) myDragon.effect_cloud_expand_speed/20f);
@@ -5,10 +5,10 @@ import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.Listener;
import org.bukkit.event.entity.EntityRegainHealthEvent;
import pers.xanadu.enderdragon.util.MyDragon;
import pers.xanadu.enderdragon.manager.DragonManager;
import pers.xanadu.enderdragon.metadata.MyDragon;
import static pers.xanadu.enderdragon.manager.DragonManager.getSpecialKey;
import static pers.xanadu.enderdragon.manager.DragonManager.mp;
public class DragonHealListener implements Listener {
@EventHandler(priority = EventPriority.HIGH)
@@ -18,7 +18,7 @@ public class DragonHealListener implements Listener {
if(!e.getRegainReason().equals(EntityRegainHealthEvent.RegainReason.ENDER_CRYSTAL)) return;
String unique_name = getSpecialKey(dragon);
if(unique_name == null) return;
MyDragon myDragon = mp.get(unique_name);
MyDragon myDragon = DragonManager.get_dragon_config(unique_name);
if(myDragon == null) return;
e.setAmount(myDragon.crystal_heal_speed / 2d);
}
@@ -14,7 +14,8 @@ import pers.xanadu.enderdragon.config.Config;
import pers.xanadu.enderdragon.config.Lang;
import pers.xanadu.enderdragon.event.DragonRespawnPostEvent;
import pers.xanadu.enderdragon.manager.DamageManager;
import pers.xanadu.enderdragon.util.MyDragon;
import pers.xanadu.enderdragon.metadata.DragonInfo;
import pers.xanadu.enderdragon.metadata.MyDragon;
import pers.xanadu.enderdragon.util.Version;
import java.util.*;
@@ -40,6 +41,15 @@ public class DragonSpawnListener implements Listener {
Lang.warn("special_dragon_jude_mode setting error!");
return;
}
DragonInfo info = new DragonInfo(myDragon.unique_name);
Bukkit.getPluginManager().callEvent(new DragonRespawnPostEvent(dragon,e.getSpawnReason(),info));
MyDragon update = getFromInfo(info);
if(update == null) {
Lang.error("Unknown unique_name in DragonInfo: "+info.unique_name);
}
else{
myDragon = update;
}
setSpecialKey(dragon, myDragon.unique_name);
DamageManager.data.put(dragon.getUniqueId(),new ConcurrentHashMap<>());
int times = data.getInt("times");
@@ -73,7 +83,6 @@ public class DragonSpawnListener implements Listener {
else if(Version.mcMainVersion >= 12){
getInstance().getBossBarManager().setBossBar(dragon.getWorld(),myDragon.display_name,bossBar_color,bossBar_style);
}
Bukkit.getPluginManager().callEvent(new DragonRespawnPostEvent(dragon,e.getSpawnReason(),myDragon));
if(Config.advanced_setting_save_bossbar){
getInstance().getBossBarManager().saveBossBarData(Collections.singletonList(dragon.getWorld()));
}
@@ -17,7 +17,7 @@ import pers.xanadu.enderdragon.gui.slot.PageJumpSlot;
import pers.xanadu.enderdragon.manager.DragonManager;
import pers.xanadu.enderdragon.manager.GuiManager;
import pers.xanadu.enderdragon.manager.RewardManager;
import pers.xanadu.enderdragon.util.MyDragon;
import pers.xanadu.enderdragon.metadata.MyDragon;
public class InventoryListener implements Listener {
@EventHandler(priority = EventPriority.LOWEST)
@@ -65,7 +65,7 @@ public class InventoryListener implements Listener {
}
if(type == GUISlotType.DRAGON_SLOT){
String unique_name = guiWrapper.getData(guiWrapper.getPage(),e.getRawSlot());
MyDragon dragon = DragonManager.mp.get(unique_name);
MyDragon dragon = DragonManager.get_dragon_config(unique_name);
if(dragon == null){
Lang.sendFeedback(p,Lang.gui_not_found);
return;
@@ -98,7 +98,7 @@ public class InventoryListener implements Listener {
}
if(type == GUISlotType.DRAGON_SLOT){
String unique_name = guiWrapper.getData(guiWrapper.getPage(),e.getRawSlot());
MyDragon dragon = DragonManager.mp.get(unique_name);
MyDragon dragon = DragonManager.get_dragon_config(unique_name);
if(dragon == null){
Lang.sendFeedback(p,Lang.gui_not_found);
return;
@@ -1,5 +1,7 @@
package pers.xanadu.enderdragon.manager;
import org.bukkit.Bukkit;
import org.bukkit.entity.Entity;
import pers.xanadu.enderdragon.util.Pair;
import java.util.ArrayList;
@@ -22,4 +24,13 @@ public class DamageManager {
return -1;
}
public static void gc(){
for(UUID uuid : DamageManager.data.keySet()){
Entity entity = Bukkit.getEntity(uuid);
if(entity == null || entity.isDead()) DamageManager.data.remove(uuid);
}
}
}
@@ -6,17 +6,21 @@ import org.bukkit.attribute.AttributeInstance;
import org.bukkit.attribute.AttributeModifier;
import org.bukkit.boss.DragonBattle;
import org.bukkit.command.CommandSender;
import org.bukkit.configuration.ConfigurationSection;
import org.bukkit.configuration.file.FileConfiguration;
import org.bukkit.configuration.file.YamlConfiguration;
import org.bukkit.entity.*;
import org.bukkit.potion.PotionEffect;
import org.bukkit.potion.PotionEffectType;
import org.bukkit.scheduler.BukkitRunnable;
import org.jetbrains.annotations.Nullable;
import pers.xanadu.enderdragon.config.Config;
import pers.xanadu.enderdragon.config.Lang;
import pers.xanadu.enderdragon.metadata.DragonInfo;
import pers.xanadu.enderdragon.reward.RewardDist;
import pers.xanadu.enderdragon.reward.SpecialLoot;
import pers.xanadu.enderdragon.util.ExtraPotionEffect;
import pers.xanadu.enderdragon.util.MyDragon;
import pers.xanadu.enderdragon.metadata.MyDragon;
import pers.xanadu.enderdragon.util.Version;
import java.io.File;
@@ -24,12 +28,14 @@ import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.*;
import java.util.concurrent.ThreadLocalRandom;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import static pers.xanadu.enderdragon.EnderDragon.*;
public class DragonManager {
public static ArrayList<MyDragon> dragons = new ArrayList<>();
public static HashMap<String, MyDragon> mp = new HashMap<>();
static final ArrayList<MyDragon> dragons = new ArrayList<>();
static final Map<String, MyDragon> mp = new HashMap<>();
public static List<String> dragon_names = new ArrayList<>();
private static int sum = 0;
private static final int[][] nxt = {{3,0},{0,3},{-3,0},{0,-3}};
@@ -42,6 +48,7 @@ public class DragonManager {
private static Method getX;
private static Method getY;
private static Method getZ;
private static final Pattern pattern_attacker_top = Pattern.compile("%attacker_top_(\\d+)%");
public static void reload(){
new BukkitRunnable(){
@@ -261,17 +268,97 @@ public class DragonManager {
}
myDragon.effect_cloud_potion = effectCloudPotions;
myDragon.reward_dist = RewardDist.parse(f.getConfigurationSection("reward_dist"));
ConfigurationSection loots = f.getConfigurationSection("special_loot");
Map<Integer, List<SpecialLoot>> loot_mp = new HashMap<>();
if(loots != null){
for (String key : loots.getKeys(false)) {
ConfigurationSection loot = loots.getConfigurationSection(key);
if(loot == null || !loot.getBoolean("enable")) continue;
String type = loot.getString("type");
SpecialLoot specialLoot;
if("command".equals(type)){
List<String> commands = loot.getStringList("data");
specialLoot = (player, damage) -> handleCommandLoot(commands,player,damage);
}
else if("exp".equals(type)){
int amount = loot.getInt("data"+f.options().pathSeparator()+"amount");
specialLoot = (player, __) -> {
Player p = Bukkit.getPlayer(player);
if(p != null) p.giveExp(amount);
};
}
else{
Lang.error("Unknown special_loot type: "+type);
continue;
}
String target = loot.getString("target");
if(target == null) continue;
if("%attacker%".equals(target)){
loot_mp.compute(0,(k,v)->{
if(v==null) return Collections.singletonList(specialLoot);
v.add(specialLoot);
return v;
});
}
else{
Matcher matcher = pattern_attacker_top.matcher(target);
if (matcher.find()) {
Integer rank = Integer.parseInt(matcher.group(1));
loot_mp.compute(rank,(k,v)->{
if(v==null) return Collections.singletonList(specialLoot);
v.add(specialLoot);
return v;
});
} else {
Lang.error("Wrong special_loot target: "+target);
continue;
}
}
}
}
myDragon.lootMap = loot_mp;
dragons.add(myDragon);
mp.put(myDragon.unique_name,myDragon);
dragon_names.add(myDragon.unique_name);
sum += edge;
}
private static void handleCommandLoot(List<String> list, String name, String damage){
if(list == null) return;
for (String cmd : list) {
if(cmd.equals("")) continue;
plugin.getServer().dispatchCommand(plugin.getServer().getConsoleSender(),cmd.replaceAll("%player%",name).replaceAll("%damage%",damage));
}
}
public static void disable(){
dragons.clear();
mp.clear();
dragon_names.clear();
}
/**
* 请勿修改MyDragon对象<p>
* 方法将在后续被删除
* @return MyDragon configuration
*/
@Deprecated
public static MyDragon get_dragon_config(String unique_name){
return mp.get(unique_name);
}
/**
* 请勿修改得到的List
*/
@Deprecated
public static List<MyDragon> get_dragons(){
return dragons;
}
@Nullable
public static MyDragon getFromInfo(DragonInfo info){
return mp.get(info.unique_name);
}
public static int getCount(){
return data.getInt("times");
}
public static void setAttribute(final EnderDragon dragon,final Attribute attribute, double amount){
AttributeInstance instance = dragon.getAttribute(attribute);
assert instance != null;
@@ -63,7 +63,6 @@ public class GroovyManager {
binding.setVariable("itemStack",player.getItemInHand());
binding.setVariable("world",player.getWorld());
GroovyShell shell = new GroovyShell(GroovyManager.class.getClassLoader(),binding,compilerConfig);
//Bukkit.broadcastMessage(lib);
return shell.evaluate(lib+expression);
}
@@ -10,7 +10,7 @@ import pers.xanadu.enderdragon.config.Config;
import pers.xanadu.enderdragon.config.Lang;
import pers.xanadu.enderdragon.reward.Reward;
import pers.xanadu.enderdragon.reward.Chance;
import pers.xanadu.enderdragon.util.MyDragon;
import pers.xanadu.enderdragon.metadata.MyDragon;
import java.io.File;
import java.io.FileNotFoundException;
@@ -101,6 +101,16 @@ public class RewardManager {
}
return false;
}
/**
* 请勿修改获取的List
* @return rewards of one type of dragon
*/
public static List<Reward> getRewards(String unique_name){
MyDragon dragon = DragonManager.mp.get(unique_name);
if(dragon == null) return null;
return dragon.datum;
}
private static File getRewardFile(String key){
String file_path = "reward/" + key + ".yml";
File file = new File(plugin.getDataFolder(),file_path);
@@ -0,0 +1,8 @@
package pers.xanadu.enderdragon.metadata;
public class DragonInfo {
public String unique_name;
public DragonInfo(String unique_name){
this.unique_name = unique_name;
}
}
@@ -1,12 +1,15 @@
package pers.xanadu.enderdragon.util;
package pers.xanadu.enderdragon.metadata;
import org.bukkit.inventory.ItemStack;
import org.bukkit.potion.PotionEffect;
import pers.xanadu.enderdragon.reward.Reward;
import pers.xanadu.enderdragon.reward.RewardDist;
import pers.xanadu.enderdragon.reward.SpecialLoot;
import pers.xanadu.enderdragon.util.ExtraPotionEffect;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
public class MyDragon implements Comparable<MyDragon>{
public ItemStack icon;
@@ -53,6 +56,7 @@ public class MyDragon implements Comparable<MyDragon>{
public List<PotionEffect> effect_cloud_potion;
public List<Reward> datum = new ArrayList<>();
public RewardDist reward_dist;
public Map<Integer, List<SpecialLoot>> lootMap;
@Override
public int compareTo(final MyDragon o) {
@@ -6,7 +6,7 @@ import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack;
import pers.xanadu.enderdragon.config.Lang;
import pers.xanadu.enderdragon.reward.dist.*;
import pers.xanadu.enderdragon.util.MyDragon;
import pers.xanadu.enderdragon.metadata.MyDragon;
import java.util.ArrayList;
import java.util.List;
@@ -0,0 +1,8 @@
package pers.xanadu.enderdragon.reward;
import java.util.function.BiConsumer;
@FunctionalInterface
public interface SpecialLoot extends BiConsumer<String,String> {
}
@@ -7,7 +7,7 @@ import org.bukkit.inventory.ItemStack;
import pers.xanadu.enderdragon.config.Lang;
import pers.xanadu.enderdragon.manager.DamageManager;
import pers.xanadu.enderdragon.reward.RewardDist;
import pers.xanadu.enderdragon.util.MyDragon;
import pers.xanadu.enderdragon.metadata.MyDragon;
import java.util.List;
import java.util.concurrent.ConcurrentHashMap;
@@ -11,7 +11,7 @@ import org.bukkit.inventory.ItemStack;
import org.bukkit.util.Vector;
import pers.xanadu.enderdragon.manager.GlowManager;
import pers.xanadu.enderdragon.reward.RewardDist;
import pers.xanadu.enderdragon.util.MyDragon;
import pers.xanadu.enderdragon.metadata.MyDragon;
import java.util.List;
import java.util.concurrent.ThreadLocalRandom;
@@ -5,7 +5,7 @@ import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack;
import pers.xanadu.enderdragon.config.Lang;
import pers.xanadu.enderdragon.reward.RewardDist;
import pers.xanadu.enderdragon.util.MyDragon;
import pers.xanadu.enderdragon.metadata.MyDragon;
import java.util.List;
@@ -9,7 +9,7 @@ import pers.xanadu.enderdragon.config.Lang;
import pers.xanadu.enderdragon.manager.DamageManager;
import pers.xanadu.enderdragon.reward.RewardDist;
import pers.xanadu.enderdragon.util.AExpJ;
import pers.xanadu.enderdragon.util.MyDragon;
import pers.xanadu.enderdragon.metadata.MyDragon;
import java.util.List;
import java.util.concurrent.ConcurrentHashMap;
@@ -8,7 +8,7 @@ import org.bukkit.inventory.ItemStack;
import pers.xanadu.enderdragon.config.Lang;
import pers.xanadu.enderdragon.manager.DamageManager;
import pers.xanadu.enderdragon.reward.RewardDist;
import pers.xanadu.enderdragon.util.MyDragon;
import pers.xanadu.enderdragon.metadata.MyDragon;
import java.util.List;
import java.util.Map;
@@ -8,7 +8,7 @@ import pers.xanadu.enderdragon.config.Lang;
import pers.xanadu.enderdragon.manager.DamageManager;
import pers.xanadu.enderdragon.reward.RewardDist;
import pers.xanadu.enderdragon.util.AliasSample;
import pers.xanadu.enderdragon.util.MyDragon;
import pers.xanadu.enderdragon.metadata.MyDragon;
import java.util.ArrayList;
import java.util.List;
@@ -9,7 +9,7 @@ import pers.xanadu.enderdragon.nms.WorldData.I_WorldDataManager;
import static org.bukkit.Bukkit.getServer;
public class Version {
public static final String setting_dragon = "2.2.0";
public static final String setting_dragon = "2.4.0";
public static final String lang = "2.2.0";
public static final String config = "2.3.0";
public static final String data = "2.2.0";
+1 -1
View File
@@ -1,5 +1,5 @@
name: EnderDragon
version: 2.3.0
version: 2.4.0
main: pers.xanadu.enderdragon.EnderDragon
author: Xanadu13
api-version: 1.13
+32 -1
View File
@@ -1,5 +1,5 @@
#文件版本,请勿修改
version: 2.2.0
version: 2.4.0
#用于插件内部识别,每一种末影龙的unique_name都需要设为不同值!
unique_name: 'default'
@@ -201,3 +201,34 @@ reward_dist:
rank:
# 排名前几可获得奖励
max_num: 1
# 一些特殊的战利品
special_loot:
# 你可以按格式添加更多条目,但是名称不能重复
# 如果找不到执行目标(target),所在战利品条目会被忽略
# 目前支持的type: exp(经验), command(执行指令,可解析伤害排名)
loot1:
# [true/false]
enable: false
type: command
# %attacker% -> 所有参与屠龙的玩家
target: "%attacker%"
# %player% -> 目标, %damage% -> 该玩家造成的总伤害
data:
- 'give %player% stone 1'
- 'ed action %player% tell: 你获得了保底奖励.'
loot2:
enable: false
type: command
# %attacker_top_<rank>% -> 在屠龙中取得此排名的玩家
target: "%attacker_top_1%"
data:
- 'ed action %player% tell: 你的伤害占比是最高的!'
- 'ed action %player% tell: 你造成的伤害: %damage%'
loot_exp1:
enable: false
type: exp
target: "%attacker_top_2%"
data:
# 给予排名第二的玩家20点经验
amount: 20
+32 -3
View File
@@ -1,4 +1,4 @@
version: 2.2.0
version: 2.4.0
#This is used for plugin internal identification.
#Please make sure the value is unique among all the types of dragons
@@ -154,7 +154,7 @@ effect_cloud:
#All the settings below can be disabled with a "[]".(Ex: spawn_cmd: [] )
#commands that server will run when this dragon spawn
#Attention: You shouldn't add “/” at the beginning of each command!
#Attention: Please DON'T add “/” at the beginning of each command!
spawn_cmd:
- ''
- ''
@@ -198,7 +198,7 @@ reward_dist:
# killer: Only give to the final killer.
# pack: Pack all items that trigger drop and distribute them to players weighted based on their damage percentage.
# rank: Strictly based on player damage ranking, give the top few players with the highest damage.
# termwise: Assign the items that trigger the drop ONE BY ONE to the player based on the weighted proportion of damage.
# termwise: Assign items that trigger the drop ONE BY ONE to the player based on the weighted proportion of damage.
type: killer
drop:
# Whether the dropped item glows.
@@ -211,3 +211,32 @@ reward_dist:
# Top few can receive rewards
max_num: 1
special_loot:
# You can add more entries with DIFFERENT name according to the format.
# If such target not exists, this option will be ignored.
# type: exp, command
loot1:
# [true/false]
enable: false
type: command
# %attacker% -> all participants in dragon slaying
target: "%attacker%"
# %player% -> target, %damage% -> this player's damage to EnderDragon
data:
- 'give %player% stone 1'
- 'ed action %player% tell: This is a guaranteed reward.'
loot2:
enable: false
type: command
# %attacker_top_<rank>% -> the player with exactly this rank
target: "%attacker_top_1%"
data:
- 'ed action %player% tell: You are the one who causes the highest damage!'
- 'ed action %player% tell: Your damage: %damage%'
loot_exp1:
enable: false
type: exp
target: "%attacker_top_2%"
data:
# add 20 exp for the rank_2 player
amount: 20
+32 -1
View File
@@ -1,5 +1,5 @@
#文件版本,请勿修改
version: 2.2.0
version: 2.4.0
#用于插件内部识别,每一种末影龙的unique_name都需要设为不同值!
unique_name: 'special001'
@@ -194,3 +194,34 @@ reward_dist:
rank:
# 排名前几可获得奖励
max_num: 1
# 一些特殊的战利品
special_loot:
# 你可以按格式添加更多条目,但是名称不能重复
# 如果找不到执行目标(target),所在战利品条目会被忽略
# 目前支持的type: exp(经验), command(执行指令,可解析伤害排名)
loot1:
# [true/false]
enable: false
type: command
# %attacker% -> 所有参与屠龙的玩家
target: "%attacker%"
# %player% -> 目标, %damage% -> 该玩家造成的总伤害
data:
- 'give %player% stone 1'
- 'ed action %player% tell: 你获得了保底奖励.'
loot2:
enable: false
type: command
# %attacker_top_<rank>% -> 在屠龙中取得此排名的玩家
target: "%attacker_top_1%"
data:
- 'ed action %player% tell: 你的伤害占比是最高的!'
- 'ed action %player% tell: 你造成的伤害: %damage%'
loot_exp1:
enable: false
type: exp
target: "%attacker_top_2%"
data:
# 给予排名第二的玩家20点经验
amount: 20
+31 -1
View File
@@ -1,7 +1,7 @@
## Special thanks to Phaxius for the translation
# File version, do not edit
version: 2.2.0
version: 2.4.0
# Unique ID used by plugin to identify each type of dragon
# unique_name needs to be different in each dragon settings file
@@ -230,3 +230,33 @@ reward_dist:
rank:
# Top few can receive rewards
max_num: 1
special_loot:
# You can add more entries with DIFFERENT name according to the format.
# If such target not exists, this option will be ignored.
# type: exp, command
loot1:
# [true/false]
enable: false
type: command
# %attacker% -> all participants in dragon slaying
target: "%attacker%"
# %player% -> target, %damage% -> this player's damage to EnderDragon
data:
- 'give %player% stone 1'
- 'ed action %player% tell: This is a guaranteed reward.'
loot2:
enable: false
type: command
# %attacker_top_<rank>% -> the player with exactly this rank
target: "%attacker_top_1%"
data:
- 'ed action %player% tell: You are the one who causes the highest damage!'
- 'ed action %player% tell: Your damage: %damage%'
loot_exp1:
enable: false
type: exp
target: "%attacker_top_2%"
data:
# add 20 exp for the rank_2 player
amount: 20