Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 14 additions & 10 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,22 +4,21 @@

### Modern Xposed API (libxposed 102)

TeleVip now ships **two entry points in one APK** and runs on whichever contract the installed
framework activates:
TeleVip is now a **libxposed API 102 module**, loaded through a single modern entry point:

| Entry | Descriptor | Class |
|---|---|---|
| Modern (API 102) | `META-INF/xposed/java_init.list` + `module.prop` | `com.my.televip.xposed.TeleVipModule` |
| Legacy (API 93) | `assets/xposed_init` | `com.my.televip.MainHook` |

Both funnel into `com.my.televip.xposed.ModuleEntry#attach`, which is guarded so activating both
can never double-hook.
It funnels into `com.my.televip.xposed.ModuleEntry#attach`. The legacy API 93 entry
(`assets/xposed_init` → `MainHook`) was dropped before release: leaving it in place would make
LSPosed 1.9.x and EdXposed advertise the module and then fail at load time, because there is no
longer a `de.robv` entry class for them to find.

New compatibility layer under `com.my.televip.xposed`:

- **`XBridge`** — the only seam to the framework: hooking, logging, module APK path, deoptimize,
framework name/version. Everything else in the module goes through it.
- **`LegacyBackend`** — adapts to `de.robv.android.xposed.XposedBridge` / `XC_MethodHook`.
- **`ModernBackend`** — adapts to `XposedInterface.hook(Executable).intercept(Hooker)`. API 102
replaced the before/after pair with an OkHttp-style interceptor chain, so the adapter rebuilds
classic semantics on top of `Chain`: a result set in `beforeMethod` short-circuits the chain
Expand Down Expand Up @@ -49,19 +48,24 @@ the same best-match argument resolution (exact match → boxing → primitive wi
- Language packs moved from `assets/lang/` to `src/main/resources/lang/` and are read straight off
the module class loader — no APK path needed at all. The old ZIP scan is kept as a fallback and
still auto-discovers packs the index does not list.
- `Logger` routes through `XBridge`, so logging works on both backends and degrades to
`android.util.Log` if no backend is installed yet.
- `Logger` routes through `XBridge` and degrades to `android.util.Log` if no backend is
installed yet.
- Startup now logs the active backend, framework name and version.

### Nekogram

- **Nekogram X added** (`nekox.messenger`): new `Clients/NekogramX.java` resolver, `ClientType`
entry and `xposedscope` item. Like its Momogram fork, NekoX ships unobfuscated Telegram symbols,
so the mapping tables are empty and names resolve to upstream Telegram names.
entry and `META-INF/xposed/scope.list` item. Like its Momogram fork, NekoX ships unobfuscated
Telegram symbols, so the mapping tables are empty and names resolve to upstream Telegram names.
- **Version drift is now visible.** `ClientChecker#checkClientVersion` records the build each
resolver table was generated against and logs one clear warning at startup when the installed
client differs — loud for the obfuscated clients (Nekogram, Cherrygram), where a mismatch means
essentially every hook silently fails.
- **Official Telegram re-verified against 12.10.1** (build 70382). The symbols the module resolves
by name — `TLRPC.Message` fields, `TL_messages_readHistory` / `TL_channels_readHistory`,
`TL_updateDeleteMessages`, `MessagesController` / `ConnectionsManager` / `UserConfig` accessors
and `PeerStoriesView$StoryItemHolder#allowScreenshots` — are unchanged from the previously
verified build, so no hook needed updating.

> The Nekogram/Cherrygram R8 mapping tables themselves still have to be regenerated from the target
> APK whenever those clients update; that cannot be done from source.
Expand Down
8 changes: 4 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -80,14 +80,14 @@ A powerful Xposed module that adds advanced customization features to Telegram c

# 🧩 Supported frameworks

TeleVip ships **two entry points** and uses whichever one the installed framework activates, so a
single APK covers both the old and the new Xposed module contracts.
TeleVip is a **libxposed API 102 module only**. It declares `minApiVersion=102`, so frameworks that
implement the modern contract load it and older ones do not advertise it at all.

| Framework | Module API | Entry point |
|---|---|---|
| Vector 2.2+ (JingMatrix) | 102 (modern libxposed) | `META-INF/xposed/java_init.list` → `com.my.televip.xposed.TeleVipModule` |
| LSPosed 1.10+ | 100/102 (modern libxposed) | same as above |
| LSPosed (older), EdXposed, LSPatch | 93 (legacy) | `assets/xposed_init` → `com.my.televip.MainHook` |
| LSPosed 1.10+ | 102 (modern libxposed) | same as above |
| LSPosed 1.9.x, EdXposed, LSPatch | 93 (legacy) | **not supported** — the legacy `assets/xposed_init` entry was removed |

Zygisk providers: **Zygisk Next / NeoZygisk**, Magisk built-in Zygisk and KernelSU are all supported —
the module talks to the Xposed framework only through `com.my.televip.xposed.XBridge` and never
Expand Down
3 changes: 0 additions & 3 deletions app/proguard-rules.pro
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,6 @@
#-renamesourcefileattribute SourceFile

# --- Xposed -------------------------------------------------------------------
# Legacy entry point, referenced by name from assets/xposed_init.
-keep class com.my.televip.MainHook { *; }

# Modern libxposed entry point, referenced by name from META-INF/xposed/java_init.list.
-dontwarn io.github.libxposed.annotation.**
-adaptresourcefilecontents META-INF/xposed/java_init.list
Expand Down
7 changes: 6 additions & 1 deletion app/src/main/java/com/my/televip/ClientChecker.java
Original file line number Diff line number Diff line change
Expand Up @@ -33,11 +33,16 @@ public static boolean isTgnetObfuscated()
* R8 name, and those names change on every client release. When the installed build differs
* from the one below, the module used to fail silently with a stream of "Not found ..." lines;
* {@link #checkClientVersion} now says so once, up front.</p>
*
* <p>The number in brackets is {@code PackageInfo.versionCode}. Telegram encodes its build
* code and distribution channel in it as {@code code * 10 + channel}, where 1 and 2 are the
* store bundles and 9 is the direct/web APK — so 70382 is build 7038 (12.10.1) from the
* Play Store.</p>
*/
private static final Map<ClientType, String> VERIFIED_BUILD = new EnumMap<>(ClientType.class);

static {
VERIFIED_BUILD.put(ClientType.Telegram, "12.8.3 (69222)");
VERIFIED_BUILD.put(ClientType.Telegram, "12.10.1 (70382)");
VERIFIED_BUILD.put(ClientType.TelegramBeta, "12.9.0 (69579)");
VERIFIED_BUILD.put(ClientType.TelegramWeb, "12.8.3 (69229)");
VERIFIED_BUILD.put(ClientType.TelegramPlus, "12.8.1.0 (22350)");
Expand Down
2 changes: 1 addition & 1 deletion app/src/main/java/com/my/televip/xposed/ModernBackend.java
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
import io.github.libxposed.api.XposedInterfaceWrapper;

/**
* Backend for the modern libxposed API (100 / 102), i.e. current LSPosed and Vector 2.2.
* Backend for the modern libxposed API 102, i.e. current LSPosed and Vector 2.2.
*
* <p>API 102 replaced the before/after callback pair with an OkHttp-style interceptor chain. The
* adapter below rebuilds the classic semantics on top of it:</p>
Expand Down
6 changes: 3 additions & 3 deletions app/src/main/java/com/my/televip/xposed/TeleVipModule.java
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,11 @@
import io.github.libxposed.api.XposedModuleInterface;

/**
* Modern entry point (libxposed API 100 / 102).
* Modern entry point (libxposed API 102).
*
* <p>Registered through {@code META-INF/xposed/java_init.list}. Used by current LSPosed and by
* Vector 2.2 running on Zygisk Next / NeoZygisk. The legacy {@code assets/xposed_init} entry is
* still shipped for older frameworks; whichever the host picks, both land in
* Vector 2.2 running on Zygisk Next / NeoZygisk. This is the module's only entry point — the
* legacy {@code assets/xposed_init} path was removed — and it lands in
* {@link ModuleEntry#attach}.</p>
*
* <p>Per the API contract nothing is initialised in the constructor — the framework attaches itself
Expand Down
4 changes: 2 additions & 2 deletions app/src/main/resources/META-INF/xposed/module.prop
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Modern Xposed module descriptor (libxposed API).
# Read by LSPosed 1.10+ and Vector 2.2. Frameworks that do not understand this file
# fall back to assets/xposed_init + the xposedminversion meta-data (module API 93).
# Read by LSPosed 1.10+ and Vector 2.2. This is the module's only descriptor: the legacy
# API 93 path was removed, so a framework that cannot read this file will not load TeleVip.
minApiVersion=102
targetApiVersion=102
staticScope=false