mirror of
https://github.com/ichmagmaus111/ghostgram.git
synced 2026-06-10 20:07:47 +02:00
Update Ghostgram features
This commit is contained in:
@@ -5,6 +5,8 @@
|
||||
// to avoid Swift/ObjC bridging complexities in MtProtoKit
|
||||
|
||||
static NSString *const kDeviceSpoofIsEnabled = @"DeviceSpoof.isEnabled";
|
||||
static NSString *const kDeviceSpoofHasExplicitConfiguration =
|
||||
@"DeviceSpoof.hasExplicitConfiguration";
|
||||
static NSString *const kDeviceSpoofSelectedProfileId =
|
||||
@"DeviceSpoof.selectedProfileId";
|
||||
static NSString *const kDeviceSpoofCustomDeviceModel =
|
||||
@@ -12,89 +14,132 @@ static NSString *const kDeviceSpoofCustomDeviceModel =
|
||||
static NSString *const kDeviceSpoofCustomSystemVersion =
|
||||
@"DeviceSpoof.customSystemVersion";
|
||||
|
||||
static NSDictionary<NSNumber *, NSDictionary<NSString *, NSString *> *> *
|
||||
DeviceSpoofProfiles(void) {
|
||||
static NSDictionary<NSNumber *, NSDictionary<NSString *, NSString *> *>
|
||||
*profiles;
|
||||
static dispatch_once_t onceToken;
|
||||
dispatch_once(&onceToken, ^{
|
||||
profiles = @{
|
||||
@1 : @{
|
||||
@"deviceModel" : @"iPhone 14 Pro",
|
||||
@"systemVersion" : @"iOS 17.2"
|
||||
},
|
||||
@2 : @{
|
||||
@"deviceModel" : @"iPhone 15 Pro Max",
|
||||
@"systemVersion" : @"iOS 17.4"
|
||||
},
|
||||
@3 : @{
|
||||
@"deviceModel" : @"Samsung SM-S918B",
|
||||
@"systemVersion" : @"Android 14"
|
||||
},
|
||||
@4 : @{
|
||||
@"deviceModel" : @"Google Pixel 8 Pro",
|
||||
@"systemVersion" : @"Android 14"
|
||||
},
|
||||
@5 : @{
|
||||
@"deviceModel" : @"PC 64bit",
|
||||
@"systemVersion" : @"Windows 11"
|
||||
},
|
||||
@6 : @{
|
||||
@"deviceModel" : @"MacBook Pro",
|
||||
@"systemVersion" : @"macOS 14.3"
|
||||
},
|
||||
@7 : @{
|
||||
@"deviceModel" : @"Web",
|
||||
@"systemVersion" : @"Chrome 121"
|
||||
},
|
||||
@8 : @{
|
||||
@"deviceModel" : @"HUAWEI MNA-LX9",
|
||||
@"systemVersion" : @"HarmonyOS 4.0"
|
||||
},
|
||||
@9 : @{
|
||||
@"deviceModel" : @"Xiaomi 2311DRK48G",
|
||||
@"systemVersion" : @"Android 14"
|
||||
}
|
||||
};
|
||||
});
|
||||
return profiles;
|
||||
}
|
||||
|
||||
static NSString *DeviceSpoofTrimmedString(NSString *value) {
|
||||
if (value == nil) {
|
||||
return @"";
|
||||
}
|
||||
return
|
||||
[value stringByTrimmingCharactersInSet:
|
||||
[NSCharacterSet whitespaceAndNewlineCharacterSet]];
|
||||
}
|
||||
|
||||
static NSInteger DeviceSpoofSanitizedProfileId(NSUserDefaults *defaults) {
|
||||
NSInteger profileId =
|
||||
[defaults integerForKey:kDeviceSpoofSelectedProfileId];
|
||||
if (profileId == 0 || profileId == 100 ||
|
||||
DeviceSpoofProfiles()[@(profileId)] != nil) {
|
||||
return profileId;
|
||||
}
|
||||
[defaults setInteger:0 forKey:kDeviceSpoofSelectedProfileId];
|
||||
return 0;
|
||||
}
|
||||
|
||||
static BOOL DeviceSpoofIsEnabled(NSUserDefaults *defaults) {
|
||||
return [defaults boolForKey:kDeviceSpoofHasExplicitConfiguration] &&
|
||||
[defaults boolForKey:kDeviceSpoofIsEnabled];
|
||||
}
|
||||
|
||||
static void DeviceSpoofResolveValues(NSUserDefaults *defaults,
|
||||
NSString *__autoreleasing *deviceModel,
|
||||
NSString *__autoreleasing *systemVersion) {
|
||||
*deviceModel = nil;
|
||||
*systemVersion = nil;
|
||||
|
||||
if (!DeviceSpoofIsEnabled(defaults)) {
|
||||
return;
|
||||
}
|
||||
|
||||
NSInteger profileId = DeviceSpoofSanitizedProfileId(defaults);
|
||||
if (profileId == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (profileId == 100) {
|
||||
NSString *customDeviceModel =
|
||||
DeviceSpoofTrimmedString([defaults stringForKey:kDeviceSpoofCustomDeviceModel]);
|
||||
NSString *customSystemVersion =
|
||||
DeviceSpoofTrimmedString([defaults stringForKey:kDeviceSpoofCustomSystemVersion]);
|
||||
if (customDeviceModel.length == 0 || customSystemVersion.length == 0) {
|
||||
return;
|
||||
}
|
||||
*deviceModel = customDeviceModel;
|
||||
*systemVersion = customSystemVersion;
|
||||
return;
|
||||
}
|
||||
|
||||
NSDictionary<NSString *, NSString *> *profile = DeviceSpoofProfiles()[@(profileId)];
|
||||
*deviceModel = profile[@"deviceModel"];
|
||||
*systemVersion = profile[@"systemVersion"];
|
||||
}
|
||||
|
||||
@implementation DeviceSpoofBridge
|
||||
|
||||
+ (BOOL)isEnabled {
|
||||
return
|
||||
[[NSUserDefaults standardUserDefaults] boolForKey:kDeviceSpoofIsEnabled];
|
||||
return DeviceSpoofIsEnabled([NSUserDefaults standardUserDefaults]);
|
||||
}
|
||||
|
||||
+ (NSString *)spoofedDeviceModel {
|
||||
if (![self isEnabled]) {
|
||||
return nil;
|
||||
}
|
||||
|
||||
NSInteger profileId = [[NSUserDefaults standardUserDefaults]
|
||||
integerForKey:kDeviceSpoofSelectedProfileId];
|
||||
|
||||
// Profile ID 0 = real device
|
||||
if (profileId == 0) {
|
||||
return nil;
|
||||
}
|
||||
|
||||
// Profile ID 100 = custom
|
||||
if (profileId == 100) {
|
||||
NSString *custom = [[NSUserDefaults standardUserDefaults]
|
||||
stringForKey:kDeviceSpoofCustomDeviceModel];
|
||||
if (custom.length > 0) {
|
||||
return custom;
|
||||
}
|
||||
return nil;
|
||||
}
|
||||
|
||||
// Preset profiles
|
||||
NSDictionary<NSNumber *, NSString *> *profiles = @{
|
||||
@1 : @"iPhone 14 Pro",
|
||||
@2 : @"iPhone 15 Pro Max",
|
||||
@3 : @"Samsung SM-S918B",
|
||||
@4 : @"Google Pixel 8 Pro",
|
||||
@5 : @"PC 64bit",
|
||||
@6 : @"MacBook Pro",
|
||||
@7 : @"Web",
|
||||
@8 : @"HUAWEI MNA-LX9",
|
||||
@9 : @"Xiaomi 2311DRK48G"
|
||||
};
|
||||
|
||||
return profiles[@(profileId)];
|
||||
NSString *deviceModel = nil;
|
||||
NSString *systemVersion = nil;
|
||||
DeviceSpoofResolveValues([NSUserDefaults standardUserDefaults], &deviceModel,
|
||||
&systemVersion);
|
||||
return deviceModel;
|
||||
}
|
||||
|
||||
+ (NSString *)spoofedSystemVersion {
|
||||
if (![self isEnabled]) {
|
||||
return nil;
|
||||
}
|
||||
|
||||
NSInteger profileId = [[NSUserDefaults standardUserDefaults]
|
||||
integerForKey:kDeviceSpoofSelectedProfileId];
|
||||
|
||||
// Profile ID 0 = real device
|
||||
if (profileId == 0) {
|
||||
return nil;
|
||||
}
|
||||
|
||||
// Profile ID 100 = custom
|
||||
if (profileId == 100) {
|
||||
NSString *custom = [[NSUserDefaults standardUserDefaults]
|
||||
stringForKey:kDeviceSpoofCustomSystemVersion];
|
||||
if (custom.length > 0) {
|
||||
return custom;
|
||||
}
|
||||
return nil;
|
||||
}
|
||||
|
||||
// Preset profiles
|
||||
NSDictionary<NSNumber *, NSString *> *versions = @{
|
||||
@1 : @"iOS 17.2",
|
||||
@2 : @"iOS 17.4",
|
||||
@3 : @"Android 14",
|
||||
@4 : @"Android 14",
|
||||
@5 : @"Windows 11",
|
||||
@6 : @"macOS 14.3",
|
||||
@7 : @"Chrome 121",
|
||||
@8 : @"HarmonyOS 4.0",
|
||||
@9 : @"Android 14"
|
||||
};
|
||||
|
||||
return versions[@(profileId)];
|
||||
NSString *deviceModel = nil;
|
||||
NSString *systemVersion = nil;
|
||||
DeviceSpoofResolveValues([NSUserDefaults standardUserDefaults], &deviceModel,
|
||||
&systemVersion);
|
||||
return systemVersion;
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@@ -41,10 +41,20 @@ public final class DeviceSpoofManager {
|
||||
|
||||
private enum Keys {
|
||||
static let isEnabled = "DeviceSpoof.isEnabled"
|
||||
static let hasExplicitConfiguration = "DeviceSpoof.hasExplicitConfiguration"
|
||||
static let selectedProfileId = "DeviceSpoof.selectedProfileId"
|
||||
static let customDeviceModel = "DeviceSpoof.customDeviceModel"
|
||||
static let customSystemVersion = "DeviceSpoof.customSystemVersion"
|
||||
}
|
||||
|
||||
private struct ResolvedConfiguration {
|
||||
let isEnabled: Bool
|
||||
let selectedProfileId: Int
|
||||
let customDeviceModel: String
|
||||
let customSystemVersion: String
|
||||
}
|
||||
|
||||
private static let validProfileIds = Set(profiles.map { $0.id })
|
||||
|
||||
private let defaults = UserDefaults.standard
|
||||
|
||||
@@ -52,18 +62,34 @@ public final class DeviceSpoofManager {
|
||||
|
||||
/// Whether device spoofing is enabled
|
||||
public var isEnabled: Bool {
|
||||
get { defaults.bool(forKey: Keys.isEnabled) }
|
||||
get {
|
||||
let configuration = resolvedConfiguration()
|
||||
return configuration.isEnabled
|
||||
}
|
||||
set {
|
||||
defaults.set(newValue, forKey: Keys.isEnabled)
|
||||
notifyChanged()
|
||||
}
|
||||
}
|
||||
|
||||
/// Whether the current spoofing configuration was explicitly set by the user
|
||||
public var hasExplicitConfiguration: Bool {
|
||||
get { defaults.bool(forKey: Keys.hasExplicitConfiguration) }
|
||||
set {
|
||||
defaults.set(newValue, forKey: Keys.hasExplicitConfiguration)
|
||||
notifyChanged()
|
||||
}
|
||||
}
|
||||
|
||||
/// Selected profile ID (0 = real device, 100 = custom)
|
||||
public var selectedProfileId: Int {
|
||||
get { defaults.integer(forKey: Keys.selectedProfileId) }
|
||||
get {
|
||||
sanitizeStoredConfiguration()
|
||||
return defaults.integer(forKey: Keys.selectedProfileId)
|
||||
}
|
||||
set {
|
||||
defaults.set(newValue, forKey: Keys.selectedProfileId)
|
||||
sanitizeStoredConfiguration()
|
||||
notifyChanged()
|
||||
}
|
||||
}
|
||||
@@ -90,15 +116,19 @@ public final class DeviceSpoofManager {
|
||||
|
||||
/// Get the currently effective device model
|
||||
public var effectiveDeviceModel: String? {
|
||||
guard isEnabled else { return nil }
|
||||
|
||||
if selectedProfileId == 100 {
|
||||
// Custom profile
|
||||
let custom = customDeviceModel.trimmingCharacters(in: .whitespacesAndNewlines)
|
||||
return custom.isEmpty ? nil : custom
|
||||
let configuration = resolvedConfiguration()
|
||||
guard configuration.isEnabled else {
|
||||
return nil
|
||||
}
|
||||
|
||||
if let profile = Self.profiles.first(where: { $0.id == selectedProfileId }), profile.id != 0 {
|
||||
|
||||
if configuration.selectedProfileId == 100 {
|
||||
guard !configuration.customDeviceModel.isEmpty, !configuration.customSystemVersion.isEmpty else {
|
||||
return nil
|
||||
}
|
||||
return configuration.customDeviceModel
|
||||
}
|
||||
|
||||
if let profile = Self.profiles.first(where: { $0.id == configuration.selectedProfileId }), profile.id != 0 {
|
||||
return profile.deviceModel.isEmpty ? nil : profile.deviceModel
|
||||
}
|
||||
|
||||
@@ -107,15 +137,19 @@ public final class DeviceSpoofManager {
|
||||
|
||||
/// Get the currently effective system version
|
||||
public var effectiveSystemVersion: String? {
|
||||
guard isEnabled else { return nil }
|
||||
|
||||
if selectedProfileId == 100 {
|
||||
// Custom profile
|
||||
let custom = customSystemVersion.trimmingCharacters(in: .whitespacesAndNewlines)
|
||||
return custom.isEmpty ? nil : custom
|
||||
let configuration = resolvedConfiguration()
|
||||
guard configuration.isEnabled else {
|
||||
return nil
|
||||
}
|
||||
|
||||
if let profile = Self.profiles.first(where: { $0.id == selectedProfileId }), profile.id != 0 {
|
||||
|
||||
if configuration.selectedProfileId == 100 {
|
||||
guard !configuration.customDeviceModel.isEmpty, !configuration.customSystemVersion.isEmpty else {
|
||||
return nil
|
||||
}
|
||||
return configuration.customSystemVersion
|
||||
}
|
||||
|
||||
if let profile = Self.profiles.first(where: { $0.id == configuration.selectedProfileId }), profile.id != 0 {
|
||||
return profile.systemVersion.isEmpty ? nil : profile.systemVersion
|
||||
}
|
||||
|
||||
@@ -134,8 +168,40 @@ public final class DeviceSpoofManager {
|
||||
private func notifyChanged() {
|
||||
NotificationCenter.default.post(name: Self.settingsChangedNotification, object: nil)
|
||||
}
|
||||
|
||||
private func sanitizeStoredConfiguration() {
|
||||
let rawSelectedProfileId = defaults.integer(forKey: Keys.selectedProfileId)
|
||||
if !Self.validProfileIds.contains(rawSelectedProfileId) {
|
||||
defaults.set(0, forKey: Keys.selectedProfileId)
|
||||
}
|
||||
|
||||
let rawCustomDeviceModel = defaults.string(forKey: Keys.customDeviceModel) ?? ""
|
||||
let trimmedCustomDeviceModel = rawCustomDeviceModel.trimmingCharacters(in: .whitespacesAndNewlines)
|
||||
if rawCustomDeviceModel != trimmedCustomDeviceModel {
|
||||
defaults.set(trimmedCustomDeviceModel, forKey: Keys.customDeviceModel)
|
||||
}
|
||||
|
||||
let rawCustomSystemVersion = defaults.string(forKey: Keys.customSystemVersion) ?? ""
|
||||
let trimmedCustomSystemVersion = rawCustomSystemVersion.trimmingCharacters(in: .whitespacesAndNewlines)
|
||||
if rawCustomSystemVersion != trimmedCustomSystemVersion {
|
||||
defaults.set(trimmedCustomSystemVersion, forKey: Keys.customSystemVersion)
|
||||
}
|
||||
}
|
||||
|
||||
private func resolvedConfiguration() -> ResolvedConfiguration {
|
||||
sanitizeStoredConfiguration()
|
||||
|
||||
return ResolvedConfiguration(
|
||||
isEnabled: defaults.bool(forKey: Keys.hasExplicitConfiguration) && defaults.bool(forKey: Keys.isEnabled),
|
||||
selectedProfileId: defaults.integer(forKey: Keys.selectedProfileId),
|
||||
customDeviceModel: defaults.string(forKey: Keys.customDeviceModel) ?? "",
|
||||
customSystemVersion: defaults.string(forKey: Keys.customSystemVersion) ?? ""
|
||||
)
|
||||
}
|
||||
|
||||
// MARK: - Init
|
||||
|
||||
private init() {}
|
||||
private init() {
|
||||
sanitizeStoredConfiguration()
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user