Passed
Push — main ( 6543c5...0dff68 )
by YeBeKhe
01:52
created

create_tehran_timestamp_tomorrow()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 5
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 1
eloc 4
c 1
b 0
f 0
nc 1
nop 0
dl 0
loc 5
rs 10
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 VmessSingbox($VmessUrl) {
32
    $decode_vmess = decode_vmess($VmessUrl);
33
    if (is_null($decode_vmess['ps']) || $decode_vmess['ps'] === ""){
34
        return null;
35
    }
36
    $configResult = array(
37
        "tag"=> $decode_vmess['ps'],
38
        "type"=> "vmess",
39
        "server"=> $decode_vmess['add'],
40
        "server_port"=> intval($decode_vmess['port']),
41
        "uuid"=> $decode_vmess['id'],
42
        "security"=> "auto",
43
        "alter_id"=> intval($decode_vmess['aid']),
44
        "global_padding"=> false,
45
        "authenticated_length"=> true,
46
        "packet_encoding"=> "",
47
        "multiplex"=> array(
48
          "enabled"=> false,
49
          "protocol"=> "smux",
50
          "max_streams"=> 32
51
        )
52
    );
53
54
    if ($decode_vmess['port'] === "443" || $decode_vmess['tls'] === "tls") {
55
        $configResult["tls"] = array(
56
            "enabled" => true,
57
            "server_name" => $decode_vmess['sni'] !== "" ? $decode_vmess['sni'] : $decode_vmess['add'],
58
            "insecure" => true,
59
            "disable_sni" => false,
60
            "utls"=> array(
61
                "enabled"=> true,
62
                "fingerprint"=> "chrome"
63
              )
64
        );
65
    }
66
67
    if ($decode_vmess['net'] === "ws") {
68
        $configResult["transport"] = array(
69
            "type" => $decode_vmess['net'],
70
            "path" => "/" . $decode_vmess['path'],
71
            "headers" => array(
72
                "Host" => $decode_vmess['host'] !== "" ? $decode_vmess['host'] : $decode_vmess['add'] !== "" ? $decode_vmess['add'] : ""
73
            ),
74
            "max_early_data" => 0,
75
            "early_data_header_name" => "Sec-WebSocket-Protocol"
76
        );
77
    } elseif ($decode_vmess['net'] === "grpc") {
78
        $configResult["transport"] = array(
79
            "type" => $decode_vmess['net'],
80
            "service_name" => $decode_vmess['path'],
81
            "idle_timeout" => "15s",
82
            "ping_timeout" => "15s",
83
            "permit_without_stream" => false
84
        );
85
    }
86
87
    return $configResult;
88
}
89
90
function VlessSingbox($VlessUrl)
91
{
92
    $decoded_vless = parseProxyUrl($VlessUrl, "vless");
93
    //print_r($decoded_vless);
94
    if (is_null($decoded_vless["hash"]) || $decoded_vless["hash"] === "") {
95
        return null;
96
    }
97
    $configResult = [
98
        "tag" => $decoded_vless["hash"],
99
        "type" => "vless",
100
        "server" => $decoded_vless["hostname"],
101
        "server_port" => intval($decoded_vless["port"]),
102
        "uuid" => $decoded_vless["username"],
103
        "flow" => !is_null($decoded_vless["params"]["flow"])
104
            ? "xtls-rprx-vision"
105
            : "",
106
        "packet_encoding" => "xudp",
107
        "multiplex" => [
108
            "enabled" => false,
109
            "protocol" => "smux",
110
            "max_streams" => 32,
111
        ],
112
    ];
113
114
    if (
115
        $decoded_vless["port"] === "443" ||
116
        $decoded_vless["params"]["security"] === "tls" ||
117
        $decoded_vless["params"]["security"] === "reality"
118
    ) {
119
        $configResult["tls"] = [
120
            "enabled" => true,
121
            "server_name" => !is_null($decoded_vless["params"]["sni"])
122
                ? $decoded_vless["params"]["sni"]
123
                : "",
124
            "insecure" => false,
125
            "utls" => [
126
                "enabled" => true,
127
                "fingerprint" => "chrome",
128
            ],
129
        ];
130
131
        if (
132
            $decoded_vless["params"]["security"] === "reality" ||
133
            isset($decoded_vless["params"]["pbk"])
134
        ) {
135
            $configResult["tls"]["reality"] = [
136
                "enabled" => true,
137
                "public_key" => !is_null($decoded_vless["params"]["pbk"])
138
                    ? $decoded_vless["params"]["pbk"]
139
                    : "",
140
                "short_id" => !is_null($decoded_vless["params"]["sid"])
141
                    ? $decoded_vless["params"]["sid"]
142
                    : "",
143
            ];
144
        if (
145
            is_null($decoded_vless["params"]["pbk"]) or
146
            $decoded_vless["params"]["pbk"] === ""
147
        ) {
148
            return null;
149
        }
150
        if (
151
            !isEvenLength($decoded_vless["params"]["sid"]) && 
152
            !is_null($decoded_vless["params"]["sid"])
153
           ) {
154
            return null;
155
        }
156
        }
157
    }
158
    $transportTypes = [
159
        "ws" => [
160
            "type" => $decoded_vless["params"]["type"],
161
            "path" => "/" . $decoded_vless["params"]["path"],
162
            "headers" => [
163
                "Host" => !is_null($decoded_vless["params"]["host"])
164
                    ? $decoded_vless["params"]["host"]
165
                    : "",
166
            ],
167
            "max_early_data" => 0,
168
            "early_data_header_name" => "Sec-WebSocket-Protocol",
169
        ],
170
        "grpc" => [
171
            "type" => $decoded_vless["params"]["type"],
172
            "service_name" => $decoded_vless["params"]["serviceName"],
173
            "idle_timeout" => "15s",
174
            "ping_timeout" => "15s",
175
            "permit_without_stream" => false,
176
        ],
177
    ];
178
    if (isset($decoded_vless["params"]["type"])) {
179
        if (
180
            $decoded_vless["params"]["type"] === "ws" ||
181
            $decoded_vless["params"]["type"] === "grpc"
182
        ) {
183
            $configResult["transport"] =
184
                $transportTypes[$decoded_vless["params"]["type"]];
185
        }
186
    }
187
    return $configResult;
188
}
189
190
function TrojanSingbox($TrojanUrl){
191
    $decoded_trojan = parseProxyUrl($TrojanUrl);
192
    if (is_null($decoded_trojan['hash']) || $decoded_trojan['hash'] === ""){
193
        return null;
194
    }
195
    $configResult = array(
196
        "tag"=> $decoded_trojan['hash'],
197
        "type"=> "trojan",
198
        "server"=> $decoded_trojan['hostname'],
199
        "server_port"=> intval($decoded_trojan['port']),
200
        "password"=> $decoded_trojan['username'],
201
        "multiplex"=> array(
202
          "enabled"=> false,
203
          "protocol"=> "smux",
204
          "max_streams"=> 32
205
        )
206
    );
207
208
    if ($decoded_trojan['port'] === "443" || $decoded_trojan['params']["security"] === "tls"){
209
        $configResult['tls'] = array(
210
            "enabled"=> true,
211
            "server_name"=> !is_null($decoded_trojan['params']['sni']) ? $decoded_trojan['params']['sni'] : "",
212
            "insecure"=> true,
213
            "utls"=> array(
214
                "enabled"=> true,
215
                "fingerprint"=> "chrome"
216
            )
217
        );
218
    }
219
220
    $transportTypes = array(
221
        "ws" => array(
222
            "type"=> $decoded_trojan['params']["type"],
223
            "path"=> "/" . $decoded_trojan['params']["path"],
224
            "headers"=> array(
225
                "Host"=> $decoded_trojan['params']["host"]
226
            )
227
          ),
228
          "grpc" => array(
229
            "type" => $decoded_trojan['params']["type"],
230
            "service_name" => $decoded_trojan['params']["serviceName"],
231
            "idle_timeout" => "15s",
232
            "ping_timeout" => "15s",
233
            "permit_without_stream" => false
234
          )
235
    );
236
    if (isset($decoded_trojan['params']["type"])){
237
        if ($decoded_trojan['params']["type"] === "ws" || $decoded_trojan['params']["type"] === "grpc"){
238
            $configResult["transport"] = $transportTypes[$decoded_trojan['params']["type"]];
239
        }
240
    }
241
    return $configResult;
242
}
243
244
function ShadowsocksSingbox($ShadowsocksUrl) {
245
    $decoded_shadowsocks = ParseShadowsocks($ShadowsocksUrl);
246
    if (is_null($decoded_shadowsocks['name']) || $decoded_shadowsocks['name'] === ""){
247
        return null;
248
    }
249
    $configResult = [
250
        'tag' => $decoded_shadowsocks['name'],
251
        'type' => "shadowsocks",
252
        'server' => $decoded_shadowsocks['server_address'],
253
        'server_port' => intval($decoded_shadowsocks['server_port']),
254
        'method' => $decoded_shadowsocks['encryption_method'],
255
        'password' => $decoded_shadowsocks['password'],
256
        'plugin' => "",
257
        'plugin_opts' => ""
258
    ];
259
    return $configResult;
260
}
261
262
function GenerateConfig($input, $output){
263
    $outbound = [];
264
    $v2ray_subscription = str_replace(" ", "%20", $input);
265
266
    $configArray = explode("\n", $v2ray_subscription);
267
    foreach ($configArray as $config) {
268
        $configType = detect_type($config);
269
        $config = str_replace("%20", " ", $config);
270
        switch($configType) {
271
            case "vmess":
272
                $configSingbox = VmessSingbox($config);
273
                break;
274
            case "vless":
275
                $configSingbox = VlessSingbox($config);
276
                break;
277
            case "trojan":
278
                $configSingbox = TrojanSingbox($config);
279
                break;
280
            case "ss":
281
                $configSingbox = ShadowsocksSingbox($config);
282
                break;
283
        }
284
        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...
285
            $configName = $configSingbox['tag'];
286
            if (stripos($configName, "RELAY🚩")){
287
                $configLocation = "RELAY🚩";
288
            } else {
289
                $pattern = '/\b[A-Z]{2}\b[\x{1F1E6}-\x{1F1FF}]{2}/u';
290
                preg_match_all($pattern, $configName, $matches);
291
                $configLocation = $matches[0][0];
292
            }
293
            if (!in_array($configSingbox, $outbound[$configLocation])) {
294
                $outbound[$configLocation][] = $configSingbox;
295
            }
296
        }
297
    }
298
    $templateMap = [
299
        "nold" => "nekobox_1.1.7.json", 
300
        "nnew" => "nekobox_1.1.8.json", 
301
        "sfia" => "sfi.json"
302
    ];
303
    $templateBase = json_decode(
304
        file_get_contents("modules/singbox/" . $templateMap[$output]), 
305
        true
306
    );
307
    $templateManual = json_decode(
308
        file_get_contents("modules/singbox/manual.json"), 
309
        true
310
    );
311
    $templateUrltest = json_decode(
312
        file_get_contents("modules/singbox/url_test.json"), 
313
        true
314
    );
315
    
316
    $outboundUrltest =[];
0 ignored issues
show
Unused Code introduced by
The assignment to $outboundUrltest is dead and can be removed.
Loading history...
317
    $outboundSingles = [];
318
    $locationNames = [];
319
    $outboundBasedOnLocationFull = [];
320
    foreach ($outbound as $location => $outboundEachLocation){
321
        $locationNames[] = $location;
322
        $eachLocationNames = extract_names($outboundEachLocation);
323
        $templateUrltest[0]['tag'] = $location;
324
        $outboundBasedOnLocation = process_jsons($templateUrltest, $eachLocationNames);
325
        $outboundBasedOnLocationFull = array_merge($outboundBasedOnLocationFull, $outboundBasedOnLocation);
326
        $outboundSingles = array_merge($outboundSingles, $outboundEachLocation);
327
    }
328
329
    $templateManual = process_jsons($templateManual, $locationNames);
330
    $templateUrltest[0]['tag'] = "URL-TEST | رایگان";
331
    $configNamesFull = extract_names($outboundSingles);
332
    $outboundUrltest = process_jsons($templateUrltest, $configNamesFull);
333
    $outboundUrltest = array_merge($outboundUrltest, $outboundBasedOnLocationFull);
334
335
    $templateBase['outbounds'] = array_merge($templateManual, $outboundUrltest, $outboundSingles,  $templateBase['outbounds']);
336
    return json_encode($templateBase, JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT);
337
}
338
339
function GenerateConfigLite($input, $output){
340
    $outbound = [];
341
    $v2ray_subscription = $input;
342
343
    $configArray = explode("\n", $v2ray_subscription);
344
    foreach ($configArray as $config) {
345
        $configType = detect_type($config);
346
        switch($configType) {
347
            case "vmess":
348
                $configSingbox = VmessSingbox($config);
349
                break;
350
            case "vless":
351
                $configSingbox = VlessSingbox($config);
352
                break;
353
            case "trojan":
354
                $configSingbox = TrojanSingbox($config);
355
                break;
356
            case "ss":
357
                $configSingbox = ShadowsocksSingbox($config);
358
                break;
359
        }
360
        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...
361
            if (!in_array($configSingbox, $outbound)) {
362
                $outbound[] = $configSingbox;
363
            }
364
        }
365
    }
366
    $templateMap = [
367
        "nold" => "nekobox_1.1.7.json", 
368
        "nnew" => "nekobox_1.1.8.json", 
369
        "sfia" => "sfi.json"
370
    ];
371
    $templateBase = json_decode(
372
        file_get_contents("modules/singbox/" . $templateMap[$output]), 
373
        true
374
    );
375
    $templateManual = json_decode(
376
        file_get_contents("modules/singbox/manual.json"), 
377
        true
378
    );
379
    $templateUrltest = json_decode(
380
        file_get_contents("modules/singbox/url_test.json"), 
381
        true
382
    );
383
384
    $names = extract_names($outbound);
385
    $outboundManual = process_jsons($templateManual, $names);
386
    $outboundUrltest = process_jsons($templateUrltest, $names);
387
388
    $templateBase['outbounds'] = array_merge($outboundManual, $outboundUrltest, $outbound,  $templateBase['outbounds']);
389
    $finalJson = json_encode($templateBase, JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT);
390
    $headerText = "//profile-title: base64:VFZDIHwgWUVCRUtIRQ==
391
//profile-update-interval: 1
392
//subscription-userinfo: upload=0; download=0; total=10737418240000; expire=" . create_tehran_timestamp_tomorrow() . "
393
//support-url: https://t.me/v2raycollector
394
//profile-web-page-url: https://github.com/yebekhe/TelegramV2rayCollector
395
396
";
397
    $createJsonc = $headerText . $finalJson ;
398
    return $createJsonc;
399
}
400