From 6a8e00cc852af59f11ab189913f1b60dc708b257 Mon Sep 17 00:00:00 2001 From: Tau Date: Mon, 26 Nov 2018 17:07:51 -0500 Subject: [PATCH] Add encoder layer to aimedb --- src/aimedb.js | 86 ++++++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 75 insertions(+), 11 deletions(-) diff --git a/src/aimedb.js b/src/aimedb.js index 4cca1fc..5c63f93 100644 --- a/src/aimedb.js +++ b/src/aimedb.js @@ -3,7 +3,7 @@ const { Transform, pipeline } = require('stream') const K = Buffer.from('Copyright(C)SEGA', 'utf8') -class Decoder extends Transform { +class Deframer extends Transform { constructor(options) { super({ readableObjectMode: true, @@ -43,7 +43,71 @@ class Decoder extends Transform { } } +class Decoder extends Transform { + constructor(options) { + super({ + readableObjectMode: true, + writableObjectMode: true, + ...options, + }) + } + + static ident(payload) { + const gameId = payload.toString('ascii', 2, 6) + const keychipId = payload.toString('ascii', 12, 23) + + return { gameId, keychipId } + } + + _transform(chunk, encoding, callback) { + const { cmd, payload } = chunk + + switch (cmd) { + case 0x0064: + return callback(null, { + cmd: 'hello', + ...Decoder.ident(payload) + }) + + case 0x0066: + return callback(null, { + cmd: 'goodbye', + }) + + default: + return callback(new Error(`Unknown AimeDB command ${cmd}`)) + } + } +} + class Encoder extends Transform { + constructor(options) { + super({ + readableObjectMode: true, + writableObjectMode: true, + ...options, + }) + } + + _transform(chunk, encoding, callback) { + console.log('Aimedb: Encode', chunk) + + let payload + + switch (chunk.cmd) { + case 'hello': + payload = Buffer.alloc(24) + payload.writeInt16LE(chunk.status) + + return callback(null, { cmd: 0x0065, payload }) + + default: + return callback(newError(`Unimplemented response: ${cmd}`)) + } + } +} + +class Framer extends Transform { constructor(options) { super({ writableObjectMode: true, @@ -79,14 +143,15 @@ async function dispatch(socket) { crypto .createDecipheriv('aes-128-ecb', K, null) .setAutoPadding(false), + new Deframer(), new Decoder(), ) - const output = new Encoder() pipeline( output, + new Framer(), crypto .createCipheriv('aes-128-ecb', K, null) .setAutoPadding(false), @@ -95,26 +160,25 @@ async function dispatch(socket) { try { for await (const req of input) { + console.log('Aimedb: Decode', req) + + const { cmd } = req let payload - switch (req.cmd) { - case 0x0064: + switch (cmd) { + case 'hello': console.log('Aimedb: Hello') - - payload = Buffer.alloc(24) - payload.writeInt16LE(0x0001, 0) - - output.write({ cmd: 0x0065, payload }) + output.write({ cmd, status: 1 }) break - case 0x0066: + case 'goodbye': console.log('Aimedb: Goodbye') break default: - console.log('Aimedb: Unknown command', req.cmd) + console.log('Aimedb: Handler not implemented!') break }