diff --git a/.gitignore b/.gitignore index ec015cd..1714241 100644 --- a/.gitignore +++ b/.gitignore @@ -9,6 +9,7 @@ build/mapping.pro build/production/* build/test/* +build/stringer.jar !buildnumber Launcher.jar diff --git a/LaunchServer/source/auth/handler/AuthlibAuthHandler.java b/LaunchServer/source/auth/handler/AuthlibAuthHandler.java index 7b9bdb0..8fe6325 100644 --- a/LaunchServer/source/auth/handler/AuthlibAuthHandler.java +++ b/LaunchServer/source/auth/handler/AuthlibAuthHandler.java @@ -2,6 +2,7 @@ import com.eclipsesource.json.Json; import com.eclipsesource.json.JsonObject; +import launcher.helper.IOHelper; import launcher.serialize.config.entry.BlockConfigEntry; import launcher.serialize.config.entry.StringConfigEntry; import launchserver.auth.provider.AuthProviderResult; @@ -17,8 +18,8 @@ public class AuthlibAuthHandler extends AuthHandler { - private static java.net.URL URL; - private static String joinUrl; + private static java.net.URL URL_join, URL_hasJoin; + private static String joinUrl, hasJoinUrl; public final HashMap usernameToUUID = new HashMap<>(); @@ -26,11 +27,15 @@ { super(block); joinUrl = block.getEntryValue("joinUrl", StringConfigEntry.class); + hasJoinUrl = block.getEntryValue("hasJoinUrl", StringConfigEntry.class); try { // Docs: https://wiki.vg/Protocol_Encryption#Client - URL = new URL(joinUrl); // "https://sessionserver.mojang.com/session/minecraft/join" + URL_join = new URL(joinUrl); // "https://sessionserver.mojang.com/session/minecraft/join" + + // Docs: https://wiki.vg/Protocol_Encryption#Server + URL_hasJoin = new URL(hasJoinUrl); // "https://sessionserver.mojang.com/session/minecraft/hasJoined" } catch (MalformedURLException e) { @@ -49,8 +54,26 @@ } @Override - public UUID checkServer(String username, String serverID) { - return UUID.fromString(username); + public UUID checkServer(String username, String serverID) + { + JsonObject uuidResponse; + try { + URL uuidURL = new URL(URL_hasJoin + "?username=" + IOHelper.urlEncode(username) + "&serverId=" + IOHelper.urlEncode(serverID)); + uuidResponse = HTTPRequestHelper.makeAuthlibRequest(uuidURL, null, "Authlib"); + } + catch (IOException e) + { + throw new IllegalArgumentException("Empty UUID response"); + } + if (uuidResponse.get("error") != null) + { + throw new IllegalArgumentException(String.valueOf(uuidResponse.get("errorMessage"))); + } + if (uuidResponse.get("id") == null) + { + throw new IllegalArgumentException("Empty UUID response"); + } + return UUID.fromString(uuidResponse.get("id").asString().replaceFirst("(\\w{8})(\\w{4})(\\w{4})(\\w{4})(\\w{12})", "$1-$2-$3-$4-$5")); } @Override @@ -60,10 +83,11 @@ @Override public boolean joinServer(String username, String accessToken, String serverID) throws IOException { JsonObject request = Json.object(). - add("accessToken", accessToken).add("selectedProfile", usernameToUUID(username).toString().replace("-", "")). + add("accessToken", accessToken). + add("selectedProfile", usernameToUUID(username).toString().replace("-", "")). add("serverId", serverID); - int response = HTTPRequestHelper.authJoinRequest(URL, request, "AuthLib"); + int response = HTTPRequestHelper.authJoinRequest(URL_join, request, "AuthLib"); if (200 <= response && response < 300 ) { diff --git a/LaunchServer/source/auth/handler/MineSocialAuthHandler.java b/LaunchServer/source/auth/handler/MineSocialAuthHandler.java index ea882b5..dc64f64 100644 --- a/LaunchServer/source/auth/handler/MineSocialAuthHandler.java +++ b/LaunchServer/source/auth/handler/MineSocialAuthHandler.java @@ -2,6 +2,7 @@ import com.eclipsesource.json.Json; import com.eclipsesource.json.JsonObject; +import launcher.helper.IOHelper; import launcher.serialize.config.entry.BlockConfigEntry; import launchserver.auth.provider.AuthProviderResult; import launchserver.auth.provider.MineSocialAuthProviderResult; @@ -16,13 +17,14 @@ public class MineSocialAuthHandler extends AuthHandler { - private static final java.net.URL URL; + private static final java.net.URL URL_join, URL_hasJoin; static { try { - URL = new URL("https://sessionserver.minesocial.net/session/minecraft/join"); + URL_join = new URL("https://sessionserver.minesocial.net/session/minecraft/join"); + URL_hasJoin = new URL("https://sessionserver.minesocial.net/session/minecraft/hasJoined"); } catch (MalformedURLException e) { @@ -48,8 +50,26 @@ } @Override - public UUID checkServer(String username, String serverID) { - return UUID.fromString(username); + public UUID checkServer(String username, String serverID) + { + JsonObject uuidResponse; + try { + URL uuidURL = new URL(URL_hasJoin + "?username=" + IOHelper.urlEncode(username) + "&serverId=" + IOHelper.urlEncode(serverID)); + uuidResponse = HTTPRequestHelper.makeAuthlibRequest(uuidURL, null, "MineSocial"); + } + catch (IOException e) + { + throw new IllegalArgumentException("Empty UUID response"); + } + if (uuidResponse.get("error") != null) + { + throw new IllegalArgumentException(String.valueOf(uuidResponse.get("errorMessage"))); + } + if (uuidResponse.get("id") == null) + { + throw new IllegalArgumentException("Empty UUID response"); + } + return UUID.fromString(uuidResponse.get("id").asString().replaceFirst("(\\w{8})(\\w{4})(\\w{4})(\\w{4})(\\w{12})", "$1-$2-$3-$4-$5")); } @Override @@ -59,10 +79,11 @@ @Override public boolean joinServer(String username, String accessToken, String serverID) throws IOException { JsonObject request = Json.object(). - add("accessToken", accessToken).add("selectedProfile", usernameToUUID(username).toString().replace("-", "")). + add("accessToken", accessToken). + add("selectedProfile", usernameToUUID(username).toString().replace("-", "")). add("serverId", serverID); - int response = HTTPRequestHelper.authJoinRequest(URL, request, "MineSocial"); + int response = HTTPRequestHelper.authJoinRequest(URL_join, request, "MineSocial"); if (200 <= response && response < 300 ) { diff --git a/LaunchServer/source/auth/handler/MojangAuthHandler.java b/LaunchServer/source/auth/handler/MojangAuthHandler.java index 99bfc44..1b27c08 100644 --- a/LaunchServer/source/auth/handler/MojangAuthHandler.java +++ b/LaunchServer/source/auth/handler/MojangAuthHandler.java @@ -2,6 +2,7 @@ import com.eclipsesource.json.Json; import com.eclipsesource.json.JsonObject; +import launcher.helper.IOHelper; import launcher.serialize.config.entry.BlockConfigEntry; import launchserver.auth.provider.AuthProviderResult; import launchserver.auth.provider.MojangAuthProviderResult; @@ -16,13 +17,14 @@ public class MojangAuthHandler extends AuthHandler { - private static final java.net.URL URL; + private static final java.net.URL URL_join, URL_hasJoin; static { try { - URL = new URL("https://sessionserver.mojang.com/session/minecraft/join"); + URL_join = new URL("https://sessionserver.mojang.com/session/minecraft/join"); + URL_hasJoin = new URL("https://sessionserver.mojang.com/session/minecraft/hasJoined"); } catch (MalformedURLException e) { @@ -48,9 +50,26 @@ } @Override - public UUID checkServer(String username, String serverID) { - // .....допустим - return UUID.fromString(username); + public UUID checkServer(String username, String serverID) + { + JsonObject uuidResponse; + try { + URL uuidURL = new URL(URL_hasJoin + "?username=" + IOHelper.urlEncode(username) + "&serverId=" + IOHelper.urlEncode(serverID)); + uuidResponse = HTTPRequestHelper.makeAuthlibRequest(uuidURL, null, "Mojang"); + } + catch (IOException e) + { + throw new IllegalArgumentException("Empty UUID response"); + } + if (uuidResponse.get("error") != null) + { + throw new IllegalArgumentException(String.valueOf(uuidResponse.get("errorMessage"))); + } + if (uuidResponse.get("id") == null) + { + throw new IllegalArgumentException("Empty UUID response"); + } + return UUID.fromString(uuidResponse.get("id").asString().replaceFirst("(\\w{8})(\\w{4})(\\w{4})(\\w{4})(\\w{12})", "$1-$2-$3-$4-$5")); } @Override @@ -60,10 +79,11 @@ @Override public boolean joinServer(String username, String accessToken, String serverID) throws IOException { JsonObject request = Json.object(). - add("accessToken", accessToken).add("selectedProfile", usernameToUUID(username).toString().replace("-", "")). + add("accessToken", accessToken). + add("selectedProfile", usernameToUUID(username).toString().replace("-", "")). add("serverId", serverID); - int response = HTTPRequestHelper.authJoinRequest(URL, request, "Mojang"); + int response = HTTPRequestHelper.authJoinRequest(URL_join, request, "Mojang"); if (200 <= response && response < 300 ) { diff --git a/LaunchServer/source/auth/provider/AuthlibAuthProvider.java b/LaunchServer/source/auth/provider/AuthlibAuthProvider.java index 55f50a7..25184b4 100644 --- a/LaunchServer/source/auth/provider/AuthlibAuthProvider.java +++ b/LaunchServer/source/auth/provider/AuthlibAuthProvider.java @@ -3,20 +3,12 @@ import com.eclipsesource.json.Json; import com.eclipsesource.json.JsonObject; import com.eclipsesource.json.JsonValue; -import com.eclipsesource.json.WriterConfig; -import launcher.helper.IOHelper; -import launcher.helper.LogHelper; import launcher.serialize.config.entry.BlockConfigEntry; import launcher.serialize.config.entry.StringConfigEntry; +import launchserver.helpers.HTTPRequestHelper; -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; -import java.net.HttpURLConnection; import java.net.MalformedURLException; import java.net.URL; -import java.nio.charset.Charset; -import java.nio.charset.StandardCharsets; import java.util.UUID; import java.util.regex.Pattern; @@ -46,47 +38,16 @@ } } - public static JsonObject makeAuthlibRequest(URL url, JsonObject request) throws IOException - { - HttpURLConnection connection = request == null ? - (HttpURLConnection) IOHelper.newConnection(url) : - IOHelper.newConnectionPost(url); - - // Make request - if (request != null) - { - connection.setRequestProperty("Content-Type", "application/json"); - try (OutputStream output = connection.getOutputStream()) - { - output.write(request.toString(WriterConfig.MINIMAL).getBytes(StandardCharsets.UTF_8)); - } - } - connection.getResponseCode(); // Actually make request - - // Read response - InputStream errorInput = connection.getErrorStream(); - try (InputStream input = errorInput == null ? connection.getInputStream() : errorInput) - { - String charset = connection.getContentEncoding(); - Charset charsetObject = charset == null ? - IOHelper.UNICODE_CHARSET : Charset.forName(charset); - - // Parse response - String json = new String(IOHelper.read(input), charsetObject); - LogHelper.subDebug("Raw Authlib response: '" + json + '\''); - return json.isEmpty() ? null : Json.parse(json).asObject(); - } - } - @Override public AuthProviderResult auth(String login, String password, String ip) throws Throwable { + // https://wiki.vg/Authentication#Payload JsonObject request = Json.object(). add("agent", Json.object().add("name", "Minecraft").add("version", 1)). add("username", login).add("password", password); // Verify there's no error - JsonObject response = makeAuthlibRequest(URL, request); + JsonObject response = HTTPRequestHelper.makeAuthlibRequest(URL, request, "Authlib"); if (response == null) { authError("Empty Authlib response"); diff --git a/LaunchServer/source/auth/provider/MineSocialAuthProvider.java b/LaunchServer/source/auth/provider/MineSocialAuthProvider.java index 0aea68c..862a8d6 100644 --- a/LaunchServer/source/auth/provider/MineSocialAuthProvider.java +++ b/LaunchServer/source/auth/provider/MineSocialAuthProvider.java @@ -7,6 +7,7 @@ import launcher.helper.IOHelper; import launcher.helper.LogHelper; import launcher.serialize.config.entry.BlockConfigEntry; +import launchserver.helpers.HTTPRequestHelper; import java.io.IOException; import java.io.InputStream; @@ -41,55 +42,16 @@ super(block); } - public static JsonObject makeMineSocialRequest(URL url, JsonObject request) throws IOException - { - HttpURLConnection connection = request == null ? - (HttpURLConnection) IOHelper.newConnection(url) : - IOHelper.newConnectionPost(url); - - // Make request - if (request != null) - { - connection.setRequestProperty("Content-Type", "application/json"); - try (OutputStream output = connection.getOutputStream()) - { - output.write(request.toString(WriterConfig.MINIMAL).getBytes(StandardCharsets.UTF_8)); - } - } - int statusCode = connection.getResponseCode(); - - // Read response - InputStream errorInput = connection.getErrorStream(); - try (InputStream input = errorInput == null ? connection.getInputStream() : errorInput) - { - String charset = connection.getContentEncoding(); - Charset charsetObject = charset == null ? - IOHelper.UNICODE_CHARSET : Charset.forName(charset); - - // Parse response - String json = new String(IOHelper.read(input), charsetObject); - LogHelper.subDebug("Raw MineSocial response: '" + json + '\''); - - if (200 <= statusCode && statusCode < 300) - { - return Json.parse(json).asObject(); - } - else - { - return json.isEmpty() ? null : Json.parse(json).asObject(); - } - } - } - @Override public AuthProviderResult auth(String login, String password, String ip) throws Throwable { + // https://wiki.vg/Authentication#Payload JsonObject request = Json.object(). add("agent", Json.object().add("name", "Minecraft").add("version", 1)). add("username", login).add("password", password); // Verify there's no error - JsonObject response = makeMineSocialRequest(URL, request); + JsonObject response = HTTPRequestHelper.makeAuthlibRequest(URL, request, "MineSocial"); if (response == null) { authError("Empty MineSocial Provider response"); diff --git a/LaunchServer/source/auth/provider/MojangAuthProvider.java b/LaunchServer/source/auth/provider/MojangAuthProvider.java index f06fbce..3e68d39 100644 --- a/LaunchServer/source/auth/provider/MojangAuthProvider.java +++ b/LaunchServer/source/auth/provider/MojangAuthProvider.java @@ -3,19 +3,11 @@ import com.eclipsesource.json.Json; import com.eclipsesource.json.JsonObject; import com.eclipsesource.json.JsonValue; -import com.eclipsesource.json.WriterConfig; -import launcher.helper.IOHelper; -import launcher.helper.LogHelper; import launcher.serialize.config.entry.BlockConfigEntry; +import launchserver.helpers.HTTPRequestHelper; -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; -import java.net.HttpURLConnection; import java.net.MalformedURLException; import java.net.URL; -import java.nio.charset.Charset; -import java.nio.charset.StandardCharsets; import java.util.UUID; import java.util.regex.Pattern; @@ -41,47 +33,16 @@ super(block); } - public static JsonObject makeMojangRequest(URL url, JsonObject request) throws IOException - { - HttpURLConnection connection = request == null ? - (HttpURLConnection) IOHelper.newConnection(url) : - IOHelper.newConnectionPost(url); - - // Make request - if (request != null) - { - connection.setRequestProperty("Content-Type", "application/json"); - try (OutputStream output = connection.getOutputStream()) - { - output.write(request.toString(WriterConfig.MINIMAL).getBytes(StandardCharsets.UTF_8)); - } - } - connection.getResponseCode(); // Actually make request - - // Read response - InputStream errorInput = connection.getErrorStream(); - try (InputStream input = errorInput == null ? connection.getInputStream() : errorInput) - { - String charset = connection.getContentEncoding(); - Charset charsetObject = charset == null ? - IOHelper.UNICODE_CHARSET : Charset.forName(charset); - - // Parse response - String json = new String(IOHelper.read(input), charsetObject); - LogHelper.subDebug("Raw Mojang response: '" + json + '\''); - return json.isEmpty() ? null : Json.parse(json).asObject(); - } - } - @Override public AuthProviderResult auth(String login, String password, String ip) throws Throwable { + // https://wiki.vg/Authentication#Payload JsonObject request = Json.object(). add("agent", Json.object().add("name", "Minecraft").add("version", 1)). add("username", login).add("password", password); // Verify there's no error - JsonObject response = makeMojangRequest(URL, request); + JsonObject response = HTTPRequestHelper.makeAuthlibRequest(URL, request, "Mojang"); if (response == null) { authError("Empty mojang response"); diff --git a/LaunchServer/source/helpers/HTTPRequestHelper.java b/LaunchServer/source/helpers/HTTPRequestHelper.java index f93ff2e..71d32cc 100644 --- a/LaunchServer/source/helpers/HTTPRequestHelper.java +++ b/LaunchServer/source/helpers/HTTPRequestHelper.java @@ -1,16 +1,15 @@ package launchserver.helpers; +import com.eclipsesource.json.Json; import com.eclipsesource.json.JsonObject; import com.eclipsesource.json.WriterConfig; import launcher.helper.IOHelper; import launcher.helper.LogHelper; -import java.io.BufferedReader; -import java.io.IOException; -import java.io.InputStreamReader; -import java.io.OutputStream; +import java.io.*; import java.net.HttpURLConnection; import java.net.URL; +import java.nio.charset.Charset; import java.nio.charset.StandardCharsets; public class HTTPRequestHelper { @@ -20,6 +19,46 @@ return connection; } + public static JsonObject makeAuthlibRequest(URL url, JsonObject request, String requestType) throws IOException + { + HttpURLConnection connection = request == null ? + (HttpURLConnection) IOHelper.newConnection(url) : + IOHelper.newConnectionPost(url); + + // Make request + if (request != null) + { + connection.setRequestProperty("Content-Type", "application/json"); + try (OutputStream output = connection.getOutputStream()) + { + output.write(request.toString(WriterConfig.MINIMAL).getBytes(StandardCharsets.UTF_8)); + } + } + int statusCode = connection.getResponseCode(); + + // Read response + InputStream errorInput = connection.getErrorStream(); + try (InputStream input = errorInput == null ? connection.getInputStream() : errorInput) + { + String charset = connection.getContentEncoding(); + Charset charsetObject = charset == null ? + IOHelper.UNICODE_CHARSET : Charset.forName(charset); + + // Parse response + String json = new String(IOHelper.read(input), charsetObject); + LogHelper.subDebug("Raw " + requestType + " response: '" + json + '\''); + + if (200 <= statusCode && statusCode < 300) + { + return Json.parse(json).asObject(); + } + else + { + return json.isEmpty() ? null : Json.parse(json).asObject(); + } + } + } + public static boolean fileExist(URL url) throws IOException { HttpURLConnection request = makeRequest(url, "HEAD"); int responseCode = request.getResponseCode(); diff --git a/LaunchServer/source/texture/AuthlibTextureProvider.java b/LaunchServer/source/texture/AuthlibTextureProvider.java index fa866cb..64c95b2 100644 --- a/LaunchServer/source/texture/AuthlibTextureProvider.java +++ b/LaunchServer/source/texture/AuthlibTextureProvider.java @@ -12,7 +12,7 @@ import launcher.helper.VerifyHelper; import launcher.serialize.config.entry.BlockConfigEntry; import launcher.serialize.config.entry.StringConfigEntry; -import launchserver.auth.provider.AuthlibAuthProvider; +import launchserver.helpers.HTTPRequestHelper; import java.net.URL; import java.nio.charset.StandardCharsets; @@ -78,7 +78,7 @@ { // TODO Don't query UUID by username if using mojang auth handler (not implemented yet) URL uuidURL = new URL(setUuidURL + IOHelper.urlEncode(username)); - JsonObject uuidResponse = AuthlibAuthProvider.makeAuthlibRequest(uuidURL, null); + JsonObject uuidResponse = HTTPRequestHelper.makeAuthlibRequest(uuidURL, null, "Authlib"); if (uuidResponse == null) { throw new IllegalArgumentException("Empty UUID response"); @@ -87,7 +87,7 @@ // Obtain player profile URL profileURL = new URL(setProfileURL + uuidResolved); - JsonObject profileResponse = AuthlibAuthProvider.makeAuthlibRequest(profileURL, null); + JsonObject profileResponse = HTTPRequestHelper.makeAuthlibRequest(profileURL, null, "Authlib"); if (profileResponse == null) { throw new IllegalArgumentException("Empty Authlib response"); diff --git a/LaunchServer/source/texture/MineSocialTextureProvider.java b/LaunchServer/source/texture/MineSocialTextureProvider.java index 7e40536..e396535 100644 --- a/LaunchServer/source/texture/MineSocialTextureProvider.java +++ b/LaunchServer/source/texture/MineSocialTextureProvider.java @@ -12,6 +12,7 @@ import launcher.helper.VerifyHelper; import launcher.serialize.config.entry.BlockConfigEntry; import launchserver.auth.provider.MineSocialAuthProvider; +import launchserver.helpers.HTTPRequestHelper; import java.net.URL; import java.nio.charset.StandardCharsets; @@ -72,7 +73,7 @@ try { URL uuidURL = new URL("https://api.minesocial.net/users/profiles/minecraft/" + IOHelper.urlEncode(username)); - JsonObject uuidResponse = MineSocialAuthProvider.makeMineSocialRequest(uuidURL, null); + JsonObject uuidResponse = HTTPRequestHelper.makeAuthlibRequest(uuidURL, null, "MineSocial"); if (uuidResponse == null) { throw new IllegalArgumentException("Empty MineSocial UUID response!"); @@ -81,7 +82,7 @@ // Obtain player profile URL profileURL = new URL("https://sessionserver.minesocial.net/session/minecraft/profile/" + uuidResolved); - JsonObject profileResponse = MineSocialAuthProvider.makeMineSocialRequest(profileURL, null); + JsonObject profileResponse = HTTPRequestHelper.makeAuthlibRequest(profileURL, null, "MineSocial"); if (profileResponse == null) { throw new IllegalArgumentException("Empty MineSocial profile response!"); diff --git a/LaunchServer/source/texture/MojangTextureProvider.java b/LaunchServer/source/texture/MojangTextureProvider.java index 4dfc66b..cd5be61 100644 --- a/LaunchServer/source/texture/MojangTextureProvider.java +++ b/LaunchServer/source/texture/MojangTextureProvider.java @@ -11,7 +11,7 @@ import launcher.helper.LogHelper; import launcher.helper.VerifyHelper; import launcher.serialize.config.entry.BlockConfigEntry; -import launchserver.auth.provider.MojangAuthProvider; +import launchserver.helpers.HTTPRequestHelper; import java.net.URL; import java.nio.charset.StandardCharsets; @@ -71,7 +71,7 @@ { // TODO Don't query UUID by username if using mojang auth handler (not implemented yet) URL uuidURL = new URL("https://api.mojang.com/users/profiles/minecraft/" + IOHelper.urlEncode(username)); - JsonObject uuidResponse = MojangAuthProvider.makeMojangRequest(uuidURL, null); + JsonObject uuidResponse = HTTPRequestHelper.makeAuthlibRequest(uuidURL, null, "Mojang"); if (uuidResponse == null) { throw new IllegalArgumentException("Empty UUID response"); @@ -80,7 +80,7 @@ // Obtain player profile URL profileURL = new URL("https://sessionserver.mojang.com/session/minecraft/profile/" + uuidResolved); - JsonObject profileResponse = MojangAuthProvider.makeMojangRequest(profileURL, null); + JsonObject profileResponse = HTTPRequestHelper.makeAuthlibRequest(profileURL, null, "Mojang"); if (profileResponse == null) { throw new IllegalArgumentException("Empty Mojang response"); diff --git a/build/proguard.jar b/build/proguard.jar index 08f4a4c..21d93ce 100644 --- a/build/proguard.jar +++ b/build/proguard.jar Binary files differ diff --git a/buildnumber b/buildnumber index 6b9dd9a..d32d87a 100644 --- a/buildnumber +++ b/buildnumber @@ -1 +1 @@ -552, 02.06.2021 \ No newline at end of file +561, 12.06.2021 \ No newline at end of file