2017-01-30 21:22:36 +01:00
package net.ME1312.SubServers.Host ;
2018-01-21 21:45:27 +01:00
import jline.console.ConsoleReader ;
2018-03-21 21:45:59 +01:00
import net.ME1312.SubServers.Host.API.Event.* ;
2017-01-30 21:22:36 +01:00
import net.ME1312.SubServers.Host.API.SubPluginInfo ;
import net.ME1312.SubServers.Host.API.SubPlugin ;
2017-04-01 07:37:48 +02:00
import net.ME1312.SubServers.Host.Executable.SubCreator ;
import net.ME1312.SubServers.Host.Executable.SubServer ;
2017-01-30 21:22:36 +01:00
import net.ME1312.SubServers.Host.Library.Config.YAMLConfig ;
import net.ME1312.SubServers.Host.Library.Config.YAMLSection ;
import net.ME1312.SubServers.Host.Library.Exception.IllegalPluginException ;
import net.ME1312.SubServers.Host.Library.Log.FileLogger ;
import net.ME1312.SubServers.Host.Library.Log.Logger ;
2018-01-21 21:45:27 +01:00
import net.ME1312.SubServers.Host.Library.PluginClassLoader ;
2018-01-02 23:29:25 +01:00
import net.ME1312.SubServers.Host.Library.NamedContainer ;
2017-01-30 21:22:36 +01:00
import net.ME1312.SubServers.Host.Library.UniversalFile ;
import net.ME1312.SubServers.Host.Library.Util ;
import net.ME1312.SubServers.Host.Library.Version.Version ;
2018-03-21 21:45:59 +01:00
import net.ME1312.SubServers.Host.Library.Version.VersionType ;
2018-01-05 21:37:23 +01:00
import net.ME1312.SubServers.Host.Network.Cipher ;
2017-01-30 21:22:36 +01:00
import net.ME1312.SubServers.Host.Network.SubDataClient ;
2018-01-21 21:45:27 +01:00
import org.fusesource.jansi.AnsiConsole ;
2017-04-01 18:50:09 +02:00
import org.json.JSONObject ;
2017-08-18 11:58:06 +02:00
import org.w3c.dom.Document ;
import org.w3c.dom.Node ;
import org.w3c.dom.NodeList ;
import org.xml.sax.InputSource ;
2017-01-30 21:22:36 +01:00
2017-08-18 11:58:06 +02:00
import javax.xml.parsers.DocumentBuilderFactory ;
2017-04-14 04:39:51 +02:00
import java.io.* ;
2017-01-30 21:22:36 +01:00
import java.lang.reflect.InvocationTargetException ;
import java.net.InetAddress ;
import java.net.URL ;
2017-08-18 11:58:06 +02:00
import java.nio.charset.Charset ;
2017-01-30 21:22:36 +01:00
import java.nio.file.Files ;
2017-07-19 01:28:59 +02:00
import java.text.DecimalFormat ;
2017-01-30 21:22:36 +01:00
import java.util.* ;
2017-04-01 18:50:09 +02:00
import java.util.concurrent.TimeUnit ;
2018-01-21 21:45:27 +01:00
import java.util.jar.JarEntry ;
import java.util.jar.JarFile ;
2017-01-30 21:22:36 +01:00
/ * *
* SubServers . Host Main Class
* /
2017-04-16 19:02:14 +02:00
public final class ExHost {
2018-01-02 23:29:25 +01:00
protected NamedContainer < Long , Map < String , Map < String , String > > > lang = null ;
2017-05-30 21:38:51 +02:00
public HashMap < String , SubCreator . ServerTemplate > templates = new HashMap < String , SubCreator . ServerTemplate > ( ) ;
2017-04-01 07:37:48 +02:00
public HashMap < String , SubServer > servers = new HashMap < String , SubServer > ( ) ;
public SubCreator creator ;
2017-01-30 21:22:36 +01:00
public Logger log ;
public final UniversalFile dir = new UniversalFile ( new File ( System . getProperty ( " user.dir " ) ) ) ;
public YAMLConfig config ;
2017-04-01 07:37:48 +02:00
public YAMLSection host = null ;
2017-01-30 21:22:36 +01:00
public SubDataClient subdata = null ;
2018-03-14 04:38:26 +01:00
//public final Version version = new Version("2.13a");
2018-03-16 03:45:54 +01:00
//public final Version version = new Version(new Version("2.13a"), Version.VersionType.BETA, 1); // TODO Beta Version Setting
2018-03-21 21:45:59 +01:00
public final Version version = new Version ( new Version ( new Version ( " 2.13a " ) , VersionType . PRE_RELEASE , 2 ) , VersionType . BETA , 3 ) ; // TODO Beta Version Setting
2017-01-30 21:22:36 +01:00
public final SubAPI api = new SubAPI ( this ) ;
2018-01-21 21:45:27 +01:00
private ConsoleReader jline ;
2017-12-06 23:34:47 +01:00
private boolean running = false ;
private boolean ready = false ;
2017-01-30 21:22:36 +01:00
2017-02-08 01:39:18 +01:00
/ * *
* SubServers . Host Launch
*
* @param args Args
* @throws Exception
* /
2017-01-30 21:22:36 +01:00
public static void main ( String [ ] args ) throws Exception {
2018-01-12 22:56:22 +01:00
if ( System . getProperty ( " RM.subservers " , " true " ) . equalsIgnoreCase ( " true " ) ) {
2018-01-21 21:45:27 +01:00
new ExHost ( args ) ;
2018-01-12 22:56:22 +01:00
} else {
System . out . println ( " >> SubServers code has been disallowed to work on this machine " ) ;
System . out . println ( " >> Check with your provider for more information " ) ;
System . exit ( 1 ) ;
}
2017-01-30 21:22:36 +01:00
}
2018-01-21 21:45:27 +01:00
private ExHost ( String [ ] args ) {
try {
JarFile jarFile = new JarFile ( new File ( ExHost . class . getProtectionDomain ( ) . getCodeSource ( ) . getLocation ( ) . toURI ( ) ) ) ;
Enumeration < JarEntry > entries = jarFile . entries ( ) ;
boolean isplugin = false ;
while ( entries . hasMoreElements ( ) ) {
JarEntry entry = entries . nextElement ( ) ;
if ( ! entry . isDirectory ( ) & & entry . getName ( ) . endsWith ( " .class " ) ) {
api . knownClasses . add ( entry . getName ( ) . substring ( 0 , entry . getName ( ) . length ( ) - 6 ) . replace ( '/' , '.' ) ) ;
}
}
} catch ( Exception e ) {
e . printStackTrace ( ) ;
}
2017-01-30 21:22:36 +01:00
log = new Logger ( " SubServers " ) ;
try {
2018-01-21 21:45:27 +01:00
jline = new ConsoleReader ( System . in , AnsiConsole . out ( ) ) ;
Logger . setup ( AnsiConsole . out ( ) , AnsiConsole . err ( ) , jline , dir ) ;
2017-12-13 18:29:50 +01:00
log . info . println ( " Loading SubServers.Host v " + version . toString ( ) + " Libraries " ) ;
2017-01-30 21:22:36 +01:00
dir . mkdirs ( ) ;
new File ( dir , " Plugins " ) . mkdir ( ) ;
if ( ! ( new UniversalFile ( dir , " config.yml " ) . exists ( ) ) ) {
2017-04-16 19:02:14 +02:00
Util . copyFromJar ( ExHost . class . getClassLoader ( ) , " net/ME1312/SubServers/Host/Library/Files/config.yml " , new UniversalFile ( dir , " config.yml " ) . getPath ( ) ) ;
2017-02-08 01:39:18 +01:00
log . info . println ( " Created ~/config.yml " ) ;
2017-01-30 21:22:36 +01:00
} else if ( ( new Version ( ( new YAMLConfig ( new UniversalFile ( dir , " config.yml " ) ) ) . get ( ) . getSection ( " Settings " ) . getString ( " Version " , " 0 " ) ) . compareTo ( new Version ( " 2.11.2a+ " ) ) ) ! = 0 ) {
Files . move ( new UniversalFile ( dir , " config.yml " ) . toPath ( ) , new UniversalFile ( dir , " config.old " + Math . round ( Math . random ( ) * 100000 ) + " .yml " ) . toPath ( ) ) ;
2017-04-16 19:02:14 +02:00
Util . copyFromJar ( ExHost . class . getClassLoader ( ) , " net/ME1312/SubServers/Host/Library/Files/config.yml " , new UniversalFile ( dir , " config.yml " ) . getPath ( ) ) ;
2017-02-08 01:39:18 +01:00
log . info . println ( " Updated ~/config.yml " ) ;
2017-01-30 21:22:36 +01:00
}
2017-07-23 06:32:57 +02:00
config = new YAMLConfig ( new UniversalFile ( dir , " config.yml " ) ) ;
2017-04-01 07:37:48 +02:00
2018-01-21 21:45:27 +01:00
if ( ! ( new UniversalFile ( dir , " Templates " ) . exists ( ) ) ) {
new UniversalFile ( dir , " Templates " ) . mkdir ( ) ;
log . info . println ( " Created ~/Templates/ " ) ;
}
2017-04-01 18:50:09 +02:00
if ( new UniversalFile ( dir , " Recently Deleted " ) . exists ( ) ) {
int f = new UniversalFile ( dir , " Recently Deleted " ) . listFiles ( ) . length ;
for ( File file : new UniversalFile ( dir , " Recently Deleted " ) . listFiles ( ) ) {
try {
if ( file . isDirectory ( ) ) {
if ( new UniversalFile ( dir , " Recently Deleted: " + file . getName ( ) + " :info.json " ) . exists ( ) ) {
2018-03-14 08:01:44 +01:00
FileReader reader = new FileReader ( new UniversalFile ( dir , " Recently Deleted: " + file . getName ( ) + " :info.json " ) ) ;
JSONObject json = new JSONObject ( Util . readAll ( reader ) ) ;
2017-04-01 18:50:09 +02:00
if ( json . keySet ( ) . contains ( " Timestamp " ) ) {
if ( TimeUnit . MILLISECONDS . toDays ( Calendar . getInstance ( ) . getTime ( ) . getTime ( ) - json . getLong ( " Timestamp " ) ) > = 7 ) {
Util . deleteDirectory ( file ) ;
f - - ;
2017-05-30 21:38:51 +02:00
log . info . println ( " Removed ~/Recently Deleted/ " + file . getName ( ) ) ;
2017-04-01 18:50:09 +02:00
}
} else {
Util . deleteDirectory ( file ) ;
f - - ;
2017-05-30 21:38:51 +02:00
log . info . println ( " Removed ~/Recently Deleted/ " + file . getName ( ) ) ;
2017-04-01 18:50:09 +02:00
}
} else {
Util . deleteDirectory ( file ) ;
f - - ;
2017-05-30 21:38:51 +02:00
log . info . println ( " Removed ~/Recently Deleted/ " + file . getName ( ) ) ;
2017-04-01 18:50:09 +02:00
}
} else {
Files . delete ( file . toPath ( ) ) ;
f - - ;
2017-05-30 21:38:51 +02:00
log . info . println ( " Removed ~/Recently Deleted/ " + file . getName ( ) ) ;
2017-04-01 18:50:09 +02:00
}
} catch ( Exception e ) {
2017-04-03 19:52:28 +02:00
log . error . println ( e ) ;
2017-04-01 18:50:09 +02:00
}
}
if ( f < = 0 ) {
Files . delete ( new UniversalFile ( dir , " Recently Deleted " ) . toPath ( ) ) ;
}
}
2017-01-30 21:22:36 +01:00
2018-01-22 03:49:18 +01:00
/ *
* Find Jars
* /
2018-01-21 21:45:27 +01:00
UniversalFile pldir = new UniversalFile ( dir , " Plugins " ) ;
2018-02-19 23:59:51 +01:00
LinkedList < File > pljars = new LinkedList < File > ( ) ;
2018-01-22 03:49:18 +01:00
if ( pldir . exists ( ) & & pldir . isDirectory ( ) ) for ( File file : pldir . listFiles ( ) ) {
2018-02-19 23:59:51 +01:00
if ( file . getName ( ) . endsWith ( " .jar " ) ) pljars . add ( file ) ;
2018-01-22 03:49:18 +01:00
}
2018-02-19 23:59:51 +01:00
if ( pljars . size ( ) > 0 ) {
2017-01-30 21:22:36 +01:00
long begin = Calendar . getInstance ( ) . getTime ( ) . getTime ( ) ;
2017-02-08 01:39:18 +01:00
log . info . println ( " Loading SubAPI Plugins... " ) ;
2017-02-05 23:03:17 +01:00
/ *
2018-01-22 03:49:18 +01:00
* Load Jars & Find Main Classes
2018-01-21 21:45:27 +01:00
* ( Unordered )
2017-02-05 23:03:17 +01:00
* /
2018-02-19 23:59:51 +01:00
LinkedHashMap < PluginClassLoader , NamedContainer < LinkedList < String > , LinkedHashMap < String , String > > > classes = new LinkedHashMap < PluginClassLoader , NamedContainer < LinkedList < String > , LinkedHashMap < String , String > > > ( ) ;
for ( File file : pljars ) {
try {
JarFile jar = new JarFile ( file ) ;
Enumeration < JarEntry > entries = jar . entries ( ) ;
PluginClassLoader loader = new PluginClassLoader ( this . getClass ( ) . getClassLoader ( ) , file . toURI ( ) . toURL ( ) ) ;
List < String > contents = new ArrayList < String > ( ) ;
2018-01-21 21:45:27 +01:00
2018-02-19 23:59:51 +01:00
loader . setDefaultClass ( ClassNotFoundException . class ) ;
2018-03-14 04:38:26 +01:00
boolean isplugin = false ;
2018-02-19 23:59:51 +01:00
while ( entries . hasMoreElements ( ) ) {
JarEntry entry = entries . nextElement ( ) ;
if ( ! entry . isDirectory ( ) & & entry . getName ( ) . endsWith ( " .class " ) ) {
String cname = entry . getName ( ) . substring ( 0 , entry . getName ( ) . length ( ) - 6 ) . replace ( '/' , '.' ) ;
contents . add ( cname ) ;
2018-01-21 21:45:27 +01:00
try {
2018-02-19 23:59:51 +01:00
Class < ? > clazz = loader . loadClass ( cname ) ;
if ( clazz . isAnnotationPresent ( SubPlugin . class ) ) {
NamedContainer < LinkedList < String > , LinkedHashMap < String , String > > jarmap = ( classes . keySet ( ) . contains ( loader ) ) ? classes . get ( loader ) : new NamedContainer < LinkedList < String > , LinkedHashMap < String , String > > ( new LinkedList < String > ( ) , new LinkedHashMap < > ( ) ) ;
for ( String dependancy : clazz . getAnnotation ( SubPlugin . class ) . dependencies ( ) ) jarmap . name ( ) . add ( dependancy ) ;
for ( String dependancy : clazz . getAnnotation ( SubPlugin . class ) . softDependencies ( ) ) jarmap . name ( ) . add ( dependancy ) ;
jarmap . get ( ) . put ( clazz . getAnnotation ( SubPlugin . class ) . name ( ) , cname ) ;
classes . put ( loader , jarmap ) ;
isplugin = true ;
2018-01-21 21:45:27 +01:00
}
2018-02-19 23:59:51 +01:00
} catch ( Throwable e ) {
log . error . println ( new IllegalPluginException ( e , " Couldn't load class: " + cname ) ) ;
2018-01-21 21:45:27 +01:00
}
}
2018-02-19 23:59:51 +01:00
}
loader . setDefaultClass ( null ) ;
2018-01-21 21:45:27 +01:00
2018-02-19 23:59:51 +01:00
if ( ! isplugin ) {
new PluginClassLoader ( this . getClass ( ) . getClassLoader ( ) , file . toURI ( ) . toURL ( ) ) ;
log . info . println ( " Loaded Library: " + file . getName ( ) ) ;
2018-01-21 21:45:27 +01:00
}
2018-02-19 23:59:51 +01:00
api . knownClasses . addAll ( contents ) ;
jar . close ( ) ;
} catch ( Throwable e ) {
log . error . println ( new InvocationTargetException ( e , " Problem searching plugin jar: " + file . getName ( ) ) ) ;
2018-01-21 21:45:27 +01:00
}
}
/ *
* Load Main Classes & Plugin Descriptions
* ( Ordered by Known Dependencies )
* /
int progress = 1 ;
HashMap < String , SubPluginInfo > plugins = new LinkedHashMap < String , SubPluginInfo > ( ) ;
while ( classes . size ( ) > 0 ) {
2018-02-19 23:59:51 +01:00
LinkedHashMap < PluginClassLoader , LinkedList < String > > loaded = new LinkedHashMap < PluginClassLoader , LinkedList < String > > ( ) ;
for ( PluginClassLoader loader : classes . keySet ( ) ) {
2018-01-21 21:45:27 +01:00
LinkedList < String > loadedlist = new LinkedList < String > ( ) ;
2018-02-19 23:59:51 +01:00
for ( String name : classes . get ( loader ) . get ( ) . keySet ( ) ) {
2018-01-21 21:45:27 +01:00
boolean load = true ;
2018-02-19 23:59:51 +01:00
for ( String depend : classes . get ( loader ) . name ( ) ) {
2018-01-21 21:45:27 +01:00
if ( ! plugins . keySet ( ) . contains ( depend . toLowerCase ( ) ) ) {
load = progress < = 0 ;
}
}
if ( load ) {
2018-02-19 23:59:51 +01:00
String main = classes . get ( loader ) . get ( ) . get ( name ) ;
2018-01-21 21:45:27 +01:00
try {
2018-02-19 23:59:51 +01:00
Class < ? > clazz = loader . loadClass ( main ) ;
2018-01-21 21:45:27 +01:00
if ( ! clazz . isAnnotationPresent ( SubPlugin . class ) )
throw new ClassCastException ( " Cannot find plugin descriptor " ) ;
Object obj = clazz . getConstructor ( ) . newInstance ( ) ;
try {
SubPluginInfo plugin = new SubPluginInfo ( this , obj , clazz . getAnnotation ( SubPlugin . class ) . name ( ) , new Version ( clazz . getAnnotation ( SubPlugin . class ) . version ( ) ) ,
2018-01-22 03:49:18 +01:00
Arrays . asList ( clazz . getAnnotation ( SubPlugin . class ) . authors ( ) ) , ( clazz . getAnnotation ( SubPlugin . class ) . description ( ) . length ( ) > 0 ) ? clazz . getAnnotation ( SubPlugin . class ) . description ( ) : null ,
( clazz . getAnnotation ( SubPlugin . class ) . website ( ) . length ( ) > 0 ) ? new URL ( clazz . getAnnotation ( SubPlugin . class ) . website ( ) ) : null , Arrays . asList ( clazz . getAnnotation ( SubPlugin . class ) . loadBefore ( ) ) ,
2018-01-21 21:45:27 +01:00
Arrays . asList ( clazz . getAnnotation ( SubPlugin . class ) . dependencies ( ) ) , Arrays . asList ( clazz . getAnnotation ( SubPlugin . class ) . softDependencies ( ) ) ) ;
if ( plugins . keySet ( ) . contains ( plugin . getName ( ) . toLowerCase ( ) ) )
log . warn . println ( " Duplicate plugin: " + plugin . getName ( ) . toLowerCase ( ) ) ;
plugin . addExtra ( " subservers.plugin.loadafter " , new ArrayList < String > ( ) ) ;
plugins . put ( plugin . getName ( ) . toLowerCase ( ) , plugin ) ;
} catch ( Throwable e ) {
2018-01-22 03:49:18 +01:00
log . error . println ( new IllegalPluginException ( e , " Couldn't load plugin descriptor for main class: " + main ) ) ;
2018-01-21 21:45:27 +01:00
}
2018-01-22 03:49:18 +01:00
} catch ( ClassCastException e ) {
2018-01-21 21:45:27 +01:00
log . error . println ( new IllegalPluginException ( e , " Main class isn't annotated as a SubPlugin: " + main ) ) ;
2018-01-22 03:49:18 +01:00
} catch ( InvocationTargetException e ) {
2018-01-21 21:45:27 +01:00
log . error . println ( new IllegalPluginException ( e . getTargetException ( ) , " Uncaught exception occurred while loading main class: " + main ) ) ;
2018-01-22 03:49:18 +01:00
} catch ( Throwable e ) {
2018-01-21 21:45:27 +01:00
log . error . println ( new IllegalPluginException ( e , " Couldn't load main class: " + main ) ) ;
}
loadedlist . add ( name ) ;
}
}
2018-02-19 23:59:51 +01:00
if ( loadedlist . size ( ) > 0 ) loaded . put ( loader , loadedlist ) ;
2018-01-21 21:45:27 +01:00
}
progress = 0 ;
2018-02-19 23:59:51 +01:00
for ( PluginClassLoader loader : loaded . keySet ( ) ) {
NamedContainer < LinkedList < String > , LinkedHashMap < String , String > > jarmap = classes . get ( loader ) ;
2018-01-21 21:45:27 +01:00
progress + + ;
2018-02-19 23:59:51 +01:00
for ( String main : loaded . get ( loader ) ) jarmap . get ( ) . remove ( main ) ;
2018-01-21 21:45:27 +01:00
if ( jarmap . get ( ) . size ( ) > 0 ) {
2018-02-19 23:59:51 +01:00
classes . put ( loader , jarmap ) ;
2018-01-21 21:45:27 +01:00
} else {
2018-02-19 23:59:51 +01:00
classes . remove ( loader ) ;
2017-01-31 01:33:30 +01:00
}
2017-01-30 21:22:36 +01:00
}
}
2017-02-05 23:03:17 +01:00
/ *
* Load Extra Plugin Settings
* /
for ( SubPluginInfo plugin : plugins . values ( ) ) {
for ( String loadbefore : plugin . getLoadBefore ( ) ) {
if ( plugins . keySet ( ) . contains ( loadbefore . toLowerCase ( ) ) ) {
List < String > loadafter = plugins . get ( loadbefore . toLowerCase ( ) ) . getExtra ( " subservers.plugin.loadafter " ) . asRawStringList ( ) ;
loadafter . add ( plugin . getName ( ) . toLowerCase ( ) ) ;
plugins . get ( loadbefore . toLowerCase ( ) ) . addExtra ( " subservers.plugin.loadafter " , loadafter ) ;
}
}
}
/ *
* Register Plugins
2018-01-21 21:45:27 +01:00
* ( Ordered by LoadBefore & Dependencies )
2017-02-05 23:03:17 +01:00
* /
2018-01-21 21:45:27 +01:00
int i = 0 ;
2017-01-30 21:22:36 +01:00
while ( plugins . size ( ) > 0 ) {
List < String > loaded = new ArrayList < String > ( ) ;
2017-02-05 23:03:17 +01:00
for ( SubPluginInfo plugin : plugins . values ( ) ) {
2017-01-30 21:22:36 +01:00
try {
boolean load = true ;
for ( String depend : plugin . getDependancies ( ) ) {
if ( plugins . keySet ( ) . contains ( depend . toLowerCase ( ) ) ) {
load = false ;
} else if ( ! api . plugins . keySet ( ) . contains ( depend . toLowerCase ( ) ) ) {
2017-01-31 01:33:30 +01:00
throw new IllegalPluginException ( new IllegalStateException ( " Unknown dependency: " + depend ) , " Cannot meet requirements for plugin: " + plugin . getName ( ) + " v " + plugin . getVersion ( ) . toString ( ) ) ;
2017-01-30 21:22:36 +01:00
}
}
for ( String softdepend : plugin . getSoftDependancies ( ) ) {
if ( plugins . keySet ( ) . contains ( softdepend . toLowerCase ( ) ) ) {
load = false ;
}
}
2017-02-05 23:03:17 +01:00
for ( String loadafter : plugin . getExtra ( " subservers.plugin.loadafter " ) . asRawStringList ( ) ) {
if ( plugins . keySet ( ) . contains ( loadafter . toLowerCase ( ) ) ) {
load = false ;
2017-01-30 21:22:36 +01:00
}
}
2017-02-05 23:03:17 +01:00
if ( load ) try {
plugin . removeExtra ( " subservers.plugin.loadafter " ) ;
plugin . setEnabled ( true ) ;
api . addListener ( plugin , plugin . get ( ) ) ;
api . plugins . put ( plugin . getName ( ) . toLowerCase ( ) , plugin ) ;
2017-12-06 23:34:47 +01:00
api . plugins . put ( plugin . getName ( ) . toLowerCase ( ) , plugin ) ;
2017-02-05 23:03:17 +01:00
loaded . add ( plugin . getName ( ) . toLowerCase ( ) ) ;
2017-02-08 01:39:18 +01:00
log . info . println ( " Loaded " + plugin . getName ( ) + " v " + plugin . getVersion ( ) . toString ( ) + " by " + plugin . getAuthors ( ) . toString ( ) . substring ( 1 , plugin . getAuthors ( ) . toString ( ) . length ( ) - 1 ) ) ;
2017-02-05 23:03:17 +01:00
i + + ;
} catch ( Throwable e ) {
plugin . setEnabled ( false ) ;
throw new InvocationTargetException ( e , " Problem loading plugin: " + plugin . getName ( ) ) ;
}
2017-01-31 01:33:30 +01:00
} catch ( InvocationTargetException e ) {
2017-02-08 01:39:18 +01:00
log . error . println ( e ) ;
2017-02-05 23:03:17 +01:00
loaded . add ( plugin . getName ( ) . toLowerCase ( ) ) ;
2017-01-30 21:22:36 +01:00
}
}
2018-01-21 21:45:27 +01:00
progress = 0 ;
2017-01-30 21:22:36 +01:00
for ( String name : loaded ) {
2017-01-31 01:33:30 +01:00
progress + + ;
2017-01-30 21:22:36 +01:00
plugins . remove ( name ) ;
}
2017-01-31 01:33:30 +01:00
if ( progress = = 0 & & plugins . size ( ) ! = 0 ) {
2017-08-09 08:25:56 +02:00
log . error . println ( new IllegalStateException ( " Couldn't load more plugins yet " + plugins . size ( ) + " remain unloaded " ) ) ;
2017-01-31 01:33:30 +01:00
break ;
}
2017-01-30 21:22:36 +01:00
}
2017-02-05 23:03:17 +01:00
/ *
* Enable Plugins
* /
api . executeEvent ( new SubEnableEvent ( this ) ) ;
2018-01-21 21:45:27 +01:00
log . info . println ( i + " Plugin " + ( ( i = = 1 ) ? " " : " s " ) + " loaded in " + new DecimalFormat ( " 0.000 " ) . format ( ( Calendar . getInstance ( ) . getTime ( ) . getTime ( ) - begin ) / 1000D ) + " s " ) ;
2017-01-30 21:22:36 +01:00
}
2018-03-21 21:45:59 +01:00
running = true ;
Cipher cipher = null ;
if ( ! config . get ( ) . getSection ( " Settings " ) . getSection ( " SubData " ) . getRawString ( " Encryption " , " NONE " ) . equalsIgnoreCase ( " NONE " ) ) {
if ( config . get ( ) . getSection ( " Settings " ) . getSection ( " SubData " ) . getString ( " Password " , " " ) . length ( ) = = 0 ) {
log . info . println ( " Cannot encrypt connection without a password " ) ;
} else if ( ! SubDataClient . getCiphers ( ) . keySet ( ) . contains ( config . get ( ) . getSection ( " Settings " ) . getSection ( " SubData " ) . getRawString ( " Encryption " ) . toUpperCase ( ) . replace ( '-' , '_' ) . replace ( ' ' , '_' ) ) ) {
log . info . println ( " Unknown encryption type: " + config . get ( ) . getSection ( " Settings " ) . getSection ( " SubData " ) . getRawString ( " Encryption " ) ) ;
} else {
cipher = SubDataClient . getCipher ( config . get ( ) . getSection ( " Settings " ) . getSection ( " SubData " ) . getRawString ( " Encryption " ) ) ;
}
}
subdata = new SubDataClient ( this , config . get ( ) . getSection ( " Settings " ) . getSection ( " SubData " ) . getString ( " Name " , " undefined " ) ,
InetAddress . getByName ( config . get ( ) . getSection ( " Settings " ) . getSection ( " SubData " ) . getString ( " Address " , " 127.0.0.1:4391 " ) . split ( " : " ) [ 0 ] ) ,
Integer . parseInt ( config . get ( ) . getSection ( " Settings " ) . getSection ( " SubData " ) . getString ( " Address " , " 127.0.0.1:4391 " ) . split ( " : " ) [ 1 ] ) , cipher ) ;
Runtime . getRuntime ( ) . addShutdownHook ( new Thread ( ( ) - > {
if ( running ) {
log . warn . println ( " Received request from system to shutdown " ) ;
forcequit ( 0 ) ;
}
} ) ) ;
creator = new SubCreator ( this ) ;
2017-02-05 23:03:17 +01:00
loadDefaults ( ) ;
2017-08-18 11:58:06 +02:00
new Timer ( ) . schedule ( new TimerTask ( ) {
@Override
public void run ( ) {
try {
2017-12-06 23:34:47 +01:00
Document updxml = DocumentBuilderFactory . newInstance ( ) . newDocumentBuilder ( ) . parse ( new InputSource ( new StringReader ( Util . readAll ( new BufferedReader ( new InputStreamReader ( new URL ( " https://src.me1312.net/maven/net/ME1312/SubServers/SubServers.Host/maven-metadata.xml " ) . openStream ( ) , Charset . forName ( " UTF-8 " ) ) ) ) ) ) ) ;
2017-08-18 11:58:06 +02:00
NodeList updnodeList = updxml . getElementsByTagName ( " version " ) ;
Version updversion = version ;
2018-03-14 22:50:15 +01:00
int updcount = 0 ;
2017-08-18 11:58:06 +02:00
for ( int i = 0 ; i < updnodeList . getLength ( ) ; i + + ) {
Node node = updnodeList . item ( i ) ;
if ( node . getNodeType ( ) = = Node . ELEMENT_NODE ) {
2018-03-16 03:45:54 +01:00
if ( ! node . getTextContent ( ) . startsWith ( " - " ) & & ! node . getTextContent ( ) . equals ( version . toString ( ) ) & & Version . fromString ( node . getTextContent ( ) ) . compareTo ( updversion ) > 0 ) {
updversion = Version . fromString ( node . getTextContent ( ) ) ;
2017-08-18 11:58:06 +02:00
updcount + + ;
}
}
}
2018-03-14 22:50:15 +01:00
if ( updcount > 0 ) log . info . println ( " SubServers.Host v " + updversion + " is available. You are " + updcount + " version " + ( ( updcount = = 1 ) ? " " : " s " ) + " behind. " ) ;
2017-08-18 11:58:06 +02:00
} catch ( Exception e ) { }
}
} , 0 , TimeUnit . DAYS . toMillis ( 2 ) ) ;
2017-01-30 21:22:36 +01:00
loop ( ) ;
} catch ( Exception e ) {
2017-02-08 01:39:18 +01:00
log . error . println ( e ) ;
2017-12-06 23:34:47 +01:00
forcequit ( 1 ) ;
2017-01-30 21:22:36 +01:00
}
}
2017-12-14 01:04:58 +01:00
public void reload ( ) throws IOException {
if ( subdata ! = null )
subdata . destroy ( 0 ) ;
config . reload ( ) ;
2018-01-05 21:37:23 +01:00
Cipher cipher = null ;
if ( ! config . get ( ) . getSection ( " Settings " ) . getSection ( " SubData " ) . getRawString ( " Encryption " , " NONE " ) . equalsIgnoreCase ( " NONE " ) ) {
if ( config . get ( ) . getSection ( " Settings " ) . getSection ( " SubData " ) . getString ( " Password " , " " ) . length ( ) = = 0 ) {
log . info . println ( " Cannot encrypt connection without a password " ) ;
2018-01-12 22:56:22 +01:00
} else if ( ! SubDataClient . getCiphers ( ) . keySet ( ) . contains ( config . get ( ) . getSection ( " Settings " ) . getSection ( " SubData " ) . getRawString ( " Encryption " ) . toUpperCase ( ) . replace ( '-' , '_' ) . replace ( ' ' , '_' ) ) ) {
2018-01-05 21:37:23 +01:00
log . info . println ( " Unknown encryption type: " + config . get ( ) . getSection ( " Settings " ) . getSection ( " SubData " ) . getRawString ( " Encryption " ) ) ;
} else {
cipher = SubDataClient . getCipher ( config . get ( ) . getSection ( " Settings " ) . getSection ( " SubData " ) . getRawString ( " Encryption " ) ) ;
}
2017-12-14 01:04:58 +01:00
}
subdata = new SubDataClient ( this , config . get ( ) . getSection ( " Settings " ) . getSection ( " SubData " ) . getString ( " Name " , " undefined " ) ,
InetAddress . getByName ( config . get ( ) . getSection ( " Settings " ) . getSection ( " SubData " ) . getString ( " Address " , " 127.0.0.1:4391 " ) . split ( " : " ) [ 0 ] ) ,
2018-01-05 21:37:23 +01:00
Integer . parseInt ( config . get ( ) . getSection ( " Settings " ) . getSection ( " SubData " ) . getString ( " Address " , " 127.0.0.1:4391 " ) . split ( " : " ) [ 1 ] ) , cipher ) ;
2017-12-14 01:04:58 +01:00
SubAPI . getInstance ( ) . executeEvent ( new SubReloadEvent ( this ) ) ;
}
2018-01-21 21:45:27 +01:00
private void loop ( ) throws Exception {
String umsg ;
2017-12-06 23:34:47 +01:00
ready = true ;
2018-01-21 21:45:27 +01:00
while ( ready & & ( umsg = jline . readLine ( " > " ) ) ! = null ) {
if ( ! ready | | umsg . equals ( " " ) ) continue ;
2017-01-30 21:22:36 +01:00
final CommandPreProcessEvent event ;
2017-02-05 23:03:17 +01:00
api . executeEvent ( event = new CommandPreProcessEvent ( this , umsg ) ) ;
2017-01-30 21:22:36 +01:00
if ( ! event . isCancelled ( ) ) {
2017-02-05 23:03:17 +01:00
final String cmd = ( umsg . startsWith ( " / " ) ) ? ( ( umsg . contains ( " " ) ? umsg . split ( " " ) : new String [ ] { umsg } ) [ 0 ] . substring ( 1 ) ) : ( ( umsg . contains ( " " ) ? umsg . split ( " " ) : new String [ ] { umsg } ) [ 0 ] ) ;
2017-01-30 21:22:36 +01:00
if ( api . commands . keySet ( ) . contains ( cmd . toLowerCase ( ) ) ) {
ArrayList < String > args = new ArrayList < String > ( ) ;
args . addAll ( Arrays . asList ( umsg . contains ( " " ) ? umsg . split ( " " ) : new String [ ] { umsg } ) ) ;
args . remove ( 0 ) ;
2018-01-21 21:45:27 +01:00
try {
api . commands . get ( cmd . toLowerCase ( ) ) . command ( cmd , args . toArray ( new String [ args . size ( ) ] ) ) ;
} catch ( Exception e ) {
log . error . println ( new InvocationTargetException ( e , " Uncaught exception while running command " ) ) ;
}
2017-01-30 21:22:36 +01:00
} else {
2017-02-08 01:39:18 +01:00
log . message . println ( " Unknown Command - " + umsg ) ;
2017-01-30 21:22:36 +01:00
}
2018-01-21 21:45:27 +01:00
jline . getOutput ( ) . write ( " \ b \ b " ) ;
2017-01-30 21:22:36 +01:00
}
}
}
2017-02-05 23:03:17 +01:00
private void loadDefaults ( ) {
2017-04-01 22:31:57 +02:00
SubCommand . load ( this ) ;
2017-02-05 23:03:17 +01:00
}
2017-02-08 01:39:18 +01:00
/ * *
* Stop SubServers . Host
*
* @param exit Exit Code
* /
2017-01-30 21:22:36 +01:00
public void stop ( int exit ) {
2017-12-06 23:34:47 +01:00
if ( ready ) {
log . info . println ( " Shutting down... " ) ;
SubDisableEvent event = new SubDisableEvent ( this , exit ) ;
api . executeEvent ( event ) ;
2017-04-01 07:37:48 +02:00
2017-12-06 23:34:47 +01:00
forcequit ( event . getExitCode ( ) ) ;
}
} private void forcequit ( int exit ) {
if ( ready ) {
ready = false ;
List < String > subservers = new ArrayList < String > ( ) ;
subservers . addAll ( servers . keySet ( ) ) ;
for ( String server : subservers ) {
servers . get ( server ) . stop ( ) ;
try {
servers . get ( server ) . waitFor ( ) ;
} catch ( Exception e ) {
log . error . println ( e ) ;
}
}
servers . clear ( ) ;
if ( creator ! = null ) {
creator . terminate ( ) ;
try {
creator . waitFor ( ) ;
} catch ( Exception e ) {
log . error . println ( e ) ;
}
}
running = false ;
2017-04-01 07:37:48 +02:00
try {
2017-12-06 23:34:47 +01:00
Thread . sleep ( 500 ) ;
2017-04-01 07:37:48 +02:00
} catch ( Exception e ) {
log . error . println ( e ) ;
}
2017-12-06 23:34:47 +01:00
if ( subdata ! = null ) Util . isException ( ( ) - > subdata . destroy ( 0 ) ) ;
2017-04-01 07:37:48 +02:00
2017-12-06 23:34:47 +01:00
Util . isException ( FileLogger : : end ) ;
System . exit ( exit ) ;
2017-04-01 07:37:48 +02:00
}
2017-01-30 21:22:36 +01:00
}
}