Apply Prettier

This commit is contained in:
Tau
2019-11-06 17:28:29 -05:00
parent f667b6ee6e
commit 1337fc21f3
9 changed files with 480 additions and 400 deletions
+83 -76
View File
@@ -1,4 +1,4 @@
const { Transform } = require('stream')
const { Transform } = require("stream");
class Decoder extends Transform {
constructor(options) {
@@ -6,84 +6,91 @@ class Decoder extends Transform {
readableObjectMode: true,
writableObjectMode: true,
...options,
})
});
}
static ident(chunk) {
const gameId = chunk.toString('ascii', 0x000A, 0x000E)
const keychipId = chunk.toString('ascii', 0x0014, 0x001F)
const gameId = chunk.toString("ascii", 0x000a, 0x000e);
const keychipId = chunk.toString("ascii", 0x0014, 0x001f);
return { gameId, keychipId }
return { gameId, keychipId };
}
static cardId(chunk) {
const luid = chunk.slice(0x0020, 0x002A)
const luid = chunk.slice(0x0020, 0x002a);
return { luid, ...Decoder.ident(chunk) }
return { luid, ...Decoder.ident(chunk) };
}
static log(chunk) {
// idk what any of this stuff means yet
// field20 and field28 appear to be an aime id but that is all.
const field20 = chunk.readUInt32LE(0x20)
const field24 = chunk.readUInt32LE(0x24)
const field28 = chunk.readUInt32LE(0x28)
const field2C = chunk.readUInt32LE(0x2C)
const field30 = chunk.readUInt32LE(0x30)
const field34 = chunk.readUInt32LE(0x34)
const field38 = chunk.readUInt32LE(0x38)
const field3C = chunk.readUInt32LE(0x3C)
const field20 = chunk.readUInt32LE(0x20);
const field24 = chunk.readUInt32LE(0x24);
const field28 = chunk.readUInt32LE(0x28);
const field2C = chunk.readUInt32LE(0x2c);
const field30 = chunk.readUInt32LE(0x30);
const field34 = chunk.readUInt32LE(0x34);
const field38 = chunk.readUInt32LE(0x38);
const field3C = chunk.readUInt32LE(0x3c);
return {
field20, field24, field28, field2C, field30, field34, field38, field3C,
...Decoder.ident(chunk)
}
field20,
field24,
field28,
field2C,
field30,
field34,
field38,
field3C,
...Decoder.ident(chunk),
};
}
_transform(chunk, encoding, callback) {
const cmd = chunk.readUInt16LE(0x04)
const cmd = chunk.readUInt16LE(0x04);
switch (cmd) {
case 0x0005:
return callback(null, {
cmd: 'register',
cmd: "register",
...Decoder.cardId(chunk),
})
});
case 0x0009:
return callback(null, {
cmd: 'log',
cmd: "log",
...Decoder.log(chunk),
})
});
case 0x000B:
case 0x000b:
return callback(null, {
cmd: 'campaign',
cmd: "campaign",
...Decoder.ident(chunk),
})
});
case 0x000F:
case 0x000f:
return callback(null, {
cmd: 'lookup',
cmd: "lookup",
...Decoder.cardId(chunk),
})
});
case 0x0064:
return callback(null, {
cmd: 'hello',
...Decoder.ident(chunk)
})
cmd: "hello",
...Decoder.ident(chunk),
});
case 0x0066:
return callback(null, {
cmd: 'goodbye',
})
cmd: "goodbye",
});
default:
return callback(null, {
cmd: `unknown_${cmd}`,
})
});
}
}
}
@@ -94,78 +101,78 @@ class Encoder extends Transform {
readableObjectMode: true,
writableObjectMode: true,
...options,
})
});
}
static init(length) {
const buf = Buffer.alloc(length)
const buf = Buffer.alloc(length);
buf.writeUInt16LE(0xA13E, 0x0000) // Magic?
buf.writeUInt16LE(0x3087, 0x0002) // ???
buf.writeUInt16LE(length, 0x0006)
buf.writeUInt16LE(0xa13e, 0x0000); // Magic?
buf.writeUInt16LE(0x3087, 0x0002); // ???
buf.writeUInt16LE(length, 0x0006);
return buf
return buf;
}
_transform(chunk, encoding, callback) {
console.log('Aimedb: Encode', chunk)
console.log("Aimedb: Encode", chunk);
let buf
let buf;
switch (chunk.cmd) {
case 'hello':
buf = Encoder.init(0x0020)
buf.writeUInt16LE(0x0065, 0x0004) // cmd code
buf.writeUInt16LE(chunk.status, 0x0008)
case "hello":
buf = Encoder.init(0x0020);
buf.writeUInt16LE(0x0065, 0x0004); // cmd code
buf.writeUInt16LE(chunk.status, 0x0008);
break
break;
case 'campaign':
case "campaign":
// Still figuring this out...
buf = Encoder.init(0x0200)
buf.writeUInt16LE(0x000C, 0x0004) // cmd code
buf.writeUInt16LE(chunk.status, 0x0008)
buf = Encoder.init(0x0200);
buf.writeUInt16LE(0x000c, 0x0004); // cmd code
buf.writeUInt16LE(chunk.status, 0x0008);
// Campaign array starts at 0x20
// Element size is 0xA0
break
break;
case 'lookup':
case "lookup":
// -1 aime id means card is not registered
// register level does not seem to matter
buf = Encoder.init(0x0130)
buf.writeUInt16LE(0x0010, 0x0004) // cmd code
buf.writeUInt16LE(chunk.status, 0x0008)
buf.writeInt32LE(chunk.aimeId || -1, 0x0020)
buf.writeUInt8(Encoder.registerLevels[chunk.registerLevel], 0x0024)
buf = Encoder.init(0x0130);
buf.writeUInt16LE(0x0010, 0x0004); // cmd code
buf.writeUInt16LE(chunk.status, 0x0008);
buf.writeInt32LE(chunk.aimeId || -1, 0x0020);
buf.writeUInt8(Encoder.registerLevels[chunk.registerLevel], 0x0024);
break
break;
case 'register':
buf = Encoder.init(0x0030)
buf.writeUInt16LE(0x0006, 0x0004) // cmd code
buf.writeUInt16LE(chunk.status, 0x0008)
buf.writeInt32LE(chunk.aimeId, 0x0020)
case "register":
buf = Encoder.init(0x0030);
buf.writeUInt16LE(0x0006, 0x0004); // cmd code
buf.writeUInt16LE(chunk.status, 0x0008);
buf.writeInt32LE(chunk.aimeId, 0x0020);
break
break;
case 'log':
buf = Encoder.init(0x0020)
buf.writeUInt16LE(0x000A, 0x0004) // cmd code
buf.writeUInt16LE(chunk.status, 0x0008)
case "log":
buf = Encoder.init(0x0020);
buf.writeUInt16LE(0x000a, 0x0004); // cmd code
buf.writeUInt16LE(chunk.status, 0x0008);
break
break;
default:
return callback(new Error(`Unimplemented response: ${cmd}`))
return callback(new Error(`Unimplemented response: ${cmd}`));
}
console.log('Aimedb: Send', buf)
console.log("Aimedb: Send", buf);
return callback(null, buf)
return callback(null, buf);
}
}
@@ -173,9 +180,9 @@ Encoder.registerLevels = {
none: 0,
portal: 1,
segaid: 2,
}
};
module.exports = {
Decoder,
Encoder,
}
};
+100 -33
View File
@@ -1,47 +1,114 @@
const { Decoder } = require('./cmd')
const { Decoder } = require("./cmd");
function decode(req) {
const decoder = new Decoder()
const decoder = new Decoder();
decoder.write(req)
decoder.write(req);
return decoder.read()
return decoder.read();
}
test('decode hello', () => {
test("decode hello", () => {
const req = Buffer.from([
0x3e, 0xa1, 0x87, 0x30, 0x64, 0x00, 0x20, 0x00,
0x00, 0x00, 0x53, 0x44, 0x42, 0x54, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x41, 0x36, 0x39, 0x45,
0x30, 0x31, 0x41, 0x39, 0x39, 0x39, 0x39, 0x00,
])
0x3e,
0xa1,
0x87,
0x30,
0x64,
0x00,
0x20,
0x00,
0x00,
0x00,
0x53,
0x44,
0x42,
0x54,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0x41,
0x36,
0x39,
0x45,
0x30,
0x31,
0x41,
0x39,
0x39,
0x39,
0x39,
0x00,
]);
const obj = decode(req)
const obj = decode(req);
expect(obj.cmd).toBe('hello')
expect(obj.gameId).toBe('SDBT')
expect(obj.keychipId).toBe('A69E01A9999')
})
expect(obj.cmd).toBe("hello");
expect(obj.gameId).toBe("SDBT");
expect(obj.keychipId).toBe("A69E01A9999");
});
test('decode lookup', () => {
test("decode lookup", () => {
const req = Buffer.from([
0x3e, 0xa1, 0x87, 0x30, 0x0f, 0x00, 0x30, 0x00,
0x00, 0x00, 0x53, 0x44, 0x42, 0x54, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x41, 0x36, 0x39, 0x45,
0x30, 0x31, 0x41, 0x39, 0x39, 0x39, 0x39, 0x00,
0x01, 0x03, 0x64, 0x95, 0x85, 0x05, 0x23, 0x03,
0x06, 0x76, 0x01, 0x02, 0x22, 0xc6, 0x4e, 0x00,
])
0x3e,
0xa1,
0x87,
0x30,
0x0f,
0x00,
0x30,
0x00,
0x00,
0x00,
0x53,
0x44,
0x42,
0x54,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0x41,
0x36,
0x39,
0x45,
0x30,
0x31,
0x41,
0x39,
0x39,
0x39,
0x39,
0x00,
0x01,
0x03,
0x64,
0x95,
0x85,
0x05,
0x23,
0x03,
0x06,
0x76,
0x01,
0x02,
0x22,
0xc6,
0x4e,
0x00,
]);
const obj = decode(req)
const obj = decode(req);
expect(obj.cmd).toBe('lookup')
expect(obj.gameId).toBe('SDBT')
expect(obj.keychipId).toBe('A69E01A9999')
expect(obj.cmd).toBe("lookup");
expect(obj.gameId).toBe("SDBT");
expect(obj.keychipId).toBe("A69E01A9999");
expect(obj.luid).toEqual(
Buffer.from([
0x01, 0x03, 0x64, 0x95, 0x85, 0x05, 0x23, 0x03,
0x06, 0x76,
])
)
})
Buffer.from([0x01, 0x03, 0x64, 0x95, 0x85, 0x05, 0x23, 0x03, 0x06, 0x76])
);
});
+15 -15
View File
@@ -1,44 +1,44 @@
const { Transform } = require('stream')
const { Transform } = require("stream");
class Deframer extends Transform {
constructor(options) {
super({
readableObjectMode: true,
...options,
})
});
this.state = Buffer.alloc(0)
this.state = Buffer.alloc(0);
}
_transform(chunk, encoding, callback) {
this.state = Buffer.concat([ this.state, chunk ])
this.state = Buffer.concat([this.state, chunk]);
if (this.state.length < 8) {
return
return;
}
const magic = this.state.readUInt16LE(0x0000)
const magic = this.state.readUInt16LE(0x0000);
if (magic != 0xA13E) {
return callback(new Error(`Invalid magic (decimal ${magic})`))
if (magic != 0xa13e) {
return callback(new Error(`Invalid magic (decimal ${magic})`));
}
const len = this.state.readUInt16LE(0x0006)
const len = this.state.readUInt16LE(0x0006);
if (this.state.length < len) {
return
return;
}
const frame = this.state.slice(0, len)
const frame = this.state.slice(0, len);
console.log('Aimedb: Recv', frame)
console.log("Aimedb: Recv", frame);
this.state = this.state.slice(len)
this.state = this.state.slice(len);
return callback(null, frame)
return callback(null, frame);
}
}
module.exports = {
Deframer,
}
};
+34 -34
View File
@@ -1,66 +1,66 @@
const setup = require('./pipeline')
const setup = require("./pipeline");
async function aimedb(socket) {
console.log('Aimedb: Connection opened')
console.log("Aimedb: Connection opened");
const { input, output } = setup(socket)
const { input, output } = setup(socket);
try {
for await (const req of input) {
console.log('Aimedb: Decode', req)
console.log("Aimedb: Decode", req);
const { cmd } = req
const { cmd } = req;
switch (cmd) {
case 'hello':
console.log('Aimedb: Hello')
output.write({ cmd, status: 1 })
case "hello":
console.log("Aimedb: Hello");
output.write({ cmd, status: 1 });
break
break;
case 'campaign':
console.log('Aimedb: Campaign stuff')
output.write({ cmd, status: 1 })
case "campaign":
console.log("Aimedb: Campaign stuff");
output.write({ cmd, status: 1 });
break
break;
case 'lookup':
console.log('Aimedb: Mifare lookup', req.luid)
output.write({ cmd, status: 1 }) // Add aimeId if desired
case "lookup":
console.log("Aimedb: Mifare lookup", req.luid);
output.write({ cmd, status: 1 }); // Add aimeId if desired
break
break;
case 'register':
case "register":
// We get sent here if lookup does not return an aimeId
console.log('Aimedb: Mifare register', req.luid)
output.write({ cmd, status: 1, aimeId: 12345678 })
console.log("Aimedb: Mifare register", req.luid);
output.write({ cmd, status: 1, aimeId: 12345678 });
break
break;
case 'log':
console.log('Aimedb: Log message')
output.write({ cmd, status: 1 })
case "log":
console.log("Aimedb: Log message");
output.write({ cmd, status: 1 });
break
break;
case 'goodbye':
console.log('Aimedb: Goodbye')
case "goodbye":
console.log("Aimedb: Goodbye");
break
break;
default:
console.log('Aimedb: Handler not implemented!')
console.log("Aimedb: Handler not implemented!");
break
break;
}
}
} catch (e) {
console.log('Aimedb: Connection error:\n', e)
console.log("Aimedb: Connection error:\n", e);
}
console.log('Aimedb: Connection closed\n')
socket.end()
console.log("Aimedb: Connection closed\n");
socket.end();
}
module.exports = aimedb
module.exports = aimedb;
+14 -18
View File
@@ -1,32 +1,28 @@
const crypto = require('crypto')
const { pipeline } = require('stream')
const crypto = require("crypto");
const { pipeline } = require("stream");
const { Deframer } = require('./frame')
const { Decoder, Encoder } = require('./cmd')
const { Deframer } = require("./frame");
const { Decoder, Encoder } = require("./cmd");
const K = Buffer.from('Copyright(C)SEGA', 'utf8')
const K = Buffer.from("Copyright(C)SEGA", "utf8");
function setup(socket) {
const input = pipeline(
socket,
crypto
.createDecipheriv('aes-128-ecb', K, null)
.setAutoPadding(false),
crypto.createDecipheriv("aes-128-ecb", K, null).setAutoPadding(false),
new Deframer(),
new Decoder(),
)
new Decoder()
);
const output = new Encoder()
const output = new Encoder();
pipeline(
output,
crypto
.createCipheriv('aes-128-ecb', K, null)
.setAutoPadding(false),
socket,
)
crypto.createCipheriv("aes-128-ecb", K, null).setAutoPadding(false),
socket
);
return { input, output }
return { input, output };
}
module.exports = setup
module.exports = setup;