chore: Merge branch dev to main (#3673)

This commit is contained in:
oSumAtrIX 2024-09-23 16:08:46 +02:00 committed by GitHub
commit 00f78373f6
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
15 changed files with 169 additions and 139 deletions

View File

@ -1,3 +1,27 @@
# [4.15.0-dev.1](https://github.com/ReVanced/revanced-patches/compare/v4.14.2-dev.2...v4.15.0-dev.1) (2024-09-22)
### Features
* **TikTok:** Bump patches to support the latest version 36.5.4 ([e5dcb72](https://github.com/ReVanced/revanced-patches/commit/e5dcb72597092fb32003f11fdf6f861ede4e7ff3))
## [4.14.2-dev.2](https://github.com/ReVanced/revanced-patches/compare/v4.14.2-dev.1...v4.14.2-dev.2) (2024-09-21)
### Bug Fixes
* **YouTube - Spoof video streams:** Change default client type to Android VR ([74c8637](https://github.com/ReVanced/revanced-patches/commit/74c8637943347078955f51325bc6af92a35d4463))
* **YouTube - Spoof video streams:** Change default client type to Android VR ([#3672](https://github.com/ReVanced/revanced-patches/issues/3672)) ([a3306f6](https://github.com/ReVanced/revanced-patches/commit/a3306f6717a09b734354f00363a96abad0ae14e7))
## [4.14.2-dev.1](https://github.com/ReVanced/revanced-patches/compare/v4.14.1...v4.14.2-dev.1) (2024-09-21)
### Bug Fixes
* **TikTok - Playback speed:** Prevent crash by fixing invalid patch ([82d53cb](https://github.com/ReVanced/revanced-patches/commit/82d53cbc3bbfa585ba4337fdfaec9f0f19c802e6))
* **TikTok - Settings:** Prevent crash by fixing invalid patch ([8074032](https://github.com/ReVanced/revanced-patches/commit/8074032fad3eff1c03296a882d2e2820da99b592))
* **Twitter - Open links with app chooser:** Constrain patch to last working version `10.48.0-release` ([b9955d5](https://github.com/ReVanced/revanced-patches/commit/b9955d5ff6e456593b01f0f25d80ff660d02082a))
## [4.14.1](https://github.com/ReVanced/revanced-patches/compare/v4.14.0...v4.14.1) (2024-09-18) ## [4.14.1](https://github.com/ReVanced/revanced-patches/compare/v4.14.0...v4.14.1) (2024-09-18)

View File

@ -1,4 +1,4 @@
org.gradle.parallel = true org.gradle.parallel = true
org.gradle.caching = true org.gradle.caching = true
kotlin.code.style = official kotlin.code.style = official
version = 4.14.1 version = 4.15.0-dev.1

View File

@ -17,16 +17,16 @@ import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction
@Patch( @Patch(
name = "Feed filter", name = "Feed filter",
description = "Removes ads, livestreams, stories, image videos " + description = "Removes ads, livestreams, stories, image videos " +
"and videos with a specific amount of views or likes from the feed.", "and videos with a specific amount of views or likes from the feed.",
dependencies = [IntegrationsPatch::class, SettingsPatch::class], dependencies = [IntegrationsPatch::class, SettingsPatch::class],
compatiblePackages = [ compatiblePackages = [
CompatiblePackage("com.ss.android.ugc.trill", ["32.5.3"]), CompatiblePackage("com.ss.android.ugc.trill", ["36.5.4"]),
CompatiblePackage("com.zhiliaoapp.musically", ["32.5.3"]) CompatiblePackage("com.zhiliaoapp.musically", ["36.5.4"]),
] ],
) )
@Suppress("unused") @Suppress("unused")
object FeedFilterPatch : BytecodePatch( object FeedFilterPatch : BytecodePatch(
setOf(FeedApiServiceLIZFingerprint, SettingsStatusLoadFingerprint) setOf(FeedApiServiceLIZFingerprint, SettingsStatusLoadFingerprint),
) { ) {
override fun execute(context: BytecodeContext) { override fun execute(context: BytecodeContext) {
FeedApiServiceLIZFingerprint.result?.mutableMethod?.apply { FeedApiServiceLIZFingerprint.result?.mutableMethod?.apply {
@ -36,13 +36,13 @@ object FeedFilterPatch : BytecodePatch(
addInstruction( addInstruction(
returnFeedItemInstruction.location.index, returnFeedItemInstruction.location.index,
"invoke-static { v$feedItemsRegister }, " + "invoke-static { v$feedItemsRegister }, " +
"Lapp/revanced/integrations/tiktok/feedfilter/FeedItemsFilter;->filter(Lcom/ss/android/ugc/aweme/feed/model/FeedItemList;)V" "Lapp/revanced/integrations/tiktok/feedfilter/FeedItemsFilter;->filter(Lcom/ss/android/ugc/aweme/feed/model/FeedItemList;)V",
) )
} ?: throw FeedApiServiceLIZFingerprint.exception } ?: throw FeedApiServiceLIZFingerprint.exception
SettingsStatusLoadFingerprint.result?.mutableMethod?.addInstruction( SettingsStatusLoadFingerprint.result?.mutableMethod?.addInstruction(
0, 0,
"invoke-static {}, Lapp/revanced/integrations/tiktok/settings/SettingsStatus;->enableFeedFilter()V" "invoke-static {}, Lapp/revanced/integrations/tiktok/settings/SettingsStatus;->enableFeedFilter()V",
) ?: throw SettingsStatusLoadFingerprint.exception ) ?: throw SettingsStatusLoadFingerprint.exception
} }
} }

View File

@ -9,7 +9,7 @@ import app.revanced.patcher.patch.annotation.CompatiblePackage
import app.revanced.patcher.patch.annotation.Patch import app.revanced.patcher.patch.annotation.Patch
import app.revanced.patcher.util.smali.ExternalLabel import app.revanced.patcher.util.smali.ExternalLabel
import app.revanced.patches.tiktok.interaction.cleardisplay.fingerprints.OnClearDisplayEventFingerprint import app.revanced.patches.tiktok.interaction.cleardisplay.fingerprints.OnClearDisplayEventFingerprint
import app.revanced.patches.tiktok.interaction.cleardisplay.fingerprints.OnRenderFirstFrameFingerprint import app.revanced.patches.tiktok.shared.fingerprints.OnRenderFirstFrameFingerprint
import app.revanced.util.exception import app.revanced.util.exception
import app.revanced.util.indexOfFirstInstructionOrThrow import app.revanced.util.indexOfFirstInstructionOrThrow
import com.android.tools.smali.dexlib2.Opcode import com.android.tools.smali.dexlib2.Opcode
@ -19,16 +19,16 @@ import com.android.tools.smali.dexlib2.iface.instruction.formats.Instruction22c
name = "Remember clear display", name = "Remember clear display",
description = "Remembers the clear display configurations in between videos.", description = "Remembers the clear display configurations in between videos.",
compatiblePackages = [ compatiblePackages = [
CompatiblePackage("com.ss.android.ugc.trill", ["32.5.3"]), CompatiblePackage("com.ss.android.ugc.trill", ["36.5.4"]),
CompatiblePackage("com.zhiliaoapp.musically", ["32.5.3"]) CompatiblePackage("com.zhiliaoapp.musically", ["36.5.4"]),
] ],
) )
@Suppress("unused") @Suppress("unused")
object RememberClearDisplayPatch : BytecodePatch( object RememberClearDisplayPatch : BytecodePatch(
setOf( setOf(
OnClearDisplayEventFingerprint, OnClearDisplayEventFingerprint,
OnRenderFirstFrameFingerprint OnRenderFirstFrameFingerprint,
) ),
) { ) {
override fun execute(context: BytecodeContext) { override fun execute(context: BytecodeContext) {
OnClearDisplayEventFingerprint.result?.mutableMethod?.let { OnClearDisplayEventFingerprint.result?.mutableMethod?.let {
@ -40,7 +40,7 @@ object RememberClearDisplayPatch : BytecodePatch(
it.addInstructions( it.addInstructions(
isEnabledIndex, isEnabledIndex,
"invoke-static { v$isEnabledRegister }, " + "invoke-static { v$isEnabledRegister }, " +
"Lapp/revanced/integrations/tiktok/cleardisplay/RememberClearDisplayPatch;->rememberClearDisplayState(Z)V" "Lapp/revanced/integrations/tiktok/cleardisplay/RememberClearDisplayPatch;->rememberClearDisplayState(Z)V",
) )
// endregion // endregion
@ -54,22 +54,25 @@ object RememberClearDisplayPatch : BytecodePatch(
""" """
# Create a new clearDisplayEvent and post it to the EventBus (https://github.com/greenrobot/EventBus) # Create a new clearDisplayEvent and post it to the EventBus (https://github.com/greenrobot/EventBus)
# The state of clear display.
invoke-static { }, Lapp/revanced/integrations/tiktok/cleardisplay/RememberClearDisplayPatch;->getClearDisplayState()Z
move-result v3
if-eqz v3, :clear_display_disabled
# Clear display type such as 0 = LONG_PRESS, 1 = SCREEN_RECORD etc. # Clear display type such as 0 = LONG_PRESS, 1 = SCREEN_RECORD etc.
const/4 v1, 0x0 const/4 v1, 0x0
# Enter method (Such as "pinch", "swipe_exit", or an empty string (unknown, what it means)).
const-string v2, ""
# Name of the clear display type which is equivalent to the clear display type. # Name of the clear display type which is equivalent to the clear display type.
const-string v2, "long_press" const-string v3, "long_press"
# The state of clear display.
invoke-static { }, Lapp/revanced/integrations/tiktok/cleardisplay/RememberClearDisplayPatch;->getClearDisplayState()Z
move-result v4
if-eqz v4, :clear_display_disabled
new-instance v0, $clearDisplayEventClass new-instance v0, $clearDisplayEventClass
invoke-direct { v0, v1, v2, v3 }, $clearDisplayEventClass-><init>(ILjava/lang/String;Z)V invoke-direct { v0, v1, v2, v3, v4 }, $clearDisplayEventClass-><init>(ILjava/lang/String;Ljava/lang/String;Z)V
invoke-virtual { v0 }, $clearDisplayEventClass->post()Lcom/ss/android/ugc/governance/eventbus/IEvent; invoke-virtual { v0 }, $clearDisplayEventClass->post()Lcom/ss/android/ugc/governance/eventbus/IEvent;
""", """,
ExternalLabel("clear_display_disabled", getInstruction(0)) ExternalLabel("clear_display_disabled", getInstruction(0)),
) )
} ?: throw OnRenderFirstFrameFingerprint.exception } ?: throw OnRenderFirstFrameFingerprint.exception

View File

@ -1,9 +0,0 @@
package app.revanced.patches.tiktok.interaction.cleardisplay.fingerprints
import app.revanced.patcher.fingerprint.MethodFingerprint
internal object OnRenderFirstFrameFingerprint : MethodFingerprint(
customFingerprint = { methodDef, _ ->
methodDef.definingClass.endsWith("/BaseListFragmentPanel;") && methodDef.name == "onRenderFirstFrame"
}
)

View File

@ -13,14 +13,13 @@ import app.revanced.patcher.util.proxy.mutableTypes.MutableMethod
import app.revanced.patches.tiktok.interaction.downloads.fingerprints.ACLCommonShareFingerprint import app.revanced.patches.tiktok.interaction.downloads.fingerprints.ACLCommonShareFingerprint
import app.revanced.patches.tiktok.interaction.downloads.fingerprints.ACLCommonShareFingerprint2 import app.revanced.patches.tiktok.interaction.downloads.fingerprints.ACLCommonShareFingerprint2
import app.revanced.patches.tiktok.interaction.downloads.fingerprints.ACLCommonShareFingerprint3 import app.revanced.patches.tiktok.interaction.downloads.fingerprints.ACLCommonShareFingerprint3
import app.revanced.patches.tiktok.interaction.downloads.fingerprints.DownloadPathParentFingerprint import app.revanced.patches.tiktok.interaction.downloads.fingerprints.DownloadUriFingerprint
import app.revanced.patches.tiktok.misc.integrations.IntegrationsPatch import app.revanced.patches.tiktok.misc.integrations.IntegrationsPatch
import app.revanced.patches.tiktok.misc.settings.SettingsPatch import app.revanced.patches.tiktok.misc.settings.SettingsPatch
import app.revanced.patches.tiktok.misc.settings.fingerprints.SettingsStatusLoadFingerprint import app.revanced.patches.tiktok.misc.settings.fingerprints.SettingsStatusLoadFingerprint
import app.revanced.util.exception import app.revanced.util.exception
import app.revanced.util.getReference
import app.revanced.util.indexOfFirstInstructionOrThrow import app.revanced.util.indexOfFirstInstructionOrThrow
import com.android.tools.smali.dexlib2.Opcode
import com.android.tools.smali.dexlib2.iface.instruction.formats.Instruction35c
import com.android.tools.smali.dexlib2.iface.reference.MethodReference import com.android.tools.smali.dexlib2.iface.reference.MethodReference
@Patch( @Patch(
@ -28,9 +27,9 @@ import com.android.tools.smali.dexlib2.iface.reference.MethodReference
description = "Removes download restrictions and changes the default path to download to.", description = "Removes download restrictions and changes the default path to download to.",
dependencies = [IntegrationsPatch::class, SettingsPatch::class], dependencies = [IntegrationsPatch::class, SettingsPatch::class],
compatiblePackages = [ compatiblePackages = [
CompatiblePackage("com.ss.android.ugc.trill", ["32.5.3"]), CompatiblePackage("com.ss.android.ugc.trill", ["36.5.4"]),
CompatiblePackage("com.zhiliaoapp.musically", ["32.5.3"]) CompatiblePackage("com.zhiliaoapp.musically", ["36.5.4"]),
] ],
) )
@Suppress("unused") @Suppress("unused")
object DownloadsPatch : BytecodePatch( object DownloadsPatch : BytecodePatch(
@ -38,9 +37,9 @@ object DownloadsPatch : BytecodePatch(
ACLCommonShareFingerprint, ACLCommonShareFingerprint,
ACLCommonShareFingerprint2, ACLCommonShareFingerprint2,
ACLCommonShareFingerprint3, ACLCommonShareFingerprint3,
DownloadPathParentFingerprint, DownloadUriFingerprint,
SettingsStatusLoadFingerprint SettingsStatusLoadFingerprint,
) ),
) { ) {
override fun execute(context: BytecodeContext) { override fun execute(context: BytecodeContext) {
fun MethodFingerprint.getMethod() = result?.mutableMethod ?: throw exception fun MethodFingerprint.getMethod() = result?.mutableMethod ?: throw exception
@ -52,7 +51,7 @@ object DownloadsPatch : BytecodePatch(
""" """
const/4 v0, 0x0 const/4 v0, 0x0
return v0 return v0
""" """,
) )
}, },
ACLCommonShareFingerprint2 to { ACLCommonShareFingerprint2 to {
@ -61,7 +60,7 @@ object DownloadsPatch : BytecodePatch(
""" """
const/4 v0, 0x2 const/4 v0, 0x2
return v0 return v0
""" """,
) )
}, },
// Download videos without watermark. // Download videos without watermark.
@ -76,48 +75,40 @@ object DownloadsPatch : BytecodePatch(
return v0 return v0
:noremovewatermark :noremovewatermark
nop nop
""" """,
) )
}, },
// Change the download path patch. // Change the download path patch.
DownloadPathParentFingerprint to { DownloadUriFingerprint to {
val targetIndex = indexOfFirstInstructionOrThrow { opcode == Opcode.INVOKE_STATIC } val firstIndex = indexOfFirstInstructionOrThrow {
val downloadUriMethod = context getReference<MethodReference>()?.name == "<init>"
.toMethodWalker(this)
.nextMethod(targetIndex, true)
.getMethod() as MutableMethod
val firstIndex = downloadUriMethod.indexOfFirstInstructionOrThrow {
opcode == Opcode.INVOKE_DIRECT && ((this as Instruction35c).reference as MethodReference).name == "<init>"
} }
val secondIndex = downloadUriMethod.indexOfFirstInstructionOrThrow { val secondIndex = indexOfFirstInstructionOrThrow {
opcode == Opcode.INVOKE_STATIC && ((this as Instruction35c).reference as MethodReference).returnType.contains( getReference<MethodReference>()?.returnType?.contains("Uri") == true
"Uri"
)
} }
downloadUriMethod.addInstructions( addInstructions(
secondIndex, secondIndex,
""" """
invoke-static {}, Lapp/revanced/integrations/tiktok/download/DownloadsPatch;->getDownloadPath()Ljava/lang/String; invoke-static {}, Lapp/revanced/integrations/tiktok/download/DownloadsPatch;->getDownloadPath()Ljava/lang/String;
move-result-object v0 move-result-object v0
""" """,
) )
downloadUriMethod.addInstructions( addInstructions(
firstIndex, firstIndex,
""" """
invoke-static {}, Lapp/revanced/integrations/tiktok/download/DownloadsPatch;->getDownloadPath()Ljava/lang/String; invoke-static {}, Lapp/revanced/integrations/tiktok/download/DownloadsPatch;->getDownloadPath()Ljava/lang/String;
move-result-object v0 move-result-object v0
""" """,
) )
}, },
SettingsStatusLoadFingerprint to { SettingsStatusLoadFingerprint to {
addInstruction( addInstruction(
0, 0,
"invoke-static {}, Lapp/revanced/integrations/tiktok/settings/SettingsStatus;->enableDownload()V" "invoke-static {}, Lapp/revanced/integrations/tiktok/settings/SettingsStatus;->enableDownload()V",
) )
} },
).forEach { (fingerprint, patch) -> ).forEach { (fingerprint, patch) ->
fingerprint.getMethod().patch() fingerprint.getMethod().patch()
} }

View File

@ -3,22 +3,18 @@ package app.revanced.patches.tiktok.interaction.downloads.fingerprints
import app.revanced.patcher.extensions.or import app.revanced.patcher.extensions.or
import app.revanced.patcher.fingerprint.MethodFingerprint import app.revanced.patcher.fingerprint.MethodFingerprint
import com.android.tools.smali.dexlib2.AccessFlags import com.android.tools.smali.dexlib2.AccessFlags
import com.android.tools.smali.dexlib2.Opcode
internal object DownloadPathParentFingerprint : MethodFingerprint( internal object DownloadUriFingerprint : MethodFingerprint(
"L", "Landroid/net/Uri;",
AccessFlags.PUBLIC or AccessFlags.STATIC, AccessFlags.PUBLIC or AccessFlags.STATIC,
strings = listOf( strings = listOf(
"video/mp4" "/",
"/Camera",
"/Camera/",
"video/mp4",
), ),
parameters = listOf( parameters = listOf(
"L", "Landroid/content/Context;",
"L" "Ljava/lang/String;",
), ),
opcodes = listOf( )
Opcode.CONST_STRING,
Opcode.INVOKE_STATIC,
Opcode.MOVE_RESULT_OBJECT,
Opcode.RETURN_OBJECT
)
)

View File

@ -9,30 +9,33 @@ import app.revanced.patcher.patch.PatchException
import app.revanced.patcher.patch.annotation.CompatiblePackage import app.revanced.patcher.patch.annotation.CompatiblePackage
import app.revanced.patcher.patch.annotation.Patch import app.revanced.patcher.patch.annotation.Patch
import app.revanced.patches.tiktok.interaction.speed.fingerprints.GetSpeedFingerprint import app.revanced.patches.tiktok.interaction.speed.fingerprints.GetSpeedFingerprint
import app.revanced.patches.tiktok.interaction.speed.fingerprints.OnRenderFirstFrameFingerprint
import app.revanced.patches.tiktok.interaction.speed.fingerprints.SetSpeedFingerprint import app.revanced.patches.tiktok.interaction.speed.fingerprints.SetSpeedFingerprint
import app.revanced.patches.tiktok.shared.fingerprints.GetEnterFromFingerprint
import app.revanced.patches.tiktok.shared.fingerprints.OnRenderFirstFrameFingerprint
import app.revanced.util.exception import app.revanced.util.exception
import app.revanced.util.getReference import app.revanced.util.getReference
import app.revanced.util.indexOfFirstInstructionOrThrow import app.revanced.util.indexOfFirstInstructionOrThrow
import app.revanced.util.resultOrThrow
import com.android.tools.smali.dexlib2.iface.instruction.formats.Instruction11x import com.android.tools.smali.dexlib2.iface.instruction.formats.Instruction11x
import com.android.tools.smali.dexlib2.iface.reference.MethodReference import com.android.tools.smali.dexlib2.iface.reference.MethodReference
@Patch( @Patch(
name = "Playback speed", name = "Playback speed",
description = "Enables the playback speed option for all videos and " + description = "Enables the playback speed option for all videos and " +
"retains the speed configurations in between videos.", "retains the speed configurations in between videos.",
compatiblePackages = [ compatiblePackages = [
CompatiblePackage("com.ss.android.ugc.trill", ["32.5.3"]), CompatiblePackage("com.ss.android.ugc.trill", ["36.5.4"]),
CompatiblePackage("com.zhiliaoapp.musically", ["32.5.3"]) CompatiblePackage("com.zhiliaoapp.musically", ["36.5.4"]),
] ],
) )
@Suppress("unused") @Suppress("unused")
object PlaybackSpeedPatch : BytecodePatch( object PlaybackSpeedPatch : BytecodePatch(
setOf( setOf(
GetSpeedFingerprint, GetSpeedFingerprint,
OnRenderFirstFrameFingerprint, OnRenderFirstFrameFingerprint,
SetSpeedFingerprint SetSpeedFingerprint,
) GetEnterFromFingerprint,
),
) { ) {
override fun execute(context: BytecodeContext) { override fun execute(context: BytecodeContext) {
SetSpeedFingerprint.result?.let { onVideoSwiped -> SetSpeedFingerprint.result?.let { onVideoSwiped ->
@ -44,7 +47,7 @@ object PlaybackSpeedPatch : BytecodePatch(
addInstruction( addInstruction(
injectIndex, injectIndex,
"invoke-static { v$register }," + "invoke-static { v$register }," +
" Lapp/revanced/integrations/tiktok/speed/PlaybackSpeedPatch;->rememberPlaybackSpeed(F)V" " Lapp/revanced/integrations/tiktok/speed/PlaybackSpeedPatch;->rememberPlaybackSpeed(F)V",
) )
} ?: throw GetSpeedFingerprint.exception } ?: throw GetSpeedFingerprint.exception
@ -53,29 +56,29 @@ object PlaybackSpeedPatch : BytecodePatch(
OnRenderFirstFrameFingerprint.result?.mutableMethod?.addInstructions( OnRenderFirstFrameFingerprint.result?.mutableMethod?.addInstructions(
0, 0,
""" """
# Video playback location (e.g. home page, following page or search result page) retrieved using getEnterFrom method. # Video playback location (e.g. home page, following page or search result page) retrieved using getEnterFrom method.
const/4 v0, 0x1 const/4 v0, 0x1
invoke-virtual {p0, v0}, Lcom/ss/android/ugc/aweme/feed/panel/BaseListFragmentPanel;->getEnterFrom(Z)Ljava/lang/String; invoke-virtual {p0, v0}, ${GetEnterFromFingerprint.resultOrThrow().method}
move-result-object v0 move-result-object v0
# Model of current video retrieved using getCurrentAweme method. # Model of current video retrieved using getCurrentAweme method.
invoke-virtual {p0}, Lcom/ss/android/ugc/aweme/feed/panel/BaseListFragmentPanel;->getCurrentAweme()Lcom/ss/android/ugc/aweme/feed/model/Aweme; invoke-virtual {p0}, Lcom/ss/android/ugc/aweme/feed/panel/BaseListFragmentPanel;->getCurrentAweme()Lcom/ss/android/ugc/aweme/feed/model/Aweme;
move-result-object v1 move-result-object v1
# Desired playback speed retrieved using getPlaybackSpeed method. # Desired playback speed retrieved using getPlaybackSpeed method.
invoke-static {}, Lapp/revanced/integrations/tiktok/speed/PlaybackSpeedPatch;->getPlaybackSpeed()F invoke-static {}, Lapp/revanced/integrations/tiktok/speed/PlaybackSpeedPatch;->getPlaybackSpeed()F
move-result-object v2 move-result v2
invoke-static { v0, v1, v2 }, ${onVideoSwiped.method} invoke-static { v0, v1, v2 }, ${onVideoSwiped.method}
""" """,
) ?: throw OnRenderFirstFrameFingerprint.exception ) ?: throw OnRenderFirstFrameFingerprint.exception
// Force enable the playback speed option for all videos. // Force enable the playback speed option for all videos.
onVideoSwiped.mutableClass.methods.find { method -> method.returnType == "Z" }?.addInstructions( onVideoSwiped.mutableClass.methods.find { method -> method.returnType == "Z" }?.addInstructions(
0, 0,
""" """
const/4 v0, 0x1 const/4 v0, 0x1
return v0 return v0
""" """,
) ?: throw PatchException("Failed to force enable the playback speed option.") ) ?: throw PatchException("Failed to force enable the playback speed option.")
} ?: throw SetSpeedFingerprint.exception } ?: throw SetSpeedFingerprint.exception
} }

View File

@ -24,9 +24,9 @@ import com.android.tools.smali.dexlib2.iface.reference.FieldReference
description = "Adds ReVanced settings to TikTok.", description = "Adds ReVanced settings to TikTok.",
dependencies = [IntegrationsPatch::class], dependencies = [IntegrationsPatch::class],
compatiblePackages = [ compatiblePackages = [
CompatiblePackage("com.ss.android.ugc.trill", ["32.5.3"]), CompatiblePackage("com.ss.android.ugc.trill", ["36.5.4"]),
CompatiblePackage("com.zhiliaoapp.musically", ["32.5.3"]) CompatiblePackage("com.zhiliaoapp.musically", ["36.5.4"]),
] ],
) )
object SettingsPatch : BytecodePatch( object SettingsPatch : BytecodePatch(
setOf( setOf(
@ -34,21 +34,21 @@ object SettingsPatch : BytecodePatch(
AddSettingsEntryFingerprint, AddSettingsEntryFingerprint,
SettingsEntryFingerprint, SettingsEntryFingerprint,
SettingsEntryInfoFingerprint, SettingsEntryInfoFingerprint,
) ),
) { ) {
private const val INTEGRATIONS_CLASS_DESCRIPTOR = private const val INTEGRATIONS_CLASS_DESCRIPTOR =
"Lapp/revanced/integrations/tiktok/settings/AdPersonalizationActivityHook;" "Lapp/revanced/integrations/tiktok/settings/AdPersonalizationActivityHook;"
private const val INITIALIZE_SETTINGS_METHOD_DESCRIPTOR = private const val INITIALIZE_SETTINGS_METHOD_DESCRIPTOR =
"$INTEGRATIONS_CLASS_DESCRIPTOR->initialize(" + "$INTEGRATIONS_CLASS_DESCRIPTOR->initialize(" +
"Lcom/bytedance/ies/ugc/aweme/commercialize/compliance/personalization/AdPersonalizationActivity;" + "Lcom/bytedance/ies/ugc/aweme/commercialize/compliance/personalization/AdPersonalizationActivity;" +
")Z" ")Z"
private const val CREATE_SETTINGS_ENTRY_METHOD_DESCRIPTOR = private const val CREATE_SETTINGS_ENTRY_METHOD_DESCRIPTOR =
"$INTEGRATIONS_CLASS_DESCRIPTOR->createSettingsEntry(" + "$INTEGRATIONS_CLASS_DESCRIPTOR->createSettingsEntry(" +
"Ljava/lang/String;" + "Ljava/lang/String;" +
"Ljava/lang/String;" + "Ljava/lang/String;" +
")Ljava/lang/Object;" ")Ljava/lang/Object;"
override fun execute(context: BytecodeContext) { override fun execute(context: BytecodeContext) {
// Find the class name of classes which construct a settings entry // Find the class name of classes which construct a settings entry
@ -70,8 +70,8 @@ object SettingsPatch : BytecodePatch(
markIndex + 2, markIndex + 2,
listOf( listOf(
getUnitManager, getUnitManager,
addEntry addEntry,
) ),
) )
addInstructions( addInstructions(
@ -81,7 +81,8 @@ object SettingsPatch : BytecodePatch(
const-string v1, "$settingsButtonInfoClass" const-string v1, "$settingsButtonInfoClass"
invoke-static {v0, v1}, $CREATE_SETTINGS_ENTRY_METHOD_DESCRIPTOR invoke-static {v0, v1}, $CREATE_SETTINGS_ENTRY_METHOD_DESCRIPTOR
move-result-object v0 move-result-object v0
""" check-cast v0, ${SettingsEntryFingerprint.result!!.classDef}
""",
) )
} ?: throw AddSettingsEntryFingerprint.exception } ?: throw AddSettingsEntryFingerprint.exception
@ -102,12 +103,10 @@ object SettingsPatch : BytecodePatch(
if-eqz v$usableRegister, :do_not_open if-eqz v$usableRegister, :do_not_open
return-void return-void
""", """,
ExternalLabel("do_not_open", getInstruction(initializeSettingsIndex)) ExternalLabel("do_not_open", getInstruction(initializeSettingsIndex)),
) )
} ?: throw AdPersonalizationActivityOnCreateFingerprint.exception } ?: throw AdPersonalizationActivityOnCreateFingerprint.exception
} }
private fun String.toClassName(): String { private fun String.toClassName(): String = substring(1, this.length - 1).replace("/", ".")
return substring(1, this.length - 1).replace("/", ".") }
}
}

View File

@ -0,0 +1,24 @@
package app.revanced.patches.tiktok.shared.fingerprints
import app.revanced.patcher.extensions.or
import app.revanced.patcher.fingerprint.MethodFingerprint
import com.android.tools.smali.dexlib2.AccessFlags
import com.android.tools.smali.dexlib2.Opcode
internal object GetEnterFromFingerprint : MethodFingerprint(
returnType = "Ljava/lang/String;",
accessFlags = AccessFlags.PUBLIC or AccessFlags.FINAL,
parameters = listOf("Z"),
opcodes = listOf(
Opcode.INVOKE_VIRTUAL,
Opcode.MOVE_RESULT,
Opcode.INVOKE_VIRTUAL,
Opcode.MOVE_RESULT_OBJECT,
Opcode.INVOKE_STATIC,
Opcode.MOVE_RESULT_OBJECT,
Opcode.RETURN_OBJECT,
),
customFingerprint = { methodDef, _ ->
methodDef.definingClass.endsWith("/BaseListFragmentPanel;")
},
)

View File

@ -1,9 +1,10 @@
package app.revanced.patches.tiktok.interaction.speed.fingerprints package app.revanced.patches.tiktok.shared.fingerprints
import app.revanced.patcher.fingerprint.MethodFingerprint import app.revanced.patcher.fingerprint.MethodFingerprint
internal object OnRenderFirstFrameFingerprint : MethodFingerprint( internal object OnRenderFirstFrameFingerprint : MethodFingerprint(
strings = listOf("method_enable_viewpager_preload_duration"),
customFingerprint = { methodDef, _ -> customFingerprint = { methodDef, _ ->
methodDef.definingClass.endsWith("/BaseListFragmentPanel;") && methodDef.name == "onRenderFirstFrame" methodDef.definingClass.endsWith("/BaseListFragmentPanel;")
} },
) )

View File

@ -12,7 +12,7 @@ import app.revanced.util.exception
name = "Open links with app chooser", name = "Open links with app chooser",
description = "Instead of opening links directly, open them with an app chooser. " + description = "Instead of opening links directly, open them with an app chooser. " +
"As a result you can select a browser to open the link with.", "As a result you can select a browser to open the link with.",
compatiblePackages = [CompatiblePackage("com.twitter.android")], compatiblePackages = [CompatiblePackage("com.twitter.android", ["10.48.0-release"])],
use = false, use = false,
) )
@Suppress("unused") @Suppress("unused")

View File

@ -99,17 +99,15 @@ object SpoofVideoStreamsPatch : BytecodePatch(
preferences = setOf( preferences = setOf(
SwitchPreference("revanced_spoof_video_streams"), SwitchPreference("revanced_spoof_video_streams"),
ListPreference( ListPreference(
"revanced_spoof_video_streams_client_type", "revanced_spoof_video_streams_client",
summaryKey = null, summaryKey = null
entriesKey = "revanced_spoof_video_streams_client_type_entries",
entryValuesKey = "revanced_spoof_video_streams_client_type_entry_values",
), ),
SwitchPreference( SwitchPreference(
"revanced_spoof_video_streams_ios_force_avc", "revanced_spoof_video_streams_ios_force_avc",
tag = "app.revanced.integrations.youtube.settings.preference.ForceAVCSpoofingPreference", tag = "app.revanced.integrations.youtube.settings.preference.ForceAVCSpoofingPreference",
), ),
NonInteractivePreference("revanced_spoof_video_streams_about_ios"),
NonInteractivePreference("revanced_spoof_video_streams_about_android_vr"), NonInteractivePreference("revanced_spoof_video_streams_about_android_vr"),
NonInteractivePreference("revanced_spoof_video_streams_about_ios"),
), ),
), ),
) )

View File

@ -1,15 +1,15 @@
<resources> <resources>
<app id="youtube"> <app id="youtube">
<patch id="misc.fix.playback.SpoofVideoStreamsPatch"> <patch id="misc.fix.playback.SpoofVideoStreamsPatch">
<string-array name="revanced_spoof_video_streams_client_type_entries"> <string-array name="revanced_spoof_video_streams_client_entries">
<!-- Device and operating systems names are not translatable, so no need to use strings.xml --> <!-- Operating system names are not translatable, so no need to use strings.xml -->
<item>iOS</item>
<item>Android VR</item> <item>Android VR</item>
<item>iOS</item>
</string-array> </string-array>
<string-array name="revanced_spoof_video_streams_client_type_entry_values"> <string-array name="revanced_spoof_video_streams_client_entry_values">
<!-- Enum names from Integrations --> <!-- Enum names from Integrations -->
<item>IOS</item>
<item>ANDROID_VR</item> <item>ANDROID_VR</item>
<item>IOS</item>
</string-array> </string-array>
</patch> </patch>
<patch id="layout.spoofappversion.SpoofAppVersionPatch"> <patch id="layout.spoofappversion.SpoofAppVersionPatch">

View File

@ -1155,16 +1155,16 @@ This is because Crowdin requires temporarily flattening this file and removing t
<string name="revanced_spoof_video_streams_summary_on">Video streams are spoofed</string> <string name="revanced_spoof_video_streams_summary_on">Video streams are spoofed</string>
<string name="revanced_spoof_video_streams_summary_off">Video streams are not spoofed\n\nVideo playback may not work</string> <string name="revanced_spoof_video_streams_summary_off">Video streams are not spoofed\n\nVideo playback may not work</string>
<string name="revanced_spoof_video_streams_user_dialog_message">Turning off this setting may cause video playback issues.</string> <string name="revanced_spoof_video_streams_user_dialog_message">Turning off this setting may cause video playback issues.</string>
<string name="revanced_spoof_video_streams_client_type_title">Default client</string> <string name="revanced_spoof_video_streams_client_title">Default client</string>
<string name="revanced_spoof_video_streams_ios_force_avc_title">Force AVC (H.264)</string> <string name="revanced_spoof_video_streams_ios_force_avc_title">Force AVC (H.264)</string>
<string name="revanced_spoof_video_streams_ios_force_avc_summary_on">Video codec is AVC (H.264)</string> <string name="revanced_spoof_video_streams_ios_force_avc_summary_on">Video codec is AVC (H.264)</string>
<string name="revanced_spoof_video_streams_ios_force_avc_summary_off">Video codec is VP9 or AV1</string> <string name="revanced_spoof_video_streams_ios_force_avc_summary_off">Video codec is VP9 or AV1</string>
<string name="revanced_spoof_video_streams_ios_force_avc_no_hardware_vp9_summary_on">Your device does not have VP9 hardware decoding, and this setting is always on when Client spoofing is enabled</string> <string name="revanced_spoof_video_streams_ios_force_avc_no_hardware_vp9_summary_on">Your device does not have VP9 hardware decoding, and this setting is always on when Client spoofing is enabled</string>
<string name="revanced_spoof_video_streams_ios_force_avc_user_dialog_message">Enabling this might improve battery life and fix playback stuttering.\n\nAVC has a maximum resolution of 1080p, and video playback will use more internet data than VP9 or AV1.</string> <string name="revanced_spoof_video_streams_ios_force_avc_user_dialog_message">Enabling this might improve battery life and fix playback stuttering.\n\nAVC has a maximum resolution of 1080p, and video playback will use more internet data than VP9 or AV1.</string>
<string name="revanced_spoof_video_streams_about_ios_title">iOS spoofing side effects</string> <string name="revanced_spoof_video_streams_about_ios_title">iOS spoofing side effects</string>
<string name="revanced_spoof_video_streams_about_ios_summary">• Movies or paid videos may not play\n• Livestreams start from the beginning</string> <string name="revanced_spoof_video_streams_about_ios_summary">• Movies or paid videos may not play\n• Livestreams start from the beginning\n• Videos may end 1 second early\n• No opus audio codec</string>
<string name="revanced_spoof_video_streams_about_android_vr_title">Android VR spoofing side effects</string> <string name="revanced_spoof_video_streams_about_android_vr_title">Android VR spoofing side effects</string>
<string name="revanced_spoof_video_streams_about_android_vr_summary">• Audio track menu is missing</string> <string name="revanced_spoof_video_streams_about_android_vr_summary">• Audio track menu is missing\n• Stable volume is not available</string>
</patch> </patch>
<!-- This patch is no longer used and these strings will soon be deleted. --> <!-- This patch is no longer used and these strings will soon be deleted. -->
<patch id="video.hdrbrightness.HDRBrightnessPatch"> <patch id="video.hdrbrightness.HDRBrightnessPatch">