2016-12-24 05:55:17 +01:00
package net.ME1312.SubServers.Bungee ;
2018-10-08 01:25:08 +02:00
import com.dosse.upnp.UPnP ;
2019-01-05 22:04:45 +01:00
import com.google.common.collect.Range ;
2018-04-15 03:53:51 +02:00
import com.google.gson.Gson ;
2019-04-18 16:02:09 +02:00
import net.ME1312.Galaxi.Library.Map.ObjectMap ;
2020-06-12 07:45:49 +02:00
import net.ME1312.Galaxi.Library.Container.NamedContainer ;
2019-04-18 16:02:09 +02:00
import net.ME1312.Galaxi.Library.UniversalFile ;
import net.ME1312.Galaxi.Library.Util ;
import net.ME1312.SubData.Server.* ;
import net.ME1312.SubData.Server.Encryption.AES ;
2020-06-12 07:45:49 +02:00
import net.ME1312.SubData.Server.Encryption.DHE ;
2019-04-18 16:02:09 +02:00
import net.ME1312.SubData.Server.Encryption.RSA ;
2020-06-12 07:45:49 +02:00
import net.ME1312.SubData.Server.Library.DataSize ;
2019-04-18 16:02:09 +02:00
import net.ME1312.SubServers.Bungee.Event.* ;
2017-11-22 22:58:33 +01:00
import net.ME1312.SubServers.Bungee.Host.* ;
import net.ME1312.SubServers.Bungee.Library.* ;
2019-04-18 16:02:09 +02:00
import net.ME1312.Galaxi.Library.Config.YAMLConfig ;
import net.ME1312.Galaxi.Library.Config.YAMLSection ;
2020-01-18 06:13:10 +01:00
import net.ME1312.SubServers.Bungee.Library.Compatibility.Galaxi.GalaxiCommand ;
2020-06-12 07:45:49 +02:00
import net.ME1312.SubServers.Bungee.Library.Compatibility.LegacyServerMap ;
2019-05-17 00:36:41 +02:00
import net.ME1312.SubServers.Bungee.Library.Compatibility.Logger ;
2020-06-21 23:42:10 +02:00
import net.ME1312.SubServers.Bungee.Library.Fallback.SmartFallback ;
2020-06-12 07:45:49 +02:00
import net.ME1312.SubServers.Bungee.Library.ConfigUpdater ;
2016-12-24 05:55:17 +01:00
import net.ME1312.SubServers.Bungee.Library.Exception.InvalidHostException ;
import net.ME1312.SubServers.Bungee.Library.Exception.InvalidServerException ;
2019-04-18 16:02:09 +02:00
import net.ME1312.Galaxi.Library.Version.Version ;
import net.ME1312.SubServers.Bungee.Network.Packet.PacketOutExReload ;
import net.ME1312.SubServers.Bungee.Network.SubProtocol ;
2016-12-05 04:21:04 +01:00
import net.md_5.bungee.BungeeCord ;
2019-04-29 17:05:06 +02:00
import net.md_5.bungee.UserConnection ;
2019-04-18 16:02:09 +02:00
import net.md_5.bungee.api.ChatColor ;
2019-02-27 20:05:05 +01:00
import net.md_5.bungee.api.ServerPing ;
2019-04-29 17:05:06 +02:00
import net.md_5.bungee.api.chat.BaseComponent ;
2019-02-27 20:05:05 +01:00
import net.md_5.bungee.api.chat.TextComponent ;
2018-10-08 01:25:08 +02:00
import net.md_5.bungee.api.config.ListenerInfo ;
2016-12-05 04:21:04 +01:00
import net.md_5.bungee.api.config.ServerInfo ;
2019-02-27 20:05:05 +01:00
import net.md_5.bungee.api.event.* ;
2017-08-15 11:58:48 +02:00
import net.md_5.bungee.api.plugin.Listener ;
import net.md_5.bungee.event.EventHandler ;
2016-12-05 04:21:04 +01:00
import java.io.* ;
2017-01-30 21:22:36 +01:00
import java.lang.reflect.InvocationTargetException ;
2017-12-10 01:30:06 +01:00
import java.math.BigInteger ;
2016-12-05 04:21:04 +01:00
import java.net.InetAddress ;
2017-04-16 19:02:14 +02:00
import java.net.InetSocketAddress ;
2017-08-18 11:58:06 +02:00
import java.net.URL ;
import java.nio.charset.Charset ;
2016-12-05 04:21:04 +01:00
import java.nio.file.Files ;
2019-04-18 16:02:09 +02:00
import java.security.SecureRandom ;
2017-05-30 21:38:51 +02:00
import java.text.DecimalFormat ;
2016-12-05 04:21:04 +01:00
import java.util.* ;
2017-01-01 20:34:46 +01:00
import java.util.concurrent.TimeUnit ;
2016-12-05 04:21:04 +01:00
/ * *
* Main Plugin Class
* /
2019-08-30 21:44:54 +02:00
public final class SubProxy extends BungeeCord implements Listener {
2020-06-12 07:45:49 +02:00
final LinkedHashMap < String , LinkedHashMap < String , String > > exLang = new LinkedHashMap < String , LinkedHashMap < String , String > > ( ) ;
final HashMap < String , Class < ? extends Host > > hostDrivers = new HashMap < String , Class < ? extends Host > > ( ) ;
2018-01-22 16:01:33 +01:00
public final HashMap < String , Proxy > proxies = new HashMap < String , Proxy > ( ) ;
2016-12-05 04:21:04 +01:00
public final HashMap < String , Host > hosts = new HashMap < String , Host > ( ) ;
2017-04-16 19:02:14 +02:00
public final HashMap < String , Server > exServers = new HashMap < String , Server > ( ) ;
private final HashMap < String , ServerInfo > legServers = new HashMap < String , ServerInfo > ( ) ;
2019-04-29 17:05:06 +02:00
private final HashMap < UUID , List < ServerInfo > > fallbackLimbo = new HashMap < UUID , List < ServerInfo > > ( ) ;
2016-12-05 04:21:04 +01:00
2017-01-08 03:30:03 +01:00
public final PrintStream out ;
2016-12-15 22:04:39 +01:00
public final UniversalFile dir = new UniversalFile ( new File ( System . getProperty ( " user.dir " ) ) ) ;
2016-12-05 04:21:04 +01:00
public YAMLConfig config ;
2019-04-29 17:05:06 +02:00
public YAMLConfig servers ;
private YAMLConfig bungee ;
public YAMLConfig lang ;
2017-12-09 09:43:29 +01:00
public final SubAPI api = new SubAPI ( this ) ;
2019-04-29 17:05:06 +02:00
public SubProtocol subprotocol ;
2016-12-15 22:04:39 +01:00
public SubDataServer subdata = null ;
2017-08-15 11:58:48 +02:00
public SubServer sudo = null ;
2020-06-12 07:45:49 +02:00
public static final Version version = Version . fromString ( " 2.16a " ) ;
2016-12-05 04:21:04 +01:00
2018-08-09 20:54:56 +02:00
public Proxy redis = null ;
2018-07-19 21:34:58 +02:00
public boolean canSudo = false ;
2018-05-24 20:52:47 +02:00
public final boolean isPatched ;
2019-05-17 00:36:41 +02:00
public final boolean isGalaxi ;
2017-12-10 01:30:06 +01:00
public long resetDate = 0 ;
2017-04-16 19:02:14 +02:00
private boolean running = false ;
2020-06-20 03:00:50 +02:00
private boolean reloading = false ;
2017-08-18 11:58:06 +02:00
private boolean posted = false ;
2018-01-21 21:45:27 +01:00
private static BigInteger lastSignature = BigInteger . valueOf ( - 1 ) ;
2016-12-05 04:21:04 +01:00
2017-12-15 01:50:39 +01:00
@SuppressWarnings ( " unchecked " )
2020-06-12 07:45:49 +02:00
SubProxy ( PrintStream out , boolean isPatched ) throws Exception {
2018-05-24 20:52:47 +02:00
this . isPatched = isPatched ;
2019-05-17 00:36:41 +02:00
this . isGalaxi = ! Util . isException ( ( ) - >
Util . reflect ( Class . forName ( " net.ME1312.Galaxi.Engine.PluginManager " ) . getMethod ( " findClasses " , Class . class ) ,
Util . reflect ( Class . forName ( " net.ME1312.Galaxi.Engine.GalaxiEngine " ) . getMethod ( " getPluginManager " ) ,
Util . reflect ( Class . forName ( " net.ME1312.Galaxi.Engine.GalaxiEngine " ) . getMethod ( " getInstance " ) , null ) ) , Launch . class ) ) ;
Util . reflect ( Logger . class . getDeclaredField ( " plugin " ) , null , this ) ;
Logger . get ( " SubServers " ) . info ( " Loading SubServers.Bungee v " + version . toString ( ) + " Libraries (for Minecraft " + api . getGameVersion ( ) [ api . getGameVersion ( ) . length - 1 ] + " ) " ) ;
2017-01-08 03:30:03 +01:00
2017-01-30 21:22:36 +01:00
this . out = out ;
2016-12-24 05:55:17 +01:00
if ( ! ( new UniversalFile ( dir , " config.yml " ) . exists ( ) ) ) {
2019-08-30 21:44:54 +02:00
Util . copyFromJar ( SubProxy . class . getClassLoader ( ) , " net/ME1312/SubServers/Bungee/Library/Files/bungee.yml " , new UniversalFile ( dir , " config.yml " ) . getPath ( ) ) ;
2016-12-24 05:55:17 +01:00
YAMLConfig tmp = new YAMLConfig ( new UniversalFile ( " config.yml " ) ) ;
tmp . get ( ) . set ( " stats " , UUID . randomUUID ( ) . toString ( ) ) ;
tmp . save ( ) ;
2019-05-17 00:36:41 +02:00
Logger . get ( " SubServers " ) . info ( " Created ./config.yml " ) ;
2016-12-24 05:55:17 +01:00
}
2019-04-29 17:05:06 +02:00
bungee = new YAMLConfig ( new UniversalFile ( dir , " config.yml " ) ) ;
2017-12-09 09:43:29 +01:00
2016-12-05 04:21:04 +01:00
UniversalFile dir = new UniversalFile ( this . dir , " SubServers " ) ;
dir . mkdir ( ) ;
2019-04-29 17:05:06 +02:00
ConfigUpdater . updateConfig ( new UniversalFile ( dir , " config.yml " ) ) ;
2017-04-16 19:02:14 +02:00
config = new YAMLConfig ( new UniversalFile ( dir , " config.yml " ) ) ;
2016-12-05 04:21:04 +01:00
2019-04-29 17:05:06 +02:00
ConfigUpdater . updateServers ( new UniversalFile ( dir , " servers.yml " ) ) ;
servers = new YAMLConfig ( new UniversalFile ( dir , " servers.yml " ) ) ;
2016-12-05 04:21:04 +01:00
2019-05-09 22:17:15 +02:00
ConfigUpdater . updateLang ( new UniversalFile ( dir , " lang.yml " ) ) ;
lang = new YAMLConfig ( new UniversalFile ( dir , " lang.yml " ) ) ;
2017-07-30 02:41:02 +02:00
if ( ! ( new UniversalFile ( dir , " Templates " ) . exists ( ) ) ) {
new UniversalFile ( dir , " Templates " ) . mkdirs ( ) ;
2019-08-30 21:44:54 +02:00
Util . unzip ( SubProxy . class . getResourceAsStream ( " /net/ME1312/SubServers/Bungee/Library/Files/Templates/vanilla.zip " ) , new UniversalFile ( dir , " Templates " ) ) ;
2019-05-17 00:36:41 +02:00
Logger . get ( " SubServers " ) . info ( " Created ./SubServers/Templates/Vanilla " ) ;
2017-07-30 02:41:02 +02:00
2019-08-30 21:44:54 +02:00
Util . unzip ( SubProxy . class . getResourceAsStream ( " /net/ME1312/SubServers/Bungee/Library/Files/Templates/spigot.zip " ) , new UniversalFile ( dir , " Templates " ) ) ;
2019-05-17 00:36:41 +02:00
Logger . get ( " SubServers " ) . info ( " Created ./SubServers/Templates/Spigot " ) ;
2017-07-30 02:41:02 +02:00
2019-12-18 06:08:59 +01:00
Util . unzip ( SubProxy . class . getResourceAsStream ( " /net/ME1312/SubServers/Bungee/Library/Files/Templates/paper.zip " ) , new UniversalFile ( dir , " Templates " ) ) ;
Logger . get ( " SubServers " ) . info ( " Created ./SubServers/Templates/Paper " ) ;
2019-08-30 21:44:54 +02:00
Util . unzip ( SubProxy . class . getResourceAsStream ( " /net/ME1312/SubServers/Bungee/Library/Files/Templates/forge.zip " ) , new UniversalFile ( dir , " Templates " ) ) ;
2019-05-17 00:36:41 +02:00
Logger . get ( " SubServers " ) . info ( " Created ./SubServers/Templates/Forge " ) ;
2018-07-26 19:34:31 +02:00
2019-08-30 21:44:54 +02:00
Util . unzip ( SubProxy . class . getResourceAsStream ( " /net/ME1312/SubServers/Bungee/Library/Files/Templates/sponge.zip " ) , new UniversalFile ( dir , " Templates " ) ) ;
2019-05-17 00:36:41 +02:00
Logger . get ( " SubServers " ) . info ( " Created ./SubServers/Templates/Sponge " ) ;
2017-07-30 02:41:02 +02:00
} else {
2020-06-13 23:53:18 +02:00
long stamp = Math . round ( Math . random ( ) * 100000 ) ;
2020-06-21 05:46:16 +02:00
Version version = new Version ( " 2.16a+ " ) ;
if ( new UniversalFile ( dir , " Templates:Vanilla:template.yml " ) . exists ( ) & & ( ( new YAMLConfig ( new UniversalFile ( dir , " Templates:Vanilla:template.yml " ) ) ) . get ( ) . getVersion ( " Version " , version ) ) . compareTo ( version ) ! = 0 ) {
2020-06-13 23:53:18 +02:00
Files . move ( new UniversalFile ( dir , " Templates:Vanilla " ) . toPath ( ) , new UniversalFile ( dir , " Templates:Vanilla. " + stamp + " .x " ) . toPath ( ) ) ;
2019-08-30 21:44:54 +02:00
Util . unzip ( SubProxy . class . getResourceAsStream ( " /net/ME1312/SubServers/Bungee/Library/Files/Templates/vanilla.zip " ) , new UniversalFile ( dir , " Templates " ) ) ;
2019-05-17 00:36:41 +02:00
Logger . get ( " SubServers " ) . info ( " Updated ./SubServers/Templates/Vanilla " ) ;
2017-07-30 02:41:02 +02:00
}
2020-06-21 05:46:16 +02:00
if ( new UniversalFile ( dir , " Templates:Spigot:template.yml " ) . exists ( ) & & ( ( new YAMLConfig ( new UniversalFile ( dir , " Templates:Spigot:template.yml " ) ) ) . get ( ) . getVersion ( " Version " , version ) ) . compareTo ( version ) ! = 0 ) {
2020-06-13 23:53:18 +02:00
Files . move ( new UniversalFile ( dir , " Templates:Spigot " ) . toPath ( ) , new UniversalFile ( dir , " Templates:Spigot. " + stamp + " .x " ) . toPath ( ) ) ;
2019-08-30 21:44:54 +02:00
Util . unzip ( SubProxy . class . getResourceAsStream ( " /net/ME1312/SubServers/Bungee/Library/Files/Templates/spigot.zip " ) , new UniversalFile ( dir , " Templates " ) ) ;
2019-05-17 00:36:41 +02:00
Logger . get ( " SubServers " ) . info ( " Updated ./SubServers/Templates/Spigot " ) ;
2017-07-30 02:41:02 +02:00
}
2020-06-21 05:46:16 +02:00
if ( new UniversalFile ( dir , " Templates:Paper:template.yml " ) . exists ( ) & & ( ( new YAMLConfig ( new UniversalFile ( dir , " Templates:Paper:template.yml " ) ) ) . get ( ) . getVersion ( " Version " , version ) ) . compareTo ( version ) ! = 0 ) {
2020-06-13 23:53:18 +02:00
Files . move ( new UniversalFile ( dir , " Templates:Paper " ) . toPath ( ) , new UniversalFile ( dir , " Templates:Paper. " + stamp + " .x " ) . toPath ( ) ) ;
Util . unzip ( SubProxy . class . getResourceAsStream ( " /net/ME1312/SubServers/Bungee/Library/Files/Templates/paper.zip " ) , new UniversalFile ( dir , " Templates " ) ) ;
2019-12-18 06:08:59 +01:00
Logger . get ( " SubServers " ) . info ( " Updated ./SubServers/Templates/Paper " ) ;
}
2020-06-21 05:46:16 +02:00
if ( new UniversalFile ( dir , " Templates:Forge:template.yml " ) . exists ( ) & & ( ( new YAMLConfig ( new UniversalFile ( dir , " Templates:Forge:template.yml " ) ) ) . get ( ) . getVersion ( " Version " , version ) ) . compareTo ( version ) ! = 0 ) {
2020-06-13 23:53:18 +02:00
Files . move ( new UniversalFile ( dir , " Templates:Forge " ) . toPath ( ) , new UniversalFile ( dir , " Templates:Forge. " + stamp + " .x " ) . toPath ( ) ) ;
2019-08-30 21:44:54 +02:00
Util . unzip ( SubProxy . class . getResourceAsStream ( " /net/ME1312/SubServers/Bungee/Library/Files/Templates/forge.zip " ) , new UniversalFile ( dir , " Templates " ) ) ;
2019-05-17 00:36:41 +02:00
Logger . get ( " SubServers " ) . info ( " Updated ./SubServers/Templates/Forge " ) ;
2018-07-26 19:34:31 +02:00
}
2020-06-21 05:46:16 +02:00
if ( new UniversalFile ( dir , " Templates:Sponge:template.yml " ) . exists ( ) & & ( ( new YAMLConfig ( new UniversalFile ( dir , " Templates:Sponge:template.yml " ) ) ) . get ( ) . getVersion ( " Version " , version ) ) . compareTo ( version ) ! = 0 ) {
2020-06-13 23:53:18 +02:00
Files . move ( new UniversalFile ( dir , " Templates:Sponge " ) . toPath ( ) , new UniversalFile ( dir , " Templates:Sponge. " + stamp + " .x " ) . toPath ( ) ) ;
2019-08-30 21:44:54 +02:00
Util . unzip ( SubProxy . class . getResourceAsStream ( " /net/ME1312/SubServers/Bungee/Library/Files/Templates/sponge.zip " ) , new UniversalFile ( dir , " Templates " ) ) ;
2019-05-17 00:36:41 +02:00
Logger . get ( " SubServers " ) . info ( " Updated ./SubServers/Templates/Sponge " ) ;
2017-07-30 02:41:02 +02:00
}
2017-01-01 20:34:46 +01:00
}
2019-04-26 05:24:10 +02:00
Runnable clean = ( ) - > {
try {
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 ( ) ) {
FileReader reader = new FileReader ( new UniversalFile ( dir , " Recently Deleted: " + file . getName ( ) + " :info.json " ) ) ;
YAMLSection info = new YAMLSection ( new Gson ( ) . fromJson ( Util . readAll ( reader ) , Map . class ) ) ;
reader . close ( ) ;
if ( info . contains ( " Timestamp " ) ) {
if ( TimeUnit . MILLISECONDS . toDays ( Calendar . getInstance ( ) . getTime ( ) . getTime ( ) - info . getLong ( " Timestamp " ) ) > = 7 ) {
Util . deleteDirectory ( file ) ;
f - - ;
2019-05-17 00:36:41 +02:00
Logger . get ( " SubServers " ) . info ( " Removed ./SubServers/Recently Deleted/ " + file . getName ( ) ) ;
2019-04-26 05:24:10 +02:00
}
} else {
Util . deleteDirectory ( file ) ;
f - - ;
2019-05-17 00:36:41 +02:00
Logger . get ( " SubServers " ) . info ( " Removed ./SubServers/Recently Deleted/ " + file . getName ( ) ) ;
2019-04-26 05:24:10 +02:00
}
} else {
2017-01-01 20:34:46 +01:00
Util . deleteDirectory ( file ) ;
f - - ;
2019-05-17 00:36:41 +02:00
Logger . get ( " SubServers " ) . info ( " Removed ./SubServers/Recently Deleted/ " + file . getName ( ) ) ;
2017-01-01 20:34:46 +01:00
}
} else {
2019-04-26 05:24:10 +02:00
Files . delete ( file . toPath ( ) ) ;
2017-01-01 20:34:46 +01:00
f - - ;
2019-05-17 00:36:41 +02:00
Logger . get ( " SubServers " ) . info ( " Removed ./SubServers/Recently Deleted/ " + file . getName ( ) ) ;
2017-01-01 20:34:46 +01:00
}
2019-04-26 05:24:10 +02:00
} catch ( Exception e ) {
2019-05-17 00:36:41 +02:00
Logger . get ( " SubServers " ) . info ( " Problem scanning .SubServers/Recently Deleted/ " + file . getName ( ) ) ;
2019-04-26 05:24:10 +02:00
e . printStackTrace ( ) ;
Files . delete ( file . toPath ( ) ) ;
2017-01-01 20:34:46 +01:00
}
}
2019-04-26 05:24:10 +02:00
if ( f < = 0 ) {
Files . delete ( new UniversalFile ( dir , " Recently Deleted " ) . toPath ( ) ) ;
}
2017-01-01 20:34:46 +01:00
}
2019-04-26 05:24:10 +02:00
} catch ( Exception e ) {
e . printStackTrace ( ) ;
2017-01-01 20:34:46 +01:00
}
2019-04-26 05:24:10 +02:00
} ;
clean . run ( ) ;
new Timer ( " SubServers.Bungee::Recycle_Cleaner " ) . scheduleAtFixedRate ( new TimerTask ( ) {
@Override
public void run ( ) {
clean . run ( ) ;
2017-01-01 20:34:46 +01:00
}
2019-04-26 05:24:10 +02:00
} , TimeUnit . DAYS . toMillis ( 7 ) , TimeUnit . DAYS . toMillis ( 7 ) ) ;
2017-01-01 20:34:46 +01:00
2020-06-12 07:45:49 +02:00
api . addHostDriver ( net . ME1312 . SubServers . Bungee . Host . Internal . InternalHost . class , " virtual " ) ;
2017-08-22 15:02:23 +02:00
api . addHostDriver ( net . ME1312 . SubServers . Bungee . Host . External . ExternalHost . class , " network " ) ;
2016-12-05 04:21:04 +01:00
2017-08-15 11:58:48 +02:00
getPluginManager ( ) . registerListener ( null , this ) ;
2017-01-08 03:30:03 +01:00
2019-05-17 00:36:41 +02:00
Logger . get ( " SubServers " ) . info ( " Pre-Parsing Config... " ) ;
2019-04-29 17:05:06 +02:00
for ( String name : servers . get ( ) . getMap ( " Servers " ) . getKeys ( ) ) {
2017-08-18 11:58:06 +02:00
try {
2019-04-29 17:05:06 +02:00
if ( Util . getCaseInsensitively ( config . get ( ) . getMap ( " Hosts " ) . get ( ) , servers . get ( ) . getMap ( " Servers " ) . getMap ( name ) . getString ( " Host " ) ) = = null ) throw new InvalidServerException ( " There is no host with this name: " + servers . get ( ) . getMap ( " Servers " ) . getMap ( name ) . getString ( " Host " ) ) ;
2020-06-12 07:45:49 +02:00
legServers . put ( name , constructServerInfo ( name , new InetSocketAddress ( InetAddress . getByName ( ( String ) ( ( Map < String , ? > ) Util . getCaseInsensitively ( config . get ( ) . getMap ( " Hosts " ) . get ( ) , servers . get ( ) . getMap ( " Servers " ) . getMap ( name ) . getString ( " Host " ) ) ) . get ( " Address " ) ) , servers . get ( ) . getMap ( " Servers " ) . getMap ( name ) . getInt ( " Port " ) ) ,
2019-04-29 17:05:06 +02:00
ChatColor . translateAlternateColorCodes ( '&' , servers . get ( ) . getMap ( " Servers " ) . getMap ( name ) . getString ( " Motd " ) ) , servers . get ( ) . getMap ( " Servers " ) . getMap ( name ) . getBoolean ( " Restricted " ) ) ) ;
2017-08-18 11:58:06 +02:00
} catch ( Exception e ) {
e . printStackTrace ( ) ;
}
2017-04-16 19:02:14 +02:00
}
2017-08-17 01:29:02 +02:00
2019-04-18 16:02:09 +02:00
subprotocol = SubProtocol . get ( ) ;
2020-06-12 07:45:49 +02:00
subprotocol . registerCipher ( " DHE " , DHE . get ( 128 ) ) ;
subprotocol . registerCipher ( " DHE-128 " , DHE . get ( 128 ) ) ;
subprotocol . registerCipher ( " DHE-192 " , DHE . get ( 192 ) ) ;
subprotocol . registerCipher ( " DHE-256 " , DHE . get ( 256 ) ) ;
2019-05-17 00:36:41 +02:00
Logger . get ( " SubServers " ) . info ( " Loading BungeeCord Libraries... " ) ;
2020-01-18 06:13:10 +01:00
if ( isGalaxi ) Util . reflect ( net . ME1312 . SubServers . Bungee . Library . Compatibility . Galaxi . GalaxiEventListener . class . getConstructor ( SubProxy . class ) , this ) ;
2016-12-05 04:21:04 +01:00
}
/ * *
2017-12-09 09:43:29 +01:00
* Load SubServers before BungeeCord finishes
2016-12-05 04:21:04 +01:00
* /
@Override
2018-08-09 20:54:56 +02:00
@SuppressWarnings ( " unchecked " )
2016-12-05 04:21:04 +01:00
public void startListeners ( ) {
try {
2018-08-09 20:54:56 +02:00
if ( getPluginManager ( ) . getPlugin ( " RedisBungee " ) ! = null ) redis = Util . getDespiteException ( ( ) - > new Proxy ( ( String ) redis ( " getServerId " ) ) , null ) ;
2017-12-09 09:43:29 +01:00
reload ( ) ;
2018-10-08 23:07:44 +02:00
if ( UPnP . isUPnPAvailable ( ) ) {
2019-04-18 16:02:09 +02:00
if ( config . get ( ) . getMap ( " Settings " ) . getMap ( " UPnP " , new ObjectMap < String > ( ) ) . getBoolean ( " Forward-Proxy " , true ) ) for ( ListenerInfo listener : getConfig ( ) . getListeners ( ) ) {
2018-10-08 23:07:44 +02:00
UPnP . openPortTCP ( listener . getHost ( ) . getPort ( ) ) ;
}
} else {
getLogger ( ) . warning ( " UPnP is currently unavailable; Ports may not be automatically forwarded on this device " ) ;
}
2017-12-09 09:43:29 +01:00
super . startListeners ( ) ;
2018-10-08 23:07:44 +02:00
2017-12-09 09:43:29 +01:00
if ( ! posted ) {
post ( ) ;
posted = true ;
}
} catch ( IOException e ) {
e . printStackTrace ( ) ;
}
}
/ * *
* Load data from the config ( will attempt to merge with current configuration )
*
* @throws IOException
* /
@SuppressWarnings ( " unchecked " )
public void reload ( ) throws IOException {
List < String > ukeys = new ArrayList < String > ( ) ;
long begin = Calendar . getInstance ( ) . getTime ( ) . getTime ( ) ;
2017-12-10 01:30:06 +01:00
boolean status ;
if ( ! ( status = running ) ) resetDate = begin ;
2020-06-20 03:00:50 +02:00
reloading = true ;
2017-12-09 09:43:29 +01:00
2019-04-29 17:05:06 +02:00
ConfigUpdater . updateConfig ( new UniversalFile ( dir , " SubServers:config.yml " ) ) ;
ConfigUpdater . updateServers ( new UniversalFile ( dir , " SubServers:servers.yml " ) ) ;
ConfigUpdater . updateLang ( new UniversalFile ( dir , " SubServers:lang.yml " ) ) ;
2017-12-09 09:43:29 +01:00
YAMLSection prevconfig = config . get ( ) ;
config . reload ( ) ;
2019-04-29 17:05:06 +02:00
servers . reload ( ) ;
lang . reload ( ) ;
for ( String key : lang . get ( ) . getMap ( " Lang " ) . getKeys ( ) )
api . setLang ( " SubServers " , key , ChatColor . translateAlternateColorCodes ( '&' , lang . get ( ) . getMap ( " Lang " ) . getString ( key ) ) ) ;
2017-12-09 09:43:29 +01:00
2019-08-30 21:44:54 +02:00
if ( subdata ! = null & & ( // SubData Server must be reset
2019-04-18 16:02:09 +02:00
! config . get ( ) . getMap ( " Settings " ) . getMap ( " SubData " ) . getRawString ( " Address " , " 127.0.0.1:4391 " ) . equals ( prevconfig . getMap ( " Settings " ) . getMap ( " SubData " ) . getRawString ( " Address " , " 127.0.0.1:4391 " ) ) | |
! config . get ( ) . getMap ( " Settings " ) . getMap ( " SubData " ) . getRawString ( " Encryption " , " NONE " ) . equals ( prevconfig . getMap ( " Settings " ) . getMap ( " SubData " ) . getRawString ( " Encryption " , " NONE " ) )
2019-08-30 21:44:54 +02:00
) ) {
subdata . close ( ) ;
Util . isException ( subdata : : waitFor ) ;
subdata = null ;
2017-12-09 09:43:29 +01:00
}
2018-08-05 23:41:17 +02:00
int proxies = 1 ;
2018-08-09 20:54:56 +02:00
if ( redis ! = null ) {
2018-08-05 23:41:17 +02:00
try {
2018-08-07 04:39:29 +02:00
boolean first = true ;
2018-08-05 23:41:17 +02:00
String master = ( String ) redis ( " getServerId " ) ;
2018-08-09 20:54:56 +02:00
if ( ! master . equals ( redis . getName ( ) ) ) redis = new Proxy ( master ) ;
if ( ! redis . getDisplayName ( ) . equals ( " (master) " ) ) redis . setDisplayName ( " (master) " ) ;
2018-08-05 23:41:17 +02:00
for ( String name : ( List < String > ) redis ( " getAllServers " ) ) {
if ( ! ukeys . contains ( name . toLowerCase ( ) ) & & ! master . equals ( name ) ) try {
2019-05-17 00:36:41 +02:00
if ( first ) Logger . get ( " SubServers " ) . info ( ( ( status ) ? " Rel " : " L " ) + " oading Proxies... " ) ;
2018-08-07 04:39:29 +02:00
first = false ;
2018-08-05 23:41:17 +02:00
Proxy proxy = this . proxies . get ( name . toLowerCase ( ) ) ;
if ( proxy = = null ) {
proxy = new Proxy ( name ) ;
getPluginManager ( ) . callEvent ( new SubAddProxyEvent ( proxy ) ) ;
this . proxies . put ( name . toLowerCase ( ) , proxy ) ;
}
ukeys . add ( name . toLowerCase ( ) ) ;
proxies + + ;
} catch ( Exception e ) {
e . printStackTrace ( ) ;
}
}
} catch ( Exception e ) {
e . printStackTrace ( ) ;
}
}
ukeys . clear ( ) ;
2016-12-05 04:21:04 +01:00
2017-12-09 09:43:29 +01:00
int hosts = 0 ;
2019-05-17 00:36:41 +02:00
Logger . get ( " SubServers " ) . info ( ( ( status ) ? " Rel " : " L " ) + " oading Hosts... " ) ;
2019-04-18 16:02:09 +02:00
for ( String name : config . get ( ) . getMap ( " Hosts " ) . getKeys ( ) ) {
2017-12-09 09:43:29 +01:00
if ( ! ukeys . contains ( name . toLowerCase ( ) ) ) try {
2019-04-18 16:02:09 +02:00
if ( ! hostDrivers . keySet ( ) . contains ( config . get ( ) . getMap ( " Hosts " ) . getMap ( name ) . getRawString ( " Driver " ) . toUpperCase ( ) . replace ( '-' , '_' ) . replace ( ' ' , '_' ) ) ) throw new InvalidHostException ( " Invalid Driver for host: " + name ) ;
2017-12-09 09:43:29 +01:00
Host host = this . hosts . get ( name . toLowerCase ( ) ) ;
2017-12-10 01:30:06 +01:00
if ( host = = null | | // Host must be reset
2019-04-18 16:02:09 +02:00
! hostDrivers . get ( config . get ( ) . getMap ( " Hosts " ) . getMap ( name ) . getRawString ( " Driver " ) . toUpperCase ( ) . replace ( '-' , '_' ) . replace ( ' ' , '_' ) ) . equals ( host . getClass ( ) ) | |
! config . get ( ) . getMap ( " Hosts " ) . getMap ( name ) . getRawString ( " Address " ) . equals ( host . getAddress ( ) . getHostAddress ( ) ) | |
! config . get ( ) . getMap ( " Hosts " ) . getMap ( name ) . getRawString ( " Directory " ) . equals ( host . getPath ( ) ) | |
! config . get ( ) . getMap ( " Hosts " ) . getMap ( name ) . getRawString ( " Git-Bash " ) . equals ( host . getCreator ( ) . getBashDirectory ( ) )
2017-12-09 09:43:29 +01:00
) {
if ( host ! = null ) api . forceRemoveHost ( name ) ;
2019-04-18 16:02:09 +02:00
host = api . addHost ( config . get ( ) . getMap ( " Hosts " ) . getMap ( name ) . getRawString ( " Driver " ) . toLowerCase ( ) , name , config . get ( ) . getMap ( " Hosts " ) . getMap ( name ) . getBoolean ( " Enabled " ) ,
Range . closed ( Integer . parseInt ( config . get ( ) . getMap ( " Hosts " ) . getMap ( name ) . getRawString ( " Port-Range " , " 25500-25559 " ) . split ( " - " ) [ 0 ] ) , Integer . parseInt ( config . get ( ) . getMap ( " Hosts " ) . getMap ( name ) . getRawString ( " Port-Range " , " 25500-25559 " ) . split ( " - " ) [ 1 ] ) ) ,
config . get ( ) . getMap ( " Hosts " ) . getMap ( name ) . getBoolean ( " Log-Creator " , true ) , InetAddress . getByName ( config . get ( ) . getMap ( " Hosts " ) . getMap ( name ) . getRawString ( " Address " ) ) ,
config . get ( ) . getMap ( " Hosts " ) . getMap ( name ) . getRawString ( " Directory " ) , config . get ( ) . getMap ( " Hosts " ) . getMap ( name ) . getRawString ( " Git-Bash " ) ) ;
2017-12-10 01:30:06 +01:00
} else { // Host wasn't reset, so check for these changes
2019-04-18 16:02:09 +02:00
if ( config . get ( ) . getMap ( " Hosts " ) . getMap ( name ) . getBoolean ( " Enabled " ) ! = host . isEnabled ( ) )
host . setEnabled ( config . get ( ) . getMap ( " Hosts " ) . getMap ( name ) . getBoolean ( " Enabled " ) ) ;
if ( ! config . get ( ) . getMap ( " Hosts " ) . getMap ( name ) . getRawString ( " Port-Range " , " 25500-25559 " ) . equals ( prevconfig . getMap ( " Hosts " , new ObjectMap < String > ( ) ) . getMap ( name , new ObjectMap < String > ( ) ) . getRawString ( " Port-Range " , " 25500-25559 " ) ) )
host . getCreator ( ) . setPortRange ( Range . closed ( Integer . parseInt ( config . get ( ) . getMap ( " Hosts " ) . getMap ( name ) . getRawString ( " Port-Range " , " 25500-25559 " ) . split ( " - " ) [ 0 ] ) , Integer . parseInt ( config . get ( ) . getMap ( " Hosts " ) . getMap ( name ) . getRawString ( " Port-Range " , " 25500-25559 " ) . split ( " - " ) [ 1 ] ) ) ) ;
if ( config . get ( ) . getMap ( " Hosts " ) . getMap ( name ) . getBoolean ( " Log-Creator " , true ) ! = host . getCreator ( ) . isLogging ( ) )
host . getCreator ( ) . setLogging ( config . get ( ) . getMap ( " Hosts " ) . getMap ( name ) . getBoolean ( " Log-Creator " , true ) ) ;
2020-06-12 07:45:49 +02:00
host . getCreator ( ) . reload ( ) ;
2017-12-10 01:30:06 +01:00
} // Check for other changes
2019-06-18 01:30:30 +02:00
if ( config . get ( ) . getMap ( " Hosts " ) . getMap ( name ) . getKeys ( ) . contains ( " Display " ) & & ( ( config . get ( ) . getMap ( " Hosts " ) . getMap ( name ) . getString ( " Display " ) . length ( ) = = 0 & & ! host . getName ( ) . equals ( host . getDisplayName ( ) ) ) | | ( config . get ( ) . getMap ( " Hosts " ) . getMap ( name ) . getString ( " Display " ) . length ( ) > 0 & & ! config . get ( ) . getMap ( " Hosts " ) . getMap ( name ) . getString ( " Display " ) . equals ( host . getDisplayName ( ) ) ) ) )
2019-04-18 16:02:09 +02:00
host . setDisplayName ( config . get ( ) . getMap ( " Hosts " ) . getMap ( name ) . getString ( " Display " ) ) ;
if ( config . get ( ) . getMap ( " Hosts " ) . getMap ( name ) . getKeys ( ) . contains ( " Extra " ) )
for ( String extra : config . get ( ) . getMap ( " Hosts " ) . getMap ( name ) . getMap ( " Extra " ) . getKeys ( ) ) host . addExtra ( extra , config . get ( ) . getMap ( " Hosts " ) . getMap ( name ) . getMap ( " Extra " ) . getObject ( extra ) ) ;
2017-12-09 09:43:29 +01:00
ukeys . add ( name . toLowerCase ( ) ) ;
hosts + + ;
} catch ( Exception e ) {
e . printStackTrace ( ) ;
2016-12-05 04:21:04 +01:00
}
2017-12-09 09:43:29 +01:00
}
ukeys . clear ( ) ;
int servers = 0 ;
2019-05-17 00:36:41 +02:00
Logger . get ( " SubServers " ) . info ( ( ( status ) ? " Rel " : " L " ) + " oading Servers... " ) ;
2019-04-29 17:05:06 +02:00
bungee . reload ( ) ;
for ( String name : bungee . get ( ) . getMap ( " servers " ) . getKeys ( ) ) {
2017-12-09 09:43:29 +01:00
if ( ! ukeys . contains ( name . toLowerCase ( ) ) ) try {
Server server = api . getServer ( name ) ;
if ( server = = null | | ! ( server instanceof SubServer ) ) {
2017-12-10 01:30:06 +01:00
if ( server = = null | | // Server must be reset
2019-04-29 17:05:06 +02:00
bungee . get ( ) . getMap ( " servers " ) . getMap ( name ) . getRawString ( " address " ) . equals ( server . getAddress ( ) . getAddress ( ) . getHostAddress ( ) + ':' + server . getAddress ( ) . getPort ( ) )
2017-12-09 09:43:29 +01:00
) {
if ( server ! = null ) api . forceRemoveServer ( name ) ;
2019-04-29 17:05:06 +02:00
server = api . addServer ( name , InetAddress . getByName ( bungee . get ( ) . getMap ( " servers " ) . getMap ( name ) . getRawString ( " address " ) . split ( " : " ) [ 0 ] ) ,
Integer . parseInt ( bungee . get ( ) . getMap ( " servers " ) . getMap ( name ) . getRawString ( " address " ) . split ( " : " ) [ 1 ] ) , ChatColor . translateAlternateColorCodes ( '&' , bungee . get ( ) . getMap ( " servers " ) . getMap ( name ) . getString ( " motd " ) ) ,
bungee . get ( ) . getMap ( " servers " ) . getMap ( name ) . getBoolean ( " hidden " , false ) , bungee . get ( ) . getMap ( " servers " ) . getMap ( name ) . getBoolean ( " restricted " ) ) ;
2017-12-10 01:30:06 +01:00
} else { // Server wasn't reset, so check for these changes
2019-04-29 17:05:06 +02:00
if ( ! ChatColor . translateAlternateColorCodes ( '&' , bungee . get ( ) . getMap ( " servers " ) . getMap ( name ) . getString ( " motd " ) ) . equals ( server . getMotd ( ) ) )
server . setMotd ( ChatColor . translateAlternateColorCodes ( '&' , bungee . get ( ) . getMap ( " servers " ) . getMap ( name ) . getString ( " motd " ) ) ) ;
if ( bungee . get ( ) . getMap ( " servers " ) . getMap ( name ) . getBoolean ( " hidden " , false ) ! = server . isHidden ( ) )
server . setHidden ( bungee . get ( ) . getMap ( " servers " ) . getMap ( name ) . getBoolean ( " hidden " , false ) ) ;
if ( bungee . get ( ) . getMap ( " servers " ) . getMap ( name ) . getBoolean ( " restricted " ) ! = server . isRestricted ( ) )
server . setRestricted ( bungee . get ( ) . getMap ( " servers " ) . getMap ( name ) . getBoolean ( " restricted " ) ) ;
2017-12-10 01:30:06 +01:00
} // Check for other changes
2019-06-18 01:30:30 +02:00
if ( bungee . get ( ) . getMap ( " servers " ) . getMap ( name ) . getKeys ( ) . contains ( " display " ) & & ( ( bungee . get ( ) . getMap ( " servers " ) . getMap ( name ) . getRawString ( " display " ) . length ( ) = = 0 & & ! server . getName ( ) . equals ( server . getDisplayName ( ) ) ) | | ( bungee . get ( ) . getMap ( " servers " ) . getMap ( name ) . getRawString ( " display " ) . length ( ) > 0 & & ! bungee . get ( ) . getMap ( " servers " ) . getMap ( name ) . getRawString ( " display " ) . equals ( server . getDisplayName ( ) ) ) ) )
2019-04-29 17:05:06 +02:00
server . setDisplayName ( bungee . get ( ) . getMap ( " servers " ) . getMap ( name ) . getString ( " display " ) ) ;
if ( bungee . get ( ) . getMap ( " servers " ) . getMap ( name ) . getKeys ( ) . contains ( " group " ) ) {
2017-12-09 09:43:29 +01:00
for ( String group : server . getGroups ( ) ) server . removeGroup ( group ) ;
2019-04-29 17:05:06 +02:00
for ( String group : bungee . get ( ) . getMap ( " servers " ) . getMap ( name ) . getStringList ( " group " ) ) server . addGroup ( group ) ;
2017-12-09 09:43:29 +01:00
}
2019-04-29 17:05:06 +02:00
if ( bungee . get ( ) . getMap ( " servers " ) . getMap ( name ) . getKeys ( ) . contains ( " extra " ) )
2019-04-18 16:02:09 +02:00
for ( String extra : config . get ( ) . getMap ( " servers " ) . getMap ( name ) . getMap ( " extra " ) . getKeys ( ) ) server . addExtra ( extra , config . get ( ) . getMap ( " servers " ) . getMap ( name ) . getMap ( " extra " ) . getObject ( extra ) ) ;
2019-05-10 04:43:34 +02:00
if ( server . getSubData ( ) [ 0 ] ! = null )
( ( SubDataClient ) server . getSubData ( ) [ 0 ] ) . sendPacket ( new PacketOutExReload ( null ) ) ;
2017-12-09 09:43:29 +01:00
ukeys . add ( name . toLowerCase ( ) ) ;
2016-12-05 04:21:04 +01:00
servers + + ;
}
2017-12-09 09:43:29 +01:00
} catch ( Exception e ) {
e . printStackTrace ( ) ;
2016-12-05 04:21:04 +01:00
}
2017-12-09 09:43:29 +01:00
}
ukeys . clear ( ) ;
2016-12-05 04:21:04 +01:00
2017-12-09 09:43:29 +01:00
int subservers = 0 ;
2019-05-17 00:36:41 +02:00
Logger . get ( " SubServers " ) . info ( ( ( status ) ? " Rel " : " L " ) + " oading SubServers... " ) ;
2017-12-09 09:43:29 +01:00
if ( ! posted ) Runtime . getRuntime ( ) . addShutdownHook ( new Thread ( ( ) - > {
2018-08-10 06:50:10 +02:00
if ( running ) {
2019-05-17 00:36:41 +02:00
Logger . get ( " SubServers " ) . info ( " Received request from system to shutdown " ) ;
2016-12-05 04:21:04 +01:00
try {
2017-12-09 09:43:29 +01:00
shutdown ( ) ;
2016-12-05 04:21:04 +01:00
} catch ( Exception e ) {
e . printStackTrace ( ) ;
}
}
2019-01-06 07:58:13 +01:00
} , " SubServers.Bungee::System_Shutdown " ) ) ;
2017-12-09 09:43:29 +01:00
running = true ;
2018-01-29 07:04:36 +01:00
List < String > autorun = new LinkedList < String > ( ) ;
2019-04-29 17:05:06 +02:00
for ( String name : this . servers . get ( ) . getMap ( " Servers " ) . getKeys ( ) ) {
2017-12-09 09:43:29 +01:00
if ( ! ukeys . contains ( name . toLowerCase ( ) ) ) try {
2019-04-29 17:05:06 +02:00
if ( ! this . hosts . keySet ( ) . contains ( this . servers . get ( ) . getMap ( " Servers " ) . getMap ( name ) . getString ( " Host " ) . toLowerCase ( ) ) ) throw new InvalidServerException ( " There is no host with this name: " + this . servers . get ( ) . getMap ( " Servers " ) . getMap ( name ) . getString ( " Host " ) ) ;
2017-12-09 09:43:29 +01:00
if ( exServers . keySet ( ) . contains ( name . toLowerCase ( ) ) ) {
exServers . remove ( name . toLowerCase ( ) ) ;
servers - - ;
2017-07-21 22:45:41 +02:00
}
2017-12-09 09:43:29 +01:00
SubServer server = api . getSubServer ( name ) ;
if ( server ! = null & & server . isEditable ( ) ) { // Server can edit() (May be reset depending on change severity)
2019-04-18 16:02:09 +02:00
ObjectMap < String > edits = new ObjectMap < String > ( ) ;
2019-04-29 17:05:06 +02:00
if ( this . servers . get ( ) . getMap ( " Servers " ) . getMap ( name ) . getBoolean ( " Enabled " ) ! = server . isEnabled ( ) )
edits . set ( " enabled " , this . servers . get ( ) . getMap ( " Servers " ) . getMap ( name ) . getBoolean ( " Enabled " ) ) ;
2019-06-18 01:30:30 +02:00
if ( this . servers . get ( ) . getMap ( " Servers " ) . getMap ( name ) . getKeys ( ) . contains ( " Display " ) & & ( ( this . servers . get ( ) . getMap ( " Servers " ) . getMap ( name ) . getRawString ( " Display " ) . length ( ) = = 0 & & ! server . getName ( ) . equals ( server . getDisplayName ( ) ) ) | | ( this . servers . get ( ) . getMap ( " Servers " ) . getMap ( name ) . getRawString ( " Display " ) . length ( ) > 0 & & ! this . servers . get ( ) . getMap ( " Servers " ) . getMap ( name ) . getRawString ( " Display " ) . equals ( server . getDisplayName ( ) ) ) ) )
2019-04-29 17:05:06 +02:00
edits . set ( " display " , this . servers . get ( ) . getMap ( " Servers " ) . getMap ( name ) . getRawString ( " Display " ) ) ;
if ( ! this . servers . get ( ) . getMap ( " Servers " ) . getMap ( name ) . getString ( " Host " ) . equalsIgnoreCase ( server . getHost ( ) . getName ( ) ) )
edits . set ( " host " , this . servers . get ( ) . getMap ( " Servers " ) . getMap ( name ) . getRawString ( " Host " ) ) ;
2019-06-17 05:13:48 +02:00
if ( this . servers . get ( ) . getMap ( " Servers " ) . getMap ( name ) . getKeys ( ) . contains ( " Template " ) & & ( ( this . servers . get ( ) . getMap ( " Servers " ) . getMap ( name ) . getRawString ( " Template " ) . length ( ) = = 0 & & server . getTemplate ( ) ! = null ) | | ( this . servers . get ( ) . getMap ( " Servers " ) . getMap ( name ) . getRawString ( " Template " ) . length ( ) > 0 & & server . getTemplate ( ) = = null ) | | ( server . getTemplate ( ) ! = null & & ! this . servers . get ( ) . getMap ( " Servers " ) . getMap ( name ) . getString ( " Template " ) . equalsIgnoreCase ( server . getTemplate ( ) . getName ( ) ) ) ) )
edits . set ( " template " , this . servers . get ( ) . getMap ( " Servers " ) . getMap ( name ) . getString ( " Template " ) ) ;
2019-04-29 17:05:06 +02:00
if ( ! this . servers . get ( ) . getMap ( " Servers " ) . getMap ( name ) . getStringList ( " Group " ) . equals ( server . getGroups ( ) ) )
edits . set ( " group " , this . servers . get ( ) . getMap ( " Servers " ) . getMap ( name ) . getRawStringList ( " Group " ) ) ;
if ( this . servers . get ( ) . getMap ( " Servers " ) . getMap ( name ) . getInt ( " Port " ) ! = server . getAddress ( ) . getPort ( ) )
edits . set ( " port " , this . servers . get ( ) . getMap ( " Servers " ) . getMap ( name ) . getInt ( " Port " ) ) ;
if ( ! ( ChatColor . translateAlternateColorCodes ( '&' , this . servers . get ( ) . getMap ( " Servers " ) . getMap ( name ) . getString ( " Motd " ) ) . equals ( server . getMotd ( ) ) ) )
edits . set ( " motd " , this . servers . get ( ) . getMap ( " Servers " ) . getMap ( name ) . getRawString ( " Motd " ) ) ;
if ( this . servers . get ( ) . getMap ( " Servers " ) . getMap ( name ) . getBoolean ( " Log " ) ! = server . isLogging ( ) )
edits . set ( " log " , this . servers . get ( ) . getMap ( " Servers " ) . getMap ( name ) . getBoolean ( " Log " ) ) ;
if ( ! this . servers . get ( ) . getMap ( " Servers " ) . getMap ( name ) . getRawString ( " Directory " ) . equals ( server . getPath ( ) ) )
edits . set ( " dir " , this . servers . get ( ) . getMap ( " Servers " ) . getMap ( name ) . getRawString ( " Directory " ) ) ;
if ( ! this . servers . get ( ) . getMap ( " Servers " ) . getMap ( name ) . getRawString ( " Executable " ) . equals ( server . getExecutable ( ) ) )
edits . set ( " exec " , this . servers . get ( ) . getMap ( " Servers " ) . getMap ( name ) . getRawString ( " Executable " ) ) ;
if ( ! this . servers . get ( ) . getMap ( " Servers " ) . getMap ( name ) . getRawString ( " Stop-Command " ) . equals ( server . getStopCommand ( ) ) )
edits . set ( " stop-cmd " , this . servers . get ( ) . getMap ( " Servers " ) . getMap ( name ) . getRawString ( " Stop-Command " ) ) ;
SubServer . StopAction action = Util . getDespiteException ( ( ) - > SubServer . StopAction . valueOf ( this . servers . get ( ) . getMap ( " Servers " ) . getMap ( name ) . getRawString ( " Stop-Action " , " NONE " ) . toUpperCase ( ) . replace ( '-' , '_' ) . replace ( ' ' , '_' ) ) , null ) ;
2018-08-30 03:55:59 +02:00
if ( action ! = null & & action ! = server . getStopAction ( ) )
edits . set ( " stop-action " , action . toString ( ) ) ;
2019-04-29 17:05:06 +02:00
if ( this . servers . get ( ) . getMap ( " Servers " ) . getMap ( name ) . getBoolean ( " Restricted " ) ! = server . isRestricted ( ) )
edits . set ( " restricted " , this . servers . get ( ) . getMap ( " Servers " ) . getMap ( name ) . getBoolean ( " Restricted " ) ) ;
if ( this . servers . get ( ) . getMap ( " Servers " ) . getMap ( name ) . getBoolean ( " Hidden " ) ! = server . isHidden ( ) )
edits . set ( " hidden " , this . servers . get ( ) . getMap ( " Servers " ) . getMap ( name ) . getBoolean ( " Hidden " ) ) ;
2017-12-09 09:43:29 +01:00
if ( edits . getKeys ( ) . size ( ) > 0 ) {
2019-06-18 02:20:46 +02:00
server . edit ( edits ) ;
2017-12-09 09:43:29 +01:00
server = api . getSubServer ( name ) ;
2018-08-10 21:58:17 +02:00
}
2017-12-09 09:43:29 +01:00
} else { // Server cannot edit()
if ( server = = null | | // Server must be reset
2019-04-29 17:05:06 +02:00
! this . servers . get ( ) . getMap ( " Servers " ) . getMap ( name ) . getString ( " Host " ) . equalsIgnoreCase ( server . getHost ( ) . getName ( ) ) | |
this . servers . get ( ) . getMap ( " Servers " ) . getMap ( name ) . getInt ( " Port " ) ! = server . getAddress ( ) . getPort ( ) | |
! this . servers . get ( ) . getMap ( " Servers " ) . getMap ( name ) . getRawString ( " Directory " ) . equals ( server . getPath ( ) ) | |
! this . servers . get ( ) . getMap ( " Servers " ) . getMap ( name ) . getRawString ( " Executable " ) . equals ( server . getExecutable ( ) )
2017-12-09 09:43:29 +01:00
) {
if ( server ! = null ) server . getHost ( ) . forceRemoveSubServer ( name ) ;
2019-04-29 17:05:06 +02:00
server = this . hosts . get ( this . servers . get ( ) . getMap ( " Servers " ) . getMap ( name ) . getString ( " Host " ) . toLowerCase ( ) ) . addSubServer ( name , this . servers . get ( ) . getMap ( " Servers " ) . getMap ( name ) . getBoolean ( " Enabled " ) ,
this . servers . get ( ) . getMap ( " Servers " ) . getMap ( name ) . getInt ( " Port " ) , ChatColor . translateAlternateColorCodes ( '&' , this . servers . get ( ) . getMap ( " Servers " ) . getMap ( name ) . getString ( " Motd " ) ) , this . servers . get ( ) . getMap ( " Servers " ) . getMap ( name ) . getBoolean ( " Log " ) ,
this . servers . get ( ) . getMap ( " Servers " ) . getMap ( name ) . getRawString ( " Directory " ) , this . servers . get ( ) . getMap ( " Servers " ) . getMap ( name ) . getRawString ( " Executable " ) , this . servers . get ( ) . getMap ( " Servers " ) . getMap ( name ) . getRawString ( " Stop-Command " ) ,
this . servers . get ( ) . getMap ( " Servers " ) . getMap ( name ) . getBoolean ( " Hidden " ) , this . servers . get ( ) . getMap ( " Servers " ) . getMap ( name ) . getBoolean ( " Restricted " ) ) ;
2017-12-09 09:43:29 +01:00
} else { // Server doesn't need to reset
2019-04-29 17:05:06 +02:00
if ( this . servers . get ( ) . getMap ( " Servers " ) . getMap ( name ) . getBoolean ( " Enabled " ) ! = server . isEnabled ( ) )
server . setEnabled ( this . servers . get ( ) . getMap ( " Servers " ) . getMap ( name ) . getBoolean ( " Enabled " ) ) ;
if ( ! ChatColor . translateAlternateColorCodes ( '&' , this . servers . get ( ) . getMap ( " Servers " ) . getMap ( name ) . getString ( " Motd " ) ) . equals ( server . getMotd ( ) ) )
server . setMotd ( ChatColor . translateAlternateColorCodes ( '&' , this . servers . get ( ) . getMap ( " Servers " ) . getMap ( name ) . getString ( " Motd " ) ) ) ;
if ( this . servers . get ( ) . getMap ( " Servers " ) . getMap ( name ) . getBoolean ( " Log " ) ! = server . isLogging ( ) )
server . setLogging ( this . servers . get ( ) . getMap ( " Servers " ) . getMap ( name ) . getBoolean ( " Log " ) ) ;
if ( ! this . servers . get ( ) . getMap ( " Servers " ) . getMap ( name ) . getRawString ( " Stop-Command " ) . equals ( server . getStopCommand ( ) ) )
server . setStopCommand ( this . servers . get ( ) . getMap ( " Servers " ) . getMap ( name ) . getRawString ( " Stop-Command " ) ) ;
if ( this . servers . get ( ) . getMap ( " Servers " ) . getMap ( name ) . getBoolean ( " Restricted " ) ! = server . isRestricted ( ) )
server . setRestricted ( this . servers . get ( ) . getMap ( " Servers " ) . getMap ( name ) . getBoolean ( " Restricted " ) ) ;
if ( this . servers . get ( ) . getMap ( " Servers " ) . getMap ( name ) . getBoolean ( " Hidden " ) ! = server . isHidden ( ) )
server . setHidden ( this . servers . get ( ) . getMap ( " Servers " ) . getMap ( name ) . getBoolean ( " Hidden " ) ) ;
2017-12-09 09:43:29 +01:00
} // Apply these changes regardless of reset
2019-04-29 17:05:06 +02:00
SubServer . StopAction action = Util . getDespiteException ( ( ) - > SubServer . StopAction . valueOf ( this . servers . get ( ) . getMap ( " Servers " ) . getMap ( name ) . getRawString ( " Stop-Action " , " NONE " ) . toUpperCase ( ) . replace ( '-' , '_' ) . replace ( ' ' , '_' ) ) , null ) ;
2018-08-30 03:55:59 +02:00
if ( action ! = null & & action ! = server . getStopAction ( ) )
server . setStopAction ( action ) ;
2019-04-29 17:05:06 +02:00
if ( ! status & & this . servers . get ( ) . getMap ( " Servers " ) . getMap ( name ) . getBoolean ( " Run-On-Launch " ) )
2018-01-29 07:04:36 +01:00
autorun . add ( name . toLowerCase ( ) ) ;
2019-06-18 01:30:30 +02:00
if ( this . servers . get ( ) . getMap ( " Servers " ) . getMap ( name ) . getKeys ( ) . contains ( " Display " ) & & ( ( this . servers . get ( ) . getMap ( " Servers " ) . getMap ( name ) . getRawString ( " Display " ) . length ( ) = = 0 & & ! server . getName ( ) . equals ( server . getDisplayName ( ) ) ) | | ( this . servers . get ( ) . getMap ( " Servers " ) . getMap ( name ) . getRawString ( " Display " ) . length ( ) > 0 & & ! this . servers . get ( ) . getMap ( " Servers " ) . getMap ( name ) . getRawString ( " Display " ) . equals ( server . getDisplayName ( ) ) ) ) )
2019-04-29 17:05:06 +02:00
server . setDisplayName ( this . servers . get ( ) . getMap ( " Servers " ) . getMap ( name ) . getRawString ( " Display " ) ) ;
2019-06-17 05:13:48 +02:00
if ( this . servers . get ( ) . getMap ( " Servers " ) . getMap ( name ) . getKeys ( ) . contains ( " Template " ) & & ( ( this . servers . get ( ) . getMap ( " Servers " ) . getMap ( name ) . getRawString ( " Template " ) . length ( ) = = 0 & & server . getTemplate ( ) ! = null ) | | ( this . servers . get ( ) . getMap ( " Servers " ) . getMap ( name ) . getRawString ( " Template " ) . length ( ) > 0 & & server . getTemplate ( ) = = null ) | | ( server . getTemplate ( ) ! = null & & ! this . servers . get ( ) . getMap ( " Servers " ) . getMap ( name ) . getString ( " Template " ) . equalsIgnoreCase ( server . getTemplate ( ) . getName ( ) ) ) ) )
2020-06-20 03:00:50 +02:00
server . setTemplate ( this . servers . get ( ) . getMap ( " Servers " ) . getMap ( name ) . getRawString ( " Template " ) ) ;
2019-04-29 17:05:06 +02:00
if ( this . servers . get ( ) . getMap ( " Servers " ) . getMap ( name ) . getKeys ( ) . contains ( " Group " ) ) {
2017-12-09 09:43:29 +01:00
for ( String group : server . getGroups ( ) ) server . removeGroup ( group ) ;
2019-04-29 17:05:06 +02:00
for ( String group : this . servers . get ( ) . getMap ( " Servers " ) . getMap ( name ) . getStringList ( " Group " ) ) server . addGroup ( group ) ;
2017-12-09 09:43:29 +01:00
}
} // Apply these changes regardless of edit/reset
2019-04-29 17:05:06 +02:00
if ( this . servers . get ( ) . getMap ( " Servers " ) . getMap ( name ) . getKeys ( ) . contains ( " Extra " ) ) for ( String extra : this . servers . get ( ) . getMap ( " Servers " ) . getMap ( name ) . getMap ( " Extra " ) . getKeys ( ) ) server . addExtra ( extra , this . servers . get ( ) . getMap ( " Servers " ) . getMap ( name ) . getMap ( " Extra " ) . getObject ( extra ) ) ;
2017-12-09 09:43:29 +01:00
ukeys . add ( name . toLowerCase ( ) ) ;
subservers + + ;
} catch ( Exception e ) {
e . printStackTrace ( ) ;
2017-07-21 22:45:41 +02:00
}
2017-12-09 09:43:29 +01:00
}
for ( String name : ukeys ) {
SubServer server = api . getSubServer ( name ) ;
2019-04-29 17:05:06 +02:00
for ( String oname : this . servers . get ( ) . getMap ( " Servers " ) . getMap ( server . getName ( ) ) . getRawStringList ( " Incompatible " , new ArrayList < > ( ) ) ) {
2017-12-09 09:43:29 +01:00
SubServer oserver = api . getSubServer ( oname ) ;
if ( oserver ! = null & & server . isCompatible ( oserver ) ) server . toggleCompatibility ( oserver ) ;
}
}
ukeys . clear ( ) ;
api . ready = true ;
legServers . clear ( ) ;
2019-08-30 21:44:54 +02:00
// Initialize SubData
if ( subdata = = null ) {
subprotocol . unregisterCipher ( " AES " ) ;
subprotocol . unregisterCipher ( " AES-128 " ) ;
subprotocol . unregisterCipher ( " AES-192 " ) ;
subprotocol . unregisterCipher ( " AES-256 " ) ;
subprotocol . unregisterCipher ( " RSA " ) ;
2020-06-12 07:45:49 +02:00
subprotocol . setBlockSize ( config . get ( ) . getMap ( " Settings " ) . getMap ( " SubData " ) . getLong ( " Block-Size " , ( long ) DataSize . MB ) ) ;
subprotocol . setTimeout ( TimeUnit . SECONDS . toMillis ( config . get ( ) . getMap ( " Settings " ) . getMap ( " SubData " ) . getInt ( " Timeout " , 30 ) ) ) ;
2019-08-30 21:44:54 +02:00
String cipher = config . get ( ) . getMap ( " Settings " ) . getMap ( " SubData " ) . getRawString ( " Encryption " , " NULL " ) ;
String [ ] ciphers = ( cipher . contains ( " / " ) ) ? cipher . split ( " / " ) : new String [ ] { cipher } ;
2020-06-12 07:45:49 +02:00
2019-08-30 21:44:54 +02:00
if ( ciphers [ 0 ] . equals ( " AES " ) | | ciphers [ 0 ] . equals ( " AES-128 " ) | | ciphers [ 0 ] . equals ( " AES-192 " ) | | ciphers [ 0 ] . equals ( " AES-256 " ) ) {
if ( config . get ( ) . getMap ( " Settings " ) . getMap ( " SubData " ) . getRawString ( " Password " , " " ) . length ( ) = = 0 ) {
byte [ ] bytes = new byte [ 32 ] ;
new SecureRandom ( ) . nextBytes ( bytes ) ;
String random = Base64 . getUrlEncoder ( ) . withoutPadding ( ) . encodeToString ( bytes ) ;
if ( random . length ( ) > bytes . length ) random = random . substring ( 0 , bytes . length ) ;
config . get ( ) . getMap ( " Settings " ) . getMap ( " SubData " ) . set ( " Password " , random ) ;
config . save ( ) ;
}
subprotocol . registerCipher ( " AES " , new AES ( 128 , config . get ( ) . getMap ( " Settings " ) . getMap ( " SubData " ) . getRawString ( " Password " ) ) ) ;
subprotocol . registerCipher ( " AES-128 " , new AES ( 128 , config . get ( ) . getMap ( " Settings " ) . getMap ( " SubData " ) . getRawString ( " Password " ) ) ) ;
subprotocol . registerCipher ( " AES-192 " , new AES ( 192 , config . get ( ) . getMap ( " Settings " ) . getMap ( " SubData " ) . getRawString ( " Password " ) ) ) ;
subprotocol . registerCipher ( " AES-256 " , new AES ( 256 , config . get ( ) . getMap ( " Settings " ) . getMap ( " SubData " ) . getRawString ( " Password " ) ) ) ;
Logger . get ( " SubData " ) . info ( " Encrypting SubData with AES: " ) ;
2020-06-12 07:45:49 +02:00
Logger . get ( " SubData " ) . info ( " Use the password field in config.yml to allow clients to connect " ) ;
} else if ( ciphers [ 0 ] . equals ( " DHE " ) | | ciphers [ 0 ] . equals ( " DHE-128 " ) | | ciphers [ 0 ] . equals ( " DHE-192 " ) | | ciphers [ 0 ] . equals ( " DHE-256 " ) ) {
Logger . get ( " SubData " ) . info ( " Encrypting SubData with DHE/AES: " ) ;
Logger . get ( " SubData " ) . info ( " SubData will negotiate what password to use automatically using the Diffie-Hellman Exchange " ) ;
2019-08-30 21:44:54 +02:00
} else if ( ciphers [ 0 ] . equals ( " RSA " ) | | ciphers [ 0 ] . equals ( " RSA-2048 " ) | | ciphers [ 0 ] . equals ( " RSA-3072 " ) | | ciphers [ 0 ] . equals ( " RSA-4096 " ) ) {
try {
int length = ( ciphers [ 0 ] . contains ( " - " ) ) ? Integer . parseInt ( ciphers [ 0 ] . split ( " - " ) [ 1 ] ) : 2048 ;
if ( ! ( new UniversalFile ( " SubServers:Cache " ) . exists ( ) ) ) new UniversalFile ( " SubServers:Cache " ) . mkdirs ( ) ;
subprotocol . registerCipher ( " RSA " , new RSA ( length , new UniversalFile ( " SubServers:Cache:private.rsa.key " ) , new UniversalFile ( " SubServers:subdata.rsa.key " ) ) ) ;
cipher = " RSA " + cipher . substring ( ciphers [ 0 ] . length ( ) ) ;
Logger . get ( " SubData " ) . info ( " Encrypting SubData with RSA: " ) ;
Logger . get ( " SubData " ) . info ( " Copy your subdata.rsa.key to clients to allow them to connect " ) ;
} catch ( Exception e ) {
e . printStackTrace ( ) ;
}
}
Logger . get ( " SubData " ) . info ( " " ) ;
subdata = subprotocol . open ( ( config . get ( ) . getMap ( " Settings " ) . getMap ( " SubData " ) . getRawString ( " Address " , " 127.0.0.1:4391 " ) . split ( " : " ) [ 0 ] . equals ( " 0.0.0.0 " ) ) ? null : InetAddress . getByName ( config . get ( ) . getMap ( " Settings " ) . getMap ( " SubData " ) . getRawString ( " Address " , " 127.0.0.1:4391 " ) . split ( " : " ) [ 0 ] ) ,
Integer . parseInt ( config . get ( ) . getMap ( " Settings " ) . getMap ( " SubData " ) . getRawString ( " Address " , " 127.0.0.1:4391 " ) . split ( " : " ) [ 1 ] ) , cipher ) ;
} // Add new entries to Allowed-Connections
2019-08-31 19:26:37 +02:00
for ( String s : config . get ( ) . getMap ( " Settings " ) . getMap ( " SubData " ) . getStringList ( " Whitelist " , new ArrayList < String > ( ) ) ) {
2019-08-30 21:44:54 +02:00
try {
subdata . whitelist ( s ) ;
} catch ( Exception e ) {
e . printStackTrace ( ) ;
}
}
2017-12-09 09:43:29 +01:00
int plugins = 0 ;
2019-01-23 18:27:34 +01:00
List < Runnable > listeners = ( status ) ? api . reloadListeners : api . enableListeners ;
2017-12-13 18:29:50 +01:00
if ( listeners . size ( ) > 0 ) {
2019-05-17 00:36:41 +02:00
Logger . get ( " SubServers " ) . info ( ( ( status ) ? " Rel " : " L " ) + " oading SubAPI Plugins... " ) ;
2019-01-23 18:27:34 +01:00
for ( Runnable obj : listeners ) {
try {
obj . run ( ) ;
plugins + + ;
} catch ( Throwable e ) {
new InvocationTargetException ( e , " Problem " + ( ( status ) ? " reloading " : " enabling " ) + " plugin " ) . printStackTrace ( ) ;
2017-01-26 23:19:48 +01:00
}
}
2016-12-05 04:21:04 +01:00
}
2017-12-09 09:43:29 +01:00
2018-08-10 21:58:17 +02:00
if ( status ) {
2019-05-10 04:43:34 +02:00
for ( Host host : api . getHosts ( ) . values ( ) ) if ( host instanceof ClientHandler & & ( ( ClientHandler ) host ) . getSubData ( ) [ 0 ] ! = null ) ( ( SubDataClient ) ( ( ClientHandler ) host ) . getSubData ( ) [ 0 ] ) . sendPacket ( new PacketOutExReload ( null ) ) ;
for ( Server server : api . getServers ( ) . values ( ) ) if ( server . getSubData ( ) [ 0 ] ! = null ) ( ( SubDataClient ) server . getSubData ( ) [ 0 ] ) . sendPacket ( new PacketOutExReload ( null ) ) ;
2018-08-10 21:58:17 +02:00
}
2020-06-20 03:00:50 +02:00
reloading = false ;
2019-05-17 00:36:41 +02:00
Logger . get ( " SubServers " ) . info ( ( ( plugins > 0 ) ? plugins + " Plugin " + ( ( plugins = = 1 ) ? " " : " s " ) + " , " : " " ) + ( ( proxies > 1 ) ? proxies + " Proxies, " : " " ) + hosts + " Host " + ( ( hosts = = 1 ) ? " " : " s " ) + " , " + servers + " Server " + ( ( servers = = 1 ) ? " " : " s " ) + " , and " + subservers + " SubServer " + ( ( subservers = = 1 ) ? " " : " s " ) + " " + ( ( status ) ? " re " : " " ) + " loaded in " + new DecimalFormat ( " 0.000 " ) . format ( ( Calendar . getInstance ( ) . getTime ( ) . getTime ( ) - begin ) / 1000D ) + " s " ) ;
2019-01-30 04:05:59 +01:00
2019-04-29 17:05:06 +02:00
long scd = TimeUnit . SECONDS . toMillis ( this . servers . get ( ) . getMap ( " Settings " ) . getLong ( " Run-On-Launch-Timeout " , 0L ) ) ;
2019-01-30 04:32:28 +01:00
if ( autorun . size ( ) > 0 ) for ( Host host : api . getHosts ( ) . values ( ) ) {
List < String > ar = new LinkedList < String > ( ) ;
for ( String name : autorun ) if ( host . getSubServer ( name ) ! = null ) ar . add ( name ) ;
if ( ar . size ( ) > 0 ) new Thread ( ( ) - > {
2019-01-30 04:05:59 +01:00
try {
while ( running & & begin = = resetDate & & ! host . isAvailable ( ) ) {
Thread . sleep ( 250 ) ;
}
long init = Calendar . getInstance ( ) . getTime ( ) . getTime ( ) ;
while ( running & & begin = = resetDate & & ar . size ( ) > 0 ) {
SubServer server = host . getSubServer ( ar . get ( 0 ) ) ;
ar . remove ( 0 ) ;
if ( server ! = null & & ! server . isRunning ( ) ) {
server . start ( ) ;
if ( ar . size ( ) > 0 & & scd > 0 ) {
long sleep = Calendar . getInstance ( ) . getTime ( ) . getTime ( ) ;
2019-05-10 04:43:34 +02:00
while ( running & & begin = = resetDate & & server . getSubData ( ) [ 0 ] = = null & & Calendar . getInstance ( ) . getTime ( ) . getTime ( ) - sleep < scd ) {
2019-01-30 04:05:59 +01:00
Thread . sleep ( 250 ) ;
}
}
}
}
if ( running & & begin = = resetDate & & Calendar . getInstance ( ) . getTime ( ) . getTime ( ) - init > = 5000 )
2019-05-17 00:36:41 +02:00
Logger . get ( " SubServers " ) . info ( " The auto-start queue for " + host . getName ( ) + " has been finished " ) ;
2019-01-30 04:05:59 +01:00
} catch ( Exception e ) {
e . printStackTrace ( ) ;
}
} , " SubServers.Bungee::Automatic_Server_Starter( " + host . getName ( ) + " ) " ) . start ( ) ;
}
2016-12-05 04:21:04 +01:00
}
2017-08-18 11:58:06 +02:00
private void post ( ) {
2019-04-18 16:02:09 +02:00
if ( config . get ( ) . getMap ( " Settings " ) . getBoolean ( " Override-Bungee-Commands " , true ) ) {
2017-12-13 18:29:50 +01:00
getPluginManager ( ) . registerCommand ( null , SubCommand . BungeeServer . newInstance ( this , " server " ) . get ( ) ) ;
2017-12-08 08:35:50 +01:00
getPluginManager ( ) . registerCommand ( null , new SubCommand . BungeeList ( this , " glist " ) ) ;
}
2019-04-29 17:05:06 +02:00
if ( config . get ( ) . getMap ( " Settings " ) . getBoolean ( " Smart-Fallback " , true ) ) {
2020-06-21 23:42:10 +02:00
setReconnectHandler ( new SmartFallback ( ) ) ;
2019-04-29 17:05:06 +02:00
}
2017-12-13 18:29:50 +01:00
getPluginManager ( ) . registerCommand ( null , SubCommand . newInstance ( this , " subservers " ) . get ( ) ) ;
getPluginManager ( ) . registerCommand ( null , SubCommand . newInstance ( this , " subserver " ) . get ( ) ) ;
getPluginManager ( ) . registerCommand ( null , SubCommand . newInstance ( this , " sub " ) . get ( ) ) ;
2019-06-17 05:13:48 +02:00
GalaxiCommand . group ( SubCommand . class ) ;
2017-12-08 08:35:50 +01:00
2017-08-18 11:58:06 +02:00
new Metrics ( this ) ;
2019-01-06 07:58:13 +01:00
new Timer ( " SubServers.Bungee::Routine_Update_Check " ) . schedule ( new TimerTask ( ) {
2018-07-27 21:36:51 +02:00
@SuppressWarnings ( " unchecked " )
2017-08-18 11:58:06 +02:00
@Override
public void run ( ) {
try {
2019-04-18 16:02:09 +02:00
ObjectMap < String > tags = new ObjectMap < String > ( new Gson ( ) . fromJson ( " { \" tags \" : " + Util . readAll ( new BufferedReader ( new InputStreamReader ( new URL ( " https://api.github.com/repos/ME1312/SubServers-2/git/refs/tags " ) . openStream ( ) , Charset . forName ( " UTF-8 " ) ) ) ) + '}' , Map . class ) ) ;
2018-07-29 05:02:47 +02:00
List < Version > versions = new LinkedList < Version > ( ) ;
2017-08-18 11:58:06 +02:00
Version updversion = version ;
2018-03-14 22:50:15 +01:00
int updcount = 0 ;
2019-04-18 16:02:09 +02:00
for ( ObjectMap < String > tag : tags . getMapList ( " tags " ) ) versions . add ( Version . fromString ( tag . getString ( " ref " ) . substring ( 10 ) ) ) ;
2018-07-29 05:02:47 +02:00
Collections . sort ( versions ) ;
for ( Version version : versions ) {
if ( version . compareTo ( updversion ) > 0 ) {
2018-07-27 21:36:51 +02:00
updversion = version ;
updcount + + ;
2017-08-18 11:58:06 +02:00
}
}
2019-05-17 00:36:41 +02:00
if ( updcount > 0 ) Logger . get ( " SubServers " ) . info ( " SubServers.Bungee 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-12-10 01:30:06 +01:00
/ * *
* Reset all changes made by startListeners
*
2019-08-30 21:44:54 +02:00
* @see SubProxy # startListeners ( )
2017-12-10 01:30:06 +01:00
* /
@Override
public void stopListeners ( ) {
try {
legServers . clear ( ) ;
legServers . putAll ( getServers ( ) ) ;
2019-01-23 18:27:34 +01:00
if ( api . disableListeners . size ( ) > 0 ) {
2019-05-17 00:36:41 +02:00
Logger . get ( " SubServers " ) . info ( " Resetting SubAPI Plugins... " ) ;
2019-01-23 18:27:34 +01:00
for ( Runnable listener : api . disableListeners ) {
2017-12-10 01:30:06 +01:00
try {
2019-01-23 18:27:34 +01:00
listener . run ( ) ;
2017-12-10 01:30:06 +01:00
} catch ( Throwable e ) {
new InvocationTargetException ( e , " Problem disabling plugin " ) . printStackTrace ( ) ;
}
}
}
shutdown ( ) ;
2019-04-18 16:02:09 +02:00
subdata . close ( ) ;
2018-10-08 01:25:08 +02:00
for ( ListenerInfo listener : getConfig ( ) . getListeners ( ) ) {
if ( UPnP . isUPnPAvailable ( ) & & UPnP . isMappedTCP ( listener . getHost ( ) . getPort ( ) ) ) UPnP . closePortTCP ( listener . getHost ( ) . getPort ( ) ) ;
}
2017-12-10 01:30:06 +01:00
} catch ( Exception e ) {
e . printStackTrace ( ) ;
}
super . stopListeners ( ) ;
} private void shutdown ( ) throws Exception {
api . ready = false ;
2019-05-17 00:36:41 +02:00
Logger . get ( " SubServers " ) . info ( " Resetting Hosts and Server Data " ) ;
2017-12-10 01:30:06 +01:00
List < String > hosts = new ArrayList < String > ( ) ;
hosts . addAll ( this . hosts . keySet ( ) ) ;
for ( String host : hosts ) {
api . forceRemoveHost ( host ) ;
}
running = false ;
this . hosts . clear ( ) ;
exServers . clear ( ) ;
2018-08-05 23:41:17 +02:00
for ( String proxy : proxies . keySet ( ) ) {
getPluginManager ( ) . callEvent ( new SubRemoveProxyEvent ( proxies . get ( proxy ) ) ) ;
}
proxies . clear ( ) ;
2018-10-08 01:25:08 +02:00
for ( ListenerInfo listener : getConfig ( ) . getListeners ( ) ) {
if ( UPnP . isUPnPAvailable ( ) & & UPnP . isMappedTCP ( listener . getHost ( ) . getPort ( ) ) ) UPnP . closePortTCP ( listener . getHost ( ) . getPort ( ) ) ;
}
2017-12-10 01:30:06 +01:00
}
2017-12-13 18:29:50 +01:00
String getNewSignature ( ) {
BigInteger number = ( lastSignature = lastSignature . add ( BigInteger . ONE ) ) ;
2018-01-21 21:45:27 +01:00
final String DIGITS = " 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz-_ " ;
2018-01-13 22:22:13 +01:00
final BigInteger BASE = BigInteger . valueOf ( DIGITS . length ( ) ) ;
2017-12-13 18:29:50 +01:00
StringBuilder result = new StringBuilder ( ) ;
2018-01-13 22:22:13 +01:00
while ( number . compareTo ( BigInteger . ZERO ) > 0 ) { // number > 0
2017-12-13 18:29:50 +01:00
BigInteger [ ] divmod = number . divideAndRemainder ( BASE ) ;
number = divmod [ 0 ] ;
int digit = divmod [ 1 ] . intValue ( ) ;
result . insert ( 0 , DIGITS . charAt ( digit ) ) ;
}
return ( result . length ( ) = = 0 ) ? DIGITS . substring ( 0 , 1 ) : result . toString ( ) ;
2017-12-10 01:30:06 +01:00
}
2017-12-08 08:35:50 +01:00
/ * *
* Reference a RedisBungee method via reflection
*
* @param method Method to reference
* @param args Method arguments
* @return Method Response
* /
@SuppressWarnings ( " unchecked " )
2018-01-21 21:45:27 +01:00
public Object redis ( String method , NamedContainer < Class < ? > , ? > . . . args ) throws NoSuchMethodException , InvocationTargetException , IllegalAccessException {
2018-08-09 20:54:56 +02:00
if ( getPluginManager ( ) . getPlugin ( " RedisBungee " ) ! = null ) {
2017-12-08 08:35:50 +01:00
Object api = getPluginManager ( ) . getPlugin ( " RedisBungee " ) . getClass ( ) . getMethod ( " getApi " ) . invoke ( null ) ;
Class < ? > [ ] classargs = new Class < ? > [ args . length ] ;
Object [ ] objargs = new Object [ args . length ] ;
for ( int i = 0 ; i < args . length ; i + + ) {
classargs [ i ] = args [ i ] . name ( ) ;
objargs [ i ] = args [ i ] . get ( ) ;
2020-06-12 07:45:49 +02:00
if ( ! classargs [ i ] . isPrimitive ( ) & & ! classargs [ i ] . isInstance ( objargs [ i ] ) ) throw new ClassCastException ( classargs [ i ] . getCanonicalName ( ) + " != " + objargs [ i ] . getClass ( ) . getCanonicalName ( ) ) ;
2017-12-08 08:35:50 +01:00
}
return api . getClass ( ) . getMethod ( method , classargs ) . invoke ( api , objargs ) ;
} else {
throw new IllegalStateException ( " RedisBungee is not installed " ) ;
}
}
2017-12-07 23:51:06 +01:00
/ * *
* Further override BungeeCord ' s signature when patched into the same jar
*
* @return Software Name
* /
@Override
public String getName ( ) {
2018-08-30 03:55:59 +02:00
return ( isPatched ) ? " SubServers Platform " : super . getName ( ) ;
2017-12-07 23:51:06 +01:00
}
/ * *
2018-05-24 20:52:47 +02:00
* Get the name from BungeeCord ' s original signature ( for determining which fork is being used )
2017-12-07 23:51:06 +01:00
*
2018-05-24 20:52:47 +02:00
* @return BungeeCord Software Name
2017-12-07 23:51:06 +01:00
* /
2018-05-24 20:52:47 +02:00
public String getBungeeName ( ) {
return super . getName ( ) ;
2017-12-07 23:51:06 +01:00
}
2016-12-05 04:21:04 +01:00
/ * *
2016-12-15 22:04:39 +01:00
* Emulate BungeeCord ' s getServers ( )
2016-12-05 04:21:04 +01:00
*
* @return Server Map
* /
@Override
public Map < String , ServerInfo > getServers ( ) {
2020-06-12 07:45:49 +02:00
return new LegacyServerMap ( getServersCopy ( ) ) ;
}
/ * *
* Emulate Waterfall ' s getServersCopy ( )
*
* @return Server Map Copy
* /
public Map < String , ServerInfo > getServersCopy ( ) {
2017-04-16 19:02:14 +02:00
HashMap < String , ServerInfo > servers = new HashMap < String , ServerInfo > ( ) ;
2017-12-06 23:34:47 +01:00
if ( ! api . ready ) {
2017-07-21 22:45:41 +02:00
servers . putAll ( super . getServers ( ) ) ;
2017-08-17 01:29:02 +02:00
servers . putAll ( legServers ) ;
2017-01-08 03:30:03 +01:00
} else {
for ( ServerInfo server : exServers . values ( ) ) servers . put ( server . getName ( ) , server ) ;
for ( Host host : this . hosts . values ( ) ) {
for ( ServerInfo server : host . getSubServers ( ) . values ( ) ) servers . put ( server . getName ( ) , server ) ;
}
2016-12-05 04:21:04 +01:00
}
2017-04-16 19:02:14 +02:00
return servers ;
2016-12-05 04:21:04 +01:00
}
2020-01-25 19:30:16 +01:00
/ * *
* Force BungeeCord ' s implementation of getServerInfo ( )
*
* @return ServerInfo
* /
@Override
public ServerInfo getServerInfo ( String name ) {
2020-06-12 07:45:49 +02:00
return getServersCopy ( ) . get ( name ) ;
2020-01-25 19:30:16 +01:00
}
2019-02-27 20:05:05 +01:00
@EventHandler ( priority = Byte . MAX_VALUE )
public void ping ( ProxyPingEvent e ) {
int offline = 0 ;
for ( String name : e . getConnection ( ) . getListener ( ) . getServerPriority ( ) ) {
2019-04-29 17:05:06 +02:00
ServerInfo server = api . getServer ( name . toLowerCase ( ) ) ;
if ( server = = null ) server = getServerInfo ( name ) ;
2020-02-16 21:01:17 +01:00
if ( server = = null | | ( server instanceof SubServer & & ! ( ( SubServer ) server ) . isRunning ( ) ) ) offline + + ;
2019-02-27 20:05:05 +01:00
}
if ( offline > = e . getConnection ( ) . getListener ( ) . getServerPriority ( ) . size ( ) ) {
e . setResponse ( new ServerPing ( e . getResponse ( ) . getVersion ( ) , e . getResponse ( ) . getPlayers ( ) , new TextComponent ( api . getLang ( " SubServers " , " Bungee.Ping.Offline " ) ) , null ) ) ;
}
}
2018-11-21 22:52:03 +01:00
@SuppressWarnings ( " deprecation " )
2017-08-18 11:58:06 +02:00
@EventHandler ( priority = Byte . MAX_VALUE )
2019-02-27 20:05:05 +01:00
public void validate ( ServerConnectEvent e ) {
2017-08-18 11:58:06 +02:00
Map < String , ServerInfo > servers = new TreeMap < String , ServerInfo > ( api . getServers ( ) ) ;
if ( servers . keySet ( ) . contains ( e . getTarget ( ) . getName ( ) . toLowerCase ( ) ) & & e . getTarget ( ) ! = servers . get ( e . getTarget ( ) . getName ( ) . toLowerCase ( ) ) ) {
e . setTarget ( servers . get ( e . getTarget ( ) . getName ( ) . toLowerCase ( ) ) ) ;
} else {
servers = getServers ( ) ;
if ( servers . keySet ( ) . contains ( e . getTarget ( ) . getName ( ) ) & & e . getTarget ( ) ! = servers . get ( e . getTarget ( ) . getName ( ) ) ) {
e . setTarget ( servers . get ( e . getTarget ( ) . getName ( ) ) ) ;
}
}
2018-11-21 22:52:03 +01:00
if ( ! e . getTarget ( ) . canAccess ( e . getPlayer ( ) ) ) {
2019-04-29 17:05:06 +02:00
if ( e . getPlayer ( ) . getServer ( ) = = null | | fallbackLimbo . keySet ( ) . contains ( e . getPlayer ( ) . getUniqueId ( ) ) ) {
if ( ! fallbackLimbo . keySet ( ) . contains ( e . getPlayer ( ) . getUniqueId ( ) ) | | fallbackLimbo . get ( e . getPlayer ( ) . getUniqueId ( ) ) . contains ( e . getTarget ( ) ) ) {
ServerKickEvent kick = new ServerKickEvent ( e . getPlayer ( ) , e . getTarget ( ) , new BaseComponent [ ] {
new TextComponent ( getTranslation ( " no_server_permission " ) )
} , null , ServerKickEvent . State . CONNECTING ) ;
fallback ( kick ) ;
if ( ! kick . isCancelled ( ) ) e . getPlayer ( ) . disconnect ( kick . getKickReasonComponent ( ) ) ;
if ( e . getPlayer ( ) . getServer ( ) ! = null ) e . setCancelled ( true ) ;
}
} else {
e . getPlayer ( ) . sendMessage ( getTranslation ( " no_server_permission " ) ) ;
e . setCancelled ( true ) ;
}
} else if ( e . getPlayer ( ) . getServer ( ) ! = null & & ! fallbackLimbo . keySet ( ) . contains ( e . getPlayer ( ) . getUniqueId ( ) ) & & e . getTarget ( ) instanceof SubServer & & ! ( ( SubServer ) e . getTarget ( ) ) . isRunning ( ) ) {
2019-02-27 20:05:05 +01:00
e . getPlayer ( ) . sendMessage ( api . getLang ( " SubServers " , " Bungee.Server.Offline " ) ) ;
2019-04-29 17:05:06 +02:00
e . setCancelled ( true ) ;
}
if ( fallbackLimbo . keySet ( ) . contains ( e . getPlayer ( ) . getUniqueId ( ) ) ) {
if ( fallbackLimbo . get ( e . getPlayer ( ) . getUniqueId ( ) ) . contains ( e . getTarget ( ) ) ) {
fallbackLimbo . get ( e . getPlayer ( ) . getUniqueId ( ) ) . remove ( e . getTarget ( ) ) ;
} else if ( e . getPlayer ( ) . getServer ( ) ! = null ) {
e . setCancelled ( true ) ;
}
2018-11-21 22:52:03 +01:00
}
2017-08-18 11:58:06 +02:00
}
2018-10-04 01:18:16 +02:00
@SuppressWarnings ( " deprecation " )
2019-04-29 17:05:06 +02:00
@EventHandler ( priority = Byte . MAX_VALUE )
2018-10-04 01:18:16 +02:00
public void fallback ( ServerKickEvent e ) {
2019-04-29 17:05:06 +02:00
if ( e . getPlayer ( ) instanceof UserConnection & & config . get ( ) . getMap ( " Settings " ) . getBoolean ( " Smart-Fallback " , true ) ) {
Map < String , ServerInfo > fallbacks ;
if ( ! fallbackLimbo . keySet ( ) . contains ( e . getPlayer ( ) . getUniqueId ( ) ) ) {
2020-06-21 23:42:10 +02:00
fallbacks = SmartFallback . getFallbackServers ( e . getPlayer ( ) . getPendingConnection ( ) . getListener ( ) , e . getPlayer ( ) ) ;
2019-04-29 17:05:06 +02:00
} else {
fallbacks = new LinkedHashMap < String , ServerInfo > ( ) ;
for ( ServerInfo server : fallbackLimbo . get ( e . getPlayer ( ) . getUniqueId ( ) ) ) fallbacks . put ( server . getName ( ) , server ) ;
2018-10-04 01:18:16 +02:00
}
2018-10-14 09:26:23 +02:00
2019-04-29 17:05:06 +02:00
fallbacks . remove ( e . getKickedFrom ( ) . getName ( ) ) ;
if ( ! fallbacks . isEmpty ( ) ) {
e . setCancelled ( true ) ;
e . getPlayer ( ) . sendMessage ( api . getLang ( " SubServers " , " Bungee.Feature.Smart-Fallback " ) . replace ( " $str$ " , ( e . getKickedFrom ( ) instanceof Server ) ? ( ( Server ) e . getKickedFrom ( ) ) . getDisplayName ( ) : e . getKickedFrom ( ) . getName ( ) ) . replace ( " $msg$ " , e . getKickReason ( ) ) ) ;
if ( ! fallbackLimbo . keySet ( ) . contains ( e . getPlayer ( ) . getUniqueId ( ) ) ) fallbackLimbo . put ( e . getPlayer ( ) . getUniqueId ( ) , new LinkedList < > ( fallbacks . values ( ) ) ) ;
ServerInfo next = new LinkedList < Map . Entry < String , ServerInfo > > ( fallbacks . entrySet ( ) ) . getFirst ( ) . getValue ( ) ;
e . setCancelServer ( next ) ;
2019-05-23 19:03:14 +02:00
if ( Util . isException ( ( ) - > Util . reflect ( ServerKickEvent . class . getDeclaredMethod ( " setCancelServers " , ServerInfo [ ] . class ) , e , ( Object ) fallbacks . values ( ) . toArray ( new ServerInfo [ 0 ] ) ) ) ) {
2019-05-23 20:37:18 +02:00
( ( UserConnection ) e . getPlayer ( ) ) . setServerJoinQueue ( new LinkedList < > ( fallbacks . keySet ( ) ) ) ;
2019-05-23 19:03:14 +02:00
( ( UserConnection ) e . getPlayer ( ) ) . connect ( next , null , true ) ;
}
2019-04-29 17:05:06 +02:00
}
2018-10-04 01:18:16 +02:00
}
}
2019-04-29 17:05:06 +02:00
@SuppressWarnings ( " deprecation " )
@EventHandler ( priority = Byte . MAX_VALUE )
public void fallbackFound ( ServerConnectedEvent e ) {
if ( fallbackLimbo . keySet ( ) . contains ( e . getPlayer ( ) . getUniqueId ( ) ) ) new Timer ( " SubServers.Bungee::Fallback_Limbo_Timer( " + e . getPlayer ( ) . getUniqueId ( ) + ')' ) . schedule ( new TimerTask ( ) {
@Override
public void run ( ) {
if ( e . getPlayer ( ) . getServer ( ) ! = null & & ! ( ( UserConnection ) e . getPlayer ( ) ) . isDimensionChange ( ) & & e . getPlayer ( ) . getServer ( ) . getInfo ( ) . getAddress ( ) . equals ( e . getServer ( ) . getInfo ( ) . getAddress ( ) ) ) {
fallbackLimbo . remove ( e . getPlayer ( ) . getUniqueId ( ) ) ;
e . getPlayer ( ) . sendMessage ( api . getLang ( " SubServers " , " Bungee.Feature.Smart-Fallback.Result " ) . replace ( " $str$ " , ( e . getServer ( ) . getInfo ( ) instanceof Server ) ? ( ( Server ) e . getServer ( ) . getInfo ( ) ) . getDisplayName ( ) : e . getServer ( ) . getInfo ( ) . getName ( ) ) ) ;
}
}
} , 1000 ) ;
}
@EventHandler ( priority = Byte . MIN_VALUE )
public void resetLimbo ( PlayerDisconnectEvent e ) {
fallbackLimbo . remove ( e . getPlayer ( ) . getUniqueId ( ) ) ;
2019-05-11 23:23:31 +02:00
SubCommand . players . remove ( e . getPlayer ( ) . getUniqueId ( ) ) ;
2019-04-29 17:05:06 +02:00
}
2018-10-04 01:18:16 +02:00
2017-08-18 11:58:06 +02:00
@EventHandler ( priority = Byte . MIN_VALUE )
2019-02-27 20:05:05 +01:00
public void unsudo ( SubStoppedEvent e ) {
2017-08-15 11:58:48 +02:00
if ( sudo = = e . getServer ( ) ) {
sudo = null ;
2019-05-17 00:36:41 +02:00
Logger . get ( " SubServers " ) . info ( " Reverting to the BungeeCord Console " ) ;
2017-08-15 11:58:48 +02:00
}
}
2016-12-05 04:21:04 +01:00
}