mirror of
https://github.com/ReVanced/revanced-patches.git
synced 2026-01-29 05:31:02 +00:00
progress
This commit is contained in:
@@ -1,8 +1,6 @@
|
||||
package app.revanced.patches.spotify.misc.extension
|
||||
|
||||
import app.revanced.patcher.firstMethodComposite
|
||||
import app.revanced.patcher.instructions
|
||||
import app.revanced.patcher.invoke
|
||||
import app.revanced.patcher.*
|
||||
|
||||
internal val loadOrbitLibraryMethodMatch = firstMethodComposite {
|
||||
instructions(
|
||||
|
||||
@@ -1,30 +1,52 @@
|
||||
package app.revanced.patches.spotify.misc.extension
|
||||
|
||||
import app.revanced.patcher.definingClass
|
||||
import app.revanced.patcher.extensions.getInstruction
|
||||
import app.revanced.patcher.extensions.instructions
|
||||
import app.revanced.patcher.instructions
|
||||
import app.revanced.patcher.invoke
|
||||
import app.revanced.patcher.name
|
||||
import app.revanced.patcher.parameterTypes
|
||||
import app.revanced.patcher.returnType
|
||||
import app.revanced.patches.shared.misc.extension.activityOnCreateExtensionHook
|
||||
import app.revanced.patches.shared.misc.extension.extensionHook
|
||||
import app.revanced.patches.spotify.shared.mainActivityOnCreateMethod
|
||||
import app.revanced.util.getReference
|
||||
import app.revanced.util.indexOfFirstInstruction
|
||||
import com.android.tools.smali.dexlib2.AccessFlags
|
||||
import com.android.tools.smali.dexlib2.iface.instruction.TwoRegisterInstruction
|
||||
import com.android.tools.smali.dexlib2.iface.reference.FieldReference
|
||||
|
||||
internal val mainActivityOnCreateHook = extensionHook { mainActivityOnCreateMethod }
|
||||
internal val mainActivityOnCreateHook = activityOnCreateExtensionHook(
|
||||
"Lcom/spotify/music/SpotifyMainActivity;"
|
||||
)
|
||||
|
||||
internal val loadOrbitLibraryHook = extensionHook {
|
||||
// FIXME: Creating this is a mess and needs refactoring.
|
||||
extensionHook(
|
||||
getInsertIndex = {
|
||||
loadOrbitLibraryMethodMatch.stringMatches.last().index
|
||||
},
|
||||
getContextRegister = { method ->
|
||||
val contextReferenceIndex = method.indexOfFirstInstruction {
|
||||
getReference<FieldReference>()?.type == "Landroid/content/Context;"
|
||||
private var contextReferenceIndex = -1
|
||||
|
||||
internal val loadOrbitLibraryHook = extensionHook(
|
||||
getInsertIndex = {
|
||||
// Find the last orbit_library_load string usage
|
||||
var lastIndex = -1
|
||||
instructions.forEachIndexed { index, instruction ->
|
||||
instruction.toString().let {
|
||||
if (it.contains("orbit_library_load") || it.contains("orbit-jni-spotify")) {
|
||||
lastIndex = index
|
||||
}
|
||||
}
|
||||
val contextRegister =
|
||||
method.getInstruction<TwoRegisterInstruction>(contextReferenceIndex).registerA
|
||||
}
|
||||
lastIndex
|
||||
},
|
||||
getContextRegister = {
|
||||
contextReferenceIndex = indexOfFirstInstruction {
|
||||
getReference<FieldReference>()?.type == "Landroid/content/Context;"
|
||||
}
|
||||
val contextRegister =
|
||||
getInstruction<TwoRegisterInstruction>(contextReferenceIndex).registerA
|
||||
|
||||
"v$contextRegister"
|
||||
},
|
||||
fingerprint = loadOrbitLibraryMethodMatch,
|
||||
"v$contextRegister"
|
||||
},
|
||||
) {
|
||||
instructions(
|
||||
"orbit_library_load"(),
|
||||
"orbit-jni-spotify"()
|
||||
)
|
||||
}
|
||||
|
||||
@@ -1,34 +1,30 @@
|
||||
package app.revanced.patches.spotify.misc.privacy
|
||||
|
||||
import app.revanced.patcher.accessFlags
|
||||
import app.revanced.patcher.gettingFirstMethodDeclaratively
|
||||
import app.revanced.patcher.opcodes
|
||||
import app.revanced.patcher.parameterTypes
|
||||
import app.revanced.patcher.*
|
||||
import app.revanced.patcher.patch.BytecodePatchContext
|
||||
import app.revanced.patcher.returnType
|
||||
import app.revanced.util.literal
|
||||
import com.android.tools.smali.dexlib2.AccessFlags
|
||||
import com.android.tools.smali.dexlib2.Opcode
|
||||
|
||||
internal val BytecodePatchContext.shareCopyUrlMethod by gettingFirstMethodDeclaratively {
|
||||
internal val BytecodePatchContext.shareCopyUrlMethod by gettingFirstMutableMethodDeclarativelyOrNull(
|
||||
"clipboard",
|
||||
"Spotify Link",
|
||||
) {
|
||||
name("invokeSuspend")
|
||||
returnType("Ljava/lang/Object;")
|
||||
parameterTypes("Ljava/lang/Object;")
|
||||
strings("clipboard", "Spotify Link")
|
||||
custom { method, _ ->
|
||||
method.name == "invokeSuspend"
|
||||
}
|
||||
}
|
||||
|
||||
internal val BytecodePatchContext.oldShareCopyUrlMethod by gettingFirstMethodDeclaratively {
|
||||
internal val BytecodePatchContext.oldShareCopyUrlMethod by gettingFirstMutableMethodDeclaratively(
|
||||
"clipboard",
|
||||
"createNewSession failed",
|
||||
) {
|
||||
name("apply")
|
||||
returnType("Ljava/lang/Object;")
|
||||
parameterTypes("Ljava/lang/Object;")
|
||||
strings("clipboard", "createNewSession failed")
|
||||
custom { method, _ ->
|
||||
method.name == "apply"
|
||||
}
|
||||
}
|
||||
|
||||
internal val BytecodePatchContext.formatAndroidShareSheetUrlMethod by gettingFirstMethodDeclaratively {
|
||||
internal val BytecodePatchContext.formatAndroidShareSheetUrlMethod by gettingFirstMutableMethodDeclarativelyOrNull {
|
||||
returnType("Ljava/lang/String;")
|
||||
parameterTypes("L", "Ljava/lang/String;")
|
||||
opcodes(
|
||||
@@ -38,16 +34,12 @@ internal val BytecodePatchContext.formatAndroidShareSheetUrlMethod by gettingFir
|
||||
Opcode.MOVE_RESULT_OBJECT,
|
||||
Opcode.RETURN_OBJECT,
|
||||
)
|
||||
literal {
|
||||
'\n'.code.toLong()
|
||||
}
|
||||
literal { '\n'.code.toLong() }
|
||||
}
|
||||
|
||||
internal val BytecodePatchContext.oldFormatAndroidShareSheetUrlMethod by gettingFirstMethodDeclaratively {
|
||||
internal val BytecodePatchContext.oldFormatAndroidShareSheetUrlMethod by gettingFirstMutableMethodDeclaratively {
|
||||
accessFlags(AccessFlags.PUBLIC)
|
||||
returnType("Ljava/lang/String;")
|
||||
parameterTypes("Lcom/spotify/share/social/sharedata/ShareData;", "Ljava/lang/String;")
|
||||
literal {
|
||||
'\n'.code.toLong()
|
||||
}
|
||||
instructions('\n'.code.toLong()())
|
||||
}
|
||||
|
||||
@@ -2,13 +2,12 @@ package app.revanced.patches.spotify.misc.privacy
|
||||
|
||||
import app.revanced.patcher.extensions.addInstructions
|
||||
import app.revanced.patcher.extensions.getInstruction
|
||||
import app.revanced.patcher.extensions.methodReference
|
||||
import app.revanced.patcher.patch.creatingBytecodePatch
|
||||
import app.revanced.patches.spotify.misc.extension.sharedExtensionPatch
|
||||
import app.revanced.util.getReference
|
||||
import app.revanced.util.indexOfFirstInstructionOrThrow
|
||||
import com.android.tools.smali.dexlib2.AccessFlags
|
||||
import com.android.tools.smali.dexlib2.iface.instruction.FiveRegisterInstruction
|
||||
import com.android.tools.smali.dexlib2.iface.reference.MethodReference
|
||||
|
||||
private const val EXTENSION_CLASS_DESCRIPTOR =
|
||||
"Lapp/revanced/extension/spotify/misc/privacy/SanitizeSharingLinksPatch;"
|
||||
@@ -25,15 +24,15 @@ val `Sanitize sharing links` by creatingBytecodePatch(
|
||||
val extensionMethodDescriptor = "$EXTENSION_CLASS_DESCRIPTOR->" +
|
||||
"sanitizeSharingLink(Ljava/lang/String;)Ljava/lang/String;"
|
||||
|
||||
val copyFingerprint = if (shareCopyUrlMethod.immutableMethodOrNull != null) {
|
||||
val copyMethod = if (shareCopyUrlMethod != null) {
|
||||
shareCopyUrlMethod
|
||||
} else {
|
||||
oldShareCopyUrlMethod
|
||||
}
|
||||
|
||||
copyFingerprint.method.apply {
|
||||
copyMethod!!.apply {
|
||||
val newPlainTextInvokeIndex = indexOfFirstInstructionOrThrow {
|
||||
getReference<MethodReference>()?.name == "newPlainText"
|
||||
methodReference?.name == "newPlainText"
|
||||
}
|
||||
val urlRegister = getInstruction<FiveRegisterInstruction>(newPlainTextInvokeIndex).registerD
|
||||
|
||||
@@ -48,9 +47,8 @@ val `Sanitize sharing links` by creatingBytecodePatch(
|
||||
|
||||
// Android native share sheet is used for all other quick share types (X, WhatsApp, etc).
|
||||
val shareUrlParameter: String
|
||||
val shareSheetFingerprint = if (formatAndroidShareSheetUrlMethod.immutableMethodOrNull != null) {
|
||||
val methodAccessFlags = formatAndroidShareSheetUrlMethod.immutableMethod
|
||||
shareUrlParameter = if (AccessFlags.STATIC.isSet(methodAccessFlags.accessFlags)) {
|
||||
val shareSheetMethod = if (formatAndroidShareSheetUrlMethod != null) {
|
||||
shareUrlParameter = if (AccessFlags.STATIC.isSet(formatAndroidShareSheetUrlMethod!!.accessFlags)) {
|
||||
// In newer implementations the method is static, so p0 is not `this`.
|
||||
"p1"
|
||||
} else {
|
||||
@@ -65,7 +63,7 @@ val `Sanitize sharing links` by creatingBytecodePatch(
|
||||
oldFormatAndroidShareSheetUrlMethod
|
||||
}
|
||||
|
||||
shareSheetFingerprint.method.addInstructions(
|
||||
shareSheetMethod!!.addInstructions(
|
||||
0,
|
||||
"""
|
||||
invoke-static { $shareUrlParameter }, $extensionMethodDescriptor
|
||||
|
||||
@@ -1,11 +1,10 @@
|
||||
package app.revanced.patches.spotify.misc.widgets
|
||||
|
||||
import app.revanced.patcher.gettingFirstMethodDeclaratively
|
||||
import app.revanced.patcher.gettingFirstMutableMethodDeclaratively
|
||||
import app.revanced.patcher.opcodes
|
||||
import app.revanced.patcher.patch.BytecodePatchContext
|
||||
import com.android.tools.smali.dexlib2.Opcode
|
||||
|
||||
internal val BytecodePatchContext.canBindAppWidgetPermissionMethod by gettingFirstMethodDeclaratively {
|
||||
strings("android.permission.BIND_APPWIDGET")
|
||||
internal val BytecodePatchContext.canBindAppWidgetPermissionMethod by gettingFirstMutableMethodDeclaratively("android.permission.BIND_APPWIDGET") {
|
||||
opcodes(Opcode.AND_INT_LIT8)
|
||||
}
|
||||
|
||||
@@ -1,19 +1,25 @@
|
||||
package app.revanced.patches.strava.mediaupload
|
||||
|
||||
internal val BytecodePatchContext.getCompressionQualityMethod by gettingFirstMethodDeclaratively {
|
||||
custom { method, _ ->
|
||||
method.name == "getCompressionQuality"
|
||||
}
|
||||
import app.revanced.patcher.definingClass
|
||||
import app.revanced.patcher.firstMutableMethodDeclaratively
|
||||
import app.revanced.patcher.name
|
||||
import app.revanced.patcher.patch.BytecodePatchContext
|
||||
import com.android.tools.smali.dexlib2.iface.ClassDef
|
||||
|
||||
context(_: BytecodePatchContext)
|
||||
internal fun ClassDef.getGetCompressionQualityMethod() = firstMutableMethodDeclaratively {
|
||||
name("getCompressionQuality")
|
||||
definingClass { endsWith("/MediaUploadParameters;") }
|
||||
}
|
||||
|
||||
internal val BytecodePatchContext.getMaxDurationMethod by gettingFirstMethodDeclaratively {
|
||||
custom { method, _ ->
|
||||
method.name == "getMaxDuration"
|
||||
}
|
||||
context(_: BytecodePatchContext)
|
||||
internal fun ClassDef.getGetMaxDurationMethod() = firstMutableMethodDeclaratively {
|
||||
name("getMaxDuration")
|
||||
definingClass { endsWith("/MediaUploadParameters;") }
|
||||
}
|
||||
|
||||
internal val BytecodePatchContext.getMaxSizeMethod by gettingFirstMethodDeclaratively {
|
||||
custom { method, _ ->
|
||||
method.name == "getMaxSize"
|
||||
}
|
||||
context(_: BytecodePatchContext)
|
||||
internal fun ClassDef.getGetMaxSizeMethod() = firstMutableMethodDeclaratively {
|
||||
name("getMaxSize")
|
||||
definingClass { endsWith("/MediaUploadParameters;") }
|
||||
}
|
||||
|
||||
@@ -31,15 +31,15 @@ val `Overwrite media upload parameters` by creatingBytecodePatch(
|
||||
val mediaUploadParametersClass = firstClassDef { type.endsWith("/MediaUploadParameters;") }
|
||||
|
||||
compressionQuality?.let { compressionQuality ->
|
||||
getCompressionQualityMethod.match(mediaUploadParametersClass).method.returnEarly(compressionQuality / 100f)
|
||||
mediaUploadParametersClass.getGetCompressionQualityMethod().returnEarly(compressionQuality / 100f)
|
||||
}
|
||||
|
||||
maxDuration?.let { maxDuration ->
|
||||
getMaxDurationMethod.match(mediaUploadParametersClass).method.returnEarly(maxDuration)
|
||||
mediaUploadParametersClass.getGetMaxDurationMethod().returnEarly(maxDuration)
|
||||
}
|
||||
|
||||
maxSize?.let {
|
||||
getMaxSizeMethod.match(mediaUploadParametersClass).method.returnEarly(it)
|
||||
mediaUploadParametersClass.getGetMaxSizeMethod().returnEarly(it)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
package app.revanced.patches.tiktok.misc.login.disablerequirement
|
||||
|
||||
import app.revanced.patcher.extensions.addInstructions
|
||||
import app.revanced.patcher.patch.creatingBytecodePatch
|
||||
import app.revanced.util.returnEarly
|
||||
|
||||
@Suppress("unused", "ObjectPropertyName")
|
||||
val `Disable login requirement` by creatingBytecodePatch {
|
||||
@@ -14,14 +14,6 @@ val `Disable login requirement` by creatingBytecodePatch {
|
||||
listOf(
|
||||
mandatoryLoginServiceMethod,
|
||||
mandatoryLoginService2Method,
|
||||
).forEach { fingerprint ->
|
||||
fingerprint.method.addInstructions(
|
||||
0,
|
||||
"""
|
||||
const/4 v0, 0x0
|
||||
return v0
|
||||
""",
|
||||
)
|
||||
}
|
||||
).forEach { method -> method.returnEarly() }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,15 +1,14 @@
|
||||
package app.revanced.patches.tiktok.misc.login.disablerequirement
|
||||
|
||||
internal val BytecodePatchContext.mandatoryLoginServiceMethod by gettingFirstMethodDeclaratively {
|
||||
custom { method, classDef ->
|
||||
classDef.endsWith("/MandatoryLoginService;") &&
|
||||
method.name == "enableForcedLogin"
|
||||
}
|
||||
import app.revanced.patcher.*
|
||||
import app.revanced.patcher.patch.BytecodePatchContext
|
||||
|
||||
internal val BytecodePatchContext.mandatoryLoginServiceMethod by gettingFirstMutableMethodDeclaratively {
|
||||
name("enableForcedLogin")
|
||||
definingClass { endsWith("/MandatoryLoginService;") }
|
||||
}
|
||||
|
||||
internal val BytecodePatchContext.mandatoryLoginService2Method by gettingFirstMethodDeclaratively {
|
||||
custom { method, classDef ->
|
||||
classDef.endsWith("/MandatoryLoginService;") &&
|
||||
method.name == "shouldShowForcedLogin"
|
||||
}
|
||||
internal val BytecodePatchContext.mandatoryLoginService2Method by gettingFirstMutableMethodDeclaratively {
|
||||
name("shouldShowForcedLogin")
|
||||
definingClass { endsWith("/MandatoryLoginService;") }
|
||||
}
|
||||
|
||||
@@ -1,9 +1,6 @@
|
||||
package app.revanced.patches.tiktok.misc.settings
|
||||
|
||||
import app.revanced.patcher.definingClass
|
||||
import app.revanced.patcher.gettingFirstMethodDeclaratively
|
||||
import app.revanced.patcher.gettingFirstMutableMethodDeclaratively
|
||||
import app.revanced.patcher.name
|
||||
import app.revanced.patcher.*
|
||||
import app.revanced.patcher.patch.BytecodePatchContext
|
||||
|
||||
internal val BytecodePatchContext.addSettingsEntryMethod by gettingFirstMutableMethodDeclaratively {
|
||||
@@ -20,16 +17,9 @@ internal val BytecodePatchContext.settingsEntryMethod by gettingFirstMethodDecla
|
||||
"pls pass item or extends the EventUnit",
|
||||
)
|
||||
|
||||
internal val BytecodePatchContext.settingsEntryInfoMethod by gettingFirstMethodDeclaratively {
|
||||
strings(
|
||||
"ExposeItem(title=",
|
||||
", icon=",
|
||||
)
|
||||
}
|
||||
internal val BytecodePatchContext.settingsEntryInfoMethod by gettingFirstMethod("ExposeItem(title=", ", icon=")
|
||||
|
||||
internal val BytecodePatchContext.settingsStatusLoadMethod by gettingFirstMethodDeclaratively {
|
||||
custom { method, classDef ->
|
||||
classDef.endsWith("Lapp/revanced/extension/tiktok/settings/SettingsStatus;") &&
|
||||
method.name == "load"
|
||||
}
|
||||
name("load")
|
||||
definingClass { endsWith("Lapp/revanced/extension/tiktok/settings/SettingsStatus;") }
|
||||
}
|
||||
|
||||
@@ -1,15 +1,12 @@
|
||||
package app.revanced.patches.tiktok.shared
|
||||
|
||||
import app.revanced.patcher.accessFlags
|
||||
import app.revanced.patcher.gettingFirstMethodDeclaratively
|
||||
import app.revanced.patcher.opcodes
|
||||
import app.revanced.patcher.parameterTypes
|
||||
import app.revanced.patcher.*
|
||||
import app.revanced.patcher.patch.BytecodePatchContext
|
||||
import app.revanced.patcher.returnType
|
||||
import com.android.tools.smali.dexlib2.AccessFlags
|
||||
import com.android.tools.smali.dexlib2.Opcode
|
||||
|
||||
internal val BytecodePatchContext.getEnterFromMethod by gettingFirstMethodDeclaratively {
|
||||
definingClass { endsWith("/BaseListFragmentPanel;") }
|
||||
returnType("Ljava/lang/String;")
|
||||
accessFlags(AccessFlags.PUBLIC, AccessFlags.FINAL)
|
||||
parameterTypes("Z")
|
||||
@@ -22,14 +19,8 @@ internal val BytecodePatchContext.getEnterFromMethod by gettingFirstMethodDeclar
|
||||
Opcode.MOVE_RESULT_OBJECT,
|
||||
Opcode.RETURN_OBJECT,
|
||||
)
|
||||
custom { methodDef, _ ->
|
||||
methodDef.definingClass.endsWith("/BaseListFragmentPanel;")
|
||||
}
|
||||
}
|
||||
|
||||
internal val BytecodePatchContext.onRenderFirstFrameMethod by gettingFirstMethodDeclaratively {
|
||||
strings("method_enable_viewpager_preload_duration")
|
||||
custom { _, classDef ->
|
||||
classDef.endsWith("/BaseListFragmentPanel;")
|
||||
}
|
||||
internal val BytecodePatchContext.onRenderFirstFrameMethod by gettingFirstMutableMethodDeclaratively("method_enable_viewpager_preload_duration") {
|
||||
definingClass { endsWith("/BaseListFragmentPanel;") }
|
||||
}
|
||||
|
||||
@@ -1,28 +1,16 @@
|
||||
package app.revanced.patches.trakt
|
||||
|
||||
import app.revanced.patcher.custom
|
||||
import app.revanced.patcher.definingClass
|
||||
import app.revanced.patcher.gettingFirstMutableMethodDeclaratively
|
||||
import app.revanced.patcher.name
|
||||
import app.revanced.patcher.patch.BytecodePatchContext
|
||||
|
||||
internal val BytecodePatchContext.isVIPEPMethod by gettingFirstMutableMethodDeclaratively {
|
||||
custom { method, classDef ->
|
||||
if (!classDef.endsWith("RemoteUser;")) return@custom false
|
||||
|
||||
method.name == "isVIPEP"
|
||||
}
|
||||
name("isVIPEP")
|
||||
definingClass { endsWith("RemoteUser;") }
|
||||
}
|
||||
|
||||
internal val BytecodePatchContext.isVIPMethod by gettingFirstMutableMethodDeclaratively {
|
||||
custom { method, classDef ->
|
||||
if (!classDef.endsWith("RemoteUser;")) return@custom false
|
||||
|
||||
method.name == "isVIP"
|
||||
}
|
||||
name("isVIP")
|
||||
definingClass { endsWith("RemoteUser;") }
|
||||
}
|
||||
internal val BytecodePatchContext.remoteUserMethod by gettingFirstMutableMethodDeclaratively {
|
||||
custom { _, classDef ->
|
||||
classDef.endsWith("RemoteUser;")
|
||||
}
|
||||
}
|
||||
|
||||
// TODO
|
||||
@@ -1,20 +1,17 @@
|
||||
package app.revanced.patches.trakt
|
||||
|
||||
import app.revanced.patcher.extensions.addInstructions
|
||||
import app.revanced.patcher.immutableClassDef
|
||||
import app.revanced.patcher.patch.creatingBytecodePatch
|
||||
import com.android.tools.smali.dexlib2.mutable.MutableMethod
|
||||
|
||||
@Suppress("unused", "ObjectPropertyName")
|
||||
val `Unlock pro` by creatingBytecodePatch {
|
||||
compatibleWith("tv.trakt.trakt"("1.1.1"))
|
||||
|
||||
apply {
|
||||
arrayOf(isVIPMethod, isVIPEPMethod).onEach { fingerprint ->
|
||||
// Resolve both fingerprints on the same class.
|
||||
fingerprint.match(remoteUserMethod.immutableClassDef) // TODO
|
||||
}.forEach { fingerprint ->
|
||||
// Return true for both VIP check methods.
|
||||
fingerprint.addInstructions(
|
||||
// Return true for both VIP check methods.
|
||||
arrayOf(isVIPMethod, isVIPEPMethod).forEach { method: MutableMethod ->
|
||||
method.addInstructions(
|
||||
0,
|
||||
"""
|
||||
const/4 v0, 0x1
|
||||
|
||||
@@ -1,19 +1,14 @@
|
||||
package app.revanced.patches.tudortmund.lockscreen
|
||||
|
||||
import app.revanced.patcher.accessFlags
|
||||
import app.revanced.patcher.gettingFirstMethodDeclaratively
|
||||
import app.revanced.patcher.parameterTypes
|
||||
import app.revanced.patcher.*
|
||||
import app.revanced.patcher.patch.BytecodePatchContext
|
||||
import app.revanced.patcher.returnType
|
||||
import com.android.tools.smali.dexlib2.AccessFlags
|
||||
|
||||
internal val BytecodePatchContext.brightnessMethod by gettingFirstMethodDeclaratively {
|
||||
name("run")
|
||||
definingClass { contains("/ScreenPlugin$") }
|
||||
accessFlags(AccessFlags.PUBLIC)
|
||||
returnType("V")
|
||||
parameterTypes()
|
||||
custom { method, classDef ->
|
||||
method.name == "run" &&
|
||||
method.definingClass.contains("/ScreenPlugin\$") &&
|
||||
classDef.fields.any { it.type == "Ljava/lang/Float;" }
|
||||
}
|
||||
custom { immutableClassDef.anyField { type == "Ljava/lang/Float;" } }
|
||||
}
|
||||
|
||||
@@ -1,9 +1,13 @@
|
||||
package app.revanced.patches.tumblr.annoyances.notifications
|
||||
|
||||
import app.revanced.patcher.gettingFirstMutableMethod
|
||||
import app.revanced.patcher.patch.BytecodePatchContext
|
||||
|
||||
// The BlogNotifyCtaDialog asks you if you want to enable notifications for a blog.
|
||||
// It shows whenever you visit a certain blog for the second time and disables itself
|
||||
// if it was shown a total of 3 times (stored in app storage).
|
||||
// This targets the BlogNotifyCtaDialog.isEnabled() method to let it always return false.
|
||||
internal val BytecodePatchContext.isBlogNotifyEnabledMethod by gettingFirstMethodDeclaratively {
|
||||
strings("isEnabled --> ", "blog_notify_enabled")
|
||||
}
|
||||
internal val BytecodePatchContext.isBlogNotifyEnabledMethod by gettingFirstMutableMethod(
|
||||
"isEnabled --> ",
|
||||
"blog_notify_enabled",
|
||||
)
|
||||
|
||||
@@ -3,7 +3,7 @@ package app.revanced.patches.twitch.ad.shared.util
|
||||
import app.revanced.patcher.extensions.ExternalLabel
|
||||
import app.revanced.patcher.extensions.addInstructionsWithLabels
|
||||
import app.revanced.patcher.extensions.getInstruction
|
||||
import app.revanced.patcher.firstClassDefMutableOrNull
|
||||
import app.revanced.patcher.firstMutableClassDefOrNull
|
||||
import app.revanced.patcher.patch.BytecodePatchBuilder
|
||||
import app.revanced.patcher.patch.BytecodePatchContext
|
||||
import app.revanced.patcher.patch.bytecodePatch
|
||||
@@ -30,10 +30,10 @@ fun adPatch(
|
||||
classDefType: String,
|
||||
methodNames: Set<String>,
|
||||
returnMethod: ReturnMethod,
|
||||
) = with(firstClassDefMutableOrNull(classDefType)) {
|
||||
this ?: return false
|
||||
): Boolean {
|
||||
val classDef = firstMutableClassDefOrNull(classDefType) ?: return false
|
||||
|
||||
methods.filter { it.name in methodNames }.forEach {
|
||||
classDef.methods.filter { it.name in methodNames }.forEach { method ->
|
||||
val retInstruction = when (returnMethod.returnType) {
|
||||
'V' -> "return-void"
|
||||
'Z' ->
|
||||
@@ -45,17 +45,17 @@ fun adPatch(
|
||||
else -> throw NotImplementedError()
|
||||
}
|
||||
|
||||
it.addInstructionsWithLabels(
|
||||
method.addInstructionsWithLabels(
|
||||
0,
|
||||
"""
|
||||
${createConditionInstructions("v0")}
|
||||
$retInstruction
|
||||
""",
|
||||
ExternalLabel(skipLabelName, it.getInstruction(0)),
|
||||
ExternalLabel(skipLabelName, method.getInstruction(0)),
|
||||
)
|
||||
}
|
||||
|
||||
true
|
||||
return true
|
||||
}
|
||||
|
||||
block(::createConditionInstructions, BytecodePatchContext::blockMethods)
|
||||
|
||||
@@ -145,7 +145,7 @@ val Settings by creatingBytecodePatch(
|
||||
)
|
||||
|
||||
// Intercept onclick events for the settings menu
|
||||
menuGroupsOnClickFingerprint.method.addInstructionsWithLabels(
|
||||
menuGroupsOnClickMethod.addInstructionsWithLabels(
|
||||
0,
|
||||
"""
|
||||
invoke-static {p1}, $ACTIVITY_HOOKS_CLASS_DESCRIPTOR->handleSettingMenuOnClick(Ljava/lang/Enum;)Z
|
||||
@@ -157,7 +157,7 @@ val Settings by creatingBytecodePatch(
|
||||
""",
|
||||
ExternalLabel(
|
||||
"no_rv_settings_onclick",
|
||||
menuGroupsOnClickFingerprint.method.getInstruction(0),
|
||||
menuGroupsOnClickMethod.getInstruction(0),
|
||||
),
|
||||
)
|
||||
}
|
||||
|
||||
@@ -1,36 +1,29 @@
|
||||
package app.revanced.patches.twitter.misc.links
|
||||
|
||||
import app.revanced.patcher.accessFlags
|
||||
import app.revanced.patcher.gettingFirstMethodDeclaratively
|
||||
import app.revanced.patcher.parameterTypes
|
||||
import app.revanced.patcher.*
|
||||
import app.revanced.patcher.patch.BytecodePatchContext
|
||||
import app.revanced.patcher.returnType
|
||||
import com.android.tools.smali.dexlib2.AccessFlags
|
||||
|
||||
internal val BytecodePatchContext.sanitizeSharingLinksMethod by gettingFirstMethodDeclaratively {
|
||||
returnType("Ljava/lang/String;")
|
||||
strings("<this>", "shareParam", "sessionToken")
|
||||
}
|
||||
internal val BytecodePatchContext.sanitizeSharingLinksMethod by gettingFirstMutableMethod(
|
||||
"<this>",
|
||||
"shareParam",
|
||||
"sessionToken",
|
||||
) { returnType == "Ljava/lang/String;" }
|
||||
|
||||
// Returns a shareable link string based on a tweet ID and a username.
|
||||
internal val BytecodePatchContext.linkBuilderMethod by gettingFirstMethodDeclaratively {
|
||||
strings("/%1\$s/status/%2\$d")
|
||||
}
|
||||
internal val BytecodePatchContext.linkBuilderMethod by gettingFirstMutableMethod($$"/%1$s/status/%2$d")
|
||||
|
||||
// TODO remove this once changeLinkSharingDomainResourcePatch is restored
|
||||
// Returns a shareable link for the "Share via..." dialog.
|
||||
internal val BytecodePatchContext.linkResourceGetterMethod by gettingFirstMethodDeclaratively {
|
||||
internal val BytecodePatchContext.linkResourceGetterMethod by gettingFirstMutableMethodDeclaratively {
|
||||
accessFlags(AccessFlags.PUBLIC, AccessFlags.FINAL)
|
||||
parameterTypes("Landroid/content/res/Resources;")
|
||||
custom { _, classDef ->
|
||||
classDef.fields.any { field ->
|
||||
field.type.startsWith("Lcom/twitter/model/core/")
|
||||
}
|
||||
custom {
|
||||
immutableClassDef.anyField { type.startsWith("Lcom/twitter/model/core/") }
|
||||
}
|
||||
}
|
||||
|
||||
internal val BytecodePatchContext.linkSharingDomainHelperMethod by gettingFirstMethodDeclaratively {
|
||||
custom { method, classDef ->
|
||||
method.name == "getShareDomain" && classDef.type == EXTENSION_CLASS_DESCRIPTOR
|
||||
}
|
||||
internal val BytecodePatchContext.linkSharingDomainHelperMethod by gettingFirstMutableMethodDeclaratively {
|
||||
name("getShareDomain")
|
||||
definingClass(EXTENSION_CLASS_DESCRIPTOR)
|
||||
}
|
||||
|
||||
@@ -1,18 +1,16 @@
|
||||
package app.revanced.patches.viber.misc.navbar
|
||||
import app.revanced.patcher.gettingFirstMethodDeclaratively
|
||||
|
||||
import app.revanced.patcher.firstMutableMethodDeclaratively
|
||||
import app.revanced.patcher.gettingFirstMethod
|
||||
import app.revanced.patcher.parameterTypes
|
||||
import app.revanced.patcher.patch.BytecodePatchContext
|
||||
import app.revanced.patcher.returnType
|
||||
import com.android.tools.smali.dexlib2.iface.ClassDef
|
||||
|
||||
internal val BytecodePatchContext.tabIdClassMethod by gettingFirstMethodDeclaratively {
|
||||
strings("shouldShowTabId")
|
||||
}
|
||||
internal val BytecodePatchContext.tabIdClassMethod by gettingFirstMethod("shouldShowTabId")
|
||||
|
||||
context(BytecodePatchContext)
|
||||
internal val shouldShowTabIdMethodFingerprint get() = fingerprint {
|
||||
context(_: BytecodePatchContext)
|
||||
internal fun ClassDef.getShouldShowTabIdMethod() = firstMutableMethodDeclaratively {
|
||||
parameterTypes("I", "I")
|
||||
returnType("Z")
|
||||
custom { methodDef, classDef ->
|
||||
classDef == tabIdClassMethod.classDef
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package app.revanced.patches.viber.misc.navbar
|
||||
|
||||
import app.revanced.patcher.extensions.addInstructionsWithLabels
|
||||
import app.revanced.patcher.immutableClassDef
|
||||
import app.revanced.patcher.patch.booleanOption
|
||||
import app.revanced.patcher.patch.creatingBytecodePatch
|
||||
import java.util.logging.Logger
|
||||
@@ -8,7 +9,7 @@ import java.util.logging.Logger
|
||||
@Suppress("unused", "ObjectPropertyName")
|
||||
val `Hide navigation buttons` by creatingBytecodePatch(
|
||||
description = "Permanently hides navigation bar buttons, such as Explore and Marketplace.",
|
||||
use = false
|
||||
use = false,
|
||||
) {
|
||||
compatibleWith("com.viber.voip")
|
||||
|
||||
@@ -26,7 +27,7 @@ val `Hide navigation buttons` by creatingBytecodePatch(
|
||||
|
||||
if (allowedItems.size == AllowedNavigationItems.entries.size) {
|
||||
return@apply Logger.getLogger(this::class.java.name).warning(
|
||||
"No hide navigation buttons options are enabled. No changes applied."
|
||||
"No hide navigation buttons options are enabled. No changes applied.",
|
||||
)
|
||||
}
|
||||
|
||||
@@ -42,7 +43,7 @@ val `Hide navigation buttons` by creatingBytecodePatch(
|
||||
nop
|
||||
"""
|
||||
|
||||
shouldShowTabIdMethodFingerprint.method
|
||||
tabIdClassMethod.immutableClassDef.getShouldShowTabIdMethod()
|
||||
.addInstructionsWithLabels(0, injectionInstructions)
|
||||
}
|
||||
}
|
||||
@@ -54,7 +55,7 @@ val `Hide navigation buttons` by creatingBytecodePatch(
|
||||
private enum class AllowedNavigationItems(
|
||||
val defaultHideOption: Boolean,
|
||||
private val itemName: String,
|
||||
private vararg val ids: Int
|
||||
private vararg val ids: Int,
|
||||
) {
|
||||
CHATS(false, "Chats", 0),
|
||||
CALLS(false, "Calls", 1, 7),
|
||||
@@ -62,16 +63,16 @@ private enum class AllowedNavigationItems(
|
||||
MORE(false, "More", 3),
|
||||
PAY(true, "Pay", 5),
|
||||
CAMERA(true, "Camera", 6),
|
||||
MARKETPLACE(true, "Marketplace", 8);
|
||||
MARKETPLACE(true, "Marketplace", 8),
|
||||
;
|
||||
|
||||
val optionName = "Hide $itemName"
|
||||
val description = "Permanently hides the $itemName button."
|
||||
|
||||
fun buildAllowInstruction(): String =
|
||||
ids.joinToString("\n") { id ->
|
||||
"""
|
||||
fun buildAllowInstruction(): String = ids.joinToString("\n") { id ->
|
||||
"""
|
||||
const/4 v0, $id # If tabId == $id ($itemName), don't hide it
|
||||
if-eq p1, v0, :continue
|
||||
"""
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package app.revanced.patches.youtube.ad.general
|
||||
|
||||
import app.revanced.patcher.accessFlags
|
||||
import app.revanced.patcher.custom
|
||||
import app.revanced.patcher.gettingFirstMethodDeclaratively
|
||||
import app.revanced.patcher.parameterTypes
|
||||
import app.revanced.patcher.patch.BytecodePatchContext
|
||||
@@ -16,9 +17,9 @@ internal val BytecodePatchContext.fullScreenEngagementAdContainerMethod by getti
|
||||
accessFlags(AccessFlags.PUBLIC, AccessFlags.FINAL)
|
||||
returnType("V")
|
||||
parameterTypes()
|
||||
custom { method, _ ->
|
||||
method.containsLiteralInstruction(fullScreenEngagementAdContainer) &&
|
||||
indexOfAddListInstruction(method) >= 0
|
||||
custom {
|
||||
containsLiteralInstruction(fullScreenEngagementAdContainer) &&
|
||||
indexOfAddListInstruction(this) >= 0
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
package app.revanced.patches.youtube.ad.video
|
||||
|
||||
internal val BytecodePatchContext.loadVideoAdsMethod by gettingFirstMethodDeclaratively {
|
||||
strings(
|
||||
"TriggerBundle doesn't have the required metadata specified by the trigger ",
|
||||
"Ping migration no associated ping bindings for activated trigger: ",
|
||||
)
|
||||
}
|
||||
import app.revanced.patcher.gettingFirstMethod
|
||||
import app.revanced.patcher.patch.BytecodePatchContext
|
||||
|
||||
internal val BytecodePatchContext.loadVideoAdsMethod by gettingFirstMethod(
|
||||
"TriggerBundle doesn't have the required metadata specified by the trigger ",
|
||||
"Ping migration no associated ping bindings for activated trigger: ",
|
||||
)
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package app.revanced.patches.youtube.interaction.doubletap
|
||||
|
||||
import app.revanced.patcher.*
|
||||
import app.revanced.patcher.extensions.addInstructions
|
||||
import app.revanced.patcher.patch.creatingBytecodePatch
|
||||
import app.revanced.patches.all.misc.resources.addResources
|
||||
@@ -13,7 +14,6 @@ import app.revanced.patches.youtube.misc.settings.settingsPatch
|
||||
import com.android.tools.smali.dexlib2.AccessFlags
|
||||
import com.android.tools.smali.dexlib2.Opcode
|
||||
import java.util.logging.Logger
|
||||
import kotlin.jvm.java
|
||||
|
||||
private const val EXTENSION_CLASS_DESCRIPTOR =
|
||||
"Lapp/revanced/extension/youtube/patches/DisableDoubleTapActionsPatch;"
|
||||
@@ -53,7 +53,7 @@ val `Disable double tap actions` by creatingBytecodePatch(
|
||||
SwitchPreference("revanced_disable_chapter_skip_double_tap"),
|
||||
)
|
||||
|
||||
val doubleTapInfoGetSeekSourceFingerprint = fingerprint {
|
||||
val doubleTapInfoGetSeekSourceMethod = firstMutableMethodDeclaratively {
|
||||
accessFlags(AccessFlags.PUBLIC, AccessFlags.FINAL)
|
||||
parameterTypes("Z")
|
||||
returnType(seekTypeEnumMethod.immutableClassDef.type)
|
||||
@@ -64,13 +64,11 @@ val `Disable double tap actions` by creatingBytecodePatch(
|
||||
Opcode.SGET_OBJECT,
|
||||
Opcode.RETURN_OBJECT,
|
||||
)
|
||||
custom { _, classDef ->
|
||||
classDef.fields.count() == 4
|
||||
}
|
||||
custom { immutableClassDef.fields.count() == 4 }
|
||||
}
|
||||
|
||||
// Force isChapterSeek flag to false.
|
||||
doubleTapInfoGetSeekSourceFingerprint.method.addInstructions(
|
||||
doubleTapInfoGetSeekSourceMethod.addInstructions(
|
||||
0,
|
||||
"""
|
||||
invoke-static { p1 }, $EXTENSION_CLASS_DESCRIPTOR->disableDoubleTapChapters(Z)Z
|
||||
@@ -78,9 +76,7 @@ val `Disable double tap actions` by creatingBytecodePatch(
|
||||
""",
|
||||
)
|
||||
|
||||
doubleTapInfoCtorMethod.match(
|
||||
doubleTapInfoGetSeekSourceFingerprint.classDef,
|
||||
).method.addInstructions(
|
||||
doubleTapInfoGetSeekSourceMethod.immutableClassDef.getDoubleTapInfoCtorMethod().addInstructions(
|
||||
0,
|
||||
"""
|
||||
invoke-static { p3 }, $EXTENSION_CLASS_DESCRIPTOR->disableDoubleTapChapters(Z)Z
|
||||
|
||||
@@ -1,25 +1,27 @@
|
||||
package app.revanced.patches.youtube.interaction.doubletap
|
||||
|
||||
import app.revanced.patcher.accessFlags
|
||||
import app.revanced.patcher.firstMutableMethodDeclaratively
|
||||
import app.revanced.patcher.gettingFirstMethodDeclaratively
|
||||
import app.revanced.patcher.parameterTypes
|
||||
import app.revanced.patcher.patch.BytecodePatchContext
|
||||
import com.android.tools.smali.dexlib2.AccessFlags
|
||||
import com.android.tools.smali.dexlib2.iface.ClassDef
|
||||
|
||||
internal val BytecodePatchContext.seekTypeEnumMethod by gettingFirstMethodDeclaratively {
|
||||
internal val BytecodePatchContext.seekTypeEnumMethod by gettingFirstMethodDeclaratively(
|
||||
"SEEK_SOURCE_SEEK_TO_NEXT_CHAPTER",
|
||||
"SEEK_SOURCE_SEEK_TO_PREVIOUS_CHAPTER",
|
||||
) {
|
||||
accessFlags(AccessFlags.STATIC, AccessFlags.CONSTRUCTOR)
|
||||
strings(
|
||||
"SEEK_SOURCE_SEEK_TO_NEXT_CHAPTER",
|
||||
"SEEK_SOURCE_SEEK_TO_PREVIOUS_CHAPTER",
|
||||
)
|
||||
}
|
||||
|
||||
internal val BytecodePatchContext.doubleTapInfoCtorMethod by gettingFirstMethodDeclaratively {
|
||||
context(_: BytecodePatchContext)
|
||||
internal fun ClassDef.getDoubleTapInfoCtorMethod() = firstMutableMethodDeclaratively {
|
||||
accessFlags(AccessFlags.PUBLIC, AccessFlags.CONSTRUCTOR)
|
||||
parameterTypes(
|
||||
"Landroid/view/MotionEvent;",
|
||||
"I",
|
||||
"Z",
|
||||
"Lj\$/time/Duration;",
|
||||
"Lj$/time/Duration;",
|
||||
)
|
||||
}
|
||||
|
||||
@@ -1,11 +1,7 @@
|
||||
package app.revanced.patches.youtube.interaction.downloads
|
||||
|
||||
import app.revanced.patcher.accessFlags
|
||||
import app.revanced.patcher.gettingFirstMethodDeclaratively
|
||||
import app.revanced.patcher.instructions
|
||||
import app.revanced.patcher.parameterTypes
|
||||
import app.revanced.patcher.*
|
||||
import app.revanced.patcher.patch.BytecodePatchContext
|
||||
import app.revanced.patcher.returnType
|
||||
import com.android.tools.smali.dexlib2.AccessFlags
|
||||
|
||||
internal val BytecodePatchContext.offlineVideoEndpointMethod by gettingFirstMethodDeclaratively {
|
||||
|
||||
@@ -1,32 +1,27 @@
|
||||
package app.revanced.patches.youtube.layout.autocaptions
|
||||
|
||||
import app.revanced.patcher.accessFlags
|
||||
import app.revanced.patcher.gettingFirstMethodDeclaratively
|
||||
import app.revanced.patcher.opcodes
|
||||
import app.revanced.patcher.parameterTypes
|
||||
import app.revanced.patcher.*
|
||||
import app.revanced.patcher.patch.BytecodePatchContext
|
||||
import app.revanced.patcher.returnType
|
||||
import com.android.tools.smali.dexlib2.AccessFlags
|
||||
import com.android.tools.smali.dexlib2.Opcode
|
||||
|
||||
internal val BytecodePatchContext.startVideoInformerMethod by gettingFirstMethodDeclaratively {
|
||||
internal val BytecodePatchContext.startVideoInformerMethod by gettingFirstMethodDeclaratively("pc") {
|
||||
accessFlags(AccessFlags.PUBLIC, AccessFlags.FINAL)
|
||||
returnType("V")
|
||||
opcodes(
|
||||
Opcode.INVOKE_INTERFACE,
|
||||
Opcode.RETURN_VOID,
|
||||
)
|
||||
strings("pc")
|
||||
}
|
||||
|
||||
internal val BytecodePatchContext.storyboardRendererDecoderRecommendedLevelMethod by gettingFirstMethodDeclaratively {
|
||||
internal val BytecodePatchContext.storyboardRendererDecoderRecommendedLevelMethod by gettingFirstMethodDeclaratively("#-1#") {
|
||||
returnType("V")
|
||||
accessFlags(AccessFlags.PUBLIC, AccessFlags.FINAL)
|
||||
parameterTypes("L")
|
||||
strings("#-1#")
|
||||
}
|
||||
|
||||
internal val BytecodePatchContext.subtitleTrackMethod by gettingFirstMethodDeclaratively {
|
||||
internal val BytecodePatchContext.subtitleTrackMethod by gettingFirstMethodDeclaratively("DISABLE_CAPTIONS_OPTION") {
|
||||
definingClass { endsWith("/SubtitleTrack;") }
|
||||
accessFlags(AccessFlags.PUBLIC, AccessFlags.FINAL)
|
||||
returnType("Z")
|
||||
parameterTypes()
|
||||
@@ -38,8 +33,4 @@ internal val BytecodePatchContext.subtitleTrackMethod by gettingFirstMethodDecla
|
||||
Opcode.MOVE_RESULT,
|
||||
Opcode.RETURN,
|
||||
)
|
||||
strings("DISABLE_CAPTIONS_OPTION")
|
||||
custom { _, classDef ->
|
||||
classDef.endsWith("/SubtitleTrack;")
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
package app.revanced.patches.youtube.layout.formfactor
|
||||
|
||||
import app.revanced.patcher.*
|
||||
import app.revanced.patcher.extensions.addInstructions
|
||||
import app.revanced.patcher.extensions.getInstruction
|
||||
import app.revanced.patcher.instructions
|
||||
import app.revanced.patcher.patch.creatingBytecodePatch
|
||||
import app.revanced.patches.all.misc.resources.addResources
|
||||
import app.revanced.patches.all.misc.resources.addResourcesPatch
|
||||
@@ -46,21 +46,19 @@ val `Change form factor` by creatingBytecodePatch(
|
||||
|
||||
hookNavigationButtonCreated(EXTENSION_CLASS_DESCRIPTOR)
|
||||
|
||||
val createPlayerRequestBodyWithModelFingerprint = fingerprint {
|
||||
val formFactorEnumConstructorClass = formFactorEnumConstructorMethod.definingClass
|
||||
|
||||
val createPlayerRequestBodyWithModelMatch = firstMethodComposite {
|
||||
accessFlags(AccessFlags.PUBLIC, AccessFlags.FINAL)
|
||||
returnType("L")
|
||||
parameterTypes()
|
||||
instructions(
|
||||
fieldAccess(smali = "Landroid/os/Build;->MODEL:Ljava/lang/String;"),
|
||||
fieldAccess(
|
||||
definingClass = formFactorEnumConstructorMethod.immutableClassDef.type,
|
||||
type = "I",
|
||||
afterAtMost(50),
|
||||
),
|
||||
field { name == "MODEL" && definingClass == "Landroid/os/Build;" },
|
||||
field { type == "I" && definingClass == formFactorEnumConstructorClass },
|
||||
)
|
||||
}
|
||||
|
||||
createPlayerRequestBodyWithModelFingerprint.let {
|
||||
createPlayerRequestBodyWithModelMatch.let {
|
||||
it.method.apply {
|
||||
val index = it.indices.last()
|
||||
val register = getInstruction<TwoRegisterInstruction>(index).registerA
|
||||
|
||||
@@ -5,12 +5,11 @@ import app.revanced.patcher.gettingFirstMethodDeclaratively
|
||||
import app.revanced.patcher.patch.BytecodePatchContext
|
||||
import com.android.tools.smali.dexlib2.AccessFlags
|
||||
|
||||
internal val BytecodePatchContext.formFactorEnumConstructorMethod by gettingFirstMethodDeclaratively {
|
||||
internal val BytecodePatchContext.formFactorEnumConstructorMethod by gettingFirstMethodDeclaratively(
|
||||
"UNKNOWN_FORM_FACTOR",
|
||||
"SMALL_FORM_FACTOR",
|
||||
"LARGE_FORM_FACTOR",
|
||||
"AUTOMOTIVE_FORM_FACTOR",
|
||||
) {
|
||||
accessFlags(AccessFlags.STATIC, AccessFlags.CONSTRUCTOR)
|
||||
strings(
|
||||
"UNKNOWN_FORM_FACTOR",
|
||||
"SMALL_FORM_FACTOR",
|
||||
"LARGE_FORM_FACTOR",
|
||||
"AUTOMOTIVE_FORM_FACTOR",
|
||||
)
|
||||
}
|
||||
|
||||
@@ -1,18 +1,13 @@
|
||||
package app.revanced.patches.youtube.layout.hide.fullscreenambientmode
|
||||
|
||||
import app.revanced.patcher.accessFlags
|
||||
import app.revanced.patcher.gettingFirstMethodDeclaratively
|
||||
import app.revanced.patcher.parameterTypes
|
||||
import app.revanced.patcher.*
|
||||
import app.revanced.patcher.patch.BytecodePatchContext
|
||||
import app.revanced.patcher.returnType
|
||||
import com.android.tools.smali.dexlib2.AccessFlags
|
||||
|
||||
internal val BytecodePatchContext.setFullScreenBackgroundColorMethod by gettingFirstMethodDeclaratively {
|
||||
name("onLayout")
|
||||
definingClass { endsWith("/YouTubePlayerViewNotForReflection;") }
|
||||
returnType("V")
|
||||
accessFlags(AccessFlags.PROTECTED, AccessFlags.FINAL)
|
||||
parameterTypes("Z", "I", "I", "I", "I")
|
||||
custom { method, classDef ->
|
||||
classDef.type.endsWith("/YouTubePlayerViewNotForReflection;") &&
|
||||
method.name == "onLayout"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,10 +2,10 @@ package app.revanced.patches.youtube.layout.hide.shorts
|
||||
|
||||
import app.revanced.patcher.accessFlags
|
||||
import app.revanced.patcher.after
|
||||
import app.revanced.patcher.at
|
||||
import app.revanced.patcher.gettingFirstMethodDeclaratively
|
||||
import app.revanced.patcher.instructions
|
||||
import app.revanced.patcher.invoke
|
||||
import app.revanced.patcher.method
|
||||
import app.revanced.patcher.opcodes
|
||||
import app.revanced.patcher.parameterTypes
|
||||
import app.revanced.patcher.patch.BytecodePatchContext
|
||||
@@ -21,7 +21,7 @@ internal val BytecodePatchContext.shortsBottomBarContainerMethod by gettingFirst
|
||||
instructions(
|
||||
"r_pfvc"(),
|
||||
ResourceType.ID("bottom_bar_container"),
|
||||
methodCall(name = "getHeight"),
|
||||
method("getHeight"),
|
||||
Opcode.MOVE_RESULT(),
|
||||
)
|
||||
}
|
||||
|
||||
@@ -5,6 +5,7 @@ import app.revanced.patcher.extensions.addInstructions
|
||||
import app.revanced.patcher.extensions.getInstruction
|
||||
import app.revanced.patcher.extensions.wideLiteral
|
||||
import app.revanced.patcher.patch.booleanOption
|
||||
import app.revanced.patcher.patch.creatingBytecodePatch
|
||||
import app.revanced.patcher.patch.resourcePatch
|
||||
import app.revanced.patches.all.misc.resources.addResources
|
||||
import app.revanced.patches.all.misc.resources.addResourcesPatch
|
||||
@@ -95,7 +96,8 @@ private val hideShortsComponentsResourcePatch = resourcePatch {
|
||||
SwitchPreference("revanced_hide_shorts_effect_button"),
|
||||
SwitchPreference("revanced_hide_shorts_green_screen_button"),
|
||||
SwitchPreference("revanced_hide_shorts_hashtag_button"),
|
||||
SwitchPreference("revanced_hide_shorts_live_preview"), SwitchPreference("revanced_hide_shorts_new_posts_button"),
|
||||
SwitchPreference("revanced_hide_shorts_live_preview"),
|
||||
SwitchPreference("revanced_hide_shorts_new_posts_button"),
|
||||
SwitchPreference("revanced_hide_shorts_shop_button"),
|
||||
SwitchPreference("revanced_hide_shorts_tagged_products"),
|
||||
SwitchPreference("revanced_hide_shorts_search_suggestions"),
|
||||
@@ -103,7 +105,8 @@ private val hideShortsComponentsResourcePatch = resourcePatch {
|
||||
SwitchPreference("revanced_hide_shorts_stickers"),
|
||||
|
||||
// Bottom of the screen.
|
||||
SwitchPreference("revanced_hide_shorts_auto_dubbed_label"), SwitchPreference("revanced_hide_shorts_location_label"),
|
||||
SwitchPreference("revanced_hide_shorts_auto_dubbed_label"),
|
||||
SwitchPreference("revanced_hide_shorts_location_label"),
|
||||
SwitchPreference("revanced_hide_shorts_channel_bar"),
|
||||
SwitchPreference("revanced_hide_shorts_info_panel"),
|
||||
SwitchPreference("revanced_hide_shorts_full_video_link_label"),
|
||||
@@ -154,7 +157,7 @@ private val hideShortsComponentsResourcePatch = resourcePatch {
|
||||
private const val FILTER_CLASS_DESCRIPTOR = "Lapp/revanced/extension/youtube/patches/components/ShortsFilter;"
|
||||
|
||||
@Suppress("unused", "ObjectPropertyName")
|
||||
val `Hide Shorts componentsby creatingBytecodePatch(
|
||||
val `Hide Shorts components` by creatingBytecodePatch(
|
||||
description = "Adds options to hide components related to Shorts.",
|
||||
) {
|
||||
dependsOn(
|
||||
|
||||
Reference in New Issue
Block a user