Skip to content
Merged
Show file tree
Hide file tree
Changes from 18 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 5 additions & 20 deletions PCL.Mac.Core/Minecraft/Launch/MinecraftLauncher.swift
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ public class MinecraftLauncher {
"library_directory": librariesURL.path,

"auth_player_name": options.profile.name,
"version_name": manifest.id,
"version_name": options.runningDirectory.lastPathComponent,
"game_directory": runningDirectory.path,
"assets_root": librariesURL.deletingLastPathComponent().appending(path: "assets").path,
"assets_index_name": manifest.assetIndex.id,
Expand All @@ -54,21 +54,14 @@ public class MinecraftLauncher {
arguments.append(contentsOf: manifest.jvmArguments.flatMap { $0.rules.allSatisfy { $0.test(with: options) } ? $0.value : [] })
arguments.append(manifest.mainClass)
arguments.append(contentsOf: manifest.gameArguments.flatMap { $0.rules.allSatisfy { $0.test(with: options) } ? $0.value : [] })
arguments = arguments.map(replaceWithValue(_:))
arguments = arguments.map { Utils.replace($0, withValues: values) }
process.arguments = arguments

// accessToken 打码
// arguments 不会再被使用了,可以直接修改
if let accessTokenIndex: Int = arguments.firstIndex(of: "--accessToken"),
accessTokenIndex + 1 < arguments.count {
arguments[accessTokenIndex + 1] = "🥚"
}

let pipe: Pipe = .init()
process.standardOutput = pipe
process.standardError = pipe

log("正在使用以下参数启动 Minecraft:\(arguments)")
log("正在使用以下参数启动 Minecraft:\(arguments.map { $0 == options.accessToken ? "🥚" : $0 })")
try process.run()
Self.gameLogQueue.async {
FileManager.default.createFile(atPath: self.logURL.path, contents: nil)
Expand All @@ -92,20 +85,12 @@ public class MinecraftLauncher {

private func buildClasspath() -> String {
var urls: [URL] = []
for library in manifest.libraries {
if library.isRulesSatisfied, let artifact = library.artifact {
for library in manifest.getLibraries() {
if let artifact = library.artifact {
urls.append(librariesURL.appending(path: artifact.path))
}
}
urls.append(runningDirectory.appending(path: "\(runningDirectory.lastPathComponent).jar"))
return urls.map(\.path).joined(separator: ":")
}

private func replaceWithValue(_ string: String) -> String {
var s: String = string
for key in values.keys {
s = s.replacingOccurrences(of: "${\(key)}", with: values[key]!)
}
return s
}
}
13 changes: 6 additions & 7 deletions PCL.Mac.Core/Minecraft/MinecraftInstance.swift
Original file line number Diff line number Diff line change
Expand Up @@ -114,16 +114,13 @@ public class MinecraftInstance {
/// - version: (可选)缓存的版本号。
/// - Returns: 实例对象。
public static func load(from runningDirectory: URL) throws -> MinecraftInstance {
if FileManager.default.fileExists(atPath: runningDirectory.appending(path: ".incomplete").path) {
throw MinecraftError.incomplete
}
// 加载客户端清单
let manifestURL: URL = runningDirectory.appending(path: "\(runningDirectory.lastPathComponent).json")
guard FileManager.default.fileExists(atPath: manifestURL.path) else { throw MinecraftError.missingManifest }
let manifest: ClientManifest
do {
manifest = try JSONDecoder.shared.decode(ClientManifest.self, from: Data(contentsOf: manifestURL))
} catch {
err("加载客户端清单失败:\(error)")
throw MinecraftError.unknownManifestFormat
}
let manifest: ClientManifest = try .load(at: manifestURL)
// 获取版本
let version: MinecraftVersion
if let cachedVersion = VersionCache.version(of: manifestURL) {
Expand All @@ -135,6 +132,8 @@ public class MinecraftInstance {
let json: JSON = try? JSON(data: ArchiveUtils.getEntry(url: jarURL, path: "version.json")) {
log("成功解析 version.json")
version = .init(json["id"].stringValue)
} else if let clVersion: String = manifest.version {
version = .init(clVersion)
} else {
warn("\(jarURL.lastPathComponent)!/version.json 不存在或解析失败,使用客户端清单中的 id 作为版本号")
version = .init(manifest.id)
Expand Down
9 changes: 9 additions & 0 deletions PCL.Mac.Core/Minecraft/MinecraftRepository.swift
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,15 @@ public class MinecraftRepository: ObservableObject, Codable, Hashable, Equatable
err("加载实例失败:不支持的客户端清单格式。")
errorInstances.append(.init(name: content.lastPathComponent, message: "不支持的客户端清单格式。"))
continue
} catch MinecraftError.incomplete {
log("实例未完成安装,正在尝试自动删除")
do {
try FileManager.default.removeItem(at: content)
} catch {
err("删除失败:\(error.localizedDescription)")
errorInstances.append(.init(name: content.lastPathComponent, message: "该实例未完成安装,且自动删除失败。"))
}
continue
} catch {
err("加载实例失败:\(error.localizedDescription)")
continue
Expand Down
19 changes: 19 additions & 0 deletions PCL.Mac.Core/Minecraft/ModLoader.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
//
// ModLoader.swift
// PCL.Mac
//
// Created by 温迪 on 2026/2/11.
//

import Foundation

public enum ModLoader: CustomStringConvertible {
case fabric, forge

public var description: String {
switch self {
case .fabric: "Fabric"
case .forge: "Forge"
}
}
}
Loading