Apply Prettier
This commit is contained in:
+83
-76
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user