mirror of
https://github.com/ReVanced/revanced-patches.git
synced 2026-01-28 05:01:03 +00:00
Compare commits
46 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
93d4cee16e | ||
|
|
bc3b654357 | ||
|
|
64b4c92ca0 | ||
|
|
cd66ee4e57 | ||
|
|
f527226757 | ||
|
|
ec0b17a4d8 | ||
|
|
63598d0d42 | ||
|
|
14f6b66135 | ||
|
|
18893c005e | ||
|
|
73b51a0687 | ||
|
|
c4de003fc1 | ||
|
|
45b8ad099e | ||
|
|
8c40ff4852 | ||
|
|
f304c866f1 | ||
|
|
9adf42c308 | ||
|
|
2391db0f53 | ||
|
|
9809e4dfd0 | ||
|
|
b191efea2d | ||
|
|
c5ec801b90 | ||
|
|
95f22bc2a1 | ||
|
|
0098f25bfb | ||
|
|
9395e0835e | ||
|
|
d59d6b7022 | ||
|
|
c21e177ed1 | ||
|
|
d3e1419d0e | ||
|
|
f44d09059b | ||
|
|
185f6d84fb | ||
|
|
3dc6be5d8d | ||
|
|
742e2394a9 | ||
|
|
d9d389b939 | ||
|
|
b0775e13d5 | ||
|
|
0fe98b6c5e | ||
|
|
3a78021f5e | ||
|
|
e096009893 | ||
|
|
b599ee2096 | ||
|
|
bd7cedee48 | ||
|
|
278c07ea56 | ||
|
|
6dc2875057 | ||
|
|
7b24071956 | ||
|
|
6c472aa71d | ||
|
|
ca66490930 | ||
|
|
5317a482d1 | ||
|
|
f21d1d83f6 | ||
|
|
bb6c805f55 | ||
|
|
c5dfe3e842 | ||
|
|
4290a4e820 |
135
CHANGELOG.md
135
CHANGELOG.md
@@ -1,3 +1,138 @@
|
|||||||
|
## [2.9.1](https://github.com/revanced/revanced-patches/compare/v2.9.0...v2.9.1) (2022-07-05)
|
||||||
|
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* make `minimized-playback-manager-fingerprint` unique ([#120](https://github.com/revanced/revanced-patches/issues/120)) ([cd5e911](https://github.com/revanced/revanced-patches/commit/cd5e911f4ed9ad95b02c13c30cd9466d250e8904))
|
||||||
|
|
||||||
|
# [2.9.0](https://github.com/revanced/revanced-patches/compare/v2.8.2...v2.9.0) (2022-07-05)
|
||||||
|
|
||||||
|
|
||||||
|
### Features
|
||||||
|
|
||||||
|
* `swipe-controls` patch ([#115](https://github.com/revanced/revanced-patches/issues/115)) ([1d0a7dc](https://github.com/revanced/revanced-patches/commit/1d0a7dcc0cc3ea2bcd8ce0221d5e2f53d6eb0ae5))
|
||||||
|
|
||||||
|
## [2.8.2](https://github.com/revanced/revanced-patches/compare/v2.8.1...v2.8.2) (2022-07-05)
|
||||||
|
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* show minimized playback options in settings ([#118](https://github.com/revanced/revanced-patches/issues/118)) ([6e1a538](https://github.com/revanced/revanced-patches/commit/6e1a538d34291d75f19bf66a188bc69241de3a7a))
|
||||||
|
|
||||||
|
## [2.8.1](https://github.com/revanced/revanced-patches/compare/v2.8.0...v2.8.1) (2022-07-05)
|
||||||
|
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* remove unnecessary version constraints ([#117](https://github.com/revanced/revanced-patches/issues/117)) ([1cddf8d](https://github.com/revanced/revanced-patches/commit/1cddf8d9063da3bbdba0fd7080c8c93768b83a4c))
|
||||||
|
|
||||||
|
# [2.8.0](https://github.com/revanced/revanced-patches/compare/v2.7.0...v2.8.0) (2022-07-04)
|
||||||
|
|
||||||
|
|
||||||
|
### Features
|
||||||
|
|
||||||
|
* `enable-debugging` patch ([#116](https://github.com/revanced/revanced-patches/issues/116)) ([bb355e7](https://github.com/revanced/revanced-patches/commit/bb355e7b7e78e602a10b346fe7e5795463615a81))
|
||||||
|
|
||||||
|
# [2.7.0](https://github.com/revanced/revanced-patches/compare/v2.6.0...v2.7.0) (2022-07-03)
|
||||||
|
|
||||||
|
|
||||||
|
### Features
|
||||||
|
|
||||||
|
* `hdr-max-brightness` patch ([#105](https://github.com/revanced/revanced-patches/issues/105)) ([1310573](https://github.com/revanced/revanced-patches/commit/131057366a777786d6016d3385584b4e17bc4a8b))
|
||||||
|
* `hide-infocard-suggestions` patch ([#107](https://github.com/revanced/revanced-patches/issues/107)) ([31a767a](https://github.com/revanced/revanced-patches/commit/31a767adbb152906303ab0ae5250769fc38d0625))
|
||||||
|
|
||||||
|
# [2.6.0](https://github.com/revanced/revanced-patches/compare/v2.5.0...v2.6.0) (2022-07-02)
|
||||||
|
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* freezing panels when watching video in fullscreen ([#89](https://github.com/revanced/revanced-patches/issues/89)) ([f5d4f6c](https://github.com/revanced/revanced-patches/commit/f5d4f6c3419916c6a9cf67babc6be8a64c854d3b))
|
||||||
|
* invalid version in compatibility annotation ([#90](https://github.com/revanced/revanced-patches/issues/90)) ([df43547](https://github.com/revanced/revanced-patches/commit/df435475cdd0494a1e4ea9e2980c2998c9bc7048))
|
||||||
|
* remove refreshing home screen not working ([6c24ebe](https://github.com/revanced/revanced-patches/commit/6c24ebef2fb4f0d58e369ac5bf63e4cab6ca0e80))
|
||||||
|
|
||||||
|
|
||||||
|
### Features
|
||||||
|
|
||||||
|
* migrate to breaking changes of patcher ([d9147cd](https://github.com/revanced/revanced-patches/commit/d9147cd60c0c25d0c5cc05409b8889dfacd89af9))
|
||||||
|
|
||||||
|
# [2.6.0-dev.2](https://github.com/revanced/revanced-patches/compare/v2.6.0-dev.1...v2.6.0-dev.2) (2022-07-02)
|
||||||
|
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* remove refreshing home screen not working ([ec7ae90](https://github.com/revanced/revanced-patches/commit/ec7ae900181b6456c692adb3b5bb337e81bc5fea))
|
||||||
|
|
||||||
|
# [2.6.0-dev.1](https://github.com/revanced/revanced-patches/compare/v2.5.1-dev.1...v2.6.0-dev.1) (2022-07-02)
|
||||||
|
|
||||||
|
|
||||||
|
### Features
|
||||||
|
|
||||||
|
* migrate to breaking changes of patcher ([a116852](https://github.com/revanced/revanced-patches/commit/a11685263fb2274c67684258e73c5247502cb010))
|
||||||
|
|
||||||
|
## [2.5.1-dev.1](https://github.com/revanced/revanced-patches/compare/v2.5.0...v2.5.1-dev.1) (2022-06-30)
|
||||||
|
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* freezing panels when watching video in fullscreen ([#89](https://github.com/revanced/revanced-patches/issues/89)) ([f5d4f6c](https://github.com/revanced/revanced-patches/commit/f5d4f6c3419916c6a9cf67babc6be8a64c854d3b))
|
||||||
|
* invalid version in compatibility annotation ([#90](https://github.com/revanced/revanced-patches/issues/90)) ([df43547](https://github.com/revanced/revanced-patches/commit/df435475cdd0494a1e4ea9e2980c2998c9bc7048))
|
||||||
|
|
||||||
|
# [2.5.0](https://github.com/revanced/revanced-patches/compare/v2.4.0...v2.5.0) (2022-06-30)
|
||||||
|
|
||||||
|
|
||||||
|
### Features
|
||||||
|
|
||||||
|
* hide watermark support for 17.25.34 ([#87](https://github.com/revanced/revanced-patches/issues/87)) ([0cdb65b](https://github.com/revanced/revanced-patches/commit/0cdb65bbb3e7b9d75eb393ee87e3718bcd6af4b3))
|
||||||
|
|
||||||
|
# [2.4.0](https://github.com/revanced/revanced-patches/compare/v2.3.1...v2.4.0) (2022-06-30)
|
||||||
|
|
||||||
|
|
||||||
|
### Features
|
||||||
|
|
||||||
|
* add youtube version 17.25.34 ([#85](https://github.com/revanced/revanced-patches/issues/85)) ([889c9d5](https://github.com/revanced/revanced-patches/commit/889c9d564d16c6e68a52095a4fc8e6d04346c9e9))
|
||||||
|
|
||||||
|
## [2.3.1](https://github.com/revanced/revanced-patches/compare/v2.3.0...v2.3.1) (2022-06-30)
|
||||||
|
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* change fingerprint to work on latest youtube ([#80](https://github.com/revanced/revanced-patches/issues/80)) ([4dba323](https://github.com/revanced/revanced-patches/commit/4dba323ddf8980cd2b0908a0de41c4b4dea6b0d7))
|
||||||
|
|
||||||
|
# [2.3.0](https://github.com/revanced/revanced-patches/compare/v2.2.0...v2.3.0) (2022-06-30)
|
||||||
|
|
||||||
|
|
||||||
|
### Features
|
||||||
|
|
||||||
|
* `disable-autoplay-button` patch ([#79](https://github.com/revanced/revanced-patches/issues/79)) ([0d6fb51](https://github.com/revanced/revanced-patches/commit/0d6fb51e025649aae37e230778ea367482fab0d7))
|
||||||
|
|
||||||
|
# [2.2.0](https://github.com/revanced/revanced-patches/compare/v2.1.0...v2.2.0) (2022-06-29)
|
||||||
|
|
||||||
|
|
||||||
|
### Features
|
||||||
|
|
||||||
|
* make resource mapping patch aware of types ([#77](https://github.com/revanced/revanced-patches/issues/77)) ([188491a](https://github.com/revanced/revanced-patches/commit/188491a707abccc1164413f075d8a66c145a1455))
|
||||||
|
|
||||||
|
# [2.1.0](https://github.com/revanced/revanced-patches/compare/v2.0.3...v2.1.0) (2022-06-28)
|
||||||
|
|
||||||
|
|
||||||
|
### Features
|
||||||
|
|
||||||
|
* `custom-playback-speed` patch ([#50](https://github.com/revanced/revanced-patches/issues/50)) ([224254b](https://github.com/revanced/revanced-patches/commit/224254bcce2b394bbfd2549089f0204ce4ed4a89))
|
||||||
|
|
||||||
|
## [2.0.3](https://github.com/revanced/revanced-patches/compare/v2.0.2...v2.0.3) (2022-06-27)
|
||||||
|
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* check if resource files exist ([ba1f3af](https://github.com/revanced/revanced-patches/commit/ba1f3af99be58edc44ed1b8f1875508d5034efd8))
|
||||||
|
|
||||||
|
## [2.0.2](https://github.com/revanced/revanced-patches/compare/v2.0.1...v2.0.2) (2022-06-27)
|
||||||
|
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* some more refactoring of integrations, add hide-watermark patch ([#63](https://github.com/revanced/revanced-patches/issues/63)) ([feb09c5](https://github.com/revanced/revanced-patches/commit/feb09c56f475e2537a67d3636b08737848158a8e))
|
||||||
|
|
||||||
## [2.0.1](https://github.com/revanced/revanced-patches/compare/v2.0.0...v2.0.1) (2022-06-26)
|
## [2.0.1](https://github.com/revanced/revanced-patches/compare/v2.0.0...v2.0.1) (2022-06-26)
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -22,7 +22,7 @@ repositories {
|
|||||||
dependencies {
|
dependencies {
|
||||||
implementation(kotlin("stdlib"))
|
implementation(kotlin("stdlib"))
|
||||||
|
|
||||||
implementation("app.revanced:revanced-patcher:2.0.1")
|
implementation("app.revanced:revanced-patcher:2.3.0")
|
||||||
implementation("app.revanced:multidexlib2:2.5.2.r2")
|
implementation("app.revanced:multidexlib2:2.5.2.r2")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,2 +1,2 @@
|
|||||||
kotlin.code.style = official
|
kotlin.code.style = official
|
||||||
version = 2.0.1
|
version = 2.9.1
|
||||||
|
|||||||
@@ -1,7 +1,18 @@
|
|||||||
package app.revanced.extensions
|
package app.revanced.extensions
|
||||||
|
|
||||||
|
import app.revanced.patcher.data.impl.BytecodeData
|
||||||
|
import app.revanced.patcher.extensions.addInstructions
|
||||||
|
import app.revanced.patcher.patch.PatchResultError
|
||||||
|
import app.revanced.patcher.util.proxy.mutableTypes.MutableMethod
|
||||||
import app.revanced.patcher.util.smali.toInstruction
|
import app.revanced.patcher.util.smali.toInstruction
|
||||||
|
import org.jf.dexlib2.AccessFlags
|
||||||
|
import org.jf.dexlib2.Opcode
|
||||||
import org.jf.dexlib2.builder.MutableMethodImplementation
|
import org.jf.dexlib2.builder.MutableMethodImplementation
|
||||||
|
import org.jf.dexlib2.builder.instruction.BuilderInstruction11n
|
||||||
|
import org.jf.dexlib2.builder.instruction.BuilderInstruction11x
|
||||||
|
import org.jf.dexlib2.builder.instruction.BuilderInstruction21t
|
||||||
|
import org.jf.dexlib2.builder.instruction.BuilderInstruction35c
|
||||||
|
import org.jf.dexlib2.immutable.reference.ImmutableMethodReference
|
||||||
import org.w3c.dom.Node
|
import org.w3c.dom.Node
|
||||||
|
|
||||||
internal fun MutableMethodImplementation.injectHideCall(
|
internal fun MutableMethodImplementation.injectHideCall(
|
||||||
@@ -14,6 +25,115 @@ internal fun MutableMethodImplementation.injectHideCall(
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Insert an event hook at the top of the method. If the hook returns true, the event is consumed and the method will return with true
|
||||||
|
*
|
||||||
|
* the hook method MUST return a boolean and MUST take two parameters, like so:
|
||||||
|
* fun hook(thisRef: Object, eventData: Object): Boolean {}
|
||||||
|
*
|
||||||
|
* The final injected code will resemble the following logic:
|
||||||
|
* if( YouHook(this, event) ) { return true; }
|
||||||
|
* ...
|
||||||
|
*
|
||||||
|
* @param hookRef reference to the hook method
|
||||||
|
*/
|
||||||
|
internal fun MutableMethod.injectConsumableEventHook(hookRef: ImmutableMethodReference) {
|
||||||
|
val isStaticMethod = AccessFlags.STATIC.isSet(this.accessFlags)
|
||||||
|
this.implementation?.let { impl ->
|
||||||
|
// create label to index 0 to continue to the normal program flow
|
||||||
|
val lblContinueNormalFlow = impl.newLabelForIndex(0)
|
||||||
|
|
||||||
|
// define registers
|
||||||
|
/** V0 */
|
||||||
|
val regV0 = 0
|
||||||
|
|
||||||
|
/** this */
|
||||||
|
val regP0 = impl.registerCount - this.parameters.size - (if (isStaticMethod) 0 else 1)
|
||||||
|
|
||||||
|
/** motionEvent */
|
||||||
|
val regP1 = regP0 + 1
|
||||||
|
|
||||||
|
// insert instructions at the start of the method:
|
||||||
|
// if( Hook(this, event) ) { return true; }
|
||||||
|
impl.addInstructions(
|
||||||
|
0, listOf(
|
||||||
|
// invoke-static { p0, p1 } <hook>
|
||||||
|
BuilderInstruction35c(
|
||||||
|
Opcode.INVOKE_STATIC,
|
||||||
|
2,
|
||||||
|
regP0,
|
||||||
|
regP1,
|
||||||
|
0, 0, 0,
|
||||||
|
hookRef
|
||||||
|
),
|
||||||
|
|
||||||
|
// move-result v0
|
||||||
|
BuilderInstruction11x(
|
||||||
|
Opcode.MOVE_RESULT,
|
||||||
|
regV0
|
||||||
|
),
|
||||||
|
|
||||||
|
// if-eqz v0, :continue_normal_flow
|
||||||
|
BuilderInstruction21t(
|
||||||
|
Opcode.IF_EQZ,
|
||||||
|
regV0,
|
||||||
|
lblContinueNormalFlow
|
||||||
|
),
|
||||||
|
|
||||||
|
// const/4 v0, 0x1
|
||||||
|
BuilderInstruction11n(
|
||||||
|
Opcode.CONST_4,
|
||||||
|
regV0,
|
||||||
|
0x1
|
||||||
|
),
|
||||||
|
|
||||||
|
// return v0
|
||||||
|
BuilderInstruction11x(
|
||||||
|
Opcode.RETURN,
|
||||||
|
regV0
|
||||||
|
)
|
||||||
|
|
||||||
|
// :continue_normal_flow
|
||||||
|
)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Insert instructions into a named method
|
||||||
|
*
|
||||||
|
* @param targetClass the name of the class of which the method is a member
|
||||||
|
* @param targetMethod the name of the method to insert into
|
||||||
|
* @param index index to insert the instructions at. If the index is negative, it is used as an offset to the last method (so -1 inserts at the end of the method)
|
||||||
|
* @param instructions the smali instructions to insert (they'll be compiled by MutableMethod.addInstructions)
|
||||||
|
*/
|
||||||
|
internal fun BytecodeData.injectIntoNamedMethod(
|
||||||
|
targetClass: String,
|
||||||
|
targetMethod: String,
|
||||||
|
index: Int,
|
||||||
|
instructions: String
|
||||||
|
) {
|
||||||
|
var injections = 0
|
||||||
|
this.classes.filter { it.type.endsWith("$targetClass;") }.forEach { classDef ->
|
||||||
|
this.proxy(classDef).resolve().methods.filter { it.name == targetMethod }.forEach { methodDef ->
|
||||||
|
// if index is negative, interpret as an offset from the back
|
||||||
|
var insertIndex = index
|
||||||
|
if (insertIndex < 0) {
|
||||||
|
insertIndex += methodDef.implementation!!.instructions.size
|
||||||
|
}
|
||||||
|
|
||||||
|
// insert instructions
|
||||||
|
methodDef.addInstructions(insertIndex, instructions)
|
||||||
|
injections++
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// fail if nothing was injected
|
||||||
|
if (injections <= 0) {
|
||||||
|
throw PatchResultError("failed to inject into $targetClass.$targetMethod: no targets were found")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
internal fun Node.doRecursively(action: (Node) -> Unit) {
|
internal fun Node.doRecursively(action: (Node) -> Unit) {
|
||||||
action(this)
|
action(this)
|
||||||
for (i in 0 until this.childNodes.length) this.childNodes.item(i).doRecursively(action)
|
for (i in 0 until this.childNodes.length) this.childNodes.item(i).doRecursively(action)
|
||||||
|
|||||||
@@ -1,3 +1,5 @@
|
|||||||
|
package app.revanced.patches.music.audio.exclusiveaudio.fingerprints
|
||||||
|
|
||||||
import app.revanced.patcher.annotation.Name
|
import app.revanced.patcher.annotation.Name
|
||||||
import app.revanced.patcher.annotation.Version
|
import app.revanced.patcher.annotation.Version
|
||||||
import app.revanced.patcher.extensions.or
|
import app.revanced.patcher.extensions.or
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
package app.revanced.patches.music.audio.exclusiveaudio.patch
|
package app.revanced.patches.music.audio.exclusiveaudio.patch
|
||||||
|
|
||||||
import AudioOnlyEnablerFingerprint
|
|
||||||
import app.revanced.patcher.annotation.Description
|
import app.revanced.patcher.annotation.Description
|
||||||
import app.revanced.patcher.annotation.Name
|
import app.revanced.patcher.annotation.Name
|
||||||
import app.revanced.patcher.annotation.Version
|
import app.revanced.patcher.annotation.Version
|
||||||
@@ -13,6 +12,7 @@ import app.revanced.patcher.patch.PatchResultSuccess
|
|||||||
import app.revanced.patcher.patch.annotations.Patch
|
import app.revanced.patcher.patch.annotations.Patch
|
||||||
import app.revanced.patcher.patch.impl.BytecodePatch
|
import app.revanced.patcher.patch.impl.BytecodePatch
|
||||||
import app.revanced.patches.music.audio.exclusiveaudio.annotations.ExclusiveAudioCompatibility
|
import app.revanced.patches.music.audio.exclusiveaudio.annotations.ExclusiveAudioCompatibility
|
||||||
|
import app.revanced.patches.music.audio.exclusiveaudio.fingerprints.AudioOnlyEnablerFingerprint
|
||||||
import app.revanced.patches.music.audio.exclusiveaudio.fingerprints.ExclusiveAudioFingerprint
|
import app.revanced.patches.music.audio.exclusiveaudio.fingerprints.ExclusiveAudioFingerprint
|
||||||
|
|
||||||
@Patch
|
@Patch
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ import app.revanced.patcher.annotation.Package
|
|||||||
|
|
||||||
@Compatibility(
|
@Compatibility(
|
||||||
[Package(
|
[Package(
|
||||||
"com.google.android.youtube", arrayOf("17.19.36", "17.20.37", "17.22.36", "17.23.35", "17.23.36", "17.24.34","17.24.35")
|
"com.google.android.youtube", arrayOf("17.19.36", "17.20.37", "17.22.36", "17.23.35", "17.23.36", "17.24.34","17.24.35","17.25.34")
|
||||||
)]
|
)]
|
||||||
)
|
)
|
||||||
@Target(AnnotationTarget.CLASS)
|
@Target(AnnotationTarget.CLASS)
|
||||||
|
|||||||
@@ -21,7 +21,6 @@ import app.revanced.patches.youtube.ad.general.bytecode.extensions.MethodExtensi
|
|||||||
import app.revanced.patches.youtube.ad.general.bytecode.extensions.MethodExtensions.insertBlocks
|
import app.revanced.patches.youtube.ad.general.bytecode.extensions.MethodExtensions.insertBlocks
|
||||||
import app.revanced.patches.youtube.ad.general.bytecode.extensions.MethodExtensions.toDescriptor
|
import app.revanced.patches.youtube.ad.general.bytecode.extensions.MethodExtensions.toDescriptor
|
||||||
import app.revanced.patches.youtube.ad.general.bytecode.utils.MethodUtils.createMutableMethod
|
import app.revanced.patches.youtube.ad.general.bytecode.utils.MethodUtils.createMutableMethod
|
||||||
import app.revanced.patches.youtube.ad.general.resource.patch.GeneralResourceAdsPatch
|
|
||||||
import app.revanced.patches.youtube.misc.integrations.patch.IntegrationsPatch
|
import app.revanced.patches.youtube.misc.integrations.patch.IntegrationsPatch
|
||||||
import app.revanced.patches.youtube.misc.mapping.patch.ResourceIdMappingProviderResourcePatch
|
import app.revanced.patches.youtube.misc.mapping.patch.ResourceIdMappingProviderResourcePatch
|
||||||
import org.jf.dexlib2.Opcode
|
import org.jf.dexlib2.Opcode
|
||||||
@@ -40,15 +39,13 @@ import org.jf.dexlib2.immutable.reference.ImmutableMethodReference
|
|||||||
|
|
||||||
@Patch
|
@Patch
|
||||||
@Dependencies(
|
@Dependencies(
|
||||||
dependencies = [ResourceIdMappingProviderResourcePatch::class, IntegrationsPatch::class, GeneralResourceAdsPatch::class]
|
dependencies = [ResourceIdMappingProviderResourcePatch::class, IntegrationsPatch::class]
|
||||||
)
|
)
|
||||||
@Name("general-ads")
|
@Name("general-ads")
|
||||||
@Description("Patch to remove general ads in bytecode.")
|
@Description("Patch to remove general ads in bytecode.")
|
||||||
@GeneralAdsCompatibility
|
@GeneralAdsCompatibility
|
||||||
@Version("0.0.1")
|
@Version("0.0.1")
|
||||||
class GeneralBytecodeAdsPatch : BytecodePatch(
|
class GeneralBytecodeAdsPatch : BytecodePatch() {
|
||||||
listOf()
|
|
||||||
) {
|
|
||||||
// a constant used by litho
|
// a constant used by litho
|
||||||
private val lithoConstant = 0xaed2868
|
private val lithoConstant = 0xaed2868
|
||||||
|
|
||||||
@@ -62,8 +59,8 @@ class GeneralBytecodeAdsPatch : BytecodePatch(
|
|||||||
"endscreen_element_layout_icon",
|
"endscreen_element_layout_icon",
|
||||||
"promoted_video_item_land",
|
"promoted_video_item_land",
|
||||||
"promoted_video_item_full_bleed",
|
"promoted_video_item_full_bleed",
|
||||||
).map {
|
).map { name ->
|
||||||
ResourceIdMappingProviderResourcePatch.resourceMappings[it]!!
|
ResourceIdMappingProviderResourcePatch.resourceMappings.first { it.name == name }.id
|
||||||
}
|
}
|
||||||
|
|
||||||
private val stringReferences = arrayOf(
|
private val stringReferences = arrayOf(
|
||||||
@@ -244,20 +241,20 @@ class GeneralBytecodeAdsPatch : BytecodePatch(
|
|||||||
val block1 = """
|
val block1 = """
|
||||||
invoke-static/range {p3}, $thisType->getTemplateName($templateNameParameterType)Ljava/lang/String;
|
invoke-static/range {p3}, $thisType->getTemplateName($templateNameParameterType)Ljava/lang/String;
|
||||||
move-result-object v0
|
move-result-object v0
|
||||||
""".trimIndent().toInstructions(lithoMethod)
|
""".toInstructions(lithoMethod)
|
||||||
val block2 = """
|
val block2 = """
|
||||||
move-object/from16 v1, p3
|
move-object/from16 v1, p3
|
||||||
iget-object v2, v1, $templateNameParameterType->b:Ljava/nio/ByteBuffer;
|
iget-object v2, v1, $templateNameParameterType->b:Ljava/nio/ByteBuffer;
|
||||||
invoke-static {v0, v2}, Lapp/revanced/integrations/patches/GeneralBytecodeAdsPatch;->containsAd(Ljava/lang/String;Ljava/nio/ByteBuffer;)Z
|
invoke-static {v0, v2}, Lapp/revanced/integrations/patches/GeneralBytecodeAdsPatch;->containsAd(Ljava/lang/String;Ljava/nio/ByteBuffer;)Z
|
||||||
move-result v1
|
move-result v1
|
||||||
""".trimIndent().toInstructions(lithoMethod)
|
""".toInstructions(lithoMethod)
|
||||||
val block3 = """
|
val block3 = """
|
||||||
move-object/from16 v2, p1
|
move-object/from16 v2, p1
|
||||||
invoke-static {v2}, $descriptor1
|
invoke-static {v2}, $descriptor1
|
||||||
move-result-object v0
|
move-result-object v0
|
||||||
iget-object v0, v0, $descriptor2
|
iget-object v0, v0, $descriptor2
|
||||||
return-object v0
|
return-object v0
|
||||||
""".trimIndent().toInstructions(lithoMethod)
|
""".toInstructions(lithoMethod)
|
||||||
|
|
||||||
// insert blocks and branch instructions
|
// insert blocks and branch instructions
|
||||||
lithoMethodImplementation.insertBlocks(
|
lithoMethodImplementation.insertBlocks(
|
||||||
@@ -368,7 +365,7 @@ class GeneralBytecodeAdsPatch : BytecodePatch(
|
|||||||
const v0, $lithoConstant
|
const v0, $lithoConstant
|
||||||
invoke-static {p0, v0}, ${descriptors[1]}
|
invoke-static {p0, v0}, ${descriptors[1]}
|
||||||
move-result-object p0
|
move-result-object p0
|
||||||
""".trimIndent().toInstructions()
|
""".toInstructions()
|
||||||
val block2 = """
|
val block2 = """
|
||||||
invoke-static {p0}, ${descriptors[2]}
|
invoke-static {p0}, ${descriptors[2]}
|
||||||
move-result-object p0
|
move-result-object p0
|
||||||
@@ -376,12 +373,12 @@ class GeneralBytecodeAdsPatch : BytecodePatch(
|
|||||||
move-result-object v0
|
move-result-object v0
|
||||||
invoke-static {v0}, ${this.type}->getIsEmpty(Ljava/lang/String;)Z
|
invoke-static {v0}, ${this.type}->getIsEmpty(Ljava/lang/String;)Z
|
||||||
move-result v0
|
move-result v0
|
||||||
""".trimIndent().toInstructions()
|
""".toInstructions()
|
||||||
val block3 = """
|
val block3 = """
|
||||||
invoke-virtual {p0}, ${descriptors[3]}
|
invoke-virtual {p0}, ${descriptors[3]}
|
||||||
move-result-object p0
|
move-result-object p0
|
||||||
return-object p0
|
return-object p0
|
||||||
""".trimIndent().toInstructions()
|
""".toInstructions()
|
||||||
|
|
||||||
// create target instruction
|
// create target instruction
|
||||||
val targetInstruction = BuilderInstruction11n(Opcode.CONST_4, 1, 0)
|
val targetInstruction = BuilderInstruction11n(Opcode.CONST_4, 1, 0)
|
||||||
|
|||||||
@@ -1,60 +0,0 @@
|
|||||||
package app.revanced.patches.youtube.ad.general.resource.patch
|
|
||||||
|
|
||||||
import app.revanced.extensions.doRecursively
|
|
||||||
import app.revanced.extensions.startsWithAny
|
|
||||||
import app.revanced.patcher.annotation.Description
|
|
||||||
import app.revanced.patcher.annotation.Name
|
|
||||||
import app.revanced.patcher.annotation.Version
|
|
||||||
import app.revanced.patcher.data.impl.ResourceData
|
|
||||||
import app.revanced.patcher.patch.annotations.Dependencies
|
|
||||||
import app.revanced.patcher.patch.impl.ResourcePatch
|
|
||||||
import app.revanced.patcher.patch.PatchResult
|
|
||||||
import app.revanced.patcher.patch.PatchResultSuccess
|
|
||||||
import app.revanced.patches.youtube.ad.general.annotation.GeneralAdsCompatibility
|
|
||||||
import app.revanced.patches.youtube.misc.manifest.patch.FixLocaleConfigErrorPatch
|
|
||||||
import org.w3c.dom.Element
|
|
||||||
|
|
||||||
@Dependencies(dependencies = [FixLocaleConfigErrorPatch::class])
|
|
||||||
@Name("general-resource-ads")
|
|
||||||
@Description("Patch to remove general ads in resources.")
|
|
||||||
@GeneralAdsCompatibility
|
|
||||||
@Version("0.0.1")
|
|
||||||
class GeneralResourceAdsPatch : ResourcePatch() {
|
|
||||||
// list of resource file names which need to be hidden
|
|
||||||
private val resourceFileNames = arrayOf(
|
|
||||||
"compact_promoted_video_item.xml",
|
|
||||||
"inline_muted_metadata_swap.xml",
|
|
||||||
"interstitial_promo_view.xml",
|
|
||||||
"pip_ad_overlay.xml",
|
|
||||||
"promoted_",
|
|
||||||
"watch_metadata_companion_cards.xml",
|
|
||||||
//"watch_while_activity.xml" // FIXME: find out why patching this resource fails
|
|
||||||
)
|
|
||||||
|
|
||||||
// the attributes to change the value of
|
|
||||||
private val replacements = arrayOf(
|
|
||||||
"height",
|
|
||||||
"width",
|
|
||||||
"marginTop",
|
|
||||||
)
|
|
||||||
|
|
||||||
override fun execute(data: ResourceData): PatchResult {
|
|
||||||
data.forEach {
|
|
||||||
if (!it.name.startsWithAny(*resourceFileNames)) return@forEach
|
|
||||||
|
|
||||||
// for each file in the "layouts" directory replace all necessary attributes content
|
|
||||||
data.getXmlEditor(it.absolutePath).use { editor ->
|
|
||||||
editor.file.doRecursively { node ->
|
|
||||||
replacements.forEach replacement@{ replacement ->
|
|
||||||
if (node !is Element) return@replacement
|
|
||||||
|
|
||||||
node.getAttributeNode("android:layout_$replacement")?.let { attribute ->
|
|
||||||
attribute.textContent = "1.0dip"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return PatchResultSuccess()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -0,0 +1,13 @@
|
|||||||
|
package app.revanced.patches.youtube.ad.infocardsuggestions.annotations
|
||||||
|
|
||||||
|
import app.revanced.patcher.annotation.Compatibility
|
||||||
|
import app.revanced.patcher.annotation.Package
|
||||||
|
|
||||||
|
@Compatibility(
|
||||||
|
[Package(
|
||||||
|
"com.google.android.youtube", arrayOf("17.25.34")
|
||||||
|
)]
|
||||||
|
)
|
||||||
|
@Target(AnnotationTarget.CLASS)
|
||||||
|
@Retention(AnnotationRetention.RUNTIME)
|
||||||
|
internal annotation class HideInfocardSuggestionsCompatibility
|
||||||
@@ -0,0 +1,24 @@
|
|||||||
|
package app.revanced.patches.youtube.ad.infocardsuggestions.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.annotation.FuzzyPatternScanMethod
|
||||||
|
import app.revanced.patcher.fingerprint.method.annotation.MatchingMethod
|
||||||
|
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
|
||||||
|
import app.revanced.patches.youtube.ad.infocardsuggestions.annotations.HideInfocardSuggestionsCompatibility
|
||||||
|
import org.jf.dexlib2.AccessFlags
|
||||||
|
|
||||||
|
@Name("hide-infocard-suggestions-fingerprint")
|
||||||
|
@MatchingMethod("Liff;", "i")
|
||||||
|
@FuzzyPatternScanMethod(2)
|
||||||
|
@HideInfocardSuggestionsCompatibility
|
||||||
|
@Version("0.0.1")
|
||||||
|
object HideInfocardSuggestionsFingerprint : MethodFingerprint(
|
||||||
|
"Ljava/lang/Boolean;",
|
||||||
|
AccessFlags.PUBLIC or AccessFlags.FINAL,
|
||||||
|
null,
|
||||||
|
null,
|
||||||
|
listOf("vibrator"),
|
||||||
|
null
|
||||||
|
)
|
||||||
@@ -0,0 +1,24 @@
|
|||||||
|
package app.revanced.patches.youtube.ad.infocardsuggestions.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.patcher.fingerprint.method.annotation.FuzzyPatternScanMethod
|
||||||
|
import app.revanced.patcher.fingerprint.method.annotation.MatchingMethod
|
||||||
|
import app.revanced.patches.youtube.ad.infocardsuggestions.annotations.HideInfocardSuggestionsCompatibility
|
||||||
|
import org.jf.dexlib2.AccessFlags
|
||||||
|
|
||||||
|
@Name("hide-infocard-suggestions-parent-fingerprint")
|
||||||
|
@MatchingMethod("Liff;", "lE")
|
||||||
|
@FuzzyPatternScanMethod(2)
|
||||||
|
@HideInfocardSuggestionsCompatibility
|
||||||
|
@Version("0.0.1")
|
||||||
|
object HideInfocardSuggestionsParentFingerprint : MethodFingerprint(
|
||||||
|
"Ljava/lang/String;",
|
||||||
|
AccessFlags.PUBLIC or AccessFlags.FINAL,
|
||||||
|
listOf(),
|
||||||
|
null,
|
||||||
|
listOf("player_overlay_info_card_teaser"),
|
||||||
|
null
|
||||||
|
)
|
||||||
@@ -0,0 +1,71 @@
|
|||||||
|
package app.revanced.patches.youtube.ad.infocardsuggestions.patch
|
||||||
|
|
||||||
|
import app.revanced.patcher.annotation.Description
|
||||||
|
import app.revanced.patcher.annotation.Name
|
||||||
|
import app.revanced.patcher.annotation.Version
|
||||||
|
import app.revanced.patcher.data.impl.BytecodeData
|
||||||
|
import app.revanced.patcher.extensions.addInstruction
|
||||||
|
import app.revanced.patcher.extensions.addInstructions
|
||||||
|
import app.revanced.patcher.extensions.removeInstruction
|
||||||
|
import app.revanced.patcher.extensions.removeInstructions
|
||||||
|
import app.revanced.patcher.fingerprint.method.utils.MethodFingerprintUtils.resolve
|
||||||
|
import app.revanced.patcher.patch.annotations.Dependencies
|
||||||
|
import app.revanced.patcher.patch.annotations.Patch
|
||||||
|
import app.revanced.patcher.patch.impl.BytecodePatch
|
||||||
|
import app.revanced.patcher.patch.PatchResult
|
||||||
|
import app.revanced.patcher.patch.PatchResultError
|
||||||
|
import app.revanced.patcher.patch.PatchResultSuccess
|
||||||
|
import app.revanced.patcher.util.smali.toBuilderInstruction
|
||||||
|
import app.revanced.patches.youtube.ad.infocardsuggestions.annotations.HideInfocardSuggestionsCompatibility
|
||||||
|
import app.revanced.patches.youtube.ad.infocardsuggestions.fingerprints.HideInfocardSuggestionsFingerprint
|
||||||
|
import app.revanced.patches.youtube.ad.infocardsuggestions.fingerprints.HideInfocardSuggestionsParentFingerprint
|
||||||
|
import app.revanced.patches.youtube.misc.integrations.patch.IntegrationsPatch
|
||||||
|
import org.jf.dexlib2.Opcode
|
||||||
|
import org.jf.dexlib2.builder.instruction.BuilderInstruction21t
|
||||||
|
import org.jf.dexlib2.builder.instruction.BuilderInstruction35c
|
||||||
|
import org.jf.dexlib2.iface.instruction.FiveRegisterInstruction
|
||||||
|
import org.jf.dexlib2.iface.instruction.NarrowLiteralInstruction
|
||||||
|
import org.jf.dexlib2.iface.instruction.OneRegisterInstruction
|
||||||
|
import org.jf.dexlib2.iface.instruction.TwoRegisterInstruction
|
||||||
|
|
||||||
|
@Patch
|
||||||
|
@Dependencies(dependencies = [IntegrationsPatch::class])
|
||||||
|
@Name("hide-infocard-suggestions")
|
||||||
|
@Description("Hides infocards in videos.")
|
||||||
|
@HideInfocardSuggestionsCompatibility
|
||||||
|
@Version("0.0.1")
|
||||||
|
class HideInfocardSuggestionsPatch : BytecodePatch(
|
||||||
|
listOf(
|
||||||
|
HideInfocardSuggestionsParentFingerprint
|
||||||
|
)
|
||||||
|
) {
|
||||||
|
override fun execute(data: BytecodeData): PatchResult {
|
||||||
|
val parentResult = HideInfocardSuggestionsParentFingerprint.result
|
||||||
|
?: return PatchResultError("Parent fingerprint not resolved!")
|
||||||
|
|
||||||
|
|
||||||
|
HideInfocardSuggestionsFingerprint.resolve(data, parentResult.classDef)
|
||||||
|
val result = HideInfocardSuggestionsFingerprint.result
|
||||||
|
?: return PatchResultError("Required parent method could not be found.")
|
||||||
|
|
||||||
|
val method = result.mutableMethod
|
||||||
|
val implementation = method.implementation
|
||||||
|
?: return PatchResultError("Implementation not found.")
|
||||||
|
|
||||||
|
val index = implementation.instructions.indexOfFirst { ((it as? BuilderInstruction35c)?.reference.toString() == "Landroid/view/View;->setVisibility(I)V") }
|
||||||
|
val register = "v" + (implementation.instructions.get(index) as FiveRegisterInstruction).registerD
|
||||||
|
|
||||||
|
method.removeInstruction(index)
|
||||||
|
|
||||||
|
method.addInstructions(
|
||||||
|
index, """
|
||||||
|
invoke-static {}, Lapp/revanced/integrations/patches/HideInfoCardSuggestionsPatch;->hideInfoCardSuggestions()I
|
||||||
|
move-result $register
|
||||||
|
invoke-virtual {p1, $register}, Landroid/view/View;->setVisibility(I)V
|
||||||
|
"""
|
||||||
|
)
|
||||||
|
|
||||||
|
return PatchResultSuccess()
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -5,7 +5,7 @@ import app.revanced.patcher.annotation.Package
|
|||||||
|
|
||||||
@Compatibility(
|
@Compatibility(
|
||||||
[Package(
|
[Package(
|
||||||
"com.google.android.youtube", arrayOf("17.14.35", "17.17.34", "17.19.36", "17.20.37", "17.22.36", "17.23.35", "17.23.36", "17.24.34","17.24.35")
|
"com.google.android.youtube", arrayOf("17.14.35", "17.17.34", "17.19.36", "17.20.37", "17.22.36", "17.23.35", "17.23.36", "17.24.34","17.24.35","17.25.34")
|
||||||
)]
|
)]
|
||||||
)
|
)
|
||||||
@Target(AnnotationTarget.CLASS)
|
@Target(AnnotationTarget.CLASS)
|
||||||
|
|||||||
@@ -1,3 +1,5 @@
|
|||||||
|
package app.revanced.patches.youtube.ad.video.fingerprints
|
||||||
|
|
||||||
import app.revanced.patcher.annotation.Name
|
import app.revanced.patcher.annotation.Name
|
||||||
import app.revanced.patcher.annotation.Version
|
import app.revanced.patcher.annotation.Version
|
||||||
import app.revanced.patcher.extensions.or
|
import app.revanced.patcher.extensions.or
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
package app.revanced.patches.youtube.ad.video.patch
|
package app.revanced.patches.youtube.ad.video.patch
|
||||||
|
|
||||||
import ShowVideoAdsFingerprint
|
|
||||||
import app.revanced.patcher.annotation.Description
|
import app.revanced.patcher.annotation.Description
|
||||||
import app.revanced.patcher.annotation.Name
|
import app.revanced.patcher.annotation.Name
|
||||||
import app.revanced.patcher.annotation.Version
|
import app.revanced.patcher.annotation.Version
|
||||||
@@ -14,6 +13,7 @@ import app.revanced.patcher.patch.annotations.Patch
|
|||||||
import app.revanced.patcher.patch.impl.BytecodePatch
|
import app.revanced.patcher.patch.impl.BytecodePatch
|
||||||
import app.revanced.patches.youtube.ad.video.annotations.VideoAdsCompatibility
|
import app.revanced.patches.youtube.ad.video.annotations.VideoAdsCompatibility
|
||||||
import app.revanced.patches.youtube.ad.video.fingerprints.ShowVideoAdsConstructorFingerprint
|
import app.revanced.patches.youtube.ad.video.fingerprints.ShowVideoAdsConstructorFingerprint
|
||||||
|
import app.revanced.patches.youtube.ad.video.fingerprints.ShowVideoAdsFingerprint
|
||||||
import app.revanced.patches.youtube.misc.integrations.patch.IntegrationsPatch
|
import app.revanced.patches.youtube.misc.integrations.patch.IntegrationsPatch
|
||||||
|
|
||||||
@Patch
|
@Patch
|
||||||
|
|||||||
@@ -0,0 +1,14 @@
|
|||||||
|
package app.revanced.patches.youtube.interaction.fenster.annotation
|
||||||
|
|
||||||
|
import app.revanced.patcher.annotation.Compatibility
|
||||||
|
import app.revanced.patcher.annotation.Package
|
||||||
|
|
||||||
|
//TODO the patch may be compatible with more versions, but this is the one i'm testing on right now...
|
||||||
|
@Compatibility(
|
||||||
|
[Package(
|
||||||
|
"com.google.android.youtube", arrayOf("17.24.34")
|
||||||
|
)]
|
||||||
|
)
|
||||||
|
@Target(AnnotationTarget.CLASS)
|
||||||
|
@Retention(AnnotationRetention.RUNTIME)
|
||||||
|
internal annotation class FensterCompatibility
|
||||||
@@ -0,0 +1,45 @@
|
|||||||
|
package app.revanced.patches.youtube.interaction.fenster.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.annotation.FuzzyPatternScanMethod
|
||||||
|
import app.revanced.patcher.fingerprint.method.annotation.MatchingMethod
|
||||||
|
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
|
||||||
|
import app.revanced.patches.youtube.interaction.fenster.annotation.FensterCompatibility
|
||||||
|
import org.jf.dexlib2.AccessFlags
|
||||||
|
import org.jf.dexlib2.Opcode
|
||||||
|
|
||||||
|
@Name("update-player-type-fingerprint")
|
||||||
|
@MatchingMethod(
|
||||||
|
"LYoutubePlayerOverlaysLayout;",
|
||||||
|
"nM"
|
||||||
|
)
|
||||||
|
@FuzzyPatternScanMethod(2)
|
||||||
|
@FensterCompatibility
|
||||||
|
@Version("0.0.1")
|
||||||
|
object UpdatePlayerTypeFingerprint : MethodFingerprint(
|
||||||
|
"V",
|
||||||
|
AccessFlags.PUBLIC or AccessFlags.FINAL,
|
||||||
|
null,
|
||||||
|
listOf(
|
||||||
|
Opcode.INVOKE_VIRTUAL,
|
||||||
|
Opcode.IGET_OBJECT,
|
||||||
|
Opcode.IF_NE,
|
||||||
|
Opcode.RETURN_VOID,
|
||||||
|
Opcode.IPUT_OBJECT,
|
||||||
|
Opcode.INVOKE_DIRECT,
|
||||||
|
Opcode.INVOKE_VIRTUAL,
|
||||||
|
Opcode.INVOKE_VIRTUAL,
|
||||||
|
Opcode.INVOKE_VIRTUAL,
|
||||||
|
Opcode.MOVE_RESULT,
|
||||||
|
Opcode.IF_EQZ,
|
||||||
|
Opcode.CONST_4,
|
||||||
|
Opcode.INVOKE_STATIC,
|
||||||
|
Opcode.RETURN_VOID,
|
||||||
|
Opcode.CONST_4,
|
||||||
|
Opcode.INVOKE_STATIC,
|
||||||
|
Opcode.INVOKE_VIRTUAL,
|
||||||
|
Opcode.RETURN_VOID
|
||||||
|
)
|
||||||
|
)
|
||||||
@@ -0,0 +1,121 @@
|
|||||||
|
package app.revanced.patches.youtube.interaction.fenster.patch
|
||||||
|
|
||||||
|
import app.revanced.extensions.injectConsumableEventHook
|
||||||
|
import app.revanced.extensions.injectIntoNamedMethod
|
||||||
|
import app.revanced.patcher.annotation.Description
|
||||||
|
import app.revanced.patcher.annotation.Name
|
||||||
|
import app.revanced.patcher.annotation.Version
|
||||||
|
import app.revanced.patcher.data.impl.BytecodeData
|
||||||
|
import app.revanced.patcher.extensions.addInstruction
|
||||||
|
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprintResult
|
||||||
|
import app.revanced.patcher.patch.PatchResult
|
||||||
|
import app.revanced.patcher.patch.PatchResultError
|
||||||
|
import app.revanced.patcher.patch.PatchResultSuccess
|
||||||
|
import app.revanced.patcher.patch.annotations.Dependencies
|
||||||
|
import app.revanced.patcher.patch.annotations.Patch
|
||||||
|
import app.revanced.patcher.patch.impl.BytecodePatch
|
||||||
|
import app.revanced.patches.youtube.interaction.fenster.annotation.FensterCompatibility
|
||||||
|
import app.revanced.patches.youtube.interaction.fenster.fingerprints.UpdatePlayerTypeFingerprint
|
||||||
|
import app.revanced.patches.youtube.misc.integrations.patch.IntegrationsPatch
|
||||||
|
import org.jf.dexlib2.immutable.reference.ImmutableMethodReference
|
||||||
|
|
||||||
|
@Patch
|
||||||
|
@Name("fenster-swipe-controls")
|
||||||
|
@Description("volume and brightness swipe controls")
|
||||||
|
@FensterCompatibility
|
||||||
|
@Version("0.0.1")
|
||||||
|
@Dependencies(dependencies = [IntegrationsPatch::class])
|
||||||
|
class FensterPatch : BytecodePatch(
|
||||||
|
listOf(
|
||||||
|
UpdatePlayerTypeFingerprint
|
||||||
|
)
|
||||||
|
) {
|
||||||
|
override fun execute(data: BytecodeData): PatchResult {
|
||||||
|
// hook WatchWhileActivity.onStart (main activity lifecycle hook)
|
||||||
|
data.injectIntoNamedMethod(
|
||||||
|
"com/google/android/apps/youtube/app/watchwhile/WatchWhileActivity",
|
||||||
|
"onStart",
|
||||||
|
0,
|
||||||
|
"invoke-static { p0 }, Lapp/revanced/integrations/patches/FensterSwipePatch;->WatchWhileActivity_onStartHookEX(Ljava/lang/Object;)V"
|
||||||
|
)
|
||||||
|
|
||||||
|
// hook YoutubePlayerOverlaysLayout.onFinishInflate (player overlays init hook)
|
||||||
|
data.injectIntoNamedMethod(
|
||||||
|
"com/google/android/apps/youtube/app/common/player/overlay/YouTubePlayerOverlaysLayout",
|
||||||
|
"onFinishInflate",
|
||||||
|
-2,
|
||||||
|
"invoke-static { p0 }, Lapp/revanced/integrations/patches/FensterSwipePatch;->YouTubePlayerOverlaysLayout_onFinishInflateHookEX(Ljava/lang/Object;)V"
|
||||||
|
)
|
||||||
|
|
||||||
|
// hook YoutubePlayerOverlaysLayout.UpdatePlayerType
|
||||||
|
injectUpdatePlayerTypeHook(
|
||||||
|
UpdatePlayerTypeFingerprint.result!!,
|
||||||
|
"com/google/android/apps/youtube/app/common/player/overlay/YouTubePlayerOverlaysLayout"
|
||||||
|
)
|
||||||
|
|
||||||
|
// hook NextGenWatchLayout.onTouchEvent and NextGenWatchLayout.onInterceptTouchEvent (player touch event hook)
|
||||||
|
injectWatchLayoutTouchHooks(
|
||||||
|
data,
|
||||||
|
"com/google/android/apps/youtube/app/watch/nextgenwatch/ui/NextGenWatchLayout"
|
||||||
|
)
|
||||||
|
|
||||||
|
return PatchResultSuccess()
|
||||||
|
}
|
||||||
|
|
||||||
|
@Suppress("SameParameterValue")
|
||||||
|
private fun injectUpdatePlayerTypeHook(fingerPrintResult: MethodFingerprintResult, targetClass: String) {
|
||||||
|
// validate fingerprint found the right class
|
||||||
|
if (!fingerPrintResult.classDef.type.endsWith("$targetClass;")) {
|
||||||
|
throw PatchResultError("$targetClass.UpdatePlayerType fingerprint could not be validated")
|
||||||
|
}
|
||||||
|
|
||||||
|
// insert the hook
|
||||||
|
fingerPrintResult.mutableMethod.addInstruction(
|
||||||
|
0,
|
||||||
|
"invoke-static { p1 }, Lapp/revanced/integrations/patches/FensterSwipePatch;->YouTubePlayerOverlaysLayout_updatePlayerTypeHookEX(Ljava/lang/Object;)V"
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Inject onTouch event hooks into the watch layout class
|
||||||
|
*
|
||||||
|
* @param data bytecode data
|
||||||
|
* @param targetClass watch layout class name
|
||||||
|
*/
|
||||||
|
@Suppress("SameParameterValue")
|
||||||
|
private fun injectWatchLayoutTouchHooks(data: BytecodeData, targetClass: String) {
|
||||||
|
var touchHooksCount = 0
|
||||||
|
data.classes.filter { it.type.endsWith("$targetClass;") }.forEach { classDef ->
|
||||||
|
// hook onTouchEvent
|
||||||
|
data.proxy(classDef).resolve().methods.filter { it.name == "onTouchEvent" }.forEach { methodDef ->
|
||||||
|
touchHooksCount++
|
||||||
|
methodDef.injectConsumableEventHook(
|
||||||
|
ImmutableMethodReference(
|
||||||
|
"Lapp/revanced/integrations/patches/FensterSwipePatch;",
|
||||||
|
"NextGenWatchLayout_onTouchEventHookEX",
|
||||||
|
listOf("Ljava/lang/Object;", "Ljava/lang/Object;"),
|
||||||
|
"Z"
|
||||||
|
)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
// hook onInterceptTouchEvent
|
||||||
|
data.proxy(classDef).resolve().methods.filter { it.name == "onInterceptTouchEvent" }.forEach { methodDef ->
|
||||||
|
touchHooksCount++
|
||||||
|
methodDef.injectConsumableEventHook(
|
||||||
|
ImmutableMethodReference(
|
||||||
|
"Lapp/revanced/integrations/patches/FensterSwipePatch;",
|
||||||
|
"NextGenWatchLayout_onInterceptTouchEventHookEX",
|
||||||
|
listOf("Ljava/lang/Object;", "Ljava/lang/Object;"),
|
||||||
|
"Z"
|
||||||
|
)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// fail if no touch hooks were inserted
|
||||||
|
if (touchHooksCount <= 0) {
|
||||||
|
throw PatchResultError("failed to inject onTouchEvent hook into NextGenWatchLayout: none found")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -5,7 +5,7 @@ import app.revanced.patcher.annotation.Package
|
|||||||
|
|
||||||
@Compatibility(
|
@Compatibility(
|
||||||
[Package(
|
[Package(
|
||||||
"com.google.android.youtube", arrayOf("17.17.34", "17.19.36", "17.20.37", "17.22.36", "17.23.35", "17.23.36", "17.24.34","17.24.35")
|
"com.google.android.youtube", arrayOf("17.17.34", "17.19.36", "17.20.37", "17.22.36", "17.23.35", "17.23.36", "17.24.34","17.24.35","17.25.34")
|
||||||
)]
|
)]
|
||||||
)
|
)
|
||||||
@Target(AnnotationTarget.CLASS)
|
@Target(AnnotationTarget.CLASS)
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ import app.revanced.patcher.annotation.Package
|
|||||||
|
|
||||||
@Compatibility(
|
@Compatibility(
|
||||||
[Package(
|
[Package(
|
||||||
"com.google.android.youtube", arrayOf("17.14.35", "17.17.34", "17.19.36", "17.20.37", "17.22.36", "17.23.35", "17.23.36", "17.24.34","17.24.35")
|
"com.google.android.youtube", arrayOf("17.14.35", "17.17.34", "17.19.36", "17.20.37", "17.22.36", "17.23.35", "17.23.36", "17.24.34","17.24.35","17.25.34")
|
||||||
)]
|
)]
|
||||||
)
|
)
|
||||||
@Target(AnnotationTarget.CLASS)
|
@Target(AnnotationTarget.CLASS)
|
||||||
|
|||||||
@@ -4,11 +4,11 @@ import app.revanced.patcher.annotation.Description
|
|||||||
import app.revanced.patcher.annotation.Name
|
import app.revanced.patcher.annotation.Name
|
||||||
import app.revanced.patcher.annotation.Version
|
import app.revanced.patcher.annotation.Version
|
||||||
import app.revanced.patcher.data.impl.ResourceData
|
import app.revanced.patcher.data.impl.ResourceData
|
||||||
|
import app.revanced.patcher.patch.PatchResult
|
||||||
|
import app.revanced.patcher.patch.PatchResultSuccess
|
||||||
import app.revanced.patcher.patch.annotations.Dependencies
|
import app.revanced.patcher.patch.annotations.Dependencies
|
||||||
import app.revanced.patcher.patch.annotations.Patch
|
import app.revanced.patcher.patch.annotations.Patch
|
||||||
import app.revanced.patcher.patch.impl.ResourcePatch
|
import app.revanced.patcher.patch.impl.ResourcePatch
|
||||||
import app.revanced.patcher.patch.PatchResult
|
|
||||||
import app.revanced.patcher.patch.PatchResultSuccess
|
|
||||||
import app.revanced.patches.youtube.layout.amoled.annotations.AmoledCompatibility
|
import app.revanced.patches.youtube.layout.amoled.annotations.AmoledCompatibility
|
||||||
import app.revanced.patches.youtube.misc.manifest.patch.FixLocaleConfigErrorPatch
|
import app.revanced.patches.youtube.misc.manifest.patch.FixLocaleConfigErrorPatch
|
||||||
import org.w3c.dom.Element
|
import org.w3c.dom.Element
|
||||||
@@ -26,7 +26,7 @@ import java.io.File
|
|||||||
@Version("0.0.1")
|
@Version("0.0.1")
|
||||||
class AmoledPatch : ResourcePatch() {
|
class AmoledPatch : ResourcePatch() {
|
||||||
override fun execute(data: ResourceData): PatchResult {
|
override fun execute(data: ResourceData): PatchResult {
|
||||||
data.getXmlEditor("res${File.separator}values${File.separator}colors.xml").use { editor ->
|
data.xmlEditor["res${File.separator}values${File.separator}colors.xml"].use { editor ->
|
||||||
val resourcesNode = editor.file.getElementsByTagName("resources").item(0) as Element
|
val resourcesNode = editor.file.getElementsByTagName("resources").item(0) as Element
|
||||||
|
|
||||||
for (i in 0 until resourcesNode.childNodes.length) {
|
for (i in 0 until resourcesNode.childNodes.length) {
|
||||||
|
|||||||
@@ -0,0 +1,13 @@
|
|||||||
|
package app.revanced.patches.youtube.layout.autoplaybutton.annotations
|
||||||
|
|
||||||
|
import app.revanced.patcher.annotation.Compatibility
|
||||||
|
import app.revanced.patcher.annotation.Package
|
||||||
|
|
||||||
|
@Compatibility(
|
||||||
|
[Package(
|
||||||
|
"com.google.android.youtube", arrayOf("17.25.34")
|
||||||
|
)]
|
||||||
|
)
|
||||||
|
@Target(AnnotationTarget.CLASS)
|
||||||
|
@Retention(AnnotationRetention.RUNTIME)
|
||||||
|
internal annotation class AutoplayButtonCompatibility
|
||||||
@@ -0,0 +1,34 @@
|
|||||||
|
package app.revanced.patches.youtube.layout.autoplaybutton.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.annotation.FuzzyPatternScanMethod
|
||||||
|
import app.revanced.patcher.fingerprint.method.annotation.MatchingMethod
|
||||||
|
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
|
||||||
|
import app.revanced.patches.youtube.layout.autoplaybutton.annotations.AutoplayButtonCompatibility
|
||||||
|
import org.jf.dexlib2.AccessFlags
|
||||||
|
import org.jf.dexlib2.Opcode
|
||||||
|
|
||||||
|
@Name("autonav-informer-fingerprint")
|
||||||
|
@MatchingMethod(
|
||||||
|
"LWillAutonavInformer;", "k"
|
||||||
|
)
|
||||||
|
@FuzzyPatternScanMethod(2)
|
||||||
|
@AutoplayButtonCompatibility
|
||||||
|
@Version("0.0.1")
|
||||||
|
object AutonavInformerFingerprint : MethodFingerprint(
|
||||||
|
"Z",
|
||||||
|
AccessFlags.PUBLIC or AccessFlags.FINAL,
|
||||||
|
null,
|
||||||
|
listOf(
|
||||||
|
Opcode.IGET_OBJECT,
|
||||||
|
Opcode.INVOKE_INTERFACE,
|
||||||
|
Opcode.MOVE_RESULT_OBJECT,
|
||||||
|
Opcode.CHECK_CAST,
|
||||||
|
Opcode.INVOKE_VIRTUAL,
|
||||||
|
Opcode.MOVE_RESULT,
|
||||||
|
),
|
||||||
|
null,
|
||||||
|
{ it.definingClass.endsWith("WillAutonavInformer;") }
|
||||||
|
)
|
||||||
@@ -0,0 +1,32 @@
|
|||||||
|
package app.revanced.patches.youtube.layout.autoplaybutton.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.annotation.FuzzyPatternScanMethod
|
||||||
|
import app.revanced.patcher.fingerprint.method.annotation.MatchingMethod
|
||||||
|
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
|
||||||
|
import app.revanced.patches.youtube.layout.autoplaybutton.annotations.AutoplayButtonCompatibility
|
||||||
|
import org.jf.dexlib2.AccessFlags
|
||||||
|
import org.jf.dexlib2.Opcode
|
||||||
|
|
||||||
|
@Name("layout-constructor-fingerprint")
|
||||||
|
@MatchingMethod(
|
||||||
|
"LYouTubeControlsOverlay;", "F"
|
||||||
|
)
|
||||||
|
@FuzzyPatternScanMethod(2)
|
||||||
|
@AutoplayButtonCompatibility
|
||||||
|
@Version("0.0.1")
|
||||||
|
object LayoutConstructorFingerprint : MethodFingerprint(
|
||||||
|
"V",
|
||||||
|
AccessFlags.PUBLIC or AccessFlags.FINAL,
|
||||||
|
null,
|
||||||
|
listOf(
|
||||||
|
Opcode.CONST,
|
||||||
|
Opcode.INVOKE_VIRTUAL,
|
||||||
|
Opcode.MOVE_RESULT_OBJECT,
|
||||||
|
Opcode.CHECK_CAST,
|
||||||
|
Opcode.INVOKE_VIRTUAL,
|
||||||
|
),
|
||||||
|
listOf("1.0x")
|
||||||
|
)
|
||||||
@@ -0,0 +1,61 @@
|
|||||||
|
package app.revanced.patches.youtube.layout.autoplaybutton.patch
|
||||||
|
|
||||||
|
import app.revanced.patcher.annotation.Description
|
||||||
|
import app.revanced.patcher.annotation.Name
|
||||||
|
import app.revanced.patcher.annotation.Version
|
||||||
|
import app.revanced.patcher.data.impl.BytecodeData
|
||||||
|
import app.revanced.patcher.extensions.removeInstructions
|
||||||
|
import app.revanced.patcher.extensions.replaceInstructions
|
||||||
|
import app.revanced.patcher.patch.PatchResult
|
||||||
|
import app.revanced.patcher.patch.PatchResultSuccess
|
||||||
|
import app.revanced.patcher.patch.annotations.Dependencies
|
||||||
|
import app.revanced.patcher.patch.annotations.Patch
|
||||||
|
import app.revanced.patcher.patch.impl.BytecodePatch
|
||||||
|
import app.revanced.patches.youtube.layout.autoplaybutton.annotations.AutoplayButtonCompatibility
|
||||||
|
import app.revanced.patches.youtube.layout.autoplaybutton.fingerprints.AutonavInformerFingerprint
|
||||||
|
import app.revanced.patches.youtube.layout.autoplaybutton.fingerprints.LayoutConstructorFingerprint
|
||||||
|
import app.revanced.patches.youtube.misc.mapping.patch.ResourceIdMappingProviderResourcePatch
|
||||||
|
import org.jf.dexlib2.iface.instruction.WideLiteralInstruction
|
||||||
|
|
||||||
|
@Patch
|
||||||
|
@Dependencies(dependencies = [ResourceIdMappingProviderResourcePatch::class])
|
||||||
|
@Name("hide-autoplay-button")
|
||||||
|
@Description("Disable the autoplay button.")
|
||||||
|
@AutoplayButtonCompatibility
|
||||||
|
@Version("0.0.1")
|
||||||
|
class HideAutoplayButton : BytecodePatch(
|
||||||
|
listOf(
|
||||||
|
LayoutConstructorFingerprint, AutonavInformerFingerprint
|
||||||
|
)
|
||||||
|
) {
|
||||||
|
override fun execute(data: BytecodeData): PatchResult {
|
||||||
|
val layoutGenMethod = LayoutConstructorFingerprint.result!!.mutableMethod
|
||||||
|
|
||||||
|
val autonavToggle =
|
||||||
|
ResourceIdMappingProviderResourcePatch.resourceMappings.first { it.type == "id" && it.name == "autonav_toggle" }
|
||||||
|
val autonavPreviewStub =
|
||||||
|
ResourceIdMappingProviderResourcePatch.resourceMappings.first { it.type == "id" && it.name == "autonav_preview_stub" }
|
||||||
|
|
||||||
|
val autonavToggleConstIndex =
|
||||||
|
layoutGenMethod.implementation!!.instructions.indexOfFirst { (it as? WideLiteralInstruction)?.wideLiteral == autonavToggle.id }
|
||||||
|
val autonavPreviewStubConstIndex =
|
||||||
|
layoutGenMethod.implementation!!.instructions.indexOfFirst { (it as? WideLiteralInstruction)?.wideLiteral == autonavPreviewStub.id }
|
||||||
|
|
||||||
|
//remove adding autoplay button to the layout
|
||||||
|
layoutGenMethod.removeInstructions(autonavToggleConstIndex, 5)
|
||||||
|
layoutGenMethod.removeInstructions(autonavPreviewStubConstIndex, 5)
|
||||||
|
|
||||||
|
val autonavInformerMethod = AutonavInformerFingerprint.result!!.mutableMethod
|
||||||
|
|
||||||
|
//force disable autoplay since it's hard to do without the button
|
||||||
|
autonavInformerMethod.replaceInstructions(
|
||||||
|
0,
|
||||||
|
"""
|
||||||
|
const/4 v0, 0x0
|
||||||
|
return v0
|
||||||
|
"""
|
||||||
|
)
|
||||||
|
|
||||||
|
return PatchResultSuccess()
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -4,16 +4,17 @@ import app.revanced.patcher.annotation.Description
|
|||||||
import app.revanced.patcher.annotation.Name
|
import app.revanced.patcher.annotation.Name
|
||||||
import app.revanced.patcher.annotation.Version
|
import app.revanced.patcher.annotation.Version
|
||||||
import app.revanced.patcher.data.impl.ResourceData
|
import app.revanced.patcher.data.impl.ResourceData
|
||||||
import app.revanced.patcher.patch.annotations.Dependencies
|
|
||||||
import app.revanced.patcher.patch.annotations.Patch
|
|
||||||
import app.revanced.patcher.patch.impl.ResourcePatch
|
|
||||||
import app.revanced.patcher.patch.PatchResult
|
import app.revanced.patcher.patch.PatchResult
|
||||||
import app.revanced.patcher.patch.PatchResultError
|
import app.revanced.patcher.patch.PatchResultError
|
||||||
import app.revanced.patcher.patch.PatchResultSuccess
|
import app.revanced.patcher.patch.PatchResultSuccess
|
||||||
|
import app.revanced.patcher.patch.annotations.Dependencies
|
||||||
|
import app.revanced.patcher.patch.annotations.Patch
|
||||||
|
import app.revanced.patcher.patch.impl.ResourcePatch
|
||||||
import app.revanced.patches.youtube.layout.branding.header.annotations.PremiumHeadingCompatibility
|
import app.revanced.patches.youtube.layout.branding.header.annotations.PremiumHeadingCompatibility
|
||||||
import app.revanced.patches.youtube.misc.manifest.patch.FixLocaleConfigErrorPatch
|
import app.revanced.patches.youtube.misc.manifest.patch.FixLocaleConfigErrorPatch
|
||||||
import java.nio.file.Files
|
import java.nio.file.Files
|
||||||
import java.nio.file.StandardCopyOption
|
import java.nio.file.StandardCopyOption
|
||||||
|
import kotlin.io.path.exists
|
||||||
|
|
||||||
@Patch
|
@Patch
|
||||||
@Dependencies(
|
@Dependencies(
|
||||||
@@ -25,7 +26,7 @@ import java.nio.file.StandardCopyOption
|
|||||||
@Version("0.0.1")
|
@Version("0.0.1")
|
||||||
class PremiumHeadingPatch : ResourcePatch() {
|
class PremiumHeadingPatch : ResourcePatch() {
|
||||||
override fun execute(data: ResourceData): PatchResult {
|
override fun execute(data: ResourceData): PatchResult {
|
||||||
val resDirectory = data.get("res")
|
val resDirectory = data["res"]
|
||||||
if (!resDirectory.isDirectory) return PatchResultError("The res folder can not be found.")
|
if (!resDirectory.isDirectory) return PatchResultError("The res folder can not be found.")
|
||||||
|
|
||||||
val (original, replacement) = "yt_premium_wordmark_header" to "yt_wordmark_header"
|
val (original, replacement) = "yt_premium_wordmark_header" to "yt_wordmark_header"
|
||||||
@@ -34,9 +35,14 @@ class PremiumHeadingPatch : ResourcePatch() {
|
|||||||
arrayOf("xxxhdpi", "xxhdpi", "xhdpi", "hdpi", "mdpi").forEach { size ->
|
arrayOf("xxxhdpi", "xxhdpi", "xhdpi", "hdpi", "mdpi").forEach { size ->
|
||||||
val headingDirectory = resDirectory.resolve("drawable-$size")
|
val headingDirectory = resDirectory.resolve("drawable-$size")
|
||||||
modes.forEach {mode ->
|
modes.forEach {mode ->
|
||||||
|
val fromPath = headingDirectory.resolve("${original}_$mode.png").toPath()
|
||||||
|
val toPath = headingDirectory.resolve("${replacement}_$mode.png").toPath()
|
||||||
|
|
||||||
|
if (!fromPath.exists())
|
||||||
|
return PatchResultError("The file $fromPath does not exist in the resources. Therefore, this patch can not succeed.")
|
||||||
Files.copy(
|
Files.copy(
|
||||||
headingDirectory.resolve("${original}_$mode.png").toPath(),
|
fromPath,
|
||||||
headingDirectory.resolve("${replacement}_$mode.png").toPath(),
|
toPath,
|
||||||
StandardCopyOption.REPLACE_EXISTING
|
StandardCopyOption.REPLACE_EXISTING
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,12 +4,12 @@ import app.revanced.patcher.annotation.Description
|
|||||||
import app.revanced.patcher.annotation.Name
|
import app.revanced.patcher.annotation.Name
|
||||||
import app.revanced.patcher.annotation.Version
|
import app.revanced.patcher.annotation.Version
|
||||||
import app.revanced.patcher.data.impl.ResourceData
|
import app.revanced.patcher.data.impl.ResourceData
|
||||||
import app.revanced.patcher.patch.annotations.Dependencies
|
|
||||||
import app.revanced.patcher.patch.annotations.Patch
|
|
||||||
import app.revanced.patcher.patch.impl.ResourcePatch
|
|
||||||
import app.revanced.patcher.patch.PatchResult
|
import app.revanced.patcher.patch.PatchResult
|
||||||
import app.revanced.patcher.patch.PatchResultError
|
import app.revanced.patcher.patch.PatchResultError
|
||||||
import app.revanced.patcher.patch.PatchResultSuccess
|
import app.revanced.patcher.patch.PatchResultSuccess
|
||||||
|
import app.revanced.patcher.patch.annotations.Dependencies
|
||||||
|
import app.revanced.patcher.patch.annotations.Patch
|
||||||
|
import app.revanced.patcher.patch.impl.ResourcePatch
|
||||||
import app.revanced.patches.youtube.layout.branding.icon.annotations.CustomBrandingCompatibility
|
import app.revanced.patches.youtube.layout.branding.icon.annotations.CustomBrandingCompatibility
|
||||||
import app.revanced.patches.youtube.misc.manifest.patch.FixLocaleConfigErrorPatch
|
import app.revanced.patches.youtube.misc.manifest.patch.FixLocaleConfigErrorPatch
|
||||||
import java.nio.file.Files
|
import java.nio.file.Files
|
||||||
@@ -24,7 +24,7 @@ import java.nio.file.Files
|
|||||||
@Version("0.0.1")
|
@Version("0.0.1")
|
||||||
class CustomBrandingPatch : ResourcePatch() {
|
class CustomBrandingPatch : ResourcePatch() {
|
||||||
override fun execute(data: ResourceData): PatchResult {
|
override fun execute(data: ResourceData): PatchResult {
|
||||||
val resDirectory = data.get("res")
|
val resDirectory = data["res"]
|
||||||
if (!resDirectory.isDirectory) return PatchResultError("The res folder can not be found.")
|
if (!resDirectory.isDirectory) return PatchResultError("The res folder can not be found.")
|
||||||
|
|
||||||
val iconNames = arrayOf(
|
val iconNames = arrayOf(
|
||||||
|
|||||||
@@ -19,7 +19,7 @@ import app.revanced.patches.youtube.misc.integrations.patch.IntegrationsPatch
|
|||||||
@Description("Patch to hide the cast button.")
|
@Description("Patch to hide the cast button.")
|
||||||
@CastButtonCompatibility
|
@CastButtonCompatibility
|
||||||
@Version("0.0.1")
|
@Version("0.0.1")
|
||||||
class HideCastButtonPatch : BytecodePatch(listOf()) {
|
class HideCastButtonPatch : BytecodePatch() {
|
||||||
override fun execute(data: BytecodeData): PatchResult {
|
override fun execute(data: BytecodeData): PatchResult {
|
||||||
data.classes.forEach { classDef ->
|
data.classes.forEach { classDef ->
|
||||||
classDef.methods.forEach { method ->
|
classDef.methods.forEach { method ->
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ import app.revanced.patcher.annotation.Package
|
|||||||
|
|
||||||
@Compatibility(
|
@Compatibility(
|
||||||
[Package(
|
[Package(
|
||||||
"com.google.android.youtube", arrayOf("17.14.35", "17.17.34", "17.19.36", "17.20.37", "17.22.36", "17.23.35", "17.23.36", "17.24.34","17.24.35")
|
"com.google.android.youtube", arrayOf("17.14.35", "17.17.34", "17.19.36", "17.20.37", "17.22.36", "17.23.35", "17.23.36", "17.24.34","17.24.35","17.25.34")
|
||||||
)]
|
)]
|
||||||
)
|
)
|
||||||
@Target(AnnotationTarget.CLASS)
|
@Target(AnnotationTarget.CLASS)
|
||||||
|
|||||||
@@ -38,11 +38,11 @@ class CreateButtonRemoverPatch : BytecodePatch(
|
|||||||
// Get the required register which holds the view object we need to pass to the method hideCreateButton
|
// Get the required register which holds the view object we need to pass to the method hideCreateButton
|
||||||
val implementation = result.mutableMethod.implementation!!
|
val implementation = result.mutableMethod.implementation!!
|
||||||
|
|
||||||
val imageOnlyLayout = ResourceIdMappingProviderResourcePatch.resourceMappings["image_only_tab"]
|
val imageOnlyLayout =
|
||||||
?: return PatchResultError("Required resource could not be found in the map")
|
ResourceIdMappingProviderResourcePatch.resourceMappings.first { it.type == "layout" && it.name == "image_only_tab" }
|
||||||
|
|
||||||
val imageOnlyLayoutConstIndex =
|
val imageOnlyLayoutConstIndex =
|
||||||
implementation.instructions.indexOfFirst { (it as? WideLiteralInstruction)?.wideLiteral == imageOnlyLayout }
|
implementation.instructions.indexOfFirst { (it as? WideLiteralInstruction)?.wideLiteral == imageOnlyLayout.id }
|
||||||
|
|
||||||
val (instructionIndex, instruction) = implementation.instructions.drop(imageOnlyLayoutConstIndex).withIndex()
|
val (instructionIndex, instruction) = implementation.instructions.drop(imageOnlyLayoutConstIndex).withIndex()
|
||||||
.first {
|
.first {
|
||||||
@@ -63,4 +63,4 @@ class CreateButtonRemoverPatch : BytecodePatch(
|
|||||||
|
|
||||||
return PatchResultSuccess()
|
return PatchResultSuccess()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ import app.revanced.patcher.annotation.Package
|
|||||||
|
|
||||||
@Compatibility(
|
@Compatibility(
|
||||||
[Package(
|
[Package(
|
||||||
"com.google.android.youtube", arrayOf("17.23.35", "17.23.36", "17.24.34","17.24.35")
|
"com.google.android.youtube", arrayOf("17.23.35", "17.23.36", "17.24.34","17.24.35","17.25.34")
|
||||||
)]
|
)]
|
||||||
)
|
)
|
||||||
@Target(AnnotationTarget.CLASS)
|
@Target(AnnotationTarget.CLASS)
|
||||||
|
|||||||
@@ -0,0 +1,32 @@
|
|||||||
|
package app.revanced.patches.youtube.layout.fullscreenpanels.fingerprints
|
||||||
|
|
||||||
|
import app.revanced.patcher.annotation.Name
|
||||||
|
import app.revanced.patcher.annotation.Version
|
||||||
|
import app.revanced.patcher.fingerprint.method.annotation.FuzzyPatternScanMethod
|
||||||
|
import app.revanced.patcher.fingerprint.method.annotation.MatchingMethod
|
||||||
|
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
|
||||||
|
import app.revanced.patches.youtube.layout.shorts.button.annotations.ShortsButtonCompatibility
|
||||||
|
import org.jf.dexlib2.Opcode
|
||||||
|
|
||||||
|
@Name("fullscreen-view-adder-fingerprint")
|
||||||
|
@MatchingMethod(
|
||||||
|
"LFullscreenEngagementPanelOverlay;", "e"
|
||||||
|
)
|
||||||
|
@FuzzyPatternScanMethod(2)
|
||||||
|
@ShortsButtonCompatibility
|
||||||
|
@Version("0.0.1")
|
||||||
|
object FullscreenViewAdderFingerprint : MethodFingerprint(
|
||||||
|
null,
|
||||||
|
null,
|
||||||
|
listOf("L", "L"),
|
||||||
|
listOf(
|
||||||
|
Opcode.GOTO,
|
||||||
|
Opcode.IGET_BOOLEAN,
|
||||||
|
Opcode.IF_EQ,
|
||||||
|
Opcode.GOTO,
|
||||||
|
Opcode.CONST_4,
|
||||||
|
Opcode.INVOKE_VIRTUAL,
|
||||||
|
),
|
||||||
|
null,
|
||||||
|
{ it.definingClass.endsWith("FullscreenEngagementPanelOverlay;") }
|
||||||
|
)
|
||||||
@@ -4,31 +4,47 @@ import app.revanced.patcher.annotation.Description
|
|||||||
import app.revanced.patcher.annotation.Name
|
import app.revanced.patcher.annotation.Name
|
||||||
import app.revanced.patcher.annotation.Version
|
import app.revanced.patcher.annotation.Version
|
||||||
import app.revanced.patcher.data.impl.BytecodeData
|
import app.revanced.patcher.data.impl.BytecodeData
|
||||||
import app.revanced.patcher.extensions.addInstructions
|
import app.revanced.patcher.extensions.addInstruction
|
||||||
import app.revanced.patcher.patch.annotations.Patch
|
import app.revanced.patcher.extensions.removeInstruction
|
||||||
import app.revanced.patcher.patch.impl.BytecodePatch
|
|
||||||
import app.revanced.patcher.patch.PatchResult
|
import app.revanced.patcher.patch.PatchResult
|
||||||
import app.revanced.patcher.patch.PatchResultSuccess
|
import app.revanced.patcher.patch.PatchResultSuccess
|
||||||
|
import app.revanced.patcher.patch.annotations.Patch
|
||||||
|
import app.revanced.patcher.patch.impl.BytecodePatch
|
||||||
import app.revanced.patches.youtube.layout.fullscreenpanels.annotations.FullscreenPanelsCompatibility
|
import app.revanced.patches.youtube.layout.fullscreenpanels.annotations.FullscreenPanelsCompatibility
|
||||||
|
import app.revanced.patches.youtube.layout.fullscreenpanels.fingerprints.FullscreenViewAdderFingerprint
|
||||||
|
import org.jf.dexlib2.Opcode
|
||||||
|
import org.jf.dexlib2.iface.instruction.FiveRegisterInstruction
|
||||||
|
import org.jf.dexlib2.iface.instruction.ReferenceInstruction
|
||||||
|
import org.jf.dexlib2.iface.reference.MethodReference
|
||||||
|
|
||||||
@Patch
|
@Patch
|
||||||
@Name("disable-fullscreen-panels")
|
@Name("disable-fullscreen-panels")
|
||||||
@Description("Disable comments panel in fullscreen view.")
|
@Description("Disable comments panel in fullscreen view.")
|
||||||
@FullscreenPanelsCompatibility
|
@FullscreenPanelsCompatibility
|
||||||
@Version("0.0.1")
|
@Version("0.0.1")
|
||||||
class FullscreenPanelsRemovalPatch : BytecodePatch(listOf()) {
|
class FullscreenPanelsRemovalPatch : BytecodePatch(
|
||||||
|
listOf(
|
||||||
|
FullscreenViewAdderFingerprint
|
||||||
|
)
|
||||||
|
) {
|
||||||
override fun execute(data: BytecodeData): PatchResult {
|
override fun execute(data: BytecodeData): PatchResult {
|
||||||
val classDef = data.classes.first { it.type.endsWith("FullscreenEngagementPanelOverlay;") }
|
val method = FullscreenViewAdderFingerprint.result?.mutableMethod!!
|
||||||
val method = data.proxy(classDef).resolve().methods.first { it.name == "<init>" }
|
|
||||||
val implementation = method.implementation!!
|
val implementation = method.implementation!!
|
||||||
|
|
||||||
method.addInstructions(
|
val (visibilityCallIndex, visibilityCall) =
|
||||||
implementation.instructions.count() - 1,
|
implementation.instructions.withIndex()
|
||||||
"""
|
.first { ((it.value as? ReferenceInstruction)?.reference as? MethodReference)?.name == ("setVisibility") }
|
||||||
const/4 v1, 0x0
|
|
||||||
iput-boolean v1, v0, ${classDef.type}->a:Z
|
val gotoIndex =
|
||||||
"""
|
implementation.instructions.subList(0, visibilityCallIndex).indexOfLast { it.opcode == Opcode.GOTO }
|
||||||
)
|
|
||||||
|
//force the if
|
||||||
|
method.removeInstruction(gotoIndex)
|
||||||
|
|
||||||
|
val visibilityIntRegister = (visibilityCall as FiveRegisterInstruction).registerD
|
||||||
|
|
||||||
|
//set the visibility to GONE
|
||||||
|
method.addInstruction(visibilityCallIndex - 1, "const/16 v$visibilityIntRegister, 0x8")
|
||||||
|
|
||||||
return PatchResultSuccess()
|
return PatchResultSuccess()
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ import app.revanced.patcher.annotation.Package
|
|||||||
|
|
||||||
@Compatibility(
|
@Compatibility(
|
||||||
[Package(
|
[Package(
|
||||||
"com.google.android.youtube", arrayOf("17.14.35", "17.17.34", "17.19.36", "17.20.37", "17.22.36", "17.23.35", "17.23.36", "17.24.34","17.24.35")
|
"com.google.android.youtube", arrayOf("17.14.35", "17.17.34", "17.19.36", "17.20.37", "17.22.36", "17.23.35", "17.23.36", "17.24.34","17.24.35","17.25.34")
|
||||||
)]
|
)]
|
||||||
)
|
)
|
||||||
@Target(AnnotationTarget.CLASS)
|
@Target(AnnotationTarget.CLASS)
|
||||||
|
|||||||
@@ -0,0 +1,37 @@
|
|||||||
|
package app.revanced.patches.youtube.layout.minimizedplayback.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.annotation.FuzzyPatternScanMethod
|
||||||
|
import app.revanced.patcher.fingerprint.method.annotation.MatchingMethod
|
||||||
|
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
|
||||||
|
import app.revanced.patches.youtube.layout.minimizedplayback.annotations.MinimizedPlaybackCompatibility
|
||||||
|
import app.revanced.patches.youtube.misc.mapping.patch.ResourceIdMappingProviderResourcePatch
|
||||||
|
import org.jf.dexlib2.AccessFlags
|
||||||
|
import org.jf.dexlib2.Opcode
|
||||||
|
import org.jf.dexlib2.iface.instruction.WideLiteralInstruction
|
||||||
|
|
||||||
|
@Name("minimized-playback-manager-fingerprint")
|
||||||
|
@MatchingMethod(
|
||||||
|
"Ladj", "w"
|
||||||
|
)
|
||||||
|
@FuzzyPatternScanMethod(2)
|
||||||
|
@MinimizedPlaybackCompatibility
|
||||||
|
@Version("0.0.1")
|
||||||
|
object MinimizedPlaybackSettingsFingerprint : MethodFingerprint(
|
||||||
|
"L",
|
||||||
|
AccessFlags.PUBLIC or AccessFlags.FINAL,
|
||||||
|
null,
|
||||||
|
listOf(
|
||||||
|
Opcode.INVOKE_VIRTUAL,
|
||||||
|
Opcode.MOVE_RESULT,
|
||||||
|
Opcode.INVOKE_VIRTUAL,
|
||||||
|
Opcode.MOVE_RESULT,
|
||||||
|
Opcode.IF_EQZ,
|
||||||
|
Opcode.IF_NEZ,
|
||||||
|
Opcode.GOTO,
|
||||||
|
Opcode.IGET_OBJECT,
|
||||||
|
Opcode.CHECK_CAST
|
||||||
|
),
|
||||||
|
)
|
||||||
@@ -3,14 +3,20 @@ package app.revanced.patches.youtube.layout.minimizedplayback.patch
|
|||||||
import app.revanced.patcher.annotation.Description
|
import app.revanced.patcher.annotation.Description
|
||||||
import app.revanced.patcher.annotation.Name
|
import app.revanced.patcher.annotation.Name
|
||||||
import app.revanced.patcher.annotation.Version
|
import app.revanced.patcher.annotation.Version
|
||||||
import app.revanced.patcher.extensions.addInstructions
|
|
||||||
import app.revanced.patcher.data.impl.BytecodeData
|
import app.revanced.patcher.data.impl.BytecodeData
|
||||||
import app.revanced.patcher.patch.annotations.Patch
|
import app.revanced.patcher.data.impl.toMethodWalker
|
||||||
import app.revanced.patcher.patch.impl.BytecodePatch
|
import app.revanced.patcher.extensions.addInstructions
|
||||||
import app.revanced.patcher.patch.PatchResult
|
import app.revanced.patcher.patch.PatchResult
|
||||||
import app.revanced.patcher.patch.PatchResultSuccess
|
import app.revanced.patcher.patch.PatchResultSuccess
|
||||||
|
import app.revanced.patcher.patch.annotations.Patch
|
||||||
|
import app.revanced.patcher.patch.impl.BytecodePatch
|
||||||
|
import app.revanced.patcher.util.proxy.mutableTypes.MutableMethod
|
||||||
import app.revanced.patches.youtube.layout.minimizedplayback.annotations.MinimizedPlaybackCompatibility
|
import app.revanced.patches.youtube.layout.minimizedplayback.annotations.MinimizedPlaybackCompatibility
|
||||||
import app.revanced.patches.youtube.layout.minimizedplayback.fingerprints.MinimizedPlaybackManagerFingerprint
|
import app.revanced.patches.youtube.layout.minimizedplayback.fingerprints.MinimizedPlaybackManagerFingerprint
|
||||||
|
import app.revanced.patches.youtube.layout.minimizedplayback.fingerprints.MinimizedPlaybackSettingsFingerprint
|
||||||
|
import app.revanced.patches.youtube.misc.mapping.patch.ResourceIdMappingProviderResourcePatch
|
||||||
|
import org.jf.dexlib2.iface.instruction.ReferenceInstruction
|
||||||
|
import org.jf.dexlib2.iface.reference.MethodReference
|
||||||
|
|
||||||
|
|
||||||
@Patch
|
@Patch
|
||||||
@@ -20,7 +26,7 @@ import app.revanced.patches.youtube.layout.minimizedplayback.fingerprints.Minimi
|
|||||||
@Version("0.0.1")
|
@Version("0.0.1")
|
||||||
class MinimizedPlaybackPatch : BytecodePatch(
|
class MinimizedPlaybackPatch : BytecodePatch(
|
||||||
listOf(
|
listOf(
|
||||||
MinimizedPlaybackManagerFingerprint
|
MinimizedPlaybackManagerFingerprint, MinimizedPlaybackSettingsFingerprint
|
||||||
)
|
)
|
||||||
) {
|
) {
|
||||||
override fun execute(data: BytecodeData): PatchResult {
|
override fun execute(data: BytecodeData): PatchResult {
|
||||||
@@ -32,6 +38,22 @@ class MinimizedPlaybackPatch : BytecodePatch(
|
|||||||
return v0
|
return v0
|
||||||
"""
|
"""
|
||||||
)
|
)
|
||||||
|
|
||||||
|
val method = MinimizedPlaybackSettingsFingerprint.result!!.mutableMethod
|
||||||
|
val booleanCalls = method.implementation!!.instructions.withIndex()
|
||||||
|
.filter { ((it.value as? ReferenceInstruction)?.reference as? MethodReference)?.returnType == "Z" }
|
||||||
|
|
||||||
|
val settingsBooleanIndex = booleanCalls.elementAt(1).index
|
||||||
|
val settingsBooleanMethod =
|
||||||
|
data.toMethodWalker(method).nextMethod(settingsBooleanIndex, true).getMethod() as MutableMethod
|
||||||
|
|
||||||
|
settingsBooleanMethod.addInstructions(
|
||||||
|
0, """
|
||||||
|
const/4 v0, 0x1
|
||||||
|
return v0
|
||||||
|
"""
|
||||||
|
)
|
||||||
|
|
||||||
return PatchResultSuccess()
|
return PatchResultSuccess()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ import app.revanced.patcher.annotation.Package
|
|||||||
|
|
||||||
@Compatibility(
|
@Compatibility(
|
||||||
[Package(
|
[Package(
|
||||||
"com.google.android.youtube", arrayOf("17.17.34", "17.19.36", "17.20.37", "17.22.36", "17.23.35", "17.23.36", "17.24.34","17.24.35")
|
"com.google.android.youtube", arrayOf("17.17.34", "17.19.36", "17.20.37", "17.22.36", "17.23.35", "17.23.36", "17.24.34","17.24.35","17.25.34")
|
||||||
)]
|
)]
|
||||||
)
|
)
|
||||||
@Target(AnnotationTarget.CLASS)
|
@Target(AnnotationTarget.CLASS)
|
||||||
|
|||||||
@@ -1,3 +1,5 @@
|
|||||||
|
package app.revanced.patches.youtube.layout.oldqualitylayout.fingerprints
|
||||||
|
|
||||||
import app.revanced.patcher.annotation.Name
|
import app.revanced.patcher.annotation.Name
|
||||||
import app.revanced.patcher.annotation.Version
|
import app.revanced.patcher.annotation.Version
|
||||||
import app.revanced.patcher.extensions.or
|
import app.revanced.patcher.extensions.or
|
||||||
|
|||||||
@@ -1,19 +1,19 @@
|
|||||||
package app.revanced.patches.youtube.layout.oldqualitylayout.patch
|
package app.revanced.patches.youtube.layout.oldqualitylayout.patch
|
||||||
|
|
||||||
import OldQualityFingerprint
|
|
||||||
import app.revanced.patcher.annotation.Description
|
import app.revanced.patcher.annotation.Description
|
||||||
import app.revanced.patcher.annotation.Name
|
import app.revanced.patcher.annotation.Name
|
||||||
import app.revanced.patcher.annotation.Version
|
import app.revanced.patcher.annotation.Version
|
||||||
import app.revanced.patcher.data.impl.BytecodeData
|
import app.revanced.patcher.data.impl.BytecodeData
|
||||||
import app.revanced.patcher.extensions.addInstructions
|
import app.revanced.patcher.extensions.addInstructions
|
||||||
import app.revanced.patcher.fingerprint.method.utils.MethodFingerprintUtils.resolve
|
import app.revanced.patcher.fingerprint.method.utils.MethodFingerprintUtils.resolve
|
||||||
import app.revanced.patcher.patch.annotations.Dependencies
|
|
||||||
import app.revanced.patcher.patch.annotations.Patch
|
|
||||||
import app.revanced.patcher.patch.impl.BytecodePatch
|
|
||||||
import app.revanced.patcher.patch.PatchResult
|
import app.revanced.patcher.patch.PatchResult
|
||||||
import app.revanced.patcher.patch.PatchResultError
|
import app.revanced.patcher.patch.PatchResultError
|
||||||
import app.revanced.patcher.patch.PatchResultSuccess
|
import app.revanced.patcher.patch.PatchResultSuccess
|
||||||
|
import app.revanced.patcher.patch.annotations.Dependencies
|
||||||
|
import app.revanced.patcher.patch.annotations.Patch
|
||||||
|
import app.revanced.patcher.patch.impl.BytecodePatch
|
||||||
import app.revanced.patches.youtube.layout.oldqualitylayout.annotations.OldQualityLayoutCompatibility
|
import app.revanced.patches.youtube.layout.oldqualitylayout.annotations.OldQualityLayoutCompatibility
|
||||||
|
import app.revanced.patches.youtube.layout.oldqualitylayout.fingerprints.OldQualityFingerprint
|
||||||
import app.revanced.patches.youtube.layout.oldqualitylayout.fingerprints.OldQualityParentFingerprint
|
import app.revanced.patches.youtube.layout.oldqualitylayout.fingerprints.OldQualityParentFingerprint
|
||||||
import app.revanced.patches.youtube.misc.integrations.patch.IntegrationsPatch
|
import app.revanced.patches.youtube.misc.integrations.patch.IntegrationsPatch
|
||||||
import org.jf.dexlib2.Opcode
|
import org.jf.dexlib2.Opcode
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ import app.revanced.patcher.annotation.Package
|
|||||||
|
|
||||||
@Compatibility(
|
@Compatibility(
|
||||||
[Package(
|
[Package(
|
||||||
"com.google.android.youtube", arrayOf("17.14.35", "17.17.34", "17.23.35", "17.23.36", "17.24.34","17.24.35")
|
"com.google.android.youtube", arrayOf("17.14.35", "17.17.34", "17.23.35", "17.23.36", "17.24.34","17.24.35","17.25.34")
|
||||||
)]
|
)]
|
||||||
)
|
)
|
||||||
@Target(AnnotationTarget.CLASS)
|
@Target(AnnotationTarget.CLASS)
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ import app.revanced.patcher.annotation.Package
|
|||||||
|
|
||||||
@Compatibility(
|
@Compatibility(
|
||||||
[Package(
|
[Package(
|
||||||
"com.google.android.youtube", arrayOf("17.14.35", "17.17.34", "17.19.36", "17.20.37", "17.22.36", "17.23.35", "17.23.36", "17.24.34","17.24.35")
|
"com.google.android.youtube", arrayOf("17.14.35", "17.17.34", "17.19.36", "17.20.37", "17.22.36", "17.23.35", "17.23.36", "17.24.34","17.24.35","17.25.34")
|
||||||
)]
|
)]
|
||||||
)
|
)
|
||||||
@Target(AnnotationTarget.CLASS)
|
@Target(AnnotationTarget.CLASS)
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ import org.jf.dexlib2.iface.instruction.OneRegisterInstruction
|
|||||||
|
|
||||||
@Patch
|
@Patch
|
||||||
@Dependencies(dependencies = [IntegrationsPatch::class])
|
@Dependencies(dependencies = [IntegrationsPatch::class])
|
||||||
@Name("disable-shorts-button")
|
@Name("hide-shorts-button")
|
||||||
@Description("Hide the shorts button.")
|
@Description("Hide the shorts button.")
|
||||||
@ShortsButtonCompatibility
|
@ShortsButtonCompatibility
|
||||||
@Version("0.0.1")
|
@Version("0.0.1")
|
||||||
@@ -38,6 +38,7 @@ class ShortsButtonRemoverPatch : BytecodePatch(
|
|||||||
val moveViewInstruction = buttonsViewImplementation.instructions[buttonsViewResult.patternScanResult!!.endIndex]
|
val moveViewInstruction = buttonsViewImplementation.instructions[buttonsViewResult.patternScanResult!!.endIndex]
|
||||||
val viewRegister = (moveViewInstruction as OneRegisterInstruction).registerA
|
val viewRegister = (moveViewInstruction as OneRegisterInstruction).registerA
|
||||||
|
|
||||||
|
|
||||||
// Save the tab enum in XGlobals to avoid smali/register workarounds
|
// Save the tab enum in XGlobals to avoid smali/register workarounds
|
||||||
tabEnumResult.mutableMethod.addInstruction(
|
tabEnumResult.mutableMethod.addInstruction(
|
||||||
tabEnumResult.patternScanResult!!.endIndex + 1,
|
tabEnumResult.patternScanResult!!.endIndex + 1,
|
||||||
|
|||||||
@@ -0,0 +1,13 @@
|
|||||||
|
package app.revanced.patches.youtube.layout.watermark.annotations
|
||||||
|
|
||||||
|
import app.revanced.patcher.annotation.Compatibility
|
||||||
|
import app.revanced.patcher.annotation.Package
|
||||||
|
|
||||||
|
@Compatibility(
|
||||||
|
[Package(
|
||||||
|
"com.google.android.youtube", arrayOf("17.24.34", "17.24.35", "17.25.34")
|
||||||
|
)]
|
||||||
|
)
|
||||||
|
@Target(AnnotationTarget.CLASS)
|
||||||
|
@Retention(AnnotationRetention.RUNTIME)
|
||||||
|
internal annotation class HideWatermarkCompatibility
|
||||||
@@ -0,0 +1,21 @@
|
|||||||
|
package app.revanced.patches.youtube.layout.watermark.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.annotation.FuzzyPatternScanMethod
|
||||||
|
import app.revanced.patcher.fingerprint.method.annotation.MatchingMethod
|
||||||
|
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
|
||||||
|
import app.revanced.patches.youtube.layout.watermark.annotations.HideWatermarkCompatibility
|
||||||
|
import org.jf.dexlib2.AccessFlags
|
||||||
|
|
||||||
|
@Name("hide-watermark-signature")
|
||||||
|
@MatchingMethod(
|
||||||
|
"Ljvy;", "<init>"
|
||||||
|
)
|
||||||
|
@FuzzyPatternScanMethod(3)
|
||||||
|
@HideWatermarkCompatibility
|
||||||
|
@Version("0.0.1")
|
||||||
|
object HideWatermarkFingerprint : MethodFingerprint (
|
||||||
|
"V", AccessFlags.PUBLIC or AccessFlags.FINAL, listOf("L", "L"), null ,null, null
|
||||||
|
)
|
||||||
@@ -0,0 +1,21 @@
|
|||||||
|
package app.revanced.patches.youtube.layout.watermark.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.annotation.FuzzyPatternScanMethod
|
||||||
|
import app.revanced.patcher.fingerprint.method.annotation.MatchingMethod
|
||||||
|
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
|
||||||
|
import app.revanced.patches.youtube.layout.watermark.annotations.HideWatermarkCompatibility
|
||||||
|
import org.jf.dexlib2.AccessFlags
|
||||||
|
|
||||||
|
@Name("hide-watermark-parent-signature")
|
||||||
|
@MatchingMethod(
|
||||||
|
"Ljvy;", "<init>"
|
||||||
|
)
|
||||||
|
@FuzzyPatternScanMethod(3)
|
||||||
|
@HideWatermarkCompatibility
|
||||||
|
@Version("0.0.1")
|
||||||
|
object HideWatermarkParentFingerprint : MethodFingerprint (
|
||||||
|
"L", AccessFlags.PUBLIC or AccessFlags.FINAL, null, null, listOf("player_overlay_in_video_programming"), null
|
||||||
|
)
|
||||||
@@ -0,0 +1,50 @@
|
|||||||
|
package app.revanced.patches.youtube.layout.watermark.patch
|
||||||
|
|
||||||
|
import app.revanced.patcher.annotation.Description
|
||||||
|
import app.revanced.patcher.annotation.Name
|
||||||
|
import app.revanced.patcher.annotation.Version
|
||||||
|
import app.revanced.patcher.data.impl.BytecodeData
|
||||||
|
import app.revanced.patcher.extensions.addInstructions
|
||||||
|
import app.revanced.patcher.extensions.removeInstruction
|
||||||
|
import app.revanced.patcher.fingerprint.method.utils.MethodFingerprintUtils.resolve
|
||||||
|
import app.revanced.patcher.patch.PatchResult
|
||||||
|
import app.revanced.patcher.patch.PatchResultError
|
||||||
|
import app.revanced.patcher.patch.PatchResultSuccess
|
||||||
|
import app.revanced.patcher.patch.annotations.Dependencies
|
||||||
|
import app.revanced.patcher.patch.annotations.Patch
|
||||||
|
import app.revanced.patcher.patch.impl.BytecodePatch
|
||||||
|
import app.revanced.patches.youtube.layout.watermark.annotations.HideWatermarkCompatibility
|
||||||
|
import app.revanced.patches.youtube.layout.watermark.fingerprints.HideWatermarkParentFingerprint
|
||||||
|
import app.revanced.patches.youtube.layout.watermark.fingerprints.HideWatermarkFingerprint
|
||||||
|
import app.revanced.patches.youtube.misc.integrations.patch.IntegrationsPatch
|
||||||
|
|
||||||
|
@Patch
|
||||||
|
@Dependencies(dependencies = [IntegrationsPatch::class])
|
||||||
|
@Name("hide-watermark")
|
||||||
|
@Description("Hide the creator's watermark on video's.")
|
||||||
|
@HideWatermarkCompatibility
|
||||||
|
@Version("0.0.1")
|
||||||
|
class HideWatermarkPatch : BytecodePatch(
|
||||||
|
listOf(
|
||||||
|
HideWatermarkParentFingerprint
|
||||||
|
)
|
||||||
|
) {
|
||||||
|
override fun execute(data: BytecodeData): PatchResult {
|
||||||
|
HideWatermarkFingerprint.resolve(data, HideWatermarkParentFingerprint.result!!.classDef)
|
||||||
|
val result = HideWatermarkFingerprint.result
|
||||||
|
?: return PatchResultError("Required parent method could not be found.")
|
||||||
|
|
||||||
|
val method = result.mutableMethod
|
||||||
|
val line = method.implementation!!.instructions.size - 5
|
||||||
|
|
||||||
|
method.removeInstruction(line)
|
||||||
|
method.addInstructions(
|
||||||
|
line, """
|
||||||
|
invoke-static {}, Lapp/revanced/integrations/patches/BrandingWaterMarkPatch;->isBrandingWatermarkShown()Z
|
||||||
|
move-result p2
|
||||||
|
"""
|
||||||
|
)
|
||||||
|
|
||||||
|
return PatchResultSuccess()
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,13 @@
|
|||||||
|
package app.revanced.patches.youtube.misc.customplaybackspeed.annotations
|
||||||
|
|
||||||
|
import app.revanced.patcher.annotation.Compatibility
|
||||||
|
import app.revanced.patcher.annotation.Package
|
||||||
|
|
||||||
|
@Compatibility(
|
||||||
|
[Package(
|
||||||
|
"com.google.android.youtube", arrayOf("17.24.34","17.25.34")
|
||||||
|
)]
|
||||||
|
)
|
||||||
|
@Target(AnnotationTarget.CLASS)
|
||||||
|
@Retention(AnnotationRetention.RUNTIME)
|
||||||
|
internal annotation class CustomPlaybackSpeedCompatibility
|
||||||
@@ -0,0 +1,33 @@
|
|||||||
|
package app.revanced.patches.youtube.misc.customplaybackspeed.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.patcher.fingerprint.method.annotation.FuzzyPatternScanMethod
|
||||||
|
import app.revanced.patcher.fingerprint.method.annotation.MatchingMethod
|
||||||
|
import app.revanced.patches.youtube.misc.customplaybackspeed.annotations.CustomPlaybackSpeedCompatibility
|
||||||
|
import org.jf.dexlib2.AccessFlags
|
||||||
|
import org.jf.dexlib2.Opcode
|
||||||
|
|
||||||
|
@Name("speed-array-generator-fingerprint")
|
||||||
|
@MatchingMethod(
|
||||||
|
"Lzdj;", "d"
|
||||||
|
)
|
||||||
|
@FuzzyPatternScanMethod(2)
|
||||||
|
@CustomPlaybackSpeedCompatibility
|
||||||
|
@Version("0.0.1")
|
||||||
|
object SpeedArrayGeneratorFingerprint : MethodFingerprint(
|
||||||
|
"[L",
|
||||||
|
AccessFlags.PUBLIC or AccessFlags.STATIC,
|
||||||
|
null,
|
||||||
|
listOf(
|
||||||
|
Opcode.IF_NEZ,
|
||||||
|
Opcode.SGET_OBJECT,
|
||||||
|
Opcode.GOTO,
|
||||||
|
Opcode.INVOKE_INTERFACE,
|
||||||
|
Opcode.MOVE_RESULT_OBJECT,
|
||||||
|
Opcode.IGET_OBJECT,
|
||||||
|
),
|
||||||
|
listOf("0.0#")
|
||||||
|
)
|
||||||
@@ -0,0 +1,34 @@
|
|||||||
|
package app.revanced.patches.youtube.misc.customplaybackspeed.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.patcher.fingerprint.method.annotation.FuzzyPatternScanMethod
|
||||||
|
import app.revanced.patcher.fingerprint.method.annotation.MatchingMethod
|
||||||
|
import app.revanced.patches.youtube.misc.customplaybackspeed.annotations.CustomPlaybackSpeedCompatibility
|
||||||
|
import org.jf.dexlib2.AccessFlags
|
||||||
|
import org.jf.dexlib2.Opcode
|
||||||
|
|
||||||
|
@Name("speed-limiter-fingerprint")
|
||||||
|
@MatchingMethod(
|
||||||
|
"Lxgy;", "y"
|
||||||
|
)
|
||||||
|
@FuzzyPatternScanMethod(2)
|
||||||
|
@CustomPlaybackSpeedCompatibility
|
||||||
|
@Version("0.0.1")
|
||||||
|
object SpeedLimiterFingerprint : MethodFingerprint(
|
||||||
|
"V",
|
||||||
|
AccessFlags.PUBLIC or AccessFlags.FINAL,
|
||||||
|
listOf("F"),
|
||||||
|
listOf(
|
||||||
|
Opcode.INVOKE_STATIC,
|
||||||
|
Opcode.MOVE_RESULT,
|
||||||
|
Opcode.IF_EQZ,
|
||||||
|
Opcode.CONST_HIGH16,
|
||||||
|
Opcode.GOTO,
|
||||||
|
Opcode.CONST_HIGH16,
|
||||||
|
Opcode.CONST_HIGH16,
|
||||||
|
Opcode.INVOKE_STATIC,
|
||||||
|
),
|
||||||
|
)
|
||||||
@@ -0,0 +1,110 @@
|
|||||||
|
package app.revanced.patches.youtube.misc.customplaybackspeed.patch
|
||||||
|
|
||||||
|
import app.revanced.patcher.annotation.Description
|
||||||
|
import app.revanced.patcher.annotation.Name
|
||||||
|
import app.revanced.patcher.annotation.Version
|
||||||
|
import app.revanced.patcher.data.impl.BytecodeData
|
||||||
|
import app.revanced.patcher.extensions.addInstructions
|
||||||
|
import app.revanced.patcher.extensions.replaceInstruction
|
||||||
|
import app.revanced.patcher.patch.PatchResult
|
||||||
|
import app.revanced.patcher.patch.PatchResultError
|
||||||
|
import app.revanced.patcher.patch.PatchResultSuccess
|
||||||
|
import app.revanced.patcher.patch.annotations.Dependencies
|
||||||
|
import app.revanced.patcher.patch.annotations.Patch
|
||||||
|
import app.revanced.patcher.patch.impl.BytecodePatch
|
||||||
|
import app.revanced.patches.youtube.misc.customplaybackspeed.annotations.CustomPlaybackSpeedCompatibility
|
||||||
|
import app.revanced.patches.youtube.misc.customplaybackspeed.fingerprints.SpeedArrayGeneratorFingerprint
|
||||||
|
import app.revanced.patches.youtube.misc.customplaybackspeed.fingerprints.SpeedLimiterFingerprint
|
||||||
|
import app.revanced.patches.youtube.misc.integrations.patch.IntegrationsPatch
|
||||||
|
import org.jf.dexlib2.iface.instruction.NarrowLiteralInstruction
|
||||||
|
import org.jf.dexlib2.iface.instruction.OneRegisterInstruction
|
||||||
|
import org.jf.dexlib2.iface.instruction.ReferenceInstruction
|
||||||
|
import org.jf.dexlib2.iface.reference.FieldReference
|
||||||
|
import org.jf.dexlib2.iface.reference.MethodReference
|
||||||
|
|
||||||
|
@Patch
|
||||||
|
@Name("custom-playback-speed")
|
||||||
|
@Description("Allows to change the default playback speed options.")
|
||||||
|
@Dependencies(dependencies = [IntegrationsPatch::class])
|
||||||
|
@CustomPlaybackSpeedCompatibility
|
||||||
|
@Version("0.0.1")
|
||||||
|
class CustomPlaybackSpeedPatch : BytecodePatch(
|
||||||
|
listOf(
|
||||||
|
SpeedArrayGeneratorFingerprint, SpeedLimiterFingerprint
|
||||||
|
)
|
||||||
|
) {
|
||||||
|
|
||||||
|
override fun execute(data: BytecodeData): PatchResult {
|
||||||
|
val arrayGenMethod = SpeedArrayGeneratorFingerprint.result?.mutableMethod!!
|
||||||
|
val arrayGenMethodImpl = arrayGenMethod.implementation!!
|
||||||
|
|
||||||
|
val sizeCallIndex = arrayGenMethodImpl.instructions
|
||||||
|
.indexOfFirst { ((it as? ReferenceInstruction)?.reference as? MethodReference)?.name == "size" }
|
||||||
|
|
||||||
|
if (sizeCallIndex == -1) return PatchResultError("Couldn't find call to size()")
|
||||||
|
|
||||||
|
val sizeCallResultRegister =
|
||||||
|
(arrayGenMethodImpl.instructions.elementAt(sizeCallIndex + 1) as OneRegisterInstruction).registerA
|
||||||
|
|
||||||
|
arrayGenMethod.replaceInstruction(
|
||||||
|
sizeCallIndex + 1,
|
||||||
|
"const/4 v$sizeCallResultRegister, 0x0"
|
||||||
|
)
|
||||||
|
|
||||||
|
val (arrayLengthConstIndex, arrayLengthConst) = arrayGenMethodImpl.instructions.withIndex()
|
||||||
|
.first { (it.value as? NarrowLiteralInstruction)?.narrowLiteral == 7 }
|
||||||
|
|
||||||
|
val arrayLengthConstDestination = (arrayLengthConst as OneRegisterInstruction).registerA
|
||||||
|
|
||||||
|
val videoSpeedsArrayType = "Lapp/revanced/integrations/videoplayer/videosettings/VideoSpeed;->videoSpeeds:[F"
|
||||||
|
|
||||||
|
arrayGenMethod.addInstructions(
|
||||||
|
arrayLengthConstIndex + 1,
|
||||||
|
"""
|
||||||
|
sget-object v$arrayLengthConstDestination, $videoSpeedsArrayType
|
||||||
|
array-length v$arrayLengthConstDestination, v$arrayLengthConstDestination
|
||||||
|
"""
|
||||||
|
)
|
||||||
|
|
||||||
|
val (originalArrayFetchIndex, originalArrayFetch) = arrayGenMethodImpl.instructions.withIndex()
|
||||||
|
.first {
|
||||||
|
val reference = ((it.value as? ReferenceInstruction)?.reference as? FieldReference)
|
||||||
|
reference?.definingClass?.contains("PlayerConfigModel") ?: false &&
|
||||||
|
reference?.type == "[F"
|
||||||
|
}
|
||||||
|
|
||||||
|
val originalArrayFetchDestination = (originalArrayFetch as OneRegisterInstruction).registerA
|
||||||
|
|
||||||
|
arrayGenMethod.replaceInstruction(
|
||||||
|
originalArrayFetchIndex,
|
||||||
|
"sget-object v$originalArrayFetchDestination, $videoSpeedsArrayType"
|
||||||
|
)
|
||||||
|
|
||||||
|
val limiterMethod = SpeedLimiterFingerprint.result?.mutableMethod!!;
|
||||||
|
val limiterMethodImpl = limiterMethod.implementation!!
|
||||||
|
|
||||||
|
val speedLimitMin = 0.25f
|
||||||
|
val speedLimitMax = 100f
|
||||||
|
|
||||||
|
val (limiterMinConstIndex, limiterMinConst) = limiterMethodImpl.instructions.withIndex()
|
||||||
|
.first { (it.value as? NarrowLiteralInstruction)?.narrowLiteral == 0.25f.toRawBits() }
|
||||||
|
val (limiterMaxConstIndex, limiterMaxConst) = limiterMethodImpl.instructions.withIndex()
|
||||||
|
.first { (it.value as? NarrowLiteralInstruction)?.narrowLiteral == 2.0f.toRawBits() }
|
||||||
|
|
||||||
|
val limiterMinConstDestination = (limiterMinConst as OneRegisterInstruction).registerA
|
||||||
|
val limiterMaxConstDestination = (limiterMaxConst as OneRegisterInstruction).registerA
|
||||||
|
|
||||||
|
fun hexFloat(float: Float): String = "0x%08x".format(float.toRawBits())
|
||||||
|
|
||||||
|
limiterMethod.replaceInstruction(
|
||||||
|
limiterMinConstIndex,
|
||||||
|
"const/high16 v$limiterMinConstDestination, ${hexFloat(speedLimitMin)}"
|
||||||
|
)
|
||||||
|
limiterMethod.replaceInstruction(
|
||||||
|
limiterMaxConstIndex,
|
||||||
|
"const/high16 v$limiterMaxConstDestination, ${hexFloat(speedLimitMax)}"
|
||||||
|
)
|
||||||
|
|
||||||
|
return PatchResultSuccess()
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,13 @@
|
|||||||
|
package app.revanced.patches.youtube.misc.enabledebugging.annotations
|
||||||
|
|
||||||
|
import app.revanced.patcher.annotation.Compatibility
|
||||||
|
import app.revanced.patcher.annotation.Package
|
||||||
|
|
||||||
|
@Compatibility(
|
||||||
|
[Package(
|
||||||
|
"com.google.android.youtube", arrayOf()
|
||||||
|
)]
|
||||||
|
)
|
||||||
|
@Target(AnnotationTarget.CLASS)
|
||||||
|
@Retention(AnnotationRetention.RUNTIME)
|
||||||
|
internal annotation class EnableDebuggingCompatibility
|
||||||
@@ -0,0 +1,35 @@
|
|||||||
|
package app.revanced.patches.youtube.misc.enabledebugging.patch
|
||||||
|
|
||||||
|
import app.revanced.patcher.annotation.Description
|
||||||
|
import app.revanced.patcher.annotation.Name
|
||||||
|
import app.revanced.patcher.annotation.Version
|
||||||
|
import app.revanced.patcher.data.impl.ResourceData
|
||||||
|
import app.revanced.patcher.patch.PatchResult
|
||||||
|
import app.revanced.patcher.patch.PatchResultSuccess
|
||||||
|
import app.revanced.patcher.patch.annotations.Patch
|
||||||
|
import app.revanced.patcher.patch.impl.ResourcePatch
|
||||||
|
import app.revanced.patches.youtube.misc.enabledebugging.annotations.EnableDebuggingCompatibility
|
||||||
|
import org.w3c.dom.Element
|
||||||
|
|
||||||
|
@Patch(false)
|
||||||
|
@Name("enable-debugging")
|
||||||
|
@Description("Enable app debugging by patching the manifest file")
|
||||||
|
@EnableDebuggingCompatibility
|
||||||
|
@Version("0.0.1")
|
||||||
|
class EnableDebuggingPatch : ResourcePatch() {
|
||||||
|
override fun execute(data: ResourceData): PatchResult {
|
||||||
|
// create an xml editor instance
|
||||||
|
data.xmlEditor["AndroidManifest.xml"].use { dom ->
|
||||||
|
// get the application node
|
||||||
|
val applicationNode = dom
|
||||||
|
.file
|
||||||
|
.getElementsByTagName("application")
|
||||||
|
.item(0) as Element
|
||||||
|
|
||||||
|
// set application as debuggable
|
||||||
|
applicationNode.setAttribute("android:debuggable", "true")
|
||||||
|
}
|
||||||
|
|
||||||
|
return PatchResultSuccess()
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,13 @@
|
|||||||
|
package app.revanced.patches.youtube.misc.hdrbrightness.annotations
|
||||||
|
|
||||||
|
import app.revanced.patcher.annotation.Compatibility
|
||||||
|
import app.revanced.patcher.annotation.Package
|
||||||
|
|
||||||
|
@Compatibility(
|
||||||
|
[Package(
|
||||||
|
"com.google.android.youtube", arrayOf("17.24.34", "17.24.35", "17.25.34")
|
||||||
|
)]
|
||||||
|
)
|
||||||
|
@Target(AnnotationTarget.CLASS)
|
||||||
|
@Retention(AnnotationRetention.RUNTIME)
|
||||||
|
internal annotation class HDRBrightnessCompatibility
|
||||||
@@ -0,0 +1,35 @@
|
|||||||
|
package app.revanced.patches.youtube.misc.hdrbrightness.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.annotation.FuzzyPatternScanMethod
|
||||||
|
import app.revanced.patcher.fingerprint.method.annotation.MatchingMethod
|
||||||
|
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
|
||||||
|
import app.revanced.patches.youtube.misc.hdrbrightness.annotations.HDRBrightnessCompatibility
|
||||||
|
import org.jf.dexlib2.AccessFlags
|
||||||
|
import org.jf.dexlib2.Opcode
|
||||||
|
import org.jf.dexlib2.iface.instruction.NarrowLiteralInstruction
|
||||||
|
|
||||||
|
@Name("hdrbrightness-fingerprint")
|
||||||
|
@MatchingMethod(
|
||||||
|
"Lghz;", "mZ"
|
||||||
|
)
|
||||||
|
@FuzzyPatternScanMethod(3)
|
||||||
|
@HDRBrightnessCompatibility
|
||||||
|
@Version("0.0.1")
|
||||||
|
object HDRBrightnessFingerprint : MethodFingerprint(
|
||||||
|
"V", AccessFlags.PUBLIC or AccessFlags.FINAL, null,
|
||||||
|
listOf(
|
||||||
|
Opcode.MOVE_RESULT_OBJECT,
|
||||||
|
Opcode.INVOKE_VIRTUAL,
|
||||||
|
Opcode.MOVE_RESULT_OBJECT,
|
||||||
|
Opcode.CONST_HIGH16,
|
||||||
|
Opcode.IPUT,
|
||||||
|
Opcode.INVOKE_VIRTUAL
|
||||||
|
),
|
||||||
|
null,
|
||||||
|
customFingerprint = { methodDef ->
|
||||||
|
methodDef.implementation!!.instructions.count() == 16 && methodDef.implementation!!.instructions.any {((it as? NarrowLiteralInstruction)?.narrowLiteral == (-1.0f).toRawBits())}
|
||||||
|
}
|
||||||
|
)
|
||||||
@@ -0,0 +1,51 @@
|
|||||||
|
package app.revanced.patches.youtube.misc.hdrbrightness.patch;
|
||||||
|
|
||||||
|
import app.revanced.patcher.annotation.Description;
|
||||||
|
import app.revanced.patcher.annotation.Name;
|
||||||
|
import app.revanced.patcher.annotation.Version;
|
||||||
|
import app.revanced.patcher.data.impl.BytecodeData
|
||||||
|
import app.revanced.patcher.extensions.addInstructions
|
||||||
|
import app.revanced.patcher.extensions.removeInstruction
|
||||||
|
import app.revanced.patcher.patch.PatchResult
|
||||||
|
import app.revanced.patcher.patch.PatchResultError
|
||||||
|
import app.revanced.patcher.patch.PatchResultSuccess
|
||||||
|
import app.revanced.patcher.patch.annotations.Patch;
|
||||||
|
import app.revanced.patcher.patch.impl.BytecodePatch;
|
||||||
|
import app.revanced.patcher.util.smali.toBuilderInstruction
|
||||||
|
import app.revanced.patches.youtube.misc.hdrbrightness.annotations.HDRBrightnessCompatibility;
|
||||||
|
import app.revanced.patches.youtube.misc.hdrbrightness.fingerprints.HDRBrightnessFingerprint
|
||||||
|
import org.jf.dexlib2.Opcode
|
||||||
|
import org.jf.dexlib2.iface.instruction.NarrowLiteralInstruction
|
||||||
|
import org.jf.dexlib2.iface.instruction.OneRegisterInstruction
|
||||||
|
|
||||||
|
@Patch
|
||||||
|
@Name("hdr-max-brightness")
|
||||||
|
@Description("Set brightness to max for HDR videos in fullscreen mode.")
|
||||||
|
@HDRBrightnessCompatibility
|
||||||
|
@Version("0.0.1")
|
||||||
|
class HDRBrightnessPatch : BytecodePatch(
|
||||||
|
listOf(
|
||||||
|
HDRBrightnessFingerprint
|
||||||
|
)
|
||||||
|
) {
|
||||||
|
override fun execute(data: BytecodeData): PatchResult {
|
||||||
|
val result = HDRBrightnessFingerprint.result
|
||||||
|
?: return PatchResultError("HDRBrightnessFingerprint could not resolve the method!")
|
||||||
|
|
||||||
|
|
||||||
|
val method = result.mutableMethod
|
||||||
|
|
||||||
|
//Get the index here so we know where to inject our code to override -1.0f
|
||||||
|
val index = method.implementation!!.instructions.indexOfFirst { ((it as? NarrowLiteralInstruction)?.narrowLiteral == (-1.0f).toRawBits()) }
|
||||||
|
val register = (method.implementation!!.instructions.get(index) as OneRegisterInstruction).registerA
|
||||||
|
|
||||||
|
method.addInstructions(
|
||||||
|
index + 1, """
|
||||||
|
invoke-static {v$register}, Lapp/revanced/integrations/patches/HDRMaxBrightnessPatch;->getHDRBrightness(F)F
|
||||||
|
move-result v$register
|
||||||
|
"""
|
||||||
|
)
|
||||||
|
|
||||||
|
return PatchResultSuccess()
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -5,7 +5,7 @@ import app.revanced.patcher.annotation.Package
|
|||||||
|
|
||||||
@Compatibility(
|
@Compatibility(
|
||||||
[Package(
|
[Package(
|
||||||
"com.google.android.youtube", arrayOf("17.03.38", "17.14.35", "17.17.34", "17.19.36", "17.20.37", "17.22.36", "17.23.35", "17.23.36", "17.24.34","17.24.35")
|
"com.google.android.youtube", arrayOf("17.03.38", "17.14.35", "17.17.34", "17.19.36", "17.20.37", "17.22.36", "17.23.35", "17.23.36", "17.24.34","17.24.35","17.25.34")
|
||||||
)]
|
)]
|
||||||
)
|
)
|
||||||
@Target(AnnotationTarget.CLASS)
|
@Target(AnnotationTarget.CLASS)
|
||||||
|
|||||||
@@ -28,7 +28,7 @@ class IntegrationsPatch : BytecodePatch(
|
|||||||
)
|
)
|
||||||
) {
|
) {
|
||||||
override fun execute(data: BytecodeData): PatchResult {
|
override fun execute(data: BytecodeData): PatchResult {
|
||||||
if (data.findClass("Lapp/revanced/integrations/utils/Globals") == null)
|
if (data.findClass("Lapp/revanced/integrations/utils/ReVancedUtils") == null)
|
||||||
return PatchResultError("Integrations have not been merged yet. This patch can not succeed without the integrations.")
|
return PatchResultError("Integrations have not been merged yet. This patch can not succeed without the integrations.")
|
||||||
|
|
||||||
val result = InitFingerprint.result!!
|
val result = InitFingerprint.result!!
|
||||||
@@ -40,7 +40,7 @@ class IntegrationsPatch : BytecodePatch(
|
|||||||
method.addInstructions(
|
method.addInstructions(
|
||||||
0, """
|
0, """
|
||||||
invoke-static {v$count}, Lapp/revanced/integrations/sponsorblock/StringRef;->setContext(Landroid/content/Context;)V
|
invoke-static {v$count}, Lapp/revanced/integrations/sponsorblock/StringRef;->setContext(Landroid/content/Context;)V
|
||||||
sput-object v$count, Lapp/revanced/integrations/utils/Globals;->context:Landroid/content/Context;
|
sput-object v$count, Lapp/revanced/integrations/utils/ReVancedUtils;->context:Landroid/content/Context;
|
||||||
"""
|
"""
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -56,10 +56,10 @@ class IntegrationsPatch : BytecodePatch(
|
|||||||
null,
|
null,
|
||||||
ImmutableMethodImplementation(
|
ImmutableMethodImplementation(
|
||||||
1, """
|
1, """
|
||||||
invoke-static { }, Lapp/revanced/integrations/utils/Globals;->getAppContext()Landroid/content/Context;
|
invoke-static { }, Lapp/revanced/integrations/utils/ReVancedUtils;->getAppContext()Landroid/content/Context;
|
||||||
move-result-object v0
|
move-result-object v0
|
||||||
return-object v0
|
return-object v0
|
||||||
""".trimIndent().toInstructions(), null, null
|
""".toInstructions(), null, null
|
||||||
)
|
)
|
||||||
).toMutable()
|
).toMutable()
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ import app.revanced.patcher.annotation.Package
|
|||||||
|
|
||||||
@Compatibility(
|
@Compatibility(
|
||||||
[Package(
|
[Package(
|
||||||
"com.google.android.youtube", arrayOf("17.14.35", "17.17.34", "17.19.36", "17.20.37", "17.22.36", "17.23.35", "17.23.36", "17.24.34","17.24.35")
|
"com.google.android.youtube", arrayOf("17.14.35", "17.17.34", "17.19.36", "17.20.37", "17.22.36", "17.23.35", "17.23.36", "17.24.34","17.24.35","17.25.34")
|
||||||
)]
|
)]
|
||||||
)
|
)
|
||||||
@Target(AnnotationTarget.CLASS)
|
@Target(AnnotationTarget.CLASS)
|
||||||
|
|||||||
@@ -4,9 +4,9 @@ import app.revanced.patcher.annotation.Description
|
|||||||
import app.revanced.patcher.annotation.Name
|
import app.revanced.patcher.annotation.Name
|
||||||
import app.revanced.patcher.annotation.Version
|
import app.revanced.patcher.annotation.Version
|
||||||
import app.revanced.patcher.data.impl.ResourceData
|
import app.revanced.patcher.data.impl.ResourceData
|
||||||
import app.revanced.patcher.patch.impl.ResourcePatch
|
|
||||||
import app.revanced.patcher.patch.PatchResult
|
import app.revanced.patcher.patch.PatchResult
|
||||||
import app.revanced.patcher.patch.PatchResultSuccess
|
import app.revanced.patcher.patch.PatchResultSuccess
|
||||||
|
import app.revanced.patcher.patch.impl.ResourcePatch
|
||||||
import app.revanced.patches.youtube.misc.manifest.annotations.FixLocaleConfigErrorCompatibility
|
import app.revanced.patches.youtube.misc.manifest.annotations.FixLocaleConfigErrorCompatibility
|
||||||
import org.w3c.dom.Element
|
import org.w3c.dom.Element
|
||||||
|
|
||||||
@@ -17,7 +17,7 @@ import org.w3c.dom.Element
|
|||||||
class FixLocaleConfigErrorPatch : ResourcePatch() {
|
class FixLocaleConfigErrorPatch : ResourcePatch() {
|
||||||
override fun execute(data: ResourceData): PatchResult {
|
override fun execute(data: ResourceData): PatchResult {
|
||||||
// create an xml editor instance
|
// create an xml editor instance
|
||||||
data.getXmlEditor("AndroidManifest.xml").use {
|
data.xmlEditor["AndroidManifest.xml"].use {
|
||||||
// edit the application nodes attribute...
|
// edit the application nodes attribute...
|
||||||
val applicationNode = it
|
val applicationNode = it
|
||||||
.file
|
.file
|
||||||
|
|||||||
@@ -15,22 +15,26 @@ import org.w3c.dom.Element
|
|||||||
@Version("0.0.1")
|
@Version("0.0.1")
|
||||||
class ResourceIdMappingProviderResourcePatch : ResourcePatch() {
|
class ResourceIdMappingProviderResourcePatch : ResourcePatch() {
|
||||||
companion object {
|
companion object {
|
||||||
internal lateinit var resourceMappings: Map<String, Long>
|
internal lateinit var resourceMappings: List<ResourceElement>
|
||||||
private set
|
private set
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun execute(data: ResourceData): PatchResult {
|
override fun execute(data: ResourceData): PatchResult {
|
||||||
data.xmlEditor["res/values/public.xml"].use { editor ->
|
data.xmlEditor["res/values/public.xml"].use { editor ->
|
||||||
resourceMappings = buildMap {
|
resourceMappings = buildList {
|
||||||
editor.file.documentElement.doRecursively { node ->
|
editor.file.documentElement.doRecursively { node ->
|
||||||
if (node !is Element) return@doRecursively
|
if (node !is Element) return@doRecursively
|
||||||
val nameAttribute = node.getAttribute("name")
|
val nameAttribute = node.getAttribute("name")
|
||||||
|
val typeAttribute = node.getAttribute("type")
|
||||||
if (node.nodeName != "public" || nameAttribute.startsWith("APKTOOL")) return@doRecursively
|
if (node.nodeName != "public" || nameAttribute.startsWith("APKTOOL")) return@doRecursively
|
||||||
this[nameAttribute] = node.getAttribute("id").substring(2).toLong(16)
|
val id = node.getAttribute("id").substring(2).toLong(16)
|
||||||
|
add(ResourceElement(typeAttribute, nameAttribute, id))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return PatchResultSuccess()
|
return PatchResultSuccess()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
data class ResourceElement(val type: String, val name: String, val id: Long)
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ import app.revanced.patcher.annotation.Package
|
|||||||
|
|
||||||
@Compatibility(
|
@Compatibility(
|
||||||
[Package(
|
[Package(
|
||||||
"com.google.android.youtube", arrayOf("17.14.35", "17.19.36", "17.20.37", "17.22.36", "17.23.35", "17.23.36", "17.24.34","17.24.35")
|
"com.google.android.youtube", arrayOf("17.14.35", "17.19.36", "17.20.37", "17.22.36", "17.23.35", "17.23.36", "17.24.34","17.24.35","17.25.34")
|
||||||
)]
|
)]
|
||||||
)
|
)
|
||||||
@Target(AnnotationTarget.CLASS)
|
@Target(AnnotationTarget.CLASS)
|
||||||
|
|||||||
Reference in New Issue
Block a user