diff --git a/src/main/kotlin/app/revanced/patches/twitch/chat/antidelete/annotations/ShowDeletedMessagesCompatibility.kt b/src/main/kotlin/app/revanced/patches/twitch/chat/antidelete/annotations/ShowDeletedMessagesCompatibility.kt new file mode 100644 index 000000000..c0c71beaa --- /dev/null +++ b/src/main/kotlin/app/revanced/patches/twitch/chat/antidelete/annotations/ShowDeletedMessagesCompatibility.kt @@ -0,0 +1,10 @@ +package app.revanced.patches.twitch.chat.antidelete.annotations + +import app.revanced.patcher.annotation.Compatibility +import app.revanced.patcher.annotation.Package + +@Compatibility([Package("tv.twitch.android.app")]) +@Target(AnnotationTarget.CLASS) +@Retention(AnnotationRetention.RUNTIME) +internal annotation class ShowDeletedMessagesCompatibility + diff --git a/src/main/kotlin/app/revanced/patches/twitch/chat/antidelete/fingerprints/DeletedMessageClickableSpanCtorFingerprint.kt b/src/main/kotlin/app/revanced/patches/twitch/chat/antidelete/fingerprints/DeletedMessageClickableSpanCtorFingerprint.kt new file mode 100644 index 000000000..c542722d3 --- /dev/null +++ b/src/main/kotlin/app/revanced/patches/twitch/chat/antidelete/fingerprints/DeletedMessageClickableSpanCtorFingerprint.kt @@ -0,0 +1,19 @@ +package app.revanced.patches.twitch.chat.antidelete.fingerprints + +import app.revanced.patcher.annotation.Name +import app.revanced.patcher.annotation.Version +import app.revanced.patcher.extensions.or + +import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint +import app.revanced.patches.twitch.chat.antidelete.annotations.ShowDeletedMessagesCompatibility +import org.jf.dexlib2.AccessFlags + +@Name("deleted-msg-span-ctor-fingerprint") +@ShowDeletedMessagesCompatibility +@Version("0.0.1") +object DeletedMessageClickableSpanCtorFingerprint : MethodFingerprint( + "V", AccessFlags.PUBLIC or AccessFlags.CONSTRUCTOR, + customFingerprint = { methodDef -> + methodDef.definingClass.endsWith("DeletedMessageClickableSpan;") + } +) \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/twitch/chat/antidelete/fingerprints/SetHasModAccessFingerprint.kt b/src/main/kotlin/app/revanced/patches/twitch/chat/antidelete/fingerprints/SetHasModAccessFingerprint.kt new file mode 100644 index 000000000..33d8b21c7 --- /dev/null +++ b/src/main/kotlin/app/revanced/patches/twitch/chat/antidelete/fingerprints/SetHasModAccessFingerprint.kt @@ -0,0 +1,16 @@ +package app.revanced.patches.twitch.chat.antidelete.fingerprints + +import app.revanced.patcher.annotation.Name +import app.revanced.patcher.annotation.Version + +import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint +import app.revanced.patches.twitch.chat.antidelete.annotations.ShowDeletedMessagesCompatibility + +@Name("has-mod-access-fingerprint") +@ShowDeletedMessagesCompatibility +@Version("0.0.1") +object SetHasModAccessFingerprint : MethodFingerprint( + customFingerprint = { methodDef -> + methodDef.definingClass.endsWith("DeletedMessageClickableSpan;") && methodDef.name == "setHasModAccess" + } +) \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/twitch/chat/antidelete/patch/ShowDeletedMessagesPatch.kt b/src/main/kotlin/app/revanced/patches/twitch/chat/antidelete/patch/ShowDeletedMessagesPatch.kt new file mode 100644 index 000000000..a6f3bfa8a --- /dev/null +++ b/src/main/kotlin/app/revanced/patches/twitch/chat/antidelete/patch/ShowDeletedMessagesPatch.kt @@ -0,0 +1,45 @@ +package app.revanced.patches.twitch.chat.antidelete.patch + +import app.revanced.patcher.annotation.Description +import app.revanced.patcher.annotation.Name +import app.revanced.patcher.annotation.Version +import app.revanced.patcher.data.BytecodeContext +import app.revanced.patcher.extensions.* +import app.revanced.patcher.patch.* +import app.revanced.patcher.patch.annotations.Patch +import app.revanced.patches.twitch.chat.antidelete.annotations.ShowDeletedMessagesCompatibility +import app.revanced.patches.twitch.chat.antidelete.fingerprints.* +import org.jf.dexlib2.Opcode +import org.jf.dexlib2.builder.instruction.BuilderInstruction10x + +@Patch +@Name("show-deleted-messages") +@Description("Shows deleted chat messages behind a clickable spoiler.") +@ShowDeletedMessagesCompatibility +@Version("0.0.1") +class ShowDeletedMessagesPatch : BytecodePatch( + listOf( + SetHasModAccessFingerprint, + DeletedMessageClickableSpanCtorFingerprint, + ) +) { + override fun execute(context: BytecodeContext): PatchResult { + // Force set hasModAccess member to true in constructor + with(DeletedMessageClickableSpanCtorFingerprint.result!!.mutableMethod) { + addInstructions( + implementation!!.instructions.lastIndex, /* place in front of return-void */ + """ + const/4 v0, 1 + iput-boolean v0, p0, $definingClass->hasModAccess:Z + """ + ) + } + + // Disable setHasModAccess setter + with(SetHasModAccessFingerprint.result!!.mutableMethod.implementation!!) { + addInstruction(0, BuilderInstruction10x(Opcode.RETURN_VOID)) + } + + return PatchResultSuccess() + } +}