From 7c4a4964fdc61fdd8ef20570c10b44b71065ad33 Mon Sep 17 00:00:00 2001 From: mercury Date: Mon, 10 Apr 2023 13:09:37 +0400 Subject: [PATCH] timer for wireguard peer --- app/bot.php | 75 ++++++++++++++++++++++++++++++++++++-- app/cron.php | 11 ++++++ app/i18n.php | 83 ++++++++++++++++++++++--------------------- app/init.php | 2 ++ scripts/start_unit.sh | 1 + 5 files changed, 129 insertions(+), 43 deletions(-) create mode 100644 app/cron.php diff --git a/app/bot.php b/app/bot.php index 052cf21..0e1b743 100644 --- a/app/bot.php +++ b/app/bot.php @@ -234,6 +234,9 @@ class Bot case preg_match('~^/rename (?P\d+(?:_(?:-)?\d+)?)$~', $this->input['callback'], $m): $this->rename(...explode('_', $m['arg'])); break; + case preg_match('~^/timer (?P\d+(?:_(?:-)?\d+)?)$~', $this->input['callback'], $m): + $this->timer(...explode('_', $m['arg'])); + break; case !empty($this->input['reply']): $this->reply(); break; @@ -360,6 +363,67 @@ class Bot ]; } + public function timer(int $client, $page) + { + $r = $this->send( + $this->input['chat'], + "@{$this->input['username']} enter time like 1 month/1 day/1 hour/1 minute/1 second:", + $this->input['message_id'], + reply: 'enter time like 1 month/1 day/1 hour/1 minute/1 second:', + ); + $_SESSION['reply'][$r['result']['message_id']] = [ + 'start_message' => $this->input['message_id'], + 'start_callback' => $this->input['callback_id'], + 'callback' => 'timerClient', + 'args' => [$client, $page], + ]; + } + + public function timerClient(string $time, int $client) + { + $clients = $this->readClients(); + $server = $this->readConfig(); + switch (true) { + case preg_match('~(\d+)\s(month|day|second|minute)~', $time, $m): + $date = date('Y-m-d H:i:s', strtotime("+{$m[1]} {$m[2]}")); + $clients[$client]['interface']['## time'] = $date; + foreach ($server['peers'] as $k => $v) { + if ($v['AllowedIPs'] == $clients[$client]['interface']['Address']) { + $server['peers'][$k]['## time'] = $date; + } + } + break; + case preg_match('~0~', $time): + unset($clients[$client]['interface']['## time']); + foreach ($server['peers'] as $k => $v) { + if ($v['AllowedIPs'] == $clients[$client]['interface']['Address']) { + unset($server['peers'][$k]['## time']); + } + } + break; + } + $this->saveClients($clients); + $this->restartWG($this->createConfig($server)); + $this->menu('client', implode('_', $_SESSION['reply'][$this->input['reply']]['args'])); + } + + public function cron() + { + while (true) { + $clients = $this->readClients(); + if ($clients) { + foreach ($clients as $k => $v) { + if (!empty($v['interface']['## time'])) { + if (strtotime($v['interface']['## time']) < time()) { + $this->deletePeer($k, 0, false); + } + } + } + } + sleep(10); + } + } + public function renameClient(string $name, int $client) { $clients = $this->readClients(); @@ -1178,13 +1242,15 @@ DNS-over-HTTPS with IP: ); } - public function deletePeer($client, $page) + public function deletePeer($client, $page, $menu = true) { $conf = $this->readConfig(); $this->deleteClient($client); unset($conf['peers'][$client]); $this->restartWG($this->createConfig($conf)); - $this->menu('wg', $page); + if ($menu) { + $this->menu('wg', $page); + } } public function statusWg(int $page = 0) @@ -1210,6 +1276,7 @@ DNS-over-HTTPS with IP: foreach ($conf['peers'] as $k => $v) { preg_match_all('~([0-9.]+\.?)\s(\w+)~', $v['status']['transfer'], $m); $text[] = ($v['online'] == 'OFFLINE' ? '(OFFLINE) ' : '') + . ($v['## time'] ? "({$v['## time']}) ": "") . "{$this->getName($v)} " . ($v['online'] != 'OFFLINE' ? "({$v['online']})" : '') . ($m[0] ? " {$m[1][0]}↑ {$m[2][0]} / {$m[1][1]}↓ {$m[2][1]}" : '') @@ -1255,6 +1322,10 @@ DNS-over-HTTPS with IP: 'text' => $this->i18n('rename'), 'callback_data' => "/rename {$client}_$page", ], + [ + 'text' => $this->i18n('timer'), + 'callback_data' => "/timer {$client}_$page", + ], ], [ [ diff --git a/app/cron.php b/app/cron.php new file mode 100644 index 0000000..de10317 --- /dev/null +++ b/app/cron.php @@ -0,0 +1,11 @@ +cron(); diff --git a/app/i18n.php b/app/i18n.php index 64ad651..4ed19af 100644 --- a/app/i18n.php +++ b/app/i18n.php @@ -2,48 +2,49 @@ $i = [ 'en' => [ - 'wg_title' => 'Wireguard', - 'sh_title' => 'Shadowsocks', - 'ad_title' => 'AdGuard', - 'config' => 'config', - 'pac' => 'PAC', - 'chat' => 'discussion group', - 'back' => 'back', - 'import' => 'import', - 'export' => 'export', - 'delete' => 'delete', - 'add' => 'add', - 'donate' => 'donate', - 'admin' => 'admin', - 'menu' => 'Menu', - 'update status' => 'update status', - 'add peer' => 'add peer', - 'all traffic' => 'all traffic', - 'subnet' => 'subnet', - 'proxy ip' => 'proxy ip', - 'rename' => 'rename', - 'show QR' => 'show QR', - 'download config' => 'download config', - 'install domain' => 'install domain', - 'renew SSL' => 'renew SSL', - 'delete SSL' => 'delete SSL', - 'Letsencrypt SSL' => 'Letsencrypt SSL', - 'Self SSL' => 'Self SSL', - 'change password' => 'change password', - 'reset settings' => 'reset settings', - 'add upstream' => 'add upstream', - 'check DNS' => 'check DNS', - 'update' => 'update', - 'self list' => 'self list', - 'reverse list' => 'reverse list', - 'subzones' => 'subzones', - 'check url' => 'check url', - 'blacklist exclude' => 'blacklist exclude', - 'lang' => 'language', - 'adguard web' => 'web interface', - 'domain explain' => 'Some clients require a valid certificate when connecting, such as windows 11 DoH or ShadowSocks Android (PAC url), this requires a domain', + 'wg_title' => 'Wireguard', + 'sh_title' => 'Shadowsocks', + 'ad_title' => 'AdGuard', + 'config' => 'config', + 'pac' => 'PAC', + 'chat' => 'discussion group', + 'back' => 'back', + 'import' => 'import', + 'export' => 'export', + 'delete' => 'delete', + 'add' => 'add', + 'donate' => 'donate', + 'admin' => 'admin', + 'menu' => 'Menu', + 'update status' => 'update status', + 'add peer' => 'add peer', + 'all traffic' => 'all traffic', + 'subnet' => 'subnet', + 'proxy ip' => 'proxy ip', + 'rename' => 'rename', + 'show QR' => 'show QR', + 'download config' => 'download config', + 'install domain' => 'install domain', + 'renew SSL' => 'renew SSL', + 'delete SSL' => 'delete SSL', + 'Letsencrypt SSL' => 'Letsencrypt SSL', + 'Self SSL' => 'Self SSL', + 'change password' => 'change password', + 'reset settings' => 'reset settings', + 'add upstream' => 'add upstream', + 'check DNS' => 'check DNS', + 'update' => 'update', + 'self list' => 'self list', + 'reverse list' => 'reverse list', + 'subzones' => 'subzones', + 'check url' => 'check url', + 'blacklist exclude' => 'blacklist exclude', + 'lang' => 'language', + 'adguard web' => 'web interface', + 'domain explain' => 'Some clients require a valid certificate when connecting, such as windows 11 DoH or ShadowSocks Android (PAC url), this requires a domain', 'self list explain' => ' - domains that will work through a proxy', 'reverse list explain' => ' - domains that will work without a proxy, all others through a proxy', + 'timer' => 'set timer', ], 'ru' => [ 'wg_title' => 'Wireguard', @@ -88,6 +89,6 @@ $i = [ 'domain explain' => 'Некоторым клиентам требуется валидный сертификат при подключении, например Windows 11 DoH или ShadowSocks Android (URL-адрес PAC), для этого требуется домен', 'self list explain' => ' - домены, которые будут работать через прокси', 'reverse list explain' => ' - домены которые будут работать без прокси, все остальные через прокси', - + 'timer' => 'установить время действия', ], ]; diff --git a/app/init.php b/app/init.php index 2dd1d46..3261094 100644 --- a/app/init.php +++ b/app/init.php @@ -1,5 +1,7 @@