release: prepare 0.2.0 for sing-box 1.14

This commit is contained in:
2026-09-08 19:26:00 +05:00
parent 81ea89f7fa
commit 76dce5b47a
42 changed files with 1634 additions and 549 deletions
+119
View File
@@ -0,0 +1,119 @@
from __future__ import annotations
import json
from typing import Any
from .model import Hy2Endpoint
from .policy import Policy
from .version import SUPPORTED_SING_BOX_VERSION
TARGET_VERSION = SUPPORTED_SING_BOX_VERSION
GECKO_MIN_PACKET_SIZE = 512
GECKO_MAX_PACKET_SIZE = 1200
def render_config(policy: Policy, endpoint: Hy2Endpoint) -> dict[str, Any]:
network = policy.network
dns = policy.dns
outbound: dict[str, Any] = {
"type": "hysteria2",
"tag": "hy2-out",
"server": endpoint.server,
"up_mbps": policy.bandwidth.up_mbps,
"down_mbps": policy.bandwidth.down_mbps,
"password": endpoint.password,
"tls": {
"enabled": True,
"server_name": endpoint.sni,
"insecure": endpoint.insecure,
},
"disable_chrome_parrot": False,
"bind_interface": network.upstream_interface,
"domain_resolver": {"server": "bootstrap-dns", "strategy": dns.strategy},
}
if endpoint.server_port is not None:
outbound["server_port"] = endpoint.server_port
else:
outbound["server_ports"] = list(endpoint.server_ports)
if endpoint.obfs_type is not None:
obfs: dict[str, Any] = {
"type": endpoint.obfs_type,
"password": endpoint.obfs_password,
}
if endpoint.obfs_type == "gecko":
obfs["min_packet_size"] = GECKO_MIN_PACKET_SIZE
obfs["max_packet_size"] = GECKO_MAX_PACKET_SIZE
outbound["obfs"] = obfs
return {
"log": {"level": "info", "timestamp": True},
"dns": {
"servers": [
{
"type": "udp",
"tag": "bootstrap-dns",
"server": dns.bootstrap_server,
"server_port": dns.bootstrap_port,
"bind_interface": network.upstream_interface,
},
{
"type": "https",
"tag": "remote-dns",
"server": dns.remote_server,
"server_port": dns.remote_port,
"path": dns.remote_path,
"tls": {
"enabled": True,
"server_name": dns.remote_tls_server_name,
},
"detour": "hy2-out",
},
],
"final": "remote-dns",
"strategy": dns.strategy,
},
"inbounds": [
{
"type": "tun",
"tag": "tun-in",
"interface_name": network.tun_name,
"address": [network.tun_address],
"mtu": network.mtu,
"dns_mode": "disabled",
"auto_route": True,
"iproute2_table_index": network.iproute2_table_index,
"iproute2_rule_index": network.iproute2_rule_index,
"auto_redirect": True,
"auto_redirect_input_mark": network.auto_redirect_input_mark,
"auto_redirect_output_mark": network.auto_redirect_output_mark,
"auto_redirect_reset_mark": network.auto_redirect_reset_mark,
"auto_redirect_nfqueue": network.auto_redirect_nfqueue,
"auto_redirect_iproute2_fallback_rule_index": network.auto_redirect_fallback_rule_index,
"strict_route": True,
"stack": "mixed",
"route_exclude_address": list(network.route_exclude_address),
}
],
"outbounds": [outbound],
"route": {
"auto_detect_interface": True,
"default_domain_resolver": {
"server": "bootstrap-dns",
"strategy": dns.strategy,
},
"final": "hy2-out",
"rules": [
{
"network": ["tcp", "udp"],
"port": 53,
"action": "hijack-dns",
}
],
},
}
def render_bytes(policy: Policy, endpoint: Hy2Endpoint) -> bytes:
return (
json.dumps(render_config(policy, endpoint), ensure_ascii=False, indent=2) + "\n"
).encode("utf-8")