major refactor: auth v3

This commit is contained in:
Matthew Toro 2026-04-06 02:33:39 -04:00
parent 8a8b4b2573
commit 179d21d7b6
18 changed files with 376 additions and 166 deletions

View file

@ -48,7 +48,16 @@ shared_ptr<AuthPacket> HandshakeManager::handlePacket(const shared_ptr<AuthPacke
shared_ptr<AuthPacket> HandshakeManager::createInitialPacket()
{
state = HandshakeState::VERSION_SENT;
return makePacket(AuthStage::ANNOUNCE_VERSION, {{L"version", PROTOCOL_VERSION}});
wstring schemes;
for (const auto &[name, mod] : modules)
{
if (!schemes.empty()) schemes += L",";
schemes += name;
}
return makePacket(AuthStage::ANNOUNCE_VERSION, {
{L"version", PROTOCOL_VERSION},
{L"schemes", schemes}
});
}
shared_ptr<AuthPacket> HandshakeManager::handleServer(const shared_ptr<AuthPacket> &packet)
@ -61,11 +70,32 @@ shared_ptr<AuthPacket> HandshakeManager::handleServer(const shared_ptr<AuthPacke
if (protocolVersion != PROTOCOL_VERSION)
return fail();
// Pick first registered module as the scheme
if (modules.empty())
return fail();
activeModule = modules.begin()->second.get();
auto splitCsv = [](const wstring &s) {
vector<wstring> out;
for (size_t p = 0; p < s.size(); ) {
size_t c = s.find(L',', p);
if (c == wstring::npos) c = s.size();
out.push_back(s.substr(p, c - p));
p = c + 1;
}
return out;
};
auto supported = splitCsv(getField(packet->fields, L"schemes"));
activeModule = nullptr;
for (auto &[name, mod] : modules)
{
if (supported.empty() || std::find(supported.begin(), supported.end(), name) != supported.end())
{
activeModule = mod.get();
break;
}
}
if (!activeModule)
return fail();
state = HandshakeState::SCHEME_DECLARED;
return makePacket(AuthStage::DECLARE_SCHEME, {
{L"version", PROTOCOL_VERSION},
@ -133,6 +163,8 @@ shared_ptr<AuthPacket> HandshakeManager::handleClient(const shared_ptr<AuthPacke
protocolVersion = getField(packet->fields, L"version");
wstring scheme = getField(packet->fields, L"scheme");
app.DebugPrintf("AUTH CLIENT: DECLARE_SCHEME scheme=%ls\n", scheme.c_str());
if (protocolVersion != PROTOCOL_VERSION)
return fail();
@ -149,24 +181,39 @@ shared_ptr<AuthPacket> HandshakeManager::handleClient(const shared_ptr<AuthPacke
else
activeVariation = variations.empty() ? L"" : variations[0];
app.DebugPrintf("AUTH CLIENT: accepting variation=%ls\n", activeVariation.c_str());
state = HandshakeState::SCHEME_ACCEPTED;
return makePacket(AuthStage::ACCEPT_SCHEME, {{L"variation", activeVariation}});
}
case AuthStage::SCHEME_SETTINGS:
{
if (!activeModule)
return fail();
wstring serverId = getField(packet->fields, L"serverId");
wstring sessionEndpoint = getField(packet->fields, L"sessionEndpoint");
wstring joinUrlW = getField(packet->fields, L"joinUrl");
wstring scheme(activeModule->schemeName());
if (scheme == L"mcconsoles:session" && !accessToken.empty())
app.DebugPrintf("AUTH CLIENT: SCHEME_SETTINGS joinUrl=%ls serverId=%ls\n", joinUrlW.c_str(), serverId.c_str());
if (scheme == L"mcconsoles:session" && !accessToken.empty() && !joinUrlW.empty())
{
nlohmann::json body = {
{"accessToken", narrowStr(accessToken)},
{"selectedProfile", narrowStr(clientUid)},
{"serverId", narrowStr(serverId)}
};
auto resp = HttpClient::post(narrowStr(sessionEndpoint) + "/session/minecraft/join", body.dump());
if (resp.statusCode != 204)
string joinUrl = narrowStr(joinUrlW);
app.DebugPrintf("AUTH CLIENT: POSTing join to %s\n", joinUrl.c_str());
HttpResponse resp;
try {
resp = HttpClient::post(joinUrl, body.dump());
} catch (...) {
app.DebugPrintf("AUTH CLIENT: join POST threw exception\n");
return fail();
}
app.DebugPrintf("AUTH CLIENT: join POST status=%d\n", resp.statusCode);
if (resp.statusCode < 200 || resp.statusCode >= 300)
return fail();
}