标签:vertica define header fine cte 机器 ges 有用 注意
---恢复内容开始---
背景:2月1日我们实验室的qq群引入了一个聊天机器人,可实现签到,打劫,玩游戏(如24点,猜字谜等)等的功能,签到,打劫成功,游戏胜利(如24点回答正确)可获得积分,寒假时未曾关注群所以开学时自己毫无积分,而其他同学都已为富一方,尤其是某学长积分竟达十万之巨,(签到一次100左右,24点回答正确100),遂疑惑,问之,学长曰:无他,刷分耳。于是在4月9日,参考了下学长的思路(http://www.zhangzaizai.com/2017/02/08/xiaozi-helper/),便开始试着开发一个刷分的辅助。
技术:我的后端平台是nodejs,其他框架不是学得很深所以用最底层的http模块来发送post请求。用明文传输信息的smartqq来作为post的接受端。
步骤
var http = require(‘http‘);
exports.post = function (contents) {
var options = {
host: "d1.web2.qq.com",
method: "POST",
path: "/channel/send_qun_msg2",
headers: {
‘Host‘: ‘d1.web2.qq.com‘,
‘User-Agent‘: ‘Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:52.0) Gecko/20100101 Firefox/52.0‘,
‘Accept‘: ‘*/*‘,
‘Accept-Language‘: ‘en-US,en;q=0.5‘,
‘Content-Type‘: ‘application/x-www-form-urlencoded‘,
‘Referer‘: ‘https://d1.web2.qq.com/cfproxy.html?v=20151105001&callback=1‘,
‘Content-Length‘: contents.length,
‘Cookie‘: ‘‘,/*出于安全考虑隐去cookie*/
‘Connection‘: ‘keep-alive‘
}
};
var req = http.request(options, function (res) {});
req.write(contents);
req.end();
};
我为了操作方便把它封装在了模块中。
var rr = {
"group_uin": 4111913875,
"content": "[\"开始24点\",[\"font\",{\"name\":\"宋体\",\"size\":10,\"style\":[0,0,0],\"color\":\"000000\"}]]",
"face": 210,
"clientid": 53156849,/*出于安全考虑隐去真实数字,换以同长数字*/
"msg_id": 62220001,
"psessionid": ""/*出于安全考虑隐去psessionid*/
};
),但是传输老失败,后来询问学长,发现实际传输的内容并不是直接JSON,而需要经过URLencode加密,于是我调用了nodejs自带的encodeURI函数把上述加密后传输(),后即成功
var contents2 = encodeURI(‘r=‘ + JSON.stringify(rr));
var buf=Buffer.concat(chunks,size);
var str=iconv.decode(buf,‘utf-8‘);
)还是不行。‘Accept-Encoding‘: ‘gzip, deflate, br‘,
于是寻求相关信息,发现(http://www.jb51.net/article/61721.htm)这个网站,尝试着解压了下响应体,如
zlib.unzip(body, function (err, buffer) {
console.log(buffer.toString());
})
6. 然后就ok了,当屏幕上出现send ok时心情还是蛮激动的,然后十分兴奋的告诉学长,只听学长一声“你可以发请求头要求它不做gzip压缩的”,遂删去Accept-Encoding。发送消息至此就算成功了。在此向某个被我拿来做实验的群说声抱歉,我不是故意水的。。
接下来是接受消息。
在smartqq上接受消息的原理是不断post poll2当有人发给你消息时post就会响应,响应内容即为接受内容。那么模拟它即可。
此post跟上述的并没有太大的不同,但是要注意option的path要变了,以及content-length固定不变,option的代码如下,
var options = {
host: "d1.web2.qq.com",
method: "POST",
path: "/channel/poll2",/*注意此处*/
headers: {
‘Host‘: ‘d1.web2.qq.com‘,
‘User-Agent‘: ‘Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:52.0) Gecko/20100101 Firefox/52.0‘,
‘Accept‘: ‘*/*‘,
‘Accept-Language‘: ‘en-US,en;q=0.5‘,
‘Content-Type‘: ‘application/x-www-form-urlencoded‘,
‘Referer‘: ‘https://d1.web2.qq.com/cfproxy.html?v=20151105001&callback=1‘,
‘Content-Length‘: ‘395‘,/*我认为由于参数不同你们的不一定是395,自己抓包即可获得长度*/
‘Cookie‘: ‘‘,/*出于安全考虑隐去cookie*/
‘Connection‘: ‘keep-alive‘
}
};
重点在于对响应的处理。当我输入“开始24点”后小紫(机器人)会返回这样一段话:"24点开始!数字(共有6种解法):8, 8, 8, 5将以上数字加减乘除(+,-,*,/)得出24,并列出算式即可。如发送:24点 (4-2)*12/1",当我回答正确后会返回:"很强悍!算式正确。增加100积分当前数字(共有20种解法):9, 9, 3, 5将以上数字加减乘除(+,-,*,/)得出24,并列出算式即可。如发送:24点 (4-2)*12/1",我要做的是正确获取四个数字并避免其他信息干扰,同时不能在没获得信息,即没人互动时程序整个挂掉(会返回一个HTML网页),还要根据4个数字计算得出正确的字符串。
function tdisoper(f0, f1, f2, f3) {
this[0] = f0;
this[1] = f1;
this[2] = f2;
this[3] = f3;
}
disoper = new tdisoper("-", "+", "/", "*");
function oper(f, m, n) {
if (f === 3) return (m * n);
if (f === 2) return (m / n);
if (f === 1) return (parseFloat(m) + parseFloat(n));
if (f === 0) return (m - n);
}
function tb(i1, i2, i4, i8) {
this[1] = i1;
this[2] = i2;
this[4] = i4;
this[8] = i8;
}
function valid(a,b,c,d) {
var result = ‘‘;
n = 1;
b = new tb(a, b, c, d);
k = 0;
var output = "";
for (i1 = 1; i1 <= 8; i1 *= 2)
for (i2 = 1; i2 <= 8; i2 *= 2)
for (i3 = 1; i3 <= 8; i3 *= 2)
for (i4 = 1; i4 <= 8; i4 *= 2) {
if ((i1 | i2 | i3 | i4) !== 0xf) continue;
for (f1 = 0; f1 <= 3; f1++)
for (f2 = 0; f2 <= 3; f2++)
for (f3 = 0; f3 <= 3; f3++) {
m = oper(f3, oper(f2, oper(f1, b[i1], b[i2]), b[i3]), b[i4]);
if (Math.abs(m - 24) < 1e-5) {
result = result + "((" + b[i1] + disoper[f1] + b[i2] + ")" + disoper[f2] + b[i3] + ")" + disoper[f3] + b[i4];
if ((n !== 0) && (++k >= n)) return result;
}
m = oper(f1, b[i1], oper(f3, oper(f2, b[i2], b[i3]), b[i4]));
if (Math.abs(m - 24) < 1e-5) {
result = result + b[i1] + disoper[f1] + "((" + b[i2] + disoper[f2] + b[i3] + ")" + disoper[f3] + b[i4] + ")";
if ((n !== 0) && (++k >= n)) return result;
}
m = oper(f3, oper(f1, b[i1], oper(f2, b[i2], b[i3])), b[i4]);
if (Math.abs(m - 24) < 1e-5) {
result = result + "(" + b[i1] + disoper[f1] + "(" + b[i2] + disoper[f2] + b[i3] + "))" + disoper[f3] + b[i4];
if ((n !== 0) && (++k >= n)) return result;
}
m = oper(f1, b[i1], oper(f2, b[i2], oper(f3, b[i3], b[i4])));
if (Math.abs(m - 24) < 1e-5) {
result = result + b[i1] + disoper[f1] + "(" + b[i2] + disoper[f2] + "(" + b[i3] + disoper[f3] + b[i4] + "))";
if ((n !== 0) && (++k >= n)) return result;
}
m = oper(f2, oper(f1, b[i1], b[i2]), oper(f3, b[i3], b[i4]));
if (Math.abs(m - 24) < 1e-5) {
result = result + "(" + b[i1] + disoper[f1] + b[i2] + ")" + disoper[f2] + "(" + b[i3] + disoper[f3] + b[i4] + ")";
if ((n !== 0) && (++k >= n)) return result;
}
}
}
return result;
exports.cal = function(a,b,c,d){
return valid(a,b,c,d);
};
var req = http.request(options, function (res) {
res.on(‘data‘, function (body) {
if (body.toString().search(‘<html>‘) === -1) {/*此处是为了避免长时间未收到数据导致程序直接崩溃*/
var str;
str = JSON.parse(body.toString());/*解析响应体为JSON格式*/
console.log("接受消息 " + str.result[0].value.content);/*获得接受内容*/
if (str.result[0].value.send_uin === 8888888/*此处出于安全考虑。。*/) {
var usethen;/*含有关键4个数字的字符串*/
if (str.result[0].value.content.length >= 6)/*避免无关信息干扰*/
usethen = str.result[0].value.content[5];
if (usethen!==undefined) {
var use = usethen.match(/\u89e3[^\n]*\u4ee5/g);/*利用正则表达式获取从‘解‘到‘以‘的字符串*/
var number;
if (use!==undefined)
number = use[0].match(/[0-9]/g); /*利用正则获取4个重要数字*/
console.log("获得数字" + number);
if (number !== undefined) {
var result = calc.cal(number[0], number[1], number[2], number[3]);
console.log("得到结果" + result);
var reg = /["][^\n]*[",]/;
rr.content = rr.content.replace(‘开始24点‘, "24点 " + result);/*rr就是上面的rr*/
contents2 = encodeURI(‘r=‘ + JSON.stringify(rr));
contents2 = contents2.replace(‘+‘, ‘%2b‘);/*为什么有这四个,我要放在下面讲*/
contents2 = contents2.replace(‘+‘, ‘%2b‘);
contents2 = contents2.replace(‘+‘, ‘%2b‘);
contents2 = contents2.replace(‘+‘, ‘%2b‘);
post.post(contents2);
}
}
}
}
});
res.on(‘err‘, function (err) {
console.log(err);
})
});
req.write(contents);
req.end();
为什么我要写四个contents = contents.replace(‘+‘,‘%2b‘)呢,因为encodeURI函数不会转换加号等特殊字符,导致我发送出去的字符串一直没有加号,这里又卡了我一下。如有更好的方法,希望有大神教与我。
至此,程序编的差不多了,作为并不熟练的noder,自然是有很多瑕疵,也希望有大神能够指出。
基于nodejs的http模块通过smartqq实现自动收发qq消息的程序
标签:vertica define header fine cte 机器 ges 有用 注意
原文地址:http://www.cnblogs.com/sinasap/p/6746689.html