update to v2.2.0

This commit is contained in:
Xanadu13
2023-08-25 22:00:26 +08:00
committed by GitHub
parent c1211c5155
commit 2d03cc4113
57 changed files with 4905 additions and 0 deletions
@@ -0,0 +1,45 @@
package pers.xanadu.enderdragon.listener;
import org.bukkit.entity.*;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.Listener;
import org.bukkit.event.entity.EntityDamageByEntityEvent;
import org.bukkit.potion.PotionEffect;
import pers.xanadu.enderdragon.manager.DragonManager;
import pers.xanadu.enderdragon.util.ExtraPotionEffect;
import pers.xanadu.enderdragon.util.MyDragon;
public class DragonAttackListener implements Listener {
@EventHandler(priority = EventPriority.LOW)
public void OnDragonAttack(final EntityDamageByEntityEvent e){
Entity victim = e.getEntity();
Entity attack = e.getDamager();
if(!(attack instanceof EnderDragon)) return;
EnderDragon dragon = (EnderDragon) attack;
String unique_name = DragonManager.getSpecialKey(dragon);
if(unique_name == null) return;
MyDragon myDragon = DragonManager.mp.get(unique_name);
if(myDragon == null) return;
e.setDamage(Math.max(0.1, e.getDamage() + myDragon.attack_damage_modify));
if(victim instanceof Player){
Player player = (Player) victim;
for(PotionEffect effect : myDragon.attack_potion_effect){
player.addPotionEffect(effect);
}
for(ExtraPotionEffect effect : myDragon.attack_extra_effect){
effect.apply(player);
}
if(!myDragon.suck_blood_enable) return;
double suck = e.getFinalDamage() * myDragon.suck_blood_rate + myDragon.suck_blood_base_amount;
dragon.setHealth(Math.min(dragon.getHealth()+suck,dragon.getMaxHealth()));
}
else{
if(!myDragon.suck_blood_enable) return;
if(myDragon.suck_blood_only_player) return;
double suck = e.getFinalDamage() * myDragon.suck_blood_rate + myDragon.suck_blood_base_amount;
dragon.setHealth(Math.min(dragon.getHealth()+suck,dragon.getMaxHealth()));
}
}
}
@@ -0,0 +1,33 @@
package pers.xanadu.enderdragon.listener;
import org.bukkit.entity.*;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.Listener;
import org.bukkit.event.entity.EntityDamageByEntityEvent;
import pers.xanadu.enderdragon.event.DragonDamageByPlayerEvent;
import static pers.xanadu.enderdragon.EnderDragon.pm;
public class DragonBaseHurtListener implements Listener {
@EventHandler(priority = EventPriority.HIGHEST)
public void BaseAttackToDragon(EntityDamageByEntityEvent e){
if(e.isCancelled()) return;
if(e.getDamage() <= 0.0) return;
Entity victim = e.getEntity();
Entity entity = e.getDamager();
if(victim instanceof EnderDragon){
EnderDragon dragon = (EnderDragon) victim;
if(entity instanceof Player){
Player player = (Player) entity;
pm.callEvent(new DragonDamageByPlayerEvent(player,dragon,e.getCause(),e.getFinalDamage()));
}
else if(entity instanceof Projectile){
Projectile projectile = (Projectile) entity;
if(!(projectile.getShooter() instanceof Player)) return;
Player damager = (Player) projectile.getShooter();
pm.callEvent(new DragonDamageByPlayerEvent(damager,dragon,e.getCause(),e.getFinalDamage()));
}
}
}
}
@@ -0,0 +1,60 @@
package pers.xanadu.enderdragon.listener;
import net.md_5.bungee.api.ChatMessageType;
import net.md_5.bungee.api.chat.TextComponent;
import org.bukkit.entity.EnderDragon;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.Listener;
import pers.xanadu.enderdragon.config.Config;
import pers.xanadu.enderdragon.config.Lang;
import pers.xanadu.enderdragon.event.DragonDamageByPlayerEvent;
import pers.xanadu.enderdragon.manager.DamageManager;
import java.util.UUID;
import java.util.concurrent.ConcurrentHashMap;
public class DragonDamageByPlayerListener implements Listener {
@EventHandler(priority = EventPriority.HIGHEST)
public void OnDragonDamageByPlayer(final DragonDamageByPlayerEvent e){
Player p = e.getDamager();
EnderDragon dragon = e.getDragon();
double health = dragon.getHealth();
double damage = Math.min(e.getFinalDamage(),health);
if(damage > 0.0d){
UUID dragon_uid = dragon.getUniqueId();
ConcurrentHashMap<String,Double> mp = DamageManager.data.computeIfAbsent(dragon_uid, k->new ConcurrentHashMap<>());
mp.compute(p.getName(),(k,v)->v==null?damage:v+damage);
}
//Bukkit.broadcastMessage(RewardManager.data.get(dragon.getUniqueId()).get(p.getUniqueId())+"");
double max_health = dragon.getMaxHealth();
double remain_health = Math.max(health-e.getFinalDamage(),0.0);
String str = Lang.dragon_damage_display.replaceAll("%damage%", format(damage)).replaceAll("%remain_health%",format(remain_health)).replaceAll("%max_health%",format(max_health));
switch (Config.damage_visible_mode.toLowerCase()){
case "actionbar" : {
p.spigot().sendMessage(ChatMessageType.ACTION_BAR, TextComponent.fromLegacyText(str));
break;
}
case "chatbox" : {
Lang.sendFeedback(p,str);
break;
}
case "subtitle" : {
p.sendTitle("",str,5,40,5);
break;
}
default : {
}
}
}
private String format(double d0){
return String.format("%.2f",d0);
}
}
@@ -0,0 +1,163 @@
package pers.xanadu.enderdragon.listener;
import net.md_5.bungee.api.chat.BaseComponent;
import net.md_5.bungee.api.chat.ComponentBuilder;
import net.md_5.bungee.api.chat.HoverEvent;
import net.md_5.bungee.api.chat.TextComponent;
import org.bukkit.Bukkit;
import org.bukkit.Material;
import org.bukkit.block.Block;
import org.bukkit.entity.EnderDragon;
import org.bukkit.entity.Entity;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.entity.EntityDeathEvent;
import org.bukkit.scheduler.BukkitRunnable;
import pers.xanadu.enderdragon.config.Config;
import pers.xanadu.enderdragon.config.Lang;
import pers.xanadu.enderdragon.manager.DamageManager;
import pers.xanadu.enderdragon.manager.DragonManager;
import pers.xanadu.enderdragon.manager.TimerManager;
import pers.xanadu.enderdragon.util.MyDragon;
import pers.xanadu.enderdragon.util.Pair;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ThreadLocalRandom;
import static pers.xanadu.enderdragon.EnderDragon.*;
public class DragonDeathListener implements Listener {
@EventHandler
public void OnDragonDeath(final EntityDeathEvent e){
if(!(e.getEntity() instanceof EnderDragon)) return;
EnderDragon dragon = (EnderDragon) e.getEntity();
String unique_name = DragonManager.getSpecialKey(dragon);
if(unique_name == null) return;
MyDragon myDragon = DragonManager.mp.get(unique_name);
if(myDragon == null) return;
int times = data.getInt("times");
data.set("times",times+1);
try{
data.save(dataF);
}catch (IOException ex){
Lang.error(Lang.plugin_file_save_error.replaceAll("\\{file_name}",dataF.getName()));
}
e.setDroppedExp(myDragon.exp_drop);
if(myDragon.dragon_egg_spawn_chance > ThreadLocalRandom.current().nextDouble(100)){
new BukkitRunnable() {
@Override
public void run() {
Block block = e.getEntity().getWorld().getBlockAt(myDragon.dragon_egg_spawn_x, myDragon.dragon_egg_spawn_y, myDragon.dragon_egg_spawn_z);
block.setType(Material.DRAGON_EGG);
}
}.runTaskLater(plugin, myDragon.dragon_egg_spawn_delay);
}
Player p = e.getEntity().getKiller();
myDragon.reward_dist.handle_dist(myDragon,dragon,p);
{
List<String> processed = new ArrayList<>();
if(p != null){
for(String str : myDragon.death_broadcast_msg){
processed.add(str.replaceAll("%times%",String.valueOf(times)).replaceAll("%player%",p.getDisplayName()));
}
}
else{
StringBuilder names = new StringBuilder();
List<Entity> entities = dragon.getNearbyEntities(5,5,5);
for (Entity entity : entities) {
if (entity instanceof Player) {
names.append(((Player) entity).getDisplayName()).append(",");
}
}
String name = names.toString();
if(name.equals("")) name = Lang.dragon_no_killer;
if(name.endsWith(",")) name = name.substring(0,name.length()-1);
for(String str : myDragon.death_broadcast_msg){
processed.add(str.replaceAll("%times%",String.valueOf(times)).replaceAll("%player%", name));
}
}
handleBroadcast(processed,myDragon,dragon);
}
DamageManager.data.remove(dragon.getUniqueId());
Lang.runCommands(myDragon.death_cmd,p);
if(p != null){
for(String str : myDragon.msg_to_killer){
Lang.sendFeedback(p,str.replaceAll("%times%",String.valueOf(times)));
}
}
TimerManager.startTimer(dragon.getWorld().getName());
}
public static void handleBroadcast(final List<String> list,final MyDragon myDragon,final EnderDragon dragon){
boolean find = false;
for(String str : list){
if(str.contains("{damage_statistics}")){
find = true;
break;
}
}
if(!find) Lang.broadcastMSG(list);
else{
final TextComponent hover = getHover(myDragon,dragon);
for(String str : list){
final String[] splits = str.split("\\{damage_statistics}");
final ComponentBuilder builder = new ComponentBuilder(Lang.plugin_prefix);
int size = splits.length;
for(int i=0;i<size-1;i++){
builder.append(splits[i]).append(hover);
}
builder.append(splits[size-1]);
if(str.endsWith("{damage_statistics}")) builder.append(hover);
Bukkit.getOnlinePlayers().forEach(p->p.spigot().sendMessage(builder.create()));
}
}
}
public static TextComponent getHover(final MyDragon myDragon,final EnderDragon dragon) {
final TextComponent text = new TextComponent(Lang.dragon_damage_statistics_text);
List<Pair<String,Double>> list = DamageManager.getDamageList(dragon.getUniqueId());
list.sort(DamageManager::sortByDamage);
double sum = 0d;
for(Pair<String,Double> pair : list){
sum += pair.second;
}
StringBuilder builder = new StringBuilder();
for(String raw : Lang.dragon_damage_statistics_hover_prefix){
builder.append(raw
.replaceAll("%dragon_display_name%",myDragon.display_name)
.replaceAll("%damage_sum%",String.format("%.2f",sum))
).append("\n");
}
int i = 0;
for(Pair<String,Double> pair : list){
String raw = Lang.dragon_damage_statistics_hover_mt;
if(i < Config.damage_statistics_limit){
double damage = pair.second;
double percent = damage/sum*100;
builder.append(raw
.replaceAll("%rank%", String.valueOf(++i))
.replaceAll("%player%", pair.first)
.replaceAll("%damage%",String.format("%.2f",damage))
.replaceAll("%percent%",String.format("%.2f%%",percent))
).append("\n");
}
}
if(list.size()-i>0){
String raw = Lang.dragon_damage_statistics_hover_exceeds_limit;
builder.append(raw
.replaceAll("%exceeds_number%", String.valueOf(list.size()-i))
).append("\n");
}
for(String raw : Lang.dragon_damage_statistics_hover_suffix){
builder.append(raw
.replaceAll("%dragon_display_name%",myDragon.display_name)
.replaceAll("%damage_sum%",String.format("%.2f",sum))
);
}
BaseComponent[] cmp = new ComponentBuilder(builder.toString()).create();
text.setHoverEvent(new HoverEvent(HoverEvent.Action.SHOW_TEXT,cmp));
return text;
}
}
@@ -0,0 +1,93 @@
package pers.xanadu.enderdragon.listener;
import org.bukkit.Location;
import org.bukkit.World;
import org.bukkit.entity.EnderDragon;
import org.bukkit.entity.Entity;
import org.bukkit.entity.Player;
import org.bukkit.entity.TNTPrimed;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.Listener;
import org.bukkit.event.entity.EntityDamageByBlockEvent;
import org.bukkit.event.entity.EntityDamageByEntityEvent;
import org.bukkit.event.entity.EntityDamageEvent;
import org.bukkit.event.player.PlayerBedEnterEvent;
import pers.xanadu.enderdragon.event.DragonDamageByPlayerEvent;
import pers.xanadu.enderdragon.event.PlayerExplodeDragonEvent;
import java.util.Collection;
import java.util.UUID;
import java.util.concurrent.ConcurrentHashMap;
import static pers.xanadu.enderdragon.EnderDragon.pm;
import static pers.xanadu.enderdragon.manager.WorldManager.getExplosionDragon;
public class DragonExplosionHurtListener implements Listener {
private static final ConcurrentHashMap<UUID,PlayerExplodeDragonEvent> mp = new ConcurrentHashMap<>();
@EventHandler(priority = EventPriority.HIGHEST)
public void OnDragonDamageByTNT(final EntityDamageByEntityEvent e){
if(e.isCancelled()) return;
if(e.getDamage() <= 0.0) return;
Entity victim = e.getEntity();
Entity entity = e.getDamager();
if(victim instanceof EnderDragon){
EnderDragon dragon = (EnderDragon) victim;
if(entity instanceof TNTPrimed){
TNTPrimed tnt = (TNTPrimed) entity;
if(!(tnt.getSource() instanceof Player)) return;
Player damager = (Player) tnt.getSource();
pers.xanadu.enderdragon.EnderDragon.pm.callEvent(new DragonDamageByPlayerEvent(damager,dragon,e.getCause(),e.getFinalDamage()));
}
}
}
/**
* 用tnt隔着方块炸龙也能触发
*/
@EventHandler(priority = EventPriority.HIGHEST)
public void OnDragonDamageByExplode(final EntityDamageByBlockEvent e){
long time = pers.xanadu.enderdragon.EnderDragon.getInstance().getWorldDataManager().getGameTime(e.getEntity().getWorld());
EntityDamageEvent.DamageCause cause = e.getCause();
if(e.getCause() != EntityDamageEvent.DamageCause.BLOCK_EXPLOSION) return;
Entity entity = e.getEntity();
if(entity instanceof EnderDragon){
//Bukkit.broadcastMessage(e.getFinalDamage()+"awa");
EnderDragon dragon = (EnderDragon) entity;
for(UUID uuid : mp.keySet()){
PlayerExplodeDragonEvent ped = mp.get(uuid);
if(ped == null) continue;
if(ped.getTime() != time) continue;
if(ped.getEnderDragon().getUniqueId() != dragon.getUniqueId()) continue;
//mp.remove(uuid);
pm.callEvent(new DragonDamageByPlayerEvent(ped.getPlayer(),dragon,cause,e.getFinalDamage()));
//Bukkit.broadcastMessage("final: "+e.getFinalDamage());
break;
}
}
}
@EventHandler(priority = EventPriority.HIGH)
public void OnPlayerClickBed(final PlayerBedEnterEvent e){
Player p = e.getPlayer();
if(p.getWorld().getEnvironment() != World.Environment.THE_END) return;
long time = pers.xanadu.enderdragon.EnderDragon.getInstance().getWorldDataManager().getGameTime(e.getPlayer().getWorld());
Location bed_loc = e.getBed().getLocation();
Collection<EnderDragon> entities = getExplosionDragon(5f,bed_loc);
for(EnderDragon dragon : entities){
UUID uuid = p.getUniqueId();
mp.put(uuid,new PlayerExplodeDragonEvent(time,p,dragon,bed_loc));
break;
}
}
public static void clearUID(final UUID uuid){
mp.remove(uuid);
}
public static void addUID(final UUID uuid,final PlayerExplodeDragonEvent ped){
mp.put(uuid,ped);
}
}
@@ -0,0 +1,66 @@
package pers.xanadu.enderdragon.listener;
import org.bukkit.Bukkit;
import org.bukkit.Color;
import org.bukkit.Particle;
import org.bukkit.entity.AreaEffectCloud;
import org.bukkit.entity.DragonFireball;
import org.bukkit.entity.EnderDragon;
import org.bukkit.entity.Projectile;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.Listener;
import org.bukkit.event.entity.EnderDragonChangePhaseEvent;
import org.bukkit.event.entity.EntitySpawnEvent;
import org.bukkit.event.entity.ProjectileLaunchEvent;
import org.bukkit.potion.PotionEffect;
import org.bukkit.projectiles.ProjectileSource;
import pers.xanadu.enderdragon.util.MyDragon;
import static pers.xanadu.enderdragon.manager.DragonManager.getSpecialKey;
import static pers.xanadu.enderdragon.manager.DragonManager.mp;
public class DragonFireballListener implements Listener {
@EventHandler
public void OnDragonChangePhase(EnderDragonChangePhaseEvent e){
//Bukkit.broadcastMessage("old: "+e.getCurrentPhase());
//Bukkit.broadcastMessage("new: "+e.getNewPhase());
}
@EventHandler
public void OnDragonFireballLaunch(ProjectileLaunchEvent e){
Projectile projectile = e.getEntity();
if(!(projectile instanceof DragonFireball)) return;
Bukkit.broadcastMessage("DragonFireball launched!");
DragonFireball fireball = (DragonFireball) e.getEntity();
ProjectileSource source = projectile.getShooter();
if(source instanceof EnderDragon){
Bukkit.broadcastMessage("status set!");
}
}
@EventHandler(priority = EventPriority.HIGH)
public void OnEffectCloudSpawn(final EntitySpawnEvent e){
if(!(e.getEntity() instanceof AreaEffectCloud)) return;
AreaEffectCloud effectCloud = (AreaEffectCloud) e.getEntity();
if(effectCloud.getSource() == null) return;
if(!(effectCloud.getSource() instanceof EnderDragon)) return;
EnderDragon dragon = (EnderDragon) effectCloud.getSource();
String unique_name = getSpecialKey(dragon);
if(unique_name == null) return;
MyDragon myDragon = mp.get(unique_name);
if(myDragon == null) return;
effectCloud.setRadius((float) myDragon.effect_cloud_original_radius);
effectCloud.setRadiusPerTick((float) myDragon.effect_cloud_expand_speed/20f);
effectCloud.setDuration(myDragon.effect_cloud_duration * 20);
if(myDragon.effect_cloud_color_R != -1){
effectCloud.setParticle(Particle.SPELL_MOB);
effectCloud.setColor(Color.fromRGB(myDragon.effect_cloud_color_R,myDragon.effect_cloud_color_G,myDragon.effect_cloud_color_B));
}
effectCloud.clearCustomEffects();
for(PotionEffect effect : myDragon.effect_cloud_potion){
effectCloud.addCustomEffect(effect,true);
}
}
}
@@ -0,0 +1,26 @@
package pers.xanadu.enderdragon.listener;
import org.bukkit.entity.EnderDragon;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.Listener;
import org.bukkit.event.entity.EntityRegainHealthEvent;
import pers.xanadu.enderdragon.util.MyDragon;
import static pers.xanadu.enderdragon.manager.DragonManager.getSpecialKey;
import static pers.xanadu.enderdragon.manager.DragonManager.mp;
public class DragonHealListener implements Listener {
@EventHandler(priority = EventPriority.HIGH)
public void OnDragonHeal(final EntityRegainHealthEvent e){
if(!(e.getEntity() instanceof EnderDragon)) return;
EnderDragon dragon = (EnderDragon) e.getEntity();
if(!e.getRegainReason().equals(EntityRegainHealthEvent.RegainReason.ENDER_CRYSTAL)) return;
String unique_name = getSpecialKey(dragon);
if(unique_name == null) return;
MyDragon myDragon = mp.get(unique_name);
if(myDragon == null) return;
e.setAmount(myDragon.crystal_heal_speed / 2d);
}
}
@@ -0,0 +1,71 @@
package pers.xanadu.enderdragon.listener;
import org.bukkit.attribute.Attribute;
import org.bukkit.boss.BarColor;
import org.bukkit.boss.BarStyle;
import org.bukkit.boss.BossBar;
import org.bukkit.entity.*;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.Listener;
import org.bukkit.event.entity.CreatureSpawnEvent;
import pers.xanadu.enderdragon.config.Config;
import pers.xanadu.enderdragon.config.Lang;
import pers.xanadu.enderdragon.manager.DamageManager;
import pers.xanadu.enderdragon.util.MyDragon;
import pers.xanadu.enderdragon.util.Version;
import java.util.concurrent.ConcurrentHashMap;
import static pers.xanadu.enderdragon.EnderDragon.*;
import static pers.xanadu.enderdragon.manager.DragonManager.*;
import static pers.xanadu.enderdragon.manager.GlowManager.*;
public class DragonSpawnListener implements Listener {
@EventHandler(priority = EventPriority.LOW)
public void OnDragonSpawn(final CreatureSpawnEvent e){
if(!(e.getEntity() instanceof EnderDragon)) return;
if(Config.blacklist_worlds.contains(e.getEntity().getWorld().getName())) return;
EnderDragon dragon = (EnderDragon) e.getEntity();
MyDragon myDragon = judge();
if(myDragon == null) {
Lang.warn("special_dragon_jude_mode setting error!");
return;
}
setSpecialKey(dragon, myDragon.unique_name);
DamageManager.data.put(dragon.getUniqueId(),new ConcurrentHashMap<>());
int times = data.getInt("times");
Lang.runCommands(myDragon.spawn_cmd);
for(String str : myDragon.spawn_broadcast_msg){
Lang.broadcastMSG(str.replaceAll("%times%",String.valueOf(times)));
}
dragon.setCustomName(myDragon.display_name);
setAttribute(dragon, Attribute.GENERIC_MAX_HEALTH, myDragon.max_health);
dragon.setHealth(myDragon.spawn_health);
dragon.setMaximumNoDamageTicks(myDragon.no_damage_tick);
//modifyAttribute(dragon, Attribute.GENERIC_MOVEMENT_SPEED, myDragon.move_speed_modify);//
modifyAttribute(dragon, Attribute.GENERIC_ARMOR, myDragon.armor_modify);
modifyAttribute(dragon, Attribute.GENERIC_ARMOR_TOUGHNESS, myDragon.armor_toughness_modify);
String color = myDragon.glow_color.toUpperCase();
if(!color.equals("NONE")) setGlowingColor(dragon,getGlowColor(color));
else dragon.setGlowing(false);
String bossBar_color = myDragon.bossbar_color.toUpperCase();
String bossBar_style = myDragon.bossbar_style.toUpperCase();
if(Version.mcMainVersion >= 14){
BossBar bossBar = dragon.getBossBar();
if(bossBar != null){
bossBar.setColor(BarColor.valueOf(bossBar_color));
bossBar.setStyle(BarStyle.valueOf(bossBar_style));
}
}
else if(Version.mcMainVersion >= 12){
getInstance().getBossBarManager().setBossBar(dragon.getWorld(),myDragon.display_name,bossBar_color,bossBar_style);
}
//dragon.getMetadata();
}
}
@@ -0,0 +1,21 @@
package pers.xanadu.enderdragon.listener;
import org.bukkit.entity.Item;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.player.PlayerDropItemEvent;
public class EndGatewayListener implements Listener {
// @EventHandler
// public void OnEndGateWaySpawn(final PortalCreateEvent e){
// Bukkit.broadcastMessage("123");
// List<BlockState> list = e.getBlocks();
// list.forEach(block -> Bukkit.broadcastMessage(block.toString()));
// }
// @EventHandler
// public void OnEndGateWaySpawn2(final EntityCreatePortalEvent e){
// Bukkit.broadcastMessage("12345");
//
// }
}
@@ -0,0 +1,123 @@
package pers.xanadu.enderdragon.listener;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.Listener;
import org.bukkit.event.inventory.ClickType;
import org.bukkit.event.inventory.InventoryClickEvent;
import org.bukkit.event.inventory.InventoryDragEvent;
import org.bukkit.inventory.InventoryHolder;
import org.bukkit.inventory.PlayerInventory;
import pers.xanadu.enderdragon.config.Lang;
import pers.xanadu.enderdragon.gui.*;
import pers.xanadu.enderdragon.gui.holder.Menu;
import pers.xanadu.enderdragon.gui.holder.MenuEditor;
import pers.xanadu.enderdragon.gui.slot.PageJumpSlot;
import pers.xanadu.enderdragon.manager.DragonManager;
import pers.xanadu.enderdragon.manager.GuiManager;
import pers.xanadu.enderdragon.manager.RewardManager;
import pers.xanadu.enderdragon.util.MyDragon;
public class InventoryListener implements Listener {
@EventHandler(priority = EventPriority.LOWEST)
public void OnInventoryClick(final InventoryClickEvent e){
InventoryHolder holder = e.getInventory().getHolder();
if(!(holder instanceof GUIHolder)) return;
GUIHolder guiHolder = (GUIHolder) holder;
if(!(guiHolder.getGUI() instanceof GUIWrapper)) return;
e.setCancelled(true);
GUIWrapper guiWrapper = (GUIWrapper) guiHolder.getGUI();
if(e.getClickedInventory() instanceof PlayerInventory){
return;
}
if(e.getRawSlot() >= 54 || e.getRawSlot() < 0){ //点击箱子以外界面会返回-999
return;
}
Player p = (Player) e.getWhoClicked();
GUISlot slot = guiWrapper.getSlot(e.getRawSlot());
GUISlotType type = slot.getType();
if(type == GUISlotType.EMPTY || type == GUISlotType.TIP || type == GUISlotType.PAGE_TIP){
return;
}
if(type == GUISlotType.PAGE_PREV){
guiWrapper.prev();
p.updateInventory();
return;
}
if(type == GUISlotType.PAGE_NEXT){
guiWrapper.next();
p.updateInventory();
return;
}
if(holder instanceof Menu){
if(e.getClick() != ClickType.LEFT && e.getClick() != ClickType.RIGHT){
return;
}
if(type == GUISlotType.ITEM_SLOT){
return;
}
if(type == GUISlotType.PAGE_JUMP){
String name = ((PageJumpSlot)slot).getGuiName();
GuiManager.openGui(p,name,false);
return;
}
if(type == GUISlotType.DRAGON_SLOT){
String unique_name = guiWrapper.getData(guiWrapper.getPage(),e.getRawSlot());
MyDragon dragon = DragonManager.mp.get(unique_name);
if(dragon == null){
Lang.sendFeedback(p,Lang.gui_not_found);
return;
}
GuiManager.openGui(p,dragon.drop_gui,dragon.unique_name,false);
return;
}
}
else if(holder instanceof MenuEditor){
MenuEditor menuEditor = (MenuEditor) holder;
if(e.getClick() != ClickType.LEFT && e.getClick() != ClickType.RIGHT && e.getClick() != ClickType.SHIFT_RIGHT){
return;
}
if(type == GUISlotType.ITEM_SLOT){
if(e.getClick() != ClickType.SHIFT_RIGHT) return;
int idx = guiWrapper.getPage()*guiWrapper.getItemSize()+guiWrapper.getItemSlotIdx(e.getRawSlot());
//Bukkit.broadcastMessage(idx+"");
boolean b = RewardManager.removeItem(menuEditor.getDragon_key(),idx);
if(b) {
p.sendMessage(Lang.command_drop_item_remove_succeed);
guiWrapper.updateItemChanges(true);
}
else p.sendMessage(Lang.command_drop_item_remove_fail);
return;
}
if(type == GUISlotType.PAGE_JUMP){
String name = ((PageJumpSlot)slot).getGuiName();
GuiManager.openGui(p,name,true);
return;
}
if(type == GUISlotType.DRAGON_SLOT){
String unique_name = guiWrapper.getData(guiWrapper.getPage(),e.getRawSlot());
MyDragon dragon = DragonManager.mp.get(unique_name);
if(dragon == null){
Lang.sendFeedback(p,Lang.gui_not_found);
return;
}
GuiManager.openGui(p,dragon.drop_gui,dragon.unique_name,true);
return;
}
}
}
@EventHandler(priority = EventPriority.LOWEST)
public void OnInventoryDrag(final InventoryDragEvent e){
InventoryHolder holder = e.getInventory().getHolder();
if(!(holder instanceof GUIHolder)) return;
if(holder instanceof Menu){
GUIHolder guiHolder = (GUIHolder) holder;
if(!(guiHolder.getGUI() instanceof GUIWrapper)) return;
e.setCancelled(true);
}
}
}
@@ -0,0 +1,83 @@
package pers.xanadu.enderdragon.listener;
import org.bukkit.GameMode;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.World;
import org.bukkit.block.Block;
import org.bukkit.entity.*;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.Listener;
import org.bukkit.event.block.Action;
import org.bukkit.event.player.PlayerInteractEvent;
import org.bukkit.event.player.PlayerJoinEvent;
import org.bukkit.event.player.PlayerQuitEvent;
import org.bukkit.inventory.ItemStack;
import pers.xanadu.enderdragon.config.Config;
import pers.xanadu.enderdragon.manager.GlowManager;
import java.util.Collection;
public class PlayerListener implements Listener {
@EventHandler
public void onPlayerJoin(final PlayerJoinEvent e){
Player p = e.getPlayer();
GlowManager.setScoreBoard(p);
}
@EventHandler
public void onPlayerQuit(final PlayerQuitEvent e){
DragonExplosionHurtListener.clearUID(e.getPlayer().getUniqueId());
}
@EventHandler(priority = EventPriority.HIGHEST)
public void OnCrystalPlaced(final PlayerInteractEvent e){
if(!Config.resist_player_respawn) return;
if(e.getAction() != Action.RIGHT_CLICK_BLOCK) return;
if(e.getMaterial() != Material.END_CRYSTAL) return;
if(e.getClickedBlock() == null) return;
Material blockType = e.getClickedBlock().getType();
if(blockType != Material.OBSIDIAN && blockType != Material.BEDROCK) return;
World world = e.getPlayer().getWorld();
if(world.getEnvironment() != World.Environment.THE_END) return;
Block block = e.getClickedBlock();
int d0 = block.getX();
int d1 = block.getY() + 1;
int d2 = block.getZ();
if(world.getBlockAt(d0, d1, d2).getType() != Material.AIR) return;
Location cen = block.getLocation().clone().add(0.5,1,0.5);
Collection<Entity> list = world.getNearbyEntities(cen,0.5,1,0.5);
if(!list.isEmpty()) return;
e.setCancelled(true);
if(e.getPlayer().getGameMode() != GameMode.CREATIVE){
ItemStack item = e.getItem();
assert item != null;
int amount = item.getAmount();
e.getItem().setAmount(amount-1);
}
EnderCrystal crystal = (EnderCrystal) world.spawnEntity(cen,EntityType.ENDER_CRYSTAL);
crystal.setShowingBottom(false);
}
@EventHandler(priority = EventPriority.LOW)
public void OnDragonBreathGather(final PlayerInteractEvent e){
if(!Config.resist_dragon_breath_gather) return;
if(e.getMaterial() != Material.GLASS_BOTTLE) return;
if(e.getAction() != Action.RIGHT_CLICK_BLOCK && e.getAction() != Action.RIGHT_CLICK_AIR) return;
World world = e.getPlayer().getWorld();
if(world.getEnvironment() != World.Environment.THE_END) return;
Player p = e.getPlayer();
Location cen = p.getLocation().clone().add(0d,0.9d,0d);
Collection<Entity> list = world.getNearbyEntities(cen,2.3d,2.9d,2.3d);
for(Entity entity : list){
if(entity instanceof AreaEffectCloud) {
AreaEffectCloud effectCloud = (AreaEffectCloud) entity;
if(effectCloud.getSource() instanceof EnderDragon){
e.setCancelled(true);
break;
}
}
}
}
}
@@ -0,0 +1,16 @@
package pers.xanadu.enderdragon.listener;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.server.PluginDisableEvent;
import static pers.xanadu.enderdragon.EnderDragon.*;
public class PluginDisableListener implements Listener {
@EventHandler
public void OnPluginDisable(final PluginDisableEvent e){
if(e.getPlugin().equals(plugin)){
disableAll();
}
}
}
@@ -0,0 +1,45 @@
package pers.xanadu.enderdragon.listener;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.block.Block;
import org.bukkit.block.data.type.RespawnAnchor;
import org.bukkit.entity.EnderDragon;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.Listener;
import org.bukkit.event.block.Action;
import org.bukkit.event.player.PlayerInteractEvent;
import org.bukkit.inventory.EquipmentSlot;
import pers.xanadu.enderdragon.event.PlayerExplodeDragonEvent;
import java.util.Collection;
import java.util.UUID;
import static pers.xanadu.enderdragon.manager.WorldManager.getExplosionDragon;
public class RespawnAnchorExplodeListener implements Listener {
@EventHandler(priority = EventPriority.HIGH)
public void OnRespawnAnchorExplode(final PlayerInteractEvent e){
if(e.getAction() != Action.RIGHT_CLICK_BLOCK) return;
Block block = e.getClickedBlock();
if(block == null || block.getType() != Material.RESPAWN_ANCHOR) return;
RespawnAnchor anchor = (RespawnAnchor) block.getBlockData();
Player p = e.getPlayer();
Material offHand = p.getInventory().getItemInOffHand().getType();
if(e.getHand()== EquipmentSlot.HAND && e.getMaterial()!=Material.GLOWSTONE && offHand==Material.GLOWSTONE) return;
if(e.getMaterial()==Material.GLOWSTONE && anchor.getCharges()<4) return;
if(anchor.getCharges()==0) return;
if(pers.xanadu.enderdragon.EnderDragon.getInstance().getRespawnAnchorManager().isRespawnAnchorWorks(p.getWorld())) return;
if(p.isSneaking() && (p.getItemInHand().getType()!=Material.AIR || offHand!=Material.AIR)) return;
long time = pers.xanadu.enderdragon.EnderDragon.getInstance().getWorldDataManager().getGameTime(e.getPlayer().getWorld());
Location loc = block.getLocation();
Collection<EnderDragon> entities = getExplosionDragon(5f,loc);
for(EnderDragon dragon : entities){
UUID uuid = p.getUniqueId();
DragonExplosionHurtListener.addUID(uuid,new PlayerExplodeDragonEvent(time,p,dragon,loc));
break;
}
}
}
@@ -0,0 +1,27 @@
package pers.xanadu.enderdragon.listener.mythiclib;
import io.lumine.mythic.lib.api.event.PlayerAttackEvent;
import io.lumine.mythic.lib.damage.DamageMetadata;
import org.bukkit.entity.EnderDragon;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.Listener;
import pers.xanadu.enderdragon.event.DragonDamageByPlayerEvent;
import static pers.xanadu.enderdragon.EnderDragon.pm;
public class PlayerAttackListener implements Listener {
@EventHandler(priority = EventPriority.HIGH)
public void onPlayerAttack(final PlayerAttackEvent e){
if(e.isCancelled()) return;
if(!(e.getEntity() instanceof org.bukkit.entity.EnderDragon)) return;
EnderDragon dragon = (EnderDragon) e.getEntity();
DamageMetadata damage = e.getDamage();
double final_damage = damage.getDamage();
if(final_damage > 0.0d){
DragonDamageByPlayerEvent event = new DragonDamageByPlayerEvent(e.getAttacker().getPlayer(),dragon, e.toBukkit().getCause(), final_damage);
pm.callEvent(event);
}
}
}
@@ -0,0 +1,40 @@
package pers.xanadu.enderdragon.manager;
import org.bukkit.entity.Player;
import pers.xanadu.enderdragon.config.Lang;
import pers.xanadu.enderdragon.hook.HookManager;
import pers.xanadu.enderdragon.maven.DependencyManager;
import pers.xanadu.enderdragon.util.ColorUtil;
public class ActionManager {
public static void executeAction(final Player player,final String[] args){
String raw = getRawText(args,3);
switch (args[2]){
case "tell:" : {
player.sendMessage(ColorUtil.parse(HookManager.parsePapi(player,raw)));
return;
}
case "tell-colorless:" : {
player.sendMessage(HookManager.parsePapi(player,raw));
return;
}
case "tell-raw:" : {
player.sendMessage(raw);
return;
}
case "groovy:" : {
if(DependencyManager.isGroovyLoaded()) GroovyManager.eval(raw,player);
else Lang.sendFeedback(player,Lang.expansion_groovy_disable);
return;
}
}
}
private static String getRawText(final String[] args,int from){
if(from<0 || from>=args.length) throw new IllegalArgumentException("Index out of bounds!");
StringBuilder sb = new StringBuilder(args[from]);
for(int i=from+1;i<args.length;i++){
sb.append(" ").append(args[i]);
}
return sb.toString();
}
}
@@ -0,0 +1,25 @@
package pers.xanadu.enderdragon.manager;
import pers.xanadu.enderdragon.util.Pair;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
import java.util.concurrent.ConcurrentHashMap;
public class DamageManager {
public static final ConcurrentHashMap<UUID, ConcurrentHashMap<String,Double>> data = new ConcurrentHashMap<>();
public static List<Pair<String,Double>> getDamageList(UUID uuid){
ConcurrentHashMap<String,Double> mp = data.get(uuid);
List<Pair<String,Double>> list = new ArrayList<>();
if(mp == null) return list;
mp.forEach((k,v)->list.add(new Pair<>(k,v)));
return list;
}
public static <T> int sortByDamage(Pair<T, Double> p1, Pair<T, Double> p2){
if(p2.second>p1.second) return 1;
if(p2.second.equals(p1.second)) return 0;
return -1;
}
}
@@ -0,0 +1,464 @@
package pers.xanadu.enderdragon.manager;
import org.bukkit.*;
import org.bukkit.attribute.Attribute;
import org.bukkit.attribute.AttributeInstance;
import org.bukkit.attribute.AttributeModifier;
import org.bukkit.boss.DragonBattle;
import org.bukkit.command.CommandSender;
import org.bukkit.configuration.file.FileConfiguration;
import org.bukkit.configuration.file.YamlConfiguration;
import org.bukkit.entity.*;
import org.bukkit.potion.PotionEffect;
import org.bukkit.potion.PotionEffectType;
import org.bukkit.scheduler.BukkitRunnable;
import pers.xanadu.enderdragon.config.Config;
import pers.xanadu.enderdragon.config.Lang;
import pers.xanadu.enderdragon.reward.RewardDist;
import pers.xanadu.enderdragon.util.ExtraPotionEffect;
import pers.xanadu.enderdragon.util.MyDragon;
import pers.xanadu.enderdragon.util.Version;
import java.io.File;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.*;
import java.util.concurrent.ThreadLocalRandom;
import static pers.xanadu.enderdragon.EnderDragon.*;
public class DragonManager {
public static ArrayList<MyDragon> dragons = new ArrayList<>();
public static HashMap<String, MyDragon> mp = new HashMap<>();
public static List<String> dragon_names = new ArrayList<>();
private static int sum = 0;
private static final int[][] nxt = {{3,0},{0,3},{-3,0},{0,-3}};
private Method DragonBattle_e;
private Method getX;
private Method getY;
private Method getZ;
public static void reload(){
new BukkitRunnable(){
@Override
public void run(){
dragons.clear();
mp.clear();
dragon_names.clear();
sum = 0;
if(Config.dragon_setting_file == null){
Lang.error("\"dragon_setting_file\" in config.yml is empty!");
Lang.warn("Plugin will use the default config...");
Config.dragon_setting_file = new ArrayList<>();
Config.dragon_setting_file.add("default:5");
Config.dragon_setting_file.add("special:5");
}
for(String str : Config.dragon_setting_file){
String[] s = str.split(":");
if(s.length != 2){
Lang.error("\"dragon_setting_file\" in config.yml error! Key: " + str);
continue;
}
String path = "setting/" + s[0] + ".yml";
int edge = -1;
try {
edge = Integer.parseInt(s[1]);
} catch (NumberFormatException ignored){}
if(edge < 0) {
Lang.error("\"dragon_setting_file\" in config.yml error! Key: " + str);
continue;
}
File file = new File(plugin.getDataFolder(),path);
if(!file.exists()) {
try{
plugin.saveResource("setting/"+file.getName(),false);
file = new File(plugin.getDataFolder(),path);
}catch (Exception ignored){
Lang.error("Not Found setting/" + s[0] + ".yml ,skipped it.");
continue;
}
}
FileConfiguration fc = YamlConfiguration.loadConfiguration(file);
if(!Version.setting_dragon.equals(fc.getString("version"))){
Lang.warn(Lang.plugin_wrong_file_version.replace("{file_name}", file.getName()));
}
readSettingFile(fc,edge);
}
dragons.sort((o1, o2) -> o2.priority - o1.priority);
RewardManager.reload();
}
}.runTaskAsynchronously(plugin);
}
public static MyDragon judge(){
if(Config.special_dragon_jude_mode.equalsIgnoreCase("weight")){
int cnt = 0, random = ThreadLocalRandom.current().nextInt(0, sum);
for(MyDragon cur : dragons){
if(cnt <= random && cnt + cur.edge > random){
return cur;
}
cnt += cur.edge;
}
}
else if(Config.special_dragon_jude_mode.equalsIgnoreCase("pc")){
Iterator<MyDragon> it = dragons.iterator();
MyDragon cur = null;
while (it.hasNext()){
cur = it.next();
boolean judge = cur.spawn_chance > ThreadLocalRandom.current().nextDouble(100);
if(judge) return cur;
}
return cur;
}
else if(Config.special_dragon_jude_mode.equalsIgnoreCase("edge")){
int cnt = 0, random = ThreadLocalRandom.current().nextInt(0, sum);
for(MyDragon cur : dragons){
if(cnt <= random && cnt + cur.edge > random){
return cur;
}
cnt += cur.edge;
}
Lang.error("\"edge\" in \"special_dragon_jude_mode\" of config.yml is deprecated!Please use \"weight\" instead.");
}
return null;
}
public static void setSpecialKey(Entity e, String key){
e.addScoreboardTag(key);
}
public static String getSpecialKey(Entity e){
for(MyDragon a : dragons){
if(e.getScoreboardTags().contains(a.unique_name)) return a.unique_name;
}
return null;
}
public static void readSettingFile(FileConfiguration f,int edge){
MyDragon myDragon = new MyDragon();
myDragon.unique_name = f.getString("unique_name","default");
if(mp.containsKey(myDragon.unique_name)){
Lang.error("The unique_name conflict! Key: "+myDragon.unique_name);
return;
}
myDragon.icon = ItemManager.readFromBukkit(f,"icon");
myDragon.display_name = f.getString("display_name","Special Dragon");
myDragon.drop_gui = f.getString("drop_gui");
myDragon.edge = edge;
myDragon.priority = f.getInt("priority",1);
myDragon.spawn_chance = f.getDouble("spawn_chance",0);
myDragon.max_health = f.getInt("max_health",200);
myDragon.spawn_health = f.getInt("spawn_health",200);
myDragon.no_damage_tick = f.getInt("no_damage_tick",10);
myDragon.exp_drop = f.getInt("exp_drop",500);
myDragon.dragon_egg_spawn_delay = f.getInt("dragon_egg_spawn.delay",410);
myDragon.dragon_egg_spawn_x = f.getInt("dragon_egg_spawn.x",0);
myDragon.dragon_egg_spawn_y = f.getInt("dragon_egg_spawn.y",70);
myDragon.dragon_egg_spawn_z = f.getInt("dragon_egg_spawn.z",0);
myDragon.dragon_egg_spawn_chance = f.getDouble("dragon_egg_spawn.chance",0);
//myDragon.move_speed_modify = f.getDouble("move_speed_modify",0);
myDragon.armor_modify = f.getDouble("armor_modify",0);
myDragon.armor_toughness_modify = f.getDouble("armor_toughness_modify",0);
myDragon.crystal_heal_speed = f.getDouble("crystal_heal_speed",2.0);
myDragon.attack_damage_modify = f.getDouble("attack.damage_modify",0);
myDragon.suck_blood_enable = f.getBoolean("suck_blood.enable",true);
myDragon.suck_blood_rate = f.getDouble("suck_blood.rate",50) / 100d;
myDragon.suck_blood_base_amount = f.getDouble("suck_blood.base_amount",1);
myDragon.suck_blood_only_player = f.getBoolean("suck_blood.only_player",true);
List<ExtraPotionEffect> extraEffect = new ArrayList<>();
int fire = f.getInt("attack.extra_effect.fire");
if(fire>0) extraEffect.add(new ExtraPotionEffect(ExtraPotionEffect.ExtraPotionEffectType.fire,fire));
if(Version.mcMainVersion >= 17){
int freeze = f.getInt("attack.extra_effect.freeze");
if(freeze>0) extraEffect.add(new ExtraPotionEffect(ExtraPotionEffect.ExtraPotionEffectType.freeze,freeze));
}
myDragon.attack_extra_effect = extraEffect;
List<String> stringList = f.getStringList("attack.potion_effect");
List<PotionEffect> potions = new ArrayList<>();
for(String string : stringList){
String[] s = string.split(" ");
if(s.length != 3) continue;
PotionEffectType type = PotionEffectType.getByName(s[0].toUpperCase());
if(type == null){
Lang.error("Unknown potion type: " + s[0]);
continue;
}
int duration = -1;
try {
duration = Integer.parseInt(s[1]);
} catch (NumberFormatException ex){
Lang.error("Wrong number format: " + s[1]);
}
if(duration == -1) continue;
int level = -1;
try {
level = Integer.parseInt(s[2]);
} catch (NumberFormatException ex){
Lang.error("Wrong number format: " + s[2]);
}
if(level == -1) continue;
PotionEffect potionEffect = new PotionEffect(type,duration*20,level-1);
potions.add(potionEffect);
}
myDragon.attack_potion_effect = potions;
myDragon.spawn_cmd = f.getStringList("spawn_cmd");
myDragon.death_cmd = f.getStringList("death_cmd");
myDragon.spawn_broadcast_msg = f.getStringList("spawn_broadcast_msg");
myDragon.death_broadcast_msg = f.getStringList("death_broadcast_msg");
myDragon.msg_to_killer = f.getStringList("msg_to_killer");
myDragon.glow_color = f.getString("glow_color","random");
myDragon.bossbar_color = f.getString("bossbar.color","WHITE");
myDragon.bossbar_style = f.getString("bossbar.style","SOLID");
myDragon.effect_cloud_original_radius = f.getDouble("effect_cloud.original_radius",3);
myDragon.effect_cloud_expand_speed = f.getDouble("effect_cloud.expand_speed",0.1333333);
myDragon.effect_cloud_duration = f.getInt("effect_cloud.duration",60);
String effect_cloud_color = f.getString("effect_cloud.color","none");
String[] s0 = effect_cloud_color.split(":");
if(s0.length != 3) myDragon.effect_cloud_color_R = -1;
else{
try{
myDragon.effect_cloud_color_R = Integer.parseInt(s0[0]);
myDragon.effect_cloud_color_G = Integer.parseInt(s0[1]);
myDragon.effect_cloud_color_B = Integer.parseInt(s0[2]);
}
catch (NumberFormatException e){
Lang.error("Wrong effect_cloud_color format!");
myDragon.effect_cloud_color_R = -1;
}
}
List<String> stringList2 = f.getStringList("effect_cloud.potion");
List<PotionEffect> effectCloudPotions = new ArrayList<>();
for(String string : stringList2){
String[] s = string.split(" ");
if(s.length != 3) continue;
PotionEffectType type = PotionEffectType.getByName(s[0].toUpperCase());
if(type == null){
Lang.error("Unknown potion type: " + s[0]);
continue;
}
int duration = -1;
try {
duration = Integer.parseInt(s[1]);
} catch (NumberFormatException ex){
Lang.error("Wrong number format: " + s[1]);
}
if(duration == -1) continue;
int level = -1;
try {
level = Integer.parseInt(s[2]);
} catch (NumberFormatException ex){
Lang.error("Wrong number format: " + s[2]);
}
if(level == -1) continue;
PotionEffect potionEffect = new PotionEffect(type,duration*20,level-1);
effectCloudPotions.add(potionEffect);
}
myDragon.effect_cloud_potion = effectCloudPotions;
myDragon.reward_dist = RewardDist.parse(f.getConfigurationSection("reward_dist"));
dragons.add(myDragon);
mp.put(myDragon.unique_name,myDragon);
dragon_names.add(myDragon.unique_name);
sum += edge;
}
public static void disable(){
dragons.clear();
mp.clear();
dragon_names.clear();
}
public static void setAttribute(final EnderDragon dragon,final Attribute attribute, double amount){
AttributeInstance instance = dragon.getAttribute(attribute);
assert instance != null;
instance.setBaseValue(amount);
}
public static void modifyAttribute(final EnderDragon dragon,final Attribute attribute, double amount){
AttributeInstance instance = dragon.getAttribute(attribute);
assert instance != null;
instance.addModifier(new AttributeModifier("EnderDragon",amount,AttributeModifier.Operation.ADD_NUMBER));
}
public void initiateRespawn(final Player p){
DragonRespawnResult res = initiateRespawn(p.getWorld());
if(res == DragonRespawnResult.success) Lang.broadcastMSG(Lang.dragon_auto_respawn);
else Lang.sendFeedback(p,"§c"+res.getMessage());
}
public void initiateRespawn(final CommandSender sender,final String world_name){
DragonRespawnResult res = initiateRespawn(Bukkit.getWorld(world_name));
if(res == DragonRespawnResult.success) Lang.broadcastMSG(Lang.dragon_auto_respawn);
else Lang.sendFeedback(sender,"§c"+res.getMessage());
}
public void initiateRespawn(final String world_name){
DragonRespawnResult res = initiateRespawn(Bukkit.getWorld(world_name));
if(res == DragonRespawnResult.success) Lang.broadcastMSG(Lang.dragon_auto_respawn);
else Lang.error(res.getMessage());
}
public boolean canRespawn(final String world_name){
return canRespawn(Bukkit.getWorld(world_name));
}
public boolean canRespawn(final World world){
if(world == null) return false;
if(world.getEnvironment() != World.Environment.THE_END) return false;
if(Version.mcMainVersion >= 16){//executes 1e5 times within 27ms
DragonBattle battle = world.getEnderDragonBattle();
if(battle == null) return false;
if(battle.getEnderDragon() != null) return false;
if(battle.getRespawnPhase() != DragonBattle.RespawnPhase.NONE) return false;
Location cen = battle.getEndPortalLocation();
if(cen == null) {
battle.initiateRespawn();
cen = battle.getEndPortalLocation();
if(cen == null){
return false;
}
}
return true;
}
try {//executes 1e5 times within 76ms
Object battle = getInstance().getNMSManager().getEnderDragonBattle(world);
if(battle == null) return false;
Field k = battle.getClass().getDeclaredField("k");
k.setAccessible(true);
Object isAlive = k.get(battle);
if(!((boolean) isAlive)) return false;
Field p = battle.getClass().getDeclaredField("p");
p.setAccessible(true);
Object phase = p.get(battle);
if(phase != null) return false;
Field field = battle.getClass().getDeclaredField("o");
field.setAccessible(true);
Object BlockPosition = field.get(battle);
if(BlockPosition == null){
if (this.DragonBattle_e == null) this.DragonBattle_e = battle.getClass().getMethod("e");
this.DragonBattle_e.invoke(battle);
BlockPosition = field.get(battle);
if(BlockPosition == null) return false;
}
return true;
} catch (ReflectiveOperationException e) {
return false;
}
}
public boolean isRespawnRunning(final World world){
if(world == null) return false;
if(world.getEnvironment() != World.Environment.THE_END) return false;
if(Version.mcMainVersion >= 16){
DragonBattle battle = world.getEnderDragonBattle();
assert battle != null;
return battle.getRespawnPhase() != DragonBattle.RespawnPhase.NONE;
}
try {
Object battle = getInstance().getNMSManager().getEnderDragonBattle(world);
assert battle != null;
Field p = battle.getClass().getDeclaredField("p");
p.setAccessible(true);
Object phase = p.get(battle);
return phase != null;
} catch (ReflectiveOperationException e) {
e.printStackTrace();
return false;
}
}
public void refresh_respawn(final World world){
if(world == null) return;
if(world.getEnvironment() != World.Environment.THE_END) return;
if(Version.mcMainVersion >= 16){
DragonBattle battle = world.getEnderDragonBattle();
assert battle != null;
battle.initiateRespawn();
return;
}
try {
Object battle = getInstance().getNMSManager().getEnderDragonBattle(world);
assert battle != null;
if (this.DragonBattle_e == null) this.DragonBattle_e = battle.getClass().getMethod("e");
this.DragonBattle_e.invoke(battle);
} catch (ReflectiveOperationException e) {
e.printStackTrace();
}
}
private DragonRespawnResult initiateRespawn(final World world){
if(world == null) return DragonRespawnResult.world_not_found;
if(world.getEnvironment() != World.Environment.THE_END) return DragonRespawnResult.world_wrong_env;
if(Version.mcMainVersion >= 16){
DragonBattle battle = world.getEnderDragonBattle();
assert battle != null;
if(battle.getEnderDragon() != null) return DragonRespawnResult.dragon_has_existed;
if(battle.getRespawnPhase() != DragonBattle.RespawnPhase.NONE) return DragonRespawnResult.respawn_has_started;
Location cen = battle.getEndPortalLocation();
if(cen == null) {
battle.initiateRespawn();
cen = battle.getEndPortalLocation();
if(cen == null){
return DragonRespawnResult.world_unloaded;//也可尝试chunk.load()
}
}
placeEndCrystals(world,cen);
battle.initiateRespawn();
return DragonRespawnResult.success;
}
try {
Object battle = getInstance().getNMSManager().getEnderDragonBattle(world);
assert battle != null;
Field k = battle.getClass().getDeclaredField("k");
k.setAccessible(true);
Object isAlive = k.get(battle);
if(!((boolean) isAlive)) return DragonRespawnResult.dragon_has_existed;
Field p = battle.getClass().getDeclaredField("p");
p.setAccessible(true);
Object phase = p.get(battle);
if(phase != null) return DragonRespawnResult.respawn_has_started;
Field field = battle.getClass().getDeclaredField("o");
field.setAccessible(true);
Object BlockPosition = field.get(battle);
if(BlockPosition == null){
if (this.DragonBattle_e == null) this.DragonBattle_e = battle.getClass().getMethod("e");
this.DragonBattle_e.invoke(battle);
BlockPosition = field.get(battle);
if(BlockPosition == null) return DragonRespawnResult.world_unloaded;
}
if(this.getX == null) this.getX = BlockPosition.getClass().getMethod("getX");
if(this.getY == null) this.getY = BlockPosition.getClass().getMethod("getY");
if(this.getZ == null) this.getZ = BlockPosition.getClass().getMethod("getZ");
Location loc = new Location(world,(int)getX.invoke(BlockPosition),(int)this.getY.invoke(BlockPosition),(int)this.getZ.invoke(BlockPosition));
placeEndCrystals(world, loc);
if (this.DragonBattle_e == null) this.DragonBattle_e = battle.getClass().getMethod("e");
this.DragonBattle_e.invoke(battle);
return DragonRespawnResult.success;
} catch (ReflectiveOperationException e) {
return DragonRespawnResult.version_not_support;
}
}
private void placeEndCrystals(final World world,final Location cen){
cen.add(0.5,1,0.5);
for(int i = 0; i < 4; i++){
EnderCrystal crystal = (EnderCrystal) world.spawnEntity(cen.clone().add(nxt[i][0],0,nxt[i][1]), EntityType.ENDER_CRYSTAL);
if(Config.crystal_invulnerable) crystal.setInvulnerable(true);
crystal.setShowingBottom(false);
}
}
public enum DragonRespawnResult{
success,
world_not_found,
world_unloaded,
world_wrong_env,
respawn_has_started,
dragon_has_existed,
version_not_support;
public String getMessage(){
switch (this){
case success: return "Success";
case world_not_found: return "Can't find this world!";
case world_unloaded: return "The world_the_end is unloaded.";
case world_wrong_env: return "Respawn only can be called in the End.";
case respawn_has_started: return "The respawning has already started.";
case dragon_has_existed: return "There is already a dragon here.";
case version_not_support: return "Your server version (" + Version.getVersion() + ") is not supported!";
default: return "Unknown error!";
}
}
}
}
@@ -0,0 +1,76 @@
package pers.xanadu.enderdragon.manager;
import org.bukkit.Bukkit;
import org.bukkit.ChatColor;
import org.bukkit.entity.Entity;
import org.bukkit.entity.Player;
import org.bukkit.scoreboard.Scoreboard;
import org.bukkit.scoreboard.Team;
import pers.xanadu.enderdragon.util.Version;
import java.util.HashSet;
import java.util.Set;
import java.util.concurrent.ThreadLocalRandom;
public class GlowManager {
public static Set<Scoreboard> handled = new HashSet<>();
public static void reload(){
handled.clear();
}
public static void setScoreBoard(Player p){
Scoreboard board = p.getScoreboard();
if(handled.contains(board)) return;
ChatColor[] colors = ChatColor.values();
for(ChatColor color : colors){
String name = "ed-"+color.name();
if(board.getTeam(name)==null) board.registerNewTeam(name);
Team team = board.getTeam(name);
assert team != null;
if(Version.mcMainVersion >= 13) team.setColor(color);
else team.setPrefix(color.toString());
}
handled.add(board);
}
public static void addUUID(String uuid,String color){
Set<Team> teams = new HashSet<>();
Bukkit.getOnlinePlayers().forEach(player -> {
GlowManager.setScoreBoard(player);
Team team = player.getScoreboard().getTeam("ed-"+color.toUpperCase());
teams.add(team);
});
teams.forEach(team->{
team.addEntry(uuid);
});
}
public static void setGlowingColor(Entity entity, ChatColor color){
Set<Team> teams = new HashSet<>();
Bukkit.getOnlinePlayers().forEach(player -> {
GlowManager.setScoreBoard(player);
Team team = player.getScoreboard().getTeam("ed-"+color.name());
teams.add(team);
});
teams.forEach(team->{
team.addEntry(entity.getUniqueId().toString());
entity.setGlowing(true);
});
}
public static ChatColor getGlowColor(String str){
ChatColor chatColor;
if(str.equals("RANDOM")) chatColor = randomColor();
else chatColor = ChatColor.valueOf(str);
return chatColor;
}
public static ChatColor getGlowColor(GlowColor glowColor){
if(glowColor == GlowColor.NONE) return null;
if(glowColor == GlowColor.RANDOM) return randomColor();
return ChatColor.valueOf(glowColor.name());
}
public static ChatColor randomColor(){
return ChatColor.values()[ThreadLocalRandom.current().nextInt(16)];
}
public enum GlowColor{
AQUA,BLACK,BLUE,DARK_AQUA,DARK_BLUE,DARK_GRAY,DARK_GREEN,DARK_PURPLE,DARK_RED,GOLD,GRAY,GREEN,LIGHT_PURPLE,RED,WHITE,YELLOW,
NONE,RANDOM
}
}
@@ -0,0 +1,105 @@
package pers.xanadu.enderdragon.manager;
import groovy.lang.*;
import groovy.util.GroovyScriptEngine;
import io.netty.util.internal.ConcurrentSet;
import org.bukkit.entity.Player;
import org.codehaus.groovy.control.CompilerConfiguration;
import org.codehaus.groovy.control.customizers.ImportCustomizer;
import pers.xanadu.enderdragon.config.Config;
import pers.xanadu.enderdragon.script.Events;
import pers.xanadu.enderdragon.script.tool.ScriptCommand;
import java.io.File;
import java.io.InputStream;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.concurrent.ConcurrentHashMap;
import static pers.xanadu.enderdragon.EnderDragon.plugin;
import static pers.xanadu.enderdragon.config.Lang.error;
import static pers.xanadu.enderdragon.config.Lang.info;
public class GroovyManager {
private static final File baseDir = new File(plugin.getDataFolder(),"expansion/groovy");
private static final ConcurrentHashMap<String, Script> script_mp = new ConcurrentHashMap<>();
public static final ConcurrentSet<Events<?>> event_set = new ConcurrentSet<>();
public static final ConcurrentSet<ScriptCommand> cmd_set = new ConcurrentSet<>();
private static final GroovyScriptEngine engine;
private static final CompilerConfiguration compilerConfig;
private static final String lib;
static {
try {
compilerConfig = new CompilerConfiguration();
ImportCustomizer importCustomizer = new ImportCustomizer();
importCustomizer.addImport("Bukkit","org.bukkit.Bukkit");
importCustomizer.addImport("Player","org.bukkit.entity.Player");
importCustomizer.addImport("Events","pers.xanadu.enderdragon.script.Events");
importCustomizer.addImport("Command","pers.xanadu.enderdragon.script.tool.ScriptCommand");
importCustomizer.addStaticImport("plugin","pers.xanadu.enderdragon.EnderDragon","plugin");
compilerConfig.addCompilationCustomizers(importCustomizer);
GroovyClassLoader classLoader = new GroovyClassLoader(GroovyManager.class.getClassLoader(),compilerConfig);
engine = new GroovyScriptEngine(new URL[]{baseDir.toURI().toURL()}, classLoader);
InputStream inputStream = plugin.getResource("script/lib.groovy");
lib = Config.convertInputStreamToString(inputStream);
} catch (MalformedURLException e) {
throw new RuntimeException(e);
}
}
public static void reload() {
event_set.forEach(Events::unregister);
event_set.clear();
cmd_set.forEach(ScriptCommand::unregister);
cmd_set.clear();
script_mp.clear();
loadAllScripts(baseDir);
script_mp.forEach((key,script)->invoke(key,"enable"));
}
public static Object eval(String expression, Player player){
Binding binding = new Binding();
binding.setVariable("player",player);
binding.setVariable("itemStack",player.getItemInHand());
binding.setVariable("world",player.getWorld());
GroovyShell shell = new GroovyShell(GroovyManager.class.getClassLoader(),binding,compilerConfig);
//Bukkit.broadcastMessage(lib);
return shell.evaluate(lib+expression);
}
public static Object invoke(String fileName, String function, Object... args) {
Script script = GroovyManager.script_mp.get(fileName);
if (script != null) {
try {
return script.invokeMethod(function, args);
} catch (Exception e) {
e.printStackTrace();
}
}
return null;
}
private static void loadAllScripts(File folder) {
if (folder.isDirectory()) {
File[] subFiles = folder.listFiles();
if(subFiles == null) return;
for (File file : subFiles) {
if(file.isDirectory()) loadAllScripts(file);
else if(file.getName().endsWith(".groovy")) loadGroovyFile(file);
}
}
}
private static void loadGroovyFile(File file) {
String key = file.getPath().substring(37);
try {
Script script = engine.createScript(key, new Binding());
//script.evaluate("import org.bukkit.Bukkit");
script_mp.put(key, script);
info("Successfully load script: "+key);
} catch (Exception e) {
error("Failed to load script: "+key);
e.printStackTrace();
}
}
}
@@ -0,0 +1,76 @@
package pers.xanadu.enderdragon.manager;
import org.bukkit.configuration.ConfigurationSection;
import org.bukkit.configuration.file.FileConfiguration;
import org.bukkit.configuration.file.YamlConfiguration;
import org.bukkit.entity.Player;
import org.bukkit.scheduler.BukkitRunnable;
import pers.xanadu.enderdragon.config.Lang;
import pers.xanadu.enderdragon.gui.GUIWrapper;
import java.io.File;
import java.util.HashMap;
import java.util.Iterator;
import static pers.xanadu.enderdragon.EnderDragon.plugin;
public class GuiManager {
private static HashMap<String, GUIWrapper> f = new HashMap<>();
public static void loadGui(){
new BukkitRunnable(){
@Override
public void run(){
File folder = new File(plugin.getDataFolder(),"gui");
if(!folder.exists()) return;
File[] files = folder.listFiles();
if(files == null) return;
for(File file : files){
if(!file.getName().endsWith(".yml")) continue;
Lang.info(Lang.plugin_read_file + file.getName());
FileConfiguration fileConfiguration = YamlConfiguration.loadConfiguration(file);
Iterator it = fileConfiguration.getKeys(false).iterator();
while (it.hasNext()){
String name = (String) it.next();
ConfigurationSection section = fileConfiguration.getConfigurationSection(name);
GUIWrapper guiWrapper = new GUIWrapper(section);
f.put(name, guiWrapper);
}
}
}
}.runTaskAsynchronously(plugin);
}
public static void disable(){
f.clear();
}
public static void openGui(Player player, String name, boolean editor) {
if (!f.containsKey(name)) {
Lang.sendFeedback(player,Lang.gui_not_found);
return;
}
player.openInventory(new GUIWrapper(f.get(name),name,editor).current());
}
public static void openGui(Player player,String style,String key, boolean editor){
if (!f.containsKey(style)) {
Lang.sendFeedback(player,Lang.gui_not_found);
return;
}
player.openInventory(new GUIWrapper(f.get(style),key,editor).current());
}
@Deprecated
public static void openGui(Player player, String name) {
if (!f.containsKey(name)) {
Lang.sendFeedback(player,Lang.gui_not_found);
return;
}
player.openInventory(new GUIWrapper(f.get(name),name,false).current());
}
@Deprecated
public static void openGui(Player player,String style,String key){
if (!f.containsKey(style)) {
Lang.sendFeedback(player,Lang.gui_not_found);
return;
}
player.openInventory(new GUIWrapper(f.get(style),key,false).current());
}
}
@@ -0,0 +1,431 @@
package pers.xanadu.enderdragon.manager;
import org.bukkit.Material;
import org.bukkit.attribute.Attribute;
import org.bukkit.attribute.AttributeModifier;
import org.bukkit.configuration.ConfigurationSection;
import org.bukkit.configuration.file.YamlConfiguration;
import org.bukkit.enchantments.Enchantment;
import org.bukkit.inventory.ItemFlag;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.ItemMeta;
import org.bukkit.inventory.meta.Repairable;
import org.bukkit.persistence.PersistentDataContainer;
import pers.xanadu.enderdragon.EnderDragon;
import pers.xanadu.enderdragon.config.Config;
import pers.xanadu.enderdragon.reward.Reward;
import pers.xanadu.enderdragon.reward.Chance;
import pers.xanadu.enderdragon.util.Version;
import java.util.*;
public class ItemManager {
public static String write(Reward reward){
Chance chance = reward.getChance();
return write(reward.getItem(),chance.getValue(),chance.getStr(),reward.getName());
}
public static String write(ItemStack item,double value,String str,String name){
YamlConfiguration yaml = new YamlConfiguration();
if(Config.advanced_setting_backslash_split_reward) yaml.options().pathSeparator('\\');
if(name == null){
ItemMeta meta = item.getItemMeta();
if(meta != null) {
String displayName = meta.getDisplayName();
if("".equals(displayName) || displayName == null){
name = item.getType().name().toLowerCase() + "(" + TaskManager.getCurrentTimeWithSpecialFormat() + ")";
}
else name = meta.getDisplayName();
}
else name = item.getType().name().toLowerCase() + "(" + TaskManager.getCurrentTimeWithSpecialFormat() + ")";
}
ConfigurationSection section = yaml.createSection(name);
switch(Config.item_format_reward){
case "nbt" : {
section.set("data_type","nbt");
section.set("data",EnderDragon.getInstance().getNMSManager().getNBT(item));
break;
}
case "advanced" : {
section.set("data_type","advanced");
ConfigurationSection section_data = section.createSection("data");
//type
String type = item.getType().name();
section_data.set("type",type);
if("AIR".equals(type)) break;
//amount
int amount = item.getAmount();
section_data.set("amount",amount);
//damage
int damage = item.getDurability();
if(damage != 0) section_data.set("damage",damage);
ItemMeta meta = item.getItemMeta();
if(meta == null) break;
//DisplayName
String display_name = meta.getDisplayName();
if(!"".equals(display_name)) section_data.set("display_name",display_name);
//LocalizedName
if(meta.hasLocalizedName()){
section_data.set("localized_name",meta.getLocalizedName());
}
//lore
List<String> lores = meta.getLore();
if(lores != null) section_data.set("lore",lores);
//Enchantments
if(meta.hasEnchants()){
ConfigurationSection enchants = section_data.createSection("enchants");
Map<Enchantment,Integer> mp = meta.getEnchants();
mp.forEach((enchantment,level) -> enchants.set(enchantment.getName(),level));
}
if(Version.mcMainVersion>=14 || "v1_13_R2".equals(Version.getVersion())){
//AttributeModifiers
if(meta.hasAttributeModifiers()){
ConfigurationSection attributes = section_data.createSection("AttributeModifiers");
meta.getAttributeModifiers().forEach((attribute,modifier)->{
attributes.set(attribute.name(),modifier);
});
}
}
if(Version.mcMainVersion>=14){
//CustomModelData
if(meta.hasCustomModelData()) {
section_data.set("CustomModelData",meta.getCustomModelData());//int
}
//PersistentDataContainer
PersistentDataContainer dataContainer = meta.getPersistentDataContainer();
if(!dataContainer.isEmpty()){
ConfigurationSection dataContainer_section = section_data.createSection("PersistentDataContainer");
String cpd = EnderDragon.getInstance().getNMSManager().PDCtoString(dataContainer);
dataContainer_section.set("data_type","nbt");
dataContainer_section.set("data",cpd);
}
}
//RepairCost
if(meta instanceof Repairable){
Repairable repairable = (Repairable) meta;
section_data.set("RepairCost",repairable.getRepairCost());
}
//ItemFlags
Set<ItemFlag> flags = meta.getItemFlags();
if(!flags.isEmpty()){
List<String> list = new ArrayList<>();
flags.forEach(flag ->{
list.add(flag.name());
});
section_data.set("ItemFlags",list);
}
//Unbreakable
section_data.set("unbreakable",meta.isUnbreakable());
//internal
Object cpd = EnderDragon.getInstance().getNMSManager().getCPD(item);
Map<String,Object> mp = EnderDragon.getInstance().getNMSManager().cpdToMap(cpd);
if(mp.containsKey("tag")){
cpd = mp.get("tag");
mp = EnderDragon.getInstance().getNMSManager().cpdToMap(cpd);
mp.remove("Damage");
if(mp.containsKey("display")){
Object display = mp.get("display");
Map<String,Object> display_mp = EnderDragon.getInstance().getNMSManager().cpdToMap(display);
display_mp.remove("Name");
display_mp.remove("LocName");
display_mp.remove("Lore");
Object new_display = EnderDragon.getInstance().getNMSManager().getNBTTagCompound(display_mp);
mp.put("display",new_display);
}
//mp.remove("display");//Name, LocName, Lore, color
mp.remove("Enchantments");
mp.remove("AttributeModifiers");
mp.remove("CustomModelData");
mp.remove("PublicBukkitValues");//PersistentDataContainer
mp.remove("RepairCost");
mp.remove("HideFlags");//ItemFlags
mp.remove("Unbreakable");
//CanDestroy, CanPlaceOn
Object new_cpd = EnderDragon.getInstance().getNMSManager().getNBTTagCompound(mp);
ConfigurationSection internal = section_data.createSection("internal");
internal.set("data_type","nbt");
internal.set("data",new_cpd.toString());
}
// Map<String,Object> mp = EnderDragon.getInstance().getNMSManager().getUnhandledTags(meta);
// if(mp != null){
// ConfigurationSection internal = section_data.createSection("internal");
// saveUnhandledTags(internal,mp);
// }
break;
}
default : {
section.set("data_type","default");
section.set("data", item);
}
}
ConfigurationSection drop_section = section.createSection("drop_chance");
drop_section.set("value",value);
drop_section.set("format",str);
return yaml.saveToString();
}
public static Reward readAsReward(ConfigurationSection section){
Set<String> strings = section.getKeys(false);
String name = strings.iterator().next();
ConfigurationSection section0 = section.getConfigurationSection(name);
if(section0 == null) return null;
String data_type = section0.getString("data_type");
//data_type may be null
ItemStack item;
if("nbt".equals(data_type)) item = readFromNBT(section0,"data");
else if("advanced".equals(data_type)) item = readFromAdvData(section0, "data");
else item = readFromBukkit(section0,"data");
ConfigurationSection chance_section = section0.getConfigurationSection("drop_chance");
if(chance_section == null) return null;
double d0 = chance_section.getDouble("value");
String str = chance_section.getString("format");
return new Reward(item,new Chance(d0, str));
}
public static ItemStack readFromAdvData(ConfigurationSection section, String path){
ConfigurationSection data = section.getConfigurationSection(path);
if(data == null) return new ItemStack(Material.AIR);
String type = data.getString("type");
if(type == null || "AIR".equals(type)) return new ItemStack(Material.AIR);
int amount = data.getInt("amount");
Material material = Material.getMaterial(type);
if(material == null) return new ItemStack(Material.AIR);
ItemStack item = new ItemStack(material,amount);
//internal
if(data.contains("internal")){
ConfigurationSection internal_section = data.getConfigurationSection("internal");
if(internal_section!=null){
if("nbt".equals(internal_section.getString("data_type"))){
String nbt = internal_section.getString("data");
Object cpd = EnderDragon.getInstance().getNMSManager().getCPD(nbt);
Map<String,Object> mp_tag = new HashMap<>();
mp_tag.put("tag",cpd);
Object full_cpd = EnderDragon.getInstance().getNMSManager().getNBTTagCompound(mp_tag);
item = EnderDragon.getInstance().getNMSManager().mergeItemCPD(item,full_cpd);
}
// else{
// Map<String,Object> mp = getUnhandledTags(internal_section);
// EnderDragon.getInstance().getNMSManager().setUnhandledTags(meta,mp);
// }
// Map<String,Object> mp = new HashMap<>();
// internal_section.getKeys(false).forEach(key->{
// Object obj = internal_section.get(key);//obj instanceof String
// Object nbt_base = EnderDragon.getInstance().getNMSItemManager().readAsNBTBase((String) obj);
// mp.put(key,nbt_base);
// });
// Map<String,Object> mp = getUnhandledTags(internal_section);
// NBTTagCompound cpd = getNBTTagCompound(mp);
// net.minecraft.world.item.ItemStack ei = CraftItemStack.asNMSCopy(item);
// ei.c(cpd);
// item = CraftItemStack.asBukkitCopy(ei);
//EnderDragon.getInstance().getNMSManager().setUnhandledTags(meta,mp);
}
}
//damage
if(data.contains("damage")){
int damage = data.getInt("damage");
item.setDurability((short) damage);
}
ItemMeta meta = item.getItemMeta();
if(meta == null) return item;
//DisplayName
String display_name = data.getString("display_name");
if(display_name != null) meta.setDisplayName(display_name);
//LocalizedName
if(data.contains("localized_name")){
String LocalizedName = data.getString("localized_name");
if(LocalizedName != null) meta.setLocalizedName(LocalizedName);
}
//lore
if(data.contains("lore")){
List<String> lores = data.getStringList("lore");
if(!lores.isEmpty()) meta.setLore(lores);
}
//Enchantments
if(data.contains("enchants")){
ConfigurationSection enchants = data.getConfigurationSection("enchants");
if(enchants != null){
//Map<Enchantment,Integer> mp = new HashMap<>();
enchants.getKeys(false).forEach(key->{
Enchantment enchantment = Enchantment.getByName(key);
int level = enchants.getInt(key);
if(enchantment != null && level>0){
meta.addEnchant(enchantment,level,true);
}
});
}
}
//CustomModelData
if(data.contains("CustomModelData")){
int CustomModelData = data.getInt("CustomModelData");
meta.setCustomModelData(CustomModelData);
}
//AttributeModifiers
if(data.contains("AttributeModifiers")){
ConfigurationSection attributes = data.getConfigurationSection("AttributeModifiers");
if(attributes != null){
attributes.getKeys(false).forEach(name->{
Attribute attribute = Attribute.valueOf(name);
AttributeModifier modifier = (AttributeModifier) attributes.get(name);
if(modifier != null){
meta.addAttributeModifier(attribute,modifier);
}
});
}
}
//RepairCost
if(data.contains("RepairCost")){
int cost = data.getInt("RepairCost");
if(meta instanceof Repairable){
((Repairable)meta).setRepairCost(cost);
}
}
//ItemFlags
if(data.contains("ItemFlags")){
List<String> names = data.getStringList("ItemFlags");
names.forEach(name->meta.addItemFlags(ItemFlag.valueOf(name)));
}
//Unbreakable
if(data.contains("unbreakable") && data.getBoolean("unbreakable")) meta.setUnbreakable(true);
//PersistentDataContainer
if(data.contains("PersistentDataContainer")){
ConfigurationSection dataContainer_section = data.getConfigurationSection("PersistentDataContainer");
if(dataContainer_section != null){
if("nbt".equals(dataContainer_section.getString("data_type"))){
String nbt = dataContainer_section.getString("data");
Object cpd = EnderDragon.getInstance().getNMSManager().getCPD(nbt);
PersistentDataContainer container = meta.getPersistentDataContainer();
EnderDragon.getInstance().getNMSManager().setPersistentDataContainer(container, cpd);
}
}
}
item.setItemMeta(meta);
return item;
}
public static ItemStack readFromNBT(ConfigurationSection section, String path){
String nbt = section.getString(path);
if (nbt == null) return new ItemStack(Material.AIR);
return EnderDragon.getInstance().getNMSItemManager().readAsItem(nbt);
}
public static ItemStack readFromBukkit(ConfigurationSection section, String path){
String nbt = section.getString(path);
if (nbt == null) return new ItemStack(Material.AIR);
return section.getItemStack(path);
}
public static ItemStack readFromString(String str){
YamlConfiguration yml = new YamlConfiguration();
if(Config.advanced_setting_backslash_split_reward) yml.options().pathSeparator('\\');
yml.set("test",str);
return yml.getItemStack("test");
}
public static void addLoreFront(ItemStack item, String lore){
ItemMeta meta = item.getItemMeta();
if(meta != null) {
List<String> lores = meta.getLore();
if (lores != null) {
lores.add(0,lore);
meta.setLore(lores);
}
else {
meta.setLore(Collections.singletonList(lore));
}
item.setItemMeta(meta);
}
}
public static void addLoreBack(ItemStack item, String lore){
ItemMeta meta = item.getItemMeta();
if(meta != null) {
List<String> lores = meta.getLore();
if (lores != null) {
lores.add(lore);
meta.setLore(lores);
}
else {
meta.setLore(Collections.singletonList(lore));
}
item.setItemMeta(meta);
}
}
public static boolean isEmpty(ItemStack item){
if(item == null) return true;
if(item.getType() == Material.AIR) return true;
return false;
}
private static void saveUnhandledTags(ConfigurationSection section, Map<String,Object> mp){
mp.forEach((k,v)->{
//Bukkit.broadcastMessage(k+": "+v.getClass().toString());
if(v instanceof Map){
saveUnhandledTags(section.createSection(k), (Map<String, Object>) v);
}
else section.set(k,v.toString());
});
}
/**
private static void saveUnhandledTags(ConfigurationSection section, Map<String,Object> mp){
mp.forEach((k,v)->{
Object obj = v;
//Bukkit.broadcastMessage(obj.getClass().toString());
try{
obj = EnderDragon.getInstance().getNMSItemManager().parseNBT(v);
}catch (Throwable ignored){
}
if(obj instanceof Map){
saveUnhandledTags(section.createSection(k), (Map<String, Object>) obj);
}
else section.set(k,obj);
});
}**/
private static Map<String, Object> getUnhandledTags(ConfigurationSection section){
Map<String,Object> res = new HashMap<>();
section.getKeys(false).forEach(key->{
Object obj = section.get(key);
if(obj instanceof ConfigurationSection){
ConfigurationSection subSection = section.getConfigurationSection(key);
if(subSection != null){
obj = getUnhandledTags(subSection);
// Object mp = getUnhandledTags(subSection);
// Bukkit.getLogger().info(mp.getClass().toString());
// try{
// obj = EnderDragon.getInstance().getNMSItemManager().getNBTBase(mp);
// }catch (Throwable throwable){
//
// }
}
}
else obj = EnderDragon.getInstance().getNMSManager().getCPD((String) obj);
//else obj = EnderDragon.getInstance().getNMSItemManager().readAsNBTBase((String) obj);
res.put(key,obj);
});
return res;
}
// private static Object dfs(ConfigurationSection section){
// section.getKeys(false).forEach(key->{
// Object obj = section.get(key);
// if(obj instanceof ConfigurationSection){
// ConfigurationSection subSection = section.getConfigurationSection(key);
// if(subSection != null) obj = dfs(subSection);
// }
// else obj = EnderDragon.getInstance().getNMSItemManager().readAsNBTBase((String) obj);
//
// });
// return
// }
// //internal
// Map<String,Object> mp = EnderDragon.getInstance().getNMSManager().getUnhandledTags(meta);
// if(mp != null){
// ConfigurationSection internal = section_data.createSection("internal");
// mp.forEach((k,v)->{
// Object obj = EnderDragon.getInstance().getNMSItemManager().parseNBT(v);
//
// if(obj instanceof Map) obj = obj.toString();
// else if(obj instanceof List) obj = obj.toString();
//
// internal.set(k,obj);
// });
// }
}
@@ -0,0 +1,133 @@
package pers.xanadu.enderdragon.manager;
import org.bukkit.Bukkit;
import org.bukkit.configuration.InvalidConfigurationException;
import org.bukkit.configuration.file.FileConfiguration;
import org.bukkit.configuration.file.YamlConfiguration;
import org.bukkit.inventory.ItemStack;
import org.jetbrains.annotations.NotNull;
import pers.xanadu.enderdragon.config.Config;
import pers.xanadu.enderdragon.config.Lang;
import pers.xanadu.enderdragon.reward.Reward;
import pers.xanadu.enderdragon.reward.Chance;
import pers.xanadu.enderdragon.util.MyDragon;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.List;
import java.util.logging.Level;
import static pers.xanadu.enderdragon.EnderDragon.*;
public class RewardManager {
public static void reload(){
for(MyDragon dragon : DragonManager.dragons){
dragon.datum.clear();
File file = getRewardFile(dragon.unique_name);
if(file == null) return;
FileConfiguration data = loadConfiguration(file);
String path = "list";
List<String> list = data.getStringList(path);
// if list == null ?
for(String str : list){
YamlConfiguration yml = new YamlConfiguration();
if(Config.advanced_setting_backslash_split_reward) yml.options().pathSeparator('\\');
try{
yml.loadFromString(str);
Reward reward = ItemManager.readAsReward(yml);
dragon.datum.add(reward);
}catch (InvalidConfigurationException e){
Lang.error(Lang.plugin_item_read_error + str);
}
}
}
}
public static void addItem(String key,Reward reward){
addItem(key,reward.getItem(),reward.getChance());
}
public static void addItem(String key, ItemStack item, Chance chance){
MyDragon dragon = DragonManager.mp.get(key);
if(dragon == null) return;
File file = getRewardFile(dragon.unique_name);
if(file == null) return;
FileConfiguration data = loadConfiguration(file);
String path = "list";
List<String> list = data.getStringList(path);
Reward reward = new Reward(item,chance);
list.add(reward.toString());
data.set(path,list);
try {
data.save(file);
} catch (IOException e) {
throw new RuntimeException(e);
}
dragon.datum.add(reward);
}
public static void clearItem(String key){
MyDragon dragon = DragonManager.mp.get(key);
if(dragon == null) return;
File file = getRewardFile(dragon.unique_name);
if(file == null) return;
FileConfiguration data = loadConfiguration(file);
String path = "list";
data.set(path,"");
try {
data.save(file);
} catch (IOException e) {
throw new RuntimeException(e);
}
dragon.datum.clear();
}
public static boolean removeItem(String key,int idx){
MyDragon dragon = DragonManager.mp.get(key);
if(dragon == null) return false;
File file = getRewardFile(dragon.unique_name);
if(file == null) return false;
FileConfiguration data = loadConfiguration(file);
String path = "list";
List<String> list = data.getStringList(path);
try{
list.remove(idx);
data.set(path,list);
data.save(file);
dragon.datum.remove(idx);
return true;
}catch (IndexOutOfBoundsException e){
Lang.error("Index out of bound!");
}catch (IOException e) {
throw new RuntimeException(e);
}
return false;
}
private static File getRewardFile(String key){
String file_path = "reward/" + key + ".yml";
File file = new File(plugin.getDataFolder(),file_path);
if(!file.exists()) {
try{
YamlConfiguration yml = new YamlConfiguration();
if(Config.advanced_setting_backslash_split_reward) yml.options().pathSeparator('\\');
yml.set("version","2.1.0");
yml.set("list","");
yml.save(file);
}catch (IOException e){
Lang.error("Not Found "+file_path+" ,skipped it.");
return null;
}
}
return new File(plugin.getDataFolder(),file_path);
}
private static YamlConfiguration loadConfiguration(@NotNull File file) {
YamlConfiguration config = new YamlConfiguration();
if(Config.advanced_setting_backslash_split_reward) config.options().pathSeparator('\\');
try {
config.load(file);
} catch (FileNotFoundException ex) {
} catch (IOException | InvalidConfigurationException ex) {
Bukkit.getLogger().log(Level.SEVERE, "Cannot load " + file, ex);
}
return config;
}
}
@@ -0,0 +1,81 @@
package pers.xanadu.enderdragon.manager;
import org.bukkit.Location;
import org.bukkit.World;
import org.bukkit.block.Block;
import org.bukkit.entity.*;
import pers.xanadu.enderdragon.util.MathUtil;
import java.util.concurrent.ThreadLocalRandom;
public class SkillManager {
//离开祭坛
//向指定位置发射末影龙火球
//在玩家附近召唤愤怒的末影人
//立刻飞向玩家并近战攻击
//在当前位置吐龙息
public static void leaveEndPortal(final EnderDragon dragon){
dragon.setPhase(EnderDragon.Phase.LEAVE_PORTAL);
}
public static void launchDragonFireball(final EnderDragon dragon, final Location target){
Location loc1 = dragon.getLocation();
World world = loc1.getWorld();
if(world == null) return;
double dx = target.getX() - loc1.getX();
double dy = target.getY() - loc1.getY();
double dz = target.getZ() - loc1.getZ();
double yaw = Math.toDegrees(-Math.atan2(dx, dz));
double horizontalDistance = Math.sqrt(dx * dx + dz * dz);
double pitch = Math.toDegrees(-Math.atan2(dy, horizontalDistance));
yaw = normalizeAngle(yaw, -180, 180);
pitch = normalizeAngle(pitch, -90, 90);
Location loc = new Location(world,loc1.getX(),loc1.getY(),loc1.getZ(), (float) yaw, (float) pitch);
Projectile projectile = world.spawn(loc, DragonFireball.class);
projectile.setShooter(dragon);
//Projectile projectile2 = loc1.getWorld().spawn(loc, DragonFireball.class);
//projectile2.setShooter(dragon);
//projectile2.setVelocity(new Vector(-dx,-dy,-dz).normalize());
}
public static void callEnderManReinforce(final Player p,int num){
if(num <= 0) return;
ThreadLocalRandom random = ThreadLocalRandom.current();
Location loc = p.getLocation();
World world = loc.getWorld();
assert world != null;
int i = MathUtil.floor(loc.getX());
int j = MathUtil.floor(loc.getY());
int k = MathUtil.floor(loc.getZ());
int i1=10,j1,k1=10;
for (int l = 0; l < 50; l++) {
i1 = i + (random.nextInt(7, 41) * random.nextInt(-1, 2));
j1 = j + (random.nextInt(7, 41) * random.nextInt(-1, 2));
k1 = k + (random.nextInt(7, 41) * random.nextInt(-1, 2));
Block block = world.getBlockAt(i1,j1-1,k1);
if(block.isLiquid() || block.isEmpty()) continue;
if(!world.getBlockAt(i1,j1,k1).isEmpty()) continue;
if(!world.getBlockAt(i1,j1+1,k1).isEmpty()) continue;
if(!world.getBlockAt(i1,j1+2,k1).isEmpty()) continue;
Enderman enderman = (Enderman) world.spawnEntity(new Location(world,i1,j1,k1),EntityType.ENDERMAN);
enderman.setTarget(p);
--num;
if(num == 0) return;
}
loc = world.getHighestBlockAt(i1,k1).getLocation().add(0,1,0);
while (num>0){
--num;
Enderman enderman = (Enderman) world.spawnEntity(loc,EntityType.ENDERMAN);
enderman.setTarget(p);
}
}
private static double normalizeAngle(double angle, double min, double max) {
if (angle < min) {
angle = min;
} else if (angle > max) {
angle = max;
}
return angle;
}
}
@@ -0,0 +1,103 @@
package pers.xanadu.enderdragon.manager;
import org.bukkit.configuration.ConfigurationSection;
import pers.xanadu.enderdragon.config.Lang;
import pers.xanadu.enderdragon.task.DragonRespawnRunnable;
import pers.xanadu.enderdragon.task.type.*;
import pers.xanadu.enderdragon.task.Task;
import pers.xanadu.enderdragon.task.TaskType;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.format.DateTimeFormatter;
import java.time.format.DateTimeParseException;
import java.util.Date;
import java.util.concurrent.ConcurrentHashMap;
import static pers.xanadu.enderdragon.EnderDragon.*;
public class TaskManager {
public static final ConcurrentHashMap<String, DragonRespawnRunnable> mp = new ConcurrentHashMap<>();
private static final DateTimeFormatter RoundTimeFormat_hm = DateTimeFormatter.ofPattern("HH:mm");
private static final DateTimeFormatter RoundTimeFormat_all = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm");
public static Task parse(String unique_name,String world_name,String string){
String[] str = string.split(":",2);
TaskType taskType = TaskType.getByName(str[0]);
switch (taskType){
case minute : {
return new Minute(TaskType.minute,unique_name,world_name,str[1]);
}
case hour : {
return new Hour(TaskType.hour,unique_name,world_name,str[1]);
}
case day : {
return new Day(TaskType.day,unique_name,world_name,str[1]);
}
case week : {
return new Week(TaskType.week,unique_name,world_name,str[1]);
}
case month : {
return new Month(TaskType.month,unique_name,world_name,str[1]);
}
case year : {
return new Year(TaskType.year,unique_name,world_name,str[1]);
}
default : {
return null;
}
}
}
public static void reload(){
mp.forEach((key,runnable)->runnable.cancel());
mp.clear();
ConfigurationSection section = plugin.getConfig().getConfigurationSection("auto_respawn");
if(section==null) return;
int cnt = 0;
for (String key : section.getKeys(false)) {
ConfigurationSection sub = section.getConfigurationSection(key);
if(sub == null) continue;
boolean enable = sub.getBoolean("enable");
String world_name = sub.getString("world_name");
String task_string = sub.getString("respawn_time");
if(!enable || task_string == null || world_name == null) continue;
DragonRespawnRunnable runnable = new DragonRespawnRunnable(parse(key,world_name,task_string));
runnable.start();
mp.put(key,runnable);
++cnt;
}
Lang.info(String.format("%d auto_respawn task(s) started to run...",cnt));
}
public static LocalTime getRoundTime(String str){
try {
return LocalTime.parse(str, RoundTimeFormat_hm);
}catch (DateTimeParseException e){
Lang.error("\"respawn_time\" in config.yml error!The format of time should be HH:mm.");
}
return null;
}
public static String getRoundTimeStr(LocalDateTime time){
return time.format(RoundTimeFormat_all);
}
public static LocalDateTime getLocalDateTime(String str){
if(isValidTime(str)) return LocalDateTime.parse(str, RoundTimeFormat_all);
return null;
}
public static boolean isValidTime(String str){
SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm");
try{
df.parse(str);
} catch (ParseException e) {
Lang.error("\"next_respawn_time\" in data.yml error!The format of time should be HH:mm.");
return false;
}
return true;
}
public static String getCurrentTimeWithSpecialFormat(){
SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HHmmss");//这里的∶是特殊字符
return df.format(new Date());
}
}
@@ -0,0 +1,76 @@
package pers.xanadu.enderdragon.manager;
import org.bukkit.configuration.ConfigurationSection;
import org.bukkit.configuration.file.FileConfiguration;
import org.bukkit.configuration.file.YamlConfiguration;
import pers.xanadu.enderdragon.config.Lang;
import pers.xanadu.enderdragon.task.DragonRespawnTimer;
import java.io.File;
import java.io.IOException;
import java.util.HashMap;
import static pers.xanadu.enderdragon.EnderDragon.plugin;
public class TimerManager {
private static final HashMap<String, DragonRespawnTimer> mp = new HashMap<>();
public static void enable(){
File file = new File(plugin.getDataFolder(),"respawn_cd.yml");
if(file.exists()){
FileConfiguration fc = YamlConfiguration.loadConfiguration(file);
ConfigurationSection section = fc.getConfigurationSection("respawn_cd");
if(section == null) return;
section.getKeys(false).forEach(name->{
int set_time = section.getInt(name+".setTime");
int rest_time = section.getInt(name+".remainTime");
if(set_time>0){
boolean run = section.getBoolean(name+".isRunning");
DragonRespawnTimer timer = new DragonRespawnTimer(name,set_time,rest_time);
if(run) timer.run();
TimerManager.mp.put(name,timer);
}
});
}
}
public static void save(){
YamlConfiguration yml = new YamlConfiguration();
char split = yml.options().pathSeparator();
mp.forEach((k,v)->{
ConfigurationSection section = yml.createSection("respawn_cd"+split+k);
if(v.getRestTime()>0){
//section.set("world_name",k);
section.set("setTime",v.getSetTime());
section.set("remainTime",v.getRestTime());
section.set("isRunning",v.isRunning());
}
});
try{
yml.save(new File(plugin.getDataFolder(),"respawn_cd.yml"));
}catch (IOException e){
Lang.error("Failed to save respawn_cd.yml!");
}
}
public static void startTimer(String world_name){
DragonRespawnTimer timer = mp.get(world_name);
if(timer != null){
timer.run();
}
}
public static void setTimer(String world_name, DragonRespawnTimer timer){
DragonRespawnTimer timer_old = mp.get(world_name);
if(timer_old != null) timer_old.del();
mp.put(world_name,timer);
}
public static DragonRespawnTimer getTimer(String world_name){
return mp.get(world_name);
}
public static void removeTimer(String world_name){
DragonRespawnTimer timer_old = mp.get(world_name);
if(timer_old != null) timer_old.del();
mp.remove(world_name);
}
public static void removeAll(){
mp.values().forEach(DragonRespawnTimer::del);
mp.clear();
}
}
@@ -0,0 +1,196 @@
package pers.xanadu.enderdragon.manager;
import org.bukkit.Bukkit;
import org.bukkit.Location;
import org.bukkit.World;
import org.bukkit.entity.EnderDragon;
import org.bukkit.entity.Entity;
import pers.xanadu.enderdragon.config.Lang;
import pers.xanadu.enderdragon.util.Version;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import static java.lang.Math.sqrt;
import static pers.xanadu.enderdragon.EnderDragon.getInstance;
import static pers.xanadu.enderdragon.util.MathUtil.*;
public class WorldManager {
public static final List<String> worlds = new ArrayList<>();
private Field dimension;
private Field world_provider;
private Method getDimensionID;
public static void reload(){
worlds.clear();
Bukkit.getWorlds().forEach(world -> worlds.add(world.getName()));
}
public static Collection<EnderDragon> getExplosionDragon(float power, Location loc){
World world = loc.getWorld();
if(world == null) return Collections.EMPTY_LIST;
return getExplosionDragon(loc.getWorld(),power,loc.getX()+0.5d,loc.getY()+0.5d,loc.getZ()+0.5d);
}
public static Collection<EnderDragon> getExplosionDragon(World world,float power,double x,double y,double z){
float f = power * 2.0F;
int x1 = floor(x - (double)f - 1.0);
int x2 = floor(x + (double)f + 1.0);
int y1 = floor(y - (double)f - 1.0);
int y2 = floor(y + (double)f + 1.0);
int z1 = floor(z - (double)f - 1.0);
int z2 = floor(z + (double)f + 1.0);
// Collection<Entity> list = world.getNearbyEntities(new BoundingBox(x1, y1, z1, x2, y2, z2));
Location cen = new Location(world,(x1+x2)/2d,(y1+y2)/2d,(z1+z2)/2d);
double rx = (x2-x1)/2d;
double ry = (y2-y1)/2d;
double rz = (z2-z1)/2d;
Collection<Entity> list = world.getNearbyEntities(cen,rx,ry,rz);
List<EnderDragon> res = new ArrayList<>();
for (Entity entity : list) {
if(entity instanceof EnderDragon){
double d0 = sqrt(c(entity,x, y, z)) / f;
if (d0 <= 1.0) {
Location loc = entity.getLocation();
double dx = loc.getX() - x;
double dy = loc.getY() + 6.8d - y;
double dz = loc.getZ() - z;
double d1 = sqrt(dx * dx + dy * dy + dz * dz);
if (d1 != 0.0) {
res.add((EnderDragon) entity);
}
}
}
}
return res;
}
// public static float a(Vector endPos, Entity entity) {
// BoundingBox bb = entity.getBoundingBox();
// double d0 = 1.0 / ((bb.getMaxX() - bb.getMinX()) * 2.0 + 1.0);
// double d1 = 1.0 / ((bb.getMaxY() - bb.getMinY()) * 2.0 + 1.0);
// double d2 = 1.0 / ((bb.getMaxZ() - bb.getMinZ()) * 2.0 + 1.0);
// double d3 = (1.0 - Math.floor(1.0 / d0) * d0) / 2.0;
// double d4 = (1.0 - Math.floor(1.0 / d2) * d2) / 2.0;
// if (d0 >= 0.0 && d1 >= 0.0 && d2 >= 0.0) {
// int i = 0;
// int j = 0;
//
// for(float f = 0.0F; f <= 1.0F; f = (float)((double)f + d0)) {
// for(float f1 = 0.0F; f1 <= 1.0F; f1 = (float)((double)f1 + d1)) {
// for(float f2 = 0.0F; f2 <= 1.0F; f2 = (float)((double)f2 + d2)) {
// double d5 = d(f, bb.getMinX(), bb.getMaxX());
// double d6 = d(f1, bb.getMinY(), bb.getMaxY());
// double d7 = d(f2, bb.getMinZ(), bb.getMaxZ());
// //Vec3D vec3d1 = new Vec3D(d5 + d3, d6, d7 + d4);
// Location start = new Location(entity.getWorld(),d5 + d3, d6, d7 + d4);
// Vector dir = new Vector(endPos.getX()-start.getX(),endPos.getY()-start.getY(),endPos.getZ()-start.getZ());
// double maxDistance = dir.length();
// RayTraceResult result = entity.getWorld().rayTraceBlocks(start,dir,maxDistance, FluidCollisionMode.NEVER,false);
// if(result == null) ++i;
//// if (entity.getWorld().rayTrace(new RayTrace(vec3d1, endPos, RayTrace.BlockCollisionOption.OUTLINE, RayTrace.FluidCollisionOption.NONE, entity)).getType() == MovingObjectPosition.EnumMovingObjectType.MISS) {
//// ++i;
//// }
// ++j;
// }
// }
// }
// return (float)i / (float)j;
// } else {
// return 0.0F;
// }
// }
public void fixWorldEnvironment(){
Bukkit.getWorlds().forEach(world -> {
try{
if(isTheEnd(world)) getInstance().getNMSManager().setEnvironment(world, World.Environment.THE_END);
}catch(ReflectiveOperationException e){
e.printStackTrace();
}
});
}
private boolean isTheEnd(World world) throws ReflectiveOperationException {
String version = Version.getVersion();
switch (version) {
case "v1_12_R1" :
case "v1_13_R1" : {
Object world_server = getInstance().getNMSManager().getWorldServer(world);
if(dimension == null) dimension = world_server.getClass().getDeclaredField("dimension");
int dimen = (int) dimension.get(world_server);
return dimen == 1;
}
case "v1_13_R2" : {
Object world_server = getInstance().getNMSManager().getWorldServer(world);
if(dimension == null) dimension = world_server.getClass().getField("dimension");
Object DimensionManager = dimension.get(world_server);
if(getDimensionID == null) getDimensionID = DimensionManager.getClass().getMethod("getDimensionID");
int dimen = (int) getDimensionID.invoke(DimensionManager);
return dimen == 1;
}
case "v1_14_R1" :
case "v1_15_R1" : {
Object world_server = getInstance().getNMSManager().getWorldServer(world);
if(world_provider == null) world_provider = world_server.getClass().getField("worldProvider");
Object worldProvider = world_provider.get(world_server);
if(dimension == null) dimension = getInstance().getNMSManager().getWorldProviderClass().getDeclaredField("f");
dimension.setAccessible(true);
Object DimensionManager = dimension.get(worldProvider);
if(getDimensionID == null) getDimensionID = DimensionManager.getClass().getMethod("getDimensionID");
int dimen = (int) getDimensionID.invoke(DimensionManager);
return dimen == 1;
}
case "v1_16_R1" :
case "v1_16_R2" :
case "v1_16_R3" :
case "v1_17_R1" : {
Object world_server = getInstance().getNMSManager().getWorldServer(world);
if(getDimensionID == null) getDimensionID = getInstance().getNMSManager().getWorldClass().getMethod("getDimensionKey");
Object world_type = getDimensionID.invoke(world_server);
return world_type.toString().contains("minecraft:the_end");
}
default : {
if(Version.mcMainVersion < 12){
Lang.warn("Your server version (" + version + ") is not supported!");
return false;
}
Object world_server = getInstance().getNMSManager().getWorldServer(world);
if(getDimensionID == null) getDimensionID = world_server.getClass().getMethod("getTypeKey");
Object world_type = getDimensionID.invoke(world_server);
return world_type.toString().contains("minecraft:the_end");
}
}
/*
try{
//>=1.18 建议使用WorldServer::getTypeKey
Object world_server = getInstance().getNMSManager().getWorldServer(world);
Class<?> World_Class = Class.forName("net.minecraft.server."+ Version.getVersion()+".World");//<=1.16.5
Object world_type = World_Class.getDeclaredMethod("getDimensionKey").invoke(world_server);//<=1.17.1
String string_type = world_type.toString();
Bukkit.broadcastMessage(string_type);
Class<?> ResourceKey_Class = Class.forName("net.minecraft.server."+Version.getVersion()+".ResourceKey");
Object ResourceKey = ResourceKey_Class.cast(world_type);
Object MinecraftKey = ResourceKey_Class.getDeclaredMethod("a").invoke(ResourceKey);
Class<?> MinecraftKey_Class = Class.forName("net.minecraft.server."+Version.getVersion()+".MinecraftKey");
String string_type2 = (String) MinecraftKey_Class.getDeclaredMethod("getKey").invoke(MinecraftKey);
Bukkit.broadcastMessage(string_type2);
// Object world_c = getCraftWorld(world);
// Object envi = CraftWorldClass.getDeclaredMethod("getEnvironment").invoke(world_c);
// World.Environment environment = (World.Environment) envi;
// Bukkit.broadcastMessage(environment.toString());
}catch (ReflectiveOperationException e){
e.printStackTrace();
}
*/
}
}
@@ -0,0 +1,144 @@
package pers.xanadu.enderdragon.maven;
import me.lucko.jarrelocator.JarRelocator;
import me.lucko.jarrelocator.Relocation;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Objects;
import static pers.xanadu.enderdragon.maven.DependencyManager.*;
public class Dependency {
protected final String groupId;
protected final String artifactId;
protected final String version;
private final String repository;
private final AlgorithmType algorithm;
protected final String path;
private final List<String> relocate_rules_str;
private final List<Relocation> rules = new ArrayList<>();
public Dependency(String groupId, String artifactId, String version){
this(groupId,artifactId,version,"https://repo1.maven.org/maven2/",AlgorithmType.SHA_1, Collections.emptyList());
}
public Dependency(String groupId,String artifactId,String version,String repository,AlgorithmType algo,List<String> relocate_rules){
this.groupId = groupId;
this.artifactId = artifactId;
this.version = version;
this.repository = repository.endsWith("/")?repository:repository+"/";
this.algorithm = algo;
this.relocate_rules_str = relocate_rules;
this.path = groupId.replaceAll("\\.","/") + "/"
+ artifactId.replaceAll("\\.","/") + "/"
+ version;
int rule_size = relocate_rules.size()/2;
for(int i=0;i<rule_size;i++){
this.rules.add(new Relocation(relocate_rules.get(i*2),relocate_rules.get(i*2+1)));
}
}
public boolean load(){
String depend_name = groupId+":"+artifactId+":"+version;
print("Loading library " + depend_name);
String baseDir = getBaseDir();
File folder = new File(baseDir);
folder.mkdirs();
//遇到需要重定向的依赖先检验当前重定向文件hash验证无误就直接加载
if(requireRelocate()){
String relocated_name = getRelocatedFileName();
File relocated = new File(baseDir,relocated_name);
File relocated_hash_file = new File(baseDir,getHashFileName(relocated_name));
if(checkHash(relocated,relocated_hash_file,algorithm.value())){
ClassLoader loader = JarLoader.addPath(relocated.toPath());
return loader != null;
}
}
String jar_name = artifactId+"-"+version+".jar";
String hashFile_name = getHashFileName(jar_name);
File jarFile = new File(baseDir,jar_name);
File hashFile = new File(baseDir,hashFile_name);
//检验原始文件hash不一致就重新下载
if(!checkHash(jarFile,hashFile,algorithm.value())){
String url_head = repository + path + "/";
String jar_url = url_head + jar_name;
String jar_savePath = jarFile.getPath();
String hashFile_url = url_head + hashFile_name;
String hashFile_savePath = hashFile.getPath();
if(downloadFile(jar_url,jar_savePath) && downloadFile(hashFile_url,hashFile_savePath)){
jarFile = new File(baseDir,jar_name);
hashFile = new File(baseDir,hashFile_name);
if(!checkHash(jarFile,hashFile,algorithm.value())){
err("Hash check failed for downloaded file " + jar_name);
return false;
}
}
else{
err("Failed to download file " + jar_name);
return false;
}
}
//原始文件已无误
ClassLoader loader;
if(requireRelocate()){
String relocated_name = getRelocatedFileName();
File relocated = new File(baseDir,relocated_name);
JarRelocator relocator = new JarRelocator(jarFile, relocated, rules);
print("Relocating library " + depend_name);
try {
relocator.run();
generateHashFile(new File(baseDir,relocated_name));
} catch (IOException e) {
e.printStackTrace();
return false;
}
loader = JarLoader.addPath(relocated.toPath());
}
else{
loader = JarLoader.addPath(jarFile.toPath());
}
return loader != null;
}
private void generateHashFile(File file){
String hash = DependencyManager.getHash(file,algorithm.value());
File hashFile = new File(getBaseDir(),getHashFileName(file.getName()));
try{
FileWriter writer = new FileWriter(hashFile);
if(hash!=null) writer.write(hash);
writer.close();
}catch (IOException e){
e.printStackTrace();
}
}
private String getHashFileName(String jarName){
return jarName+"."+algorithm.getFileExtension();
}
private String getRelocatedFileName(){
return artifactId+"-"+version+"-Rel"+hashCode()+".jar";
}
private String getBaseDir(){
return "libs/"+path;
}
private boolean requireRelocate(){
return !rules.isEmpty();
}
public String getName(){
return groupId+":"+artifactId+":"+version;
}
@Override
public int hashCode(){
return Objects.hash(getName()+"$"+repository+"$"+algorithm.value(),relocate_rules_str);
}
public enum AlgorithmType{
MD5,SHA_1,SHA_256,SHA_512;
private String value(){
return this.name().replace('_','-');
}
private String getFileExtension(){
return this.name().replaceAll("_","").toLowerCase();
}
}
}
@@ -0,0 +1,197 @@
package pers.xanadu.enderdragon.maven;
import org.bukkit.Bukkit;
import org.jetbrains.annotations.TestOnly;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;
import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.net.URL;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.*;
import java.util.logging.Logger;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
public class DependencyManager {
private static final Set<String> dependency_set = new TreeSet<>();
private static final Logger logger = Bukkit.getLogger();
private static boolean dep_groovy = false;
public static void onEnable(){
dependency_set.clear();
List<String> rules = Collections.emptyList();
// List<String> rules = Arrays.asList(
// "groovy","xanadu.groovy",
// "org.apache.groovy","xanadu.org.apache.groovy"
// );
Dependency groovy = new Dependency("org.apache.groovy","groovy","4.0.10","https://repo1.maven.org/maven2/", Dependency.AlgorithmType.SHA_256,rules);
boolean f = groovy.load();
if(f) dep_groovy = true;
else err("Failed to load library: "+groovy.getName());
//addDependency("org.jetbrains.kotlin","kotlin-stdlib","1.7.20");
//addDependency("com.fasterxml.jackson.core","jackson-databind","2.14.2");
//loadAllDependency();
}
@TestOnly
private static void loadAllDependency(){
dependency_set.forEach(key->{
String[] splits = key.split("\\$",3);
new Dependency(splits[0],splits[1],splits[2]).load();
});
}
@TestOnly
public static void addDependency(String groupId, String artifactId, String version,String... exclusion){
dependency_set.add(groupId+"$"+artifactId+"$"+version);
if(exclusion!=null && exclusion.length!=0 && "*$*".equals(exclusion[0])) return;
String pom_url = "https://repo1.maven.org/maven2/"
+ groupId.replaceAll("\\.", "/") + "/"
+ artifactId.replaceAll("\\.","/") + "/"
+ version + "/" + artifactId + "-" + version + ".pom";
String baseDir = "libs\\"
+ groupId.replaceAll("\\.", "\\\\") + "\\"
+ artifactId.replaceAll("\\.","\\\\") + "\\"
+ version;
File folder = new File(baseDir);
folder.mkdirs();
String filePath = baseDir + "\\" + artifactId + "-" + version + ".pom";
DependencyManager.downloadFile(pom_url,filePath);
File file = new File(filePath);
try{
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = factory.newDocumentBuilder();
Document doc = builder.parse(file);
Element root = doc.getDocumentElement();
Element dependenciesElement = XMLParser.getElement(root,"dependencies");
if(dependenciesElement == null) return;
NodeList dependencyList = dependenciesElement.getElementsByTagName("dependency");
for (int i = 0; i < dependencyList.getLength(); i++) {
Element dependencyElement = (Element) dependencyList.item(i);
String nxt_groupId = XMLParser.getString(dependencyElement,"groupId");
String nxt_artifactId = XMLParser.getString(dependencyElement,"artifactId");
String nxt_version = XMLParser.getString(dependencyElement,"version");
if(nxt_groupId==null || nxt_artifactId==null || nxt_version==null){
return;
}
String scope = XMLParser.getString(dependencyElement,"scope");
String optional = XMLParser.getString(dependencyElement,"optional");
//${xxx}如何处理
//获取不到版本怎么办
//if(scope.matches("${}"))
if(isRequired(scope,optional)) {
String[] nxt_exclusions = getExclusions(dependencyElement);
String id = nxt_groupId + "$" + nxt_artifactId;
String parent_id = nxt_groupId + "$*";
if(exclusion!=null){
boolean add = true;
for(int j=0;j<exclusion.length;j++){
if(exclusion[j].equals(id) || exclusion[j].equals(parent_id)){
add = false;
break;
}
}
if(add) addDependency(nxt_groupId,nxt_artifactId,nxt_version,nxt_exclusions);
}
else {
addDependency(nxt_groupId,nxt_artifactId,nxt_version,nxt_exclusions);
}
}
}
}catch (IOException | ParserConfigurationException | SAXException e){
e.printStackTrace();
}
}
public static void err(String str){
logger.severe("[EnderDragon] "+str);
}
public static void warning(String str){
logger.warning("[EnderDragon] "+str);
}
public static void print(String str){
logger.info("[EnderDragon] "+str);
}
public static boolean checkHash(File file,File hash_file,String algorithm){
if(!file.exists() || !hash_file.exists()) return false;
String hash = readAsString(hash_file);
String sha_256 = getHash(file,algorithm);
return Objects.equals(sha_256, hash);
}
public static boolean downloadFile(String fileUrl, String savePath) {
print("Download "+fileUrl);
try{
URL url = new URL(fileUrl);
try (BufferedInputStream in = new BufferedInputStream(url.openStream());
FileOutputStream fileOutputStream = new FileOutputStream(savePath)) {
byte[] dataBuffer = new byte[1024];
int bytesRead;
while ((bytesRead = in.read(dataBuffer, 0, 1024)) != -1) {
fileOutputStream.write(dataBuffer, 0, bytesRead);
}
}
return true;
}catch (IOException e){
return false;
}
}
private static String[] getExclusions(Element dependencyElement){
Element exclusionsElement = XMLParser.getElement(dependencyElement,"exclusions");
if(exclusionsElement!=null){
NodeList exclusionList = exclusionsElement.getElementsByTagName("exclusion");
String[] res = new String[exclusionList.getLength()];
for(int j=0;j<res.length;j++){
Element element = (Element) exclusionList.item(j);
String tmp = XMLParser.getString(element,"groupId")+"$"+XMLParser.getString(element,"artifactId");
res[j] = tmp;
}
return res;
}
else return new String[0];
}
private static boolean isRequired(String scope,String optional){
if("true".equals(optional)) return false;
return !"test".equals(scope) && !"provided".equals(scope) && !"system".equals(scope);
}
private static String readAsString(File file){
try {
Path path = file.toPath();
byte[] fileBytes = Files.readAllBytes(path);
return new String(fileBytes, StandardCharsets.UTF_8);
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
public static String getHash(final File file,final String algorithm){
try {
Path path = file.toPath();
byte[] fileBytes = Files.readAllBytes(path);
MessageDigest md = MessageDigest.getInstance(algorithm);
byte[] bytes = md.digest(fileBytes);
StringBuilder sb = new StringBuilder();
for (byte b : bytes) {
sb.append(String.format("%02x", b));
}
return sb.toString();
}catch (IOException|NoSuchAlgorithmException e){
e.printStackTrace();
return null;
}
}
public static boolean isGroovyLoaded(){
return dep_groovy;
}
}
@@ -0,0 +1,84 @@
package pers.xanadu.enderdragon.maven;
import pers.xanadu.enderdragon.EnderDragon;
import sun.misc.Unsafe;
import java.io.File;
import java.lang.invoke.MethodHandle;
import java.lang.invoke.MethodHandles;
import java.lang.invoke.MethodType;
import java.lang.reflect.Field;
import java.net.URL;
import java.net.URLClassLoader;
import java.nio.file.Path;
/**
* @author sky
* @since 2020-04-12 22:39
*/
public class JarLoader {
private static MethodHandles.Lookup lookup;
private static Unsafe unsafe;
static {
try {
Field field = Unsafe.class.getDeclaredField("theUnsafe");
field.setAccessible(true);
unsafe = (Unsafe) field.get(null);
Field lookupField = MethodHandles.Lookup.class.getDeclaredField("IMPL_LOOKUP");
Object lookupBase = unsafe.staticFieldBase(lookupField);
long lookupOffset = unsafe.staticFieldOffset(lookupField);
lookup = (MethodHandles.Lookup) unsafe.getObject(lookupBase, lookupOffset);
} catch (Throwable ignore) {
}
}
JarLoader() {
}
public static ClassLoader addPath(Path path) {
try {
File file = new File(path.toUri().getPath());
ClassLoader loader = EnderDragon.class.getClassLoader();
// Bukkit
Field ucpField;
try {
ucpField = URLClassLoader.class.getDeclaredField("ucp");
} catch (NoSuchFieldError | NoSuchFieldException ignored) {
ucpField = ucp(loader.getClass());
}
addURL(loader, ucpField, file);
return loader;
} catch (Throwable t) {
t.printStackTrace();
}
return null;
}
private static void addURL(ClassLoader loader, Field ucpField, File file) throws Throwable {
if (ucpField == null) {
throw new IllegalStateException("ucp field not found");
}
Object ucp = unsafe.getObject(loader, unsafe.objectFieldOffset(ucpField));
try {
MethodHandle methodHandle = lookup.findVirtual(ucp.getClass(), "addURL", MethodType.methodType(void.class, URL.class));
methodHandle.invoke(ucp, file.toURI().toURL());
} catch (NoSuchMethodError e) {
throw new IllegalStateException("Unsupported (classloader: " + loader.getClass().getName() + ", ucp: " + ucp.getClass().getName() + ")", e);
}
}
private static Field ucp(Class<?> loader) {
try {
return loader.getDeclaredField("ucp");
} catch (NoSuchFieldError | NoSuchFieldException e2) {
Class<?> superclass = loader.getSuperclass();
if (superclass == Object.class) {
return null;
}
return ucp(superclass);
}
}
}
@@ -0,0 +1,15 @@
package pers.xanadu.enderdragon.maven;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;
public class XMLParser {
public static String getString(Element element,String tag){
Element element_section = getElement(element,tag);
return element_section==null?null:element_section.getTextContent();
}
public static Element getElement(Element element,String tag){
NodeList nodeList = element.getElementsByTagName(tag);
return (Element) nodeList.item(0);
}
}
@@ -0,0 +1,849 @@
package pers.xanadu.enderdragon.metrics;
import java.io.BufferedReader;
import java.io.ByteArrayOutputStream;
import java.io.DataOutputStream;
import java.io.File;
import java.io.IOException;
import java.io.InputStreamReader;
import java.lang.reflect.Method;
import java.net.URL;
import java.nio.charset.StandardCharsets;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashSet;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
import java.util.UUID;
import java.util.concurrent.Callable;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
import java.util.function.BiConsumer;
import java.util.function.Consumer;
import java.util.function.Supplier;
import java.util.logging.Level;
import java.util.stream.Collectors;
import java.util.zip.GZIPOutputStream;
import javax.net.ssl.HttpsURLConnection;
import org.bukkit.Bukkit;
import org.bukkit.configuration.file.YamlConfiguration;
import org.bukkit.entity.Player;
import org.bukkit.plugin.Plugin;
import org.bukkit.plugin.java.JavaPlugin;
public class Metrics {
private final Plugin plugin;
private final MetricsBase metricsBase;
/**
* Creates a new Metrics instance.
*
* @param plugin Your plugin instance.
* @param serviceId The id of the service. It can be found at <a
* href="https://bstats.org/what-is-my-plugin-id">What is my plugin id?</a>
*/
public Metrics(JavaPlugin plugin, int serviceId) {
this.plugin = plugin;
// Get the config file
File bStatsFolder = new File(plugin.getDataFolder().getParentFile(), "bStats");
File configFile = new File(bStatsFolder, "config.yml");
YamlConfiguration config = YamlConfiguration.loadConfiguration(configFile);
if (!config.isSet("serverUuid")) {
config.addDefault("enabled", true);
config.addDefault("serverUuid", UUID.randomUUID().toString());
config.addDefault("logFailedRequests", false);
config.addDefault("logSentData", false);
config.addDefault("logResponseStatusText", false);
// Inform the server owners about bStats
config
.options()
.header(
"bStats (https://bStats.org) collects some basic information for plugin authors, like how\n"
+ "many people use their plugin and their total player count. It's recommended to keep bStats\n"
+ "enabled, but if you're not comfortable with this, you can turn this setting off. There is no\n"
+ "performance penalty associated with having metrics enabled, and data sent to bStats is fully\n"
+ "anonymous.")
.copyDefaults(true);
try {
config.save(configFile);
} catch (IOException ignored) {
}
}
// Load the data
boolean enabled = plugin.getConfig().getBoolean("bStats.enabled", true);
String serverUUID = config.getString("serverUuid");
boolean logErrors = config.getBoolean("logFailedRequests", false);
boolean logSentData = config.getBoolean("logSentData", false);
boolean logResponseStatusText = config.getBoolean("logResponseStatusText", false);
metricsBase =
new MetricsBase(
"bukkit",
serverUUID,
serviceId,
enabled,
this::appendPlatformData,
this::appendServiceData,
submitDataTask -> Bukkit.getScheduler().runTask(plugin, submitDataTask),
plugin::isEnabled,
(message, error) -> this.plugin.getLogger().log(Level.WARNING, message, error),
(message) -> this.plugin.getLogger().log(Level.INFO, message),
logErrors,
logSentData,
logResponseStatusText);
}
/**
* Adds a custom chart.
*
* @param chart The chart to add.
*/
public void addCustomChart(CustomChart chart) {
metricsBase.addCustomChart(chart);
}
private void appendPlatformData(JsonObjectBuilder builder) {
builder.appendField("playerAmount", getPlayerAmount());
builder.appendField("onlineMode", Bukkit.getOnlineMode() ? 1 : 0);
builder.appendField("bukkitVersion", Bukkit.getVersion());
builder.appendField("bukkitName", Bukkit.getName());
builder.appendField("javaVersion", System.getProperty("java.version"));
builder.appendField("osName", System.getProperty("os.name"));
builder.appendField("osArch", System.getProperty("os.arch"));
builder.appendField("osVersion", System.getProperty("os.version"));
builder.appendField("coreCount", Runtime.getRuntime().availableProcessors());
}
private void appendServiceData(JsonObjectBuilder builder) {
builder.appendField("pluginVersion", plugin.getDescription().getVersion());
}
private int getPlayerAmount() {
try {
// Around MC 1.8 the return type was changed from an array to a collection,
// This fixes java.lang.NoSuchMethodError:
// org.bukkit.Bukkit.getOnlinePlayers()Ljava/util/Collection;
Method onlinePlayersMethod = Class.forName("org.bukkit.Server").getMethod("getOnlinePlayers");
return onlinePlayersMethod.getReturnType().equals(Collection.class)
? ((Collection<?>) onlinePlayersMethod.invoke(Bukkit.getServer())).size()
: ((Player[]) onlinePlayersMethod.invoke(Bukkit.getServer())).length;
} catch (Exception e) {
// Just use the new method if the reflection failed
return Bukkit.getOnlinePlayers().size();
}
}
public static class MetricsBase {
/** The version of the Metrics class. */
public static final String METRICS_VERSION = "3.0.0";
private static final ScheduledExecutorService scheduler =
Executors.newScheduledThreadPool(1, task -> new Thread(task, "bStats-Metrics"));
private static final String REPORT_URL = "https://bStats.org/api/v2/data/%s";
private final String platform;
private final String serverUuid;
private final int serviceId;
private final Consumer<JsonObjectBuilder> appendPlatformDataConsumer;
private final Consumer<JsonObjectBuilder> appendServiceDataConsumer;
private final Consumer<Runnable> submitTaskConsumer;
private final Supplier<Boolean> checkServiceEnabledSupplier;
private final BiConsumer<String, Throwable> errorLogger;
private final Consumer<String> infoLogger;
private final boolean logErrors;
private final boolean logSentData;
private final boolean logResponseStatusText;
private final Set<CustomChart> customCharts = new HashSet<>();
private final boolean enabled;
/**
* Creates a new MetricsBase class instance.
*
* @param platform The platform of the service.
* @param serviceId The id of the service.
* @param serverUuid The server uuid.
* @param enabled Whether or not data sending is enabled.
* @param appendPlatformDataConsumer A consumer that receives a {@code JsonObjectBuilder} and
* appends all platform-specific data.
* @param appendServiceDataConsumer A consumer that receives a {@code JsonObjectBuilder} and
* appends all service-specific data.
* @param submitTaskConsumer A consumer that takes a runnable with the submit task. This can be
* used to delegate the data collection to a another thread to prevent errors caused by
* concurrency. Can be {@code null}.
* @param checkServiceEnabledSupplier A supplier to check if the service is still enabled.
* @param errorLogger A consumer that accepts log message and an error.
* @param infoLogger A consumer that accepts info log messages.
* @param logErrors Whether or not errors should be logged.
* @param logSentData Whether or not the sent data should be logged.
* @param logResponseStatusText Whether or not the response status text should be logged.
*/
public MetricsBase(
String platform,
String serverUuid,
int serviceId,
boolean enabled,
Consumer<JsonObjectBuilder> appendPlatformDataConsumer,
Consumer<JsonObjectBuilder> appendServiceDataConsumer,
Consumer<Runnable> submitTaskConsumer,
Supplier<Boolean> checkServiceEnabledSupplier,
BiConsumer<String, Throwable> errorLogger,
Consumer<String> infoLogger,
boolean logErrors,
boolean logSentData,
boolean logResponseStatusText) {
this.platform = platform;
this.serverUuid = serverUuid;
this.serviceId = serviceId;
this.enabled = enabled;
this.appendPlatformDataConsumer = appendPlatformDataConsumer;
this.appendServiceDataConsumer = appendServiceDataConsumer;
this.submitTaskConsumer = submitTaskConsumer;
this.checkServiceEnabledSupplier = checkServiceEnabledSupplier;
this.errorLogger = errorLogger;
this.infoLogger = infoLogger;
this.logErrors = logErrors;
this.logSentData = logSentData;
this.logResponseStatusText = logResponseStatusText;
checkRelocation();
if (enabled) {
// WARNING: Removing the option to opt-out will get your plugin banned from bStats
startSubmitting();
}
}
public void addCustomChart(CustomChart chart) {
this.customCharts.add(chart);
}
private void startSubmitting() {
final Runnable submitTask =
() -> {
if (!enabled || !checkServiceEnabledSupplier.get()) {
// Submitting data or service is disabled
scheduler.shutdown();
return;
}
if (submitTaskConsumer != null) {
submitTaskConsumer.accept(this::submitData);
} else {
this.submitData();
}
};
// Many servers tend to restart at a fixed time at xx:00 which causes an uneven distribution
// of requests on the
// bStats backend. To circumvent this problem, we introduce some randomness into the initial
// and second delay.
// WARNING: You must not modify and part of this Metrics class, including the submit delay or
// frequency!
// WARNING: Modifying this code will get your plugin banned on bStats. Just don't do it!
long initialDelay = (long) (1000 * 60 * (3 + Math.random() * 3));
long secondDelay = (long) (1000 * 60 * (Math.random() * 30));
scheduler.schedule(submitTask, initialDelay, TimeUnit.MILLISECONDS);
scheduler.scheduleAtFixedRate(
submitTask, initialDelay + secondDelay, 1000 * 60 * 30, TimeUnit.MILLISECONDS);
}
private void submitData() {
final JsonObjectBuilder baseJsonBuilder = new JsonObjectBuilder();
appendPlatformDataConsumer.accept(baseJsonBuilder);
final JsonObjectBuilder serviceJsonBuilder = new JsonObjectBuilder();
appendServiceDataConsumer.accept(serviceJsonBuilder);
JsonObjectBuilder.JsonObject[] chartData =
customCharts.stream()
.map(customChart -> customChart.getRequestJsonObject(errorLogger, logErrors))
.filter(Objects::nonNull)
.toArray(JsonObjectBuilder.JsonObject[]::new);
serviceJsonBuilder.appendField("id", serviceId);
serviceJsonBuilder.appendField("customCharts", chartData);
baseJsonBuilder.appendField("service", serviceJsonBuilder.build());
baseJsonBuilder.appendField("serverUUID", serverUuid);
baseJsonBuilder.appendField("metricsVersion", METRICS_VERSION);
JsonObjectBuilder.JsonObject data = baseJsonBuilder.build();
scheduler.execute(
() -> {
try {
// Send the data
sendData(data);
} catch (Exception e) {
// Something went wrong! :(
if (logErrors) {
errorLogger.accept("Could not submit bStats metrics data", e);
}
}
});
}
private void sendData(JsonObjectBuilder.JsonObject data) throws Exception {
if (logSentData) {
infoLogger.accept("Sent bStats metrics data: " + data.toString());
}
String url = String.format(REPORT_URL, platform);
HttpsURLConnection connection = (HttpsURLConnection) new URL(url).openConnection();
// Compress the data to save bandwidth
byte[] compressedData = compress(data.toString());
connection.setRequestMethod("POST");
connection.addRequestProperty("Accept", "application/json");
connection.addRequestProperty("Connection", "close");
connection.addRequestProperty("Content-Encoding", "gzip");
connection.addRequestProperty("Content-Length", String.valueOf(compressedData.length));
connection.setRequestProperty("Content-Type", "application/json");
connection.setRequestProperty("User-Agent", "Metrics-Service/1");
connection.setDoOutput(true);
try (DataOutputStream outputStream = new DataOutputStream(connection.getOutputStream())) {
outputStream.write(compressedData);
}
StringBuilder builder = new StringBuilder();
try (BufferedReader bufferedReader =
new BufferedReader(new InputStreamReader(connection.getInputStream()))) {
String line;
while ((line = bufferedReader.readLine()) != null) {
builder.append(line);
}
}
if (logResponseStatusText) {
infoLogger.accept("Sent data to bStats and received response: " + builder);
}
}
/** Checks that the class was properly relocated. */
private void checkRelocation() {
// You can use the property to disable the check in your test environment
if (System.getProperty("bstats.relocatecheck") == null
|| !System.getProperty("bstats.relocatecheck").equals("false")) {
// Maven's Relocate is clever and changes strings, too. So we have to use this little
// "trick" ... :D
final String defaultPackage =
new String(new byte[] {'o', 'r', 'g', '.', 'b', 's', 't', 'a', 't', 's'});
final String examplePackage =
new String(new byte[] {'y', 'o', 'u', 'r', '.', 'p', 'a', 'c', 'k', 'a', 'g', 'e'});
// We want to make sure no one just copy & pastes the example and uses the wrong package
// names
if (MetricsBase.class.getPackage().getName().startsWith(defaultPackage)
|| MetricsBase.class.getPackage().getName().startsWith(examplePackage)) {
throw new IllegalStateException("bStats Metrics class has not been relocated correctly!");
}
}
}
/**
* Gzips the given string.
*
* @param str The string to gzip.
* @return The gzipped string.
*/
private static byte[] compress(final String str) throws IOException {
if (str == null) {
return null;
}
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
try (GZIPOutputStream gzip = new GZIPOutputStream(outputStream)) {
gzip.write(str.getBytes(StandardCharsets.UTF_8));
}
return outputStream.toByteArray();
}
}
public static class DrilldownPie extends CustomChart {
private final Callable<Map<String, Map<String, Integer>>> callable;
/**
* Class constructor.
*
* @param chartId The id of the chart.
* @param callable The callable which is used to request the chart data.
*/
public DrilldownPie(String chartId, Callable<Map<String, Map<String, Integer>>> callable) {
super(chartId);
this.callable = callable;
}
@Override
public JsonObjectBuilder.JsonObject getChartData() throws Exception {
JsonObjectBuilder valuesBuilder = new JsonObjectBuilder();
Map<String, Map<String, Integer>> map = callable.call();
if (map == null || map.isEmpty()) {
// Null = skip the chart
return null;
}
boolean reallyAllSkipped = true;
for (Map.Entry<String, Map<String, Integer>> entryValues : map.entrySet()) {
JsonObjectBuilder valueBuilder = new JsonObjectBuilder();
boolean allSkipped = true;
for (Map.Entry<String, Integer> valueEntry : map.get(entryValues.getKey()).entrySet()) {
valueBuilder.appendField(valueEntry.getKey(), valueEntry.getValue());
allSkipped = false;
}
if (!allSkipped) {
reallyAllSkipped = false;
valuesBuilder.appendField(entryValues.getKey(), valueBuilder.build());
}
}
if (reallyAllSkipped) {
// Null = skip the chart
return null;
}
return new JsonObjectBuilder().appendField("values", valuesBuilder.build()).build();
}
}
public static class AdvancedPie extends CustomChart {
private final Callable<Map<String, Integer>> callable;
/**
* Class constructor.
*
* @param chartId The id of the chart.
* @param callable The callable which is used to request the chart data.
*/
public AdvancedPie(String chartId, Callable<Map<String, Integer>> callable) {
super(chartId);
this.callable = callable;
}
@Override
protected JsonObjectBuilder.JsonObject getChartData() throws Exception {
JsonObjectBuilder valuesBuilder = new JsonObjectBuilder();
Map<String, Integer> map = callable.call();
if (map == null || map.isEmpty()) {
// Null = skip the chart
return null;
}
boolean allSkipped = true;
for (Map.Entry<String, Integer> entry : map.entrySet()) {
if (entry.getValue() == 0) {
// Skip this invalid
continue;
}
allSkipped = false;
valuesBuilder.appendField(entry.getKey(), entry.getValue());
}
if (allSkipped) {
// Null = skip the chart
return null;
}
return new JsonObjectBuilder().appendField("values", valuesBuilder.build()).build();
}
}
public static class MultiLineChart extends CustomChart {
private final Callable<Map<String, Integer>> callable;
/**
* Class constructor.
*
* @param chartId The id of the chart.
* @param callable The callable which is used to request the chart data.
*/
public MultiLineChart(String chartId, Callable<Map<String, Integer>> callable) {
super(chartId);
this.callable = callable;
}
@Override
protected JsonObjectBuilder.JsonObject getChartData() throws Exception {
JsonObjectBuilder valuesBuilder = new JsonObjectBuilder();
Map<String, Integer> map = callable.call();
if (map == null || map.isEmpty()) {
// Null = skip the chart
return null;
}
boolean allSkipped = true;
for (Map.Entry<String, Integer> entry : map.entrySet()) {
if (entry.getValue() == 0) {
// Skip this invalid
continue;
}
allSkipped = false;
valuesBuilder.appendField(entry.getKey(), entry.getValue());
}
if (allSkipped) {
// Null = skip the chart
return null;
}
return new JsonObjectBuilder().appendField("values", valuesBuilder.build()).build();
}
}
public static class SimpleBarChart extends CustomChart {
private final Callable<Map<String, Integer>> callable;
/**
* Class constructor.
*
* @param chartId The id of the chart.
* @param callable The callable which is used to request the chart data.
*/
public SimpleBarChart(String chartId, Callable<Map<String, Integer>> callable) {
super(chartId);
this.callable = callable;
}
@Override
protected JsonObjectBuilder.JsonObject getChartData() throws Exception {
JsonObjectBuilder valuesBuilder = new JsonObjectBuilder();
Map<String, Integer> map = callable.call();
if (map == null || map.isEmpty()) {
// Null = skip the chart
return null;
}
for (Map.Entry<String, Integer> entry : map.entrySet()) {
valuesBuilder.appendField(entry.getKey(), new int[] {entry.getValue()});
}
return new JsonObjectBuilder().appendField("values", valuesBuilder.build()).build();
}
}
public abstract static class CustomChart {
private final String chartId;
protected CustomChart(String chartId) {
if (chartId == null) {
throw new IllegalArgumentException("chartId must not be null");
}
this.chartId = chartId;
}
public JsonObjectBuilder.JsonObject getRequestJsonObject(
BiConsumer<String, Throwable> errorLogger, boolean logErrors) {
JsonObjectBuilder builder = new JsonObjectBuilder();
builder.appendField("chartId", chartId);
try {
JsonObjectBuilder.JsonObject data = getChartData();
if (data == null) {
// If the data is null we don't send the chart.
return null;
}
builder.appendField("data", data);
} catch (Throwable t) {
if (logErrors) {
errorLogger.accept("Failed to get data for custom chart with id " + chartId, t);
}
return null;
}
return builder.build();
}
protected abstract JsonObjectBuilder.JsonObject getChartData() throws Exception;
}
public static class SimplePie extends CustomChart {
private final Callable<String> callable;
/**
* Class constructor.
*
* @param chartId The id of the chart.
* @param callable The callable which is used to request the chart data.
*/
public SimplePie(String chartId, Callable<String> callable) {
super(chartId);
this.callable = callable;
}
@Override
protected JsonObjectBuilder.JsonObject getChartData() throws Exception {
String value = callable.call();
if (value == null || value.isEmpty()) {
// Null = skip the chart
return null;
}
return new JsonObjectBuilder().appendField("value", value).build();
}
}
public static class AdvancedBarChart extends CustomChart {
private final Callable<Map<String, int[]>> callable;
/**
* Class constructor.
*
* @param chartId The id of the chart.
* @param callable The callable which is used to request the chart data.
*/
public AdvancedBarChart(String chartId, Callable<Map<String, int[]>> callable) {
super(chartId);
this.callable = callable;
}
@Override
protected JsonObjectBuilder.JsonObject getChartData() throws Exception {
JsonObjectBuilder valuesBuilder = new JsonObjectBuilder();
Map<String, int[]> map = callable.call();
if (map == null || map.isEmpty()) {
// Null = skip the chart
return null;
}
boolean allSkipped = true;
for (Map.Entry<String, int[]> entry : map.entrySet()) {
if (entry.getValue().length == 0) {
// Skip this invalid
continue;
}
allSkipped = false;
valuesBuilder.appendField(entry.getKey(), entry.getValue());
}
if (allSkipped) {
// Null = skip the chart
return null;
}
return new JsonObjectBuilder().appendField("values", valuesBuilder.build()).build();
}
}
public static class SingleLineChart extends CustomChart {
private final Callable<Integer> callable;
/**
* Class constructor.
*
* @param chartId The id of the chart.
* @param callable The callable which is used to request the chart data.
*/
public SingleLineChart(String chartId, Callable<Integer> callable) {
super(chartId);
this.callable = callable;
}
@Override
protected JsonObjectBuilder.JsonObject getChartData() throws Exception {
int value = callable.call();
if (value == 0) {
// Null = skip the chart
return null;
}
return new JsonObjectBuilder().appendField("value", value).build();
}
}
/**
* An extremely simple JSON builder.
*
* <p>While this class is neither feature-rich nor the most performant one, it's sufficient enough
* for its use-case.
*/
public static class JsonObjectBuilder {
private StringBuilder builder = new StringBuilder();
private boolean hasAtLeastOneField = false;
public JsonObjectBuilder() {
builder.append("{");
}
/**
* Appends a null field to the JSON.
*
* @param key The key of the field.
* @return A reference to this object.
*/
public JsonObjectBuilder appendNull(String key) {
appendFieldUnescaped(key, "null");
return this;
}
/**
* Appends a string field to the JSON.
*
* @param key The key of the field.
* @param value The value of the field.
* @return A reference to this object.
*/
public JsonObjectBuilder appendField(String key, String value) {
if (value == null) {
throw new IllegalArgumentException("JSON value must not be null");
}
appendFieldUnescaped(key, "\"" + escape(value) + "\"");
return this;
}
/**
* Appends an integer field to the JSON.
*
* @param key The key of the field.
* @param value The value of the field.
* @return A reference to this object.
*/
public JsonObjectBuilder appendField(String key, int value) {
appendFieldUnescaped(key, String.valueOf(value));
return this;
}
/**
* Appends an object to the JSON.
*
* @param key The key of the field.
* @param object The object.
* @return A reference to this object.
*/
public JsonObjectBuilder appendField(String key, JsonObject object) {
if (object == null) {
throw new IllegalArgumentException("JSON object must not be null");
}
appendFieldUnescaped(key, object.toString());
return this;
}
/**
* Appends a string array to the JSON.
*
* @param key The key of the field.
* @param values The string array.
* @return A reference to this object.
*/
public JsonObjectBuilder appendField(String key, String[] values) {
if (values == null) {
throw new IllegalArgumentException("JSON values must not be null");
}
String escapedValues =
Arrays.stream(values)
.map(value -> "\"" + escape(value) + "\"")
.collect(Collectors.joining(","));
appendFieldUnescaped(key, "[" + escapedValues + "]");
return this;
}
/**
* Appends an integer array to the JSON.
*
* @param key The key of the field.
* @param values The integer array.
* @return A reference to this object.
*/
public JsonObjectBuilder appendField(String key, int[] values) {
if (values == null) {
throw new IllegalArgumentException("JSON values must not be null");
}
String escapedValues =
Arrays.stream(values).mapToObj(String::valueOf).collect(Collectors.joining(","));
appendFieldUnescaped(key, "[" + escapedValues + "]");
return this;
}
/**
* Appends an object array to the JSON.
*
* @param key The key of the field.
* @param values The integer array.
* @return A reference to this object.
*/
public JsonObjectBuilder appendField(String key, JsonObject[] values) {
if (values == null) {
throw new IllegalArgumentException("JSON values must not be null");
}
String escapedValues =
Arrays.stream(values).map(JsonObject::toString).collect(Collectors.joining(","));
appendFieldUnescaped(key, "[" + escapedValues + "]");
return this;
}
/**
* Appends a field to the object.
*
* @param key The key of the field.
* @param escapedValue The escaped value of the field.
*/
private void appendFieldUnescaped(String key, String escapedValue) {
if (builder == null) {
throw new IllegalStateException("JSON has already been built");
}
if (key == null) {
throw new IllegalArgumentException("JSON key must not be null");
}
if (hasAtLeastOneField) {
builder.append(",");
}
builder.append("\"").append(escape(key)).append("\":").append(escapedValue);
hasAtLeastOneField = true;
}
/**
* Builds the JSON string and invalidates this builder.
*
* @return The built JSON string.
*/
public JsonObject build() {
if (builder == null) {
throw new IllegalStateException("JSON has already been built");
}
JsonObject object = new JsonObject(builder.append("}").toString());
builder = null;
return object;
}
/**
* Escapes the given string like stated in https://www.ietf.org/rfc/rfc4627.txt.
*
* <p>This method escapes only the necessary characters '"', '\'. and '\u0000' - '\u001F'.
* Compact escapes are not used (e.g., '\n' is escaped as "\u000a" and not as "\n").
*
* @param value The value to escape.
* @return The escaped value.
*/
private static String escape(String value) {
final StringBuilder builder = new StringBuilder();
for (int i = 0; i < value.length(); i++) {
char c = value.charAt(i);
if (c == '"') {
builder.append("\\\"");
} else if (c == '\\') {
builder.append("\\\\");
} else if (c <= '\u000F') {
builder.append("\\u000").append(Integer.toHexString(c));
} else if (c <= '\u001F') {
builder.append("\\u00").append(Integer.toHexString(c));
} else {
builder.append(c);
}
}
return builder.toString();
}
/**
* A super simple representation of a JSON object.
*
* <p>This class only exists to make methods of the {@link JsonObjectBuilder} type-safe and not
* allow a raw string inputs for methods like {@link JsonObjectBuilder#appendField(String,
* JsonObject)}.
*/
public static class JsonObject {
private final String value;
private JsonObject(String value) {
this.value = value;
}
@Override
public String toString() {
return value;
}
}
}
}
@@ -0,0 +1,11 @@
package pers.xanadu.enderdragon.nms.BossBar;
import org.bukkit.World;
import java.util.List;
public interface I_BossBarManager {
void saveBossBarData(List<World> worlds);
void loadBossBarData(List<World> worlds);
void setBossBar(World world,String title,String color,String style);
}
@@ -0,0 +1,105 @@
package pers.xanadu.enderdragon.nms.BossBar.v1_12_R1;
import net.minecraft.server.v1_12_R1.BossBattle;
import net.minecraft.server.v1_12_R1.BossBattleServer;
import org.bukkit.World;
import org.bukkit.configuration.InvalidConfigurationException;
import org.bukkit.configuration.file.YamlConfiguration;
import org.bukkit.craftbukkit.v1_12_R1.util.CraftChatMessage;
import pers.xanadu.enderdragon.config.Lang;
import pers.xanadu.enderdragon.nms.BossBar.I_BossBarManager;
import java.io.File;
import java.io.IOException;
import java.lang.reflect.Field;
import java.util.List;
import static pers.xanadu.enderdragon.EnderDragon.getInstance;
import static pers.xanadu.enderdragon.EnderDragon.plugin;
public class BossBarManager implements I_BossBarManager {
private Field BossBattleServer = null;
public void saveBossBarData(List<World> worlds){
File file = new File(plugin.getDataFolder(),"world_data.yml");
YamlConfiguration yml = new YamlConfiguration();
worlds.forEach(world -> {
try{
Object edb = getInstance().getNMSManager().getEnderDragonBattle(world);
if(BossBattleServer == null) BossBattleServer = edb.getClass().getDeclaredField("c");
BossBattleServer.setAccessible(true);
BossBattleServer bbs = (BossBattleServer) BossBattleServer.get(edb);
String path = world.getName()+yml.options().pathSeparator();
yml.set(path+"title",bbs.title.getText());
yml.set(path+"color",bbs.color.name());
yml.set(path+"style",bbs.style.name());
}catch (ReflectiveOperationException e){
e.printStackTrace();
}
});
try{
yml.save(file);
Lang.info("BossBar data has been saved!");
}catch (IOException e){
Lang.error("Failed to save world_data!");
}
}
public void loadBossBarData(List<World> worlds){
File file = new File(plugin.getDataFolder(),"world_data.yml");
if(!file.exists()) return;
Lang.info("Enabling BossBar fix...");
YamlConfiguration yml = new YamlConfiguration();
try{
yml.load(file);
}catch (InvalidConfigurationException | IOException e) {
Lang.error("Failed to load world_data!");
return;
}
worlds.forEach(world -> {
try{
Object edb = getInstance().getNMSManager().getEnderDragonBattle(world);
if(BossBattleServer == null) BossBattleServer = edb.getClass().getDeclaredField("c");
BossBattleServer.setAccessible(true);
BossBattleServer bbs = (BossBattleServer) BossBattleServer.get(edb);
String path = world.getName()+".";
bbs.title = CraftChatMessage.fromString(yml.getString(path+"title"), true)[0];
bbs.color = BossBattle.BarColor.valueOf(yml.getString(path+"color"));
bbs.style = BossBattle.BarStyle.valueOf(yml.getString(path+"style"));
}catch (ReflectiveOperationException e){
e.printStackTrace();
}
});
}
public void setBossBar(World world,String title,String color,String style){
BossBattleServer bbs = new BossBattleServer(
CraftChatMessage.fromString(title, true)[0],
convertColor(color),
convertStyle(style)
);
bbs.setCreateFog(true);
bbs.setDarkenSky(true);
bbs.setPlayMusic(true);
try{
Object edb = getInstance().getNMSManager().getEnderDragonBattle(world);
if(BossBattleServer == null) BossBattleServer = edb.getClass().getDeclaredField("c");
BossBattleServer.setAccessible(true);
BossBattleServer.set(edb,bbs);
}catch (ReflectiveOperationException e){
e.printStackTrace();
}
}
private BossBattle.BarColor convertColor(String color) {
return BossBattle.BarColor.valueOf(color);
}
private BossBattle.BarStyle convertStyle(String style) {
switch (style) {
case "SOLID":
default: return net.minecraft.server.v1_12_R1.BossBattle.BarStyle.PROGRESS;
case "SEGMENTED_6": return net.minecraft.server.v1_12_R1.BossBattle.BarStyle.NOTCHED_6;
case "SEGMENTED_10": return net.minecraft.server.v1_12_R1.BossBattle.BarStyle.NOTCHED_10;
case "SEGMENTED_12": return net.minecraft.server.v1_12_R1.BossBattle.BarStyle.NOTCHED_12;
case "SEGMENTED_20": return net.minecraft.server.v1_12_R1.BossBattle.BarStyle.NOTCHED_20;
}
}
}
@@ -0,0 +1,103 @@
package pers.xanadu.enderdragon.nms.BossBar.v1_13_R1;
import net.minecraft.server.v1_13_R1.BossBattle;
import net.minecraft.server.v1_13_R1.BossBattleServer;
import org.bukkit.World;
import org.bukkit.configuration.InvalidConfigurationException;
import org.bukkit.configuration.file.YamlConfiguration;
import org.bukkit.craftbukkit.v1_13_R1.util.CraftChatMessage;
import pers.xanadu.enderdragon.config.Lang;
import pers.xanadu.enderdragon.nms.BossBar.I_BossBarManager;
import java.io.File;
import java.io.IOException;
import java.lang.reflect.Field;
import java.util.List;
import static pers.xanadu.enderdragon.EnderDragon.getInstance;
import static pers.xanadu.enderdragon.EnderDragon.plugin;
public class BossBarManager implements I_BossBarManager {
private Field BossBattleServer = null;
public void saveBossBarData(List<World> worlds){
File file = new File(plugin.getDataFolder(),"world_data.yml");
YamlConfiguration yml = new YamlConfiguration();
worlds.forEach(world -> {
try{
Object edb = getInstance().getNMSManager().getEnderDragonBattle(world);
if(BossBattleServer == null) BossBattleServer = edb.getClass().getDeclaredField("c");
BossBattleServer.setAccessible(true);
BossBattleServer bbs = (BossBattleServer) BossBattleServer.get(edb);
String path = world.getName() + yml.options().pathSeparator();
yml.set(path+"title",bbs.title.getText());
yml.set(path+"color",bbs.color.name());
yml.set(path+"style",bbs.style.name());
}catch (ReflectiveOperationException e){
e.printStackTrace();
}
});
try{
yml.save(file);
Lang.info("BossBar data has been saved!");
}catch (IOException e){
Lang.error("Failed to save world_data!");
}
}
public void loadBossBarData(List<World> worlds){
File file = new File(plugin.getDataFolder(),"world_data.yml");
if(!file.exists()) return;
Lang.info("Enabling BossBar fix...");
YamlConfiguration yml = new YamlConfiguration();
try{
yml.load(file);
}catch (InvalidConfigurationException | IOException e) {
Lang.error("Failed to load world_data!");
return;
}
worlds.forEach(world -> {
try{
Object edb = getInstance().getNMSManager().getEnderDragonBattle(world);
if(BossBattleServer == null) BossBattleServer = edb.getClass().getDeclaredField("c");
BossBattleServer.setAccessible(true);
BossBattleServer bbs = (BossBattleServer) BossBattleServer.get(edb);
String path = world.getName()+".";
bbs.title = CraftChatMessage.fromString(yml.getString(path+"title"), true)[0];
bbs.color = BossBattle.BarColor.valueOf(yml.getString(path+"color"));
bbs.style = BossBattle.BarStyle.valueOf(yml.getString(path+"style"));
}catch (ReflectiveOperationException e){
e.printStackTrace();
}
});
}
public void setBossBar(World world,String title,String color,String style){
BossBattleServer bbs = new BossBattleServer(
CraftChatMessage.fromString(title, true)[0],
convertColor(color),
convertStyle(style)
);
bbs.setCreateFog(true);
bbs.setDarkenSky(true);
bbs.setPlayMusic(true);
try{
Object edb = getInstance().getNMSManager().getEnderDragonBattle(world);
if(BossBattleServer == null) BossBattleServer = edb.getClass().getDeclaredField("c");
BossBattleServer.setAccessible(true);
BossBattleServer.set(edb,bbs);
}catch (ReflectiveOperationException e){
e.printStackTrace();
}
}
private BossBattle.BarColor convertColor(String color) {
return BossBattle.BarColor.valueOf(color);
}
private BossBattle.BarStyle convertStyle(String style) {
switch (style) {
case "SOLID":
default: return net.minecraft.server.v1_13_R1.BossBattle.BarStyle.PROGRESS;
case "SEGMENTED_6": return net.minecraft.server.v1_13_R1.BossBattle.BarStyle.NOTCHED_6;
case "SEGMENTED_10": return net.minecraft.server.v1_13_R1.BossBattle.BarStyle.NOTCHED_10;
case "SEGMENTED_12": return net.minecraft.server.v1_13_R1.BossBattle.BarStyle.NOTCHED_12;
case "SEGMENTED_20": return net.minecraft.server.v1_13_R1.BossBattle.BarStyle.NOTCHED_20;
}
}
}
@@ -0,0 +1,103 @@
package pers.xanadu.enderdragon.nms.BossBar.v1_13_R2;
import net.minecraft.server.v1_13_R2.BossBattle;
import net.minecraft.server.v1_13_R2.BossBattleServer;
import org.bukkit.World;
import org.bukkit.configuration.InvalidConfigurationException;
import org.bukkit.configuration.file.YamlConfiguration;
import org.bukkit.craftbukkit.v1_13_R2.util.CraftChatMessage;
import pers.xanadu.enderdragon.config.Lang;
import pers.xanadu.enderdragon.nms.BossBar.I_BossBarManager;
import java.io.File;
import java.io.IOException;
import java.lang.reflect.Field;
import java.util.List;
import static pers.xanadu.enderdragon.EnderDragon.getInstance;
import static pers.xanadu.enderdragon.EnderDragon.plugin;
public class BossBarManager implements I_BossBarManager {
private Field BossBattleServer = null;
public void saveBossBarData(List<World> worlds){
File file = new File(plugin.getDataFolder(),"world_data.yml");
YamlConfiguration yml = new YamlConfiguration();
worlds.forEach(world -> {
try{
Object edb = getInstance().getNMSManager().getEnderDragonBattle(world);
if(BossBattleServer == null) BossBattleServer = edb.getClass().getDeclaredField("bossBattle");
BossBattleServer.setAccessible(true);
BossBattleServer bbs = (BossBattleServer) BossBattleServer.get(edb);
String path = world.getName() + yml.options().pathSeparator();
yml.set(path+"title",bbs.title.getText());
yml.set(path+"color",bbs.color.name());
yml.set(path+"style",bbs.style.name());
}catch (ReflectiveOperationException e){
e.printStackTrace();
}
});
try{
yml.save(file);
Lang.info("BossBar data has been saved!");
}catch (IOException e){
Lang.error("Failed to save world_data!");
}
}
public void loadBossBarData(List<World> worlds){
File file = new File(plugin.getDataFolder(),"world_data.yml");
if(!file.exists()) return;
Lang.info("Enabling BossBar fix...");
YamlConfiguration yml = new YamlConfiguration();
try{
yml.load(file);
}catch (InvalidConfigurationException | IOException e) {
Lang.error("Failed to load world_data!");
return;
}
worlds.forEach(world -> {
try{
Object edb = getInstance().getNMSManager().getEnderDragonBattle(world);
if(BossBattleServer == null) BossBattleServer = edb.getClass().getDeclaredField("bossBattle");
BossBattleServer.setAccessible(true);
BossBattleServer bbs = (BossBattleServer) BossBattleServer.get(edb);
String path = world.getName() + yml.options().pathSeparator();
bbs.title = CraftChatMessage.fromString(yml.getString(path+"title"), true)[0];
bbs.color = BossBattle.BarColor.valueOf(yml.getString(path+"color"));
bbs.style = BossBattle.BarStyle.valueOf(yml.getString(path+"style"));
}catch (ReflectiveOperationException e){
e.printStackTrace();
}
});
}
public void setBossBar(World world,String title,String color,String style){
BossBattleServer bbs = new BossBattleServer(
CraftChatMessage.fromString(title, true)[0],
convertColor(color),
convertStyle(style)
);
bbs.setCreateFog(true);
bbs.setDarkenSky(true);
bbs.setPlayMusic(true);
try{
Object edb = getInstance().getNMSManager().getEnderDragonBattle(world);
if(BossBattleServer == null) BossBattleServer = edb.getClass().getField("bossBattle");
BossBattleServer.setAccessible(true);
BossBattleServer.set(edb,bbs);
}catch (ReflectiveOperationException e){
e.printStackTrace();
}
}
private BossBattle.BarColor convertColor(String color) {
return BossBattle.BarColor.valueOf(color);
}
private BossBattle.BarStyle convertStyle(String style) {
switch (style) {
case "SOLID":
default: return net.minecraft.server.v1_13_R2.BossBattle.BarStyle.PROGRESS;
case "SEGMENTED_6": return net.minecraft.server.v1_13_R2.BossBattle.BarStyle.NOTCHED_6;
case "SEGMENTED_10": return net.minecraft.server.v1_13_R2.BossBattle.BarStyle.NOTCHED_10;
case "SEGMENTED_12": return net.minecraft.server.v1_13_R2.BossBattle.BarStyle.NOTCHED_12;
case "SEGMENTED_20": return net.minecraft.server.v1_13_R2.BossBattle.BarStyle.NOTCHED_20;
}
}
}
@@ -0,0 +1,11 @@
package pers.xanadu.enderdragon.nms.NMSItem;
import org.bukkit.inventory.ItemStack;
public interface I_NMSItemManager {
ItemStack readAsItem(String nbt);
ItemStack cpdToItem(Object cpd);
Object parseNBT(Object nbt_base);
Object readAsNBTBase(String raw);
Object getNBTBase(Object obj);
}
@@ -0,0 +1,146 @@
package pers.xanadu.enderdragon.nms.NMSItem.v1_12_R1;
import net.minecraft.server.v1_12_R1.*;
import java.lang.reflect.Constructor;
import java.lang.reflect.Method;
import java.util.*;
import java.util.regex.Pattern;
public class CraftNBTTagConfigSerializer {
private static final Pattern ARRAY = Pattern.compile("^\\[.*]");
private static final Pattern INTEGER = Pattern.compile("[-+]?(?:0|[1-9][0-9]*)?i", 2);
private static final Pattern DOUBLE = Pattern.compile("[-+]?(?:[0-9]+[.]?|[0-9]*[.][0-9]+)(?:e[-+]?[0-9]+)?d", 2);
private static final Pattern byte_format = Pattern.compile("[-+]?(?:0|[1-9][0-9]*)b", 2);
private static final Pattern short_format = Pattern.compile("[-+]?(?:0|[1-9][0-9]*)s", 2);
private static final Pattern integer_format = Pattern.compile("[-+]?(?:0|[1-9][0-9]*)");
private static final Pattern long_format = Pattern.compile("[-+]?(?:0|[1-9][0-9]*)l", 2);
private static final Pattern float_format = Pattern.compile("[-+]?(?:[0-9]+[.]?|[0-9]*[.][0-9]+)(?:e[-+]?[0-9]+)?f", 2);
private static final Pattern double_format = Pattern.compile("[-+]?(?:[0-9]+[.]?|[0-9]*[.][0-9]+)(?:e[-+]?[0-9]+)?d", 2);
private static final Pattern double_format2 = Pattern.compile("[-+]?(?:[0-9]+[.]|[0-9]*[.][0-9]+)(?:e[-+]?[0-9]+)?", 2);
public CraftNBTTagConfigSerializer() {
}
public static Object serialize(NBTBase base) {
if (base instanceof NBTTagCompound) {
Map<String, Object> innerMap = new HashMap();
for (String key : ((NBTTagCompound) base).c()) {
innerMap.put(key, serialize(((NBTTagCompound) base).get(key)));
}
return innerMap;
}
if (base instanceof NBTTagString) {
return ((NBTTagString) base).c_();
}
else {
return base instanceof NBTTagInt ? base + "i" : base.toString();
}
}
public static NBTBase deserialize(Object object) {
if (object instanceof Map) {
NBTTagCompound compound = new NBTTagCompound();
for (Object obj : ((Map) object).entrySet()) {
Map.Entry<String, Object> entry = (Map.Entry) obj;
compound.set(entry.getKey(), deserialize(entry.getValue()));
}
return compound;
} else if (!(object instanceof List)) {
if (object instanceof String) {
String string = (String)object;
if (ARRAY.matcher(string).matches()) {
try {
Constructor<MojangsonParser> constructor = MojangsonParser.class.getDeclaredConstructor(String.class);
MojangsonParser parser = constructor.newInstance(string);
Method parseArray = MojangsonParser.class.getDeclaredMethod("k");
parseArray.setAccessible(true);
return (NBTBase) parseArray.invoke(parser);
} catch (Throwable e) {
throw new RuntimeException("Could not deserialize found list ", e);
}
} else if (INTEGER.matcher(string).matches()) {
return new NBTTagInt(Integer.parseInt(string.substring(0, string.length() - 1)));
} else if (DOUBLE.matcher(string).matches()) {
return new NBTTagDouble(Double.parseDouble(string.substring(0, string.length() - 1)));
} else {
try{
Constructor<MojangsonParser> constructor = MojangsonParser.class.getDeclaredConstructor(String.class);
MojangsonParser parser = constructor.newInstance("");
Method parseLiteral = MojangsonParser.class.getDeclaredMethod("c", String.class);
parseLiteral.setAccessible(true);
NBTBase nbtBase = (NBTBase) parseLiteral.invoke(parser,string);
if (nbtBase instanceof NBTTagInt) {
return new NBTTagString(nbtBase.toString());
} else {
return (nbtBase instanceof NBTTagDouble ? new NBTTagString(String.valueOf(((NBTTagDouble)nbtBase).asDouble())) : nbtBase);
}
}catch (ReflectiveOperationException e){
throw new RuntimeException("Could not deserialize NBTBase");
}
}
} else {
throw new RuntimeException("Could not deserialize NBTBase");
}
} else {
List<Object> list = (List)object;
if (list.isEmpty()) {
return new NBTTagList();
}
else {
NBTTagList tagList = new NBTTagList();
for (Object tag : list) {
tagList.add(deserialize(tag));
}
return tagList;
}
}
}
public static NBTBase v1_12_R1_c(String raw) {
try {
if (float_format.matcher(raw).matches()) {
return new NBTTagFloat(Float.parseFloat(raw.substring(0, raw.length() - 1)));
}
if (byte_format.matcher(raw).matches()) {
return new NBTTagByte(Byte.parseByte(raw.substring(0, raw.length() - 1)));
}
if (long_format.matcher(raw).matches()) {
return new NBTTagLong(Long.parseLong(raw.substring(0, raw.length() - 1)));
}
if (short_format.matcher(raw).matches()) {
return new NBTTagShort(Short.parseShort(raw.substring(0, raw.length() - 1)));
}
if (integer_format.matcher(raw).matches()) {
return new NBTTagInt(Integer.parseInt(raw));
}
if (double_format.matcher(raw).matches()) {
return new NBTTagDouble(Double.parseDouble(raw.substring(0, raw.length() - 1)));
}
if (double_format2.matcher(raw).matches()) {
return new NBTTagDouble(Double.parseDouble(raw));
}
if ("true".equalsIgnoreCase(raw)) {
return new NBTTagByte((byte)1);
}
if ("false".equalsIgnoreCase(raw)) {
return new NBTTagByte((byte)0);
}
} catch (NumberFormatException e) {
e.printStackTrace();
}
return new NBTTagString(raw);
}
}
@@ -0,0 +1,35 @@
package pers.xanadu.enderdragon.nms.NMSItem.v1_12_R1;
import net.minecraft.server.v1_12_R1.*;
import org.bukkit.Material;
import org.bukkit.craftbukkit.v1_12_R1.inventory.CraftItemStack;
import pers.xanadu.enderdragon.config.Lang;
import pers.xanadu.enderdragon.nms.NMSItem.I_NMSItemManager;
public class NMSItemManager implements I_NMSItemManager {
public org.bukkit.inventory.ItemStack readAsItem(String nbt){
try {
NBTTagCompound cpd = MojangsonParser.parse(nbt);
ItemStack ei = new ItemStack(cpd);
return CraftItemStack.asBukkitCopy(ei);
} catch (MojangsonParseException e) {
Lang.error("Wrong item nbt format:"+nbt);
return new org.bukkit.inventory.ItemStack(Material.AIR);
}
}
public org.bukkit.inventory.ItemStack cpdToItem(Object cpd){
ItemStack ei = new ItemStack((NBTTagCompound) cpd);
return CraftItemStack.asBukkitCopy(ei);
}
public Object parseNBT(Object nbt_base){
return CraftNBTTagConfigSerializer.serialize((NBTBase) nbt_base);
}
public Object readAsNBTBase(String raw){
return CraftNBTTagConfigSerializer.v1_12_R1_c(raw);
}
public Object getNBTBase(Object obj){
return CraftNBTTagConfigSerializer.deserialize(obj);
}
}
@@ -0,0 +1,151 @@
package pers.xanadu.enderdragon.nms.NMSItem.v1_13_R1;
import com.mojang.brigadier.StringReader;
import net.minecraft.server.v1_13_R1.*;
import java.lang.reflect.Method;
import java.util.*;
import java.util.regex.Pattern;
public class CraftNBTTagConfigSerializer {
private static final Pattern ARRAY = Pattern.compile("^\\[.*]");
private static final Pattern INTEGER = Pattern.compile("[-+]?(?:0|[1-9][0-9]*)?i", 2);
private static final Pattern DOUBLE = Pattern.compile("[-+]?(?:[0-9]+[.]?|[0-9]*[.][0-9]+)(?:e[-+]?[0-9]+)?d", 2);
public static final MojangsonParser MOJANGSON_PARSER = new MojangsonParser(new StringReader(""));
private static final Pattern byte_format = Pattern.compile("[-+]?(?:0|[1-9][0-9]*)b", 2);
private static final Pattern short_format = Pattern.compile("[-+]?(?:0|[1-9][0-9]*)s", 2);
private static final Pattern integer_format = Pattern.compile("[-+]?(?:0|[1-9][0-9]*)");
private static final Pattern long_format = Pattern.compile("[-+]?(?:0|[1-9][0-9]*)l", 2);
private static final Pattern float_format = Pattern.compile("[-+]?(?:[0-9]+[.]?|[0-9]*[.][0-9]+)(?:e[-+]?[0-9]+)?f", 2);
private static final Pattern double_format = Pattern.compile("[-+]?(?:[0-9]+[.]?|[0-9]*[.][0-9]+)(?:e[-+]?[0-9]+)?d", 2);
private static final Pattern double_format_2 = Pattern.compile("[-+]?(?:[0-9]+[.]|[0-9]*[.][0-9]+)(?:e[-+]?[0-9]+)?", 2);
public CraftNBTTagConfigSerializer() {
}
public static Object serialize(NBTBase base) {
if (base instanceof NBTTagCompound) {
Map<String, Object> innerMap = new HashMap();
Iterator var3 = ((NBTTagCompound)base).getKeys().iterator();
while(var3.hasNext()) {
String key = (String)var3.next();
innerMap.put(key, serialize(((NBTTagCompound)base).get(key)));
}
return innerMap;
} else if (!(base instanceof NBTTagList)) {
if (base instanceof NBTTagString) {
return base.b_();
} else {
return base instanceof NBTTagInt ? base + "i" : base.toString();
}
} else {
List<Object> baseList = new ArrayList();
for(int i = 0; i < ((NBTList)base).size(); ++i) {
baseList.add(serialize(((NBTList)base).get(i)));
}
return baseList;
}
}
public static NBTBase v1_13_R1_b(String str) {
try {
if (float_format.matcher(str).matches()) {
return new NBTTagFloat(Float.parseFloat(str.substring(0, str.length() - 1)));
}
if (byte_format.matcher(str).matches()) {
return new NBTTagByte(Byte.parseByte(str.substring(0, str.length() - 1)));
}
if (long_format.matcher(str).matches()) {
return new NBTTagLong(Long.parseLong(str.substring(0, str.length() - 1)));
}
if (short_format.matcher(str).matches()) {
return new NBTTagShort(Short.parseShort(str.substring(0, str.length() - 1)));
}
if (integer_format.matcher(str).matches()) {
return new NBTTagInt(Integer.parseInt(str));
}
if (double_format.matcher(str).matches()) {
return new NBTTagDouble(Double.parseDouble(str.substring(0, str.length() - 1)));
}
if (double_format_2.matcher(str).matches()) {
return new NBTTagDouble(Double.parseDouble(str));
}
if ("true".equalsIgnoreCase(str)) {
return new NBTTagByte((byte)1);
}
if ("false".equalsIgnoreCase(str)) {
return new NBTTagByte((byte)0);
}
} catch (NumberFormatException e) {
e.printStackTrace();
}
return new NBTTagString(str);
}
public static NBTBase deserialize(Object object) {
if (object instanceof Map) {
NBTTagCompound compound = new NBTTagCompound();
for (Object obj : ((Map) object).entrySet()) {
Map.Entry<String, Object> entry = (Map.Entry) obj;
compound.set(entry.getKey(), deserialize(entry.getValue()));
}
return compound;
} else if (!(object instanceof List)) {
if (object instanceof String) {
String string = (String)object;
if (ARRAY.matcher(string).matches()) {
try {
Method parseArray = MojangsonParser.class.getDeclaredMethod("h");
parseArray.setAccessible(true);
MojangsonParser parser = new MojangsonParser(new StringReader(string));
return (NBTBase) parseArray.invoke(parser);
} catch (Throwable e) {
throw new RuntimeException("Could not deserialize found list ", e);
}
} else if (INTEGER.matcher(string).matches()) {
return new NBTTagInt(Integer.parseInt(string.substring(0, string.length() - 1)));
} else if (DOUBLE.matcher(string).matches()) {
return new NBTTagDouble(Double.parseDouble(string.substring(0, string.length() - 1)));
} else {
try{
Method parseLiteral = MojangsonParser.class.getDeclaredMethod("b", String.class);
parseLiteral.setAccessible(true);
NBTBase nbtBase = (NBTBase) parseLiteral.invoke(MOJANGSON_PARSER,string);
if (nbtBase instanceof NBTTagInt) {
return new NBTTagString(nbtBase.b_());
} else {
return (nbtBase instanceof NBTTagDouble ? new NBTTagString(String.valueOf(((NBTTagDouble)nbtBase).asDouble())) : nbtBase);
}
}catch (ReflectiveOperationException e){
throw new RuntimeException("Could not deserialize NBTBase");
}
}
} else {
throw new RuntimeException("Could not deserialize NBTBase");
}
} else {
List<Object> list = (List)object;
if (list.isEmpty()) {
return new NBTTagList();
} else {
NBTTagList tagList = new NBTTagList();
for (Object tag : list) {
tagList.add(deserialize(tag));
}
return tagList;
}
}
}
}
@@ -0,0 +1,37 @@
package pers.xanadu.enderdragon.nms.NMSItem.v1_13_R1;
import com.mojang.brigadier.exceptions.CommandSyntaxException;
import net.minecraft.server.v1_13_R1.ItemStack;
import net.minecraft.server.v1_13_R1.MojangsonParser;
import net.minecraft.server.v1_13_R1.NBTBase;
import net.minecraft.server.v1_13_R1.NBTTagCompound;
import org.bukkit.Material;
import org.bukkit.craftbukkit.v1_13_R1.inventory.CraftItemStack;
import pers.xanadu.enderdragon.config.Lang;
import pers.xanadu.enderdragon.nms.NMSItem.I_NMSItemManager;
public class NMSItemManager implements I_NMSItemManager {
public org.bukkit.inventory.ItemStack readAsItem(String nbt){
try {
NBTTagCompound cpd = MojangsonParser.parse(nbt);
ItemStack ei = ItemStack.a(cpd);
return CraftItemStack.asBukkitCopy(ei);
} catch (CommandSyntaxException e) {
Lang.error("Wrong item nbt format:"+nbt);
return new org.bukkit.inventory.ItemStack(Material.AIR);
}
}
public org.bukkit.inventory.ItemStack cpdToItem(Object cpd){
ItemStack ei = ItemStack.a((NBTTagCompound) cpd);
return CraftItemStack.asBukkitCopy(ei);
}
public Object parseNBT(Object nbt_base){
return CraftNBTTagConfigSerializer.serialize((NBTBase) nbt_base);
}
public Object readAsNBTBase(String raw){
return CraftNBTTagConfigSerializer.v1_13_R1_b(raw);
}
public Object getNBTBase(Object obj){
return CraftNBTTagConfigSerializer.deserialize(obj);
}
}
@@ -0,0 +1,30 @@
package pers.xanadu.enderdragon.nms.NMSItem.v1_13_R2_above;
import org.bukkit.Material;
import org.bukkit.inventory.ItemStack;
import pers.xanadu.enderdragon.EnderDragon;
import pers.xanadu.enderdragon.config.Lang;
import pers.xanadu.enderdragon.nms.NMSItem.I_NMSItemManager;
public class NMSItemManager implements I_NMSItemManager {
public ItemStack readAsItem(String nbt){
try {
return EnderDragon.getInstance().getNMSManager().getItemStack(nbt);
} catch (Throwable e) {
Lang.error("Wrong item nbt format:"+nbt);
return new org.bukkit.inventory.ItemStack(Material.AIR);
}
}
public ItemStack cpdToItem(Object cpd){
return EnderDragon.getInstance().getNMSManager().getItemStack(cpd);
}
public Object parseNBT(Object nbt_base){
return EnderDragon.getInstance().getNMSManager().serializeNBTBase(nbt_base);
}
public Object readAsNBTBase(String raw){
return EnderDragon.getInstance().getNMSManager().StringParseLiteral(raw);
}
public Object getNBTBase(Object obj){
return EnderDragon.getInstance().getNMSManager().deserializeObject(obj);
}
}
@@ -0,0 +1,7 @@
package pers.xanadu.enderdragon.nms.RespawnAnchor;
import org.bukkit.World;
public interface I_RespawnAnchorManager {
boolean isRespawnAnchorWorks(World world);
}
@@ -0,0 +1,15 @@
package pers.xanadu.enderdragon.nms.RespawnAnchor.v1_16_R1;
import net.minecraft.server.v1_16_R1.DimensionManager;
import org.bukkit.World;
import org.bukkit.craftbukkit.v1_16_R1.CraftWorld;
import pers.xanadu.enderdragon.nms.RespawnAnchor.I_RespawnAnchorManager;
public class RespawnAnchorManager implements I_RespawnAnchorManager {
public boolean isRespawnAnchorWorks(World world){
CraftWorld cw = (CraftWorld) world;
net.minecraft.server.v1_16_R1.World ew = cw.getHandle();
DimensionManager dm = ew.getDimensionManager();
return dm.isRespawnAnchorWorks();
}
}
@@ -0,0 +1,15 @@
package pers.xanadu.enderdragon.nms.RespawnAnchor.v1_16_R2;
import net.minecraft.server.v1_16_R2.DimensionManager;
import org.bukkit.World;
import org.bukkit.craftbukkit.v1_16_R2.CraftWorld;
import pers.xanadu.enderdragon.nms.RespawnAnchor.I_RespawnAnchorManager;
public class RespawnAnchorManager implements I_RespawnAnchorManager {
public boolean isRespawnAnchorWorks(World world){
CraftWorld cw = (CraftWorld) world;
net.minecraft.server.v1_16_R2.World ew = cw.getHandle();
DimensionManager dm = ew.getDimensionManager();
return dm.isRespawnAnchorWorks();
}
}
@@ -0,0 +1,15 @@
package pers.xanadu.enderdragon.nms.RespawnAnchor.v1_16_R3;
import net.minecraft.server.v1_16_R3.DimensionManager;
import org.bukkit.World;
import org.bukkit.craftbukkit.v1_16_R3.CraftWorld;
import pers.xanadu.enderdragon.nms.RespawnAnchor.I_RespawnAnchorManager;
public class RespawnAnchorManager implements I_RespawnAnchorManager {
public boolean isRespawnAnchorWorks(World world){
CraftWorld cw = (CraftWorld) world;
net.minecraft.server.v1_16_R3.World ew = cw.getHandle();
DimensionManager dm = ew.getDimensionManager();
return dm.isRespawnAnchorWorks();
}
}
@@ -0,0 +1,15 @@
package pers.xanadu.enderdragon.nms.RespawnAnchor.v1_17_R1;
import net.minecraft.world.level.dimension.DimensionManager;
import org.bukkit.World;
import org.bukkit.craftbukkit.v1_17_R1.CraftWorld;
import pers.xanadu.enderdragon.nms.RespawnAnchor.I_RespawnAnchorManager;
public class RespawnAnchorManager implements I_RespawnAnchorManager {
public boolean isRespawnAnchorWorks(World world){
CraftWorld cw = (CraftWorld) world;
net.minecraft.world.level.World ew = cw.getHandle();
DimensionManager dm = ew.getDimensionManager();
return dm.isRespawnAnchorWorks();
}
}
@@ -0,0 +1,10 @@
package pers.xanadu.enderdragon.nms.RespawnAnchor.v1_18_above;
import org.bukkit.World;
import pers.xanadu.enderdragon.nms.RespawnAnchor.I_RespawnAnchorManager;
public class RespawnAnchorManager implements I_RespawnAnchorManager {
public boolean isRespawnAnchorWorks(World world){
return world.isRespawnAnchorWorks();
}
}
@@ -0,0 +1,7 @@
package pers.xanadu.enderdragon.nms.WorldData;
import org.bukkit.World;
public interface I_WorldDataManager {
long getGameTime(World world);
}
@@ -0,0 +1,14 @@
package pers.xanadu.enderdragon.nms.WorldData.v1_12_R1;
import net.minecraft.server.v1_12_R1.WorldServer;
import org.bukkit.World;
import org.bukkit.craftbukkit.v1_12_R1.CraftWorld;
import pers.xanadu.enderdragon.nms.WorldData.I_WorldDataManager;
public class WorldDataManager implements I_WorldDataManager {
public long getGameTime(World world){
CraftWorld cw = (CraftWorld) world;
WorldServer ws = cw.getHandle();
return ws.getTime();
}
}
@@ -0,0 +1,14 @@
package pers.xanadu.enderdragon.nms.WorldData.v1_13_R1;
import net.minecraft.server.v1_13_R1.WorldServer;
import org.bukkit.World;
import org.bukkit.craftbukkit.v1_13_R1.CraftWorld;
import pers.xanadu.enderdragon.nms.WorldData.I_WorldDataManager;
public class WorldDataManager implements I_WorldDataManager {
public long getGameTime(World world){
CraftWorld cw = (CraftWorld) world;
WorldServer ws = cw.getHandle();
return ws.getTime();
}
}
@@ -0,0 +1,14 @@
package pers.xanadu.enderdragon.nms.WorldData.v1_13_R2;
import net.minecraft.server.v1_13_R2.WorldServer;
import org.bukkit.World;
import org.bukkit.craftbukkit.v1_13_R2.CraftWorld;
import pers.xanadu.enderdragon.nms.WorldData.I_WorldDataManager;
public class WorldDataManager implements I_WorldDataManager {
public long getGameTime(World world){
CraftWorld cw = (CraftWorld) world;
WorldServer ws = cw.getHandle();
return ws.getTime();
}
}
@@ -0,0 +1,14 @@
package pers.xanadu.enderdragon.nms.WorldData.v1_14_R1;
import net.minecraft.server.v1_14_R1.WorldServer;
import org.bukkit.World;
import org.bukkit.craftbukkit.v1_14_R1.CraftWorld;
import pers.xanadu.enderdragon.nms.WorldData.I_WorldDataManager;
public class WorldDataManager implements I_WorldDataManager {
public long getGameTime(World world){
CraftWorld cw = (CraftWorld) world;
WorldServer ws = cw.getHandle();
return ws.getTime();
}
}
@@ -0,0 +1,14 @@
package pers.xanadu.enderdragon.nms.WorldData.v1_15_R1;
import net.minecraft.server.v1_15_R1.WorldServer;
import org.bukkit.World;
import org.bukkit.craftbukkit.v1_15_R1.CraftWorld;
import pers.xanadu.enderdragon.nms.WorldData.I_WorldDataManager;
public class WorldDataManager implements I_WorldDataManager {
public long getGameTime(World world){
CraftWorld cw = (CraftWorld) world;
WorldServer ws = cw.getHandle();
return ws.getTime();
}
}
@@ -0,0 +1,14 @@
package pers.xanadu.enderdragon.nms.WorldData.v1_16_R1;
import net.minecraft.server.v1_16_R1.WorldServer;
import org.bukkit.World;
import org.bukkit.craftbukkit.v1_16_R1.CraftWorld;
import pers.xanadu.enderdragon.nms.WorldData.I_WorldDataManager;
public class WorldDataManager implements I_WorldDataManager {
public long getGameTime(World world){
CraftWorld cw = (CraftWorld) world;
WorldServer ws = cw.getHandle();
return ws.getTime();
}
}
@@ -0,0 +1,14 @@
package pers.xanadu.enderdragon.nms.WorldData.v1_16_R2;
import net.minecraft.server.v1_16_R2.WorldServer;
import org.bukkit.World;
import org.bukkit.craftbukkit.v1_16_R2.CraftWorld;
import pers.xanadu.enderdragon.nms.WorldData.I_WorldDataManager;
public class WorldDataManager implements I_WorldDataManager {
public long getGameTime(World world){
CraftWorld cw = (CraftWorld) world;
WorldServer ws = cw.getHandle();
return ws.getTime();
}
}
@@ -0,0 +1,14 @@
package pers.xanadu.enderdragon.nms.WorldData.v1_16_R3;
import net.minecraft.server.v1_16_R3.WorldServer;
import org.bukkit.World;
import org.bukkit.craftbukkit.v1_16_R3.CraftWorld;
import pers.xanadu.enderdragon.nms.WorldData.I_WorldDataManager;
public class WorldDataManager implements I_WorldDataManager {
public long getGameTime(World world){
CraftWorld cw = (CraftWorld) world;
WorldServer ws = cw.getHandle();
return ws.getTime();
}
}
@@ -0,0 +1,10 @@
package pers.xanadu.enderdragon.nms.WorldData.v1_17_above;
import org.bukkit.World;
import pers.xanadu.enderdragon.nms.WorldData.I_WorldDataManager;
public class WorldDataManager implements I_WorldDataManager {
public long getGameTime(World world){
return world.getGameTime();
}
}