2019-08-25 10:49:44 +03:00
package pro.gravit.launchserver.config ;
import io.netty.channel.epoll.Epoll ;
import io.netty.handler.logging.LogLevel ;
2021-05-10 10:34:27 +03:00
import org.apache.logging.log4j.LogManager ;
import org.apache.logging.log4j.Logger ;
2019-08-25 10:49:44 +03:00
import pro.gravit.launcher.Launcher ;
import pro.gravit.launcher.LauncherConfig ;
import pro.gravit.launchserver.LaunchServer ;
import pro.gravit.launchserver.auth.AuthProviderPair ;
2021-06-16 12:35:55 +03:00
import pro.gravit.launchserver.auth.core.RejectAuthCoreProvider ;
2019-08-25 10:49:44 +03:00
import pro.gravit.launchserver.auth.protect.ProtectHandler ;
import pro.gravit.launchserver.auth.protect.StdProtectHandler ;
import pro.gravit.launchserver.auth.texture.RequestTextureProvider ;
2020-01-14 19:32:29 +03:00
import pro.gravit.launchserver.binary.tasks.exe.Launch4JTask ;
2019-08-25 10:49:44 +03:00
import pro.gravit.launchserver.components.AuthLimiterComponent ;
import pro.gravit.launchserver.components.Component ;
2021-03-26 17:56:17 +03:00
import pro.gravit.launchserver.components.ProGuardComponent ;
2019-08-25 10:49:44 +03:00
import pro.gravit.launchserver.components.RegLimiterComponent ;
import pro.gravit.utils.Version ;
import pro.gravit.utils.helper.JVMHelper ;
2019-10-19 19:46:04 +03:00
import java.io.File ;
2022-03-11 11:55:54 +03:00
import java.util.* ;
2019-10-19 19:46:04 +03:00
2019-08-25 10:49:44 +03:00
public final class LaunchServerConfig {
2021-05-25 12:17:29 +03:00
private transient final Logger logger = LogManager . getLogger ( ) ;
2019-08-25 10:49:44 +03:00
public String projectName ;
public String [ ] mirrors ;
public String binaryName ;
2020-02-01 20:59:16 +03:00
public boolean copyBinaries = true ;
2021-06-01 01:48:33 +03:00
public boolean cacheUpdates = true ;
2019-08-25 10:49:44 +03:00
public LauncherConfig . LauncherEnvironment env ;
2020-04-05 10:27:04 +03:00
public Map < String , AuthProviderPair > auth ;
2019-08-25 10:49:44 +03:00
// Handlers & Providers
2020-04-05 10:27:04 +03:00
public ProtectHandler protectHandler ;
public Map < String , Component > components ;
public ExeConf launch4j ;
public NettyConfig netty ;
public LauncherConf launcher ;
public JarSignerConf sign ;
public String startScript ;
private transient LaunchServer server = null ;
private transient AuthProviderPair authDefault ;
2019-08-25 10:49:44 +03:00
2020-04-05 10:27:04 +03:00
public static LaunchServerConfig getDefault ( LaunchServer . LaunchServerEnv env ) {
LaunchServerConfig newConfig = new LaunchServerConfig ( ) ;
2023-01-11 14:16:38 +03:00
newConfig . mirrors = new String [ ] { " https://mirror.gravitlauncher.com/5.3.x/ " , " https://gravit-launcher-mirror.storage.googleapis.com/ " } ;
2020-04-05 10:27:04 +03:00
newConfig . launch4j = new LaunchServerConfig . ExeConf ( ) ;
2022-07-24 12:24:25 +03:00
newConfig . launch4j . enabled = false ;
2020-04-05 10:27:04 +03:00
newConfig . launch4j . copyright = " © GravitLauncher Team " ;
newConfig . launch4j . fileDesc = " GravitLauncher " . concat ( Version . getVersion ( ) . getVersionString ( ) ) ;
newConfig . launch4j . fileVer = Version . getVersion ( ) . getVersionString ( ) . concat ( " . " ) . concat ( String . valueOf ( Version . getVersion ( ) . patch ) ) ;
newConfig . launch4j . internalName = " Launcher " ;
newConfig . launch4j . trademarks = " This product is licensed under GPLv3 " ;
newConfig . launch4j . txtFileVersion = " %s, build %d " ;
newConfig . launch4j . txtProductVersion = " %s, build %d " ;
newConfig . launch4j . productName = " GravitLauncher " ;
newConfig . launch4j . productVer = newConfig . launch4j . fileVer ;
newConfig . launch4j . maxVersion = " 1.8.999 " ;
newConfig . env = LauncherConfig . LauncherEnvironment . STD ;
newConfig . startScript = JVMHelper . OS_TYPE . equals ( JVMHelper . OS . MUSTDIE ) ? " . " + File . separator + " start.bat " : " . " + File . separator + " start.sh " ;
newConfig . auth = new HashMap < > ( ) ;
2021-06-16 12:35:55 +03:00
AuthProviderPair a = new AuthProviderPair ( new RejectAuthCoreProvider ( ) ,
2020-04-05 10:27:04 +03:00
new RequestTextureProvider ( " http://example.com/skins/%username%.png " , " http://example.com/cloaks/%username%.png " )
) ;
a . displayName = " Default " ;
newConfig . auth . put ( " std " , a ) ;
newConfig . protectHandler = new StdProtectHandler ( ) ;
newConfig . binaryName = " Launcher " ;
2019-08-25 10:49:44 +03:00
2020-04-05 10:27:04 +03:00
newConfig . netty = new NettyConfig ( ) ;
newConfig . netty . fileServerEnabled = true ;
newConfig . netty . binds = new NettyBindAddress [ ] { new NettyBindAddress ( " 0.0.0.0 " , 9274 ) } ;
newConfig . netty . performance = new NettyPerformanceConfig ( ) ;
try {
newConfig . netty . performance . usingEpoll = Epoll . isAvailable ( ) ;
} catch ( Throwable e ) {
// Epoll class line 51+ catch (Exception) but Error will be thrown by System.load
newConfig . netty . performance . usingEpoll = false ;
} // such as on ARM
newConfig . netty . performance . bossThread = 2 ;
newConfig . netty . performance . workerThread = 8 ;
2021-05-10 09:52:12 +03:00
newConfig . netty . performance . schedulerThread = 2 ;
2019-08-25 10:49:44 +03:00
2020-04-05 10:27:04 +03:00
newConfig . launcher = new LauncherConf ( ) ;
newConfig . launcher . guardType = " no " ;
newConfig . launcher . compress = true ;
newConfig . launcher . deleteTempFiles = true ;
newConfig . launcher . stripLineNumbers = true ;
newConfig . sign = new JarSignerConf ( ) ;
newConfig . components = new HashMap < > ( ) ;
AuthLimiterComponent authLimiterComponent = new AuthLimiterComponent ( ) ;
authLimiterComponent . rateLimit = 3 ;
authLimiterComponent . rateLimitMillis = 8000 ;
authLimiterComponent . message = " Превышен лимит авторизаций " ;
newConfig . components . put ( " authLimiter " , authLimiterComponent ) ;
RegLimiterComponent regLimiterComponent = new RegLimiterComponent ( ) ;
regLimiterComponent . rateLimit = 3 ;
regLimiterComponent . rateLimitMillis = 1000 * 60 * 60 * 10 ; //Блок на 10 часов
regLimiterComponent . message = " Превышен лимит регистраций " ;
newConfig . components . put ( " regLimiter " , regLimiterComponent ) ;
2021-03-26 17:56:17 +03:00
ProGuardComponent proGuardComponent = new ProGuardComponent ( ) ;
newConfig . components . put ( " proguard " , proGuardComponent ) ;
2020-04-05 10:27:04 +03:00
return newConfig ;
}
public LaunchServerConfig setLaunchServer ( LaunchServer server ) {
this . server = server ;
return this ;
}
2019-08-25 10:49:44 +03:00
public AuthProviderPair getAuthProviderPair ( String name ) {
2020-02-11 08:08:35 +03:00
return auth . get ( name ) ;
2019-08-25 10:49:44 +03:00
}
public AuthProviderPair getAuthProviderPair ( ) {
if ( authDefault ! = null ) return authDefault ;
2020-02-11 08:08:35 +03:00
for ( AuthProviderPair pair : auth . values ( ) ) {
2019-08-25 10:49:44 +03:00
if ( pair . isDefault ) {
authDefault = pair ;
return pair ;
}
}
2019-10-19 19:43:25 +03:00
throw new IllegalStateException ( " Default AuthProviderPair not found " ) ;
2019-08-25 10:49:44 +03:00
}
public void setProjectName ( String projectName ) {
this . projectName = projectName ;
}
public void setBinaryName ( String binaryName ) {
this . binaryName = binaryName ;
}
public void setEnv ( LauncherConfig . LauncherEnvironment env ) {
this . env = env ;
}
public void verify ( ) {
2020-02-11 08:08:35 +03:00
if ( auth = = null | | auth . size ( ) < 1 ) {
throw new NullPointerException ( " AuthProviderPair`s count should be at least one " ) ;
2019-08-25 10:49:44 +03:00
}
2020-02-11 08:08:35 +03:00
2019-08-25 10:49:44 +03:00
boolean isOneDefault = false ;
2020-02-11 08:08:35 +03:00
for ( AuthProviderPair pair : auth . values ( ) ) {
2019-08-25 10:49:44 +03:00
if ( pair . isDefault ) {
isOneDefault = true ;
break ;
}
}
if ( protectHandler = = null ) {
throw new NullPointerException ( " ProtectHandler must not be null " ) ;
}
if ( ! isOneDefault ) {
throw new IllegalStateException ( " No auth pairs declared by default. " ) ;
}
if ( env = = null ) {
throw new NullPointerException ( " Env must not be null " ) ;
}
if ( netty = = null ) {
throw new NullPointerException ( " Netty must not be null " ) ;
}
2022-01-12 16:45:13 +03:00
// Mirror check
{
boolean updateMirror = Boolean . getBoolean ( " launchserver.config.disableUpdateMirror " ) ;
2022-11-18 10:47:03 +03:00
if ( ! updateMirror ) {
for ( int i = 0 ; i < mirrors . length ; + + i ) {
if ( " https://mirror.gravit.pro/5.2.x/ " . equals ( mirrors [ i ] ) ) {
2023-01-11 14:16:38 +03:00
logger . warn ( " Replace mirror 'https://mirror.gravit.pro/5.2.x/' to 'https://mirror.gravitlauncher.com/5.3.x/'. If you really need to use original url, use '-Dlaunchserver.config.disableUpdateMirror=true' " ) ;
mirrors [ i ] = " https://mirror.gravitlauncher.com/5.3.x/ " ;
} else if ( " https://mirror.gravit.pro/5.3.x/ " . equals ( mirrors [ i ] ) ) {
logger . warn ( " Replace mirror 'https://mirror.gravit.pro/5.3.x/' to 'https://mirror.gravitlauncher.com/5.3.x/'. If you really need to use original url, use '-Dlaunchserver.config.disableUpdateMirror=true' " ) ;
mirrors [ i ] = " https://mirror.gravitlauncher.com/5.3.x/ " ;
2022-01-12 16:45:13 +03:00
}
}
}
}
2019-08-25 10:49:44 +03:00
}
public void init ( LaunchServer . ReloadType type ) {
Launcher . applyLauncherEnv ( env ) ;
2020-04-05 10:27:04 +03:00
for ( Map . Entry < String , AuthProviderPair > provider : auth . entrySet ( ) ) {
2020-02-11 08:08:35 +03:00
provider . getValue ( ) . init ( server , provider . getKey ( ) ) ;
2020-03-30 06:56:23 +03:00
}
2019-08-25 10:49:44 +03:00
if ( protectHandler ! = null ) {
2020-05-18 15:26:38 +03:00
server . registerObject ( " protectHandler " , protectHandler ) ;
2020-08-27 16:38:59 +03:00
protectHandler . init ( server ) ;
2019-08-25 10:49:44 +03:00
protectHandler . checkLaunchServerLicense ( ) ;
}
2019-10-19 19:46:04 +03:00
if ( components ! = null ) {
components . forEach ( ( k , v ) - > server . registerObject ( " component. " . concat ( k ) , v ) ) ;
2019-08-25 10:49:44 +03:00
}
2019-10-19 19:46:04 +03:00
if ( ! type . equals ( LaunchServer . ReloadType . NO_AUTH ) ) {
2020-02-11 08:08:35 +03:00
for ( AuthProviderPair pair : auth . values ( ) ) {
2021-05-20 18:35:34 +03:00
server . registerObject ( " auth. " . concat ( pair . name ) . concat ( " .core " ) , pair . core ) ;
2019-08-25 10:49:44 +03:00
server . registerObject ( " auth. " . concat ( pair . name ) . concat ( " .texture " ) , pair . textureProvider ) ;
}
}
Arrays . stream ( mirrors ) . forEach ( server . mirrorManager : : addMirror ) ;
}
public void close ( LaunchServer . ReloadType type ) {
try {
2019-10-19 19:46:04 +03:00
if ( ! type . equals ( LaunchServer . ReloadType . NO_AUTH ) ) {
2020-02-11 08:08:35 +03:00
for ( AuthProviderPair pair : auth . values ( ) ) {
2021-05-20 18:35:34 +03:00
server . unregisterObject ( " auth. " . concat ( pair . name ) . concat ( " .core " ) , pair . core ) ;
2019-08-25 10:49:44 +03:00
server . unregisterObject ( " auth. " . concat ( pair . name ) . concat ( " .texture " ) , pair . textureProvider ) ;
2020-03-31 06:59:50 +03:00
pair . close ( ) ;
2019-08-25 10:49:44 +03:00
}
}
2019-10-19 19:46:04 +03:00
if ( type . equals ( LaunchServer . ReloadType . FULL ) ) {
2019-08-25 10:49:44 +03:00
components . forEach ( ( k , component ) - > {
server . unregisterObject ( " component. " . concat ( k ) , component ) ;
2019-10-19 19:46:04 +03:00
if ( component instanceof AutoCloseable ) {
2019-08-25 10:49:44 +03:00
try {
( ( AutoCloseable ) component ) . close ( ) ;
} catch ( Exception e ) {
2021-05-10 10:34:27 +03:00
logger . error ( e ) ;
2019-08-25 10:49:44 +03:00
}
}
} ) ;
}
} catch ( Exception e ) {
2021-05-10 10:34:27 +03:00
logger . error ( e ) ;
2019-08-25 10:49:44 +03:00
}
2020-05-18 15:26:38 +03:00
if ( protectHandler ! = null ) {
server . unregisterObject ( " protectHandler " , protectHandler ) ;
2020-05-29 19:46:12 +03:00
protectHandler . close ( ) ;
2020-05-18 15:26:38 +03:00
}
2019-08-25 10:49:44 +03:00
}
public static class ExeConf {
public boolean enabled ;
public boolean setMaxVersion ;
public String maxVersion ;
2020-01-14 19:32:29 +03:00
public String minVersion = " 1.8.0 " ;
public String supportURL = null ;
public String downloadUrl = Launch4JTask . DOWNLOAD_URL ;
2019-08-25 10:49:44 +03:00
public String productName ;
public String productVer ;
public String fileDesc ;
public String fileVer ;
public String internalName ;
public String copyright ;
public String trademarks ;
public String txtFileVersion ;
public String txtProductVersion ;
}
2019-10-20 16:40:11 +03:00
public static class JarSignerConf {
2019-10-27 17:47:55 +03:00
public boolean enabled = false ;
2019-10-20 16:40:11 +03:00
public String keyStore = " pathToKey " ;
public String keyStoreType = " JKS " ;
public String keyStorePass = " mypass " ;
public String keyAlias = " myname " ;
public String keyPass = " mypass " ;
2019-10-20 19:10:41 +03:00
public String metaInfKeyName = " SIGNUMO.RSA " ;
public String metaInfSfName = " SIGNUMO.SF " ;
2019-10-20 16:40:11 +03:00
public String signAlgo = " SHA256WITHRSA " ;
}
2019-08-25 10:49:44 +03:00
public static class NettyUpdatesBind {
public String url ;
public boolean zip ;
}
2019-10-19 19:46:04 +03:00
2019-08-25 10:49:44 +03:00
public static class LauncherConf {
public String guardType ;
public boolean compress ;
public boolean stripLineNumbers ;
public boolean deleteTempFiles ;
2021-01-28 20:13:21 +03:00
public boolean certificatePinning ;
2021-04-26 18:21:28 +03:00
public boolean encryptRuntime ;
2022-03-11 11:55:54 +03:00
public List < String > customJvmOptions = new ArrayList < > ( ) ;
2021-01-28 20:13:21 +03:00
public int memoryLimit = 256 ;
2019-08-25 10:49:44 +03:00
}
public static class NettyConfig {
public boolean fileServerEnabled ;
public boolean ipForwarding ;
2020-09-17 15:40:53 +03:00
public boolean disableWebApiInterface ;
2019-08-29 12:19:33 +03:00
public boolean showHiddenFiles ;
2022-10-01 12:40:19 +03:00
public boolean sendProfileUpdatesEvent = true ;
2019-08-25 10:49:44 +03:00
public String launcherURL ;
public String downloadURL ;
public String launcherEXEURL ;
public String address ;
2020-02-01 20:59:16 +03:00
public Map < String , LaunchServerConfig . NettyUpdatesBind > bindings = new HashMap < > ( ) ;
2019-08-25 10:49:44 +03:00
public NettyPerformanceConfig performance ;
2022-07-24 12:24:25 +03:00
public NettySecurityConfig security = new NettySecurityConfig ( ) ;
2019-08-25 10:49:44 +03:00
public NettyBindAddress [ ] binds ;
2020-02-01 20:59:16 +03:00
public LogLevel logLevel = LogLevel . DEBUG ;
2019-08-25 10:49:44 +03:00
}
public static class NettyPerformanceConfig {
public boolean usingEpoll ;
public int bossThread ;
public int workerThread ;
2021-05-10 09:52:12 +03:00
public int schedulerThread ;
2020-11-21 16:33:10 +03:00
public int maxWebSocketRequestBytes = 1024 * 1024 ;
2019-08-25 10:49:44 +03:00
}
public static class NettyBindAddress {
2020-02-01 20:59:16 +03:00
public String address ;
public int port ;
2019-08-25 10:49:44 +03:00
public NettyBindAddress ( String address , int port ) {
this . address = address ;
this . port = port ;
}
}
2022-07-24 12:24:25 +03:00
public static class NettySecurityConfig {
public long hardwareTokenExpire = 60 * 60 * 8 ;
public long publicKeyTokenExpire = 60 * 60 * 8 ;
public long launcherTokenExpire = 60 * 60 * 8 ;
}
2019-08-25 10:49:44 +03:00
}