├── README.md
├── Surge
├── CMB_ID.js
├── Piao_Bak.js
├── Piao_No.js
├── TF_link.js
├── TF_keys.js
├── Nomo.js
├── PDDNS.js
├── CMB_piao.js
├── Capture.js
├── EPIC_free_games.js
├── XiYou-summary.js
├── Follow.js
├── IP-Geolocation.js
├── Auto_join_TF.js
├── IP.js
├── XiYou-Sign.js
├── campusphere-night.js
├── campusphere.js
├── IP-Score-All-Info.js
└── up_pddns.js
├── Quantumult-X
├── EPIC_free_games.js
├── topsports.js
└── campusphere.js
├── Shadowrocket
└── campusphere.js
└── Loon
└── campusphere.js
/README.md:
--------------------------------------------------------------------------------
1 | *JavaScript*
2 |
3 | 原创
4 |
5 | 仅供学习,若侵权请联系删除,忽做违法用途,若他人用此项目违反法律或其他规定,出现任何问题,与作者无关。可借鉴修改
6 |
--------------------------------------------------------------------------------
/Surge/CMB_ID.js:
--------------------------------------------------------------------------------
1 | let chnlUserId = JSON.parse($request.body).chnlUserId
2 | $persistentStore.write(chnlUserId, 'chnlUserId')
3 | console.log('若chnlUserId后有字符串则获取成功\nchnlUserId:' + $persistentStore.read('chnlUserId'))
4 | $done({})
--------------------------------------------------------------------------------
/Surge/Piao_Bak.js:
--------------------------------------------------------------------------------
1 | let productBakNo = JSON.parse($response.body).respData.bakNo
2 | $persistentStore.write(productBakNo, 'productBakNo')
3 | console.log('若productBakNo后有字符串则获取成功\nproductBakNo:' + $persistentStore.read('productBakNo'))
4 | $done({})
--------------------------------------------------------------------------------
/Surge/Piao_No.js:
--------------------------------------------------------------------------------
1 | let cityNo = getArgs().cityNo
2 | let longitude = getArgs().longitude
3 | let dimension = getArgs().dimension
4 | let productNo = getArgs().productNo
5 | $persistentStore.write(cityNo, 'cityNo')
6 | $persistentStore.write(longitude, 'longitude')
7 | $persistentStore.write(dimension, 'dimension')
8 | $persistentStore.write(productNo, 'productNo')
9 | console.log('\n' + $persistentStore.read('cityNo') + '\n' + $persistentStore.read('longitude') + '\n' + $persistentStore.read('dimension') + '\n' + $persistentStore.read('productNo') + '\n若为四个数字串则正确')
10 | $done({})
11 |
12 | function getArgs() {
13 | return Object.fromEntries(
14 | $request.body
15 | .split(”&“)
16 | .map((item) => item.split(”=“))
17 | .map(([k, v]) => [k, decodeURIComponent(v)])
18 | );
19 | }
--------------------------------------------------------------------------------
/Surge/TF_link.js:
--------------------------------------------------------------------------------
1 | /**
2 | 作用:显示公共TF的分享链接(非公测链接无法显示),若没有链接或者没有描述说明啥也没有(无法分享链接
3 | 路径:App--App Details--Description
4 | 使用方法:
5 | Surge:
6 | [Script]
7 | TF_link = type=http-response,pattern=^https:\/\/testflight\.apple\.com\/v2\/accounts\/\w+-\w+-\w+-\w+-\w+\/apps\/\d+\/builds\/\d+$,requires-body=1,max-size=0,script-path=https://github.com/DecoAri/JavaScript/blob/main/Surge/TF_link.js?raw=true
8 | [MITM]
9 | hostname = testflight.apple.com
10 |
11 | QX:
12 | ^https:\/\/testflight\.apple\.com\/v2\/accounts\/\w+-\w+-\w+-\w+-\w+\/apps\/\d+\/builds\/\d+$ url script-response-body https://github.com/DecoAri/JavaScript/blob/main/Surge/TF_link.js?raw=true
13 | hostname = testflight.apple.com
14 |
15 | **/
16 |
17 |
18 | let obj = JSON.parse($response.body);obj.data.builds[0].description = obj.data.shareUrl + '\n' + obj.data.builds[0].description;$done({body:JSON.stringify(obj)});
--------------------------------------------------------------------------------
/Surge/TF_keys.js:
--------------------------------------------------------------------------------
1 | $persistentStore.write(null, 'request_id')
2 | let url = $request.url
3 | let key = url.replace(/(.*accounts\/)(.*)(\/apps)/, '$2')
4 | let session_id = $request.headers['x-session-id'] || $request.headers['X-Session-Id']
5 | let session_digest = $request.headers['x-session-digest'] || $request.headers['X-Session-Digest']
6 | let request_id = $request.headers['x-request-id'] || $request.headers['X-Request-Id']
7 | let X_Apple_AMD_M = $request.headers['X-Apple-AMD-M'] || $request.headers['x-apple-amd-m']
8 | let UA = $request.headers['User-Agent'] || $request.headers['user-agent']
9 | $persistentStore.write(key, 'key')
10 | $persistentStore.write(session_id, 'session_id')
11 | $persistentStore.write(session_digest, 'session_digest')
12 | $persistentStore.write(request_id, 'request_id')
13 | $persistentStore.write(X_Apple_AMD_M, 'X-Apple-AMD-M')
14 | $persistentStore.write(UA, 'TFUA')
15 | if ($persistentStore.read('request_id') !== null) {
16 | $notification.post('请关闭本脚本', '信息获取成功','')
17 | } else {
18 | $notification.post('信息获取失败','请打开MITM H2开关并添加testflight.apple.com','')
19 | }
20 | $done({})
--------------------------------------------------------------------------------
/Surge/Nomo.js:
--------------------------------------------------------------------------------
1 | /****
2 | Unlock Nomo CAM and Nomo RAW.
3 |
4 | Please note:
5 | Nomo RAW premium need restored in Nomo CAM APP. So....restore Nomo CAM first.
6 |
7 | Usage: Use Surge module or directly add them by yourself.
8 |
9 | [Script]
10 | Nomo = type=http-response,pattern=https://nomo.dafork.com/api/v5/iap/ios_verify$,requires-body=1,max-size=0,script-path=https://github.com/DecoAri/JavaScript/blob/main/Surge/Nomo.js?raw=true
11 |
12 | [MITM]
13 | hostname = %APPEND% nomo.dafork.com
14 |
15 | ****/
16 |
17 | let obj = $response.body
18 |
19 | obj = '{"sign":"eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJ0aW1lc3RhbXAiOjE2OTY1Mzk1NTMsInJlcXVlc3Rfc2lnbiI6IjIxMDIwMjRjYTcxNWY0NjI5NDJlYzIzMmIwMDIyMmI0IiwidmFsaWRhdGVkX2lvc19pZHMiOlsiYmxpbmsuYWNhZGVteS5ub21vLnByby55ZWFyIl0sImhhc192YWxpZF9zdWJzY3JpcHRpb24iOnRydWUsInN1YnNjcmlwdGlvbl9leHBpcmVfYXQiOjQxMDA2ODgwMDB9.XLQk0ScKVpxIinNgtujwJtS75ckzkrlGdzcK76paTq65F2Bl5UH5ImTyTNvpj6YJiz_SoS87LkLMPAQOCEhESGCsqjYC4HUaKGBrPp1JW9bwa_P4UCKYddbyRv7Yr5-yuFYan6nxozRUTnze-6yd1dc8sJJnfaDyGTnnzieHodtHp0SFPD9zCkb4flrbaxciDIZVAWDt3MakkMe1azoGHjH2cYz1YU3aOZDaKChqZi4y-pevYIMTDFth1LQsJpzqfV0OcS25ObVs-8h8lKxSLRK338WIrB2cQbRM8MXTSx4Tm_dBXbbROoofIuPfU9WnLqF5xUCrLNpx_TuFwbUgaQ"}'
20 |
21 | $done({obj});
--------------------------------------------------------------------------------
/Surge/PDDNS.js:
--------------------------------------------------------------------------------
1 | /****
2 | 写脚本缘由:私有DDNS脚本,由于Surge自带的sgddns无法同时解析ipv4和ipv6同时使用。由于经常换网络环境,不一定全是公网IP,可能只有公网V6,可能全部都有。所以自写一份私有ddns脚本。
3 |
4 | ⚠️需要配合python/JS自动上传本机公网IP到github后此脚本才可用
5 |
6 | ⚠️请详细(一个个字)阅读
7 |
8 | 使用方法:在Surge中文本编辑配置文件。
9 |
10 | Surge iOS添加内容如下:
11 | [Script]这个section下粘贴以下内容:
12 | DDNS = type=dns,script-path=https://raw.githubusercontent.com/DecoAri/JavaScript/main/Surge/PDDNS.js,argument=URL=🌍&TOKEN=🔑
13 | [Host]下添加以下内容:
14 | // 随便写一个不常见域名例如
15 | home.mac.pddns = script:DDNS
16 | 把你的家里的节点的server改为上面的域名: home.mac.pddns
17 |
18 | 请替换argument里面的🌍和🔑
19 | 🌍为你github私有库的dns IP文件的链接(该文件的IP由py/js自动上传,请不要自己填写文件内容)
20 | 🔑为github的personal access token。如不知道该开什么权限请全部勾选(⚠️别把token分享给别人)
21 |
22 | 自动上传IP到github请访问本库的up_pddns.js或者python库
23 | ****/
24 |
25 | let ddnsurl = {
26 | url: getArgs().URL,
27 | headers: {
28 | 'Authorization': 'token ' + getArgs().TOKEN
29 | }
30 | }
31 |
32 | $httpClient.get(ddnsurl, function(error, response, data){
33 | $done({addresses: data.split(';'), ttl: 600});
34 | });
35 |
36 | function getArgs() {
37 | return Object.fromEntries(
38 | $argument
39 | .split("&")
40 | .map((item) => item.split("="))
41 | .map(([k, v]) => [k, decodeURIComponent(v)])
42 | );
43 | }
--------------------------------------------------------------------------------
/Surge/CMB_piao.js:
--------------------------------------------------------------------------------
1 | //Adjust yourself or waiting for me.
2 |
3 | (async function() {
4 | await OMG();
5 | $done();
6 | })();
7 |
8 | function OMG() {
9 | return new Promise(function(resolve) {
10 | $httpClient.post({url: 'https://fpwx.o2o.cmbchina.com/wechatmp-gateway/wechat/rush/order/create', headers: {'User-Agent': 'Mozilla/5.0 (iPhone; CPU iPhone OS 15_6 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Mobile/15E148 MicroMessenger/8.0.26(0x18001a25) NetType/WIFI Language/en', 'Content-Type': 'application/json'}, body: {"chnlUserId":`${$persistentStore.read("chnlUserId")}`,"chnlId":"01","productNo":$persistentStore.read("productNo"),"productBakNo":$persistentStore.read("productBakNo"),"buyCount":1,"cardType":"1100","userVouId":null,"cityNo":$persistentStore.read("cityNo"),"longitude":$persistentStore.read("longitude"),"dimension":$persistentStore.read("dimension"),"blackListToken":""}}, function(error,resp,body) {
11 | let msg = JSON.parse(body).respMsg
12 | let code = JSON.parse(body).respCode
13 | if (code == 1000 || code == "COU_PC_0000000019" || code == "COU_PC_0000000026") {
14 | $notification.post("🛍️周二提前购", "🧾订单状态:" + msg,"⚠️仅限周三使用哦(不要忘了去掌上生活付款)")
15 | resolve();
16 | } else {
17 | console.log(msg)
18 | OMG()
19 | }
20 | })
21 | })
22 | }
--------------------------------------------------------------------------------
/Surge/Capture.js:
--------------------------------------------------------------------------------
1 | !(async () => {
2 | let mods = (await httpAPI("GET", "/v1/modules", null))
3 | let modsStatus = /MitM All Hostnames/.test(mods.enabled)
4 | let capture = (await httpAPI("GET", "/v1/features/capture", null))
5 | if ($trigger === "button") {
6 | if (capture.enabled == false){
7 | await httpAPI("POST", "/v1/features/capture", {enabled: "true"})
8 | await httpAPI("POST", "/v1/modules", {"MitM All Hostnames": "true"})
9 | $done({
10 | title:"HTTP Capture",
11 | content:"Capture: \u2611 Hostnames: \u2611",
12 | icon: "hand.raised.square.on.square.fill",
13 | "icon-color": "ED0001"
14 | })
15 | } else {
16 | await httpAPI("POST", "/v1/features/capture", {enabled: "false"})
17 | await httpAPI("POST", "/v1/modules", {"MitM All Hostnames": "false"})
18 | $done({
19 | title:"HTTP Capture",
20 | content:"Capture: \u2612 Hostnames: \u2612",
21 | icon: "archivebox",
22 | "icon-color": "88989F"
23 | })
24 | }
25 | } else if(modsStatus == true || capture.enabled == true) {
26 | $done({
27 | title:"HTTP Capture",
28 | content:"Capture: " + iconStatus(capture.enabled) + " Hostnames: " + iconStatus(modsStatus),
29 | icon: "hand.raised.square.on.square.fill",
30 | "icon-color": "ED0001"
31 | })
32 | } else {
33 | $done({
34 | title:"HTTP Capture",
35 | content:"Capture: " + iconStatus(capture.enabled) + " Hostnames: " + iconStatus(modsStatus),
36 | icon: "archivebox",
37 | "icon-color": "88989F"
38 | })
39 | }
40 | })();
41 |
42 | function httpAPI(method = "", path = "", body = "") {
43 | return new Promise((resolve) => {
44 | $httpAPI(method, path, body, (result) => {
45 | resolve(result);
46 | });
47 | });
48 | }
49 |
50 | function iconStatus(status) {
51 | if (status) {
52 | return "\u2611";
53 | } else {
54 | return "\u2612"
55 | }
56 | }
--------------------------------------------------------------------------------
/Quantumult-X/EPIC_free_games.js:
--------------------------------------------------------------------------------
1 | /**
2 | 建议cron:1 0 * * *
3 | surge脚本请去surge文件夹路径寻找
4 | */
5 |
6 |
7 |
8 |
9 | $task.fetch({url:"https://store-site-backend-static-ipv4.ak.epicgames.com/freeGamesPromotions?locale=en-US&country=US&allowCountries=US"}).then(response => {
10 | let jsonData = JSON.parse(response.body)
11 | let i = 0
12 | let games = jsonData.data.Catalog.searchStore.elements
13 | while (games) {
14 | if (jsonData.data.Catalog.searchStore.elements[i] == undefined) {
15 | break;
16 | } else if (jsonData.data.Catalog.searchStore.elements[i].title == "Mystery Game") {
17 | i++
18 | } else {
19 | games = jsonData.data.Catalog.searchStore.elements[i]
20 | console.log(JSON.stringify(games))
21 | if (games.promotions == null) {
22 | $notify('🎮EPIC: ' + games.title, '🕒UPCOMING: ' + 'UNKNOWN', '📜DESCRIPTION: ' + games.description, {"media-url":games.keyImages[1].url})
23 | i++
24 | } else if (games.promotions.upcomingPromotionalOffers == '') {
25 | $notify('🎮EPIC: ' + games.title, '🕒OPEN: ' + transFormTime(games.promotions.promotionalOffers[0].promotionalOffers[0].startDate) + '\n🕐END: ' + transFormTime(games.promotions.promotionalOffers[0].promotionalOffers[0].endDate), '📜DESCRIPTION: ' + games.description, {"media-url":games.keyImages[1].url})
26 | i++
27 | } else {
28 | $notify('🎮EPIC: ' + games.title, '🕒UPCOMING: ' + transFormTime(games.promotions.upcomingPromotionalOffers[0].promotionalOffers[0].startDate) + '\n🕐END: ' + transFormTime(games.promotions.upcomingPromotionalOffers[0].promotionalOffers[0].endDate), '📜DESCRIPTION: ' + games.description, {"media-url":games.keyImages[1].url})
29 | i++
30 | }
31 | }
32 | }
33 | $done()
34 | }, reason => {
35 | // reason.error
36 | $notify("EPIC FREE GAMES", "ERROR", reason.error); // Error!
37 | $done();
38 | });
39 |
40 |
41 | function transFormTime(times) {
42 | const date = new Date(times);
43 | return `${date.getFullYear()}Y-${
44 | date.getMonth() + 1
45 | }M-${date.getDate()}D-${date.getHours()}H`;
46 | }
47 |
--------------------------------------------------------------------------------
/Surge/EPIC_free_games.js:
--------------------------------------------------------------------------------
1 | /*
2 | 适配tf版本通知
3 | 建议cron:1 0 * * *
4 | 相比于rsshub来说,信息来自官网,更新更及时
5 | QX的js请去Quantumult X的文件夹路径寻找
6 | */
7 |
8 |
9 |
10 | $httpClient.get({url:"https://store-site-backend-static-ipv4.ak.epicgames.com/freeGamesPromotions?locale=en-US&country=US&allowCountries=US"}, function(error,resp,body) {
11 | let jsonBody = JSON.parse(body)
12 | let i = 0
13 | let games = jsonBody.data.Catalog.searchStore.elements
14 | while (games) {
15 | if (jsonBody.data.Catalog.searchStore.elements[i] == undefined) {
16 | break;
17 | } else if (jsonBody.data.Catalog.searchStore.elements[i].title == "Mystery Game") {
18 | i++
19 | } else {
20 | games = jsonBody.data.Catalog.searchStore.elements[i]
21 | console.log(games)
22 | if (games.promotions == null) {
23 | $notification.post('🎮EPIC: ' + games.title, '🕒UPCOMING: ' + 'UNKNOWN', '📜DESCRIPTION: ' + games.description, {'media-url':games.keyImages[1].url})
24 | i++
25 | } else if (games.promotions.upcomingPromotionalOffers == '') {
26 | $notification.post('🎮EPIC: ' + games.title, '🕒OPEN: ' + transFormTime(games.promotions.promotionalOffers[0].promotionalOffers[0].startDate) + '\n🕐END: ' + transFormTime(games.promotions.promotionalOffers[0].promotionalOffers[0].endDate), '📜DESCRIPTION: ' + games.description, {'media-url':games.keyImages[1].url,'action':'open-url','url':'https://store.epicgames.com/en-US/p/'+games.catalogNs.mappings[0].pageSlug})
27 | i++
28 | } else {
29 | $notification.post('🎮EPIC: ' + games.title, '🕒UPCOMING: ' + transFormTime(games.promotions.upcomingPromotionalOffers[0].promotionalOffers[0].startDate) + '\n🕐END: ' + transFormTime(games.promotions.upcomingPromotionalOffers[0].promotionalOffers[0].endDate), '📜DESCRIPTION: ' + games.description, {'media-url':games.keyImages[1].url,'action':'open-url','url':'https://store.epicgames.com/en-US/p/'+games.catalogNs.mappings[0].pageSlug})
30 | i++
31 | }
32 | }
33 | }
34 | $done()
35 | })
36 |
37 | function transFormTime(times) {
38 | const date = new Date(times);
39 | return `${date.getFullYear()}Y-${
40 | date.getMonth() + 1
41 | }M-${date.getDate()}D-${date.getHours()}H`;
42 | }
--------------------------------------------------------------------------------
/Surge/XiYou-summary.js:
--------------------------------------------------------------------------------
1 | let xy = {};
2 | xy.body = "all",
3 | (async function() {
4 | await token();
5 | await task();
6 | await submit()
7 | $done()
8 | })();
9 |
10 | function token() {
11 | const loginurl = {
12 | url: 'https://www.yunzhixiyou.com/api/sys/manage/login',
13 | headers: {
14 | 'User-Agent' : 'xiyou/4.2.2 2280 ios14.3 (iPhone 6s Plus)',
15 | 'Content-Type' : 'application/x-www-form-urlencoded; charset=utf-8'
16 | },
17 | body: 'password=000000&schoolId=00000&username=00000'
18 | };
19 | return new Promise(function(resolve) {
20 | $httpClient.post(loginurl, function(error, resp, data) {
21 | xy.token =JSON.parse(data).token;
22 | resolve();
23 | });
24 | });
25 | }
26 |
27 | function task() {
28 | const taskurl = {
29 | url: 'https://www.yunzhixiyou.com/api/task/getTopTask',
30 | headers: {
31 | 'User-Agent' : 'xiyou/4.2.2 2280 ios14.3 (iPhone 6s Plus)',
32 | 'token' : xy.token
33 | },
34 | };
35 | return new Promise(function(resolve) {
36 | $httpClient.get(taskurl, function(error, resp, data) {
37 | xy.id = JSON.parse(data).data[0].id;
38 | resolve();
39 | });
40 | });
41 | }
42 |
43 | function submit() {
44 | let content = `
` + xy.body
45 | xy.content = encodeURIComponent(content)
46 | xy.sign = encodeURI("
")
47 | const submiturl = {
48 | url: 'https://www.yunzhixiyou.com/api/summary/publish',
49 | headers: {
50 | 'User-Agent' : 'xiyou/4.2.2 2280 ios14.3 (iPhone 6s Plus)',
51 | 'Content-Type' : 'application/x-www-form-urlencoded; charset=utf-8',
52 | 'token' : xy.token
53 | },
54 | body: "content=" + xy.content + xy.sign + "&taskId=" + xy.id
55 | };
56 | return new Promise(function(resolve) {
57 | $httpClient.post(submiturl, function(error, resp, body) {
58 | xy.msg = JSON.parse(body).msg;
59 | console.log(body)
60 | $notification.post("习柚总结", xy.msg, "")
61 | resolve();
62 | });
63 | });
64 | }
--------------------------------------------------------------------------------
/Surge/Follow.js:
--------------------------------------------------------------------------------
1 | /****************
2 | 只需要以下三个就能自动签到
3 | https://api.follow.is/wallets?userId=xxxxxxx
4 | 1: 这整个url
5 |
6 |
7 | https://api.follow.is/wallets/transactions/claim_daily
8 | 2: 请求头的cookie:authjs.session-token=
9 | 3: 整个请求体
10 |
11 | 现在已经有人写了脚本转换器。所以QX loon shadowrocket不再更新
12 | 以下示例脚本 自己改
13 | ****************/
14 |
15 | function getPower(callback) {
16 | $httpClient.get({
17 | url: $persistentStore.read('Follow_URL'), headers: {'cookie': 'authjs.session-token=' + `${$persistentStore.read('Follow_sToken')}`}
18 | }, function (error, resp, body) {
19 | let power = JSON.parse(body).data[0].dailyPowerToken / 1e18
20 | callback(power); // 将获取到的 power 通过回调传递给调用者
21 | });
22 | }
23 |
24 | function postRequest() {
25 | $httpClient.post({
26 | url: 'https://api.follow.is/wallets/transactions/claim_daily',
27 | headers: {'cookie': 'authjs.session-token=' + `${$persistentStore.read('Follow_sToken')}` + ';' + `${$persistentStore.read('Follow_CSRF')}`},
28 | body: {"csrfToken": `${$persistentStore.read('Follow_csrfToken')}`}
29 | }, function (error, res, data) {
30 | let code = JSON.parse(data).code;
31 | console.log('Code: ' + code);
32 |
33 | if (code === 0) {
34 | getPower(function (finalPower) { // 如果code=0,再次获取power
35 | console.log('Final Power after POST: ' + finalPower);
36 | $notification.post('Follow', 'Power: ' + finalPower,'Sign successful. 数据可能有延迟。如需确认请自行登录Follow点击刷新power', {'media-url':'https://app.follow.is/opengraph-image.png'})
37 | $done(); // 完成流程
38 | });
39 | } else if (code === 4000) {
40 | console.log("Retrying request...");
41 | postRequest(); // 如果code=4000,重新发起POST请求(不获取power)
42 | } else if (code === 1000) {
43 | $notification.post('Follow', '未授权', '请重新获取cookie', {'media-url':'https://app.follow.is/opengraph-image.png'})
44 | console.log(data)
45 | $done(); // 其他情况结束流程
46 | } else {
47 | $notification.post('其他错误', '查看日志', '')
48 | console.log('\n'+error + '\n'+res + '\n'+data)
49 | $done()
50 | }
51 | });
52 | }
53 |
54 | getPower(function (initialPower) { // 脚本运行时首次获取power
55 | console.log('Initial Power before POST: ' + initialPower);
56 | $notification.post('Follow', 'Power: ' + initialPower,'如果没收到Power更新通知请重新执行脚本', {'media-url':'https://app.follow.is/opengraph-image.png'})
57 | postRequest(); // 获取完power后,开始执行POST请求
58 | });
--------------------------------------------------------------------------------
/Surge/IP-Geolocation.js:
--------------------------------------------------------------------------------
1 | const flags = new Map([[ "NA" , "globe.americas.fill" ],["SA","globe.americas.fill"], [ "EU" , "globe.europe.africa.fill" ], [ "AS" , "globe.asia.australia.fill" ], [ "OC" , "globe.asia.australia.fill" ], [ "AF" , "globe.europe.africa.fill" ]])
2 | const carriers = new Map([["460-03","China Telecom"], ["460-05","China Telecom"], ["460-11","China Telecom"], ["460-01","China Unicom"], ["460-06","China Unicom"], ["460-09","China Unicom"], ["460-00","China Mobile"], ["460-02","China Mobile"], ["460-04","China Mobile"], ["460-07","China Mobile"], ["460-08","China Mobile"], ["460-15","China Broadcasting Network"], ["460-20","China Mobile"]])
3 |
4 | $httpClient.get({url: 'https://www.youtube.com/premium', headers: {'User-Agent' : 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/94.0.4606.61 Safari/537.36'}}, function(error,resp,body) {
5 | let reg = new RegExp ("contentRegion\\\":\\\"\\w{2}\\\"")
6 | let a = JSON.stringify(reg.exec(body))
7 | console.log(a)
8 | let YouTube = a.replace(/(\[\"contentRegion\\\":\\\")(\w+)\\\"\"\]/, '$2')
9 | $httpClient.get("http://ip-api.com/json/", function(error, response, body){
10 | $httpClient.get("http://ip-api.com/json/" + JSON.parse(body).query + "?fields=status,message,continent,continentCode,country,countryCode,region,regionName,city,district,zip,lat,lon,timezone,offset,currency,isp,org,as,asname,reverse,mobile,proxy,hosting,query", function(error, response, body){
11 | if ($network.wifi.ssid == null) {
12 | $done({
13 | title: carriers.get($network["cellular-data"].carrier) + "|" + $network["cellular-data"].radio,
14 | content: `${flagEmojis(JSON.parse(body).countryCode)}: ${JSON.parse(body).city} :${flagEmojis(YouTube)}\nISP: ${JSON.parse(body).isp}`,
15 | icon: flags.get(JSON.parse(body).continentCode),
16 | 'icon-color': $argument
17 | })
18 | } else {
19 | $done({
20 | title: $network.wifi.ssid,
21 | content: `${flagEmojis(JSON.parse(body).countryCode)}: ${JSON.parse(body).city} :${flagEmojis(YouTube)}\nISP: ${JSON.parse(body).isp}`,
22 | icon: flags.get(JSON.parse(body).continentCode),
23 | 'icon-color': $argument
24 | })
25 | }
26 | })
27 | })
28 | })
29 |
30 | function flagEmojis(country_code) {
31 | const codes = (country_code == 'TW' || country_code == 'HK') ? 'CN':country_code
32 | const codePoints = codes
33 | .toUpperCase()
34 | .split('')
35 | .map(char => 127397 + char.charCodeAt());
36 | return String.fromCodePoint(...codePoints);
37 | }
--------------------------------------------------------------------------------
/Quantumult-X/topsports.js:
--------------------------------------------------------------------------------
1 | //滔搏运动(TopSports)发售监控
2 | /***********
3 | 暂不支持多城市监控,如需要请配置多个本地脚本或修改脚本本体(小白勿动)
4 |
5 | 已支持多双鞋发售通知
6 |
7 | 只支持Quantumult X / Loon(因名字不能清楚知道鞋子样子,所以需要图片通知来决定是否需要去抽奖,所以暂不支持surge,Loon未适配)
8 |
9 | qx脚本配置(cron按需自行修改):
10 |
11 | [task_local]
12 | 50 8,10,11,12,13,14 * * * https://github.com/DecoAri/JavaScript/blob/main/Quantumult-X/topsports.js?raw=true, tag=滔搏监控, enabled=true
13 |
14 |
15 | 城市代码请复制以下url在浏览器打开查看cityCode
16 | https://m-app.topsports.com.cn/app/location/cityList
17 |
18 | ⚠️⚠️⚠️使用前请先运行以下脚本
19 | 打开qx,点击右下角风车,下拉找到工具&分析,点击构造HTTP请求,再点击右下角的写脚本图标,进去之后删除里面全部内容,复制以下代码并替换里面的中文,然后运行即可。
20 |
21 | $done($prefs.setValueForKey("请修改此中文为城市代码", "cityCode"))
22 |
23 | ***********/
24 | //以下为脚本本体
25 |
26 |
27 |
28 | const getShoes = {
29 | url: "https://m-app-cdn.topsports.com.cn/presale-api/activity/list?brandCode=TS&cityCode=" + $prefs.valueForKey("cityCode") + "¤t=1&pageSize=10",
30 | method: "GET"
31 | };
32 |
33 | $task.fetch(getShoes).then(response => {
34 | let jsonData = JSON.parse(response.body)
35 | let i = 0
36 | let shoes = jsonData.data.extend
37 | if (shoes == null) {
38 | console.log("👟没有新鞋发售")
39 | } else {
40 | while (shoes) {
41 | if (jsonData.data.extend[i] == undefined) {
42 | break;
43 | } else {
44 | shoes = jsonData.data.extend[i]
45 | console.log(JSON.stringify(shoes))
46 | let start = time(jsonData.data.extend[i].exchangeStartTime)
47 | let end = time(jsonData.data.extend[i].exchangeEndTime)
48 | $notify("👟有新鞋发售啦", jsonData.data.extend[i].productName, "发售时间:" + start +"\n" + "结束时间:" + end, {"media-url": jsonData.data.extend[i].indexPicUrl});
49 | console.log("👟有新鞋发售啦" + "\n" + jsonData.data.extend[i].productName + "\n" + "发售时间:" + start +"\n" + "结束时间:" + end)
50 | i++
51 | }
52 | }
53 | }
54 | $done()
55 | }, reason => {
56 | $notify("滔搏发售", "脚本运行出错", reason.error);
57 | $done();
58 | });
59 |
60 |
61 | function time(releaseDate) {
62 | var date = new Date(releaseDate);
63 | Y = date.getFullYear() + '-';
64 | M = (date.getMonth()+1 < 10 ? '0'+(date.getMonth()+1) : date.getMonth()+1) + '-';
65 | D = (date.getDate() < 10 ? '0'+(date.getDate()) : date.getDate()) + ' ';
66 | h = (date.getHours() < 10 ? '0'+(date.getHours()) : date.getHours()) + ':';
67 | m = (date.getMinutes() < 10 ? '0'+(date.getMinutes()) : date.getMinutes()) + ':';
68 | s = (date.getSeconds() < 10 ? '0'+(date.getSeconds()) : date.getSeconds());
69 | return Y+M+D+h+m+s;
70 | }
--------------------------------------------------------------------------------
/Surge/Auto_join_TF.js:
--------------------------------------------------------------------------------
1 | !(async () => {
2 | ids = $persistentStore.read('APP_ID')
3 | if (ids == '') {
4 | $notification.post('所有TF已加入完毕','模块已自动关闭','')
5 | $done($httpAPI('POST', '/v1/modules', {'Auto module for JavaScripts': 'false'}))
6 | } else {
7 | ids = ids.split(',')
8 | for await (const ID of ids) {
9 | await autoPost(ID)
10 | }
11 | }
12 | $done()
13 | })();
14 |
15 | function autoPost(ID) {
16 | let Key = $persistentStore.read('key')
17 | let testurl = 'https://testflight.apple.com/v3/accounts/' + Key + '/ru/'
18 | let header = {
19 | 'X-Session-Id': `${$persistentStore.read('session_id')}`,
20 | 'X-Session-Digest': `${$persistentStore.read('session_digest')}`,
21 | 'X-Request-Id': `${$persistentStore.read('request_id')}`,
22 | 'X-Apple-AMD-X': `${$persistentStore.read('X-Apple-AMD-X')}`,
23 | 'User-Agent': `${$persistentStore.read('TFUA')}`
24 | }
25 | return new Promise(function(resolve) {
26 | $httpClient.get({url: testurl + ID,headers: header}, function(error, resp, data) {
27 | if (error === null) {
28 | if (resp.status == 404) {
29 | ids = $persistentStore.read('APP_ID').split(',')
30 | ids = ids.filter(ids => ids !== ID)
31 | $persistentStore.write(ids.toString(),'APP_ID')
32 | console.log(ID + ' ' + '不存在该TF,已自动删除该APP_ID')
33 | $notification.post(ID, '不存在该TF', '已自动删除该APP_ID')
34 | resolve()
35 | } else {
36 | let jsonData = JSON.parse(data)
37 | if (jsonData.data == null) {
38 | console.log(ID + ': ' + jsonData.messages[0].message)
39 | resolve();
40 | } else if (jsonData.data.status == 'FULL') {
41 | var name = jsonData.data.app.name
42 | console.log(name + ' (' + ID + '): ' + jsonData.data.message)
43 | resolve();
44 | } else {
45 | $httpClient.post({url: testurl + ID + '/accept',headers: header}, function(error, resp, body) {
46 | let appName = JSON.parse(body).data.name
47 | $notification.post('🎉' + appName, 'TestFlight加入成功', '')
48 | console.log('🎉' + appName + '🎉' + ' (' + ID + '): ' + ' TestFlight加入成功')
49 | ids = $persistentStore.read('APP_ID').split(',')
50 | ids = ids.filter(ids => ids !== ID)
51 | $persistentStore.write(ids.toString(),'APP_ID')
52 | resolve()
53 | });
54 | }
55 | }
56 | } else {
57 | if (error =='The request timed out.') {
58 | resolve();
59 | } else if (error.includes("error -1012")) {
60 | $notification.post('自动加入TF', error,'请获取TF账户信息,模块已自动关闭,获取成功后再自行打开模块')
61 | $done($httpAPI('POST', '/v1/modules', {'Auto module for JavaScripts': 'false'}))
62 | resolve();
63 | } else {
64 | $notification.post('自动加入TF', error,'')
65 | console.log(ID + ': ' + error)
66 | resolve();
67 | }
68 | }
69 | })
70 | })
71 | }
--------------------------------------------------------------------------------
/Surge/IP.js:
--------------------------------------------------------------------------------
1 | var 中国电信 = ['460-03','460-05','460-11'];
2 | var 中国联通 = ['460-01','460-06','460-09'];
3 | var 中国移动 = ['460-00','460-02','460-04','460-07','460-08'];
4 | var 中国广电 = ['460-15'];
5 | var 中国铁通 = ['460-20'];
6 | let v4 = $network.v4.primaryAddress
7 | var ssid = $network.wifi.ssid
8 | var carrier = $network["cellular-data"].carrier
9 | var router = $network.v4.primaryRouter
10 | var radio = $network["cellular-data"].radio
11 | $httpClient.get("http://ip-api.com/json/", function(error, response, body){
12 | var jsondata = JSON.parse(body)
13 | var city = jsondata.city
14 | var query = jsondata.query
15 | var emoji = getFlagEmoji(jsondata.countryCode)
16 | var regex=/^192.168/
17 | if(regex.test(v4)){
18 | if(`${v4}` == `${query}`){
19 | $done({
20 | title: `${ssid}`,
21 | content: `${emoji}: ${query}\nRouter: ${router}\nLocal IP: ${v4}`,
22 | icon: "wifi",
23 | 'icon-color': "#00FF00"
24 | });
25 | }else{
26 | $done({
27 | title: `${ssid}`,
28 | content: `${emoji}: ${query}\nRouter: ${router}\nLocal IP: ${v4}`,
29 | icon: "wifi",
30 | 'icon-color': "#00FF00"
31 | });
32 | }
33 | }else if(`${radio}` == "null"){
34 | if(`${v4}` == `${query}`){
35 | $done({
36 | title: `Hotspot`,
37 | content: `${emoji}: ${query}\nRouter: ${router}\nLocal IP: ${v4}`,
38 | icon: "personalhotspot",
39 | 'icon-color': "#0000FF"
40 | });
41 | }else{
42 | $done({
43 | title: `Hotspot`,
44 | content: `${emoji}: ${query}\nRouter: ${router}\nLocal IP: ${v4}`,
45 | icon: "personalhotspot",
46 | 'icon-color': "#0000FF"
47 | });
48 | }
49 | }else{
50 | let 运营商 = "";
51 | if(中国电信.includes(carrier)){
52 | 运营商 = "China Telecom";
53 | }else if(中国联通.includes(carrier)){
54 | 运营商 = "China Unicom";
55 | }else if(中国移动.includes(carrier)){
56 | 运营商 = "China Mobile";
57 | }else if(中国广电.includes(carrier)){
58 | 运营商 = "China Broadcasting Network";
59 | }else if(中国铁通.includes(carrier)){
60 | 运营商 = "China Tietong";
61 | }else{
62 | 运营商 = "𝓜𝓸𝓫𝓲𝓵𝓮 𝓝𝓮𝓽𝔀𝓸𝓻𝓴";
63 | }
64 | if(`${v4}` == `${query}`){
65 | $done({
66 | title: `${运营商}`,
67 | content: `Radio: ${radio}\n${emoji}: ${query}\nLocal IP: ${v4}`,
68 | icon: "antenna.radiowaves.left.and.right",
69 | 'icon-color': "#EA0300"
70 | });
71 | }else{
72 | $done({
73 | title: `${运营商}`,
74 | content: `Radio: ${radio}\n${emoji}: ${query}\nLocal IP: ${v4}`,
75 | icon: "antenna.radiowaves.left.and.right",
76 | 'icon-color': "#EA0300"
77 | });
78 | }
79 | }
80 | });
81 | function getFlagEmoji(countryCode) {
82 | const codePoints = countryCode
83 | .toUpperCase()
84 | .split('')
85 | .map(char => 127397 + char.charCodeAt());
86 | return String.fromCodePoint(...codePoints);
87 | };
88 | function getFlagEmoji(country_code) {
89 | if(country_code === `TW`){
90 | let codePoints = `CN`
91 | .toUpperCase()
92 | .split('')
93 | .map(char => 127397 + char.charCodeAt());
94 | return String.fromCodePoint(...codePoints);
95 | }else{
96 | const codePoints = country_code
97 | .toUpperCase()
98 | .split('')
99 | .map(char => 127397 + char.charCodeAt());
100 | return String.fromCodePoint(...codePoints);
101 | }
102 | };
--------------------------------------------------------------------------------
/Surge/XiYou-Sign.js:
--------------------------------------------------------------------------------
1 | let xy = {};
2 | xy.city = "重庆市";
3 | xy.district = "区";
4 | xy.lat = 100.75648332114813;
5 | xy.lng = 107.2709211714478;
6 | xy.province = "重庆";
7 | xy.street = "大道";
8 | (async function() {
9 | await token();
10 | await task();
11 | await status();
12 | if(xy.data == 0) {
13 | $notification.post("签到未开始", xy.id, "");
14 | $httpClient.post({
15 | url: 'https://sctapi.ftqq.com/SCT87132TpuhLxVx2dJZnsvyVfs0fYejf.send',
16 | headers: {
17 | 'Content-Type' : 'application/x-www-form-urlencoded; charset=utf-8'
18 | },
19 | body: 'title=签到未开始&desp=' + xy.id
20 | })
21 | } else if(xy.data == 1) {
22 | await submit();
23 | $notification.post("习柚", xy.msgs, "");
24 | $httpClient.post({
25 | url: 'https://sctapi.ftqq.com/SCT87132TpuhLxVx2dJZnsvyVfs0fYejf.send',
26 | headers: {
27 | 'Content-Type' : 'application/x-www-form-urlencoded; charset=utf-8'
28 | },
29 | body: 'title=习柚' + xy.msgs + '&desp=' + xy.msgs
30 | })
31 | } else if(xy.data == "-1") {
32 | $notification.post("习柚", xy.msg, "");
33 | $httpClient.post({
34 | url: 'https://sctapi.ftqq.com/SCT87132TpuhLxVx2dJZnsvyVfs0fYejf.send',
35 | headers: {
36 | 'Content-Type' : 'application/x-www-form-urlencoded; charset=utf-8'
37 | },
38 | body: 'title=习柚&desp=' + xy.msg
39 | })
40 | } else {
41 | $notification.post("错误", "网络或其他错误,需重新运行", "");
42 | $httpClient.post({
43 | url: 'https://sctapi.ftqq.com/SCT87132TpuhLxVx2dJZnsvyVfs0fYejf.send',
44 | headers: {
45 | 'Content-Type' : 'application/x-www-form-urlencoded; charset=utf-8'
46 | },
47 | body: 'title=错误&desp=网络或其他错误,需重新运行'
48 | })
49 | }
50 | $done()
51 | })();
52 |
53 | function token() {
54 | const loginurl = {
55 | url: 'https://www.yunzhixiyou.com/api/sys/manage/login',
56 | headers: {
57 | 'User-Agent' : 'xiyou/4.2.2 2280 ios14.3 (iPhone 6s Plus)',
58 | 'Content-Type' : 'application/x-www-form-urlencoded; charset=utf-8'
59 | },
60 | body: 'password=00000&schoolId=000&username=0000000'
61 | };
62 | return new Promise(function(resolve) {
63 | $httpClient.post(loginurl, function(error, resp, data) {
64 | xy.token =JSON.parse(data).token;
65 | resolve();
66 | });
67 | });
68 | }
69 |
70 | function task() {
71 | const taskurl = {
72 | url: 'https://www.yunzhixiyou.com/api/task/getTopTask',
73 | headers: {
74 | 'User-Agent' : 'xiyou/4.2.2 2280 ios14.3 (iPhone 6s Plus)',
75 | 'token' : xy.token
76 | },
77 | };
78 | return new Promise(function(resolve) {
79 | $httpClient.get(taskurl, function(error, resp, data) {
80 | xy.id = JSON.parse(data).data[0].id;
81 | resolve();
82 | });
83 | });
84 | }
85 |
86 | function status() {
87 | const statusurl = {
88 | url: 'https://www.yunzhixiyou.com/api/sign/isSignOrNoSignInt',
89 | headers: {
90 | 'User-Agent' : 'xiyou/4.2.2 2280 ios14.3 (iPhone 6s Plus)',
91 | 'Content-Type' : 'application/x-www-form-urlencoded; charset=utf-8',
92 | 'token' : xy.token
93 | },
94 | body: 'taskId=' + xy.id
95 | };
96 | return new Promise(function(resolve) {
97 | $httpClient.post(statusurl, function(error, resp, body) {
98 | xy.data =JSON.parse(body).result;
99 | console.log(body);
100 | xy.msg = JSON.parse(body).msg;
101 | resolve();
102 | });
103 | });
104 | }
105 |
106 | function submit() {
107 | const submiturl = {
108 | url: 'https://www.yunzhixiyou.com/api/sign/signIn',
109 | headers: {
110 | 'User-Agent' : 'xiyou/4.2.2 2280 ios14.3 (iPhone 6s Plus)',
111 | 'Content-Type' : 'application/x-www-form-urlencoded; charset=utf-8',
112 | 'token' : xy.token
113 | },
114 | body: "city=" + xy.city + "&district=" + xy.district + "&lat=" + xy.lat + "&lng=" + xy.lng + "&phoneUuid=uuid&province=" + xy.province + "&signStatus=1&street=" + xy.street + "&taskId=" + xy.id + "&type=1"
115 | };
116 | return new Promise(function(resolve) {
117 | $httpClient.post(submiturl, function(error, resp, body) {
118 | xy.msgs = JSON.parse(body).msg;
119 | resolve();
120 | });
121 | });
122 | }
--------------------------------------------------------------------------------
/Surge/campusphere-night.js:
--------------------------------------------------------------------------------
1 | let cp = {};
2 | cp.long = $persistentStore.read("经度");
3 | cp.la = $persistentStore.read("纬度");
4 | cp.location = $persistentStore.read("地区");
5 | (async function() {
6 | await login();
7 | await wid();
8 | await form()
9 | await submit()
10 | $done()
11 | })();
12 | function login() {
13 | const loginurl = {
14 | url: 'http://' + $persistentStore.read("ip") + ':8080/wisedu-unified-login-api-v1.0/api/login?login_url=http%3A%2F%2Fauthserver.' + $persistentStore.read("学校") + '.cn%2Fauthserver%2Flogin%3Fservice%3Dhttps%253A%252F%252F' + $persistentStore.read("学校") + '.campusphere.net%252Fiap%252FloginSuccess&password=' + $persistentStore.read("密码") + '&username=' + $persistentStore.read("账号"),
15 | };
16 | return new Promise(function(resolve) {
17 | $httpClient.post(loginurl, function(error, resp, data) {
18 | console.log(resp.status)
19 | if (resp.status != 200) {
20 | login()
21 | } else {
22 | let jsonData = JSON.parse(data);
23 | console.log(jsonData.msg)
24 | if (jsonData.msg != "login success!") {
25 | login()
26 | } else {
27 | let cookies = jsonData.cookies
28 | let regex = /route.*MOD_AUTH_CAS/
29 | cp.cookie = cookies.replace(regex, "MOD_AUTH_CAS")
30 | console.log('\n' + cp.cookie)
31 | resolve(); //异步操作成功时调用, 将Promise对象的状态标记为"成功", 表示已完成
32 | }
33 | }
34 | });
35 | });
36 | }
37 |
38 | function wid() {
39 | const widurl = {
40 | url: 'https://' + $persistentStore.read("学校") + '.campusphere.net/wec-counselor-sign-apps/stu/sign/getStuSignInfosInOneDay',
41 | headers: {
42 | 'Cookie' : cp.cookie,
43 | 'Content-Type' : `application/json;charset=utf-8`
44 | },
45 | body: '{}'
46 | };
47 | return new Promise(function(resolve) {
48 | $httpClient.post(widurl, function(error, resp, data) {
49 | let jsonData = JSON.parse(data);
50 | console.log('\n' + data)
51 | cp.leave = jsonData["datas"].leaveTasks[0]
52 | if (cp.leave == undefined) {
53 | cp.wid = jsonData["datas"].unSignedTasks[0].signInstanceWid
54 | cp.signWid = jsonData["datas"].unSignedTasks[0].signWid
55 | } else {
56 | cp.wid = jsonData["datas"].leaveTasks[0].signInstanceWid
57 | cp.signWid = jsonData["datas"].leaveTasks[0].signWid
58 | }
59 | resolve(); //异步操作成功时调用, 将Promise对象的状态标记为"成功", 表示已完成
60 | });
61 | });
62 | }
63 |
64 | function form() {
65 | const formurl = {
66 | url: 'https://' + $persistentStore.read("学校") + '.campusphere.net/wec-counselor-sign-apps/stu/sign/detailSignInstance',
67 | headers: {
68 | 'Cookie' : cp.cookie,
69 | 'Content-Type' : 'application/json;charset=utf-8'
70 | },
71 | body: `{
72 | "signWid": ${cp.signWid},
73 | "signInstanceWid": ${cp.wid}
74 | }`,
75 | };
76 | return new Promise(function(resolve) {
77 | $httpClient.post(formurl, function(error, resp, data) {
78 | let jsonData = JSON.parse(data);
79 | cp.formWid = jsonData.datas.extraField[0].extraFieldItems[0].wid
80 | cp.formcontent = jsonData.datas.extraField[0].extraFieldItems[0].content
81 | resolve();
82 | })
83 | })
84 | }
85 | function submit() {
86 | const bodys = {
87 | "position": `${cp.location}`,
88 | "isMalposition": 1,
89 | "extraFieldItems": [
90 | {
91 | "extraFieldItemWid": `${cp.formWid}`,
92 | "extraFieldItemValue": `${cp.formcontent}`
93 | }
94 | ],
95 | "longitude": `${cp.long}`,
96 | "latitude": `${cp.la}`,
97 | "abnormalReason": "",
98 | "signInstanceWid": `${cp.wid}`,
99 | "isNeedExtra": 1,
100 | "signPhotoUrl": `${$persistentStore.read("照片")}`,
101 | "uaIsCpadaily": false
102 | }
103 | const submiturl = {
104 | url: 'https://' + $persistentStore.read("学校") + '.campusphere.net/wec-counselor-sign-apps/stu/sign/submitSign',
105 | headers: {
106 | 'Cookie' : cp.cookie,
107 | 'Content-Type' : 'application/json;charset=utf-8'
108 | },
109 | body: JSON.stringify(bodys)
110 | };
111 | return new Promise(function(resolve) {
112 | $httpClient.post(submiturl, function(error, resp, data) {
113 | let jsonData = JSON.parse(data);
114 | cp.msg = jsonData.message
115 | console.log(cp.msg)
116 | $httpClient.post({
117 | url: 'https://sctapi.ftqq.com/' + $persistentStore.read("server酱") + '.send',
118 | header: {
119 | 'Content-Type' : 'application/x-www-form-urlencoded; charset=utf-8'
120 | },
121 | body: 'title=今日校园' + cp.msg + '&desp=今日校园'
122 | }, function(error,resp,data) {
123 | let jsonData = JSON.parse(data)
124 | console.log('\n' + jsonData.message)
125 | $notification.post("今日校园", cp.msg, jsonData.message)
126 | resolve(); //异步操作成功时调用, 将Promise对象的状态标记为"成功", 表示已完成
127 | })
128 | });
129 | });
130 | }
131 |
--------------------------------------------------------------------------------
/Shadowrocket/campusphere.js:
--------------------------------------------------------------------------------
1 | let cp = {};
2 | cp.long = $persistentStore.read("经度");
3 | cp.la = $persistentStore.read("纬度");
4 | cp.location = $persistentStore.read("地区");
5 | (async function() {
6 | await login();
7 | await wid();
8 | await form();
9 | await submit();
10 | $done();
11 | })();
12 | function login() {
13 | console.log("await login")
14 | const loginurl = {
15 | url: 'http://' + $persistentStore.read("ip") + ':8080/wisedu-unified-login-api-v1.0/api/login?login_url=http%3A%2F%2Fauthserver.' + $persistentStore.read("学校") + '.cn%2Fauthserver%2Flogin%3Fservice%3Dhttps%253A%252F%252F' + $persistentStore.read("学校") + '.campusphere.net%252Fiap%252FloginSuccess&password=' + $persistentStore.read("密码") + '&username=' + $persistentStore.read("账号")
16 | };
17 | return new Promise(function(resolve) {
18 | $httpClient.post(loginurl, function(error, resp, data) {
19 | if (typeof(resp) == "undefined") {
20 | console.log(resp)
21 | login()
22 | }else if (resp.statusCode != 200) {
23 | console.log(resp.statusCode)
24 | login()
25 | } else {
26 | let jsonData = JSON.parse(data);
27 | console.log(jsonData.msg)
28 | if (jsonData.msg != "login success!") {
29 | login()
30 | } else {
31 | let cookies = jsonData.cookies
32 | let regex = /route.*MOD_AUTH_CAS/
33 | cp.cookie = cookies.replace(regex, "MOD_AUTH_CAS")
34 | console.log('\n' + cp.cookie)
35 | resolve(); //异步操作成功时调用, 将Promise对象的状态标记为"成功", 表示已完成
36 | }
37 | }
38 | });
39 | });
40 | }
41 |
42 | function wid() {
43 | console.log("await wid")
44 | const widurl = {
45 | url: 'https://' + $persistentStore.read("学校") + '.campusphere.net/wec-counselor-sign-apps/stu/sign/getStuSignInfosInOneDay',
46 | headers: {
47 | 'Cookie' : cp.cookie,
48 | 'Content-Type' : `application/json;charset=utf-8`
49 | },
50 | body: '{}'
51 | };
52 | return new Promise(function(resolve) {
53 | $httpClient.post(widurl, function(error, resp, data) {
54 | let jsonData = JSON.parse(data);
55 | console.log('\n' + data)
56 | cp.leave = jsonData["datas"].leaveTasks[0]
57 | cp.unsign = jsonData["datas"].unSignedTasks[0]
58 | if (typeof(cp.unsign) == "undefined" && typeof(cp.leave) == "undefined") {
59 | console.log("无签到")
60 | $done($notification.post("无签到","",""))
61 | } else if (typeof(cp.unsign) == "undefined") {
62 | cp.wid = jsonData["datas"].leaveTasks[0].signInstanceWid
63 | cp.signWid = jsonData["datas"].leaveTasks[0].signWid
64 | resolve();
65 | } else {
66 | cp.wid = jsonData["datas"].unSignedTasks[0].signInstanceWid
67 | cp.signWid = jsonData["datas"].unSignedTasks[0].signWid
68 | resolve();
69 | }
70 | });
71 | });
72 | }
73 |
74 | function form() {
75 | console.log("await form")
76 | const formurl = {
77 | url: 'https://' + $persistentStore.read("学校") + '.campusphere.net/wec-counselor-sign-apps/stu/sign/detailSignInstance',
78 | headers: {
79 | 'Cookie' : cp.cookie,
80 | 'Content-Type' : 'application/json;charset=utf-8'
81 | },
82 | body: `{
83 | "signWid": ${cp.signWid},
84 | "signInstanceWid": ${cp.wid}
85 | }`,
86 | };
87 | return new Promise(function(resolve) {
88 | $httpClient.post(formurl, function(error, resp, data) {
89 | let jsonData = JSON.parse(data);
90 | cp.formWid = jsonData.datas.extraField[0].extraFieldItems[0].wid
91 | cp.formWid1 = jsonData.datas.extraField[1].extraFieldItems[0].wid
92 | cp.formWid2 = jsonData.datas.extraField[2].extraFieldItems[0].wid
93 | cp.formWid3 = jsonData.datas.extraField[3].extraFieldItems[0].wid
94 | cp.formWid4 = jsonData.datas.extraField[4].extraFieldItems[0].wid
95 | cp.formcontent = jsonData.datas.extraField[0].extraFieldItems[0].content
96 | cp.formcontent1 = jsonData.datas.extraField[1].extraFieldItems[0].content
97 | cp.formcontent2 = jsonData.datas.extraField[2].extraFieldItems[0].content
98 | cp.formcontent3 = jsonData.datas.extraField[3].extraFieldItems[0].content
99 | cp.formcontent4 = jsonData.datas.extraField[4].extraFieldItems[0].content
100 | resolve();
101 | })
102 | })
103 | }
104 | function submit() {
105 | console.log("await submit")
106 | const bodys = {
107 | "abnormalReason": "",
108 | "position": `${cp.location}`,
109 | "longitude": `${cp.long}`,
110 | "isNeedExtra": 1,
111 | "latitude": `${cp.la}`,
112 | "isMalposition": 1,
113 | "extraFieldItems": [
114 | {
115 | "extraFieldItemWid": `${cp.formWid}`,
116 | "extraFieldItemValue": `${cp.formcontent}`
117 | },
118 | {
119 | "extraFieldItemWid": `${cp.formWid1}`,
120 | "extraFieldItemValue": `${cp.formcontent1}`
121 | },
122 | {
123 | "extraFieldItemWid": `${cp.formWid2}`,
124 | "extraFieldItemValue": `${cp.formcontent2}`
125 | },
126 | {
127 | "extraFieldItemWid": `${cp.formWid3}`,
128 | "extraFieldItemValue": `${cp.formcontent3}`
129 | },
130 | {
131 | "extraFieldItemWid": `${cp.formWid4}`,
132 | "extraFieldItemValue": `${cp.formcontent4}`
133 | }
134 | ],
135 | "signPhotoUrl": "",
136 | "uaIsCpadaily": false,
137 | "signInstanceWid": `${cp.wid}`
138 | }
139 | const submiturl = {
140 | url: 'https://' + $persistentStore.read("学校") + '.campusphere.net/wec-counselor-sign-apps/stu/sign/submitSign',
141 | headers: {
142 | 'Cookie' : cp.cookie,
143 | 'Content-Type' : 'application/json;charset=utf-8'
144 | },
145 | body: JSON.stringify(bodys)
146 | };
147 | return new Promise(function(resolve) {
148 | $httpClient.post(submiturl, function(error, resp, data) {
149 | let jsonData = JSON.parse(data);
150 | cp.msg = jsonData.message
151 | console.log(cp.msg)
152 | $notification.post("今日校园", cp.msg, "")
153 | resolve();
154 | });
155 | });
156 | }
--------------------------------------------------------------------------------
/Loon/campusphere.js:
--------------------------------------------------------------------------------
1 | let cp = {};
2 | cp.long = $persistentStore.read("经度");
3 | cp.la = $persistentStore.read("纬度");
4 | cp.location = $persistentStore.read("地区");
5 | (async function() {
6 | if ($persistentStore.read("sign") == "SUCCESS") {
7 | $done(console.log("已签到"))
8 | } else {
9 | await login();
10 | await wid();
11 | await form();
12 | await submit();
13 | $done();
14 | }
15 | })();
16 | function login() {
17 | console.log("await login")
18 | const loginurl = {
19 | url: 'http://' + $persistentStore.read("ip") + ':8080/wisedu-unified-login-api-v1.0/api/login?login_url=http%3A%2F%2Fauthserver.' + $persistentStore.read("学校") + '.cn%2Fauthserver%2Flogin%3Fservice%3Dhttps%253A%252F%252F' + $persistentStore.read("学校") + '.campusphere.net%252Fiap%252FloginSuccess&password=' + $persistentStore.read("密码") + '&username=' + $persistentStore.read("账号"),
20 | timeout: 30
21 | };
22 | return new Promise(function(resolve) {
23 | $httpClient.post(loginurl, function(error, resp, data) {
24 | if (typeof(resp) == "undefined") {
25 | console.log(resp)
26 | login()
27 | }else if (resp.status != 200) {
28 | console.log(resp.status)
29 | login()
30 | } else {
31 | let jsonData = JSON.parse(data);
32 | console.log(jsonData.msg)
33 | if (jsonData.msg != "login success!") {
34 | login()
35 | } else {
36 | let cookies = jsonData.cookies
37 | let regex = /route.*MOD_AUTH_CAS/
38 | cp.cookie = cookies.replace(regex, "MOD_AUTH_CAS")
39 | console.log('\n' + cp.cookie)
40 | resolve(); //异步操作成功时调用, 将Promise对象的状态标记为"成功", 表示已完成
41 | }
42 | }
43 | });
44 | });
45 | }
46 |
47 | function wid() {
48 | console.log("await wid")
49 | const widurl = {
50 | url: 'https://' + $persistentStore.read("学校") + '.campusphere.net/wec-counselor-sign-apps/stu/sign/getStuSignInfosInOneDay',
51 | headers: {
52 | 'Cookie' : cp.cookie,
53 | 'Content-Type' : `application/json;charset=utf-8`
54 | },
55 | body: '{}'
56 | };
57 | return new Promise(function(resolve) {
58 | $httpClient.post(widurl, function(error, resp, data) {
59 | let jsonData = JSON.parse(data);
60 | console.log('\n' + data)
61 | cp.leave = jsonData["datas"].leaveTasks[0]
62 | cp.unsign = jsonData["datas"].unSignedTasks[0]
63 | if (typeof(cp.unsign) == "undefined" && typeof(cp.leave) == "undefined") {
64 | console.log("无签到")
65 | $persistentStore.write('SUCCESS', 'sign')
66 | $done($notification.post("无签到","",""))
67 | } else if (typeof(cp.unsign) == "undefined") {
68 | cp.wid = jsonData["datas"].leaveTasks[0].signInstanceWid
69 | cp.signWid = jsonData["datas"].leaveTasks[0].signWid
70 | resolve();
71 | } else {
72 | cp.wid = jsonData["datas"].unSignedTasks[0].signInstanceWid
73 | cp.signWid = jsonData["datas"].unSignedTasks[0].signWid
74 | resolve();
75 | }
76 | });
77 | });
78 | }
79 |
80 | function form() {
81 | console.log("await form")
82 | const formurl = {
83 | url: 'https://' + $persistentStore.read("学校") + '.campusphere.net/wec-counselor-sign-apps/stu/sign/detailSignInstance',
84 | headers: {
85 | 'Cookie' : cp.cookie,
86 | 'Content-Type' : 'application/json;charset=utf-8'
87 | },
88 | body: `{
89 | "signWid": ${cp.signWid},
90 | "signInstanceWid": ${cp.wid}
91 | }`,
92 | };
93 | return new Promise(function(resolve) {
94 | $httpClient.post(formurl, function(error, resp, data) {
95 | let jsonData = JSON.parse(data);
96 | cp.formWid = jsonData.datas.extraField[0].extraFieldItems[0].wid
97 | cp.formWid1 = jsonData.datas.extraField[1].extraFieldItems[0].wid
98 | cp.formWid2 = jsonData.datas.extraField[2].extraFieldItems[0].wid
99 | cp.formWid3 = jsonData.datas.extraField[3].extraFieldItems[0].wid
100 | cp.formWid4 = jsonData.datas.extraField[4].extraFieldItems[0].wid
101 | cp.formcontent = jsonData.datas.extraField[0].extraFieldItems[0].content
102 | cp.formcontent1 = jsonData.datas.extraField[1].extraFieldItems[0].content
103 | cp.formcontent2 = jsonData.datas.extraField[2].extraFieldItems[0].content
104 | cp.formcontent3 = jsonData.datas.extraField[3].extraFieldItems[0].content
105 | cp.formcontent4 = jsonData.datas.extraField[4].extraFieldItems[0].content
106 | resolve();
107 | })
108 | })
109 | }
110 | function submit() {
111 | console.log("await submit")
112 | const bodys = {
113 | "abnormalReason": "",
114 | "position": `${cp.location}`,
115 | "longitude": `${cp.long}`,
116 | "isNeedExtra": 1,
117 | "latitude": `${cp.la}`,
118 | "isMalposition": 1,
119 | "extraFieldItems": [
120 | {
121 | "extraFieldItemWid": `${cp.formWid}`,
122 | "extraFieldItemValue": `${cp.formcontent}`
123 | },
124 | {
125 | "extraFieldItemWid": `${cp.formWid1}`,
126 | "extraFieldItemValue": `${cp.formcontent1}`
127 | },
128 | {
129 | "extraFieldItemWid": `${cp.formWid2}`,
130 | "extraFieldItemValue": `${cp.formcontent2}`
131 | },
132 | {
133 | "extraFieldItemWid": `${cp.formWid3}`,
134 | "extraFieldItemValue": `${cp.formcontent3}`
135 | },
136 | {
137 | "extraFieldItemWid": `${cp.formWid4}`,
138 | "extraFieldItemValue": `${cp.formcontent4}`
139 | }
140 | ],
141 | "signPhotoUrl": "",
142 | "uaIsCpadaily": false,
143 | "signInstanceWid": `${cp.wid}`
144 | }
145 | const submiturl = {
146 | url: 'https://' + $persistentStore.read("学校") + '.campusphere.net/wec-counselor-sign-apps/stu/sign/submitSign',
147 | headers: {
148 | 'Cookie' : cp.cookie,
149 | 'Content-Type' : 'application/json;charset=utf-8'
150 | },
151 | body: JSON.stringify(bodys)
152 | };
153 | return new Promise(function(resolve) {
154 | $httpClient.post(submiturl, function(error, resp, data) {
155 | let jsonData = JSON.parse(data);
156 | cp.msg = jsonData.message
157 | console.log(cp.msg)
158 | $notification.post("今日校园", cp.msg, "")
159 | if (cp.msg == "SUCCESS") {
160 | $persistentStore.write(cp.msg, 'sign')
161 | resolve()
162 | } else {
163 | resolve();
164 | }
165 | });
166 | });
167 | }
--------------------------------------------------------------------------------
/Surge/campusphere.js:
--------------------------------------------------------------------------------
1 | let cp = {};
2 | cp.long = $persistentStore.read("经度");
3 | cp.la = $persistentStore.read("纬度");
4 | cp.location = $persistentStore.read("地区");
5 | (async function() {
6 | if ($persistentStore.read("sign") == "SUCCESS") {
7 | $done(console.log("已签到"))
8 | } else {
9 | await login();
10 | await wid();
11 | await form();
12 | await submit();
13 | $done();
14 | }
15 | })();
16 | function login() {
17 | console.log("await login")
18 | const loginurl = {
19 | url: 'http://' + $persistentStore.read("ip") + ':8080/wisedu-unified-login-api-v1.0/api/login?login_url=http%3A%2F%2Fauthserver.' + $persistentStore.read("学校") + '.cn%2Fauthserver%2Flogin%3Fservice%3Dhttps%253A%252F%252F' + $persistentStore.read("学校") + '.campusphere.net%252Fiap%252FloginSuccess&password=' + $persistentStore.read("密码") + '&username=' + $persistentStore.read("账号"),
20 | timeout: 30
21 | };
22 | return new Promise(function(resolve) {
23 | $httpClient.post(loginurl, function(error, resp, data) {
24 | if (typeof(resp) == "undefined") {
25 | console.log(resp)
26 | login()
27 | }else if (resp.status != 200) {
28 | console.log(resp.status)
29 | login()
30 | } else {
31 | let jsonData = JSON.parse(data);
32 | console.log(jsonData.msg)
33 | if (jsonData.msg != "login success!") {
34 | login()
35 | } else {
36 | let cookies = jsonData.cookies
37 | let regex = /route.*MOD_AUTH_CAS/
38 | cp.cookie = cookies.replace(regex, "MOD_AUTH_CAS")
39 | console.log('\n' + cp.cookie)
40 | resolve(); //异步操作成功时调用, 将Promise对象的状态标记为"成功", 表示已完成
41 | }
42 | }
43 | });
44 | });
45 | }
46 |
47 | function wid() {
48 | console.log("await wid")
49 | const widurl = {
50 | url: 'https://' + $persistentStore.read("学校") + '.campusphere.net/wec-counselor-sign-apps/stu/sign/getStuSignInfosInOneDay',
51 | headers: {
52 | 'Cookie' : cp.cookie,
53 | 'Content-Type' : `application/json;charset=utf-8`
54 | },
55 | body: '{}'
56 | };
57 | return new Promise(function(resolve) {
58 | $httpClient.post(widurl, function(error, resp, data) {
59 | let jsonData = JSON.parse(data);
60 | console.log('\n' + data)
61 | cp.leave = jsonData["datas"].leaveTasks[0]
62 | cp.unsign = jsonData["datas"].unSignedTasks[0]
63 | if (typeof(cp.unsign) == "undefined" && typeof(cp.leave) == "undefined") {
64 | console.log("无签到")
65 | $persistentStore.write('SUCCESS', 'sign')
66 | $done($notification.post("无签到","",""))
67 | } else if (typeof(cp.unsign) == "undefined") {
68 | cp.wid = jsonData["datas"].leaveTasks[0].signInstanceWid
69 | cp.signWid = jsonData["datas"].leaveTasks[0].signWid
70 | resolve();
71 | } else {
72 | cp.wid = jsonData["datas"].unSignedTasks[0].signInstanceWid
73 | cp.signWid = jsonData["datas"].unSignedTasks[0].signWid
74 | resolve();
75 | }
76 | });
77 | });
78 | }
79 |
80 | function form() {
81 | console.log("await form")
82 | const formurl = {
83 | url: 'https://' + $persistentStore.read("学校") + '.campusphere.net/wec-counselor-sign-apps/stu/sign/detailSignInstance',
84 | headers: {
85 | 'Cookie' : cp.cookie,
86 | 'Content-Type' : 'application/json;charset=utf-8'
87 | },
88 | body: `{
89 | "signWid": ${cp.signWid},
90 | "signInstanceWid": ${cp.wid}
91 | }`,
92 | };
93 | return new Promise(function(resolve) {
94 | $httpClient.post(formurl, function(error, resp, data) {
95 | let jsonData = JSON.parse(data);
96 | cp.formWid = jsonData.datas.extraField[0].extraFieldItems[0].wid
97 | cp.formWid1 = jsonData.datas.extraField[1].extraFieldItems[0].wid
98 | cp.formWid2 = jsonData.datas.extraField[2].extraFieldItems[0].wid
99 | cp.formWid3 = jsonData.datas.extraField[3].extraFieldItems[0].wid
100 | cp.formWid4 = jsonData.datas.extraField[4].extraFieldItems[0].wid
101 | cp.formcontent = jsonData.datas.extraField[0].extraFieldItems[0].content
102 | cp.formcontent1 = jsonData.datas.extraField[1].extraFieldItems[0].content
103 | cp.formcontent2 = jsonData.datas.extraField[2].extraFieldItems[0].content
104 | cp.formcontent3 = jsonData.datas.extraField[3].extraFieldItems[0].content
105 | cp.formcontent4 = jsonData.datas.extraField[4].extraFieldItems[0].content
106 | resolve();
107 | })
108 | })
109 | }
110 | function submit() {
111 | console.log("await submit")
112 | const bodys = {
113 | "abnormalReason": "",
114 | "position": `${cp.location}`,
115 | "longitude": `${cp.long}`,
116 | "isNeedExtra": 1,
117 | "latitude": `${cp.la}`,
118 | "isMalposition": 1,
119 | "extraFieldItems": [
120 | {
121 | "extraFieldItemWid": `${cp.formWid}`,
122 | "extraFieldItemValue": `${cp.formcontent}`
123 | },
124 | {
125 | "extraFieldItemWid": `${cp.formWid1}`,
126 | "extraFieldItemValue": `${cp.formcontent1}`
127 | },
128 | {
129 | "extraFieldItemWid": `${cp.formWid2}`,
130 | "extraFieldItemValue": `${cp.formcontent2}`
131 | },
132 | {
133 | "extraFieldItemWid": `${cp.formWid3}`,
134 | "extraFieldItemValue": `${cp.formcontent3}`
135 | },
136 | {
137 | "extraFieldItemWid": `${cp.formWid4}`,
138 | "extraFieldItemValue": `${cp.formcontent4}`
139 | }
140 | ],
141 | "signPhotoUrl": "",
142 | "uaIsCpadaily": false,
143 | "signInstanceWid": `${cp.wid}`
144 | }
145 | const submiturl = {
146 | url: 'https://' + $persistentStore.read("学校") + '.campusphere.net/wec-counselor-sign-apps/stu/sign/submitSign',
147 | headers: {
148 | 'Cookie' : cp.cookie,
149 | 'Content-Type' : 'application/json;charset=utf-8'
150 | },
151 | body: JSON.stringify(bodys)
152 | };
153 | return new Promise(function(resolve) {
154 | $httpClient.post(submiturl, function(error, resp, data) {
155 | let jsonData = JSON.parse(data);
156 | cp.msg = jsonData.message
157 | console.log(cp.msg)
158 | $notification.post("今日校园", cp.msg, "")
159 | if (cp.msg == "SUCCESS") {
160 | $persistentStore.write(cp.msg, 'sign')
161 | resolve()
162 | } else {
163 | resolve();
164 | }
165 | });
166 | });
167 | }
--------------------------------------------------------------------------------
/Quantumult-X/campusphere.js:
--------------------------------------------------------------------------------
1 | let cp = {};
2 | cp.long = $prefs.valueForKey("经度");
3 | cp.la = $prefs.valueForKey("纬度");
4 | cp.location = $prefs.valueForKey("地区");
5 | (async function() {
6 | await login()
7 | await wid()
8 | await form()
9 | await submit()
10 | $done();
11 | })();
12 |
13 | function login() {
14 | console.log("await response")
15 | const Head = {
16 | url: 'http://' + $prefs.valueForKey("ip") + ':8080/wisedu-unified-login-api-v1.0/swagger-ui.html',
17 | method: "HEAD"
18 | };
19 | const loginurl = {
20 | url: 'http://' + $prefs.valueForKey("ip") + ':8080/wisedu-unified-login-api-v1.0/api/login?login_url=http%3A%2F%2Fauthserver.' + $prefs.valueForKey("学校") + '.cn%2Fauthserver%2Flogin%3Fservice%3Dhttps%253A%252F%252F' + $prefs.valueForKey("学校") + '.campusphere.net%252Fiap%252FloginSuccess&password=' + $prefs.valueForKey("密码") + '&username=' + $prefs.valueForKey("账号")
21 | };
22 | return new Promise(function(resolve) {
23 | $task.fetch(Head).then(response => {
24 | console.log(response.statusCode)
25 | if (response.statusCode != 200) {
26 | login()
27 | } else {
28 | console.log("await login")
29 | $task.fetch(loginurl).then(resp => {
30 | if (typeof(resp.body) == "undefined") {
31 | console.log(resp.body)
32 | login()
33 | } else {
34 | let jsonData = JSON.parse(resp.body);
35 | if (jsonData.msg != "login success!") {
36 | login()
37 | } else {
38 | let cookies = jsonData.cookies
39 | let regex = /route.*MOD_AUTH_CAS/
40 | cp.cookie = cookies.replace(regex, "MOD_AUTH_CAS")
41 | console.log('\n' + cp.cookie)
42 | resolve()
43 | }
44 | }
45 | }, reason => {
46 | console.log(reason.error)
47 | login()
48 | })
49 | }
50 | }, reason => {
51 | console.log(reason.error)
52 | login()
53 | });
54 | });
55 | }
56 |
57 | function wid() {
58 | console.log("await wid")
59 | const widurl = {
60 | url: 'https://' + $prefs.valueForKey("学校") + '.campusphere.net/wec-counselor-sign-apps/stu/sign/getStuSignInfosInOneDay',
61 | method: "POST",
62 | headers: {
63 | 'Cookie' : cp.cookie,
64 | 'Content-Type' : 'application/json;charset=utf-8'
65 | },
66 | body: '{}'
67 | };
68 | return new Promise(function(resolve) {
69 | $task.fetch(widurl).then(response => {
70 | let jsonData = JSON.parse(response.body);
71 | console.log('\n' + response.body)
72 | cp.leave = jsonData["datas"].leaveTasks[0]
73 | cp.unsign = jsonData["datas"].unSignedTasks[0]
74 | if (typeof(cp.unsign) == "undefined" && typeof(cp.leave) == "undefined") {
75 | console.log("无签到")
76 | $done($notify("无签到","",""))
77 | } else if (typeof(cp.unsign) == "undefined") {
78 | cp.wid = jsonData["datas"].leaveTasks[0].signInstanceWid
79 | cp.signWid = jsonData["datas"].leaveTasks[0].signWid
80 | resolve();
81 | } else {
82 | cp.wid = jsonData["datas"].unSignedTasks[0].signInstanceWid
83 | cp.signWid = jsonData["datas"].unSignedTasks[0].signWid
84 | resolve();
85 | }
86 | }, reason => {
87 | console.log(reason.error)
88 | wid()
89 | })
90 | });
91 | }
92 |
93 | function form() {
94 | console.log("await form")
95 | const formurl = {
96 | url: 'https://' + $prefs.valueForKey("学校") + '.campusphere.net/wec-counselor-sign-apps/stu/sign/detailSignInstance',
97 | method: "POST",
98 | headers: {
99 | 'Cookie' : cp.cookie,
100 | 'Content-Type' : 'application/json;charset=utf-8'
101 | },
102 | body: `{
103 | "signWid": ${cp.signWid},
104 | "signInstanceWid": ${cp.wid}
105 | }`
106 | };
107 | return new Promise(function(resolve) {
108 | $task.fetch(formurl).then(response => {
109 | let jsonData = JSON.parse(response.body);
110 | cp.formWid = jsonData.datas.extraField[0].extraFieldItems[0].wid
111 | cp.formWid1 = jsonData.datas.extraField[1].extraFieldItems[0].wid
112 | cp.formWid2 = jsonData.datas.extraField[2].extraFieldItems[0].wid
113 | cp.formWid3 = jsonData.datas.extraField[3].extraFieldItems[0].wid
114 | cp.formWid4 = jsonData.datas.extraField[4].extraFieldItems[0].wid
115 | cp.formcontent = jsonData.datas.extraField[0].extraFieldItems[0].content
116 | cp.formcontent1 = jsonData.datas.extraField[1].extraFieldItems[0].content
117 | cp.formcontent2 = jsonData.datas.extraField[2].extraFieldItems[0].content
118 | cp.formcontent3 = jsonData.datas.extraField[3].extraFieldItems[0].content
119 | cp.formcontent4 = jsonData.datas.extraField[4].extraFieldItems[0].content
120 | resolve();
121 | }, reason => {
122 | console.log(reason.error)
123 | form()
124 | })
125 | })
126 | }
127 | function submit() {
128 | console.log("await submit")
129 | const bodys = {
130 | "abnormalReason": "",
131 | "position": `${cp.location}`,
132 | "longitude": `${cp.long}`,
133 | "isNeedExtra": 1,
134 | "latitude": `${cp.la}`,
135 | "isMalposition": 1,
136 | "extraFieldItems": [
137 | {
138 | "extraFieldItemWid": `${cp.formWid}`,
139 | "extraFieldItemValue": `${cp.formcontent}`
140 | },
141 | {
142 | "extraFieldItemWid": `${cp.formWid1}`,
143 | "extraFieldItemValue": `${cp.formcontent1}`
144 | },
145 | {
146 | "extraFieldItemWid": `${cp.formWid2}`,
147 | "extraFieldItemValue": `${cp.formcontent2}`
148 | },
149 | {
150 | "extraFieldItemWid": `${cp.formWid3}`,
151 | "extraFieldItemValue": `${cp.formcontent3}`
152 | },
153 | {
154 | "extraFieldItemWid": `${cp.formWid4}`,
155 | "extraFieldItemValue": `${cp.formcontent4}`
156 | }
157 | ],
158 | "signPhotoUrl": "",
159 | "uaIsCpadaily": false,
160 | "signInstanceWid": `${cp.wid}`
161 | }
162 | const submiturl = {
163 | url: 'https://' + $prefs.valueForKey("学校") + '.campusphere.net/wec-counselor-sign-apps/stu/sign/submitSign',
164 | method: "POST",
165 | headers: {
166 | 'Cookie' : cp.cookie,
167 | 'Content-Type' : 'application/json;charset=utf-8'
168 | },
169 | body: JSON.stringify(bodys)
170 | };
171 | return new Promise(function(resolve) {
172 | $task.fetch(submiturl).then(response => {
173 | let jsonData = JSON.parse(response.body);
174 | cp.msg = jsonData.message
175 | console.log(cp.msg)
176 | $notify("今日校园", cp.msg, "")
177 | resolve();
178 | }, reason => {
179 | console.log(reason.error)
180 | submit()
181 | })
182 | });
183 | }
184 |
--------------------------------------------------------------------------------
/Surge/IP-Score-All-Info.js:
--------------------------------------------------------------------------------
1 | /***
2 | 本人懒,懒得改能用就行
3 |
4 | IP检测评分等等等等等等,懒得写了
5 | ***/
6 |
7 |
8 | let net = {}; //预留的空对象, 便于"函数"(function)之间读
9 |
10 | net.中国电信 = ['460-03','460-05','460-11'];
11 | net.中国联通 = ['460-01','460-06','460-09'];
12 | net.中国移动 = ['460-00','460-02','460-04','460-07','460-08'];
13 | net.中国广电 = ['460-15'];
14 | net.中国铁通 = ['460-20'];
15 | net.v4 = $network.v4.primaryAddress
16 | net.ssid = $network.wifi.ssid
17 | net.carrier = $network["cellular-data"].carrier
18 | net.router = $network.v4.primaryRouter
19 | net.radio = $network["cellular-data"].radio;
20 |
21 | (async function() {
22 | await ipapi();
23 | await Promise.all([
24 | scam(),
25 | ipinfo(),
26 | youtube()
27 | ]);
28 | var regex=/^192.168/
29 | if(regex.test(net.v4)){
30 | if(net.v4 == net.query){
31 | $done({
32 | title: `${net.ssid}`,
33 | content: `ASN: `+net.asn+`\n`+net.youtube+`: Google `+net.emoji+`: `+net.query+`\nIPs: `+net.router+` & `+net.v4+`\nFraud score: `+net.score+` `+net.risk+` risk`+`\nTor: `+net.tor+` VPN: `+net.vpn+`\nRelay: `+net.relay+` Proxy: `+net.proxy+`\nServer: `+net.server+` Hosting: `+net.hosting+`\nASN Type: `+net.atype+`\nName: `+net.aname+`\nCompany Type: `+net.ctype+`\nName: `+net.cname,
34 | icon: "wifi",
35 | 'icon-color': "#00FF00"
36 | });
37 | }else{
38 | $done({
39 | title: `${net.ssid}`,
40 | content: `ASN: `+net.asn+`\n`+net.youtube+`: Google `+net.emoji+`: `+net.query+`\nIPs: `+net.router+` & `+net.v4+`\nFraud score: `+net.score+` `+net.risk+` risk`+`\nTor: `+net.tor+` VPN: `+net.vpn+`\nRelay: `+net.relay+` Proxy: `+net.proxy+`\nServer: `+net.server+` Hosting: `+net.hosting+`\nASN Type: `+net.atype+`\nName: `+net.aname+`\nCompany Type: `+net.ctype+`\nName: `+net.cname,
41 | icon: "wifi",
42 | 'icon-color': "#00FF00"
43 | });
44 | }
45 | }else if(`${net.radio}` == "null"){
46 | if(`${net.v4}` == `${net.query}`){
47 | $done({
48 | title: `Hotspot`,
49 | content: `ASN: `+net.asn+`\n`+net.youtube+`: Google `+net.emoji+`: `+net.query+`\nIPs: `+net.router+` & `+net.v4+`\nFraud score: `+net.score+` `+net.risk+` risk`+`\nTor: `+net.tor+` VPN: `+net.vpn+`\nRelay: `+net.relay+` Proxy: `+net.proxy+`\nServer: `+net.server+` Hosting: `+net.hosting+`\nASN Type: `+net.atype+`\nName: `+net.aname+`\nCompany Type: `+net.ctype+`\nName: `+net.cname,
50 | icon: "personalhotspot",
51 | 'icon-color': "#0000FF"
52 | });
53 | }else{
54 | $done({
55 | title: `Hotspot`,
56 | content: `ASN: `+net.asn+`\n`+net.youtube+`: Google `+net.emoji+`: `+net.query+`\nIPs: `+net.router+` & `+net.v4+`\nFraud score: `+net.score+` `+net.risk+` risk`+`\nTor: `+net.tor+` VPN: `+net.vpn+`\nRelay: `+net.relay+` Proxy: `+net.proxy+`\nServer: `+net.server+` Hosting: `+net.hosting+`\nASN Type: `+net.atype+`\nName: `+net.aname+`\nCompany Type: `+net.ctype+`\nName: `+net.cname,
57 | icon: "personalhotspot",
58 | 'icon-color': "#0000FF"
59 | });
60 | }
61 | }else{
62 | if(net.中国电信.includes(net.carrier)){
63 | net.运营商 = "China Telecom";
64 | }else if(net.中国联通.includes(net.carrier)){
65 | net.运营商 = "China Unicom";
66 | }else if(net.中国移动.includes(net.carrier)){
67 | net.运营商 = "China Mobile";
68 | }else if(net.中国广电.includes(net.carrier)){
69 | net.运营商 = "China Broadcasting Network";
70 | }else if(net.中国铁通.includes(net.carrier)){
71 | net.运营商 = "China Tietong";
72 | }else{
73 | net.运营商 = "𝓜𝓸𝓫𝓲𝓵𝓮 𝓝𝓮𝓽𝔀𝓸𝓻𝓴";
74 | }
75 | if(`${net.v4}` == `${net.query}`){
76 | $done({
77 | title: `${net.运营商}`,
78 | content: `Radio: `+net.radio+` ASN: `+net.asn+`\n`+net.youtube+`: Google `+net.emoji+`: `+net.query+`\nIPs: `+net.router+` & `+net.v4+`\nFraud score: `+net.score+` `+net.risk+` risk`+`\nTor: `+net.tor+` VPN: `+net.vpn+`\nRelay: `+net.relay+` Proxy: `+net.proxy+`\nServer: `+net.server+` Hosting: `+net.hosting+`\nASN Type: `+net.atype+`\nName: `+net.aname+`\nCompany Type: `+net.ctype+`\nName: `+net.cname,
79 | icon: "antenna.radiowaves.left.and.right",
80 | 'icon-color': "#EA0300"
81 | });
82 | }else{
83 | $done({
84 | title: `${net.运营商}`,
85 | content: `Radio: `+net.radio+` ASN: `+net.asn+`\n`+net.youtube+`: Google `+net.emoji+`: `+net.query+`\nIPs: `+net.router+` & `+net.v4+`\nFraud score: `+net.score+` `+net.risk+` risk`+`\nTor: `+net.tor+` VPN: `+net.vpn+`\nRelay: `+net.relay+` Proxy: `+net.proxy+`\nServer: `+net.server+` Hosting: `+net.hosting+`\nASN Type: `+net.atype+`\nName: `+net.aname+`\nCompany Type: `+net.ctype+`\nName: `+net.cname,
86 | icon: "antenna.radiowaves.left.and.right",
87 | 'icon-color': "#EA0300"
88 | });
89 | }
90 | };
91 | })();
92 |
93 | function ipapi() {
94 | return new Promise(function(resolve) {
95 | $httpClient.get("http://ip-api.com/json/", function(error, response, body){
96 | var jsondata = JSON.parse(body)
97 | net.city = jsondata.city
98 | net.query = jsondata.query
99 | net.emoji = getFlagEmoji(jsondata.countryCode)
100 | //net.proxy = jsondata.proxy
101 | //net.hosting = jsondata.hosting
102 | resolve();
103 | })
104 | })
105 | };
106 |
107 | function scam() {
108 | return new Promise(function(resolve) {
109 | $httpClient.get({url: 'https://scamalytics.com/ip/' + net.query}, function(error,resp,html) {
110 | const regex = /"score":"(\d+)"/;
111 | const regex1 = /"risk":"(\w+)"/;
112 | const regex2 = /Server<\/th>\s* | (Yes|No)<\/div><\/td>/;
113 | const regex3 = / Tor Exit Node<\/th>\s* | (Yes|No)<\/div><\/td>/;
114 | const match = html.match(regex);
115 | const same = html.match(regex1);
116 | const server = html.match(regex2);
117 | const tor = html.match(regex3)
118 | net.score = match[1];
119 | net.risk = same[1];
120 | net.server = server[2];
121 | net.tor = tor[2];
122 | resolve();
123 | });
124 | })
125 | };
126 |
127 | function ipinfo() {
128 | return new Promise(function(resolve) {
129 | $httpClient.get({url: 'https://ipinfo.io/widget/demo/' + net.query}, function(error,resp,data) {
130 | let jsonData = JSON.parse(data)
131 | net.asn = jsonData.data.asn.asn
132 | net.atype = jsonData.data.asn.type
133 | net.aname = jsonData.data.asn.name
134 | net.ctype = jsonData.data.company.type
135 | net.cname = jsonData.data.company.name
136 | net.proxy = jsonData.data.privacy.proxy
137 | net.hosting = jsonData.data.privacy.hosting
138 | net.vpn = jsonData.data.privacy.vpn
139 | net.relay = jsonData.data.privacy.relay
140 | resolve();
141 | })
142 | })
143 | };
144 |
145 | function youtube() {
146 | return new Promise(function(resolve) {
147 | $httpClient.get({url: 'https://www.youtube.com/premium', headers: {'User-Agent' : 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/94.0.4606.61 Safari/537.36'}}, function(error,resp,body) {
148 | let reg = new RegExp ("contentRegion\\\":\\\"\\w{2}\\\"")
149 | let a = JSON.stringify(reg.exec(body))
150 | let YouTube = a.replace(/(\[\"contentRegion\\\":\\\")(\w+)\\\"\"\]/, '$2')
151 | net.youtube = getFlagEmoji(YouTube)
152 | resolve();
153 | })
154 | })
155 | };
156 |
157 | /**
158 | function getFlagEmoji(countryCode) {
159 | const codePoints = countryCode
160 | .toUpperCase()
161 | .split('')
162 | .map(char => 127397 + char.charCodeAt());
163 | return String.fromCodePoint(...codePoints);
164 | };
165 | **/
166 |
167 | function getFlagEmoji(country_code) {
168 | if(country_code === `TW`){
169 | let codePoints = `CN`
170 | .toUpperCase()
171 | .split('')
172 | .map(char => 127397 + char.charCodeAt());
173 | return String.fromCodePoint(...codePoints);
174 | }else{
175 | const codePoints = country_code
176 | .toUpperCase()
177 | .split('')
178 | .map(char => 127397 + char.charCodeAt());
179 | return String.fromCodePoint(...codePoints);
180 | }
181 | };
--------------------------------------------------------------------------------
/Surge/up_pddns.js:
--------------------------------------------------------------------------------
1 | /*****
2 | 使用方法:
3 | 1: Github创建私有库后直接创建DDNS.json文件。再创建classic personal access token并给予所有权限
4 |
5 | 2: Surge Mac文本编辑配置文件添加内容如下:
6 |
7 | 3: [Rule]规则:
8 | DOMAIN,api64.ipify.org,V6
9 | DOMAIN,ipapi.co,V6
10 | DOMAIN,api.ipify.org,V4
11 |
12 | 4: [Proxy]节点:
13 | V6 = direct, test-url=http://connectivitycheck.platform.hicloud.com/generate_204, ip-version=v6-only
14 | V4 = direct, test-url=http://connectivitycheck.platform.hicloud.com/generate_204, ip-version=v4-only
15 |
16 | 5: [Script]脚本:
17 | up_pddns = type=event,event-name=network-changed,script-path=https://raw.githubusercontent.com/DecoAri/JavaScript/main/Surge/up_pddns.js,argument=owner=👨&token=🔑&repo=🏠&branch=🛣️&filePath=📄&fileName=📖
18 |
19 | 6: 请替换步骤5里面argument里面的👨、🔑、🏠、🛣️、📄和📖。
20 | 👨为你github的用户名
21 | 🔑为github的personal access token。如不知道该开什么权限请全部勾选(⚠️别把token分享给别人)
22 | 🏠为你的第一步创建的库名称
23 | 🛣️为你的branch(一般为main或者master)
24 | 📄为你的最终文件的路径,如:path/to/your-DDNS.json
25 | 📖为你的文件名称:如DDNS.json
26 |
27 | 举个完整例子:
28 | https://raw.githubusercontent.com/woaini/PDDNS/main/DDNS.json
29 | 或
30 | https://raw.githubusercontent.com/woaini/PDDNS/main/Surge/DDNS.json 此条带filePath
31 |
32 | 以上例子owner为woaini、repo为PDDNS、branch为main、filePath为Surge/DDNS.json、fileName为DDNS.json
33 | ****/
34 |
35 |
36 |
37 | function getArgs() {
38 | return Object.fromEntries(
39 | $argument
40 | .split("&")
41 | .map((item) => item.split("="))
42 | .map(([k, v]) => [k, decodeURIComponent(v)])
43 | );
44 | }
45 |
46 | var base64EncodeChars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/',
47 | base64DecodeChars = new Array((-1), (-1), (-1), (-1), (-1), (-1), (-1), (-1), (-1), (-1), (-1), (-1), (-1), (-1), (-1), (-1), (-1), (-1), (-1), (-1), (-1), (-1), (-1), (-1), (-1), (-1), (-1), (-1), (-1), (-1), (-1), (-1), (-1), (-1), (-1), (-1), (-1), (-1), (-1), (-1), (-1), (-1), (-1), 62, (-1), (-1), (-1), 63, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, (-1), (-1), (-1), (-1), (-1), (-1), (-1), 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, (-1), (-1), (-1), (-1), (-1), (-1), 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, (-1), (-1), (-1), (-1), (-1));
48 | var base64encode = function (e) {
49 | var r, a, c, h, o, t;
50 | for (c = e.length, a = 0, r = ''; a < c;) {
51 | if (h = 255 & e.charCodeAt(a++), a == c) {
52 | r += base64EncodeChars.charAt(h >> 2),
53 | r += base64EncodeChars.charAt((3 & h) << 4),
54 | r += '==';
55 | break
56 | }
57 | if (o = e.charCodeAt(a++), a == c) {
58 | r += base64EncodeChars.charAt(h >> 2),
59 | r += base64EncodeChars.charAt((3 & h) << 4 | (240 & o) >> 4),
60 | r += base64EncodeChars.charAt((15 & o) << 2),
61 | r += '=';
62 | break
63 | }
64 | t = e.charCodeAt(a++),
65 | r += base64EncodeChars.charAt(h >> 2),
66 | r += base64EncodeChars.charAt((3 & h) << 4 | (240 & o) >> 4),
67 | r += base64EncodeChars.charAt((15 & o) << 2 | (192 & t) >> 6),
68 | r += base64EncodeChars.charAt(63 & t)
69 | }
70 | return r
71 | }
72 | var base64decode = function (e) {
73 | var r, a, c, h, o, t, d;
74 | for (t = e.length, o = 0, d = ''; o < t;) {
75 | do r = base64DecodeChars[255 & e.charCodeAt(o++)];
76 | while (o < t && r == -1);
77 | if (r == -1) break;
78 | do a = base64DecodeChars[255 & e.charCodeAt(o++)];
79 | while (o < t && a == -1);
80 | if (a == -1) break;
81 | d += String.fromCharCode(r << 2 | (48 & a) >> 4);
82 | do {
83 | if (c = 255 & e.charCodeAt(o++), 61 == c) return d;
84 | c = base64DecodeChars[c]
85 | } while (o < t && c == -1);
86 | if (c == -1) break;
87 | d += String.fromCharCode((15 & a) << 4 | (60 & c) >> 2);
88 | do {
89 | if (h = 255 & e.charCodeAt(o++), 61 == h) return d;
90 | h = base64DecodeChars[h]
91 | } while (o < t && h == -1);
92 | if (h == -1) break;
93 | d += String.fromCharCode((3 & c) << 6 | h)
94 | }
95 | return d
96 | }
97 | var hexToBytes = function (hex) {
98 | for (var bytes = [], c = 0; c < hex.length; c += 2)
99 | bytes.push(parseInt(hex.substr(c, 2), 16));
100 | return bytes;
101 | }
102 | var bytesToHex = function (bytes) {
103 | for (var hex = [], i = 0; i < bytes.length; i++) {
104 | hex.push((bytes[i] >>> 4).toString(16));
105 | hex.push((bytes[i] & 0xF).toString(16));
106 | }
107 | return hex.join("");
108 | }
109 | var bytesToString = function (arr) {
110 | var str = "";
111 | arr = new Uint8Array(arr);
112 | for (i in arr) {
113 | str += String.fromCharCode(arr[i]);
114 | }
115 | return str;
116 | }
117 | var stringToBytes = function (str) {
118 | var ch, st, re = [];
119 | for (var i = 0; i < str.length; i++) {
120 | ch = str.charCodeAt(i);
121 | st = [];
122 | do {
123 | st.push(ch & 0xFF);
124 | ch = ch >> 8;
125 | }
126 | while (ch);
127 | re = re.concat(st.reverse())
128 | }
129 | return re;
130 | }
131 | var bytesToBase64 = function (bytes) {
132 |
133 | // Use browser-native function if it exists
134 | // if (typeof btoa == "function") return btoa(bytesToString(bytes));
135 |
136 | for (var base64 = [], i = 0; i < bytes.length; i += 3) {
137 | var triplet = (bytes[i] << 16) | (bytes[i + 1] << 8) | bytes[i + 2];
138 | for (var j = 0; j < 4; j++) {
139 | if (i * 8 + j * 6 <= bytes.length * 8)
140 | base64.push(base64EncodeChars.charAt((triplet >>> 6 * (3 - j)) & 0x3F));
141 | else base64.push("=");
142 | }
143 | }
144 | return base64.join("");
145 | }
146 | var base64ToBytes = function (base64) {
147 |
148 | // Use browser-native function if it exists
149 | // if (typeof atob == "function") return stringToBytes(atob(base64));
150 |
151 | // Remove non-base-64 characters
152 | base64 = base64.replace(/[^A-Z0-9+\/]/ig, "");
153 |
154 | for (var bytes = [], i = 0, imod4 = 0; i < base64.length; imod4 = ++i % 4) {
155 | if (imod4 == 0) continue;
156 | bytes.push(((base64EncodeChars.indexOf(base64.charAt(i - 1)) & (Math.pow(2, -2 * imod4 + 8) - 1)) << (imod4 * 2)) |
157 | (base64EncodeChars.indexOf(base64.charAt(i)) >>> (6 - imod4 * 2)));
158 | }
159 |
160 | return bytes;
161 |
162 | }
163 | var hexToString = function (hex) {
164 | var arr = hex.split("")
165 | var out = ""
166 | for (var i = 0; i < arr.length / 2; i++) {
167 | var tmp = "0x" + arr[i * 2] + arr[i * 2 + 1]
168 | var charValue = String.fromCharCode(tmp);
169 | out += charValue
170 | }
171 | return out
172 | }
173 | var stringToHex = function (str) {
174 | var val = "";
175 | for (var i = 0; i < str.length; i++) {
176 | if (val == "")
177 | val = str.charCodeAt(i).toString(16);
178 | else
179 | val += str.charCodeAt(i).toString(16);
180 | }
181 | val += "0a"
182 | return val
183 | }
184 | var hexToBase64 = function (str) {
185 | return base64encode(String.fromCharCode.apply(null, str.replace(/\r|\n/g, "").replace(/([\da-fA-F]{2}) ?/g, "0x$1 ").replace(/ +$/, "").split(" ")));
186 | }
187 | var base64ToHex = function (str) {
188 | for (var i = 0,
189 | bin = base64decode(str.replace(/[ \r\n]+$/, "")), hex = []; i < bin.length; ++i) {
190 | var tmp = bin.charCodeAt(i).toString(16);
191 | if (tmp.length === 1) tmp = "0" + tmp;
192 | hex[hex.length] = tmp;
193 | }
194 | return hex.join("");
195 | };
196 |
197 | let ddns = {};
198 | ddns.owner = getArgs().owner;
199 | ddns.token = getArgs().token;
200 | ddns.repo = getArgs().repo;
201 | ddns.branch = getArgs().branch;
202 | ddns.filePath = getArgs().filePath;
203 | ddns.fileName = getArgs().fileName;
204 | ddns.commitMessage = "Auto update";
205 |
206 | (async function() {
207 | console.log("等待 1 分钟后运行脚本..."); //防止网络更换脚本识别错误
208 | await new Promise(resolve => setTimeout(resolve, 60000));
209 | console.log("开始运行脚本...");
210 | await Promise.all([
211 | getV4(), //如果没有公网v4不要执行此条,因为api能获取到公网IP但你没有。surge连接此地址不通。直接使用ddns.v4 = null
212 | getV6(), //有公网v6。这里v6可以直接使用$network.v6.primaryAddress。不用api请求更快更准。没有公网v6使用ddns.v6 = null
213 | getSha()
214 | ]);
215 | ddns.fileContent = ddns.v4 + ';' + ddns.v6 + ';'
216 | ddns.hexContent = stringToHex(ddns.fileContent);
217 | ddns.base64Content = hexToBase64(ddns.hexContent);
218 | console.log(ddns.base64Content)
219 | await commit();
220 | $done();
221 | })();
222 |
223 | // get public ip
224 | function getV4() {
225 | return new Promise(function(resolve) {
226 | $httpClient.get('https://api.ipify.org', function(error,head,data) {
227 | ddns.v4 = data
228 | console.log(ddns.v4)
229 | resolve()
230 | })
231 | });
232 | }
233 |
234 | function getV6() {
235 | return new Promise(function(resolve) {
236 | $httpClient.get('https://api64.ipify.org', function(error,head,data) {
237 | ddns.v6 = data
238 | console.log(ddns.v6)
239 | resolve()
240 | })
241 | });
242 | }
243 |
244 | //获取文件sha值
245 | function getSha() {
246 | return new Promise(function(resolve) {
247 | $httpClient.get({
248 | url: `https://api.github.com/repos/${ddns.owner}/${ddns.repo}/contents/${ddns.fileName}`,
249 | headers: {
250 | "Authorization": 'token ' + ddns.token
251 | }},
252 | function(error,headers,resp) {
253 | let jsonResp = JSON.parse(resp)
254 | ddns.sha = jsonResp.sha
255 | resolve()
256 | }
257 | );
258 | })
259 | }
260 |
261 | //commit message
262 | function commit() {
263 | const body = {
264 | message: ddns.commitMessage,
265 | content: ddns.base64Content,
266 | branch: ddns.branch,
267 | sha: ddns.sha,
268 | };
269 | return new Promise(function(resolve) {
270 | $httpClient.put({
271 | url: `https://api.github.com/repos/${ddns.owner}/${ddns.repo}/contents/${ddns.fileName}`,
272 | headers: {
273 | "Authorization": 'token ' + ddns.token
274 | },
275 | body: body},
276 | function(error,headers,resp) {
277 | console.log(headers.status)
278 | console.log(resp)
279 | if (headers.status === 200 || headers.status === 201) {
280 | $notification.post('Commit DDNS IP','文件上传/修改成功!',''),
281 | console.log("文件修改成功!");
282 | resolve();
283 | } else {
284 | console.log("文件修改失败!");
285 | console.log(error)
286 | resolve();
287 | }
288 | },
289 | );
290 | })
291 | }
--------------------------------------------------------------------------------
| |