mirror of
https://github.com/ReVanced/revanced-patches.git
synced 2026-01-21 18:03:56 +00:00
Compare commits
13 Commits
v5.47.0-de
...
v5.47.0-de
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
a0ec4c07f7 | ||
|
|
0928dcd00d | ||
|
|
bbd8932b2e | ||
|
|
300b12f948 | ||
|
|
ac583d40d0 | ||
|
|
c400188c38 | ||
|
|
0af0ee92c4 | ||
|
|
fff29544b9 | ||
|
|
9495cf49ef | ||
|
|
15675b5164 | ||
|
|
654d091e65 | ||
|
|
98371be33c | ||
|
|
2f0de15e67 |
43
CHANGELOG.md
43
CHANGELOG.md
@@ -1,3 +1,46 @@
|
|||||||
|
# [5.47.0-dev.8](https://github.com/ReVanced/revanced-patches/compare/v5.47.0-dev.7...v5.47.0-dev.8) (2025-12-08)
|
||||||
|
|
||||||
|
|
||||||
|
### Features
|
||||||
|
|
||||||
|
* **Instagram:** Add `Disable Reels scrolling` patch ([#6317](https://github.com/ReVanced/revanced-patches/issues/6317)) ([0928dcd](https://github.com/ReVanced/revanced-patches/commit/0928dcd00dc2a9c1eef9a23c1e26ff5dc9ee670a))
|
||||||
|
* **ProtonVPN:** Add `Remove delay` patch ([#6326](https://github.com/ReVanced/revanced-patches/issues/6326)) ([bbd8932](https://github.com/ReVanced/revanced-patches/commit/bbd8932b2e740aff96ba047332e541bff3e09436))
|
||||||
|
|
||||||
|
# [5.47.0-dev.7](https://github.com/ReVanced/revanced-patches/compare/v5.47.0-dev.6...v5.47.0-dev.7) (2025-12-03)
|
||||||
|
|
||||||
|
|
||||||
|
### Features
|
||||||
|
|
||||||
|
* **Spoof SIM provider:** Spoof additional TelephonyManager methods ([#6293](https://github.com/ReVanced/revanced-patches/issues/6293)) ([ac583d4](https://github.com/ReVanced/revanced-patches/commit/ac583d40d0f4c0e6544e3661ff3e82a25912f2b0))
|
||||||
|
|
||||||
|
# [5.47.0-dev.6](https://github.com/ReVanced/revanced-patches/compare/v5.47.0-dev.5...v5.47.0-dev.6) (2025-11-24)
|
||||||
|
|
||||||
|
|
||||||
|
### Features
|
||||||
|
|
||||||
|
* **Letterboxd:** Add `Hide ads` patch ([#6309](https://github.com/ReVanced/revanced-patches/issues/6309)) ([0af0ee9](https://github.com/ReVanced/revanced-patches/commit/0af0ee92c48bb2ffc332197e05439e20c5c05d83))
|
||||||
|
|
||||||
|
# [5.47.0-dev.5](https://github.com/ReVanced/revanced-patches/compare/v5.47.0-dev.4...v5.47.0-dev.5) (2025-11-13)
|
||||||
|
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* **YouTube - Hide player flyout menu items:** Allow hiding audio menu with 'Android No SDK' client type ([9495cf4](https://github.com/ReVanced/revanced-patches/commit/9495cf49ef8a872be64de6c971c1919b4b9a8720))
|
||||||
|
|
||||||
|
# [5.47.0-dev.4](https://github.com/ReVanced/revanced-patches/compare/v5.47.0-dev.3...v5.47.0-dev.4) (2025-11-12)
|
||||||
|
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* **YouTube - Sanitize sharing links:** Handle non hierarchical urls ([654d091](https://github.com/ReVanced/revanced-patches/commit/654d091e650cda37650b57cbf3ba6f1cdd6d47d3))
|
||||||
|
|
||||||
|
# [5.47.0-dev.3](https://github.com/ReVanced/revanced-patches/compare/v5.47.0-dev.2...v5.47.0-dev.3) (2025-11-12)
|
||||||
|
|
||||||
|
|
||||||
|
### Features
|
||||||
|
|
||||||
|
* **Instagram:** Add `Disable auto story flipping` patch ([#6262](https://github.com/ReVanced/revanced-patches/issues/6262)) ([2f0de15](https://github.com/ReVanced/revanced-patches/commit/2f0de15e67e4f99ed6ecdc136d04cceb23b0d069))
|
||||||
|
|
||||||
# [5.47.0-dev.2](https://github.com/ReVanced/revanced-patches/compare/v5.47.0-dev.1...v5.47.0-dev.2) (2025-11-12)
|
# [5.47.0-dev.2](https://github.com/ReVanced/revanced-patches/compare/v5.47.0-dev.1...v5.47.0-dev.2) (2025-11-12)
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -35,6 +35,15 @@ public class LinkSanitizer {
|
|||||||
|
|
||||||
public Uri sanitizeUri(Uri uri) {
|
public Uri sanitizeUri(Uri uri) {
|
||||||
try {
|
try {
|
||||||
|
String scheme = uri.getScheme();
|
||||||
|
if (scheme == null || !(scheme.equals("http") || scheme.equals("https"))) {
|
||||||
|
// Opening YouTube share sheet 'other' option passes the video title as a URI.
|
||||||
|
// Checking !uri.isHierarchical() works for all cases, except if the
|
||||||
|
// video title starts with / and then it's hierarchical but still an invalid URI.
|
||||||
|
Logger.printDebug(() -> "Ignoring uri: " + uri);
|
||||||
|
return uri;
|
||||||
|
}
|
||||||
|
|
||||||
Uri.Builder builder = uri.buildUpon().clearQuery();
|
Uri.Builder builder = uri.buildUpon().clearQuery();
|
||||||
|
|
||||||
if (!parametersToRemove.isEmpty()) {
|
if (!parametersToRemove.isEmpty()) {
|
||||||
|
|||||||
@@ -72,7 +72,7 @@ public class SpoofVideoStreamsPatch {
|
|||||||
public static boolean spoofingToClientWithNoMultiAudioStreams() {
|
public static boolean spoofingToClientWithNoMultiAudioStreams() {
|
||||||
return isPatchIncluded()
|
return isPatchIncluded()
|
||||||
&& SPOOF_STREAMING_DATA
|
&& SPOOF_STREAMING_DATA
|
||||||
&& preferredClient != ClientType.IPADOS;
|
&& !preferredClient.supportsMultiAudioTracks;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -21,13 +21,14 @@ import app.revanced.extension.youtube.shared.PlayerType;
|
|||||||
|
|
||||||
@SuppressWarnings("unused")
|
@SuppressWarnings("unused")
|
||||||
public final class LayoutComponentsFilter extends Filter {
|
public final class LayoutComponentsFilter extends Filter {
|
||||||
private static final StringTrieSearch mixPlaylistsExceptions = new StringTrieSearch(
|
private static final StringTrieSearch mixPlaylistsContextExceptions = new StringTrieSearch(
|
||||||
"V.ED", // Playlist browse id.
|
"V.ED", // Playlist browse id.
|
||||||
"java.lang.ref.WeakReference"
|
"java.lang.ref.WeakReference"
|
||||||
);
|
);
|
||||||
private static final ByteArrayFilterGroup mixPlaylistsExceptions2 = new ByteArrayFilterGroup(
|
private static final ByteArrayFilterGroup mixPlaylistsBufferExceptions = new ByteArrayFilterGroup(
|
||||||
null,
|
null,
|
||||||
"cell_description_body"
|
"cell_description_body",
|
||||||
|
"channel_profile"
|
||||||
);
|
);
|
||||||
private static final ByteArrayFilterGroup mixPlaylists = new ByteArrayFilterGroup(
|
private static final ByteArrayFilterGroup mixPlaylists = new ByteArrayFilterGroup(
|
||||||
null,
|
null,
|
||||||
@@ -380,17 +381,15 @@ public final class LayoutComponentsFilter extends Filter {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Prevent playlist items being hidden, if a mix playlist is present in it.
|
if (mixPlaylists.check(bytes).isFiltered()
|
||||||
if (mixPlaylistsExceptions.matches(conversionContext.toString())) {
|
// Prevent hiding the description of some videos accidentally.
|
||||||
return false;
|
&& !mixPlaylistsBufferExceptions.check(bytes).isFiltered()
|
||||||
}
|
// Prevent playlist items being hidden, if a mix playlist is present in it.
|
||||||
|
// Check last since it requires creating a context string.
|
||||||
// Prevent hiding the description of some videos accidentally.
|
//
|
||||||
if (mixPlaylistsExceptions2.check(bytes).isFiltered()) {
|
// FIXME: The conversion context passed in does not always generate a valid toString.
|
||||||
return false;
|
// This string check may no longer be needed, or the patch may be broken.
|
||||||
}
|
&& !mixPlaylistsContextExceptions.matches(conversionContext.toString())) {
|
||||||
|
|
||||||
if (mixPlaylists.check(bytes).isFiltered()) {
|
|
||||||
Logger.printDebug(() -> "Filtered mix playlist");
|
Logger.printDebug(() -> "Filtered mix playlist");
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -12,13 +12,9 @@ import java.util.List;
|
|||||||
public class PlayerFlyoutMenuItemsFilter extends Filter {
|
public class PlayerFlyoutMenuItemsFilter extends Filter {
|
||||||
|
|
||||||
public static final class HideAudioFlyoutMenuAvailability implements Setting.Availability {
|
public static final class HideAudioFlyoutMenuAvailability implements Setting.Availability {
|
||||||
private static final boolean AVAILABLE_ON_LAUNCH = !SpoofVideoStreamsPatch.spoofingToClientWithNoMultiAudioStreams();
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isAvailable() {
|
public boolean isAvailable() {
|
||||||
// Check conditions of launch and now. Otherwise if spoofing is changed
|
return !SpoofVideoStreamsPatch.spoofingToClientWithNoMultiAudioStreams();
|
||||||
// without a restart the setting will show as available when it's not.
|
|
||||||
return AVAILABLE_ON_LAUNCH && !SpoofVideoStreamsPatch.spoofingToClientWithNoMultiAudioStreams();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -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.47.0-dev.2
|
version = 5.47.0-dev.8
|
||||||
|
|||||||
@@ -1,3 +1,7 @@
|
|||||||
|
public final class DisableReelsScrollingPatchKt {
|
||||||
|
public static final fun getDisableReelsScrollingPatch ()Lapp/revanced/patcher/patch/BytecodePatch;
|
||||||
|
}
|
||||||
|
|
||||||
public final class app/revanced/patches/all/misc/activity/exportall/ExportAllActivitiesPatchKt {
|
public final class app/revanced/patches/all/misc/activity/exportall/ExportAllActivitiesPatchKt {
|
||||||
public static final fun getExportAllActivitiesPatch ()Lapp/revanced/patcher/patch/ResourcePatch;
|
public static final fun getExportAllActivitiesPatch ()Lapp/revanced/patcher/patch/ResourcePatch;
|
||||||
}
|
}
|
||||||
@@ -56,6 +60,10 @@ public final class app/revanced/patches/all/misc/connectivity/telephony/sim/spoo
|
|||||||
public static final fun getSpoofSimCountryPatch ()Lapp/revanced/patcher/patch/BytecodePatch;
|
public static final fun getSpoofSimCountryPatch ()Lapp/revanced/patcher/patch/BytecodePatch;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public final class app/revanced/patches/all/misc/connectivity/telephony/sim/spoof/SpoofSimProviderPatchKt {
|
||||||
|
public static final fun getSpoofSimProviderPatch ()Lapp/revanced/patcher/patch/BytecodePatch;
|
||||||
|
}
|
||||||
|
|
||||||
public final class app/revanced/patches/all/misc/connectivity/wifi/spoof/SpoofWifiPatchKt {
|
public final class app/revanced/patches/all/misc/connectivity/wifi/spoof/SpoofWifiPatchKt {
|
||||||
public static final fun getSpoofWifiPatch ()Lapp/revanced/patcher/patch/BytecodePatch;
|
public static final fun getSpoofWifiPatch ()Lapp/revanced/patcher/patch/BytecodePatch;
|
||||||
}
|
}
|
||||||
@@ -320,10 +328,18 @@ public final class app/revanced/patches/instagram/misc/signature/SignatureCheckP
|
|||||||
public static final fun getSignatureCheckPatch ()Lapp/revanced/patcher/patch/BytecodePatch;
|
public static final fun getSignatureCheckPatch ()Lapp/revanced/patcher/patch/BytecodePatch;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public final class app/revanced/patches/instagram/story/flipping/DisableStoryAutoFlippingPatchKt {
|
||||||
|
public static final fun getDisableStoryAutoFlippingPatch ()Lapp/revanced/patcher/patch/BytecodePatch;
|
||||||
|
}
|
||||||
|
|
||||||
public final class app/revanced/patches/irplus/ad/RemoveAdsPatchKt {
|
public final class app/revanced/patches/irplus/ad/RemoveAdsPatchKt {
|
||||||
public static final fun getRemoveAdsPatch ()Lapp/revanced/patcher/patch/BytecodePatch;
|
public static final fun getRemoveAdsPatch ()Lapp/revanced/patcher/patch/BytecodePatch;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public final class app/revanced/patches/letterboxd/ads/HideAdsPatchKt {
|
||||||
|
public static final fun getHideAdsPatch ()Lapp/revanced/patcher/patch/BytecodePatch;
|
||||||
|
}
|
||||||
|
|
||||||
public final class app/revanced/patches/lightroom/misc/login/DisableMandatoryLoginPatchKt {
|
public final class app/revanced/patches/lightroom/misc/login/DisableMandatoryLoginPatchKt {
|
||||||
public static final fun getDisableMandatoryLoginPatch ()Lapp/revanced/patcher/patch/BytecodePatch;
|
public static final fun getDisableMandatoryLoginPatch ()Lapp/revanced/patcher/patch/BytecodePatch;
|
||||||
}
|
}
|
||||||
@@ -609,6 +625,10 @@ public final class app/revanced/patches/protonmail/signature/RemoveSentFromSigna
|
|||||||
public static final fun getRemoveSentFromSignaturePatch ()Lapp/revanced/patcher/patch/ResourcePatch;
|
public static final fun getRemoveSentFromSignaturePatch ()Lapp/revanced/patcher/patch/ResourcePatch;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public final class app/revanced/patches/protonvpn/delay/RemoveDelayPatchKt {
|
||||||
|
public static final fun getRemoveDelayPatch ()Lapp/revanced/patcher/patch/BytecodePatch;
|
||||||
|
}
|
||||||
|
|
||||||
public final class app/revanced/patches/rar/misc/annoyances/purchasereminder/HidePurchaseReminderPatchKt {
|
public final class app/revanced/patches/rar/misc/annoyances/purchasereminder/HidePurchaseReminderPatchKt {
|
||||||
public static final fun getHidePurchaseReminderPatch ()Lapp/revanced/patcher/patch/BytecodePatch;
|
public static final fun getHidePurchaseReminderPatch ()Lapp/revanced/patcher/patch/BytecodePatch;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,105 +1,9 @@
|
|||||||
package app.revanced.patches.all.misc.connectivity.telephony.sim.spoof
|
package app.revanced.patches.all.misc.connectivity.telephony.sim.spoof
|
||||||
|
|
||||||
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.patcher.patch.stringOption
|
|
||||||
import app.revanced.patcher.util.proxy.mutableTypes.MutableMethod
|
|
||||||
import app.revanced.patches.all.misc.transformation.transformInstructionsPatch
|
|
||||||
import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction
|
|
||||||
import com.android.tools.smali.dexlib2.iface.instruction.ReferenceInstruction
|
|
||||||
import com.android.tools.smali.dexlib2.iface.reference.MethodReference
|
|
||||||
import com.android.tools.smali.dexlib2.immutable.reference.ImmutableMethodReference
|
|
||||||
import com.android.tools.smali.dexlib2.util.MethodUtil
|
|
||||||
import java.util.*
|
|
||||||
|
|
||||||
|
@Deprecated("Patch was renamed", ReplaceWith("spoofSimProviderPatch"))
|
||||||
@Suppress("unused")
|
@Suppress("unused")
|
||||||
val spoofSimCountryPatch = bytecodePatch(
|
val spoofSimCountryPatch = bytecodePatch {
|
||||||
name = "Spoof SIM country",
|
dependsOn(spoofSimProviderPatch)
|
||||||
description = "Spoofs country information returned by the SIM card provider.",
|
|
||||||
use = false,
|
|
||||||
) {
|
|
||||||
val countries = Locale.getISOCountries().associateBy { Locale("", it).displayCountry }
|
|
||||||
|
|
||||||
fun isoCountryPatchOption(
|
|
||||||
key: String,
|
|
||||||
title: String,
|
|
||||||
) = stringOption(
|
|
||||||
key,
|
|
||||||
null,
|
|
||||||
countries,
|
|
||||||
title,
|
|
||||||
"ISO-3166-1 alpha-2 country code equivalent for the SIM provider's country code.",
|
|
||||||
false,
|
|
||||||
validator = { it: String? -> it == null || it.uppercase() in countries.values },
|
|
||||||
)
|
|
||||||
|
|
||||||
val networkCountryIso by isoCountryPatchOption(
|
|
||||||
"networkCountryIso",
|
|
||||||
"Network ISO country code",
|
|
||||||
)
|
|
||||||
|
|
||||||
val simCountryIso by isoCountryPatchOption(
|
|
||||||
"simCountryIso",
|
|
||||||
"SIM ISO country code",
|
|
||||||
)
|
|
||||||
|
|
||||||
dependsOn(
|
|
||||||
transformInstructionsPatch(
|
|
||||||
filterMap = { _, _, instruction, instructionIndex ->
|
|
||||||
if (instruction !is ReferenceInstruction) return@transformInstructionsPatch null
|
|
||||||
|
|
||||||
val reference = instruction.reference as? MethodReference ?: return@transformInstructionsPatch null
|
|
||||||
|
|
||||||
val match = MethodCall.entries.firstOrNull { search ->
|
|
||||||
MethodUtil.methodSignaturesMatch(reference, search.reference)
|
|
||||||
} ?: return@transformInstructionsPatch null
|
|
||||||
|
|
||||||
val iso = when (match) {
|
|
||||||
MethodCall.NetworkCountryIso -> networkCountryIso
|
|
||||||
MethodCall.SimCountryIso -> simCountryIso
|
|
||||||
}?.lowercase()
|
|
||||||
|
|
||||||
iso?.let { instructionIndex to it }
|
|
||||||
},
|
|
||||||
transform = { mutableMethod, entry: Pair<Int, String> ->
|
|
||||||
transformMethodCall(entry, mutableMethod)
|
|
||||||
},
|
|
||||||
),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun transformMethodCall(
|
|
||||||
entry: Pair<Int, String>,
|
|
||||||
mutableMethod: MutableMethod,
|
|
||||||
) {
|
|
||||||
val (instructionIndex, methodCallValue) = entry
|
|
||||||
|
|
||||||
val register = mutableMethod.getInstruction<OneRegisterInstruction>(instructionIndex + 1).registerA
|
|
||||||
|
|
||||||
mutableMethod.replaceInstruction(
|
|
||||||
instructionIndex + 1,
|
|
||||||
"const-string v$register, \"$methodCallValue\"",
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
private enum class MethodCall(
|
|
||||||
val reference: MethodReference,
|
|
||||||
) {
|
|
||||||
NetworkCountryIso(
|
|
||||||
ImmutableMethodReference(
|
|
||||||
"Landroid/telephony/TelephonyManager;",
|
|
||||||
"getNetworkCountryIso",
|
|
||||||
emptyList(),
|
|
||||||
"Ljava/lang/String;",
|
|
||||||
),
|
|
||||||
),
|
|
||||||
SimCountryIso(
|
|
||||||
ImmutableMethodReference(
|
|
||||||
"Landroid/telephony/TelephonyManager;",
|
|
||||||
"getSimCountryIso",
|
|
||||||
emptyList(),
|
|
||||||
"Ljava/lang/String;",
|
|
||||||
),
|
|
||||||
),
|
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,169 @@
|
|||||||
|
package app.revanced.patches.all.misc.connectivity.telephony.sim.spoof
|
||||||
|
|
||||||
|
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.intOption
|
||||||
|
import app.revanced.patcher.patch.stringOption
|
||||||
|
import app.revanced.patcher.util.proxy.mutableTypes.MutableMethod
|
||||||
|
import app.revanced.patches.all.misc.transformation.transformInstructionsPatch
|
||||||
|
import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction
|
||||||
|
import com.android.tools.smali.dexlib2.iface.instruction.ReferenceInstruction
|
||||||
|
import com.android.tools.smali.dexlib2.iface.reference.MethodReference
|
||||||
|
import com.android.tools.smali.dexlib2.immutable.reference.ImmutableMethodReference
|
||||||
|
import com.android.tools.smali.dexlib2.util.MethodUtil
|
||||||
|
import java.util.Locale
|
||||||
|
|
||||||
|
@Suppress("unused")
|
||||||
|
val spoofSimProviderPatch = bytecodePatch(
|
||||||
|
name = "Spoof SIM provider",
|
||||||
|
description = "Spoofs information about the SIM card provider.",
|
||||||
|
use = false,
|
||||||
|
) {
|
||||||
|
val countries = Locale.getISOCountries().associateBy { Locale("", it).displayCountry }
|
||||||
|
|
||||||
|
fun isoCountryPatchOption(
|
||||||
|
key: String,
|
||||||
|
title: String,
|
||||||
|
) = stringOption(
|
||||||
|
key,
|
||||||
|
null,
|
||||||
|
countries,
|
||||||
|
title,
|
||||||
|
"ISO-3166-1 alpha-2 country code equivalent for the SIM provider's country code.",
|
||||||
|
false,
|
||||||
|
validator = { it: String? -> it == null || it.uppercase() in countries.values },
|
||||||
|
)
|
||||||
|
|
||||||
|
fun isMccMncValid(it: Int?): Boolean = it == null || (it >= 10000 && it <= 999999)
|
||||||
|
|
||||||
|
val networkCountryIso by isoCountryPatchOption(
|
||||||
|
"networkCountryIso",
|
||||||
|
"Network ISO country code",
|
||||||
|
)
|
||||||
|
|
||||||
|
val networkOperator by intOption(
|
||||||
|
key = "networkOperator",
|
||||||
|
title = "MCC+MNC network operator code",
|
||||||
|
description = "The 5 or 6 digits MCC+MNC (Mobile Country Code + Mobile Network Code) of the network operator.",
|
||||||
|
validator = { isMccMncValid(it) }
|
||||||
|
)
|
||||||
|
|
||||||
|
val networkOperatorName by stringOption(
|
||||||
|
key = "networkOperatorName",
|
||||||
|
title = "Network operator name",
|
||||||
|
description = "The full name of the network operator.",
|
||||||
|
)
|
||||||
|
|
||||||
|
val simCountryIso by isoCountryPatchOption(
|
||||||
|
"simCountryIso",
|
||||||
|
"SIM ISO country code",
|
||||||
|
)
|
||||||
|
|
||||||
|
val simOperator by intOption(
|
||||||
|
key = "simOperator",
|
||||||
|
title = "MCC+MNC SIM operator code",
|
||||||
|
description = "The 5 or 6 digits MCC+MNC (Mobile Country Code + Mobile Network Code) of the SIM operator.",
|
||||||
|
validator = { isMccMncValid(it) }
|
||||||
|
)
|
||||||
|
|
||||||
|
val simOperatorName by stringOption(
|
||||||
|
key = "simOperatorName",
|
||||||
|
title = "SIM operator name",
|
||||||
|
description = "The full name of the SIM operator.",
|
||||||
|
)
|
||||||
|
|
||||||
|
dependsOn(
|
||||||
|
transformInstructionsPatch(
|
||||||
|
filterMap = { _, _, instruction, instructionIndex ->
|
||||||
|
if (instruction !is ReferenceInstruction) return@transformInstructionsPatch null
|
||||||
|
|
||||||
|
val reference = instruction.reference as? MethodReference ?: return@transformInstructionsPatch null
|
||||||
|
|
||||||
|
val match = MethodCall.entries.firstOrNull { search ->
|
||||||
|
MethodUtil.methodSignaturesMatch(reference, search.reference)
|
||||||
|
} ?: return@transformInstructionsPatch null
|
||||||
|
|
||||||
|
val replacement = when (match) {
|
||||||
|
MethodCall.NetworkCountryIso -> networkCountryIso?.lowercase()
|
||||||
|
MethodCall.NetworkOperator -> networkOperator?.toString()
|
||||||
|
MethodCall.NetworkOperatorName -> networkOperatorName
|
||||||
|
MethodCall.SimCountryIso -> simCountryIso?.lowercase()
|
||||||
|
MethodCall.SimOperator -> simOperator?.toString()
|
||||||
|
MethodCall.SimOperatorName -> simOperatorName
|
||||||
|
}
|
||||||
|
replacement?.let { instructionIndex to it }
|
||||||
|
},
|
||||||
|
transform = ::transformMethodCall,
|
||||||
|
),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun transformMethodCall(
|
||||||
|
mutableMethod: MutableMethod,
|
||||||
|
entry: Pair<Int, String>,
|
||||||
|
) {
|
||||||
|
val (instructionIndex, methodCallValue) = entry
|
||||||
|
|
||||||
|
// Get the register which would have contained the return value
|
||||||
|
val register = mutableMethod.getInstruction<OneRegisterInstruction>(instructionIndex + 1).registerA
|
||||||
|
|
||||||
|
// Replace the move-result instruction with our fake value
|
||||||
|
mutableMethod.replaceInstruction(
|
||||||
|
instructionIndex + 1,
|
||||||
|
"const-string v$register, \"$methodCallValue\"",
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
private enum class MethodCall(
|
||||||
|
val reference: MethodReference,
|
||||||
|
) {
|
||||||
|
NetworkCountryIso(
|
||||||
|
ImmutableMethodReference(
|
||||||
|
"Landroid/telephony/TelephonyManager;",
|
||||||
|
"getNetworkCountryIso",
|
||||||
|
emptyList(),
|
||||||
|
"Ljava/lang/String;",
|
||||||
|
),
|
||||||
|
),
|
||||||
|
NetworkOperator(
|
||||||
|
ImmutableMethodReference(
|
||||||
|
"Landroid/telephony/TelephonyManager;",
|
||||||
|
"getNetworkOperator",
|
||||||
|
emptyList(),
|
||||||
|
"Ljava/lang/String;",
|
||||||
|
),
|
||||||
|
),
|
||||||
|
NetworkOperatorName(
|
||||||
|
ImmutableMethodReference(
|
||||||
|
"Landroid/telephony/TelephonyManager;",
|
||||||
|
"getNetworkOperatorName",
|
||||||
|
emptyList(),
|
||||||
|
"Ljava/lang/String;",
|
||||||
|
),
|
||||||
|
),
|
||||||
|
SimCountryIso(
|
||||||
|
ImmutableMethodReference(
|
||||||
|
"Landroid/telephony/TelephonyManager;",
|
||||||
|
"getSimCountryIso",
|
||||||
|
emptyList(),
|
||||||
|
"Ljava/lang/String;",
|
||||||
|
),
|
||||||
|
),
|
||||||
|
SimOperator(
|
||||||
|
ImmutableMethodReference(
|
||||||
|
"Landroid/telephony/TelephonyManager;",
|
||||||
|
"getSimOperator",
|
||||||
|
emptyList(),
|
||||||
|
"Ljava/lang/String;",
|
||||||
|
),
|
||||||
|
),
|
||||||
|
SimOperatorName(
|
||||||
|
ImmutableMethodReference(
|
||||||
|
"Landroid/telephony/TelephonyManager;",
|
||||||
|
"getSimOperatorName",
|
||||||
|
emptyList(),
|
||||||
|
"Ljava/lang/String;",
|
||||||
|
),
|
||||||
|
),
|
||||||
|
}
|
||||||
@@ -0,0 +1,34 @@
|
|||||||
|
import app.revanced.patcher.extensions.InstructionExtensions.addInstructions
|
||||||
|
import app.revanced.patcher.patch.bytecodePatch
|
||||||
|
import app.revanced.patches.instagram.reels.clipsSwipeRefreshLayoutOnInterceptTouchEventFingerprint
|
||||||
|
import app.revanced.patches.instagram.reels.clipsViewPagerImplGetViewAtIndexFingerprint
|
||||||
|
import app.revanced.util.returnEarly
|
||||||
|
|
||||||
|
@Suppress("unused")
|
||||||
|
val disableReelsScrollingPatch = bytecodePatch(
|
||||||
|
name = "Disable Reels scrolling",
|
||||||
|
description = "Disables the endless scrolling behavior in Instagram Reels, preventing swiping to the next Reel. " +
|
||||||
|
"Note: On a clean install, the 'Tip' animation may appear but will stop on its own after a few seconds.",
|
||||||
|
use = true
|
||||||
|
) {
|
||||||
|
compatibleWith("com.instagram.android")
|
||||||
|
|
||||||
|
execute {
|
||||||
|
val viewPagerField = clipsViewPagerImplGetViewAtIndexFingerprint.classDef.fields.first {
|
||||||
|
it.type == "Landroidx/viewpager2/widget/ViewPager2;"
|
||||||
|
}
|
||||||
|
|
||||||
|
// Disable user input on the ViewPager2 to prevent scrolling.
|
||||||
|
clipsViewPagerImplGetViewAtIndexFingerprint.method.addInstructions(
|
||||||
|
0,
|
||||||
|
"""
|
||||||
|
iget-object v0, p0, $viewPagerField
|
||||||
|
const/4 v1, 0x0
|
||||||
|
invoke-virtual { v0, v1 }, Landroidx/viewpager2/widget/ViewPager2;->setUserInputEnabled(Z)V
|
||||||
|
"""
|
||||||
|
)
|
||||||
|
|
||||||
|
// Return false in onInterceptTouchEvent to disable pull-to-refresh.
|
||||||
|
clipsSwipeRefreshLayoutOnInterceptTouchEventFingerprint.method.returnEarly(false)
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,13 @@
|
|||||||
|
package app.revanced.patches.instagram.reels
|
||||||
|
|
||||||
|
import app.revanced.patcher.fingerprint
|
||||||
|
|
||||||
|
internal val clipsViewPagerImplGetViewAtIndexFingerprint = fingerprint {
|
||||||
|
strings("ClipsViewPagerImpl_getViewAtIndex")
|
||||||
|
}
|
||||||
|
|
||||||
|
internal val clipsSwipeRefreshLayoutOnInterceptTouchEventFingerprint = fingerprint {
|
||||||
|
parameters("Landroid/view/MotionEvent;")
|
||||||
|
custom { _, classDef -> classDef.type == "Linstagram/features/clips/viewer/ui/ClipsSwipeRefreshLayout;" }
|
||||||
|
}
|
||||||
|
|
||||||
@@ -0,0 +1,17 @@
|
|||||||
|
package app.revanced.patches.instagram.story.flipping
|
||||||
|
|
||||||
|
import app.revanced.patcher.patch.bytecodePatch
|
||||||
|
import app.revanced.util.returnEarly
|
||||||
|
|
||||||
|
@Suppress("unused")
|
||||||
|
val disableStoryAutoFlippingPatch = bytecodePatch(
|
||||||
|
name = "Disable story auto flipping",
|
||||||
|
description = "Disable stories automatically flipping/skipping after some seconds.",
|
||||||
|
use = false
|
||||||
|
) {
|
||||||
|
compatibleWith("com.instagram.android")
|
||||||
|
|
||||||
|
execute {
|
||||||
|
onStoryTimeoutActionFingerprint.method.returnEarly()
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,12 @@
|
|||||||
|
package app.revanced.patches.instagram.story.flipping
|
||||||
|
|
||||||
|
import app.revanced.patcher.fingerprint
|
||||||
|
|
||||||
|
internal val onStoryTimeoutActionFingerprint = fingerprint {
|
||||||
|
parameters("Ljava/lang/Object;")
|
||||||
|
returns("V")
|
||||||
|
strings("userSession")
|
||||||
|
custom { _, classDef ->
|
||||||
|
classDef.type == "Linstagram/features/stories/fragment/ReelViewerFragment;"
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,29 @@
|
|||||||
|
package app.revanced.patches.letterboxd.ads
|
||||||
|
|
||||||
|
import app.revanced.patcher.fingerprint
|
||||||
|
|
||||||
|
internal const val admobHelperClassName = "Lcom/letterboxd/letterboxd/helpers/AdmobHelper;"
|
||||||
|
|
||||||
|
internal val admobHelperSetShowAdsFingerprint = fingerprint {
|
||||||
|
custom { method, classDef ->
|
||||||
|
method.name == "setShowAds" && classDef.type == admobHelperClassName
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
internal val admobHelperShouldShowAdsFingerprint = fingerprint {
|
||||||
|
custom { method, classDef ->
|
||||||
|
method.name == "shouldShowAds" && classDef.type == admobHelperClassName
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
internal val filmFragmentShowAdsFingerprint = fingerprint {
|
||||||
|
custom { method, classDef ->
|
||||||
|
method.name == "showAds" && classDef.type.endsWith("/FilmFragment;")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
internal val memberExtensionShowAdsFingerprint = fingerprint {
|
||||||
|
custom { method, classDef ->
|
||||||
|
method.name == "showAds" && classDef.type.endsWith("/AMemberExtensionKt;")
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,20 @@
|
|||||||
|
|
||||||
|
package app.revanced.patches.letterboxd.ads
|
||||||
|
|
||||||
|
import app.revanced.patcher.extensions.InstructionExtensions.addInstruction
|
||||||
|
import app.revanced.patcher.patch.bytecodePatch
|
||||||
|
import app.revanced.util.returnEarly
|
||||||
|
|
||||||
|
@Suppress("unused")
|
||||||
|
val hideAdsPatch = bytecodePatch(
|
||||||
|
name = "Hide ads",
|
||||||
|
) {
|
||||||
|
compatibleWith("com.letterboxd.letterboxd")
|
||||||
|
|
||||||
|
execute {
|
||||||
|
admobHelperSetShowAdsFingerprint.method.addInstruction(0, "const p1, 0x0")
|
||||||
|
listOf(admobHelperShouldShowAdsFingerprint, filmFragmentShowAdsFingerprint, memberExtensionShowAdsFingerprint).forEach {
|
||||||
|
it.method.returnEarly(false)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,16 @@
|
|||||||
|
package app.revanced.patches.protonvpn.delay
|
||||||
|
|
||||||
|
import app.revanced.patcher.fingerprint
|
||||||
|
|
||||||
|
|
||||||
|
internal val longDelayFingerprint = fingerprint {
|
||||||
|
custom { method, _ ->
|
||||||
|
method.name == "getChangeServerLongDelayInSeconds"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
internal val shortDelayFingerprint = fingerprint {
|
||||||
|
custom { method, _ ->
|
||||||
|
method.name == "getChangeServerShortDelayInSeconds"
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,17 @@
|
|||||||
|
package app.revanced.patches.protonvpn.delay
|
||||||
|
|
||||||
|
import app.revanced.patcher.patch.bytecodePatch
|
||||||
|
import app.revanced.util.returnEarly
|
||||||
|
|
||||||
|
@Suppress("unused")
|
||||||
|
val removeDelayPatch = bytecodePatch(
|
||||||
|
name = "Remove delay",
|
||||||
|
description = "Removes the delay when changing servers.",
|
||||||
|
) {
|
||||||
|
compatibleWith("ch.protonvpn.android")
|
||||||
|
|
||||||
|
execute {
|
||||||
|
longDelayFingerprint.method.returnEarly(0)
|
||||||
|
shortDelayFingerprint.method.returnEarly(0)
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -807,10 +807,11 @@ If changing this setting does not take effect, try switching to Incognito mode."
|
|||||||
<string name="revanced_hide_player_flyout_audio_track_title">Hide Audio track</string>
|
<string name="revanced_hide_player_flyout_audio_track_title">Hide Audio track</string>
|
||||||
<string name="revanced_hide_player_flyout_audio_track_summary_on">Audio track menu is hidden</string>
|
<string name="revanced_hide_player_flyout_audio_track_summary_on">Audio track menu is hidden</string>
|
||||||
<string name="revanced_hide_player_flyout_audio_track_summary_off">Audio track menu is shown</string>
|
<string name="revanced_hide_player_flyout_audio_track_summary_off">Audio track menu is shown</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'.
|
||||||
|
'Android No SDK' must be kept untranslated. -->
|
||||||
<string name="revanced_hide_player_flyout_audio_track_not_available">"Audio track menu is hidden
|
<string name="revanced_hide_player_flyout_audio_track_not_available">"Audio track menu is hidden
|
||||||
|
|
||||||
To show the Audio track menu, change \'Spoof video streams\' to iPadOS"</string>
|
To show the Audio track menu, change \'Spoof video streams\' to \'Android No SDK\'"</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">Hide Watch in VR</string>
|
<string name="revanced_hide_player_flyout_watch_in_vr_title">Hide Watch in VR</string>
|
||||||
<string name="revanced_hide_player_flyout_watch_in_vr_summary_on">Watch in VR menu is hidden</string>
|
<string name="revanced_hide_player_flyout_watch_in_vr_summary_on">Watch in VR menu is hidden</string>
|
||||||
|
|||||||
Reference in New Issue
Block a user