Merge pull request #74 from ReturnFI/beta

Added New Features
This commit is contained in:
Whispering Wind
2025-01-10 21:54:27 +03:30
committed by GitHub
8 changed files with 224 additions and 48 deletions

View File

@ -1,2 +1,6 @@
1. Fix: Changed geo category
2. Reject(malware, phishing, cryptominers)
3. Add: GeoCountry(Iran, China, and Russia)
4. Add: Geo Update flag --country option(cli)
5. Add: CPU monitoring module(Telegram-Bot)
6. Add: Search users by the `blocked` status(Telegram-Bot)

View File

@ -289,10 +289,14 @@ def ip_address(edit, ipv4, ipv6):
run_cmd(['bash', Command.IP_ADD.value, 'add'])
@cli.command('update-geo')
def cli_update_geo():
@click.option('--country', '-c',
type=click.Choice(['iran', 'china', 'russia'], case_sensitive=False),
default='iran',
help='Select country for geo files (default: iran)')
def cli_update_geo(country):
script_path = Command.UPDATE_GEO.value
try:
subprocess.run(['python3', script_path], check=True)
subprocess.run(['python3', script_path, country.lower()], check=True)
except subprocess.CalledProcessError as e:
print(f"Failed to update geo files: {e}")
except FileNotFoundError:

View File

@ -1,46 +1,70 @@
#!/usr/bin/env python3
import os
import subprocess
from enum import Enum
import sys
import requests
class GeoCountry(Enum):
IRAN = {
'geosite': 'https://github.com/chocolate4u/Iran-v2ray-rules/releases/latest/download/geosite.dat',
'geoip': 'https://github.com/chocolate4u/Iran-v2ray-rules/releases/latest/download/geoip.dat'
}
CHINA = {
'geosite': 'https://github.com/Loyalsoldier/v2ray-rules-dat/releases/latest/download/geosite.dat',
'geoip': 'https://github.com/Loyalsoldier/v2ray-rules-dat/releases/latest/download/geoip.dat'
}
RUSSIA = {
'geosite': 'https://github.com/runetfreedom/russia-v2ray-rules-dat/releases/latest/download/geosite.dat',
'geoip': 'https://github.com/runetfreedom/russia-v2ray-rules-dat/releases/latest/download/geoip.dat'
}
GEOSITE_PATH = "/etc/hysteria/geosite.dat"
GEOIP_PATH = "/etc/hysteria/geoip.dat"
GEOSITE_URL = "https://raw.githubusercontent.com/Chocolate4U/Iran-v2ray-rules/release/geosite.dat"
GEOIP_URL = "https://raw.githubusercontent.com/Chocolate4U/Iran-v2ray-rules/release/geoip.dat"
def remove_file(file_path):
if os.path.exists(file_path):
os.remove(file_path)
print(f"Removed existing file: {file_path}")
def download_file(url, destination):
try:
subprocess.run(
["wget", "-O", destination, url],
stdout=subprocess.DEVNULL,
stderr=subprocess.DEVNULL,
check=True
)
print(f"Downloaded {url} to {destination}")
except subprocess.CalledProcessError:
print(f"Failed to download {url}")
if os.path.exists(file_path):
os.remove(file_path)
print(f"Removed existing file: {file_path}")
except Exception as e:
print(f"Error removing file {file_path}: {e}")
def update_geo_files():
def download_file(url, destination, chunk_size=8192):
try:
print("Starting geo files update...")
destination_dir = os.path.dirname(destination)
if destination_dir and not os.path.exists(destination_dir):
os.makedirs(destination_dir)
response = requests.get(url, stream=True)
response.raise_for_status()
with open(destination, "wb") as file:
for chunk in response.iter_content(chunk_size=chunk_size):
file.write(chunk)
print(f"File successfully downloaded to: {destination}")
except requests.exceptions.RequestException as e:
print(f"Error: Failed to download the file from '{url}'.\n{e}")
except IOError as e:
print(f"Error: Failed to save the file to '{destination}'.\n{e}")
def update_geo_files(country='iran'):
try:
print(f"Starting geo files update for {country.upper()}...")
country_enum = GeoCountry[country.upper()]
remove_file(GEOSITE_PATH)
remove_file(GEOIP_PATH)
download_file(GEOSITE_URL, GEOSITE_PATH)
download_file(GEOIP_URL, GEOIP_PATH)
download_file(country_enum.value['geosite'], GEOSITE_PATH)
download_file(country_enum.value['geoip'], GEOIP_PATH)
print("Geo files update completed successfully.")
except KeyError:
print(f"Invalid country selection. Available options: {', '.join([c.name.lower() for c in GeoCountry])}")
except Exception as e:
print(f"An error occurred during the update process: {e}")
if __name__ == "__main__":
update_geo_files()
country = sys.argv[1] if len(sys.argv) > 1 else 'iran'
update_geo_files(country)

View File

@ -7,6 +7,9 @@ from utils.deleteuser import *
from utils.edituser import *
from utils.search import *
from utils.serverinfo import *
from utils.cpu import *
import threading
import time
@bot.message_handler(commands=['start'])
def send_welcome(message):
@ -16,5 +19,12 @@ def send_welcome(message):
else:
bot.reply_to(message, "Unauthorized access. You do not have permission to use this bot.")
def monitoring_thread():
while True:
monitor_system_resources()
time.sleep(60)
if __name__ == '__main__':
monitor_thread = threading.Thread(target=monitoring_thread, daemon=True)
monitor_thread.start()
bot.polling(none_stop=True)

View File

@ -0,0 +1,64 @@
import psutil
import time
from utils.command import *
def get_system_usage():
cpu_usage = psutil.cpu_percent(interval=1)
ram = psutil.virtual_memory()
ram_usage = ram.percent
return cpu_usage, ram_usage
def format_alert_message(cpu_usage, ram_usage):
return (
"🚨ALERT🚨\n"
"High CPU and RAM usage detected ⚠️\n\n"
f"📈 CPU: {cpu_usage:.1f}%\n"
f"📋 RAM: {ram_usage:.1f}%"
)
def monitor_system_resources():
# Thresholds
CPU_THRESHOLD = 90.0
RAM_THRESHOLD = 90.0
CONFIRMATION_DELAY = 60 # seconds
try:
cpu_usage, ram_usage = get_system_usage()
if cpu_usage > CPU_THRESHOLD and ram_usage > RAM_THRESHOLD:
time.sleep(CONFIRMATION_DELAY)
cpu_usage, ram_usage = get_system_usage()
if cpu_usage > CPU_THRESHOLD and ram_usage > RAM_THRESHOLD:
alert_message = format_alert_message(cpu_usage, ram_usage)
for admin_id in ADMIN_USER_IDS:
try:
bot.send_message(admin_id, alert_message)
except Exception as e:
print(f"Failed to send alert to admin {admin_id}: {str(e)}")
return True
except Exception as e:
print(f"Error monitoring system resources: {str(e)}")
return False
@bot.message_handler(commands=['system'])
def check_system(message):
if not is_admin(message.from_user.id):
bot.reply_to(message, "Unauthorized access. You do not have permission to use this command.")
return
try:
cpu_usage, ram_usage = get_system_usage()
response = (
"📊 System Resource Usage 📊\n\n"
f"📈 CPU Usage: {cpu_usage:.1f}%\n"
f"📋 RAM Usage: {ram_usage:.1f}%"
)
bot.reply_to(message, response)
except Exception as e:
bot.reply_to(message, f"Error checking system resources: {str(e)}")

View File

@ -1,7 +1,6 @@
from telebot import types
from utils.command import *
@bot.inline_handler(lambda query: is_admin(query.from_user.id))
def handle_inline_query(query):
command = f"python3 {CLI_PATH} list-users"
@ -14,21 +13,40 @@ def handle_inline_query(query):
query_text = query.query.lower()
results = []
for username, details in users.items():
if query_text in username.lower():
title = f"{username}"
description = f"Traffic Limit: {details['max_download_bytes'] / (1024 ** 3):.2f} GB, Expiration Days: {details['expiration_days']}"
results.append(types.InlineQueryResultArticle(
id=username,
title=title,
description=description,
input_message_content=types.InputTextMessageContent(
message_text=f"Name: {username}\n"
f"Traffic limit: {details['max_download_bytes'] / (1024 ** 3):.2f} GB\n"
f"Days: {details['expiration_days']}\n"
f"Account Creation: {details['account_creation_date']}\n"
f"Blocked: {details['blocked']}"
)
))
if query_text == "block":
for username, details in users.items():
if details.get('blocked', False):
title = f"{username} (Blocked)"
description = f"Traffic Limit: {details['max_download_bytes'] / (1024 ** 3):.2f} GB, Expiration Days: {details['expiration_days']}"
results.append(types.InlineQueryResultArticle(
id=username,
title=title,
description=description,
input_message_content=types.InputTextMessageContent(
message_text=f"Name: {username}\n"
f"Traffic limit: {details['max_download_bytes'] / (1024 ** 3):.2f} GB\n"
f"Days: {details['expiration_days']}\n"
f"Account Creation: {details['account_creation_date']}\n"
f"Blocked: {details['blocked']}"
)
))
else:
for username, details in users.items():
if query_text in username.lower():
title = f"{username}"
description = f"Traffic Limit: {details['max_download_bytes'] / (1024 ** 3):.2f} GB, Expiration Days: {details['expiration_days']}"
results.append(types.InlineQueryResultArticle(
id=username,
title=title,
description=description,
input_message_content=types.InputTextMessageContent(
message_text=f"Name: {username}\n"
f"Traffic limit: {details['max_download_bytes'] / (1024 ** 3):.2f} GB\n"
f"Days: {details['expiration_days']}\n"
f"Account Creation: {details['account_creation_date']}\n"
f"Blocked: {details['blocked']}"
)
))
bot.answer_inline_query(query.id, results, cache_time=0)

53
menu.sh
View File

@ -589,6 +589,57 @@ obfs_handler() {
done
}
geo_update_handler() {
echo "Configure Geo Update Options:"
echo "1. Update Iran Geo Files"
echo "2. Update China Geo Files"
echo "3. Update Russia Geo Files"
echo "4. Check Current Geo Files"
echo "0. Cancel"
read -p "Select an option: " option
case $option in
1)
echo "Updating Iran Geo Files..."
python3 $CLI_PATH update-geo --country iran
;;
2)
echo "Updating China Geo Files..."
python3 $CLI_PATH update-geo --country china
;;
3)
echo "Updating Russia Geo Files..."
python3 $CLI_PATH update-geo --country russia
;;
4)
echo "Current Geo Files Information:"
echo "--------------------------"
if [ -f "/etc/hysteria/geosite.dat" ]; then
echo "GeoSite File:"
ls -lh /etc/hysteria/geosite.dat
echo "Last modified: $(stat -c %y /etc/hysteria/geosite.dat)"
else
echo "GeoSite file not found!"
fi
echo
if [ -f "/etc/hysteria/geoip.dat" ]; then
echo "GeoIP File:"
ls -lh /etc/hysteria/geoip.dat
echo "Last modified: $(stat -c %y /etc/hysteria/geoip.dat)"
else
echo "GeoIP file not found!"
fi
;;
0)
echo "Geo update configuration canceled."
;;
*)
echo "Invalid option. Please try again."
;;
esac
}
# Function to display the main menu
display_main_menu() {
clear
@ -737,7 +788,7 @@ advance_menu() {
9) hysteria2_change_sni_handler ;;
10) obfs_handler ;;
11) edit_ips ;;
12) python3 $CLI_PATH update-geo ;;
12) geo_update_handler ;;
13) python3 $CLI_PATH restart-hysteria2 ;;
14) python3 $CLI_PATH update-hysteria2 ;;
15) python3 $CLI_PATH uninstall-hysteria2 ;;

View File

@ -4,3 +4,4 @@ python-dotenv==1.0.1
requests==2.32.3
aiohttp==3.10.5
click==8.1.7
psutil==6.1.1