icqq
Version:
QQ protocol for NodeJS!
313 lines (312 loc) • 11.3 kB
JavaScript
;
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
__setModuleDefault(result, mod);
return result;
};
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.decodePb = exports.decode = exports.encode = exports.Proto = void 0;
// import * as pb from "protobufjs"
const protobuf_min_js_1 = __importDefault(require("./protobuf.min.js"));
const zlib = __importStar(require("zlib"));
class Proto {
get length() {
return this.encoded.length;
}
constructor(encoded, decoded) {
this.encoded = encoded;
if (decoded)
Reflect.setPrototypeOf(this, decoded);
}
toString() {
return this.encoded.toString();
}
toHex() {
return this.encoded.toString("hex");
}
toBase64() {
return this.encoded.toString("base64");
}
toBuffer() {
return this.encoded;
}
toJSON() {
const toJSON = (pb) => {
if (!(pb instanceof Proto))
return pb;
const keys = Object.keys(pb);
if (keys.length === 1 && keys[0] === 'encoded') {
try {
pb = decode(pb.encoded);
}
catch {
return pb.encoded.toString();
}
}
if (!pb)
return pb;
const result = {};
for (const k of Object.keys(pb)) {
if (!/^\d+$/.test(k))
continue;
const key = Number(k);
if (Array.isArray(pb[key]))
return pb[key].map(toJSON);
else if (pb[key] instanceof Proto)
result[key] = pb[key].toJSON();
else if (pb[key] && typeof pb[key] === "object")
result[key] = toJSON(pb[key]);
else if (Buffer.isBuffer(pb[key]))
result[key] = pb[key].toString("hex");
else
result[key] = pb[key];
}
return result;
};
return toJSON(this);
}
[Symbol.toPrimitive]() {
return this.toString();
}
}
exports.Proto = Proto;
function _encode(writer, tag, value) {
if (value === null || value === undefined)
return;
let type = 2;
if (typeof value === "number") {
type = Number.isInteger(value) ? 0 : 1;
}
else if (typeof value === "string") {
value = Buffer.from(value);
}
else if (value instanceof Uint8Array) {
//
}
else if (value instanceof Proto) {
value = value.toBuffer();
}
else if (typeof value === "object") {
value = encode(value);
}
else if (typeof value === "bigint") {
const tmp = new protobuf_min_js_1.default.util.Long();
tmp.unsigned = false;
tmp.low = Number(value & 0xffffffffn);
tmp.high = Number((value & 0xffffffff00000000n) >> 32n);
value = tmp;
type = 0;
}
else {
return;
}
const head = tag << 3 | type;
writer.uint32(head);
switch (type) {
case 0:
if (value < 0)
writer.sint64(value);
else
writer.int64(value);
break;
case 2:
writer.bytes(value);
break;
case 1:
writer.double(value);
break;
}
}
function encode(obj) {
Reflect.setPrototypeOf(obj, null);
const writer = new protobuf_min_js_1.default.Writer();
for (const tag of Object.keys(obj).map(Number)) {
const value = obj[tag];
if (Array.isArray(value)) {
for (let v of value)
_encode(writer, tag, v);
}
else {
_encode(writer, tag, value);
}
}
return writer.finish();
}
exports.encode = encode;
function long2int(long) {
if (long.high === 0)
return long.low >>> 0;
const bigint = (BigInt(long.high) << 32n) | (BigInt(long.low) & 0xffffffffn);
const int = Number(bigint);
return Number.isSafeInteger(int) ? int : bigint;
}
function decode(encoded) {
const result = new Proto(encoded);
const reader = new protobuf_min_js_1.default.Reader(encoded);
while (reader.pos < reader.len) {
const k = reader.uint32();
const tag = k >> 3, type = k & 0b111;
let value, decoded;
switch (type) {
case 0:
value = long2int(reader.int64());
break;
case 1:
value = long2int(reader.fixed64());
break;
case 2:
value = Buffer.from(reader.bytes());
try {
decoded = decode(value);
}
catch { }
value = new Proto(value, decoded);
break;
case 5:
value = reader.fixed32();
break;
default:
return null;
}
if (Array.isArray(result[tag])) {
result[tag].push(value);
}
else if (Reflect.has(result, tag)) {
result[tag] = [result[tag]];
result[tag].push(value);
}
else {
result[tag] = value;
}
}
return result;
}
exports.decode = decode;
function decodePb(buffer_data) {
let pb = {
decode,
encode
};
let proto = pb.decode(buffer_data);
let json = {};
let data;
//delete proto;
//console.log("小叶子调试",pb.decode(proto[3][1][2][1][1][1]));
let index = 0;
async function decode2(proto, json) {
for (let key in proto) {
if (key == "encoded") {
continue;
}
if (proto[key] instanceof Object) {
if (proto[key] instanceof Array) {
json[key] = [];
for (let i = 0; i < proto[key].length; i++) {
json[key].push({});
decode2(proto[key][i], json[key][i]);
}
}
else {
try {
if (pb.decode(proto[key].encoded) == null) {
if (data.length > 3) {
let Prefix = "";
if (data[0] == 0x01 || data[0] == 0x00) {
Prefix = data.toString("hex").slice(0, 2);
data = data.slice(1);
}
let data_json = {};
data_json.Prefix = Prefix;
if (data[0] == 0x78 && data[1] == 0x9c) {
let Deflatedata = zlib.unzipSync(data);
// data_json.RawData = proto[key].encoded;
// data_json.DecompressedData =Deflatedata;
// data_json.CompressType = "Deflate"
data_json.txt = Deflatedata.toString();
data_json.tip = "数据被加密过,使用时请把数据加密回去 deflateSync()";
json[key] = data_json;
decode2(proto[key], json[key]);
continue;
}
else {
json[key] = proto[key].encoded.toString();
decode2(proto[key], json[key]);
continue;
}
}
json[key] = proto[key].encoded.toString();
decode2(proto[key], json[key]);
continue;
}
json[key] = {};
decode2(proto[key], json[key]);
}
catch (error) {
data = proto[key].encoded;
if (data.length > 3) {
let Prefix = "";
if (data[0] == 0x01 || data[0] == 0x00) {
Prefix = data.toString("hex").slice(0, 2);
data = data.slice(1);
}
let data_json = {};
data_json.Prefix = Prefix;
if (data[0] == 0x78 && data[1] == 0x9c) {
let Deflatedata = zlib.unzipSync(data);
// data_json.RawData = proto[key].encoded;
// data_json.DecompressedData =Deflatedata;
// data_json.CompressType = "Deflate"
data_json.txt = Deflatedata.toString();
data_json.tip = "数据被加密过,使用时请把数据加密回去 deflateSync()";
json[key] = data_json;
decode2(proto[key], json[key]);
continue;
}
else {
json[key] = proto[key].encoded.toString();
decode2(proto[key], json[key]);
continue;
}
}
json[key] = proto[key].encoded.toString();
decode2(proto[key], json[key]);
continue;
}
}
}
else {
//console.log("小叶子调试",proto[key]);
let value = proto[key];
if (typeof value == "bigint") {
value = value.toString();
value = Number(value);
}
json[key] = value;
}
}
}
decode2(proto, json);
return json;
}
exports.decodePb = decodePb;