mirror of
https://github.com/GravitLauncher/Launcher
synced 2024-12-23 00:51:01 +03:00
Merge branch 'dev' into master
This commit is contained in:
commit
b34042b8e1
41 changed files with 523 additions and 207 deletions
3
.gitmodules
vendored
3
.gitmodules
vendored
|
@ -1,3 +1,6 @@
|
|||
[submodule "modules"]
|
||||
path = modules
|
||||
url = git@github.com:GravitLauncher/LauncherModules.git
|
||||
[submodule "Radon"]
|
||||
path = Radon
|
||||
url = git@github.com:GravitLauncher/Radon.git
|
||||
|
|
|
@ -3,10 +3,10 @@
|
|||
|
||||
repositories {
|
||||
maven {
|
||||
url "http://maven.geomajas.org/"
|
||||
url "https://oss.sonatype.org/content/repositories/snapshots"
|
||||
}
|
||||
maven {
|
||||
url "https://oss.sonatype.org/content/repositories/snapshots"
|
||||
url "http://maven.geomajas.org/"
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -14,6 +14,7 @@
|
|||
targetCompatibility = '1.8'
|
||||
|
||||
configurations {
|
||||
compileOnlyA
|
||||
bundleOnly
|
||||
bundle
|
||||
hikari
|
||||
|
@ -38,8 +39,7 @@
|
|||
|
||||
dependencies {
|
||||
pack project(':libLauncher')
|
||||
bundle 'org.ow2.asm:asm-commons:7.0'
|
||||
bundle 'org.ow2.asm:asm-util:7.0'
|
||||
bundle project(':Radon')
|
||||
bundle 'mysql:mysql-connector-java:8.0.13'
|
||||
bundle 'jline:jline:2.14.6'
|
||||
bundle 'net.sf.proguard:proguard-base:6.0.3'
|
||||
|
@ -48,7 +48,6 @@ pack project(':libLauncher')
|
|||
bundle 'commons-codec:commons-codec:1.11'
|
||||
bundle 'org.javassist:javassist:3.24.1-GA'
|
||||
bundle 'io.netty:netty-all:4.1.32.Final'
|
||||
bundle 'org.kohsuke:github-api:1.95'
|
||||
|
||||
bundle 'org.slf4j:slf4j-simple:1.7.25'
|
||||
bundle 'org.slf4j:slf4j-api:1.7.25'
|
||||
|
@ -71,6 +70,9 @@ pack project(':libLauncher')
|
|||
launch4jCJ('net.sf.launch4j:launch4j:3.12:workdir-linux') {
|
||||
exclude group: '*'
|
||||
}
|
||||
|
||||
compileOnlyA 'com.google.guava:guava:26.0-jre'
|
||||
compileOnlyA 'org.apache.logging.log4j:log4j-core:2.11.2'
|
||||
}
|
||||
|
||||
task hikari(type: Copy) {
|
||||
|
@ -105,7 +107,7 @@ task launch4jA(type: Copy) {
|
|||
} else {
|
||||
fcp.exclude()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
task dumpLibs(type: Copy) {
|
||||
|
@ -114,13 +116,25 @@ task dumpLibs(type: Copy) {
|
|||
from configurations.bundleOnly
|
||||
}
|
||||
|
||||
task dumpCompileOnlyLibs(type: Copy) {
|
||||
into "$buildDir/libs/launcher-libraries-compile"
|
||||
from configurations.compileOnlyA
|
||||
}
|
||||
|
||||
task bundle(type: Zip) {
|
||||
dependsOn parent.childProjects.Launcher.tasks.build, tasks.dumpLibs, tasks.jar
|
||||
dependsOn parent.childProjects.Launcher.tasks.build, tasks.dumpLibs, tasks.dumpCompileOnlyLibs, tasks.jar
|
||||
archiveName 'LaunchServer.zip'
|
||||
destinationDir file("$buildDir")
|
||||
from(tasks.dumpLibs.destinationDir) { into 'libraries' }
|
||||
from(tasks.dumpCompileOnlyLibs.destinationDir) { into 'launcher-libraries-compile' }
|
||||
from tasks.jar.archivePath
|
||||
from(parent.childProjects.Launcher.tasks.dumpLibs) { into 'launcher-libraries' }
|
||||
}
|
||||
|
||||
build.dependsOn tasks.dumpLibs, tasks.bundle
|
||||
task dumpClientLibs(type: Copy) {
|
||||
dependsOn parent.childProjects.Launcher.tasks.build
|
||||
into "$buildDir/libs/launcher-libraries"
|
||||
from parent.childProjects.Launcher.tasks.dumpLibs.destinationDir
|
||||
}
|
||||
|
||||
build.dependsOn tasks.dumpLibs, tasks.dumpCompileOnlyLibs, tasks.dumpClientLibs, tasks.bundle
|
||||
|
|
|
@ -10,6 +10,9 @@
|
|||
import ru.gravit.launcher.serialize.signed.SignedObjectHolder;
|
||||
import ru.gravit.launchserver.auth.AuthLimiter;
|
||||
import ru.gravit.launchserver.auth.AuthProviderPair;
|
||||
import ru.gravit.launchserver.auth.protect.NoProtectHandler;
|
||||
import ru.gravit.launchserver.auth.protect.ProtectHandler;
|
||||
import ru.gravit.launchserver.components.AuthLimiterComponent;
|
||||
import ru.gravit.launchserver.auth.handler.AuthHandler;
|
||||
import ru.gravit.launchserver.auth.handler.MemoryAuthHandler;
|
||||
import ru.gravit.launchserver.auth.hwid.AcceptHWIDHandler;
|
||||
|
@ -19,6 +22,7 @@
|
|||
import ru.gravit.launchserver.auth.provider.AuthProvider;
|
||||
import ru.gravit.launchserver.auth.provider.RejectAuthProvider;
|
||||
import ru.gravit.launchserver.binary.*;
|
||||
import ru.gravit.launchserver.components.Component;
|
||||
import ru.gravit.utils.command.CommandHandler;
|
||||
import ru.gravit.utils.command.JLineCommandHandler;
|
||||
import ru.gravit.utils.command.StdCommandHandler;
|
||||
|
@ -96,6 +100,9 @@ public AuthProviderPair getAuthProviderPair(String name)
|
|||
}
|
||||
return null;
|
||||
}
|
||||
public ProtectHandler protectHandler;
|
||||
|
||||
public PermissionsHandler permissionsHandler;
|
||||
|
||||
public AuthProviderPair getAuthProviderPair()
|
||||
{
|
||||
|
@ -115,6 +122,8 @@ public AuthProviderPair getAuthProviderPair()
|
|||
|
||||
public HWIDHandler hwidHandler;
|
||||
|
||||
public HashMap<String, Component> components;
|
||||
|
||||
// Misc options
|
||||
public int threadCount;
|
||||
|
||||
|
@ -126,14 +135,6 @@ public AuthProviderPair getAuthProviderPair()
|
|||
|
||||
public boolean compress;
|
||||
|
||||
public int authRateLimit;
|
||||
|
||||
public int authRateLimitMilis;
|
||||
|
||||
public String[] authLimitExclusions;
|
||||
|
||||
public String authRejectString;
|
||||
|
||||
public String whitelistRejectString;
|
||||
|
||||
public boolean genMappings;
|
||||
|
@ -142,14 +143,13 @@ public AuthProviderPair getAuthProviderPair()
|
|||
|
||||
public boolean isWarningMissArchJava;
|
||||
public boolean enabledProGuard;
|
||||
public boolean enabledRadon;
|
||||
public boolean stripLineNumbers;
|
||||
public boolean deleteTempFiles;
|
||||
public boolean enableRcon;
|
||||
|
||||
public String startScript;
|
||||
|
||||
public boolean updatesNotify = true; // Defaultly to true
|
||||
|
||||
public String getAddress() {
|
||||
return address;
|
||||
}
|
||||
|
@ -195,6 +195,9 @@ public void verify() {
|
|||
isOneDefault = true;
|
||||
break;
|
||||
}
|
||||
if(protectHandler == null)
|
||||
{
|
||||
throw new NullPointerException("ProtectHandler must not be null");
|
||||
}
|
||||
if(!isOneDefault)
|
||||
{
|
||||
|
@ -294,7 +297,8 @@ public static void main(String... args) throws Throwable {
|
|||
// Start LaunchServer
|
||||
long startTime = System.currentTimeMillis();
|
||||
try {
|
||||
LaunchServer launchserver = new LaunchServer(IOHelper.WORKING_DIR, args);
|
||||
@SuppressWarnings("resource")
|
||||
LaunchServer launchserver = new LaunchServer(IOHelper.WORKING_DIR, args);
|
||||
if(args.length == 0) launchserver.run();
|
||||
else { //Обработка команды
|
||||
launchserver.commandHandler.eval(args,false);
|
||||
|
@ -313,6 +317,8 @@ public static void main(String... args) throws Throwable {
|
|||
|
||||
public final Path launcherLibraries;
|
||||
|
||||
public final Path launcherLibrariesCompile;
|
||||
|
||||
public final List<String> args;
|
||||
|
||||
public final Path configFile;
|
||||
|
@ -341,8 +347,6 @@ public static void main(String... args) throws Throwable {
|
|||
public final LauncherBinary launcherEXEBinary;
|
||||
// HWID ban + anti-brutforce
|
||||
|
||||
public final AuthLimiter limiter;
|
||||
|
||||
public final SessionManager sessionManager;
|
||||
|
||||
public final SocketHookManager socketHookManager;
|
||||
|
@ -377,7 +381,6 @@ public static void main(String... args) throws Throwable {
|
|||
public volatile Map<String, SignedObjectHolder<HashedDir>> updatesDirMap;
|
||||
|
||||
public final Timer taskPool;
|
||||
public final Updater updater;
|
||||
|
||||
public static Gson gson;
|
||||
public static GsonBuilder gsonBuilder;
|
||||
|
@ -386,10 +389,7 @@ public LaunchServer(Path dir, String[] args) throws IOException, InvalidKeySpecE
|
|||
this.dir = dir;
|
||||
taskPool = new Timer("Timered task worker thread", true);
|
||||
launcherLibraries = dir.resolve("launcher-libraries");
|
||||
if (!Files.isDirectory(launcherLibraries)) {
|
||||
Files.deleteIfExists(launcherLibraries);
|
||||
Files.createDirectory(launcherLibraries);
|
||||
}
|
||||
launcherLibrariesCompile = dir.resolve("launcher-libraries-compile");
|
||||
this.args = Arrays.asList(args);
|
||||
configFile = dir.resolve("LaunchServer.conf");
|
||||
publicKeyFile = dir.resolve("public.key");
|
||||
|
@ -404,6 +404,8 @@ public LaunchServer(Path dir, String[] args) throws IOException, InvalidKeySpecE
|
|||
HWIDHandler.registerHandlers();
|
||||
PermissionsHandler.registerHandlers();
|
||||
Response.registerResponses();
|
||||
Component.registerComponents();
|
||||
ProtectHandler.registerHandlers();
|
||||
LaunchServer.server = this;
|
||||
|
||||
// Set command handler
|
||||
|
@ -462,10 +464,23 @@ public LaunchServer(Path dir, String[] args) throws IOException, InvalidKeySpecE
|
|||
for (AuthProviderPair provider : config.auth) {
|
||||
provider.init();
|
||||
}
|
||||
if(config.protectHandler != null)
|
||||
{
|
||||
config.protectHandler.checkLaunchServerLicense();
|
||||
}
|
||||
config.authHandler.init();
|
||||
if(config.components != null)
|
||||
{
|
||||
LogHelper.debug("PreInit components");
|
||||
config.components.forEach((k,v) -> {
|
||||
LogHelper.subDebug("PreInit component %s", k);
|
||||
v.preInit(this);
|
||||
});
|
||||
LogHelper.debug("PreInit components successful");
|
||||
}
|
||||
|
||||
// build hooks, anti-brutforce and other
|
||||
buildHookManager = new BuildHookManager();
|
||||
limiter = new AuthLimiter(this);
|
||||
proguardConf = new ProguardConf(this);
|
||||
sessionManager = new SessionManager();
|
||||
mirrorManager = new MirrorManager();
|
||||
|
@ -474,7 +489,6 @@ public LaunchServer(Path dir, String[] args) throws IOException, InvalidKeySpecE
|
|||
socketHookManager = new SocketHookManager();
|
||||
authHookManager = new AuthHookManager();
|
||||
GarbageManager.registerNeedGC(sessionManager);
|
||||
GarbageManager.registerNeedGC(limiter);
|
||||
reloadManager.registerReloadable("launchServer", this);
|
||||
if (config.permissionsHandler instanceof Reloadable)
|
||||
reloadManager.registerReloadable("permissionsHandler", (Reloadable) config.permissionsHandler);
|
||||
|
@ -506,6 +520,15 @@ public LaunchServer(Path dir, String[] args) throws IOException, InvalidKeySpecE
|
|||
|
||||
// init modules
|
||||
modulesManager.initModules();
|
||||
if(config.components != null)
|
||||
{
|
||||
LogHelper.debug("Init components");
|
||||
config.components.forEach((k,v) -> {
|
||||
LogHelper.subDebug("Init component %s", k);
|
||||
v.init(this);
|
||||
});
|
||||
LogHelper.debug("Init components successful");
|
||||
}
|
||||
|
||||
// Set launcher EXE binary
|
||||
launcherBinary = new JARLauncherBinary(this);
|
||||
|
@ -531,8 +554,16 @@ public LaunchServer(Path dir, String[] args) throws IOException, InvalidKeySpecE
|
|||
|
||||
// post init modules
|
||||
modulesManager.postInitModules();
|
||||
if(config.components != null)
|
||||
{
|
||||
LogHelper.debug("PostInit components");
|
||||
config.components.forEach((k,v) -> {
|
||||
LogHelper.subDebug("PostInit component %s", k);
|
||||
v.postInit(this);
|
||||
});
|
||||
LogHelper.debug("PostInit components successful");
|
||||
}
|
||||
// start updater
|
||||
this.updater = new Updater(this);
|
||||
if(config.netty != null)
|
||||
nettyServerSocketHandler = new NettyServerSocketHandler(this);
|
||||
else
|
||||
|
@ -547,6 +578,8 @@ public static void initGson() {
|
|||
Launcher.gsonBuilder.registerTypeAdapter(AuthHandler.class, new AuthHandlerAdapter());
|
||||
Launcher.gsonBuilder.registerTypeAdapter(PermissionsHandler.class, new PermissionsHandlerAdapter());
|
||||
Launcher.gsonBuilder.registerTypeAdapter(HWIDHandler.class, new HWIDHandlerAdapter());
|
||||
Launcher.gsonBuilder.registerTypeAdapter(Component.class, new ComponentAdapter());
|
||||
Launcher.gsonBuilder.registerTypeAdapter(ProtectHandler.class, new ProtectHandlerAdapter());
|
||||
Launcher.gson = Launcher.gsonBuilder.create();
|
||||
|
||||
//Human readable
|
||||
|
@ -557,6 +590,8 @@ public static void initGson() {
|
|||
LaunchServer.gsonBuilder.registerTypeAdapter(AuthHandler.class, new AuthHandlerAdapter());
|
||||
LaunchServer.gsonBuilder.registerTypeAdapter(PermissionsHandler.class, new PermissionsHandlerAdapter());
|
||||
LaunchServer.gsonBuilder.registerTypeAdapter(HWIDHandler.class, new HWIDHandlerAdapter());
|
||||
LaunchServer.gsonBuilder.registerTypeAdapter(Component.class, new ComponentAdapter());
|
||||
LaunchServer.gsonBuilder.registerTypeAdapter(ProtectHandler.class, new ProtectHandlerAdapter());
|
||||
LaunchServer.gson = LaunchServer.gsonBuilder.create();
|
||||
}
|
||||
|
||||
|
@ -611,10 +646,10 @@ private void generateConfigIfNotExists() throws IOException {
|
|||
new MemoryAuthHandler(),
|
||||
new RequestTextureProvider("http://example.com/skins/%username%.png", "http://example.com/cloaks/%username%.png")
|
||||
, "std") };
|
||||
newConfig.protectHandler = new NoProtectHandler();
|
||||
newConfig.permissionsHandler = new JsonFilePermissionsHandler();
|
||||
newConfig.port = 7240;
|
||||
newConfig.bindAddress = "0.0.0.0";
|
||||
newConfig.authRejectString = "Превышен лимит авторизаций";
|
||||
newConfig.binaryName = "Launcher";
|
||||
newConfig.whitelistRejectString = "Вас нет в белом списке";
|
||||
|
||||
|
@ -626,11 +661,19 @@ private void generateConfigIfNotExists() throws IOException {
|
|||
newConfig.threadCoreCount = 0; // on your own
|
||||
newConfig.threadCount = JVMHelper.OPERATING_SYSTEM_MXBEAN.getAvailableProcessors() >= 4 ? JVMHelper.OPERATING_SYSTEM_MXBEAN.getAvailableProcessors() / 2 : JVMHelper.OPERATING_SYSTEM_MXBEAN.getAvailableProcessors();
|
||||
|
||||
newConfig.enabledRadon = true;
|
||||
newConfig.enabledProGuard = true;
|
||||
newConfig.stripLineNumbers = true;
|
||||
newConfig.deleteTempFiles = true;
|
||||
newConfig.isWarningMissArchJava = true;
|
||||
|
||||
newConfig.components = new HashMap<>();
|
||||
AuthLimiterComponent authLimiterComponent = new AuthLimiterComponent();
|
||||
authLimiterComponent.rateLimit = 3;
|
||||
authLimiterComponent.rateLimitMilis = 8000;
|
||||
authLimiterComponent.message = "Превышен лимит авторизаций";
|
||||
newConfig.components.put("authLimiter", authLimiterComponent);
|
||||
|
||||
// Set server address
|
||||
System.out.println("LaunchServer address: ");
|
||||
newConfig.setAddress(commandHandler.readLine());
|
||||
|
|
|
@ -1,92 +0,0 @@
|
|||
package ru.gravit.launchserver;
|
||||
|
||||
import java.time.Instant;
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.ZoneId;
|
||||
import java.time.format.DateTimeFormatter;
|
||||
import java.util.Date;
|
||||
import java.util.Locale;
|
||||
import java.util.TimerTask;
|
||||
import java.util.concurrent.atomic.AtomicReference;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import org.kohsuke.github.GHRelease;
|
||||
import org.kohsuke.github.GHRepository;
|
||||
import org.kohsuke.github.GitHub;
|
||||
|
||||
import ru.gravit.launcher.Launcher;
|
||||
import ru.gravit.utils.Version;
|
||||
import ru.gravit.utils.Version.Type;
|
||||
import ru.gravit.utils.helper.LogHelper;
|
||||
|
||||
public class Updater extends TimerTask {
|
||||
private static final DateTimeFormatter DATE_TIME_FORMATTER = DateTimeFormatter.ofPattern("yyyy.MM.dd HH:mm:ss", Locale.US);
|
||||
private static final long period = 1000*3600;
|
||||
private static final Version VERSION = Launcher.getVersion();
|
||||
private final GHRepository gravitLauncher;
|
||||
private Version parent = VERSION;
|
||||
|
||||
public Updater(LaunchServer srv) {
|
||||
|
||||
GHRepository gravitLauncherTmp = null;
|
||||
try {
|
||||
gravitLauncherTmp = GitHub.connectAnonymously().getOrganization("GravitLauncher").getRepository("Launcher");
|
||||
} catch (Throwable e) {
|
||||
LogHelper.error(e);
|
||||
}
|
||||
this.gravitLauncher = gravitLauncherTmp;
|
||||
run();
|
||||
if (srv.config.updatesNotify) srv.taskPool.schedule(this, new Date(System.currentTimeMillis()+period), period);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
try {
|
||||
GHRelease rel = gravitLauncher.getLatestRelease();
|
||||
Version relV = parseVer(rel.getTagName());
|
||||
if (relV == null) {
|
||||
LogHelper.debug("Updater: parsing version error.");
|
||||
return;
|
||||
}
|
||||
if (!parent.equals(relV)) parent = relV;
|
||||
if (VERSION.major >= relV.major && VERSION.minor >= relV.minor
|
||||
&& VERSION.patch >= relV.patch && VERSION.build >= relV.build) return;
|
||||
if (relV.release.equals(Type.STABLE) || relV.release.equals(Type.LTS)) {
|
||||
LogHelper.warning("New %s release: %s", relV.getReleaseStatus(), relV.getVersionString());
|
||||
LogHelper.warning("You can download it: " + rel.getHtmlUrl().toString());
|
||||
LogHelper.warning("It`s published at: " + DATE_TIME_FORMATTER.format(LocalDateTime.ofInstant(Instant.ofEpochMilli(rel.getPublished_at().getTime()), ZoneId.systemDefault())));
|
||||
} else {
|
||||
LogHelper.debug("New %s release: %s", relV.getReleaseStatus(), relV.getVersionString());
|
||||
LogHelper.debug("You can download it: " + rel.getHtmlUrl());
|
||||
LogHelper.debug("It`s published at: " + DATE_TIME_FORMATTER.format(LocalDateTime.ofInstant(Instant.ofEpochMilli(rel.getPublished_at().getTime()), ZoneId.systemDefault())));
|
||||
}
|
||||
} catch (Throwable e) {
|
||||
LogHelper.error(e);
|
||||
}
|
||||
}
|
||||
|
||||
private static final Pattern startingVerPattern = Pattern.compile("\\d+\\.\\d+\\.\\d+\\.?\\d*");
|
||||
private static final Pattern pointPatternSpltitter = Pattern.compile("\\.");
|
||||
|
||||
private static Version parseVer(String relS) {
|
||||
Matcher verMatcher = startingVerPattern.matcher(relS);
|
||||
if (!verMatcher.find()) return VERSION;
|
||||
String[] ver = pointPatternSpltitter.split(relS.substring(verMatcher.start(), verMatcher.end()));
|
||||
if (ver.length < 3) return VERSION;
|
||||
return new Version(Integer.parseInt(ver[0]), Integer.parseInt(ver[1]),
|
||||
Integer.parseInt(ver[2]), ver.length > 3 ? Integer.parseInt(ver[3]) : 0, findRelType(relS.substring(verMatcher.end())));
|
||||
}
|
||||
|
||||
private static Type findRelType(String substring) {
|
||||
if (substring.isEmpty()) return Type.UNKNOWN;
|
||||
String tS = substring;
|
||||
if (tS.startsWith("-")) tS = tS.substring(1);
|
||||
final String wrk = tS.toLowerCase(Locale.ENGLISH);
|
||||
final AtomicReference<Type> t = new AtomicReference<Type>(Type.UNKNOWN);
|
||||
Type.unModTypes.forEach((s, type) -> {
|
||||
if (wrk.startsWith(s)) t.set(type);
|
||||
});
|
||||
return t.get();
|
||||
}
|
||||
}
|
|
@ -4,6 +4,7 @@
|
|||
import ru.gravit.utils.helper.LogHelper;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.sql.Connection;
|
||||
import java.sql.PreparedStatement;
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
|
@ -64,8 +65,8 @@ protected Entry fetchEntry(UUID uuid) throws IOException {
|
|||
}
|
||||
|
||||
private Entry query(String sql, String value) throws IOException {
|
||||
try {
|
||||
PreparedStatement s = mySQLHolder.getConnection().prepareStatement(sql);
|
||||
try(Connection c = mySQLHolder.getConnection()) {
|
||||
PreparedStatement s = c.prepareStatement(sql);
|
||||
s.setString(1, value);
|
||||
s.setQueryTimeout(MySQLSourceConfig.TIMEOUT);
|
||||
try (ResultSet set = s.executeQuery()) {
|
||||
|
@ -78,8 +79,8 @@ private Entry query(String sql, String value) throws IOException {
|
|||
|
||||
@Override
|
||||
protected boolean updateAuth(UUID uuid, String username, String accessToken) throws IOException {
|
||||
try {
|
||||
PreparedStatement s = mySQLHolder.getConnection().prepareStatement(updateAuthSQL);
|
||||
try(Connection c = mySQLHolder.getConnection()) {
|
||||
PreparedStatement s = c.prepareStatement(updateAuthSQL);
|
||||
s.setString(1, username); // Username case
|
||||
s.setString(2, accessToken);
|
||||
s.setString(3, uuid.toString());
|
||||
|
@ -92,8 +93,8 @@ protected boolean updateAuth(UUID uuid, String username, String accessToken) thr
|
|||
|
||||
@Override
|
||||
protected boolean updateServerID(UUID uuid, String serverID) throws IOException {
|
||||
try {
|
||||
PreparedStatement s = mySQLHolder.getConnection().prepareStatement(updateServerIDSQL);
|
||||
try(Connection c = mySQLHolder.getConnection()) {
|
||||
PreparedStatement s = c.prepareStatement(updateServerIDSQL);
|
||||
s.setString(1, serverID);
|
||||
s.setString(2, uuid.toString());
|
||||
s.setQueryTimeout(MySQLSourceConfig.TIMEOUT);
|
||||
|
|
|
@ -63,8 +63,7 @@ public class MysqlHWIDHandler extends HWIDHandler {
|
|||
public void check0(HWID hwid, String username) throws HWIDException {
|
||||
if (hwid instanceof OshiHWID) {
|
||||
OshiHWID oshiHWID = (OshiHWID) hwid;
|
||||
try {
|
||||
Connection c = mySQLHolder.getConnection();
|
||||
try(Connection c = mySQLHolder.getConnection()) {
|
||||
|
||||
PreparedStatement s = c.prepareStatement(String.format("SELECT %s, %s FROM `%s` WHERE `%s` = ? LIMIT 1",
|
||||
userFieldHwid, userFieldLogin, tableUsers, userFieldLogin));
|
||||
|
@ -178,22 +177,21 @@ public void setIsBanned(HWID hwid, boolean isBanned) {
|
|||
LogHelper.debug("%s Request HWID: %s", isBanned ? "Ban" : "UnBan", hwid.toString());
|
||||
if (hwid instanceof OshiHWID) {
|
||||
OshiHWID oshiHWID = (OshiHWID) hwid;
|
||||
Connection c = null;
|
||||
try {
|
||||
c = mySQLHolder.getConnection();
|
||||
} catch (SQLException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
try (PreparedStatement a = c.prepareStatement(queryBan)) {
|
||||
String[] replaceParamsUpd = {"totalMemory", String.valueOf(oshiHWID.totalMemory), "serialNumber", oshiHWID.serialNumber, "HWDiskSerial", oshiHWID.HWDiskSerial, "processorID", oshiHWID.processorID, "isBanned", isBanned ? "1" : "0"};
|
||||
for (int i = 0; i < paramsBan.length; i++) {
|
||||
a.setString(i + 1, CommonHelper.replace(paramsBan[i], replaceParamsUpd));
|
||||
try(Connection c = mySQLHolder.getConnection()) {
|
||||
try (PreparedStatement a = c.prepareStatement(queryBan)) {
|
||||
String[] replaceParamsUpd = {"totalMemory", String.valueOf(oshiHWID.totalMemory), "serialNumber", oshiHWID.serialNumber, "HWDiskSerial", oshiHWID.HWDiskSerial, "processorID", oshiHWID.processorID, "isBanned", isBanned ? "1" : "0"};
|
||||
for (int i = 0; i < paramsBan.length; i++) {
|
||||
a.setString(i + 1, CommonHelper.replace(paramsBan[i], replaceParamsUpd));
|
||||
}
|
||||
a.setQueryTimeout(MySQLSourceConfig.TIMEOUT);
|
||||
a.executeUpdate();
|
||||
} catch (SQLException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
a.setQueryTimeout(MySQLSourceConfig.TIMEOUT);
|
||||
a.executeUpdate();
|
||||
} catch (SQLException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -214,9 +212,8 @@ public void unban(List<HWID> list) {
|
|||
@Override
|
||||
public List<HWID> getHwid(String username) {
|
||||
ArrayList<HWID> list = new ArrayList<>();
|
||||
try {
|
||||
try(Connection c = mySQLHolder.getConnection()) {
|
||||
LogHelper.debug("Try find HWID from username %s", username);
|
||||
Connection c = mySQLHolder.getConnection();
|
||||
PreparedStatement s = c.prepareStatement(String.format("SELECT %s, %s FROM `%s` WHERE `%s` = ? LIMIT 1", userFieldHwid, userFieldLogin, tableUsers, userFieldLogin));
|
||||
s.setString(1, username);
|
||||
|
||||
|
|
|
@ -0,0 +1,16 @@
|
|||
package ru.gravit.launchserver.auth.protect;
|
||||
|
||||
import ru.gravit.launchserver.response.auth.AuthResponse;
|
||||
import ru.gravit.utils.helper.SecurityHelper;
|
||||
|
||||
public class NoProtectHandler extends ProtectHandler {
|
||||
@Override
|
||||
public String generateSecureToken(AuthResponse.AuthContext context) {
|
||||
return SecurityHelper.randomStringToken();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void checkLaunchServerLicense() {
|
||||
// None
|
||||
}
|
||||
}
|
|
@ -0,0 +1,46 @@
|
|||
package ru.gravit.launchserver.auth.protect;
|
||||
|
||||
import ru.gravit.launchserver.auth.AuthException;
|
||||
import ru.gravit.launchserver.auth.handler.AuthHandler;
|
||||
import ru.gravit.launchserver.response.auth.AuthResponse;
|
||||
import ru.gravit.utils.helper.VerifyHelper;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
public abstract class ProtectHandler {
|
||||
private static final Map<String, Class<? extends ProtectHandler>> PROTECT_HANDLERS = new ConcurrentHashMap<>(4);
|
||||
private static boolean registredHandl = false;
|
||||
|
||||
|
||||
public static void registerHandler(String name, Class<? extends ProtectHandler> adapter) {
|
||||
VerifyHelper.verifyIDName(name);
|
||||
VerifyHelper.putIfAbsent(PROTECT_HANDLERS, name, Objects.requireNonNull(adapter, "adapter"),
|
||||
String.format("Protect handler has been already registered: '%s'", name));
|
||||
}
|
||||
|
||||
public static Class<? extends ProtectHandler> getHandlerClass(String name) {
|
||||
return PROTECT_HANDLERS.get(name);
|
||||
}
|
||||
|
||||
public static String getHandlerName(Class<ProtectHandler> clazz) {
|
||||
for (Map.Entry<String, Class<? extends ProtectHandler>> e : PROTECT_HANDLERS.entrySet()) {
|
||||
if (e.getValue().equals(clazz)) return e.getKey();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static void registerHandlers() {
|
||||
if (!registredHandl) {
|
||||
registerHandler("none", NoProtectHandler.class);
|
||||
registredHandl = true;
|
||||
}
|
||||
}
|
||||
|
||||
public abstract String generateSecureToken(AuthResponse.AuthContext context); //Генерация токена для передачи его в LauncherGuardInterface
|
||||
|
||||
public abstract void checkLaunchServerLicense(); //Выдает SecurityException при ошибке проверки лицензии
|
||||
//public abstract
|
||||
}
|
|
@ -8,6 +8,7 @@
|
|||
import ru.gravit.utils.helper.LogHelper;
|
||||
import ru.gravit.utils.helper.SecurityHelper;
|
||||
|
||||
import java.sql.Connection;
|
||||
import java.sql.PreparedStatement;
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
|
@ -28,16 +29,20 @@ public void init() {
|
|||
|
||||
@Override
|
||||
public AuthProviderResult auth(String login, String password, String ip) throws SQLException, AuthException {
|
||||
PreparedStatement s = mySQLHolder.getConnection().prepareStatement(query);
|
||||
String[] replaceParams = {"login", login, "password", password, "ip", ip};
|
||||
for (int i = 0; i < queryParams.length; i++)
|
||||
s.setString(i + 1, CommonHelper.replace(queryParams[i], replaceParams));
|
||||
try(Connection c = mySQLHolder.getConnection())
|
||||
{
|
||||
PreparedStatement s = c.prepareStatement(query);
|
||||
String[] replaceParams = {"login", login, "password", password, "ip", ip};
|
||||
for (int i = 0; i < queryParams.length; i++)
|
||||
s.setString(i + 1, CommonHelper.replace(queryParams[i], replaceParams));
|
||||
|
||||
// Execute SQL query
|
||||
s.setQueryTimeout(MySQLSourceConfig.TIMEOUT);
|
||||
try (ResultSet set = s.executeQuery()) {
|
||||
return set.next() ? new AuthProviderResult(set.getString(1), SecurityHelper.randomStringToken(), usePermission ? new ClientPermissions(set.getLong(2)) : LaunchServer.server.config.permissionsHandler.getPermissions(set.getString(1))) : authError(message);
|
||||
// Execute SQL query
|
||||
s.setQueryTimeout(MySQLSourceConfig.TIMEOUT);
|
||||
try (ResultSet set = s.executeQuery()) {
|
||||
return set.next() ? new AuthProviderResult(set.getString(1), SecurityHelper.randomStringToken(), usePermission ? new ClientPermissions(set.getLong(2)) : LaunchServer.server.config.permissionsHandler.getPermissions(set.getString(1))) : authError(message);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -21,6 +21,7 @@ public final class JARLauncherBinary extends LauncherBinary {
|
|||
public final Path buildDir;
|
||||
public List<LauncherBuildTask> tasks;
|
||||
public List<Path> coreLibs;
|
||||
public List<Path> addonLibs;
|
||||
|
||||
public JARLauncherBinary(LaunchServer server) throws IOException {
|
||||
super(server);
|
||||
|
@ -31,6 +32,7 @@ public JARLauncherBinary(LaunchServer server) throws IOException {
|
|||
buildDir = server.dir.resolve("build");
|
||||
tasks = new ArrayList<>();
|
||||
coreLibs = new ArrayList<>();
|
||||
addonLibs = new ArrayList<>();
|
||||
if (!Files.isDirectory(buildDir)) {
|
||||
Files.deleteIfExists(buildDir);
|
||||
Files.createDirectory(buildDir);
|
||||
|
@ -42,8 +44,9 @@ public void init() {
|
|||
tasks.add(new PrepareBuildTask(server));
|
||||
tasks.add(new MainBuildTask(server));
|
||||
tasks.add(new ProGuardBuildTask(server));
|
||||
tasks.add(new AttachJarsTask(server));
|
||||
tasks.add(new AdditionalFixesApplyTask(server));
|
||||
tasks.add(new RadonBuildTask(server));
|
||||
tasks.add(new AttachJarsTask(server));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
import ru.gravit.utils.helper.IOHelper;
|
||||
import ru.gravit.utils.helper.LogHelper;
|
||||
import ru.gravit.utils.helper.SecurityHelper;
|
||||
import ru.gravit.utils.helper.UnpackHelper;
|
||||
|
||||
import java.io.*;
|
||||
import java.nio.file.Files;
|
||||
|
@ -13,7 +14,6 @@
|
|||
import java.util.List;
|
||||
|
||||
public class ProguardConf {
|
||||
private static final String charsFirst = "aAbBcCdDeEfFgGhHiIjJkKlLmMnNoOpPqQrRsStTuUvVwWxXyYzZ";
|
||||
private static final String chars = "1aAbBcC2dDeEfF3gGhHiI4jJkKl5mMnNoO6pPqQrR7sStT8uUvV9wWxX0yYzZ";
|
||||
|
||||
private static String generateString(SecureRandom rand, String lowString, String upString, int il) {
|
||||
|
@ -50,6 +50,9 @@ public String[] buildConfig(Path inputJar, Path outputJar) {
|
|||
srv.launcherBinary.coreLibs.stream()
|
||||
.map(e -> "-libraryjars \'" + e.toAbsolutePath().toString() + "\'")
|
||||
.forEach(confStrs::add);
|
||||
srv.launcherBinary.addonLibs.stream()
|
||||
.map(e -> "-libraryjars \'" + e.toAbsolutePath().toString() + "\'")
|
||||
.forEach(confStrs::add);
|
||||
confStrs.add("-classobfuscationdictionary \'" + words.toFile().getName() + "\'");
|
||||
confStrs.add(readConf());
|
||||
return confStrs.toArray(new String[0]);
|
||||
|
@ -58,9 +61,7 @@ public String[] buildConfig(Path inputJar, Path outputJar) {
|
|||
private void genConfig(boolean force) throws IOException {
|
||||
if (IOHelper.exists(config) && !force) return;
|
||||
Files.deleteIfExists(config);
|
||||
try (OutputStream out = IOHelper.newOutput(config); InputStream in = IOHelper.newInput(IOHelper.getResourceURL("ru/gravit/launchserver/defaults/proguard.cfg"))) {
|
||||
IOHelper.transfer(in, out);
|
||||
}
|
||||
UnpackHelper.unpack(IOHelper.getResourceURL("ru/gravit/launchserver/defaults/proguard.cfg"), config);
|
||||
}
|
||||
|
||||
public void genWords(boolean force) throws IOException {
|
||||
|
|
|
@ -30,7 +30,9 @@ public String getName() {
|
|||
@Override
|
||||
public Path process(Path inputFile) throws IOException {
|
||||
server.launcherBinary.coreLibs.clear();
|
||||
server.launcherBinary.addonLibs.clear();
|
||||
IOHelper.walk(server.launcherLibraries, new ListFileVisitor(server.launcherBinary.coreLibs), true);
|
||||
IOHelper.walk(server.launcherLibrariesCompile, new ListFileVisitor(server.launcherBinary.addonLibs), true);
|
||||
UnpackHelper.unpack(IOHelper.getResourceURL("Launcher.jar"), result);
|
||||
tryUnpack();
|
||||
return result;
|
||||
|
|
|
@ -25,8 +25,8 @@ public String getName() {
|
|||
|
||||
@Override
|
||||
public Path process(Path inputFile) throws IOException {
|
||||
Path outputJar = server.launcherBinary.nextLowerPath(this);
|
||||
if (server.config.enabledProGuard) {
|
||||
Path outputJar = server.launcherBinary.nextLowerPath(this);
|
||||
Configuration proguard_cfg = new Configuration();
|
||||
ConfigurationParser parser = new ConfigurationParser(server.proguardConf.buildConfig(inputFile, outputJar),
|
||||
server.proguardConf.proguard.toFile(), System.getProperties());
|
||||
|
@ -37,12 +37,9 @@ public Path process(Path inputFile) throws IOException {
|
|||
} catch (ParseException e) {
|
||||
LogHelper.error(e);
|
||||
}
|
||||
return outputJar;
|
||||
} else {
|
||||
Path outputJar = server.launcherBinary.nextPath("non-obf");
|
||||
} else
|
||||
IOHelper.copy(inputFile, outputJar);
|
||||
return outputJar;
|
||||
}
|
||||
return outputJar;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -0,0 +1,55 @@
|
|||
package ru.gravit.launchserver.binary.tasks;
|
||||
|
||||
import ru.gravit.launchserver.LaunchServer;
|
||||
import ru.gravit.utils.helper.IOHelper;
|
||||
import ru.gravit.utils.helper.UnpackHelper;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Path;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import me.itzsomebody.radon.Radon;
|
||||
import me.itzsomebody.radon.SessionInfo;
|
||||
import me.itzsomebody.radon.config.ConfigurationParser;
|
||||
|
||||
public class RadonBuildTask implements LauncherBuildTask {
|
||||
private final LaunchServer srv;
|
||||
public final Path config;
|
||||
|
||||
public RadonBuildTask(LaunchServer srv) {
|
||||
this.srv = srv;
|
||||
config = this.srv.dir.resolve("radon.yml");
|
||||
System.setProperty("radon.useJVMCP", "true");
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return "Radon";
|
||||
}
|
||||
|
||||
@Override
|
||||
public Path process(Path inputFile) throws IOException {
|
||||
Path outputFile = srv.launcherBinary.nextLowerPath(this);
|
||||
if (srv.config.enabledRadon) {
|
||||
if (!IOHelper.isFile(config)) UnpackHelper.unpack(IOHelper.getResourceURL("ru/gravit/launchserver/defaults/radon.cfg"), config);
|
||||
ConfigurationParser p = new ConfigurationParser(IOHelper.newInput(config));
|
||||
SessionInfo info = p.createSessionFromConfig();
|
||||
info.setInput(inputFile.toFile());
|
||||
info.setOutput(outputFile.toFile());
|
||||
List<File> libs = srv.launcherBinary.coreLibs.stream().map(e -> e.toFile()).collect(Collectors.toList());
|
||||
libs.addAll(srv.launcherBinary.addonLibs.stream().map(e -> e.toFile()).collect(Collectors.toList()));
|
||||
info.setLibraries(libs);
|
||||
Radon r = new Radon(info);
|
||||
r.run();
|
||||
} else
|
||||
IOHelper.copy(inputFile, outputFile);
|
||||
return outputFile;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean allowDelete() {
|
||||
return true;
|
||||
}
|
||||
}
|
|
@ -1,14 +1,42 @@
|
|||
package ru.gravit.launchserver.auth;
|
||||
package ru.gravit.launchserver.components;
|
||||
|
||||
import ru.gravit.launcher.NeedGarbageCollection;
|
||||
import ru.gravit.launchserver.LaunchServer;
|
||||
import ru.gravit.launchserver.auth.AuthException;
|
||||
import ru.gravit.launchserver.auth.provider.AuthProvider;
|
||||
import ru.gravit.launchserver.components.Component;
|
||||
import ru.gravit.launchserver.response.auth.AuthResponse;
|
||||
import ru.gravit.launchserver.socket.Client;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
|
||||
public class AuthLimiter implements NeedGarbageCollection {
|
||||
public class AuthLimiterComponent extends Component implements NeedGarbageCollection {
|
||||
private LaunchServer server;
|
||||
@Override
|
||||
public void preInit(LaunchServer launchServer) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void init(LaunchServer launchServer) {
|
||||
server = launchServer;
|
||||
launchServer.authHookManager.registerPreHook(this::preAuthHook);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void postInit(LaunchServer launchServer) {
|
||||
|
||||
}
|
||||
public void preAuthHook(AuthResponse.AuthContext context, Client client) throws AuthException {
|
||||
if(isLimit(context.ip))
|
||||
{
|
||||
AuthProvider.authError(message);
|
||||
}
|
||||
}
|
||||
|
||||
static class AuthEntry {
|
||||
public int value;
|
||||
|
||||
|
@ -50,20 +78,12 @@ public String toString() {
|
|||
|
||||
|
||||
public static final long TIMEOUT = 10 * 60 * 1000; //10 минут
|
||||
public final int rateLimit;
|
||||
public final int rateLimitMilis;
|
||||
public int rateLimit;
|
||||
public int rateLimitMilis;
|
||||
public String message;
|
||||
|
||||
private final HashMap<String, AuthEntry> map;
|
||||
private final List<String> excludeIps;
|
||||
|
||||
public AuthLimiter(LaunchServer srv) {
|
||||
map = new HashMap<>();
|
||||
excludeIps = new ArrayList<>();
|
||||
if (srv.config.authLimitExclusions != null)
|
||||
excludeIps.addAll(Arrays.asList(srv.config.authLimitExclusions));
|
||||
rateLimit = srv.config.authRateLimit;
|
||||
rateLimitMilis = srv.config.authRateLimitMilis;
|
||||
}
|
||||
public transient HashMap<String, AuthEntry> map = new HashMap<>();
|
||||
public List<String> excludeIps = new ArrayList<>();
|
||||
|
||||
@Override
|
||||
public void garbageCollection() {
|
|
@ -0,0 +1,40 @@
|
|||
package ru.gravit.launchserver.components;
|
||||
|
||||
import ru.gravit.launchserver.LaunchServer;
|
||||
import ru.gravit.utils.helper.VerifyHelper;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
public abstract class Component {
|
||||
private static final Map<String, Class<? extends Component>> COMPONENTS = new ConcurrentHashMap<>(4);
|
||||
private static boolean registredComp = false;
|
||||
|
||||
public static void registerComponent(String name, Class<? extends Component> adapter) {
|
||||
VerifyHelper.verifyIDName(name);
|
||||
VerifyHelper.putIfAbsent(COMPONENTS, name, Objects.requireNonNull(adapter, "adapter"),
|
||||
String.format("Auth handler has been already registered: '%s'", name));
|
||||
}
|
||||
|
||||
public static Class<? extends Component> getComponentClass(String name) {
|
||||
return COMPONENTS.get(name);
|
||||
}
|
||||
|
||||
public static String getComponentName(Class<Component> clazz) {
|
||||
for (Map.Entry<String, Class<? extends Component>> e : COMPONENTS.entrySet()) {
|
||||
if (e.getValue().equals(clazz)) return e.getKey();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static void registerComponents() {
|
||||
if (!registredComp) {
|
||||
registerComponent("authLimiter", AuthLimiterComponent.class);
|
||||
registredComp = true;
|
||||
}
|
||||
}
|
||||
public abstract void preInit(LaunchServer launchServer);
|
||||
public abstract void init(LaunchServer launchServer);
|
||||
public abstract void postInit(LaunchServer launchServer);
|
||||
}
|
|
@ -2,6 +2,7 @@
|
|||
|
||||
import com.google.gson.*;
|
||||
import ru.gravit.launchserver.auth.handler.AuthHandler;
|
||||
import ru.gravit.utils.helper.LogHelper;
|
||||
|
||||
import java.lang.reflect.Type;
|
||||
|
||||
|
@ -12,6 +13,11 @@ public class AuthHandlerAdapter implements JsonSerializer<AuthHandler>, JsonDese
|
|||
public AuthHandler deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {
|
||||
String typename = json.getAsJsonObject().getAsJsonPrimitive(PROP_NAME).getAsString();
|
||||
Class<? extends AuthHandler> cls = AuthHandler.getHandlerClass(typename);
|
||||
if(cls == null)
|
||||
{
|
||||
LogHelper.error("AuthHandler %s not found", typename);
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
return (AuthHandler) context.deserialize(json, cls);
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
|
||||
import com.google.gson.*;
|
||||
import ru.gravit.launchserver.auth.provider.AuthProvider;
|
||||
import ru.gravit.utils.helper.LogHelper;
|
||||
|
||||
import java.lang.reflect.Type;
|
||||
|
||||
|
@ -12,6 +13,11 @@ public class AuthProviderAdapter implements JsonSerializer<AuthProvider>, JsonDe
|
|||
public AuthProvider deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {
|
||||
String typename = json.getAsJsonObject().getAsJsonPrimitive(PROP_NAME).getAsString();
|
||||
Class<? extends AuthProvider> cls = AuthProvider.getProviderClass(typename);
|
||||
if(cls == null)
|
||||
{
|
||||
LogHelper.error("AuthProvider %s not found", typename);
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
return (AuthProvider) context.deserialize(json, cls);
|
||||
|
|
|
@ -0,0 +1,36 @@
|
|||
package ru.gravit.launchserver.config;
|
||||
|
||||
import com.google.gson.*;
|
||||
import ru.gravit.launchserver.components.Component;
|
||||
import ru.gravit.utils.helper.LogHelper;
|
||||
|
||||
import java.lang.reflect.Type;
|
||||
|
||||
public class ComponentAdapter implements JsonSerializer<Component>, JsonDeserializer<Component> {
|
||||
private static final String PROP_NAME = "component";
|
||||
|
||||
@Override
|
||||
public Component deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {
|
||||
String typename = json.getAsJsonObject().getAsJsonPrimitive(PROP_NAME).getAsString();
|
||||
Class<? extends Component> cls = Component.getComponentClass(typename);
|
||||
if(cls == null)
|
||||
{
|
||||
LogHelper.error("Component %s not found", typename);
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
return (Component) context.deserialize(json, cls);
|
||||
}
|
||||
|
||||
@Override
|
||||
public JsonElement serialize(Component src, Type typeOfSrc, JsonSerializationContext context) {
|
||||
JsonObject jo = context.serialize(src).getAsJsonObject();
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
String classPath = Component.getComponentName((Class<Component>) src.getClass());
|
||||
jo.add(PROP_NAME, new JsonPrimitive(classPath));
|
||||
|
||||
return jo;
|
||||
}
|
||||
}
|
|
@ -2,6 +2,7 @@
|
|||
|
||||
import com.google.gson.*;
|
||||
import ru.gravit.launchserver.auth.hwid.HWIDHandler;
|
||||
import ru.gravit.utils.helper.LogHelper;
|
||||
|
||||
import java.lang.reflect.Type;
|
||||
|
||||
|
@ -12,6 +13,11 @@ public class HWIDHandlerAdapter implements JsonSerializer<HWIDHandler>, JsonDese
|
|||
public HWIDHandler deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {
|
||||
String typename = json.getAsJsonObject().getAsJsonPrimitive(PROP_NAME).getAsString();
|
||||
Class<? extends HWIDHandler> cls = HWIDHandler.getHandlerClass(typename);
|
||||
if(cls == null)
|
||||
{
|
||||
LogHelper.error("HWIDHandler %s not found", typename);
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
return (HWIDHandler) context.deserialize(json, cls);
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
|
||||
import com.google.gson.*;
|
||||
import ru.gravit.launchserver.auth.permissions.PermissionsHandler;
|
||||
import ru.gravit.utils.helper.LogHelper;
|
||||
|
||||
import java.lang.reflect.Type;
|
||||
|
||||
|
@ -12,6 +13,11 @@ public class PermissionsHandlerAdapter implements JsonSerializer<PermissionsHand
|
|||
public PermissionsHandler deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {
|
||||
String typename = json.getAsJsonObject().getAsJsonPrimitive(PROP_NAME).getAsString();
|
||||
Class<? extends PermissionsHandler> cls = PermissionsHandler.getHandlerClass(typename);
|
||||
if(cls == null)
|
||||
{
|
||||
LogHelper.error("PermissionsHandler %s not found", typename);
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
return (PermissionsHandler) context.deserialize(json, cls);
|
||||
|
|
|
@ -0,0 +1,37 @@
|
|||
package ru.gravit.launchserver.config;
|
||||
|
||||
import com.google.gson.*;
|
||||
import ru.gravit.launchserver.auth.handler.AuthHandler;
|
||||
import ru.gravit.launchserver.auth.protect.ProtectHandler;
|
||||
import ru.gravit.utils.helper.LogHelper;
|
||||
|
||||
import java.lang.reflect.Type;
|
||||
|
||||
public class ProtectHandlerAdapter implements JsonSerializer<ProtectHandler>, JsonDeserializer<ProtectHandler> {
|
||||
private static final String PROP_NAME = "type";
|
||||
|
||||
@Override
|
||||
public ProtectHandler deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {
|
||||
String typename = json.getAsJsonObject().getAsJsonPrimitive(PROP_NAME).getAsString();
|
||||
Class<? extends ProtectHandler> cls = ProtectHandler.getHandlerClass(typename);
|
||||
if(cls == null)
|
||||
{
|
||||
LogHelper.error("ProtectHandler %s not found", typename);
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
return (ProtectHandler) context.deserialize(json, cls);
|
||||
}
|
||||
|
||||
@Override
|
||||
public JsonElement serialize(ProtectHandler src, Type typeOfSrc, JsonSerializationContext context) {
|
||||
JsonObject jo = context.serialize(src).getAsJsonObject();
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
String classPath = ProtectHandler.getHandlerName((Class<ProtectHandler>) src.getClass());
|
||||
jo.add(PROP_NAME, new JsonPrimitive(classPath));
|
||||
|
||||
return jo;
|
||||
}
|
||||
}
|
|
@ -2,6 +2,7 @@
|
|||
|
||||
import com.google.gson.*;
|
||||
import ru.gravit.launchserver.texture.TextureProvider;
|
||||
import ru.gravit.utils.helper.LogHelper;
|
||||
|
||||
import java.lang.reflect.Type;
|
||||
|
||||
|
@ -12,6 +13,11 @@ public class TextureProviderAdapter implements JsonSerializer<TextureProvider>,
|
|||
public TextureProvider deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {
|
||||
String typename = json.getAsJsonObject().getAsJsonPrimitive(PROP_NAME).getAsString();
|
||||
Class<? extends TextureProvider> cls = TextureProvider.getProviderClass(typename);
|
||||
if(cls == null)
|
||||
{
|
||||
LogHelper.error("TextureProvider %s not found", typename);
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
return (TextureProvider) context.deserialize(json, cls);
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
package ru.gravit.launchserver.manangers.hook;
|
||||
|
||||
import ru.gravit.launcher.request.RequestException;
|
||||
import ru.gravit.launchserver.auth.AuthException;
|
||||
import ru.gravit.launchserver.response.auth.AuthResponse;
|
||||
import ru.gravit.launchserver.socket.Client;
|
||||
|
||||
|
@ -14,22 +16,22 @@ public class AuthHookManager {
|
|||
|
||||
@FunctionalInterface
|
||||
public interface AuthPreHook {
|
||||
void preAuthHook(AuthResponse.AuthContext context, Client client);
|
||||
void preAuthHook(AuthResponse.AuthContext context, Client client) throws AuthException;
|
||||
}
|
||||
|
||||
@FunctionalInterface
|
||||
public interface AuthPostHook {
|
||||
void postAuthHook(AuthResponse.AuthContext context, Client client);
|
||||
void postAuthHook(AuthResponse.AuthContext context, Client client) throws AuthException;
|
||||
}
|
||||
|
||||
@FunctionalInterface
|
||||
public interface CheckServerHook {
|
||||
void checkServerHook(String username, String serverID);
|
||||
void checkServerHook(String username, String serverID) throws AuthException;
|
||||
}
|
||||
|
||||
@FunctionalInterface
|
||||
public interface JoinServerHook {
|
||||
void joinServerHook(String username, String accessToken, String serverID);
|
||||
void joinServerHook(String username, String accessToken, String serverID) throws AuthException;
|
||||
}
|
||||
|
||||
public void registerPostHook(AuthPostHook hook) {
|
||||
|
@ -48,25 +50,25 @@ public void registerPreHook(AuthPreHook hook) {
|
|||
PRE_HOOKS.add(hook);
|
||||
}
|
||||
|
||||
public void preHook(AuthResponse.AuthContext context, Client client) {
|
||||
public void preHook(AuthResponse.AuthContext context, Client client) throws AuthException {
|
||||
for (AuthPreHook preHook : PRE_HOOKS) {
|
||||
preHook.preAuthHook(context, client);
|
||||
}
|
||||
}
|
||||
|
||||
public void checkServerHook(String username, String serverID) {
|
||||
public void checkServerHook(String username, String serverID) throws AuthException {
|
||||
for (CheckServerHook hook : CHECKSERVER_HOOKS) {
|
||||
hook.checkServerHook(username, serverID);
|
||||
}
|
||||
}
|
||||
|
||||
public void joinServerHook(String username, String accessToken, String serverID) {
|
||||
public void joinServerHook(String username, String accessToken, String serverID) throws AuthException {
|
||||
for (JoinServerHook hook : JOINSERVER_HOOKS) {
|
||||
hook.joinServerHook(username, accessToken, serverID);
|
||||
}
|
||||
}
|
||||
|
||||
public void postHook(AuthResponse.AuthContext context, Client client) {
|
||||
public void postHook(AuthResponse.AuthContext context, Client client) throws AuthException {
|
||||
for (AuthPostHook postHook : POST_HOOKS) {
|
||||
postHook.postAuthHook(context, client);
|
||||
}
|
||||
|
|
|
@ -37,13 +37,14 @@ public AuthResponse(LaunchServer server, long session, HInput input, HOutput out
|
|||
}
|
||||
|
||||
public static class AuthContext {
|
||||
public AuthContext(long session, String login, int password_lenght, String customText, String client, String hwid, boolean isServerAuth) {
|
||||
public AuthContext(long session, String login, int password_lenght, String customText, String client, String hwid, String ip, boolean isServerAuth) {
|
||||
this.session = session;
|
||||
this.login = login;
|
||||
this.password_lenght = password_lenght;
|
||||
this.customText = customText;
|
||||
this.client = client;
|
||||
this.hwid = hwid;
|
||||
this.ip = ip;
|
||||
this.isServerAuth = isServerAuth;
|
||||
}
|
||||
|
||||
|
@ -53,6 +54,7 @@ public AuthContext(long session, String login, int password_lenght, String custo
|
|||
public String client;
|
||||
public String hwid;
|
||||
public String customText;
|
||||
public String ip;
|
||||
public boolean isServerAuth;
|
||||
}
|
||||
|
||||
|
@ -86,13 +88,9 @@ public void reply() throws Exception {
|
|||
if(pair == null) requestError("Auth type not found");
|
||||
AuthProvider provider = pair.provider;
|
||||
clientData.type = Client.Type.USER;
|
||||
AuthContext context = new AuthContext(session, login, password.length(), customText, client, hwid_str, false);
|
||||
AuthContext context = new AuthContext(session, login, password.length(), customText, client, hwid_str, ip, false);
|
||||
try {
|
||||
server.authHookManager.preHook(context, clientData);
|
||||
if (server.limiter.isLimit(ip)) {
|
||||
AuthProvider.authError(server.config.authRejectString);
|
||||
return;
|
||||
}
|
||||
if (!clientData.checkSign) {
|
||||
throw new AuthException("You must using checkLauncher");
|
||||
}
|
||||
|
@ -145,10 +143,12 @@ public void reply() throws Exception {
|
|||
requestError("Internal auth handler error");
|
||||
return;
|
||||
}
|
||||
String protectToken = server.config.protectHandler.generateSecureToken(context);
|
||||
writeNoError(output);
|
||||
// Write profile and UUID
|
||||
ProfileByUUIDResponse.getProfile(server, uuid, result.username, client, clientData.auth.textureProvider).write(output);
|
||||
output.writeASCII(result.accessToken, -SecurityHelper.TOKEN_STRING_LENGTH);
|
||||
clientData.permissions.write(output);
|
||||
output.writeString(protectToken, SerializeLimits.MAX_CUSTOM_TEXT);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -57,10 +57,6 @@ public void reply() throws Exception {
|
|||
if(pair == null) requestError("Auth type not found");
|
||||
AuthProvider provider = pair.provider;
|
||||
try {
|
||||
if (server.limiter.isLimit(ip)) {
|
||||
AuthProvider.authError(server.config.authRejectString);
|
||||
return;
|
||||
}
|
||||
result = provider.auth(login, password, ip);
|
||||
if (!VerifyHelper.isValidUsername(result.username)) {
|
||||
AuthProvider.authError(String.format("Illegal result: '%s'", result.username));
|
||||
|
|
|
@ -57,10 +57,6 @@ public void execute(WebSocketService service, ChannelHandlerContext ctx, Client
|
|||
try {
|
||||
AuthRequestEvent result = new AuthRequestEvent();
|
||||
String ip = IOHelper.getIP(ctx.channel().remoteAddress());
|
||||
if (LaunchServer.server.limiter.isLimit(ip)) {
|
||||
AuthProvider.authError(LaunchServer.server.config.authRejectString);
|
||||
return;
|
||||
}
|
||||
if ((authType == null || authType == ConnectTypes.CLIENT) &&!clientData.checkSign) {
|
||||
AuthProvider.authError("Don't skip Launcher Update");
|
||||
return;
|
||||
|
@ -86,7 +82,7 @@ public void execute(WebSocketService service, ChannelHandlerContext ctx, Client
|
|||
AuthProviderPair pair;
|
||||
if(auth_id.isEmpty()) pair = LaunchServer.server.config.getAuthProviderPair();
|
||||
else pair = LaunchServer.server.config.getAuthProviderPair(auth_id);
|
||||
ru.gravit.launchserver.response.auth.AuthResponse.AuthContext context = new ru.gravit.launchserver.response.auth.AuthResponse.AuthContext(0, login, password.length(),customText, client, null, false);
|
||||
ru.gravit.launchserver.response.auth.AuthResponse.AuthContext context = new ru.gravit.launchserver.response.auth.AuthResponse.AuthContext(0, login, password.length(),customText, client, ip, null, false);
|
||||
AuthProvider provider = pair.provider;
|
||||
LaunchServer.server.authHookManager.preHook(context, clientData);
|
||||
provider.preAuth(login,password,customText,ip);
|
||||
|
|
|
@ -0,0 +1,21 @@
|
|||
StringEncryption:
|
||||
Enabled: true
|
||||
Mode: Normal
|
||||
StringPool: false
|
||||
InvokeDynamic: None
|
||||
NumberObfuscation: Normal
|
||||
FlowObfuscation: Normal
|
||||
HideCode: false
|
||||
Shuffler: true
|
||||
Crasher: false
|
||||
Optimizer:
|
||||
Enabled: true
|
||||
InlineGotoGoto: true
|
||||
InlineGotoReturn: true
|
||||
RemoveNopInstructions: true
|
||||
Watermarker:
|
||||
Enabled: false
|
||||
Message: "This copy belongs to GravitLauncher"
|
||||
Key: "SuperSecureKey"
|
||||
Dictionary: Spaces
|
||||
TrashClasses: 500
|
|
@ -215,6 +215,7 @@ function doAuth(login, rsaPassword) {
|
|||
overlay.show(processing.overlay, function (event) {
|
||||
FunctionalBridge.getHWID.join();
|
||||
makeAuthRequest(login, rsaPassword, function (result) {
|
||||
FunctionalBridge.setAuthParams(result);
|
||||
loginData = { pp: result.playerProfile , accessToken: result.accessToken, permissions: result.permissions};
|
||||
|
||||
overlay.hide(0, function () {
|
||||
|
|
|
@ -302,7 +302,7 @@ public static Process launch(
|
|||
// Write params file (instead of CLI; Mustdie32 API can't handle command line > 32767 chars)
|
||||
LogHelper.debug("Writing ClientLauncher params");
|
||||
ClientLauncherContext context = new ClientLauncherContext();
|
||||
CommonHelper.newThread("Client params writter", false, () ->
|
||||
CommonHelper.newThread("Client params writter", true, () ->
|
||||
{
|
||||
try {
|
||||
try (ServerSocket socket = new ServerSocket()) {
|
||||
|
@ -356,8 +356,6 @@ public static Process launch(
|
|||
context.args.add(JVMHelper.jvmProperty("os.name", "Windows 10"));
|
||||
context.args.add(JVMHelper.jvmProperty("os.version", "10.0"));
|
||||
}
|
||||
context.args.add(JVMHelper.systemToJvmProperty("avn32"));
|
||||
context.args.add(JVMHelper.systemToJvmProperty("avn64"));
|
||||
}
|
||||
// Add classpath and main class
|
||||
String pathLauncher = IOHelper.getCodeSource(ClientLauncher.class).toString();
|
||||
|
@ -388,6 +386,7 @@ public static Process launch(
|
|||
}
|
||||
// Let's rock!
|
||||
process = builder.start();
|
||||
if(!LogHelper.isDebugEnabled()) Thread.sleep(1000); //даем время потоку записи
|
||||
return process;
|
||||
}
|
||||
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
import javafx.concurrent.Task;
|
||||
import ru.gravit.launcher.HWID;
|
||||
import ru.gravit.launcher.LauncherAPI;
|
||||
import ru.gravit.launcher.events.request.AuthRequestEvent;
|
||||
import ru.gravit.launcher.guard.LauncherGuardManager;
|
||||
import ru.gravit.launcher.hasher.FileNameMatcher;
|
||||
import ru.gravit.launcher.hasher.HashedDir;
|
||||
|
@ -103,6 +104,12 @@ public static HasherStore getDefaultHasherStore() {
|
|||
return HasherManager.getDefaultStore();
|
||||
}
|
||||
|
||||
@LauncherAPI
|
||||
public static void setAuthParams(AuthRequestEvent event)
|
||||
{
|
||||
LauncherGuardManager.guard.setProtectToken(event.protectToken);
|
||||
}
|
||||
|
||||
@FunctionalInterface
|
||||
public interface HashedDirRunnable {
|
||||
SignedObjectHolder<HashedDir> run() throws Exception;
|
||||
|
|
|
@ -11,4 +11,5 @@ public interface LauncherGuardInterface {
|
|||
void init(boolean clientInstance);
|
||||
void addCustomParams(ClientLauncherContext context);
|
||||
void addCustomEnv(ClientLauncherContext context);
|
||||
void setProtectToken(String token);
|
||||
}
|
||||
|
|
|
@ -43,4 +43,9 @@ public void addCustomParams(ClientLauncherContext context) {
|
|||
public void addCustomEnv(ClientLauncherContext context) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setProtectToken(String token) {
|
||||
//Skip
|
||||
}
|
||||
}
|
||||
|
|
|
@ -40,4 +40,9 @@ public void addCustomParams(ClientLauncherContext context) {
|
|||
public void addCustomEnv(ClientLauncherContext context) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setProtectToken(String token) {
|
||||
//Skip
|
||||
}
|
||||
}
|
||||
|
|
|
@ -13,6 +13,9 @@
|
|||
import java.util.Map;
|
||||
|
||||
public class LauncherWrapperGuard implements LauncherGuardInterface {
|
||||
|
||||
public String protectToken;
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return "wrapper";
|
||||
|
@ -62,6 +65,7 @@ public void addCustomEnv(ClientLauncherContext context) {
|
|||
env.put("GUARD_USERNAME", context.playerProfile.username);
|
||||
env.put("GUARD_PUBLICKEY", config.publicKey.getModulus().toString(16));
|
||||
env.put("GUARD_PROJECTNAME", config.projectname);
|
||||
env.put("GUARD_TOKEN", protectToken);
|
||||
if(config.guardLicenseName != null)
|
||||
env.put("GUARD_LICENSE_NAME", config.guardLicenseName);
|
||||
if(config.guardLicenseKey != null)
|
||||
|
@ -69,4 +73,9 @@ public void addCustomEnv(ClientLauncherContext context) {
|
|||
env.put("GUARD_LICENSE_KEY", config.guardLicenseKey);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setProtectToken(String token) {
|
||||
protectToken = token;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -109,7 +109,8 @@ protected AuthRequestEvent requestDo(HInput input, HOutput output) throws IOExce
|
|||
PlayerProfile pp = new PlayerProfile(input);
|
||||
String accessToken = input.readASCII(-SecurityHelper.TOKEN_STRING_LENGTH);
|
||||
ClientPermissions permissions = new ClientPermissions(input);
|
||||
return new AuthRequestEvent(pp, accessToken, permissions);
|
||||
String protectToken = input.readString(SerializeLimits.MAX_CUSTOM_TEXT);
|
||||
return new AuthRequestEvent(permissions, pp, accessToken, protectToken);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -303,9 +303,16 @@ public Integer getLegacyType() {
|
|||
}
|
||||
|
||||
@Override
|
||||
protected UpdateRequestEvent requestDo(HInput input, HOutput output) throws IOException, SignatureException {
|
||||
public UpdateRequestEvent request() throws Exception {
|
||||
Files.createDirectories(dir);
|
||||
localDir = new HashedDir(dir, matcher, false, digest);
|
||||
|
||||
// Start request
|
||||
return super.request();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected UpdateRequestEvent requestDo(HInput input, HOutput output) throws IOException, SignatureException {
|
||||
// Write update dir name
|
||||
output.writeString(dirName, 255);
|
||||
output.flush();
|
||||
|
|
1
Radon
Submodule
1
Radon
Submodule
|
@ -0,0 +1 @@
|
|||
Subproject commit e1f7548f97132fa29b01f68bd57ffab32de7b6e7
|
|
@ -1,10 +1,11 @@
|
|||
configure(subprojects.findAll {it.name != 'modules'}) {
|
||||
configure(subprojects.findAll { it.name != 'modules' && it.name != 'Radon' }) {
|
||||
apply plugin: 'idea'
|
||||
apply plugin: 'eclipse'
|
||||
apply plugin: 'java'
|
||||
|
||||
repositories {
|
||||
mavenCentral()
|
||||
maven { url 'http://oss.sonatype.org/content/groups/public' }
|
||||
maven {
|
||||
url "http://clojars.org/repo/"
|
||||
}
|
||||
|
|
|
@ -20,6 +20,8 @@ public AuthRequestEvent() {
|
|||
public PlayerProfile playerProfile;
|
||||
@LauncherNetworkAPI
|
||||
public String accessToken;
|
||||
@LauncherNetworkAPI
|
||||
public String protectToken;
|
||||
|
||||
public AuthRequestEvent(PlayerProfile pp, String accessToken, ClientPermissions permissions) {
|
||||
this.playerProfile = pp;
|
||||
|
@ -27,6 +29,13 @@ public AuthRequestEvent(PlayerProfile pp, String accessToken, ClientPermissions
|
|||
this.permissions = permissions;
|
||||
}
|
||||
|
||||
public AuthRequestEvent(ClientPermissions permissions, PlayerProfile playerProfile, String accessToken, String protectToken) {
|
||||
this.permissions = permissions;
|
||||
this.playerProfile = playerProfile;
|
||||
this.accessToken = accessToken;
|
||||
this.protectToken = protectToken;
|
||||
}
|
||||
|
||||
@Override
|
||||
public UUID getUUID() {
|
||||
return uuid;
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
rootProject.name = 'GravitLauncher'
|
||||
|
||||
include 'Launcher'
|
||||
include 'Radon'
|
||||
include 'libLauncher'
|
||||
include 'LauncherAPI'
|
||||
include 'ServerWrapper'
|
||||
|
|
Loading…
Reference in a new issue