2016-07-27 12:27:09 +00:00
/ * *
* Created on 17 May 2014 by _MylesC
* Copyright 2014
* /
package pw.yumc.Yum.inject ;
import java.io.File ;
import java.lang.reflect.Field ;
import java.lang.reflect.Modifier ;
import java.util.Iterator ;
import java.util.Map ;
import java.util.Map.Entry ;
import java.util.Set ;
import java.util.logging.Level ;
import java.util.regex.Pattern ;
import org.bukkit.Bukkit ;
import org.bukkit.Server ;
import org.bukkit.event.Event ;
import org.bukkit.event.Listener ;
import org.bukkit.plugin.InvalidDescriptionException ;
import org.bukkit.plugin.InvalidPluginException ;
import org.bukkit.plugin.Plugin ;
import org.bukkit.plugin.PluginDescriptionFile ;
import org.bukkit.plugin.PluginLoader ;
import org.bukkit.plugin.PluginManager ;
import org.bukkit.plugin.RegisteredListener ;
import org.bukkit.plugin.UnknownDependencyException ;
2016-07-28 07:59:08 +00:00
import org.bukkit.plugin.java.JavaPlugin ;
2016-07-27 12:27:09 +00:00
import org.bukkit.plugin.java.JavaPluginLoader ;
public class YumPluginLoader implements PluginLoader {
2016-07-28 07:59:08 +00:00
private static boolean isInit = false ;
private static final String needRestart = "§6[§bYum§6] §c由于修改了服务器内部文件 §bYum §c无法直接重载 §4请重启服务器!" ;
private static final YumPluginLoader yumPluginLoader = new YumPluginLoader ( Bukkit . getServer ( ) ) ;
2016-07-27 12:27:09 +00:00
private final JavaPluginLoader internal_loader ;
private final Server server ;
@SuppressWarnings ( "deprecation" )
public YumPluginLoader ( final Server instance ) {
server = instance ;
internal_loader = new JavaPluginLoader ( instance ) ;
}
2016-07-28 07:59:08 +00:00
public static void inject ( ) {
injectExistingPlugins ( yumPluginLoader ) ;
replaceJavaPluginLoaders ( yumPluginLoader ) ;
}
2016-08-05 02:21:54 +00:00
public static void inject ( final String pname ) {
injectExistingPlugin ( Bukkit . getPluginManager ( ) . getPlugin ( pname ) , yumPluginLoader ) ;
replaceJavaPluginLoaders ( yumPluginLoader ) ;
}
private static void injectExistingPlugin ( final Plugin p , final YumPluginLoader yumPluginLoader ) {
if ( p ! = null & & p instanceof JavaPlugin ) {
final JavaPlugin jp = ( JavaPlugin ) p ;
try {
final Field f = JavaPlugin . class . getDeclaredField ( "loader" ) ;
f . setAccessible ( true ) ;
f . set ( jp , yumPluginLoader ) ;
} catch ( final Exception e ) {
Bukkit . getServer ( ) . getLogger ( ) . log ( Level . SEVERE , "Yum failed injecting " + jp . getDescription ( ) . getFullName ( ) + " with the new PluginLoader, contact the developers on YUMC!" , e ) ;
}
}
}
2016-07-28 07:59:08 +00:00
private static void injectExistingPlugins ( final YumPluginLoader yumPluginLoader ) {
for ( final org . bukkit . plugin . Plugin p : Bukkit . getPluginManager ( ) . getPlugins ( ) ) {
2016-08-05 02:21:54 +00:00
injectExistingPlugin ( p , yumPluginLoader ) ;
2016-07-28 07:59:08 +00:00
}
}
private static void replaceJavaPluginLoaders ( final YumPluginLoader yumPluginLoader ) {
2016-07-27 12:27:09 +00:00
final PluginManager spm = Bukkit . getPluginManager ( ) ;
try {
final Field field = spm . getClass ( ) . getDeclaredField ( "fileAssociations" ) ;
field . setAccessible ( true ) ;
final Field modifiersField = Field . class . getDeclaredField ( "modifiers" ) ;
modifiersField . setAccessible ( true ) ;
modifiersField . setInt ( field , field . getModifiers ( ) & ~ Modifier . FINAL ) ;
@SuppressWarnings ( "unchecked" )
final Map < Pattern , PluginLoader > map = ( Map < Pattern , PluginLoader > ) field . get ( spm ) ;
final Iterator < Map . Entry < Pattern , PluginLoader > > iter = map . entrySet ( ) . iterator ( ) ;
while ( iter . hasNext ( ) ) {
final Entry < Pattern , PluginLoader > entry = iter . next ( ) ;
2016-08-05 02:21:54 +00:00
entry . setValue ( yumPluginLoader ) ;
2016-07-27 12:27:09 +00:00
}
field . set ( spm , map ) ;
} catch ( final Exception e ) {
Bukkit . getServer ( ) . getLogger ( ) . log ( Level . SEVERE , "Yum failed replacing the existing PluginLoader, contact the developers on YUMC!" , e ) ;
}
}
@Override
public Map < Class < ? extends Event > , Set < RegisteredListener > > createRegisteredListeners ( final Listener listener , final Plugin plugin ) {
return internal_loader . createRegisteredListeners ( listener , plugin ) ;
}
@Override
public void disablePlugin ( final Plugin plugin ) {
2016-07-28 07:59:08 +00:00
if ( plugin . getName ( ) . equalsIgnoreCase ( "Yum" ) ) {
Bukkit . getConsoleSender ( ) . sendMessage ( needRestart ) ;
} else {
2016-07-27 12:27:09 +00:00
internal_loader . disablePlugin ( plugin ) ;
}
}
@Override
2016-07-28 07:59:08 +00:00
public void enablePlugin ( final Plugin plugin ) {
if ( plugin . getName ( ) . equalsIgnoreCase ( "Yum" ) ) {
if ( isInit ) {
Bukkit . getConsoleSender ( ) . sendMessage ( needRestart ) ;
} else {
internal_loader . enablePlugin ( plugin ) ;
isInit = true ;
}
} else {
internal_loader . enablePlugin ( plugin ) ;
}
2016-07-27 12:27:09 +00:00
}
@Override
public PluginDescriptionFile getPluginDescription ( final File arg0 ) throws InvalidDescriptionException {
return internal_loader . getPluginDescription ( arg0 ) ;
}
@Override
public Pattern [ ] getPluginFileFilters ( ) {
return internal_loader . getPluginFileFilters ( ) ;
}
@Override
2016-07-28 07:59:08 +00:00
public Plugin loadPlugin ( final File file ) throws InvalidPluginException , UnknownDependencyException {
try {
final PluginDescriptionFile description = getPluginDescription ( file ) ;
if ( description . getName ( ) . equalsIgnoreCase ( "Yum" ) ) {
Bukkit . getConsoleSender ( ) . sendMessage ( needRestart ) ;
return null ;
}
} catch ( final InvalidDescriptionException ex ) {
}
return internal_loader . loadPlugin ( file ) ;
2016-07-27 12:27:09 +00:00
}
}