-
Notifications
You must be signed in to change notification settings - Fork 0
/
nf_autoselect.js
288 lines (234 loc) · 7.81 KB
/
nf_autoselect.js
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
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
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
/* 脚本经本人测试已经可以正常运行,但仍可能存在bug,使用过程中遇到障碍请联系Telegram:https://t.me/okmytg
脚本说明:
1:本脚本修改自 @Helge_0x00
2:panel脚本依赖cron脚本传送数据,你应当手动运行一次cron脚本以获取节点列表
3:为了节省效能,请尽量精简策略组
4:点击panel时切换至下一个可解锁节点,节点列表为空时,仅执行状态检测
5:panel脚本允许自动更新,自动更新将刷新策略组信息,并可以自动选择更优选项
6:检测数据有一定概率会出错,且网飞数据会有所变动,因此你可能遇到切换至非全解锁节点,此时切换至下一个即可,毕竟这是概率较小的事件,大部分检测都是正确的,亦可手动执行一次cron脚本,节点列表将得到更新与修正
6:可用的自定义参数:
icon1 color1:全解锁时的图标及颜色
icon2 color2:仅自制时的图标及颜色
icon3 color3:无可用节点的图标及颜色
netflixGroup:网飞策略组名称
*/
const FILM_ID = 81215567
const AREA_TEST_FILM_ID = 80018499
let params = getParams($argument)
;(async () => {
let netflixGroup = params.netflixGroup
//将策略组名称创建为持久化数据
$persistentStore.write(netflixGroup,"NFGroupName");
let proxy = await httpAPI("/v1/policy_groups");
let groupName = (await httpAPI("/v1/policy_groups/select?group_name="+encodeURIComponent(netflixGroup)+"")).policy;
let first = groupName;
var proxyName= [];//netflix节点组名称
let arr = proxy[""+netflixGroup+""];
for (let i = 0; i < arr.length; ++i) {
proxyName.push(arr[i].name);
}
let allGroup = [];
for (var key in proxy){
allGroup.push(key)
}
var fullUnlock=[];
var onlyOriginal=[];
//读取持久化数据
fullUnlock = $persistentStore.read("fullUnlockNetflix").split(",");
onlyOriginal= $persistentStore.read("onlyOriginalNetflix").split(",");
//打印测试结果
console.log("全解锁:"+fullUnlock.sort())
console.log("仅自制:"+onlyOriginal.sort())
/**
* 过滤选择列表
*/
//删除策略组外节点并更新持久化数据
var select=[];
//清除空值
if(fullUnlock.toString().length==0){
fullUnlock.splice(fullUnlock.indexOf(fullUnlock[0]), 1)
}
if(onlyOriginal.toString().length==0){
onlyOriginal.splice(onlyOriginal.indexOf(onlyOriginal[0]), 1)
}
console.log(fullUnlock.length+" | "+ onlyOriginal.length)
if(fullUnlock.length>0){
for (let i = 0; i < fullUnlock.length; ++i) {
if(proxyName.includes(fullUnlock[i])==false){
fullUnlock.splice(fullUnlock.indexOf(fullUnlock[i]), 1)
}
}
select = fullUnlock
$persistentStore.write(select.sort().toString(),"fullUnlockNetflix");
}else if(fullUnlock.length==0&&onlyOriginal.length>0){
for (let i = 0; i < onlyOriginal.length; ++i) {
if(proxyName.includes(onlyOriginal[i])==false){
onlyOriginal.splice(onlyOriginal.indexOf(onlyOriginal[i]), 1)
}
}
select = onlyOriginal
$persistentStore.write(select.sort().toString(),"onlyOriginalNetflix")
}
console.log("选择列表:"+select.sort())
//手动切换
if($trigger == "button"){
//当前节点
groupName = (await httpAPI("/v1/policy_groups/select?group_name="+encodeURIComponent(netflixGroup)+"")).policy;
console.log("当前节点:"+groupName)
let index = select.indexOf(groupName)+1;
if(index>=select.length){
index=0
}
console.log("目标节点:"+ select[index])
$surge.setSelectGroupPolicy(netflixGroup, select[index]);
await timeout(1000).catch(() => {})
}
/**
* 自动刷新
*/
/* 检查选择列表 */
console.log(select.length)
if(select.length==0){
$notification.post("节点列表获取失败", "未获取到节点列表,请手动运行一次NetflixChecker脚本", "")
}
//测试当前选择
//当前节点
groupName = (await httpAPI("/v1/policy_groups/select?group_name="+encodeURIComponent(netflixGroup)+"")).policy;
console.log("当前节点:"+groupName)
let { status, regionCode, policyName } = await testPolicy(groupName);
let newStatus=status
let reg = regionCode
console.log("节点状态:"+status)
//当前节点不可全解锁时,执行自动切换,若列表为空,仅执行测试
if(status!= 2){
if(select.length>0){
//遍历选择列表,找到第一个更优节点
for (let i = 0; i < select.length; ++i) {
$surge.setSelectGroupPolicy(netflixGroup, select[i]);
await timeout(1000).catch(() => {})
groupName = (await httpAPI("/v1/policy_groups/select?group_name="+encodeURIComponent(netflixGroup)+"")).policy;
console.log("当前节点:"+groupName)
let { status, regionCode, policyName } = await testPolicy(groupName);
console.log("节点状态:"+status)
if(status>newStatus){
newStatus=status
reg = regionCode
break;
}
}
}else {
groupName = (await httpAPI("/v1/policy_groups/select?group_name="+encodeURIComponent(netflixGroup)+"")).policy;
console.log("当前节点:"+groupName)
let { status, regionCode, policyName } = await testPolicy(groupName);
console.log("节点状态:"+status)
newStatus=status
reg = regionCode
}
}
status=newStatus
regionCode=reg
//获取根节点名
let rootName = (await httpAPI("/v1/policy_groups/select?group_name="+encodeURIComponent(netflixGroup)+"")).policy;
while(allGroup.includes(rootName)==true){
rootName = (await httpAPI("/v1/policy_groups/select?group_name="+encodeURIComponent(rootName)+"")).policy;
}
/**
* 面板显示
*/
let title = "Netflix ➟ " + rootName;
let panel = {
title: `${title}`,
}
if (status==2) {
panel['content'] = `已完整解锁Netflix 区域:${regionCode}`
panel['icon'] = params.icon1
panel['icon-color'] = params.color1
} else if (status==1) {
panel['content'] = `仅解锁Netflix自制剧`
panel['icon'] = params.icon2
panel['icon-color'] = params.color2
}else {
$surge.setSelectGroupPolicy(netflixGroup, first);
panel['content'] = `该节点未解锁Netflix`
panel['icon'] = params.icon3
panel['icon-color'] = params.color3
return
}
console.log(panel)
$done(panel)
})();
function httpAPI(path = "", method = "GET", body = null) {
return new Promise((resolve) => {
$httpAPI(method, path, body, (result) => {
resolve(result);
});
});
};
async function testPolicy(policyName) {
try {
const regionCode = await Promise.race([testFilm(FILM_ID), timeout(3000)])
return { status: 2, regionCode, policyName }
} catch (error) {
if (error === 'Not Found') {
return { status: 1, policyName }
}
if (error === 'Not Available') {
return { status: 0, policyName }
}
console.log(error)
return { status: -1, policyName }
}
}
/**
* 测试是否解锁
*/
function testFilm(filmId) {
return new Promise((resolve, reject) => {
let option = {
url: `https://www.netflix.com/title/${filmId}`,
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',
},
}
$httpClient.get(option, function (error, response, data) {
if (error != null) {
reject(error)
return
}
if (response.status === 403) {
reject('Not Available')
return
}
if (response.status === 404) {
reject('Not Found')
return
}
if (response.status === 200) {
let url = response.headers['x-originating-url']
let region = url.split('/')[3]
region = region.split('-')[0]
if (region == 'title') {
region = 'us'
}
resolve(region.toUpperCase())
return
}
reject('Error')
})
})
}
function timeout(delay = 5000) {
return new Promise((resolve, reject) => {
setTimeout(() => {
reject('Timeout')
}, delay)
})
}
function getParams(param) {
return Object.fromEntries(
$argument
.split("&")
.map((item) => item.split("="))
.map(([k, v]) => [k, decodeURIComponent(v)])
);
}