2019-06-02 05:03:08 +03:00
|
|
|
package pro.gravit.launcher;
|
2018-09-17 10:07:32 +03:00
|
|
|
|
2019-10-19 19:46:04 +03:00
|
|
|
import pro.gravit.launcher.managers.GsonManager;
|
|
|
|
import pro.gravit.launcher.profiles.ClientProfile;
|
|
|
|
import pro.gravit.launcher.serialize.HInput;
|
|
|
|
import pro.gravit.utils.helper.IOHelper;
|
|
|
|
import pro.gravit.utils.helper.LogHelper;
|
|
|
|
import pro.gravit.utils.helper.SecurityHelper;
|
|
|
|
|
2018-09-17 10:07:32 +03:00
|
|
|
import java.io.IOException;
|
|
|
|
import java.net.URL;
|
|
|
|
import java.nio.file.NoSuchFileException;
|
|
|
|
import java.security.spec.InvalidKeySpecException;
|
|
|
|
import java.util.Arrays;
|
|
|
|
import java.util.UUID;
|
2018-09-25 17:06:13 +03:00
|
|
|
import java.util.concurrent.atomic.AtomicBoolean;
|
2018-09-17 10:07:32 +03:00
|
|
|
import java.util.concurrent.atomic.AtomicReference;
|
|
|
|
import java.util.regex.Pattern;
|
|
|
|
|
|
|
|
public final class Launcher {
|
2018-09-22 17:22:39 +03:00
|
|
|
|
2018-09-25 17:06:13 +03:00
|
|
|
// Authlib constants
|
2019-12-08 22:21:05 +03:00
|
|
|
|
2018-09-25 17:06:13 +03:00
|
|
|
public static final String SKIN_URL_PROPERTY = "skinURL";
|
2019-12-08 22:21:05 +03:00
|
|
|
|
2018-09-25 17:06:13 +03:00
|
|
|
public static final String SKIN_DIGEST_PROPERTY = "skinDigest";
|
2019-12-08 22:21:05 +03:00
|
|
|
|
2021-07-27 00:25:04 +03:00
|
|
|
public static final String SKIN_METADATA_PROPERTY = "skinMetadata";
|
|
|
|
|
2018-09-25 17:06:13 +03:00
|
|
|
public static final String CLOAK_URL_PROPERTY = "cloakURL";
|
2019-12-08 22:21:05 +03:00
|
|
|
|
2018-09-25 17:06:13 +03:00
|
|
|
public static final String CLOAK_DIGEST_PROPERTY = "cloakDigest";
|
2021-07-27 00:25:04 +03:00
|
|
|
|
|
|
|
public static final String CLOAK_METADATA_PROPERTY = "cloakMetadata";
|
|
|
|
|
|
|
|
|
2018-09-25 17:06:13 +03:00
|
|
|
// Used to determine from clientside is launched from launcher
|
|
|
|
public static final AtomicBoolean LAUNCHED = new AtomicBoolean(false);
|
2018-09-17 10:07:32 +03:00
|
|
|
public static final int PROTOCOL_MAGIC_LEGACY = 0x724724_00 + 24;
|
|
|
|
public static final int PROTOCOL_MAGIC = 0xA205B064; // e = 2.718281828
|
|
|
|
public static final String RUNTIME_DIR = "runtime";
|
2019-12-08 22:21:05 +03:00
|
|
|
|
2020-04-05 10:27:04 +03:00
|
|
|
// Constants
|
2018-09-17 10:07:32 +03:00
|
|
|
public static final String CONFIG_FILE = "config.bin";
|
2020-04-05 10:27:04 +03:00
|
|
|
private static final AtomicReference<LauncherConfig> CONFIG = new AtomicReference<>();
|
2018-09-17 10:07:32 +03:00
|
|
|
private static final Pattern UUID_PATTERN = Pattern.compile("-", Pattern.LITERAL);
|
2020-04-05 10:27:04 +03:00
|
|
|
public static ClientProfile profile;
|
2019-04-20 01:03:06 +03:00
|
|
|
public static GsonManager gsonManager;
|
2018-09-17 10:07:32 +03:00
|
|
|
|
2019-12-08 22:21:05 +03:00
|
|
|
|
2018-09-17 10:07:32 +03:00
|
|
|
public static LauncherConfig getConfig() {
|
|
|
|
LauncherConfig config = CONFIG.get();
|
|
|
|
if (config == null) {
|
|
|
|
try (HInput input = new HInput(IOHelper.newInput(IOHelper.getResourceURL(CONFIG_FILE)))) {
|
|
|
|
config = new LauncherConfig(input);
|
|
|
|
} catch (IOException | InvalidKeySpecException e) {
|
|
|
|
throw new SecurityException(e);
|
|
|
|
}
|
|
|
|
CONFIG.set(config);
|
|
|
|
}
|
|
|
|
return config;
|
|
|
|
}
|
2018-11-08 15:30:16 +03:00
|
|
|
|
2019-12-08 22:21:05 +03:00
|
|
|
|
2018-11-08 15:30:16 +03:00
|
|
|
public static void setConfig(LauncherConfig cfg) {
|
2018-09-26 11:54:14 +03:00
|
|
|
CONFIG.set(cfg);
|
|
|
|
}
|
2018-09-17 10:07:32 +03:00
|
|
|
|
2019-12-08 22:21:05 +03:00
|
|
|
|
2018-09-17 10:07:32 +03:00
|
|
|
public static URL getResourceURL(String name) throws IOException {
|
2018-10-26 20:23:27 +03:00
|
|
|
LauncherConfig config = getConfig();
|
|
|
|
byte[] validDigest = config.runtime.get(name);
|
|
|
|
if (validDigest == null)
|
|
|
|
throw new NoSuchFileException(name);
|
2018-09-17 10:07:32 +03:00
|
|
|
|
|
|
|
// Resolve URL and verify digest
|
|
|
|
URL url = IOHelper.getResourceURL(RUNTIME_DIR + '/' + name);
|
2018-10-26 20:23:27 +03:00
|
|
|
if (!Arrays.equals(validDigest, SecurityHelper.digest(SecurityHelper.DigestAlgorithm.MD5, url)))
|
|
|
|
throw new NoSuchFileException(name); // Digest mismatch
|
2018-09-17 10:07:32 +03:00
|
|
|
|
|
|
|
// Return verified URL
|
|
|
|
return url;
|
|
|
|
}
|
|
|
|
|
2018-11-08 15:30:16 +03:00
|
|
|
public static URL getResourceURL(String name, String prefix) throws IOException {
|
2018-11-01 16:03:14 +03:00
|
|
|
LauncherConfig config = getConfig();
|
|
|
|
byte[] validDigest = config.runtime.get(name);
|
|
|
|
if (validDigest == null)
|
|
|
|
throw new NoSuchFileException(name);
|
|
|
|
|
|
|
|
// Resolve URL and verify digest
|
|
|
|
URL url = IOHelper.getResourceURL(prefix + '/' + name);
|
|
|
|
if (!Arrays.equals(validDigest, SecurityHelper.digest(SecurityHelper.DigestAlgorithm.MD5, url)))
|
|
|
|
throw new NoSuchFileException(name); // Digest mismatch
|
|
|
|
|
|
|
|
// Return verified URL
|
|
|
|
return url;
|
|
|
|
}
|
|
|
|
|
2019-12-08 22:21:05 +03:00
|
|
|
|
2018-09-17 10:07:32 +03:00
|
|
|
public static String toHash(UUID uuid) {
|
|
|
|
return UUID_PATTERN.matcher(uuid.toString()).replaceAll("");
|
|
|
|
}
|
|
|
|
|
2019-04-03 16:27:40 +03:00
|
|
|
public static void applyLauncherEnv(LauncherConfig.LauncherEnvironment env) {
|
|
|
|
switch (env) {
|
2019-01-15 06:48:20 +03:00
|
|
|
case DEV:
|
|
|
|
LogHelper.setDevEnabled(true);
|
|
|
|
LogHelper.setStacktraceEnabled(true);
|
|
|
|
LogHelper.setDebugEnabled(true);
|
|
|
|
break;
|
|
|
|
case DEBUG:
|
|
|
|
LogHelper.setDebugEnabled(true);
|
|
|
|
LogHelper.setStacktraceEnabled(true);
|
|
|
|
break;
|
|
|
|
case STD:
|
|
|
|
break;
|
|
|
|
case PROD:
|
|
|
|
LogHelper.setStacktraceEnabled(false);
|
|
|
|
LogHelper.setDebugEnabled(false);
|
|
|
|
LogHelper.setDevEnabled(false);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
2018-09-17 10:07:32 +03:00
|
|
|
}
|