mirror of
https://github.com/GLEGram/GLEGram-iOS.git
synced 2026-04-24 11:56:18 +02:00
4647310322
Based on Swiftgram 12.5 (Telegram iOS 12.5). All GLEGram features ported and organized in GLEGram/ folder. Features: Ghost Mode, Saved Deleted Messages, Content Protection Bypass, Font Replacement, Fake Profile, Chat Export, Plugin System, and more. See CHANGELOG_12.5.md for full details.
267 lines
9.2 KiB
Swift
267 lines
9.2 KiB
Swift
import Foundation
|
|
|
|
// MARK: - GLEGram check_user response models
|
|
|
|
public struct GLEGramUserStatus: Equatable {
|
|
public let userId: String
|
|
public let badges: [GLEGramBadge]
|
|
public let subscription: GLEGramSubscription?
|
|
public let trial: GLEGramTrial?
|
|
public let donation: GLEGramDonation?
|
|
public let access: GLEGramAccess
|
|
public let glegramPromo: GLEGramPromo?
|
|
public let betaConfig: GLEGramBetaConfig?
|
|
public let hasActiveSubscription: Bool
|
|
public let hasActiveTrial: Bool
|
|
public let trialAvailable: Bool
|
|
|
|
public init(json: [String: Any]) {
|
|
self.userId = json["userId"] as? String ?? ""
|
|
self.badges = (json["badges"] as? [[String: Any]] ?? []).compactMap { GLEGramBadge(json: $0) }
|
|
self.subscription = (json["subscription"] as? [String: Any]).flatMap { GLEGramSubscription(json: $0) }
|
|
self.trial = (json["trial"] as? [String: Any]).flatMap { GLEGramTrial(json: $0) }
|
|
self.donation = (json["donation"] as? [String: Any]).flatMap { GLEGramDonation(json: $0) }
|
|
self.access = GLEGramAccess(json: json["access"] as? [String: Any] ?? [:])
|
|
self.glegramPromo = (json["glegramPromo"] as? [String: Any]).flatMap { GLEGramPromo(json: $0) }
|
|
self.betaConfig = (json["betaConfig"] as? [String: Any]).flatMap { GLEGramBetaConfig(json: $0) }
|
|
self.hasActiveSubscription = json["hasActiveSubscription"] as? Bool ?? false
|
|
self.hasActiveTrial = json["hasActiveTrial"] as? Bool ?? false
|
|
self.trialAvailable = json["trialAvailable"] as? Bool ?? false
|
|
}
|
|
}
|
|
|
|
public struct GLEGramBadge: Equatable {
|
|
public let id: String
|
|
public let name: String
|
|
public let color: String
|
|
public let displayMode: String // "text" or "image"
|
|
public let image: String? // relative URL for image badges
|
|
public let uiEnabled: Bool
|
|
public let uiConfig: GLEGramBadgeUIConfig?
|
|
|
|
public init?(json: [String: Any]) {
|
|
guard let id = json["id"] as? String else { return nil }
|
|
self.id = id
|
|
self.name = json["name"] as? String ?? id
|
|
self.color = json["color"] as? String ?? "#34C759"
|
|
self.displayMode = json["displayMode"] as? String ?? "text"
|
|
self.image = json["image"] as? String
|
|
self.uiEnabled = json["uiEnabled"] as? Bool ?? false
|
|
self.uiConfig = (json["uiConfig"] as? [String: Any]).flatMap { GLEGramBadgeUIConfig(json: $0) }
|
|
}
|
|
}
|
|
|
|
public struct GLEGramBadgeUIConfig: Equatable {
|
|
public let title: String
|
|
public let description: String
|
|
public let buttons: [GLEGramBadgeButton]
|
|
|
|
public init?(json: [String: Any]) {
|
|
self.title = json["title"] as? String ?? ""
|
|
self.description = json["description"] as? String ?? ""
|
|
self.buttons = (json["buttons"] as? [[String: Any]] ?? []).compactMap { GLEGramBadgeButton(json: $0) }
|
|
}
|
|
}
|
|
|
|
public struct GLEGramBadgeButton: Equatable {
|
|
public let label: String
|
|
public let url: String
|
|
|
|
public init?(json: [String: Any]) {
|
|
guard let label = json["label"] as? String, let url = json["url"] as? String else { return nil }
|
|
self.label = label
|
|
self.url = url
|
|
}
|
|
}
|
|
|
|
public struct GLEGramSubscription: Equatable {
|
|
public let planId: String
|
|
public let startedAt: String
|
|
public let expiresAt: String
|
|
public let active: Bool
|
|
|
|
public init?(json: [String: Any]) {
|
|
self.planId = json["planId"] as? String ?? ""
|
|
self.startedAt = json["startedAt"] as? String ?? ""
|
|
self.expiresAt = json["expiresAt"] as? String ?? ""
|
|
self.active = json["active"] as? Bool ?? false
|
|
}
|
|
}
|
|
|
|
public struct GLEGramTrial: Equatable {
|
|
public let startedAt: String
|
|
public let expiresAt: String
|
|
public let active: Bool
|
|
public let alreadyUsed: Bool
|
|
|
|
public init?(json: [String: Any]) {
|
|
self.startedAt = json["startedAt"] as? String ?? ""
|
|
self.expiresAt = json["expiresAt"] as? String ?? ""
|
|
self.active = json["active"] as? Bool ?? false
|
|
self.alreadyUsed = json["alreadyUsed"] as? Bool ?? false
|
|
}
|
|
}
|
|
|
|
public struct GLEGramDonation: Equatable {
|
|
public let amount: Int
|
|
public let lastDonatedAt: String
|
|
public let betaAccess: Bool
|
|
|
|
public init?(json: [String: Any]) {
|
|
self.amount = json["amount"] as? Int ?? 0
|
|
self.lastDonatedAt = json["lastDonatedAt"] as? String ?? ""
|
|
self.betaAccess = json["betaAccess"] as? Bool ?? false
|
|
}
|
|
}
|
|
|
|
public struct GLEGramAccess: Equatable {
|
|
// Obfuscated storage: actual bits XOR'd with per-instance random salt.
|
|
// Prevents trivial memory scanning for plain true/false values.
|
|
private let _enc: UInt32
|
|
private let _salt: UInt32
|
|
/// HMAC access token (base64). Used by integrity layer to verify flags haven't been tampered.
|
|
public let accessToken: String?
|
|
|
|
public var glegramTab: Bool {
|
|
return (_enc ^ _salt) & 0x1 != 0
|
|
}
|
|
|
|
public var betaBuilds: Bool {
|
|
return (_enc ^ _salt) & 0x2 != 0
|
|
}
|
|
|
|
public init(json: [String: Any]) {
|
|
let tab = json["glegramTab"] as? Bool ?? false
|
|
let beta = json["betaBuilds"] as? Bool ?? false
|
|
let bits: UInt32 = (tab ? 1 : 0) | (beta ? 2 : 0)
|
|
let salt = UInt32.random(in: 1...UInt32.max)
|
|
self._enc = bits ^ salt
|
|
self._salt = salt
|
|
self.accessToken = json["_accessToken"] as? String
|
|
}
|
|
|
|
public static func == (lhs: GLEGramAccess, rhs: GLEGramAccess) -> Bool {
|
|
return lhs.glegramTab == rhs.glegramTab && lhs.betaBuilds == rhs.betaBuilds
|
|
}
|
|
}
|
|
|
|
public struct GLEGramPromo: Equatable {
|
|
public let title: String
|
|
public let subtitle: String
|
|
public let features: [String]
|
|
public let trialButtonText: String
|
|
public let subscribeButtonText: String
|
|
public let miniAppUrl: String?
|
|
|
|
public init?(json: [String: Any]) {
|
|
self.title = json["title"] as? String ?? ""
|
|
self.subtitle = json["subtitle"] as? String ?? ""
|
|
self.features = json["features"] as? [String] ?? []
|
|
self.trialButtonText = json["trialButtonText"] as? String ?? ""
|
|
self.subscribeButtonText = json["subscribeButtonText"] as? String ?? ""
|
|
self.miniAppUrl = json["miniAppUrl"] as? String
|
|
}
|
|
}
|
|
|
|
public struct GLEGramBetaConfig: Equatable {
|
|
public let channelId: String?
|
|
public let channelUrl: String?
|
|
public let buildUrl: String?
|
|
|
|
public init?(json: [String: Any]) {
|
|
self.channelId = json["channelId"] as? String
|
|
self.channelUrl = json["channelUrl"] as? String
|
|
self.buildUrl = json["buildUrl"] as? String
|
|
}
|
|
}
|
|
|
|
// MARK: - JSON serialization for cache
|
|
|
|
extension GLEGramUserStatus {
|
|
public func toJSON() -> [String: Any] {
|
|
var dict: [String: Any] = [
|
|
"userId": userId,
|
|
"badges": badges.map { $0.toJSON() },
|
|
"hasActiveSubscription": hasActiveSubscription,
|
|
"hasActiveTrial": hasActiveTrial,
|
|
"trialAvailable": trialAvailable,
|
|
"access": access.toJSON()
|
|
]
|
|
if let s = subscription { dict["subscription"] = s.toJSON() }
|
|
if let t = trial { dict["trial"] = t.toJSON() }
|
|
if let d = donation { dict["donation"] = d.toJSON() }
|
|
if let p = glegramPromo { dict["glegramPromo"] = p.toJSON() }
|
|
if let b = betaConfig { dict["betaConfig"] = b.toJSON() }
|
|
return dict
|
|
}
|
|
}
|
|
|
|
extension GLEGramBadge {
|
|
func toJSON() -> [String: Any] {
|
|
var dict: [String: Any] = [
|
|
"id": id, "name": name, "color": color,
|
|
"displayMode": displayMode, "uiEnabled": uiEnabled
|
|
]
|
|
if let img = image { dict["image"] = img }
|
|
if let ui = uiConfig { dict["uiConfig"] = ui.toJSON() }
|
|
return dict
|
|
}
|
|
}
|
|
|
|
extension GLEGramBadgeUIConfig {
|
|
func toJSON() -> [String: Any] {
|
|
return [
|
|
"title": title,
|
|
"description": description,
|
|
"buttons": buttons.map { ["label": $0.label, "url": $0.url] }
|
|
]
|
|
}
|
|
}
|
|
|
|
extension GLEGramSubscription {
|
|
func toJSON() -> [String: Any] {
|
|
return ["planId": planId, "startedAt": startedAt, "expiresAt": expiresAt, "active": active]
|
|
}
|
|
}
|
|
|
|
extension GLEGramTrial {
|
|
func toJSON() -> [String: Any] {
|
|
return ["startedAt": startedAt, "expiresAt": expiresAt, "active": active, "alreadyUsed": alreadyUsed]
|
|
}
|
|
}
|
|
|
|
extension GLEGramDonation {
|
|
func toJSON() -> [String: Any] {
|
|
return ["amount": amount, "lastDonatedAt": lastDonatedAt, "betaAccess": betaAccess]
|
|
}
|
|
}
|
|
|
|
extension GLEGramAccess {
|
|
func toJSON() -> [String: Any] {
|
|
var d: [String: Any] = ["glegramTab": glegramTab, "betaBuilds": betaBuilds]
|
|
if let t = accessToken { d["_accessToken"] = t }
|
|
return d
|
|
}
|
|
}
|
|
|
|
extension GLEGramPromo {
|
|
func toJSON() -> [String: Any] {
|
|
var dict: [String: Any] = [
|
|
"title": title, "subtitle": subtitle, "features": features,
|
|
"trialButtonText": trialButtonText, "subscribeButtonText": subscribeButtonText
|
|
]
|
|
if let url = miniAppUrl { dict["miniAppUrl"] = url }
|
|
return dict
|
|
}
|
|
}
|
|
|
|
extension GLEGramBetaConfig {
|
|
func toJSON() -> [String: Any] {
|
|
var dict: [String: Any] = [:]
|
|
if let v = channelId { dict["channelId"] = v }
|
|
if let v = channelUrl { dict["channelUrl"] = v }
|
|
if let v = buildUrl { dict["buildUrl"] = v }
|
|
return dict
|
|
}
|
|
}
|