update to v2.2.0
This commit is contained in:
@@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user