update to v2.2.0

This commit is contained in:
Xanadu13
2023-08-25 22:01:38 +08:00
committed by GitHub
parent 2d03cc4113
commit f75915bc33
31 changed files with 1859 additions and 0 deletions
@@ -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,101 @@
package pers.xanadu.enderdragon.script;
import java.lang.reflect.Method;
import java.util.concurrent.atomic.AtomicLong;
import java.util.function.Consumer;
import org.bukkit.Bukkit;
import org.bukkit.event.Event;
import org.bukkit.event.EventPriority;
import org.bukkit.event.HandlerList;
import org.bukkit.event.Listener;
import org.bukkit.plugin.EventExecutor;
import org.jetbrains.annotations.NotNull;
import pers.xanadu.enderdragon.manager.GroovyManager;
import static pers.xanadu.enderdragon.EnderDragon.plugin;
public class Events<T extends Event> implements Listener, EventExecutor {
private final Consumer<T> consumer;
private final Class<T> clazz;
private boolean disabled;
private final AtomicLong expireTime;
public Events(Class<T> clazz, Consumer<T> consumer) {
this.clazz = clazz;
this.consumer = consumer;
this.expireTime = new AtomicLong(-1L);
this.disabled = false;
}
public void unregister() {
if (!this.disabled) {
try {
Method method = this.clazz.getMethod("getHandlerList");
HandlerList handlerList = (HandlerList) method.invoke(null);
if (Bukkit.isPrimaryThread()) {
handlerList.unregister(this);
}
else {
Bukkit.getScheduler().runTask(plugin, () -> handlerList.unregister(this));
}
} catch (Exception e) {
e.printStackTrace();
}
this.disabled = true;
}
}
public static <T extends Event> Events<T> registerPersistently(Class<T> clazz, Consumer<T> consumer) {
return Events.registerPersistently(clazz, EventPriority.NORMAL, false, consumer);
}
public static <T extends Event> Events<T> registerPersistently(Class<T> clazz, EventPriority priority, boolean ignoreCancelled, Consumer<T> consumer) {
Events<T> tmp = new Events<>(clazz, consumer);
if (Bukkit.isPrimaryThread()) {
Bukkit.getPluginManager().registerEvent(clazz,tmp,priority,tmp,plugin,ignoreCancelled);
}
else {
Bukkit.getScheduler().runTask(plugin, () -> Bukkit.getPluginManager().registerEvent(clazz,tmp,priority,tmp,plugin,ignoreCancelled));
}
return tmp;
}
public static <T extends Event> Events<T> register(Class<T> clazz, Consumer<T> consumer) {
return Events.register(clazz, EventPriority.NORMAL, false, consumer);
}
public static <T extends Event> Events<T> register(Class<T> clazz, EventPriority priority, boolean ignoreCancelled, Consumer<T> consumer) {
Events<T> tmp = new Events<>(clazz, consumer);
if (Bukkit.isPrimaryThread()) {
Bukkit.getPluginManager().registerEvent(clazz,tmp,priority,tmp,plugin,ignoreCancelled);
}
else {
Bukkit.getScheduler().runTask(plugin, () -> Bukkit.getPluginManager().registerEvent(clazz,tmp,priority,tmp,plugin,ignoreCancelled));
}
GroovyManager.event_set.add(tmp);
return tmp;
}
// private static <T extends Event> void register(Class<T> clazz, Events<T> event, EventPriority priority, boolean ignoreCancelled) {
// Bukkit.getPluginManager().registerEvent(clazz,event,priority,event,plugin,ignoreCancelled);
// }
@Override
public void execute(@NotNull Listener listener, @NotNull Event event) {
if (this.expireTime.get() > 0L && System.currentTimeMillis() > this.expireTime.get()) {
Bukkit.getScheduler().runTask(plugin, this::unregister);
return;
}
if (this.clazz.isInstance(event)) {
this.consumer.accept((T) event);
}
}
public Events<T> withTime(long time) {
this.expireTime.set(time);
return this;
}
public boolean cancelIfExpired() {
if (this.expireTime.get() > 0L && System.currentTimeMillis() > this.expireTime.get()) {
this.unregister();
return true;
}
return false;
}
}
@@ -0,0 +1,37 @@
package pers.xanadu.enderdragon.task;
import org.bukkit.scheduler.BukkitRunnable;
import pers.xanadu.enderdragon.config.Lang;
import pers.xanadu.enderdragon.EnderDragon;
import static pers.xanadu.enderdragon.EnderDragon.*;
public class DragonRespawnRunnable extends BukkitRunnable {
private final Task task;
public DragonRespawnRunnable(Task task){
this.task = task;
}
@Override
public void run(){
if(task == null) {
this.cancel();
Lang.error("The config of auto-respawn errors!Task has been disabled...");
return;
}
if(task.isTimeUp()){
new BukkitRunnable(){
@Override
public void run(){
EnderDragon.getInstance().getDragonManager().initiateRespawn(task.world_name);
task.updateTime();
task.saveFile();
}
}.runTask(plugin);
}
}
public void start(){
this.runTaskTimerAsynchronously(plugin,0,200L);
}
}
@@ -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,94 @@
package pers.xanadu.enderdragon.task;
import pers.xanadu.enderdragon.EnderDragon;
import pers.xanadu.enderdragon.config.Lang;
import pers.xanadu.enderdragon.manager.TaskManager;
import java.io.IOException;
import java.time.LocalDateTime;
import java.time.LocalTime;
import static pers.xanadu.enderdragon.EnderDragon.data;
import static pers.xanadu.enderdragon.EnderDragon.dataF;
import static pers.xanadu.enderdragon.manager.TaskManager.getRoundTimeStr;
public abstract class Task {
protected int period;
protected int day;
private final TaskType type;
protected abstract LocalDateTime initNextTime(LocalDateTime cur);
public abstract void updateTime();
protected LocalDateTime nextTime;
protected final String world_name;
protected final String unique_name;
protected Task(TaskType type, String unique_name,String world_name,String str){
this.type = type;
this.unique_name = unique_name;
this.world_name = world_name;
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;
}
}
char split = data.options().pathSeparator();
String next_time = EnderDragon.data.getString("auto_respawn"+split+unique_name+split+"next_respawn_time");
if(next_time == null){
switch (type){
case minute :
case hour : {
this.nextTime = this.initNextTime(LocalDateTime.now().withSecond(0));
break;
}
case day :
case week :
case month :
case year : {
calcNextTime(str);
break;
}
}
this.saveFile();
}
else this.nextTime = TaskManager.getLocalDateTime(next_time);
}
private void calcNextTime(String str){
LocalTime time = TaskManager.getRoundTime(str.split(",")[1]);
if(time != null) this.nextTime = this.initNextTime(LocalDateTime.now().withSecond(0).with(time));
else this.nextTime = this.initNextTime(LocalDateTime.now().withSecond(0));
}
public boolean isTimeUp(){
LocalDateTime now = LocalDateTime.now().plusSeconds(1);
if(now.isAfter(nextTime)){
return true;
}
return false;
}
public void saveFile(){
char split = data.options().pathSeparator();
String path = "auto_respawn"+split+unique_name+split;
data.set(path+"world_name",world_name);
data.set(path+"next_respawn_time",getRoundTimeStr(nextTime));
try{
data.save(dataF);
}catch (IOException ex){
Lang.error(Lang.plugin_file_save_error.replaceAll("\\{file_name}",dataF.getName()));
}
}
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,21 @@
package pers.xanadu.enderdragon.task.type;
import pers.xanadu.enderdragon.task.Task;
import pers.xanadu.enderdragon.task.TaskType;
import java.time.LocalDateTime;
public class Day extends Task {
@Override
public LocalDateTime initNextTime(LocalDateTime cur) {
return cur.plusDays(period);
}
@Override
public void updateTime(){
this.nextTime = LocalDateTime.now().withSecond(0).plusDays(period);
}
public Day(TaskType type, String unique_name,String world_name,String str){
super(type,unique_name,world_name,str);
}
}
@@ -0,0 +1,20 @@
package pers.xanadu.enderdragon.task.type;
import pers.xanadu.enderdragon.task.Task;
import pers.xanadu.enderdragon.task.TaskType;
import java.time.LocalDateTime;
public class Hour extends Task {
@Override
public LocalDateTime initNextTime(LocalDateTime cur) {
return cur.plusHours(period);
}
@Override
public void updateTime(){
this.nextTime = LocalDateTime.now().withSecond(0).plusHours(period);
}
public Hour(TaskType type, String unique_name,String world_name,String str){
super(type,unique_name,world_name,str);
}
}
@@ -0,0 +1,22 @@
package pers.xanadu.enderdragon.task.type;
import pers.xanadu.enderdragon.task.Task;
import pers.xanadu.enderdragon.task.TaskType;
import java.time.LocalDateTime;
public class Minute extends Task {
@Override
public LocalDateTime initNextTime(LocalDateTime cur) {
return cur.plusMinutes(period);
}
@Override
public void updateTime(){
this.nextTime = LocalDateTime.now().withSecond(0).plusMinutes(period);
}
public Minute(TaskType type, String unique_name,String world_name,String str){
super(type,unique_name,world_name,str);
}
}
@@ -0,0 +1,21 @@
package pers.xanadu.enderdragon.task.type;
import pers.xanadu.enderdragon.task.Task;
import pers.xanadu.enderdragon.task.TaskType;
import java.time.LocalDateTime;
public class Month extends Task {
@Override
public LocalDateTime initNextTime(LocalDateTime cur) {
return cur.plusMonths(1).withDayOfMonth(day);
}
@Override
public void updateTime(){
this.nextTime = LocalDateTime.now().withSecond(0).plusMonths(1).withDayOfMonth(day);
}
public Month(TaskType type, String unique_name,String world_name,String str){
super(type,unique_name,world_name,str);
}
}
@@ -0,0 +1,22 @@
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;
public class Week extends Task {
@Override
public LocalDateTime initNextTime(LocalDateTime cur) {
return cur.with(DayOfWeek.of(day)).plusDays(7);
}
@Override
public void updateTime(){
this.nextTime = LocalDateTime.now().withSecond(0).plusDays(7);
}
public Week(TaskType type, String unique_name,String world_name,String str){
super(type,unique_name,world_name,str);
}
}
@@ -0,0 +1,20 @@
package pers.xanadu.enderdragon.task.type;
import pers.xanadu.enderdragon.task.Task;
import pers.xanadu.enderdragon.task.TaskType;
import java.time.LocalDateTime;
public class Year extends Task {
@Override
public LocalDateTime initNextTime(LocalDateTime cur) {
return cur.plusYears(1).withDayOfMonth(day);
}
@Override
public void updateTime(){
this.nextTime = LocalDateTime.now().withSecond(0).plusYears(1);
}
public Year(TaskType type, String unique_name,String world_name,String str){
super(type,unique_name,world_name,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(final 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(final 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,69 @@
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 parse(String str){
if(mcMainVersion >= 16){
return org.bukkit.ChatColor.translateAlternateColorCodes('&',transGradient(str));
}
else{
return org.bukkit.ChatColor.translateAlternateColorCodes('&',str);
}
}
private static String translateHexCodes(String 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());
}
private static String transGradient(String 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,32 @@
package pers.xanadu.enderdragon.util;
import org.bukkit.entity.Player;
public class ExtraPotionEffect {
private final ExtraPotionEffectType type;
private final int tick;
public void apply(final Player player){
switch (type){
case fire: {
player.setFireTicks(player.getFireTicks()+tick);
break;
}
case freeze: {
player.setFreezeTicks(player.getFreezeTicks()+tick);
break;
}
}
}
public ExtraPotionEffect(final String effect,int second){
this(ExtraPotionEffectType.valueOf(effect.toLowerCase()),second);
}
public ExtraPotionEffect(final ExtraPotionEffectType type,int second){
this.type = type;
this.tick = second*20;
}
public enum ExtraPotionEffectType{
fire,
freeze
}
}
@@ -0,0 +1,100 @@
package pers.xanadu.enderdragon.util;
import org.bukkit.Bukkit;
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;
public class MathUtil {
public static int floor(double d) {
int i = (int)d;
return d < (double)i ? i - 1 : i;
}
public static double c(final 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(final 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(final Location loc){
if (loc.getWorld() == null) return "";
return loc.getWorld().getName()+";"+loc.getX()+";"+loc.getY()+";"+loc.getZ();
}
public static Location stringToLocation(final String str){
final String[] parts = str.split(";");
if(parts.length != 4) return null;
final World world = Bukkit.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(final 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,62 @@
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 no_damage_tick;
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<ExtraPotionEffect> attack_extra_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(final MyDragon o) {
return o.priority - this.priority;//降序
}
}
@@ -0,0 +1,453 @@
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.Config;
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.getNMSWord = CraftWorldClass.getDeclaredMethod("getHandle");
this.WorldClass = this.getNMSWord.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;
}
if(Config.debug) check();
}
public void check(){
try{
Field[] fields = NMSUtil.class.getDeclaredFields();
for(Field field : fields){
Bukkit.getLogger().info(field.getName()+"->"+field.get(this));
}
}catch (ReflectiveOperationException e){
e.printStackTrace();
}
}
// 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(final ItemStack item,final 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(final Object cpd){
try{
return (Map<String, Object>) NBTTagCompound_map.get(cpd);
}catch (ReflectiveOperationException e){
e.printStackTrace();
return null;
}
}
public Object getNBTTagCompound(final 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(final String str){
try{
return stringToNBTBase.invoke(MOJANGSON_PARSER.get(null),str);
}catch (ReflectiveOperationException e){
e.printStackTrace();
return null;
}
}
public void setPersistentDataContainer(final PersistentDataContainer dataContainer,final Object cpd){
try{
Object PDC = CraftPersistentDataContainerClass.cast(dataContainer);
PersistentDataContainer_putAll.invoke(PDC,cpd);
}catch (ReflectiveOperationException e){
e.printStackTrace();
}
}
public String PDCtoString(final PersistentDataContainer dataContainer){
try{
Object PDC = CraftPersistentDataContainerClass.cast(dataContainer);
return PDCtoCPD.invoke(PDC).toString();
}catch (ReflectiveOperationException e){
e.printStackTrace();
return null;
}
}
public Object deserializeObject(final Object object){
try{
return deserializeObject.invoke(null,object);
}catch (ReflectiveOperationException e){
e.printStackTrace();
return null;
}
}
public Object serializeNBTBase(final Object nbt_base){
try{
return serializeNBTBase.invoke(null, nbt_base);
}catch (ReflectiveOperationException e){
e.printStackTrace();
return null;
}
}
public void setUnhandledTags(final 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(final 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(final ItemStack item,final 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(final 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(final 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(final String nbt){
try{
return stringToCPD.invoke(null,nbt);
}catch (ReflectiveOperationException e){
e.printStackTrace();
return null;
}
}
/**
* 仅1.13+可用
*/
public ItemStack getItemStack(final 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(final 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(final World world,final 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(final 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(final World ThisWorld) {
try {
Object castClass = getCraftWorld(ThisWorld);
return this.CraftWorldClass.getDeclaredMethod("getHandle").invoke(castClass);
} catch (ReflectiveOperationException e) {
e.printStackTrace();
}
return null;
}
public Object getCraftWorld(final World ThisWorld) {
if (this.CraftWorldClass.isInstance(ThisWorld)) return this.CraftWorldClass.cast(ThisWorld);
return null;
}
public Object getWorld_e(final World world){
try {
Object world_c = getCraftWorld(world);
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(final 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,48 @@
package pers.xanadu.enderdragon.util;
import org.bukkit.event.player.PlayerJoinEvent;
import org.bukkit.scheduler.BukkitRunnable;
import pers.xanadu.enderdragon.EnderDragon;
import pers.xanadu.enderdragon.config.Lang;
import pers.xanadu.enderdragon.script.Events;
import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.URL;
import java.net.URLConnection;
public class UpdateChecker {
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));
Events.registerPersistently(PlayerJoinEvent.class,e->{
if(e.getPlayer().hasPermission("ed.update.notify")) {
e.getPlayer().sendMessage("§3An update for §bEnderDragon §r(v" + newVer + ")§3 is available at", "§7§nhttps://www.spigotmc.org/resources/enderdragon.101583/");
}
});
}
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,87 @@
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 final String setting_dragon = "2.2.0";
public static final String lang = "2.2.0";
public static final String config = "2.2.0";
public static final String data = "2.2.0";
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;
}
}