diff --git a/src/main/kotlin/app/revanced/patches/music/general/branding/name/CustomBrandingNamePatch.kt b/src/main/kotlin/app/revanced/patches/music/general/branding/name/CustomBrandingNamePatch.kt index ba43f4abb..55cd04380 100644 --- a/src/main/kotlin/app/revanced/patches/music/general/branding/name/CustomBrandingNamePatch.kt +++ b/src/main/kotlin/app/revanced/patches/music/general/branding/name/CustomBrandingNamePatch.kt @@ -2,19 +2,22 @@ package app.revanced.patches.music.general.branding.name import app.revanced.patcher.data.ResourceContext import app.revanced.patcher.patch.PatchException -import app.revanced.patcher.patch.ResourcePatch import app.revanced.patcher.patch.annotation.CompatiblePackage import app.revanced.patcher.patch.annotation.Patch import app.revanced.patcher.patch.options.PatchOption.PatchExtensions.stringPatchOption +import app.revanced.patches.music.utils.integrations.Constants.LANGUAGE_LIST +import app.revanced.patches.shared.patch.elements.AbstractRemoveStringsElementsPatch @Patch( name = "Custom branding name YouTube Music", description = "Rename the YouTube Music app to the name specified in options.json.", - dependencies = [RemoveElementsPatch::class], compatiblePackages = [CompatiblePackage("com.google.android.apps.youtube.music")] ) @Suppress("unused") -object CustomBrandingNamePatch : ResourcePatch() { +object CustomBrandingNamePatch : AbstractRemoveStringsElementsPatch( + LANGUAGE_LIST, + arrayOf("app_launcher_name", "app_name") +) { private const val APP_NAME_NOTIFICATION = "ReVanced Extended Music" private const val APP_NAME_LAUNCHER = "RVX Music" @@ -43,6 +46,7 @@ object CustomBrandingNamePatch : ResourcePatch() { ) override fun execute(context: ResourceContext) { + super.execute(context) AppNameNotification?.let { notificationName -> AppNameLauncher?.let { launcherName -> diff --git a/src/main/kotlin/app/revanced/patches/music/general/branding/name/RemoveElementsPatch.kt b/src/main/kotlin/app/revanced/patches/music/general/branding/name/RemoveElementsPatch.kt deleted file mode 100644 index 95ccd0d54..000000000 --- a/src/main/kotlin/app/revanced/patches/music/general/branding/name/RemoveElementsPatch.kt +++ /dev/null @@ -1,121 +0,0 @@ -package app.revanced.patches.music.general.branding.name - -import app.revanced.patcher.data.ResourceContext -import app.revanced.patcher.patch.ResourcePatch -import kotlin.io.path.exists - -object RemoveElementsPatch : ResourcePatch() { - override fun execute(context: ResourceContext) { - - LANGUAGE_LIST.forEach { path -> - val resDirectory = context["res"] - val targetXmlPath = resDirectory.resolve(path).resolve("strings.xml").toPath() - - if (targetXmlPath.exists()) { - val targetXml = context["res/$path/strings.xml"] - - targetXml.writeText( - targetXml.readText() - .replace(""".+"app_launcher_name".+""".toRegex(), "") - .replace(""".+"app_name".+""".toRegex(), "") - ) - } - } - - } - - private val LANGUAGE_LIST = arrayOf( - "values", - "values-af", - "values-am", - "values-ar", - "values-ar-rXB", - "values-as", - "values-az", - "values-b+es+419", - "values-b+sr+Latn", - "values-be", - "values-bg", - "values-bn", - "values-bs", - "values-ca", - "values-cs", - "values-da", - "values-de", - "values-el", - "values-en-rAU", - "values-en-rCA", - "values-en-rGB", - "values-en-rIN", - "values-en-rXA", - "values-en-rXC", - "values-es", - "values-es-rUS", - "values-et", - "values-eu", - "values-fa", - "values-fi", - "values-fr", - "values-fr-rCA", - "values-gl", - "values-gu", - "values-hi", - "values-hr", - "values-hu", - "values-hy", - "values-id", - "values-in", - "values-is", - "values-it", - "values-iw", - "values-ja", - "values-ka", - "values-kk", - "values-km", - "values-kn", - "values-ko", - "values-ky", - "values-lo", - "values-lt", - "values-lv", - "values-mk", - "values-ml", - "values-mn", - "values-mr", - "values-ms", - "values-my", - "values-nb", - "values-ne", - "values-nl", - "values-no", - "values-or", - "values-pa", - "values-pl", - "values-pt", - "values-pt-rBR", - "values-pt-rPT", - "values-ro", - "values-ru", - "values-si", - "values-sk", - "values-sl", - "values-sq", - "values-sr", - "values-sv", - "values-sw", - "values-ta", - "values-te", - "values-th", - "values-tl", - "values-tr", - "values-uk", - "values-ur", - "values-uz", - "values-vi", - "values-zh", - "values-zh-rCN", - "values-zh-rHK", - "values-zh-rTW", - "values-zu" - ) -} diff --git a/src/main/kotlin/app/revanced/patches/music/misc/tracking/SanitizeUrlQueryPatch.kt b/src/main/kotlin/app/revanced/patches/music/misc/tracking/SanitizeUrlQueryPatch.kt index e83fc7355..67a657aa7 100644 --- a/src/main/kotlin/app/revanced/patches/music/misc/tracking/SanitizeUrlQueryPatch.kt +++ b/src/main/kotlin/app/revanced/patches/music/misc/tracking/SanitizeUrlQueryPatch.kt @@ -18,12 +18,7 @@ import app.revanced.patches.shared.patch.tracking.AbstractSanitizeUrlQueryPatch ) @Suppress("unused") object SanitizeUrlQueryPatch : AbstractSanitizeUrlQueryPatch( - "$MISC_PATH/SanitizeUrlQueryPatch;", - listOf( - CopyTextEndpointFingerprint, - ShareLinkFormatterFingerprint - ), - null + "$MISC_PATH/SanitizeUrlQueryPatch;" ) { override fun execute(context: BytecodeContext) { super.execute(context) diff --git a/src/main/kotlin/app/revanced/patches/music/utils/integrations/Constants.kt b/src/main/kotlin/app/revanced/patches/music/utils/integrations/Constants.kt index f61d13808..b274d89ae 100644 --- a/src/main/kotlin/app/revanced/patches/music/utils/integrations/Constants.kt +++ b/src/main/kotlin/app/revanced/patches/music/utils/integrations/Constants.kt @@ -23,4 +23,99 @@ object Constants { const val GENERAL = "$GENERAL_PATH/GeneralPatch;" const val NAVIGATION = "$NAVIGATION_PATH/NavigationPatch;" const val PLAYER = "$PLAYER_PATH/PlayerPatch;" + + val LANGUAGE_LIST = arrayOf( + "values", + "values-af", + "values-am", + "values-ar", + "values-ar-rXB", + "values-as", + "values-az", + "values-b+es+419", + "values-b+sr+Latn", + "values-be", + "values-bg", + "values-bn", + "values-bs", + "values-ca", + "values-cs", + "values-da", + "values-de", + "values-el", + "values-en-rAU", + "values-en-rCA", + "values-en-rGB", + "values-en-rIN", + "values-en-rXA", + "values-en-rXC", + "values-es", + "values-es-rUS", + "values-et", + "values-eu", + "values-fa", + "values-fi", + "values-fr", + "values-fr-rCA", + "values-gl", + "values-gu", + "values-hi", + "values-hr", + "values-hu", + "values-hy", + "values-id", + "values-in", + "values-is", + "values-it", + "values-iw", + "values-ja", + "values-ka", + "values-kk", + "values-km", + "values-kn", + "values-ko", + "values-ky", + "values-lo", + "values-lt", + "values-lv", + "values-mk", + "values-ml", + "values-mn", + "values-mr", + "values-ms", + "values-my", + "values-nb", + "values-ne", + "values-nl", + "values-no", + "values-or", + "values-pa", + "values-pl", + "values-pt", + "values-pt-rBR", + "values-pt-rPT", + "values-ro", + "values-ru", + "values-si", + "values-sk", + "values-sl", + "values-sq", + "values-sr", + "values-sv", + "values-sw", + "values-ta", + "values-te", + "values-th", + "values-tl", + "values-tr", + "values-uk", + "values-ur", + "values-uz", + "values-vi", + "values-zh", + "values-zh-rCN", + "values-zh-rHK", + "values-zh-rTW", + "values-zu" + ) } \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/shared/patch/elements/AbstractRemoveStringsElementsPatch.kt b/src/main/kotlin/app/revanced/patches/shared/patch/elements/AbstractRemoveStringsElementsPatch.kt new file mode 100644 index 000000000..480f0d25c --- /dev/null +++ b/src/main/kotlin/app/revanced/patches/shared/patch/elements/AbstractRemoveStringsElementsPatch.kt @@ -0,0 +1,28 @@ +package app.revanced.patches.shared.patch.elements + +import app.revanced.patcher.data.ResourceContext +import app.revanced.patcher.patch.ResourcePatch +import kotlin.io.path.exists + +abstract class AbstractRemoveStringsElementsPatch( + private val paths: Array, + private val replacements: Array +) : ResourcePatch() { + override fun execute(context: ResourceContext) { + paths.forEach { path -> + val resDirectory = context["res"] + val targetXmlPath = resDirectory.resolve(path).resolve("strings.xml").toPath() + + if (targetXmlPath.exists()) { + val targetXml = context["res/$path/strings.xml"] + + replacements.forEach replacementsLoop@{ replacement -> + targetXml.writeText( + targetXml.readText() + .replace(""".+"$replacement".+""".toRegex(), "") + ) + } + } + } + } +} diff --git a/src/main/kotlin/app/revanced/patches/shared/patch/tracking/AbstractSanitizeUrlQueryPatch.kt b/src/main/kotlin/app/revanced/patches/shared/patch/tracking/AbstractSanitizeUrlQueryPatch.kt index f9fc7b392..9dbe0446e 100644 --- a/src/main/kotlin/app/revanced/patches/shared/patch/tracking/AbstractSanitizeUrlQueryPatch.kt +++ b/src/main/kotlin/app/revanced/patches/shared/patch/tracking/AbstractSanitizeUrlQueryPatch.kt @@ -3,21 +3,50 @@ package app.revanced.patches.shared.patch.tracking import app.revanced.patcher.data.BytecodeContext import app.revanced.patcher.extensions.InstructionExtensions.addInstructions import app.revanced.patcher.extensions.InstructionExtensions.getInstruction +import app.revanced.patcher.extensions.InstructionExtensions.replaceInstruction import app.revanced.patcher.fingerprint.MethodFingerprint import app.revanced.patcher.patch.BytecodePatch +import app.revanced.patches.shared.fingerprints.tracking.CopyTextEndpointFingerprint import app.revanced.util.exception +import com.android.tools.smali.dexlib2.Opcode +import com.android.tools.smali.dexlib2.iface.instruction.FiveRegisterInstruction +import com.android.tools.smali.dexlib2.iface.instruction.ReferenceInstruction import com.android.tools.smali.dexlib2.iface.instruction.TwoRegisterInstruction abstract class AbstractSanitizeUrlQueryPatch( private val descriptor: String, - private val sharedFingerprints: List, - private val additionalFingerprints: List? = null + private val additionalFingerprints: Set = emptySet() ) : BytecodePatch( buildSet { - addAll(sharedFingerprints) - additionalFingerprints?.let(::addAll) + add(CopyTextEndpointFingerprint) + additionalFingerprints.let(::addAll) } ) { + private fun MethodFingerprint.additionalInvoke() { + result?.let { + it.mutableMethod.apply { + for ((index, instruction) in implementation!!.instructions.withIndex()) { + if (instruction.opcode != Opcode.INVOKE_VIRTUAL) + continue + + if ((instruction as ReferenceInstruction).reference.toString() != "Landroid/content/Intent;->putExtra(Ljava/lang/String;Ljava/lang/String;)Landroid/content/Intent;") + continue + + if (getInstruction(index + 1).opcode != Opcode.GOTO) + continue + + val invokeInstruction = instruction as FiveRegisterInstruction + + replaceInstruction( + index, + "invoke-static {v${invokeInstruction.registerC}, v${invokeInstruction.registerD}, v${invokeInstruction.registerE}}, " + + "$descriptor->stripQueryParameters(Landroid/content/Intent;Ljava/lang/String;Ljava/lang/String;)V" + ) + } + } + } ?: throw exception + } + private fun MethodFingerprint.invoke() { result?.let { it.mutableMethod.apply { @@ -35,7 +64,12 @@ abstract class AbstractSanitizeUrlQueryPatch( } override fun execute(context: BytecodeContext) { - for (fingerprint in sharedFingerprints) - fingerprint.invoke() + CopyTextEndpointFingerprint.invoke() + + if (additionalFingerprints.isNotEmpty()) { + additionalFingerprints.forEach { fingerprint -> + fingerprint.additionalInvoke() + } + } } } \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/branding/name/CustomBrandingNamePatch.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/branding/name/CustomBrandingNamePatch.kt index 3d3a863a0..547ca7104 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/layout/branding/name/CustomBrandingNamePatch.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/layout/branding/name/CustomBrandingNamePatch.kt @@ -2,20 +2,18 @@ package app.revanced.patches.youtube.layout.branding.name import app.revanced.patcher.data.ResourceContext import app.revanced.patcher.patch.PatchException -import app.revanced.patcher.patch.ResourcePatch import app.revanced.patcher.patch.annotation.CompatiblePackage import app.revanced.patcher.patch.annotation.Patch import app.revanced.patcher.patch.options.PatchOption.PatchExtensions.stringPatchOption +import app.revanced.patches.shared.patch.elements.AbstractRemoveStringsElementsPatch +import app.revanced.patches.youtube.utils.integrations.Constants.LANGUAGE_LIST import app.revanced.patches.youtube.utils.settings.ResourceUtils.updatePatchStatusLabel import app.revanced.patches.youtube.utils.settings.SettingsPatch @Patch( name = "Custom branding name YouTube", description = "Rename the YouTube app to the name specified in options.json.", - dependencies = [ - RemoveElementsPatch::class, - SettingsPatch::class - ], + dependencies = [SettingsPatch::class], compatiblePackages = [ CompatiblePackage( "com.google.android.youtube", @@ -44,7 +42,10 @@ import app.revanced.patches.youtube.utils.settings.SettingsPatch ] ) @Suppress("unused") -object CustomBrandingNamePatch : ResourcePatch() { +object CustomBrandingNamePatch : AbstractRemoveStringsElementsPatch( + LANGUAGE_LIST, + arrayOf("application_name") +) { private const val APP_NAME = "ReVanced Extended" private val AppName by stringPatchOption( @@ -60,6 +61,7 @@ object CustomBrandingNamePatch : ResourcePatch() { ) override fun execute(context: ResourceContext) { + super.execute(context) AppName?.let { context.xmlEditor["res/values/strings.xml"].use { editor -> diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/branding/name/RemoveElementsPatch.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/branding/name/RemoveElementsPatch.kt deleted file mode 100644 index 9f10f1a3b..000000000 --- a/src/main/kotlin/app/revanced/patches/youtube/layout/branding/name/RemoveElementsPatch.kt +++ /dev/null @@ -1,111 +0,0 @@ -package app.revanced.patches.youtube.layout.branding.name - -import app.revanced.patcher.data.ResourceContext -import app.revanced.patcher.patch.ResourcePatch -import kotlin.io.path.exists - -object RemoveElementsPatch : ResourcePatch() { - override fun execute(context: ResourceContext) { - - LANGUAGE_LIST.forEach { path -> - val resDirectory = context["res"] - val targetXmlPath = resDirectory.resolve(path).resolve("strings.xml").toPath() - - if (targetXmlPath.exists()) { - val targetXml = context["res/$path/strings.xml"] - - targetXml.writeText( - targetXml.readText() - .replace(""".+"application_name".+""".toRegex(), "") - ) - } - } - - } - - private val LANGUAGE_LIST = arrayOf( - "values", - "values-af", - "values-am", - "values-ar", - "values-as", - "values-az", - "values-b+sr+Latn", - "values-be", - "values-bg", - "values-bn", - "values-bs", - "values-ca", - "values-cs", - "values-da", - "values-de", - "values-el", - "values-en-rGB", - "values-en-rIN", - "values-es", - "values-es-rUS", - "values-et", - "values-eu", - "values-fa", - "values-fi", - "values-fr", - "values-fr-rCA", - "values-gl", - "values-gu", - "values-hi", - "values-hr", - "values-hu", - "values-hy", - "values-in", - "values-is", - "values-it", - "values-iw", - "values-ja", - "values-ka", - "values-kk", - "values-km", - "values-kn", - "values-ko", - "values-ky", - "values-lo", - "values-lt", - "values-lv", - "values-mk", - "values-ml", - "values-mn", - "values-mr", - "values-ms", - "values-my", - "values-nb", - "values-ne", - "values-nl", - "values-or", - "values-pa", - "values-pl", - "values-pt", - "values-pt-rBR", - "values-pt-rPT", - "values-ro", - "values-ru", - "values-si", - "values-sk", - "values-sl", - "values-sq", - "values-sr", - "values-sv", - "values-sw", - "values-ta", - "values-te", - "values-th", - "values-tl", - "values-tr", - "values-uk", - "values-ur", - "values-uz", - "values-vi", - "values-zh-rCN", - "values-zh-rHK", - "values-zh-rTW", - "values-zu" - ) -} diff --git a/src/main/kotlin/app/revanced/patches/youtube/misc/tracking/SanitizeUrlQueryPatch.kt b/src/main/kotlin/app/revanced/patches/youtube/misc/tracking/SanitizeUrlQueryPatch.kt index eb968a552..b380a274f 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/misc/tracking/SanitizeUrlQueryPatch.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/misc/tracking/SanitizeUrlQueryPatch.kt @@ -1,20 +1,13 @@ package app.revanced.patches.youtube.misc.tracking import app.revanced.patcher.data.BytecodeContext -import app.revanced.patcher.extensions.InstructionExtensions.getInstruction -import app.revanced.patcher.extensions.InstructionExtensions.replaceInstruction import app.revanced.patcher.patch.annotation.CompatiblePackage import app.revanced.patcher.patch.annotation.Patch -import app.revanced.patches.shared.fingerprints.tracking.CopyTextEndpointFingerprint import app.revanced.patches.shared.patch.tracking.AbstractSanitizeUrlQueryPatch import app.revanced.patches.youtube.misc.tracking.fingerprints.ShareLinkFormatterFingerprint import app.revanced.patches.youtube.misc.tracking.fingerprints.SystemShareLinkFormatterFingerprint import app.revanced.patches.youtube.utils.integrations.Constants.MISC_PATH import app.revanced.patches.youtube.utils.settings.SettingsPatch -import app.revanced.util.exception -import com.android.tools.smali.dexlib2.Opcode -import com.android.tools.smali.dexlib2.iface.instruction.FiveRegisterInstruction -import com.android.tools.smali.dexlib2.iface.instruction.ReferenceInstruction @Patch( name = "Sanitize sharing links", @@ -50,47 +43,14 @@ import com.android.tools.smali.dexlib2.iface.instruction.ReferenceInstruction @Suppress("unused") object SanitizeUrlQueryPatch : AbstractSanitizeUrlQueryPatch( "$MISC_PATH/SanitizeUrlQueryPatch;", - listOf(CopyTextEndpointFingerprint), - listOf( + setOf( ShareLinkFormatterFingerprint, SystemShareLinkFormatterFingerprint ) ) { - private const val INTEGRATIONS_CLASS_DESCRIPTOR = - "$MISC_PATH/SanitizeUrlQueryPatch;" - override fun execute(context: BytecodeContext) { super.execute(context) - arrayOf( - ShareLinkFormatterFingerprint, - SystemShareLinkFormatterFingerprint - ).forEach { fingerprint -> - fingerprint.result?.let { - it.mutableMethod.apply { - for ((index, instruction) in implementation!!.instructions.withIndex()) { - if (instruction.opcode != Opcode.INVOKE_VIRTUAL) - continue - - if ((instruction as ReferenceInstruction).reference.toString() != "Landroid/content/Intent;->putExtra(Ljava/lang/String;Ljava/lang/String;)Landroid/content/Intent;") - continue - - if (getInstruction(index + 1).opcode != Opcode.GOTO) - continue - - val invokeInstruction = instruction as FiveRegisterInstruction - - replaceInstruction( - index, - "invoke-static {v${invokeInstruction.registerC}, v${invokeInstruction.registerD}, v${invokeInstruction.registerE}}, " - + "$INTEGRATIONS_CLASS_DESCRIPTOR->stripQueryParameters(Landroid/content/Intent;Ljava/lang/String;Ljava/lang/String;)V" - ) - } - } - } ?: throw fingerprint.exception - } - - /** * Add settings */ diff --git a/src/main/kotlin/app/revanced/patches/youtube/utils/integrations/Constants.kt b/src/main/kotlin/app/revanced/patches/youtube/utils/integrations/Constants.kt index ca84f07ff..aa29c38f6 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/utils/integrations/Constants.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/utils/integrations/Constants.kt @@ -31,4 +31,90 @@ object Constants { const val PLAYER = "$PLAYER_PATH/PlayerPatch;" const val SEEKBAR = "$SEEKBAR_PATH/SeekBarPatch;" const val SHORTS = "$SHORTS_PATH/ShortsPatch;" + + val LANGUAGE_LIST = arrayOf( + "values", + "values-af", + "values-am", + "values-ar", + "values-as", + "values-az", + "values-b+sr+Latn", + "values-be", + "values-bg", + "values-bn", + "values-bs", + "values-ca", + "values-cs", + "values-da", + "values-de", + "values-el", + "values-en-rGB", + "values-en-rIN", + "values-es", + "values-es-rUS", + "values-et", + "values-eu", + "values-fa", + "values-fi", + "values-fr", + "values-fr-rCA", + "values-gl", + "values-gu", + "values-hi", + "values-hr", + "values-hu", + "values-hy", + "values-in", + "values-is", + "values-it", + "values-iw", + "values-ja", + "values-ka", + "values-kk", + "values-km", + "values-kn", + "values-ko", + "values-ky", + "values-lo", + "values-lt", + "values-lv", + "values-mk", + "values-ml", + "values-mn", + "values-mr", + "values-ms", + "values-my", + "values-nb", + "values-ne", + "values-nl", + "values-or", + "values-pa", + "values-pl", + "values-pt", + "values-pt-rBR", + "values-pt-rPT", + "values-ro", + "values-ru", + "values-si", + "values-sk", + "values-sl", + "values-sq", + "values-sr", + "values-sv", + "values-sw", + "values-ta", + "values-te", + "values-th", + "values-tl", + "values-tr", + "values-uk", + "values-ur", + "values-uz", + "values-vi", + "values-zh-rCN", + "values-zh-rHK", + "values-zh-rTW", + "values-zu" + ) } \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/youtube/utils/settings/SettingsPatch.kt b/src/main/kotlin/app/revanced/patches/youtube/utils/settings/SettingsPatch.kt index d62004c78..a773b07ae 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/utils/settings/SettingsPatch.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/utils/settings/SettingsPatch.kt @@ -63,9 +63,6 @@ object SettingsPatch : AbstractSettingsResourcePatch( super.execute(context) contexts = context - /** - * Check if YouTube version is higher than v18.28.xx - */ val resourceXmlFile = context["res/values/integers.xml"].readBytes() for (threadIndex in 0 until THREAD_COUNT) {