2016-12-20 00:31:01 +01:00
package net.ME1312.SubServers.Client.Bukkit ;
2020-11-16 21:34:59 +01:00
import net.ME1312.Galaxi.Library.Config.YAMLConfig ;
import net.ME1312.Galaxi.Library.Config.YAMLSection ;
import net.ME1312.Galaxi.Library.Container.Pair ;
2019-04-18 16:02:09 +02:00
import net.ME1312.Galaxi.Library.Map.ObjectMap ;
2020-11-16 21:34:59 +01:00
import net.ME1312.Galaxi.Library.UniversalFile ;
import net.ME1312.Galaxi.Library.Util ;
import net.ME1312.Galaxi.Library.Version.Version ;
2019-08-31 19:26:37 +02:00
import net.ME1312.SubData.Client.DataClient ;
2019-04-18 16:02:09 +02:00
import net.ME1312.SubData.Client.Encryption.AES ;
2020-06-12 07:45:49 +02:00
import net.ME1312.SubData.Client.Encryption.DHE ;
2019-04-18 16:02:09 +02:00
import net.ME1312.SubData.Client.Encryption.RSA ;
2019-05-10 04:43:34 +02:00
import net.ME1312.SubData.Client.Library.DisconnectReason ;
2020-11-16 21:34:59 +01:00
import net.ME1312.SubData.Client.SubDataClient ;
2018-08-12 23:23:21 +02:00
import net.ME1312.SubServers.Client.Bukkit.Graphic.DefaultUIHandler ;
2017-01-21 17:49:37 +01:00
import net.ME1312.SubServers.Client.Bukkit.Graphic.UIHandler ;
2020-06-12 07:45:49 +02:00
import net.ME1312.SubServers.Client.Bukkit.Library.ConfigUpdater ;
2020-11-16 21:34:59 +01:00
import net.ME1312.SubServers.Client.Bukkit.Library.Metrics ;
2019-04-18 16:02:09 +02:00
import net.ME1312.SubServers.Client.Bukkit.Network.SubProtocol ;
2020-11-16 21:34:59 +01:00
2016-12-20 00:31:01 +01:00
import org.bukkit.Bukkit ;
2019-04-29 17:05:06 +02:00
import org.bukkit.command.CommandMap ;
2020-06-12 07:45:49 +02:00
import org.bukkit.entity.Player ;
2016-12-20 00:31:01 +01:00
import org.bukkit.plugin.java.JavaPlugin ;
import java.io.* ;
2017-12-14 01:04:58 +01:00
import java.lang.reflect.InvocationTargetException ;
2016-12-20 00:31:01 +01:00
import java.net.InetAddress ;
2017-11-22 22:58:33 +01:00
import java.net.URL ;
import java.nio.charset.Charset ;
2016-12-20 00:31:01 +01:00
import java.nio.file.Files ;
2017-05-25 21:55:47 +02:00
import java.nio.file.StandardCopyOption ;
2019-05-10 04:43:34 +02:00
import java.util.* ;
2017-11-22 22:58:33 +01:00
import java.util.concurrent.TimeUnit ;
2016-12-20 00:31:01 +01:00
2021-06-06 23:01:28 +02:00
import static net.ME1312.SubServers.Client.Bukkit.Library.AccessMode.* ;
2017-01-08 20:42:40 +01:00
/ * *
* SubServers Client Plugin Class
* /
2016-12-20 00:31:01 +01:00
public final class SubPlugin extends JavaPlugin {
2019-05-17 00:36:41 +02:00
HashMap < Integer , SubDataClient > subdata = new HashMap < Integer , SubDataClient > ( ) ;
2020-11-14 08:07:25 +01:00
Pair < Long , Map < String , Map < String , String > > > lang = null ;
2021-06-12 21:27:51 +02:00
private UniversalFile dir ;
2017-01-26 23:19:48 +01:00
public YAMLConfig config ;
2019-04-29 17:05:06 +02:00
public SubProtocol subprotocol ;
2016-12-20 00:31:01 +01:00
2017-01-21 17:49:37 +01:00
public UIHandler gui = null ;
2017-01-08 20:42:40 +01:00
public final Version version ;
2017-01-21 17:49:37 +01:00
public final SubAPI api = new SubAPI ( this ) ;
2021-07-09 07:46:10 +02:00
public String server_address ;
2016-12-20 00:31:01 +01:00
2019-08-31 19:26:37 +02:00
private long resetDate = 0 ;
2019-05-10 04:43:34 +02:00
private boolean reconnect = false ;
2017-01-08 20:42:40 +01:00
public SubPlugin ( ) {
super ( ) ;
2018-07-29 20:39:42 +02:00
version = Version . fromString ( getDescription ( ) . getVersion ( ) ) ;
2019-05-10 06:04:10 +02:00
subdata . put ( 0 , null ) ;
2017-01-08 20:42:40 +01:00
}
/ * *
* Enable Plugin
* /
2016-12-20 00:31:01 +01:00
@Override
2018-04-15 03:53:51 +02:00
@SuppressWarnings ( " unchecked " )
2016-12-20 00:31:01 +01:00
public void onEnable ( ) {
try {
2017-12-13 18:29:50 +01:00
Bukkit . getLogger ( ) . info ( " SubServers > Loading SubServers.Client.Bukkit v " + version . toString ( ) + " Libraries (for Minecraft " + api . getGameVersion ( ) + " ) " ) ;
2021-06-12 21:27:51 +02:00
dir = new UniversalFile ( getDataFolder ( ) . getParentFile ( ) , " SubServers-Client " ) ;
if ( getDataFolder ( ) . exists ( ) ) {
Files . move ( getDataFolder ( ) . toPath ( ) , dir . toPath ( ) , StandardCopyOption . REPLACE_EXISTING ) ;
} else dir . mkdirs ( ) ;
ConfigUpdater . updateConfig ( new UniversalFile ( dir , " config.yml " ) ) ;
config = new YAMLConfig ( new UniversalFile ( dir , " config.yml " ) ) ;
2019-04-18 16:02:09 +02:00
if ( new UniversalFile ( new File ( System . getProperty ( " user.dir " ) ) , " subdata.json " ) . exists ( ) ) {
FileReader reader = new FileReader ( new UniversalFile ( new File ( System . getProperty ( " user.dir " ) ) , " subdata.json " ) ) ;
config . get ( ) . getMap ( " Settings " ) . set ( " SubData " , new YAMLSection ( parseJSON ( Util . readAll ( reader ) ) ) ) ;
2017-05-29 07:00:02 +02:00
config . save ( ) ;
2018-01-29 07:04:36 +01:00
reader . close ( ) ;
2019-04-18 16:02:09 +02:00
new UniversalFile ( new File ( System . getProperty ( " user.dir " ) ) , " subdata.json " ) . delete ( ) ;
}
if ( new UniversalFile ( new File ( System . getProperty ( " user.dir " ) ) , " subdata.rsa.key " ) . exists ( ) ) {
2021-06-12 21:27:51 +02:00
if ( new UniversalFile ( dir , " subdata.rsa.key " ) . exists ( ) ) new UniversalFile ( dir , " subdata.rsa.key " ) . delete ( ) ;
Files . move ( new UniversalFile ( new File ( System . getProperty ( " user.dir " ) ) , " subdata.rsa.key " ) . toPath ( ) , new UniversalFile ( dir , " subdata.rsa.key " ) . toPath ( ) ) ;
2017-05-29 07:00:02 +02:00
}
2017-12-14 01:04:58 +01:00
2020-06-12 07:45:49 +02:00
getServer ( ) . getMessenger ( ) . registerOutgoingPluginChannel ( this , " BungeeCord " ) ;
2020-11-28 04:00:54 +01:00
reload ( false ) ;
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 ) ) ;
2020-11-28 04:00:54 +01:00
api . name = config . get ( ) . getMap ( " Settings " ) . getMap ( " SubData " ) . getString ( " Name " , System . getenv ( " name " ) ) ;
2021-07-09 07:46:10 +02:00
server_address = config . get ( ) . getMap ( " Settings " ) . getRawString ( " Connect-Address " , System . getenv ( " address " ) ) ;
2020-11-28 04:00:54 +01:00
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 " ) ) ) ;
2021-09-15 04:05:56 +02:00
Bukkit . getLogger ( ) . info ( " SubData > AES Encryption Available " ) ;
2020-11-28 04:00:54 +01:00
}
2021-06-12 21:27:51 +02:00
if ( new UniversalFile ( dir , " subdata.rsa.key " ) . exists ( ) ) {
2020-11-28 04:00:54 +01:00
try {
2021-06-12 21:27:51 +02:00
subprotocol . registerCipher ( " RSA " , new RSA ( new UniversalFile ( dir , " subdata.rsa.key " ) ) ) ;
2021-09-15 04:05:56 +02:00
Bukkit . getLogger ( ) . info ( " SubData > RSA Encryption Available " ) ;
2020-11-28 04:00:54 +01:00
} catch ( Exception e ) {
e . printStackTrace ( ) ;
}
}
reconnect = true ;
2021-09-15 04:05:56 +02:00
Bukkit . getLogger ( ) . info ( " SubData > " ) ;
Bukkit . getLogger ( ) . info ( " SubData > Connecting to / " + config . get ( ) . getMap ( " Settings " ) . getMap ( " SubData " ) . getRawString ( " Address " , " 127.0.0.1:4391 " ) ) ;
2020-11-28 04:00:54 +01:00
connect ( null ) ;
2016-12-20 00:31:01 +01:00
2021-06-06 23:01:28 +02:00
gui = new DefaultUIHandler ( this ) ;
if ( api . access . value > NO_COMMANDS . value & & ! config . get ( ) . getMap ( " Settings " ) . getBoolean ( " API-Only-Mode " , false ) ) {
2019-04-29 17:05:06 +02:00
CommandMap cmd = Util . reflect ( Bukkit . getServer ( ) . getClass ( ) . getDeclaredField ( " commandMap " ) , Bukkit . getServer ( ) ) ;
cmd . register ( " subservers " , new SubCommand ( this , " subservers " ) ) ;
cmd . register ( " subservers " , new SubCommand ( this , " subserver " ) ) ;
cmd . register ( " subservers " , new SubCommand ( this , " sub " ) ) ;
2019-04-18 16:02:09 +02:00
}
2017-11-22 22:58:33 +01:00
2021-06-06 23:01:28 +02:00
if ( api . access . value > NO_INTEGRATIONS . value & & Bukkit . getPluginManager ( ) . getPlugin ( " PlaceholderAPI " ) ! = null ) {
2020-07-05 04:39:59 +02:00
new net . ME1312 . SubServers . Client . Bukkit . Library . Compatibility . PlaceholderImpl ( this ) . register ( ) ;
}
2021-07-28 08:28:16 +02:00
new Metrics ( this , 2334 ) ;
2017-11-22 22:58:33 +01:00
Bukkit . getScheduler ( ) . runTaskTimerAsynchronously ( this , ( ) - > {
try {
2018-08-04 02:43:02 +02:00
YAMLSection tags = new YAMLSection ( parseJSON ( " { \" 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 " ) ) ) ) + '}' ) ) ;
2018-07-29 20:39:42 +02:00
List < Version > versions = new LinkedList < Version > ( ) ;
2017-11-22 22:58:33 +01: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 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-11-22 22:58:33 +01:00
}
}
2018-07-23 05:44:20 +02:00
if ( updcount > 0 ) Bukkit . getLogger ( ) . info ( " SubServers > SubServers.Client.Bukkit v " + updversion + " is available. You are " + updcount + " version " + ( ( updcount = = 1 ) ? " " : " s " ) + " behind. " ) ;
2017-11-22 22:58:33 +01:00
} catch ( Exception e ) { }
} , 0 , TimeUnit . DAYS . toSeconds ( 2 ) * 20 ) ;
2018-08-04 02:43:02 +02:00
} catch ( Exception e ) {
2016-12-20 00:31:01 +01:00
e . printStackTrace ( ) ;
}
}
2017-12-14 01:04:58 +01:00
public void reload ( boolean notifyPlugins ) throws IOException {
2019-08-31 19:26:37 +02:00
resetDate = Calendar . getInstance ( ) . getTime ( ) . getTime ( ) ;
2017-12-14 01:04:58 +01:00
2021-06-12 21:27:51 +02:00
ConfigUpdater . updateConfig ( new UniversalFile ( dir , " config.yml " ) ) ;
2017-12-14 01:04:58 +01:00
config . reload ( ) ;
if ( notifyPlugins ) {
List < Runnable > listeners = api . reloadListeners ;
if ( listeners . size ( ) > 0 ) {
for ( Object obj : listeners ) {
try {
( ( Runnable ) obj ) . run ( ) ;
} catch ( Throwable e ) {
new InvocationTargetException ( e , " Problem reloading plugin " ) . printStackTrace ( ) ;
}
}
}
}
}
2020-11-14 08:07:25 +01:00
private void connect ( Pair < DisconnectReason , DataClient > disconnect ) throws IOException {
2020-11-11 22:07:22 +01:00
int reconnect = config . get ( ) . getMap ( " Settings " ) . getMap ( " SubData " ) . getInt ( " Reconnect " , 60 ) ;
2020-11-14 08:07:25 +01:00
if ( disconnect = = null | | ( this . reconnect & & reconnect > 0 & & disconnect . key ( ) ! = DisconnectReason . PROTOCOL_MISMATCH & & disconnect . key ( ) ! = DisconnectReason . ENCRYPTION_MISMATCH ) ) {
2019-08-31 19:26:37 +02:00
long reset = resetDate ;
2020-06-12 07:45:49 +02:00
if ( disconnect ! = null ) Bukkit . getLogger ( ) . info ( " SubData > Attempting reconnect in " + reconnect + " seconds " ) ;
2019-08-31 19:26:37 +02:00
Bukkit . getScheduler ( ) . runTaskLaterAsynchronously ( this , new Runnable ( ) {
@Override
public void run ( ) {
try {
2019-10-19 22:38:44 +02:00
if ( reset = = resetDate & & ( subdata . getOrDefault ( 0 , null ) = = null | | subdata . get ( 0 ) . isClosed ( ) ) ) {
2021-04-13 23:32:41 +02:00
SubDataClient open = subprotocol . open ( InetAddress . getByName ( config . get ( ) . getMap ( " Settings " ) . getMap ( " SubData " ) . getRawString ( " Address " , " 127.0.0.1:4391 " ) . split ( " : " ) [ 0 ] ) ,
2019-10-19 00:24:58 +02:00
Integer . parseInt ( config . get ( ) . getMap ( " Settings " ) . getMap ( " SubData " ) . getRawString ( " Address " , " 127.0.0.1:4391 " ) . split ( " : " ) [ 1 ] ) ) ;
if ( subdata . getOrDefault ( 0 , null ) ! = null ) subdata . get ( 0 ) . reconnect ( open ) ;
subdata . put ( 0 , open ) ;
}
2019-08-31 19:26:37 +02:00
} catch ( IOException e ) {
Bukkit . getLogger ( ) . info ( " SubData > Connection was unsuccessful, retrying in " + reconnect + " seconds " ) ;
Bukkit . getScheduler ( ) . runTaskLater ( SubPlugin . this , this , reconnect * 20 ) ;
}
}
} , ( disconnect = = null ) ? 0 : reconnect * 20 ) ;
}
2019-05-10 04:43:34 +02:00
}
2017-01-08 20:42:40 +01:00
/ * *
* Disable Plugin
* /
2016-12-20 00:31:01 +01:00
@Override
public void onDisable ( ) {
2017-01-21 17:49:37 +01:00
if ( subdata ! = null ) try {
2019-04-29 17:05:06 +02:00
setEnabled ( false ) ;
2019-05-10 04:43:34 +02:00
reconnect = false ;
ArrayList < SubDataClient > temp = new ArrayList < SubDataClient > ( ) ;
temp . addAll ( subdata . values ( ) ) ;
2019-05-11 23:23:31 +02:00
for ( SubDataClient client : temp ) if ( client ! = null ) {
2019-05-10 04:43:34 +02:00
client . close ( ) ;
client . waitFor ( ) ;
}
subdata . clear ( ) ;
2019-05-11 23:23:31 +02:00
subdata . put ( 0 , null ) ;
2021-01-21 20:28:23 +01:00
} catch ( InterruptedException e ) {
2017-01-21 17:49:37 +01:00
e . printStackTrace ( ) ;
}
2016-12-20 00:31:01 +01:00
}
2018-08-04 02:43:02 +02:00
/ * *
* Use reflection to access Gson for parsing
*
* @param json JSON to parse
* @return JSON as a map
* @throws NoSuchMethodException
* @throws IllegalAccessException
* @throws InvocationTargetException
* @throws InstantiationException
* @throws ClassNotFoundException
* /
@SuppressWarnings ( " unchecked " )
public Map < String , ? > parseJSON ( String json ) throws NoSuchMethodException , IllegalAccessException , InvocationTargetException , InstantiationException , ClassNotFoundException {
Class < ? > gson = Class . forName ( ( ( Util . getDespiteException ( ( ) - > Class . forName ( " com.google.gson.Gson " ) ! = null , false ) ? " " : " org.bukkit.craftbukkit.libs. " ) ) + " com.google.gson.Gson " ) ;
//Class<?> gson = com.google.gson.Gson.class;
return ( Map < String , ? > ) gson . getMethod ( " fromJson " , String . class , Class . class ) . invoke ( gson . newInstance ( ) , json , Map . class ) ;
}
2020-06-12 07:45:49 +02:00
/ * *
* Send a message to the BungeeCord Plugin Messaging Channel
*
* @param player Player that will send
* @param message Message contents
* /
public void pmc ( Player player , String . . . message ) {
ByteArrayOutputStream stream = new ByteArrayOutputStream ( ) ;
DataOutputStream data = new DataOutputStream ( stream ) ;
try {
for ( String m : message ) data . writeUTF ( m ) ;
data . flush ( ) ;
} catch ( IOException e ) {
e . printStackTrace ( ) ;
}
player . sendPluginMessage ( this , " BungeeCord " , stream . toByteArray ( ) ) ;
}
2016-12-20 00:31:01 +01:00
}