Skip to content

Commit

Permalink
fix import and share vless
Browse files Browse the repository at this point in the history
  • Loading branch information
yanue committed Jun 6, 2021
1 parent db0f515 commit 0f2bce4
Show file tree
Hide file tree
Showing 5 changed files with 188 additions and 57 deletions.
69 changes: 68 additions & 1 deletion V2rayU/Import.swift
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ class ImportUri {
}
if uri.hasPrefix("vless://") {
let importUri = ImportUri()
importUri.importVmessUri(uri: uri, id: id)
importUri.importVlessUri(uri: uri)
return importUri
}
if uri.hasPrefix("ss://") {
Expand Down Expand Up @@ -219,6 +219,73 @@ class ImportUri {
}
}

func importVlessUri(uri: String, id: String = "") {
if URL(string: uri) == nil {
self.error = "invalid vless url"
return
}

self.uri = uri

let vmess = VlessUri()
vmess.Init(url: URL(string: uri)!)
if vmess.error.count > 0 {
self.error = vmess.error
return
}
self.remark = vmess.remark
print("vmess", vmess)
let v2ray = V2rayConfig()
v2ray.serverProtocol = V2rayProtocolOutbound.vless.rawValue

var vmessItem = V2rayOutboundVLessItem()
vmessItem.address = vmess.address
vmessItem.port = vmess.port
var user = V2rayOutboundVLessUser()
user.id = vmess.id
user.flow = vmess.flow
user.encryption = vmess.encryption
user.level = vmess.level
vmessItem.users = [user]
v2ray.serverVless = vmessItem

// stream
v2ray.streamNetwork = vmess.type
v2ray.streamTlsSecurity = vmess.security

// tls servername for h2 or ws
if (vmess.type == V2rayStreamSettings.network.h2.rawValue || vmess.type == V2rayStreamSettings.network.ws.rawValue) {
v2ray.streamTlsServerName = vmess.host
}

// kcp
v2ray.streamKcp.header.type = vmess.type

// h2
v2ray.streamH2.host[0] = vmess.host
v2ray.streamH2.path = vmess.path

// ws
v2ray.streamWs.path = vmess.path
v2ray.streamWs.headers.host = vmess.host

// tcp
v2ray.streamTcp.header.type = vmess.type

// quic
v2ray.streamQuic.header.type = vmess.type

// check is valid
v2ray.checkManualValid()
if v2ray.isValid {
self.isValid = true
self.json = v2ray.combineManual()
} else {
self.error = v2ray.error
self.isValid = false
}
}

func importTrojanUri(uri: String) {
if URL(string: uri) == nil {
self.error = "invalid ssr url"
Expand Down
36 changes: 36 additions & 0 deletions V2rayU/Share.swift
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,11 @@ class ShareUri {
return
}

if v2ray.serverProtocol == V2rayProtocolOutbound.vless.rawValue {
self.genVlessUri()
return
}

if v2ray.serverProtocol == V2rayProtocolOutbound.shadowsocks.rawValue {
self.genShadowsocksUri()
return
Expand Down Expand Up @@ -131,4 +136,35 @@ class ShareUri {
self.uri = ss.encode()
self.error = ss.error
}

func genVlessUri() {
let ss = VlessUri()
ss.address = self.v2ray.serverVless.address
ss.port = self.v2ray.serverVless.port

ss.id = self.v2ray.serverVless.users[0].id
ss.level = self.v2ray.serverVless.users[0].level
ss.flow = self.v2ray.serverVless.users[0].flow
ss.encryption = self.v2ray.serverVless.users[0].encryption

ss.remark = self.remark

ss.security = self.v2ray.streamTlsSecurity

ss.type = self.v2ray.streamNetwork

if self.v2ray.streamNetwork == "h2" {
ss.host = self.v2ray.streamH2.host[0]
ss.path = self.v2ray.streamH2.path
}

if self.v2ray.streamNetwork == "ws" {
ss.host = self.v2ray.streamWs.headers.host
ss.path = self.v2ray.streamWs.path
}

self.uri = ss.encode()
self.error = ss.error
}

}
121 changes: 67 additions & 54 deletions V2rayU/Uri.swift
Original file line number Diff line number Diff line change
Expand Up @@ -446,75 +446,88 @@ class VlessUri {
var address: String = ""
var port: Int = 0
var id: String = ""

var level: Int = 0
var flow: String = ""

var encryption: String = "" // auto,aes-128-gcm,...
var security: String = "" // xtls,tls

var network: String = "tcp"
var netHost: String = ""
var netPath: String = ""

var headerType: String = ""

var type: String = "none"
var uplinkCapacity: Int = 50
var downlinkCapacity: Int = 20
var allowInsecure: Bool = false
var tlsServer: String = ""
var mux: Bool = true
var muxConcurrency: Int = 8

func parseType1(url: URL) {
let urlStr = url.absoluteString
// vless://
let base64Begin = urlStr.index(urlStr.startIndex, offsetBy: 8)
let base64End = urlStr.firstIndex(of: "?")
let encodedStr = String(urlStr[base64Begin..<(base64End ?? urlStr.endIndex)])
var type: String = "" // tcp,http
var host: String = ""
var sni: String = ""
var path: String = ""

var paramsStr: String = ""
if base64End != nil {
let paramsAll = urlStr.components(separatedBy: "?")
paramsStr = paramsAll[1]
}
// vless://[email protected]:443?flow=xtls-rprx-splite&encryption=none&security=xtls&sni=aaaaa&type=http&host=00.com&path=%2fvl#vless1
func encode() -> String {
var uri = URLComponents()
uri.scheme = "vless"
uri.user = self.id
uri.host = self.address
uri.port = self.port
uri.queryItems = [
URLQueryItem(name: "flow", value: self.flow),
URLQueryItem(name: "encryption", value: self.encryption),
URLQueryItem(name: "type", value: self.type),
URLQueryItem(name: "host", value: self.host),
URLQueryItem(name: "path", value: self.path),
URLQueryItem(name: "sni", value: self.sni),
]

return uri.url?.absoluteString ?? "" + "#" + self.remark
}

guard let decodeStr = encodedStr.base64Decoded() else {
self.error = "error decode Str"
func Init(url: URL) {
guard let address = url.host else {
self.error = "error:missing host"
return
}
print("decodeStr", decodeStr)
// main
var uuid_ = ""
var host_ = ""
let mainArr = decodeStr.components(separatedBy: "@")
if mainArr.count > 1 {
uuid_ = mainArr[0]
host_ = mainArr[1]
}

let uuid_security = uuid_.components(separatedBy: ":")
if uuid_security.count > 1 {
self.security = uuid_security[0]
self.id = uuid_security[1]
guard let port = url.port else {
self.error = "error:missing port"
return
}

let host_port = host_.components(separatedBy: ":")
if host_port.count > 1 {
self.address = host_port[0]
self.port = Int(host_port[1]) ?? 0
guard let id = url.user else {
self.error = "error:missing id"
return
}
print("VmessUri self", self)

// params
let params = paramsStr.components(separatedBy: "&")
for item in params {
var param = item.components(separatedBy: "=")
switch param[0] {
self.address = address
self.port = Int(port)
self.id = id
let queryItems = url.queryParams()
for item in queryItems {
switch item.key {
case "level":
self.level = item.value as! Int
break
case "flow":
self.flow = item.value as! String
break
case "encryption":
self.encryption = item.value as! String
if self.encryption.count == 0 {
self.encryption = "none"
}
break
case "security":
self.security = item.value as! String
break
case "type":
self.type = item.value as! String
break
case "host":
self.host = item.value as! String
break
case "sni":
self.sni = item.value as! String
break
case "path":
self.path = item.value as! String
break
default:
break
}
}
}

self.remark = url.fragment ?? "vless"
}
}
17 changes: 17 additions & 0 deletions V2rayU/Util.swift
Original file line number Diff line number Diff line change
Expand Up @@ -252,3 +252,20 @@ extension FileManager {
func getAppVersion() -> String {
return "\(Bundle.main.infoDictionary!["CFBundleShortVersionString"] ?? "")"
}

extension URL {
func queryParams() -> [String: Any] {
var dict = [String: Any]()

if let components = URLComponents(url: self, resolvingAgainstBaseURL: false) {
if let queryItems = components.queryItems {
for item in queryItems {
dict[item.name] = item.value!
}
}
return dict
} else {
return [:]
}
}
}
2 changes: 0 additions & 2 deletions V2rayU/ping.swift
Original file line number Diff line number Diff line change
Expand Up @@ -87,8 +87,6 @@ class PingSpeed: NSObject {

DispatchQueue.main.async {
menuController.statusMenu.item(withTag: 1)?.title = "\(normalTitle)"
print(" // refresh server menuController.showServers()")
// refresh servers
// reload
V2rayServer.loadConfig()

Expand Down

0 comments on commit 0f2bce4

Please sign in to comment.