6 Commits
6 changed files with 131 additions and 8 deletions
+18
View File
@@ -1,3 +1,21 @@
## [1.1.3](https://git.krtss.de/StanPonomarev/twitter-patch/compare/v1.1.2...v1.1.3) (2026-08-22)
### 🐛 Bug Fixes
* xchat shutting down the app ([1985bf3](https://git.krtss.de/StanPonomarev/twitter-patch/commit/1985bf307b4552655216079082757a53af00140b))
## [1.1.2](https://git.krtss.de/StanPonomarev/twitter-patch/compare/v1.1.1...v1.1.2) (2026-08-22)
### 🐛 Bug Fixes
* manifest ([7062792](https://git.krtss.de/StanPonomarev/twitter-patch/commit/7062792215590cce79caa6e78354ee73375eaa79))
## [1.1.1](https://git.krtss.de/StanPonomarev/twitter-patch/compare/v1.1.0...v1.1.1) (2026-08-21)
### 🐛 Bug Fixes
* update screen ([cb1230a](https://git.krtss.de/StanPonomarev/twitter-patch/commit/cb1230a7abf46edb11f2b8dad100b091dd672aee))
## [1.1.0](https://git.krtss.de/StanPonomarev/twitter-patch/compare/v1.0.3...v1.1.0) (2026-08-21)
### ✨ New Features
+1 -1
View File
@@ -4,7 +4,7 @@ Patch bundle for X (Twitter), maintained by
[Stan Ponomarev](https://git.krtss.de/StanPonomarev).
<!-- PATCHES_START -->
> **[v1.1.0](https://git.krtss.de/StanPonomarev/twitter-patch/releases/tag/v1.1.0)**&nbsp;&nbsp;•&nbsp;&nbsp;`main`&nbsp;&nbsp;•&nbsp;&nbsp;2 patches total
> **[v1.1.3](https://git.krtss.de/StanPonomarev/twitter-patch/releases/tag/v1.1.3)**&nbsp;&nbsp;•&nbsp;&nbsp;`main`&nbsp;&nbsp;•&nbsp;&nbsp;2 patches total
<details open>
<summary>📦 X&nbsp;&nbsp;•&nbsp;&nbsp;2 patches</summary>
<br>
+1 -1
View File
@@ -1,4 +1,4 @@
org.gradle.parallel = true
org.gradle.caching = true
kotlin.code.style = official
version = 1.1.0
version = 1.1.3
+4 -4
View File
@@ -1,7 +1,7 @@
{
"created_at": "2026-08-21T18:50:29",
"description": "## [1.1.0](https://git.krtss.de/StanPonomarev/twitter-patch/compare/v1.0.3...v1.1.0) (2026-08-21)\n\n### ✨ New Features\n\n* remove upgrade button ([723964b](https://git.krtss.de/StanPonomarev/twitter-patch/commit/723964bc29d0a9edc7ad1915c9cf5669fe9e6f95))",
"download_url": "https://git.krtss.de/StanPonomarev/twitter-patch/releases/download/v1.1.0/patches-1.1.0.mpp",
"created_at": "2026-08-22T15:34:23",
"description": "## [1.1.3](https://git.krtss.de/StanPonomarev/twitter-patch/compare/v1.1.2...v1.1.3) (2026-08-22)\n\n### 🐛 Bug Fixes\n\n* xchat shutting down the app ([1985bf3](https://git.krtss.de/StanPonomarev/twitter-patch/commit/1985bf307b4552655216079082757a53af00140b))",
"download_url": "https://git.krtss.de/StanPonomarev/twitter-patch/releases/download/v1.1.3/patches-1.1.3.mpp",
"signature_download_url": "",
"version": "1.1.0"
"version": "1.1.3"
}
+4 -2
View File
@@ -1,12 +1,14 @@
{
"NOTE": "Do NOT manually edit this file. This file is automatically updated when semantic release (release.yml) runs. Manually editing this file can break your releases and break third party tools that use this file.",
"version": "1.1.0",
"version": "1.1.3",
"patches": [
{
"name": "Disable outdated version screen",
"description": "Prevents X from blocking app access when it marks the client version as outdated.",
"default": true,
"dependencies": [],
"dependencies": [
"ResourcePatch"
],
"compatiblePackages": [
{
"packageName": "com.twitter.android",
@@ -3,7 +3,9 @@ package app.twitter.patches
import app.morphe.patcher.extensions.InstructionExtensions.addInstructions
import app.morphe.patcher.Fingerprint
import app.morphe.patcher.patch.bytecodePatch
import app.morphe.patcher.patch.resourcePatch
import app.twitter.patches.shared.Constants.COMPATIBILITY_X
import org.w3c.dom.Element
private val outdatedVersionEnforcementFingerprint = Fingerprint(
definingClass = "Lcom/twitter/subsystem/clientshutdown/o;",
@@ -13,6 +15,41 @@ private val outdatedVersionEnforcementFingerprint = Fingerprint(
strings = listOf("Target version is ", "Detected shutdown")
)
private val forceUpdateNavigationFingerprint = Fingerprint(
definingClass = "Lcom/x/android/main/helpers/o8;",
name = "a",
returnType = "Lcom/x/compose/core/o2;",
parameters = listOf(
"Lcom/x/navigation/RootNavigationArgs;",
"Lcom/arkivanov/decompose/c;",
"Lcom/x/navigation/f1;"
)
)
private val shutdownForegroundHandlerFingerprint = Fingerprint(
definingClass = "Lcom/twitter/subsystem/clientshutdown/m;",
name = "invoke",
returnType = "Ljava/lang/Object;",
parameters = listOf("Ljava/lang/Object;"),
strings = listOf("Entered foreground, shutdown is ", "Launching app update")
)
private val appUpdateLauncherFingerprint = Fingerprint(
definingClass = "Lcom/twitter/subsystem/clientshutdown/i;",
name = "a",
returnType = "V",
parameters = listOf("Ljava/lang/String;"),
strings = listOf("Launching app update")
)
private val shutdownEntryPointDisablerFingerprint = Fingerprint(
definingClass = "Lcom/twitter/subsystem/clientshutdown/i;",
name = "b",
returnType = "V",
parameters = emptyList(),
strings = listOf("com.twitter.clientshutdown.update.AppUpdateActivityAlias")
)
private val shutdownStateFingerprint = Fingerprint(
definingClass = "Lcom/twitter/subsystem/clientshutdown/q;",
name = "isShutdown",
@@ -20,6 +57,31 @@ private val shutdownStateFingerprint = Fingerprint(
parameters = emptyList()
)
private val xChatObsoleteVersionStateFingerprint = Fingerprint(
definingClass = "Lcom/x/dms/y;",
name = "invokeSuspend",
returnType = "Ljava/lang/Object;",
parameters = listOf("Ljava/lang/Object;")
)
private const val APP_UPDATE_ACTIVITY = "com.twitter.clientshutdown.update.AppUpdateActivity"
private val disableOutdatedVersionActivityPatch = resourcePatch {
execute {
document("AndroidManifest.xml").use { document ->
val appUpdateActivity = document.getElementsByTagName("activity")
.let { activities ->
(0 until activities.length)
.asSequence()
.map { activities.item(it) }
.filterIsInstance<Element>()
.single { it.getAttribute("android:name") == APP_UPDATE_ACTIVITY }
}
appUpdateActivity.setAttribute("android:enabled", "false")
}
}
}
@Suppress("unused")
val disableOutdatedVersionScreenPatch = bytecodePatch(
name = "Disable outdated version screen",
@@ -27,8 +89,41 @@ val disableOutdatedVersionScreenPatch = bytecodePatch(
default = true
) {
compatibleWith(COMPATIBILITY_X)
dependsOn(disableOutdatedVersionActivityPatch)
execute {
forceUpdateNavigationFingerprint.method.addInstructions(
0,
"""
move-object/from16 v2, p1
instance-of v0, v2, Lcom/x/navigation/ForceUpdateArgs;
if-eqz v0, :force_update_allowed
sget-object v0, Lcom/x/navigation/MainLandingArgs${'$'}TabType;->HOME:Lcom/x/navigation/MainLandingArgs${'$'}TabType;
const/4 v1, 0x0
new-instance v2, Lcom/x/navigation/MainLandingArgs;
invoke-direct {v2, v0, v1, v1, v1}, Lcom/x/navigation/MainLandingArgs;-><init>(Lcom/x/navigation/MainLandingArgs${'$'}TabType;Lcom/x/navigation/AcceptGroupInviteArgs;Lcom/x/navigation/RootNavigationArgs;Lcom/x/models/PostIdentifier;)V
move-object/16 p1, v2
:force_update_allowed
"""
)
shutdownForegroundHandlerFingerprint.method.addInstructions(
0,
"""
sget-object v0, Lkotlin/Unit;->a:Lkotlin/Unit;
return-object v0
"""
)
appUpdateLauncherFingerprint.method.addInstructions(
0,
"return-void"
)
shutdownEntryPointDisablerFingerprint.method.addInstructions(
0,
"return-void"
)
outdatedVersionEnforcementFingerprint.method.addInstructions(
0,
"""
@@ -44,5 +139,13 @@ val disableOutdatedVersionScreenPatch = bytecodePatch(
return v0
"""
)
xChatObsoleteVersionStateFingerprint.method.addInstructions(
0,
"""
const/4 v0, 0x0
iput-boolean v0, p0, Lcom/x/dms/y;->o:Z
"""
)
}
}