Repository navigation
fix: warn instead of block on unverified Minecraft ownership, and explain the login 400 - #3
Merged
Conversation
Signing in with a Microsoft account that has never bought Minecraft previously threw NotPurchasedMinecraftException and aborted the login with an error the user could not act on. The ownership check itself is unchanged and still runs; only its failure handling changes. - verifyGameOwnership() now returns whether an entitlement was found instead of throwing. microsoftAuthAsync() uses that to fall back to an offline identity, built from the Xbox gamertag carried on the XSTS response, when no entitlement exists. The selected instance still launches. - Account gains ownsMinecraft, persisted via a new Room migration, so the state survives restarts. The account list shows an "ownership unverified" hint, and skin/cape fetches are skipped because no official profile exists to read from. - Login reports the situation as a notice rather than an error. Offline play is unaffected. Online play is not unlocked by this change and cannot be, because official servers perform their own ownership check on every connection. Also surface the real cause of the Microsoft login 400. A build with no oauth_client_id sends an empty client_id and Azure answers 400 AADSTS900144, which the launcher presented as "(400) The server could not understand the request". fetchDeviceCodeResponse() now detects the missing ID up front and says so, pointing at gradle.properties, the git-ignored .oauth_client_id.txt, and the OAUTH_CLIENT_ID CI secret. README: document the non-blocking ownership behaviour, the three account types, and how to register an Azure app to enable Microsoft sign-in. Co-authored-by: openhands <openhands@all-hands.dev>
Owner
Author
CI build result
Artifact: All Kotlin changes in this PR (account model, Room migration, authenticator, viewmodel, Compose UI, and the three
This comment was posted by an AI agent (OpenHands) on behalf of the user. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Follow-up to #2 (already merged). Two account-flow bugs, both reported by users.
1. Unverified Minecraft ownership blocked the login
An account that signs in successfully but has never bought Minecraft hit
NotPurchasedMinecraftExceptionand the login aborted with a message the user could not act on.The ownership check is not removed and still runs exactly as upstream intends. Only its failure
handling changed:
verifyGameOwnership()returns whether an entitlement was found, instead of throwing.microsoftAuthAsync()uses that to fall back to an offline identity, built from the Xbox gamertagcarried on the XSTS response. The selected instance still launches.
Account.ownsMinecraftis persisted via a new Room migration, so the state survives restarts. The accountlist shows an "ownership unverified" hint, and skin/cape fetches are skipped because there is no official
profile to read from.
Offline play works. Online play is not unlocked and cannot be — official servers run their own ownership
check on every connection. No client-side change can alter that, and this PR does not try to bypass it.
2. Microsoft login failed with "(400) the server could not understand the request"
Root cause confirmed empirically: a build with no
oauth_client_idsends an emptyclient_idto thedevice-code endpoint, and Azure answers
which
ResponseException.toLocal()rendered as the unhelpful(400) The server could not understand the request.fetchDeviceCodeResponse()now detects the missing ID up front and states the real cause, pointing atgradle.properties, the git-ignored.oauth_client_id.txt, and theOAUTH_CLIENT_IDCI secret. An OAuthclient ID belongs to whoever ships the build — upstream's is not reusable by a fork — so this cannot be
"fixed" in code; it has to be configured.
README
Documented the non-blocking ownership behaviour, the three account types, and step-by-step Azure app
registration to enable Microsoft sign-in.
Verification
No JDK/Android SDK in this environment, so CI is the check.
build.ymlalready builds APKs onpull_request;this PR should produce an artifact the way #2 did. Changes are compile-checked by the
build (all)job.New strings added to
values,values-zh-rCNandvalues-zh-rTW(all three XML files validate, no duplicatekeys).
This pull request was created by an AI agent (OpenHands) on behalf of the user.
@ChimeraAnt-DEV can click here to continue refining the PR