xfuture 1.1.5 → 1.1.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/index.js CHANGED
@@ -1,36 +1,88 @@
1
1
  let xFuturePath = "";
2
2
  let os = require("os");
3
- var isMac = true;
3
+ const { spawn } = require('child_process')
4
+ var isMac = false;
4
5
  if (os.platform() === "win32") {
5
- xFuturePath = "./package/win/xFuture";
6
- isMac = false;
6
+ xFuturePath = "./package/windows/xFuture";
7
7
  } else if (os.platform() === "darwin") {
8
8
  xFuturePath = "./package/mac/xFuture"
9
+ isMac = true;
9
10
  } else {
10
11
  throw ("Platform not supported")
11
12
  }
12
13
 
13
14
  const ff = require(xFuturePath);
15
+ const parser = require('./parser');
16
+ parser.isGlobalMode = false;
14
17
 
15
18
  class xFuture {
16
19
 
20
+ SetPassword(password) {
21
+ ff.SetPassword(password);
22
+ }
23
+
17
24
  StartTunnel(url){
18
- return ff.StartTunnel(url);
25
+ if(this.driver.length == 0) return false;
26
+ var json = JSON.stringify(parser.parse(url));
27
+ console.log("json:", json);
28
+ var ret = ff.StartTunnel(json, url);
29
+ if (ret) {
30
+ ret = this.StartProxy();
31
+ }
32
+ return ret;
19
33
  }
20
34
 
21
35
  StopTunnel(){
22
36
  ff.StopTunnel();
23
37
  }
24
38
 
39
+ StartProxy(){
40
+ if (isMac) return true;
41
+ var ret = true;
42
+ try {
43
+ let process = spawn(this.driver, ["global", "socks=127.0.0.1:1081"])
44
+ process.on('close', (code) => {
45
+ console.info('[sysproxy open] close:', code)
46
+ this.invoke(2);
47
+ });
48
+ } catch(err) {
49
+ console.warn('[sysproxy open] failed', err)
50
+ this.invoke(3);
51
+ this.StopTunnel();
52
+ ret = false;
53
+ }
54
+ return ret;
55
+ }
56
+
57
+ // App 进程退出时调用该接口,否则会导致电脑出现断网情况
58
+ StopProxy(){
59
+ if (!isMac) {
60
+ try {
61
+ let process = spawn(this.driver, ["off"])
62
+ process.on('close', function (code) {
63
+ console.info('[sysproxy stop] close:', code)
64
+ });
65
+ } catch(err) {
66
+ console.warn('[sysproxy stop] failed', err)
67
+ }
68
+ }
69
+ ff.StopProxy();
70
+ }
71
+
25
72
  ChangeURL(url){
26
- ff.ChangeURL(url);
73
+ var json = JSON.stringify(parser.parse(url));
74
+ return ff.ChangeURL(json, url);
27
75
  }
28
76
 
29
- SetGlobalMode(isGlobalMode){
30
- ff.SetGlobalMode(isGlobalMode);
77
+ SetGlobalMode(isGlobalMode, ipdir){
78
+ parser.isGlobalMode = isGlobalMode;
79
+ ff.SetGlobalMode(isGlobalMode, ipdir);
31
80
  }
32
81
 
82
+ // 1. Mac 请传 install_helper.sh 和 xfuture_helper 的绝对路径
83
+ // 2. Windows 请传 "maodou" 固定字符串 和 sysproxy.exe 的绝对路径
33
84
  InstallDriver(shell_path, helper_path){
85
+ this.driver = helper_path;
34
86
  return ff.InstallDriver(shell_path, helper_path);
35
87
  }
36
88
 
@@ -55,6 +107,10 @@ class xFuture {
55
107
  SetEventCallback(name, func){
56
108
  ff.SetEventCallback(name, func);
57
109
  }
110
+
111
+ invoke(status) {
112
+ ff.invoke(status);
113
+ }
58
114
  }
59
115
 
60
116
  const xFutureInstance = new xFuture;
@@ -13,7 +13,7 @@ NS_ASSUME_NONNULL_BEGIN
13
13
 
14
14
  +(instancetype)sharedManager;
15
15
 
16
- -(void)setGlobalProxyEnable:(BOOL)enable;
16
+ -(void)setGlobalProxyEnable:(BOOL)enable dir:(NSString *)dir;
17
17
 
18
18
  -(BOOL)startTunnel:(NSString *)url;
19
19
 
@@ -11,20 +11,11 @@
11
11
  </dict>
12
12
  <key>files2</key>
13
13
  <dict>
14
- <key>Frameworks/ExtParser.framework</key>
15
- <dict>
16
- <key>cdhash</key>
17
- <data>
18
- LFatOKRon24FRRDzucwtgHdQZFI=
19
- </data>
20
- <key>requirement</key>
21
- <string>identifier "com.maodou.ExtParser" and anchor apple generic and certificate leaf[subject.CN] = "Apple Development: Casey Cristich (7U948C49D2)" and certificate 1[field.1.2.840.113635.100.6.2.1] /* exists */</string>
22
- </dict>
23
14
  <key>Headers/YDLinkManager.h</key>
24
15
  <dict>
25
16
  <key>hash2</key>
26
17
  <data>
27
- vTuBFysTP+SJof+PsBZr0ccOdmrQUQ20yEVjOcjYDwo=
18
+ fg8MWdsOFHa8jehaqM37qZbkcsL4Q43UUK1K77v6uMc=
28
19
  </data>
29
20
  </dict>
30
21
  <key>Headers/xFuture.h</key>
Binary file
Binary file
Binary file
Binary file
Binary file
package/package.json CHANGED
@@ -1,10 +1,11 @@
1
1
  {
2
2
  "name": "xfuture",
3
- "version": "1.1.5",
3
+ "version": "1.1.7",
4
4
  "description": "electron vpn sdk",
5
- "main": "index.js",
5
+ "main": "x.js",
6
6
  "scripts": {
7
- "test": "test"
7
+ "test": "test",
8
+ "start": "electron ."
8
9
  },
9
10
  "keywords": [
10
11
  "chatgpt"
@@ -23,8 +24,12 @@
23
24
  "package/mac/xfuture_helper",
24
25
  "package/mac/install_helper.sh",
25
26
  "index.js",
27
+ "parser.js",
26
28
  "package.json",
27
- "package/mac/xFuture.framework"
29
+ "package/mac/xFuture.framework",
30
+ "package/windows/sysproxy.exe",
31
+ "package/windows/xFuture.node",
32
+ "package/windows/xray.dll"
28
33
  ],
29
34
  "build": {
30
35
  "mac": {
package/parser.js ADDED
@@ -0,0 +1,286 @@
1
+
2
+
3
+ class xParser {
4
+
5
+ parse(uri){
6
+ if (this.isGlobalMode == null || this.isGlobalMode == undefined) {
7
+ this.isGlobalMode = false;
8
+ }
9
+ if (uri.startsWith("vmess://")) {
10
+ return this.parseVMess(uri);
11
+ }
12
+ else if (uri.startsWith("vless://")) {
13
+ return this.parseVless(uri);
14
+ }
15
+ else if (uri.startsWith("ss://")) {
16
+ return this.parseSS(uri);
17
+ }
18
+ else if (uri.startsWith("trojan://")) {
19
+ return this.parseTrojan(uri);
20
+ }
21
+ return {};
22
+ }
23
+
24
+ parseSS(url){
25
+ url = url.substring(5);
26
+ if (url.includes("@")) {
27
+ var list = url.split("@");
28
+ var prefix = list[0];
29
+ var prefix = this.decode(prefix);
30
+ url = prefix + "@" + list[1];
31
+ }
32
+ else {
33
+ var list = url.split("#");
34
+ var prefix = list[0];
35
+ var prefix = this.decode(prefix);
36
+ url = prefix + "#" + list[1];
37
+ }
38
+
39
+ var list = url.split("#");
40
+ if (list.length != 2) return {};
41
+ var remark = list[1];
42
+ var userInfos = list[0].split("@");
43
+ if (userInfos.length != 2) return {};
44
+
45
+ var userInfo = userInfos[0];
46
+ var serverInfo = userInfos[1];
47
+
48
+ var accountPasswords = userInfo.split(":");
49
+ var ipPorts = serverInfo.split(":");
50
+ if (accountPasswords.length != 2 || ipPorts.length != 2) {
51
+ return {};
52
+ }
53
+ var address = ipPorts[0];
54
+ var port = Integer.parseInt(ipPorts[1]);
55
+
56
+ var security = "";
57
+ var method = accountPasswords[0];
58
+ var password = accountPasswords[1];
59
+ var routing = {};
60
+ var rules = [];
61
+ if (this.isGlobalMode) {
62
+ rules = this.getRules();
63
+ routing.domainStrategy = "IPIfNonMatch";
64
+ }
65
+ else{
66
+ routing.domainStrategy = "AsIs";
67
+ }
68
+ routing.rules = rules;
69
+ var base = this.getBase();
70
+ base.routing = routing;
71
+ base.remark = remark;
72
+ base.address = address;
73
+ base.port = port;
74
+ return base;
75
+ }
76
+
77
+ decode(str) {
78
+ var buffer = Buffer.from(str, 'base64');
79
+ var raw = buffer.toString('utf-8');
80
+ return raw;
81
+ }
82
+
83
+ parseVless(url){
84
+ url = url.substring(8);
85
+ var raw = url;
86
+
87
+ var info = raw.split("@");
88
+ if (info.length < 2) {
89
+ raw = this.decode(url);
90
+ info = raw.split("@");
91
+ }
92
+ if (info.length < 2) return {};
93
+
94
+ var uuid = info[0];
95
+ var config = info[1].split("?");
96
+ if (config.length < 2) return {};
97
+
98
+ var ipAddress = config[0].split(":");
99
+ if (ipAddress.length < 2) return {};
100
+
101
+ var address = ipAddress[0];
102
+ var port = ipAddress[1];
103
+ var suffix = config[1].split("#");
104
+ if (suffix.length < 2) return {};
105
+
106
+ var remark = suffix[1];
107
+
108
+ var tag = "proxy";
109
+ var parameters = suffix[0].split("&");
110
+
111
+ var routing = {};
112
+ var rules = [];
113
+ if (this.isGlobalMode) {
114
+ rules = this.getRules();
115
+ routing.domainStrategy = "IPIfNonMatch";
116
+ }
117
+ else{
118
+ routing.domainStrategy = "AsIs";
119
+ }
120
+ routing.rules = rules;
121
+ var base = this.getBase();
122
+ base.routing = routing;
123
+ base.remark = remark;
124
+ base.address = address;
125
+ base.port = port;
126
+ return base;
127
+ }
128
+
129
+ parseTrojan(url){
130
+ url = url.substring(9);
131
+ var info = url.split("@");
132
+ if (info.length < 2) {
133
+ return {};
134
+ }
135
+
136
+ var uuid = info[0];
137
+ var config = info[1].split("?");
138
+ if (config.length < 2) {
139
+ return {};
140
+ }
141
+
142
+ var ipAddress = config[0].split(":");
143
+ if (ipAddress.length < 2) {
144
+ return {};
145
+ }
146
+ var address = ipAddress[0];
147
+ var port = Integer.parseInt(ipAddress[1]);
148
+
149
+ var suffix = config[1].split("#");
150
+ if (suffix.length < 2) {
151
+ return {};
152
+ }
153
+
154
+ var remark = suffix[1];
155
+ var routing = {};
156
+ var rules = [];
157
+ if (this.isGlobalMode) {
158
+ rules = this.getRules();
159
+ routing.domainStrategy = "IPIfNonMatch";
160
+ }
161
+ else{
162
+ routing.domainStrategy = "AsIs";
163
+ }
164
+ routing.rules = rules;
165
+ var base = this.getBase();
166
+ base.routing = routing;
167
+ base.remark = remark;
168
+ base.address = address;
169
+ base.port = port;
170
+ return base;
171
+
172
+
173
+ }
174
+
175
+ parseVMess(url){
176
+ var url = url.substring(8);
177
+ var vmess = this.decode(url);
178
+ var info = JSON.parse(vmess);
179
+ var address = info.add;
180
+ var port = info.port;
181
+ var remark = info.remark;
182
+ if (remark == null || remark == undefined) {
183
+ remark = info.ps;
184
+ }
185
+ var routing = {};
186
+ var rules = [];
187
+ if (this.isGlobalMode) {
188
+ rules = this.getRules();
189
+ routing.domainStrategy = "IPIfNonMatch";
190
+ }
191
+ else{
192
+ routing.domainStrategy = "AsIs";
193
+ }
194
+ routing.rules = rules;
195
+ var base = this.getBase();
196
+ base.routing = routing;
197
+ base.remark = remark;
198
+ base.address = address;
199
+ base.port = port;
200
+ return base;
201
+ }
202
+
203
+ getRules() {
204
+ var rules = [];
205
+ if (this.isGlobalMode) {
206
+ A = {};
207
+ A.type = "field";
208
+ A.domain = ["geosite:cn"];
209
+ A.outboundTag = "direct";
210
+ rules.push(A);
211
+
212
+ B = {};
213
+ B.type = "field";
214
+ B.domain = ["geosite:cn"];
215
+ B.outboundTag = "direct";
216
+ rules.push(B);
217
+
218
+ C = {};
219
+ C.type = "field";
220
+ C.domain = ["geosite:cn"];
221
+ C.outboundTag = "direct";
222
+ rules.push(C);
223
+ }
224
+ return rules;
225
+ }
226
+
227
+ getBase(){
228
+ var base = {
229
+ "remark": "Unknown",
230
+ "log": {
231
+ "loglevel": "info"
232
+ },
233
+ "inbounds": [
234
+ {
235
+ "settings": {
236
+ "userLevel": 8
237
+ },
238
+ "protocol": "http",
239
+ "port": 1082,
240
+ "tag": "http",
241
+ "listen": "127.0.0.1"
242
+ },
243
+ {
244
+ "settings": {
245
+ "udp": true,
246
+ "auth": "noauth"
247
+ },
248
+ "protocol": "socks",
249
+ "port": 1081,
250
+ "sniffing": {
251
+ "enabled": true,
252
+ "destOverride": [
253
+ "http",
254
+ "tls"
255
+ ]
256
+ },
257
+ "tag": "socks",
258
+ "listen": "127.0.0.1"
259
+ }
260
+ ],
261
+ "outbounds":[
262
+ {
263
+ "protocol": "freedom",
264
+ "tag": "direct"
265
+ },
266
+ {
267
+ "protocol": "freedom",
268
+ "tag": "direct"
269
+ },
270
+ {
271
+ "settings": {
272
+ "response": {
273
+ "type": "http"
274
+ }
275
+ },
276
+ "protocol": "blackhole",
277
+ "tag": "block"
278
+ }
279
+ ]
280
+ }
281
+ return base;
282
+ }
283
+ }
284
+
285
+ const xParserInstance = new xParser;
286
+ module.exports = xParserInstance;
package/x.js ADDED
@@ -0,0 +1,56 @@
1
+ /** main.js */
2
+ const { app, BrowserWindow, crashReporter, ipcMain} = require("electron");
3
+ var engine = require("./index");
4
+
5
+ // app.commandLine.appendArgument("--enable-features=Metal");
6
+ crashReporter.start({ submitURL: 'http://82.157.38.31:1127/crashreports' })
7
+
8
+ let log = crashReporter.getLastCrashReport();
9
+ let path = app.getPath('crashDumps');
10
+ console.log(path);
11
+
12
+ app.on('before-quit', () => {
13
+ engine.InstallDriver("/Users/yangyudong/Documents/dream/xfuture/package/mac/install_helper.sh", "D:\\linkv\\xfuture\\package\\windows\\sysproxy.exe");
14
+ engine.StopProxy();
15
+ })
16
+
17
+ app.on("ready", () => {
18
+ mainWindow = new BrowserWindow({
19
+ width: 800,
20
+ height: 500,
21
+ webPreferences: {
22
+ nodeIntegration: true,
23
+ // nodeIntegrationInWorker: true,
24
+ contextIsolation : false
25
+ }
26
+ });
27
+
28
+ mainWindow.setMenu(null);
29
+
30
+ mainWindow.loadFile("index.html"); // 隐藏Chromium菜单
31
+ mainWindow.webContents.openDevTools() // 开启调试模式
32
+
33
+ mainWindow.on("closed", () => {
34
+ mainWindow = null;
35
+ });
36
+ mainWindow.on("show", () => {
37
+ mainWindow.webContents.send('window-show');
38
+ });
39
+ mainWindow.on("hide", () => {
40
+ mainWindow.webContents.send('window-hide');
41
+ });
42
+ });
43
+
44
+ app.on("window-all-closed", () => {
45
+ /* 在Mac系统用户通过Cmd+Q显式退出之前,保持应用程序和菜单栏处于激活状态。*/
46
+ if (process.platform !== "darwin") {
47
+ app.quit();
48
+ }
49
+ });
50
+
51
+ app.on("activate", () => {
52
+ /* 当dock图标被点击并且不会有其它窗口被打开的时候,在Mac系统上重新建立一个应用内的window。*/
53
+ if (mainWindow === null) {
54
+ createWindow();
55
+ }
56
+ });
@@ -1,46 +0,0 @@
1
- <?xml version="1.0" encoding="UTF-8"?>
2
- <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
3
- <plist version="1.0">
4
- <dict>
5
- <key>BuildMachineOSBuild</key>
6
- <string>23A344</string>
7
- <key>CFBundleDevelopmentRegion</key>
8
- <string>en</string>
9
- <key>CFBundleExecutable</key>
10
- <string>ExtParser</string>
11
- <key>CFBundleIdentifier</key>
12
- <string>com.maodou.ExtParser</string>
13
- <key>CFBundleInfoDictionaryVersion</key>
14
- <string>6.0</string>
15
- <key>CFBundleName</key>
16
- <string>ExtParser</string>
17
- <key>CFBundlePackageType</key>
18
- <string>FMWK</string>
19
- <key>CFBundleShortVersionString</key>
20
- <string>1.0</string>
21
- <key>CFBundleSupportedPlatforms</key>
22
- <array>
23
- <string>MacOSX</string>
24
- </array>
25
- <key>CFBundleVersion</key>
26
- <string>1</string>
27
- <key>DTCompiler</key>
28
- <string>com.apple.compilers.llvm.clang.1_0</string>
29
- <key>DTPlatformBuild</key>
30
- <string></string>
31
- <key>DTPlatformName</key>
32
- <string>macosx</string>
33
- <key>DTPlatformVersion</key>
34
- <string>14.0</string>
35
- <key>DTSDKBuild</key>
36
- <string>23A334</string>
37
- <key>DTSDKName</key>
38
- <string>macosx14.0</string>
39
- <key>DTXcode</key>
40
- <string>1500</string>
41
- <key>DTXcodeBuild</key>
42
- <string>15A240d</string>
43
- <key>LSMinimumSystemVersion</key>
44
- <string>11.0</string>
45
- </dict>
46
- </plist>
@@ -1,128 +0,0 @@
1
- <?xml version="1.0" encoding="UTF-8"?>
2
- <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
3
- <plist version="1.0">
4
- <dict>
5
- <key>files</key>
6
- <dict>
7
- <key>Resources/Info.plist</key>
8
- <data>
9
- 0X1vRvDmL9aHVYXeuivfDeE1wQ8=
10
- </data>
11
- </dict>
12
- <key>files2</key>
13
- <dict>
14
- <key>Resources/Info.plist</key>
15
- <dict>
16
- <key>hash2</key>
17
- <data>
18
- 7GexduFiy5SGHRjiqRrsks7ZiZnzbWL+MZbVv6r/yek=
19
- </data>
20
- </dict>
21
- </dict>
22
- <key>rules</key>
23
- <dict>
24
- <key>^Resources/</key>
25
- <true/>
26
- <key>^Resources/.*\.lproj/</key>
27
- <dict>
28
- <key>optional</key>
29
- <true/>
30
- <key>weight</key>
31
- <real>1000</real>
32
- </dict>
33
- <key>^Resources/.*\.lproj/locversion.plist$</key>
34
- <dict>
35
- <key>omit</key>
36
- <true/>
37
- <key>weight</key>
38
- <real>1100</real>
39
- </dict>
40
- <key>^Resources/Base\.lproj/</key>
41
- <dict>
42
- <key>weight</key>
43
- <real>1010</real>
44
- </dict>
45
- <key>^version.plist$</key>
46
- <true/>
47
- </dict>
48
- <key>rules2</key>
49
- <dict>
50
- <key>.*\.dSYM($|/)</key>
51
- <dict>
52
- <key>weight</key>
53
- <real>11</real>
54
- </dict>
55
- <key>^(.*/)?\.DS_Store$</key>
56
- <dict>
57
- <key>omit</key>
58
- <true/>
59
- <key>weight</key>
60
- <real>2000</real>
61
- </dict>
62
- <key>^(Frameworks|SharedFrameworks|PlugIns|Plug-ins|XPCServices|Helpers|MacOS|Library/(Automator|Spotlight|LoginItems))/</key>
63
- <dict>
64
- <key>nested</key>
65
- <true/>
66
- <key>weight</key>
67
- <real>10</real>
68
- </dict>
69
- <key>^.*</key>
70
- <true/>
71
- <key>^Info\.plist$</key>
72
- <dict>
73
- <key>omit</key>
74
- <true/>
75
- <key>weight</key>
76
- <real>20</real>
77
- </dict>
78
- <key>^PkgInfo$</key>
79
- <dict>
80
- <key>omit</key>
81
- <true/>
82
- <key>weight</key>
83
- <real>20</real>
84
- </dict>
85
- <key>^Resources/</key>
86
- <dict>
87
- <key>weight</key>
88
- <real>20</real>
89
- </dict>
90
- <key>^Resources/.*\.lproj/</key>
91
- <dict>
92
- <key>optional</key>
93
- <true/>
94
- <key>weight</key>
95
- <real>1000</real>
96
- </dict>
97
- <key>^Resources/.*\.lproj/locversion.plist$</key>
98
- <dict>
99
- <key>omit</key>
100
- <true/>
101
- <key>weight</key>
102
- <real>1100</real>
103
- </dict>
104
- <key>^Resources/Base\.lproj/</key>
105
- <dict>
106
- <key>weight</key>
107
- <real>1010</real>
108
- </dict>
109
- <key>^[^/]+$</key>
110
- <dict>
111
- <key>nested</key>
112
- <true/>
113
- <key>weight</key>
114
- <real>10</real>
115
- </dict>
116
- <key>^embedded\.provisionprofile$</key>
117
- <dict>
118
- <key>weight</key>
119
- <real>20</real>
120
- </dict>
121
- <key>^version\.plist$</key>
122
- <dict>
123
- <key>weight</key>
124
- <real>20</real>
125
- </dict>
126
- </dict>
127
- </dict>
128
- </plist>