Compare commits

...

9 Commits

Author SHA1 Message Date
semantic-release-bot
25e86c5545 chore(release): 2.87.0 [skip ci]
# [2.87.0](https://github.com/revanced/revanced-patches/compare/v2.86.0...v2.87.0) (2022-10-25)

### Bug Fixes

* **metanav/fix-scaling:** use semantic versioning in package versions ([d45279f](f1bf2c589b))
* **youtube/theme:** theme litho ui components & use correct theme for settings ([#791](https://github.com/revanced/revanced-patches/issues/791)) ([03b565c](8cf0343f29))

### Features

* `fix-metanav-scaling` patch ([#831](https://github.com/revanced/revanced-patches/issues/831)) ([2ddc846](3761dbd7b2))
* `hide-crowdfunding-box` patch ([#856](https://github.com/revanced/revanced-patches/issues/856)) ([823beeb](8b54559953))
2022-10-25 18:15:10 +00:00
oSumAtrIX
f1bf2c589b fix(metanav/fix-scaling): use semantic versioning in package versions 2022-10-25 20:12:49 +02:00
OxrxL
8b54559953 feat: hide-crowdfunding-box patch (#856)
Co-authored-by: oSumAtrIX <johan.melkonyan1@web.de>
2022-10-25 18:20:05 +02:00
Caroline Joy Bell
3761dbd7b2 feat: fix-metanav-scaling patch (#831) 2022-10-25 08:39:28 +02:00
OxrxL
8cf0343f29 fix(youtube/theme): theme litho ui components & use correct theme for settings (#791) 2022-10-25 08:36:59 +02:00
semantic-release-bot
f3753a22da chore(release): 2.86.0 [skip ci]
# [2.86.0](https://github.com/revanced/revanced-patches/compare/v2.85.2...v2.86.0) (2022-10-25)

### Features

* **youtube/theme:** extend theming to splash screen ([#769](https://github.com/revanced/revanced-patches/issues/769)) ([297db08](c90312a925))
2022-10-25 06:32:58 +00:00
OxrxL
c90312a925 feat(youtube/theme): extend theming to splash screen (#769) 2022-10-25 08:30:42 +02:00
semantic-release-bot
c1d6aa3e49 chore(release): 2.85.2 [skip ci]
## [2.85.2](https://github.com/revanced/revanced-patches/compare/v2.85.1...v2.85.2) (2022-10-22)

### Bug Fixes

* **youtube/integrations:** set context for remaining activities ([#828](https://github.com/revanced/revanced-patches/issues/828)) ([ba515d2](c097370960))
2022-10-22 10:46:54 +00:00
Canny
c097370960 fix(youtube/integrations): set context for remaining activities (#828) 2022-10-22 12:45:10 +02:00
21 changed files with 403 additions and 129 deletions

View File

@@ -1,3 +1,31 @@
# [2.87.0](https://github.com/revanced/revanced-patches/compare/v2.86.0...v2.87.0) (2022-10-25)
### Bug Fixes
* **metanav/fix-scaling:** use semantic versioning in package versions ([a9445a8](https://github.com/revanced/revanced-patches/commit/a9445a823e3a4885764cea9d08b51a1584d3238f))
* **youtube/theme:** theme litho ui components & use correct theme for settings ([#791](https://github.com/revanced/revanced-patches/issues/791)) ([91c03c5](https://github.com/revanced/revanced-patches/commit/91c03c5624ca28ac13ee761261dea423f0ac42d7))
### Features
* `fix-metanav-scaling` patch ([#831](https://github.com/revanced/revanced-patches/issues/831)) ([4808e09](https://github.com/revanced/revanced-patches/commit/4808e099856e50a6f7e66834a92e2210cc84c8bc))
* `hide-crowdfunding-box` patch ([#856](https://github.com/revanced/revanced-patches/issues/856)) ([3704ce2](https://github.com/revanced/revanced-patches/commit/3704ce22dbbff02b2e2d6dbdf9a74254a2511d3c))
# [2.86.0](https://github.com/revanced/revanced-patches/compare/v2.85.2...v2.86.0) (2022-10-25)
### Features
* **youtube/theme:** extend theming to splash screen ([#769](https://github.com/revanced/revanced-patches/issues/769)) ([f7bb937](https://github.com/revanced/revanced-patches/commit/f7bb937ef2374d1042ea3772f03627d7f0111b78))
## [2.85.2](https://github.com/revanced/revanced-patches/compare/v2.85.1...v2.85.2) (2022-10-22)
### Bug Fixes
* **youtube/integrations:** set context for remaining activities ([#828](https://github.com/revanced/revanced-patches/issues/828)) ([b2b6a3d](https://github.com/revanced/revanced-patches/commit/b2b6a3d1492bc2d5a6e27c68c74e3904764dda4b))
## [2.85.1](https://github.com/revanced/revanced-patches/compare/v2.85.0...v2.85.1) (2022-10-21) ## [2.85.1](https://github.com/revanced/revanced-patches/compare/v2.85.0...v2.85.1) (2022-10-21)

View File

@@ -4,6 +4,14 @@ The official Patch bundle provided by ReVanced and the community.
> Looking for the JSON variant of this? [Click here](patches.json). > Looking for the JSON variant of this? [Click here](patches.json).
### 📦 `com.metanav`
<details>
| 💊 Patch | 📜 Description | 🏹 Target Version |
|:--------:|:--------------:|:-----------------:|
| `fix-scaling` | Scales the content properly. | 0.1.0 |
</details>
### 📦 `com.ss.android.ugc.trill` ### 📦 `com.ss.android.ugc.trill`
<details> <details>
@@ -65,6 +73,7 @@ The official Patch bundle provided by ReVanced and the community.
| 💊 Patch | 📜 Description | 🏹 Target Version | | 💊 Patch | 📜 Description | 🏹 Target Version |
|:--------:|:--------------:|:-----------------:| |:--------:|:--------------:|:-----------------:|
| `hide-crowdfunding-box` | Hides the crowdfunding box between the player and video description. | 17.36.37 |
| `hide-time-and-seekbar` | Hides progress bar and time counter on videos. | 17.36.37 | | `hide-time-and-seekbar` | Hides progress bar and time counter on videos. | 17.36.37 |
| `hide-video-buttons` | Adds options to hide action buttons under a video. | 17.36.37 | | `hide-video-buttons` | Adds options to hide action buttons under a video. | 17.36.37 |
| `enable-wide-searchbar` | Replaces the search icon with a wide search bar. This will hide the YouTube logo when active. | 17.36.37 | | `enable-wide-searchbar` | Replaces the search icon with a wide search bar. This will hide the YouTube logo when active. | 17.36.37 |

View File

@@ -1,2 +1,2 @@
kotlin.code.style = official kotlin.code.style = official
version = 2.85.1 version = 2.87.0

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,9 @@
package app.revanced.patches.metanav.scaling.annotations
import app.revanced.patcher.annotation.Compatibility
import app.revanced.patcher.annotation.Package
@Compatibility([Package("com.metanav", arrayOf("0.1.0"))])
@Target(AnnotationTarget.CLASS)
@Retention(AnnotationRetention.RUNTIME)
internal annotation class FixScalingCompatibility

View File

@@ -0,0 +1,32 @@
package app.revanced.patches.metanav.scaling.patch
import app.revanced.patcher.annotation.Description
import app.revanced.patcher.annotation.Name
import app.revanced.patcher.annotation.Version
import app.revanced.patcher.data.ResourceContext
import app.revanced.patcher.patch.PatchResult
import app.revanced.patcher.patch.PatchResultSuccess
import app.revanced.patcher.patch.ResourcePatch
import app.revanced.patcher.patch.annotations.Patch
import app.revanced.patches.metanav.scaling.annotations.FixScalingCompatibility
import org.w3c.dom.Element
@Patch
@Name("fix-scaling")
@Description("Scales the content properly.")
@FixScalingCompatibility
@Version("0.0.1")
class FixScalingPatch : ResourcePatch {
override fun execute(context: ResourceContext): PatchResult {
context.xmlEditor["assets/startScreenCanvas.html"].use { editor ->
val svgNode = editor
.file
.getElementsByTagName("svg")
.item(0) as Element
svgNode.setAttribute("height", "750")
}
return PatchResultSuccess()
}
}

View File

@@ -0,0 +1,13 @@
package app.revanced.patches.youtube.layout.hidecrowdfundingbox.annotations
import app.revanced.patcher.annotation.Compatibility
import app.revanced.patcher.annotation.Package
@Compatibility(
[Package(
"com.google.android.youtube", arrayOf("17.33.42", "17.34.35", "17.34.36", "17.36.37")
)]
)
@Target(AnnotationTarget.CLASS)
@Retention(AnnotationRetention.RUNTIME)
internal annotation class CrowdfundingBoxCompatibility

View File

@@ -0,0 +1,37 @@
package app.revanced.patches.youtube.layout.hidecrowdfundingbox.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.impl.MethodFingerprint
import app.revanced.patches.youtube.layout.hidecrowdfundingbox.annotations.CrowdfundingBoxCompatibility
import org.jf.dexlib2.AccessFlags
import org.jf.dexlib2.Opcode
@Name("crowdfunding-box-view-fingerprint")
@FuzzyPatternScanMethod(3)
@CrowdfundingBoxCompatibility
@Version("0.0.1")
object CrowdfundingBoxFingerprint : MethodFingerprint(
"V",
AccessFlags.PUBLIC or AccessFlags.CONSTRUCTOR,
listOf("L", "L", "L", "L", "L", "L", "L", "[B", "[B"),
listOf(
Opcode.MOVE_OBJECT,
Opcode.MOVE_OBJECT_FROM16,
Opcode.INVOKE_DIRECT,
Opcode.MOVE_OBJECT_FROM16,
Opcode.IPUT_OBJECT,
Opcode.MOVE_OBJECT_FROM16,
Opcode.IPUT_OBJECT,
Opcode.IPUT_OBJECT,
Opcode.INVOKE_STATIC,
Opcode.MOVE_RESULT_OBJECT,
Opcode.CONST_4,
Opcode.CONST_4,
Opcode.CONST,
Opcode.INVOKE_VIRTUAL,
Opcode.MOVE_RESULT_OBJECT,
)
)

View File

@@ -0,0 +1,59 @@
package app.revanced.patches.youtube.layout.hidecrowdfundingbox.patch
import app.revanced.patcher.annotation.Description
import app.revanced.patcher.annotation.Name
import app.revanced.patcher.annotation.Version
import app.revanced.patcher.data.BytecodeContext
import app.revanced.patcher.extensions.addInstruction
import app.revanced.patcher.extensions.instruction
import app.revanced.patcher.patch.BytecodePatch
import app.revanced.patcher.patch.PatchResult
import app.revanced.patcher.patch.PatchResultSuccess
import app.revanced.patcher.patch.annotations.DependsOn
import app.revanced.patcher.patch.annotations.Patch
import app.revanced.patches.youtube.layout.hidecrowdfundingbox.annotations.CrowdfundingBoxCompatibility
import app.revanced.patches.youtube.layout.hidecrowdfundingbox.fingerprints.CrowdfundingBoxFingerprint
import app.revanced.patches.youtube.misc.integrations.patch.IntegrationsPatch
import app.revanced.patches.youtube.misc.mapping.patch.ResourceMappingResourcePatch
import app.revanced.patches.youtube.misc.settings.bytecode.patch.SettingsPatch
import app.revanced.patches.youtube.misc.settings.framework.components.impl.StringResource
import app.revanced.patches.youtube.misc.settings.framework.components.impl.SwitchPreference
import org.jf.dexlib2.iface.instruction.OneRegisterInstruction
@Patch
@DependsOn([IntegrationsPatch::class, SettingsPatch::class, ResourceMappingResourcePatch::class])
@Name("hide-crowdfunding-box")
@Description("Hides the crowdfunding box between the player and video description.")
@CrowdfundingBoxCompatibility
@Version("0.0.1")
class CrowdfundingBoxPatch : BytecodePatch(
listOf(
CrowdfundingBoxFingerprint
)
) {
override fun execute(context: BytecodeContext): PatchResult {
SettingsPatch.PreferenceScreen.LAYOUT.addPreferences(
SwitchPreference(
"revanced_hide_crowdfunding_box",
StringResource("revanced_hide_crowdfunding_box_title", "Hide the crowdfunding box"),
false,
StringResource("revanced_hide_crowdfunding_box_summary_on", "Crowdfunding box is hidden"),
StringResource("revanced_hide_crowdfunding_box_summary_off", "Crowdfunding box is visible")
)
)
val crowdfundingBoxResult = CrowdfundingBoxFingerprint.result!!
val crowdfundingBoxMethod = crowdfundingBoxResult.mutableMethod
val moveResultObjectIndex = crowdfundingBoxResult.scanResult.patternScanResult!!.endIndex
val patchIndex = moveResultObjectIndex + 1
crowdfundingBoxMethod.addInstruction(
patchIndex, """
invoke-static {v${(crowdfundingBoxMethod.instruction(moveResultObjectIndex) as OneRegisterInstruction).registerA}}, Lapp/revanced/integrations/patches/HideCrowdfundingBoxPatch;->hideCrowdfundingBox(Landroid/view/View;)V
"""
)
return PatchResultSuccess()
}
}

View File

@@ -8,10 +8,10 @@ import app.revanced.patches.youtube.layout.theme.annotations.ThemeCompatibility
import org.jf.dexlib2.AccessFlags import org.jf.dexlib2.AccessFlags
import org.jf.dexlib2.Opcode import org.jf.dexlib2.Opcode
@Name("comment-actionbar-fingerprint") @Name("litho-ui-fingerprint")
@ThemeCompatibility @ThemeCompatibility
@Version("0.0.1") @Version("0.0.1")
object CommentsFilterBarFingerprint : MethodFingerprint( object LithoThemeFingerprint : MethodFingerprint(
"V", AccessFlags.PROTECTED or AccessFlags.FINAL, listOf("L"), listOf( "V", AccessFlags.PROTECTED or AccessFlags.FINAL, listOf("L"), listOf(
Opcode.APUT, Opcode.APUT,
Opcode.NEW_INSTANCE, Opcode.NEW_INSTANCE,

View File

@@ -11,36 +11,27 @@ import app.revanced.patcher.patch.PatchResult
import app.revanced.patcher.patch.PatchResultSuccess import app.revanced.patcher.patch.PatchResultSuccess
import app.revanced.patcher.util.smali.ExternalLabel import app.revanced.patcher.util.smali.ExternalLabel
import app.revanced.patches.youtube.layout.theme.annotations.ThemeCompatibility import app.revanced.patches.youtube.layout.theme.annotations.ThemeCompatibility
import app.revanced.patches.youtube.layout.theme.fingerprints.CommentsFilterBarFingerprint import app.revanced.patches.youtube.layout.theme.fingerprints.LithoThemeFingerprint
@Name("comment-filter-bar-theme") @Name("litho-components-theme")
@Description("Applies custom theming to comments filter action bar.") @Description("Applies a custom theme to litho components.")
@ThemeCompatibility @ThemeCompatibility
@Version("0.0.1") @Version("0.0.1")
class CommentsFilterBarPatch : BytecodePatch( class LithoThemePatch : BytecodePatch(
listOf( listOf(
CommentsFilterBarFingerprint LithoThemeFingerprint
) )
) { ) {
override fun execute(context: BytecodeContext): PatchResult { override fun execute(context: BytecodeContext): PatchResult {
val result = CommentsFilterBarFingerprint.result!! val result = LithoThemeFingerprint.result!!
val method = result.mutableMethod val method = result.mutableMethod
val patchIndex = result.scanResult.patternScanResult!!.endIndex - 1 val patchIndex = result.scanResult.patternScanResult!!.endIndex - 1
method.addInstructions( method.addInstructions(
patchIndex, """ patchIndex, """
invoke-static {}, Lapp/revanced/integrations/utils/ThemeHelper;->isDarkTheme()Z invoke-static {p1}, Lapp/revanced/integrations/patches/LithoThemePatch;->applyLithoTheme(I)I
move-result v2 move-result p1
if-nez v2, :comments_filter_white """
const v1, -0x1
if-ne v1, p1, :comments_filter_white
const/4 p1, 0x0
:comments_filter_white
if-eqz v2, :comments_filter_dark
const v1, -0xdededf
if-ne v1, p1, :comments_filter_dark
const/4 p1, 0x0
""", listOf(ExternalLabel("comments_filter_dark", method.instruction(patchIndex)))
) )
return PatchResultSuccess() return PatchResultSuccess()
} }

View File

@@ -9,10 +9,12 @@ import app.revanced.patcher.patch.annotations.DependsOn
import app.revanced.patcher.patch.annotations.Patch import app.revanced.patcher.patch.annotations.Patch
import app.revanced.patches.youtube.layout.theme.annotations.ThemeCompatibility import app.revanced.patches.youtube.layout.theme.annotations.ThemeCompatibility
import app.revanced.patches.youtube.misc.manifest.patch.FixLocaleConfigErrorPatch import app.revanced.patches.youtube.misc.manifest.patch.FixLocaleConfigErrorPatch
import app.revanced.util.resources.ResourceUtils
import app.revanced.util.resources.ResourceUtils.copyResources
import org.w3c.dom.Element import org.w3c.dom.Element
@Patch @Patch
@DependsOn([CommentsFilterBarPatch::class, FixLocaleConfigErrorPatch::class]) @DependsOn([LithoThemePatch::class, FixLocaleConfigErrorPatch::class])
@Name("theme") @Name("theme")
@Description("Applies a custom theme.") @Description("Applies a custom theme.")
@ThemeCompatibility @ThemeCompatibility
@@ -31,16 +33,22 @@ class ThemePatch : ResourcePatch {
node.textContent = when (node.getAttribute("name")) { node.textContent = when (node.getAttribute("name")) {
"yt_black1", "yt_black1_opacity95", "yt_black1_opacity98", "yt_black2", "yt_black3", "yt_black4", "yt_black1", "yt_black1_opacity95", "yt_black1_opacity98", "yt_black2", "yt_black3", "yt_black4",
"yt_status_bar_background_dark", "material_grey_100", "material_grey_50", "material_grey_600", "yt_status_bar_background_dark", "material_grey_100", "material_grey_50", "material_grey_600",
"material_grey_800", "material_grey_850", "material_grey_900", "material_grey_white_1000" -> darkThemeBackgroundColor "material_grey_800", "material_grey_850", "material_grey_900", "material_grey_white_1000",
"sud_glif_v3_dialog_background_color_dark" -> darkThemeBackgroundColor
"yt_white1", "yt_white1_opacity95", "yt_white1_opacity98", "yt_white2", "yt_white3", "yt_white1", "yt_white1_opacity95", "yt_white1_opacity98", "yt_white2", "yt_white3",
"yt_white4" -> lightThemeBackgroundColor "yt_white4", "sud_glif_v3_dialog_background_color_light" -> lightThemeBackgroundColor
else -> continue else -> continue
} }
} }
} }
// copies the resource file to change the splash screen color
context.copyResources("theme",
ResourceUtils.ResourceGroup("values-night-v31", "styles.xml")
)
return PatchResultSuccess() return PatchResultSuccess()
} }

View File

@@ -0,0 +1,13 @@
package app.revanced.patches.youtube.misc.integrations.fingerprints
import app.revanced.patcher.annotation.Name
import app.revanced.patcher.annotation.Version
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
import app.revanced.patches.youtube.misc.integrations.annotations.IntegrationsCompatibility
@Name("service-fingerprint")
@IntegrationsCompatibility
@Version("0.0.1")
object ServiceFingerprint : MethodFingerprint(
customFingerprint = { methodDef -> methodDef.definingClass.endsWith("ApiPlayerService;") && methodDef.name == "<init>" }
)

View File

@@ -0,0 +1,16 @@
package app.revanced.patches.youtube.misc.integrations.fingerprints
import app.revanced.patcher.annotation.Name
import app.revanced.patcher.annotation.Version
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
import app.revanced.patches.youtube.misc.integrations.annotations.IntegrationsCompatibility
@Name("standalone-player-fingerprint")
@IntegrationsCompatibility
@Version("0.0.1")
object StandalonePlayerFingerprint : MethodFingerprint(
strings = listOf(
"Invalid PlaybackStartDescriptor. Returning the instance itself.",
"com.google.android.music",
)
)

View File

@@ -4,6 +4,7 @@ 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.BytecodeContext import app.revanced.patcher.data.BytecodeContext
import app.revanced.patcher.extensions.MethodFingerprintExtensions.name
import app.revanced.patcher.extensions.addInstruction import app.revanced.patcher.extensions.addInstruction
import app.revanced.patcher.extensions.or import app.revanced.patcher.extensions.or
import app.revanced.patcher.patch.BytecodePatch import app.revanced.patcher.patch.BytecodePatch
@@ -14,6 +15,8 @@ import app.revanced.patcher.util.proxy.mutableTypes.MutableMethod.Companion.toMu
import app.revanced.patcher.util.smali.toInstructions import app.revanced.patcher.util.smali.toInstructions
import app.revanced.patches.youtube.misc.integrations.annotations.IntegrationsCompatibility import app.revanced.patches.youtube.misc.integrations.annotations.IntegrationsCompatibility
import app.revanced.patches.youtube.misc.integrations.fingerprints.InitFingerprint import app.revanced.patches.youtube.misc.integrations.fingerprints.InitFingerprint
import app.revanced.patches.youtube.misc.integrations.fingerprints.ServiceFingerprint
import app.revanced.patches.youtube.misc.integrations.fingerprints.StandalonePlayerFingerprint
import org.jf.dexlib2.AccessFlags import org.jf.dexlib2.AccessFlags
import org.jf.dexlib2.immutable.ImmutableMethod import org.jf.dexlib2.immutable.ImmutableMethod
import org.jf.dexlib2.immutable.ImmutableMethodImplementation import org.jf.dexlib2.immutable.ImmutableMethodImplementation
@@ -24,42 +27,33 @@ import org.jf.dexlib2.immutable.ImmutableMethodImplementation
@Version("0.0.1") @Version("0.0.1")
class IntegrationsPatch : BytecodePatch( class IntegrationsPatch : BytecodePatch(
listOf( listOf(
InitFingerprint InitFingerprint, StandalonePlayerFingerprint, ServiceFingerprint
) )
) { ) {
companion object {
private const val INTEGRATIONS_DESCRIPTOR = "Lapp/revanced/integrations/utils/ReVancedUtils;"
}
override fun execute(context: BytecodeContext): PatchResult { override fun execute(context: BytecodeContext): PatchResult {
if (context.findClass("Lapp/revanced/integrations/utils/ReVancedUtils") == null) if (context.findClass(INTEGRATIONS_DESCRIPTOR) == 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 merging the integrations.")
val result = InitFingerprint.result!! arrayOf(InitFingerprint, StandalonePlayerFingerprint, ServiceFingerprint).map {
it to (it.result ?: return PatchResultError("${it.name} failed to resolve"))
}.forEach { (fingerprint, result) ->
with(result.mutableMethod) {
// parameter which holds the context
val contextParameter = if (fingerprint == ServiceFingerprint) parameters.size else 1
// register which holds the context
val contextRegister = implementation!!.registerCount - contextParameter
val method = result.mutableMethod addInstruction(
val implementation = method.implementation!! 0,
val count = implementation.registerCount - 1 "sput-object v$contextRegister, $INTEGRATIONS_DESCRIPTOR->context:Landroid/content/Context;"
method.addInstruction(
0, "sput-object v$count, Lapp/revanced/integrations/utils/ReVancedUtils;->context:Landroid/content/Context;"
)
val classDef = result.mutableClass
classDef.methods.add(
ImmutableMethod(
classDef.type,
"getAppContext",
null,
"Landroid/content/Context;",
AccessFlags.PUBLIC or AccessFlags.STATIC,
null,
null,
ImmutableMethodImplementation(
1, """
invoke-static { }, Lapp/revanced/integrations/utils/ReVancedUtils;->getAppContext()Landroid/content/Context;
move-result-object v0
return-object v0
""".toInstructions(), null, null
) )
).toMutable() }
) }
return PatchResultSuccess() return PatchResultSuccess()
} }
} }

View File

@@ -1,17 +0,0 @@
package app.revanced.patches.youtube.misc.settings.bytecode.fingerprints
import app.revanced.patcher.annotation.Name
import app.revanced.patcher.annotation.Version
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
import app.revanced.patches.youtube.misc.settings.annotations.SettingsCompatibility
// TODO: This is more of a class fingerprint than a method fingerprint.
// Convert to a class fingerprint whenever possible.
@Name("revanced-settings-activity-fingerprint")
@SettingsCompatibility
@Version("0.0.1")
object ReVancedSettingsActivityFingerprint : MethodFingerprint(
customFingerprint = { methodDef ->
methodDef.definingClass.endsWith("ReVancedSettingActivity;") && methodDef.name == "initializeSettings"
}
)

View File

@@ -0,0 +1,39 @@
package app.revanced.patches.youtube.misc.settings.bytecode.fingerprints
import app.revanced.patcher.annotation.Name
import app.revanced.patcher.annotation.Version
import app.revanced.patcher.extensions.or
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
import app.revanced.patches.youtube.misc.settings.annotations.SettingsCompatibility
import org.jf.dexlib2.AccessFlags
import org.jf.dexlib2.Opcode
@Name("theme-setter-app-fingerprint")
@SettingsCompatibility
@Version("0.0.1")
object ThemeSetterAppFingerprint : MethodFingerprint(
"L", AccessFlags.PUBLIC or AccessFlags.STATIC, listOf("L", "L", "L"), listOf(
Opcode.INVOKE_VIRTUAL,
Opcode.MOVE_RESULT,
Opcode.IF_EQZ,
Opcode.INVOKE_VIRTUAL,
Opcode.MOVE_RESULT,
Opcode.IF_EQZ,
Opcode.NEW_INSTANCE,
Opcode.INVOKE_INTERFACE,
Opcode.MOVE_RESULT_OBJECT,
Opcode.SGET_OBJECT,
Opcode.IF_NE,
Opcode.CONST,
Opcode.GOTO,
Opcode.CONST,
Opcode.INVOKE_DIRECT,
Opcode.RETURN_OBJECT,
Opcode.NEW_INSTANCE,
Opcode.INVOKE_INTERFACE,
Opcode.MOVE_RESULT_OBJECT,
Opcode.SGET_OBJECT,
Opcode.IF_NE,
Opcode.CONST,
)
)

View File

@@ -5,18 +5,19 @@ import app.revanced.patcher.annotation.Version
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
import app.revanced.patches.youtube.misc.settings.annotations.SettingsCompatibility import app.revanced.patches.youtube.misc.settings.annotations.SettingsCompatibility
import app.revanced.patches.youtube.misc.settings.bytecode.patch.SettingsPatch import app.revanced.patches.youtube.misc.settings.bytecode.patch.SettingsPatch
import app.revanced.patches.youtube.misc.settings.resource.patch.SettingsResourcePatch
import org.jf.dexlib2.Opcode import org.jf.dexlib2.Opcode
import org.jf.dexlib2.iface.instruction.WideLiteralInstruction import org.jf.dexlib2.iface.instruction.WideLiteralInstruction
@Name("theme-setter-fingerprint") @Name("theme-setter-system-fingerprint")
@SettingsCompatibility @SettingsCompatibility
@Version("0.0.1") @Version("0.0.1")
object ThemeSetterFingerprint : MethodFingerprint( object ThemeSetterSystemFingerprint : MethodFingerprint(
"L", "L",
opcodes = listOf(Opcode.RETURN_OBJECT), opcodes = listOf(Opcode.RETURN_OBJECT),
customFingerprint = { methodDef -> customFingerprint = { methodDef ->
methodDef.implementation?.instructions?.any { methodDef.implementation?.instructions?.any {
it.opcode.ordinal == Opcode.CONST.ordinal && (it as WideLiteralInstruction).wideLiteral == SettingsPatch.appearanceStringId it.opcode.ordinal == Opcode.CONST.ordinal && (it as WideLiteralInstruction).wideLiteral == SettingsResourcePatch.appearanceStringId
} == true } == true
} }
) )

View File

@@ -11,15 +11,12 @@ import app.revanced.patcher.patch.PatchResult
import app.revanced.patcher.patch.PatchResultSuccess import app.revanced.patcher.patch.PatchResultSuccess
import app.revanced.patcher.patch.annotations.DependsOn import app.revanced.patcher.patch.annotations.DependsOn
import app.revanced.patcher.patch.annotations.Patch import app.revanced.patcher.patch.annotations.Patch
import app.revanced.patcher.util.smali.toInstruction
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.ResourceMappingResourcePatch
import app.revanced.patches.youtube.misc.settings.annotations.SettingsCompatibility import app.revanced.patches.youtube.misc.settings.annotations.SettingsCompatibility
import app.revanced.patches.youtube.misc.settings.bytecode.fingerprints.LicenseActivityFingerprint import app.revanced.patches.youtube.misc.settings.bytecode.fingerprints.LicenseActivityFingerprint
import app.revanced.patches.youtube.misc.settings.bytecode.fingerprints.ReVancedSettingsActivityFingerprint import app.revanced.patches.youtube.misc.settings.bytecode.fingerprints.ThemeSetterAppFingerprint
import app.revanced.patches.youtube.misc.settings.bytecode.fingerprints.ThemeSetterFingerprint import app.revanced.patches.youtube.misc.settings.bytecode.fingerprints.ThemeSetterSystemFingerprint
import app.revanced.patches.youtube.misc.settings.framework.components.BasePreference import app.revanced.patches.youtube.misc.settings.framework.components.BasePreference
import app.revanced.patches.youtube.misc.settings.framework.components.impl.ArrayResource
import app.revanced.patches.youtube.misc.settings.framework.components.impl.Preference import app.revanced.patches.youtube.misc.settings.framework.components.impl.Preference
import app.revanced.patches.youtube.misc.settings.framework.components.impl.PreferenceScreen import app.revanced.patches.youtube.misc.settings.framework.components.impl.PreferenceScreen
import app.revanced.patches.youtube.misc.settings.framework.components.impl.StringResource import app.revanced.patches.youtube.misc.settings.framework.components.impl.StringResource
@@ -39,64 +36,92 @@ import java.io.Closeable
@SettingsCompatibility @SettingsCompatibility
@Version("0.0.1") @Version("0.0.1")
class SettingsPatch : BytecodePatch( class SettingsPatch : BytecodePatch(
listOf(LicenseActivityFingerprint, ReVancedSettingsActivityFingerprint, ThemeSetterFingerprint) listOf(LicenseActivityFingerprint, ThemeSetterSystemFingerprint, ThemeSetterAppFingerprint)
) { ) {
override fun execute(context: BytecodeContext): PatchResult { override fun execute(context: BytecodeContext): PatchResult {
val licenseActivityResult = LicenseActivityFingerprint.result!! fun buildInvokeInstructionsString(
val settingsResult = ReVancedSettingsActivityFingerprint.result!! registers: String = "v0",
val themeSetterResult = ThemeSetterFingerprint.result!! classDescriptor: String = THEME_HELPER_DESCRIPTOR,
methodName: String = SET_THEME_METHOD_NAME,
parameters: String = "Ljava/lang/Object;"
) = "invoke-static {$registers}, $classDescriptor->$methodName($parameters)V"
val licenseActivityClass = licenseActivityResult.mutableClass // apply the current theme of the settings page
val settingsClass = settingsResult.mutableClass with(ThemeSetterSystemFingerprint.result!!) {
with(mutableMethod) {
val call = buildInvokeInstructionsString()
val onCreate = licenseActivityResult.mutableMethod addInstruction(
val setThemeMethodName = "setTheme" scanResult.patternScanResult!!.startIndex,
val initializeSettings = settingsResult.mutableMethod call
)
val setThemeInstruction = addInstruction(
"invoke-static {v0}, Lapp/revanced/integrations/utils/ThemeHelper;->setTheme(Ljava/lang/Object;)V".toInstruction( mutableMethod.implementation!!.instructions.size - 1,
themeSetterResult.mutableMethod call
) )
}
// add instructions to set the theme of the settings activity
themeSetterResult.mutableMethod.implementation!!.let {
it.addInstruction(
themeSetterResult.scanResult.patternScanResult!!.startIndex,
setThemeInstruction
)
it.addInstruction(
it.instructions.size - 1, // add before return
setThemeInstruction
)
} }
// add the setTheme call to the onCreate method to not affect the offsets // set the theme based on the preference of the app
onCreate.addInstructions( with(ThemeSetterAppFingerprint.result!!) {
1, with(mutableMethod) {
""" fun buildInstructionsString(theme: Int) = """
invoke-static { p0 }, ${settingsClass.type}->${initializeSettings.name}(${licenseActivityClass.type})V const/4 v0, 0x$theme
return-void ${buildInvokeInstructionsString(parameters = "I")}
""" """
)
// add the initializeSettings call to the onCreate method addInstructions(
onCreate.addInstruction( scanResult.patternScanResult!!.endIndex + 1,
0, buildInstructionsString(1)
"invoke-static { p0 }, ${settingsClass.type}->$setThemeMethodName(${licenseActivityClass.type})V" )
)
// get rid of, now, useless overridden methods addInstructions(
licenseActivityResult.mutableClass.methods.removeIf { it.name != "onCreate" && !MethodUtil.isConstructor(it) } mutableMethod.implementation!!.instructions.size - 2,
buildInstructionsString(0)
)
}
}
// set the theme based on the preference of the device
with(LicenseActivityFingerprint.result!!) licenseActivity@{
with(mutableMethod) {
fun buildSettingsActivityInvokeString(
registers: String = "p0",
classDescriptor: String = SETTINGS_ACTIVITY_DESCRIPTOR,
methodName: String = "initializeSettings",
parameters: String = this@licenseActivity.mutableClass.type
) = buildInvokeInstructionsString(registers, classDescriptor, methodName, parameters)
// initialize the settings
addInstructions(
1,
"""
${buildSettingsActivityInvokeString()}
return-void
"""
)
// set the current theme
addInstruction(0, buildSettingsActivityInvokeString(methodName = "setTheme"))
}
// remove method overrides
with(mutableClass) {
methods.removeIf { it.name != "onCreate" && !MethodUtil.isConstructor(it) }
}
}
return PatchResultSuccess() return PatchResultSuccess()
} }
internal companion object { internal companion object {
// TODO: hide this somehow private const val INTEGRATIONS_PACKAGE = "app/revanced/integrations"
var appearanceStringId: Long = ResourceMappingResourcePatch.resourceMappings.find {
it.type == "string" && it.name == "app_theme_appearance_dark" private const val SETTINGS_ACTIVITY_DESCRIPTOR = "L$INTEGRATIONS_PACKAGE/settingsmenu/ReVancedSettingActivity;"
}!!.id
private const val THEME_HELPER_DESCRIPTOR = "L$INTEGRATIONS_PACKAGE/utils/ThemeHelper;"
private const val SET_THEME_METHOD_NAME = "setTheme"
fun addString(identifier: String, value: String, formatted: Boolean = true) = fun addString(identifier: String, value: String, formatted: Boolean = true) =
SettingsResourcePatch.addString(identifier, value, formatted) SettingsResourcePatch.addString(identifier, value, formatted)
@@ -107,9 +132,6 @@ class SettingsPatch : BytecodePatch(
fun addPreference(preference: Preference) = fun addPreference(preference: Preference) =
SettingsResourcePatch.addPreference(preference) SettingsResourcePatch.addPreference(preference)
fun addArray(arrayResource: ArrayResource) =
SettingsResourcePatch.addArray(arrayResource)
fun renameIntentsTargetPackage(newPackage: String) { fun renameIntentsTargetPackage(newPackage: String) {
SettingsResourcePatch.overrideIntentsTargetPackage = newPackage SettingsResourcePatch.overrideIntentsTargetPackage = newPackage
} }
@@ -152,4 +174,4 @@ class SettingsPatch : BytecodePatch(
override fun close() = PreferenceScreen.values().forEach(PreferenceScreen::close) override fun close() = PreferenceScreen.values().forEach(PreferenceScreen::close)
} }

View File

@@ -24,8 +24,14 @@ import org.w3c.dom.Node
@DependsOn([FixLocaleConfigErrorPatch::class, ResourceMappingResourcePatch::class]) @DependsOn([FixLocaleConfigErrorPatch::class, ResourceMappingResourcePatch::class])
@Version("0.0.1") @Version("0.0.1")
class SettingsResourcePatch : ResourcePatch { class SettingsResourcePatch : ResourcePatch {
override fun execute(context: ResourceContext): PatchResult { override fun execute(context: ResourceContext): PatchResult {
/*
* used by a fingerprint of SettingsPatch
*/
appearanceStringId = ResourceMappingResourcePatch.resourceMappings.find {
it.type == "string" && it.name == "app_theme_appearance_dark"
}!!.id
/* /*
* create missing directory for the resources * create missing directory for the resources
*/ */
@@ -84,6 +90,12 @@ class SettingsResourcePatch : ResourcePatch {
internal companion object { internal companion object {
// Used by a fingerprint of SettingsPatch
// this field is located in the SettingsResourcePatch
// because if it were to be defined in the SettingsPatch companion object,
// the companion object could be initialized before ResourceMappingResourcePatch has executed.
internal var appearanceStringId: Long = -1
// if this is not null, all intents will be renamed to this // if this is not null, all intents will be renamed to this
var overrideIntentsTargetPackage: String? = null var overrideIntentsTargetPackage: String? = null

View File

@@ -0,0 +1,8 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<style name="Base.Theme.YouTube.Launcher" parent="@style/Theme.AppCompat.NoActionBar">
<item name="android:windowSplashScreenBackground">@android:color/black</item>
<item name="android:windowSplashScreenAnimatedIcon">@drawable/avd_anim</item>
<item name="android:windowSplashScreenAnimationDuration">1000</item>
</style>
</resources>