diff --git a/.idea/artifacts/Launcher.xml b/.idea/artifacts/Launcher.xml
index 4610f79..09af903 100644
--- a/.idea/artifacts/Launcher.xml
+++ b/.idea/artifacts/Launcher.xml
@@ -7,6 +7,7 @@
+
\ No newline at end of file
diff --git a/.idea/artifacts/LauncherAuthlib.xml b/.idea/artifacts/LauncherAuthlib.xml
deleted file mode 100644
index 4775b7d..0000000
--- a/.idea/artifacts/LauncherAuthlib.xml
+++ /dev/null
@@ -1,12 +0,0 @@
-
-
- $PROJECT_DIR$/
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/.idea/modules.xml b/.idea/modules.xml
index 78ef274..6d11769 100644
--- a/.idea/modules.xml
+++ b/.idea/modules.xml
@@ -4,7 +4,6 @@
-
\ No newline at end of file
diff --git a/LaunchServer/LaunchServer.iml b/LaunchServer/LaunchServer.iml
index 1e1f432..6c20146 100644
--- a/LaunchServer/LaunchServer.iml
+++ b/LaunchServer/LaunchServer.iml
@@ -9,7 +9,7 @@
-
+
@@ -18,9 +18,9 @@
-
-
-
+
+
+
diff --git a/Launcher.pro b/Launcher.pro
index 11b76aa..6ea75d3 100644
--- a/Launcher.pro
+++ b/Launcher.pro
@@ -1,5 +1,7 @@
-injars 'Launcher.jar'
-outjars 'Launcher-obf.jar'
+-libraryjars 'build/libraries/obf'
+-libraryjars 'build/libraries/guava-17.0.jar'
-libraryjars 'build/libraries/jansi-1.11.jar'
-libraryjars '/lib/rt.jar'
-libraryjars '/lib/jce.jar'
@@ -24,9 +26,9 @@
-renamesourcefileattribute SourceFile
-adaptresourcefilecontents META-INF/MANIFEST.MF
--keeppackagenames com.eclipsesource.json.**
+-keeppackagenames com.eclipsesource.json.**,com.mojang.**
--keep class com.eclipsesource.json.** {
+-keep class com.eclipsesource.json.**,com.mojang.** {
;
;
}
diff --git a/Launcher.stringer b/Launcher.stringer
index 7fd8144..8918ace 100644
--- a/Launcher.stringer
+++ b/Launcher.stringer
@@ -2,17 +2,22 @@
true
none
- build/dictionary.pro
-
-
- glob:launcher/**
-
-
-
-
- true
- false
- false
-
-
+ build/mapping.pro
+
+
+
+ filter
+ true
+
+
+ filter
+
+
+ filter
+ true
+ false
+ false
+
+
+
diff --git a/Launcher/Launcher.iml b/Launcher/Launcher.iml
index 21cb0d9..8bc22bc 100644
--- a/Launcher/Launcher.iml
+++ b/Launcher/Launcher.iml
@@ -5,10 +5,29 @@
+
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Launcher/MANIFEST.MF b/Launcher/MANIFEST.MF
index 60cd9e0..752edd1 100644
--- a/Launcher/MANIFEST.MF
+++ b/Launcher/MANIFEST.MF
@@ -3,3 +3,10 @@
Name: launcher/
Sealed: true
+
+Name: com/mojang/authlib/
+Sealed: true
+
+Name: com/mojang/util/
+Sealed: true
+
diff --git a/Launcher/source-authlib/minecraft/MinecraftProfileTexture.java b/Launcher/source-authlib/minecraft/MinecraftProfileTexture.java
new file mode 100644
index 0000000..0d8434c
--- /dev/null
+++ b/Launcher/source-authlib/minecraft/MinecraftProfileTexture.java
@@ -0,0 +1,40 @@
+package com.mojang.authlib.minecraft;
+
+public final class MinecraftProfileTexture {
+ public static final int PROFILE_TEXTURE_COUNT = Type.values().length;
+
+ // Instance
+ private final String url;
+ private final String hash;
+
+ public MinecraftProfileTexture(String url, String hash) {
+ this.url = url;
+ this.hash = hash;
+ }
+
+ @Override
+ public String toString() {
+ return String.format("MinecraftProfileTexture{url='%s',hash=%s}", url, hash);
+ }
+
+ @SuppressWarnings("unused")
+ public String getHash() {
+ return hash;
+ }
+
+ @SuppressWarnings({ "unused", "SameReturnValue" })
+ public String getMetadata(String key) {
+ return null;
+ }
+
+ @SuppressWarnings("unused")
+ public String getUrl() {
+ return url;
+ }
+
+ public enum Type {
+ SKIN,
+ CAPE,
+ ELYTRA
+ }
+}
diff --git a/Launcher/source-authlib/yggdrasil/LegacyBridge.java b/Launcher/source-authlib/yggdrasil/LegacyBridge.java
new file mode 100644
index 0000000..018f669
--- /dev/null
+++ b/Launcher/source-authlib/yggdrasil/LegacyBridge.java
@@ -0,0 +1,49 @@
+package com.mojang.authlib.yggdrasil;
+
+import launcher.client.ClientLauncher;
+import launcher.helper.CommonHelper;
+import launcher.helper.IOHelper;
+import launcher.helper.LogHelper;
+import launcher.request.auth.CheckServerRequest;
+import launcher.request.auth.JoinServerRequest;
+
+public final class LegacyBridge {
+ private LegacyBridge() {
+ }
+
+ @SuppressWarnings("unused")
+ public static boolean checkServer(String username, String serverID) throws Exception {
+ LogHelper.debug("LegacyBridge.checkServer, Username: '%s', Server ID: %s", username, serverID);
+ return new CheckServerRequest(username, serverID).request() != null;
+ }
+
+ @SuppressWarnings("unused")
+ public static String getCloakURL(String username) {
+ LogHelper.debug("LegacyBridge.getCloakURL: '%s'", username);
+ return CommonHelper.replace(System.getProperty("launcher.legacy.cloaksURL",
+ "http://skins.minecraft.net/MinecraftCloaks/%username%.png"), "username", IOHelper.urlEncode(username));
+ }
+
+ @SuppressWarnings("unused")
+ public static String getSkinURL(String username) {
+ LogHelper.debug("LegacyBridge.getSkinURL: '%s'", username);
+ return CommonHelper.replace(System.getProperty("launcher.legacy.skinsURL",
+ "http://skins.minecraft.net/MinecraftSkins/%username%.png"), "username", IOHelper.urlEncode(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);
+ try {
+ return new JoinServerRequest(username, accessToken, serverID).request() ? "OK" : "Bad Login (Clientside)";
+ } catch (Exception e) {
+ return e.toString();
+ }
+ }
+}
diff --git a/Launcher/source-authlib/yggdrasil/YggdrasilAuthenticationService.java b/Launcher/source-authlib/yggdrasil/YggdrasilAuthenticationService.java
new file mode 100644
index 0000000..d30bfde
--- /dev/null
+++ b/Launcher/source-authlib/yggdrasil/YggdrasilAuthenticationService.java
@@ -0,0 +1,32 @@
+package com.mojang.authlib.yggdrasil;
+
+import java.net.Proxy;
+
+import com.mojang.authlib.Agent;
+import com.mojang.authlib.AuthenticationService;
+import com.mojang.authlib.GameProfileRepository;
+import com.mojang.authlib.UserAuthentication;
+import com.mojang.authlib.minecraft.MinecraftSessionService;
+import launcher.helper.LogHelper;
+
+public final class YggdrasilAuthenticationService implements AuthenticationService {
+ @SuppressWarnings("UnusedParameters")
+ public YggdrasilAuthenticationService(Proxy proxy, String clientToken) {
+ LogHelper.debug("Patched AuthenticationService created: '%s'", clientToken);
+ }
+
+ @Override
+ public MinecraftSessionService createMinecraftSessionService() {
+ return new YggdrasilMinecraftSessionService(this);
+ }
+
+ @Override
+ public GameProfileRepository createProfileRepository() {
+ return new YggdrasilGameProfileRepository();
+ }
+
+ @Override
+ public UserAuthentication createUserAuthentication(Agent agent) {
+ throw new UnsupportedOperationException("createUserAuthentication is used only by Mojang Launcher");
+ }
+}
diff --git a/Launcher/source-authlib/yggdrasil/YggdrasilGameProfileRepository.java b/Launcher/source-authlib/yggdrasil/YggdrasilGameProfileRepository.java
new file mode 100644
index 0000000..1232bad
--- /dev/null
+++ b/Launcher/source-authlib/yggdrasil/YggdrasilGameProfileRepository.java
@@ -0,0 +1,76 @@
+package com.mojang.authlib.yggdrasil;
+
+import java.util.Arrays;
+import java.util.UUID;
+
+import com.mojang.authlib.Agent;
+import com.mojang.authlib.GameProfile;
+import com.mojang.authlib.GameProfileRepository;
+import com.mojang.authlib.ProfileLookupCallback;
+import launcher.client.PlayerProfile;
+import launcher.helper.LogHelper;
+import launcher.helper.VerifyHelper;
+import launcher.request.uuid.BatchProfileByUsernameRequest;
+
+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");
+ 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");
+
+ public YggdrasilGameProfileRepository() {
+ LogHelper.debug("Patched GameProfileRepository created");
+ }
+
+ @Override
+ public void findProfilesByNames(String[] usernames, Agent agent, ProfileLookupCallback callback) {
+ int offset = 0;
+ while (offset < usernames.length) {
+ String[] sliceUsernames = Arrays.copyOfRange(usernames, offset, Math.min(offset + BatchProfileByUsernameRequest.MAX_BATCH_SIZE, usernames.length));
+ offset += BatchProfileByUsernameRequest.MAX_BATCH_SIZE;
+
+ // Batch Username-To-UUID request
+ PlayerProfile[] sliceProfiles;
+ try {
+ sliceProfiles = new BatchProfileByUsernameRequest(sliceUsernames).request();
+ } catch (Exception e) {
+ for (String username : sliceUsernames) {
+ LogHelper.debug("Couldn't find profile '%s': %s", username, e);
+ callback.onProfileLookupFailed(new GameProfile((UUID) null, username), e);
+ }
+
+ // Busy wait, like in standard authlib
+ busyWait(ERROR_BUSY_WAIT_MS);
+ continue;
+ }
+
+ // Request succeeded!
+ for (int i = 0; i < sliceProfiles.length; i++) {
+ PlayerProfile pp = sliceProfiles[i];
+ if (pp == null) {
+ String username = sliceUsernames[i];
+ LogHelper.debug("Couldn't find profile '%s'", username);
+ callback.onProfileLookupFailed(new GameProfile((UUID) null, username), new ProfileNotFoundException("Server did not find the requested profile"));
+ continue;
+ }
+
+ // Report as looked up
+ LogHelper.debug("Successfully looked up profile '%s'", pp.username);
+ callback.onProfileLookupSucceeded(YggdrasilMinecraftSessionService.toGameProfile(pp));
+ }
+
+ // Busy wait, like in standard authlib
+ busyWait(BUSY_WAIT_MS);
+ }
+ }
+
+ private static void busyWait(long ms) {
+ try {
+ Thread.sleep(ms);
+ } catch (InterruptedException e) {
+ LogHelper.error(e);
+ }
+ }
+}
diff --git a/Launcher/source-authlib/yggdrasil/YggdrasilMinecraftSessionService.java b/Launcher/source-authlib/yggdrasil/YggdrasilMinecraftSessionService.java
new file mode 100644
index 0000000..8342dc9
--- /dev/null
+++ b/Launcher/source-authlib/yggdrasil/YggdrasilMinecraftSessionService.java
@@ -0,0 +1,153 @@
+package com.mojang.authlib.yggdrasil;
+
+import java.net.InetAddress;
+import java.util.EnumMap;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.UUID;
+
+import com.mojang.authlib.AuthenticationService;
+import com.mojang.authlib.GameProfile;
+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 launcher.client.ClientLauncher;
+import launcher.client.PlayerProfile;
+import launcher.helper.LogHelper;
+import launcher.helper.SecurityHelper;
+import launcher.request.auth.CheckServerRequest;
+import launcher.request.auth.JoinServerRequest;
+import launcher.request.uuid.ProfileByUUIDRequest;
+
+public final class YggdrasilMinecraftSessionService extends BaseMinecraftSessionService {
+ public YggdrasilMinecraftSessionService(AuthenticationService service) {
+ super(service);
+ LogHelper.debug("Patched MinecraftSessionService created");
+ }
+
+ @Override
+ public GameProfile fillProfileProperties(GameProfile profile, boolean requireSecure) {
+ // Verify has UUID
+ UUID uuid = profile.getUUID();
+ LogHelper.debug("fillProfileProperties, UUID: %s", uuid);
+ if (uuid == null) {
+ return profile;
+ }
+
+ // Make profile request
+ PlayerProfile pp;
+ try {
+ pp = new ProfileByUUIDRequest(uuid).request();
+ } catch (Exception e) {
+ LogHelper.debug("Couldn't fetch profile properties for '%s': %s", profile, e);
+ return profile;
+ }
+
+ // Verify is found
+ if (pp == null) {
+ LogHelper.debug("Couldn't fetch profile properties for '%s' as the profile does not exist", profile);
+ return profile;
+ }
+
+ // Create new game profile from player profile
+ LogHelper.debug("Successfully fetched profile properties for '%s'", profile);
+ fillTextureProperties(profile, pp);
+ return toGameProfile(pp);
+ }
+
+ @Override
+ public Map getTextures(GameProfile profile, boolean requireSecure) {
+ LogHelper.debug("getTextures, Username: '%s'", profile.getName());
+ Map textures = new EnumMap<>(Type.class);
+
+ // Add skin URL to textures map
+ Iterator skinURL = profile.getProperties().get(ClientLauncher.SKIN_URL_PROPERTY).iterator();
+ Iterator skinHash = profile.getProperties().get(ClientLauncher.SKIN_DIGEST_PROPERTY).iterator();
+ if (skinURL.hasNext() && skinHash.hasNext()) {
+ String urlValue = skinURL.next().getValue();
+ String hashValue = skinHash.next().getValue();
+ textures.put(Type.SKIN, new MinecraftProfileTexture(urlValue, hashValue));
+ }
+
+ // Add cloak URL to textures map
+ Iterator cloakURL = profile.getProperties().get(ClientLauncher.CLOAK_URL_PROPERTY).iterator();
+ Iterator cloakHash = profile.getProperties().get(ClientLauncher.CLOAK_DIGEST_PROPERTY).iterator();
+ if (cloakURL.hasNext() && cloakHash.hasNext()) {
+ String urlValue = cloakURL.next().getValue();
+ String hashValue = cloakHash.next().getValue();
+ textures.put(Type.CAPE, new MinecraftProfileTexture(urlValue, hashValue));
+ }
+
+ // Return filled textures
+ return textures;
+ }
+
+ @Override
+ public GameProfile hasJoinedServer(GameProfile profile, String serverID) throws AuthenticationUnavailableException {
+ String username = profile.getName();
+ LogHelper.debug("checkServer, Username: '%s', Server ID: %s", username, serverID);
+
+ // Make checkServer request
+ PlayerProfile pp;
+ try {
+ pp = new CheckServerRequest(username, serverID).request();
+ } catch (Exception e) {
+ LogHelper.error(e);
+ throw new AuthenticationUnavailableException(e);
+ }
+
+ // Return profile if found
+ return pp == null ? null : toGameProfile(pp);
+ }
+
+ @Override
+ public GameProfile hasJoinedServer(GameProfile profile, String serverID, InetAddress address) throws AuthenticationUnavailableException {
+ return hasJoinedServer(profile, serverID);
+ }
+
+ @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();
+ LogHelper.debug("joinServer, Username: '%s', Access token: %s, Server ID: %s", username, accessToken, serverID);
+
+ // Make joinServer request
+ boolean success;
+ try {
+ success = new JoinServerRequest(username, accessToken, serverID).request();
+ } catch (Exception e) {
+ throw new AuthenticationUnavailableException(e);
+ }
+
+ // Verify is success
+ if (!success) {
+ throw new AuthenticationException("Bad Login (Clientside)");
+ }
+ }
+
+ public static void fillTextureProperties(GameProfile profile, PlayerProfile pp) {
+ 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), ""));
+ }
+ 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), ""));
+ }
+ }
+
+ public static GameProfile toGameProfile(PlayerProfile pp) {
+ GameProfile profile = new GameProfile(pp.uuid, pp.username);
+ fillTextureProperties(profile, pp);
+ return profile;
+ }
+}
diff --git a/LauncherAuthlib/LauncherAuthlib.iml b/LauncherAuthlib/LauncherAuthlib.iml
deleted file mode 100644
index af1f8b3..0000000
--- a/LauncherAuthlib/LauncherAuthlib.iml
+++ /dev/null
@@ -1,30 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/LauncherAuthlib/MANIFEST.MF b/LauncherAuthlib/MANIFEST.MF
deleted file mode 100644
index 2263df0..0000000
--- a/LauncherAuthlib/MANIFEST.MF
+++ /dev/null
@@ -1,7 +0,0 @@
-Manifest-Version: 1.0
-
-Name: com/mojang/authlib/
-Sealed: true
-
-Name: com/mojang/util/
-Sealed: true
diff --git a/LauncherAuthlib/source/minecraft/MinecraftProfileTexture.java b/LauncherAuthlib/source/minecraft/MinecraftProfileTexture.java
deleted file mode 100644
index 0d8434c..0000000
--- a/LauncherAuthlib/source/minecraft/MinecraftProfileTexture.java
+++ /dev/null
@@ -1,40 +0,0 @@
-package com.mojang.authlib.minecraft;
-
-public final class MinecraftProfileTexture {
- public static final int PROFILE_TEXTURE_COUNT = Type.values().length;
-
- // Instance
- private final String url;
- private final String hash;
-
- public MinecraftProfileTexture(String url, String hash) {
- this.url = url;
- this.hash = hash;
- }
-
- @Override
- public String toString() {
- return String.format("MinecraftProfileTexture{url='%s',hash=%s}", url, hash);
- }
-
- @SuppressWarnings("unused")
- public String getHash() {
- return hash;
- }
-
- @SuppressWarnings({ "unused", "SameReturnValue" })
- public String getMetadata(String key) {
- return null;
- }
-
- @SuppressWarnings("unused")
- public String getUrl() {
- return url;
- }
-
- public enum Type {
- SKIN,
- CAPE,
- ELYTRA
- }
-}
diff --git a/LauncherAuthlib/source/yggdrasil/LegacyBridge.java b/LauncherAuthlib/source/yggdrasil/LegacyBridge.java
deleted file mode 100644
index 018f669..0000000
--- a/LauncherAuthlib/source/yggdrasil/LegacyBridge.java
+++ /dev/null
@@ -1,49 +0,0 @@
-package com.mojang.authlib.yggdrasil;
-
-import launcher.client.ClientLauncher;
-import launcher.helper.CommonHelper;
-import launcher.helper.IOHelper;
-import launcher.helper.LogHelper;
-import launcher.request.auth.CheckServerRequest;
-import launcher.request.auth.JoinServerRequest;
-
-public final class LegacyBridge {
- private LegacyBridge() {
- }
-
- @SuppressWarnings("unused")
- public static boolean checkServer(String username, String serverID) throws Exception {
- LogHelper.debug("LegacyBridge.checkServer, Username: '%s', Server ID: %s", username, serverID);
- return new CheckServerRequest(username, serverID).request() != null;
- }
-
- @SuppressWarnings("unused")
- public static String getCloakURL(String username) {
- LogHelper.debug("LegacyBridge.getCloakURL: '%s'", username);
- return CommonHelper.replace(System.getProperty("launcher.legacy.cloaksURL",
- "http://skins.minecraft.net/MinecraftCloaks/%username%.png"), "username", IOHelper.urlEncode(username));
- }
-
- @SuppressWarnings("unused")
- public static String getSkinURL(String username) {
- LogHelper.debug("LegacyBridge.getSkinURL: '%s'", username);
- return CommonHelper.replace(System.getProperty("launcher.legacy.skinsURL",
- "http://skins.minecraft.net/MinecraftSkins/%username%.png"), "username", IOHelper.urlEncode(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);
- try {
- return new JoinServerRequest(username, accessToken, serverID).request() ? "OK" : "Bad Login (Clientside)";
- } catch (Exception e) {
- return e.toString();
- }
- }
-}
diff --git a/LauncherAuthlib/source/yggdrasil/YggdrasilAuthenticationService.java b/LauncherAuthlib/source/yggdrasil/YggdrasilAuthenticationService.java
deleted file mode 100644
index d30bfde..0000000
--- a/LauncherAuthlib/source/yggdrasil/YggdrasilAuthenticationService.java
+++ /dev/null
@@ -1,32 +0,0 @@
-package com.mojang.authlib.yggdrasil;
-
-import java.net.Proxy;
-
-import com.mojang.authlib.Agent;
-import com.mojang.authlib.AuthenticationService;
-import com.mojang.authlib.GameProfileRepository;
-import com.mojang.authlib.UserAuthentication;
-import com.mojang.authlib.minecraft.MinecraftSessionService;
-import launcher.helper.LogHelper;
-
-public final class YggdrasilAuthenticationService implements AuthenticationService {
- @SuppressWarnings("UnusedParameters")
- public YggdrasilAuthenticationService(Proxy proxy, String clientToken) {
- LogHelper.debug("Patched AuthenticationService created: '%s'", clientToken);
- }
-
- @Override
- public MinecraftSessionService createMinecraftSessionService() {
- return new YggdrasilMinecraftSessionService(this);
- }
-
- @Override
- public GameProfileRepository createProfileRepository() {
- return new YggdrasilGameProfileRepository();
- }
-
- @Override
- public UserAuthentication createUserAuthentication(Agent agent) {
- throw new UnsupportedOperationException("createUserAuthentication is used only by Mojang Launcher");
- }
-}
diff --git a/LauncherAuthlib/source/yggdrasil/YggdrasilGameProfileRepository.java b/LauncherAuthlib/source/yggdrasil/YggdrasilGameProfileRepository.java
deleted file mode 100644
index 1232bad..0000000
--- a/LauncherAuthlib/source/yggdrasil/YggdrasilGameProfileRepository.java
+++ /dev/null
@@ -1,76 +0,0 @@
-package com.mojang.authlib.yggdrasil;
-
-import java.util.Arrays;
-import java.util.UUID;
-
-import com.mojang.authlib.Agent;
-import com.mojang.authlib.GameProfile;
-import com.mojang.authlib.GameProfileRepository;
-import com.mojang.authlib.ProfileLookupCallback;
-import launcher.client.PlayerProfile;
-import launcher.helper.LogHelper;
-import launcher.helper.VerifyHelper;
-import launcher.request.uuid.BatchProfileByUsernameRequest;
-
-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");
- 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");
-
- public YggdrasilGameProfileRepository() {
- LogHelper.debug("Patched GameProfileRepository created");
- }
-
- @Override
- public void findProfilesByNames(String[] usernames, Agent agent, ProfileLookupCallback callback) {
- int offset = 0;
- while (offset < usernames.length) {
- String[] sliceUsernames = Arrays.copyOfRange(usernames, offset, Math.min(offset + BatchProfileByUsernameRequest.MAX_BATCH_SIZE, usernames.length));
- offset += BatchProfileByUsernameRequest.MAX_BATCH_SIZE;
-
- // Batch Username-To-UUID request
- PlayerProfile[] sliceProfiles;
- try {
- sliceProfiles = new BatchProfileByUsernameRequest(sliceUsernames).request();
- } catch (Exception e) {
- for (String username : sliceUsernames) {
- LogHelper.debug("Couldn't find profile '%s': %s", username, e);
- callback.onProfileLookupFailed(new GameProfile((UUID) null, username), e);
- }
-
- // Busy wait, like in standard authlib
- busyWait(ERROR_BUSY_WAIT_MS);
- continue;
- }
-
- // Request succeeded!
- for (int i = 0; i < sliceProfiles.length; i++) {
- PlayerProfile pp = sliceProfiles[i];
- if (pp == null) {
- String username = sliceUsernames[i];
- LogHelper.debug("Couldn't find profile '%s'", username);
- callback.onProfileLookupFailed(new GameProfile((UUID) null, username), new ProfileNotFoundException("Server did not find the requested profile"));
- continue;
- }
-
- // Report as looked up
- LogHelper.debug("Successfully looked up profile '%s'", pp.username);
- callback.onProfileLookupSucceeded(YggdrasilMinecraftSessionService.toGameProfile(pp));
- }
-
- // Busy wait, like in standard authlib
- busyWait(BUSY_WAIT_MS);
- }
- }
-
- private static void busyWait(long ms) {
- try {
- Thread.sleep(ms);
- } catch (InterruptedException e) {
- LogHelper.error(e);
- }
- }
-}
diff --git a/LauncherAuthlib/source/yggdrasil/YggdrasilMinecraftSessionService.java b/LauncherAuthlib/source/yggdrasil/YggdrasilMinecraftSessionService.java
deleted file mode 100644
index 8342dc9..0000000
--- a/LauncherAuthlib/source/yggdrasil/YggdrasilMinecraftSessionService.java
+++ /dev/null
@@ -1,153 +0,0 @@
-package com.mojang.authlib.yggdrasil;
-
-import java.net.InetAddress;
-import java.util.EnumMap;
-import java.util.Iterator;
-import java.util.Map;
-import java.util.UUID;
-
-import com.mojang.authlib.AuthenticationService;
-import com.mojang.authlib.GameProfile;
-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 launcher.client.ClientLauncher;
-import launcher.client.PlayerProfile;
-import launcher.helper.LogHelper;
-import launcher.helper.SecurityHelper;
-import launcher.request.auth.CheckServerRequest;
-import launcher.request.auth.JoinServerRequest;
-import launcher.request.uuid.ProfileByUUIDRequest;
-
-public final class YggdrasilMinecraftSessionService extends BaseMinecraftSessionService {
- public YggdrasilMinecraftSessionService(AuthenticationService service) {
- super(service);
- LogHelper.debug("Patched MinecraftSessionService created");
- }
-
- @Override
- public GameProfile fillProfileProperties(GameProfile profile, boolean requireSecure) {
- // Verify has UUID
- UUID uuid = profile.getUUID();
- LogHelper.debug("fillProfileProperties, UUID: %s", uuid);
- if (uuid == null) {
- return profile;
- }
-
- // Make profile request
- PlayerProfile pp;
- try {
- pp = new ProfileByUUIDRequest(uuid).request();
- } catch (Exception e) {
- LogHelper.debug("Couldn't fetch profile properties for '%s': %s", profile, e);
- return profile;
- }
-
- // Verify is found
- if (pp == null) {
- LogHelper.debug("Couldn't fetch profile properties for '%s' as the profile does not exist", profile);
- return profile;
- }
-
- // Create new game profile from player profile
- LogHelper.debug("Successfully fetched profile properties for '%s'", profile);
- fillTextureProperties(profile, pp);
- return toGameProfile(pp);
- }
-
- @Override
- public Map getTextures(GameProfile profile, boolean requireSecure) {
- LogHelper.debug("getTextures, Username: '%s'", profile.getName());
- Map textures = new EnumMap<>(Type.class);
-
- // Add skin URL to textures map
- Iterator skinURL = profile.getProperties().get(ClientLauncher.SKIN_URL_PROPERTY).iterator();
- Iterator skinHash = profile.getProperties().get(ClientLauncher.SKIN_DIGEST_PROPERTY).iterator();
- if (skinURL.hasNext() && skinHash.hasNext()) {
- String urlValue = skinURL.next().getValue();
- String hashValue = skinHash.next().getValue();
- textures.put(Type.SKIN, new MinecraftProfileTexture(urlValue, hashValue));
- }
-
- // Add cloak URL to textures map
- Iterator cloakURL = profile.getProperties().get(ClientLauncher.CLOAK_URL_PROPERTY).iterator();
- Iterator cloakHash = profile.getProperties().get(ClientLauncher.CLOAK_DIGEST_PROPERTY).iterator();
- if (cloakURL.hasNext() && cloakHash.hasNext()) {
- String urlValue = cloakURL.next().getValue();
- String hashValue = cloakHash.next().getValue();
- textures.put(Type.CAPE, new MinecraftProfileTexture(urlValue, hashValue));
- }
-
- // Return filled textures
- return textures;
- }
-
- @Override
- public GameProfile hasJoinedServer(GameProfile profile, String serverID) throws AuthenticationUnavailableException {
- String username = profile.getName();
- LogHelper.debug("checkServer, Username: '%s', Server ID: %s", username, serverID);
-
- // Make checkServer request
- PlayerProfile pp;
- try {
- pp = new CheckServerRequest(username, serverID).request();
- } catch (Exception e) {
- LogHelper.error(e);
- throw new AuthenticationUnavailableException(e);
- }
-
- // Return profile if found
- return pp == null ? null : toGameProfile(pp);
- }
-
- @Override
- public GameProfile hasJoinedServer(GameProfile profile, String serverID, InetAddress address) throws AuthenticationUnavailableException {
- return hasJoinedServer(profile, serverID);
- }
-
- @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();
- LogHelper.debug("joinServer, Username: '%s', Access token: %s, Server ID: %s", username, accessToken, serverID);
-
- // Make joinServer request
- boolean success;
- try {
- success = new JoinServerRequest(username, accessToken, serverID).request();
- } catch (Exception e) {
- throw new AuthenticationUnavailableException(e);
- }
-
- // Verify is success
- if (!success) {
- throw new AuthenticationException("Bad Login (Clientside)");
- }
- }
-
- public static void fillTextureProperties(GameProfile profile, PlayerProfile pp) {
- 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), ""));
- }
- 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), ""));
- }
- }
-
- public static GameProfile toGameProfile(PlayerProfile pp) {
- GameProfile profile = new GameProfile(pp.uuid, pp.username);
- fillTextureProperties(profile, pp);
- return profile;
- }
-}
diff --git a/build.bat b/build.bat
index 33ffc31..6e8a511 100644
--- a/build.bat
+++ b/build.bat
@@ -6,16 +6,11 @@
java -jar build/proguard.jar @Launcher.pro
del Launcher.jar
ren Launcher-obf.jar Launcher.jar
-pack200 -E9 -Htrue -mlatest -Uerror -r Launcher.jar
java -jar build/stringer.jar -configFile Launcher.stringer Launcher.jar Launcher.jar
+pack200 -E9 -Htrue -mlatest -Uerror -r Launcher.jar
jarsigner -keystore build/sashok724.jks -storepass PSP1004 -sigfile LAUNCHER Launcher.jar sashok724
pack200 Launcher.pack.gz Launcher.jar
-REM Build LauncherAuthlib.jar
-echo Building LauncherAuthlib.jar...
-pack200 -E9 -Htrue -mlatest -Uerror -r LauncherAuthlib.jar
-jarsigner -keystore build/sashok724.jks -storepass PSP1004 -sigfile LAUNCHER LauncherAuthlib.jar sashok724
-
REM Build LaunchServer.jar
echo Building LaunchServer.jar...
jar -uf LaunchServer.jar Launcher.pack.gz buildnumber