diff --git a/.DS_Store b/.DS_Store index c4ad82f..4692b27 100644 Binary files a/.DS_Store and b/.DS_Store differ diff --git a/RootHelper/.theos/obj/debug/arm64/trolltoolsroothelper b/RootHelper/.theos/obj/debug/arm64/trolltoolsroothelper index c2a0bc2..7aa8090 100755 Binary files a/RootHelper/.theos/obj/debug/arm64/trolltoolsroothelper and b/RootHelper/.theos/obj/debug/arm64/trolltoolsroothelper differ diff --git a/RootHelper/.theos/obj/debug/arm64/trolltoolsroothelper.dSYM/Contents/Resources/DWARF/trolltoolsroothelper b/RootHelper/.theos/obj/debug/arm64/trolltoolsroothelper.dSYM/Contents/Resources/DWARF/trolltoolsroothelper index 8bb99cd..9006bce 100644 Binary files a/RootHelper/.theos/obj/debug/arm64/trolltoolsroothelper.dSYM/Contents/Resources/DWARF/trolltoolsroothelper and b/RootHelper/.theos/obj/debug/arm64/trolltoolsroothelper.dSYM/Contents/Resources/DWARF/trolltoolsroothelper differ diff --git a/RootHelper/.theos/obj/debug/trolltoolsroothelper b/RootHelper/.theos/obj/debug/trolltoolsroothelper index ed720a6..45433ec 100755 Binary files a/RootHelper/.theos/obj/debug/trolltoolsroothelper and b/RootHelper/.theos/obj/debug/trolltoolsroothelper differ diff --git a/TrollTools.xcodeproj/project.pbxproj b/TrollTools.xcodeproj/project.pbxproj index 8a0ff64..6d110a0 100644 --- a/TrollTools.xcodeproj/project.pbxproj +++ b/TrollTools.xcodeproj/project.pbxproj @@ -7,6 +7,7 @@ objects = { /* Begin PBXBuildFile section */ + 6F63906B294B957900BA22D4 /* LSFootnoteChangerView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6F63906A294B957900BA22D4 /* LSFootnoteChangerView.swift */; }; 6FDA067D2935AA52003CE14A /* ZIPFoundation in Frameworks */ = {isa = PBXBuildFile; productRef = 6FDA067C2935AA52003CE14A /* ZIPFoundation */; }; CE141B372903E73F00AB48A7 /* CardChangerView.swift in Sources */ = {isa = PBXBuildFile; fileRef = CE141B362903E73F00AB48A7 /* CardChangerView.swift */; }; CE141B3A2903F20800AB48A7 /* ThemesSettingsView.swift in Sources */ = {isa = PBXBuildFile; fileRef = CE141B392903F20800AB48A7 /* ThemesSettingsView.swift */; }; @@ -53,6 +54,7 @@ /* End PBXBuildFile section */ /* Begin PBXFileReference section */ + 6F63906A294B957900BA22D4 /* LSFootnoteChangerView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LSFootnoteChangerView.swift; sourceTree = ""; }; CE141B362903E73F00AB48A7 /* CardChangerView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CardChangerView.swift; sourceTree = ""; }; CE141B392903F20800AB48A7 /* ThemesSettingsView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ThemesSettingsView.swift; sourceTree = ""; }; CE141B3B2903F22F00AB48A7 /* ThemeView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ThemeView.swift; sourceTree = ""; }; @@ -250,6 +252,7 @@ CE7975B0291C4533007A38E7 /* LockscreenRespringView.swift */, CEF56C3E291C605600DDEBFD /* CalculatorErrorView.swift */, CEF56C5329215AA900DDEBFD /* CarrierNameChangerView.swift */, + 6F63906A294B957900BA22D4 /* LSFootnoteChangerView.swift */, ); path = Tools; sourceTree = ""; @@ -392,6 +395,7 @@ CE7975A5291B1E0C007A38E7 /* ToolsView.swift in Sources */, CE2BF8242902E07F00AD10BE /* Extensions.swift in Sources */, CE141B5A290460AE00AB48A7 /* WebclipsThemeManager.swift in Sources */, + 6F63906B294B957900BA22D4 /* LSFootnoteChangerView.swift in Sources */, CEF56C3F291C605600DDEBFD /* CalculatorErrorView.swift in Sources */, CE7975A7291B2A4B007A38E7 /* GesturesView.swift in Sources */, CE76386D290AED160099C6F0 /* ProblemReporter.swift in Sources */, diff --git a/TrollTools.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved b/TrollTools.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved new file mode 100644 index 0000000..f40f271 --- /dev/null +++ b/TrollTools.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved @@ -0,0 +1,59 @@ +{ + "pins" : [ + { + "identity" : "dynamic", + "kind" : "remoteSourceControl", + "location" : "https://github.com/mhdhejazi/Dynamic", + "state" : { + "branch" : "master", + "revision" : "772883073d044bc754d401cabb6574624eb3778f" + } + }, + { + "identity" : "map", + "kind" : "remoteSourceControl", + "location" : "https://github.com/pauljohanneskraft/Map", + "state" : { + "revision" : "a99a9083aac4c5eba1cd83291eb2e222df287f31", + "version" : "0.1.0" + } + }, + { + "identity" : "santanderwrappers", + "kind" : "remoteSourceControl", + "location" : "https://github.com/SerenaKit/SantanderWrappers", + "state" : { + "branch" : "main", + "revision" : "78c19b2eeba612b0fb7b13df7ab304062ee22622" + } + }, + { + "identity" : "swift-argument-parser", + "kind" : "remoteSourceControl", + "location" : "https://github.com/apple/swift-argument-parser.git", + "state" : { + "revision" : "fddd1c00396eed152c45a46bea9f47b98e59301d", + "version" : "1.2.0" + } + }, + { + "identity" : "swiftyxmlparser", + "kind" : "remoteSourceControl", + "location" : "https://github.com/yahoojapan/SwiftyXMLParser", + "state" : { + "revision" : "d7a1d23f04c86c1cd2e8f19247dd15d74e0ea8be", + "version" : "5.6.0" + } + }, + { + "identity" : "zipfoundation", + "kind" : "remoteSourceControl", + "location" : "https://github.com/weichsel/ZIPFoundation", + "state" : { + "branch" : "development", + "revision" : "642436f3684009ca7a5e3d6b30f2ecea26f8f772" + } + } + ], + "version" : 2 +} diff --git a/TrollTools.xcodeproj/project.xcworkspace/xcuserdata/lemin.xcuserdatad/UserInterfaceState.xcuserstate b/TrollTools.xcodeproj/project.xcworkspace/xcuserdata/lemin.xcuserdatad/UserInterfaceState.xcuserstate index 5e50d15..8798984 100644 Binary files a/TrollTools.xcodeproj/project.xcworkspace/xcuserdata/lemin.xcuserdatad/UserInterfaceState.xcuserstate and b/TrollTools.xcodeproj/project.xcworkspace/xcuserdata/lemin.xcuserdatad/UserInterfaceState.xcuserstate differ diff --git a/TrollTools/.DS_Store b/TrollTools/.DS_Store index 2592265..f95abb6 100644 Binary files a/TrollTools/.DS_Store and b/TrollTools/.DS_Store differ diff --git a/TrollTools/Assets.xcassets/.DS_Store b/TrollTools/Assets.xcassets/.DS_Store index 8927f0d..d82e620 100644 Binary files a/TrollTools/Assets.xcassets/.DS_Store and b/TrollTools/Assets.xcassets/.DS_Store differ diff --git a/TrollTools/Assets.xcassets/screens/.DS_Store b/TrollTools/Assets.xcassets/screens/.DS_Store new file mode 100644 index 0000000..7695375 Binary files /dev/null and b/TrollTools/Assets.xcassets/screens/.DS_Store differ diff --git a/TrollTools/Info.plist b/TrollTools/Info.plist index 6a6654d..6997cbf 100644 --- a/TrollTools/Info.plist +++ b/TrollTools/Info.plist @@ -2,10 +2,71 @@ + CFBundleDocumentTypes + + + CFBundleTypeName + Passcode Theme + LSHandlerRank + Owner + LSItemContentTypes + + net.sourceloc.passthm + + + NSAppTransportSecurity NSAllowsArbitraryLoads + UTExportedTypeDeclarations + + + UTTypeConformsTo + + public.data + public.archive + + UTTypeDescription + Passcode Theme File + UTTypeIconFiles + + UTTypeIdentifier + net.sourceloc.passthm + UTTypeTagSpecification + + public.filename-extension + + passthm + PASSTHM + + + + + UTImportedTypeDeclarations + + + UTTypeConformsTo + + public.data + public.archive + + UTTypeDescription + Passcode Theme File + UTTypeIconFiles + + UTTypeIdentifier + net.sourceloc.passthm + UTTypeTagSpecification + + public.filename-extension + + passthm + PASSTHM + + + + diff --git a/TrollTools/Other/TrollToolsApp.swift b/TrollTools/Other/TrollToolsApp.swift index bd9a38c..6ee4bbc 100644 --- a/TrollTools/Other/TrollToolsApp.swift +++ b/TrollTools/Other/TrollToolsApp.swift @@ -13,12 +13,12 @@ struct TrollToolsApp: App { WindowGroup { RootView() .onAppear { - if let version = Bundle.main.infoDictionary?["CFBundleShortVersionString"] as? String, let url = URL(string: "https://api.github.com/repos/sourcelocation/TrollTools/releases/latest") { + if let version = Bundle.main.infoDictionary?["CFBundleShortVersionString"] as? Double, let url = URL(string: "https://api.github.com/repos/sourcelocation/TrollTools/releases/latest") { let task = URLSession.shared.dataTask(with: url) {(data, response, error) in guard let data = data else { return } if let json = try? JSONSerialization.jsonObject(with: data, options: .mutableContainers) as? [String: Any] { - if json["tag_name"] as? String != version { + if json["tag_name"] as? Double ?? 2.1 > version { UIApplication.shared.confirmAlert(title: "Update available", body: "A new TrollTools update is available, do you want to visit releases page?", onOK: { UIApplication.shared.open(URL(string: "https://github.com/sourcelocation/TrollTools/releases/latest")!) }, noCancel: false) @@ -29,6 +29,19 @@ struct TrollToolsApp: App { } try? RootHelper.loadMCM() } + .onOpenURL(perform: { url in + // for opening passthm files + if url.pathExtension.lowercased() == "passthm" { + let defaultKeySize = PasscodeKeyFaceManager.getDefaultFaceSize() + do { + // try appying the themes + try PasscodeKeyFaceManager.setFacesFromTheme(url, keySize: CGFloat(defaultKeySize), customX: CGFloat(150), customY: CGFloat(150)) + // show the passcode screen + //PasscodeEditorView() + ToolsView().activateView(viewName: "PasscodeEditorView", isActive: true) + } catch { UIApplication.shared.alert(body: error.localizedDescription) } + } + }) } } } diff --git a/TrollTools/Views/.DS_Store b/TrollTools/Views/.DS_Store index 5008ddf..3beae43 100644 Binary files a/TrollTools/Views/.DS_Store and b/TrollTools/Views/.DS_Store differ diff --git a/TrollTools/Views/Tools/LSFootnoteChangerView.swift b/TrollTools/Views/Tools/LSFootnoteChangerView.swift new file mode 100644 index 0000000..5415986 --- /dev/null +++ b/TrollTools/Views/Tools/LSFootnoteChangerView.swift @@ -0,0 +1,86 @@ +// +// LSFootnoteChangerView.swift +// TrollTools +// +// Created by LeminLimez on 12/15/22. +// + +import SwiftUI + +struct LSFootnoteChangerView: View { + @State var footnoteText = "" + @State var footnoteOffset: CGFloat = .zero + @State var footnoteSize: [CGFloat] = [.zero, .zero] + + var sharedDeviceConfigPath = "/var/containers/Shared/SystemGroup/systemgroup.com.apple.configurationprofiles/Library/ConfigurationProfiles" + + var body: some View { + ZStack { + VStack { + Spacer() + ZStack(alignment: .center) { + Image("lockscreen") + .resizable() + .aspectRatio(contentMode: .fit) + .frame(maxWidth: .infinity) + .padding(.bottom) + .background(GeometryReader { (geometry) -> Color in + DispatchQueue.main.async { + // set the footnote textbox size + footnoteSize[0] = geometry.size.width/3 + footnoteSize[1] = geometry.size.height/25 + + // set the footnote textbox offset + footnoteOffset = -geometry.size.height/2 + (870/990) * geometry.size.height + footnoteSize[1]/2 + } + return .clear + }) + TextField("Footnote", text: $footnoteText) + .foregroundColor(.white) + .offset(x: 0, y: footnoteOffset) + .frame(width: footnoteSize[0], height: footnoteSize[1], alignment: .center) + .multilineTextAlignment(.center) + } + } + } + //.ignoresSafeArea(.keyboard, edges: .bottom) + .toolbar { + ToolbarItem(placement: .navigationBarTrailing) { + Button(action: { + do { + let url = URL(fileURLWithPath: sharedDeviceConfigPath + "/SharedDeviceConfiguration.plist") + + var plistData: Data + if !FileManager.default.fileExists(atPath: url.path) { + plistData = try PropertyListSerialization.data(fromPropertyList: ["LockScreenFootnote": footnoteText], format: .xml, options: 0) + } else { + guard let data = try? Data(contentsOf: url), var plist = try PropertyListSerialization.propertyList(from: data, format: nil) as? [String:Any] else { throw "Couldn't read SharedDeviceConfiguration.plist" } + plist["LockScreenFootnote"] = footnoteText + + // Save plist + plistData = try PropertyListSerialization.data(fromPropertyList: plist, format: .xml, options: 0) + UserDefaults.standard.set(footnoteText, forKey: "LSFootnoteText") + } + + // write to file + try RootHelper.writeStr(String(decoding: plistData, as: UTF8.self), to: url) + } catch { + UIApplication.shared.alert(body: "\(error)") + } + }) { + Image(systemName: "checkmark") + } + } + } + .onAppear { + footnoteText = UserDefaults.standard.string(forKey: "LSFootnoteText") ?? "" + } + .navigationTitle("Lock Screen Footnote Changer") + } +} + +struct LSFootnoteChangerView_Previews: PreviewProvider { + static var previews: some View { + LSFootnoteChangerView() + } +} diff --git a/TrollTools/Views/Tools/PasscodeEditorView.swift b/TrollTools/Views/Tools/PasscodeEditorView.swift index d695cbb..6df0e09 100644 --- a/TrollTools/Views/Tools/PasscodeEditorView.swift +++ b/TrollTools/Views/Tools/PasscodeEditorView.swift @@ -81,7 +81,7 @@ struct PasscodeEditorView: View { // export key Button(action: { do { - var archiveURL: URL? = try PasscodeKeyFaceManager.exportFaceTheme() + let archiveURL: URL? = try PasscodeKeyFaceManager.exportFaceTheme() // show share menu let avc = UIActivityViewController(activityItems: [archiveURL!], applicationActivities: nil) let view: UIView = UIApplication.shared.windows.first!.rootViewController!.view @@ -174,7 +174,7 @@ struct PasscodeEditorView: View { let customAction = UIAlertAction(title: "Custom", style: .default) { (action) in // ask the user for a custom size - var sizeAlert = UIAlertController(title: "Enter Key Dimensions", message: "Min: "+String(sizeLimit[0])+", Max: "+String(sizeLimit[1]), preferredStyle: .alert) + let sizeAlert = UIAlertController(title: "Enter Key Dimensions", message: "Min: "+String(sizeLimit[0])+", Max: "+String(sizeLimit[1]), preferredStyle: .alert) // bring up the text prompts sizeAlert.addTextField { (textField) in // text field for width @@ -357,7 +357,7 @@ struct PasscodeKeyView: View { ZStack { Circle() .fill(Color(UIColor(red: 1, green: 1, blue: 1, alpha: 0.12))) - .frame(width: 70, height: 70) // background circle + .frame(width: 78, height: 78) // background circle Circle() .fill(Color(UIColor(red: 1, green: 1, blue: 1, alpha: 0))) // hidden circle for image if face == nil { diff --git a/TrollTools/Views/Tools/ToolsView.swift b/TrollTools/Views/Tools/ToolsView.swift index 627deb0..db1315c 100644 --- a/TrollTools/Views/Tools/ToolsView.swift +++ b/TrollTools/Views/Tools/ToolsView.swift @@ -16,6 +16,15 @@ struct ToolsView: View { var imageName: String } + struct GeneralOption: Identifiable { + var key: String + var id = UUID() + var view: AnyView + var title: String + var imageName: String + var active: Bool = false + } + @State var springboardOptions: [SpringboardOption] = [ .init(value: false, key: "SBShowRSSI", title: "Numeric Wi-Fi Strength", imageName: "wifi"), @@ -29,74 +38,31 @@ struct ToolsView: View { .init(value: false, key: "SBControlCenterDemo", title: "CC AirPlay Radar", imageName: "wifi.circle"), ] + @State var generalOptions: [GeneralOption] = [ + .init(key: "GesturesView", view: AnyView(GesturesView()), title: "iPhone X Gestures", imageName: "iphone"), + .init(key: "BadgeChangerView", view: AnyView(BadgeChangerView()), title: "Custom Badges", imageName: "app.badge"), + .init(key: "PasscodeEditorView", view: AnyView(PasscodeEditorView()), title: "Passcode faces", imageName: "ellipsis.rectangle"), + .init(key: "CarrierNameChangerView", view: AnyView(CarrierNameChangerView()), title: "Custom Carrier Name", imageName: "chart.bar"), + .init(key: "LockscreenRespringView", view: AnyView(LockscreenRespringView()), title: "Locking after Respring", imageName: "lock"), + .init(key: "CalculatorErrorView", view: AnyView(CalculatorErrorView()), title: "Calculator Error Message", imageName: "function"), + .init(key: "LSFootnoteChangerView", view: AnyView(LSFootnoteChangerView()), title: "Lock Screen Footnote", imageName: "platter.filled.bottom.and.arrow.down.iphone"), + ] + var body: some View { NavigationView { List { Section { - NavigationLink(destination: GesturesView()) { - HStack { - Image(systemName: "iphone") - .resizable() - .aspectRatio(contentMode: .fit) - .frame(width: 24, height: 24) - .foregroundColor(.blue) - Text("iPhone X Gestures") - .padding(.horizontal, 10) - } - } - NavigationLink(destination: BadgeChangerView()) { - HStack { - Image(systemName: "app.badge") - .resizable() - .aspectRatio(contentMode: .fit) - .frame(width: 24, height: 24) - .foregroundColor(.blue) - Text("Custom Badges") - .padding(.horizontal, 8) - } - } - NavigationLink(destination: PasscodeEditorView()) { - HStack { - Image(systemName: "ellipsis.rectangle") - .resizable() - .aspectRatio(contentMode: .fit) - .frame(width: 24, height: 24) - .foregroundColor(.blue) - Text("Passcode faces") - .padding(.horizontal, 8) - } - } - NavigationLink(destination: CarrierNameChangerView()) { - HStack { - Image(systemName: "chart.bar") - .resizable() - .aspectRatio(contentMode: .fit) - .frame(width: 24, height: 24) - .foregroundColor(.blue) - Text("Custom Carrier Name") - .padding(.horizontal, 8) - } - } - NavigationLink(destination: LockscreenRespringView()) { - HStack { - Image(systemName: "lock") - .resizable() - .aspectRatio(contentMode: .fit) - .frame(width: 24, height: 24) - .foregroundColor(.blue) - Text("Locking after Respring") - .padding(.horizontal, 8) - } - } - NavigationLink(destination: CalculatorErrorView()) { - HStack { - Image(systemName: "function") - .resizable() - .aspectRatio(contentMode: .fit) - .frame(width: 24, height: 24) - .foregroundColor(.blue) - Text("Calculator Error Message") - .padding(.horizontal, 8) + ForEach($generalOptions) { option in + NavigationLink(destination: option.view.wrappedValue, isActive: option.active) { + HStack { + Image(systemName: option.imageName.wrappedValue) + .resizable() + .aspectRatio(contentMode: .fit) + .frame(width: 24, height: 24) + .foregroundColor(.blue) + Text(option.title.wrappedValue) + .padding(.horizontal, 8) + } } } } header: { @@ -135,7 +101,7 @@ struct ToolsView: View { .navigationTitle("Tools") .onAppear { for (i, option) in springboardOptions.enumerated() { -// springboardOptions[i].value = getSpringboardOption(key: option.key) as? Bool ?? false + springboardOptions[i].value = getSpringboardOption(key: option.key) as? Bool ?? false } } } @@ -147,7 +113,7 @@ struct ToolsView: View { guard let data = try? Data(contentsOf: url) else { return nil } let plist = try? PropertyListSerialization.propertyList(from: data, format: nil) as? [String:Any] - return plist?["SBDontLockAfterCrash"] + return plist?[key] } func toggleSpringboardOption(key: String, value: Any) throws { @@ -167,6 +133,18 @@ struct ToolsView: View { // write to file try RootHelper.writeStr(String(decoding: plistData, as: UTF8.self), to: url) } + + func activateView(viewName: String, isActive: Bool) { + for (i, option) in generalOptions.enumerated() { + if option.key == viewName { + var option = generalOptions[i] + option.active = isActive + generalOptions[i] = option + print("Activity: " + String(generalOptions[i].active) ) + return + } + } + } } struct ToolsView_Previews: PreviewProvider {