diff --git a/CHANGELOG.md b/CHANGELOG.md index d850ff7..73f0113 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,70 @@ +# [1.12.0-dev.6](https://github.com/IndusAryan/twitter-patches/compare/v1.12.0-dev.5...v1.12.0-dev.6) (2024-03-22) + + +### Features + +* **twitter:** prepare merge2 ([33626bb](https://github.com/IndusAryan/twitter-patches/commit/33626bbd5d4608718f1b365cdcab78ddc90dd341)) + +# [1.12.0-dev.5](https://github.com/IndusAryan/twitter-patches/compare/v1.12.0-dev.4...v1.12.0-dev.5) (2024-03-22) + + +### Features + +* **twitter:** prepare merge ([e22f6ec](https://github.com/IndusAryan/twitter-patches/commit/e22f6ec42bc010c3d4f1702d41e46d7d6462264d)) + +# [1.12.0-dev.4](https://github.com/IndusAryan/twitter-patches/compare/v1.12.0-dev.3...v1.12.0-dev.4) (2024-03-22) + + +### Bug Fixes + +* **twitter:** fix monochrome again lmao ([37375b7](https://github.com/IndusAryan/twitter-patches/commit/37375b771babeb99f0c44e5fccf8f996904dcce0)) + +# [1.12.0-dev.3](https://github.com/IndusAryan/twitter-patches/compare/v1.12.0-dev.2...v1.12.0-dev.3) (2024-03-22) + + +### Bug Fixes + +* **twitter:** fix monochrome ([4d6622a](https://github.com/IndusAryan/twitter-patches/commit/4d6622a29d18da3fdbcc0412310ca141b738bc40)) + +# [1.12.0-dev.2](https://github.com/IndusAryan/twitter-patches/compare/v1.12.0-dev.1...v1.12.0-dev.2) (2024-03-22) + + +### Features + +* **twitter:** add warning. ([2cd9fc4](https://github.com/IndusAryan/twitter-patches/commit/2cd9fc47495f4f51e685cbcc45370ea60138f879)) + +# [1.12.0-dev.1](https://github.com/IndusAryan/twitter-patches/compare/v1.11.0...v1.12.0-dev.1) (2024-03-22) + + +### Bug Fixes + +* **twitter:** fix crash ([9f6aaa4](https://github.com/IndusAryan/twitter-patches/commit/9f6aaa42eeace22f539a533b1cf8fda7488ea116)) + + +### Features + +* **twitter:** initial patch release ([23740b0](https://github.com/IndusAryan/twitter-patches/commit/23740b061cda6bab54f2692bbd248ea78604a106)) +* **twitter:** new patches ([bc94acd](https://github.com/IndusAryan/twitter-patches/commit/bc94acda01cbb78065a7b4b190ad5f082ae89075)) + +# [1.12.0-dev.1](https://github.com/IndusAryan/twitter-patches/compare/v1.11.0...v1.12.0-dev.1) (2024-03-22) + + +### Bug Fixes + +* **twitter:** fix crash ([9f6aaa4](https://github.com/IndusAryan/twitter-patches/commit/9f6aaa42eeace22f539a533b1cf8fda7488ea116)) + + +### Features + +* **twitter:** new patches ([bc94acd](https://github.com/IndusAryan/twitter-patches/commit/bc94acda01cbb78065a7b4b190ad5f082ae89075)) + +# [1.12.0-dev.1](https://github.com/IndusAryan/twitter-patches/compare/v1.11.0...v1.12.0-dev.1) (2024-03-22) + + +### Features + +* **twitter:** new patches ([bc94acd](https://github.com/IndusAryan/twitter-patches/commit/bc94acda01cbb78065a7b4b190ad5f082ae89075)) + # [1.12.0-dev.1](https://github.com/IndusAryan/twitter-patches/compare/v1.11.0...v1.12.0-dev.1) (2024-03-16) diff --git a/README.md b/README.md index 4c3d77b..fd39a57 100644 --- a/README.md +++ b/README.md @@ -6,6 +6,7 @@ ⦿ OG Twitter name and in app branding ⦿ Bird Splash screen and toolbar icon ⦿ Three Icon sets +⦿ Adaptive Monochrome Icon ⦿ Video downloads -> from Revanced Official @@ -13,9 +14,7 @@ ⦿ Hide promoted users and AdBlock -> from Crimera Piko -⦿ Hide Google ads -⦿ Clean URL -⦿ Hide Promoted Trends +⦿ All Patches and settings menu (RIP originality) ``` ## Usage @@ -25,15 +24,18 @@ To use these patches, follow the steps below: 2. Set `twitter-patches` as the source for your patches.
-usage +usage
-## Warning: -Only use 1 icon patch and deselect other two otherwise; last applied patch will be used. +## Warnings: +Only use 1 icon patch and deselect other two otherwise; last applied patch icon will be used. +All icon sets contain adaptive monochrome icon. +Use crimera integrations as seen in image due to implementation of Mod menu. ## Icons
-icons +icons +adaptive_icons
## Screenshots @@ -70,4 +72,4 @@ These patches are fully FOSS. You can use, study, share and modify it at your wi --- ### Info: -These patches are only for educational purpose and personal usages. They are safe and don't tamper with any application functionality in a negative way, neither they are capable of it. We are not affiliated with Revanced Project. Some patches and parts are taken from Crimera and TheRealSwak, So many thanks to them and do star their Repo. +These patches are only for educational purpose and personal usages. They are safe and don't tamper with any application functionality in a negative way, neither they are capable of it. We are not affiliated with Revanced Project. This Repo also contains patches and parts from the Crimera piko and TheRealSwak, So many thanks to them and do star their awesome Repo. diff --git a/gradle.properties b/gradle.properties index d9cadc4..1f296f9 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,4 +1,4 @@ org.gradle.parallel = true org.gradle.caching = true kotlin.code.style = official -version = 1.12.0-dev.1 +version = 1.12.0-dev.6 diff --git a/package-lock.json b/package-lock.json index 7b58423..bd981ac 100644 --- a/package-lock.json +++ b/package-lock.json @@ -5217,7 +5217,7 @@ "inBundle": true, "license": "MIT", "dependencies": { - "ip": "^2.0.0", + "ip": "^2.0.1", "smart-buffer": "^4.2.0" }, "engines": { diff --git a/screenshots/raw1.jpg b/screenshots/raw1.jpg deleted file mode 100644 index bb6623e..0000000 Binary files a/screenshots/raw1.jpg and /dev/null differ diff --git a/screenshots/raw1.png b/screenshots/raw1.png new file mode 100644 index 0000000..75b2380 Binary files /dev/null and b/screenshots/raw1.png differ diff --git a/screenshots/raw3.jpg b/screenshots/raw3.jpg new file mode 100644 index 0000000..e50ace8 Binary files /dev/null and b/screenshots/raw3.jpg differ diff --git a/src/main/kotlin/indus/org/patches/twitter/XMLUtils.kt b/src/main/kotlin/indus/org/patches/twitter/XMLUtils.kt index d4a4ca6..39d73fa 100644 --- a/src/main/kotlin/indus/org/patches/twitter/XMLUtils.kt +++ b/src/main/kotlin/indus/org/patches/twitter/XMLUtils.kt @@ -11,6 +11,7 @@ class XMLUtils(context: ResourceContext) { /*** ⚠ DON'T TOUCH THE XML WITHIN """INDENTS""", IT FUCKS UP THE WHOLE VECTOR AS WELL AS PATCH **/ private val avatarMarkerTwitterFile = context["res/drawable/avatar_marker_twitter.xml"] + private val monochromeFile = context["res/drawable/ic_vector_twitter_circle_fill.xml"] private val mipmapDirectory = context["res"].resolve("mipmap-anydpi") private val mipmapDirectory26 = context["res"].resolve("mipmap-anydpi-v26") private val icLauncherTwitterXml = mipmapDirectory.resolve("ic_launcher_twitter.xml") @@ -18,8 +19,9 @@ class XMLUtils(context: ResourceContext) { private val icLauncherTwitterXml26 = mipmapDirectory26.resolve("ic_launcher_twitter.xml") private val icLauncherTwitterRoundXml26 = mipmapDirectory26.resolve("ic_launcher_twitter_round.xml") - private fun avatarFile() { + private fun createIconFiles() { if (!avatarMarkerTwitterFile.isFile) Files.createFile(avatarMarkerTwitterFile.toPath()) + if (!monochromeFile.isFile) Files.createFile(monochromeFile.toPath()) } fun whiteIconBlackBG() { @@ -53,7 +55,8 @@ class XMLUtils(context: ResourceContext) { """.trimIndent() - avatarFile() + createIconFiles() + addMonochromeIcon() avatarMarkerTwitterFile.writeText(whiteBird) } @@ -88,7 +91,8 @@ class XMLUtils(context: ResourceContext) { """.trimIndent() - avatarFile() + createIconFiles() + addMonochromeIcon() avatarMarkerTwitterFile.writeText(newAvatarMarkerTwitterContent) } @@ -123,7 +127,8 @@ class XMLUtils(context: ResourceContext) { """.trimIndent() - avatarFile() + createIconFiles() + addMonochromeIcon() avatarMarkerTwitterFile.writeText(blackIcon) } @@ -158,16 +163,34 @@ class XMLUtils(context: ResourceContext) { vectorFileDark.writeText(newBirdVector) } + private fun addMonochromeIcon() { + val adaptiveIcon = """ + + + + + """.trimIndent() + + monochromeFile.writeText(adaptiveIcon) + } + private fun updateXmlFile(xmlFile: File) { if (!Files.isRegularFile(xmlFile.toPath())) throw PatchException("$xmlFile not found.") - val content = xmlFile.readText() - val modifiedContent = content.replace( - """android:drawable="@mipmap/ic_launcher_twitter_foreground"""", - """android:drawable="@drawable/avatar_marker_twitter"""" - ) + val newMipmap = """ + + + + + + + """.trimIndent() - xmlFile.writeText(modifiedContent) + xmlFile.writeText(newMipmap) } fun updateLauncherXmlFiles() { @@ -181,6 +204,7 @@ class XMLUtils(context: ResourceContext) { updateXmlFile(icLauncherTwitterXml26) updateXmlFile(icLauncherTwitterRoundXml26) } + else throw PatchException("Mipmap directory not found") } } \ No newline at end of file diff --git a/src/main/kotlin/indus/org/patches/twitter/adsandpromotions/fingerprints/GAdsFingerprint.kt b/src/main/kotlin/indus/org/patches/twitter/adsandpromotions/fingerprints/GAdsFingerprint.kt deleted file mode 100644 index a1da2f7..0000000 --- a/src/main/kotlin/indus/org/patches/twitter/adsandpromotions/fingerprints/GAdsFingerprint.kt +++ /dev/null @@ -1,10 +0,0 @@ -package indus.org.patches.twitter.adsandpromotions.fingerprints - -import app.revanced.patcher.fingerprint.MethodFingerprint - -object GAdsFingerprint : MethodFingerprint( - returnType = "V", - strings = listOf( - "ssp_ads_google_dsp_client_context_enabled" - ) -) diff --git a/src/main/kotlin/indus/org/patches/twitter/crimeraswak/ads/timelineEntryHook/HideAds.kt b/src/main/kotlin/indus/org/patches/twitter/crimeraswak/ads/timelineEntryHook/HideAds.kt new file mode 100644 index 0000000..5bc251b --- /dev/null +++ b/src/main/kotlin/indus/org/patches/twitter/crimeraswak/ads/timelineEntryHook/HideAds.kt @@ -0,0 +1,27 @@ +package indus.org.patches.twitter.crimeraswak.ads.timelineEntryHook + +import app.revanced.patcher.data.BytecodeContext +import app.revanced.patcher.extensions.InstructionExtensions.addInstruction +import app.revanced.patcher.patch.BytecodePatch +import app.revanced.patcher.patch.annotation.CompatiblePackage +import app.revanced.patcher.patch.annotation.Patch +import indus.org.patches.twitter.crimeraswak.misc.settings.SettingsPatch +import indus.org.patches.twitter.crimeraswak.misc.settings.fingerprints.SettingsStatusLoadFingerprint + +@Patch( + name = "Remove Ads", + dependencies = [SettingsPatch::class, TimelineEntryHookPatch::class], + compatiblePackages = [CompatiblePackage("com.twitter.android")], + use = true +) +object HideAds :BytecodePatch( + setOf() +){ + override fun execute(context: BytecodeContext) { + SettingsStatusLoadFingerprint.result!!.mutableMethod.addInstruction( + 0, + "${SettingsPatch.SSTS_DESCRIPTOR}->hideAds()V" + ) + + } +} \ No newline at end of file diff --git a/src/main/kotlin/indus/org/patches/twitter/crimeraswak/ads/timelineEntryHook/HideCTJ.kt b/src/main/kotlin/indus/org/patches/twitter/crimeraswak/ads/timelineEntryHook/HideCTJ.kt new file mode 100644 index 0000000..507677d --- /dev/null +++ b/src/main/kotlin/indus/org/patches/twitter/crimeraswak/ads/timelineEntryHook/HideCTJ.kt @@ -0,0 +1,27 @@ +package indus.org.patches.twitter.crimeraswak.ads.timelineEntryHook + +import app.revanced.patcher.data.BytecodeContext +import app.revanced.patcher.extensions.InstructionExtensions.addInstruction +import app.revanced.patcher.patch.BytecodePatch +import app.revanced.patcher.patch.annotation.CompatiblePackage +import app.revanced.patcher.patch.annotation.Patch +import indus.org.patches.twitter.crimeraswak.misc.settings.SettingsPatch +import indus.org.patches.twitter.crimeraswak.misc.settings.fingerprints.SettingsStatusLoadFingerprint + +@Patch( + name = "Remove \"Communities to join\" Banner", + dependencies = [SettingsPatch::class, TimelineEntryHookPatch::class], + compatiblePackages = [CompatiblePackage("com.twitter.android")], + use = true +) +object HideCTJ :BytecodePatch( + setOf() +){ + override fun execute(context: BytecodeContext) { + SettingsStatusLoadFingerprint.result!!.mutableMethod.addInstruction( + 0, + "${SettingsPatch.SSTS_DESCRIPTOR}->hideCommToJoin()V" + ) + + } +} \ No newline at end of file diff --git a/src/main/kotlin/indus/org/patches/twitter/crimeraswak/ads/timelineEntryHook/HideCTS.kt b/src/main/kotlin/indus/org/patches/twitter/crimeraswak/ads/timelineEntryHook/HideCTS.kt new file mode 100644 index 0000000..9fc2808 --- /dev/null +++ b/src/main/kotlin/indus/org/patches/twitter/crimeraswak/ads/timelineEntryHook/HideCTS.kt @@ -0,0 +1,27 @@ +package indus.org.patches.twitter.crimeraswak.ads.timelineEntryHook + +import app.revanced.patcher.data.BytecodeContext +import app.revanced.patcher.extensions.InstructionExtensions.addInstruction +import app.revanced.patcher.patch.BytecodePatch +import app.revanced.patcher.patch.annotation.CompatiblePackage +import app.revanced.patcher.patch.annotation.Patch +import indus.org.patches.twitter.crimeraswak.misc.settings.SettingsPatch +import indus.org.patches.twitter.crimeraswak.misc.settings.fingerprints.SettingsStatusLoadFingerprint + +@Patch( + name = "Remove \"Creators to subscribe\" Banner", + dependencies = [SettingsPatch::class, TimelineEntryHookPatch::class], + compatiblePackages = [CompatiblePackage("com.twitter.android")], + use = true +) +object HideCTS :BytecodePatch( + setOf() +){ + override fun execute(context: BytecodeContext) { + SettingsStatusLoadFingerprint.result!!.mutableMethod.addInstruction( + 0, + "${SettingsPatch.SSTS_DESCRIPTOR}->hideCreatorsToSub()V" + ) + + } +} \ No newline at end of file diff --git a/src/main/kotlin/indus/org/patches/twitter/crimeraswak/ads/timelineEntryHook/HideDetailedPosts.kt b/src/main/kotlin/indus/org/patches/twitter/crimeraswak/ads/timelineEntryHook/HideDetailedPosts.kt new file mode 100644 index 0000000..80c5058 --- /dev/null +++ b/src/main/kotlin/indus/org/patches/twitter/crimeraswak/ads/timelineEntryHook/HideDetailedPosts.kt @@ -0,0 +1,28 @@ +package indus.org.patches.twitter.crimeraswak.ads.timelineEntryHook + +import app.revanced.patcher.data.BytecodeContext +import app.revanced.patcher.extensions.InstructionExtensions.addInstruction +import app.revanced.patcher.patch.BytecodePatch +import app.revanced.patcher.patch.annotation.CompatiblePackage +import app.revanced.patcher.patch.annotation.Patch +import indus.org.patches.twitter.crimeraswak.misc.settings.SettingsPatch +import indus.org.patches.twitter.crimeraswak.misc.settings.fingerprints.SettingsStatusLoadFingerprint + +@Patch( + name = "Remove Detailed posts", + description = "Removes detailed posts in replies", + dependencies = [SettingsPatch::class, TimelineEntryHookPatch::class], + compatiblePackages = [CompatiblePackage("com.twitter.android")], + use = false +) +object HideDetailedPosts :BytecodePatch( + setOf() +){ + override fun execute(context: BytecodeContext) { + SettingsStatusLoadFingerprint.result!!.mutableMethod.addInstruction( + 0, + "${SettingsPatch.SSTS_DESCRIPTOR}->hideDetailedPost()V" + ) + + } +} \ No newline at end of file diff --git a/src/main/kotlin/indus/org/patches/twitter/crimeraswak/ads/timelineEntryHook/HideGoogleAds.kt b/src/main/kotlin/indus/org/patches/twitter/crimeraswak/ads/timelineEntryHook/HideGoogleAds.kt new file mode 100644 index 0000000..54fcd31 --- /dev/null +++ b/src/main/kotlin/indus/org/patches/twitter/crimeraswak/ads/timelineEntryHook/HideGoogleAds.kt @@ -0,0 +1,27 @@ +package indus.org.patches.twitter.crimeraswak.ads.timelineEntryHook + +import app.revanced.patcher.data.BytecodeContext +import app.revanced.patcher.extensions.InstructionExtensions.addInstruction +import app.revanced.patcher.patch.BytecodePatch +import app.revanced.patcher.patch.annotation.CompatiblePackage +import app.revanced.patcher.patch.annotation.Patch +import indus.org.patches.twitter.crimeraswak.misc.settings.SettingsPatch +import indus.org.patches.twitter.crimeraswak.misc.settings.fingerprints.SettingsStatusLoadFingerprint + +@Patch( + name = "Remove Google Ads", + dependencies = [SettingsPatch::class, TimelineEntryHookPatch::class], + compatiblePackages = [CompatiblePackage("com.twitter.android")], + use = true +) +object HideGoogleAds :BytecodePatch( + setOf() +){ + override fun execute(context: BytecodeContext) { + SettingsStatusLoadFingerprint.result!!.mutableMethod.addInstruction( + 0, + "${SettingsPatch.SSTS_DESCRIPTOR}->hideGAds()V" + ) + + } +} \ No newline at end of file diff --git a/src/main/kotlin/indus/org/patches/twitter/crimeraswak/ads/timelineEntryHook/HidePinnedByFollowers.kt b/src/main/kotlin/indus/org/patches/twitter/crimeraswak/ads/timelineEntryHook/HidePinnedByFollowers.kt new file mode 100644 index 0000000..1eb212a --- /dev/null +++ b/src/main/kotlin/indus/org/patches/twitter/crimeraswak/ads/timelineEntryHook/HidePinnedByFollowers.kt @@ -0,0 +1,28 @@ +package indus.org.patches.twitter.crimeraswak.ads.timelineEntryHook + +import app.revanced.patcher.data.BytecodeContext +import app.revanced.patcher.extensions.InstructionExtensions.addInstruction +import app.revanced.patcher.patch.BytecodePatch +import app.revanced.patcher.patch.annotation.CompatiblePackage +import app.revanced.patcher.patch.annotation.Patch +import indus.org.patches.twitter.crimeraswak.misc.settings.SettingsPatch +import indus.org.patches.twitter.crimeraswak.misc.settings.fingerprints.SettingsStatusLoadFingerprint + +@Patch( + name = "Remove \"Pinned posts by followers\" Banner", + dependencies = [SettingsPatch::class,TimelineEntryHookPatch::class], + compatiblePackages = [CompatiblePackage("com.twitter.android")], + use = true +) +@Suppress("UNUSED") +object HidePinnedByFollowers :BytecodePatch( + setOf() +){ + override fun execute(context: BytecodeContext) { + SettingsStatusLoadFingerprint.result!!.mutableMethod.addInstruction( + 0, + "${SettingsPatch.SSTS_DESCRIPTOR}->hideRevistPinnedPost()V" + ) + + } +} \ No newline at end of file diff --git a/src/main/kotlin/indus/org/patches/twitter/crimeraswak/ads/timelineEntryHook/HideWTF.kt b/src/main/kotlin/indus/org/patches/twitter/crimeraswak/ads/timelineEntryHook/HideWTF.kt new file mode 100644 index 0000000..61bde4e --- /dev/null +++ b/src/main/kotlin/indus/org/patches/twitter/crimeraswak/ads/timelineEntryHook/HideWTF.kt @@ -0,0 +1,27 @@ +package indus.org.patches.twitter.crimeraswak.ads.timelineEntryHook + +import app.revanced.patcher.data.BytecodeContext +import app.revanced.patcher.extensions.InstructionExtensions.addInstruction +import app.revanced.patcher.patch.BytecodePatch +import app.revanced.patcher.patch.annotation.CompatiblePackage +import app.revanced.patcher.patch.annotation.Patch +import indus.org.patches.twitter.crimeraswak.misc.settings.SettingsPatch +import indus.org.patches.twitter.crimeraswak.misc.settings.fingerprints.SettingsStatusLoadFingerprint + +@Patch( + name = "Remove \"Who to follow\" Banner", + dependencies = [SettingsPatch::class, TimelineEntryHookPatch::class], + compatiblePackages = [CompatiblePackage("com.twitter.android")], + use = false +) +object HideWTF :BytecodePatch( + setOf() +){ + override fun execute(context: BytecodeContext) { + SettingsStatusLoadFingerprint.result!!.mutableMethod.addInstruction( + 0, + "${SettingsPatch.SSTS_DESCRIPTOR}->hideWhoToFollow()V" + ) + + } +} \ No newline at end of file diff --git a/src/main/kotlin/indus/org/patches/twitter/crimeraswak/ads/timelineEntryHook/TimelineEntryHookPatch.kt b/src/main/kotlin/indus/org/patches/twitter/crimeraswak/ads/timelineEntryHook/TimelineEntryHookPatch.kt new file mode 100644 index 0000000..19bdbdf --- /dev/null +++ b/src/main/kotlin/indus/org/patches/twitter/crimeraswak/ads/timelineEntryHook/TimelineEntryHookPatch.kt @@ -0,0 +1,50 @@ +package indus.org.patches.twitter.crimeraswak.ads.timelineEntryHook + +import app.revanced.patcher.data.BytecodeContext +import app.revanced.patcher.extensions.InstructionExtensions.addInstructionsWithLabels +import app.revanced.patcher.extensions.InstructionExtensions.getInstructions +import app.revanced.patcher.patch.BytecodePatch +import app.revanced.patcher.patch.PatchException +import app.revanced.patcher.patch.annotation.CompatiblePackage +import app.revanced.patcher.patch.annotation.Patch +import app.revanced.patcher.util.smali.ExternalLabel +import com.android.tools.smali.dexlib2.Opcode +import indus.org.patches.twitter.crimeraswak.misc.settings.SettingsPatch +import app.revanced.patcher.fingerprint.MethodFingerprint + +object TimelineEntryHookFingerprint:MethodFingerprint( + returnType = "Ljava/lang/Object", + customFingerprint = {it,_-> + it.definingClass == "Lcom/twitter/model/json/timeline/urt/JsonTimelineEntry\$\$JsonObjectMapper;" && it.name == "parse" + } +) + +@Patch( + name = "Hook for timeline entry", + compatiblePackages = [CompatiblePackage("com.twitter.android")], +) +object TimelineEntryHookPatch:BytecodePatch( + setOf(TimelineEntryHookFingerprint) +){ + override fun execute(context: BytecodeContext) { + val TIMELINE_ENTRY_DESCRIPTOR = "${SettingsPatch.PATCHES_DESCRIPTOR}/TimelineEntry" + + val result = TimelineEntryHookFingerprint.result + ?:throw PatchException("TimelineEntryHookFingerprint not found") + + val methods = result.mutableMethod + val instructions = methods.getInstructions() + + val returnObj = instructions.last { it.opcode == Opcode.RETURN_OBJECT } + + methods.addInstructionsWithLabels(returnObj.location.index,""" + invoke-static {p1}, $TIMELINE_ENTRY_DESCRIPTOR;->checkEntry(Ljava/lang/Object;)Z + move-result v0 + if-eqz v0, :end + const p1,0x0 + """.trimIndent(), + ExternalLabel("end",returnObj)) + + //end + } +} \ No newline at end of file diff --git a/src/main/kotlin/indus/org/patches/twitter/adsandpromotions/RemovePromotedTrends.kt b/src/main/kotlin/indus/org/patches/twitter/crimeraswak/ads/trends/HidePromotedTrendPatch.kt similarity index 61% rename from src/main/kotlin/indus/org/patches/twitter/adsandpromotions/RemovePromotedTrends.kt rename to src/main/kotlin/indus/org/patches/twitter/crimeraswak/ads/trends/HidePromotedTrendPatch.kt index f7a6f9f..b290f23 100644 --- a/src/main/kotlin/indus/org/patches/twitter/adsandpromotions/RemovePromotedTrends.kt +++ b/src/main/kotlin/indus/org/patches/twitter/crimeraswak/ads/trends/HidePromotedTrendPatch.kt @@ -1,6 +1,7 @@ -package indus.org.patches.twitter.adsandpromotions +package indus.org.patches.twitter.crimeraswak.ads.trends import app.revanced.patcher.data.BytecodeContext +import app.revanced.patcher.extensions.InstructionExtensions.addInstruction import app.revanced.patcher.extensions.InstructionExtensions.addInstructionsWithLabels import app.revanced.patcher.extensions.InstructionExtensions.getInstruction import app.revanced.patcher.extensions.InstructionExtensions.getInstructions @@ -12,16 +13,19 @@ import app.revanced.patcher.util.smali.ExternalLabel import com.android.tools.smali.dexlib2.Opcode import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction import com.android.tools.smali.dexlib2.iface.instruction.TwoRegisterInstruction -import indus.org.patches.twitter.adsandpromotions.fingerprints.HidePromotedTrendFingerprint +import indus.org.patches.twitter.crimeraswak.ads.trends.fingerprints.HidePromotedTrendFingerprint +import indus.org.patches.twitter.crimeraswak.misc.settings.SettingsPatch +import indus.org.patches.twitter.crimeraswak.misc.settings.fingerprints.SettingsStatusLoadFingerprint @Patch( name = "Hide Promoted Trends", + dependencies = [SettingsPatch::class], compatiblePackages = [CompatiblePackage("com.twitter.android")], use = true ) @Suppress("unused") -object RemovePromotedTrends : BytecodePatch( - setOf(HidePromotedTrendFingerprint) +class HidePromotedTrendPatch : BytecodePatch( + setOf(HidePromotedTrendFingerprint, SettingsStatusLoadFingerprint) ) { override fun execute(context: BytecodeContext) { val result = HidePromotedTrendFingerprint.result @@ -33,15 +37,26 @@ object RemovePromotedTrends : BytecodePatch( val return_obj = instructions.last { it.opcode == Opcode.RETURN_OBJECT } val return_loc = return_obj.location.index val return_reg = method.getInstruction(return_loc).registerA - val loc = return_loc - 7 + val loc = return_loc-7 val reg = method.getInstruction(loc).registerA - method.addInstructionsWithLabels( - return_loc, """ + val HOOK_DESCRIPTOR = + "invoke-static {v$reg}, ${SettingsPatch.PREF_DESCRIPTOR};->hidePromotedTrend(Ljava/lang/Object;)Z" + + + method.addInstructionsWithLabels(return_loc,""" + $HOOK_DESCRIPTOR + move-result v$reg if-eqz v$reg, :cond_1212 const v$return_reg, 0x0 """.trimIndent(), ExternalLabel("cond_1212", return_obj) ) + + + SettingsStatusLoadFingerprint.result!!.mutableMethod.addInstruction( + 0, + "${SettingsPatch.SSTS_DESCRIPTOR}->hidePromotedTrends()V" + ) } -} +} \ No newline at end of file diff --git a/src/main/kotlin/indus/org/patches/twitter/adsandpromotions/fingerprints/HidePromotedTrendFingerprint.kt b/src/main/kotlin/indus/org/patches/twitter/crimeraswak/ads/trends/fingerprints/HidePromotedTrendFingerprint.kt similarity index 79% rename from src/main/kotlin/indus/org/patches/twitter/adsandpromotions/fingerprints/HidePromotedTrendFingerprint.kt rename to src/main/kotlin/indus/org/patches/twitter/crimeraswak/ads/trends/fingerprints/HidePromotedTrendFingerprint.kt index 9fe3f86..81e06a8 100644 --- a/src/main/kotlin/indus/org/patches/twitter/adsandpromotions/fingerprints/HidePromotedTrendFingerprint.kt +++ b/src/main/kotlin/indus/org/patches/twitter/crimeraswak/ads/trends/fingerprints/HidePromotedTrendFingerprint.kt @@ -1,4 +1,4 @@ -package indus.org.patches.twitter.adsandpromotions.fingerprints +package indus.org.patches.twitter.crimeraswak.ads.trends.fingerprints import app.revanced.patcher.fingerprint.MethodFingerprint @@ -7,4 +7,4 @@ object HidePromotedTrendFingerprint : MethodFingerprint( customFingerprint = {it,_-> it.definingClass == "Lcom/twitter/model/json/timeline/urt/JsonTimelineTrend;" } -) +) \ No newline at end of file diff --git a/src/main/kotlin/indus/org/patches/twitter/crimeraswak/integrations/BaseIntegrationsPatch.kt b/src/main/kotlin/indus/org/patches/twitter/crimeraswak/integrations/BaseIntegrationsPatch.kt new file mode 100644 index 0000000..b16d1a8 --- /dev/null +++ b/src/main/kotlin/indus/org/patches/twitter/crimeraswak/integrations/BaseIntegrationsPatch.kt @@ -0,0 +1,78 @@ +package indus.org.patches.twitter.crimeraswak.integrations + +import app.revanced.patcher.data.BytecodeContext +import app.revanced.patcher.extensions.InstructionExtensions.addInstruction +import app.revanced.patcher.fingerprint.MethodFingerprint +import app.revanced.patcher.patch.BytecodePatch +import app.revanced.patcher.patch.PatchException +import com.android.tools.smali.dexlib2.Opcode +import com.android.tools.smali.dexlib2.iface.ClassDef +import com.android.tools.smali.dexlib2.iface.Method + +abstract class BaseIntegrationsPatch( + private val hooks: Set +) : BytecodePatch(hooks) { + + @Deprecated( + "Use the constructor without the integrationsDescriptor parameter", + ReplaceWith("AbstractIntegrationsPatch(hooks)") + ) + @Suppress("UNUSED_PARAMETER") + constructor( + integrationsDescriptor: String, + hooks: Set + ) : this(hooks) + + override fun execute(context: BytecodeContext) { + if (context.findClass(INTEGRATIONS_CLASS_DESCRIPTOR) == null) throw PatchException( + "Integrations have not been merged yet. This patch can not succeed without merging the integrations." + ) + + hooks.forEach { hook -> + hook.invoke(INTEGRATIONS_CLASS_DESCRIPTOR) + } + } + + /** + * [MethodFingerprint] for integrations. + * + * @param contextRegisterResolver A [IRegisterResolver] to get the register. + * @see MethodFingerprint + */ + abstract class IntegrationsFingerprint( + returnType: String? = null, + accessFlags: Int? = null, + parameters: Iterable? = null, + opcodes: Iterable? = null, + strings: Iterable? = null, + customFingerprint: ((methodDef: Method, classDef: ClassDef) -> Boolean)? = null, + private val contextRegisterResolver: (Method) -> Int = object : IRegisterResolver {} + ) : MethodFingerprint( + returnType, + accessFlags, + parameters, + opcodes, + strings, + customFingerprint + ) { + fun invoke(integrationsDescriptor: String) { + result?.mutableMethod?.let { method -> + val contextRegister = contextRegisterResolver(method) + + method.addInstruction( + 0, + "sput-object v$contextRegister, " + + "$integrationsDescriptor->context:Landroid/content/Context;" + ) + } ?: throw PatchException("Could not find hook target fingerprint.") + } + + interface IRegisterResolver : (Method) -> Int { + override operator fun invoke(method: Method) = method.implementation!!.registerCount - 1 + } + } + + private companion object { + private const val INTEGRATIONS_CLASS_DESCRIPTOR = "Lapp/revanced/integrations/shared/Utils;" + } +} \ No newline at end of file diff --git a/src/main/kotlin/indus/org/patches/twitter/crimeraswak/interaction/downloads/changedirectory/ChangeDownloadDirPatch.kt b/src/main/kotlin/indus/org/patches/twitter/crimeraswak/interaction/downloads/changedirectory/ChangeDownloadDirPatch.kt new file mode 100644 index 0000000..0827e2c --- /dev/null +++ b/src/main/kotlin/indus/org/patches/twitter/crimeraswak/interaction/downloads/changedirectory/ChangeDownloadDirPatch.kt @@ -0,0 +1,57 @@ +package indus.org.patches.twitter.crimeraswak.interaction.downloads.changedirectory + +import app.revanced.patcher.data.BytecodeContext +import app.revanced.patcher.extensions.InstructionExtensions.addInstruction +import app.revanced.patcher.extensions.InstructionExtensions.addInstructions +import app.revanced.patcher.extensions.InstructionExtensions.getInstruction +import app.revanced.patcher.extensions.InstructionExtensions.getInstructions +import app.revanced.patcher.patch.BytecodePatch +import app.revanced.patcher.patch.PatchException +import app.revanced.patcher.patch.annotation.CompatiblePackage +import app.revanced.patcher.patch.annotation.Patch +import com.android.tools.smali.dexlib2.Opcode +import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction +import indus.org.patches.twitter.crimeraswak.interaction.downloads.changedirectory.fingerprints.SetDownloadDestinationFingerprint +import indus.org.patches.twitter.crimeraswak.misc.settings.SettingsPatch +import indus.org.patches.twitter.crimeraswak.misc.settings.SettingsPatch.PREF_DESCRIPTOR +import indus.org.patches.twitter.crimeraswak.misc.settings.fingerprints.SettingsStatusLoadFingerprint + +@Patch( + name = "Custom download folder", + description = "Change the download directory for video downloads", + dependencies = [SettingsPatch::class], + compatiblePackages = [CompatiblePackage("com.twitter.android")] +) +@Suppress("unused") +object ChangeDownloadDirPatch: BytecodePatch( + setOf(SetDownloadDestinationFingerprint, SettingsStatusLoadFingerprint) +) { + private const val GETFOLDER_DESCRIPTOR = + "invoke-static {p1}, $PREF_DESCRIPTOR;->getVideoFolder(Ljava/lang/String;)Ljava/lang/String;" + private const val PUBLICFOLDER_DESCRIPTOR = + "invoke-static {}, $PREF_DESCRIPTOR;->getPublicFolder()Ljava/lang/String;" + + override fun execute(context: BytecodeContext) { + val result = SetDownloadDestinationFingerprint.result + ?: throw PatchException("Could not find fingerprint") + + val method = result.mutableMethod + + val insertAt = method.getInstructions() + .first { it.opcode == Opcode.INVOKE_VIRTUAL }.location.index + + val publicFolderRegister = method.getInstruction(insertAt-1).registerA + method.addInstructions(insertAt, """ + $PUBLICFOLDER_DESCRIPTOR + move-result-object v$publicFolderRegister + + $GETFOLDER_DESCRIPTOR + move-result-object p1 + """.trimIndent()) + + SettingsStatusLoadFingerprint.result!!.mutableMethod.addInstruction( + 0, + "${SettingsPatch.SSTS_DESCRIPTOR}->enableDownloadFolder()V" + ) + } +} \ No newline at end of file diff --git a/src/main/kotlin/indus/org/patches/twitter/crimeraswak/interaction/downloads/changedirectory/fingerprints/SetDownloadDestinationFingerprint.kt b/src/main/kotlin/indus/org/patches/twitter/crimeraswak/interaction/downloads/changedirectory/fingerprints/SetDownloadDestinationFingerprint.kt new file mode 100644 index 0000000..192e414 --- /dev/null +++ b/src/main/kotlin/indus/org/patches/twitter/crimeraswak/interaction/downloads/changedirectory/fingerprints/SetDownloadDestinationFingerprint.kt @@ -0,0 +1,10 @@ +package indus.org.patches.twitter.crimeraswak.interaction.downloads.changedirectory.fingerprints + +import app.revanced.patcher.fingerprint.MethodFingerprint + +object SetDownloadDestinationFingerprint: MethodFingerprint( + returnType = "V", + strings = listOf( + "parse(downloadData.url)" + ) +) diff --git a/src/main/kotlin/indus/org/patches/twitter/crimeraswak/link/cleartrackingparams/ClearTrackingParamsPatch.kt b/src/main/kotlin/indus/org/patches/twitter/crimeraswak/link/cleartrackingparams/ClearTrackingParamsPatch.kt new file mode 100644 index 0000000..7043738 --- /dev/null +++ b/src/main/kotlin/indus/org/patches/twitter/crimeraswak/link/cleartrackingparams/ClearTrackingParamsPatch.kt @@ -0,0 +1,27 @@ +package indus.org.patches.twitter.crimeraswak.link.cleartrackingparams + +import app.revanced.patcher.data.BytecodeContext +import app.revanced.patcher.extensions.InstructionExtensions.addInstruction +import app.revanced.patcher.patch.BytecodePatch +import app.revanced.patcher.patch.PatchException +import app.revanced.patcher.patch.annotation.CompatiblePackage +import app.revanced.patcher.patch.annotation.Patch +import crimera.patches.twitter.link.cleartrackingparams.fingerprints.AddSessionTokenFingerprint + +// https://github.com/FrozenAlex/revanced-patches-new +@Patch( + name = "Clear tracking params", + description = "Removes tracking parameters when sharing links", + compatiblePackages = [CompatiblePackage("com.twitter.android")] +) +@Suppress("unused") +object ClearTrackingParamsPatch: BytecodePatch( + setOf(AddSessionTokenFingerprint) +) { + override fun execute(context: BytecodeContext) { + val result = AddSessionTokenFingerprint.result + ?: throw PatchException("Fingerprint not found") + + result.mutableMethod.addInstruction(0, "return-object p0") + } +} \ No newline at end of file diff --git a/src/main/kotlin/indus/org/patches/twitter/crimeraswak/link/cleartrackingparams/fingerprints/AddSessionTokenFingerprint.kt b/src/main/kotlin/indus/org/patches/twitter/crimeraswak/link/cleartrackingparams/fingerprints/AddSessionTokenFingerprint.kt new file mode 100644 index 0000000..3773b25 --- /dev/null +++ b/src/main/kotlin/indus/org/patches/twitter/crimeraswak/link/cleartrackingparams/fingerprints/AddSessionTokenFingerprint.kt @@ -0,0 +1,12 @@ +package crimera.patches.twitter.link.cleartrackingparams.fingerprints + +import app.revanced.patcher.fingerprint.MethodFingerprint + +// Reference: +object AddSessionTokenFingerprint: MethodFingerprint( + strings = listOf( + "", + "shareParam", + "sessionToken" + ) +) \ No newline at end of file diff --git a/src/main/kotlin/indus/org/patches/twitter/sanitizelinks/SanitizeLinksPatch.kt b/src/main/kotlin/indus/org/patches/twitter/crimeraswak/link/unshorten/NoShortenedUrlPatch.kt similarity index 58% rename from src/main/kotlin/indus/org/patches/twitter/sanitizelinks/SanitizeLinksPatch.kt rename to src/main/kotlin/indus/org/patches/twitter/crimeraswak/link/unshorten/NoShortenedUrlPatch.kt index e50a830..26275b8 100644 --- a/src/main/kotlin/indus/org/patches/twitter/sanitizelinks/SanitizeLinksPatch.kt +++ b/src/main/kotlin/indus/org/patches/twitter/crimeraswak/link/unshorten/NoShortenedUrlPatch.kt @@ -1,34 +1,30 @@ -package indus.org.patches.twitter.sanitizelinks +package indus.org.patches.twitter.crimeraswak.link.unshorten import app.revanced.patcher.data.BytecodeContext -import app.revanced.patcher.extensions.InstructionExtensions.addInstruction import app.revanced.patcher.extensions.InstructionExtensions.addInstructions import app.revanced.patcher.extensions.InstructionExtensions.getInstructions import app.revanced.patcher.patch.BytecodePatch -import app.revanced.patcher.patch.PatchException import app.revanced.patcher.patch.annotation.CompatiblePackage import app.revanced.patcher.patch.annotation.Patch import com.android.tools.smali.dexlib2.Opcode -import indus.org.patches.twitter.sanitizelinks.fingerprints.DexFingerprint +import indus.org.patches.twitter.crimeraswak.link.unshorten.fingerprints.JsonObjectMapperFingerprint -// parts taken from https://github.com/crimera/piko @Patch( - name = "Sanitize URLs", - description = "Remove t.co short links and trackers from shared URL.", - compatiblePackages = [CompatiblePackage("com.twitter.android")], - use = true + name = "No shortened URL", + description = "Get rid of t.co short urls.", + compatiblePackages = [CompatiblePackage("com.twitter.android")] ) @Suppress("unused") -object SanitizeLinksPatch : BytecodePatch( - setOf(DexFingerprint.JsonObjectMapperFingerprint) +object NoShortenedUrlPatch : BytecodePatch( + setOf(JsonObjectMapperFingerprint) ) { private const val METHOD_REFERENCE = - "Lapp/revanced/integrations/twitter/patches/links/SanitizeLinksPatch;->" + + "Lapp/revanced/integrations/twitter/patches/links/UnshortenUrlsPatch;->" + "unshort(Ljava/lang/Object;)V" override fun execute(context: BytecodeContext) { - val result = DexFingerprint.JsonObjectMapperFingerprint.result + val result = JsonObjectMapperFingerprint.result ?: throw Exception("Fingerprint not found") val method = result.mutableMethod @@ -51,12 +47,4 @@ object SanitizeLinksPatch : BytecodePatch( result.mutableMethod.addInstructions(targetIndex2, inject) } - - private fun removeTrackingLinks() { - // removes telemetry ?si= - val result = DexFingerprint.AddSessionTokenFingerprint.result - ?: throw PatchException("Fingerprint not found") - - result.mutableMethod.addInstruction(0, "return-object p0") - } -} \ No newline at end of file +} diff --git a/src/main/kotlin/indus/org/patches/twitter/crimeraswak/link/unshorten/fingerprints/JsonObjectMapperFingerprint.kt b/src/main/kotlin/indus/org/patches/twitter/crimeraswak/link/unshorten/fingerprints/JsonObjectMapperFingerprint.kt new file mode 100644 index 0000000..a3fd520 --- /dev/null +++ b/src/main/kotlin/indus/org/patches/twitter/crimeraswak/link/unshorten/fingerprints/JsonObjectMapperFingerprint.kt @@ -0,0 +1,11 @@ +package indus.org.patches.twitter.crimeraswak.link.unshorten.fingerprints + +import app.revanced.patcher.extensions.or +import app.revanced.patcher.fingerprint.MethodFingerprint +import com.android.tools.smali.dexlib2.AccessFlags + + +internal object JsonObjectMapperFingerprint : MethodFingerprint( + // Lcom/twitter/model/json/core/JsonUrlEntity$$JsonObjectMapper; + customFingerprint = { methodDef, _ -> methodDef.name.contains("parse") && methodDef.definingClass == "Lcom/twitter/model/json/core/JsonUrlEntity\$\$JsonObjectMapper;" } +) diff --git a/src/main/kotlin/indus/org/patches/twitter/adsandpromotions/GoogleAdsPatch.kt b/src/main/kotlin/indus/org/patches/twitter/crimeraswak/misc/FAB/HideFABMenuButtonsPatch.kt similarity index 50% rename from src/main/kotlin/indus/org/patches/twitter/adsandpromotions/GoogleAdsPatch.kt rename to src/main/kotlin/indus/org/patches/twitter/crimeraswak/misc/FAB/HideFABMenuButtonsPatch.kt index eaa434e..e5f1dd4 100644 --- a/src/main/kotlin/indus/org/patches/twitter/adsandpromotions/GoogleAdsPatch.kt +++ b/src/main/kotlin/indus/org/patches/twitter/crimeraswak/misc/FAB/HideFABMenuButtonsPatch.kt @@ -1,36 +1,39 @@ -package indus.org.patches.twitter.adsandpromotions +package indus.org.patches.twitter.crimeraswak.misc.FAB import app.revanced.patcher.data.BytecodeContext -import app.revanced.patcher.extensions.InstructionExtensions.addInstruction +import app.revanced.patcher.extensions.InstructionExtensions.addInstructions +import app.revanced.patcher.extensions.InstructionExtensions.getInstruction import app.revanced.patcher.extensions.InstructionExtensions.getInstructions import app.revanced.patcher.patch.BytecodePatch import app.revanced.patcher.patch.PatchException import app.revanced.patcher.patch.annotation.CompatiblePackage import app.revanced.patcher.patch.annotation.Patch import com.android.tools.smali.dexlib2.Opcode -import indus.org.patches.twitter.adsandpromotions.fingerprints.GAdsFingerprint +import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction +import indus.org.patches.twitter.crimeraswak.misc.FAB.fingerprints.HideFABFingerprint @Patch( - name = "Remove Google Ads", + name = "Hide FAB Menu Buttons", compatiblePackages = [CompatiblePackage("com.twitter.android")], - use = true + use = false ) @Suppress("unused") -object GoogleAdsPatch: BytecodePatch( - setOf(GAdsFingerprint) -) { +class HideFABMenuButtonsPatch : BytecodePatch( + setOf(HideFABFingerprint) +){ override fun execute(context: BytecodeContext) { - val result = GAdsFingerprint.result + val result = HideFABFingerprint.result ?: throw PatchException("Fingerprint not found") val method = result.mutableMethod val instructions = method.getInstructions() + val loc = instructions.last { it.opcode == Opcode.CONST_STRING }.location.index+2 + val reg = method.getInstruction(loc).registerA - val bro = instructions.last { it.opcode == Opcode.INVOKE_VIRTUAL }.location.index + method.addInstructions(loc+1,""" + const v$reg, false + """.trimIndent(), + ) - method.addInstruction(bro, """ - const v0, false - move-object v0, p5 - """.trimIndent()) } } \ No newline at end of file diff --git a/src/main/kotlin/indus/org/patches/twitter/crimeraswak/misc/FAB/HideFABPatch.kt b/src/main/kotlin/indus/org/patches/twitter/crimeraswak/misc/FAB/HideFABPatch.kt new file mode 100644 index 0000000..4e4cd31 --- /dev/null +++ b/src/main/kotlin/indus/org/patches/twitter/crimeraswak/misc/FAB/HideFABPatch.kt @@ -0,0 +1,47 @@ +package crimera.patches.twitter.misc.FAB + +import app.revanced.patcher.data.BytecodeContext +import app.revanced.patcher.extensions.InstructionExtensions.addInstruction +import app.revanced.patcher.extensions.InstructionExtensions.addInstructionsWithLabels +import app.revanced.patcher.extensions.InstructionExtensions.getInstructions +import app.revanced.patcher.patch.BytecodePatch +import app.revanced.patcher.patch.PatchException +import app.revanced.patcher.patch.annotation.CompatiblePackage +import app.revanced.patcher.patch.annotation.Patch +import app.revanced.patcher.util.smali.ExternalLabel +import com.android.tools.smali.dexlib2.Opcode +import indus.org.patches.twitter.crimeraswak.misc.FAB.fingerprints.HideFABFingerprint +import indus.org.patches.twitter.crimeraswak.misc.settings.SettingsPatch +import indus.org.patches.twitter.crimeraswak.misc.settings.fingerprints.SettingsStatusLoadFingerprint + +@Patch( + name = "Hide FAB", + compatiblePackages = [CompatiblePackage("com.twitter.android")] , + use = false +) +@Suppress("unused") +class HideFABPatch :BytecodePatch( + setOf(HideFABFingerprint) +){ + override fun execute(context: BytecodeContext) { + val result = HideFABFingerprint.result + ?: throw PatchException("Fingerprint not found") + + val method = result.mutableMethod + val instructions = method.getInstructions() + val constObj = instructions.last { it.opcode == Opcode.CONST_4 } + + method.addInstructionsWithLabels(0,""" + invoke-static {}, ${SettingsPatch.PREF_DESCRIPTOR};->hideFAB()Z + move-result v0 + if-nez v0, :cond_1212 + """.trimIndent(), + ExternalLabel("cond_1212",constObj) + ) + + SettingsStatusLoadFingerprint.result!!.mutableMethod.addInstruction( + 0, + "${SettingsPatch.SSTS_DESCRIPTOR}->hideFAB()V" + ) + } +} \ No newline at end of file diff --git a/src/main/kotlin/indus/org/patches/twitter/crimeraswak/misc/FAB/fingerprints/HideFABFingerprint.kt b/src/main/kotlin/indus/org/patches/twitter/crimeraswak/misc/FAB/fingerprints/HideFABFingerprint.kt new file mode 100644 index 0000000..34319ea --- /dev/null +++ b/src/main/kotlin/indus/org/patches/twitter/crimeraswak/misc/FAB/fingerprints/HideFABFingerprint.kt @@ -0,0 +1,9 @@ +package indus.org.patches.twitter.crimeraswak.misc.FAB.fingerprints + +import app.revanced.patcher.fingerprint.MethodFingerprint + +object HideFABFingerprint: MethodFingerprint( + strings = listOf( + "android_compose_fab_menu_enabled" + ) +) \ No newline at end of file diff --git a/src/main/kotlin/indus/org/patches/twitter/crimeraswak/misc/disablechirpfont/DisableChirpFontPatch.kt b/src/main/kotlin/indus/org/patches/twitter/crimeraswak/misc/disablechirpfont/DisableChirpFontPatch.kt new file mode 100644 index 0000000..9ac0184 --- /dev/null +++ b/src/main/kotlin/indus/org/patches/twitter/crimeraswak/misc/disablechirpfont/DisableChirpFontPatch.kt @@ -0,0 +1,41 @@ +package indus.org.patches.twitter.crimeraswak.misc.disablechirpfont + +import app.revanced.patcher.data.BytecodeContext +import app.revanced.patcher.extensions.InstructionExtensions.addInstruction +import app.revanced.patcher.extensions.InstructionExtensions.addInstructions +import app.revanced.patcher.patch.BytecodePatch +import app.revanced.patcher.patch.annotation.CompatiblePackage +import app.revanced.patcher.patch.annotation.Patch +import indus.org.patches.twitter.crimeraswak.misc.disablechirpfont.fingerprints.ChirpFontFingerprint +import indus.org.patches.twitter.crimeraswak.misc.settings.SettingsPatch +import indus.org.patches.twitter.crimeraswak.misc.settings.fingerprints.SettingsStatusLoadFingerprint + +@Patch( + name = "Disable chirp font", + use = false, + dependencies = [SettingsPatch::class], + compatiblePackages = [CompatiblePackage("com.twitter.android")] +) +@Suppress("unused") +object DisableChirpFontPatch: BytecodePatch( + setOf(ChirpFontFingerprint) +) { + private const val CHIRP_FONT_DESCRIPTOR = + "invoke-static {}, ${SettingsPatch.PREF_DESCRIPTOR};->isChirpFontEnabled()Z" + + override fun execute(context: BytecodeContext) { + ChirpFontFingerprint.result!!.mutableMethod.addInstructions( + 0, + """ + $CHIRP_FONT_DESCRIPTOR + move-result v0 + return v0 + """ + ) + + SettingsStatusLoadFingerprint.result!!.mutableMethod.addInstruction( + 0, + "${SettingsPatch.SSTS_DESCRIPTOR}->enableFont()V" + ) + } +} \ No newline at end of file diff --git a/src/main/kotlin/indus/org/patches/twitter/layout/disablechirpfont/ChirpFontFingerprint.kt b/src/main/kotlin/indus/org/patches/twitter/crimeraswak/misc/disablechirpfont/fingerprints/ChirpFontFingerprint.kt similarity index 65% rename from src/main/kotlin/indus/org/patches/twitter/layout/disablechirpfont/ChirpFontFingerprint.kt rename to src/main/kotlin/indus/org/patches/twitter/crimeraswak/misc/disablechirpfont/fingerprints/ChirpFontFingerprint.kt index 9af7b61..007a56c 100644 --- a/src/main/kotlin/indus/org/patches/twitter/layout/disablechirpfont/ChirpFontFingerprint.kt +++ b/src/main/kotlin/indus/org/patches/twitter/crimeraswak/misc/disablechirpfont/fingerprints/ChirpFontFingerprint.kt @@ -1,4 +1,4 @@ -package indus.org.patches.twitter.layout.disablechirpfont +package indus.org.patches.twitter.crimeraswak.misc.disablechirpfont.fingerprints import app.revanced.patcher.fingerprint.MethodFingerprint diff --git a/src/main/kotlin/indus/org/patches/twitter/crimeraswak/misc/hidecommunitynotes/HideCommunityNotePatch.kt b/src/main/kotlin/indus/org/patches/twitter/crimeraswak/misc/hidecommunitynotes/HideCommunityNotePatch.kt new file mode 100644 index 0000000..0975203 --- /dev/null +++ b/src/main/kotlin/indus/org/patches/twitter/crimeraswak/misc/hidecommunitynotes/HideCommunityNotePatch.kt @@ -0,0 +1,53 @@ +package indus.org.patches.twitter.crimeraswak.misc.hidecommunitynotes + +import app.revanced.patcher.data.BytecodeContext +import app.revanced.patcher.extensions.InstructionExtensions.addInstruction +import app.revanced.patcher.extensions.InstructionExtensions.addInstructionsWithLabels +import app.revanced.patcher.extensions.InstructionExtensions.getInstructions +import app.revanced.patcher.patch.BytecodePatch +import app.revanced.patcher.patch.PatchException +import app.revanced.patcher.patch.annotation.CompatiblePackage +import app.revanced.patcher.patch.annotation.Patch +import app.revanced.patcher.util.smali.ExternalLabel +import com.android.tools.smali.dexlib2.Opcode +import indus.org.patches.twitter.crimeraswak.misc.hidecommunitynotes.fingerprints.HideCommunityNoteFingerprint +import indus.org.patches.twitter.crimeraswak.misc.settings.SettingsPatch +import indus.org.patches.twitter.crimeraswak.misc.settings.fingerprints.SettingsStatusLoadFingerprint + +@Patch( + name = "Hide Community Notes", + compatiblePackages = [CompatiblePackage("com.twitter.android")] , + dependencies = [SettingsPatch::class], + use = false +) +object HideCommunityNotePatch :BytecodePatch( + setOf(HideCommunityNoteFingerprint) +){ + override fun execute(context: BytecodeContext) { + val result = HideCommunityNoteFingerprint.result + ?: throw PatchException("HideCommunityNoteFingerprint not Found") + + val methods = result.mutableMethod + val instructions = methods.getInstructions() + + val loc = instructions.last { it.opcode == Opcode.IPUT_OBJECT }.location.index + + val HOOK_DESCRIPTOR = + "invoke-static {}, ${SettingsPatch.PREF_DESCRIPTOR};->hideCommNotes()Z" + + methods.addInstructionsWithLabels(loc,""" + $HOOK_DESCRIPTOR + move-result v0 + if-nez v0, :end + """.trimIndent(), + ExternalLabel("end",instructions.last { it.opcode == Opcode.RETURN_VOID }) + ) + + SettingsStatusLoadFingerprint.result!!.mutableMethod.addInstruction( + 0, + "${SettingsPatch.SSTS_DESCRIPTOR}->hideCommunityNotes()V" + ) + + //end + } +} \ No newline at end of file diff --git a/src/main/kotlin/indus/org/patches/twitter/crimeraswak/misc/hidecommunitynotes/fingerprints/HideCommunityNoteFingerprint.kt b/src/main/kotlin/indus/org/patches/twitter/crimeraswak/misc/hidecommunitynotes/fingerprints/HideCommunityNoteFingerprint.kt new file mode 100644 index 0000000..ae66d2e --- /dev/null +++ b/src/main/kotlin/indus/org/patches/twitter/crimeraswak/misc/hidecommunitynotes/fingerprints/HideCommunityNoteFingerprint.kt @@ -0,0 +1,16 @@ +package indus.org.patches.twitter.crimeraswak.misc.hidecommunitynotes.fingerprints + +import app.revanced.patcher.fingerprint.MethodFingerprint + +object HideCommunityNoteFingerprint : MethodFingerprint( + returnType = "V", + strings = listOf( + "article", + "ext_birdwatch_pivot", + "birdwatch_pivot", + ), + customFingerprint = {it,_ -> + it.definingClass =="Lcom/twitter/api/model/json/core/JsonApiTweet\$\$JsonObjectMapper;" + } + +) \ No newline at end of file diff --git a/src/main/kotlin/indus/org/patches/twitter/crimeraswak/misc/integrations/IntegrationsPatch.kt b/src/main/kotlin/indus/org/patches/twitter/crimeraswak/misc/integrations/IntegrationsPatch.kt new file mode 100644 index 0000000..7213470 --- /dev/null +++ b/src/main/kotlin/indus/org/patches/twitter/crimeraswak/misc/integrations/IntegrationsPatch.kt @@ -0,0 +1,12 @@ +package indus.org.patches.twitter.crimeraswak.misc.integrations + +import app.revanced.patcher.patch.annotation.Patch +import indus.org.patches.twitter.crimeraswak.integrations.BaseIntegrationsPatch +import indus.org.patches.twitter.crimeraswak.misc.integrations.fingerprints.InitFingerprint + +@Patch( + requiresIntegrations = true +) +object IntegrationsPatch: BaseIntegrationsPatch( + setOf(InitFingerprint) +) \ No newline at end of file diff --git a/src/main/kotlin/indus/org/patches/twitter/crimeraswak/misc/integrations/fingerprints/InitFingerprint.kt b/src/main/kotlin/indus/org/patches/twitter/crimeraswak/misc/integrations/fingerprints/InitFingerprint.kt new file mode 100644 index 0000000..94cdc19 --- /dev/null +++ b/src/main/kotlin/indus/org/patches/twitter/crimeraswak/misc/integrations/fingerprints/InitFingerprint.kt @@ -0,0 +1,10 @@ +package indus.org.patches.twitter.crimeraswak.misc.integrations.fingerprints + +import indus.org.patches.twitter.crimeraswak.integrations.BaseIntegrationsPatch + +internal object InitFingerprint : BaseIntegrationsPatch.IntegrationsFingerprint( + strings = listOf("builderClass"), + customFingerprint = { methodDef, _ -> + methodDef.name == "onCreate" + } +) \ No newline at end of file diff --git a/src/main/kotlin/indus/org/patches/twitter/crimeraswak/misc/recommendedusers/HideRecommendedUsersPatch.kt b/src/main/kotlin/indus/org/patches/twitter/crimeraswak/misc/recommendedusers/HideRecommendedUsersPatch.kt new file mode 100644 index 0000000..8186ec3 --- /dev/null +++ b/src/main/kotlin/indus/org/patches/twitter/crimeraswak/misc/recommendedusers/HideRecommendedUsersPatch.kt @@ -0,0 +1,51 @@ +package indus.org.patches.twitter.crimeraswak.misc.recommendedusers + +import app.revanced.patcher.data.BytecodeContext +import app.revanced.patcher.extensions.InstructionExtensions.addInstruction +import app.revanced.patcher.extensions.InstructionExtensions.addInstructions +import app.revanced.patcher.extensions.InstructionExtensions.getInstruction +import app.revanced.patcher.extensions.InstructionExtensions.getInstructions +import app.revanced.patcher.patch.BytecodePatch +import app.revanced.patcher.patch.PatchException +import app.revanced.patcher.patch.annotation.CompatiblePackage +import app.revanced.patcher.patch.annotation.Patch +import com.android.tools.smali.dexlib2.Opcode +import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction +import indus.org.patches.twitter.crimeraswak.misc.settings.SettingsPatch +import indus.org.patches.twitter.crimeraswak.misc.settings.fingerprints.SettingsStatusLoadFingerprint +import indus.org.patches.twitter.crimeraswak.misc.recommendedusers.fingerprints.HideRecommendedUsersFingerprint + + +@Patch( + name = "Hide Recommended Users", + description = "Hide recommended users that pops up when you follow someone", + compatiblePackages = [CompatiblePackage("com.twitter.android")] +) +@Suppress("unused") +object HideRecommendedUsers: BytecodePatch( + setOf(HideRecommendedUsersFingerprint) +) { + override fun execute(context: BytecodeContext) { + val result = HideRecommendedUsersFingerprint.result + ?: throw PatchException("Fingerprint not found") + + val method = result.mutableMethod + val instructions = method.getInstructions() + + val check = instructions.last { it.opcode == Opcode.IGET_OBJECT }.location.index + val reg = method.getInstruction(check).registerA + + val HIDE_RECOMMENDED_USERS_DESCRIPTOR = + "invoke-static {v$reg}, ${SettingsPatch.PREF_DESCRIPTOR};->hideRecommendedUsers(Ljava/util/ArrayList;)Ljava/util/ArrayList;" + + method.addInstructions(check+1, """ + $HIDE_RECOMMENDED_USERS_DESCRIPTOR + move-result-object v$reg + """.trimIndent()) + + SettingsStatusLoadFingerprint.result!!.mutableMethod.addInstruction( + 0, + "${SettingsPatch.SSTS_DESCRIPTOR}->hideRecommendedUsers()V" + ) + } +} \ No newline at end of file diff --git a/src/main/kotlin/indus/org/patches/twitter/crimeraswak/misc/recommendedusers/fingerprints/HideRecommendedUsersFingerprint.kt b/src/main/kotlin/indus/org/patches/twitter/crimeraswak/misc/recommendedusers/fingerprints/HideRecommendedUsersFingerprint.kt new file mode 100644 index 0000000..a381423 --- /dev/null +++ b/src/main/kotlin/indus/org/patches/twitter/crimeraswak/misc/recommendedusers/fingerprints/HideRecommendedUsersFingerprint.kt @@ -0,0 +1,14 @@ +package indus.org.patches.twitter.crimeraswak.misc.recommendedusers.fingerprints + +import app.revanced.patcher.fingerprint.MethodFingerprint +import com.android.tools.smali.dexlib2.Opcode + +object HideRecommendedUsersFingerprint: MethodFingerprint( + opcodes = listOf( + Opcode.IGET_OBJECT, + ), + + customFingerprint = { it, _ -> + it.definingClass == "Lcom/twitter/model/json/people/JsonProfileRecommendationModuleResponse;" + } +) \ No newline at end of file diff --git a/src/main/kotlin/indus/org/patches/twitter/layout/selectableText/SelectableTextPatch.kt b/src/main/kotlin/indus/org/patches/twitter/crimeraswak/misc/selectabletext/SelectableTextPatch.kt similarity index 87% rename from src/main/kotlin/indus/org/patches/twitter/layout/selectableText/SelectableTextPatch.kt rename to src/main/kotlin/indus/org/patches/twitter/crimeraswak/misc/selectabletext/SelectableTextPatch.kt index b1dcba3..9945193 100644 --- a/src/main/kotlin/indus/org/patches/twitter/layout/selectableText/SelectableTextPatch.kt +++ b/src/main/kotlin/indus/org/patches/twitter/crimeraswak/misc/selectabletext/SelectableTextPatch.kt @@ -1,4 +1,4 @@ -package indus.org.patches.twitter.layout.selectableText +package indus.org.patches.twitter.crimeraswak.misc.selectabletext import app.revanced.patcher.data.ResourceContext import app.revanced.patcher.patch.PatchException @@ -7,11 +7,10 @@ import app.revanced.patcher.patch.annotation.CompatiblePackage import app.revanced.patcher.patch.annotation.Patch import org.w3c.dom.Element -// credits to https://github.com/crimera/piko @Patch( - name = "Make bio and username text selectable", - compatiblePackages = [CompatiblePackage("com.twitter.android")], - use = true + name = "Selectable Text", + description = "Makes bio and username selectable", + compatiblePackages = [CompatiblePackage("com.twitter.android")] ) @Suppress("unused") object SelectableTextPatch: ResourcePatch() { diff --git a/src/main/kotlin/indus/org/patches/twitter/crimeraswak/misc/sensitivemediasettings/ShowSensitiveMediaPatch.kt b/src/main/kotlin/indus/org/patches/twitter/crimeraswak/misc/sensitivemediasettings/ShowSensitiveMediaPatch.kt new file mode 100644 index 0000000..4520012 --- /dev/null +++ b/src/main/kotlin/indus/org/patches/twitter/crimeraswak/misc/sensitivemediasettings/ShowSensitiveMediaPatch.kt @@ -0,0 +1,34 @@ +package indus.org.patches.twitter.crimeraswak.misc.sensitivemediasettings + +import app.revanced.patcher.data.BytecodeContext +import app.revanced.patcher.extensions.InstructionExtensions.getInstructions +import app.revanced.patcher.extensions.InstructionExtensions.removeInstruction +import app.revanced.patcher.patch.BytecodePatch +import app.revanced.patcher.patch.PatchException +import app.revanced.patcher.patch.annotation.CompatiblePackage +import app.revanced.patcher.patch.annotation.Patch +import com.android.tools.smali.dexlib2.Opcode +import indus.org.patches.twitter.crimeraswak.misc.sensitivemediasettings.fingerprints.SensitiveMediaSettingsPatchFingerprint + +// Credits to @Cradlesofashes +@Patch( + name = "Show sensitive media", + description = "Shows sensitive media", + compatiblePackages = [CompatiblePackage("com.twitter.android")] +) +@Suppress("unused") +object SensitiveMediaPatch: BytecodePatch( + setOf(SensitiveMediaSettingsPatchFingerprint) +) { + override fun execute(context: BytecodeContext) { + val result = SensitiveMediaSettingsPatchFingerprint.result + ?: throw PatchException("Fingerprint not found") + + val method = result.mutableMethod + val instructions = method.getInstructions() + + instructions.filter{ it.opcode == Opcode.IPUT_BOOLEAN }.forEach { + method.removeInstruction(it.location.index) + } + } +} \ No newline at end of file diff --git a/src/main/kotlin/indus/org/patches/twitter/crimeraswak/misc/sensitivemediasettings/fingerprints/ShowSensitiveMediaPatchFingerprint.kt b/src/main/kotlin/indus/org/patches/twitter/crimeraswak/misc/sensitivemediasettings/fingerprints/ShowSensitiveMediaPatchFingerprint.kt new file mode 100644 index 0000000..bbdca3c --- /dev/null +++ b/src/main/kotlin/indus/org/patches/twitter/crimeraswak/misc/sensitivemediasettings/fingerprints/ShowSensitiveMediaPatchFingerprint.kt @@ -0,0 +1,19 @@ +package indus.org.patches.twitter.crimeraswak.misc.sensitivemediasettings.fingerprints + +import app.revanced.patcher.fingerprint.MethodFingerprint +import com.android.tools.smali.dexlib2.Opcode + +object SensitiveMediaSettingsPatchFingerprint: MethodFingerprint( + returnType = "V", + strings = listOf( + "adult_content", + "graphic_violence", + "other" + ), + opcodes = listOf( + Opcode.IPUT_BOOLEAN, + ), + customFingerprint = { it, _ -> + it.definingClass == "Lcom/twitter/model/json/core/JsonSensitiveMediaWarning\$\$JsonObjectMapper;" + } +) \ No newline at end of file diff --git a/src/main/kotlin/indus/org/patches/twitter/crimeraswak/misc/settings/SettingsPatch.kt b/src/main/kotlin/indus/org/patches/twitter/crimeraswak/misc/settings/SettingsPatch.kt new file mode 100644 index 0000000..9562942 --- /dev/null +++ b/src/main/kotlin/indus/org/patches/twitter/crimeraswak/misc/settings/SettingsPatch.kt @@ -0,0 +1,73 @@ +package indus.org.patches.twitter.crimeraswak.misc.settings + +import app.revanced.patcher.data.BytecodeContext +import app.revanced.patcher.extensions.InstructionExtensions.addInstructions +import app.revanced.patcher.extensions.InstructionExtensions.addInstructionsWithLabels +import app.revanced.patcher.extensions.InstructionExtensions.getInstruction +import app.revanced.patcher.extensions.InstructionExtensions.getInstructions +import app.revanced.patcher.patch.BytecodePatch +import app.revanced.patcher.patch.PatchException +import app.revanced.patcher.patch.annotation.CompatiblePackage +import app.revanced.patcher.patch.annotation.Patch +import app.revanced.patcher.util.smali.ExternalLabel +import com.android.tools.smali.dexlib2.Opcode +import com.android.tools.smali.dexlib2.builder.instruction.BuilderInstruction11x +import indus.org.patches.twitter.crimeraswak.misc.integrations.IntegrationsPatch +import indus.org.patches.twitter.crimeraswak.misc.settings.fingerprints.SettingsFingerprint + +@Patch( + description = "Adds settings", + requiresIntegrations = true, + dependencies = [SettingsResourcePatch::class, IntegrationsPatch::class], + compatiblePackages = [CompatiblePackage("com.twitter.android")], +) +@Suppress("unused") +object SettingsPatch : BytecodePatch( + setOf(SettingsFingerprint) +) { + private const val INTEGRATIONS_PACKAGE = "Lapp/revanced/integrations/twitter" + const val UTILS_DESCRIPTOR = "$INTEGRATIONS_PACKAGE/Utils" + const val PREF_DESCRIPTOR = "$INTEGRATIONS_PACKAGE/Pref" + const val PATCHES_DESCRIPTOR = "$INTEGRATIONS_PACKAGE/patches" + private const val ADD_PREF_DESCRIPTOR = "$UTILS_DESCRIPTOR;->addPref([Ljava/lang/String;Ljava/lang/String;)[Ljava/lang/String;" + const val SSTS_DESCRIPTOR = "invoke-static {}, $INTEGRATIONS_PACKAGE/settings/SettingsStatus;" + private const val START_ACTIVITY_DESCRIPTOR = + "invoke-static {}, $UTILS_DESCRIPTOR;->startSettingsActivity()V" + + override fun execute(context: BytecodeContext) { + val result = SettingsFingerprint.result + ?: throw PatchException("Fingerprint not found") + + val initMethod = result.mutableClass.methods.first() + + val arrayCreation = initMethod.getInstructions() + .first { it.opcode == Opcode.FILLED_NEW_ARRAY_RANGE }.location.index+1 + + initMethod.getInstruction(arrayCreation).registerA.also { reg-> + initMethod.addInstructions(arrayCreation+1, """ + const-string v1, "pref_mod" + invoke-static {v$reg, v1}, $ADD_PREF_DESCRIPTOR + move-result-object v$reg + """) + } + + val prefCLickedMethod = result.mutableClass.methods.find { it.returnType == "Z" }!! + val constIndex = prefCLickedMethod.getInstructions().first{ it.opcode == Opcode.CONST_4 }.location.index + + prefCLickedMethod.addInstructionsWithLabels(1, """ + const-string v1, "pref_mod" + invoke-virtual {p1, v1}, Ljava/lang/String;->equals(Ljava/lang/Object;)Z + move-result v2 + + if-nez v2, :start + goto :cont + + :start + $START_ACTIVITY_DESCRIPTOR + const/4 v3, 0x1 + return v3 + """, + ExternalLabel("cont", prefCLickedMethod.getInstruction(constIndex)) + ) + } +} \ No newline at end of file diff --git a/src/main/kotlin/indus/org/patches/twitter/crimeraswak/misc/settings/SettingsResourcePatch.kt b/src/main/kotlin/indus/org/patches/twitter/crimeraswak/misc/settings/SettingsResourcePatch.kt new file mode 100644 index 0000000..5ed97e0 --- /dev/null +++ b/src/main/kotlin/indus/org/patches/twitter/crimeraswak/misc/settings/SettingsResourcePatch.kt @@ -0,0 +1,43 @@ +package indus.org.patches.twitter.crimeraswak.misc.settings + +import app.revanced.patcher.data.ResourceContext +import app.revanced.patcher.patch.PatchException +import app.revanced.patcher.patch.ResourcePatch +import app.revanced.patcher.patch.annotation.CompatiblePackage +import app.revanced.patcher.patch.annotation.Patch +import org.w3c.dom.Element + +@Patch( + compatiblePackages = [CompatiblePackage("com.twitter.android")], +) +@Suppress("unused") +object SettingsResourcePatch: ResourcePatch() { + override fun execute(context: ResourceContext) { + val settingsRoot = context["res/xml/settings_root.xml"] + if (!settingsRoot.exists()) throw PatchException("settings_root not found") + + context.xmlEditor["res/xml/settings_root.xml"].use { editor -> + val parent = editor.file.getElementsByTagName("PreferenceScreen").item(0) as Element + + val prefMod = editor.file.createElement("Preference") + prefMod.setAttribute("android:icon", "@drawable/ic_vector_settings_stroke") + prefMod.setAttribute("android:title", "Mod Settings") + prefMod.setAttribute("android:key", "pref_mod") + prefMod.setAttribute("android:order", "110") + + parent.appendChild(prefMod) + } + + context.xmlEditor["AndroidManifest.xml"].use { + val applicationNode = it.file.getElementsByTagName("application").item(0) + + val modActivity = it.file.createElement("activity").apply { + setAttribute("android:label", "Mod Settings") + setAttribute("android:name", "app.revanced.integrations.twitter.settings.SettingsActivity") + setAttribute("android:excludeFromRecents", "true") + } + + applicationNode.appendChild(modActivity) + } + } +} \ No newline at end of file diff --git a/src/main/kotlin/indus/org/patches/twitter/crimeraswak/misc/settings/fingerprints/SettingsFingerprint.kt b/src/main/kotlin/indus/org/patches/twitter/crimeraswak/misc/settings/fingerprints/SettingsFingerprint.kt new file mode 100644 index 0000000..cf64d94 --- /dev/null +++ b/src/main/kotlin/indus/org/patches/twitter/crimeraswak/misc/settings/fingerprints/SettingsFingerprint.kt @@ -0,0 +1,13 @@ +package indus.org.patches.twitter.crimeraswak.misc.settings.fingerprints + +import app.revanced.patcher.fingerprint.MethodFingerprint + +object SettingsFingerprint: MethodFingerprint( + returnType = "V", + strings = listOf( + "pref_proxy" + ), + customFingerprint = { it, _ -> + it.name == "" + } +) diff --git a/src/main/kotlin/indus/org/patches/twitter/crimeraswak/misc/settings/fingerprints/SettingsStatusLoadFingerprint.kt b/src/main/kotlin/indus/org/patches/twitter/crimeraswak/misc/settings/fingerprints/SettingsStatusLoadFingerprint.kt new file mode 100644 index 0000000..c2d136d --- /dev/null +++ b/src/main/kotlin/indus/org/patches/twitter/crimeraswak/misc/settings/fingerprints/SettingsStatusLoadFingerprint.kt @@ -0,0 +1,10 @@ +package indus.org.patches.twitter.crimeraswak.misc.settings.fingerprints + +import app.revanced.patcher.fingerprint.MethodFingerprint + +object SettingsStatusLoadFingerprint: MethodFingerprint( + customFingerprint = { methodDef, _ -> + methodDef.definingClass.endsWith("Lapp/revanced/integrations/twitter/settings/SettingsStatus;") && + methodDef.name == "load" + } +) \ No newline at end of file diff --git a/src/main/kotlin/indus/org/patches/twitter/crimeraswak/misc/viewcount/RemoveViewCountPatch.kt b/src/main/kotlin/indus/org/patches/twitter/crimeraswak/misc/viewcount/RemoveViewCountPatch.kt new file mode 100644 index 0000000..7dec5de --- /dev/null +++ b/src/main/kotlin/indus/org/patches/twitter/crimeraswak/misc/viewcount/RemoveViewCountPatch.kt @@ -0,0 +1,43 @@ +package indus.org.patches.twitter.crimeraswak.misc.viewcount + +import app.revanced.patcher.data.BytecodeContext +import app.revanced.patcher.extensions.InstructionExtensions.addInstruction +import app.revanced.patcher.extensions.InstructionExtensions.addInstructions +import app.revanced.patcher.patch.BytecodePatch +import app.revanced.patcher.patch.PatchException +import app.revanced.patcher.patch.annotation.CompatiblePackage +import app.revanced.patcher.patch.annotation.Patch +import indus.org.patches.twitter.crimeraswak.misc.settings.SettingsPatch +import indus.org.patches.twitter.crimeraswak.misc.settings.fingerprints.SettingsStatusLoadFingerprint +import indus.org.patches.twitter.crimeraswak.misc.viewcount.fingerprints.RemoveViewCountPatchFingerprint + +// Credits to @iKirby +@Patch( + name = "Remove view count", + description = "Removes the view count from the bottom of tweets", + compatiblePackages = [CompatiblePackage("com.twitter.android")], + use = false +) +@Suppress("unused") +object RemoveViewCountPatch: BytecodePatch( + setOf(RemoveViewCountPatchFingerprint) +) { + override fun execute(context: BytecodeContext) { + val result = RemoveViewCountPatchFingerprint.result + ?: throw PatchException("Fingerprint not found") + + val method = result.mutableMethod + + method.addInstructions(0, """ + invoke-static {}, ${SettingsPatch.PREF_DESCRIPTOR};->hideViewCount()Z + move-result v0 + return v0 + """.trimIndent()) + + SettingsStatusLoadFingerprint.result!!.mutableMethod.addInstruction( + 0, + "${SettingsPatch.SSTS_DESCRIPTOR}->hideViewCount()V" + ) + } + +} \ No newline at end of file diff --git a/src/main/kotlin/indus/org/patches/twitter/crimeraswak/misc/viewcount/fingerprints/RemoveViewCountPatchFingerprint.kt b/src/main/kotlin/indus/org/patches/twitter/crimeraswak/misc/viewcount/fingerprints/RemoveViewCountPatchFingerprint.kt new file mode 100644 index 0000000..3ac4e8a --- /dev/null +++ b/src/main/kotlin/indus/org/patches/twitter/crimeraswak/misc/viewcount/fingerprints/RemoveViewCountPatchFingerprint.kt @@ -0,0 +1,10 @@ +package indus.org.patches.twitter.crimeraswak.misc.viewcount.fingerprints + +import app.revanced.patcher.fingerprint.MethodFingerprint + +object RemoveViewCountPatchFingerprint: MethodFingerprint ( + returnType = "Z", + strings = listOf( + "view_counts_public_visibility_enabled", + ) +) \ No newline at end of file diff --git a/src/main/kotlin/indus/org/patches/twitter/crimeraswak/premium/readermode/EnableReaderModePatch.kt b/src/main/kotlin/indus/org/patches/twitter/crimeraswak/premium/readermode/EnableReaderModePatch.kt new file mode 100644 index 0000000..3db6554 --- /dev/null +++ b/src/main/kotlin/indus/org/patches/twitter/crimeraswak/premium/readermode/EnableReaderModePatch.kt @@ -0,0 +1,67 @@ +package indus.org.patches.twitter.crimeraswak.premium.readermode + +import app.revanced.patcher.data.BytecodeContext +import app.revanced.patcher.extensions.InstructionExtensions.getInstructions +import app.revanced.patcher.extensions.InstructionExtensions.removeInstruction +import app.revanced.patcher.patch.BytecodePatch +import app.revanced.patcher.patch.PatchException +import app.revanced.patcher.patch.annotation.CompatiblePackage +import app.revanced.patcher.patch.annotation.Patch +import com.android.tools.smali.dexlib2.Opcode +import indus.org.patches.twitter.crimeraswak.premium.readermode.fingerprints.EnableReaderMode1Fingerprint +import indus.org.patches.twitter.crimeraswak.premium.readermode.fingerprints.EnableReaderMode2Fingerprint + +@Patch( + name = "Enable Reader Mode", + description = "Enables reader mode on long threads", + compatiblePackages = [CompatiblePackage("com.twitter.android")], + use = false +) +@Suppress("unused") +object EnableReaderModePatch:BytecodePatch( + setOf(EnableReaderMode1Fingerprint, EnableReaderMode2Fingerprint) +){ + override fun execute(context: BytecodeContext) { + val result1 = EnableReaderMode1Fingerprint.result + ?: throw PatchException("EnableReaderMode1Fingerprint not found") + + //find location of the flag + var strLoc: Int = 0 + result1.scanResult.stringsScanResult!!.matches.forEach{ match -> + val str = match.string + if(str.equals("subscriptions_feature_1005")){ + strLoc = match.index + return@forEach + } + } + + if(strLoc==0){ + throw PatchException("hook not found") + } + //remove the flag check + val methods = result1.mutableMethod + val instructions = methods.getInstructions() + val filters = instructions.filter { it.opcode == Opcode.IF_EQZ } + for(item in filters){ + val loc = item.location.index + if(loc > strLoc){ + methods.removeInstruction(loc) + break + } + } + + + val result2 = EnableReaderMode2Fingerprint.result + ?: throw PatchException("EnableReaderMode2Fingerprint not found") + + //remove the flag check + val methods2 = result2.mutableMethod + val loc = methods2.getInstructions().first{it.opcode == Opcode.IF_EQZ}.location.index + methods2.removeInstruction(loc) + + + //end + } + + +} \ No newline at end of file diff --git a/src/main/kotlin/indus/org/patches/twitter/crimeraswak/premium/readermode/fingerprints/EnableReaderMode1Fingerprint.kt b/src/main/kotlin/indus/org/patches/twitter/crimeraswak/premium/readermode/fingerprints/EnableReaderMode1Fingerprint.kt new file mode 100644 index 0000000..81c01ea --- /dev/null +++ b/src/main/kotlin/indus/org/patches/twitter/crimeraswak/premium/readermode/fingerprints/EnableReaderMode1Fingerprint.kt @@ -0,0 +1,11 @@ +package indus.org.patches.twitter.crimeraswak.premium.readermode.fingerprints + +import app.revanced.patcher.fingerprint.MethodFingerprint + +object EnableReaderMode1Fingerprint: MethodFingerprint( + returnType = "V", + strings = listOf( + "android_audio_protected_account_creation_enabled", + "subscriptions_feature_1005" + ) +) \ No newline at end of file diff --git a/src/main/kotlin/indus/org/patches/twitter/crimeraswak/premium/readermode/fingerprints/EnableReaderMode2Fingerprint.kt b/src/main/kotlin/indus/org/patches/twitter/crimeraswak/premium/readermode/fingerprints/EnableReaderMode2Fingerprint.kt new file mode 100644 index 0000000..689e7f9 --- /dev/null +++ b/src/main/kotlin/indus/org/patches/twitter/crimeraswak/premium/readermode/fingerprints/EnableReaderMode2Fingerprint.kt @@ -0,0 +1,12 @@ +package indus.org.patches.twitter.crimeraswak.premium.readermode.fingerprints + +import app.revanced.patcher.fingerprint.MethodFingerprint + +object EnableReaderMode2Fingerprint: MethodFingerprint( + returnType = "Ljava/lang/Object;", + strings = listOf( + "id", + "subscriptions_feature_1005", + "extra_tweet_id" + ) +) \ No newline at end of file diff --git a/src/main/kotlin/indus/org/patches/twitter/crimeraswak/premium/undoposts/EnableUndoPostPatch.kt b/src/main/kotlin/indus/org/patches/twitter/crimeraswak/premium/undoposts/EnableUndoPostPatch.kt new file mode 100644 index 0000000..cac8700 --- /dev/null +++ b/src/main/kotlin/indus/org/patches/twitter/crimeraswak/premium/undoposts/EnableUndoPostPatch.kt @@ -0,0 +1,69 @@ +package crimera.patches.twitter.premium.undoposts + +import app.revanced.patcher.data.BytecodeContext +import app.revanced.patcher.extensions.InstructionExtensions.addInstructions +import app.revanced.patcher.extensions.InstructionExtensions.getInstruction +import app.revanced.patcher.extensions.InstructionExtensions.getInstructions +import app.revanced.patcher.extensions.InstructionExtensions.removeInstruction +import app.revanced.patcher.extensions.InstructionExtensions.removeInstructions +import app.revanced.patcher.patch.BytecodePatch +import app.revanced.patcher.patch.PatchException +import app.revanced.patcher.patch.annotation.CompatiblePackage +import app.revanced.patcher.patch.annotation.Patch +import com.android.tools.smali.dexlib2.Opcode +import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction +import crimera.patches.twitter.premium.undoposts.fingerprints.UndoPost1Fingerprint +import crimera.patches.twitter.premium.undoposts.fingerprints.UndoPost2Fingerprint +import crimera.patches.twitter.premium.undoposts.fingerprints.UndoPost3Fingerprint + +@Patch( + name = "Enable Undo Posts", + description = "Enable ability to undo posts before it gets posted", + compatiblePackages = [CompatiblePackage("com.twitter.android")], + use = false +) +object EnableUndoPostPatch :BytecodePatch( + setOf(UndoPost1Fingerprint,UndoPost2Fingerprint,UndoPost3Fingerprint) +){ + override fun execute(context: BytecodeContext) { + + val result1 = UndoPost1Fingerprint.result + ?: throw PatchException("UndoPost1Fingerprint not found") + + //removes flag check + val method1 = result1.mutableMethod + val loc1 = method1.getInstructions().first { it.opcode == Opcode.IF_EQZ }.location.index + method1.removeInstruction(loc1) + + + + val result2 = UndoPost2Fingerprint.result + ?: throw PatchException("UndoPost2Fingerprint not found") + + //removes flag check + val method2 = result2.mutableMethod + val loc2 = method2.getInstructions().first { it.opcode == Opcode.IF_EQZ }.location.index + method2.removeInstruction(loc2) + + val result3 = UndoPost3Fingerprint.result + ?: throw PatchException("UndoPost2Fingerprint not found") + + + + //removes flag check and always return true + val method3 = result3.mutableMethod + + val instructions = method3.getInstructions() + method3.removeInstructions(0, instructions.count()) + + method3.addInstructions(0,""" + sget-object v0, Ljava/lang/Boolean;->TRUE:Ljava/lang/Boolean; + return-object v0 + """.trimIndent()) + + + + //end + } + +} \ No newline at end of file diff --git a/src/main/kotlin/indus/org/patches/twitter/crimeraswak/premium/undoposts/fingerprints/UndoPost1Fingerprint.kt b/src/main/kotlin/indus/org/patches/twitter/crimeraswak/premium/undoposts/fingerprints/UndoPost1Fingerprint.kt new file mode 100644 index 0000000..57101e3 --- /dev/null +++ b/src/main/kotlin/indus/org/patches/twitter/crimeraswak/premium/undoposts/fingerprints/UndoPost1Fingerprint.kt @@ -0,0 +1,18 @@ +package crimera.patches.twitter.premium.undoposts.fingerprints + +import app.revanced.patcher.fingerprint.MethodFingerprint +import com.android.tools.smali.dexlib2.Opcode + +object UndoPost1Fingerprint :MethodFingerprint( + returnType = "Z", + strings = listOf( + "subscriptions_feature_1003", + "allow_undo_replies", + "allow_undo_tweet" + ), + opcodes = listOf( + Opcode.MOVE_RESULT_OBJECT + ) + + +) \ No newline at end of file diff --git a/src/main/kotlin/indus/org/patches/twitter/crimeraswak/premium/undoposts/fingerprints/UndoPost2Fingerprint.kt b/src/main/kotlin/indus/org/patches/twitter/crimeraswak/premium/undoposts/fingerprints/UndoPost2Fingerprint.kt new file mode 100644 index 0000000..2eeb5e5 --- /dev/null +++ b/src/main/kotlin/indus/org/patches/twitter/crimeraswak/premium/undoposts/fingerprints/UndoPost2Fingerprint.kt @@ -0,0 +1,14 @@ +package crimera.patches.twitter.premium.undoposts.fingerprints + +import app.revanced.patcher.fingerprint.MethodFingerprint + +object UndoPost2Fingerprint :MethodFingerprint( + returnType = "Z", + strings = listOf( + "userPreferences", + "draftTweet", + "subscriptions_feature_1003", + "allow_undo_replies", + "allow_undo_tweet" + ) +) \ No newline at end of file diff --git a/src/main/kotlin/indus/org/patches/twitter/crimeraswak/premium/undoposts/fingerprints/UndoPost3Fingerprint.kt b/src/main/kotlin/indus/org/patches/twitter/crimeraswak/premium/undoposts/fingerprints/UndoPost3Fingerprint.kt new file mode 100644 index 0000000..73c811d --- /dev/null +++ b/src/main/kotlin/indus/org/patches/twitter/crimeraswak/premium/undoposts/fingerprints/UndoPost3Fingerprint.kt @@ -0,0 +1,10 @@ +package crimera.patches.twitter.premium.undoposts.fingerprints + +import app.revanced.patcher.fingerprint.MethodFingerprint + +object UndoPost3Fingerprint :MethodFingerprint( + returnType = "Ljava/lang/Object;", + strings = listOf( + "subscriptions_feature_1003" + ) +) \ No newline at end of file diff --git a/src/main/kotlin/indus/org/patches/twitter/crimeraswak/premium/unlockdownloads/DownloadPatch.kt b/src/main/kotlin/indus/org/patches/twitter/crimeraswak/premium/unlockdownloads/DownloadPatch.kt new file mode 100644 index 0000000..fae4edd --- /dev/null +++ b/src/main/kotlin/indus/org/patches/twitter/crimeraswak/premium/unlockdownloads/DownloadPatch.kt @@ -0,0 +1,95 @@ +package crimera.patches.twitter.premium.unlockdownloads + +import app.revanced.patcher.data.BytecodeContext +import app.revanced.patcher.extensions.InstructionExtensions.addInstructions +import app.revanced.patcher.extensions.InstructionExtensions.addInstructionsWithLabels +import app.revanced.patcher.extensions.InstructionExtensions.getInstruction +import app.revanced.patcher.extensions.InstructionExtensions.getInstructions +import app.revanced.patcher.extensions.InstructionExtensions.removeInstruction +import app.revanced.patcher.patch.BytecodePatch +import app.revanced.patcher.patch.PatchException +import app.revanced.patcher.patch.annotation.CompatiblePackage +import app.revanced.patcher.patch.annotation.Patch +import app.revanced.patcher.util.smali.ExternalLabel +import com.android.tools.smali.dexlib2.Opcode +import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction +import com.android.tools.smali.dexlib2.iface.instruction.TwoRegisterInstruction +import crimera.patches.twitter.premium.unlockdownloads.fingerprints.DownloadPatchFingerprint +import crimera.patches.twitter.premium.unlockdownloads.fingerprints.FIleDownloaderFingerprint +import crimera.patches.twitter.premium.unlockdownloads.fingerprints.MediaEntityFingerprint + +// Credits to @iKirby +@Patch( + name = "Download patch", + description = "Unlocks the ability to download videos and gifs from Twitter/X", + compatiblePackages = [CompatiblePackage("com.twitter.android")], +) +@Suppress("unused") +object DownloadPatch : BytecodePatch( + setOf(DownloadPatchFingerprint,FIleDownloaderFingerprint,MediaEntityFingerprint) +) { + override fun execute(context: BytecodeContext) { + val result = DownloadPatchFingerprint.result + ?: throw PatchException("DownloadPatchFingerprint not found") + + val method = result.mutableMethod + val instructions = method.getInstructions() + + val first_if_loc = instructions.first { it.opcode == Opcode.IF_EQ }.location.index + val reg = method.getInstruction(first_if_loc) + val r1 = reg.registerA + val r2 = reg.registerB + + ////add support for gif + method.addInstructionsWithLabels( + first_if_loc + 1, + """ + const/4 v$r2, 0x2 + + if-eq v$r1, v$r2, :cond_1212 + """, + ExternalLabel("cond_1212", method.getInstructions().first { it.opcode == Opcode.NEW_INSTANCE }) + ) + + //enable download for all media + instructions.first { it.opcode == Opcode.IGET_BOOLEAN }.location.index.apply { + method.removeInstruction(this) + method.removeInstruction(this) + } + + val f2Result = FIleDownloaderFingerprint.result + ?: throw PatchException("FIleDownloaderFingerprint not found") + + + val method2 = f2Result.mutableMethod + val instructions2 = method2.getInstructions() + val first_if2_loc = instructions2.first { it.opcode == Opcode.IF_EQZ }.location.index + val r3 = method2.getInstruction(first_if2_loc).registerA + + //remove premium restriction + method2.addInstructions(first_if2_loc,""" + const v$r3, true + """.trimIndent()) + + + //force video downloadable + val f3Result = MediaEntityFingerprint.result + ?: throw PatchException("MediaEntityFingerprint not found") + + val method3 = f3Result.mutableMethod + val instructions3 = method3.getInstructions() + val loc = instructions3.last { it.opcode == Opcode.IGET_BOOLEAN }.location.index + val r4 = method3.getInstruction(loc).registerA + + method3.addInstructions(loc+1,""" + const v$r4, true + """.trimIndent()) + + + + + //end + } + + +} \ No newline at end of file diff --git a/src/main/kotlin/indus/org/patches/twitter/crimeraswak/premium/unlockdownloads/fingerprints/DownloadPatchFingerprint.kt b/src/main/kotlin/indus/org/patches/twitter/crimeraswak/premium/unlockdownloads/fingerprints/DownloadPatchFingerprint.kt new file mode 100644 index 0000000..59d9211 --- /dev/null +++ b/src/main/kotlin/indus/org/patches/twitter/crimeraswak/premium/unlockdownloads/fingerprints/DownloadPatchFingerprint.kt @@ -0,0 +1,12 @@ +package crimera.patches.twitter.premium.unlockdownloads.fingerprints + +import app.revanced.patcher.fingerprint.MethodFingerprint + +object DownloadPatchFingerprint : MethodFingerprint( + returnType = "V", + strings = listOf( + "media_options_sheet", + "resources.getString(R.string.post_video)", + "resources.getString(R.string.post_photo)" + ) +) \ No newline at end of file diff --git a/src/main/kotlin/indus/org/patches/twitter/crimeraswak/premium/unlockdownloads/fingerprints/FIleDownloaderFingerprint.kt b/src/main/kotlin/indus/org/patches/twitter/crimeraswak/premium/unlockdownloads/fingerprints/FIleDownloaderFingerprint.kt new file mode 100644 index 0000000..78c0443 --- /dev/null +++ b/src/main/kotlin/indus/org/patches/twitter/crimeraswak/premium/unlockdownloads/fingerprints/FIleDownloaderFingerprint.kt @@ -0,0 +1,11 @@ +package crimera.patches.twitter.premium.unlockdownloads.fingerprints + +import app.revanced.patcher.fingerprint.MethodFingerprint + +object FIleDownloaderFingerprint: MethodFingerprint( + returnType = "Z", + strings = listOf( + "mediaEntity", + "variantToDownload.url" + ) +) \ No newline at end of file diff --git a/src/main/kotlin/indus/org/patches/twitter/crimeraswak/premium/unlockdownloads/fingerprints/MediaEntityFingerprint.kt b/src/main/kotlin/indus/org/patches/twitter/crimeraswak/premium/unlockdownloads/fingerprints/MediaEntityFingerprint.kt new file mode 100644 index 0000000..313e38a --- /dev/null +++ b/src/main/kotlin/indus/org/patches/twitter/crimeraswak/premium/unlockdownloads/fingerprints/MediaEntityFingerprint.kt @@ -0,0 +1,16 @@ +package crimera.patches.twitter.premium.unlockdownloads.fingerprints + +import app.revanced.patcher.fingerprint.MethodFingerprint +import com.android.tools.smali.dexlib2.Opcode + + +object MediaEntityFingerprint:MethodFingerprint( + opcodes = listOf( + Opcode.IGET_BOOLEAN, + ), + + customFingerprint = { it, _ -> + it.definingClass == "Lcom/twitter/model/json/core/JsonMediaEntity;" + } + +) \ No newline at end of file diff --git a/src/main/kotlin/indus/org/patches/twitter/crimeraswak/timeline/banner/HideBannerPatch.kt b/src/main/kotlin/indus/org/patches/twitter/crimeraswak/timeline/banner/HideBannerPatch.kt new file mode 100644 index 0000000..3fa5309 --- /dev/null +++ b/src/main/kotlin/indus/org/patches/twitter/crimeraswak/timeline/banner/HideBannerPatch.kt @@ -0,0 +1,50 @@ +package indus.org.patches.twitter.crimeraswak.timeline.banner + + +import app.revanced.patcher.data.BytecodeContext +import app.revanced.patcher.extensions.InstructionExtensions.addInstruction +import app.revanced.patcher.extensions.InstructionExtensions.addInstructions +import app.revanced.patcher.extensions.InstructionExtensions.getInstructions +import app.revanced.patcher.patch.BytecodePatch +import app.revanced.patcher.patch.PatchException +import app.revanced.patcher.patch.annotation.CompatiblePackage +import app.revanced.patcher.patch.annotation.Patch +import com.android.tools.smali.dexlib2.Opcode +import indus.org.patches.twitter.crimeraswak.misc.settings.SettingsPatch +import indus.org.patches.twitter.crimeraswak.misc.settings.fingerprints.SettingsStatusLoadFingerprint +import indus.org.patches.twitter.crimeraswak.timeline.banner.fingerprints.HideBannerFingerprint + +@Patch( + name = "Hide Banner", + description = "Hide new post banner", + dependencies = [SettingsPatch::class], + compatiblePackages = [CompatiblePackage("com.twitter.android")], + use = false +) +@Suppress("unused") +object HideBannerPatch : BytecodePatch( + setOf(HideBannerFingerprint) +) { + override fun execute(context: BytecodeContext) { + val result = HideBannerFingerprint.result + ?: throw PatchException("Fingerprint not found") + + val method = result.mutableMethod + val instuctions = method.getInstructions() + + val loc = instuctions.first{it.opcode == Opcode.IF_NEZ}.location.index + + val HIDE_BANNER_DESCRIPTOR = + "invoke-static {}, ${SettingsPatch.PREF_DESCRIPTOR};->hideBanner()Z" + + method.addInstructions(loc, """ + $HIDE_BANNER_DESCRIPTOR + move-result v0 + """.trimIndent()) + + SettingsStatusLoadFingerprint.result!!.mutableMethod.addInstruction( + 0, + "${SettingsPatch.SSTS_DESCRIPTOR}->hideBanner()V" + ) + } +} \ No newline at end of file diff --git a/src/main/kotlin/indus/org/patches/twitter/crimeraswak/timeline/banner/fingerprints/HideBannerFingerprint.kt b/src/main/kotlin/indus/org/patches/twitter/crimeraswak/timeline/banner/fingerprints/HideBannerFingerprint.kt new file mode 100644 index 0000000..0c5d661 --- /dev/null +++ b/src/main/kotlin/indus/org/patches/twitter/crimeraswak/timeline/banner/fingerprints/HideBannerFingerprint.kt @@ -0,0 +1,12 @@ +package indus.org.patches.twitter.crimeraswak.timeline.banner.fingerprints + +import app.revanced.patcher.fingerprint.MethodFingerprint +import com.android.tools.smali.dexlib2.Opcode + +object HideBannerFingerprint : MethodFingerprint( + returnType = "Z", + opcodes = listOf( Opcode.RETURN), + customFingerprint = {it, _ -> + it.definingClass == "Lcom/twitter/timeline/newtweetsbanner/BaseNewTweetsBannerPresenter;" + } +) \ No newline at end of file diff --git a/src/main/kotlin/indus/org/patches/twitter/crimeraswak/timeline/foryou/HideForYouPatch.kt b/src/main/kotlin/indus/org/patches/twitter/crimeraswak/timeline/foryou/HideForYouPatch.kt new file mode 100644 index 0000000..b4e5b71 --- /dev/null +++ b/src/main/kotlin/indus/org/patches/twitter/crimeraswak/timeline/foryou/HideForYouPatch.kt @@ -0,0 +1,53 @@ +package indus.org.patches.twitter.crimeraswak.timeline.foryou + +import app.revanced.patcher.data.BytecodeContext +import app.revanced.patcher.extensions.InstructionExtensions.addInstruction +import app.revanced.patcher.extensions.InstructionExtensions.addInstructionsWithLabels +import app.revanced.patcher.extensions.InstructionExtensions.getInstruction +import app.revanced.patcher.extensions.InstructionExtensions.getInstructions +import app.revanced.patcher.extensions.InstructionExtensions.removeInstruction +import app.revanced.patcher.patch.BytecodePatch +import app.revanced.patcher.patch.PatchException +import app.revanced.patcher.patch.annotation.CompatiblePackage +import app.revanced.patcher.patch.annotation.Patch +import com.android.tools.smali.dexlib2.Opcode +import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction +import indus.org.patches.twitter.crimeraswak.timeline.foryou.fingerprints.HideForYouFingerprint +import indus.org.patches.twitter.crimeraswak.misc.settings.SettingsPatch +import indus.org.patches.twitter.crimeraswak.misc.settings.fingerprints.SettingsStatusLoadFingerprint + +@Patch( + name = "Hide For You", + description = "Hides For You tab from timeline", + dependencies = [SettingsPatch::class], + compatiblePackages = [CompatiblePackage("com.twitter.android")], + use = false +) +@Suppress("unused") +object HideForYouPatch : BytecodePatch( + setOf(HideForYouFingerprint, SettingsStatusLoadFingerprint) +){ + + override fun execute(context: BytecodeContext) { + val result = HideForYouFingerprint.result + ?: throw PatchException("Fingerprint not found") + + val method = result.mutableMethod + + val instructions = method.getInstructions() + + val check = instructions.first { it.opcode == Opcode.CONST_16 }.location.index + val reg = method.getInstruction(check).registerA + method.removeInstruction(check) + method.addInstructionsWithLabels(check,""" + invoke-static {}, ${SettingsPatch.PREF_DESCRIPTOR};->hideForYou()I + + move-result v$reg + """.trimIndent()) + + SettingsStatusLoadFingerprint.result!!.mutableMethod.addInstruction( + 0, + "${SettingsPatch.SSTS_DESCRIPTOR}->hideForYou()V" + ) + } +} diff --git a/src/main/kotlin/indus/org/patches/twitter/crimeraswak/timeline/foryou/fingerprints/HideForYouFingerprint.kt b/src/main/kotlin/indus/org/patches/twitter/crimeraswak/timeline/foryou/fingerprints/HideForYouFingerprint.kt new file mode 100644 index 0000000..07e5b33 --- /dev/null +++ b/src/main/kotlin/indus/org/patches/twitter/crimeraswak/timeline/foryou/fingerprints/HideForYouFingerprint.kt @@ -0,0 +1,16 @@ +package indus.org.patches.twitter.crimeraswak.timeline.foryou.fingerprints + +import app.revanced.patcher.fingerprint.MethodFingerprint +import com.android.tools.smali.dexlib2.Opcode + +object HideForYouFingerprint : MethodFingerprint( + returnType = "V", + strings = listOf( + "selectedTabStateRepo", + "pinnedTimelinesRepo", + "releaseCompletable", + ), + opcodes = listOf( + Opcode.CONST_16, + ), +) \ No newline at end of file diff --git a/src/main/kotlin/indus/org/patches/twitter/crimeraswak/timeline/live/HideLiveThreadsPatch.kt b/src/main/kotlin/indus/org/patches/twitter/crimeraswak/timeline/live/HideLiveThreadsPatch.kt new file mode 100644 index 0000000..5691e33 --- /dev/null +++ b/src/main/kotlin/indus/org/patches/twitter/crimeraswak/timeline/live/HideLiveThreadsPatch.kt @@ -0,0 +1,51 @@ +package indus.org.patches.twitter.crimeraswak.timeline.live + +import app.revanced.patcher.data.BytecodeContext +import app.revanced.patcher.extensions.InstructionExtensions.addInstruction +import app.revanced.patcher.extensions.InstructionExtensions.addInstructions +import app.revanced.patcher.extensions.InstructionExtensions.getInstruction +import app.revanced.patcher.extensions.InstructionExtensions.getInstructions +import app.revanced.patcher.patch.BytecodePatch +import app.revanced.patcher.patch.PatchException +import app.revanced.patcher.patch.annotation.CompatiblePackage +import app.revanced.patcher.patch.annotation.Patch +import com.android.tools.smali.dexlib2.Opcode +import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction +import indus.org.patches.twitter.crimeraswak.misc.settings.SettingsPatch +import indus.org.patches.twitter.crimeraswak.misc.settings.fingerprints.SettingsStatusLoadFingerprint +import indus.org.patches.twitter.crimeraswak.timeline.live.fingerprints.HideLiveThreadsFingerprint + +@Patch( + name = "Hide Live Threads", + dependencies = [SettingsPatch::class], + compatiblePackages = [CompatiblePackage("com.twitter.android")], + use = false +) +@Suppress("unused") +object HideLiveThreadsPatch : BytecodePatch( + setOf(HideLiveThreadsFingerprint) +){ + override fun execute(context: BytecodeContext) { + val result = HideLiveThreadsFingerprint.result + ?: throw PatchException("Fingerprint not found") + + val method = result.mutableMethod + val instructions = method.getInstructions() + + val loc = instructions.first{it.opcode == Opcode.IGET_OBJECT}.location.index + val reg = method.getInstruction(loc).registerA + + val HIDE_LIVE_DESCRIPTOR = + "invoke-static {v$reg}, ${SettingsPatch.PREF_DESCRIPTOR};->liveThread(Ljava/util/ArrayList;)Ljava/util/ArrayList;" + + method.addInstructions(loc+1,""" + $HIDE_LIVE_DESCRIPTOR + move-result-object v$reg + """.trimIndent()) + + SettingsStatusLoadFingerprint.result!!.mutableMethod.addInstruction( + 0, + "${SettingsPatch.SSTS_DESCRIPTOR}->hideLiveThreads()V" + ) + } +} \ No newline at end of file diff --git a/src/main/kotlin/indus/org/patches/twitter/crimeraswak/timeline/live/fingerprints/HideLiveThreadsFingerprint.kt b/src/main/kotlin/indus/org/patches/twitter/crimeraswak/timeline/live/fingerprints/HideLiveThreadsFingerprint.kt new file mode 100644 index 0000000..a40003d --- /dev/null +++ b/src/main/kotlin/indus/org/patches/twitter/crimeraswak/timeline/live/fingerprints/HideLiveThreadsFingerprint.kt @@ -0,0 +1,13 @@ +package indus.org.patches.twitter.crimeraswak.timeline.live.fingerprints + +import app.revanced.patcher.fingerprint.MethodFingerprint +import com.android.tools.smali.dexlib2.Opcode + +object HideLiveThreadsFingerprint : MethodFingerprint( + opcodes = listOf( + Opcode.IGET_OBJECT, + ), + customFingerprint = {it,_ -> + it.definingClass == "Lcom/twitter/fleets/api/json/JsonFleetsTimelineResponse;" + } +) \ No newline at end of file diff --git a/src/main/kotlin/indus/org/patches/twitter/hook/patch/ads/HideAdsHookPatch.kt b/src/main/kotlin/indus/org/patches/twitter/hook/patch/ads/HideAdsHookPatch.kt index 731d906..deb9ec5 100644 --- a/src/main/kotlin/indus/org/patches/twitter/hook/patch/ads/HideAdsHookPatch.kt +++ b/src/main/kotlin/indus/org/patches/twitter/hook/patch/ads/HideAdsHookPatch.kt @@ -7,9 +7,10 @@ import indus.org.patches.twitter.hook.patch.BaseHookPatch @Patch( name = "Hide ads", - description = "Hides ads.", + description = "DON'T USE WHEN PATCHING ALONG WITH CRIMERA PATCHES AND INTEGRATIONS (NOT NEEDED ANYWAYS THEN).", dependencies = [JsonHookPatch::class], - compatiblePackages = [CompatiblePackage("com.twitter.android")] + compatiblePackages = [CompatiblePackage("com.twitter.android")], + use = false ) @Suppress("unused") object HideAdsHookPatch : BaseHookPatch("Lapp/revanced/integrations/twitter/patches/hook/patch/ads/AdsHook;") \ No newline at end of file diff --git a/src/main/kotlin/indus/org/patches/twitter/hook/patch/recommendation/HideRecommendedUsersPatch.kt b/src/main/kotlin/indus/org/patches/twitter/hook/patch/recommendation/HideRecommendedUsersPatch.kt index b0741f4..354277a 100644 --- a/src/main/kotlin/indus/org/patches/twitter/hook/patch/recommendation/HideRecommendedUsersPatch.kt +++ b/src/main/kotlin/indus/org/patches/twitter/hook/patch/recommendation/HideRecommendedUsersPatch.kt @@ -7,8 +7,10 @@ import indus.org.patches.twitter.hook.patch.BaseHookPatch @Patch( name = "Hide promoted users", + description = "DON'T USE WHEN PATCHING ALONG WITH CRIMERA PATCHES AND INTEGRATIONS (NOT NEEDED ANYWAYS THEN).", dependencies = [JsonHookPatch::class], - compatiblePackages = [CompatiblePackage("com.twitter.android")] + compatiblePackages = [CompatiblePackage("com.twitter.android")], + use = false ) @Suppress("unused") object HideRecommendedUsersPatch : BaseHookPatch( diff --git a/src/main/kotlin/indus/org/patches/twitter/interaction/downloads/UnlockDownloadsPatch.kt b/src/main/kotlin/indus/org/patches/twitter/interaction/downloads/UnlockDownloadsPatch.kt deleted file mode 100644 index 6396a1c..0000000 --- a/src/main/kotlin/indus/org/patches/twitter/interaction/downloads/UnlockDownloadsPatch.kt +++ /dev/null @@ -1,82 +0,0 @@ -package indus.org.patches.twitter.interaction.downloads - -import app.revanced.patcher.data.BytecodeContext -import app.revanced.patcher.extensions.InstructionExtensions.addInstruction -import app.revanced.patcher.extensions.InstructionExtensions.addInstructionsWithLabels -import app.revanced.patcher.extensions.InstructionExtensions.getInstruction -import app.revanced.patcher.extensions.InstructionExtensions.getInstructions -import app.revanced.patcher.extensions.InstructionExtensions.removeInstruction -import app.revanced.patcher.fingerprint.MethodFingerprint -import app.revanced.patcher.fingerprint.MethodFingerprintResult -import app.revanced.patcher.patch.BytecodePatch -import app.revanced.patcher.patch.annotation.CompatiblePackage -import app.revanced.patcher.patch.annotation.Patch -import app.revanced.patcher.util.smali.ExternalLabel -import com.android.tools.smali.dexlib2.Opcode -import indus.org.patches.twitter.interaction.downloads.fingerprints.ConstructMediaOptionsSheetFingerprint -import indus.org.patches.twitter.interaction.downloads.fingerprints.ShowDownloadVideoUpsellBottomSheetFingerprint -import indus.org.patches.util.exception -import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction -import com.android.tools.smali.dexlib2.iface.instruction.TwoRegisterInstruction -import indus.org.patches.twitter.interaction.downloads.fingerprints.BuildMediaOptionsSheetFingerprint - -@Patch( - name = "Unlock Video and GIF downloads", - compatiblePackages = [CompatiblePackage("com.twitter.android")], -) -@Suppress("unused") -object UnlockDownloadsPatch : BytecodePatch( - setOf( - ConstructMediaOptionsSheetFingerprint, - ShowDownloadVideoUpsellBottomSheetFingerprint, - BuildMediaOptionsSheetFingerprint, - ), -) { - override fun execute(context: BytecodeContext) { - fun MethodFingerprint.patch(getRegisterAndIndex: MethodFingerprintResult.() -> Pair) = result?.let { - getRegisterAndIndex(it).let { (index, register) -> - it.mutableMethod.addInstruction(index, "const/4 v$register, 0x1") - } - } ?: throw exception - - // Allow downloads (for non copyrighted videos) - ShowDownloadVideoUpsellBottomSheetFingerprint.patch { - val checkIndex = scanResult.patternScanResult!!.startIndex - val register = mutableMethod.getInstruction(checkIndex).registerA - - checkIndex to register - } - - // Force show the download menu item. - ConstructMediaOptionsSheetFingerprint.patch { - val showDownloadButtonIndex = mutableMethod.getInstructions().lastIndex - 1 - val register = mutableMethod.getInstruction(showDownloadButtonIndex).registerA - - showDownloadButtonIndex to register - } - - // Make GIFs downloadable. - BuildMediaOptionsSheetFingerprint.result?.let { - val scanResult = it.scanResult.patternScanResult!! - it.mutableMethod.apply { - val checkMediaTypeIndex = scanResult.startIndex - val checkMediaTypeInstruction = getInstruction(checkMediaTypeIndex) - - // Treat GIFs as videos. - addInstructionsWithLabels( - checkMediaTypeIndex + 1, - """ - const/4 v${checkMediaTypeInstruction.registerB}, 0x2 # GIF - if-eq v${checkMediaTypeInstruction.registerA}, v${checkMediaTypeInstruction.registerB}, :video - """, - ExternalLabel("video", getInstruction(scanResult.endIndex)), - ) - - // Remove media.isDownloadable check. - removeInstruction( - getInstructions().first { insn -> insn.opcode == Opcode.IGET_BOOLEAN }.location.index + 1, - ) - } - } ?: throw BuildMediaOptionsSheetFingerprint.exception - } -} diff --git a/src/main/kotlin/indus/org/patches/twitter/interaction/downloads/fingerprints/BuildMediaOptionsSheetFingerprint.kt b/src/main/kotlin/indus/org/patches/twitter/interaction/downloads/fingerprints/BuildMediaOptionsSheetFingerprint.kt deleted file mode 100644 index 548a513..0000000 --- a/src/main/kotlin/indus/org/patches/twitter/interaction/downloads/fingerprints/BuildMediaOptionsSheetFingerprint.kt +++ /dev/null @@ -1,14 +0,0 @@ -package indus.org.patches.twitter.interaction.downloads.fingerprints - -import app.revanced.patcher.fingerprint.MethodFingerprint -import com.android.tools.smali.dexlib2.Opcode - -internal object BuildMediaOptionsSheetFingerprint : MethodFingerprint( - opcodes = listOf( - Opcode.IF_EQ, - Opcode.SGET_OBJECT, - Opcode.GOTO_16, - Opcode.NEW_INSTANCE, - ), - strings = listOf("resources.getString(R.string.post_video)"), -) \ No newline at end of file diff --git a/src/main/kotlin/indus/org/patches/twitter/interaction/downloads/fingerprints/ConstructMediaOptionsSheetFingerprint.kt b/src/main/kotlin/indus/org/patches/twitter/interaction/downloads/fingerprints/ConstructMediaOptionsSheetFingerprint.kt deleted file mode 100644 index e014653..0000000 --- a/src/main/kotlin/indus/org/patches/twitter/interaction/downloads/fingerprints/ConstructMediaOptionsSheetFingerprint.kt +++ /dev/null @@ -1,12 +0,0 @@ -package indus.org.patches.twitter.interaction.downloads.fingerprints - -import app.revanced.patcher.extensions.or -import app.revanced.patcher.fingerprint.MethodFingerprint -import com.android.tools.smali.dexlib2.AccessFlags - - -internal object ConstructMediaOptionsSheetFingerprint : MethodFingerprint( - returnType = "V", - accessFlags = AccessFlags.PUBLIC or AccessFlags.CONSTRUCTOR, - strings = listOf("captionsState") -) diff --git a/src/main/kotlin/indus/org/patches/twitter/interaction/downloads/fingerprints/ShowDownloadVideoUpsellBottomSheetFingerprint.kt b/src/main/kotlin/indus/org/patches/twitter/interaction/downloads/fingerprints/ShowDownloadVideoUpsellBottomSheetFingerprint.kt deleted file mode 100644 index e89e5ab..0000000 --- a/src/main/kotlin/indus/org/patches/twitter/interaction/downloads/fingerprints/ShowDownloadVideoUpsellBottomSheetFingerprint.kt +++ /dev/null @@ -1,10 +0,0 @@ -package indus.org.patches.twitter.interaction.downloads.fingerprints - -import app.revanced.patcher.fingerprint.MethodFingerprint -import com.android.tools.smali.dexlib2.Opcode - -internal object ShowDownloadVideoUpsellBottomSheetFingerprint : MethodFingerprint( - returnType = "Z", - strings = listOf("variantToDownload.url"), - opcodes = listOf(Opcode.IF_EQZ) -) diff --git a/src/main/kotlin/indus/org/patches/twitter/layout/disablechirpfont/DisableChirpFontPatch.kt b/src/main/kotlin/indus/org/patches/twitter/layout/disablechirpfont/DisableChirpFontPatch.kt deleted file mode 100644 index a86c032..0000000 --- a/src/main/kotlin/indus/org/patches/twitter/layout/disablechirpfont/DisableChirpFontPatch.kt +++ /dev/null @@ -1,28 +0,0 @@ -package indus.org.patches.twitter.layout.disablechirpfont - -import app.revanced.patcher.data.BytecodeContext -import app.revanced.patcher.extensions.InstructionExtensions.addInstructions -import app.revanced.patcher.patch.BytecodePatch -import app.revanced.patcher.patch.annotation.CompatiblePackage -import app.revanced.patcher.patch.annotation.Patch - -// credits to https://github.com/crimera/piko -@Patch( - name = "Disable chirp font", - use = false, - compatiblePackages = [CompatiblePackage("com.twitter.android")] -) -@Suppress("unused") -object DisableChirpFontPatch: BytecodePatch( - setOf(ChirpFontFingerprint) -) { - override fun execute(context: BytecodeContext) { - ChirpFontFingerprint.result?.mutableMethod?.addInstructions( - 0, - """ - const v0, false - return v0 - """ - ) - } -} \ No newline at end of file diff --git a/src/main/kotlin/indus/org/patches/twitter/layout/viewcount/HideViewCountPatch.kt b/src/main/kotlin/indus/org/patches/twitter/layout/viewcount/HideViewCountPatch.kt deleted file mode 100644 index d3bbcf6..0000000 --- a/src/main/kotlin/indus/org/patches/twitter/layout/viewcount/HideViewCountPatch.kt +++ /dev/null @@ -1,30 +0,0 @@ -package indus.org.patches.twitter.layout.viewcount - - -import app.revanced.patcher.data.BytecodeContext -import app.revanced.patcher.extensions.InstructionExtensions.addInstructions -import app.revanced.patcher.patch.BytecodePatch -import app.revanced.patcher.patch.annotation.CompatiblePackage -import app.revanced.patcher.patch.annotation.Patch -import app.revanced.patches.twitter.layout.viewcount.fingerprints.ViewCountsEnabledFingerprint -import indus.org.patches.util.exception - -@Patch( - name = "Hide view count", - description = "Hides the view count of Tweets.", - compatiblePackages = [CompatiblePackage("com.twitter.android")], - use = false -) -@Suppress("unused") -object HideViewCountPatch : BytecodePatch( - setOf(ViewCountsEnabledFingerprint) -) { - override fun execute(context: BytecodeContext) = - ViewCountsEnabledFingerprint.result?.mutableMethod?.addInstructions( - 0, - """ - const/4 v0, 0x0 - return v0 - """ - ) ?: throw ViewCountsEnabledFingerprint.exception -} diff --git a/src/main/kotlin/indus/org/patches/twitter/layout/viewcount/fingerprints/ViewCountsEnabledFingerprint.kt b/src/main/kotlin/indus/org/patches/twitter/layout/viewcount/fingerprints/ViewCountsEnabledFingerprint.kt deleted file mode 100644 index 3b3e7af..0000000 --- a/src/main/kotlin/indus/org/patches/twitter/layout/viewcount/fingerprints/ViewCountsEnabledFingerprint.kt +++ /dev/null @@ -1,8 +0,0 @@ -package app.revanced.patches.twitter.layout.viewcount.fingerprints - -import app.revanced.patcher.fingerprint.MethodFingerprint - -internal object ViewCountsEnabledFingerprint : MethodFingerprint( - returnType = "Z", - strings = listOf("view_counts_public_visibility_enabled") -) diff --git a/src/main/kotlin/indus/org/patches/twitter/sanitizelinks/fingerprints/DexFingerprint.kt b/src/main/kotlin/indus/org/patches/twitter/sanitizelinks/fingerprints/DexFingerprint.kt deleted file mode 100644 index c518942..0000000 --- a/src/main/kotlin/indus/org/patches/twitter/sanitizelinks/fingerprints/DexFingerprint.kt +++ /dev/null @@ -1,19 +0,0 @@ -package indus.org.patches.twitter.sanitizelinks.fingerprints - -import app.revanced.patcher.fingerprint.MethodFingerprint - -object DexFingerprint { - - object AddSessionTokenFingerprint: MethodFingerprint( - strings = listOf( - "", - "shareParam", - "sessionToken" - ) - ) - - internal object JsonObjectMapperFingerprint : MethodFingerprint( - // Lcom/twitter/model/json/core/JsonUrlEntity$$JsonObjectMapper; - customFingerprint = { methodDef, _ -> methodDef.name.contains("parse") && methodDef.definingClass == "Lcom/twitter/model/json/core/JsonUrlEntity\$\$JsonObjectMapper;" } - ) -} \ No newline at end of file