Feat: Allow Launching from launchers

This commit is contained in:
2026-05-27 08:21:56 -04:00
parent 77b5b16de4
commit 9795b96e8f
3 changed files with 180 additions and 32 deletions
@@ -16,6 +16,7 @@
#include "./../../Minecraft.Server/Windows64/ServerAuth.h"
#else
#include "../Windows64_Launcher.h"
#include "../Windows64_Minecraft.h"
#endif
#include "../../../Minecraft.World/DisconnectPacket.h"
@@ -93,7 +94,7 @@ char g_Win64RelayServerIP[256] = "relay.mclegacyedition.xyz";
wchar_t g_Win64RelayServerIP_Wide[256] = L"relay.mclegacyedition.xyz";
wchar_t g_Win64AuthIP[256] = L"auth.mclegacyedition.xyz";
int g_Win64RelayServerPort = 2052;
char g_GameVersion[9] = "TU19";
char g_GameVersion[] = "TU19";
bool WinsockNetLayer::Initialize()
{
@@ -243,7 +244,12 @@ bool WinsockNetLayer::HostGame(int port, const char* bindIp)
{
#if defined(MINECRAFT_SERVER_BUILD)
#else
if (Windows64Launcher::IsInOfflineMode()) return true;
if (Windows64Minecraft::IsExternalLauncher()) {
if (Windows64Minecraft::IsOfflineMode()) return true;
}
else {
if (Windows64Launcher::IsInOfflineMode()) return true;
}
#endif
if (!s_initialized && !Initialize()) return false;
@@ -303,7 +309,13 @@ bool WinsockNetLayer::HostGame(int port, const char* bindIp)
#if defined(MINECRAFT_SERVER_BUILD)
std::string authToken = ServerAuth::GetAuthenticationToken();
#else
std::string authToken = Windows64Launcher::GetAuthenticationToken();
std::string authToken;
if (Windows64Minecraft::IsExternalLauncher()) {
authToken = Windows64Minecraft::GetAuthenticationTicket();
}
else {
authToken = Windows64Launcher::GetAuthenticationToken();
}
#endif
std::string isDedicatedServer = (g_Win64DedicatedServer ? "1" : "0");
std::string req = "HOST " + authToken + " " + isDedicatedServer + "\n";
@@ -322,7 +334,12 @@ bool WinsockNetLayer::JoinGame(const char* ip, int port)
{
#if defined(MINECRAFT_SERVER_BUILD)
#else
if (Windows64Launcher::IsInOfflineMode()) return true;
if (Windows64Minecraft::IsExternalLauncher()) {
if (Windows64Minecraft::IsOfflineMode()) return true;
}
else {
if (Windows64Launcher::IsInOfflineMode()) return true;
}
#endif
if (!s_initialized && !Initialize()) return false;
@@ -388,7 +405,13 @@ bool WinsockNetLayer::JoinGame(const char* ip, int port)
#if defined(MINECRAFT_SERVER_BUILD)
std::string authToken = ServerAuth::GetAuthenticationToken();
#else
std::string authToken = Windows64Launcher::GetAuthenticationToken();
std::string authToken;
if (Windows64Minecraft::IsExternalLauncher()) {
authToken = Windows64Minecraft::GetAuthenticationTicket();
}
else {
authToken = Windows64Launcher::GetAuthenticationToken();
}
#endif
std::string hostname(ip);
std::string req = "JOIN " + authToken + " 0 " + hostname + " 0\n";
@@ -441,7 +464,12 @@ bool WinsockNetLayer::BeginJoinGame(const char* ip, int port)
{
#if defined(MINECRAFT_SERVER_BUILD)
#else
if (Windows64Launcher::IsInOfflineMode()) return true;
if (Windows64Minecraft::IsExternalLauncher()) {
if (Windows64Minecraft::IsOfflineMode()) return true;
}
else {
if (Windows64Launcher::IsInOfflineMode()) return true;
}
#endif
if (!s_initialized && !Initialize()) return false;
@@ -548,7 +576,13 @@ DWORD WINAPI WinsockNetLayer::JoinThreadProc(LPVOID param)
#if defined(MINECRAFT_SERVER_BUILD)
std::string authToken = ServerAuth::GetAuthenticationToken();
#else
std::string authToken = Windows64Launcher::GetAuthenticationToken();
std::string authToken;
if (Windows64Minecraft::IsExternalLauncher()) {
authToken = Windows64Minecraft::GetAuthenticationTicket();
}
else {
authToken = Windows64Launcher::GetAuthenticationToken();
}
#endif
std::string hostname(s_joinIP);
std::string req = "JOIN " + authToken + " 0 " + hostname + " 0\n";
@@ -847,7 +881,13 @@ DWORD WINAPI WinsockNetLayer::AcceptThreadProc(LPVOID param)
#if defined(MINECRAFT_SERVER_BUILD)
std::string authToken = ServerAuth::GetAuthenticationToken();
#else
std::string authToken = Windows64Launcher::GetAuthenticationToken();
std::string authToken;
if (Windows64Minecraft::IsExternalLauncher()) {
authToken = Windows64Minecraft::GetAuthenticationTicket();
}
else {
authToken = Windows64Launcher::GetAuthenticationToken();
}
#endif
std::string isDedicatedServer = (g_Win64DedicatedServer ? "1" : "0");
std::string acc = "ACCEPT " + authToken + " " + isDedicatedServer + " " + clientId + "\n";
@@ -1207,7 +1247,13 @@ bool WinsockNetLayer::JoinSplitScreen(int padIndex, BYTE* outSmallId)
#if defined(MINECRAFT_SERVER_BUILD)
std::string authToken = ServerAuth::GetAuthenticationToken();
#else
std::string authToken = Windows64Launcher::GetAuthenticationToken();
std::string authToken;
if (Windows64Minecraft::IsExternalLauncher()) {
authToken = Windows64Minecraft::GetAuthenticationTicket();
}
else {
authToken = Windows64Launcher::GetAuthenticationToken();
}
#endif
std::string hostname(g_Win64MultiplayerIP);
std::string req = "JOIN " + authToken + " 0 " + hostname + " 1\n";
@@ -1364,7 +1410,12 @@ bool WinsockNetLayer::StartAdvertising(int gamePort, const wchar_t* hostName, un
{
#if defined(MINECRAFT_SERVER_BUILD)
#else
if (Windows64Launcher::IsInOfflineMode()) return true;
if (Windows64Minecraft::IsExternalLauncher()) {
if (Windows64Minecraft::IsOfflineMode()) return true;
}
else {
if (Windows64Launcher::IsInOfflineMode()) return true;
}
#endif
if (s_advertising) return true;
if (!s_initialized) return false;
@@ -1477,7 +1528,13 @@ DWORD WINAPI WinsockNetLayer::AdvertiseThreadProc(LPVOID param)
#if defined(MINECRAFT_SERVER_BUILD)
std::string authToken = ServerAuth::GetAuthenticationToken();
#else
std::string authToken = Windows64Launcher::GetAuthenticationToken();
std::string authToken;
if (Windows64Minecraft::IsExternalLauncher()) {
authToken = Windows64Minecraft::GetAuthenticationTicket();
}
else {
authToken = Windows64Launcher::GetAuthenticationToken();
}
#endif
std::string isDedicatedServer = (g_Win64DedicatedServer ? "1" : "0");
std::string req = "ADVERTISE " + authToken + " " + isDedicatedServer;
@@ -1504,7 +1561,12 @@ bool WinsockNetLayer::StartDiscovery()
{
#if defined(MINECRAFT_SERVER_BUILD)
#else
if (Windows64Launcher::IsInOfflineMode()) return true;
if (Windows64Minecraft::IsExternalLauncher()) {
if (Windows64Minecraft::IsOfflineMode()) return true;
}
else {
if (Windows64Launcher::IsInOfflineMode()) return true;
}
#endif
if (s_discovering) return true;
if (!s_initialized) return false;
@@ -1591,7 +1653,13 @@ DWORD WINAPI WinsockNetLayer::DiscoveryThreadProc(LPVOID param)
#if defined(MINECRAFT_SERVER_BUILD)
std::string authToken = ServerAuth::GetAuthenticationToken();
#else
std::string authToken = Windows64Launcher::GetAuthenticationToken();
std::string authToken;
if (Windows64Minecraft::IsExternalLauncher()) {
authToken = Windows64Minecraft::GetAuthenticationTicket();
}
else {
authToken = Windows64Launcher::GetAuthenticationToken();
}
#endif
std::string req = "LIST " + authToken + " 0 dedicated " + g_GameVersion + "\n";
send(sock, req.c_str(), (int)req.length(), 0);
@@ -57,6 +57,7 @@ extern Renderer InternalRenderManager;
#include "Xbox/Resource.h"
#include "Windows64_Minecraft.h"
#include "Windows64_Launcher.h"
// request use of dedicated GPU from AMD and Nvidia drivers
@@ -125,16 +126,50 @@ static bool g_bResizeReady = false;
char g_Win64Username[17] = { 0 };
wchar_t g_Win64UsernameW[17] = { 0 };
char g_Win64SessionTicket[256];
bool s_externalLauncher = false;
bool isOfflineMode = false;
bool Windows64Minecraft::IsOfflineMode() {
return isOfflineMode;
}
bool Windows64Minecraft::IsExternalLauncher() {
return s_externalLauncher;
}
std::string Windows64Minecraft::GetAuthenticationTicket() {
return g_Win64SessionTicket;
}
static bool FetchSessionInfo() {
std::vector<std::wstring> headers;
headers.push_back(L"Content-Type: text/plain");
HttpResponse response = WinsockNetLayer::DoWinHttpRequest(L"/getAccountInfo", L"POST", Windows64Minecraft::GetAuthenticationTicket(), headers);
if (response.status == 0) return false;
if (response.status != 200) return false;
if (response.body.empty() || response.body[0] != '-') return false;
std::string payload = response.body.substr(1);
//std::vector<std::string> splitData = split(payload, '|');
strncpy_s(g_Win64Username, sizeof(g_Win64Username), payload.c_str(), _TRUNCATE);
MultiByteToWideChar(CP_UTF8, 0, g_Win64Username, -1, g_Win64UsernameW, sizeof(g_Win64UsernameW) / sizeof(wchar_t));
//WideCharToMultiByte(CP_ACP, 0, g_Win64UsernameW, -1, g_Win64Username, static_cast<int>(sizeof(g_Win64Username)), nullptr, nullptr);
return true;
}
// Fullscreen toggle state
static bool g_isFullscreen = false;
static WINDOWPLACEMENT g_wpPrev = { sizeof(g_wpPrev) };
struct Win64LaunchOptions
{
int screenMode;
bool fullscreen;
};
static void CopyWideArgToAnsi(LPCWSTR source, char* dest, size_t destSize)
{
if (destSize == 0)
@@ -213,14 +248,13 @@ static void ApplyScreenMode(int screenMode)
}
}
using Win64LaunchOptions = Windows64Minecraft::Win64LaunchOptions;
static Win64LaunchOptions ParseLaunchOptions()
{
Win64LaunchOptions options = {};
options.screenMode = 0;
g_Win64MultiplayerJoin = false;
g_Win64MultiplayerPort = WIN64_NET_DEFAULT_PORT;
int argc = 0;
LPWSTR* argv = CommandLineToArgvW(GetCommandLineW(), &argc);
if (argv == nullptr)
@@ -238,6 +272,21 @@ static Win64LaunchOptions ParseLaunchOptions()
options.fullscreen = true;
}
for (int i = 1; i < argc; ++i)
{
if (_wcsicmp(argv[i], L"-username") == 0 && (i + 1) < argc) {
CopyWideArgToAnsi(argv[++i], g_Win64Username, sizeof(g_Win64Username));
options.username = true;
}
else if (_wcsicmp(argv[i], L"-token") == 0 && (i + 1) < argc) {
CopyWideArgToAnsi(argv[++i], g_Win64SessionTicket, sizeof(g_Win64SessionTicket));
options.token = true;
}
else if (_wcsicmp(argv[i], L"-offline") == 0) {
isOfflineMode = true;
}
}
LocalFree(argv);
return options;
}
@@ -1289,10 +1338,7 @@ static Minecraft* InitialiseMinecraftRuntime()
void StartGame(Win64LaunchOptions launchOptions, int nCmdShow);
int APIENTRY _tWinMain(_In_ HINSTANCE hInstance,
_In_opt_ HINSTANCE hPrevInstance,
_In_ LPTSTR lpCmdLine,
_In_ int nCmdShow)
int APIENTRY _tWinMain(_In_ HINSTANCE hInstance, _In_opt_ HINSTANCE hPrevInstance, _In_ LPTSTR lpCmdLine, _In_ int nCmdShow)
{
UNREFERENCED_PARAMETER(hPrevInstance);
UNREFERENCED_PARAMETER(lpCmdLine);
@@ -1300,29 +1346,45 @@ int APIENTRY _tWinMain(_In_ HINSTANCE hInstance,
// 4J-Win64: set CWD to exe dir so asset paths resolve correctly
{
char szExeDir[MAX_PATH] = {};
GetModuleFileNameA(NULL, szExeDir, MAX_PATH);
char *pSlash = strrchr(szExeDir, '\\');
GetModuleFileNameA(nullptr, szExeDir, MAX_PATH);
char* pSlash = strrchr(szExeDir, '\\');
if (pSlash) { *(pSlash + 1) = '\0'; SetCurrentDirectoryA(szExeDir); }
}
// Declare DPI awareness so GetSystemMetrics returns physical pixels
SetProcessDPIAware();
g_iScreenWidth = GetSystemMetrics(SM_CXSCREEN);
g_iScreenHeight = GetSystemMetrics(SM_CYSCREEN);
g_rScreenWidth = g_iScreenWidth;
g_rScreenHeight = g_iScreenHeight;
// Load stuff from launch options, including username
Win64LaunchOptions launchOptions = ParseLaunchOptions();
ApplyScreenMode(launchOptions.screenMode);
hMyInst = hInstance;
// If -token was passed by an external launcher then skip the internal launcher
// or if -offline was passed then skip auth
if (launchOptions.token)
{
// External launcher path: resolve session info and go straight to game
s_externalLauncher = true;
MultiByteToWideChar(CP_ACP, 0, g_Win64Username, -1, g_Win64UsernameW, 17);
FetchSessionInfo();
StartGame(launchOptions, nCmdShow);
}
else if (Windows64Minecraft::IsOfflineMode()) {
MultiByteToWideChar(CP_ACP, 0, g_Win64Username, -1, g_Win64UsernameW, 17);
StartGame(launchOptions, nCmdShow);
}
else
{
Windows64Launcher::CreateLauncherWindow(hInstance, [launchOptions, nCmdShow]() {
const char* username = Windows64Launcher::GetUsername().c_str();
strncpy_s(g_Win64Username, sizeof(g_Win64Username), username, _TRUNCATE);
MultiByteToWideChar(CP_ACP, 0, g_Win64Username, -1, g_Win64UsernameW, 17);
StartGame(launchOptions, nCmdShow);
});
});
}
return 0;
}
@@ -0,0 +1,18 @@
#pragma once
#include <string>
class Windows64Minecraft {
public:
static bool IsOfflineMode();
static std::string GetAuthenticationTicket();
static bool IsExternalLauncher();
struct Win64LaunchOptions
{
int screenMode;
bool fullscreen;
bool username;
bool token;
};
};