diff --git a/JSBox/Rules-lhie1.box b/JSBox/Rules-lhie1.box deleted file mode 100644 index cd38bce..0000000 Binary files a/JSBox/Rules-lhie1.box and /dev/null differ diff --git a/JSBox/Rules-lhie1/README.md b/JSBox/Rules-lhie1/README.md deleted file mode 100644 index f417cbb..0000000 --- a/JSBox/Rules-lhie1/README.md +++ /dev/null @@ -1,30 +0,0 @@ -## lhie1规则生成 - -### 简介 -经过一周的迭代更新,目前脚本已经可以完全替代Workflow甚至能做到Workflow不能做到的如: -1. 由于没有运行动画,生成速度快 -2. 能自由对节点进行排序和筛选等操作 -3. 提供小组件支持,可以快速判断规则是否有更新并快速生成一次配置 -4. 提供Safari拓展支持,可以像Surge3一样在浏览网页时添加对应的规则 -5. 能识别批量ss://或surge链接 -6. 支持URL Scheme一键生成配置文件 - -更多介绍请参考: - -[Rules-lhie1脚本简介](https://github.com/Fndroid/jsbox_script/blob/master/Rules-lhie1/docs.md) - - -[Rules-lhie1脚本更新日志](https://github.com/Fndroid/jsbox_script/blob/master/Rules-lhie1/updateLog.md) - -[打赏名单](https://github.com/Fndroid/jsbox_script/blob/master/Rules-lhie1/donate.md) - -### 界面截图 - -![](https://github.com/Fndroid/jsbox_script/blob/master/imgs/Rules-lhie1_pre6.png?raw=true) - -### 下载脚本 - -[下载Rules-lhie1](https://xteko.com/redir?name=Rules-lhie1&url=https://raw.githubusercontent.com/Fndroid/jsbox_script/master/Rules-lhie1/.output/Rules-lhie1.box) - -### 感谢支持 -![](https://raw.githubusercontent.com/Fndroid/jsbox_script/master/imgs/thankyou.jpg) \ No newline at end of file diff --git a/JSBox/Rules-lhie1/assets/balloons.json b/JSBox/Rules-lhie1/assets/balloons.json deleted file mode 100644 index 0ed2b5a..0000000 --- a/JSBox/Rules-lhie1/assets/balloons.json +++ /dev/null @@ -1 +0,0 @@ -{"v":"5.1.1","fr":60,"ip":0,"op":600,"w":1440,"h":2560,"nm":"Balloon Animation","ddd":0,"assets":[],"layers":[{"ddd":0,"ind":1,"ty":4,"nm":"pinkBalloon ","sr":1,"ks":{"o":{"a":0,"k":70,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.833,"y":0.852},"o":{"x":0.167,"y":0.151},"n":"0p833_0p852_0p167_0p151","t":52,"s":[856,3484.5,0],"e":[875.959,-515.333,0],"to":[3.32643795013428,-666.638854980469,0],"ti":[-3.32643795013428,666.638854980469,0]},{"t":350}],"ix":2},"a":{"a":0,"k":[400.438,352.479,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":2,"ty":"el","s":{"a":0,"k":[177.031,247.812],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ind":1,"ty":"sh","ix":2,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0],[0,0]],"v":[[10.025,120.696],[12.355,149.564],[2.966,147.251],[-7.063,148.633],[-4.733,120.696]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[1,0,0.465349324544,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[400.437,338.703],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[128.744,107.385],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":80,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":4,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":600,"st":0,"bm":0},{"ddd":0,"ind":2,"ty":4,"nm":"greenBalloon 4","sr":1,"ks":{"o":{"a":0,"k":70,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.833,"y":0.829},"o":{"x":0.167,"y":0.173},"n":"0p833_0p829_0p167_0p173","t":52,"s":[56,3300.5,0],"e":[315.448,-162.334,0],"to":[43.2412719726562,-577.138977050781,0],"ti":[-43.2412719726562,577.138977050781,0]},{"t":350}],"ix":2},"a":{"a":0,"k":[400.438,352.479,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":2,"ty":"el","s":{"a":0,"k":[177.031,247.812],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ind":1,"ty":"sh","ix":2,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0],[0,0]],"v":[[10.025,120.696],[12.355,149.564],[2.966,147.251],[-7.063,148.633],[-4.733,120.696]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0,1,0.528860234279,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[400.437,338.703],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[128.744,107.385],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":80,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":4,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":600,"st":0,"bm":0},{"ddd":0,"ind":3,"ty":4,"nm":"greenBalloon 3","sr":1,"ks":{"o":{"a":0,"k":70,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.833,"y":0.851},"o":{"x":0.167,"y":0.16},"n":"0p833_0p851_0p167_0p16","t":148,"s":[1240,2924.5,0],"e":[1275.959,-478.276,0],"to":[5.99310493469238,-567.12939453125,0],"ti":[-5.99310493469238,567.12939453125,0]},{"t":402}],"ix":2},"a":{"a":0,"k":[400.438,352.479,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":2,"ty":"el","s":{"a":0,"k":[177.031,247.812],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ind":1,"ty":"sh","ix":2,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0],[0,0]],"v":[[10.025,120.696],[12.355,149.564],[2.966,147.251],[-7.063,148.633],[-4.733,120.696]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0,1,0.528860234279,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[400.437,338.703],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[128.744,107.385],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":80,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":4,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":600,"st":0,"bm":0},{"ddd":0,"ind":4,"ty":4,"nm":"greenBalloon 2","sr":1,"ks":{"o":{"a":0,"k":70,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.833,"y":0.834},"o":{"x":0.167,"y":0.167},"n":"0p833_0p834_0p167_0p167","t":0,"s":[198,2837.667,0],"e":[762,-368.5,0],"to":[94,-534.361145019531,0],"ti":[-94,534.361145019531,0]},{"t":271}],"ix":2},"a":{"a":0,"k":[400.438,352.479,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":2,"ty":"el","s":{"a":0,"k":[177.031,247.812],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ind":1,"ty":"sh","ix":2,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0],[0,0]],"v":[[10.025,120.696],[12.355,149.564],[2.966,147.251],[-7.063,148.633],[-4.733,120.696]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0,1,0.528860234279,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[400.437,338.703],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[128.744,107.385],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":80,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":4,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":600,"st":0,"bm":0},{"ddd":0,"ind":5,"ty":4,"nm":"blueBalloon","sr":1,"ks":{"o":{"a":0,"k":70,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.833,"y":0.83},"o":{"x":0.167,"y":0.198},"n":"0p833_0p83_0p167_0p198","t":23,"s":[1235.406,3127.833,0],"e":[761.634,-588.86,0],"to":[-78.9620056152344,-619.448791503906,0],"ti":[78.9620056152344,619.448791503906,0]},{"t":344}],"ix":2},"a":{"a":0,"k":[400.438,352.479,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":2,"ty":"el","s":{"a":0,"k":[177.031,247.812],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ind":1,"ty":"sh","ix":2,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0],[0,0]],"v":[[10.025,120.696],[12.355,149.564],[2.966,147.251],[-7.063,148.633],[-4.733,120.696]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0,0.46011020436,1,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[400.437,338.703],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[128.744,107.385],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":80,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":4,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":600,"st":0,"bm":0},{"ddd":0,"ind":6,"ty":4,"nm":"yellowBalloon","sr":1,"ks":{"o":{"a":0,"k":70,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.833,"y":0.856},"o":{"x":0.167,"y":0.167},"n":"0p833_0p856_0p167_0p167","t":0,"s":[1235.406,3127.833,0],"e":[1211.959,-627.333,0],"to":[-3.90793800354004,-625.861022949219,0],"ti":[3.90793800354004,625.861022949219,0]},{"t":271}],"ix":2},"a":{"a":0,"k":[400.438,352.479,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":2,"ty":"el","s":{"a":0,"k":[177.031,247.812],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ind":1,"ty":"sh","ix":2,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0],[0,0]],"v":[[10.025,120.696],[12.355,149.564],[2.966,147.251],[-7.063,148.633],[-4.733,120.696]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[1,0.987591911765,0,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[400.437,338.703],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[128.744,107.385],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":80,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":4,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":600,"st":0,"bm":0},{"ddd":0,"ind":7,"ty":4,"nm":"purpleBalloon","sr":1,"ks":{"o":{"a":0,"k":70,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.833,"y":0.845},"o":{"x":0.167,"y":0.167},"n":"0p833_0p845_0p167_0p167","t":0,"s":[776,3020.5,0],"e":[539.959,-454.276,0],"to":[-39.3402290344238,-579.12939453125,0],"ti":[39.3402290344238,579.12939453125,0]},{"t":271}],"ix":2},"a":{"a":0,"k":[400.438,352.479,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":2,"ty":"el","s":{"a":0,"k":[177.031,247.812],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ind":1,"ty":"sh","ix":2,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0],[0,0]],"v":[[10.025,120.696],[12.355,149.564],[2.966,147.251],[-7.063,148.633],[-4.733,120.696]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.462959289551,0,1,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[400.437,338.703],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[128.744,107.385],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":80,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":4,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":600,"st":0,"bm":0},{"ddd":0,"ind":8,"ty":4,"nm":"blueBallloon","sr":1,"ks":{"o":{"a":0,"k":70,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.833,"y":0.863},"o":{"x":0.167,"y":0.134},"n":"0p833_0p863_0p167_0p134","t":106,"s":[512,2724.5,0],"e":[1162,-464.5,0],"to":[108.333335876465,-531.5,0],"ti":[-108.333335876465,531.5,0]},{"t":330}],"ix":2},"a":{"a":0,"k":[400.438,352.479,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":2,"ty":"el","s":{"a":0,"k":[177.031,247.812],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ind":1,"ty":"sh","ix":2,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0],[0,0]],"v":[[10.025,120.696],[12.355,149.564],[2.966,147.251],[-7.063,148.633],[-4.733,120.696]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0,0.721047674441,1,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[400.437,338.703],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[128.744,107.385],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":80,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":4,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":600,"st":0,"bm":0},{"ddd":0,"ind":9,"ty":4,"nm":"blueBalloon","sr":1,"ks":{"o":{"a":0,"k":70,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.833,"y":0.869},"o":{"x":0.167,"y":0.128},"n":"0p833_0p869_0p167_0p128","t":191,"s":[1232,2996.5,0],"e":[831.959,-273.776,0],"to":[-60.6597709655762,-578.37939453125,0],"ti":[66.6735610961914,545.046020507812,0]},{"t":408}],"ix":2},"a":{"a":0,"k":[400.438,352.479,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":2,"ty":"el","s":{"a":0,"k":[177.031,247.812],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ind":1,"ty":"sh","ix":2,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0],[0,0]],"v":[[10.025,120.696],[12.355,149.564],[2.966,147.251],[-7.063,148.633],[-4.733,120.696]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0,0.497150914809,1,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[400.437,338.703],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[128.744,107.385],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":80,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":4,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":600,"st":0,"bm":0},{"ddd":0,"ind":10,"ty":4,"nm":"redBallloon","sr":1,"ks":{"o":{"a":0,"k":70,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.833,"y":0.885},"o":{"x":0.167,"y":0.112},"n":"0p833_0p885_0p167_0p112","t":191,"s":[848,3476.5,0],"e":[604.041,-273.776,0],"to":[-60.6597709655762,-578.37939453125,0],"ti":[40.6597709655762,625.046020507812,0]},{"t":408}],"ix":2},"a":{"a":0,"k":[400.438,352.479,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":2,"ty":"el","s":{"a":0,"k":[177.031,247.812],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ind":1,"ty":"sh","ix":2,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0],[0,0]],"v":[[10.025,120.696],[12.355,149.564],[2.966,147.251],[-7.063,148.633],[-4.733,120.696]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[1,0,0.392279561361,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[400.437,338.703],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[128.744,107.385],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":80,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":4,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":600,"st":0,"bm":0},{"ddd":0,"ind":11,"ty":4,"nm":"yellowBallloon 3","sr":1,"ks":{"o":{"a":0,"k":70,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.833,"y":0.877},"o":{"x":0.167,"y":0.121},"n":"0p833_0p877_0p167_0p121","t":191,"s":[272,3204.5,0],"e":[312.041,-293.667,0],"to":[6.67356204986572,-583.02783203125,0],"ti":[-6.67356204986572,583.02783203125,0]},{"t":408}],"ix":2},"a":{"a":0,"k":[400.438,352.479,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":2,"ty":"el","s":{"a":0,"k":[177.031,247.812],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ind":1,"ty":"sh","ix":2,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0],[0,0]],"v":[[10.025,120.696],[12.355,149.564],[2.966,147.251],[-7.063,148.633],[-4.733,120.696]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[1,0.949172794118,0,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[400.437,338.703],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[128.744,107.385],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":80,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":4,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":600,"st":0,"bm":0},{"ddd":0,"ind":12,"ty":4,"nm":"yellowBallloon 2","sr":1,"ks":{"o":{"a":0,"k":70,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.833,"y":0.841},"o":{"x":0.167,"y":0.156},"n":"0p833_0p841_0p167_0p156","t":121,"s":[512,2924.5,0],"e":[539.959,-454.276,0],"to":[4.65977144241333,-563.12939453125,0],"ti":[-4.65977144241333,563.12939453125,0]},{"t":391}],"ix":2},"a":{"a":0,"k":[400.438,352.479,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":2,"ty":"el","s":{"a":0,"k":[177.031,247.812],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ind":1,"ty":"sh","ix":2,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0],[0,0]],"v":[[10.025,120.696],[12.355,149.564],[2.966,147.251],[-7.063,148.633],[-4.733,120.696]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[1,0.949172794118,0,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[400.437,338.703],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[128.744,107.385],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":80,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":4,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":600,"st":0,"bm":0},{"ddd":0,"ind":13,"ty":4,"nm":"yellowBallloon","sr":1,"ks":{"o":{"a":0,"k":70,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.833,"y":0.863},"o":{"x":0.167,"y":0.134},"n":"0p833_0p863_0p167_0p134","t":106,"s":[1376,2804.5,0],"e":[312.041,-293.667,0],"to":[-177.326431274414,-516.361145019531,0],"ti":[177.326431274414,516.361145019531,0]},{"t":331}],"ix":2},"a":{"a":0,"k":[400.438,352.479,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":2,"ty":"el","s":{"a":0,"k":[177.031,247.812],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ind":1,"ty":"sh","ix":2,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0],[0,0]],"v":[[10.025,120.696],[12.355,149.564],[2.966,147.251],[-7.063,148.633],[-4.733,120.696]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[1,0.949172794118,0,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[400.437,338.703],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[128.744,107.385],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":80,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":4,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":600,"st":0,"bm":0},{"ddd":0,"ind":14,"ty":4,"nm":"redBalloonNew","sr":1,"ks":{"o":{"a":0,"k":70,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.833,"y":0.847},"o":{"x":0.167,"y":0.167},"n":"0p833_0p847_0p167_0p167","t":0,"s":[1016,2740.5,0],"e":[1098,-774.166,0],"to":[13.6666669845581,-585.777709960938,0],"ti":[-13.6666669845581,585.777709960938,0]},{"t":271}],"ix":2},"a":{"a":0,"k":[400.438,352.479,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":2,"ty":"el","s":{"a":0,"k":[177.031,247.812],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ind":1,"ty":"sh","ix":2,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0],[0,0]],"v":[[10.025,120.696],[12.355,149.564],[2.966,147.251],[-7.063,148.633],[-4.733,120.696]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[1,0,0.404779561361,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[400.437,338.703],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[128.744,107.385],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":80,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":4,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":600,"st":0,"bm":0},{"ddd":0,"ind":15,"ty":4,"nm":"greenBalloonNew","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":0,"s":[198,2984.5,0],"e":[718,-260,0],"to":[86.6666641235352,-540.75,0],"ti":[-86.6666641235352,540.75,0]},{"t":360}],"ix":2},"a":{"a":0,"k":[-100.906,408.167,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":2,"ty":"el","s":{"a":0,"k":[177.031,247.812],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ind":1,"ty":"sh","ix":2,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0],[0,0]],"v":[[10.025,120.696],[12.355,149.564],[2.966,147.251],[-7.063,148.633],[-4.733,120.696]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0,1,0.903125,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[-100.906,394.391],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[128.744,107.385],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":80,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":4,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":600,"st":0,"bm":0}],"markers":[]} \ No newline at end of file diff --git a/JSBox/Rules-lhie1/assets/close_icon.png b/JSBox/Rules-lhie1/assets/close_icon.png deleted file mode 100644 index 2805913..0000000 Binary files a/JSBox/Rules-lhie1/assets/close_icon.png and /dev/null differ diff --git a/JSBox/Rules-lhie1/assets/icon.png b/JSBox/Rules-lhie1/assets/icon.png deleted file mode 100644 index 13f1d40..0000000 Binary files a/JSBox/Rules-lhie1/assets/icon.png and /dev/null differ diff --git a/JSBox/Rules-lhie1/assets/menu_icon.png b/JSBox/Rules-lhie1/assets/menu_icon.png deleted file mode 100644 index 918e225..0000000 Binary files a/JSBox/Rules-lhie1/assets/menu_icon.png and /dev/null differ diff --git a/JSBox/Rules-lhie1/assets/new_rules_tag.png b/JSBox/Rules-lhie1/assets/new_rules_tag.png deleted file mode 100644 index a9555cb..0000000 Binary files a/JSBox/Rules-lhie1/assets/new_rules_tag.png and /dev/null differ diff --git a/JSBox/Rules-lhie1/assets/new_version_tag.png b/JSBox/Rules-lhie1/assets/new_version_tag.png deleted file mode 100644 index 9c7516b..0000000 Binary files a/JSBox/Rules-lhie1/assets/new_version_tag.png and /dev/null differ diff --git a/JSBox/Rules-lhie1/assets/selected_icon.png b/JSBox/Rules-lhie1/assets/selected_icon.png deleted file mode 100644 index 0f1342c..0000000 Binary files a/JSBox/Rules-lhie1/assets/selected_icon.png and /dev/null differ diff --git a/JSBox/Rules-lhie1/assets/thankyou.jpg b/JSBox/Rules-lhie1/assets/thankyou.jpg deleted file mode 100644 index 892823a..0000000 Binary files a/JSBox/Rules-lhie1/assets/thankyou.jpg and /dev/null differ diff --git a/JSBox/Rules-lhie1/assets/thankyou2.jpg b/JSBox/Rules-lhie1/assets/thankyou2.jpg deleted file mode 100644 index 2cd5c60..0000000 Binary files a/JSBox/Rules-lhie1/assets/thankyou2.jpg and /dev/null differ diff --git a/JSBox/Rules-lhie1/assets/today_jsbox.png b/JSBox/Rules-lhie1/assets/today_jsbox.png deleted file mode 100644 index 980e083..0000000 Binary files a/JSBox/Rules-lhie1/assets/today_jsbox.png and /dev/null differ diff --git a/JSBox/Rules-lhie1/assets/today_pull.png b/JSBox/Rules-lhie1/assets/today_pull.png deleted file mode 100644 index fc0f192..0000000 Binary files a/JSBox/Rules-lhie1/assets/today_pull.png and /dev/null differ diff --git a/JSBox/Rules-lhie1/assets/today_quan.png b/JSBox/Rules-lhie1/assets/today_quan.png deleted file mode 100644 index 6110aa3..0000000 Binary files a/JSBox/Rules-lhie1/assets/today_quan.png and /dev/null differ diff --git a/JSBox/Rules-lhie1/assets/today_quan_off.png b/JSBox/Rules-lhie1/assets/today_quan_off.png deleted file mode 100644 index 8c3cd5e..0000000 Binary files a/JSBox/Rules-lhie1/assets/today_quan_off.png and /dev/null differ diff --git a/JSBox/Rules-lhie1/assets/today_surge.png b/JSBox/Rules-lhie1/assets/today_surge.png deleted file mode 100644 index f74857f..0000000 Binary files a/JSBox/Rules-lhie1/assets/today_surge.png and /dev/null differ diff --git a/JSBox/Rules-lhie1/assets/today_surge2.png b/JSBox/Rules-lhie1/assets/today_surge2.png deleted file mode 100644 index dd8fd9c..0000000 Binary files a/JSBox/Rules-lhie1/assets/today_surge2.png and /dev/null differ diff --git a/JSBox/Rules-lhie1/assets/today_surge_off.png b/JSBox/Rules-lhie1/assets/today_surge_off.png deleted file mode 100644 index efe381f..0000000 Binary files a/JSBox/Rules-lhie1/assets/today_surge_off.png and /dev/null differ diff --git a/JSBox/Rules-lhie1/config.json b/JSBox/Rules-lhie1/config.json deleted file mode 100644 index e345a31..0000000 --- a/JSBox/Rules-lhie1/config.json +++ /dev/null @@ -1,22 +0,0 @@ -{ - "info": { - "name": "Rules-lhie1", - "url": "https://raw.githubusercontent.com/Fndroid/jsbox_script/master/Rules-lhie1/.output/Rules-lhie1.box", - "version": "1.8.1", - "author": "Fndroid", - "website": "https://github.com/Fndroid/jsbox_script/tree/master/Rules-lhie1", - "types": 15 - }, - "settings": { - "minSDKVer": "1.0.0", - "minOSVer": "10.0.0", - "idleTimerDisabled": false, - "autoKeyboardEnabled": false, - "keyboardToolbarEnabled": false, - "rotateDisabled": false - }, - "widget": { - "tintColor": "", - "iconColor": "" - } -} diff --git a/JSBox/Rules-lhie1/data.js b/JSBox/Rules-lhie1/data.js deleted file mode 100644 index d74b461..0000000 --- a/JSBox/Rules-lhie1/data.js +++ /dev/null @@ -1 +0,0 @@ -{"urls":[],"widgetSettings":"# 带流量信息的订阅或托管链接\r\n# 每行一个,格式为:name=url","generalSettings":"[General]\r\n// Auto\r\nloglevel = notify\r\ndns-server = system,1.2.4.8,223.5.5.5,223.6.6.6\r\nskip-proxy = 127.0.0.1,192.168.0.0/16,10.0.0.0/8,172.16.0.0/12,100.64.0.0/10,17.0.0.0/8,localhost,*.local,*.crashlytics.com\r\n\r\n// iOS\r\nexternal-controller-access = lhie1@0.0.0.0:6170\r\n\r\nallow-wifi-access = true\r\n\r\n// macOS\r\ninterface = 0.0.0.0\r\nsocks-interface = 0.0.0.0\r\nport = 8888\r\nsocks-port = 8889\r\n\r\nenhanced-mode-by-rule = false\r\nshow-error-page-for-reject = true\r\n\r\n// Auto\r\nexclude-simple-hostnames = true\r\nipv6 = true\r\nreplica = false\r\n\r\n[Replica]\r\nhide-apple-request = true\r\nhide-crashlytics-request = true\r\nhide-udp = false\r\nuse-keyword-filter = false","proxyGroupSettings":"[Proxy Group]\r\n🍃 Proxy = select,🏃 Auto,🚀 Direct,Proxy Header\r\n\r\n🍂 Domestic = select,🚀 Direct,🍃 Proxy\r\n\r\n🍎 Only = select,🚀 Direct,Proxy Header\r\n\r\n☁️ Others = select,🚀 Direct,🍃 Proxy\r\n\r\n🏃 Auto = url-test,ProxyHeader,url = http://www.gstatic.com/generate_204,interval = 1200","customSettings":"# Custom","hostSettings":"// custom host","urlrewriteSettings":"// custom url rewrite","ssidSettings":"// custom ssid","headerrewriteSettings":"// custom header rewrite","hostnameSettings":"","mitmSettings":"enable = true\r\nca-passphrase = 4B676386\r\nca-p12 = MIIJtAIBAzCCCX4GCSqGSIb3DQEHAaCCCW8EgglrMIIJZzCCA9cGCSqGSIb3DQEHBqCCA8gwggPEAgEAMIIDvQYJKoZIhvcNAQcBMBwGCiqGSIb3DQEMAQYwDgQI6Y6Nt7P0s1QCAggAgIIDkE4px9tUmX4zyAE2qK9f761b7vkat/g7X4gjWSPRtrdovsbnP05XaNdYF8sRn+GktrbqJ6m4LwPe1GUCDht8vuno76ZPAKdT5LVxAeKKJIz8+kqvdKh5COwMSHUD8SqJpncfiH90xu/HmzPbIPCKIE89ZWTRDECmJc9bwH97kefu+U/FB6suMVyEKD7oKhYcjY7110DLNe0okD+MMOLZkMv2DcPb/B9RqKCNAT86bFyF2jtsvyQ15WxkILb03R8Pal1LqkDD9P+r0tTjSRNLKKzWXK0blQeL3teZcusClXPUWo3wZZwNe+8kfUoe23vm62TjSIdYF0gi7G2wpoIIlSlijiPffFFfvG6FS2Y976uLPZb1MonWRdjBYYwry180YQJOyWZQQOR+lWj01lp9o5GaYLKNRNGfrGdsbHx/xKcYEX7Fo/SycUQhzvDh0YbgYz09VNVsbKQDRj0lnxYLnJTLVX0DMmNlWWT6qMwXJ7HLYVT8sgA51h/meUfHmpzI1Qv9k8T/KZQtcVpHSWZ2LXdmwwLJ1A4VgQWxPS7a2GisrYs8DJbDLqaCpRrCyTqpOUclvZ/ONFqiqvJNbuzg33clgutbQNIxoyqJ5A9VDvbKcwgEq91KdSfsQ1shpS/lxGNCsfF+kFcgD95YS2ZfQ5QoFMszoSMCIkz/juc0aLbrGehpmrtd+LGOjomE/y7m8zJ2AxBLQpKSICRu6Dcz0nC2Jgf25/NJlUuX4kIZJyz0MxBBNreUzcevpFIIgsUpwlYAKZKP01/clVV+mVyax49RRVZttMKTaLymSeKO0lGqi9xzbnd0TCtmzN6wp4UpwtISxqLju3fTcgiWnCYRiEY7JZcaAO02J8C8dRsGU1lOBJOJ6hksPwbJ6B52maLmF3cu7WBG5RAmx/MtvJrvzNZYAyord6jjThcfQp8bMv1evmo8BDDpQ6FQb6TR8W9GvLSH21iLbuRFygDnzkKQ+s+LyiO3G0LNseNLxILEcxBgSx0hzoh7/k/MVaO+p0w5csf+VIlOLcew+7Oen5KJFRXhcUDKR3Km7cdcOPv8M8lqvHeScfga6X+W83B+u1+fYhkE8rwlFPj/bUk11A+fbThnM6K069DMh8388S9Tz8otf7zKzad24mUHWSx37GJx1jg0T3dVHegx2JJ3iBLQlGXxF+JiXY/DEeT0VxXJZXt2QbPY9LQ3McIKngeHKpYh4zCCBYgGCSqGSIb3DQEHAaCCBXkEggV1MIIFcTCCBW0GCyqGSIb3DQEMCgECoIIE7jCCBOowHAYKKoZIhvcNAQwBAzAOBAgB2aT5GqvE2AICCAAEggTIPV10t7HrCN6H+dB2i0z4MuGWtSblZVax8UGxygolskl9x7ATpi5+Wo7CpW1EQljzCUmIWygajuqSwvywT5clhuXplenLIXMJcknaf/IjoqF847TY0qSvnOJm+ywoLZ8MhOjTjSNk2N6c+szhr46eSu+1AnMD/fGdh+Z/Xp0i3BdqD4DO+9r8fmjoJlQ1I6ieI6M0baQc/yVPYXJfwZPGYfB3BukXdq1TXtByuCowA8lezoiHQ8EtAongtN2mekiUtHtwK4qHqLqEdr15arht8cFQPXxsX/OE09D/UjzOu04goqEctIBofbUhRMfBprarMfa6qZcFf5saUT7OWk7uC+LcRXd0ZF9XqCTe87u7030jbIh3zuRAX64xbvsowrs8cxM1OaOeqW0Fr0XydsmoPg6r+XlXXyItZvSJllumJHoB2QcpQO03hrRcBuhm7PT5pBG36S4DxwDRBPxID+kWLzbDKJUvsxyX6FyRfn2pySX03w2GcPxlqCexkVHRYInL+MPEUJ8zPOfBx7GvpZStkadnoIo2Zf0t6miHYoxuw81IL6jBQpMaWwL1TMWnioisvoE3zn3oHCTLXWoLwUEKXNX0tQ7IokuXdG7abeD3iBRwXyX6q5jbeQ4PfLll9utT17YSswz2WDoX8fwyiiv+DEZgfWUA5Fc56eVX1w5JIUN/SnqfB1DLcXI4KzSlhZBk+P2MYHCZFTYiFEBYS+A5TPIdt4nhK8+LSA7PA9YyTNSBn09nRjMNtrfSvp5tL4DHkNOPsn4Uxtpl1PW1xxkbfWS3WK3LRAM84jTIE06pqpixSube62F/GqTi5DwyDOdobehgkfXxmQmjTKe4HvIXYC12Mfl9r5VY/gnVLNV0z5PoEA3ycRNWBhXL4BkRyQijZTLm7oH/xP+wWKdOimbJnxAzl8jhiTkJKZGSgj63pioTC60eyDQo8Dh6BdASuSnIdLoqDjB3vFA1Gbp9rOI7YLEYp0bXBzwdbsamasuQKN5juqzvOhmTIKTskx+IKUBRzZ1+5Zse5606PCKMOPyXYgkk42XfdZiyXcmLo/LvHWsxHYvsLspegLRJBDl+HREOzSKoT1FYW//twJaYh34928E1Ek5BeMUzRYrVJklPwAhUoUTpZuZE+kGdCqCBlTq2fN6CEcMB4t88TjGWDS1AGby9zQTK23NQkdTTx0sBnWZDecLAWk1xTdHxV/dvfnQGgByQKilmDf9meeRFFZn89uMX9SK3hhQ3bAh1Z4lTpqLYNyi7j3QSrhhn9ByLL8awH8Hn71EIRznw7mGGOIcyVKQQsE6Z7a7xMMKHhTvdjLwVpTsSLp46nTmBgk7AluBATeJM9FQpOrP142ZtHRifAFUSuhWLhBXYE+NYRaQT1VJQJU5FLadgUQzRGQuvi3dBkM6zXJapEB94OOvq1QjP6bt0SJXVW26+tqBS4tpcqUUJ5fTrfDzAX1ZuVbSSAQw73wNwSsd6OikYfIsg5jL+WnBMPOXnwTKdR3cUYynoqmbLf8A39m+EyRg5Z4kEZksxLxQ9oQH2O+XfgvFbRq9C/POwJV01knSRwjQCjvE6kr7bJSAF/DEekJMhP96ayZ1ZgzUDv+aazlPP2fLIjf4wYmg5h5+Et6GGMWwwIwYJKoZIhvcNAQkVMRYEFAk2eIvfMVYoZsDby30OzlTkJrwGMEUGCSqGSIb3DQEJFDE4HjYAUwB1AHIAZwBlACAARwBlAG4AZQByAGEAdABlAGQAIABDAEEAIAA0AEIANgA3ADYAMwA4ADYwLTAhMAkGBSsOAwIaBQAEFBY2VuZtNCmmQeiV3UDh7JuSWFqPBAj+OgUq8sPPwA==\r\n","workspace":{"fileName":"","serverData":[],"withEmoji":false,"usualData":[{"title":{"bgcolor":false,"text":"ADS","textColor":false}},{"title":{"bgcolor":false,"text":"MITM","textColor":false}},{"title":{"bgcolor":false,"text":"Emoji","textColor":false}},{"title":{"bgcolor":false,"text":"导出","textColor":false}}],"outputFormat":"Surge 3 TF","serverSuffix":"","deleteKeywords":"","customProxyGroup":{"ProxyHeader":[]}},"repoSha":{}} \ No newline at end of file diff --git a/JSBox/Rules-lhie1/defaultConf/customSettings b/JSBox/Rules-lhie1/defaultConf/customSettings deleted file mode 100644 index b55c643..0000000 --- a/JSBox/Rules-lhie1/defaultConf/customSettings +++ /dev/null @@ -1 +0,0 @@ -# Custom \ No newline at end of file diff --git a/JSBox/Rules-lhie1/defaultConf/generalSettings b/JSBox/Rules-lhie1/defaultConf/generalSettings deleted file mode 100644 index 9f60ea7..0000000 --- a/JSBox/Rules-lhie1/defaultConf/generalSettings +++ /dev/null @@ -1,30 +0,0 @@ -[General] -// Auto -loglevel = notify -dns-server = system,1.2.4.8,223.5.5.5,223.6.6.6 -skip-proxy = 127.0.0.1,192.168.0.0/16,10.0.0.0/8,172.16.0.0/12,100.64.0.0/10,17.0.0.0/8,localhost,*.local,*.crashlytics.com - -// iOS -external-controller-access = lhie1@0.0.0.0:6170 - -allow-wifi-access = true - -// macOS -interface = 0.0.0.0 -socks-interface = 0.0.0.0 -port = 8888 -socks-port = 8889 - -enhanced-mode-by-rule = false -show-error-page-for-reject = true - -// Auto -exclude-simple-hostnames = true -ipv6 = true -replica = false - -[Replica] -hide-apple-request = true -hide-crashlytics-request = true -hide-udp = false -use-keyword-filter = false \ No newline at end of file diff --git a/JSBox/Rules-lhie1/defaultConf/headerrewriteSettings b/JSBox/Rules-lhie1/defaultConf/headerrewriteSettings deleted file mode 100644 index 9785a7b..0000000 --- a/JSBox/Rules-lhie1/defaultConf/headerrewriteSettings +++ /dev/null @@ -1 +0,0 @@ -// custom header rewrite \ No newline at end of file diff --git a/JSBox/Rules-lhie1/defaultConf/hostSettings b/JSBox/Rules-lhie1/defaultConf/hostSettings deleted file mode 100644 index 9db2d42..0000000 --- a/JSBox/Rules-lhie1/defaultConf/hostSettings +++ /dev/null @@ -1 +0,0 @@ -// custom host \ No newline at end of file diff --git a/JSBox/Rules-lhie1/defaultConf/hostnameSettings b/JSBox/Rules-lhie1/defaultConf/hostnameSettings deleted file mode 100644 index e69de29..0000000 diff --git a/JSBox/Rules-lhie1/defaultConf/mitmSettings b/JSBox/Rules-lhie1/defaultConf/mitmSettings deleted file mode 100644 index a595a2d..0000000 --- a/JSBox/Rules-lhie1/defaultConf/mitmSettings +++ /dev/null @@ -1,3 +0,0 @@ -enable = true -ca-passphrase = 4B676386 -ca-p12 = MIIJtAIBAzCCCX4GCSqGSIb3DQEHAaCCCW8EgglrMIIJZzCCA9cGCSqGSIb3DQEHBqCCA8gwggPEAgEAMIIDvQYJKoZIhvcNAQcBMBwGCiqGSIb3DQEMAQYwDgQI6Y6Nt7P0s1QCAggAgIIDkE4px9tUmX4zyAE2qK9f761b7vkat/g7X4gjWSPRtrdovsbnP05XaNdYF8sRn+GktrbqJ6m4LwPe1GUCDht8vuno76ZPAKdT5LVxAeKKJIz8+kqvdKh5COwMSHUD8SqJpncfiH90xu/HmzPbIPCKIE89ZWTRDECmJc9bwH97kefu+U/FB6suMVyEKD7oKhYcjY7110DLNe0okD+MMOLZkMv2DcPb/B9RqKCNAT86bFyF2jtsvyQ15WxkILb03R8Pal1LqkDD9P+r0tTjSRNLKKzWXK0blQeL3teZcusClXPUWo3wZZwNe+8kfUoe23vm62TjSIdYF0gi7G2wpoIIlSlijiPffFFfvG6FS2Y976uLPZb1MonWRdjBYYwry180YQJOyWZQQOR+lWj01lp9o5GaYLKNRNGfrGdsbHx/xKcYEX7Fo/SycUQhzvDh0YbgYz09VNVsbKQDRj0lnxYLnJTLVX0DMmNlWWT6qMwXJ7HLYVT8sgA51h/meUfHmpzI1Qv9k8T/KZQtcVpHSWZ2LXdmwwLJ1A4VgQWxPS7a2GisrYs8DJbDLqaCpRrCyTqpOUclvZ/ONFqiqvJNbuzg33clgutbQNIxoyqJ5A9VDvbKcwgEq91KdSfsQ1shpS/lxGNCsfF+kFcgD95YS2ZfQ5QoFMszoSMCIkz/juc0aLbrGehpmrtd+LGOjomE/y7m8zJ2AxBLQpKSICRu6Dcz0nC2Jgf25/NJlUuX4kIZJyz0MxBBNreUzcevpFIIgsUpwlYAKZKP01/clVV+mVyax49RRVZttMKTaLymSeKO0lGqi9xzbnd0TCtmzN6wp4UpwtISxqLju3fTcgiWnCYRiEY7JZcaAO02J8C8dRsGU1lOBJOJ6hksPwbJ6B52maLmF3cu7WBG5RAmx/MtvJrvzNZYAyord6jjThcfQp8bMv1evmo8BDDpQ6FQb6TR8W9GvLSH21iLbuRFygDnzkKQ+s+LyiO3G0LNseNLxILEcxBgSx0hzoh7/k/MVaO+p0w5csf+VIlOLcew+7Oen5KJFRXhcUDKR3Km7cdcOPv8M8lqvHeScfga6X+W83B+u1+fYhkE8rwlFPj/bUk11A+fbThnM6K069DMh8388S9Tz8otf7zKzad24mUHWSx37GJx1jg0T3dVHegx2JJ3iBLQlGXxF+JiXY/DEeT0VxXJZXt2QbPY9LQ3McIKngeHKpYh4zCCBYgGCSqGSIb3DQEHAaCCBXkEggV1MIIFcTCCBW0GCyqGSIb3DQEMCgECoIIE7jCCBOowHAYKKoZIhvcNAQwBAzAOBAgB2aT5GqvE2AICCAAEggTIPV10t7HrCN6H+dB2i0z4MuGWtSblZVax8UGxygolskl9x7ATpi5+Wo7CpW1EQljzCUmIWygajuqSwvywT5clhuXplenLIXMJcknaf/IjoqF847TY0qSvnOJm+ywoLZ8MhOjTjSNk2N6c+szhr46eSu+1AnMD/fGdh+Z/Xp0i3BdqD4DO+9r8fmjoJlQ1I6ieI6M0baQc/yVPYXJfwZPGYfB3BukXdq1TXtByuCowA8lezoiHQ8EtAongtN2mekiUtHtwK4qHqLqEdr15arht8cFQPXxsX/OE09D/UjzOu04goqEctIBofbUhRMfBprarMfa6qZcFf5saUT7OWk7uC+LcRXd0ZF9XqCTe87u7030jbIh3zuRAX64xbvsowrs8cxM1OaOeqW0Fr0XydsmoPg6r+XlXXyItZvSJllumJHoB2QcpQO03hrRcBuhm7PT5pBG36S4DxwDRBPxID+kWLzbDKJUvsxyX6FyRfn2pySX03w2GcPxlqCexkVHRYInL+MPEUJ8zPOfBx7GvpZStkadnoIo2Zf0t6miHYoxuw81IL6jBQpMaWwL1TMWnioisvoE3zn3oHCTLXWoLwUEKXNX0tQ7IokuXdG7abeD3iBRwXyX6q5jbeQ4PfLll9utT17YSswz2WDoX8fwyiiv+DEZgfWUA5Fc56eVX1w5JIUN/SnqfB1DLcXI4KzSlhZBk+P2MYHCZFTYiFEBYS+A5TPIdt4nhK8+LSA7PA9YyTNSBn09nRjMNtrfSvp5tL4DHkNOPsn4Uxtpl1PW1xxkbfWS3WK3LRAM84jTIE06pqpixSube62F/GqTi5DwyDOdobehgkfXxmQmjTKe4HvIXYC12Mfl9r5VY/gnVLNV0z5PoEA3ycRNWBhXL4BkRyQijZTLm7oH/xP+wWKdOimbJnxAzl8jhiTkJKZGSgj63pioTC60eyDQo8Dh6BdASuSnIdLoqDjB3vFA1Gbp9rOI7YLEYp0bXBzwdbsamasuQKN5juqzvOhmTIKTskx+IKUBRzZ1+5Zse5606PCKMOPyXYgkk42XfdZiyXcmLo/LvHWsxHYvsLspegLRJBDl+HREOzSKoT1FYW//twJaYh34928E1Ek5BeMUzRYrVJklPwAhUoUTpZuZE+kGdCqCBlTq2fN6CEcMB4t88TjGWDS1AGby9zQTK23NQkdTTx0sBnWZDecLAWk1xTdHxV/dvfnQGgByQKilmDf9meeRFFZn89uMX9SK3hhQ3bAh1Z4lTpqLYNyi7j3QSrhhn9ByLL8awH8Hn71EIRznw7mGGOIcyVKQQsE6Z7a7xMMKHhTvdjLwVpTsSLp46nTmBgk7AluBATeJM9FQpOrP142ZtHRifAFUSuhWLhBXYE+NYRaQT1VJQJU5FLadgUQzRGQuvi3dBkM6zXJapEB94OOvq1QjP6bt0SJXVW26+tqBS4tpcqUUJ5fTrfDzAX1ZuVbSSAQw73wNwSsd6OikYfIsg5jL+WnBMPOXnwTKdR3cUYynoqmbLf8A39m+EyRg5Z4kEZksxLxQ9oQH2O+XfgvFbRq9C/POwJV01knSRwjQCjvE6kr7bJSAF/DEekJMhP96ayZ1ZgzUDv+aazlPP2fLIjf4wYmg5h5+Et6GGMWwwIwYJKoZIhvcNAQkVMRYEFAk2eIvfMVYoZsDby30OzlTkJrwGMEUGCSqGSIb3DQEJFDE4HjYAUwB1AHIAZwBlACAARwBlAG4AZQByAGEAdABlAGQAIABDAEEAIAA0AEIANgA3ADYAMwA4ADYwLTAhMAkGBSsOAwIaBQAEFBY2VuZtNCmmQeiV3UDh7JuSWFqPBAj+OgUq8sPPwA== diff --git a/JSBox/Rules-lhie1/defaultConf/proxyGroupSettings b/JSBox/Rules-lhie1/defaultConf/proxyGroupSettings deleted file mode 100644 index da8de48..0000000 --- a/JSBox/Rules-lhie1/defaultConf/proxyGroupSettings +++ /dev/null @@ -1,10 +0,0 @@ -[Proxy Group] -🍃 Proxy = select,🏃 Auto,🚀 Direct,Proxy Header - -🍂 Domestic = select,🚀 Direct,🍃 Proxy - -🍎 Only = select,🚀 Direct,Proxy Header - -☁️ Others = select,🚀 Direct,🍃 Proxy - -🏃 Auto = url-test,ProxyHeader,url = http://www.gstatic.com/generate_204,interval = 1200 \ No newline at end of file diff --git a/JSBox/Rules-lhie1/defaultConf/ssidSettings b/JSBox/Rules-lhie1/defaultConf/ssidSettings deleted file mode 100644 index 0b22e8b..0000000 --- a/JSBox/Rules-lhie1/defaultConf/ssidSettings +++ /dev/null @@ -1 +0,0 @@ -// custom ssid \ No newline at end of file diff --git a/JSBox/Rules-lhie1/defaultConf/urlrewriteSettings b/JSBox/Rules-lhie1/defaultConf/urlrewriteSettings deleted file mode 100644 index e164c55..0000000 --- a/JSBox/Rules-lhie1/defaultConf/urlrewriteSettings +++ /dev/null @@ -1 +0,0 @@ -// custom url rewrite \ No newline at end of file diff --git a/JSBox/Rules-lhie1/defaultConf/widgetSettings b/JSBox/Rules-lhie1/defaultConf/widgetSettings deleted file mode 100644 index 59c76be..0000000 --- a/JSBox/Rules-lhie1/defaultConf/widgetSettings +++ /dev/null @@ -1,2 +0,0 @@ -# 带流量信息的订阅或托管链接 -# 每行一个,格式为:name=url \ No newline at end of file diff --git a/JSBox/Rules-lhie1/docs.md b/JSBox/Rules-lhie1/docs.md deleted file mode 100644 index 5094ff2..0000000 --- a/JSBox/Rules-lhie1/docs.md +++ /dev/null @@ -1,60 +0,0 @@ -### Rules-lhie1脚本使用简介 - -#### 主界面名词 -- 去广告:加载去广告规则(现有总规则6000+) -- 开启MITM:不选中则不使用MITM证书,选中后默认使用lhie1的证书(CA 4B676386),可以在进阶设置中进行自定义 -- 节点后缀:用于在节点后添加UDP、TFO和插件等功能 -- 导出配置:采用Action Sheet将.conf配置文件导出,不打开则尝试直接导出配置文件到Surge 3 -- 进阶设置:可自行配置常规(General)、代理分组(Proxy Group)、代理规则(Custom Rule)、本地DNS映射(Host)、URL重定向(URL Rewrite)、Header修改(Header Rewrite)、SSID、主机名(Hostname)和配置根证书(MITM),也可一键还原全部进阶设置 -- 生成配置:拉取规则生成.conf配置文件 - -#### 节点导入编辑 -> 这是脚本的一个特点,可以对节点进行编辑筛选等操作。 - -- 导入、更新:可以通过剪贴板或二维码导入,支持``ss://链接``、``Surge链接``和``托管地址``,支持批量导入(每行一个) -- 倒序:将节点顺序颠倒,方便不同机场节点选择 -- 占位符:为策略组添加占位符,默认Auto组的占位符是ProxyHeader -- 特殊代理:节点左滑即可将节点设置为某些链接的特殊代理,按钮可以设置Direct、查看设置和清除特殊代理设置 -- 节点删除:在节点列表左滑选择删除 -- 节点重命名:节点列表左滑选择重命名(方便部分不带节点名节点改名) -- 节点排序:节点列表长按拖动即可调整顺序 - -#### 新手指导 -熟悉以上内容后,只需根据自己的需求,导入节点,在列表中选择测速节点,选中开关,拉取规则生成即可享受最新的lhie1规则,而且在托管没有发生变化的情况下,每次进入脚本都可以直接拉取生成最新规则不需要重新配置。 - -#### 进阶设置 -> 进阶设置配置完毕后即可自动保存 - -- 常规(General):常规配置内容,可以设置DNS、Replica等内容 -- 代理分组(Proxy Group):配置代理组内容,每个组别都可以通过``Proxy Header(有空格)``代表所有节点名,``ProxyHeader(无空格)``代替Auto节点名 -- 代理规则(Custom Rule):自定义规则配置,将需要添加的规则添加到规则的最上面,如果要删除lhie1的规则,在规则前添加``-``即可,添加的优先级较高 -- 本地DNS映射(Host):自定义本地DNS映射 -- URL重定向(URL Rewrite):自定义URL重定向 -- Header修改(Header Rewrite):自定义Header修改 -- SSID:自定义SSID -- 主机名(Hostname):自定义主机名 -- MITM:用于配置根证书,默认为lhie1的证书(CA 4B676386),也可自行配置 - -注: -1.以上进阶设置请在“知道自己在做什么”的情况下修改; -2.如果信息填错导致Surge无法启动,可以将对应部分清空保存即可自动恢复为默认,也可一键还原全部进阶设置。 - -#### JSBox小组件 -> 可在iOS的Widget页面中添加使用,使用前需先在JSBox的小组件设置中选中该脚本。小组件视图高度可考虑设置为120。 - -- Surge3启动/停止运行(红色Surge3图标):利用Surge3提供的URL Scheme,可做到Surge3一键启动/停止运行 -- 生成配置(绿色下载图标):一键生成配置,并根据个人脚本中的设置,自动执行导出到Surge3或者打开导出配置的系统选单 -- 打开脚本(蓝色JSBox图标):从小组件进到该JSBox脚本的主界面 - -> 当规则有更新时小组件会有角标提醒及更新内容提示 - -#### URL Scheme -脚本支持自动根据配置拉取最新规则,URL Scheme如下: -``` -jsbox://run?name=Rules-lhie1&auto=1 -``` - -#### 最后 -目前该JSBox脚本只支持生成Surge3的配置,生成配置的各项功能已经能替代大部分的Workflow的自定义功能。 - -如觉得这个脚本好用,愿意打赏,感激不尽。 diff --git a/JSBox/Rules-lhie1/donate.md b/JSBox/Rules-lhie1/donate.md deleted file mode 100644 index 1d29b5f..0000000 --- a/JSBox/Rules-lhie1/donate.md +++ /dev/null @@ -1 +0,0 @@ -感谢所有可爱的支持者! \ No newline at end of file diff --git a/JSBox/Rules-lhie1/main.js b/JSBox/Rules-lhie1/main.js deleted file mode 100644 index b8b37b3..0000000 --- a/JSBox/Rules-lhie1/main.js +++ /dev/null @@ -1,55 +0,0 @@ -console.clear() - -const app = require('scripts/app') -const init = require('scripts/init') -const today = require('scripts/today') -const extension = require('scripts/extension') -const updateUtil = require('scripts/updateUtil') -const siri = require('scripts/siri') - -$app.autoKeyboardEnabled = true -$app.rotateDisabled = true -$app.keyboardToolbarEnabled = true - -let query = $context.query - -$objc('notification').invoke('objectForKey') - -if (query.auto == 1) { - app.autoGen() - return -} - -if ($app.env === $env.today) { - today.renderTodayUI() - return -} else if ($app.env === $env.safari) { - extension.renderExtensionUI() - return -} else if ($app.env === $env.action) { - extension.collectRules() - return -} else if ($app.env === $env.siri) { - siri.renderSiriUI() - return -} - -app.setUpWorkspace() - -init.asyncInitialize() - -app.renderUI() - -updateUtil.getLatestVersion({ - handler: version => { - if (updateUtil.needUpdate(version, updateUtil.getCurVersion())) { - $http.get({ - url: 'https://raw.githubusercontent.com/Fndroid/jsbox_script/master/Rules-lhie1/updateLog.md' + '?t=' + new Date().getTime(), - handler: resp => { - updateUtil.updateScript(version) - } - }) - - } - } -}) diff --git a/JSBox/Rules-lhie1/restart.fndroid b/JSBox/Rules-lhie1/restart.fndroid deleted file mode 100644 index f32a580..0000000 --- a/JSBox/Rules-lhie1/restart.fndroid +++ /dev/null @@ -1 +0,0 @@ -true \ No newline at end of file diff --git a/JSBox/Rules-lhie1/scripts/app.js b/JSBox/Rules-lhie1/scripts/app.js deleted file mode 100644 index e90227e..0000000 --- a/JSBox/Rules-lhie1/scripts/app.js +++ /dev/null @@ -1,3010 +0,0 @@ -const proxyUtil = require('scripts/proxyUitl') -const updateUtil = require('scripts/updateUtil') -const cu = require('scripts/colorUtil') -const ruleUpdateUtil = require('scripts/ruleUpdateUtil') -const colorUtil = require('scripts/colorUtil') - -const FILE = 'data.js' -const PROXY_HEADER = 'ProxyHeader' - -const settingKeys = ['widgetSettings', 'generalSettings', 'proxyGroupSettings', 'customSettings', 'hostSettings', 'urlrewriteSettings', 'ssidSettings', 'headerrewriteSettings', 'hostnameSettings', 'mitmSettings'] - -if (!$file.exists(FILE)) { - $file.write({ - data: $data({ "string": JSON.stringify({ "urls": [] }) }), - path: FILE - }) -} - -String.prototype.reverse = function () { - return this.toString().split('').reverse().join('') -} - -String.prototype.contains = function (sub) { - return this.indexOf(sub) > -1 -} - -setDefaultSettings() - -let screenHeight = $device.info.screen.height -const screenWidth = $device.info.screen.width - -const iPhoneX = $device.isIphoneX -if (iPhoneX) { - screenHeight -= 48 -} - -const statusBarHeight = iPhoneX ? 44 : 20 -const navBarHeight = 45 - -const selectedColor = $color("#c1dcf0") -const btnOnFg = colorUtil.getColor("usualBtnOnFg") -const btnOnBg = colorUtil.getColor("usualBtnOnBg") -const btnOffFg = colorUtil.getColor("usualBtnOffFg") -const btnOffBg = colorUtil.getColor("usualBtnOffBg") - -function renderUI() { - $ui.render({ - props: { - title: "lhie1规则", - navBarHidden: true, - statusBarHidden: colorUtil.getColor("statusBar", true) === 'clear' ? true : false, - statusBarStyle: colorUtil.getColor("statusBar", true) === '#ffffff' ? 1 : 0, - id: "bodyView", - }, - events: { - appeared: function (sender) { - // $("bodyView").runtimeValue().$viewController().$navigationController().$interactivePopGestureRecognizer().$delegate() - // $("bodyView").runtimeValue().$viewController().$navigationController().$interactivePopGestureRecognizer().$setDelegate(null) - if (typeof $ui.window.next !== 'undefined') { - console.error('警告:正在调试模式运行,界面可能会被遮挡,请从JSBox主界面运行此脚本!') - $addin.restart() - } - } - }, - views: [{ - type: "view", - props: { - id: "navBar", - bgcolor: colorUtil.getColor("navBar") - }, - layout: (make, view) => { - make.height.equalTo(navBarHeight + statusBarHeight) - make.width.equalTo(view.super) - }, - views: [{ - type: "lottie", - props: { - id: "navLoadingIcon", - loop: false, - speed: 3, - src: "assets/balloons.json" - }, - layout: (make, view) => { - make.size.equalTo($size(screenWidth, screenHeight)) - make.bottom.equalTo(navBarHeight + statusBarHeight + 80) - // make.right.equalTo(view.prev.left).offset(-15) - // make.bottom.equalTo(view.super).offset(100) - } - }, { - type: "label", - props: { - text: "lhie1规则", - textColor: colorUtil.getColor("navTitleText"), - font: $font("bold", 25) - }, - layout: (make, view) => { - make.height.equalTo(navBarHeight) - make.top.equalTo(statusBarHeight) - make.left.equalTo(15) - } - }, { - type: "image", - props: { - icon: $icon("204", colorUtil.getColor("navIconRight"), $size(25, 25)), - bgcolor: $color("clear") - }, - layout: (make, view) => { - make.right.equalTo(view.super).offset(-15) - make.height.width.equalTo(25) - make.bottom.equalTo(view.super).offset(-10) - }, - events: { - tapped: sender => { - archivesHandler() - } - } - }, { - type: "image", - props: { - icon: $icon("074", colorUtil.getColor("navIconLeft"), $size(25, 25)), - bgcolor: $color("clear") - }, - layout: (make, view) => { - make.right.equalTo(view.prev.left).offset(-15) - make.height.width.equalTo(25) - make.bottom.equalTo(view.super).offset(-10) - }, - events: { - tapped: sender => { - // $clipboard.text = 'GxsAtS84U7' - // $app.openURL("alipay://") - // $app.openURL("https://qr.alipay.com/c1x047207ryk0wiaj6m6ye3") - $ui.alert({ - title: '感谢支持', - message: '作者投入大量时间和精力对脚本进行开发和完善,你愿意给他赏杯咖啡支持一下吗?', - actions: [{ - title: "支付宝", - handler: () => { - $app.openURL($qrcode.decode($file.read("assets/thankyou2.jpg").image)) - } - }, { - title: "微信", - handler: () => { - $quicklook.open({ - image: $file.read("assets/thankyou.jpg").image - }) - } - }, { - title: "返回" - }] - }) - } - } - },] - }, { - type: "view", - props: { - id: "mainView" - }, - layout: (make, view) => { - make.height.equalTo(view.super).offset(navBarHeight + statusBarHeight); - make.width.equalTo(view.super) - make.top.equalTo(navBarHeight + statusBarHeight) - }, - views: [{ - type: "input", - props: { - id: "fileName", - text: '', - placeholder: "配置名(lhie1)" - }, - layout: (make, view) => { - make.width.equalTo(view.super).offset(-120) - make.height.equalTo(40) - make.left.top.equalTo(10) - }, - events: { - changed: sender => { - saveWorkspace() - }, - returned: sender => { - sender.blur() - } - } - }, { - type: "button", - props: { - type: $btnType.contactAdd, - id: "serverURL", - titleColor: colorUtil.getColor("importBtnText"), - title: " 导入节点", - }, - layout: (make, view) => { - make.width.equalTo(100) - make.height.equalTo(40) - make.right.equalTo(-10) - make.top.equalTo(10) - }, - events: { - tapped: sender => { - importMenu({ - handler: nodeImportHandler - }) - } - } - }, { - type: "matrix", - props: { - id: "serverControl", - columns: 3, - scrollEnabled: false, - itemHeight: 40, - bgcolor: $color("#f0f5f5"), - data: genControlItems(), - template: [{ - type: "label", - props: { - id: "title", - align: $align.center, - font: $font(14), - textColor: colorUtil.getColor("controlBtnText"), - autoFontSize: true - }, - layout: $layout.fill - }], - info: {} - }, - layout: (make, view) => { - make.width.equalTo(view.super).offset(-20) - make.centerX.equalTo(view.super) - make.height.equalTo(40) - make.top.equalTo($("serverURL").bottom).offset(10) - }, - events: { - didSelect: (sender, indexPath, data) => { - let btnTitle = data.title.text - if (btnTitle === '节点倒序') { - reverseServerGroup() - } else if (btnTitle === '删除分组') { - deleteServerGroup() - } else if (btnTitle === '特殊代理') { - specialProxyGroup(); - } else { - groupShortcut() - } - } - } - }, { - type: "list", - props: { - id: "serverEditor", - data: [], - separatorHidden: true, - reorder: true, - actions: [{ - title: "delete", - handler: (sender, indexPath) => { - saveWorkspace() - } - }, { - title: "编辑", - color: $color("tint"), - handler: (sender, indexPath) => { - let od = sender.data - let section = od[indexPath.section] - let item = section.rows[indexPath.row] - showAlterDialog(section.title, item.proxyLink, (newSec, newLink) => { - item.proxyLink = newLink - item.proxyName.text = newLink.split(/\s*=/)[0] - section.rows[indexPath.row] = item - section.title = newSec - sender.data = formatListData(od) - saveWorkspace() - }) - } - }], - borderWidth: 2, - borderColor: $color("#f0f5f5"), - template: { - views: [{ - type: 'label', - props: { - id: 'proxyName', - align: $align.left, - line: 1, - textColor: colorUtil.getColor("editorItemText"), - font: $font(16), - }, - layout: (make, view) => { - make.width.equalTo(view.super).offset(-60) - make.height.equalTo(view.super) - make.left.equalTo(view.super).offset(15) - } - }, { - type: "image", - props: { - id: "proxyAuto", - icon: $icon("062", colorUtil.getColor("editorItemIcon"), $size(15, 15)), - bgcolor: $color("clear"), - hidden: true - }, - layout: (make, view) => { - make.right.equalTo(view.super).offset(-15) - make.size.equalTo($size(15, 15)) - make.centerY.equalTo(view.super) - } - }] - }, - // radius: 5 - }, - layout: (make, view) => { - make.width.equalTo(view.super).offset(-20) - make.centerX.equalTo(view.super) - make.height.equalTo(screenHeight - 330 - (typeof $ui.window.next !== 'undefined' ? 45 : 0)) - make.top.equalTo($("serverControl").bottom) - }, - events: { - didSelect: (sender, indexPath, data) => { - let proxyName = data.proxyName.text - let isSelected = !data.proxyAuto.hidden - let controlInfo = $("serverControl").info - let currentGroup = controlInfo.currentProxyGroup - let customProxyGroup = controlInfo.customProxyGroup || {} - if (isSelected) { - data.proxyAuto.hidden = true - customProxyGroup[currentGroup] = customProxyGroup[currentGroup].filter(i => i !== proxyName) - } else { - data.proxyAuto.hidden = false - customProxyGroup[currentGroup].push(proxyName) - } - let uiData = sender.data - uiData[indexPath.section].rows[indexPath.row] = data - sender.data = uiData - $("serverControl").info = controlInfo - saveWorkspace() - }, - reorderFinished: data => { - $thread.background({ - delay: 0, - handler: function () { - $("serverEditor").data = formatListData(data) - saveWorkspace() - } - }) - }, - forEachItem: (view, indexPath) => { - if (indexPath.row % 2 === 1) { - view.bgcolor = $color("#f1f8ff") - } else { - view.bgcolor = $color("white") - } - }, - pulled: sender => { - let listSections = $("serverEditor").data.filter(i => /^http/.test(i.url)) - linkHandler(listSections.map(i => i.url).join('\n'), { - handler: (res, name, url, type) => { - sender.endRefreshing() - nodeImportHandler(res, name, url, type) - } - }) - } - } - }, { - type: "input", - props: { - id: "serverSuffixEditor", - placeholder: '节点后缀', - text: '', - font: $font(18), - type: $kbType.ascii - }, - layout: (make, view) => { - make.top.equalTo(view.prev.bottom).offset(10) - make.width.equalTo(view.prev).offset(-125) - make.height.equalTo(45) - make.left.equalTo(view.prev.left) - }, - events: { - changed: sender => { - saveWorkspace() - }, - returned: sender => { - sender.blur() - } - } - }, { - type: "view", - props: { - id: "outputFormatLabel", - bgcolor: $color("#f1f1f1"), - radius: 6 - }, - layout: (make, view) => { - make.right.equalTo(view.super.right).offset(-10) - make.top.equalTo(view.prev) - make.height.equalTo(view.prev) - make.width.equalTo(120) - }, - views: [{ - type: "image", - props: { - data: $file.read('assets/menu_icon.png'), - bgcolor: $color("clear"), - hidden: true - }, - layout: (make, view) => { - make.left.equalTo(view.super).offset(10) - make.height.width.equalTo(view.super.height).offset(-25) - make.centerY.equalTo(view.super) - } - }, { - type: "image", - props: { - id: "outputFormatIcon", - data: $file.read('assets/today_surge.png'), - bgcolor: $color("clear") - }, - layout: (make, view) => { - make.left.equalTo(view.super).offset(5) - make.height.width.equalTo(view.super.height).offset(-15) - make.centerY.equalTo(view.super).offset(1) - } - }, { - type: 'label', - props: { - textColor: colorUtil.getColor("outputFormatText"), - id: 'outputFormatType', - text: 'Surge3 Pro', - align: $align.center, - font: $font("bold", 16), - autoFontSize: true, - }, - layout: (make, view) => { - make.height.equalTo(view.super) - make.width.equalTo(view.super).offset(-45) - make.left.equalTo(view.prev.right) - make.top.equalTo(view.super) - } - }], - events: { - tapped: sender => { - renderOutputFormatMenu(sender) - } - } - }, { - type: "matrix", - props: { - id: "usualSettings", - columns: 4, - itemHeight: 40, - spacing: 5, - scrollEnabled: false, - data: [{ - title: { text: 'ADS', bgcolor: btnOnFg, textColor: btnOffFg } - }, { - title: { text: 'MITM', bgcolor: btnOnFg, textColor: btnOffFg } - }, { - title: { text: 'Emoji', bgcolor: btnOnFg, textColor: btnOffFg } - }, { - title: { text: '导出', bgcolor: btnOnFg, textColor: btnOffFg } - }], - template: [{ - type: "label", - props: { - id: "title", - align: $align.center, - font: $font(14), - radius: 5, - borderColor: btnOnBg, - borderWidth: 0.3, - }, - layout: $layout.fill - }] - }, - layout: (make, view) => { - make.width.equalTo(view.super).offset(-10) - make.centerX.equalTo(view.super) - make.height.equalTo(50) - make.top.equalTo($("serverSuffixEditor").bottom).offset(5) - }, - events: { - didSelect: (sender, indexPath, data) => { - if (indexPath.row === 2) { - refreshListEmoji(isEmoji()) - } - data.title.bgcolor = cu.isEqual(data.title.bgcolor, btnOnBg) ? btnOffBg : btnOnBg - data.title.textColor = cu.isEqual(data.title.bgcolor, btnOnFg) ? btnOffFg : btnOnFg - let uiData = $("usualSettings").data - uiData[indexPath.row] = data - $("usualSettings").data = uiData - saveWorkspace() - } - } - }] - }, { - type: "button", - props: { - id: "advanceBtn", - titleColor: colorUtil.getColor("advanceBtnFg"), - title: "进阶设置", - bgcolor: colorUtil.getColor("advanceBtnBg") - }, - layout: (make, view) => { - make.width.equalTo((screenWidth / 2 - 15) * 0.686 - 10) - make.left.equalTo(10) - make.height.equalTo(40) - make.top.equalTo($("usualSettings").bottom).offset(5) - }, - events: { - tapped: sender => { - renderAdvanceUI() - } - } - }, { - type: "button", - props: { - id: "aboutBtn", - titleColor: colorUtil.getColor("aboutBtnFg"), - title: "关于", - bgcolor: colorUtil.getColor("aboutBtnBg") - }, - layout: (make, view) => { - make.height.equalTo(40) - make.width.equalTo((screenWidth / 2 - 15) * 0.314 + 5) - make.left.equalTo($("advanceBtn").right).offset(5) - make.top.equalTo($("usualSettings").bottom).offset(5) - }, - events: { - tapped: sender => { - renderAboutUI() - } - } - }, { - type: "button", - props: { - id: "genBtn", - titleColor: colorUtil.getColor("genBtnFg"), - bgcolor: colorUtil.getColor("genBtnBg"), - title: "生成配置" - }, - layout: (make, view) => { - make.width.equalTo((screenWidth - 10) * 0.5 - 5) - make.height.equalTo(40) - make.right.equalTo(view.super).offset(-10) - make.top.equalTo($("usualSettings").bottom).offset(5) - }, - events: { - tapped: sender => { - makeConf({ - onStart: () => { - $("progressView").hidden = false - $ui.animate({ - duration: 0.2, - animation: function () { - $("progressView").alpha = 1 - } - }) - }, - onProgress: (p, hint) => { - hint !== '' && ($("loadingHintLabel").text = hint) - $("progressBar").value = p - }, - onDone: res => { - $ui.animate({ - duration: 0.3, - animation: function () { - $("progressView").alpha = 0 - }, - completion: function () { - $("loadingHintLabel").text = '处理中,请稍后' - $("progressBar").value = 0 - $("progressView").hidden = true - } - }) - exportConf(res.fileName, res.fileData, res.target, res.actionSheet, false, () => { - $http.stopServer() - }) - $app.listen({ - resume: function () { - $http.stopServer() - } - }) - }, - onError: res => { - $("progressView").value = 0 - $("progressView").hidden = true - } - }) - }, - longPressed: sender => { - $share.sheet(['data.js', $file.read('data.js')]) - } - } - }, { - type: "blur", - props: { - id: "progressView", - style: 1, - alpha: 0, - hidden: true - }, - layout: $layout.fill, - views: [{ - type: "label", - props: { - id: "loadingHintLabel", - text: "处理中,请稍后", - textColor: $color("black"), - }, - layout: (make, view) => { - make.centerX.equalTo(view.super) - make.centerY.equalTo(view.super).offset(-30) - } - }, { - type: "progress", - props: { - id: "progressBar", - value: 0 - }, - layout: (make, view) => { - make.width.equalTo(screenWidth * 0.8) - make.center.equalTo(view.super) - make.height.equalTo(3) - } - }] - },] - }) -} - -let nodeImportHandler = (res, name, url, type = -1) => { - // 如果是托管,url不为undefined - // console.log([res, name, url]) - let listData = $("serverEditor").data || [] - let existsSec = listData.find(item => item.url === url) - if (!res || res.length === 0) { - $ui.alert({ - title: `${existsSec ? '更新' : '获取'}失败`, - message: `${existsSec ? existsSec.title : url}` - }) - return - } - let section = existsSec || { title: name, rows: [], url: url } - section.rows = [] - let controlInfo = $("serverControl").info - for (let idx in res) { - if (res[idx].split("=")[1].trim() == 'direct') { - // 过滤直连 - continue - } - let selected = controlInfo.customProxyGroup[controlInfo.currentProxyGroup].indexOf(res[idx].split('=')[0].trim()) > -1 - section.rows.push({ - proxyName: { text: res[idx].split('=')[0].trim() }, - proxyLink: res[idx], - proxyAuto: { hidden: !selected }, - proxyType: type - }) - } - if (!existsSec) { - listData.unshift(section) - } - $("serverEditor").data = listData - saveWorkspace() -} - -function formatListData(data) { - if (!data || data.length === 0) { - return [] - } - let noGroup = [] - data = data.map(i => { - if (i.title === '' || i.rows.length === 0) { - noGroup = noGroup.concat(i.rows) - return null - } - return i - }).filter(i => i !== null) - if (noGroup.length > 0) { - data.unshift({ title: "", rows: noGroup }) - } - return data -} - - -function loading(on) { - let iconView = $("navLoadingIcon") - if (on) { - // iconView.play() - } else { - // iconView.pause() - } -} - -function refreshListEmoji(isEmoji) { - function addEmoji(emojiSet, name) { - let minIdx = 300; - let resEmoji = ''; - for (let idx in emojiSet) { - let reg = `(${emojiSet[idx].slice(1).join('|')})` - let matcher = name.match(new RegExp(reg)) - if (matcher && matcher.index < minIdx) { - minIdx = matcher.index - resEmoji = emojiSet[idx][0] - } - } - return minIdx !== 300 ? `${resEmoji} ${name}` : name - } - - function removeEmoji(emojiSet, name) { - let emoji = emojiSet.map(i => i[0]) - let reg = `(${emoji.join('|')}) ` - return name.replace(new RegExp(reg, 'g'), '') - } - - let serverEditorData = $("serverEditor").data - - loading(true) - $http.get({ - url: "https://raw.githubusercontent.com/Fndroid/country_emoji/master/emoji.json" + `?t=${new Date().getTime()}` - }).then(resp => { - loading(false) - let emojiSet = resp.data - $("serverEditor").data = serverEditorData.map(sec => { - sec.rows = sec.rows.map(i => { - i.proxyLink = isEmoji ? removeEmoji(emojiSet, i.proxyLink) : addEmoji(emojiSet, i.proxyLink) - i.proxyName.text = i.proxyLink.split(/\s*=/)[0] - return i - }) - return sec - }) - saveWorkspace() - }).catch(error => { - loading(false) - $ui.alert("Emoji配置获取失败") - }) -} - -function showAlterDialog(reg, rep, callback) { - let fontSize = $text.sizeThatFits({ - text: rep, - width: screenWidth - 100, - font: $font(16) - }) - let view = { - type: "blur", - layout: $layout.fill, - props: { - id: "alertBody", - style: 1, - alpha: 0 - }, - views: [{ - type: "view", - props: { - id: "alterMainView", - bgcolor: $color("#ccc"), - smoothRadius: 10 - }, - layout: (make, view) => { - make.height.equalTo(230 + fontSize.height); - make.width.equalTo(view.super).offset(-60); - make.center.equalTo(view.super) - }, - events: { - tapped: sender => { } - }, - views: [{ - type: "label", - props: { - text: "组别名称", - font: $font("bold", 16) - }, - layout: (make, view) => { - make.top.equalTo(view.super).offset(20); - make.left.equalTo(view.super).offset(10); - } - }, { - type: "input", - props: { - id: "alterInputSection", - text: reg, - autoFontSize: true - }, - events: { - returned: sender => { - sender.blur() - } - }, - layout: (make, view) => { - make.top.equalTo(view.prev.bottom).offset(10); - make.width.equalTo(view.super).offset(-20); - make.centerX.equalTo(view.super) - make.left.equalTo(view.super).offset(10); - make.height.equalTo(40) - } - }, { - type: "label", - props: { - text: "节点信息", - font: $font("bold", 16) - }, - layout: (make, view) => { - make.top.equalTo(view.prev.bottom).offset(15); - make.left.equalTo(view.super).offset(10); - } - }, { - type: "text", - props: { - id: "alberInputLink", - text: rep, - autoFontSize: true, - radius: 6, - font: $font(16), - bgcolor: $color("#eff0f2"), - insets: $insets(10, 5, 10, 5) - }, - events: { - returned: sender => { - sender.blur() - } - }, - layout: (make, view) => { - make.top.equalTo(view.prev.bottom).offset(10); - make.width.equalTo(view.super).offset(-20); - make.centerX.equalTo(view.super) - make.left.equalTo(view.super).offset(10); - make.height.equalTo(fontSize.height + 20) - } - }, { - type: 'button', - props: { - icon: $icon("064", $color("#fff"), $size(20, 20)), - id: 'confirmBtn', - radius: 25 - }, - layout: (make, view) => { - make.height.width.equalTo(50) - make.bottom.equalTo(view.super).offset(-10) - make.right.equalTo(view.super).offset(-10) - }, - events: { - tapped: sender => { - callback && callback($("alterInputSection").text, $("alberInputLink").text); - $("alertBody").remove(); - } - } - }] - }], - events: { - tapped: sender => { - sender.remove() - } - } - } - $("bodyView").add(view) - $ui.animate({ - duration: 0.2, - animation: () => { - $("alertBody").alpha = 1 - } - }) -} - -function renderOutputFormatMenu(superView) { - $("bodyView").add({ - type: "view", - props: { - id: "outputFormatSelectorView", - alpha: 0 - }, - layout: (make, view) => { - make.height.width.equalTo(view.super) - make.center.equalTo(view.super) - }, - views: [{ - type: "blur", - props: { - style: 2, - alpha: 1, - }, - layout: $layout.fill, - events: { - tapped: sender => { - hideView(sender); - } - } - }, { - type: "list", - props: { - id: "outputFormatSelectorItems", - radius: 15, - rowHeight: 50, - alwaysBounceVertical: false, - data: ['Surge 3 TF', 'Surge 3 Pro', 'Surge 2', 'Quantumult'], - frame: resetFrame(superView.frame), - header: { - type: "label", - props: { - text: "选择导出格式", - height: 50, - font: $font("bold", 15), - align: 1 - } - }, - separatorHidden: true - }, - events: { - didSelect: (sender, indexPath, data) => { - let type = 'surge' - if (data === 'Quantumult') { - type = 'quan' - } else if (data === 'Surge 2') { - type = 'surge2' - } - $("outputFormatType").text = data - $("outputFormatIcon").data = $file.read(`assets/today_${type}.png`) - saveWorkspace() - hideView(sender) - } - } - }] - }) - - $ui.animate({ - duration: 0.3, - damping: 0.8, - velocity: 0.3, - animation: () => { - superView.scale(1.2) - $("outputFormatSelectorView").alpha = 1 - $("outputFormatSelectorItems").frame = $rect(80, screenHeight - 430 + navBarHeight + statusBarHeight, screenWidth - 90, 250) - } - }) - - function hideView(sender) { - $ui.animate({ - duration: 0.2, - velocity: 0.5, - animation: () => { - superView.scale(1) - $("outputFormatSelectorView").alpha = 0; - $("outputFormatSelectorItems").frame = resetFrame(superView.frame); - }, - completion: () => { - sender.super.remove(); - } - }); - } -} - -function resetFrame(frame) { - return $rect(frame.x, frame.y + navBarHeight + statusBarHeight, frame.width, frame.height) -} - -function archivesHandler() { - const ARCHIVES = $addin.current.name + '/archivesFiles' - if (!$drive.exists(ARCHIVES)) { - $drive.mkdir(ARCHIVES) - } - console.log($drive.list(ARCHIVES)) - let latestVersion = ($app.info.build * 1) > 335 - let getFiles = function () { - return $drive.list(ARCHIVES).map(i => { - let path = i.runtimeValue().invoke('pathComponents').rawValue() - let name = latestVersion ? i : path[path.length - 1] - return { - archiveName: { - text: name, - textColor: name === $cache.get('currentArchive') ? $color("red") : $color("black") - } - } - }) - } - $("bodyView").add({ - type: "view", - props: { - id: "archivesView", - alpha: 0 - }, - layout: (make, view) => { - make.height.width.equalTo(view.super) - make.center.equalTo(view.super) - }, - views: [{ - type: "blur", - props: { - style: 2, - alpha: 1, - }, - layout: $layout.fill, - events: { - tapped: sender => { - $ui.animate({ - duration: 0.2, - animation: () => { - $("archivesView").alpha = 0 - $("archivesList").frame = $rect(0, 0, screenWidth, screenHeight) - }, - completion: () => { - sender.super.remove() - } - }) - } - } - }, { - type: "list", - props: { - id: "archivesList", - radius: 15, - data: getFiles(), - header: { - type: "label", - props: { - text: "配置备份", - height: 50, - font: $font("bold", 20), - align: $align.center - } - }, - template: { - props: { - bgcolor: $color("clear") - }, - views: [ - { - type: "label", - props: { - id: "archiveName" - }, - layout: (make, view) => { - make.width.equalTo(view.super).offset(-20) - make.left.equalTo(view.super).offset(10) - make.height.equalTo(view.super) - } - } - ] - }, - actions: [{ - title: "删除", - color: $color('red'), - handler: (sender, indexPath) => { - let fileName = sender.object(indexPath).archiveName.text - let success = $drive.delete(ARCHIVES + '/' + fileName) - if (success) { - sender.data = getFiles() - } - } - }, { - title: "导出", - handler: (sender, indexPath) => { - let fileName = sender.object(indexPath).archiveName.text - $share.sheet(['data.js', $drive.read(ARCHIVES + "/" + fileName)]) - } - }, { - title: "覆盖", - color: $color("tint"), - handler: (sender, indexPath) => { - let filename = sender.object(indexPath).archiveName.text - let success = $drive.write({ - data: $file.read('data.js'), - path: ARCHIVES + '/' + filename - }) - $ui.toast("配置文件覆盖" + (success ? "成功" : "失败")) - } - }] - }, - layout: (make, view) => { - make.height.equalTo(view.super).dividedBy(12 / 7) - make.width.equalTo(view.super).dividedBy(12 / 9) - make.center.equalTo(view.super) - }, - events: { - didSelect: (sender, indexPath, item) => { - let data = item.archiveName.text - if (/\..*?\.icloud/.test(data)) { - $ui.alert(`备份文件不在本地,请先进入iCloud下载,路径为:文件 -> JSBox -> ${$addin.current.name} -> archivesFiles`) - return - } - let success = $file.write({ - data: $drive.read(ARCHIVES + '/' + data), - path: "data.js" - }) - if (success) { - $cache.set('currentArchive', data) - $app.notify({ - name: 'loadData' - }) - $ui.animate({ - duration: 0.2, - animation: () => { - $("archivesView").alpha = 0 - $("archivesList").frame = $rect(0, 0, screenWidth, screenHeight) - }, - completion: () => { - sender.super.remove() - } - }) - } - } - } - }, { - type: "button", - props: { - title: "+", - circular: true, - }, - layout: (make, view) => { - make.bottom.equalTo(view.prev) - make.right.equalTo(view.prev).offset(-5) - make.height.width.equalTo(50) - }, - events: { - tapped: sender => { - $input.text({ - type: $kbType.default, - placeholder: "请输入备份文件名", - handler: function (text) { - if (text === '') { - $ui.error("无法创建备份") - return - } - let success = $drive.write({ - data: $file.read('data.js'), - path: ARCHIVES + '/' + text - }) - if (success) { - $cache.set('currentArchive', text) - sender.prev.data = getFiles() - } - } - }) - } - } - }] - }) - - $ui.animate({ - duration: .3, - damping: 0.8, - velocity: 0.3, - animation: () => { - $("archivesView").alpha = 1 - $("archivesList").scale(1.1) - } - }) -} - -// function specialProxyGroup() { -// if (getRulesReplacement()) { -// $ui.alert('检测到有规则替换,无法使用特殊代理设置') -// return -// } -// let groups = getProxyGroups(); -// const menuItems = groups.concat(['🚀 Direct', '查看设置', '清除设置']); -// $ui.menu({ -// items: menuItems, -// handler: function (mTitle, idx) { -// if (idx === menuItems.length - 1) { -// $("serverEditor").info = {}; -// saveWorkspace(); -// } -// else if (idx === menuItems.length - 2) { -// let videoProxy = $("serverEditor").info; -// let output = []; -// for (let k in videoProxy) { -// output.push(`${k} - ${videoProxy[k]}`); -// } -// $ui.alert(output.length > 0 ? output.join('\n') : "无设置特殊代理"); -// } -// else { -// let videoReg = require('scripts/videoReg') -// $ui.menu({ -// items: Object.keys(videoReg), -// handler: function (title, idx) { -// let proxyName = mTitle; -// let videoProxy = $("serverEditor").info; -// videoProxy[title] = proxyName; -// $("serverEditor").info = videoProxy; -// saveWorkspace(); -// } -// }); -// } -// } -// }); -// } - -function genControlItems() { - let currentProxyGroup = PROXY_HEADER - try { - currentProxyGroup = $("serverControl").info.currentProxyGroup - } catch (e) { } - return [{ - title: { text: '节点倒序' } - }, { - title: { text: currentProxyGroup } - }, { - title: { text: '删除分组' } - }] -} - -function getProxyGroups() { - let fileData = JSON.parse($file.read(FILE).string) - let proxyGroupSettings = fileData.proxyGroupSettings - let groups = proxyGroupSettings.split(/[\n\r]/).filter(i => /^(?!\/\/)[\s\S]+=[\s\S]+/.test(i)).map(i => i.split('=')[0].trim()) - return groups -} - -function groupShortcut() { - let controlInfo = $("serverControl").info - let currentProxyGroup = controlInfo.currentProxyGroup || PROXY_HEADER - let customProxyGroup = controlInfo.customProxyGroup || {} - let menuItems = Object.keys(customProxyGroup).sort() - $("bodyView").add({ - type: "view", - props: { - id: "placeholderView", - alpha: 0 - }, - layout: (make, view) => { - make.height.width.equalTo(view.super) - make.center.equalTo(view.super) - }, - views: [{ - type: "blur", - props: { - style: 2, - alpha: 1, - }, - layout: $layout.fill, - events: { - tapped: sender => { - removeAnimation() - } - } - }, { - type: "list", - props: { - id: "placeholderList", - radius: 15, - data: menuItems, - header: { - type: "label", - props: { - text: "占位符", - height: 50, - font: $font("bold", 20), - align: $align.center - } - }, - actions: [{ - title: "删除", - color: $color('red'), - handler: (sender, indexPath) => { - let title = sender.object(indexPath) - if ([PROXY_HEADER, 'Proxy Header'].indexOf(title) > -1) { - $ui.error("此占位符无法删除") - return - } - delete customProxyGroup[title] - $("serverControl").info = controlInfo - saveWorkspace() - $("placeholderList").data = Object.keys(customProxyGroup).sort() - } - }, { - title: "重命名", - handler: (sender, indexPath) => { - let title = sender.object(indexPath) - if ([PROXY_HEADER, 'Proxy Header'].indexOf(title) > -1) { - $ui.error("此占位符无法重命名") - return - } - $input.text({ - type: $kbType.default, - placeholder: title, - handler: function (text) { - if (sender.data.indexOf(text) > -1) { - $ui.error("此名称已被占用") - } else { - customProxyGroup[text] = customProxyGroup[title] - delete customProxyGroup[title] - if ($("serverControl").info.currentProxyGroup === title) { - switchToGroup(text) - } - $("serverControl").info = controlInfo - saveWorkspace() - sender.data = Object.keys(customProxyGroup).sort() - } - } - }) - } - }, { - title: "删除节点", - color: $color('tint'), - handler: (sender, indexPath) => { - let title = sender.object(indexPath) - let headers = customProxyGroup[title] - let editorData = $("serverEditor").data - editorData.map(section => { - section.rows = section.rows.filter(item => headers.indexOf(item.proxyName.text) === -1) - return section - }) - $("serverEditor").data = editorData - saveWorkspace() - $ui.toast("已删除占位符对应节点") - removeAnimation() - } - }] - }, - layout: (make, view) => { - make.height.equalTo(view.super).dividedBy(12 / 7) - make.width.equalTo(view.super).dividedBy(12 / 9) - make.center.equalTo(view.super) - }, - events: { - didSelect: (sender, indexPath, data) => { - $ui.toast(`当前占位符为:${data}`) - switchToGroup(data) - removeAnimation() - } - } - }, { - type: "button", - props: { - title: "+", - circular: true, - }, - layout: (make, view) => { - make.bottom.equalTo(view.prev) - make.right.equalTo(view.prev).offset(-5) - make.height.width.equalTo(50) - }, - events: { - tapped: sender => { - $input.text({ - type: $kbType.default, - placeholder: "建议:xxxHeader", - handler: function (text) { - if ([PROXY_HEADER, 'Proxy Header', ''].indexOf(text) > -1) { - $ui.error("占位符名称冲突") - return - } - customProxyGroup[text] = [] - $("serverControl").info = controlInfo - saveWorkspace() - $("placeholderList").data = Object.keys(customProxyGroup).sort() - } - }) - } - } - }] - }) - - function removeAnimation() { - $ui.animate({ - duration: 0.2, - animation: () => { - $("placeholderView").alpha = 0 - $("placeholderList").frame = resetFrame($("serverEditor").frame) - }, - completion: () => { - $("placeholderView").remove() - } - }) - } - - $ui.animate({ - duration: .3, - damping: 0.8, - animation: () => { - $("placeholderView").alpha = 1 - $("placeholderList").scale(1.1) - } - }) - - function switchToGroup(title) { - let group = customProxyGroup[title]; - // 保存当前编辑策略组 - controlInfo.currentProxyGroup = title; - $("serverControl").info = controlInfo; - // 恢复选中的策略组UI - let listData = $("serverEditor").data || []; - listData = listData.map(section => { - section.rows = section.rows.map(item => { - item.proxyAuto.hidden = !(group.indexOf(item.proxyName.text) > -1) - return item; - }); - return section; - }); - $("serverEditor").data = listData; - $("serverControl").data = genControlItems() - } -} - -function listReplace(sender, indexPath, obj) { - let oldData = sender.data - if (indexPath.section != null) { - oldData[indexPath.section].rows[indexPath.row] = obj - } else { - oldData[indexPath.row] = obj - } - sender.data = oldData -} - -function getAutoRules(url, done, hint = '') { - return new Promise((resolve, reject) => { - $http.get({ - url: url, - handler: function (resp) { - if (done) done(hint) - resolve(resp.data) - } - }) - }) -} - -function importMenu(params) { - let staticItems = ['剪贴板', '二维码', '空节点'] - $ui.menu({ - items: staticItems, - handler: function (title, idx) { - if (title === staticItems[0]) { - let clipText = $clipboard.text - linkHandler(clipText, params) - } else if (title === staticItems[1]) { - $qrcode.scan({ - handler(string) { - linkHandler(string, params) - } - }) - } else if (title === staticItems[2]) { - params.handler(['Empty Node = '], 'Default', `emptynode${new Date().getTime()}`) - } - } - }) -} - -function isEmoji() { - try { - let advanceSettings = JSON.parse($file.read(FILE).string) - let workspace = advanceSettings.workspace - let usualData = workspace.usualData - - let usualValue = function (key) { - return usualData.find(i => i.title.text == key) ? usualData.find(i => i.title.text == key).title.bgcolor : false - } - return usualValue('Emoji') - } catch (e) { - return false - } -} - -function linkHandler(url, params) { - let emoji = isEmoji() - let servers = { - shadowsocks: [], - surge: [], - online: [], - vmess: [], - ignore: [], - shadowsocksr: [] - } - - if (!url) { - $ui.alert('没有识别到有效链接') - return - } - - let urls = url.split(/[\r\n]+/g).map(i => i.trim()).filter(i => i !== '') - urls.forEach(item => { - if (/^ss:\/\//.test(item)) { - servers.shadowsocks.push(item) - } else if (/^https?:\/\//.test(item)) { - servers.online.push(item) - } else if (/[\S\s]+=[\s]*(custom|ss|http|https|socks5|socks5-tls|external)/.test(item)) { - servers.surge.push(item) - } else if (/^vmess:\/\//.test(item)) { - servers.vmess.push(item) - } else if (/^ssr:\/\//.test(item)) { - servers.shadowsocksr.push(item) - } else { - servers.ignore.push(item) - } - }) - - let updateHint = '' - updateHint += servers.shadowsocks.length > 0 ? `\nShadowsocks链接${servers.shadowsocks.length}个\n` : '' - updateHint += servers.shadowsocksr.length > 0 ? `\nShadowsocksR链接${servers.shadowsocksr.length}个\n` : '' - updateHint += servers.surge.length > 0 ? `\nSurge链接${servers.surge.length}个\n` : '' - updateHint += servers.vmess.length > 0 ? `\nV2Ray链接${servers.vmess.length}个\n` : '' - updateHint += servers.online.length > 0 ? `\n托管或订阅${servers.online.length}个\n` : '' - // $ui.alert({ - // title: '更新概况', - // message: updateHint - // }) - - function addEmoji(emojiSet, link) { - let name = link.split(/=/)[0] - let minIdx = 300; - let resEmoji = ''; - for (let idx in emojiSet) { - let reg = `(${emojiSet[idx].slice(1).join('|')})` - let matcher = name.match(new RegExp(reg)) - if (matcher && matcher.index < minIdx) { - minIdx = matcher.index - resEmoji = emojiSet[idx][0] - } - } - return minIdx !== 300 ? `${resEmoji} ${link}` : link - } - - function detailHandler(emojiSet = null) { - for (let k in servers) { - if (servers[k].length === 0) { - continue - } - if (k === 'shadowsocks') { - let res = proxyUtil.proxyFromURL(servers[k]) - params.handler(emojiSet ? res.servers.map(i => addEmoji(emojiSet, i)) : res.servers, res.sstag, servers[k].join('\n')) - } else if (k === 'surge') { - let urls = servers[k].map(i => i.replace(/,[\s]*udp-relay=true/, '')) - let result = [] - for (let idx in urls) { - result[idx] = urls[idx] - } - $delay(0.3, function () { - params.handler(emojiSet ? result.map(i => addEmoji(emojiSet, i)) : result, urls.length > 1 ? `批量Surge链接(${urls.length})` : result[0].split('=')[0].trim(), urls.join('\n')) - }) - } else if (k === 'online') { - loading(true) - proxyUtil.proxyFromConf({ - urls: servers[k], - handler: res => { - console.log('res', res); - loading(false) - params.handler(emojiSet ? res.servers.map(i => addEmoji(emojiSet, i)) : res.servers, res.filename, res.url, res.type) - } - }) - } else if (k === 'vmess') { - let res = proxyUtil.proxyFromVmess(servers[k]) - params.handler(emojiSet ? res.servers.map(i => addEmoji(emojiSet, i)) : res.servers, res.sstag, servers[k].join('\n')) - } else if (k === 'shadowsocksr') { - let res = proxyUtil.proxyFromSSR(servers[k]) - params.handler(emojiSet ? res.servers.map(i => addEmoji(emojiSet, i)) : res.servers, res.sstag, servers[k].join('\n')) - } else { - $ui.alert('剪贴板存在无法识别的行:\n\n' + servers.ignore.join('\n') + '\n\n以上行将被丢弃!') - } - } - } - - if (emoji) { - loading(true) - $http.get({ - url: "https://raw.githubusercontent.com/Fndroid/country_emoji/master/emoji.json" + `?t=${new Date().getTime()}` - }).then(resp => { - loading(false) - let emojiSet = resp.data - detailHandler(emojiSet) - }).catch(error => { - loading(false) - $ui.alert("Emoji配置获取失败") - }) - } else { - detailHandler(null) - } -} - -function write2file(key, value) { - let content = JSON.parse($file.read(FILE).string) - content[key] = value - $file.write({ - data: $data({ "string": JSON.stringify(content) }), - path: FILE - }) -} - -function renderAdvanceUI() { - let previewData = JSON.parse($file.read(FILE).string) - let placeHolders = Object.keys(previewData.workspace.customProxyGroup) - let inputViewData = [] - for (let idx in settingKeys) { - let content = previewData[settingKeys[idx]] - let view = { - type: "text", - props: { - text: content, - bgcolor: $color("#f0f5f5"), - font: $font(14) - }, - events: { - didChange: sender => { - let content = sender.text - if (sender.text == '') { - content = $file.read('defaultConf/' + settingKeys[idx]).string - sender.text = content - } - write2file(settingKeys[idx], content) - } - } - } - let phWidth = placeHolders.reduce((pre, cur) => (cur.length * 10 + pre), 0) + (placeHolders.length + 1) * 5 - if (idx == 2) { - view.props.accessoryView = { - type: "view", - props: { - height: 44, - bgcolor: $color("#ced4d4") - }, - views: [{ - type: "label", - props: { - text: "完成", - align: $align.center - }, - layout: (make, view) => { - make.right.equalTo(view.super) - make.top.equalTo(view.super) - make.height.equalTo(view.super) - make.width.equalTo(60) - }, - events: { - tapped: sender => { - $("inputViews").views[2].blur() - } - } - }, { - type: "scroll", - props: { - alwaysBounceHorizontal: true, - alwaysBounceVertical: false, - showsHorizontalIndicator: false, - contentSize: $size(phWidth, 34) - }, - views: placeHolders.map((i, idx) => { - return { - type: 'label', - props: { - text: i, - lines: 1, - font: $font("bold", 15), - align: $align.center, - bgcolor: $color("#fff"), - radius: 5, - textColor: $color('#000') - }, - layout: (make, view) => { - make.size.equalTo($size(i.length * 10, 34)) - make.centerY.equalTo(view.super) - // make.top.equalTo(view.suepr).offset(5) - if (idx > 0) { - make.left.equalTo(view.prev.right).offset(5) - } else { - make.left.equalTo(5) - } - }, - events: { - tapped: sender => { - let inputView = $("inputViews").views[2] - inputView.runtimeValue().$insertText(sender.text) - // let sr = inputView.selectedRange - // let old = inputView.text.split('') - // old.splice(sr.location, sr.length, sender.text) - // inputView.text = old.join('') - } - } - } - }), - layout: (make, view) => { - make.left.equalTo(view.super) - make.top.equalTo(view.super) - make.height.equalTo(view.super).offset(0) - make.width.equalTo(view.super).offset(-60) - } - }] - } - } - inputViewData.push(view) - } - let genControlBnts = function (idx) { - let titleTexts = ['小组件流量', '常规', '代理分组', '代理规则', '本地DNS映射', 'URL重定向', 'SSID', 'Header修改', '主机名', '配置根证书'] - const sbgc = colorUtil.getColor("advanceGridOnBg") - const stc = colorUtil.getColor("advanceGridOnFg") - const dbgc = colorUtil.getColor("advanceGridOffBg") - const dtc = colorUtil.getColor("advanceGridOffFg") - return titleTexts.map((item, i) => { - return { - title: { text: item, bgcolor: i === idx ? sbgc : dbgc, radius: 5, color: i == idx ? stc : dtc } - } - }) - } - $ui.push({ - type: "scroll", - props: { - title: "进阶设置", - navBarHidden: true, - statusBarHidden: colorUtil.getColor("statusBar", true) === 'clear' ? true : false, - statusBarStyle: colorUtil.getColor("statusBar", true) === '#ffffff' ? 1 : 0, - }, - views: [{ - type: "view", - props: { - id: "navBar", - bgcolor: colorUtil.getColor("navBar") - }, - layout: (make, view) => { - make.height.equalTo(navBarHeight + statusBarHeight) - make.width.equalTo(view.super) - }, - views: [{ - type: "label", - props: { - text: "进阶设置", - textColor: colorUtil.getColor("navTitleText"), - font: $font("bold", 25) - }, - layout: (make, view) => { - make.height.equalTo(navBarHeight) - make.top.equalTo(statusBarHeight) - make.left.equalTo(15) - } - }, { - type: "image", - props: { - icon: $icon("225", colorUtil.getColor("navIconRight"), $size(25, 25)), - bgcolor: $color("clear") - }, - layout: (make, view) => { - make.right.equalTo(view.super).offset(-15) - make.height.width.equalTo(25) - make.bottom.equalTo(view.super).offset(-10) - }, - events: { - tapped: sender => { - $ui.pop() - } - } - }] - }, { - type: "gallery", - props: { - id: "inputViews", - items: inputViewData, - interval: 0, - smoothRadius: 10, - }, - layout: (make, view) => { - make.height.equalTo(screenHeight - 325 - statusBarHeight - navBarHeight) - make.width.equalTo(view.super).offset(-20) - make.centerX.equalTo(view.super) - make.top.equalTo(navBarHeight + statusBarHeight + 10) - }, - events: { - changed: sender => { - let idx = sender.page - $("settingsControl").data = genControlBnts(idx) - } - } - }, { - type: "matrix", - props: { - columns: 2, - id: "settingsControl", - itemHeight: 40, - bgcolor: $color("#ffffff"), - spacing: 3, - data: genControlBnts(0), - template: [{ - type: "label", - props: { - id: "title", - align: $align.center, - font: $font("bold", 14) - }, - layout: $layout.fill - }] - }, - layout: (make, view) => { - make.height.equalTo(220) - make.centerX.equalTo(view.super) - make.width.equalTo(view.super).offset(-13) - make.top.equalTo(view.prev.bottom).offset(5) - }, - events: { - didSelect: (sender, indexPath, data) => { - let idx = indexPath.row - $("inputViews").page = idx - } - } - }, { - type: "label", - props: { - text: "上述设置点击完成生效,清空保存一次恢复默认", - font: $font(12), - textColor: $color("#595959"), - align: $align.center - }, - layout: (make, view) => { - make.top.equalTo(view.prev.bottom).offset(0) - make.width.equalTo(view.super) - make.height.equalTo(30) - make.centerX.equalTo(view.super) - } - }, { - type: "button", - props: { - title: '还原全部进阶设置', - bgcolor: $color("#ff6840") - }, - layout: (make, view) => { - make.width.equalTo(view.super).offset(-40) - make.centerX.equalTo(view.super) - make.top.equalTo(view.prev.bottom).offset(10) - make.height.equalTo(40) - }, - events: { - tapped: sender => { - $ui.alert({ - title: "提示", - message: "是否还原配置,还原后无法恢复", - actions: [{ - title: 'Cancel', - handler: () => { } - }, { - title: 'OK', - handler: () => { - let previewData = JSON.parse($file.read(FILE).string) - for (let idx in settingKeys) { - let defaultValue = $file.read(`defaultConf/${settingKeys[idx]}`).string - previewData[settingKeys[idx]] = defaultValue - } - $file.write({ - data: $data({ "string": JSON.stringify(previewData) }), - path: FILE - }) - $ui.pop() - } - }] - }) - } - } - }] - }) -} - -function renderAboutUI() { - let previewMD = function (title, filePath) { - $ui.push({ - props: { - title: title - }, - views: [{ - type: "markdown", - props: { - id: "", - content: $file.read(filePath).string - }, - layout: $layout.fill - }] - }) - } - - $ui.push({ - props: { - title: "关于", - id: "aboutMainView", - navBarHidden: true, - statusBarHidden: colorUtil.getColor("statusBar", true) === 'clear' ? true : false, - statusBarStyle: colorUtil.getColor("statusBar", true) === '#ffffff' ? 1 : 0, - }, - views: [{ - type: "view", - props: { - id: "navBar", - bgcolor: colorUtil.getColor("navBar") - }, - layout: (make, view) => { - make.height.equalTo(navBarHeight + statusBarHeight) - make.width.equalTo(view.super) - }, - views: [{ - type: "label", - props: { - text: "脚本相关", - textColor: colorUtil.getColor("navTitleText"), - font: $font("bold", 25) - }, - layout: (make, view) => { - make.height.equalTo(navBarHeight) - make.top.equalTo(statusBarHeight) - make.left.equalTo(15) - } - }, { - type: "image", - props: { - icon: $icon("225", colorUtil.getColor("navIconRight"), $size(25, 25)), - bgcolor: $color("clear") - }, - layout: (make, view) => { - make.right.equalTo(view.super).offset(-15) - make.height.width.equalTo(25) - make.bottom.equalTo(view.super).offset(-10) - }, - events: { - tapped: sender => { - $ui.pop() - } - } - }] - }, { - type: "scroll", - props: { - id: "mainAboutView", - contentSize: $size(0, 1000) - }, - layout: (make, view) => { - make.top.equalTo(navBarHeight + statusBarHeight); - make.width.equalTo(view.super) - make.height.equalTo(view.super).offset(navBarHeight + statusBarHeight) - }, - views: [{ - type: "label", - props: { - text: "文档说明", - font: $font(13), - textColor: $color("#505050") - }, - layout: (make, view) => { - make.top.equalTo(view.super).offset(10) - make.height.equalTo(30) - make.left.equalTo(15) - } - }, { - type: "list", - props: { - data: ["🗂 脚本简介", "🛠 使用手册", "📃 更新日志", "🖥 论坛导航"], - scrollEnabled: false - }, - layout: (make, view) => { - make.width.equalTo(view.super) - make.top.equalTo(view.prev.bottom).offset(0) - make.height.equalTo(180) - }, - events: { - didSelect: (sender, indexPath, data) => { - if (indexPath.row === 0) { - previewMD(data, 'docs.md') - } else if (indexPath.row === 1) { - $safari.open({ - url: "https://github.com/Fndroid/jsbox_script/wiki/Rules-lhie1" - }) - } else if (indexPath.row === 2) { - previewMD(data, 'updateLog.md') - } else { - $safari.open({ - url: "https://jsboxbbs.com/d/290-lhie1" - }) - } - } - } - }, { - type: "label", - props: { - text: "外部拓展", - font: $font(13), - textColor: $color("#505050") - }, - layout: (make, view) => { - make.top.equalTo(view.prev.bottom).offset(20) - make.height.equalTo(30) - make.left.equalTo(15) - } - }, { - type: "list", - props: { - data: ["🤖️ Rules-lhie1托管", "🎩 Quantumult去FA更新"], - scrollEnabled: false - }, - layout: (make, view) => { - make.width.equalTo(view.super) - make.top.equalTo(view.prev.bottom).offset(0) - make.height.equalTo(90) - }, - events: { - didSelect: (sender, indexPath, data) => { - if (indexPath.row === 0) { - $app.openURL("https://t.me/rules_lhie1_bot") - } else { - $safari.open({ - url: "https://jsboxbbs.com/d/474-quantumult-filter-action", - }) - } - } - } - }, { - type: "label", - props: { - text: "致谢捐献", - font: $font(13), - textColor: $color("#505050") - }, - layout: (make, view) => { - make.top.equalTo(view.prev.bottom).offset(20) - make.height.equalTo(30) - make.left.equalTo(15) - } - }, { - type: "list", - props: { - data: ["🙏 捐献打赏名单", "👍 赏杯咖啡支持作者"], - scrollEnabled: false - }, - layout: (make, view) => { - make.width.equalTo(view.super) - make.top.equalTo(view.prev.bottom).offset(0) - make.height.equalTo(90) - }, - events: { - didSelect: (sender, indexPath, data) => { - if (indexPath.row === 0) { - $http.get('https://raw.githubusercontent.com/Fndroid/sponsor_list/master/sponsors.md').then(res => { - let success = $file.write({ - data: $data({ string: res.data }), - path: 'donate.md' - }) - success && previewMD(data, 'donate.md') - }) - } else if (indexPath.row === 1) { - $ui.alert({ - title: '感谢支持', - message: '作者投入大量时间和精力对脚本进行开发和完善,你愿意给他赏杯咖啡支持一下吗?', - actions: [{ - title: "支付宝", - handler: () => { - $app.openURL($qrcode.decode($file.read("assets/thankyou2.jpg").image)) - } - }, { - title: "微信", - handler: () => { - $quicklook.open({ - image: $file.read("assets/thankyou.jpg").image - }) - } - }, { - title: "返回" - }] - }) - } else { - // $clipboard.text = 'GxsAtS84U7' - // $app.openURL("alipay://") - $app.openURL("https://qr.alipay.com/c1x047207ryk0wiaj6m6ye3") - } - } - } - }, { - type: "label", - props: { - text: "反馈联系", - font: $font(13), - textColor: $color("#505050") - }, - layout: (make, view) => { - make.top.equalTo(view.prev.bottom).offset(20) - make.height.equalTo(30) - make.left.equalTo(15) - } - }, { - type: "list", - props: { - data: ["📠 Telegram", "💡 GitHub", "📅 Channel"], - scrollEnabled: false - }, - layout: (make, view) => { - make.width.equalTo(view.super) - make.top.equalTo(view.prev.bottom).offset(0) - make.height.equalTo(140) - }, - events: { - didSelect: (sender, indexPath, data) => { - if (indexPath.row === 0) { - $safari.open({ - url: "https://t.me/Rules_lhie1", - }) - } else if (indexPath.row === 1) { - $safari.open({ - url: "https://github.com/Fndroid/jsbox_script/tree/master/Rules-lhie1/README.md", - }) - } else { - $safari.open({ - url: "https://t.me/Fndroids", - }) - } - } - } - }, { - type: "label", - props: { - text: "版本号:" + updateUtil.getCurVersion(), - font: $font(13), - textColor: $color("#505050") - }, - layout: (make, view) => { - make.top.equalTo(view.prev.bottom).offset(20) - make.height.equalTo(30) - make.centerX.equalTo(view.super) - } - }] - }] - }) -} - -function deleteServerGroup() { - let serverData = $("serverEditor").data - let sections = serverData.map(i => { - if (i.title === '') { - return '无分组节点' - } - return i.title - }) - $ui.menu({ - items: sections.concat(['全部删除', '关键字删除']), - handler: function (title, idx) { - if (title === '全部删除') { - $("serverEditor").data = [] - } else if (title === '关键字删除') { - $input.text({ - type: $kbType.default, - placeholder: "关键字,空格隔开", - text: $("serverControl").info.deleteKeywords || '', - handler: function (text) { - let keywords = text.split(/\s+/g).filter(i => i !== '') - let editorData = $("serverEditor").data - editorData.map(section => { - section.rows = section.rows.filter(item => keywords.every(k => !(new RegExp(k, 'g')).test(item.proxyName.text))) - return section - }) - $("serverEditor").data = editorData - let controlInfo = $("serverControl").info - controlInfo.deleteKeywords = text - $("serverControl").info = controlInfo - saveWorkspace() - } - }) - } else { - serverData.splice(idx, 1) - $("serverEditor").data = serverData - } - saveWorkspace() - } - }) -} - -function reverseServerGroup() { - let serverData = $("serverEditor").data - let sections = serverData.map(i => i.title) - if (sections.length === 1) { - serverData[0].rows.reverse() - $("serverEditor").data = serverData - saveWorkspace() - return - } - $ui.menu({ - items: sections.concat(['组别倒序']), - handler: function (title, idx) { - if (idx === sections.length) { - $("serverEditor").data = serverData.reverse() - } else { - serverData[idx].rows.reverse() - $("serverEditor").data = serverData - } - saveWorkspace() - } - }) -} - -let filePartReg = function (name) { - let reg = `\\[${name}\\]([\\S\\s]*?)(?:\\[General\\]|\\[Replica\\]|\\[Proxy\\]|\\[Proxy Group\\]|\\[Rule\\]|\\[Host\\]|\\[URL Rewrite\\]|\\[Header Rewrite\\]|\\[SSID Setting\\]|\\[MITM\\]|\\[URL-REJECTION\\]|\\[HOST\\]|\\[POLICY\\]|\\[REWRITE\\]|\\[Script\\]|$)` - return new RegExp(reg) -} - -function setUpWorkspace() { - $app.listen({ - ready: function () { - $("navLoadingIcon").play({ - fromProgress: 0, - toProgress: 0.6, - }) - $app.notify({ - name: 'loadData' - }) - }, - resume: () => { - - }, - loadData: () => { - let file = JSON.parse($file.read(FILE).string) - if (file && file.workspace) { - let workspace = file.workspace - $("fileName").text = workspace.fileName || '' - $("serverSuffixEditor").text = workspace.serverSuffix || '' - $("serverURL").info = workspace.withEmoji || false - let customProxyGroup = workspace.customProxyGroup || {} - let defaultGroupName = PROXY_HEADER - if (!(defaultGroupName in customProxyGroup)) { - customProxyGroup[defaultGroupName] = [] - } - let defaultGroup = customProxyGroup[defaultGroupName] - $("serverEditor").data = workspace.serverData.map(section => { - section.rows.map(item => { - item.proxyName = { - text: item.proxyName.text - } - item.proxyAuto = { - hidden: !(defaultGroup.indexOf(item.proxyName.text) > -1) - } - return item - }) - return section - }) - let usualSettingsData = workspace.usualData - let nd = $("usualSettings").data.map(item => { - let sd = usualSettingsData.find(i => i.title.text === item.title.text) - if (sd) { - item.title.bgcolor = sd.title.bgcolor ? btnOnBg : btnOffBg - item.title.textColor = sd.title.textColor ? btnOnFg : btnOffFg - } else { - item.title.bgcolor = btnOffFg - item.title.textColor = btnOffFg - } - return item - }) - $("usualSettings").data = nd - $("serverControl").info = { - deleteKeywords: workspace.deleteKeywords || '', - customProxyGroup: customProxyGroup, - currentProxyGroup: defaultGroupName - } - let outputFormat = workspace.outputFormat || 'Surge3' - let type = 'surge' - if (outputFormat === 'Quantumult') { - type = 'quan' - } else if (outputFormat === 'Surge 2') { - type = 'surge2' - } - $("outputFormatType").text = outputFormat - $("outputFormatIcon").data = $file.read(`assets/today_${type}.png`) - } else if (file && !file.workspace) { - let customProxyGroup = {} - let defaultGroupName = PROXY_HEADER - customProxyGroup[defaultGroupName] = [] - let defaultGroup = customProxyGroup[defaultGroupName] - $("serverControl").info = { - deleteKeywords: '', - customProxyGroup: customProxyGroup, - currentProxyGroup: defaultGroupName - } - } - } - }) -} - -function saveWorkspace() { - let workspace = { - fileName: $("fileName").text, - serverData: $("serverEditor").data, - withEmoji: $("serverURL").info || false, - usualData: $("usualSettings").data.map(i => { - i.title.bgcolor = cu.isEqual(btnOnBg, i.title.bgcolor) - i.title.textColor = cu.isEqual(btnOnFg, i.title.textColor) - return i - }), - outputFormat: $("outputFormatType").text, - serverSuffix: $("serverSuffixEditor").text, - deleteKeywords: $("serverControl").info.deleteKeywords || '', - customProxyGroup: $("serverControl").info.customProxyGroup || {} - } - let file = JSON.parse($file.read(FILE).string) - file.workspace = workspace - $file.write({ - data: $data({ string: JSON.stringify(file) }), - path: FILE - }) -} - - -function setDefaultSettings() { - let previewData = JSON.parse($file.read(FILE).string) - for (let idx in settingKeys) { - if (typeof previewData[settingKeys[idx]] === 'undefined' || previewData[settingKeys[idx]] == "") { - let defaultValue = ' ' - if ($file.exists(`defaultConf/${settingKeys[idx]}`)) { - defaultValue = $file.read(`defaultConf/${settingKeys[idx]}`).string - } - previewData[settingKeys[idx]] = defaultValue - } - } - $file.write({ - data: $data({ "string": JSON.stringify(previewData) }), - path: FILE - }) -} - -function autoGen() { - $ui.render({ - props: { - title: "" - }, - layout: $layout.fill, - views: [{ - type: "blur", - props: { - id: "progressView", - style: 1 - }, - layout: $layout.fill, - views: [{ - type: "label", - props: { - id: "loadingHintLabel", - text: "处理中,请稍后", - textColor: $color("black"), - }, - layout: (make, view) => { - make.centerX.equalTo(view.super) - make.centerY.equalTo(view.super).offset(-30) - } - }, { - type: "progress", - props: { - id: "progressBar", - value: 0 - }, - layout: (make, view) => { - make.width.equalTo(screenWidth * 0.8) - make.center.equalTo(view.super) - make.height.equalTo(3) - } - }, { - type: "button", - props: { - title: "CLOSE" - }, - layout: (make, view) => { - make.width.equalTo(80) - make.top.equalTo(view.prev.bottom).offset(20) - make.centerX.equalTo(view.super) - }, - events: { - tapped: sender => { - $http.stopServer() - $app.close() - } - } - }] - }] - }) - $app.listen({ - ready: function () { - makeConf({ - onProgress: (p, hint) => { - hint !== '' && ($("loadingHintLabel").text = hint) - $("progressBar").value = p - }, - onDone: res => { - exportConf(res.fileName, res.fileData, res.target, res.actionSheet, true, () => { - $http.stopServer() - $app.close() - }) - }, - onError: res => { - $ui.alert("无法生成配置文件,可能是规则仓库发生变化或网络出现问题") - } - }) - } - }) -} - -function makeConf(params) { - 'onStart' in params && params.onStart() - try { - let pu = { - prototype: "https://raw.githubusercontent.com/lhie1/Rules/master/Surge/Prototype.conf", - apple: 'https://raw.githubusercontent.com/lhie1/Rules/master/Auto/Apple.conf', - direct: 'https://raw.githubusercontent.com/lhie1/Rules/master/Auto/DIRECT.conf', - proxy: 'https://raw.githubusercontent.com/lhie1/Rules/master/Auto/PROXY.conf', - reject: 'https://raw.githubusercontent.com/lhie1/Rules/master/Auto/REJECT.conf', - testflight: 'https://raw.githubusercontent.com/lhie1/Rules/master/Surge/TestFlight.conf', - host: 'https://raw.githubusercontent.com/lhie1/Rules/master/Auto/HOST.conf', - urlrewrite: 'https://raw.githubusercontent.com/lhie1/Rules/master/Auto/URL%20Rewrite.conf', - headerrewrite: 'https://raw.githubusercontent.com/lhie1/Rules/master/Auto/Header%20Rewrite.conf', - hostname: 'https://raw.githubusercontent.com/lhie1/Rules/master/Auto/Hostname.conf', - mitm: 'https://raw.githubusercontent.com/lhie1/Rules/master/Surge/MITM.conf', - quanretcp: 'https://raw.githubusercontent.com/lhie1/Rules/master/Quantumult/Quantumult.conf', - quanextra: 'https://raw.githubusercontent.com/lhie1/Rules/master/Quantumult/Quantumult_Extra_JS.conf', - quanrejection: 'https://raw.githubusercontent.com/lhie1/Rules/master/Quantumult/Quantumult_URL.conf', - localhost: 'http://127.0.0.1/fndroid' - } - let advanceSettings = JSON.parse($file.read(FILE).string) - let workspace = advanceSettings.workspace - let usualData = workspace.usualData - let customProxyGroup = workspace.customProxyGroup - - let usualValue = function (key) { - return usualData.find(i => i.title.text == key) ? usualData.find(i => i.title.text == key).title.bgcolor : false - } - - let ads = usualValue('ADS') - let isMitm = usualValue('MITM') - let isActionSheet = usualValue('导出') - - let outputFormat = workspace.outputFormat - let surge2 = outputFormat === 'Surge 2' - let isQuan = outputFormat === 'Quantumult' - let testflight = outputFormat === 'Surge 3 TF' - - let serverEditorData = workspace.serverData - if (isQuan) { - serverEditorData = serverEditorData.map(i => { - let rows = i.rows.map(s => { - let containsOP = /obfs_param/.test(s.proxyLink) - s.proxyLink = s.proxyLink.replace(/,\s*group\s*=[^,]*/, '') - if (containsOP) { - s.proxyLink = s.proxyLink.replace(/obfs_param/, `group=${i.title}, obfs_param`) - } else { - s.proxyLink += `, group=${i.title}` - } - return s - }) - i.rows = rows - return i - }) - } - let flatServerData = serverEditorData.reduce((all, cur) => { - return { - rows: all.rows.concat(cur.rows) - } - }, { rows: [] }).rows - - let proxyNameLegal = function (name) { - return flatServerData.map(i => i.proxyName.text).concat(getProxyGroups()).concat(['🚀 Direct']).find(i => i === name) !== undefined - } - - let proxySuffix = workspace.serverSuffix.split(/\s*,\s*/g).map(i => i.replace(/\s/g, '')).filter(i => i !== '') - let proxies = flatServerData.map(i => { - let notExistSuffix = proxySuffix.filter((ps, idx) => { - if (idx === 0 && ps === '') return true - return i.proxyLink.indexOf(ps) < 0 - }) - let containsOP = /obfs_param/.test(i.proxyLink) - if (containsOP) { - i.proxyLink = i.proxyLink.replace(/obfs_param/, `${notExistSuffix.join(',')},obfs_param`) - } else if (notExistSuffix.length > 0) { - i.proxyLink += `,${notExistSuffix.join(',')}` - } - return i.proxyLink.replace('http://omgib13x8.bkt.clouddn.com/SSEncrypt.module', 'https://github.com/lhie1/Rules/blob/master/SSEncrypt.module?raw=true') - }).filter((item, idx, self) => { - let proxyName = item.split(/=/)[0].trim() - return self.findIndex(i => { - let pn = i.split('=')[0].trim() - return proxyName === pn - }) === idx - }) - proxies = proxies.join('\n') - let proxyHeaders = flatServerData.map(i => i.proxyName.text).join(', ') - let rules = '' - let prototype = '' - let host = '' - let urlRewrite = '' - let urlReject = '' - let headerRewrite = '' - let hostName = '' - let rename = null - let rulesReplacement = getRulesReplacement() - - let pgs = 0 - - let onPgs = function (hint) { - pgs += 0.1 - 'onProgress' in params && params.onProgress(pgs, hint) - } - - let emptyPromise = function (done, hint = '') { - if (done) done(hint) - return Promise.resolve('') - } - - let promiseArray = [ - getAutoRules(pu.prototype, onPgs, '成功取回配置模板'), // 0 - rulesReplacement ? getAutoRules(rulesReplacement, onPgs, '成功取回替换配置') : getAutoRules(isQuan || testflight ? pu.direct : pu.apple, onPgs, '成功取回APPLE规则'), // 1 - !ads || rulesReplacement ? emptyPromise(onPgs) : getAutoRules(isQuan || testflight ? pu.localhost : pu.reject, onPgs, '成功取回Reject规则'), // 2 - rulesReplacement ? emptyPromise(onPgs) : getAutoRules(isQuan || testflight ? pu.quanretcp : pu.proxy, onPgs, '成功取回Proxy规则'), // 3 - rulesReplacement ? emptyPromise(onPgs) : getAutoRules(isQuan || testflight ? pu.quanextra : pu.direct, onPgs, '成功取回Direct规则'), // 4 - rulesReplacement ? emptyPromise(onPgs) : getAutoRules(pu.host, onPgs, '成功取回Host'), // 5 - rulesReplacement ? emptyPromise(onPgs) : getAutoRules(pu.urlrewrite, onPgs, '成功取回URL Rewrite'), // 6 - rulesReplacement ? emptyPromise(onPgs) : getAutoRules(pu.headerrewrite, onPgs, '成功取回Header Rewrite'), // 7 - !ads || rulesReplacement ? emptyPromise(onPgs) : getAutoRules(pu.hostname, onPgs, '成功取回MITM Hostname'), // 8 - ] - - // 获取RULE-SET - let ruleSets = [] - if (!testflight) { - ruleSets = advanceSettings.customSettings.split(/[\r\n]/g).map(i => { - if (/^RULE-SET\s*,\s*(.*?)\s*,\s*(.*)/.test(i)) { - return { - url: RegExp.$1, - policy: RegExp.$2 - } - } - return null - }).filter(i => i) - } - console.log('ruleSets', ruleSets); - - promiseArray = promiseArray.concat(ruleSets.map(i => getAutoRules(i.url))) - - Promise.all(promiseArray).then(v => { - prototype = v[0] - if (rulesReplacement) { - let repRules = v[1].match(filePartReg('Rule')) - let repHost = v[1].match(filePartReg('Host')) - let repUrlRewrite = v[1].match(filePartReg('URL Rewrite')) - let repHeaderRewrite = v[1].match(filePartReg('Header Rewrite')) - let repHostName = v[1].match(/hostname\s*=\s*(.*?)[\n\r]/) - repRules && repRules[1] && (v[1] = repRules[1]) - repHost && repHost[1] && (v[5] = repHost[1]) - repUrlRewrite && repUrlRewrite[1] && (v[6] = '[URL Rewrite]\n' + repUrlRewrite[1]) - repHeaderRewrite && repHeaderRewrite[1] && (v[8] = '[Header Rewrite]\n' + repHeaderRewrite[1]) - repHostName && repHostName[1] && (v[9] = repHostName[1]) - } - - if (isQuan && !rulesReplacement && /\[TCP\]([\s\S]*)\/\/ Detect local network/.test(v[3])) { - let tcpRules = `${v[4]}\n${RegExp.$1}`.split(/[\n\r]+/g) - if (!ads) { - tcpRules = tcpRules.filter(i => !/^.*?,\s*REJECT\s*$/.test(i)) - } - let surgeLan = v[1].split(/[\r\n]/g).filter(i => /.*?,\s*DIRECT/.test(i)) - tcpRules = tcpRules.map(r => { - if (surgeLan.indexOf(r) > -1) return r - r = r.replace(/(^.*?,.*?,\s*)选择YouTube Music的策略(.*$)/, '$1🍃 Proxy$2') - r = r.replace(/(^.*?,.*?,\s*)选择TVB\/Viu的策略(.*$)/, '$1🍃 Proxy$2') - r = r.replace(/(^.*?,.*?,\s*)选择Vidol的策略(.*$)/, '$1🍃 Proxy$2') - r = r.replace(/(^.*?,.*?,\s*)选择Hulu的策略(.*$)/, '$1🍃 Proxy$2') - r = r.replace(/(^.*?,.*?,\s*)选择Spotify的策略(.*$)/, '$1🍃 Proxy$2') - r = r.replace(/(^.*?,.*?,\s*)选择Google的策略,不懂就不选(.*$)/, '$1🍃 Proxy$2') - r = r.replace(/(^.*?,.*?,\s*)选择微软服务的策略,不懂就选择DIRECT(.*$)/, '$1🍂 Domestic$2') - r = r.replace(/(^.*?,.*?,\s*)选择PayPal的策略,不懂就选择DIRECT(.*$)/, '$1🍂 Domestic$2') - r = r.replace(/(^.*?,.*?,\s*)选择Apple的策略,不懂就选择DIRECT(.*$)/, '$1🍎 Only$2') - r = r.replace(/(^.*?,.*?,\s*)选择Netflix的策略,不懂就不选(.*$)/, '$1🍃 Proxy$2') - r = r.replace(/(^.*?,.*?,\s*)选择国外流媒体的策略(.*$)/, '$1🍃 Proxy$2') - r = r.replace(/(^.*?,.*?,\s*)DIRECT(.*$)/i, '$1🍂 Domestic$2') - r = r.replace(/(^.*?,.*?,\s*)PROXY(.*$)/i, '$1🍃 Proxy$2') - r = r.replace(/^DOMAIN(.*?)🍃 Proxy\s*$/, 'DOMAIN$1🍃 Proxy,force-remote-dns') - return r - }) - v[1] = tcpRules.join('\n') - v[2] = '' - v[3] = '' - v[4] = '' - v[7] = v[7].replace(/hostname = /, '# hostname = ') - } - - if (testflight && !rulesReplacement) { - let autoNewPrefix = 'https://raw.githubusercontent.com/lhie1/Rules/master/Surge/Surge%203/Provider' - v[1] = `RULE-SET,SYSTEM,DIRECT\nRULE-SET,${autoNewPrefix}/Apple.list,🍎 Only` - v[2] = ads ? `RULE-SET,${autoNewPrefix}/Reject.list,REJECT` : '' - v[3] = `RULE-SET,${autoNewPrefix}/AsianTV.list,🍂 Domestic\nRULE-SET,${autoNewPrefix}/GlobalTV.list,🍃 Proxy\nRULE-SET,${autoNewPrefix}/Proxy.list,🍃 Proxy` - v[4] = `RULE-SET,${autoNewPrefix}/Domestic.list,🍂 Domestic\nRULE-SET,LAN,DIRECT` - } - - rules += `\n${v[1]}\n${v[2].replace(/REJECT/g, surge2 || isQuan ? "REJECT" : "REJECT-TINYGIF")}\n${v[3]}\n${v[4]}\n` - host = v[5] - urlRewrite += v[6] - urlReject += v[7] - headerRewrite = v[8] - hostName = v[9].split('\n') - - let seperateLines = function (content, rules = false) { - let addRules = content.split('\n').filter(i => !/^-/.test(i)).map(i => i.trim()) - if (rules && !testflight && promiseArray.length > 10) { - addRules = addRules.filter(i => !/^\s*RULE-SET/.test(i)) - for (let i = 10; i < promiseArray.length; i++) { - let policy = ruleSets[i - 10].policy - addRules = addRules.concat(v[i].split(/[\r\n]/g).map(i => { - console.log('i', i); - if (/^(.+?),(.+?),(.+)$/.test(i)) { - return `${RegExp.$1 + ',' + RegExp.$2},${policy},${RegExp.$3}${!testflight ? ',force-remote-dns' : ''}` - }else if (/^(.+?),(.+?)(?=$|\/\/|\#)/.test(i)) { - return `${RegExp.$1},${RegExp.$2},${policy}${!testflight ? ',force-remote-dns' : ''}` - } - return i - })) - } - } - console.log('adru', addRules) - - let res = { - add: addRules, - delete: content.split("\n").filter(i => /^-/.test(i)).map(i => i.replace(/^-/, '').trim()) - } - return res - } - - let prettyInsert = function (lines) { - return '\n\n' + lines.join('\n') + '\n\n' - } - - // 配置代理分组 - if (advanceSettings.proxyGroupSettings) { - let pgs = advanceSettings.proxyGroupSettings - rename = pgs.match(/\/\/\s*rename\s*:\s*(.*?)(?:\n|\r|$)/) - pgs = pgs.replace(/Proxy Header/g, proxyHeaders) - for (let name in customProxyGroup) { - let nameReg = new RegExp(`,\\s*${name}`, 'g') - let serverNames = customProxyGroup[name] - serverNames = serverNames.filter(i => proxyNameLegal(i)) - pgs = pgs.replace(nameReg, ',' + (serverNames.join(',') || flatServerData.map(i => i.proxyName.text).join(','))) - } - prototype = prototype.replace(/\[Proxy Group\][\s\S]+\[Rule\]/, pgs + '\n\n[Rule]') - } else { - prototype = prototype.replace(/Proxy Header/g, proxyHeaders) - prototype = prototype.replace(/ProxyHeader/g, customProxyGroup[PROXY_HEADER].filter(i => proxyNameLegal(i)).join(',') || flatServerData.map(i => i.proxyName.text).join(',')) - } - // 配置常规设置 - if (advanceSettings.generalSettings) { - prototype = prototype.replace(/\[General\][\s\S]+\[Proxy\]/, advanceSettings.generalSettings + '\n\n[Proxy]') - } - // 配置自定义规则 - let customRules = seperateLines(advanceSettings.customSettings, true) - let rulesList = rules.split(/[\r\n]/g) - let deleteList = customRules.add.map(i => { - if (/^(.*?),(.*?),/.test(i)) { - let type = RegExp.$1 - let content = RegExp.$2 - return `${type},${content}` - } - }) - rules = rulesList.filter(i => deleteList.findIndex(d => i.startsWith(d)) === -1).join('\n') - customRules.delete.forEach(i => rules = rules.replace(i, '')) - // 配置本地DNS映射 - let userHost = seperateLines(advanceSettings.hostSettings) - userHost.delete.forEach(i => host = host.replace(i, '')) - // 配置URL重定向 - let userUrl = seperateLines(advanceSettings.urlrewriteSettings) - userUrl.delete.forEach(i => { - urlRewrite = urlRewrite.replace(i, '') - urlReject = urlReject.replace(i, '') - }) - // 配置Header修改 - let userHeader = seperateLines(advanceSettings.headerrewriteSettings) - userHeader.delete.forEach(i => headerRewrite = headerRewrite.replace(i, '')) - // 配置SSID - let userSSID = advanceSettings.ssidSettings - // 配置MITM的Hostname - let userHostname = seperateLines(advanceSettings.hostnameSettings) - userHostname.delete.forEach(i => { - if (hostName.indexOf(i) >= 0) { - hostName.splice(hostName.indexOf(i), 1) - } - }) - - function ssr2ss(proxies) { - let proxyList = proxies.split(/\n/); - let res = proxyList.map(proxy => { - if (/=\s*shadowsocksr/.test(proxy)) { - return proxy.replace(/=\s*shadowsocksr/g, '= custom').replace(/"/g, '').replace(/,\s*(protocol|protocol_param|obfs|obfs_param)[^,$]+/g, '') + ', https://github.com/lhie1/Rules/blob/master/SSEncrypt.module?raw=true' - } else { - return proxy - } - }) - return res.join('\n') - } - - // if (isQuan) { - // prototype = prototype.replace(/\/\/ Detect local network/, `${prettyInsert(customRules.add)}\n`) - // } else { - prototype = prototype.replace('# Custom', prettyInsert(customRules.add)) - // } - prototype = prototype.replace('Proxys', isQuan ? proxies : ssr2ss(proxies)) - if (rulesReplacement) { - prototype = prototype.replace(/\[Rule\][\s\S]*FINAL\s*,[^\r\n]+/, `[Rule]\n${prettyInsert(customRules.add)}\n${rules}\n`) - } else { - prototype = prototype.replace('# All Rules', rules) - } - prototype = prototype.replace('# Host', "[Host]\n" + host + prettyInsert(userHost.add)) - prototype = prototype.replace('# URL Rewrite', urlRewrite.replace(/307/g, surge2 ? '302' : '307') + prettyInsert(userUrl.add)) - prototype = prototype.replace('# URL REJECT', urlReject) - prototype = prototype.replace('# SSID', '[SSID Setting]\n' + userSSID) - prototype = prototype.replace('# Header Rewrite', headerRewrite + prettyInsert(userHeader.add)) - //fix by shenqinci 2019年03月20日:当只有userHostName时,配置文件出现第一行为空的问题 - let finalHostNames = hostName.concat(userHostname.add).filter(i => i).join(', ') - if (finalHostNames !== '') { - prototype = prototype.replace('// Hostname', 'hostname = ' + finalHostNames) - } - - if (isMitm) { - prototype = prototype.replace('# MITM', advanceSettings.mitmSettings) - } else { - prototype = prototype.replace(/\[MITM\][\s\S]*$/, '') - } - - function genQuanPolices(content) { - let items = content.split(/[\n\r]+/).filter(i => i !== '' && !/^\/\//.test(i)).map(sta => { - let matcher = sta.match(/^(.*?)=(.*?),(.*?)$/); - if (/^(.*?)=(.*?),(.*?)$/.test(sta)) { - let pName = RegExp.$1 - let pType = RegExp.$2 - let pNodes = RegExp.$3 - let data = pNodes.split(/,/g) - if (/url-test/.test(pType) || /fallback/.test(pType)) { - let v = data.filter(i => !/(?:url|interval|tolerance|timeout)\s*=\s*/.test(i)) - return { - name: pName, - sta: ' auto', - data: v - } - } else if (/select/.test(pType)) { - return { - name: pName, - sta: pType.replace(/select/, 'static'), - data: data - } - } else if (/round-robin/.test(pType)) { - return { - name: pName, - sta: 'balance, round-robin', - data: data - } - } else { - return { - name: pName, - sta: 'ssid', - data: data - } - } - } else { - return null - } - }).filter(i => i !== null) - items.push({ - name: '🚀 Direct', - sta: 'static', - data: ["DIRECT"] - }) - let policies = items.map(i => { - if (i.sta.contains('auto') || i.sta.contains('balance, round-robin')) { - return `${i.name} : ${i.sta}\n${i.data.join('\n')}` - } else if (i.sta.contains('static')) { - return `${i.name} : ${i.sta}, ${i.data[0]}\n${i.data.join('\n')}` - } else if (i.sta === 'ssid') { - let wifi = i.data.find(i => /default\s*=/.test(i)) - let cellular = i.data.find(i => /cellular\s*=/.test(i)) || 'cellular = DIRECT' - let left = i.data.filter(i => i !== wifi && i !== cellular).map(i => { - let p = i.split('=') - return p[0].replace(/"/g, '') + '=' + p.slice(1).join('=') - }) - return `${i.name} : ${wifi.replace(/default\s*=/, 'wifi =')}, ${cellular}\n${left.join('\n')}` - } - }) - return policies.map(i => { - if (rename && rename[1]) { - i = globalRename(rename, i) // 圈特殊性 - } - return $text.base64Encode(i) - }) - } - - function seperateRejection(reject) { - let lines = reject.split(/[\r\n]+/) - let res = { reject: [], rewrite: []} - lines.forEach(l => { - if (/(.*?\s+\-\s+reject)/.test(l)) { - res.reject.push(RegExp.$1) - } else if (/(.*?\s+url\s(302|307|modify|simple\-response)\s.*$)/.test(l)) { - res.rewrite.push(RegExp.$1) - } - }) - return res - } - - function genQuanRewrite(content) { - let items = content.split(/[\n\r]+/).filter(i => i !== '' && /^(?!\/\/|#)/.test(i)).map(i => { - if (/^(.*?)\s+(.*?)\s+(.*?)\s*$/.test(i)) { - let type = RegExp.$3 - return `${RegExp.$1} url ${type === 'header' ? 'modify' : type} ${RegExp.$2}` - } - return '' - }).join('\n') - return items - } - - function genQuanRewriteTinyPng(reject, rewrite) { - let rejects = reject.split(/[\n\r]/g).filter(i => /.*?\s*-\s*reject/.test(i)).map(i => i.replace(/(.*?)\s*-\s*reject\s*$/, '$1')) - let items = rejects.map(i => `${i} url simple-response SFRUUC8xLjEgMjAwIE9LDQpTZXJ2ZXI6IG5naW54DQpDb250ZW50LVR5cGU6IGltYWdlL3BuZw0KQ29udGVudC1MZW5ndGg6IDU2DQpDb25uZWN0aW9uOiBjbG9zZQ0KDQqJUE5HDQoaCgAAAA1JSERSAAAAAQAAAAEIBgAAAB8VxIkAAAALSURBVHicY2AAAgAABQABel6rPw==`) - items = items.concat(rewrite.split(/[\n\r]+/).filter(i => i !== '' && /^(?!\/\/|#)/.test(i)).map(i => { - if (/^(.*?)\s+(.*?)\s+(.*?)\s*$/.test(i)) { - let type = RegExp.$3 - return `${RegExp.$1} url ${type === 'header' ? 'modify' : type} ${RegExp.$2}` - } - return '' - })) - return items.join('\n') - } - - function genQuanPart(name, content) { - return `\n[${name}]\n${content}\n` - } - - if (isQuan) { - prototype = prototype.replace(/☁️ Others, dns-failed/, '☁️ Others') - let proxyGroup = prototype.match(filePartReg('Proxy Group')) - if (proxyGroup && proxyGroup[1]) { - let policies = genQuanPolices(proxyGroup[1]) - prototype += genQuanPart('POLICY', policies.join('\n')) - } - userUrl.add.forEach(i => { - // if (/reject\s*$/.test(i)) { - // urlReject += `\n${i}\n` - // } else { - // urlRewrite += `\n${i}\n` - // } - let rule = i - if (/(.*?)\s+(.*?)\s+(307|302|header|reject)\s*$/.test(i)) { - if (RegExp.$3 === 'reject') { - rule = i - } else if (RegExp.$3 === 'header') { - rule = `${RegExp.$1} url modify ${RegExp.$2}` - } else { - rule = `${RegExp.$1} url ${RegExp.$3} ${RegExp.$2}` - } - } - urlReject = `\n${rule}\n${urlReject}` - }) - let quanRe = seperateRejection(urlReject) - prototype += genQuanPart('URL-REJECTION', quanRe.reject.join('\n')) - prototype += genQuanPart('REWRITE', quanRe.rewrite.join('\n')) - // prototype += genQuanPart('REWRITE', genQuanRewriteTinyPng(urlReject, urlRewrite)) - prototype += genQuanPart('HOST', host + prettyInsert(userHost.add)) - let sourceType = 'false, true, false'; - let sourceTypeParam = proxySuffix.find(x => /\s*source-type\s*=\s*[0-7]\s*(?:,|$)/.test(x)) - if (sourceTypeParam) { - let type = sourceTypeParam.match(/\s*source-type\s*=\s*([0-7])/)[1] * 1; - sourceType = `${type & 4 ? 'true' : 'false'}, ${type & 2 ? 'true' : 'false'}, ${type & 1 ? 'true' : 'false'}` - } - console.log(serverEditorData) - prototype += genQuanPart('SOURCE', serverEditorData.filter(i => { - // let isSSR = i.rows.find(l => /^.*?=\s*(?=shadowsocksr|vmess)/.test(l.proxyLink)) - // return isSSR !== undefined - return i.rows.find(i => i.proxyType > 0) - }).map(i => { - return `${i.title}, server, ${i.url}, ${sourceType}, ${i.title}` - }).join('\n') + (rulesReplacement ? "" : "\nlhie1, filter, https://raw.githubusercontent.com/lhie1/Rules/master/Quantumult/Quantumult.conf, true\nlhie1_extra, filter, https://raw.githubusercontent.com/lhie1/Rules/master/Quantumult/Quantumult_Extra.conf, true\nlhie1, blacklist, https://raw.githubusercontent.com/lhie1/Rules/master/Quantumult/Quantumult_URL.conf, true\n")) - let customDNS = prototype.match(/dns-server\s*=\s*(.*?)(?:\n|\r|$)/) - if (customDNS && customDNS[1]) { - prototype += genQuanPart('DNS', customDNS[1]) - } - let widgetProxies = customProxyGroup['WidgetHeader'] || null - if (widgetProxies) { - widgetProxies = widgetProxies.filter(i => proxyNameLegal(i)) - prototype += genQuanPart('BACKUP-SERVER', widgetProxies.join('\n')) - } - prototype = prototype.replace(/\[SSID Setting\]/, "[SUSPEND-SSID]").replace(/\ssuspend=true/g, '') - } - - if (rename && rename[1]) { - prototype = globalRename(rename, prototype); - } - - let fn = (workspace.fileName || 'lhie1') + '.conf' - - let exportTarget = 0 - - if (surge2) { - exportTarget = 1 - } - - if (isQuan) { - exportTarget = 2 - } - - if ('onDone' in params) { - ruleUpdateUtil.getGitHubFilesSha({ - handler: sha => { - if (sha) { - ruleUpdateUtil.setFilesSha(sha) - } - params.onDone({ - target: exportTarget, - actionSheet: isActionSheet, - fileName: fn, - fileData: prototype - }) - } - }) - } - }).catch(e => { - console.error(e.stack) - }) - } catch (e) { - console.error(e.stack) - 'onError' in params && params.onError(e) - } - - function globalRename(rename, prototype) { - let renamePat = rename[1].split(/\s*,\s*/g).filter(i => i.indexOf('=') > -1).map(i => { - let sp = i.reverse().split(/\s*=(?!\\)\s*/g); - return sp.map(i => i.reverse().trim().replace(">", ',')).reverse(); - }); - console.log(renamePat) - renamePat.forEach(i => { - let oldName = i[0]; - let newName = i[1].replace(/\\=/g, '='); - let oldNameReg = new RegExp(oldName, 'g'); - prototype = prototype.replace(oldNameReg, newName); - }); - return prototype; - } -} - -function getRulesReplacement(content = '') { - let advanceSettings = content ? content : JSON.parse($file.read(FILE).string) - if (advanceSettings.customSettings) { - let cs = advanceSettings.customSettings; - let pat = cs.match(/\/\/\s*replacement\s*:\s*(.*?)(?:\n|\r|$)/); - if (pat && pat[1]) { - return pat[1]; - } - } - return null; -} - -function exportConf(fileName, fileData, exportTarget, actionSheet, isAuto, actionSheetCancel) { - let surge3 = exportTarget === 0 - let surge2 = exportTarget === 1 - let isQuan = exportTarget === 2 - if (surge2 || surge3) { - let fnReg = /^[\x21-\x2A\x2C-\x2E\x30-\x3B\x3D\x3F-\x5B\x5D\x5F\x61-\x7B\x7D-\x7E]+$/ - if (actionSheet || !fnReg.test(fileName)) { - $share.sheet({ - items: [fileName, $data({ "string": fileData })], - handler: success => { - if (!success && actionSheetCancel) { - actionSheetCancel() - } - } - }) - } else { - if (!$file.exists("confs")) { - $file.mkdir("confs") - } else { - $file.list('confs').forEach(i => $file.delete('confs/' + i)) - } - $file.write({ - data: $data({ "string": fileData }), - path: `confs/${fileName}` - }) - $http.startServer({ - path: "confs/", - handler: res => { - let serverUrl = `http://127.0.0.1:${res.port}/` - $http.get({ - url: serverUrl + "list?path=", - handler: function (resp) { - if (resp.response.statusCode == 200) { - let surgeScheme = `surge${surge2 ? "" : "3"}:///install-config?url=${encodeURIComponent(serverUrl + "download?path=" + fileName)}` - $app.openURL(surgeScheme) - $delay(10, () => { - $http.stopServer() - if (isAuto) { - $app.close() - } - }) - } else { - $ui.alert("内置服务器启动失败,请重试") - } - } - }) - } - }) - } - } else if (isQuan) { - if (actionSheet) { - $share.sheet({ - items: [fileName, $data({ "string": fileData })], - handler: success => { - if (!success && actionSheetCancel) { - actionSheetCancel() - } - } - }) - } else { - $clipboard.text = fileData - $app.openURL("quantumult://settings?configuration=clipboard&autoclear=1") - } - } - - function genServerFiles(name, data) { - $file.write({ - data: $data({ "string": data }), - path: `confs/${name}` - }); - } -} - -function urlsaveBase64Encode(url) { - return $text.base64Encode(url).replace(/\+/g, '-').replace(/\\/g, '_').replace(/=/g, '') -} - -module.exports = { - renderUI: renderUI, - setUpWorkspace: setUpWorkspace, - autoGen: autoGen, - getRulesReplacement: getRulesReplacement -} diff --git a/JSBox/Rules-lhie1/scripts/colorUtil.js b/JSBox/Rules-lhie1/scripts/colorUtil.js deleted file mode 100644 index b1ecbb4..0000000 --- a/JSBox/Rules-lhie1/scripts/colorUtil.js +++ /dev/null @@ -1,60 +0,0 @@ -/* - -提示:自定义颜色请建立_custom/color.js文件以覆盖默认颜色, -格式: - -module.exports = { - editorItemText: "tint", - editorItemIcon: "tint", -} - -*/ - -const DEFAULT = { - statusBar: "#000000", // 状态栏文字颜色,#ffffff为白色,clear隐藏,其他为黑色 - navBar: "#ffffff", // 导航栏颜色 - navTitleText: "tint", // 标题栏文字颜色 - navIconLoading: "tint", // 加载图标颜色 - navIconLeft: "tint", // 标题栏红包按钮文字颜色 - navIconRight: "tint", // 标题栏备份按钮文字颜色 - importBtnText: "tint", // 导入按钮文字颜色 - controlBtnText: "#000000", // 操作栏文字颜色 - editorItemText: "tint", // 服务器列表文字颜色 - editorItemIcon: "tint", // 服务器列表图标颜色 - outputFormatText: "tint", // 输出格式文字颜色 - usualBtnOnBg: "#ff6666", // 常规选项按钮开启背景色 - usualBtnOnFg: "#ffffff", // 常规选项按钮开启前景色 - usualBtnOffBg: "#ffffff", // 常规选项按钮关闭背景色 - usualBtnOffFg: "#000000", // 常规选项按钮关闭前景色 - advanceBtnBg: "#808080", // 进阶按钮背景色 - advanceBtnFg: "#ffffff", // 进阶按钮前景色 - aboutBtnBg: "#808080", // 关于按钮背景色 - aboutBtnFg: "#ffffff", // 关于按钮前景色 - genBtnBg: "tint", // 生成按钮背景色 - genBtnFg: "#ffffff", // 生成按钮前景色 - advanceGridOnBg: "#ffda40", // 进阶设置网格选中背景色 - advanceGridOnFg: "#034769", // 进阶设置网格选中前景色 - advanceGridOffBg: "#63add0", // 进阶设置网格默认背景色 - advanceGridOffFg: "#ffffff", // 进阶设置网格默认前景色 -} - -const customColor = $file.exists("_custom/color.js") ? require('_custom/color.js') : {} - -function isEqual(color1, color2) { - return color1.runtimeValue().invoke('isEqual', color2) -} - -function getColor(name, hex = false) { - let resColor = "tint" - if (name in customColor) { - resColor = customColor[name] - } else if (name in DEFAULT) { - resColor = DEFAULT[name] - } - return hex ? resColor : $color(resColor) -} - -module.exports = { - isEqual: isEqual, - getColor: getColor -} \ No newline at end of file diff --git a/JSBox/Rules-lhie1/scripts/extension.js b/JSBox/Rules-lhie1/scripts/extension.js deleted file mode 100644 index 92ebb9d..0000000 --- a/JSBox/Rules-lhie1/scripts/extension.js +++ /dev/null @@ -1,325 +0,0 @@ -const app = require('scripts/app') - -const FILE = 'data.js' - -let screenHeight = $device.info.screen.height -const screenWidth = $device.info.screen.width - -const iPhoneX = screenWidth == 375 && screenHeight == 812 -if (iPhoneX) { - screenHeight -= 48 -} - -let renderExtensionUI = function () { - const host = $context.safari.items.location.hostname - $ui.render({ - props: { - title: "增加规则" - }, - views: [{ - type: "scroll", - props: { - id: "mainScrollView", - bgcolor: $color("#f0f5f5") - }, - layout: $layout.fill, - views: [{ - type: "label", - props: { - text: "当前网页路径" - }, - layout: (make, view) => { - make.width.equalTo(view.super) - make.left.equalTo(5) - make.height.equalTo(30) - make.top.equalTo(view.super.top).offset(10) - } - }, { - type: "text", - props: { - editable: false, - text: $context.safari.items.baseURI - }, - layout: (make, view) => { - make.top.equalTo(view.prev.bottom).offset(5) - make.width.equalTo(view.super) - make.height.equalTo(60) - } - }, { - type: "label", - props: { - text: "规则匹配项" - }, - layout: (make, view) => { - make.width.equalTo(view.super) - make.left.equalTo(5) - make.height.equalTo(30) - make.top.equalTo(view.prev.bottom).offset(10) - } - }, { - type: "list", - props: { - rowHeight: 60, - id: "styleList", - template: { - views: [{ - type: "label", - props: { - id: "styleName", - font: $font("bold", 16) - }, - layout: (make, view) => { - make.width.equalTo(view.super) - make.height.equalTo(view.super).dividedBy(2) - make.left.equalTo(view.super.left).offset(15) - make.top.equalTo(view.super.top).offset(5) - } - }, { - type: "label", - props: { - id: "styleValue", - }, - layout: (make, view) => { - make.width.equalTo(view.super) - make.height.equalTo(view.super).dividedBy(2) - make.left.equalTo(view.super.left).offset(15) - make.top.equalTo(view.prev.bottom).offset(-10) - } - }, { - type: "image", - props: { - id: "styleSelected", - bgcolor: $color("#ffffff") - }, - layout: (make, view) => { - make.centerY.equalTo(view.super) - make.height.width.equalTo(20) - make.right.equalTo(view.super.right).offset(-20) - } - }] - } - }, - layout: (make, view) => { - make.top.equalTo(view.prev.bottom).offset(5) - make.width.equalTo(view.super) - make.height.equalTo(0) - }, - events: { - didSelect: (sender, indexPath, data) => { - let uiData = sender.data.map((i, idx) => { - return { - styleName: i.styleName, - styleValue: i.styleValue, - styleSelected: { data: null } - } - }) - uiData[indexPath.row].styleSelected = { data: $file.read("assets/selected_icon.png") } - sender.data = uiData - sender.info = indexPath.row - } - } - }, { - type: "label", - props: { - text: "选择代理" - }, - layout: (make, view) => { - make.width.equalTo(view.super) - make.left.equalTo(5) - make.height.equalTo(30) - make.top.equalTo(view.prev.bottom).offset(10) - } - }, { - type: "list", - props: { - id: "proxyList", - rowHeight: 40, - template: { - views: [{ - type: "label", - props: { - id: "proxyName" - }, - layout: (make, view) => { - make.centerY.equalTo(view.super) - make.width.equalTo(view.super).offset(-80) - make.height.equalTo(view.super) - make.left.equalTo(view.super.left).offset(15) - } - }, { - type: "image", - props: { - id: "proxySelected", - bgcolor: $color("#ffffff") - }, - layout: (make, view) => { - make.centerY.equalTo(view.super) - make.height.width.equalTo(20) - make.right.equalTo(view.super.right).offset(-20) - } - }] - } - }, - layout: (make, view) => { - make.top.equalTo(view.prev.bottom).offset(5) - make.width.equalTo(view.super) - make.height.equalTo(0) - }, - events: { - didSelect: (sender, indexPath, data) => { - let uiData = sender.data.map((i, idx) => { - return { - proxyName: i.proxyName, - proxySelected: { data: null } - } - }) - uiData[indexPath.row].proxySelected = { data: $file.read("assets/selected_icon.png") } - sender.data = uiData - sender.info = indexPath.row - } - } - }, { - type: "label", - props: { - text: "添加规则", - align: $align.center, - bgcolor: $color("#fff") - }, - layout: (make, view) => { - make.width.equalTo(view.super) - make.height.equalTo(40) - make.top.equalTo(view.prev.bottom).offset(20) - }, - events: { - tapped: sender => { - if ($("styleList").info !== null && $("proxyList").info !== null) { - let styleName = $("styleList").data[$("styleList").info].styleName.text - let styleValue = $("styleList").data[$("styleList").info].styleValue.text - let proxy = $("proxyList").data[$("proxyList").info].proxyName.text - let rule = [styleName, styleValue, proxy].join(',') - saveRule(rule) - $context.close() - } else { - $ui.alert("请选择匹配项和代理") - } - } - } - }] - }] - }) - let styles = genStyleDefaultData(host) - let styleListHeight = styles.length * 60 - $("styleList").data = styles - $("styleList").updateLayout(make => { - make.height.equalTo(styleListHeight) - }) - let savedData = JSON.parse($file.read(FILE).string) - let proxyGroup = savedData.proxyGroupSettings.split('\n').filter(i => /^(?!\/|#)[\s\S]+=/.test(i)).map(i => i.split(/[\s]*=/)[0]) - let flatServerData = savedData.workspace.serverData.reduce((all, cur) => { - return { - rows: all.rows.concat(cur.rows) - } - }).rows - let proxies = ['🚀 Direct'].concat(proxyGroup, ['REJECT', 'REJECT-TINYGIF'], flatServerData.map(i => i.proxyName.text)) - let proxiesData = genProxyDefaultData(proxies) - let proxiesListHeight = proxiesData.length * 40 - $("proxyList").data = proxiesData - $("proxyList").updateLayout(make => { - make.height.equalTo(proxiesListHeight) - }) - resizeScrollView(styleListHeight + proxiesListHeight) - -} - -let resizeScrollView = function (listHeight) { - $("mainScrollView").contentSize = $size(screenWidth, 350 + listHeight) -} - -let genStyleDefaultData = function (domain) { - let dp = domain.split('.') - let res = [] - res.push({ - styleName: { text: 'DOMAIN' }, - styleValue: { text: domain } - }) - return res.concat(dp.map((item, idx, obj) => { - return { - styleName: { text: 'DOMAIN-SUFFIX' }, - styleValue: { text: obj.slice(idx).join('.') } - } - })) -} - -let saveRule = function (rule) { - let data = JSON.parse($file.read(FILE).string) - data.customSettings += `\n${rule}\n` - $file.write({ - data: $data({ "string": JSON.stringify(data) }), - path: FILE - }) -} - -let genProxyDefaultData = function (proxies) { - return proxies.map(i => { - return { - proxyName: { text: i } - } - }) -} - -function collectRules() { - let confFile = $context.data.string - let surgeReg = /\[Rule\]\n([\s\S]+)\n# Custom/ - let quanReg = /\[SERVER\]\n([\s\S]+)\n\[SOURCE\]/ - if (surgeReg.test(confFile)) { - let matcher = confFile.match(surgeReg) - if (matcher.length === 2) { - let rules = matcher[1] - saveRule(rules) - } - $context.close() - } else if (quanReg.test(confFile)) { - let matcher = confFile.match(quanReg); - let serversRaw = matcher[1] - let servers = serversRaw.split(/[\r\n]+/).filter(i => /.*?=/.test(i)) - let serverDataItem = { - title: "Quantumult导出节点", - url: "", - rows: servers.map(server => { - return { - proxyLink: server, - proxyName: { - bgcolor: false, - text: server.split(/=/)[0].trim() - } - } - }) - } - let file = JSON.parse($file.read(FILE).string); - let workspace = file.workspace; - let serverData = workspace.serverData; - serverData.unshift(serverDataItem); - let success = $file.write({ - data: $data({ "string": JSON.stringify(file) }), - path: FILE - }) - $ui.alert({ - title: "导入" + success ? '成功': '失败', - message: success ? `已经成功导入${serverDataItem.rows.length}个服务器至脚本,请重启脚本查看` : '文件格式有误', - actions: [{ - title: 'OK', - handler: () => { - $context.close() - } - }] - }); - } else { - $ui.alert("分享文件不合法") - } -} - - -module.exports = { - renderExtensionUI: renderExtensionUI, - collectRules: collectRules -} \ No newline at end of file diff --git a/JSBox/Rules-lhie1/scripts/filenameUtil.js b/JSBox/Rules-lhie1/scripts/filenameUtil.js deleted file mode 100644 index 9508d51..0000000 --- a/JSBox/Rules-lhie1/scripts/filenameUtil.js +++ /dev/null @@ -1,23 +0,0 @@ -const knownURLs = [ - {domain: 'api.rixcloud.io', name: 'rixCloud'}, - {domain: 'dler.cloud', name: 'Dler Cloud'} -] - -function getConfName(url) { - let matchConst = knownURLs.find(i => url.indexOf(i.domain) > -1) - if (matchConst) { - return matchConst.name - } else { - let path = url.split('?')[0].split('/') - let filename = path[path.length - 1] - if (filename.indexOf('.conf') == filename.length - 5) { - return filename.substring(0, filename.length - 5) - } else { - return filename - } - } -} - -module.exports = { - getConfName: getConfName -} \ No newline at end of file diff --git a/JSBox/Rules-lhie1/scripts/init.js b/JSBox/Rules-lhie1/scripts/init.js deleted file mode 100644 index 7e8e60d..0000000 --- a/JSBox/Rules-lhie1/scripts/init.js +++ /dev/null @@ -1,21 +0,0 @@ -function asyncInitialize() { - updateSpecialReg() -} - -function updateSpecialReg() { - $http.download({ - showsProgress: false, - url: "https://raw.githubusercontent.com/Fndroid/specialReg/master/specialReg.js?t=" + new Date().getTime() - }).then(resp => { - if (resp.response.statusCode === 200) { - let success = $file.write({ - data: resp.data, - path: "scripts/videoReg.js" - }); - } - }) -} - -module.exports = { - asyncInitialize: asyncInitialize -} \ No newline at end of file diff --git a/JSBox/Rules-lhie1/scripts/proxyUitl.js b/JSBox/Rules-lhie1/scripts/proxyUitl.js deleted file mode 100644 index a158f7a..0000000 --- a/JSBox/Rules-lhie1/scripts/proxyUitl.js +++ /dev/null @@ -1,318 +0,0 @@ -const filenameUtil = require('scripts/filenameUtil') - -String.prototype.strictTrim = function () { - let trimed = this.trim() - if ((matcher = trimed.match(/([\s\S]+),$/)) !== null) { - return matcher[1] - } - return trimed -} - -function urlsafeBase64Encode(url) { - return $text.base64Encode(url).replace(/\-/g, '+').replace(/\\/g, '_').replace(/=+$/, '') -} - -function urlsafeBase64Decode(base64) { - // Add removed at end '=' - base64 += Array(5 - base64.length % 4).join('='); - base64 = base64 - .replace(/\-/g, '+') // Convert '-' to '+' - .replace(/\_/g, '/'); // Convert '_' to '/' - return $text.base64Decode(base64).replace(/\u0000/, ''); -} - -function promiseConf(url) { - return new Promise((resolve, reject) => { - $http.get({ - url: url, - header: { - 'User-Agent': 'Surge/1174 CFNetwork/962 Darwin/18.0.0' - }, - handler: function (resp) { - let data = resp.data + '' - let filename = url - try { - let matcher = resp.response.runtimeValue().invoke('allHeaderFields').rawValue()["Content-Disposition"].match(/filename="?(.*?)(?:.conf|"|$)/) - filename = matcher[1] - } catch (e) { - filename = filenameUtil.getConfName(url) - } - // 兼容不规范ssr链接 - let noPaddingData = data - let padding = noPaddingData.length % 4 == 0 ? 0 : 4 - noPaddingData.length % 4 - for (let i = 0; i < padding; i++) { - noPaddingData += '=' - } - let decodedData = $text.base64Decode(data) || $text.base64Decode(noPaddingData) - if (/\[Proxy\]([\s\S]*?)\[Proxy Group\]/.test(data)) { - // Surge托管 - resolve({ - servers: RegExp.$1, - filename: filename, - type: 0 - }) - } else if (/^(ssr|ss|vmess):\/\//.test(decodedData)) { - let rawLinks = decodedData.split(/[\n\r\|\s]+/g).filter(i => i !== '' && /^(ssr|ss|vmess):\/\//.test(i)); - let output = rawLinks.map(i => { - if (/^ssr:\/\//.test(i)) { - let res = decodeSSR([i]) - return res.servers - } else if (/^ss:\/\//.test(i)) { - let res = decodeScheme([i]) - return res.servers - } else { - let res = decodeVmess([i]) - return res.servers - } - }) - resolve({ - servers: output.reduce((p, c) => { - return p.concat(c) - }, []).join('\n'), - filename: getDomain(url), - type: 4 - }) - } else if (/^ssr:\/\//.test(decodedData)) { - // SSR订阅 - let rawLinks = decodedData.split(/[\n\r\|\s]+/g).filter(i => i !== '' && /^ssr:\/\//.test(i)); - let res = decodeSSR(rawLinks); - resolve({ - servers: res.servers.join('\n'), - filename: res.sstag || filename, - type: 1 - }) - } else if (/^ss:\/\//.test(decodedData)) { - // SS订阅 - let rawLinks = decodedData.split(/[\n\r\|\s]+/g).filter(i => i !== '' && /^ss:\/\//.test(i)); - let serInfo = decodeScheme(rawLinks); - resolve({ - servers: serInfo.servers.join('\n'), - filename: serInfo.sstag || filename, - type: 2 - }) - } else if (/^vmess:\/\//.test(decodedData)) { - let rawLinks = decodedData.split(/[\n\r\|\s]+/g).filter(i => i !== '' && /^vmess:\/\//.test(i)); - console.log('rawLinks', typeof rawLinks); - let res = decodeVmess(rawLinks); - console.log('res', res); - resolve({ - servers: res.servers.join('\n'), - filename: res.sstag || filename, - type: 3 - }) - } else { - resolve() - } - } - }) - }) -} - -function getDomain(url) { - if (/https?:\/\/.*?\.(.*?)\.(.*?)(?=\/|$)/.test(url)) { - return `${RegExp.$1.trim()}.${RegExp.$2.trim()}` - } - return '批量导入' -} - -function decodeSSR(links) { - let tag = '' - let first = '' - function getParam(key, content) { - let reg = new RegExp(`${key}=(.*?)(?:&|$)`); - let matcher = content.match(reg); - return matcher && matcher[1] ? matcher[1] : ''; - } - let decodedLinks = links.map(i => { - let rawContentMatcher = i.match(/^ssr:\/\/(.*?)$/); - if (rawContentMatcher && rawContentMatcher[1]) { - let rawContent = urlsafeBase64Decode(rawContentMatcher[1]); - let rawContentParts = rawContent.split(/\/*\?/g) - let paramsMatcher = rawContentParts[0].match(/^(.*?):(.*?):(.*?):(.*?):(.*?):(.*?)$/); - if (paramsMatcher && paramsMatcher.length === 7) { - let host = paramsMatcher[1]; - let port = paramsMatcher[2]; - let protocol = paramsMatcher[3]; - let method = paramsMatcher[4]; - let obfs = paramsMatcher[5]; - let pass = urlsafeBase64Decode(paramsMatcher[6]); - let obfsparam = ''; - let protoparam = ''; - let group = ''; - let remarks = ''; - if (rawContentParts.length > 1) { - let target = rawContentParts[1]; - obfsparam = urlsafeBase64Decode(getParam('obfsparam', target)); - protoparam = urlsafeBase64Decode(getParam('protoparam', target)); - group = urlsafeBase64Decode(getParam('group', target)); - remarks = urlsafeBase64Decode(getParam('remarks', target)); - } - if (tag === '' && group !== '') { - tag = group; - } - let finalName = remarks === '' ? `${host}:${port}` : remarks - first = finalName - let res = `${finalName} = shadowsocksr, ${host}, ${port}, ${method}, "${pass}", protocol=${protocol}, obfs=${obfs}`; - res += protoparam ? `, protocol_param=${protoparam}` : ''; - res += obfsparam ? `, obfs_param="${obfsparam}"` : ''; - return res; - } - else { - return ''; - } - } - else { - return ''; - } - }); - let sstag = first - if (decodedLinks.length > 1) { - sstag = `批量SSR节点(${decodedLinks.length})` - } - if (tag !== '') { - sstag = tag - } - return { servers: decodedLinks, sstag: sstag } -} - -function getServersFromConfFile(params) { - let promiseArray = params.urls.map(i => promiseConf(i)) - Promise.all(promiseArray).then(confs => { - for (let idx in confs) { - let res = confs[idx] - let type = res ? res.type : -1 - let filename = res ? res.filename : ''; - let servers = res ? res.servers.split(/[\n\r]+/).filter(item => item !== '').map(i => i.strictTrim()) : []; - params.handler({ servers: servers, filename: filename, url: params.urls[idx], type: type }) - } - }).catch(reason => { - console.error(reason.stack) - params.handler(null) - }) -} - -function isJson(str) { - try { - JSON.parse(str) - } catch (e) { - return false - } - return true -} - -function decodeVmess(links) { - let result = [] - let tag = '' - - for (let idx in links) { - let link = links[idx] - - if (/^vmess:\/\/(.*?)$/.test(link)) { - let content = urlsafeBase64Decode(RegExp.$1) - if (isJson(content)) { - // v2rayN style - let jsonConf = JSON.parse(content) - let group = '' - const ua = 'Mozilla/5.0 (iPhone; CPU iPhone OS 12_0 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Mobile/16A5366a' - let obfs = `,obfs=${jsonConf.net === 'ws' ? 'ws' : 'http'},obfs-path="${jsonConf.path || '/'}",obfs-header="Host:${jsonConf.host || jsonConf.add}[Rr][Nn]User-Agent:${ua}"` - let quanVmess = `${jsonConf.ps} = vmess,${jsonConf.add},${jsonConf.port},chacha20-ietf-poly1305,"${jsonConf.id}",group=${group},over-tls=${jsonConf.tls === 'tls' ? 'true' : 'false'},certificate=1${jsonConf.type === 'none' && jsonConf.net !== 'ws' ? '' : obfs}` - result.push(quanVmess) - } else { - // Quantumult style - if (/group=(.*?),/.test(content)) { - tag = RegExp.$1 - } - result.push(content) - } - } - } - return { servers: result, sstag: tag || `批量V2Ray节点(${result.length})` } -} - -function decodeScheme(urls) { - // let urls = params.ssURL - let result = [] - let tag - let group = '' - - for (let idx in urls) { - let url = urls[idx] - let method, password, hostname, port, plugin - if (!url.includes('#')) { - let name = '无节点名称' - url += `#${name}` - } - tag = $text.URLDecode(url.match(/#(.*?)$/)[1]) - if (url.includes('?')) { - // tag = $text.URLDecode(url.match(/#(.*?)$/)[1]) - let mdps = url.match(/ss:\/\/(.*?)@/)[1] - let padding = 4 - mdps.length % 4 - if (padding < 4) { - mdps += Array(padding + 1).join('=') - } - let userinfo = $text.base64Decode(mdps) - method = userinfo.split(':')[0] - password = userinfo.split(':')[1] - let htpr = url.match(/@(.*?)\?/)[1].replace('\/', '') - hostname = htpr.split(':')[0] - port = htpr.split(':')[1] - let ps = $text.URLDecode(url.match(/\?(.*?)#/)[1]) - let obfsMatcher = ps.match(/obfs=(.*?)(;|$)/) - let obfsHostMatcher = ps.match(/obfs-host=(.*?)(&|;|$)/) - if (obfsMatcher) { - let obfs = obfsMatcher[1] - let obfsHost = obfsHostMatcher ? obfsHostMatcher[1] : 'cloudfront.net' - plugin = `obfs=${obfs}, obfs-host=${obfsHost}` - } - if (/group=(.*)(&|;|$)/.test(ps)) { - group = $text.base64Decode(RegExp.$1.trim()) - } - } else { - if (/ss:\/\/([^#]*)/.test(url)) { - let mdps = RegExp.$1 - if (/^(.*)@(.*?):(.*?)$/.test(mdps)) { - hostname = RegExp.$2 - port = RegExp.$3 - let methodAndPass = urlsafeBase64Decode(RegExp.$1) - console.log('methodAndPass', methodAndPass); - if (/^(.*?):(.*?)$/.test(methodAndPass)) { - method = RegExp.$1 - password = RegExp.$2 - } - } else { - let padding = 4 - mdps.length % 4 - if (padding < 4) { - mdps += Array(padding + 1).join('=') - } - if (/^(.*?):(.*)@(.*?):(.*?)$/.test($text.base64Decode(mdps))) { - method = RegExp.$1 - password = RegExp.$2 - hostname = RegExp.$3 - port = RegExp.$4 - } - } - } - } - let proxy = `${tag} = custom, ${hostname}, ${port}, ${method}, ${password}, https://github.com/lhie1/Rules/blob/master/SSEncrypt.module?raw=true` - if (plugin != undefined) { - proxy += `, ${plugin}` - } - result[idx] = proxy - } - let outName = '' - if (group) { - outName = group - } else if (result.length === 1) { - outName = tag - } else { - outName = `批量ss节点(${result.length})` - } - return { servers: result, sstag: outName } -} - -module.exports = { - proxyFromConf: getServersFromConfFile, - proxyFromURL: decodeScheme, - proxyFromVmess: decodeVmess, - proxyFromSSR: decodeSSR -} \ No newline at end of file diff --git a/JSBox/Rules-lhie1/scripts/ruleUpdateUtil.js b/JSBox/Rules-lhie1/scripts/ruleUpdateUtil.js deleted file mode 100644 index 5763964..0000000 --- a/JSBox/Rules-lhie1/scripts/ruleUpdateUtil.js +++ /dev/null @@ -1,87 +0,0 @@ -let githubRawReg = /^https:\/\/raw\.githubusercontent\.com\/(.*?)\/(.*?)\/master\/(.*?)$/ - -const FILE = 'data.js' - -function getRulesReplacement(content = '') { - let advanceSettings = content ? content : JSON.parse($file.read(FILE).string) - if (advanceSettings.customSettings) { - let cs = advanceSettings.customSettings; - let pat = cs.match(/\/\/\s*replacement\s*:\s*(.*?)[\n\r]/); - if (pat && pat[1]) { - return pat[1]; - } - } - return null; -} - -function getSoftwareType() { - let file = JSON.parse($file.read(FILE).string) - let workspace = file.workspace - let outputFormat = workspace.outputFormat - if (outputFormat === 'Surge 3 TF') { - return 0 - } else if (outputFormat === 'Surge 2') { - return 2 - } else if (outputFormat === 'Quantumult') { - return 3 - } - return 1 -} - -function checkUpdate(oldSha, newSha) { - return Object.keys(newSha).some(i => oldSha[i] !== newSha[i]) -} - -function setFilesSha(sha) { - let file = JSON.parse($file.read(FILE).string) - file['repoSha'] = sha - $file.write({ - data: $data({ "string": JSON.stringify(file) }), - path: FILE - }) -} - -function getFilesSha() { - let file = JSON.parse($file.read(FILE).string) - return file['repoSha'] || {} -} - -function getGitHubFilesSha(params) { - params.handler({}) -} - -function getRepoInfo() { - let owner = 'lhie1'; - let repoName = 'Rules'; - let filePath = 'Auto'; - let softwareType = getSoftwareType() - if (softwareType === 0) { - filePath = 'Auto_New' - } else if (softwareType === 3) { - filePath = 'Quantumult' - } - console.log(filePath) - let rulesRep = getRulesReplacement(); - if (rulesRep) { - let reg = rulesRep.match(githubRawReg); - if (reg && reg.length === 4) { - owner = reg[1]; - repoName = reg[2]; - filePath = reg[3]; - } - } - return { owner, repoName, filePath }; -} - -function getLatestCommitMessage(params) { - params.handler(null) -} - -module.exports = { - checkUpdate: checkUpdate, - getGitHubFilesSha: getGitHubFilesSha, - setFilesSha: setFilesSha, - getFilesSha: getFilesSha, - getLatestCommitMessage: getLatestCommitMessage, - getRepoInfo: getRepoInfo -} \ No newline at end of file diff --git a/JSBox/Rules-lhie1/scripts/siri.js b/JSBox/Rules-lhie1/scripts/siri.js deleted file mode 100644 index 03e5054..0000000 --- a/JSBox/Rules-lhie1/scripts/siri.js +++ /dev/null @@ -1,14 +0,0 @@ -const ruleUpdateUtil = require('scripts/ruleUpdateUtil'); - -function siriRun() { - -} - -function renderSiriUI() { - $intents.height = 100 -} - -module.exports = { - siriRun: siriRun, - renderSiriUI: renderSiriUI -} \ No newline at end of file diff --git a/JSBox/Rules-lhie1/scripts/sizeUtil.js b/JSBox/Rules-lhie1/scripts/sizeUtil.js deleted file mode 100644 index 25dd4d0..0000000 --- a/JSBox/Rules-lhie1/scripts/sizeUtil.js +++ /dev/null @@ -1,8 +0,0 @@ -function pc(x) { - let sw = $device.info.screen.width - return x * sw / 100 -} - -module.exports = { - pc: pc -} \ No newline at end of file diff --git a/JSBox/Rules-lhie1/scripts/socketLogger.js b/JSBox/Rules-lhie1/scripts/socketLogger.js deleted file mode 100644 index c5143d0..0000000 --- a/JSBox/Rules-lhie1/scripts/socketLogger.js +++ /dev/null @@ -1,49 +0,0 @@ -module.exports = { - init: (address, port, clearFirst = true, debug = true) => { - var oldLog = console.log; - var oldInfo = console.info; - var oldWarn = console.warn; - var oldError = console.error; - let start = clearFirst - var socket = $socket.new(`ws://${address}:${port}`); - socket.open() - console.log = function (obj) { - if (debug) { - let msg = JSON.stringify({ type: 'log', args: Array.prototype.slice.call(arguments) }); - start = sendMessage(start, socket, msg); - } - oldLog.apply(console, arguments); - } - console.info = function (obj) { - if (debug) { - let msg = JSON.stringify({ type: 'info', args: Array.prototype.slice.call(arguments) }); - start = sendMessage(start, socket, msg); - } - oldInfo.apply(console, arguments); - } - console.warn = function (obj) { - if (debug) { - let msg = JSON.stringify({ type: 'warn', args: Array.prototype.slice.call(arguments) }); - start = sendMessage(start, socket, msg); - } - oldWarn.apply(console, arguments); - } - console.error = function (obj) { - if (debug) { - let msg = JSON.stringify({ type: 'error', args: Array.prototype.slice.call(arguments) }); - start = sendMessage(start, socket, msg); - } - oldError.apply(console, arguments); - } - } -} - -function sendMessage(start, socket, msg) { - if (start) { - socket.send(JSON.stringify({ type: "_open" })); - start = false; - } - socket.send(msg); - return start; -} - diff --git a/JSBox/Rules-lhie1/scripts/today.js b/JSBox/Rules-lhie1/scripts/today.js deleted file mode 100644 index 13b12fa..0000000 --- a/JSBox/Rules-lhie1/scripts/today.js +++ /dev/null @@ -1,468 +0,0 @@ -const ruleUpdateUtil = require('scripts/ruleUpdateUtil') -const updateUtil = require('scripts/updateUtil') - -const loadingHint = "检查规则/脚本更新..." - -const scriptName = $addin.current.name - -const FILE = 'data.js' - -let pm = function (method) { - return new Promise((resolve, reject) => { - method({ - handler: res => { - resolve(res) - } - }) - }) -} - -function getIfaData() { - return Object.keys($network.ifa_data).filter(i => i.indexOf('utun') > -1) -} - -function vpnStatus() { - try { - // 支持最新TF($network.proxy_settings) - let proxySettings = $network.proxy_settings - let proxyScoped = proxySettings['__SCOPED__'] - let lans = Object.keys(proxyScoped) - return lans.find(i => i.indexOf('utun') > -1) ? 1 : 0 - } catch (e) { - // 兼容旧版,需要手动设置状态 - if ($cache.get("surgeOn")) { - let surgeOn = $cache.get('surgeOn') - let nowIfa = getIfaData() - let oldIfa = surgeOn.ifaKeys - if (nowIfa.length === oldIfa.length) { - return surgeOn.status ? 1 : 0 - } else { - return surgeOn.status ? 0 : 1 - } - } - return -1 - } -} - -function genSrugeLabel(status, isQuan) { - if (status === -1) { - return '长按设置' - } else if (status === 0) { - return isQuan ? '开启Quantumult' : '开启Surge' - } else { - return isQuan ? '关闭Quantumult' : '关闭Surge' - } -} - -function requestHead(url) { - if (!/^https?:\/\//.test(url)) return Promise.resolve('') - return new Promise((resolve, reject) => { - $http.request({ - method: "HEAD", - url: url, - header: { - // 'User-Agent': 'Quantumult' - }, - handler: function (resp) { - let headerFields = resp.response.runtimeValue().$allHeaderFields().rawValue(); - if ('Subscription-userinfo' in headerFields) { - resolve(headerFields['Subscription-userinfo']) - } else if ('subscription-userinfo' in headerFields) { - resolve(headerFields['subscription-userinfo']) - } else { - resolve('') - } - } - }) - }) -} - -function parseUsage(usageStr) { - let uploadMatcher = usageStr.match(/upload=(\d+)(?:;|$)/) - let downloadMatcher = usageStr.match(/download=(\d+)(?:;|$)/) - let totalMatcher = usageStr.match(/total=(\d+)(?:;|$)/) - let upload = 0 - let download = 0 - let total = 0 - if (uploadMatcher && uploadMatcher[1]) upload = uploadMatcher[1] * 1 - if (downloadMatcher && downloadMatcher[1]) download = downloadMatcher[1] * 1 - if (totalMatcher && totalMatcher[1]) total = totalMatcher[1] * 1 - return { - upload: upload, - download: download, - total: total - } -} - -function widgetSettings(file) { - let items = file.widgetSettings.split(/[\r\n]+/g).filter(i => /^.*?=\s*http/.test(i)) - return items.map(i => { - let p = i.split(/=/) - return { - name: p[0].trim(), - url: p.slice(1).join('=').trim() - } - }) -} - -function renderTodayUI() { - let file = JSON.parse($file.read(FILE).string) - let workspace = file.workspace - let widget = widgetSettings(file); - let groupNames = workspace.serverData.map(i => i.title).concat(widget.map(i => i.name)) - let groupURLs = workspace.serverData.map(i => i.url).concat(widget.map(i => i.url)).map(i => requestHead(i)) - Promise.all(groupURLs).then(res => { - console.log(res) - let usageData = [] - for (let idx in res) { - if (res[idx] === '') continue - let usage = parseUsage(res[idx]) - const GB = Math.pow(1024, 3) - usageData.push({ - groupName: { - text: `${groupNames[idx]}` - }, - usageProgress: { - value: (usage.download + usage.upload) / usage.total - }, - usageDetail: { - text: `↑ ${(usage.upload / GB).toFixed(2)}GB ↓ ${(usage.download / GB).toFixed(2)}GB ≡ ${((usage.total - usage.download - usage.upload) / GB).toFixed(2)}GB` - }, - usageDetail2: { - text: `${groupNames[idx]} ( ${(usage.total / GB).toFixed(2)}GB )` - } - }) - } - $("usageView").data = usageData - $("usageView").updateLayout(make => { - make.height.equalTo(usageData.length * 50) - }) - $widget.height = 110 + (usageData.length * 50) - }) - $widget.modeChanged = mode => { - if (mode === 1) { - $widget.height = 110 + ($("usageView").data.length * 50) - } - } - let outputFormat = workspace.outputFormat - let surge2 = outputFormat === 'Surge 2' - let isQuan = outputFormat === 'Quantumult' - let isLauncher = $app.widgetIndex < 0 || $app.widgetIndex > 2 - let checks = [pm(ruleUpdateUtil.getGitHubFilesSha), pm(updateUtil.getLatestVersion)] - let vStatus = vpnStatus() - Promise.all(checks).then(res => { - let canUpdate = ruleUpdateUtil.checkUpdate(ruleUpdateUtil.getFilesSha(), res[0]) - let newVersion = updateUtil.needUpdate(res[1], updateUtil.getCurVersion()) - $("newTag").hidden = !canUpdate - $("newVersionTag").hidden = !newVersion - return canUpdate ? pm(ruleUpdateUtil.getLatestCommitMessage) : Promise.resolve() - }).then(res => { - let { owner, repoName, filePath } = ruleUpdateUtil.getRepoInfo() - $("updateStatus").text = res ? res.commit.message : `${owner}\/${repoName}` - }) - let targetAppOn = $file.read("assets/today_surge.png") - let targetAppOff = $file.read("assets/today_surge_off.png") - if (isQuan) { - targetAppOn = $file.read("assets/today_quan.png") - targetAppOff = $file.read("assets/today_quan_off.png") - } else if (surge2) { - targetAppOn = $file.read("assets/today_surge2.png") - } - $ui.render({ - props: { - id: "todayMainView", - title: "Surge3规则生成", - hideNavbar: true, - navBarHidden: true, - }, - views: [{ - type: "blur", - props: { - id: "close", - style: 1, - radius: 0, - hidden: !isLauncher - }, - layout: (make, view) => { - make.width.height.equalTo(view.super).offset(10) - make.top.equalTo(view.super.top).offset(-10) - }, - events: { - tapped: sender => { - $app.close(0.3) - } - } - }, { - type: "view", - props: { - id: "", - }, - layout: (make, view) => { - make.height.equalTo(110) - make.width.equalTo(view.super).offset(-60) - make.centerX.equalTo(view.super) - }, - views: [{ - type: "label", - props: { - id: "updateStatus", - text: "Rules-lhie1 by Fndroid", - font: $font(12), - textColor: $rgba(50, 50, 50, .3) - }, - layout: (make, view) => { - make.top.equalTo(view.super.top).offset(5) - make.centerX.equalTo(view.super) - } - }, { - type: "label", - props: { - id: "updateStatus", - text: loadingHint, - font: $font(12), - textColor: $rgba(50, 50, 50, .3) - }, - layout: (make, view) => { - make.bottom.equalTo(view.super.bottom).offset(-5) - make.centerX.equalTo(view.super) - } - }, { - type: "image", - props: { - id: "pullBtn", - data: $file.read("assets/today_pull.png"), - radius: 25, - bgcolor: $rgba(255, 255, 255, 0) - }, - layout: (make, view) => { - make.width.height.equalTo(55) - make.centerY.equalTo(view.super).offset(-10) - make.centerX.equalTo(view.super) - }, - events: { - tapped: sender => { - $app.openURL(`jsbox://run?name=${encodeURIComponent(scriptName)}&auto=1`) - } - }, - }, { - type: "image", - props: { - id: "surgeBtn", - data: vStatus === 0 ? targetAppOff : targetAppOn, - radius: 25, - bgcolor: $rgba(255, 255, 255, 0) - }, - layout: (make, view) => { - make.width.height.equalTo(55) - make.centerY.equalTo(view.super).offset(-10) - // make.left.equalTo(view.prev.left).offset(-(sw / 3.5)) - make.left.equalTo(view.super) - console.log('width', $widget.width) - }, - events: { - tapped: sender => { - let url = `surge${surge2 ? "" : "3"}:///toggle?autoclose=true` - if (isQuan) { - url = 'quantumult://' + (vStatus === 0 ? 'start' : 'stop') - } - $app.openURL(url) - }, - longPressed: sender => { - $ui.alert({ - title: "初始设置", - message: '请选择当前VPN开关状态?', - actions: [{ - title: '已关闭', - handler: () => { - $cache.set("surgeOn", { - status: false, - ifaKeys: getIfaData() - }) - } - }, { - title: '已开启', - handler: () => { - $cache.set("surgeOn", { - status: true, - ifaKeys: getIfaData() - }) - } - }] - }) - } - } - }, { - type: "image", - props: { - id: "jsboxBtn", - data: $file.read("assets/today_jsbox.png"), - radius: 25, - bgcolor: $rgba(255, 255, 255, 0) - }, - layout: (make, view) => { - make.width.height.equalTo(50) - make.centerY.equalTo(view.super).offset(-10) - // make.right.equalTo(view.prev.prev.right).offset((sw / 3.5)) - make.right.equalTo(view.super) - }, - events: { - tapped: sender => { - $app.openURL(`jsbox://run?name=${encodeURIComponent(scriptName)}`) - } - } - }, { - type: "label", - props: { - text: "更新规则", - font: $font(12), - textColor: $rgba(50, 50, 50, .8), - align: $align.center - }, - layout: (make, view) => { - make.height.equalTo(12) - make.top.equalTo($("pullBtn").bottom) - make.width.equalTo($("pullBtn").width) - make.centerX.equalTo($("pullBtn")) - } - }, { - type: "label", - props: { - id: "surgeLabel", - text: genSrugeLabel(vStatus, isQuan), - font: $font(12), - textColor: $rgba(50, 50, 50, .8), - align: $align.center - }, - layout: (make, view) => { - make.height.equalTo(12) - make.top.equalTo(view.prev.top) - make.centerX.equalTo($("surgeBtn")) - } - }, { - type: "label", - props: { - text: "脚本设置", - font: $font(12), - textColor: $rgba(50, 50, 50, .8), - align: $align.center - }, - layout: (make, view) => { - make.height.equalTo(12) - make.top.equalTo($("pullBtn").bottom) - make.width.equalTo($("pullBtn").width) - make.centerX.equalTo($("jsboxBtn")) - } - }, { - type: "image", - props: { - id: "newTag", - data: $file.read("assets/new_rules_tag.png"), - bgcolor: $rgba(255, 255, 255, 0), - hidden: true - }, - layout: (make, view) => { - make.width.height.equalTo(15) - make.centerY.equalTo(view.super).offset(-20) - make.left.equalTo($("pullBtn").right).offset(-10) - } - }, { - type: "image", - props: { - id: "newVersionTag", - data: $file.read("assets/new_version_tag.png"), - bgcolor: $rgba(255, 255, 255, 0), - hidden: true - }, - layout: (make, view) => { - make.width.height.equalTo(15) - make.centerY.equalTo(view.super).offset(-20) - make.left.equalTo($("jsboxBtn").right).offset(-10) - } - }, { - type: "image", - props: { - id: "closeBtn", - data: $file.read("assets/close_icon.png"), - bgcolor: $rgba(255, 255, 255, 0), - hidden: !isLauncher, - alpha: 0.7 - }, - layout: (make, view) => { - make.width.height.equalTo(20) - make.top.equalTo(view.super.top).offset(10) - make.right.equalTo(view.super.right).offset(-10) - }, - events: { - tapped: sender => { - $app.close(.2) - } - } - }] - }, { - type: 'list', - props: { - id: "usageView", - data: [], - rowHeight: 50, - alwaysBounceVertical: false, - bgcolor: $color("clear"), - separatorHidden: true, - template: { - props: { - bgcolor: $color("clear") - }, - views: [{ - type: "progress", - props: { - id: 'usageProgress' - }, - layout: function (make, view) { - make.centerY.equalTo(view.super).offset(-3); - make.centerX.equalTo(view.super); - make.height.equalTo(3) - make.width.equalTo(view.super).multipliedBy(1).offset(-50) - }, - views: [{ - type: 'label', - props: { - id: 'usageDetail', - align: $align.center, - font: $font("bold", 10), - textColor: $color("#595959") - }, - layout: (make, view) => { - make.width.equalTo(view.super) - make.height.equalTo(20) - make.top.equalTo(view.super).offset(-20) - make.centerX.equalTo(view.super) - } - }, { - type: 'label', - props: { - id: 'usageDetail2', - align: $align.center, - font: $font("bold", 12), - textColor: $color("#595959") - }, - layout: (make, view) => { - make.width.equalTo(view.super) - make.height.equalTo(23) - make.top.equalTo(view.super) - make.centerX.equalTo(view.super) - } - }] - }] - } - }, - layout: (make, view) => { - make.top.equalTo(110) - make.width.equalTo(view.super) - make.height.width.equalTo(100) - } - }] - }) -} - -module.exports = { - renderTodayUI: renderTodayUI -} diff --git a/JSBox/Rules-lhie1/scripts/updateUtil.js b/JSBox/Rules-lhie1/scripts/updateUtil.js deleted file mode 100644 index 585ba00..0000000 --- a/JSBox/Rules-lhie1/scripts/updateUtil.js +++ /dev/null @@ -1,60 +0,0 @@ -function getCurVersion() { - let version = $file.read("version.fndroid").string - return version -} - -function needRestart() { - return $http.get({ - url: 'https://raw.githubusercontent.com/Fndroid/jsbox_script/master/Rules-lhie1/restart.fndroid' - }) -} - -function getLatestVersion(params) { - $http.get({ - url: 'https://raw.githubusercontent.com/Fndroid/jsbox_script/master/Rules-lhie1/version.fndroid' + '?t=' + new Date().getTime(), - handler: res => { - params.handler(res.data) - } - }) -} - -function updateScript(version) { - let url = 'https://raw.githubusercontent.com/Fndroid/jsbox_script/master/Rules-lhie1/.output/Rules-lhie1.box' + '?t=' + new Date().getTime() - const scriptName = $addin.current.name - let downloadBox = $http.download({ - url: url - }) - Promise.all([downloadBox, needRestart()]).then(res => { - let box = res[0].data - let restart = /true/.test(res[1].data) - $addin.save({ - name: scriptName, - data: box, - handler: (success) => { - if (success) { - $ui.toast(`更新完成`) - if (restart) { - $delay(0.3, () => { - $addin.run(scriptName) - }) - } - } - } - }) - }) -} - -function needUpdate(nv, ov) { - let getVersionWeight = i => { - return i.split('.').map(i => i * 1).reduce((s, i) => s * 100 + i) - } - return getVersionWeight(nv) > getVersionWeight(ov) -} - - -module.exports = { - getCurVersion: getCurVersion, - getLatestVersion: getLatestVersion, - updateScript: updateScript, - needUpdate: needUpdate -} diff --git a/JSBox/Rules-lhie1/scripts/videoReg.js b/JSBox/Rules-lhie1/scripts/videoReg.js deleted file mode 100644 index b529478..0000000 --- a/JSBox/Rules-lhie1/scripts/videoReg.js +++ /dev/null @@ -1,16 +0,0 @@ -module.exports = { - Netflix: /(?=USER-AGENT,Argo\*,|DOMAIN-SUFFIX,netflix.com,|DOMAIN-SUFFIX,netflix.net,|DOMAIN-SUFFIX,nflxext.com,|DOMAIN-SUFFIX,nflximg.com,|DOMAIN-SUFFIX,nflximg.net,|DOMAIN-SUFFIX,nflxvideo.net,|IP-CIDR,23.246.0.0\/12,|IP-CIDR,37.77.0.0\/12,|IP-CIDR,45.57.0.0\/12,|IP-CIDR,64.120.128.0\/17,|IP-CIDR,66.197.128.0\/17,|IP-CIDR,108.175.0.0\/12,|IP-CIDR,185.2.0.0\/12,|IP-CIDR,185.9.188.0\/22,|IP-CIDR,192.173.64.0\/18,|IP-CIDR,198.38.0.0\/12,|IP-CIDR,198.45.0.0\/12,)[^\n]+/g, - Spotify: /(?=PROCESS-NAME,Spotify,|DOMAIN-SUFFIX,spoti.fi,|DOMAIN-KEYWORD,spotify,|USER-AGENT,\*Spotify\*,|DOMAIN-SUFFIX,scdn.co,|DOMAIN-SUFFIX,spotify.com,)[^\n]+/g, - YouTube: /(?=USER-AGENT,com.google.ios.youtube\*,|USER-AGENT,YouTube\*,|DOMAIN-SUFFIX,googlevideo.com,|DOMAIN-SUFFIX,youtube.com,|DOMAIN-KEYWORD,youtube,)[^\n]+/g, - MytvSUPER: /(?=DOMAIN-KEYWORD,nowtv100,|DOMAIN-KEYWORD,rthklive,|DOMAIN-SUFFIX,mytvsuper.com,|DOMAIN-SUFFIX,tvb.com,)[^\n]+/g, - BBC: /(?=USER-AGENT,BBCiPlayer\*,|USER-AGENT,BBCBeacon\*,|DOMAIN-KEYWORD,co.uk,|DOMAIN-KEYWORD,uk-live,|DOMAIN-SUFFIX,bbc.co,|DOMAIN-SUFFIX,bbc.com,|DOMAIN-SUFFIX,bbci.co.uk,|DOMAIN-SUFFIX,bbc.co.uk,|DOMAIN-SUFFIX,vod-hls-uk-live.akamaized.net,)[^\n]+/g, - LINE: /(?=DOMAIN-SUFFIX,lin.ee,|DOMAIN-SUFFIX,line.me,|DOMAIN-SUFFIX,line.naver.jp,|DOMAIN-SUFFIX,line-apps.com,|DOMAIN-SUFFIX,line-cdn.net,|DOMAIN-SUFFIX,line-scdn.net,|DOMAIN-SUFFIX,nhncorp.jp,|IP-CIDR,103.2.28.0\/22,|IP-CIDR,119.235.224.0\/21,|IP-CIDR,119.235.232.0\/23,|IP-CIDR,119.235.235.0\/24,|IP-CIDR,119.235.236.0\/23,|IP-CIDR,125.6.146.0\/24,|IP-CIDR,125.6.149.0\/24,|IP-CIDR,125.6.190.0\/24,|IP-CIDR,125.209.208.0\/20,|IP-CIDR,203.104.103.0\/24,|IP-CIDR,203.104.128.0\/20,|IP-CIDR,203.174.66.64\/26,|IP-CIDR,203.174.77.0\/24,)[^\n]+/g, - SoundCloud: /(?=USER-AGENT,SoundCloud\*,|DOMAIN-SUFFIX,soundcloud.com,|DOMAIN-SUFFIX,sndcdn.com,)[^\n]+/g, - Google: /(?=DOMAIN-SUFFIX,goo.gl,|DOMAIN-SUFFIX,gvt1.com,|DOMAIN-SUFFIX,youtu.be,|DOMAIN-SUFFIX,ytimg.com,|DOMAIN-SUFFIX,ggpht.com,|DOMAIN-KEYWORD,gmail,|DOMAIN-KEYWORD,google,|DOMAIN-KEYWORD,gstatic,|DOMAIN-KEYWORD,youtube,|USER-AGENT,WalletAPP.app\*,|USER-AGENT,Wallet\*iSL\*,|DOMAIN-SUFFIX,google.com,|DOMAIN-SUFFIX,googleapis.com,)[^\n]+/g, - PayPal: /(?=USER-AGENT,PayPal\*,|DOMAIN-KEYWORD,paypal,|DOMAIN-SUFFIX,paypal.com,)[^\n]+/g, - Microsoft: /(?=USER-AGENT,Microsoft\*,|USER-AGENT,OneDrive\*,|DOMAIN-KEYWORD,microsoft,|DOMAIN-SUFFIX,bing.com,|DOMAIN-SUFFIX,bing.net,|DOMAIN-SUFFIX,cloudappsecurity.com,|DOMAIN-SUFFIX,docs.com,|DOMAIN-SUFFIX,hotmail.com,|DOMAIN-SUFFIX,live.com,|DOMAIN-SUFFIX,live.net,|DOMAIN-SUFFIX,microsoft.com,|DOMAIN-SUFFIX,msedge.net,|DOMAIN-SUFFIX,msn.com,|DOMAIN-SUFFIX,office.com,|DOMAIN-SUFFIX,office.net,|DOMAIN-SUFFIX,office365.com,|DOMAIN-SUFFIX,onedrive.com,|DOMAIN-SUFFIX,onenote.com,|DOMAIN-SUFFIX,onenote.net,|DOMAIN-SUFFIX,onmicrosoft.com,|DOMAIN-SUFFIX,outlook.com,|DOMAIN-SUFFIX,outlookgroups.ms,|DOMAIN-SUFFIX,visualstudio.com,|DOMAIN-SUFFIX,windows.com,|DOMAIN-SUFFIX,windows.net,|DOMAIN-SUFFIX,windowsupdate.com,)[^\n]+/g, - YoutubeMusic: /(?=USER-AGENT,\*youtubemusic\*,|USER-AGENT,YouTubeMusic\*,)[^\n]+/g, - TVB: /(?=USER-AGENT,mytv\*,|DOMAIN-SUFFIX,mytvsuper.com,|DOMAIN-KEYWORD,nowtv100,|DOMAIN-KEYWORD,rthklive,|DOMAIN-SUFFIX,tvb.com,|USER-AGENT,OTT_iPhone\*,|USER-AGENT,Viu\*,|DOMAIN-SUFFIX,viu.com,)[^\n]+/g, - Vidol: /(?=USER-AGENT,Vidol\*,|DOMAIN-SUFFIX,vidol.tv,)[^\n]+/g, - Hulu: /(?=DOMAIN-SUFFIX,hulu.com,)[^\n]+/g -} diff --git a/JSBox/Rules-lhie1/strings/en.strings b/JSBox/Rules-lhie1/strings/en.strings deleted file mode 100644 index ae42947..0000000 --- a/JSBox/Rules-lhie1/strings/en.strings +++ /dev/null @@ -1,3 +0,0 @@ -"OK" = "OK"; -"DONE" = "Done"; -"HELLO_WORLD" = "Hello, World!"; diff --git a/JSBox/Rules-lhie1/strings/zh-Hans.strings b/JSBox/Rules-lhie1/strings/zh-Hans.strings deleted file mode 100644 index b2d0c5d..0000000 --- a/JSBox/Rules-lhie1/strings/zh-Hans.strings +++ /dev/null @@ -1,3 +0,0 @@ -"OK" = "好的"; -"DONE" = "完成"; -"HELLO_WORLD" = "你好,世界!"; diff --git a/JSBox/Rules-lhie1/updateLog.md b/JSBox/Rules-lhie1/updateLog.md deleted file mode 100644 index 51c96a7..0000000 --- a/JSBox/Rules-lhie1/updateLog.md +++ /dev/null @@ -1,546 +0,0 @@ -**如打赏名单有遗漏,请TG联系我加一下** - -#### 2019.05.06 -1. 修复规则仓库调整导致的不兼容问题 -v1.9.70 - -#### 2019.04.15 -1. 修复“删除节点”逻辑问题 -v1.9.69 - -#### 2019.03.21 -1. 修复Quantumult自定义url rewrite不生效问题 -v1.9.67 - -#### 2019.03.20 -1. 修复规则仓库调整导致的不兼容问题 -v1.9.64 -2. 修复当只有userHostName时,配置文件出现第一行为空的问题 -v1.9.65 -3. 修复Quantumult规则变化导致的问题 -v1.9.66 - -#### 2019.02.25 -1. 修复规则仓库调整导致的不兼容问题 -v1.9.63 -2. 修复ss节点密码带有@导致不能识别问题 -v1.9.63 - -#### 2019.02.07 -1. 修复RuleSet注释无法识别问题 -v1.9.62 - -#### 2019.01.04 -1. 修复进阶设置占位符滚动问题 -v1.9.61 - -#### 2019.01.01 -1. 修复导出到Quantumult时RULE-SET转换错误问题 -v1.9.60 - -#### 2018.12.30 -1. rename替换中使用``>``代替``,`` -v1.9.59 - -#### 2018.12.21 -1. 支持导入混合类型订阅 -v1.9.58 - -#### 2018.12.20 -1. 修复RULE-SET被注释依然转换问题 -v1.9.57 - -#### 2018.11.24 -1. 修复非TF导出带有RULE-SET问题 -v1.9.56 - -#### 2018.11.19 -1. 修复Quantumult和Surge TF无法使用replacement问题 -v1.9.54 - -#### 2018.11.17 -1. 修复Widget布局问题 -v1.9.52 -2. 自定义规则对所有导出支持RULE-SET -v1.9.52 - -#### 2018.11.16 -1. 去除特殊代理 -v1.9.51 -2. 去除RuleSet的时间戳 -v1.9.51 - -#### 2018.11.14 -1. Quantumult所有Rejection部分使用最新Rewrite实现1x1像素过滤 -v1.9.50 -2. 替换支付宝红包 -v1.9.50 - -#### 2018.11.08 -1. 修复SSEncrypt.module失效问题 -v1.9.47 -2. 修复重复策略名无法导出问题 -v1.9.48 - -#### 2018.11.03 -1. 修复Quantumult问题 -v1.9.45 - -#### 2018.11.01 -1. 允许添加空节点 -v1.9.43 - -#### 2018.10.30 -1. 修复Shadowsocks订阅识别问题 -v1.9.39 -2. 修复Quantumult规则导出问题 -v1.9.40 -3. 修复SurgeTF规则导出问题 -v1.9.40 - -#### 2018.10.29 -1. 调整Quantumult自定义规则位置于GEOIP,CN上面 -v1.9.38 - -#### 2018.10.27 -1. 修复Quantumult所有LAN规则没有设置为DIRECT的问题 -v1.9.37 - -#### 2018.10.22 -1. 修正备份问题 -v1.9.36 - -#### 2018.10.18 -1. 恢复占位符重命名 -v1.9.35 -1. 代理分组输入框提供所有占位符名称选择 -v1.9.35 - -#### 2018.10.17 -1. 修复动画资源过大问题 -v1.9.34 - -#### 2018.10.15 -1. 小组件流量显示调整,设置时等号两边可以留空格 -v1.9.33 - -#### 2018.10.14 -1. 小组件规则更新信息根据APP显示 -v1.9.32 - -#### 2018.10.10 -1. 修复Shadowsocks链接导入错误 -v1.9.30 -2. 修复Shadowsocks订阅在Quantumult不生成的问题 -v1.9.31 - -#### 2018.10.05 -1. 调整调试状态栏显示状态下UI被遮挡的问题 -v1.9.28 - -#### 2018.10.03 -1. 替换占位符操作“重命名”为“删除节点” -v1.9.26 -2. 修复ssid策略组名称问题 -v1.9.27 - -#### 2018.10.01 -1. 调整RULE-SET中的URL,添加时间戳强制刷新 -v1.9.24 -2. 支持添加类型为round-robin的策略组,配置如select,对应Quantumult轮询 -v1.9.24 -3. 修复规则替换问题 -v1.9.25 - -#### 2018.09.29 -1. 生成Quantumult规则时,自动生成对应的favorite -v1.9.22 -2. 增加列表下拉更新节点 -v1.9.23 - -#### 2018.09.28 -1. 修复Quantumult无法导出问题 -v1.9.15 -2. 增加升级重启逻辑,仅在需要时重启脚本 -v1.9.16 -3. 修复SSID设置失效问题 -v1.9.17 -4. 增加导出Surge3 TF格式规则 -v1.9.18 -5. 修复图标问题 -v1.9.19 -6. 修复Bug -v1.9.21 - -#### 2018.09.25 -1. 修复特殊代理设置后无法生成配置文件问题 -v1.9.13 - -#### 2018.09.24 -1. 调整列表样式 -v1.9.12 - -#### 2018.09.20 -1. 修复特殊代理设置无效问题 -v1.9.11 - -#### 2018.09.19 -1. 调整Quantumult规则 -v1.9.9 - -#### 2018.09.16 -1. 调整ss链接识别 -v1.9.5 -2. 更改Quantulult导出的规则为Jacky Y维护的规则 -v1.9.7 -3. 增加备份文件选择后的提示 -v1.9.7 - -#### 2018.09.13 -1. 修复首次打开无法导入节点问题 -v1.9.4 -2. 允许空白分组,并在生成时清除其group信息 -v1.9.4 - -#### 2018.09.11 -1. 新添加节点显示在最顶部 -v1.9.3 -2. 修复v2ray订阅不生成问题 -v1.9.3 - -#### 2018.09.10 -1. 支持导入v2订阅(Quantumult和v2rayN),去除对Shadowrocket和Kitsunebi的vmess格式支持 -v1.9.1 -2. v2rayN的vmess默认加密方式改为chacha20-ietf-poly1305 -1.9.2 - -#### 2018.08.30 -1. 修复bug -v1.8.4 - -#### 2018.08.28 -1. 修复加载慢或无法加载的问题 -v1.8.2 - -#### 2018.08.26 -1. 修复Bug -v1.7.89 -2. 适配Quantumult的SSID suspend -v1.8.1 - -#### 2018.08.23 -1. 调整导航栏样式 -v1.7.82 -2. 增加Loading动画 -v1.7.83 - -#### 2018.08.22 -1. 允许定义部分UI(主界面和进阶设置)颜色,且不会因更新覆盖 -v1.7.80 - -#### 2018.08.21 -1. 增加从Quantumult导出节点,导出文件是选择JSBox即可 -v1.7.76 -2. 恢复SSID设置 -1.7.77 - -#### 2018.08.20 -1. 增加小组件流量显示自定义 -v1.7.75 - -#### 2018.08.19 -1. 修复SSR订阅识别Quantumult无法联网问题 -v1.7.73 -2. 修复Bug -v1.7.74 - -#### 2018.08.18 -1. 增加节点编辑,去除重命名 -v1.7.71 -2. 兼容某些不合规范的订阅 -v1.7.72 - -#### 2018.08.17 -1. 特殊代理设置会在脚本启动时从Github更新,地址:https://github.com/Fndroid/specialReg -v1.7.70 - -#### 2018.08.13 -1. 更新默认General配置,更新需要清空进阶设置里的“常规” -v1.7.69 - -#### 2018.08.12 -1. Emoji功能独立开关 -v1.7.66 -2. 修复更新节点时批量节点被恢复问题 -v1.7.66 -3. 部分机场订阅不规范无法识别问题 -v1.7.67 - -#### 2018.08.11 -1. Emoji更新可以对所有节点生效 -v1.7.64 -2. 修复bug -v1.7.65 - -#### 2018.08.09 -1. 修复SSR转换时模块丢失问题 -v1.7.63 - -#### 2018.08.07 -1. SSR链接导出到Surge时仅支持plain/origin兼容模式 -v1.7.62 -2. 订阅识别不支持混合类型,仅仅会读取首个节点类型,不同的将被抛弃 -v1.7.62 - -#### 2018.08.06 -1. 增加识别external类型Surge链接 -v1.7.61 -2. 导出为Surge时尝试将链接转换为ss链接 -v1.7.61 - -#### 2018.08.05 -1. 更新节点列表时可以带上国旗Emoji -v1.7.60 - -#### 2018.08.03 -1. 修复拓展选择时注释被误识别的问题 -v1.7.59 -2. 调整下载逻辑 -v1.7.59 - -#### 2018.08.01 -1. 修复Quantumult添加后缀被误识别为混淆参数的问题 -v1.7.58 - -#### 2018.07.30 -1. 增加后缀source-type=n,n合法值为0-7,用于Quantumult导出时设置订阅的OPTION选项 -v1.7.57 -2. 增加307重定向识别 -v1.7.57 - -#### 2018.07.28 -1. 修复某些设备小组件字体被遮挡的问题 -v1.7.56 - -#### 2018.07.27 -1. 增加识别Shadowsocks订阅 -v1.7.54 -2. 修复某些机场不能显示流量问题 -v1.7.54 -3. 增加节点更新/识别失败提示 -v1.7.55 - -#### 2018.07.25 -1. 调整小组件流量显示样式 -v1.7.52 -2. 修复流量信息和组名不对应问题 -v1.7.53 - -#### 2018.07.24 -1. 修复一个很难触发的Bug -v1.7.51 - -#### 2018.07.23 -1. 界面调整 -v1.7.50 - -#### 2018.07.22 -1. Quantumult调整REJECT规则部分,解决某些广告不能屏蔽问题(如腾讯视频) -v1.7.47 -2. 删除昨晚加班解决的问题 -v1.7.48 -3. 修复小Bug -v1.7.49 - -#### 2018.07.21 -1. 修复Quantumult导出时自定义URLRewrite或URLReject丢失问题 -v1.7.44 -2. 修复Quantumult导出时因节点名称不合法而丢弃的问题 -v1.7.45 - -#### 2018.07.20 -1. 关于页面增加托管Bot入口 -v1.7.41 -2. 长按“生成配置”按钮可以快速导出data.js文件 -v1.7.41 -3. 小组件会根据配置使用Quantumult支持的流量显示方式显示流量信息 -v1.7.42 -4. 调整小组件样式 -v1.7.43 - -#### 2018.07.19 -1. 更新托管文件名获取逻辑 -v1.7.40 - -#### 2018.07.18 -1. 调整小组件和启动器区分逻辑 -v1.7.38 -2. 调整主界面UI -v1.7.38 -3. 区分Surge2/3的图标 -v1.7.39 - -#### 2018.07.17 -1. 生成Quantumult配置时,如检测到SSR链接,则在Favorite里生成对应订阅 -v1.7.37 - -#### 2018.07.16 -1. 配置文件增加覆盖功能 -v1.7.36 - -#### 2018.07.15 -1. 支持识别Kitsunebi和Shadowrocket的V2Ray链接 - v1.7.35 - -#### 2018.07.13 -1. 修复SSR托管无法识别问题 - v1.7.32 -2. 增加更新/导入识别结果提示 - v1.7.32 -3. 增加都某些机场不规范订阅的识别 -v1.7.33 -4. 调整节点列表样式 -v1.7.33 - -#### 2018.07.12 -1. 导入Quantumult显示分组(vmess除外) - v1.7.30 -2. 支持识别SSR订阅和批量导入 - v1.7.31 -3. 支持识别V2Ray订阅和批量导入 - v1.7.31 - -#### 2018.07.10 -1. Quantumult最新TF已经修正obfs-host问题,所以删除hack逻辑 - v1.7.28 -2. 测试识别V2Ray链接(vmess://) - v1.7.29 - -#### 2018.07.09 -1. 修复下滑问题 - v1.7.27 -2. 修复Quantumult无法获取配置DNS问题 - v1.7.27 -3. 去除URL Scheme导出filter和rejection的特性,因为Quantumult无法识别里面的Policy - v1.7.27 -4. 支持使用特殊占位符``WidgetHeader``来配置Quantumult的Widget节点 - v1.7.27 - -#### 2018.07.08 -1. hack解决圈obfs-host识别问题 - v1.7.26 -2. 修复占位符会替换策略组名问题(占位符不要与节点名冲突)- v1.7.26 -3. 增加Quantumult小组件开关 - v1.7.26 -4. 导出为Quantumult时,不选择导出则只更新filter和rejection两部分 - v1.7.26 - -#### 2018.07.07 -1. 支持导出为Quantumult格式配置(beta),测试前请备份配置先 - v1.7.25 - -#### 2018.07.06 -1. Surge开关使用最新API判断,可不预先设置 - v1.7.24 - -#### 2018.07.05 -1. 调整Surge开关状态逻辑,如不能显示请反馈 - v1.7.22 -2. Surge开关状态需要先进行初始设置(长按图标即可) - v1.7.23 - -#### 2018.07.03 -1. 小组件点击逻辑不变,但会显示Surge开关状态 - -#### 2018.06.30 -1. 修复Surge2不开启MITM时报错的问题 - -#### 2018.06.26 -1. 增加占位符重命名 -2. 修复批量导入节点在更新时会重复出现的问题 - -#### 2018.06.24 -1. 关键字删除时,可以使用正则表达式,但除了``\s``(空格),这是分隔符 - -#### 2018.06.23 -1. 列表不选择时默认为DIRECT改为默认全选 - -#### 2018.06.22 -1. 调整右上角按钮,分别改为支付宝红包领取和备份当前配置 -2. 调整UI -3. 备份改为存储到iCloud -4. 修复可以创建空占位符问题 - -#### 2018.06.21 -1. ``// replacement``注释现在将会替换除General、Proxy Group和MITM的CA部分(替换规则不需要重新生成证书)外的其他内容 -2. 修复部分情况下hostname为空的错误 - -#### 2018.06.20 -1. 脚本右上角增加导出data.js文件选项,方便后续生成订阅 - -#### 2018.06.19 -1. 修复完成按钮无法保存后缀问题 - -#### 2018.06.18 -1. rename注释可以识别等号,但需要使用转义``\=``,每个替换的左边可以是一个正则表达式,右边为替换字符串 -2. 适配新版TF,脚本主界面右上角可以直接进入Surge - -#### 2018.06.17 -1. 直接导出到Surge的时间设置为10s,10s后会关闭开启的内置服务器防止耗电过多问题 - -#### 2018.06.16 -1. 为保证小组件快捷生成成功率,取消生成后回到JSBox自动退出功能,添加按钮手动操作 -2. 小组件支持显示规则替换仓库信息(仅支持Github托管master分支的配置) -3. 修复rename和replacement注释因边界无法识别问题 - -#### 2018.06.15 -1. 支持重命名默认策略组,需要在进阶设置中代理分组中添加注释:// rename: o1 = n1, o2 = n2 -2. 支持替换lhie1的所有规则,可以配合分组代理加载其他规则,用法在进阶设置中代理规则添加注释:// replacement: https://xxxx - -#### 2018.06.14 -1. 支持Surge2(未测试,因为我没有Surge2) -2. 修复Surge2的跳转问题 - -#### 2018.06.13 -1. 更新脚本简介 - -#### 2018.06.12 -1. 更新方式改为静默更新,有新版本将不会再弹出提示更新而在后台静默更新,更新后可不重启脚本生成规则,修复因更新脚本造成打断操作而产生心里阴影面积过大的问题 -2. 修复ProxyHeader占位符丢失问题 -3. 去除重复后缀 -4. 先进行占位符替换,避免影响General的内容,占位符命名请不要与Proxy Group里面的内容相同 - -#### 2018.06.11 -1. 调整界面 -2. 去除UPD设置选项,增加节点后缀设置,可用于UDP、TFO和插件设置 -3. 修复undefined问题 - -#### 2018.06.10 -1. 生成配置时检查特殊代理设置服务器是否存在,不存在则忽略避免报错 -2. 删除**批量Auto**选项 -3. 增加**策略组别**选项,用于生成用于进阶设置的占位符,和ProxyHeader类似 -4. 修复无法删除策略组占位符问题 -5. 增加特殊代理可选择策略组功能 -6. 修复特殊代理direct无效问题 - -如担心数据丢失,可对脚本内data.js文件进行备份 - -#### 2018.06.07 -1. 修复脚本名称更改后升级和小组件异常问题 - -#### 2018.06.06 -1. 删除导入节点时对组别进行保存的功能,因为有列表更新,所以貌似也没什么用 -2. 默认给所有节点打开tfo,开关明天做 - -#### 2018.06.03 -1. 删除分组时可以选择按照关键字删除 -2. 修复单个组别无法进行关键字删除的问题 - -#### 2018.06.02 -1. 小组件/启动器在规则有更新时显示最新的commit message - -#### 2018.05.27 -1. 适配两种奇葩的机场托管节点识别(分别是在节点前面加空格和节点后面加逗号) -2. 修复部分ss节点无法识别问题 -3. 修复windows下Shadowsocks二维码无法识别问题 -4. 打开小组件或启动器时同时检查脚本和规则更新 - -#### 2018.05.26 -1. 修复obfs识别问题 -2. 调整更新等待时间 -3. 区分启动器和小组件样式,启动器加入关闭按钮(性能模式启动器有效) - -#### 2018.05.25 -1. 修正不添加节点不能导出规则问题 -2. 调整启动器启动样式,启动后点击上下两部分空白可退出脚本 - -#### 2018.05.22 -1. 调整Widget样式 - -#### 2018.05.15 -1. 增加一个特性:在Surge里面将配置文件(.conf)分享到脚本,脚本会将当前配置的自定义规则(通过Surge的Extension添加的)追加到进阶设置里。 - -> 1的识别的配置文件需要时脚本生成的且进阶设置的代理规则包括``# Custom``注释 - -#### 2018.05.13 -1. 调整导入节点表现,当列表中已有该组时,会更新已有组 -2. 导入节点增加“更新节点列表”选项,用于升级列表中所有组 - -> 上述1,2仅对1.6.19及以后导入的组别生效 - -#### 2018.05.12 -1. 调整Widget样式,去除启动器启动时的导航栏 -2. 去除输入法上方的提示栏 -3. 修复定义ProxyHeader失败问题 - -#### 2018.05.11 -1. 增加对http/https/socks5/socks5-tls代理类型的支持,统一理解为Surge链接 -2. 增强剪贴板导入,以行为单位支持批量ss链接、Surge链接和托管地址混合导入 - -#### 2018.05.10 -1. 修复Safari拓展节点消失问题 -2. 优化拉取速度,更新规则耗时更短 -3. 当节点列表只有一个分组时,节点倒序、批量Auto和删除节点将不会弹出菜单,直接操作当前唯一组 - -#### 2018.05.09 -1. 调整UI -2. 增加组别支持,每次导入的节点会被分为一组,可以根据组别进行倒序、Auto和删除操作 -3. 取消对``固定脚本``的支持,列表外上滑将不再减少高度 -4. 节点重命名选项可以对所在组别进行重命名 - -> 由于列表结构改变,原本节点列表的数据会丢失,请重新导入 - -#### 2018.05.08 -1. 增加Safari拓展,在页面添加规则 -2. 修复图标过大导致JSBox启动器无法载入问题 -3. 调整``全部Auto``,如果当前已经全选,则全部反选一次 -4. 调整``导入节点``,如果列表中已经存在,则不会重复显示 -5. 修复自动生成时选择取消Action Sheet时脚本不退出问题 - -#### 2018.05.07 -1. 增加小组件支持 -2. 修复批量导入时不能识别``\r``换行的问题 -3. 自动生成后回到JSBox自动退出脚本 -4. 特殊代理增加单独查看、清除按钮,支持选择Direct -5. 调整小组件按钮位置,规则无更新时下方小字不再显示 - -#### 2018.05.06 -1. .conf的所有配置项现在都可以在进阶配置中定义,大部分设置可以使用``-(减号)``对lhie1配置剔除 -2. 内部代码调整,异常请反馈 -3. 部分UI调整 -4. 增加特殊代理设置,左滑节点即可设置 -5. 文档修正,感谢**Mornwind**的PR - -#### 2018.05.05 -1. 增加去自定义规则删除(优先级低于添加),写法: - ![](https://github.com/Fndroid/jsbox_script/blob/master/imgs/Rules-lhie1_pre2.jpg?raw=true) -2. 修复进阶设置Gallery切换按钮不联动的问题 -3. 增加关于页面 - - 感谢**Mornwind、几位匿名赞赏者**的咖啡 - -#### 2018.05.04 -1. 检测文件名,不合法则采用Action Sheet分享 -2. 由于无法检测脚本是否在``固定脚本``中运行,所以增加了上下滑动列表高度变化,虽然很突兀,但是没办法 -3. 增加节点重命名和排序 -4. 进阶设置界面调整,DNS设置改为General,MITM默认为lhie1的,不开启则为空 -5. 修正Surge3跳转 -6. 增加URL Scheme支持,添加``auto=1``即可根据配置自动生成一次规则 - -#### 2018.05.03 -1. 增加直接导出到Surge功能,但有限制,进入Surge后不要等待过长时间确定安装 -2. 更改TestFlight选项名为UDP -3. 尝试突破Surge加载问题 -4. 修复托管direct多余问题 - - 感谢**Nicked、Mornwind**的咖啡 - -#### 2018.05.02 - -1. 增加批量导入ss节点(剪贴板) -2. 增加批量导入Surge节点(剪贴板) -3. 增加生成的过渡动画代替默认的loading -4. 修复TINYGIF的问题 -5. 增加配置Proxy Group,``ProxyHeader``为Auto节点名,``Proxy Header``为所有节点名,可更改Auto设置 -6. 删除导入的相册选择选项,如需此操作请更新JSBox - - 感谢**Wangsc1 M**的咖啡 - -#### 2018.05.01 - -1. 跳转到主应用运行 -2. 调整界面(节点操作栏不再跟随滚动,开关说明) -3. 解除底部按钮固定,适配iPhoneX屏幕 - -> 无法运行无解,我无法复现... - -#### 2018.04.30 A - -1. 每次退出脚本先保存环境,下次进入可以直接使用 -2. 修改图标 -3. 支持导入Surge节点 -4. 修复``墙洞``托管无法识别问题 - -> 仅测试了cordcloud和rixCloud的托管导入,其他如果不能导入的,要不把托管借我测试再改密,要不等别人借我测试 - -> 脚本无法启动问题已经提交JSBox作者调试 - -#### 2018.04.30 - -1. 修复TF无效(节点无udp-relay=true)的问题 -2. 修复升级日志遮挡问题 -3. 由于``$addin.save``无回调,增加2s防止极端情况更新失败 -4. 调整界面,去掉Auto显示框,改为列表显示形式 -5. 增加``MITM``、``DNS``和``Rule Custom``设置 -6. 修正配置可能丢失的问题 -7. 修复输入框遮挡问题 -8. 修正配置文件与wf部分区别 -9. 增加MITM开关 - -> iOS 10.3.3如果能进入脚本,请TG和我说一下 - -#### 2018.04.29 - -1. 不选Auto时,Auto则为DIRECT,生成后请手动选择Proxy -2. 保存的``托管``或``ss://``改为以名称显示(可能不能很好兼容上版本) -3. 增加倒序和全部添加到Auto功能 -3. 调整界面大小 -4. 修正无法识别托管文件名的问题 diff --git a/JSBox/Rules-lhie1/version.fndroid b/JSBox/Rules-lhie1/version.fndroid deleted file mode 100644 index 770d2d0..0000000 --- a/JSBox/Rules-lhie1/version.fndroid +++ /dev/null @@ -1 +0,0 @@ -1.9.90 \ No newline at end of file diff --git a/README.md b/README.md index f18867d..9e372c6 100644 --- a/README.md +++ b/README.md @@ -61,18 +61,18 @@ Quantumult | [@Jacky Y](https://t.me/WatanabeMayu) | [Quantumult](https://t.me/q --- -### JSBox +### Subscription Converter ```` -Surge:https://xteko.com/redir?name=Rules-lhie1&url=https://raw.githubusercontent.com/lhie1/Rules/master/JSBox/Rules-lhie1.box +https://sub.dleris.best ```` --- -### Remote Files +### Shadowrocket (Remote Files) ```` -Shadowrocket:https://raw.githubusercontent.com/lhie1/Rules/master/Shadowrocket/Complete.conf +https://raw.githubusercontent.com/lhie1/Rules/master/Shadowrocket/Complete.conf ```` ---