mirror of
https://github.com/inotia00/revanced-patches.git
synced 2025-04-29 22:24:31 +02:00
fix(YouTube - Hook download actions, Overlay buttons): Auth key is set before the Context is initialized
This commit is contained in:
parent
4a19a960c5
commit
783e366242
@ -1,6 +1,10 @@
|
|||||||
package app.revanced.extension.youtube.patches.utils;
|
package app.revanced.extension.youtube.patches.utils;
|
||||||
|
|
||||||
import static app.revanced.extension.shared.utils.StringRef.str;
|
import static app.revanced.extension.shared.utils.StringRef.str;
|
||||||
|
import static app.revanced.extension.shared.utils.Utils.runOnMainThreadDelayed;
|
||||||
|
import static app.revanced.extension.youtube.utils.VideoUtils.dismissPlayer;
|
||||||
|
import static app.revanced.extension.youtube.utils.VideoUtils.launchVideoExternalDownloader;
|
||||||
|
import static app.revanced.extension.youtube.utils.VideoUtils.openPlaylist;
|
||||||
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.view.KeyEvent;
|
import android.view.KeyEvent;
|
||||||
@ -32,30 +36,18 @@ import app.revanced.extension.youtube.patches.utils.requests.SavePlaylistRequest
|
|||||||
import app.revanced.extension.youtube.settings.Settings;
|
import app.revanced.extension.youtube.settings.Settings;
|
||||||
import app.revanced.extension.youtube.shared.PlayerType;
|
import app.revanced.extension.youtube.shared.PlayerType;
|
||||||
import app.revanced.extension.youtube.shared.VideoInformation;
|
import app.revanced.extension.youtube.shared.VideoInformation;
|
||||||
|
import app.revanced.extension.youtube.utils.AuthUtils;
|
||||||
import app.revanced.extension.youtube.utils.ExtendedUtils;
|
import app.revanced.extension.youtube.utils.ExtendedUtils;
|
||||||
import app.revanced.extension.youtube.utils.VideoUtils;
|
|
||||||
import kotlin.Pair;
|
import kotlin.Pair;
|
||||||
|
|
||||||
// TODO: Implement sync queue and clean up code.
|
// TODO: Implement sync queue and clean up code.
|
||||||
@SuppressWarnings({"unused", "StaticFieldLeak"})
|
@SuppressWarnings({"unused", "StaticFieldLeak"})
|
||||||
public class PlaylistPatch extends VideoUtils {
|
public class PlaylistPatch extends AuthUtils {
|
||||||
private static final String AUTHORIZATION_HEADER = "Authorization";
|
|
||||||
private static final String[] REQUEST_HEADER_KEYS = {
|
|
||||||
AUTHORIZATION_HEADER,
|
|
||||||
"X-GOOG-API-FORMAT-VERSION",
|
|
||||||
"X-Goog-Visitor-Id"
|
|
||||||
};
|
|
||||||
private static final boolean QUEUE_MANAGER =
|
private static final boolean QUEUE_MANAGER =
|
||||||
Settings.OVERLAY_BUTTON_EXTERNAL_DOWNLOADER_QUEUE_MANAGER.get()
|
Settings.OVERLAY_BUTTON_EXTERNAL_DOWNLOADER_QUEUE_MANAGER.get()
|
||||||
|| Settings.OVERRIDE_VIDEO_DOWNLOAD_BUTTON_QUEUE_MANAGER.get();
|
|| Settings.OVERRIDE_VIDEO_DOWNLOAD_BUTTON_QUEUE_MANAGER.get();
|
||||||
|
|
||||||
private static Context mContext;
|
private static Context mContext;
|
||||||
private static volatile String authorization = "";
|
|
||||||
public static volatile String dataSyncId = "";
|
|
||||||
public static volatile boolean isIncognito = false;
|
|
||||||
private static volatile Map<String, String> requestHeader;
|
|
||||||
private static volatile String playlistId = "";
|
|
||||||
private static volatile String videoId = "";
|
|
||||||
|
|
||||||
private static String checkFailedAuth;
|
private static String checkFailedAuth;
|
||||||
private static String checkFailedPlaylistId;
|
private static String checkFailedPlaylistId;
|
||||||
@ -141,30 +133,6 @@ public class PlaylistPatch extends VideoUtils {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Injection point.
|
|
||||||
*/
|
|
||||||
public static void setRequestHeaders(String url, Map<String, String> requestHeaders) {
|
|
||||||
if (QUEUE_MANAGER) {
|
|
||||||
try {
|
|
||||||
// Save requestHeaders whenever an account is switched.
|
|
||||||
String auth = requestHeaders.get(AUTHORIZATION_HEADER);
|
|
||||||
if (auth == null || authorization.equals(auth)) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
for (String key : REQUEST_HEADER_KEYS) {
|
|
||||||
if (requestHeaders.get(key) == null) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
authorization = auth;
|
|
||||||
requestHeader = requestHeaders;
|
|
||||||
} catch (Exception ex) {
|
|
||||||
Logger.printException(() -> "setRequestHeaders failure", ex);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Invoked by extension.
|
* Invoked by extension.
|
||||||
*/
|
*/
|
||||||
|
@ -0,0 +1,40 @@
|
|||||||
|
package app.revanced.extension.youtube.utils;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import app.revanced.extension.shared.utils.Logger;
|
||||||
|
|
||||||
|
@SuppressWarnings("unused")
|
||||||
|
public class AuthUtils {
|
||||||
|
public static final String AUTHORIZATION_HEADER = "Authorization";
|
||||||
|
public static final String[] REQUEST_HEADER_KEYS = {
|
||||||
|
AUTHORIZATION_HEADER,
|
||||||
|
"X-GOOG-API-FORMAT-VERSION",
|
||||||
|
"X-Goog-Visitor-Id"
|
||||||
|
};
|
||||||
|
public static volatile String authorization = "";
|
||||||
|
public static volatile String dataSyncId = "";
|
||||||
|
public static volatile boolean isIncognito = false;
|
||||||
|
public static volatile Map<String, String> requestHeader;
|
||||||
|
public static volatile String playlistId = "";
|
||||||
|
public static volatile String videoId = "";
|
||||||
|
|
||||||
|
public static void setRequestHeaders(String url, Map<String, String> requestHeaders) {
|
||||||
|
try {
|
||||||
|
// Save requestHeaders whenever an account is switched.
|
||||||
|
String auth = requestHeaders.get(AUTHORIZATION_HEADER);
|
||||||
|
if (auth == null || authorization.equals(auth)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
for (String key : REQUEST_HEADER_KEYS) {
|
||||||
|
if (requestHeaders.get(key) == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
authorization = auth;
|
||||||
|
requestHeader = requestHeaders;
|
||||||
|
} catch (Exception ex) {
|
||||||
|
Logger.initializationException(AuthUtils.class, "setRequestHeaders failure", ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,34 @@
|
|||||||
|
package app.revanced.patches.youtube.utils.auth
|
||||||
|
|
||||||
|
import app.revanced.patcher.extensions.InstructionExtensions.addInstructions
|
||||||
|
import app.revanced.patcher.patch.bytecodePatch
|
||||||
|
import app.revanced.patches.youtube.utils.extension.Constants.EXTENSION_PATH
|
||||||
|
import app.revanced.patches.youtube.utils.extension.sharedExtensionPatch
|
||||||
|
import app.revanced.patches.youtube.utils.request.buildRequestPatch
|
||||||
|
import app.revanced.patches.youtube.utils.request.hookBuildRequest
|
||||||
|
import app.revanced.util.fingerprint.methodOrThrow
|
||||||
|
|
||||||
|
private const val EXTENSION_AUTH_UTILS_CLASS_DESCRIPTOR =
|
||||||
|
"$EXTENSION_PATH/utils/AuthUtils;"
|
||||||
|
|
||||||
|
val authHookPatch = bytecodePatch(
|
||||||
|
description = "authHookPatch"
|
||||||
|
) {
|
||||||
|
dependsOn(
|
||||||
|
sharedExtensionPatch,
|
||||||
|
buildRequestPatch,
|
||||||
|
)
|
||||||
|
|
||||||
|
execute {
|
||||||
|
// Get incognito status and data sync id.
|
||||||
|
accountIdentityFingerprint.methodOrThrow().addInstructions(
|
||||||
|
1, """
|
||||||
|
sput-object p3, $EXTENSION_AUTH_UTILS_CLASS_DESCRIPTOR->dataSyncId:Ljava/lang/String;
|
||||||
|
sput-boolean p4, $EXTENSION_AUTH_UTILS_CLASS_DESCRIPTOR->isIncognito:Z
|
||||||
|
"""
|
||||||
|
)
|
||||||
|
|
||||||
|
// Get the header to use the auth token.
|
||||||
|
hookBuildRequest("$EXTENSION_AUTH_UTILS_CLASS_DESCRIPTOR->setRequestHeaders(Ljava/lang/String;Ljava/util/Map;)V")
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,14 @@
|
|||||||
|
package app.revanced.patches.youtube.utils.auth
|
||||||
|
|
||||||
|
import app.revanced.util.fingerprint.legacyFingerprint
|
||||||
|
import app.revanced.util.or
|
||||||
|
import com.android.tools.smali.dexlib2.AccessFlags
|
||||||
|
|
||||||
|
internal val accountIdentityFingerprint = legacyFingerprint(
|
||||||
|
name = "accountIdentityFingerprint",
|
||||||
|
returnType = "V",
|
||||||
|
accessFlags = AccessFlags.PUBLIC or AccessFlags.CONSTRUCTOR,
|
||||||
|
customFingerprint = { method, _ ->
|
||||||
|
method.definingClass.endsWith("${'$'}AutoValue_AccountIdentity;")
|
||||||
|
}
|
||||||
|
)
|
@ -9,15 +9,6 @@ import com.android.tools.smali.dexlib2.Opcode
|
|||||||
import com.android.tools.smali.dexlib2.iface.Method
|
import com.android.tools.smali.dexlib2.iface.Method
|
||||||
import com.android.tools.smali.dexlib2.iface.reference.FieldReference
|
import com.android.tools.smali.dexlib2.iface.reference.FieldReference
|
||||||
|
|
||||||
internal val accountIdentityFingerprint = legacyFingerprint(
|
|
||||||
name = "accountIdentityFingerprint",
|
|
||||||
returnType = "V",
|
|
||||||
accessFlags = AccessFlags.PUBLIC or AccessFlags.CONSTRUCTOR,
|
|
||||||
customFingerprint = { method, _ ->
|
|
||||||
method.definingClass.endsWith("${'$'}AutoValue_AccountIdentity;")
|
|
||||||
}
|
|
||||||
)
|
|
||||||
|
|
||||||
internal val editPlaylistConstructorFingerprint = legacyFingerprint(
|
internal val editPlaylistConstructorFingerprint = legacyFingerprint(
|
||||||
name = "editPlaylistConstructorFingerprint",
|
name = "editPlaylistConstructorFingerprint",
|
||||||
returnType = "V",
|
returnType = "V",
|
||||||
|
@ -7,13 +7,12 @@ import app.revanced.patcher.extensions.InstructionExtensions.getInstruction
|
|||||||
import app.revanced.patcher.patch.PatchException
|
import app.revanced.patcher.patch.PatchException
|
||||||
import app.revanced.patcher.patch.bytecodePatch
|
import app.revanced.patcher.patch.bytecodePatch
|
||||||
import app.revanced.patches.shared.mainactivity.getMainActivityMethod
|
import app.revanced.patches.shared.mainactivity.getMainActivityMethod
|
||||||
|
import app.revanced.patches.youtube.utils.auth.authHookPatch
|
||||||
import app.revanced.patches.youtube.utils.dismiss.dismissPlayerHookPatch
|
import app.revanced.patches.youtube.utils.dismiss.dismissPlayerHookPatch
|
||||||
import app.revanced.patches.youtube.utils.extension.Constants.UTILS_PATH
|
import app.revanced.patches.youtube.utils.extension.Constants.UTILS_PATH
|
||||||
import app.revanced.patches.youtube.utils.extension.sharedExtensionPatch
|
import app.revanced.patches.youtube.utils.extension.sharedExtensionPatch
|
||||||
import app.revanced.patches.youtube.utils.mainactivity.mainActivityResolvePatch
|
import app.revanced.patches.youtube.utils.mainactivity.mainActivityResolvePatch
|
||||||
import app.revanced.patches.youtube.utils.playertype.playerTypeHookPatch
|
import app.revanced.patches.youtube.utils.playertype.playerTypeHookPatch
|
||||||
import app.revanced.patches.youtube.utils.request.buildRequestPatch
|
|
||||||
import app.revanced.patches.youtube.utils.request.hookBuildRequest
|
|
||||||
import app.revanced.patches.youtube.video.information.videoInformationPatch
|
import app.revanced.patches.youtube.video.information.videoInformationPatch
|
||||||
import app.revanced.util.fingerprint.matchOrThrow
|
import app.revanced.util.fingerprint.matchOrThrow
|
||||||
import app.revanced.util.fingerprint.methodOrThrow
|
import app.revanced.util.fingerprint.methodOrThrow
|
||||||
@ -34,21 +33,10 @@ val playlistPatch = bytecodePatch(
|
|||||||
dismissPlayerHookPatch,
|
dismissPlayerHookPatch,
|
||||||
playerTypeHookPatch,
|
playerTypeHookPatch,
|
||||||
videoInformationPatch,
|
videoInformationPatch,
|
||||||
buildRequestPatch,
|
authHookPatch,
|
||||||
)
|
)
|
||||||
|
|
||||||
execute {
|
execute {
|
||||||
// In Incognito mode, sending a request always seems to fail.
|
|
||||||
accountIdentityFingerprint.methodOrThrow().addInstructions(
|
|
||||||
1, """
|
|
||||||
sput-object p3, $EXTENSION_CLASS_DESCRIPTOR->dataSyncId:Ljava/lang/String;
|
|
||||||
sput-boolean p4, $EXTENSION_CLASS_DESCRIPTOR->isIncognito:Z
|
|
||||||
"""
|
|
||||||
)
|
|
||||||
|
|
||||||
// Get the header to use the auth token.
|
|
||||||
hookBuildRequest("$EXTENSION_CLASS_DESCRIPTOR->setRequestHeaders(Ljava/lang/String;Ljava/util/Map;)V")
|
|
||||||
|
|
||||||
// Open the queue manager by pressing and holding the back button.
|
// Open the queue manager by pressing and holding the back button.
|
||||||
getMainActivityMethod("onKeyLongPress")
|
getMainActivityMethod("onKeyLongPress")
|
||||||
.addInstructionsWithLabels(
|
.addInstructionsWithLabels(
|
||||||
|
Loading…
x
Reference in New Issue
Block a user