Passed
Push — main ( 51e6d9...e39e98 )
by YeBeKhe
03:02 queued 57s
created

get_tuic_ip()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

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

475
                        strtoupper(/** @scrutinizer ignore-type */ $type)
Loading history...
476
                    );
477
                    $final_config = build_config($the_config, $type);
478
479
                    $key = ${"array_helper_$type"};
480
481
                    $final_data[$type][$key]["channel"]["username"] = $channel;
482
                    $final_data[$type][$key]["channel"]["title"] = $channel;
483
                    $final_data[$type][$key]["channel"]["logo"] = "null";
484
                    $final_data[$type][$key]["type"] = $is_reality
485
                        ? "reality"
486
                        : $type;
487
                    $final_data[$type][$key]["config"] = $final_config;
488
                    $final_data[$type][$key]["ping"] = $ping_data;
489
                    $final_data[$type][$key]["time"] = tehran_time();
490
491
                    $key++;
492
                    ${"array_helper_$type"} = $key;
493
                    $config_number++;
494
                }
495
            }
496
        }
497
    }
498
    $i++;
499
    return $final_data;
500
}
501