ProtoFactory PoC

This commit is contained in:
TheLostTree 2022-07-31 11:34:43 -07:00
parent f7bce82c44
commit 41346eb1b8
3 changed files with 107 additions and 3 deletions

103
src/ProtoFactory.ts Normal file
View File

@ -0,0 +1,103 @@
//ts-proto generated types required, import them here
import * as types from "./data/proto/StarRail";
import protobufjs from "protobufjs";
import {CmdID, PacketName} from "./server/kcp/Packet"
import Logger from "./util/Logger";
var c = new Logger("ProtoFactory");
class MessageType<T>{
"encode": (arg0: T) => protobufjs.Writer;
"fromPartial": (arg0: object) => T;
// "decode": (input: protobufjs.Reader | Uint8Array, length?: number)=> T;
// "fromJSON": (object: any)=>T;
// "toJSON": (message: T)=> unknown
//you can add more fields here from the generated types
//fromjson etc...
};
var messageTypeMap = new Map<PacketName, MessageType<any>>();
function send<Class extends MessageType<T>,T>(type: Class, data: T){
console.log(type.encode(data).finish())
}
function isMessageType<T>(pet: MessageType<T> | any): pet is MessageType<T> {
return (<MessageType<T>>pet).encode !== undefined;
}
export default class ProtoFactory{
// ONLY USE THIS IF YOU'RE DECODING SOMETHING DONT USE IT TO SEND SHIT
// BECAUSE THEN YOU FUCK YOUR TYPECHECKING
static getType(name: PacketName){
return messageTypeMap.get(name) as MessageType<any>;
}
static init() {
//iterate over everything in types and check if they are a MessageType
for (const key of Object.keys(types)) {
let value = types[key as keyof typeof types];
if (isMessageType(value)) {
if(Object.values(CmdID).includes(key)){
messageTypeMap.set(key as PacketName, value);
}else{
// there are some types that are not packets, but are still MessageType
// you can figure out what you want to do with them here
}
}
}
c.log("Initialized with " + messageTypeMap.size + " types");
return;
// example usages of send function
send(types.PlayerLoginScRsp, {
retcode: 0,
isRelay: false,
basicInfo: {
exp: 0,
level: 1,
hcoin: 0,
mcoin: 0,
nickname: "test",
scoin: 0,
stamina: 100,
worldLevel: 1,
},
isNewPlayer: true,
stamina: 100,
curTimezone: 1,
loginRandom: 0,
serverTimestampMs: Math.round(new Date().getTime() / 1000),
bsBinVersion: ""
});
//if you want a partial type
send(types.PlayerLoginScRsp, types.PlayerLoginScRsp.fromPartial({
basicInfo: {
exp: 0,
level: 1,
hcoin: 0,
mcoin: 0,
nickname: "test",
scoin: 0,
stamina: 100,
worldLevel: 1,
},
isNewPlayer: true,
stamina: 100,
curTimezone: 1,
serverTimestampMs: Math.round(new Date().getTime() / 1000),
}))
}
}

View File

@ -7,8 +7,10 @@ import Interface from "./commands/Interface";
import HttpServer from "./http/HttpServer"; import HttpServer from "./http/HttpServer";
import SRServer from "./server/kcp/SRServer"; import SRServer from "./server/kcp/SRServer";
import Logger from "./util/Logger"; import Logger from "./util/Logger";
const c = new Logger("CrepeSR"); import ProtoFactory from "./protoFactory"
const c = new Logger("CrepeSR");
ProtoFactory.init();
c.log(`Starting CrepeSR...`); c.log(`Starting CrepeSR...`);
Interface.start(); Interface.start();
HttpServer.getInstance().start(); HttpServer.getInstance().start();

View File

@ -39,7 +39,6 @@ export default class Packet {
public static encode(name: PacketName, body: {}, customCmdId?: number): Packet | null { public static encode(name: PacketName, body: {}, customCmdId?: number): Packet | null {
try { try {
// @ts-ignore - Bullshit. You can just get enums by name
const cmdid = CmdID[name]; const cmdid = CmdID[name];
const Message = Packet.root.lookupTypeOrEnum(name); const Message = Packet.root.lookupTypeOrEnum(name);
@ -73,7 +72,7 @@ export default class Packet {
export type PacketName = keyof typeof CmdID; export type PacketName = keyof typeof CmdID;
enum CmdID { export enum CmdID {
None = 0, None = 0,
PlayerLoginCsReq = 1, PlayerLoginCsReq = 1,
PlayerLoginScRsp = 2, PlayerLoginScRsp = 2,