This commit is contained in:
anlicheng 2025-05-12 16:39:10 +08:00
parent 269ee4f524
commit e2599ed57b
4 changed files with 214 additions and 120 deletions

View File

@ -9,6 +9,15 @@
/* Begin PBXBuildFile section */
C8A77F2A2DD1E77B00195617 /* NetworkExtension.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = C8A77F292DD1E77B00195617 /* NetworkExtension.framework */; };
C8A77F322DD1E77B00195617 /* Tun.appex in Embed Foundation Extensions */ = {isa = PBXBuildFile; fileRef = C8A77F272DD1E77B00195617 /* Tun.appex */; settings = {ATTRIBUTES = (RemoveHeadersOnCopy, ); }; };
C8A77F792DD1E93900195617 /* NIO in Frameworks */ = {isa = PBXBuildFile; productRef = C8A77F782DD1E93900195617 /* NIO */; };
C8A77F7B2DD1E93900195617 /* NIOConcurrencyHelpers in Frameworks */ = {isa = PBXBuildFile; productRef = C8A77F7A2DD1E93900195617 /* NIOConcurrencyHelpers */; };
C8A77F7D2DD1E93900195617 /* NIOCore in Frameworks */ = {isa = PBXBuildFile; productRef = C8A77F7C2DD1E93900195617 /* NIOCore */; };
C8A77F7F2DD1E93900195617 /* NIOEmbedded in Frameworks */ = {isa = PBXBuildFile; productRef = C8A77F7E2DD1E93900195617 /* NIOEmbedded */; };
C8A77F812DD1E93900195617 /* NIOFoundationCompat in Frameworks */ = {isa = PBXBuildFile; productRef = C8A77F802DD1E93900195617 /* NIOFoundationCompat */; };
C8A77F832DD1E98B00195617 /* NIO in Frameworks */ = {isa = PBXBuildFile; productRef = C8A77F822DD1E98B00195617 /* NIO */; };
C8A77F852DD1E99300195617 /* NIOCore in Frameworks */ = {isa = PBXBuildFile; productRef = C8A77F842DD1E99300195617 /* NIOCore */; };
C8A77F882DD1EA0200195617 /* SwiftProtobuf in Frameworks */ = {isa = PBXBuildFile; productRef = C8A77F872DD1EA0200195617 /* SwiftProtobuf */; };
C8A77F8A2DD1EA0200195617 /* SwiftProtobufPluginLibrary in Frameworks */ = {isa = PBXBuildFile; productRef = C8A77F892DD1EA0200195617 /* SwiftProtobufPluginLibrary */; };
/* End PBXBuildFile section */
/* Begin PBXContainerItemProxy section */
@ -65,11 +74,21 @@
);
target = C8A77F262DD1E77B00195617 /* Tun */;
};
C8A77F8C2DD1EA7900195617 /* Exceptions for "punchnet" folder in "Tun" target */ = {
isa = PBXFileSystemSynchronizedBuildFileExceptionSet;
membershipExceptions = (
Core/NoticeMessage.swift,
);
target = C8A77F262DD1E77B00195617 /* Tun */;
};
/* End PBXFileSystemSynchronizedBuildFileExceptionSet section */
/* Begin PBXFileSystemSynchronizedRootGroup section */
C8A77EF52DD1E6D000195617 /* punchnet */ = {
isa = PBXFileSystemSynchronizedRootGroup;
exceptions = (
C8A77F8C2DD1EA7900195617 /* Exceptions for "punchnet" folder in "Tun" target */,
);
path = punchnet;
sourceTree = "<group>";
};
@ -98,6 +117,11 @@
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
C8A77F7D2DD1E93900195617 /* NIOCore in Frameworks */,
C8A77F812DD1E93900195617 /* NIOFoundationCompat in Frameworks */,
C8A77F792DD1E93900195617 /* NIO in Frameworks */,
C8A77F7B2DD1E93900195617 /* NIOConcurrencyHelpers in Frameworks */,
C8A77F7F2DD1E93900195617 /* NIOEmbedded in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@ -119,7 +143,11 @@
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
C8A77F852DD1E99300195617 /* NIOCore in Frameworks */,
C8A77F2A2DD1E77B00195617 /* NetworkExtension.framework in Frameworks */,
C8A77F8A2DD1EA0200195617 /* SwiftProtobufPluginLibrary in Frameworks */,
C8A77F832DD1E98B00195617 /* NIO in Frameworks */,
C8A77F882DD1EA0200195617 /* SwiftProtobuf in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@ -179,6 +207,11 @@
);
name = punchnet;
packageProductDependencies = (
C8A77F782DD1E93900195617 /* NIO */,
C8A77F7A2DD1E93900195617 /* NIOConcurrencyHelpers */,
C8A77F7C2DD1E93900195617 /* NIOCore */,
C8A77F7E2DD1E93900195617 /* NIOEmbedded */,
C8A77F802DD1E93900195617 /* NIOFoundationCompat */,
);
productName = punchnet;
productReference = C8A77EF32DD1E6D000195617 /* punchnet.app */;
@ -247,6 +280,10 @@
);
name = Tun;
packageProductDependencies = (
C8A77F822DD1E98B00195617 /* NIO */,
C8A77F842DD1E99300195617 /* NIOCore */,
C8A77F872DD1EA0200195617 /* SwiftProtobuf */,
C8A77F892DD1EA0200195617 /* SwiftProtobufPluginLibrary */,
);
productName = Tun;
productReference = C8A77F272DD1E77B00195617 /* Tun.appex */;
@ -287,6 +324,10 @@
);
mainGroup = C8A77EEA2DD1E6D000195617;
minimizedProjectReferenceProxies = 1;
packageReferences = (
C8A77F772DD1E93900195617 /* XCLocalSwiftPackageReference "../../packages/swift-nio" */,
C8A77F862DD1EA0200195617 /* XCLocalSwiftPackageReference "../../packages/swift-protobuf" */,
);
preferredProjectObjectVersion = 77;
productRefGroup = C8A77EF42DD1E6D000195617 /* Products */;
projectDirPath = "";
@ -724,6 +765,58 @@
defaultConfigurationName = Release;
};
/* End XCConfigurationList section */
/* Begin XCLocalSwiftPackageReference section */
C8A77F772DD1E93900195617 /* XCLocalSwiftPackageReference "../../packages/swift-nio" */ = {
isa = XCLocalSwiftPackageReference;
relativePath = "../../packages/swift-nio";
};
C8A77F862DD1EA0200195617 /* XCLocalSwiftPackageReference "../../packages/swift-protobuf" */ = {
isa = XCLocalSwiftPackageReference;
relativePath = "../../packages/swift-protobuf";
};
/* End XCLocalSwiftPackageReference section */
/* Begin XCSwiftPackageProductDependency section */
C8A77F782DD1E93900195617 /* NIO */ = {
isa = XCSwiftPackageProductDependency;
productName = NIO;
};
C8A77F7A2DD1E93900195617 /* NIOConcurrencyHelpers */ = {
isa = XCSwiftPackageProductDependency;
productName = NIOConcurrencyHelpers;
};
C8A77F7C2DD1E93900195617 /* NIOCore */ = {
isa = XCSwiftPackageProductDependency;
productName = NIOCore;
};
C8A77F7E2DD1E93900195617 /* NIOEmbedded */ = {
isa = XCSwiftPackageProductDependency;
productName = NIOEmbedded;
};
C8A77F802DD1E93900195617 /* NIOFoundationCompat */ = {
isa = XCSwiftPackageProductDependency;
productName = NIOFoundationCompat;
};
C8A77F822DD1E98B00195617 /* NIO */ = {
isa = XCSwiftPackageProductDependency;
package = C8A77F772DD1E93900195617 /* XCLocalSwiftPackageReference "../../packages/swift-nio" */;
productName = NIO;
};
C8A77F842DD1E99300195617 /* NIOCore */ = {
isa = XCSwiftPackageProductDependency;
package = C8A77F772DD1E93900195617 /* XCLocalSwiftPackageReference "../../packages/swift-nio" */;
productName = NIOCore;
};
C8A77F872DD1EA0200195617 /* SwiftProtobuf */ = {
isa = XCSwiftPackageProductDependency;
productName = SwiftProtobuf;
};
C8A77F892DD1EA0200195617 /* SwiftProtobufPluginLibrary */ = {
isa = XCSwiftPackageProductDependency;
productName = SwiftProtobufPluginLibrary;
};
/* End XCSwiftPackageProductDependency section */
};
rootObject = C8A77EEB2DD1E6D000195617 /* Project object */;
}

View File

@ -0,0 +1,33 @@
{
"originHash" : "fc5ff56467a09054cad310ea04e2207caefea4e4c42012fbd995ed64d089417b",
"pins" : [
{
"identity" : "swift-atomics",
"kind" : "remoteSourceControl",
"location" : "https://github.com/apple/swift-atomics.git",
"state" : {
"revision" : "cd142fd2f64be2100422d658e7411e39489da985",
"version" : "1.2.0"
}
},
{
"identity" : "swift-collections",
"kind" : "remoteSourceControl",
"location" : "https://github.com/apple/swift-collections.git",
"state" : {
"revision" : "671108c96644956dddcd89dd59c203dcdb36cec7",
"version" : "1.1.4"
}
},
{
"identity" : "swift-system",
"kind" : "remoteSourceControl",
"location" : "https://github.com/apple/swift-system.git",
"state" : {
"revision" : "a34201439c74b53f0fd71ef11741af7e7caf01e1",
"version" : "1.4.2"
}
}
],
"version" : 3
}

View File

@ -6,10 +6,13 @@
//
import SwiftUI
import AppKit
import SwiftData
import Combine
@main
struct punchnetApp: App {
/*
var sharedModelContainer: ModelContainer = {
let schema = Schema([
Item.self,
@ -22,11 +25,93 @@ struct punchnetApp: App {
fatalError("Could not create ModelContainer: \(error)")
}
}()
*/
@Environment(\.openWindow) private var openWindow
@NSApplicationDelegateAdaptor(AppDelegate.self) var appDelegate
@AppStorage("token") var token: String = ""
@ObservedObject var vpnManager = VPNManager.shared
var body: some Scene {
WindowGroup {
WindowGroup(id: "mainWindow") {
ContentView()
}
.modelContainer(sharedModelContainer)
.commands {
CommandGroup(replacing: .appInfo) {
Button {
openWindow(id: "abortSDLAN")
} label: {
Text("About sdlan")
}
}
}
Window("", id: "abortSDLAN") {
AbortView()
}
//.modelContainer(sharedModelContainer)
MenuBarExtra("sdlanApp", systemImage: "hammer") {
VStack {
Button(action: {
self.menuClick()
}, label: {
Text(vpnManager.title)
})
Divider()
Button(action: {
NSApplication.shared.terminate(nil)
}, label: { Text("退出") })
}
}
.menuBarExtraStyle(.menu)
}
private func menuClick() {
switch self.vpnManager.vpnStatus {
case .disconnected:
if token.isEmpty {
let windows = NSApplication.shared.windows
if let window = windows.first(where: {$0.title == "sdlan"}) {
window.level = .floating
} else {
self.openWindow(id: "mainWindow")
}
} else {
Task {
try await vpnManager.enableVpn(options: ["token": token as NSObject])
}
}
case .connected:
Task {
try await vpnManager.disableVpn()
}
}
}
}
// APP
class AppDelegate: NSObject, NSApplicationDelegate {
func applicationWillFinishLaunching(_ notification: Notification) {
UDPNoticeCenterServer.shared.start()
}
func applicationShouldTerminate(_ sender: NSApplication) -> NSApplication.TerminateReply {
Task {
try await VPNManager.shared.disableVpn()
DispatchQueue.main.async {
sender.reply(toApplicationShouldTerminate: true)
}
UDPNoticeCenterServer.shared.stop()
}
return .terminateLater
}
}

View File

@ -1,117 +0,0 @@
//
// sdlanApp.swift
// sdlan
//
// Created by on 2024/1/17.
//
import SwiftUI
import AppKit
import SwiftData
import Combine
@main
struct sdlanApp: App {
/*
var sharedModelContainer: ModelContainer = {
let schema = Schema([
Item.self,
])
let modelConfiguration = ModelConfiguration(schema: schema, isStoredInMemoryOnly: false)
do {
return try ModelContainer(for: schema, configurations: [modelConfiguration])
} catch {
fatalError("Could not create ModelContainer: \(error)")
}
}()
*/
@Environment(\.openWindow) private var openWindow
@NSApplicationDelegateAdaptor(AppDelegate.self) var appDelegate
@AppStorage("token") var token: String = ""
@ObservedObject var vpnManager = VPNManager.shared
var body: some Scene {
WindowGroup(id: "mainWindow") {
ContentView()
}
.commands {
CommandGroup(replacing: .appInfo) {
Button {
openWindow(id: "abortSDLAN")
} label: {
Text("About sdlan")
}
}
}
Window("", id: "abortSDLAN") {
AbortView()
}
//.modelContainer(sharedModelContainer)
MenuBarExtra("sdlanApp", systemImage: "hammer") {
VStack {
Button(action: {
self.menuClick()
}, label: {
Text(vpnManager.title)
})
Divider()
Button(action: {
NSApplication.shared.terminate(nil)
}, label: { Text("退出") })
}
}
.menuBarExtraStyle(.menu)
}
private func menuClick() {
switch self.vpnManager.vpnStatus {
case .disconnected:
if token.isEmpty {
let windows = NSApplication.shared.windows
if let window = windows.first(where: {$0.title == "sdlan"}) {
window.level = .floating
} else {
self.openWindow(id: "mainWindow")
}
} else {
Task {
try await vpnManager.enableVpn(options: ["token": token as NSObject])
}
}
case .connected:
Task {
try await vpnManager.disableVpn()
}
}
}
}
// APP
class AppDelegate: NSObject, NSApplicationDelegate {
func applicationWillFinishLaunching(_ notification: Notification) {
UDPNoticeCenterServer.shared.start()
}
func applicationShouldTerminate(_ sender: NSApplication) -> NSApplication.TerminateReply {
Task {
try await VPNManager.shared.disableVpn()
DispatchQueue.main.async {
sender.reply(toApplicationShouldTerminate: true)
}
UDPNoticeCenterServer.shared.stop()
}
return .terminateLater
}
}