update to v2.1.0
This commit is contained in:
@@ -0,0 +1,392 @@
|
||||
package pers.xanadu.enderdragon.command;
|
||||
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.command.Command;
|
||||
import org.bukkit.command.CommandExecutor;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import pers.xanadu.enderdragon.config.Config;
|
||||
import pers.xanadu.enderdragon.config.Lang;
|
||||
import pers.xanadu.enderdragon.manager.DragonManager;
|
||||
import pers.xanadu.enderdragon.manager.GuiManager;
|
||||
import pers.xanadu.enderdragon.manager.RewardManager;
|
||||
import pers.xanadu.enderdragon.EnderDragon;
|
||||
import pers.xanadu.enderdragon.manager.TimerManager;
|
||||
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 org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.lang.reflect.Method;
|
||||
|
||||
import static pers.xanadu.enderdragon.EnderDragon.*;
|
||||
|
||||
public class MainCommand implements CommandExecutor {
|
||||
private Class<?> CraftItemStackClass;
|
||||
private Class<?> NBTTagCompoundClass;
|
||||
private Class<?> ItemStackClass_e;
|
||||
private Method asNMSCopy;
|
||||
private Method save;
|
||||
|
||||
@Override
|
||||
public boolean onCommand(@NotNull CommandSender sender, @NotNull Command command, @NotNull String label, String[] args) {
|
||||
if (args.length == 0) {
|
||||
sendCommandTips(sender);
|
||||
return false;
|
||||
}
|
||||
switch(args[0].toLowerCase()){
|
||||
// case "parse" : {
|
||||
// if(!(sender instanceof Player)) {
|
||||
// Lang.sendFeedback(sender,Lang.command_only_player);
|
||||
// return false;
|
||||
// }
|
||||
// Player p = (Player) sender;
|
||||
// if(sender.isOp()){
|
||||
//// List<Entity> entities = p.getNearbyEntities(50,50,50);
|
||||
//// entities.forEach(entity -> {
|
||||
//// if(entity instanceof org.bukkit.entity.EnderDragon){
|
||||
//// ScoreboardManager sm = server.getScoreboardManager();
|
||||
//// CraftScoreboardManager csm = (CraftScoreboardManager) sm;
|
||||
//// try {
|
||||
//// Field field = csm.getClass().getDeclaredField("scoreboards");
|
||||
//// field.setAccessible(true);
|
||||
//// Collection<CraftScoreboard> sbs = (Collection<CraftScoreboard>) field.get(csm);
|
||||
//// sbs.forEach(sb->{
|
||||
//// Team team = sb.getEntryTeam(entity.getUniqueId().toString());
|
||||
//// if(team!=null) Bukkit.broadcastMessage(team.getName());
|
||||
//// });
|
||||
//// } catch (ReflectiveOperationException e) {
|
||||
//// throw new RuntimeException(e);
|
||||
//// }
|
||||
//// }
|
||||
////// if(entity instanceof org.bukkit.entity.EnderDragon){
|
||||
////// Bukkit.broadcastMessage(entity.getName());//1 Special Ender Dragon
|
||||
////// }
|
||||
////// if(entity instanceof ComplexEntityPart){
|
||||
////// Bukkit.broadcastMessage(entity.getName());//1 Special Ender Dragon
|
||||
////// }
|
||||
////// if(entity instanceof ComplexLivingEntity){
|
||||
////// Bukkit.broadcastMessage(entity.getName());//8 EnderDragon
|
||||
////// }
|
||||
//// });
|
||||
// }
|
||||
// return true;
|
||||
// }
|
||||
case "reload" : {
|
||||
if(!sender.hasPermission("ed.reload")){
|
||||
Lang.sendFeedback(sender,Lang.command_no_permission);
|
||||
return false;
|
||||
}
|
||||
if(args.length == 1){
|
||||
closeAllInventory();
|
||||
reloadAll();
|
||||
Lang.sendFeedback(sender,Lang.command_reload_config);
|
||||
return true;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case "update" : {
|
||||
if(!sender.hasPermission("ed.update")){
|
||||
Lang.sendFeedback(sender,Lang.command_no_permission);
|
||||
return false;
|
||||
}
|
||||
if(args.length == 1){
|
||||
try {
|
||||
FileUpdater.update();
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case "respawn" : {//ed respawn [world_name]
|
||||
if(!sender.hasPermission("ed.respawn")){
|
||||
Lang.sendFeedback(sender,Lang.command_no_permission);
|
||||
return false;
|
||||
}
|
||||
if(args.length == 1){
|
||||
if(!(sender instanceof Player)){
|
||||
Lang.sendFeedback(sender,"§cConsole usage: /ed respawn <world_name>");
|
||||
return false;
|
||||
}
|
||||
Player player = (Player) sender;
|
||||
EnderDragon.getInstance().getDragonManager().initiateRespawn(player);
|
||||
return true;
|
||||
}
|
||||
else if(args.length == 2){
|
||||
String world_name = args[1];
|
||||
EnderDragon.getInstance().getDragonManager().initiateRespawn(sender,world_name);
|
||||
return true;
|
||||
}
|
||||
else {
|
||||
int size = args.length;
|
||||
StringBuilder builder = new StringBuilder(args[1]);
|
||||
for(int i=2;i<size;i++) builder.append(" ").append(args[i]);
|
||||
EnderDragon.getInstance().getDragonManager().initiateRespawn(sender,builder.toString());
|
||||
return true;
|
||||
}
|
||||
}
|
||||
case "respawn_cd" : {
|
||||
if(!sender.hasPermission("ed.respawn")){
|
||||
Lang.sendFeedback(sender,Lang.command_no_permission);
|
||||
return false;
|
||||
}
|
||||
if(!Config.respawn_cd_enable){
|
||||
Lang.sendFeedback(sender,Lang.command_respawn_cd_disable);
|
||||
return false;
|
||||
}
|
||||
//ed respawn_cd get <world_name>
|
||||
if(args.length == 3 && args[1].equalsIgnoreCase("get")){
|
||||
String world_name = args[2];
|
||||
DragonRespawnTimer timer = TimerManager.getTimer(world_name);
|
||||
String value = timer!=null?timer.toString():world_name+": null";
|
||||
Lang.sendFeedback(sender,value);
|
||||
return true;
|
||||
}
|
||||
//ed respawn_cd set <world_name> <delay:second>
|
||||
else if(args.length == 4 && args[1].equalsIgnoreCase("set")){
|
||||
String world_name = args[2];
|
||||
World world = Bukkit.getWorld(world_name);
|
||||
if(world == null){
|
||||
Lang.sendFeedback(sender,"§c"+DragonManager.DragonRespawnResult.world_not_found.getMessage());
|
||||
return false;
|
||||
}
|
||||
if(world.getEnvironment() != World.Environment.THE_END){
|
||||
Lang.sendFeedback(sender,"§c"+DragonManager.DragonRespawnResult.world_wrong_env.getMessage());
|
||||
return false;
|
||||
}
|
||||
int delay = Integer.parseInt(args[3]);
|
||||
TimerManager.setTimer(world_name,new DragonRespawnTimer(world_name,delay));
|
||||
TimerManager.save();
|
||||
Lang.sendFeedback(sender,Lang.command_respawn_cd_set.replaceAll("\\{second}",args[3]));
|
||||
return true;
|
||||
}
|
||||
//ed respawn_cd removeAll
|
||||
else if(args.length == 2 && args[1].equalsIgnoreCase("removeAll")){
|
||||
TimerManager.removeAll();
|
||||
TimerManager.save();
|
||||
Lang.sendFeedback(sender,Lang.command_respawn_cd_removeAll);
|
||||
return true;
|
||||
}
|
||||
//ed respawn_cd remove <world_name>
|
||||
else if(args.length == 3 && args[1].equalsIgnoreCase("remove")){
|
||||
String world_name = args[2];
|
||||
TimerManager.removeTimer(world_name);
|
||||
TimerManager.save();
|
||||
Lang.sendFeedback(sender,Lang.command_respawn_cd_remove.replaceAll("\\{world}",world_name));
|
||||
return true;
|
||||
}
|
||||
//ed respawn_cd start <world_name>
|
||||
else if(args.length == 3 && args[1].equalsIgnoreCase("start")){
|
||||
String world_name = args[2];
|
||||
DragonRespawnTimer timer = TimerManager.getTimer(world_name);
|
||||
if(timer == null){
|
||||
Lang.sendFeedback(sender,Lang.command_respawn_cd_start_none);
|
||||
return false;
|
||||
}
|
||||
if(timer.isRunning()){
|
||||
Lang.sendFeedback(sender,Lang.command_respawn_cd_start_already_started);
|
||||
return false;
|
||||
}
|
||||
TimerManager.startTimer(world_name);
|
||||
Lang.sendFeedback(sender,Lang.command_respawn_cd_start_succeed);
|
||||
return true;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case "drop" : {
|
||||
if(!(sender instanceof Player)) {
|
||||
Lang.sendFeedback(sender,Lang.command_only_player);
|
||||
return false;
|
||||
}
|
||||
Player p = (Player) sender;
|
||||
switch (args[1].toLowerCase()){
|
||||
case "gui" : {
|
||||
if(!sender.hasPermission("ed.drop.gui")){
|
||||
Lang.sendFeedback(sender,Lang.command_no_permission);
|
||||
return false;
|
||||
}
|
||||
if(args.length == 2){
|
||||
GuiManager.openGui(p, Config.main_gui,false);
|
||||
return true;
|
||||
}
|
||||
if(args.length == 3){
|
||||
String key = args[2];
|
||||
MyDragon dragon = DragonManager.mp.get(key);
|
||||
if(dragon == null){
|
||||
Lang.sendFeedback(sender, Lang.dragon_not_found);
|
||||
return false;
|
||||
}
|
||||
GuiManager.openGui(p,dragon.drop_gui,key,false);
|
||||
return true;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case "clear" : {
|
||||
if(!sender.hasPermission("ed.drop.edit")){
|
||||
Lang.sendFeedback(sender,Lang.command_no_permission);
|
||||
return false;
|
||||
}
|
||||
if(args.length == 3) {
|
||||
String key = args[2];
|
||||
RewardManager.clearItem(key);
|
||||
Lang.sendFeedback(sender,Lang.command_drop_item_clear);
|
||||
return true;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case "add" : {
|
||||
if(!sender.hasPermission("ed.drop.edit")){
|
||||
Lang.sendFeedback(sender,Lang.command_no_permission);
|
||||
return false;
|
||||
}
|
||||
if(args.length == 4) {
|
||||
if(p.getInventory().getItemInMainHand().getType() == Material.AIR){
|
||||
Lang.sendFeedback(p, Lang.command_drop_item_add_empty);
|
||||
return false;
|
||||
}
|
||||
String ChanceStr = args[3];
|
||||
String key = args[2];
|
||||
double chance = -1;
|
||||
try {
|
||||
chance = Double.parseDouble(ChanceStr);
|
||||
} catch (NumberFormatException ex){
|
||||
Lang.sendFeedback(p,Lang.command_drop_item_add_invalid_chance + ChanceStr);
|
||||
return false;
|
||||
}
|
||||
if(chance <= 0) {
|
||||
Lang.sendFeedback(p,Lang.command_drop_item_add_invalid_chance + ChanceStr);
|
||||
return false;
|
||||
}
|
||||
if(chance > 100) chance = 100;
|
||||
ItemStack item = p.getItemInHand().clone();
|
||||
RewardManager.addItem(key,item,new Chance(chance,ChanceStr));
|
||||
Lang.sendFeedback(p,Lang.command_drop_item_add_succeed.replaceAll("\\{chance}",ChanceStr));
|
||||
return true;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case "edit" : {
|
||||
if(!sender.hasPermission("ed.drop.edit")){
|
||||
Lang.sendFeedback(sender,Lang.command_no_permission);
|
||||
return false;
|
||||
}
|
||||
if(args.length == 2){
|
||||
GuiManager.openGui(p, Config.main_gui,true);
|
||||
return true;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case "remove" : {
|
||||
if(!sender.hasPermission("ed.drop.edit")){
|
||||
Lang.sendFeedback(sender,Lang.command_no_permission);
|
||||
return false;
|
||||
}
|
||||
if(args.length == 4) {
|
||||
try{
|
||||
int idx = Integer.parseInt(args[3]);
|
||||
boolean b = RewardManager.removeItem(args[2],idx);
|
||||
if(b) Lang.sendFeedback(sender,Lang.command_drop_item_remove_succeed);
|
||||
else Lang.sendFeedback(sender,Lang.command_drop_item_remove_fail);
|
||||
return true;
|
||||
}catch (NumberFormatException e){
|
||||
Lang.sendFeedback(sender,Lang.command_drop_item_remove_invalid_num+args[3]);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
default : break;
|
||||
}
|
||||
}
|
||||
}
|
||||
sendCommandTips(sender);
|
||||
return false;
|
||||
}
|
||||
private static void sendCommandTips(CommandSender sender){
|
||||
sender.sendMessage(Lang.CommandTips1);
|
||||
sender.sendMessage(Lang.CommandTips2);
|
||||
sender.sendMessage(Lang.CommandTips3);
|
||||
sender.sendMessage(Lang.CommandTips4);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
// 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());
|
||||
@@ -0,0 +1,81 @@
|
||||
package pers.xanadu.enderdragon.command;
|
||||
|
||||
import org.bukkit.command.Command;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import pers.xanadu.enderdragon.manager.DragonManager;
|
||||
import pers.xanadu.enderdragon.manager.WorldManager;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
public class TabCompleter implements org.bukkit.command.TabCompleter {
|
||||
|
||||
private static final List<String> arguments_ed = Arrays.asList("drop", "reload", "respawn", "respawn_cd", "update");
|
||||
private static final List<String> arguments_drop = Arrays.asList("add", "clear", "edit", "remove", "gui");
|
||||
private static final List<String> arguments_respawn_cd = Arrays.asList("get","remove","removeAll","set","start");
|
||||
|
||||
@Override
|
||||
public List<String> onTabComplete(@NotNull CommandSender sender, @NotNull Command command, @NotNull String label, String[] args) {
|
||||
|
||||
List<String> result = new ArrayList<>();
|
||||
if (args.length == 1) {
|
||||
for (String s : arguments_ed) {
|
||||
if (s.toLowerCase().startsWith(args[0].toLowerCase())) {
|
||||
result.add(s);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
else if (args.length == 2){
|
||||
if(args[0].equalsIgnoreCase("drop")) {
|
||||
for (String s : arguments_drop) {
|
||||
if (s.toLowerCase().startsWith(args[1].toLowerCase())) {
|
||||
result.add(s);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if(args[0].equalsIgnoreCase("respawn")){
|
||||
for(String s : WorldManager.worlds){
|
||||
if (s.toLowerCase().startsWith(args[1].toLowerCase())) {
|
||||
result.add(s);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if(args[0].equalsIgnoreCase("respawn_cd")){
|
||||
for(String s : arguments_respawn_cd){
|
||||
if (s.toLowerCase().startsWith(args[1].toLowerCase())) {
|
||||
result.add(s);
|
||||
}
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
else if(args.length == 3){
|
||||
if("drop".equals(args[0])){
|
||||
String str = args[1].toLowerCase();
|
||||
if("add".equals(str) || "clear".equals(str) || "gui".equals(str) || "remove".equals(str)){
|
||||
for (String s : DragonManager.dragon_names) {
|
||||
if (s.toLowerCase().startsWith(args[2].toLowerCase())) {
|
||||
result.add(s);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else if("respawn_cd".equals(args[0])){
|
||||
String str = args[1].toLowerCase();
|
||||
if("get".equals(str) || "remove".equals(str) || "removeAll".equals(str) || "set".equals(str) || "start".equals(str)){
|
||||
for (String s : WorldManager.worlds) {
|
||||
if (s.toLowerCase().startsWith(args[2].toLowerCase())) {
|
||||
result.add(s);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,122 @@
|
||||
package pers.xanadu.enderdragon.config;
|
||||
|
||||
import org.bukkit.configuration.ConfigurationSection;
|
||||
import org.bukkit.configuration.file.FileConfiguration;
|
||||
|
||||
import java.io.*;
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.Type;
|
||||
import java.nio.file.Files;
|
||||
import java.util.*;
|
||||
|
||||
import static pers.xanadu.enderdragon.EnderDragon.plugin;
|
||||
import static pers.xanadu.enderdragon.config.Lang.error;
|
||||
|
||||
public class Config {
|
||||
public static String version;
|
||||
public static String lang;
|
||||
public static boolean debug;
|
||||
public static boolean advanced_setting_world_env_fix;
|
||||
public static boolean advanced_setting_save_respawn_status;
|
||||
public static boolean advanced_setting_glowing_fix;
|
||||
public static String damage_visible_mode;
|
||||
public static int damage_statistics_limit;
|
||||
public static String special_dragon_jude_mode;
|
||||
public static boolean auto_respawn_enable;
|
||||
public static String auto_respawn_world_the_end_name;
|
||||
public static String auto_respawn_respawn_time;
|
||||
public static boolean auto_respawn_invulnerable;
|
||||
public static boolean respawn_cd_enable;
|
||||
public static boolean resist_player_respawn;
|
||||
public static boolean resist_dragon_breath_gather;
|
||||
public static boolean hook_plugins_MythicLib;
|
||||
public static String main_gui;
|
||||
public static String item_format_data;
|
||||
public static List<String> dragon_setting_file;
|
||||
public static List<String> blacklist_worlds;
|
||||
public static void reload(FileConfiguration file){
|
||||
Field[] fields = Config.class.getFields();
|
||||
for(Field field : fields){
|
||||
Type type = field.getType();
|
||||
if(type.equals(java.lang.String.class)){
|
||||
try{
|
||||
field.set(null,"");
|
||||
}catch (Exception ignored){}
|
||||
}
|
||||
else if(type.equals(java.util.List.class)){
|
||||
try{
|
||||
field.set(null,new ArrayList());
|
||||
}catch (Exception ignored){}
|
||||
}
|
||||
}
|
||||
Iterator<String> it = file.getKeys(true).iterator();
|
||||
while (it.hasNext()){
|
||||
String str = it.next();
|
||||
try{
|
||||
if(file.isConfigurationSection(str)) continue;
|
||||
Config.class.getField(str.replace(".","_")).set(null, file.get(str));
|
||||
}catch (Exception e){
|
||||
error("Config loading error! Key: "+str);
|
||||
}
|
||||
}
|
||||
switch (special_dragon_jude_mode.toLowerCase()){
|
||||
case "pc" :
|
||||
case "weight" : break;
|
||||
default: {
|
||||
error("Wrong special_dragon_jude_mode type in config.yml! Only \"weight\" or \"pc\" is valid.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static void saveResource(String source,String to,boolean replace){
|
||||
if (source == null || source.equals("")) return;
|
||||
source = source.replace('\\', '/');
|
||||
InputStream in = plugin.getResource(source);
|
||||
if (in == null) return;
|
||||
File outFile = new File("plugins/EnderDragon", to);
|
||||
int lastIndex = to.lastIndexOf('/');
|
||||
File outDir = new File("plugins/EnderDragon", to.substring(0, Math.max(lastIndex, 0)));
|
||||
if (!outDir.exists()) {
|
||||
outDir.mkdirs();
|
||||
}
|
||||
try {
|
||||
if (!outFile.exists() || replace) {
|
||||
OutputStream out = new FileOutputStream(outFile);
|
||||
byte[] buf = new byte[1024];
|
||||
int len;
|
||||
while ((len = in.read(buf)) > 0) {
|
||||
out.write(buf, 0, len);
|
||||
}
|
||||
out.close();
|
||||
in.close();
|
||||
}
|
||||
} catch (IOException ignored) {}
|
||||
}
|
||||
public static void copyFile(String source, String dest,boolean replace) {
|
||||
if (source == null || source.equals("")) return;
|
||||
source = source.replace('\\', '/');
|
||||
File inFile = new File("plugins/EnderDragon", source);
|
||||
File outFile = new File("plugins/EnderDragon", dest);
|
||||
int lastIndex = dest.lastIndexOf('/');
|
||||
File outDir = new File("plugins/EnderDragon", dest.substring(0, Math.max(lastIndex, 0)));
|
||||
if (!outDir.exists()) {
|
||||
outDir.mkdirs();
|
||||
}
|
||||
try {
|
||||
if (!outFile.exists() || replace) {
|
||||
InputStream in = new FileInputStream(inFile);
|
||||
OutputStream out = new FileOutputStream(outFile);
|
||||
byte[] buf = new byte[1024];
|
||||
int len;
|
||||
while ((len = in.read(buf)) > 0) {
|
||||
out.write(buf, 0, len);
|
||||
}
|
||||
out.close();
|
||||
in.close();
|
||||
}
|
||||
} catch (IOException ignored) {
|
||||
Lang.error("Failed to copy file: "+inFile.getPath()+" -> "+outFile.getPath());
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,123 @@
|
||||
package pers.xanadu.enderdragon.config;
|
||||
|
||||
import org.bukkit.configuration.file.FileConfiguration;
|
||||
import org.bukkit.configuration.file.YamlConfiguration;
|
||||
import pers.xanadu.enderdragon.manager.DragonManager;
|
||||
import pers.xanadu.enderdragon.EnderDragon;
|
||||
import pers.xanadu.enderdragon.util.MyDragon;
|
||||
|
||||
import java.io.*;
|
||||
import java.util.List;
|
||||
|
||||
import static pers.xanadu.enderdragon.EnderDragon.*;
|
||||
|
||||
public class FileUpdater {
|
||||
public static void update() throws IOException {
|
||||
FileConfiguration config_old = plugin.getConfig();
|
||||
if("2.0.4".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"));
|
||||
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"));
|
||||
config_new.set("auto_respawn.enable",config_old.getBoolean("auto_respawn.enable"));
|
||||
config_new.set("auto_respawn.world_the_end_name",config_old.getString("auto_respawn.world_the_end_name"));
|
||||
config_new.set("auto_respawn.respawn_time",config_old.getString("auto_respawn.respawn_time"));
|
||||
config_new.set("auto_respawn.invulnerable",config_old.getBoolean("auto_respawn.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.save(config_new_F);
|
||||
}
|
||||
else Lang.error("The version of config.yml is not supported!");
|
||||
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.0.1".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);
|
||||
out.write(("\n\n" +
|
||||
"reward_dist:\n" +
|
||||
" # enable: [all,drop,killer,pack,rank,termwise]\n" +
|
||||
" # all: Give to all participants in dragon slaying.\n" +
|
||||
" # drop: Dropped item, players can grab it casually.\n" +
|
||||
" # killer: Only give to the final killer.\n" +
|
||||
" # pack: Pack all items that trigger drop and distribute them to players weighted based on their damage percentage.\n" +
|
||||
" # rank: Strictly based on player damage ranking, give the top few players with the highest damage.\n" +
|
||||
" # termwise: Assign the items that trigger the drop ONE BY ONE to the player based on the weighted proportion of damage.\n" +
|
||||
" type: killer\n" +
|
||||
" drop:\n" +
|
||||
" # Whether the dropped item glows.\n" +
|
||||
" # Refer to the previous 'glow_color' for configuration method\n" +
|
||||
" glow: green\n" +
|
||||
" pack:\n" +
|
||||
" # the number of player(s) can be selected at most\n" +
|
||||
" max_num: 1\n" +
|
||||
" rank:\n" +
|
||||
" # Top few can receive rewards\n" +
|
||||
" max_num: 1\n" +
|
||||
"\n"
|
||||
).getBytes());
|
||||
out.close();
|
||||
FileConfiguration fc = YamlConfiguration.loadConfiguration(file);
|
||||
fc.set("version","2.1.0");
|
||||
fc.set("move_speed_modify",null);
|
||||
fc.save(file);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
String lang_name = config_old.getString("lang","English") + ".yml";
|
||||
FileConfiguration lang_old = lang;
|
||||
if("2.0.0".equals(lang_old.getString("version"))){
|
||||
Config.saveResource("lang/"+lang_name,"new/lang/"+lang_name,true);
|
||||
File lang_new_F = new File(plugin.getDataFolder(),"new/lang/"+lang_name);
|
||||
FileConfiguration lang_new = YamlConfiguration.loadConfiguration(lang_new_F);
|
||||
lang_old.getKeys(true).forEach(key->{
|
||||
Object obj = lang_old.get(key);
|
||||
if(obj instanceof String){
|
||||
lang_new.set(key,obj);
|
||||
}
|
||||
});
|
||||
lang_new.set("version","2.1.0");
|
||||
lang_new.save(lang_new_F);
|
||||
}
|
||||
else Lang.error("The version of "+lang_name+" is not supported!");
|
||||
FileConfiguration data_old = EnderDragon.data;
|
||||
if("2.0.0".equals(data_old.getString("version"))){
|
||||
File new_folder = new File(plugin.getDataFolder(),"new/reward");
|
||||
for (MyDragon myDragon : DragonManager.dragons) {
|
||||
String key = myDragon.unique_name;
|
||||
List<String> list = data.getStringList(key);
|
||||
File new_data = new File(new_folder,key+".yml");
|
||||
FileConfiguration fc = YamlConfiguration.loadConfiguration(new_data);
|
||||
fc.set("version","2.1.0");
|
||||
fc.set("list",list);
|
||||
fc.save(new_data);
|
||||
data_old.set(key,null);
|
||||
}
|
||||
data_old.set("version","2.1.0");
|
||||
data_old.save(new File(plugin.getDataFolder(),"new/data.yml"));
|
||||
}
|
||||
else Lang.error("The version of data.yml is not supported!");
|
||||
Lang.info("New config files are generated in plugins/EnderDragon/new.");
|
||||
Lang.error("Attention: Please confirm the accuracy before using new config!");
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,215 @@
|
||||
package pers.xanadu.enderdragon.config;
|
||||
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.configuration.file.FileConfiguration;
|
||||
import org.bukkit.entity.Player;
|
||||
import pers.xanadu.enderdragon.util.ColorUtil;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.Type;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
|
||||
import static pers.xanadu.enderdragon.EnderDragon.*;
|
||||
import static pers.xanadu.enderdragon.EnderDragon.server;
|
||||
|
||||
public class Lang {
|
||||
public static String version;
|
||||
public static String plugin_prefix;
|
||||
public static String plugin_wrong_file_version;
|
||||
public static String plugin_read_file;
|
||||
public static String plugin_item_read_error;
|
||||
public static String plugin_checking_update;
|
||||
public static String plugin_check_update_fail;
|
||||
public static String plugin_out_of_date;
|
||||
public static String plugin_up_to_date;
|
||||
public static String plugin_disable;
|
||||
public static String plugin_file_save_error;
|
||||
public static String command_no_permission;
|
||||
public static String command_reload_config;
|
||||
public static String command_only_player;
|
||||
public static String command_drop_item_add_empty;
|
||||
public static String command_drop_item_add_invalid_chance;
|
||||
public static String command_drop_item_add_succeed;
|
||||
public static String command_drop_item_clear;
|
||||
public static String command_drop_item_remove_invalid_num;
|
||||
public static String command_drop_item_remove_fail;
|
||||
public static String command_drop_item_remove_succeed;
|
||||
public static String command_respawn_cd_disable;
|
||||
public static String command_respawn_cd_remove;
|
||||
public static String command_respawn_cd_removeAll;
|
||||
public static String command_respawn_cd_retry;
|
||||
public static String command_respawn_cd_set;
|
||||
public static String command_respawn_cd_start_already_started;
|
||||
public static String command_respawn_cd_start_none;
|
||||
public static String command_respawn_cd_start_succeed;
|
||||
|
||||
|
||||
|
||||
|
||||
public static String gui_default_title;
|
||||
public static String gui_not_found;
|
||||
public static String gui_item_lore;
|
||||
public static String gui_item_cmd_lore;
|
||||
|
||||
public static String dragon_damage_display;
|
||||
public static String dragon_player_inv_full;
|
||||
public static String dragon_no_killer;
|
||||
public static String dragon_auto_respawn;
|
||||
public static String dragon_not_found;
|
||||
public static String dragon_damage_statistics_text;
|
||||
public static List<String> dragon_damage_statistics_hover_prefix;
|
||||
public static String dragon_damage_statistics_hover_mt;
|
||||
public static List<String> dragon_damage_statistics_hover_suffix;
|
||||
public static String dragon_damage_statistics_hover_exceeds_limit;
|
||||
public static String world_env_fix_enable;
|
||||
|
||||
|
||||
|
||||
public static String CommandTips1;
|
||||
public static String CommandTips2;
|
||||
public static String CommandTips3;
|
||||
public static String CommandTips4;
|
||||
public static void reload(FileConfiguration file){
|
||||
Field[] fields = Lang.class.getFields();
|
||||
for(Field field : fields){
|
||||
Type type = field.getType();
|
||||
if(type.equals(java.lang.String.class)){
|
||||
try{
|
||||
field.set(null,"");
|
||||
}catch (Exception ignored){}
|
||||
}
|
||||
else if(type.equals(java.util.List.class)){
|
||||
try{
|
||||
field.set(null,new ArrayList());
|
||||
}catch (Exception ignored){}
|
||||
}
|
||||
}
|
||||
Iterator<String> it = file.getKeys(true).iterator();
|
||||
while (it.hasNext()){
|
||||
String str = it.next();
|
||||
try{
|
||||
if(file.isConfigurationSection(str)) continue;
|
||||
if(file.isString(str)) Lang.class.getField(str.replace(".","_")).set(null, ColorUtil.transGradient(file.getString(str)));
|
||||
else if(file.isList(str)){
|
||||
List<String> list = file.getStringList(str);
|
||||
list.forEach(s-> s = ColorUtil.transGradient(s));
|
||||
Lang.class.getField(str.replace(".","_")).set(null, list);
|
||||
}
|
||||
}catch (Exception e){
|
||||
error("Language loading error! Key: "+str);
|
||||
}
|
||||
}
|
||||
CommandTips1 = ColorUtil.transGradient(lang.getString("CommandTips1","§e/ed reload §a- reload the config"));
|
||||
CommandTips2 = ColorUtil.transGradient(lang.getString("CommandTips2","§e/ed respawn §a- respawn a dragon"));
|
||||
CommandTips3 = ColorUtil.transGradient(lang.getString("CommandTips3","§e/ed drop gui §a- view the drop_item"));
|
||||
CommandTips4 = ColorUtil.transGradient(lang.getString("CommandTips4","§e/ed drop add <name> <chance> §a- add drop_item to one dragon"));
|
||||
}
|
||||
public static void sendMessage(String str) {
|
||||
if(str == null) {
|
||||
Bukkit.getConsoleSender().sendMessage(Lang.plugin_prefix + "null");
|
||||
return;
|
||||
}
|
||||
if(str.contains("\\n")){
|
||||
String[] strings = str.split("\\\\n");
|
||||
for(String s : strings){
|
||||
sendMessage(s);
|
||||
}
|
||||
}
|
||||
else Bukkit.getConsoleSender().sendMessage(Lang.plugin_prefix + str);
|
||||
}
|
||||
public static void info(String str){
|
||||
if(str == null) {
|
||||
Bukkit.getConsoleSender().sendMessage("§a[EnderDragon] " + "null");
|
||||
return;
|
||||
}
|
||||
if(str.contains("\\n")){
|
||||
String[] strings = str.split("\\\\n");
|
||||
for(String s : strings){
|
||||
info(s);
|
||||
}
|
||||
}
|
||||
else Bukkit.getConsoleSender().sendMessage("§a[EnderDragon] "+str);
|
||||
}
|
||||
public static void warn(String str){
|
||||
if(str == null) {
|
||||
Bukkit.getConsoleSender().sendMessage("§e[EnderDragon] " + "null");
|
||||
return;
|
||||
}
|
||||
if(str.contains("\\n")){
|
||||
String[] strings = str.split("\\\\n");
|
||||
for(String s : strings){
|
||||
warn(s);
|
||||
}
|
||||
}
|
||||
else Bukkit.getConsoleSender().sendMessage("§e[EnderDragon] "+str);
|
||||
}
|
||||
public static void error(String str){
|
||||
if(str == null) {
|
||||
Bukkit.getConsoleSender().sendMessage("§c[EnderDragon] " + "null");
|
||||
return;
|
||||
}
|
||||
if(str.contains("\\n")){
|
||||
String[] strings = str.split("\\\\n");
|
||||
for(String s : strings){
|
||||
error(s);
|
||||
}
|
||||
}
|
||||
else Bukkit.getConsoleSender().sendMessage("§c[EnderDragon] "+str);
|
||||
}
|
||||
public static void debug(String str){
|
||||
if(Config.debug) Bukkit.getLogger().info(str);
|
||||
}
|
||||
public static void sendFeedback(CommandSender sender,String str){
|
||||
if(str == null) {
|
||||
sender.sendMessage(Lang.plugin_prefix + "null");
|
||||
return;
|
||||
}
|
||||
if(str.contains("\\n")){
|
||||
String[] strings = str.split("\\\\n");
|
||||
for(String s : strings){
|
||||
sender.sendMessage(Lang.plugin_prefix + s);
|
||||
}
|
||||
}
|
||||
else sender.sendMessage(Lang.plugin_prefix + str);
|
||||
}
|
||||
public static void broadcastMSG(String str){
|
||||
if(str == null) {
|
||||
Bukkit.broadcastMessage(Lang.plugin_prefix + "null");
|
||||
return;
|
||||
}
|
||||
if(str.contains("\\n")){
|
||||
String[] strings = str.split("\\\\n");
|
||||
for(String s : strings){
|
||||
broadcastMSG(s);
|
||||
}
|
||||
}
|
||||
else Bukkit.broadcastMessage(Lang.plugin_prefix + str);
|
||||
}
|
||||
public static void broadcastMSG(List<String> list){
|
||||
if(list == null) return;
|
||||
for(String str : list){
|
||||
Bukkit.broadcastMessage(Lang.plugin_prefix + str);
|
||||
}
|
||||
}
|
||||
public static void runCommands(List<String> list, Player p){
|
||||
if(list == null) return;
|
||||
for (String cmd : list) {
|
||||
if(cmd.equals("")) continue;
|
||||
if(!cmd.contains("%player%")) server.dispatchCommand(server.getConsoleSender(),cmd);
|
||||
else{
|
||||
if(p != null) server.dispatchCommand(server.getConsoleSender(),cmd.replaceAll("%player%",p.getName()));
|
||||
}
|
||||
}
|
||||
}
|
||||
public static void runCommands(List<String> list){
|
||||
if(list == null) return;
|
||||
for(String cmd : list){
|
||||
if(cmd.equals("")) continue;
|
||||
server.dispatchCommand(server.getConsoleSender(),cmd);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,56 @@
|
||||
package pers.xanadu.enderdragon.event;
|
||||
|
||||
import org.bukkit.entity.EnderDragon;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.HandlerList;
|
||||
import org.bukkit.event.entity.EntityDamageByEntityEvent;
|
||||
|
||||
public final class DragonDamageByPlayerEvent extends EntityDamageByEntityEvent {
|
||||
private static final HandlerList handlers = new HandlerList();
|
||||
private boolean cancel = false;
|
||||
private final Player damager;
|
||||
private final EnderDragon dragon;
|
||||
private final DamageCause cause;
|
||||
private final double finalDamage;
|
||||
|
||||
public DragonDamageByPlayerEvent(final Player damager, final EnderDragon dragon, final DamageCause cause, final double finalDamage) {
|
||||
super(damager, dragon, cause, finalDamage);
|
||||
this.damager = damager;
|
||||
this.dragon = dragon;
|
||||
this.cause = cause;
|
||||
this.finalDamage = finalDamage;
|
||||
}
|
||||
|
||||
public static HandlerList getHandlerList() {
|
||||
return handlers;
|
||||
}
|
||||
|
||||
@Override
|
||||
public HandlerList getHandlers() {
|
||||
return handlers;
|
||||
}
|
||||
|
||||
public void setCancelled(final boolean cancel) {
|
||||
this.cancel = cancel;
|
||||
}
|
||||
|
||||
public boolean isCancelled() {
|
||||
return cancel;
|
||||
}
|
||||
|
||||
public Player getDamager() {
|
||||
return damager;
|
||||
}
|
||||
|
||||
public EnderDragon getDragon() {
|
||||
return dragon;
|
||||
}
|
||||
|
||||
public DamageCause getDamagerCause() {
|
||||
return cause;
|
||||
}
|
||||
@Override
|
||||
public double getDamage() {
|
||||
return finalDamage;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
package pers.xanadu.enderdragon.event;
|
||||
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.entity.EnderDragon;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
public final class PlayerExplodeDragonEvent {
|
||||
long _time;
|
||||
Player _player;
|
||||
EnderDragon _dragon;
|
||||
Location _loc;
|
||||
public PlayerExplodeDragonEvent(long time,Player player,EnderDragon dragon,Location loc){
|
||||
_time = time;
|
||||
_player = player;
|
||||
_dragon = dragon;
|
||||
_loc = loc;
|
||||
}
|
||||
public long getTime(){
|
||||
return _time;
|
||||
}
|
||||
public Player getPlayer(){
|
||||
return _player;
|
||||
}
|
||||
public EnderDragon getEnderDragon(){
|
||||
return _dragon;
|
||||
}
|
||||
public Location getLocation(){
|
||||
return _loc;
|
||||
}
|
||||
// private static final class MyComparator implements Comparator<PlayerExplodeDragonEvent>{
|
||||
// @Override
|
||||
// public int compare(final PlayerExplodeDragonEvent e1,final PlayerExplodeDragonEvent e2){
|
||||
// if(e2._time>e1._time) return 1;
|
||||
// else if(e2._time==e1._time) return 0;
|
||||
// return -1;
|
||||
// }
|
||||
// }
|
||||
}
|
||||
@@ -0,0 +1,203 @@
|
||||
package pers.xanadu.enderdragon.gui;
|
||||
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.inventory.Inventory;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.bukkit.inventory.meta.ItemMeta;
|
||||
import pers.xanadu.enderdragon.config.Lang;
|
||||
import pers.xanadu.enderdragon.gui.slot.DragonSlot;
|
||||
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.reward.Reward;
|
||||
import pers.xanadu.enderdragon.util.MyDragon;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
|
||||
public class GUI {
|
||||
protected String title;
|
||||
protected int maxPage;
|
||||
protected int page;
|
||||
protected int size;
|
||||
protected ArrayList<ItemStack[]> pagedItems;
|
||||
protected ArrayList<String[]> pagedData;
|
||||
protected List<GUISlot> slots;
|
||||
protected Inventory inv;
|
||||
protected HashSet<Integer> dynamics;
|
||||
|
||||
protected GUI(String str,int size,int maxPage){
|
||||
this.slots = new ArrayList<>();
|
||||
this.pagedItems = new ArrayList<>();
|
||||
this.pagedData = new ArrayList<>();
|
||||
this.dynamics = new HashSet<>();
|
||||
this.title = str;
|
||||
this.size = size;
|
||||
this.maxPage = maxPage;
|
||||
this.page = 0;
|
||||
}
|
||||
public GUISlot getSlot(int index){
|
||||
GUISlot slot = this.slots.get(index);
|
||||
if(slot == null) return new EmptySlot();
|
||||
return slot;
|
||||
}
|
||||
public void setPage(int a) {
|
||||
this.page = a;
|
||||
for(int i=0;i<this.slots.size();i++){
|
||||
GUISlot slot = this.slots.get(i);
|
||||
if (slot instanceof ItemSlot) {
|
||||
this.inv.setItem(i, new ItemStack(Material.AIR));
|
||||
}
|
||||
}
|
||||
if (this.pagedItems.isEmpty()) {
|
||||
this.pagedItems.add(new ItemStack[this.size]);
|
||||
}
|
||||
if (this.pagedData.isEmpty()) {
|
||||
this.pagedData.add(new String[this.size]);
|
||||
}
|
||||
ItemStack[] array = this.pagedItems.get(a);
|
||||
for(int i=0 ; i<array.length ; i++){
|
||||
ItemStack itemStack = array[i];
|
||||
if (itemStack != null) {
|
||||
this.inv.setItem(i, itemStack);
|
||||
}
|
||||
}
|
||||
for(Integer n2 : this.dynamics){
|
||||
GUISlotType type = this.getSlot(n2).getType();
|
||||
ItemStack clone;
|
||||
if(type == GUISlotType.PAGE_PREV){
|
||||
if(a == 0) clone = this.slots.get(n2).getItemOnDisable();
|
||||
else clone = this.slots.get(n2).getItem();
|
||||
this.inv.setItem(n2,clone);
|
||||
}
|
||||
else if(type == GUISlotType.PAGE_NEXT){
|
||||
if(a == this.pagedItems.size()-1) clone = this.slots.get(n2).getItemOnDisable();
|
||||
else clone = this.slots.get(n2).getItem();
|
||||
this.inv.setItem(n2,clone);
|
||||
}
|
||||
else if(type == GUISlotType.PAGE_TIP){
|
||||
clone = this.slots.get(n2).getItem().clone();
|
||||
ItemMeta itemMeta = clone.getItemMeta();
|
||||
if (itemMeta != null) {
|
||||
itemMeta.setDisplayName(String.format("§r%d/" + this.pagedItems.size(),a+1));
|
||||
clone.setItemMeta(itemMeta);
|
||||
this.inv.setItem(n2, clone);
|
||||
}
|
||||
}
|
||||
// else if(type == GUISlotType.PAGE_JUMP){
|
||||
// clone = this.slots.get(n2).getItem().clone();
|
||||
// this.inv.setItem(n2,clone);
|
||||
// }
|
||||
}
|
||||
}
|
||||
public Inventory current() {
|
||||
return this.inv;
|
||||
}
|
||||
public Inventory getInventory() {
|
||||
return this.inv;
|
||||
}
|
||||
protected void init() {
|
||||
for(int i=0;i<this.slots.size();i++){
|
||||
GUISlot slot = slots.get(i);
|
||||
inv.setItem(i, slot.getItem());
|
||||
}
|
||||
}
|
||||
public void resetPagedItem(ItemStack item){
|
||||
this.pagedItems.clear();
|
||||
this.pagedItems.add(new ItemStack[]{item});
|
||||
}
|
||||
public void resetPagedItem(int type, String key,boolean cmd){
|
||||
this.pagedItems.clear();
|
||||
this.pagedData.clear();
|
||||
if(type == 1){
|
||||
resetPagedItem(key,cmd);
|
||||
}
|
||||
else if(type == 2){
|
||||
for(MyDragon myDragon : DragonManager.dragons){
|
||||
this.addDragon(myDragon.icon.clone(),myDragon.unique_name);
|
||||
}
|
||||
}
|
||||
}
|
||||
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){
|
||||
//if(ItemManager.isEmpty(reward.getItem())) continue;
|
||||
ItemStack item = reward.getItem().clone();
|
||||
if("".equals(Lang.gui_item_lore)) Lang.gui_item_lore = "§6(chance: {drop_chance}%)§r";
|
||||
String lore = Lang.gui_item_lore.replaceAll("\\{drop_chance}",reward.getChance().getStr());
|
||||
if(cmd) {
|
||||
if("".equals(Lang.gui_item_cmd_lore)) Lang.gui_item_cmd_lore = "§6Shift+RightClick§f to remove§r";
|
||||
ItemManager.addLoreFront(item,Lang.gui_item_cmd_lore);
|
||||
}
|
||||
ItemManager.addLoreFront(item,lore);
|
||||
this.addItem(item);
|
||||
}
|
||||
}
|
||||
protected void addItem(ItemStack item) {
|
||||
for(int i = 0 ; i < this.maxPage ; i++){
|
||||
if (i >= this.pagedItems.size()) {
|
||||
this.pagedItems.add(new ItemStack[this.size]);
|
||||
}
|
||||
for(int j = 0 ; j < this.slots.size() ; j++){
|
||||
GUISlot slot = this.slots.get(j);
|
||||
if (slot instanceof ItemSlot) {
|
||||
ItemStack itemStack = this.pagedItems.get(i)[j];
|
||||
if (itemStack == null) {
|
||||
this.pagedItems.get(i)[j] = item;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
protected void addDragon(ItemStack item,String unique_name) {
|
||||
for(int i = 0 ; i < this.maxPage ; i++){
|
||||
if (i >= this.pagedItems.size()) {
|
||||
this.pagedItems.add(new ItemStack[this.size]);
|
||||
this.pagedData.add(new String[this.size]);
|
||||
}
|
||||
for(int j = 0 ; j < this.slots.size() ; j++){
|
||||
if (this.slots.get(j) instanceof DragonSlot) {
|
||||
ItemStack itemStack = this.pagedItems.get(i)[j];
|
||||
if (itemStack == null) {
|
||||
//itemStack = item;(可以吗?)
|
||||
this.pagedItems.get(i)[j] = item;
|
||||
this.pagedData.get(i)[j] = unique_name;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
public String getData(int page,int index){
|
||||
return this.pagedData.get(page)[index];
|
||||
}
|
||||
public int getSize() {
|
||||
return this.size;
|
||||
}
|
||||
public int getPage(){
|
||||
return this.page;
|
||||
}
|
||||
public void prev() {
|
||||
if (this.page > 0) {
|
||||
this.setPage(this.page - 1);
|
||||
}
|
||||
}
|
||||
|
||||
public void addPage() {
|
||||
if (this.pagedItems.size() >= this.maxPage) {
|
||||
return;
|
||||
}
|
||||
this.pagedItems.add(new ItemStack[this.size]);
|
||||
}
|
||||
|
||||
public void next() {
|
||||
if (this.page < this.pagedItems.size() - 1) {
|
||||
this.setPage(this.page + 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
package pers.xanadu.enderdragon.gui;
|
||||
|
||||
import org.bukkit.inventory.Inventory;
|
||||
import org.bukkit.inventory.InventoryHolder;
|
||||
|
||||
public abstract class GUIHolder implements InventoryHolder {
|
||||
private final GUI gui;
|
||||
|
||||
public Inventory getInventory() {
|
||||
return this.gui.getInventory();
|
||||
}
|
||||
|
||||
public GUI getGUI() {
|
||||
return this.gui;
|
||||
}
|
||||
|
||||
public GUIHolder(GUI gui) {
|
||||
this.gui = gui;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
package pers.xanadu.enderdragon.gui;
|
||||
|
||||
import org.bukkit.configuration.ConfigurationSection;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import pers.xanadu.enderdragon.gui.slot.*;
|
||||
|
||||
public abstract class GUISlot {
|
||||
private final GUISlotType guiSlotType;
|
||||
protected DataType data_type;
|
||||
public abstract ItemStack getItem();
|
||||
public abstract ItemStack getItemOnDisable();
|
||||
protected GUISlot(GUISlotType type){
|
||||
this.guiSlotType = type;
|
||||
}
|
||||
public final GUISlotType getType(){
|
||||
return this.guiSlotType;
|
||||
}
|
||||
public static GUISlot parse(ConfigurationSection section){
|
||||
if(section == null) return new EmptySlot();
|
||||
GUISlotType guiSlotType = GUISlotType.getByName(section.getString("type"));
|
||||
switch (guiSlotType) {
|
||||
case ITEM_SLOT : {
|
||||
return new ItemSlot(section);
|
||||
}
|
||||
case DRAGON_SLOT : {
|
||||
return new DragonSlot(section);
|
||||
}
|
||||
case PAGE_PREV :
|
||||
case PAGE_NEXT :
|
||||
case PAGE_TIP :
|
||||
case TIP : {
|
||||
return new TipSlot(guiSlotType, section);
|
||||
}
|
||||
case PAGE_JUMP : {
|
||||
return new PageJumpSlot(section);
|
||||
}
|
||||
}
|
||||
return new EmptySlot();
|
||||
}
|
||||
protected enum DataType{
|
||||
DEFAULT,NBT,ADVANCED
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
package pers.xanadu.enderdragon.gui;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.TreeMap;
|
||||
|
||||
public enum GUISlotType {
|
||||
TIP,
|
||||
PAGE_TIP,
|
||||
PAGE_PREV,
|
||||
PAGE_NEXT,
|
||||
PAGE_JUMP,
|
||||
EMPTY,
|
||||
ITEM_SLOT,
|
||||
DRAGON_SLOT;
|
||||
private static final Map<String,GUISlotType> mp = new TreeMap<>(String.CASE_INSENSITIVE_ORDER);
|
||||
public static GUISlotType getByName(String str){
|
||||
if(str == null) return EMPTY;
|
||||
return mp.getOrDefault(str.replaceAll("_",""),EMPTY);
|
||||
}
|
||||
static{
|
||||
GUISlotType[] values = values();
|
||||
for (GUISlotType guiSlotType : values) {
|
||||
String name = guiSlotType.name();
|
||||
String target = "_";
|
||||
String replacement = "";
|
||||
mp.put(name.replaceAll(target, replacement), guiSlotType);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,138 @@
|
||||
package pers.xanadu.enderdragon.gui;
|
||||
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.configuration.ConfigurationSection;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import pers.xanadu.enderdragon.config.Lang;
|
||||
import pers.xanadu.enderdragon.gui.holder.MenuEditor;
|
||||
import pers.xanadu.enderdragon.gui.holder.Menu;
|
||||
import pers.xanadu.enderdragon.gui.holder.RewardEditor;
|
||||
import pers.xanadu.enderdragon.gui.slot.EmptySlot;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
|
||||
public class GUIWrapper extends GUI{
|
||||
private final String name;
|
||||
private final String key;
|
||||
private int type;
|
||||
private int[] item_idx;
|
||||
private int item_size;
|
||||
|
||||
public String getName() {
|
||||
return this.name;
|
||||
}
|
||||
public GUIWrapper(GUIWrapper a, String key, boolean editor){
|
||||
super(a.title, a.size, a.maxPage);
|
||||
if(editor) this.inv = Bukkit.createInventory(new MenuEditor(this,key), this.size, this.title);
|
||||
else this.inv = Bukkit.createInventory(new Menu(this), this.size, this.title);
|
||||
this.slots.addAll(a.slots);
|
||||
this.dynamics.addAll(a.dynamics);
|
||||
this.name = a.name;
|
||||
this.key = key;
|
||||
this.type = a.type;
|
||||
this.item_idx = a.item_idx;
|
||||
this.item_size = a.item_size;
|
||||
this.init();
|
||||
this.resetPagedItem(type,key,editor);
|
||||
this.setPage(0);
|
||||
}
|
||||
public GUIWrapper(GUIWrapper a, ItemStack item) {
|
||||
super(a.title, a.size, a.maxPage);
|
||||
this.inv = Bukkit.createInventory(new RewardEditor(this), this.size, this.title);
|
||||
this.slots.addAll(a.slots);
|
||||
this.dynamics.addAll(a.dynamics);
|
||||
this.name = a.name;
|
||||
this.key = null;
|
||||
this.type = a.type;
|
||||
this.item_idx = a.item_idx;
|
||||
this.item_size = a.item_size;
|
||||
this.init();
|
||||
this.resetPagedItem(item);
|
||||
this.setPage(0);
|
||||
}
|
||||
@Deprecated
|
||||
public GUIWrapper(GUIWrapper a, String key) {
|
||||
super(a.title, a.size, a.maxPage);
|
||||
this.inv = Bukkit.createInventory(new Menu(this), this.size, this.title);
|
||||
this.slots.addAll(a.slots);
|
||||
this.dynamics.addAll(a.dynamics);
|
||||
this.name = a.name;
|
||||
this.key = key;
|
||||
this.type = a.type;
|
||||
this.item_idx = a.item_idx;
|
||||
this.item_size = a.item_size;
|
||||
this.init();
|
||||
this.resetPagedItem(type,key,false);
|
||||
this.setPage(0);
|
||||
}
|
||||
public GUIWrapper(ConfigurationSection config) {
|
||||
super(config.getString("Title", Lang.gui_default_title).replaceAll("&", "§"), calcline(config.getStringList("Slots").size()) * 9, config.getInt("Page", 1000));
|
||||
this.type = 0;
|
||||
this.name = config.getName();
|
||||
this.key = null;
|
||||
this.inv = Bukkit.createInventory(new Menu(this), this.size, this.title);
|
||||
for(int i = 0 ; i < this.size ; i++){
|
||||
slots.add(new EmptySlot());
|
||||
}
|
||||
ConfigurationSection section = config.getConfigurationSection("Items");
|
||||
HashMap<Character,GUISlot> hash = new HashMap<>();
|
||||
if (section == null) return;
|
||||
for (String s : section.getKeys(false)) {
|
||||
GUISlot slot = GUISlot.parse(section.getConfigurationSection(s));
|
||||
hash.put(s.charAt(0), slot);
|
||||
}
|
||||
int n2 = 0;
|
||||
List<String> stringList = config.getStringList("Slots");
|
||||
for (String line : stringList) {
|
||||
int i;
|
||||
for (i = 0; i < line.length() && i < 9; ++i) {
|
||||
char value = line.charAt(i);
|
||||
this.slots.set(n2++, (hash.getOrDefault(value, new EmptySlot())));
|
||||
}
|
||||
while(i ++ < 9){
|
||||
this.slots.set(n2++, new EmptySlot());
|
||||
}
|
||||
}
|
||||
boolean b = false;
|
||||
for(int i = 0 ; i < slots.size(); i++){
|
||||
GUISlotType type = this.slots.get(i).getType();
|
||||
if(type == GUISlotType.PAGE_PREV || type == GUISlotType.PAGE_NEXT || type == GUISlotType.PAGE_TIP){
|
||||
this.dynamics.add(i);
|
||||
}
|
||||
else if(type == GUISlotType.ITEM_SLOT){
|
||||
this.type = 1;
|
||||
}
|
||||
else if(type == GUISlotType.DRAGON_SLOT){
|
||||
this.type = 2;
|
||||
}
|
||||
else if (type == GUISlotType.PAGE_JUMP) {
|
||||
b = true;
|
||||
}
|
||||
}
|
||||
this.item_idx = new int[size];
|
||||
int cur = -1;
|
||||
for(int i=0;i<size;i++){
|
||||
if(this.slots.get(i).getType()==GUISlotType.ITEM_SLOT) cur++;
|
||||
this.item_idx[i] = cur;
|
||||
}
|
||||
this.item_size = cur+1;
|
||||
}
|
||||
public int getItemSlotIdx(int cur){
|
||||
return this.item_idx[cur];
|
||||
}
|
||||
public int getItemSize(){
|
||||
return this.item_size;
|
||||
}
|
||||
public void updateItemChanges(boolean cmd){
|
||||
this.resetPagedItem(type,key,cmd);
|
||||
this.setPage(page);
|
||||
}
|
||||
|
||||
private static int calcline(final int a) {
|
||||
if (a < 1) {
|
||||
return 1;
|
||||
}
|
||||
return Math.min(a, 6);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
package pers.xanadu.enderdragon.gui.holder;
|
||||
|
||||
import org.bukkit.inventory.InventoryHolder;
|
||||
import pers.xanadu.enderdragon.gui.GUI;
|
||||
import pers.xanadu.enderdragon.gui.GUIHolder;
|
||||
|
||||
public class Menu extends GUIHolder implements InventoryHolder {
|
||||
|
||||
public Menu(GUI gui) {
|
||||
super(gui);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
package pers.xanadu.enderdragon.gui.holder;
|
||||
|
||||
import org.bukkit.inventory.InventoryHolder;
|
||||
import pers.xanadu.enderdragon.gui.GUI;
|
||||
import pers.xanadu.enderdragon.gui.GUIHolder;
|
||||
|
||||
public class MenuEditor extends GUIHolder implements InventoryHolder {
|
||||
private final String dragon_key;
|
||||
public String getDragon_key(){
|
||||
return this.dragon_key;
|
||||
}
|
||||
|
||||
public MenuEditor(GUI gui, String key) {
|
||||
super(gui);
|
||||
this.dragon_key = key;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
package pers.xanadu.enderdragon.gui.holder;
|
||||
|
||||
import org.bukkit.inventory.InventoryHolder;
|
||||
import pers.xanadu.enderdragon.gui.GUI;
|
||||
import pers.xanadu.enderdragon.gui.GUIHolder;
|
||||
|
||||
public class RewardEditor extends GUIHolder implements InventoryHolder {
|
||||
public RewardEditor(GUI gui){
|
||||
super(gui);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
package pers.xanadu.enderdragon.gui.slot;
|
||||
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.configuration.ConfigurationSection;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import pers.xanadu.enderdragon.gui.GUISlot;
|
||||
import pers.xanadu.enderdragon.gui.GUISlotType;
|
||||
|
||||
public class DragonSlot extends GUISlot {
|
||||
private String unique_name;
|
||||
private ItemStack item;
|
||||
|
||||
public DragonSlot(ConfigurationSection section) {
|
||||
super(GUISlotType.DRAGON_SLOT);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemStack getItem() {
|
||||
return new ItemStack(Material.AIR);
|
||||
}
|
||||
@Override
|
||||
public ItemStack getItemOnDisable(){
|
||||
return this.item;
|
||||
}
|
||||
public void setUnique_name(String str){
|
||||
this.unique_name = str;
|
||||
}
|
||||
public String getUnique_name(){
|
||||
return this.unique_name;
|
||||
}
|
||||
|
||||
public DragonSlot(GUISlotType a, ItemStack item) {
|
||||
super(a);
|
||||
this.item = item;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
package pers.xanadu.enderdragon.gui.slot;
|
||||
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import pers.xanadu.enderdragon.gui.GUISlot;
|
||||
import pers.xanadu.enderdragon.gui.GUISlotType;
|
||||
|
||||
public class EmptySlot extends GUISlot {
|
||||
@Override
|
||||
public ItemStack getItem(){
|
||||
return new ItemStack(Material.AIR);
|
||||
}
|
||||
@Override
|
||||
public ItemStack getItemOnDisable(){
|
||||
return new ItemStack(Material.AIR);
|
||||
}
|
||||
public EmptySlot(){
|
||||
super(GUISlotType.EMPTY);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
package pers.xanadu.enderdragon.gui.slot;
|
||||
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.configuration.ConfigurationSection;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import pers.xanadu.enderdragon.gui.GUISlot;
|
||||
import pers.xanadu.enderdragon.gui.GUISlotType;
|
||||
|
||||
public class ItemSlot extends GUISlot {
|
||||
private ItemStack item;
|
||||
|
||||
@Override
|
||||
public ItemStack getItem() {
|
||||
return this.item;
|
||||
}
|
||||
@Override
|
||||
public ItemStack getItemOnDisable(){
|
||||
return this.item;
|
||||
}
|
||||
|
||||
public ItemSlot(ConfigurationSection section) {
|
||||
super(GUISlotType.ITEM_SLOT);
|
||||
String str = section.getString("Item");
|
||||
if(str == null){
|
||||
this.item = new ItemStack(Material.AIR);
|
||||
}
|
||||
else{
|
||||
// this.item = EnderDragon.getInstance().getItemManager().stringToItemStack(str);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
package pers.xanadu.enderdragon.gui.slot;
|
||||
|
||||
import org.bukkit.configuration.ConfigurationSection;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import pers.xanadu.enderdragon.gui.GUISlotType;
|
||||
|
||||
public class PageJumpSlot extends TipSlot{
|
||||
private final String name;
|
||||
public String getGuiName() {
|
||||
return this.name;
|
||||
}
|
||||
public PageJumpSlot(ConfigurationSection section) {
|
||||
super(GUISlotType.PAGE_JUMP, section);
|
||||
this.name = section.getString("gui");
|
||||
}
|
||||
@Override
|
||||
public ItemStack getItemOnDisable(){
|
||||
return this.itemOnDisable;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,64 @@
|
||||
package pers.xanadu.enderdragon.gui.slot;
|
||||
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.configuration.ConfigurationSection;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.bukkit.inventory.meta.ItemMeta;
|
||||
import pers.xanadu.enderdragon.gui.GUISlot;
|
||||
import pers.xanadu.enderdragon.gui.GUISlotType;
|
||||
|
||||
import static pers.xanadu.enderdragon.manager.ItemManager.*;
|
||||
|
||||
public class TipSlot extends GUISlot {
|
||||
private ItemStack item;
|
||||
protected boolean hasDisableMode;
|
||||
protected ItemStack itemOnDisable;
|
||||
|
||||
public TipSlot(GUISlotType slotType, Material material, String str) {
|
||||
super(slotType);
|
||||
this.item = new ItemStack(material);
|
||||
ItemMeta meta = this.item.getItemMeta();
|
||||
meta.setDisplayName(str);
|
||||
this.item.setItemMeta(meta);
|
||||
}
|
||||
|
||||
public TipSlot(GUISlotType slotType, ConfigurationSection section) {
|
||||
super(slotType);
|
||||
if(slotType == GUISlotType.PAGE_PREV || slotType == GUISlotType.PAGE_NEXT){
|
||||
this.hasDisableMode = true;
|
||||
}
|
||||
else this.hasDisableMode = false;
|
||||
if(hasDisableMode){
|
||||
if(data_type == DataType.NBT) this.itemOnDisable = readFromNBT(section,"data_disable");
|
||||
else this.itemOnDisable = readFromBukkit(section,"data_disable");
|
||||
}
|
||||
String data_type = section.getString("data_type");
|
||||
if("nbt".equals(data_type)) {
|
||||
this.data_type = DataType.NBT;
|
||||
this.item = readFromNBT(section,"data");
|
||||
}
|
||||
else if("advanced".equals(data_type)){
|
||||
this.data_type = DataType.ADVANCED;
|
||||
this.item = readFromAdvData(section,"data");
|
||||
}
|
||||
else {
|
||||
this.data_type = DataType.DEFAULT;
|
||||
this.item = readFromBukkit(section,"data");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemStack getItem() {
|
||||
return this.item;
|
||||
}
|
||||
@Override
|
||||
public ItemStack getItemOnDisable(){
|
||||
if(hasDisableMode) return this.itemOnDisable;
|
||||
return this.item;
|
||||
}
|
||||
|
||||
public TipSlot(GUISlotType a, ItemStack item) {
|
||||
super(a);
|
||||
this.item = item;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,116 @@
|
||||
package pers.xanadu.enderdragon.hook;
|
||||
|
||||
import me.clip.placeholderapi.expansion.PlaceholderExpansion;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.OfflinePlayer;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import pers.xanadu.enderdragon.EnderDragon;
|
||||
import pers.xanadu.enderdragon.manager.TimerManager;
|
||||
import pers.xanadu.enderdragon.task.DragonRespawnTimer;
|
||||
import pers.xanadu.enderdragon.util.MathUtil;
|
||||
|
||||
public class Papi extends PlaceholderExpansion {
|
||||
private final EnderDragon plugin;
|
||||
|
||||
public Papi(EnderDragon plugin) {
|
||||
this.plugin = plugin;
|
||||
register();
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull String getAuthor() {
|
||||
return "Xanadu13";
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull String getIdentifier() {
|
||||
return "ed";
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull String getVersion() {
|
||||
return this.plugin.getDescription().getVersion();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean persist() {
|
||||
return true;
|
||||
}
|
||||
@Override
|
||||
public boolean canRegister(){
|
||||
return true;
|
||||
}
|
||||
@Override
|
||||
public String onPlaceholderRequest(Player player, @NotNull String params){
|
||||
if(params.equals("can_respawn")){
|
||||
if(player == null) return String.valueOf(false);
|
||||
boolean res = EnderDragon.getInstance().getDragonManager().canRespawn(player.getWorld());
|
||||
return String.valueOf(res);
|
||||
}
|
||||
if(params.equals("respawn_cd_progress")){
|
||||
if(player == null) return null;
|
||||
World world = player.getWorld();
|
||||
DragonRespawnTimer timer = TimerManager.getTimer(world.getName());
|
||||
if(timer == null) return "null";
|
||||
return String.valueOf(timer.getProgress());
|
||||
}
|
||||
if(params.equals("respawn_cd_remainTime")){
|
||||
if(player == null) return null;
|
||||
World world = player.getWorld();
|
||||
DragonRespawnTimer timer = TimerManager.getTimer(world.getName());
|
||||
if(timer == null) return "null";
|
||||
return String.valueOf(timer.getRestTime());
|
||||
}
|
||||
if(params.equals("respawn_cd_setTime")){
|
||||
if(player == null) return null;
|
||||
World world = player.getWorld();
|
||||
DragonRespawnTimer timer = TimerManager.getTimer(world.getName());
|
||||
if(timer == null) return "null";
|
||||
return String.valueOf(timer.getSetTime());
|
||||
}
|
||||
if(params.startsWith("can_respawn_")){
|
||||
String name = params.substring("can_respawn_".length());
|
||||
World world = Bukkit.getWorld(name);
|
||||
boolean res = EnderDragon.getInstance().getDragonManager().canRespawn(world);
|
||||
return String.valueOf(res);
|
||||
}
|
||||
if(params.startsWith("respawn_cd_progress_")){
|
||||
String name = params.substring("respawn_cd_progress_".length());
|
||||
DragonRespawnTimer timer = TimerManager.getTimer(name);
|
||||
if(timer == null) return "null";
|
||||
return String.valueOf(timer.getProgress());
|
||||
}
|
||||
if(params.startsWith("respawn_cd_remainTime_")){
|
||||
String name = params.substring("respawn_cd_remainTime_".length());
|
||||
DragonRespawnTimer timer = TimerManager.getTimer(name);
|
||||
if(timer == null) return "null";
|
||||
return String.valueOf(timer.getRestTime());
|
||||
}
|
||||
if(params.startsWith("respawn_cd_setTime_")){
|
||||
String name = params.substring("respawn_cd_setTime_".length());
|
||||
DragonRespawnTimer timer = TimerManager.getTimer(name);
|
||||
if(timer == null) return "null";
|
||||
return String.valueOf(timer.getSetTime());
|
||||
}
|
||||
if(params.startsWith("respawn_cd_remain_")){
|
||||
String sub = params.substring("respawn_cd_remain_".length());
|
||||
String[] splits = sub.split("\\$",5);
|
||||
DragonRespawnTimer timer = TimerManager.getTimer(splits[0]);
|
||||
if(timer == null) return "null";
|
||||
if(splits.length==1) return MathUtil.formatDuration(timer.getRestTime());
|
||||
if(splits.length==5){
|
||||
int[] values = MathUtil.getDate(timer.getRestTime());
|
||||
return values[0]+splits[1]+values[1]+splits[2]+values[2]+splits[3]+values[3]+splits[4];
|
||||
}
|
||||
return "wrong format";
|
||||
}
|
||||
return null;
|
||||
}
|
||||
@Override
|
||||
public String onRequest(OfflinePlayer player, @NotNull String params) {
|
||||
if(player == null) return onPlaceholderRequest(null,params);
|
||||
return onPlaceholderRequest(player.getPlayer(),params);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,145 @@
|
||||
package pers.xanadu.enderdragon.listener;
|
||||
|
||||
import org.bukkit.*;
|
||||
import org.bukkit.attribute.Attribute;
|
||||
import org.bukkit.block.Block;
|
||||
import org.bukkit.boss.BarColor;
|
||||
import org.bukkit.boss.BarStyle;
|
||||
import org.bukkit.boss.BossBar;
|
||||
import org.bukkit.entity.*;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.EventPriority;
|
||||
import org.bukkit.event.Listener;
|
||||
import org.bukkit.event.block.Action;
|
||||
import org.bukkit.event.entity.CreatureSpawnEvent;
|
||||
import org.bukkit.event.entity.EntitySpawnEvent;
|
||||
import org.bukkit.event.player.PlayerInteractEvent;
|
||||
import org.bukkit.potion.PotionEffect;
|
||||
import pers.xanadu.enderdragon.config.Config;
|
||||
import pers.xanadu.enderdragon.config.Lang;
|
||||
import pers.xanadu.enderdragon.manager.DamageManager;
|
||||
import pers.xanadu.enderdragon.manager.RewardManager;
|
||||
import pers.xanadu.enderdragon.util.MyDragon;
|
||||
import pers.xanadu.enderdragon.util.Version;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
import static pers.xanadu.enderdragon.EnderDragon.*;
|
||||
import static pers.xanadu.enderdragon.manager.DragonManager.*;
|
||||
import static pers.xanadu.enderdragon.manager.GlowManager.*;
|
||||
|
||||
public class CreatureSpawnListener implements Listener {
|
||||
@EventHandler(priority = EventPriority.LOW)
|
||||
public void OnDragonSpawn(final CreatureSpawnEvent e){
|
||||
if(!(e.getEntity() instanceof EnderDragon)) return;
|
||||
if(Config.blacklist_worlds.contains(e.getEntity().getWorld().getName())) return;
|
||||
EnderDragon dragon = (EnderDragon) e.getEntity();
|
||||
MyDragon myDragon = judge();
|
||||
if(myDragon == null) {
|
||||
Lang.warn("special_dragon_jude_mode setting error!");
|
||||
return;
|
||||
}
|
||||
setSpecialKey(dragon, myDragon.unique_name);
|
||||
DamageManager.data.put(dragon.getUniqueId(),new ConcurrentHashMap<>());
|
||||
int times = data.getInt("times");
|
||||
Lang.runCommands(myDragon.spawn_cmd);
|
||||
for(String str : myDragon.spawn_broadcast_msg){
|
||||
Lang.broadcastMSG(str.replaceAll("%times%",String.valueOf(times)));
|
||||
}
|
||||
dragon.setCustomName(myDragon.display_name);
|
||||
setAttribute(dragon, Attribute.GENERIC_MAX_HEALTH, myDragon.max_health);
|
||||
dragon.setHealth(myDragon.spawn_health);
|
||||
|
||||
//modifyAttribute(dragon, Attribute.GENERIC_MOVEMENT_SPEED, myDragon.move_speed_modify);//
|
||||
|
||||
modifyAttribute(dragon, Attribute.GENERIC_ARMOR, myDragon.armor_modify);
|
||||
|
||||
modifyAttribute(dragon, Attribute.GENERIC_ARMOR_TOUGHNESS, myDragon.armor_toughness_modify);
|
||||
String color = myDragon.glow_color.toUpperCase();
|
||||
if(!color.equals("NONE")) setGlowingColor(dragon,getGlowColor(color));
|
||||
else dragon.setGlowing(false);
|
||||
String bossBar_color = myDragon.bossbar_color.toUpperCase();
|
||||
String bossBar_style = myDragon.bossbar_style.toUpperCase();
|
||||
|
||||
if(Version.mcMainVersion >= 14){
|
||||
BossBar bossBar = dragon.getBossBar();
|
||||
if(bossBar != null){
|
||||
bossBar.setColor(BarColor.valueOf(bossBar_color));
|
||||
bossBar.setStyle(BarStyle.valueOf(bossBar_style));
|
||||
}
|
||||
}
|
||||
else if(Version.mcMainVersion >= 12){
|
||||
getInstance().getBossBarManager().setBossBar(dragon.getWorld(),myDragon.display_name,bossBar_color,bossBar_style);
|
||||
}
|
||||
//dragon.getMetadata();
|
||||
|
||||
}
|
||||
@EventHandler(priority = EventPriority.HIGHEST)
|
||||
public void OnCrystalPlaced(final PlayerInteractEvent e){
|
||||
if(!Config.resist_player_respawn) return;
|
||||
if(e.getAction() != Action.RIGHT_CLICK_BLOCK) return;
|
||||
if(e.getMaterial() != Material.END_CRYSTAL) return;
|
||||
if(e.getClickedBlock() == null) return;
|
||||
Material blockType = e.getClickedBlock().getType();
|
||||
if(blockType != Material.OBSIDIAN && blockType != Material.BEDROCK) return;
|
||||
World world = e.getPlayer().getWorld();
|
||||
if(world.getEnvironment() != World.Environment.THE_END) return;
|
||||
Block block = e.getClickedBlock();
|
||||
int d0 = block.getX();
|
||||
int d1 = block.getY() + 1;
|
||||
int d2 = block.getZ();
|
||||
if(world.getBlockAt(d0, d1, d2).getType() != Material.AIR) return;
|
||||
Location cen = block.getLocation().clone().add(0.5,1,0.5);
|
||||
Collection<Entity> list = world.getNearbyEntities(cen,0.5,1,0.5);
|
||||
if(!list.isEmpty()) return;
|
||||
e.setCancelled(true);
|
||||
EnderCrystal crystal = (EnderCrystal) world.spawnEntity(cen,EntityType.ENDER_CRYSTAL);
|
||||
crystal.setShowingBottom(false);
|
||||
}
|
||||
@EventHandler(priority = EventPriority.HIGH)
|
||||
public void OnEffectCloudSpawn(final EntitySpawnEvent e){
|
||||
if(!(e.getEntity() instanceof AreaEffectCloud)) return;
|
||||
AreaEffectCloud effectCloud = (AreaEffectCloud) e.getEntity();
|
||||
if(effectCloud.getSource() == null) return;
|
||||
if(!(effectCloud.getSource() instanceof EnderDragon)) return;
|
||||
EnderDragon dragon = (EnderDragon) effectCloud.getSource();
|
||||
String unique_name = getSpecialKey(dragon);
|
||||
if(unique_name == null) return;
|
||||
MyDragon myDragon = mp.get(unique_name);
|
||||
if(myDragon == null) return;
|
||||
effectCloud.setRadius((float) myDragon.effect_cloud_original_radius);
|
||||
effectCloud.setRadiusPerTick((float) myDragon.effect_cloud_expand_speed/20f);
|
||||
effectCloud.setDuration(myDragon.effect_cloud_duration * 20);
|
||||
if(myDragon.effect_cloud_color_R != -1){
|
||||
effectCloud.setParticle(Particle.SPELL_MOB);
|
||||
effectCloud.setColor(Color.fromRGB(myDragon.effect_cloud_color_R,myDragon.effect_cloud_color_G,myDragon.effect_cloud_color_B));
|
||||
}
|
||||
effectCloud.clearCustomEffects();
|
||||
for(PotionEffect effect : myDragon.effect_cloud_potion){
|
||||
effectCloud.addCustomEffect(effect,true);
|
||||
}
|
||||
}
|
||||
@EventHandler(priority = EventPriority.LOW)
|
||||
public void OnDragonBreathGather(final PlayerInteractEvent e){
|
||||
if(!Config.resist_dragon_breath_gather) return;
|
||||
if(e.getMaterial() != Material.GLASS_BOTTLE) return;
|
||||
if(e.getAction() != Action.RIGHT_CLICK_BLOCK && e.getAction() != Action.RIGHT_CLICK_AIR) return;
|
||||
World world = e.getPlayer().getWorld();
|
||||
if(world.getEnvironment() != World.Environment.THE_END) return;
|
||||
Player p = e.getPlayer();
|
||||
Location cen = p.getLocation().clone().add(0d,0.9d,0d);
|
||||
Collection<Entity> list = world.getNearbyEntities(cen,2.3d,2.9d,2.3d);
|
||||
for(Entity entity : list){
|
||||
if(entity instanceof AreaEffectCloud) {
|
||||
AreaEffectCloud effectCloud = (AreaEffectCloud) entity;
|
||||
if(effectCloud.getSource() instanceof EnderDragon){
|
||||
e.setCancelled(true);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
package pers.xanadu.enderdragon.listener;
|
||||
|
||||
import org.bukkit.entity.*;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.EventPriority;
|
||||
import org.bukkit.event.Listener;
|
||||
import org.bukkit.event.entity.EntityDamageByEntityEvent;
|
||||
import org.bukkit.potion.PotionEffect;
|
||||
import pers.xanadu.enderdragon.manager.DragonManager;
|
||||
import pers.xanadu.enderdragon.util.MyDragon;
|
||||
|
||||
public class DragonAttackListener implements Listener {
|
||||
@EventHandler(priority = EventPriority.LOW)
|
||||
public void OnDragonAttack(final EntityDamageByEntityEvent e){
|
||||
Entity victim = e.getEntity();
|
||||
Entity attack = e.getDamager();
|
||||
if(!(attack instanceof EnderDragon)) return;
|
||||
EnderDragon dragon = (EnderDragon) attack;
|
||||
String unique_name = DragonManager.getSpecialKey(dragon);
|
||||
if(unique_name == null) return;
|
||||
MyDragon myDragon = DragonManager.mp.get(unique_name);
|
||||
if(myDragon == null) return;
|
||||
e.setDamage(Math.max(0.1, e.getDamage() + myDragon.attack_damage_modify));
|
||||
if(victim instanceof Player){
|
||||
Player player = (Player) victim;
|
||||
for(PotionEffect effect : myDragon.attack_potion_effect){
|
||||
player.addPotionEffect(effect);
|
||||
}
|
||||
if(!myDragon.suck_blood_enable) return;
|
||||
double suck = e.getFinalDamage() * myDragon.suck_blood_rate + myDragon.suck_blood_base_amount;
|
||||
dragon.setHealth(Math.min(dragon.getHealth()+suck,dragon.getMaxHealth()));
|
||||
}
|
||||
else{
|
||||
if(!myDragon.suck_blood_enable) return;
|
||||
if(myDragon.suck_blood_only_player) return;
|
||||
double suck = e.getFinalDamage() * myDragon.suck_blood_rate + myDragon.suck_blood_base_amount;
|
||||
dragon.setHealth(Math.min(dragon.getHealth()+suck,dragon.getMaxHealth()));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
package pers.xanadu.enderdragon.listener;
|
||||
|
||||
import org.bukkit.entity.*;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.EventPriority;
|
||||
import org.bukkit.event.Listener;
|
||||
import org.bukkit.event.entity.EntityDamageByEntityEvent;
|
||||
import pers.xanadu.enderdragon.event.DragonDamageByPlayerEvent;
|
||||
|
||||
import static pers.xanadu.enderdragon.EnderDragon.pm;
|
||||
|
||||
public class DragonBaseHurtListener implements Listener {
|
||||
@EventHandler(priority = EventPriority.HIGHEST)
|
||||
public void BaseAttackToDragon(EntityDamageByEntityEvent e){
|
||||
if(e.isCancelled()) return;
|
||||
if(e.getDamage() <= 0.0) return;
|
||||
Entity victim = e.getEntity();
|
||||
Entity entity = e.getDamager();
|
||||
if(victim instanceof EnderDragon){
|
||||
EnderDragon dragon = (EnderDragon) victim;
|
||||
if(entity instanceof Player){
|
||||
Player player = (Player) entity;
|
||||
pm.callEvent(new DragonDamageByPlayerEvent(player,dragon,e.getCause(),e.getFinalDamage()));
|
||||
}
|
||||
else if(entity instanceof Projectile){
|
||||
Projectile projectile = (Projectile) entity;
|
||||
if(!(projectile.getShooter() instanceof Player)) return;
|
||||
Player damager = (Player) projectile.getShooter();
|
||||
pm.callEvent(new DragonDamageByPlayerEvent(damager,dragon,e.getCause(),e.getFinalDamage()));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,60 @@
|
||||
package pers.xanadu.enderdragon.listener;
|
||||
|
||||
import net.md_5.bungee.api.ChatMessageType;
|
||||
import net.md_5.bungee.api.chat.TextComponent;
|
||||
import org.bukkit.entity.EnderDragon;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.EventPriority;
|
||||
import org.bukkit.event.Listener;
|
||||
import pers.xanadu.enderdragon.config.Config;
|
||||
import pers.xanadu.enderdragon.config.Lang;
|
||||
import pers.xanadu.enderdragon.event.DragonDamageByPlayerEvent;
|
||||
import pers.xanadu.enderdragon.manager.DamageManager;
|
||||
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
public class DragonDamageByPlayerListener implements Listener {
|
||||
|
||||
@EventHandler(priority = EventPriority.HIGHEST)
|
||||
public void OnDragonDamageByPlayer(final DragonDamageByPlayerEvent e){
|
||||
Player p = e.getDamager();
|
||||
EnderDragon dragon = e.getDragon();
|
||||
double health = dragon.getHealth();
|
||||
double damage = Math.min(e.getFinalDamage(),health);
|
||||
if(damage > 0.0d){
|
||||
UUID dragon_uid = dragon.getUniqueId();
|
||||
ConcurrentHashMap<String,Double> mp = DamageManager.data.computeIfAbsent(dragon_uid, k->new ConcurrentHashMap<>());
|
||||
mp.compute(p.getName(),(k,v)->v==null?damage:v+damage);
|
||||
}
|
||||
//Bukkit.broadcastMessage(RewardManager.data.get(dragon.getUniqueId()).get(p.getUniqueId())+"");
|
||||
double max_health = dragon.getMaxHealth();
|
||||
double remain_health = Math.max(health-e.getFinalDamage(),0.0);
|
||||
String str = Lang.dragon_damage_display.replaceAll("%damage%", format(damage)).replaceAll("%remain_health%",format(remain_health)).replaceAll("%max_health%",format(max_health));
|
||||
switch (Config.damage_visible_mode.toLowerCase()){
|
||||
case "actionbar" : {
|
||||
p.spigot().sendMessage(ChatMessageType.ACTION_BAR, TextComponent.fromLegacyText(str));
|
||||
break;
|
||||
}
|
||||
case "chatbox" : {
|
||||
Lang.sendFeedback(p,str);
|
||||
break;
|
||||
}
|
||||
case "subtitle" : {
|
||||
p.sendTitle("",str,5,40,5);
|
||||
break;
|
||||
}
|
||||
default : {
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
private String format(double d0){
|
||||
return String.format("%.2f",d0);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,163 @@
|
||||
package pers.xanadu.enderdragon.listener;
|
||||
|
||||
import net.md_5.bungee.api.chat.BaseComponent;
|
||||
import net.md_5.bungee.api.chat.ComponentBuilder;
|
||||
import net.md_5.bungee.api.chat.HoverEvent;
|
||||
import net.md_5.bungee.api.chat.TextComponent;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.block.Block;
|
||||
import org.bukkit.entity.EnderDragon;
|
||||
import org.bukkit.entity.Entity;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.Listener;
|
||||
import org.bukkit.event.entity.EntityDeathEvent;
|
||||
import org.bukkit.scheduler.BukkitRunnable;
|
||||
import pers.xanadu.enderdragon.config.Config;
|
||||
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.util.Pair;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.ThreadLocalRandom;
|
||||
|
||||
import static pers.xanadu.enderdragon.EnderDragon.*;
|
||||
|
||||
public class DragonDeathListener implements Listener {
|
||||
@EventHandler
|
||||
public void OnDragonDeath(final EntityDeathEvent e){
|
||||
if(!(e.getEntity() instanceof EnderDragon)) return;
|
||||
EnderDragon dragon = (EnderDragon) e.getEntity();
|
||||
String unique_name = DragonManager.getSpecialKey(dragon);
|
||||
if(unique_name == null) return;
|
||||
MyDragon myDragon = DragonManager.mp.get(unique_name);
|
||||
if(myDragon == null) return;
|
||||
int times = data.getInt("times");
|
||||
data.set("times",times+1);
|
||||
try{
|
||||
data.save(dataF);
|
||||
}catch (IOException ex){
|
||||
Lang.error(Lang.plugin_file_save_error.replaceAll("\\{file_name}",dataF.getName()));
|
||||
}
|
||||
e.setDroppedExp(myDragon.exp_drop);
|
||||
if(myDragon.dragon_egg_spawn_chance > ThreadLocalRandom.current().nextDouble(100)){
|
||||
new BukkitRunnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
Block block = e.getEntity().getWorld().getBlockAt(myDragon.dragon_egg_spawn_x, myDragon.dragon_egg_spawn_y, myDragon.dragon_egg_spawn_z);
|
||||
block.setType(Material.DRAGON_EGG);
|
||||
}
|
||||
}.runTaskLater(plugin, myDragon.dragon_egg_spawn_delay);
|
||||
}
|
||||
Player p = e.getEntity().getKiller();
|
||||
myDragon.reward_dist.handle_dist(myDragon,dragon,p);
|
||||
{
|
||||
List<String> processed = new ArrayList<>();
|
||||
if(p != null){
|
||||
for(String str : myDragon.death_broadcast_msg){
|
||||
processed.add(str.replaceAll("%times%",String.valueOf(times)).replaceAll("%player%",p.getDisplayName()));
|
||||
}
|
||||
}
|
||||
else{
|
||||
StringBuilder names = new StringBuilder();
|
||||
List<Entity> entities = dragon.getNearbyEntities(5,5,5);
|
||||
for (Entity entity : entities) {
|
||||
if (entity instanceof Player) {
|
||||
names.append(((Player) entity).getDisplayName()).append(",");
|
||||
}
|
||||
}
|
||||
String name = names.toString();
|
||||
if(name.equals("")) name = Lang.dragon_no_killer;
|
||||
if(name.endsWith(",")) name = name.substring(0,name.length()-1);
|
||||
for(String str : myDragon.death_broadcast_msg){
|
||||
processed.add(str.replaceAll("%times%",String.valueOf(times)).replaceAll("%player%", name));
|
||||
}
|
||||
}
|
||||
handleBroadcast(processed,myDragon,dragon);
|
||||
}
|
||||
DamageManager.data.remove(dragon.getUniqueId());
|
||||
Lang.runCommands(myDragon.death_cmd,p);
|
||||
if(p != null){
|
||||
for(String str : myDragon.msg_to_killer){
|
||||
Lang.sendFeedback(p,str.replaceAll("%times%",String.valueOf(times)));
|
||||
}
|
||||
}
|
||||
TimerManager.startTimer(dragon.getWorld().getName());
|
||||
}
|
||||
public static void handleBroadcast(final List<String> list,final MyDragon myDragon,final EnderDragon dragon){
|
||||
boolean find = false;
|
||||
for(String str : list){
|
||||
if(str.contains("{damage_statistics}")){
|
||||
find = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(!find) Lang.broadcastMSG(list);
|
||||
else{
|
||||
final TextComponent hover = getHover(myDragon,dragon);
|
||||
for(String str : list){
|
||||
final String[] splits = str.split("\\{damage_statistics}");
|
||||
final ComponentBuilder builder = new ComponentBuilder(Lang.plugin_prefix);
|
||||
int size = splits.length;
|
||||
for(int i=0;i<size-1;i++){
|
||||
builder.append(splits[i]).append(hover);
|
||||
}
|
||||
builder.append(splits[size-1]);
|
||||
if(str.endsWith("{damage_statistics}")) builder.append(hover);
|
||||
Bukkit.getOnlinePlayers().forEach(p->p.spigot().sendMessage(builder.create()));
|
||||
}
|
||||
}
|
||||
}
|
||||
public static TextComponent getHover(final MyDragon myDragon,final EnderDragon dragon) {
|
||||
final TextComponent text = new TextComponent(Lang.dragon_damage_statistics_text);
|
||||
List<Pair<String,Double>> list = DamageManager.getDamageList(dragon.getUniqueId());
|
||||
list.sort(DamageManager::sortByDamage);
|
||||
double sum = 0d;
|
||||
for(Pair<String,Double> pair : list){
|
||||
sum += pair.second;
|
||||
}
|
||||
StringBuilder builder = new StringBuilder();
|
||||
for(String raw : Lang.dragon_damage_statistics_hover_prefix){
|
||||
builder.append(raw
|
||||
.replaceAll("%dragon_display_name%",myDragon.display_name)
|
||||
.replaceAll("%damage_sum%",String.format("%.2f",sum))
|
||||
).append("\n");
|
||||
}
|
||||
int i = 0;
|
||||
for(Pair<String,Double> pair : list){
|
||||
String raw = Lang.dragon_damage_statistics_hover_mt;
|
||||
if(i < Config.damage_statistics_limit){
|
||||
double damage = pair.second;
|
||||
double percent = damage/sum*100;
|
||||
builder.append(raw
|
||||
.replaceAll("%rank%", String.valueOf(++i))
|
||||
.replaceAll("%player%", pair.first)
|
||||
.replaceAll("%damage%",String.format("%.2f",damage))
|
||||
.replaceAll("%percent%",String.format("%.2f%%",percent))
|
||||
).append("\n");
|
||||
}
|
||||
}
|
||||
if(list.size()-i>0){
|
||||
String raw = Lang.dragon_damage_statistics_hover_exceeds_limit;
|
||||
builder.append(raw
|
||||
.replaceAll("%exceeds_number%", String.valueOf(list.size()-i))
|
||||
).append("\n");
|
||||
}
|
||||
for(String raw : Lang.dragon_damage_statistics_hover_suffix){
|
||||
builder.append(raw
|
||||
.replaceAll("%dragon_display_name%",myDragon.display_name)
|
||||
.replaceAll("%damage_sum%",String.format("%.2f",sum))
|
||||
);
|
||||
}
|
||||
BaseComponent[] cmp = new ComponentBuilder(builder.toString()).create();
|
||||
text.setHoverEvent(new HoverEvent(HoverEvent.Action.SHOW_TEXT,cmp));
|
||||
return text;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,94 @@
|
||||
package pers.xanadu.enderdragon.listener;
|
||||
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.entity.EnderDragon;
|
||||
import org.bukkit.entity.Entity;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.entity.TNTPrimed;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.EventPriority;
|
||||
import org.bukkit.event.Listener;
|
||||
import org.bukkit.event.entity.EntityDamageByBlockEvent;
|
||||
import org.bukkit.event.entity.EntityDamageByEntityEvent;
|
||||
import org.bukkit.event.entity.EntityDamageEvent;
|
||||
import org.bukkit.event.player.PlayerBedEnterEvent;
|
||||
import pers.xanadu.enderdragon.event.DragonDamageByPlayerEvent;
|
||||
import pers.xanadu.enderdragon.event.PlayerExplodeDragonEvent;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
import static pers.xanadu.enderdragon.EnderDragon.pm;
|
||||
import static pers.xanadu.enderdragon.manager.WorldManager.getExplosionDragon;
|
||||
|
||||
public class DragonExplosionHurtListener implements Listener {
|
||||
|
||||
private static final ConcurrentHashMap<UUID,PlayerExplodeDragonEvent> mp = new ConcurrentHashMap<>();
|
||||
|
||||
@EventHandler(priority = EventPriority.HIGHEST)
|
||||
public void OnDragonDamageByTNT(final EntityDamageByEntityEvent e){
|
||||
if(e.isCancelled()) return;
|
||||
if(e.getDamage() <= 0.0) return;
|
||||
Entity victim = e.getEntity();
|
||||
Entity entity = e.getDamager();
|
||||
if(victim instanceof EnderDragon){
|
||||
EnderDragon dragon = (EnderDragon) victim;
|
||||
if(entity instanceof TNTPrimed){
|
||||
TNTPrimed tnt = (TNTPrimed) entity;
|
||||
if(!(tnt.getSource() instanceof Player)) return;
|
||||
Player damager = (Player) tnt.getSource();
|
||||
pers.xanadu.enderdragon.EnderDragon.pm.callEvent(new DragonDamageByPlayerEvent(damager,dragon,e.getCause(),e.getFinalDamage()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 用tnt隔着方块炸龙也能触发
|
||||
*/
|
||||
@EventHandler(priority = EventPriority.HIGHEST)
|
||||
public void OnDragonDamageByExplode(final EntityDamageByBlockEvent e){
|
||||
long time = pers.xanadu.enderdragon.EnderDragon.getInstance().getWorldDataManager().getGameTime(e.getEntity().getWorld());
|
||||
EntityDamageEvent.DamageCause cause = e.getCause();
|
||||
if(e.getCause() != EntityDamageEvent.DamageCause.BLOCK_EXPLOSION) return;
|
||||
Entity entity = e.getEntity();
|
||||
if(entity instanceof EnderDragon){
|
||||
//Bukkit.broadcastMessage(e.getFinalDamage()+"awa");
|
||||
EnderDragon dragon = (EnderDragon) entity;
|
||||
for(UUID uuid : mp.keySet()){
|
||||
PlayerExplodeDragonEvent ped = mp.get(uuid);
|
||||
if(ped == null) continue;
|
||||
if(ped.getTime() != time) continue;
|
||||
if(ped.getEnderDragon().getUniqueId() != dragon.getUniqueId()) continue;
|
||||
//mp.remove(uuid);
|
||||
pm.callEvent(new DragonDamageByPlayerEvent(ped.getPlayer(),dragon,cause,e.getFinalDamage()));
|
||||
//Bukkit.broadcastMessage(ped._loc.toString());
|
||||
//Bukkit.broadcastMessage("final: "+e.getFinalDamage());
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
@EventHandler(priority = EventPriority.HIGH)
|
||||
public void OnPlayerClickBed(final PlayerBedEnterEvent e){
|
||||
Player p = e.getPlayer();
|
||||
if(p.getWorld().getEnvironment() != World.Environment.THE_END) return;
|
||||
long time = pers.xanadu.enderdragon.EnderDragon.getInstance().getWorldDataManager().getGameTime(e.getPlayer().getWorld());
|
||||
Location bed_loc = e.getBed().getLocation();
|
||||
Collection<EnderDragon> entities = getExplosionDragon(5f,bed_loc);
|
||||
for(EnderDragon dragon : entities){
|
||||
UUID uuid = p.getUniqueId();
|
||||
mp.put(uuid,new PlayerExplodeDragonEvent(time,p,dragon,bed_loc));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public static void clearUID(final UUID uuid){
|
||||
mp.remove(uuid);
|
||||
}
|
||||
public static void addUID(final UUID uuid,final PlayerExplodeDragonEvent ped){
|
||||
mp.put(uuid,ped);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
package pers.xanadu.enderdragon.listener;
|
||||
|
||||
import org.bukkit.entity.EnderDragon;
|
||||
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 static pers.xanadu.enderdragon.manager.DragonManager.getSpecialKey;
|
||||
import static pers.xanadu.enderdragon.manager.DragonManager.mp;
|
||||
|
||||
public class DragonHealListener implements Listener {
|
||||
@EventHandler(priority = EventPriority.HIGH)
|
||||
public void OnDragonHeal(final EntityRegainHealthEvent e){
|
||||
if(!(e.getEntity() instanceof EnderDragon)) return;
|
||||
EnderDragon dragon = (EnderDragon) e.getEntity();
|
||||
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);
|
||||
if(myDragon == null) return;
|
||||
e.setAmount(myDragon.crystal_heal_speed / 2d);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
package pers.xanadu.enderdragon.listener;
|
||||
|
||||
import org.bukkit.entity.Item;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.Listener;
|
||||
import org.bukkit.event.player.PlayerDropItemEvent;
|
||||
|
||||
public class EndGatewayListener implements Listener {
|
||||
// @EventHandler
|
||||
// public void OnEndGateWaySpawn(final PortalCreateEvent e){
|
||||
// Bukkit.broadcastMessage("123");
|
||||
// List<BlockState> list = e.getBlocks();
|
||||
// list.forEach(block -> Bukkit.broadcastMessage(block.toString()));
|
||||
// }
|
||||
// @EventHandler
|
||||
// public void OnEndGateWaySpawn2(final EntityCreatePortalEvent e){
|
||||
// Bukkit.broadcastMessage("12345");
|
||||
//
|
||||
// }
|
||||
}
|
||||
|
||||
@@ -0,0 +1,123 @@
|
||||
package pers.xanadu.enderdragon.listener;
|
||||
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.EventPriority;
|
||||
import org.bukkit.event.Listener;
|
||||
import org.bukkit.event.inventory.ClickType;
|
||||
import org.bukkit.event.inventory.InventoryClickEvent;
|
||||
import org.bukkit.event.inventory.InventoryDragEvent;
|
||||
import org.bukkit.inventory.InventoryHolder;
|
||||
import org.bukkit.inventory.PlayerInventory;
|
||||
import pers.xanadu.enderdragon.config.Lang;
|
||||
import pers.xanadu.enderdragon.gui.*;
|
||||
import pers.xanadu.enderdragon.gui.holder.Menu;
|
||||
import pers.xanadu.enderdragon.gui.holder.MenuEditor;
|
||||
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;
|
||||
|
||||
public class InventoryListener implements Listener {
|
||||
@EventHandler(priority = EventPriority.LOWEST)
|
||||
public void OnInventoryClick(InventoryClickEvent e){
|
||||
InventoryHolder holder = e.getInventory().getHolder();
|
||||
if(!(holder instanceof GUIHolder)) return;
|
||||
GUIHolder guiHolder = (GUIHolder) holder;
|
||||
if(!(guiHolder.getGUI() instanceof GUIWrapper)) return;
|
||||
e.setCancelled(true);
|
||||
GUIWrapper guiWrapper = (GUIWrapper) guiHolder.getGUI();
|
||||
if(e.getClickedInventory() instanceof PlayerInventory){
|
||||
return;
|
||||
}
|
||||
if(e.getRawSlot() >= 54 || e.getRawSlot() < 0){ //点击箱子以外界面会返回-999
|
||||
return;
|
||||
}
|
||||
Player p = (Player) e.getWhoClicked();
|
||||
GUISlot slot = guiWrapper.getSlot(e.getRawSlot());
|
||||
GUISlotType type = slot.getType();
|
||||
if(type == GUISlotType.EMPTY || type == GUISlotType.TIP || type == GUISlotType.PAGE_TIP){
|
||||
return;
|
||||
}
|
||||
if(type == GUISlotType.PAGE_PREV){
|
||||
guiWrapper.prev();
|
||||
p.updateInventory();
|
||||
return;
|
||||
}
|
||||
if(type == GUISlotType.PAGE_NEXT){
|
||||
guiWrapper.next();
|
||||
p.updateInventory();
|
||||
return;
|
||||
}
|
||||
|
||||
if(holder instanceof Menu){
|
||||
if(e.getClick() != ClickType.LEFT && e.getClick() != ClickType.RIGHT){
|
||||
return;
|
||||
}
|
||||
if(type == GUISlotType.ITEM_SLOT){
|
||||
return;
|
||||
}
|
||||
if(type == GUISlotType.PAGE_JUMP){
|
||||
String name = ((PageJumpSlot)slot).getGuiName();
|
||||
GuiManager.openGui(p,name,false);
|
||||
return;
|
||||
}
|
||||
if(type == GUISlotType.DRAGON_SLOT){
|
||||
String unique_name = guiWrapper.getData(guiWrapper.getPage(),e.getRawSlot());
|
||||
MyDragon dragon = DragonManager.mp.get(unique_name);
|
||||
if(dragon == null){
|
||||
Lang.sendFeedback(p,Lang.gui_not_found);
|
||||
return;
|
||||
}
|
||||
GuiManager.openGui(p,dragon.drop_gui,dragon.unique_name,false);
|
||||
return;
|
||||
}
|
||||
}
|
||||
else if(holder instanceof MenuEditor){
|
||||
MenuEditor menuEditor = (MenuEditor) holder;
|
||||
if(e.getClick() != ClickType.LEFT && e.getClick() != ClickType.RIGHT && e.getClick() != ClickType.SHIFT_RIGHT){
|
||||
return;
|
||||
}
|
||||
if(type == GUISlotType.ITEM_SLOT){
|
||||
if(e.getClick() != ClickType.SHIFT_RIGHT) return;
|
||||
int idx = guiWrapper.getPage()*guiWrapper.getItemSize()+guiWrapper.getItemSlotIdx(e.getRawSlot());
|
||||
//Bukkit.broadcastMessage(idx+"");
|
||||
boolean b = RewardManager.removeItem(menuEditor.getDragon_key(),idx);
|
||||
if(b) {
|
||||
p.sendMessage(Lang.command_drop_item_remove_succeed);
|
||||
guiWrapper.updateItemChanges(true);
|
||||
}
|
||||
else p.sendMessage(Lang.command_drop_item_remove_fail);
|
||||
return;
|
||||
}
|
||||
if(type == GUISlotType.PAGE_JUMP){
|
||||
String name = ((PageJumpSlot)slot).getGuiName();
|
||||
GuiManager.openGui(p,name,true);
|
||||
return;
|
||||
}
|
||||
if(type == GUISlotType.DRAGON_SLOT){
|
||||
String unique_name = guiWrapper.getData(guiWrapper.getPage(),e.getRawSlot());
|
||||
MyDragon dragon = DragonManager.mp.get(unique_name);
|
||||
if(dragon == null){
|
||||
Lang.sendFeedback(p,Lang.gui_not_found);
|
||||
return;
|
||||
}
|
||||
GuiManager.openGui(p,dragon.drop_gui,dragon.unique_name,true);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@EventHandler(priority = EventPriority.LOWEST)
|
||||
public void OnInventoryDrag(InventoryDragEvent e){
|
||||
InventoryHolder holder = e.getInventory().getHolder();
|
||||
if(!(holder instanceof GUIHolder)) return;
|
||||
if(holder instanceof Menu){
|
||||
GUIHolder guiHolder = (GUIHolder) holder;
|
||||
if(!(guiHolder.getGUI() instanceof GUIWrapper)) return;
|
||||
e.setCancelled(true);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
package pers.xanadu.enderdragon.listener;
|
||||
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.Listener;
|
||||
import org.bukkit.event.player.PlayerJoinEvent;
|
||||
import org.bukkit.event.player.PlayerQuitEvent;
|
||||
import pers.xanadu.enderdragon.manager.GlowManager;
|
||||
|
||||
public class PlayerListener implements Listener {
|
||||
@EventHandler
|
||||
public void onPlayerJoin(final PlayerJoinEvent e){
|
||||
GlowManager.setScoreBoard(e.getPlayer());
|
||||
|
||||
}
|
||||
@EventHandler
|
||||
public void onPlayerQuit(final PlayerQuitEvent e){
|
||||
DragonExplosionHurtListener.clearUID(e.getPlayer().getUniqueId());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
package pers.xanadu.enderdragon.listener;
|
||||
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.Listener;
|
||||
import org.bukkit.event.server.PluginDisableEvent;
|
||||
|
||||
import static pers.xanadu.enderdragon.EnderDragon.*;
|
||||
|
||||
public class PluginDisableListener implements Listener {
|
||||
@EventHandler
|
||||
public void OnPluginDisable(PluginDisableEvent e){
|
||||
if(e.getPlugin().equals(plugin)){
|
||||
disableAll();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
package pers.xanadu.enderdragon.listener;
|
||||
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.block.Block;
|
||||
import org.bukkit.block.data.type.RespawnAnchor;
|
||||
import org.bukkit.entity.EnderDragon;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.EventPriority;
|
||||
import org.bukkit.event.Listener;
|
||||
import org.bukkit.event.block.Action;
|
||||
import org.bukkit.event.player.PlayerInteractEvent;
|
||||
import org.bukkit.inventory.EquipmentSlot;
|
||||
import pers.xanadu.enderdragon.event.PlayerExplodeDragonEvent;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.UUID;
|
||||
|
||||
import static pers.xanadu.enderdragon.manager.WorldManager.getExplosionDragon;
|
||||
|
||||
public class RespawnAnchorExplodeListener implements Listener {
|
||||
@EventHandler(priority = EventPriority.HIGH)
|
||||
public void OnRespawnAnchorExplode(final PlayerInteractEvent e){
|
||||
if(e.getAction() != Action.RIGHT_CLICK_BLOCK) return;
|
||||
Block block = e.getClickedBlock();
|
||||
if(block == null || block.getType() != Material.RESPAWN_ANCHOR) return;
|
||||
RespawnAnchor anchor = (RespawnAnchor) block.getBlockData();
|
||||
Player p = e.getPlayer();
|
||||
Material offHand = p.getInventory().getItemInOffHand().getType();
|
||||
if(e.getHand()== EquipmentSlot.HAND && e.getMaterial()!=Material.GLOWSTONE && offHand==Material.GLOWSTONE) return;
|
||||
if(e.getMaterial()==Material.GLOWSTONE && anchor.getCharges()<4) return;
|
||||
if(anchor.getCharges()==0) return;
|
||||
if(pers.xanadu.enderdragon.EnderDragon.getInstance().getRespawnAnchorManager().isRespawnAnchorWorks(p.getWorld())) return;
|
||||
if(p.isSneaking() && (p.getItemInHand().getType()!=Material.AIR || offHand!=Material.AIR)) return;
|
||||
long time = pers.xanadu.enderdragon.EnderDragon.getInstance().getWorldDataManager().getGameTime(e.getPlayer().getWorld());
|
||||
Location loc = block.getLocation();
|
||||
Collection<EnderDragon> entities = getExplosionDragon(5f,loc);
|
||||
for(EnderDragon dragon : entities){
|
||||
UUID uuid = p.getUniqueId();
|
||||
DragonExplosionHurtListener.addUID(uuid,new PlayerExplodeDragonEvent(time,p,dragon,loc));
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
package pers.xanadu.enderdragon.listener.mythiclib;
|
||||
|
||||
import io.lumine.mythic.lib.api.event.PlayerAttackEvent;
|
||||
import io.lumine.mythic.lib.damage.DamageMetadata;
|
||||
import org.bukkit.entity.EnderDragon;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.EventPriority;
|
||||
import org.bukkit.event.Listener;
|
||||
import pers.xanadu.enderdragon.event.DragonDamageByPlayerEvent;
|
||||
|
||||
import static pers.xanadu.enderdragon.EnderDragon.pm;
|
||||
|
||||
public class PlayerAttackListener implements Listener {
|
||||
@EventHandler(priority = EventPriority.HIGH)
|
||||
public void onPlayerAttack(PlayerAttackEvent e){
|
||||
if(e.isCancelled()) return;
|
||||
if(!(e.getEntity() instanceof org.bukkit.entity.EnderDragon)) return;
|
||||
EnderDragon dragon = (EnderDragon) e.getEntity();
|
||||
DamageMetadata damage = e.getDamage();
|
||||
double final_damage = damage.getDamage();
|
||||
if(final_damage > 0.0d){
|
||||
DragonDamageByPlayerEvent event = new DragonDamageByPlayerEvent(e.getAttacker().getPlayer(),dragon, e.toBukkit().getCause(), final_damage);
|
||||
pm.callEvent(event);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
package pers.xanadu.enderdragon.manager;
|
||||
|
||||
import pers.xanadu.enderdragon.util.Pair;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
public class DamageManager {
|
||||
public static final ConcurrentHashMap<UUID, ConcurrentHashMap<String,Double>> data = new ConcurrentHashMap<>();
|
||||
public static List<Pair<String,Double>> getDamageList(UUID uuid){
|
||||
ConcurrentHashMap<String,Double> mp = data.get(uuid);
|
||||
List<Pair<String,Double>> list = new ArrayList<>();
|
||||
if(mp == null) return list;
|
||||
mp.forEach((k,v)->list.add(new Pair<>(k,v)));
|
||||
return list;
|
||||
}
|
||||
public static <T> int sortByDamage(Pair<T, Double> p1, Pair<T, Double> p2){
|
||||
if(p2.second>p1.second) return 1;
|
||||
if(p2.second.equals(p1.second)) return 0;
|
||||
return -1;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,463 @@
|
||||
package pers.xanadu.enderdragon.manager;
|
||||
|
||||
import org.bukkit.*;
|
||||
import org.bukkit.attribute.Attribute;
|
||||
import org.bukkit.attribute.AttributeInstance;
|
||||
import org.bukkit.attribute.AttributeModifier;
|
||||
import org.bukkit.boss.DragonBattle;
|
||||
import org.bukkit.command.CommandSender;
|
||||
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.bukkit.scoreboard.Team;
|
||||
import pers.xanadu.enderdragon.config.Config;
|
||||
import pers.xanadu.enderdragon.config.Lang;
|
||||
import pers.xanadu.enderdragon.reward.RewardDist;
|
||||
import pers.xanadu.enderdragon.util.MyDragon;
|
||||
import pers.xanadu.enderdragon.util.Version;
|
||||
|
||||
import java.io.File;
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.*;
|
||||
import java.util.concurrent.ThreadLocalRandom;
|
||||
|
||||
import static pers.xanadu.enderdragon.EnderDragon.*;
|
||||
|
||||
public class DragonManager {
|
||||
public static ArrayList<MyDragon> dragons = new ArrayList<>();
|
||||
public static HashMap<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}};
|
||||
private Method DragonBattle_e;
|
||||
private Method getX;
|
||||
private Method getY;
|
||||
private Method getZ;
|
||||
|
||||
public static void reload(){
|
||||
new BukkitRunnable(){
|
||||
@Override
|
||||
public void run(){
|
||||
dragons.clear();
|
||||
mp.clear();
|
||||
dragon_names.clear();
|
||||
sum = 0;
|
||||
if(Config.dragon_setting_file == null){
|
||||
Lang.error("\"dragon_setting_file\" in config.yml is empty!");
|
||||
Lang.warn("Plugin will use the default config...");
|
||||
Config.dragon_setting_file = new ArrayList<>();
|
||||
Config.dragon_setting_file.add("default:5");
|
||||
Config.dragon_setting_file.add("special:5");
|
||||
}
|
||||
for(String str : Config.dragon_setting_file){
|
||||
String[] s = str.split(":");
|
||||
if(s.length != 2){
|
||||
Lang.error("\"dragon_setting_file\" in config.yml error! Key: " + str);
|
||||
continue;
|
||||
}
|
||||
String path = "setting/" + s[0] + ".yml";
|
||||
int edge = -1;
|
||||
try {
|
||||
edge = Integer.parseInt(s[1]);
|
||||
} catch (NumberFormatException ignored){}
|
||||
if(edge < 0) {
|
||||
Lang.error("\"dragon_setting_file\" in config.yml error! Key: " + str);
|
||||
continue;
|
||||
}
|
||||
File file = new File(plugin.getDataFolder(),path);
|
||||
if(!file.exists()) {
|
||||
try{
|
||||
plugin.saveResource("setting/"+file.getName(),false);
|
||||
file = new File(plugin.getDataFolder(),path);
|
||||
}catch (Exception ignored){
|
||||
Lang.error("Not Found setting/" + s[0] + ".yml ,skipped it.");
|
||||
continue;
|
||||
}
|
||||
}
|
||||
FileConfiguration fc = YamlConfiguration.loadConfiguration(file);
|
||||
readSettingFile(fc,edge);
|
||||
}
|
||||
dragons.sort((o1, o2) -> o2.priority - o1.priority);
|
||||
RewardManager.reload();
|
||||
}
|
||||
}.runTaskAsynchronously(plugin);
|
||||
|
||||
}
|
||||
public static MyDragon judge(){
|
||||
if(Config.special_dragon_jude_mode.equalsIgnoreCase("weight")){
|
||||
int cnt = 0, random = ThreadLocalRandom.current().nextInt(0, sum);
|
||||
for(MyDragon cur : dragons){
|
||||
if(cnt <= random && cnt + cur.edge > random){
|
||||
return cur;
|
||||
}
|
||||
cnt += cur.edge;
|
||||
}
|
||||
}
|
||||
else if(Config.special_dragon_jude_mode.equalsIgnoreCase("pc")){
|
||||
Iterator<MyDragon> it = dragons.iterator();
|
||||
MyDragon cur = null;
|
||||
while (it.hasNext()){
|
||||
cur = it.next();
|
||||
boolean judge = cur.spawn_chance > ThreadLocalRandom.current().nextDouble(100);
|
||||
if(judge) return cur;
|
||||
}
|
||||
return cur;
|
||||
}
|
||||
else if(Config.special_dragon_jude_mode.equalsIgnoreCase("edge")){
|
||||
int cnt = 0, random = ThreadLocalRandom.current().nextInt(0, sum);
|
||||
for(MyDragon cur : dragons){
|
||||
if(cnt <= random && cnt + cur.edge > random){
|
||||
return cur;
|
||||
}
|
||||
cnt += cur.edge;
|
||||
}
|
||||
Lang.error("\"edge\" in \"special_dragon_jude_mode\" of config.yml is deprecated!Please use \"weight\" instead.");
|
||||
}
|
||||
return null;
|
||||
}
|
||||
public static void setSpecialKey(Entity e, String key){
|
||||
e.addScoreboardTag(key);
|
||||
}
|
||||
public static String getSpecialKey(Entity e){
|
||||
for(MyDragon a : dragons){
|
||||
if(e.getScoreboardTags().contains(a.unique_name)) return a.unique_name;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
public static void readSettingFile(FileConfiguration f,int edge){
|
||||
MyDragon myDragon = new MyDragon();
|
||||
myDragon.unique_name = f.getString("unique_name","default");
|
||||
if(mp.containsKey(myDragon.unique_name)){
|
||||
Lang.error("The unique_name conflict! Key: "+myDragon.unique_name);
|
||||
return;
|
||||
}
|
||||
myDragon.icon = ItemManager.readFromBukkit(f,"icon");
|
||||
myDragon.display_name = f.getString("display_name","Special Dragon");
|
||||
myDragon.drop_gui = f.getString("drop_gui");
|
||||
myDragon.edge = edge;
|
||||
myDragon.priority = f.getInt("priority",1);
|
||||
myDragon.spawn_chance = f.getDouble("spawn_chance",0);
|
||||
myDragon.max_health = f.getInt("max_health",200);
|
||||
myDragon.spawn_health = f.getInt("spawn_health",200);
|
||||
myDragon.exp_drop = f.getInt("exp_drop",500);
|
||||
myDragon.dragon_egg_spawn_delay = f.getInt("dragon_egg_spawn.delay",410);
|
||||
myDragon.dragon_egg_spawn_x = f.getInt("dragon_egg_spawn.x",0);
|
||||
myDragon.dragon_egg_spawn_y = f.getInt("dragon_egg_spawn.y",70);
|
||||
myDragon.dragon_egg_spawn_z = f.getInt("dragon_egg_spawn.z",0);
|
||||
myDragon.dragon_egg_spawn_chance = f.getDouble("dragon_egg_spawn.chance",0);
|
||||
myDragon.attack_damage_modify = f.getDouble("attack_damage_modify",0);
|
||||
//myDragon.move_speed_modify = f.getDouble("move_speed_modify",0);
|
||||
myDragon.armor_modify = f.getDouble("armor_modify",0);
|
||||
myDragon.armor_toughness_modify = f.getDouble("armor_toughness_modify",0);
|
||||
myDragon.crystal_heal_speed = f.getDouble("crystal_heal_speed",2.0);
|
||||
myDragon.suck_blood_enable = f.getBoolean("suck_blood.enable",true);
|
||||
myDragon.suck_blood_rate = f.getDouble("suck_blood.rate",50) / 100d;
|
||||
myDragon.suck_blood_base_amount = f.getDouble("suck_blood.base_amount",1);
|
||||
myDragon.suck_blood_only_player = f.getBoolean("suck_blood.only_player",true);
|
||||
List<String> stringList = f.getStringList("attack_potion_effect");
|
||||
List<PotionEffect> potions = new ArrayList<>();
|
||||
for(String string : stringList){
|
||||
String[] s = string.split(" ");
|
||||
if(s.length != 3) continue;
|
||||
PotionEffectType type = PotionEffectType.getByName(s[0].toUpperCase());
|
||||
if(type == null){
|
||||
Lang.error("Unknown potion type: " + s[0]);
|
||||
continue;
|
||||
}
|
||||
int duration = -1;
|
||||
try {
|
||||
duration = Integer.parseInt(s[1]);
|
||||
} catch (NumberFormatException ex){
|
||||
Lang.error("Wrong number format: " + s[1]);
|
||||
}
|
||||
if(duration == -1) continue;
|
||||
int level = -1;
|
||||
try {
|
||||
level = Integer.parseInt(s[2]);
|
||||
} catch (NumberFormatException ex){
|
||||
Lang.error("Wrong number format: " + s[2]);
|
||||
}
|
||||
if(level == -1) continue;
|
||||
PotionEffect potionEffect = new PotionEffect(type,duration*20,level-1);
|
||||
potions.add(potionEffect);
|
||||
}
|
||||
myDragon.attack_potion_effect = potions;
|
||||
myDragon.spawn_cmd = f.getStringList("spawn_cmd");
|
||||
myDragon.death_cmd = f.getStringList("death_cmd");
|
||||
myDragon.spawn_broadcast_msg = f.getStringList("spawn_broadcast_msg");
|
||||
myDragon.death_broadcast_msg = f.getStringList("death_broadcast_msg");
|
||||
myDragon.msg_to_killer = f.getStringList("msg_to_killer");
|
||||
myDragon.glow_color = f.getString("glow_color","random");
|
||||
myDragon.bossbar_color = f.getString("bossbar.color","WHITE");
|
||||
myDragon.bossbar_style = f.getString("bossbar.style","SOLID");
|
||||
myDragon.effect_cloud_original_radius = f.getDouble("effect_cloud.original_radius",3);
|
||||
myDragon.effect_cloud_expand_speed = f.getDouble("effect_cloud.expand_speed",0.1333333);
|
||||
myDragon.effect_cloud_duration = f.getInt("effect_cloud.duration",60);
|
||||
String effect_cloud_color = f.getString("effect_cloud.color","none");
|
||||
String[] s0 = effect_cloud_color.split(":");
|
||||
if(s0.length != 3) myDragon.effect_cloud_color_R = -1;
|
||||
else{
|
||||
try{
|
||||
myDragon.effect_cloud_color_R = Integer.parseInt(s0[0]);
|
||||
myDragon.effect_cloud_color_G = Integer.parseInt(s0[1]);
|
||||
myDragon.effect_cloud_color_B = Integer.parseInt(s0[2]);
|
||||
}
|
||||
catch (NumberFormatException e){
|
||||
Lang.error("Wrong effect_cloud_color format!");
|
||||
myDragon.effect_cloud_color_R = -1;
|
||||
}
|
||||
}
|
||||
List<String> stringList2 = f.getStringList("effect_cloud.potion");
|
||||
List<PotionEffect> effectCloudPotions = new ArrayList<>();
|
||||
for(String string : stringList2){
|
||||
String[] s = string.split(" ");
|
||||
if(s.length != 3) continue;
|
||||
PotionEffectType type = PotionEffectType.getByName(s[0].toUpperCase());
|
||||
if(type == null){
|
||||
Lang.error("Unknown potion type: " + s[0]);
|
||||
continue;
|
||||
}
|
||||
int duration = -1;
|
||||
try {
|
||||
duration = Integer.parseInt(s[1]);
|
||||
} catch (NumberFormatException ex){
|
||||
Lang.error("Wrong number format: " + s[1]);
|
||||
}
|
||||
if(duration == -1) continue;
|
||||
int level = -1;
|
||||
try {
|
||||
level = Integer.parseInt(s[2]);
|
||||
} catch (NumberFormatException ex){
|
||||
Lang.error("Wrong number format: " + s[2]);
|
||||
}
|
||||
if(level == -1) continue;
|
||||
PotionEffect potionEffect = new PotionEffect(type,duration*20,level-1);
|
||||
effectCloudPotions.add(potionEffect);
|
||||
}
|
||||
myDragon.effect_cloud_potion = effectCloudPotions;
|
||||
myDragon.reward_dist = RewardDist.parse(f.getConfigurationSection("reward_dist"));
|
||||
dragons.add(myDragon);
|
||||
mp.put(myDragon.unique_name,myDragon);
|
||||
dragon_names.add(myDragon.unique_name);
|
||||
sum += edge;
|
||||
}
|
||||
public static void disable(){
|
||||
dragons.clear();
|
||||
mp.clear();
|
||||
dragon_names.clear();
|
||||
}
|
||||
|
||||
public static void setAttribute(EnderDragon dragon, Attribute attribute, double amount){
|
||||
AttributeInstance instance = dragon.getAttribute(attribute);
|
||||
assert instance != null;
|
||||
instance.setBaseValue(amount);
|
||||
}
|
||||
public static void modifyAttribute(EnderDragon dragon, Attribute attribute, double amount){
|
||||
AttributeInstance instance = dragon.getAttribute(attribute);
|
||||
assert instance != null;
|
||||
instance.addModifier(new AttributeModifier("EnderDragon",amount,AttributeModifier.Operation.ADD_NUMBER));
|
||||
}
|
||||
|
||||
public void initiateRespawn(Player p){
|
||||
DragonRespawnResult res = initiateRespawn(p.getWorld());
|
||||
if(res == DragonRespawnResult.success) Lang.broadcastMSG(Lang.dragon_auto_respawn);
|
||||
else Lang.sendFeedback(p,"§c"+res.getMessage());
|
||||
}
|
||||
public void initiateRespawn(CommandSender sender, String world_name){
|
||||
DragonRespawnResult res = initiateRespawn(Bukkit.getWorld(world_name));
|
||||
if(res == DragonRespawnResult.success) Lang.broadcastMSG(Lang.dragon_auto_respawn);
|
||||
else Lang.sendFeedback(sender,"§c"+res.getMessage());
|
||||
}
|
||||
public void initiateRespawn(String world_name){
|
||||
DragonRespawnResult res = initiateRespawn(Bukkit.getWorld(world_name));
|
||||
if(res == DragonRespawnResult.success) Lang.broadcastMSG(Lang.dragon_auto_respawn);
|
||||
else Lang.error(res.getMessage());
|
||||
}
|
||||
public boolean canRespawn(String world_name){
|
||||
return canRespawn(Bukkit.getWorld(world_name));
|
||||
}
|
||||
public boolean canRespawn(World world){
|
||||
if(world == null) return false;
|
||||
if(world.getEnvironment() != World.Environment.THE_END) return false;
|
||||
if(Version.mcMainVersion >= 16){//executes 1e5 times within 27ms
|
||||
DragonBattle battle = world.getEnderDragonBattle();
|
||||
if(battle == null) return false;
|
||||
if(battle.getEnderDragon() != null) return false;
|
||||
if(battle.getRespawnPhase() != DragonBattle.RespawnPhase.NONE) return false;
|
||||
Location cen = battle.getEndPortalLocation();
|
||||
if(cen == null) {
|
||||
battle.initiateRespawn();
|
||||
cen = battle.getEndPortalLocation();
|
||||
if(cen == null){
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
try {//executes 1e5 times within 76ms
|
||||
Object battle = getInstance().getNMSManager().getEnderDragonBattle(world);
|
||||
if(battle == null) return false;
|
||||
Field k = battle.getClass().getDeclaredField("k");
|
||||
k.setAccessible(true);
|
||||
Object isAlive = k.get(battle);
|
||||
if(!((boolean) isAlive)) return false;
|
||||
Field p = battle.getClass().getDeclaredField("p");
|
||||
p.setAccessible(true);
|
||||
Object phase = p.get(battle);
|
||||
if(phase != null) return false;
|
||||
Field field = battle.getClass().getDeclaredField("o");
|
||||
field.setAccessible(true);
|
||||
Object BlockPosition = field.get(battle);
|
||||
if(BlockPosition == null){
|
||||
if (this.DragonBattle_e == null) this.DragonBattle_e = battle.getClass().getMethod("e");
|
||||
this.DragonBattle_e.invoke(battle);
|
||||
BlockPosition = field.get(battle);
|
||||
if(BlockPosition == null) return false;
|
||||
}
|
||||
return true;
|
||||
} catch (ReflectiveOperationException e) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
public boolean isRespawnRunning(World world){
|
||||
if(world == null) return false;
|
||||
if(world.getEnvironment() != World.Environment.THE_END) return false;
|
||||
if(Version.mcMainVersion >= 16){
|
||||
DragonBattle battle = world.getEnderDragonBattle();
|
||||
assert battle != null;
|
||||
return battle.getRespawnPhase() != DragonBattle.RespawnPhase.NONE;
|
||||
}
|
||||
try {
|
||||
Object battle = getInstance().getNMSManager().getEnderDragonBattle(world);
|
||||
assert battle != null;
|
||||
Field p = battle.getClass().getDeclaredField("p");
|
||||
p.setAccessible(true);
|
||||
Object phase = p.get(battle);
|
||||
return phase != null;
|
||||
} catch (ReflectiveOperationException e) {
|
||||
e.printStackTrace();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
public void refresh_respawn(World world){
|
||||
if(world == null) return;
|
||||
if(world.getEnvironment() != World.Environment.THE_END) return;
|
||||
if(Version.mcMainVersion >= 16){
|
||||
DragonBattle battle = world.getEnderDragonBattle();
|
||||
assert battle != null;
|
||||
battle.initiateRespawn();
|
||||
return;
|
||||
}
|
||||
try {
|
||||
Object battle = getInstance().getNMSManager().getEnderDragonBattle(world);
|
||||
assert battle != null;
|
||||
if (this.DragonBattle_e == null) this.DragonBattle_e = battle.getClass().getMethod("e");
|
||||
this.DragonBattle_e.invoke(battle);
|
||||
} catch (ReflectiveOperationException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
private DragonRespawnResult initiateRespawn(World world){
|
||||
if(world == null) return DragonRespawnResult.world_not_found;
|
||||
if(world.getEnvironment() != World.Environment.THE_END) return DragonRespawnResult.world_wrong_env;
|
||||
if(Version.mcMainVersion >= 16){
|
||||
DragonBattle battle = world.getEnderDragonBattle();
|
||||
assert battle != null;
|
||||
if(battle.getEnderDragon() != null) return DragonRespawnResult.dragon_has_existed;
|
||||
if(battle.getRespawnPhase() != DragonBattle.RespawnPhase.NONE) return DragonRespawnResult.respawn_has_started;
|
||||
Location cen = battle.getEndPortalLocation();
|
||||
if(cen == null) {
|
||||
battle.initiateRespawn();
|
||||
cen = battle.getEndPortalLocation();
|
||||
if(cen == null){
|
||||
return DragonRespawnResult.world_unloaded;//也可尝试chunk.load()
|
||||
}
|
||||
}
|
||||
placeEndCrystals(world,cen);
|
||||
battle.initiateRespawn();
|
||||
return DragonRespawnResult.success;
|
||||
}
|
||||
try {
|
||||
Object battle = getInstance().getNMSManager().getEnderDragonBattle(world);
|
||||
assert battle != null;
|
||||
Field k = battle.getClass().getDeclaredField("k");
|
||||
k.setAccessible(true);
|
||||
Object isAlive = k.get(battle);
|
||||
if(!((boolean) isAlive)) return DragonRespawnResult.dragon_has_existed;
|
||||
Field p = battle.getClass().getDeclaredField("p");
|
||||
p.setAccessible(true);
|
||||
Object phase = p.get(battle);
|
||||
if(phase != null) return DragonRespawnResult.respawn_has_started;
|
||||
Field field = battle.getClass().getDeclaredField("o");
|
||||
field.setAccessible(true);
|
||||
Object BlockPosition = field.get(battle);
|
||||
if(BlockPosition == null){
|
||||
if (this.DragonBattle_e == null) this.DragonBattle_e = battle.getClass().getMethod("e");
|
||||
this.DragonBattle_e.invoke(battle);
|
||||
BlockPosition = field.get(battle);
|
||||
if(BlockPosition == null) return DragonRespawnResult.world_unloaded;
|
||||
}
|
||||
if(this.getX == null) this.getX = BlockPosition.getClass().getMethod("getX");
|
||||
if(this.getY == null) this.getY = BlockPosition.getClass().getMethod("getY");
|
||||
if(this.getZ == null) this.getZ = BlockPosition.getClass().getMethod("getZ");
|
||||
Location loc = new Location(world,(int)getX.invoke(BlockPosition),(int)this.getY.invoke(BlockPosition),(int)this.getZ.invoke(BlockPosition));
|
||||
placeEndCrystals(world, loc);
|
||||
if (this.DragonBattle_e == null) this.DragonBattle_e = battle.getClass().getMethod("e");
|
||||
this.DragonBattle_e.invoke(battle);
|
||||
return DragonRespawnResult.success;
|
||||
} catch (ReflectiveOperationException e) {
|
||||
return DragonRespawnResult.version_not_support;
|
||||
}
|
||||
|
||||
}
|
||||
private void placeEndCrystals(World world, Location cen){
|
||||
cen.add(0.5,1,0.5);
|
||||
for(int i = 0; i < 4; i++){
|
||||
EnderCrystal crystal = (EnderCrystal) world.spawnEntity(cen.clone().add(nxt[i][0],0,nxt[i][1]), EntityType.ENDER_CRYSTAL);
|
||||
if(Config.auto_respawn_invulnerable) crystal.setInvulnerable(true);
|
||||
crystal.setShowingBottom(false);
|
||||
}
|
||||
}
|
||||
public enum DragonRespawnResult{
|
||||
success,
|
||||
world_not_found,
|
||||
world_unloaded,
|
||||
world_wrong_env,
|
||||
respawn_has_started,
|
||||
dragon_has_existed,
|
||||
version_not_support;
|
||||
public String getMessage(){
|
||||
switch (this){
|
||||
case success: return "Success";
|
||||
case world_not_found: return "Can't find this world!";
|
||||
case world_unloaded: return "The world_the_end is unloaded.";
|
||||
case world_wrong_env: return "Respawn only can be called in the End.";
|
||||
case respawn_has_started: return "The respawning has already started.";
|
||||
case dragon_has_existed: return "There is already a dragon here.";
|
||||
case version_not_support: return "Your server version (" + Version.getVersion() + ") is not supported!";
|
||||
default: return "Unknown error!";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// try {
|
||||
// Object WorldServer = getInstance().getNMSManager().getWorldServer(world);
|
||||
// Field Z = WorldServer.getClass().getDeclaredField("Z");
|
||||
// Z.setAccessible(true);
|
||||
// Object edb = Z.get(WorldServer);
|
||||
// Class<?> edb_clazz = Class.forName("net.minecraft.world.level.dimension.end.EnderDragonBattle");
|
||||
// Method a = edb_clazz.getMethod("a");
|
||||
// a.invoke(edb);
|
||||
// Field y = edb_clazz.getDeclaredField("y");
|
||||
// y.setAccessible(true);
|
||||
// Object bp = y.get(edb);
|
||||
// if(bp == null) Bukkit.broadcastMessage("123");
|
||||
// }catch (ReflectiveOperationException e){
|
||||
// e.printStackTrace();
|
||||
// }
|
||||
@@ -0,0 +1,76 @@
|
||||
package pers.xanadu.enderdragon.manager;
|
||||
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.ChatColor;
|
||||
import org.bukkit.entity.Entity;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.scoreboard.Scoreboard;
|
||||
import org.bukkit.scoreboard.Team;
|
||||
import pers.xanadu.enderdragon.util.Version;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.ThreadLocalRandom;
|
||||
|
||||
public class GlowManager {
|
||||
public static Set<Scoreboard> handled = new HashSet<>();
|
||||
public static void reload(){
|
||||
handled.clear();
|
||||
}
|
||||
public static void setScoreBoard(Player p){
|
||||
Scoreboard board = p.getScoreboard();
|
||||
if(handled.contains(board)) return;
|
||||
ChatColor[] colors = ChatColor.values();
|
||||
for(ChatColor color : colors){
|
||||
String name = "ed-"+color.name();
|
||||
if(board.getTeam(name)==null) board.registerNewTeam(name);
|
||||
Team team = board.getTeam(name);
|
||||
assert team != null;
|
||||
if(Version.mcMainVersion >= 13) team.setColor(color);
|
||||
else team.setPrefix(color.toString());
|
||||
}
|
||||
handled.add(board);
|
||||
}
|
||||
public static void addUUID(String uuid,String color){
|
||||
Set<Team> teams = new HashSet<>();
|
||||
Bukkit.getOnlinePlayers().forEach(player -> {
|
||||
GlowManager.setScoreBoard(player);
|
||||
Team team = player.getScoreboard().getTeam("ed-"+color.toUpperCase());
|
||||
teams.add(team);
|
||||
});
|
||||
teams.forEach(team->{
|
||||
team.addEntry(uuid);
|
||||
});
|
||||
}
|
||||
public static void setGlowingColor(Entity entity, ChatColor color){
|
||||
Set<Team> teams = new HashSet<>();
|
||||
Bukkit.getOnlinePlayers().forEach(player -> {
|
||||
GlowManager.setScoreBoard(player);
|
||||
Team team = player.getScoreboard().getTeam("ed-"+color.name());
|
||||
teams.add(team);
|
||||
});
|
||||
teams.forEach(team->{
|
||||
team.addEntry(entity.getUniqueId().toString());
|
||||
entity.setGlowing(true);
|
||||
});
|
||||
}
|
||||
public static ChatColor getGlowColor(String str){
|
||||
ChatColor chatColor;
|
||||
if(str.equals("RANDOM")) chatColor = randomColor();
|
||||
else chatColor = ChatColor.valueOf(str);
|
||||
return chatColor;
|
||||
}
|
||||
public static ChatColor getGlowColor(GlowColor glowColor){
|
||||
if(glowColor == GlowColor.NONE) return null;
|
||||
if(glowColor == GlowColor.RANDOM) return randomColor();
|
||||
return ChatColor.valueOf(glowColor.name());
|
||||
}
|
||||
public static ChatColor randomColor(){
|
||||
return ChatColor.values()[ThreadLocalRandom.current().nextInt(16)];
|
||||
}
|
||||
public enum GlowColor{
|
||||
AQUA,BLACK,BLUE,DARK_AQUA,DARK_BLUE,DARK_GRAY,DARK_GREEN,DARK_PURPLE,DARK_RED,GOLD,GRAY,GREEN,LIGHT_PURPLE,RED,WHITE,YELLOW,
|
||||
NONE,RANDOM
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,76 @@
|
||||
package pers.xanadu.enderdragon.manager;
|
||||
|
||||
import org.bukkit.configuration.ConfigurationSection;
|
||||
import org.bukkit.configuration.file.FileConfiguration;
|
||||
import org.bukkit.configuration.file.YamlConfiguration;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.scheduler.BukkitRunnable;
|
||||
import pers.xanadu.enderdragon.config.Lang;
|
||||
import pers.xanadu.enderdragon.gui.GUIWrapper;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
|
||||
import static pers.xanadu.enderdragon.EnderDragon.plugin;
|
||||
|
||||
public class GuiManager {
|
||||
private static HashMap<String, GUIWrapper> f = new HashMap<>();
|
||||
public static void loadGui(){
|
||||
new BukkitRunnable(){
|
||||
@Override
|
||||
public void run(){
|
||||
File folder = new File(plugin.getDataFolder(),"gui");
|
||||
if(!folder.exists()) return;
|
||||
File[] files = folder.listFiles();
|
||||
if(files == null) return;
|
||||
for(File file : files){
|
||||
if(!file.getName().endsWith(".yml")) continue;
|
||||
Lang.info(Lang.plugin_read_file + file.getName());
|
||||
FileConfiguration fileConfiguration = YamlConfiguration.loadConfiguration(file);
|
||||
Iterator it = fileConfiguration.getKeys(false).iterator();
|
||||
while (it.hasNext()){
|
||||
String name = (String) it.next();
|
||||
ConfigurationSection section = fileConfiguration.getConfigurationSection(name);
|
||||
GUIWrapper guiWrapper = new GUIWrapper(section);
|
||||
f.put(name, guiWrapper);
|
||||
}
|
||||
}
|
||||
}
|
||||
}.runTaskAsynchronously(plugin);
|
||||
}
|
||||
public static void disable(){
|
||||
f.clear();
|
||||
}
|
||||
public static void openGui(Player player, String name, boolean editor) {
|
||||
if (!f.containsKey(name)) {
|
||||
Lang.sendFeedback(player,Lang.gui_not_found);
|
||||
return;
|
||||
}
|
||||
player.openInventory(new GUIWrapper(f.get(name),name,editor).current());
|
||||
}
|
||||
public static void openGui(Player player,String style,String key, boolean editor){
|
||||
if (!f.containsKey(style)) {
|
||||
Lang.sendFeedback(player,Lang.gui_not_found);
|
||||
return;
|
||||
}
|
||||
player.openInventory(new GUIWrapper(f.get(style),key,editor).current());
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
public static void openGui(Player player, String name) {
|
||||
if (!f.containsKey(name)) {
|
||||
Lang.sendFeedback(player,Lang.gui_not_found);
|
||||
return;
|
||||
}
|
||||
player.openInventory(new GUIWrapper(f.get(name),name,false).current());
|
||||
}
|
||||
@Deprecated
|
||||
public static void openGui(Player player,String style,String key){
|
||||
if (!f.containsKey(style)) {
|
||||
Lang.sendFeedback(player,Lang.gui_not_found);
|
||||
return;
|
||||
}
|
||||
player.openInventory(new GUIWrapper(f.get(style),key,false).current());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,426 @@
|
||||
package pers.xanadu.enderdragon.manager;
|
||||
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.attribute.Attribute;
|
||||
import org.bukkit.attribute.AttributeModifier;
|
||||
import org.bukkit.configuration.ConfigurationSection;
|
||||
import org.bukkit.configuration.file.YamlConfiguration;
|
||||
import org.bukkit.enchantments.Enchantment;
|
||||
import org.bukkit.inventory.ItemFlag;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.bukkit.inventory.meta.ItemMeta;
|
||||
import org.bukkit.inventory.meta.Repairable;
|
||||
import org.bukkit.persistence.PersistentDataContainer;
|
||||
import pers.xanadu.enderdragon.EnderDragon;
|
||||
import pers.xanadu.enderdragon.config.Config;
|
||||
import pers.xanadu.enderdragon.reward.Reward;
|
||||
import pers.xanadu.enderdragon.reward.Chance;
|
||||
import pers.xanadu.enderdragon.util.Version;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
public class ItemManager {
|
||||
public static String write(Reward reward){
|
||||
Chance chance = reward.getChance();
|
||||
return write(reward.getItem(),chance.getValue(),chance.getStr(),reward.getName());
|
||||
}
|
||||
public static String write(ItemStack item,double value,String str,String name){
|
||||
YamlConfiguration yaml = new YamlConfiguration();
|
||||
if(name == null){
|
||||
ItemMeta meta = item.getItemMeta();
|
||||
if(meta != null) {
|
||||
String displayName = meta.getDisplayName();
|
||||
if("".equals(displayName) || displayName == null){
|
||||
name = item.getType().name().toLowerCase() + "(" + TaskManager.getCurrentTimeWithSpecialFormat() + ")";
|
||||
}
|
||||
else name = meta.getDisplayName();
|
||||
}
|
||||
else name = item.getType().name().toLowerCase() + "(" + TaskManager.getCurrentTimeWithSpecialFormat() + ")";
|
||||
}
|
||||
ConfigurationSection section = yaml.createSection(name);
|
||||
switch(Config.item_format_data){
|
||||
case "nbt" : {
|
||||
section.set("data_type","nbt");
|
||||
section.set("data",EnderDragon.getInstance().getNMSManager().getNBT(item));
|
||||
break;
|
||||
}
|
||||
case "advanced" : {
|
||||
section.set("data_type","advanced");
|
||||
ConfigurationSection section_data = section.createSection("data");
|
||||
//type
|
||||
String type = item.getType().name();
|
||||
section_data.set("type",type);
|
||||
if("AIR".equals(type)) break;
|
||||
//amount
|
||||
int amount = item.getAmount();
|
||||
section_data.set("amount",amount);
|
||||
//damage
|
||||
int damage = item.getDurability();
|
||||
if(damage != 0) section_data.set("damage",damage);
|
||||
ItemMeta meta = item.getItemMeta();
|
||||
if(meta == null) break;
|
||||
//DisplayName
|
||||
String display_name = meta.getDisplayName();
|
||||
if(!"".equals(display_name)) section_data.set("display_name",display_name);
|
||||
//LocalizedName
|
||||
if(meta.hasLocalizedName()){
|
||||
section_data.set("localized_name",meta.getLocalizedName());
|
||||
}
|
||||
//lore
|
||||
List<String> lores = meta.getLore();
|
||||
if(lores != null) section_data.set("lore",lores);
|
||||
//Enchantments
|
||||
if(meta.hasEnchants()){
|
||||
ConfigurationSection enchants = section_data.createSection("enchants");
|
||||
Map<Enchantment,Integer> mp = meta.getEnchants();
|
||||
mp.forEach((enchantment,level) -> enchants.set(enchantment.getName(),level));
|
||||
}
|
||||
if(Version.mcMainVersion>=14 || "v1_13_R2".equals(Version.getVersion())){
|
||||
//AttributeModifiers
|
||||
if(meta.hasAttributeModifiers()){
|
||||
ConfigurationSection attributes = section_data.createSection("AttributeModifiers");
|
||||
meta.getAttributeModifiers().forEach((attribute,modifier)->{
|
||||
attributes.set(attribute.name(),modifier);
|
||||
});
|
||||
}
|
||||
}
|
||||
if(Version.mcMainVersion>=14){
|
||||
//CustomModelData
|
||||
if(meta.hasCustomModelData()) {
|
||||
section_data.set("CustomModelData",meta.getCustomModelData());//int
|
||||
}
|
||||
//PersistentDataContainer
|
||||
PersistentDataContainer dataContainer = meta.getPersistentDataContainer();
|
||||
if(!dataContainer.isEmpty()){
|
||||
ConfigurationSection dataContainer_section = section_data.createSection("PersistentDataContainer");
|
||||
String cpd = EnderDragon.getInstance().getNMSManager().PDCtoString(dataContainer);
|
||||
dataContainer_section.set("data_type","nbt");
|
||||
dataContainer_section.set("data",cpd);
|
||||
}
|
||||
}
|
||||
//RepairCost
|
||||
if(meta instanceof Repairable){
|
||||
Repairable repairable = (Repairable) meta;
|
||||
section_data.set("RepairCost",repairable.getRepairCost());
|
||||
}
|
||||
//ItemFlags
|
||||
Set<ItemFlag> flags = meta.getItemFlags();
|
||||
if(!flags.isEmpty()){
|
||||
List<String> list = new ArrayList<>();
|
||||
flags.forEach(flag ->{
|
||||
list.add(flag.name());
|
||||
});
|
||||
section_data.set("ItemFlags",list);
|
||||
}
|
||||
//Unbreakable
|
||||
section_data.set("unbreakable",meta.isUnbreakable());
|
||||
//internal
|
||||
Object cpd = EnderDragon.getInstance().getNMSManager().getCPD(item);
|
||||
Map<String,Object> mp = EnderDragon.getInstance().getNMSManager().cpdToMap(cpd);
|
||||
if(mp.containsKey("tag")){
|
||||
cpd = mp.get("tag");
|
||||
mp = EnderDragon.getInstance().getNMSManager().cpdToMap(cpd);
|
||||
mp.remove("Damage");
|
||||
if(mp.containsKey("display")){
|
||||
Object display = mp.get("display");
|
||||
Map<String,Object> display_mp = EnderDragon.getInstance().getNMSManager().cpdToMap(display);
|
||||
display_mp.remove("Name");
|
||||
display_mp.remove("LocName");
|
||||
display_mp.remove("Lore");
|
||||
Object new_display = EnderDragon.getInstance().getNMSManager().getNBTTagCompound(display_mp);
|
||||
mp.put("display",new_display);
|
||||
}
|
||||
//mp.remove("display");//Name, LocName, Lore, color
|
||||
mp.remove("Enchantments");
|
||||
mp.remove("AttributeModifiers");
|
||||
mp.remove("CustomModelData");
|
||||
mp.remove("PublicBukkitValues");//PersistentDataContainer
|
||||
mp.remove("RepairCost");
|
||||
mp.remove("HideFlags");//ItemFlags
|
||||
mp.remove("Unbreakable");
|
||||
//CanDestroy, CanPlaceOn
|
||||
Object new_cpd = EnderDragon.getInstance().getNMSManager().getNBTTagCompound(mp);
|
||||
ConfigurationSection internal = section_data.createSection("internal");
|
||||
internal.set("data_type","nbt");
|
||||
internal.set("data",new_cpd.toString());
|
||||
}
|
||||
// Map<String,Object> mp = EnderDragon.getInstance().getNMSManager().getUnhandledTags(meta);
|
||||
// if(mp != null){
|
||||
// ConfigurationSection internal = section_data.createSection("internal");
|
||||
// saveUnhandledTags(internal,mp);
|
||||
// }
|
||||
|
||||
break;
|
||||
}
|
||||
default : {
|
||||
section.set("data_type","default");
|
||||
section.set("data", item);
|
||||
}
|
||||
}
|
||||
section.set("drop_chance.value",value);
|
||||
section.set("drop_chance.format",str);
|
||||
return yaml.saveToString();
|
||||
}
|
||||
public static Reward readAsReward(ConfigurationSection section){
|
||||
Set<String> strings = section.getKeys(false);
|
||||
String name = strings.iterator().next();
|
||||
ConfigurationSection section0 = section.getConfigurationSection(name);
|
||||
if(section0 == null) return null;
|
||||
String data_type = section0.getString("data_type");
|
||||
//data_type may be null
|
||||
ItemStack item;
|
||||
if("nbt".equals(data_type)) item = readFromNBT(section0,"data");
|
||||
else if("advanced".equals(data_type)) item = readFromAdvData(section0, "data");
|
||||
else item = readFromBukkit(section0,"data");
|
||||
double d0 = section0.getDouble("drop_chance.value");
|
||||
String str = section0.getString("drop_chance.format");
|
||||
return new Reward(item,new Chance(d0, str));
|
||||
}
|
||||
public static ItemStack readFromAdvData(ConfigurationSection section, String path){
|
||||
ConfigurationSection data = section.getConfigurationSection(path);
|
||||
if(data == null) return new ItemStack(Material.AIR);
|
||||
String type = data.getString("type");
|
||||
if(type == null || "AIR".equals(type)) return new ItemStack(Material.AIR);
|
||||
int amount = data.getInt("amount");
|
||||
Material material = Material.getMaterial(type);
|
||||
if(material == null) return new ItemStack(Material.AIR);
|
||||
ItemStack item = new ItemStack(material,amount);
|
||||
//internal
|
||||
if(data.contains("internal")){
|
||||
ConfigurationSection internal_section = data.getConfigurationSection("internal");
|
||||
if(internal_section!=null){
|
||||
if("nbt".equals(internal_section.getString("data_type"))){
|
||||
String nbt = internal_section.getString("data");
|
||||
Object cpd = EnderDragon.getInstance().getNMSManager().getCPD(nbt);
|
||||
Map<String,Object> mp_tag = new HashMap<>();
|
||||
mp_tag.put("tag",cpd);
|
||||
Object full_cpd = EnderDragon.getInstance().getNMSManager().getNBTTagCompound(mp_tag);
|
||||
item = EnderDragon.getInstance().getNMSManager().mergeItemCPD(item,full_cpd);
|
||||
}
|
||||
// else{
|
||||
// Map<String,Object> mp = getUnhandledTags(internal_section);
|
||||
// EnderDragon.getInstance().getNMSManager().setUnhandledTags(meta,mp);
|
||||
// }
|
||||
// Map<String,Object> mp = new HashMap<>();
|
||||
// internal_section.getKeys(false).forEach(key->{
|
||||
// Object obj = internal_section.get(key);//obj instanceof String
|
||||
// Object nbt_base = EnderDragon.getInstance().getNMSItemManager().readAsNBTBase((String) obj);
|
||||
// mp.put(key,nbt_base);
|
||||
// });
|
||||
// Map<String,Object> mp = getUnhandledTags(internal_section);
|
||||
// NBTTagCompound cpd = getNBTTagCompound(mp);
|
||||
// net.minecraft.world.item.ItemStack ei = CraftItemStack.asNMSCopy(item);
|
||||
// ei.c(cpd);
|
||||
// item = CraftItemStack.asBukkitCopy(ei);
|
||||
//EnderDragon.getInstance().getNMSManager().setUnhandledTags(meta,mp);
|
||||
}
|
||||
}
|
||||
//damage
|
||||
if(data.contains("damage")){
|
||||
int damage = data.getInt("damage");
|
||||
item.setDurability((short) damage);
|
||||
}
|
||||
ItemMeta meta = item.getItemMeta();
|
||||
if(meta == null) return item;
|
||||
//DisplayName
|
||||
String display_name = data.getString("display_name");
|
||||
if(display_name != null) meta.setDisplayName(display_name);
|
||||
//LocalizedName
|
||||
if(data.contains("localized_name")){
|
||||
String LocalizedName = data.getString("localized_name");
|
||||
if(LocalizedName != null) meta.setLocalizedName(LocalizedName);
|
||||
}
|
||||
//lore
|
||||
if(data.contains("lore")){
|
||||
List<String> lores = data.getStringList("lore");
|
||||
if(!lores.isEmpty()) meta.setLore(lores);
|
||||
}
|
||||
//Enchantments
|
||||
if(data.contains("enchants")){
|
||||
ConfigurationSection enchants = data.getConfigurationSection("enchants");
|
||||
if(enchants != null){
|
||||
//Map<Enchantment,Integer> mp = new HashMap<>();
|
||||
enchants.getKeys(false).forEach(key->{
|
||||
Enchantment enchantment = Enchantment.getByName(key);
|
||||
int level = enchants.getInt(key);
|
||||
if(enchantment != null && level>0){
|
||||
meta.addEnchant(enchantment,level,true);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
//CustomModelData
|
||||
if(data.contains("CustomModelData")){
|
||||
int CustomModelData = data.getInt("CustomModelData");
|
||||
meta.setCustomModelData(CustomModelData);
|
||||
}
|
||||
//AttributeModifiers
|
||||
if(data.contains("AttributeModifiers")){
|
||||
ConfigurationSection attributes = data.getConfigurationSection("AttributeModifiers");
|
||||
if(attributes != null){
|
||||
attributes.getKeys(false).forEach(name->{
|
||||
Attribute attribute = Attribute.valueOf(name);
|
||||
AttributeModifier modifier = (AttributeModifier) attributes.get(name);
|
||||
if(modifier != null){
|
||||
meta.addAttributeModifier(attribute,modifier);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
//RepairCost
|
||||
if(data.contains("RepairCost")){
|
||||
int cost = data.getInt("RepairCost");
|
||||
if(meta instanceof Repairable){
|
||||
((Repairable)meta).setRepairCost(cost);
|
||||
}
|
||||
}
|
||||
//ItemFlags
|
||||
if(data.contains("ItemFlags")){
|
||||
List<String> names = data.getStringList("ItemFlags");
|
||||
names.forEach(name->meta.addItemFlags(ItemFlag.valueOf(name)));
|
||||
}
|
||||
//Unbreakable
|
||||
if(data.contains("unbreakable") && data.getBoolean("unbreakable")) meta.setUnbreakable(true);
|
||||
//PersistentDataContainer
|
||||
if(data.contains("PersistentDataContainer")){
|
||||
ConfigurationSection dataContainer_section = data.getConfigurationSection("PersistentDataContainer");
|
||||
if(dataContainer_section != null){
|
||||
if("nbt".equals(dataContainer_section.getString("data_type"))){
|
||||
String nbt = dataContainer_section.getString("data");
|
||||
Object cpd = EnderDragon.getInstance().getNMSManager().getCPD(nbt);
|
||||
PersistentDataContainer container = meta.getPersistentDataContainer();
|
||||
EnderDragon.getInstance().getNMSManager().setPersistentDataContainer(container, cpd);
|
||||
}
|
||||
}
|
||||
}
|
||||
item.setItemMeta(meta);
|
||||
return item;
|
||||
}
|
||||
public static ItemStack readFromNBT(ConfigurationSection section, String path){
|
||||
String nbt = section.getString(path);
|
||||
if (nbt == null) return new ItemStack(Material.AIR);
|
||||
return EnderDragon.getInstance().getNMSItemManager().readAsItem(nbt);
|
||||
}
|
||||
public static ItemStack readFromBukkit(ConfigurationSection section, String path){
|
||||
String nbt = section.getString(path);
|
||||
if (nbt == null) return new ItemStack(Material.AIR);
|
||||
return section.getItemStack(path);
|
||||
}
|
||||
public static ItemStack readFromString(String str){
|
||||
YamlConfiguration yml = new YamlConfiguration();
|
||||
yml.set("test",str);
|
||||
return yml.getItemStack("test");
|
||||
}
|
||||
public static void addLoreFront(ItemStack item, String lore){
|
||||
ItemMeta meta = item.getItemMeta();
|
||||
if(meta != null) {
|
||||
List<String> lores = meta.getLore();
|
||||
if (lores != null) {
|
||||
lores.add(0,lore);
|
||||
meta.setLore(lores);
|
||||
}
|
||||
else {
|
||||
meta.setLore(Collections.singletonList(lore));
|
||||
}
|
||||
item.setItemMeta(meta);
|
||||
}
|
||||
}
|
||||
public static void addLoreBack(ItemStack item, String lore){
|
||||
ItemMeta meta = item.getItemMeta();
|
||||
if(meta != null) {
|
||||
List<String> lores = meta.getLore();
|
||||
if (lores != null) {
|
||||
lores.add(lore);
|
||||
meta.setLore(lores);
|
||||
}
|
||||
else {
|
||||
meta.setLore(Collections.singletonList(lore));
|
||||
}
|
||||
item.setItemMeta(meta);
|
||||
}
|
||||
}
|
||||
public static boolean isEmpty(ItemStack item){
|
||||
if(item == null) return true;
|
||||
if(item.getType() == Material.AIR) return true;
|
||||
return false;
|
||||
}
|
||||
private static void saveUnhandledTags(ConfigurationSection section, Map<String,Object> mp){
|
||||
mp.forEach((k,v)->{
|
||||
//Bukkit.broadcastMessage(k+": "+v.getClass().toString());
|
||||
if(v instanceof Map){
|
||||
saveUnhandledTags(section.createSection(k), (Map<String, Object>) v);
|
||||
}
|
||||
else section.set(k,v.toString());
|
||||
});
|
||||
}
|
||||
/**
|
||||
private static void saveUnhandledTags(ConfigurationSection section, Map<String,Object> mp){
|
||||
mp.forEach((k,v)->{
|
||||
Object obj = v;
|
||||
//Bukkit.broadcastMessage(obj.getClass().toString());
|
||||
try{
|
||||
obj = EnderDragon.getInstance().getNMSItemManager().parseNBT(v);
|
||||
}catch (Throwable ignored){
|
||||
|
||||
}
|
||||
if(obj instanceof Map){
|
||||
saveUnhandledTags(section.createSection(k), (Map<String, Object>) obj);
|
||||
}
|
||||
else section.set(k,obj);
|
||||
});
|
||||
}**/
|
||||
private static Map<String, Object> getUnhandledTags(ConfigurationSection section){
|
||||
Map<String,Object> res = new HashMap<>();
|
||||
section.getKeys(false).forEach(key->{
|
||||
Object obj = section.get(key);
|
||||
if(obj instanceof ConfigurationSection){
|
||||
ConfigurationSection subSection = section.getConfigurationSection(key);
|
||||
if(subSection != null){
|
||||
obj = getUnhandledTags(subSection);
|
||||
// Object mp = getUnhandledTags(subSection);
|
||||
// Bukkit.getLogger().info(mp.getClass().toString());
|
||||
// try{
|
||||
// obj = EnderDragon.getInstance().getNMSItemManager().getNBTBase(mp);
|
||||
// }catch (Throwable throwable){
|
||||
//
|
||||
// }
|
||||
}
|
||||
}
|
||||
else obj = EnderDragon.getInstance().getNMSManager().getCPD((String) obj);
|
||||
//else obj = EnderDragon.getInstance().getNMSItemManager().readAsNBTBase((String) obj);
|
||||
res.put(key,obj);
|
||||
});
|
||||
return res;
|
||||
}
|
||||
|
||||
// private static Object dfs(ConfigurationSection section){
|
||||
// section.getKeys(false).forEach(key->{
|
||||
// Object obj = section.get(key);
|
||||
// if(obj instanceof ConfigurationSection){
|
||||
// ConfigurationSection subSection = section.getConfigurationSection(key);
|
||||
// if(subSection != null) obj = dfs(subSection);
|
||||
// }
|
||||
// else obj = EnderDragon.getInstance().getNMSItemManager().readAsNBTBase((String) obj);
|
||||
//
|
||||
// });
|
||||
// return
|
||||
// }
|
||||
|
||||
// //internal
|
||||
// Map<String,Object> mp = EnderDragon.getInstance().getNMSManager().getUnhandledTags(meta);
|
||||
// if(mp != null){
|
||||
// ConfigurationSection internal = section_data.createSection("internal");
|
||||
// mp.forEach((k,v)->{
|
||||
// Object obj = EnderDragon.getInstance().getNMSItemManager().parseNBT(v);
|
||||
//
|
||||
// if(obj instanceof Map) obj = obj.toString();
|
||||
// else if(obj instanceof List) obj = obj.toString();
|
||||
//
|
||||
// internal.set(k,obj);
|
||||
// });
|
||||
// }
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,117 @@
|
||||
package pers.xanadu.enderdragon.manager;
|
||||
|
||||
import org.bukkit.configuration.InvalidConfigurationException;
|
||||
import org.bukkit.configuration.file.FileConfiguration;
|
||||
import org.bukkit.configuration.file.YamlConfiguration;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
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 java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
import static pers.xanadu.enderdragon.EnderDragon.*;
|
||||
|
||||
public class RewardManager {
|
||||
|
||||
public static void reload(){
|
||||
for(MyDragon dragon : DragonManager.dragons){
|
||||
dragon.datum.clear();
|
||||
File file = getRewardFile(dragon.unique_name);
|
||||
if(file == null) return;
|
||||
FileConfiguration data = YamlConfiguration.loadConfiguration(file);
|
||||
String path = "list";
|
||||
List<String> list = data.getStringList(path);
|
||||
// if list == null ?
|
||||
for(String str : list){
|
||||
YamlConfiguration yml = new YamlConfiguration();
|
||||
try{
|
||||
yml.loadFromString(str);
|
||||
Reward reward = ItemManager.readAsReward(yml);
|
||||
dragon.datum.add(reward);
|
||||
}catch (InvalidConfigurationException e){
|
||||
Lang.error(Lang.plugin_item_read_error + str);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
public static void addItem(String key,Reward reward){
|
||||
addItem(key,reward.getItem(),reward.getChance());
|
||||
}
|
||||
public static void addItem(String key, ItemStack item, Chance chance){
|
||||
MyDragon dragon = DragonManager.mp.get(key);
|
||||
if(dragon == null) return;
|
||||
File file = getRewardFile(dragon.unique_name);
|
||||
if(file == null) return;
|
||||
FileConfiguration data = YamlConfiguration.loadConfiguration(file);
|
||||
String path = "list";
|
||||
List<String> list = data.getStringList(path);
|
||||
Reward reward = new Reward(item,chance);
|
||||
list.add(reward.toString());
|
||||
data.set(path,list);
|
||||
try {
|
||||
data.save(file);
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
dragon.datum.add(reward);
|
||||
}
|
||||
public static void clearItem(String key){
|
||||
MyDragon dragon = DragonManager.mp.get(key);
|
||||
if(dragon == null) return;
|
||||
File file = getRewardFile(dragon.unique_name);
|
||||
if(file == null) return;
|
||||
FileConfiguration data = YamlConfiguration.loadConfiguration(file);
|
||||
String path = "list";
|
||||
data.set(path,"");
|
||||
try {
|
||||
data.save(file);
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
dragon.datum.clear();
|
||||
}
|
||||
public static boolean removeItem(String key,int idx){
|
||||
MyDragon dragon = DragonManager.mp.get(key);
|
||||
if(dragon == null) return false;
|
||||
File file = getRewardFile(dragon.unique_name);
|
||||
if(file == null) return false;
|
||||
FileConfiguration data = YamlConfiguration.loadConfiguration(file);
|
||||
String path = "list";
|
||||
List<String> list = data.getStringList(path);
|
||||
try{
|
||||
list.remove(idx);
|
||||
data.set(path,list);
|
||||
data.save(file);
|
||||
dragon.datum.remove(idx);
|
||||
return true;
|
||||
}catch (IndexOutOfBoundsException e){
|
||||
Lang.error("Index out of bound!");
|
||||
}catch (IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
private static File getRewardFile(String key){
|
||||
String file_path = "reward/" + key + ".yml";
|
||||
File file = new File(plugin.getDataFolder(),file_path);
|
||||
if(!file.exists()) {
|
||||
try{
|
||||
YamlConfiguration yml = new YamlConfiguration();
|
||||
yml.set("version","2.1.0");
|
||||
yml.set("list","");
|
||||
yml.save(file);
|
||||
}catch (IOException e){
|
||||
Lang.error("Not Found "+file_path+" ,skipped it.");
|
||||
return null;
|
||||
}
|
||||
}
|
||||
return new File(plugin.getDataFolder(),file_path);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,93 @@
|
||||
package pers.xanadu.enderdragon.manager;
|
||||
|
||||
import pers.xanadu.enderdragon.config.Config;
|
||||
import pers.xanadu.enderdragon.config.Lang;
|
||||
import pers.xanadu.enderdragon.task.type.*;
|
||||
import pers.xanadu.enderdragon.task.Task;
|
||||
import pers.xanadu.enderdragon.task.TaskType;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.text.ParseException;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.LocalTime;
|
||||
import java.time.format.DateTimeFormatter;
|
||||
import java.time.format.DateTimeParseException;
|
||||
import java.util.Date;
|
||||
|
||||
import static pers.xanadu.enderdragon.EnderDragon.*;
|
||||
|
||||
public class TaskManager {
|
||||
private static final DateTimeFormatter RoundTimeFormat_hm = DateTimeFormatter.ofPattern("HH:mm");
|
||||
private static final DateTimeFormatter RoundTimeFormat_all = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm");
|
||||
public static String path = "auto_respawn.next_respawn_time";
|
||||
public static Task task = null;
|
||||
public static Task parse(String string){
|
||||
String[] str = string.split(":",2);
|
||||
TaskType taskType = TaskType.getByName(str[0]);
|
||||
switch (taskType){
|
||||
case minute : {
|
||||
return new Minute(TaskType.minute,str[1]);
|
||||
}
|
||||
case hour : {
|
||||
return new Hour(TaskType.hour,str[1]);
|
||||
}
|
||||
case day : {
|
||||
return new Day(TaskType.day,str[1]);
|
||||
}
|
||||
case week : {
|
||||
return new Week(TaskType.week,str[1]);
|
||||
}
|
||||
case month : {
|
||||
return new Month(TaskType.month,str[1]);
|
||||
}
|
||||
case year : {
|
||||
return new Year(TaskType.year,str[1]);
|
||||
}
|
||||
default : {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
public static void reload(){
|
||||
task = parse(Config.auto_respawn_respawn_time);
|
||||
}
|
||||
public static LocalTime getRoundTime(String str){
|
||||
try {
|
||||
return LocalTime.parse(str, RoundTimeFormat_hm);
|
||||
}catch (DateTimeParseException e){
|
||||
Lang.error("\"respawn_time\" in config.yml error!The format of time should be HH:mm.");
|
||||
}
|
||||
return null;
|
||||
}
|
||||
public static String getRoundTimeStr(LocalDateTime time){
|
||||
return time.format(RoundTimeFormat_all);
|
||||
}
|
||||
public static LocalDateTime getLocalDateTime(String str){
|
||||
if(isValidTime(str)) return LocalDateTime.parse(str, RoundTimeFormat_all);
|
||||
return null;
|
||||
}
|
||||
public static boolean isValidTime(String str){
|
||||
SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm");
|
||||
try{
|
||||
df.parse(str);
|
||||
} catch (ParseException e) {
|
||||
Lang.error("\"next_respawn_time\" in data.yml error!The format of time should be HH:mm.");
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
public static void saveFile(LocalDateTime nextTime){
|
||||
data.set(TaskManager.path,getRoundTimeStr(nextTime));
|
||||
try{
|
||||
data.save(dataF);
|
||||
}catch (IOException ex){
|
||||
Lang.error(Lang.plugin_file_save_error.replaceAll("\\{file_name}",dataF.getName()));
|
||||
}
|
||||
}
|
||||
public static String getCurrentTimeWithSpecialFormat(){
|
||||
SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH∶mm∶ss");//这里的∶是特殊字符
|
||||
return df.format(new Date());
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,75 @@
|
||||
package pers.xanadu.enderdragon.manager;
|
||||
|
||||
import org.bukkit.configuration.ConfigurationSection;
|
||||
import org.bukkit.configuration.file.FileConfiguration;
|
||||
import org.bukkit.configuration.file.YamlConfiguration;
|
||||
import pers.xanadu.enderdragon.config.Lang;
|
||||
import pers.xanadu.enderdragon.task.DragonRespawnTimer;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.HashMap;
|
||||
|
||||
import static pers.xanadu.enderdragon.EnderDragon.plugin;
|
||||
|
||||
public class TimerManager {
|
||||
private static final HashMap<String, DragonRespawnTimer> mp = new HashMap<>();
|
||||
public static void enable(){
|
||||
File file = new File(plugin.getDataFolder(),"respawn_cd.yml");
|
||||
if(file.exists()){
|
||||
FileConfiguration fc = YamlConfiguration.loadConfiguration(file);
|
||||
ConfigurationSection section = fc.getConfigurationSection("respawn_cd");
|
||||
if(section == null) return;
|
||||
section.getKeys(false).forEach(name->{
|
||||
int set_time = section.getInt(name+".setTime");
|
||||
int rest_time = section.getInt(name+".remainTime");
|
||||
if(set_time>0){
|
||||
boolean run = section.getBoolean(name+".isRunning");
|
||||
DragonRespawnTimer timer = new DragonRespawnTimer(name,set_time,rest_time);
|
||||
if(run) timer.run();
|
||||
TimerManager.mp.put(name,timer);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
public static void save(){
|
||||
YamlConfiguration yml = new YamlConfiguration();
|
||||
mp.forEach((k,v)->{
|
||||
ConfigurationSection section = yml.createSection("respawn_cd."+k);
|
||||
if(v.getRestTime()>0){
|
||||
//section.set("world_name",k);
|
||||
section.set("setTime",v.getSetTime());
|
||||
section.set("remainTime",v.getRestTime());
|
||||
section.set("isRunning",v.isRunning());
|
||||
}
|
||||
});
|
||||
try{
|
||||
yml.save(new File(plugin.getDataFolder(),"respawn_cd.yml"));
|
||||
}catch (IOException e){
|
||||
Lang.error("Failed to save respawn_cd.yml!");
|
||||
}
|
||||
}
|
||||
public static void startTimer(String world_name){
|
||||
DragonRespawnTimer timer = mp.get(world_name);
|
||||
if(timer != null){
|
||||
timer.run();
|
||||
}
|
||||
}
|
||||
public static void setTimer(String world_name, DragonRespawnTimer timer){
|
||||
DragonRespawnTimer timer_old = mp.get(world_name);
|
||||
if(timer_old != null) timer_old.del();
|
||||
mp.put(world_name,timer);
|
||||
}
|
||||
public static DragonRespawnTimer getTimer(String world_name){
|
||||
return mp.get(world_name);
|
||||
}
|
||||
public static void removeTimer(String world_name){
|
||||
DragonRespawnTimer timer_old = mp.get(world_name);
|
||||
if(timer_old != null) timer_old.del();
|
||||
mp.remove(world_name);
|
||||
}
|
||||
public static void removeAll(){
|
||||
mp.values().forEach(DragonRespawnTimer::del);
|
||||
mp.clear();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,196 @@
|
||||
package pers.xanadu.enderdragon.manager;
|
||||
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.entity.EnderDragon;
|
||||
import org.bukkit.entity.Entity;
|
||||
import pers.xanadu.enderdragon.config.Lang;
|
||||
import pers.xanadu.enderdragon.util.Version;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import static java.lang.Math.sqrt;
|
||||
import static pers.xanadu.enderdragon.EnderDragon.getInstance;
|
||||
import static pers.xanadu.enderdragon.util.MathUtil.*;
|
||||
|
||||
public class WorldManager {
|
||||
public static final List<String> worlds = new ArrayList<>();
|
||||
private Field dimension;
|
||||
private Field world_provider;
|
||||
private Method getDimensionID;
|
||||
|
||||
public static void reload(){
|
||||
worlds.clear();
|
||||
Bukkit.getWorlds().forEach(world -> worlds.add(world.getName()));
|
||||
}
|
||||
|
||||
public static Collection<EnderDragon> getExplosionDragon(float power, Location loc){
|
||||
World world = loc.getWorld();
|
||||
if(world == null) return Collections.EMPTY_LIST;
|
||||
return getExplosionDragon(loc.getWorld(),power,loc.getX()+0.5d,loc.getY()+0.5d,loc.getZ()+0.5d);
|
||||
}
|
||||
public static Collection<EnderDragon> getExplosionDragon(World world,float power,double x,double y,double z){
|
||||
float f = power * 2.0F;
|
||||
int x1 = floor(x - (double)f - 1.0);
|
||||
int x2 = floor(x + (double)f + 1.0);
|
||||
int y1 = floor(y - (double)f - 1.0);
|
||||
int y2 = floor(y + (double)f + 1.0);
|
||||
int z1 = floor(z - (double)f - 1.0);
|
||||
int z2 = floor(z + (double)f + 1.0);
|
||||
// Collection<Entity> list = world.getNearbyEntities(new BoundingBox(x1, y1, z1, x2, y2, z2));
|
||||
Location cen = new Location(world,(x1+x2)/2d,(y1+y2)/2d,(z1+z2)/2d);
|
||||
double rx = (x2-x1)/2d;
|
||||
double ry = (y2-y1)/2d;
|
||||
double rz = (z2-z1)/2d;
|
||||
Collection<Entity> list = world.getNearbyEntities(cen,rx,ry,rz);
|
||||
List<EnderDragon> res = new ArrayList<>();
|
||||
for (Entity entity : list) {
|
||||
if(entity instanceof EnderDragon){
|
||||
double d0 = sqrt(c(entity,x, y, z)) / f;
|
||||
if (d0 <= 1.0) {
|
||||
Location loc = entity.getLocation();
|
||||
double dx = loc.getX() - x;
|
||||
double dy = loc.getY() + 6.8d - y;
|
||||
double dz = loc.getZ() - z;
|
||||
double d1 = sqrt(dx * dx + dy * dy + dz * dz);
|
||||
if (d1 != 0.0) {
|
||||
res.add((EnderDragon) entity);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return res;
|
||||
}
|
||||
// public static float a(Vector endPos, Entity entity) {
|
||||
// BoundingBox bb = entity.getBoundingBox();
|
||||
// double d0 = 1.0 / ((bb.getMaxX() - bb.getMinX()) * 2.0 + 1.0);
|
||||
// double d1 = 1.0 / ((bb.getMaxY() - bb.getMinY()) * 2.0 + 1.0);
|
||||
// double d2 = 1.0 / ((bb.getMaxZ() - bb.getMinZ()) * 2.0 + 1.0);
|
||||
// double d3 = (1.0 - Math.floor(1.0 / d0) * d0) / 2.0;
|
||||
// double d4 = (1.0 - Math.floor(1.0 / d2) * d2) / 2.0;
|
||||
// if (d0 >= 0.0 && d1 >= 0.0 && d2 >= 0.0) {
|
||||
// int i = 0;
|
||||
// int j = 0;
|
||||
//
|
||||
// for(float f = 0.0F; f <= 1.0F; f = (float)((double)f + d0)) {
|
||||
// for(float f1 = 0.0F; f1 <= 1.0F; f1 = (float)((double)f1 + d1)) {
|
||||
// for(float f2 = 0.0F; f2 <= 1.0F; f2 = (float)((double)f2 + d2)) {
|
||||
// double d5 = d(f, bb.getMinX(), bb.getMaxX());
|
||||
// double d6 = d(f1, bb.getMinY(), bb.getMaxY());
|
||||
// double d7 = d(f2, bb.getMinZ(), bb.getMaxZ());
|
||||
// //Vec3D vec3d1 = new Vec3D(d5 + d3, d6, d7 + d4);
|
||||
// Location start = new Location(entity.getWorld(),d5 + d3, d6, d7 + d4);
|
||||
// Vector dir = new Vector(endPos.getX()-start.getX(),endPos.getY()-start.getY(),endPos.getZ()-start.getZ());
|
||||
// double maxDistance = dir.length();
|
||||
// RayTraceResult result = entity.getWorld().rayTraceBlocks(start,dir,maxDistance, FluidCollisionMode.NEVER,false);
|
||||
// if(result == null) ++i;
|
||||
//// if (entity.getWorld().rayTrace(new RayTrace(vec3d1, endPos, RayTrace.BlockCollisionOption.OUTLINE, RayTrace.FluidCollisionOption.NONE, entity)).getType() == MovingObjectPosition.EnumMovingObjectType.MISS) {
|
||||
//// ++i;
|
||||
//// }
|
||||
// ++j;
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// return (float)i / (float)j;
|
||||
// } else {
|
||||
// return 0.0F;
|
||||
// }
|
||||
// }
|
||||
|
||||
public void fixWorldEnvironment(){
|
||||
Bukkit.getWorlds().forEach(world -> {
|
||||
try{
|
||||
if(isTheEnd(world)) getInstance().getNMSManager().setEnvironment(world, World.Environment.THE_END);
|
||||
}catch(ReflectiveOperationException e){
|
||||
e.printStackTrace();
|
||||
}
|
||||
});
|
||||
}
|
||||
private boolean isTheEnd(World world) throws ReflectiveOperationException {
|
||||
String version = Version.getVersion();
|
||||
switch (version) {
|
||||
case "v1_12_R1" :
|
||||
case "v1_13_R1" : {
|
||||
Object world_server = getInstance().getNMSManager().getWorldServer(world);
|
||||
if(dimension == null) dimension = world_server.getClass().getDeclaredField("dimension");
|
||||
int dimen = (int) dimension.get(world_server);
|
||||
return dimen == 1;
|
||||
}
|
||||
case "v1_13_R2" : {
|
||||
Object world_server = getInstance().getNMSManager().getWorldServer(world);
|
||||
if(dimension == null) dimension = world_server.getClass().getField("dimension");
|
||||
Object DimensionManager = dimension.get(world_server);
|
||||
if(getDimensionID == null) getDimensionID = DimensionManager.getClass().getMethod("getDimensionID");
|
||||
int dimen = (int) getDimensionID.invoke(DimensionManager);
|
||||
return dimen == 1;
|
||||
}
|
||||
case "v1_14_R1" :
|
||||
case "v1_15_R1" : {
|
||||
Object world_server = getInstance().getNMSManager().getWorldServer(world);
|
||||
if(world_provider == null) world_provider = world_server.getClass().getField("worldProvider");
|
||||
Object worldProvider = world_provider.get(world_server);
|
||||
if(dimension == null) dimension = getInstance().getNMSManager().getWorldProviderClass().getDeclaredField("f");
|
||||
dimension.setAccessible(true);
|
||||
Object DimensionManager = dimension.get(worldProvider);
|
||||
if(getDimensionID == null) getDimensionID = DimensionManager.getClass().getMethod("getDimensionID");
|
||||
int dimen = (int) getDimensionID.invoke(DimensionManager);
|
||||
return dimen == 1;
|
||||
}
|
||||
case "v1_16_R1" :
|
||||
case "v1_16_R2" :
|
||||
case "v1_16_R3" :
|
||||
case "v1_17_R1" : {
|
||||
Object world_server = getInstance().getNMSManager().getWorldServer(world);
|
||||
if(getDimensionID == null) getDimensionID = getInstance().getNMSManager().getWorldClass().getMethod("getDimensionKey");
|
||||
Object world_type = getDimensionID.invoke(world_server);
|
||||
return world_type.toString().contains("minecraft:the_end");
|
||||
}
|
||||
default : {
|
||||
if(Version.mcMainVersion < 12){
|
||||
Lang.warn("Your server version (" + version + ") is not supported!");
|
||||
return false;
|
||||
}
|
||||
Object world_server = getInstance().getNMSManager().getWorldServer(world);
|
||||
if(getDimensionID == null) getDimensionID = world_server.getClass().getMethod("getTypeKey");
|
||||
Object world_type = getDimensionID.invoke(world_server);
|
||||
return world_type.toString().contains("minecraft:the_end");
|
||||
}
|
||||
}
|
||||
/*
|
||||
try{
|
||||
//>=1.18 建议使用WorldServer::getTypeKey
|
||||
Object world_server = getInstance().getNMSManager().getWorldServer(world);
|
||||
Class<?> World_Class = Class.forName("net.minecraft.server."+ Version.getVersion()+".World");//<=1.16.5
|
||||
Object world_type = World_Class.getDeclaredMethod("getDimensionKey").invoke(world_server);//<=1.17.1
|
||||
|
||||
String string_type = world_type.toString();
|
||||
Bukkit.broadcastMessage(string_type);
|
||||
|
||||
Class<?> ResourceKey_Class = Class.forName("net.minecraft.server."+Version.getVersion()+".ResourceKey");
|
||||
Object ResourceKey = ResourceKey_Class.cast(world_type);
|
||||
Object MinecraftKey = ResourceKey_Class.getDeclaredMethod("a").invoke(ResourceKey);
|
||||
Class<?> MinecraftKey_Class = Class.forName("net.minecraft.server."+Version.getVersion()+".MinecraftKey");
|
||||
String string_type2 = (String) MinecraftKey_Class.getDeclaredMethod("getKey").invoke(MinecraftKey);
|
||||
Bukkit.broadcastMessage(string_type2);
|
||||
|
||||
|
||||
|
||||
|
||||
// Object world_c = getCraftWorld(world);
|
||||
// Object envi = CraftWorldClass.getDeclaredMethod("getEnvironment").invoke(world_c);
|
||||
// World.Environment environment = (World.Environment) envi;
|
||||
// Bukkit.broadcastMessage(environment.toString());
|
||||
}catch (ReflectiveOperationException e){
|
||||
e.printStackTrace();
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,849 @@
|
||||
package pers.xanadu.enderdragon.metrics;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.DataOutputStream;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStreamReader;
|
||||
import java.lang.reflect.Method;
|
||||
import java.net.URL;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.HashSet;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.Callable;
|
||||
import java.util.concurrent.Executors;
|
||||
import java.util.concurrent.ScheduledExecutorService;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.function.BiConsumer;
|
||||
import java.util.function.Consumer;
|
||||
import java.util.function.Supplier;
|
||||
import java.util.logging.Level;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.zip.GZIPOutputStream;
|
||||
import javax.net.ssl.HttpsURLConnection;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.configuration.file.YamlConfiguration;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.plugin.Plugin;
|
||||
import org.bukkit.plugin.java.JavaPlugin;
|
||||
|
||||
public class Metrics {
|
||||
|
||||
private final Plugin plugin;
|
||||
|
||||
private final MetricsBase metricsBase;
|
||||
|
||||
/**
|
||||
* Creates a new Metrics instance.
|
||||
*
|
||||
* @param plugin Your plugin instance.
|
||||
* @param serviceId The id of the service. It can be found at <a
|
||||
* href="https://bstats.org/what-is-my-plugin-id">What is my plugin id?</a>
|
||||
*/
|
||||
public Metrics(JavaPlugin plugin, int serviceId) {
|
||||
this.plugin = plugin;
|
||||
// Get the config file
|
||||
File bStatsFolder = new File(plugin.getDataFolder().getParentFile(), "bStats");
|
||||
File configFile = new File(bStatsFolder, "config.yml");
|
||||
YamlConfiguration config = YamlConfiguration.loadConfiguration(configFile);
|
||||
if (!config.isSet("serverUuid")) {
|
||||
config.addDefault("enabled", true);
|
||||
config.addDefault("serverUuid", UUID.randomUUID().toString());
|
||||
config.addDefault("logFailedRequests", false);
|
||||
config.addDefault("logSentData", false);
|
||||
config.addDefault("logResponseStatusText", false);
|
||||
// Inform the server owners about bStats
|
||||
config
|
||||
.options()
|
||||
.header(
|
||||
"bStats (https://bStats.org) collects some basic information for plugin authors, like how\n"
|
||||
+ "many people use their plugin and their total player count. It's recommended to keep bStats\n"
|
||||
+ "enabled, but if you're not comfortable with this, you can turn this setting off. There is no\n"
|
||||
+ "performance penalty associated with having metrics enabled, and data sent to bStats is fully\n"
|
||||
+ "anonymous.")
|
||||
.copyDefaults(true);
|
||||
try {
|
||||
config.save(configFile);
|
||||
} catch (IOException ignored) {
|
||||
}
|
||||
}
|
||||
// Load the data
|
||||
boolean enabled = config.getBoolean("enabled", true);
|
||||
String serverUUID = config.getString("serverUuid");
|
||||
boolean logErrors = config.getBoolean("logFailedRequests", false);
|
||||
boolean logSentData = config.getBoolean("logSentData", false);
|
||||
boolean logResponseStatusText = config.getBoolean("logResponseStatusText", false);
|
||||
metricsBase =
|
||||
new MetricsBase(
|
||||
"bukkit",
|
||||
serverUUID,
|
||||
serviceId,
|
||||
enabled,
|
||||
this::appendPlatformData,
|
||||
this::appendServiceData,
|
||||
submitDataTask -> Bukkit.getScheduler().runTask(plugin, submitDataTask),
|
||||
plugin::isEnabled,
|
||||
(message, error) -> this.plugin.getLogger().log(Level.WARNING, message, error),
|
||||
(message) -> this.plugin.getLogger().log(Level.INFO, message),
|
||||
logErrors,
|
||||
logSentData,
|
||||
logResponseStatusText);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a custom chart.
|
||||
*
|
||||
* @param chart The chart to add.
|
||||
*/
|
||||
public void addCustomChart(CustomChart chart) {
|
||||
metricsBase.addCustomChart(chart);
|
||||
}
|
||||
|
||||
private void appendPlatformData(JsonObjectBuilder builder) {
|
||||
builder.appendField("playerAmount", getPlayerAmount());
|
||||
builder.appendField("onlineMode", Bukkit.getOnlineMode() ? 1 : 0);
|
||||
builder.appendField("bukkitVersion", Bukkit.getVersion());
|
||||
builder.appendField("bukkitName", Bukkit.getName());
|
||||
builder.appendField("javaVersion", System.getProperty("java.version"));
|
||||
builder.appendField("osName", System.getProperty("os.name"));
|
||||
builder.appendField("osArch", System.getProperty("os.arch"));
|
||||
builder.appendField("osVersion", System.getProperty("os.version"));
|
||||
builder.appendField("coreCount", Runtime.getRuntime().availableProcessors());
|
||||
}
|
||||
|
||||
private void appendServiceData(JsonObjectBuilder builder) {
|
||||
builder.appendField("pluginVersion", plugin.getDescription().getVersion());
|
||||
}
|
||||
|
||||
private int getPlayerAmount() {
|
||||
try {
|
||||
// Around MC 1.8 the return type was changed from an array to a collection,
|
||||
// This fixes java.lang.NoSuchMethodError:
|
||||
// org.bukkit.Bukkit.getOnlinePlayers()Ljava/util/Collection;
|
||||
Method onlinePlayersMethod = Class.forName("org.bukkit.Server").getMethod("getOnlinePlayers");
|
||||
return onlinePlayersMethod.getReturnType().equals(Collection.class)
|
||||
? ((Collection<?>) onlinePlayersMethod.invoke(Bukkit.getServer())).size()
|
||||
: ((Player[]) onlinePlayersMethod.invoke(Bukkit.getServer())).length;
|
||||
} catch (Exception e) {
|
||||
// Just use the new method if the reflection failed
|
||||
return Bukkit.getOnlinePlayers().size();
|
||||
}
|
||||
}
|
||||
|
||||
public static class MetricsBase {
|
||||
|
||||
/** The version of the Metrics class. */
|
||||
public static final String METRICS_VERSION = "3.0.0";
|
||||
|
||||
private static final ScheduledExecutorService scheduler =
|
||||
Executors.newScheduledThreadPool(1, task -> new Thread(task, "bStats-Metrics"));
|
||||
|
||||
private static final String REPORT_URL = "https://bStats.org/api/v2/data/%s";
|
||||
|
||||
private final String platform;
|
||||
|
||||
private final String serverUuid;
|
||||
|
||||
private final int serviceId;
|
||||
|
||||
private final Consumer<JsonObjectBuilder> appendPlatformDataConsumer;
|
||||
|
||||
private final Consumer<JsonObjectBuilder> appendServiceDataConsumer;
|
||||
|
||||
private final Consumer<Runnable> submitTaskConsumer;
|
||||
|
||||
private final Supplier<Boolean> checkServiceEnabledSupplier;
|
||||
|
||||
private final BiConsumer<String, Throwable> errorLogger;
|
||||
|
||||
private final Consumer<String> infoLogger;
|
||||
|
||||
private final boolean logErrors;
|
||||
|
||||
private final boolean logSentData;
|
||||
|
||||
private final boolean logResponseStatusText;
|
||||
|
||||
private final Set<CustomChart> customCharts = new HashSet<>();
|
||||
|
||||
private final boolean enabled;
|
||||
|
||||
/**
|
||||
* Creates a new MetricsBase class instance.
|
||||
*
|
||||
* @param platform The platform of the service.
|
||||
* @param serviceId The id of the service.
|
||||
* @param serverUuid The server uuid.
|
||||
* @param enabled Whether or not data sending is enabled.
|
||||
* @param appendPlatformDataConsumer A consumer that receives a {@code JsonObjectBuilder} and
|
||||
* appends all platform-specific data.
|
||||
* @param appendServiceDataConsumer A consumer that receives a {@code JsonObjectBuilder} and
|
||||
* appends all service-specific data.
|
||||
* @param submitTaskConsumer A consumer that takes a runnable with the submit task. This can be
|
||||
* used to delegate the data collection to a another thread to prevent errors caused by
|
||||
* concurrency. Can be {@code null}.
|
||||
* @param checkServiceEnabledSupplier A supplier to check if the service is still enabled.
|
||||
* @param errorLogger A consumer that accepts log message and an error.
|
||||
* @param infoLogger A consumer that accepts info log messages.
|
||||
* @param logErrors Whether or not errors should be logged.
|
||||
* @param logSentData Whether or not the sent data should be logged.
|
||||
* @param logResponseStatusText Whether or not the response status text should be logged.
|
||||
*/
|
||||
public MetricsBase(
|
||||
String platform,
|
||||
String serverUuid,
|
||||
int serviceId,
|
||||
boolean enabled,
|
||||
Consumer<JsonObjectBuilder> appendPlatformDataConsumer,
|
||||
Consumer<JsonObjectBuilder> appendServiceDataConsumer,
|
||||
Consumer<Runnable> submitTaskConsumer,
|
||||
Supplier<Boolean> checkServiceEnabledSupplier,
|
||||
BiConsumer<String, Throwable> errorLogger,
|
||||
Consumer<String> infoLogger,
|
||||
boolean logErrors,
|
||||
boolean logSentData,
|
||||
boolean logResponseStatusText) {
|
||||
this.platform = platform;
|
||||
this.serverUuid = serverUuid;
|
||||
this.serviceId = serviceId;
|
||||
this.enabled = enabled;
|
||||
this.appendPlatformDataConsumer = appendPlatformDataConsumer;
|
||||
this.appendServiceDataConsumer = appendServiceDataConsumer;
|
||||
this.submitTaskConsumer = submitTaskConsumer;
|
||||
this.checkServiceEnabledSupplier = checkServiceEnabledSupplier;
|
||||
this.errorLogger = errorLogger;
|
||||
this.infoLogger = infoLogger;
|
||||
this.logErrors = logErrors;
|
||||
this.logSentData = logSentData;
|
||||
this.logResponseStatusText = logResponseStatusText;
|
||||
checkRelocation();
|
||||
if (enabled) {
|
||||
// WARNING: Removing the option to opt-out will get your plugin banned from bStats
|
||||
startSubmitting();
|
||||
}
|
||||
}
|
||||
|
||||
public void addCustomChart(CustomChart chart) {
|
||||
this.customCharts.add(chart);
|
||||
}
|
||||
|
||||
private void startSubmitting() {
|
||||
final Runnable submitTask =
|
||||
() -> {
|
||||
if (!enabled || !checkServiceEnabledSupplier.get()) {
|
||||
// Submitting data or service is disabled
|
||||
scheduler.shutdown();
|
||||
return;
|
||||
}
|
||||
if (submitTaskConsumer != null) {
|
||||
submitTaskConsumer.accept(this::submitData);
|
||||
} else {
|
||||
this.submitData();
|
||||
}
|
||||
};
|
||||
// Many servers tend to restart at a fixed time at xx:00 which causes an uneven distribution
|
||||
// of requests on the
|
||||
// bStats backend. To circumvent this problem, we introduce some randomness into the initial
|
||||
// and second delay.
|
||||
// WARNING: You must not modify and part of this Metrics class, including the submit delay or
|
||||
// frequency!
|
||||
// WARNING: Modifying this code will get your plugin banned on bStats. Just don't do it!
|
||||
long initialDelay = (long) (1000 * 60 * (3 + Math.random() * 3));
|
||||
long secondDelay = (long) (1000 * 60 * (Math.random() * 30));
|
||||
scheduler.schedule(submitTask, initialDelay, TimeUnit.MILLISECONDS);
|
||||
scheduler.scheduleAtFixedRate(
|
||||
submitTask, initialDelay + secondDelay, 1000 * 60 * 30, TimeUnit.MILLISECONDS);
|
||||
}
|
||||
|
||||
private void submitData() {
|
||||
final JsonObjectBuilder baseJsonBuilder = new JsonObjectBuilder();
|
||||
appendPlatformDataConsumer.accept(baseJsonBuilder);
|
||||
final JsonObjectBuilder serviceJsonBuilder = new JsonObjectBuilder();
|
||||
appendServiceDataConsumer.accept(serviceJsonBuilder);
|
||||
JsonObjectBuilder.JsonObject[] chartData =
|
||||
customCharts.stream()
|
||||
.map(customChart -> customChart.getRequestJsonObject(errorLogger, logErrors))
|
||||
.filter(Objects::nonNull)
|
||||
.toArray(JsonObjectBuilder.JsonObject[]::new);
|
||||
serviceJsonBuilder.appendField("id", serviceId);
|
||||
serviceJsonBuilder.appendField("customCharts", chartData);
|
||||
baseJsonBuilder.appendField("service", serviceJsonBuilder.build());
|
||||
baseJsonBuilder.appendField("serverUUID", serverUuid);
|
||||
baseJsonBuilder.appendField("metricsVersion", METRICS_VERSION);
|
||||
JsonObjectBuilder.JsonObject data = baseJsonBuilder.build();
|
||||
scheduler.execute(
|
||||
() -> {
|
||||
try {
|
||||
// Send the data
|
||||
sendData(data);
|
||||
} catch (Exception e) {
|
||||
// Something went wrong! :(
|
||||
if (logErrors) {
|
||||
errorLogger.accept("Could not submit bStats metrics data", e);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void sendData(JsonObjectBuilder.JsonObject data) throws Exception {
|
||||
if (logSentData) {
|
||||
infoLogger.accept("Sent bStats metrics data: " + data.toString());
|
||||
}
|
||||
String url = String.format(REPORT_URL, platform);
|
||||
HttpsURLConnection connection = (HttpsURLConnection) new URL(url).openConnection();
|
||||
// Compress the data to save bandwidth
|
||||
byte[] compressedData = compress(data.toString());
|
||||
connection.setRequestMethod("POST");
|
||||
connection.addRequestProperty("Accept", "application/json");
|
||||
connection.addRequestProperty("Connection", "close");
|
||||
connection.addRequestProperty("Content-Encoding", "gzip");
|
||||
connection.addRequestProperty("Content-Length", String.valueOf(compressedData.length));
|
||||
connection.setRequestProperty("Content-Type", "application/json");
|
||||
connection.setRequestProperty("User-Agent", "Metrics-Service/1");
|
||||
connection.setDoOutput(true);
|
||||
try (DataOutputStream outputStream = new DataOutputStream(connection.getOutputStream())) {
|
||||
outputStream.write(compressedData);
|
||||
}
|
||||
StringBuilder builder = new StringBuilder();
|
||||
try (BufferedReader bufferedReader =
|
||||
new BufferedReader(new InputStreamReader(connection.getInputStream()))) {
|
||||
String line;
|
||||
while ((line = bufferedReader.readLine()) != null) {
|
||||
builder.append(line);
|
||||
}
|
||||
}
|
||||
if (logResponseStatusText) {
|
||||
infoLogger.accept("Sent data to bStats and received response: " + builder);
|
||||
}
|
||||
}
|
||||
|
||||
/** Checks that the class was properly relocated. */
|
||||
private void checkRelocation() {
|
||||
// You can use the property to disable the check in your test environment
|
||||
if (System.getProperty("bstats.relocatecheck") == null
|
||||
|| !System.getProperty("bstats.relocatecheck").equals("false")) {
|
||||
// Maven's Relocate is clever and changes strings, too. So we have to use this little
|
||||
// "trick" ... :D
|
||||
final String defaultPackage =
|
||||
new String(new byte[] {'o', 'r', 'g', '.', 'b', 's', 't', 'a', 't', 's'});
|
||||
final String examplePackage =
|
||||
new String(new byte[] {'y', 'o', 'u', 'r', '.', 'p', 'a', 'c', 'k', 'a', 'g', 'e'});
|
||||
// We want to make sure no one just copy & pastes the example and uses the wrong package
|
||||
// names
|
||||
if (MetricsBase.class.getPackage().getName().startsWith(defaultPackage)
|
||||
|| MetricsBase.class.getPackage().getName().startsWith(examplePackage)) {
|
||||
throw new IllegalStateException("bStats Metrics class has not been relocated correctly!");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gzips the given string.
|
||||
*
|
||||
* @param str The string to gzip.
|
||||
* @return The gzipped string.
|
||||
*/
|
||||
private static byte[] compress(final String str) throws IOException {
|
||||
if (str == null) {
|
||||
return null;
|
||||
}
|
||||
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
|
||||
try (GZIPOutputStream gzip = new GZIPOutputStream(outputStream)) {
|
||||
gzip.write(str.getBytes(StandardCharsets.UTF_8));
|
||||
}
|
||||
return outputStream.toByteArray();
|
||||
}
|
||||
}
|
||||
|
||||
public static class DrilldownPie extends CustomChart {
|
||||
|
||||
private final Callable<Map<String, Map<String, Integer>>> callable;
|
||||
|
||||
/**
|
||||
* Class constructor.
|
||||
*
|
||||
* @param chartId The id of the chart.
|
||||
* @param callable The callable which is used to request the chart data.
|
||||
*/
|
||||
public DrilldownPie(String chartId, Callable<Map<String, Map<String, Integer>>> callable) {
|
||||
super(chartId);
|
||||
this.callable = callable;
|
||||
}
|
||||
|
||||
@Override
|
||||
public JsonObjectBuilder.JsonObject getChartData() throws Exception {
|
||||
JsonObjectBuilder valuesBuilder = new JsonObjectBuilder();
|
||||
Map<String, Map<String, Integer>> map = callable.call();
|
||||
if (map == null || map.isEmpty()) {
|
||||
// Null = skip the chart
|
||||
return null;
|
||||
}
|
||||
boolean reallyAllSkipped = true;
|
||||
for (Map.Entry<String, Map<String, Integer>> entryValues : map.entrySet()) {
|
||||
JsonObjectBuilder valueBuilder = new JsonObjectBuilder();
|
||||
boolean allSkipped = true;
|
||||
for (Map.Entry<String, Integer> valueEntry : map.get(entryValues.getKey()).entrySet()) {
|
||||
valueBuilder.appendField(valueEntry.getKey(), valueEntry.getValue());
|
||||
allSkipped = false;
|
||||
}
|
||||
if (!allSkipped) {
|
||||
reallyAllSkipped = false;
|
||||
valuesBuilder.appendField(entryValues.getKey(), valueBuilder.build());
|
||||
}
|
||||
}
|
||||
if (reallyAllSkipped) {
|
||||
// Null = skip the chart
|
||||
return null;
|
||||
}
|
||||
return new JsonObjectBuilder().appendField("values", valuesBuilder.build()).build();
|
||||
}
|
||||
}
|
||||
|
||||
public static class AdvancedPie extends CustomChart {
|
||||
|
||||
private final Callable<Map<String, Integer>> callable;
|
||||
|
||||
/**
|
||||
* Class constructor.
|
||||
*
|
||||
* @param chartId The id of the chart.
|
||||
* @param callable The callable which is used to request the chart data.
|
||||
*/
|
||||
public AdvancedPie(String chartId, Callable<Map<String, Integer>> callable) {
|
||||
super(chartId);
|
||||
this.callable = callable;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected JsonObjectBuilder.JsonObject getChartData() throws Exception {
|
||||
JsonObjectBuilder valuesBuilder = new JsonObjectBuilder();
|
||||
Map<String, Integer> map = callable.call();
|
||||
if (map == null || map.isEmpty()) {
|
||||
// Null = skip the chart
|
||||
return null;
|
||||
}
|
||||
boolean allSkipped = true;
|
||||
for (Map.Entry<String, Integer> entry : map.entrySet()) {
|
||||
if (entry.getValue() == 0) {
|
||||
// Skip this invalid
|
||||
continue;
|
||||
}
|
||||
allSkipped = false;
|
||||
valuesBuilder.appendField(entry.getKey(), entry.getValue());
|
||||
}
|
||||
if (allSkipped) {
|
||||
// Null = skip the chart
|
||||
return null;
|
||||
}
|
||||
return new JsonObjectBuilder().appendField("values", valuesBuilder.build()).build();
|
||||
}
|
||||
}
|
||||
|
||||
public static class MultiLineChart extends CustomChart {
|
||||
|
||||
private final Callable<Map<String, Integer>> callable;
|
||||
|
||||
/**
|
||||
* Class constructor.
|
||||
*
|
||||
* @param chartId The id of the chart.
|
||||
* @param callable The callable which is used to request the chart data.
|
||||
*/
|
||||
public MultiLineChart(String chartId, Callable<Map<String, Integer>> callable) {
|
||||
super(chartId);
|
||||
this.callable = callable;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected JsonObjectBuilder.JsonObject getChartData() throws Exception {
|
||||
JsonObjectBuilder valuesBuilder = new JsonObjectBuilder();
|
||||
Map<String, Integer> map = callable.call();
|
||||
if (map == null || map.isEmpty()) {
|
||||
// Null = skip the chart
|
||||
return null;
|
||||
}
|
||||
boolean allSkipped = true;
|
||||
for (Map.Entry<String, Integer> entry : map.entrySet()) {
|
||||
if (entry.getValue() == 0) {
|
||||
// Skip this invalid
|
||||
continue;
|
||||
}
|
||||
allSkipped = false;
|
||||
valuesBuilder.appendField(entry.getKey(), entry.getValue());
|
||||
}
|
||||
if (allSkipped) {
|
||||
// Null = skip the chart
|
||||
return null;
|
||||
}
|
||||
return new JsonObjectBuilder().appendField("values", valuesBuilder.build()).build();
|
||||
}
|
||||
}
|
||||
|
||||
public static class SimpleBarChart extends CustomChart {
|
||||
|
||||
private final Callable<Map<String, Integer>> callable;
|
||||
|
||||
/**
|
||||
* Class constructor.
|
||||
*
|
||||
* @param chartId The id of the chart.
|
||||
* @param callable The callable which is used to request the chart data.
|
||||
*/
|
||||
public SimpleBarChart(String chartId, Callable<Map<String, Integer>> callable) {
|
||||
super(chartId);
|
||||
this.callable = callable;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected JsonObjectBuilder.JsonObject getChartData() throws Exception {
|
||||
JsonObjectBuilder valuesBuilder = new JsonObjectBuilder();
|
||||
Map<String, Integer> map = callable.call();
|
||||
if (map == null || map.isEmpty()) {
|
||||
// Null = skip the chart
|
||||
return null;
|
||||
}
|
||||
for (Map.Entry<String, Integer> entry : map.entrySet()) {
|
||||
valuesBuilder.appendField(entry.getKey(), new int[] {entry.getValue()});
|
||||
}
|
||||
return new JsonObjectBuilder().appendField("values", valuesBuilder.build()).build();
|
||||
}
|
||||
}
|
||||
|
||||
public abstract static class CustomChart {
|
||||
|
||||
private final String chartId;
|
||||
|
||||
protected CustomChart(String chartId) {
|
||||
if (chartId == null) {
|
||||
throw new IllegalArgumentException("chartId must not be null");
|
||||
}
|
||||
this.chartId = chartId;
|
||||
}
|
||||
|
||||
public JsonObjectBuilder.JsonObject getRequestJsonObject(
|
||||
BiConsumer<String, Throwable> errorLogger, boolean logErrors) {
|
||||
JsonObjectBuilder builder = new JsonObjectBuilder();
|
||||
builder.appendField("chartId", chartId);
|
||||
try {
|
||||
JsonObjectBuilder.JsonObject data = getChartData();
|
||||
if (data == null) {
|
||||
// If the data is null we don't send the chart.
|
||||
return null;
|
||||
}
|
||||
builder.appendField("data", data);
|
||||
} catch (Throwable t) {
|
||||
if (logErrors) {
|
||||
errorLogger.accept("Failed to get data for custom chart with id " + chartId, t);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
return builder.build();
|
||||
}
|
||||
|
||||
protected abstract JsonObjectBuilder.JsonObject getChartData() throws Exception;
|
||||
}
|
||||
|
||||
public static class SimplePie extends CustomChart {
|
||||
|
||||
private final Callable<String> callable;
|
||||
|
||||
/**
|
||||
* Class constructor.
|
||||
*
|
||||
* @param chartId The id of the chart.
|
||||
* @param callable The callable which is used to request the chart data.
|
||||
*/
|
||||
public SimplePie(String chartId, Callable<String> callable) {
|
||||
super(chartId);
|
||||
this.callable = callable;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected JsonObjectBuilder.JsonObject getChartData() throws Exception {
|
||||
String value = callable.call();
|
||||
if (value == null || value.isEmpty()) {
|
||||
// Null = skip the chart
|
||||
return null;
|
||||
}
|
||||
return new JsonObjectBuilder().appendField("value", value).build();
|
||||
}
|
||||
}
|
||||
|
||||
public static class AdvancedBarChart extends CustomChart {
|
||||
|
||||
private final Callable<Map<String, int[]>> callable;
|
||||
|
||||
/**
|
||||
* Class constructor.
|
||||
*
|
||||
* @param chartId The id of the chart.
|
||||
* @param callable The callable which is used to request the chart data.
|
||||
*/
|
||||
public AdvancedBarChart(String chartId, Callable<Map<String, int[]>> callable) {
|
||||
super(chartId);
|
||||
this.callable = callable;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected JsonObjectBuilder.JsonObject getChartData() throws Exception {
|
||||
JsonObjectBuilder valuesBuilder = new JsonObjectBuilder();
|
||||
Map<String, int[]> map = callable.call();
|
||||
if (map == null || map.isEmpty()) {
|
||||
// Null = skip the chart
|
||||
return null;
|
||||
}
|
||||
boolean allSkipped = true;
|
||||
for (Map.Entry<String, int[]> entry : map.entrySet()) {
|
||||
if (entry.getValue().length == 0) {
|
||||
// Skip this invalid
|
||||
continue;
|
||||
}
|
||||
allSkipped = false;
|
||||
valuesBuilder.appendField(entry.getKey(), entry.getValue());
|
||||
}
|
||||
if (allSkipped) {
|
||||
// Null = skip the chart
|
||||
return null;
|
||||
}
|
||||
return new JsonObjectBuilder().appendField("values", valuesBuilder.build()).build();
|
||||
}
|
||||
}
|
||||
|
||||
public static class SingleLineChart extends CustomChart {
|
||||
|
||||
private final Callable<Integer> callable;
|
||||
|
||||
/**
|
||||
* Class constructor.
|
||||
*
|
||||
* @param chartId The id of the chart.
|
||||
* @param callable The callable which is used to request the chart data.
|
||||
*/
|
||||
public SingleLineChart(String chartId, Callable<Integer> callable) {
|
||||
super(chartId);
|
||||
this.callable = callable;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected JsonObjectBuilder.JsonObject getChartData() throws Exception {
|
||||
int value = callable.call();
|
||||
if (value == 0) {
|
||||
// Null = skip the chart
|
||||
return null;
|
||||
}
|
||||
return new JsonObjectBuilder().appendField("value", value).build();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* An extremely simple JSON builder.
|
||||
*
|
||||
* <p>While this class is neither feature-rich nor the most performant one, it's sufficient enough
|
||||
* for its use-case.
|
||||
*/
|
||||
public static class JsonObjectBuilder {
|
||||
|
||||
private StringBuilder builder = new StringBuilder();
|
||||
|
||||
private boolean hasAtLeastOneField = false;
|
||||
|
||||
public JsonObjectBuilder() {
|
||||
builder.append("{");
|
||||
}
|
||||
|
||||
/**
|
||||
* Appends a null field to the JSON.
|
||||
*
|
||||
* @param key The key of the field.
|
||||
* @return A reference to this object.
|
||||
*/
|
||||
public JsonObjectBuilder appendNull(String key) {
|
||||
appendFieldUnescaped(key, "null");
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Appends a string field to the JSON.
|
||||
*
|
||||
* @param key The key of the field.
|
||||
* @param value The value of the field.
|
||||
* @return A reference to this object.
|
||||
*/
|
||||
public JsonObjectBuilder appendField(String key, String value) {
|
||||
if (value == null) {
|
||||
throw new IllegalArgumentException("JSON value must not be null");
|
||||
}
|
||||
appendFieldUnescaped(key, "\"" + escape(value) + "\"");
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Appends an integer field to the JSON.
|
||||
*
|
||||
* @param key The key of the field.
|
||||
* @param value The value of the field.
|
||||
* @return A reference to this object.
|
||||
*/
|
||||
public JsonObjectBuilder appendField(String key, int value) {
|
||||
appendFieldUnescaped(key, String.valueOf(value));
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Appends an object to the JSON.
|
||||
*
|
||||
* @param key The key of the field.
|
||||
* @param object The object.
|
||||
* @return A reference to this object.
|
||||
*/
|
||||
public JsonObjectBuilder appendField(String key, JsonObject object) {
|
||||
if (object == null) {
|
||||
throw new IllegalArgumentException("JSON object must not be null");
|
||||
}
|
||||
appendFieldUnescaped(key, object.toString());
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Appends a string array to the JSON.
|
||||
*
|
||||
* @param key The key of the field.
|
||||
* @param values The string array.
|
||||
* @return A reference to this object.
|
||||
*/
|
||||
public JsonObjectBuilder appendField(String key, String[] values) {
|
||||
if (values == null) {
|
||||
throw new IllegalArgumentException("JSON values must not be null");
|
||||
}
|
||||
String escapedValues =
|
||||
Arrays.stream(values)
|
||||
.map(value -> "\"" + escape(value) + "\"")
|
||||
.collect(Collectors.joining(","));
|
||||
appendFieldUnescaped(key, "[" + escapedValues + "]");
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Appends an integer array to the JSON.
|
||||
*
|
||||
* @param key The key of the field.
|
||||
* @param values The integer array.
|
||||
* @return A reference to this object.
|
||||
*/
|
||||
public JsonObjectBuilder appendField(String key, int[] values) {
|
||||
if (values == null) {
|
||||
throw new IllegalArgumentException("JSON values must not be null");
|
||||
}
|
||||
String escapedValues =
|
||||
Arrays.stream(values).mapToObj(String::valueOf).collect(Collectors.joining(","));
|
||||
appendFieldUnescaped(key, "[" + escapedValues + "]");
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Appends an object array to the JSON.
|
||||
*
|
||||
* @param key The key of the field.
|
||||
* @param values The integer array.
|
||||
* @return A reference to this object.
|
||||
*/
|
||||
public JsonObjectBuilder appendField(String key, JsonObject[] values) {
|
||||
if (values == null) {
|
||||
throw new IllegalArgumentException("JSON values must not be null");
|
||||
}
|
||||
String escapedValues =
|
||||
Arrays.stream(values).map(JsonObject::toString).collect(Collectors.joining(","));
|
||||
appendFieldUnescaped(key, "[" + escapedValues + "]");
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Appends a field to the object.
|
||||
*
|
||||
* @param key The key of the field.
|
||||
* @param escapedValue The escaped value of the field.
|
||||
*/
|
||||
private void appendFieldUnescaped(String key, String escapedValue) {
|
||||
if (builder == null) {
|
||||
throw new IllegalStateException("JSON has already been built");
|
||||
}
|
||||
if (key == null) {
|
||||
throw new IllegalArgumentException("JSON key must not be null");
|
||||
}
|
||||
if (hasAtLeastOneField) {
|
||||
builder.append(",");
|
||||
}
|
||||
builder.append("\"").append(escape(key)).append("\":").append(escapedValue);
|
||||
hasAtLeastOneField = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Builds the JSON string and invalidates this builder.
|
||||
*
|
||||
* @return The built JSON string.
|
||||
*/
|
||||
public JsonObject build() {
|
||||
if (builder == null) {
|
||||
throw new IllegalStateException("JSON has already been built");
|
||||
}
|
||||
JsonObject object = new JsonObject(builder.append("}").toString());
|
||||
builder = null;
|
||||
return object;
|
||||
}
|
||||
|
||||
/**
|
||||
* Escapes the given string like stated in https://www.ietf.org/rfc/rfc4627.txt.
|
||||
*
|
||||
* <p>This method escapes only the necessary characters '"', '\'. and '\u0000' - '\u001F'.
|
||||
* Compact escapes are not used (e.g., '\n' is escaped as "\u000a" and not as "\n").
|
||||
*
|
||||
* @param value The value to escape.
|
||||
* @return The escaped value.
|
||||
*/
|
||||
private static String escape(String value) {
|
||||
final StringBuilder builder = new StringBuilder();
|
||||
for (int i = 0; i < value.length(); i++) {
|
||||
char c = value.charAt(i);
|
||||
if (c == '"') {
|
||||
builder.append("\\\"");
|
||||
} else if (c == '\\') {
|
||||
builder.append("\\\\");
|
||||
} else if (c <= '\u000F') {
|
||||
builder.append("\\u000").append(Integer.toHexString(c));
|
||||
} else if (c <= '\u001F') {
|
||||
builder.append("\\u00").append(Integer.toHexString(c));
|
||||
} else {
|
||||
builder.append(c);
|
||||
}
|
||||
}
|
||||
return builder.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* A super simple representation of a JSON object.
|
||||
*
|
||||
* <p>This class only exists to make methods of the {@link JsonObjectBuilder} type-safe and not
|
||||
* allow a raw string inputs for methods like {@link JsonObjectBuilder#appendField(String,
|
||||
* JsonObject)}.
|
||||
*/
|
||||
public static class JsonObject {
|
||||
|
||||
private final String value;
|
||||
|
||||
private JsonObject(String value) {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return value;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
package pers.xanadu.enderdragon.nms.BossBar;
|
||||
|
||||
import org.bukkit.World;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public interface I_BossBarManager {
|
||||
void saveBossBarData(List<World> worlds);
|
||||
void loadBossBarData(List<World> worlds);
|
||||
void setBossBar(World world,String title,String color,String style);
|
||||
}
|
||||
@@ -0,0 +1,105 @@
|
||||
package pers.xanadu.enderdragon.nms.BossBar.v1_12_R1;
|
||||
|
||||
import net.minecraft.server.v1_12_R1.BossBattle;
|
||||
import net.minecraft.server.v1_12_R1.BossBattleServer;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.configuration.InvalidConfigurationException;
|
||||
import org.bukkit.configuration.file.YamlConfiguration;
|
||||
import org.bukkit.craftbukkit.v1_12_R1.util.CraftChatMessage;
|
||||
import pers.xanadu.enderdragon.config.Lang;
|
||||
import pers.xanadu.enderdragon.nms.BossBar.I_BossBarManager;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.lang.reflect.Field;
|
||||
import java.util.List;
|
||||
|
||||
import static pers.xanadu.enderdragon.EnderDragon.getInstance;
|
||||
import static pers.xanadu.enderdragon.EnderDragon.plugin;
|
||||
|
||||
public class BossBarManager implements I_BossBarManager {
|
||||
private Field BossBattleServer = null;
|
||||
public void saveBossBarData(List<World> worlds){
|
||||
File file = new File(plugin.getDataFolder(),"world_data.yml");
|
||||
YamlConfiguration yml = new YamlConfiguration();
|
||||
worlds.forEach(world -> {
|
||||
try{
|
||||
Object edb = getInstance().getNMSManager().getEnderDragonBattle(world);
|
||||
if(BossBattleServer == null) BossBattleServer = edb.getClass().getDeclaredField("c");
|
||||
BossBattleServer.setAccessible(true);
|
||||
BossBattleServer bbs = (BossBattleServer) BossBattleServer.get(edb);
|
||||
String path = world.getName()+".";
|
||||
yml.set(path+"title",bbs.title.getText());
|
||||
yml.set(path+"color",bbs.color.name());
|
||||
yml.set(path+"style",bbs.style.name());
|
||||
}catch (ReflectiveOperationException e){
|
||||
e.printStackTrace();
|
||||
}
|
||||
});
|
||||
try{
|
||||
yml.save(file);
|
||||
Lang.info("BossBar data has been saved!");
|
||||
}catch (IOException e){
|
||||
Lang.error("Failed to save world_data!");
|
||||
}
|
||||
}
|
||||
public void loadBossBarData(List<World> worlds){
|
||||
File file = new File(plugin.getDataFolder(),"world_data.yml");
|
||||
if(!file.exists()) return;
|
||||
Lang.info("Enabling BossBar fix...");
|
||||
YamlConfiguration yml = new YamlConfiguration();
|
||||
try{
|
||||
yml.load(file);
|
||||
}catch (InvalidConfigurationException | IOException e) {
|
||||
Lang.error("Failed to load world_data!");
|
||||
return;
|
||||
}
|
||||
worlds.forEach(world -> {
|
||||
try{
|
||||
Object edb = getInstance().getNMSManager().getEnderDragonBattle(world);
|
||||
if(BossBattleServer == null) BossBattleServer = edb.getClass().getDeclaredField("c");
|
||||
BossBattleServer.setAccessible(true);
|
||||
BossBattleServer bbs = (BossBattleServer) BossBattleServer.get(edb);
|
||||
String path = world.getName()+".";
|
||||
bbs.title = CraftChatMessage.fromString(yml.getString(path+"title"), true)[0];
|
||||
bbs.color = BossBattle.BarColor.valueOf(yml.getString(path+"color"));
|
||||
bbs.style = BossBattle.BarStyle.valueOf(yml.getString(path+"style"));
|
||||
}catch (ReflectiveOperationException e){
|
||||
e.printStackTrace();
|
||||
}
|
||||
});
|
||||
}
|
||||
public void setBossBar(World world,String title,String color,String style){
|
||||
BossBattleServer bbs = new BossBattleServer(
|
||||
CraftChatMessage.fromString(title, true)[0],
|
||||
convertColor(color),
|
||||
convertStyle(style)
|
||||
);
|
||||
bbs.setCreateFog(true);
|
||||
bbs.setDarkenSky(true);
|
||||
bbs.setPlayMusic(true);
|
||||
try{
|
||||
Object edb = getInstance().getNMSManager().getEnderDragonBattle(world);
|
||||
if(BossBattleServer == null) BossBattleServer = edb.getClass().getDeclaredField("c");
|
||||
BossBattleServer.setAccessible(true);
|
||||
BossBattleServer.set(edb,bbs);
|
||||
}catch (ReflectiveOperationException e){
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
private BossBattle.BarColor convertColor(String color) {
|
||||
return BossBattle.BarColor.valueOf(color);
|
||||
}
|
||||
private BossBattle.BarStyle convertStyle(String style) {
|
||||
switch (style) {
|
||||
case "SOLID":
|
||||
default: return net.minecraft.server.v1_12_R1.BossBattle.BarStyle.PROGRESS;
|
||||
case "SEGMENTED_6": return net.minecraft.server.v1_12_R1.BossBattle.BarStyle.NOTCHED_6;
|
||||
case "SEGMENTED_10": return net.minecraft.server.v1_12_R1.BossBattle.BarStyle.NOTCHED_10;
|
||||
case "SEGMENTED_12": return net.minecraft.server.v1_12_R1.BossBattle.BarStyle.NOTCHED_12;
|
||||
case "SEGMENTED_20": return net.minecraft.server.v1_12_R1.BossBattle.BarStyle.NOTCHED_20;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,103 @@
|
||||
package pers.xanadu.enderdragon.nms.BossBar.v1_13_R1;
|
||||
|
||||
import net.minecraft.server.v1_13_R1.BossBattle;
|
||||
import net.minecraft.server.v1_13_R1.BossBattleServer;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.configuration.InvalidConfigurationException;
|
||||
import org.bukkit.configuration.file.YamlConfiguration;
|
||||
import org.bukkit.craftbukkit.v1_13_R1.util.CraftChatMessage;
|
||||
import pers.xanadu.enderdragon.config.Lang;
|
||||
import pers.xanadu.enderdragon.nms.BossBar.I_BossBarManager;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.lang.reflect.Field;
|
||||
import java.util.List;
|
||||
|
||||
import static pers.xanadu.enderdragon.EnderDragon.getInstance;
|
||||
import static pers.xanadu.enderdragon.EnderDragon.plugin;
|
||||
|
||||
public class BossBarManager implements I_BossBarManager {
|
||||
private Field BossBattleServer = null;
|
||||
public void saveBossBarData(List<World> worlds){
|
||||
File file = new File(plugin.getDataFolder(),"world_data.yml");
|
||||
YamlConfiguration yml = new YamlConfiguration();
|
||||
worlds.forEach(world -> {
|
||||
try{
|
||||
Object edb = getInstance().getNMSManager().getEnderDragonBattle(world);
|
||||
if(BossBattleServer == null) BossBattleServer = edb.getClass().getDeclaredField("c");
|
||||
BossBattleServer.setAccessible(true);
|
||||
BossBattleServer bbs = (BossBattleServer) BossBattleServer.get(edb);
|
||||
String path = world.getName()+".";
|
||||
yml.set(path+"title",bbs.title.getText());
|
||||
yml.set(path+"color",bbs.color.name());
|
||||
yml.set(path+"style",bbs.style.name());
|
||||
}catch (ReflectiveOperationException e){
|
||||
e.printStackTrace();
|
||||
}
|
||||
});
|
||||
try{
|
||||
yml.save(file);
|
||||
Lang.info("BossBar data has been saved!");
|
||||
}catch (IOException e){
|
||||
Lang.error("Failed to save world_data!");
|
||||
}
|
||||
}
|
||||
public void loadBossBarData(List<World> worlds){
|
||||
File file = new File(plugin.getDataFolder(),"world_data.yml");
|
||||
if(!file.exists()) return;
|
||||
Lang.info("Enabling BossBar fix...");
|
||||
YamlConfiguration yml = new YamlConfiguration();
|
||||
try{
|
||||
yml.load(file);
|
||||
}catch (InvalidConfigurationException | IOException e) {
|
||||
Lang.error("Failed to load world_data!");
|
||||
return;
|
||||
}
|
||||
worlds.forEach(world -> {
|
||||
try{
|
||||
Object edb = getInstance().getNMSManager().getEnderDragonBattle(world);
|
||||
if(BossBattleServer == null) BossBattleServer = edb.getClass().getDeclaredField("c");
|
||||
BossBattleServer.setAccessible(true);
|
||||
BossBattleServer bbs = (BossBattleServer) BossBattleServer.get(edb);
|
||||
String path = world.getName()+".";
|
||||
bbs.title = CraftChatMessage.fromString(yml.getString(path+"title"), true)[0];
|
||||
bbs.color = BossBattle.BarColor.valueOf(yml.getString(path+"color"));
|
||||
bbs.style = BossBattle.BarStyle.valueOf(yml.getString(path+"style"));
|
||||
}catch (ReflectiveOperationException e){
|
||||
e.printStackTrace();
|
||||
}
|
||||
});
|
||||
}
|
||||
public void setBossBar(World world,String title,String color,String style){
|
||||
BossBattleServer bbs = new BossBattleServer(
|
||||
CraftChatMessage.fromString(title, true)[0],
|
||||
convertColor(color),
|
||||
convertStyle(style)
|
||||
);
|
||||
bbs.setCreateFog(true);
|
||||
bbs.setDarkenSky(true);
|
||||
bbs.setPlayMusic(true);
|
||||
try{
|
||||
Object edb = getInstance().getNMSManager().getEnderDragonBattle(world);
|
||||
if(BossBattleServer == null) BossBattleServer = edb.getClass().getDeclaredField("c");
|
||||
BossBattleServer.setAccessible(true);
|
||||
BossBattleServer.set(edb,bbs);
|
||||
}catch (ReflectiveOperationException e){
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
private BossBattle.BarColor convertColor(String color) {
|
||||
return BossBattle.BarColor.valueOf(color);
|
||||
}
|
||||
private BossBattle.BarStyle convertStyle(String style) {
|
||||
switch (style) {
|
||||
case "SOLID":
|
||||
default: return net.minecraft.server.v1_13_R1.BossBattle.BarStyle.PROGRESS;
|
||||
case "SEGMENTED_6": return net.minecraft.server.v1_13_R1.BossBattle.BarStyle.NOTCHED_6;
|
||||
case "SEGMENTED_10": return net.minecraft.server.v1_13_R1.BossBattle.BarStyle.NOTCHED_10;
|
||||
case "SEGMENTED_12": return net.minecraft.server.v1_13_R1.BossBattle.BarStyle.NOTCHED_12;
|
||||
case "SEGMENTED_20": return net.minecraft.server.v1_13_R1.BossBattle.BarStyle.NOTCHED_20;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,103 @@
|
||||
package pers.xanadu.enderdragon.nms.BossBar.v1_13_R2;
|
||||
|
||||
import net.minecraft.server.v1_13_R2.BossBattle;
|
||||
import net.minecraft.server.v1_13_R2.BossBattleServer;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.configuration.InvalidConfigurationException;
|
||||
import org.bukkit.configuration.file.YamlConfiguration;
|
||||
import org.bukkit.craftbukkit.v1_13_R2.util.CraftChatMessage;
|
||||
import pers.xanadu.enderdragon.config.Lang;
|
||||
import pers.xanadu.enderdragon.nms.BossBar.I_BossBarManager;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.lang.reflect.Field;
|
||||
import java.util.List;
|
||||
|
||||
import static pers.xanadu.enderdragon.EnderDragon.getInstance;
|
||||
import static pers.xanadu.enderdragon.EnderDragon.plugin;
|
||||
|
||||
public class BossBarManager implements I_BossBarManager {
|
||||
private Field BossBattleServer = null;
|
||||
public void saveBossBarData(List<World> worlds){
|
||||
File file = new File(plugin.getDataFolder(),"world_data.yml");
|
||||
YamlConfiguration yml = new YamlConfiguration();
|
||||
worlds.forEach(world -> {
|
||||
try{
|
||||
Object edb = getInstance().getNMSManager().getEnderDragonBattle(world);
|
||||
if(BossBattleServer == null) BossBattleServer = edb.getClass().getDeclaredField("bossBattle");
|
||||
BossBattleServer.setAccessible(true);
|
||||
BossBattleServer bbs = (BossBattleServer) BossBattleServer.get(edb);
|
||||
String path = world.getName()+".";
|
||||
yml.set(path+"title",bbs.title.getText());
|
||||
yml.set(path+"color",bbs.color.name());
|
||||
yml.set(path+"style",bbs.style.name());
|
||||
}catch (ReflectiveOperationException e){
|
||||
e.printStackTrace();
|
||||
}
|
||||
});
|
||||
try{
|
||||
yml.save(file);
|
||||
Lang.info("BossBar data has been saved!");
|
||||
}catch (IOException e){
|
||||
Lang.error("Failed to save world_data!");
|
||||
}
|
||||
}
|
||||
public void loadBossBarData(List<World> worlds){
|
||||
File file = new File(plugin.getDataFolder(),"world_data.yml");
|
||||
if(!file.exists()) return;
|
||||
Lang.info("Enabling BossBar fix...");
|
||||
YamlConfiguration yml = new YamlConfiguration();
|
||||
try{
|
||||
yml.load(file);
|
||||
}catch (InvalidConfigurationException | IOException e) {
|
||||
Lang.error("Failed to load world_data!");
|
||||
return;
|
||||
}
|
||||
worlds.forEach(world -> {
|
||||
try{
|
||||
Object edb = getInstance().getNMSManager().getEnderDragonBattle(world);
|
||||
if(BossBattleServer == null) BossBattleServer = edb.getClass().getDeclaredField("bossBattle");
|
||||
BossBattleServer.setAccessible(true);
|
||||
BossBattleServer bbs = (BossBattleServer) BossBattleServer.get(edb);
|
||||
String path = world.getName()+".";
|
||||
bbs.title = CraftChatMessage.fromString(yml.getString(path+"title"), true)[0];
|
||||
bbs.color = BossBattle.BarColor.valueOf(yml.getString(path+"color"));
|
||||
bbs.style = BossBattle.BarStyle.valueOf(yml.getString(path+"style"));
|
||||
}catch (ReflectiveOperationException e){
|
||||
e.printStackTrace();
|
||||
}
|
||||
});
|
||||
}
|
||||
public void setBossBar(World world,String title,String color,String style){
|
||||
BossBattleServer bbs = new BossBattleServer(
|
||||
CraftChatMessage.fromString(title, true)[0],
|
||||
convertColor(color),
|
||||
convertStyle(style)
|
||||
);
|
||||
bbs.setCreateFog(true);
|
||||
bbs.setDarkenSky(true);
|
||||
bbs.setPlayMusic(true);
|
||||
try{
|
||||
Object edb = getInstance().getNMSManager().getEnderDragonBattle(world);
|
||||
if(BossBattleServer == null) BossBattleServer = edb.getClass().getField("bossBattle");
|
||||
BossBattleServer.setAccessible(true);
|
||||
BossBattleServer.set(edb,bbs);
|
||||
}catch (ReflectiveOperationException e){
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
private BossBattle.BarColor convertColor(String color) {
|
||||
return BossBattle.BarColor.valueOf(color);
|
||||
}
|
||||
private BossBattle.BarStyle convertStyle(String style) {
|
||||
switch (style) {
|
||||
case "SOLID":
|
||||
default: return net.minecraft.server.v1_13_R2.BossBattle.BarStyle.PROGRESS;
|
||||
case "SEGMENTED_6": return net.minecraft.server.v1_13_R2.BossBattle.BarStyle.NOTCHED_6;
|
||||
case "SEGMENTED_10": return net.minecraft.server.v1_13_R2.BossBattle.BarStyle.NOTCHED_10;
|
||||
case "SEGMENTED_12": return net.minecraft.server.v1_13_R2.BossBattle.BarStyle.NOTCHED_12;
|
||||
case "SEGMENTED_20": return net.minecraft.server.v1_13_R2.BossBattle.BarStyle.NOTCHED_20;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
package pers.xanadu.enderdragon.nms.NMSItem;
|
||||
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
|
||||
public interface I_NMSItemManager {
|
||||
ItemStack readAsItem(String nbt);
|
||||
ItemStack cpdToItem(Object cpd);
|
||||
Object parseNBT(Object nbt_base);
|
||||
Object readAsNBTBase(String raw);
|
||||
Object getNBTBase(Object obj);
|
||||
}
|
||||
+146
@@ -0,0 +1,146 @@
|
||||
package pers.xanadu.enderdragon.nms.NMSItem.v1_12_R1;
|
||||
|
||||
import net.minecraft.server.v1_12_R1.*;
|
||||
|
||||
import java.lang.reflect.Constructor;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.*;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
public class CraftNBTTagConfigSerializer {
|
||||
private static final Pattern ARRAY = Pattern.compile("^\\[.*]");
|
||||
private static final Pattern INTEGER = Pattern.compile("[-+]?(?:0|[1-9][0-9]*)?i", 2);
|
||||
private static final Pattern DOUBLE = Pattern.compile("[-+]?(?:[0-9]+[.]?|[0-9]*[.][0-9]+)(?:e[-+]?[0-9]+)?d", 2);
|
||||
private static final Pattern byte_format = Pattern.compile("[-+]?(?:0|[1-9][0-9]*)b", 2);
|
||||
private static final Pattern short_format = Pattern.compile("[-+]?(?:0|[1-9][0-9]*)s", 2);
|
||||
private static final Pattern integer_format = Pattern.compile("[-+]?(?:0|[1-9][0-9]*)");
|
||||
private static final Pattern long_format = Pattern.compile("[-+]?(?:0|[1-9][0-9]*)l", 2);
|
||||
private static final Pattern float_format = Pattern.compile("[-+]?(?:[0-9]+[.]?|[0-9]*[.][0-9]+)(?:e[-+]?[0-9]+)?f", 2);
|
||||
private static final Pattern double_format = Pattern.compile("[-+]?(?:[0-9]+[.]?|[0-9]*[.][0-9]+)(?:e[-+]?[0-9]+)?d", 2);
|
||||
private static final Pattern double_format2 = Pattern.compile("[-+]?(?:[0-9]+[.]|[0-9]*[.][0-9]+)(?:e[-+]?[0-9]+)?", 2);
|
||||
|
||||
|
||||
public CraftNBTTagConfigSerializer() {
|
||||
}
|
||||
|
||||
public static Object serialize(NBTBase base) {
|
||||
if (base instanceof NBTTagCompound) {
|
||||
Map<String, Object> innerMap = new HashMap();
|
||||
|
||||
for (String key : ((NBTTagCompound) base).c()) {
|
||||
innerMap.put(key, serialize(((NBTTagCompound) base).get(key)));
|
||||
}
|
||||
|
||||
return innerMap;
|
||||
}
|
||||
if (base instanceof NBTTagString) {
|
||||
return ((NBTTagString) base).c_();
|
||||
}
|
||||
else {
|
||||
return base instanceof NBTTagInt ? base + "i" : base.toString();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static NBTBase deserialize(Object object) {
|
||||
if (object instanceof Map) {
|
||||
NBTTagCompound compound = new NBTTagCompound();
|
||||
for (Object obj : ((Map) object).entrySet()) {
|
||||
Map.Entry<String, Object> entry = (Map.Entry) obj;
|
||||
compound.set(entry.getKey(), deserialize(entry.getValue()));
|
||||
}
|
||||
return compound;
|
||||
} else if (!(object instanceof List)) {
|
||||
if (object instanceof String) {
|
||||
String string = (String)object;
|
||||
if (ARRAY.matcher(string).matches()) {
|
||||
try {
|
||||
Constructor<MojangsonParser> constructor = MojangsonParser.class.getDeclaredConstructor(String.class);
|
||||
MojangsonParser parser = constructor.newInstance(string);
|
||||
Method parseArray = MojangsonParser.class.getDeclaredMethod("k");
|
||||
parseArray.setAccessible(true);
|
||||
return (NBTBase) parseArray.invoke(parser);
|
||||
} catch (Throwable e) {
|
||||
throw new RuntimeException("Could not deserialize found list ", e);
|
||||
}
|
||||
} else if (INTEGER.matcher(string).matches()) {
|
||||
return new NBTTagInt(Integer.parseInt(string.substring(0, string.length() - 1)));
|
||||
} else if (DOUBLE.matcher(string).matches()) {
|
||||
return new NBTTagDouble(Double.parseDouble(string.substring(0, string.length() - 1)));
|
||||
} else {
|
||||
try{
|
||||
Constructor<MojangsonParser> constructor = MojangsonParser.class.getDeclaredConstructor(String.class);
|
||||
MojangsonParser parser = constructor.newInstance("");
|
||||
Method parseLiteral = MojangsonParser.class.getDeclaredMethod("c", String.class);
|
||||
parseLiteral.setAccessible(true);
|
||||
NBTBase nbtBase = (NBTBase) parseLiteral.invoke(parser,string);
|
||||
if (nbtBase instanceof NBTTagInt) {
|
||||
return new NBTTagString(nbtBase.toString());
|
||||
} else {
|
||||
return (nbtBase instanceof NBTTagDouble ? new NBTTagString(String.valueOf(((NBTTagDouble)nbtBase).asDouble())) : nbtBase);
|
||||
}
|
||||
}catch (ReflectiveOperationException e){
|
||||
throw new RuntimeException("Could not deserialize NBTBase");
|
||||
}
|
||||
|
||||
}
|
||||
} else {
|
||||
throw new RuntimeException("Could not deserialize NBTBase");
|
||||
}
|
||||
} else {
|
||||
List<Object> list = (List)object;
|
||||
if (list.isEmpty()) {
|
||||
return new NBTTagList();
|
||||
}
|
||||
else {
|
||||
NBTTagList tagList = new NBTTagList();
|
||||
for (Object tag : list) {
|
||||
tagList.add(deserialize(tag));
|
||||
}
|
||||
return tagList;
|
||||
}
|
||||
}
|
||||
}
|
||||
public static NBTBase v1_12_R1_c(String raw) {
|
||||
try {
|
||||
if (float_format.matcher(raw).matches()) {
|
||||
return new NBTTagFloat(Float.parseFloat(raw.substring(0, raw.length() - 1)));
|
||||
}
|
||||
|
||||
if (byte_format.matcher(raw).matches()) {
|
||||
return new NBTTagByte(Byte.parseByte(raw.substring(0, raw.length() - 1)));
|
||||
}
|
||||
|
||||
if (long_format.matcher(raw).matches()) {
|
||||
return new NBTTagLong(Long.parseLong(raw.substring(0, raw.length() - 1)));
|
||||
}
|
||||
|
||||
if (short_format.matcher(raw).matches()) {
|
||||
return new NBTTagShort(Short.parseShort(raw.substring(0, raw.length() - 1)));
|
||||
}
|
||||
|
||||
if (integer_format.matcher(raw).matches()) {
|
||||
return new NBTTagInt(Integer.parseInt(raw));
|
||||
}
|
||||
|
||||
if (double_format.matcher(raw).matches()) {
|
||||
return new NBTTagDouble(Double.parseDouble(raw.substring(0, raw.length() - 1)));
|
||||
}
|
||||
|
||||
if (double_format2.matcher(raw).matches()) {
|
||||
return new NBTTagDouble(Double.parseDouble(raw));
|
||||
}
|
||||
|
||||
if ("true".equalsIgnoreCase(raw)) {
|
||||
return new NBTTagByte((byte)1);
|
||||
}
|
||||
|
||||
if ("false".equalsIgnoreCase(raw)) {
|
||||
return new NBTTagByte((byte)0);
|
||||
}
|
||||
} catch (NumberFormatException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return new NBTTagString(raw);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
package pers.xanadu.enderdragon.nms.NMSItem.v1_12_R1;
|
||||
|
||||
import net.minecraft.server.v1_12_R1.*;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.craftbukkit.v1_12_R1.inventory.CraftItemStack;
|
||||
import pers.xanadu.enderdragon.config.Lang;
|
||||
import pers.xanadu.enderdragon.nms.NMSItem.I_NMSItemManager;
|
||||
|
||||
public class NMSItemManager implements I_NMSItemManager {
|
||||
|
||||
public org.bukkit.inventory.ItemStack readAsItem(String nbt){
|
||||
try {
|
||||
NBTTagCompound cpd = MojangsonParser.parse(nbt);
|
||||
ItemStack ei = new ItemStack(cpd);
|
||||
return CraftItemStack.asBukkitCopy(ei);
|
||||
} catch (MojangsonParseException e) {
|
||||
Lang.error("Wrong item nbt format:"+nbt);
|
||||
return new org.bukkit.inventory.ItemStack(Material.AIR);
|
||||
}
|
||||
}
|
||||
public org.bukkit.inventory.ItemStack cpdToItem(Object cpd){
|
||||
ItemStack ei = new ItemStack((NBTTagCompound) cpd);
|
||||
return CraftItemStack.asBukkitCopy(ei);
|
||||
}
|
||||
public Object parseNBT(Object nbt_base){
|
||||
return CraftNBTTagConfigSerializer.serialize((NBTBase) nbt_base);
|
||||
}
|
||||
public Object readAsNBTBase(String raw){
|
||||
return CraftNBTTagConfigSerializer.v1_12_R1_c(raw);
|
||||
}
|
||||
public Object getNBTBase(Object obj){
|
||||
return CraftNBTTagConfigSerializer.deserialize(obj);
|
||||
}
|
||||
|
||||
}
|
||||
+151
@@ -0,0 +1,151 @@
|
||||
package pers.xanadu.enderdragon.nms.NMSItem.v1_13_R1;
|
||||
|
||||
import com.mojang.brigadier.StringReader;
|
||||
import net.minecraft.server.v1_13_R1.*;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.*;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
public class CraftNBTTagConfigSerializer {
|
||||
private static final Pattern ARRAY = Pattern.compile("^\\[.*]");
|
||||
private static final Pattern INTEGER = Pattern.compile("[-+]?(?:0|[1-9][0-9]*)?i", 2);
|
||||
private static final Pattern DOUBLE = Pattern.compile("[-+]?(?:[0-9]+[.]?|[0-9]*[.][0-9]+)(?:e[-+]?[0-9]+)?d", 2);
|
||||
public static final MojangsonParser MOJANGSON_PARSER = new MojangsonParser(new StringReader(""));
|
||||
private static final Pattern byte_format = Pattern.compile("[-+]?(?:0|[1-9][0-9]*)b", 2);
|
||||
private static final Pattern short_format = Pattern.compile("[-+]?(?:0|[1-9][0-9]*)s", 2);
|
||||
private static final Pattern integer_format = Pattern.compile("[-+]?(?:0|[1-9][0-9]*)");
|
||||
private static final Pattern long_format = Pattern.compile("[-+]?(?:0|[1-9][0-9]*)l", 2);
|
||||
private static final Pattern float_format = Pattern.compile("[-+]?(?:[0-9]+[.]?|[0-9]*[.][0-9]+)(?:e[-+]?[0-9]+)?f", 2);
|
||||
private static final Pattern double_format = Pattern.compile("[-+]?(?:[0-9]+[.]?|[0-9]*[.][0-9]+)(?:e[-+]?[0-9]+)?d", 2);
|
||||
private static final Pattern double_format_2 = Pattern.compile("[-+]?(?:[0-9]+[.]|[0-9]*[.][0-9]+)(?:e[-+]?[0-9]+)?", 2);
|
||||
|
||||
public CraftNBTTagConfigSerializer() {
|
||||
}
|
||||
|
||||
public static Object serialize(NBTBase base) {
|
||||
if (base instanceof NBTTagCompound) {
|
||||
Map<String, Object> innerMap = new HashMap();
|
||||
Iterator var3 = ((NBTTagCompound)base).getKeys().iterator();
|
||||
|
||||
while(var3.hasNext()) {
|
||||
String key = (String)var3.next();
|
||||
innerMap.put(key, serialize(((NBTTagCompound)base).get(key)));
|
||||
}
|
||||
|
||||
return innerMap;
|
||||
} else if (!(base instanceof NBTTagList)) {
|
||||
if (base instanceof NBTTagString) {
|
||||
return base.b_();
|
||||
} else {
|
||||
return base instanceof NBTTagInt ? base + "i" : base.toString();
|
||||
}
|
||||
} else {
|
||||
List<Object> baseList = new ArrayList();
|
||||
|
||||
for(int i = 0; i < ((NBTList)base).size(); ++i) {
|
||||
baseList.add(serialize(((NBTList)base).get(i)));
|
||||
}
|
||||
|
||||
return baseList;
|
||||
}
|
||||
}
|
||||
|
||||
public static NBTBase v1_13_R1_b(String str) {
|
||||
try {
|
||||
if (float_format.matcher(str).matches()) {
|
||||
return new NBTTagFloat(Float.parseFloat(str.substring(0, str.length() - 1)));
|
||||
}
|
||||
|
||||
if (byte_format.matcher(str).matches()) {
|
||||
return new NBTTagByte(Byte.parseByte(str.substring(0, str.length() - 1)));
|
||||
}
|
||||
|
||||
if (long_format.matcher(str).matches()) {
|
||||
return new NBTTagLong(Long.parseLong(str.substring(0, str.length() - 1)));
|
||||
}
|
||||
|
||||
if (short_format.matcher(str).matches()) {
|
||||
return new NBTTagShort(Short.parseShort(str.substring(0, str.length() - 1)));
|
||||
}
|
||||
|
||||
if (integer_format.matcher(str).matches()) {
|
||||
return new NBTTagInt(Integer.parseInt(str));
|
||||
}
|
||||
|
||||
if (double_format.matcher(str).matches()) {
|
||||
return new NBTTagDouble(Double.parseDouble(str.substring(0, str.length() - 1)));
|
||||
}
|
||||
|
||||
if (double_format_2.matcher(str).matches()) {
|
||||
return new NBTTagDouble(Double.parseDouble(str));
|
||||
}
|
||||
|
||||
if ("true".equalsIgnoreCase(str)) {
|
||||
return new NBTTagByte((byte)1);
|
||||
}
|
||||
|
||||
if ("false".equalsIgnoreCase(str)) {
|
||||
return new NBTTagByte((byte)0);
|
||||
}
|
||||
} catch (NumberFormatException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return new NBTTagString(str);
|
||||
}
|
||||
|
||||
public static NBTBase deserialize(Object object) {
|
||||
if (object instanceof Map) {
|
||||
NBTTagCompound compound = new NBTTagCompound();
|
||||
for (Object obj : ((Map) object).entrySet()) {
|
||||
Map.Entry<String, Object> entry = (Map.Entry) obj;
|
||||
compound.set(entry.getKey(), deserialize(entry.getValue()));
|
||||
}
|
||||
return compound;
|
||||
} else if (!(object instanceof List)) {
|
||||
if (object instanceof String) {
|
||||
String string = (String)object;
|
||||
if (ARRAY.matcher(string).matches()) {
|
||||
try {
|
||||
Method parseArray = MojangsonParser.class.getDeclaredMethod("h");
|
||||
parseArray.setAccessible(true);
|
||||
MojangsonParser parser = new MojangsonParser(new StringReader(string));
|
||||
return (NBTBase) parseArray.invoke(parser);
|
||||
} catch (Throwable e) {
|
||||
throw new RuntimeException("Could not deserialize found list ", e);
|
||||
}
|
||||
} else if (INTEGER.matcher(string).matches()) {
|
||||
return new NBTTagInt(Integer.parseInt(string.substring(0, string.length() - 1)));
|
||||
} else if (DOUBLE.matcher(string).matches()) {
|
||||
return new NBTTagDouble(Double.parseDouble(string.substring(0, string.length() - 1)));
|
||||
} else {
|
||||
try{
|
||||
Method parseLiteral = MojangsonParser.class.getDeclaredMethod("b", String.class);
|
||||
parseLiteral.setAccessible(true);
|
||||
NBTBase nbtBase = (NBTBase) parseLiteral.invoke(MOJANGSON_PARSER,string);
|
||||
if (nbtBase instanceof NBTTagInt) {
|
||||
return new NBTTagString(nbtBase.b_());
|
||||
} else {
|
||||
return (nbtBase instanceof NBTTagDouble ? new NBTTagString(String.valueOf(((NBTTagDouble)nbtBase).asDouble())) : nbtBase);
|
||||
}
|
||||
}catch (ReflectiveOperationException e){
|
||||
throw new RuntimeException("Could not deserialize NBTBase");
|
||||
}
|
||||
}
|
||||
} else {
|
||||
throw new RuntimeException("Could not deserialize NBTBase");
|
||||
}
|
||||
} else {
|
||||
List<Object> list = (List)object;
|
||||
if (list.isEmpty()) {
|
||||
return new NBTTagList();
|
||||
} else {
|
||||
NBTTagList tagList = new NBTTagList();
|
||||
for (Object tag : list) {
|
||||
tagList.add(deserialize(tag));
|
||||
}
|
||||
return tagList;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
package pers.xanadu.enderdragon.nms.NMSItem.v1_13_R1;
|
||||
|
||||
import com.mojang.brigadier.exceptions.CommandSyntaxException;
|
||||
import net.minecraft.server.v1_13_R1.ItemStack;
|
||||
import net.minecraft.server.v1_13_R1.MojangsonParser;
|
||||
import net.minecraft.server.v1_13_R1.NBTBase;
|
||||
import net.minecraft.server.v1_13_R1.NBTTagCompound;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.craftbukkit.v1_13_R1.inventory.CraftItemStack;
|
||||
import pers.xanadu.enderdragon.config.Lang;
|
||||
import pers.xanadu.enderdragon.nms.NMSItem.I_NMSItemManager;
|
||||
|
||||
public class NMSItemManager implements I_NMSItemManager {
|
||||
public org.bukkit.inventory.ItemStack readAsItem(String nbt){
|
||||
try {
|
||||
NBTTagCompound cpd = MojangsonParser.parse(nbt);
|
||||
ItemStack ei = ItemStack.a(cpd);
|
||||
return CraftItemStack.asBukkitCopy(ei);
|
||||
} catch (CommandSyntaxException e) {
|
||||
Lang.error("Wrong item nbt format:"+nbt);
|
||||
return new org.bukkit.inventory.ItemStack(Material.AIR);
|
||||
}
|
||||
}
|
||||
public org.bukkit.inventory.ItemStack cpdToItem(Object cpd){
|
||||
ItemStack ei = ItemStack.a((NBTTagCompound) cpd);
|
||||
return CraftItemStack.asBukkitCopy(ei);
|
||||
}
|
||||
public Object parseNBT(Object nbt_base){
|
||||
return CraftNBTTagConfigSerializer.serialize((NBTBase) nbt_base);
|
||||
}
|
||||
public Object readAsNBTBase(String raw){
|
||||
return CraftNBTTagConfigSerializer.v1_13_R1_b(raw);
|
||||
}
|
||||
public Object getNBTBase(Object obj){
|
||||
return CraftNBTTagConfigSerializer.deserialize(obj);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
package pers.xanadu.enderdragon.nms.NMSItem.v1_13_R2_above;
|
||||
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import pers.xanadu.enderdragon.EnderDragon;
|
||||
import pers.xanadu.enderdragon.config.Lang;
|
||||
import pers.xanadu.enderdragon.nms.NMSItem.I_NMSItemManager;
|
||||
|
||||
public class NMSItemManager implements I_NMSItemManager {
|
||||
public ItemStack readAsItem(String nbt){
|
||||
try {
|
||||
return EnderDragon.getInstance().getNMSManager().getItemStack(nbt);
|
||||
} catch (Throwable e) {
|
||||
Lang.error("Wrong item nbt format:"+nbt);
|
||||
return new org.bukkit.inventory.ItemStack(Material.AIR);
|
||||
}
|
||||
}
|
||||
public ItemStack cpdToItem(Object cpd){
|
||||
return EnderDragon.getInstance().getNMSManager().getItemStack(cpd);
|
||||
}
|
||||
public Object parseNBT(Object nbt_base){
|
||||
return EnderDragon.getInstance().getNMSManager().serializeNBTBase(nbt_base);
|
||||
}
|
||||
public Object readAsNBTBase(String raw){
|
||||
return EnderDragon.getInstance().getNMSManager().StringParseLiteral(raw);
|
||||
}
|
||||
public Object getNBTBase(Object obj){
|
||||
return EnderDragon.getInstance().getNMSManager().deserializeObject(obj);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
package pers.xanadu.enderdragon.nms.RespawnAnchor;
|
||||
|
||||
import org.bukkit.World;
|
||||
|
||||
public interface I_RespawnAnchorManager {
|
||||
boolean isRespawnAnchorWorks(World world);
|
||||
}
|
||||
+15
@@ -0,0 +1,15 @@
|
||||
package pers.xanadu.enderdragon.nms.RespawnAnchor.v1_16_R1;
|
||||
|
||||
import net.minecraft.server.v1_16_R1.DimensionManager;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.craftbukkit.v1_16_R1.CraftWorld;
|
||||
import pers.xanadu.enderdragon.nms.RespawnAnchor.I_RespawnAnchorManager;
|
||||
|
||||
public class RespawnAnchorManager implements I_RespawnAnchorManager {
|
||||
public boolean isRespawnAnchorWorks(World world){
|
||||
CraftWorld cw = (CraftWorld) world;
|
||||
net.minecraft.server.v1_16_R1.World ew = cw.getHandle();
|
||||
DimensionManager dm = ew.getDimensionManager();
|
||||
return dm.isRespawnAnchorWorks();
|
||||
}
|
||||
}
|
||||
+15
@@ -0,0 +1,15 @@
|
||||
package pers.xanadu.enderdragon.nms.RespawnAnchor.v1_16_R2;
|
||||
|
||||
import net.minecraft.server.v1_16_R2.DimensionManager;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.craftbukkit.v1_16_R2.CraftWorld;
|
||||
import pers.xanadu.enderdragon.nms.RespawnAnchor.I_RespawnAnchorManager;
|
||||
|
||||
public class RespawnAnchorManager implements I_RespawnAnchorManager {
|
||||
public boolean isRespawnAnchorWorks(World world){
|
||||
CraftWorld cw = (CraftWorld) world;
|
||||
net.minecraft.server.v1_16_R2.World ew = cw.getHandle();
|
||||
DimensionManager dm = ew.getDimensionManager();
|
||||
return dm.isRespawnAnchorWorks();
|
||||
}
|
||||
}
|
||||
+15
@@ -0,0 +1,15 @@
|
||||
package pers.xanadu.enderdragon.nms.RespawnAnchor.v1_16_R3;
|
||||
|
||||
import net.minecraft.server.v1_16_R3.DimensionManager;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.craftbukkit.v1_16_R3.CraftWorld;
|
||||
import pers.xanadu.enderdragon.nms.RespawnAnchor.I_RespawnAnchorManager;
|
||||
|
||||
public class RespawnAnchorManager implements I_RespawnAnchorManager {
|
||||
public boolean isRespawnAnchorWorks(World world){
|
||||
CraftWorld cw = (CraftWorld) world;
|
||||
net.minecraft.server.v1_16_R3.World ew = cw.getHandle();
|
||||
DimensionManager dm = ew.getDimensionManager();
|
||||
return dm.isRespawnAnchorWorks();
|
||||
}
|
||||
}
|
||||
+15
@@ -0,0 +1,15 @@
|
||||
package pers.xanadu.enderdragon.nms.RespawnAnchor.v1_17_R1;
|
||||
|
||||
import net.minecraft.world.level.dimension.DimensionManager;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.craftbukkit.v1_17_R1.CraftWorld;
|
||||
import pers.xanadu.enderdragon.nms.RespawnAnchor.I_RespawnAnchorManager;
|
||||
|
||||
public class RespawnAnchorManager implements I_RespawnAnchorManager {
|
||||
public boolean isRespawnAnchorWorks(World world){
|
||||
CraftWorld cw = (CraftWorld) world;
|
||||
net.minecraft.world.level.World ew = cw.getHandle();
|
||||
DimensionManager dm = ew.getDimensionManager();
|
||||
return dm.isRespawnAnchorWorks();
|
||||
}
|
||||
}
|
||||
+10
@@ -0,0 +1,10 @@
|
||||
package pers.xanadu.enderdragon.nms.RespawnAnchor.v1_18_above;
|
||||
|
||||
import org.bukkit.World;
|
||||
import pers.xanadu.enderdragon.nms.RespawnAnchor.I_RespawnAnchorManager;
|
||||
|
||||
public class RespawnAnchorManager implements I_RespawnAnchorManager {
|
||||
public boolean isRespawnAnchorWorks(World world){
|
||||
return world.isRespawnAnchorWorks();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
package pers.xanadu.enderdragon.nms.WorldData;
|
||||
|
||||
import org.bukkit.World;
|
||||
|
||||
public interface I_WorldDataManager {
|
||||
long getGameTime(World world);
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
package pers.xanadu.enderdragon.nms.WorldData.v1_12_R1;
|
||||
|
||||
import net.minecraft.server.v1_12_R1.WorldServer;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.craftbukkit.v1_12_R1.CraftWorld;
|
||||
import pers.xanadu.enderdragon.nms.WorldData.I_WorldDataManager;
|
||||
|
||||
public class WorldDataManager implements I_WorldDataManager {
|
||||
public long getGameTime(World world){
|
||||
CraftWorld cw = (CraftWorld) world;
|
||||
WorldServer ws = cw.getHandle();
|
||||
return ws.getTime();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
package pers.xanadu.enderdragon.nms.WorldData.v1_13_R1;
|
||||
|
||||
import net.minecraft.server.v1_13_R1.WorldServer;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.craftbukkit.v1_13_R1.CraftWorld;
|
||||
import pers.xanadu.enderdragon.nms.WorldData.I_WorldDataManager;
|
||||
|
||||
public class WorldDataManager implements I_WorldDataManager {
|
||||
public long getGameTime(World world){
|
||||
CraftWorld cw = (CraftWorld) world;
|
||||
WorldServer ws = cw.getHandle();
|
||||
return ws.getTime();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
package pers.xanadu.enderdragon.nms.WorldData.v1_13_R2;
|
||||
|
||||
import net.minecraft.server.v1_13_R2.WorldServer;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.craftbukkit.v1_13_R2.CraftWorld;
|
||||
import pers.xanadu.enderdragon.nms.WorldData.I_WorldDataManager;
|
||||
|
||||
public class WorldDataManager implements I_WorldDataManager {
|
||||
public long getGameTime(World world){
|
||||
CraftWorld cw = (CraftWorld) world;
|
||||
WorldServer ws = cw.getHandle();
|
||||
return ws.getTime();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
package pers.xanadu.enderdragon.nms.WorldData.v1_14_R1;
|
||||
|
||||
import net.minecraft.server.v1_14_R1.WorldServer;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.craftbukkit.v1_14_R1.CraftWorld;
|
||||
import pers.xanadu.enderdragon.nms.WorldData.I_WorldDataManager;
|
||||
|
||||
public class WorldDataManager implements I_WorldDataManager {
|
||||
public long getGameTime(World world){
|
||||
CraftWorld cw = (CraftWorld) world;
|
||||
WorldServer ws = cw.getHandle();
|
||||
return ws.getTime();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
package pers.xanadu.enderdragon.nms.WorldData.v1_15_R1;
|
||||
|
||||
import net.minecraft.server.v1_15_R1.WorldServer;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.craftbukkit.v1_15_R1.CraftWorld;
|
||||
import pers.xanadu.enderdragon.nms.WorldData.I_WorldDataManager;
|
||||
|
||||
public class WorldDataManager implements I_WorldDataManager {
|
||||
public long getGameTime(World world){
|
||||
CraftWorld cw = (CraftWorld) world;
|
||||
WorldServer ws = cw.getHandle();
|
||||
return ws.getTime();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
package pers.xanadu.enderdragon.nms.WorldData.v1_16_R1;
|
||||
|
||||
import net.minecraft.server.v1_16_R1.WorldServer;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.craftbukkit.v1_16_R1.CraftWorld;
|
||||
import pers.xanadu.enderdragon.nms.WorldData.I_WorldDataManager;
|
||||
|
||||
public class WorldDataManager implements I_WorldDataManager {
|
||||
public long getGameTime(World world){
|
||||
CraftWorld cw = (CraftWorld) world;
|
||||
WorldServer ws = cw.getHandle();
|
||||
return ws.getTime();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
package pers.xanadu.enderdragon.nms.WorldData.v1_16_R2;
|
||||
|
||||
import net.minecraft.server.v1_16_R2.WorldServer;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.craftbukkit.v1_16_R2.CraftWorld;
|
||||
import pers.xanadu.enderdragon.nms.WorldData.I_WorldDataManager;
|
||||
|
||||
public class WorldDataManager implements I_WorldDataManager {
|
||||
public long getGameTime(World world){
|
||||
CraftWorld cw = (CraftWorld) world;
|
||||
WorldServer ws = cw.getHandle();
|
||||
return ws.getTime();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
package pers.xanadu.enderdragon.nms.WorldData.v1_16_R3;
|
||||
|
||||
import net.minecraft.server.v1_16_R3.WorldServer;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.craftbukkit.v1_16_R3.CraftWorld;
|
||||
import pers.xanadu.enderdragon.nms.WorldData.I_WorldDataManager;
|
||||
|
||||
public class WorldDataManager implements I_WorldDataManager {
|
||||
public long getGameTime(World world){
|
||||
CraftWorld cw = (CraftWorld) world;
|
||||
WorldServer ws = cw.getHandle();
|
||||
return ws.getTime();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
package pers.xanadu.enderdragon.nms.WorldData.v1_17_above;
|
||||
|
||||
import org.bukkit.World;
|
||||
import pers.xanadu.enderdragon.nms.WorldData.I_WorldDataManager;
|
||||
|
||||
public class WorldDataManager implements I_WorldDataManager {
|
||||
public long getGameTime(World world){
|
||||
return world.getGameTime();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
package pers.xanadu.enderdragon.reward;
|
||||
|
||||
|
||||
public class Chance {
|
||||
private double value;
|
||||
private String str;
|
||||
public Chance(Chance chance){
|
||||
str = chance.str;
|
||||
value = chance.value;
|
||||
}
|
||||
public Chance(double d0,String str){
|
||||
this.str = str;
|
||||
this.value = d0;
|
||||
}
|
||||
public double getValue(){
|
||||
return value;
|
||||
}
|
||||
public String getStr(){
|
||||
return str;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
package pers.xanadu.enderdragon.reward;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.TreeMap;
|
||||
|
||||
public enum DistType {
|
||||
killer,
|
||||
drop,//glow?
|
||||
all,
|
||||
rank,//num
|
||||
pack,//num
|
||||
termwise,
|
||||
unknown;
|
||||
|
||||
private static final Map<String, DistType> mp = new TreeMap<>(String.CASE_INSENSITIVE_ORDER);
|
||||
|
||||
public static DistType getByName(String str){
|
||||
//if(str == null) return drop;
|
||||
return mp.getOrDefault(str,unknown);
|
||||
}
|
||||
static {
|
||||
DistType[] values = DistType.values();
|
||||
for (DistType type : values) {
|
||||
String name = type.name();
|
||||
mp.put(name, type);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,50 @@
|
||||
package pers.xanadu.enderdragon.reward;
|
||||
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import pers.xanadu.enderdragon.manager.ItemManager;
|
||||
|
||||
|
||||
public class Reward extends ItemStack {
|
||||
protected String name;
|
||||
protected Chance chance;
|
||||
private ItemStack item;
|
||||
|
||||
@Override
|
||||
public String toString(){
|
||||
return ItemManager.write(this);
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return this.name;
|
||||
}
|
||||
//
|
||||
// @Override
|
||||
// public int hashCode() {
|
||||
// return this.name.hashCode();
|
||||
// }
|
||||
|
||||
public ItemStack getItem() {
|
||||
if(item == null) return new ItemStack(Material.AIR);
|
||||
return item.clone();
|
||||
}
|
||||
public Chance getChance(){
|
||||
return this.chance;
|
||||
}
|
||||
|
||||
|
||||
|
||||
protected Reward(ItemStack item,String chance) {
|
||||
this.item = item;
|
||||
|
||||
}
|
||||
public Reward(ItemStack item, Chance chance){
|
||||
this.item = item;
|
||||
this.chance = chance;
|
||||
}
|
||||
public Reward(ItemStack item){
|
||||
this.item = item;
|
||||
this.chance = null;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,59 @@
|
||||
package pers.xanadu.enderdragon.reward;
|
||||
|
||||
import org.bukkit.configuration.ConfigurationSection;
|
||||
import org.bukkit.entity.EnderDragon;
|
||||
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 java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.ThreadLocalRandom;
|
||||
|
||||
public abstract class RewardDist {
|
||||
public static RewardDist parse(ConfigurationSection section){
|
||||
if(section == null) return new Dist_Drop();
|
||||
String type_name = section.getString("type");
|
||||
DistType type = DistType.getByName(type_name);
|
||||
switch (type){
|
||||
case all : {
|
||||
return new Dist_All();
|
||||
}
|
||||
case drop : {
|
||||
return new Dist_Drop(section.getConfigurationSection("drop"));
|
||||
}
|
||||
case killer : {
|
||||
return new Dist_Killer();
|
||||
}
|
||||
case pack : {
|
||||
return new Dist_Pack(section.getConfigurationSection("pack"));
|
||||
}
|
||||
case rank : {
|
||||
return new Dist_Rank(section.getConfigurationSection("rank"));
|
||||
}
|
||||
case termwise : {
|
||||
return new Dist_Termwise();
|
||||
}
|
||||
default : {
|
||||
Lang.error("Unknown reward_dist type: "+type_name);
|
||||
return new Dist_Drop();
|
||||
}
|
||||
}
|
||||
}
|
||||
public List<ItemStack> getDropReward(MyDragon myDragon){
|
||||
List<ItemStack> list = new ArrayList<>();
|
||||
for(Reward reward : myDragon.datum){
|
||||
double chance = reward.getChance().getValue();
|
||||
if(chance > ThreadLocalRandom.current().nextDouble(100)){
|
||||
list.add(reward.getItem());
|
||||
}
|
||||
}
|
||||
return list;
|
||||
}
|
||||
public void handle_dist(final MyDragon myDragon,final EnderDragon dragon,final Player killer){
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
package pers.xanadu.enderdragon.reward.dist;
|
||||
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.entity.EnderDragon;
|
||||
import org.bukkit.entity.Player;
|
||||
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 java.util.List;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
public class Dist_All extends RewardDist {
|
||||
@Override
|
||||
public void handle_dist(final MyDragon myDragon,final EnderDragon dragon,final Player killer){
|
||||
ConcurrentHashMap<String,Double> damage_data = DamageManager.data.get(dragon.getUniqueId());
|
||||
if(damage_data == null) return;
|
||||
List<ItemStack> items = getDropReward(myDragon);
|
||||
if(items.isEmpty()) return;
|
||||
Bukkit.getOnlinePlayers().forEach(p->{
|
||||
if(damage_data.containsKey(p.getName())){
|
||||
boolean full = false;
|
||||
for(ItemStack item : items){
|
||||
if(full || p.getInventory().firstEmpty() == -1){
|
||||
p.getWorld().dropItem(p.getLocation(),item);
|
||||
full = true;
|
||||
}
|
||||
else p.getInventory().addItem(item);
|
||||
}
|
||||
if(full) Lang.sendFeedback(p, Lang.dragon_player_inv_full);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,53 @@
|
||||
package pers.xanadu.enderdragon.reward.dist;
|
||||
|
||||
import org.bukkit.ChatColor;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.configuration.ConfigurationSection;
|
||||
import org.bukkit.entity.EnderDragon;
|
||||
import org.bukkit.entity.Item;
|
||||
import org.bukkit.entity.Player;
|
||||
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 java.util.List;
|
||||
import java.util.concurrent.ThreadLocalRandom;
|
||||
|
||||
import static pers.xanadu.enderdragon.manager.GlowManager.setGlowingColor;
|
||||
|
||||
public class Dist_Drop extends RewardDist {
|
||||
private final GlowManager.GlowColor color;
|
||||
public Dist_Drop(ConfigurationSection section){
|
||||
if(section == null) color = GlowManager.GlowColor.NONE;
|
||||
else {
|
||||
String color = section.getString("glow","NONE").toUpperCase();
|
||||
this.color = GlowManager.GlowColor.valueOf(color);
|
||||
}
|
||||
}
|
||||
public Dist_Drop(){
|
||||
color = GlowManager.GlowColor.NONE;
|
||||
}
|
||||
@Override
|
||||
public void handle_dist(final MyDragon myDragon, final EnderDragon dragon, final Player killer){
|
||||
List<ItemStack> items = getDropReward(myDragon);
|
||||
if(items.isEmpty()) return;
|
||||
World world = dragon.getWorld();
|
||||
Location loc = dragon.getLocation();
|
||||
items.forEach(item->{
|
||||
Item entity_item = world.dropItemNaturally(loc,item);
|
||||
ChatColor color = getGlowColor();
|
||||
if(color!=null) setGlowingColor(entity_item,color);
|
||||
double x = ThreadLocalRandom.current().nextDouble(0.25);
|
||||
double y = ThreadLocalRandom.current().nextDouble(0.25);
|
||||
double z = ThreadLocalRandom.current().nextDouble(0.25);
|
||||
entity_item.setVelocity(new Vector(x,y,z));
|
||||
});
|
||||
}
|
||||
|
||||
public ChatColor getGlowColor(){
|
||||
return GlowManager.getGlowColor(color);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
package pers.xanadu.enderdragon.reward.dist;
|
||||
|
||||
import org.bukkit.entity.EnderDragon;
|
||||
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 java.util.List;
|
||||
|
||||
public class Dist_Killer extends RewardDist {
|
||||
@Override
|
||||
public void handle_dist(final MyDragon myDragon,final EnderDragon dragon,final Player p){
|
||||
List<ItemStack> items = getDropReward(myDragon);
|
||||
if(items.isEmpty()) return;
|
||||
if(p != null){
|
||||
boolean full = false;
|
||||
for(ItemStack item : items){
|
||||
if(full || p.getInventory().firstEmpty() == -1){
|
||||
p.getWorld().dropItem(p.getLocation(),item);
|
||||
full = true;
|
||||
}
|
||||
else p.getInventory().addItem(item);
|
||||
}
|
||||
if(full) Lang.sendFeedback(p, Lang.dragon_player_inv_full);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,53 @@
|
||||
package pers.xanadu.enderdragon.reward.dist;
|
||||
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.configuration.ConfigurationSection;
|
||||
import org.bukkit.entity.EnderDragon;
|
||||
import org.bukkit.entity.Player;
|
||||
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.AExpJ;
|
||||
import pers.xanadu.enderdragon.util.MyDragon;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
public class Dist_Pack extends RewardDist {
|
||||
private final int max_num;
|
||||
public Dist_Pack(ConfigurationSection section){
|
||||
if(section == null) max_num = 1;
|
||||
else max_num = section.getInt("max_num",1);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handle_dist(final MyDragon myDragon,final EnderDragon dragon,final Player killer){
|
||||
ConcurrentHashMap<String,Double> damage_data = DamageManager.data.get(dragon.getUniqueId());
|
||||
if(damage_data == null) return;
|
||||
List<ItemStack> items = getDropReward(myDragon);
|
||||
if(items.isEmpty()) return;
|
||||
int m = Math.min(max_num,damage_data.size());
|
||||
if(m<=0) return;
|
||||
List<String> receivers = AExpJ.sample(damage_data,m);
|
||||
receivers.forEach(receiver->{
|
||||
Player p = Bukkit.getPlayer(receiver);
|
||||
if(p != null){
|
||||
boolean full = false;
|
||||
for(ItemStack item : items){
|
||||
if(full || p.getInventory().firstEmpty() == -1){
|
||||
p.getWorld().dropItem(p.getLocation(),item);
|
||||
full = true;
|
||||
}
|
||||
else p.getInventory().addItem(item);
|
||||
}
|
||||
if(full) Lang.sendFeedback(p, Lang.dragon_player_inv_full);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public int getMax_num(){
|
||||
return max_num;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,57 @@
|
||||
package pers.xanadu.enderdragon.reward.dist;
|
||||
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.configuration.ConfigurationSection;
|
||||
import org.bukkit.entity.EnderDragon;
|
||||
import org.bukkit.entity.Player;
|
||||
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 java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
public class Dist_Rank extends RewardDist {
|
||||
private final int max_num;
|
||||
public Dist_Rank(ConfigurationSection section){
|
||||
if(section == null) max_num = 1;
|
||||
else max_num = section.getInt("max_num",1);
|
||||
}
|
||||
public int getMax_num(){
|
||||
return max_num;
|
||||
}
|
||||
@Override
|
||||
public void handle_dist(final MyDragon myDragon,final EnderDragon dragon,final Player killer){
|
||||
ConcurrentHashMap<String,Double> damage_data = DamageManager.data.get(dragon.getUniqueId());
|
||||
if(damage_data == null) return;
|
||||
List<ItemStack> items = getDropReward(myDragon);
|
||||
if(items.isEmpty()) return;
|
||||
int m = Math.min(max_num,damage_data.size());
|
||||
if(m<=0) return;
|
||||
List<Map.Entry<String, Double>> list = damage_data.entrySet().stream().sorted(Dist_Rank::sortByDamage).collect(Collectors.toList());
|
||||
for(int i=0;i<m;i++){
|
||||
String name = list.get(i).getKey();
|
||||
Player p = Bukkit.getPlayer(name);
|
||||
if(p != null){
|
||||
boolean full = false;
|
||||
for(ItemStack item : items){
|
||||
if(full || p.getInventory().firstEmpty() == -1){
|
||||
p.getWorld().dropItem(p.getLocation(),item);
|
||||
full = true;
|
||||
}
|
||||
else p.getInventory().addItem(item);
|
||||
}
|
||||
if(full) Lang.sendFeedback(p, Lang.dragon_player_inv_full);
|
||||
}
|
||||
}
|
||||
}
|
||||
private static <T> int sortByDamage(Map.Entry<T, Double> e1,Map.Entry<T, Double> e2){
|
||||
if(e2.getValue()>e1.getValue()) return 1;
|
||||
if(e2.getValue().equals(e1.getValue())) return 0;
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
package pers.xanadu.enderdragon.reward.dist;
|
||||
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.entity.EnderDragon;
|
||||
import org.bukkit.entity.Player;
|
||||
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.AliasSample;
|
||||
import pers.xanadu.enderdragon.util.MyDragon;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
public class Dist_Termwise extends RewardDist {
|
||||
@Override
|
||||
public void handle_dist(final MyDragon myDragon,final EnderDragon dragon,final Player killer){
|
||||
ConcurrentHashMap<String,Double> damage_data = DamageManager.data.get(dragon.getUniqueId());
|
||||
if(damage_data == null) return;
|
||||
List<ItemStack> items = getDropReward(myDragon);
|
||||
if(items.isEmpty()) return;
|
||||
AliasSample alias = new AliasSample(new ArrayList<>(damage_data.values()));
|
||||
List<String> list = new ArrayList<>(damage_data.keySet());
|
||||
items.forEach(item->{
|
||||
int idx = alias.next();
|
||||
String receiver = list.get(idx);
|
||||
Player p = Bukkit.getPlayer(receiver);
|
||||
if(p != null){
|
||||
if(p.getInventory().firstEmpty() == -1){
|
||||
p.getWorld().dropItem(p.getLocation(),item);
|
||||
Lang.sendFeedback(p, Lang.dragon_player_inv_full);
|
||||
}
|
||||
else p.getInventory().addItem(item);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
package pers.xanadu.enderdragon.task;
|
||||
|
||||
import org.bukkit.scheduler.BukkitRunnable;
|
||||
import pers.xanadu.enderdragon.config.Config;
|
||||
import pers.xanadu.enderdragon.config.Lang;
|
||||
import pers.xanadu.enderdragon.manager.TaskManager;
|
||||
import pers.xanadu.enderdragon.EnderDragon;
|
||||
|
||||
import static pers.xanadu.enderdragon.EnderDragon.plugin;
|
||||
|
||||
public class DragonRespawnRunnable extends BukkitRunnable {
|
||||
private static DragonRespawnRunnable runnable = null;
|
||||
@Override
|
||||
public void run(){
|
||||
if(TaskManager.task == null) {
|
||||
this.cancel();
|
||||
runnable = null;
|
||||
Lang.error("The config of auto-respawn errors!Task has been disabled...");
|
||||
return;
|
||||
}
|
||||
if(TaskManager.task.isTimeUp()){
|
||||
new BukkitRunnable(){
|
||||
@Override
|
||||
public void run(){
|
||||
EnderDragon.getInstance().getDragonManager().initiateRespawn(Config.auto_respawn_world_the_end_name);
|
||||
}
|
||||
}.runTask(plugin);
|
||||
TaskManager.task.updateTime();
|
||||
}
|
||||
}
|
||||
public static void reload(){
|
||||
if(runnable != null){
|
||||
runnable.cancel();
|
||||
runnable = null;
|
||||
}
|
||||
runnable = new DragonRespawnRunnable();
|
||||
runnable.runTaskTimerAsynchronously(plugin,0,200L);
|
||||
Lang.info("The task has started to run...");
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,82 @@
|
||||
package pers.xanadu.enderdragon.task;
|
||||
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.scheduler.BukkitRunnable;
|
||||
import pers.xanadu.enderdragon.EnderDragon;
|
||||
import pers.xanadu.enderdragon.config.Lang;
|
||||
import pers.xanadu.enderdragon.util.MathUtil;
|
||||
|
||||
import static pers.xanadu.enderdragon.EnderDragon.plugin;
|
||||
|
||||
public class DragonRespawnTimer {
|
||||
private final String world_name;
|
||||
private final int delay;
|
||||
private BukkitRunnable runnable;
|
||||
private int remainSecond;
|
||||
private boolean isRunning;
|
||||
public DragonRespawnTimer(String WorldName,int second){
|
||||
this(WorldName,second,second);
|
||||
}
|
||||
public DragonRespawnTimer(String WorldName,int second,int rest_second){
|
||||
this.world_name = WorldName;
|
||||
this.delay = second;
|
||||
this.remainSecond = rest_second;
|
||||
this.isRunning = false;
|
||||
resetRunnable();
|
||||
}
|
||||
public void run(){
|
||||
if(!isRunning) runnable.runTaskTimerAsynchronously(plugin,0L,20L);
|
||||
isRunning = true;
|
||||
}
|
||||
public void update(){
|
||||
remainSecond = delay;
|
||||
runnable.cancel();
|
||||
isRunning = false;
|
||||
resetRunnable();
|
||||
}
|
||||
public void del(){
|
||||
if(isRunning) runnable.cancel();
|
||||
}
|
||||
public String getWorld_name(){
|
||||
return this.world_name;
|
||||
}
|
||||
public int getSetTime(){
|
||||
return this.delay;
|
||||
}
|
||||
public int getRestTime(){
|
||||
return this.remainSecond;
|
||||
}
|
||||
public boolean isRunning(){
|
||||
return isRunning;
|
||||
}
|
||||
public double getProgress(){
|
||||
return 1d*remainSecond/delay;
|
||||
}
|
||||
@Override
|
||||
public String toString(){
|
||||
return "(" + world_name + ") " +
|
||||
"remain:" + MathUtil.formatDuration(remainSecond) +
|
||||
", set:" + MathUtil.formatDuration(delay);
|
||||
}
|
||||
private void resetRunnable(){
|
||||
this.runnable = new BukkitRunnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
remainSecond--;
|
||||
if(remainSecond <= 0){
|
||||
Bukkit.getScheduler().runTask(plugin,() -> {
|
||||
if(EnderDragon.getInstance().getDragonManager().canRespawn(world_name)){
|
||||
EnderDragon.getInstance().getDragonManager().initiateRespawn(world_name);
|
||||
update();
|
||||
}
|
||||
else {
|
||||
remainSecond = delay;
|
||||
Lang.error(Lang.command_respawn_cd_retry);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,70 @@
|
||||
package pers.xanadu.enderdragon.task;
|
||||
|
||||
import pers.xanadu.enderdragon.EnderDragon;
|
||||
import pers.xanadu.enderdragon.manager.TaskManager;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.LocalTime;
|
||||
|
||||
public abstract class Task {
|
||||
protected int period;
|
||||
protected int day;
|
||||
private final TaskType type;
|
||||
public abstract LocalDateTime getNextTime(LocalDateTime cur);
|
||||
public abstract void updateTime();
|
||||
protected LocalDateTime nextTime;
|
||||
protected Task(TaskType type,String str){
|
||||
this.type = type;
|
||||
switch (type){
|
||||
case minute :
|
||||
case hour : {
|
||||
this.period = Integer.parseInt(str);
|
||||
break;
|
||||
}
|
||||
case day : {
|
||||
this.period = Integer.parseInt(str.split(",")[0]);
|
||||
break;
|
||||
}
|
||||
case week :
|
||||
case month :
|
||||
case year : {
|
||||
this.day = Integer.parseInt(str.split(",")[0]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(EnderDragon.data.getString(TaskManager.path) == null){
|
||||
switch (type){
|
||||
case minute :
|
||||
case hour : {
|
||||
this.nextTime = this.getNextTime(LocalDateTime.now().withSecond(0));
|
||||
break;
|
||||
}
|
||||
case day :
|
||||
case week :
|
||||
case month :
|
||||
case year : {
|
||||
calcNextTime(str);
|
||||
break;
|
||||
}
|
||||
}
|
||||
TaskManager.saveFile(nextTime);
|
||||
}
|
||||
else this.nextTime = TaskManager.getLocalDateTime(EnderDragon.data.getString(TaskManager.path));
|
||||
}
|
||||
private void calcNextTime(String str){
|
||||
LocalTime time = TaskManager.getRoundTime(str.split(",")[1]);
|
||||
if(time != null) this.nextTime = this.getNextTime(LocalDateTime.now().withSecond(0).with(time));
|
||||
else this.nextTime = this.getNextTime(LocalDateTime.now().withSecond(0));
|
||||
}
|
||||
public boolean isTimeUp(){
|
||||
LocalDateTime now = LocalDateTime.now();
|
||||
if(now.isEqual(nextTime) || now.isAfter(nextTime)){
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
public TaskType getType(){
|
||||
return this.type;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
package pers.xanadu.enderdragon.task;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.TreeMap;
|
||||
|
||||
public enum TaskType {
|
||||
minute,
|
||||
hour,
|
||||
day,
|
||||
week,
|
||||
month,
|
||||
year,
|
||||
unknown;
|
||||
private static final Map<String,TaskType> mp = new TreeMap<>(String.CASE_INSENSITIVE_ORDER);
|
||||
public static TaskType getByName(String str){
|
||||
if(str == null) return unknown;
|
||||
return mp.getOrDefault(str,unknown);
|
||||
}
|
||||
static{
|
||||
TaskType[] values = values();
|
||||
for (TaskType taskType : values) {
|
||||
String name = taskType.name();
|
||||
mp.put(name, taskType);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
package pers.xanadu.enderdragon.task.type;
|
||||
|
||||
import pers.xanadu.enderdragon.task.Task;
|
||||
import pers.xanadu.enderdragon.task.TaskType;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
import static pers.xanadu.enderdragon.manager.TaskManager.saveFile;
|
||||
|
||||
public class Day extends Task {
|
||||
|
||||
@Override
|
||||
public LocalDateTime getNextTime(LocalDateTime cur) {
|
||||
return cur.plusDays(period);
|
||||
}
|
||||
@Override
|
||||
public void updateTime(){
|
||||
this.nextTime = LocalDateTime.now().withSecond(0).plusDays(period);
|
||||
saveFile(nextTime);
|
||||
}
|
||||
public Day(TaskType type, String str){
|
||||
super(type,str);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
package pers.xanadu.enderdragon.task.type;
|
||||
|
||||
import pers.xanadu.enderdragon.task.Task;
|
||||
import pers.xanadu.enderdragon.task.TaskType;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
import static pers.xanadu.enderdragon.manager.TaskManager.saveFile;
|
||||
|
||||
public class Hour extends Task {
|
||||
@Override
|
||||
public LocalDateTime getNextTime(LocalDateTime cur) {
|
||||
return cur.plusHours(period);
|
||||
}
|
||||
@Override
|
||||
public void updateTime(){
|
||||
this.nextTime = LocalDateTime.now().withSecond(0).plusHours(period);
|
||||
saveFile(nextTime);
|
||||
}
|
||||
public Hour(TaskType type, String str){
|
||||
super(type,str);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
package pers.xanadu.enderdragon.task.type;
|
||||
|
||||
import pers.xanadu.enderdragon.task.Task;
|
||||
import pers.xanadu.enderdragon.task.TaskType;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
import static pers.xanadu.enderdragon.manager.TaskManager.saveFile;
|
||||
|
||||
public class Minute extends Task {
|
||||
|
||||
@Override
|
||||
public LocalDateTime getNextTime(LocalDateTime cur) {
|
||||
return cur.plusMinutes(period);
|
||||
}
|
||||
@Override
|
||||
public void updateTime(){
|
||||
this.nextTime = LocalDateTime.now().withSecond(0).plusMinutes(period);
|
||||
saveFile(nextTime);
|
||||
}
|
||||
|
||||
public Minute(TaskType type, String str){
|
||||
super(type,str);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
package pers.xanadu.enderdragon.task.type;
|
||||
|
||||
import pers.xanadu.enderdragon.task.Task;
|
||||
import pers.xanadu.enderdragon.task.TaskType;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
import static pers.xanadu.enderdragon.manager.TaskManager.saveFile;
|
||||
|
||||
public class Month extends Task {
|
||||
@Override
|
||||
public LocalDateTime getNextTime(LocalDateTime cur) {
|
||||
return cur.plusMonths(1).withDayOfMonth(day);
|
||||
}
|
||||
@Override
|
||||
public void updateTime(){
|
||||
this.nextTime = LocalDateTime.now().withSecond(0).plusMonths(1).withDayOfMonth(day);
|
||||
saveFile(nextTime);
|
||||
}
|
||||
public Month(TaskType type, String str){
|
||||
super(type,str);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
package pers.xanadu.enderdragon.task.type;
|
||||
|
||||
import pers.xanadu.enderdragon.task.Task;
|
||||
import pers.xanadu.enderdragon.task.TaskType;
|
||||
|
||||
import java.time.DayOfWeek;
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
import static pers.xanadu.enderdragon.manager.TaskManager.saveFile;
|
||||
|
||||
public class Week extends Task {
|
||||
|
||||
@Override
|
||||
public LocalDateTime getNextTime(LocalDateTime cur) {
|
||||
return cur.with(DayOfWeek.of(day)).plusDays(7);
|
||||
}
|
||||
@Override
|
||||
public void updateTime(){
|
||||
this.nextTime = LocalDateTime.now().withSecond(0).plusDays(7);
|
||||
saveFile(nextTime);
|
||||
}
|
||||
public Week(TaskType type, String str){
|
||||
super(type,str);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
package pers.xanadu.enderdragon.task.type;
|
||||
|
||||
import pers.xanadu.enderdragon.task.Task;
|
||||
import pers.xanadu.enderdragon.task.TaskType;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
import static pers.xanadu.enderdragon.manager.TaskManager.saveFile;
|
||||
|
||||
public class Year extends Task {
|
||||
@Override
|
||||
public LocalDateTime getNextTime(LocalDateTime cur) {
|
||||
return cur.plusYears(1).withDayOfMonth(day);
|
||||
}
|
||||
@Override
|
||||
public void updateTime(){
|
||||
this.nextTime = LocalDateTime.now().withSecond(0).plusYears(1);
|
||||
saveFile(nextTime);
|
||||
}
|
||||
public Year(TaskType type, String str){
|
||||
super(type,str);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,63 @@
|
||||
package pers.xanadu.enderdragon.util;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.ThreadLocalRandom;
|
||||
|
||||
public final class AExpJ {
|
||||
public static <T> List<T> sample(ConcurrentHashMap<T,Double> mp,int m){
|
||||
List<Pair<T,Double>> list = new ArrayList<>();
|
||||
mp.forEach((k,v)->list.add(new Pair<>(k,v)));
|
||||
return sample(list,m);
|
||||
}
|
||||
public static <T> List<T> sample(List<Pair<T,Double>> samples, int m) {
|
||||
PriorityQueue<Pair<T,Double>> heap = new PriorityQueue<>(Comparator.comparingDouble(p -> p.second));
|
||||
double Xw = 0.0;
|
||||
double Tw = 0.0;
|
||||
double w_acc = 0.0;
|
||||
for (Pair<T,Double> sample : samples) {
|
||||
if (heap.size() < m) {
|
||||
double wi = sample.second;
|
||||
double ui = ThreadLocalRandom.current().nextDouble();
|
||||
double ki = Math.pow(ui, 1 / wi);
|
||||
heap.offer(new Pair<>(sample.first, ki));
|
||||
continue;
|
||||
}
|
||||
if (w_acc == 0) {
|
||||
if (heap.isEmpty()) break;
|
||||
Tw = heap.peek().second;
|
||||
double r = ThreadLocalRandom.current().nextDouble();
|
||||
Xw = Math.log(r) / Math.log(Tw);
|
||||
}
|
||||
double wi = sample.second;
|
||||
if (w_acc + wi < Xw) {
|
||||
w_acc += wi;
|
||||
continue;
|
||||
}
|
||||
else w_acc = 0;
|
||||
double tw = Math.pow(Tw, wi);
|
||||
double r2 = ThreadLocalRandom.current().nextDouble() * (1 - tw) + tw;
|
||||
double ki = Math.pow(r2, 1 / wi);
|
||||
heap.poll();
|
||||
heap.offer(new Pair<>(sample.first, ki));
|
||||
}
|
||||
List<T> res = new ArrayList<>();
|
||||
for (Pair<T,Double> pair : heap) {
|
||||
res.add(pair.first);
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
// public static void main(String[] args) {
|
||||
// List<Pair<String,Double>> samples = new ArrayList<>();
|
||||
// samples.add(new Pair<>("item1", 0.8));
|
||||
// samples.add(new Pair<>("item2", 0.4));
|
||||
// samples.add(new Pair<>("item3", 0.2));
|
||||
// Map<String,Integer> mp = new HashMap<>();
|
||||
// for(int i=0;i<1e5;i++){
|
||||
// List<String> result = sample(samples, 1);
|
||||
// mp.compute(result.get(0), (k, v)->v==null?1:v+1);
|
||||
// }
|
||||
// System.out.println(mp);
|
||||
// }
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
package pers.xanadu.enderdragon.util;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.concurrent.ThreadLocalRandom;
|
||||
|
||||
public final class AliasSample {
|
||||
private final int[] alias;
|
||||
private final double[] probability;
|
||||
public AliasSample(List<Double> probabilities) {
|
||||
if (probabilities == null) throw new NullPointerException();
|
||||
if (probabilities.size() == 0)
|
||||
throw new IllegalArgumentException("Probability vector can't be empty.");
|
||||
this.probability = new double[probabilities.size()];
|
||||
this.alias = new int[probabilities.size()];
|
||||
final double average = 1.0 / probabilities.size();
|
||||
probabilities = new ArrayList<>(probabilities);//make a copy of list, avoid modifying the param
|
||||
Deque<Integer> small = new ArrayDeque<>();
|
||||
Deque<Integer> large = new ArrayDeque<>();
|
||||
for (int i = 0; i < probabilities.size(); ++i) {
|
||||
if (probabilities.get(i) >= average) large.add(i);
|
||||
else small.add(i);
|
||||
}
|
||||
while (!small.isEmpty() && !large.isEmpty()) {
|
||||
int less = small.removeLast();
|
||||
int more = large.removeLast();
|
||||
probability[less] = probabilities.get(less) * probabilities.size();
|
||||
alias[less] = more;
|
||||
probabilities.set(more, (probabilities.get(more) + probabilities.get(less)) - average);
|
||||
if (probabilities.get(more) >= 1.0 / probabilities.size()) large.add(more);
|
||||
else small.add(more);
|
||||
}
|
||||
while (!small.isEmpty()) probability[small.removeLast()] = 1.0;
|
||||
while (!large.isEmpty()) probability[large.removeLast()] = 1.0;
|
||||
}
|
||||
|
||||
public int next() {
|
||||
int column = ThreadLocalRandom.current().nextInt(probability.length);
|
||||
boolean coinToss = ThreadLocalRandom.current().nextDouble() < probability[column];
|
||||
return coinToss ? column : alias[column];
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,63 @@
|
||||
package pers.xanadu.enderdragon.util;
|
||||
|
||||
import net.md_5.bungee.api.ChatColor;
|
||||
|
||||
import java.awt.*;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import static pers.xanadu.enderdragon.util.Version.mcMainVersion;
|
||||
|
||||
public class ColorUtil {
|
||||
|
||||
public static Pattern hex_code = Pattern.compile("&#([0-9A-Fa-f]{6})");
|
||||
public static Pattern gradient = Pattern.compile("&\\[#([0-9a-fA-F]{6})-#([0-9a-fA-F]{6})(.+)]");
|
||||
public static String translateHexCodes (String str) {
|
||||
if(mcMainVersion < 16) return str;
|
||||
Matcher matcher = hex_code.matcher(str);
|
||||
StringBuffer buffer = new StringBuffer();
|
||||
while(matcher.find()) {
|
||||
matcher.appendReplacement(buffer, ChatColor.of("#" + matcher.group(1)).toString());
|
||||
}
|
||||
return ChatColor.translateAlternateColorCodes('&', matcher.appendTail(buffer).toString());
|
||||
}
|
||||
public static String transGradient(String str) {
|
||||
if(mcMainVersion < 16) return str;
|
||||
if (str.contains("&[#")&&str.contains("]")) {
|
||||
Matcher matcher = gradient.matcher(str);
|
||||
StringBuffer buffer = new StringBuffer();
|
||||
while (matcher.find()) {
|
||||
String text = matcher.group(3);
|
||||
int[] colors = gradient(matcher.group(1),matcher.group(2),text.length());
|
||||
StringBuilder builder = new StringBuilder();
|
||||
for (int i = 0; i < text.length(); i++) {
|
||||
Color c = new Color(colors[i]);
|
||||
builder.append(ChatColor.of(c)).append(text.charAt(i));
|
||||
}
|
||||
matcher.appendReplacement(buffer, builder.toString());
|
||||
}
|
||||
matcher.appendTail(buffer);
|
||||
return buffer.toString();
|
||||
}
|
||||
return translateHexCodes(str);
|
||||
}
|
||||
private static int[] gradient(String start,String end,int length){
|
||||
int[] color = new int[length];
|
||||
int[] rgb1 = MathUtil.hexToInt(start);
|
||||
int[] rgb2 = MathUtil.hexToInt(end);
|
||||
if(length==0){return color;}
|
||||
if(length==1){
|
||||
for(int j=0;j<3;j++){
|
||||
color[0] = color[0]*256+rgb1[j];
|
||||
}
|
||||
return color;
|
||||
}
|
||||
for(int i=0;i<length;i++){
|
||||
for(int j=0;j<3;j++){
|
||||
color[i] = color[i]*256+rgb1[j]+(rgb2[j]-rgb1[j])*i/(length-1);
|
||||
}
|
||||
}
|
||||
return color;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,101 @@
|
||||
package pers.xanadu.enderdragon.util;
|
||||
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.entity.Entity;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.math.RoundingMode;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.ThreadLocalRandom;
|
||||
import java.util.concurrent.atomic.AtomicReference;
|
||||
|
||||
import static pers.xanadu.enderdragon.EnderDragon.server;
|
||||
|
||||
public class MathUtil {
|
||||
public static int floor(double d) {
|
||||
int i = (int)d;
|
||||
return d < (double)i ? i - 1 : i;
|
||||
}
|
||||
public static double c(Entity entity, double x, double y, double z) {
|
||||
Location loc = entity.getLocation();
|
||||
double d0 = loc.getX() - x;
|
||||
double d1 = loc.getY() - y;
|
||||
double d2 = loc.getZ() - z;
|
||||
return d0 * d0 + d1 * d1 + d2 * d2;
|
||||
}
|
||||
public static double div(double d1,double d2,int len){
|
||||
BigDecimal b1 = new BigDecimal(d1);
|
||||
BigDecimal b2 = new BigDecimal(d2);
|
||||
return b1.divide(b2,len, RoundingMode.HALF_UP).doubleValue();
|
||||
}
|
||||
public static int[] hexToInt(String hex){
|
||||
int[] result = new int[3];
|
||||
String s1 = hex.substring(0,2);
|
||||
String s2 = hex.substring(2,4);
|
||||
String s3 = hex.substring(4,6);
|
||||
result[0] = Integer.parseInt(s1,16);
|
||||
result[1] = Integer.parseInt(s2,16);
|
||||
result[2] = Integer.parseInt(s3,16);
|
||||
return result;
|
||||
}
|
||||
public static String locationToString(Location loc){
|
||||
if (loc.getWorld() == null) return "";
|
||||
return loc.getWorld().getName()+";"+loc.getX()+";"+loc.getY()+";"+loc.getZ();
|
||||
}
|
||||
public static Location stringToLocation(String str){
|
||||
final String[] parts = str.split(";");
|
||||
if(parts.length != 4) return null;
|
||||
final World world = server.getWorld(parts[0]);
|
||||
final double x = Double.parseDouble(parts[1]);
|
||||
final double y = Double.parseDouble(parts[2]);
|
||||
final double z = Double.parseDouble(parts[3]);
|
||||
return new Location(world,x,y,z);
|
||||
}
|
||||
public static String formatDuration(int seconds) {
|
||||
if (seconds < 0) throw new IllegalArgumentException("Duration must be a positive number.");
|
||||
int days = seconds / (24 * 3600);
|
||||
int hours = (seconds % (24 * 3600)) / 3600;
|
||||
int minutes = ((seconds % (24 * 3600)) % 3600) / 60;
|
||||
int remainingSeconds = ((seconds % (24 * 3600)) % 3600) % 60;
|
||||
StringBuilder duration = new StringBuilder();
|
||||
boolean f = false;
|
||||
if(days>0){
|
||||
duration.append(days).append("d");
|
||||
f = true;
|
||||
}
|
||||
if(f||hours>0){
|
||||
duration.append(hours).append("h");
|
||||
f = true;
|
||||
}
|
||||
if(f||minutes>0){
|
||||
duration.append(minutes).append("m");
|
||||
}
|
||||
duration.append(remainingSeconds).append("s");
|
||||
return duration.toString();
|
||||
}
|
||||
public static int[] getDate(int seconds){
|
||||
if (seconds < 0) throw new IllegalArgumentException("Duration must be a positive number.");
|
||||
int days = seconds / (24 * 3600);
|
||||
int hours = (seconds % (24 * 3600)) / 3600;
|
||||
int minutes = ((seconds % (24 * 3600)) % 3600) / 60;
|
||||
int remainingSeconds = ((seconds % (24 * 3600)) % 3600) % 60;
|
||||
return new int[]{days,hours,minutes,remainingSeconds};
|
||||
}
|
||||
@Deprecated
|
||||
public static <K> K getByWeight(ConcurrentHashMap<K,Double> mp){
|
||||
double sum = mp.values().stream().mapToDouble(Double::doubleValue).sum();
|
||||
double rand = ThreadLocalRandom.current().nextDouble(sum);
|
||||
final AtomicReference<Double> cur = new AtomicReference<>(0d);
|
||||
final AtomicReference<K> res = new AtomicReference<>();
|
||||
mp.forEach((k,v)->{
|
||||
Double value = cur.get();
|
||||
if(value<=rand && value+v>rand) {
|
||||
res.set(k);
|
||||
return;
|
||||
}
|
||||
cur.updateAndGet(v1 -> v1 + v);
|
||||
});
|
||||
return res.get();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,60 @@
|
||||
package pers.xanadu.enderdragon.util;
|
||||
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.bukkit.potion.PotionEffect;
|
||||
import pers.xanadu.enderdragon.reward.Reward;
|
||||
import pers.xanadu.enderdragon.reward.RewardDist;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class MyDragon implements Comparable<MyDragon>{
|
||||
public ItemStack icon;
|
||||
public String unique_name;
|
||||
public String display_name;
|
||||
public String drop_gui;
|
||||
public int edge;
|
||||
public int priority;
|
||||
public double spawn_chance;
|
||||
public int max_health;
|
||||
public int spawn_health;
|
||||
public int exp_drop;
|
||||
public int dragon_egg_spawn_delay;
|
||||
public int dragon_egg_spawn_x;
|
||||
public int dragon_egg_spawn_y;
|
||||
public int dragon_egg_spawn_z;
|
||||
public double dragon_egg_spawn_chance;
|
||||
public double attack_damage_modify;
|
||||
//public double move_speed_modify;
|
||||
public double armor_modify;
|
||||
public double armor_toughness_modify;
|
||||
public double crystal_heal_speed;
|
||||
public boolean suck_blood_enable;
|
||||
public double suck_blood_rate;
|
||||
public double suck_blood_base_amount;
|
||||
public boolean suck_blood_only_player;
|
||||
public List<PotionEffect> attack_potion_effect;
|
||||
public List<String> spawn_cmd;
|
||||
public List<String> death_cmd;
|
||||
public List<String> spawn_broadcast_msg;
|
||||
public List<String> death_broadcast_msg;
|
||||
public List<String> msg_to_killer;
|
||||
public String glow_color;
|
||||
public String bossbar_color;
|
||||
public String bossbar_style;
|
||||
public double effect_cloud_original_radius;
|
||||
public double effect_cloud_expand_speed;
|
||||
public int effect_cloud_duration;
|
||||
public int effect_cloud_color_R;
|
||||
public int effect_cloud_color_G;
|
||||
public int effect_cloud_color_B;
|
||||
public List<PotionEffect> effect_cloud_potion;
|
||||
public List<Reward> datum = new ArrayList<>();
|
||||
public RewardDist reward_dist;
|
||||
|
||||
@Override
|
||||
public int compareTo(MyDragon o) {
|
||||
return o.priority - this.priority;//降序
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
package pers.xanadu.enderdragon.util;
|
||||
|
||||
import org.bukkit.scheduler.BukkitRunnable;
|
||||
import pers.xanadu.enderdragon.EnderDragon;
|
||||
import pers.xanadu.enderdragon.config.Lang;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
import java.net.URL;
|
||||
import java.net.URLConnection;
|
||||
|
||||
public class MyUpdater {
|
||||
public static void checkUpdate(){
|
||||
Lang.info(Lang.plugin_checking_update);
|
||||
new BukkitRunnable(){
|
||||
@Override
|
||||
public void run(){
|
||||
try {
|
||||
URLConnection conn = new URL("https://api.github.com/repos/iXanadu13/EnderDragon/releases/latest").openConnection();
|
||||
conn.setConnectTimeout(20000);
|
||||
conn.setReadTimeout(60000);
|
||||
InputStream is = conn.getInputStream();
|
||||
String line = new BufferedReader(new InputStreamReader(is)).readLine();
|
||||
is.close();
|
||||
String newVer = line.substring(line.indexOf("\"tag_name\"") + 13, line.indexOf("\"target_commitish\"") - 2);
|
||||
String localVer = EnderDragon.plugin.getDescription().getVersion();
|
||||
if (!localVer.equals(newVer)) {
|
||||
Lang.warn(Lang.plugin_out_of_date.replace("{0}",localVer).replace("{1}",newVer));
|
||||
}
|
||||
else{
|
||||
Lang.info(Lang.plugin_up_to_date.replace("{1}",newVer));
|
||||
}
|
||||
} catch (Exception e) {
|
||||
Lang.warn(Lang.plugin_check_update_fail);
|
||||
}
|
||||
}
|
||||
}.runTaskAsynchronously(EnderDragon.plugin);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,444 @@
|
||||
package pers.xanadu.enderdragon.util;
|
||||
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.bukkit.inventory.meta.ItemMeta;
|
||||
import org.bukkit.persistence.PersistentDataContainer;
|
||||
import pers.xanadu.enderdragon.EnderDragon;
|
||||
import pers.xanadu.enderdragon.config.Lang;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.Map;
|
||||
|
||||
import static pers.xanadu.enderdragon.EnderDragon.getInstance;
|
||||
|
||||
public class NMSUtil {
|
||||
private String getEDB_base;
|
||||
private Method getNMSWord;
|
||||
private Method asNMSCopy;
|
||||
private Method copyNMSStack;
|
||||
private Method asBukkitCopy;
|
||||
private Method asCraftMirror;
|
||||
private Method asCraftCopy;
|
||||
private Method NMSItemStack_save;
|
||||
private Method NMSItemStack_setTag;
|
||||
private Method cpdToEi;
|
||||
private Method stringToCPD;
|
||||
private Method stringToNBTBase;
|
||||
private Method serializeNBTBase;
|
||||
private Method deserializeObject;
|
||||
private Method PDCtoCPD;
|
||||
private Method PersistentDataContainer_putAll;
|
||||
private Method NBTTagCompound_set;
|
||||
|
||||
private Field unhandledTags;
|
||||
private Field internalTag;
|
||||
private Field MOJANGSON_PARSER;
|
||||
private Field world_c_environment;
|
||||
private Field NBTTagCompound_map;
|
||||
private Class<?> WorldClass;
|
||||
private Class<?> CraftWorldClass;
|
||||
private Class<?> WorldProviderClass;
|
||||
private Class<?> WorldProviderTheEndClass;
|
||||
private Class<?> CraftItemStackClass;
|
||||
private Class<?> CraftMetaItemClass;
|
||||
private Class<?> NMSItemStackClass;
|
||||
private Class<?> CraftEntityClass;
|
||||
private Class<?> NBTTagCompoundClass;
|
||||
private Class<?> NBTBaseClass;
|
||||
private Class<?> MojangsonParserClass;
|
||||
private Class<?> CraftNBTTagConfigSerializerClass;
|
||||
private Class<?> CraftPersistentDataContainerClass;
|
||||
|
||||
public void init(){
|
||||
String version = Version.getVersion();
|
||||
try{
|
||||
this.CraftWorldClass = Class.forName("org.bukkit.craftbukkit." + version + ".CraftWorld");
|
||||
this.WorldClass = CraftWorldClass.getDeclaredMethod("getHandle").getReturnType().getSuperclass();
|
||||
this.world_c_environment = CraftWorldClass.getDeclaredField("environment");
|
||||
this.world_c_environment.setAccessible(true);
|
||||
if(Version.mcMainVersion>=12 && Version.mcMainVersion<16){
|
||||
this.WorldProviderClass = Class.forName("net.minecraft.server."+version+".WorldProvider");
|
||||
this.WorldProviderTheEndClass = Class.forName("net.minecraft.server."+version+".WorldProviderTheEnd");
|
||||
}
|
||||
this.CraftItemStackClass = Class.forName("org.bukkit.craftbukkit." + version + ".inventory.CraftItemStack");
|
||||
this.CraftMetaItemClass = Class.forName("org.bukkit.craftbukkit." + version + ".inventory.CraftMetaItem");
|
||||
this.unhandledTags = CraftMetaItemClass.getDeclaredField("unhandledTags");
|
||||
unhandledTags.setAccessible(true);
|
||||
this.internalTag = CraftMetaItemClass.getDeclaredField("internalTag");
|
||||
internalTag.setAccessible(true);
|
||||
this.NMSItemStackClass = CraftItemStackClass.getDeclaredField("handle").getType();
|
||||
this.CraftEntityClass = Class.forName("org.bukkit.craftbukkit."+version+".entity.CraftEntity");
|
||||
init_NBTTagCompoundClass();
|
||||
init_NBTBaseClass();
|
||||
init_NBTTagCompound_map();
|
||||
this.NBTTagCompound_set = NBTTagCompoundClass.getMethod(getMethodName(ReflectiveMethod.NBTTagCompound_set),String.class,NBTBaseClass);
|
||||
this.asNMSCopy = CraftItemStackClass.getMethod("asNMSCopy",ItemStack.class);
|
||||
this.copyNMSStack = CraftItemStackClass.getMethod("copyNMSStack",NMSItemStackClass,int.class);
|
||||
this.asBukkitCopy = CraftItemStackClass.getMethod("asBukkitCopy",NMSItemStackClass);
|
||||
this.asCraftMirror = CraftItemStackClass.getMethod("asCraftMirror",NMSItemStackClass);
|
||||
this.asCraftCopy = CraftItemStackClass.getMethod("asCraftCopy",ItemStack.class);
|
||||
this.NMSItemStack_save = NMSItemStackClass.getMethod(getMethodName(ReflectiveMethod.NMSItemStack_save),NBTTagCompoundClass);
|
||||
this.NMSItemStack_setTag = NMSItemStackClass.getMethod(getMethodName(ReflectiveMethod.NMSItemStack_setTag),NBTTagCompoundClass);
|
||||
if(Version.mcMainVersion>=13) this.cpdToEi = NMSItemStackClass.getMethod("a",NBTTagCompoundClass);
|
||||
|
||||
if(Version.mcMainVersion<=16) this.MojangsonParserClass = Class.forName("net.minecraft.server."+version+".MojangsonParser");
|
||||
else this.MojangsonParserClass = Class.forName("net.minecraft.nbt.MojangsonParser");
|
||||
this.stringToCPD = MojangsonParserClass.getMethod(getMethodName(ReflectiveMethod.MojangsonParser_parse),String.class);
|
||||
this.stringToNBTBase = MojangsonParserClass.getDeclaredMethod(getMethodName(ReflectiveMethod.MojangsonParser_parseLiteral),String.class);
|
||||
stringToNBTBase.setAccessible(true);
|
||||
|
||||
if(Version.mcMainVersion>13 || "v1_13_R2".equals(Version.getVersion())){
|
||||
this.CraftNBTTagConfigSerializerClass = Class.forName("org.bukkit.craftbukkit." + version + ".util.CraftNBTTagConfigSerializer");
|
||||
this.serializeNBTBase = CraftNBTTagConfigSerializerClass.getMethods()[0];
|
||||
this.deserializeObject = CraftNBTTagConfigSerializerClass.getMethod("deserialize",Object.class);
|
||||
this.MOJANGSON_PARSER = CraftNBTTagConfigSerializerClass.getDeclaredField("MOJANGSON_PARSER");
|
||||
MOJANGSON_PARSER.setAccessible(true);
|
||||
}
|
||||
if(Version.mcMainVersion>=14){
|
||||
this.CraftPersistentDataContainerClass = Class.forName("org.bukkit.craftbukkit." + version + ".persistence.CraftPersistentDataContainer");
|
||||
this.PDCtoCPD = CraftPersistentDataContainerClass.getDeclaredMethod("toTagCompound");
|
||||
this.PersistentDataContainer_putAll = CraftPersistentDataContainerClass.getDeclaredMethod("putAll",NBTTagCompoundClass);
|
||||
}
|
||||
|
||||
|
||||
|
||||
}catch(ReflectiveOperationException e){
|
||||
e.printStackTrace();
|
||||
}
|
||||
switch (version) {
|
||||
case "v1_12_R1" : {
|
||||
getEDB_base = "t";
|
||||
break;
|
||||
}
|
||||
case "v1_13_R1" :
|
||||
case "v1_13_R2" : {
|
||||
getEDB_base = "r";
|
||||
break;
|
||||
}
|
||||
case "v1_14_R1" : {
|
||||
getEDB_base = "q";
|
||||
break;
|
||||
}
|
||||
case "v1_15_R1" : {
|
||||
getEDB_base = "o";
|
||||
break;
|
||||
}
|
||||
default : getEDB_base = null;
|
||||
}
|
||||
}
|
||||
// public Object getMetaCPD(ItemMeta meta){
|
||||
// try{
|
||||
// Object craft_meta = CraftMetaItemClass.cast(meta);
|
||||
// Object internalTag = this.internalTag.get(craft_meta);
|
||||
// return internalTag;
|
||||
// }catch (ReflectiveOperationException e){
|
||||
// e.printStackTrace();
|
||||
// return null;
|
||||
// }
|
||||
// }
|
||||
|
||||
/**
|
||||
* 只保留物品type和amount
|
||||
* nbt深合并需要遍历每一层
|
||||
*/
|
||||
@Deprecated
|
||||
public ItemStack mergeItemCPD(ItemStack item,Object cpd){
|
||||
Map<String,Object> self = cpdToMap(getCPD(item));
|
||||
Map<String,Object> rhs = cpdToMap(cpd);
|
||||
self.putAll(rhs);
|
||||
Object new_cpd = getNBTTagCompound(self);
|
||||
return EnderDragon.getInstance().getNMSItemManager().cpdToItem(new_cpd);
|
||||
}
|
||||
public Map<String,Object> cpdToMap(Object cpd){
|
||||
try{
|
||||
return (Map<String, Object>) NBTTagCompound_map.get(cpd);
|
||||
}catch (ReflectiveOperationException e){
|
||||
e.printStackTrace();
|
||||
return null;
|
||||
}
|
||||
}
|
||||
public Object getNBTTagCompound(Map<String,Object> mp){
|
||||
try{
|
||||
Object cpd = NBTTagCompoundClass.newInstance();
|
||||
mp.forEach((key,value)->{
|
||||
Object res;
|
||||
if(value instanceof Map){
|
||||
res = getNBTTagCompound((Map<String, Object>) value);
|
||||
}
|
||||
else res = value;
|
||||
try{
|
||||
NBTTagCompound_set.invoke(cpd,key,res);
|
||||
}catch (ReflectiveOperationException e){
|
||||
throw new RuntimeException("Reflective error!");
|
||||
}
|
||||
});
|
||||
return cpd;
|
||||
}catch (ReflectiveOperationException e){
|
||||
e.printStackTrace();
|
||||
return null;
|
||||
}
|
||||
}
|
||||
public Object StringParseLiteral(String str){
|
||||
try{
|
||||
return stringToNBTBase.invoke(MOJANGSON_PARSER.get(null),str);
|
||||
}catch (ReflectiveOperationException e){
|
||||
e.printStackTrace();
|
||||
return null;
|
||||
}
|
||||
}
|
||||
public void setPersistentDataContainer(PersistentDataContainer dataContainer,Object cpd){
|
||||
try{
|
||||
Object PDC = CraftPersistentDataContainerClass.cast(dataContainer);
|
||||
PersistentDataContainer_putAll.invoke(PDC,cpd);
|
||||
}catch (ReflectiveOperationException e){
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
public String PDCtoString(PersistentDataContainer dataContainer){
|
||||
try{
|
||||
Object PDC = CraftPersistentDataContainerClass.cast(dataContainer);
|
||||
return PDCtoCPD.invoke(PDC).toString();
|
||||
}catch (ReflectiveOperationException e){
|
||||
e.printStackTrace();
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public Object deserializeObject(Object object){
|
||||
try{
|
||||
return deserializeObject.invoke(null,object);
|
||||
}catch (ReflectiveOperationException e){
|
||||
e.printStackTrace();
|
||||
return null;
|
||||
}
|
||||
}
|
||||
public Object serializeNBTBase(Object nbt_base){
|
||||
try{
|
||||
return serializeNBTBase.invoke(null, nbt_base);
|
||||
}catch (ReflectiveOperationException e){
|
||||
e.printStackTrace();
|
||||
return null;
|
||||
}
|
||||
}
|
||||
public void setUnhandledTags(ItemMeta meta, Map<String,?> unhandledTags){
|
||||
try{
|
||||
Object craft_meta = CraftMetaItemClass.cast(meta);
|
||||
this.unhandledTags.set(craft_meta, unhandledTags);
|
||||
}catch (ReflectiveOperationException e){
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
public Map<String,Object> getUnhandledTags(ItemMeta meta){
|
||||
try{
|
||||
Object craft_meta = CraftMetaItemClass.cast(meta);
|
||||
Object unhandledTags = this.unhandledTags.get(craft_meta);
|
||||
return (Map<String, Object>) unhandledTags;
|
||||
}catch (ReflectiveOperationException e){
|
||||
e.printStackTrace();
|
||||
return null;
|
||||
}
|
||||
}
|
||||
public ItemStack applyItemTag(ItemStack item,Object cpd){
|
||||
try{
|
||||
Object ei = asNMSCopy.invoke(null,item);
|
||||
NMSItemStack_setTag.invoke(ei,cpd);
|
||||
return (ItemStack) asBukkitCopy.invoke(null,ei);
|
||||
}catch (ReflectiveOperationException e){
|
||||
e.printStackTrace();
|
||||
return new ItemStack(Material.AIR);
|
||||
}
|
||||
}
|
||||
public String getNBT(ItemStack item){
|
||||
try{
|
||||
Object ci = CraftItemStackClass.isInstance(item)?CraftItemStackClass.cast(item):asCraftCopy.invoke(null,item);
|
||||
Object ei = asNMSCopy.invoke(null, ci);
|
||||
Object cpd = NMSItemStack_save.invoke(ei, NBTTagCompoundClass.newInstance());
|
||||
return cpd.toString();
|
||||
}catch (ReflectiveOperationException e){
|
||||
e.printStackTrace();
|
||||
return "{id:\"minecraft:air\"}";
|
||||
}
|
||||
}
|
||||
public Object getCPD(ItemStack item){
|
||||
try{
|
||||
Object ci = CraftItemStackClass.isInstance(item)?CraftItemStackClass.cast(item):asCraftCopy.invoke(null,item);
|
||||
Object ei = asNMSCopy.invoke(null, ci);
|
||||
return NMSItemStack_save.invoke(ei, NBTTagCompoundClass.newInstance());
|
||||
}catch (ReflectiveOperationException e){
|
||||
e.printStackTrace();
|
||||
return null;
|
||||
}
|
||||
}
|
||||
public Object getCPD(String nbt){
|
||||
try{
|
||||
return stringToCPD.invoke(null,nbt);
|
||||
}catch (ReflectiveOperationException e){
|
||||
e.printStackTrace();
|
||||
return null;
|
||||
}
|
||||
}
|
||||
/**
|
||||
* 仅1.13+可用
|
||||
*/
|
||||
public ItemStack getItemStack(Object cpd){
|
||||
try{
|
||||
Object ei = cpdToEi.invoke(null,cpd);
|
||||
Object ci = asBukkitCopy.invoke(null,ei);
|
||||
return (ItemStack) ci;
|
||||
}catch (ReflectiveOperationException e){
|
||||
e.printStackTrace();
|
||||
return null;
|
||||
}
|
||||
}
|
||||
/**
|
||||
* 仅1.13+可用
|
||||
*/
|
||||
public ItemStack getItemStack(String nbt){
|
||||
try{
|
||||
Object cpd = stringToCPD.invoke(null,nbt);
|
||||
Object ei = cpdToEi.invoke(null,cpd);
|
||||
Object ci = asBukkitCopy.invoke(null,ei);
|
||||
return (ItemStack) ci;
|
||||
}catch (ReflectiveOperationException e){
|
||||
e.printStackTrace();
|
||||
return null;
|
||||
}
|
||||
}
|
||||
public void setEnvironment(World world,World.Environment env){
|
||||
Object world_c = getCraftWorld(world);
|
||||
try{
|
||||
//Object old_env = world_c_environment.get(world_c);
|
||||
world_c_environment.set(world_c,env);
|
||||
}catch (ReflectiveOperationException e){
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
public Object getEnderDragonBattle(World world){
|
||||
String version = Version.getVersion();
|
||||
if (Version.mcMainVersion>=12 && Version.mcMainVersion<16) {
|
||||
try {
|
||||
Object worldServer = getInstance().getNMSManager().getWorldServer(world);
|
||||
assert worldServer != null;
|
||||
Field field = worldServer.getClass().getField("worldProvider");
|
||||
Object worldProvider = field.get(worldServer);
|
||||
Object WorldProviderTheEnd = WorldProviderTheEndClass.cast(worldProvider);
|
||||
String method_name = getInstance().getNMSManager().getEDB_base;
|
||||
if(method_name == null) return null;
|
||||
Method method = WorldProviderTheEnd.getClass().getDeclaredMethod(method_name);
|
||||
return method.invoke(WorldProviderTheEnd);
|
||||
} catch (ReflectiveOperationException e) {
|
||||
Lang.warn("Your server version (" + version + ") is not supported!");
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
Lang.warn("Your server version (" + version + ") is not supported!");
|
||||
return null;
|
||||
}
|
||||
public Object getWorldServer(World ThisWorld) {
|
||||
try {
|
||||
Object castClass = getCraftWorld(ThisWorld);
|
||||
return this.CraftWorldClass.getDeclaredMethod("getHandle").invoke(castClass);
|
||||
} catch (ReflectiveOperationException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
public Object getCraftWorld(World ThisWorld) {
|
||||
if (this.CraftWorldClass.isInstance(ThisWorld)) return this.CraftWorldClass.cast(ThisWorld);
|
||||
return null;
|
||||
}
|
||||
public Object getWorld_e(World world){
|
||||
try {
|
||||
Object world_c = getCraftWorld(world);
|
||||
if(this.getNMSWord == null){
|
||||
this.getNMSWord = this.CraftWorldClass.getDeclaredMethod("getHandle");
|
||||
}
|
||||
return this.getNMSWord.invoke(world_c);
|
||||
} catch (ReflectiveOperationException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
public Class<?> getNBTBaseClass(){
|
||||
return this.NBTBaseClass;
|
||||
}
|
||||
public Class<?> getNBTTagCompoundClass(){
|
||||
return this.NBTTagCompoundClass;
|
||||
}
|
||||
public Class<?> getWorldClass(){
|
||||
return this.WorldClass;
|
||||
}
|
||||
public Class<?> getWorldProviderClass(){
|
||||
return this.WorldProviderClass;
|
||||
}
|
||||
private String getMethodName(ReflectiveMethod method){
|
||||
switch (method){
|
||||
case NMSItemStack_save: {
|
||||
if(Version.mcMainVersion<=17) return "save";
|
||||
return "b";
|
||||
}
|
||||
case NMSItemStack_setTag: {
|
||||
if(Version.mcMainVersion<=17) return "setTag";
|
||||
return "c";
|
||||
}
|
||||
case MojangsonParser_parse: {
|
||||
if(Version.mcMainVersion<=17) return "parse";
|
||||
return "a";
|
||||
}
|
||||
case MojangsonParser_parseLiteral: {
|
||||
if(Version.mcMainVersion==12) return "c";
|
||||
else if("v1_13_R1".equals(Version.getVersion())) return "b";
|
||||
else if(Version.mcMainVersion<=17) return "parseLiteral";
|
||||
else return "b";
|
||||
}
|
||||
case NBTTagCompound_set: {
|
||||
if(Version.mcMainVersion<=17) return "set";
|
||||
return "a";
|
||||
}
|
||||
default: return "unreachable";
|
||||
}
|
||||
}
|
||||
private void init_NBTTagCompoundClass(){
|
||||
try{
|
||||
Class<?> CraftMetaBlockStateClass = Class.forName("org.bukkit.craftbukkit."+Version.getVersion()+".inventory.CraftMetaBlockState");
|
||||
Field field = CraftMetaBlockStateClass.getDeclaredField("blockEntityTag");
|
||||
this.NBTTagCompoundClass = field.getType();
|
||||
return;
|
||||
}catch (ReflectiveOperationException ignored){}
|
||||
|
||||
Method[] methods = CraftEntityClass.getDeclaredMethods();
|
||||
for (Method method : methods) {
|
||||
if ("save".equals(method.getName())) this.NBTTagCompoundClass = method.getReturnType();
|
||||
}
|
||||
}
|
||||
private void init_NBTTagCompound_map(){
|
||||
Field[] fields = NBTTagCompoundClass.getDeclaredFields();
|
||||
for(Field field : fields){
|
||||
if(field.getType() == this.unhandledTags.getType()){
|
||||
this.NBTTagCompound_map = field;
|
||||
break;
|
||||
}
|
||||
}
|
||||
this.NBTTagCompound_map.setAccessible(true);
|
||||
}
|
||||
private void init_NBTBaseClass(){
|
||||
try{
|
||||
//在mohist端使用getPackage()喜提null
|
||||
this.NBTBaseClass = Class.forName(this.NBTTagCompoundClass.getName().replace(".NBTTagCompound",".NBTBase"));
|
||||
}catch (ClassNotFoundException e){
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
private static enum ReflectiveMethod {
|
||||
NMSItemStack_save,
|
||||
NMSItemStack_setTag,
|
||||
MojangsonParser_parse,
|
||||
MojangsonParser_parseLiteral,
|
||||
NBTTagCompound_set
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
package pers.xanadu.enderdragon.util;
|
||||
|
||||
public class Pair<P1,P2> {
|
||||
public P1 first;
|
||||
public P2 second;
|
||||
public Pair(P1 first, P2 second) {
|
||||
this.first = first;
|
||||
this.second = second;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,83 @@
|
||||
package pers.xanadu.enderdragon.util;
|
||||
|
||||
import pers.xanadu.enderdragon.config.Lang;
|
||||
import pers.xanadu.enderdragon.nms.BossBar.I_BossBarManager;
|
||||
import pers.xanadu.enderdragon.nms.NMSItem.I_NMSItemManager;
|
||||
import pers.xanadu.enderdragon.nms.RespawnAnchor.I_RespawnAnchorManager;
|
||||
import pers.xanadu.enderdragon.nms.WorldData.I_WorldDataManager;
|
||||
|
||||
import static org.bukkit.Bukkit.getServer;
|
||||
|
||||
public class Version {
|
||||
public static int mcMainVersion;
|
||||
public static int mcPatchVersion;
|
||||
private static String version = "no version found";
|
||||
private static boolean isMohist = false;
|
||||
public static void init(){
|
||||
try {
|
||||
version = getServer().getClass().getPackage().getName().split("\\.")[3];
|
||||
String[] mc_version = getServer().getBukkitVersion().split("-")[0].split("\\.");
|
||||
mcMainVersion = Integer.parseInt(mc_version[1]);
|
||||
if(mc_version.length<=2) mcPatchVersion = 0;
|
||||
else mcPatchVersion = Integer.parseInt(mc_version[2]);
|
||||
} catch (Throwable throwable) {
|
||||
throwable.printStackTrace();
|
||||
Lang.warn("Failed to get nms-version!");
|
||||
}
|
||||
Lang.info("Found version: " + version);
|
||||
try{
|
||||
Class.forName("net.minecraftforge.server.ServerMain");
|
||||
isMohist = true;
|
||||
}catch(ReflectiveOperationException ignored){}
|
||||
|
||||
}
|
||||
public static I_NMSItemManager getNMSItemManager(){
|
||||
switch (version){
|
||||
case "v1_12_R1" : return new pers.xanadu.enderdragon.nms.NMSItem.v1_12_R1.NMSItemManager();
|
||||
case "v1_13_R1" : return new pers.xanadu.enderdragon.nms.NMSItem.v1_13_R1.NMSItemManager();
|
||||
default: return new pers.xanadu.enderdragon.nms.NMSItem.v1_13_R2_above.NMSItemManager();
|
||||
}
|
||||
}
|
||||
public static I_BossBarManager getBossBarManager(){
|
||||
switch(version){
|
||||
case "v1_12_R1" : return new pers.xanadu.enderdragon.nms.BossBar.v1_12_R1.BossBarManager();
|
||||
case "v1_13_R1" : return new pers.xanadu.enderdragon.nms.BossBar.v1_13_R1.BossBarManager();
|
||||
case "v1_13_R2" : return new pers.xanadu.enderdragon.nms.BossBar.v1_13_R2.BossBarManager();
|
||||
default: return null;
|
||||
}
|
||||
}
|
||||
public static I_WorldDataManager getWorldDataManager(){
|
||||
switch (version){
|
||||
case "v1_12_R1" : return new pers.xanadu.enderdragon.nms.WorldData.v1_12_R1.WorldDataManager();
|
||||
case "v1_13_R1" : return new pers.xanadu.enderdragon.nms.WorldData.v1_13_R1.WorldDataManager();
|
||||
case "v1_13_R2" : return new pers.xanadu.enderdragon.nms.WorldData.v1_13_R2.WorldDataManager();
|
||||
case "v1_14_R1" : return new pers.xanadu.enderdragon.nms.WorldData.v1_14_R1.WorldDataManager();
|
||||
case "v1_15_R1" : return new pers.xanadu.enderdragon.nms.WorldData.v1_15_R1.WorldDataManager();
|
||||
case "v1_16_R1" : return new pers.xanadu.enderdragon.nms.WorldData.v1_16_R1.WorldDataManager();
|
||||
case "v1_16_R2" : return new pers.xanadu.enderdragon.nms.WorldData.v1_16_R2.WorldDataManager();
|
||||
case "v1_16_R3" : return new pers.xanadu.enderdragon.nms.WorldData.v1_16_R3.WorldDataManager();
|
||||
default : return new pers.xanadu.enderdragon.nms.WorldData.v1_17_above.WorldDataManager();
|
||||
}
|
||||
}
|
||||
public static I_RespawnAnchorManager getRespawnAnchorManager(){
|
||||
switch (version){
|
||||
case "v1_12_R1" :
|
||||
case "v1_13_R1" :
|
||||
case "v1_14_R1" :
|
||||
case "v1_13_R2" :
|
||||
case "v1_15_R1" : return null;
|
||||
case "v1_16_R1" : return new pers.xanadu.enderdragon.nms.RespawnAnchor.v1_16_R1.RespawnAnchorManager();
|
||||
case "v1_16_R2" : return new pers.xanadu.enderdragon.nms.RespawnAnchor.v1_16_R2.RespawnAnchorManager();
|
||||
case "v1_16_R3" : return new pers.xanadu.enderdragon.nms.RespawnAnchor.v1_16_R3.RespawnAnchorManager();
|
||||
case "v1_17_R1" : return new pers.xanadu.enderdragon.nms.RespawnAnchor.v1_17_R1.RespawnAnchorManager();
|
||||
default: return new pers.xanadu.enderdragon.nms.RespawnAnchor.v1_18_above.RespawnAnchorManager();
|
||||
}
|
||||
}
|
||||
public static String getVersion() {
|
||||
return version;
|
||||
}
|
||||
public static boolean isMohist(){
|
||||
return isMohist;
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user