mirror of
https://github.com/inotia00/revanced-patches.git
synced 2025-04-29 14:14:36 +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;
|
||||
|
||||
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.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.shared.PlayerType;
|
||||
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.VideoUtils;
|
||||
import kotlin.Pair;
|
||||
|
||||
// TODO: Implement sync queue and clean up code.
|
||||
@SuppressWarnings({"unused", "StaticFieldLeak"})
|
||||
public class PlaylistPatch extends VideoUtils {
|
||||
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"
|
||||
};
|
||||
public class PlaylistPatch extends AuthUtils {
|
||||
private static final boolean QUEUE_MANAGER =
|
||||
Settings.OVERLAY_BUTTON_EXTERNAL_DOWNLOADER_QUEUE_MANAGER.get()
|
||||
|| Settings.OVERRIDE_VIDEO_DOWNLOAD_BUTTON_QUEUE_MANAGER.get();
|
||||
|
||||
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 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.
|
||||
*/
|
||||
|
@ -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.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(
|
||||
name = "editPlaylistConstructorFingerprint",
|
||||
returnType = "V",
|
||||
|
@ -7,13 +7,12 @@ import app.revanced.patcher.extensions.InstructionExtensions.getInstruction
|
||||
import app.revanced.patcher.patch.PatchException
|
||||
import app.revanced.patcher.patch.bytecodePatch
|
||||
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.extension.Constants.UTILS_PATH
|
||||
import app.revanced.patches.youtube.utils.extension.sharedExtensionPatch
|
||||
import app.revanced.patches.youtube.utils.mainactivity.mainActivityResolvePatch
|
||||
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.util.fingerprint.matchOrThrow
|
||||
import app.revanced.util.fingerprint.methodOrThrow
|
||||
@ -34,21 +33,10 @@ val playlistPatch = bytecodePatch(
|
||||
dismissPlayerHookPatch,
|
||||
playerTypeHookPatch,
|
||||
videoInformationPatch,
|
||||
buildRequestPatch,
|
||||
authHookPatch,
|
||||
)
|
||||
|
||||
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.
|
||||
getMainActivityMethod("onKeyLongPress")
|
||||
.addInstructionsWithLabels(
|
||||
|
Loading…
x
Reference in New Issue
Block a user