Skip to content

Commit

Permalink
feat: add settings
Browse files Browse the repository at this point in the history
Signed-off-by: 82Flex <[email protected]>
  • Loading branch information
Lessica committed Jul 28, 2024
1 parent 5a23ef7 commit 538eda8
Show file tree
Hide file tree
Showing 9 changed files with 141 additions and 38 deletions.
8 changes: 6 additions & 2 deletions TrollFools.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
CC1549022C4B62E300A4173E /* cp-15 in Resources */ = {isa = PBXBuildFile; fileRef = CC1549012C4B62E300A4173E /* cp-15 */; };
CC15490C2C4B79D800A4173E /* optool in Resources */ = {isa = PBXBuildFile; fileRef = CC15490B2C4B79D800A4173E /* optool */; };
CC15490E2C4B80AF00A4173E /* EjectListView.swift in Sources */ = {isa = PBXBuildFile; fileRef = CC15490D2C4B80AF00A4173E /* EjectListView.swift */; };
CC19E4BB2C561D7300E0F1B5 /* SettingsView.swift in Sources */ = {isa = PBXBuildFile; fileRef = CC19E4BA2C561D7300E0F1B5 /* SettingsView.swift */; };
CC5E54BE2C4E12F900FDE4A8 /* install_name_tool in Resources */ = {isa = PBXBuildFile; fileRef = CC5E54BC2C4E12F900FDE4A8 /* install_name_tool */; };
CC5E54BF2C4E131000FDE4A8 /* libxar.1.dylib in Resources */ = {isa = PBXBuildFile; fileRef = CC5E54BB2C4E12F900FDE4A8 /* libxar.1.dylib */; };
CC61A87C2C4A677B003BD9A0 /* CydiaSubstrate.framework.zip in Resources */ = {isa = PBXBuildFile; fileRef = CC61A87B2C4A677B003BD9A0 /* CydiaSubstrate.framework.zip */; };
Expand Down Expand Up @@ -64,6 +65,7 @@
CC1549012C4B62E300A4173E /* cp-15 */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.executable"; path = "cp-15"; sourceTree = "<group>"; };
CC15490B2C4B79D800A4173E /* optool */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.executable"; path = optool; sourceTree = "<group>"; };
CC15490D2C4B80AF00A4173E /* EjectListView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EjectListView.swift; sourceTree = "<group>"; };
CC19E4BA2C561D7300E0F1B5 /* SettingsView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SettingsView.swift; sourceTree = "<group>"; };
CC5E54BB2C4E12F900FDE4A8 /* libxar.1.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; path = libxar.1.dylib; sourceTree = "<group>"; };
CC5E54BC2C4E12F900FDE4A8 /* install_name_tool */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.executable"; path = install_name_tool; sourceTree = "<group>"; };
CC61A87B2C4A677B003BD9A0 /* CydiaSubstrate.framework.zip */ = {isa = PBXFileReference; lastKnownFileType = archive.zip; path = CydiaSubstrate.framework.zip; sourceTree = "<group>"; };
Expand Down Expand Up @@ -168,6 +170,7 @@
CCF470592C4A4649008D8197 /* TrollFoolsApp.swift */,
CCF4706D2C4A4BAB008D8197 /* AppListView.swift */,
CCB6A1182C4A58C7000D75B0 /* OptionView.swift */,
CC19E4BA2C561D7300E0F1B5 /* SettingsView.swift */,
CCB6A11A2C4A6066000D75B0 /* InjectView.swift */,
CC15490D2C4B80AF00A4173E /* EjectListView.swift */,
CC1548D22C4A743200A4173E /* SuccessView.swift */,
Expand Down Expand Up @@ -295,6 +298,7 @@
CC1548DB2C4A7C7000A4173E /* Execute.swift in Sources */,
CCF5A0A42C4D45160097D48D /* AuxiliaryExecute.swift in Sources */,
CCF4705A2C4A4649008D8197 /* TrollFoolsApp.swift in Sources */,
CC19E4BB2C561D7300E0F1B5 /* SettingsView.swift in Sources */,
CC1548D72C4A768700A4173E /* Injector.swift in Sources */,
CCB6A1192C4A58C7000D75B0 /* OptionView.swift in Sources */,
CCF5A0A22C4D417F0097D48D /* main.swift in Sources */,
Expand Down Expand Up @@ -467,7 +471,7 @@
"$(inherited)",
"$(PROJECT_DIR)/TrollFools",
);
MARKETING_VERSION = 2.4;
MARKETING_VERSION = 2.5;
PRODUCT_BUNDLE_IDENTIFIER = wiki.qaq.TrollFools;
PRODUCT_NAME = "$(TARGET_NAME)";
SUPPORTED_PLATFORMS = "iphoneos iphonesimulator";
Expand Down Expand Up @@ -509,7 +513,7 @@
"$(inherited)",
"$(PROJECT_DIR)/TrollFools",
);
MARKETING_VERSION = 2.4;
MARKETING_VERSION = 2.5;
PRODUCT_BUNDLE_IDENTIFIER = wiki.qaq.TrollFools;
PRODUCT_NAME = "$(TARGET_NAME)";
SUPPORTED_PLATFORMS = "iphoneos iphonesimulator";
Expand Down
4 changes: 2 additions & 2 deletions TrollFools/AppListView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -277,7 +277,7 @@ struct AppListCell: View {
if app.isDetached {
Button {
do {
let injector = try Injector(bundleURL: app.url, teamID: app.teamID)
let injector = try Injector(app.url, appID: app.id, teamID: app.teamID)
try injector.setDetached(false)
withAnimation {
app.reload()
Expand All @@ -290,7 +290,7 @@ struct AppListCell: View {
} else {
Button {
do {
let injector = try Injector(bundleURL: app.url, teamID: app.teamID)
let injector = try Injector(app.url, appID: app.id, teamID: app.teamID)
try injector.setDetached(true)
withAnimation {
app.reload()
Expand Down
4 changes: 2 additions & 2 deletions TrollFools/EjectListView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -250,7 +250,7 @@ struct EjectListView: View {
do {
let plugInsToRemove = offsets.map { vm.filteredPlugIns[$0] }
let plugInURLsToRemove = plugInsToRemove.map { $0.url }
let injector = try Injector(bundleURL: vm.app.url, teamID: vm.app.teamID)
let injector = try Injector(vm.app.url, appID: vm.app.id, teamID: vm.app.teamID)
try injector.eject(plugInURLsToRemove)

vm.app.reload()
Expand All @@ -265,7 +265,7 @@ struct EjectListView: View {

func deleteAll() {
do {
let injector = try Injector(bundleURL: vm.app.url, teamID: vm.app.teamID)
let injector = try Injector(vm.app.url, appID: vm.app.id, teamID: vm.app.teamID)

let view = viewControllerHost.viewController?
.navigationController?.view
Expand Down
5 changes: 1 addition & 4 deletions TrollFools/InjectView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -63,10 +63,7 @@ struct InjectView: View {

func inject() -> Result<Void, Error> {
do {
let injector = try Injector(
bundleURL: app.url,
teamID: app.teamID
)
let injector = try Injector(app.url, appID: app.id, teamID: app.teamID)
try injector.inject(urlList)
return .success(())
} catch {
Expand Down
22 changes: 18 additions & 4 deletions TrollFools/Injector.swift
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
import CocoaLumberjackSwift
import Foundation
import MachOKit
import SwiftUI
import ZIPFoundation

final class Injector {
Expand Down Expand Up @@ -104,6 +105,9 @@ final class Injector {
private let tempURL: URL
private var teamID: String

@AppStorage var useWeakReference: Bool
@AppStorage var preferMainExecutable: Bool

private lazy var infoPlistURL: URL = bundleURL.appendingPathComponent("Info.plist")
private lazy var mainExecutableURL: URL = {
let infoPlist = NSDictionary(contentsOf: infoPlistURL)!
Expand All @@ -125,7 +129,7 @@ final class Injector {

private init() { fatalError("Not implemented") }

init(bundleURL: URL, teamID: String) throws {
init(_ bundleURL: URL, appID: String, teamID: String) throws {
self.bundleURL = bundleURL
self.teamID = teamID
self.tempURL = try FileManager.default.url(
Expand All @@ -134,6 +138,8 @@ final class Injector {
appropriateFor: URL(fileURLWithPath: NSHomeDirectory()),
create: true
)
_useWeakReference = AppStorage(wrappedValue: true, "UseWeakReference-\(appID)")
_preferMainExecutable = AppStorage(wrappedValue: false, "PreferMainExecutable-\(appID)")
try updateTeamIdentifier(bundleURL)
}

Expand Down Expand Up @@ -219,10 +225,18 @@ final class Injector {
}
}

return executableURLs
var fwkURLs = executableURLs
.intersection(initialDylibs)
.filter { isMachOURL($0) }
.sorted(by: { $0.lastPathComponent < $1.lastPathComponent }) + [target]
.sorted(by: { $0.lastPathComponent < $1.lastPathComponent })

if preferMainExecutable {
fwkURLs.insert(target, at: 0)
} else {
fwkURLs.append(target)
}

return fwkURLs
}

private func copyTempInjectURLs(_ injectURLs: [URL]) throws -> [URL] {
Expand Down Expand Up @@ -568,7 +582,7 @@ final class Injector {
}

try _insertLoadCommandRpath(target, name: "@executable_path/Frameworks")
try _insertLoadCommandDylib(target, name: name, isWeak: true)
try _insertLoadCommandDylib(target, name: name, isWeak: useWeakReference)
try applyTargetFixes(target, name: name)
}

Expand Down
68 changes: 44 additions & 24 deletions TrollFools/OptionView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -59,49 +59,61 @@ struct OptionView: View {
@State var isImporterPresented = false
@State var isImporterSelected = false

@State var isSettingsPresented = false

@State var importerResult: Result<[URL], any Error>?

init(_ app: App) {
self.app = app
}

var body: some View {
HStack {
Spacer()
VStack(spacing: 80) {
HStack {
Spacer()

Button {
isImporterPresented = true
} label: {
OptionCell(option: .attach)
}
.accessibilityLabel(NSLocalizedString("Inject", comment: ""))

Spacer()

NavigationLink {
EjectListView(app)
} label: {
OptionCell(option: .detach)
}
.accessibilityLabel(NSLocalizedString("Eject", comment: ""))

Spacer()
}

Button {
isSettingsPresented = true
} label: {
Label(NSLocalizedString("Advanced Settings", comment: ""),
systemImage: "gear")
}
}
.padding()
.navigationTitle(app.name)
.background(Group {
NavigationLink(isActive: $isImporterSelected) {
if let result = importerResult {
switch result {
case .success(let urls):
InjectView(app: app, urlList: urls
.sorted(by: { $0.lastPathComponent < $1.lastPathComponent }))
case .failure(let message):
FailureView(title: NSLocalizedString("Error", comment: ""),
FailureView(title: NSLocalizedString("Error", comment: ""),
message: message.localizedDescription)
}
}
} label: { }

Button {
isImporterPresented = true
} label: {
OptionCell(option: .attach)
}
.accessibilityLabel(NSLocalizedString("Inject", comment: ""))

Spacer()

NavigationLink {
EjectListView(app)
} label: {
OptionCell(option: .detach)
}
.accessibilityLabel(NSLocalizedString("Eject", comment: ""))

Spacer()
}
.padding()
.navigationTitle(app.name)
})
.fileImporter(
isPresented: $isImporterPresented,
allowedContentTypes: [
Expand All @@ -117,5 +129,13 @@ struct OptionView: View {
importerResult = result
isImporterSelected = true
}
.sheet(isPresented: $isSettingsPresented) {
if #available(iOS 16.0, *) {
SettingsView(app)
.presentationDetents([.medium, .large])
} else {
SettingsView(app)
}
}
}
}
38 changes: 38 additions & 0 deletions TrollFools/SettingsView.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
//
// SettingsView.swift
// TrollFools
//
// Created by Lessica on 2024/7/28.
//

import SwiftUI

struct SettingsView: View {
let app: App

init(_ app: App) {
self.app = app
self._useWeakReference = AppStorage(wrappedValue: true, "UseWeakReference-\(app.id)")
self._preferMainExecutable = AppStorage(wrappedValue: false, "PreferMainExecutable-\(app.id)")
}

@AppStorage var useWeakReference: Bool
@AppStorage var preferMainExecutable: Bool

var body: some View {
NavigationView {
Form {
Section {
Toggle(NSLocalizedString("Use Weak Reference", comment: ""), systemImage: "link", isOn: $useWeakReference)
Toggle(NSLocalizedString("Prefer Main Executable", comment: ""), systemImage: "doc.badge.gearshape", isOn: $preferMainExecutable)
} header: {
Text(NSLocalizedString("Injection", comment: ""))
} footer: {
Text(NSLocalizedString("If you do not know what these options mean, please do not change them.", comment: ""))
}
}
.navigationTitle(NSLocalizedString("Advanced Settings", comment: ""))
.navigationBarTitleDisplayMode(.inline)
}
}
}
15 changes: 15 additions & 0 deletions TrollFools/en.lproj/Localizable.strings
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,9 @@
/* No comment provided by engineer. */
"A pure TrollStore software channel!" = "A pure TrollStore software channel!";

/* No comment provided by engineer. */
"Advanced Settings" = "Advanced Settings";

/* No comment provided by engineer. */
"AE86 TrollStore Channel" = "AE86 TrollStore Channel";

Expand Down Expand Up @@ -40,6 +43,9 @@
/* No comment provided by engineer. */
"Failed to parse: %@" = "Failed to parse: %@";

/* No comment provided by engineer. */
"If you do not know what these options mean, please do not change them." = "If you do not know what these options mean, please do not change them.";

/* No comment provided by engineer. */
"Inject" = "Inject";

Expand All @@ -52,6 +58,9 @@
/* No comment provided by engineer. */
"Injecting" = "Injecting";

/* No comment provided by engineer. */
"Injection" = "Injection";

/* No comment provided by engineer. */
"Launch" = "Launch";

Expand Down Expand Up @@ -85,6 +94,9 @@
/* No comment provided by engineer. */
"Plug-Ins" = "Plug-Ins";

/* No comment provided by engineer. */
"Prefer Main Executable" = "Prefer Main Executable";

/* No comment provided by engineer. */
"Rebuild Icon Cache" = "Rebuild Icon Cache";

Expand Down Expand Up @@ -118,6 +130,9 @@
/* No comment provided by engineer. */
"Unlock Version" = "Unlock Version";

/* No comment provided by engineer. */
"Use Weak Reference" = "Use Weak Reference";

/* No comment provided by engineer. */
"User Applications" = "User Applications";

Expand Down
Loading

0 comments on commit 538eda8

Please sign in to comment.