Skip to content

Commit

Permalink
Tidy up extra stuff from nethernet initial implementation
Browse files Browse the repository at this point in the history
  • Loading branch information
rtm516 committed Aug 24, 2024
1 parent b4a9847 commit 46bda46
Show file tree
Hide file tree
Showing 11 changed files with 42 additions and 86 deletions.
62 changes: 19 additions & 43 deletions core/src/main/java/com/rtm516/mcxboxbroadcast/core/AuthManager.java
Original file line number Diff line number Diff line change
@@ -1,19 +1,17 @@
package com.rtm516.mcxboxbroadcast.core;

import static com.rtm516.mcxboxbroadcast.core.models.auth.SisuAuthorizeBody.sisuAuthorizedBody;

import com.google.gson.JsonObject;
import com.rtm516.mcxboxbroadcast.core.models.auth.PlayfabLoginBody;
import com.rtm516.mcxboxbroadcast.core.models.auth.PlayfabLoginResponse;
import com.rtm516.mcxboxbroadcast.core.models.auth.SisuAuthorizeBody;
import com.rtm516.mcxboxbroadcast.core.models.auth.XboxTokenInfo;
import com.rtm516.mcxboxbroadcast.core.models.auth.XstsAuthData;
import com.rtm516.mcxboxbroadcast.core.storage.StorageManager;
import java.io.IOException;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;

import net.lenni0451.commons.httpclient.HttpClient;
import net.lenni0451.commons.httpclient.requests.impl.PostRequest;
import net.raphimc.minecraftauth.MinecraftAuth;
import net.raphimc.minecraftauth.responsehandler.PlayFabResponseHandler;
import net.raphimc.minecraftauth.responsehandler.XblResponseHandler;
import net.raphimc.minecraftauth.step.AbstractStep;
import net.raphimc.minecraftauth.step.msa.MsaCodeStep;
Expand All @@ -33,11 +31,9 @@

public class AuthManager {
private final StorageManager storageManager;
private final HttpClient client;
private final Logger logger;

private StepXblSisuAuthentication.XblSisuTokens xboxToken;
// private StepFullBedrockSession.FullBedrockSession bedrockSession;
private XboxTokenInfo xboxTokenInfo;
private String playfabSessionTicket;

Expand All @@ -47,9 +43,8 @@ public class AuthManager {
* @param storageManager The storage manager to use for storing data
* @param logger The logger to use for outputting messages
*/
public AuthManager(StorageManager storageManager, HttpClient client, Logger logger) {
public AuthManager(StorageManager storageManager, Logger logger) {
this.storageManager = storageManager;
this.client = client;
this.logger = logger.prefixed("Auth");

this.xboxToken = null;
Expand Down Expand Up @@ -104,14 +99,7 @@ private void initialise() {
// Load in cache.json if we haven't loaded one from the old auth token
try {
String cacheData = storageManager.cache();
if (xboxToken == null && !cacheData.isBlank()) {
xboxToken = MinecraftAuth.BEDROCK_XBL_DEVICE_CODE_LOGIN.fromJson(JsonUtil.parseString(cacheData).getAsJsonObject());
// var lines = cacheData.lines().toList();
// xboxToken = MinecraftAuth.BEDROCK_XBL_DEVICE_CODE_LOGIN.fromJson(JsonUtil.parseString(lines.get(0)).getAsJsonObject());
// if (lines.size() > 1) {
// bedrockSession = MinecraftAuth.BEDROCK_DEVICE_CODE_LOGIN.fromJson(JsonUtil.parseString(lines.get(1)).getAsJsonObject());
// }
}
if (xboxToken == null && !cacheData.isBlank()) xboxToken = MinecraftAuth.BEDROCK_XBL_DEVICE_CODE_LOGIN.fromJson(JsonUtil.parseString(cacheData).getAsJsonObject());
} catch (IOException e) {
logger.error("Failed to load cache.json", e);
}
Expand All @@ -126,47 +114,35 @@ private void initialise() {
xboxToken = MinecraftAuth.BEDROCK_XBL_DEVICE_CODE_LOGIN.refresh(logger, httpClient, xboxToken);
}

// if (bedrockSession == null) {
// bedrockSession = MinecraftAuth.BEDROCK_DEVICE_CODE_LOGIN.getFromInput(logger, httpClient, xboxToken);
// }

// Save to cache.json
storageManager.cache(Constants.GSON.toJson(MinecraftAuth.BEDROCK_XBL_DEVICE_CODE_LOGIN.toJson(xboxToken)));

// Construct and store the Xbox token info
xboxTokenInfo = new XboxTokenInfo(xboxToken.getDisplayClaims().get("xid"), xboxToken.getUserHash(), xboxToken.getDisplayClaims().get("gtg"), xboxToken.getToken(), String.valueOf(xboxToken.getExpireTimeMs()));

playfabSessionTicket = fetchPlayfabSessionTicket();
playfabSessionTicket = fetchPlayfabSessionTicket(httpClient);
} catch (Exception e) {
logger.error("Failed to get/refresh auth token", e);
}
}

private String fetchPlayfabSessionTicket() throws IOException, InterruptedException {
// TODO Use minecraftauth library
private String fetchPlayfabSessionTicket(HttpClient httpClient) throws IOException, InterruptedException {
// TODO Use minecraftauth library using StepPlayFabToken
var initialSession = xboxToken.getInitialXblSession();

var authorizeRequest = new PostRequest(StepXblSisuAuthentication.XBL_SISU_URL);
authorizeRequest
.setContent(new JsonContent(sisuAuthorizedBody(initialSession, "https://b980a380.minecraft.playfabapi.com/")))
.setHeader(CryptUtil.getSignatureHeader(authorizeRequest, initialSession.getXblDeviceToken().getPrivateKey()));
var authorizeResponse = MinecraftAuth.createHttpClient().execute(authorizeRequest, new XblResponseHandler());
var authorizeRequest = new PostRequest(StepXblSisuAuthentication.XBL_SISU_URL)
.setContent(new JsonContent(SisuAuthorizeBody.create(initialSession, MicrosoftConstants.BEDROCK_PLAY_FAB_XSTS_RELYING_PARTY)));
authorizeRequest.setHeader(CryptUtil.getSignatureHeader(authorizeRequest, initialSession.getXblDeviceToken().getPrivateKey()));
var authorizeResponse = httpClient.execute(authorizeRequest, new XblResponseHandler());

var tokens = XblXstsToken.fromMicrosoftJson(authorizeResponse.getAsJsonObject("AuthorizationToken"), null);

var loginRequest = HttpRequest.newBuilder(Constants.PLAYFAB_LOGIN)
.header("Accept-Language", "en-US")
.header("Content-Type", "application/json; charset=utf-8")
.header("Accept", "application/json")
.POST(HttpRequest.BodyPublishers.ofString(PlayfabLoginBody.playfabLoginBody(tokens.getServiceToken())))
.build();

var loginResponse = client.send(loginRequest, HttpResponse.BodyHandlers.ofString());
if (loginResponse.statusCode() != 200) {
logger.debug("Playfab response: " + loginResponse.body());
throw new IllegalStateException("Unable to login to playfab!");
}
return Constants.GSON.fromJson(loginResponse.body(), PlayfabLoginResponse.class).data().SessionTicket();
var playfabRequest = new PostRequest(Constants.PLAYFAB_LOGIN)
.setContent(new JsonContent(PlayfabLoginBody.create(tokens.getServiceToken())));

var playfabResponse = httpClient.execute(playfabRequest, new PlayFabResponseHandler());

return playfabResponse.getAsJsonObject("data").get("SessionTicket").getAsString();
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ public class Constants {
public static final String CREATE_SESSION = "https://sessiondirectory.xboxlive.com/serviceconfigs/" + SERVICE_CONFIG_ID + "/sessionTemplates/MinecraftLobby/sessions/%s";
public static final String JOIN_SESSION = "https://sessiondirectory.xboxlive.com/handles/%s/session";

public static final URI PLAYFAB_LOGIN = URI.create("https://20ca2.playfabapi.com/Client/LoginWithXbox");
public static final String PLAYFAB_LOGIN = "https://20ca2.playfabapi.com/Client/LoginWithXbox";
public static final URI START_SESSION = URI.create("https://authorization.franchise.minecraft-services.net/api/v1.0/session/start");
public static final String RTC_WEBSOCKET_FORMAT = "wss://signal.franchise.minecraft-services.net/ws/v1.0/signaling/%s";

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,6 @@
*/
public class RtaWebsocketClient extends WebSocketClient {
private String connectionId;
private ExpandedSessionInfo sessionInfo;
private String tokenHeader;
private final Logger logger;
private boolean firstConnectionId = true;

Expand All @@ -25,11 +23,9 @@ public class RtaWebsocketClient extends WebSocketClient {
*
* @param authenticationToken The token to use for authentication
*/
public RtaWebsocketClient(String authenticationToken, ExpandedSessionInfo sessionInfo, String tokenHeader, Logger logger) {
public RtaWebsocketClient(String authenticationToken, Logger logger) {
super(Constants.RTA_WEBSOCKET);
addHeader("Authorization", authenticationToken);
this.sessionInfo = sessionInfo;
this.tokenHeader = tokenHeader;
this.logger = logger;
}

Expand Down Expand Up @@ -69,7 +65,7 @@ public void onMessage(String message) {
connectionId = ((Map<String, String>) parts[4]).get("ConnectionId");
firstConnectionId = false;
} else {
logger.debug("RTA Websocket message: " + message);
logger.debug("RTA Websocket received: " + message);
}
}

Expand All @@ -78,14 +74,14 @@ public void onMessage(String message) {
*/
@Override
public void onClose(int code, String reason, boolean remote) {
logger.debug("RTAWebsocket disconnected: " + reason + " (" + code + ")");
logger.debug("RTA Websocket disconnected: " + reason + " (" + code + ")");
}

/**
* @see WebSocketClient#onError(Exception)
**/
@Override
public void onError(Exception ex) {
logger.debug("RTAWebsocket error: " + ex.getMessage());
logger.debug("RTA Websocket error: " + ex.getMessage());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -50,12 +50,6 @@ public String getVersion() {
}

public void setVersion(String version) {
// If we are given a version with a slash, we only want the last part
// EG 1.21.20/1.21.21
if (version.contains("/")) {
String[] split = version.split("/");
version = split[split.length - 1].trim();
}
this.version = version;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ public SessionManagerCore(StorageManager storageManager, Logger logger) {
this.coreLogger = logger.prefixed("");
this.storageManager = storageManager;

this.authManager = new AuthManager(storageManager, httpClient, logger);
this.authManager = new AuthManager(storageManager, logger);

this.friendManager = new FriendManager(httpClient, logger, this);

Expand Down Expand Up @@ -359,7 +359,7 @@ protected String setupSession() {

var request = HttpRequest.newBuilder(Constants.START_SESSION)
.header("Content-Type", "application/json")
.POST(HttpRequest.BodyPublishers.ofString(SessionStartBody.sessionStart(sessionInfo, playfabTicket)))
.POST(HttpRequest.BodyPublishers.ofString(SessionStartBody.create(sessionInfo, playfabTicket)))
.build();

HttpResponse<String> response;
Expand All @@ -385,7 +385,7 @@ protected void setupRtaWebsocket(String token) {
if (rtaWebsocket != null) {
rtaWebsocket.close();
}
rtaWebsocket = new RtaWebsocketClient(token, sessionInfo, getTokenHeader(), logger);
rtaWebsocket = new RtaWebsocketClient(token, logger);
rtaWebsocket.connect();
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,13 +1,12 @@
package com.rtm516.mcxboxbroadcast.core.models.auth;

import com.google.gson.JsonObject;
import com.rtm516.mcxboxbroadcast.core.Constants;
import java.util.HashMap;

public final class PlayfabLoginBody {
private PlayfabLoginBody() {}

public static String playfabLoginBody(String xboxToken) {
return Constants.GSON_NULLS.toJson(new HashMap<>() {{
public static JsonObject create(String xboxToken) {
return Constants.GSON_NULLS.toJsonTree(new HashMap<>() {{
put("CreateAccount", true);
put("EncryptedRequest", null);
put("InfoRequestParameters", new HashMap<>() {{
Expand All @@ -30,6 +29,6 @@ public static String playfabLoginBody(String xboxToken) {
put("PlayerSecret", null);
put("TitleId", "20CA2");
put("XboxToken", "XBL3.0 x=" + xboxToken);
}});
}}).getAsJsonObject();
}
}

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,7 @@
import java.util.HashMap;

public final class SessionStartBody {
private SessionStartBody() {}

public static String sessionStart(ExpandedSessionInfo info, String playfabSessionTicket) {
public static String create(ExpandedSessionInfo info, String playfabSessionTicket) {
return Constants.GSON_NULLS.toJson(new HashMap<>() {{
put("device", new HashMap<>() {{
put("applicationType", "MinecraftPE");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,7 @@
import net.raphimc.minecraftauth.util.CryptUtil;

public final class SisuAuthorizeBody {
private SisuAuthorizeBody() {}

public static JsonObject sisuAuthorizedBody(InitialXblSession initialSession, String relyingParty) {
public static JsonObject create(InitialXblSession initialSession, String relyingParty) {
var content = new JsonObject();
content.addProperty("AccessToken", "t=" + initialSession.getMsaToken().getAccessToken());
content.addProperty("DeviceToken", initialSession.getXblDeviceToken().getToken());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,12 +25,6 @@
import java.util.concurrent.ThreadLocalRandom;
import java.util.concurrent.TimeUnit;

/**
* Licenced under GPL-2.0
* Modified to fit MCXboxBroadcast
*
* https://github.com/WaterdogPE/WaterdogPE/blob/4e2b3cd1a3d5e4d3599476fd907b6bd3186783eb/src/main/java/dev/waterdog/waterdogpe/network/serverinfo/BedrockServerInfo.java
*/
public class PingUtil {
private static EventLoopGroup workerEventLoopGroup;
private static boolean webPingEnabled = false;
Expand Down Expand Up @@ -59,6 +53,12 @@ public static Promise<BedrockPong> ping(InetSocketAddress server, long timeout,
return promise;
}

/**
* Licenced under GPL-2.0
* Modified to fit MCXboxBroadcast
*
* https://github.com/WaterdogPE/WaterdogPE/blob/4e2b3cd1a3d5e4d3599476fd907b6bd3186783eb/src/main/java/dev/waterdog/waterdogpe/network/serverinfo/BedrockServerInfo.java
*/
private static Promise<BedrockPong> raknetPing(InetSocketAddress server, long timeout, TimeUnit timeUnit) {
EventLoop eventLoop = workerEventLoopGroup.next();
Promise<BedrockPong> promise = eventLoop.newPromise();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ public void onOpen(ServerHandshake serverHandshake) {
*/
@Override
public void onMessage(String message) {
logger.debug("RTC Websocket message: " + message);
logger.debug("RTC Websocket received: " + message);
var messageWrapper = Constants.GSON.fromJson(message, WsFromMessage.class);

if (messageWrapper.Type() == 2) {
Expand Down Expand Up @@ -174,12 +174,12 @@ private void initialize(JsonObject message) {
public void onClose(int code, String reason, boolean remote) {
heartbeatFuture.cancel(true);

logger.info("RTCWebsocket disconnected: " + reason + " (" + code + ")");
logger.info("RTC Websocket disconnected: " + reason + " (" + code + ")");
}

@Override
public void onError(Exception ex) {
logger.info("RTCWebsocket error: " + ex.getMessage());
logger.info("RTC Websocket error: " + ex.getMessage());
}

public SessionInfo sessionInfo() {
Expand Down

0 comments on commit 46bda46

Please sign in to comment.