init commit
This commit is contained in:
128
core/models.go
Normal file
128
core/models.go
Normal file
@@ -0,0 +1,128 @@
|
||||
package core
|
||||
|
||||
// ConnectionState represents VPN connection state.
|
||||
type ConnectionState int
|
||||
|
||||
const (
|
||||
Disconnected ConnectionState = iota
|
||||
Connecting
|
||||
Connected
|
||||
Disconnecting
|
||||
Error
|
||||
)
|
||||
|
||||
func (s ConnectionState) String() string {
|
||||
switch s {
|
||||
case Disconnected:
|
||||
return "Disconnected"
|
||||
case Connecting:
|
||||
return "Connecting"
|
||||
case Connected:
|
||||
return "Connected"
|
||||
case Disconnecting:
|
||||
return "Disconnecting"
|
||||
case Error:
|
||||
return "Error"
|
||||
default:
|
||||
return "Unknown"
|
||||
}
|
||||
}
|
||||
|
||||
// ProxyLink represents a parsed VPN link (trojan://, vless://, etc.)
|
||||
type ProxyLink struct {
|
||||
// Protocol: trojan, vless, vmess, shadowsocks
|
||||
Protocol string
|
||||
// Server IP or domain
|
||||
Address string
|
||||
// Server port
|
||||
Port int
|
||||
// Password (trojan) or UUID (vless/vmess)
|
||||
Credential string
|
||||
// Security type: reality, tls, none
|
||||
Security string
|
||||
// Server Name Indication for TLS/REALITY
|
||||
Sni string
|
||||
// TLS fingerprint (chrome, firefox, safari, etc.)
|
||||
Fingerprint string
|
||||
// REALITY public key
|
||||
PublicKey string
|
||||
// REALITY short ID
|
||||
ShortId string
|
||||
// Transport type: tcp, grpc, ws, h2, xhttp
|
||||
Transport string
|
||||
// gRPC service name
|
||||
ServiceName string
|
||||
// WebSocket/HTTP2 path
|
||||
Path string
|
||||
// Host header for WebSocket/HTTP2
|
||||
Host string
|
||||
// Server name from link fragment (#remark)
|
||||
Remark string
|
||||
// XTLS Flow (e.g. xtls-rprx-vision)
|
||||
Flow string
|
||||
}
|
||||
|
||||
func (p *ProxyLink) String() string {
|
||||
return "[" + p.Protocol + "] " + p.Remark + " (" + p.Address + ":" + itoa(p.Port) + ") security=" + p.Security + " transport=" + p.Transport
|
||||
}
|
||||
|
||||
// VpnConfig represents a saved VPN configuration.
|
||||
type VpnConfig struct {
|
||||
ID string `json:"Id"`
|
||||
Name string `json:"Name"`
|
||||
Link string `json:"Link"`
|
||||
}
|
||||
|
||||
func (c *VpnConfig) DisplayName() string {
|
||||
if c.Name == "" {
|
||||
return "Unknown Server"
|
||||
}
|
||||
return c.Name
|
||||
}
|
||||
|
||||
func (c *VpnConfig) ProtocolType() string {
|
||||
if len(c.Link) < 5 {
|
||||
return "UNKNOWN"
|
||||
}
|
||||
switch {
|
||||
case hasPrefix(c.Link, "vless://"):
|
||||
return "VLESS"
|
||||
case hasPrefix(c.Link, "trojan://"):
|
||||
return "TROJAN"
|
||||
case hasPrefix(c.Link, "hy2://"):
|
||||
return "HYSTERIA2"
|
||||
case hasPrefix(c.Link, "ss://"):
|
||||
return "SHADOWSOCKS"
|
||||
default:
|
||||
return "UNKNOWN"
|
||||
}
|
||||
}
|
||||
|
||||
// ExtractNameFromLink extracts server name from a VPN link.
|
||||
func ExtractNameFromLink(link string) string {
|
||||
if link == "" {
|
||||
return "New Config"
|
||||
}
|
||||
idx := lastIndexOf(link, '#')
|
||||
if idx >= 0 && idx < len(link)-1 {
|
||||
encoded := link[idx+1:]
|
||||
decoded, err := urlUnescape(encoded)
|
||||
if err != nil {
|
||||
return encoded
|
||||
}
|
||||
return decoded
|
||||
}
|
||||
parts := splitAt(link, '@')
|
||||
if len(parts) > 1 {
|
||||
addrPart := parts[1]
|
||||
for i, ch := range addrPart {
|
||||
if ch == '?' || ch == ':' || ch == '/' || ch == '#' {
|
||||
if i > 0 {
|
||||
return addrPart[:i]
|
||||
}
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
return "Custom Config"
|
||||
}
|
||||
Reference in New Issue
Block a user