platform: modularize api/gui, add docs-tests-web foundation, and refresh root config
This commit is contained in:
420
selective-vpn-gui/main_window/ui_tabs_singbox_editor_mixin.py
Normal file
420
selective-vpn-gui/main_window/ui_tabs_singbox_editor_mixin.py
Normal file
@@ -0,0 +1,420 @@
|
||||
from __future__ import annotations
|
||||
|
||||
from PySide6.QtCore import QSize
|
||||
from PySide6.QtWidgets import (
|
||||
QApplication,
|
||||
QCheckBox,
|
||||
QComboBox,
|
||||
QFormLayout,
|
||||
QGroupBox,
|
||||
QHBoxLayout,
|
||||
QLabel,
|
||||
QLineEdit,
|
||||
QPushButton,
|
||||
QRadioButton,
|
||||
QSpinBox,
|
||||
QToolButton,
|
||||
QVBoxLayout,
|
||||
QWidget,
|
||||
)
|
||||
|
||||
from main_window.constants import SINGBOX_EDITOR_PROTOCOL_IDS, SINGBOX_EDITOR_PROTOCOL_OPTIONS
|
||||
|
||||
|
||||
class UITabsSingBoxEditorMixin:
|
||||
def _build_singbox_vless_editor(self, parent_layout: QVBoxLayout) -> None:
|
||||
grp = QGroupBox("Protocol editor (client)")
|
||||
self.grp_singbox_proto_editor = grp
|
||||
lay = QVBoxLayout(grp)
|
||||
|
||||
self.lbl_singbox_proto_editor_info = QLabel(
|
||||
"Client-side fields only. Server billing/traffic/expiry fields are excluded."
|
||||
)
|
||||
self.lbl_singbox_proto_editor_info.setStyleSheet("color: gray;")
|
||||
lay.addWidget(self.lbl_singbox_proto_editor_info)
|
||||
|
||||
form = QFormLayout()
|
||||
self.frm_singbox_proto_form = form
|
||||
|
||||
self.ent_singbox_proto_name = QLineEdit()
|
||||
self.ent_singbox_proto_name.setPlaceholderText("Profile name")
|
||||
form.addRow("Profile name:", self.ent_singbox_proto_name)
|
||||
|
||||
self.chk_singbox_proto_enabled = QCheckBox("Enabled")
|
||||
self.chk_singbox_proto_enabled.setChecked(True)
|
||||
form.addRow("Enabled:", self.chk_singbox_proto_enabled)
|
||||
|
||||
self.cmb_singbox_proto_protocol = QComboBox()
|
||||
for label, pid in SINGBOX_EDITOR_PROTOCOL_OPTIONS:
|
||||
self.cmb_singbox_proto_protocol.addItem(label, pid)
|
||||
self.cmb_singbox_proto_protocol.currentIndexChanged.connect(
|
||||
self.on_singbox_vless_editor_changed
|
||||
)
|
||||
form.addRow("Protocol:", self.cmb_singbox_proto_protocol)
|
||||
|
||||
self.ent_singbox_vless_server = QLineEdit()
|
||||
self.ent_singbox_vless_server.setPlaceholderText("example.com")
|
||||
form.addRow("Address:", self.ent_singbox_vless_server)
|
||||
|
||||
self.spn_singbox_vless_port = QSpinBox()
|
||||
self.spn_singbox_vless_port.setRange(1, 65535)
|
||||
self.spn_singbox_vless_port.setValue(443)
|
||||
form.addRow("Port:", self.spn_singbox_vless_port)
|
||||
|
||||
self.ent_singbox_vless_uuid = QLineEdit()
|
||||
self.ent_singbox_vless_uuid.setPlaceholderText("xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx")
|
||||
form.addRow("UUID:", self.ent_singbox_vless_uuid)
|
||||
|
||||
self.ent_singbox_proto_password = QLineEdit()
|
||||
self.ent_singbox_proto_password.setPlaceholderText("password")
|
||||
form.addRow("Password:", self.ent_singbox_proto_password)
|
||||
|
||||
self.cmb_singbox_vless_flow = QComboBox()
|
||||
self.cmb_singbox_vless_flow.addItem("None", "")
|
||||
# sing-box v1.12/v1.13 VLESS flow preset; field remains editable for custom/raw values.
|
||||
self.cmb_singbox_vless_flow.addItem("xtls-rprx-vision", "xtls-rprx-vision")
|
||||
self.cmb_singbox_vless_flow.setEditable(True)
|
||||
self.cmb_singbox_vless_flow.setInsertPolicy(QComboBox.NoInsert)
|
||||
form.addRow("Flow:", self.cmb_singbox_vless_flow)
|
||||
|
||||
self.cmb_singbox_vless_packet_encoding = QComboBox()
|
||||
self.cmb_singbox_vless_packet_encoding.addItem("auto", "")
|
||||
self.cmb_singbox_vless_packet_encoding.addItem("xudp", "xudp")
|
||||
form.addRow("Packet encoding:", self.cmb_singbox_vless_packet_encoding)
|
||||
|
||||
self.cmb_singbox_ss_method = QComboBox()
|
||||
self.cmb_singbox_ss_method.setEditable(True)
|
||||
self.cmb_singbox_ss_method.setInsertPolicy(QComboBox.NoInsert)
|
||||
for method in (
|
||||
"aes-128-gcm",
|
||||
"aes-256-gcm",
|
||||
"chacha20-ietf-poly1305",
|
||||
"2022-blake3-aes-128-gcm",
|
||||
"2022-blake3-aes-256-gcm",
|
||||
"none",
|
||||
):
|
||||
self.cmb_singbox_ss_method.addItem(method, method)
|
||||
form.addRow("SS method:", self.cmb_singbox_ss_method)
|
||||
|
||||
self.ent_singbox_ss_plugin = QLineEdit()
|
||||
self.ent_singbox_ss_plugin.setPlaceholderText("obfs-local;obfs=http;obfs-host=example.com")
|
||||
form.addRow("SS plugin:", self.ent_singbox_ss_plugin)
|
||||
|
||||
self.spn_singbox_hy2_up_mbps = QSpinBox()
|
||||
self.spn_singbox_hy2_up_mbps.setRange(0, 100000)
|
||||
form.addRow("HY2 up mbps:", self.spn_singbox_hy2_up_mbps)
|
||||
|
||||
self.spn_singbox_hy2_down_mbps = QSpinBox()
|
||||
self.spn_singbox_hy2_down_mbps.setRange(0, 100000)
|
||||
form.addRow("HY2 down mbps:", self.spn_singbox_hy2_down_mbps)
|
||||
|
||||
self.ent_singbox_hy2_obfs = QLineEdit()
|
||||
self.ent_singbox_hy2_obfs.setPlaceholderText("salamander")
|
||||
form.addRow("HY2 obfs type:", self.ent_singbox_hy2_obfs)
|
||||
|
||||
self.ent_singbox_hy2_obfs_password = QLineEdit()
|
||||
self.ent_singbox_hy2_obfs_password.setPlaceholderText("obfs password")
|
||||
form.addRow("HY2 obfs password:", self.ent_singbox_hy2_obfs_password)
|
||||
|
||||
self.cmb_singbox_tuic_congestion = QComboBox()
|
||||
self.cmb_singbox_tuic_congestion.setEditable(True)
|
||||
self.cmb_singbox_tuic_congestion.setInsertPolicy(QComboBox.NoInsert)
|
||||
self.cmb_singbox_tuic_congestion.addItem("Default", "")
|
||||
self.cmb_singbox_tuic_congestion.addItem("bbr", "bbr")
|
||||
self.cmb_singbox_tuic_congestion.addItem("cubic", "cubic")
|
||||
self.cmb_singbox_tuic_congestion.addItem("new_reno", "new_reno")
|
||||
form.addRow("TUIC congestion:", self.cmb_singbox_tuic_congestion)
|
||||
|
||||
self.cmb_singbox_tuic_udp_mode = QComboBox()
|
||||
self.cmb_singbox_tuic_udp_mode.addItem("Default", "")
|
||||
self.cmb_singbox_tuic_udp_mode.addItem("native", "native")
|
||||
self.cmb_singbox_tuic_udp_mode.addItem("quic", "quic")
|
||||
form.addRow("TUIC UDP relay:", self.cmb_singbox_tuic_udp_mode)
|
||||
|
||||
self.chk_singbox_tuic_zero_rtt = QCheckBox("Enable zero RTT handshake")
|
||||
form.addRow("TUIC zero RTT:", self.chk_singbox_tuic_zero_rtt)
|
||||
|
||||
self.ent_singbox_wg_private_key = QLineEdit()
|
||||
self.ent_singbox_wg_private_key.setPlaceholderText("wireguard private key")
|
||||
self.ent_singbox_wg_private_key.setEchoMode(QLineEdit.PasswordEchoOnEdit)
|
||||
form.addRow("WG private key:", self.ent_singbox_wg_private_key)
|
||||
|
||||
self.ent_singbox_wg_peer_public_key = QLineEdit()
|
||||
self.ent_singbox_wg_peer_public_key.setPlaceholderText("peer public key")
|
||||
self.ent_singbox_wg_peer_public_key.setEchoMode(QLineEdit.PasswordEchoOnEdit)
|
||||
form.addRow("WG peer public key:", self.ent_singbox_wg_peer_public_key)
|
||||
|
||||
self.ent_singbox_wg_psk = QLineEdit()
|
||||
self.ent_singbox_wg_psk.setPlaceholderText("pre-shared key (optional)")
|
||||
self.ent_singbox_wg_psk.setEchoMode(QLineEdit.PasswordEchoOnEdit)
|
||||
form.addRow("WG pre-shared key:", self.ent_singbox_wg_psk)
|
||||
|
||||
self.ent_singbox_wg_local_address = QLineEdit()
|
||||
self.ent_singbox_wg_local_address.setPlaceholderText("10.0.0.2/32,fd00::2/128")
|
||||
form.addRow("WG local address:", self.ent_singbox_wg_local_address)
|
||||
|
||||
self.ent_singbox_wg_reserved = QLineEdit()
|
||||
self.ent_singbox_wg_reserved.setPlaceholderText("0,0,0 (optional)")
|
||||
form.addRow("WG reserved:", self.ent_singbox_wg_reserved)
|
||||
|
||||
self.spn_singbox_wg_mtu = QSpinBox()
|
||||
self.spn_singbox_wg_mtu.setRange(0, 9200)
|
||||
form.addRow("WG MTU:", self.spn_singbox_wg_mtu)
|
||||
|
||||
self.cmb_singbox_vless_transport = QComboBox()
|
||||
self.cmb_singbox_vless_transport.addItem("TCP (RAW)", "tcp")
|
||||
self.cmb_singbox_vless_transport.addItem("WebSocket", "ws")
|
||||
self.cmb_singbox_vless_transport.addItem("gRPC", "grpc")
|
||||
self.cmb_singbox_vless_transport.addItem("HTTP", "http")
|
||||
self.cmb_singbox_vless_transport.addItem("HTTP Upgrade", "httpupgrade")
|
||||
self.cmb_singbox_vless_transport.addItem("QUIC", "quic")
|
||||
self.cmb_singbox_vless_transport.currentIndexChanged.connect(
|
||||
self.on_singbox_vless_editor_changed
|
||||
)
|
||||
form.addRow("Transport:", self.cmb_singbox_vless_transport)
|
||||
|
||||
self.ent_singbox_vless_path = QLineEdit()
|
||||
self.ent_singbox_vless_path.setPlaceholderText("/")
|
||||
form.addRow("Transport path:", self.ent_singbox_vless_path)
|
||||
|
||||
self.ent_singbox_vless_grpc_service = QLineEdit()
|
||||
self.ent_singbox_vless_grpc_service.setPlaceholderText("service-name")
|
||||
form.addRow("gRPC service:", self.ent_singbox_vless_grpc_service)
|
||||
|
||||
self.cmb_singbox_vless_security = QComboBox()
|
||||
self.cmb_singbox_vless_security.addItem("None", "none")
|
||||
self.cmb_singbox_vless_security.addItem("TLS", "tls")
|
||||
self.cmb_singbox_vless_security.addItem("Reality", "reality")
|
||||
self.cmb_singbox_vless_security.currentIndexChanged.connect(
|
||||
self.on_singbox_vless_editor_changed
|
||||
)
|
||||
form.addRow("Security:", self.cmb_singbox_vless_security)
|
||||
|
||||
self.ent_singbox_vless_sni = QLineEdit()
|
||||
self.ent_singbox_vless_sni.setPlaceholderText("www.example.com")
|
||||
form.addRow("SNI:", self.ent_singbox_vless_sni)
|
||||
|
||||
self.ent_singbox_tls_alpn = QLineEdit()
|
||||
self.ent_singbox_tls_alpn.setPlaceholderText("h2,http/1.1")
|
||||
form.addRow("TLS ALPN:", self.ent_singbox_tls_alpn)
|
||||
|
||||
self.cmb_singbox_vless_utls_fp = QComboBox()
|
||||
self.cmb_singbox_vless_utls_fp.addItem("Default", "")
|
||||
self.cmb_singbox_vless_utls_fp.addItem("chrome", "chrome")
|
||||
self.cmb_singbox_vless_utls_fp.addItem("firefox", "firefox")
|
||||
self.cmb_singbox_vless_utls_fp.addItem("safari", "safari")
|
||||
self.cmb_singbox_vless_utls_fp.addItem("edge", "edge")
|
||||
form.addRow("uTLS fingerprint:", self.cmb_singbox_vless_utls_fp)
|
||||
|
||||
self.ent_singbox_vless_reality_pk = QLineEdit()
|
||||
self.ent_singbox_vless_reality_pk.setPlaceholderText("Reality public key")
|
||||
form.addRow("Reality public key:", self.ent_singbox_vless_reality_pk)
|
||||
|
||||
self.ent_singbox_vless_reality_sid = QLineEdit()
|
||||
self.ent_singbox_vless_reality_sid.setPlaceholderText("short_id")
|
||||
form.addRow("Reality short id:", self.ent_singbox_vless_reality_sid)
|
||||
|
||||
self.chk_singbox_vless_insecure = QCheckBox("Allow insecure TLS")
|
||||
form.addRow("TLS insecure:", self.chk_singbox_vless_insecure)
|
||||
|
||||
self.chk_singbox_vless_sniff = QCheckBox("Enable sniffing for local inbound")
|
||||
self.chk_singbox_vless_sniff.setChecked(True)
|
||||
form.addRow("Sniffing:", self.chk_singbox_vless_sniff)
|
||||
|
||||
lay.addLayout(form)
|
||||
|
||||
wg_helpers = QHBoxLayout()
|
||||
self.btn_singbox_wg_paste_private = QToolButton()
|
||||
self.btn_singbox_wg_paste_private.setText("Paste private")
|
||||
self.btn_singbox_wg_paste_private.clicked.connect(
|
||||
lambda: self._paste_line_edit_from_clipboard(self.ent_singbox_wg_private_key)
|
||||
)
|
||||
wg_helpers.addWidget(self.btn_singbox_wg_paste_private)
|
||||
|
||||
self.btn_singbox_wg_copy_private = QToolButton()
|
||||
self.btn_singbox_wg_copy_private.setText("Copy private")
|
||||
self.btn_singbox_wg_copy_private.clicked.connect(
|
||||
lambda: self._copy_line_edit_to_clipboard(self.ent_singbox_wg_private_key)
|
||||
)
|
||||
wg_helpers.addWidget(self.btn_singbox_wg_copy_private)
|
||||
|
||||
self.btn_singbox_wg_paste_peer = QToolButton()
|
||||
self.btn_singbox_wg_paste_peer.setText("Paste peer")
|
||||
self.btn_singbox_wg_paste_peer.clicked.connect(
|
||||
lambda: self._paste_line_edit_from_clipboard(self.ent_singbox_wg_peer_public_key)
|
||||
)
|
||||
wg_helpers.addWidget(self.btn_singbox_wg_paste_peer)
|
||||
|
||||
self.btn_singbox_wg_copy_peer = QToolButton()
|
||||
self.btn_singbox_wg_copy_peer.setText("Copy peer")
|
||||
self.btn_singbox_wg_copy_peer.clicked.connect(
|
||||
lambda: self._copy_line_edit_to_clipboard(self.ent_singbox_wg_peer_public_key)
|
||||
)
|
||||
wg_helpers.addWidget(self.btn_singbox_wg_copy_peer)
|
||||
|
||||
self.btn_singbox_wg_paste_psk = QToolButton()
|
||||
self.btn_singbox_wg_paste_psk.setText("Paste PSK")
|
||||
self.btn_singbox_wg_paste_psk.clicked.connect(
|
||||
lambda: self._paste_line_edit_from_clipboard(self.ent_singbox_wg_psk)
|
||||
)
|
||||
wg_helpers.addWidget(self.btn_singbox_wg_paste_psk)
|
||||
|
||||
self.btn_singbox_wg_copy_psk = QToolButton()
|
||||
self.btn_singbox_wg_copy_psk.setText("Copy PSK")
|
||||
self.btn_singbox_wg_copy_psk.clicked.connect(
|
||||
lambda: self._copy_line_edit_to_clipboard(self.ent_singbox_wg_psk)
|
||||
)
|
||||
wg_helpers.addWidget(self.btn_singbox_wg_copy_psk)
|
||||
wg_helpers.addStretch(1)
|
||||
|
||||
self.wdg_singbox_wg_key_helpers = QWidget()
|
||||
self.wdg_singbox_wg_key_helpers.setLayout(wg_helpers)
|
||||
lay.addWidget(self.wdg_singbox_wg_key_helpers)
|
||||
|
||||
self.lbl_singbox_proto_guardrails = QLabel("Guardrails: address/port/uuid required")
|
||||
self.lbl_singbox_proto_guardrails.setStyleSheet("color: gray;")
|
||||
lay.addWidget(self.lbl_singbox_proto_guardrails)
|
||||
|
||||
parent_layout.addWidget(grp)
|
||||
|
||||
self.on_singbox_vless_editor_changed()
|
||||
|
||||
def _set_proto_form_row_visible(self, field: QWidget, visible: bool) -> None:
|
||||
field.setVisible(visible)
|
||||
label = None
|
||||
form = getattr(self, "frm_singbox_proto_form", None)
|
||||
if form is not None:
|
||||
try:
|
||||
label = form.labelForField(field)
|
||||
except Exception:
|
||||
label = None
|
||||
if label is not None:
|
||||
label.setVisible(visible)
|
||||
|
||||
def _copy_line_edit_to_clipboard(self, field: QLineEdit) -> None:
|
||||
txt = str(field.text() or "").strip()
|
||||
if txt:
|
||||
QApplication.clipboard().setText(txt)
|
||||
|
||||
def _paste_line_edit_from_clipboard(self, field: QLineEdit) -> None:
|
||||
txt = str(QApplication.clipboard().text() or "").strip()
|
||||
field.setText(txt)
|
||||
|
||||
def _current_editor_protocol(self) -> str:
|
||||
return str(self.cmb_singbox_proto_protocol.currentData() or "vless").strip().lower() or "vless"
|
||||
|
||||
def _is_supported_editor_protocol(self, protocol: str) -> bool:
|
||||
return str(protocol or "").strip().lower() in SINGBOX_EDITOR_PROTOCOL_IDS
|
||||
|
||||
def on_singbox_vless_editor_changed(self, _index: int = 0) -> None:
|
||||
protocol = self._current_editor_protocol()
|
||||
self._singbox_editor_protocol = protocol
|
||||
|
||||
transport = str(self.cmb_singbox_vless_transport.currentData() or "tcp").strip().lower()
|
||||
security = str(self.cmb_singbox_vless_security.currentData() or "none").strip().lower()
|
||||
if protocol == "vless":
|
||||
self.cmb_singbox_vless_security.setEnabled(True)
|
||||
elif protocol == "trojan":
|
||||
if security == "reality":
|
||||
idx = self.cmb_singbox_vless_security.findData("tls")
|
||||
self.cmb_singbox_vless_security.setCurrentIndex(idx if idx >= 0 else 1)
|
||||
security = "tls"
|
||||
self.cmb_singbox_vless_security.setEnabled(True)
|
||||
elif protocol in ("hysteria2", "tuic"):
|
||||
idx = self.cmb_singbox_vless_security.findData("tls")
|
||||
self.cmb_singbox_vless_security.setCurrentIndex(idx if idx >= 0 else 1)
|
||||
security = "tls"
|
||||
self.cmb_singbox_vless_security.setEnabled(False)
|
||||
elif protocol == "wireguard":
|
||||
idx = self.cmb_singbox_vless_security.findData("none")
|
||||
self.cmb_singbox_vless_security.setCurrentIndex(idx if idx >= 0 else 0)
|
||||
security = "none"
|
||||
self.cmb_singbox_vless_security.setEnabled(False)
|
||||
else:
|
||||
idx = self.cmb_singbox_vless_security.findData("none")
|
||||
self.cmb_singbox_vless_security.setCurrentIndex(idx if idx >= 0 else 0)
|
||||
security = "none"
|
||||
self.cmb_singbox_vless_security.setEnabled(False)
|
||||
|
||||
path_needed = transport in ("ws", "http", "httpupgrade")
|
||||
grpc_needed = transport == "grpc"
|
||||
transport_supported = protocol in ("vless", "trojan")
|
||||
|
||||
self.cmb_singbox_vless_transport.setEnabled(transport_supported)
|
||||
self.ent_singbox_vless_path.setEnabled(transport_supported and path_needed)
|
||||
self.ent_singbox_vless_grpc_service.setEnabled(transport_supported and grpc_needed)
|
||||
|
||||
tls_like = security in ("tls", "reality")
|
||||
reality = security == "reality"
|
||||
|
||||
self.ent_singbox_vless_sni.setEnabled(tls_like)
|
||||
self.ent_singbox_tls_alpn.setEnabled(tls_like)
|
||||
self.cmb_singbox_vless_utls_fp.setEnabled(tls_like)
|
||||
self.chk_singbox_vless_insecure.setEnabled(tls_like)
|
||||
self.ent_singbox_vless_reality_pk.setEnabled(reality)
|
||||
self.ent_singbox_vless_reality_sid.setEnabled(reality)
|
||||
|
||||
show_vless_auth = protocol == "vless"
|
||||
show_password = protocol in ("trojan", "shadowsocks", "hysteria2", "tuic")
|
||||
show_ss = protocol == "shadowsocks"
|
||||
show_hy2 = protocol == "hysteria2"
|
||||
show_tuic = protocol == "tuic"
|
||||
show_wg = protocol == "wireguard"
|
||||
|
||||
self._set_proto_form_row_visible(self.ent_singbox_vless_uuid, show_vless_auth or show_tuic)
|
||||
self._set_proto_form_row_visible(self.ent_singbox_proto_password, show_password)
|
||||
self._set_proto_form_row_visible(self.cmb_singbox_vless_flow, show_vless_auth)
|
||||
self._set_proto_form_row_visible(self.cmb_singbox_vless_packet_encoding, show_vless_auth)
|
||||
|
||||
self._set_proto_form_row_visible(self.cmb_singbox_ss_method, show_ss)
|
||||
self._set_proto_form_row_visible(self.ent_singbox_ss_plugin, show_ss)
|
||||
|
||||
self._set_proto_form_row_visible(self.spn_singbox_hy2_up_mbps, show_hy2)
|
||||
self._set_proto_form_row_visible(self.spn_singbox_hy2_down_mbps, show_hy2)
|
||||
self._set_proto_form_row_visible(self.ent_singbox_hy2_obfs, show_hy2)
|
||||
self._set_proto_form_row_visible(self.ent_singbox_hy2_obfs_password, show_hy2)
|
||||
|
||||
self._set_proto_form_row_visible(self.cmb_singbox_tuic_congestion, show_tuic)
|
||||
self._set_proto_form_row_visible(self.cmb_singbox_tuic_udp_mode, show_tuic)
|
||||
self._set_proto_form_row_visible(self.chk_singbox_tuic_zero_rtt, show_tuic)
|
||||
|
||||
self._set_proto_form_row_visible(self.ent_singbox_wg_private_key, show_wg)
|
||||
self._set_proto_form_row_visible(self.ent_singbox_wg_peer_public_key, show_wg)
|
||||
self._set_proto_form_row_visible(self.ent_singbox_wg_psk, show_wg)
|
||||
self._set_proto_form_row_visible(self.ent_singbox_wg_local_address, show_wg)
|
||||
self._set_proto_form_row_visible(self.ent_singbox_wg_reserved, show_wg)
|
||||
self._set_proto_form_row_visible(self.spn_singbox_wg_mtu, show_wg)
|
||||
self.wdg_singbox_wg_key_helpers.setVisible(show_wg)
|
||||
|
||||
self._set_proto_form_row_visible(self.cmb_singbox_vless_transport, transport_supported)
|
||||
self._set_proto_form_row_visible(self.ent_singbox_vless_path, transport_supported)
|
||||
self._set_proto_form_row_visible(self.ent_singbox_vless_grpc_service, transport_supported)
|
||||
|
||||
self._set_proto_form_row_visible(self.cmb_singbox_vless_security, protocol not in ("shadowsocks", "wireguard"))
|
||||
self._set_proto_form_row_visible(self.ent_singbox_vless_sni, tls_like)
|
||||
self._set_proto_form_row_visible(self.ent_singbox_tls_alpn, tls_like)
|
||||
self._set_proto_form_row_visible(self.cmb_singbox_vless_utls_fp, tls_like)
|
||||
self._set_proto_form_row_visible(self.chk_singbox_vless_insecure, tls_like)
|
||||
self._set_proto_form_row_visible(self.ent_singbox_vless_reality_pk, reality)
|
||||
self._set_proto_form_row_visible(self.ent_singbox_vless_reality_sid, reality)
|
||||
|
||||
tips = ["Guardrails:"]
|
||||
if protocol == "vless":
|
||||
tips.append("address/port/uuid required")
|
||||
elif protocol == "trojan":
|
||||
tips.append("address/port/password required")
|
||||
elif protocol == "shadowsocks":
|
||||
tips.append("address/port/SS method/password required")
|
||||
elif protocol == "hysteria2":
|
||||
tips.append("address/port/password required")
|
||||
elif protocol == "tuic":
|
||||
tips.append("address/port/uuid/password required")
|
||||
elif protocol == "wireguard":
|
||||
tips.append("address/port/private_key/peer_public_key/local_address required")
|
||||
if reality:
|
||||
tips.append("reality.public_key is required")
|
||||
if transport_supported and grpc_needed:
|
||||
tips.append("gRPC service is required")
|
||||
if transport_supported and path_needed:
|
||||
tips.append("transport path is required")
|
||||
self.lbl_singbox_proto_guardrails.setText(" | ".join(tips))
|
||||
Reference in New Issue
Block a user