2016-06-12 19:43:41 +02:00
package me.libraryaddict.disguise ;
2016-11-30 18:38:43 +01:00
import java.io.File ;
2016-06-12 19:43:41 +02:00
import java.io.IOException ;
import java.lang.reflect.Field ;
import org.bukkit.Bukkit ;
2016-11-28 15:01:06 +01:00
import org.bukkit.command.CommandExecutor ;
import org.bukkit.command.PluginCommand ;
import org.bukkit.command.TabCompleter ;
2016-06-12 19:43:41 +02:00
import org.bukkit.entity.Ageable ;
import org.bukkit.entity.Creature ;
import org.bukkit.entity.Damageable ;
import org.bukkit.entity.Entity ;
import org.bukkit.entity.LivingEntity ;
import org.bukkit.entity.Tameable ;
import org.bukkit.entity.Zombie ;
import org.bukkit.event.HandlerList ;
import org.bukkit.plugin.java.JavaPlugin ;
import com.comphenix.protocol.reflect.FieldAccessException ;
import com.comphenix.protocol.wrappers.WrappedDataWatcher ;
import com.comphenix.protocol.wrappers.WrappedWatchableObject ;
2016-11-28 22:47:48 +01:00
import me.libraryaddict.disguise.commands.DisguiseCloneCommand ;
2016-06-12 19:43:41 +02:00
import me.libraryaddict.disguise.commands.DisguiseCommand ;
2016-11-28 22:47:48 +01:00
import me.libraryaddict.disguise.commands.DisguiseEntityCommand ;
2016-11-30 05:08:12 +01:00
import me.libraryaddict.disguise.commands.DisguiseHelpCommand ;
2016-11-28 22:47:48 +01:00
import me.libraryaddict.disguise.commands.DisguisePlayerCommand ;
import me.libraryaddict.disguise.commands.DisguiseRadiusCommand ;
2016-11-30 05:08:12 +01:00
import me.libraryaddict.disguise.commands.DisguiseViewSelfCommand ;
import me.libraryaddict.disguise.commands.LibsDisguisesCommand ;
2016-06-12 19:43:41 +02:00
import me.libraryaddict.disguise.commands.UndisguiseCommand ;
import me.libraryaddict.disguise.commands.UndisguiseEntityCommand ;
import me.libraryaddict.disguise.commands.UndisguisePlayerCommand ;
import me.libraryaddict.disguise.commands.UndisguiseRadiusCommand ;
import me.libraryaddict.disguise.disguisetypes.DisguiseType ;
2017-02-06 18:12:00 +01:00
import me.libraryaddict.disguise.disguisetypes.MetaIndex ;
2016-06-12 19:43:41 +02:00
import me.libraryaddict.disguise.disguisetypes.FlagWatcher ;
import me.libraryaddict.disguise.disguisetypes.watchers.AgeableWatcher ;
import me.libraryaddict.disguise.disguisetypes.watchers.ArrowWatcher ;
import me.libraryaddict.disguise.disguisetypes.watchers.GuardianWatcher ;
import me.libraryaddict.disguise.disguisetypes.watchers.InsentientWatcher ;
import me.libraryaddict.disguise.disguisetypes.watchers.LivingWatcher ;
import me.libraryaddict.disguise.disguisetypes.watchers.MinecartWatcher ;
import me.libraryaddict.disguise.disguisetypes.watchers.SkeletonWatcher ;
import me.libraryaddict.disguise.disguisetypes.watchers.SlimeWatcher ;
import me.libraryaddict.disguise.disguisetypes.watchers.SpiderWatcher ;
import me.libraryaddict.disguise.disguisetypes.watchers.TNTWatcher ;
import me.libraryaddict.disguise.disguisetypes.watchers.TameableWatcher ;
import me.libraryaddict.disguise.disguisetypes.watchers.ZombieWatcher ;
import me.libraryaddict.disguise.utilities.DisguiseSound ;
import me.libraryaddict.disguise.utilities.DisguiseUtilities ;
import me.libraryaddict.disguise.utilities.DisguiseValues ;
import me.libraryaddict.disguise.utilities.FakeBoundingBox ;
import me.libraryaddict.disguise.utilities.Metrics ;
import me.libraryaddict.disguise.utilities.PacketsManager ;
import me.libraryaddict.disguise.utilities.ReflectionManager ;
2016-11-25 13:07:02 +01:00
public class LibsDisguises extends JavaPlugin {
2016-06-12 19:43:41 +02:00
private static LibsDisguises instance ;
private DisguiseListener listener ;
@Override
2016-11-25 13:07:02 +01:00
public void onEnable ( ) {
try {
2016-07-08 12:23:11 +02:00
Class . forName ( " com.comphenix.protocol.wrappers.Vector3F " ) . getName ( ) ;
}
2016-11-25 13:07:02 +01:00
catch ( Exception ex ) {
2016-07-08 12:23:11 +02:00
System . err . println ( " [LibsDisguises] Lib's Disguises failed to startup, outdated ProtocolLib! " ) ;
System . err . println (
" [LibsDisguises] You need to update ProtocolLib, please try this build http://ci.dmulloy2.net/job/ProtocolLib/lastStableBuild/artifact/modules/ProtocolLib/target/ProtocolLib.jar " ) ;
return ;
}
2016-11-25 13:07:02 +01:00
try {
2016-11-30 05:08:12 +01:00
ReflectionManager . getNmsClass ( " EntityEvoker " ) . getName ( ) ;
2016-07-08 12:23:11 +02:00
}
2016-11-25 13:07:02 +01:00
catch ( Exception ex ) {
2016-07-08 12:23:11 +02:00
System . err . println ( " [LibsDisguises] Lib's Disguises failed to startup, outdated server! " ) ;
System . err . println ( " [LibsDisguises] This plugin does not offer backwards support! " ) ;
return ;
}
2016-11-30 18:38:43 +01:00
instance = this ;
saveDefaultConfig ( ) ;
2016-06-12 19:43:41 +02:00
getLogger ( ) . info ( " Discovered MC version: " + ReflectionManager . getBukkitVersion ( ) ) ;
2016-11-30 18:38:43 +01:00
if ( ! new File ( getDataFolder ( ) , " disguises.yml " ) . exists ( ) ) {
saveResource ( " disguises.yml " , false ) ;
}
2016-06-12 19:43:41 +02:00
PacketsManager . init ( this ) ;
DisguiseUtilities . init ( this ) ;
2016-11-30 18:38:43 +01:00
registerValues ( ) ;
2016-06-12 19:43:41 +02:00
DisguiseConfig . initConfig ( getConfig ( ) ) ;
PacketsManager . addPacketListeners ( ) ;
listener = new DisguiseListener ( this ) ;
Bukkit . getPluginManager ( ) . registerEvents ( listener , this ) ;
2016-11-28 15:01:06 +01:00
registerCommand ( " disguise " , new DisguiseCommand ( ) ) ;
registerCommand ( " undisguise " , new UndisguiseCommand ( ) ) ;
2016-11-28 22:47:48 +01:00
registerCommand ( " disguiseplayer " , new DisguisePlayerCommand ( ) ) ;
2016-11-28 15:01:06 +01:00
registerCommand ( " undisguiseplayer " , new UndisguisePlayerCommand ( ) ) ;
registerCommand ( " undisguiseentity " , new UndisguiseEntityCommand ( ) ) ;
2016-11-28 22:47:48 +01:00
registerCommand ( " disguiseentity " , new DisguiseEntityCommand ( ) ) ;
registerCommand ( " disguiseradius " , new DisguiseRadiusCommand ( getConfig ( ) . getInt ( " DisguiseRadiusMax " ) ) ) ;
2016-11-28 15:01:06 +01:00
registerCommand ( " undisguiseradius " , new UndisguiseRadiusCommand ( getConfig ( ) . getInt ( " UndisguiseRadiusMax " ) ) ) ;
registerCommand ( " disguisehelp " , new DisguiseHelpCommand ( ) ) ;
2016-11-28 22:47:48 +01:00
registerCommand ( " disguiseclone " , new DisguiseCloneCommand ( ) ) ;
2016-11-28 15:01:06 +01:00
registerCommand ( " libsdisguises " , new LibsDisguisesCommand ( ) ) ;
2016-11-28 22:47:48 +01:00
registerCommand ( " disguiseviewself " , new DisguiseViewSelfCommand ( ) ) ;
2016-06-12 19:43:41 +02:00
2016-11-25 13:07:02 +01:00
try {
2016-06-12 19:43:41 +02:00
Metrics metrics = new Metrics ( this ) ;
metrics . start ( ) ;
}
2016-11-25 13:07:02 +01:00
catch ( IOException e ) {
2016-06-12 19:43:41 +02:00
}
}
2016-11-28 15:01:06 +01:00
private void registerCommand ( String commandName , CommandExecutor executioner ) {
PluginCommand command = getCommand ( commandName ) ;
command . setExecutor ( executioner ) ;
if ( executioner instanceof TabCompleter ) {
command . setTabCompleter ( ( TabCompleter ) executioner ) ;
}
}
2016-06-12 19:43:41 +02:00
/ * *
* Reloads the config with new config options .
* /
2016-11-25 13:07:02 +01:00
public void reload ( ) {
2016-06-12 19:43:41 +02:00
HandlerList . unregisterAll ( listener ) ;
reloadConfig ( ) ;
DisguiseConfig . initConfig ( getConfig ( ) ) ;
}
/ * *
* Here we create a nms entity for each disguise . Then grab their default values in their datawatcher . Then their sound volume
* for mob noises . As well as setting their watcher class and entity size .
* /
2016-11-25 13:07:02 +01:00
private void registerValues ( ) {
for ( DisguiseType disguiseType : DisguiseType . values ( ) ) {
if ( disguiseType . getEntityType ( ) = = null ) {
2016-06-12 19:43:41 +02:00
continue ;
}
Class watcherClass = null ;
2016-11-25 13:07:02 +01:00
try {
switch ( disguiseType ) {
2016-06-12 19:43:41 +02:00
case SPECTRAL_ARROW :
watcherClass = ArrowWatcher . class ;
break ;
case PRIMED_TNT :
watcherClass = TNTWatcher . class ;
break ;
case MINECART_CHEST :
case MINECART_COMMAND :
case MINECART_FURNACE :
case MINECART_HOPPER :
case MINECART_MOB_SPAWNER :
case MINECART_TNT :
watcherClass = MinecartWatcher . class ;
break ;
case SPIDER :
case CAVE_SPIDER :
watcherClass = SpiderWatcher . class ;
break ;
case ZOMBIE_VILLAGER :
case PIG_ZOMBIE :
2016-06-12 20:24:14 +02:00
case HUSK :
2016-06-12 19:43:41 +02:00
watcherClass = ZombieWatcher . class ;
break ;
case MAGMA_CUBE :
watcherClass = SlimeWatcher . class ;
break ;
case ELDER_GUARDIAN :
watcherClass = GuardianWatcher . class ;
break ;
case WITHER_SKELETON :
2016-06-12 20:24:14 +02:00
case STRAY :
2016-06-12 19:43:41 +02:00
watcherClass = SkeletonWatcher . class ;
break ;
default :
watcherClass = Class . forName (
" me.libraryaddict.disguise.disguisetypes.watchers. " + toReadable ( disguiseType . name ( ) ) + " Watcher " ) ;
break ;
}
}
2016-11-25 13:07:02 +01:00
catch ( ClassNotFoundException ex ) {
2016-06-12 19:43:41 +02:00
// There is no explicit watcher for this entity.
Class entityClass = disguiseType . getEntityType ( ) . getEntityClass ( ) ;
2016-11-25 13:07:02 +01:00
if ( entityClass ! = null ) {
if ( Tameable . class . isAssignableFrom ( entityClass ) ) {
2016-06-12 19:43:41 +02:00
watcherClass = TameableWatcher . class ;
}
2016-11-25 13:07:02 +01:00
else if ( Ageable . class . isAssignableFrom ( entityClass ) ) {
2016-06-12 19:43:41 +02:00
watcherClass = AgeableWatcher . class ;
}
2016-11-25 13:07:02 +01:00
else if ( Creature . class . isAssignableFrom ( entityClass ) ) {
2016-06-12 19:43:41 +02:00
watcherClass = InsentientWatcher . class ;
}
2016-11-25 13:07:02 +01:00
else if ( LivingEntity . class . isAssignableFrom ( entityClass ) ) {
2016-06-12 19:43:41 +02:00
watcherClass = LivingWatcher . class ;
}
2016-11-25 13:07:02 +01:00
else {
2016-06-12 19:43:41 +02:00
watcherClass = FlagWatcher . class ;
}
}
2016-11-25 13:07:02 +01:00
else {
2016-06-12 19:43:41 +02:00
watcherClass = FlagWatcher . class ; // Disguise is unknown type
}
}
2016-11-25 13:07:02 +01:00
if ( watcherClass = = null ) {
2016-06-12 19:43:41 +02:00
System . err . println ( " Error loading " + disguiseType . name ( ) + " , FlagWatcher not assigned " ) ;
continue ;
}
disguiseType . setWatcherClass ( watcherClass ) ;
2016-11-25 13:07:02 +01:00
if ( DisguiseValues . getDisguiseValues ( disguiseType ) ! = null ) {
2016-06-12 19:43:41 +02:00
continue ;
}
String nmsEntityName = toReadable ( disguiseType . name ( ) ) ;
2016-11-25 13:07:02 +01:00
switch ( disguiseType ) {
2016-06-12 19:43:41 +02:00
case WITHER_SKELETON :
case ZOMBIE_VILLAGER :
case DONKEY :
case MULE :
2016-11-26 16:36:57 +01:00
case ZOMBIE_HORSE :
2016-06-12 19:43:41 +02:00
case SKELETON_HORSE :
2016-06-12 20:24:14 +02:00
case STRAY :
case HUSK :
2016-06-12 19:43:41 +02:00
continue ;
case PRIMED_TNT :
nmsEntityName = " TNTPrimed " ;
break ;
case MINECART_TNT :
nmsEntityName = " MinecartTNT " ;
break ;
case MINECART :
nmsEntityName = " MinecartRideable " ;
break ;
case FIREWORK :
nmsEntityName = " Fireworks " ;
break ;
case SPLASH_POTION :
nmsEntityName = " Potion " ;
break ;
case GIANT :
nmsEntityName = " GiantZombie " ;
break ;
case DROPPED_ITEM :
nmsEntityName = " Item " ;
break ;
case FIREBALL :
nmsEntityName = " LargeFireball " ;
break ;
case LEASH_HITCH :
nmsEntityName = " Leash " ;
break ;
case ELDER_GUARDIAN :
nmsEntityName = " Guardian " ;
break ;
case ARROW :
case SPECTRAL_ARROW :
nmsEntityName = " TippedArrow " ;
default :
break ;
}
2016-11-25 13:07:02 +01:00
try {
if ( nmsEntityName . equalsIgnoreCase ( " Unknown " ) ) {
2016-06-12 19:43:41 +02:00
DisguiseValues disguiseValues = new DisguiseValues ( disguiseType , null , 0 , 0 ) ;
disguiseValues . setAdultBox ( new FakeBoundingBox ( 0 , 0 , 0 ) ) ;
DisguiseSound sound = DisguiseSound . getType ( disguiseType . name ( ) ) ;
2016-11-25 13:07:02 +01:00
if ( sound ! = null ) {
2016-06-12 19:43:41 +02:00
sound . setDamageAndIdleSoundVolume ( 1f ) ;
}
continue ;
}
Object nmsEntity = ReflectionManager . createEntityInstance ( nmsEntityName ) ;
2016-11-25 13:07:02 +01:00
if ( nmsEntity = = null ) {
2016-06-12 19:43:41 +02:00
getLogger ( ) . warning ( " Entity not found! ( " + nmsEntityName + " ) " ) ;
continue ;
}
Entity bukkitEntity = ReflectionManager . getBukkitEntity ( nmsEntity ) ;
int entitySize = 0 ;
2016-11-25 13:07:02 +01:00
for ( Field field : ReflectionManager . getNmsClass ( " Entity " ) . getFields ( ) ) {
if ( field . getType ( ) . getName ( ) . equals ( " EnumEntitySize " ) ) {
2016-06-12 19:43:41 +02:00
Enum enumEntitySize = ( Enum ) field . get ( nmsEntity ) ;
entitySize = enumEntitySize . ordinal ( ) ;
break ;
}
}
DisguiseValues disguiseValues = new DisguiseValues ( disguiseType , nmsEntity . getClass ( ) , entitySize ,
bukkitEntity instanceof Damageable ? ( ( Damageable ) bukkitEntity ) . getMaxHealth ( ) : 0 ) ;
WrappedDataWatcher watcher = WrappedDataWatcher . getEntityWatcher ( bukkitEntity ) ;
2016-11-25 13:07:02 +01:00
for ( WrappedWatchableObject watch : watcher . getWatchableObjects ( ) ) {
2017-02-06 18:12:00 +01:00
MetaIndex flagType = MetaIndex . getFlag ( watcherClass , watch . getIndex ( ) ) ;
2016-06-12 19:43:41 +02:00
2016-11-25 13:07:02 +01:00
if ( flagType = = null ) {
2016-06-12 19:43:41 +02:00
System . err . println ( " Error finding the FlagType for " + disguiseType . name ( ) + " ! Index " + watch . getIndex ( )
+ " can't be found! " ) ;
System . err . println ( " Value is " + watch . getRawValue ( ) + " ( " + watch . getRawValue ( ) . getClass ( ) + " ) ( "
+ nmsEntity . getClass ( ) + " ) & " + watcherClass . getSimpleName ( ) ) ;
System . err . println ( " Lib's Disguises will continue to load, but this will not work properly! " ) ;
continue ;
}
2016-11-26 16:36:57 +01:00
if ( ReflectionManager . convertInvalidItem ( flagType . getDefault ( ) ) . getClass ( ) ! = ReflectionManager
. convertInvalidItem ( watch . getValue ( ) ) . getClass ( ) ) {
System . err . println ( " Mismatch of FlagType's for " + disguiseType . name ( ) + " ! Index " + watch . getIndex ( )
+ " has the wrong classtype! " ) ;
System . err . println ( " Value is " + watch . getRawValue ( ) + " ( " + watch . getRawValue ( ) . getClass ( ) + " ) ( "
+ nmsEntity . getClass ( ) + " ) & " + watcherClass . getSimpleName ( ) + " which doesn't match up with "
+ flagType . getDefault ( ) . getClass ( ) ) ;
System . err . println ( " Lib's Disguises will continue to load, but this will not work properly! " ) ;
continue ;
}
2016-06-12 19:43:41 +02:00
}
DisguiseSound sound = DisguiseSound . getType ( disguiseType . name ( ) ) ;
2016-11-25 13:07:02 +01:00
if ( sound ! = null ) {
2016-06-12 19:43:41 +02:00
Float soundStrength = ReflectionManager . getSoundModifier ( nmsEntity ) ;
2016-11-25 13:07:02 +01:00
if ( soundStrength ! = null ) {
2016-06-12 19:43:41 +02:00
sound . setDamageAndIdleSoundVolume ( soundStrength ) ;
}
}
// Get the bounding box
disguiseValues . setAdultBox ( ReflectionManager . getBoundingBox ( bukkitEntity ) ) ;
2016-11-25 13:07:02 +01:00
if ( bukkitEntity instanceof Ageable ) {
2016-06-12 19:43:41 +02:00
( ( Ageable ) bukkitEntity ) . setBaby ( ) ;
disguiseValues . setBabyBox ( ReflectionManager . getBoundingBox ( bukkitEntity ) ) ;
}
2016-11-25 13:07:02 +01:00
else if ( bukkitEntity instanceof Zombie ) {
2016-06-12 19:43:41 +02:00
( ( Zombie ) bukkitEntity ) . setBaby ( true ) ;
disguiseValues . setBabyBox ( ReflectionManager . getBoundingBox ( bukkitEntity ) ) ;
}
disguiseValues . setEntitySize ( ReflectionManager . getSize ( bukkitEntity ) ) ;
}
2016-11-25 13:07:02 +01:00
catch ( SecurityException | IllegalArgumentException | IllegalAccessException | FieldAccessException ex ) {
2016-06-12 19:43:41 +02:00
System . out . print (
" [LibsDisguises] Uh oh! Trouble while making values for the disguise " + disguiseType . name ( ) + " ! " ) ;
System . out . print ( " [LibsDisguises] Before reporting this error, "
+ " please make sure you are using the latest version of LibsDisguises and ProtocolLib. " ) ;
System . out . print ( " [LibsDisguises] Development builds are available at (ProtocolLib) "
+ " http://ci.dmulloy2.net/job/ProtocolLib/ and (LibsDisguises) http://server.o2gaming.com:8080/job/LibsDisguises%201.9+/ " ) ;
2016-06-18 17:16:32 +02:00
ex . printStackTrace ( ) ;
2016-06-12 19:43:41 +02:00
}
}
}
2016-11-25 13:07:02 +01:00
private String toReadable ( String string ) {
2016-06-12 19:43:41 +02:00
StringBuilder builder = new StringBuilder ( ) ;
2016-11-25 13:07:02 +01:00
for ( String s : string . split ( " _ " ) ) {
2016-06-12 19:43:41 +02:00
builder . append ( s . substring ( 0 , 1 ) ) . append ( s . substring ( 1 ) . toLowerCase ( ) ) ;
}
return builder . toString ( ) ;
}
2016-11-25 13:07:02 +01:00
public DisguiseListener getListener ( ) {
2016-06-12 19:43:41 +02:00
return listener ;
}
/ * *
* External APIs shouldn ' t actually need this instance . DisguiseAPI should be enough to handle most cases .
*
* @return The instance of this plugin
* /
2016-11-25 13:07:02 +01:00
public static LibsDisguises getInstance ( ) {
2016-06-12 19:43:41 +02:00
return instance ;
}
}