update ios

This commit is contained in:
hiddify 2026-02-01 02:17:13 +03:30
parent c017e3cefe
commit a4a4780e02
9 changed files with 418 additions and 220 deletions

View File

@ -29,8 +29,9 @@ class PacketTunnelProvider: ExtensionProvider {
}
override func handleAppMessage(_ messageData: Data) async -> Data? {
NSLog("H?C2")
let message = String(data: messageData, encoding: .utf8)
// NSLog("H?C2"+message??"")
switch message {
case "stats":
return "\(upload),\(download)".data(using: .utf8)!

View File

@ -27,17 +27,20 @@ public class ExtensionPlatformInterface: NSObject, LibboxPlatformInterfaceProtoc
}
private func openTun0(_ options: LibboxTunOptionsProtocol?, _ ret0_: UnsafeMutablePointer<Int32>?) async throws {
NSLog("H?A2")
guard let options else {
throw NSError(domain: "nil options", code: 0)
throw NSError(domain: "ExtensionPlatformInterface", code: 0, userInfo: [NSLocalizedDescriptionKey: String(localized: "Nil options")])
}
guard let ret0_ else {
throw NSError(domain: "nil return pointer", code: 0)
throw NSError(domain: "ExtensionPlatformInterface", code: 0, userInfo: [NSLocalizedDescriptionKey: String(localized: "Nil return pointer")])
}
let autoRouteUseSubRangesByDefault = true// await SharedPreferences.autoRouteUseSubRangesByDefault.get()
let excludeAPNs = false //await SharedPreferences.excludeAPNsRoute.get()
// let prefs = tunnel.overridePreferences ?? ExtensionProvider.OverridePreferences()
let autoRouteUseSubRangesByDefault = true//prefs.autoRouteUseSubRangesByDefault // await SharedPreferences.autoRouteUseSubRangesByDefault.get()
let excludeAPNs = false//prefs.excludeAPNsRoute //await SharedPreferences.excludeAPNsRoute.get()
let excludeDefaultRoute = false// prefs.excludeDefaultRoute
let systemProxyEnabled = false//prefs.systemProxyEnabled
let settings = NEPacketTunnelNetworkSettings(tunnelRemoteAddress: "127.0.0.1")
if options.getAutoRoute() {
settings.mtu = NSNumber(value: options.getMTU())
@ -84,13 +87,13 @@ public class ExtensionPlatformInterface: NSObject, LibboxPlatformInterfaceProtoc
let ipv4RoutePrefix = inet4RouteExcludeAddressIterator.next()!
ipv4ExcludeRoutes.append(NEIPv4Route(destinationAddress: ipv4RoutePrefix.address(), subnetMask: ipv4RoutePrefix.mask()))
}
// if await SharedPreferences.excludeDefaultRoute.get(), !ipv4Routes.isEmpty {
// if !ipv4ExcludeRoutes.contains(where: { it in
// it.destinationAddress == "0.0.0.0" && it.destinationSubnetMask == "255.255.255.254"
// }) {
// ipv4ExcludeRoutes.append(NEIPv4Route(destinationAddress: "0.0.0.0", subnetMask: "255.255.255.254"))
// }
// }
if excludeDefaultRoute, !ipv4Routes.isEmpty {
if !ipv4ExcludeRoutes.contains(where: { it in
it.destinationAddress == "0.0.0.0" && it.destinationSubnetMask == "255.255.255.254"
}) {
ipv4ExcludeRoutes.append(NEIPv4Route(destinationAddress: "0.0.0.0", subnetMask: "255.255.255.254"))
}
}
if excludeAPNs, !ipv4Routes.isEmpty {
if !ipv4ExcludeRoutes.contains(where: { it in
it.destinationAddress == "17.0.0.0" && it.destinationSubnetMask == "255.0.0.0"
@ -138,7 +141,13 @@ public class ExtensionPlatformInterface: NSObject, LibboxPlatformInterfaceProtoc
let ipv6RoutePrefix = inet6RouteExcludeAddressIterator.next()!
ipv6ExcludeRoutes.append(NEIPv6Route(destinationAddress: ipv6RoutePrefix.address(), networkPrefixLength: NSNumber(value: ipv6RoutePrefix.prefix())))
}
if excludeDefaultRoute, !ipv6Routes.isEmpty {
if !ipv6ExcludeRoutes.contains(where: { it in
it.destinationAddress == "::" && it.destinationNetworkPrefixLength == 127
}) {
ipv6ExcludeRoutes.append(NEIPv6Route(destinationAddress: "::", networkPrefixLength: 127))
}
}
ipv6Settings.includedRoutes = ipv6Routes
ipv6Settings.excludedRoutes = ipv6ExcludeRoutes
settings.ipv6Settings = ipv6Settings
@ -149,10 +158,10 @@ public class ExtensionPlatformInterface: NSObject, LibboxPlatformInterfaceProtoc
let proxyServer = NEProxyServer(address: options.getHTTPProxyServer(), port: Int(options.getHTTPProxyServerPort()))
proxySettings.httpServer = proxyServer
proxySettings.httpsServer = proxyServer
// if await SharedPreferences.systemProxyEnabled.get() {
// proxySettings.httpEnabled = true
// proxySettings.httpsEnabled = true
// }
if systemProxyEnabled {
proxySettings.httpEnabled = true
proxySettings.httpsEnabled = true
}
var bypassDomains: [String] = []
let bypassDomainIterator = options.getHTTPProxyBypassDomain()!
@ -203,80 +212,212 @@ public class ExtensionPlatformInterface: NSObject, LibboxPlatformInterfaceProtoc
}
public func usePlatformAutoDetectControl() -> Bool {
true
false
}
public func autoDetectControl(_: Int32) throws {}
public func findConnectionOwner(_: Int32, sourceAddress _: String?, sourcePort _: Int32, destinationAddress _: String?, destinationPort _: Int32, ret0_ _: UnsafeMutablePointer<Int32>?) throws {
throw NSError(domain: "not implemented", code: 0)
}
public func packageName(byUid _: Int32, error _: NSErrorPointer) -> String {
""
}
public func uid(byPackageName _: String?, ret0_ _: UnsafeMutablePointer<Int32>?) throws {
throw NSError(domain: "not implemented", code: 0)
public func findConnectionOwner(_ ipProtocol: Int32, sourceAddress: String?, sourcePort: Int32, destinationAddress: String?, destinationPort: Int32) throws -> LibboxConnectionOwner {
#if os(macOS)
if Variant.useSystemExtension {
guard let sourceAddress, let destinationAddress else {
throw NSError(domain: "findConnectionOwner", code: 0, userInfo: [
NSLocalizedDescriptionKey: "Missing source or destination address",
])
}
let owner = try RootHelperClient.shared.findConnectionOwner(
ipProtocol: ipProtocol,
sourceAddress: sourceAddress,
sourcePort: sourcePort,
destinationAddress: destinationAddress,
destinationPort: destinationPort
)
let result = LibboxConnectionOwner()
result.userId = owner.userId
result.userName = owner.userName
result.processPath = owner.processPath
return result
}
#endif
throw NSError(domain: "ExtensionPlatformInterface", code: 0, userInfo: [NSLocalizedDescriptionKey: String(localized: "Not implemented")])
}
public func useProcFS() -> Bool {
false
}
func writeLogs(_ messageList: (any LibboxStringIteratorProtocol)?) {
// guard let message else {
// return
// }
// tunnel.writeMessage(message)
public func writeLog(_ message: String?) {
guard let message else {
return
}
tunnel.writeMessage(message)
}
public func usePlatformDefaultInterfaceMonitor() -> Bool {
false
private var nwMonitor: NWPathMonitor?
public func startDefaultInterfaceMonitor(_ listener: LibboxInterfaceUpdateListenerProtocol?) throws {
return
guard let listener else {
return
}
let monitor = NWPathMonitor()
nwMonitor = monitor
let semaphore = DispatchSemaphore(value: 0)
monitor.pathUpdateHandler = { path in
self.onUpdateDefaultInterface(listener, path)
semaphore.signal()
monitor.pathUpdateHandler = { path in
self.onUpdateDefaultInterface(listener, path)
}
}
monitor.start(queue: DispatchQueue.global())
semaphore.wait()
}
public func startDefaultInterfaceMonitor(_: LibboxInterfaceUpdateListenerProtocol?) throws {}
private func onUpdateDefaultInterface(_ listener: LibboxInterfaceUpdateListenerProtocol, _ path: Network.NWPath) {
return
guard path.status != .unsatisfied,
let defaultInterface = path.availableInterfaces.first
else {
listener.updateDefaultInterface("", interfaceIndex: -1, isExpensive: false, isConstrained: false)
return
}
listener.updateDefaultInterface(defaultInterface.name, interfaceIndex: Int32(defaultInterface.index), isExpensive: path.isExpensive, isConstrained: path.isConstrained)
}
public func closeDefaultInterfaceMonitor(_: LibboxInterfaceUpdateListenerProtocol?) throws {}
public func useGetter() -> Bool {
false
public func closeDefaultInterfaceMonitor(_: LibboxInterfaceUpdateListenerProtocol?) throws {
nwMonitor?.cancel()
nwMonitor = nil
}
public func getInterfaces() throws -> LibboxNetworkInterfaceIteratorProtocol {
throw NSError(domain: "not implemented", code: 0)
guard let nwMonitor else {
throw NSError(domain: "ExtensionPlatformInterface", code: 0, userInfo: [NSLocalizedDescriptionKey: String(localized: "NWMonitor not started")])
}
let path = nwMonitor.currentPath
if path.status == .unsatisfied {
return networkInterfaceArray([])
}
var interfaces: [LibboxNetworkInterface] = []
for it in path.availableInterfaces {
let interface = LibboxNetworkInterface()
interface.name = it.name
interface.index = Int32(it.index)
switch it.type {
case .wifi:
interface.type = LibboxInterfaceTypeWIFI
case .cellular:
interface.type = LibboxInterfaceTypeCellular
case .wiredEthernet:
interface.type = LibboxInterfaceTypeEthernet
default:
interface.type = LibboxInterfaceTypeOther
}
interfaces.append(interface)
}
return networkInterfaceArray(interfaces)
}
class networkInterfaceArray: NSObject, LibboxNetworkInterfaceIteratorProtocol {
private var iterator: IndexingIterator<[LibboxNetworkInterface]>
init(_ array: [LibboxNetworkInterface]) {
iterator = array.makeIterator()
}
private var nextValue: LibboxNetworkInterface?
func hasNext() -> Bool {
nextValue = iterator.next()
return nextValue != nil
}
func next() -> LibboxNetworkInterface? {
nextValue
}
}
public func underNetworkExtension() -> Bool {
true
}
public func includeAllNetworks() -> Bool {
#if !os(tvOS)
// return SharedPreferences.includeAllNetworks.getBlocking()
#if os(tvOS)
return false
#else
return false
// return tunnel.overridePreferences?.includeAllNetworks ?? false
#endif
}
public func clearDNSCache() {
guard let networkSettings else {
return
}
tunnel.reasserting = true
tunnel.setTunnelNetworkSettings(nil) { _ in
runBlocking {
self.tunnel.reasserting = true
defer { self.tunnel.reasserting = false }
await withCheckedContinuation { continuation in
self.tunnel.setTunnelNetworkSettings(nil) { _ in
continuation.resume()
}
}
await withCheckedContinuation { continuation in
self.tunnel.setTunnelNetworkSettings(networkSettings) { _ in
continuation.resume()
}
}
}
tunnel.setTunnelNetworkSettings(networkSettings) { _ in
}
tunnel.reasserting = false
}
public func readWIFIState() -> LibboxWIFIState? {
// #if os(iOS)
// let network = runBlocking {
// await NEHotspotNetwork.fetchCurrent()
// }
// guard let network else {
// return nil
// }
// return LibboxWIFIState(network.ssid, wifiBSSID: network.bssid)!
// #elseif os(macOS)
// if Variant.useSystemExtension {
// return UserServiceClient.shared.readWIFIState()
// }
// guard let interface = CWWiFiClient.shared().interface() else {
// return nil
// }
// guard let ssid = interface.ssid() else {
// return nil
// }
// guard let bssid = interface.bssid() else {
// return nil
// }
// return LibboxWIFIState(ssid, wifiBSSID: bssid)!
// #else
return nil
// #endif
}
public func readWIFISSID() -> String? {
// #if os(iOS)
// return runBlocking {
// await NEHotspotNetwork.fetchCurrent()?.ssid
// }
// #elseif os(macOS)
// return CWWiFiClient.shared().interface()?.ssid()
// #else
return nil
// #endif
}
// public func serviceStop() throws {
// tunnel.stopService()
// }
public func serviceReload() throws {
runBlocking { [self] in
await tunnel.reloadService()
try runBlocking { [self] in
try await tunnel.reloadService()
}
}
public func getSystemProxyStatus() -> LibboxSystemProxyStatus? {
public func getSystemProxyStatus() throws -> LibboxSystemProxyStatus {
let status = LibboxSystemProxyStatus()
guard let networkSettings else {
return status
@ -313,24 +454,56 @@ public class ExtensionPlatformInterface: NSObject, LibboxPlatformInterfaceProtoc
}
}
public func postServiceClose() {
NSLog("H?A3")
// TODO
public func writeDebugMessage(_ message: String?) {
guard let message else {
return
}
// tunnel.writeMessage(message)
}
func reset() {
NSLog("H?A4")
networkSettings = nil
nwMonitor?.cancel()
nwMonitor = nil
}
public func writeLog(_ message: String?) {
}
public func send(_ notification: LibboxNotification?) throws {
#if !os(tvOS)
guard let notification else {
return
}
#if os(macOS)
if Variant.useSystemExtension {
try UserServiceClient.shared.sendNotification(notification)
return
}
#endif
// let center = UNUserNotificationCenter.current()
// let content = UNMutableNotificationContent()
//
// content.title = notification.title
// content.subtitle = notification.subtitle
// content.body = notification.body
// if !notification.openURL.isEmpty {
// content.userInfo["OPEN_URL"] = notification.openURL
// content.categoryIdentifier = "OPEN_URL"
// }
// content.interruptionLevel = .active
// let request = UNNotificationRequest(identifier: notification.identifier, content: content, trigger: nil)
// try runBlocking {
// try await center.requestAuthorization(options: [.alert])
// try await center.add(request)
// }
#endif
}
public func readWIFIState() -> LibboxWIFIState? {
return nil;
public func localDNSTransport() -> (any LibboxLocalDNSTransportProtocol)? {
nil
}
public func systemCertificates() -> (any LibboxStringIteratorProtocol)? {
nil
}
public func autoDetectControl(_: Int32) throws {}
}

View File

@ -7,7 +7,7 @@ open class ExtensionProvider: NEPacketTunnelProvider {
public static let errorFile = FilePath.workingDirectory.appendingPathComponent("network_extension_error.log")
private let logger = Logger(subsystem: "apple.hiddify.com.HiddifyPacketTunnel", category: "PacketTunnel")
private var commandServer: LibboxCommandServer!
// private var commandServer: LibboxCommandServer!
private var systemProxyAvailable = false
private var systemProxyEnabled = false
private var platformInterface: ExtensionPlatformInterface!
@ -54,14 +54,17 @@ open class ExtensionProvider: NEPacketTunnelProvider {
}
// Initialize mobile setup with error handling
var setupError: NSError?
MobileSetup(
sharedDir,
workDir,
cacheDir,
4,
"127.0.0.1:\(grpcServiceModePort)",
"",
false,
let opts = MobileSetupOptions()
opts.basePath = sharedDir
opts.workingDir = workDir
opts.tempDir = cacheDir
opts.listen = "127.0.0.1:\(grpcServiceModePort)"
opts.secret = ""
opts.debug = false
opts.mode = 4
opts.fixAndroidStack = false
MobileSetup(opts,
platformInterface,
&setupError
)
@ -70,6 +73,7 @@ open class ExtensionProvider: NEPacketTunnelProvider {
throw setupError
}
LibboxSetMemoryLimit(!disableMemoryLimit)
writeMessage("(packet-tunnel) setup completed successfully")
@ -84,19 +88,19 @@ open class ExtensionProvider: NEPacketTunnelProvider {
}
private func startService(_ config: String) async throws {
writeMessage("Starting service")
var error: NSError?
do {
try MobileStart("", config, &error)
if let error = error {
throw error
}
writeMessage("(packet-tunnel) service started successfully")
} catch {
writeFatalError("(packet-tunnel) error: start service: \(error.localizedDescription)")
throw error
}
// writeMessage("Starting service")
// var error: NSError?
//
// do {
//// try MobileStart("", "", &error)
// if let error = error {
// throw error
// }
// writeMessage("(packet-tunnel) service started successfully")
// } catch {
// writeFatalError("(packet-tunnel) error: start service: \(error.localizedDescription)")
// throw error
// }
}
private func createRequiredDirectories() throws {
@ -155,13 +159,13 @@ open class ExtensionProvider: NEPacketTunnelProvider {
writeMessage("(packet-tunnel) stopping, reason: \(reason)")
stopService()
// Allow time for cleanup
try? await Task.sleep(nanoseconds: 100 * NSEC_PER_MSEC)
if let server = commandServer {
try? server.close()
commandServer = nil
}
// // Allow time for cleanup
// try? await Task.sleep(nanoseconds: 100 * NSEC_PER_MSEC)
//
// if let server = commandServer {
// try? server.close()
// commandServer = nil
// }
}
private func stopService() {
@ -197,11 +201,13 @@ open class ExtensionProvider: NEPacketTunnelProvider {
override open func sleep() async {
logger.debug("Entering sleep mode")
MobilePause()
// Add any sleep mode handling if needed
}
override open func wake() {
logger.debug("Waking from sleep")
MobileWake()
// Add any wake handling if needed
}
}

View File

@ -110,9 +110,9 @@ PODS:
- pointer_interceptor_ios (0.0.1):
- Flutter
- PromisesObjC (2.4.0)
- SDWebImage (5.21.3):
- SDWebImage/Core (= 5.21.3)
- SDWebImage/Core (5.21.3)
- SDWebImage (5.21.5):
- SDWebImage/Core (= 5.21.5)
- SDWebImage/Core (5.21.5)
- Sentry/HybridSDK (8.46.0)
- sentry_flutter (8.14.0):
- Flutter
@ -262,7 +262,7 @@ SPEC CHECKSUMS:
path_provider_foundation: 2b6b4c569c0fb62ec74538f866245ac84301af46
pointer_interceptor_ios: 508241697ff0947f853c061945a8b822463947c1
PromisesObjC: f5707f49cb48b9636751c5b2e7d227e43fba9f47
SDWebImage: 16309af6d214ba3f77a7c6f6fdda888cb313a50a
SDWebImage: e9c98383c7572d713c1a0d7dd2783b10599b9838
Sentry: da60d980b197a46db0b35ea12cb8f39af48d8854
sentry_flutter: 187f9b6b06f00f36b4930ec7ea9f34c254095d15
share_plus: 8b6f8b3447e494cca5317c8c3073de39b3600d1f

View File

@ -56,8 +56,12 @@
debugServiceExtension = "internal"
allowLocationSimulation = "YES"
launchAutomaticallySubstyle = "2">
<BuildableProductRunnable
runnableDebuggingMode = "0">
<RemoteRunnable
runnableDebuggingMode = "0"
BundleIdentifier = "apple.hiddify.com"
RemotePath = "/var/containers/Bundle/Application/8EBA9FC7-47CA-4C36-B670-54E8EB45F196/Runner.app">
</RemoteRunnable>
<MacroExpansion>
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "97C146ED1CF9000F007C117D"
@ -65,7 +69,7 @@
BlueprintName = "Runner"
ReferencedContainer = "container:Runner.xcodeproj">
</BuildableReference>
</BuildableProductRunnable>
</MacroExpansion>
</LaunchAction>
<ProfileAction
buildConfiguration = "Release"

View File

@ -26,10 +26,10 @@ import Sentry
FileMethodHandler.register(with: self.registrar(forPlugin: FileMethodHandler.name)!)
StatusEventHandler.register(with: self.registrar(forPlugin: StatusEventHandler.name)!)
AlertsEventHandler.register(with: self.registrar(forPlugin: AlertsEventHandler.name)!)
LogsEventHandler.register(with: self.registrar(forPlugin: LogsEventHandler.name)!)
GroupsEventHandler.register(with: self.registrar(forPlugin: GroupsEventHandler.name)!)
ActiveGroupsEventHandler.register(with: self.registrar(forPlugin: ActiveGroupsEventHandler.name)!)
StatsEventHandler.register(with: self.registrar(forPlugin: StatsEventHandler.name)!)
// LogsEventHandler.register(with: self.registrar(forPlugin: LogsEventHandler.name)!)
// GroupsEventHandler.register(with: self.registrar(forPlugin: GroupsEventHandler.name)!)
// ActiveGroupsEventHandler.register(with: self.registrar(forPlugin: ActiveGroupsEventHandler.name)!)
// StatsEventHandler.register(with: self.registrar(forPlugin: StatsEventHandler.name)!)
}
}

View File

@ -77,7 +77,20 @@ public class MethodHandler: NSObject, FlutterPlugin {
VPNConfig.shared.workingDir=workingDir
VPNConfig.shared.tempDir=tempDir
var error: NSError?
MobileSetup(baseDir, workingDir, tempDir, mode, "127.0.0.1:\(grpcPort)", "", false, nil, &error)
let opts = MobileSetupOptions()
opts.basePath = baseDir
opts.workingDir = workingDir
opts.tempDir = tempDir
opts.listen = "127.0.0.1:\(grpcPort)"
opts.secret = ""
opts.debug = false
opts.mode = 4
opts.fixAndroidStack = false
MobileSetup(opts,
nil,
&error
)
if let error {
result(FlutterError(code: String(error.code), message: error.localizedDescription, details: nil))
return
@ -106,14 +119,14 @@ public class MethodHandler: NSObject, FlutterPlugin {
VPNConfig.shared.grpcServiceModePort=grpcPort
var error: NSError?
let configstr=MobileBuildConfig(path,&error) as String
//let configstr=MobileBuildConfig(path,&error) as String
if let error {
await mainResult(FlutterError(code: String(error.code), message: error.description, details: nil))
return
}
do {
try await VPNManager.shared.setup()
try await VPNManager.shared.connect(with: configstr, grpcServiceModePort: grpcPort, disableMemoryLimit: VPNConfig.shared.disableMemoryLimit)
try await VPNManager.shared.connect(with: path, grpcServiceModePort: grpcPort, disableMemoryLimit: VPNConfig.shared.disableMemoryLimit)
} catch {
await mainResult(FlutterError(code: "SETUP_CONNECTION", message: error.localizedDescription, details: nil))
return

View File

@ -50,122 +50,122 @@ public class CommandClient: ObservableObject {
}
private nonisolated func connect0() async {
let clientOptions = LibboxCommandClientOptions()
switch connectionType {
case .status:
clientOptions.command = LibboxCommandStatus
case .groups:
clientOptions.command = LibboxCommandGroup
case .log:
clientOptions.command = LibboxCommandLog
case .groupsInfoOnly:
clientOptions.command = LibboxCommandGroupInfoOnly
}
clientOptions.statusInterval = Int64(2 * NSEC_PER_SEC)
let client = LibboxNewCommandClient(clientHandler(self), clientOptions)!
do {
for i in 0 ..< 10 {
try await Task.sleep(nanoseconds: UInt64(Double(100 + (i * 50)) * Double(NSEC_PER_MSEC)))
try Task.checkCancellation()
do {
try client.connect()
await MainActor.run {
commandClient = client
}
return
} catch {}
try Task.checkCancellation()
}
} catch {
try? client.disconnect()
}
// let clientOptions = LibboxCommandClientOptions()
// switch connectionType {
// case .status:
// clientOptions.command = LibboxCommandStatus
// case .groups:
// clientOptions.command = LibboxCommandGroup
// case .log:
// clientOptions.command = LibboxCommandLog
// case .groupsInfoOnly:
// clientOptions.command = LibboxCommandGroupInfoOnly
// }
// clientOptions.statusInterval = Int64(2 * NSEC_PER_SEC)
// let client = LibboxNewCommandClient(clientHandler(self), clientOptions)!
// do {
// for i in 0 ..< 10 {
// try await Task.sleep(nanoseconds: UInt64(Double(100 + (i * 50)) * Double(NSEC_PER_MSEC)))
// try Task.checkCancellation()
// do {
// try client.connect()
// await MainActor.run {
// commandClient = client
// }
// return
// } catch {}
// try Task.checkCancellation()
// }
// } catch {
// try? client.disconnect()
// }
}
private class clientHandler: NSObject, LibboxCommandClientHandlerProtocol {
private let commandClient: CommandClient
init(_ commandClient: CommandClient) {
self.commandClient = commandClient
}
func connected() {
DispatchQueue.main.async { [self] in
if commandClient.connectionType == .log {
commandClient.logList = []
}
commandClient.isConnected = true
}
}
func disconnected(_: String?) {
DispatchQueue.main.async { [self] in
commandClient.isConnected = false
}
}
func clearLogs() {
DispatchQueue.main.async { [self] in
commandClient.logList.removeAll()
}
}
func writeLogs(_ messageList: (any LibboxStringIteratorProtocol)?) {
// guard let message else {
// private class clientHandler: NSObject, LibboxCommandClientHandlerProtocol {
//
//
// private let commandClient: CommandClient
//
// init(_ commandClient: CommandClient) {
// self.commandClient = commandClient
// }
//
// func connected() {
// DispatchQueue.main.async { [self] in
// if commandClient.connectionType == .log {
// commandClient.logList = []
// }
// commandClient.isConnected = true
// }
// }
//
// func disconnected(_: String?) {
// DispatchQueue.main.async { [self] in
// commandClient.isConnected = false
// }
// }
//
// func clearLogs() {
// DispatchQueue.main.async { [self] in
// commandClient.logList.removeAll()
// }
// }
//
// func writeLogs(_ messageList: (any LibboxStringIteratorProtocol)?) {
//// guard let message else {
//// return
//// }
//// DispatchQueue.main.async { [self] in
//// if commandClient.logList.count > commandClient.logMaxLines {
//// commandClient.logList.removeFirst()
//// }
//// commandClient.logList.append(message)
//// }
// }
//
// func writeStatus(_ message: LibboxStatusMessage?) {
// DispatchQueue.main.async { [self] in
// commandClient.status = message
// }
// }
//
// func writeGroups(_ groups: LibboxOutboundGroupIteratorProtocol?) {
// guard let groups else {
// return
// }
// DispatchQueue.main.async { [self] in
// if commandClient.logList.count > commandClient.logMaxLines {
// commandClient.logList.removeFirst()
// var sbGroups = [SBGroup]()
// while groups.hasNext() {
// let group = groups.next()!
// var items = [SBItem]()
// let groupItems = group.getItems()
// while groupItems?.hasNext() ?? false {
// let item = groupItems?.next()!
// items.append(SBItem(tag: item!.tag,
// type: item!.type,
// urlTestDelay: Int(item!.urlTestDelay)
// )
// )
// }
// commandClient.logList.append(message)
//
// sbGroups.append(.init(tag: group.tag,
// type: group.type,
// selected: group.selected,
// items: items)
// )
//
// }
}
func writeStatus(_ message: LibboxStatusMessage?) {
DispatchQueue.main.async { [self] in
commandClient.status = message
}
}
func writeGroups(_ groups: LibboxOutboundGroupIteratorProtocol?) {
guard let groups else {
return
}
var sbGroups = [SBGroup]()
while groups.hasNext() {
let group = groups.next()!
var items = [SBItem]()
let groupItems = group.getItems()
while groupItems?.hasNext() ?? false {
let item = groupItems?.next()!
items.append(SBItem(tag: item!.tag,
type: item!.type,
urlTestDelay: Int(item!.urlTestDelay)
)
)
}
sbGroups.append(.init(tag: group.tag,
type: group.type,
selected: group.selected,
items: items)
)
}
DispatchQueue.main.async { [self] in
commandClient.groups = sbGroups
}
}
func initializeClashMode(_ modeList: LibboxStringIteratorProtocol?, currentMode: String?) {
}
func updateClashMode(_ newMode: String?) {
}
func write(_ message: LibboxConnections?) {
}
}
// DispatchQueue.main.async { [self] in
// commandClient.groups = sbGroups
// }
// }
//
// func initializeClashMode(_ modeList: LibboxStringIteratorProtocol?, currentMode: String?) {
// }
//
// func updateClashMode(_ newMode: String?) {
// }
// func write(_ message: LibboxConnections?) {
// }
//
// }
}

View File

@ -42,6 +42,7 @@ class HiddifyCoreService with InfraLogger {
setup(dirs, debug)
.mapLeft((e) {
loggy.error(e);
if (PlatformUtils.isIOS) return;
ref.read(inAppNotificationControllerProvider).showErrorToast(e);
})
.map((_) {