mirror of
https://github.com/GravitLauncher/Launcher
synced 2024-11-15 03:31:15 +03:00
Merge branch 'release/5.0.9'
This commit is contained in:
commit
610b6de76f
39 changed files with 674 additions and 296 deletions
|
@ -1,41 +1,49 @@
|
||||||
image: frekele/java
|
image: docker:latest
|
||||||
|
services:
|
||||||
|
- docker:dind
|
||||||
|
|
||||||
|
variables:
|
||||||
|
DOCKER_DRIVER: overlay2
|
||||||
|
CI_VERSION: '6.6.$CI_PIPELINE_IID'
|
||||||
|
|
||||||
stages:
|
stages:
|
||||||
- build
|
- build
|
||||||
- test
|
- test
|
||||||
- deploy
|
|
||||||
|
|
||||||
before_script:
|
|
||||||
# - echo `pwd` # debug
|
|
||||||
# - echo "$CI_BUILD_NAME, $CI_BUILD_REF_NAME $CI_BUILD_STAGE" # debug
|
|
||||||
- export GRADLE_USER_HOME=`pwd`/.gradle
|
|
||||||
- apt-get update -qq && apt-get install -y -qq git git-core
|
|
||||||
|
|
||||||
cache:
|
|
||||||
key: ${CI_COMMIT_REF_NAME}
|
|
||||||
paths:
|
|
||||||
- .gradle/wrapper
|
|
||||||
- .gradle/caches
|
|
||||||
|
|
||||||
build:
|
build:
|
||||||
|
image: frekele/java
|
||||||
stage: build
|
stage: build
|
||||||
|
before_script:
|
||||||
|
- apt-get -y update
|
||||||
|
- apt-get -y install zip git
|
||||||
|
- export GRADLE_USER_HOME=`pwd`/.gradle
|
||||||
|
- chmod +x gradlew
|
||||||
|
- sed -i 's/git@github.com:/https:\/\/github.com\//' .gitmodules
|
||||||
|
- git submodule sync
|
||||||
|
- git submodule update --init --recursive
|
||||||
script:
|
script:
|
||||||
- sed -i 's/git@github.com:/https:\/\/github.com\//' .gitmodules
|
- ./gradlew assemble
|
||||||
- git submodule sync
|
after_script:
|
||||||
- git submodule update --init --recursive
|
- mkdir -p artifacts/modules
|
||||||
- ./gradlew assemble
|
- cd LaunchServer/build/libs/
|
||||||
- mv LaunchServer/build/libs/*.jar LaunchServer
|
- zip -r -9 ../../../artifacts/libraries.zip * -x "LaunchServer.jar" -x "LaunchServer-clean.jar"
|
||||||
- mv ServerWrapper/build/libs/*.jar ServerWrapper
|
- mv LaunchServer.jar ../../../artifacts/LaunchServer.jar
|
||||||
- mv modules/*_module/build/libs/*.jar modules
|
- cd ../../../ServerWrapper/build/libs
|
||||||
artifacts:
|
- mv ServerWrapper.jar ../../../artifacts/ServerWrapper.jar
|
||||||
|
- cd ../../../
|
||||||
|
- mv modules/*_module/build/libs/*.jar artifacts/modules
|
||||||
|
- mv modules/*_swmodule/build/libs/*.jar artifacts/modules
|
||||||
|
- mv modules/*_lmodule/build/libs/*.jar artifacts/modules
|
||||||
|
cache:
|
||||||
paths:
|
paths:
|
||||||
- LaunchServer/*.jar
|
- .gradle
|
||||||
- ServerWrapper/*.jar
|
artifacts:
|
||||||
- modules/*.jar
|
expire_in: 6 week
|
||||||
|
paths:
|
||||||
|
- artifacts
|
||||||
|
|
||||||
test:
|
test:
|
||||||
|
image: frekele/java
|
||||||
stage: test
|
stage: test
|
||||||
script:
|
script:
|
||||||
- ./gradlew check
|
- ./gradlew check
|
||||||
|
|
||||||
after_script:
|
|
||||||
- echo "End CI"
|
|
|
@ -55,6 +55,15 @@ public void acceptVisitor(byte[] classData, ClassVisitor visitor) {
|
||||||
public void acceptVisitor(String className, ClassVisitor visitor) throws IOException {
|
public void acceptVisitor(String className, ClassVisitor visitor) throws IOException {
|
||||||
acceptVisitor(getClassData(className), visitor);
|
acceptVisitor(getClassData(className), visitor);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void acceptVisitor(byte[] classData, ClassVisitor visitor, int flags) {
|
||||||
|
new ClassReader(classData).accept(visitor, flags);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void acceptVisitor(String className, ClassVisitor visitor, int flags) throws IOException {
|
||||||
|
acceptVisitor(getClassData(className), visitor, flags);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
public byte[] getClassData(String className) throws IOException {
|
public byte[] getClassData(String className) throws IOException {
|
||||||
for (JarFile f : cp) {
|
for (JarFile f : cp) {
|
||||||
|
|
|
@ -0,0 +1,169 @@
|
||||||
|
package pro.gravit.launchserver.asm;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import org.objectweb.asm.ClassReader;
|
||||||
|
import org.objectweb.asm.Type;
|
||||||
|
import org.objectweb.asm.tree.AbstractInsnNode;
|
||||||
|
import org.objectweb.asm.tree.AnnotationNode;
|
||||||
|
import org.objectweb.asm.tree.ClassNode;
|
||||||
|
import org.objectweb.asm.tree.InvokeDynamicInsnNode;
|
||||||
|
import org.objectweb.asm.tree.LdcInsnNode;
|
||||||
|
import org.objectweb.asm.tree.MethodInsnNode;
|
||||||
|
import org.objectweb.asm.tree.MethodNode;
|
||||||
|
|
||||||
|
import pro.gravit.utils.helper.IOHelper;
|
||||||
|
|
||||||
|
import static org.objectweb.asm.Opcodes.*;
|
||||||
|
|
||||||
|
public final class NodeUtils {
|
||||||
|
private NodeUtils() { }
|
||||||
|
public static ClassNode forClass(Class<?> cls, int flags) {
|
||||||
|
try (InputStream in = cls.getClassLoader().getResourceAsStream(cls.getName().replace('.', '/') + ".class")) {
|
||||||
|
ClassNode ret = new ClassNode();
|
||||||
|
new ClassReader(IOHelper.read(in)).accept(ret, flags);
|
||||||
|
return ret;
|
||||||
|
} catch (IOException e) {
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static ClassNode forClass(String clazz, int flags, ClassMetadataReader r) {
|
||||||
|
try {
|
||||||
|
ClassNode ret = new ClassNode();
|
||||||
|
r.acceptVisitor(clazz, ret, flags);
|
||||||
|
return ret;
|
||||||
|
} catch (IOException e) {
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static List<AnnotationNode> annots(String clazz, String method, ClassMetadataReader r) {
|
||||||
|
if (clazz.startsWith("L")) clazz = Type.getType(clazz).getInternalName();
|
||||||
|
try {
|
||||||
|
List<AnnotationNode> ret = new ArrayList<>();
|
||||||
|
ClassNode n = forClass(clazz, ClassReader.SKIP_CODE | ClassReader.SKIP_DEBUG, r);
|
||||||
|
if (n.visibleAnnotations != null) ret.addAll(n.visibleAnnotations);
|
||||||
|
if (n.invisibleAnnotations != null) ret.addAll(n.invisibleAnnotations);
|
||||||
|
for (MethodNode m : n.methods)
|
||||||
|
if (method.equals(m.name)) {
|
||||||
|
if (m.visibleAnnotations != null) ret.addAll(m.visibleAnnotations);
|
||||||
|
if (m.invisibleAnnotations != null) ret.addAll(m.invisibleAnnotations);
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
} catch (Throwable e) {
|
||||||
|
return Collections.emptyList();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static int doMethodEmulation(String desc) {
|
||||||
|
int result = 0;
|
||||||
|
Type returnType = Type.getReturnType(desc);
|
||||||
|
|
||||||
|
if (returnType.getSort() == Type.LONG || returnType.getSort() == Type.DOUBLE)
|
||||||
|
result++;
|
||||||
|
if (returnType.getSort() != Type.VOID)
|
||||||
|
result++;
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static int opcodeEmulation(AbstractInsnNode e) {
|
||||||
|
int stackSize = 0;
|
||||||
|
switch (e.getOpcode()) {
|
||||||
|
case NOP:
|
||||||
|
case LALOAD: // (index, arrayref) -> (long, long_top)
|
||||||
|
case DALOAD: // (index, arrayref) -> (double, double_top)
|
||||||
|
case SWAP: // (value1, value2) -> (value2, value1)
|
||||||
|
case INEG:
|
||||||
|
case LNEG:
|
||||||
|
case FNEG:
|
||||||
|
case DNEG:
|
||||||
|
case IINC:
|
||||||
|
case I2F:
|
||||||
|
case L2D:
|
||||||
|
case F2I:
|
||||||
|
case D2L:
|
||||||
|
case I2B:
|
||||||
|
case I2C:
|
||||||
|
case I2S:
|
||||||
|
case GOTO:
|
||||||
|
case RETURN:
|
||||||
|
case NEWARRAY:
|
||||||
|
case ANEWARRAY:
|
||||||
|
case ARRAYLENGTH:
|
||||||
|
case CHECKCAST:
|
||||||
|
case INSTANCEOF:
|
||||||
|
// Does nothing
|
||||||
|
break;
|
||||||
|
case ACONST_NULL:
|
||||||
|
case ICONST_M1:
|
||||||
|
case ICONST_0:
|
||||||
|
case ICONST_1:
|
||||||
|
case ICONST_2:
|
||||||
|
case ICONST_3:
|
||||||
|
case ICONST_4:
|
||||||
|
case ICONST_5:
|
||||||
|
case FCONST_0:
|
||||||
|
case FCONST_1:
|
||||||
|
case FCONST_2:
|
||||||
|
case BIPUSH:
|
||||||
|
case SIPUSH:
|
||||||
|
case ILOAD:
|
||||||
|
case FLOAD:
|
||||||
|
case ALOAD:
|
||||||
|
case DUP:
|
||||||
|
case DUP_X1:
|
||||||
|
case DUP_X2:
|
||||||
|
case I2L:
|
||||||
|
case I2D:
|
||||||
|
case F2L:
|
||||||
|
case F2D:
|
||||||
|
case NEW:
|
||||||
|
// Pushes one-word constant to stack
|
||||||
|
stackSize++;
|
||||||
|
break;
|
||||||
|
case LDC:
|
||||||
|
LdcInsnNode ldc = (LdcInsnNode) e;
|
||||||
|
if (ldc.cst instanceof Long || ldc.cst instanceof Double)
|
||||||
|
stackSize++;
|
||||||
|
|
||||||
|
stackSize++;
|
||||||
|
break;
|
||||||
|
case LCONST_0:
|
||||||
|
case LCONST_1:
|
||||||
|
case DCONST_0:
|
||||||
|
case DCONST_1:
|
||||||
|
case LLOAD:
|
||||||
|
case DLOAD:
|
||||||
|
case DUP2:
|
||||||
|
case DUP2_X1:
|
||||||
|
case DUP2_X2:
|
||||||
|
// Pushes two-word constant or two one-word constants to stack
|
||||||
|
stackSize++;
|
||||||
|
stackSize++;
|
||||||
|
break;
|
||||||
|
case INVOKEVIRTUAL:
|
||||||
|
case INVOKESPECIAL:
|
||||||
|
case INVOKEINTERFACE:
|
||||||
|
stackSize += doMethodEmulation(((MethodInsnNode) e).desc);
|
||||||
|
break;
|
||||||
|
case INVOKESTATIC:
|
||||||
|
stackSize += doMethodEmulation(((MethodInsnNode) e).desc);
|
||||||
|
break;
|
||||||
|
case INVOKEDYNAMIC:
|
||||||
|
stackSize += doMethodEmulation(((InvokeDynamicInsnNode) e).desc);
|
||||||
|
break;
|
||||||
|
case JSR:
|
||||||
|
case RET:
|
||||||
|
throw new RuntimeException("Did not expect JSR/RET instructions");
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return stackSize;
|
||||||
|
}
|
||||||
|
}
|
|
@ -77,7 +77,7 @@ public static void apply(Path inputFile, Path addFile, ZipOutputStream output, L
|
||||||
try {
|
try {
|
||||||
bytes = classFix(bytes, reader, srv.config.launcher.stripLineNumbers);
|
bytes = classFix(bytes, reader, srv.config.launcher.stripLineNumbers);
|
||||||
} catch (Throwable t) {
|
} catch (Throwable t) {
|
||||||
LogHelper.subWarning("Error on fixing class: " + t);
|
LogHelper.error(t);
|
||||||
}
|
}
|
||||||
output.write(bytes);
|
output.write(bytes);
|
||||||
} else
|
} else
|
||||||
|
|
|
@ -3,7 +3,6 @@
|
||||||
import pro.gravit.launchserver.LaunchServer;
|
import pro.gravit.launchserver.LaunchServer;
|
||||||
import pro.gravit.launchserver.command.Command;
|
import pro.gravit.launchserver.command.Command;
|
||||||
import pro.gravit.launchserver.dao.User;
|
import pro.gravit.launchserver.dao.User;
|
||||||
import pro.gravit.launchserver.dao.UserHWID;
|
|
||||||
import pro.gravit.utils.helper.LogHelper;
|
import pro.gravit.utils.helper.LogHelper;
|
||||||
|
|
||||||
public class GetUserCommand extends Command {
|
public class GetUserCommand extends Command {
|
||||||
|
@ -31,9 +30,9 @@ public void invoke(String... args) throws Exception {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
LogHelper.info("[%s] UUID: %s", user.username, user.uuid.toString());
|
LogHelper.info("[%s] UUID: %s", user.username, user.uuid.toString());
|
||||||
for(UserHWID hwid : user.hwids)
|
//for(UserHWID hwid : user.hwids)
|
||||||
{
|
//{
|
||||||
LogHelper.info("[%s] HWID: memory: %d | serial %s | hwdiskserial: %s | processorID %s | macAddr %s", user.username, hwid.totalMemory, hwid.serialNumber, hwid.HWDiskSerial, hwid.processorID, hwid.macAddr);
|
// LogHelper.info("[%s] HWID: memory: %d | serial %s | hwdiskserial: %s | processorID %s | macAddr %s", user.username, hwid.totalMemory, hwid.serialNumber, hwid.HWDiskSerial, hwid.processorID, hwid.macAddr);
|
||||||
}
|
//}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,18 +4,13 @@
|
||||||
import java.security.MessageDigest;
|
import java.security.MessageDigest;
|
||||||
import java.security.NoSuchAlgorithmException;
|
import java.security.NoSuchAlgorithmException;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.Collection;
|
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
|
||||||
import javax.persistence.CascadeType;
|
|
||||||
import javax.persistence.Column;
|
import javax.persistence.Column;
|
||||||
import javax.persistence.Entity;
|
import javax.persistence.Entity;
|
||||||
import javax.persistence.FetchType;
|
|
||||||
import javax.persistence.GeneratedValue;
|
import javax.persistence.GeneratedValue;
|
||||||
import javax.persistence.GenerationType;
|
import javax.persistence.GenerationType;
|
||||||
import javax.persistence.Id;
|
import javax.persistence.Id;
|
||||||
import javax.persistence.JoinColumn;
|
|
||||||
import javax.persistence.OneToMany;
|
|
||||||
import javax.persistence.Table;
|
import javax.persistence.Table;
|
||||||
|
|
||||||
import pro.gravit.launcher.ClientPermissions;
|
import pro.gravit.launcher.ClientPermissions;
|
||||||
|
@ -39,12 +34,6 @@ public class User {
|
||||||
public String serverID;
|
public String serverID;
|
||||||
private String password_salt;
|
private String password_salt;
|
||||||
public long permissions;
|
public long permissions;
|
||||||
//TODO: заменить EAGER на LASY и придумать способ сохранить сессию
|
|
||||||
// [ERROR] org.hibernate.LazyInitializationException:
|
|
||||||
// failed to lazily initialize a collection of role: pro.gravit.launchserver.dao.User.hwids, could not initialize proxy - no Session
|
|
||||||
@OneToMany(cascade = CascadeType.ALL, fetch = FetchType.EAGER)
|
|
||||||
@JoinColumn(name = "user_id")
|
|
||||||
public Collection<UserHWID> hwids;
|
|
||||||
public void setPassword(String password)
|
public void setPassword(String password)
|
||||||
{
|
{
|
||||||
password_salt = SecurityHelper.randomStringAESKey();
|
password_salt = SecurityHelper.randomStringAESKey();
|
||||||
|
|
|
@ -0,0 +1,40 @@
|
||||||
|
{
|
||||||
|
"version": "1.14.4",
|
||||||
|
"assetIndex": "1.14.4",
|
||||||
|
"assetDir": "asset1.14.4",
|
||||||
|
"dir": "HiTech",
|
||||||
|
"info": "Информация о сервере",
|
||||||
|
"sortIndex": 0,
|
||||||
|
"title": "xxxxxxxx",
|
||||||
|
"serverAddress": "localhost",
|
||||||
|
"serverPort": 25565,
|
||||||
|
"update": [
|
||||||
|
"servers.dat"
|
||||||
|
],
|
||||||
|
"updateExclusions": [],
|
||||||
|
"updateShared": [],
|
||||||
|
"updateVerify": [
|
||||||
|
"libraries",
|
||||||
|
"natives",
|
||||||
|
"minecraft.jar"
|
||||||
|
],
|
||||||
|
"updateOptional": [],
|
||||||
|
"updateFastCheck": true,
|
||||||
|
"useWhitelist": false,
|
||||||
|
"mainClass": "net.minecraft.client.main.Main",
|
||||||
|
"jvmArgs": [
|
||||||
|
"-Dfml.ignorePatchDiscrepancies=true",
|
||||||
|
"-Dfml.ignoreInvalidMinecraftCertificates=rue",
|
||||||
|
"-XX:+UseConcMarkSweepGC",
|
||||||
|
"-XX:+CMSIncrementalMode",
|
||||||
|
"-XX:-UseAdaptiveSizePolicy",
|
||||||
|
"-Xmn128M",
|
||||||
|
"-XX:+DisableAttachMechanism"
|
||||||
|
],
|
||||||
|
"classPath": [
|
||||||
|
"minecraft.jar",
|
||||||
|
"libraries"
|
||||||
|
],
|
||||||
|
"clientArgs": [],
|
||||||
|
"whitelist": []
|
||||||
|
}
|
|
@ -20,9 +20,9 @@
|
||||||
-keepattributes Signature
|
-keepattributes Signature
|
||||||
-adaptresourcefilecontents META-INF/MANIFEST.MF
|
-adaptresourcefilecontents META-INF/MANIFEST.MF
|
||||||
|
|
||||||
-keeppackagenames com.mojang.**,net.minecraftforge.fml.**,cpw.mods.fml.**,com.google.gson.**,pro.gravit.repackage.**,org.fusesource.**
|
-keeppackagenames com.mojang.**,net.minecraftforge.fml.**,cpw.mods.fml.**,com.google.gson.**,pro.gravit.repackage.**,org.fusesource.**, pro.gravit.launcher.api.**
|
||||||
|
|
||||||
-keep class com.mojang.**,net.minecraftforge.fml.**,cpw.mods.fml.**,com.google.gson.**,pro.gravit.repackage.**,org.fusesource.** {
|
-keep class com.mojang.**,net.minecraftforge.fml.**,cpw.mods.fml.**,com.google.gson.**,pro.gravit.repackage.**,org.fusesource.**, pro.gravit.launcher.api.** {
|
||||||
*;
|
*;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
package pro.gravit.launcher;
|
package pro.gravit.launcher;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.nio.file.Path;
|
import java.nio.file.Path;
|
||||||
import java.nio.file.Paths;
|
import java.nio.file.Paths;
|
||||||
|
@ -8,6 +9,7 @@
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import pro.gravit.launcher.client.ClientLauncher;
|
import pro.gravit.launcher.client.ClientLauncher;
|
||||||
|
import pro.gravit.launcher.client.ClientModuleManager;
|
||||||
import pro.gravit.launcher.client.DirBridge;
|
import pro.gravit.launcher.client.DirBridge;
|
||||||
import pro.gravit.utils.helper.EnvHelper;
|
import pro.gravit.utils.helper.EnvHelper;
|
||||||
import pro.gravit.utils.helper.IOHelper;
|
import pro.gravit.utils.helper.IOHelper;
|
||||||
|
@ -17,7 +19,9 @@
|
||||||
public class ClientLauncherWrapper {
|
public class ClientLauncherWrapper {
|
||||||
public static final String MAGIC_ARG = "-Djdk.attach.allowAttachSelf";
|
public static final String MAGIC_ARG = "-Djdk.attach.allowAttachSelf";
|
||||||
public static final String WAIT_PROCESS_PROPERTY = "launcher.waitProcess";
|
public static final String WAIT_PROCESS_PROPERTY = "launcher.waitProcess";
|
||||||
|
public static final String NO_JAVA9_CHECK_PROPERTY = "launcher.noJava9Check";
|
||||||
public static boolean waitProcess = Boolean.getBoolean(WAIT_PROCESS_PROPERTY);
|
public static boolean waitProcess = Boolean.getBoolean(WAIT_PROCESS_PROPERTY);
|
||||||
|
public static boolean noJava9check = Boolean.getBoolean(NO_JAVA9_CHECK_PROPERTY);
|
||||||
|
|
||||||
public static void main(String[] arguments) throws IOException, InterruptedException {
|
public static void main(String[] arguments) throws IOException, InterruptedException {
|
||||||
LogHelper.printVersion("Launcher");
|
LogHelper.printVersion("Launcher");
|
||||||
|
@ -26,6 +30,9 @@ public static void main(String[] arguments) throws IOException, InterruptedExcep
|
||||||
JVMHelper.verifySystemProperties(Launcher.class, true);
|
JVMHelper.verifySystemProperties(Launcher.class, true);
|
||||||
EnvHelper.checkDangerousParams();
|
EnvHelper.checkDangerousParams();
|
||||||
LauncherConfig config = Launcher.getConfig();
|
LauncherConfig config = Launcher.getConfig();
|
||||||
|
LauncherEngine.modulesManager = new ClientModuleManager();
|
||||||
|
LauncherConfig.getAutogenConfig().initModules();
|
||||||
|
|
||||||
LogHelper.info("Launcher for project %s", config.projectname);
|
LogHelper.info("Launcher for project %s", config.projectname);
|
||||||
if (config.environment.equals(LauncherConfig.LauncherEnvironment.PROD)) {
|
if (config.environment.equals(LauncherConfig.LauncherEnvironment.PROD)) {
|
||||||
if (System.getProperty(LogHelper.DEBUG_PROPERTY) != null) {
|
if (System.getProperty(LogHelper.DEBUG_PROPERTY) != null) {
|
||||||
|
@ -53,12 +60,34 @@ public static void main(String[] arguments) throws IOException, InterruptedExcep
|
||||||
JVMHelper.addSystemPropertyToArgs(args, DirBridge.CUSTOMDIR_PROPERTY);
|
JVMHelper.addSystemPropertyToArgs(args, DirBridge.CUSTOMDIR_PROPERTY);
|
||||||
JVMHelper.addSystemPropertyToArgs(args, DirBridge.USE_CUSTOMDIR_PROPERTY);
|
JVMHelper.addSystemPropertyToArgs(args, DirBridge.USE_CUSTOMDIR_PROPERTY);
|
||||||
JVMHelper.addSystemPropertyToArgs(args, DirBridge.USE_OPTDIR_PROPERTY);
|
JVMHelper.addSystemPropertyToArgs(args, DirBridge.USE_OPTDIR_PROPERTY);
|
||||||
|
if (!noJava9check && !System.getProperty("java.version").startsWith("1.8"))
|
||||||
|
{
|
||||||
|
LogHelper.debug("Found Java 9+ ( %s )", System.getProperty("java.version"));
|
||||||
|
Collections.addAll(args, "--add-modules");
|
||||||
|
Collections.addAll(args, "javafx.base,javafx.fxml,javafx.controls,jdk.unsupported");
|
||||||
|
Path jvmDir = Paths.get(System.getProperty("java.home"));
|
||||||
|
String pathToFx = System.getenv("PATH_TO_FX");
|
||||||
|
Path fxPath = pathToFx == null ? null : Paths.get(pathToFx);
|
||||||
|
StringBuilder builder = new StringBuilder();
|
||||||
|
Path[] findPath = new Path[]{jvmDir, fxPath};
|
||||||
|
tryAddModule(findPath, "javafx.base", builder);
|
||||||
|
tryAddModule(findPath, "javafx.graphics", builder);
|
||||||
|
tryAddModule(findPath, "javafx.fxml", builder);
|
||||||
|
tryAddModule(findPath, "javafx.controls", builder);
|
||||||
|
String modulePath = builder.toString();
|
||||||
|
if(!modulePath.isEmpty())
|
||||||
|
{
|
||||||
|
Collections.addAll(args, "--module-path");
|
||||||
|
Collections.addAll(args, modulePath);
|
||||||
|
}
|
||||||
|
}
|
||||||
Collections.addAll(args, MAGIC_ARG);
|
Collections.addAll(args, MAGIC_ARG);
|
||||||
Collections.addAll(args, "-XX:+DisableAttachMechanism");
|
Collections.addAll(args, "-XX:+DisableAttachMechanism");
|
||||||
Collections.addAll(args, "-javaagent:".concat(pathLauncher).concat("=pr"));
|
Collections.addAll(args, "-javaagent:".concat(pathLauncher));
|
||||||
Collections.addAll(args, "-cp");
|
Collections.addAll(args, "-cp");
|
||||||
Collections.addAll(args, pathLauncher);
|
Collections.addAll(args, pathLauncher);
|
||||||
Collections.addAll(args, LauncherEngine.class.getName());
|
Collections.addAll(args, LauncherEngine.class.getName());
|
||||||
|
LauncherEngine.modulesManager.callWrapper(processBuilder, args);
|
||||||
EnvHelper.addEnv(processBuilder);
|
EnvHelper.addEnv(processBuilder);
|
||||||
LogHelper.debug("Commandline: " + args);
|
LogHelper.debug("Commandline: " + args);
|
||||||
processBuilder.command(args);
|
processBuilder.command(args);
|
||||||
|
@ -78,4 +107,30 @@ public static void main(String[] arguments) throws IOException, InterruptedExcep
|
||||||
process.waitFor();
|
process.waitFor();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
public static Path tryFindModule(Path path, String moduleName)
|
||||||
|
{
|
||||||
|
Path result = path.resolve(moduleName.concat(".jar"));
|
||||||
|
LogHelper.dev("Try resolve %s", result.toString());
|
||||||
|
if(!IOHelper.isFile(result))
|
||||||
|
result = path.resolve("lib").resolve(moduleName.concat(".jar"));
|
||||||
|
else return result;
|
||||||
|
if(!IOHelper.isFile(result))
|
||||||
|
return null;
|
||||||
|
else return result;
|
||||||
|
}
|
||||||
|
public static boolean tryAddModule(Path[] paths, String moduleName, StringBuilder args)
|
||||||
|
{
|
||||||
|
for(Path path : paths)
|
||||||
|
{
|
||||||
|
if(path == null) continue;
|
||||||
|
Path result = tryFindModule(path, moduleName);
|
||||||
|
if(result != null)
|
||||||
|
{
|
||||||
|
if(args.length() != 0) args.append(File.pathSeparatorChar);
|
||||||
|
args.append(result.toAbsolutePath().toString());
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,29 +1,14 @@
|
||||||
package pro.gravit.launcher;
|
package pro.gravit.launcher;
|
||||||
|
|
||||||
import static org.objectweb.asm.Opcodes.ACONST_NULL;
|
|
||||||
import static org.objectweb.asm.Opcodes.ARETURN;
|
|
||||||
|
|
||||||
import java.io.ByteArrayOutputStream;
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
|
||||||
import java.lang.instrument.Instrumentation;
|
import java.lang.instrument.Instrumentation;
|
||||||
import java.nio.file.Path;
|
import java.nio.file.Path;
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Locale;
|
|
||||||
import java.util.jar.JarFile;
|
import java.util.jar.JarFile;
|
||||||
|
|
||||||
import org.objectweb.asm.ClassReader;
|
|
||||||
import org.objectweb.asm.ClassWriter;
|
|
||||||
import org.objectweb.asm.tree.ClassNode;
|
|
||||||
import org.objectweb.asm.tree.InsnNode;
|
|
||||||
import org.objectweb.asm.tree.MethodNode;
|
|
||||||
|
|
||||||
import cpw.mods.fml.SafeExitJVMLegacy;
|
import cpw.mods.fml.SafeExitJVMLegacy;
|
||||||
import net.minecraftforge.fml.SafeExitJVM;
|
import net.minecraftforge.fml.SafeExitJVM;
|
||||||
import pro.gravit.launcher.utils.NativeJVMHalt;
|
import pro.gravit.launcher.utils.NativeJVMHalt;
|
||||||
import pro.gravit.utils.helper.JVMHelper;
|
|
||||||
import pro.gravit.utils.helper.LogHelper;
|
import pro.gravit.utils.helper.LogHelper;
|
||||||
|
|
||||||
@LauncherAPI
|
@LauncherAPI
|
||||||
|
@ -52,138 +37,16 @@ public static void premain(String agentArgument, Instrumentation instrumentation
|
||||||
SafeExitJVM.class.getName();
|
SafeExitJVM.class.getName();
|
||||||
NativeJVMHalt.class.getName();
|
NativeJVMHalt.class.getName();
|
||||||
NativeJVMHalt.initFunc();
|
NativeJVMHalt.initFunc();
|
||||||
isAgentStarted = true;
|
boolean bad = false;
|
||||||
if (System.getProperty("java.vm.name").toUpperCase(Locale.US).contains("HOTSPOT"))
|
try {
|
||||||
try {
|
for (StackTraceElement e : new Throwable().getStackTrace())
|
||||||
if (JVMHelper.OS_TYPE == JVMHelper.OS.MUSTDIE) {
|
if (Class.forName(e.getClassName()).getClassLoader() != Runtime.class.getClassLoader() && Class.forName(e.getClassName()) != LauncherAgent.class) bad = true;
|
||||||
boolean pb = true;
|
} catch(Throwable e) { bad = true; }
|
||||||
boolean rt = true;
|
if (bad) NativeJVMHalt.haltA(-17);
|
||||||
if (agentArgument != null) {
|
else isAgentStarted = true;
|
||||||
String trimmedArg = agentArgument.trim();
|
|
||||||
if (!trimmedArg.isEmpty()) {
|
|
||||||
if (trimmedArg.contains("p")) pb = false;
|
|
||||||
if (trimmedArg.contains("r")) rt = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
replaceClasses(pb, rt);
|
|
||||||
} else replaceClasses(false, false);
|
|
||||||
} catch (Error e) {
|
|
||||||
NativeJVMHalt.haltA(294);
|
|
||||||
throw e;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static boolean isStarted() {
|
public static boolean isStarted() {
|
||||||
return isAgentStarted;
|
return isAgentStarted;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void replaceClasses(boolean pb, boolean rt) {
|
|
||||||
java.awt.Robot.class.getName();
|
|
||||||
List<java.lang.instrument.ClassDefinition> defs = new ArrayList<>();
|
|
||||||
if (rt) {
|
|
||||||
try {
|
|
||||||
defs.add(new java.lang.instrument.ClassDefinition(java.lang.Runtime.class, transformClass(java.lang.Runtime.class.getName(), getClassFile(java.lang.Runtime.class))));
|
|
||||||
} catch (Exception e) {
|
|
||||||
throw new Error(e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (pb) {
|
|
||||||
try {
|
|
||||||
defs.add(new java.lang.instrument.ClassDefinition(java.lang.ProcessBuilder.class, transformClass(java.lang.ProcessBuilder.class.getName(), getClassFile(java.lang.ProcessBuilder.class))));
|
|
||||||
} catch (Exception e) {
|
|
||||||
throw new Error(e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
try {
|
|
||||||
defs.add(new java.lang.instrument.ClassDefinition(java.awt.Robot.class, transformClass(java.awt.Robot.class.getName(), getClassFile(java.awt.Robot.class))));
|
|
||||||
} catch (Exception e) {
|
|
||||||
throw new Error(e);
|
|
||||||
}
|
|
||||||
try {
|
|
||||||
inst.redefineClasses(defs.toArray(new java.lang.instrument.ClassDefinition[0]));
|
|
||||||
} catch (Exception e) {
|
|
||||||
throw new Error(e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @author https://github.com/Konloch/JVM-Sandbox
|
|
||||||
* Use ASM to modify the byte array
|
|
||||||
*/
|
|
||||||
private static byte[] transformClass(String className, byte[] classBytes) {
|
|
||||||
switch (className) {
|
|
||||||
case "java.lang.Runtime": {
|
|
||||||
ClassReader cr = new ClassReader(classBytes);
|
|
||||||
ClassNode cn = new ClassNode();
|
|
||||||
cr.accept(cn, ClassReader.EXPAND_FRAMES);
|
|
||||||
|
|
||||||
for (Object o : cn.methods.toArray()) {
|
|
||||||
MethodNode m = (MethodNode) o;
|
|
||||||
if (m.name.equals("exec")) {
|
|
||||||
m.instructions.insert(new InsnNode(ARETURN));
|
|
||||||
m.instructions.insert(new InsnNode(ACONST_NULL));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_FRAMES | ClassWriter.COMPUTE_MAXS);
|
|
||||||
cn.accept(cw);
|
|
||||||
return cw.toByteArray();
|
|
||||||
}
|
|
||||||
case "java.lang.ProcessBuilder": {
|
|
||||||
ClassReader cr = new ClassReader(classBytes);
|
|
||||||
ClassNode cn = new ClassNode();
|
|
||||||
cr.accept(cn, ClassReader.EXPAND_FRAMES);
|
|
||||||
|
|
||||||
for (Object o : cn.methods.toArray()) {
|
|
||||||
MethodNode m = (MethodNode) o;
|
|
||||||
if (m.name.equals("start")) {
|
|
||||||
m.instructions.insert(new InsnNode(ARETURN));
|
|
||||||
m.instructions.insert(new InsnNode(ACONST_NULL));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_FRAMES | ClassWriter.COMPUTE_MAXS);
|
|
||||||
cn.accept(cw);
|
|
||||||
return cw.toByteArray();
|
|
||||||
}
|
|
||||||
case "java.awt.Robot": {
|
|
||||||
ClassReader cr = new ClassReader(classBytes);
|
|
||||||
ClassNode cn = new ClassNode();
|
|
||||||
cr.accept(cn, ClassReader.EXPAND_FRAMES);
|
|
||||||
|
|
||||||
for (Object o : cn.methods.toArray()) {
|
|
||||||
MethodNode m = (MethodNode) o;
|
|
||||||
if (m.name.equals("createScreenCapture") || m.name.equals("getPixelColor") ||
|
|
||||||
m.name.equals("keyPress") || m.name.equals("keyRelease") ||
|
|
||||||
m.name.equals("mouseMove") || m.name.equals("mousePress") ||
|
|
||||||
m.name.equals("mouseWheel")) {
|
|
||||||
m.instructions.insert(new InsnNode(ARETURN));
|
|
||||||
m.instructions.insert(new InsnNode(ACONST_NULL));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_FRAMES | ClassWriter.COMPUTE_MAXS);
|
|
||||||
cn.accept(cw);
|
|
||||||
return cw.toByteArray();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return classBytes;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param clazz
|
|
||||||
* @return array, respending this class in bytecode.
|
|
||||||
* @throws IOException
|
|
||||||
* @author https://github.com/Konloch/JVM-Sandbox
|
|
||||||
* Do not remove this method. Do not to cause classloading!
|
|
||||||
* Grab the byte array from the loaded Class object
|
|
||||||
*/
|
|
||||||
private static byte[] getClassFile(Class<?> clazz) throws IOException {
|
|
||||||
try (InputStream is = clazz.getResourceAsStream("/" + clazz.getName().replace('.', '/') + ".class");
|
|
||||||
ByteArrayOutputStream baos = new ByteArrayOutputStream()) {
|
|
||||||
int r;
|
|
||||||
byte[] buffer = new byte[8192];
|
|
||||||
while ((r = is.read(buffer)) >= 0) {
|
|
||||||
baos.write(buffer, 0, r);
|
|
||||||
}
|
|
||||||
return baos.toByteArray();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,19 @@
|
||||||
|
package pro.gravit.launcher.api;
|
||||||
|
|
||||||
|
import pro.gravit.launcher.ClientPermissions;
|
||||||
|
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
public class AuthService {
|
||||||
|
public static String username;
|
||||||
|
public static ClientPermissions permissions = new ClientPermissions();
|
||||||
|
public static UUID uuid;
|
||||||
|
public static boolean isAdmin()
|
||||||
|
{
|
||||||
|
return permissions.canAdmin;
|
||||||
|
}
|
||||||
|
public static boolean isServer()
|
||||||
|
{
|
||||||
|
return permissions.canServer;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,10 @@
|
||||||
|
package pro.gravit.launcher.api;
|
||||||
|
|
||||||
|
import java.lang.instrument.Instrumentation;
|
||||||
|
import java.net.URL;
|
||||||
|
|
||||||
|
public class ClientService {
|
||||||
|
public static Instrumentation instrumentation;
|
||||||
|
public static ClassLoader classLoader;
|
||||||
|
public static URL[] baseURLs;
|
||||||
|
}
|
|
@ -32,7 +32,11 @@
|
||||||
import pro.gravit.launcher.LauncherAgent;
|
import pro.gravit.launcher.LauncherAgent;
|
||||||
import pro.gravit.launcher.LauncherConfig;
|
import pro.gravit.launcher.LauncherConfig;
|
||||||
import pro.gravit.launcher.LauncherEngine;
|
import pro.gravit.launcher.LauncherEngine;
|
||||||
|
import pro.gravit.launcher.api.AuthService;
|
||||||
|
import pro.gravit.launcher.api.ClientService;
|
||||||
|
import pro.gravit.launcher.client.events.ClientLaunchPhase;
|
||||||
import pro.gravit.launcher.client.events.ClientLauncherInitPhase;
|
import pro.gravit.launcher.client.events.ClientLauncherInitPhase;
|
||||||
|
import pro.gravit.launcher.client.events.ClientLauncherPostInitPhase;
|
||||||
import pro.gravit.launcher.guard.LauncherGuardManager;
|
import pro.gravit.launcher.guard.LauncherGuardManager;
|
||||||
import pro.gravit.launcher.gui.JSRuntimeProvider;
|
import pro.gravit.launcher.gui.JSRuntimeProvider;
|
||||||
import pro.gravit.launcher.hasher.FileNameMatcher;
|
import pro.gravit.launcher.hasher.FileNameMatcher;
|
||||||
|
@ -40,7 +44,6 @@
|
||||||
import pro.gravit.launcher.hwid.HWIDProvider;
|
import pro.gravit.launcher.hwid.HWIDProvider;
|
||||||
import pro.gravit.launcher.managers.ClientGsonManager;
|
import pro.gravit.launcher.managers.ClientGsonManager;
|
||||||
import pro.gravit.launcher.managers.ClientHookManager;
|
import pro.gravit.launcher.managers.ClientHookManager;
|
||||||
import pro.gravit.launcher.modules.events.PostInitPhase;
|
|
||||||
import pro.gravit.launcher.modules.events.PreConfigPhase;
|
import pro.gravit.launcher.modules.events.PreConfigPhase;
|
||||||
import pro.gravit.launcher.profiles.ClientProfile;
|
import pro.gravit.launcher.profiles.ClientProfile;
|
||||||
import pro.gravit.launcher.profiles.PlayerProfile;
|
import pro.gravit.launcher.profiles.PlayerProfile;
|
||||||
|
@ -51,6 +54,7 @@
|
||||||
import pro.gravit.launcher.serialize.HOutput;
|
import pro.gravit.launcher.serialize.HOutput;
|
||||||
import pro.gravit.launcher.serialize.stream.StreamObject;
|
import pro.gravit.launcher.serialize.stream.StreamObject;
|
||||||
import pro.gravit.launcher.utils.DirWatcher;
|
import pro.gravit.launcher.utils.DirWatcher;
|
||||||
|
import pro.gravit.launcher.utils.NativeJVMHalt;
|
||||||
import pro.gravit.utils.PublicURLClassLoader;
|
import pro.gravit.utils.PublicURLClassLoader;
|
||||||
import pro.gravit.utils.Version;
|
import pro.gravit.utils.Version;
|
||||||
import pro.gravit.utils.helper.CommonHelper;
|
import pro.gravit.utils.helper.CommonHelper;
|
||||||
|
@ -300,11 +304,11 @@ private static void launch(ClientProfile profile, Params params) throws Throwabl
|
||||||
LogHelper.debug("Args: " + copy);
|
LogHelper.debug("Args: " + copy);
|
||||||
// Resolve main class and method
|
// Resolve main class and method
|
||||||
Class<?> mainClass = classLoader.loadClass(profile.getMainClass());
|
Class<?> mainClass = classLoader.loadClass(profile.getMainClass());
|
||||||
MethodHandle mainMethod = MethodHandles.publicLookup().findStatic(mainClass, "main", MethodType.methodType(void.class, String[].class));
|
MethodHandle mainMethod = MethodHandles.publicLookup().findStatic(mainClass, "main", MethodType.methodType(void.class, String[].class)).asFixedArity();
|
||||||
Launcher.LAUNCHED.set(true);
|
Launcher.LAUNCHED.set(true);
|
||||||
JVMHelper.fullGC();
|
JVMHelper.fullGC();
|
||||||
// Invoke main method
|
// Invoke main method
|
||||||
mainMethod.invoke((Object) args.toArray(new String[0]));
|
mainMethod.invokeWithArguments((Object)args.toArray(new String[0]));
|
||||||
}
|
}
|
||||||
|
|
||||||
private static Process process = null;
|
private static Process process = null;
|
||||||
|
@ -410,9 +414,16 @@ public static Process launch(
|
||||||
builder.redirectErrorStream(true);
|
builder.redirectErrorStream(true);
|
||||||
builder.redirectOutput(Redirect.PIPE);
|
builder.redirectOutput(Redirect.PIPE);
|
||||||
}
|
}
|
||||||
|
List<String> command = builder.command();
|
||||||
// Let's rock!
|
// Let's rock!
|
||||||
ClientHookManager.preStartHook.hook(context, builder);
|
ClientHookManager.preStartHook.hook(context, builder);
|
||||||
process = builder.start();
|
process = builder.start();
|
||||||
|
if (builder.command() != command) {
|
||||||
|
LogHelper.error("Something strange cheating...");
|
||||||
|
System.exit(100);
|
||||||
|
clientStarted = false;
|
||||||
|
return null;
|
||||||
|
}
|
||||||
if(ClientHookManager.postStartHook.hook(context, builder)) return process;
|
if(ClientHookManager.postStartHook.hook(context, builder)) return process;
|
||||||
if (!pipeOutput) {
|
if (!pipeOutput) {
|
||||||
for (int i = 0; i < 50; ++i) {
|
for (int i = 0; i < 50; ++i) {
|
||||||
|
@ -434,6 +445,21 @@ public static Process launch(
|
||||||
clientStarted = false;
|
clientStarted = false;
|
||||||
return process;
|
return process;
|
||||||
}
|
}
|
||||||
|
public static class ClientLaunchContext
|
||||||
|
{
|
||||||
|
public final Params params;
|
||||||
|
public final ClientProfile profile;
|
||||||
|
public final HashedDir assetHDir, clientHDir;
|
||||||
|
public DirWatcher assetWatcher, clientWatcher;
|
||||||
|
|
||||||
|
|
||||||
|
public ClientLaunchContext(Params params, ClientProfile profile, HashedDir assetHDir, HashedDir clientHDir) {
|
||||||
|
this.params = params;
|
||||||
|
this.profile = profile;
|
||||||
|
this.assetHDir = assetHDir;
|
||||||
|
this.clientHDir = clientHDir;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@LauncherAPI
|
@LauncherAPI
|
||||||
public static void main(String... args) throws Throwable {
|
public static void main(String... args) throws Throwable {
|
||||||
|
@ -444,6 +470,10 @@ public static void main(String... args) throws Throwable {
|
||||||
LauncherEngine.modulesManager.initModules(null);
|
LauncherEngine.modulesManager.initModules(null);
|
||||||
initGson(LauncherEngine.modulesManager);
|
initGson(LauncherEngine.modulesManager);
|
||||||
//Launcher.modulesManager.preInitModules();
|
//Launcher.modulesManager.preInitModules();
|
||||||
|
if (!LauncherAgent.isStarted()) {
|
||||||
|
NativeJVMHalt.haltA(100);
|
||||||
|
return;
|
||||||
|
}
|
||||||
LauncherEngine.modulesManager.invokeEvent(new PreConfigPhase());
|
LauncherEngine.modulesManager.invokeEvent(new PreConfigPhase());
|
||||||
JVMHelper.verifySystemProperties(ClientLauncher.class, true);
|
JVMHelper.verifySystemProperties(ClientLauncher.class, true);
|
||||||
EnvHelper.checkDangerousParams();
|
EnvHelper.checkDangerousParams();
|
||||||
|
@ -474,11 +504,12 @@ public static void main(String... args) throws Throwable {
|
||||||
System.exit(-98);
|
System.exit(-98);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
ClientLaunchContext context = new ClientLaunchContext(params, profile, assetHDir, clientHDir);
|
||||||
Launcher.profile = profile;
|
Launcher.profile = profile;
|
||||||
playerProfile = params.pp;
|
playerProfile = params.pp;
|
||||||
Request.setSession(params.session);
|
Request.setSession(params.session);
|
||||||
checkJVMBitsAndVersion();
|
checkJVMBitsAndVersion();
|
||||||
LauncherEngine.modulesManager.invokeEvent(new ClientLauncherInitPhase());
|
LauncherEngine.modulesManager.invokeEvent(new ClientLauncherInitPhase(context));
|
||||||
// Verify ClientLauncher sign and classpath
|
// Verify ClientLauncher sign and classpath
|
||||||
LogHelper.debug("Verifying ClientLauncher sign and classpath");
|
LogHelper.debug("Verifying ClientLauncher sign and classpath");
|
||||||
LinkedList<Path> classPath = resolveClassPathList(params.clientDir, profile.getClassPath());
|
LinkedList<Path> classPath = resolveClassPathList(params.clientDir, profile.getClassPath());
|
||||||
|
@ -518,6 +549,11 @@ public static void main(String... args) throws Throwable {
|
||||||
LogHelper.error(e);
|
LogHelper.error(e);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
AuthService.username = params.pp.username;
|
||||||
|
AuthService.uuid = params.pp.uuid;
|
||||||
|
ClientService.instrumentation = LauncherAgent.inst;
|
||||||
|
ClientService.classLoader = classLoader;
|
||||||
|
ClientService.baseURLs = classpathurls;
|
||||||
LogHelper.debug("Starting JVM and client WatchService");
|
LogHelper.debug("Starting JVM and client WatchService");
|
||||||
FileNameMatcher assetMatcher = profile.getAssetUpdateMatcher();
|
FileNameMatcher assetMatcher = profile.getAssetUpdateMatcher();
|
||||||
FileNameMatcher clientMatcher = profile.getClientUpdateMatcher();
|
FileNameMatcher clientMatcher = profile.getClientUpdateMatcher();
|
||||||
|
@ -529,13 +565,16 @@ public static void main(String... args) throws Throwable {
|
||||||
// if (params.updateOptional.contains(s)) s.mark = true;
|
// if (params.updateOptional.contains(s)) s.mark = true;
|
||||||
// else hdir.removeR(s.file);
|
// else hdir.removeR(s.file);
|
||||||
//}
|
//}
|
||||||
|
context.assetWatcher = assetWatcher;
|
||||||
|
context.clientWatcher = clientWatcher;
|
||||||
Launcher.profile.pushOptionalFile(clientHDir, false);
|
Launcher.profile.pushOptionalFile(clientHDir, false);
|
||||||
LauncherEngine.modulesManager.invokeEvent(new PostInitPhase());
|
LauncherEngine.modulesManager.invokeEvent(new ClientLauncherPostInitPhase(context));
|
||||||
// Start WatchService, and only then client
|
// Start WatchService, and only then client
|
||||||
CommonHelper.newThread("Asset Directory Watcher", true, assetWatcher).start();
|
CommonHelper.newThread("Asset Directory Watcher", true, assetWatcher).start();
|
||||||
CommonHelper.newThread("Client Directory Watcher", true, clientWatcher).start();
|
CommonHelper.newThread("Client Directory Watcher", true, clientWatcher).start();
|
||||||
verifyHDir(params.assetDir, assetHDir, assetMatcher, digest);
|
verifyHDir(params.assetDir, assetHDir, assetMatcher, digest);
|
||||||
verifyHDir(params.clientDir, clientHDir, clientMatcher, digest);
|
verifyHDir(params.clientDir, clientHDir, clientMatcher, digest);
|
||||||
|
LauncherEngine.modulesManager.invokeEvent(new ClientLaunchPhase(context));
|
||||||
launch(profile, params);
|
launch(profile, params);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.nio.file.Path;
|
import java.nio.file.Path;
|
||||||
|
import java.util.Collection;
|
||||||
|
|
||||||
import pro.gravit.launcher.modules.LauncherModule;
|
import pro.gravit.launcher.modules.LauncherModule;
|
||||||
import pro.gravit.launcher.modules.impl.SimpleModuleManager;
|
import pro.gravit.launcher.modules.impl.SimpleModuleManager;
|
||||||
|
@ -25,4 +26,14 @@ public void autoload(Path dir) throws IOException {
|
||||||
public LauncherModule loadModule(Path file) throws IOException {
|
public LauncherModule loadModule(Path file) throws IOException {
|
||||||
throw new UnsupportedOperationException();
|
throw new UnsupportedOperationException();
|
||||||
}
|
}
|
||||||
|
public void callWrapper(ProcessBuilder processBuilder, Collection<String> jvmArgs)
|
||||||
|
{
|
||||||
|
for(LauncherModule module : modules)
|
||||||
|
{
|
||||||
|
if(module instanceof ClientWrapperModule)
|
||||||
|
{
|
||||||
|
((ClientWrapperModule) module).wrapperPhase(processBuilder, jvmArgs);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,7 @@
|
||||||
|
package pro.gravit.launcher.client;
|
||||||
|
|
||||||
|
import java.util.Collection;
|
||||||
|
|
||||||
|
public interface ClientWrapperModule {
|
||||||
|
void wrapperPhase(ProcessBuilder processBuilder, Collection<String> jvmArgs);
|
||||||
|
}
|
|
@ -7,6 +7,7 @@
|
||||||
import java.util.concurrent.atomic.AtomicReference;
|
import java.util.concurrent.atomic.AtomicReference;
|
||||||
|
|
||||||
import pro.gravit.launcher.LauncherAPI;
|
import pro.gravit.launcher.LauncherAPI;
|
||||||
|
import pro.gravit.launcher.api.AuthService;
|
||||||
import pro.gravit.launcher.events.request.AuthRequestEvent;
|
import pro.gravit.launcher.events.request.AuthRequestEvent;
|
||||||
import pro.gravit.launcher.guard.LauncherGuardManager;
|
import pro.gravit.launcher.guard.LauncherGuardManager;
|
||||||
import pro.gravit.launcher.hasher.FileNameMatcher;
|
import pro.gravit.launcher.hasher.FileNameMatcher;
|
||||||
|
@ -100,6 +101,12 @@ public static void setAuthParams(AuthRequestEvent event) {
|
||||||
Request.setSession(event.session);
|
Request.setSession(event.session);
|
||||||
}
|
}
|
||||||
LauncherGuardManager.guard.setProtectToken(event.protectToken);
|
LauncherGuardManager.guard.setProtectToken(event.protectToken);
|
||||||
|
AuthService.permissions = event.permissions;
|
||||||
|
if(event.playerProfile != null)
|
||||||
|
{
|
||||||
|
AuthService.username = event.playerProfile.username;
|
||||||
|
AuthService.uuid = event.playerProfile.uuid;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@FunctionalInterface
|
@FunctionalInterface
|
||||||
|
|
|
@ -76,6 +76,7 @@ public void postDiff(UpdateRequest request, UpdateRequestEvent e, HashedDir.Diff
|
||||||
LogHelper.debug("Copy file %s to %s", ret.toAbsolutePath().toString(), source.toAbsolutePath().toString());
|
LogHelper.debug("Copy file %s to %s", ret.toAbsolutePath().toString(), source.toAbsolutePath().toString());
|
||||||
}
|
}
|
||||||
//Let's go!
|
//Let's go!
|
||||||
|
Files.deleteIfExists(source);
|
||||||
Files.copy(ret, source);
|
Files.copy(ret, source);
|
||||||
try (InputStream input = IOHelper.newInput(ret)) {
|
try (InputStream input = IOHelper.newInput(ret)) {
|
||||||
IOHelper.transfer(input, source);
|
IOHelper.transfer(input, source);
|
||||||
|
|
|
@ -0,0 +1,12 @@
|
||||||
|
package pro.gravit.launcher.client.events;
|
||||||
|
|
||||||
|
import pro.gravit.launcher.client.ClientLauncher;
|
||||||
|
import pro.gravit.launcher.modules.LauncherModule;
|
||||||
|
|
||||||
|
public class ClientLaunchPhase extends LauncherModule.Event {
|
||||||
|
public final ClientLauncher.ClientLaunchContext context;
|
||||||
|
|
||||||
|
public ClientLaunchPhase(ClientLauncher.ClientLaunchContext context) {
|
||||||
|
this.context = context;
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,6 +1,12 @@
|
||||||
package pro.gravit.launcher.client.events;
|
package pro.gravit.launcher.client.events;
|
||||||
|
|
||||||
|
import pro.gravit.launcher.client.ClientLauncher;
|
||||||
import pro.gravit.launcher.modules.events.InitPhase;
|
import pro.gravit.launcher.modules.events.InitPhase;
|
||||||
|
|
||||||
public class ClientLauncherInitPhase extends InitPhase {
|
public class ClientLauncherInitPhase extends InitPhase {
|
||||||
|
public final ClientLauncher.ClientLaunchContext context;
|
||||||
|
|
||||||
|
public ClientLauncherInitPhase(ClientLauncher.ClientLaunchContext context) {
|
||||||
|
this.context = context;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,12 @@
|
||||||
|
package pro.gravit.launcher.client.events;
|
||||||
|
|
||||||
|
import pro.gravit.launcher.client.ClientLauncher;
|
||||||
|
import pro.gravit.launcher.modules.events.PostInitPhase;
|
||||||
|
|
||||||
|
public class ClientLauncherPostInitPhase extends PostInitPhase {
|
||||||
|
public final ClientLauncher.ClientLaunchContext context;
|
||||||
|
|
||||||
|
public ClientLauncherPostInitPhase(ClientLauncher.ClientLaunchContext context) {
|
||||||
|
this.context = context;
|
||||||
|
}
|
||||||
|
}
|
|
@ -23,19 +23,15 @@ public class LauncherGravitGuard implements LauncherGuardInterface {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getName() {
|
public String getName() {
|
||||||
return "wrapper";
|
return "gravitguard";
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Path getJavaBinPath() {
|
public Path getJavaBinPath() {
|
||||||
if (JVMHelper.OS_TYPE == JVMHelper.OS.MUSTDIE) {
|
if (JVMHelper.OS_TYPE == JVMHelper.OS.MUSTDIE) {
|
||||||
String projectName = Launcher.getConfig().projectname;
|
|
||||||
String wrapperUnpackName = JVMHelper.JVM_BITS == 64 ? projectName.concat("64.exe") : projectName.concat("32.exe");
|
|
||||||
return DirBridge.getGuardDir().resolve(wrapperUnpackName);
|
|
||||||
} else if (ClientLauncher.getJavaBinPath() != null) {
|
|
||||||
javaBinPath = ClientLauncher.getJavaBinPath();
|
javaBinPath = ClientLauncher.getJavaBinPath();
|
||||||
String projectName = Launcher.getConfig().projectname;
|
String projectName = Launcher.getConfig().projectname;
|
||||||
String wrapperUnpackName = JVMHelper.JVM_BITS == 64 ? projectName.concat("64.exe") : projectName.concat("32.exe");
|
String wrapperUnpackName = ( javaBinPath == null ? JVMHelper.JVM_BITS : JVMHelper.OS_BITS ) == 64 ? projectName.concat("64.exe") : projectName.concat("32.exe");
|
||||||
return DirBridge.getGuardDir().resolve(wrapperUnpackName);
|
return DirBridge.getGuardDir().resolve(wrapperUnpackName);
|
||||||
} else
|
} else
|
||||||
return IOHelper.resolveJavaBin(Paths.get(System.getProperty("java.home")));
|
return IOHelper.resolveJavaBin(Paths.get(System.getProperty("java.home")));
|
||||||
|
@ -43,22 +39,26 @@ public Path getJavaBinPath() {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getClientJVMBits() {
|
public int getClientJVMBits() {
|
||||||
return JVMHelper.JVM_BITS;
|
//При использовании GravitGuard без своей джавы
|
||||||
|
//Если при запуске лаунчера используется 32 бит джава, а ОС 64бит
|
||||||
|
//То в окне настроек будет отображаться >1.5Гб доступной памяти
|
||||||
|
//Однако при выставлении >1.5Гб JVM x32 работать откажеться
|
||||||
|
return JVMHelper.OS_BITS;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void init(boolean clientInstance) {
|
public void init(boolean clientInstance) {
|
||||||
try {
|
try {
|
||||||
String wrapperName = JVMHelper.JVM_BITS == 64 ? "wrapper64.exe" : "wrapper32.exe";
|
|
||||||
String projectName = Launcher.getConfig().projectname;
|
String projectName = Launcher.getConfig().projectname;
|
||||||
String wrapperUnpackName = JVMHelper.JVM_BITS == 64 ? projectName.concat("64.exe") : projectName.concat("32.exe");
|
UnpackHelper.unpack(Launcher.getResourceURL("wrapper32.exe", "guard"), DirBridge.getGuardDir().resolve(projectName.concat("64.exe")));
|
||||||
String antiInjectName = JVMHelper.JVM_BITS == 64 ? "AntiInject64.dll" : "AntiInject32.dll";
|
UnpackHelper.unpack(Launcher.getResourceURL("AntiInject64.dll", "guard"), DirBridge.getGuardDir().resolve("AntiInject64.dll"));
|
||||||
UnpackHelper.unpack(Launcher.getResourceURL(wrapperName, "guard"), DirBridge.getGuardDir().resolve(wrapperUnpackName));
|
|
||||||
UnpackHelper.unpack(Launcher.getResourceURL(antiInjectName, "guard"), DirBridge.getGuardDir().resolve(antiInjectName));
|
UnpackHelper.unpack(Launcher.getResourceURL("wrapper32.exe", "guard"), DirBridge.getGuardDir().resolve(projectName.concat("32.exe")));
|
||||||
|
UnpackHelper.unpack(Launcher.getResourceURL("AntiInject32.dll", "guard"), DirBridge.getGuardDir().resolve("AntiInject32.dll"));
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
throw new SecurityException(e);
|
throw new SecurityException(e);
|
||||||
}
|
}
|
||||||
if (clientInstance) GravitGuardBridge.callGuard();
|
if (clientInstance && JVMHelper.OS_TYPE == JVMHelper.OS.MUSTDIE) GravitGuardBridge.callGuard();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
package pro.gravit.launcher.managers;
|
package pro.gravit.launcher.managers;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.lang.reflect.Type;
|
|
||||||
import java.nio.file.FileVisitResult;
|
import java.nio.file.FileVisitResult;
|
||||||
import java.nio.file.Files;
|
import java.nio.file.Files;
|
||||||
import java.nio.file.Path;
|
import java.nio.file.Path;
|
||||||
|
@ -102,9 +101,4 @@ public void loadHDirStore() throws IOException {
|
||||||
public void saveHDirStore() throws IOException {
|
public void saveHDirStore() throws IOException {
|
||||||
saveHDirStore(DirBridge.dirProjectStore);
|
saveHDirStore(DirBridge.dirProjectStore);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setType(Type type) {
|
|
||||||
super.setType(type);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,29 +1,13 @@
|
||||||
package pro.gravit.launcher.config;
|
package pro.gravit.launcher.config;
|
||||||
|
|
||||||
import java.io.BufferedReader;
|
|
||||||
import java.io.BufferedWriter;
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.lang.reflect.Type;
|
import java.lang.reflect.Type;
|
||||||
import java.nio.file.Path;
|
import java.nio.file.Path;
|
||||||
|
|
||||||
import pro.gravit.launcher.Launcher;
|
|
||||||
import pro.gravit.launcher.LauncherAPI;
|
import pro.gravit.launcher.LauncherAPI;
|
||||||
import pro.gravit.utils.helper.IOHelper;
|
|
||||||
import pro.gravit.utils.helper.LogHelper;
|
|
||||||
|
|
||||||
public abstract class JsonConfigurable<T> {
|
public abstract class JsonConfigurable<T> implements JsonConfigurableInterface<T> {
|
||||||
private Type type;
|
private transient final Type type;
|
||||||
protected Path configPath;
|
protected transient final Path configPath;
|
||||||
|
|
||||||
@LauncherAPI
|
|
||||||
public void saveConfig() throws IOException {
|
|
||||||
saveConfig(configPath);
|
|
||||||
}
|
|
||||||
|
|
||||||
@LauncherAPI
|
|
||||||
public void loadConfig() throws IOException {
|
|
||||||
loadConfig(configPath);
|
|
||||||
}
|
|
||||||
|
|
||||||
@LauncherAPI
|
@LauncherAPI
|
||||||
public JsonConfigurable(Type type, Path configPath) {
|
public JsonConfigurable(Type type, Path configPath) {
|
||||||
|
@ -31,55 +15,14 @@ public JsonConfigurable(Type type, Path configPath) {
|
||||||
this.configPath = configPath;
|
this.configPath = configPath;
|
||||||
}
|
}
|
||||||
|
|
||||||
@LauncherAPI
|
@Override
|
||||||
public void saveConfig(Path configPath) throws IOException {
|
public Path getPath() {
|
||||||
try (BufferedWriter writer = IOHelper.newWriter(configPath)) {
|
return configPath;
|
||||||
Launcher.gsonManager.configGson.toJson(getConfig(), type, writer);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@LauncherAPI
|
@Override
|
||||||
public void loadConfig(Path configPath) throws IOException {
|
public Type getType() {
|
||||||
if (generateConfigIfNotExists(configPath)) return;
|
return type;
|
||||||
try (BufferedReader reader = IOHelper.newReader(configPath)) {
|
|
||||||
setConfig(Launcher.gsonManager.configGson.fromJson(reader, type));
|
|
||||||
} catch (Exception e)
|
|
||||||
{
|
|
||||||
LogHelper.error(e);
|
|
||||||
resetConfig(configPath);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@LauncherAPI
|
|
||||||
public void resetConfig() throws IOException {
|
|
||||||
setConfig(getDefaultConfig());
|
|
||||||
saveConfig();
|
|
||||||
}
|
|
||||||
|
|
||||||
@LauncherAPI
|
|
||||||
public void resetConfig(Path newPath) throws IOException {
|
|
||||||
setConfig(getDefaultConfig());
|
|
||||||
saveConfig(newPath);
|
|
||||||
}
|
|
||||||
|
|
||||||
@LauncherAPI
|
|
||||||
public boolean generateConfigIfNotExists(Path path) throws IOException {
|
|
||||||
if (IOHelper.isFile(path))
|
|
||||||
return false;
|
|
||||||
resetConfig(path);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
@LauncherAPI
|
|
||||||
public boolean generateConfigIfNotExists() throws IOException {
|
|
||||||
if (IOHelper.isFile(configPath))
|
|
||||||
return false;
|
|
||||||
resetConfig();
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected void setType(Type type) {
|
|
||||||
this.type = type;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@LauncherAPI
|
@LauncherAPI
|
||||||
|
|
|
@ -0,0 +1,84 @@
|
||||||
|
package pro.gravit.launcher.config;
|
||||||
|
|
||||||
|
import com.google.gson.Gson;
|
||||||
|
import pro.gravit.launcher.Launcher;
|
||||||
|
import pro.gravit.launcher.LauncherAPI;
|
||||||
|
import pro.gravit.utils.helper.IOHelper;
|
||||||
|
import pro.gravit.utils.helper.LogHelper;
|
||||||
|
|
||||||
|
import java.io.BufferedReader;
|
||||||
|
import java.io.BufferedWriter;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.lang.reflect.Type;
|
||||||
|
import java.nio.file.Path;
|
||||||
|
|
||||||
|
public interface JsonConfigurableInterface<T> {
|
||||||
|
@LauncherAPI
|
||||||
|
default void saveConfig() throws IOException {
|
||||||
|
saveConfig(getPath());
|
||||||
|
}
|
||||||
|
@LauncherAPI
|
||||||
|
default void loadConfig() throws IOException {
|
||||||
|
loadConfig(getPath());
|
||||||
|
}
|
||||||
|
@LauncherAPI
|
||||||
|
default void saveConfig(Gson gson, Path configPath) throws IOException {
|
||||||
|
try (BufferedWriter writer = IOHelper.newWriter(configPath)) {
|
||||||
|
gson.toJson(getConfig(), getType(), writer);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@LauncherAPI
|
||||||
|
default void loadConfig(Gson gson, Path configPath) throws IOException {
|
||||||
|
if (generateConfigIfNotExists(configPath)) return;
|
||||||
|
try (BufferedReader reader = IOHelper.newReader(configPath)) {
|
||||||
|
setConfig(gson.fromJson(reader, getType()));
|
||||||
|
} catch (Exception e)
|
||||||
|
{
|
||||||
|
LogHelper.error(e);
|
||||||
|
resetConfig(configPath);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@LauncherAPI
|
||||||
|
default void saveConfig(Path configPath) throws IOException {
|
||||||
|
saveConfig(Launcher.gsonManager.configGson, configPath);
|
||||||
|
}
|
||||||
|
@LauncherAPI
|
||||||
|
default void loadConfig(Path configPath) throws IOException {
|
||||||
|
loadConfig(Launcher.gsonManager.configGson, configPath);
|
||||||
|
}
|
||||||
|
@LauncherAPI
|
||||||
|
default void resetConfig() throws IOException {
|
||||||
|
setConfig(getDefaultConfig());
|
||||||
|
saveConfig();
|
||||||
|
}
|
||||||
|
@LauncherAPI
|
||||||
|
default void resetConfig(Path newPath) throws IOException {
|
||||||
|
setConfig(getDefaultConfig());
|
||||||
|
saveConfig(newPath);
|
||||||
|
}
|
||||||
|
@LauncherAPI
|
||||||
|
default boolean generateConfigIfNotExists(Path path) throws IOException {
|
||||||
|
if (IOHelper.isFile(path))
|
||||||
|
return false;
|
||||||
|
resetConfig(path);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
@LauncherAPI
|
||||||
|
default boolean generateConfigIfNotExists() throws IOException {
|
||||||
|
if (IOHelper.isFile(getPath()))
|
||||||
|
return false;
|
||||||
|
resetConfig();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
@LauncherAPI
|
||||||
|
T getConfig();
|
||||||
|
@LauncherAPI
|
||||||
|
T getDefaultConfig();
|
||||||
|
@LauncherAPI
|
||||||
|
void setConfig(T config);
|
||||||
|
@LauncherAPI
|
||||||
|
Path getPath();
|
||||||
|
|
||||||
|
Type getType();
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,39 @@
|
||||||
|
package pro.gravit.launcher.config;
|
||||||
|
|
||||||
|
import java.lang.reflect.Type;
|
||||||
|
import java.nio.file.Path;
|
||||||
|
|
||||||
|
public abstract class SimpleConfig<T> implements JsonConfigurableInterface<T> {
|
||||||
|
private transient final Class<T> type;
|
||||||
|
protected transient final Path configPath;
|
||||||
|
|
||||||
|
protected SimpleConfig(Class<T> type, Path configPath) {
|
||||||
|
this.type = type;
|
||||||
|
this.configPath = configPath;
|
||||||
|
}
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
@Override
|
||||||
|
public T getConfig() {
|
||||||
|
return (T) this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public T getDefaultConfig() {
|
||||||
|
try {
|
||||||
|
return type.newInstance();
|
||||||
|
} catch (InstantiationException | IllegalAccessException e) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Path getPath() {
|
||||||
|
return configPath;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Type getType() {
|
||||||
|
return type;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,32 @@
|
||||||
|
package pro.gravit.launcher.config;
|
||||||
|
|
||||||
|
import java.nio.file.Path;
|
||||||
|
|
||||||
|
public class SimpleConfigurable<T> extends JsonConfigurable<T> {
|
||||||
|
public T config;
|
||||||
|
private final Class<T> tClass;
|
||||||
|
|
||||||
|
public SimpleConfigurable(Class<T> type, Path configPath) {
|
||||||
|
super(type, configPath);
|
||||||
|
tClass = type;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public T getConfig() {
|
||||||
|
return config;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public T getDefaultConfig() {
|
||||||
|
try {
|
||||||
|
return tClass.newInstance();
|
||||||
|
} catch (InstantiationException | IllegalAccessException e) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setConfig(T config) {
|
||||||
|
this.config = config;
|
||||||
|
}
|
||||||
|
}
|
|
@ -4,6 +4,7 @@
|
||||||
import java.nio.file.Files;
|
import java.nio.file.Files;
|
||||||
import java.nio.file.Path;
|
import java.nio.file.Path;
|
||||||
|
|
||||||
|
import pro.gravit.launcher.config.SimpleConfigurable;
|
||||||
import pro.gravit.launcher.modules.ModulesConfigManager;
|
import pro.gravit.launcher.modules.ModulesConfigManager;
|
||||||
import pro.gravit.utils.helper.IOHelper;
|
import pro.gravit.utils.helper.IOHelper;
|
||||||
import pro.gravit.utils.helper.LogHelper;
|
import pro.gravit.utils.helper.LogHelper;
|
||||||
|
@ -34,4 +35,9 @@ public Path getModuleConfigDir(String moduleName) {
|
||||||
}
|
}
|
||||||
return configDir.resolve(moduleName);
|
return configDir.resolve(moduleName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public <T> SimpleConfigurable<T> getConfigurable(Class<T> tClass, Path configPath) {
|
||||||
|
return new SimpleConfigurable<>(tClass, configPath);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,7 @@
|
||||||
package pro.gravit.launcher.modules;
|
package pro.gravit.launcher.modules;
|
||||||
|
|
||||||
|
import pro.gravit.launcher.config.SimpleConfigurable;
|
||||||
|
|
||||||
import java.nio.file.Path;
|
import java.nio.file.Path;
|
||||||
|
|
||||||
public interface ModulesConfigManager {
|
public interface ModulesConfigManager {
|
||||||
|
@ -8,4 +10,16 @@ public interface ModulesConfigManager {
|
||||||
Path getModuleConfig(String moduleName, String configName);
|
Path getModuleConfig(String moduleName, String configName);
|
||||||
|
|
||||||
Path getModuleConfigDir(String moduleName);
|
Path getModuleConfigDir(String moduleName);
|
||||||
|
|
||||||
|
<T> SimpleConfigurable<T> getConfigurable(Class<T> tClass, Path configPath);
|
||||||
|
|
||||||
|
default <T> SimpleConfigurable<T> getConfigurable(Class<T> tClass, String moduleName)
|
||||||
|
{
|
||||||
|
return getConfigurable(tClass, getModuleConfig(moduleName));
|
||||||
|
}
|
||||||
|
|
||||||
|
default <T> SimpleConfigurable<T> getConfigurable(Class<T> tClass, String moduleName, String configName)
|
||||||
|
{
|
||||||
|
return getConfigurable(tClass, getModuleConfig(moduleName, configName));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,8 @@
|
||||||
package pro.gravit.launcher.request.update;
|
package pro.gravit.launcher.request.update;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.nio.file.Files;
|
||||||
import java.nio.file.Path;
|
import java.nio.file.Path;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
@ -25,6 +27,9 @@ public final class LauncherRequest extends Request<LauncherRequestEvent> impleme
|
||||||
public int launcher_type = EXE_BINARY ? 2 : 1;
|
public int launcher_type = EXE_BINARY ? 2 : 1;
|
||||||
@LauncherAPI
|
@LauncherAPI
|
||||||
public static final Path BINARY_PATH = IOHelper.getCodeSource(Launcher.class);
|
public static final Path BINARY_PATH = IOHelper.getCodeSource(Launcher.class);
|
||||||
|
|
||||||
|
@LauncherAPI
|
||||||
|
public static final Path C_BINARY_PATH = BINARY_PATH.getParent().resolve(IOHelper.getFileName(BINARY_PATH) + ".tmp");
|
||||||
|
|
||||||
@LauncherAPI
|
@LauncherAPI
|
||||||
public static final boolean EXE_BINARY = IOHelper.hasExtension(BINARY_PATH, "exe");
|
public static final boolean EXE_BINARY = IOHelper.hasExtension(BINARY_PATH, "exe");
|
||||||
|
@ -52,7 +57,12 @@ public static void update(LauncherRequestEvent result) throws IOException {
|
||||||
}*/
|
}*/
|
||||||
try {
|
try {
|
||||||
ListDownloader downloader = new ListDownloader();
|
ListDownloader downloader = new ListDownloader();
|
||||||
downloader.downloadOne(result.url, BINARY_PATH);
|
Files.deleteIfExists(C_BINARY_PATH);
|
||||||
|
downloader.downloadOne(result.url, C_BINARY_PATH);
|
||||||
|
try (InputStream in = IOHelper.newInput(C_BINARY_PATH)) {
|
||||||
|
IOHelper.transfer(in, BINARY_PATH);
|
||||||
|
}
|
||||||
|
Files.deleteIfExists(C_BINARY_PATH);
|
||||||
} catch (Throwable e) {
|
} catch (Throwable e) {
|
||||||
LogHelper.error(e);
|
LogHelper.error(e);
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
import java.util.EnumSet;
|
import java.util.EnumSet;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
public final class MinecraftProfileTexture {
|
public class MinecraftProfileTexture {
|
||||||
public enum Type {
|
public enum Type {
|
||||||
SKIN,
|
SKIN,
|
||||||
CAPE,
|
CAPE,
|
||||||
|
|
|
@ -14,7 +14,7 @@
|
||||||
|
|
||||||
// Used to bypass Launcher's class name obfuscation and access API
|
// Used to bypass Launcher's class name obfuscation and access API
|
||||||
@LauncherAPI
|
@LauncherAPI
|
||||||
public final class CompatBridge {
|
public class CompatBridge {
|
||||||
public static final int PROFILES_MAX_BATCH_SIZE = SerializeLimits.MAX_BATCH_SIZE;
|
public static final int PROFILES_MAX_BATCH_SIZE = SerializeLimits.MAX_BATCH_SIZE;
|
||||||
|
|
||||||
public static CompatProfile checkServer(String username, String serverID) throws Exception {
|
public static CompatProfile checkServer(String username, String serverID) throws Exception {
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
import pro.gravit.utils.helper.SecurityHelper;
|
import pro.gravit.utils.helper.SecurityHelper;
|
||||||
|
|
||||||
@LauncherAPI
|
@LauncherAPI
|
||||||
public final class CompatProfile {
|
public class CompatProfile {
|
||||||
public static final String SKIN_URL_PROPERTY = Launcher.SKIN_URL_PROPERTY;
|
public static final String SKIN_URL_PROPERTY = Launcher.SKIN_URL_PROPERTY;
|
||||||
public static final String SKIN_DIGEST_PROPERTY = Launcher.SKIN_DIGEST_PROPERTY;
|
public static final String SKIN_DIGEST_PROPERTY = Launcher.SKIN_DIGEST_PROPERTY;
|
||||||
public static final String CLOAK_URL_PROPERTY = Launcher.CLOAK_URL_PROPERTY;
|
public static final String CLOAK_URL_PROPERTY = Launcher.CLOAK_URL_PROPERTY;
|
||||||
|
|
|
@ -9,7 +9,7 @@
|
||||||
|
|
||||||
// Used by 1.6.4 and below versions
|
// Used by 1.6.4 and below versions
|
||||||
@LauncherAPI
|
@LauncherAPI
|
||||||
public final class LegacyBridge {
|
public class LegacyBridge {
|
||||||
public static boolean checkServer(String username, String serverID) throws Exception {
|
public static boolean checkServer(String username, String serverID) throws Exception {
|
||||||
LogHelper.debug("LegacyBridge.checkServer, Username: '%s', Server ID: %s", username, serverID);
|
LogHelper.debug("LegacyBridge.checkServer, Username: '%s', Server ID: %s", username, serverID);
|
||||||
return new CheckServerRequest(username, serverID).request() != null;
|
return new CheckServerRequest(username, serverID).request() != null;
|
||||||
|
|
|
@ -10,7 +10,7 @@
|
||||||
|
|
||||||
import pro.gravit.utils.helper.LogHelper;
|
import pro.gravit.utils.helper.LogHelper;
|
||||||
|
|
||||||
public final class YggdrasilAuthenticationService implements AuthenticationService {
|
public class YggdrasilAuthenticationService implements AuthenticationService {
|
||||||
public YggdrasilAuthenticationService(Proxy proxy, String clientToken) {
|
public YggdrasilAuthenticationService(Proxy proxy, String clientToken) {
|
||||||
LogHelper.debug("Patched AuthenticationService created: '%s'", clientToken);
|
LogHelper.debug("Patched AuthenticationService created: '%s'", clientToken);
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,7 +14,7 @@
|
||||||
import pro.gravit.utils.helper.LogHelper;
|
import pro.gravit.utils.helper.LogHelper;
|
||||||
import pro.gravit.utils.helper.VerifyHelper;
|
import pro.gravit.utils.helper.VerifyHelper;
|
||||||
|
|
||||||
public final class YggdrasilGameProfileRepository implements GameProfileRepository {
|
public class YggdrasilGameProfileRepository implements GameProfileRepository {
|
||||||
private static final long BUSY_WAIT_MS = VerifyHelper.verifyLong(
|
private static final long BUSY_WAIT_MS = VerifyHelper.verifyLong(
|
||||||
Long.parseLong(System.getProperty("launcher.com.mojang.authlib.busyWait", Long.toString(100L))),
|
Long.parseLong(System.getProperty("launcher.com.mojang.authlib.busyWait", Long.toString(100L))),
|
||||||
VerifyHelper.L_NOT_NEGATIVE, "launcher.com.mojang.authlib.busyWait can't be < 0");
|
VerifyHelper.L_NOT_NEGATIVE, "launcher.com.mojang.authlib.busyWait can't be < 0");
|
||||||
|
|
|
@ -28,7 +28,7 @@
|
||||||
import pro.gravit.utils.helper.LogHelper;
|
import pro.gravit.utils.helper.LogHelper;
|
||||||
import pro.gravit.utils.helper.SecurityHelper;
|
import pro.gravit.utils.helper.SecurityHelper;
|
||||||
|
|
||||||
public final class YggdrasilMinecraftSessionService extends BaseMinecraftSessionService {
|
public class YggdrasilMinecraftSessionService extends BaseMinecraftSessionService {
|
||||||
public static final JsonParser JSON_PARSER = new JsonParser();
|
public static final JsonParser JSON_PARSER = new JsonParser();
|
||||||
public static final boolean NO_TEXTURES = Boolean.parseBoolean("launcher.com.mojang.authlib.noTextures");
|
public static final boolean NO_TEXTURES = Boolean.parseBoolean("launcher.com.mojang.authlib.noTextures");
|
||||||
|
|
||||||
|
|
|
@ -22,7 +22,7 @@ public final class Version {
|
||||||
public final Type release;
|
public final Type release;
|
||||||
public static final int MAJOR = 5;
|
public static final int MAJOR = 5;
|
||||||
public static final int MINOR = 0;
|
public static final int MINOR = 0;
|
||||||
public static final int PATCH = 8;
|
public static final int PATCH = 9;
|
||||||
public static final int BUILD = 1;
|
public static final int BUILD = 1;
|
||||||
public static final Version.Type RELEASE = Type.STABLE;
|
public static final Version.Type RELEASE = Type.STABLE;
|
||||||
|
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
id 'signing'
|
id 'signing'
|
||||||
}
|
}
|
||||||
group = 'pro.gravit.launcher'
|
group = 'pro.gravit.launcher'
|
||||||
version = '5.0.8'
|
version = '5.0.9'
|
||||||
|
|
||||||
configure(subprojects.findAll { it.name != 'modules' }) {
|
configure(subprojects.findAll { it.name != 'modules' }) {
|
||||||
apply plugin: 'idea'
|
apply plugin: 'idea'
|
||||||
|
|
2
modules
2
modules
|
@ -1 +1 @@
|
||||||
Subproject commit 88bd03c38a2681e997a305e376eb63e446c99a7f
|
Subproject commit 8d7a95d0707539ab18fba83bef6ef9f09b70c0ad
|
Loading…
Reference in a new issue