Compare commits

...

8 Commits

Author SHA1 Message Date
semantic-release-bot
545e16913a chore: Release v5.2.0-dev.4 [skip ci]
# [5.2.0-dev.4](https://github.com/ReVanced/revanced-patches/compare/v5.2.0-dev.3...v5.2.0-dev.4) (2024-11-26)

### Bug Fixes

* **YouTube - Playback speed:** Allow long press 2x speed when using custom playback speeds ([#3990](https://github.com/ReVanced/revanced-patches/issues/3990)) ([fafed09](fafed099c5))
2024-11-26 21:16:15 +00:00
LisoUseInAIKyrios
fafed099c5 fix(YouTube - Playback speed): Allow long press 2x speed when using custom playback speeds (#3990) 2024-11-26 22:12:46 +01:00
semantic-release-bot
a65bbebfdb chore: Release v5.2.0-dev.3 [skip ci]
# [5.2.0-dev.3](https://github.com/ReVanced/revanced-patches/compare/v5.2.0-dev.2...v5.2.0-dev.3) (2024-11-26)

### Features

* **VSCO:** Remove non functional `Unlock pro` patch ([1a910a2](1a910a2cf6))
2024-11-26 21:06:29 +00:00
oSumAtrIX
1a910a2cf6 feat(VSCO): Remove non functional Unlock pro patch 2024-11-26 22:03:31 +01:00
semantic-release-bot
6d23a4e000 chore: Release v5.2.0-dev.2 [skip ci]
# [5.2.0-dev.2](https://github.com/ReVanced/revanced-patches/compare/v5.2.0-dev.1...v5.2.0-dev.2) (2024-11-26)

### Bug Fixes

* **YouTube - Settings:** Show navigation back button in setting sub menus ([#3991](https://github.com/ReVanced/revanced-patches/issues/3991)) ([5c3c684](5c3c68406e))
2024-11-26 16:49:10 +00:00
LisoUseInAIKyrios
5c3c68406e fix(YouTube - Settings): Show navigation back button in setting sub menus (#3991) 2024-11-26 20:45:48 +04:00
github-actions[bot]
b0c3709be7 chore: Sync translations (#3993) 2024-11-26 20:45:18 +04:00
LisoUseInAIKyrios
cd19f976e7 chore: Fix redundant patch description 2024-11-26 16:47:36 +04:00
15 changed files with 703 additions and 588 deletions

View File

@@ -1,3 +1,24 @@
# [5.2.0-dev.4](https://github.com/ReVanced/revanced-patches/compare/v5.2.0-dev.3...v5.2.0-dev.4) (2024-11-26)
### Bug Fixes
* **YouTube - Playback speed:** Allow long press 2x speed when using custom playback speeds ([#3990](https://github.com/ReVanced/revanced-patches/issues/3990)) ([79a543a](https://github.com/ReVanced/revanced-patches/commit/79a543a57470638f983862c61270e046f3ac5cb7))
# [5.2.0-dev.3](https://github.com/ReVanced/revanced-patches/compare/v5.2.0-dev.2...v5.2.0-dev.3) (2024-11-26)
### Features
* **VSCO:** Remove non functional `Unlock pro` patch ([4fddb19](https://github.com/ReVanced/revanced-patches/commit/4fddb1930bc7adeee3b60ae9cd346b143e88bd42))
# [5.2.0-dev.2](https://github.com/ReVanced/revanced-patches/compare/v5.2.0-dev.1...v5.2.0-dev.2) (2024-11-26)
### Bug Fixes
* **YouTube - Settings:** Show navigation back button in setting sub menus ([#3991](https://github.com/ReVanced/revanced-patches/issues/3991)) ([e61686c](https://github.com/ReVanced/revanced-patches/commit/e61686c1039ae29e443273e4da4ec63956216841))
# [5.2.0-dev.1](https://github.com/ReVanced/revanced-patches/compare/v5.1.1-dev.2...v5.2.0-dev.1) (2024-11-25) # [5.2.0-dev.1](https://github.com/ReVanced/revanced-patches/compare/v5.1.1-dev.2...v5.2.0-dev.1) (2024-11-25)

View File

@@ -1,21 +1,33 @@
package app.revanced.extension.shared.settings.preference; package app.revanced.extension.shared.settings.preference;
import static app.revanced.extension.shared.StringRef.str;
import static app.revanced.extension.shared.Utils.getResourceIdentifier;
import android.annotation.SuppressLint; import android.annotation.SuppressLint;
import android.app.AlertDialog; import android.app.AlertDialog;
import android.app.Dialog;
import android.content.Context; import android.content.Context;
import android.content.SharedPreferences; import android.content.SharedPreferences;
import android.graphics.drawable.Drawable;
import android.os.Build;
import android.os.Bundle; import android.os.Bundle;
import android.preference.*; import android.preference.*;
import android.util.TypedValue;
import android.view.ViewGroup;
import android.widget.TextView;
import android.widget.Toolbar;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
import androidx.annotation.Nullable; import androidx.annotation.Nullable;
import java.util.Objects;
import app.revanced.extension.shared.Logger; import app.revanced.extension.shared.Logger;
import app.revanced.extension.shared.Utils; import app.revanced.extension.shared.Utils;
import app.revanced.extension.shared.settings.BaseSettings; import app.revanced.extension.shared.settings.BaseSettings;
import app.revanced.extension.shared.settings.BooleanSetting; import app.revanced.extension.shared.settings.BooleanSetting;
import app.revanced.extension.shared.settings.Setting; import app.revanced.extension.shared.settings.Setting;
import app.revanced.extension.youtube.ThemeHelper;
import static app.revanced.extension.shared.StringRef.str;
@SuppressWarnings("deprecation") @SuppressWarnings("deprecation")
public abstract class AbstractPreferenceFragment extends PreferenceFragment { public abstract class AbstractPreferenceFragment extends PreferenceFragment {
@@ -71,6 +83,15 @@ public abstract class AbstractPreferenceFragment extends PreferenceFragment {
} }
}; };
@SuppressLint("UseCompatLoadingForDrawables")
public static Drawable getBackButtonDrawable() {
final int backButtonResource = getResourceIdentifier(ThemeHelper.isDarkTheme()
? "yt_outline_arrow_left_white_24"
: "yt_outline_arrow_left_black_24",
"drawable");
return Utils.getContext().getResources().getDrawable(backButtonResource);
}
/** /**
* Initialize this instance, and do any custom behavior. * Initialize this instance, and do any custom behavior.
* <p> * <p>
@@ -98,7 +119,7 @@ public abstract class AbstractPreferenceFragment extends PreferenceFragment {
showingUserDialogMessage = true; showingUserDialogMessage = true;
new AlertDialog.Builder(context) new AlertDialog.Builder(context)
.setTitle(confirmDialogTitle) .setTitle(confirmDialogTitle)
.setMessage(setting.userDialogMessage.toString()) .setMessage(Objects.requireNonNull(setting.userDialogMessage).toString())
.setPositiveButton(android.R.string.ok, (dialog, id) -> { .setPositiveButton(android.R.string.ok, (dialog, id) -> {
if (setting.rebootApp) { if (setting.rebootApp) {
showRestartDialog(context); showRestartDialog(context);
@@ -261,6 +282,7 @@ public abstract class AbstractPreferenceFragment extends PreferenceFragment {
// causes a callback to the listener even though nothing changed. // causes a callback to the listener even though nothing changed.
initialize(); initialize();
updateUIToSettingValues(); updateUIToSettingValues();
setPreferenceScreenToolbar(getPreferenceScreen());
preferenceManager.getSharedPreferences().registerOnSharedPreferenceChangeListener(listener); preferenceManager.getSharedPreferences().registerOnSharedPreferenceChangeListener(listener);
} catch (Exception ex) { } catch (Exception ex) {
@@ -273,4 +295,44 @@ public abstract class AbstractPreferenceFragment extends PreferenceFragment {
getPreferenceManager().getSharedPreferences().unregisterOnSharedPreferenceChangeListener(listener); getPreferenceManager().getSharedPreferences().unregisterOnSharedPreferenceChangeListener(listener);
super.onDestroy(); super.onDestroy();
} }
private void setPreferenceScreenToolbar(PreferenceScreen parentScreen) {
for (int i = 0, preferenceCount = parentScreen.getPreferenceCount(); i < preferenceCount; i++) {
Preference childPreference = parentScreen.getPreference(i);
if (childPreference instanceof PreferenceScreen) {
// Recursively set sub preferences.
setPreferenceScreenToolbar((PreferenceScreen) childPreference);
childPreference.setOnPreferenceClickListener(
childScreen -> {
Dialog preferenceScreenDialog = ((PreferenceScreen) childScreen).getDialog();
ViewGroup rootView = (ViewGroup) preferenceScreenDialog
.findViewById(android.R.id.content)
.getParent();
Toolbar toolbar = new Toolbar(childScreen.getContext());
toolbar.setTitle(childScreen.getTitle());
toolbar.setNavigationIcon(getBackButtonDrawable());
toolbar.setNavigationOnClickListener(view -> preferenceScreenDialog.dismiss());
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
final int margin = (int) TypedValue.applyDimension(
TypedValue.COMPLEX_UNIT_DIP, 16, getResources().getDisplayMetrics()
);
toolbar.setTitleMargin(margin, 0, margin, 0);
}
TextView toolbarTextView = Utils.getChildView(toolbar,
true, TextView.class::isInstance);
if (toolbarTextView != null) {
toolbarTextView.setTextColor(ThemeHelper.getForegroundColor());
}
rootView.addView(toolbar, 0);
return false;
}
);
}
}
}
} }

View File

@@ -82,4 +82,12 @@ public class ThemeHelper {
} }
return Utils.getResourceColor(colorString); return Utils.getResourceColor(colorString);
} }
public static int getBackgroundColor() {
return isDarkTheme() ? getDarkThemeColor() : getLightThemeColor();
}
public static int getForegroundColor() {
return isDarkTheme() ? getLightThemeColor() : getDarkThemeColor();
}
} }

View File

@@ -1,14 +1,14 @@
package app.revanced.extension.youtube.patches; package app.revanced.extension.youtube.patches;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
import app.revanced.extension.youtube.patches.playback.speed.RememberPlaybackSpeedPatch;
import app.revanced.extension.youtube.shared.VideoState;
import app.revanced.extension.shared.Logger;
import app.revanced.extension.shared.Utils;
import java.lang.ref.WeakReference; import java.lang.ref.WeakReference;
import java.util.Objects; import java.util.Objects;
import app.revanced.extension.shared.Logger;
import app.revanced.extension.shared.Utils;
import app.revanced.extension.youtube.shared.VideoState;
/** /**
* Hooking class for the current playing video. * Hooking class for the current playing video.
* @noinspection unused * @noinspection unused
@@ -120,6 +120,16 @@ public final class VideoInformation {
} }
} }
/**
* Injection point.
*/
public static void videoSpeedChanged(float currentVideoSpeed) {
if (playbackSpeed != currentVideoSpeed) {
Logger.printDebug(() -> "Video speed changed: " + currentVideoSpeed);
playbackSpeed = currentVideoSpeed;
}
}
/** /**
* Injection point. * Injection point.
* Called when user selects a playback speed. * Called when user selects a playback speed.
@@ -131,18 +141,6 @@ public final class VideoInformation {
playbackSpeed = userSelectedPlaybackSpeed; playbackSpeed = userSelectedPlaybackSpeed;
} }
/**
* Overrides the current playback speed.
* <p>
* <b> Used exclusively by {@link RememberPlaybackSpeedPatch} </b>
*/
public static void overridePlaybackSpeed(float speedOverride) {
if (playbackSpeed != speedOverride) {
Logger.printDebug(() -> "Overriding playback speed to: " + speedOverride);
playbackSpeed = speedOverride;
}
}
/** /**
* Injection point. * Injection point.
* *

View File

@@ -12,6 +12,8 @@ public final class RememberPlaybackSpeedPatch {
private static final long TOAST_DELAY_MILLISECONDS = 750; private static final long TOAST_DELAY_MILLISECONDS = 750;
private static volatile boolean newVideoStarted;
private static long lastTimeSpeedChanged; private static long lastTimeSpeedChanged;
/** /**
@@ -19,7 +21,7 @@ public final class RememberPlaybackSpeedPatch {
*/ */
public static void newVideoStarted(VideoInformation.PlaybackController ignoredPlayerController) { public static void newVideoStarted(VideoInformation.PlaybackController ignoredPlayerController) {
Logger.printDebug(() -> "newVideoStarted"); Logger.printDebug(() -> "newVideoStarted");
VideoInformation.overridePlaybackSpeed(Settings.PLAYBACK_SPEED_DEFAULT.get()); newVideoStarted = true;
} }
/** /**
@@ -29,42 +31,56 @@ public final class RememberPlaybackSpeedPatch {
* @param playbackSpeed The playback speed the user selected * @param playbackSpeed The playback speed the user selected
*/ */
public static void userSelectedPlaybackSpeed(float playbackSpeed) { public static void userSelectedPlaybackSpeed(float playbackSpeed) {
if (Settings.REMEMBER_PLAYBACK_SPEED_LAST_SELECTED.get()) { try {
// With the 0.05x menu, if the speed is set by integrations to higher than 2.0x if (Settings.REMEMBER_PLAYBACK_SPEED_LAST_SELECTED.get()) {
// then the menu will allow increasing without bounds but the max speed is // With the 0.05x menu, if the speed is set by integrations to higher than 2.0x
// still capped to under 8.0x. // then the menu will allow increasing without bounds but the max speed is
playbackSpeed = Math.min(playbackSpeed, CustomPlaybackSpeedPatch.PLAYBACK_SPEED_MAXIMUM - 0.05f); // still capped to under 8.0x.
playbackSpeed = Math.min(playbackSpeed, CustomPlaybackSpeedPatch.PLAYBACK_SPEED_MAXIMUM - 0.05f);
// Prevent toast spamming if using the 0.05x adjustments. // Prevent toast spamming if using the 0.05x adjustments.
// Show exactly one toast after the user stops interacting with the speed menu. // Show exactly one toast after the user stops interacting with the speed menu.
final long now = System.currentTimeMillis(); final long now = System.currentTimeMillis();
lastTimeSpeedChanged = now; lastTimeSpeedChanged = now;
final float finalPlaybackSpeed = playbackSpeed; final float finalPlaybackSpeed = playbackSpeed;
Utils.runOnMainThreadDelayed(() -> { Utils.runOnMainThreadDelayed(() -> {
if (lastTimeSpeedChanged != now) { if (lastTimeSpeedChanged != now) {
// The user made additional speed adjustments and this call is outdated. // The user made additional speed adjustments and this call is outdated.
return; return;
} }
if (Settings.PLAYBACK_SPEED_DEFAULT.get() == finalPlaybackSpeed) { if (Settings.PLAYBACK_SPEED_DEFAULT.get() == finalPlaybackSpeed) {
// User changed to a different speed and immediately changed back. // User changed to a different speed and immediately changed back.
// Or the user is going past 8.0x in the glitched out 0.05x menu. // Or the user is going past 8.0x in the glitched out 0.05x menu.
return; return;
} }
Settings.PLAYBACK_SPEED_DEFAULT.save(finalPlaybackSpeed); Settings.PLAYBACK_SPEED_DEFAULT.save(finalPlaybackSpeed);
Utils.showToastLong(str("revanced_remember_playback_speed_toast", (finalPlaybackSpeed + "x"))); Utils.showToastLong(str("revanced_remember_playback_speed_toast", (finalPlaybackSpeed + "x")));
}, TOAST_DELAY_MILLISECONDS); }, TOAST_DELAY_MILLISECONDS);
}
} catch (Exception ex) {
Logger.printException(() -> "userSelectedPlaybackSpeed failure", ex);
} }
} }
/** /**
* Injection point. * Injection point.
* Overrides the video speed. Called after video loads, and immediately after user selects a different playback speed * Overrides the video speed. Called after video loads,
* and immediately after the user selects a different playback speed.
*/ */
public static float getPlaybackSpeedOverride() { public static float getPlaybackSpeedOverride() {
return VideoInformation.getPlaybackSpeed(); if (newVideoStarted) {
newVideoStarted = false;
final float defaultSpeed = Settings.PLAYBACK_SPEED_DEFAULT.get();
if (defaultSpeed > 0) {
return defaultSpeed;
}
}
return -2.0f;
} }
} }

View File

@@ -7,6 +7,7 @@ import android.view.ViewGroup;
import android.widget.ImageButton; import android.widget.ImageButton;
import android.widget.TextView; import android.widget.TextView;
import app.revanced.extension.shared.Logger; import app.revanced.extension.shared.Logger;
import app.revanced.extension.shared.settings.preference.AbstractPreferenceFragment;
import app.revanced.extension.youtube.ThemeHelper; import app.revanced.extension.youtube.ThemeHelper;
import app.revanced.extension.youtube.settings.preference.ReVancedPreferenceFragment; import app.revanced.extension.youtube.settings.preference.ReVancedPreferenceFragment;
import app.revanced.extension.youtube.settings.preference.ReturnYouTubeDislikePreferenceFragment; import app.revanced.extension.youtube.settings.preference.ReturnYouTubeDislikePreferenceFragment;
@@ -39,7 +40,7 @@ public class LicenseActivityHook {
PreferenceFragment fragment; PreferenceFragment fragment;
String toolbarTitleResourceName; String toolbarTitleResourceName;
String dataString = licenseActivity.getIntent().getDataString(); String dataString = Objects.requireNonNull(licenseActivity.getIntent().getDataString());
switch (dataString) { switch (dataString) {
case "revanced_sb_settings_intent": case "revanced_sb_settings_intent":
toolbarTitleResourceName = "revanced_sb_settings_title"; toolbarTitleResourceName = "revanced_sb_settings_title";
@@ -59,12 +60,14 @@ public class LicenseActivityHook {
} }
setToolbarTitle(licenseActivity, toolbarTitleResourceName); setToolbarTitle(licenseActivity, toolbarTitleResourceName);
//noinspection deprecation
licenseActivity.getFragmentManager() licenseActivity.getFragmentManager()
.beginTransaction() .beginTransaction()
.replace(getResourceIdentifier("revanced_settings_fragments", "id"), fragment) .replace(getResourceIdentifier("revanced_settings_fragments", "id"), fragment)
.commit(); .commit();
} catch (Exception ex) { } catch (Exception ex) {
Logger.printException(() -> "onCreate failure", ex); Logger.printException(() -> "initialize failure", ex);
} }
} }
@@ -80,11 +83,7 @@ public class LicenseActivityHook {
ViewGroup toolbar = activity.findViewById(getToolbarResourceId()); ViewGroup toolbar = activity.findViewById(getToolbarResourceId());
ImageButton imageButton = Objects.requireNonNull(getChildView(toolbar, false, ImageButton imageButton = Objects.requireNonNull(getChildView(toolbar, false,
view -> view instanceof ImageButton)); view -> view instanceof ImageButton));
final int backButtonResource = getResourceIdentifier(ThemeHelper.isDarkTheme() imageButton.setImageDrawable(AbstractPreferenceFragment.getBackButtonDrawable());
? "yt_outline_arrow_left_white_24"
: "yt_outline_arrow_left_black_24",
"drawable");
imageButton.setImageDrawable(activity.getResources().getDrawable(backButtonResource));
imageButton.setOnClickListener(view -> activity.onBackPressed()); imageButton.setOnClickListener(view -> activity.onBackPressed());
} }

View File

@@ -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.2.0-dev.1 version = 5.2.0-dev.4

View File

@@ -1370,11 +1370,9 @@ public final class app/revanced/patches/youtube/shared/FingerprintsKt {
} }
public final class app/revanced/patches/youtube/video/information/VideoInformationPatchKt { public final class app/revanced/patches/youtube/video/information/VideoInformationPatchKt {
public static final fun getSetPlaybackSpeedClassFieldReference ()Ljava/lang/String;
public static final fun getSetPlaybackSpeedContainerClassFieldReference ()Ljava/lang/String;
public static final fun getSetPlaybackSpeedMethodReference ()Ljava/lang/String;
public static final fun getVideoInformationPatch ()Lapp/revanced/patcher/patch/BytecodePatch; public static final fun getVideoInformationPatch ()Lapp/revanced/patcher/patch/BytecodePatch;
public static final fun userSelectedPlaybackSpeedHook (Ljava/lang/String;Ljava/lang/String;)V public static final fun userSelectedPlaybackSpeedHook (Ljava/lang/String;Ljava/lang/String;)V
public static final fun videoSpeedChangedHook (Ljava/lang/String;Ljava/lang/String;)V
public static final fun videoTimeHook (Ljava/lang/String;Ljava/lang/String;)V public static final fun videoTimeHook (Ljava/lang/String;Ljava/lang/String;)V
} }

View File

@@ -3,9 +3,9 @@ package app.revanced.patches.vsco.misc.pro
import app.revanced.patcher.extensions.InstructionExtensions.addInstruction import app.revanced.patcher.extensions.InstructionExtensions.addInstruction
import app.revanced.patcher.patch.bytecodePatch import app.revanced.patcher.patch.bytecodePatch
@Deprecated("This patch is deprecated because it does not work anymore and will be removed in the future.")
@Suppress("unused") @Suppress("unused")
val unlockProPatch = bytecodePatch( val unlockProPatch = bytecodePatch(
name = "Unlock pro",
description = "Unlocks pro features.", description = "Unlocks pro features.",
) { ) {
compatibleWith("com.vsco.cam"("345")) compatibleWith("com.vsco.cam"("345"))

View File

@@ -135,8 +135,7 @@ private const val EXTENSION_CLASS_DESCRIPTOR = "Lapp/revanced/extension/youtube/
@Suppress("unused") @Suppress("unused")
val miniplayerPatch = bytecodePatch( val miniplayerPatch = bytecodePatch(
name = "Miniplayer", name = "Miniplayer",
description = "Adds options to change the in app minimized player. " + description = "Adds options to change the in app minimized player."
"Patching target 19.16+ adds modern miniplayers.",
) { ) {
dependsOn( dependsOn(
sharedExtensionPatch, sharedExtensionPatch,

View File

@@ -20,13 +20,13 @@ import app.revanced.util.getReference
import app.revanced.util.indexOfFirstInstructionOrThrow import app.revanced.util.indexOfFirstInstructionOrThrow
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.BuilderInstruction
import com.android.tools.smali.dexlib2.builder.MutableMethodImplementation import com.android.tools.smali.dexlib2.builder.MutableMethodImplementation
import com.android.tools.smali.dexlib2.iface.Method import com.android.tools.smali.dexlib2.iface.Method
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.instruction.ReferenceInstruction import com.android.tools.smali.dexlib2.iface.instruction.ReferenceInstruction
import com.android.tools.smali.dexlib2.iface.instruction.TwoRegisterInstruction import com.android.tools.smali.dexlib2.iface.instruction.TwoRegisterInstruction
import com.android.tools.smali.dexlib2.iface.reference.FieldReference
import com.android.tools.smali.dexlib2.iface.reference.MethodReference import com.android.tools.smali.dexlib2.iface.reference.MethodReference
import com.android.tools.smali.dexlib2.immutable.ImmutableMethod import com.android.tools.smali.dexlib2.immutable.ImmutableMethod
import com.android.tools.smali.dexlib2.immutable.ImmutableMethodParameter import com.android.tools.smali.dexlib2.immutable.ImmutableMethodParameter
@@ -57,12 +57,16 @@ private lateinit var speedSelectionInsertMethod: MutableMethod
private var speedSelectionInsertIndex = -1 private var speedSelectionInsertIndex = -1
private var speedSelectionValueRegister = -1 private var speedSelectionValueRegister = -1
// Change playback speed method.
private lateinit var setPlaybackSpeedMethod: MutableMethod
private var setPlaybackSpeedMethodIndex = -1
// Used by other patches. // Used by other patches.
lateinit var setPlaybackSpeedContainerClassFieldReference: String internal lateinit var setPlaybackSpeedContainerClassFieldReference: FieldReference
private set private set
lateinit var setPlaybackSpeedClassFieldReference: String internal lateinit var setPlaybackSpeedClassFieldReference: FieldReference
private set private set
lateinit var setPlaybackSpeedMethodReference: String internal lateinit var setPlaybackSpeedMethodReference: MethodReference
private set private set
val videoInformationPatch = bytecodePatch( val videoInformationPatch = bytecodePatch(
@@ -164,24 +168,27 @@ val videoInformationPatch = bytecodePatch(
videoTimeHook(EXTENSION_CLASS_DESCRIPTOR, "setVideoTime") videoTimeHook(EXTENSION_CLASS_DESCRIPTOR, "setVideoTime")
/* /*
* Hook the user playback speed selection * Hook the user playback speed selection.
*/ */
onPlaybackSpeedItemClickFingerprint.method.apply { onPlaybackSpeedItemClickFingerprint.method.apply {
val speedSelectionMethodInstructions = implementation!!.instructions val speedSelectionValueInstructionIndex = indexOfFirstInstructionOrThrow(Opcode.IGET)
val speedSelectionValueInstructionIndex = speedSelectionMethodInstructions.indexOfFirst {
it.opcode == Opcode.IGET
}
legacySpeedSelectionInsertMethod = this legacySpeedSelectionInsertMethod = this
legacySpeedSelectionInsertIndex = speedSelectionValueInstructionIndex + 1 legacySpeedSelectionInsertIndex = speedSelectionValueInstructionIndex + 1
legacySpeedSelectionValueRegister = legacySpeedSelectionValueRegister =
getInstruction<TwoRegisterInstruction>(speedSelectionValueInstructionIndex).registerA getInstruction<TwoRegisterInstruction>(speedSelectionValueInstructionIndex).registerA
setPlaybackSpeedClassFieldReference =
getInstruction<ReferenceInstruction>(speedSelectionValueInstructionIndex + 1).reference.toString()
setPlaybackSpeedMethodReference = setPlaybackSpeedMethodReference =
getInstruction<ReferenceInstruction>(speedSelectionValueInstructionIndex + 2).reference.toString() getInstruction<ReferenceInstruction>(speedSelectionValueInstructionIndex + 2).reference as MethodReference
setPlaybackSpeedClassFieldReference =
getInstruction<ReferenceInstruction>(speedSelectionValueInstructionIndex + 1).reference as FieldReference
setPlaybackSpeedContainerClassFieldReference = setPlaybackSpeedContainerClassFieldReference =
getReference(speedSelectionMethodInstructions, -1, Opcode.IF_EQZ) getInstruction<ReferenceInstruction>(indexOfFirstInstructionOrThrow(Opcode.IF_EQZ) - 1).reference as FieldReference
setPlaybackSpeedMethod =
proxy(classes.first { it.type == setPlaybackSpeedMethodReference.definingClass })
.mutableClass.methods.first { it.name == setPlaybackSpeedMethodReference.name }
setPlaybackSpeedMethodIndex = 0
} }
// Handle new playback speed menu. // Handle new playback speed menu.
@@ -195,6 +202,7 @@ val videoInformationPatch = bytecodePatch(
speedSelectionValueRegister = getInstruction<TwoRegisterInstruction>(index).registerA speedSelectionValueRegister = getInstruction<TwoRegisterInstruction>(index).registerA
} }
videoSpeedChangedHook(EXTENSION_CLASS_DESCRIPTOR, "videoSpeedChanged")
userSelectedPlaybackSpeedHook(EXTENSION_CLASS_DESCRIPTOR, "userSelectedPlaybackSpeed") userSelectedPlaybackSpeedHook(EXTENSION_CLASS_DESCRIPTOR, "userSelectedPlaybackSpeed")
} }
} }
@@ -295,9 +303,14 @@ fun videoTimeHook(targetMethodClass: String, targetMethodName: String) =
"$targetMethodClass->$targetMethodName(J)V", "$targetMethodClass->$targetMethodName(J)V",
) )
private fun getReference(instructions: List<BuilderInstruction>, offset: Int, opcode: Opcode) = /**
(instructions[instructions.indexOfFirst { it.opcode == opcode } + offset] as ReferenceInstruction) * Hook when the video speed is changed for any reason _except when the user manually selects a new speed_.
.reference.toString() */
fun videoSpeedChangedHook(targetMethodClass: String, targetMethodName: String) =
setPlaybackSpeedMethod.addInstruction(
setPlaybackSpeedMethodIndex++,
"invoke-static { p1 }, $targetMethodClass->$targetMethodName(F)V"
)
/** /**
* Hook the video speed selected by the user. * Hook the video speed selected by the user.
@@ -312,4 +325,4 @@ fun userSelectedPlaybackSpeedHook(targetMethodClass: String, targetMethodName: S
speedSelectionInsertIndex++, speedSelectionInsertIndex++,
"invoke-static { v$speedSelectionValueRegister }, $targetMethodClass->$targetMethodName(F)V", "invoke-static { v$speedSelectionValueRegister }, $targetMethodClass->$targetMethodName(F)V",
) )
} }

View File

@@ -33,7 +33,7 @@ This is because Crowdin requires temporarily flattening this file and removing t
<resources> <resources>
<app id="shared"> <app id="shared">
<patch id="misc.checks.checkEnvironmentPatch"> <patch id="misc.checks.checkEnvironmentPatch">
<string name="revanced_check_environment_failed_title">Überprüfungen fehlgeschlagen</string> <string name="revanced_check_environment_failed_title">Überprüfung fehlgeschlagen</string>
<string name="revanced_check_environment_dialog_open_official_source_button">Offizielle Webseite öffnen</string> <string name="revanced_check_environment_dialog_open_official_source_button">Offizielle Webseite öffnen</string>
<string name="revanced_check_environment_dialog_ignore_button">Ignorieren</string> <string name="revanced_check_environment_dialog_ignore_button">Ignorieren</string>
<string name="revanced_check_environment_failed_message">&lt;h5&gt;Diese App wurde offenbar nicht von Ihnen gepatcht.&lt;/h5&gt;&lt;br&gt;Diese App funktioniert möglicherweise nicht richtig, &lt;b&gt;könnte schädlich oder sogar gefährlich in der Verwendung sein&lt;/b&gt;.&lt; br&gt;&lt;br&gt;Diese Prüfungen deuten darauf hin, dass diese App vorab gepatcht wurde oder von jemandem bezogen wurde sonst:&lt;br&gt;&lt;br&gt;&lt;small&gt;%1$s&lt;/small&gt;&lt;br&gt;Es wird dringend empfohlen, &lt;b&gt;diese App zu deinstallieren und selbst zu patchen&lt;/b&gt; um sicherzustellen, dass Sie eine validierte und sichere App verwenden.&lt;p&gt;&lt;br&gt;Wenn Sie diese Warnung ignorieren, wird sie nur zweimal angezeigt.</string> <string name="revanced_check_environment_failed_message">&lt;h5&gt;Diese App wurde offenbar nicht von Ihnen gepatcht.&lt;/h5&gt;&lt;br&gt;Diese App funktioniert möglicherweise nicht richtig, &lt;b&gt;könnte schädlich oder sogar gefährlich in der Verwendung sein&lt;/b&gt;.&lt; br&gt;&lt;br&gt;Diese Prüfungen deuten darauf hin, dass diese App vorab gepatcht wurde oder von jemandem bezogen wurde sonst:&lt;br&gt;&lt;br&gt;&lt;small&gt;%1$s&lt;/small&gt;&lt;br&gt;Es wird dringend empfohlen, &lt;b&gt;diese App zu deinstallieren und selbst zu patchen&lt;/b&gt; um sicherzustellen, dass Sie eine validierte und sichere App verwenden.&lt;p&gt;&lt;br&gt;Wenn Sie diese Warnung ignorieren, wird sie nur zweimal angezeigt.</string>

View File

@@ -1045,7 +1045,7 @@ This is because Crowdin requires temporarily flattening this file and removing t
<string name="revanced_miniplayer_width_dip_summary">Awal pada ukuran layar, dalam piksel</string> <string name="revanced_miniplayer_width_dip_summary">Awal pada ukuran layar, dalam piksel</string>
<string name="revanced_miniplayer_width_dip_invalid_toast">Ukuran piksel harus antara %1$s dan %2$s</string> <string name="revanced_miniplayer_width_dip_invalid_toast">Ukuran piksel harus antara %1$s dan %2$s</string>
<string name="revanced_miniplayer_opacity_title">Opasitas hamparan</string> <string name="revanced_miniplayer_opacity_title">Opasitas hamparan</string>
<string name="revanced_miniplayer_opacity_summary">Nilai opasitas antara 0-100, di mana 0 adalah transparan</string> <string name="revanced_miniplayer_opacity_summary">Nilai opasitas antara 0-100, dimana 0 adalah transparan</string>
<string name="revanced_miniplayer_opacity_invalid_toast">Opasitas hamparan pemutar mini antara 0-100</string> <string name="revanced_miniplayer_opacity_invalid_toast">Opasitas hamparan pemutar mini antara 0-100</string>
</patch> </patch>
<patch id="layout.theme.themePatch"> <patch id="layout.theme.themePatch">

View File

@@ -1012,6 +1012,7 @@ This is because Crowdin requires temporarily flattening this file and removing t
<string name="revanced_miniplayer_type_title">Loại trình phát thu nhỏ</string> <string name="revanced_miniplayer_type_title">Loại trình phát thu nhỏ</string>
<string name="revanced_miniplayer_type_entry_0">Đã tắt</string> <string name="revanced_miniplayer_type_entry_0">Đã tắt</string>
<string name="revanced_miniplayer_type_entry_1">Nguyên bản</string> <string name="revanced_miniplayer_type_entry_1">Nguyên bản</string>
<string name="revanced_miniplayer_type_entry_2"></string>
<string name="revanced_miniplayer_type_entry_3">Máy tính bảng</string> <string name="revanced_miniplayer_type_entry_3">Máy tính bảng</string>
<string name="revanced_miniplayer_type_entry_4">Hiện đại 1</string> <string name="revanced_miniplayer_type_entry_4">Hiện đại 1</string>
<string name="revanced_miniplayer_type_entry_5">Hiện đại 2</string> <string name="revanced_miniplayer_type_entry_5">Hiện đại 2</string>