This commit is contained in:
Tau
2019-11-06 17:28:29 -05:00
parent 558c05095a
commit 046b3d0023
7 changed files with 154 additions and 66 deletions
+10 -7
View File
@@ -1,24 +1,27 @@
import { Transform } from "stream";
import { MSG, MSG_LEN } from "./defs";
import { Request } from "./request";
const readers = new Map();
type ReaderFn = (buf: Buffer) => Request;
function readHeader(buf) {
const readers = new Map<number, ReaderFn>();
function readHeader(buf: Buffer) {
return {
blah: "blah",
};
}
readers.set(MSG.GET_CONFIG_DATA_REQ, buf => {
readers.set(MSG.GET_CONFIG_DATA_REQ, () => {
return { type: "get_config_data_req" };
});
readers.set(MSG.GET_CONFIG_DATA_2_REQ, buf => {
readers.set(MSG.GET_CONFIG_DATA_2_REQ, () => {
return { type: "get_config_data_2_req" };
});
readers.set(MSG.GET_SERVER_LIST_REQ, buf => {
readers.set(MSG.GET_SERVER_LIST_REQ, () => {
return { type: "get_server_list_req" };
});
@@ -34,7 +37,7 @@ export class Decoder extends Transform {
this.state = Buffer.alloc(0);
}
_transform(chunk, encoding, callback) {
_transform(chunk: Buffer, encoding, callback) {
this.state = Buffer.concat([this.state, chunk]);
// Read header
@@ -86,6 +89,6 @@ export class Decoder extends Transform {
console.log("Idz: Header:", header);
console.log("Idz: Payload:", payload);
return callback(null, { header, payload });
return callback(null, payload);
}
}
+3
View File
@@ -3,6 +3,8 @@ export const MSG = {
GET_CONFIG_DATA_RES: 0x0005,
GET_SERVER_LIST_REQ: 0x0006,
GET_SERVER_LIST_RES: 0x0007,
ACT_LOCK_REQ: 0x0069,
ACT_LOCK_RES: 0x006a,
GET_CONFIG_DATA_2_REQ: 0x00ab,
GET_CONFIG_DATA_2_RES: 0x00ac,
};
@@ -11,4 +13,5 @@ export const MSG_LEN = new Map();
MSG_LEN.set(MSG.GET_CONFIG_DATA_REQ, 0x0050);
MSG_LEN.set(MSG.GET_CONFIG_DATA_2_REQ, 0x0010);
MSG_LEN.set(MSG.ACT_LOCK_REQ, 0x001c);
MSG_LEN.set(MSG.GET_SERVER_LIST_REQ, 0x0020);
+48 -56
View File
@@ -1,56 +1,7 @@
import { Transform } from "stream";
import { MSG } from "./defs";
const writers = new Map<string, (foo: any) => Buffer>();
writers.set("get_config_data_res", obj => {
const buf = Buffer.alloc(0x01a0);
buf.writeUInt16LE(MSG.GET_CONFIG_DATA_RES, 0x0000);
buf.writeUInt16LE(obj.status, 0x0002);
return buf;
});
writers.set("get_config_data_2_res", obj => {
const buf = Buffer.alloc(0x230);
buf.writeUInt16LE(MSG.GET_CONFIG_DATA_2_RES, 0x0000);
buf.writeUInt16LE(obj.status, 0x0002);
return buf;
});
writers.set("get_server_list_res", obj => {
const buf = Buffer.alloc(0x04b0);
buf.writeUInt16LE(MSG.GET_SERVER_LIST_RES, 0x0000);
buf.writeUInt16LE(obj.status, 0x0002);
buf.write(obj.userDb.addr, 0x0004);
buf.writeUInt16LE(obj.userDb.tcp, 0x0084);
buf.writeUInt16LE(obj.userDb.http, 0x0086);
buf.write(obj.matchAddr, 0x0088);
buf.writeUInt16LE(obj.matchPort.tcp, 0x0108);
buf.writeUInt16LE(obj.matchPort.udpSend, 0x010a);
buf.writeUInt16LE(obj.matchPort.udpRecv, 0x010c);
buf.writeUInt16LE(obj.tagMatchPort.tcp, 0x010e);
buf.writeUInt16LE(obj.tagMatchPort.udpSend, 0x0110);
buf.writeUInt16LE(obj.tagMatchPort.udpRecv, 0x0112);
buf.write(obj.event.addr, 0x0114);
buf.writeUInt16LE(obj.event.tcp, 0x0194);
buf.write(obj.screenshot.addr, 0x0198);
buf.writeUInt16LE(obj.screenshot.tcp, 0x0218);
buf.write(obj.pingReturn, 0x021c);
buf.write(obj.echo1.addr, 0x029c);
buf.write(obj.echo2.addr, 0x031c);
buf.writeUInt16LE(obj.echo1.udp, 0x39c);
buf.writeUInt16LE(obj.echo2.udp, 0x39e);
buf.write(obj.newsUrl, 0x03a0);
buf.write(obj.reportErrorUrl, 0x0424);
return buf;
});
import { Response } from "./response";
export class Encoder extends Transform {
constructor() {
@@ -60,17 +11,58 @@ export class Encoder extends Transform {
});
}
_transform(obj, encoding, callback) {
_transform(obj: Response, encoding, callback) {
console.log("Idz: Response:", obj);
const writer = writers.get(obj.type);
let buf: Buffer;
if (writer === undefined) {
return callback(new Error(`No writer for type ${obj.type}`));
switch (obj.type) {
case "get_config_data_res":
buf = Buffer.alloc(0x01a0);
buf.writeUInt16LE(MSG.GET_CONFIG_DATA_RES, 0x0000);
buf.writeUInt16LE(obj.status, 0x0002);
break;
case "get_config_data_2_res":
buf = Buffer.alloc(0x230);
buf.writeUInt16LE(MSG.GET_CONFIG_DATA_2_RES, 0x0000);
buf.writeUInt16LE(obj.status, 0x0002);
break;
case "get_server_list_res":
buf = Buffer.alloc(0x04b0);
buf.writeUInt16LE(MSG.GET_SERVER_LIST_RES, 0x0000);
buf.writeUInt16LE(obj.status, 0x0002);
buf.write(obj.userDb.addr, 0x0004);
buf.writeUInt16LE(obj.userDb.tcp, 0x0084);
buf.writeUInt16LE(obj.userDb.http, 0x0086);
buf.write(obj.matchAddr, 0x0088);
buf.writeUInt16LE(obj.matchPort.tcp, 0x0108);
buf.writeUInt16LE(obj.matchPort.udpSend, 0x010a);
buf.writeUInt16LE(obj.matchPort.udpRecv, 0x010c);
buf.writeUInt16LE(obj.tagMatchPort.tcp, 0x010e);
buf.writeUInt16LE(obj.tagMatchPort.udpSend, 0x0110);
buf.writeUInt16LE(obj.tagMatchPort.udpRecv, 0x0112);
buf.write(obj.event.addr, 0x0114);
buf.writeUInt16LE(obj.event.tcp, 0x0194);
buf.write(obj.screenshot.addr, 0x0198);
buf.writeUInt16LE(obj.screenshot.tcp, 0x0218);
buf.write(obj.pingReturn, 0x021c);
buf.write(obj.echo1.addr, 0x029c);
buf.write(obj.echo2.addr, 0x031c);
buf.writeUInt16LE(obj.echo1.udp, 0x39c);
buf.writeUInt16LE(obj.echo2.udp, 0x39e);
buf.write(obj.newsUrl, 0x03a0);
buf.write(obj.reportErrorUrl, 0x0424);
break;
default:
return callback(new Error(`No writer fn for ${obj["type"]}`));
}
const buf = writer(obj);
return callback(null, buf);
}
}
+1 -1
View File
@@ -9,7 +9,7 @@ export default async function idz(socket) {
try {
for await (const msg of input) {
switch (msg.payload.type) {
switch (msg.type) {
case "get_server_list_req":
const myHost = hostname();
+25
View File
@@ -0,0 +1,25 @@
export interface AccountLockRequest {
type: "account_lock_req";
field_0002: number;
field_0004: number;
field_0008: Buffer;
field_0018: number;
}
export interface GetConfigDataRequest {
type: "get_config_data_req";
}
export interface GetConfigDataRequest2 {
type: "get_config_data_2_req";
}
export interface GetServerListRequest {
type: "get_server_list_req";
}
export type Request =
| AccountLockRequest
| GetConfigDataRequest
| GetConfigDataRequest2
| GetServerListRequest;
+54
View File
@@ -0,0 +1,54 @@
export interface GetConfigDataResponse {
type: "get_config_data_res";
status: number;
}
export interface GetConfigDataResponse2 {
type: "get_config_data_2_res";
status: number;
}
export interface GetServerListResponse {
type: "get_server_list_res";
status: number;
userDb: {
addr: string;
tcp: number;
http: number;
};
matchAddr: string;
matchPort: {
tcp: number;
udpSend: number;
udpRecv: number;
};
tagMatchPort: {
tcp: number;
udpSend: number;
udpRecv: number;
};
event: {
addr: string;
tcp: number;
};
screenshot: {
addr: string;
tcp: number;
};
pingReturn: string;
echo1: {
addr: string;
udp: number;
};
echo2: {
addr: string;
udp: number;
};
newsUrl: string;
reportErrorUrl: string;
}
export type Response =
| GetConfigDataResponse
| GetConfigDataResponse2
| GetServerListResponse;
+13 -2
View File
@@ -5,8 +5,12 @@ import { pipeline } from "stream";
import { byteString, modPow } from "./bigint";
import { Decoder } from "./decoder";
import { Encoder } from "./encoder";
import { Request } from "./request";
import { Response } from "./response";
// Proof-of-concept, so we only ever use one of the ten RSA key pairs
// (SEGA shipped their central server private keys for god knows what reason)
// Proof-of-concept, so we only ever use one of the ten RSA keys
const key = {
N: 4922323266120814292574970172377860734034664704992758249880018618131907367614177800329506877981986877921220485681998287752778495334541127048495486311792061n,
d: 1163847742215766215216916151663017691387519688859977157498780867776436010396072628219119707788340687440419444081289736279466637153082223960965411473296473n,
@@ -25,7 +29,14 @@ console.log("RSA ENC :", byteString(test1, 0x40).toString("hex"));
console.log("RSA ENCDEC :", byteString(test2, 0x40).toString("hex"));
// -- TEST --
export default function setup(socket: Socket) {
interface Session {
input: AsyncIterable<Request>;
output: {
write: (res: Response) => void;
};
}
export default function setup(socket: Socket): Session {
//
// Construct and transmit setup message
//