2016-12-24 05:55:17 +01:00
package net.ME1312.SubServers.Bungee.Host.Internal ;
2016-12-05 04:21:04 +01:00
2019-01-05 22:04:45 +01:00
import com.google.common.collect.Range ;
2018-10-23 01:25:42 +02:00
import com.google.gson.Gson ;
2016-12-24 05:55:17 +01:00
import net.ME1312.SubServers.Bungee.Event.SubCreateEvent ;
2017-01-11 04:23:29 +01:00
import net.ME1312.SubServers.Bungee.Host.* ;
2018-08-30 03:55:59 +02:00
import net.ME1312.SubServers.Bungee.Library.* ;
2016-12-28 01:15:36 +01:00
import net.ME1312.SubServers.Bungee.Library.Config.YAMLConfig ;
2016-12-24 05:55:17 +01:00
import net.ME1312.SubServers.Bungee.Library.Config.YAMLSection ;
2016-12-29 08:29:22 +01:00
import net.ME1312.SubServers.Bungee.Library.Exception.InvalidServerException ;
2017-07-23 06:32:57 +02:00
import net.ME1312.SubServers.Bungee.Library.Exception.SubCreatorException ;
2016-12-24 05:55:17 +01:00
import net.ME1312.SubServers.Bungee.Library.Version.Version ;
2017-07-23 06:32:57 +02:00
import net.ME1312.SubServers.Bungee.SubAPI ;
2016-12-28 01:15:36 +01:00
import net.ME1312.SubServers.Bungee.SubPlugin ;
2016-12-15 22:04:39 +01:00
import org.w3c.dom.Document ;
import org.w3c.dom.Node ;
import org.w3c.dom.NodeList ;
import org.xml.sax.InputSource ;
2016-12-05 04:21:04 +01:00
2016-12-15 22:04:39 +01:00
import javax.xml.parsers.DocumentBuilderFactory ;
import java.io.* ;
2018-08-30 03:55:59 +02:00
import java.lang.reflect.InvocationTargetException ;
2018-10-08 23:07:44 +02:00
import java.net.InetSocketAddress ;
2016-12-15 22:04:39 +01:00
import java.net.URL ;
import java.nio.charset.Charset ;
2017-05-29 07:00:02 +02:00
import java.util.* ;
2017-09-24 05:19:22 +02:00
import java.util.regex.Pattern ;
2016-12-05 04:21:04 +01:00
2017-01-07 20:06:54 +01:00
/ * *
* Internal SubCreator Class
* /
2017-12-21 17:02:47 +01:00
@SuppressWarnings ( " unchecked " )
2016-12-05 04:21:04 +01:00
public class InternalSubCreator extends SubCreator {
2017-05-29 07:00:02 +02:00
private HashMap < String , ServerTemplate > templates = new HashMap < String , ServerTemplate > ( ) ;
2016-12-15 22:04:39 +01:00
private InternalHost host ;
2019-01-05 22:04:45 +01:00
private Range < Integer > ports ;
private Container < Boolean > log ;
2016-12-15 22:04:39 +01:00
private String gitBash ;
2018-10-08 23:07:44 +02:00
private TreeMap < String , CreatorTask > thread ;
private class CreatorTask extends Thread {
private final UUID player ;
private final String name ;
private final ServerTemplate template ;
private final Version version ;
private final int port ;
private final InternalSubLogger log ;
private final Callback < SubServer > callback ;
private Process process ;
private CreatorTask ( UUID player , String name , ServerTemplate template , Version version , int port , Callback < SubServer > callback ) {
this . player = player ;
this . name = name ;
this . template = template ;
this . version = version ;
this . port = port ;
2019-01-05 22:04:45 +01:00
this . log = new InternalSubLogger ( null , this , name + File . separator + " Creator " , InternalSubCreator . this . log , null ) ;
2018-10-08 23:07:44 +02:00
this . callback = callback ;
}
2017-01-07 20:06:54 +01:00
2018-10-08 23:07:44 +02:00
private YAMLSection build ( File dir , ServerTemplate template , List < ServerTemplate > history ) throws SubCreatorException {
YAMLSection server = new YAMLSection ( ) ;
Version version = this . version ;
2019-01-04 22:51:58 +01:00
List < String > args = new LinkedList < String > ( ) ;
2018-10-08 23:07:44 +02:00
boolean error = false ;
if ( history . contains ( template ) ) throw new IllegalStateException ( " Template Import loop detected " ) ;
history . add ( template ) ;
for ( String other : template . getBuildOptions ( ) . getStringList ( " Import " , new ArrayList < String > ( ) ) ) {
if ( templates . keySet ( ) . contains ( other . toLowerCase ( ) ) ) {
if ( templates . get ( other . toLowerCase ( ) ) . isEnabled ( ) ) {
YAMLSection config = build ( dir , templates . get ( other . toLowerCase ( ) ) , history ) ;
if ( config = = null ) {
throw new SubCreatorException ( ) ;
} else {
server . setAll ( config ) ;
}
2018-08-10 06:50:10 +02:00
} else {
2018-10-08 23:07:44 +02:00
System . out . println ( name + File . separator + " Creator > Skipping disabled template: " + other ) ;
2018-08-10 06:50:10 +02:00
}
2017-07-23 06:32:57 +02:00
} else {
2018-10-08 23:07:44 +02:00
System . out . println ( name + File . separator + " Creator > Skipping missing template: " + other ) ;
2017-07-23 06:32:57 +02:00
}
}
2018-10-08 23:07:44 +02:00
server . setAll ( template . getConfigOptions ( ) ) ;
try {
System . out . println ( name + File . separator + " Creator > Loading Template: " + template . getDisplayName ( ) ) ;
Util . copyDirectory ( template . getDirectory ( ) , dir ) ;
2019-01-04 22:51:58 +01:00
switch ( template . getType ( ) ) {
case SPONGE :
case FORGE :
System . out . println ( name + File . separator + " Creator > Searching Versions... " ) ;
YAMLSection spversionmanifest = new YAMLSection ( new Gson ( ) . fromJson ( " { \" versions \" : " + Util . readAll ( new BufferedReader ( new InputStreamReader ( new URL ( " https://dl-api.spongepowered.org/v1/org.spongepowered/sponge " + ( ( template . getType ( ) = = ServerType . FORGE ) ? " forge " : " vanilla " ) + " /downloads?type=stable&minecraft= " + version ) . openStream ( ) , Charset . forName ( " UTF-8 " ) ) ) ) + '}' , Map . class ) ) ;
2018-10-08 23:07:44 +02:00
2019-01-04 22:51:58 +01:00
YAMLSection spprofile = null ;
Version spversion = null ;
for ( YAMLSection profile : spversionmanifest . getSectionList ( " versions " ) ) {
if ( profile . getSection ( " dependencies " ) . getRawString ( " minecraft " ) . equalsIgnoreCase ( version . toString ( ) ) & & ( spversion = = null | | new Version ( profile . getRawString ( " version " ) ) . compareTo ( spversion ) > = 0 ) ) {
spprofile = profile ;
spversion = new Version ( profile . getRawString ( " version " ) ) ;
}
2017-01-07 20:06:54 +01:00
}
2019-01-04 22:51:58 +01:00
if ( spversion = = null )
throw new InvalidServerException ( " Cannot find Sponge version for Minecraft " + version . toString ( ) ) ;
System . out . println ( name + File . separator + " Creator > Found \" sponge " + ( ( template . getType ( ) = = ServerType . FORGE ) ? " forge " : " vanilla " ) + " - " + spversion . toString ( ) + '"' ) ;
2018-10-08 23:07:44 +02:00
2019-01-04 22:51:58 +01:00
if ( template . getType ( ) = = ServerType . FORGE ) {
Version mcfversion = new Version ( spprofile . getSection ( " dependencies " ) . getRawString ( " minecraft " ) + '-' + spprofile . getSection ( " dependencies " ) . getRawString ( " forge " ) ) ;
System . out . println ( name + File . separator + " Creator > Found \" forge- " + mcfversion . toString ( ) + '"' ) ;
2017-01-07 20:06:54 +01:00
2019-01-04 22:51:58 +01:00
args . add ( mcfversion . toString ( ) ) ;
}
args . add ( spversion . toString ( ) ) ;
break ;
default :
args . add ( version . toString ( ) ) ;
2018-10-08 23:07:44 +02:00
}
} catch ( Exception e ) {
e . printStackTrace ( ) ;
2017-01-07 20:06:54 +01:00
}
2018-10-08 23:07:44 +02:00
if ( template . getBuildOptions ( ) . contains ( " Shell-Location " ) ) {
File cache ;
if ( template . getBuildOptions ( ) . getBoolean ( " Use-Cache " , true ) ) {
cache = new UniversalFile ( host . plugin . dir , " SubServers:Cache:Templates: " + template . getName ( ) ) ;
cache . mkdirs ( ) ;
2019-01-04 22:51:58 +01:00
args . add ( '\"' + cache . toString ( ) . replace ( File . separatorChar , '/' ) + '\"' ) ;
2018-10-08 23:07:44 +02:00
} else {
cache = null ;
}
2019-01-04 06:35:56 +01:00
2019-01-04 22:51:58 +01:00
String command = " bash \" " + template . getBuildOptions ( ) . getRawString ( " Shell-Location " ) + '\"' ;
for ( String arg : args ) command + = ' ' + arg ;
2019-01-05 00:32:01 +01:00
if ( ! System . getProperty ( " os.name " ) . toLowerCase ( ) . startsWith ( " windows " ) & & template . getBuildOptions ( ) . contains ( " Permission " ) ) {
2018-10-08 23:07:44 +02:00
try {
Process process = Runtime . getRuntime ( ) . exec ( " chmod " + template . getBuildOptions ( ) . getRawString ( " Permission " ) + ' ' + template . getBuildOptions ( ) . getRawString ( " Shell-Location " ) , null , dir ) ;
Thread . sleep ( 500 ) ;
if ( process . exitValue ( ) ! = 0 ) {
System . out . println ( name + File . separator + " Creator > Couldn't set " + template . getBuildOptions ( ) . getRawString ( " Permission " ) + " permissions to " + template . getBuildOptions ( ) . getRawString ( " Shell-Location " ) ) ;
}
} catch ( Exception e ) {
2017-11-22 22:58:33 +01:00
System . out . println ( name + File . separator + " Creator > Couldn't set " + template . getBuildOptions ( ) . getRawString ( " Permission " ) + " permissions to " + template . getBuildOptions ( ) . getRawString ( " Shell-Location " ) ) ;
2018-10-08 23:07:44 +02:00
e . printStackTrace ( ) ;
2017-01-07 20:06:54 +01:00
}
2018-10-08 23:07:44 +02:00
}
try {
System . out . println ( name + File . separator + " Creator > Launching " + template . getBuildOptions ( ) . getRawString ( " Shell-Location " ) ) ;
2019-01-04 22:51:58 +01:00
process = Runtime . getRuntime ( ) . exec ( Executable . parse ( gitBash , command ) , null , dir ) ;
2019-01-05 22:04:45 +01:00
log . file = new File ( dir , " SubCreator- " + template . getName ( ) + " - " + version . toString ( ) + " .log " ) ;
2018-10-08 23:07:44 +02:00
log . process = process ;
log . start ( ) ;
process . waitFor ( ) ;
Thread . sleep ( 500 ) ;
if ( process . exitValue ( ) ! = 0 ) error = true ;
} catch ( InterruptedException e ) {
error = true ;
2017-05-29 07:00:02 +02:00
} catch ( Exception e ) {
2018-10-08 23:07:44 +02:00
error = true ;
2017-05-29 07:00:02 +02:00
e . printStackTrace ( ) ;
2017-01-07 20:06:54 +01:00
}
2018-10-08 23:07:44 +02:00
if ( cache ! = null ) {
if ( cache . isDirectory ( ) & & cache . listFiles ( ) . length = = 0 ) cache . delete ( ) ;
cache = new UniversalFile ( host . plugin . dir , " SubServers:Cache:Templates " ) ;
if ( cache . isDirectory ( ) & & cache . listFiles ( ) . length = = 0 ) cache . delete ( ) ;
cache = new UniversalFile ( host . plugin . dir , " SubServers:Cache " ) ;
if ( cache . isDirectory ( ) & & cache . listFiles ( ) . length = = 0 ) cache . delete ( ) ;
}
2017-05-29 07:00:02 +02:00
}
2017-01-07 20:06:54 +01:00
2018-10-08 23:07:44 +02:00
new UniversalFile ( dir , " template.yml " ) . delete ( ) ;
if ( error ) throw new SubCreatorException ( ) ;
return server ;
}
public void run ( ) {
UniversalFile dir = new UniversalFile ( new File ( host . getPath ( ) ) , name ) ;
dir . mkdirs ( ) ;
YAMLSection server = new YAMLSection ( ) ;
YAMLSection config ;
2017-05-29 07:00:02 +02:00
try {
2018-10-08 23:07:44 +02:00
config = build ( dir , template , new LinkedList < > ( ) ) ;
generateProperties ( dir , port ) ;
generateClient ( dir , template . getType ( ) , name ) ;
} catch ( SubCreatorException e ) {
config = null ;
2017-05-29 07:00:02 +02:00
} catch ( Exception e ) {
2018-10-08 23:07:44 +02:00
config = null ;
2017-05-29 07:00:02 +02:00
e . printStackTrace ( ) ;
}
2018-04-07 21:04:55 +02:00
2018-10-08 23:07:44 +02:00
if ( config ! = null ) {
try {
System . out . println ( name + File . separator + " Creator > Saving... " ) ;
if ( host . plugin . exServers . keySet ( ) . contains ( name . toLowerCase ( ) ) )
host . plugin . exServers . remove ( name . toLowerCase ( ) ) ;
config = new YAMLSection ( ( Map < String , ? > ) convert ( config . get ( ) , new NamedContainer < > ( " $player$ " , ( player = = null ) ? " " : player . toString ( ) ) , new NamedContainer < > ( " $name$ " , name ) , new NamedContainer < > ( " $template$ " , template . getName ( ) ) ,
new NamedContainer < > ( " $type$ " , template . getType ( ) . toString ( ) ) , new NamedContainer < > ( " $version$ " , version . toString ( ) . replace ( " " , " @ " ) ) , new NamedContainer < > ( " $port$ " , Integer . toString ( port ) ) ) ) ;
server . set ( " Enabled " , true ) ;
server . set ( " Display " , " " ) ;
server . set ( " Host " , host . getName ( ) ) ;
server . set ( " Group " , new ArrayList < String > ( ) ) ;
server . set ( " Port " , port ) ;
server . set ( " Motd " , " Some SubServer " ) ;
server . set ( " Log " , true ) ;
server . set ( " Directory " , " . " + File . separatorChar + name ) ;
server . set ( " Executable " , " java -Xmx1024M -jar " + template . getType ( ) . toString ( ) + " .jar " ) ;
server . set ( " Stop-Command " , " stop " ) ;
server . set ( " Stop-Action " , " NONE " ) ;
server . set ( " Run-On-Launch " , false ) ;
server . set ( " Restricted " , false ) ;
server . set ( " Incompatible " , new ArrayList < String > ( ) ) ;
server . set ( " Hidden " , false ) ;
server . setAll ( config ) ;
SubServer subserver = host . addSubServer ( player , name , server . getBoolean ( " Enabled " ) , port , server . getColoredString ( " Motd " , '&' ) , server . getBoolean ( " Log " ) , server . getRawString ( " Directory " ) ,
2019-01-04 22:51:58 +01:00
server . getRawString ( " Executable " ) , server . getRawString ( " Stop-Command " ) , server . getBoolean ( " Hidden " ) , server . getBoolean ( " Restricted " ) ) ;
2018-10-08 23:07:44 +02:00
if ( server . getString ( " Display " ) . length ( ) > 0 ) subserver . setDisplayName ( server . getString ( " Display " ) ) ;
for ( String group : server . getStringList ( " Group " ) ) subserver . addGroup ( group ) ;
SubServer . StopAction action = Util . getDespiteException ( ( ) - > SubServer . StopAction . valueOf ( server . getRawString ( " Stop-Action " ) . toUpperCase ( ) . replace ( '-' , '_' ) . replace ( ' ' , '_' ) ) , null ) ;
if ( action ! = null ) subserver . setStopAction ( action ) ;
if ( server . contains ( " Extra " ) ) for ( String extra : server . getSection ( " Extra " ) . getKeys ( ) )
subserver . addExtra ( extra , server . getSection ( " Extra " ) . getObject ( extra ) ) ;
host . plugin . config . get ( ) . getSection ( " Servers " ) . set ( name , server ) ;
host . plugin . config . save ( ) ;
if ( template . getBuildOptions ( ) . getBoolean ( " Run-On-Finish " , true ) )
subserver . start ( ) ;
InternalSubCreator . this . thread . remove ( name . toLowerCase ( ) ) ;
callback . run ( subserver ) ;
} catch ( Exception e ) {
e . printStackTrace ( ) ;
}
} else {
System . out . println ( name + File . separator + " Creator > Couldn't build the server jar. Check the SubCreator logs for more detail. " ) ;
2018-04-07 21:04:55 +02:00
}
2018-10-08 23:07:44 +02:00
InternalSubCreator . this . thread . remove ( name . toLowerCase ( ) ) ;
} private Object convert ( Object value , NamedContainer < String , String > . . . replacements ) {
if ( value instanceof Map ) {
List < String > list = new ArrayList < String > ( ) ;
list . addAll ( ( ( Map < String , Object > ) value ) . keySet ( ) ) ;
for ( String key : list ) ( ( Map < String , Object > ) value ) . put ( key , convert ( ( ( Map < String , Object > ) value ) . get ( key ) , replacements ) ) ;
return value ;
} else if ( value instanceof Collection ) {
List < Object > list = new ArrayList < Object > ( ) ;
for ( Object val : ( Collection < Object > ) value ) list . add ( convert ( val , replacements ) ) ;
return list ;
} else if ( value . getClass ( ) . isArray ( ) ) {
List < Object > list = new ArrayList < Object > ( ) ;
for ( int i = 0 ; i < ( ( Object [ ] ) value ) . length ; i + + ) list . add ( convert ( ( ( Object [ ] ) value ) [ i ] , replacements ) ) ;
return list ;
} else if ( value instanceof String ) {
return replace ( ( String ) value , replacements ) ;
} else {
return value ;
}
} private String replace ( String string , NamedContainer < String , String > . . . replacements ) {
for ( NamedContainer < String , String > replacement : replacements ) string = string . replace ( replacement . name ( ) , replacement . get ( ) ) ;
return string ;
2017-05-29 07:00:02 +02:00
}
2017-07-23 06:32:57 +02:00
}
2018-10-08 23:07:44 +02:00
/ * *
* Creates an Internal SubCreator
*
* @param host Host
2019-01-05 22:04:45 +01:00
* @param ports The range of ports to auto - select from
* @param log Whether SubCreator should log to console
* @param gitBash The Git Bash directory
2018-10-08 23:07:44 +02:00
* /
2019-01-05 22:04:45 +01:00
public InternalSubCreator ( InternalHost host , Range < Integer > ports , boolean log , String gitBash ) {
if ( ! ports . hasLowerBound ( ) | | ! ports . hasUpperBound ( ) ) throw new IllegalArgumentException ( " Port range is not bound " ) ;
if ( Util . isNull ( host , ports , log , gitBash ) ) throw new NullPointerException ( ) ;
2018-10-08 23:07:44 +02:00
this . host = host ;
2019-01-05 22:04:45 +01:00
this . ports = ports ;
this . log = new Container < Boolean > ( log ) ;
2018-10-08 23:07:44 +02:00
this . gitBash = ( System . getenv ( " ProgramFiles(x86) " ) = = null ) ? Pattern . compile ( " %(ProgramFiles) \\ (x86 \\ )% " , Pattern . CASE_INSENSITIVE ) . matcher ( gitBash ) . replaceAll ( " %$1% " ) : gitBash ;
2019-01-04 22:51:58 +01:00
if ( this . gitBash . endsWith ( File . pathSeparator ) ) this . gitBash = this . gitBash . substring ( 0 , this . gitBash . length ( ) - 1 ) ;
2018-10-08 23:07:44 +02:00
this . thread = new TreeMap < String , CreatorTask > ( ) ;
reload ( ) ;
}
2018-08-30 03:55:59 +02:00
2018-10-08 23:07:44 +02:00
@Override
public void reload ( ) {
templates . clear ( ) ;
if ( new UniversalFile ( host . plugin . dir , " SubServers:Templates " ) . exists ( ) )
for ( File file : new UniversalFile ( host . plugin . dir , " SubServers:Templates " ) . listFiles ( ) ) {
try {
if ( file . isDirectory ( ) ) {
YAMLSection config = ( new UniversalFile ( file , " template.yml " ) . exists ( ) ) ? new YAMLConfig ( new UniversalFile ( file , " template.yml " ) ) . get ( ) . getSection ( " Template " , new YAMLSection ( ) ) : new YAMLSection ( ) ;
ServerTemplate template = new ServerTemplate ( file . getName ( ) , config . getBoolean ( " Enabled " , true ) , config . getRawString ( " Icon " , " ::NULL:: " ) , file , config . getSection ( " Build " , new YAMLSection ( ) ) , config . getSection ( " Settings " , new YAMLSection ( ) ) ) ;
templates . put ( file . getName ( ) . toLowerCase ( ) , template ) ;
if ( config . getKeys ( ) . contains ( " Display " ) ) template . setDisplayName ( config . getString ( " Display " ) ) ;
}
} catch ( Exception e ) {
System . out . println ( host . getName ( ) + File . separator + " Creator > Couldn't load template: " + file . getName ( ) ) ;
e . printStackTrace ( ) ;
}
2017-01-07 20:06:54 +01:00
}
}
2018-10-08 23:07:44 +02:00
@SuppressWarnings ( " deprecation " )
2017-01-07 20:06:54 +01:00
@Override
2018-10-08 23:07:44 +02:00
public boolean create ( UUID player , String name , ServerTemplate template , Version version , Integer port , Callback < SubServer > callback ) {
if ( Util . isNull ( name , template , version ) ) throw new NullPointerException ( ) ;
2018-08-30 03:55:59 +02:00
if ( host . isAvailable ( ) & & host . isEnabled ( ) & & template . isEnabled ( ) & & ! SubAPI . getInstance ( ) . getSubServers ( ) . keySet ( ) . contains ( name . toLowerCase ( ) ) & & ! SubCreator . isReserved ( name ) ) {
StackTraceElement [ ] origin = new Exception ( ) . getStackTrace ( ) ;
2018-10-08 23:07:44 +02:00
if ( port = = null ) {
2019-01-05 22:04:45 +01:00
Container < Integer > i = new Container < Integer > ( ports . lowerEndpoint ( ) - 1 ) ;
2018-10-08 23:07:44 +02:00
port = Util . getNew ( getAllReservedAddresses ( ) , ( ) - > {
2019-01-05 22:04:45 +01:00
do {
i . set ( i . get ( ) + 1 ) ;
if ( i . get ( ) > ports . upperEndpoint ( ) ) throw new IllegalStateException ( " There are no more ports available in range: " + ports . toString ( ) ) ;
} while ( ! ports . contains ( i . get ( ) ) ) ;
2018-10-08 23:07:44 +02:00
return new InetSocketAddress ( host . getAddress ( ) , i . get ( ) ) ;
} ) . getPort ( ) ;
}
2017-08-31 02:12:26 +02:00
2017-05-29 07:00:02 +02:00
final SubCreateEvent event = new SubCreateEvent ( player , host , name , template , version , port ) ;
2017-01-07 20:06:54 +01:00
host . plugin . getPluginManager ( ) . callEvent ( event ) ;
if ( ! event . isCancelled ( ) ) {
2018-10-08 23:07:44 +02:00
CreatorTask task = new CreatorTask ( player , name , template , version , port , server - > {
2018-08-30 03:55:59 +02:00
if ( callback ! = null & & server ! = null ) try {
callback . run ( server ) ;
} catch ( Throwable e ) {
Throwable ew = new InvocationTargetException ( e ) ;
ew . setStackTrace ( origin ) ;
ew . printStackTrace ( ) ;
}
2018-10-08 23:07:44 +02:00
} ) ;
this . thread . put ( name . toLowerCase ( ) , task ) ;
task . start ( ) ;
2017-01-07 20:06:54 +01:00
return true ;
2017-08-31 02:12:26 +02:00
} else {
this . thread . remove ( name . toLowerCase ( ) ) ;
return false ;
}
2017-01-07 20:06:54 +01:00
} else return false ;
}
@Override
public void terminate ( ) {
2018-10-08 23:07:44 +02:00
HashMap < String , CreatorTask > temp = new HashMap < String , CreatorTask > ( ) ;
2017-07-23 06:32:57 +02:00
temp . putAll ( thread ) ;
for ( String i : temp . keySet ( ) ) {
terminate ( i ) ;
}
}
@Override
public void terminate ( String name ) {
2018-10-08 23:07:44 +02:00
if ( this . thread . keySet ( ) . contains ( name . toLowerCase ( ) ) ) {
2019-01-05 00:32:01 +01:00
boolean success = false ;
if ( this . thread . get ( name . toLowerCase ( ) ) . process ! = null & & this . thread . get ( name . toLowerCase ( ) ) . process . isAlive ( ) & & System . getProperty ( " os.name " ) . toLowerCase ( ) . startsWith ( " windows " ) ) try {
Process terminator = Runtime . getRuntime ( ) . exec ( new String [ ] { " taskkill " , " /T " , " /F " , " /PID " , Long . toString ( ( long ) Process . class . getDeclaredMethod ( " pid " ) . invoke ( this . thread . get ( name . toLowerCase ( ) ) . process ) ) } ) ;
terminator . waitFor ( ) ;
if ( terminator . exitValue ( ) ! = 0 ) throw new IllegalStateException ( " taskkill exited with code " + terminator . exitValue ( ) ) ;
success = true ;
} catch ( Exception e ) { }
2018-10-08 23:07:44 +02:00
if ( this . thread . get ( name . toLowerCase ( ) ) . process ! = null & & this . thread . get ( name . toLowerCase ( ) ) . process . isAlive ( ) ) {
this . thread . get ( name . toLowerCase ( ) ) . process . destroyForcibly ( ) ;
2019-01-05 00:32:01 +01:00
success = true ;
}
if ( ! success & & this . thread . get ( name . toLowerCase ( ) ) . isAlive ( ) ) {
2018-10-08 23:07:44 +02:00
this . thread . get ( name . toLowerCase ( ) ) . interrupt ( ) ;
this . thread . remove ( name . toLowerCase ( ) ) ;
}
2017-01-07 20:06:54 +01:00
}
}
@Override
public void waitFor ( ) throws InterruptedException {
2018-10-08 23:07:44 +02:00
HashMap < String , CreatorTask > temp = new HashMap < String , CreatorTask > ( ) ;
2017-07-23 06:32:57 +02:00
temp . putAll ( thread ) ;
for ( String i : temp . keySet ( ) ) {
waitFor ( i ) ;
}
}
@Override
public void waitFor ( String name ) throws InterruptedException {
2018-10-08 23:07:44 +02:00
while ( this . thread . keySet ( ) . contains ( name . toLowerCase ( ) ) & & this . thread . get ( name . toLowerCase ( ) ) . isAlive ( ) ) {
2017-01-07 20:06:54 +01:00
Thread . sleep ( 250 ) ;
}
}
@Override
public Host getHost ( ) {
return host ;
}
2019-01-05 22:04:45 +01:00
@Override
public Range getPortRange ( ) {
return ports ;
}
@Override
public void setPortRange ( Range < Integer > value ) {
if ( ! value . hasLowerBound ( ) | | ! value . hasUpperBound ( ) ) throw new IllegalArgumentException ( " Port range is not bound " ) ;
ports = value ;
}
2017-01-07 20:06:54 +01:00
@Override
2017-01-21 17:49:37 +01:00
public String getBashDirectory ( ) {
2017-01-07 20:06:54 +01:00
return gitBash ;
}
2017-01-11 04:23:29 +01:00
@Override
2018-10-08 23:07:44 +02:00
public List < SubLogger > getLoggers ( ) {
2017-07-23 06:32:57 +02:00
List < SubLogger > loggers = new ArrayList < SubLogger > ( ) ;
2018-10-08 23:07:44 +02:00
HashMap < String , CreatorTask > temp = new HashMap < String , CreatorTask > ( ) ;
2017-07-23 06:32:57 +02:00
temp . putAll ( thread ) ;
for ( String i : temp . keySet ( ) ) {
loggers . add ( getLogger ( i ) ) ;
}
return loggers ;
}
@Override
2017-07-23 23:05:33 +02:00
public SubLogger getLogger ( String name ) {
2018-10-08 23:07:44 +02:00
return this . thread . get ( name . toLowerCase ( ) ) . log ;
2017-01-11 04:23:29 +01:00
}
2019-01-05 22:04:45 +01:00
@Override
public boolean isLogging ( ) {
return log . get ( ) ;
}
@Override
public void setLogging ( boolean value ) {
if ( Util . isNull ( value ) ) throw new NullPointerException ( ) ;
log . set ( value ) ;
}
2017-01-07 20:06:54 +01:00
@Override
2017-07-23 06:32:57 +02:00
public List < String > getReservedNames ( ) {
return new ArrayList < String > ( thread . keySet ( ) ) ;
2017-01-07 20:06:54 +01:00
}
2018-10-08 23:07:44 +02:00
@Override
public List < Integer > getReservedPorts ( ) {
List < Integer > ports = new ArrayList < Integer > ( ) ;
for ( CreatorTask task : thread . values ( ) ) ports . add ( task . port ) ;
return ports ;
}
2017-05-29 07:00:02 +02:00
@Override
public Map < String , ServerTemplate > getTemplates ( ) {
return new TreeMap < String , ServerTemplate > ( templates ) ;
2017-01-07 20:06:54 +01:00
}
2016-12-15 22:04:39 +01:00
2017-05-29 07:00:02 +02:00
@Override
public ServerTemplate getTemplate ( String name ) {
if ( Util . isNull ( name ) ) throw new NullPointerException ( ) ;
return getTemplates ( ) . get ( name . toLowerCase ( ) ) ;
}
2016-12-15 22:04:39 +01:00
2017-05-29 07:00:02 +02:00
private void generateClient ( File dir , ServerType type , String name ) throws IOException {
if ( new UniversalFile ( dir , " subservers.client " ) . exists ( ) ) {
if ( type = = ServerType . SPIGOT ) {
if ( ! new UniversalFile ( dir , " plugins " ) . exists ( ) ) new UniversalFile ( dir , " plugins " ) . mkdirs ( ) ;
2018-07-17 09:10:17 +02:00
Util . copyFromJar ( SubPlugin . class . getClassLoader ( ) , " net/ME1312/SubServers/Bungee/Library/Files/client.jar " , new UniversalFile ( dir , " plugins:SubServers.Client.jar " ) . getPath ( ) ) ;
2018-07-26 19:34:31 +02:00
} else if ( type = = ServerType . FORGE | | type = = ServerType . SPONGE ) {
2018-07-23 05:44:20 +02:00
if ( ! new UniversalFile ( dir , " mods " ) . exists ( ) ) new UniversalFile ( dir , " mods " ) . mkdirs ( ) ;
Util . copyFromJar ( SubPlugin . class . getClassLoader ( ) , " net/ME1312/SubServers/Bungee/Library/Files/client.jar " , new UniversalFile ( dir , " mods:SubServers.Client.jar " ) . getPath ( ) ) ;
2017-05-29 07:00:02 +02:00
}
2018-04-15 03:53:51 +02:00
YAMLSection config = new YAMLSection ( ) ;
2017-05-29 07:00:02 +02:00
FileWriter writer = new FileWriter ( new UniversalFile ( dir , " subservers.client " ) , false ) ;
2018-04-15 03:53:51 +02:00
config . set ( " Name " , name ) ;
config . set ( " Address " , host . plugin . config . get ( ) . getSection ( " Settings " ) . getSection ( " SubData " ) . getRawString ( " Address " , " 127.0.0.1 " ) . replace ( " 0.0.0.0 " , " 127.0.0.1 " ) ) ;
config . set ( " Password " , host . plugin . config . get ( ) . getSection ( " Settings " ) . getSection ( " SubData " ) . getRawString ( " Password " , " " ) ) ;
config . set ( " Encryption " , host . plugin . config . get ( ) . getSection ( " Settings " ) . getSection ( " SubData " ) . getRawString ( " Encryption " , " NONE " ) ) ;
writer . write ( config . toJSON ( ) ) ;
2017-05-29 07:00:02 +02:00
writer . close ( ) ;
}
2016-12-15 22:04:39 +01:00
}
2017-04-14 04:39:51 +02:00
private void generateProperties ( File dir , int port ) throws IOException {
File file = new File ( dir , " server.properties " ) ;
2017-05-29 07:00:02 +02:00
if ( ! file . exists ( ) ) file . createNewFile ( ) ;
2017-12-15 01:50:39 +01:00
InputStream stream = new FileInputStream ( file ) ;
2018-11-21 23:33:52 +01:00
String content = Util . readAll ( new BufferedReader ( new InputStreamReader ( stream ) ) ) . replaceAll ( " server-port=.*( \ r? \ n) " , " server-port= " + port + " $1 " ) . replaceAll ( " server-ip=.*( \ r? \ n) " , " server-ip= " + host . getAddress ( ) . getHostAddress ( ) + " $1 " ) ;
2017-12-15 01:50:39 +01:00
stream . close ( ) ;
2017-04-14 04:39:51 +02:00
file . delete ( ) ;
PrintWriter writer = new PrintWriter ( file , " UTF-8 " ) ;
writer . write ( content ) ;
2016-12-15 22:04:39 +01:00
writer . close ( ) ;
}
2017-11-22 22:58:33 +01:00
}