mirror of
https://github.com/X1a0He/Adobe-Downloader.git
synced 2025-11-25 03:14:57 +08:00
feat: Detection of Setup components and version
This commit is contained in:
@@ -10,8 +10,21 @@
|
||||
3CB9FF092CDBAEF200D7A58B /* Sparkle in Frameworks */ = {isa = PBXBuildFile; productRef = 3CB9FF082CDBAEF200D7A58B /* Sparkle */; };
|
||||
/* End PBXBuildFile section */
|
||||
|
||||
/* Begin PBXCopyFilesBuildPhase section */
|
||||
3CE663452CE1FE8600CB9B35 /* CopyFiles */ = {
|
||||
isa = PBXCopyFilesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
dstPath = /usr/share/man/man1/;
|
||||
dstSubfolderSpec = 0;
|
||||
files = (
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 1;
|
||||
};
|
||||
/* End PBXCopyFilesBuildPhase section */
|
||||
|
||||
/* Begin PBXFileReference section */
|
||||
3CCC3AE02CC67B8F006E22B4 /* Adobe Downloader.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "Adobe Downloader.app"; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
3CE663472CE1FE8600CB9B35 /* AdobeDownloaderHelper */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = AdobeDownloaderHelper; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
/* End PBXFileReference section */
|
||||
|
||||
/* Begin PBXFileSystemSynchronizedBuildFileExceptionSet section */
|
||||
@@ -49,6 +62,13 @@
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
3CE663442CE1FE8600CB9B35 /* Frameworks */ = {
|
||||
isa = PBXFrameworksBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
/* End PBXFrameworksBuildPhase section */
|
||||
|
||||
/* Begin PBXGroup section */
|
||||
@@ -65,6 +85,7 @@
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
3CCC3AE02CC67B8F006E22B4 /* Adobe Downloader.app */,
|
||||
3CE663472CE1FE8600CB9B35 /* AdobeDownloaderHelper */,
|
||||
);
|
||||
name = Products;
|
||||
sourceTree = "<group>";
|
||||
@@ -96,6 +117,25 @@
|
||||
productReference = 3CCC3AE02CC67B8F006E22B4 /* Adobe Downloader.app */;
|
||||
productType = "com.apple.product-type.application";
|
||||
};
|
||||
3CE663462CE1FE8600CB9B35 /* AdobeDownloaderHelper */ = {
|
||||
isa = PBXNativeTarget;
|
||||
buildConfigurationList = 3CE6634B2CE1FE8600CB9B35 /* Build configuration list for PBXNativeTarget "AdobeDownloaderHelper" */;
|
||||
buildPhases = (
|
||||
3CE663432CE1FE8600CB9B35 /* Sources */,
|
||||
3CE663442CE1FE8600CB9B35 /* Frameworks */,
|
||||
3CE663452CE1FE8600CB9B35 /* CopyFiles */,
|
||||
);
|
||||
buildRules = (
|
||||
);
|
||||
dependencies = (
|
||||
);
|
||||
name = AdobeDownloaderHelper;
|
||||
packageProductDependencies = (
|
||||
);
|
||||
productName = AdobeDownloaderHelper;
|
||||
productReference = 3CE663472CE1FE8600CB9B35 /* AdobeDownloaderHelper */;
|
||||
productType = "com.apple.product-type.tool";
|
||||
};
|
||||
/* End PBXNativeTarget section */
|
||||
|
||||
/* Begin PBXProject section */
|
||||
@@ -103,12 +143,15 @@
|
||||
isa = PBXProject;
|
||||
attributes = {
|
||||
BuildIndependentTargetsInParallel = 1;
|
||||
LastSwiftUpdateCheck = 1600;
|
||||
LastSwiftUpdateCheck = 1610;
|
||||
LastUpgradeCheck = 1610;
|
||||
TargetAttributes = {
|
||||
3CCC3ADF2CC67B8F006E22B4 = {
|
||||
CreatedOnToolsVersion = 16.0;
|
||||
};
|
||||
3CE663462CE1FE8600CB9B35 = {
|
||||
CreatedOnToolsVersion = 16.1;
|
||||
};
|
||||
};
|
||||
};
|
||||
buildConfigurationList = 3CCC3ADB2CC67B8F006E22B4 /* Build configuration list for PBXProject "Adobe Downloader" */;
|
||||
@@ -129,6 +172,7 @@
|
||||
projectRoot = "";
|
||||
targets = (
|
||||
3CCC3ADF2CC67B8F006E22B4 /* Adobe Downloader */,
|
||||
3CE663462CE1FE8600CB9B35 /* AdobeDownloaderHelper */,
|
||||
);
|
||||
};
|
||||
/* End PBXProject section */
|
||||
@@ -151,6 +195,13 @@
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
3CE663432CE1FE8600CB9B35 /* Sources */ = {
|
||||
isa = PBXSourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
/* End PBXSourcesBuildPhase section */
|
||||
|
||||
/* Begin XCBuildConfiguration section */
|
||||
@@ -286,7 +337,7 @@
|
||||
CODE_SIGN_ENTITLEMENTS = "Adobe Downloader/Adobe Downloader.entitlements";
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
COMBINE_HIDPI_IMAGES = YES;
|
||||
CURRENT_PROJECT_VERSION = 110;
|
||||
CURRENT_PROJECT_VERSION = 120;
|
||||
DEAD_CODE_STRIPPING = YES;
|
||||
DEVELOPMENT_ASSET_PATHS = "\"Adobe Downloader/Preview Content\"";
|
||||
DEVELOPMENT_TEAM = "";
|
||||
@@ -294,13 +345,14 @@
|
||||
ENABLE_PREVIEWS = YES;
|
||||
GENERATE_INFOPLIST_FILE = YES;
|
||||
INFOPLIST_KEY_CFBundleDisplayName = "Adobe Downloader";
|
||||
INFOPLIST_KEY_NSDownloadsFolderUsageDescription = "需要访问下载文件夹来保存Adobe安装文件";
|
||||
INFOPLIST_KEY_NSHumanReadableCopyright = "";
|
||||
LD_RUNPATH_SEARCH_PATHS = (
|
||||
"$(inherited)",
|
||||
"@executable_path/../Frameworks",
|
||||
);
|
||||
MACOSX_DEPLOYMENT_TARGET = 12.0;
|
||||
MARKETING_VERSION = 1.1.0;
|
||||
MARKETING_VERSION = 1.2;
|
||||
PRODUCT_BUNDLE_IDENTIFIER = "com.x1a0he.macOS.Adobe-Downloader";
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
SWIFT_EMIT_LOC_STRINGS = YES;
|
||||
@@ -318,7 +370,7 @@
|
||||
"CODE_SIGN_IDENTITY[sdk=macosx*]" = "-";
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
COMBINE_HIDPI_IMAGES = YES;
|
||||
CURRENT_PROJECT_VERSION = 110;
|
||||
CURRENT_PROJECT_VERSION = 120;
|
||||
DEAD_CODE_STRIPPING = YES;
|
||||
DEVELOPMENT_ASSET_PATHS = "\"Adobe Downloader/Preview Content\"";
|
||||
DEVELOPMENT_TEAM = "";
|
||||
@@ -326,13 +378,14 @@
|
||||
ENABLE_PREVIEWS = YES;
|
||||
GENERATE_INFOPLIST_FILE = YES;
|
||||
INFOPLIST_KEY_CFBundleDisplayName = "Adobe Downloader";
|
||||
INFOPLIST_KEY_NSDownloadsFolderUsageDescription = "需要访问下载文件夹来保存Adobe安装文件";
|
||||
INFOPLIST_KEY_NSHumanReadableCopyright = "";
|
||||
LD_RUNPATH_SEARCH_PATHS = (
|
||||
"$(inherited)",
|
||||
"@executable_path/../Frameworks",
|
||||
);
|
||||
MACOSX_DEPLOYMENT_TARGET = 12.0;
|
||||
MARKETING_VERSION = 1.1.0;
|
||||
MARKETING_VERSION = 1.2;
|
||||
PRODUCT_BUNDLE_IDENTIFIER = "com.x1a0he.macOS.Adobe-Downloader";
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
SWIFT_EMIT_LOC_STRINGS = YES;
|
||||
@@ -340,6 +393,27 @@
|
||||
};
|
||||
name = Release;
|
||||
};
|
||||
3CE6634C2CE1FE8600CB9B35 /* Debug */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
MACOSX_DEPLOYMENT_TARGET = 15.1;
|
||||
ONLY_ACTIVE_ARCH = YES;
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
SWIFT_VERSION = 5.0;
|
||||
};
|
||||
name = Debug;
|
||||
};
|
||||
3CE6634D2CE1FE8600CB9B35 /* Release */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
MACOSX_DEPLOYMENT_TARGET = 15.1;
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
SWIFT_VERSION = 5.0;
|
||||
};
|
||||
name = Release;
|
||||
};
|
||||
/* End XCBuildConfiguration section */
|
||||
|
||||
/* Begin XCConfigurationList section */
|
||||
@@ -361,6 +435,15 @@
|
||||
defaultConfigurationIsVisible = 0;
|
||||
defaultConfigurationName = Release;
|
||||
};
|
||||
3CE6634B2CE1FE8600CB9B35 /* Build configuration list for PBXNativeTarget "AdobeDownloaderHelper" */ = {
|
||||
isa = XCConfigurationList;
|
||||
buildConfigurations = (
|
||||
3CE6634C2CE1FE8600CB9B35 /* Debug */,
|
||||
3CE6634D2CE1FE8600CB9B35 /* Release */,
|
||||
);
|
||||
defaultConfigurationIsVisible = 0;
|
||||
defaultConfigurationName = Release;
|
||||
};
|
||||
/* End XCConfigurationList section */
|
||||
|
||||
/* Begin XCRemoteSwiftPackageReference section */
|
||||
|
||||
@@ -31,7 +31,7 @@
|
||||
shouldAutocreateTestPlan = "YES">
|
||||
</TestAction>
|
||||
<LaunchAction
|
||||
buildConfiguration = "Release"
|
||||
buildConfiguration = "Debug"
|
||||
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
|
||||
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
|
||||
launchStyle = "0"
|
||||
|
||||
@@ -20,5 +20,21 @@
|
||||
landmarkType = "7">
|
||||
</BreakpointContent>
|
||||
</BreakpointProxy>
|
||||
<BreakpointProxy
|
||||
BreakpointExtensionID = "Xcode.Breakpoint.FileBreakpoint">
|
||||
<BreakpointContent
|
||||
uuid = "E5CEF575-C3CE-40C5-8038-C2BE8D9FAEA0"
|
||||
shouldBeEnabled = "No"
|
||||
ignoreCount = "0"
|
||||
continueAfterRunningActions = "No"
|
||||
filePath = "Adobe Downloader/Utils/InstallManager.swift"
|
||||
startingColumnNumber = "9223372036854775807"
|
||||
endingColumnNumber = "9223372036854775807"
|
||||
startingLineNumber = "143"
|
||||
endingLineNumber = "143"
|
||||
landmarkName = "install(at:progressHandler:logHandler:)"
|
||||
landmarkType = "7">
|
||||
</BreakpointContent>
|
||||
</BreakpointProxy>
|
||||
</Breakpoints>
|
||||
</Bucket>
|
||||
|
||||
@@ -14,6 +14,11 @@
|
||||
<key>orderHint</key>
|
||||
<integer>0</integer>
|
||||
</dict>
|
||||
<key>AdobeDownloaderHelper.xcscheme_^#shared#^_</key>
|
||||
<dict>
|
||||
<key>orderHint</key>
|
||||
<integer>1</integer>
|
||||
</dict>
|
||||
</dict>
|
||||
<key>SuppressBuildableAutocreation</key>
|
||||
<dict>
|
||||
|
||||
@@ -15,6 +15,9 @@ struct Adobe_DownloaderApp: App {
|
||||
@AppStorage("confirmRedownload") private var confirmRedownload: Bool = true
|
||||
@AppStorage("useDefaultDirectory") private var useDefaultDirectory: Bool = true
|
||||
@AppStorage("defaultDirectory") private var defaultDirectory: String = ""
|
||||
@State private var showBackupResultAlert = false
|
||||
@State private var backupResultMessage = ""
|
||||
@State private var backupSuccess = false
|
||||
private let updaterController: SPUStandardUpdaterController
|
||||
|
||||
init() {
|
||||
@@ -61,8 +64,8 @@ struct Adobe_DownloaderApp: App {
|
||||
networkManager.loadSavedTasks()
|
||||
|
||||
checkCreativeCloudSetup()
|
||||
|
||||
if ModifySetup.checkSetupBackup() {
|
||||
|
||||
if !showCreativeCloudAlert && !ModifySetup.isSetupBackup() {
|
||||
showBackupAlert = true
|
||||
}
|
||||
|
||||
@@ -71,18 +74,26 @@ struct Adobe_DownloaderApp: App {
|
||||
UserDefaults.standard.removeObject(forKey: "isFirstLaunch")
|
||||
}
|
||||
}
|
||||
.sheet(isPresented: $showCreativeCloudAlert) {
|
||||
ShouldExistsSetUpView()
|
||||
}
|
||||
.alert("Setup未备份提示", isPresented: $showBackupAlert) {
|
||||
Button("OK") {
|
||||
Button("确定") {
|
||||
ModifySetup.backupSetupFile { success, message in
|
||||
if !success {
|
||||
print(message)
|
||||
}
|
||||
backupSuccess = success
|
||||
backupResultMessage = message
|
||||
showBackupResultAlert = true
|
||||
}
|
||||
}
|
||||
Button("取消", role: .cancel) {}
|
||||
} message: {
|
||||
Text("检测到Setup文件尚未备份,如果你需要安装程序,则Setup必须被处理,点击确定后你需要输入密码,Adobe Downloader将自动处理并备份为Setup.original")
|
||||
}
|
||||
.alert(backupSuccess ? "备份成功" : "备份失败", isPresented: $showBackupResultAlert) {
|
||||
Button("确定") { }
|
||||
} message: {
|
||||
Text(backupResultMessage)
|
||||
}
|
||||
.sheet(isPresented: $showTipsSheet) {
|
||||
VStack(spacing: 20) {
|
||||
Text("Adobe Downloader 已为你默认设定如下值")
|
||||
@@ -161,19 +172,6 @@ struct Adobe_DownloaderApp: App {
|
||||
}
|
||||
}
|
||||
}
|
||||
.alert("未安装 Adobe Creative Cloud", isPresented: $showCreativeCloudAlert) {
|
||||
Button("前往下载") {
|
||||
if let url = URL(string: "https://creativecloud.adobe.com/apps/download/creative-cloud") {
|
||||
NSWorkspace.shared.open(url)
|
||||
}
|
||||
NSApplication.shared.terminate(nil)
|
||||
}
|
||||
Button("取消", role: .cancel) {
|
||||
NSApplication.shared.terminate(nil)
|
||||
}
|
||||
} message: {
|
||||
Text("需要先安装 Adobe Creative Cloud 才能继续使用本程序")
|
||||
}
|
||||
}
|
||||
.windowStyle(.hiddenTitleBar)
|
||||
.windowResizabilityContentSize()
|
||||
|
||||
@@ -86,6 +86,16 @@ struct ContentView: View {
|
||||
.padding(.vertical, 8)
|
||||
.background(Color(NSColor.windowBackgroundColor))
|
||||
|
||||
HStack() {
|
||||
Image(systemName: "exclamationmark.triangle.fill")
|
||||
.foregroundColor(.orange)
|
||||
Text("Adobe Downloader 完全开源免费: https://github.com/X1a0He/Adobe-Downloader")
|
||||
}
|
||||
.frame(maxWidth: .infinity, alignment: .leading)
|
||||
.padding(.horizontal)
|
||||
.padding(.bottom, 5)
|
||||
.background(Color(NSColor.windowBackgroundColor))
|
||||
|
||||
ZStack {
|
||||
Color(NSColor.windowBackgroundColor)
|
||||
.ignoresSafeArea()
|
||||
|
||||
@@ -2,30 +2,28 @@
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>com.apple.security.network.client</key>
|
||||
<true/>
|
||||
<key>com.apple.security.network.server</key>
|
||||
<true/>
|
||||
<key>NSAppTransportSecurity</key>
|
||||
<dict>
|
||||
<key>NSAllowsArbitraryLoads</key>
|
||||
<true/>
|
||||
</dict>
|
||||
<key>NSDownloadsFolderUsageDescription</key>
|
||||
<string>需要访问下载文件夹来保存Adobe安装文件</string>
|
||||
<key>SUFeedURL</key>
|
||||
<string>https://raw.githubusercontent.com/X1a0He/Adobe-Downloader/refs/heads/main/appcast.xml</string>
|
||||
<key>SUPublicEDKey</key>
|
||||
<string>gYylad3ybfiyK5ZTS3xRrw+3c/8063mpXdQnPpMB86Q=</string>
|
||||
<key>com.apple.security.app-sandbox</key>
|
||||
<true/>
|
||||
<key>com.apple.security.files.downloads.read-write</key>
|
||||
<true/>
|
||||
<key>com.apple.security.files.user-selected.read-write</key>
|
||||
<true/>
|
||||
<key>com.apple.security.network.client</key>
|
||||
<true/>
|
||||
<key>com.apple.security.network.server</key>
|
||||
<true/>
|
||||
<key>com.apple.security.temporary-exception.files.home-relative-path.read-write</key>
|
||||
<array>
|
||||
<string>/Downloads/</string>
|
||||
</array>
|
||||
<key>SUPublicEDKey</key>
|
||||
<string>gYylad3ybfiyK5ZTS3xRrw+3c/8063mpXdQnPpMB86Q=</string>
|
||||
<key>SUFeedURL</key>
|
||||
<string>https://raw.githubusercontent.com/X1a0He/Adobe-Downloader/refs/heads/main/appcast.xml</string>
|
||||
</dict>
|
||||
</plist>
|
||||
|
||||
@@ -94,7 +94,7 @@ actor InstallManager {
|
||||
let code = Int32(codeStr) {
|
||||
if code != 0 {
|
||||
let errorMessage = code == -1
|
||||
? String(localized: "安装程序调用失败,请联系X1a0He")
|
||||
? String(localized: "安装程序调用失败,Setup 组件未被处理,请联系开发者")
|
||||
: String(localized: "(退出代码: \(code))")
|
||||
|
||||
installProcess.terminate()
|
||||
@@ -115,9 +115,7 @@ actor InstallManager {
|
||||
if installProcess.terminationStatus == 0 {
|
||||
continuation.resume()
|
||||
} else {
|
||||
let errorMessage = withSudo
|
||||
? String(localized: "(退出代码: \(installProcess.terminationStatus))")
|
||||
: String(localized: "重试失败,需要重新输入密码")
|
||||
let errorMessage = String(localized: "(退出代码: \(installProcess.terminationStatus))")
|
||||
continuation.resume(throwing: InstallError.installationFailed(errorMessage))
|
||||
}
|
||||
} catch {
|
||||
@@ -154,9 +152,11 @@ actor InstallManager {
|
||||
logHandler: @escaping (String) -> Void
|
||||
) async throws {
|
||||
self.progressHandler = progressHandler
|
||||
let password = try await requestPassword()
|
||||
try await executeInstallation(
|
||||
at: appPath,
|
||||
withSudo: false,
|
||||
withSudo: true,
|
||||
password: password,
|
||||
progressHandler: progressHandler,
|
||||
logHandler: logHandler
|
||||
)
|
||||
|
||||
@@ -9,12 +9,64 @@ import Foundation
|
||||
import SwiftUI
|
||||
|
||||
class ModifySetup {
|
||||
static func checkSetupBackup() -> Bool {
|
||||
let setupPath = "/Library/Application Support/Adobe/Adobe Desktop Common/HDBox/Setup"
|
||||
let backupPath = "/Library/Application Support/Adobe/Adobe Desktop Common/HDBox/Setup.original"
|
||||
private static var cachedVersion: String?
|
||||
|
||||
static func checkComponentVersion() -> String {
|
||||
if let cachedVersion = cachedVersion {
|
||||
return cachedVersion
|
||||
}
|
||||
|
||||
return FileManager.default.fileExists(atPath: setupPath) &&
|
||||
!FileManager.default.fileExists(atPath: backupPath)
|
||||
let setupPath = "/Library/Application Support/Adobe/Adobe Desktop Common/HDBox/Setup"
|
||||
|
||||
guard FileManager.default.fileExists(atPath: setupPath) else {
|
||||
let message = String(localized: "未找到 Setup 组件")
|
||||
cachedVersion = message
|
||||
return message
|
||||
}
|
||||
|
||||
let process = Process()
|
||||
process.executableURL = URL(fileURLWithPath: "/usr/bin/strings")
|
||||
process.arguments = [setupPath]
|
||||
|
||||
let pipe = Pipe()
|
||||
process.standardOutput = pipe
|
||||
process.standardError = pipe
|
||||
|
||||
do {
|
||||
try process.run()
|
||||
process.waitUntilExit()
|
||||
|
||||
if let output = try pipe.fileHandleForReading.readToEnd(),
|
||||
let outputString = String(data: output, encoding: .utf8) {
|
||||
let lines = outputString.components(separatedBy: .newlines)
|
||||
for (index, line) in lines.enumerated() {
|
||||
if line == "Adobe Setup Version: %s" && index + 1 < lines.count {
|
||||
let version = lines[index + 1].trimmingCharacters(in: .whitespacesAndNewlines)
|
||||
if version.range(of: "^[0-9.]+$", options: .regularExpression) != nil {
|
||||
cachedVersion = version
|
||||
return version
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let message = String(localized: "未知 Setup 组件版本号")
|
||||
cachedVersion = message
|
||||
return message
|
||||
} catch {
|
||||
print("Error checking Setup version: \(error)")
|
||||
let message = String(localized: "未知 Setup 组件版本号")
|
||||
cachedVersion = message
|
||||
return message
|
||||
}
|
||||
}
|
||||
|
||||
static func clearVersionCache() {
|
||||
cachedVersion = nil
|
||||
}
|
||||
|
||||
static func isSetupBackup() -> Bool {
|
||||
return FileManager.default.fileExists(atPath: "/Library/Application Support/Adobe/Adobe Desktop Common/HDBox/Setup.original")
|
||||
}
|
||||
|
||||
static func backupSetupFile(completion: @escaping (Bool, String) -> Void) {
|
||||
@@ -55,7 +107,7 @@ prep '\(setupPath)'
|
||||
try shellScript.write(to: tempScriptPath, atomically: true, encoding: .utf8)
|
||||
|
||||
let script = """
|
||||
do shell script "chmod +x '\(tempScriptPath.path)' && sudo '\(tempScriptPath.path)'" with administrator privileges
|
||||
do shell script "sudo chmod 777 '\(tempScriptPath.path)' && sudo '\(tempScriptPath.path)'" with administrator privileges
|
||||
"""
|
||||
|
||||
var scriptError: NSDictionary?
|
||||
|
||||
@@ -10,7 +10,6 @@ class TaskPersistenceManager {
|
||||
private init() {
|
||||
let containerURL = fileManager.urls(for: .applicationSupportDirectory, in: .userDomainMask).first!
|
||||
tasksDirectory = containerURL.appendingPathComponent("Adobe Downloader/tasks", isDirectory: true)
|
||||
print(tasksDirectory)
|
||||
try? fileManager.createDirectory(at: tasksDirectory, withIntermediateDirectories: true)
|
||||
}
|
||||
|
||||
|
||||
@@ -27,7 +27,7 @@ struct AboutView: View {
|
||||
}
|
||||
}
|
||||
.background(Color(NSColor.windowBackgroundColor))
|
||||
.frame(width: 500, height: 350)
|
||||
.frame(width: 600)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -40,6 +40,11 @@ struct GeneralSettingsView: View {
|
||||
@AppStorage("downloadAppleSilicon") private var downloadAppleSilicon: Bool = true
|
||||
@State private var showLanguagePicker = false
|
||||
@EnvironmentObject private var networkManager: NetworkManager
|
||||
@State private var showAlert = false
|
||||
@State private var alertMessage = ""
|
||||
@State private var isSuccess = false
|
||||
|
||||
@State private var setupVersion: String = ""
|
||||
|
||||
private let updater: SPUUpdater
|
||||
@State private var automaticallyChecksForUpdates: Bool
|
||||
@@ -106,7 +111,44 @@ struct GeneralSettingsView: View {
|
||||
}
|
||||
.padding(8)
|
||||
}
|
||||
GroupBox(label: Text("其他设置").padding(.bottom, 8)) {
|
||||
VStack(alignment: .leading, spacing: 12) {
|
||||
HStack {
|
||||
Text("Setup 备份状态: ")
|
||||
if ModifySetup.isSetupBackup() {
|
||||
Image(systemName: "checkmark.circle.fill")
|
||||
.foregroundColor(.green)
|
||||
} else {
|
||||
Image(systemName: "xmark.circle.fill")
|
||||
.foregroundColor(.red)
|
||||
Text("(将导致无法使用安装功能)")
|
||||
}
|
||||
Spacer()
|
||||
|
||||
Button(action: {
|
||||
ModifySetup.backupSetupFile { success, message in
|
||||
self.isSuccess = success
|
||||
self.alertMessage = message
|
||||
self.showAlert = true
|
||||
}
|
||||
}) {
|
||||
Text("立即备份")
|
||||
}
|
||||
.disabled(ModifySetup.isSetupBackup())
|
||||
}
|
||||
Divider()
|
||||
HStack {
|
||||
Text("Setup 组件版本: \(setupVersion)")
|
||||
Spacer()
|
||||
|
||||
Button(action: {}) {
|
||||
Text("下载 Setup 组件")
|
||||
}
|
||||
.disabled(setupVersion != String(localized: "未知 Setup 组件版本号"))
|
||||
}
|
||||
}.padding(8)
|
||||
}
|
||||
.padding(.vertical, 5)
|
||||
GroupBox(label: Text("更新设置").padding(.bottom, 8)) {
|
||||
VStack(alignment: .leading, spacing: 12) {
|
||||
HStack {
|
||||
@@ -136,7 +178,15 @@ struct GeneralSettingsView: View {
|
||||
showLanguagePicker = false
|
||||
}
|
||||
}
|
||||
.alert(isPresented: $showAlert) {
|
||||
Alert(
|
||||
title: Text(isSuccess ? "操作成功" : "操作失败"),
|
||||
message: Text(alertMessage),
|
||||
dismissButton: .default(Text("确定"))
|
||||
)
|
||||
}
|
||||
.onAppear {
|
||||
setupVersion = ModifySetup.checkComponentVersion()
|
||||
networkManager.updateAllowedPlatform(useAppleSilicon: downloadAppleSilicon)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,6 +19,7 @@ struct DownloadProgressView: View {
|
||||
@State private var isPackageListExpanded: Bool = false
|
||||
@State private var expandedProducts: Set<String> = []
|
||||
@State private var iconImage: NSImage? = nil
|
||||
@State private var showSetupBackupAlert = false
|
||||
|
||||
private var statusLabel: some View {
|
||||
Text(task.status.description)
|
||||
@@ -116,16 +117,25 @@ struct DownloadProgressView: View {
|
||||
HStack(spacing: 8) {
|
||||
if task.displayInstallButton {
|
||||
Button(action: {
|
||||
showInstallPrompt = false
|
||||
isInstalling = true
|
||||
Task {
|
||||
await networkManager.installProduct(at: task.directory)
|
||||
if !ModifySetup.isSetupBackup() {
|
||||
showSetupBackupAlert = true
|
||||
} else {
|
||||
showInstallPrompt = false
|
||||
isInstalling = true
|
||||
Task {
|
||||
await networkManager.installProduct(at: task.directory)
|
||||
}
|
||||
}
|
||||
}) {
|
||||
Label("安装", systemImage: "square.and.arrow.down.on.square")
|
||||
}
|
||||
.buttonStyle(.borderedProminent)
|
||||
.tint(.green)
|
||||
.alert("Setup 组件未处理", isPresented: $showSetupBackupAlert) {
|
||||
Button("确定") { }
|
||||
} message: {
|
||||
Text("未对 Setup 组件进行备份处理,无法使用安装功能\n你可以通过设置页面再次对 Setup 组件进行备份处理")
|
||||
}
|
||||
}
|
||||
|
||||
Button(action: onRemove) {
|
||||
|
||||
@@ -1,3 +1,10 @@
|
||||
//
|
||||
// ShouldExistsSetUpView.swift
|
||||
// Adobe Downloader
|
||||
//
|
||||
// Created by X1a0He.
|
||||
//
|
||||
|
||||
import SwiftUI
|
||||
|
||||
struct ExistingFileAlertView: View {
|
||||
|
||||
125
Adobe Downloader/Views/ShouldExistsSetUpView.swift
Normal file
125
Adobe Downloader/Views/ShouldExistsSetUpView.swift
Normal file
@@ -0,0 +1,125 @@
|
||||
//
|
||||
// ShouldExistsSetUpView.swift
|
||||
// Adobe Downloader
|
||||
//
|
||||
// Created by X1a0He on 11/11/24.
|
||||
//
|
||||
|
||||
import SwiftUI
|
||||
|
||||
struct ShouldExistsSetUpView: View {
|
||||
@Environment(\.dismiss) private var dismiss
|
||||
@State private var showingAlert = false
|
||||
@State private var isDownloading = false
|
||||
@State private var downloadProgress: Double = 0
|
||||
|
||||
var body: some View {
|
||||
VStack(spacing: 20) {
|
||||
Image(systemName: "exclamationmark.triangle.fill")
|
||||
.font(.system(size: 64))
|
||||
.foregroundColor(.orange)
|
||||
.padding(.bottom, 5)
|
||||
.frame(alignment: .bottomTrailing)
|
||||
|
||||
Text("未检测到 Adobe Setup 组件")
|
||||
.font(.system(size: 24))
|
||||
.bold()
|
||||
|
||||
VStack(spacing: 4) {
|
||||
Text("程序检测到你的系统中不存在 Adobe Setup 组件")
|
||||
.multilineTextAlignment(.center)
|
||||
|
||||
Text("可能导致无法使用安装功能,请确保是否使用安装功能")
|
||||
.multilineTextAlignment(.center)
|
||||
}
|
||||
|
||||
VStack(spacing: 16) {
|
||||
Button(action: {
|
||||
showingAlert = true
|
||||
}) {
|
||||
Label("不使用安装功能", systemImage: "exclamationmark.triangle.fill")
|
||||
.frame(minWidth: 0,maxWidth: 360)
|
||||
.frame(height: 32)
|
||||
.font(.system(size: 14))
|
||||
}
|
||||
.buttonStyle(.borderedProminent)
|
||||
.tint(.orange)
|
||||
.alert("确认", isPresented: $showingAlert) {
|
||||
Button("取消", role: .cancel) { }
|
||||
Button("确定", role: .destructive) {
|
||||
dismiss()
|
||||
}
|
||||
} message: {
|
||||
Text("你确定不使用安装功能吗?")
|
||||
}
|
||||
.disabled(isDownloading)
|
||||
Button(action: {
|
||||
isDownloading = true
|
||||
// TODO
|
||||
}) {
|
||||
if isDownloading {
|
||||
ProgressView(value: downloadProgress) {
|
||||
Label("正在下载 X1a0He CC \(Int(downloadProgress * 100))%", systemImage: "arrow.down")
|
||||
.frame(height: 32)
|
||||
.frame(maxWidth: 360)
|
||||
.frame(alignment: .center)
|
||||
.font(.system(size: 14))
|
||||
}
|
||||
.progressViewStyle(.linear)
|
||||
.tint(.green)
|
||||
.frame(maxWidth: 360)
|
||||
} else {
|
||||
Label("下载 X1a0He CC 组件", systemImage: "arrow.down")
|
||||
.frame(minWidth: 0, maxWidth: 360)
|
||||
.frame(height: 32)
|
||||
.font(.system(size: 14))
|
||||
}
|
||||
}
|
||||
.buttonStyle(.borderedProminent)
|
||||
.tint(.blue)
|
||||
.disabled(isDownloading)
|
||||
|
||||
Button(action: {
|
||||
if let url = URL(string: "https://creativecloud.adobe.com/apps/download/creative-cloud") {
|
||||
NSWorkspace.shared.open(url)
|
||||
dismiss()
|
||||
DispatchQueue.main.asyncAfter(deadline: .now() + 0.1) {
|
||||
NSApplication.shared.terminate(nil)
|
||||
}
|
||||
}
|
||||
}) {
|
||||
Label("前往 Adobe Creative Cloud", systemImage: "cloud.fill")
|
||||
.frame(minWidth: 0,maxWidth: 360)
|
||||
.frame(height: 32)
|
||||
.font(.system(size: 14))
|
||||
}
|
||||
.disabled(isDownloading)
|
||||
|
||||
Button(action: {
|
||||
dismiss()
|
||||
DispatchQueue.main.asyncAfter(deadline: .now() + 0.1) {
|
||||
NSApplication.shared.terminate(nil)
|
||||
}
|
||||
}) {
|
||||
Label("退出", systemImage: "xmark")
|
||||
.frame(minWidth: 0, maxWidth: 360)
|
||||
.frame(height: 32)
|
||||
.font(.system(size: 14))
|
||||
}
|
||||
.buttonStyle(.borderedProminent)
|
||||
.tint(.red)
|
||||
.keyboardShortcut(.cancelAction)
|
||||
.disabled(isDownloading)
|
||||
}
|
||||
}
|
||||
.frame(width: 400)
|
||||
.padding()
|
||||
.background(Color(NSColor.windowBackgroundColor))
|
||||
.cornerRadius(12)
|
||||
.shadow(radius: 10)
|
||||
}
|
||||
}
|
||||
|
||||
#Preview {
|
||||
ShouldExistsSetUpView()
|
||||
}
|
||||
@@ -1,6 +1,16 @@
|
||||
{
|
||||
"sourceLanguage" : "en",
|
||||
"strings" : {
|
||||
"(将导致无法使用安装功能)" : {
|
||||
"localizations" : {
|
||||
"en" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "(Unavailable to use install)"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"(退出代码: %d)" : {
|
||||
"localizations" : {
|
||||
"en" : {
|
||||
@@ -105,6 +115,16 @@
|
||||
},
|
||||
"Adobe Downloader %@" : {
|
||||
|
||||
},
|
||||
"Adobe Downloader 完全开源免费: https://github.com/X1a0He/Adobe-Downloader" : {
|
||||
"localizations" : {
|
||||
"en" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "Adobe Downloader is completely open source and free: https://github.com/X1a0He/Adobe-Downloader"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"Adobe Downloader 已为你默认设定如下值" : {
|
||||
"localizations" : {
|
||||
@@ -132,8 +152,35 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"OK" : {
|
||||
|
||||
"Setup 备份状态: " : {
|
||||
"localizations" : {
|
||||
"en" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "Setup backup status:"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"Setup 组件未处理" : {
|
||||
"localizations" : {
|
||||
"en" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "Setup component not processed"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"Setup 组件版本: %@" : {
|
||||
"localizations" : {
|
||||
"en" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "Setup component version: %@"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"Setup未备份提示" : {
|
||||
"localizations" : {
|
||||
@@ -165,6 +212,26 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"下载 Setup 组件" : {
|
||||
"localizations" : {
|
||||
"en" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "Download Setup component"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"下载 X1a0He CC 组件" : {
|
||||
"localizations" : {
|
||||
"en" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "Download X1a0He CC"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"下载中" : {
|
||||
"localizations" : {
|
||||
"en" : {
|
||||
@@ -238,6 +305,16 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"不使用安装功能" : {
|
||||
"localizations" : {
|
||||
"en" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "I don't install apps"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"产品和包列表" : {
|
||||
"localizations" : {
|
||||
"en" : {
|
||||
@@ -258,6 +335,16 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"你确定不使用安装功能吗?" : {
|
||||
"localizations" : {
|
||||
"en" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "Are you sure you don't want to install apps?"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"使用现有程序" : {
|
||||
"localizations" : {
|
||||
"en" : {
|
||||
@@ -348,6 +435,16 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"其他设置" : {
|
||||
"localizations" : {
|
||||
"en" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "Other settings"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"删除" : {
|
||||
"localizations" : {
|
||||
"en" : {
|
||||
@@ -358,12 +455,12 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"前往下载" : {
|
||||
"前往 Adobe Creative Cloud" : {
|
||||
"localizations" : {
|
||||
"en" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "Go to download"
|
||||
"value" : "Go to Adobe Creative Cloud"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -398,6 +495,36 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"可能导致无法使用安装功能,请确保是否使用安装功能" : {
|
||||
"localizations" : {
|
||||
"en" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "This may result in the inability to use the installation function. Please make sure whether you use the installation function."
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"备份失败" : {
|
||||
"localizations" : {
|
||||
"en" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "Backup failure"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"备份成功" : {
|
||||
"localizations" : {
|
||||
"en" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "Backup success"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"复制命令" : {
|
||||
"localizations" : {
|
||||
"en" : {
|
||||
@@ -477,8 +604,12 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"安装程序调用失败,Setup 组件未被处理,请联系开发者" : {
|
||||
|
||||
},
|
||||
"安装程序调用失败,请联系X1a0He" : {
|
||||
"extractionState" : "stale",
|
||||
"localizations" : {
|
||||
"en" : {
|
||||
"stringUnit" : {
|
||||
@@ -639,6 +770,26 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"操作失败" : {
|
||||
"localizations" : {
|
||||
"en" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "Operation failed"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"操作成功" : {
|
||||
"localizations" : {
|
||||
"en" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "Operation successful"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"无法将响应数据转换为json字符串" : {
|
||||
"localizations" : {
|
||||
"en" : {
|
||||
@@ -720,15 +871,18 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"未安装 Adobe Creative Cloud" : {
|
||||
"未对 Setup 组件进行备份处理,无法使用安装功能\n你可以通过设置页面再次对 Setup 组件进行备份处理" : {
|
||||
"localizations" : {
|
||||
"en" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "Adobe Creative Cloud not installed"
|
||||
"value" : "The Setup component has not been backed up, so the installation function cannot be used. You can back up the Setup component again through the settings page."
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"未找到 Setup 组件" : {
|
||||
|
||||
},
|
||||
"未找到语言" : {
|
||||
"localizations" : {
|
||||
@@ -740,6 +894,26 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"未检测到 Adobe Setup 组件" : {
|
||||
"localizations" : {
|
||||
"en" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "Adobe Setup component not detected"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"未知 Setup 组件版本号" : {
|
||||
"localizations" : {
|
||||
"en" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "Unknown Setup component version"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"未设置" : {
|
||||
"comment" : "Default directory not set",
|
||||
"localizations" : {
|
||||
@@ -798,6 +972,16 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"正在下载 X1a0He CC %lld%%" : {
|
||||
"localizations" : {
|
||||
"en" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "Downloading X1a0He CC %lld"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"正在准备..." : {
|
||||
"localizations" : {
|
||||
"en" : {
|
||||
@@ -989,6 +1173,16 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"程序检测到你的系统中不存在 Adobe Setup 组件" : {
|
||||
"localizations" : {
|
||||
"en" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "Detected that the Adobe Setup component is not present on your system"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"程序重启后自动暂停" : {
|
||||
"localizations" : {
|
||||
"en" : {
|
||||
@@ -999,6 +1193,16 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"立即备份" : {
|
||||
"localizations" : {
|
||||
"en" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "Backup now"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"等待中" : {
|
||||
"comment" : "Download status waiting",
|
||||
"localizations" : {
|
||||
@@ -1216,6 +1420,7 @@
|
||||
}
|
||||
},
|
||||
"重试失败,需要重新输入密码" : {
|
||||
"extractionState" : "stale",
|
||||
"localizations" : {
|
||||
"en" : {
|
||||
"stringUnit" : {
|
||||
@@ -1234,16 +1439,6 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"需要先安装 Adobe Creative Cloud 才能继续使用本程序" : {
|
||||
"localizations" : {
|
||||
"en" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "You need to install Adobe Creative Cloud before you can continue using this program"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"version" : "1.0"
|
||||
|
||||
BIN
X1a0HeCC/HDBox/HDHelper
Executable file
BIN
X1a0HeCC/HDBox/HDHelper
Executable file
Binary file not shown.
BIN
X1a0HeCC/HDBox/HDIM.dylib
Executable file
BIN
X1a0HeCC/HDBox/HDIM.dylib
Executable file
Binary file not shown.
BIN
X1a0HeCC/HDBox/HDPIM.dylib
Executable file
BIN
X1a0HeCC/HDBox/HDPIM.dylib
Executable file
Binary file not shown.
BIN
X1a0HeCC/HDBox/HUM.dylib
Executable file
BIN
X1a0HeCC/HDBox/HUM.dylib
Executable file
Binary file not shown.
BIN
X1a0HeCC/HDBox/Setup
Executable file
BIN
X1a0HeCC/HDBox/Setup
Executable file
Binary file not shown.
@@ -4,7 +4,7 @@
|
||||
|
||||
# **[English version](readme-en.md)**
|
||||
|
||||
## 使用须知
|
||||
## 使用须知 Q & A
|
||||
|
||||
**🍎仅支持 macOS 12.0+**
|
||||
|
||||
|
||||
@@ -1,5 +1,22 @@
|
||||
# Change Log
|
||||
|
||||
- 2024-11-11 23:00 更新日志
|
||||
|
||||
[//]: # (1.2.0)
|
||||
|
||||
```markdown
|
||||
1. 调整程序启动时 sheet 的弹出顺序
|
||||
2. 设置中添加了 Setup 组件的检测和版本号检测,支持在设置中重新备份与处理
|
||||
3. 调整 Setup 组件的检测,不再需要完整安装 Adobe Creative Cloud
|
||||
4. 增加了安装前 Setup 组件是否已处理的判断,未处理 Setup 组件,无法使用安装功能
|
||||
5. 调整 Setup 组件检测弹窗界面
|
||||
|
||||
PS: Setup 组件的来源均为 Adobe Creative Cloud 官方组件
|
||||
====================
|
||||
|
||||
1.
|
||||
```
|
||||
|
||||
- 2024-11-09 23:00 更新日志
|
||||
|
||||
[//]: # (1.1.0)
|
||||
|
||||
Reference in New Issue
Block a user