mirror of
https://github.com/ichmagmaus111/ghostgram.git
synced 2026-07-25 08:50:51 +02:00
feat: add Ghostgram features
- Anti-Delete: save deleted messages locally - Ghost Mode: hide online status, read receipts - Voice Morpher: audio processing effects - Device Spoof: spoof device info - Custom GhostIcon app icon - User Notes: personal notes for contacts - Misc settings and controllers - GPLv2 License
This commit is contained in:
@@ -0,0 +1,22 @@
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
/// Objective-C bridge for DeviceSpoofManager (Swift)
|
||||
/// Provides access to spoofed device information from Objective-C code
|
||||
@interface DeviceSpoofBridge : NSObject
|
||||
|
||||
/// Returns YES if device spoofing is enabled
|
||||
+ (BOOL)isEnabled;
|
||||
|
||||
/// Returns the spoofed device model, or nil if spoofing is disabled or using
|
||||
/// real device
|
||||
+ (NSString *_Nullable)spoofedDeviceModel;
|
||||
|
||||
/// Returns the spoofed system version, or nil if spoofing is disabled or using
|
||||
/// real device
|
||||
+ (NSString *_Nullable)spoofedSystemVersion;
|
||||
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
||||
@@ -0,0 +1,100 @@
|
||||
#import "DeviceSpoofBridge.h"
|
||||
|
||||
// Access to UserDefaults to get spoofing settings
|
||||
// This mirrors DeviceSpoofManager logic but in pure Objective-C
|
||||
// to avoid Swift/ObjC bridging complexities in MtProtoKit
|
||||
|
||||
static NSString *const kDeviceSpoofIsEnabled = @"DeviceSpoof.isEnabled";
|
||||
static NSString *const kDeviceSpoofSelectedProfileId =
|
||||
@"DeviceSpoof.selectedProfileId";
|
||||
static NSString *const kDeviceSpoofCustomDeviceModel =
|
||||
@"DeviceSpoof.customDeviceModel";
|
||||
static NSString *const kDeviceSpoofCustomSystemVersion =
|
||||
@"DeviceSpoof.customSystemVersion";
|
||||
|
||||
@implementation DeviceSpoofBridge
|
||||
|
||||
+ (BOOL)isEnabled {
|
||||
return
|
||||
[[NSUserDefaults standardUserDefaults] boolForKey:kDeviceSpoofIsEnabled];
|
||||
}
|
||||
|
||||
+ (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 *)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)];
|
||||
}
|
||||
|
||||
@end
|
||||
@@ -0,0 +1,141 @@
|
||||
import Foundation
|
||||
|
||||
/// DeviceSpoofManager - Manages device identity spoofing
|
||||
/// Allows changing device model and system version reported to Telegram servers
|
||||
public final class DeviceSpoofManager {
|
||||
public static let shared = DeviceSpoofManager()
|
||||
|
||||
// MARK: - Device Profile
|
||||
|
||||
public struct DeviceProfile: Equatable {
|
||||
public let id: Int
|
||||
public let name: String
|
||||
public let deviceModel: String
|
||||
public let systemVersion: String
|
||||
|
||||
public init(id: Int, name: String, deviceModel: String, systemVersion: String) {
|
||||
self.id = id
|
||||
self.name = name
|
||||
self.deviceModel = deviceModel
|
||||
self.systemVersion = systemVersion
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: - Preset Profiles
|
||||
|
||||
public static let profiles: [DeviceProfile] = [
|
||||
DeviceProfile(id: 0, name: "Реальное устройство", deviceModel: "", systemVersion: ""),
|
||||
DeviceProfile(id: 1, name: "iPhone 14 Pro", deviceModel: "iPhone 14 Pro", systemVersion: "iOS 17.2"),
|
||||
DeviceProfile(id: 2, name: "iPhone 15 Pro Max", deviceModel: "iPhone 15 Pro Max", systemVersion: "iOS 17.4"),
|
||||
DeviceProfile(id: 3, name: "Samsung Galaxy S23", deviceModel: "Samsung SM-S918B", systemVersion: "Android 14"),
|
||||
DeviceProfile(id: 4, name: "Google Pixel 8", deviceModel: "Google Pixel 8 Pro", systemVersion: "Android 14"),
|
||||
DeviceProfile(id: 5, name: "Desktop Windows", deviceModel: "PC 64bit", systemVersion: "Windows 11"),
|
||||
DeviceProfile(id: 6, name: "Desktop macOS", deviceModel: "MacBook Pro", systemVersion: "macOS 14.3"),
|
||||
DeviceProfile(id: 7, name: "Telegram Web", deviceModel: "Web", systemVersion: "Chrome 121"),
|
||||
DeviceProfile(id: 8, name: "Huawei P60 Pro", deviceModel: "HUAWEI MNA-LX9", systemVersion: "HarmonyOS 4.0"),
|
||||
DeviceProfile(id: 9, name: "Xiaomi 14", deviceModel: "Xiaomi 2311DRK48G", systemVersion: "Android 14"),
|
||||
DeviceProfile(id: 100, name: "Своё устройство", deviceModel: "", systemVersion: "")
|
||||
]
|
||||
|
||||
// MARK: - Keys
|
||||
|
||||
private enum Keys {
|
||||
static let isEnabled = "DeviceSpoof.isEnabled"
|
||||
static let selectedProfileId = "DeviceSpoof.selectedProfileId"
|
||||
static let customDeviceModel = "DeviceSpoof.customDeviceModel"
|
||||
static let customSystemVersion = "DeviceSpoof.customSystemVersion"
|
||||
}
|
||||
|
||||
private let defaults = UserDefaults.standard
|
||||
|
||||
// MARK: - Properties
|
||||
|
||||
/// Whether device spoofing is enabled
|
||||
public var isEnabled: Bool {
|
||||
get { defaults.bool(forKey: Keys.isEnabled) }
|
||||
set {
|
||||
defaults.set(newValue, forKey: Keys.isEnabled)
|
||||
notifyChanged()
|
||||
}
|
||||
}
|
||||
|
||||
/// Selected profile ID (0 = real device, 100 = custom)
|
||||
public var selectedProfileId: Int {
|
||||
get { defaults.integer(forKey: Keys.selectedProfileId) }
|
||||
set {
|
||||
defaults.set(newValue, forKey: Keys.selectedProfileId)
|
||||
notifyChanged()
|
||||
}
|
||||
}
|
||||
|
||||
/// Custom device model (when profile ID = 100)
|
||||
public var customDeviceModel: String {
|
||||
get { defaults.string(forKey: Keys.customDeviceModel) ?? "" }
|
||||
set {
|
||||
defaults.set(newValue, forKey: Keys.customDeviceModel)
|
||||
notifyChanged()
|
||||
}
|
||||
}
|
||||
|
||||
/// Custom system version (when profile ID = 100)
|
||||
public var customSystemVersion: String {
|
||||
get { defaults.string(forKey: Keys.customSystemVersion) ?? "" }
|
||||
set {
|
||||
defaults.set(newValue, forKey: Keys.customSystemVersion)
|
||||
notifyChanged()
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: - Computed
|
||||
|
||||
/// 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
|
||||
}
|
||||
|
||||
if let profile = Self.profiles.first(where: { $0.id == selectedProfileId }), profile.id != 0 {
|
||||
return profile.deviceModel.isEmpty ? nil : profile.deviceModel
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
/// 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
|
||||
}
|
||||
|
||||
if let profile = Self.profiles.first(where: { $0.id == selectedProfileId }), profile.id != 0 {
|
||||
return profile.systemVersion.isEmpty ? nil : profile.systemVersion
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
/// Get selected profile
|
||||
public var selectedProfile: DeviceProfile? {
|
||||
return Self.profiles.first(where: { $0.id == selectedProfileId })
|
||||
}
|
||||
|
||||
// MARK: - Notification
|
||||
|
||||
public static let settingsChangedNotification = Notification.Name("DeviceSpoofSettingsChanged")
|
||||
|
||||
private func notifyChanged() {
|
||||
NotificationCenter.default.post(name: Self.settingsChangedNotification, object: nil)
|
||||
}
|
||||
|
||||
// MARK: - Init
|
||||
|
||||
private init() {}
|
||||
}
|
||||
Reference in New Issue
Block a user