Passed
Push — main ( 1b7a26...4b0048 )
by YeBeKhe
02:25
created

VmessSingbox()   C

Complexity

Conditions 11
Paths 22

Size

Total Lines 68
Code Lines 53

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 11
eloc 53
c 1
b 0
f 0
nc 22
nop 1
dl 0
loc 68
rs 6.8787

How to fix   Long Method    Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
3
header("Content-type: application/json;");
4
5
function create_tehran_timestamp_tomorrow() {
6
  date_default_timezone_set('Asia/Tehran');
7
  $dateTomorrow = new DateTime('tomorrow');
8
  $timestampTomorrow = strtotime($dateTomorrow->format('Y-m-d H:i:s'));
9
  return $timestampTomorrow;
10
}
11
12
function isEvenLength($str) {
13
    $length = strlen($str);
14
    return $length % 2 == 0;
15
}
16
17
function process_jsons($input, $locationNames){
18
    $input[0]['outbounds'] = array_merge($input[0]['outbounds'], array_filter($locationNames));
19
    return $input;
20
}
21
22
function extract_names($input){
23
    foreach($input as $config){
24
        if ($config['tag'] !== ""){
25
             $locationNames[] = $config['tag'];
26
        }
27
    }
28
    return $locationNames;
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $locationNames does not seem to be defined for all execution paths leading up to this point.
Loading history...
29
}
30
31
function processWsPath($input) {
32
  if (strpos($input, '/') === 0) {
33
    $input = substr($input, 1);
34
  }
35
  $max_early_data = 0;
36
  if (strpos($input, '?ed=2048') !== false) {
37
    $input = str_replace('?ed=2048', '', $input);
38
    $max_early_data = 2048;
39
  }
40
  $output = [
41
      "path" => "/" . $input,
42
      "max_early_data" => $max_early_data
43
  ];
44
  
45
  return $output;
46
}
47
48
function VmessSingbox($VmessUrl)
49
{
50
    $decode_vmess = decode_vmess($VmessUrl);
51
    if (is_null($decode_vmess["ps"]) || $decode_vmess["ps"] === "") {
52
        return null;
53
    }
54
    $configResult = [
55
        "tag" => $decode_vmess["ps"],
56
        "type" => "vmess",
57
        "server" => $decode_vmess["add"],
58
        "server_port" => intval($decode_vmess["port"]),
59
        "uuid" => $decode_vmess["id"],
60
        "security" => "auto",
61
        "alter_id" => intval($decode_vmess["aid"]),
62
        "global_padding" => false,
63
        "authenticated_length" => true,
64
        "packet_encoding" => "",
65
        "multiplex" => [
66
            "enabled" => false,
67
            "protocol" => "smux",
68
            "max_streams" => 32,
69
        ],
70
    ];
71
72
    if ($decode_vmess["port"] === "443" || $decode_vmess["tls"] === "tls") {
73
        $configResult["tls"] = [
74
            "enabled" => true,
75
            "server_name" =>
76
                $decode_vmess["sni"] !== ""
77
                    ? $decode_vmess["sni"]
78
                    : $decode_vmess["add"],
79
            "insecure" => true,
80
            "disable_sni" => false,
81
            "utls" => [
82
                "enabled" => true,
83
                "fingerprint" => "chrome",
84
            ],
85
        ];
86
    }
87
    
88
    if ($decode_vmess["net"] === "ws") {
89
        $pathProcess = processWsPath($decode_vmess["path"]);
90
        $configResult["transport"] = [
91
            "type" => $decode_vmess["net"],
92
            "path" => $pathProcess['path'],
93
            "headers" => [
94
                "Host" =>
95
                    $decode_vmess["host"] !== ""
96
                        ? $decode_vmess["host"]
97
                        : ($decode_vmess["add"] !== ""
98
                            ? $decode_vmess["add"]
99
                            : ""),
100
            ],
101
            "max_early_data" => $pathProcess['max_early_data'],
102
            "early_data_header_name" => "Sec-WebSocket-Protocol",
103
        ];
104
        if ($configResult["transport"]["headers"]["Host"] === "") return null;
105
    } elseif ($decode_vmess["net"] === "grpc") {
106
        $configResult["transport"] = [
107
            "type" => $decode_vmess["net"],
108
            "service_name" => $decode_vmess["path"],
109
            "idle_timeout" => "15s",
110
            "ping_timeout" => "15s",
111
            "permit_without_stream" => false,
112
        ];
113
    }
114
115
    return $configResult;
116
}
117
118
function VlessSingbox($VlessUrl)
119
{
120
    $decoded_vless = parseProxyUrl($VlessUrl, "vless");
121
    //print_r($decoded_vless);
122
    if (is_null($decoded_vless["hash"]) || $decoded_vless["hash"] === "") {
123
        return null;
124
    }
125
    $configResult = [
126
        "tag" => $decoded_vless["hash"],
127
        "type" => "vless",
128
        "server" => $decoded_vless["hostname"],
129
        "server_port" => intval($decoded_vless["port"]),
130
        "uuid" => $decoded_vless["username"],
131
        "flow" => !is_null($decoded_vless["params"]["flow"])
132
            ? "xtls-rprx-vision"
133
            : "",
134
        "packet_encoding" => "xudp",
135
        "multiplex" => [
136
            "enabled" => false,
137
            "protocol" => "smux",
138
            "max_streams" => 32,
139
        ],
140
    ];
141
142
    if (
143
        $decoded_vless["port"] === "443" ||
144
        $decoded_vless["params"]["security"] === "tls" ||
145
        $decoded_vless["params"]["security"] === "reality"
146
    ) {
147
        $configResult["tls"] = [
148
            "enabled" => true,
149
            "server_name" => !is_null($decoded_vless["params"]["sni"])
150
                ? $decoded_vless["params"]["sni"]
151
                : "",
152
            "insecure" => false,
153
            "utls" => [
154
                "enabled" => true,
155
                "fingerprint" => "chrome",
156
            ],
157
        ];
158
159
        if (
160
            $decoded_vless["params"]["security"] === "reality" ||
161
            isset($decoded_vless["params"]["pbk"])
162
        ) {
163
            $configResult["tls"]["utls"]["fingerprint"] = $decoded_vless["params"]["fp"];
164
            $configResult["tls"]["reality"] = [
165
                "enabled" => true,
166
                "public_key" => !is_null($decoded_vless["params"]["pbk"])
167
                    ? $decoded_vless["params"]["pbk"]
168
                    : "",
169
                "short_id" => !is_null($decoded_vless["params"]["sid"])
170
                    ? $decoded_vless["params"]["sid"]
171
                    : "",
172
            ];
173
        if (
174
            is_null($decoded_vless["params"]["pbk"]) or
175
            $decoded_vless["params"]["pbk"] === ""
176
        ) {
177
            return null;
178
        }
179
        }
180
    }
181
    $transportTypes = [
182
        "ws" => [
183
            "type" => $decoded_vless["params"]["type"],
184
            "path" => processWsPath($decoded_vless["params"]["path"])['path'],
185
            "headers" => [
186
                "Host" => !is_null($decoded_vless["params"]["host"])
187
                    ? $decoded_vless["params"]["host"]
188
                    : "",
189
            ],
190
            "max_early_data" => processWsPath($decoded_vless["params"]["path"])['max_early_data'],
191
            "early_data_header_name" => "Sec-WebSocket-Protocol",
192
        ],
193
        "grpc" => [
194
            "type" => $decoded_vless["params"]["type"],
195
            "service_name" => $decoded_vless["params"]["serviceName"],
196
            "idle_timeout" => "15s",
197
            "ping_timeout" => "15s",
198
            "permit_without_stream" => false,
199
        ],
200
    ];
201
    if (isset($decoded_vless["params"]["type"])) {
202
        if (
203
            $decoded_vless["params"]["type"] === "ws" ||
204
            $decoded_vless["params"]["type"] === "grpc"
205
        ) {
206
            $configResult["transport"] =
207
                $transportTypes[$decoded_vless["params"]["type"]];
208
        }
209
    }
210
    return $configResult;
211
}
212
213
function TrojanSingbox($TrojanUrl)
214
{
215
    $decoded_trojan = parseProxyUrl($TrojanUrl);
216
    if (is_null($decoded_trojan["hash"]) || $decoded_trojan["hash"] === "") {
217
        return null;
218
    }
219
    $configResult = [
220
        "tag" => $decoded_trojan["hash"],
221
        "type" => "trojan",
222
        "server" => $decoded_trojan["hostname"],
223
        "server_port" => intval($decoded_trojan["port"]),
224
        "password" => $decoded_trojan["username"],
225
        "multiplex" => [
226
            "enabled" => false,
227
            "protocol" => "smux",
228
            "max_streams" => 32,
229
        ],
230
    ];
231
232
    if (
233
        $decoded_trojan["port"] === "443" ||
234
        $decoded_trojan["params"]["security"] === "tls"
235
    ) {
236
        $configResult["tls"] = [
237
            "enabled" => true,
238
            "server_name" => !is_null($decoded_trojan["params"]["sni"])
239
                ? $decoded_trojan["params"]["sni"]
240
                : "",
241
            "insecure" => true,
242
            "utls" => [
243
                "enabled" => true,
244
                "fingerprint" => "chrome",
245
            ],
246
        ];
247
    }
248
249
    $transportTypes = [
250
        "ws" => [
251
            "type" => $decoded_trojan["params"]["type"],
252
            "path" => processWsPath($decoded_trojan["params"]["path"])["path"],
253
            "headers" => [
254
                "Host" => $decoded_trojan["params"]["host"],
255
            ],
256
        ],
257
        "grpc" => [
258
            "type" => $decoded_trojan["params"]["type"],
259
            "service_name" => $decoded_trojan["params"]["serviceName"],
260
            "idle_timeout" => "15s",
261
            "ping_timeout" => "15s",
262
            "permit_without_stream" => false,
263
        ],
264
    ];
265
    if (isset($decoded_trojan["params"]["type"])) {
266
        if (
267
            $decoded_trojan["params"]["type"] === "ws" ||
268
            $decoded_trojan["params"]["type"] === "grpc"
269
        ) {
270
            $configResult["transport"] =
271
                $transportTypes[$decoded_trojan["params"]["type"]];
272
        }
273
    }
274
    return $configResult;
275
}
276
277
function ShadowsocksSingbox($ShadowsocksUrl) {
278
    $decoded_shadowsocks = ParseShadowsocks($ShadowsocksUrl);
279
    if (is_null($decoded_shadowsocks['name']) || $decoded_shadowsocks['name'] === ""){
280
        return null;
281
    }
282
    if ($decoded_shadowsocks['encryption_method'] === "chacha20-poly1305") {
283
        return null;
284
    }
285
    $configResult = [
286
        'tag' => $decoded_shadowsocks['name'],
287
        'type' => "shadowsocks",
288
        'server' => $decoded_shadowsocks['server_address'],
289
        'server_port' => intval($decoded_shadowsocks['server_port']),
290
        'method' => $decoded_shadowsocks['encryption_method'],
291
        'password' => $decoded_shadowsocks['password'],
292
        'plugin' => "",
293
        'plugin_opts' => ""
294
    ];
295
    return $configResult;
296
}
297
298
function TuicSingbox($TuicUrl) {
299
    $decodedTuic = ParseTuic($TuicUrl);
300
    if (
301
        is_null($decodedTuic['hash']) ||
302
        $decodedTuic['hash'] === ""
303
    ) {
304
        return null;
305
    }
306
307
    $configResult = [
308
        "tag" => $decodedTuic["hash"],
309
        "type" => "tuic",
310
        "server" => $decodedTuic['hostname'],
311
        "server_port" => intval($decodedTuic['port']),
312
        "uuid" => $decodedTuic['username'],
313
        "password" => $decodedTuic['pass'],
314
        "congestion_control" => $decodedTuic['params']['congestion_control'],
315
        "udp_relay_mode" => $decodedTuic['params']['udp_relay_mode'],
316
        "zero_rtt_handshake" => false,
317
        "heartbeat" => "10s",
318
        "network" => "tcp",
319
    ];
320
321
    $configResult['tls'] = [
322
            "enabled" => true,
323
            "disable_sni" => isset($decodedTuic['params']['sni']) ? false : true,
324
            "server_name" => isset($decodedTuic['params']['sni']) ? $decodedTuic['params']['sni'] : "",
325
            "insecure" => isset($decodedTuic['params']['allow_insecure']) && intval($decodedTuic['params']['allow_insecure']) === 1 ? true : false,
326
            "alpn" => [
327
                "h3",
328
                "spdy/3.1"
329
            ],
330
        ];
331
    if (!isset($decodedTuic['params']['alpn']) || is_null($decodedTuic['params']['alpn']) || $decodedTuic['params']['alpn'] === "") {
332
      unset($configResult['tls']["alpn"]);
333
    }
334
335
    return $configResult;
336
}
337
338
function Hy2Singbox($Hy2Url) {
339
    $decodedHy2 = ParseTuic($Hy2Url);
340
    if (
341
        is_null($decodedHy2['hash']) ||
342
        $decodedHy2['hash'] === ""
343
    ) {
344
        return null;
345
    }
346
347
    $configResult = [
348
        "tag" => $decodedHy2["hash"],
349
        "type" => "hysteria2",
350
        "server" => $decodedHy2['hostname'],
351
        "server_port" => intval($decodedHy2['port']),
352
        "up_mbps" => 0,
353
        "down_mbps" => 0,
354
        "password" => $decodedHy2['username'],
355
        "network" => "tcp",
356
    ];
357
358
359
    $configResult['obfs'] = [
360
        "type" => $decodedHy2['params']['obfs'],
361
        "password" => $decodedHy2['params']['obfs-password'],
362
    ];
363
    $configResult['tls'] = [
364
            "enabled" => true,
365
            "disable_sni" => isset($decodedHy2['params']['sni']) ? false : true,
366
            "server_name" => isset($decodedHy2['params']['sni']) ? $decodedHy2['params']['sni'] : "",
367
            "insecure" => isset($decodedHy2['params']['insecure']) && intval($decodedHy2['params']['insecure']) === 1 ? true : false,
368
            "alpn" => [
369
                "h3"
370
            ],
371
    ];
372
    /*if (!isset($decodedHy2['params']['alpn']) || is_null($decodedHy2['params']['alpn']) || $decodedHy2['params']['alpn'] === "") {
373
      unset($configResult['tls']["alpn"]);
374
    }*/
375
376
    return $configResult;
377
}
378
379
function GenerateConfig($input, $output, $theType){
380
    $outbound = [];
381
    $v2ray_subscription = str_replace(" ", "%20", $input);
382
383
    $configArray = explode("\n", $v2ray_subscription);
384
    foreach ($configArray as $config) {
385
        $configType = detect_type($config);
386
        $config = str_replace("%20", " ", $config);
387
        switch($configType) {
388
            case "vmess":
389
                $configSingbox = VmessSingbox($config);
390
                break;
391
            case "vless":
392
                $configSingbox = VlessSingbox($config);
393
                break;
394
            case "trojan":
395
                $configSingbox = TrojanSingbox($config);
396
                break;
397
            case "tuic":
398
                $configSingbox = TuicSingbox($config);
399
                break;
400
            case "hy2":
401
                $configSingbox = Hy2Singbox($config);
402
                break;
403
            case "ss":
404
                $configSingbox = ShadowsocksSingbox($config);
405
                break;
406
        }
407
        if (!is_null($configSingbox)){
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $configSingbox does not seem to be defined for all execution paths leading up to this point.
Loading history...
408
            $configName = $configSingbox['tag'];
409
            if (stripos($configName, "RELAY🚩")){
410
                $configLocation = "RELAY🚩";
411
            } else {
412
                $pattern = '/\b[A-Z]{2}\b[\x{1F1E6}-\x{1F1FF}]{2}/u';
413
                preg_match_all($pattern, $configName, $matches);
414
                $configLocation = $matches[0][0];
415
            }
416
            if (!in_array($configSingbox, $outbound[$configLocation])) {
417
                $outbound[$configLocation][] = $configSingbox;
418
            }
419
        }
420
    }
421
    $templateMap = [
422
        "nold" => "nekobox_1.1.7.json", 
423
        "nnew" => "nekobox_1.1.8.json", 
424
        "sfia" => "sfi.json"
425
    ];
426
    $templateBase = json_decode(
427
        file_get_contents("modules/singbox/" . $templateMap[$output]), 
428
        true
429
    );
430
    $templateManual = json_decode(
431
        file_get_contents("modules/singbox/manual.json"), 
432
        true
433
    );
434
    $templateUrltest = json_decode(
435
        file_get_contents("modules/singbox/url_test.json"), 
436
        true
437
    );
438
    
439
    $outboundUrltest =[];
0 ignored issues
show
Unused Code introduced by
The assignment to $outboundUrltest is dead and can be removed.
Loading history...
440
    $outboundSingles = [];
441
    $locationNames = [];
442
    $outboundBasedOnLocationFull = [];
443
    foreach ($outbound as $location => $outboundEachLocation){
444
        $locationNames[] = $location;
445
        $eachLocationNames = extract_names($outboundEachLocation);
446
        $templateUrltest[0]['tag'] = $location;
447
        $outboundBasedOnLocation = process_jsons($templateUrltest, $eachLocationNames);
448
        $outboundBasedOnLocationFull = array_merge($outboundBasedOnLocationFull, $outboundBasedOnLocation);
449
        $outboundSingles = array_merge($outboundSingles, $outboundEachLocation);
450
    }
451
452
    $templateManual = process_jsons($templateManual, $locationNames);
453
    $templateUrltest[0]['tag'] = "URL-TEST | رایگان";
454
    $configNamesFull = extract_names($outboundSingles);
455
    $outboundUrltest = process_jsons($templateUrltest, $configNamesFull);
456
    $outboundUrltest = array_merge($outboundUrltest, $outboundBasedOnLocationFull);
457
458
    $templateBase['outbounds'] = array_merge($templateManual, $outboundUrltest, $outboundSingles,  $templateBase['outbounds']);
459
    $finalJson = json_encode($templateBase, JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT);
460
    $headerText = "//profile-title: base64:" . base64_encode("TVC | " . strtoupper($theType)) . "
461
//profile-update-interval: 1
462
//subscription-userinfo: upload=0; download=0; total=10737418240000000; expire=2546249531
463
//support-url: https://t.me/v2raycollector
464
//profile-web-page-url: https://github.com/yebekhe/TelegramV2rayCollector
465
466
";
467
    $createJsonc = $headerText . $finalJson ;
468
    return $createJsonc;
469
}
470
471
function GenerateConfigLite($input, $output, $theType){
472
    $outbound = [];
473
    $v2ray_subscription = $input;
474
475
    $configArray = explode("\n", $v2ray_subscription);
476
    foreach ($configArray as $config) {
477
        $configType = detect_type($config);
478
        switch($configType) {
479
            case "vmess":
480
                $configSingbox = VmessSingbox($config);
481
                break;
482
            case "vless":
483
                $configSingbox = VlessSingbox($config);
484
                break;
485
            case "trojan":
486
                $configSingbox = TrojanSingbox($config);
487
                break;
488
            case "tuic":
489
                $configSingbox = TuicSingbox($config);
490
                break;
491
            case "hy2":
492
                $configSingbox = Hy2Singbox($config);
493
                break;
494
            case "ss":
495
                $configSingbox = ShadowsocksSingbox($config);
496
                break;
497
        }
498
        if (!is_null($configSingbox)){
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $configSingbox does not seem to be defined for all execution paths leading up to this point.
Loading history...
499
            if (!in_array($configSingbox, $outbound)) {
500
                $outbound[] = $configSingbox;
501
            }
502
        }
503
    }
504
    $templateMap = [
505
        "nold" => "nekobox_1.1.7.json", 
506
        "nnew" => "nekobox_1.1.8.json", 
507
        "sfia" => "sfi.json"
508
    ];
509
    $templateBase = json_decode(
510
        file_get_contents("modules/singbox/" . $templateMap[$output]), 
511
        true
512
    );
513
    $templateManual = json_decode(
514
        file_get_contents("modules/singbox/manual.json"), 
515
        true
516
    );
517
    $templateUrltest = json_decode(
518
        file_get_contents("modules/singbox/url_test.json"), 
519
        true
520
    );
521
522
    $names = extract_names($outbound);
523
    $outboundManual = process_jsons($templateManual, $names);
524
    $outboundUrltest = process_jsons($templateUrltest, $names);
525
526
    $templateBase['outbounds'] = array_merge($outboundManual, $outboundUrltest, $outbound,  $templateBase['outbounds']);
527
    $finalJson = json_encode($templateBase, JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT);
528
    $headerText = "//profile-title: base64:" . base64_encode("TVC | " . strtoupper($theType)) . "
529
//profile-update-interval: 1
530
//subscription-userinfo: upload=0; download=0; total=10737418240000000; expire=2546249531
531
//support-url: https://t.me/v2raycollector
532
//profile-web-page-url: https://github.com/yebekhe/TelegramV2rayCollector
533
534
";
535
    $createJsonc = $headerText . $finalJson ;
536
    return $createJsonc;
537
}
538