2016-06-12 19:43:41 +02:00
package me.libraryaddict.disguise ;
2017-06-22 18:14:19 +02:00
import com.comphenix.protocol.reflect.FieldAccessException ;
import com.comphenix.protocol.wrappers.WrappedDataWatcher ;
import com.comphenix.protocol.wrappers.WrappedWatchableObject ;
import me.libraryaddict.disguise.commands.* ;
import me.libraryaddict.disguise.disguisetypes.* ;
2017-06-08 17:06:58 +02:00
import me.libraryaddict.disguise.disguisetypes.watchers.* ;
2017-06-11 23:36:54 +02:00
import me.libraryaddict.disguise.utilities.* ;
2016-06-12 19:43:41 +02:00
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 ;
2017-06-22 18:14:19 +02:00
import org.bukkit.entity.* ;
2016-06-12 19:43:41 +02:00
import org.bukkit.plugin.java.JavaPlugin ;
2017-06-22 18:14:19 +02:00
import java.io.File ;
import java.lang.reflect.Field ;
import java.util.ArrayList ;
2017-07-10 18:02:24 +02:00
import java.util.Collection ;
2017-06-22 18:14:19 +02:00
import java.util.HashMap ;
import java.util.HashSet ;
2016-06-12 19:43:41 +02:00
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 ( ) {
2016-11-30 18:38:43 +01:00
instance = this ;
2017-07-10 18:02:24 +02:00
2016-11-30 18:38:43 +01:00
saveDefaultConfig ( ) ;
2017-06-25 21:36:09 +02:00
getLogger ( ) . info ( " Discovered nms version: " + ReflectionManager . getBukkitVersion ( ) ) ;
2016-06-12 19:43:41 +02:00
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
2017-07-10 18:02:24 +02:00
LibsPremium . check ( instance ) ;
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 ( ) ) ;
2017-02-19 15:53:03 +01:00
registerCommand ( " disguisemodify " , new DisguiseModifyCommand ( ) ) ;
registerCommand ( " disguisemodifyentity " , new DisguiseModifyEntityCommand ( ) ) ;
registerCommand ( " disguisemodifyplayer " , new DisguiseModifyPlayerCommand ( ) ) ;
2017-04-15 06:22:17 +02:00
registerCommand ( " disguisemodifyradius " ,
new DisguiseModifyRadiusCommand ( getConfig ( ) . getInt ( " DisguiseRadiusMax " ) ) ) ;
2016-06-12 19:43:41 +02:00
2017-06-22 18:14:19 +02:00
infectWithMetrics ( ) ;
}
private void infectWithMetrics ( ) {
Metrics metrics = new Metrics ( this ) ;
final String premium = LibsPremium . isPremium ( ) ?
getDescription ( ) . getVersion ( ) . contains ( " SNAPSHOT " ) ? " Paid Builds " : " Paid Plugin " : " Free Builds " ;
metrics . addCustomChart ( new Metrics . SimplePie ( " premium " ) {
@Override
public String getValue ( ) {
return premium ;
}
} ) ;
metrics . addCustomChart ( new Metrics . SimplePie ( " translations " ) {
@Override
public String getValue ( ) {
return LibsPremium . isPremium ( ) & & DisguiseConfig . isUseTranslations ( ) ? " Yes " : " No " ;
}
} ) ;
metrics . addCustomChart ( new Metrics . SimplePie ( " custom_disguises " ) {
@Override
public String getValue ( ) {
HashMap map = DisguiseConfig . getCustomDisguises ( ) ;
return map . size ( ) + ( map . containsKey ( " libraryaddict " ) ? - 1 : 0 ) > 0 ? " Yes " : " No " ;
}
} ) ;
metrics . addCustomChart ( new Metrics . MultiLineChart ( " disguised_entities " ) {
@Override
public HashMap < String , Integer > getValues ( HashMap < String , Integer > hashMap ) {
for ( HashSet < TargetedDisguise > list : DisguiseUtilities . getDisguises ( ) . values ( ) ) {
for ( Disguise disg : list ) {
if ( disg . getEntity ( ) = = null | | ! disg . isDisguiseInUse ( ) )
continue ;
String name = disg . getEntity ( ) . getType ( ) . name ( ) ;
hashMap . put ( name , hashMap . containsKey ( name ) ? hashMap . get ( name ) + 1 : 1 ) ;
}
}
return hashMap ;
}
} ) ;
metrics . addCustomChart ( new Metrics . MultiLineChart ( " disguises_used " ) {
@Override
public HashMap < String , Integer > getValues ( HashMap < String , Integer > hashMap ) {
for ( HashSet < TargetedDisguise > list : DisguiseUtilities . getDisguises ( ) . values ( ) ) {
for ( Disguise disg : list ) {
if ( disg . getEntity ( ) = = null | | ! disg . isDisguiseInUse ( ) )
continue ;
String name = disg . getType ( ) . name ( ) ;
hashMap . put ( name , hashMap . containsKey ( name ) ? hashMap . get ( name ) + 1 : 1 ) ;
}
}
return hashMap ;
}
} ) ;
2017-06-25 21:36:09 +02:00
metrics . addCustomChart ( new Metrics . SimplePie ( " disguised_using " ) {
2017-06-22 18:14:19 +02:00
@Override
public String getValue ( ) {
2017-06-25 21:36:09 +02:00
if ( DisguiseUtilities . isPluginsUsed ( ) ) {
if ( DisguiseUtilities . isCommandsUsed ( ) ) {
return " Plugins and Commands " ;
}
2017-06-22 18:14:19 +02:00
2017-06-25 21:36:09 +02:00
return " Plugins " ;
} else if ( DisguiseUtilities . isCommandsUsed ( ) ) {
return " Commands " ;
}
return " Unknown " ;
2017-06-22 18:14:19 +02:00
}
} ) ;
2017-06-25 21:36:09 +02:00
metrics . addCustomChart ( new Metrics . SimplePie ( " active_disguises " ) {
2017-06-22 18:14:19 +02:00
@Override
public String getValue ( ) {
2017-06-25 21:36:09 +02:00
int disgs = 0 ;
for ( HashSet set : DisguiseUtilities . getDisguises ( ) . values ( ) ) {
disgs + = set . size ( ) ;
}
if ( disgs = = 0 )
return " 0 " ;
if ( disgs < = 5 )
return " 1 to 5 " ;
else if ( disgs < = 15 )
return " 6 to 15 " ;
else if ( disgs < = 30 )
return " 16 to 30 " ;
return " More than 30 " ;
2017-06-22 18:14:19 +02:00
}
} ) ;
metrics . addCustomChart ( new Metrics . SimplePie ( " self_disguises " ) {
@Override
public String getValue ( ) {
return DisguiseConfig . isViewDisguises ( ) ? " Yes " : " No " ;
}
} ) ;
metrics . addCustomChart ( new Metrics . SimplePie ( " spigot " ) {
@Override
public String getValue ( ) {
try {
Class . forName ( " org.spigotmc.SpigotConfig " ) ;
return " Yes " ;
}
catch ( Exception ex ) {
return " No " ;
}
}
} ) ;
2017-06-24 14:20:19 +02:00
final boolean updates = getConfig ( ) . getBoolean ( " NotifyUpdate " ) ;
metrics . addCustomChart ( new Metrics . SimplePie ( " updates " ) {
@Override
public String getValue ( ) {
return updates ? " Enabled " : " Disabled " ;
}
} ) ;
2017-07-10 18:02:24 +02:00
metrics . addCustomChart ( new Metrics . SimplePie ( " targeted_disguises " ) {
@Override
public String getValue ( ) {
Collection < HashSet < TargetedDisguise > > list = DisguiseUtilities . getDisguises ( ) . values ( ) ;
if ( list . isEmpty ( ) )
return " Unknown " ;
for ( HashSet < TargetedDisguise > dList : list ) {
for ( TargetedDisguise disg : dList ) {
if ( disg . getObservers ( ) . isEmpty ( ) )
continue ;
return " Yes " ;
}
}
return " No " ;
}
} ) ;
2016-06-12 19:43:41 +02:00
}
2017-06-02 15:51:03 +02:00
@Override
public void onDisable ( ) {
DisguiseUtilities . saveDisguises ( ) ;
}
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
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 ;
}
2017-06-08 17:06:58 +02:00
Class watcherClass ;
2016-06-12 19:43:41 +02:00
2016-11-25 13:07:02 +01:00
try {
switch ( disguiseType ) {
2017-04-15 06:22:17 +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 :
case HUSK :
watcherClass = ZombieWatcher . class ;
break ;
case MAGMA_CUBE :
watcherClass = SlimeWatcher . class ;
break ;
case ELDER_GUARDIAN :
watcherClass = GuardianWatcher . class ;
break ;
case WITHER_SKELETON :
case STRAY :
watcherClass = SkeletonWatcher . class ;
break ;
2017-06-08 17:06:58 +02:00
case ILLUSIONER :
case EVOKER :
watcherClass = IllagerWizardWatcher . class ;
break ;
2017-04-15 06:22:17 +02:00
default :
watcherClass = Class . forName ( " me.libraryaddict.disguise.disguisetypes.watchers. " + toReadable (
disguiseType . name ( ) ) + " Watcher " ) ;
break ;
2016-06-12 19:43:41 +02:00
}
}
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 ;
2017-04-15 06:22:17 +02:00
} else if ( Ageable . class . isAssignableFrom ( entityClass ) ) {
2016-06-12 19:43:41 +02:00
watcherClass = AgeableWatcher . class ;
2017-04-15 06:22:17 +02:00
} else if ( Creature . class . isAssignableFrom ( entityClass ) ) {
2016-06-12 19:43:41 +02:00
watcherClass = InsentientWatcher . class ;
2017-04-15 06:22:17 +02:00
} else if ( LivingEntity . class . isAssignableFrom ( entityClass ) ) {
2016-06-12 19:43:41 +02:00
watcherClass = LivingWatcher . class ;
2017-04-15 06:22:17 +02:00
} else {
2016-06-12 19:43:41 +02:00
watcherClass = FlagWatcher . class ;
}
2017-04-15 06:22:17 +02: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 ) {
2017-04-15 06:22:17 +02:00
case WITHER_SKELETON :
case ZOMBIE_VILLAGER :
case DONKEY :
case MULE :
case ZOMBIE_HORSE :
case SKELETON_HORSE :
case STRAY :
case HUSK :
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 " ;
2017-06-08 17:06:58 +02:00
break ;
case ILLUSIONER :
nmsEntityName = " IllagerIllusioner " ;
break ;
2017-04-15 06:22:17 +02:00
default :
break ;
2016-06-12 19:43:41 +02:00
}
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 ) ;
2017-06-08 23:14:36 +02:00
ArrayList < MetaIndex > indexes = MetaIndex . getFlags ( disguiseType . getWatcherClass ( ) ) ;
2016-06-12 19:43:41 +02:00
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 ) {
2017-06-22 13:36:45 +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 ( ) ) ;
2016-06-12 19:43:41 +02:00
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
2017-06-08 23:14:36 +02:00
indexes . remove ( flagType ) ;
2017-07-10 18:02:24 +02:00
Object obj1 = ReflectionManager . convertInvalidItem ( flagType . getDefault ( ) ) ;
Object obj2 = ReflectionManager . convertInvalidItem ( watch . getValue ( ) ) ;
if ( obj1 ! = obj2 & & ( ( obj1 = = null | | obj2 = = null ) | | obj1 . getClass ( ) ! = obj2 . getClass ( ) ) ) {
System . err . println ( " Mismatch of " + " FlagType's for " + disguiseType . name ( ) + " ! Index " + watch
2017-06-22 13:36:45 +02:00
. getIndex ( ) + " has the wrong classtype! " ) ;
2017-07-10 18:02:24 +02:00
System . err . println (
" MetaIndex has the " + " default of " + flagType . getDefault ( ) + " ( " + flagType
. getDefault ( ) . getClass ( ) + " ) ( " + nmsEntity . getClass ( ) + " ) & " + watcherClass
. getSimpleName ( ) ) ;
System . err . println ( " Where the internals is " + watch . getRawValue ( ) + " ( " + watch . getRawValue ( )
. getClass ( ) ) ;
2016-11-26 16:36:57 +01:00
System . err . println ( " Lib's Disguises will continue to load, but this will not work properly! " ) ;
}
2016-06-12 19:43:41 +02:00
}
2017-06-08 23:14:36 +02:00
for ( MetaIndex index : indexes ) {
2017-06-22 13:36:45 +02:00
System . out . println ( disguiseType + " has MetaIndex remaining! " + index . getFlagWatcher ( )
. getSimpleName ( ) + " at index " + index . getIndex ( ) ) ;
2017-06-08 23:14:36 +02:00
}
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 ) ) ;
2017-04-15 06:22:17 +02: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 ) {
2017-06-22 13:36:45 +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-12 19:43:41 +02:00
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 ;
}
}