From 28219a3bb36c829cda7a924164d105e69d169108 Mon Sep 17 00:00:00 2001 From: anlicheng <244108715@qq.com> Date: Thu, 23 Oct 2025 17:01:36 +0800 Subject: [PATCH] fix bundle id --- Tun/PacketTunnelProvider.swift | 9 +- Tun/Punchnet/SDLConfiguration.swift | 4 +- Tun/Punchnet/SDLContext.swift | 14 +-- Tun/Punchnet/SDLMessage.pb.swift | 110 ++++++++---------- Tun/Punchnet/SDLSuperClient.swift | 3 + Tun/Punchnet/SDLUDPHole.swift | 8 +- punchnet.xcodeproj/project.pbxproj | 20 ++-- .../xcschemes/xcschememanagement.plist | 6 +- punchnet/Core/SDLAPI.swift | 31 ++++- punchnet/Core/SystemConfig.swift | 24 +++- punchnet/Core/VPNManager.swift | 7 +- punchnet/Views/IndexView.swift | 89 +++++++++++--- punchnet/punchnetApp.swift | 5 +- 13 files changed, 213 insertions(+), 117 deletions(-) diff --git a/Tun/PacketTunnelProvider.swift b/Tun/PacketTunnelProvider.swift index d8052ac..c767591 100644 --- a/Tun/PacketTunnelProvider.swift +++ b/Tun/PacketTunnelProvider.swift @@ -37,6 +37,8 @@ class PacketTunnelProvider: NEPacketTunnelProvider { let stunServersStr = options["stun_servers"] as! String let noticePort = options["notice_port"] as! Int let token = options["token"] as! String + let networkCode = options["network_code"] as! String + let clientId = options["client_id"] as! String let stunServers = stunServersStr.split(separator: ";").compactMap { server -> SDLConfiguration.StunServer? in let parts = server.split(separator: ":", maxSplits: 2) @@ -56,15 +58,18 @@ class PacketTunnelProvider: NEPacketTunnelProvider { NSLog("stunServers配置错误") return } + + NSLog("[PacketTunnelProvider] client_id: \(clientId), token: \(token), network_code: \(networkCode)") let config = SDLConfiguration(version: 1, installedChannel: installed_channel, superHost: superIp, superPort: superPort, stunServers: stunServers, - clientId: SDLContext.getUUID(), + clientId: clientId, noticePort: noticePort, - token: token) + token: token, + networkCode: networkCode) // 加密算法 let rsaCipher = try! CCRSACipher(keySize: 1024) let aesChiper = CCAESChiper() diff --git a/Tun/Punchnet/SDLConfiguration.swift b/Tun/Punchnet/SDLConfiguration.swift index 5c2df3c..cbb8f7b 100644 --- a/Tun/Punchnet/SDLConfiguration.swift +++ b/Tun/Punchnet/SDLConfiguration.swift @@ -50,8 +50,9 @@ public class SDLConfiguration { let clientId: String let token: String + let networkCode: String - public init(version: UInt8, installedChannel: String, superHost: String, superPort: Int, stunServers: [StunServer], clientId: String, noticePort: Int, token: String) { + public init(version: UInt8, installedChannel: String, superHost: String, superPort: Int, stunServers: [StunServer], clientId: String, noticePort: Int, token: String, networkCode: String) { self.version = version self.installedChannel = installedChannel self.superHost = superHost @@ -60,6 +61,7 @@ public class SDLConfiguration { self.clientId = clientId self.noticePort = noticePort self.token = token + self.networkCode = networkCode } } diff --git a/Tun/Punchnet/SDLContext.swift b/Tun/Punchnet/SDLContext.swift index 5a00c68..6777549 100644 --- a/Tun/Punchnet/SDLContext.swift +++ b/Tun/Punchnet/SDLContext.swift @@ -249,7 +249,7 @@ public class SDLContext: @unchecked Sendable { let aesKey = try! self.rsaCipher.decode(data: Data(registerSuperAck.aesKey)) let upgradeType = SDLUpgradeType(rawValue: registerSuperAck.upgradeType) - self.logger.log("[SDLContext] get registerSuperAck, aes_key len: \(aesKey.count)", level: .info) + self.logger.log("[SDLContext] get registerSuperAck, aes_key len: \(aesKey.count), network_id:\(registerSuperAck.devAddr.networkID)", level: .info) self.devAddr = registerSuperAck.devAddr if upgradeType == .force { @@ -589,18 +589,6 @@ public class SDLContext: @unchecked Sendable { self.superClient = nil } - public static func getUUID() -> String { - let userDefaults = UserDefaults.standard - if let uuid = userDefaults.value(forKey: "gClientId") as? String { - return uuid - } else { - let uuid = UUID().uuidString.replacingOccurrences(of: "-", with: "").lowercased() - userDefaults.setValue(uuid, forKey: "gClientId") - - return uuid - } - } - // 获取mac地址 public static func getMacAddress() -> Data { let key = "gMacAddress2" diff --git a/Tun/Punchnet/SDLMessage.pb.swift b/Tun/Punchnet/SDLMessage.pb.swift index 60cfbd7..999b3ea 100644 --- a/Tun/Punchnet/SDLMessage.pb.swift +++ b/Tun/Punchnet/SDLMessage.pb.swift @@ -1,5 +1,6 @@ // DO NOT EDIT. // swift-format-ignore-file +// swiftlint:disable all // // Generated by the Swift generator plugin for the protocol buffer compiler. // Source: sdlan_pb.proto @@ -20,7 +21,7 @@ fileprivate struct _GeneratedWithProtocGenSwiftVersion: SwiftProtobuf.ProtobufAP typealias Version = _2 } -struct SDLV4Info { +struct SDLV4Info: @unchecked Sendable { // SwiftProtobuf.Message conformance is added in an extension below. See the // `Message` and `Message+*Additions` files in the SwiftProtobuf library for // methods supported on all messages. @@ -36,7 +37,7 @@ struct SDLV4Info { init() {} } -struct SDLV6Info { +struct SDLV6Info: @unchecked Sendable { // SwiftProtobuf.Message conformance is added in an extension below. See the // `Message` and `Message+*Additions` files in the SwiftProtobuf library for // methods supported on all messages. @@ -51,7 +52,7 @@ struct SDLV6Info { } /// 设备网络地址信息 -struct SDLDevAddr { +struct SDLDevAddr: @unchecked Sendable { // SwiftProtobuf.Message conformance is added in an extension below. See the // `Message` and `Message+*Additions` files in the SwiftProtobuf library for // methods supported on all messages. @@ -70,7 +71,7 @@ struct SDLDevAddr { } /// tcp通讯消息 -struct SDLEmpty { +struct SDLEmpty: Sendable { // SwiftProtobuf.Message conformance is added in an extension below. See the // `Message` and `Message+*Additions` files in the SwiftProtobuf library for // methods supported on all messages. @@ -80,7 +81,7 @@ struct SDLEmpty { init() {} } -struct SDLRegisterSuper { +struct SDLRegisterSuper: Sendable { // SwiftProtobuf.Message conformance is added in an extension below. See the // `Message` and `Message+*Additions` files in the SwiftProtobuf library for // methods supported on all messages. @@ -104,6 +105,8 @@ struct SDLRegisterSuper { var token: String = String() + var networkCode: String = String() + var unknownFields = SwiftProtobuf.UnknownStorage() init() {} @@ -111,7 +114,7 @@ struct SDLRegisterSuper { fileprivate var _devAddr: SDLDevAddr? = nil } -struct SDLRegisterSuperAck { +struct SDLRegisterSuperAck: @unchecked Sendable { // SwiftProtobuf.Message conformance is added in an extension below. See the // `Message` and `Message+*Additions` files in the SwiftProtobuf library for // methods supported on all messages. @@ -156,7 +159,7 @@ struct SDLRegisterSuperAck { fileprivate var _upgradeAddress: String? = nil } -struct SDLRegisterSuperNak { +struct SDLRegisterSuperNak: Sendable { // SwiftProtobuf.Message conformance is added in an extension below. See the // `Message` and `Message+*Additions` files in the SwiftProtobuf library for // methods supported on all messages. @@ -170,7 +173,7 @@ struct SDLRegisterSuperNak { init() {} } -struct SDLQueryInfo { +struct SDLQueryInfo: @unchecked Sendable { // SwiftProtobuf.Message conformance is added in an extension below. See the // `Message` and `Message+*Additions` files in the SwiftProtobuf library for // methods supported on all messages. @@ -182,7 +185,7 @@ struct SDLQueryInfo { init() {} } -struct SDLPeerInfo { +struct SDLPeerInfo: @unchecked Sendable { // SwiftProtobuf.Message conformance is added in an extension below. See the // `Message` and `Message+*Additions` files in the SwiftProtobuf library for // methods supported on all messages. @@ -198,8 +201,6 @@ struct SDLPeerInfo { /// Clears the value of `v4Info`. Subsequent reads from it will return its default value. mutating func clearV4Info() {self._v4Info = nil} - var natType: UInt32 = 0 - var v6Info: SDLV6Info { get {return _v6Info ?? SDLV6Info()} set {_v6Info = newValue} @@ -217,7 +218,7 @@ struct SDLPeerInfo { fileprivate var _v6Info: SDLV6Info? = nil } -struct SDLNatChangedEvent { +struct SDLNatChangedEvent: @unchecked Sendable { // SwiftProtobuf.Message conformance is added in an extension below. See the // `Message` and `Message+*Additions` files in the SwiftProtobuf library for // methods supported on all messages. @@ -231,7 +232,7 @@ struct SDLNatChangedEvent { init() {} } -struct SDLSendRegisterEvent { +struct SDLSendRegisterEvent: @unchecked Sendable { // SwiftProtobuf.Message conformance is added in an extension below. See the // `Message` and `Message+*Additions` files in the SwiftProtobuf library for // methods supported on all messages. @@ -242,6 +243,8 @@ struct SDLSendRegisterEvent { var natPort: UInt32 = 0 + var natType: UInt32 = 0 + var v6Info: SDLV6Info { get {return _v6Info ?? SDLV6Info()} set {_v6Info = newValue} @@ -258,7 +261,7 @@ struct SDLSendRegisterEvent { fileprivate var _v6Info: SDLV6Info? = nil } -struct SDLNetworkShutdownEvent { +struct SDLNetworkShutdownEvent: Sendable { // SwiftProtobuf.Message conformance is added in an extension below. See the // `Message` and `Message+*Additions` files in the SwiftProtobuf library for // methods supported on all messages. @@ -270,7 +273,7 @@ struct SDLNetworkShutdownEvent { init() {} } -struct SDLChangeNetworkCommand { +struct SDLChangeNetworkCommand: @unchecked Sendable { // SwiftProtobuf.Message conformance is added in an extension below. See the // `Message` and `Message+*Additions` files in the SwiftProtobuf library for // methods supported on all messages. @@ -293,7 +296,7 @@ struct SDLChangeNetworkCommand { fileprivate var _devAddr: SDLDevAddr? = nil } -struct SDLCommandAck { +struct SDLCommandAck: Sendable { // SwiftProtobuf.Message conformance is added in an extension below. See the // `Message` and `Message+*Additions` files in the SwiftProtobuf library for // methods supported on all messages. @@ -317,7 +320,7 @@ struct SDLCommandAck { fileprivate var _message: String? = nil } -struct SDLFlows { +struct SDLFlows: Sendable { // SwiftProtobuf.Message conformance is added in an extension below. See the // `Message` and `Message+*Additions` files in the SwiftProtobuf library for // methods supported on all messages. @@ -336,7 +339,7 @@ struct SDLFlows { init() {} } -struct SDLStunRequest { +struct SDLStunRequest: @unchecked Sendable { // SwiftProtobuf.Message conformance is added in an extension below. See the // `Message` and `Message+*Additions` files in the SwiftProtobuf library for // methods supported on all messages. @@ -369,7 +372,7 @@ struct SDLStunRequest { fileprivate var _v6Info: SDLV6Info? = nil } -struct SDLStunReply { +struct SDLStunReply: Sendable { // SwiftProtobuf.Message conformance is added in an extension below. See the // `Message` and `Message+*Additions` files in the SwiftProtobuf library for // methods supported on all messages. @@ -381,7 +384,7 @@ struct SDLStunReply { init() {} } -struct SDLData { +struct SDLData: @unchecked Sendable { // SwiftProtobuf.Message conformance is added in an extension below. See the // `Message` and `Message+*Additions` files in the SwiftProtobuf library for // methods supported on all messages. @@ -403,7 +406,7 @@ struct SDLData { init() {} } -struct SDLRegister { +struct SDLRegister: @unchecked Sendable { // SwiftProtobuf.Message conformance is added in an extension below. See the // `Message` and `Message+*Additions` files in the SwiftProtobuf library for // methods supported on all messages. @@ -419,7 +422,7 @@ struct SDLRegister { init() {} } -struct SDLRegisterAck { +struct SDLRegisterAck: @unchecked Sendable { // SwiftProtobuf.Message conformance is added in an extension below. See the // `Message` and `Message+*Additions` files in the SwiftProtobuf library for // methods supported on all messages. @@ -435,7 +438,7 @@ struct SDLRegisterAck { init() {} } -struct SDLStunProbe { +struct SDLStunProbe: Sendable { // SwiftProtobuf.Message conformance is added in an extension below. See the // `Message` and `Message+*Additions` files in the SwiftProtobuf library for // methods supported on all messages. @@ -449,7 +452,7 @@ struct SDLStunProbe { init() {} } -struct SDLStunProbeReply { +struct SDLStunProbeReply: Sendable { // SwiftProtobuf.Message conformance is added in an extension below. See the // `Message` and `Message+*Additions` files in the SwiftProtobuf library for // methods supported on all messages. @@ -465,31 +468,6 @@ struct SDLStunProbeReply { init() {} } -#if swift(>=5.5) && canImport(_Concurrency) -extension SDLV4Info: @unchecked Sendable {} -extension SDLV6Info: @unchecked Sendable {} -extension SDLDevAddr: @unchecked Sendable {} -extension SDLEmpty: @unchecked Sendable {} -extension SDLRegisterSuper: @unchecked Sendable {} -extension SDLRegisterSuperAck: @unchecked Sendable {} -extension SDLRegisterSuperNak: @unchecked Sendable {} -extension SDLQueryInfo: @unchecked Sendable {} -extension SDLPeerInfo: @unchecked Sendable {} -extension SDLNatChangedEvent: @unchecked Sendable {} -extension SDLSendRegisterEvent: @unchecked Sendable {} -extension SDLNetworkShutdownEvent: @unchecked Sendable {} -extension SDLChangeNetworkCommand: @unchecked Sendable {} -extension SDLCommandAck: @unchecked Sendable {} -extension SDLFlows: @unchecked Sendable {} -extension SDLStunRequest: @unchecked Sendable {} -extension SDLStunReply: @unchecked Sendable {} -extension SDLData: @unchecked Sendable {} -extension SDLRegister: @unchecked Sendable {} -extension SDLRegisterAck: @unchecked Sendable {} -extension SDLStunProbe: @unchecked Sendable {} -extension SDLStunProbeReply: @unchecked Sendable {} -#endif // swift(>=5.5) && canImport(_Concurrency) - // MARK: - Code below here is support for the SwiftProtobuf runtime. extension SDLV4Info: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { @@ -629,8 +607,8 @@ extension SDLEmpty: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationB static let _protobuf_nameMap = SwiftProtobuf._NameMap() mutating func decodeMessage(decoder: inout D) throws { - while let _ = try decoder.nextFieldNumber() { - } + // Load everything into unknown fields + while try decoder.nextFieldNumber() != nil {} } func traverse(visitor: inout V) throws { @@ -652,6 +630,7 @@ extension SDLRegisterSuper: SwiftProtobuf.Message, SwiftProtobuf._MessageImpleme 4: .standard(proto: "dev_addr"), 5: .standard(proto: "pub_key"), 6: .same(proto: "token"), + 7: .standard(proto: "network_code"), ] mutating func decodeMessage(decoder: inout D) throws { @@ -666,6 +645,7 @@ extension SDLRegisterSuper: SwiftProtobuf.Message, SwiftProtobuf._MessageImpleme case 4: try { try decoder.decodeSingularMessageField(value: &self._devAddr) }() case 5: try { try decoder.decodeSingularStringField(value: &self.pubKey) }() case 6: try { try decoder.decodeSingularStringField(value: &self.token) }() + case 7: try { try decoder.decodeSingularStringField(value: &self.networkCode) }() default: break } } @@ -694,6 +674,9 @@ extension SDLRegisterSuper: SwiftProtobuf.Message, SwiftProtobuf._MessageImpleme if !self.token.isEmpty { try visitor.visitSingularStringField(value: self.token, fieldNumber: 6) } + if !self.networkCode.isEmpty { + try visitor.visitSingularStringField(value: self.networkCode, fieldNumber: 7) + } try unknownFields.traverse(visitor: &visitor) } @@ -704,6 +687,7 @@ extension SDLRegisterSuper: SwiftProtobuf.Message, SwiftProtobuf._MessageImpleme if lhs._devAddr != rhs._devAddr {return false} if lhs.pubKey != rhs.pubKey {return false} if lhs.token != rhs.token {return false} + if lhs.networkCode != rhs.networkCode {return false} if lhs.unknownFields != rhs.unknownFields {return false} return true } @@ -844,8 +828,7 @@ extension SDLPeerInfo: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementati static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ 1: .standard(proto: "dst_mac"), 2: .standard(proto: "v4_info"), - 3: .standard(proto: "nat_type"), - 4: .standard(proto: "v6_info"), + 3: .standard(proto: "v6_info"), ] mutating func decodeMessage(decoder: inout D) throws { @@ -856,8 +839,7 @@ extension SDLPeerInfo: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementati switch fieldNumber { case 1: try { try decoder.decodeSingularBytesField(value: &self.dstMac) }() case 2: try { try decoder.decodeSingularMessageField(value: &self._v4Info) }() - case 3: try { try decoder.decodeSingularUInt32Field(value: &self.natType) }() - case 4: try { try decoder.decodeSingularMessageField(value: &self._v6Info) }() + case 3: try { try decoder.decodeSingularMessageField(value: &self._v6Info) }() default: break } } @@ -874,11 +856,8 @@ extension SDLPeerInfo: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementati try { if let v = self._v4Info { try visitor.visitSingularMessageField(value: v, fieldNumber: 2) } }() - if self.natType != 0 { - try visitor.visitSingularUInt32Field(value: self.natType, fieldNumber: 3) - } try { if let v = self._v6Info { - try visitor.visitSingularMessageField(value: v, fieldNumber: 4) + try visitor.visitSingularMessageField(value: v, fieldNumber: 3) } }() try unknownFields.traverse(visitor: &visitor) } @@ -886,7 +865,6 @@ extension SDLPeerInfo: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementati static func ==(lhs: SDLPeerInfo, rhs: SDLPeerInfo) -> Bool { if lhs.dstMac != rhs.dstMac {return false} if lhs._v4Info != rhs._v4Info {return false} - if lhs.natType != rhs.natType {return false} if lhs._v6Info != rhs._v6Info {return false} if lhs.unknownFields != rhs.unknownFields {return false} return true @@ -937,7 +915,8 @@ extension SDLSendRegisterEvent: SwiftProtobuf.Message, SwiftProtobuf._MessageImp 1: .standard(proto: "dst_mac"), 2: .standard(proto: "nat_ip"), 3: .standard(proto: "nat_port"), - 4: .standard(proto: "v6_info"), + 4: .standard(proto: "nat_type"), + 5: .standard(proto: "v6_info"), ] mutating func decodeMessage(decoder: inout D) throws { @@ -949,7 +928,8 @@ extension SDLSendRegisterEvent: SwiftProtobuf.Message, SwiftProtobuf._MessageImp case 1: try { try decoder.decodeSingularBytesField(value: &self.dstMac) }() case 2: try { try decoder.decodeSingularUInt32Field(value: &self.natIp) }() case 3: try { try decoder.decodeSingularUInt32Field(value: &self.natPort) }() - case 4: try { try decoder.decodeSingularMessageField(value: &self._v6Info) }() + case 4: try { try decoder.decodeSingularUInt32Field(value: &self.natType) }() + case 5: try { try decoder.decodeSingularMessageField(value: &self._v6Info) }() default: break } } @@ -969,8 +949,11 @@ extension SDLSendRegisterEvent: SwiftProtobuf.Message, SwiftProtobuf._MessageImp if self.natPort != 0 { try visitor.visitSingularUInt32Field(value: self.natPort, fieldNumber: 3) } + if self.natType != 0 { + try visitor.visitSingularUInt32Field(value: self.natType, fieldNumber: 4) + } try { if let v = self._v6Info { - try visitor.visitSingularMessageField(value: v, fieldNumber: 4) + try visitor.visitSingularMessageField(value: v, fieldNumber: 5) } }() try unknownFields.traverse(visitor: &visitor) } @@ -979,6 +962,7 @@ extension SDLSendRegisterEvent: SwiftProtobuf.Message, SwiftProtobuf._MessageImp if lhs.dstMac != rhs.dstMac {return false} if lhs.natIp != rhs.natIp {return false} if lhs.natPort != rhs.natPort {return false} + if lhs.natType != rhs.natType {return false} if lhs._v6Info != rhs._v6Info {return false} if lhs.unknownFields != rhs.unknownFields {return false} return true diff --git a/Tun/Punchnet/SDLSuperClient.swift b/Tun/Punchnet/SDLSuperClient.swift index dd4a98e..82f18d2 100644 --- a/Tun/Punchnet/SDLSuperClient.swift +++ b/Tun/Punchnet/SDLSuperClient.swift @@ -148,6 +148,9 @@ actor SDLSuperClient { registerSuper.devAddr = ctx.devAddr registerSuper.pubKey = ctx.rsaCipher.pubKey registerSuper.token = ctx.config.token + registerSuper.networkCode = ctx.config.networkCode + + NSLog("[SuperClient] register super request: \(registerSuper)") let data = try! registerSuper.serializedData() diff --git a/Tun/Punchnet/SDLUDPHole.swift b/Tun/Punchnet/SDLUDPHole.swift index 2e0209a..e8b7aba 100644 --- a/Tun/Punchnet/SDLUDPHole.swift +++ b/Tun/Punchnet/SDLUDPHole.swift @@ -128,7 +128,11 @@ actor SDLUDPHole { // MARK: super_node apis - func stunRequest(context ctx: SDLContext) -> UInt32 { + func stunRequest(context ctx: SDLContext) -> UInt32? { + guard ctx.devAddr.networkID > 0 else { + return nil + } + let cookie = self.cookieGenerator.nextId() let remoteAddress = ctx.config.stunSocketAddress @@ -140,7 +144,7 @@ actor SDLUDPHole { stunRequest.mac = ctx.devAddr.mac stunRequest.natType = UInt32(ctx.natType.rawValue) - self.logger.log("[SDLUDPHole] stunRequest: \(remoteAddress), host: \(ctx.config.stunServers[0].host):\(ctx.config.stunServers[0].ports[0])", level: .debug) + self.logger.log("[SDLUDPHole] stunRequest: \(remoteAddress), host: \(ctx.config.stunServers[0].host):\(ctx.config.stunServers[0].ports[0]), network_id: \(ctx.devAddr.networkID)", level: .debug) self.send(remoteAddress: remoteAddress, type: .stunRequest, data: try! stunRequest.serializedData()) diff --git a/punchnet.xcodeproj/project.pbxproj b/punchnet.xcodeproj/project.pbxproj index a60892e..6c862fb 100644 --- a/punchnet.xcodeproj/project.pbxproj +++ b/punchnet.xcodeproj/project.pbxproj @@ -561,6 +561,7 @@ ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; CODE_SIGN_ENTITLEMENTS = punchnet/punchnet.entitlements; + CODE_SIGN_IDENTITY = "Apple Development"; "CODE_SIGN_IDENTITY[sdk=macosx*]" = "Mac Developer"; CODE_SIGN_STYLE = Manual; COMBINE_HIDPI_IMAGES = YES; @@ -578,10 +579,10 @@ ); MACOSX_DEPLOYMENT_TARGET = 14.6; MARKETING_VERSION = 1.0; - PRODUCT_BUNDLE_IDENTIFIER = com.jihe.punchnet; + PRODUCT_BUNDLE_IDENTIFIER = com.jihe.punchnetmac; PRODUCT_NAME = "$(TARGET_NAME)"; PROVISIONING_PROFILE_SPECIFIER = ""; - "PROVISIONING_PROFILE_SPECIFIER[sdk=macosx*]" = MacPunchnet; + "PROVISIONING_PROFILE_SPECIFIER[sdk=macosx*]" = MacPunchnetTest; SWIFT_EMIT_LOC_STRINGS = YES; SWIFT_VERSION = 5.0; }; @@ -593,6 +594,7 @@ ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; CODE_SIGN_ENTITLEMENTS = punchnet/punchnet.entitlements; + CODE_SIGN_IDENTITY = "Apple Development"; "CODE_SIGN_IDENTITY[sdk=macosx*]" = "Mac Developer"; CODE_SIGN_STYLE = Manual; COMBINE_HIDPI_IMAGES = YES; @@ -610,10 +612,10 @@ ); MACOSX_DEPLOYMENT_TARGET = 14.6; MARKETING_VERSION = 1.0; - PRODUCT_BUNDLE_IDENTIFIER = com.jihe.punchnet; + PRODUCT_BUNDLE_IDENTIFIER = com.jihe.punchnetmac; PRODUCT_NAME = "$(TARGET_NAME)"; PROVISIONING_PROFILE_SPECIFIER = ""; - "PROVISIONING_PROFILE_SPECIFIER[sdk=macosx*]" = MacPunchnet; + "PROVISIONING_PROFILE_SPECIFIER[sdk=macosx*]" = MacPunchnetTest; SWIFT_EMIT_LOC_STRINGS = YES; SWIFT_VERSION = 5.0; }; @@ -658,6 +660,7 @@ C8A77F212DD1E6D100195617 /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { + "CODE_SIGN_IDENTITY[sdk=macosx*]" = "Apple Development"; CODE_SIGN_STYLE = Automatic; CURRENT_PROJECT_VERSION = 1; DEVELOPMENT_TEAM = PF3QG837XS; @@ -675,6 +678,7 @@ C8A77F222DD1E6D100195617 /* Release */ = { isa = XCBuildConfiguration; buildSettings = { + "CODE_SIGN_IDENTITY[sdk=macosx*]" = "Apple Development"; CODE_SIGN_STYLE = Automatic; CURRENT_PROJECT_VERSION = 1; DEVELOPMENT_TEAM = PF3QG837XS; @@ -711,10 +715,10 @@ ); MACOSX_DEPLOYMENT_TARGET = 14.6; MARKETING_VERSION = 1.0; - PRODUCT_BUNDLE_IDENTIFIER = com.jihe.punchnet.tun; + PRODUCT_BUNDLE_IDENTIFIER = com.jihe.punchnetmac.tun; PRODUCT_NAME = "$(TARGET_NAME)"; PROVISIONING_PROFILE_SPECIFIER = ""; - "PROVISIONING_PROFILE_SPECIFIER[sdk=macosx*]" = MacPunchnetTun; + "PROVISIONING_PROFILE_SPECIFIER[sdk=macosx*]" = MacPunchnetTunTest; SKIP_INSTALL = YES; SWIFT_EMIT_LOC_STRINGS = YES; SWIFT_VERSION = 5.0; @@ -743,10 +747,10 @@ ); MACOSX_DEPLOYMENT_TARGET = 14.6; MARKETING_VERSION = 1.0; - PRODUCT_BUNDLE_IDENTIFIER = com.jihe.punchnet.tun; + PRODUCT_BUNDLE_IDENTIFIER = com.jihe.punchnetmac.tun; PRODUCT_NAME = "$(TARGET_NAME)"; PROVISIONING_PROFILE_SPECIFIER = ""; - "PROVISIONING_PROFILE_SPECIFIER[sdk=macosx*]" = MacPunchnetTun; + "PROVISIONING_PROFILE_SPECIFIER[sdk=macosx*]" = MacPunchnetTunTest; SKIP_INSTALL = YES; SWIFT_EMIT_LOC_STRINGS = YES; SWIFT_VERSION = 5.0; diff --git a/punchnet.xcodeproj/xcuserdata/anlicheng.xcuserdatad/xcschemes/xcschememanagement.plist b/punchnet.xcodeproj/xcuserdata/anlicheng.xcuserdatad/xcschemes/xcschememanagement.plist index 3accfd2..9a89690 100644 --- a/punchnet.xcodeproj/xcuserdata/anlicheng.xcuserdatad/xcschemes/xcschememanagement.plist +++ b/punchnet.xcodeproj/xcuserdata/anlicheng.xcuserdatad/xcschemes/xcschememanagement.plist @@ -7,17 +7,17 @@ Tun.xcscheme_^#shared#^_ orderHint - 0 + 2 punchnet.xcscheme_^#shared#^_ orderHint - 2 + 1 punchnetTests.xcscheme_^#shared#^_ orderHint - 1 + 0 punchnetUITests.xcscheme_^#shared#^_ diff --git a/punchnet/Core/SDLAPI.swift b/punchnet/Core/SDLAPI.swift index e3a5824..48aacec 100644 --- a/punchnet/Core/SDLAPI.swift +++ b/punchnet/Core/SDLAPI.swift @@ -20,12 +20,23 @@ struct JSONRPCError: Decodable { struct SDLAPI { + static let baseUrl: String = "https://punchnet.s5s8.com/api" + static let testBaseUrl: String = "http://127.0.0.1:19082/test" + struct Upgrade: Decodable { let upgrade_type: Int let upgrade_prompt: String let upgrade_address: String } - + + struct NetworkProfile: Decodable { + struct NetworkItem: Decodable { + let name: String + let code: String + } + let network: [NetworkItem] + } + static func checkVersion(clientId: String, version: Int, channel: String) async throws -> JSONRPCResponse { let params: [String:Any] = [ "client_id": clientId, @@ -34,7 +45,7 @@ struct SDLAPI { ] let postData = try! JSONSerialization.data(withJSONObject: params) - var request = URLRequest(url: URL(string: "http://127.0.0.1:18082/test/upgrade")!) + var request = URLRequest(url: URL(string: baseUrl + "/upgrade")!) request.httpMethod = "POST" request.addValue("application/json", forHTTPHeaderField: "Content-Type") request.httpBody = postData @@ -44,4 +55,20 @@ struct SDLAPI { return try JSONDecoder().decode(JSONRPCResponse.self, from: data) } + static func getUserNetworks(clientId: String) async throws -> JSONRPCResponse { + let params: [String:Any] = [ + "client_id": clientId + ] + + let postData = try! JSONSerialization.data(withJSONObject: params) + var request = URLRequest(url: URL(string: baseUrl + "/get_user_network")!) + request.httpMethod = "POST" + request.addValue("application/json", forHTTPHeaderField: "Content-Type") + request.httpBody = postData + + let (data, _) = try await URLSession.shared.data(for: request) + + return try JSONDecoder().decode(JSONRPCResponse.self, from: data) + } + } diff --git a/punchnet/Core/SystemConfig.swift b/punchnet/Core/SystemConfig.swift index a20bac1..a6f3834 100644 --- a/punchnet/Core/SystemConfig.swift +++ b/punchnet/Core/SystemConfig.swift @@ -19,29 +19,43 @@ struct SystemConfig { // super 节点 //static let superHost = "118.178.229.213" - static let superHost = "punchnet.aioe.tech" + static let superHost = "punchnet.s5s8.com" static let superPort = 18083 // stun探测服务 static let stunServers = "118.178.229.213:1265,1266;118.178.229.213:1265,1266" + //static let stunServers = "127.0.0.1:1265,1266;127.0.0.1:1265,1266" - static func getOptions(token: String, noticePort: Int) -> [String:NSObject]? { + static func getOptions(networkCode: String, token: String, clientId: String, noticePort: Int) -> [String:NSObject]? { guard let superIp = DNSResolver.resolveAddrInfos(superHost).first else { return nil } + let options = [ "version:": version as NSObject, "installed_channel": installedChannel as NSObject, + "client_id": clientId as NSObject, + "network_code": networkCode as NSObject, "token": token as NSObject, - "super_ip": "118.178.229.213" as NSObject, + "super_ip": superIp as NSObject, "super_port": superPort as NSObject, "stun_servers": stunServers as NSObject, "notice_port": noticePort as NSObject ] - print("options: \(options)") - return options } + public static func getClientId() -> String { + let userDefaults = UserDefaults.standard + if let uuid = userDefaults.value(forKey: "gClientId") as? String { + return uuid + } else { + let uuid = UUID().uuidString.replacingOccurrences(of: "-", with: "").lowercased() + userDefaults.setValue(uuid, forKey: "gClientId") + + return uuid + } + } + } diff --git a/punchnet/Core/VPNManager.swift b/punchnet/Core/VPNManager.swift index a06e6c8..ec8ec80 100644 --- a/punchnet/Core/VPNManager.swift +++ b/punchnet/Core/VPNManager.swift @@ -28,6 +28,7 @@ class VPNManager: ObservableObject { // 开启vpn func enableVpn(options: [String : NSObject]) async throws { + NSLog("enable vpn with options: \(options)") let manager = try await loadAndCreateProviderManager() try await manager.loadFromPreferences() self.addVPNStatusObserver(manager) @@ -73,14 +74,14 @@ class VPNManager: ObservableObject { let managers = try await NETunnelProviderManager.loadAllFromPreferences() let manager = managers.first ?? NETunnelProviderManager() - manager.localizedDescription = "punchnet" + manager.localizedDescription = "punchnetmac" manager.isEnabled = true // 设置相关参数,在PacketTunnel中可以用 let protocolConfiguration = NETunnelProviderProtocol() - protocolConfiguration.serverAddress = "punchnet" + protocolConfiguration.serverAddress = "punchnetmac" protocolConfiguration.providerConfiguration = [String:AnyObject]() - protocolConfiguration.providerBundleIdentifier = "com.jihe.punchnet.tun" + protocolConfiguration.providerBundleIdentifier = "com.jihe.punchnetmac.tun" manager.protocolConfiguration = protocolConfiguration manager.isOnDemandEnabled = false diff --git a/punchnet/Views/IndexView.swift b/punchnet/Views/IndexView.swift index 87f81ac..8b0f599 100644 --- a/punchnet/Views/IndexView.swift +++ b/punchnet/Views/IndexView.swift @@ -11,6 +11,8 @@ import Combine struct IndexView: View { @AppStorage("token") private var token: String = "" + @AppStorage("network_code") private var networkCode: String = "" + @State private var showToken: Bool = false @ObservedObject private var vpnManager = VPNManager.shared @@ -21,6 +23,9 @@ struct IndexView: View { @State private var showMenu: Bool = false + @State private var networkProfile: SDLAPI.NetworkProfile = .init(network: []) + @State private var selectedIdx: Int = 0 + // 显示ip信息 @State private var showIpAdress: Bool = false @State private var ipAddress: String = "" @@ -74,16 +79,34 @@ struct IndexView: View { Spacer() .frame(width: 1, height: 10) - if showToken { - TextField("邀请码", text: $token) - .multilineTextAlignment(.leading) - .textFieldStyle(PlainTextFieldStyle()) - .frame(width: 200, height: 25) - .background(Color.white) - .foregroundColor(Color.black) - .cornerRadius(5.0) + VStack(spacing: 0) { + ForEach(Array(networkProfile.network.enumerated()), id: \.offset) { idx, network in + NetworkItemView(idx: idx, item: network) + .padding(.horizontal, 8) + .padding(.vertical, 6) + .background( + RoundedRectangle(cornerRadius: 8) + .fill(selectedIdx == idx ? Color.blue.opacity(0.3) : Color.clear) + ) + .contentShape(Rectangle()) + .onTapGesture { + withAnimation(.easeInOut(duration: 0.2)) { + selectedIdx = idx + self.networkCode = network.code + } + } + } } + TextField("邀请码", text: $token) + .multilineTextAlignment(.leading) + .textFieldStyle(PlainTextFieldStyle()) + .frame(width: 200, height: 25) + .background(Color.white) + .foregroundColor(Color.black) + .cornerRadius(5.0) + .opacity(showToken ? 1 : 0) + Spacer() .frame(width: 1, height: 10) @@ -105,8 +128,6 @@ struct IndexView: View { } } } - - Spacer() } .overlay(alignment: .top) { @@ -184,8 +205,10 @@ struct IndexView: View { } .offset(x: 0, y: 10) } - .frame(width: 300, height: 500) + .padding([.leading, .trailing, .top], 10) + .padding([.bottom], 20) .background(Color(red: 36 / 255, green: 38 / 255, blue: 51 / 255)) + .frame(width: 320) .alert(isPresented: $showAlert) { Alert(title: Text("请输入正确的邀请码")) } @@ -199,6 +222,20 @@ struct IndexView: View { Alert(title: Text("")) } } + .task { + do { + let response = try await SDLAPI.getUserNetworks(clientId: SystemConfig.getClientId()) + print("get user networks: \(response)") + if let result = response.result { + self.networkProfile = result + if self.networkProfile.network.count > 0 { + self.networkCode = self.networkProfile.network[0].code + } + } + } catch let err { + NSLog("get user networks get error: \(err)") + } + } .onAppear { self.cancel = self.noticeServer.messageFlow.sink{ message in DispatchQueue.main.async { @@ -224,13 +261,39 @@ struct IndexView: View { self.ipAddress = "" try await vpnManager.disableVpn() case .disconnected: - try await vpnManager.enableVpn(options: SystemConfig.getOptions(token: self.token, noticePort: self.noticeServer.port)!) + let clientId = SystemConfig.getClientId() + NSLog("[IndexView] use token: \(self.token), network_code: \(networkCode)") + // token存在则优先使用token + try await vpnManager.enableVpn(options: SystemConfig.getOptions(networkCode: self.networkCode, token: self.token, clientId: clientId, noticePort: self.noticeServer.port)!) } } } +extension IndexView { + struct NetworkItemView: View { + let idx: Int + let item: SDLAPI.NetworkProfile.NetworkItem + + var body: some View { + HStack { + Text(item.name) + .font(.system(size: 14)) + .foregroundColor(.white) + .frame(width: 80, alignment: .leading) + + Text(item.code) + .font(.system(size: 14)) + .foregroundColor(.white) + + Spacer() + } + } + } +} + #Preview { - //IndexView(noticeServer: server) + let server = UDPNoticeCenterServer() + IndexView(noticeServer: server) //.modelContainer(for: Item.self, inMemory: true) } diff --git a/punchnet/punchnetApp.swift b/punchnet/punchnetApp.swift index cda4f5c..0c3b947 100644 --- a/punchnet/punchnetApp.swift +++ b/punchnet/punchnetApp.swift @@ -31,6 +31,7 @@ struct punchnetApp: App { @NSApplicationDelegateAdaptor(AppDelegate.self) var appDelegate @AppStorage("token") var token: String = "" + @AppStorage("network_code") var networkCode: String = "" @ObservedObject var vpnManager = VPNManager.shared private var noticeServer: UDPNoticeCenterServer @@ -43,7 +44,6 @@ struct punchnetApp: App { var body: some Scene { WindowGroup(id: "mainWindow") { IndexView(noticeServer: self.noticeServer) - .frame(minWidth: 300, maxWidth: 300, minHeight: 500, maxHeight: 500) .onAppear { // 获取主屏幕的尺寸 guard let screenFrame = NSScreen.main?.frame else { return } @@ -103,7 +103,8 @@ struct punchnetApp: App { switch self.vpnManager.vpnStatus { case .disconnected: Task { - try await vpnManager.enableVpn(options: SystemConfig.getOptions(token: self.token, noticePort: self.noticeServer.port)!) + let clientId = SystemConfig.getClientId() + try await vpnManager.enableVpn(options: SystemConfig.getOptions(networkCode: self.networkCode, token: self.token, clientId: clientId, noticePort: self.noticeServer.port)!) } case .connected: Task {