fix(config): restore legacy gameserver and urlserver contract

This commit is contained in:
2026-09-05 01:25:50 +08:00
parent f25211c64e
commit d1ad63983b
16 changed files with 622 additions and 383 deletions
@@ -1,57 +1,41 @@
import { readFileSync } from 'node:fs';
import { test } from 'node:test';
import assert from 'node:assert/strict';
import { getParam, resolveServers, type RemoteConfig } from '../../YouleNexus/assets/framework/config/remote-config.ts';
import type { ChannelIdentity } from '../../YouleNexus/assets/framework/config/identity.ts';
import { parseUrlServers } from '../../YouleNexus/assets/framework/config/remote-config.ts';
const ID: ChannelIdentity = { agentid: 'A', channelid: 'C', gameid: 'G', marketid: 2, version: 1 };
const single = JSON.parse(readFileSync(
new URL('../fixtures/contracts/remote-config-single.json', import.meta.url),
'utf8',
)) as unknown;
const array = JSON.parse(readFileSync(
new URL('../fixtures/contracts/remote-config-array.json', import.meta.url),
'utf8',
)) as unknown;
const CONFIG: RemoteConfig = {
data: {
player_server_tcp: '1.1.1.1:1000', // 顶层默认
agentlist: [{
agentid: 'A',
player_server_tcp: '2.2.2.2:2000', // agent 级覆盖
gamelist: [{
gameid: 'G',
channellist: [{
channelid: 'C',
player_server_tcp: '3.3.3.3:3000', // channel 级覆盖(最具体)
visitor_server_tcp: '4.4.4.4:4000',
marketlist: [{ marketid: 2 }],
}],
}],
}],
},
};
test('getParam:最具体层级胜出', () => {
assert.equal(getParam(CONFIG, 'player_server_tcp', ID), '3.3.3.3:3000');
test('parseUrlServers:读取 data.urlserver 字符串并补 ws://', () => {
assert.deepEqual(parseUrlServers(single), ['ws://10.0.0.1:3088']);
});
test('getParam:channel 未匹配时回退到 agent 级值', () => {
const id2 = { ...ID, channelid: 'OTHER' };
assert.equal(getParam(CONFIG, 'player_server_tcp', id2), '2.2.2.2:2000');
test('parseUrlServers:读取 data.urlserver 数组并保留已有 wss://', () => {
assert.deepEqual(parseUrlServers(array), ['ws://10.0.0.1:3088', 'wss://backup.example/ws']);
});
test('getParam:agent 未匹配时回退到顶层默认', () => {
const id3 = { ...ID, agentid: 'NONE' };
assert.equal(getParam(CONFIG, 'player_server_tcp', id3), '1.1.1.1:1000');
test('parseUrlServers:拒绝旧的 *_server_tcp 字段', () => {
assert.throws(
() => parseUrlServers({ data: { player_server_tcp: 'wrong:1' } }),
/data\.urlserver/,
);
});
test('getParam:键不存在 → null', () => {
assert.equal(getParam(CONFIG, 'not_a_key', ID), null);
test('parseUrlServers:保留原顺序和重复项,并冻结结果', () => {
const servers = parseUrlServers({ data: { urlserver: ['same:1', 'same:1', 'ws://last:2'] } });
assert.deepEqual(servers, ['ws://same:1', 'ws://same:1', 'ws://last:2']);
assert.equal(Object.isFrozen(servers), true);
});
test('getParam:无 data → null', () => {
assert.equal(getParam({}, 'player_server_tcp', ID), null);
});
test('resolveServers:player 优先、visitor 回退,前缀 ws://', () => {
assert.deepEqual(resolveServers(CONFIG, ID), ['ws://3.3.3.3:3000', 'ws://4.4.4.4:4000']);
});
test('resolveServers:已带 ws:// 不重复前缀;无地址 → 空数组', () => {
const cfg: RemoteConfig = { data: { player_server_tcp: 'ws://9.9.9.9:9' } };
assert.deepEqual(resolveServers(cfg, ID), ['ws://9.9.9.9:9']);
assert.deepEqual(resolveServers({ data: {} }, ID), []);
test('parseUrlServers:拒绝空字符串、空数组和非字符串数组项', () => {
assert.throws(() => parseUrlServers({ data: { urlserver: '' } }), /data\.urlserver/);
assert.throws(() => parseUrlServers({ data: { urlserver: [] } }), /data\.urlserver/);
assert.throws(() => parseUrlServers({ data: { urlserver: ['ok:1', ''] } }), /data\.urlserver/);
assert.throws(() => parseUrlServers({ data: { urlserver: ['ok:1', 2] } }), /data\.urlserver/);
});