Skip to content
This repository has been archived by the owner on Nov 2, 2023. It is now read-only.

Commit

Permalink
Merge pull request #66 from takayama-lily/dev
Browse files Browse the repository at this point in the history
-
  • Loading branch information
takayama-lily authored Oct 11, 2020
2 parents adb71c4 + 52877df commit 6b2781f
Show file tree
Hide file tree
Showing 17 changed files with 488 additions and 648 deletions.
2 changes: 1 addition & 1 deletion client.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -209,7 +209,7 @@ export class Client extends events.EventEmitter {
setFriendAddRequest(flag: string, approve?: boolean, remark?: string, block?: boolean): Promise<RetCommon>;
setGroupAddRequest(flag: string, approve?: boolean, reason?: string, block?: boolean): Promise<RetCommon>;

addGroup(group_id: Uin): Promise<RetCommon>;
addGroup(group_id: Uin, comment?: string): Promise<RetCommon>;
addFriend(group_id: Uin, user_id: Uin, comment?: string): Promise<RetCommon>;
deleteFriend(user_id: Uin, block?: boolean): Promise<RetCommon>;
inviteFriend(group_id: Uin, user_id: Uin): Promise<RetCommon>;
Expand Down
48 changes: 34 additions & 14 deletions client.js
Original file line number Diff line number Diff line change
Expand Up @@ -37,13 +37,24 @@ class AndroidClient extends Client {
config;
status = Client.OFFLINE;
kickoff_reconn = false;
ignore_self = true;

// default phone
apkid = "com.tencent.mobileqq";
apkver = "8.4.1.2703";
apkname = "A8.4.1.2703aac4";
apksign = Buffer.from([166, 183, 69, 191, 36, 162, 194, 119, 82, 119, 22, 246, 243, 110, 182, 141]);
buildtime = 1591690260;
appid = 16;
sub_appid = 537064989;
bitmap = 184024956;
sigmap = 34869472;
sdkver = "6.0.0.2433";
ksid;
device;

uin = 0;
password_md5;
// appid = 16;
sub_appid;
ignore_self = true;

nickname = "";
age = 0;
sex = 0;
Expand All @@ -60,29 +71,26 @@ class AndroidClient extends Client {
handlers = new Map();
seq_cache = new Map();

session_id = Buffer.from([0x02, 0xB0, 0x5B, 0x8B]);
session_id = crypto.randomBytes(4);
random_key = crypto.randomBytes(16);
ksid = Buffer.from("|454001228437590|A8.2.7.27f6ea96");
device_info;
captcha_sign;
t104;

sign_info = {
bitmap: 0,
sig = {
tgt: BUF0,
tgt_key: BUF0,
st_key: BUF0,
st_web_sig: BUF0,
s_key: BUF0,
d2: BUF0,
d2key: BUF0,
sig_key: BUF0,
ticket_key: BUF0,
device_token: BUF0,
};

sync_finished = false;
sync_cookie;

const1 = crypto.randomBytes(4).readUInt32BE();
const2 = crypto.randomBytes(4).readUInt32BE();

Expand All @@ -109,15 +117,27 @@ class AndroidClient extends Client {

this.logger = log4js.getLogger(`[BOT:${uin}]`);
this.logger.level = config.log_level;

this.sub_appid = config.platform === 1 ? 537062845 : (config.platform === 3 ? 537061176 : 537062409);
this.ignore_self = config.ignore_self;
this.kickoff_reconn = config.kickoff;

if (config.platform == 3)
this.sub_appid = 537061176;
else if (config.platform == 2) {
this.sub_appid = 537065549;
this.apkid = "com.tencent.minihd.qq";
this.apkver = "5.8.9.3460";
this.apkname = "A5.8.9.3460";
this.apksign = Buffer.from([170, 57, 120, 244, 31, 217, 111, 249, 145, 74, 102, 158, 24, 100, 116, 199]);
this.buildtime = 1595836208;
this.bitmap = 150470524;
this.sigmap = 1970400;
}

const filepath = path.join(this.dir, `device-${uin}.json`);
if (!fs.existsSync(filepath))
this.logger.info("创建了新的设备文件:" + filepath);
this.device_info = device(filepath);
this.device = device(filepath);
this.ksid = Buffer.from(`|${this.device.imei}|` + this.apkname);

this.on("error", (err)=>{
this.logger.error(err.message);
Expand Down Expand Up @@ -615,7 +635,7 @@ class AndroidClient extends Client {
* 发送加群申请,即使你已经在群里,也会返回成功
* ※设置为要正确回答问题的群,暂时回返回失败
* ※风险接口,每日加群超过一定数量账号必被风控(甚至ip)
* @param {String} comment 该参数仅占位,暂未实现
* @param {String} comment 附加信息
*/
async addGroup(group_id, comment = "") {
return await this.callApi(troop.addGroup, arguments);
Expand Down
6 changes: 3 additions & 3 deletions device.js
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ module.exports = function(filepath) {
boot_id: d.boot_id,
proc_version: d.proc_version,
baseband: "",
sim_info: "T-Mobile",
sim: "T-Mobile",
os_type: "android",
mac_address: d.mac_address,
ip_address: d.ip_address,
Expand All @@ -77,8 +77,8 @@ module.exports = function(filepath) {
sdk: 29
}
};
device.imsi_md5 = crypto.randomBytes(16);
device.tgtgt_key = crypto.randomBytes(16);
device.imsi = crypto.randomBytes(16);
device.tgtgt = crypto.randomBytes(16);
device.guid = md5(Buffer.concat([Buffer.from(device.android_id), Buffer.from(device.mac_address)]));
return device;
};
2 changes: 1 addition & 1 deletion docs/api.md
Original file line number Diff line number Diff line change
Expand Up @@ -159,7 +159,7 @@ message可以使用 `Array` 格式或 `String` 格式,支持CQ码

### 加群加好友、删好友、邀请好友入群、点赞

+ async `client.addGroup(group_id)`
+ async `client.addGroup(group_id[, comment])`
+ async `client.addFriend(group_id, user_id[, comment])`
+ async `client.deleteFriend(user_id[, block])` block默认是true
+ async `client.inviteFriend(group_id, user_id)`
Expand Down
1 change: 1 addition & 0 deletions docs/event.md
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ client.on("notice", (data)=>console.log(data)); //监听所有的通知事件
+ *`url`* 设备锁验证地址(string)
+ `system.login.error` 其他原因导致登陆失败
+ *`message`* "密码错误"等(string)
+ *`code`* 错误码

+ `system.online` 上线事件,可以开始处理消息

Expand Down
1 change: 1 addition & 0 deletions docs/project.md
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@
|-|-|-|-|
|at|||[CQ:at,qq=123456,text=@ABC] text用来定义@不到时的输出|
|face|◯|◯|表情,[CQ:face,id=104]
|sface|||小表情(HD协议不支持),[CQ:sface,id=271,text=/吃瓜]|
|bface|||原创表情,[CQ:bface,file=xxxxxxxx,text=摸头]|
|dice&rps|||魔法表情骰子和猜拳:<br>[CQ:dice,id=1] ※id=1-6 不填则随机<br>[CQ:rps,id=1] ※id=1-3 分别对应1石头2剪刀3布|
|image|||[CQ:image,file=xxxxxxxx,url=xxxxxxxx] 收到的图片<br>[CQ:image,file=C:/123.jpg] 本地图片(支持file:///和base64://)<br>[CQ:image,cache=0,file=http://abc.com] 网络图片|
Expand Down
8 changes: 4 additions & 4 deletions lib/core.js
Original file line number Diff line number Diff line change
Expand Up @@ -166,7 +166,7 @@ async function getMsg(sync_flag = 0) {
async function getNewFriend() {
this.nextSeq();
const body = pb.encode("ReqSystemMsgNew", {
msgNum: 1,
msgNum: 20,
version: 1000,
checktype: 2,
flag: {
Expand Down Expand Up @@ -205,8 +205,8 @@ async function getNewFriend() {
async function getNewGroup() {
this.nextSeq();
const body = pb.encode("ReqSystemMsgNew", {
msgNum: 1,
version: 100,
msgNum: 20,
version: 1000,
checktype: 3,
flag: {
grpMsgKickAdmin: 1,
Expand Down Expand Up @@ -679,7 +679,7 @@ function parseIncomingPacket(packet) {
case 0:
break;
case 1:
decrypted = tea.decrypt(decrypted, this.sign_info.d2key);
decrypted = tea.decrypt(decrypted, this.sig.d2key);
break;
case 2:
decrypted = tea.decrypt(decrypted, Buffer.alloc(16));
Expand Down
29 changes: 27 additions & 2 deletions lib/message/builder.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ const crypto = require("crypto");
const spawn = require("child_process");
const {downloadWebImage, downloadWebRecord} = require("./service");
const common = require("../common");
const pb = require("../pb");

function unescapeCQ(s) {
if (s === "&#91;") return "[";
Expand Down Expand Up @@ -70,7 +71,7 @@ function buildAtMessage(chain, cq, group_id) {
function buildFaceMessage(chain, cq) {
let {id} = cq;
id = parseInt(id);
if (id > 0xff) return false;
if (id < 0 || id > 0xff || isNaN(id)) return false;
const old = Buffer.alloc(2);
old.writeUInt16BE(0x1441 + id);
chain.set({face: {
Expand All @@ -81,12 +82,31 @@ function buildFaceMessage(chain, cq) {
return true;
}

/**
* @returns {Boolean} success?
*/
function buildSFaceMessage(chain, cq) {
let {id, text} = cq;
id = parseInt(id);
if (id < 0 || isNaN(id)) return false;
if (!text) text = "/" + id;
chain.set({commonElem: {
serviceType: 33,
pbElem: pb.encode("MsgElemInfoServtype33", {
id, text1: text, text2: text
}),
businessType: 1
}}, {type: "sface"});
return true;
}

/**
* @returns {Boolean} success?
*/
function buildBFaceMessage(chain, cq) {
try {
let {file, text} = cq;
if (!text) text = "原创表情";
text = "["+text.slice(0, 5)+"]";
const o = {
faceName: Buffer.from(text),
Expand Down Expand Up @@ -431,7 +451,8 @@ async function buildMessageFromString(chain, message, escape, group_id, stat) {
async function buildMessage(message, escape, group_id) {
const chain = new Map();
const stat = {
length: 0, at_cnt: 0, face_cnt: 0, bface_cnt: 0, img_cnt: 0, is_forward: false, type: "stat"
length: 0, at_cnt: 0, face_cnt: 0, sface_cnt: 0, bface_cnt: 0, img_cnt: 0,
is_forward: false, type: "stat"
};
chain.set("stat", stat);
if (typeof message === "string")
Expand Down Expand Up @@ -488,6 +509,10 @@ async function buildElement(chain, type, data, group_id, stat) {
if (buildFaceMessage.call(this, chain, data))
++stat.face_cnt;
break;
case "sface":
if (buildSFaceMessage.call(this, chain, data))
++stat.sface_cnt;
break;
case "bface":
if (buildBFaceMessage.call(this, chain, data))
++stat.bface_cnt;
Expand Down
28 changes: 18 additions & 10 deletions lib/message/chat.js
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ async function sendMsg(target, message, escape, type) {
}
await Promise.all(tasks);
await completeImages.call(this, target, images, type);
stat.length += stat.at_cnt * 22 + stat.face_cnt * 23 + stat.bface_cnt * 140 + stat.img_cnt * (type?90:304);
stat.length += stat.at_cnt * 22 + stat.face_cnt * 23 + stat.sface_cnt * 42 + stat.bface_cnt * 140 + stat.img_cnt * (type?90:304);
stat.length *= 1.05;
const is_long = type ? (stat.length>790) : (stat.length>935);
rsp = await _sendMsg({elems}, is_long);
Expand Down Expand Up @@ -401,11 +401,20 @@ async function onGroupMsg(blob) {

this.getGroupInfo(group_id);

const font = body.richText.attr.fontName, card = group.groupCard;
try {
var {chain, raw_message, extra} = await parseMessage.call(this, body.richText, group_id);
} catch (e) {return}

let font = body.richText.attr.fontName, card = group.groupCard;
if (extra.nick)
card = String(extra.nick);

let anonymous = null, user = null;
if (user_id === 80000000) {
anonymous = {
id:0, name: card, flag: ""
id: extra.bubbleId,
name: String(extra.anonNick),
flag: extra.anonId ? extra.anonId.toString("base64") : ""
};
} else {
try {
Expand All @@ -415,11 +424,17 @@ async function onGroupMsg(blob) {
user.last_sent_time = time;
this.gl.get(group_id).last_sent_time = time;
}
if (extra.senderTitle)
user.title = String(extra.senderTitle);
if (extra.level)
user.level = String(extra.level);
} catch (e) {}
}

if (user_id === this.uin && this.ignore_self)
return;
if (!raw_message)
return;

if (user) {
var {nickname, sex, age, area, level, role, title} = user;
Expand All @@ -430,13 +445,6 @@ async function onGroupMsg(blob) {
user_id, nickname, card, sex, age, area, level, role, title
};

try {
var {chain, raw_message} = await parseMessage.call(this, body.richText, group_id);
} catch (e) {return}

if (!raw_message)
return;

const sub_type = anonymous ? "anonymous" : "normal";
this.logger.info(`recv from: [Group: ${group_name}(${group_id}), Member: ${card}(${user_id})] ` + raw_message);
common.emit(this, "message.group." + sub_type, {
Expand Down
12 changes: 11 additions & 1 deletion lib/message/parser.js
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ async function parseMessage(rich, from = 0) {
const elems = rich.elems;
if (rich.ptt)
elems.unshift({ptt: rich.ptt});
const extra = {};
const chain = [];
let raw_message = "";
let bface_tmp = null, ignore_text = false;
Expand All @@ -34,6 +35,10 @@ async function parseMessage(rich, from = 0) {
const msg = {type:"",data:{}};
const o = v[type];
switch (type) {
case "anonGroupMsg":
case "extraInfo":
Object.assign(extra, o);
break;
case "generalFlags":
if (o.longTextResid)
return await parseMultiMsg.call(this, o.longTextResid);
Expand Down Expand Up @@ -90,6 +95,11 @@ async function parseMessage(rich, from = 0) {
msg.type = "flash";
msg.data = parseImage(flash[Object.keys(flash)[0]]);
ignore_text = true;
} else if (o.serviceType === 33) {
msg.type = "sface";
const sface = pb.decode("MsgElemInfoServtype33", o.pbElem);
msg.data.id = sface.id;
msg.data.text = sface.text1;
}
break;
case "ptt":
Expand All @@ -108,7 +118,7 @@ async function parseMessage(rich, from = 0) {
raw_message += genCQMsg(msg);
}
}
return {chain, raw_message};
return {chain, raw_message, extra};
}

function genCQMsg(msg) {
Expand Down
Loading

0 comments on commit 6b2781f

Please sign in to comment.