Host configuration
This commit is contained in:
parent
48282a63d4
commit
3cf12467a7
|
|
@ -774,25 +774,26 @@ _server_stop_event = None
|
||||||
|
|
||||||
|
|
||||||
async def _run(port: int, dc_opt: Dict[int, Optional[str]],
|
async def _run(port: int, dc_opt: Dict[int, Optional[str]],
|
||||||
stop_event: Optional[asyncio.Event] = None):
|
stop_event: Optional[asyncio.Event] = None,
|
||||||
|
host: str = '127.0.0.1'):
|
||||||
global _dc_opt, _server_instance, _server_stop_event
|
global _dc_opt, _server_instance, _server_stop_event
|
||||||
_dc_opt = dc_opt
|
_dc_opt = dc_opt
|
||||||
_server_stop_event = stop_event
|
_server_stop_event = stop_event
|
||||||
|
|
||||||
server = await asyncio.start_server(
|
server = await asyncio.start_server(
|
||||||
_handle_client, '127.0.0.1', port)
|
_handle_client, host, port)
|
||||||
_server_instance = server
|
_server_instance = server
|
||||||
|
|
||||||
log.info("=" * 60)
|
log.info("=" * 60)
|
||||||
log.info(" Telegram WS Bridge Proxy")
|
log.info(" Telegram WS Bridge Proxy")
|
||||||
log.info(" Listening on 127.0.0.1:%d", port)
|
log.info(" Listening on %s:%d", host, port)
|
||||||
log.info(" Target DC IPs:")
|
log.info(" Target DC IPs:")
|
||||||
for dc in dc_opt.keys():
|
for dc in dc_opt.keys():
|
||||||
ip = dc_opt.get(dc)
|
ip = dc_opt.get(dc)
|
||||||
log.info(" DC%d: %s", dc, ip)
|
log.info(" DC%d: %s", dc, ip)
|
||||||
log.info("=" * 60)
|
log.info("=" * 60)
|
||||||
log.info(" Configure Telegram Desktop:")
|
log.info(" Configure Telegram Desktop:")
|
||||||
log.info(" SOCKS5 proxy -> 127.0.0.1:%d (no user/pass)", port)
|
log.info(" SOCKS5 proxy -> %s:%d (no user/pass)", host, port)
|
||||||
log.info("=" * 60)
|
log.info("=" * 60)
|
||||||
|
|
||||||
async def log_stats():
|
async def log_stats():
|
||||||
|
|
@ -844,9 +845,10 @@ def parse_dc_ip_list(dc_ip_list: List[str]) -> Dict[int, str]:
|
||||||
|
|
||||||
|
|
||||||
def run_proxy(port: int, dc_opt: Dict[int, str],
|
def run_proxy(port: int, dc_opt: Dict[int, str],
|
||||||
stop_event: Optional[asyncio.Event] = None):
|
stop_event: Optional[asyncio.Event] = None,
|
||||||
|
host: str = '127.0.0.1'):
|
||||||
"""Run the proxy (blocking). Can be called from threads."""
|
"""Run the proxy (blocking). Can be called from threads."""
|
||||||
asyncio.run(_run(port, dc_opt, stop_event))
|
asyncio.run(_run(port, dc_opt, stop_event, host))
|
||||||
|
|
||||||
|
|
||||||
def main():
|
def main():
|
||||||
|
|
@ -854,6 +856,8 @@ def main():
|
||||||
description='Telegram Desktop WebSocket Bridge Proxy')
|
description='Telegram Desktop WebSocket Bridge Proxy')
|
||||||
ap.add_argument('--port', type=int, default=DEFAULT_PORT,
|
ap.add_argument('--port', type=int, default=DEFAULT_PORT,
|
||||||
help=f'Listen port (default {DEFAULT_PORT})')
|
help=f'Listen port (default {DEFAULT_PORT})')
|
||||||
|
ap.add_argument('--host', type=str, default='127.0.0.1',
|
||||||
|
help='Listen host (default 127.0.0.1)')
|
||||||
ap.add_argument('--dc-ip', metavar='DC:IP', action='append',
|
ap.add_argument('--dc-ip', metavar='DC:IP', action='append',
|
||||||
default=['2:149.154.167.220', '4:149.154.167.220'],
|
default=['2:149.154.167.220', '4:149.154.167.220'],
|
||||||
help='Target IP for a DC, e.g. --dc-ip 1:149.154.175.205'
|
help='Target IP for a DC, e.g. --dc-ip 1:149.154.175.205'
|
||||||
|
|
@ -875,7 +879,7 @@ def main():
|
||||||
)
|
)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
asyncio.run(_run(args.port, dc_opt))
|
asyncio.run(_run(args.port, dc_opt, host=args.host))
|
||||||
except KeyboardInterrupt:
|
except KeyboardInterrupt:
|
||||||
log.info("Shutting down. Final stats: %s", _stats.summary())
|
log.info("Shutting down. Final stats: %s", _stats.summary())
|
||||||
|
|
||||||
|
|
|
||||||
46
windows.py
46
windows.py
|
|
@ -29,6 +29,7 @@ FIRST_RUN_MARKER = APP_DIR / ".first_run_done"
|
||||||
|
|
||||||
DEFAULT_CONFIG = {
|
DEFAULT_CONFIG = {
|
||||||
"port": 1080,
|
"port": 1080,
|
||||||
|
"host": "127.0.0.1",
|
||||||
"dc_ip": ["2:149.154.167.220", "4:149.154.167.220"],
|
"dc_ip": ["2:149.154.167.220", "4:149.154.167.220"],
|
||||||
"verbose": False,
|
"verbose": False,
|
||||||
}
|
}
|
||||||
|
|
@ -145,7 +146,8 @@ def _load_icon():
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def _run_proxy_thread(port: int, dc_opt: Dict[int, str], verbose: bool):
|
def _run_proxy_thread(port: int, dc_opt: Dict[int, str], verbose: bool,
|
||||||
|
host: str = '127.0.0.1'):
|
||||||
global _async_stop
|
global _async_stop
|
||||||
loop = _asyncio.new_event_loop()
|
loop = _asyncio.new_event_loop()
|
||||||
_asyncio.set_event_loop(loop)
|
_asyncio.set_event_loop(loop)
|
||||||
|
|
@ -154,7 +156,7 @@ def _run_proxy_thread(port: int, dc_opt: Dict[int, str], verbose: bool):
|
||||||
|
|
||||||
try:
|
try:
|
||||||
loop.run_until_complete(
|
loop.run_until_complete(
|
||||||
tg_ws_proxy._run(port, dc_opt, stop_event=stop_ev))
|
tg_ws_proxy._run(port, dc_opt, stop_event=stop_ev, host=host))
|
||||||
except Exception as exc:
|
except Exception as exc:
|
||||||
log.error("Proxy thread crashed: %s", exc)
|
log.error("Proxy thread crashed: %s", exc)
|
||||||
if "10048" in str(exc) or "Address already in use" in str(exc):
|
if "10048" in str(exc) or "Address already in use" in str(exc):
|
||||||
|
|
@ -172,6 +174,7 @@ def start_proxy():
|
||||||
|
|
||||||
cfg = _config
|
cfg = _config
|
||||||
port = cfg.get("port", DEFAULT_CONFIG["port"])
|
port = cfg.get("port", DEFAULT_CONFIG["port"])
|
||||||
|
host = cfg.get("host", DEFAULT_CONFIG["host"])
|
||||||
dc_ip_list = cfg.get("dc_ip", DEFAULT_CONFIG["dc_ip"])
|
dc_ip_list = cfg.get("dc_ip", DEFAULT_CONFIG["dc_ip"])
|
||||||
verbose = cfg.get("verbose", False)
|
verbose = cfg.get("verbose", False)
|
||||||
|
|
||||||
|
|
@ -182,10 +185,10 @@ def start_proxy():
|
||||||
_show_error(f"Ошибка конфигурации:\n{e}")
|
_show_error(f"Ошибка конфигурации:\n{e}")
|
||||||
return
|
return
|
||||||
|
|
||||||
log.info("Starting proxy on port %d ...", port)
|
log.info("Starting proxy on %s:%d ...", host, port)
|
||||||
_proxy_thread = threading.Thread(
|
_proxy_thread = threading.Thread(
|
||||||
target=_run_proxy_thread,
|
target=_run_proxy_thread,
|
||||||
args=(port, dc_opt, verbose),
|
args=(port, dc_opt, verbose, host),
|
||||||
daemon=True, name="proxy")
|
daemon=True, name="proxy")
|
||||||
_proxy_thread.start()
|
_proxy_thread.start()
|
||||||
|
|
||||||
|
|
@ -217,8 +220,9 @@ def _show_info(text: str, title: str = "TG WS Proxy"):
|
||||||
|
|
||||||
|
|
||||||
def _on_open_in_telegram(icon=None, item=None):
|
def _on_open_in_telegram(icon=None, item=None):
|
||||||
|
host = _config.get("host", DEFAULT_CONFIG["host"])
|
||||||
port = _config.get("port", DEFAULT_CONFIG["port"])
|
port = _config.get("port", DEFAULT_CONFIG["port"])
|
||||||
url = f"tg://socks?server=127.0.0.1&port={port}"
|
url = f"tg://socks?server={host}&port={port}"
|
||||||
log.info("Opening %s", url)
|
log.info("Opening %s", url)
|
||||||
try:
|
try:
|
||||||
result = webbrowser.open(url)
|
result = webbrowser.open(url)
|
||||||
|
|
@ -269,7 +273,7 @@ def _edit_config_dialog():
|
||||||
TEXT_SECONDARY = "#707579"
|
TEXT_SECONDARY = "#707579"
|
||||||
FONT_FAMILY = "Segoe UI"
|
FONT_FAMILY = "Segoe UI"
|
||||||
|
|
||||||
w, h = 420, 400
|
w, h = 420, 480
|
||||||
sw = root.winfo_screenwidth()
|
sw = root.winfo_screenwidth()
|
||||||
sh = root.winfo_screenheight()
|
sh = root.winfo_screenheight()
|
||||||
root.geometry(f"{w}x{h}+{(sw-w)//2}+{(sh-h)//2}")
|
root.geometry(f"{w}x{h}+{(sw-w)//2}+{(sh-h)//2}")
|
||||||
|
|
@ -278,6 +282,17 @@ def _edit_config_dialog():
|
||||||
frame = ctk.CTkFrame(root, fg_color=BG, corner_radius=0)
|
frame = ctk.CTkFrame(root, fg_color=BG, corner_radius=0)
|
||||||
frame.pack(fill="both", expand=True, padx=24, pady=20)
|
frame.pack(fill="both", expand=True, padx=24, pady=20)
|
||||||
|
|
||||||
|
# Host
|
||||||
|
ctk.CTkLabel(frame, text="IP-адрес прокси",
|
||||||
|
font=(FONT_FAMILY, 13), text_color=TEXT_PRIMARY,
|
||||||
|
anchor="w").pack(anchor="w", pady=(0, 4))
|
||||||
|
host_var = ctk.StringVar(value=cfg.get("host", "127.0.0.1"))
|
||||||
|
host_entry = ctk.CTkEntry(frame, textvariable=host_var, width=200, height=36,
|
||||||
|
font=(FONT_FAMILY, 13), corner_radius=10,
|
||||||
|
fg_color=FIELD_BG, border_color=FIELD_BORDER,
|
||||||
|
border_width=1, text_color=TEXT_PRIMARY)
|
||||||
|
host_entry.pack(anchor="w", pady=(0, 12))
|
||||||
|
|
||||||
# Port
|
# Port
|
||||||
ctk.CTkLabel(frame, text="Порт прокси",
|
ctk.CTkLabel(frame, text="Порт прокси",
|
||||||
font=(FONT_FAMILY, 13), text_color=TEXT_PRIMARY,
|
font=(FONT_FAMILY, 13), text_color=TEXT_PRIMARY,
|
||||||
|
|
@ -315,6 +330,14 @@ def _edit_config_dialog():
|
||||||
anchor="w").pack(anchor="w", pady=(0, 16))
|
anchor="w").pack(anchor="w", pady=(0, 16))
|
||||||
|
|
||||||
def on_save():
|
def on_save():
|
||||||
|
import socket as _sock
|
||||||
|
host_val = host_var.get().strip()
|
||||||
|
try:
|
||||||
|
_sock.inet_aton(host_val)
|
||||||
|
except OSError:
|
||||||
|
_show_error("Некорректный IP-адрес.")
|
||||||
|
return
|
||||||
|
|
||||||
try:
|
try:
|
||||||
port_val = int(port_var.get().strip())
|
port_val = int(port_var.get().strip())
|
||||||
if not (1 <= port_val <= 65535):
|
if not (1 <= port_val <= 65535):
|
||||||
|
|
@ -332,6 +355,7 @@ def _edit_config_dialog():
|
||||||
return
|
return
|
||||||
|
|
||||||
new_cfg = {
|
new_cfg = {
|
||||||
|
"host": host_val,
|
||||||
"port": port_val,
|
"port": port_val,
|
||||||
"dc_ip": lines,
|
"dc_ip": lines,
|
||||||
"verbose": verbose_var.get(),
|
"verbose": verbose_var.get(),
|
||||||
|
|
@ -340,6 +364,8 @@ def _edit_config_dialog():
|
||||||
_config.update(new_cfg)
|
_config.update(new_cfg)
|
||||||
log.info("Config saved: %s", new_cfg)
|
log.info("Config saved: %s", new_cfg)
|
||||||
|
|
||||||
|
_tray_icon.menu = _build_menu()
|
||||||
|
|
||||||
from tkinter import messagebox
|
from tkinter import messagebox
|
||||||
if messagebox.askyesno("Перезапустить?",
|
if messagebox.askyesno("Перезапустить?",
|
||||||
"Настройки сохранены.\n\n"
|
"Настройки сохранены.\n\n"
|
||||||
|
|
@ -401,8 +427,9 @@ def _show_first_run():
|
||||||
if FIRST_RUN_MARKER.exists():
|
if FIRST_RUN_MARKER.exists():
|
||||||
return
|
return
|
||||||
|
|
||||||
|
host = _config.get("host", DEFAULT_CONFIG["host"])
|
||||||
port = _config.get("port", DEFAULT_CONFIG["port"])
|
port = _config.get("port", DEFAULT_CONFIG["port"])
|
||||||
tg_url = f"tg://socks?server=127.0.0.1&port={port}"
|
tg_url = f"tg://socks?server={host}&port={port}"
|
||||||
|
|
||||||
if ctk is None:
|
if ctk is None:
|
||||||
FIRST_RUN_MARKER.touch()
|
FIRST_RUN_MARKER.touch()
|
||||||
|
|
@ -454,7 +481,7 @@ def _show_first_run():
|
||||||
(f" Или ссылка: {tg_url}", False),
|
(f" Или ссылка: {tg_url}", False),
|
||||||
("\n Вручную:", True),
|
("\n Вручную:", True),
|
||||||
(" Настройки → Продвинутые → Тип подключения → Прокси", False),
|
(" Настройки → Продвинутые → Тип подключения → Прокси", False),
|
||||||
(f" SOCKS5 → 127.0.0.1 : {port} (без логина/пароля)", False),
|
(f" SOCKS5 → {host} : {port} (без логина/пароля)", False),
|
||||||
]
|
]
|
||||||
|
|
||||||
for text, bold in sections:
|
for text, bold in sections:
|
||||||
|
|
@ -500,10 +527,11 @@ def _show_first_run():
|
||||||
def _build_menu():
|
def _build_menu():
|
||||||
if pystray is None:
|
if pystray is None:
|
||||||
return None
|
return None
|
||||||
|
host = _config.get("host", DEFAULT_CONFIG["host"])
|
||||||
port = _config.get("port", DEFAULT_CONFIG["port"])
|
port = _config.get("port", DEFAULT_CONFIG["port"])
|
||||||
return pystray.Menu(
|
return pystray.Menu(
|
||||||
pystray.MenuItem(
|
pystray.MenuItem(
|
||||||
f"Открыть в Telegram (:{port})",
|
f"Открыть в Telegram ({host}:{port})",
|
||||||
_on_open_in_telegram,
|
_on_open_in_telegram,
|
||||||
default=True),
|
default=True),
|
||||||
pystray.Menu.SEPARATOR,
|
pystray.Menu.SEPARATOR,
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue