mirror of
https://github.com/house-of-vanity/OutFleet.git
synced 2025-08-21 14:37:16 +00:00
Xray works
This commit is contained in:
176
vpn/xray_api_v2/models/inbound.py
Normal file
176
vpn/xray_api_v2/models/inbound.py
Normal file
@@ -0,0 +1,176 @@
|
||||
"""Inbound configuration models"""
|
||||
from dataclasses import dataclass, field
|
||||
from typing import Optional, Dict, Any, List, Union
|
||||
|
||||
from .base import BaseXrayModel, XrayConfig, XrayProtocol
|
||||
from .protocols import (
|
||||
VLESSInboundConfig, VMeSSInboundConfig,
|
||||
TrojanServerConfig, ShadowsocksServerConfig
|
||||
)
|
||||
from .transports import StreamSettings
|
||||
|
||||
|
||||
@dataclass
|
||||
class SniffingConfig(BaseXrayModel):
|
||||
"""Traffic sniffing configuration"""
|
||||
enabled: bool = True
|
||||
destOverride: Optional[List[str]] = None
|
||||
metadataOnly: bool = False
|
||||
|
||||
def __post_init__(self):
|
||||
if self.destOverride is None:
|
||||
self.destOverride = ["http", "tls"]
|
||||
|
||||
|
||||
@dataclass
|
||||
class ReceiverConfig(XrayConfig):
|
||||
"""Receiver configuration for inbound"""
|
||||
__xray_type__ = "xray.app.proxyman.ReceiverConfig"
|
||||
|
||||
listen: str = "0.0.0.0"
|
||||
port: Optional[int] = None
|
||||
portList: Optional[Union[int, str]] = None # Can be int or range like "10000-20000"
|
||||
streamSettings: Optional[StreamSettings] = None
|
||||
|
||||
def to_xray_json(self) -> Dict[str, Any]:
|
||||
"""Convert to Xray format"""
|
||||
config = {"listen": self.listen}
|
||||
|
||||
# Either port or portList must be set
|
||||
if self.port is not None:
|
||||
config["port"] = self.port
|
||||
elif self.portList is not None:
|
||||
config["portList"] = self.portList
|
||||
else:
|
||||
raise ValueError("Either port or portList must be specified")
|
||||
|
||||
if self.streamSettings:
|
||||
config["streamSettings"] = self.streamSettings.to_xray_json()
|
||||
|
||||
return config
|
||||
|
||||
|
||||
@dataclass
|
||||
class InboundConfig(BaseXrayModel):
|
||||
"""Complete inbound configuration"""
|
||||
tag: str
|
||||
protocol: XrayProtocol
|
||||
settings: Union[VLESSInboundConfig, VMeSSInboundConfig, TrojanServerConfig, ShadowsocksServerConfig]
|
||||
listen: str = "0.0.0.0"
|
||||
port: Optional[int] = None
|
||||
portList: Optional[Union[int, str]] = None
|
||||
streamSettings: Optional[StreamSettings] = None
|
||||
sniffing: Optional[SniffingConfig] = None
|
||||
|
||||
def to_xray_json(self) -> Dict[str, Any]:
|
||||
"""Convert to Xray API format with proper field order and structure"""
|
||||
config = {
|
||||
"listen": self.listen,
|
||||
"tag": self.tag,
|
||||
"protocol": self.protocol.value if hasattr(self.protocol, 'value') else str(self.protocol),
|
||||
}
|
||||
|
||||
# Add port or portList (port comes before protocol in working format)
|
||||
if self.port is not None:
|
||||
config["port"] = self.port
|
||||
elif self.portList is not None:
|
||||
config["portList"] = self.portList
|
||||
else:
|
||||
raise ValueError("Either port or portList must be specified")
|
||||
|
||||
# Add protocol settings with _TypedMessage_
|
||||
settings = self.settings.to_xray_json()
|
||||
if "_TypedMessage_" not in settings:
|
||||
# Add _TypedMessage_ based on protocol
|
||||
protocol_type_map = {
|
||||
"vless": "xray.proxy.vless.inbound.Config",
|
||||
"vmess": "xray.proxy.vmess.inbound.Config",
|
||||
"trojan": "xray.proxy.trojan.inbound.Config",
|
||||
"shadowsocks": "xray.proxy.shadowsocks.inbound.Config"
|
||||
}
|
||||
protocol_name = self.protocol.value if hasattr(self.protocol, 'value') else str(self.protocol)
|
||||
if protocol_name in protocol_type_map:
|
||||
settings["_TypedMessage_"] = protocol_type_map[protocol_name]
|
||||
|
||||
config["settings"] = settings
|
||||
|
||||
# Add stream settings
|
||||
if self.streamSettings:
|
||||
config["streamSettings"] = self.streamSettings.to_xray_json()
|
||||
else:
|
||||
config["streamSettings"] = {"network": "tcp"} # Default TCP
|
||||
|
||||
# Add sniffing
|
||||
if self.sniffing:
|
||||
config["sniffing"] = self.sniffing.to_dict()
|
||||
|
||||
return config
|
||||
|
||||
|
||||
# Builder for easier configuration
|
||||
class InboundBuilder:
|
||||
"""Builder for creating inbound configurations"""
|
||||
|
||||
def __init__(self, tag: str, protocol: XrayProtocol):
|
||||
self.tag = tag
|
||||
self.protocol = protocol
|
||||
self._settings = None
|
||||
self._listen = "0.0.0.0"
|
||||
self._port = None
|
||||
self._port_list = None
|
||||
self._stream_settings = None
|
||||
self._sniffing = None
|
||||
|
||||
def listen(self, address: str) -> 'InboundBuilder':
|
||||
"""Set listen address"""
|
||||
self._listen = address
|
||||
return self
|
||||
|
||||
def port(self, port: int) -> 'InboundBuilder':
|
||||
"""Set single port"""
|
||||
self._port = port
|
||||
self._port_list = None
|
||||
return self
|
||||
|
||||
def port_range(self, start: int, end: int) -> 'InboundBuilder':
|
||||
"""Set port range"""
|
||||
self._port_list = f"{start}-{end}"
|
||||
self._port = None
|
||||
return self
|
||||
|
||||
def stream_settings(self, settings: StreamSettings) -> 'InboundBuilder':
|
||||
"""Set stream settings"""
|
||||
self._stream_settings = settings
|
||||
return self
|
||||
|
||||
def sniffing(self, enabled: bool = True, dest_override: Optional[List[str]] = None) -> 'InboundBuilder':
|
||||
"""Configure sniffing"""
|
||||
self._sniffing = SniffingConfig(
|
||||
enabled=enabled,
|
||||
destOverride=dest_override
|
||||
)
|
||||
return self
|
||||
|
||||
def protocol_settings(self, settings: Union[VLESSInboundConfig, VMeSSInboundConfig, TrojanServerConfig, ShadowsocksServerConfig]) -> 'InboundBuilder':
|
||||
"""Set protocol-specific settings"""
|
||||
self._settings = settings
|
||||
return self
|
||||
|
||||
def build(self) -> InboundConfig:
|
||||
"""Build the inbound configuration"""
|
||||
if not self._settings:
|
||||
raise ValueError("Protocol settings must be specified")
|
||||
|
||||
if not self._port and not self._port_list:
|
||||
raise ValueError("Either port or port range must be specified")
|
||||
|
||||
return InboundConfig(
|
||||
tag=self.tag,
|
||||
protocol=self.protocol,
|
||||
settings=self._settings,
|
||||
listen=self._listen,
|
||||
port=self._port,
|
||||
portList=self._port_list,
|
||||
streamSettings=self._stream_settings,
|
||||
sniffing=self._sniffing
|
||||
)
|
Reference in New Issue
Block a user