Compare commits
13 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| d370b78815 | |||
| 913f75b4a8 | |||
| c3e850b102 | |||
| 3a89a1543b | |||
| 2a3e8e393c | |||
| 332b74e366 | |||
| dfa9efec7a | |||
| e1902827ce | |||
| 95fea3bb7b | |||
| 80a9f9f32d | |||
| 7fc1105728 | |||
| d46679caf6 | |||
| 910186ff00 |
+354
-160
@@ -7,6 +7,8 @@ class Bot
|
||||
public $update;
|
||||
public $ip;
|
||||
public $limit;
|
||||
public $key;
|
||||
public $file;
|
||||
|
||||
public function __construct($key, $i18n)
|
||||
{
|
||||
@@ -123,7 +125,6 @@ class Bot
|
||||
case preg_match('~^/menu (?P<type>wg) (?P<arg>(?:-)?\d+)$~', $this->input['callback'], $m):
|
||||
case preg_match('~^/menu (?P<type>client) (?P<arg>\d+(?:_(?:-)?\d+)?)$~', $this->input['callback'], $m):
|
||||
case preg_match('~^/menu (?P<type>pac|adguard|config|ss|lang|oc|naive|mirror|update)$~', $this->input['callback'], $m):
|
||||
case preg_match('~^/menu (?P<type>subzoneslist|reverselist|includelist|excludelist) (?P<arg>(?:-)?\d+)$~', $this->input['callback'], $m):
|
||||
$this->menu(type: $m['type'] ?? false, arg: $m['arg'] ?? false);
|
||||
break;
|
||||
case preg_match('~^/changeWG (\d+)$~', $this->input['callback'], $m):
|
||||
@@ -285,11 +286,11 @@ class Bot
|
||||
case preg_match('~^/userXr (\d+)$~', $this->input['callback'], $m):
|
||||
$this->userXr($m[1]);
|
||||
break;
|
||||
case preg_match('~^/choiceTemplate (\d+(?:_.+)?)$~', $this->input['callback'], $m):
|
||||
case preg_match('~^/choiceTemplate (.+)$~', $this->input['callback'], $m):
|
||||
$this->choiceTemplate($m[1]);
|
||||
break;
|
||||
case preg_match('~^/templateUser (\d+)$~', $this->input['callback'], $m):
|
||||
$this->templateUser($m[1]);
|
||||
case preg_match('~^/templateUser (\w+) (\d+)$~', $this->input['callback'], $m):
|
||||
$this->templateUser($m[1], $m[2]);
|
||||
break;
|
||||
case preg_match('~^/timerXr (\d+)$~', $this->input['callback'], $m):
|
||||
$this->timerXr($m[1]);
|
||||
@@ -349,7 +350,7 @@ class Bot
|
||||
case preg_match('~^/deldomain$~', $this->input['callback'], $m):
|
||||
$this->delDomain();
|
||||
break;
|
||||
case preg_match('~^/(?P<action>change|delete)(?P<typelist>includelist) (?P<arg>[^\s]+(?:_(?:-)?\d+)?)$~', $this->input['callback'], $m):
|
||||
case preg_match('~^/(?P<action>change|delete)(?P<typelist>\w+) (?P<arg>[^\s]+(?:_(?:-)?\d+)?)$~', $this->input['callback'], $m):
|
||||
$this->listPacChange($m['typelist'], $m['action'], ...explode('_', $m['arg']));
|
||||
break;
|
||||
case preg_match('~^/paczapret$~', $this->input['callback'], $m):
|
||||
@@ -370,20 +371,26 @@ class Bot
|
||||
case preg_match('~^/xray(?: (\d+))?$~', $this->input['callback'], $m):
|
||||
$this->xray($m[1] ?: 0);
|
||||
break;
|
||||
case preg_match('~^/delTemplate(?: (.+))?$~', $this->input['callback'], $m):
|
||||
$this->delTemplate($m[1] ?: 0);
|
||||
case preg_match('~^/xtlsblock(?: (\d+))?$~', $this->input['callback'], $m):
|
||||
$this->xtlsblock($m[1] ?: 0);
|
||||
break;
|
||||
case preg_match('~^/downloadTemplate(?: (.+))?$~', $this->input['callback'], $m):
|
||||
$this->downloadTemplate($m[1] ?: 0);
|
||||
case preg_match('~^/xtlswarp(?: (\d+))?$~', $this->input['callback'], $m):
|
||||
$this->xtlswarp($m[1] ?: 0);
|
||||
break;
|
||||
case preg_match('~^/defaultTemplate(?: (.+))?$~', $this->input['callback'], $m):
|
||||
$this->defaultTemplate($m[1] ?: 0);
|
||||
case preg_match('~^/delTemplate (\w+)(?: (.+))?$~', $this->input['callback'], $m):
|
||||
$this->delTemplate($m[1], $m[2]);
|
||||
break;
|
||||
case preg_match('~^/singbox(?: (\w+))?$~', $this->input['callback'], $m):
|
||||
$this->singbox($m[1] ?: false);
|
||||
case preg_match('~^/downloadTemplate (\w+)(?: (.+))?$~', $this->input['callback'], $m):
|
||||
$this->downloadTemplate($m[1], $m[2]);
|
||||
break;
|
||||
case preg_match('~^/singAdd$~', $this->input['callback'], $m):
|
||||
$this->singAdd();
|
||||
case preg_match('~^/defaultTemplate (\w+)(?: (.+))?$~', $this->input['callback'], $m):
|
||||
$this->defaultTemplate($m[1], $m[2]);
|
||||
break;
|
||||
case preg_match('~^/templates (\w+)$~', $this->input['callback'], $m):
|
||||
$this->templates($m[1]);
|
||||
break;
|
||||
case preg_match('~^/templateAdd (\w+)$~', $this->input['callback'], $m):
|
||||
$this->templateAdd($m[1]);
|
||||
break;
|
||||
case preg_match('~^/generateSecretXray$~', $this->input['callback'], $m):
|
||||
$this->generateSecretXray();
|
||||
@@ -397,7 +404,7 @@ class Bot
|
||||
case preg_match('~^/changeTGDomain$~', $this->input['callback'], $m):
|
||||
$this->changeTGDomain();
|
||||
break;
|
||||
case preg_match('~^/include (\d+)$~', $this->input['callback'], $m):
|
||||
case preg_match('~^/include (\w+)$~', $this->input['callback'], $m):
|
||||
$this->include($m[1]);
|
||||
break;
|
||||
case preg_match('~^/exclude (\d+)$~', $this->input['callback'], $m):
|
||||
@@ -1051,7 +1058,10 @@ class Bot
|
||||
foreach ($items as $k => $v) {
|
||||
if (($t = gmdate($k, $seconds) - $v['diff']) > 0) {
|
||||
$text .= " $t{$v['sign']}";
|
||||
break;
|
||||
if (!empty($i)) {
|
||||
break;
|
||||
}
|
||||
$i++;
|
||||
}
|
||||
}
|
||||
return trim($text) ?: '♾';
|
||||
@@ -2113,7 +2123,7 @@ DNS-over-HTTPS with IP:
|
||||
$this->setSSL('self');
|
||||
}
|
||||
|
||||
public function include(int $count)
|
||||
public function include($type)
|
||||
{
|
||||
$r = $this->send(
|
||||
$this->input['chat'],
|
||||
@@ -2124,25 +2134,86 @@ DNS-over-HTTPS with IP:
|
||||
$_SESSION['reply'][$r['result']['message_id']] = [
|
||||
'start_message' => $this->input['message_id'],
|
||||
'callback' => 'addInclude',
|
||||
'args' => [$count],
|
||||
'args' => [$type],
|
||||
];
|
||||
}
|
||||
|
||||
public function addInclude(string $domains, int $count)
|
||||
public function addInclude(string $domains, $type)
|
||||
{
|
||||
$domains = explode(',', $domains);
|
||||
$domains = array_filter($domains, fn($x) => !empty(trim($x)));
|
||||
if (!empty($domains)) {
|
||||
$conf = $this->getPacConf();
|
||||
foreach ($domains as $k => $v) {
|
||||
$conf['includelist'][idn_to_ascii(trim($v))] = true;
|
||||
$conf[$type][idn_to_ascii(trim($v))] = true;
|
||||
}
|
||||
ksort($conf['includelist']);
|
||||
ksort($conf[$type]);
|
||||
$this->setPacConf($conf);
|
||||
$page = (int) floor(array_search($v, array_keys($conf['includelist'])) / $count);
|
||||
$page = (int) floor(array_search($v, array_keys($conf[$type])) / $this->limit);
|
||||
}
|
||||
$page = $page ?: -2;
|
||||
$this->pacUpdate();
|
||||
$this->backXtlsList($type);
|
||||
}
|
||||
|
||||
public function backXtlsList($type)
|
||||
{
|
||||
switch ($type) {
|
||||
case 'includelist':
|
||||
$this->pacUpdate();
|
||||
break;
|
||||
case 'blocklist':
|
||||
$this->xrayUpdateRules();
|
||||
$this->xtlsblock();
|
||||
break;
|
||||
case 'warplist':
|
||||
$this->xrayUpdateRules();
|
||||
$this->xtlswarp();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
public function xrayUpdateRules()
|
||||
{
|
||||
$c = $this->getPacConf();
|
||||
$xr = $this->getXray();
|
||||
$xr['outbounds'] = [
|
||||
[
|
||||
"protocol" => "freedom",
|
||||
"tag" => "direct",
|
||||
],
|
||||
[
|
||||
"protocol" => "blackhole",
|
||||
"tag" => "block",
|
||||
],
|
||||
[
|
||||
"protocol" => "socks",
|
||||
"tag" => "warp",
|
||||
"settings" => [
|
||||
'servers' => [
|
||||
[
|
||||
"address" => "10.10.0.13",
|
||||
"port" => 4000,
|
||||
],
|
||||
],
|
||||
],
|
||||
],
|
||||
];
|
||||
if (!empty($c['blocklist']) && !empty(array_filter($c['blocklist']))) {
|
||||
$rules[] = [
|
||||
"type" => "field",
|
||||
"outboundTag" => "block",
|
||||
"domain" => array_keys(array_filter($c['blocklist'])),
|
||||
];
|
||||
}
|
||||
if (!empty($c['warplist']) && !empty(array_filter($c['warplist']))) {
|
||||
$rules[] = [
|
||||
"type" => "field",
|
||||
"outboundTag" => "warp",
|
||||
"domain" => array_keys(array_filter($c['warplist'])),
|
||||
];
|
||||
}
|
||||
$xr['routing']['rules'] = $rules ?: [];
|
||||
$this->restartXray($xr);
|
||||
}
|
||||
|
||||
public function reverse(int $count)
|
||||
@@ -2962,44 +3033,7 @@ DNS-over-HTTPS with IP:
|
||||
'callback_data' => "/addCommunityFilter",
|
||||
],
|
||||
];
|
||||
$data[] = [
|
||||
[
|
||||
'text' => $this->i18n('add'),
|
||||
'callback_data' => "/include {$this->limit}",
|
||||
],
|
||||
];
|
||||
$domains = $this->getPacConf()['includelist'];
|
||||
if (!empty($domains)) {
|
||||
ksort($domains);
|
||||
$all = (int) ceil(count($domains) / $this->limit);
|
||||
$page = min($page, $all - 1);
|
||||
$page = $page < 0 ? $all - 1 : $page;
|
||||
$domains = array_slice($domains, $page * $this->limit, $this->limit, true);
|
||||
foreach ($domains as $k => $v) {
|
||||
$data[] = [
|
||||
[
|
||||
'text' => '(' . ($v ? 'ON' : 'OFF') . ') ' . idn_to_utf8($k),
|
||||
'callback_data' => "/changeincludelist {$k}_{$this->limit}",
|
||||
],
|
||||
[
|
||||
'text' => 'delete',
|
||||
'callback_data' => "/deleteincludelist {$k}_{$this->limit}",
|
||||
],
|
||||
];
|
||||
}
|
||||
if ($all > 1) {
|
||||
$data[] = [
|
||||
[
|
||||
'text' => '<<',
|
||||
'callback_data' => "/pacMenu " . ($page - 1 >= 0 ? $page - 1 : $all - 1),
|
||||
],
|
||||
[
|
||||
'text' => '>>',
|
||||
'callback_data' => "/pacMenu " . ($page < $all - 1 ? $page + 1 : 0),
|
||||
]
|
||||
];
|
||||
}
|
||||
}
|
||||
$data = array_merge($data, $this->listPac('includelist', $page, 'pacMenu'));
|
||||
$data[] = [
|
||||
[
|
||||
'text' => $this->i18n('back'),
|
||||
@@ -3014,22 +3048,101 @@ DNS-over-HTTPS with IP:
|
||||
);
|
||||
}
|
||||
|
||||
public function listPacChange($type, $action, $key, int $count)
|
||||
public function xtlsblock($page = 0)
|
||||
{
|
||||
$text[] = "Menu -> " . $this->i18n('xray') . ' -> block list';
|
||||
|
||||
$data = $this->listPac('blocklist', $page, 'xtlsblock');
|
||||
$data[] = [
|
||||
[
|
||||
'text' => $this->i18n('back'),
|
||||
'callback_data' => "/xray",
|
||||
],
|
||||
];
|
||||
$this->update(
|
||||
$this->input['chat'],
|
||||
$this->input['message_id'],
|
||||
implode("\n", $text ?: ['...']),
|
||||
$data ?: false,
|
||||
);
|
||||
}
|
||||
|
||||
public function xtlswarp($page = 0)
|
||||
{
|
||||
$text[] = "Menu -> " . $this->i18n('xray') . ' -> warp list';
|
||||
|
||||
$data = $this->listPac('warplist', $page, 'xtlswarp');
|
||||
$data[] = [
|
||||
[
|
||||
'text' => $this->i18n('back'),
|
||||
'callback_data' => "/xray",
|
||||
],
|
||||
];
|
||||
$this->update(
|
||||
$this->input['chat'],
|
||||
$this->input['message_id'],
|
||||
implode("\n", $text ?: ['...']),
|
||||
$data ?: false,
|
||||
);
|
||||
}
|
||||
|
||||
public function listPac($type, $page, $menu)
|
||||
{
|
||||
$data[] = [
|
||||
[
|
||||
'text' => $this->i18n('add'),
|
||||
'callback_data' => "/include $type",
|
||||
],
|
||||
];
|
||||
$domains = $this->getPacConf()[$type];
|
||||
if (!empty($domains)) {
|
||||
ksort($domains);
|
||||
$all = (int) ceil(count($domains) / $this->limit);
|
||||
$page = min($page, $all - 1);
|
||||
$page = $page < 0 ? $all - 1 : $page;
|
||||
$domains = array_slice($domains, $page * $this->limit, $this->limit, true);
|
||||
foreach ($domains as $k => $v) {
|
||||
$data[] = [
|
||||
[
|
||||
'text' => $this->i18n($v ? 'on' : 'off') . ' ' . idn_to_utf8($k),
|
||||
'callback_data' => "/change$type {$k}_{$this->limit}",
|
||||
],
|
||||
[
|
||||
'text' => 'delete',
|
||||
'callback_data' => "/delete$type {$k}_{$this->limit}",
|
||||
],
|
||||
];
|
||||
}
|
||||
if ($all > 1) {
|
||||
$data[] = [
|
||||
[
|
||||
'text' => '<<',
|
||||
'callback_data' => "/$menu " . ($page - 1 >= 0 ? $page - 1 : $all - 1),
|
||||
],
|
||||
[
|
||||
'text' => '>>',
|
||||
'callback_data' => "/$menu " . ($page < $all - 1 ? $page + 1 : 0),
|
||||
]
|
||||
];
|
||||
}
|
||||
}
|
||||
return $data;
|
||||
}
|
||||
|
||||
public function listPacChange($type, $action, $key)
|
||||
{
|
||||
$conf = $this->getPacConf();
|
||||
ksort($conf[$type]);
|
||||
$page = (int) floor(array_search($key, array_keys($conf[$type])) / $count);
|
||||
switch ($action) {
|
||||
case 'change':
|
||||
$conf[$type][$key] = !$conf[$type][$key];
|
||||
$page = (int) floor(array_search($key, array_keys($conf[$type])) / $count);
|
||||
break;
|
||||
case 'delete':
|
||||
unset($conf[$type][$key]);
|
||||
break;
|
||||
}
|
||||
$this->setPacConf($conf);
|
||||
$this->pacUpdate();
|
||||
$this->backXtlsList($type);
|
||||
}
|
||||
|
||||
public function pacZapret()
|
||||
@@ -3500,7 +3613,7 @@ DNS-over-HTTPS with IP:
|
||||
$this->xray();
|
||||
}
|
||||
|
||||
public function singAdd()
|
||||
public function templateAdd($type)
|
||||
{
|
||||
$r = $this->send(
|
||||
$this->input['chat'],
|
||||
@@ -3511,12 +3624,12 @@ DNS-over-HTTPS with IP:
|
||||
$_SESSION['reply'][$r['result']['message_id']] = [
|
||||
'start_message' => $this->input['message_id'],
|
||||
'start_callback' => $this->input['callback_id'],
|
||||
'callback' => 'singAddTemplate',
|
||||
'args' => [],
|
||||
'callback' => 'addTemplate',
|
||||
'args' => [$type],
|
||||
];
|
||||
}
|
||||
|
||||
public function singAddTemplate($n = null)
|
||||
public function addTemplate($n, $type)
|
||||
{
|
||||
if (empty($this->input['caption'])) {
|
||||
$this->send($this->input['chat'], 'empty name');
|
||||
@@ -3529,79 +3642,79 @@ DNS-over-HTTPS with IP:
|
||||
return;
|
||||
}
|
||||
$pac = $this->getPacConf();
|
||||
$pac['singtemplates'][$this->input['caption']] = $json;
|
||||
$pac["{$type}templates"][$this->input['caption']] = $json;
|
||||
$this->setPacConf($pac);
|
||||
$this->singbox();
|
||||
$this->templates($type);
|
||||
}
|
||||
|
||||
public function delTemplate($name)
|
||||
public function delTemplate($type, $name)
|
||||
{
|
||||
$pac = $this->getPacConf();
|
||||
unset($pac['singtemplates'][base64_decode($name)]);
|
||||
unset($pac["{$type}templates"][base64_decode($name)]);
|
||||
$this->setPacConf($pac);
|
||||
$this->singbox();
|
||||
$this->templates($type);
|
||||
}
|
||||
|
||||
public function downloadTemplate($name)
|
||||
public function downloadTemplate($type, $name)
|
||||
{
|
||||
$pac = $this->getPacConf();
|
||||
$f = new \CURLStringFile(json_encode($pac['singtemplates'][base64_decode($name)], JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES), base64_decode($name) . '.json', 'application/json');
|
||||
$f = new \CURLStringFile(json_encode($pac["{$type}templates"][base64_decode($name)], JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES), base64_decode($name) . '.json', 'application/json');
|
||||
$this->sendFile($this->input['chat'], $f);
|
||||
}
|
||||
|
||||
public function defaultTemplate($name)
|
||||
public function defaultTemplate($type, $name)
|
||||
{
|
||||
$pac = $this->getPacConf();
|
||||
if (!empty($name)) {
|
||||
$pac['defaulttemplate'] = $name;
|
||||
$pac["default{$type}template"] = $name;
|
||||
} else {
|
||||
unset($pac['defaulttemplate']);
|
||||
unset($pac["default{$type}template"]);
|
||||
}
|
||||
$this->setPacConf($pac);
|
||||
$this->singbox();
|
||||
$this->templates($type);
|
||||
}
|
||||
|
||||
public function singbox($name = false)
|
||||
public function templates($type)
|
||||
{
|
||||
$pac = $this->getPacConf();
|
||||
$domain = $pac['domain'] ?: $this->ip;
|
||||
$hash = substr(md5($this->key), 0, 8);
|
||||
$text[] = "Menu -> " . $this->i18n('xray') . ' -> Sing-box templates';
|
||||
$templates = $pac['singtemplates'];
|
||||
$text[] = "Menu -> " . $this->i18n('xray') . " -> $type templates";
|
||||
$templates = $pac["{$type}templates"];
|
||||
|
||||
$data[] = [
|
||||
[
|
||||
'text' => $this->i18n('add'),
|
||||
'callback_data' => "/singAdd",
|
||||
'callback_data' => "/templateAdd $type",
|
||||
],
|
||||
];
|
||||
$data[] = [
|
||||
[
|
||||
'text' => "origin",
|
||||
'web_app' => ['url' => "https://$domain/pac?h=$hash&t=te"],
|
||||
'web_app' => ['url' => "https://$domain/pac?h=$hash&t=te&ty=$type"],
|
||||
],
|
||||
[
|
||||
'text' => $this->i18n($pac['defaulttemplate'] ? 'off' : 'on'),
|
||||
'callback_data' => "/defaultTemplate",
|
||||
'text' => $this->i18n($pac["default{$type}template"] ? 'off' : 'on'),
|
||||
'callback_data' => "/defaultTemplate $type",
|
||||
],
|
||||
];
|
||||
foreach ($templates as $k => $v) {
|
||||
$data[] = [
|
||||
[
|
||||
'text' => "$k",
|
||||
'web_app' => ['url' => "https://$domain/pac?h=$hash&t=te&te=" . urlencode($k)],
|
||||
'web_app' => ['url' => "https://$domain/pac?h=$hash&t=te&ty=$type&te=" . urlencode($k)],
|
||||
],
|
||||
[
|
||||
'text' => $this->i18n('download'),
|
||||
'callback_data' => "/downloadTemplate " . base64_encode($k),
|
||||
'callback_data' => "/downloadTemplate $type " . base64_encode($k),
|
||||
],
|
||||
[
|
||||
'text' => $this->i18n('delete'),
|
||||
'callback_data' => "/delTemplate " . base64_encode($k),
|
||||
'callback_data' => "/delTemplate $type " . base64_encode($k),
|
||||
],
|
||||
[
|
||||
'text' => $this->i18n($pac['defaulttemplate'] == base64_encode($k) ? 'on' : 'off'),
|
||||
'callback_data' => "/defaultTemplate " . base64_encode($k),
|
||||
'text' => $this->i18n($pac["default{$type}template"] == base64_encode($k) ? 'on' : 'off'),
|
||||
'callback_data' => "/defaultTemplate $type " . base64_encode($k),
|
||||
],
|
||||
];
|
||||
}
|
||||
@@ -3639,9 +3752,23 @@ DNS-over-HTTPS with IP:
|
||||
],
|
||||
];
|
||||
$data[] = [
|
||||
[
|
||||
'text' => $this->i18n('v2ray templates'),
|
||||
'callback_data' => "/templates v2ray",
|
||||
],
|
||||
[
|
||||
'text' => $this->i18n('sing-box templates'),
|
||||
'callback_data' => "/singbox",
|
||||
'callback_data' => "/templates sing",
|
||||
],
|
||||
];
|
||||
$data[] = [
|
||||
[
|
||||
'text' => $this->i18n('block'),
|
||||
'callback_data' => "/xtlsblock",
|
||||
],
|
||||
[
|
||||
'text' => $this->i18n('warp'),
|
||||
'callback_data' => "/xtlswarp",
|
||||
],
|
||||
];
|
||||
$data[] = [
|
||||
@@ -3714,39 +3841,39 @@ DNS-over-HTTPS with IP:
|
||||
public function choiceTemplate($arg)
|
||||
{
|
||||
$arg = explode('_', $arg);
|
||||
$c = $this->getXray();
|
||||
if (!empty($arg[1])) {
|
||||
$c['inbounds'][0]['settings']['clients'][$arg[0]]['template'] = $arg[1];
|
||||
$c = $this->getXray();
|
||||
if (!empty($arg[2])) {
|
||||
$c['inbounds'][0]['settings']['clients'][$arg[1]]["{$arg[0]}template"] = $arg[2];
|
||||
} else {
|
||||
unset($c['inbounds'][0]['settings']['clients'][$arg[0]]['template']);
|
||||
unset($c['inbounds'][0]['settings']['clients'][$arg[1]]["{$arg[0]}template"]);
|
||||
}
|
||||
file_put_contents('/config/xray.json', json_encode($c, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES));
|
||||
$this->userXr($arg[0]);
|
||||
$this->userXr($arg[1]);
|
||||
}
|
||||
|
||||
public function templateUser($i)
|
||||
public function templateUser($type, $i)
|
||||
{
|
||||
$c = $this->getXray();
|
||||
$pac = $this->getPacConf();
|
||||
$text[] = "Menu -> " . $this->i18n('xray') . " -> {$c['inbounds'][0]['settings']['clients'][$i]['email']}\n";
|
||||
$templates = $pac['singtemplates'];
|
||||
$data[] = [
|
||||
$text[] = "Menu -> " . $this->i18n('xray') . " -> {$c['inbounds'][0]['settings']['clients'][$i]['email']}\n";
|
||||
$templates = $pac["{$type}templates"];
|
||||
$data[] = [
|
||||
[
|
||||
'text' => 'default',
|
||||
'callback_data' => "/choiceTemplate $i",
|
||||
'callback_data' => "/choiceTemplate {$type}_$i",
|
||||
],
|
||||
];
|
||||
$data[] = [
|
||||
[
|
||||
'text' => 'origin',
|
||||
'callback_data' => "/choiceTemplate {$i}_" . base64_encode('origin'),
|
||||
'callback_data' => "/choiceTemplate {$type}_{$i}_" . base64_encode('origin'),
|
||||
],
|
||||
];
|
||||
foreach ($templates as $k => $v) {
|
||||
$data[] = [
|
||||
[
|
||||
'text' => $k,
|
||||
'callback_data' => "/choiceTemplate {$i}_" . base64_encode($k),
|
||||
'callback_data' => "/choiceTemplate {$type}_{$i}_" . base64_encode($k),
|
||||
],
|
||||
];
|
||||
}
|
||||
@@ -3764,44 +3891,57 @@ DNS-over-HTTPS with IP:
|
||||
);
|
||||
}
|
||||
|
||||
public function userXr($i, $fs = 0, $fv = 0)
|
||||
public function userXr($i)
|
||||
{
|
||||
$c = $this->getXray();
|
||||
$pac = $this->getPacConf() ?: $this->ip;
|
||||
$domain = $pac['domain'] ?: $this->ip;
|
||||
$scheme = empty($this->nginxGetTypeCert()) ? 'http' : 'https';
|
||||
$hash = substr(md5($this->key), 0, 8);
|
||||
$v2ray = "$scheme://{$domain}/pac?h=$hash&t=s&b=1&s={$c['inbounds'][0]['settings']['clients'][$i]['id']}";
|
||||
$sing = "$scheme://{$domain}/pac?h=$hash&t=si&b=1&s={$c['inbounds'][0]['settings']['clients'][$i]['id']}";
|
||||
$fullsing = 'sing-box://import-remote-profile/?url=' . urlencode("$scheme://{$domain}/pac?h=$hash&t=si&s={$c['inbounds'][0]['settings']['clients'][$i]['id']}") . "#vpnbot$i";
|
||||
$fullv2ray = 'v2rayng://install-config?url=' . urlencode("$scheme://{$domain}/pac?h=$hash&t=s&s={$c['inbounds'][0]['settings']['clients'][$i]['id']}") . "#vpnbot$i";
|
||||
if (!empty($fs)) {
|
||||
return $fullsing;
|
||||
}
|
||||
if (!empty($fv)) {
|
||||
return $fullv2ray;
|
||||
}
|
||||
$c = $this->getXray()['inbounds'][0]['settings']['clients'][$i];
|
||||
$pac = $this->getPacConf();
|
||||
$domain = $pac['domain'] ?: $this->ip;
|
||||
$scheme = empty($this->nginxGetTypeCert()) ? 'http' : 'https';
|
||||
$hash = substr(md5($this->key), 0, 8);
|
||||
|
||||
$text[] = "Menu -> " . $this->i18n('xray') . " -> {$c['inbounds'][0]['settings']['clients'][$i]['email']}\n";
|
||||
$text[] = "Menu -> " . $this->i18n('xray') . " -> {$c['email']}\n";
|
||||
$text[] = "<code>{$this->linkXray($i)}</code>\n";
|
||||
$text[] = "v2ray: <a href='$v2ray'>$v2ray</a>\n";
|
||||
$text[] = "sing-box: <a href='$sing'>$sing</a>";
|
||||
|
||||
$text[] = "import subscribe:";
|
||||
$text[] = "<a href='$scheme://{$domain}/pac?h=$hash&t=s&r=v&s={$c['id']}'>v2rayng</a>";
|
||||
$text[] = "<a href='$scheme://{$domain}/pac?h=$hash&t=si&r=si&s={$c['id']}'>sing-box</a>";
|
||||
$text[] = "<a href='$scheme://{$domain}/pac?h=$hash&t=s&r=st&s={$c['id']}'>streisand</a>";
|
||||
$text[] = "<a href='$scheme://{$domain}/pac?h=$hash&t=si&r=h&s={$c['id']}'>hiddify</a>";
|
||||
|
||||
$text[] = "\nv2ray config: <code>$scheme://{$domain}/pac?h=$hash&t=s&s={$c['id']}</code>";
|
||||
$text[] = "sing-box config: <code>$scheme://{$domain}/pac?h=$hash&t=si&s={$c['id']}</code>";
|
||||
$text[] = "sing-box windows: <a href='$scheme://{$domain}/pac?h=$hash&t=si&r=w&s={$c['id']}'>windows service</a>";
|
||||
|
||||
$data[] = [
|
||||
[
|
||||
'text' => $c['inbounds'][0]['settings']['clients'][$i]['time'] ? "timer: " . $this->getTime($c['inbounds'][0]['settings']['clients'][$i]['time']) : $this->i18n('timer'),
|
||||
'text' => 'v2ray',
|
||||
'web_app' => ['url' => "https://{$domain}/pac?h=$hash&t=s&s={$c['id']}"],
|
||||
],
|
||||
[
|
||||
'text' => 'sing-box',
|
||||
'web_app' => ['url' => "https://{$domain}/pac?h=$hash&t=si&s={$c['id']}"],
|
||||
],
|
||||
];
|
||||
$data[] = [
|
||||
[
|
||||
'text' => $c['time'] ? "timer: " . $this->getTime($c['time']) : $this->i18n('timer'),
|
||||
'callback_data' => "/timerXr $i",
|
||||
],
|
||||
[
|
||||
'text' => $this->i18n($c['inbounds'][0]['settings']['clients'][$i]['off'] ? 'off' : 'on'),
|
||||
'text' => $this->i18n($c['off'] ? 'off' : 'on'),
|
||||
'callback_data' => "/switchXr $i",
|
||||
],
|
||||
];
|
||||
$template = $c['inbounds'][0]['settings']['clients'][$i]['template'] ? base64_decode($c['inbounds'][0]['settings']['clients'][$i]['template']) : 'default(' . ($pac['defaulttemplate'] ? base64_decode($pac['defaulttemplate']) : 'origin') . ')';
|
||||
$data[] = [
|
||||
$singtemplate = $c['singtemplate'] ? base64_decode($c['singtemplate']) : 'default(' . ($pac['defaultsingtemplate'] ? base64_decode($pac['defaultsingtemplate']) : 'origin') . ')';
|
||||
$v2raytemplate = $c['v2raytemplate'] ? base64_decode($c['v2raytemplate']) : 'default(' . ($pac['defaultv2raytemplate'] ? base64_decode($pac['defaultv2raytemplate']) : 'origin') . ')';
|
||||
$data[] = [
|
||||
[
|
||||
'text' => $this->i18n('template singbox') . ": $template",
|
||||
'callback_data' => "/templateUser $i",
|
||||
'text' => $this->i18n('v2ray') . ": $v2raytemplate",
|
||||
'callback_data' => "/templateUser v2ray $i",
|
||||
],
|
||||
[
|
||||
'text' => $this->i18n('singbox') . ": $singtemplate",
|
||||
'callback_data' => "/templateUser sing $i",
|
||||
],
|
||||
];
|
||||
$data[] = [
|
||||
@@ -3815,8 +3955,6 @@ DNS-over-HTTPS with IP:
|
||||
'text' => $this->i18n('rename'),
|
||||
'callback_data' => "/renameXrUser $i",
|
||||
],
|
||||
];
|
||||
$data[] = [
|
||||
[
|
||||
'text' => $this->i18n('delete'),
|
||||
'callback_data' => "/delxr $i",
|
||||
@@ -3875,22 +4013,22 @@ DNS-over-HTTPS with IP:
|
||||
echo json_encode($c);
|
||||
}
|
||||
|
||||
public function singboxSubscription($key, $fs = 0)
|
||||
public function subscription()
|
||||
{
|
||||
$pac = $this->getPacConf();
|
||||
$domain = $pac['domain'] ?: $this->ip;
|
||||
$xr = $this->getXray();
|
||||
$scheme = empty($this->nginxGetTypeCert()) ? 'http' : 'https';
|
||||
$hash = substr(md5($this->key), 0, 8);
|
||||
|
||||
$flag = true;
|
||||
foreach ($xr['inbounds'][0]['settings']['clients'] as $k => $v) {
|
||||
if ($v['id'] == $key) {
|
||||
if (!empty($fs)) {
|
||||
return $this->userXr($k, 1);
|
||||
}
|
||||
if ($v['id'] == $_GET['s']) {
|
||||
if (empty($v['off'])) {
|
||||
$flag = false;
|
||||
}
|
||||
$template = base64_decode($v['template']);
|
||||
$template = base64_decode($_GET['t'] == 's' ? $v['v2raytemplate'] : $v['singtemplate']);
|
||||
$uid = $v['id'];
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -3898,40 +4036,96 @@ DNS-over-HTTPS with IP:
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!empty($_GET['r'])) {
|
||||
$si = "$scheme://{$domain}/pac?h=$hash&t=si&s=$uid";
|
||||
$v2 = "$scheme://{$domain}/pac?h=$hash&t=s&s=$uid";
|
||||
switch ($_GET['r']) {
|
||||
case 'si':
|
||||
header("Location: sing-box://import-remote-profile/?url=" . urlencode($si));
|
||||
exit;
|
||||
case 'st':
|
||||
header("Location: streisand://import/$v2");
|
||||
exit;
|
||||
case 'v':
|
||||
header("Location: v2rayng://install-config?url=" . urlencode($v2));
|
||||
exit;
|
||||
case 'h':
|
||||
header("Location: hiddify://install-config/?url=" . urlencode($si));
|
||||
exit;
|
||||
case 'w':
|
||||
file_put_contents('/singbox/update.cmd', preg_replace('#~url~#', $si, file_get_contents('/singbox/update.cmd')));
|
||||
$zip = new ZipArchive();
|
||||
$n = "singbox_$uid.zip";
|
||||
$zip->open($n, ZipArchive::CREATE | ZipArchive::OVERWRITE);
|
||||
foreach (scandir('/singbox') as $k => $v) {
|
||||
if (!empty(!in_array($v, ['.', '..']))) {
|
||||
$zip->addFile("/singbox/$v", $v);
|
||||
}
|
||||
}
|
||||
$zip->close();
|
||||
header('Content-Disposition: attachment; filename="singbox.zip"');
|
||||
echo file_get_contents($n);
|
||||
unlink($n);
|
||||
exit;
|
||||
}
|
||||
}
|
||||
|
||||
switch (true) {
|
||||
case !empty($template) && $template == 'origin':
|
||||
case empty($template) && empty($pac['defaulttemplate']):
|
||||
$c = json_decode(file_get_contents('/config/sing.json'), true);
|
||||
case empty($template) && empty($pac['default' . ($_GET['t'] == 's' ? 'v2ray' : 'sing') . 'template']):
|
||||
$c = json_decode(file_get_contents('/config/' . ($_GET['t'] == 's' ? 'v2ray' : 'sing') . '.json'), true);
|
||||
break;
|
||||
case !empty($template):
|
||||
$c = $pac['singtemplates'][$template];
|
||||
$c = $pac[$_GET['t'] == 's' ? 'v2raytemplates' : 'singtemplates'][$template];
|
||||
break;
|
||||
|
||||
default:
|
||||
$c = $pac['singtemplates'][base64_decode($pac['defaulttemplate'])];
|
||||
$c = $pac[$_GET['t'] == 's' ? 'v2raytemplates' : 'singtemplates'][base64_decode($pac['default' . ($_GET['t'] == 's' ? 'v2ray' : 'sing') . 'template'])];
|
||||
break;
|
||||
}
|
||||
|
||||
if ($c['dns']['servers'][0]['address'] == '~dns~') {
|
||||
$c['dns']['servers'][0]['address'] = "tls://" . ($pac['adguardkey'] ? "{$pac['adguardkey']}." : '') . "$domain";
|
||||
}
|
||||
switch ($_GET['t']) {
|
||||
case 's':
|
||||
$c['outbounds'][0]['settings']['vnext'][0]['address'] = $domain;
|
||||
$c['outbounds'][0]['settings']['vnext'][0]['users'][0]['id'] = $uid;
|
||||
$c['outbounds'][0]['streamSettings']['realitySettings']['serverName'] = $xr['inbounds'][0]['streamSettings']['realitySettings']['serverNames'][0];
|
||||
$c['outbounds'][0]['streamSettings']['realitySettings']['publicKey'] = $pac['xray'];
|
||||
$c['outbounds'][0]['streamSettings']['realitySettings']['shortId'] = $xr['inbounds'][0]['streamSettings']['realitySettings']['shortIds'][0];
|
||||
|
||||
$c['outbounds'][0]['server'] = $domain;
|
||||
$c['outbounds'][0]['uuid'] = $key;
|
||||
$c['outbounds'][0]['tls']['reality']['public_key'] = $pac['xray'];
|
||||
$c['outbounds'][0]['tls']['server_name'] = $xr['inbounds'][0]['streamSettings']['realitySettings']['serverNames'][0];
|
||||
$c['outbounds'][0]['tls']['reality']['short_id'] = $xr['inbounds'][0]['streamSettings']['realitySettings']['shortIds'][0];
|
||||
foreach ($c['route']['rules'] as $k => $v) {
|
||||
if (array_key_exists('domain_suffix', $v) && $v['domain_suffix'] == '~pac~') {
|
||||
$c['route']['rules'][$k]['domain_suffix'] = array_keys(array_filter($pac['includelist']));
|
||||
if (empty($c['route']['rules'][$k]['domain_suffix'])) {
|
||||
unset($c['route']['rules'][$k]);
|
||||
foreach ($c['routing']['rules'] as $k => $v) {
|
||||
if (array_key_exists('domain', $v) && $v['domain'] == '~pac~') {
|
||||
$c['routing']['rules'][$k]['domain'] = array_keys(array_filter($pac['includelist'] ?: []));
|
||||
if (empty($c['routing']['rules'][$k]['domain'])) {
|
||||
unset($c['routing']['rules'][$k]);
|
||||
}
|
||||
}
|
||||
}
|
||||
$c['routing']['rules'] = array_values($c['routing']['rules']);
|
||||
break;
|
||||
case 'si':
|
||||
if ($c['dns']['servers'][0]['address'] == '~dns~') {
|
||||
$c['dns']['servers'][0]['address'] = "tls://" . ($pac['adguardkey'] ? "{$pac['adguardkey']}." : '') . "$domain";
|
||||
}
|
||||
}
|
||||
}
|
||||
$c['route']['rules'] = array_values($c['route']['rules']);
|
||||
|
||||
return json_encode($c);
|
||||
$c['outbounds'][0]['server'] = $domain;
|
||||
$c['outbounds'][0]['uuid'] = $uid;
|
||||
$c['outbounds'][0]['tls']['reality']['public_key'] = $pac['xray'];
|
||||
$c['outbounds'][0]['tls']['server_name'] = $xr['inbounds'][0]['streamSettings']['realitySettings']['serverNames'][0];
|
||||
$c['outbounds'][0]['tls']['reality']['short_id'] = $xr['inbounds'][0]['streamSettings']['realitySettings']['shortIds'][0];
|
||||
foreach ($c['route']['rules'] as $k => $v) {
|
||||
if (array_key_exists('domain_suffix', $v) && $v['domain_suffix'] == '~pac~') {
|
||||
$c['route']['rules'][$k]['domain_suffix'] = array_keys(array_filter($pac['includelist'] ?: []));
|
||||
if (empty($c['route']['rules'][$k]['domain_suffix'])) {
|
||||
unset($c['route']['rules'][$k]);
|
||||
}
|
||||
}
|
||||
}
|
||||
$c['route']['rules'] = array_values($c['route']['rules']);
|
||||
break;
|
||||
}
|
||||
|
||||
header('Content-type: application/json');
|
||||
echo json_encode($c);
|
||||
}
|
||||
|
||||
public function getXray()
|
||||
|
||||
+6
-33
@@ -22,50 +22,23 @@ $address = $_GET['a'] ?: '127.0.0.1';
|
||||
$port = $_GET['p'] ?: '1080';
|
||||
$hash = $_GET['h'];
|
||||
if ($hash == substr(md5($c['key']), 0, 8)) {
|
||||
require __DIR__ . '/bot.php';
|
||||
require __DIR__ . '/i18n.php';
|
||||
$bot = new Bot($c['key'], $i);
|
||||
switch ($type) {
|
||||
case 'mirror':
|
||||
require __DIR__ . '/bot.php';
|
||||
require __DIR__ . '/i18n.php';
|
||||
$bot = new Bot($c['key'], $i);
|
||||
$bot->getMirror();
|
||||
break;
|
||||
|
||||
case 's':
|
||||
require __DIR__ . '/bot.php';
|
||||
require __DIR__ . '/i18n.php';
|
||||
$bot = new Bot($c['key'], $i);
|
||||
if (!empty($_GET['b'])) {
|
||||
$fs = $bot->v2raySubscription($_GET['s'], 1);
|
||||
header("Location: $fs");
|
||||
exit;
|
||||
} else {
|
||||
header('Content-Type: application/json');
|
||||
echo $bot->v2raySubscription($_GET['s']);
|
||||
}
|
||||
exit;
|
||||
|
||||
case 'si':
|
||||
require __DIR__ . '/bot.php';
|
||||
require __DIR__ . '/i18n.php';
|
||||
$bot = new Bot($c['key'], $i);
|
||||
if (!empty($_GET['b'])) {
|
||||
$fs = $bot->singboxSubscription($_GET['s'], 1);
|
||||
header("Location: $fs");
|
||||
exit;
|
||||
} else {
|
||||
header('Content-Type: application/json');
|
||||
echo $bot->singboxSubscription($_GET['s']);
|
||||
}
|
||||
$bot->subscription();
|
||||
exit;
|
||||
|
||||
case 'te':
|
||||
require __DIR__ . '/bot.php';
|
||||
require __DIR__ . '/i18n.php';
|
||||
$bot = new Bot($c['key'], $i);
|
||||
if (!empty($_GET['te'])) {
|
||||
$t = $bot->getPacConf()['singtemplates'][urldecode($_GET['te'])];
|
||||
$t = $bot->getPacConf()["{$_GET['ty']}templates"][urldecode($_GET['te'])];
|
||||
} else {
|
||||
$t = json_decode(file_get_contents('/config/sing.json'), true);
|
||||
$t = json_decode(file_get_contents("/config/{$_GET['ty']}.json"), true);
|
||||
}
|
||||
if ($t) {
|
||||
header('Content-Type: application/json');
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
<div style="position:absolute;top:0;right:0;width:35%;text-align:center;background-color: #17212b;">
|
||||
<img src="toncoin.png" width="100%" alt="">
|
||||
<a href="javascript:;" id="copy" style="color:white;text-decoration:none" data-id="UQCDDkaX3fCAFBek28Hx4TfvDDRqeizOW74blVMVAM4_m4OW">copy</a>
|
||||
<iframe src="https://ghbtns.com/github-btn.html?user=mercurykd&repo=vpnbot&type=star&count=true" frameborder="0" scrolling="0" width="150" height="20" title="GitHub"></iframe>
|
||||
</div>
|
||||
<a style="background-color: #8B3FFD;height: 46px;display:inline-block;padding:0 54px;color: white;border-radius: 12px;text-decoration: none;font-size: 20px;line-height: 46px;font-family: arial;" href="https://yoomoney.ru/to/410011827900450">
|
||||
<svg style="width: 24px;fill: white;position: relative;top: 4px;" class="qa-fundraise-button-logo mui-m0okdh" viewBox="0 0 16 16"><path d="M4.638 8.5a5.67 5.67 0 015.681-5.68A5.693 5.693 0 0116 8.5a5.693 5.693 0 01-5.68 5.682A5.67 5.67 0 014.637 8.5zm3.56 0c0 1.151.97 2.122 2.121 2.122 1.15 0 2.085-.97 2.121-2.121 0-1.15-.97-2.121-2.12-2.121-1.151 0-2.122.97-2.122 2.12zm-3.596 4.243v-8.27H0l2.589 8.27h2.013z" clip-rule="evenodd"></path></svg>
|
||||
|
||||
@@ -3,7 +3,7 @@ worker_processes auto;
|
||||
|
||||
load_module /usr/lib/nginx/modules/ngx_stream_module.so;
|
||||
|
||||
error_log /logs/nginx_error;
|
||||
error_log /logs/upstream_error;
|
||||
pid /var/run/nginx.pid;
|
||||
|
||||
events {
|
||||
|
||||
+1
-1
@@ -85,7 +85,7 @@
|
||||
"rules": [{
|
||||
"type": "field",
|
||||
"outboundTag": "proxy",
|
||||
"domain": []
|
||||
"domain": "~pac~"
|
||||
}, {
|
||||
"type": "field",
|
||||
"port": "0-65535",
|
||||
|
||||
+32
-1
@@ -93,7 +93,7 @@ services:
|
||||
ipv4_address: 10.10.1.2
|
||||
logging: *default-logging
|
||||
php:
|
||||
image: mercurykd/vpnbot-php:1.3
|
||||
image: mercurykd/vpnbot-php:1.4
|
||||
build:
|
||||
dockerfile: dockerfile/php.dockerfile
|
||||
args:
|
||||
@@ -115,6 +115,7 @@ services:
|
||||
- ./.env:/mirror/.env
|
||||
- ./update:/update
|
||||
- ./.git:/.git
|
||||
- ./singbox_windows:/singbox
|
||||
environment:
|
||||
IP: ${IP}
|
||||
VER: ${VER}
|
||||
@@ -489,3 +490,33 @@ services:
|
||||
default:
|
||||
ipv4_address: 10.10.0.12
|
||||
logging: *default-logging
|
||||
wp:
|
||||
image: mercurykd/vpnbot-wp:1
|
||||
build:
|
||||
dockerfile: dockerfile/warp.dockerfile
|
||||
args:
|
||||
image: ${IMAGE}
|
||||
cap_add:
|
||||
- NET_ADMIN
|
||||
devices:
|
||||
- /dev/net/tun:/dev/net/tun
|
||||
volumes:
|
||||
- ./config/.profile:/root/.bashrc:ro
|
||||
- ./ssh:/ssh
|
||||
- ./config/sshd_config:/etc/ssh/sshd_config
|
||||
- ./config:/config
|
||||
- ./certs:/certs
|
||||
- ./scripts/start_wp.sh:/start_wp.sh
|
||||
hostname: warp
|
||||
container_name: warp-${VER}
|
||||
depends_on:
|
||||
php:
|
||||
condition: service_healthy
|
||||
environment:
|
||||
TZ: ${TZ}
|
||||
stop_grace_period: 1s
|
||||
command: ["/bin/sh", "/start_wp.sh"]
|
||||
networks:
|
||||
default:
|
||||
ipv4_address: 10.10.0.13
|
||||
logging: *default-logging
|
||||
|
||||
@@ -4,6 +4,7 @@ RUN apk add --no-cache --update php81 \
|
||||
php81-mbstring \
|
||||
php81-session \
|
||||
php81-phar \
|
||||
php81-zip \
|
||||
php81-curl \
|
||||
php81-opcache \
|
||||
php81-openssl \
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
FROM ubuntu:22.04
|
||||
RUN apt update && apt install -y curl gpg socat lsb-release \
|
||||
&& curl -fsSL https://pkg.cloudflareclient.com/pubkey.gpg | gpg --yes --dearmor --output /usr/share/keyrings/cloudflare-warp-archive-keyring.gpg \
|
||||
&& echo "deb [signed-by=/usr/share/keyrings/cloudflare-warp-archive-keyring.gpg] https://pkg.cloudflareclient.com/ $(lsb_release -cs) main" | tee /etc/apt/sources.list.d/cloudflare-client.list \
|
||||
&& apt update && apt install -y cloudflare-warp
|
||||
@@ -6,6 +6,10 @@ telegram bot to manage servers (inside the bot)
|
||||
- change secret
|
||||
- qr/config
|
||||
- change fake domain
|
||||
- multiple users
|
||||
- subscriptions with routing
|
||||
- routing templates per user
|
||||
- steal from yourself
|
||||
<img src="https://github.com/mercurykd/vpnbot/assets/30900414/39bdf4e0-96a6-4257-b61e-30a14122e236" width="200">
|
||||
|
||||
### NaiveProxy
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
warp-svc > /dev/null &
|
||||
sleep 3
|
||||
warp-cli --accept-tos registration new
|
||||
warp-cli --accept-tos mode proxy
|
||||
warp-cli --accept-tos connect
|
||||
socat TCP-LISTEN:4000,fork TCP:127.0.0.1:40000
|
||||
@@ -0,0 +1,2 @@
|
||||
winsw3.exe install
|
||||
pause
|
||||
Binary file not shown.
@@ -0,0 +1 @@
|
||||
winsw3.exe start
|
||||
@@ -0,0 +1,2 @@
|
||||
winsw3.exe status
|
||||
pause
|
||||
@@ -0,0 +1 @@
|
||||
winsw3.exe stop
|
||||
@@ -0,0 +1,2 @@
|
||||
winsw3.exe uninstall
|
||||
pause
|
||||
@@ -0,0 +1,35 @@
|
||||
@echo off
|
||||
setlocal
|
||||
|
||||
set "exe_path=sing-box.exe"
|
||||
set "URL=~url~"
|
||||
set "FileName=config.json"
|
||||
set "PreviousHash="
|
||||
|
||||
taskkill /IM "%exe_path%" /F
|
||||
powershell -command "(New-Object System.Net.WebClient).DownloadFile('%URL%', '%FileName%')"
|
||||
for /F "skip=1 delims=" %%H in ('2^>nul CertUtil -hashfile "%FileName%" SHA256') do (
|
||||
if not defined PreviousHash set "PreviousHash=%%H"
|
||||
)
|
||||
start "" /B "%CD%\%exe_path%" run -c "%FileName%"
|
||||
echo "%PreviousHash%"
|
||||
:loop
|
||||
powershell -command "(New-Object System.Net.WebClient).DownloadFile('%URL%', '%FileName%')"
|
||||
for /F "skip=1 delims=" %%H in ('2^>nul CertUtil -hashfile "%FileName%" SHA256') do (
|
||||
if not defined HASH set "HASH=%%H"
|
||||
)
|
||||
set "CurrentHash=%HASH%"
|
||||
set "HASH="
|
||||
echo "%CurrentHash%"
|
||||
if "%CurrentHash%" NEQ "%PreviousHash%" (
|
||||
echo "change"
|
||||
set "PreviousHash=%CurrentHash%"
|
||||
taskkill /IM "%exe_path%" /F
|
||||
start "" /B "%CD%\%exe_path%" run -c "%FileName%"
|
||||
) else (
|
||||
echo "not change"
|
||||
)
|
||||
|
||||
timeout /t 15 /nobreak
|
||||
|
||||
goto :loop
|
||||
Binary file not shown.
@@ -0,0 +1,15 @@
|
||||
<service>
|
||||
<id>singbox</id>
|
||||
<name>singbox</name>
|
||||
<description>singbox</description>
|
||||
<executable>%BASE%\update.cmd</executable>
|
||||
<logmode>rotate</logmode>
|
||||
<onfailure action="restart" delay="10 sec" />
|
||||
<onfailure action="restart" delay="20 sec" />
|
||||
<onfailure action="restart" delay="30 sec" />
|
||||
<onfailure action="none" />
|
||||
<onexit action="restart" />
|
||||
<onexit action="restart" />
|
||||
<onexit action="restart" />
|
||||
<onexit action="none" />
|
||||
</service>
|
||||
@@ -1,3 +1,16 @@
|
||||
16.04.2024 v1.29
|
||||
- рефакторинг подписок
|
||||
- кнопки импорта для различных клиентов
|
||||
- шаблоны для v2ray
|
||||
15.04.2024 v1.28
|
||||
- xtls: список блокировки, список warp
|
||||
- улучшение отображения таймера
|
||||
14.04.2024 v1.27.1
|
||||
- singbox windows: замена winsw на winsw3, + скрипт обновления подписки
|
||||
13.04.2024 v1.27
|
||||
- архив сингбокса для windows, работает как служба
|
||||
12.04.2024 v1.26
|
||||
- имя клиента xtls подтягивается по подписке из бота
|
||||
11.04.2024 v1.25
|
||||
- подпись дефолтного шаблона в разделе пользователя xtls
|
||||
11.04.2024 v1.24
|
||||
|
||||
Reference in New Issue
Block a user