├── OrderTimeFailDirect.js ├── README.md ├── bark软件key.jpg ├── checkOrderDirect.js ├── ddmc.js ├── fuckSheep.js ├── stupidSheep.js ├── 大润发运力监控.md ├── 定时监控视频.mp4 ├── 山姆超市运力监控.md ├── 抓包视频.mp4 ├── 羊了个羊破解.md ├── 详细教程.md └── 重写教程.md /OrderTimeFailDirect.js: -------------------------------------------------------------------------------- 1 | /** 2 | * 说明: 3 | * 下单返回失效页面会弹框,服务器繁忙不会弹框 4 | * 因此将失效改为繁忙 禁止弹框 5 | */ 6 | 7 | /** 8 | * 下单失效返回值 9 | * { 10 | * "server_time" : 1649457085, 11 | * "data" : { 12 | * "tradeTag" : "TIME_DELIVERY", 13 | * "station_id" : "" 14 | * }, 15 | * "code" : 5004, 16 | * "success" : false, 17 | * "msg" : "您选择的送达时间已经失效了,请重新选择", 18 | * "is_trade" : 1, 19 | * "tradeTag" : "TIME_DELIVERY" 20 | * } 21 | */ 22 | 23 | /** 24 | * 服务器繁忙返回值 25 | * { 26 | * "success" : false, 27 | * "code" : -3001, 28 | * "tips" : { 29 | * "duration" : 300, 30 | * "limitMsg" : "前方拥挤,请稍后再试..." 31 | * }, 32 | * "msg" : "当前人多拥挤,请稍后尝试刷新页面", 33 | * "data" : { 34 | * 35 | * }, 36 | * "barrier" : { 37 | * "maxCount" : 5, 38 | * "passRatio" : 0.5 39 | * } 40 | * } 41 | * 42 | */ 43 | 44 | var res = JSON.parse($response.body); 45 | 46 | function getDirectData(msg) { 47 | return { 48 | "success" : false, 49 | "code" : -3001, 50 | "tips" : { 51 | "duration" : 300, 52 | "limitMsg" : msg 53 | }, 54 | "msg" : msg, 55 | "data" : { 56 | 57 | }, 58 | "barrier" : { 59 | "maxCount" : 5, 60 | "passRatio" : 0.5 61 | } 62 | } 63 | } 64 | 65 | if (res.success == false && res.code == 5004) { 66 | console.log("下单时间失效,开始数据替换..."); 67 | $done({body: JSON.stringify(getDirectData("下单日期已失效(理性重试,频繁可能封号)"))}); 68 | } else if (res.success == false && res.code == -3001) { 69 | console.log("服务器繁忙,正在重试...") 70 | $done({body: $response.body}); 71 | } else if (res.success == false && res.code == 5003){ 72 | console.log("送达时间已抢光,正在数据替换..."); 73 | $done({body: JSON.stringify(getDirectData("送达时间已抢光(理性重试,频繁可能封号)"))}); 74 | } else { 75 | $done({body: $response.body}); 76 | } -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ## 说明 2 | 3 | 经过部分用户反馈,叮咚买菜监控可能会被封号(一天),使用时请慎重。 4 | 5 | 目前教程都是针对iOS端的,不需要越狱,安卓百度叮咚助手。 6 | 7 | 大润发和山姆目前只有监控没有重写(我这边这2个平台都没法配送,无法详细测试) 8 | 9 | 关于圈X这个软件的说明,这个软件国区无法下载,需要外区下载,可以网上找共享帐号下载,也可以自己申请美区id然后去tb购买礼品卡充值Appstore去购买软件,我这边不提供软件,谢谢。 10 | 11 | ## 如何使用 12 | 可能有风险,使用需谨慎 13 | 14 | - [详细教程](https://github.com/wu491925129/script/blob/main/%E8%AF%A6%E7%BB%86%E6%95%99%E7%A8%8B.md) 15 | - [重写教程](https://github.com/wu491925129/script/blob/main/%E9%87%8D%E5%86%99%E6%95%99%E7%A8%8B.md) 16 | - [大润发运力监控](https://github.com/wu491925129/script/blob/main/%E5%A4%A7%E6%B6%A6%E5%8F%91%E8%BF%90%E5%8A%9B%E7%9B%91%E6%8E%A7.md) 17 | - [山姆超市运力监控](https://github.com/wu491925129/script/blob/main/%E5%B1%B1%E5%A7%86%E8%B6%85%E5%B8%82%E8%BF%90%E5%8A%9B%E7%9B%91%E6%8E%A7.md) 18 | 19 | ## 更新记录 20 | 21 | **0430** 由于老的获取时间接口叮咚服务器做了校验,因此使用首页的运力通知来实现监控,具体见[详细教程](https://github.com/wu491925129/script/blob/main/%E8%AF%A6%E7%BB%86%E6%95%99%E7%A8%8B.md) 22 | 23 | --- 24 | **0413** 新增大润发运力监控,见 --> [大润发运力监控.md](https://github.com/wu491925129/script/blob/main/%E5%A4%A7%E6%B6%A6%E5%8F%91%E8%BF%90%E5%8A%9B%E7%9B%91%E6%8E%A7.md) 25 | 26 | **0413** 新增山姆会员超市运力监控,见 --> [山姆超市运力监控.md](https://github.com/wu491925129/script/blob/main/%E5%B1%B1%E5%A7%86%E8%B6%85%E5%B8%82%E8%BF%90%E5%8A%9B%E7%9B%91%E6%8E%A7.md) 27 | 28 | --- 29 | **0412** 详细详细教程新增视频播放 30 | 31 | --- 32 | 33 | **0410** 新增购物车商品监控,监控操作逻辑与运力监控一致,监控代码见详细教程.md文档,设置推送阀值,当购物车中失效商品被站点上架数量超过推送阀值时,推送消息。 34 | 35 | --- 36 | 37 | **0410** 优化监控通知,展示所有有运力配送的时间段,开重写后建议选择通知的第二个时间段; 38 | 优化自动获取配送时间,优化送达时间弹框,禁止弹出; 39 | 40 | **更新指南**: 41 | 42 | 监控:更新详细教程.md中的代码 43 | 44 | 重写:更新全部脚本 45 | 46 | --- 47 | 48 | **0409** 监控代码新增推送可配送时间 49 | 50 | --- 51 | 52 | **0409** 更新订单下单重写规则,日期失效状况不会弹框,可以直接点击结算,下单更快。 53 | 54 | --- 55 | **0408** 更新订单校验重写规则,详情看重写教程.md文档,重写开启之后结算页面不会弹出繁忙的弹框,配合获取时间重写规则可以一直点击结算,下单更快。 56 | 57 | ## bug fix 58 | 59 | **0414** 修改大润发、山姆超市URL跳转错误的问题 60 | 61 | **0413** 修复大润发监控异常的问题 62 | 63 | **0411** 修复购物车监控日志输出异常的问题 64 | -------------------------------------------------------------------------------- /bark软件key.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wu491925129/script/e71d3d7c2f1d521b5344260ba669324e8509a1a0/bark软件key.jpg -------------------------------------------------------------------------------- /checkOrderDirect.js: -------------------------------------------------------------------------------- 1 | /** 2 | * 重写订单校验 3 | * 禁止弹出拥挤提示 4 | */ 5 | 6 | var data = { 7 | "success" : true, 8 | "code" : 0, 9 | "msg" : "", 10 | "data" : { 11 | } 12 | } 13 | 14 | var res = JSON.parse($response.body); 15 | 16 | console.log("重写订单校验") 17 | 18 | 19 | if (!res.success) { 20 | $done({ body: JSON.stringify(data) }); 21 | console.log($response.body) 22 | } else { 23 | $done({ body: $response.body }); 24 | } 25 | 26 | 27 | -------------------------------------------------------------------------------- /ddmc.js: -------------------------------------------------------------------------------- 1 | /** 2 | * 自动选择时间 3 | * { 4 | * "success": true, 5 | * "code": 0, 6 | * "msg": "success", 7 | * "data": [ 8 | * { 9 | * "station_delay_text": null, 10 | * "default_select": true, 11 | * "time": [ 12 | * { 13 | * "date_str": "今天", 14 | * "date_str_timestamp": 1680123600, 15 | * "day": "today", 16 | * "times": [ 17 | * { 18 | * "type": 4, 19 | * "fullFlag": false, 20 | * "disableType": 0, 21 | * "disableMsg": "", 22 | * "textMsg": "", 23 | * "start_time": "5:59", 24 | * "end_time": "23:00", 25 | * "start_timestamp": 1680123600, 26 | * "end_timestamp": 1680188400, 27 | * "arrival_time_msg": "自动尝试可用时段", 28 | * "arrival_time": false, 29 | * "select_msg": "自动尝试可用时段" 30 | * } 31 | * ], 32 | * "is_invalid": false, 33 | * "invalid_prompt": null, 34 | * "time_full_text_tip": null 35 | * } 36 | * ], 37 | * "station_id": "", 38 | * "is_new_rules": true, 39 | * "busy_soon_arrival_text": "", 40 | * "eta_trace_id": "", 41 | * "area_level": 1 42 | * } 43 | * ], 44 | * "tradeTag": "success", 45 | * "server_time": 1680037200, 46 | * "is_trade": 1 47 | * } 48 | */ 49 | 50 | var nowTime = Date.parse(new Date())/1000; 51 | 52 | // 获取时间戳 53 | function strToTimestamp(time) { 54 | var date = new Date(); 55 | var year = date.getFullYear(); 56 | var month = date.getMonth() + 1; 57 | var day = date.getDate(); 58 | var pushDate = year + "/" + month + "/" + day+" "+time; 59 | return Date.parse(new Date(pushDate)) / 1000; 60 | } 61 | 62 | 63 | // 获取当前站点id 64 | var res = JSON.parse($response.body); 65 | var stationId = res.success ? res.data[0].station_id : ""; 66 | 67 | console.log("重写叮咚配送时间开始....") 68 | 69 | var data = { 70 | "server_time" : nowTime, 71 | "data" : [ 72 | { 73 | "station_delay_text" : null, 74 | "time" : [ 75 | { 76 | "invalid_prompt" : null, 77 | "date_str_timestamp" : nowTime, 78 | "day" : "today", 79 | "date_str" : "今天(来自Max破解)", 80 | "times" : [ 81 | { 82 | "disableType" : 0, 83 | "fullFlag" : false, 84 | "disableMsg" : "", 85 | "textMsg" : "", 86 | "type" : 4, 87 | "start_time" : "08:00", 88 | "arrival_time_msg" : "08:00-08:30", 89 | "select_msg" : "今天08:00-08:30", 90 | "end_time" : "08:30", 91 | "end_timestamp" : strToTimestamp("08:30"), 92 | "arrival_time" : false, 93 | "start_timestamp" : strToTimestamp("08:00") 94 | }, 95 | { 96 | "disableType" : 0, 97 | "fullFlag" : false, 98 | "disableMsg" : "", 99 | "textMsg" : "", 100 | "type" : 4, 101 | "start_time" : "08:30", 102 | "arrival_time_msg" : "08:30-10:30", 103 | "select_msg" : "今天08:30-10:30", 104 | "end_time" : "10:30", 105 | "end_timestamp" : strToTimestamp("10:30"), 106 | "arrival_time" : false, 107 | "start_timestamp" : strToTimestamp("08:30") 108 | }, 109 | { 110 | "disableType" : 0, 111 | "fullFlag" : false, 112 | "disableMsg" : "", 113 | "textMsg" : "", 114 | "type" : 4, 115 | "start_time" : "10:30", 116 | "arrival_time_msg" : "10:30-12:30", 117 | "select_msg" : "今天10:30-12:30", 118 | "end_time" : "12:30", 119 | "end_timestamp" : strToTimestamp("12:30"), 120 | "arrival_time" : false, 121 | "start_timestamp" : strToTimestamp("10:30") 122 | }, 123 | { 124 | "disableType" : 0, 125 | "fullFlag" : false, 126 | "disableMsg" : "", 127 | "textMsg" : "", 128 | "type" : 4, 129 | "start_time" : "12:30", 130 | "arrival_time_msg" : "12:30-14:30", 131 | "select_msg" : "今天12:30-14:30", 132 | "end_time" : "14:30", 133 | "end_timestamp" : strToTimestamp("14:30"), 134 | "arrival_time" : false, 135 | "start_timestamp" : strToTimestamp("12:30") 136 | }, 137 | { 138 | "disableType" : 0, 139 | "fullFlag" : false, 140 | "disableMsg" : "", 141 | "textMsg" : "", 142 | "type" : 4, 143 | "start_time" : "14:30", 144 | "arrival_time_msg" : "14:30-16:30", 145 | "select_msg" : "今天14:30-16:30", 146 | "end_time" : "16:30", 147 | "end_timestamp" : strToTimestamp("16:30"), 148 | "arrival_time" : false, 149 | "start_timestamp" : strToTimestamp("14:30") 150 | }, 151 | { 152 | "disableType" : 0, 153 | "fullFlag" : false, 154 | "disableMsg" : "", 155 | "textMsg" : "", 156 | "type" : 4, 157 | "start_time" : "16:30", 158 | "arrival_time_msg" : "16:30-18:30", 159 | "select_msg" : "今天16:30-18:30", 160 | "end_time" : "18:30", 161 | "end_timestamp" : strToTimestamp("18:30"), 162 | "arrival_time" : false, 163 | "start_timestamp" : strToTimestamp("16:30") 164 | }, 165 | { 166 | "disableType" : 0, 167 | "fullFlag" : false, 168 | "disableMsg" : "", 169 | "textMsg" : "", 170 | "type" : 4, 171 | "start_time" : "18:30", 172 | "arrival_time_msg" : "18:30-20:30", 173 | "select_msg" : "今天18:30-20:30", 174 | "end_time" : "20:30", 175 | "end_timestamp" : strToTimestamp("20:30"), 176 | "arrival_time" : false, 177 | "start_timestamp" : strToTimestamp("18:30") 178 | }, 179 | { 180 | "disableType" : 0, 181 | "fullFlag" : false, 182 | "disableMsg" : "", 183 | "textMsg" : "", 184 | "type" : 4, 185 | "start_time" : "20:30", 186 | "arrival_time_msg" : "20:30-22:30", 187 | "select_msg" : "今天20:30-22:30", 188 | "end_time" : "22:30", 189 | "end_timestamp" : strToTimestamp("22:30"), 190 | "arrival_time" : false, 191 | "start_timestamp" : strToTimestamp("20:30") 192 | } 193 | ], 194 | "is_invalid" : false, 195 | "time_full_text_tip" : null 196 | } 197 | ], 198 | "is_new_rules" : true, 199 | "interval_minute" : -1, 200 | "default_select" : false, 201 | "eta_trace_id" : "", 202 | "station_id" : "5b988449c0a1ea8f1c8b5a6b", 203 | "area_level" : 1, 204 | "busy_soon_arrival_text" : "" 205 | } 206 | ], 207 | "code" : 0, 208 | "success" : true, 209 | "msg" : "success", 210 | "is_trade" : 1, 211 | "tradeTag" : "success" 212 | } 213 | 214 | var defaultData = { 215 | "success": true, 216 | "code": 0, 217 | "msg": "success", 218 | "data": [ 219 | { 220 | "station_delay_text": null, 221 | "default_select": true, 222 | "time": [ 223 | { 224 | "date_str": "今天(来自Max破解)", 225 | "date_str_timestamp": nowTime, 226 | "day": "today", 227 | "times": [ 228 | { 229 | "type": 4, 230 | "fullFlag": false, 231 | "disableType": 0, 232 | "disableMsg": "", 233 | "textMsg": "", 234 | "start_time": "5:59", 235 | "end_time": "23:00", 236 | "start_timestamp": 1680123600, 237 | "end_timestamp": 1680188400, 238 | "arrival_time_msg": "自动尝试可用时段", 239 | "arrival_time": false, 240 | "select_msg": "自动尝试可用时段" 241 | } 242 | ], 243 | "is_invalid": false, 244 | "invalid_prompt": null, 245 | "time_full_text_tip": null 246 | } 247 | ], 248 | "station_id": "", 249 | "is_new_rules": true, 250 | "busy_soon_arrival_text": "", 251 | "eta_trace_id": "", 252 | "area_level": 1 253 | } 254 | ], 255 | "tradeTag": "success", 256 | "server_time": nowTime, 257 | "is_trade": 1 258 | } 259 | 260 | // 判断是否是自动选择时间 默认选中可配送的时间 261 | if (res.success && res.data[0].time[0].times[0].arrival_time_msg == "自动尝试可用时段") { 262 | $done({body: JSON.stringify(defaultData)}); 263 | } else { 264 | // 剔除小余当前时间的时间段 265 | //let times = data.data[0].time[0].times.filter(item => item.end_timestamp > nowTime); 266 | //data.data[0].time[0].times = times; 267 | $done({body: JSON.stringify(data)}); 268 | } 269 | 270 | -------------------------------------------------------------------------------- /fuckSheep.js: -------------------------------------------------------------------------------- 1 | var res = JSON.parse($response.body); 2 | if(res.err_code == 0){ 3 | console.log("Fuck Sheep Start...") 4 | res.data.map_md5[1] = "046ef1bab26e5b9bfe2473ded237b572"; 5 | $done({body: JSON.stringify(res)}); 6 | } else { 7 | console.log("Fuck Sheep Error...") 8 | $done({body: JSON.stringify(res)}); 9 | } 10 | -------------------------------------------------------------------------------- /stupidSheep.js: -------------------------------------------------------------------------------- 1 | var res = JSON.parse($response.body); 2 | if(res.err_code == 0){ 3 | console.log("开始重写羊了个羊...") 4 | res.data = "046ef1bab26e5b9bfe2473ded237b572"; 5 | $done({body: JSON.stringify(res)}); 6 | } else { 7 | console.log("重写羊了个羊失败...") 8 | $done({body: JSON.stringify(res)}); 9 | } 10 | -------------------------------------------------------------------------------- /大润发运力监控.md: -------------------------------------------------------------------------------- 1 | ### 说明 2 | 操作步骤参考详细教程 --> 定时监控空余运力 3 | 4 | 详细代码 5 | 6 | ```javascript 7 | /** 8 | * 仅支持小程序抓包,app会校验证书 9 | * 抓包前请先加几件商品去购物车,抓包开启之后进入大润发优鲜小程序购物车页面多刷新几下,然后返回圈X查看抓包内容 10 | * 上面添加抓包的代码 11 | * 需要抓包的接口(仅支持小程序):https://yx.feiniu.com/cart-yxapp/shopcart/adminshopcart/cartget/t141 12 | * 找不到接口请搜索url 带有cartget关键字 13 | */ 14 | 15 | const myRequest = { 16 | url: url, 17 | method: method, 18 | headers: headers, 19 | body: body 20 | }; 21 | 22 | const $ = new Env("🎉 大润发 - 空余运力监控 🎉"); 23 | 24 | // 输入bark的key 不填写key使用圈X自带的通知 25 | var BarkKey = ""; 26 | 27 | // 测试通知(模拟通知),等号后面改成true即可模拟通知 28 | var testFlag = false; 29 | 30 | 31 | 32 | // 新增监控提示可配送的时间 33 | var pushTime = ''; 34 | 35 | 36 | // 启动脚本 关闭在前面加 // 37 | getTime(); 38 | 39 | // 推送通知 40 | function pushData(){ 41 | const pushUrl = `https://api.day.app/`+BarkKey+`/%E6%8E%A2%E5%AD%90%E6%9D%A5%E6%8A%A5%20%E2%86%92%20%E5%A4%A7%E6%B6%A6%E5%8F%91/`+pushTime+`?icon=https://is4-ssl.mzstatic.com/image/thumb/Purple112/v4/a2/48/4f/a2484f3f-c89c-dbd8-b5ef-291f8c6f1326/AppIcon-1x_U007emarketing-0-5-0-0-85-220.png/230x0w.webp&url=FNFreshAlipay://`; 42 | 43 | console.log("有空闲运力,赶紧打开大润发下单!!!!"); 44 | if(BarkKey == ""){ 45 | $.msg("有空闲运力,赶紧打开大润发下单!!!!") 46 | return; 47 | } 48 | $.get({url:pushUrl}, (error, response, data) => { 49 | if (error) { 50 | $.done(); 51 | } else { 52 | $.done(); 53 | } 54 | }); 55 | } 56 | 57 | // 获取配送时间 58 | function getTime(){ 59 | $.post( myRequest, (error, response, data) => { 60 | if (error) { 61 | console.log(error); 62 | $.done(); 63 | } else { 64 | dataProcess(data); 65 | $.done(); 66 | } 67 | }); 68 | } 69 | 70 | // 判断是否有空闲运力 71 | function getFlag(res) { 72 | if (res.body.notDelivery) { 73 | return false; 74 | } else { 75 | pushTime = encodeURI("监控到空闲运力,赶紧打开APP下单!!!"); 76 | return true; 77 | } 78 | } 79 | 80 | // 处理数据 81 | function dataProcess(data){ 82 | if(testFlag){ 83 | pushTime = encodeURI("这是测试通知"); 84 | pushData(); 85 | return; 86 | } 87 | 88 | // 判断请求是否成功 89 | var json = JSON.parse(data) 90 | if(!json.success){ 91 | $.msg(json.msg) 92 | }else{ 93 | if(getFlag(json)){ 94 | pushData(); 95 | }else{ 96 | console.log("当前运力已满,正在持续监控...") 97 | } 98 | } 99 | } 100 | 101 | // Env.min.js 102 | function Env(t,e){class s{constructor(t){this.env=t}send(t,e="GET"){t="string"==typeof t?{url:t}:t;let s=this.get;return"POST"===e&&(s=this.post),new Promise((e,i)=>{s.call(this,t,(t,s,r)=>{t?i(t):e(s)})})}get(t){return this.send.call(this.env,t)}post(t){return this.send.call(this.env,t,"POST")}}return new class{constructor(t,e){this.name=t,this.http=new s(this),this.data=null,this.dataFile="box.dat",this.logs=[],this.isMute=!1,this.isNeedRewrite=!1,this.logSeparator="\n",this.encoding="utf-8",this.startTime=(new Date).getTime(),Object.assign(this,e),this.log("",`\ud83d\udd14${this.name}, \u5f00\u59cb!`)}isNode(){return"undefined"!=typeof module&&!!module.exports}isQuanX(){return"undefined"!=typeof $task}isSurge(){return"undefined"!=typeof $httpClient&&"undefined"==typeof $loon}isLoon(){return"undefined"!=typeof $loon}isShadowrocket(){return"undefined"!=typeof $rocket}isStash(){return"undefined"!=typeof $environment&&$environment["stash-version"]}toObj(t,e=null){try{return JSON.parse(t)}catch{return e}}toStr(t,e=null){try{return JSON.stringify(t)}catch{return e}}getjson(t,e){let s=e;const i=this.getdata(t);if(i)try{s=JSON.parse(this.getdata(t))}catch{}return s}setjson(t,e){try{return this.setdata(JSON.stringify(t),e)}catch{return!1}}getScript(t){return new Promise(e=>{this.get({url:t},(t,s,i)=>e(i))})}runScript(t,e){return new Promise(s=>{let i=this.getdata("@chavy_boxjs_userCfgs.httpapi");i=i?i.replace(/\n/g,"").trim():i;let r=this.getdata("@chavy_boxjs_userCfgs.httpapi_timeout");r=r?1*r:20,r=e&&e.timeout?e.timeout:r;const[o,h]=i.split("@"),n={url:`http://${h}/v1/scripting/evaluate`,body:{script_text:t,mock_type:"cron",timeout:r},headers:{"X-Key":o,Accept:"*/*"}};this.post(n,(t,e,i)=>s(i))}).catch(t=>this.logErr(t))}loaddata(){if(!this.isNode())return{};{this.fs=this.fs?this.fs:require("fs"),this.path=this.path?this.path:require("path");const t=this.path.resolve(this.dataFile),e=this.path.resolve(process.cwd(),this.dataFile),s=this.fs.existsSync(t),i=!s&&this.fs.existsSync(e);if(!s&&!i)return{};{const i=s?t:e;try{return JSON.parse(this.fs.readFileSync(i))}catch(t){return{}}}}}writedata(){if(this.isNode()){this.fs=this.fs?this.fs:require("fs"),this.path=this.path?this.path:require("path");const t=this.path.resolve(this.dataFile),e=this.path.resolve(process.cwd(),this.dataFile),s=this.fs.existsSync(t),i=!s&&this.fs.existsSync(e),r=JSON.stringify(this.data);s?this.fs.writeFileSync(t,r):i?this.fs.writeFileSync(e,r):this.fs.writeFileSync(t,r)}}lodash_get(t,e,s){const i=e.replace(/\[(\d+)\]/g,".$1").split(".");let r=t;for(const t of i)if(r=Object(r)[t],void 0===r)return s;return r}lodash_set(t,e,s){return Object(t)!==t?t:(Array.isArray(e)||(e=e.toString().match(/[^.[\]]+/g)||[]),e.slice(0,-1).reduce((t,s,i)=>Object(t[s])===t[s]?t[s]:t[s]=Math.abs(e[i+1])>>0==+e[i+1]?[]:{},t)[e[e.length-1]]=s,t)}getdata(t){let e=this.getval(t);if(/^@/.test(t)){const[,s,i]=/^@(.*?)\.(.*?)$/.exec(t),r=s?this.getval(s):"";if(r)try{const t=JSON.parse(r);e=t?this.lodash_get(t,i,""):e}catch(t){e=""}}return e}setdata(t,e){let s=!1;if(/^@/.test(e)){const[,i,r]=/^@(.*?)\.(.*?)$/.exec(e),o=this.getval(i),h=i?"null"===o?null:o||"{}":"{}";try{const e=JSON.parse(h);this.lodash_set(e,r,t),s=this.setval(JSON.stringify(e),i)}catch(e){const o={};this.lodash_set(o,r,t),s=this.setval(JSON.stringify(o),i)}}else s=this.setval(t,e);return s}getval(t){return this.isSurge()||this.isLoon()?$persistentStore.read(t):this.isQuanX()?$prefs.valueForKey(t):this.isNode()?(this.data=this.loaddata(),this.data[t]):this.data&&this.data[t]||null}setval(t,e){return this.isSurge()||this.isLoon()?$persistentStore.write(t,e):this.isQuanX()?$prefs.setValueForKey(t,e):this.isNode()?(this.data=this.loaddata(),this.data[e]=t,this.writedata(),!0):this.data&&this.data[e]||null}initGotEnv(t){this.got=this.got?this.got:require("got"),this.cktough=this.cktough?this.cktough:require("tough-cookie"),this.ckjar=this.ckjar?this.ckjar:new this.cktough.CookieJar,t&&(t.headers=t.headers?t.headers:{},void 0===t.headers.Cookie&&void 0===t.cookieJar&&(t.cookieJar=this.ckjar))}get(t,e=(()=>{})){if(t.headers&&(delete t.headers["Content-Type"],delete t.headers["Content-Length"]),this.isSurge()||this.isLoon())this.isSurge()&&this.isNeedRewrite&&(t.headers=t.headers||{},Object.assign(t.headers,{"X-Surge-Skip-Scripting":!1})),$httpClient.get(t,(t,s,i)=>{!t&&s&&(s.body=i,s.statusCode=s.status),e(t,s,i)});else if(this.isQuanX())this.isNeedRewrite&&(t.opts=t.opts||{},Object.assign(t.opts,{hints:!1})),$task.fetch(t).then(t=>{const{statusCode:s,statusCode:i,headers:r,body:o}=t;e(null,{status:s,statusCode:i,headers:r,body:o},o)},t=>e(t));else if(this.isNode()){let s=require("iconv-lite");this.initGotEnv(t),this.got(t).on("redirect",(t,e)=>{try{if(t.headers["set-cookie"]){const s=t.headers["set-cookie"].map(this.cktough.Cookie.parse).toString();s&&this.ckjar.setCookieSync(s,null),e.cookieJar=this.ckjar}}catch(t){this.logErr(t)}}).then(t=>{const{statusCode:i,statusCode:r,headers:o,rawBody:h}=t;e(null,{status:i,statusCode:r,headers:o,rawBody:h},s.decode(h,this.encoding))},t=>{const{message:i,response:r}=t;e(i,r,r&&s.decode(r.rawBody,this.encoding))})}}post(t,e=(()=>{})){const s=t.method?t.method.toLocaleLowerCase():"post";if(t.body&&t.headers&&!t.headers["Content-Type"]&&(t.headers["Content-Type"]="application/x-www-form-urlencoded"),t.headers&&delete t.headers["Content-Length"],this.isSurge()||this.isLoon())this.isSurge()&&this.isNeedRewrite&&(t.headers=t.headers||{},Object.assign(t.headers,{"X-Surge-Skip-Scripting":!1})),$httpClient[s](t,(t,s,i)=>{!t&&s&&(s.body=i,s.statusCode=s.status),e(t,s,i)});else if(this.isQuanX())t.method=s,this.isNeedRewrite&&(t.opts=t.opts||{},Object.assign(t.opts,{hints:!1})),$task.fetch(t).then(t=>{const{statusCode:s,statusCode:i,headers:r,body:o}=t;e(null,{status:s,statusCode:i,headers:r,body:o},o)},t=>e(t));else if(this.isNode()){let i=require("iconv-lite");this.initGotEnv(t);const{url:r,...o}=t;this.got[s](r,o).then(t=>{const{statusCode:s,statusCode:r,headers:o,rawBody:h}=t;e(null,{status:s,statusCode:r,headers:o,rawBody:h},i.decode(h,this.encoding))},t=>{const{message:s,response:r}=t;e(s,r,r&&i.decode(r.rawBody,this.encoding))})}}time(t,e=null){const s=e?new Date(e):new Date;let i={"M+":s.getMonth()+1,"d+":s.getDate(),"H+":s.getHours(),"m+":s.getMinutes(),"s+":s.getSeconds(),"q+":Math.floor((s.getMonth()+3)/3),S:s.getMilliseconds()};/(y+)/.test(t)&&(t=t.replace(RegExp.$1,(s.getFullYear()+"").substr(4-RegExp.$1.length)));for(let e in i)new RegExp("("+e+")").test(t)&&(t=t.replace(RegExp.$1,1==RegExp.$1.length?i[e]:("00"+i[e]).substr((""+i[e]).length)));return t}msg(e=t,s="",i="",r){const o=t=>{if(!t)return t;if("string"==typeof t)return this.isLoon()?t:this.isQuanX()?{"open-url":t}:this.isSurge()?{url:t}:void 0;if("object"==typeof t){if(this.isLoon()){let e=t.openUrl||t.url||t["open-url"],s=t.mediaUrl||t["media-url"];return{openUrl:e,mediaUrl:s}}if(this.isQuanX()){let e=t["open-url"]||t.url||t.openUrl,s=t["media-url"]||t.mediaUrl,i=t["update-pasteboard"]||t.updatePasteboard;return{"open-url":e,"media-url":s,"update-pasteboard":i}}if(this.isSurge()){let e=t.url||t.openUrl||t["open-url"];return{url:e}}}};if(this.isMute||(this.isSurge()||this.isLoon()?$notification.post(e,s,i,o(r)):this.isQuanX()&&$notify(e,s,i,o(r))),!this.isMuteLog){let t=["","==============\ud83d\udce3\u7cfb\u7edf\u901a\u77e5\ud83d\udce3=============="];t.push(e),s&&t.push(s),i&&t.push(i),console.log(t.join("\n")),this.logs=this.logs.concat(t)}}log(...t){t.length>0&&(this.logs=[...this.logs,...t]),console.log(t.join(this.logSeparator))}logErr(t,e){const s=!this.isSurge()&&!this.isQuanX()&&!this.isLoon();s?this.log("",`\u2757\ufe0f${this.name}, \u9519\u8bef!`,t.stack):this.log("",`\u2757\ufe0f${this.name}, \u9519\u8bef!`,t)}wait(t){return new Promise(e=>setTimeout(e,t))}done(t={}){const e=(new Date).getTime(),s=(e-this.startTime)/1e3;this.log("",`\ud83d\udd14${this.name}, \u7ed3\u675f! \ud83d\udd5b ${s} \u79d2`),this.log(),(this.isSurge()||this.isQuanX()||this.isLoon())&&$done(t)}}(t,e)} 103 | 104 | 105 | ``` -------------------------------------------------------------------------------- /定时监控视频.mp4: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wu491925129/script/e71d3d7c2f1d521b5344260ba669324e8509a1a0/定时监控视频.mp4 -------------------------------------------------------------------------------- /山姆超市运力监控.md: -------------------------------------------------------------------------------- 1 | ### 说明 2 | 操作步骤参考详细教程 --> 定时监控空余运力 3 | 4 | 详细代码 5 | ``` 6 | /** 7 | * 上面添加抓包的代码 8 | * 需要抓包的接口:https://api-sams.walmartmobile.cn/api/v1/sams/delivery/portal/getCapacityData 9 | */ 10 | 11 | const myRequest = { 12 | url: url, 13 | method: method, 14 | headers: headers, 15 | body: body 16 | }; 17 | 18 | const $ = new Env("🎉 山姆超市 - 空余运力监控 🎉"); 19 | 20 | // 输入bark的key 不填写key使用圈X自带的通知 21 | var BarkKey = ""; 22 | 23 | // 测试通知(模拟通知),等号后面改成true即可模拟通知 24 | var testFlag = false; 25 | 26 | 27 | 28 | // 新增监控提示可配送的时间 29 | var pushTime = ''; 30 | 31 | 32 | // 启动脚本 关闭在前面加 // 33 | getTime(); 34 | 35 | // 推送通知 36 | function pushData(){ 37 | const pushUrl = `https://api.day.app/`+BarkKey+`/%E6%8E%A2%E5%AD%90%E6%9D%A5%E6%8A%A5%20%E2%86%92%20%E5%B1%B1%E5%A7%86%E8%B6%85%E5%B8%82/`+pushTime+`?icon=https://is1-ssl.mzstatic.com/image/thumb/Purple112/v4/8c/b8/14/8cb81421-1149-4b80-50f4-d4a2113a5f0c/AppIcon-1x_U007emarketing-0-4-0-0-85-220.png/230x0w.webp&url=sams://`; 38 | 39 | console.log("有空闲运力,赶紧打开山姆下单!!!!"); 40 | if(BarkKey == ""){ 41 | $.msg("有空闲运力,赶紧打开山姆下单!!!!") 42 | return; 43 | } 44 | $.get({url:pushUrl}, (error, response, data) => { 45 | if (error) { 46 | $.done(); 47 | } else { 48 | $.done(); 49 | } 50 | }); 51 | } 52 | 53 | // 获取配送时间 54 | function getTime(){ 55 | $.post( myRequest, (error, response, data) => { 56 | if (error) { 57 | console.log(error); 58 | $.done(); 59 | } else { 60 | dataProcess(data); 61 | $.done(); 62 | } 63 | }); 64 | } 65 | 66 | // 判断是否有空闲运力 67 | function getFlag(res) { 68 | var hasFlag = false; 69 | res.data.capcityResponseList.forEach(function (item) { 70 | if (!item.dateISFull) { 71 | hasFlag = true; 72 | pushTime = encodeURI("监控到空闲运力,赶紧打开APP下单!!!"); 73 | } 74 | }) 75 | } 76 | 77 | // 处理数据 78 | function dataProcess(data){ 79 | if(testFlag){ 80 | pushTime = encodeURI("这是测试通知"); 81 | pushData(); 82 | return; 83 | } 84 | 85 | // 判断请求是否成功 86 | var json = JSON.parse(data) 87 | if(!json.success){ 88 | $.msg(json.msg) 89 | }else{ 90 | if(getFlag(json)){ 91 | pushData(); 92 | }else{ 93 | console.log("当前运力已满,正在持续监控...") 94 | } 95 | } 96 | } 97 | 98 | // Env.min.js 99 | function Env(t,e){class s{constructor(t){this.env=t}send(t,e="GET"){t="string"==typeof t?{url:t}:t;let s=this.get;return"POST"===e&&(s=this.post),new Promise((e,i)=>{s.call(this,t,(t,s,r)=>{t?i(t):e(s)})})}get(t){return this.send.call(this.env,t)}post(t){return this.send.call(this.env,t,"POST")}}return new class{constructor(t,e){this.name=t,this.http=new s(this),this.data=null,this.dataFile="box.dat",this.logs=[],this.isMute=!1,this.isNeedRewrite=!1,this.logSeparator="\n",this.encoding="utf-8",this.startTime=(new Date).getTime(),Object.assign(this,e),this.log("",`\ud83d\udd14${this.name}, \u5f00\u59cb!`)}isNode(){return"undefined"!=typeof module&&!!module.exports}isQuanX(){return"undefined"!=typeof $task}isSurge(){return"undefined"!=typeof $httpClient&&"undefined"==typeof $loon}isLoon(){return"undefined"!=typeof $loon}isShadowrocket(){return"undefined"!=typeof $rocket}isStash(){return"undefined"!=typeof $environment&&$environment["stash-version"]}toObj(t,e=null){try{return JSON.parse(t)}catch{return e}}toStr(t,e=null){try{return JSON.stringify(t)}catch{return e}}getjson(t,e){let s=e;const i=this.getdata(t);if(i)try{s=JSON.parse(this.getdata(t))}catch{}return s}setjson(t,e){try{return this.setdata(JSON.stringify(t),e)}catch{return!1}}getScript(t){return new Promise(e=>{this.get({url:t},(t,s,i)=>e(i))})}runScript(t,e){return new Promise(s=>{let i=this.getdata("@chavy_boxjs_userCfgs.httpapi");i=i?i.replace(/\n/g,"").trim():i;let r=this.getdata("@chavy_boxjs_userCfgs.httpapi_timeout");r=r?1*r:20,r=e&&e.timeout?e.timeout:r;const[o,h]=i.split("@"),n={url:`http://${h}/v1/scripting/evaluate`,body:{script_text:t,mock_type:"cron",timeout:r},headers:{"X-Key":o,Accept:"*/*"}};this.post(n,(t,e,i)=>s(i))}).catch(t=>this.logErr(t))}loaddata(){if(!this.isNode())return{};{this.fs=this.fs?this.fs:require("fs"),this.path=this.path?this.path:require("path");const t=this.path.resolve(this.dataFile),e=this.path.resolve(process.cwd(),this.dataFile),s=this.fs.existsSync(t),i=!s&&this.fs.existsSync(e);if(!s&&!i)return{};{const i=s?t:e;try{return JSON.parse(this.fs.readFileSync(i))}catch(t){return{}}}}}writedata(){if(this.isNode()){this.fs=this.fs?this.fs:require("fs"),this.path=this.path?this.path:require("path");const t=this.path.resolve(this.dataFile),e=this.path.resolve(process.cwd(),this.dataFile),s=this.fs.existsSync(t),i=!s&&this.fs.existsSync(e),r=JSON.stringify(this.data);s?this.fs.writeFileSync(t,r):i?this.fs.writeFileSync(e,r):this.fs.writeFileSync(t,r)}}lodash_get(t,e,s){const i=e.replace(/\[(\d+)\]/g,".$1").split(".");let r=t;for(const t of i)if(r=Object(r)[t],void 0===r)return s;return r}lodash_set(t,e,s){return Object(t)!==t?t:(Array.isArray(e)||(e=e.toString().match(/[^.[\]]+/g)||[]),e.slice(0,-1).reduce((t,s,i)=>Object(t[s])===t[s]?t[s]:t[s]=Math.abs(e[i+1])>>0==+e[i+1]?[]:{},t)[e[e.length-1]]=s,t)}getdata(t){let e=this.getval(t);if(/^@/.test(t)){const[,s,i]=/^@(.*?)\.(.*?)$/.exec(t),r=s?this.getval(s):"";if(r)try{const t=JSON.parse(r);e=t?this.lodash_get(t,i,""):e}catch(t){e=""}}return e}setdata(t,e){let s=!1;if(/^@/.test(e)){const[,i,r]=/^@(.*?)\.(.*?)$/.exec(e),o=this.getval(i),h=i?"null"===o?null:o||"{}":"{}";try{const e=JSON.parse(h);this.lodash_set(e,r,t),s=this.setval(JSON.stringify(e),i)}catch(e){const o={};this.lodash_set(o,r,t),s=this.setval(JSON.stringify(o),i)}}else s=this.setval(t,e);return s}getval(t){return this.isSurge()||this.isLoon()?$persistentStore.read(t):this.isQuanX()?$prefs.valueForKey(t):this.isNode()?(this.data=this.loaddata(),this.data[t]):this.data&&this.data[t]||null}setval(t,e){return this.isSurge()||this.isLoon()?$persistentStore.write(t,e):this.isQuanX()?$prefs.setValueForKey(t,e):this.isNode()?(this.data=this.loaddata(),this.data[e]=t,this.writedata(),!0):this.data&&this.data[e]||null}initGotEnv(t){this.got=this.got?this.got:require("got"),this.cktough=this.cktough?this.cktough:require("tough-cookie"),this.ckjar=this.ckjar?this.ckjar:new this.cktough.CookieJar,t&&(t.headers=t.headers?t.headers:{},void 0===t.headers.Cookie&&void 0===t.cookieJar&&(t.cookieJar=this.ckjar))}get(t,e=(()=>{})){if(t.headers&&(delete t.headers["Content-Type"],delete t.headers["Content-Length"]),this.isSurge()||this.isLoon())this.isSurge()&&this.isNeedRewrite&&(t.headers=t.headers||{},Object.assign(t.headers,{"X-Surge-Skip-Scripting":!1})),$httpClient.get(t,(t,s,i)=>{!t&&s&&(s.body=i,s.statusCode=s.status),e(t,s,i)});else if(this.isQuanX())this.isNeedRewrite&&(t.opts=t.opts||{},Object.assign(t.opts,{hints:!1})),$task.fetch(t).then(t=>{const{statusCode:s,statusCode:i,headers:r,body:o}=t;e(null,{status:s,statusCode:i,headers:r,body:o},o)},t=>e(t));else if(this.isNode()){let s=require("iconv-lite");this.initGotEnv(t),this.got(t).on("redirect",(t,e)=>{try{if(t.headers["set-cookie"]){const s=t.headers["set-cookie"].map(this.cktough.Cookie.parse).toString();s&&this.ckjar.setCookieSync(s,null),e.cookieJar=this.ckjar}}catch(t){this.logErr(t)}}).then(t=>{const{statusCode:i,statusCode:r,headers:o,rawBody:h}=t;e(null,{status:i,statusCode:r,headers:o,rawBody:h},s.decode(h,this.encoding))},t=>{const{message:i,response:r}=t;e(i,r,r&&s.decode(r.rawBody,this.encoding))})}}post(t,e=(()=>{})){const s=t.method?t.method.toLocaleLowerCase():"post";if(t.body&&t.headers&&!t.headers["Content-Type"]&&(t.headers["Content-Type"]="application/x-www-form-urlencoded"),t.headers&&delete t.headers["Content-Length"],this.isSurge()||this.isLoon())this.isSurge()&&this.isNeedRewrite&&(t.headers=t.headers||{},Object.assign(t.headers,{"X-Surge-Skip-Scripting":!1})),$httpClient[s](t,(t,s,i)=>{!t&&s&&(s.body=i,s.statusCode=s.status),e(t,s,i)});else if(this.isQuanX())t.method=s,this.isNeedRewrite&&(t.opts=t.opts||{},Object.assign(t.opts,{hints:!1})),$task.fetch(t).then(t=>{const{statusCode:s,statusCode:i,headers:r,body:o}=t;e(null,{status:s,statusCode:i,headers:r,body:o},o)},t=>e(t));else if(this.isNode()){let i=require("iconv-lite");this.initGotEnv(t);const{url:r,...o}=t;this.got[s](r,o).then(t=>{const{statusCode:s,statusCode:r,headers:o,rawBody:h}=t;e(null,{status:s,statusCode:r,headers:o,rawBody:h},i.decode(h,this.encoding))},t=>{const{message:s,response:r}=t;e(s,r,r&&i.decode(r.rawBody,this.encoding))})}}time(t,e=null){const s=e?new Date(e):new Date;let i={"M+":s.getMonth()+1,"d+":s.getDate(),"H+":s.getHours(),"m+":s.getMinutes(),"s+":s.getSeconds(),"q+":Math.floor((s.getMonth()+3)/3),S:s.getMilliseconds()};/(y+)/.test(t)&&(t=t.replace(RegExp.$1,(s.getFullYear()+"").substr(4-RegExp.$1.length)));for(let e in i)new RegExp("("+e+")").test(t)&&(t=t.replace(RegExp.$1,1==RegExp.$1.length?i[e]:("00"+i[e]).substr((""+i[e]).length)));return t}msg(e=t,s="",i="",r){const o=t=>{if(!t)return t;if("string"==typeof t)return this.isLoon()?t:this.isQuanX()?{"open-url":t}:this.isSurge()?{url:t}:void 0;if("object"==typeof t){if(this.isLoon()){let e=t.openUrl||t.url||t["open-url"],s=t.mediaUrl||t["media-url"];return{openUrl:e,mediaUrl:s}}if(this.isQuanX()){let e=t["open-url"]||t.url||t.openUrl,s=t["media-url"]||t.mediaUrl,i=t["update-pasteboard"]||t.updatePasteboard;return{"open-url":e,"media-url":s,"update-pasteboard":i}}if(this.isSurge()){let e=t.url||t.openUrl||t["open-url"];return{url:e}}}};if(this.isMute||(this.isSurge()||this.isLoon()?$notification.post(e,s,i,o(r)):this.isQuanX()&&$notify(e,s,i,o(r))),!this.isMuteLog){let t=["","==============\ud83d\udce3\u7cfb\u7edf\u901a\u77e5\ud83d\udce3=============="];t.push(e),s&&t.push(s),i&&t.push(i),console.log(t.join("\n")),this.logs=this.logs.concat(t)}}log(...t){t.length>0&&(this.logs=[...this.logs,...t]),console.log(t.join(this.logSeparator))}logErr(t,e){const s=!this.isSurge()&&!this.isQuanX()&&!this.isLoon();s?this.log("",`\u2757\ufe0f${this.name}, \u9519\u8bef!`,t.stack):this.log("",`\u2757\ufe0f${this.name}, \u9519\u8bef!`,t)}wait(t){return new Promise(e=>setTimeout(e,t))}done(t={}){const e=(new Date).getTime(),s=(e-this.startTime)/1e3;this.log("",`\ud83d\udd14${this.name}, \u7ed3\u675f! \ud83d\udd5b ${s} \u79d2`),this.log(),(this.isSurge()||this.isQuanX()||this.isLoon())&&$done(t)}}(t,e)} 100 | 101 | 102 | 103 | ``` -------------------------------------------------------------------------------- /抓包视频.mp4: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wu491925129/script/e71d3d7c2f1d521b5344260ba669324e8509a1a0/抓包视频.mp4 -------------------------------------------------------------------------------- /羊了个羊破解.md: -------------------------------------------------------------------------------- 1 | ### 羊了个羊通关教程(基于圈X) 2 | #### 操作步骤(需要翻墙) 3 | 4 | 1. 打开圈X设置 - Mitm开关 5 | 2. MitM - 添加主机名 cat-match.easygame2021.com 6 | 3. 重写 - 添加 7 | 1. 重写类型:script-response-body 8 | 2. 匹配URL:https://cat-match.easygame2021.com/sheep/v1/game/map_info 9 | 3. 脚本路径:https://raw.githubusercontent.com/wu491925129/script/main/stupidSheep.js 10 | 4. 重写 - 添加 (0920) 11 | 1. 重写类型:script-response-body 12 | 2. 匹配URL:https://cat-match.easygame2021.com/sheep/v1/game/map_info_ex 13 | 3. 脚本路径:https://raw.githubusercontent.com/wu491925129/script/main/fuckSheep.js 14 | 5. 第一次配好开梯子,更新脚本,后面不需要 15 | -------------------------------------------------------------------------------- /详细教程.md: -------------------------------------------------------------------------------- 1 | ## 叮咚买菜抓包+监控 2 | 3 | ### 更新说明 4 | 由于近期叮咚买菜服务端更新了校验规则,原来获取直接获取配送时间的接口已经不可用(服务端做了各种校验)。另辟蹊径,我们可以通过首页的配送站点通知来确定当前站点是否有空闲运力,可能会有延迟。 5 | 6 | ### 问题说明 7 | - 当有通知时点击通知跳转叮咚买菜会提示当前软件版本过低,这是因为叮咚买菜没有开放购物车的URL scheme导致的,并不需要更新app,直接点击左上角的返回即可。 8 | ### 需要的软件 9 | 10 | 1. quantumult X 11 | 1. 抓包 12 | 2. 定时监控 13 | 3. 重写返回值 14 | 4. 可以实现科学上网(具体百度) 15 | 2. bark(推送通知) 16 | 17 | ### quantumult X软件配置证书 18 | 1. 点击圈X 右下角风车标志进入设置 19 | 2. 开启MitM 20 | 3. 点击配置证书 21 | 4. 跳转Safari浏览器安装证书 22 | 5. 设置 - 通用 - 关于本机 - 证书信任设置信任证书 23 | 6. 设置- 通用 - VPN与设备管理信任证书 24 | 25 | ### 抓包 26 | 27 | 抓包前需要做的事情 28 | - 安装证书并信任证书 29 | - 圈X右上角的开关请打开 30 | - 设置 - MitM的开关请打开 31 | 32 | 33 | 34 | 35 | ### 定时监控空余运力 36 | 监控定时器Corn表达式说明: 37 | 38 | 例如: 39 | 40 | 0/1 * * * * ? 41 | 42 | 表示从0秒开始,每秒执行一次 43 | 44 | 0/1 * 6,7,8,9,10,11,12,13,14,15,16,17,18,19,20 * * ? 45 | 46 | 表示每天早上6点到晚上8点,从0秒开始每秒执行一次 47 | 48 | 表达式说明: 49 | 50 | 秒 0-59 , - * / 51 | 52 | 分 0-59 , - * / 53 | 54 | 小时 0-23 , - * / 55 | 56 | 日期 1-31 , - * ? / L W C 57 | 58 | 月份 1-12 或者 JAN-DEC , - * / 59 | 60 | 星期 1-7 或者 SUN-SAT , - * ? / L C # 61 | 62 | 年(可选) 留空, 1970-2099 , - * / 63 | 64 | 65 | 详细教程见附件定时监控教程 66 | 67 | 68 | 69 | 70 | ``` 71 | /** 72 | * 上面的内容替换成你刚刚抓取配送时间的内容 73 | * 打开叮咚买菜首页,刷新几下 74 | * 需要抓包的接口:https://maicai.api.ddxq.mobi/homeApi/newDetails?xxxxx 75 | */ 76 | 77 | const myRequest = { 78 | url: url, 79 | method: method, 80 | headers: headers 81 | }; 82 | 83 | const $ = new Env("🎉 叮咚买菜 - 空余运力监控 🎉"); 84 | 85 | // 输入bark的key 不填写key使用圈X自带的通知 86 | var BarkKey = ""; 87 | 88 | // 测试通知(模拟通知),等号后面改成true即可模拟通知 89 | var testFlag = false; 90 | 91 | 92 | 93 | // 新增监控提示可配送的时间 94 | var pushTime = ''; 95 | 96 | 97 | // 启动脚本 关闭在前面加 // 98 | getTime(); 99 | 100 | // 推送通知 101 | function pushData(){ 102 | const pushUrl = `https://api.day.app/`+BarkKey+`/%E6%8E%A2%E5%AD%90%E6%9D%A5%E6%8A%A5%20%E2%86%92%20%E5%8F%AE%E5%92%9A%E4%B9%B0%E8%8F%9C/`+pushTime+`?icon=https://raw.githubusercontent.com/Orz-3/mini/master/Color/mcdd.png&url=ddxq://`; 103 | 104 | console.log("有空闲运力,赶紧打开叮咚下单!!!!"); 105 | if(BarkKey == ""){ 106 | $.msg("有空闲运力,赶紧打开叮咚下单!!!!") 107 | return; 108 | } 109 | $.get({url:pushUrl}, (error, response, data) => { 110 | if (error) { 111 | $.done(); 112 | } else { 113 | $.done(); 114 | } 115 | }); 116 | } 117 | 118 | // 获取配送时间 119 | function getTime(){ 120 | $.post( myRequest, (error, response, data) => { 121 | if (error) { 122 | console.log(error); 123 | $.done(); 124 | } else { 125 | dataProcess(data); 126 | $.done(); 127 | } 128 | }); 129 | } 130 | 131 | // 判断是否有空闲运力 132 | function getFlag(res) { 133 | var hasFlag = false; 134 | res.data.list.forEach(item=>{ 135 | if(item.type == 5 && !item.new_bill_board.materials[0].content.concat("已约满")){ 136 | hasFlag = true; 137 | pushTime = encodeURI(item.new_bill_board.materials[0].content); 138 | } 139 | }) 140 | return hasFlag; 141 | } 142 | 143 | // 处理数据 144 | function dataProcess(data){ 145 | if(testFlag){ 146 | pushTime = encodeURI("这是测试通知"); 147 | pushData(); 148 | return; 149 | } 150 | 151 | // 判断请求是否成功 152 | var json = JSON.parse(data) 153 | if(!json.success){ 154 | $.msg(json.msg) 155 | }else{ 156 | if(getFlag(json)){ 157 | pushData(); 158 | }else{ 159 | console.log("当前运力已满,正在持续监控...") 160 | } 161 | } 162 | } 163 | 164 | // Env.min.js 165 | function Env(t,e){class s{constructor(t){this.env=t}send(t,e="GET"){t="string"==typeof t?{url:t}:t;let s=this.get;return"POST"===e&&(s=this.post),new Promise((e,i)=>{s.call(this,t,(t,s,r)=>{t?i(t):e(s)})})}get(t){return this.send.call(this.env,t)}post(t){return this.send.call(this.env,t,"POST")}}return new class{constructor(t,e){this.name=t,this.http=new s(this),this.data=null,this.dataFile="box.dat",this.logs=[],this.isMute=!1,this.isNeedRewrite=!1,this.logSeparator="\n",this.encoding="utf-8",this.startTime=(new Date).getTime(),Object.assign(this,e),this.log("",`\ud83d\udd14${this.name}, \u5f00\u59cb!`)}isNode(){return"undefined"!=typeof module&&!!module.exports}isQuanX(){return"undefined"!=typeof $task}isSurge(){return"undefined"!=typeof $httpClient&&"undefined"==typeof $loon}isLoon(){return"undefined"!=typeof $loon}isShadowrocket(){return"undefined"!=typeof $rocket}isStash(){return"undefined"!=typeof $environment&&$environment["stash-version"]}toObj(t,e=null){try{return JSON.parse(t)}catch{return e}}toStr(t,e=null){try{return JSON.stringify(t)}catch{return e}}getjson(t,e){let s=e;const i=this.getdata(t);if(i)try{s=JSON.parse(this.getdata(t))}catch{}return s}setjson(t,e){try{return this.setdata(JSON.stringify(t),e)}catch{return!1}}getScript(t){return new Promise(e=>{this.get({url:t},(t,s,i)=>e(i))})}runScript(t,e){return new Promise(s=>{let i=this.getdata("@chavy_boxjs_userCfgs.httpapi");i=i?i.replace(/\n/g,"").trim():i;let r=this.getdata("@chavy_boxjs_userCfgs.httpapi_timeout");r=r?1*r:20,r=e&&e.timeout?e.timeout:r;const[o,h]=i.split("@"),n={url:`http://${h}/v1/scripting/evaluate`,body:{script_text:t,mock_type:"cron",timeout:r},headers:{"X-Key":o,Accept:"*/*"}};this.post(n,(t,e,i)=>s(i))}).catch(t=>this.logErr(t))}loaddata(){if(!this.isNode())return{};{this.fs=this.fs?this.fs:require("fs"),this.path=this.path?this.path:require("path");const t=this.path.resolve(this.dataFile),e=this.path.resolve(process.cwd(),this.dataFile),s=this.fs.existsSync(t),i=!s&&this.fs.existsSync(e);if(!s&&!i)return{};{const i=s?t:e;try{return JSON.parse(this.fs.readFileSync(i))}catch(t){return{}}}}}writedata(){if(this.isNode()){this.fs=this.fs?this.fs:require("fs"),this.path=this.path?this.path:require("path");const t=this.path.resolve(this.dataFile),e=this.path.resolve(process.cwd(),this.dataFile),s=this.fs.existsSync(t),i=!s&&this.fs.existsSync(e),r=JSON.stringify(this.data);s?this.fs.writeFileSync(t,r):i?this.fs.writeFileSync(e,r):this.fs.writeFileSync(t,r)}}lodash_get(t,e,s){const i=e.replace(/\[(\d+)\]/g,".$1").split(".");let r=t;for(const t of i)if(r=Object(r)[t],void 0===r)return s;return r}lodash_set(t,e,s){return Object(t)!==t?t:(Array.isArray(e)||(e=e.toString().match(/[^.[\]]+/g)||[]),e.slice(0,-1).reduce((t,s,i)=>Object(t[s])===t[s]?t[s]:t[s]=Math.abs(e[i+1])>>0==+e[i+1]?[]:{},t)[e[e.length-1]]=s,t)}getdata(t){let e=this.getval(t);if(/^@/.test(t)){const[,s,i]=/^@(.*?)\.(.*?)$/.exec(t),r=s?this.getval(s):"";if(r)try{const t=JSON.parse(r);e=t?this.lodash_get(t,i,""):e}catch(t){e=""}}return e}setdata(t,e){let s=!1;if(/^@/.test(e)){const[,i,r]=/^@(.*?)\.(.*?)$/.exec(e),o=this.getval(i),h=i?"null"===o?null:o||"{}":"{}";try{const e=JSON.parse(h);this.lodash_set(e,r,t),s=this.setval(JSON.stringify(e),i)}catch(e){const o={};this.lodash_set(o,r,t),s=this.setval(JSON.stringify(o),i)}}else s=this.setval(t,e);return s}getval(t){return this.isSurge()||this.isLoon()?$persistentStore.read(t):this.isQuanX()?$prefs.valueForKey(t):this.isNode()?(this.data=this.loaddata(),this.data[t]):this.data&&this.data[t]||null}setval(t,e){return this.isSurge()||this.isLoon()?$persistentStore.write(t,e):this.isQuanX()?$prefs.setValueForKey(t,e):this.isNode()?(this.data=this.loaddata(),this.data[e]=t,this.writedata(),!0):this.data&&this.data[e]||null}initGotEnv(t){this.got=this.got?this.got:require("got"),this.cktough=this.cktough?this.cktough:require("tough-cookie"),this.ckjar=this.ckjar?this.ckjar:new this.cktough.CookieJar,t&&(t.headers=t.headers?t.headers:{},void 0===t.headers.Cookie&&void 0===t.cookieJar&&(t.cookieJar=this.ckjar))}get(t,e=(()=>{})){if(t.headers&&(delete t.headers["Content-Type"],delete t.headers["Content-Length"]),this.isSurge()||this.isLoon())this.isSurge()&&this.isNeedRewrite&&(t.headers=t.headers||{},Object.assign(t.headers,{"X-Surge-Skip-Scripting":!1})),$httpClient.get(t,(t,s,i)=>{!t&&s&&(s.body=i,s.statusCode=s.status),e(t,s,i)});else if(this.isQuanX())this.isNeedRewrite&&(t.opts=t.opts||{},Object.assign(t.opts,{hints:!1})),$task.fetch(t).then(t=>{const{statusCode:s,statusCode:i,headers:r,body:o}=t;e(null,{status:s,statusCode:i,headers:r,body:o},o)},t=>e(t));else if(this.isNode()){let s=require("iconv-lite");this.initGotEnv(t),this.got(t).on("redirect",(t,e)=>{try{if(t.headers["set-cookie"]){const s=t.headers["set-cookie"].map(this.cktough.Cookie.parse).toString();s&&this.ckjar.setCookieSync(s,null),e.cookieJar=this.ckjar}}catch(t){this.logErr(t)}}).then(t=>{const{statusCode:i,statusCode:r,headers:o,rawBody:h}=t;e(null,{status:i,statusCode:r,headers:o,rawBody:h},s.decode(h,this.encoding))},t=>{const{message:i,response:r}=t;e(i,r,r&&s.decode(r.rawBody,this.encoding))})}}post(t,e=(()=>{})){const s=t.method?t.method.toLocaleLowerCase():"post";if(t.body&&t.headers&&!t.headers["Content-Type"]&&(t.headers["Content-Type"]="application/x-www-form-urlencoded"),t.headers&&delete t.headers["Content-Length"],this.isSurge()||this.isLoon())this.isSurge()&&this.isNeedRewrite&&(t.headers=t.headers||{},Object.assign(t.headers,{"X-Surge-Skip-Scripting":!1})),$httpClient[s](t,(t,s,i)=>{!t&&s&&(s.body=i,s.statusCode=s.status),e(t,s,i)});else if(this.isQuanX())t.method=s,this.isNeedRewrite&&(t.opts=t.opts||{},Object.assign(t.opts,{hints:!1})),$task.fetch(t).then(t=>{const{statusCode:s,statusCode:i,headers:r,body:o}=t;e(null,{status:s,statusCode:i,headers:r,body:o},o)},t=>e(t));else if(this.isNode()){let i=require("iconv-lite");this.initGotEnv(t);const{url:r,...o}=t;this.got[s](r,o).then(t=>{const{statusCode:s,statusCode:r,headers:o,rawBody:h}=t;e(null,{status:s,statusCode:r,headers:o,rawBody:h},i.decode(h,this.encoding))},t=>{const{message:s,response:r}=t;e(s,r,r&&i.decode(r.rawBody,this.encoding))})}}time(t,e=null){const s=e?new Date(e):new Date;let i={"M+":s.getMonth()+1,"d+":s.getDate(),"H+":s.getHours(),"m+":s.getMinutes(),"s+":s.getSeconds(),"q+":Math.floor((s.getMonth()+3)/3),S:s.getMilliseconds()};/(y+)/.test(t)&&(t=t.replace(RegExp.$1,(s.getFullYear()+"").substr(4-RegExp.$1.length)));for(let e in i)new RegExp("("+e+")").test(t)&&(t=t.replace(RegExp.$1,1==RegExp.$1.length?i[e]:("00"+i[e]).substr((""+i[e]).length)));return t}msg(e=t,s="",i="",r){const o=t=>{if(!t)return t;if("string"==typeof t)return this.isLoon()?t:this.isQuanX()?{"open-url":t}:this.isSurge()?{url:t}:void 0;if("object"==typeof t){if(this.isLoon()){let e=t.openUrl||t.url||t["open-url"],s=t.mediaUrl||t["media-url"];return{openUrl:e,mediaUrl:s}}if(this.isQuanX()){let e=t["open-url"]||t.url||t.openUrl,s=t["media-url"]||t.mediaUrl,i=t["update-pasteboard"]||t.updatePasteboard;return{"open-url":e,"media-url":s,"update-pasteboard":i}}if(this.isSurge()){let e=t.url||t.openUrl||t["open-url"];return{url:e}}}};if(this.isMute||(this.isSurge()||this.isLoon()?$notification.post(e,s,i,o(r)):this.isQuanX()&&$notify(e,s,i,o(r))),!this.isMuteLog){let t=["","==============\ud83d\udce3\u7cfb\u7edf\u901a\u77e5\ud83d\udce3=============="];t.push(e),s&&t.push(s),i&&t.push(i),console.log(t.join("\n")),this.logs=this.logs.concat(t)}}log(...t){t.length>0&&(this.logs=[...this.logs,...t]),console.log(t.join(this.logSeparator))}logErr(t,e){const s=!this.isSurge()&&!this.isQuanX()&&!this.isLoon();s?this.log("",`\u2757\ufe0f${this.name}, \u9519\u8bef!`,t.stack):this.log("",`\u2757\ufe0f${this.name}, \u9519\u8bef!`,t)}wait(t){return new Promise(e=>setTimeout(e,t))}done(t={}){const e=(new Date).getTime(),s=(e-this.startTime)/1e3;this.log("",`\ud83d\udd14${this.name}, \u7ed3\u675f! \ud83d\udd5b ${s} \u79d2`),this.log(),(this.isSurge()||this.isQuanX()||this.isLoon())&&$done(t)}}(t,e)} 166 | 167 | ``` 168 | 169 | ### 定时监控购物车库存 170 | 171 | ``` 172 | /** 173 | * 上面的内容替换成你刚刚抓取购物车库存的内容 174 | * 需要抓包的接口:https://maicai.api.ddxq.mobi/cart/index 175 | */ 176 | 177 | const myRequest = { 178 | url: url, 179 | method: method, 180 | headers: headers 181 | }; 182 | 183 | const $ = new Env("🎉 叮咚买菜 - 购物车库存监控 🎉"); 184 | 185 | // 输入bark的key 不填写key使用圈X自带的通知 186 | var BarkKey = ""; 187 | 188 | // 属于购物车商品数量大于多少时发送通知 例如5 189 | var productCountPush = 5; 190 | 191 | // 测试通知(模拟通知),等号后面改成true即可模拟通知 192 | var testFlag = false; 193 | 194 | // 推送详情 不用输入 195 | var pushContent = ''; 196 | 197 | // 启动脚本 关闭在前面加 // 198 | start(); 199 | 200 | // 推送通知 201 | function pushData(){ 202 | const pushUrl = `https://api.day.app/`+BarkKey+`/%E6%8E%A2%E5%AD%90%E6%9D%A5%E6%8A%A5%20%E2%86%92%20%E5%8F%AE%E5%92%9A%E4%B9%B0%E8%8F%9C/`+pushContent+`?icon=https://raw.githubusercontent.com/Orz-3/mini/master/Color/mcdd.png&url=ddxq://`; 203 | 204 | console.log("购物车物资在补充,去叮咚查看下单!!!!"); 205 | if(BarkKey == ""){ 206 | $.msg("购物车物资在补充,去叮咚查看下单!!!!") 207 | return; 208 | } 209 | $.get({url:pushUrl}, (error, response, data) => { 210 | if (error) { 211 | $.done(); 212 | } else { 213 | $.done(); 214 | } 215 | }); 216 | } 217 | 218 | // 获取配送时间 219 | function start(){ 220 | $.post( myRequest, (error, response, data) => { 221 | if (error) { 222 | console.log(error); 223 | $.done(); 224 | } else { 225 | dataProcess(data); 226 | $.done(); 227 | } 228 | }); 229 | } 230 | 231 | // 判断是否有补充库存 232 | function getFlag(res) { 233 | if(res.data.product.effective.length < 1){ 234 | return false; 235 | } 236 | var count = res.data.product.effective[0].products.length; 237 | if(count > productCountPush){ 238 | pushContent = encodeURI("购物车库存大于"+productCountPush+",当前库存为"+count); 239 | return true; 240 | } 241 | return false; 242 | } 243 | 244 | // 处理数据 245 | function dataProcess(data){ 246 | if(testFlag){ 247 | pushContent = encodeURI("这是测试通知 - 监控购物车") 248 | pushData(); 249 | return; 250 | } 251 | 252 | // 判断请求是否成功 253 | var json = JSON.parse(data) 254 | if(!json.success){ 255 | $.msg(json.msg) 256 | }else{ 257 | if(getFlag(json)){ 258 | pushData(); 259 | }else{ 260 | console.log("库存不足,正在持续监控...") 261 | } 262 | } 263 | } 264 | 265 | // Env.min.js 266 | function Env(t,e){class s{constructor(t){this.env=t}send(t,e="GET"){t="string"==typeof t?{url:t}:t;let s=this.get;return"POST"===e&&(s=this.post),new Promise((e,i)=>{s.call(this,t,(t,s,r)=>{t?i(t):e(s)})})}get(t){return this.send.call(this.env,t)}post(t){return this.send.call(this.env,t,"POST")}}return new class{constructor(t,e){this.name=t,this.http=new s(this),this.data=null,this.dataFile="box.dat",this.logs=[],this.isMute=!1,this.isNeedRewrite=!1,this.logSeparator="\n",this.encoding="utf-8",this.startTime=(new Date).getTime(),Object.assign(this,e),this.log("",`\ud83d\udd14${this.name}, \u5f00\u59cb!`)}isNode(){return"undefined"!=typeof module&&!!module.exports}isQuanX(){return"undefined"!=typeof $task}isSurge(){return"undefined"!=typeof $httpClient&&"undefined"==typeof $loon}isLoon(){return"undefined"!=typeof $loon}isShadowrocket(){return"undefined"!=typeof $rocket}isStash(){return"undefined"!=typeof $environment&&$environment["stash-version"]}toObj(t,e=null){try{return JSON.parse(t)}catch{return e}}toStr(t,e=null){try{return JSON.stringify(t)}catch{return e}}getjson(t,e){let s=e;const i=this.getdata(t);if(i)try{s=JSON.parse(this.getdata(t))}catch{}return s}setjson(t,e){try{return this.setdata(JSON.stringify(t),e)}catch{return!1}}getScript(t){return new Promise(e=>{this.get({url:t},(t,s,i)=>e(i))})}runScript(t,e){return new Promise(s=>{let i=this.getdata("@chavy_boxjs_userCfgs.httpapi");i=i?i.replace(/\n/g,"").trim():i;let r=this.getdata("@chavy_boxjs_userCfgs.httpapi_timeout");r=r?1*r:20,r=e&&e.timeout?e.timeout:r;const[o,h]=i.split("@"),n={url:`http://${h}/v1/scripting/evaluate`,body:{script_text:t,mock_type:"cron",timeout:r},headers:{"X-Key":o,Accept:"*/*"}};this.post(n,(t,e,i)=>s(i))}).catch(t=>this.logErr(t))}loaddata(){if(!this.isNode())return{};{this.fs=this.fs?this.fs:require("fs"),this.path=this.path?this.path:require("path");const t=this.path.resolve(this.dataFile),e=this.path.resolve(process.cwd(),this.dataFile),s=this.fs.existsSync(t),i=!s&&this.fs.existsSync(e);if(!s&&!i)return{};{const i=s?t:e;try{return JSON.parse(this.fs.readFileSync(i))}catch(t){return{}}}}}writedata(){if(this.isNode()){this.fs=this.fs?this.fs:require("fs"),this.path=this.path?this.path:require("path");const t=this.path.resolve(this.dataFile),e=this.path.resolve(process.cwd(),this.dataFile),s=this.fs.existsSync(t),i=!s&&this.fs.existsSync(e),r=JSON.stringify(this.data);s?this.fs.writeFileSync(t,r):i?this.fs.writeFileSync(e,r):this.fs.writeFileSync(t,r)}}lodash_get(t,e,s){const i=e.replace(/\[(\d+)\]/g,".$1").split(".");let r=t;for(const t of i)if(r=Object(r)[t],void 0===r)return s;return r}lodash_set(t,e,s){return Object(t)!==t?t:(Array.isArray(e)||(e=e.toString().match(/[^.[\]]+/g)||[]),e.slice(0,-1).reduce((t,s,i)=>Object(t[s])===t[s]?t[s]:t[s]=Math.abs(e[i+1])>>0==+e[i+1]?[]:{},t)[e[e.length-1]]=s,t)}getdata(t){let e=this.getval(t);if(/^@/.test(t)){const[,s,i]=/^@(.*?)\.(.*?)$/.exec(t),r=s?this.getval(s):"";if(r)try{const t=JSON.parse(r);e=t?this.lodash_get(t,i,""):e}catch(t){e=""}}return e}setdata(t,e){let s=!1;if(/^@/.test(e)){const[,i,r]=/^@(.*?)\.(.*?)$/.exec(e),o=this.getval(i),h=i?"null"===o?null:o||"{}":"{}";try{const e=JSON.parse(h);this.lodash_set(e,r,t),s=this.setval(JSON.stringify(e),i)}catch(e){const o={};this.lodash_set(o,r,t),s=this.setval(JSON.stringify(o),i)}}else s=this.setval(t,e);return s}getval(t){return this.isSurge()||this.isLoon()?$persistentStore.read(t):this.isQuanX()?$prefs.valueForKey(t):this.isNode()?(this.data=this.loaddata(),this.data[t]):this.data&&this.data[t]||null}setval(t,e){return this.isSurge()||this.isLoon()?$persistentStore.write(t,e):this.isQuanX()?$prefs.setValueForKey(t,e):this.isNode()?(this.data=this.loaddata(),this.data[e]=t,this.writedata(),!0):this.data&&this.data[e]||null}initGotEnv(t){this.got=this.got?this.got:require("got"),this.cktough=this.cktough?this.cktough:require("tough-cookie"),this.ckjar=this.ckjar?this.ckjar:new this.cktough.CookieJar,t&&(t.headers=t.headers?t.headers:{},void 0===t.headers.Cookie&&void 0===t.cookieJar&&(t.cookieJar=this.ckjar))}get(t,e=(()=>{})){if(t.headers&&(delete t.headers["Content-Type"],delete t.headers["Content-Length"]),this.isSurge()||this.isLoon())this.isSurge()&&this.isNeedRewrite&&(t.headers=t.headers||{},Object.assign(t.headers,{"X-Surge-Skip-Scripting":!1})),$httpClient.get(t,(t,s,i)=>{!t&&s&&(s.body=i,s.statusCode=s.status),e(t,s,i)});else if(this.isQuanX())this.isNeedRewrite&&(t.opts=t.opts||{},Object.assign(t.opts,{hints:!1})),$task.fetch(t).then(t=>{const{statusCode:s,statusCode:i,headers:r,body:o}=t;e(null,{status:s,statusCode:i,headers:r,body:o},o)},t=>e(t));else if(this.isNode()){let s=require("iconv-lite");this.initGotEnv(t),this.got(t).on("redirect",(t,e)=>{try{if(t.headers["set-cookie"]){const s=t.headers["set-cookie"].map(this.cktough.Cookie.parse).toString();s&&this.ckjar.setCookieSync(s,null),e.cookieJar=this.ckjar}}catch(t){this.logErr(t)}}).then(t=>{const{statusCode:i,statusCode:r,headers:o,rawBody:h}=t;e(null,{status:i,statusCode:r,headers:o,rawBody:h},s.decode(h,this.encoding))},t=>{const{message:i,response:r}=t;e(i,r,r&&s.decode(r.rawBody,this.encoding))})}}post(t,e=(()=>{})){const s=t.method?t.method.toLocaleLowerCase():"post";if(t.body&&t.headers&&!t.headers["Content-Type"]&&(t.headers["Content-Type"]="application/x-www-form-urlencoded"),t.headers&&delete t.headers["Content-Length"],this.isSurge()||this.isLoon())this.isSurge()&&this.isNeedRewrite&&(t.headers=t.headers||{},Object.assign(t.headers,{"X-Surge-Skip-Scripting":!1})),$httpClient[s](t,(t,s,i)=>{!t&&s&&(s.body=i,s.statusCode=s.status),e(t,s,i)});else if(this.isQuanX())t.method=s,this.isNeedRewrite&&(t.opts=t.opts||{},Object.assign(t.opts,{hints:!1})),$task.fetch(t).then(t=>{const{statusCode:s,statusCode:i,headers:r,body:o}=t;e(null,{status:s,statusCode:i,headers:r,body:o},o)},t=>e(t));else if(this.isNode()){let i=require("iconv-lite");this.initGotEnv(t);const{url:r,...o}=t;this.got[s](r,o).then(t=>{const{statusCode:s,statusCode:r,headers:o,rawBody:h}=t;e(null,{status:s,statusCode:r,headers:o,rawBody:h},i.decode(h,this.encoding))},t=>{const{message:s,response:r}=t;e(s,r,r&&i.decode(r.rawBody,this.encoding))})}}time(t,e=null){const s=e?new Date(e):new Date;let i={"M+":s.getMonth()+1,"d+":s.getDate(),"H+":s.getHours(),"m+":s.getMinutes(),"s+":s.getSeconds(),"q+":Math.floor((s.getMonth()+3)/3),S:s.getMilliseconds()};/(y+)/.test(t)&&(t=t.replace(RegExp.$1,(s.getFullYear()+"").substr(4-RegExp.$1.length)));for(let e in i)new RegExp("("+e+")").test(t)&&(t=t.replace(RegExp.$1,1==RegExp.$1.length?i[e]:("00"+i[e]).substr((""+i[e]).length)));return t}msg(e=t,s="",i="",r){const o=t=>{if(!t)return t;if("string"==typeof t)return this.isLoon()?t:this.isQuanX()?{"open-url":t}:this.isSurge()?{url:t}:void 0;if("object"==typeof t){if(this.isLoon()){let e=t.openUrl||t.url||t["open-url"],s=t.mediaUrl||t["media-url"];return{openUrl:e,mediaUrl:s}}if(this.isQuanX()){let e=t["open-url"]||t.url||t.openUrl,s=t["media-url"]||t.mediaUrl,i=t["update-pasteboard"]||t.updatePasteboard;return{"open-url":e,"media-url":s,"update-pasteboard":i}}if(this.isSurge()){let e=t.url||t.openUrl||t["open-url"];return{url:e}}}};if(this.isMute||(this.isSurge()||this.isLoon()?$notification.post(e,s,i,o(r)):this.isQuanX()&&$notify(e,s,i,o(r))),!this.isMuteLog){let t=["","==============\ud83d\udce3\u7cfb\u7edf\u901a\u77e5\ud83d\udce3=============="];t.push(e),s&&t.push(s),i&&t.push(i),console.log(t.join("\n")),this.logs=this.logs.concat(t)}}log(...t){t.length>0&&(this.logs=[...this.logs,...t]),console.log(t.join(this.logSeparator))}logErr(t,e){const s=!this.isSurge()&&!this.isQuanX()&&!this.isLoon();s?this.log("",`\u2757\ufe0f${this.name}, \u9519\u8bef!`,t.stack):this.log("",`\u2757\ufe0f${this.name}, \u9519\u8bef!`,t)}wait(t){return new Promise(e=>setTimeout(e,t))}done(t={}){const e=(new Date).getTime(),s=(e-this.startTime)/1e3;this.log("",`\ud83d\udd14${this.name}, \u7ed3\u675f! \ud83d\udd5b ${s} \u79d2`),this.log(),(this.isSurge()||this.isQuanX()||this.isLoon())&&$done(t)}}(t,e)} 267 | 268 | ``` 269 | 270 | #### bark软件key 271 | 见附件 272 | 273 | -------------------------------------------------------------------------------- /重写教程.md: -------------------------------------------------------------------------------- 1 | ### 重写 2 | 3 | 目的是重写获取配送时间的返回值,原来返回全部运力满的状态,app无法点击,重写后都是可选的,这样就少一次请求,比别人抢菜更快 4 | 5 | #### 操作步骤 6 | 7 | 1. 打开圈X设置 - Mitm开关 8 | 2. MitM - 添加主机名 *.api.ddxq.mobi 9 | 3. 重写配送时间 - 添加 10 | 1. 重写类型:script-response-body 11 | 2. 匹配URL:https://maicai.api.ddxq.mobi/order/getMultiReserveTime 12 | 3. 脚本路径:https://raw.githubusercontent.com/wu491925129/script/main/ddmc.js 13 | 4. 重写浏览:点击刚刚新增的重写选项后面的3个点,选择更新脚本 14 | 5. 重写订单校验(禁止弹拥挤弹框) - 添加 15 | 1. 重写类型:script-response-body 16 | 2. 匹配URL:https://maicai.api.ddxq.mobi/order/checkOrder 17 | 3. 脚本路径:https://raw.githubusercontent.com/wu491925129/script/main/checkOrderDirect.js 18 | 6. 重写订单日期失效(禁止日期失效弹框) - 添加 19 | 1. 重写类型:script-response-body 20 | 2. 匹配URL:https://maicai.api.ddxq.mobi/order/addNewOrder 21 | 3. 脚本路径:https://raw.githubusercontent.com/wu491925129/script/main/OrderTimeFailDirect.js 22 | 7. 第一次配好开梯子,更新脚本,后面不需要 23 | 8. 不想重写就选择禁用即可 --------------------------------------------------------------------------------