Files
Leeksov 4647310322 GLEGram 12.5 — Initial public release
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.
2026-04-06 09:48:12 +03:00

68 lines
2.9 KiB
Swift

import Foundation
import UIKit
import SGConfig
import SGLogging
private let badgeImageCacheDir: String = {
let caches = NSSearchPathForDirectoriesInDomains(.cachesDirectory, .userDomainMask, true).first ?? NSTemporaryDirectory()
let dir = caches + "/sg_badge_images"
try? FileManager.default.createDirectory(atPath: dir, withIntermediateDirectories: true)
return dir
}()
private var inMemoryCache: [String: UIImage] = [:]
private let cacheQueue = DispatchQueue(label: "sg.badge.image.cache", qos: .userInitiated)
/// Returns cached badge image synchronously (nil if not yet downloaded).
public func cachedBadgeImage(for url: String) -> UIImage? {
let key = cacheKey(url)
if let mem = inMemoryCache[key] { return mem }
let path = badgeImageCacheDir + "/" + key + ".png"
guard let data = FileManager.default.contents(atPath: path), let img = UIImage(data: data) else { return nil }
inMemoryCache[key] = img
return img
}
/// Downloads and caches badge images in the background. Call after check_user.
/// Only fetches URLs that pass isUrlSafeForBadgeImage (same-origin, no SSRF).
public func prefetchBadgeImages(urls: [String], allowedBaseURL: String? = nil) {
let base = allowedBaseURL ?? SG_CONFIG.supportersApiUrl
for urlString in urls {
guard isUrlSafeForBadgeImage(urlString, allowedBaseURL: base) else {
SGLogger.shared.log("SGSupporters", "BadgeImageCache: skipped unsafe URL")
continue
}
let key = cacheKey(urlString)
if inMemoryCache[key] != nil { continue }
let path = badgeImageCacheDir + "/" + key + ".png"
if FileManager.default.fileExists(atPath: path) {
if let data = FileManager.default.contents(atPath: path), let img = UIImage(data: data) {
inMemoryCache[key] = img
}
continue
}
guard let url = URL(string: urlString) else { continue }
cacheQueue.async {
guard let data = try? Data(contentsOf: url), let img = UIImage(data: data) else {
SGLogger.shared.log("SGSupporters", "BadgeImageCache: failed to download \(urlString)")
return
}
FileManager.default.createFile(atPath: path, contents: img.pngData())
DispatchQueue.main.async {
inMemoryCache[key] = img
NotificationCenter.default.post(name: Notification.Name("SGBadgeImageDidCache"), object: nil)
}
SGLogger.shared.log("SGSupporters", "BadgeImageCache: cached \(urlString)")
}
}
}
private func cacheKey(_ url: String) -> String {
let cleaned = url
.replacingOccurrences(of: "https://", with: "")
.replacingOccurrences(of: "http://", with: "")
.replacingOccurrences(of: "/", with: "_")
.replacingOccurrences(of: ".", with: "_")
return String(cleaned.prefix(120))
}