log handler base functionality
+ fix makefile ios-temp-prepare upgrading pub + remove tvOS from libcore local spm +
This commit is contained in:
2
Makefile
2
Makefile
@@ -159,7 +159,7 @@ release: # Create a new tag for release.
|
||||
ios-temp-prepare:
|
||||
flutter upgrade
|
||||
flutter clean
|
||||
flutter pub upgrade
|
||||
# flutter pub upgrade
|
||||
make prepare platform=ios
|
||||
# make get-geo-assets
|
||||
# make get
|
||||
|
||||
@@ -7,8 +7,7 @@ let package = Package(
|
||||
name: "Libcore",
|
||||
platforms: [
|
||||
// Minimum platform version
|
||||
.iOS(.v13),
|
||||
.tvOS(.v13)
|
||||
.iOS(.v13)
|
||||
],
|
||||
products: [
|
||||
.library(
|
||||
|
||||
@@ -19,6 +19,9 @@ public class LogsEventHandler: NSObject, FlutterPlugin, FlutterStreamHandler {
|
||||
}
|
||||
|
||||
public func onListen(withArguments arguments: Any?, eventSink events: @escaping FlutterEventSink) -> FlutterError? {
|
||||
if VPNManager.shared.logCallback {
|
||||
events(VPNManager.shared.logList)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
|
||||
@@ -39,6 +39,8 @@ class VPNManager: ObservableObject {
|
||||
@Published private(set) var upload: Int64 = 0
|
||||
@Published private(set) var download: Int64 = 0
|
||||
@Published private(set) var elapsedTime: TimeInterval = 0
|
||||
@Published private(set) var logList: [String] = []
|
||||
@Published private(set) var logCallback = false
|
||||
|
||||
private var _connectTime: Date?
|
||||
private var connectTime: Date? {
|
||||
@@ -83,30 +85,42 @@ class VPNManager: ObservableObject {
|
||||
func setup() async throws {
|
||||
// guard !loaded else { return }
|
||||
loaded = true
|
||||
try await loadVPNPreference()
|
||||
do {
|
||||
try await loadVPNPreference()
|
||||
} catch {
|
||||
onServiceWriteLog(message: error.localizedDescription)
|
||||
}
|
||||
}
|
||||
|
||||
private func loadVPNPreference() async throws {
|
||||
let managers = try await NETunnelProviderManager.loadAllFromPreferences()
|
||||
if let manager = managers.first {
|
||||
self.manager = manager
|
||||
return
|
||||
do {
|
||||
let managers = try await NETunnelProviderManager.loadAllFromPreferences()
|
||||
if let manager = managers.first {
|
||||
self.manager = manager
|
||||
return
|
||||
}
|
||||
let newManager = NETunnelProviderManager()
|
||||
let `protocol` = NETunnelProviderProtocol()
|
||||
`protocol`.providerBundleIdentifier = "app.hiddify.com.SingBoxPacketTunnel"
|
||||
`protocol`.serverAddress = "localhost"
|
||||
newManager.protocolConfiguration = `protocol`
|
||||
newManager.localizedDescription = "Hiddify"
|
||||
try await newManager.saveToPreferences()
|
||||
try await newManager.loadFromPreferences()
|
||||
self.manager = newManager
|
||||
} catch {
|
||||
onServiceWriteLog(message: error.localizedDescription)
|
||||
}
|
||||
let newManager = NETunnelProviderManager()
|
||||
let `protocol` = NETunnelProviderProtocol()
|
||||
`protocol`.providerBundleIdentifier = "app.hiddify.com.SingBoxPacketTunnel"
|
||||
`protocol`.serverAddress = "localhost"
|
||||
newManager.protocolConfiguration = `protocol`
|
||||
newManager.localizedDescription = "Hiddify"
|
||||
try await newManager.saveToPreferences()
|
||||
try await newManager.loadFromPreferences()
|
||||
self.manager = newManager
|
||||
}
|
||||
|
||||
private func enableVPNManager() async throws {
|
||||
manager.isEnabled = true
|
||||
try await manager.saveToPreferences()
|
||||
try await manager.loadFromPreferences()
|
||||
do {
|
||||
try await manager.saveToPreferences()
|
||||
try await manager.loadFromPreferences()
|
||||
} catch {
|
||||
onServiceWriteLog(message: error.localizedDescription)
|
||||
}
|
||||
}
|
||||
|
||||
@MainActor private func set(upload: Int64, download: Int64) {
|
||||
@@ -121,7 +135,7 @@ class VPNManager: ObservableObject {
|
||||
return false
|
||||
}
|
||||
for key: String in keys.allKeys as! [String] {
|
||||
if (key == "tap" || key == "tun" || key == "ppp" || key == "ipsec" || key == "ipsec0" || key == "utun1" || key == "utun2") {
|
||||
if key == "tap" || key == "tun" || key == "ppp" || key == "ipsec" || key == "ipsec0" {
|
||||
return true
|
||||
} else if key.starts(with: "utun") {
|
||||
return true
|
||||
@@ -138,11 +152,15 @@ class VPNManager: ObservableObject {
|
||||
$state.filter { $0 == .disconnected || $0 == .invalid }.first().sink { [weak self] _ in
|
||||
Task { [weak self] () in
|
||||
self?.manager = .shared()
|
||||
let managers = try? await NETunnelProviderManager.loadAllFromPreferences()
|
||||
for manager in managers ?? [] {
|
||||
try? await manager.removeFromPreferences()
|
||||
do {
|
||||
let managers = try await NETunnelProviderManager.loadAllFromPreferences()
|
||||
for manager in managers ?? [] {
|
||||
try await manager.removeFromPreferences()
|
||||
}
|
||||
try await self?.loadVPNPreference()
|
||||
} catch {
|
||||
onServiceWriteLog(message: error.localizedDescription)
|
||||
}
|
||||
try? await self?.loadVPNPreference()
|
||||
}
|
||||
}.store(in: &cancelBag)
|
||||
|
||||
@@ -155,31 +173,39 @@ class VPNManager: ObservableObject {
|
||||
}
|
||||
guard state == .connected else { return }
|
||||
guard let connection = manager.connection as? NETunnelProviderSession else { return }
|
||||
try? connection.sendProviderMessage("stats".data(using: .utf8)!) { [weak self] response in
|
||||
guard
|
||||
let response,
|
||||
let response = String(data: response, encoding: .utf8)
|
||||
else { return }
|
||||
let responseComponents = response.components(separatedBy: ",")
|
||||
guard
|
||||
responseComponents.count == 2,
|
||||
let upload = Int64(responseComponents[0]),
|
||||
let download = Int64(responseComponents[1])
|
||||
else { return }
|
||||
Task { [upload, download, weak self] () in
|
||||
await self?.set(upload: upload, download: download)
|
||||
do {
|
||||
try connection.sendProviderMessage("stats".data(using: .utf8)!) { [weak self] response in
|
||||
guard
|
||||
let response,
|
||||
let response = String(data: response, encoding: .utf8)
|
||||
else { return }
|
||||
let responseComponents = response.components(separatedBy: ",")
|
||||
guard
|
||||
responseComponents.count == 2,
|
||||
let upload = Int64(responseComponents[0]),
|
||||
let download = Int64(responseComponents[1])
|
||||
else { return }
|
||||
Task { [upload, download, weak self] () in
|
||||
await self?.set(upload: upload, download: download)
|
||||
}
|
||||
}
|
||||
} catch {
|
||||
onServiceWriteLog(message: error.localizedDescription)
|
||||
}
|
||||
}
|
||||
|
||||
func connect(with config: String, disableMemoryLimit: Bool = false) async throws {
|
||||
await set(upload: 0, download: 0)
|
||||
guard state == .disconnected else { return }
|
||||
try await enableVPNManager()
|
||||
try manager.connection.startVPNTunnel(options: [
|
||||
"Config": config as NSString,
|
||||
"DisableMemoryLimit": (disableMemoryLimit ? "YES" : "NO") as NSString,
|
||||
])
|
||||
do {
|
||||
try await enableVPNManager()
|
||||
try manager.connection.startVPNTunnel(options: [
|
||||
"Config": config as NSString,
|
||||
"DisableMemoryLimit": (disableMemoryLimit ? "YES" : "NO") as NSString,
|
||||
])
|
||||
} catch {
|
||||
onServiceWriteLog(message: error.localizedDescription)
|
||||
}
|
||||
connectTime = .now
|
||||
}
|
||||
|
||||
@@ -188,5 +214,16 @@ class VPNManager: ObservableObject {
|
||||
manager.connection.stopVPNTunnel()
|
||||
}
|
||||
|
||||
}
|
||||
func onServiceWriteLog(message: String) {
|
||||
logCallback = true
|
||||
if logList.count > 300 {
|
||||
logList.removeFirst()
|
||||
}
|
||||
logList.append(message)
|
||||
}
|
||||
|
||||
func onServiceResetLogs() {
|
||||
logCallback = false
|
||||
logList.removeAll()
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user