This commit is contained in:
aozhiwei 2023-04-17 19:50:25 +08:00
parent 7ad03facd1
commit 13cd59f9a8
4 changed files with 433 additions and 0 deletions

View File

@ -0,0 +1,8 @@
const TestCase = require('./testcase');
async function start() {
const testCase = new TestCase();
await testCase.init();
}
start();

View File

@ -0,0 +1,319 @@
const protobuf = require('protobufjs');
const ws = require('nodejs-websocket');
function prettyJsonEncode(obj) {
return JSON.stringify(obj, "", " ");
}
class ClientNet {
constructor(url, protoPbFile, msgIdPbFile) {
this.url = url;
this.conn = null;
this.protoPbFile = protoPbFile;
this.msgIdPbFile = msgIdPbFile;
this.protoPb = null;
this.msgIdPb = null;
this.cmMsgId = null;
this.smMsgId = null;
this.recvBuf = Buffer.alloc(0);
this.uniqId = 1000;
this.msgHandlerMap = new Map();
}
selfRegisterMsgHandle(msgName) {
this.registerMsgHandle(
msgName,
(msg) => {
this[msgName](msg);
});
}
async init() {
{
this.protoPb = await (new protobuf.Root()).load(this.protoPbFile,
{
'keepCase': true
}
);
}
{
this.msgIdPb = await (new protobuf.Root()).load(this.msgIdPbFile,
{
'keepCase': true
}
);
this.cmMsgId = this.msgIdPb.lookup('CMMessageId_e');
this.smMsgId = this.msgIdPb.lookup('SMMessageId_e');
}
{
this.selfRegisterMsgHandle('SMLogin');
this.selfRegisterMsgHandle('SMGuildCreate');
this.selfRegisterMsgHandle('SMGuildInfo');
this.selfRegisterMsgHandle('SMGuildMemberList');
this.selfRegisterMsgHandle('SMGuildSearch');
this.selfRegisterMsgHandle('SMGuildSearchMember');
this.selfRegisterMsgHandle('SMGuildAgree');
this.selfRegisterMsgHandle('SMGuildMemberSetJob');
this.selfRegisterMsgHandle('SMGuildApplyList');
this.selfRegisterMsgHandle('SMGuildChange');
this.selfRegisterMsgHandle('SMGuildSetPermission');
this.selfRegisterMsgHandle('SMUserInfoUpdate');
this.selfRegisterMsgHandle('SMPing');
}
}
async connect() {
this.conn = await ws.connect(this.url);
this.on('binary', this.#onReceive.bind(this));
}
on(eventName, ...args) {
this.conn.on(eventName, ...args);
}
async #onReceive(inStream) {
inStream.on('readable', async () => {
//console.log('inStream.readable');
const newData = inStream.read();
if (newData) {
this.recvBuf = Buffer.concat([this.recvBuf, newData]);
await this.#onParsePacket();
}
});
inStream.on('end', () => {
//console.log('inStream.end', this.recvBuf.length);
});
inStream.on('close', () => {
//console.log('inStream.close');
});
}
async #onParsePacket() {
let offset = 0;
while (this.recvBuf.length > offset + 12) {
const msgSize = this.recvBuf.readUInt32LE(offset + 0);
const msgId = this.recvBuf.readUInt16LE(offset + 4);
const magicCode = this.recvBuf.readUInt16LE(offset + 6);
const seqId = this.recvBuf.readUInt32LE(offset + 8);
if (this.recvBuf.length >= offset + 12 + msgSize) {
await this.#processMsg(msgId,
this.recvBuf.slice
(
offset + 12,
offset + 12 + msgSize)
);
offset += 12 + msgSize;
} else {
break;
}
}
this.recvBuf = this.recvBuf.slice(offset);
}
async #processMsg(msgId, buff) {
const handlers = this.msgHandlerMap.get(msgId);
if (handlers) {
let msg = null;
handlers.forEach((value, key) => {
if (!msg) {
msg = value.msgType.decode(buff);
}
console.log(value.msgType['name'], prettyJsonEncode(msg));
value.cb(msg);
});
}
}
registerMsgHandle(msgName, cb) {
const msgType = this.protoPb.lookupType(msgName);
const msgId = this.smMsgId.values['_' + msgName];
if (!msgId) {
return null;
}
const handle = {
msgId: msgId,
msgName: msgName,
msgType: msgType,
cb: cb,
uniqId: ++this.uniqId}
;
if (!this.msgHandlerMap.has(msgId)) {
this.msgHandlerMap.set(msgId, new Map([
[handle.uniqId, handle]
]));
} else {
this.msgHandlerMap.get(msgId).set(handle.uniqId, handle);
}
return handle;
}
unRegisterMsgHandle(handle) {
if (this.msgHandlerMap.has(handle.msgId)) {
if (this.msgHandlerMap[handle.msgId].has(handle.uniqId)) {
this.msgHandlerMap[handle.msgId].delete(handle.uniqId);
}
}
}
async sendMsg(name, msg) {
const msgType = this.protoPb.lookupType(name);
const msgId = this.cmMsgId.values['_' + name];
const msgPb = msgType.create(msg);
const msgBuf = msgType.encode(msg).finish();
let buf = Buffer.alloc(12);
buf.writeUInt32LE(msgBuf.length, 0);
buf.writeUInt16LE(msgId, 4);
buf.writeUInt8('K'.charCodeAt(0), 6);
buf.writeUInt8('S'.charCodeAt(0), 7);
buf.writeInt32LE(0, 8);
this.conn.sendBinary(Buffer.concat([buf, msgBuf]));
console.log(name, msg, (Buffer.concat([buf, msgBuf])).length);
}
SMLogin(msg) {
if (msg.errcode) {
return;
}
if (!msg.user_info.guild_id) {
/*this.sendMsg(
'CMGuildJoin',
{
'guild_id': 10010
});*/
this.sendMsg(
'CMGuildCreate',
{
'guild_name': 'test_guild1'
});
} else {
this.sendMsg(
'CMGuildInfo',
{
'guild_id': msg.user_info.guild_id
});
this.sendMsg(
'CMGuildApplyList',
{
});
this.sendMsg(
'CMGuildAgree',
{
'applyid': "10072"
});
}
/*this.sendMsg(
'CMGuildAgree',
{
'applyid': "10000"
});
this.sendMsg(
'CMGuildMemberSetJob',
{
'member_id': "6000_1006_227",
"job": 3
});
this.sendMsg(
'CMPing',
{
});*/
}
SMGuildCreate(msg) {
this.sendMsg(
'CMGuildInfo',
{
'guild_id': msg.guild_id
});
}
SMGuildInfo(msg) {
this.sendMsg(
'CMGuildMemberList',
{
});
this.sendMsg(
'CMGuildApplyList',
{
});
this.sendMsg(
'CMGuildSearch',
{
'guild_name': ''
});
this.sendMsg(
'CMGuildSearchMember',
{
'target_id': this.accountId
});
this.sendMsg(
'CMGuildChange',
{
'guild_notice': 'test notice'
});
this.sendMsg(
'CMGuildSetPermission',
{
'permission': {
'job': 1,
'switchs': [
{
'key': 110001,
'val': 0
},
{
'key': 110002,
'val': 0
},
{
'key': 110003,
'val': 0
}
]
}
});
}
SMGuildMemberList(msg) {
}
SMGuildSearch(msg) {
}
SMGuildSearchMember(msg) {
}
SMGuildAgree(msg) {
}
SMGuildMemberSetJob(msg) {
}
SMGuildApplyList(msg) {
}
SMGuildChange(msg) {
}
SMGuildSetPermission(msg) {
}
SMUserInfoUpdate(msg) {
}
SMPing(msg) {
}
}
module.exports = ClientNet;

View File

@ -0,0 +1,12 @@
{
"name": "kcpclient",
"version": "1.0.0",
"description": "",
"private": true,
"scripts": {},
"dependencies": {
"axios": "^0.27.0",
"nodejs-websocket": "^1.7.2",
"protobufjs": "^6.11.2"
}
}

View File

@ -0,0 +1,94 @@
const axios = require('axios').default;
const ClientNet = require('./clientnet');
function getTickCount() {
return Math.floor((new Date()).getTime() / 1);
}
function httpGet(url, params) {
return new Promise((resolve) => {
const ret = {
err: null,
response: null,
};
axios({
method: 'get',
url: url,
timeout: 1000 * 5,
params: params,
responseType: 'text'
}).then((response) => {
ret.response = response.data;
resolve(ret);
}).catch((error) => {
ret.err = error;
resolve(ret);
});
});
}
async function sleep(timeout) {
return new Promise(function (resolve, reject) {
setTimeout(function () {
resolve();
}, timeout);
});
}
class TestCase {
constructor(url) {
this.relationUrl = 'ws://127.0.0.1:7132';
//this.relationUrl = 'ws://8.133.161.108/game1006/websocket/';
this.loginData = null;
this.relationWs = new ClientNet(
this.relationUrl,
'proto/cs_proto.proto',
'proto/cs_msgid.proto'
);
}
async init() {
await this.step1();
await this.step2();
while (true) {
await sleep(1000 * 3);
}
}
async step1() {
const startTick = getTickCount();
const {err, response} = await httpGet(
'http://8.133.161.108/game1006/api/webapp/index.php',
{
'c': 'Login',
'a': 'auth',
'gameid': 1006,
'channel': 6000,
'account': 'test1',
'openid': 'test1'
});
this.loginData = response;
const endTick = getTickCount();
console.log('login auth@Login', endTick - startTick, String(err), response);
}
async step2() {
await this.relationWs.init();
await this.relationWs.connect();
this.relationWs.on('connect', () => {
console.log('relation onConnect');
//this.loginData['account_id'] = '6000_1006_gh36';
//this.loginData['session_id'] = '1654932040_1654932019_997704543_9c6066a10f56f8fb8fc4210c3d9c0b85';
this.relationWs.accountId = this.loginData['account_id'];
this.relationWs.sessionId = this.loginData['session_id'];
this.relationWs.sendMsg('CMLogin', {
account_id: this.loginData['account_id'],
session_id: this.loginData['session_id'],
});
});
}
}
module.exports = TestCase;