From 8400d55c642a27a10641b5c534320fbaba18bd7f Mon Sep 17 00:00:00 2001 From: Whispering Wind <151555003+ReturnFI@users.noreply.github.com> Date: Sun, 6 Oct 2024 21:40:02 +0330 Subject: [PATCH 01/14] Create normalsub.py --- core/scripts/normalsub/normalsub.py | 96 +++++++++++++++++++++++++++++ 1 file changed, 96 insertions(+) create mode 100644 core/scripts/normalsub/normalsub.py diff --git a/core/scripts/normalsub/normalsub.py b/core/scripts/normalsub/normalsub.py new file mode 100644 index 0000000..04b15bc --- /dev/null +++ b/core/scripts/normalsub/normalsub.py @@ -0,0 +1,96 @@ +import os +import ssl +import subprocess +import time +import re +import shlex +from aiohttp import web +from aiohttp.web_middlewares import middleware +from dotenv import load_dotenv + +load_dotenv() + +# Environment variables +CERTFILE = os.getenv('HYSTERIA_CERTFILE') +KEYFILE = os.getenv('HYSTERIA_KEYFILE') +PORT = int(os.getenv('HYSTERIA_PORT', '3325')) + +RATE_LIMIT = 100 +RATE_LIMIT_WINDOW = 60 + +rate_limit_store = {} + +@middleware +async def rate_limit_middleware(request, handler): + client_ip = request.headers.get('X-Forwarded-For', request.remote) + current_time = time.time() + + if client_ip in rate_limit_store: + requests, last_request_time = rate_limit_store[client_ip] + if current_time - last_request_time < RATE_LIMIT_WINDOW: + if requests >= RATE_LIMIT: + return web.Response(status=429, text="Rate limit exceeded.") + if current_time - last_request_time >= RATE_LIMIT_WINDOW: + rate_limit_store[client_ip] = (1, current_time) + else: + rate_limit_store[client_ip] = (requests + 1, last_request_time) + else: + rate_limit_store[client_ip] = (1, current_time) + + return await handler(request) + +def sanitize_input(value, pattern): + if not re.match(pattern, value): + raise ValueError(f"Invalid value: {value}") + return value + +async def handle(request): + try: + username = sanitize_input(request.match_info.get('username', ''), r'^[a-zA-Z0-9_-]+$') + + if not username: + return web.Response(status=400, text="Error: Missing 'username' parameter.") + + uri_output = get_user_uri(username) + return web.Response(text=uri_output, content_type='text/plain') + + except ValueError as e: + return web.Response(status=400, text=f"Error: {str(e)}") + except Exception as e: + print(f"Internal Server Error: {str(e)}") + return web.Response(status=500, text="Error: Internal server error.") + +def get_user_uri(username): + try: + command = [ + 'python3', + '/etc/hysteria/core/cli.py', + 'show-user-uri', + '-u', username, + '-a' + ] + safe_command = [shlex.quote(arg) for arg in command] + output = subprocess.check_output(safe_command).decode().strip() + output = re.sub(r'IPv4:\s*', '', output) + output = re.sub(r'IPv6:\s*', '', output) + + return output + except subprocess.CalledProcessError: + raise RuntimeError("Failed to get URI.") + +async def handle_404(request): + print(f"404 Not Found: {request.path}") + return web.Response(status=404, text="Not Found") + +if __name__ == '__main__': + app = web.Application(middlewares=[rate_limit_middleware]) + + app.add_routes([web.get('/sub/normal/{username}', handle)]) + app.router.add_route('*', '/sub/normal/{tail:.*}', handle_404) + + ssl_context = ssl.SSLContext(ssl.PROTOCOL_TLS_SERVER) + ssl_context.load_cert_chain(certfile=CERTFILE, keyfile=KEYFILE) + ssl_context.minimum_version = ssl.TLSVersion.TLSv1_2 + ssl_context.set_ciphers('AES256+EECDH:AES256+EDH') + + web.run_app(app, port=PORT, ssl_context=ssl_context) From 4bc59b4858b24b504042b6c6804cfe997a792e5b Mon Sep 17 00:00:00 2001 From: Whispering Wind <151555003+ReturnFI@users.noreply.github.com> Date: Sun, 6 Oct 2024 21:40:30 +0330 Subject: [PATCH 02/14] Create normalsub.sh --- core/scripts/normalsub/normalsub.sh | 109 ++++++++++++++++++++++++++++ 1 file changed, 109 insertions(+) create mode 100644 core/scripts/normalsub/normalsub.sh diff --git a/core/scripts/normalsub/normalsub.sh b/core/scripts/normalsub/normalsub.sh new file mode 100644 index 0000000..78f65ca --- /dev/null +++ b/core/scripts/normalsub/normalsub.sh @@ -0,0 +1,109 @@ +#!/bin/bash +source /etc/hysteria/core/scripts/utils.sh +define_colors + +install_dependencies() { + echo "Installing necessary dependencies..." + apt-get install certbot -y > /dev/null 2>&1 + if [ $? -ne 0 ]; then + echo -e "${red}Error: Failed to install certbot. ${NC}" + exit 1 + fi + echo -e "${green}Certbot installed successfully. ${NC}" +} + +update_env_file() { + local domain=$1 + local port=$2 + local cert_dir="/etc/letsencrypt/live/$domain" + + cat < /etc/hysteria/core/scripts/normalsub/.env +HYSTERIA_DOMAIN=$domain +HYSTERIA_PORT=$port +HYSTERIA_CERTFILE=$cert_dir/fullchain.pem +HYSTERIA_KEYFILE=$cert_dir/privkey.pem +EOL +} + +create_service_file() { + cat < /etc/systemd/system/normalsub.service +[Unit] +Description=normalsub Python Service +After=network.target + +[Service] +ExecStart=/bin/bash -c 'source /etc/hysteria/hysteria2_venv/bin/activate && /etc/hysteria/hysteria2_venv/bin/python /etc/hysteria/core/scripts/normalsub/normalsub.py' +WorkingDirectory=/etc/hysteria/core/scripts/normalsub +EnvironmentFile=/etc/hysteria/core/scripts/normalsub/.env +Restart=always +User=root +Group=root + +[Install] +WantedBy=multi-user.target +EOL +} + +start_service() { + local domain=$1 + local port=$2 + + if systemctl is-active --quiet normalsub.service; then + echo "The normalsub.service is already running." + return + fi + + install_dependencies + + echo "Generating SSL certificates for $domain..." + certbot certonly --standalone --agree-tos --register-unsafely-without-email -d "$domain" + if [ $? -ne 0 ]; then + echo -e "${red}Error: Failed to generate SSL certificates. ${NC}" + exit 1 + fi + + update_env_file "$domain" "$port" + create_service_file + chown -R hysteria:hysteria "/etc/letsencrypt/live/$domain" + chown -R hysteria:hysteria /etc/hysteria/core/scripts/normalsub + systemctl daemon-reload + systemctl enable normalsub.service > /dev/null 2>&1 + systemctl start normalsub.service > /dev/null 2>&1 + systemctl daemon-reload > /dev/null 2>&1 + + if systemctl is-active --quiet normalsub.service; then + echo -e "${green}normalsub service setup completed. The service is now running on port $port. ${NC}" + else + echo -e "${red}normalsub setup completed. The service failed to start. ${NC}" + fi +} + +stop_service() { + systemctl stop normalsub.service > /dev/null 2>&1 + systemctl disable normalsub.service > /dev/null 2>&1 + systemctl daemon-reload > /dev/null 2>&1 + + rm -f /etc/hysteria/core/scripts/normalsub/.env + echo -e "\n" + + echo -e "${yellow}normalsub service stopped and disabled. .env file removed. ${NC}" +} + +case "$1" in + start) + if [ -z "$2" ] || [ -z "$3" ]; then + echo -e "${red}Usage: $0 start ${NC}" + exit 1 + fi + start_service "$2" "$3" + ;; + stop) + stop_service + ;; + *) + echo -e "${red}Usage: $0 {start|stop} ${NC}" + exit 1 + ;; +esac + +define_colors From 85bd0ce2605e8808d49a61ed24e5b49948df6e79 Mon Sep 17 00:00:00 2001 From: Whispering Wind <151555003+ReturnFI@users.noreply.github.com> Date: Sun, 6 Oct 2024 21:44:00 +0330 Subject: [PATCH 03/14] Added Normal Sub --- core/cli.py | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/core/cli.py b/core/cli.py index 0110b47..3c5f9ac 100644 --- a/core/cli.py +++ b/core/cli.py @@ -35,6 +35,7 @@ class Command(Enum): BACKUP_HYSTERIA = os.path.join(SCRIPT_DIR, 'hysteria2', 'backup.sh') INSTALL_TELEGRAMBOT = os.path.join(SCRIPT_DIR, 'telegrambot', 'runbot.sh') INSTALL_SINGBOX = os.path.join(SCRIPT_DIR, 'singbox', 'singbox_shell.sh') + INSTALL_NORMALSUB = os.path.join(SCRIPT_DIR, 'normalsub', 'normalsub.sh') INSTALL_TCP_BRUTAL = os.path.join(SCRIPT_DIR, 'tcp-brutal', 'install.sh') INSTALL_WARP = os.path.join(SCRIPT_DIR, 'warp', 'install.sh') UNINSTALL_WARP = os.path.join(SCRIPT_DIR, 'warp', 'uninstall.sh') @@ -325,6 +326,19 @@ def singbox(action: str, domain: str, port: int): elif action == 'stop': run_cmd(['bash', Command.INSTALL_SINGBOX.value, 'stop']) +@cli.command('normal-sub') +@click.option('--action', '-a', required=True, help='Action to perform: start or stop', type=click.Choice(['start', 'stop'], case_sensitive=False)) +@click.option('--domain', '-d', required=False, help='Domain name for SSL', type=str) +@click.option('--port', '-p', required=False, help='Port number for NormalSub service', type=int) +def normalsub(action: str, domain: str, port: int): + if action == 'start': + if not domain or not port: + click.echo("Error: Both --domain and --port are required for the start action.") + return + run_cmd(['bash', Command.INSTALL_NORMALSUB.value, 'start', domain, str(port)]) + elif action == 'stop': + run_cmd(['bash', Command.INSTALL_NORMALSUB.value, 'stop']) + # endregion From 44bf5a41c50fc8f568cb5106f6955f43b31ba1ba Mon Sep 17 00:00:00 2001 From: Whispering Wind <151555003+ReturnFI@users.noreply.github.com> Date: Sun, 6 Oct 2024 22:16:24 +0330 Subject: [PATCH 04/14] Backup normalsub --- upgrade.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/upgrade.sh b/upgrade.sh index 0930c75..86546ef 100644 --- a/upgrade.sh +++ b/upgrade.sh @@ -16,6 +16,7 @@ FILES=( "/etc/hysteria/config.json" "/etc/hysteria/core/scripts/telegrambot/.env" "/etc/hysteria/core/scripts/singbox/.env" + "/etc/hysteria/core/scripts/normalsub/.env" ) echo "Backing up files to $TEMP_DIR" From d48e9a4412205ee51e14eb87ec846719bcd97738 Mon Sep 17 00:00:00 2001 From: Whispering Wind <151555003+ReturnFI@users.noreply.github.com> Date: Sun, 6 Oct 2024 22:25:53 +0330 Subject: [PATCH 05/14] Added Normal SUB --- menu.sh | 70 ++++++++++++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 62 insertions(+), 8 deletions(-) diff --git a/menu.sh b/menu.sh index b1a4d0a..df177ad 100644 --- a/menu.sh +++ b/menu.sh @@ -413,6 +413,58 @@ singbox_handler() { done } +normalsub_handler() { + while true; do + echo -e "${cyan}1.${NC} Start Normal-Sub service" + echo -e "${red}2.${NC} Stop Normal-Sub service" + echo "0. Back" + read -p "Choose an option: " option + + case $option in + 1) + if systemctl is-active --quiet normalsub.service; then + echo "The normalsub.service is already active." + else + while true; do + read -e -p "Enter the domain name for the SSL certificate: " domain + if [ -z "$domain" ]; then + echo "Domain name cannot be empty. Please try again." + else + break + fi + done + + while true; do + read -e -p "Enter the port number for the service: " port + if [ -z "$port" ]; then + echo "Port number cannot be empty. Please try again." + elif ! [[ "$port" =~ ^[0-9]+$ ]]; then + echo "Port must be a number. Please try again." + else + break + fi + done + + python3 $CLI_PATH normal-sub -a start -d "$domain" -p "$port" + fi + ;; + 2) + if ! systemctl is-active --quiet normalsub.service; then + echo "The normalsub.service is already inactive." + else + python3 $CLI_PATH normal-sub -a stop + fi + ;; + 0) + break + ;; + *) + echo "Invalid option. Please try again." + ;; + esac + done +} + # Function to display the main menu display_main_menu() { clear @@ -523,10 +575,11 @@ display_advance_menu() { echo -e "${red}[4] ${NC}↝ Uninstall WARP" echo -e "${green}[5] ${NC}↝ Telegram Bot" echo -e "${green}[6] ${NC}↝ SingBox SubLink" - echo -e "${cyan}[7] ${NC}↝ Change Port Hysteria2" - echo -e "${cyan}[8] ${NC}↝ Change SNI Hysteria2" - echo -e "${cyan}[9] ${NC}↝ Update Core Hysteria2" - echo -e "${red}[10] ${NC}↝ Uninstall Hysteria2" + echo -e "${green}[7] ${NC}↝ Normal-SUB SubLink" + echo -e "${cyan}[8] ${NC}↝ Change Port Hysteria2" + echo -e "${cyan}[9] ${NC}↝ Change SNI Hysteria2" + echo -e "${cyan}[10] ${NC}↝ Update Core Hysteria2" + echo -e "${red}[11] ${NC}↝ Uninstall Hysteria2" echo -e "${red}[0] ${NC}↝ Back to Main Menu" echo -e "${LPurple}◇──────────────────────────────────────────────────────────────────────◇${NC}" echo -ne "${yellow}➜ Enter your option: ${NC}" @@ -546,10 +599,11 @@ advance_menu() { 4) python3 $CLI_PATH uninstall-warp ;; 5) telegram_bot_handler ;; 6) singbox_handler ;; - 7) hysteria2_change_port_handler ;; - 8) hysteria2_change_sni_handler ;; - 9) python3 $CLI_PATH update-hysteria2 ;; - 10) python3 $CLI_PATH uninstall-hysteria2 ;; + 7) normalsub_handler ;; + 8) hysteria2_change_port_handler ;; + 9) hysteria2_change_sni_handler ;; + 10) python3 $CLI_PATH update-hysteria2 ;; + 11) python3 $CLI_PATH uninstall-hysteria2 ;; 0) return ;; *) echo "Invalid option. Please try again." ;; esac From b2d6b9e317acb6fbe86aed40b4638df70b793033 Mon Sep 17 00:00:00 2001 From: Whispering Wind <151555003+ReturnFI@users.noreply.github.com> Date: Sun, 6 Oct 2024 22:27:03 +0330 Subject: [PATCH 06/14] Clone Dev --- install.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/install.sh b/install.sh index f95bacf..50e07fe 100644 --- a/install.sh +++ b/install.sh @@ -53,7 +53,7 @@ else echo "All required packages are already installed." fi -git clone https://github.com/ReturnFI/Hysteria2 /etc/hysteria +git clone -b Dev https://github.com/ReturnFI/Hysteria2 /etc/hysteria cd /etc/hysteria python3 -m venv hysteria2_venv From 08631d647dc8d005b602bfb26dc7bec2e4ae9802 Mon Sep 17 00:00:00 2001 From: Whispering Wind <151555003+ReturnFI@users.noreply.github.com> Date: Sun, 6 Oct 2024 22:49:02 +0330 Subject: [PATCH 07/14] Normal SUB --- core/scripts/hysteria2/show_user_uri.sh | 22 +++++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) diff --git a/core/scripts/hysteria2/show_user_uri.sh b/core/scripts/hysteria2/show_user_uri.sh index 00cce5a..c8c6bbf 100644 --- a/core/scripts/hysteria2/show_user_uri.sh +++ b/core/scripts/hysteria2/show_user_uri.sh @@ -14,6 +14,18 @@ get_singbox_domain_and_port() { fi } +get_normalsub_domain_and_port() { + if [ -f "$NORMALSUB_ENV" ]; then + local domain port + domain=$(grep -E '^HYSTERIA_DOMAIN=' "$NORMALSUB_ENV" | cut -d'=' -f2) + port=$(grep -E '^HYSTERIA_PORT=' "$NORMALSUB_ENV" | cut -d'=' -f2) + echo "$domain" "$port" + else + echo "" + fi +} + + show_uri() { if [ -f "$USERS_FILE" ]; then if systemctl is-active --quiet hysteria-server.service; then @@ -22,6 +34,7 @@ show_uri() { local ip_version=4 local show_all=false local generate_singbox=false + local generate_normalsub=false load_hysteria2_env @@ -32,6 +45,7 @@ show_uri() { -ip) ip_version="$2"; shift ;; -a|--all) show_all=true ;; -s|--singbox) generate_singbox=true ;; + -n|--normalsub) generate_normalsub=true ;; *) echo "Unknown parameter passed: $1"; exit 1 ;; esac shift @@ -104,6 +118,12 @@ show_uri() { echo -e "\nSingbox Sublink:\nhttps://$domain:$port/sub/singbox/$username/$ip_version#$username\n" fi fi + if [ "$generate_normalsub" = true ] && systemctl is-active --quiet normalsub.service; then + read -r domain port < <(get_normalsub_domain_and_port) + if [ -n "$domain" ] && [ -n "$port" ]; then + echo -e "\nNormal-SUB Sublink:\nhttps://$domain:$port/sub/normal/$username#Hysteria2\n" + fi + fi else echo "Invalid username. Please try again." fi @@ -115,4 +135,4 @@ show_uri() { fi } -show_uri "$@" \ No newline at end of file +show_uri "$@" From 540042cd35df51c97d5497264706f9e055af7d44 Mon Sep 17 00:00:00 2001 From: Whispering Wind <151555003+ReturnFI@users.noreply.github.com> Date: Sun, 6 Oct 2024 22:50:28 +0330 Subject: [PATCH 08/14] Update show-user-uri --- core/cli.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/core/cli.py b/core/cli.py index 3c5f9ac..408740c 100644 --- a/core/cli.py +++ b/core/cli.py @@ -208,7 +208,8 @@ def remove_user(username: str): @click.option('--ipv', '-ip', type=click.IntRange(4, 6), default=4, help='IP version (4 or 6)') @click.option('--all', '-a', is_flag=True, help='Show both IPv4 and IPv6 URIs and generate QR codes for both if requested') @click.option('--singbox', '-s', is_flag=True, help='Generate Singbox sublink if Singbox service is active') -def show_user_uri(username: str, qrcode: bool, ipv: int, all: bool, singbox: bool): +@click.option('--normalsub', '-n', is_flag=True, help='Generate Normal sublink if normalsub service is active') +def show_user_uri(username: str, qrcode: bool, ipv: int, all: bool, singbox: bool, normalsub: bool): command_args = ['bash', Command.SHOW_USER_URI.value, '-u', username] if qrcode: command_args.append('-qr') @@ -218,6 +219,8 @@ def show_user_uri(username: str, qrcode: bool, ipv: int, all: bool, singbox: boo command_args.extend(['-ip', str(ipv)]) if singbox: command_args.append('-s') + if normalsub: + command_args.append('-n') run_cmd(command_args) From edc922a5e92714a2efe69de24d70260241493d52 Mon Sep 17 00:00:00 2001 From: Whispering Wind <151555003+ReturnFI@users.noreply.github.com> Date: Sun, 6 Oct 2024 22:51:03 +0330 Subject: [PATCH 09/14] Added NORMALSUB_ENV --- core/scripts/path.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/core/scripts/path.sh b/core/scripts/path.sh index aa3d978..faec9f0 100644 --- a/core/scripts/path.sh +++ b/core/scripts/path.sh @@ -5,4 +5,5 @@ CONFIG_FILE="/etc/hysteria/config.json" CONFIG_ENV="/etc/hysteria/.configs.env" TELEGRAM_ENV="/etc/hysteria/core/scripts/telegrambot/.env" SINGBOX_ENV="/etc/hysteria/core/scripts/singbox/.env" +NORMALSUB_ENV="/etc/hysteria/core/scripts/normalsub/.env" ONLINE_API_URL="http://127.0.0.1:25413/online" From 948c3f724abe6ddbf19cb92772d37f14da1674af Mon Sep 17 00:00:00 2001 From: Whispering Wind <151555003+ReturnFI@users.noreply.github.com> Date: Sun, 6 Oct 2024 22:51:56 +0330 Subject: [PATCH 10/14] Clone Dev --- upgrade.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/upgrade.sh b/upgrade.sh index 86546ef..c13bc4d 100644 --- a/upgrade.sh +++ b/upgrade.sh @@ -29,7 +29,7 @@ echo "Removing /etc/hysteria directory" rm -rf /etc/hysteria/ echo "Cloning Hysteria2 repository" -git clone https://github.com/ReturnFI/Hysteria2 /etc/hysteria +git clone -b Dev https://github.com/ReturnFI/Hysteria2 /etc/hysteria echo "Downloading geosite.dat and geoip.dat" wget -O /etc/hysteria/geosite.dat https://raw.githubusercontent.com/Chocolate4U/Iran-v2ray-rules/release/geosite.dat >/dev/null 2>&1 From 79626c51e8bfc0f336c0f51d2e704c88390dabba Mon Sep 17 00:00:00 2001 From: Whispering Wind <151555003+ReturnFI@users.noreply.github.com> Date: Sun, 6 Oct 2024 23:44:44 +0330 Subject: [PATCH 11/14] Update Telegram bot Added Normal SUB --- core/scripts/telegrambot/tbot.py | 36 +++++++++++++++++++++++++------- 1 file changed, 29 insertions(+), 7 deletions(-) diff --git a/core/scripts/telegrambot/tbot.py b/core/scripts/telegrambot/tbot.py index f6b66be..4c0899a 100644 --- a/core/scripts/telegrambot/tbot.py +++ b/core/scripts/telegrambot/tbot.py @@ -90,7 +90,7 @@ def process_add_user_step3(message, username, traffic_limit): lower_username = username.lower() command = f"python3 {CLI_PATH} add-user -u {username} -t {traffic_limit} -e {expiration_days}" result = run_cli_command(command) - + bot.send_chat_action(message.chat.id, 'typing') qr_command = f"python3 {CLI_PATH} show-user-uri -u {lower_username} -ip 4" qr_result = run_cli_command(qr_command).replace("IPv4:\n", "").strip() @@ -115,6 +115,7 @@ def show_user(message): def process_show_user(message): username = message.text.strip().lower() + bot.send_chat_action(message.chat.id, 'typing') command = f"python3 {CLI_PATH} list-users" result = run_cli_command(command) @@ -167,17 +168,31 @@ def process_show_user(message): f"{traffic_message}" ) - combined_command = f"python3 {CLI_PATH} show-user-uri -u {actual_username} -ip 4 -s" + combined_command = f"python3 {CLI_PATH} show-user-uri -u {actual_username} -ip 4 -s -n" combined_result = run_cli_command(combined_command) if "Error" in combined_result or "Invalid" in combined_result: bot.reply_to(message, combined_result) return - result_lines = combined_result.split('\n') - uri_v4 = result_lines[1].strip() + result_lines = combined_result.strip().split('\n') + + uri_v4 = "" + singbox_sublink = "" + normal_sub_sublink = "" - singbox_sublink = result_lines[-1].strip() if "https://" in result_lines[-1] else None + for line in result_lines: + line = line.strip() + if line.startswith("hy2://"): + uri_v4 = line + elif line.startswith("Singbox Sublink:"): + singbox_sublink = result_lines[result_lines.index(line) + 1].strip() + elif line.startswith("Normal-SUB Sublink:"): + normal_sub_sublink = result_lines[result_lines.index(line) + 1].strip() + + if not uri_v4: + bot.reply_to(message, "No valid URI found.") + return qr_v4 = qrcode.make(uri_v4) bio_v4 = io.BytesIO() @@ -196,7 +211,9 @@ def process_show_user(message): caption = f"{formatted_details}\n\n**IPv4 URI:**\n\n`{uri_v4}`" if singbox_sublink: - caption += f"\n\n\n**SingBox SUB:**\n{singbox_sublink}" + caption += f"\n\n**SingBox SUB:**\n{singbox_sublink}" + if normal_sub_sublink: + caption += f"\n\n**Normal SUB:**\n{normal_sub_sublink}" bot.send_photo( message.chat.id, @@ -206,10 +223,12 @@ def process_show_user(message): parse_mode="Markdown" ) + @bot.message_handler(func=lambda message: is_admin(message.from_user.id) and message.text == 'Server Info') def server_info(message): command = f"python3 {CLI_PATH} server-info" result = run_cli_command(command) + bot.send_chat_action(message.chat.id, 'typing') bot.reply_to(message, result) @bot.callback_query_handler(func=lambda call: call.data.startswith('edit_') or call.data.startswith('renew_') or call.data.startswith('block_') or call.data.startswith('reset_') or call.data.startswith('ipv6_')) @@ -306,13 +325,16 @@ def process_delete_user(message): @bot.message_handler(func=lambda message: is_admin(message.from_user.id) and message.text == 'Backup Server') def backup_server(message): bot.reply_to(message, "Starting backup. This may take a few moments...") + bot.send_chat_action(message.chat.id, 'typing') backup_command = f"python3 {CLI_PATH} backup-hysteria" result = run_cli_command(backup_command) if "Error" in result: bot.reply_to(message, f"Backup failed: {result}") - return + else: + bot.reply_to(message, "Backup completed successfully!") + try: files = [f for f in os.listdir(BACKUP_DIRECTORY) if f.endswith('.zip')] From 01f8cde597af23f3cb3fd8e275a5616f9b2646c1 Mon Sep 17 00:00:00 2001 From: Whispering Wind <151555003+ReturnFI@users.noreply.github.com> Date: Mon, 7 Oct 2024 00:15:51 +0330 Subject: [PATCH 12/14] Clone Main --- install.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/install.sh b/install.sh index 50e07fe..f95bacf 100644 --- a/install.sh +++ b/install.sh @@ -53,7 +53,7 @@ else echo "All required packages are already installed." fi -git clone -b Dev https://github.com/ReturnFI/Hysteria2 /etc/hysteria +git clone https://github.com/ReturnFI/Hysteria2 /etc/hysteria cd /etc/hysteria python3 -m venv hysteria2_venv From 6fd726e9e761198fac442f3d1d8fcea5f8648a9e Mon Sep 17 00:00:00 2001 From: Whispering Wind <151555003+ReturnFI@users.noreply.github.com> Date: Mon, 7 Oct 2024 00:16:15 +0330 Subject: [PATCH 13/14] Clone Main --- upgrade.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/upgrade.sh b/upgrade.sh index c13bc4d..86546ef 100644 --- a/upgrade.sh +++ b/upgrade.sh @@ -29,7 +29,7 @@ echo "Removing /etc/hysteria directory" rm -rf /etc/hysteria/ echo "Cloning Hysteria2 repository" -git clone -b Dev https://github.com/ReturnFI/Hysteria2 /etc/hysteria +git clone https://github.com/ReturnFI/Hysteria2 /etc/hysteria echo "Downloading geosite.dat and geoip.dat" wget -O /etc/hysteria/geosite.dat https://raw.githubusercontent.com/Chocolate4U/Iran-v2ray-rules/release/geosite.dat >/dev/null 2>&1 From 6bd583837afb1bd65c0c963f74e52c7e7ce6563a Mon Sep 17 00:00:00 2001 From: Whispering Wind <151555003+ReturnFI@users.noreply.github.com> Date: Mon, 7 Oct 2024 00:16:26 +0330 Subject: [PATCH 14/14] Update VERSION --- VERSION | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/VERSION b/VERSION index 53a75d6..b003284 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -0.2.6 +0.2.7