Skip to Content
文件帳號與多語言

帳號與多語言

先閱讀 SDK 可用性與錯誤處理。以下範例使用宿主注入的全域物件,遊戲不需要索取帳號憑證。

玩家主動操作後登入

在需要帳號的操作前呼叫 checkSession()。若回傳 false,由玩家主動操作觸發 login(),登入介面由宿主管理。cancelled 是正常的使用者選擇;訊息傳輸、彈出視窗或帳號資料同步失敗則會拒絕 Promise。

收到 success 後直接繼續目前操作,不需要重新整理、輪詢或再次檢查這次操作的登入狀態。下一次獨立操作再重新檢查。請求進行中應停用發起按鈕。

<button id="player-button">Show player</button> <output id="player-info" aria-live="polite"></output>
async function readPlayerAfterClick() { const sdk = window.combos; if (!sdk) return null; const { methods } = await sdk.init(); if (!methods.includes("getUserInfo")) return null; if (!(await sdk.checkSession())) { const result = await sdk.login(); if (result.status !== "success") return null; } return sdk.getUserInfo(); } const button = document.querySelector<HTMLButtonElement>("#player-button"); const output = document.querySelector<HTMLOutputElement>("#player-info"); button?.addEventListener("click", async () => { if (!output) return; button.disabled = true; try { const player = await readPlayerAfterClick(); output.textContent = player ? player.nickName || "Player" : "Player information is unavailable."; } catch { output.textContent = "Unable to read player information. Please try again."; } finally { button.disabled = false; } });

範例按鈕與提示是遊戲內的示範文字,可依遊戲語言調整。輔助函式在能力缺少或登入取消時回傳 null,真正的失敗交由點擊處理函式捕捉。

讀取玩家資訊

getUserInfo() 不接收參數,在登入狀態檢查通過或登入成功後呼叫。未登入時以 session_required 拒絕請求。

欄位含義
appId目前遊戲的應用程式識別碼
openId玩家在該應用程式內的身分識別碼
nickName顯示暱稱,可能為空字串
avatarUrl頭像網址,可能為空字串
locale玩家已儲存的公開產品語言,如 en、zh-CN;未儲存時為目前產品語言

為缺少的顯示資訊提供預設值。應用程式內身分應維持其應用範圍,不要把這份顯示資料當作自有後端的憑證或授權證明。結果不包含平台使用者 ID、電子郵件或雲端能力工作階段。

翻譯已顯示的遊戲文字

先顯示原文,再請求翻譯。sourceLocale 代表原文語言,而非想要的目標語言;目標語言由宿主目前的產品語言決定。sourceTexts 傳入完整原文字串或範本,翻譯結果也以相同原文作為 key。

<button data-source-text="Play"></button> <button data-source-text="Pause"></button>
async function localizeLabels() { const nodes = [...document.querySelectorAll<HTMLElement>("[data-source-text]")]; const sourceTexts = nodes.map(node => node.dataset.sourceText ?? ""); nodes.forEach((node, index) => { node.textContent = sourceTexts[index]; }); const sdk = window.combos; if (!sdk) return; try { const { methods } = await sdk.init(); if (!methods.includes("requestI18n")) return; const result = await sdk.requestI18n({ sourceLocale: "en", sourceTexts }); if (!result.needed) return; nodes.forEach((node, index) => { const source = sourceTexts[index]; node.textContent = result.translations[source] || source; }); } catch { // Keep the source copy on screen. } } void localizeLabels();

結果為 { needed: false } 或 { needed: true, locale, translations }。不需翻譯、缺少 key、宿主不支援或請求失敗時都保留原文。SDK 收到無效結果時也會退回 needed: false。以純文字方式顯示譯文,不要插入原始 HTML。動態數值應在固定範本翻譯完成後再填入;修改範例的英文原文時,也要更新 sourceLocale。

選用雲端能力介面參考

目前 Web 宿主不宣告以下四個方法。 只有 init().methods 明確包含對應方法時才能使用。這份介面契約不代表發布遊戲後就自動取得 AI 能力。

type Authorization = { decision: "AUTHORIZATION_DECISION_GRANTED" | "AUTHORIZATION_DECISION_DENIED"; decidedAtMs: number; }; type AuthSetting = Partial<Record<"ai_model", Authorization>>; type CloudAbilitySession = { session: string; expiresAtMs: number };
方法參數與結果
getSetting()無參數,回傳 AuthSetting;缺少某項代表尚未詢問過
authorize({ scope: "ai_model" })宿主管理授權視窗,回傳 Authorization
openSetting()無參數,開啟宿主設定並回傳 AuthSetting
getCloudAbilitySession()無參數,回傳短期 CloudAbilitySession

AUTHORIZATION_DECISION_DENIED 是正常授權結果,不是傳輸失敗。不要寫入 UNSPECIFIED 零值。時間單位為毫秒,不要向這些方法傳送使用者、裝置或遊戲 ID。回傳的工作階段僅保留在記憶體,遵守 expiresAtMs,遊玩結束即捨棄,不放入持久化儲存、日誌或 URL。

Last updated on