mirror of
https://github.com/GravitLauncher/Launcher
synced 2024-12-22 16:41:46 +03:00
Authlib
This commit is contained in:
parent
b71df6ca01
commit
e44264d554
18 changed files with 60 additions and 72 deletions
|
@ -44,7 +44,7 @@ public static void registerProviders() {
|
|||
registerProvider("reject", RejectAuthProvider::new);
|
||||
|
||||
// Auth providers that doesn't do nothing :D
|
||||
registerProvider("mojang", MojangAuthProvider::new);
|
||||
registerProvider("com.mojang", MojangAuthProvider::new);
|
||||
registerProvider("mysql", MySQLAuthProvider::new);
|
||||
registerProvider("file", FileAuthProvider::new);
|
||||
registerProvider("request", RequestAuthProvider::new);
|
||||
|
|
|
@ -26,7 +26,7 @@ public final class MojangAuthProvider extends AuthProvider {
|
|||
|
||||
static {
|
||||
try {
|
||||
URL = new URL("https://authserver.mojang.com/authenticate");
|
||||
URL = new URL("https://authserver.com.mojang.com/authenticate");
|
||||
} catch (MalformedURLException e) {
|
||||
throw new InternalError(e);
|
||||
}
|
||||
|
@ -67,7 +67,7 @@ public AuthProviderResult auth(String login, String password, String ip) throws
|
|||
// Verify there's no error
|
||||
JsonObject response = makeJSONRequest(URL, request);
|
||||
if (response == null)
|
||||
authError("Empty mojang response");
|
||||
authError("Empty com.mojang response");
|
||||
JsonValue errorMessage = response.get("errorMessage");
|
||||
if (errorMessage != null)
|
||||
authError(errorMessage.asString());
|
||||
|
|
|
@ -20,9 +20,9 @@
|
|||
-keepattributes Signature
|
||||
-adaptresourcefilecontents META-INF/MANIFEST.MF
|
||||
|
||||
-keeppackagenames com.eclipsesource.json.**,com.mojang.**,org.apache.**
|
||||
-keeppackagenames com.eclipsesource.json.**,com.com.mojang.**,org.apache.**
|
||||
|
||||
-keep class com.eclipsesource.json.**,com.mojang.** {
|
||||
-keep class com.eclipsesource.json.**,com.com.mojang.** {
|
||||
<fields>;
|
||||
<methods>;
|
||||
}
|
||||
|
|
|
@ -23,8 +23,6 @@
|
|||
dependencies {
|
||||
compile project(':LauncherAPI')
|
||||
compile 'org.javassist:javassist:3.23.1-GA'
|
||||
compileOnly 'com.google.code.gson:gson:2.8.5'
|
||||
compileOnly 'com.google.guava:guava:26.0-jre'
|
||||
}
|
||||
|
||||
task genRuntimeJS(type: Zip) {
|
||||
|
|
|
@ -24,9 +24,9 @@
|
|||
-renamesourcefileattribute SourceFile
|
||||
-adaptresourcefilecontents META-INF/MANIFEST.MF
|
||||
|
||||
-keeppackagenames com.eclipsesource.json.**,com.mojang.**
|
||||
-keeppackagenames com.eclipsesource.json.**,com.com.mojang.**
|
||||
|
||||
-keep class com.eclipsesource.json.**,com.mojang.** {
|
||||
-keep class com.eclipsesource.json.**,com.com.mojang.** {
|
||||
<fields>;
|
||||
<methods>;
|
||||
}
|
||||
|
|
|
@ -16,7 +16,6 @@
|
|||
import java.nio.file.attribute.PosixFilePermission;
|
||||
import java.security.interfaces.RSAPublicKey;
|
||||
import java.util.*;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
|
||||
import javax.swing.JOptionPane;
|
||||
|
||||
|
@ -168,20 +167,6 @@ public void write(HOutput output) throws IOException {
|
|||
private static final Path NATIVES_DIR = IOHelper.toPath("natives");
|
||||
private static final Path RESOURCEPACKS_DIR = IOHelper.toPath("resourcepacks");
|
||||
private static PublicURLClassLoader classLoader;
|
||||
// Authlib constants
|
||||
@LauncherAPI
|
||||
public static final String SKIN_URL_PROPERTY = "skinURL";
|
||||
@LauncherAPI
|
||||
public static final String SKIN_DIGEST_PROPERTY = "skinDigest";
|
||||
|
||||
@LauncherAPI
|
||||
public static final String CLOAK_URL_PROPERTY = "cloakURL";
|
||||
|
||||
@LauncherAPI
|
||||
public static final String CLOAK_DIGEST_PROPERTY = "cloakDigest";
|
||||
|
||||
// Used to determine from clientside is launched from launcher
|
||||
private static final AtomicBoolean LAUNCHED = new AtomicBoolean(false);
|
||||
|
||||
private static void addClientArgs(Collection<String> args, ClientProfile profile, Params params) {
|
||||
PlayerProfile pp = params.pp;
|
||||
|
@ -199,12 +184,12 @@ private static void addClientArgs(Collection<String> args, ClientProfile profile
|
|||
Collections.addAll(args, "--userType", "mojang");
|
||||
JsonObject properties = Json.object();
|
||||
if (pp.skin != null) {
|
||||
properties.add(SKIN_URL_PROPERTY, Json.array(pp.skin.url));
|
||||
properties.add(SKIN_DIGEST_PROPERTY, Json.array(SecurityHelper.toHex(pp.skin.digest)));
|
||||
properties.add(Launcher.SKIN_URL_PROPERTY, Json.array(pp.skin.url));
|
||||
properties.add(Launcher.SKIN_DIGEST_PROPERTY, Json.array(SecurityHelper.toHex(pp.skin.digest)));
|
||||
}
|
||||
if (pp.cloak != null) {
|
||||
properties.add(CLOAK_URL_PROPERTY, Json.array(pp.cloak.url));
|
||||
properties.add(CLOAK_DIGEST_PROPERTY, Json.array(SecurityHelper.toHex(pp.cloak.digest)));
|
||||
properties.add(Launcher.CLOAK_URL_PROPERTY, Json.array(pp.cloak.url));
|
||||
properties.add(Launcher.CLOAK_DIGEST_PROPERTY, Json.array(SecurityHelper.toHex(pp.cloak.digest)));
|
||||
}
|
||||
Collections.addAll(args, "--userProperties", properties.toString(WriterConfig.MINIMAL));
|
||||
|
||||
|
@ -265,7 +250,7 @@ public static void checkJVMBitsAndVersion() {
|
|||
|
||||
@LauncherAPI
|
||||
public static boolean isLaunched() {
|
||||
return LAUNCHED.get();
|
||||
return Launcher.LAUNCHED.get();
|
||||
}
|
||||
|
||||
@LauncherAPI
|
||||
|
@ -289,7 +274,7 @@ private static void launch(ClientProfile profile, Params params) throws Throwabl
|
|||
Class<?> mainClass = classLoader.loadClass(profile.getMainClass());
|
||||
MethodHandle mainMethod = MethodHandles.publicLookup().findStatic(mainClass, "main", MethodType.methodType(void.class, String[].class));
|
||||
// Invoke main method with exception wrapping
|
||||
LAUNCHED.set(true);
|
||||
Launcher.LAUNCHED.set(true);
|
||||
JVMHelper.fullGC();
|
||||
System.setProperty("minecraft.applet.TargetDirectory", params.clientDir.toString()); // For 1.5.2
|
||||
mainMethod.invoke((Object) args.toArray(EMPTY_ARRAY));
|
||||
|
|
|
@ -3,4 +3,7 @@
|
|||
|
||||
dependencies {
|
||||
compile project(':libLauncher')
|
||||
compileOnly 'com.google.code.gson:gson:2.8.5'
|
||||
compileOnly 'com.google.guava:guava:26.0-jre'
|
||||
compile files('../compat/authlib/authlib-clean.jar')
|
||||
}
|
||||
|
|
|
@ -3,7 +3,6 @@
|
|||
import java.util.UUID;
|
||||
|
||||
import ru.gravit.launcher.LauncherAPI;
|
||||
import ru.gravit.launcher.client.ClientLauncher;
|
||||
import ru.gravit.utils.helper.LogHelper;
|
||||
import ru.gravit.launcher.profiles.PlayerProfile;
|
||||
import ru.gravit.launcher.request.auth.CheckServerRequest;
|
||||
|
@ -27,8 +26,6 @@ public static CompatProfile checkServer(String username, String serverID) throws
|
|||
|
||||
@SuppressWarnings("unused")
|
||||
public static boolean joinServer(String username, String accessToken, String serverID) throws Exception {
|
||||
if (!ClientLauncher.isLaunched())
|
||||
throw new IllegalStateException("Bad Login (Cheater)");
|
||||
|
||||
// Join server
|
||||
LogHelper.debug("LegacyBridge.joinServer, Username: '%s', Access token: %s, Server ID: %s", username, accessToken, serverID);
|
|
@ -4,17 +4,16 @@
|
|||
|
||||
import ru.gravit.launcher.Launcher;
|
||||
import ru.gravit.launcher.LauncherAPI;
|
||||
import ru.gravit.launcher.client.ClientLauncher;
|
||||
import ru.gravit.utils.helper.SecurityHelper;
|
||||
import ru.gravit.launcher.profiles.PlayerProfile;
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
@LauncherAPI
|
||||
public final class CompatProfile {
|
||||
public static final String SKIN_URL_PROPERTY = ClientLauncher.SKIN_URL_PROPERTY;
|
||||
public static final String SKIN_DIGEST_PROPERTY = ClientLauncher.SKIN_DIGEST_PROPERTY;
|
||||
public static final String CLOAK_URL_PROPERTY = ClientLauncher.CLOAK_URL_PROPERTY;
|
||||
public static final String CLOAK_DIGEST_PROPERTY = ClientLauncher.CLOAK_DIGEST_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 CLOAK_URL_PROPERTY = Launcher.CLOAK_URL_PROPERTY;
|
||||
public static final String CLOAK_DIGEST_PROPERTY = Launcher.CLOAK_DIGEST_PROPERTY;
|
||||
|
||||
public static CompatProfile fromPlayerProfile(PlayerProfile profile) {
|
||||
return profile == null ? null : new CompatProfile(profile.uuid, profile.username,
|
|
@ -1,7 +1,6 @@
|
|||
package com.mojang.authlib.yggdrasil;
|
||||
|
||||
import ru.gravit.launcher.LauncherAPI;
|
||||
import ru.gravit.launcher.client.ClientLauncher;
|
||||
import ru.gravit.utils.helper.CommonHelper;
|
||||
import ru.gravit.utils.helper.IOHelper;
|
||||
import ru.gravit.utils.helper.LogHelper;
|
||||
|
@ -33,8 +32,6 @@ public static String getSkinURL(String username) {
|
|||
|
||||
@SuppressWarnings("unused")
|
||||
public static String joinServer(String username, String accessToken, String serverID) {
|
||||
if (!ClientLauncher.isLaunched())
|
||||
return "Bad Login (Cheater)";
|
||||
|
||||
// Join server
|
||||
LogHelper.debug("LegacyBridge.joinServer, Username: '%s', Access token: %s, Server ID: %s", username, accessToken, serverID);
|
|
@ -16,11 +16,11 @@
|
|||
|
||||
public final class YggdrasilGameProfileRepository implements GameProfileRepository {
|
||||
private static final long BUSY_WAIT_MS = VerifyHelper.verifyLong(
|
||||
Long.parseLong(System.getProperty("launcher.authlib.busyWait", Long.toString(100L))),
|
||||
VerifyHelper.L_NOT_NEGATIVE, "launcher.authlib.busyWait can't be < 0");
|
||||
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");
|
||||
private static final long ERROR_BUSY_WAIT_MS = VerifyHelper.verifyLong(
|
||||
Long.parseLong(System.getProperty("launcher.authlib.errorBusyWait", Long.toString(500L))),
|
||||
VerifyHelper.L_NOT_NEGATIVE, "launcher.authlib.errorBusyWait can't be < 0");
|
||||
Long.parseLong(System.getProperty("launcher.com.mojang.authlib.errorBusyWait", Long.toString(500L))),
|
||||
VerifyHelper.L_NOT_NEGATIVE, "launcher.com.mojang.authlib.errorBusyWait can't be < 0");
|
||||
|
||||
private static void busyWait(long ms) {
|
||||
try {
|
||||
|
@ -51,7 +51,7 @@ public void findProfilesByNames(String[] usernames, Agent agent, ProfileLookupCa
|
|||
callback.onProfileLookupFailed(new GameProfile((UUID) null, username), e);
|
||||
}
|
||||
|
||||
// Busy wait, like in standard authlib
|
||||
// Busy wait, like in standard com.mojang.authlib
|
||||
busyWait(ERROR_BUSY_WAIT_MS);
|
||||
continue;
|
||||
}
|
||||
|
@ -71,7 +71,7 @@ public void findProfilesByNames(String[] usernames, Agent agent, ProfileLookupCa
|
|||
callback.onProfileLookupSucceeded(YggdrasilMinecraftSessionService.toGameProfile(pp));
|
||||
}
|
||||
|
||||
// Busy wait, like in standard authlib
|
||||
// Busy wait, like in standard com.mojang.authlib
|
||||
busyWait(BUSY_WAIT_MS);
|
||||
}
|
||||
}
|
|
@ -6,6 +6,7 @@
|
|||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
|
||||
import com.mojang.authlib.minecraft.MinecraftProfileTexture;
|
||||
import com.google.common.collect.Iterables;
|
||||
import com.google.gson.JsonElement;
|
||||
import com.google.gson.JsonObject;
|
||||
|
@ -15,12 +16,9 @@
|
|||
import com.mojang.authlib.exceptions.AuthenticationException;
|
||||
import com.mojang.authlib.exceptions.AuthenticationUnavailableException;
|
||||
import com.mojang.authlib.minecraft.BaseMinecraftSessionService;
|
||||
import com.mojang.authlib.minecraft.MinecraftProfileTexture;
|
||||
import com.mojang.authlib.minecraft.MinecraftProfileTexture.Type;
|
||||
import com.mojang.authlib.properties.Property;
|
||||
import com.mojang.authlib.properties.PropertyMap;
|
||||
|
||||
import ru.gravit.launcher.client.ClientLauncher;
|
||||
import ru.gravit.launcher.Launcher;
|
||||
import ru.gravit.utils.helper.IOHelper;
|
||||
import ru.gravit.utils.helper.LogHelper;
|
||||
import ru.gravit.utils.helper.SecurityHelper;
|
||||
|
@ -31,7 +29,7 @@
|
|||
|
||||
public final class YggdrasilMinecraftSessionService extends BaseMinecraftSessionService {
|
||||
public static final JsonParser JSON_PARSER = new JsonParser();
|
||||
public static final boolean NO_TEXTURES = Boolean.parseBoolean("launcher.authlib.noTextures");
|
||||
public static final boolean NO_TEXTURES = Boolean.parseBoolean("launcher.com.mojang.authlib.noTextures");
|
||||
|
||||
public static void fillTextureProperties(GameProfile profile, PlayerProfile pp) {
|
||||
LogHelper.debug("fillTextureProperties, Username: '%s'", profile.getName());
|
||||
|
@ -41,18 +39,18 @@ public static void fillTextureProperties(GameProfile profile, PlayerProfile pp)
|
|||
// Fill textures map
|
||||
PropertyMap properties = profile.getProperties();
|
||||
if (pp.skin != null) {
|
||||
properties.put(ClientLauncher.SKIN_URL_PROPERTY, new Property(ClientLauncher.SKIN_URL_PROPERTY, pp.skin.url, ""));
|
||||
properties.put(ClientLauncher.SKIN_DIGEST_PROPERTY, new Property(ClientLauncher.SKIN_DIGEST_PROPERTY, SecurityHelper.toHex(pp.skin.digest), ""));
|
||||
properties.put(Launcher.SKIN_URL_PROPERTY, new Property(Launcher.SKIN_URL_PROPERTY, pp.skin.url, ""));
|
||||
properties.put(Launcher.SKIN_DIGEST_PROPERTY, new Property(Launcher.SKIN_DIGEST_PROPERTY, SecurityHelper.toHex(pp.skin.digest), ""));
|
||||
LogHelper.debug("fillTextureProperties, Has skin texture for username '%s'", profile.getName());
|
||||
}
|
||||
if (pp.cloak != null) {
|
||||
properties.put(ClientLauncher.CLOAK_URL_PROPERTY, new Property(ClientLauncher.CLOAK_URL_PROPERTY, pp.cloak.url, ""));
|
||||
properties.put(ClientLauncher.CLOAK_DIGEST_PROPERTY, new Property(ClientLauncher.CLOAK_DIGEST_PROPERTY, SecurityHelper.toHex(pp.cloak.digest), ""));
|
||||
properties.put(Launcher.CLOAK_URL_PROPERTY, new Property(Launcher.CLOAK_URL_PROPERTY, pp.cloak.url, ""));
|
||||
properties.put(Launcher.CLOAK_DIGEST_PROPERTY, new Property(Launcher.CLOAK_DIGEST_PROPERTY, SecurityHelper.toHex(pp.cloak.digest), ""));
|
||||
LogHelper.debug("fillTextureProperties, Has cloak texture for username '%s'", profile.getName());
|
||||
}
|
||||
}
|
||||
|
||||
private static void getTexturesMojang(Map<Type, MinecraftProfileTexture> textures, String texturesBase64, GameProfile profile) {
|
||||
private static void getTexturesMojang(Map<MinecraftProfileTexture.Type, MinecraftProfileTexture> textures, String texturesBase64, GameProfile profile) {
|
||||
// Decode textures payload
|
||||
JsonObject texturesJSON;
|
||||
try {
|
||||
|
@ -64,7 +62,7 @@ private static void getTexturesMojang(Map<Type, MinecraftProfileTexture> texture
|
|||
}
|
||||
|
||||
// Fetch textures from textures JSON
|
||||
for (Type type : MinecraftProfileTexture.PROFILE_TEXTURE_TYPES) {
|
||||
for (MinecraftProfileTexture.Type type : MinecraftProfileTexture.PROFILE_TEXTURE_TYPES) {
|
||||
if (textures.containsKey(type))
|
||||
continue; // Overriden by launcher
|
||||
|
||||
|
@ -119,23 +117,23 @@ public GameProfile fillProfileProperties(GameProfile profile, boolean requireSec
|
|||
}
|
||||
|
||||
@Override
|
||||
public Map<Type, MinecraftProfileTexture> getTextures(GameProfile profile, boolean requireSecure) {
|
||||
public Map<MinecraftProfileTexture.Type, MinecraftProfileTexture> getTextures(GameProfile profile, boolean requireSecure) {
|
||||
LogHelper.debug("getTextures, Username: '%s', UUID: '%s'", profile.getName(), profile.getUUID());
|
||||
Map<Type, MinecraftProfileTexture> textures = new EnumMap<>(Type.class);
|
||||
Map<MinecraftProfileTexture.Type, MinecraftProfileTexture> textures = new EnumMap<>(MinecraftProfileTexture.Type.class);
|
||||
|
||||
// Add textures
|
||||
if (!NO_TEXTURES) {
|
||||
// Add skin URL to textures map
|
||||
Property skinURL = Iterables.getFirst(profile.getProperties().get(ClientLauncher.SKIN_URL_PROPERTY), null);
|
||||
Property skinDigest = Iterables.getFirst(profile.getProperties().get(ClientLauncher.SKIN_DIGEST_PROPERTY), null);
|
||||
Property skinURL = Iterables.getFirst(profile.getProperties().get(Launcher.SKIN_URL_PROPERTY), null);
|
||||
Property skinDigest = Iterables.getFirst(profile.getProperties().get(Launcher.SKIN_DIGEST_PROPERTY), null);
|
||||
if (skinURL != null && skinDigest != null)
|
||||
textures.put(Type.SKIN, new MinecraftProfileTexture(skinURL.getValue(), skinDigest.getValue()));
|
||||
textures.put(MinecraftProfileTexture.Type.SKIN, new MinecraftProfileTexture(skinURL.getValue(), skinDigest.getValue()));
|
||||
|
||||
// Add cloak URL to textures map
|
||||
Property cloakURL = Iterables.getFirst(profile.getProperties().get(ClientLauncher.CLOAK_URL_PROPERTY), null);
|
||||
Property cloakDigest = Iterables.getFirst(profile.getProperties().get(ClientLauncher.CLOAK_DIGEST_PROPERTY), null);
|
||||
Property cloakURL = Iterables.getFirst(profile.getProperties().get(Launcher.CLOAK_URL_PROPERTY), null);
|
||||
Property cloakDigest = Iterables.getFirst(profile.getProperties().get(Launcher.CLOAK_DIGEST_PROPERTY), null);
|
||||
if (cloakURL != null && cloakDigest != null)
|
||||
textures.put(Type.CAPE, new MinecraftProfileTexture(cloakURL.getValue(), cloakDigest.getValue()));
|
||||
textures.put(MinecraftProfileTexture.Type.CAPE, new MinecraftProfileTexture(cloakURL.getValue(), cloakDigest.getValue()));
|
||||
|
||||
// Try to find missing textures in textures payload (now always true because launcher is not passing elytra skins)
|
||||
if (textures.size() != MinecraftProfileTexture.PROFILE_TEXTURE_COUNT) {
|
||||
|
@ -178,8 +176,6 @@ public YggdrasilAuthenticationService getAuthenticationService() {
|
|||
|
||||
@Override
|
||||
public void joinServer(GameProfile profile, String accessToken, String serverID) throws AuthenticationException {
|
||||
if (!ClientLauncher.isLaunched())
|
||||
throw new AuthenticationException("Bad Login (Cheater)");
|
||||
|
||||
// Join server
|
||||
String username = profile.getName();
|
|
@ -69,6 +69,7 @@ public static void main(String[] args) throws Throwable {
|
|||
String[] real_args = new String[args.length - 1];
|
||||
System.arraycopy(args, 1, real_args, 0, args.length - 1);
|
||||
modulesManager.postInitModules();
|
||||
LogHelper.debug("Invoke main method");
|
||||
mainMethod.invoke(real_args);
|
||||
}
|
||||
private static void generateConfigIfNotExists() throws IOException {
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
authlib-clean.jar
|
||||
com.mojang.authlib-clean.jar
|
||||
-----------------
|
||||
Этот JAR - заготовка для сборки LauncherAuthlib.
|
||||
Из неё удалены не используемые клиентом классы, а так же классы, реализованные в LauncherAuthlib.
|
||||
|
@ -7,9 +7,9 @@ GameProfile-combined.class
|
|||
--------------------------
|
||||
Этот класс - результат слияния ASM'ом методов из Authlib 1.7.2 и Authlib 1.7.10+, в нём есть метод как для получения
|
||||
UUID старого образца (без чёрточек, например `d3730e7436794ba6-8ab2a24ac9e755d4`),
|
||||
так и нового образца (`d3730e74-3679-4ba6-8ab2-a24ac9e755d4`). Уже включён в `authlib-clean.jar`
|
||||
так и нового образца (`d3730e74-3679-4ba6-8ab2-a24ac9e755d4`). Уже включён в `com.mojang.authlib-clean.jar`
|
||||
|
||||
MinecraftSessionService-combined.class
|
||||
--------------------------------------
|
||||
Этот класс - результат слияния ASM'ом методов из Authlib 1.10.2 и Authlib 1.11+, в нём есть метод как для авторизации
|
||||
на сервере с учётом InetAddress, так и без него. Уже включён в `authlib-clean.jar`
|
||||
на сервере с учётом InetAddress, так и без него. Уже включён в `com.mojang.authlib-clean.jar`
|
||||
|
|
|
@ -4,6 +4,5 @@
|
|||
dependencies {
|
||||
compileOnly 'org.fusesource.jansi:jansi:1.17.1'
|
||||
compileOnly 'org.javassist:javassist:3.23.1-GA'
|
||||
compile files('../compat/authlib/authlib-clean.jar')
|
||||
compile 'com.eclipsesource.minimal-json:minimal-json:0.9.4'
|
||||
}
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
import java.security.spec.InvalidKeySpecException;
|
||||
import java.util.Arrays;
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
import java.util.concurrent.atomic.AtomicReference;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
|
@ -18,6 +19,18 @@
|
|||
|
||||
public final class Launcher {
|
||||
|
||||
// Authlib constants
|
||||
@LauncherAPI
|
||||
public static final String SKIN_URL_PROPERTY = "skinURL";
|
||||
@LauncherAPI
|
||||
public static final String SKIN_DIGEST_PROPERTY = "skinDigest";
|
||||
@LauncherAPI
|
||||
public static final String CLOAK_URL_PROPERTY = "cloakURL";
|
||||
@LauncherAPI
|
||||
public static final String CLOAK_DIGEST_PROPERTY = "cloakDigest";
|
||||
// Used to determine from clientside is launched from launcher
|
||||
public static final AtomicBoolean LAUNCHED = new AtomicBoolean(false);
|
||||
|
||||
static int readBuildNumber() {
|
||||
try {
|
||||
return Integer.valueOf(IOHelper.request(IOHelper.getResourceURL("buildnumber")));
|
||||
|
|
Loading…
Reference in a new issue