Skip to content

Commit

Permalink
fix
Browse files Browse the repository at this point in the history
  • Loading branch information
yanue committed Dec 26, 2024
1 parent 6f22ee4 commit 0d808ad
Show file tree
Hide file tree
Showing 22 changed files with 395 additions and 637 deletions.
84 changes: 64 additions & 20 deletions V2rayU.xcodeproj/project.pbxproj

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion V2rayU/Base/Scanner.swift
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ class Scanner {
for i in 0 ..< displayCount {
let str = getQrcodeStr(displayID: activeDisplays[Int(i)])
// support: ss:// | ssr:// | vmess://
if ImportUri.supportProtocol(uri: str) {
if supportProtocol(uri: str) {
qrStr = str
break
}
Expand Down
11 changes: 11 additions & 0 deletions V2rayU/Database/Models/ProfileModel.swift
Original file line number Diff line number Diff line change
Expand Up @@ -221,4 +221,15 @@ extension ProfileModel: TableRecord, FetchableRecord, PersistableRecord {
}
}
}

func save() {
do {
let dbWriter = AppDatabase.shared.dbWriter
try dbWriter.write { db in
try self.save(db)
}
} catch {
print("save error: \(error)")
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import Combine
import GRDB
import Foundation

class ProxyViewModel: ObservableObject {
class ProfileViewModel: ObservableObject {
@Published var list: [ProfileModel] = []
@Published var groups: [String] = []

Expand All @@ -24,7 +24,7 @@ class ProxyViewModel: ObservableObject {
}
}

func all() -> [ProfileModel] {
static func all() -> [ProfileModel] {
do {
let dbReader = AppDatabase.shared.reader
return try dbReader.read { db in
Expand All @@ -40,7 +40,7 @@ class ProxyViewModel: ObservableObject {
let dbReader = AppDatabase.shared.reader
return try dbReader.read { db in
guard let model = try ProfileModel.filter(ProfileModel.Columns.uuid == uuid).fetchOne(db) else {
throw NSError(domain: "ProxyViewModel", code: 404, userInfo: [NSLocalizedDescriptionKey: "ProfileModel not found for uuid: \(uuid)"])
throw NSError(domain: "ProfileViewModel", code: 404, userInfo: [NSLocalizedDescriptionKey: "ProfileModel not found for uuid: \(uuid)"])
}
return model
}
Expand Down
17 changes: 9 additions & 8 deletions V2rayU/Handler/ImportHandler.swift
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,13 @@ func importUri(url: String) {
}
}

func supportProtocol(uri: String) -> Bool {
if uri.hasPrefix("ss://") || uri.hasPrefix("ssr://") || uri.hasPrefix("vmess://") || uri.hasPrefix("vless://") || uri.hasPrefix("trojan://") {
return true
}
return false
}

class ImportUri {
var isValid: Bool = false
var error: String = ""
Expand All @@ -44,7 +51,7 @@ class ImportUri {
var url = URL(string: share_uri)
if url == nil {
// 标准url不支持非url-encoded
let aUri = uri.split(separator: "#")
let aUri = self.share_uri.split(separator: "#")
url = URL(string: String(aUri[0]))
if url == nil {
self.error = "invalid url"
Expand Down Expand Up @@ -73,7 +80,7 @@ class ImportUri {

// 解析 URI
if let handler = uriHandler {
let parseError = handler.parse(url: url)
let parseError = handler.parse(url: url!)
if let error = parseError {
// 如果解析失败,返回 nil
return nil
Expand All @@ -89,10 +96,4 @@ class ImportUri {
return nil
}

func supportProtocol(uri: String) -> Bool {
if uri.hasPrefix("ss://") || uri.hasPrefix("ssr://") || uri.hasPrefix("vmess://") || uri.hasPrefix("vless://") || uri.hasPrefix("trojan://") {
return true
}
return false
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,27 +4,22 @@ import Foundation
// ssr://server:port:protocol:method:obfs:password_base64/?params_base64
// 上面的链接的不同之处在于 password_base64 和 params_base64 ,顾名思义,password_base64 就是密码被 base64编码 后的字符串,而 params_base64 则是协议参数、混淆参数、备注及Group对应的参数值被 base64编码 后拼接而成的字符串。

class ShadowsockRUri: ShadowsocksUri {

private var profile: ProfileModel
private var error: String?

class ShadowsocksRUri: ShadowsocksUri {
// 初始化
init() {
self.profile = ProfileModel(remark: "ss",`protocol`: .ss)
override init() {
super.init()
}

// 从 ProfileModel 初始化
init(from model: ProfileModel) {
// 通过传入的 model 初始化 Profile 类的所有属性
self.profile = model
required init(from model: ProfileModel) {
super.init(from: model)
}

func getProfile() -> ProfileModel {
override func getProfile() -> ProfileModel {
return self.profile
}

func parse(url: URL) -> Error? {
override func parse(url: URL) -> Error? {
let (_decodedUrl, _tag) = self.decodeUrl(url: url)
guard let decodedUrl = _decodedUrl else {
return NSError(domain: "ShadowsocksUriError", code: 1001, userInfo: [NSLocalizedDescriptionKey: "error: decodeUrl"])
Expand All @@ -45,7 +40,7 @@ class ShadowsockRUri: ShadowsocksUri {
self.profile.port = aPort
}

self.profile.method = method.lowercased()
self.profile.encryption = method.lowercased()
if let tag = _tag {
self.profile.remark = tag.urlDecoded()
}
Expand All @@ -54,6 +49,7 @@ class ShadowsockRUri: ShadowsocksUri {
return NSError(domain: "ShadowsocksUriError", code: 1001, userInfo: [NSLocalizedDescriptionKey: "URL: password decode error"])
}
self.profile.password = password
return nil
}

override func decodeUrl(url: URL) -> (String?, String?) {
Expand Down Expand Up @@ -83,4 +79,4 @@ class ShadowsockRUri: ShadowsocksUri {

return (s, nil)
}
}
}
Original file line number Diff line number Diff line change
@@ -1,18 +1,17 @@
import Foundation

// link: https://github.com/shadowsocks/ShadowsocksX-NG
class ShadowsocksUri {

private var profile: ProfileModel
private var error: String?
class ShadowsocksUri: BaseShareUri {
var profile: ProfileModel
var error: String?

// 初始化
init() {
self.profile = ProfileModel(remark: "ss",`protocol`: .ss)
self.profile = ProfileModel(remark: "ss", `protocol`: .shadowsocks)
}

// 从 ProfileModel 初始化
init(from model: ProfileModel) {
required init(from model: ProfileModel) {
// 通过传入的 model 初始化 Profile 类的所有属性
self.profile = model
}
Expand All @@ -21,20 +20,12 @@ class ShadowsocksUri {
return self.profile
}

var host: String = ""
var port: Int = 8379
var method: String = "aes-128-gcm"
var password: String = ""
var remark: String = ""

var error: String = ""

// ss://bf-cfb:test@192.168.100.1:8888#remark
func encode() -> String {
let base64 = self.method + ":" + self.password + "@" + self.host + ":" + String(self.port)
let base64 = self.profile.encryption + ":" + self.profile.password + "@" + self.profile.host + ":" + String(self.profile.port)
let ss = base64.base64Encoded()
if ss != nil {
return "ss://" + ss! + "#" + self.remark
return "ss://" + ss! + "#" + self.profile.remark.urlEncoded()
}
self.error = "encode base64 fail"
return ""
Expand Down Expand Up @@ -65,7 +56,7 @@ class ShadowsocksUri {
self.profile.remark = (parsedUrl.queryItems?.filter({ $0.name == "Remark" }).first?.value ?? _tag ?? "").urlDecoded()

if let password = parsedUrl.password {
self.profile.method = user.lowercased()
self.profile.encryption = user.lowercased()
self.profile.password = password
if let tag = _tag {
self.profile.remark = tag
Expand All @@ -89,6 +80,7 @@ class ShadowsocksUri {
self.profile.remark = profileName.urlDecoded()
}
}
return nil
}

func decodeUrl(url: URL) -> (String?, String?) {
Expand Down Expand Up @@ -121,4 +113,4 @@ class ShadowsocksUri {
return string.padding(toLength: length, withPad: "=", startingAt: 0)
}
}
}
}
47 changes: 23 additions & 24 deletions V2rayU/Handler/Share/TrojanUri.swift
Original file line number Diff line number Diff line change
Expand Up @@ -2,39 +2,38 @@ import Foundation

// trojan
class TrojanUri: BaseShareUri {

private var profile: ProfileModel
private var error: String?

// 初始化
init() {
self.profile = ProfileModel(remark: "trojan",`protocol`: .trojan)
profile = ProfileModel(remark: "trojan", protocol: .trojan)
}

// 从 ProfileModel 初始化
init(from model: ProfileModel) {
required init(from model: ProfileModel) {
// 通过传入的 model 初始化 Profile 类的所有属性
self.profile = model
profile = model
}

func getProfile() -> ProfileModel {
return self.profile
return profile
}

// trojan://pass@remote_host:443?flow=xtls-rprx-origin&security=xtls&sni=sni&host=remote_host#trojan
func encode() -> String {
var uri = URLComponents()
uri.scheme = "trojan"
uri.password = self.password
uri.host = self.host
uri.port = self.port
uri.password = profile.password
uri.host = profile.address
uri.port = profile.port
uri.queryItems = [
URLQueryItem(name: "flow", value: self.flow),
URLQueryItem(name: "security", value: self.security),
URLQueryItem(name: "sni", value: self.sni),
URLQueryItem(name: "fp", value: self.fingerprint),
URLQueryItem(name: "flow", value: profile.flow),
URLQueryItem(name: "security", value: profile.security.rawValue),
URLQueryItem(name: "sni", value: profile.sni),
URLQueryItem(name: "fp", value: profile.fingerprint.rawValue),
]
return (uri.url?.absoluteString ?? "") + "#" + self.remark
return (uri.url?.absoluteString ?? "") + "#" + profile.remark.urlEncoded()
}

func parse(url: URL) -> Error? {
Expand All @@ -48,31 +47,31 @@ class TrojanUri: BaseShareUri {
return NSError(domain: "TrojanUriError", code: 1003, userInfo: [NSLocalizedDescriptionKey: "Missing password"])
}

self.profile.host = host
self.profile.port = port
self.profile.password = password
profile.host = host
profile.port = port
profile.password = password

let queryItems = url.queryParams()
for item in queryItems {
switch item.key {
case "sni":
self.profile.sni = item.value as? String ?? ""
profile.sni = item.value as? String ?? ""
case "flow":
self.profile.flow = item.value as? String ?? ""
profile.flow = item.value as? String ?? ""
case "security":
self.profile.security = item.value as? String ?? ""
profile.security = V2rayStreamSecurity(rawValue: item.value as? String ?? "") ?? .none
case "fp":
self.profile.fingerprint = item.value as? String ?? ""
profile.fingerprint = V2rayStreamFingerprint(rawValue: item.value as? String ?? "") ?? .chrome
default:
break
}
}

if self.profile.security.isEmpty {
self.profile.security = "tls"
if profile.security == .none {
profile.security = .tls
}

self.profile.remark = (url.fragment ?? "trojan").urlDecoded()
profile.remark = (url.fragment ?? "trojan").urlDecoded()
return nil
}
}
}
Loading

0 comments on commit 0d808ad

Please sign in to comment.