clean-checkpoint-1

This commit is contained in:
Magesh K
2024-12-07 17:45:09 +05:30
parent e27c5f0b87
commit 63a3203e50
95 changed files with 1040 additions and 3761 deletions

View File

@@ -82,8 +82,6 @@ public extension UserDefaults
}
@NSManaged @objc(activeAppsLimit) private var _activeAppsLimit: NSNumber?
@NSManaged var ignoreActiveAppsLimit: Bool
// Including "MacDirtyCow" in name triggers false positives with malware detectors 🤷
@NSManaged var isCowExploitSupported: Bool
@@ -129,8 +127,7 @@ public extension UserDefaults
#keyPath(UserDefaults.requiresAppGroupMigration): true,
#keyPath(UserDefaults.menuAnisetteList): "https://servers.sidestore.io/servers.json",
#keyPath(UserDefaults.menuAnisetteURL): "https://ani.sidestore.io",
#keyPath(UserDefaults.ignoreActiveAppsLimit): false,
#keyPath(UserDefaults.isMacDirtyCowSupported): isMacDirtyCowSupported
#keyPath(UserDefaults.isCowExploitSupported): isMacDirtyCowSupported,
#keyPath(UserDefaults.permissionCheckingDisabled): permissionCheckingDisabled,
#keyPath(UserDefaults._preferredAppSorting): preferredAppSorting.rawValue,
] as [String: Any]
@@ -140,8 +137,8 @@ public extension UserDefaults
if !isMacDirtyCowSupported
{
// Disable ignoreActiveAppsLimit if running iOS version that doesn't support MacDirtyCow.
UserDefaults.standard.ignoreActiveAppsLimit = false
// Disable isAppLimitDisabled if running iOS version that doesn't support MacDirtyCow.
UserDefaults.standard.isAppLimitDisabled = false
}
#if !BETA

View File

@@ -10,67 +10,6 @@ import CoreData
import UIKit
import AltSign
public extension ALTAppPermissionType
{
var localizedShortName: String? {
switch self
{
case .photos: return NSLocalizedString("Photos", comment: "")
case .backgroundAudio: return NSLocalizedString("Audio (BG)", comment: "")
case .backgroundFetch: return NSLocalizedString("Fetch (BG)", comment: "")
default: return nil
}
}
var localizedName: String? {
switch self
{
case .photos: return NSLocalizedString("Photos", comment: "")
case .camera: return NSLocalizedString("Camera", comment: "")
case .location: return NSLocalizedString("Location", comment: "")
case .contacts: return NSLocalizedString("Contacts", comment: "")
case .reminders: return NSLocalizedString("Reminders", comment: "")
case .appleMusic: return NSLocalizedString("Apple Music", comment: "")
case .microphone: return NSLocalizedString("Microphone", comment: "")
case .speechRecognition: return NSLocalizedString("Speech Recognition", comment: "")
case .backgroundAudio: return NSLocalizedString("Background Audio", comment: "")
case .backgroundFetch: return NSLocalizedString("Background Fetch", comment: "")
case .bluetooth: return NSLocalizedString("Bluetooth", comment: "")
case .network: return NSLocalizedString("Network", comment: "")
case .calendars: return NSLocalizedString("Calendars", comment: "")
case .touchID: return NSLocalizedString("Touch ID", comment: "")
case .faceID: return NSLocalizedString("Face ID", comment: "")
case .siri: return NSLocalizedString("Siri", comment: "")
case .motion: return NSLocalizedString("Motion", comment: "")
default: return nil
}
}
var icon: UIImage? {
switch self
{
case .photos: return UIImage(systemName: "photo.on.rectangle.angled")
case .camera: return UIImage(systemName: "camera.fill")
case .location: return UIImage(systemName: "location.fill")
case .contacts: return UIImage(systemName: "person.2.fill")
case .reminders: return UIImage(systemName: "checklist")
case .appleMusic: return UIImage(systemName: "music.note")
case .microphone: return UIImage(systemName: "mic.fill")
case .speechRecognition: return UIImage(systemName: "waveform.and.mic")
case .backgroundAudio: return UIImage(systemName: "speaker.fill")
case .backgroundFetch: return UIImage(systemName: "square.and.arrow.down")
case .bluetooth: return UIImage(systemName: "wave.3.right")
case .network: return UIImage(systemName: "network")
case .calendars: return UIImage(systemName: "calendar")
case .touchID: return UIImage(systemName: "touchid")
case .faceID: return UIImage(systemName: "faceid")
case .siri: return UIImage(systemName: "mic.and.signal.meter.fill")
case .motion: return UIImage(systemName: "figure.walk.motion")
default:
return nil
}
}
}
@objc(AppPermission) @dynamicMemberLookup
public class AppPermission: NSManagedObject, Fetchable

View File

@@ -157,11 +157,15 @@ public extension AppVersion
}
var isSupported: Bool {
if let minOSVersion = self.minOSVersion, !ProcessInfo.processInfo.isOperatingSystemAtLeast(minOSVersion) {
return false
} else if let maxOSVersion = self.maxOSVersion, ProcessInfo.processInfo.operatingSystemVersion > maxOSVersion {
if let minOSVersion = self.minOSVersion, !ProcessInfo.processInfo.isOperatingSystemAtLeast(minOSVersion)
{
return false
}
else if let maxOSVersion = self.maxOSVersion, ProcessInfo.processInfo.operatingSystemVersion > maxOSVersion
{
return false
}
return true
}
}

View File

@@ -53,6 +53,7 @@ public class DatabaseManager
private let coordinatorQueue = OperationQueue()
private var ignoreWillMigrateDatabaseNotification = false
private init()
{
self.persistentContainer = PersistentContainer(name: "AltStore", bundle: Bundle(for: DatabaseManager.self))
@@ -108,6 +109,7 @@ public extension DatabaseManager
self.ignoreWillMigrateDatabaseNotification = true
CFNotificationCenterPostNotification(CFNotificationCenterGetDarwinNotifyCenter(), .willMigrateDatabase, nil, nil, true)
}
self.migrateDatabaseToAppGroupIfNeeded { (result) in
switch result
{

View File

@@ -15,7 +15,7 @@ import SemanticVersion
extension InstalledApp
{
public static var freeAccountActiveAppsLimit: Int {
if UserDefaults.standard.ignoreActiveAppsLimit
if UserDefaults.standard.isAppLimitDisabled
{
// MacDirtyCow exploit allows users to remove 3-app limit, so return 10 to match App ID limit per-week.
// Don't return nil because that implies there is no limit, which isn't quite true due to App ID limit.
@@ -159,15 +159,17 @@ public extension InstalledApp
func loadIcon(completion: @escaping (Result<UIImage?, Error>) -> Void)
{
if self.bundleIdentifier == StoreApp.altstoreAppID, let iconName = UIApplication.alt_shared?.alternateIconName
{
// Use alternate app icon for AltStore, if one is chosen.
let image = UIImage(named: iconName)
completion(.success(image))
return
}
// TODO: @mahee96: Fix this later (reason: alternateIcon is not available for appEx)
// if self.bundleIdentifier == StoreApp.altstoreAppID,
// let iconName = UIApplication.alt_shared?.alternateIconName
// {
// // Use alternate app icon for AltStore, if one is chosen.
//
// let image = UIImage(named: iconName)
// completion(.success(image))
//
// return
// }
let hasAlternateIcon = self.hasAlternateIcon
let alternateIconURL = self.alternateIconURL
@@ -211,30 +213,34 @@ public extension InstalledApp
{
let fetchRequest = InstalledApp.fetchRequest() as NSFetchRequest<InstalledApp>
let predicateFormat = [
// isActive && storeApp != nil && latestSupportedVersion != nil
"%K == YES AND %K != nil AND %K != nil",
// let predicateFormat = [
// // isActive && storeApp != nil && latestSupportedVersion != nil
// "%K == YES AND %K != nil AND %K != nil",
"AND",
// "AND",
// latestSupportedVersion.version != installedApp.version || latestSupportedVersion.buildVersion != installedApp.storeBuildVersion
//
// We have to also check !(latestSupportedVersion.buildVersion == '' && installedApp.storeBuildVersion == nil)
// because latestSupportedVersion.buildVersion stores an empty string for nil, while installedApp.storeBuildVersion uses NULL.
"(%K != %K OR (%K != %K AND NOT (%K == '' AND %K == nil)))",
// // latestSupportedVersion.version != installedApp.version || latestSupportedVersion.buildVersion != installedApp.storeBuildVersion
// //
// // We have to also check !(latestSupportedVersion.buildVersion == '' && installedApp.storeBuildVersion == nil)
// // because latestSupportedVersion.buildVersion stores an empty string for nil, while installedApp.storeBuildVersion uses NULL.
// "(%K != %K OR (%K != %K AND NOT (%K == '' AND %K == nil)))",
"AND",
// "AND",
// !isPledgeRequired || isPledged
"(%K == NO OR %K == YES)"
].joined(separator: " ")
// // !isPledgeRequired || isPledged
// "(%K == NO OR %K == YES)"
// ].joined(separator: " ")
fetchRequest.predicate = NSPredicate(format: predicateFormat,
#keyPath(InstalledApp.isActive), #keyPath(InstalledApp.storeApp), #keyPath(InstalledApp.storeApp.latestSupportedVersion),
#keyPath(InstalledApp.storeApp.latestSupportedVersion.version), #keyPath(InstalledApp.version),
#keyPath(InstalledApp.storeApp.latestSupportedVersion._buildVersion), #keyPath(InstalledApp.storeBuildVersion),
#keyPath(InstalledApp.storeApp.latestSupportedVersion._buildVersion), #keyPath(InstalledApp.storeBuildVersion),
#keyPath(InstalledApp.storeApp.isPledgeRequired), #keyPath(InstalledApp.storeApp.isPledged))
// fetchRequest.predicate = NSPredicate(format: predicateFormat,
// #keyPath(InstalledApp.isActive), #keyPath(InstalledApp.storeApp), #keyPath(InstalledApp.storeApp.latestSupportedVersion),
// #keyPath(InstalledApp.storeApp.latestSupportedVersion.version), #keyPath(InstalledApp.version),
// #keyPath(InstalledApp.storeApp.latestSupportedVersion._buildVersion), #keyPath(InstalledApp.storeBuildVersion),
// #keyPath(InstalledApp.storeApp.latestSupportedVersion._buildVersion), #keyPath(InstalledApp.storeBuildVersion),
// #keyPath(InstalledApp.storeApp.isPledgeRequired), #keyPath(InstalledApp.storeApp.isPledged))
fetchRequest.predicate = NSPredicate(format: "%K == YES AND %K == YES",
#keyPath(InstalledApp.isActive), #keyPath(InstalledApp.hasUpdate))
return fetchRequest
}

View File

@@ -356,11 +356,11 @@ open class MergePolicy: RSTRelationshipPreservingMergePolicy
// Screenshots
if let sortedScreenshotIDs = sortedScreenshotIDsByGlobalAppID[globallyUniqueID],
let sortedScreenshotIDsArray = sortedScreenshotIDs.array as? [String],
case let databaseScreenshotIDs = databaseObject.allScreenshots.map({ $0.screenshotID }),
case let databaseScreenshotIDs = databaseObject.screenshots.map({ $0.screenshotID }),
databaseScreenshotIDs != sortedScreenshotIDsArray
{
// Screenshot order is incorrect, so attempt to fix by re-sorting.
let fixedScreenshots = databaseObject.allScreenshots.sorted { (screenshotA, screenshotB) in
let fixedScreenshots = databaseObject.screenshots.sorted { (screenshotA, screenshotB) in
let indexA = sortedScreenshotIDs.index(of: screenshotA.screenshotID)
let indexB = sortedScreenshotIDs.index(of: screenshotB.screenshotID)
return indexA < indexB

View File

@@ -45,7 +45,8 @@ public class PatreonAccount: NSManagedObject, Fetchable
// {
// self.isPatron = false
// }
self.isPatron = true
// self.isPatron = true
self.isAltStorePatron = true
}
}

View File

@@ -462,7 +462,7 @@ public extension Source
let source = Source(context: context)
source.name = "SideStore Offical"
source.identifier = Source.altStoreIdentifier
source.sourceURL = Source.altStoreSourceURL
try! source.setSourceURL(Source.altStoreSourceURL)
return source
}

View File

@@ -190,7 +190,7 @@ public class StoreApp: NSManagedObject, Decodable, Fetchable
permission.sourceID = self.sourceIdentifier ?? ""
}
for screenshot in self.allScreenshots
for screenshot in self.screenshots
{
screenshot.sourceID = self.sourceIdentifier ?? ""
}
@@ -282,8 +282,6 @@ public class StoreApp: NSManagedObject, Decodable, Fetchable
case developerName
case localizedDescription
case iconURL
case screenshotURLs
case downloadURL
case platformURLs
case screenshots
case tintColor
@@ -606,7 +604,7 @@ public extension StoreApp
func screenshots(for deviceType: ALTDeviceType) -> [AppScreenshot]
{
//TODO: Support multiple device types
let filteredScreenshots = self.allScreenshots.filter { $0.deviceType == deviceType }
let filteredScreenshots = self.screenshots.filter { $0.deviceType == deviceType }
return filteredScreenshots
}
@@ -626,7 +624,7 @@ public extension StoreApp
let preferredScreenshots = self.screenshots(for: deviceType)
guard !preferredScreenshots.isEmpty else {
// There are no screenshots for deviceType, so return _all_ screenshots instead.
return self.allScreenshots
return self.screenshots
}
return preferredScreenshots

View File

@@ -300,7 +300,7 @@ public extension PatreonAPI
{
let account = try result.get()
if let context = account.managedObjectContext, !account.isPatron
if let context = account.managedObjectContext, !account.isAltStorePatron
{
// Deactivate all beta apps now that we're no longer a patron.
//self.deactivateBetaApps(in: context)

View File

@@ -63,15 +63,16 @@ extension InstalledApp: AppProtocol
}
}
extension AppVersion: AppProtocol {
extension AppVersion: AppProtocol
{
public var name: String {
return self.app?.name ?? self.bundleIdentifier
}
public var bundleIdentifier: String {
return self.appBundleID
}
public var url: URL? {
return self.downloadURL
}