Merge branch 'dev' into master

This commit is contained in:
Gravit 2019-03-22 13:13:15 +07:00 committed by GitHub
commit b34042b8e1
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
41 changed files with 523 additions and 207 deletions

3
.gitmodules vendored
View file

@ -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

View file

@ -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

View file

@ -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());

View file

@ -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();
}
}

View file

@ -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);

View file

@ -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);

View file

@ -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
}
}

View file

@ -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
}

View file

@ -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

View file

@ -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

View file

@ -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 {

View file

@ -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;

View file

@ -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

View file

@ -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;
}
}

View file

@ -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() {

View file

@ -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);
}

View file

@ -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);

View file

@ -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);

View file

@ -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;
}
}

View file

@ -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);

View file

@ -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);

View file

@ -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;
}
}

View file

@ -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);

View file

@ -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);
}

View file

@ -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);
}
}

View file

@ -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));

View file

@ -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);

View file

@ -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

View file

@ -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 () {

View file

@ -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;
}

View file

@ -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;

View file

@ -11,4 +11,5 @@ public interface LauncherGuardInterface {
void init(boolean clientInstance);
void addCustomParams(ClientLauncherContext context);
void addCustomEnv(ClientLauncherContext context);
void setProtectToken(String token);
}

View file

@ -43,4 +43,9 @@ public void addCustomParams(ClientLauncherContext context) {
public void addCustomEnv(ClientLauncherContext context) {
}
@Override
public void setProtectToken(String token) {
//Skip
}
}

View file

@ -40,4 +40,9 @@ public void addCustomParams(ClientLauncherContext context) {
public void addCustomEnv(ClientLauncherContext context) {
}
@Override
public void setProtectToken(String token) {
//Skip
}
}

View file

@ -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;
}
}

View file

@ -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

View file

@ -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

@ -0,0 +1 @@
Subproject commit e1f7548f97132fa29b01f68bd57ffab32de7b6e7

View file

@ -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/"
}

View file

@ -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;

View file

@ -1,6 +1,7 @@
rootProject.name = 'GravitLauncher'
include 'Launcher'
include 'Radon'
include 'libLauncher'
include 'LauncherAPI'
include 'ServerWrapper'