2017-08-22 15:02:23 +02:00
package net.ME1312.SubServers.Sync ;
2018-10-08 01:25:08 +02:00
import com.dosse.upnp.UPnP ;
2018-07-27 21:36:51 +02:00
import com.google.gson.Gson ;
2019-05-14 04:02:38 +02:00
import net.ME1312.SubData.Client.Encryption.AES ;
import net.ME1312.SubData.Client.Encryption.RSA ;
2017-08-22 15:02:23 +02:00
import net.ME1312.SubServers.Sync.Event.* ;
2019-05-14 04:02:38 +02:00
import net.ME1312.Galaxi.Library.Config.YAMLConfig ;
import net.ME1312.Galaxi.Library.Map.ObjectMap ;
2019-06-17 05:13:48 +02:00
import net.ME1312.SubServers.Sync.Library.Compatibility.GalaxiCommand ;
2019-05-17 00:36:41 +02:00
import net.ME1312.SubServers.Sync.Library.Compatibility.Logger ;
2019-04-29 17:05:06 +02:00
import net.ME1312.SubServers.Sync.Library.Fallback.SmartReconnectHandler ;
2017-08-22 15:02:23 +02:00
import net.ME1312.SubServers.Sync.Library.Metrics ;
2019-05-14 04:02:38 +02:00
import net.ME1312.Galaxi.Library.NamedContainer ;
import net.ME1312.Galaxi.Library.UniversalFile ;
import net.ME1312.Galaxi.Library.Util ;
import net.ME1312.Galaxi.Library.Version.Version ;
import net.ME1312.SubData.Client.SubDataClient ;
import net.ME1312.SubServers.Sync.Library.Updates.ConfigUpdater ;
import net.ME1312.SubServers.Sync.Network.SubProtocol ;
2018-10-14 09:26:23 +02:00
import net.ME1312.SubServers.Sync.Server.ServerContainer ;
import net.ME1312.SubServers.Sync.Server.SubServerContainer ;
2017-08-22 15:02:23 +02:00
import net.md_5.bungee.BungeeCord ;
2019-04-29 17:05:06 +02:00
import net.md_5.bungee.UserConnection ;
2019-05-14 04:02:38 +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 ;
2017-08-22 15:02:23 +02:00
import net.md_5.bungee.api.config.ServerInfo ;
2019-04-29 17:05:06 +02:00
import net.md_5.bungee.api.event.* ;
2017-08-22 15:02:23 +02:00
import net.md_5.bungee.api.plugin.Listener ;
import net.md_5.bungee.event.EventHandler ;
import java.io.* ;
import java.lang.reflect.InvocationTargetException ;
import java.net.InetAddress ;
import java.net.URL ;
import java.nio.charset.Charset ;
import java.util.* ;
import java.util.concurrent.TimeUnit ;
/ * *
* Main Plugin Class
* /
public final class SubPlugin extends BungeeCord implements Listener {
2019-05-17 00:36:41 +02:00
HashMap < Integer , SubDataClient > subdata = new HashMap < Integer , SubDataClient > ( ) ;
NamedContainer < Long , Map < String , Map < String , String > > > lang = null ;
2018-10-14 09:26:23 +02:00
public final Map < String , ServerContainer > servers = new TreeMap < String , ServerContainer > ( ) ;
2019-04-29 17:05:06 +02:00
private final HashMap < UUID , List < ServerInfo > > fallbackLimbo = new HashMap < UUID , List < ServerInfo > > ( ) ;
2017-08-22 15:02:23 +02:00
public final PrintStream out ;
public final UniversalFile dir = new UniversalFile ( new File ( System . getProperty ( " user.dir " ) ) ) ;
public YAMLConfig config ;
2017-12-08 08:35:50 +01:00
public boolean redis = false ;
2017-12-10 01:30:06 +01:00
public final SubAPI api = new SubAPI ( this ) ;
2019-05-14 04:02:38 +02:00
public SubProtocol subprotocol ;
2019-06-17 05:13:48 +02:00
public static final Version version = Version . fromString ( " 2.14.2a " ) ;
2017-12-10 01:30:06 +01:00
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 lastReload = - 1 ;
2019-05-14 04:02:38 +02:00
private boolean reconnect = false ;
2017-08-22 15:02:23 +02:00
private boolean posted = false ;
2019-05-17 00:36:41 +02:00
protected SubPlugin ( 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.Sync v " + version . toString ( ) + " Libraries (for Minecraft " + api . getGameVersion ( ) [ api . getGameVersion ( ) . length - 1 ] + " ) " ) ;
2017-08-22 15:02:23 +02:00
this . out = out ;
if ( ! ( new UniversalFile ( dir , " config.yml " ) . exists ( ) ) ) {
Util . copyFromJar ( SubPlugin . class . getClassLoader ( ) , " net/ME1312/SubServers/Sync/Library/Files/bungee.yml " , new UniversalFile ( dir , " config.yml " ) . getPath ( ) ) ;
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 " ) ;
2017-08-22 15:02:23 +02:00
}
UniversalFile dir = new UniversalFile ( this . dir , " SubServers " ) ;
dir . mkdir ( ) ;
2019-05-14 04:02:38 +02:00
ConfigUpdater . updateConfig ( new UniversalFile ( dir , " sync.yml " ) ) ;
2017-08-22 15:02:23 +02:00
config = new YAMLConfig ( new UniversalFile ( dir , " sync.yml " ) ) ;
2019-05-14 04:02:38 +02:00
subprotocol = SubProtocol . get ( ) ;
2017-08-22 15:02:23 +02:00
getPluginManager ( ) . registerListener ( null , this ) ;
2019-05-17 00:36:41 +02:00
Logger . get ( " SubServers " ) . info ( " Loading BungeeCord Libraries... " ) ;
2017-08-22 15:02:23 +02:00
}
/ * *
* Load Hosts , Servers , SubServers , and SubData Direct
* /
@Override
public void startListeners ( ) {
try {
2018-01-22 16:01:33 +01:00
redis = getPluginManager ( ) . getPlugin ( " RedisBungee " ) ! = null ;
2019-05-14 04:02:38 +02:00
ConfigUpdater . updateConfig ( new UniversalFile ( dir , " SubServers:sync.yml " ) ) ;
2017-08-22 15:02:23 +02:00
config . reload ( ) ;
2018-01-05 21:37:23 +01:00
2019-05-14 04:02:38 +02:00
subprotocol . unregisterCipher ( " AES " ) ;
subprotocol . unregisterCipher ( " AES-128 " ) ;
subprotocol . unregisterCipher ( " AES-192 " ) ;
subprotocol . unregisterCipher ( " AES-256 " ) ;
subprotocol . unregisterCipher ( " RSA " ) ;
api . name = config . get ( ) . getMap ( " Settings " ) . getMap ( " SubData " ) . getString ( " Name " , null ) ;
if ( config . get ( ) . getMap ( " Settings " ) . getMap ( " SubData " ) . getRawString ( " Password " , " " ) . length ( ) > 0 ) {
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 " ) ) ) ;
2019-05-17 00:36:41 +02:00
Logger . get ( " SubData " ) . info ( " AES Encryption Available " ) ;
2019-05-14 04:02:38 +02:00
}
if ( new UniversalFile ( dir , " SubServers:subdata.rsa.key " ) . exists ( ) ) {
try {
subprotocol . registerCipher ( " RSA " , new RSA ( new UniversalFile ( dir , " SubServers:subdata.rsa.key " ) ) ) ;
2019-05-17 00:36:41 +02:00
Logger . get ( " SubData " ) . info ( " RSA Encryption Available " ) ;
2019-05-14 04:02:38 +02:00
} catch ( Exception e ) {
e . printStackTrace ( ) ;
2018-01-05 21:37:23 +01:00
}
2017-08-22 15:02:23 +02:00
}
2019-05-14 04:02:38 +02:00
reconnect = true ;
2019-05-17 00:36:41 +02:00
Logger . get ( " SubData " ) . info ( " " ) ;
2019-05-14 04:02:38 +02:00
connect ( ) ;
2017-08-22 15:02:23 +02:00
super . startListeners ( ) ;
2018-10-08 01:25:08 +02:00
if ( UPnP . isUPnPAvailable ( ) ) {
2019-05-14 04:02:38 +02:00
if ( config . get ( ) . getMap ( " Settings " ) . getMap ( " UPnP " , new ObjectMap < String > ( ) ) . getBoolean ( " Forward-Proxy " , true ) ) for ( ListenerInfo listener : getConfig ( ) . getListeners ( ) ) {
2018-10-08 01:25:08 +02:00
UPnP . openPortTCP ( listener . getHost ( ) . getPort ( ) ) ;
}
} else {
getLogger ( ) . warning ( " UPnP is currently unavailable; Ports may not be automatically forwarded on this device " ) ;
}
2017-08-22 15:02:23 +02:00
if ( ! posted ) {
posted = true ;
post ( ) ;
}
} catch ( IOException e ) {
e . printStackTrace ( ) ;
}
}
2019-05-14 04:02:38 +02:00
private void connect ( ) throws IOException {
subdata . put ( 0 , 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 ] ) ) ) ;
}
2017-08-22 15:02:23 +02:00
private void post ( ) {
2019-05-14 04:02:38 +02:00
if ( config . get ( ) . getMap ( " Settings " ) . getBoolean ( " Override-Bungee-Commands " , true ) ) {
2018-01-02 23:29:25 +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 " ) ) ;
}
2018-01-02 23:29:25 +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-08-22 15:02:23 +02:00
2017-12-08 08:35:50 +01:00
new Metrics ( this ) ;
2019-01-06 07:58:13 +01:00
new Timer ( " SubServers.Sync::Routine_Update_Check " ) . schedule ( new TimerTask ( ) {
2018-07-27 21:36:51 +02:00
@SuppressWarnings ( " unchecked " )
2017-08-22 15:02:23 +02:00
@Override
public void run ( ) {
try {
2019-05-14 04:02:38 +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 20:39:42 +02:00
List < Version > versions = new LinkedList < Version > ( ) ;
2017-08-22 15:02:23 +02:00
Version updversion = version ;
2018-03-14 22:50:15 +01:00
int updcount = 0 ;
2019-05-14 04:02:38 +02:00
for ( ObjectMap < String > tag : tags . getMapList ( " tags " ) ) versions . add ( Version . fromString ( tag . getString ( " ref " ) . substring ( 10 ) ) ) ;
2018-07-29 20:39:42 +02:00
Collections . sort ( versions ) ;
for ( Version version : versions ) {
2018-07-29 05:02:47 +02:00
if ( version . compareTo ( updversion ) > 0 ) {
2018-07-27 21:36:51 +02:00
updversion = version ;
updcount + + ;
2017-08-22 15:02:23 +02:00
}
}
2019-05-17 00:36:41 +02:00
if ( updcount > 0 ) Logger . get ( " SubServers " ) . info ( " SubServers.Sync v " + updversion + " is available. You are " + updcount + " version " + ( ( updcount = = 1 ) ? " " : " s " ) + " behind. " ) ;
2017-08-22 15:02:23 +02:00
} catch ( Exception e ) { }
}
} , 0 , TimeUnit . DAYS . toMillis ( 2 ) ) ;
}
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-06-09 18:19:25 +02:00
public Object redis ( String method , NamedContainer < Class < ? > , ? > . . . args ) throws NoSuchMethodException , InvocationTargetException , IllegalAccessException {
2017-12-08 08:35:50 +01:00
if ( redis ) {
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 ( ) ;
if ( ! classargs [ i ] . isInstance ( objargs [ i ] ) ) throw new ClassCastException ( classargs [ i ] . getCanonicalName ( ) + " != " + objargs [ i ] . getClass ( ) . getCanonicalName ( ) ) ;
}
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
}
2017-08-22 15:02:23 +02:00
/ * *
* Emulate BungeeCord ' s getServers ( )
*
* @return Server Map
* /
@Override
public Map < String , ServerInfo > getServers ( ) {
if ( servers . size ( ) > 0 ) {
2017-12-07 23:51:06 +01:00
HashMap < String , ServerInfo > servers = new HashMap < String , ServerInfo > ( ) ;
for ( ServerInfo server : this . servers . values ( ) ) servers . put ( server . getName ( ) , server ) ;
return servers ;
2017-08-22 15:02:23 +02:00
} else {
return super . getServers ( ) ;
}
}
/ * *
* Reset all changes made by startListeners
*
* @see SubPlugin # startListeners ( )
* /
@Override
public void stopListeners ( ) {
try {
2019-05-17 00:36:41 +02:00
Logger . get ( " SubServers " ) . info ( " Resetting Server Data " ) ;
2017-08-22 15:02:23 +02:00
servers . clear ( ) ;
2019-05-14 04:02:38 +02:00
reconnect = false ;
ArrayList < SubDataClient > tmp = new ArrayList < SubDataClient > ( ) ;
tmp . addAll ( subdata . values ( ) ) ;
for ( SubDataClient client : tmp ) if ( client ! = null ) {
client . close ( ) ;
Util . isException ( client : : waitFor ) ;
}
subdata . clear ( ) ;
subdata . put ( 0 , null ) ;
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-08-22 15:02:23 +02:00
} catch ( Exception e ) {
e . printStackTrace ( ) ;
}
super . stopListeners ( ) ;
}
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 ( ) ) {
ServerInfo server = getServerInfo ( name ) ;
if ( server = = null | | server instanceof SubServerContainer & & ! ( ( SubServerContainer ) server ) . isRunning ( ) ) offline + + ;
}
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-22 15:02:23 +02:00
@EventHandler ( priority = Byte . MAX_VALUE )
2019-02-27 20:05:05 +01:00
public void validate ( ServerConnectEvent e ) {
2018-07-01 05:46:58 +02:00
Map < String , ServerInfo > servers = new TreeMap < String , ServerInfo > ( this . servers ) ;
2017-08-22 15:02:23 +02:00
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 SubServerContainer & & ! ( ( SubServerContainer ) 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-22 15:02:23 +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-05-14 04:02:38 +02:00
if ( e . getPlayer ( ) instanceof UserConnection & & config . get ( ) . getMap ( " Settings " ) . getBoolean ( " Smart-Fallback " , true ) ) {
2019-04-29 17:05:06 +02:00
Map < String , ServerInfo > fallbacks ;
if ( ! fallbackLimbo . keySet ( ) . contains ( e . getPlayer ( ) . getUniqueId ( ) ) ) {
fallbacks = SmartReconnectHandler . getFallbackServers ( e . getPlayer ( ) . getPendingConnection ( ) . getListener ( ) ) ;
} 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 ServerContainer ) ? ( ( ServerContainer ) 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 ] ) ) ) ) {
( ( UserConnection ) e . getPlayer ( ) ) . setServerJoinQueue ( new LinkedList < > ( fallbacks . keySet ( ) ) ) ;
( ( 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.Sync::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 ServerContainer ) ? ( ( ServerContainer ) 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-14 04:02:38 +02:00
SubCommand . players . remove ( e . getPlayer ( ) . getUniqueId ( ) ) ;
}
@SuppressWarnings ( " unchecked " )
private Map < Integer , UUID > getSubDataAsMap ( net . ME1312 . SubServers . Sync . Network . API . Server server ) {
HashMap < Integer , UUID > map = new HashMap < Integer , UUID > ( ) ;
ObjectMap < Integer > subdata = new ObjectMap < Integer > ( ( Map < Integer , ? > ) server . getRaw ( ) . getObject ( " subdata " ) ) ;
for ( Integer channel : subdata . getKeys ( ) ) map . put ( channel , subdata . getUUID ( channel ) ) ;
return map ;
2019-04-29 17:05:06 +02:00
}
2018-10-04 01:18:16 +02:00
2017-08-22 15:02:23 +02:00
@EventHandler ( priority = Byte . MIN_VALUE )
public void add ( SubAddServerEvent e ) {
2018-08-09 20:54:56 +02:00
api . getServer ( e . getServer ( ) , server - > {
if ( server ! = null ) {
if ( server instanceof net . ME1312 . SubServers . Sync . Network . API . SubServer ) {
2018-10-14 09:26:23 +02:00
servers . put ( server . getName ( ) . toLowerCase ( ) , new SubServerContainer ( server . getSignature ( ) , server . getName ( ) , server . getDisplayName ( ) , server . getAddress ( ) ,
2019-05-14 04:02:38 +02:00
getSubDataAsMap ( server ) , server . getMotd ( ) , server . isHidden ( ) , server . isRestricted ( ) , server . getWhitelist ( ) , ( ( net . ME1312 . SubServers . Sync . Network . API . SubServer ) server ) . isRunning ( ) ) ) ;
2019-05-17 00:36:41 +02:00
Logger . get ( " SubServers " ) . info ( " Added SubServer: " + e . getServer ( ) ) ;
2018-08-09 20:54:56 +02:00
} else {
2018-10-14 09:26:23 +02:00
servers . put ( server . getName ( ) . toLowerCase ( ) , new ServerContainer ( server . getSignature ( ) , server . getName ( ) , server . getDisplayName ( ) , server . getAddress ( ) ,
2019-05-14 04:02:38 +02:00
getSubDataAsMap ( server ) , server . getMotd ( ) , server . isHidden ( ) , server . isRestricted ( ) , server . getWhitelist ( ) ) ) ;
2019-05-17 00:36:41 +02:00
Logger . get ( " SubServers " ) . info ( " Added Server: " + e . getServer ( ) ) ;
2018-08-09 20:54:56 +02:00
}
} else System . out . println ( " PacketDownloadServerInfo( " + e . getServer ( ) + " ) returned with an invalid response " ) ;
} ) ;
2017-08-22 15:02:23 +02:00
}
2018-08-09 20:54:56 +02:00
public Boolean merge ( net . ME1312 . SubServers . Sync . Network . API . Server server ) {
2018-10-14 09:26:23 +02:00
ServerContainer current = servers . get ( server . getName ( ) . toLowerCase ( ) ) ;
if ( current = = null | | server instanceof net . ME1312 . SubServers . Sync . Network . API . SubServer | | ! ( current instanceof SubServerContainer ) ) {
2018-08-09 20:54:56 +02:00
if ( current = = null | | ! current . getSignature ( ) . equals ( server . getSignature ( ) ) ) {
if ( server instanceof net . ME1312 . SubServers . Sync . Network . API . SubServer ) {
2018-10-14 09:26:23 +02:00
servers . put ( server . getName ( ) . toLowerCase ( ) , new SubServerContainer ( server . getSignature ( ) , server . getName ( ) , server . getDisplayName ( ) , server . getAddress ( ) ,
2019-05-14 04:02:38 +02:00
getSubDataAsMap ( server ) , server . getMotd ( ) , server . isHidden ( ) , server . isRestricted ( ) , server . getWhitelist ( ) , ( ( net . ME1312 . SubServers . Sync . Network . API . SubServer ) server ) . isRunning ( ) ) ) ;
2017-12-10 01:30:06 +01:00
} else {
2018-10-14 09:26:23 +02:00
servers . put ( server . getName ( ) . toLowerCase ( ) , new ServerContainer ( server . getSignature ( ) , server . getName ( ) , server . getDisplayName ( ) , server . getAddress ( ) ,
2019-05-14 04:02:38 +02:00
getSubDataAsMap ( server ) , server . getMotd ( ) , server . isHidden ( ) , server . isRestricted ( ) , server . getWhitelist ( ) ) ) ;
2017-12-10 01:30:06 +01:00
}
2019-05-17 00:36:41 +02:00
Logger . get ( " SubServers " ) . info ( " Added " + ( ( server instanceof net . ME1312 . SubServers . Sync . Network . API . SubServer ) ? " Sub " : " " ) + " Server: " + server . getName ( ) ) ;
2017-12-10 01:30:06 +01:00
return true ;
} else {
2018-08-09 20:54:56 +02:00
if ( server instanceof net . ME1312 . SubServers . Sync . Network . API . SubServer ) {
2018-10-14 09:26:23 +02:00
if ( ( ( net . ME1312 . SubServers . Sync . Network . API . SubServer ) server ) . isRunning ( ) ! = ( ( SubServerContainer ) current ) . isRunning ( ) )
( ( SubServerContainer ) current ) . setRunning ( ( ( net . ME1312 . SubServers . Sync . Network . API . SubServer ) server ) . isRunning ( ) ) ;
2017-12-10 01:30:06 +01:00
}
2018-08-09 20:54:56 +02:00
if ( ! server . getMotd ( ) . equals ( current . getMotd ( ) ) )
current . setMotd ( server . getMotd ( ) ) ;
if ( server . isHidden ( ) ! = current . isHidden ( ) )
current . setHidden ( server . isHidden ( ) ) ;
if ( server . isRestricted ( ) ! = current . isRestricted ( ) )
current . setRestricted ( server . isRestricted ( ) ) ;
if ( ! server . getDisplayName ( ) . equals ( current . getDisplayName ( ) ) )
current . setDisplayName ( server . getDisplayName ( ) ) ;
2017-12-10 01:30:06 +01:00
2019-05-17 00:36:41 +02:00
Logger . get ( " SubServers " ) . info ( " Re-added " + ( ( server instanceof net . ME1312 . SubServers . Sync . Network . API . SubServer ) ? " Sub " : " " ) + " Server: " + server . getName ( ) ) ;
2017-12-10 01:30:06 +01:00
return false ;
}
}
return null ;
}
2017-08-22 15:02:23 +02:00
@EventHandler ( priority = Byte . MIN_VALUE )
public void edit ( SubEditServerEvent e ) {
if ( servers . keySet ( ) . contains ( e . getServer ( ) . toLowerCase ( ) ) ) {
2018-10-14 09:26:23 +02:00
ServerContainer server = servers . get ( e . getServer ( ) . toLowerCase ( ) ) ;
2017-08-22 15:02:23 +02:00
switch ( e . getEdit ( ) . name ( ) . toLowerCase ( ) ) {
case " display " :
server . setDisplayName ( e . getEdit ( ) . get ( ) . asString ( ) ) ;
break ;
case " motd " :
2019-05-14 04:02:38 +02:00
server . setMotd ( ChatColor . translateAlternateColorCodes ( '&' , e . getEdit ( ) . get ( ) . asString ( ) ) ) ;
2017-08-22 15:02:23 +02:00
break ;
case " restricted " :
server . setRestricted ( e . getEdit ( ) . get ( ) . asBoolean ( ) ) ;
break ;
case " hidden " :
server . setHidden ( e . getEdit ( ) . get ( ) . asBoolean ( ) ) ;
break ;
}
}
}
2018-10-14 09:26:23 +02:00
@EventHandler ( priority = Byte . MIN_VALUE )
public void start ( SubStartEvent e ) {
if ( servers . keySet ( ) . contains ( e . getServer ( ) . toLowerCase ( ) ) & & servers . get ( e . getServer ( ) . toLowerCase ( ) ) instanceof SubServerContainer )
( ( SubServerContainer ) servers . get ( e . getServer ( ) . toLowerCase ( ) ) ) . setRunning ( true ) ;
}
2019-05-14 04:02:38 +02:00
public void connect ( ServerContainer server , int channel , UUID address ) {
if ( server ! = null ) {
server . setSubData ( address , channel ) ;
}
2018-10-14 09:26:23 +02:00
}
2019-05-14 04:02:38 +02:00
public void disconnect ( ServerContainer server , int channel ) {
if ( server ! = null ) {
server . setSubData ( null , channel ) ;
}
2018-10-14 09:26:23 +02:00
}
2017-08-22 15:02:23 +02:00
@EventHandler ( priority = Byte . MIN_VALUE )
public void stop ( SubStoppedEvent e ) {
2018-10-14 09:26:23 +02:00
if ( servers . keySet ( ) . contains ( e . getServer ( ) . toLowerCase ( ) ) & & servers . get ( e . getServer ( ) . toLowerCase ( ) ) instanceof SubServerContainer )
( ( SubServerContainer ) servers . get ( e . getServer ( ) . toLowerCase ( ) ) ) . setRunning ( false ) ;
2017-08-22 15:02:23 +02:00
}
@EventHandler ( priority = Byte . MIN_VALUE )
public void remove ( SubRemoveServerEvent e ) {
if ( servers . keySet ( ) . contains ( e . getServer ( ) . toLowerCase ( ) ) )
servers . remove ( e . getServer ( ) . toLowerCase ( ) ) ;
2019-05-17 00:36:41 +02:00
Logger . get ( " SubServers " ) . info ( " Removed Server: " + e . getServer ( ) ) ;
2017-08-22 15:02:23 +02:00
}
}