parse_config()   C
last analyzed

Complexity

Conditions 12
Paths 13

Size

Total Lines 24
Code Lines 22

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 12
eloc 22
c 1
b 0
f 0
nc 13
nop 3
dl 0
loc 24
rs 6.9666

How to fix   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
include "flag.php";
3
include "ipinfo.php";
4
include "shadowsocks.php";
5
include "vmess.php";
6
include "xray.php";
7
include "tuic.php";
8
include "hysteria2.php";
9
include "ping.php";
10
11
function numberToEmoji($number)
12
{
13
    $map = [
14
        "0" => "0️⃣",
15
        "1" => "1️⃣",
16
        "2" => "2️⃣",
17
        "3" => "3️⃣",
18
        "4" => "4️⃣",
19
        "5" => "5️⃣",
20
        "6" => "6️⃣",
21
        "7" => "7️⃣",
22
        "8" => "8️⃣",
23
        "9" => "9️⃣",
24
    ];
25
26
    $emoji = "";
27
    $digits = str_split($number);
28
29
    foreach ($digits as $digit) {
30
        if (count($digits) === 1) {
31
            $emoji = $map["0"];
32
        }
33
        if (isset($map[$digit])) {
34
            $emoji .= $map[$digit];
35
        }
36
    }
37
38
    return $emoji;
39
}
40
41
function openLink($url)
42
{
43
    $ch = curl_init();
44
    curl_setopt_array($ch, [
45
        CURLOPT_URL => $url,
46
        CURLOPT_RETURNTRANSFER => 1,
47
        CURLOPT_USERAGENT => "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/109.0.0.0 Safari/537.36",
48
        CURLOPT_FOLLOWLOCATION => true,
49
    ]);
50
    return curl_exec($ch);
51
}
52
53
function convert_to_iran_time($utc_timestamp)
54
{
55
    $utc_datetime = new DateTime($utc_timestamp);
56
    $utc_datetime->setTimezone(new DateTimeZone("Asia/Tehran"));
57
    return $utc_datetime->format("Y-m-d H:i:s");
58
}
59
60
function get_config_time($type, $input)
61
{
62
    preg_match_all(
63
        "/" . $type . ':\/\/[^"]+(?:[^<]+<[^<]+)*<time datetime="([^"]+)"/',
64
        $input,
65
        $times
66
    );
67
    return $times;
68
}
69
70
function get_config_items($type, $input)
71
{
72
    preg_match_all("#>" . $type . "://(.*?)<#", $input, $items);
73
    return $items;
74
}
75
76
function is_valid($input)
77
{
78
    if (stripos($input, "…") !== false or stripos($input, "...") !== false) {
79
        return false;
80
    }
81
    return true;
82
}
83
84
function is_reality($input, $type)
85
{
86
    switch ($type) {
87
        case "vmess":
88
            return false;
89
        case "vless":
90
            if (stripos($input, "reality") !== false) {
91
                return true;
92
            } else {
93
                return false;
94
            }
95
        case "trojan":
96
            return false;
97
        case "tuic":
98
            return false;
99
        case "hy2":
100
            return false;
101
        case "ss":
102
            return false;
103
    }
104
}
105
106
function check_pbk($input)
107
{
108
    if (stripos($input, "pbk=&") !== false) {
109
        return false;
110
    } else {
111
        return true;
112
    }
113
}
114
115
function get_ip($input, $type, $is_reality)
116
{
117
    switch ($type) {
118
        case "vmess":
119
            return get_vmess_ip($input);
120
        case "vless":
121
            return get_vless_ip($input, $is_reality);
122
        case "trojan":
123
            return get_trojan_ip($input);
124
        case "ss":
125
            return get_ss_ip($input);
126
        case "tuic":
127
            return get_tuic_ip($input);
128
        case "hy2":
129
            return get_hy2_ip($input);
130
    }
131
}
132
133
function get_address($input, $type)
134
{
135
    switch ($type) {
136
        case "vmess":
137
            return $input["add"];
138
        case "vless":
139
        case "trojan":
140
            return $input["hostname"];
141
        case "tuic":
142
            return $input["hostname"];
143
        case "hy2":
144
            return $input["hostname"];
145
        case "ss":
146
            return $input["server_address"];
147
    }
148
}
149
150
function is_number_with_dots($s)
151
{
152
    /*
153
     * Returns true if the given string contains only digits and dots, and false otherwise.
154
     */
155
    for ($i = 0; $i < strlen($s); $i++) {
156
        $c = $s[$i];
157
        if (!ctype_digit($c) && $c != ".") {
158
            return false;
159
        }
160
    }
161
    return true;
162
}
163
164
function is_valid_address($address)
165
{
166
    $ipv4_pattern = '/^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$/';
167
    $ipv6_pattern = '/^[0-9a-fA-F:]+$/'; // matches any valid IPv6 address
168
169
    if (
170
        preg_match($ipv4_pattern, $address) ||
171
        preg_match($ipv6_pattern, $address)
172
    ) {
173
        return true;
174
    } elseif (is_number_with_dots($address) === false) {
175
        if (
176
            substr($address, 0, 8) === "https://" ||
177
            substr($address, 0, 7) === "http://"
178
        ) {
179
            $url = filter_var($address, FILTER_VALIDATE_URL);
180
        } else {
181
            $url = filter_var("https://" . $address, FILTER_VALIDATE_URL);
182
        }
183
        if ($url !== false) {
184
            return true;
185
        } else {
186
            return false;
187
        }
188
    }
189
    return false;
190
}
191
192
function get_vmess_ip($input)
193
{
194
    return !empty($input["sni"])
195
        ? $input["sni"]
196
        : (!empty($input["host"])
197
            ? $input["host"]
198
            : $input["add"]);
199
}
200
201
function get_vless_ip($input, $is_reality)
202
{
203
    return $is_reality
204
        ? $input["hostname"]
205
        : (!empty($input["params"]["sni"])
206
            ? $input["params"]["sni"]
207
            : (!empty($input["params"]["host"])
208
                ? $input["params"]["host"]
209
                : $input["hostname"]));
210
}
211
212
function get_trojan_ip($input)
213
{
214
    return !empty($input["params"]["sni"])
215
        ? $input["params"]["sni"]
216
        : (!empty($input["params"]["host"])
217
            ? $input["params"]["host"]
218
            : $input["hostname"]);
219
}
220
221
function get_tuic_ip($input)
222
{
223
    return $input["hostname"];
224
}
225
226
function get_hy2_ip($input)
227
{
228
    return $input["hostname"];
229
}
230
231
function get_ss_ip($input)
232
{
233
    return $input["server_address"];
234
}
235
236
function get_port($input, $type)
237
{
238
    switch ($type) {
239
        case "vmess":
240
            return $input["port"];
241
        case "vless":
242
        case "trojan":
243
            return $input["port"];
244
        case "tuic":
245
            return $input["port"];
246
        case "hy2":
247
            return $input["port"];
248
        case "ss":
249
            return $input["server_port"];
250
    }
251
}
252
253
function get_flag($ip)
254
{
255
    $flag = "";
256
    $ip_info = ip_info($ip);
257
    if (isset($ip_info["country"])) {
258
        $location = $ip_info["country"];
259
        $flag = $location . getFlags($location);
260
    } else {
261
        $flag = "RELAY🚩";
262
    }
263
    return $flag;
264
}
265
266
function get_channels_assets()
267
{
268
    return json_decode(
269
        file_get_contents("modules/channels/channels_assets.json"),
270
        true
271
    );
272
}
273
274
function generate_name($channel, $flag, $is_reality, $number, $type)
275
{
276
    $name = "";
0 ignored issues
show
Unused Code introduced by
The assignment to $name is dead and can be removed.
Loading history...
277
    switch ($is_reality) {
278
        case true:
279
            return
280
                "رایگان | REALITY | " .
281
                "@" .
282
                $channel .
283
                " | " .
284
                $flag .
285
                " | " .
286
                numberToEmoji($number);
287
        case false:
288
            return
289
                "رایگان | " .
290
                $type .
291
                " | @" .
292
                $channel .
293
                " | " .
294
                $flag .
295
                " | " .
296
                numberToEmoji($number);
297
    }
298
}
299
300
function parse_config($input, $type, $is_sub = false)
301
{
302
    switch ($type) {
303
        case "vmess":
304
            return $is_sub
305
                ? decode_vmess($input)
306
                : decode_vmess($type . "://" . $input);
307
        case "vless":
308
        case "trojan":
309
            return $is_sub
310
                ? parseProxyUrl($input, $type)
311
                : parseProxyUrl($type . "://" . $input, $type);
312
        case "tuic":
313
            return $is_sub
314
                ? parseTuic($input)
315
                : parseTuic($type . "://" . $input);
316
        case "hy2":
317
            return $is_sub
318
                ? parseHy2($input)
319
                : parseHy2($type . "://" . $input);
320
        case "ss":
321
            return $is_sub
322
                ? ParseShadowsocks($input)
323
                : ParseShadowsocks($type . "://" . $input);
324
    }
325
}
326
327
function build_config($input, $type)
328
{
329
    switch ($type) {
330
        case "vmess":
331
            return encode_vmess($input);
332
        case "vless":
333
        case "trojan":
334
            return buildProxyUrl($input, $type);
335
        case "tuic":
336
            return buildTuic($input);
337
        case "hy2":
338
            return buildHy2($input);
339
        case "ss":
340
            return BuildShadowsocks($input);
341
    }
342
}
343
344
function get_config($channel, $type)
345
{
346
    $name_array = [
347
        "vmess" => "ps",
348
        "vless" => "hash",
349
        "trojan" => "hash",
350
        "ss" => "name",
351
        "tuic" => "hash",
352
        "hy2" => "hash"
353
    ];
354
    // Fetch the content of the Telegram channel URL
355
    $get = file_get_contents("https://t.me/s/" . $channel);
356
357
    // Load channels_assets JSON data
358
    $channels_assets = get_channels_assets();
359
360
    $matches = get_config_time($type, $get);
361
    $configs = get_config_items($type, $get);
362
363
    $final_data = [];
364
    if ($channel === "V2rayCollectorDonate") {
365
        $key_limit = count($configs[1]) - 20;
366
    } else {
367
        $key_limit = count($configs[1]) - 3;
368
    }
369
    $config_number = 1;
370
371
    foreach (array_reverse($configs[1]) as $key => $config) {
372
        if ($key >= $key_limit) {
373
            if (is_valid($config)) {
374
                if (strpos($config, "<br/>") !== false) {
375
                    $config = substr($config, 0, strpos($config, "<br/>"));
376
                }
377
378
                $is_reality = is_reality($config, $type);
379
380
                $the_config = parse_config($config, $type);
381
                $check_pbk = $is_reality ? check_pbk($config) : true;
382
383
                $address = get_address($the_config, $type);
384
                if ($check_pbk) {
385
                    if (is_valid_address($address)) {
386
                        $ip = get_ip($the_config, $type, $is_reality);
387
                        $port = get_port($the_config, $type);
388
389
                        @$ping_data = ping($ip, $port);
390
                        if ($ping_data !== "unavailable" || $type === "tuic") {
391
                            $flag = get_flag($ip);
392
393
                            $name_key = $name_array[$type];
394
                            $the_config[$name_key] = generate_name(
395
                                $channel,
396
                                $flag,
397
                                $is_reality,
398
                                $config_number,
399
                                strtoupper($type)
400
                            );
401
402
                            $final_config = build_config($the_config, $type);
403
404
                            $final_data[$key]["channel"]["username"] = $channel;
405
                            $final_data[$key]["channel"]["title"] =
406
                                $channels_assets[$channel]["title"];
407
                            $final_data[$key]["channel"]["logo"] =
408
                                $channels_assets[$channel]["logo"];
409
                            $final_data[$key]["type"] = $is_reality
410
                                ? "reality"
411
                                : $type;
412
                            $final_data[$key]["config"] = $final_config;
413
                            $final_data[$key]["ping"] = $ping_data;
414
                            $final_data[$key]["flag"] = $flag;
415
                            $final_data[$key]["ip"] = $ip;
416
                            $final_data[$key]["time"] = convert_to_iran_time(
417
                                $matches[1][$key]
418
                            );
419
                            $config_number++;
420
                        }
421
                    }
422
                }
423
            }
424
        }
425
    }
426
    // Return the final data array
427
    return $final_data;
428
}
429
430
function detect_type($input)
431
{
432
    if (substr($input, 0, 8) === "vmess://") {
433
        return "vmess";
434
    } elseif (substr($input, 0, 8) === "vless://") {
435
        return "vless";
436
    } elseif (substr($input, 0, 9) === "trojan://") {
437
        return "trojan";
438
    } elseif (substr($input, 0, 5) === "ss://") {
439
        return "ss";
440
    } elseif (substr($input, 0, 7) === "tuic://") {
441
        return "tuic";
442
    } elseif (substr($input, 0, 6) === "hy2://") {
443
        return "hy2";
444
    } 
445
    
446
447
}
448
449
function process_subscription($input, $channel)
450
{
451
    $name_array = [
452
        "vmess" => "ps",
453
        "vless" => "hash",
454
        "trojan" => "hash",
455
        "ss" => "name",
456
        "tuic" => "hash",
457
        "hy2" => "hash",
458
    ];
459
460
    $final_data = [];
461
    $configs = explode("\n", $input);
462
    $array_helper_vmess = 0;
463
    $array_helper_vless = 0;
464
    $array_helper_ss = 0;
465
    $array_helper_trojan = 0;
466
    $array_helper_tuic = 0;
467
    $array_helper_hy2 = 0;
468
    $config_number = 1;
469
    $i = 0;
470
    $channel = $channel . " | Donated";
471
    foreach ($configs as $config) {
472
        $type = detect_type($config);
473
        $is_reality = is_reality($config, $type);
474
475
        $the_config = parse_config($config, $type, true);
476
        $check_pbk = $is_reality ? check_pbk($config) : true;
477
478
        $address = get_address($the_config, $type);
479
        if ($check_pbk) {
480
            if (is_valid_address($address)) {
481
                $ip = get_ip($the_config, $type, $is_reality);
482
                $port = get_port($the_config, $type);
483
484
                @$ping_data = ping($ip, $port);
485
                if ($ping_data !== "unavailable" || $type === "tuic") {
486
                    $flag = get_flag($ip);
487
488
                    $name_key = $name_array[$type];
489
                    $the_config[$name_key] = generate_name(
490
                        $channel,
491
                        $flag,
492
                        $is_reality,
493
                        $config_number,
494
                        strtoupper($type)
0 ignored issues
show
Bug introduced by
It seems like $type can also be of type null; however, parameter $string of strtoupper() does only seem to accept string, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

494
                        strtoupper(/** @scrutinizer ignore-type */ $type)
Loading history...
495
                    );
496
                    $final_config = build_config($the_config, $type);
497
498
                    $key = ${"array_helper_$type"};
499
500
                    $final_data[$type][$key]["channel"]["username"] = $channel;
501
                    $final_data[$type][$key]["channel"]["title"] = $channel;
502
                    $final_data[$type][$key]["channel"]["logo"] = "null";
503
                    $final_data[$type][$key]["type"] = $is_reality
504
                        ? "reality"
505
                        : $type;
506
                    $final_data[$type][$key]["config"] = $final_config;
507
                    $final_data[$type][$key]["ping"] = $ping_data;
508
                    $final_data[$type][$key]["time"] = tehran_time();
509
510
                    $key++;
511
                    ${"array_helper_$type"} = $key;
512
                    $config_number++;
513
                }
514
            }
515
        }
516
    }
517
    $i++;
518
    return $final_data;
519
}
520