feat(platform): expose restricted game host and commands
This commit is contained in:
@@ -1,10 +1,16 @@
|
||||
import assert from 'node:assert/strict';
|
||||
import { readFileSync } from 'node:fs';
|
||||
import { test } from 'node:test';
|
||||
import type { RuntimeConfig } from '../../YouleNexus/assets/framework/config/runtime-config.ts';
|
||||
import type { OutboundEnvelope } from '../../YouleNexus/assets/framework/core/types/envelope.ts';
|
||||
import { createGameHostAdapter } from '../../YouleNexus/assets/framework/platform/game-host-adapter.ts';
|
||||
import { PlatformCommands } from '../../YouleNexus/assets/framework/platform/commands.ts';
|
||||
import { PlatformStore } from '../../YouleNexus/assets/framework/platform/stores/platform-store.ts';
|
||||
import { parseLoginResponse } from '../../YouleNexus/assets/framework/protocol/contracts/index.ts';
|
||||
import type {
|
||||
GameEntry,
|
||||
GameHost,
|
||||
GameModule,
|
||||
PlatformGameSnapshot,
|
||||
} from '../../YouleNexus/assets/framework/sdk/contracts/index.ts';
|
||||
import {
|
||||
assertGameContract,
|
||||
@@ -29,13 +35,26 @@ test('assertGameContract runs the reusable isolated session conformance suite',
|
||||
|
||||
assert.doesNotThrow(() => assertGameContract(
|
||||
entry,
|
||||
makeConformanceHost(() => { invalidations++; }, restoredDeskinfo),
|
||||
makeConformanceHost(entry, () => { invalidations++; }, restoredDeskinfo),
|
||||
));
|
||||
assert.equal(invalidations, 2);
|
||||
assert.equal(restoredDeskinfo.length, 0);
|
||||
assert.ok(nextModuleId >= 2);
|
||||
});
|
||||
|
||||
const RUNTIME_CONFIG: RuntimeConfig = Object.freeze({
|
||||
mode: 'release',
|
||||
isDebugger: false,
|
||||
identity: Object.freeze({
|
||||
agentid: 'fixture-agent', channelid: 'fixture-channel', gameid: '41',
|
||||
marketid: 'fixture-market', version: 41,
|
||||
}),
|
||||
servers: Object.freeze(['ws://fixture']),
|
||||
source: 'remote',
|
||||
gameserver: 'https://fixture/config',
|
||||
rawConfig: Object.freeze({ data: Object.freeze({ urlserver: 'fixture' }) }),
|
||||
});
|
||||
|
||||
function makeModule(id: number, onRestore: (deskinfo: unknown) => void): GameModule {
|
||||
let host: GameHost | undefined;
|
||||
let restored: unknown;
|
||||
@@ -77,25 +96,29 @@ function deskinfoFor(cycle: number): { readonly cycle: number } {
|
||||
}
|
||||
|
||||
function makeConformanceHost(
|
||||
entry: GameEntry,
|
||||
onInvalidate: () => void,
|
||||
restoredDeskinfo: unknown[],
|
||||
): () => GameContractHost {
|
||||
return () => {
|
||||
const snapshot: PlatformGameSnapshot = {
|
||||
connection: { phase: 'connected' },
|
||||
self: { playerId: 1, seat: 0 },
|
||||
room: { roomcode: 'fixture', roomtype: [], stage: 0, needprepare: 0, infinite: 0 },
|
||||
seats: [],
|
||||
};
|
||||
const login = JSON.parse(readFileSync(
|
||||
new URL('../fixtures/contracts/player-login-room.json', import.meta.url),
|
||||
'utf8',
|
||||
)) as { data: Record<string, unknown> };
|
||||
login.data.roomtype = [4];
|
||||
login.data.isbattle = 0;
|
||||
const store = new PlatformStore();
|
||||
store.applyLoginSuccess(parseLoginResponse(login.data));
|
||||
const sent: OutboundEnvelope[] = [];
|
||||
const send = { send: (envelope: OutboundEnvelope) => { sent.push(envelope); } };
|
||||
const commands = new PlatformCommands({ runtimeConfig: RUNTIME_CONFIG, store, send });
|
||||
const lease = createGameHostAdapter({ gameEntry: entry, store, commands, send });
|
||||
return {
|
||||
host: {
|
||||
seat: { toView: (seat) => seat, toServer: (seat) => seat },
|
||||
getSnapshot: () => snapshot,
|
||||
subscribe: () => () => {},
|
||||
sendGameMessage: () => {},
|
||||
execute: () => {},
|
||||
host: lease.host,
|
||||
invalidate() {
|
||||
lease.invalidate();
|
||||
onInvalidate();
|
||||
},
|
||||
invalidate: onInvalidate,
|
||||
assertRestored(deskinfo) {
|
||||
assert.equal(restoredDeskinfo.shift(), deskinfo);
|
||||
},
|
||||
|
||||
Reference in New Issue
Block a user