chore: Lint code

This commit is contained in:
inotia00
2025-01-07 14:06:31 +09:00
parent bcc9547b5f
commit a0329d28f5
18 changed files with 100 additions and 54 deletions

View File

@ -30,6 +30,7 @@ object AppClient {
private const val DEVICE_MAKE_IOS = "Apple" private const val DEVICE_MAKE_IOS = "Apple"
private const val OS_NAME_IOS = "iOS" private const val OS_NAME_IOS = "iOS"
/** /**
* The device machine id for the iPhone 15 Pro Max (iPhone16,2), * The device machine id for the iPhone 15 Pro Max (iPhone16,2),
* used to get HDR with AV1 hardware decoding. * used to get HDR with AV1 hardware decoding.
@ -240,7 +241,6 @@ object AppClient {
val userAgent: String, val userAgent: String,
/** /**
* Android SDK version, equivalent to [Build.VERSION.SDK] (System property: ro.build.version.sdk) * Android SDK version, equivalent to [Build.VERSION.SDK] (System property: ro.build.version.sdk)
* Field is null if not applicable.
*/ */
val androidSdkVersion: String = Build.VERSION.SDK, val androidSdkVersion: String = Build.VERSION.SDK,
/** /**

View File

@ -141,8 +141,9 @@ public class SpoofStreamingDataPatch {
* 1. Save the requestHeader in a field. * 1. Save the requestHeader in a field.
* 2. Invoke fetchRequest with the videoId used in PlaybackStartDescriptor. * 2. Invoke fetchRequest with the videoId used in PlaybackStartDescriptor.
* <p> * <p>
* @param requestHeaders Save the request Headers used for login to a field. *
* Only used in YouTube Music where login is required. * @param requestHeaders Save the request Headers used for login to a field.
* Only used in YouTube Music where login is required.
*/ */
private static void setRequestHeaders(Map<String, String> requestHeaders) { private static void setRequestHeaders(Map<String, String> requestHeaders) {
if (SPOOF_STREAMING_DATA_MUSIC) { if (SPOOF_STREAMING_DATA_MUSIC) {

View File

@ -130,17 +130,35 @@ object PlayerRoutes {
} }
@JvmStatic @JvmStatic
fun getPlayerResponseConnectionFromRoute(route: CompiledRoute, clientType: AppClient.ClientType): HttpURLConnection { fun getPlayerResponseConnectionFromRoute(
return getPlayerResponseConnectionFromRoute(route, clientType.userAgent, clientType.id.toString()) route: CompiledRoute,
clientType: AppClient.ClientType
): HttpURLConnection {
return getPlayerResponseConnectionFromRoute(
route,
clientType.userAgent,
clientType.id.toString()
)
} }
@JvmStatic @JvmStatic
fun getPlayerResponseConnectionFromRoute(route: CompiledRoute, clientType: WebClient.ClientType): HttpURLConnection { fun getPlayerResponseConnectionFromRoute(
return getPlayerResponseConnectionFromRoute(route, clientType.userAgent, clientType.id.toString()) route: CompiledRoute,
clientType: WebClient.ClientType
): HttpURLConnection {
return getPlayerResponseConnectionFromRoute(
route,
clientType.userAgent,
clientType.id.toString()
)
} }
@Throws(IOException::class) @Throws(IOException::class)
fun getPlayerResponseConnectionFromRoute(route: CompiledRoute, userAgent: String, clientVersion: String): HttpURLConnection { fun getPlayerResponseConnectionFromRoute(
route: CompiledRoute,
userAgent: String,
clientVersion: String
): HttpURLConnection {
val connection = Requester.getConnectionFromCompiledRoute(YT_API_URL, route) val connection = Requester.getConnectionFromCompiledRoute(YT_API_URL, route)
connection.setRequestProperty("Content-Type", "application/json") connection.setRequestProperty("Content-Type", "application/json")

View File

@ -9,7 +9,6 @@ import app.revanced.extension.shared.patches.spoof.requests.PlayerRoutes.getPlay
import app.revanced.extension.shared.settings.BaseSettings import app.revanced.extension.shared.settings.BaseSettings
import app.revanced.extension.shared.utils.Logger import app.revanced.extension.shared.utils.Logger
import app.revanced.extension.shared.utils.Utils import app.revanced.extension.shared.utils.Utils
import org.apache.commons.lang3.ArrayUtils
import org.apache.commons.lang3.StringUtils import org.apache.commons.lang3.StringUtils
import java.io.BufferedInputStream import java.io.BufferedInputStream
import java.io.ByteArrayOutputStream import java.io.ByteArrayOutputStream
@ -111,6 +110,7 @@ class StreamingDataRequest private constructor(
* Any arbitrarily large value, but must be at least twice [.HTTP_TIMEOUT_MILLISECONDS] * Any arbitrarily large value, but must be at least twice [.HTTP_TIMEOUT_MILLISECONDS]
*/ */
private const val MAX_MILLISECONDS_TO_WAIT_FOR_FETCH = 20 * 1000 private const val MAX_MILLISECONDS_TO_WAIT_FOR_FETCH = 20 * 1000
@GuardedBy("itself") @GuardedBy("itself")
val cache: MutableMap<String, StreamingDataRequest> = Collections.synchronizedMap( val cache: MutableMap<String, StreamingDataRequest> = Collections.synchronizedMap(
object : LinkedHashMap<String, StreamingDataRequest>(100) { object : LinkedHashMap<String, StreamingDataRequest>(100) {
@ -171,11 +171,13 @@ class StreamingDataRequest private constructor(
Logger.printDebug { "Fetching video streams for: $videoId using client: $clientType" } Logger.printDebug { "Fetching video streams for: $videoId using client: $clientType" }
try { try {
val connection = getPlayerResponseConnectionFromRoute(GET_STREAMING_DATA, clientType) val connection =
getPlayerResponseConnectionFromRoute(GET_STREAMING_DATA, clientType)
connection.connectTimeout = HTTP_TIMEOUT_MILLISECONDS connection.connectTimeout = HTTP_TIMEOUT_MILLISECONDS
connection.readTimeout = HTTP_TIMEOUT_MILLISECONDS connection.readTimeout = HTTP_TIMEOUT_MILLISECONDS
val usePoToken = clientType.requirePoToken && !StringUtils.isAnyEmpty(botGuardPoToken, visitorId) val usePoToken =
clientType.requirePoToken && !StringUtils.isAnyEmpty(botGuardPoToken, visitorId)
for (key in REQUEST_HEADER_KEYS) { for (key in REQUEST_HEADER_KEYS) {
var value = playerHeaders[key] var value = playerHeaders[key]
@ -248,7 +250,8 @@ class StreamingDataRequest private constructor(
// Retry with different client if empty response body is received. // Retry with different client if empty response body is received.
for (clientType in CLIENT_ORDER_TO_USE) { for (clientType in CLIENT_ORDER_TO_USE) {
if (clientType.requireAuth && if (clientType.requireAuth &&
playerHeaders[AUTHORIZATION_HEADER] == null) { playerHeaders[AUTHORIZATION_HEADER] == null
) {
Logger.printDebug { "Skipped login-required client (incognito mode or not logged in)\nClient: $clientType\nVideo: $videoId" } Logger.printDebug { "Skipped login-required client (incognito mode or not logged in)\nClient: $clientType\nVideo: $videoId" }
continue continue
} }
@ -270,7 +273,9 @@ class StreamingDataRequest private constructor(
ByteArrayOutputStream().use { stream -> ByteArrayOutputStream().use { stream ->
val buffer = ByteArray(2048) val buffer = ByteArray(2048)
var bytesRead: Int var bytesRead: Int
while ((inputStream.read(buffer).also { bytesRead = it }) >= 0) { while ((inputStream.read(buffer)
.also { bytesRead = it }) >= 0
) {
stream.write(buffer, 0, bytesRead) stream.write(buffer, 0, bytesRead)
} }
lastSpoofedClientType = clientType lastSpoofedClientType = clientType

View File

@ -121,21 +121,27 @@ public class ReturnYouTubeDislikeApi {
public static long getFetchCallResponseTimeLast() { public static long getFetchCallResponseTimeLast() {
return fetchCallResponseTimeLast; return fetchCallResponseTimeLast;
} }
public static long getFetchCallResponseTimeMin() { public static long getFetchCallResponseTimeMin() {
return fetchCallResponseTimeMin; return fetchCallResponseTimeMin;
} }
public static long getFetchCallResponseTimeMax() { public static long getFetchCallResponseTimeMax() {
return fetchCallResponseTimeMax; return fetchCallResponseTimeMax;
} }
public static long getFetchCallResponseTimeAverage() { public static long getFetchCallResponseTimeAverage() {
return fetchCallCount == 0 ? 0 : (fetchCallResponseTimeTotal / fetchCallCount); return fetchCallCount == 0 ? 0 : (fetchCallResponseTimeTotal / fetchCallCount);
} }
public static int getFetchCallCount() { public static int getFetchCallCount() {
return fetchCallCount; return fetchCallCount;
} }
public static int getFetchCallNumberOfFailures() { public static int getFetchCallNumberOfFailures() {
return fetchCallNumberOfFailures; return fetchCallNumberOfFailures;
} }
public static int getNumberOfRateLimitRequestsEncountered() { public static int getNumberOfRateLimitRequestsEncountered() {
return numberOfRateLimitRequestsEncountered; return numberOfRateLimitRequestsEncountered;
} }

View File

@ -19,7 +19,10 @@ import java.util.concurrent.Future
import java.util.concurrent.TimeUnit import java.util.concurrent.TimeUnit
import java.util.concurrent.TimeoutException import java.util.concurrent.TimeoutException
class MusicRequest private constructor(private val videoId: String, private val checkCategory: Boolean) { class MusicRequest private constructor(
private val videoId: String,
private val checkCategory: Boolean
) {
/** /**
* Time this instance and the fetch future was created. * Time this instance and the fetch future was created.
*/ */
@ -121,7 +124,10 @@ class MusicRequest private constructor(private val videoId: String, private val
Logger.printDebug { "Fetching playlist request for: $videoId using client: $clientTypeName" } Logger.printDebug { "Fetching playlist request for: $videoId using client: $clientTypeName" }
try { try {
val connection = PlayerRoutes.getPlayerResponseConnectionFromRoute(PlayerRoutes.GET_PLAYLIST_PAGE, clientType) val connection = PlayerRoutes.getPlayerResponseConnectionFromRoute(
PlayerRoutes.GET_PLAYLIST_PAGE,
clientType
)
val requestBody = val requestBody =
PlayerRoutes.createApplicationRequestBody(clientType, videoId, "RD$videoId") PlayerRoutes.createApplicationRequestBody(clientType, videoId, "RD$videoId")
@ -158,7 +164,10 @@ class MusicRequest private constructor(private val videoId: String, private val
Logger.printDebug { "Fetching playability request for: $videoId using client: $clientTypeName" } Logger.printDebug { "Fetching playability request for: $videoId using client: $clientTypeName" }
try { try {
val connection = PlayerRoutes.getPlayerResponseConnectionFromRoute(PlayerRoutes.GET_CATEGORY, clientType) val connection = PlayerRoutes.getPlayerResponseConnectionFromRoute(
PlayerRoutes.GET_CATEGORY,
clientType
)
val requestBody = val requestBody =
PlayerRoutes.createWebInnertubeBody(clientType, videoId) PlayerRoutes.createWebInnertubeBody(clientType, videoId)

View File

@ -4,7 +4,6 @@ import android.app.Activity;
import android.content.Context; import android.content.Context;
import android.os.Bundle; import android.os.Bundle;
import android.util.TypedValue; import android.util.TypedValue;
import android.view.View;
import android.view.ViewGroup; import android.view.ViewGroup;
import android.widget.EditText; import android.widget.EditText;
import android.widget.SearchView; import android.widget.SearchView;

View File

@ -30,7 +30,9 @@ internal class JsonPatchesFileGenerator : PatchesFileGenerator {
}, },
) )
}.let { }.let {
patchesJson.writeText(GsonBuilder().serializeNulls().setPrettyPrinting().create().toJson(it)) patchesJson.writeText(
GsonBuilder().serializeNulls().setPrettyPrinting().create().toJson(it)
)
} }
} }

View File

@ -75,7 +75,8 @@ val albumMusicVideoPatch = bytecodePatch(
audioVideoSwitchToggleConstructorFingerprint.methodOrThrow().apply { audioVideoSwitchToggleConstructorFingerprint.methodOrThrow().apply {
val onClickListenerIndex = indexOfAudioVideoSwitchSetOnClickListenerInstruction(this) val onClickListenerIndex = indexOfAudioVideoSwitchSetOnClickListenerInstruction(this)
val viewRegister = getInstruction<FiveRegisterInstruction>(onClickListenerIndex).registerC val viewRegister =
getInstruction<FiveRegisterInstruction>(onClickListenerIndex).registerC
addInstruction( addInstruction(
onClickListenerIndex + 1, onClickListenerIndex + 1,
@ -83,11 +84,13 @@ val albumMusicVideoPatch = bytecodePatch(
"$EXTENSION_CLASS_DESCRIPTOR->setAudioVideoSwitchToggleOnLongClickListener(Landroid/view/View;)V" "$EXTENSION_CLASS_DESCRIPTOR->setAudioVideoSwitchToggleOnLongClickListener(Landroid/view/View;)V"
) )
val onClickListenerSyntheticIndex = indexOfFirstInstructionReversedOrThrow(onClickListenerIndex) { val onClickListenerSyntheticIndex =
opcode == Opcode.INVOKE_DIRECT && indexOfFirstInstructionReversedOrThrow(onClickListenerIndex) {
getReference<MethodReference>()?.name == "<init>" opcode == Opcode.INVOKE_DIRECT &&
} getReference<MethodReference>()?.name == "<init>"
val onClickListenerSyntheticClass = (getInstruction<ReferenceInstruction>(onClickListenerSyntheticIndex).reference as MethodReference).definingClass }
val onClickListenerSyntheticClass =
(getInstruction<ReferenceInstruction>(onClickListenerSyntheticIndex).reference as MethodReference).definingClass
findMethodOrThrow(onClickListenerSyntheticClass) { findMethodOrThrow(onClickListenerSyntheticClass) {
name == "onClick" name == "onClick"

View File

@ -5,11 +5,8 @@ import app.revanced.util.getReference
import app.revanced.util.indexOfFirstInstruction import app.revanced.util.indexOfFirstInstruction
import app.revanced.util.or import app.revanced.util.or
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.iface.Method import com.android.tools.smali.dexlib2.iface.Method
import com.android.tools.smali.dexlib2.iface.reference.MethodReference import com.android.tools.smali.dexlib2.iface.reference.MethodReference
import com.android.tools.smali.dexlib2.iface.reference.StringReference
import com.android.tools.smali.dexlib2.util.MethodUtil
const val GET_GMS_CORE_VENDOR_GROUP_ID_METHOD_NAME = "getGmsCoreVendorGroupId" const val GET_GMS_CORE_VENDOR_GROUP_ID_METHOD_NAME = "getGmsCoreVendorGroupId"

View File

@ -1,19 +1,8 @@
package app.revanced.patches.shared.materialyou package app.revanced.patches.shared.materialyou
import app.revanced.patcher.patch.PatchException
import app.revanced.patcher.patch.ResourcePatchContext import app.revanced.patcher.patch.ResourcePatchContext
import app.revanced.util.copyXmlNode
import app.revanced.util.inputStreamFromBundledResource
import org.w3c.dom.Element import org.w3c.dom.Element
import org.w3c.dom.Node
import java.io.File
import java.nio.file.Files import java.nio.file.Files
import java.nio.file.StandardCopyOption
import javax.xml.parsers.DocumentBuilderFactory
import javax.xml.transform.OutputKeys
import javax.xml.transform.TransformerFactory
import javax.xml.transform.dom.DOMSource
import javax.xml.transform.stream.StreamResult
private fun ResourcePatchContext.patchXmlFile( private fun ResourcePatchContext.patchXmlFile(
fromDir: String, fromDir: String,

View File

@ -116,15 +116,20 @@ fun baseSpoofStreamingDataPatch(
// region Replace the streaming data. // region Replace the streaming data.
val approxDurationMsReference = formatStreamModelConstructorFingerprint.matchOrThrow().let { val approxDurationMsReference = formatStreamModelConstructorFingerprint.matchOrThrow().let {
with (it.method) { with(it.method) {
getInstruction<ReferenceInstruction>(it.patternMatch!!.startIndex).reference getInstruction<ReferenceInstruction>(it.patternMatch!!.startIndex).reference
} }
} }
val streamingDataFormatsReference = with(videoStreamingDataConstructorFingerprint.methodOrThrow(videoStreamingDataToStringFingerprint)) { val streamingDataFormatsReference = with(
videoStreamingDataConstructorFingerprint.methodOrThrow(
videoStreamingDataToStringFingerprint
)
) {
val getFormatsFieldIndex = indexOfGetFormatsFieldInstruction(this) val getFormatsFieldIndex = indexOfGetFormatsFieldInstruction(this)
val longMaxValueIndex = indexOfLongMaxValueInstruction(this, getFormatsFieldIndex) val longMaxValueIndex = indexOfLongMaxValueInstruction(this, getFormatsFieldIndex)
val longMaxValueRegister = getInstruction<OneRegisterInstruction>(longMaxValueIndex).registerA val longMaxValueRegister =
getInstruction<OneRegisterInstruction>(longMaxValueIndex).registerA
val videoIdIndex = val videoIdIndex =
indexOfFirstInstructionOrThrow(longMaxValueIndex) { indexOfFirstInstructionOrThrow(longMaxValueIndex) {
val reference = getReference<FieldReference>() val reference = getReference<FieldReference>()

View File

@ -209,6 +209,10 @@ internal val poTokenToStringFingerprint = legacyFingerprint(
classDef.fields.find { it.type == "[B" } != null && classDef.fields.find { it.type == "[B" } != null &&
// In YouTube, this field's type is 'Lcom/google/android/gms/potokens/PoToken;'. // In YouTube, this field's type is 'Lcom/google/android/gms/potokens/PoToken;'.
// In YouTube Music, this class name is obfuscated. // In YouTube Music, this class name is obfuscated.
classDef.fields.find { it.accessFlags == AccessFlags.PRIVATE.value && it.type.startsWith("L") } != null classDef.fields.find {
it.accessFlags == AccessFlags.PRIVATE.value && it.type.startsWith(
"L"
)
} != null
}, },
) )

View File

@ -342,10 +342,11 @@ val toolBarComponentsPatch = bytecodePatch(
opcode == Opcode.INVOKE_VIRTUAL && opcode == Opcode.INVOKE_VIRTUAL &&
getReference<MethodReference>()?.toString() == voiceInputControllerActivityMethodCall getReference<MethodReference>()?.toString() == voiceInputControllerActivityMethodCall
} }
val setOnClickListenerIndex = indexOfFirstInstructionOrThrow(voiceInputControllerActivityIndex) { val setOnClickListenerIndex =
opcode == Opcode.INVOKE_VIRTUAL && indexOfFirstInstructionOrThrow(voiceInputControllerActivityIndex) {
getReference<MethodReference>()?.name == "setOnClickListener" opcode == Opcode.INVOKE_VIRTUAL &&
} getReference<MethodReference>()?.name == "setOnClickListener"
}
val viewRegister = val viewRegister =
getInstruction<FiveRegisterInstruction>(setOnClickListenerIndex).registerC getInstruction<FiveRegisterInstruction>(setOnClickListenerIndex).registerC

View File

@ -249,7 +249,7 @@ val overlayButtonsPatch = resourcePatch(
) )
val isButton = if (is_19_17_or_greater) val isButton = if (is_19_17_or_greater)
// Note: Do not modify fullscreen button and multiview button // Note: Do not modify fullscreen button and multiview button
id.endsWith("_button") && id != "@id/multiview_button" id.endsWith("_button") && id != "@id/multiview_button"
else else
id.endsWith("_button") || id == "@id/youtube_controls_fullscreen_button_stub" id.endsWith("_button") || id == "@id/youtube_controls_fullscreen_button_stub"

View File

@ -271,7 +271,9 @@ val seekbarComponentsPatch = bytecodePatch(
).forEach { method -> ).forEach { method ->
method.apply { method.apply {
val literalIndex = val literalIndex =
indexOfFirstLiteralInstructionOrThrow(launchScreenLayoutTypeLotteFeatureFlag) indexOfFirstLiteralInstructionOrThrow(
launchScreenLayoutTypeLotteFeatureFlag
)
val resultIndex = val resultIndex =
indexOfFirstInstructionOrThrow(literalIndex, Opcode.MOVE_RESULT) indexOfFirstInstructionOrThrow(literalIndex, Opcode.MOVE_RESULT)
val register = getInstruction<OneRegisterInstruction>(resultIndex).registerA val register = getInstruction<OneRegisterInstruction>(resultIndex).registerA

View File

@ -17,8 +17,9 @@ internal val mainActivityBaseContextHook = extensionHook(
attachBaseContextIndex + 1 attachBaseContextIndex + 1
}, },
contextRegisterResolver = { method -> contextRegisterResolver = { method ->
val overrideInstruction = method.implementation!!.instructions.elementAt(attachBaseContextIndex) val overrideInstruction =
as FiveRegisterInstruction method.implementation!!.instructions.elementAt(attachBaseContextIndex)
as FiveRegisterInstruction
"v${overrideInstruction.registerD}" "v${overrideInstruction.registerD}"
}, },
) { ) {

View File

@ -31,18 +31,21 @@ val fullscreenButtonHookPatch = bytecodePatch(
dependsOn(sharedExtensionPatch) dependsOn(sharedExtensionPatch)
execute { execute {
val (referenceClass, fullscreenActionClass) = with (nextGenWatchLayoutFullscreenModeFingerprint.methodOrThrow()) { val (referenceClass, fullscreenActionClass) = with(
nextGenWatchLayoutFullscreenModeFingerprint.methodOrThrow()
) {
val targetIndex = indexOfFirstInstructionReversedOrThrow { val targetIndex = indexOfFirstInstructionReversedOrThrow {
opcode == Opcode.INVOKE_DIRECT && opcode == Opcode.INVOKE_DIRECT &&
getReference<MethodReference>()?.parameterTypes?.size == 2 getReference<MethodReference>()?.parameterTypes?.size == 2
} }
val targetReference = getInstruction<ReferenceInstruction>(targetIndex).reference as MethodReference val targetReference =
getInstruction<ReferenceInstruction>(targetIndex).reference as MethodReference
Pair(targetReference.definingClass, targetReference.parameterTypes[1].toString()) Pair(targetReference.definingClass, targetReference.parameterTypes[1].toString())
} }
val (enterFullscreenReference, exitFullscreenReference, opcodeName) = val (enterFullscreenReference, exitFullscreenReference, opcodeName) =
with (findMethodOrThrow(referenceClass) { parameters == listOf("I") }) { with(findMethodOrThrow(referenceClass) { parameters == listOf("I") }) {
val enterFullscreenIndex = indexOfFirstInstructionOrThrow { val enterFullscreenIndex = indexOfFirstInstructionOrThrow {
val reference = getReference<MethodReference>() val reference = getReference<MethodReference>()
reference?.returnType == "V" && reference?.returnType == "V" &&
@ -62,7 +65,8 @@ val fullscreenButtonHookPatch = bytecodePatch(
getInstruction<ReferenceInstruction>(exitFullscreenIndex).reference getInstruction<ReferenceInstruction>(exitFullscreenIndex).reference
val opcode = getInstruction(enterFullscreenIndex).opcode val opcode = getInstruction(enterFullscreenIndex).opcode
val enterFullscreenClass = (enterFullscreenReference as MethodReference).definingClass val enterFullscreenClass =
(enterFullscreenReference as MethodReference).definingClass
enterFullscreenMethod = if (opcode == Opcode.INVOKE_INTERFACE) { enterFullscreenMethod = if (opcode == Opcode.INVOKE_INTERFACE) {
classes.find { classDef -> classDef.interfaces.contains(enterFullscreenClass) } classes.find { classDef -> classDef.interfaces.contains(enterFullscreenClass) }