Skip to content

Commit

Permalink
fix(YouTube/Return YouTube Dislike): add support for RollingNumber
Browse files Browse the repository at this point in the history
  • Loading branch information
inotia00 committed Nov 11, 2023
1 parent dca0933 commit 58705f3
Show file tree
Hide file tree
Showing 5 changed files with 166 additions and 3 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,13 @@ package app.revanced.patches.youtube.utils.returnyoutubedislike.general
import app.revanced.extensions.exception
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.removeInstruction
import app.revanced.patcher.extensions.InstructionExtensions.replaceInstruction
import app.revanced.patcher.fingerprint.MethodFingerprint
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 app.revanced.patches.youtube.misc.spoofappversion.SpoofAppVersionPatch
import app.revanced.patches.youtube.utils.litho.LithoFilterPatch
import app.revanced.patches.youtube.utils.playerresponse.PlayerResponsePatch
import app.revanced.patches.youtube.utils.returnyoutubedislike.general.fingerprints.DislikeFingerprint
Expand All @@ -24,6 +21,7 @@ import app.revanced.patches.youtube.utils.returnyoutubedislike.general.fingerpri
import app.revanced.patches.youtube.utils.returnyoutubedislike.general.fingerprints.TextComponentContextFingerprint
import app.revanced.patches.youtube.utils.returnyoutubedislike.general.fingerprints.TextComponentTmpFingerprint
import app.revanced.patches.youtube.utils.returnyoutubedislike.oldlayout.ReturnYouTubeDislikeOldLayoutPatch
import app.revanced.patches.youtube.utils.returnyoutubedislike.rollingnumber.ReturnYouTubeDislikeRollingNumberPatch
import app.revanced.patches.youtube.utils.returnyoutubedislike.shorts.ReturnYouTubeDislikeShortsPatch
import app.revanced.patches.youtube.utils.settings.SettingsPatch
import app.revanced.patches.youtube.utils.videoid.general.VideoIdPatch
Expand All @@ -42,6 +40,7 @@ import com.android.tools.smali.dexlib2.iface.reference.Reference
LithoFilterPatch::class,
PlayerResponsePatch::class,
ReturnYouTubeDislikeOldLayoutPatch::class,
ReturnYouTubeDislikeRollingNumberPatch::class,
ReturnYouTubeDislikeShortsPatch::class,
SettingsPatch::class,
VideoIdPatch::class
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@
package app.revanced.patches.youtube.utils.returnyoutubedislike.rollingnumber

import app.revanced.extensions.exception
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.patch.BytecodePatch
import app.revanced.patcher.patch.PatchException
import app.revanced.patcher.patch.annotation.Patch
import app.revanced.patches.youtube.utils.returnyoutubedislike.rollingnumber.fingerprints.RollingNumberTextViewFingerprint
import app.revanced.patches.youtube.utils.returnyoutubedislike.rollingnumber.fingerprints.RollingNumberTypeFingerprint
import app.revanced.patches.youtube.utils.settings.SettingsPatch
import app.revanced.util.integrations.Constants.UTILS_PATH
import com.android.tools.smali.dexlib2.Opcode
import com.android.tools.smali.dexlib2.builder.instruction.BuilderInstruction21c
import com.android.tools.smali.dexlib2.iface.instruction.FiveRegisterInstruction
import com.android.tools.smali.dexlib2.iface.instruction.ReferenceInstruction
import com.android.tools.smali.dexlib2.iface.reference.FieldReference
import com.android.tools.smali.dexlib2.iface.reference.MethodReference

@Patch(dependencies = [SettingsPatch::class])
object ReturnYouTubeDislikeRollingNumberPatch : BytecodePatch(
setOf(
RollingNumberTextViewFingerprint,
RollingNumberTypeFingerprint
)
) {
private const val CONVERSION_CONTEXT_PARAMETER = 2

private const val INTEGRATIONS_RYD_CLASS_DESCRIPTOR =
"$UTILS_PATH/ReturnYouTubeDislikePatch;"

override fun execute(context: BytecodeContext) {
/**
* RollingNumber is applied to YouTube v18.41.39+.
*
* In order to maintain compatibility with YouTube v18.40.34 or previous versions,
* This patch is applied only to the version after YouTube v18.41.39
*
* Resolves following issue:
* https://github.com/revanced/revanced-patches/issues/2904
*/
if (SettingsPatch.upward1841) {

RollingNumberTypeFingerprint.result?.let {
it.mutableMethod.apply {
val rollingNumberClassIndex = it.scanResult.patternScanResult!!.startIndex
val rollingNumberClassReference =
getInstruction<BuilderInstruction21c>(rollingNumberClassIndex).reference
val rollingNumberClass =
context.findClass(rollingNumberClassReference.toString())!!.mutableClass

/**
* This class handles RollingNumber.
* Pass an instance of this class to integrations to use Java Reflection.
*/
rollingNumberClass.methods.find { method -> method.name == "<init>" }
?.apply {
val rollingNumberFieldIndex =
implementation!!.instructions.indexOfFirst { instruction ->
instruction.opcode == Opcode.IPUT_OBJECT
}
val rollingNumberFieldName =
(getInstruction<ReferenceInstruction>(rollingNumberFieldIndex).reference as FieldReference).name

addInstructions(
1, """
const-string v0, "$rollingNumberFieldName"
invoke-static {p0, v0}, $INTEGRATIONS_RYD_CLASS_DESCRIPTOR->initialize(Ljava/lang/Object;Ljava/lang/String;)V
"""
)
} ?: throw PatchException("RollingNumberClass not found!")

/**
* RollingNumber is initialized in this method.
* This method also contains information about ConversionContext.
*/
addInstruction(
1,
"invoke-static {p$CONVERSION_CONTEXT_PARAMETER}, $INTEGRATIONS_RYD_CLASS_DESCRIPTOR->onRollingNumberTextLoaded(Ljava/lang/Object;)V"
)
}
} ?: throw RollingNumberTypeFingerprint.exception

/**
* TextView with RollingNumber.
* Apply spanned text to TextView.
*/
RollingNumberTextViewFingerprint.result?.let {
// Initial TextView is set in this method.
val initiallyCreatedTextViewMethod = it.mutableMethod

// Video less than 24 hours after uploaded, like counts will be updated in real time.
// Whenever like counts are updated, TextView is set in this method.
val realTimeUpdateTextViewMethod = it.mutableClass.methods.find {
method -> method.parameterTypes.first() == "Landroid/graphics/Bitmap;"
} ?: throw PatchException("Failed to find realTimeUpdateTextViewMethod")

arrayOf(
initiallyCreatedTextViewMethod,
realTimeUpdateTextViewMethod
).forEach { insertMethod ->
insertMethod.apply {
val setTextIndex = implementation!!.instructions.indexOfFirst { instruction ->
((instruction as? ReferenceInstruction)?.reference as? MethodReference)?.name == "setText"
}
val textViewRegister =
getInstruction<FiveRegisterInstruction>(setTextIndex).registerC

addInstruction(
setTextIndex + 1,
"invoke-static {v$textViewRegister}, $INTEGRATIONS_RYD_CLASS_DESCRIPTOR->updateRollingNumberTextView(Landroid/widget/TextView;)V"
)
}
}
} ?: throw RollingNumberTextViewFingerprint.exception
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
package app.revanced.patches.youtube.utils.returnyoutubedislike.rollingnumber.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

/**
* This fingerprint is compatible with YouTube v18.32.39+
*/
object RollingNumberTextViewFingerprint : MethodFingerprint(
returnType = "V",
accessFlags = AccessFlags.PUBLIC or AccessFlags.FINAL,
parameters = listOf("L", "F", "F"),
opcodes = listOf(
Opcode.IPUT,
null, // invoke-direct or invoke-virtual
Opcode.IPUT_OBJECT,
Opcode.IGET_OBJECT,
Opcode.INVOKE_VIRTUAL,
Opcode.RETURN_VOID
),
customFingerprint = custom@{ _, classDef ->
classDef.methods.count() == 4
}
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package app.revanced.patches.youtube.utils.returnyoutubedislike.rollingnumber.fingerprints

import app.revanced.patcher.fingerprint.MethodFingerprint
import com.android.tools.smali.dexlib2.Opcode

/**
* This fingerprint is compatible with YouTube v18.29.38+
*/
object RollingNumberTypeFingerprint : MethodFingerprint(
opcodes = listOf(
Opcode.CHECK_CAST,
Opcode.IGET,
Opcode.AND_INT_LIT8
),
strings = listOf("RollingNumberType required properties missing! Need updateCount, fontName, color and fontSize.")
)
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,7 @@ object SettingsPatch : AbstractSettingsResourcePatch(
is1836 = playServicesVersion in 233700000..233801999
upward1828 = 232900000 <= playServicesVersion
upward1834 = 233502000 <= playServicesVersion
upward1841 = 234200000 <= playServicesVersion

break
}
Expand Down Expand Up @@ -201,6 +202,7 @@ object SettingsPatch : AbstractSettingsResourcePatch(
internal var is1836: Boolean = false
internal var upward1828: Boolean = false
internal var upward1834: Boolean = false
internal var upward1841: Boolean = false

internal fun addPreference(settingArray: Array<String>) {
contexts.addPreference(settingArray)
Expand Down

0 comments on commit 58705f3

Please sign in to comment.