好友
阅读权限 10
听众
最后登录 1970-1-1
本帖最后由 orpheus 于 2019-6-4 11:26 编辑
近期在琢磨某款对战答题小游戏,属于题库型对战,当前题答错会提示正确答案项,打算:
1.将每次答题得到的正确答案,保存在本地题库文件
2.下次答题时,获取到题目时,在本地题库文件中检索
3.检索到正确答案时,在正确答案前加★,如未检索到,则在A选项前加☆(用于提示脚本是否正常运行)
一、fiddler抓包分析对战过程:
1.开始对战后有一个匹配对手的过程,访问的是keepmatching:
379字节的为未匹配到,多次向服务器请求对手方,Request为空,未匹配成功时Response内容如下:
[XML] 纯文本查看 复制代码
{
"error_no":"0",
"error_info":"",
"result":{
"match":0,
"round":null,
"opponent":{
"mobile":null,
"head_img_url":null
},
"my_mobile":null,
"question":{
"question_no":null,
"question_title":null,
"right_option":null,
"option_a":null,
"option_b":null,
"option_c":null,
"option_d":null
}
}
}
2.匹配成功后Response内容如下:
[XML] 纯文本查看 复制代码
{
"error_no":"0",
"error_info":"",
"result":{
"match":1,
"round":1,
"opponent":{
"mobile":"",
"head_img_url":"http:\/\/AAAA.BBBB.com\/mmopen\/vi_32\/Q0j4TwGTfTJDdmHm6txEViaffuo5S691NhAaCMdyiaublhA9c4TDSOK3sgqnqNcKc5ZKKaJ4KlkcBrcrOVf7nxbg\/132"
},
"my_mobile":null,
"question":{
"question_no":11356,
"question_title":"哪种投资行为是理性投资?",
"right_option":null,
"option_a":"股神推荐就买",
"option_b":"盲目相信专家",
"option_c":"坚持价值投资",
"option_d":"看别人赚到钱眼红杀入"
}
}
}
3.提交答案时,post访问url为answer,post内容:
4.提交答案后,返回正确答案,并会在前端显示正确答案,Response内容为:
[XML] 纯文本查看 复制代码
{
"error_no":"0",
"error_info":"",
"result":{
"round":2,
"surplus":null,
"answer":"D",
"myself":{
"answer":"D",
"is_right":1,
"score":190
},
"opponent":{
"answer":null,
"is_right":null,
"score":100
},
"status":1,
"question":{
"question_no":null,
"question_title":null,
"right_option":null,
"option_a":null,
"option_b":null,
"option_c":null,
"option_d":null
}
}
}
其中 "answer":"D", 表示正确答案
5.完成一次答题,重复上述步骤,但访问的为keepanswer,逻辑类似
二、脚本思路:
在OnBeforeResponse函数中进行编写:
1.首先获取题目字符串 ,因为keepmatching环节有多次匹配过程,其中几次是没有获取到题目及选项的。获取到题目(即匹配成功,推送题目到客户端)时,head_img_url不为空,采用是否包含该域名进行判断,代码如下:
[JavaScript] 纯文本查看 复制代码
//取对战题目字符串
if(oSession.uriContains('/keepmatching'))
{
oSession.utilDecodeResponse();
if (oSession.utilFindInResponse("AAAA.BBBB.c0m", false) > -1)
{
var responseqbody = oSession.GetResponseBodyAsString().replace(/[\r\n ]/g, "");
writeFile1(matchtitle,responseqbody.match(/question_no\":(\S*),\"right_option/)[1]);
question.qno= responseqbody.match(/question_no\":(\S*),\"question_title/)[1];
question.question_title =responseqbody.match(/question_title\":\"(\S*)\",\"right_option/)[1];
question.option_a =responseqbody.match(/option_a\":\"(\S*)\",\"option_b/)[1];
question.option_b =responseqbody.match(/option_b\":\"(\S*)\",\"option_c/)[1];
question.option_c =responseqbody.match(/option_c\":\"(\S*)\",\"option_d/)[1];
question.option_d =responseqbody.match(/option_d\":\"(\S*)\"}/)[1];
var questionstr = question.qno+"|"+question.question_title+"|"+question.option_a+"|"+question.option_b+"|"+question.option_c+"|"+question.option_d;
writeFile1(matchtitle,questionstr); //对战题.txt 临时保存对战题,格式如:11569|合格境内机构投资者经()批准可以在境内募集资金进行境外证券投资的机构|中国证监会|中国人民银行|财政部|中国银保监会 var strqbanklin = findLineInfile(matchfile,question.question_title);
if(strqbanklin !=""){
var answerstr = strqbanklin.split("|")[6];
oSession.utilReplaceInResponse (answerstr,"★"+answerstr+"★");
} else {
oSession.utilReplaceInResponse ("option_a\":\"","option_a\":\""+"☆:");
}
}else {
}
}
keepanswer时,同样有空请求,猜测是否为心跳包(求指教 ),采用是否包含“answer”进行判断,代码如下:
[JavaScript] 纯文本查看 复制代码
//写对战题库
if (oSession.uriContains('/answer'))
{
oSession.utilDecodeResponse();
if (oSession.utilFindInResponse("answer", false) > -1)
{
var responseqbody = oSession.GetResponseBodyAsString().replace(/[\r\n ]/g, "");
var questionstr = readFile(matchtitle).replace(/[\r\n ]/g, "");
writeFile(tempfile,"responseqbody = "+responseqbody);
writeFile(tempfile,"questionstr = "+questionstr);
var answerNo = responseqbody.match(/answer\":\"(\S*)\",\"myself/)[1];
writeFile(tempfile,"answerNo = "+answerNo);
writeFile(tempfile,"");
var strtemp = readFile(matchtitle).replace(/[\r\n ]/g, "")
var questarr = strtemp.split("|");
if (questarr.length == 6) {
question.qno = questarr[0]
question.question_title = questarr[1]
question.option_a = questarr[2]
question.option_b = questarr[3]
question.option_c = questarr[4]
question.option_d = questarr[5]
if (answerNo == 'A') {
question.right_option = "A";
question.right_title = question.option_a;
} else if (answerNo == 'B') {
question.right_option = "B";
question.right_title = question.option_b;
} else if (answerNo == 'C') {
question.right_option = "C";
question.right_title = question.option_c;
} else if (answerNo == 'D') {
question.right_option = "D";
question.right_title = question.option_d;
}
var strtemp1 = question.question_title + "|" + question.option_a + "|" + question.option_b + "|" + question.option_c + "|" + question.option_d + "|" + answerNo + "|" + question.right_title
writeFile(matchfile,strtemp1);//写题库文件,例:“融资”是指客户向证券公司借入什么( )。|基金|债券|股票|资金|D|资金
}
}else {
//writeFile(tempfile,"<---answer为空---->");
//writeFile(tempfile,"");
}
}
以上过程就完成了一次自动答题,整体流程为:
取到题目及选项,存入matchtitle临时文件,检索题库→答题,获得正确答案,进行拼接,存入matchfile题库文件
实际运行效果如下:
三、写在后面
话说以前没接触过JS和fiddler,这次走了很多歪路,写下来当个笔记:
1.OnPeekAtResponseHeaders函数下需要加入以下内 容,否则无法修改ResponseBody,这个困惑了很久,感谢其他网友无私分享
[JavaScript] 纯文本查看 复制代码
//需要在返回头这里就设置buffer处理,否则,后续无法在onBeforeResponse中修改body(修改的动作不会阻塞原来的返回)
if (oSession.HostnameIs("AAA.BBB.com") && oSession.oResponse.headers.ExistsAndContains("Content-Type","application/json")){
oSession.bBufferResponse = true;
}
2.null判断很重要 ,中间跳了很多次异常,都是因为没有进行null判断,对心跳包和对手匹配的过程进行了处理,取到null,所以报错
3.正则表达式是个好东西 ,要好好学一下
4.脚本目前存在的bug:
①前面进行了空格替换,存入题库文件时没有空格,如“1 2 3”存为“123”。新答题时,如果选项中有空格,会无法匹配,只有后续手动修改题库。因为发现时候题库已经很大了,无法逐一修改,只有忍了。
②因为是用utilReplaceInResponse进行替换,所以,如果有2个选项都包含关键字,会标注2个选项,如下:
正确选项为34
选项为:
A.1234
B.2345
C.3456
D.34
会标注为:
A.12★34★
B.2★34★5
C.★34★56
D.★34★
选五角星在头尾的即可。这个可以采用分别提取4个选项,用比较的方法进行标注,因为懒,所以凑合用了
5.可以在OnBeforeRequest加入函数,实现点击错误答案,如题库中存在该题,则自动修改为正确答案进行提交。不存在则提交某个固定项或实际答题项。用于在抢答过程中抢答,目前已经实现。
6.WX已经内部集成证书,手机端无法用fiddler进行拦截,电脑端不受影响,以上操作均在电脑端完成。
7.用到的几个文件读写JS,再次感谢互联网精神
[JavaScript] 纯文本查看 复制代码
static function writeFile(filename,context)
{
var fso = new ActiveXObject("Scripting.FileSystemObject");
var f = fso.OpenTextFile(filename,8 );
//var sUA: String = fso.ReadAll();
f.writeLine(context);
f.Close();
}
static function writeFile1(filename,context)
{
var fso = new ActiveXObject("Scripting.FileSystemObject");
var f = fso.OpenTextFile(filename,2,true );
//var sUA: String = fso.ReadAll();
f.writeLine(context);
f.Close();
}
static function findLineInfile(filename,context){
var fso = new ActiveXObject("Scripting.FileSystemObject");
var f=fso.OpenTextFile(filename,1);
var arr=f.ReadAll().split("\r\n");
for(var i= 0;i<arr.length;i++)
{
if (arr[i].indexOf(context) != -1)
{
f.close();
return(arr[i]);
}
}
return("");
}
static function readFile(filename)
{
var fso = new ActiveXObject("Scripting.FileSystemObject");
var f=fso.OpenTextFile(filename,1);
var str = "";
while (!f.AtEndOfStream)
str += f.ReadLine()+"\n";
f.close();
return(str)
}
static function searchInFile(filename,context)
{
var fso = new ActiveXObject("Scripting.FileSystemObject");
var f=fso.OpenTextFile(filename,8);
var strmarch= false;
if (f.indexOf(context) != -1)
{
strmarch = true;
}
f.close();
return(strmarch)
}
第一次发帖,第一次做fiddler脚本,错误及不足之处,恳请各位指教,不胜感激
免费评分
参与人数 2 吾爱币 +6
热心值 +2
收起
理由
azw80
+ 1
+ 1
欢迎分析讨论交流,吾爱破解论坛有你更精彩!
苏紫方璇
+ 5
+ 1
欢迎分析讨论交流,吾爱破解论坛有你更精彩!
查看全部评分