ZaStoGram/TMessagesProj/build.gradle
2026-08-05 17:34:06 +03:00

351 lines
17 KiB
Groovy

import org.gradle.nativeplatform.platform.internal.DefaultNativePlatform
apply plugin: 'com.android.library'
// ZaStoGram plugin engine: embed CPython so .plugin scripts (exteraGram-compatible)
// can run. Chaquopy may be applied to exactly one module per app; TMessagesProj is the
// shared library, so every app flavor (Standalone/App/Huawei/...) inherits plugin support.
apply plugin: 'com.chaquo.python'
repositories {
mavenCentral()
google()
}
configurations {
compile.exclude module: 'support-v4'
}
configurations.all {
exclude group: 'com.google.firebase', module: 'firebase-core'
exclude group: 'androidx.recyclerview', module: 'recyclerview'
}
dependencies {
implementation 'androidx.core:core:1.16.0'
implementation 'androidx.webkit:webkit:1.14.0'
implementation 'androidx.palette:palette:1.0.0'
implementation 'androidx.exifinterface:exifinterface:1.3.6'
implementation 'androidx.dynamicanimation:dynamicanimation:1.0.0'
implementation "androidx.sharetarget:sharetarget:1.2.0"
implementation 'androidx.interpolator:interpolator:1.0.0'
implementation 'androidx.biometric:biometric:1.1.0'
implementation 'com.google.android.gms:play-services-cast-framework:21.4.0'
implementation "androidx.mediarouter:mediarouter:1.7.0"
implementation 'androidx.car.app:app:1.4.0'
implementation 'androidx.car.app:app-projected:1.4.0'
implementation 'org.nanohttpd:nanohttpd:2.3.1'
compileOnly 'org.checkerframework:checker-qual:2.5.2'
compileOnly 'org.checkerframework:checker-compat-qual:2.5.0'
implementation 'com.google.firebase:firebase-messaging:22.0.0'
implementation 'com.google.firebase:firebase-config:21.0.1'
implementation 'com.google.firebase:firebase-datatransport:18.1.0'
implementation 'com.google.firebase:firebase-appindexing:20.0.0'
implementation 'com.google.android.gms:play-services-maps:18.1.0'
implementation 'com.google.android.gms:play-services-auth:20.4.0'
implementation 'com.google.android.gms:play-services-vision:20.1.3'
implementation 'com.google.android.gms:play-services-wearable:18.0.0'
implementation 'com.google.android.gms:play-services-location:21.0.1'
implementation 'com.google.android.gms:play-services-wallet:19.1.0'
implementation 'com.googlecode.mp4parser:isoparser:1.0.6'
implementation 'com.stripe:stripe-android:2.0.2'
implementation 'com.google.mlkit:language-id:17.0.6'
implementation 'com.android.billingclient:billing:7.1.1'
implementation 'com.google.code.gson:gson:2.11.0'
implementation 'com.google.guava:guava:31.1-android'
implementation 'com.google.android.play:integrity:1.3.0'
implementation 'com.google.android.gms:play-services-safetynet:18.0.1'
implementation 'com.google.android.gms:play-services-mlkit-subject-segmentation:16.0.0-beta1'
implementation 'com.google.android.gms:play-services-mlkit-image-labeling:16.0.8'
implementation "androidx.credentials:credentials:1.6.0-alpha04"
implementation "androidx.credentials:credentials-play-services-auth:1.6.0-alpha04"
implementation "io.noties.markwon:core:4.6.2"
implementation "io.noties.markwon:ext-strikethrough:4.6.2"
implementation "io.noties.markwon:ext-tables:4.6.2"
implementation "io.noties.markwon:html:4.6.2"
implementation "io.noties.markwon:inline-parser:4.6.2"
implementation "io.noties.markwon:ext-latex:4.6.2"
// implementation 'com.google.mlkit:translate:17.0.3'
constraints {
implementation("org.jetbrains.kotlin:kotlin-stdlib-jdk7:1.8.0") {
because("kotlin-stdlib-jdk7 is now a part of kotlin-stdlib")
}
implementation("org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.8.0") {
because("kotlin-stdlib-jdk8 is now a part of kotlin-stdlib")
}
}
implementation 'com.google.android.recaptcha:recaptcha:18.7.1'
// ZaStoGram plugin engine: Pine — dynamic ART method hooking (Xposed-compatible API).
// Supports Android 4.4(ART)-15 on arm64/armv7. The :xposed module exposes
// XC_MethodHook (before/afterHookedMethod + MethodHookParam) used by the bridge.
implementation 'top.canyie.pine:core:0.3.0'
// NOTE: the :xposed compat module's latest published version is 0.2.0 (there is no 0.3.0).
// 0.2.0 declares no dependency on :core, so it coexists with core:0.3.0. If runtime ART
// hooking ever misbehaves from version skew, pin core down to 0.2.9 to match.
implementation 'top.canyie.pine:xposed:0.2.0'
coreLibraryDesugaring 'com.android.tools:desugar_jdk_libs:2.1.5'
}
def isWindows = String.valueOf(DefaultNativePlatform.currentOperatingSystem.toFamilyName() == OperatingSystemFamily.WINDOWS)
def zastoAllNativeAbis = ["armeabi-v7a", "arm64-v8a", "x86", "x86_64"]
def zastoRequestedAbiFilter = (project.findProperty("zastoAbiFilter") ?: System.getenv("ZASTO_ABI_FILTER"))?.toString()?.trim()
if (zastoRequestedAbiFilter && !zastoAllNativeAbis.contains(zastoRequestedAbiFilter)) {
throw new GradleException("Unsupported zastoAbiFilter '${zastoRequestedAbiFilter}'. Expected one of: ${zastoAllNativeAbis.join(', ')}")
}
def zastoUpdateChannel = (project.findProperty("zastoUpdateChannel") ?: System.getenv("ZASTO_UPDATE_CHANNEL") ?: "stable").toString().trim().toLowerCase()
if (!(zastoUpdateChannel in ["dev", "stable"])) {
throw new GradleException("Unsupported ZaStoGram update channel '${zastoUpdateChannel}'. Expected dev or stable")
}
def zastoReleaseTag = (project.findProperty("zastoReleaseTag") ?: System.getenv("ZASTO_RELEASE_TAG") ?: "").toString().trim()
def zastoGithubRepository = (project.findProperty("zastoGithubRepository") ?: System.getenv("ZASTO_GITHUB_REPOSITORY") ?: "youtubediscord/ZaStoGram").toString().trim()
if (!(zastoGithubRepository ==~ /[A-Za-z0-9_.-]+\/[A-Za-z0-9_.-]+/)) {
throw new GradleException("Invalid ZaStoGram GitHub repository '${zastoGithubRepository}'. Expected owner/repository")
}
def zastoBuildNumber = (project.findProperty("zastoBuildNumber") ?: System.getenv("ZASTO_BUILD_NUMBER") ?: "0").toString().trim()
if (!(zastoBuildNumber ==~ /\d+/) || zastoBuildNumber.toInteger() > 9999) {
throw new GradleException("Invalid ZaStoGram build number '${zastoBuildNumber}'. Expected an integer from 0 to 9999")
}
def zastoJavaString = { String value ->
return '"' + value.replace('\\', '\\\\').replace('"', '\\"') + '"'
}
android {
compileSdkVersion 35
buildToolsVersion '35.0.0'
ndkVersion "27.2.12479018"
sourceSets.main.jniLibs.srcDirs = ['./jni/']
externalNativeBuild {
cmake {
path 'jni/CMakeLists.txt'
}
}
lintOptions {
disable 'MissingTranslation'
disable 'ExtraTranslation'
disable 'BlockedPrivateApi'
}
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
coreLibraryDesugaringEnabled true
}
defaultConfig {
minSdkVersion 24 // ZaStoGram: Chaquopy (plugin engine) requires minSdk >= 24
targetSdkVersion 35
// ZaStoGram Standalone uses GitHub Releases instead of Telegram's app-update
// endpoint. CI overrides channel/tag/build number for every published APK.
buildConfigField "String", "ZASTO_UPDATE_CHANNEL", zastoJavaString(zastoUpdateChannel)
buildConfigField "String", "ZASTO_RELEASE_TAG", zastoJavaString(zastoReleaseTag)
buildConfigField "String", "ZASTO_GITHUB_REPOSITORY", zastoJavaString(zastoGithubRepository)
buildConfigField "int", "ZASTO_BUILD_NUMBER", zastoBuildNumber
vectorDrawables.generatedDensities = ['mdpi', 'hdpi', 'xhdpi', 'xxhdpi']
multiDexEnabled true
// ZaStoGram: CI matrix jobs pass one ABI so the library module does not rebuild
// all native outputs before packaging a single-ABI APK. Without the property, keep
// the universal fallback for local builds and afat.
ndk {
abiFilters(*(zastoRequestedAbiFilter ? [zastoRequestedAbiFilter] : zastoAllNativeAbis))
}
externalNativeBuild {
cmake {
version '3.10.2'
def cmakeArgs = ['-DANDROID_STL=c++_static', '-DANDROID_PLATFORM=android-21'] //, '-DANDROID_SUPPORT_FLEXIBLE_PAGE_SIZES=ON'
// CI speedup: route NDK compiles through ccache so unchanged native sources
// (webrtc/openh264/ffmpeg/boringssl) reuse cached object files across runs.
// Enabled only when USE_CCACHE=1 (GitHub Actions); local builds are unaffected.
if (System.getenv('USE_CCACHE') == '1') {
cmakeArgs << '-DCMAKE_C_COMPILER_LAUNCHER=ccache' << '-DCMAKE_CXX_COMPILER_LAUNCHER=ccache'
}
arguments(*cmakeArgs)
}
}
}
buildTypes {
debug {
jniDebuggable true
minifyEnabled false
shrinkResources false
multiDexEnabled true
proguardFiles getDefaultProguardFile('proguard-android.txt'), '../TMessagesProj/proguard-rules.pro', '../TMessagesProj/proguard-rules-beta.pro'
ndk.debugSymbolLevel = 'FULL'
buildConfigField "String", "BUILD_VERSION_STRING", "\"" + APP_VERSION_NAME + "\""
buildConfigField "String", "APP_CENTER_HASH", "\"\""
buildConfigField "String", "BETA_URL", "\"" + getProps("BETA_PRIVATE_URL") + "\""
buildConfigField "boolean", "DEBUG_VERSION", "true"
buildConfigField "boolean", "DEBUG_PRIVATE_VERSION", "true"
buildConfigField "boolean", "BUNDLE", "false"
buildConfigField "boolean", "BUILD_HOST_IS_WINDOWS", isWindows
buildConfigField "int", "VERSION_NUM", "0"
}
HA_private {
jniDebuggable false
minifyEnabled true
multiDexEnabled true
proguardFiles getDefaultProguardFile('proguard-android.txt'), '../TMessagesProj/proguard-rules.pro', '../TMessagesProj/proguard-rules-beta.pro'
ndk.debugSymbolLevel = 'FULL'
buildConfigField "String", "BUILD_VERSION_STRING", "\"" + APP_VERSION_NAME + "\""
buildConfigField "String", "APP_CENTER_HASH", "\"" + getProps("APP_CENTER_HASH_PRIVATE") + "\""
buildConfigField "String", "BETA_URL", "\"" + getProps("BETA_PRIVATE_URL") + "\""
buildConfigField "boolean", "DEBUG_VERSION", "true"
buildConfigField "boolean", "DEBUG_PRIVATE_VERSION", "true"
buildConfigField "boolean", "BUNDLE", "false"
buildConfigField "boolean", "BUILD_HOST_IS_WINDOWS", isWindows
buildConfigField "int", "VERSION_NUM", "1"
}
HA_public {
jniDebuggable false
minifyEnabled true
multiDexEnabled true
proguardFiles getDefaultProguardFile('proguard-android.txt'), '../TMessagesProj/proguard-rules.pro', '../TMessagesProj/proguard-rules-beta.pro'
ndk.debugSymbolLevel = 'FULL'
buildConfigField "String", "BUILD_VERSION_STRING", "\"" + APP_VERSION_NAME + "\""
buildConfigField "String", "APP_CENTER_HASH", "\"" + getProps("APP_CENTER_HASH_PUBLIC") + "\""
buildConfigField "String", "BETA_URL", "\"" + getProps("BETA_PUBLIC_URL") + "\""
buildConfigField "boolean", "DEBUG_VERSION", "true"
buildConfigField "boolean", "DEBUG_PRIVATE_VERSION", "false"
buildConfigField "boolean", "BUNDLE", "false"
buildConfigField "boolean", "BUILD_HOST_IS_WINDOWS", isWindows
buildConfigField "int", "VERSION_NUM", "4"
}
HA_hardcore {
jniDebuggable false
minifyEnabled true
multiDexEnabled true
proguardFiles getDefaultProguardFile('proguard-android.txt'), '../TMessagesProj/proguard-rules.pro', '../TMessagesProj/proguard-rules-beta.pro'
ndk.debugSymbolLevel = 'FULL'
buildConfigField "String", "BUILD_VERSION_STRING", "\"" + APP_VERSION_NAME + "\""
buildConfigField "String", "APP_CENTER_HASH", "\"" + getProps("APP_CENTER_HASH_HARDCORE") + "\""
buildConfigField "String", "BETA_URL", "\"" + getProps("BETA_HARDCORE_URL") + "\""
buildConfigField "boolean", "DEBUG_VERSION", "true"
buildConfigField "boolean", "DEBUG_PRIVATE_VERSION", "true"
buildConfigField "boolean", "BUNDLE", "false"
buildConfigField "boolean", "BUILD_HOST_IS_WINDOWS", isWindows
buildConfigField "int", "VERSION_NUM", "5"
}
standalone {
jniDebuggable false
// The standalone app module runs final R8 with this module's proguard rules.
// Running R8 here first only makes CI do an extra minify pass before the APK pass.
minifyEnabled false
multiDexEnabled true
proguardFiles getDefaultProguardFile('proguard-android.txt'), '../TMessagesProj/proguard-rules.pro'
ndk.debugSymbolLevel = 'FULL'
buildConfigField "String", "BUILD_VERSION_STRING", "\"" + APP_VERSION_NAME + "\""
buildConfigField "String", "APP_CENTER_HASH", "\"\""
buildConfigField "String", "BETA_URL", "\"\""
buildConfigField "boolean", "DEBUG_VERSION", "false"
buildConfigField "boolean", "DEBUG_PRIVATE_VERSION", "false"
buildConfigField "boolean", "BUNDLE", "false"
buildConfigField "boolean", "BUILD_HOST_IS_WINDOWS", isWindows
buildConfigField "int", "VERSION_NUM", "6"
}
release {
jniDebuggable false
minifyEnabled true
shrinkResources false
multiDexEnabled true
proguardFiles getDefaultProguardFile('proguard-android.txt'), '../TMessagesProj/proguard-rules.pro'
ndk.debugSymbolLevel = 'FULL'
buildConfigField "String", "BUILD_VERSION_STRING", "\"" + APP_VERSION_NAME + "\""
buildConfigField "String", "APP_CENTER_HASH", "\"\""
buildConfigField "String", "BETA_URL", "\"\""
buildConfigField "boolean", "DEBUG_VERSION", "false"
buildConfigField "boolean", "DEBUG_PRIVATE_VERSION", "false"
buildConfigField "boolean", "BUNDLE", "false"
buildConfigField "boolean", "BUILD_HOST_IS_WINDOWS", isWindows
buildConfigField "int", "VERSION_NUM", "7"
}
}
namespace 'org.telegram.messenger'
}
// ZaStoGram plugin engine — Python runtime configuration.
// Host API modules live in src/main/python (base_plugin, client_utils, ui.*, ...).
// User .plugin scripts are loaded at runtime from the data dir, not bundled here.
chaquopy {
defaultConfig {
version "3.11" // matches exteraGram (Chaquopy 16, CPython 3.11)
// The build machine needs a CPython 3.11 on PATH. If Android Studio can't find
// it (common on Windows), uncomment and point at it explicitly:
// buildPython "C:/Users/<you>/AppData/Local/Programs/Python/Python311/python.exe"
pyc {
src false // ship readable .py so plugin tracebacks map to real lines
}
pip {
// Common third-party libs community plugins expect at runtime. Chaquopy can only
// install these at BUILD time (there is no runtime pip), so they must be declared
// here once and shipped in the APK — mirrors what exteraGram bundles.
install "beautifulsoup4" // common HTML parsing helper used by plugin libraries
install "debugpy" // debugger backend listed by exteraGram for plugin development
install "lxml" // XML/HTML parser bundled by exteraGram
install "packaging" // version parsing for shared plugin libraries such as ZwyLib
install "Pillow" // exposes PIL for image-processing plugins
install "PyYAML" // YAML parser bundled by exteraGram
install "pyfiglet" // ASCIIGenerator and ASCII art plugins
install "requests" // th3_proxy_tools (country flags via ip-api, URL import) + many others
}
}
}
def getProps(String propName) {
def propsFile = rootProject.file('local.properties')
if (propsFile.exists()) {
def props = new Properties()
props.load(new FileInputStream(propsFile))
return props[propName]
} else {
return "";
}
}
apply plugin: 'com.google.gms.google-services'
task checkVisibility {
doFirst {
def isPrivateBuild = project.gradle.startParameter.taskNames.find {
it.contains("HA_private") || it.contains("HA_hardcore") || it.contains("Debug") || it.contains("Release")
}
def isPublicAllowed = !project.hasProperty("IS_PRIVATE") || !project.property("IS_PRIVATE").toBoolean()
if (!isPrivateBuild && !isPublicAllowed) {
throw new GradleException("Building public version of private code!")
}
}
doLast {
if (project.gradle.startParameter.taskNames.find { it.contains("HA_public") }) {
def privateBuild = file("${projectDir}_AppHockeyApp/afat/HA_private/Telegram-Beta.apk")
if (privateBuild.exists()) {
privateBuild.delete()
}
}
}
}
preBuild.dependsOn checkVisibility