Release 3.8.2.13: iOS Packet Tunnel client and Clash URL subscriptions.
Add SwiftUI + Network Extension (LibXray/hev), parse Clash Meta YAML from subscription URLs into vless/trojan/hy2 share links, keep the selected server on connect, and ship Navis-3.8.2.13.ipa with versioned changelog. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -0,0 +1,85 @@
|
||||
import Foundation
|
||||
import LibXray
|
||||
|
||||
/// Thin wrapper around LibXray.Invoke (macOS Manager engine.Start for Xray).
|
||||
enum LibXrayCore {
|
||||
struct InvokeError: LocalizedError {
|
||||
var message: String
|
||||
var errorDescription: String? { message }
|
||||
}
|
||||
|
||||
static func runJSON(_ configJSON: String) throws {
|
||||
let payload: [String: Any] = [
|
||||
"apiVersion": 1,
|
||||
"method": "runXrayFromJson",
|
||||
"payload": ["configJSON": configJSON],
|
||||
]
|
||||
try invoke(payload)
|
||||
}
|
||||
|
||||
static func runFile(_ configPath: String) throws {
|
||||
let payload: [String: Any] = [
|
||||
"apiVersion": 1,
|
||||
"method": "runXray",
|
||||
"payload": ["configPath": configPath],
|
||||
]
|
||||
try invoke(payload)
|
||||
}
|
||||
|
||||
static func stop() {
|
||||
let payload: [String: Any] = [
|
||||
"apiVersion": 1,
|
||||
"method": "stopXray",
|
||||
"payload": [:] as [String: Any],
|
||||
]
|
||||
_ = try? invoke(payload)
|
||||
}
|
||||
|
||||
static func isRunning() -> Bool {
|
||||
let payload: [String: Any] = [
|
||||
"apiVersion": 1,
|
||||
"method": "getXrayState",
|
||||
"payload": [:] as [String: Any],
|
||||
]
|
||||
guard let data = try? invokeData(payload),
|
||||
let running = data["running"] as? Bool
|
||||
else { return false }
|
||||
return running
|
||||
}
|
||||
|
||||
static func version() -> String {
|
||||
let payload: [String: Any] = [
|
||||
"apiVersion": 1,
|
||||
"method": "xrayVersion",
|
||||
"payload": [:] as [String: Any],
|
||||
]
|
||||
guard let data = try? invokeData(payload),
|
||||
let v = data["version"] as? String
|
||||
else { return "?" }
|
||||
return v
|
||||
}
|
||||
|
||||
@discardableResult
|
||||
private static func invoke(_ payload: [String: Any]) throws -> [String: Any]? {
|
||||
let data = try invokeData(payload)
|
||||
return data
|
||||
}
|
||||
|
||||
private static func invokeData(_ payload: [String: Any]) throws -> [String: Any]? {
|
||||
let reqData = try JSONSerialization.data(withJSONObject: payload)
|
||||
guard let req = String(data: reqData, encoding: .utf8) else {
|
||||
throw InvokeError(message: "encode invoke request")
|
||||
}
|
||||
let respStr = LibXrayInvoke(req)
|
||||
guard let respData = respStr.data(using: .utf8),
|
||||
let obj = try JSONSerialization.jsonObject(with: respData) as? [String: Any]
|
||||
else {
|
||||
throw InvokeError(message: "decode invoke response")
|
||||
}
|
||||
let ok = obj["success"] as? Bool ?? false
|
||||
if !ok {
|
||||
throw InvokeError(message: (obj["error"] as? String) ?? "LibXray error")
|
||||
}
|
||||
return obj["data"] as? [String: Any]
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user