60 lines
3.1 KiB
JavaScript
60 lines
3.1 KiB
JavaScript
'use strict';
|
|
|
|
const test = require('node:test');
|
|
const assert = require('node:assert/strict');
|
|
const net = require('net');
|
|
const { createPs5DebugReadonlyClient, bitPairSwap32, firmwareString, COMMANDS, PACKET_MAGIC, CMD_SUCCESS } = require('../../src/services/ps5debug-readonly-client');
|
|
|
|
test('ps5debug client sends only the five allowlisted read-only commands', async () => {
|
|
const seen = [];
|
|
const server = net.createServer(socket => {
|
|
let pending = Buffer.alloc(0);
|
|
socket.on('data', chunk => {
|
|
pending = Buffer.concat([pending, chunk]);
|
|
while (pending.length >= 12) {
|
|
const header = pending.subarray(0, 12); pending = pending.subarray(12);
|
|
assert.equal(header.readUInt32LE(0), PACKET_MAGIC >>> 0);
|
|
assert.equal(header.readUInt32LE(8), 0);
|
|
const command = header.readUInt32LE(4); seen.push(command);
|
|
if ([COMMANDS.VERSION, COMMANDS.BRANDING].includes(command)) {
|
|
const text = Buffer.from(command === COMMANDS.VERSION ? '1.3' : 'ps5debug-NG test');
|
|
const length = Buffer.alloc(4); length.writeUInt32LE(text.length, 0); socket.write(Buffer.concat([length, text]));
|
|
} else if (command === COMMANDS.FW_VERSION) {
|
|
const value = Buffer.alloc(2); value.writeUInt16LE(751, 0); socket.write(value);
|
|
} else if (command === COMMANDS.PLATFORM_ID) {
|
|
const value = Buffer.alloc(2); value.writeUInt16LE(5, 0); socket.write(value);
|
|
} else if (command === COMMANDS.FOREGROUND_APP) {
|
|
const status = Buffer.alloc(4); status.writeUInt32LE(bitPairSwap32(CMD_SUCCESS), 0); socket.write(status);
|
|
const value = Buffer.alloc(140); value.writeUInt32LE(4242, 0);
|
|
value.write('PPSA00001', 4); value.write('EP0000-PPSA00001_00-TEST', 20); value.write('eboot.bin', 84); value.write('01.23', 124); socket.write(value);
|
|
}
|
|
}
|
|
});
|
|
});
|
|
await new Promise(resolve => server.listen(0, '127.0.0.1', resolve));
|
|
try {
|
|
const port = server.address().port;
|
|
const client = createPs5DebugReadonlyClient({
|
|
settings: { get: key => key === 'ftp.host' ? '127.0.0.1' : '' }, port, timeoutMs: 1_000,
|
|
db: { getGame: id => id === 'PPSA00001' ? { title: 'Test Game', prospero_icon_url: '/icon.webp', version: '1.23' } : null },
|
|
});
|
|
const packet = await client.query();
|
|
assert.equal(packet.online, true);
|
|
assert.equal(packet.protocol, '1.3');
|
|
assert.equal(packet.firmware, '7.51');
|
|
assert.equal(packet.platform, 5);
|
|
assert.equal(packet.foreground.titleId, 'PPSA00001');
|
|
assert.equal(packet.foreground.game.title, 'Test Game');
|
|
assert.deepEqual(seen, [COMMANDS.VERSION, COMMANDS.BRANDING, COMMANDS.FW_VERSION, COMMANDS.PLATFORM_ID, COMMANDS.FOREGROUND_APP]);
|
|
assert.equal(packet.policy.memoryRead, false);
|
|
assert.equal(packet.policy.memoryWrite, false);
|
|
assert.equal(packet.policy.kernelAccess, false);
|
|
} finally { await new Promise(resolve => server.close(resolve)); }
|
|
});
|
|
|
|
test('firmware and status bit transforms are deterministic', () => {
|
|
assert.equal(firmwareString(505), '5.05');
|
|
assert.equal(firmwareString(960), '9.60');
|
|
assert.equal(bitPairSwap32(bitPairSwap32(CMD_SUCCESS)), CMD_SUCCESS);
|
|
});
|