mirror of
https://github.com/revanced/revanced-patches.git
synced 2025-12-14 21:22:27 +01:00
Compare commits
10 Commits
v5.20.0-de
...
v5.20.0-de
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
86f867fe97 | ||
|
|
0f687ecfd3 | ||
|
|
6c8b7d09c1 | ||
|
|
3d6958f157 | ||
|
|
43d7cc7374 | ||
|
|
5ebd449f1f | ||
|
|
346a061df8 | ||
|
|
13e490a422 | ||
|
|
b4e8540bbc | ||
|
|
775c1baec2 |
35
CHANGELOG.md
35
CHANGELOG.md
@@ -1,3 +1,38 @@
|
|||||||
|
# [5.20.0-dev.7](https://github.com/ReVanced/revanced-patches/compare/v5.20.0-dev.6...v5.20.0-dev.7) (2025-04-15)
|
||||||
|
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* **Spotify:** Fix login by replacing `Spoof signature` patch with new `Spoof package info` patch ([#4794](https://github.com/ReVanced/revanced-patches/issues/4794)) ([d639151](https://github.com/ReVanced/revanced-patches/commit/d639151641352ce651037b17fb65bd58953cd51c))
|
||||||
|
|
||||||
|
# [5.20.0-dev.6](https://github.com/ReVanced/revanced-patches/compare/v5.20.0-dev.5...v5.20.0-dev.6) (2025-04-15)
|
||||||
|
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* **Duolingo - Hide ads:** Support lastest app release ([#4790](https://github.com/ReVanced/revanced-patches/issues/4790)) ([215fccb](https://github.com/ReVanced/revanced-patches/commit/215fccbaf2fdd54251c46cbda106029eb304996b))
|
||||||
|
|
||||||
|
# [5.20.0-dev.5](https://github.com/ReVanced/revanced-patches/compare/v5.20.0-dev.4...v5.20.0-dev.5) (2025-04-14)
|
||||||
|
|
||||||
|
|
||||||
|
### Features
|
||||||
|
|
||||||
|
* **YouTube - Swipe controls:** Add option to change volume swipe sensitivity (step size) ([#4557](https://github.com/ReVanced/revanced-patches/issues/4557)) ([8957325](https://github.com/ReVanced/revanced-patches/commit/8957325d78eb42e087c4c1ff0abedb2146aa4423))
|
||||||
|
|
||||||
|
# [5.20.0-dev.4](https://github.com/ReVanced/revanced-patches/compare/v5.20.0-dev.3...v5.20.0-dev.4) (2025-04-14)
|
||||||
|
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* **Spotify - Unlock Spotify Premium:** Remove premium restriction for 'Spotify Connect' ([#4782](https://github.com/ReVanced/revanced-patches/issues/4782)) ([50f5b1a](https://github.com/ReVanced/revanced-patches/commit/50f5b1ac54372542d76e87626f00ddefb54da125))
|
||||||
|
|
||||||
|
# [5.20.0-dev.3](https://github.com/ReVanced/revanced-patches/compare/v5.20.0-dev.2...v5.20.0-dev.3) (2025-04-13)
|
||||||
|
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* **YouTube - Remove background playback restrictions:** Restore PiP button functionality after screen is unlocked ([6837348](https://github.com/ReVanced/revanced-patches/commit/6837348c45156d6743a63fef8b6e045087afbda8))
|
||||||
|
|
||||||
# [5.20.0-dev.2](https://github.com/ReVanced/revanced-patches/compare/v5.20.0-dev.1...v5.20.0-dev.2) (2025-04-13)
|
# [5.20.0-dev.2](https://github.com/ReVanced/revanced-patches/compare/v5.20.0-dev.1...v5.20.0-dev.2) (2025-04-13)
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -319,6 +319,7 @@ public class Settings extends BaseSettings {
|
|||||||
parentsAny(SWIPE_BRIGHTNESS, SWIPE_VOLUME));
|
parentsAny(SWIPE_BRIGHTNESS, SWIPE_VOLUME));
|
||||||
public static final IntegerSetting SWIPE_MAGNITUDE_THRESHOLD = new IntegerSetting("revanced_swipe_threshold", 30, true,
|
public static final IntegerSetting SWIPE_MAGNITUDE_THRESHOLD = new IntegerSetting("revanced_swipe_threshold", 30, true,
|
||||||
parentsAny(SWIPE_BRIGHTNESS, SWIPE_VOLUME));
|
parentsAny(SWIPE_BRIGHTNESS, SWIPE_VOLUME));
|
||||||
|
public static final IntegerSetting SWIPE_VOLUME_SENSITIVITY = new IntegerSetting("revanced_swipe_volume_sensitivity", 1, true, parent(SWIPE_VOLUME));
|
||||||
public static final BooleanSetting SWIPE_SHOW_CIRCULAR_OVERLAY = new BooleanSetting("revanced_swipe_show_circular_overlay", FALSE, true,
|
public static final BooleanSetting SWIPE_SHOW_CIRCULAR_OVERLAY = new BooleanSetting("revanced_swipe_show_circular_overlay", FALSE, true,
|
||||||
parentsAny(SWIPE_BRIGHTNESS, SWIPE_VOLUME));
|
parentsAny(SWIPE_BRIGHTNESS, SWIPE_VOLUME));
|
||||||
public static final BooleanSetting SWIPE_OVERLAY_MINIMAL_STYLE = new BooleanSetting("revanced_swipe_overlay_minimal_style", FALSE, true,
|
public static final BooleanSetting SWIPE_OVERLAY_MINIMAL_STYLE = new BooleanSetting("revanced_swipe_overlay_minimal_style", FALSE, true,
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
package app.revanced.extension.youtube.swipecontrols
|
package app.revanced.extension.youtube.swipecontrols
|
||||||
|
|
||||||
import android.content.Context
|
|
||||||
import android.graphics.Color
|
import android.graphics.Color
|
||||||
import app.revanced.extension.shared.StringRef.str
|
import app.revanced.extension.shared.StringRef.str
|
||||||
import app.revanced.extension.shared.Utils
|
import app.revanced.extension.shared.Utils
|
||||||
@@ -9,12 +8,8 @@ import app.revanced.extension.youtube.shared.PlayerType
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* provider for configuration for volume and brightness swipe controls
|
* provider for configuration for volume and brightness swipe controls
|
||||||
*
|
|
||||||
* @param context the context to create in
|
|
||||||
*/
|
*/
|
||||||
class SwipeControlsConfigurationProvider(
|
class SwipeControlsConfigurationProvider {
|
||||||
private val context: Context,
|
|
||||||
) {
|
|
||||||
//region swipe enable
|
//region swipe enable
|
||||||
/**
|
/**
|
||||||
* should swipe controls be enabled? (global setting)
|
* should swipe controls be enabled? (global setting)
|
||||||
@@ -60,6 +55,23 @@ class SwipeControlsConfigurationProvider(
|
|||||||
*/
|
*/
|
||||||
val swipeMagnitudeThreshold: Int
|
val swipeMagnitudeThreshold: Int
|
||||||
get() = Settings.SWIPE_MAGNITUDE_THRESHOLD.get()
|
get() = Settings.SWIPE_MAGNITUDE_THRESHOLD.get()
|
||||||
|
|
||||||
|
/**
|
||||||
|
* How much volume will change by single swipe.
|
||||||
|
* If it is set to 0, it will reset to the default value because 0 would disable swiping.
|
||||||
|
* */
|
||||||
|
val volumeSwipeSensitivity: Int
|
||||||
|
get() {
|
||||||
|
val sensitivity = Settings.SWIPE_VOLUME_SENSITIVITY.get()
|
||||||
|
|
||||||
|
if (sensitivity < 1) {
|
||||||
|
Settings.SWIPE_VOLUME_SENSITIVITY.resetToDefault()
|
||||||
|
|
||||||
|
return Settings.SWIPE_VOLUME_SENSITIVITY.get()
|
||||||
|
}
|
||||||
|
|
||||||
|
return sensitivity
|
||||||
|
}
|
||||||
//endregion
|
//endregion
|
||||||
|
|
||||||
//region overlay adjustments
|
//region overlay adjustments
|
||||||
|
|||||||
@@ -127,7 +127,7 @@ class SwipeControlsHostActivity : Activity() {
|
|||||||
private fun initialize() {
|
private fun initialize() {
|
||||||
// create controllers
|
// create controllers
|
||||||
printDebug { "initializing swipe controls controllers" }
|
printDebug { "initializing swipe controls controllers" }
|
||||||
config = SwipeControlsConfigurationProvider(this)
|
config = SwipeControlsConfigurationProvider()
|
||||||
keys = VolumeKeysController(this)
|
keys = VolumeKeysController(this)
|
||||||
audio = createAudioController()
|
audio = createAudioController()
|
||||||
screen = createScreenController()
|
screen = createScreenController()
|
||||||
|
|||||||
@@ -41,7 +41,7 @@ class VolumeKeysController(
|
|||||||
private fun handleVolumeKeyEvent(event: KeyEvent, volumeUp: Boolean): Boolean {
|
private fun handleVolumeKeyEvent(event: KeyEvent, volumeUp: Boolean): Boolean {
|
||||||
if (event.action == KeyEvent.ACTION_DOWN) {
|
if (event.action == KeyEvent.ACTION_DOWN) {
|
||||||
controller.audio?.apply {
|
controller.audio?.apply {
|
||||||
volume += if (volumeUp) 1 else -1
|
volume += controller.config.volumeSwipeSensitivity * if (volumeUp) 1 else -1
|
||||||
controller.overlay.onVolumeChanged(volume, maxVolume)
|
controller.overlay.onVolumeChanged(volume, maxVolume)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -24,6 +24,7 @@ abstract class BaseGestureController(
|
|||||||
controller.overlay,
|
controller.overlay,
|
||||||
10,
|
10,
|
||||||
1,
|
1,
|
||||||
|
controller.config.volumeSwipeSensitivity,
|
||||||
) {
|
) {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -41,6 +41,7 @@ interface VolumeAndBrightnessScroller {
|
|||||||
* @param overlayController overlay controller instance
|
* @param overlayController overlay controller instance
|
||||||
* @param volumeDistance unit distance for volume scrolling, in dp
|
* @param volumeDistance unit distance for volume scrolling, in dp
|
||||||
* @param brightnessDistance unit distance for brightness scrolling, in dp
|
* @param brightnessDistance unit distance for brightness scrolling, in dp
|
||||||
|
* @param volumeSwipeSensitivity how much volume will change by single swipe
|
||||||
*/
|
*/
|
||||||
class VolumeAndBrightnessScrollerImpl(
|
class VolumeAndBrightnessScrollerImpl(
|
||||||
context: Context,
|
context: Context,
|
||||||
@@ -49,6 +50,7 @@ class VolumeAndBrightnessScrollerImpl(
|
|||||||
private val overlayController: SwipeControlsOverlay,
|
private val overlayController: SwipeControlsOverlay,
|
||||||
volumeDistance: Int = 10,
|
volumeDistance: Int = 10,
|
||||||
brightnessDistance: Int = 1,
|
brightnessDistance: Int = 1,
|
||||||
|
private val volumeSwipeSensitivity: Int,
|
||||||
) : VolumeAndBrightnessScroller {
|
) : VolumeAndBrightnessScroller {
|
||||||
|
|
||||||
// region volume
|
// region volume
|
||||||
@@ -60,7 +62,7 @@ class VolumeAndBrightnessScrollerImpl(
|
|||||||
),
|
),
|
||||||
) { _, _, direction ->
|
) { _, _, direction ->
|
||||||
volumeController?.run {
|
volumeController?.run {
|
||||||
volume += direction
|
volume += direction * volumeSwipeSensitivity
|
||||||
overlayController.onVolumeChanged(volume, maxVolume)
|
overlayController.onVolumeChanged(volume, maxVolume)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -25,7 +25,7 @@ class SwipeControlsOverlayLayout(
|
|||||||
private val config: SwipeControlsConfigurationProvider,
|
private val config: SwipeControlsConfigurationProvider,
|
||||||
) : RelativeLayout(context), SwipeControlsOverlay {
|
) : RelativeLayout(context), SwipeControlsOverlay {
|
||||||
|
|
||||||
constructor(context: Context) : this(context, SwipeControlsConfigurationProvider(context))
|
constructor(context: Context) : this(context, SwipeControlsConfigurationProvider())
|
||||||
|
|
||||||
// Drawable icons for brightness and volume
|
// Drawable icons for brightness and volume
|
||||||
private val autoBrightnessIcon: Drawable = getDrawable("revanced_ic_sc_brightness_auto")
|
private val autoBrightnessIcon: Drawable = getDrawable("revanced_ic_sc_brightness_auto")
|
||||||
|
|||||||
@@ -3,4 +3,4 @@ org.gradle.jvmargs = -Xms512M -Xmx2048M
|
|||||||
org.gradle.parallel = true
|
org.gradle.parallel = true
|
||||||
android.useAndroidX = true
|
android.useAndroidX = true
|
||||||
kotlin.code.style = official
|
kotlin.code.style = official
|
||||||
version = 5.20.0-dev.2
|
version = 5.20.0-dev.7
|
||||||
|
|||||||
@@ -842,6 +842,10 @@ public final class app/revanced/patches/spotify/misc/extension/ExtensionPatchKt
|
|||||||
public static final fun getSharedExtensionPatch ()Lapp/revanced/patcher/patch/BytecodePatch;
|
public static final fun getSharedExtensionPatch ()Lapp/revanced/patcher/patch/BytecodePatch;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public final class app/revanced/patches/spotify/misc/fix/SpoofPackageInfoPatchKt {
|
||||||
|
public static final fun getSpoofPackageInfoPatch ()Lapp/revanced/patcher/patch/BytecodePatch;
|
||||||
|
}
|
||||||
|
|
||||||
public final class app/revanced/patches/spotify/misc/fix/SpoofSignaturePatchKt {
|
public final class app/revanced/patches/spotify/misc/fix/SpoofSignaturePatchKt {
|
||||||
public static final fun getSpoofSignaturePatch ()Lapp/revanced/patcher/patch/BytecodePatch;
|
public static final fun getSpoofSignaturePatch ()Lapp/revanced/patcher/patch/BytecodePatch;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -12,7 +12,8 @@ internal val initializeMonetizationDebugSettingsFingerprint = fingerprint {
|
|||||||
"Z", // useDebugBilling
|
"Z", // useDebugBilling
|
||||||
"Z", // showManageSubscriptions
|
"Z", // showManageSubscriptions
|
||||||
"Z", // alwaysShowSuperAds
|
"Z", // alwaysShowSuperAds
|
||||||
"Lcom/duolingo/debug/FamilyQuestOverride;",
|
// matches "Lcom/duolingo/debug/FamilyQuestOverride;" or "Lcom/duolingo/data/debug/monetization/FamilyQuestOverride;"
|
||||||
|
"Lcom/duolingo/",
|
||||||
)
|
)
|
||||||
opcodes(Opcode.IPUT_BOOLEAN)
|
opcodes(Opcode.IPUT_BOOLEAN)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ import app.revanced.util.findFreeRegister
|
|||||||
import app.revanced.util.findInstructionIndicesReversedOrThrow
|
import app.revanced.util.findInstructionIndicesReversedOrThrow
|
||||||
import app.revanced.util.getReference
|
import app.revanced.util.getReference
|
||||||
import app.revanced.util.indexOfFirstInstructionOrThrow
|
import app.revanced.util.indexOfFirstInstructionOrThrow
|
||||||
import app.revanced.util.insertFeatureFlagBooleanOverride
|
import app.revanced.util.insertLiteralOverride
|
||||||
import app.revanced.util.returnEarly
|
import app.revanced.util.returnEarly
|
||||||
import com.android.tools.smali.dexlib2.AccessFlags
|
import com.android.tools.smali.dexlib2.AccessFlags
|
||||||
import com.android.tools.smali.dexlib2.Opcode
|
import com.android.tools.smali.dexlib2.Opcode
|
||||||
@@ -235,7 +235,7 @@ fun spoofVideoStreamsPatch(
|
|||||||
|
|
||||||
// region Fix iOS livestream current time.
|
// region Fix iOS livestream current time.
|
||||||
|
|
||||||
hlsCurrentTimeFingerprint.method.insertFeatureFlagBooleanOverride(
|
hlsCurrentTimeFingerprint.method.insertLiteralOverride(
|
||||||
HLS_CURRENT_TIME_FEATURE_FLAG,
|
HLS_CURRENT_TIME_FEATURE_FLAG,
|
||||||
"$EXTENSION_CLASS_DESCRIPTOR->fixHLSCurrentTime(Z)Z"
|
"$EXTENSION_CLASS_DESCRIPTOR->fixHLSCurrentTime(Z)Z"
|
||||||
)
|
)
|
||||||
@@ -245,21 +245,21 @@ fun spoofVideoStreamsPatch(
|
|||||||
// region turn off stream config replacement feature flag.
|
// region turn off stream config replacement feature flag.
|
||||||
|
|
||||||
if (fixMediaFetchHotConfigChanges()) {
|
if (fixMediaFetchHotConfigChanges()) {
|
||||||
mediaFetchHotConfigFingerprint.method.insertFeatureFlagBooleanOverride(
|
mediaFetchHotConfigFingerprint.method.insertLiteralOverride(
|
||||||
MEDIA_FETCH_HOT_CONFIG_FEATURE_FLAG,
|
MEDIA_FETCH_HOT_CONFIG_FEATURE_FLAG,
|
||||||
"$EXTENSION_CLASS_DESCRIPTOR->useMediaFetchHotConfigReplacement(Z)Z"
|
"$EXTENSION_CLASS_DESCRIPTOR->useMediaFetchHotConfigReplacement(Z)Z"
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (fixMediaFetchHotConfigAlternativeChanges()) {
|
if (fixMediaFetchHotConfigAlternativeChanges()) {
|
||||||
mediaFetchHotConfigAlternativeFingerprint.method.insertFeatureFlagBooleanOverride(
|
mediaFetchHotConfigAlternativeFingerprint.method.insertLiteralOverride(
|
||||||
MEDIA_FETCH_HOT_CONFIG_ALTERNATIVE_FEATURE_FLAG,
|
MEDIA_FETCH_HOT_CONFIG_ALTERNATIVE_FEATURE_FLAG,
|
||||||
"$EXTENSION_CLASS_DESCRIPTOR->useMediaFetchHotConfigReplacement(Z)Z"
|
"$EXTENSION_CLASS_DESCRIPTOR->useMediaFetchHotConfigReplacement(Z)Z"
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (fixParsePlaybackResponseFeatureFlag()) {
|
if (fixParsePlaybackResponseFeatureFlag()) {
|
||||||
playbackStartDescriptorFeatureFlagFingerprint.method.insertFeatureFlagBooleanOverride(
|
playbackStartDescriptorFeatureFlagFingerprint.method.insertLiteralOverride(
|
||||||
PLAYBACK_START_CHECK_ENDPOINT_USED_FEATURE_FLAG,
|
PLAYBACK_START_CHECK_ENDPOINT_USED_FEATURE_FLAG,
|
||||||
"$EXTENSION_CLASS_DESCRIPTOR->usePlaybackStartFeatureFlag(Z)Z"
|
"$EXTENSION_CLASS_DESCRIPTOR->usePlaybackStartFeatureFlag(Z)Z"
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -2,4 +2,16 @@ package app.revanced.patches.spotify.misc.fix
|
|||||||
|
|
||||||
import app.revanced.patcher.fingerprint
|
import app.revanced.patcher.fingerprint
|
||||||
|
|
||||||
internal val getAppSignatureFingerprint = fingerprint { strings("Failed to get the application signatures") }
|
internal val getPackageInfoFingerprint = fingerprint {
|
||||||
|
strings(
|
||||||
|
"Failed to get the application signatures",
|
||||||
|
"Failed to get installer package"
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
internal val getPackageInfoLegacyFingerprint = fingerprint {
|
||||||
|
strings(
|
||||||
|
"Failed to get the application signatures"
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,72 @@
|
|||||||
|
package app.revanced.patches.spotify.misc.fix
|
||||||
|
|
||||||
|
import app.revanced.patcher.extensions.InstructionExtensions.getInstruction
|
||||||
|
import app.revanced.patcher.extensions.InstructionExtensions.replaceInstruction
|
||||||
|
import app.revanced.patcher.patch.bytecodePatch
|
||||||
|
import app.revanced.patches.spotify.misc.extension.IS_SPOTIFY_LEGACY_APP_TARGET
|
||||||
|
import app.revanced.util.addInstructionsAtControlFlowLabel
|
||||||
|
import app.revanced.util.indexOfFirstInstructionOrThrow
|
||||||
|
import app.revanced.util.indexOfFirstInstructionReversedOrThrow
|
||||||
|
import com.android.tools.smali.dexlib2.Opcode
|
||||||
|
import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction
|
||||||
|
|
||||||
|
@Suppress("unused")
|
||||||
|
val spoofPackageInfoPatch = bytecodePatch(
|
||||||
|
name = "Spoof package info",
|
||||||
|
description = "Spoofs the package info of the app to fix various functions of the app.",
|
||||||
|
) {
|
||||||
|
compatibleWith("com.spotify.music")
|
||||||
|
|
||||||
|
execute {
|
||||||
|
val getPackageInfoFingerprint = if (IS_SPOTIFY_LEGACY_APP_TARGET) {
|
||||||
|
getPackageInfoLegacyFingerprint
|
||||||
|
} else {
|
||||||
|
getPackageInfoFingerprint
|
||||||
|
}
|
||||||
|
|
||||||
|
getPackageInfoFingerprint.method.apply {
|
||||||
|
val stringMatches = getPackageInfoFingerprint.stringMatches!!
|
||||||
|
|
||||||
|
// region Spoof signature.
|
||||||
|
|
||||||
|
val failedToGetSignaturesStringIndex = stringMatches.first().index
|
||||||
|
|
||||||
|
val concatSignaturesIndex = indexOfFirstInstructionReversedOrThrow(
|
||||||
|
failedToGetSignaturesStringIndex,
|
||||||
|
Opcode.MOVE_RESULT_OBJECT,
|
||||||
|
)
|
||||||
|
|
||||||
|
val signatureRegister = getInstruction<OneRegisterInstruction>(concatSignaturesIndex).registerA
|
||||||
|
val expectedSignature = "d6a6dced4a85f24204bf9505ccc1fce114cadb32"
|
||||||
|
|
||||||
|
replaceInstruction(concatSignaturesIndex, "const-string v$signatureRegister, \"$expectedSignature\"")
|
||||||
|
|
||||||
|
// endregion
|
||||||
|
|
||||||
|
// region Spoof installer name.
|
||||||
|
|
||||||
|
if (IS_SPOTIFY_LEGACY_APP_TARGET) {
|
||||||
|
// Installer name is not used in the legacy app target.
|
||||||
|
return@execute
|
||||||
|
}
|
||||||
|
|
||||||
|
val expectedInstallerName = "com.android.vending"
|
||||||
|
|
||||||
|
val returnInstallerNameIndex = indexOfFirstInstructionOrThrow(
|
||||||
|
stringMatches.last().index,
|
||||||
|
Opcode.RETURN_OBJECT
|
||||||
|
)
|
||||||
|
|
||||||
|
val installerNameRegister = getInstruction<OneRegisterInstruction>(
|
||||||
|
returnInstallerNameIndex
|
||||||
|
).registerA
|
||||||
|
|
||||||
|
addInstructionsAtControlFlowLabel(
|
||||||
|
returnInstallerNameIndex,
|
||||||
|
"const-string v$installerNameRegister, \"$expectedInstallerName\""
|
||||||
|
)
|
||||||
|
|
||||||
|
// endregion
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,33 +1,13 @@
|
|||||||
package app.revanced.patches.spotify.misc.fix
|
package app.revanced.patches.spotify.misc.fix
|
||||||
|
|
||||||
import app.revanced.patcher.extensions.InstructionExtensions.getInstruction
|
|
||||||
import app.revanced.patcher.extensions.InstructionExtensions.replaceInstruction
|
|
||||||
import app.revanced.patcher.patch.bytecodePatch
|
import app.revanced.patcher.patch.bytecodePatch
|
||||||
import app.revanced.util.indexOfFirstInstructionReversedOrThrow
|
|
||||||
import com.android.tools.smali.dexlib2.Opcode
|
|
||||||
import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction
|
|
||||||
|
|
||||||
|
@Deprecated("Superseded by spoofPackageInfoPatch", ReplaceWith("spoofPackageInfoPatch"))
|
||||||
@Suppress("unused")
|
@Suppress("unused")
|
||||||
val spoofSignaturePatch = bytecodePatch(
|
val spoofSignaturePatch = bytecodePatch(
|
||||||
name = "Spoof signature",
|
description = "Spoofs the signature of the app fix various functions of the app.",
|
||||||
description = "Spoofs the signature of the app to fix various functions of the app.",
|
|
||||||
) {
|
) {
|
||||||
compatibleWith("com.spotify.music")
|
compatibleWith("com.spotify.music")
|
||||||
|
|
||||||
execute {
|
dependsOn(spoofPackageInfoPatch)
|
||||||
getAppSignatureFingerprint.method.apply {
|
|
||||||
val failedToGetSignaturesStringMatch = getAppSignatureFingerprint.stringMatches!!.first()
|
|
||||||
|
|
||||||
val concatSignaturesIndex = indexOfFirstInstructionReversedOrThrow(
|
|
||||||
failedToGetSignaturesStringMatch.index,
|
|
||||||
Opcode.MOVE_RESULT_OBJECT,
|
|
||||||
)
|
|
||||||
|
|
||||||
val register = getInstruction<OneRegisterInstruction>(concatSignaturesIndex).registerA
|
|
||||||
|
|
||||||
val expectedSignature = "d6a6dced4a85f24204bf9505ccc1fce114cadb32"
|
|
||||||
|
|
||||||
replaceInstruction(concatSignaturesIndex, "const-string v$register, \"$expectedSignature\"")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -47,6 +47,7 @@ private val swipeControlsResourcePatch = resourcePatch {
|
|||||||
TextPreference("revanced_swipe_overlay_background_opacity", inputType = InputType.NUMBER),
|
TextPreference("revanced_swipe_overlay_background_opacity", inputType = InputType.NUMBER),
|
||||||
TextPreference("revanced_swipe_overlay_timeout", inputType = InputType.NUMBER),
|
TextPreference("revanced_swipe_overlay_timeout", inputType = InputType.NUMBER),
|
||||||
TextPreference("revanced_swipe_threshold", inputType = InputType.NUMBER),
|
TextPreference("revanced_swipe_threshold", inputType = InputType.NUMBER),
|
||||||
|
TextPreference("revanced_swipe_volume_sensitivity", inputType = InputType.NUMBER),
|
||||||
)
|
)
|
||||||
|
|
||||||
copyResources(
|
copyResources(
|
||||||
@@ -117,7 +118,7 @@ val swipeControlsPatch = bytecodePatch(
|
|||||||
// region patch to enable/disable swipe to change video.
|
// region patch to enable/disable swipe to change video.
|
||||||
|
|
||||||
if (is_19_43_or_greater) {
|
if (is_19_43_or_greater) {
|
||||||
swipeChangeVideoFingerprint.method.insertFeatureFlagBooleanOverride(
|
swipeChangeVideoFingerprint.method.insertLiteralOverride(
|
||||||
SWIPE_CHANGE_VIDEO_FEATURE_FLAG,
|
SWIPE_CHANGE_VIDEO_FEATURE_FLAG,
|
||||||
"$EXTENSION_CLASS_DESCRIPTOR->allowSwipeChangeVideo(Z)Z"
|
"$EXTENSION_CLASS_DESCRIPTOR->allowSwipeChangeVideo(Z)Z"
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ import app.revanced.patches.youtube.misc.settings.PreferenceScreen
|
|||||||
import app.revanced.patches.youtube.misc.settings.settingsPatch
|
import app.revanced.patches.youtube.misc.settings.settingsPatch
|
||||||
import app.revanced.util.getReference
|
import app.revanced.util.getReference
|
||||||
import app.revanced.util.indexOfFirstInstructionOrThrow
|
import app.revanced.util.indexOfFirstInstructionOrThrow
|
||||||
import app.revanced.util.insertFeatureFlagBooleanOverride
|
import app.revanced.util.insertLiteralOverride
|
||||||
import com.android.tools.smali.dexlib2.iface.instruction.FiveRegisterInstruction
|
import com.android.tools.smali.dexlib2.iface.instruction.FiveRegisterInstruction
|
||||||
import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction
|
import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction
|
||||||
import com.android.tools.smali.dexlib2.iface.reference.MethodReference
|
import com.android.tools.smali.dexlib2.iface.reference.MethodReference
|
||||||
@@ -119,17 +119,17 @@ val navigationButtonsPatch = bytecodePatch(
|
|||||||
|
|
||||||
// Force on/off translucent effect on status bar and navigation buttons.
|
// Force on/off translucent effect on status bar and navigation buttons.
|
||||||
if (is_19_25_or_greater) {
|
if (is_19_25_or_greater) {
|
||||||
translucentNavigationStatusBarFeatureFlagFingerprint.method.insertFeatureFlagBooleanOverride(
|
translucentNavigationStatusBarFeatureFlagFingerprint.method.insertLiteralOverride(
|
||||||
TRANSLUCENT_NAVIGATION_STATUS_BAR_FEATURE_FLAG,
|
TRANSLUCENT_NAVIGATION_STATUS_BAR_FEATURE_FLAG,
|
||||||
"$EXTENSION_CLASS_DESCRIPTOR->useTranslucentNavigationStatusBar(Z)Z",
|
"$EXTENSION_CLASS_DESCRIPTOR->useTranslucentNavigationStatusBar(Z)Z",
|
||||||
)
|
)
|
||||||
|
|
||||||
translucentNavigationButtonsFeatureFlagFingerprint.method.insertFeatureFlagBooleanOverride(
|
translucentNavigationButtonsFeatureFlagFingerprint.method.insertLiteralOverride(
|
||||||
TRANSLUCENT_NAVIGATION_BUTTONS_FEATURE_FLAG,
|
TRANSLUCENT_NAVIGATION_BUTTONS_FEATURE_FLAG,
|
||||||
"$EXTENSION_CLASS_DESCRIPTOR->useTranslucentNavigationButtons(Z)Z",
|
"$EXTENSION_CLASS_DESCRIPTOR->useTranslucentNavigationButtons(Z)Z",
|
||||||
)
|
)
|
||||||
|
|
||||||
translucentNavigationButtonsSystemFeatureFlagFingerprint.method.insertFeatureFlagBooleanOverride(
|
translucentNavigationButtonsSystemFeatureFlagFingerprint.method.insertLiteralOverride(
|
||||||
TRANSLUCENT_NAVIGATION_BUTTONS_SYSTEM_FEATURE_FLAG,
|
TRANSLUCENT_NAVIGATION_BUTTONS_SYSTEM_FEATURE_FLAG,
|
||||||
"$EXTENSION_CLASS_DESCRIPTOR->useTranslucentNavigationButtons(Z)Z",
|
"$EXTENSION_CLASS_DESCRIPTOR->useTranslucentNavigationButtons(Z)Z",
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -278,7 +278,7 @@ val miniplayerPatch = bytecodePatch(
|
|||||||
fun Fingerprint.insertMiniplayerFeatureFlagBooleanOverride(
|
fun Fingerprint.insertMiniplayerFeatureFlagBooleanOverride(
|
||||||
literal: Long,
|
literal: Long,
|
||||||
extensionMethod: String,
|
extensionMethod: String,
|
||||||
) = method.insertFeatureFlagBooleanOverride(
|
) = method.insertLiteralOverride(
|
||||||
literal,
|
literal,
|
||||||
"$EXTENSION_CLASS_DESCRIPTOR->$extensionMethod(Z)Z"
|
"$EXTENSION_CLASS_DESCRIPTOR->$extensionMethod(Z)Z"
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ import app.revanced.patches.youtube.layout.shortsplayer.openShortsInRegularPlaye
|
|||||||
import app.revanced.patches.youtube.misc.extension.sharedExtensionPatch
|
import app.revanced.patches.youtube.misc.extension.sharedExtensionPatch
|
||||||
import app.revanced.patches.youtube.misc.playservice.is_19_46_or_greater
|
import app.revanced.patches.youtube.misc.playservice.is_19_46_or_greater
|
||||||
import app.revanced.patches.youtube.misc.playservice.versionCheckPatch
|
import app.revanced.patches.youtube.misc.playservice.versionCheckPatch
|
||||||
import app.revanced.util.insertFeatureFlagBooleanOverride
|
import app.revanced.util.insertLiteralOverride
|
||||||
|
|
||||||
internal const val EXTENSION_CLASS_DESCRIPTOR =
|
internal const val EXTENSION_CLASS_DESCRIPTOR =
|
||||||
"Lapp/revanced/extension/youtube/patches/OpenVideosFullscreenHookPatch;"
|
"Lapp/revanced/extension/youtube/patches/OpenVideosFullscreenHookPatch;"
|
||||||
@@ -24,7 +24,7 @@ internal val openVideosFullscreenHookPatch = bytecodePatch {
|
|||||||
return@execute
|
return@execute
|
||||||
}
|
}
|
||||||
|
|
||||||
openVideosFullscreenPortraitFingerprint.method.insertFeatureFlagBooleanOverride(
|
openVideosFullscreenPortraitFingerprint.method.insertLiteralOverride(
|
||||||
OPEN_VIDEOS_FULLSCREEN_PORTRAIT_FEATURE_FLAG,
|
OPEN_VIDEOS_FULLSCREEN_PORTRAIT_FEATURE_FLAG,
|
||||||
"$EXTENSION_CLASS_DESCRIPTOR->openVideoFullscreenPortrait(Z)Z"
|
"$EXTENSION_CLASS_DESCRIPTOR->openVideoFullscreenPortrait(Z)Z"
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -28,9 +28,8 @@ import app.revanced.util.findElementByAttributeValueOrThrow
|
|||||||
import app.revanced.util.findInstructionIndicesReversedOrThrow
|
import app.revanced.util.findInstructionIndicesReversedOrThrow
|
||||||
import app.revanced.util.getReference
|
import app.revanced.util.getReference
|
||||||
import app.revanced.util.indexOfFirstInstructionOrThrow
|
import app.revanced.util.indexOfFirstInstructionOrThrow
|
||||||
import app.revanced.util.indexOfFirstLiteralInstructionOrThrow
|
|
||||||
import app.revanced.util.inputStreamFromBundledResource
|
import app.revanced.util.inputStreamFromBundledResource
|
||||||
import app.revanced.util.insertFeatureFlagBooleanOverride
|
import app.revanced.util.insertLiteralOverride
|
||||||
import com.android.tools.smali.dexlib2.AccessFlags
|
import com.android.tools.smali.dexlib2.AccessFlags
|
||||||
import com.android.tools.smali.dexlib2.Opcode
|
import com.android.tools.smali.dexlib2.Opcode
|
||||||
import com.android.tools.smali.dexlib2.builder.MutableMethodImplementation
|
import com.android.tools.smali.dexlib2.builder.MutableMethodImplementation
|
||||||
@@ -229,16 +228,9 @@ val seekbarColorPatch = bytecodePatch(
|
|||||||
|
|
||||||
execute {
|
execute {
|
||||||
fun MutableMethod.addColorChangeInstructions(resourceId: Long) {
|
fun MutableMethod.addColorChangeInstructions(resourceId: Long) {
|
||||||
val index = indexOfFirstLiteralInstructionOrThrow(resourceId)
|
insertLiteralOverride(
|
||||||
val insertIndex = indexOfFirstInstructionOrThrow(index, Opcode.MOVE_RESULT)
|
resourceId,
|
||||||
val register = getInstruction<OneRegisterInstruction>(insertIndex).registerA
|
"$EXTENSION_CLASS_DESCRIPTOR->getVideoPlayerSeekbarColor(I)I"
|
||||||
|
|
||||||
addInstructions(
|
|
||||||
insertIndex + 1,
|
|
||||||
"""
|
|
||||||
invoke-static { v$register }, $EXTENSION_CLASS_DESCRIPTOR->getVideoPlayerSeekbarColor(I)I
|
|
||||||
move-result v$register
|
|
||||||
"""
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -354,7 +346,7 @@ val seekbarColorPatch = bytecodePatch(
|
|||||||
launchScreenLayoutTypeFingerprint,
|
launchScreenLayoutTypeFingerprint,
|
||||||
mainActivityOnCreateFingerprint
|
mainActivityOnCreateFingerprint
|
||||||
).forEach { fingerprint ->
|
).forEach { fingerprint ->
|
||||||
fingerprint.method.insertFeatureFlagBooleanOverride(
|
fingerprint.method.insertLiteralOverride(
|
||||||
launchScreenLayoutTypeLotteFeatureFlag,
|
launchScreenLayoutTypeLotteFeatureFlag,
|
||||||
"$EXTENSION_CLASS_DESCRIPTOR->useLotteLaunchSplashScreen(Z)Z"
|
"$EXTENSION_CLASS_DESCRIPTOR->useLotteLaunchSplashScreen(Z)Z"
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -21,7 +21,7 @@ import app.revanced.patches.youtube.misc.playservice.versionCheckPatch
|
|||||||
import app.revanced.patches.youtube.misc.settings.PreferenceScreen
|
import app.revanced.patches.youtube.misc.settings.PreferenceScreen
|
||||||
import app.revanced.patches.youtube.misc.settings.settingsPatch
|
import app.revanced.patches.youtube.misc.settings.settingsPatch
|
||||||
import app.revanced.util.forEachChildElement
|
import app.revanced.util.forEachChildElement
|
||||||
import app.revanced.util.insertFeatureFlagBooleanOverride
|
import app.revanced.util.insertLiteralOverride
|
||||||
import org.w3c.dom.Element
|
import org.w3c.dom.Element
|
||||||
|
|
||||||
private const val EXTENSION_CLASS_DESCRIPTOR =
|
private const val EXTENSION_CLASS_DESCRIPTOR =
|
||||||
@@ -233,7 +233,7 @@ val themePatch = bytecodePatch(
|
|||||||
SwitchPreference("revanced_gradient_loading_screen"),
|
SwitchPreference("revanced_gradient_loading_screen"),
|
||||||
)
|
)
|
||||||
|
|
||||||
useGradientLoadingScreenFingerprint.method.insertFeatureFlagBooleanOverride(
|
useGradientLoadingScreenFingerprint.method.insertLiteralOverride(
|
||||||
GRADIENT_LOADING_SCREEN_AB_CONSTANT,
|
GRADIENT_LOADING_SCREEN_AB_CONSTANT,
|
||||||
"$EXTENSION_CLASS_DESCRIPTOR->gradientLoadingScreenEnabled(Z)Z"
|
"$EXTENSION_CLASS_DESCRIPTOR->gradientLoadingScreenEnabled(Z)Z"
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -12,6 +12,8 @@ import app.revanced.patches.shared.misc.mapping.resourceMappings
|
|||||||
import app.revanced.patches.shared.misc.settings.preference.SwitchPreference
|
import app.revanced.patches.shared.misc.settings.preference.SwitchPreference
|
||||||
import app.revanced.patches.youtube.misc.extension.sharedExtensionPatch
|
import app.revanced.patches.youtube.misc.extension.sharedExtensionPatch
|
||||||
import app.revanced.patches.youtube.misc.playertype.playerTypeHookPatch
|
import app.revanced.patches.youtube.misc.playertype.playerTypeHookPatch
|
||||||
|
import app.revanced.patches.youtube.misc.playservice.is_19_34_or_greater
|
||||||
|
import app.revanced.patches.youtube.misc.playservice.versionCheckPatch
|
||||||
import app.revanced.patches.youtube.misc.settings.PreferenceScreen
|
import app.revanced.patches.youtube.misc.settings.PreferenceScreen
|
||||||
import app.revanced.patches.youtube.misc.settings.settingsPatch
|
import app.revanced.patches.youtube.misc.settings.settingsPatch
|
||||||
import app.revanced.patches.youtube.video.information.videoInformationPatch
|
import app.revanced.patches.youtube.video.information.videoInformationPatch
|
||||||
@@ -44,6 +46,7 @@ val backgroundPlaybackPatch = bytecodePatch(
|
|||||||
playerTypeHookPatch,
|
playerTypeHookPatch,
|
||||||
videoInformationPatch,
|
videoInformationPatch,
|
||||||
settingsPatch,
|
settingsPatch,
|
||||||
|
versionCheckPatch
|
||||||
)
|
)
|
||||||
|
|
||||||
compatibleWith(
|
compatibleWith(
|
||||||
@@ -100,5 +103,13 @@ val backgroundPlaybackPatch = bytecodePatch(
|
|||||||
|
|
||||||
// Force allowing background play for videos labeled for kids.
|
// Force allowing background play for videos labeled for kids.
|
||||||
kidsBackgroundPlaybackPolicyControllerFingerprint.method.returnEarly()
|
kidsBackgroundPlaybackPolicyControllerFingerprint.method.returnEarly()
|
||||||
|
|
||||||
|
// Fix PiP buttons not working after locking/unlocking device screen.
|
||||||
|
if (is_19_34_or_greater) {
|
||||||
|
pipInputConsumerFeatureFlagFingerprint.method.insertLiteralOverride(
|
||||||
|
PIP_INPUT_CONSUMER_FEATURE_FLAG,
|
||||||
|
false
|
||||||
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -84,3 +84,10 @@ internal val shortsBackgroundPlaybackFeatureFlagFingerprint = fingerprint {
|
|||||||
parameters()
|
parameters()
|
||||||
literal { 45415425 }
|
literal { 45415425 }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
internal const val PIP_INPUT_CONSUMER_FEATURE_FLAG = 45638483L
|
||||||
|
|
||||||
|
// Fix 'E/InputDispatcher: Window handle pip_input_consumer has no registered input channel'
|
||||||
|
internal val pipInputConsumerFeatureFlagFingerprint = fingerprint {
|
||||||
|
literal { PIP_INPUT_CONSUMER_FEATURE_FLAG}
|
||||||
|
}
|
||||||
@@ -269,7 +269,7 @@ val settingsPatch = bytecodePatch(
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Add setting to force cairo settings fragment on/off.
|
// Add setting to force cairo settings fragment on/off.
|
||||||
cairoFragmentConfigFingerprint.method.insertFeatureFlagBooleanOverride(
|
cairoFragmentConfigFingerprint.method.insertLiteralOverride(
|
||||||
CAIRO_CONFIG_LITERAL_VALUE,
|
CAIRO_CONFIG_LITERAL_VALUE,
|
||||||
"$activityHookClassDescriptor->useCairoSettingsFragment(Z)Z"
|
"$activityHookClassDescriptor->useCairoSettingsFragment(Z)Z"
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -636,7 +636,12 @@ fun Method.findInstructionIndicesReversedOrThrow(opcode: Opcode): List<Int> {
|
|||||||
return instructions
|
return instructions
|
||||||
}
|
}
|
||||||
|
|
||||||
internal fun MutableMethod.insertFeatureFlagBooleanOverride(literal: Long, extensionsMethod: String) {
|
/**
|
||||||
|
* Overrides the first move result with an extension call.
|
||||||
|
* Suitable for calls to extension code to override boolean and integer values.
|
||||||
|
*/
|
||||||
|
internal fun MutableMethod.insertLiteralOverride(literal: Long, extensionMethodDescriptor: String) {
|
||||||
|
// TODO: make this work with objects and wide values.
|
||||||
val literalIndex = indexOfFirstLiteralInstructionOrThrow(literal)
|
val literalIndex = indexOfFirstLiteralInstructionOrThrow(literal)
|
||||||
val index = indexOfFirstInstructionOrThrow(literalIndex, MOVE_RESULT)
|
val index = indexOfFirstInstructionOrThrow(literalIndex, MOVE_RESULT)
|
||||||
val register = getInstruction<OneRegisterInstruction>(index).registerA
|
val register = getInstruction<OneRegisterInstruction>(index).registerA
|
||||||
@@ -650,9 +655,24 @@ internal fun MutableMethod.insertFeatureFlagBooleanOverride(literal: Long, exten
|
|||||||
addInstructions(
|
addInstructions(
|
||||||
index + 1,
|
index + 1,
|
||||||
"""
|
"""
|
||||||
$operation, $extensionsMethod
|
$operation, $extensionMethodDescriptor
|
||||||
move-result v$register
|
move-result v$register
|
||||||
""",
|
"""
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Overrides a literal value result with a constant value.
|
||||||
|
*/
|
||||||
|
internal fun MutableMethod.insertLiteralOverride(literal: Long, override: Boolean) {
|
||||||
|
val literalIndex = indexOfFirstLiteralInstructionOrThrow(literal)
|
||||||
|
val index = indexOfFirstInstructionOrThrow(literalIndex, MOVE_RESULT)
|
||||||
|
val register = getInstruction<OneRegisterInstruction>(index).registerA
|
||||||
|
val overrideValue = if (override) "0x1" else "0x0"
|
||||||
|
|
||||||
|
addInstruction(
|
||||||
|
index + 1,
|
||||||
|
"const v$register, $overrideValue"
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -613,6 +613,9 @@ Bu seçimi dəyişdirmə işə düşmürsə, Gizli rejimə keçməyə çalışı
|
|||||||
<string name="revanced_hide_player_flyout_audio_track_summary_on">Səs axını menyusu gizlidir</string>
|
<string name="revanced_hide_player_flyout_audio_track_summary_on">Səs axını menyusu gizlidir</string>
|
||||||
<string name="revanced_hide_player_flyout_audio_track_summary_off">Səs axını menyusu göstərilir</string>
|
<string name="revanced_hide_player_flyout_audio_track_summary_off">Səs axını menyusu göstərilir</string>
|
||||||
<!-- 'Spoof video streams' should be the same translation used for revanced_spoof_video_streams_screen_title -->
|
<!-- 'Spoof video streams' should be the same translation used for revanced_spoof_video_streams_screen_title -->
|
||||||
|
<string name="revanced_hide_player_flyout_audio_track_not_available">"Audio trek seçimi gizlədilib
|
||||||
|
|
||||||
|
Audio trek seçimin göstərmək üçün \"Video axınları saxtalaşdır\"ı iOS TV-yə dəyiş"</string>
|
||||||
<!-- 'Watch in VR' should be translated using the same localized wording YouTube displays for the menu item. -->
|
<!-- 'Watch in VR' should be translated using the same localized wording YouTube displays for the menu item. -->
|
||||||
<string name="revanced_hide_player_flyout_watch_in_vr_title">\"VR-da İzləni\" gizlət</string>
|
<string name="revanced_hide_player_flyout_watch_in_vr_title">\"VR-da İzləni\" gizlət</string>
|
||||||
<string name="revanced_hide_player_flyout_watch_in_vr_summary_on">VR menyusunda izləmə gizlidir</string>
|
<string name="revanced_hide_player_flyout_watch_in_vr_summary_on">VR menyusunda izləmə gizlidir</string>
|
||||||
|
|||||||
@@ -613,6 +613,9 @@ Jos tämän asetuksen muuttaminen ei tule voimaan, kokeile vaihtaa Incognito-til
|
|||||||
<string name="revanced_hide_player_flyout_audio_track_summary_on">Ääniraitavalikko on piilotettu</string>
|
<string name="revanced_hide_player_flyout_audio_track_summary_on">Ääniraitavalikko on piilotettu</string>
|
||||||
<string name="revanced_hide_player_flyout_audio_track_summary_off">Ääniraitavalikko näytetään</string>
|
<string name="revanced_hide_player_flyout_audio_track_summary_off">Ääniraitavalikko näytetään</string>
|
||||||
<!-- 'Spoof video streams' should be the same translation used for revanced_spoof_video_streams_screen_title -->
|
<!-- 'Spoof video streams' should be the same translation used for revanced_spoof_video_streams_screen_title -->
|
||||||
|
<string name="revanced_hide_player_flyout_audio_track_not_available">"Ääniraitavalikko on piilotettu
|
||||||
|
|
||||||
|
Jos haluat nähdä sen, aseta \"Naamioi videovirrat\" iOS TV:ksi"</string>
|
||||||
<!-- 'Watch in VR' should be translated using the same localized wording YouTube displays for the menu item. -->
|
<!-- 'Watch in VR' should be translated using the same localized wording YouTube displays for the menu item. -->
|
||||||
<string name="revanced_hide_player_flyout_watch_in_vr_title">Piilota Katso VR-tilassa</string>
|
<string name="revanced_hide_player_flyout_watch_in_vr_title">Piilota Katso VR-tilassa</string>
|
||||||
<string name="revanced_hide_player_flyout_watch_in_vr_summary_on">Katso VR-tilassa -valinta on piilotettu</string>
|
<string name="revanced_hide_player_flyout_watch_in_vr_summary_on">Katso VR-tilassa -valinta on piilotettu</string>
|
||||||
|
|||||||
@@ -459,19 +459,19 @@ Second \"item\" text"</string>
|
|||||||
<string name="revanced_swipe_lowest_value_enable_auto_brightness_title">启用自动亮度手势</string>
|
<string name="revanced_swipe_lowest_value_enable_auto_brightness_title">启用自动亮度手势</string>
|
||||||
<string name="revanced_swipe_lowest_value_enable_auto_brightness_summary_on">滑动到最低亮度手势将启用自动亮度</string>
|
<string name="revanced_swipe_lowest_value_enable_auto_brightness_summary_on">滑动到最低亮度手势将启用自动亮度</string>
|
||||||
<string name="revanced_swipe_lowest_value_enable_auto_brightness_summary_off">滑动到最低亮度手势不启用自动亮度</string>
|
<string name="revanced_swipe_lowest_value_enable_auto_brightness_summary_off">滑动到最低亮度手势不启用自动亮度</string>
|
||||||
<string name="revanced_swipe_overlay_timeout_title">滑动覆盖超时</string>
|
<string name="revanced_swipe_overlay_timeout_title">滑动提示层显示时长</string>
|
||||||
<string name="revanced_swipe_overlay_timeout_summary">滑动叠加层显示的时长(毫秒)</string>
|
<string name="revanced_swipe_overlay_timeout_summary">滑动提示的显示时长(毫秒)</string>
|
||||||
<string name="revanced_swipe_overlay_background_opacity_title">滑动叠加层背景的不透明度</string>
|
<string name="revanced_swipe_overlay_background_opacity_title">滑动提示层背景的不透明度</string>
|
||||||
<string name="revanced_swipe_overlay_background_opacity_summary">不透明度值介于 0-100 之间</string>
|
<string name="revanced_swipe_overlay_background_opacity_summary">不透明度值介于 0-100 之间</string>
|
||||||
<string name="revanced_swipe_overlay_background_opacity_invalid_toast">滑动不透明度必须介于 0-100 之间</string>
|
<string name="revanced_swipe_overlay_background_opacity_invalid_toast">滑动不透明度必须介于 0-100 之间</string>
|
||||||
<string name="revanced_swipe_threshold_title">滑动幅度阈值</string>
|
<string name="revanced_swipe_threshold_title">滑动幅度阈值</string>
|
||||||
<string name="revanced_swipe_threshold_summary">防误触的滑动幅度阈值</string>
|
<string name="revanced_swipe_threshold_summary">防误触的滑动幅度阈值</string>
|
||||||
<string name="revanced_swipe_show_circular_overlay_title">显示圆形叠加层</string>
|
<string name="revanced_swipe_show_circular_overlay_title">圆形的叠加层样式</string>
|
||||||
<string name="revanced_swipe_show_circular_overlay_summary_on">圆形叠加层已显示</string>
|
<string name="revanced_swipe_show_circular_overlay_summary_on">提示层显示为圆形样式</string>
|
||||||
<string name="revanced_swipe_show_circular_overlay_summary_off">水平叠加层已显示</string>
|
<string name="revanced_swipe_show_circular_overlay_summary_off">提示层显示为水平样式</string>
|
||||||
<string name="revanced_swipe_overlay_minimal_style_title">启用极简样式</string>
|
<string name="revanced_swipe_overlay_minimal_style_title">极简提示样式</string>
|
||||||
<string name="revanced_swipe_overlay_minimal_style_summary_on">已启用极简叠加样式</string>
|
<string name="revanced_swipe_overlay_minimal_style_summary_on">极简样式已启用</string>
|
||||||
<string name="revanced_swipe_overlay_minimal_style_summary_off">已停用最小叠加层样式</string>
|
<string name="revanced_swipe_overlay_minimal_style_summary_off">极简样式已禁用</string>
|
||||||
<string name="revanced_swipe_change_video_title">启用滑动切换视频</string>
|
<string name="revanced_swipe_change_video_title">启用滑动切换视频</string>
|
||||||
<string name="revanced_swipe_change_video_summary_on">在全屏模式下滑动将切换到下一个/上一个视频</string>
|
<string name="revanced_swipe_change_video_summary_on">在全屏模式下滑动将切换到下一个/上一个视频</string>
|
||||||
<string name="revanced_swipe_change_video_summary_off">在全屏模式下滑动将不会切换到下一个/上一个视频</string>
|
<string name="revanced_swipe_change_video_summary_off">在全屏模式下滑动将不会切换到下一个/上一个视频</string>
|
||||||
@@ -882,9 +882,9 @@ Second \"item\" text"</string>
|
|||||||
<string name="revanced_sb_enable_voting">显示投票按钮</string>
|
<string name="revanced_sb_enable_voting">显示投票按钮</string>
|
||||||
<string name="revanced_sb_enable_voting_sum_on">显示片段投票按钮</string>
|
<string name="revanced_sb_enable_voting_sum_on">显示片段投票按钮</string>
|
||||||
<string name="revanced_sb_enable_voting_sum_off">不显示片段投票按钮</string>
|
<string name="revanced_sb_enable_voting_sum_off">不显示片段投票按钮</string>
|
||||||
<string name="revanced_sb_square_layout">使用方形布局</string>
|
<string name="revanced_sb_square_layout">使用方形控件</string>
|
||||||
<string name="revanced_sb_square_layout_sum_on">使用方形的按钮和控件</string>
|
<string name="revanced_sb_square_layout_sum_on">使用方形样式的按钮和控件</string>
|
||||||
<string name="revanced_sb_square_layout_sum_off">使用圆角的按钮和控件</string>
|
<string name="revanced_sb_square_layout_sum_off">使用圆角样式的按钮和控件</string>
|
||||||
<!-- Translations should use language similar to 'revanced_ryd_compact_layout_title' -->
|
<!-- Translations should use language similar to 'revanced_ryd_compact_layout_title' -->
|
||||||
<string name="revanced_sb_enable_compact_skip_button">使用紧凑的跳过按钮</string>
|
<string name="revanced_sb_enable_compact_skip_button">使用紧凑的跳过按钮</string>
|
||||||
<string name="revanced_sb_enable_compact_skip_button_sum_on">跳过按钮样式为最小宽度</string>
|
<string name="revanced_sb_enable_compact_skip_button_sum_on">跳过按钮样式为最小宽度</string>
|
||||||
|
|||||||
@@ -527,6 +527,8 @@ Adjust volume by swiping vertically on the right side of the screen"</string>
|
|||||||
<string name="revanced_swipe_overlay_background_opacity_invalid_toast">Swipe opacity must be between 0-100</string>
|
<string name="revanced_swipe_overlay_background_opacity_invalid_toast">Swipe opacity must be between 0-100</string>
|
||||||
<string name="revanced_swipe_threshold_title">Swipe magnitude threshold</string>
|
<string name="revanced_swipe_threshold_title">Swipe magnitude threshold</string>
|
||||||
<string name="revanced_swipe_threshold_summary">The amount of threshold for swipe to occur</string>
|
<string name="revanced_swipe_threshold_summary">The amount of threshold for swipe to occur</string>
|
||||||
|
<string name="revanced_swipe_volume_sensitivity_title">Volume swipe sensitivity</string>
|
||||||
|
<string name="revanced_swipe_volume_sensitivity_summary">How much the volume changes per swipe</string>
|
||||||
<string name="revanced_swipe_show_circular_overlay_title">Show circular overlay</string>
|
<string name="revanced_swipe_show_circular_overlay_title">Show circular overlay</string>
|
||||||
<string name="revanced_swipe_show_circular_overlay_summary_on">Circular overlay is shown</string>
|
<string name="revanced_swipe_show_circular_overlay_summary_on">Circular overlay is shown</string>
|
||||||
<string name="revanced_swipe_show_circular_overlay_summary_off">Horizontal overlay is shown</string>
|
<string name="revanced_swipe_show_circular_overlay_summary_off">Horizontal overlay is shown</string>
|
||||||
|
|||||||
Reference in New Issue
Block a user