GenerateConfigLite()   B
last analyzed

Complexity

Conditions 10
Paths 22

Size

Total Lines 66
Code Lines 48

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 10
eloc 48
nc 22
nop 3
dl 0
loc 66
rs 7.2678
c 0
b 0
f 0

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