diff --git a/cocoscreator_projects/YouleNexus/assets/framework/protocol/login.ts b/cocoscreator_projects/YouleNexus/assets/framework/protocol/login.ts new file mode 100644 index 0000000..ba9c71c --- /dev/null +++ b/cocoscreator_projects/YouleNexus/assets/framework/protocol/login.ts @@ -0,0 +1,29 @@ +import type { LoginRequestData, LoginResponseData } from '../core/types/login.ts'; + +/** 构造 player_login 请求 data。字段以 docs/protocol/01 §6、02 为准。 */ +export function buildLoginRequest(identity: LoginRequestData): LoginRequestData { + return { ...identity }; +} + +export interface ParsedLogin { + ok: boolean; // state===0 + playerid: number; + inRoom: boolean; // 含 roomcode → 需恢复房间 + hasBattle: boolean; // isbattle===1 或含 deskinfo → 需重连对局 + deskinfo: unknown; // 子游戏对局快照(原样透传,见 docs/protocol/05) + raw: LoginResponseData; +} + +/** 解析 player_login 响应(最小集)。完整字段见 docs/protocol/04。 */ +export function parseLoginResponse(data: LoginResponseData): ParsedLogin { + const roomcode = (data as any).roomcode; + const deskinfo = (data as any).deskinfo; + return { + ok: data.state === 0, + playerid: data.playerid, + inRoom: roomcode != null && roomcode !== '', + hasBattle: (data as any).isbattle === 1 || deskinfo != null, + deskinfo, + raw: data, + }; +} diff --git a/cocoscreator_projects/YouleNexus/assets/framework/protocol/routes.ts b/cocoscreator_projects/YouleNexus/assets/framework/protocol/routes.ts new file mode 100644 index 0000000..bb9452a --- /dev/null +++ b/cocoscreator_projects/YouleNexus/assets/framework/protocol/routes.ts @@ -0,0 +1,9 @@ +import { Route } from '../core/constants.ts'; +export { Route }; +/** 平台层会用到的 rpc 名(最小集)。完整清单见 docs/protocol/02、03。 */ +export const Rpc = { + player_login: 'player_login', + kick_server: 'kick_server', + connect_roomserver: 'connect_roomserver', + connect_agentserver: 'connect_agentserver', +} as const; diff --git a/cocoscreator_projects/framework-tests/protocol/login.test.ts b/cocoscreator_projects/framework-tests/protocol/login.test.ts new file mode 100644 index 0000000..f04fced --- /dev/null +++ b/cocoscreator_projects/framework-tests/protocol/login.test.ts @@ -0,0 +1,32 @@ +import { test } from 'node:test'; +import assert from 'node:assert/strict'; +import { buildLoginRequest, parseLoginResponse } from '../../YouleNexus/assets/framework/protocol/login.ts'; + +const IDENTITY = { agentid: 1, gameid: 2, openid: 'o', nickname: 'n', avatar: 'a', sex: 1, province: 'p', city: 'c', unionid: 'u', version: '1.0', channelid: 7, marketid: 9 }; + +test('buildLoginRequest 透传必备身份字段', () => { + const d = buildLoginRequest(IDENTITY); + assert.equal(d.agentid, 1); + assert.equal(d.openid, 'o'); + assert.equal(d.marketid, 9); +}); + +test('parseLoginResponse 提取核心字段 + 房间恢复标志', () => { + const r = parseLoginResponse({ state: 0, playerid: 9, bean: 100, roomcode: 'ABCD', isbattle: 1, deskinfo: { x: 1 } }); + assert.equal(r.ok, true); + assert.equal(r.playerid, 9); + assert.equal(r.inRoom, true); + assert.equal(r.hasBattle, true); + assert.deepEqual(r.deskinfo, { x: 1 }); +}); + +test('parseLoginResponse:无 roomcode 时不在房间', () => { + const r = parseLoginResponse({ state: 0, playerid: 9 }); + assert.equal(r.inRoom, false); + assert.equal(r.hasBattle, false); +}); + +test('parseLoginResponse:state!=0 视为失败', () => { + const r = parseLoginResponse({ state: 1, playerid: -1 }); + assert.equal(r.ok, false); +});