新增功能:
- 代理转发端口从内置 config.json 移到设置弹窗:可修改并持久化到用户数据目录 settings.json(下次开启代理生效) - 取值链:本地设置 > 内置 config.json > 默认 1080;非法输入(非数字/超出 1-65535)拒绝保存 - 代理运行中锁定端口修改(输入框与保存按钮禁用,提示先关闭代理)
This commit is contained in:
+107
-7
@@ -539,9 +539,60 @@ def _user_path(name: str):
|
||||
return p
|
||||
return _data_path(name)
|
||||
|
||||
# ── 本地设置(settings.json,用户数据目录,明文) ─────────────
|
||||
|
||||
def _settings_path():
|
||||
return _USER_DIR / "settings.json"
|
||||
|
||||
def _settings_load():
|
||||
"""读取本地设置;缺失或损坏返回空字典。"""
|
||||
try:
|
||||
import json
|
||||
f = _settings_path()
|
||||
if not f.is_file():
|
||||
return {}
|
||||
data = json.loads(f.read_text("utf-8"))
|
||||
return data if isinstance(data, dict) else {}
|
||||
except Exception:
|
||||
return {}
|
||||
|
||||
def _settings_save(data):
|
||||
"""本地设置原子写回。"""
|
||||
import json
|
||||
_USER_DIR.mkdir(parents=True, exist_ok=True)
|
||||
tmp = _settings_path().with_suffix(".json.tmp")
|
||||
tmp.write_text(json.dumps(data, ensure_ascii=False, indent=2) + "\n", "utf-8")
|
||||
os.replace(tmp, _settings_path())
|
||||
|
||||
def _parse_port(text):
|
||||
"""解析端口号;非法(非数字或超出 1-65535)返回 None。"""
|
||||
try:
|
||||
port = int(str(text).strip())
|
||||
except (TypeError, ValueError):
|
||||
return None
|
||||
return port if 1 <= port <= 65535 else None
|
||||
|
||||
def _port_val():
|
||||
"""代理转发端口:本地设置 > 内置 config.json > 默认 1080。"""
|
||||
port = _parse_port(_settings_load().get("local_port"))
|
||||
if port is not None:
|
||||
return port
|
||||
port = _parse_port(_config_val("local_port", 1080))
|
||||
return port if port is not None else 1080
|
||||
|
||||
def _set_local_port(port):
|
||||
"""更新代理转发端口并写回设置文件(下次开启代理生效)。"""
|
||||
global _TLS_LOCAL_PORT, PROXY_PORT
|
||||
_TLS_LOCAL_PORT = port
|
||||
PROXY_PORT = port
|
||||
data = _settings_load()
|
||||
data["local_port"] = port
|
||||
_settings_save(data)
|
||||
log(f"代理转发端口已保存: {port}(下次开启代理生效)")
|
||||
|
||||
# 以下模块级取值需在 _data_path 定义之后执行
|
||||
VERSION = _config_val("version", "999908162319")
|
||||
_TLS_LOCAL_PORT = int(_config_val("local_port", 1080)) # 本地转发器监听端口
|
||||
_TLS_LOCAL_PORT = _port_val() # 本地转发器监听端口(设置 > 内置 config > 1080)
|
||||
PROXY_PORT = _TLS_LOCAL_PORT
|
||||
|
||||
# ── PAC 数据在线更新(CDN 直连,无需认证) ─────────────
|
||||
@@ -1315,16 +1366,24 @@ class LoginDialog(QDialog):
|
||||
# ── 设置弹窗 ─────────────────────────────────────────
|
||||
|
||||
class SettingsDialog(QDialog):
|
||||
"""设置弹窗(当前仅含退出登录:清除凭据与本地节点配置)。"""
|
||||
"""设置弹窗:代理转发端口 + 退出登录。"""
|
||||
|
||||
def __init__(self, parent=None):
|
||||
def __init__(self, parent=None, port_locked=False):
|
||||
super().__init__(parent)
|
||||
self.setWindowTitle("设置")
|
||||
self.setWindowIcon(load_icon())
|
||||
self.setFixedSize(280, 150)
|
||||
self.setFixedSize(300, 230)
|
||||
self.setStyleSheet(f"""
|
||||
QDialog {{ background-color: {C_BG}; }}
|
||||
QLabel {{ color: {C_TEXT}; font-family: "Microsoft YaHei", "Segoe UI", sans-serif; font-size: 12px; }}
|
||||
QLineEdit {{
|
||||
background-color: {C_CARD};
|
||||
border: 1px solid {C_BORDER};
|
||||
border-radius: 6px;
|
||||
padding: 5px 8px;
|
||||
color: {C_TEXT};
|
||||
font-size: 12px;
|
||||
}}
|
||||
""")
|
||||
|
||||
layout = QVBoxLayout(self)
|
||||
@@ -1336,12 +1395,42 @@ class SettingsDialog(QDialog):
|
||||
title.setAlignment(Qt.AlignCenter)
|
||||
layout.addWidget(title)
|
||||
|
||||
# 代理转发端口
|
||||
port_row = QHBoxLayout()
|
||||
port_lab = QLabel("代理转发端口")
|
||||
port_lab.setStyleSheet(f"color: {C_SUBTEXT}; font-size: 12px;")
|
||||
port_row.addWidget(port_lab)
|
||||
port_row.addStretch()
|
||||
self.ed_port = QLineEdit(str(_TLS_LOCAL_PORT))
|
||||
self.ed_port.setFixedWidth(80)
|
||||
self.ed_port.setEnabled(not port_locked)
|
||||
port_row.addWidget(self.ed_port)
|
||||
layout.addLayout(port_row)
|
||||
|
||||
self.lb_port = QLabel("代理运行中,关闭代理后可修改" if port_locked else "保存后下次开启代理生效")
|
||||
self.lb_port.setStyleSheet(f"color: {C_SUBTEXT}; font-size: 11px;")
|
||||
self.lb_port.setFixedHeight(14)
|
||||
layout.addWidget(self.lb_port)
|
||||
|
||||
btn_save = QPushButton("保存端口")
|
||||
btn_save.setStyleSheet(f"""
|
||||
QPushButton {{
|
||||
background-color: {C_GREEN}; color: #fff; border: none;
|
||||
border-radius: 6px; padding: 5px 14px;
|
||||
font-size: 12px; font-weight: bold;
|
||||
}}
|
||||
QPushButton:disabled {{ background-color: #2a3a2e; color: #666; }}
|
||||
""")
|
||||
btn_save.setEnabled(not port_locked)
|
||||
btn_save.clicked.connect(self._save_port)
|
||||
layout.addWidget(btn_save)
|
||||
|
||||
btn_logout = QPushButton("退出登录")
|
||||
btn_logout.setStyleSheet(f"""
|
||||
QPushButton {{
|
||||
background-color: {C_CARD}; color: {C_RED};
|
||||
border: 1px solid {C_RED}; border-radius: 6px;
|
||||
padding: 7px 16px; font-size: 13px;
|
||||
padding: 5px 14px; font-size: 12px;
|
||||
}}
|
||||
QPushButton:hover {{ background-color: #ffecec; }}
|
||||
""")
|
||||
@@ -1351,6 +1440,17 @@ class SettingsDialog(QDialog):
|
||||
|
||||
layout.addStretch()
|
||||
|
||||
def _save_port(self):
|
||||
port = _parse_port(self.ed_port.text())
|
||||
if port is None:
|
||||
self.lb_port.setText("端口应为 1-65535 的数字")
|
||||
self.lb_port.setStyleSheet(f"color: {C_RED}; font-size: 11px;")
|
||||
return
|
||||
_set_local_port(port)
|
||||
self.ed_port.setText(str(port))
|
||||
self.lb_port.setText(f"已保存: {port},下次开启代理生效")
|
||||
self.lb_port.setStyleSheet(f"color: {C_GREEN}; font-size: 11px;")
|
||||
|
||||
def _logout(self):
|
||||
"""退出登录:删除加密凭据与本地节点配置,清空内存缓存。"""
|
||||
global _NODES
|
||||
@@ -1734,8 +1834,8 @@ class MainWindow(QWidget):
|
||||
|
||||
# ── 设置 ──
|
||||
def _show_settings_dialog(self):
|
||||
"""打开设置弹窗;退出登录后刷新节点标题。"""
|
||||
SettingsDialog(self).exec_()
|
||||
"""打开设置弹窗(代理运行中锁定端口修改);退出登录后刷新节点标题。"""
|
||||
SettingsDialog(self, port_locked=self._proxy_set_by_us).exec_()
|
||||
self._refresh_subtitle()
|
||||
|
||||
# ── 节点登录 ──
|
||||
|
||||
Reference in New Issue
Block a user