Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 14 additions & 0 deletions src/command_handler.h
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ namespace globals
extern bool g_FirstLogin;
extern std::string g_TrustToken;
extern bool g_TrustThisComputer;
extern std::string g_LoginToken;
} // namespace globals

#include "defines.h"
Expand Down Expand Up @@ -161,6 +162,19 @@ bool handleLoginCommand(int8_t command, json& login_reply_json, uint32_t& accoun
return false;
}

// LOGIN_ERROR_LAUNCH_TOKEN_INVALID
case 0x0014:
{
// Single-use and short-lived; invalid means it was already used or expired.
globals::g_LoginToken.clear();
xiloader::console::output(xiloader::color::error, "==========================================================");
xiloader::console::output(xiloader::color::error, "Launch token invalid or expired (session expired).");
xiloader::console::output(xiloader::color::error, "Please log in again from the launcher.");
xiloader::console::output(xiloader::color::error, "==========================================================");

return false;
}

// LOGIN_SUCCESS_CREATE_TOTP
case 0x0010:
{
Expand Down
10 changes: 8 additions & 2 deletions src/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ namespace globals
bool g_FirstLogin = false; // set to true when --user --pass are both set to allow for autologin
std::string g_TrustToken = ""; // trust token loaded from disk or received from server
bool g_TrustThisComputer = false; // user checkbox / CLI flag for "trust this computer"
std::string g_LoginToken = ""; // single-use launch token from the launcher; sent in place of password + OTP

char* g_CharacterList = NULL; // Pointer to the character list data being sent from the server.
bool g_IsRunning = false; // Flag to determine if the network threads should hault.
Expand Down Expand Up @@ -569,8 +570,13 @@ int __cdecl main(int argc, char* argv[])
globals::g_Username = maybeUsername.value_or(globals::g_Username);
globals::g_Password = maybePassword.value_or(globals::g_Password);

// Set autologin if it isn't set already
if (maybeUsername.has_value() && maybePassword.has_value())
// Optional single-use launch token; sent in place of password + OTP.
globals::g_LoginToken = jsonGet<std::string>(jsonData, "login_token").value_or(globals::g_LoginToken);

// A launch-token boot has a username + token but no password, so
// it also enables autologin.
if (maybeUsername.has_value() &&
(maybePassword.has_value() || !globals::g_LoginToken.empty()))
{
globals::g_FirstLogin = true;
}
Expand Down
10 changes: 9 additions & 1 deletion src/network.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ namespace globals
extern bool g_FirstLogin;
extern std::string g_TrustToken;
extern bool g_TrustThisComputer;
extern std::string g_LoginToken;
}

// mbed tls state
Expand Down Expand Up @@ -493,10 +494,17 @@ namespace xiloader
login_json["version"] = globals::g_VersionNumber;
login_json["command"] = command;

if (command == 0x10) // Only send trust fields for login
if (command == 0x10) // Only send trust/launch fields for login
{
login_json["trust_token"] = globals::g_TrustToken;
login_json["trust_this_computer"] = globals::g_TrustThisComputer;

// Optional single-use launch token; xi_connect consumes it in place
// of password + OTP (password may be empty).
if (!globals::g_LoginToken.empty())
{
login_json["login_token"] = globals::g_LoginToken;
}
}

std::string str = login_json.dump();
Expand Down