Capabilities

VERIFY_GAME_CREDENTIALS

Linking a game account to a master account

How a player proves the game account they are linking is theirs. Nothing can be delivered to a player who has not linked one, which is why this is a required capability.

ResultMeaning
VALIDAccount exists, is enabled, and the password matches
INVALID_CREDENTIALSThe account exists but the password does not match
NO_SUCH_ACCOUNTNo account of that name — optional, see below
ACCOUNT_DISABLEDAccount exists but is banned or disabled
TEMPORARY_FAILUREThe operation could not be completed

Read the account through a parameterised query. Never log, store or return the supplied password.

The column does not hold a password

On every pack, that column holds a transform of what the player typed. Comparing it as text cannot verify anyone — and on a pack where the column was once edited by hand it does something worse: it accepts a password the game itself refuses, so the portal and the login screen disagree about the same account.

Implementing it

String verifyCredentials(String accountName, String password) throws Exception;

Apply the hash your login server applies, then compare. The two reference implementations differ:

  • aCis 409 — bcrypt, through BCrypt.checkPw.
  • Mobius — SHA-1 over the UTF-8 bytes, Base64 encoded. It is worth reading LoginController#retriveAccountInfo in your own source rather than trusting this line, because it is the only place the real answer lives.

Treat a negative access level as ACCOUNT_DISABLED rather than a wrong password: a banned player retyping their password forever is a support ticket you do not need.

Telling a missing account apart

NO_SUCH_ACCOUNT is optional — answering INVALID_CREDENTIALS for both is always correct. It exists so an owner can see that their query is pointed at the wrong database.

Players are never told which one it was

Forgeport collapses NO_SUCH_ACCOUNT into INVALID_CREDENTIALS on every player-facing response. A login form that answers the two differently is a way to discover which account names exist on the server, so the distinction is visible only in Connector check, which an owner runs against their own server. If you surface credential outcomes anywhere else yourself, collapse them the same way.

Verification

Connector check submits an account that cannot exist and expects a clean rejection. If you supply a test account name it repeats the call with a password that cannot be right, which answers a different question: whether the query is reading a database where your accounts actually are. Nothing is written and your auth daemon is never involved — it is the same SELECT the connector already runs, so no login counter moves.

Neither proves the transform is right. Only a real login does; see CREATE_GAME_ACCOUNT for the one test that covers the whole chain.

On this page