feat(Reddit - Hide navigation buttons): Add support for latest versions

This commit is contained in:
inotia00 2025-01-16 12:36:54 +09:00
parent a1a775cdf8
commit 9e9b170a82
4 changed files with 83 additions and 45 deletions

View File

@ -3,7 +3,9 @@ package app.revanced.extension.reddit.patches;
import android.view.View;
import android.view.ViewGroup;
import java.util.Arrays;
import java.util.List;
import java.util.Objects;
import app.revanced.extension.reddit.settings.Settings;
import app.revanced.extension.shared.utils.Logger;
@ -24,6 +26,22 @@ public final class NavigationButtonsPatch {
return list;
}
public static Object[] hideNavigationButtons(Object[] array) {
try {
for (NavigationButton button : NavigationButton.values()) {
if (button.enabled && array.length > button.index) {
Object buttonObject = array[button.index];
array = Arrays.stream(array)
.filter(item -> !Objects.equals(item, buttonObject))
.toArray(Object[]::new);
}
}
} catch (Exception exception) {
Logger.printException(() -> "Failed to remove button array", exception);
}
return array;
}
public static void hideNavigationButtons(ViewGroup viewGroup) {
try {
if (viewGroup == null) return;

View File

@ -57,7 +57,18 @@ internal val bottomNavScreenOnGlobalLayoutFingerprint = legacyFingerprint(
Opcode.INVOKE_VIRTUAL,
Opcode.RETURN_VOID
),
customFingerprint = { methodDef, _ ->
methodDef.name == "onGlobalLayout"
customFingerprint = { method, _ ->
method.name == "onGlobalLayout"
}
)
internal val bottomNavScreenSetupBottomNavigationFingerprint = legacyFingerprint(
name = "bottomNavScreenSetupBottomNavigationFingerprint",
returnType = "V",
accessFlags = AccessFlags.PUBLIC or AccessFlags.FINAL,
opcodes = listOf(Opcode.FILLED_NEW_ARRAY),
customFingerprint = { method, classDef ->
classDef.type.startsWith("Lcom/reddit/launch/bottomnav/BottomNavScreen${'$'}setupBottomNavigation${'$'}") &&
method.name == "invoke"
}
)

View File

@ -7,13 +7,13 @@ import app.revanced.patcher.patch.bytecodePatch
import app.revanced.patches.reddit.utils.compatibility.Constants.COMPATIBLE_PACKAGE
import app.revanced.patches.reddit.utils.extension.Constants.PATCHES_PATH
import app.revanced.patches.reddit.utils.patch.PatchList.HIDE_NAVIGATION_BUTTONS
import app.revanced.patches.reddit.utils.settings.is_2024_18_or_greater
import app.revanced.patches.reddit.utils.settings.is_2024_26_or_greater
import app.revanced.patches.reddit.utils.settings.settingsPatch
import app.revanced.patches.reddit.utils.settings.updatePatchStatus
import app.revanced.util.Utils.printWarn
import app.revanced.util.fingerprint.methodOrThrow
import app.revanced.util.fingerprint.resolvable
import app.revanced.util.indexOfFirstInstructionOrThrow
import app.revanced.util.indexOfFirstInstructionReversedOrThrow
import com.android.tools.smali.dexlib2.Opcode
import com.android.tools.smali.dexlib2.iface.instruction.FiveRegisterInstruction
import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction
@ -26,7 +26,6 @@ private const val EXTENSION_CLASS_DESCRIPTOR =
val navigationButtonsPatch = bytecodePatch(
HIDE_NAVIGATION_BUTTONS.title,
HIDE_NAVIGATION_BUTTONS.summary,
false,
) {
compatibleWith(COMPATIBLE_PACKAGE)
@ -34,49 +33,59 @@ val navigationButtonsPatch = bytecodePatch(
execute {
if (is_2024_18_or_greater) {
printWarn("\"Hide navigation buttons\" patch is not supported in this version. Use Reddit 2024.17.0 or earlier.")
return@execute
}
if (bottomNavScreenFingerprint.resolvable()) {
val bottomNavScreenMutableClass = with(bottomNavScreenFingerprint.methodOrThrow()) {
val startIndex = indexOfGetDimensionPixelSizeInstruction(this)
val targetIndex = indexOfFirstInstructionOrThrow(startIndex, Opcode.NEW_INSTANCE)
val targetReference =
getInstruction<ReferenceInstruction>(targetIndex).reference.toString()
classBy { it.type == targetReference }
?.mutableClass
?: throw ClassNotFoundException("Failed to find class $targetReference")
}
bottomNavScreenOnGlobalLayoutFingerprint.second.matchOrNull(bottomNavScreenMutableClass)
?.let {
it.method.apply {
val startIndex = it.patternMatch!!.startIndex
val targetRegister =
getInstruction<FiveRegisterInstruction>(startIndex).registerC
addInstruction(
startIndex + 1,
"invoke-static {v$targetRegister}, $EXTENSION_CLASS_DESCRIPTOR->hideNavigationButtons(Landroid/view/ViewGroup;)V"
)
}
}
} else {
// Legacy method.
bottomNavScreenHandlerFingerprint.methodOrThrow().apply {
val targetIndex = indexOfGetItemsInstruction(this) + 1
val targetRegister = getInstruction<OneRegisterInstruction>(targetIndex).registerA
if (is_2024_26_or_greater) {
bottomNavScreenSetupBottomNavigationFingerprint.methodOrThrow().apply {
val arrayIndex = indexOfFirstInstructionReversedOrThrow(Opcode.FILLED_NEW_ARRAY)
val arrayRegister =
getInstruction<OneRegisterInstruction>(arrayIndex + 1).registerA
addInstructions(
targetIndex + 1, """
invoke-static {v$targetRegister}, $EXTENSION_CLASS_DESCRIPTOR->hideNavigationButtons(Ljava/util/List;)Ljava/util/List;
move-result-object v$targetRegister
arrayIndex + 2, """
invoke-static {v$arrayRegister}, $EXTENSION_CLASS_DESCRIPTOR->hideNavigationButtons([Ljava/lang/Object;)[Ljava/lang/Object;
move-result-object v$arrayRegister
"""
)
}
} else {
if (bottomNavScreenFingerprint.resolvable()) {
val bottomNavScreenMutableClass = with(bottomNavScreenFingerprint.methodOrThrow()) {
val startIndex = indexOfGetDimensionPixelSizeInstruction(this)
val targetIndex = indexOfFirstInstructionOrThrow(startIndex, Opcode.NEW_INSTANCE)
val targetReference =
getInstruction<ReferenceInstruction>(targetIndex).reference.toString()
classBy { it.type == targetReference }
?.mutableClass
?: throw ClassNotFoundException("Failed to find class $targetReference")
}
bottomNavScreenOnGlobalLayoutFingerprint.second.matchOrNull(bottomNavScreenMutableClass)
?.let {
it.method.apply {
val startIndex = it.patternMatch!!.startIndex
val targetRegister =
getInstruction<FiveRegisterInstruction>(startIndex).registerC
addInstruction(
startIndex + 1,
"invoke-static {v$targetRegister}, $EXTENSION_CLASS_DESCRIPTOR->hideNavigationButtons(Landroid/view/ViewGroup;)V"
)
}
}
} else {
// Legacy method.
bottomNavScreenHandlerFingerprint.methodOrThrow().apply {
val targetIndex = indexOfGetItemsInstruction(this) + 1
val targetRegister = getInstruction<OneRegisterInstruction>(targetIndex).registerA
addInstructions(
targetIndex + 1, """
invoke-static {v$targetRegister}, $EXTENSION_CLASS_DESCRIPTOR->hideNavigationButtons(Ljava/util/List;)Ljava/util/List;
move-result-object v$targetRegister
"""
)
}
}
}
updatePatchStatus(

View File

@ -33,7 +33,7 @@ private const val EXTENSION_METHOD_DESCRIPTOR =
private lateinit var acknowledgementsLabelBuilderMethod: MutableMethod
private lateinit var settingsStatusLoadMethod: MutableMethod
var is_2024_18_or_greater = false
var is_2024_26_or_greater = false
private set
var is_2024_41_or_greater = false
private set
@ -57,7 +57,7 @@ private val settingsBytecodePatch = bytecodePatch(
getInstruction<BuilderInstruction21c>(versionIndex).reference.toString()
.replace(".", "").toInt()
is_2024_18_or_greater = 2024180 <= versionNumber
is_2024_26_or_greater = 2024260 <= versionNumber
is_2024_41_or_greater = 2024100 <= versionNumber
}