mirror of
https://github.com/revanced/revanced-patches
synced 2024-10-31 08:43:20 +01:00
chore: Merge branch dev
to main
(#3724)
This commit is contained in:
commit
14af4c07bf
5
.github/workflows/open_pull_request.yml
vendored
5
.github/workflows/open_pull_request.yml
vendored
@ -25,7 +25,8 @@ jobs:
|
||||
pr_body: |
|
||||
This pull request will ${{ env.MESSAGE }}.
|
||||
|
||||
## Dependencies before merge
|
||||
## Before merging this PR
|
||||
|
||||
- [ ] https://github.com/revanced/revanced-integrations
|
||||
- [ ] Remember about https://github.com/revanced/revanced-integrations
|
||||
- [ ] Pull translations from Crowdin
|
||||
pr_draft: true
|
||||
|
5
.github/workflows/pull_strings.yml
vendored
5
.github/workflows/pull_strings.yml
vendored
@ -8,6 +8,9 @@ on:
|
||||
jobs:
|
||||
pull:
|
||||
name: Pull strings
|
||||
permissions:
|
||||
contents: write
|
||||
pull-requests: write
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout
|
||||
@ -30,6 +33,6 @@ jobs:
|
||||
github_user_name: revanced-bot
|
||||
github_user_email: github@revanced.app
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.REPOSITORY_PUSH_ACCESS }}
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
CROWDIN_PROJECT_ID: ${{ secrets.CROWDIN_PROJECT_ID }}
|
||||
CROWDIN_PERSONAL_TOKEN: ${{ secrets.CROWDIN_PERSONAL_TOKEN }}
|
||||
|
1
.github/workflows/push_strings.yml
vendored
1
.github/workflows/push_strings.yml
vendored
@ -24,6 +24,5 @@ jobs:
|
||||
config: crowdin.yml
|
||||
upload_sources: true
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.REPOSITORY_PUSH_ACCESS }}
|
||||
CROWDIN_PROJECT_ID: ${{ secrets.CROWDIN_PROJECT_ID }}
|
||||
CROWDIN_PERSONAL_TOKEN: ${{ secrets.CROWDIN_PERSONAL_TOKEN }}
|
||||
|
5
.github/workflows/release.yml
vendored
5
.github/workflows/release.yml
vendored
@ -10,6 +10,9 @@ on:
|
||||
jobs:
|
||||
release:
|
||||
name: Release
|
||||
permissions:
|
||||
contents: write
|
||||
packages: write
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout
|
||||
@ -46,5 +49,5 @@ jobs:
|
||||
|
||||
- name: Release
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.REPOSITORY_PUSH_ACCESS }}
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
run: npm exec semantic-release
|
||||
|
@ -21,11 +21,11 @@
|
||||
"@semantic-release/git",
|
||||
{
|
||||
"assets": [
|
||||
"README.md",
|
||||
"CHANGELOG.md",
|
||||
"gradle.properties",
|
||||
"patches.json"
|
||||
]
|
||||
],
|
||||
"message": "chore: Release v${nextRelease.version} [skip ci]\n\n${nextRelease.notes}"
|
||||
}
|
||||
],
|
||||
[
|
||||
|
100
CHANGELOG.md
100
CHANGELOG.md
@ -1,3 +1,103 @@
|
||||
# [4.17.0-dev.13](https://github.com/ReVanced/revanced-patches/compare/v4.17.0-dev.12...v4.17.0-dev.13) (2024-10-19)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **YouTube - GmsCore support:** Add more replacements ([4d39770](https://github.com/ReVanced/revanced-patches/commit/4d39770602b39b6cb399eb0d8c52947b6ebafbb0))
|
||||
* **YouTube - GmsCore support:** Remove unclear patch changes ([021d858](https://github.com/ReVanced/revanced-patches/commit/021d8584a7f5a6d1a028c5d18dc91a3b988b2884))
|
||||
|
||||
|
||||
### Performance Improvements
|
||||
|
||||
* **YouTube - GmsCore support:** Improve performance by using hashsets ([2c5d390](https://github.com/ReVanced/revanced-patches/commit/2c5d390fb1275dc3da5a3b912e221b7d594a1561))
|
||||
|
||||
# [4.17.0-dev.12](https://github.com/ReVanced/revanced-patches/compare/v4.17.0-dev.11...v4.17.0-dev.12) (2024-10-19)
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* **YouTube - Hide Shorts components:** Hide `Hashtag` button ([#3787](https://github.com/ReVanced/revanced-patches/issues/3787)) ([828a634](https://github.com/ReVanced/revanced-patches/commit/828a634667c4005a90f3e469ad2c5d69387f0760))
|
||||
|
||||
# [4.17.0-dev.11](https://github.com/ReVanced/revanced-patches/compare/v4.17.0-dev.10...v4.17.0-dev.11) (2024-10-19)
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* **YouTube:** Support versions `19.25` and `19.34` ([#3629](https://github.com/ReVanced/revanced-patches/issues/3629)) ([049e7f0](https://github.com/ReVanced/revanced-patches/commit/049e7f081358d2e1bf87d30e87b01c61b5eeafcc))
|
||||
|
||||
# [4.17.0-dev.10](https://github.com/ReVanced/revanced-patches/compare/v4.17.0-dev.9...v4.17.0-dev.10) (2024-10-17)
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* **Facebook:** Add `Hide sponsored stories` patch ([#3627](https://github.com/ReVanced/revanced-patches/issues/3627)) ([214c72b](https://github.com/ReVanced/revanced-patches/commit/214c72baeb7f87f21cd2ca34301ab11fa0ff1a4f))
|
||||
|
||||
# [4.17.0-dev.9](https://github.com/ReVanced/revanced-patches/compare/v4.17.0-dev.8...v4.17.0-dev.9) (2024-10-17)
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* **Sync for Reddit:** Add `Fix video downloads` patch ([#3739](https://github.com/ReVanced/revanced-patches/issues/3739)) ([a47ee38](https://github.com/ReVanced/revanced-patches/commit/a47ee38b1cdd974a959008006ecaf58917addc60))
|
||||
|
||||
# [4.17.0-dev.8](https://github.com/ReVanced/revanced-patches/compare/v4.17.0-dev.7...v4.17.0-dev.8) (2024-10-17)
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* **Twitter:** Add `Change link sharing domain` patch ([#3753](https://github.com/ReVanced/revanced-patches/issues/3753)) ([9269a07](https://github.com/ReVanced/revanced-patches/commit/9269a076b674ecdcf478bca842238f6e30869f44))
|
||||
|
||||
# [4.17.0-dev.7](https://github.com/ReVanced/revanced-patches/compare/v4.17.0-dev.6...v4.17.0-dev.7) (2024-10-17)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **Twitter - Unlock downloads:** Make it work with latest versions ([#3782](https://github.com/ReVanced/revanced-patches/issues/3782)) ([5189122](https://github.com/ReVanced/revanced-patches/commit/5189122006b0f72d5bfb50422021c3b0f3a9ae4a))
|
||||
* **YouTube - Spoof video streams:** Fix playback for Android VR by removing invalid body as well ([#3769](https://github.com/ReVanced/revanced-patches/issues/3769)) ([5150a15](https://github.com/ReVanced/revanced-patches/commit/5150a15ad4ca73a747f0a89f933db7f2d686ec2d))
|
||||
|
||||
# [4.17.0-dev.6](https://github.com/ReVanced/revanced-patches/compare/v4.17.0-dev.5...v4.17.0-dev.6) (2024-10-14)
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* **YouTube - Hide Shorts components:** Add option to hide `Use template`, `Upcoming`, `Green screen` buttons ([#3752](https://github.com/ReVanced/revanced-patches/issues/3752)) ([f71c406](https://github.com/ReVanced/revanced-patches/commit/f71c4068bc646d02954b59fac4756f1419c55dbe))
|
||||
|
||||
# [4.17.0-dev.5](https://github.com/ReVanced/revanced-patches/compare/v4.17.0-dev.4...v4.17.0-dev.5) (2024-10-07)
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* **Backdrops - Pro unlock:** Support latest versions by removing version constraint ([a62b506](https://github.com/ReVanced/revanced-patches/commit/a62b50691c49d1ce529a7c9c4e49da0d0dd46df2))
|
||||
|
||||
# [4.17.0-dev.4](https://github.com/ReVanced/revanced-patches/compare/v4.17.0-dev.3...v4.17.0-dev.4) (2024-10-06)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **YouTube - Hide layout components:** Adjust settings text ([#3745](https://github.com/ReVanced/revanced-patches/issues/3745)) ([13998bb](https://github.com/ReVanced/revanced-patches/commit/13998bbf95ac3cde8bf24754d60258d0ff9bc4f4))
|
||||
|
||||
# [4.17.0-dev.3](https://github.com/ReVanced/revanced-patches/compare/v4.17.0-dev.2...v4.17.0-dev.3) (2024-10-06)
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* **YouTube - Hide layout components:** Add option to hide Yoodles (YouTube Doodles) ([#3743](https://github.com/ReVanced/revanced-patches/issues/3743)) ([b8c8916](https://github.com/ReVanced/revanced-patches/commit/b8c89164cf3911ac3842df9b0d2ec42b52213505))
|
||||
|
||||
# [4.17.0-dev.2](https://github.com/ReVanced/revanced-patches/compare/v4.17.0-dev.1...v4.17.0-dev.2) (2024-10-05)
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* **Willhaben:** Add `Hide ads` patch ([#3740](https://github.com/ReVanced/revanced-patches/issues/3740)) ([1fe3a52](https://github.com/ReVanced/revanced-patches/commit/1fe3a523e99ccfe556d88800686e34ac6ed77b2c))
|
||||
|
||||
# [4.17.0-dev.1](https://github.com/ReVanced/revanced-patches/compare/v4.16.1-dev.1...v4.17.0-dev.1) (2024-10-02)
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* **YouTube - Hide Shorts components:** Add option to hide like fountain ([#3731](https://github.com/ReVanced/revanced-patches/issues/3731)) ([00a99dd](https://github.com/ReVanced/revanced-patches/commit/00a99dd13be6e5c44fa691d74c92b23ce6ba659d))
|
||||
|
||||
## [4.16.1-dev.1](https://github.com/ReVanced/revanced-patches/compare/v4.16.0...v4.16.1-dev.1) (2024-10-01)
|
||||
|
||||
# [4.16.0](https://github.com/ReVanced/revanced-patches/compare/v4.15.0...v4.16.0) (2024-09-30)
|
||||
|
||||
|
||||
|
@ -263,6 +263,12 @@ public final class app/revanced/patches/duolingo/debug/EnableDebugMenuPatch : ap
|
||||
public synthetic fun execute (Lapp/revanced/patcher/data/Context;)V
|
||||
}
|
||||
|
||||
public final class app/revanced/patches/facebook/ads/mainfeed/HideSponsoredStoriesPatch : app/revanced/patcher/patch/BytecodePatch {
|
||||
public static final field INSTANCE Lapp/revanced/patches/facebook/ads/mainfeed/HideSponsoredStoriesPatch;
|
||||
public fun execute (Lapp/revanced/patcher/data/BytecodeContext;)V
|
||||
public synthetic fun execute (Lapp/revanced/patcher/data/Context;)V
|
||||
}
|
||||
|
||||
public final class app/revanced/patches/facebook/ads/story/HideStoryAdsPatch : app/revanced/patcher/patch/BytecodePatch {
|
||||
public static final field INSTANCE Lapp/revanced/patches/facebook/ads/story/HideStoryAdsPatch;
|
||||
public fun execute (Lapp/revanced/patcher/data/BytecodeContext;)V
|
||||
@ -840,6 +846,12 @@ public final class app/revanced/patches/reddit/customclients/syncforreddit/fix/u
|
||||
public synthetic fun execute (Lapp/revanced/patcher/data/Context;)V
|
||||
}
|
||||
|
||||
public final class app/revanced/patches/reddit/customclients/syncforreddit/fix/video/FixVideoDownloadsPatch : app/revanced/patcher/patch/BytecodePatch {
|
||||
public static final field INSTANCE Lapp/revanced/patches/reddit/customclients/syncforreddit/fix/video/FixVideoDownloadsPatch;
|
||||
public fun execute (Lapp/revanced/patcher/data/BytecodeContext;)V
|
||||
public synthetic fun execute (Lapp/revanced/patcher/data/Context;)V
|
||||
}
|
||||
|
||||
public final class app/revanced/patches/reddit/customclients/syncforreddit/misc/integrations/IntegrationsPatch : app/revanced/patches/shared/misc/integrations/BaseIntegrationsPatch {
|
||||
public static final field INSTANCE Lapp/revanced/patches/reddit/customclients/syncforreddit/misc/integrations/IntegrationsPatch;
|
||||
}
|
||||
@ -1490,6 +1502,12 @@ public final class app/revanced/patches/twitter/misc/hook/patch/recommendation/H
|
||||
public static final field INSTANCE Lapp/revanced/patches/twitter/misc/hook/patch/recommendation/HideRecommendedUsersPatch;
|
||||
}
|
||||
|
||||
public final class app/revanced/patches/twitter/misc/links/ChangeLinkSharingDomainPatch : app/revanced/patcher/patch/BytecodePatch {
|
||||
public static final field INSTANCE Lapp/revanced/patches/twitter/misc/links/ChangeLinkSharingDomainPatch;
|
||||
public fun execute (Lapp/revanced/patcher/data/BytecodeContext;)V
|
||||
public synthetic fun execute (Lapp/revanced/patcher/data/Context;)V
|
||||
}
|
||||
|
||||
public final class app/revanced/patches/twitter/misc/links/OpenLinksWithAppChooserPatch : app/revanced/patcher/patch/BytecodePatch {
|
||||
public static final field INSTANCE Lapp/revanced/patches/twitter/misc/links/OpenLinksWithAppChooserPatch;
|
||||
public fun execute (Lapp/revanced/patcher/data/BytecodeContext;)V
|
||||
@ -1520,6 +1538,12 @@ public final class app/revanced/patches/warnwetter/misc/promocode/PromoCodeUnloc
|
||||
public synthetic fun execute (Lapp/revanced/patcher/data/Context;)V
|
||||
}
|
||||
|
||||
public final class app/revanced/patches/willhaben/ads/HideAdsPatch : app/revanced/patcher/patch/BytecodePatch {
|
||||
public static final field INSTANCE Lapp/revanced/patches/willhaben/ads/HideAdsPatch;
|
||||
public fun execute (Lapp/revanced/patcher/data/BytecodeContext;)V
|
||||
public synthetic fun execute (Lapp/revanced/patcher/data/Context;)V
|
||||
}
|
||||
|
||||
public final class app/revanced/patches/windyapp/misc/unlockpro/UnlockProPatch : app/revanced/patcher/patch/BytecodePatch {
|
||||
public static final field INSTANCE Lapp/revanced/patches/windyapp/misc/unlockpro/UnlockProPatch;
|
||||
public fun execute (Lapp/revanced/patcher/data/BytecodeContext;)V
|
||||
@ -1826,10 +1850,6 @@ public final class app/revanced/patches/youtube/layout/startpage/ChangeStartPage
|
||||
public synthetic fun execute (Lapp/revanced/patcher/data/Context;)V
|
||||
}
|
||||
|
||||
public final class app/revanced/patches/youtube/layout/startpage/fingerprints/StartActivityFingerprint : app/revanced/patcher/fingerprint/MethodFingerprint {
|
||||
public static final field INSTANCE Lapp/revanced/patches/youtube/layout/startpage/fingerprints/StartActivityFingerprint;
|
||||
}
|
||||
|
||||
public final class app/revanced/patches/youtube/layout/startupshortsreset/DisableResumingShortsOnStartupPatch : app/revanced/patcher/patch/BytecodePatch {
|
||||
public static final field INSTANCE Lapp/revanced/patches/youtube/layout/startupshortsreset/DisableResumingShortsOnStartupPatch;
|
||||
public fun execute (Lapp/revanced/patcher/data/BytecodeContext;)V
|
||||
@ -2178,12 +2198,28 @@ public final class app/revanced/util/BytecodeUtilsKt {
|
||||
public static final fun containsWideLiteralInstructionValue (Lcom/android/tools/smali/dexlib2/iface/Method;J)Z
|
||||
public static final fun findMutableMethodOf (Lapp/revanced/patcher/util/proxy/mutableTypes/MutableClass;Lcom/android/tools/smali/dexlib2/iface/Method;)Lapp/revanced/patcher/util/proxy/mutableTypes/MutableMethod;
|
||||
public static final fun findOpcodeIndicesReversed (Lcom/android/tools/smali/dexlib2/iface/Method;Lcom/android/tools/smali/dexlib2/Opcode;)Ljava/util/List;
|
||||
public static final fun findOpcodeIndicesReversed (Lcom/android/tools/smali/dexlib2/iface/Method;Lkotlin/jvm/functions/Function1;)Ljava/util/List;
|
||||
public static final fun forEachLiteralValueInstruction (Lapp/revanced/patcher/data/BytecodeContext;JLkotlin/jvm/functions/Function2;)V
|
||||
public static final fun getException (Lapp/revanced/patcher/fingerprint/MethodFingerprint;)Lapp/revanced/patcher/patch/PatchException;
|
||||
public static final fun indexOfFirstInstruction (Lcom/android/tools/smali/dexlib2/iface/Method;ILcom/android/tools/smali/dexlib2/Opcode;)I
|
||||
public static final fun indexOfFirstInstruction (Lcom/android/tools/smali/dexlib2/iface/Method;ILkotlin/jvm/functions/Function1;)I
|
||||
public static final fun indexOfFirstInstruction (Lcom/android/tools/smali/dexlib2/iface/Method;Lcom/android/tools/smali/dexlib2/Opcode;)I
|
||||
public static final fun indexOfFirstInstruction (Lcom/android/tools/smali/dexlib2/iface/Method;Lkotlin/jvm/functions/Function1;)I
|
||||
public static synthetic fun indexOfFirstInstruction$default (Lcom/android/tools/smali/dexlib2/iface/Method;ILcom/android/tools/smali/dexlib2/Opcode;ILjava/lang/Object;)I
|
||||
public static synthetic fun indexOfFirstInstruction$default (Lcom/android/tools/smali/dexlib2/iface/Method;ILkotlin/jvm/functions/Function1;ILjava/lang/Object;)I
|
||||
public static final fun indexOfFirstInstructionOrThrow (Lcom/android/tools/smali/dexlib2/iface/Method;ILcom/android/tools/smali/dexlib2/Opcode;)I
|
||||
public static final fun indexOfFirstInstructionOrThrow (Lcom/android/tools/smali/dexlib2/iface/Method;ILkotlin/jvm/functions/Function1;)I
|
||||
public static final fun indexOfFirstInstructionOrThrow (Lcom/android/tools/smali/dexlib2/iface/Method;Lcom/android/tools/smali/dexlib2/Opcode;)I
|
||||
public static synthetic fun indexOfFirstInstructionOrThrow$default (Lcom/android/tools/smali/dexlib2/iface/Method;ILcom/android/tools/smali/dexlib2/Opcode;ILjava/lang/Object;)I
|
||||
public static synthetic fun indexOfFirstInstructionOrThrow$default (Lcom/android/tools/smali/dexlib2/iface/Method;ILkotlin/jvm/functions/Function1;ILjava/lang/Object;)I
|
||||
public static final fun indexOfFirstInstructionReversed (Lcom/android/tools/smali/dexlib2/iface/Method;Ljava/lang/Integer;Lcom/android/tools/smali/dexlib2/Opcode;)I
|
||||
public static final fun indexOfFirstInstructionReversed (Lcom/android/tools/smali/dexlib2/iface/Method;Ljava/lang/Integer;Lkotlin/jvm/functions/Function1;)I
|
||||
public static synthetic fun indexOfFirstInstructionReversed$default (Lcom/android/tools/smali/dexlib2/iface/Method;Ljava/lang/Integer;Lcom/android/tools/smali/dexlib2/Opcode;ILjava/lang/Object;)I
|
||||
public static synthetic fun indexOfFirstInstructionReversed$default (Lcom/android/tools/smali/dexlib2/iface/Method;Ljava/lang/Integer;Lkotlin/jvm/functions/Function1;ILjava/lang/Object;)I
|
||||
public static final fun indexOfFirstInstructionReversedOrThrow (Lcom/android/tools/smali/dexlib2/iface/Method;Ljava/lang/Integer;Lcom/android/tools/smali/dexlib2/Opcode;)I
|
||||
public static final fun indexOfFirstInstructionReversedOrThrow (Lcom/android/tools/smali/dexlib2/iface/Method;Ljava/lang/Integer;Lkotlin/jvm/functions/Function1;)I
|
||||
public static synthetic fun indexOfFirstInstructionReversedOrThrow$default (Lcom/android/tools/smali/dexlib2/iface/Method;Ljava/lang/Integer;Lcom/android/tools/smali/dexlib2/Opcode;ILjava/lang/Object;)I
|
||||
public static synthetic fun indexOfFirstInstructionReversedOrThrow$default (Lcom/android/tools/smali/dexlib2/iface/Method;Ljava/lang/Integer;Lkotlin/jvm/functions/Function1;ILjava/lang/Object;)I
|
||||
public static final fun indexOfFirstWideLiteralInstructionValue (Lcom/android/tools/smali/dexlib2/iface/Method;J)I
|
||||
public static final fun indexOfFirstWideLiteralInstructionValueOrThrow (Lcom/android/tools/smali/dexlib2/iface/Method;J)I
|
||||
public static final fun indexOfFirstWideLiteralInstructionValueReversed (Lcom/android/tools/smali/dexlib2/iface/Method;J)I
|
||||
|
@ -1,4 +1,4 @@
|
||||
org.gradle.parallel = true
|
||||
org.gradle.caching = true
|
||||
kotlin.code.style = official
|
||||
version = 4.16.0
|
||||
version = 4.17.0-dev.13
|
||||
|
321
package-lock.json
generated
321
package-lock.json
generated
@ -8,8 +8,8 @@
|
||||
"@saithodev/semantic-release-backmerge": "^4.0.1",
|
||||
"@semantic-release/changelog": "^6.0.3",
|
||||
"@semantic-release/git": "^10.0.1",
|
||||
"gradle-semantic-release-plugin": "^1.9.2",
|
||||
"semantic-release": "^24.0.0"
|
||||
"gradle-semantic-release-plugin": "^1.10.1",
|
||||
"semantic-release": "^24.1.2"
|
||||
}
|
||||
},
|
||||
"node_modules/@babel/code-frame": {
|
||||
@ -235,13 +235,13 @@
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/@octokit/plugin-paginate-rest": {
|
||||
"version": "11.3.3",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/plugin-paginate-rest/-/plugin-paginate-rest-11.3.3.tgz",
|
||||
"integrity": "sha512-o4WRoOJZlKqEEgj+i9CpcmnByvtzoUYC6I8PD2SA95M+BJ2x8h7oLcVOg9qcowWXBOdcTRsMZiwvM3EyLm9AfA==",
|
||||
"version": "11.3.5",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/plugin-paginate-rest/-/plugin-paginate-rest-11.3.5.tgz",
|
||||
"integrity": "sha512-cgwIRtKrpwhLoBi0CUNuY83DPGRMaWVjqVI/bGKsLJ4PzyWZNaEmhHroI2xlrVXkk6nFv0IsZpOp+ZWSWUS2AQ==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@octokit/types": "^13.5.0"
|
||||
"@octokit/types": "^13.6.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 18"
|
||||
@ -251,9 +251,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@octokit/plugin-retry": {
|
||||
"version": "7.1.1",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/plugin-retry/-/plugin-retry-7.1.1.tgz",
|
||||
"integrity": "sha512-G9Ue+x2odcb8E1XIPhaFBnTTIrrUDfXN05iFXiqhR+SeeeDMMILcAnysOsxUpEWcQp2e5Ft397FCXTcPkiPkLw==",
|
||||
"version": "7.1.2",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/plugin-retry/-/plugin-retry-7.1.2.tgz",
|
||||
"integrity": "sha512-XOWnPpH2kJ5VTwozsxGurw+svB2e61aWlmk5EVIYZPwFK5F9h4cyPyj9CIKRyMXMHSwpIsI3mPOdpMmrRhe7UQ==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
@ -302,9 +302,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@octokit/request-error": {
|
||||
"version": "6.1.4",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/request-error/-/request-error-6.1.4.tgz",
|
||||
"integrity": "sha512-VpAhIUxwhWZQImo/dWAN/NpPqqojR6PSLgLYAituLM6U+ddx9hCioFGwBr5Mi+oi5CLeJkcAs3gJ0PYYzU6wUg==",
|
||||
"version": "6.1.5",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/request-error/-/request-error-6.1.5.tgz",
|
||||
"integrity": "sha512-IlBTfGX8Yn/oFPMwSfvugfncK2EwRLjzbrpifNaMY8o/HTEAFqCA1FZxjD9cWvSKBHgrIhc4CSBIzMxiLsbzFQ==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
@ -315,9 +315,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@octokit/types": {
|
||||
"version": "13.5.0",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/types/-/types-13.5.0.tgz",
|
||||
"integrity": "sha512-HdqWTf5Z3qwDVlzCrP8UJquMwunpDiMPt5er+QjGzL4hqr/vBVY/MauQgS1xWxCDT1oMx1EULyqxncdCY/NVSQ==",
|
||||
"version": "13.6.0",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/types/-/types-13.6.0.tgz",
|
||||
"integrity": "sha512-CrooV/vKCXqwLa+osmHLIMUb87brpgUqlqkPGc6iE2wCkUvTrHiXFMhAKoDDaAAYJrtKtrFTgSQTg5nObBEaew==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
@ -355,9 +355,9 @@
|
||||
"license": "ISC"
|
||||
},
|
||||
"node_modules/@pnpm/npm-conf": {
|
||||
"version": "2.2.2",
|
||||
"resolved": "https://registry.npmjs.org/@pnpm/npm-conf/-/npm-conf-2.2.2.tgz",
|
||||
"integrity": "sha512-UA91GwWPhFExt3IizW6bOeY/pQ0BkuNwKjk9iQW9KqxluGCrg4VenZ0/L+2Y0+ZOtme72EVvg6v0zo3AMQRCeA==",
|
||||
"version": "2.3.1",
|
||||
"resolved": "https://registry.npmjs.org/@pnpm/npm-conf/-/npm-conf-2.3.1.tgz",
|
||||
"integrity": "sha512-c83qWb22rNRuB0UaVCI0uRPNRr8Z0FWnEIvT47jiHAmOIUHbBOg5XvV7pM5x+rKn9HRpjxquDbXYSXr3fAKFcw==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
@ -977,6 +977,19 @@
|
||||
"url": "https://github.com/sponsors/sindresorhus"
|
||||
}
|
||||
},
|
||||
"node_modules/@saithodev/semantic-release-backmerge/node_modules/hosted-git-info": {
|
||||
"version": "7.0.2",
|
||||
"resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-7.0.2.tgz",
|
||||
"integrity": "sha512-puUZAUKT5m8Zzvs72XWy3HtvVbTWljRE66cP60bxJzAqf2DgICo7lYTY2IHUmLnNpjYvw5bvmoHvPc0QO2a62w==",
|
||||
"dev": true,
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"lru-cache": "^10.0.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": "^16.14.0 || >=18.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@saithodev/semantic-release-backmerge/node_modules/human-signals": {
|
||||
"version": "5.0.0",
|
||||
"resolved": "https://registry.npmjs.org/human-signals/-/human-signals-5.0.0.tgz",
|
||||
@ -1372,9 +1385,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@semantic-release/github": {
|
||||
"version": "10.1.1",
|
||||
"resolved": "https://registry.npmjs.org/@semantic-release/github/-/github-10.1.1.tgz",
|
||||
"integrity": "sha512-sSmsBKGpAlTtXf9rUJf/si16p+FwPEsvsJRjl3KCwFP0WywaSpynvUhlYvE18n5rzkQNbGJnObAKIoo3xFMSjA==",
|
||||
"version": "11.0.0",
|
||||
"resolved": "https://registry.npmjs.org/@semantic-release/github/-/github-11.0.0.tgz",
|
||||
"integrity": "sha512-Uon6G6gJD8U1JNvPm7X0j46yxNRJ8Ui6SgK4Zw5Ktu8RgjEft3BGn+l/RX1TTzhhO3/uUcKuqM+/9/ETFxWS/Q==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
@ -1399,7 +1412,7 @@
|
||||
"node": ">=20.8.1"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"semantic-release": ">=20.1.0"
|
||||
"semantic-release": ">=24.1.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@semantic-release/github/node_modules/@semantic-release/error": {
|
||||
@ -1569,9 +1582,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@semantic-release/npm/node_modules/execa": {
|
||||
"version": "9.3.0",
|
||||
"resolved": "https://registry.npmjs.org/execa/-/execa-9.3.0.tgz",
|
||||
"integrity": "sha512-l6JFbqnHEadBoVAVpN5dl2yCyfX28WoBAGaoQcNmLLSedOxTxcn2Qa83s8I/PA5i56vWru2OHOtrwF7Om2vqlg==",
|
||||
"version": "9.4.0",
|
||||
"resolved": "https://registry.npmjs.org/execa/-/execa-9.4.0.tgz",
|
||||
"integrity": "sha512-yKHlle2YGxZE842MERVIplWwNH5VYmqqcPFgtnlU//K8gxuFFXu0pwd/CrfXTumFpeEiufsP7+opT/bPJa1yVw==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
@ -1579,10 +1592,10 @@
|
||||
"cross-spawn": "^7.0.3",
|
||||
"figures": "^6.1.0",
|
||||
"get-stream": "^9.0.0",
|
||||
"human-signals": "^7.0.0",
|
||||
"human-signals": "^8.0.0",
|
||||
"is-plain-obj": "^4.1.0",
|
||||
"is-stream": "^4.0.1",
|
||||
"npm-run-path": "^5.2.0",
|
||||
"npm-run-path": "^6.0.0",
|
||||
"pretty-ms": "^9.0.0",
|
||||
"signal-exit": "^4.1.0",
|
||||
"strip-final-newline": "^4.0.0",
|
||||
@ -1613,9 +1626,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@semantic-release/npm/node_modules/human-signals": {
|
||||
"version": "7.0.0",
|
||||
"resolved": "https://registry.npmjs.org/human-signals/-/human-signals-7.0.0.tgz",
|
||||
"integrity": "sha512-74kytxOUSvNbjrT9KisAbaTZ/eJwD/LrbM/kh5j0IhPuJzwuA19dWvniFGwBzN9rVjg+O/e+F310PjObDXS+9Q==",
|
||||
"version": "8.0.0",
|
||||
"resolved": "https://registry.npmjs.org/human-signals/-/human-signals-8.0.0.tgz",
|
||||
"integrity": "sha512-/1/GPCpDUCCYwlERiYjxoczfP0zfvZMU/OWgQPMya9AbAE24vseigFdhAMObpc8Q4lc/kjutPfUddDYyAmejnA==",
|
||||
"dev": true,
|
||||
"license": "Apache-2.0",
|
||||
"engines": {
|
||||
@ -1649,16 +1662,17 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@semantic-release/npm/node_modules/npm-run-path": {
|
||||
"version": "5.3.0",
|
||||
"resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-5.3.0.tgz",
|
||||
"integrity": "sha512-ppwTtiJZq0O/ai0z7yfudtBpWIoxM8yE6nHi1X47eFR2EWORqfbu6CnPlNsjeN683eT0qG6H/Pyf9fCcvjnnnQ==",
|
||||
"version": "6.0.0",
|
||||
"resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-6.0.0.tgz",
|
||||
"integrity": "sha512-9qny7Z9DsQU8Ou39ERsPU4OZQlSTP47ShQzuKZ6PRXpYLtIFgl/DEBYEXKlvcEa+9tHVcK8CF81Y2V72qaZhWA==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"path-key": "^4.0.0"
|
||||
"path-key": "^4.0.0",
|
||||
"unicorn-magic": "^0.3.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": "^12.20.0 || ^14.13.1 || >=16.0.0"
|
||||
"node": ">=18"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/sindresorhus"
|
||||
@ -1703,6 +1717,19 @@
|
||||
"url": "https://github.com/sponsors/sindresorhus"
|
||||
}
|
||||
},
|
||||
"node_modules/@semantic-release/npm/node_modules/unicorn-magic": {
|
||||
"version": "0.3.0",
|
||||
"resolved": "https://registry.npmjs.org/unicorn-magic/-/unicorn-magic-0.3.0.tgz",
|
||||
"integrity": "sha512-+QBBXBCvifc56fsbuxZQ6Sic3wqqc3WWaqxs58gvJrcOuN83HGTCwz3oS5phzU9LthRNE9VrJCFCLUgHeeFnfA==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/sindresorhus"
|
||||
}
|
||||
},
|
||||
"node_modules/@semantic-release/release-notes-generator": {
|
||||
"version": "14.0.1",
|
||||
"resolved": "https://registry.npmjs.org/@semantic-release/release-notes-generator/-/release-notes-generator-14.0.1.tgz",
|
||||
@ -2273,13 +2300,13 @@
|
||||
}
|
||||
},
|
||||
"node_modules/debug": {
|
||||
"version": "4.3.5",
|
||||
"resolved": "https://registry.npmjs.org/debug/-/debug-4.3.5.tgz",
|
||||
"integrity": "sha512-pt0bNEmneDIvdL1Xsd9oDQ/wrQRkXDT4AUWlNZNPKvW5x/jyO9VFXkJUP07vQ2upmw5PlaITaPKc31jK13V+jg==",
|
||||
"version": "4.3.7",
|
||||
"resolved": "https://registry.npmjs.org/debug/-/debug-4.3.7.tgz",
|
||||
"integrity": "sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"ms": "2.1.2"
|
||||
"ms": "^2.1.3"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=6.0"
|
||||
@ -2358,9 +2385,9 @@
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/env-ci": {
|
||||
"version": "11.0.0",
|
||||
"resolved": "https://registry.npmjs.org/env-ci/-/env-ci-11.0.0.tgz",
|
||||
"integrity": "sha512-apikxMgkipkgTvMdRT9MNqWx5VLOci79F4VBd7Op/7OPjjoanjdAvn6fglMCCEf/1bAh8eOiuEVCUs4V3qP3nQ==",
|
||||
"version": "11.1.0",
|
||||
"resolved": "https://registry.npmjs.org/env-ci/-/env-ci-11.1.0.tgz",
|
||||
"integrity": "sha512-Z8dnwSDbV1XYM9SBF2J0GcNVvmfmfh3a49qddGIROhBoVro6MZVTji15z/sJbQ2ko2ei8n988EU1wzoLU/tF+g==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
@ -2549,9 +2576,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/escalade": {
|
||||
"version": "3.1.2",
|
||||
"resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.2.tgz",
|
||||
"integrity": "sha512-ErCHMCae19vR8vQGe50xIsVomy19rg6gFu3+r3jkEO46suLMWBksvVyoGgQV+jOfl84ZSOSlmv6Gxa89PmTGmA==",
|
||||
"version": "3.2.0",
|
||||
"resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz",
|
||||
"integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
@ -2847,9 +2874,9 @@
|
||||
"license": "ISC"
|
||||
},
|
||||
"node_modules/gradle-semantic-release-plugin": {
|
||||
"version": "1.9.2",
|
||||
"resolved": "https://registry.npmjs.org/gradle-semantic-release-plugin/-/gradle-semantic-release-plugin-1.9.2.tgz",
|
||||
"integrity": "sha512-8qpf4GYFPQ+UMUymYBy/VchOOwLILAWzZMrZX1R0RR3JMgJBMN2R0tJn92R/3rXmxx4OAqwUFH6Np51eFoxr3w==",
|
||||
"version": "1.10.1",
|
||||
"resolved": "https://registry.npmjs.org/gradle-semantic-release-plugin/-/gradle-semantic-release-plugin-1.10.1.tgz",
|
||||
"integrity": "sha512-Q4dLAFICjPouUyRRHEKK8cXNB75nraXoioYZDZlVQOg4sYKudnTDZ3ohLmV3k4cPGiiMCh1ckXETkx9JnuyKmA==",
|
||||
"dev": true,
|
||||
"funding": [
|
||||
{
|
||||
@ -2925,16 +2952,16 @@
|
||||
}
|
||||
},
|
||||
"node_modules/hosted-git-info": {
|
||||
"version": "7.0.2",
|
||||
"resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-7.0.2.tgz",
|
||||
"integrity": "sha512-puUZAUKT5m8Zzvs72XWy3HtvVbTWljRE66cP60bxJzAqf2DgICo7lYTY2IHUmLnNpjYvw5bvmoHvPc0QO2a62w==",
|
||||
"version": "8.0.0",
|
||||
"resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-8.0.0.tgz",
|
||||
"integrity": "sha512-4nw3vOVR+vHUOT8+U4giwe2tcGv+R3pwwRidUe67DoMBTjhrfr6rZYJVVwdkBE+Um050SG+X9tf0Jo4fOpn01w==",
|
||||
"dev": true,
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"lru-cache": "^10.0.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": "^16.14.0 || >=18.0.0"
|
||||
"node": "^18.17.0 || >=20.5.0"
|
||||
}
|
||||
},
|
||||
"node_modules/http-proxy-agent": {
|
||||
@ -2976,9 +3003,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/ignore": {
|
||||
"version": "5.3.1",
|
||||
"resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.1.tgz",
|
||||
"integrity": "sha512-5Fytz/IraMjqpwfd34ke28PTVMjZjJG2MPn5t7OE4eUCUNf8BAa7b5WUS9/Qvr6mwOQS7Mk6vdsMno5he+T8Xw==",
|
||||
"version": "5.3.2",
|
||||
"resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz",
|
||||
"integrity": "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
@ -3191,9 +3218,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/is-unicode-supported": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-2.0.0.tgz",
|
||||
"integrity": "sha512-FRdAyx5lusK1iHG0TWpVtk9+1i+GjrzRffhDg4ovQ7mcidMQ6mj+MhKPmvh7Xwyv5gIS06ns49CA7Sqg7lC22Q==",
|
||||
"version": "2.1.0",
|
||||
"resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-2.1.0.tgz",
|
||||
"integrity": "sha512-mE00Gnza5EEB3Ds0HfMyllZzbBrmLOX3vfWoj9A9PEnTfratQ/BcaJOuMhnkhjXvb2+FkY3VuHqtAGpTPmglFQ==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
@ -3497,9 +3524,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/micromatch": {
|
||||
"version": "4.0.7",
|
||||
"resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.7.tgz",
|
||||
"integrity": "sha512-LPP/3KorzCwBxfeUuZmaR6bG2kdeHSbe0P2tY3FLRU4vYrjYz5hI4QZwV0njUx3jeuKe67YukQ1LSPZBKDqO/Q==",
|
||||
"version": "4.0.8",
|
||||
"resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz",
|
||||
"integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
@ -3547,9 +3574,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/ms": {
|
||||
"version": "2.1.2",
|
||||
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
|
||||
"integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==",
|
||||
"version": "2.1.3",
|
||||
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
|
||||
"integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==",
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
@ -3610,6 +3637,19 @@
|
||||
"node": "^16.14.0 || >=18.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/normalize-package-data/node_modules/hosted-git-info": {
|
||||
"version": "7.0.2",
|
||||
"resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-7.0.2.tgz",
|
||||
"integrity": "sha512-puUZAUKT5m8Zzvs72XWy3HtvVbTWljRE66cP60bxJzAqf2DgICo7lYTY2IHUmLnNpjYvw5bvmoHvPc0QO2a62w==",
|
||||
"dev": true,
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"lru-cache": "^10.0.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": "^16.14.0 || >=18.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/normalize-url": {
|
||||
"version": "8.0.1",
|
||||
"resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-8.0.1.tgz",
|
||||
@ -3624,9 +3664,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/npm": {
|
||||
"version": "10.8.2",
|
||||
"resolved": "https://registry.npmjs.org/npm/-/npm-10.8.2.tgz",
|
||||
"integrity": "sha512-x/AIjFIKRllrhcb48dqUNAAZl0ig9+qMuN91RpZo3Cb2+zuibfh+KISl6+kVVyktDz230JKc208UkQwwMqyB+w==",
|
||||
"version": "10.8.3",
|
||||
"resolved": "https://registry.npmjs.org/npm/-/npm-10.8.3.tgz",
|
||||
"integrity": "sha512-0IQlyAYvVtQ7uOhDFYZCGK8kkut2nh8cpAdA9E6FvRSJaTgtZRZgNjlC5ZCct//L73ygrpY93CxXpRJDtNqPVg==",
|
||||
"bundleDependencies": [
|
||||
"@isaacs/string-locale-compare",
|
||||
"@npmcli/arborist",
|
||||
@ -3719,13 +3759,13 @@
|
||||
"@sigstore/tuf": "^2.3.4",
|
||||
"abbrev": "^2.0.0",
|
||||
"archy": "~1.0.0",
|
||||
"cacache": "^18.0.3",
|
||||
"cacache": "^18.0.4",
|
||||
"chalk": "^5.3.0",
|
||||
"ci-info": "^4.0.0",
|
||||
"cli-columns": "^4.0.0",
|
||||
"fastest-levenshtein": "^1.0.16",
|
||||
"fs-minipass": "^3.0.3",
|
||||
"glob": "^10.4.2",
|
||||
"glob": "^10.4.5",
|
||||
"graceful-fs": "^4.2.11",
|
||||
"hosted-git-info": "^7.0.2",
|
||||
"ini": "^4.1.3",
|
||||
@ -3734,7 +3774,7 @@
|
||||
"json-parse-even-better-errors": "^3.0.2",
|
||||
"libnpmaccess": "^8.0.6",
|
||||
"libnpmdiff": "^6.1.4",
|
||||
"libnpmexec": "^8.1.3",
|
||||
"libnpmexec": "^8.1.4",
|
||||
"libnpmfund": "^5.0.12",
|
||||
"libnpmhook": "^10.0.5",
|
||||
"libnpmorg": "^6.0.6",
|
||||
@ -3748,12 +3788,12 @@
|
||||
"minipass": "^7.1.1",
|
||||
"minipass-pipeline": "^1.2.4",
|
||||
"ms": "^2.1.2",
|
||||
"node-gyp": "^10.1.0",
|
||||
"node-gyp": "^10.2.0",
|
||||
"nopt": "^7.2.1",
|
||||
"normalize-package-data": "^6.0.2",
|
||||
"npm-audit-report": "^5.0.0",
|
||||
"npm-install-checks": "^6.3.0",
|
||||
"npm-package-arg": "^11.0.2",
|
||||
"npm-package-arg": "^11.0.3",
|
||||
"npm-pick-manifest": "^9.1.0",
|
||||
"npm-profile": "^10.0.0",
|
||||
"npm-registry-fetch": "^17.1.0",
|
||||
@ -3764,7 +3804,7 @@
|
||||
"proc-log": "^4.2.0",
|
||||
"qrcode-terminal": "^0.12.0",
|
||||
"read": "^3.0.1",
|
||||
"semver": "^7.6.2",
|
||||
"semver": "^7.6.3",
|
||||
"spdx-expression-parse": "^4.0.0",
|
||||
"ssri": "^10.0.6",
|
||||
"supports-color": "^9.4.0",
|
||||
@ -4335,7 +4375,7 @@
|
||||
}
|
||||
},
|
||||
"node_modules/npm/node_modules/cacache": {
|
||||
"version": "18.0.3",
|
||||
"version": "18.0.4",
|
||||
"dev": true,
|
||||
"inBundle": true,
|
||||
"license": "ISC",
|
||||
@ -4502,7 +4542,7 @@
|
||||
}
|
||||
},
|
||||
"node_modules/npm/node_modules/debug": {
|
||||
"version": "4.3.5",
|
||||
"version": "4.3.6",
|
||||
"dev": true,
|
||||
"inBundle": true,
|
||||
"license": "MIT",
|
||||
@ -4586,7 +4626,7 @@
|
||||
}
|
||||
},
|
||||
"node_modules/npm/node_modules/foreground-child": {
|
||||
"version": "3.2.1",
|
||||
"version": "3.3.0",
|
||||
"dev": true,
|
||||
"inBundle": true,
|
||||
"license": "ISC",
|
||||
@ -4614,7 +4654,7 @@
|
||||
}
|
||||
},
|
||||
"node_modules/npm/node_modules/glob": {
|
||||
"version": "10.4.2",
|
||||
"version": "10.4.5",
|
||||
"dev": true,
|
||||
"inBundle": true,
|
||||
"license": "ISC",
|
||||
@ -4629,9 +4669,6 @@
|
||||
"bin": {
|
||||
"glob": "dist/esm/bin.mjs"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=16 || 14 >=14.18"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/isaacs"
|
||||
}
|
||||
@ -4815,16 +4852,13 @@
|
||||
"license": "ISC"
|
||||
},
|
||||
"node_modules/npm/node_modules/jackspeak": {
|
||||
"version": "3.4.0",
|
||||
"version": "3.4.3",
|
||||
"dev": true,
|
||||
"inBundle": true,
|
||||
"license": "BlueOak-1.0.0",
|
||||
"dependencies": {
|
||||
"@isaacs/cliui": "^8.0.2"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=14"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/isaacs"
|
||||
},
|
||||
@ -4910,7 +4944,7 @@
|
||||
}
|
||||
},
|
||||
"node_modules/npm/node_modules/libnpmexec": {
|
||||
"version": "8.1.3",
|
||||
"version": "8.1.4",
|
||||
"dev": true,
|
||||
"inBundle": true,
|
||||
"license": "ISC",
|
||||
@ -5044,13 +5078,10 @@
|
||||
}
|
||||
},
|
||||
"node_modules/npm/node_modules/lru-cache": {
|
||||
"version": "10.2.2",
|
||||
"version": "10.4.3",
|
||||
"dev": true,
|
||||
"inBundle": true,
|
||||
"license": "ISC",
|
||||
"engines": {
|
||||
"node": "14 || >=16.14"
|
||||
}
|
||||
"license": "ISC"
|
||||
},
|
||||
"node_modules/npm/node_modules/make-fetch-happen": {
|
||||
"version": "13.0.1",
|
||||
@ -5262,7 +5293,7 @@
|
||||
}
|
||||
},
|
||||
"node_modules/npm/node_modules/node-gyp": {
|
||||
"version": "10.1.0",
|
||||
"version": "10.2.0",
|
||||
"dev": true,
|
||||
"inBundle": true,
|
||||
"license": "MIT",
|
||||
@ -5273,9 +5304,9 @@
|
||||
"graceful-fs": "^4.2.6",
|
||||
"make-fetch-happen": "^13.0.0",
|
||||
"nopt": "^7.0.0",
|
||||
"proc-log": "^3.0.0",
|
||||
"proc-log": "^4.1.0",
|
||||
"semver": "^7.3.5",
|
||||
"tar": "^6.1.2",
|
||||
"tar": "^6.2.1",
|
||||
"which": "^4.0.0"
|
||||
},
|
||||
"bin": {
|
||||
@ -5285,15 +5316,6 @@
|
||||
"node": "^16.14.0 || >=18.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/npm/node_modules/node-gyp/node_modules/proc-log": {
|
||||
"version": "3.0.0",
|
||||
"dev": true,
|
||||
"inBundle": true,
|
||||
"license": "ISC",
|
||||
"engines": {
|
||||
"node": "^14.17.0 || ^16.13.0 || >=18.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/npm/node_modules/nopt": {
|
||||
"version": "7.2.1",
|
||||
"dev": true,
|
||||
@ -5366,7 +5388,7 @@
|
||||
}
|
||||
},
|
||||
"node_modules/npm/node_modules/npm-package-arg": {
|
||||
"version": "11.0.2",
|
||||
"version": "11.0.3",
|
||||
"dev": true,
|
||||
"inBundle": true,
|
||||
"license": "ISC",
|
||||
@ -5540,7 +5562,7 @@
|
||||
}
|
||||
},
|
||||
"node_modules/npm/node_modules/postcss-selector-parser": {
|
||||
"version": "6.1.0",
|
||||
"version": "6.1.2",
|
||||
"dev": true,
|
||||
"inBundle": true,
|
||||
"license": "MIT",
|
||||
@ -5678,7 +5700,7 @@
|
||||
"optional": true
|
||||
},
|
||||
"node_modules/npm/node_modules/semver": {
|
||||
"version": "7.6.2",
|
||||
"version": "7.6.3",
|
||||
"dev": true,
|
||||
"inBundle": true,
|
||||
"license": "ISC",
|
||||
@ -6437,9 +6459,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/picocolors": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.1.tgz",
|
||||
"integrity": "sha512-anP1Z8qwhkbmu7MFP5iTt+wQKXgwzf7zTyGlcdzabySa9vd0Xt392U0rVmz9poOaBj0uHJKyyo9/upk0HrEQew==",
|
||||
"version": "1.1.0",
|
||||
"resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.0.tgz",
|
||||
"integrity": "sha512-TQ92mBOW0l3LeMeyLV6mzy/kWr8lkd/hp3mTg7wYK7zJhuBStmGMBG0BdeDZS/dZx1IukaX6Bk11zcln25o1Aw==",
|
||||
"dev": true,
|
||||
"license": "ISC"
|
||||
},
|
||||
@ -6481,9 +6503,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/pretty-ms": {
|
||||
"version": "9.0.0",
|
||||
"resolved": "https://registry.npmjs.org/pretty-ms/-/pretty-ms-9.0.0.tgz",
|
||||
"integrity": "sha512-E9e9HJ9R9NasGOgPaPE8VMeiPKAyWR5jcFpNnwIejslIhWqdqOrb2wShBsncMPUb+BcCd2OPYfh7p2W6oemTng==",
|
||||
"version": "9.1.0",
|
||||
"resolved": "https://registry.npmjs.org/pretty-ms/-/pretty-ms-9.1.0.tgz",
|
||||
"integrity": "sha512-o1piW0n3tgKIKCwk2vpM/vOV13zjJzvP37Ioze54YlTHE06m4tjEbzg9WsKkvTuyYln2DHjo5pY4qrZGI0otpw==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
@ -6738,15 +6760,15 @@
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/semantic-release": {
|
||||
"version": "24.0.0",
|
||||
"resolved": "https://registry.npmjs.org/semantic-release/-/semantic-release-24.0.0.tgz",
|
||||
"integrity": "sha512-v46CRPw+9eI3ZuYGF2oAjqPqsfbnfFTwLBgQsv/lch4goD09ytwOTESMN4QIrx/wPLxUGey60/NMx+ANQtWRsA==",
|
||||
"version": "24.1.2",
|
||||
"resolved": "https://registry.npmjs.org/semantic-release/-/semantic-release-24.1.2.tgz",
|
||||
"integrity": "sha512-hvEJ7yI97pzJuLsDZCYzJgmRxF8kiEJvNZhf0oiZQcexw+Ycjy4wbdsn/sVMURgNCu8rwbAXJdBRyIxM4pe32g==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@semantic-release/commit-analyzer": "^13.0.0-beta.1",
|
||||
"@semantic-release/error": "^4.0.0",
|
||||
"@semantic-release/github": "^10.0.0",
|
||||
"@semantic-release/github": "^11.0.0",
|
||||
"@semantic-release/npm": "^12.0.0",
|
||||
"@semantic-release/release-notes-generator": "^14.0.0-beta.1",
|
||||
"aggregate-error": "^5.0.0",
|
||||
@ -6759,7 +6781,7 @@
|
||||
"get-stream": "^6.0.0",
|
||||
"git-log-parser": "^1.2.0",
|
||||
"hook-std": "^3.0.0",
|
||||
"hosted-git-info": "^7.0.0",
|
||||
"hosted-git-info": "^8.0.0",
|
||||
"import-from-esm": "^1.3.1",
|
||||
"lodash-es": "^4.17.21",
|
||||
"marked": "^12.0.0",
|
||||
@ -6851,9 +6873,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/semantic-release/node_modules/execa": {
|
||||
"version": "9.3.0",
|
||||
"resolved": "https://registry.npmjs.org/execa/-/execa-9.3.0.tgz",
|
||||
"integrity": "sha512-l6JFbqnHEadBoVAVpN5dl2yCyfX28WoBAGaoQcNmLLSedOxTxcn2Qa83s8I/PA5i56vWru2OHOtrwF7Om2vqlg==",
|
||||
"version": "9.4.0",
|
||||
"resolved": "https://registry.npmjs.org/execa/-/execa-9.4.0.tgz",
|
||||
"integrity": "sha512-yKHlle2YGxZE842MERVIplWwNH5VYmqqcPFgtnlU//K8gxuFFXu0pwd/CrfXTumFpeEiufsP7+opT/bPJa1yVw==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
@ -6861,10 +6883,10 @@
|
||||
"cross-spawn": "^7.0.3",
|
||||
"figures": "^6.1.0",
|
||||
"get-stream": "^9.0.0",
|
||||
"human-signals": "^7.0.0",
|
||||
"human-signals": "^8.0.0",
|
||||
"is-plain-obj": "^4.1.0",
|
||||
"is-stream": "^4.0.1",
|
||||
"npm-run-path": "^5.2.0",
|
||||
"npm-run-path": "^6.0.0",
|
||||
"pretty-ms": "^9.0.0",
|
||||
"signal-exit": "^4.1.0",
|
||||
"strip-final-newline": "^4.0.0",
|
||||
@ -6895,9 +6917,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/semantic-release/node_modules/human-signals": {
|
||||
"version": "7.0.0",
|
||||
"resolved": "https://registry.npmjs.org/human-signals/-/human-signals-7.0.0.tgz",
|
||||
"integrity": "sha512-74kytxOUSvNbjrT9KisAbaTZ/eJwD/LrbM/kh5j0IhPuJzwuA19dWvniFGwBzN9rVjg+O/e+F310PjObDXS+9Q==",
|
||||
"version": "8.0.0",
|
||||
"resolved": "https://registry.npmjs.org/human-signals/-/human-signals-8.0.0.tgz",
|
||||
"integrity": "sha512-/1/GPCpDUCCYwlERiYjxoczfP0zfvZMU/OWgQPMya9AbAE24vseigFdhAMObpc8Q4lc/kjutPfUddDYyAmejnA==",
|
||||
"dev": true,
|
||||
"license": "Apache-2.0",
|
||||
"engines": {
|
||||
@ -6931,16 +6953,17 @@
|
||||
}
|
||||
},
|
||||
"node_modules/semantic-release/node_modules/npm-run-path": {
|
||||
"version": "5.3.0",
|
||||
"resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-5.3.0.tgz",
|
||||
"integrity": "sha512-ppwTtiJZq0O/ai0z7yfudtBpWIoxM8yE6nHi1X47eFR2EWORqfbu6CnPlNsjeN683eT0qG6H/Pyf9fCcvjnnnQ==",
|
||||
"version": "6.0.0",
|
||||
"resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-6.0.0.tgz",
|
||||
"integrity": "sha512-9qny7Z9DsQU8Ou39ERsPU4OZQlSTP47ShQzuKZ6PRXpYLtIFgl/DEBYEXKlvcEa+9tHVcK8CF81Y2V72qaZhWA==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"path-key": "^4.0.0"
|
||||
"path-key": "^4.0.0",
|
||||
"unicorn-magic": "^0.3.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": "^12.20.0 || ^14.13.1 || >=16.0.0"
|
||||
"node": ">=18"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/sindresorhus"
|
||||
@ -6998,6 +7021,19 @@
|
||||
"url": "https://github.com/sponsors/sindresorhus"
|
||||
}
|
||||
},
|
||||
"node_modules/semantic-release/node_modules/unicorn-magic": {
|
||||
"version": "0.3.0",
|
||||
"resolved": "https://registry.npmjs.org/unicorn-magic/-/unicorn-magic-0.3.0.tgz",
|
||||
"integrity": "sha512-+QBBXBCvifc56fsbuxZQ6Sic3wqqc3WWaqxs58gvJrcOuN83HGTCwz3oS5phzU9LthRNE9VrJCFCLUgHeeFnfA==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/sindresorhus"
|
||||
}
|
||||
},
|
||||
"node_modules/semver": {
|
||||
"version": "7.6.3",
|
||||
"resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz",
|
||||
@ -7239,9 +7275,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/spdx-license-ids": {
|
||||
"version": "3.0.18",
|
||||
"resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.18.tgz",
|
||||
"integrity": "sha512-xxRs31BqRYHwiMzudOrpSiHtZ8i/GeionCBDSilhYRj+9gIcI8wCZTlXZKu9vZIVqViP3dcp9qE5G6AlIaD+TQ==",
|
||||
"version": "3.0.20",
|
||||
"resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.20.tgz",
|
||||
"integrity": "sha512-jg25NiDV/1fLtSgEgyvVyDunvaNHbuwF9lfNV17gSmPFAlYzdfNBlLtLzXTevwkPj7DhGbmN9VnmJIgLnhvaBw==",
|
||||
"dev": true,
|
||||
"license": "CC0-1.0"
|
||||
},
|
||||
@ -7365,9 +7401,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/supports-hyperlinks": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/supports-hyperlinks/-/supports-hyperlinks-3.0.0.tgz",
|
||||
"integrity": "sha512-QBDPHyPQDRTy9ku4URNGY5Lah8PAaXs6tAAwp55sL5WCsSW7GIfdf6W5ixfziW+t7wh3GVvHyHHyQ1ESsoRvaA==",
|
||||
"version": "3.1.0",
|
||||
"resolved": "https://registry.npmjs.org/supports-hyperlinks/-/supports-hyperlinks-3.1.0.tgz",
|
||||
"integrity": "sha512-2rn0BZ+/f7puLOHZm1HOJfwBggfaHXUpPUSSG/SWM4TWp5KCfmNYwnC3hruy2rZlMnmWZ+QAGpZfchu3f3695A==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
@ -7376,6 +7412,9 @@
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=14.18"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/sindresorhus"
|
||||
}
|
||||
},
|
||||
"node_modules/temp-dir": {
|
||||
@ -7530,9 +7569,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/type-fest": {
|
||||
"version": "4.22.1",
|
||||
"resolved": "https://registry.npmjs.org/type-fest/-/type-fest-4.22.1.tgz",
|
||||
"integrity": "sha512-9tHNEa0Ov81YOopiVkcCJVz5TM6AEQ+CHHjFIktqPnE3NV0AHIkx+gh9tiCl58m/66wWxkOC9eltpa75J4lQPA==",
|
||||
"version": "4.26.1",
|
||||
"resolved": "https://registry.npmjs.org/type-fest/-/type-fest-4.26.1.tgz",
|
||||
"integrity": "sha512-yOGpmOAL7CkKe/91I5O3gPICmJNLJ1G4zFYVAsRHg7M64biSnPtRj0WNQt++bRkjYOqjWXrhnUw1utzmVErAdg==",
|
||||
"dev": true,
|
||||
"license": "(MIT OR CC0-1.0)",
|
||||
"engines": {
|
||||
@ -7543,9 +7582,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/uglify-js": {
|
||||
"version": "3.19.0",
|
||||
"resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.19.0.tgz",
|
||||
"integrity": "sha512-wNKHUY2hYYkf6oSFfhwwiHo4WCHzHmzcXsqXYTN9ja3iApYIFbb2U6ics9hBcYLHcYGQoAlwnZlTrf3oF+BL/Q==",
|
||||
"version": "3.19.3",
|
||||
"resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.19.3.tgz",
|
||||
"integrity": "sha512-v3Xu+yuwBXisp6QYTcH4UbH+xYJXqnq2m/LtQVWKWzYc1iehYnLixoQDN9FH6/j9/oybfd6W9Ghwkl8+UMKTKQ==",
|
||||
"dev": true,
|
||||
"license": "BSD-2-Clause",
|
||||
"optional": true,
|
||||
|
@ -3,7 +3,7 @@
|
||||
"@saithodev/semantic-release-backmerge": "^4.0.1",
|
||||
"@semantic-release/changelog": "^6.0.3",
|
||||
"@semantic-release/git": "^10.0.1",
|
||||
"gradle-semantic-release-plugin": "^1.9.2",
|
||||
"semantic-release": "^24.0.0"
|
||||
"gradle-semantic-release-plugin": "^1.10.1",
|
||||
"semantic-release": "^24.1.2"
|
||||
}
|
||||
}
|
||||
|
@ -12,7 +12,7 @@ import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction
|
||||
|
||||
@Patch(
|
||||
name = "Pro unlock",
|
||||
compatiblePackages = [CompatiblePackage("com.backdrops.wallpapers", ["4.52"])]
|
||||
compatiblePackages = [CompatiblePackage("com.backdrops.wallpapers")]
|
||||
)
|
||||
@Suppress("unused")
|
||||
object ProUnlockPatch : BytecodePatch(
|
||||
@ -34,4 +34,4 @@ object ProUnlockPatch : BytecodePatch(
|
||||
|
||||
} ?: throw ProUnlockFingerprint.exception
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,96 @@
|
||||
package app.revanced.patches.facebook.ads.mainfeed
|
||||
|
||||
import app.revanced.patcher.data.BytecodeContext
|
||||
import app.revanced.patcher.extensions.InstructionExtensions.addInstructions
|
||||
import app.revanced.patcher.extensions.InstructionExtensions.addInstructionsWithLabels
|
||||
import app.revanced.patcher.extensions.or
|
||||
import app.revanced.patcher.patch.BytecodePatch
|
||||
import app.revanced.patcher.patch.annotation.CompatiblePackage
|
||||
import app.revanced.patcher.patch.annotation.Patch
|
||||
import app.revanced.patcher.util.proxy.mutableTypes.MutableMethod.Companion.toMutable
|
||||
import app.revanced.patches.facebook.ads.mainfeed.fingerprints.BaseModelMapperFingerprint
|
||||
import app.revanced.patches.facebook.ads.mainfeed.fingerprints.GetSponsoredDataModelTemplateFingerprint
|
||||
import app.revanced.patches.facebook.ads.mainfeed.fingerprints.GetStoryVisibilityFingerprint
|
||||
import app.revanced.util.exception
|
||||
import app.revanced.util.resultOrThrow
|
||||
import com.android.tools.smali.dexlib2.AccessFlags
|
||||
import com.android.tools.smali.dexlib2.builder.MutableMethodImplementation
|
||||
import com.android.tools.smali.dexlib2.iface.instruction.formats.Instruction31i
|
||||
import com.android.tools.smali.dexlib2.immutable.ImmutableMethod
|
||||
import com.android.tools.smali.dexlib2.immutable.ImmutableMethodParameter
|
||||
|
||||
@Patch(
|
||||
name = "Hide 'Sponsored Stories'",
|
||||
compatiblePackages = [CompatiblePackage("com.facebook.katana")],
|
||||
)
|
||||
@Suppress("unused")
|
||||
object HideSponsoredStoriesPatch : BytecodePatch(
|
||||
setOf(GetStoryVisibilityFingerprint, GetSponsoredDataModelTemplateFingerprint, BaseModelMapperFingerprint),
|
||||
) {
|
||||
private const val GRAPHQL_STORY_TYPE = "Lcom/facebook/graphql/model/GraphQLStory;"
|
||||
|
||||
override fun execute(context: BytecodeContext) {
|
||||
GetStoryVisibilityFingerprint.result?.apply {
|
||||
val sponsoredDataModelTemplateMethod = GetSponsoredDataModelTemplateFingerprint.resultOrThrow().method
|
||||
val baseModelMapperMethod = BaseModelMapperFingerprint.resultOrThrow().method
|
||||
val baseModelWithTreeType = baseModelMapperMethod.returnType
|
||||
|
||||
// The "SponsoredDataModelTemplate" methods has the ids in its body to extract sponsored data
|
||||
// from GraphQL models, but targets the wrong derived type of "BaseModelWithTree". Since those ids
|
||||
// could change in future version, we need to extract them and call the base implementation directly.
|
||||
val getSponsoredDataHelperMethod = ImmutableMethod(
|
||||
classDef.type,
|
||||
"getSponsoredData",
|
||||
listOf(ImmutableMethodParameter(GRAPHQL_STORY_TYPE, null, null)),
|
||||
baseModelWithTreeType,
|
||||
AccessFlags.PRIVATE or AccessFlags.STATIC,
|
||||
null,
|
||||
null,
|
||||
MutableMethodImplementation(4),
|
||||
).toMutable().apply {
|
||||
// Extract the ids of the original method. These ids seem to correspond to model types for
|
||||
// GraphQL data structure. They are then fed to a method of BaseModelWithTree that populate
|
||||
// and cast the requested GraphQL subtype. The Ids are found in the two first "CONST" instructions.
|
||||
val constInstructions = sponsoredDataModelTemplateMethod.implementation!!.instructions
|
||||
.asSequence()
|
||||
.filterIsInstance<Instruction31i>()
|
||||
.take(2)
|
||||
.toList()
|
||||
|
||||
val storyTypeId = constInstructions[0].narrowLiteral
|
||||
val sponsoredDataTypeId = constInstructions[1].narrowLiteral
|
||||
|
||||
addInstructions(
|
||||
"""
|
||||
const-class v2, $baseModelWithTreeType
|
||||
const v1, $storyTypeId
|
||||
const v0, $sponsoredDataTypeId
|
||||
invoke-virtual {p0, v2, v1, v0}, $baseModelMapperMethod
|
||||
move-result-object v0
|
||||
check-cast v0, $baseModelWithTreeType
|
||||
return-object v0
|
||||
""",
|
||||
)
|
||||
}
|
||||
|
||||
mutableClass.methods.add(getSponsoredDataHelperMethod)
|
||||
|
||||
// Check if the parameter type is GraphQLStory and if sponsoredDataModelGetter returns a non-null value.
|
||||
// If so, hide the story by setting the visibility to StoryVisibility.GONE.
|
||||
mutableMethod.addInstructionsWithLabels(
|
||||
scanResult.patternScanResult!!.startIndex,
|
||||
"""
|
||||
instance-of v0, p0, $GRAPHQL_STORY_TYPE
|
||||
if-eqz v0, :resume_normal
|
||||
invoke-static {p0}, $getSponsoredDataHelperMethod
|
||||
move-result-object v0
|
||||
if-eqz v0, :resume_normal
|
||||
const-string v0, "GONE"
|
||||
return-object v0
|
||||
:resume_normal
|
||||
nop
|
||||
""",
|
||||
)
|
||||
} ?: throw GetStoryVisibilityFingerprint.exception
|
||||
}
|
||||
}
|
@ -0,0 +1,21 @@
|
||||
package app.revanced.patches.facebook.ads.mainfeed.fingerprints
|
||||
|
||||
import app.revanced.patcher.extensions.or
|
||||
import app.revanced.patcher.fingerprint.MethodFingerprint
|
||||
import com.android.tools.smali.dexlib2.AccessFlags
|
||||
import com.android.tools.smali.dexlib2.Opcode
|
||||
|
||||
internal object BaseModelMapperFingerprint : MethodFingerprint(
|
||||
|
||||
accessFlags = (AccessFlags.PUBLIC or AccessFlags.FINAL),
|
||||
parameters = listOf("Ljava/lang/Class","I","I"),
|
||||
returnType = "Lcom/facebook/graphql/modelutil/BaseModelWithTree;",
|
||||
opcodes = listOf(
|
||||
Opcode.SGET_OBJECT,
|
||||
Opcode.INVOKE_STATIC,
|
||||
Opcode.MOVE_RESULT_OBJECT,
|
||||
Opcode.CONST_4,
|
||||
Opcode.IF_EQ
|
||||
)
|
||||
|
||||
)
|
@ -0,0 +1,23 @@
|
||||
package app.revanced.patches.facebook.ads.mainfeed.fingerprints
|
||||
|
||||
import app.revanced.patcher.extensions.or
|
||||
import app.revanced.patcher.fingerprint.MethodFingerprint
|
||||
import com.android.tools.smali.dexlib2.AccessFlags
|
||||
import com.android.tools.smali.dexlib2.Opcode
|
||||
|
||||
internal object GetSponsoredDataModelTemplateFingerprint : MethodFingerprint(
|
||||
|
||||
accessFlags = (AccessFlags.PUBLIC or AccessFlags.FINAL),
|
||||
parameters = listOf(),
|
||||
returnType = "L",
|
||||
opcodes = listOf(
|
||||
Opcode.CONST,
|
||||
Opcode.CONST,
|
||||
Opcode.INVOKE_STATIC,
|
||||
Opcode.MOVE_RESULT_OBJECT,
|
||||
Opcode.RETURN_OBJECT
|
||||
),
|
||||
customFingerprint = { methodDef, classDef ->
|
||||
classDef.type == "Lcom/facebook/graphql/model/GraphQLFBMultiAdsFeedUnit;"
|
||||
}
|
||||
)
|
@ -0,0 +1,23 @@
|
||||
package app.revanced.patches.facebook.ads.mainfeed.fingerprints
|
||||
|
||||
import app.revanced.patcher.extensions.or
|
||||
import app.revanced.patcher.fingerprint.MethodFingerprint
|
||||
import com.android.tools.smali.dexlib2.AccessFlags
|
||||
import com.android.tools.smali.dexlib2.Opcode
|
||||
import com.android.tools.smali.dexlib2.iface.Annotation
|
||||
import com.android.tools.smali.dexlib2.iface.value.StringEncodedValue
|
||||
|
||||
internal object GetStoryVisibilityFingerprint : MethodFingerprint(
|
||||
returnType = "Ljava/lang/String;",
|
||||
accessFlags = (AccessFlags.PUBLIC or AccessFlags.STATIC),
|
||||
opcodes = listOf(
|
||||
Opcode.INSTANCE_OF,
|
||||
Opcode.IF_NEZ,
|
||||
Opcode.INSTANCE_OF,
|
||||
Opcode.IF_NEZ,
|
||||
Opcode.INSTANCE_OF,
|
||||
Opcode.IF_NEZ,
|
||||
Opcode.CONST
|
||||
),
|
||||
strings = listOf("This should not be called for base class object"),
|
||||
)
|
@ -3,7 +3,6 @@ package app.revanced.patches.music.misc.gms
|
||||
import app.revanced.patches.music.misc.gms.Constants.MUSIC_PACKAGE_NAME
|
||||
import app.revanced.patches.music.misc.gms.Constants.REVANCED_MUSIC_PACKAGE_NAME
|
||||
import app.revanced.patches.music.misc.gms.GmsCoreSupportResourcePatch.gmsCoreVendorGroupIdOption
|
||||
import app.revanced.patches.music.misc.gms.fingerprints.CastDynamiteModuleV2Fingerprint
|
||||
import app.revanced.patches.music.misc.gms.fingerprints.MusicActivityOnCreateFingerprint
|
||||
import app.revanced.patches.music.misc.gms.fingerprints.PrimeMethodFingerprint
|
||||
import app.revanced.patches.music.misc.integrations.IntegrationsPatch
|
||||
@ -16,7 +15,6 @@ object GmsCoreSupportPatch : BaseGmsCoreSupportPatch(
|
||||
toPackageName = REVANCED_MUSIC_PACKAGE_NAME,
|
||||
primeMethodFingerprint = PrimeMethodFingerprint,
|
||||
earlyReturnFingerprints = setOf(
|
||||
CastDynamiteModuleV2Fingerprint,
|
||||
CastContextFetchFingerprint,
|
||||
),
|
||||
mainActivityOnCreateFingerprint = MusicActivityOnCreateFingerprint,
|
||||
@ -26,7 +24,6 @@ object GmsCoreSupportPatch : BaseGmsCoreSupportPatch(
|
||||
CompatiblePackage("com.google.android.apps.youtube.music"),
|
||||
),
|
||||
fingerprints = setOf(
|
||||
CastDynamiteModuleV2Fingerprint,
|
||||
CastContextFetchFingerprint,
|
||||
PrimeMethodFingerprint,
|
||||
),
|
||||
|
@ -1,8 +0,0 @@
|
||||
package app.revanced.patches.music.misc.gms.fingerprints
|
||||
|
||||
|
||||
import app.revanced.patcher.fingerprint.MethodFingerprint
|
||||
|
||||
internal object CastDynamiteModuleV2Fingerprint : MethodFingerprint(
|
||||
strings = listOf("Failed to load module via V2: ")
|
||||
)
|
@ -0,0 +1,62 @@
|
||||
package app.revanced.patches.reddit.customclients.syncforreddit.fix.video
|
||||
|
||||
import app.revanced.patcher.data.BytecodeContext
|
||||
import app.revanced.patcher.extensions.InstructionExtensions.addInstructions
|
||||
import app.revanced.patcher.extensions.InstructionExtensions.getInstruction
|
||||
import app.revanced.patcher.patch.BytecodePatch
|
||||
import app.revanced.patcher.patch.annotation.CompatiblePackage
|
||||
import app.revanced.patcher.patch.annotation.Patch
|
||||
import app.revanced.patches.reddit.customclients.syncforreddit.fix.video.fingerprints.ParseRedditVideoNetworkResponseFingerprint
|
||||
import app.revanced.util.resultOrThrow
|
||||
import com.android.tools.smali.dexlib2.iface.instruction.formats.Instruction35c
|
||||
|
||||
@Patch(
|
||||
name = "Fix video downloads",
|
||||
description = "Fixes a bug in Sync's MPD parser resulting in only the audio-track being saved.",
|
||||
compatiblePackages = [
|
||||
CompatiblePackage("com.laurencedawson.reddit_sync"),
|
||||
CompatiblePackage("com.laurencedawson.reddit_sync.pro"),
|
||||
CompatiblePackage("com.laurencedawson.reddit_sync.dev"),
|
||||
],
|
||||
requiresIntegrations = true,
|
||||
)
|
||||
@Suppress("unused")
|
||||
object FixVideoDownloadsPatch : BytecodePatch(
|
||||
fingerprints = setOf(ParseRedditVideoNetworkResponseFingerprint),
|
||||
) {
|
||||
private const val INTEGRATIONS_CLASS_DESCRIPTOR =
|
||||
"Lapp/revanced/integrations/syncforreddit/FixRedditVideoDownloadPatch;"
|
||||
private const val GET_LINKS_METHOD = "getLinks([B)[Ljava/lang/String;"
|
||||
|
||||
override fun execute(context: BytecodeContext) {
|
||||
ParseRedditVideoNetworkResponseFingerprint.resultOrThrow().let {
|
||||
val scanResult = it.scanResult.patternScanResult!!
|
||||
val newInstanceIndex = scanResult.startIndex
|
||||
val invokeDirectIndex = scanResult.endIndex - 1
|
||||
|
||||
val buildResponseInstruction = it.mutableMethod.getInstruction<Instruction35c>(invokeDirectIndex)
|
||||
|
||||
it.mutableMethod.addInstructions(
|
||||
newInstanceIndex + 1,
|
||||
"""
|
||||
# Get byte array from response.
|
||||
iget-object v2, p1, Lcom/android/volley/NetworkResponse;->data:[B
|
||||
|
||||
# Parse the videoUrl and audioUrl from the byte array.
|
||||
invoke-static { v2 }, $INTEGRATIONS_CLASS_DESCRIPTOR->$GET_LINKS_METHOD
|
||||
move-result-object v2
|
||||
|
||||
# Get videoUrl (Index 0).
|
||||
const/4 v5, 0x0
|
||||
aget-object v${buildResponseInstruction.registerE}, v2, v5
|
||||
|
||||
# Get audioUrl (Index 1).
|
||||
const/4 v6, 0x1
|
||||
aget-object v${buildResponseInstruction.registerF}, v2, v6
|
||||
|
||||
# Register E and F are used to build the response.
|
||||
""",
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,16 @@
|
||||
package app.revanced.patches.reddit.customclients.syncforreddit.fix.video.fingerprints
|
||||
|
||||
import app.revanced.patcher.fingerprint.MethodFingerprint
|
||||
import com.android.tools.smali.dexlib2.Opcode
|
||||
|
||||
internal object ParseRedditVideoNetworkResponseFingerprint : MethodFingerprint(
|
||||
opcodes = listOf(
|
||||
Opcode.NEW_INSTANCE,
|
||||
Opcode.IGET_OBJECT,
|
||||
Opcode.INVOKE_DIRECT,
|
||||
Opcode.CONST_WIDE_32
|
||||
),
|
||||
customFingerprint = { methodDef, classDef ->
|
||||
classDef.sourceFile == "RedditVideoRequest.java" && methodDef.name == "parseNetworkResponse"
|
||||
}
|
||||
)
|
@ -11,7 +11,6 @@ import app.revanced.patches.all.misc.packagename.ChangePackageNamePatch
|
||||
import app.revanced.patches.shared.misc.gms.BaseGmsCoreSupportPatch.Constants.ACTIONS
|
||||
import app.revanced.patches.shared.misc.gms.BaseGmsCoreSupportPatch.Constants.AUTHORITIES
|
||||
import app.revanced.patches.shared.misc.gms.BaseGmsCoreSupportPatch.Constants.PERMISSIONS
|
||||
import app.revanced.patches.shared.misc.gms.fingerprints.CastDynamiteModuleFingerprint
|
||||
import app.revanced.patches.shared.misc.gms.fingerprints.GmsCoreSupportFingerprint
|
||||
import app.revanced.patches.shared.misc.gms.fingerprints.GmsCoreSupportFingerprint.GET_GMS_CORE_VENDOR_GROUP_ID_METHOD_NAME
|
||||
import app.revanced.patches.shared.misc.gms.fingerprints.GooglePlayUtilityFingerprint
|
||||
@ -69,7 +68,6 @@ abstract class BaseGmsCoreSupportPatch(
|
||||
GmsCoreSupportFingerprint,
|
||||
GooglePlayUtilityFingerprint,
|
||||
ServiceCheckFingerprint,
|
||||
CastDynamiteModuleFingerprint,
|
||||
mainActivityOnCreateFingerprint,
|
||||
) + fingerprints,
|
||||
requiresIntegrations = true,
|
||||
@ -104,10 +102,7 @@ abstract class BaseGmsCoreSupportPatch(
|
||||
// Return these methods early to prevent the app from crashing.
|
||||
earlyReturnFingerprints.returnEarly()
|
||||
ServiceCheckFingerprint.returnEarly()
|
||||
// Not all apps have CastDynamiteModule, so we need to check if it's present.
|
||||
if (CastDynamiteModuleFingerprint.result != null) {
|
||||
CastDynamiteModuleFingerprint.returnEarly()
|
||||
}
|
||||
|
||||
// Google Play Utility is not present in all apps, so we need to check if it's present.
|
||||
if (GooglePlayUtilityFingerprint.result != null) {
|
||||
GooglePlayUtilityFingerprint.returnEarly()
|
||||
@ -236,131 +231,268 @@ abstract class BaseGmsCoreSupportPatch(
|
||||
/**
|
||||
* A collection of permissions, intents and content provider authorities
|
||||
* that are present in GmsCore which need to be transformed.
|
||||
*
|
||||
* NOTE: The following were present, but it seems like they are not needed to be transformed:
|
||||
* - com.google.android.gms.chimera.GmsIntentOperationService
|
||||
* - com.google.android.gms.phenotype.internal.IPhenotypeCallbacks
|
||||
* - com.google.android.gms.phenotype.internal.IPhenotypeService
|
||||
* - com.google.android.gms.phenotype.PACKAGE_NAME
|
||||
* - com.google.android.gms.phenotype.UPDATE
|
||||
* - com.google.android.gms.phenotype
|
||||
*/
|
||||
private object Constants {
|
||||
/**
|
||||
* A list of all permissions.
|
||||
* All permissions.
|
||||
*/
|
||||
val PERMISSIONS = listOf(
|
||||
// C2DM / GCM
|
||||
val PERMISSIONS = setOf(
|
||||
"com.google.android.c2dm.permission.RECEIVE",
|
||||
"com.google.android.c2dm.permission.SEND",
|
||||
"com.google.android.gtalkservice.permission.GTALK_SERVICE",
|
||||
|
||||
// GAuth
|
||||
"com.google.android.gms.auth.api.phone.permission.SEND",
|
||||
"com.google.android.gms.permission.AD_ID",
|
||||
"com.google.android.gms.permission.AD_ID_NOTIFICATION",
|
||||
"com.google.android.gms.permission.CAR_FUEL",
|
||||
"com.google.android.gms.permission.CAR_INFORMATION",
|
||||
"com.google.android.gms.permission.CAR_MILEAGE",
|
||||
"com.google.android.gms.permission.CAR_SPEED",
|
||||
"com.google.android.gms.permission.CAR_VENDOR_EXTENSION",
|
||||
"com.google.android.googleapps.permission.GOOGLE_AUTH",
|
||||
"com.google.android.googleapps.permission.GOOGLE_AUTH.cp",
|
||||
"com.google.android.googleapps.permission.GOOGLE_AUTH.local",
|
||||
"com.google.android.googleapps.permission.GOOGLE_AUTH.mail",
|
||||
"com.google.android.googleapps.permission.GOOGLE_AUTH.writely",
|
||||
"com.google.android.gtalkservice.permission.GTALK_SERVICE",
|
||||
"com.google.android.providers.gsf.permission.READ_GSERVICES",
|
||||
)
|
||||
|
||||
/**
|
||||
* All intent actions.
|
||||
*/
|
||||
val ACTIONS = listOf(
|
||||
// location
|
||||
"com.google.android.gms.location.places.ui.PICK_PLACE",
|
||||
"com.google.android.gms.location.places.GeoDataApi",
|
||||
"com.google.android.gms.location.places.PlacesApi",
|
||||
"com.google.android.gms.location.places.PlaceDetectionApi",
|
||||
"com.google.android.gms.wearable.MESSAGE_RECEIVED",
|
||||
|
||||
// C2DM / GCM
|
||||
val ACTIONS = setOf(
|
||||
"com.google.android.c2dm.intent.RECEIVE",
|
||||
"com.google.android.c2dm.intent.REGISTER",
|
||||
"com.google.android.c2dm.intent.REGISTRATION",
|
||||
"com.google.android.c2dm.intent.UNREGISTER",
|
||||
"com.google.android.c2dm.intent.RECEIVE",
|
||||
"com.google.iid.TOKEN_REQUEST",
|
||||
"com.google.android.contextmanager.service.ContextManagerService.START",
|
||||
"com.google.android.gcm.intent.SEND",
|
||||
|
||||
// car
|
||||
"com.google.android.gms.car.service.START",
|
||||
|
||||
// people
|
||||
"com.google.android.gms.people.service.START",
|
||||
|
||||
// wearable
|
||||
"com.google.android.gms.wearable.BIND",
|
||||
|
||||
// auth
|
||||
"com.google.android.gsf.login",
|
||||
"com.google.android.gsf.action.GET_GLS",
|
||||
"com.google.android.gms.common.account.CHOOSE_ACCOUNT",
|
||||
"com.google.android.gms.auth.login.LOGIN",
|
||||
"com.google.android.gms.accounts.ACCOUNT_SERVICE",
|
||||
"com.google.android.gms.accountsettings.ACCOUNT_PREFERENCES_SETTINGS",
|
||||
"com.google.android.gms.accountsettings.action.BROWSE_SETTINGS",
|
||||
"com.google.android.gms.accountsettings.action.VIEW_SETTINGS",
|
||||
"com.google.android.gms.accountsettings.MY_ACCOUNT",
|
||||
"com.google.android.gms.accountsettings.PRIVACY_SETTINGS",
|
||||
"com.google.android.gms.accountsettings.SECURITY_SETTINGS",
|
||||
"com.google.android.gms.ads.gservice.START",
|
||||
"com.google.android.gms.ads.identifier.service.EVENT_ATTESTATION",
|
||||
"com.google.android.gms.ads.service.CACHE",
|
||||
"com.google.android.gms.ads.service.CONSENT_LOOKUP",
|
||||
"com.google.android.gms.ads.service.HTTP",
|
||||
"com.google.android.gms.analytics.service.START",
|
||||
"com.google.android.gms.app.settings.GoogleSettingsLink",
|
||||
"com.google.android.gms.appstate.service.START",
|
||||
"com.google.android.gms.appusage.service.START",
|
||||
"com.google.android.gms.asterism.service.START",
|
||||
"com.google.android.gms.audiomodem.service.AudioModemService.START",
|
||||
"com.google.android.gms.audit.service.START",
|
||||
"com.google.android.gms.auth.account.authapi.START",
|
||||
"com.google.android.gms.auth.account.authenticator.auto.service.START",
|
||||
"com.google.android.gms.auth.account.authenticator.chromeos.START",
|
||||
"com.google.android.gms.auth.account.authenticator.tv.service.START",
|
||||
"com.google.android.gms.auth.account.data.service.START",
|
||||
"com.google.android.gms.auth.api.credentials.PICKER",
|
||||
"com.google.android.gms.auth.api.credentials.service.START",
|
||||
"com.google.android.gms.auth.service.START",
|
||||
"com.google.firebase.auth.api.gms.service.START",
|
||||
"com.google.android.gms.auth.api.identity.service.authorization.START",
|
||||
"com.google.android.gms.auth.api.identity.service.credentialsaving.START",
|
||||
"com.google.android.gms.auth.api.identity.service.signin.START",
|
||||
"com.google.android.gms.auth.api.phone.service.InternalService.START",
|
||||
"com.google.android.gms.auth.api.signin.service.START",
|
||||
"com.google.android.gms.auth.be.appcert.AppCertService",
|
||||
|
||||
// fido
|
||||
"com.google.android.gms.fido.fido2.privileged.START",
|
||||
|
||||
// gass
|
||||
"com.google.android.gms.gass.START",
|
||||
|
||||
// games
|
||||
"com.google.android.gms.games.service.START",
|
||||
"com.google.android.gms.games.PLAY_GAMES_UPGRADE",
|
||||
|
||||
// chimera
|
||||
"com.google.android.gms.chimera",
|
||||
|
||||
// fonts
|
||||
"com.google.android.gms.fonts",
|
||||
|
||||
// phenotype
|
||||
"com.google.android.gms.phenotype.service.START",
|
||||
|
||||
// location
|
||||
"com.google.android.gms.location.reporting.service.START",
|
||||
|
||||
// misc
|
||||
"com.google.android.gms.gmscompliance.service.START",
|
||||
"com.google.android.gms.oss.licenses.service.START",
|
||||
"com.google.android.gms.tapandpay.service.BIND",
|
||||
"com.google.android.gms.measurement.START",
|
||||
"com.google.android.gms.languageprofile.service.START",
|
||||
"com.google.android.gms.auth.blockstore.service.START",
|
||||
"com.google.android.gms.auth.config.service.START",
|
||||
"com.google.android.gms.auth.cryptauth.cryptauthservice.START",
|
||||
"com.google.android.gms.auth.GOOGLE_SIGN_IN",
|
||||
"com.google.android.gms.auth.login.LOGIN",
|
||||
"com.google.android.gms.auth.proximity.devicesyncservice.START",
|
||||
"com.google.android.gms.auth.proximity.securechannelservice.START",
|
||||
"com.google.android.gms.auth.proximity.START",
|
||||
"com.google.android.gms.auth.service.START",
|
||||
"com.google.android.gms.backup.ACTION_BACKUP_SETTINGS",
|
||||
"com.google.android.gms.backup.G1_BACKUP",
|
||||
"com.google.android.gms.backup.G1_RESTORE",
|
||||
"com.google.android.gms.backup.GMS_MODULE_RESTORE",
|
||||
"com.google.android.gms.beacon.internal.IBleService.START",
|
||||
"com.google.android.gms.car.service.START",
|
||||
"com.google.android.gms.carrierauth.service.START",
|
||||
"com.google.android.gms.cast.firstparty.START",
|
||||
"com.google.android.gms.cast.remote_display.service.START",
|
||||
"com.google.android.gms.cast.service.BIND_CAST_DEVICE_CONTROLLER_SERVICE",
|
||||
"com.google.android.gms.cast_mirroring.service.START",
|
||||
"com.google.android.gms.checkin.BIND_TO_SERVICE",
|
||||
"com.google.android.gms.chromesync.service.START",
|
||||
"com.google.android.gms.clearcut.service.START",
|
||||
"com.google.android.gms.icing.LIGHTWEIGHT_INDEX_SERVICE",
|
||||
"com.google.android.gms.accountsettings.action.VIEW_SETTINGS",
|
||||
|
||||
// potoken
|
||||
"com.google.android.gms.potokens.service.START",
|
||||
|
||||
// droidguard/ safetynet
|
||||
"com.google.android.gms.common.account.CHOOSE_ACCOUNT",
|
||||
"com.google.android.gms.common.download.START",
|
||||
"com.google.android.gms.common.service.START",
|
||||
"com.google.android.gms.common.telemetry.service.START",
|
||||
"com.google.android.gms.config.START",
|
||||
"com.google.android.gms.constellation.service.START",
|
||||
"com.google.android.gms.credential.manager.service.firstparty.START",
|
||||
"com.google.android.gms.deviceconnection.service.START",
|
||||
"com.google.android.gms.drive.ApiService.RESET_AFTER_BOOT",
|
||||
"com.google.android.gms.drive.ApiService.START",
|
||||
"com.google.android.gms.drive.ApiService.STOP",
|
||||
"com.google.android.gms.droidguard.service.INIT",
|
||||
"com.google.android.gms.droidguard.service.PING",
|
||||
"com.google.android.gms.droidguard.service.START",
|
||||
"com.google.android.gms.enterprise.loader.service.START",
|
||||
"com.google.android.gms.facs.cache.service.START",
|
||||
"com.google.android.gms.facs.internal.service.START",
|
||||
"com.google.android.gms.feedback.internal.IFeedbackService",
|
||||
"com.google.android.gms.fido.credentialstore.internal_service.START",
|
||||
"com.google.android.gms.fido.fido2.privileged.START",
|
||||
"com.google.android.gms.fido.fido2.regular.START",
|
||||
"com.google.android.gms.fido.fido2.zeroparty.START",
|
||||
"com.google.android.gms.fido.sourcedevice.service.START",
|
||||
"com.google.android.gms.fido.targetdevice.internal_service.START",
|
||||
"com.google.android.gms.fido.u2f.privileged.START",
|
||||
"com.google.android.gms.fido.u2f.thirdparty.START",
|
||||
"com.google.android.gms.fido.u2f.zeroparty.START",
|
||||
"com.google.android.gms.fitness.BleApi",
|
||||
"com.google.android.gms.fitness.ConfigApi",
|
||||
"com.google.android.gms.fitness.GoalsApi",
|
||||
"com.google.android.gms.fitness.GoogleFitnessService.START",
|
||||
"com.google.android.gms.fitness.HistoryApi",
|
||||
"com.google.android.gms.fitness.InternalApi",
|
||||
"com.google.android.gms.fitness.RecordingApi",
|
||||
"com.google.android.gms.fitness.SensorsApi",
|
||||
"com.google.android.gms.fitness.SessionsApi",
|
||||
"com.google.android.gms.fonts.service.START",
|
||||
"com.google.android.gms.freighter.service.START",
|
||||
"com.google.android.gms.games.internal.connect.service.START",
|
||||
"com.google.android.gms.games.PLAY_GAMES_UPGRADE",
|
||||
"com.google.android.gms.games.service.START",
|
||||
"com.google.android.gms.gass.START",
|
||||
"com.google.android.gms.gmscompliance.service.START",
|
||||
"com.google.android.gms.googlehelp.HELP",
|
||||
"com.google.android.gms.googlehelp.service.GoogleHelpService.START",
|
||||
"com.google.android.gms.growth.service.START",
|
||||
"com.google.android.gms.herrevad.services.LightweightNetworkQualityAndroidService.START",
|
||||
"com.google.android.gms.icing.INDEX_SERVICE",
|
||||
"com.google.android.gms.icing.LIGHTWEIGHT_INDEX_SERVICE",
|
||||
"com.google.android.gms.identity.service.BIND",
|
||||
"com.google.android.gms.inappreach.service.START",
|
||||
"com.google.android.gms.instantapps.START",
|
||||
"com.google.android.gms.kids.service.START",
|
||||
"com.google.android.gms.languageprofile.service.START",
|
||||
"com.google.android.gms.learning.internal.dynamitesupport.START",
|
||||
"com.google.android.gms.learning.intservice.START",
|
||||
"com.google.android.gms.learning.predictor.START",
|
||||
"com.google.android.gms.learning.trainer.START",
|
||||
"com.google.android.gms.learning.training.background.START",
|
||||
"com.google.android.gms.location.places.GeoDataApi",
|
||||
"com.google.android.gms.location.places.PlaceDetectionApi",
|
||||
"com.google.android.gms.location.places.PlacesApi",
|
||||
"com.google.android.gms.location.reporting.service.START",
|
||||
"com.google.android.gms.location.settings.LOCATION_HISTORY",
|
||||
"com.google.android.gms.location.settings.LOCATION_REPORTING_SETTINGS",
|
||||
"com.google.android.gms.locationsharing.api.START",
|
||||
"com.google.android.gms.locationsharingreporter.service.START",
|
||||
"com.google.android.gms.lockbox.service.START",
|
||||
"com.google.android.gms.matchstick.lighter.service.START",
|
||||
"com.google.android.gms.mdm.services.DeviceManagerApiService.START",
|
||||
"com.google.android.gms.mdm.services.START",
|
||||
"com.google.android.gms.mdns.service.START",
|
||||
"com.google.android.gms.measurement.START",
|
||||
"com.google.android.gms.nearby.bootstrap.service.NearbyBootstrapService.START",
|
||||
"com.google.android.gms.nearby.connection.service.START",
|
||||
"com.google.android.gms.nearby.fastpair.START",
|
||||
"com.google.android.gms.nearby.messages.service.NearbyMessagesService.START",
|
||||
"com.google.android.gms.nearby.sharing.service.NearbySharingService.START",
|
||||
"com.google.android.gms.nearby.sharing.START_SERVICE",
|
||||
"com.google.android.gms.notifications.service.START",
|
||||
"com.google.android.gms.ocr.service.internal.START",
|
||||
"com.google.android.gms.ocr.service.START",
|
||||
"com.google.android.gms.oss.licenses.service.START",
|
||||
"com.google.android.gms.payse.service.BIND",
|
||||
"com.google.android.gms.people.contactssync.service.START",
|
||||
"com.google.android.gms.people.service.START",
|
||||
"com.google.android.gms.phenotype.service.START",
|
||||
"com.google.android.gms.photos.autobackup.service.START",
|
||||
"com.google.android.gms.playlog.service.START",
|
||||
"com.google.android.gms.plus.service.default.INTENT",
|
||||
"com.google.android.gms.plus.service.image.INTENT",
|
||||
"com.google.android.gms.plus.service.internal.START",
|
||||
"com.google.android.gms.plus.service.START",
|
||||
"com.google.android.gms.potokens.service.START",
|
||||
"com.google.android.gms.pseudonymous.service.START",
|
||||
"com.google.android.gms.rcs.START",
|
||||
"com.google.android.gms.reminders.service.START",
|
||||
"com.google.android.gms.romanesco.MODULE_BACKUP_AGENT",
|
||||
"com.google.android.gms.romanesco.service.START",
|
||||
"com.google.android.gms.safetynet.service.START",
|
||||
"com.google.android.gms.scheduler.ACTION_PROXY_SCHEDULE",
|
||||
"com.google.android.gms.search.service.SEARCH_AUTH_START",
|
||||
"com.google.android.gms.semanticlocation.service.START_ODLH",
|
||||
"com.google.android.gms.sesame.service.BIND",
|
||||
"com.google.android.gms.settings.EXPOSURE_NOTIFICATION_SETTINGS",
|
||||
"com.google.android.gms.setup.auth.SecondDeviceAuth.START",
|
||||
"com.google.android.gms.signin.service.START",
|
||||
"com.google.android.gms.smartdevice.d2d.SourceDeviceService.START",
|
||||
"com.google.android.gms.smartdevice.d2d.TargetDeviceService.START",
|
||||
"com.google.android.gms.smartdevice.directtransfer.SourceDirectTransferService.START",
|
||||
"com.google.android.gms.smartdevice.directtransfer.TargetDirectTransferService.START",
|
||||
"com.google.android.gms.smartdevice.postsetup.PostSetupService.START",
|
||||
"com.google.android.gms.smartdevice.setup.accounts.AccountsService.START",
|
||||
"com.google.android.gms.smartdevice.wifi.START_WIFI_HELPER_SERVICE",
|
||||
"com.google.android.gms.social.location.activity.service.START",
|
||||
"com.google.android.gms.speech.service.START",
|
||||
"com.google.android.gms.statementservice.EXECUTE",
|
||||
"com.google.android.gms.stats.ACTION_UPLOAD_DROPBOX_ENTRIES",
|
||||
"com.google.android.gms.tapandpay.service.BIND",
|
||||
"com.google.android.gms.telephonyspam.service.START",
|
||||
"com.google.android.gms.testsupport.service.START",
|
||||
"com.google.android.gms.thunderbird.service.START",
|
||||
"com.google.android.gms.trustagent.BridgeApi.START",
|
||||
"com.google.android.gms.trustagent.StateApi.START",
|
||||
"com.google.android.gms.trustagent.trustlet.trustletmanagerservice.BIND",
|
||||
"com.google.android.gms.trustlet.bluetooth.service.BIND",
|
||||
"com.google.android.gms.trustlet.connectionlessble.service.BIND",
|
||||
"com.google.android.gms.trustlet.face.service.BIND",
|
||||
"com.google.android.gms.trustlet.nfc.service.BIND",
|
||||
"com.google.android.gms.trustlet.onbody.service.BIND",
|
||||
"com.google.android.gms.trustlet.place.service.BIND",
|
||||
"com.google.android.gms.trustlet.voiceunlock.service.BIND",
|
||||
"com.google.android.gms.udc.service.START",
|
||||
"com.google.android.gms.update.START_API_SERVICE",
|
||||
"com.google.android.gms.update.START_SERVICE",
|
||||
"com.google.android.gms.update.START_SINGLE_USER_API_SERVICE",
|
||||
"com.google.android.gms.update.START_TV_API_SERVICE",
|
||||
"com.google.android.gms.usagereporting.service.START",
|
||||
"com.google.android.gms.userlocation.service.START",
|
||||
"com.google.android.gms.vehicle.cabin.service.START",
|
||||
"com.google.android.gms.vehicle.climate.service.START",
|
||||
"com.google.android.gms.vehicle.info.service.START",
|
||||
"com.google.android.gms.wallet.service.BIND",
|
||||
"com.google.android.gms.walletp2p.service.firstparty.BIND",
|
||||
"com.google.android.gms.walletp2p.service.zeroparty.BIND",
|
||||
"com.google.android.gms.wearable.BIND",
|
||||
"com.google.android.gms.wearable.BIND_LISTENER",
|
||||
"com.google.android.gms.wearable.DATA_CHANGED",
|
||||
"com.google.android.gms.wearable.MESSAGE_RECEIVED",
|
||||
"com.google.android.gms.wearable.NODE_CHANGED",
|
||||
"com.google.android.gsf.action.GET_GLS",
|
||||
"com.google.android.location.settings.LOCATION_REPORTING_SETTINGS",
|
||||
"com.google.android.mdd.service.START",
|
||||
"com.google.android.mdh.service.listener.START",
|
||||
"com.google.android.mdh.service.START",
|
||||
"com.google.android.mobstore.service.START",
|
||||
"com.google.firebase.auth.api.gms.service.START",
|
||||
"com.google.firebase.dynamiclinks.service.START",
|
||||
"com.google.iid.TOKEN_REQUEST",
|
||||
"com.google.android.gms.location.places.ui.PICK_PLACE",
|
||||
)
|
||||
|
||||
/**
|
||||
* All content provider authorities.
|
||||
*/
|
||||
val AUTHORITIES = listOf(
|
||||
// gsf
|
||||
val AUTHORITIES = setOf(
|
||||
"com.google.android.gms.auth.accounts",
|
||||
"com.google.android.gms.chimera",
|
||||
"com.google.android.gms.fonts",
|
||||
"com.google.android.gms.phenotype",
|
||||
"com.google.android.gsf.gservices",
|
||||
"com.google.settings",
|
||||
|
||||
// auth
|
||||
"com.google.android.gms.auth.accounts",
|
||||
|
||||
// chimera
|
||||
"com.google.android.gms.chimera",
|
||||
|
||||
// fonts
|
||||
"com.google.android.gms.fonts",
|
||||
|
||||
// phenotype
|
||||
"com.google.android.gms.phenotype",
|
||||
)
|
||||
}
|
||||
|
||||
|
@ -1,8 +0,0 @@
|
||||
package app.revanced.patches.shared.misc.gms.fingerprints
|
||||
|
||||
|
||||
import app.revanced.patcher.fingerprint.MethodFingerprint
|
||||
|
||||
internal object CastDynamiteModuleFingerprint : MethodFingerprint(
|
||||
strings = listOf("com.google.android.gms.cast.framework.internal.CastDynamiteModuleImpl")
|
||||
)
|
@ -13,7 +13,7 @@ import app.revanced.patches.tiktok.shared.fingerprints.OnRenderFirstFrameFingerp
|
||||
import app.revanced.util.exception
|
||||
import app.revanced.util.indexOfFirstInstructionOrThrow
|
||||
import com.android.tools.smali.dexlib2.Opcode
|
||||
import com.android.tools.smali.dexlib2.iface.instruction.formats.Instruction22c
|
||||
import com.android.tools.smali.dexlib2.iface.instruction.TwoRegisterInstruction
|
||||
|
||||
@Patch(
|
||||
name = "Remember clear display",
|
||||
@ -34,8 +34,8 @@ object RememberClearDisplayPatch : BytecodePatch(
|
||||
OnClearDisplayEventFingerprint.result?.mutableMethod?.let {
|
||||
// region Hook the "Clear display" configuration save event to remember the state of clear display.
|
||||
|
||||
val isEnabledIndex = it.indexOfFirstInstructionOrThrow { opcode == Opcode.IGET_BOOLEAN } + 1
|
||||
val isEnabledRegister = it.getInstruction<Instruction22c>(isEnabledIndex - 1).registerA
|
||||
val isEnabledIndex = it.indexOfFirstInstructionOrThrow(Opcode.IGET_BOOLEAN) + 1
|
||||
val isEnabledRegister = it.getInstruction<TwoRegisterInstruction>(isEnabledIndex - 1).registerA
|
||||
|
||||
it.addInstructions(
|
||||
isEnabledIndex,
|
||||
|
@ -10,5 +10,5 @@ internal object BuildMediaOptionsSheetFingerprint : MethodFingerprint(
|
||||
Opcode.GOTO_16,
|
||||
Opcode.NEW_INSTANCE,
|
||||
),
|
||||
strings = listOf("resources.getString(R.string.post_video)"),
|
||||
strings = listOf("mediaEntity", "media_options_sheet"),
|
||||
)
|
||||
|
@ -5,6 +5,6 @@ import com.android.tools.smali.dexlib2.Opcode
|
||||
|
||||
internal object ShowDownloadVideoUpsellBottomSheetFingerprint : MethodFingerprint(
|
||||
returnType = "Z",
|
||||
strings = listOf("variantToDownload.url"),
|
||||
strings = listOf("mediaEntity", "url"),
|
||||
opcodes = listOf(Opcode.IF_EQZ)
|
||||
)
|
||||
|
@ -0,0 +1,93 @@
|
||||
package app.revanced.patches.twitter.misc.links
|
||||
|
||||
import app.revanced.patcher.data.BytecodeContext
|
||||
import app.revanced.patcher.extensions.InstructionExtensions.addInstructions
|
||||
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.annotation.CompatiblePackage
|
||||
import app.revanced.patcher.patch.annotation.Patch
|
||||
import app.revanced.patcher.patch.options.PatchOption.PatchExtensions.stringPatchOption
|
||||
import app.revanced.patches.twitter.misc.links.fingerprints.LinkBuilderFingerprint
|
||||
import app.revanced.patches.twitter.misc.links.fingerprints.LinkResourceGetterFingerprint
|
||||
import app.revanced.patches.twitter.misc.links.fingerprints.LinkSharingDomainFingerprint
|
||||
import app.revanced.util.exception
|
||||
import app.revanced.util.getReference
|
||||
import app.revanced.util.indexOfFirstInstructionOrThrow
|
||||
import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction
|
||||
import com.android.tools.smali.dexlib2.iface.instruction.formats.Instruction35c
|
||||
import com.android.tools.smali.dexlib2.iface.reference.StringReference
|
||||
|
||||
@Patch(
|
||||
name = "Change link sharing domain",
|
||||
description = "Replaces the domain name of Twitter links when sharing them.",
|
||||
compatiblePackages = [CompatiblePackage("com.twitter.android")],
|
||||
)
|
||||
@Suppress("unused")
|
||||
object ChangeLinkSharingDomainPatch : BytecodePatch(
|
||||
setOf(
|
||||
LinkBuilderFingerprint,
|
||||
LinkResourceGetterFingerprint,
|
||||
LinkSharingDomainFingerprint,
|
||||
),
|
||||
) {
|
||||
private var domainName by stringPatchOption(
|
||||
key = "domainName",
|
||||
default = "fxtwitter.com",
|
||||
title = "Domain name",
|
||||
description = "The domain name to use when sharing links.",
|
||||
required = true,
|
||||
)
|
||||
|
||||
// This method is used to build the link that is shared when the "Share via..." button is pressed.
|
||||
private const val FORMAT_METHOD_RESOURCE_REFERENCE =
|
||||
"Lapp/revanced/integrations/twitter/patches/links/ChangeLinkSharingDomainPatch;->" +
|
||||
"formatResourceLink([Ljava/lang/Object;)Ljava/lang/String;"
|
||||
|
||||
// This method is used to build the link that is shared when the "Copy link" button is pressed.
|
||||
private const val FORMAT_METHOD_REFERENCE =
|
||||
"Lapp/revanced/integrations/twitter/patches/links/ChangeLinkSharingDomainPatch;->" +
|
||||
"formatLink(JLjava/lang/String;)Ljava/lang/String;"
|
||||
|
||||
override fun execute(context: BytecodeContext) {
|
||||
LinkSharingDomainFingerprint.result?.let {
|
||||
val replacementIndex = it.scanResult.stringsScanResult!!.matches.first().index
|
||||
val domainRegister = it.mutableMethod.getInstruction<OneRegisterInstruction>(replacementIndex).registerA
|
||||
it.mutableMethod.replaceInstruction(
|
||||
replacementIndex,
|
||||
"const-string v$domainRegister, \"https://$domainName\"",
|
||||
)
|
||||
} ?: throw LinkSharingDomainFingerprint.exception
|
||||
|
||||
// Replace the domain name when copying a link with "Copy link" button.
|
||||
LinkBuilderFingerprint.result?.let {
|
||||
it.mutableMethod.apply {
|
||||
addInstructions(
|
||||
0,
|
||||
"""
|
||||
invoke-static { p0, p1, p2 }, $FORMAT_METHOD_REFERENCE
|
||||
move-result-object p0
|
||||
return-object p0
|
||||
""",
|
||||
)
|
||||
}
|
||||
} ?: throw LinkBuilderFingerprint.exception
|
||||
|
||||
// Used in the Share via... dialog.
|
||||
LinkResourceGetterFingerprint.result?.mutableMethod?.apply {
|
||||
val constWithParameterName = indexOfFirstInstructionOrThrow {
|
||||
getReference<StringReference>()?.string?.contains("id.toString()") == true
|
||||
}
|
||||
|
||||
// Format the link with the new domain name register (2 instructions above the const-string).
|
||||
val formatLinkCallIndex = constWithParameterName - 2
|
||||
val formatLinkCall = getInstruction<Instruction35c>(formatLinkCallIndex)
|
||||
|
||||
// Replace the original method call with the new method call.
|
||||
replaceInstruction(
|
||||
formatLinkCallIndex,
|
||||
"invoke-static { v${formatLinkCall.registerE} }, $FORMAT_METHOD_RESOURCE_REFERENCE",
|
||||
)
|
||||
} ?: throw LinkResourceGetterFingerprint.exception
|
||||
}
|
||||
}
|
@ -0,0 +1,8 @@
|
||||
package app.revanced.patches.twitter.misc.links.fingerprints
|
||||
|
||||
import app.revanced.patcher.fingerprint.MethodFingerprint
|
||||
|
||||
// Returns a shareable link string based on a tweet ID and a username.
|
||||
internal object LinkBuilderFingerprint : MethodFingerprint(
|
||||
strings = listOf("/%1\$s/status/%2\$d"),
|
||||
)
|
@ -0,0 +1,12 @@
|
||||
package app.revanced.patches.twitter.misc.links.fingerprints
|
||||
|
||||
import app.revanced.patcher.extensions.or
|
||||
import app.revanced.patcher.fingerprint.MethodFingerprint
|
||||
import com.android.tools.smali.dexlib2.AccessFlags
|
||||
|
||||
// Gets Resource string for share link view available by pressing "Share via" button.
|
||||
internal object LinkResourceGetterFingerprint : MethodFingerprint(
|
||||
accessFlags = AccessFlags.PUBLIC or AccessFlags.FINAL,
|
||||
parameters = listOf("Landroid/content/res/Resources;"),
|
||||
strings = listOf("res.getString(R.string.t…lUsername, id.toString())"),
|
||||
)
|
@ -0,0 +1,7 @@
|
||||
package app.revanced.patches.twitter.misc.links.fingerprints
|
||||
|
||||
import app.revanced.patcher.fingerprint.MethodFingerprint
|
||||
|
||||
internal object LinkSharingDomainFingerprint : MethodFingerprint(
|
||||
strings = listOf("https://fxtwitter.com"),
|
||||
)
|
@ -0,0 +1,28 @@
|
||||
package app.revanced.patches.willhaben.ads
|
||||
|
||||
import app.revanced.patcher.data.BytecodeContext
|
||||
import app.revanced.patcher.patch.BytecodePatch
|
||||
import app.revanced.patcher.patch.annotation.CompatiblePackage
|
||||
import app.revanced.patcher.patch.annotation.Patch
|
||||
import app.revanced.patches.willhaben.ads.fingerprints.AdResolverFingerprint
|
||||
import app.revanced.patches.willhaben.ads.fingerprints.WHAdViewInjectorFingerprint
|
||||
import app.revanced.util.returnEarly
|
||||
|
||||
@Patch(
|
||||
name = "Hide ads",
|
||||
description = "Hides all in-app ads.",
|
||||
compatiblePackages = [CompatiblePackage("at.willhaben")]
|
||||
)
|
||||
@Suppress("unused")
|
||||
object HideAdsPatch : BytecodePatch(
|
||||
fingerprints = setOf(
|
||||
AdResolverFingerprint,
|
||||
WHAdViewInjectorFingerprint
|
||||
)
|
||||
) {
|
||||
override fun execute(context: BytecodeContext) {
|
||||
arrayOf(AdResolverFingerprint, WHAdViewInjectorFingerprint).forEach {
|
||||
it.returnEarly()
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,17 @@
|
||||
package app.revanced.patches.willhaben.ads.fingerprints
|
||||
|
||||
import app.revanced.patcher.extensions.or
|
||||
import app.revanced.patcher.fingerprint.MethodFingerprint
|
||||
import com.android.tools.smali.dexlib2.AccessFlags
|
||||
|
||||
internal object AdResolverFingerprint : MethodFingerprint(
|
||||
"L",
|
||||
parameters = listOf("L", "L"),
|
||||
accessFlags = AccessFlags.PUBLIC or AccessFlags.FINAL,
|
||||
strings = listOf(
|
||||
"Google Ad is invalid ",
|
||||
"Google Native Ad is invalid ",
|
||||
"Criteo Ad is invalid ",
|
||||
"Amazon Ad is invalid "
|
||||
)
|
||||
)
|
@ -0,0 +1,15 @@
|
||||
package app.revanced.patches.willhaben.ads.fingerprints
|
||||
|
||||
import app.revanced.patcher.extensions.or
|
||||
import app.revanced.patcher.fingerprint.MethodFingerprint
|
||||
import com.android.tools.smali.dexlib2.AccessFlags
|
||||
|
||||
internal object WHAdViewInjectorFingerprint : MethodFingerprint(
|
||||
"V",
|
||||
parameters = listOf("L", "L", "L", "Z"),
|
||||
accessFlags = AccessFlags.PUBLIC or AccessFlags.FINAL,
|
||||
strings = listOf("successfulAdView"),
|
||||
customFingerprint = { _, classDef ->
|
||||
classDef.type == "Lat/willhaben/advertising/WHAdView;"
|
||||
}
|
||||
)
|
@ -26,30 +26,11 @@ import com.android.tools.smali.dexlib2.iface.instruction.formats.Instruction35c
|
||||
CompatiblePackage(
|
||||
"com.google.android.youtube",
|
||||
[
|
||||
"18.32.39",
|
||||
"18.37.36",
|
||||
"18.38.44",
|
||||
"18.43.45",
|
||||
"18.44.41",
|
||||
"18.45.43",
|
||||
"18.48.39",
|
||||
"18.49.37",
|
||||
"19.01.34",
|
||||
"19.02.39",
|
||||
"19.03.36",
|
||||
"19.04.38",
|
||||
"19.05.36",
|
||||
"19.06.39",
|
||||
"19.07.40",
|
||||
"19.08.36",
|
||||
"19.09.38",
|
||||
"19.10.39",
|
||||
"19.11.43",
|
||||
"19.12.41",
|
||||
"19.13.37",
|
||||
"19.14.43",
|
||||
"19.15.36",
|
||||
"19.16.39",
|
||||
"19.25.37",
|
||||
"19.34.42",
|
||||
],
|
||||
),
|
||||
],
|
||||
|
@ -20,30 +20,11 @@ import com.android.tools.smali.dexlib2.iface.instruction.TwoRegisterInstruction
|
||||
compatiblePackages = [
|
||||
CompatiblePackage(
|
||||
"com.google.android.youtube", [
|
||||
"18.32.39",
|
||||
"18.37.36",
|
||||
"18.38.44",
|
||||
"18.43.45",
|
||||
"18.44.41",
|
||||
"18.45.43",
|
||||
"18.48.39",
|
||||
"18.49.37",
|
||||
"19.01.34",
|
||||
"19.02.39",
|
||||
"19.03.36",
|
||||
"19.04.38",
|
||||
"19.05.36",
|
||||
"19.06.39",
|
||||
"19.07.40",
|
||||
"19.08.36",
|
||||
"19.09.38",
|
||||
"19.10.39",
|
||||
"19.11.43",
|
||||
"19.12.41",
|
||||
"19.13.37",
|
||||
"19.14.43",
|
||||
"19.15.36",
|
||||
"19.16.39",
|
||||
"19.25.37",
|
||||
"19.34.42",
|
||||
]
|
||||
)
|
||||
]
|
||||
|
@ -25,30 +25,11 @@ import app.revanced.patches.youtube.misc.settings.SettingsPatch
|
||||
CompatiblePackage(
|
||||
"com.google.android.youtube",
|
||||
[
|
||||
"18.32.39",
|
||||
"18.37.36",
|
||||
"18.38.44",
|
||||
"18.43.45",
|
||||
"18.44.41",
|
||||
"18.45.43",
|
||||
"18.48.39",
|
||||
"18.49.37",
|
||||
"19.01.34",
|
||||
"19.02.39",
|
||||
"19.03.36",
|
||||
"19.04.38",
|
||||
"19.05.36",
|
||||
"19.06.39",
|
||||
"19.07.40",
|
||||
"19.08.36",
|
||||
"19.09.38",
|
||||
"19.10.39",
|
||||
"19.11.43",
|
||||
"19.12.41",
|
||||
"19.13.37",
|
||||
"19.14.43",
|
||||
"19.15.36",
|
||||
"19.16.39",
|
||||
"19.25.37",
|
||||
"19.34.42",
|
||||
]
|
||||
)
|
||||
]
|
||||
|
@ -19,24 +19,11 @@ import app.revanced.patches.youtube.video.information.VideoInformationPatch
|
||||
CompatiblePackage(
|
||||
"com.google.android.youtube",
|
||||
[
|
||||
"18.48.39",
|
||||
"18.38.44",
|
||||
"18.49.37",
|
||||
"19.01.34",
|
||||
"19.02.39",
|
||||
"19.03.36",
|
||||
"19.04.38",
|
||||
"19.05.36",
|
||||
"19.06.39",
|
||||
"19.07.40",
|
||||
"19.08.36",
|
||||
"19.09.38",
|
||||
"19.10.39",
|
||||
"19.11.43",
|
||||
"19.12.41",
|
||||
"19.13.37",
|
||||
"19.14.43",
|
||||
"19.15.36",
|
||||
"19.16.39",
|
||||
"19.25.37",
|
||||
"19.34.42",
|
||||
],
|
||||
),
|
||||
],
|
||||
|
@ -22,30 +22,11 @@ import com.android.tools.smali.dexlib2.iface.instruction.FiveRegisterInstruction
|
||||
compatiblePackages = [
|
||||
CompatiblePackage(
|
||||
"com.google.android.youtube", [
|
||||
"18.32.39",
|
||||
"18.37.36",
|
||||
"18.38.44",
|
||||
"18.43.45",
|
||||
"18.44.41",
|
||||
"18.45.43",
|
||||
"18.48.39",
|
||||
"18.49.37",
|
||||
"19.01.34",
|
||||
"19.02.39",
|
||||
"19.03.36",
|
||||
"19.04.38",
|
||||
"19.05.36",
|
||||
"19.06.39",
|
||||
"19.07.40",
|
||||
"19.08.36",
|
||||
"19.09.38",
|
||||
"19.10.39",
|
||||
"19.11.43",
|
||||
"19.12.41",
|
||||
"19.13.37",
|
||||
"19.14.43",
|
||||
"19.15.36",
|
||||
"19.16.39",
|
||||
"19.25.37",
|
||||
"19.34.42",
|
||||
]
|
||||
)
|
||||
]
|
||||
|
@ -25,24 +25,11 @@ import app.revanced.util.resultOrThrow
|
||||
CompatiblePackage(
|
||||
"com.google.android.youtube",
|
||||
[
|
||||
"18.48.39",
|
||||
"18.38.44",
|
||||
"18.49.37",
|
||||
"19.01.34",
|
||||
"19.02.39",
|
||||
"19.03.36",
|
||||
"19.04.38",
|
||||
"19.05.36",
|
||||
"19.06.39",
|
||||
"19.07.40",
|
||||
"19.08.36",
|
||||
"19.09.38",
|
||||
"19.10.39",
|
||||
"19.11.43",
|
||||
"19.12.41",
|
||||
"19.13.37",
|
||||
"19.14.43",
|
||||
"19.15.36",
|
||||
"19.16.39",
|
||||
"19.25.37",
|
||||
"19.34.42",
|
||||
],
|
||||
),
|
||||
],
|
||||
|
@ -24,30 +24,11 @@ import app.revanced.util.alsoResolve
|
||||
CompatiblePackage(
|
||||
"com.google.android.youtube",
|
||||
[
|
||||
"18.32.39",
|
||||
"18.37.36",
|
||||
"18.38.44",
|
||||
"18.43.45",
|
||||
"18.44.41",
|
||||
"18.45.43",
|
||||
"18.48.39",
|
||||
"18.49.37",
|
||||
"19.01.34",
|
||||
"19.02.39",
|
||||
"19.03.36",
|
||||
"19.04.38",
|
||||
"19.05.36",
|
||||
"19.06.39",
|
||||
"19.07.40",
|
||||
"19.08.36",
|
||||
"19.09.38",
|
||||
"19.10.39",
|
||||
"19.11.43",
|
||||
"19.12.41",
|
||||
"19.13.37",
|
||||
"19.14.43",
|
||||
"19.15.36",
|
||||
"19.16.39",
|
||||
"19.25.37",
|
||||
"19.34.42",
|
||||
]
|
||||
)
|
||||
]
|
||||
|
@ -27,27 +27,11 @@ import com.android.tools.smali.dexlib2.iface.reference.MethodReference
|
||||
CompatiblePackage(
|
||||
"com.google.android.youtube",
|
||||
[
|
||||
"18.43.45",
|
||||
"18.44.41",
|
||||
"18.45.43",
|
||||
"18.48.39",
|
||||
// 18.38.44 patches but crashes on startup.
|
||||
"18.49.37",
|
||||
"19.01.34",
|
||||
"19.02.39",
|
||||
"19.03.36",
|
||||
"19.04.38",
|
||||
"19.05.36",
|
||||
"19.06.39",
|
||||
"19.07.40",
|
||||
"19.08.36",
|
||||
"19.09.38",
|
||||
"19.10.39",
|
||||
"19.11.43",
|
||||
"19.12.41",
|
||||
"19.13.37",
|
||||
"19.14.43",
|
||||
"19.15.36",
|
||||
"19.16.39",
|
||||
"19.25.37",
|
||||
"19.34.42",
|
||||
]
|
||||
)
|
||||
]
|
||||
|
@ -4,46 +4,37 @@ import app.revanced.patcher.data.BytecodeContext
|
||||
import app.revanced.patcher.extensions.InstructionExtensions.addInstructions
|
||||
import app.revanced.patcher.extensions.InstructionExtensions.getInstruction
|
||||
import app.revanced.patcher.patch.BytecodePatch
|
||||
import app.revanced.patcher.patch.PatchException
|
||||
import app.revanced.patcher.patch.annotation.CompatiblePackage
|
||||
import app.revanced.patcher.patch.annotation.Patch
|
||||
import app.revanced.patches.all.misc.resources.AddResourcesPatch
|
||||
import app.revanced.patches.shared.misc.settings.preference.SwitchPreference
|
||||
import app.revanced.patches.youtube.interaction.seekbar.fingerprints.DoubleSpeedSeekNoticeFingerprint
|
||||
import app.revanced.patches.youtube.interaction.seekbar.fingerprints.DisableFastForwardLegacyFingerprint
|
||||
import app.revanced.patches.youtube.interaction.seekbar.fingerprints.DisableFastForwardGestureFingerprint
|
||||
import app.revanced.patches.youtube.interaction.seekbar.fingerprints.DisableFastForwardNoticeFingerprint
|
||||
import app.revanced.patches.youtube.interaction.seekbar.fingerprints.SlideToSeekFingerprint
|
||||
import app.revanced.patches.youtube.misc.integrations.IntegrationsPatch
|
||||
import app.revanced.patches.youtube.misc.playservice.VersionCheckPatch
|
||||
import app.revanced.patches.youtube.misc.settings.SettingsPatch
|
||||
import app.revanced.util.exception
|
||||
import app.revanced.util.getReference
|
||||
import app.revanced.util.resultOrThrow
|
||||
import com.android.tools.smali.dexlib2.Opcode
|
||||
import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction
|
||||
import com.android.tools.smali.dexlib2.iface.reference.MethodReference
|
||||
|
||||
@Patch(
|
||||
name = "Enable slide to seek",
|
||||
description = "Adds an option to enable slide to seek instead of playing at 2x speed when pressing and holding in the video player. Including this patch may cause issues with tapping or double tapping the video player overlay.",
|
||||
description = "Adds an option to enable slide to seek instead of playing at 2x speed when pressing and holding in the video player. Including this patch may cause issues with the video player overlay, such as missing buttons and ignored taps and double taps.",
|
||||
dependencies = [IntegrationsPatch::class, SettingsPatch::class, AddResourcesPatch::class],
|
||||
compatiblePackages = [
|
||||
CompatiblePackage(
|
||||
"com.google.android.youtube",
|
||||
[
|
||||
"18.43.45",
|
||||
"18.44.41",
|
||||
"18.45.43",
|
||||
"18.48.39",
|
||||
"18.38.44",
|
||||
"18.49.37",
|
||||
"19.01.34",
|
||||
"19.02.39",
|
||||
"19.03.36",
|
||||
"19.04.38",
|
||||
"19.05.36",
|
||||
"19.06.39",
|
||||
"19.07.40",
|
||||
"19.08.36",
|
||||
"19.09.38",
|
||||
"19.10.39",
|
||||
"19.11.43",
|
||||
"19.12.41",
|
||||
"19.13.37",
|
||||
"19.14.43",
|
||||
"19.15.36",
|
||||
"19.16.39",
|
||||
"19.25.37",
|
||||
"19.34.42",
|
||||
]
|
||||
)
|
||||
],
|
||||
@ -53,10 +44,13 @@ import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction
|
||||
object EnableSlideToSeekPatch : BytecodePatch(
|
||||
setOf(
|
||||
SlideToSeekFingerprint,
|
||||
DoubleSpeedSeekNoticeFingerprint
|
||||
DisableFastForwardLegacyFingerprint,
|
||||
DisableFastForwardGestureFingerprint,
|
||||
DisableFastForwardNoticeFingerprint
|
||||
)
|
||||
) {
|
||||
private const val INTEGRATIONS_CLASS_DESCRIPTOR = "Lapp/revanced/integrations/youtube/patches/SlideToSeekPatch;"
|
||||
private const val INTEGRATIONS_METHOD_DESCRIPTOR =
|
||||
"Lapp/revanced/integrations/youtube/patches/SlideToSeekPatch;->isSlideToSeekDisabled(Z)Z"
|
||||
|
||||
override fun execute(context: BytecodeContext) {
|
||||
AddResourcesPatch(this::class)
|
||||
@ -65,27 +59,74 @@ object EnableSlideToSeekPatch : BytecodePatch(
|
||||
SwitchPreference("revanced_slide_to_seek")
|
||||
)
|
||||
|
||||
arrayOf(
|
||||
// Restore the behaviour to slide to seek.
|
||||
SlideToSeekFingerprint,
|
||||
// Disable the double speed seek notice.
|
||||
DoubleSpeedSeekNoticeFingerprint
|
||||
).map {
|
||||
it.result ?: throw it.exception
|
||||
}.forEach {
|
||||
val insertIndex = it.scanResult.patternScanResult!!.endIndex + 1
|
||||
var modifiedMethods = false
|
||||
|
||||
it.mutableMethod.apply {
|
||||
val isEnabledRegister = getInstruction<OneRegisterInstruction>(insertIndex).registerA
|
||||
// Restore the behaviour to slide to seek.
|
||||
SlideToSeekFingerprint.resultOrThrow().let {
|
||||
val checkIndex = it.scanResult.patternScanResult!!.startIndex
|
||||
val checkReference = it.mutableMethod
|
||||
.getInstruction(checkIndex).getReference<MethodReference>()!!
|
||||
|
||||
addInstructions(
|
||||
insertIndex,
|
||||
"""
|
||||
invoke-static { }, $INTEGRATIONS_CLASS_DESCRIPTOR->isSlideToSeekDisabled()Z
|
||||
move-result v$isEnabledRegister
|
||||
"""
|
||||
)
|
||||
// A/B check method was only called on this class.
|
||||
it.mutableClass.methods.forEach { method ->
|
||||
method.implementation!!.instructions.forEachIndexed { index, instruction ->
|
||||
if (instruction.opcode == Opcode.INVOKE_VIRTUAL &&
|
||||
instruction.getReference<MethodReference>() == checkReference
|
||||
) {
|
||||
method.apply {
|
||||
val targetRegister = getInstruction<OneRegisterInstruction>(index + 1).registerA
|
||||
|
||||
addInstructions(
|
||||
index + 2,
|
||||
"""
|
||||
invoke-static { v$targetRegister }, $INTEGRATIONS_METHOD_DESCRIPTOR
|
||||
move-result v$targetRegister
|
||||
"""
|
||||
)
|
||||
}
|
||||
|
||||
modifiedMethods = true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!modifiedMethods) throw PatchException("Could not find methods to modify")
|
||||
|
||||
// Disable the double speed seek gesture.
|
||||
if (!VersionCheckPatch.is_19_17_or_greater) {
|
||||
DisableFastForwardLegacyFingerprint.resultOrThrow().let {
|
||||
it.mutableMethod.apply {
|
||||
val insertIndex = it.scanResult.patternScanResult!!.endIndex + 1
|
||||
val targetRegister = getInstruction<OneRegisterInstruction>(insertIndex).registerA
|
||||
|
||||
addInstructions(
|
||||
insertIndex,
|
||||
"""
|
||||
invoke-static { v$targetRegister }, $INTEGRATIONS_METHOD_DESCRIPTOR
|
||||
move-result v$targetRegister
|
||||
"""
|
||||
)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
arrayOf(
|
||||
DisableFastForwardGestureFingerprint,
|
||||
DisableFastForwardNoticeFingerprint
|
||||
).forEach { it.resultOrThrow().let {
|
||||
it.mutableMethod.apply {
|
||||
val targetIndex = it.scanResult.patternScanResult!!.endIndex
|
||||
val targetRegister = getInstruction<OneRegisterInstruction>(targetIndex).registerA
|
||||
|
||||
addInstructions(
|
||||
targetIndex + 1,
|
||||
"""
|
||||
invoke-static { v$targetRegister }, $INTEGRATIONS_METHOD_DESCRIPTOR
|
||||
move-result v$targetRegister
|
||||
"""
|
||||
)
|
||||
}
|
||||
}}
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,21 @@
|
||||
package app.revanced.patches.youtube.interaction.seekbar.fingerprints
|
||||
|
||||
import app.revanced.patcher.extensions.or
|
||||
import app.revanced.patcher.fingerprint.MethodFingerprint
|
||||
import com.android.tools.smali.dexlib2.AccessFlags
|
||||
import com.android.tools.smali.dexlib2.Opcode
|
||||
|
||||
internal object DisableFastForwardGestureFingerprint : MethodFingerprint(
|
||||
accessFlags = AccessFlags.PUBLIC or AccessFlags.FINAL,
|
||||
returnType = "Z",
|
||||
parameters = emptyList(),
|
||||
opcodes = listOf(
|
||||
Opcode.IF_EQZ,
|
||||
Opcode.INVOKE_VIRTUAL,
|
||||
Opcode.MOVE_RESULT
|
||||
),
|
||||
customFingerprint = { methodDef, classDef ->
|
||||
methodDef.implementation!!.instructions.count() > 30 &&
|
||||
classDef.type.endsWith("/NextGenWatchLayout;")
|
||||
}
|
||||
)
|
@ -3,7 +3,7 @@ package app.revanced.patches.youtube.interaction.seekbar.fingerprints
|
||||
import app.revanced.util.patch.LiteralValueFingerprint
|
||||
import com.android.tools.smali.dexlib2.Opcode
|
||||
|
||||
internal object DoubleSpeedSeekNoticeFingerprint : LiteralValueFingerprint(
|
||||
internal object DisableFastForwardLegacyFingerprint : LiteralValueFingerprint(
|
||||
returnType = "Z",
|
||||
parameters = emptyList(),
|
||||
opcodes = listOf(Opcode.MOVE_RESULT),
|
@ -0,0 +1,19 @@
|
||||
package app.revanced.patches.youtube.interaction.seekbar.fingerprints
|
||||
|
||||
import app.revanced.patcher.extensions.or
|
||||
import app.revanced.patcher.fingerprint.MethodFingerprint
|
||||
import com.android.tools.smali.dexlib2.AccessFlags
|
||||
import com.android.tools.smali.dexlib2.Opcode
|
||||
|
||||
internal object DisableFastForwardNoticeFingerprint : MethodFingerprint(
|
||||
accessFlags = AccessFlags.PUBLIC or AccessFlags.FINAL,
|
||||
returnType = "V",
|
||||
parameters = emptyList(),
|
||||
opcodes = listOf(
|
||||
Opcode.CHECK_CAST,
|
||||
Opcode.IGET_OBJECT,
|
||||
Opcode.INVOKE_VIRTUAL,
|
||||
Opcode.MOVE_RESULT
|
||||
),
|
||||
strings = listOf("Failed to easy seek haptics vibrate")
|
||||
)
|
@ -2,10 +2,9 @@ package app.revanced.patches.youtube.interaction.seekbar.fingerprints
|
||||
|
||||
import app.revanced.patcher.extensions.or
|
||||
import app.revanced.patcher.fingerprint.MethodFingerprint
|
||||
import app.revanced.util.containsWideLiteralInstructionValue
|
||||
import com.android.tools.smali.dexlib2.AccessFlags
|
||||
import com.android.tools.smali.dexlib2.Opcode
|
||||
import com.android.tools.smali.dexlib2.iface.instruction.NarrowLiteralInstruction
|
||||
|
||||
|
||||
internal object SeekbarTappingFingerprint : MethodFingerprint(
|
||||
returnType = "Z",
|
||||
@ -21,14 +20,6 @@ internal object SeekbarTappingFingerprint : MethodFingerprint(
|
||||
customFingerprint = custom@{ methodDef, _ ->
|
||||
if (methodDef.name != "onTouchEvent") return@custom false
|
||||
|
||||
methodDef.implementation!!.instructions.any { instruction ->
|
||||
if (instruction.opcode != Opcode.CONST) return@any false
|
||||
|
||||
val literal = (instruction as NarrowLiteralInstruction).narrowLiteral
|
||||
|
||||
// onTouchEvent method contains a CONST instruction
|
||||
// with this literal making it unique with the rest of the properties of this fingerprint.
|
||||
literal == Integer.MAX_VALUE
|
||||
}
|
||||
methodDef.containsWideLiteralInstructionValue(Integer.MAX_VALUE.toLong())
|
||||
}
|
||||
)
|
@ -1,11 +1,19 @@
|
||||
package app.revanced.patches.youtube.interaction.seekbar.fingerprints
|
||||
|
||||
import app.revanced.patcher.extensions.or
|
||||
import app.revanced.util.patch.LiteralValueFingerprint
|
||||
import com.android.tools.smali.dexlib2.AccessFlags
|
||||
import com.android.tools.smali.dexlib2.Opcode
|
||||
|
||||
internal object SlideToSeekFingerprint : LiteralValueFingerprint(
|
||||
returnType = "Z",
|
||||
parameters = emptyList(),
|
||||
opcodes = listOf(Opcode.MOVE_RESULT),
|
||||
literalSupplier = { 45411329 }
|
||||
accessFlags = AccessFlags.PRIVATE or AccessFlags.FINAL,
|
||||
returnType = "V",
|
||||
parameters = listOf("Landroid/view/View;", "F"),
|
||||
opcodes = listOf(
|
||||
Opcode.INVOKE_VIRTUAL,
|
||||
Opcode.MOVE_RESULT,
|
||||
Opcode.IF_EQZ,
|
||||
Opcode.GOTO_16
|
||||
),
|
||||
literalSupplier = { 67108864 }
|
||||
)
|
@ -1,11 +1,8 @@
|
||||
package app.revanced.patches.youtube.interaction.seekbar.fingerprints
|
||||
|
||||
import app.revanced.patcher.extensions.or
|
||||
import app.revanced.util.patch.LiteralValueFingerprint
|
||||
import com.android.tools.smali.dexlib2.AccessFlags
|
||||
|
||||
internal object SwipingUpGestureParentFingerprint : LiteralValueFingerprint(
|
||||
accessFlags = AccessFlags.PUBLIC or AccessFlags.FINAL,
|
||||
returnType = "Z",
|
||||
parameters = listOf(),
|
||||
literalSupplier = { 45379021 }
|
||||
|
@ -26,30 +26,11 @@ import com.android.tools.smali.dexlib2.immutable.ImmutableMethod
|
||||
CompatiblePackage(
|
||||
"com.google.android.youtube",
|
||||
[
|
||||
"18.32.39",
|
||||
"18.37.36",
|
||||
"18.38.44",
|
||||
"18.43.45",
|
||||
"18.44.41",
|
||||
"18.45.43",
|
||||
"18.48.39",
|
||||
"18.49.37",
|
||||
"19.01.34",
|
||||
"19.02.39",
|
||||
"19.03.36",
|
||||
"19.04.38",
|
||||
"19.05.36",
|
||||
"19.06.39",
|
||||
"19.07.40",
|
||||
"19.08.36",
|
||||
"19.09.38",
|
||||
"19.10.39",
|
||||
"19.11.43",
|
||||
"19.12.41",
|
||||
"19.13.37",
|
||||
"19.14.43",
|
||||
"19.15.36",
|
||||
"19.16.39",
|
||||
"19.25.37",
|
||||
"19.34.42",
|
||||
],
|
||||
),
|
||||
],
|
||||
|
@ -24,30 +24,11 @@ import app.revanced.util.exception
|
||||
CompatiblePackage(
|
||||
"com.google.android.youtube",
|
||||
[
|
||||
"18.32.39",
|
||||
"18.37.36",
|
||||
"18.38.44",
|
||||
"18.43.45",
|
||||
"18.44.41",
|
||||
"18.45.43",
|
||||
"18.48.39",
|
||||
"18.49.37",
|
||||
"19.01.34",
|
||||
"19.02.39",
|
||||
"19.03.36",
|
||||
"19.04.38",
|
||||
"19.05.36",
|
||||
"19.06.39",
|
||||
"19.07.40",
|
||||
"19.08.36",
|
||||
"19.09.38",
|
||||
"19.10.39",
|
||||
"19.11.43",
|
||||
"19.12.41",
|
||||
"19.13.37",
|
||||
"19.14.43",
|
||||
"19.15.36",
|
||||
"19.16.39",
|
||||
"19.25.37",
|
||||
"19.34.42",
|
||||
]
|
||||
)
|
||||
],
|
||||
|
@ -23,30 +23,11 @@ import app.revanced.patches.youtube.misc.settings.SettingsPatch
|
||||
CompatiblePackage(
|
||||
"com.google.android.youtube",
|
||||
[
|
||||
"18.32.39",
|
||||
"18.37.36",
|
||||
"18.38.44",
|
||||
"18.43.45",
|
||||
"18.44.41",
|
||||
"18.45.43",
|
||||
"18.48.39",
|
||||
"18.49.37",
|
||||
"19.01.34",
|
||||
"19.02.39",
|
||||
"19.03.36",
|
||||
"19.04.38",
|
||||
"19.05.36",
|
||||
"19.06.39",
|
||||
"19.07.40",
|
||||
"19.08.36",
|
||||
"19.09.38",
|
||||
"19.10.39",
|
||||
"19.11.43",
|
||||
"19.12.41",
|
||||
"19.13.37",
|
||||
"19.14.43",
|
||||
"19.15.36",
|
||||
"19.16.39",
|
||||
"19.25.37",
|
||||
"19.34.42",
|
||||
]
|
||||
)
|
||||
]
|
||||
|
@ -34,30 +34,11 @@ import com.android.tools.smali.dexlib2.iface.reference.MethodReference
|
||||
CompatiblePackage(
|
||||
"com.google.android.youtube",
|
||||
[
|
||||
"18.32.39",
|
||||
"18.37.36",
|
||||
"18.38.44",
|
||||
"18.43.45",
|
||||
"18.44.41",
|
||||
"18.45.43",
|
||||
"18.48.39",
|
||||
"18.49.37",
|
||||
"19.01.34",
|
||||
"19.02.39",
|
||||
"19.03.36",
|
||||
"19.04.38",
|
||||
"19.05.36",
|
||||
"19.06.39",
|
||||
"19.07.40",
|
||||
"19.08.36",
|
||||
"19.09.38",
|
||||
"19.10.39",
|
||||
"19.11.43",
|
||||
"19.12.41",
|
||||
"19.13.37",
|
||||
"19.14.43",
|
||||
"19.15.36",
|
||||
"19.16.39",
|
||||
"19.25.37",
|
||||
"19.34.42",
|
||||
],
|
||||
),
|
||||
],
|
||||
|
@ -24,30 +24,11 @@ import com.android.tools.smali.dexlib2.Opcode
|
||||
CompatiblePackage(
|
||||
"com.google.android.youtube",
|
||||
[
|
||||
"18.32.39",
|
||||
"18.37.36",
|
||||
"18.38.44",
|
||||
"18.43.45",
|
||||
"18.44.41",
|
||||
"18.45.43",
|
||||
"18.48.39",
|
||||
"18.49.37",
|
||||
"19.01.34",
|
||||
"19.02.39",
|
||||
"19.03.36",
|
||||
"19.04.38",
|
||||
"19.05.36",
|
||||
"19.06.39",
|
||||
"19.07.40",
|
||||
"19.08.36",
|
||||
"19.09.38",
|
||||
"19.10.39",
|
||||
"19.11.43",
|
||||
"19.12.41",
|
||||
"19.13.37",
|
||||
"19.14.43",
|
||||
"19.15.36",
|
||||
"19.16.39",
|
||||
"19.25.37",
|
||||
"19.34.42",
|
||||
]
|
||||
)
|
||||
]
|
||||
|
@ -37,30 +37,11 @@ import com.android.tools.smali.dexlib2.iface.reference.MethodReference
|
||||
CompatiblePackage(
|
||||
"com.google.android.youtube",
|
||||
[
|
||||
"18.32.39",
|
||||
"18.37.36",
|
||||
"18.38.44",
|
||||
"18.43.45",
|
||||
"18.44.41",
|
||||
"18.45.43",
|
||||
"18.48.39",
|
||||
"18.49.37",
|
||||
"19.01.34",
|
||||
"19.02.39",
|
||||
"19.03.36",
|
||||
"19.04.38",
|
||||
"19.05.36",
|
||||
"19.06.39",
|
||||
"19.07.40",
|
||||
"19.08.36",
|
||||
"19.09.38",
|
||||
"19.10.39",
|
||||
"19.11.43",
|
||||
"19.12.41",
|
||||
"19.13.37",
|
||||
"19.14.43",
|
||||
"19.15.36",
|
||||
"19.16.39",
|
||||
"19.25.37",
|
||||
"19.34.42",
|
||||
],
|
||||
),
|
||||
],
|
||||
|
@ -1,20 +1,23 @@
|
||||
package app.revanced.patches.youtube.layout.buttons.player.hide
|
||||
|
||||
import app.revanced.patcher.data.BytecodeContext
|
||||
import app.revanced.patcher.extensions.InstructionExtensions.addInstructions
|
||||
import app.revanced.patcher.extensions.InstructionExtensions.addInstruction
|
||||
import app.revanced.patcher.extensions.InstructionExtensions.getInstruction
|
||||
import app.revanced.patcher.patch.BytecodePatch
|
||||
import app.revanced.patcher.patch.annotation.CompatiblePackage
|
||||
import app.revanced.patcher.patch.annotation.Patch
|
||||
import app.revanced.patches.all.misc.resources.AddResourcesPatch
|
||||
import app.revanced.patches.shared.misc.settings.preference.SwitchPreference
|
||||
import app.revanced.patches.youtube.layout.buttons.player.hide.HidePlayerButtonsPatch.ParameterOffsets.HAS_NEXT
|
||||
import app.revanced.patches.youtube.layout.buttons.player.hide.HidePlayerButtonsPatch.ParameterOffsets.HAS_PREVIOUS
|
||||
import app.revanced.patches.youtube.layout.buttons.player.hide.fingerprints.PlayerControlsVisibilityModelFingerprint
|
||||
import app.revanced.patches.youtube.layout.buttons.player.hide.fingerprints.PlayerControlsPreviousNextOverlayTouchFingerprint
|
||||
import app.revanced.patches.youtube.misc.integrations.IntegrationsPatch
|
||||
import app.revanced.patches.youtube.misc.settings.SettingsPatch
|
||||
import app.revanced.util.exception
|
||||
import com.android.tools.smali.dexlib2.iface.instruction.formats.Instruction3rc
|
||||
import app.revanced.util.getReference
|
||||
import app.revanced.util.indexOfFirstInstructionOrThrow
|
||||
import app.revanced.util.indexOfFirstWideLiteralInstructionValueOrThrow
|
||||
import app.revanced.util.resultOrThrow
|
||||
import com.android.tools.smali.dexlib2.Opcode
|
||||
import com.android.tools.smali.dexlib2.iface.instruction.FiveRegisterInstruction
|
||||
import com.android.tools.smali.dexlib2.iface.reference.MethodReference
|
||||
|
||||
@Patch(
|
||||
name = "Hide player buttons",
|
||||
@ -22,43 +25,25 @@ import com.android.tools.smali.dexlib2.iface.instruction.formats.Instruction3rc
|
||||
dependencies = [
|
||||
IntegrationsPatch::class,
|
||||
SettingsPatch::class,
|
||||
AddResourcesPatch::class
|
||||
AddResourcesPatch::class,
|
||||
HidePlayerButtonsResourcePatch::class,
|
||||
],
|
||||
compatiblePackages = [
|
||||
CompatiblePackage(
|
||||
"com.google.android.youtube",
|
||||
[
|
||||
"18.32.39",
|
||||
"18.37.36",
|
||||
"18.38.44",
|
||||
"18.43.45",
|
||||
"18.44.41",
|
||||
"18.45.43",
|
||||
"18.48.39",
|
||||
"18.49.37",
|
||||
"19.01.34",
|
||||
"19.02.39",
|
||||
"19.03.36",
|
||||
"19.04.38",
|
||||
"19.05.36",
|
||||
"19.06.39",
|
||||
"19.07.40",
|
||||
"19.08.36",
|
||||
"19.09.38",
|
||||
"19.10.39",
|
||||
"19.11.43",
|
||||
"19.12.41",
|
||||
"19.13.37",
|
||||
"19.14.43",
|
||||
"19.15.36",
|
||||
"19.16.39",
|
||||
"19.25.37",
|
||||
"19.34.42",
|
||||
]
|
||||
)
|
||||
]
|
||||
)
|
||||
@Suppress("unused")
|
||||
object HidePlayerButtonsPatch : BytecodePatch(
|
||||
setOf(PlayerControlsVisibilityModelFingerprint)
|
||||
setOf(PlayerControlsPreviousNextOverlayTouchFingerprint)
|
||||
) {
|
||||
override fun execute(context: BytecodeContext) {
|
||||
AddResourcesPatch(this::class)
|
||||
@ -67,29 +52,23 @@ object HidePlayerButtonsPatch : BytecodePatch(
|
||||
SwitchPreference("revanced_hide_player_buttons")
|
||||
)
|
||||
|
||||
PlayerControlsVisibilityModelFingerprint.result?.apply {
|
||||
val callIndex = scanResult.patternScanResult!!.endIndex
|
||||
val callInstruction = mutableMethod.getInstruction<Instruction3rc>(callIndex)
|
||||
|
||||
// overriding this parameter register hides the previous and next buttons
|
||||
val hasNextParameterRegister = callInstruction.startRegister + HAS_NEXT
|
||||
val hasPreviousParameterRegister = callInstruction.startRegister + HAS_PREVIOUS
|
||||
|
||||
mutableMethod.addInstructions(
|
||||
callIndex,
|
||||
"""
|
||||
invoke-static { v$hasNextParameterRegister }, Lapp/revanced/integrations/youtube/patches/HidePlayerButtonsPatch;->previousOrNextButtonIsVisible(Z)Z
|
||||
move-result v$hasNextParameterRegister
|
||||
|
||||
invoke-static { v$hasPreviousParameterRegister }, Lapp/revanced/integrations/youtube/patches/HidePlayerButtonsPatch;->previousOrNextButtonIsVisible(Z)Z
|
||||
move-result v$hasPreviousParameterRegister
|
||||
"""
|
||||
PlayerControlsPreviousNextOverlayTouchFingerprint.resultOrThrow().mutableMethod.apply {
|
||||
val resourceIndex = indexOfFirstWideLiteralInstructionValueOrThrow(
|
||||
HidePlayerButtonsResourcePatch.playerControlPreviousButtonTouchArea
|
||||
)
|
||||
} ?: throw PlayerControlsVisibilityModelFingerprint.exception
|
||||
}
|
||||
|
||||
private object ParameterOffsets {
|
||||
const val HAS_NEXT = 5
|
||||
const val HAS_PREVIOUS = 6
|
||||
val insertIndex = indexOfFirstInstructionOrThrow(resourceIndex) {
|
||||
opcode == Opcode.INVOKE_STATIC
|
||||
&& getReference<MethodReference>()?.parameterTypes?.firstOrNull() == "Landroid/view/View;"
|
||||
}
|
||||
|
||||
val viewRegister = getInstruction<FiveRegisterInstruction>(insertIndex).registerC
|
||||
|
||||
addInstruction(
|
||||
insertIndex,
|
||||
"invoke-static { v$viewRegister }, Lapp/revanced/integrations/youtube/patches/HidePlayerButtonsPatch;" +
|
||||
"->hidePreviousNextButtons(Landroid/view/View;)V"
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,24 @@
|
||||
package app.revanced.patches.youtube.layout.buttons.player.hide
|
||||
|
||||
import app.revanced.patcher.data.ResourceContext
|
||||
import app.revanced.patcher.patch.ResourcePatch
|
||||
import app.revanced.patcher.patch.annotation.Patch
|
||||
import app.revanced.patches.shared.misc.mapping.ResourceMappingPatch
|
||||
|
||||
@Patch(dependencies = [ResourceMappingPatch::class])
|
||||
internal object HidePlayerButtonsResourcePatch : ResourcePatch() {
|
||||
var playerControlPreviousButtonTouchArea = -1L
|
||||
var playerControlNextButtonTouchArea = -1L
|
||||
|
||||
override fun execute(context: ResourceContext) {
|
||||
playerControlPreviousButtonTouchArea = ResourceMappingPatch[
|
||||
"id",
|
||||
"player_control_previous_button_touch_area"
|
||||
]
|
||||
|
||||
playerControlNextButtonTouchArea = ResourceMappingPatch[
|
||||
"id",
|
||||
"player_control_next_button_touch_area"
|
||||
]
|
||||
}
|
||||
}
|
@ -0,0 +1,20 @@
|
||||
package app.revanced.patches.youtube.layout.buttons.player.hide.fingerprints
|
||||
|
||||
import app.revanced.patcher.extensions.or
|
||||
import app.revanced.patcher.fingerprint.MethodFingerprint
|
||||
import app.revanced.patches.youtube.layout.buttons.player.hide.HidePlayerButtonsResourcePatch
|
||||
import app.revanced.util.containsWideLiteralInstructionValue
|
||||
import com.android.tools.smali.dexlib2.AccessFlags
|
||||
|
||||
internal object PlayerControlsPreviousNextOverlayTouchFingerprint : MethodFingerprint(
|
||||
accessFlags = AccessFlags.PUBLIC or AccessFlags.FINAL,
|
||||
returnType = "V",
|
||||
strings = listOf("1.0x"),
|
||||
customFingerprint = { methodDef, _ ->
|
||||
methodDef.containsWideLiteralInstructionValue(
|
||||
HidePlayerButtonsResourcePatch.playerControlPreviousButtonTouchArea
|
||||
) && methodDef.containsWideLiteralInstructionValue(
|
||||
HidePlayerButtonsResourcePatch.playerControlNextButtonTouchArea
|
||||
)
|
||||
}
|
||||
)
|
@ -1,9 +0,0 @@
|
||||
package app.revanced.patches.youtube.layout.buttons.player.hide.fingerprints
|
||||
|
||||
import app.revanced.patcher.fingerprint.MethodFingerprint
|
||||
import com.android.tools.smali.dexlib2.Opcode
|
||||
|
||||
internal object PlayerControlsVisibilityModelFingerprint : MethodFingerprint(
|
||||
opcodes = listOf(Opcode.INVOKE_DIRECT_RANGE),
|
||||
strings = listOf("Missing required properties:", "hasNext", "hasPrevious")
|
||||
)
|
@ -22,30 +22,11 @@ import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction
|
||||
CompatiblePackage(
|
||||
"com.google.android.youtube",
|
||||
[
|
||||
"18.32.39",
|
||||
"18.37.36",
|
||||
"18.38.44",
|
||||
"18.43.45",
|
||||
"18.44.41",
|
||||
"18.45.43",
|
||||
"18.48.39",
|
||||
"18.49.37",
|
||||
"19.01.34",
|
||||
"19.02.39",
|
||||
"19.03.36",
|
||||
"19.04.38",
|
||||
"19.05.36",
|
||||
"19.06.39",
|
||||
"19.07.40",
|
||||
"19.08.36",
|
||||
"19.09.38",
|
||||
"19.10.39",
|
||||
"19.11.43",
|
||||
"19.12.41",
|
||||
"19.13.37",
|
||||
"19.14.43",
|
||||
"19.15.36",
|
||||
"19.16.39",
|
||||
"19.25.37",
|
||||
"19.34.42",
|
||||
]
|
||||
)
|
||||
]
|
||||
|
@ -22,30 +22,11 @@ import app.revanced.patches.youtube.misc.settings.SettingsPatch
|
||||
CompatiblePackage(
|
||||
"com.google.android.youtube",
|
||||
[
|
||||
"18.32.39",
|
||||
"18.37.36",
|
||||
"18.38.44",
|
||||
"18.43.45",
|
||||
"18.44.41",
|
||||
"18.45.43",
|
||||
"18.48.39",
|
||||
"18.49.37",
|
||||
"19.01.34",
|
||||
"19.02.39",
|
||||
"19.03.36",
|
||||
"19.04.38",
|
||||
"19.05.36",
|
||||
"19.06.39",
|
||||
"19.07.40",
|
||||
"19.08.36",
|
||||
"19.09.38",
|
||||
"19.10.39",
|
||||
"19.11.43",
|
||||
"19.12.41",
|
||||
"19.13.37",
|
||||
"19.14.43",
|
||||
"19.15.36",
|
||||
"19.16.39",
|
||||
"19.25.37",
|
||||
"19.34.42",
|
||||
]
|
||||
)
|
||||
]
|
||||
|
@ -22,30 +22,11 @@ import com.android.tools.smali.dexlib2.iface.instruction.TwoRegisterInstruction
|
||||
CompatiblePackage(
|
||||
"com.google.android.youtube",
|
||||
[
|
||||
"18.32.39",
|
||||
"18.37.36",
|
||||
"18.38.44",
|
||||
"18.43.45",
|
||||
"18.44.41",
|
||||
"18.45.43",
|
||||
"18.48.39",
|
||||
"18.49.37",
|
||||
"19.01.34",
|
||||
"19.02.39",
|
||||
"19.03.36",
|
||||
"19.04.38",
|
||||
"19.05.36",
|
||||
"19.06.39",
|
||||
"19.07.40",
|
||||
"19.08.36",
|
||||
"19.09.38",
|
||||
"19.10.39",
|
||||
"19.11.43",
|
||||
"19.12.41",
|
||||
"19.13.37",
|
||||
"19.14.43",
|
||||
"19.15.36",
|
||||
"19.16.39",
|
||||
"19.25.37",
|
||||
"19.34.42",
|
||||
]
|
||||
)
|
||||
]
|
||||
|
@ -25,30 +25,11 @@ import com.android.tools.smali.dexlib2.iface.instruction.formats.Instruction21c
|
||||
CompatiblePackage(
|
||||
"com.google.android.youtube",
|
||||
[
|
||||
"18.32.39",
|
||||
"18.37.36",
|
||||
"18.38.44",
|
||||
"18.43.45",
|
||||
"18.44.41",
|
||||
"18.45.43",
|
||||
"18.48.39",
|
||||
"18.49.37",
|
||||
"19.01.34",
|
||||
"19.02.39",
|
||||
"19.03.36",
|
||||
"19.04.38",
|
||||
"19.05.36",
|
||||
"19.06.39",
|
||||
"19.07.40",
|
||||
"19.08.36",
|
||||
"19.09.38",
|
||||
"19.10.39",
|
||||
"19.11.43",
|
||||
"19.12.41",
|
||||
"19.13.37",
|
||||
"19.14.43",
|
||||
"19.15.36",
|
||||
"19.16.39",
|
||||
"19.25.37",
|
||||
"19.34.42",
|
||||
]
|
||||
)
|
||||
]
|
||||
|
@ -22,30 +22,11 @@ import com.android.tools.smali.dexlib2.iface.instruction.TwoRegisterInstruction
|
||||
CompatiblePackage(
|
||||
"com.google.android.youtube",
|
||||
[
|
||||
"18.32.39",
|
||||
"18.37.36",
|
||||
"18.38.44",
|
||||
"18.43.45",
|
||||
"18.44.41",
|
||||
"18.45.43",
|
||||
"18.48.39",
|
||||
"18.49.37",
|
||||
"19.01.34",
|
||||
"19.02.39",
|
||||
"19.03.36",
|
||||
"19.04.38",
|
||||
"19.05.36",
|
||||
"19.06.39",
|
||||
"19.07.40",
|
||||
"19.08.36",
|
||||
"19.09.38",
|
||||
"19.10.39",
|
||||
"19.11.43",
|
||||
"19.12.41",
|
||||
"19.13.37",
|
||||
"19.14.43",
|
||||
"19.15.36",
|
||||
"19.16.39",
|
||||
"19.25.37",
|
||||
"19.34.42",
|
||||
]
|
||||
)
|
||||
]
|
||||
|
@ -18,30 +18,11 @@ import com.android.tools.smali.dexlib2.iface.instruction.TwoRegisterInstruction
|
||||
CompatiblePackage(
|
||||
"com.google.android.youtube",
|
||||
[
|
||||
"18.32.39",
|
||||
"18.37.36",
|
||||
"18.38.44",
|
||||
"18.43.45",
|
||||
"18.44.41",
|
||||
"18.45.43",
|
||||
"18.48.39",
|
||||
"18.49.37",
|
||||
"19.01.34",
|
||||
"19.02.39",
|
||||
"19.03.36",
|
||||
"19.04.38",
|
||||
"19.05.36",
|
||||
"19.06.39",
|
||||
"19.07.40",
|
||||
"19.08.36",
|
||||
"19.09.38",
|
||||
"19.10.39",
|
||||
"19.11.43",
|
||||
"19.12.41",
|
||||
"19.13.37",
|
||||
"19.14.43",
|
||||
"19.15.36",
|
||||
"19.16.39",
|
||||
"19.25.37",
|
||||
"19.34.42",
|
||||
]
|
||||
)
|
||||
]
|
||||
|
@ -19,29 +19,11 @@ import app.revanced.util.exception
|
||||
compatiblePackages = [
|
||||
CompatiblePackage(
|
||||
"com.google.android.youtube", [
|
||||
"18.37.36",
|
||||
"18.38.44",
|
||||
"18.43.45",
|
||||
"18.44.41",
|
||||
"18.45.43",
|
||||
"18.48.39",
|
||||
"18.49.37",
|
||||
"19.01.34",
|
||||
"19.02.39",
|
||||
"19.03.36",
|
||||
"19.04.38",
|
||||
"19.05.36",
|
||||
"19.06.39",
|
||||
"19.07.40",
|
||||
"19.08.36",
|
||||
"19.09.38",
|
||||
"19.10.39",
|
||||
"19.11.43",
|
||||
"19.12.41",
|
||||
"19.13.37",
|
||||
"19.14.43",
|
||||
"19.15.36",
|
||||
"19.16.39",
|
||||
"19.25.37",
|
||||
"19.34.42",
|
||||
]
|
||||
)
|
||||
]
|
||||
|
@ -18,13 +18,19 @@ import app.revanced.patches.youtube.layout.hide.general.fingerprints.HideShowMor
|
||||
import app.revanced.patches.youtube.layout.hide.general.fingerprints.ParseElementFromBufferFingerprint
|
||||
import app.revanced.patches.youtube.layout.hide.general.fingerprints.PlayerOverlayFingerprint
|
||||
import app.revanced.patches.youtube.layout.hide.general.fingerprints.ShowWatermarkFingerprint
|
||||
import app.revanced.patches.youtube.layout.hide.general.fingerprints.YoodlesImageViewFingerprint
|
||||
import app.revanced.patches.youtube.misc.litho.filter.LithoFilterPatch
|
||||
import app.revanced.patches.youtube.misc.navigation.NavigationBarHookPatch
|
||||
import app.revanced.patches.youtube.misc.settings.SettingsPatch
|
||||
import app.revanced.util.findOpcodeIndicesReversed
|
||||
import app.revanced.util.getReference
|
||||
import app.revanced.util.alsoResolve
|
||||
import app.revanced.util.resultOrThrow
|
||||
import com.android.tools.smali.dexlib2.Opcode
|
||||
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.TwoRegisterInstruction
|
||||
import com.android.tools.smali.dexlib2.iface.reference.MethodReference
|
||||
|
||||
@Patch(
|
||||
name = "Hide layout components",
|
||||
@ -40,37 +46,23 @@ import com.android.tools.smali.dexlib2.iface.instruction.TwoRegisterInstruction
|
||||
CompatiblePackage(
|
||||
"com.google.android.youtube",
|
||||
[
|
||||
"18.32.39",
|
||||
"18.37.36",
|
||||
"18.38.44",
|
||||
"18.43.45",
|
||||
"18.44.41",
|
||||
"18.45.43",
|
||||
"18.48.39",
|
||||
"18.49.37",
|
||||
"19.01.34",
|
||||
"19.02.39",
|
||||
"19.03.36",
|
||||
"19.04.38",
|
||||
"19.05.36",
|
||||
"19.06.39",
|
||||
"19.07.40",
|
||||
"19.08.36",
|
||||
"19.09.38",
|
||||
"19.10.39",
|
||||
"19.11.43",
|
||||
"19.12.41",
|
||||
"19.13.37",
|
||||
"19.14.43",
|
||||
"19.15.36",
|
||||
"19.16.39",
|
||||
"19.25.37",
|
||||
"19.34.42",
|
||||
],
|
||||
),
|
||||
],
|
||||
)
|
||||
@Suppress("unused")
|
||||
object HideLayoutComponentsPatch : BytecodePatch(
|
||||
setOf(ParseElementFromBufferFingerprint, PlayerOverlayFingerprint, HideShowMoreButtonFingerprint),
|
||||
setOf(
|
||||
ParseElementFromBufferFingerprint,
|
||||
PlayerOverlayFingerprint,
|
||||
HideShowMoreButtonFingerprint,
|
||||
YoodlesImageViewFingerprint,
|
||||
),
|
||||
) {
|
||||
private const val LAYOUT_COMPONENTS_FILTER_CLASS_DESCRIPTOR =
|
||||
"Lapp/revanced/integrations/youtube/patches/components/LayoutComponentsFilter;"
|
||||
@ -128,6 +120,7 @@ object HideLayoutComponentsPatch : BytecodePatch(
|
||||
SwitchPreference("revanced_hide_search_result_recommendations"),
|
||||
SwitchPreference("revanced_hide_search_result_shelf_header"),
|
||||
SwitchPreference("revanced_hide_show_more_button"),
|
||||
SwitchPreference("revanced_hide_doodles"),
|
||||
PreferenceScreen(
|
||||
key = "revanced_hide_keyword_content_screen",
|
||||
sorting = Sorting.UNSORTED,
|
||||
@ -191,9 +184,10 @@ object HideLayoutComponentsPatch : BytecodePatch(
|
||||
|
||||
// region Watermark (legacy code for old versions of YouTube)
|
||||
|
||||
ShowWatermarkFingerprint.also {
|
||||
it.resolve(context, PlayerOverlayFingerprint.resultOrThrow().classDef)
|
||||
}.resultOrThrow().mutableMethod.apply {
|
||||
ShowWatermarkFingerprint.alsoResolve(
|
||||
context,
|
||||
PlayerOverlayFingerprint
|
||||
).mutableMethod.apply {
|
||||
val index = implementation!!.instructions.size - 5
|
||||
|
||||
removeInstruction(index)
|
||||
@ -226,5 +220,28 @@ object HideLayoutComponentsPatch : BytecodePatch(
|
||||
}
|
||||
|
||||
// endregion
|
||||
|
||||
// region 'Yoodles'
|
||||
|
||||
YoodlesImageViewFingerprint.resultOrThrow().mutableMethod.apply {
|
||||
findOpcodeIndicesReversed{
|
||||
opcode == Opcode.INVOKE_VIRTUAL
|
||||
&& getReference<MethodReference>()?.name == "setImageDrawable"
|
||||
}.forEach { insertIndex ->
|
||||
val register = getInstruction<FiveRegisterInstruction>(insertIndex).registerD
|
||||
|
||||
addInstructionsWithLabels(
|
||||
insertIndex,
|
||||
"""
|
||||
invoke-static { v$register }, $LAYOUT_COMPONENTS_FILTER_CLASS_DESCRIPTOR->hideYoodles(Landroid/graphics/drawable/Drawable;)Landroid/graphics/drawable/Drawable;
|
||||
move-result-object v$register
|
||||
if-eqz v$register, :hide
|
||||
""",
|
||||
ExternalLabel("hide", getInstruction(insertIndex + 1)),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
// endregion
|
||||
}
|
||||
}
|
||||
|
@ -17,10 +17,17 @@ import app.revanced.patches.youtube.misc.settings.SettingsPatch
|
||||
internal object HideLayoutComponentsResourcePatch : ResourcePatch() {
|
||||
internal var expandButtonDownId: Long = -1
|
||||
|
||||
var youTubeLogo = -1L
|
||||
|
||||
override fun execute(context: ResourceContext) {
|
||||
expandButtonDownId = ResourceMappingPatch[
|
||||
"layout",
|
||||
"expand_button_down",
|
||||
]
|
||||
|
||||
youTubeLogo = ResourceMappingPatch[
|
||||
"id",
|
||||
"youtube_logo"
|
||||
]
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,13 @@
|
||||
package app.revanced.patches.youtube.layout.hide.general.fingerprints
|
||||
|
||||
import app.revanced.patcher.extensions.or
|
||||
import app.revanced.patches.youtube.layout.hide.general.HideLayoutComponentsResourcePatch
|
||||
import app.revanced.util.patch.LiteralValueFingerprint
|
||||
import com.android.tools.smali.dexlib2.AccessFlags
|
||||
|
||||
internal object YoodlesImageViewFingerprint : LiteralValueFingerprint(
|
||||
accessFlags = AccessFlags.PUBLIC or AccessFlags.FINAL,
|
||||
parameters = listOf("L", "L"),
|
||||
returnType = "Landroid/view/View;",
|
||||
literalSupplier = { HideLayoutComponentsResourcePatch.youTubeLogo }
|
||||
)
|
@ -13,6 +13,7 @@ import app.revanced.patches.youtube.layout.hide.infocards.fingerprints.Infocards
|
||||
import app.revanced.patches.youtube.layout.hide.infocards.fingerprints.InfocardsMethodCallFingerprint
|
||||
import app.revanced.patches.youtube.misc.integrations.IntegrationsPatch
|
||||
import app.revanced.patches.youtube.misc.litho.filter.LithoFilterPatch
|
||||
import app.revanced.util.alsoResolve
|
||||
import com.android.tools.smali.dexlib2.Opcode
|
||||
import com.android.tools.smali.dexlib2.iface.instruction.FiveRegisterInstruction
|
||||
import com.android.tools.smali.dexlib2.iface.instruction.ReferenceInstruction
|
||||
@ -29,30 +30,11 @@ import com.android.tools.smali.dexlib2.iface.instruction.ReferenceInstruction
|
||||
CompatiblePackage(
|
||||
"com.google.android.youtube",
|
||||
[
|
||||
"18.32.39",
|
||||
"18.37.36",
|
||||
"18.38.44",
|
||||
"18.43.45",
|
||||
"18.44.41",
|
||||
"18.45.43",
|
||||
"18.48.39",
|
||||
"18.49.37",
|
||||
"19.01.34",
|
||||
"19.02.39",
|
||||
"19.03.36",
|
||||
"19.04.38",
|
||||
"19.05.36",
|
||||
"19.06.39",
|
||||
"19.07.40",
|
||||
"19.08.36",
|
||||
"19.09.38",
|
||||
"19.10.39",
|
||||
"19.11.43",
|
||||
"19.12.41",
|
||||
"19.13.37",
|
||||
"19.14.43",
|
||||
"19.15.36",
|
||||
"19.16.39",
|
||||
"19.25.37",
|
||||
"19.34.42",
|
||||
]
|
||||
)
|
||||
]
|
||||
@ -68,9 +50,7 @@ object HideInfoCardsPatch : BytecodePatch(
|
||||
"Lapp/revanced/integrations/youtube/patches/components/HideInfoCardsFilterPatch;"
|
||||
|
||||
override fun execute(context: BytecodeContext) {
|
||||
InfocardsIncognitoFingerprint.also {
|
||||
it.resolve(context, InfocardsIncognitoParentFingerprint.result!!.classDef)
|
||||
}.result!!.mutableMethod.apply {
|
||||
InfocardsIncognitoFingerprint.alsoResolve(context, InfocardsIncognitoParentFingerprint).mutableMethod.apply {
|
||||
val invokeInstructionIndex = implementation!!.instructions.indexOfFirst {
|
||||
it.opcode.ordinal == Opcode.INVOKE_VIRTUAL.ordinal &&
|
||||
((it as ReferenceInstruction).reference.toString() == "Landroid/view/View;->setVisibility(I)V")
|
||||
|
@ -23,30 +23,11 @@ import app.revanced.patches.youtube.misc.settings.SettingsPatch
|
||||
compatiblePackages = [
|
||||
CompatiblePackage(
|
||||
"com.google.android.youtube", [
|
||||
"18.32.39",
|
||||
"18.37.36",
|
||||
"18.38.44",
|
||||
"18.43.45",
|
||||
"18.44.41",
|
||||
"18.45.43",
|
||||
"18.48.39",
|
||||
"18.49.37",
|
||||
"19.01.34",
|
||||
"19.02.39",
|
||||
"19.03.36",
|
||||
"19.04.38",
|
||||
"19.05.36",
|
||||
"19.06.39",
|
||||
"19.07.40",
|
||||
"19.08.36",
|
||||
"19.09.38",
|
||||
"19.10.39",
|
||||
"19.11.43",
|
||||
"19.12.41",
|
||||
"19.13.37",
|
||||
"19.14.43",
|
||||
"19.15.36",
|
||||
"19.16.39",
|
||||
"19.25.37",
|
||||
"19.34.42",
|
||||
]
|
||||
)
|
||||
]
|
||||
|
@ -23,27 +23,11 @@ import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction
|
||||
compatiblePackages = [
|
||||
CompatiblePackage(
|
||||
"com.google.android.youtube", [
|
||||
"18.43.45",
|
||||
"18.44.41",
|
||||
"18.45.43",
|
||||
"18.48.39",
|
||||
// 18.43 is the earliest target this patch works.
|
||||
"18.49.37",
|
||||
"19.01.34",
|
||||
"19.02.39",
|
||||
"19.03.36",
|
||||
"19.04.38",
|
||||
"19.05.36",
|
||||
"19.06.39",
|
||||
"19.07.40",
|
||||
"19.08.36",
|
||||
"19.09.38",
|
||||
"19.10.39",
|
||||
"19.11.43",
|
||||
"19.12.41",
|
||||
"19.13.37",
|
||||
"19.14.43",
|
||||
"19.15.36",
|
||||
"19.16.39",
|
||||
"19.25.37",
|
||||
"19.34.42",
|
||||
]
|
||||
)
|
||||
]
|
||||
|
@ -12,6 +12,7 @@ import app.revanced.patches.youtube.misc.integrations.IntegrationsPatch
|
||||
import app.revanced.patches.youtube.misc.settings.SettingsPatch
|
||||
import app.revanced.patches.youtube.shared.fingerprints.SeekbarFingerprint
|
||||
import app.revanced.patches.youtube.shared.fingerprints.SeekbarOnDrawFingerprint
|
||||
import app.revanced.util.alsoResolve
|
||||
|
||||
@Patch(
|
||||
name = "Hide seekbar",
|
||||
@ -25,30 +26,11 @@ import app.revanced.patches.youtube.shared.fingerprints.SeekbarOnDrawFingerprint
|
||||
compatiblePackages = [
|
||||
CompatiblePackage(
|
||||
"com.google.android.youtube", [
|
||||
"18.32.39",
|
||||
"18.37.36",
|
||||
"18.38.44",
|
||||
"18.43.45",
|
||||
"18.44.41",
|
||||
"18.45.43",
|
||||
"18.48.39",
|
||||
"18.49.37",
|
||||
"19.01.34",
|
||||
"19.02.39",
|
||||
"19.03.36",
|
||||
"19.04.38",
|
||||
"19.05.36",
|
||||
"19.06.39",
|
||||
"19.07.40",
|
||||
"19.08.36",
|
||||
"19.09.38",
|
||||
"19.10.39",
|
||||
"19.11.43",
|
||||
"19.12.41",
|
||||
"19.13.37",
|
||||
"19.14.43",
|
||||
"19.15.36",
|
||||
"19.16.39",
|
||||
"19.25.37",
|
||||
"19.34.42",
|
||||
]
|
||||
)
|
||||
]
|
||||
@ -65,9 +47,10 @@ object HideSeekbarPatch : BytecodePatch(
|
||||
SwitchPreference("revanced_hide_seekbar_thumbnail")
|
||||
)
|
||||
|
||||
SeekbarFingerprint.result!!.let {
|
||||
SeekbarOnDrawFingerprint.apply { resolve(context, it.mutableClass) }
|
||||
}.result!!.mutableMethod.addInstructionsWithLabels(
|
||||
SeekbarOnDrawFingerprint.alsoResolve(
|
||||
context,
|
||||
SeekbarFingerprint
|
||||
).mutableMethod.addInstructionsWithLabels(
|
||||
0,
|
||||
"""
|
||||
const/4 v0, 0x0
|
||||
|
@ -2,6 +2,7 @@ package app.revanced.patches.youtube.layout.hide.shorts
|
||||
|
||||
import app.revanced.patcher.data.BytecodeContext
|
||||
import app.revanced.patcher.extensions.InstructionExtensions.addInstruction
|
||||
import app.revanced.patcher.extensions.InstructionExtensions.addInstructions
|
||||
import app.revanced.patcher.extensions.InstructionExtensions.getInstruction
|
||||
import app.revanced.patcher.patch.BytecodePatch
|
||||
import app.revanced.patcher.patch.annotation.CompatiblePackage
|
||||
@ -13,10 +14,15 @@ import app.revanced.patches.youtube.layout.hide.shorts.fingerprints.*
|
||||
import app.revanced.patches.youtube.misc.integrations.IntegrationsPatch
|
||||
import app.revanced.patches.youtube.misc.litho.filter.LithoFilterPatch
|
||||
import app.revanced.patches.youtube.misc.navigation.NavigationBarHookPatch
|
||||
import app.revanced.util.exception
|
||||
import app.revanced.patches.youtube.misc.playservice.VersionCheckPatch
|
||||
import app.revanced.util.forEachLiteralValueInstruction
|
||||
import app.revanced.util.alsoResolve
|
||||
import app.revanced.util.getReference
|
||||
import app.revanced.util.indexOfFirstInstructionOrThrow
|
||||
import app.revanced.util.indexOfFirstWideLiteralInstructionValue
|
||||
import app.revanced.util.indexOfIdResourceOrThrow
|
||||
import app.revanced.util.injectHideViewCall
|
||||
import app.revanced.util.resultOrThrow
|
||||
import com.android.tools.smali.dexlib2.Opcode
|
||||
import com.android.tools.smali.dexlib2.iface.instruction.FiveRegisterInstruction
|
||||
import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction
|
||||
@ -32,35 +38,17 @@ import com.android.tools.smali.dexlib2.iface.reference.MethodReference
|
||||
HideShortsComponentsResourcePatch::class,
|
||||
ResourceMappingPatch::class,
|
||||
NavigationBarHookPatch::class,
|
||||
VersionCheckPatch::class
|
||||
],
|
||||
compatiblePackages = [
|
||||
CompatiblePackage(
|
||||
"com.google.android.youtube",
|
||||
[
|
||||
"18.32.39",
|
||||
"18.37.36",
|
||||
"18.38.44",
|
||||
"18.43.45",
|
||||
"18.44.41",
|
||||
"18.45.43",
|
||||
"18.48.39",
|
||||
"18.49.37",
|
||||
"19.01.34",
|
||||
"19.02.39",
|
||||
"19.03.36",
|
||||
"19.04.38",
|
||||
"19.05.36",
|
||||
"19.06.39",
|
||||
"19.07.40",
|
||||
"19.08.36",
|
||||
"19.09.38",
|
||||
"19.10.39",
|
||||
"19.11.43",
|
||||
"19.12.41",
|
||||
"19.13.37",
|
||||
"19.14.43",
|
||||
"19.15.36",
|
||||
"19.16.39",
|
||||
"19.25.37",
|
||||
"19.34.42",
|
||||
],
|
||||
),
|
||||
],
|
||||
@ -70,7 +58,8 @@ object HideShortsComponentsPatch : BytecodePatch(
|
||||
setOf(
|
||||
CreateShortsButtonsFingerprint,
|
||||
ReelConstructorFingerprint,
|
||||
BottomNavigationBarFingerprint,
|
||||
ShortsBottomBarContainerFingerprint,
|
||||
LegacyRenderBottomNavigationBarParentFingerprint,
|
||||
RenderBottomNavigationBarParentFingerprint,
|
||||
SetPivotBarVisibilityParentFingerprint,
|
||||
),
|
||||
@ -95,29 +84,30 @@ object HideShortsComponentsPatch : BytecodePatch(
|
||||
// region Hide the Shorts shelf.
|
||||
|
||||
// This patch point is not present in 19.03.x and greater.
|
||||
// If 19.02.x and lower is dropped, then this section of code and the fingerprint should be removed.
|
||||
ReelConstructorFingerprint.result?.let {
|
||||
it.mutableMethod.apply {
|
||||
val insertIndex = it.scanResult.patternScanResult!!.startIndex + 2
|
||||
val viewRegister = getInstruction<TwoRegisterInstruction>(insertIndex).registerA
|
||||
if (!VersionCheckPatch.is_19_03_or_greater) {
|
||||
ReelConstructorFingerprint.result?.let {
|
||||
it.mutableMethod.apply {
|
||||
val insertIndex = it.scanResult.patternScanResult!!.startIndex + 2
|
||||
val viewRegister = getInstruction<TwoRegisterInstruction>(insertIndex).registerA
|
||||
|
||||
injectHideViewCall(
|
||||
insertIndex,
|
||||
viewRegister,
|
||||
FILTER_CLASS_DESCRIPTOR,
|
||||
"hideShortsShelf",
|
||||
)
|
||||
injectHideViewCall(
|
||||
insertIndex,
|
||||
viewRegister,
|
||||
FILTER_CLASS_DESCRIPTOR,
|
||||
"hideShortsShelf",
|
||||
)
|
||||
}
|
||||
}
|
||||
} // Do not throw an exception if not resolved.
|
||||
}
|
||||
|
||||
// endregion
|
||||
|
||||
// region Hide the Shorts buttons in older versions of YouTube.
|
||||
|
||||
// Some Shorts buttons are views, hide them by setting their visibility to GONE.
|
||||
CreateShortsButtonsFingerprint.result?.let {
|
||||
CreateShortsButtonsFingerprint.resultOrThrow().let {
|
||||
ShortsButtons.entries.forEach { button -> button.injectHideCall(it.mutableMethod) }
|
||||
} ?: throw CreateShortsButtonsFingerprint.exception
|
||||
}
|
||||
|
||||
// endregion
|
||||
|
||||
@ -125,54 +115,68 @@ object HideShortsComponentsPatch : BytecodePatch(
|
||||
|
||||
LithoFilterPatch.addFilter(FILTER_CLASS_DESCRIPTOR)
|
||||
|
||||
context.forEachLiteralValueInstruction(
|
||||
HideShortsComponentsResourcePatch.reelPlayerRightPivotV2Size
|
||||
) { literalInstructionIndex ->
|
||||
val targetIndex = indexOfFirstInstructionOrThrow(literalInstructionIndex) {
|
||||
getReference<MethodReference>()?.name == "getDimensionPixelSize"
|
||||
} + 1
|
||||
|
||||
val sizeRegister = getInstruction<OneRegisterInstruction>(targetIndex).registerA
|
||||
|
||||
addInstructions(targetIndex + 1, """
|
||||
invoke-static { v$sizeRegister }, $FILTER_CLASS_DESCRIPTOR->getSoundButtonSize(I)I
|
||||
move-result v$sizeRegister
|
||||
"""
|
||||
)
|
||||
}
|
||||
|
||||
// endregion
|
||||
|
||||
// region Hide the navigation bar.
|
||||
|
||||
// Hook to get the pivotBar view.
|
||||
SetPivotBarVisibilityParentFingerprint.result?.let {
|
||||
if (!SetPivotBarVisibilityFingerprint.resolve(context, it.classDef)) {
|
||||
throw SetPivotBarVisibilityFingerprint.exception
|
||||
}
|
||||
|
||||
SetPivotBarVisibilityFingerprint.result!!.let { result ->
|
||||
result.mutableMethod.apply {
|
||||
val insertIndex = result.scanResult.patternScanResult!!.endIndex
|
||||
val viewRegister = getInstruction<OneRegisterInstruction>(insertIndex - 1).registerA
|
||||
addInstruction(
|
||||
insertIndex,
|
||||
"sput-object v$viewRegister, $FILTER_CLASS_DESCRIPTOR->pivotBar:" +
|
||||
"Lcom/google/android/libraries/youtube/rendering/ui/pivotbar/PivotBar;",
|
||||
)
|
||||
}
|
||||
}
|
||||
} ?: throw SetPivotBarVisibilityParentFingerprint.exception
|
||||
|
||||
// Hook to hide the navigation bar when Shorts are being played.
|
||||
RenderBottomNavigationBarParentFingerprint.result?.let {
|
||||
if (!RenderBottomNavigationBarFingerprint.resolve(context, it.classDef)) {
|
||||
throw RenderBottomNavigationBarFingerprint.exception
|
||||
}
|
||||
|
||||
RenderBottomNavigationBarFingerprint.result!!.mutableMethod.apply {
|
||||
addInstruction(0, "invoke-static { }, $FILTER_CLASS_DESCRIPTOR->hideNavigationBar()V")
|
||||
}
|
||||
} ?: throw RenderBottomNavigationBarParentFingerprint.exception
|
||||
|
||||
// Required to prevent a black bar from appearing at the bottom of the screen.
|
||||
BottomNavigationBarFingerprint.result?.let {
|
||||
it.mutableMethod.apply {
|
||||
val moveResultIndex = it.scanResult.patternScanResult!!.startIndex + 2
|
||||
val viewRegister = getInstruction<OneRegisterInstruction>(moveResultIndex).registerA
|
||||
val insertIndex = moveResultIndex + 1
|
||||
|
||||
addInstruction(
|
||||
insertIndex,
|
||||
"invoke-static { v$viewRegister }, $FILTER_CLASS_DESCRIPTOR->" +
|
||||
"hideNavigationBar(Landroid/view/View;)Landroid/view/View;",
|
||||
SetPivotBarVisibilityFingerprint.alsoResolve(
|
||||
context,
|
||||
SetPivotBarVisibilityParentFingerprint
|
||||
).let { result->
|
||||
result.mutableMethod.apply {
|
||||
val insertIndex = result.scanResult.patternScanResult!!.endIndex
|
||||
val viewRegister = getInstruction<OneRegisterInstruction>(insertIndex - 1).registerA
|
||||
addInstruction(insertIndex, "invoke-static {v$viewRegister}," +
|
||||
" $FILTER_CLASS_DESCRIPTOR->setNavigationBar(Lcom/google/android/libraries/youtube/rendering/ui/pivotbar/PivotBar;)V"
|
||||
)
|
||||
}
|
||||
} ?: throw BottomNavigationBarFingerprint.exception
|
||||
}
|
||||
|
||||
// Hook to hide the shared navigation bar when the Shorts player is opened.
|
||||
RenderBottomNavigationBarFingerprint.alsoResolve(
|
||||
context,
|
||||
if (VersionCheckPatch.is_19_41_or_greater)
|
||||
RenderBottomNavigationBarParentFingerprint
|
||||
else
|
||||
LegacyRenderBottomNavigationBarParentFingerprint
|
||||
).mutableMethod.addInstruction(
|
||||
0,
|
||||
"invoke-static { p1 }, $FILTER_CLASS_DESCRIPTOR->hideNavigationBar(Ljava/lang/String;)V"
|
||||
)
|
||||
|
||||
// Hide the bottom bar container of the Shorts player.
|
||||
ShortsBottomBarContainerFingerprint.resultOrThrow().mutableMethod.apply {
|
||||
val resourceIndex = indexOfFirstWideLiteralInstructionValue(HideShortsComponentsResourcePatch.bottomBarContainer)
|
||||
|
||||
val targetIndex = indexOfFirstInstructionOrThrow(resourceIndex) {
|
||||
getReference<MethodReference>()?.name == "getHeight"
|
||||
} + 1
|
||||
|
||||
val heightRegister = getInstruction<OneRegisterInstruction>(targetIndex).registerA
|
||||
|
||||
addInstructions(targetIndex + 1, """
|
||||
invoke-static { v$heightRegister }, $FILTER_CLASS_DESCRIPTOR->getNavigationBarHeight(I)I
|
||||
move-result v$heightRegister
|
||||
"""
|
||||
)
|
||||
}
|
||||
|
||||
// endregion
|
||||
}
|
||||
@ -187,14 +191,12 @@ object HideShortsComponentsPatch : BytecodePatch(
|
||||
fun injectHideCall(method: MutableMethod) {
|
||||
val referencedIndex = method.indexOfIdResourceOrThrow(resourceName)
|
||||
|
||||
val instruction = method.implementation!!.instructions
|
||||
.subList(referencedIndex, referencedIndex + 20)
|
||||
.first {
|
||||
it.opcode == Opcode.INVOKE_VIRTUAL && it.getReference<MethodReference>()?.name == "setId"
|
||||
}
|
||||
val setIdIndex = method.indexOfFirstInstructionOrThrow(referencedIndex) {
|
||||
opcode == Opcode.INVOKE_VIRTUAL && getReference<MethodReference>()?.name == "setId"
|
||||
}
|
||||
|
||||
val setIdIndex = instruction.location.index
|
||||
val viewRegister = method.getInstruction<FiveRegisterInstruction>(setIdIndex).registerC
|
||||
|
||||
method.injectHideViewCall(setIdIndex + 1, viewRegister, FILTER_CLASS_DESCRIPTOR, methodName)
|
||||
}
|
||||
}
|
||||
|
@ -8,13 +8,23 @@ import app.revanced.patches.shared.misc.mapping.ResourceMappingPatch
|
||||
import app.revanced.patches.shared.misc.settings.preference.SwitchPreference
|
||||
import app.revanced.patches.youtube.layout.hide.shorts.HideShortsComponentsPatch.hideShortsAppShortcut
|
||||
import app.revanced.patches.youtube.layout.hide.shorts.HideShortsComponentsPatch.hideShortsWidget
|
||||
import app.revanced.patches.youtube.misc.playservice.VersionCheckPatch
|
||||
import app.revanced.patches.youtube.misc.settings.SettingsPatch
|
||||
import app.revanced.util.findElementByAttributeValueOrThrow
|
||||
|
||||
@Patch(dependencies = [SettingsPatch::class, ResourceMappingPatch::class, AddResourcesPatch::class])
|
||||
@Patch(
|
||||
dependencies = [
|
||||
SettingsPatch::class,
|
||||
ResourceMappingPatch::class,
|
||||
AddResourcesPatch::class,
|
||||
VersionCheckPatch::class
|
||||
]
|
||||
)
|
||||
object HideShortsComponentsResourcePatch : ResourcePatch() {
|
||||
internal var reelMultipleItemShelfId = -1L
|
||||
internal var reelPlayerRightCellButtonHeight = -1L
|
||||
internal var bottomBarContainer = -1L
|
||||
internal var reelPlayerRightPivotV2Size = -1L
|
||||
|
||||
override fun execute(context: ResourceContext) {
|
||||
AddResourcesPatch(this::class)
|
||||
@ -29,6 +39,7 @@ object HideShortsComponentsResourcePatch : ResourcePatch() {
|
||||
// since this Setting menu currently uses the ordering used here.
|
||||
|
||||
// Vertical row of buttons on right side of the screen.
|
||||
SwitchPreference("revanced_hide_shorts_like_fountain"),
|
||||
SwitchPreference("revanced_hide_shorts_like_button"),
|
||||
SwitchPreference("revanced_hide_shorts_dislike_button"),
|
||||
SwitchPreference("revanced_hide_shorts_comments_button"),
|
||||
@ -41,6 +52,10 @@ object HideShortsComponentsResourcePatch : ResourcePatch() {
|
||||
SwitchPreference("revanced_hide_shorts_subscribe_button"),
|
||||
SwitchPreference("revanced_hide_shorts_paused_overlay_buttons"),
|
||||
SwitchPreference("revanced_hide_shorts_save_sound_button"),
|
||||
SwitchPreference("revanced_hide_shorts_use_template_button"),
|
||||
SwitchPreference("revanced_hide_shorts_upcoming_button"),
|
||||
SwitchPreference("revanced_hide_shorts_green_screen_button"),
|
||||
SwitchPreference("revanced_hide_shorts_hashtag_button"),
|
||||
SwitchPreference("revanced_hide_shorts_shop_button"),
|
||||
SwitchPreference("revanced_hide_shorts_tagged_products"),
|
||||
SwitchPreference("revanced_hide_shorts_stickers"),
|
||||
@ -59,7 +74,7 @@ object HideShortsComponentsResourcePatch : ResourcePatch() {
|
||||
context.xmlEditor["res/xml/main_shortcuts.xml"].use { editor ->
|
||||
val shortsItem = editor.file.childNodes.findElementByAttributeValueOrThrow(
|
||||
"android:shortcutId",
|
||||
"shorts-shortcut"
|
||||
"shorts-shortcut",
|
||||
)
|
||||
|
||||
shortsItem.parentNode.removeChild(shortsItem)
|
||||
@ -70,7 +85,7 @@ object HideShortsComponentsResourcePatch : ResourcePatch() {
|
||||
context.xmlEditor["res/layout/appwidget_two_rows.xml"].use { editor ->
|
||||
val shortsItem = editor.file.childNodes.findElementByAttributeValueOrThrow(
|
||||
"android:id",
|
||||
"@id/button_shorts_container"
|
||||
"@id/button_shorts_container",
|
||||
)
|
||||
|
||||
shortsItem.parentNode.removeChild(shortsItem)
|
||||
@ -82,14 +97,21 @@ object HideShortsComponentsResourcePatch : ResourcePatch() {
|
||||
"reel_player_right_cell_button_height",
|
||||
]
|
||||
|
||||
// Resource not present in new versions of the app.
|
||||
try {
|
||||
ResourceMappingPatch[
|
||||
bottomBarContainer = ResourceMappingPatch[
|
||||
"id",
|
||||
"bottom_bar_container"
|
||||
]
|
||||
|
||||
reelPlayerRightPivotV2Size = ResourceMappingPatch[
|
||||
"dimen",
|
||||
"reel_player_right_pivot_v2_size"
|
||||
]
|
||||
|
||||
if (!VersionCheckPatch.is_19_03_or_greater) {
|
||||
reelMultipleItemShelfId = ResourceMappingPatch[
|
||||
"dimen",
|
||||
"reel_player_right_cell_button_height",
|
||||
]
|
||||
} catch (e: NoSuchElementException) {
|
||||
return
|
||||
}.also { reelPlayerRightCellButtonHeight = it }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,24 +0,0 @@
|
||||
package app.revanced.patches.youtube.layout.hide.shorts.fingerprints
|
||||
|
||||
import app.revanced.patcher.extensions.or
|
||||
import app.revanced.patcher.fingerprint.MethodFingerprint
|
||||
import com.android.tools.smali.dexlib2.AccessFlags
|
||||
import com.android.tools.smali.dexlib2.Opcode
|
||||
|
||||
internal object BottomNavigationBarFingerprint : MethodFingerprint(
|
||||
returnType = "V",
|
||||
accessFlags = AccessFlags.PUBLIC or AccessFlags.FINAL,
|
||||
parameters = listOf("Landroid/view/View;", "Landroid/os/Bundle;"),
|
||||
opcodes = listOf(
|
||||
Opcode.CONST, // R.id.app_engagement_panel_wrapper
|
||||
Opcode.INVOKE_VIRTUAL,
|
||||
Opcode.MOVE_RESULT_OBJECT,
|
||||
Opcode.IF_EQZ,
|
||||
Opcode.IGET_OBJECT,
|
||||
Opcode.IGET_OBJECT,
|
||||
Opcode.IGET_OBJECT,
|
||||
),
|
||||
strings = listOf(
|
||||
"ReelWatchPaneFragmentViewModelKey"
|
||||
),
|
||||
)
|
@ -0,0 +1,15 @@
|
||||
package app.revanced.patches.youtube.layout.hide.shorts.fingerprints
|
||||
|
||||
import app.revanced.patcher.fingerprint.MethodFingerprint
|
||||
|
||||
internal object LegacyRenderBottomNavigationBarParentFingerprint : MethodFingerprint(
|
||||
parameters = listOf(
|
||||
"I",
|
||||
"I",
|
||||
"L",
|
||||
"L",
|
||||
"J",
|
||||
"L",
|
||||
),
|
||||
strings = listOf("aa")
|
||||
)
|
@ -1,19 +1,13 @@
|
||||
package app.revanced.patches.youtube.layout.hide.shorts.fingerprints
|
||||
|
||||
import app.revanced.patcher.extensions.or
|
||||
import app.revanced.patcher.fingerprint.MethodFingerprint
|
||||
import app.revanced.patches.youtube.layout.hide.shorts.HideShortsComponentsResourcePatch
|
||||
import app.revanced.util.containsWideLiteralInstructionValue
|
||||
import app.revanced.util.patch.LiteralValueFingerprint
|
||||
import com.android.tools.smali.dexlib2.AccessFlags
|
||||
import com.android.tools.smali.dexlib2.Opcode
|
||||
|
||||
internal object ReelConstructorFingerprint : MethodFingerprint(
|
||||
internal object ReelConstructorFingerprint : LiteralValueFingerprint(
|
||||
accessFlags = AccessFlags.PUBLIC or AccessFlags.CONSTRUCTOR,
|
||||
opcodes = listOf(Opcode.INVOKE_VIRTUAL),
|
||||
customFingerprint = { methodDef, _ ->
|
||||
// Cannot use LiteralValueFingerprint, because the resource id may not be present.
|
||||
val reelMultipleItemShelfId = HideShortsComponentsResourcePatch.reelMultipleItemShelfId
|
||||
reelMultipleItemShelfId != -1L
|
||||
&& methodDef.containsWideLiteralInstructionValue(reelMultipleItemShelfId)
|
||||
}
|
||||
literalSupplier = { HideShortsComponentsResourcePatch.reelMultipleItemShelfId }
|
||||
)
|
@ -4,6 +4,8 @@ import app.revanced.patcher.fingerprint.MethodFingerprint
|
||||
import com.android.tools.smali.dexlib2.Opcode
|
||||
|
||||
internal object RenderBottomNavigationBarFingerprint : MethodFingerprint(
|
||||
returnType = "V",
|
||||
parameters = listOf("Ljava/lang/String;"),
|
||||
opcodes = listOf(
|
||||
Opcode.IGET_OBJECT,
|
||||
Opcode.MONITOR_ENTER,
|
||||
|
@ -1,8 +1,23 @@
|
||||
package app.revanced.patches.youtube.layout.hide.shorts.fingerprints
|
||||
|
||||
import app.revanced.patcher.extensions.or
|
||||
import app.revanced.patcher.fingerprint.MethodFingerprint
|
||||
import com.android.tools.smali.dexlib2.AccessFlags
|
||||
|
||||
/**
|
||||
* Identical to [LegacyRenderBottomNavigationBarParentFingerprint]
|
||||
* except this has an extra parameter.
|
||||
*/
|
||||
internal object RenderBottomNavigationBarParentFingerprint : MethodFingerprint(
|
||||
parameters = listOf("I", "I", "L", "L", "J", "L"),
|
||||
accessFlags = AccessFlags.PUBLIC or AccessFlags.FINAL,
|
||||
parameters = listOf(
|
||||
"I",
|
||||
"I",
|
||||
"L", // ReelWatchEndpointOuterClass
|
||||
"L",
|
||||
"J",
|
||||
"Ljava/lang/String;",
|
||||
"L"
|
||||
),
|
||||
strings = listOf("aa")
|
||||
)
|
@ -0,0 +1,16 @@
|
||||
package app.revanced.patches.youtube.layout.hide.shorts.fingerprints
|
||||
|
||||
import app.revanced.patcher.extensions.or
|
||||
import app.revanced.patches.youtube.layout.hide.shorts.HideShortsComponentsResourcePatch
|
||||
import app.revanced.util.patch.LiteralValueFingerprint
|
||||
import com.android.tools.smali.dexlib2.AccessFlags
|
||||
|
||||
internal object ShortsBottomBarContainerFingerprint : LiteralValueFingerprint(
|
||||
returnType = "V",
|
||||
accessFlags = AccessFlags.PUBLIC or AccessFlags.FINAL,
|
||||
parameters = listOf("Landroid/view/View;", "Landroid/os/Bundle;"),
|
||||
strings = listOf(
|
||||
"r_pfvc"
|
||||
),
|
||||
literalSupplier = { HideShortsComponentsResourcePatch.bottomBarContainer }
|
||||
)
|
@ -18,29 +18,11 @@ import com.android.tools.smali.dexlib2.iface.instruction.FiveRegisterInstruction
|
||||
compatiblePackages = [
|
||||
CompatiblePackage(
|
||||
"com.google.android.youtube", [
|
||||
"18.37.36",
|
||||
"18.38.44",
|
||||
"18.43.45",
|
||||
"18.44.41",
|
||||
"18.45.43",
|
||||
"18.48.39",
|
||||
"18.49.37",
|
||||
"19.01.34",
|
||||
"19.02.39",
|
||||
"19.03.36",
|
||||
"19.04.38",
|
||||
"19.05.36",
|
||||
"19.06.39",
|
||||
"19.07.40",
|
||||
"19.08.36",
|
||||
"19.09.38",
|
||||
"19.10.39",
|
||||
"19.11.43",
|
||||
"19.12.41",
|
||||
"19.13.37",
|
||||
"19.14.43",
|
||||
"19.15.36",
|
||||
"19.16.39",
|
||||
"19.25.37",
|
||||
"19.34.42",
|
||||
]
|
||||
)
|
||||
]
|
||||
|
@ -19,29 +19,11 @@ import app.revanced.util.exception
|
||||
compatiblePackages = [
|
||||
CompatiblePackage(
|
||||
"com.google.android.youtube", [
|
||||
"18.37.36",
|
||||
"18.38.44",
|
||||
"18.43.45",
|
||||
"18.44.41",
|
||||
"18.45.43",
|
||||
"18.48.39",
|
||||
"18.49.37",
|
||||
"19.01.34",
|
||||
"19.02.39",
|
||||
"19.03.36",
|
||||
"19.04.38",
|
||||
"19.05.36",
|
||||
"19.06.39",
|
||||
"19.07.40",
|
||||
"19.08.36",
|
||||
"19.09.38",
|
||||
"19.10.39",
|
||||
"19.11.43",
|
||||
"19.12.41",
|
||||
"19.13.37",
|
||||
"19.14.43",
|
||||
"19.15.36",
|
||||
"19.16.39",
|
||||
"19.25.37",
|
||||
"19.34.42",
|
||||
]
|
||||
)
|
||||
]
|
||||
|
@ -1,17 +1,20 @@
|
||||
@file:Suppress("SpellCheckingInspection")
|
||||
|
||||
package app.revanced.patches.youtube.layout.miniplayer
|
||||
|
||||
import app.revanced.patcher.data.BytecodeContext
|
||||
import app.revanced.patcher.extensions.InstructionExtensions.addInstruction
|
||||
import app.revanced.patcher.extensions.InstructionExtensions.addInstructions
|
||||
import app.revanced.patcher.extensions.InstructionExtensions.getInstruction
|
||||
import app.revanced.patcher.extensions.InstructionExtensions.removeInstruction
|
||||
import app.revanced.patcher.extensions.InstructionExtensions.replaceInstruction
|
||||
import app.revanced.patcher.fingerprint.MethodFingerprint
|
||||
import app.revanced.patcher.patch.BytecodePatch
|
||||
import app.revanced.patcher.patch.annotation.CompatiblePackage
|
||||
import app.revanced.patcher.patch.annotation.Patch
|
||||
import app.revanced.patcher.util.proxy.mutableTypes.MutableMethod
|
||||
import app.revanced.patcher.util.proxy.mutableTypes.MutableMethod.Companion.toMutable
|
||||
import app.revanced.patches.all.misc.resources.AddResourcesPatch
|
||||
import app.revanced.patches.shared.misc.settings.preference.BasePreference
|
||||
import app.revanced.patches.shared.misc.settings.preference.InputType
|
||||
import app.revanced.patches.shared.misc.settings.preference.ListPreference
|
||||
import app.revanced.patches.shared.misc.settings.preference.PreferenceScreen
|
||||
@ -26,6 +29,7 @@ import app.revanced.patches.youtube.layout.miniplayer.MiniplayerResourcePatch.sc
|
||||
import app.revanced.patches.youtube.layout.miniplayer.MiniplayerResourcePatch.ytOutlinePictureInPictureWhite24
|
||||
import app.revanced.patches.youtube.layout.miniplayer.MiniplayerResourcePatch.ytOutlineXWhite24
|
||||
import app.revanced.patches.youtube.layout.miniplayer.fingerprints.MiniplayerDimensionsCalculatorParentFingerprint
|
||||
import app.revanced.patches.youtube.layout.miniplayer.fingerprints.MiniplayerMinimumSizeFingerprint
|
||||
import app.revanced.patches.youtube.layout.miniplayer.fingerprints.MiniplayerModernAddViewListenerFingerprint
|
||||
import app.revanced.patches.youtube.layout.miniplayer.fingerprints.MiniplayerModernCloseButtonFingerprint
|
||||
import app.revanced.patches.youtube.layout.miniplayer.fingerprints.MiniplayerModernConstructorFingerprint
|
||||
@ -42,30 +46,32 @@ import app.revanced.patches.youtube.layout.miniplayer.fingerprints.YouTubePlayer
|
||||
import app.revanced.patches.youtube.layout.miniplayer.fingerprints.YouTubePlayerOverlaysLayoutFingerprint.YOUTUBE_PLAYER_OVERLAYS_LAYOUT_CLASS_NAME
|
||||
import app.revanced.patches.youtube.layout.tablet.fingerprints.GetFormFactorFingerprint
|
||||
import app.revanced.patches.youtube.misc.integrations.IntegrationsPatch
|
||||
import app.revanced.patches.youtube.misc.playservice.VersionCheckPatch
|
||||
import app.revanced.patches.youtube.misc.settings.SettingsPatch
|
||||
import app.revanced.util.addInstructionsAtControlFlowLabel
|
||||
import app.revanced.util.alsoResolve
|
||||
import app.revanced.util.findOpcodeIndicesReversed
|
||||
import app.revanced.util.getReference
|
||||
import app.revanced.util.indexOfFirstInstructionOrThrow
|
||||
import app.revanced.util.indexOfFirstWideLiteralInstructionValueOrThrow
|
||||
import app.revanced.util.patch.LiteralValueFingerprint
|
||||
import app.revanced.util.resultOrThrow
|
||||
import com.android.tools.smali.dexlib2.AccessFlags
|
||||
import com.android.tools.smali.dexlib2.Opcode
|
||||
import com.android.tools.smali.dexlib2.builder.MutableMethodImplementation
|
||||
import com.android.tools.smali.dexlib2.iface.Method
|
||||
import com.android.tools.smali.dexlib2.iface.instruction.NarrowLiteralInstruction
|
||||
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.TwoRegisterInstruction
|
||||
import com.android.tools.smali.dexlib2.iface.reference.FieldReference
|
||||
import com.android.tools.smali.dexlib2.iface.reference.TypeReference
|
||||
import com.android.tools.smali.dexlib2.immutable.ImmutableMethod
|
||||
import com.android.tools.smali.dexlib2.immutable.ImmutableMethodParameter
|
||||
|
||||
// YT uses "Miniplayer" without a space between 'mini' and 'player: https://support.google.com/youtube/answer/9162927.
|
||||
// YT uses "Miniplayer" without a space between 'mini' and 'player': https://support.google.com/youtube/answer/9162927.
|
||||
@Patch(
|
||||
name = "Miniplayer",
|
||||
description = "Adds options to change the in app minimized player, " +
|
||||
"and if patching target 19.16+ adds options to use modern miniplayers.",
|
||||
description = "Adds options to change the in app minimized player. " +
|
||||
"Patching target 19.16+ adds modern miniplayers.",
|
||||
dependencies = [
|
||||
IntegrationsPatch::class,
|
||||
SettingsPatch::class,
|
||||
@ -75,32 +81,28 @@ import com.android.tools.smali.dexlib2.immutable.ImmutableMethodParameter
|
||||
compatiblePackages = [
|
||||
CompatiblePackage(
|
||||
"com.google.android.youtube", [
|
||||
"18.32.39",
|
||||
"18.37.36",
|
||||
"18.38.44",
|
||||
"18.43.45",
|
||||
"18.44.41",
|
||||
"18.45.43",
|
||||
"18.48.39",
|
||||
"18.49.37",
|
||||
"19.01.34",
|
||||
"19.02.39",
|
||||
"19.03.36",
|
||||
"19.04.38",
|
||||
"19.05.36",
|
||||
"19.06.39",
|
||||
"19.07.40",
|
||||
"19.08.36",
|
||||
"19.09.38",
|
||||
"19.10.39",
|
||||
"19.11.43",
|
||||
"19.12.41",
|
||||
"19.13.37",
|
||||
// 19.14 is left out, as it has incomplete miniplayer code and missing some UI resources.
|
||||
// It's simpler to not bother with supporting this single old version.
|
||||
// 19.15 has a different code for handling sub title texts,
|
||||
// and also probably not worth making changes just to support this single old version.
|
||||
"19.16.39" // Earliest supported version with modern miniplayers.
|
||||
// 19.14.43 // Incomplete code for modern miniplayers.
|
||||
// 19.15.36 // Different code for handling subtitle texts and not worth supporting.
|
||||
"19.16.39", // First with modern miniplayers.
|
||||
// 19.17.41 // Works without issues, but no reason to recommend over 19.16.
|
||||
// 19.18.41 // Works without issues, but no reason to recommend over 19.16.
|
||||
// 19.19.39 // Last bug free version with smaller Modern 1 miniplayer, but no reason to recommend over 19.16.
|
||||
// 19.20.35 // Cannot swipe to expand.
|
||||
// 19.21.40 // Cannot swipe to expand.
|
||||
// 19.22.43 // Cannot swipe to expand.
|
||||
// 19.23.40 // First with Modern 1 drag and drop, Cannot swipe to expand.
|
||||
// 19.24.45 // First with larger Modern 1, Cannot swipe to expand.
|
||||
"19.25.37", // First with double tap, last with skip forward/back buttons, last with swipe to expand/close, and last before double tap to expand seems to be required.
|
||||
// 19.26.42 // Modern 1 Pause/play button are always hidden. Unusable.
|
||||
// 19.28.42 // First with custom miniplayer size, screen flickers when swiping to maximize Modern 1. Swipe to close miniplayer is broken.
|
||||
// 19.29.42 // All modern players are broken and ignore tapping the miniplayer video.
|
||||
// 19.30.39 // Modern 3 is less broken when double tap expand is enabled, but cannot swipe to expand when double tap is off.
|
||||
// 19.31.36 // All Modern 1 buttons are missing. Unusable.
|
||||
// 19.32.36 // 19.32+ and beyond all work without issues.
|
||||
// 19.33.35
|
||||
"19.34.42",
|
||||
]
|
||||
)
|
||||
]
|
||||
@ -113,6 +115,7 @@ object MiniplayerPatch : BytecodePatch(
|
||||
MiniplayerOverrideFingerprint,
|
||||
MiniplayerModernConstructorFingerprint,
|
||||
MiniplayerModernViewParentFingerprint,
|
||||
MiniplayerMinimumSizeFingerprint,
|
||||
YouTubePlayerOverlaysLayoutFingerprint
|
||||
)
|
||||
) {
|
||||
@ -121,48 +124,71 @@ object MiniplayerPatch : BytecodePatch(
|
||||
override fun execute(context: BytecodeContext) {
|
||||
AddResourcesPatch(this::class)
|
||||
|
||||
// Modern mini player is only present and functional in 19.15+.
|
||||
// Resource is not present in older versions. Using it to determine, if patching an old version.
|
||||
val isPatchingOldVersion = ytOutlinePictureInPictureWhite24 < 0
|
||||
val preferences = mutableSetOf<BasePreference>()
|
||||
|
||||
if (!VersionCheckPatch.is_19_16_or_greater) {
|
||||
preferences += ListPreference(
|
||||
"revanced_miniplayer_type",
|
||||
summaryKey = null,
|
||||
entriesKey = "revanced_miniplayer_type_legacy_entries",
|
||||
entryValuesKey = "revanced_miniplayer_type_legacy_entry_values"
|
||||
)
|
||||
} else {
|
||||
preferences += ListPreference(
|
||||
"revanced_miniplayer_type",
|
||||
summaryKey = null,
|
||||
)
|
||||
|
||||
if (VersionCheckPatch.is_19_25_or_greater) {
|
||||
if (!VersionCheckPatch.is_19_29_or_greater) {
|
||||
preferences += SwitchPreference("revanced_miniplayer_double_tap_action")
|
||||
}
|
||||
preferences += SwitchPreference("revanced_miniplayer_drag_and_drop")
|
||||
}
|
||||
|
||||
if (VersionCheckPatch.is_19_36_or_greater) {
|
||||
preferences += SwitchPreference("revanced_miniplayer_rounded_corners")
|
||||
}
|
||||
|
||||
preferences += SwitchPreference("revanced_miniplayer_hide_subtext")
|
||||
|
||||
preferences +=
|
||||
if (VersionCheckPatch.is_19_26_or_greater) {
|
||||
SwitchPreference("revanced_miniplayer_hide_expand_close")
|
||||
} else {
|
||||
SwitchPreference(
|
||||
key = "revanced_miniplayer_hide_expand_close",
|
||||
titleKey = "revanced_miniplayer_hide_expand_close_legacy_title",
|
||||
summaryOnKey = "revanced_miniplayer_hide_expand_close_legacy_summary_on",
|
||||
summaryOffKey = "revanced_miniplayer_hide_expand_close_legacy_summary_off",
|
||||
)
|
||||
}
|
||||
|
||||
if (!VersionCheckPatch.is_19_26_or_greater) {
|
||||
preferences += SwitchPreference("revanced_miniplayer_hide_rewind_forward")
|
||||
}
|
||||
|
||||
if (VersionCheckPatch.is_19_26_or_greater) {
|
||||
preferences += TextPreference("revanced_miniplayer_width_dip", inputType = InputType.NUMBER)
|
||||
}
|
||||
|
||||
preferences += TextPreference("revanced_miniplayer_opacity", inputType = InputType.NUMBER)
|
||||
}
|
||||
|
||||
SettingsPatch.PreferenceScreen.PLAYER.addPreferences(
|
||||
PreferenceScreen(
|
||||
key = "revanced_miniplayer_screen",
|
||||
sorting = Sorting.UNSORTED,
|
||||
preferences =
|
||||
if (isPatchingOldVersion) {
|
||||
setOf(
|
||||
ListPreference(
|
||||
"revanced_miniplayer_type",
|
||||
summaryKey = null,
|
||||
entriesKey = "revanced_miniplayer_type_legacy_entries",
|
||||
entryValuesKey = "revanced_miniplayer_type_legacy_entry_values"
|
||||
)
|
||||
)
|
||||
} else {
|
||||
setOf(
|
||||
ListPreference(
|
||||
"revanced_miniplayer_type",
|
||||
summaryKey = null,
|
||||
entriesKey = "revanced_miniplayer_type_19_15_entries",
|
||||
entryValuesKey = "revanced_miniplayer_type_19_15_entry_values"
|
||||
),
|
||||
SwitchPreference("revanced_miniplayer_hide_expand_close"),
|
||||
SwitchPreference("revanced_miniplayer_hide_subtext"),
|
||||
SwitchPreference("revanced_miniplayer_hide_rewind_forward"),
|
||||
TextPreference("revanced_miniplayer_opacity", inputType = InputType.NUMBER)
|
||||
)
|
||||
}
|
||||
preferences = preferences
|
||||
)
|
||||
)
|
||||
|
||||
// region Enable tablet miniplayer.
|
||||
|
||||
MiniplayerOverrideNoContextFingerprint.resolve(
|
||||
MiniplayerOverrideNoContextFingerprint.alsoResolve(
|
||||
context,
|
||||
MiniplayerDimensionsCalculatorParentFingerprint.resultOrThrow().classDef
|
||||
)
|
||||
MiniplayerOverrideNoContextFingerprint.resultOrThrow().mutableMethod.apply {
|
||||
MiniplayerDimensionsCalculatorParentFingerprint
|
||||
).mutableMethod.apply {
|
||||
findReturnIndicesReversed().forEach { index -> insertLegacyTabletMiniplayerOverride(index) }
|
||||
}
|
||||
|
||||
@ -188,8 +214,8 @@ object MiniplayerPatch : BytecodePatch(
|
||||
it.mutableMethod.insertLegacyTabletMiniplayerOverride(it.scanResult.patternScanResult!!.endIndex)
|
||||
}
|
||||
|
||||
if (isPatchingOldVersion) {
|
||||
// Return here, as patch below is only intended for new versions of the app.
|
||||
if (!VersionCheckPatch.is_19_16_or_greater) {
|
||||
// Return here, as patch below is only for the current versions of the app.
|
||||
return
|
||||
}
|
||||
|
||||
@ -212,59 +238,150 @@ object MiniplayerPatch : BytecodePatch(
|
||||
}
|
||||
}
|
||||
|
||||
if (VersionCheckPatch.is_19_23_or_greater) {
|
||||
MiniplayerModernConstructorFingerprint.insertLiteralValueBooleanOverride(
|
||||
MiniplayerModernConstructorFingerprint.DRAG_DROP_ENABLED_FEATURE_KEY_LITERAL,
|
||||
"enableMiniplayerDragAndDrop"
|
||||
)
|
||||
}
|
||||
|
||||
if (VersionCheckPatch.is_19_25_or_greater) {
|
||||
MiniplayerModernConstructorFingerprint.insertLiteralValueBooleanOverride(
|
||||
MiniplayerModernConstructorFingerprint.MODERN_MINIPLAYER_ENABLED_OLD_TARGETS_FEATURE_KEY,
|
||||
"getModernMiniplayerOverride"
|
||||
)
|
||||
|
||||
MiniplayerModernConstructorFingerprint.insertLiteralValueBooleanOverride(
|
||||
MiniplayerModernConstructorFingerprint.MODERN_FEATURE_FLAGS_ENABLED_KEY_LITERAL,
|
||||
"getModernFeatureFlagsActiveOverride"
|
||||
)
|
||||
|
||||
MiniplayerModernConstructorFingerprint.insertLiteralValueBooleanOverride(
|
||||
MiniplayerModernConstructorFingerprint.DOUBLE_TAP_ENABLED_FEATURE_KEY_LITERAL,
|
||||
"enableMiniplayerDoubleTapAction"
|
||||
)
|
||||
}
|
||||
|
||||
if (VersionCheckPatch.is_19_26_or_greater) {
|
||||
MiniplayerModernConstructorFingerprint.resultOrThrow().mutableMethod.apply {
|
||||
val literalIndex = indexOfFirstWideLiteralInstructionValueOrThrow(
|
||||
MiniplayerModernConstructorFingerprint.INITIAL_SIZE_FEATURE_KEY_LITERAL
|
||||
)
|
||||
val targetIndex = indexOfFirstInstructionOrThrow(literalIndex, Opcode.LONG_TO_INT)
|
||||
|
||||
val register = getInstruction<OneRegisterInstruction>(targetIndex).registerA
|
||||
|
||||
addInstructions(
|
||||
targetIndex + 1,
|
||||
"""
|
||||
invoke-static { v$register }, $INTEGRATIONS_CLASS_DESCRIPTOR->setMiniplayerDefaultSize(I)I
|
||||
move-result v$register
|
||||
"""
|
||||
)
|
||||
}
|
||||
|
||||
// Override a mininimum miniplayer size constant.
|
||||
MiniplayerMinimumSizeFingerprint.resultOrThrow().mutableMethod.apply {
|
||||
val index = indexOfFirstInstructionOrThrow {
|
||||
opcode == Opcode.CONST_16 && (this as NarrowLiteralInstruction).narrowLiteral == 192
|
||||
}
|
||||
val register = getInstruction<OneRegisterInstruction>(index).registerA
|
||||
|
||||
// Smaller sizes can be used, but the miniplayer will always start in size 170 if set any smaller.
|
||||
// The 170 initial limit probably could be patched to allow even smaller initial sizes,
|
||||
// but 170 is already half the horizontal space and smaller does not seem useful.
|
||||
replaceInstruction(index, "const/16 v$register, 170")
|
||||
}
|
||||
}
|
||||
|
||||
if (VersionCheckPatch.is_19_32_or_greater) {
|
||||
// Feature is not exposed in the settings, and currently only for debugging.
|
||||
|
||||
MiniplayerModernConstructorFingerprint.insertLiteralValueFloatOverride(
|
||||
MiniplayerModernConstructorFingerprint.ANIMATION_INTERPOLATION_FEATURE_KEY,
|
||||
"setMovementBoundFactor"
|
||||
)
|
||||
}
|
||||
|
||||
if (VersionCheckPatch.is_19_36_or_greater) {
|
||||
MiniplayerModernConstructorFingerprint.insertLiteralValueBooleanOverride(
|
||||
MiniplayerModernConstructorFingerprint.DROP_SHADOW_FEATURE_KEY,
|
||||
"setDropShadow"
|
||||
)
|
||||
|
||||
MiniplayerModernConstructorFingerprint.insertLiteralValueBooleanOverride(
|
||||
MiniplayerModernConstructorFingerprint.ROUNDED_CORNERS_FEATURE_KEY,
|
||||
"setRoundedCorners"
|
||||
)
|
||||
}
|
||||
|
||||
// endregion
|
||||
|
||||
// region Fix 19.16 using mixed up drawables for tablet modern.
|
||||
// YT fixed this mistake in 19.17.
|
||||
// Fix this, by swapping the drawable resource values with each other.
|
||||
|
||||
MiniplayerModernExpandCloseDrawablesFingerprint.apply {
|
||||
resolve(
|
||||
if (ytOutlinePictureInPictureWhite24 >= 0) {
|
||||
MiniplayerModernExpandCloseDrawablesFingerprint.alsoResolve(
|
||||
context,
|
||||
MiniplayerModernViewParentFingerprint.resultOrThrow().classDef
|
||||
)
|
||||
}.resultOrThrow().mutableMethod.apply {
|
||||
listOf(
|
||||
ytOutlinePictureInPictureWhite24 to ytOutlineXWhite24,
|
||||
ytOutlineXWhite24 to ytOutlinePictureInPictureWhite24,
|
||||
).forEach { (originalResource, replacementResource) ->
|
||||
val imageResourceIndex = indexOfFirstWideLiteralInstructionValueOrThrow(originalResource)
|
||||
val register = getInstruction<OneRegisterInstruction>(imageResourceIndex).registerA
|
||||
MiniplayerModernViewParentFingerprint
|
||||
).mutableMethod.apply {
|
||||
listOf(
|
||||
ytOutlinePictureInPictureWhite24 to ytOutlineXWhite24,
|
||||
ytOutlineXWhite24 to ytOutlinePictureInPictureWhite24,
|
||||
).forEach { (originalResource, replacementResource) ->
|
||||
val imageResourceIndex = indexOfFirstWideLiteralInstructionValueOrThrow(originalResource)
|
||||
val register = getInstruction<OneRegisterInstruction>(imageResourceIndex).registerA
|
||||
|
||||
replaceInstruction(imageResourceIndex, "const v$register, $replacementResource")
|
||||
replaceInstruction(imageResourceIndex, "const v$register, $replacementResource")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// endregion
|
||||
|
||||
|
||||
// region Add hooks to hide tablet modern miniplayer buttons.
|
||||
// region Add hooks to hide modern miniplayer buttons.
|
||||
|
||||
listOf(
|
||||
Triple(MiniplayerModernExpandButtonFingerprint, modernMiniplayerExpand,"hideMiniplayerExpandClose"),
|
||||
Triple(MiniplayerModernCloseButtonFingerprint, modernMiniplayerClose, "hideMiniplayerExpandClose"),
|
||||
Triple(MiniplayerModernRewindButtonFingerprint, modernMiniplayerRewindButton, "hideMiniplayerRewindForward"),
|
||||
Triple(MiniplayerModernForwardButtonFingerprint, modernMiniplayerForwardButton, "hideMiniplayerRewindForward"),
|
||||
Triple(MiniplayerModernOverlayViewFingerprint, scrimOverlay, "adjustMiniplayerOpacity")
|
||||
).forEach { (fingerprint, literalValue, methodName) ->
|
||||
fingerprint.resolve(
|
||||
context,
|
||||
MiniplayerModernViewParentFingerprint.resultOrThrow().classDef
|
||||
Triple(
|
||||
MiniplayerModernExpandButtonFingerprint,
|
||||
modernMiniplayerExpand,
|
||||
"hideMiniplayerExpandClose"
|
||||
),
|
||||
Triple(
|
||||
MiniplayerModernCloseButtonFingerprint,
|
||||
modernMiniplayerClose,
|
||||
"hideMiniplayerExpandClose"
|
||||
),
|
||||
Triple(
|
||||
MiniplayerModernRewindButtonFingerprint,
|
||||
modernMiniplayerRewindButton,
|
||||
"hideMiniplayerRewindForward"
|
||||
),
|
||||
Triple(
|
||||
MiniplayerModernForwardButtonFingerprint,
|
||||
modernMiniplayerForwardButton,
|
||||
"hideMiniplayerRewindForward"
|
||||
),
|
||||
Triple(
|
||||
MiniplayerModernOverlayViewFingerprint,
|
||||
scrimOverlay,
|
||||
"adjustMiniplayerOpacity"
|
||||
)
|
||||
|
||||
fingerprint.hookInflatedView(
|
||||
).forEach { (fingerprint, literalValue, methodName) ->
|
||||
fingerprint.alsoResolve(
|
||||
context,
|
||||
MiniplayerModernViewParentFingerprint
|
||||
).mutableMethod.hookInflatedView(
|
||||
literalValue,
|
||||
"Landroid/widget/ImageView;",
|
||||
"$INTEGRATIONS_CLASS_DESCRIPTOR->$methodName(Landroid/widget/ImageView;)V"
|
||||
)
|
||||
}
|
||||
|
||||
MiniplayerModernAddViewListenerFingerprint.apply {
|
||||
resolve(
|
||||
context,
|
||||
MiniplayerModernViewParentFingerprint.resultOrThrow().classDef
|
||||
)
|
||||
}.resultOrThrow().mutableMethod.addInstruction(
|
||||
MiniplayerModernAddViewListenerFingerprint.alsoResolve(
|
||||
context,
|
||||
MiniplayerModernViewParentFingerprint
|
||||
).mutableMethod.addInstruction(
|
||||
0,
|
||||
"invoke-static { p1 }, $INTEGRATIONS_CLASS_DESCRIPTOR->" +
|
||||
"hideMiniplayerSubTexts(Landroid/view/View;)V"
|
||||
@ -275,6 +392,9 @@ object MiniplayerPatch : BytecodePatch(
|
||||
// Modern 2 uses the same overlay controls as the regular video player,
|
||||
// and the overlay views are added at runtime.
|
||||
// Add a hook to the overlay class, and pass the added views to integrations.
|
||||
//
|
||||
// NOTE: Modern 2 uses the same video UI as the regular player except resized to smaller.
|
||||
// This patch code could be used to hide other player overlays that do not use Litho.
|
||||
YouTubePlayerOverlaysLayoutFingerprint.resultOrThrow().mutableClass.methods.add(
|
||||
ImmutableMethod(
|
||||
YOUTUBE_PLAYER_OVERLAYS_LAYOUT_CLASS_NAME,
|
||||
@ -319,6 +439,37 @@ object MiniplayerPatch : BytecodePatch(
|
||||
insertBooleanOverride(index, "getModernMiniplayerOverride")
|
||||
}
|
||||
|
||||
private fun MethodFingerprint.insertLiteralValueBooleanOverride(
|
||||
literal: Long,
|
||||
integrationsMethod: String
|
||||
) {
|
||||
resultOrThrow().mutableMethod.apply {
|
||||
val literalIndex = indexOfFirstWideLiteralInstructionValueOrThrow(literal)
|
||||
val targetIndex = indexOfFirstInstructionOrThrow(literalIndex, Opcode.MOVE_RESULT)
|
||||
|
||||
insertBooleanOverride(targetIndex + 1, integrationsMethod)
|
||||
}
|
||||
}
|
||||
|
||||
private fun MethodFingerprint.insertLiteralValueFloatOverride(
|
||||
literal: Long,
|
||||
integrationsMethod: String
|
||||
) {
|
||||
resultOrThrow().mutableMethod.apply {
|
||||
val literalIndex = indexOfFirstWideLiteralInstructionValueOrThrow(literal)
|
||||
val targetIndex = indexOfFirstInstructionOrThrow(literalIndex, Opcode.DOUBLE_TO_FLOAT)
|
||||
val register = getInstruction<OneRegisterInstruction>(targetIndex).registerA
|
||||
|
||||
addInstructions(
|
||||
targetIndex + 1,
|
||||
"""
|
||||
invoke-static {v$register}, $INTEGRATIONS_CLASS_DESCRIPTOR->$integrationsMethod(F)F
|
||||
move-result v$register
|
||||
"""
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
private fun MutableMethod.insertBooleanOverride(index: Int, methodName: String) {
|
||||
val register = getInstruction<OneRegisterInstruction>(index).registerA
|
||||
addInstructions(
|
||||
@ -335,36 +486,30 @@ object MiniplayerPatch : BytecodePatch(
|
||||
*/
|
||||
private fun MutableMethod.insertModernMiniplayerTypeOverride(iPutIndex: Int) {
|
||||
val targetInstruction = getInstruction<TwoRegisterInstruction>(iPutIndex)
|
||||
val targetReference = (targetInstruction as ReferenceInstruction).reference
|
||||
|
||||
addInstructions(
|
||||
iPutIndex + 1, """
|
||||
addInstructionsAtControlFlowLabel(
|
||||
iPutIndex, """
|
||||
invoke-static { v${targetInstruction.registerA} }, $INTEGRATIONS_CLASS_DESCRIPTOR->getModernMiniplayerOverrideType(I)I
|
||||
move-result v${targetInstruction.registerA}
|
||||
# Original instruction
|
||||
iput v${targetInstruction.registerA}, v${targetInstruction.registerB}, $targetReference
|
||||
"""
|
||||
)
|
||||
removeInstruction(iPutIndex)
|
||||
}
|
||||
|
||||
private fun LiteralValueFingerprint.hookInflatedView(
|
||||
private fun MutableMethod.hookInflatedView(
|
||||
literalValue: Long,
|
||||
hookedClassType: String,
|
||||
integrationsMethodName: String,
|
||||
) {
|
||||
resultOrThrow().mutableMethod.apply {
|
||||
val imageViewIndex = indexOfFirstInstructionOrThrow(
|
||||
indexOfFirstWideLiteralInstructionValueOrThrow(literalValue)
|
||||
) {
|
||||
opcode == Opcode.CHECK_CAST && getReference<TypeReference>()?.type == hookedClassType
|
||||
}
|
||||
|
||||
val register = getInstruction<OneRegisterInstruction>(imageViewIndex).registerA
|
||||
addInstruction(
|
||||
imageViewIndex + 1,
|
||||
"invoke-static { v$register }, $integrationsMethodName"
|
||||
)
|
||||
val imageViewIndex = indexOfFirstInstructionOrThrow(
|
||||
indexOfFirstWideLiteralInstructionValueOrThrow(literalValue)
|
||||
) {
|
||||
opcode == Opcode.CHECK_CAST && getReference<TypeReference>()?.type == hookedClassType
|
||||
}
|
||||
|
||||
val register = getInstruction<OneRegisterInstruction>(imageViewIndex).registerA
|
||||
addInstruction(
|
||||
imageViewIndex + 1,
|
||||
"invoke-static { v$register }, $integrationsMethodName"
|
||||
)
|
||||
}
|
||||
}
|
||||
|
@ -1,12 +1,12 @@
|
||||
package app.revanced.patches.youtube.layout.miniplayer
|
||||
|
||||
import app.revanced.patcher.data.ResourceContext
|
||||
import app.revanced.patcher.patch.PatchException
|
||||
import app.revanced.patcher.patch.ResourcePatch
|
||||
import app.revanced.patcher.patch.annotation.Patch
|
||||
import app.revanced.patches.shared.misc.mapping.ResourceMappingPatch
|
||||
import app.revanced.patches.youtube.misc.playservice.VersionCheckPatch
|
||||
|
||||
@Patch(dependencies = [ResourceMappingPatch::class])
|
||||
@Patch(dependencies = [ResourceMappingPatch::class, VersionCheckPatch::class])
|
||||
internal object MiniplayerResourcePatch : ResourcePatch() {
|
||||
var floatyBarButtonTopMargin = -1L
|
||||
|
||||
@ -19,6 +19,7 @@ internal object MiniplayerResourcePatch : ResourcePatch() {
|
||||
var modernMiniplayerRewindButton = -1L
|
||||
var modernMiniplayerForwardButton = -1L
|
||||
var playerOverlays = -1L
|
||||
var miniplayerMaxSize = -1L
|
||||
|
||||
override fun execute(context: ResourceContext) {
|
||||
floatyBarButtonTopMargin = ResourceMappingPatch[
|
||||
@ -26,56 +27,63 @@ internal object MiniplayerResourcePatch : ResourcePatch() {
|
||||
"floaty_bar_button_top_margin"
|
||||
]
|
||||
|
||||
try {
|
||||
ytOutlinePictureInPictureWhite24 = ResourceMappingPatch[
|
||||
"drawable",
|
||||
"yt_outline_picture_in_picture_white_24"
|
||||
]
|
||||
} catch (exception: PatchException) {
|
||||
// Ignore, and assume the app is 19.14 or earlier.
|
||||
return
|
||||
}
|
||||
|
||||
ytOutlineXWhite24 = ResourceMappingPatch[
|
||||
"drawable",
|
||||
"yt_outline_x_white_24"
|
||||
]
|
||||
|
||||
scrimOverlay = ResourceMappingPatch[
|
||||
"id",
|
||||
"scrim_overlay"
|
||||
]
|
||||
|
||||
modernMiniplayerClose = ResourceMappingPatch[
|
||||
"id",
|
||||
"modern_miniplayer_close"
|
||||
]
|
||||
|
||||
modernMiniplayerExpand = ResourceMappingPatch[
|
||||
"id",
|
||||
"modern_miniplayer_expand"
|
||||
]
|
||||
|
||||
modernMiniplayerRewindButton = ResourceMappingPatch[
|
||||
"id",
|
||||
"modern_miniplayer_rewind_button"
|
||||
]
|
||||
|
||||
modernMiniplayerForwardButton = ResourceMappingPatch[
|
||||
"id",
|
||||
"modern_miniplayer_forward_button"
|
||||
]
|
||||
|
||||
playerOverlays = ResourceMappingPatch[
|
||||
"layout",
|
||||
"player_overlays"
|
||||
]
|
||||
|
||||
// Resource id is not used during patching, but is used by integrations.
|
||||
// Verify the resource is present while patching.
|
||||
ResourceMappingPatch[
|
||||
"id",
|
||||
"modern_miniplayer_subtitle_text"
|
||||
]
|
||||
if (VersionCheckPatch.is_19_16_or_greater) {
|
||||
modernMiniplayerClose = ResourceMappingPatch[
|
||||
"id",
|
||||
"modern_miniplayer_close"
|
||||
]
|
||||
|
||||
modernMiniplayerExpand = ResourceMappingPatch[
|
||||
"id",
|
||||
"modern_miniplayer_expand"
|
||||
]
|
||||
|
||||
modernMiniplayerRewindButton = ResourceMappingPatch[
|
||||
"id",
|
||||
"modern_miniplayer_rewind_button"
|
||||
]
|
||||
|
||||
modernMiniplayerForwardButton = ResourceMappingPatch[
|
||||
"id",
|
||||
"modern_miniplayer_forward_button"
|
||||
]
|
||||
|
||||
// Resource id is not used during patching, but is used by integrations.
|
||||
// Verify the resource is present while patching.
|
||||
ResourceMappingPatch[
|
||||
"id",
|
||||
"modern_miniplayer_subtitle_text"
|
||||
]
|
||||
|
||||
// Only required for exactly 19.16
|
||||
if (!VersionCheckPatch.is_19_17_or_greater) {
|
||||
ytOutlinePictureInPictureWhite24 = ResourceMappingPatch[
|
||||
"drawable",
|
||||
"yt_outline_picture_in_picture_white_24"
|
||||
]
|
||||
|
||||
ytOutlineXWhite24 = ResourceMappingPatch[
|
||||
"drawable",
|
||||
"yt_outline_x_white_24"
|
||||
]
|
||||
}
|
||||
|
||||
if (VersionCheckPatch.is_19_26_or_greater) {
|
||||
miniplayerMaxSize = ResourceMappingPatch[
|
||||
"dimen",
|
||||
"miniplayer_max_size"
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,16 @@
|
||||
package app.revanced.patches.youtube.layout.miniplayer.fingerprints
|
||||
|
||||
import app.revanced.patcher.extensions.or
|
||||
import app.revanced.patcher.fingerprint.MethodFingerprint
|
||||
import app.revanced.patches.youtube.layout.miniplayer.MiniplayerResourcePatch
|
||||
import app.revanced.util.containsWideLiteralInstructionValue
|
||||
import com.android.tools.smali.dexlib2.AccessFlags
|
||||
|
||||
internal object MiniplayerMinimumSizeFingerprint : MethodFingerprint(
|
||||
accessFlags = AccessFlags.PUBLIC or AccessFlags.CONSTRUCTOR,
|
||||
customFingerprint = { methodDef, _ ->
|
||||
methodDef.containsWideLiteralInstructionValue(192)
|
||||
&& methodDef.containsWideLiteralInstructionValue(128)
|
||||
&& methodDef.containsWideLiteralInstructionValue(MiniplayerResourcePatch.miniplayerMaxSize)
|
||||
}
|
||||
)
|
@ -8,4 +8,14 @@ internal object MiniplayerModernConstructorFingerprint : LiteralValueFingerprint
|
||||
accessFlags = AccessFlags.PUBLIC or AccessFlags.CONSTRUCTOR,
|
||||
parameters = listOf("L"),
|
||||
literalSupplier = { 45623000L } // Magic number found in the constructor.
|
||||
)
|
||||
) {
|
||||
const val MODERN_FEATURE_FLAGS_ENABLED_KEY_LITERAL = 45622882L
|
||||
// In later targets this feature flag does nothing and is dead code.
|
||||
const val MODERN_MINIPLAYER_ENABLED_OLD_TARGETS_FEATURE_KEY = 45630429L
|
||||
const val DOUBLE_TAP_ENABLED_FEATURE_KEY_LITERAL = 45628823L
|
||||
const val DRAG_DROP_ENABLED_FEATURE_KEY_LITERAL = 45628752L
|
||||
const val INITIAL_SIZE_FEATURE_KEY_LITERAL = 45640023L
|
||||
const val ANIMATION_INTERPOLATION_FEATURE_KEY = 45647018L
|
||||
const val DROP_SHADOW_FEATURE_KEY = 45652223L
|
||||
const val ROUNDED_CORNERS_FEATURE_KEY = 45652224L
|
||||
}
|
@ -7,6 +7,5 @@ import com.android.tools.smali.dexlib2.AccessFlags
|
||||
internal object MiniplayerOverrideFingerprint : MethodFingerprint(
|
||||
returnType = "L",
|
||||
accessFlags = AccessFlags.PUBLIC or AccessFlags.FINAL,
|
||||
parameters = listOf("L"),
|
||||
strings = listOf("appName")
|
||||
)
|
@ -19,30 +19,11 @@ import app.revanced.util.exception
|
||||
compatiblePackages = [
|
||||
CompatiblePackage(
|
||||
"com.google.android.youtube", [
|
||||
"18.32.39",
|
||||
"18.37.36",
|
||||
"18.38.44",
|
||||
"18.43.45",
|
||||
"18.44.41",
|
||||
"18.45.43",
|
||||
"18.48.39",
|
||||
"18.49.37",
|
||||
"19.01.34",
|
||||
"19.02.39",
|
||||
"19.03.36",
|
||||
"19.04.38",
|
||||
"19.05.36",
|
||||
"19.06.39",
|
||||
"19.07.40",
|
||||
"19.08.36",
|
||||
"19.09.38",
|
||||
"19.10.39",
|
||||
"19.11.43",
|
||||
"19.12.41",
|
||||
"19.13.37",
|
||||
"19.14.43",
|
||||
"19.15.36",
|
||||
"19.16.39",
|
||||
"19.25.37",
|
||||
"19.34.42",
|
||||
]
|
||||
)
|
||||
]
|
||||
|
@ -14,30 +14,11 @@ import org.w3c.dom.Element
|
||||
CompatiblePackage(
|
||||
"com.google.android.youtube",
|
||||
[
|
||||
"18.32.39",
|
||||
"18.37.36",
|
||||
"18.38.44",
|
||||
"18.43.45",
|
||||
"18.44.41",
|
||||
"18.45.43",
|
||||
"18.48.39",
|
||||
"18.49.37",
|
||||
"19.01.34",
|
||||
"19.02.39",
|
||||
"19.03.36",
|
||||
"19.04.38",
|
||||
"19.05.36",
|
||||
"19.06.39",
|
||||
"19.07.40",
|
||||
"19.08.36",
|
||||
"19.09.38",
|
||||
"19.10.39",
|
||||
"19.11.43",
|
||||
"19.12.41",
|
||||
"19.13.37",
|
||||
"19.14.43",
|
||||
"19.15.36",
|
||||
"19.16.39",
|
||||
"19.25.37",
|
||||
"19.34.42",
|
||||
],
|
||||
),
|
||||
],
|
||||
|
@ -5,6 +5,7 @@ import app.revanced.patcher.extensions.InstructionExtensions.addInstruction
|
||||
import app.revanced.patcher.extensions.InstructionExtensions.addInstructions
|
||||
import app.revanced.patcher.extensions.InstructionExtensions.addInstructionsWithLabels
|
||||
import app.revanced.patcher.extensions.InstructionExtensions.getInstruction
|
||||
import app.revanced.patcher.extensions.InstructionExtensions.getInstructions
|
||||
import app.revanced.patcher.fingerprint.MethodFingerprint
|
||||
import app.revanced.patcher.patch.BytecodePatch
|
||||
import app.revanced.patcher.patch.PatchException
|
||||
@ -27,11 +28,14 @@ import app.revanced.patches.youtube.layout.returnyoutubedislike.fingerprints.Tex
|
||||
import app.revanced.patches.youtube.misc.integrations.IntegrationsPatch
|
||||
import app.revanced.patches.youtube.misc.litho.filter.LithoFilterPatch
|
||||
import app.revanced.patches.youtube.misc.playertype.PlayerTypeHookPatch
|
||||
import app.revanced.patches.youtube.misc.playservice.VersionCheckPatch
|
||||
import app.revanced.patches.youtube.shared.fingerprints.RollingNumberTextViewAnimationUpdateFingerprint
|
||||
import app.revanced.patches.youtube.video.videoid.VideoIdPatch
|
||||
import app.revanced.util.alsoResolve
|
||||
import app.revanced.util.exception
|
||||
import app.revanced.util.getReference
|
||||
import app.revanced.util.indexOfFirstInstructionOrThrow
|
||||
import app.revanced.util.addInstructionsAtControlFlowLabel
|
||||
import app.revanced.util.resultOrThrow
|
||||
import com.android.tools.smali.dexlib2.Opcode
|
||||
import com.android.tools.smali.dexlib2.iface.instruction.FiveRegisterInstruction
|
||||
@ -51,27 +55,15 @@ import com.android.tools.smali.dexlib2.iface.reference.TypeReference
|
||||
VideoIdPatch::class,
|
||||
ReturnYouTubeDislikeResourcePatch::class,
|
||||
PlayerTypeHookPatch::class,
|
||||
VersionCheckPatch::class
|
||||
],
|
||||
compatiblePackages = [
|
||||
CompatiblePackage(
|
||||
"com.google.android.youtube", [
|
||||
"18.49.37",
|
||||
"19.01.34",
|
||||
"19.02.39",
|
||||
"19.03.36",
|
||||
"19.04.38",
|
||||
"19.05.36",
|
||||
"19.06.39",
|
||||
"19.07.40",
|
||||
"19.08.36",
|
||||
"19.09.38",
|
||||
"19.10.39",
|
||||
"19.11.43",
|
||||
"19.12.41",
|
||||
"19.13.37",
|
||||
"19.14.43",
|
||||
"19.15.36",
|
||||
"19.16.39",
|
||||
"19.25.37",
|
||||
"19.34.42",
|
||||
]
|
||||
)
|
||||
]
|
||||
@ -117,7 +109,7 @@ object ReturnYouTubeDislikePatch : BytecodePatch(
|
||||
DislikeFingerprint.toPatch(Vote.DISLIKE),
|
||||
RemoveLikeFingerprint.toPatch(Vote.REMOVE_LIKE)
|
||||
).forEach { (fingerprint, vote) ->
|
||||
fingerprint.result?.mutableMethod?.apply {
|
||||
fingerprint.resultOrThrow().mutableMethod.apply {
|
||||
addInstructions(
|
||||
0,
|
||||
"""
|
||||
@ -125,7 +117,7 @@ object ReturnYouTubeDislikePatch : BytecodePatch(
|
||||
invoke-static {v0}, $INTEGRATIONS_CLASS_DESCRIPTOR->sendVote(I)V
|
||||
"""
|
||||
)
|
||||
} ?: throw fingerprint.exception
|
||||
}
|
||||
}
|
||||
|
||||
// endregion
|
||||
@ -136,7 +128,7 @@ object ReturnYouTubeDislikePatch : BytecodePatch(
|
||||
// And it works in all situations except it fails to update the Span when the user dislikes,
|
||||
// since the underlying (likes only) text did not change.
|
||||
// This hook handles all situations, as it's where the created Spans are stored and later reused.
|
||||
TextComponentConstructorFingerprint.result?.let { textConstructorResult ->
|
||||
TextComponentConstructorFingerprint.resultOrThrow().let { textConstructorResult ->
|
||||
// Find the field name of the conversion context.
|
||||
val conversionContextClassType = ConversionContextFingerprint.resultOrThrow().classDef.type
|
||||
val conversionContextField = textConstructorResult.classDef.fields.find {
|
||||
@ -147,55 +139,80 @@ object ReturnYouTubeDislikePatch : BytecodePatch(
|
||||
TextComponentLookupFingerprint.resultOrThrow().mutableMethod.apply {
|
||||
// Find the instruction for creating the text data object.
|
||||
val textDataClassType = TextComponentDataFingerprint.resultOrThrow().classDef.type
|
||||
val insertIndex = indexOfFirstInstructionOrThrow {
|
||||
opcode == Opcode.NEW_INSTANCE &&
|
||||
getReference<TypeReference>()?.type == textDataClassType
|
||||
|
||||
val insertIndex : Int
|
||||
val tempRegister : Int
|
||||
val charSequenceRegister : Int
|
||||
|
||||
if (VersionCheckPatch.is_19_33_or_greater) {
|
||||
insertIndex = indexOfFirstInstructionOrThrow {
|
||||
opcode == Opcode.INVOKE_STATIC_RANGE &&
|
||||
getReference<MethodReference>()?.returnType == textDataClassType
|
||||
}
|
||||
|
||||
tempRegister = getInstruction<OneRegisterInstruction>(insertIndex + 1).registerA
|
||||
|
||||
// Find the instruction that sets the span to an instance field.
|
||||
// The instruction is only a few lines after the creation of the instance.
|
||||
charSequenceRegister = getInstruction<FiveRegisterInstruction>(
|
||||
indexOfFirstInstructionOrThrow(insertIndex) {
|
||||
opcode == Opcode.INVOKE_VIRTUAL &&
|
||||
getReference<MethodReference>()?.parameterTypes?.firstOrNull() == "Ljava/lang/CharSequence;"
|
||||
}
|
||||
).registerD
|
||||
} else {
|
||||
insertIndex = indexOfFirstInstructionOrThrow {
|
||||
opcode == Opcode.NEW_INSTANCE &&
|
||||
getReference<TypeReference>()?.type == textDataClassType
|
||||
}
|
||||
|
||||
tempRegister = getInstruction<OneRegisterInstruction>(insertIndex).registerA
|
||||
|
||||
charSequenceRegister = getInstruction<TwoRegisterInstruction>(
|
||||
indexOfFirstInstructionOrThrow(insertIndex) {
|
||||
opcode == Opcode.IPUT_OBJECT &&
|
||||
getReference<FieldReference>()?.type == "Ljava/lang/CharSequence;"
|
||||
}
|
||||
).registerA
|
||||
}
|
||||
val tempRegister = getInstruction<OneRegisterInstruction>(insertIndex).registerA
|
||||
|
||||
// Find the instruction that sets the span to an instance field.
|
||||
// The instruction is only a few lines after the creation of the instance.
|
||||
// The method has multiple iput-object instructions using a CharSequence,
|
||||
// so verify the found instruction is in the expected location.
|
||||
val putFieldInstruction = implementation!!.instructions
|
||||
.subList(insertIndex, insertIndex + 20)
|
||||
.find {
|
||||
it.opcode == Opcode.IPUT_OBJECT &&
|
||||
it.getReference<FieldReference>()?.type == "Ljava/lang/CharSequence;"
|
||||
} ?: throw PatchException("Could not find put object instruction")
|
||||
val charSequenceRegister = (putFieldInstruction as TwoRegisterInstruction).registerA
|
||||
|
||||
addInstructions(
|
||||
insertIndex,
|
||||
addInstructionsAtControlFlowLabel(insertIndex,
|
||||
"""
|
||||
# Copy conversion context
|
||||
move-object/from16 v$tempRegister, p0
|
||||
iget-object v$tempRegister, v$tempRegister, $conversionContextField
|
||||
invoke-static { v$tempRegister, v$charSequenceRegister }, $INTEGRATIONS_CLASS_DESCRIPTOR->onLithoTextLoaded(Ljava/lang/Object;Ljava/lang/CharSequence;)Ljava/lang/CharSequence;
|
||||
move-result-object v$charSequenceRegister
|
||||
"""
|
||||
# Copy conversion context
|
||||
move-object/from16 v$tempRegister, p0
|
||||
iget-object v$tempRegister, v$tempRegister, $conversionContextField
|
||||
invoke-static {v$tempRegister, v$charSequenceRegister}, $INTEGRATIONS_CLASS_DESCRIPTOR->onLithoTextLoaded(Ljava/lang/Object;Ljava/lang/CharSequence;)Ljava/lang/CharSequence;
|
||||
move-result-object v$charSequenceRegister
|
||||
"""
|
||||
)
|
||||
}
|
||||
} ?: throw TextComponentConstructorFingerprint.exception
|
||||
}
|
||||
|
||||
// endregion
|
||||
|
||||
// region Hook for non-litho Short videos.
|
||||
|
||||
ShortsTextViewFingerprint.result?.let {
|
||||
ShortsTextViewFingerprint.resultOrThrow().let {
|
||||
it.mutableMethod.apply {
|
||||
val patternResult = it.scanResult.patternScanResult!!
|
||||
val insertIndex = it.scanResult.patternScanResult!!.endIndex + 1
|
||||
|
||||
// If the field is true, the TextView is for a dislike button.
|
||||
val isDisLikesBooleanReference = getInstruction<ReferenceInstruction>(patternResult.endIndex).reference
|
||||
val isDisLikesBooleanInstruction = getInstructions().first { instruction ->
|
||||
instruction.opcode == Opcode.IGET_BOOLEAN
|
||||
} as ReferenceInstruction
|
||||
|
||||
val textViewFieldReference = // Like/Dislike button TextView field
|
||||
getInstruction<ReferenceInstruction>(patternResult.endIndex - 1).reference
|
||||
val isDisLikesBooleanReference = isDisLikesBooleanInstruction.reference
|
||||
|
||||
// Like/Dislike button TextView field.
|
||||
val textViewFieldInstruction = getInstructions().first { instruction ->
|
||||
instruction.opcode == Opcode.IGET_OBJECT
|
||||
} as ReferenceInstruction
|
||||
|
||||
val textViewFieldReference = textViewFieldInstruction.reference
|
||||
|
||||
// Check if the hooked TextView object is that of the dislike button.
|
||||
// If RYD is disabled, or the TextView object is not that of the dislike button, the execution flow is not interrupted.
|
||||
// Otherwise, the TextView object is modified, and the execution flow is interrupted to prevent it from being changed afterward.
|
||||
val insertIndex = patternResult.startIndex + 6
|
||||
addInstructionsWithLabels(
|
||||
insertIndex,
|
||||
"""
|
||||
@ -216,7 +233,7 @@ object ReturnYouTubeDislikePatch : BytecodePatch(
|
||||
"""
|
||||
)
|
||||
}
|
||||
} ?: throw ShortsTextViewFingerprint.exception
|
||||
}
|
||||
|
||||
// endregion
|
||||
|
||||
@ -251,20 +268,14 @@ object ReturnYouTubeDislikePatch : BytecodePatch(
|
||||
|
||||
// region Hook rolling numbers.
|
||||
|
||||
// Do this last to allow patching old unsupported versions (if the user really wants),
|
||||
// On older unsupported version this will fail to resolve and throw an exception,
|
||||
// but everything will still work correctly anyways.
|
||||
|
||||
RollingNumberSetterFingerprint.result?.let {
|
||||
RollingNumberSetterFingerprint.resultOrThrow().let {
|
||||
val dislikesIndex = it.scanResult.patternScanResult!!.endIndex
|
||||
|
||||
it.mutableMethod.apply {
|
||||
val insertIndex = 1
|
||||
|
||||
val charSequenceInstanceRegister =
|
||||
getInstruction<OneRegisterInstruction>(0).registerA
|
||||
val charSequenceFieldReference =
|
||||
getInstruction<ReferenceInstruction>(dislikesIndex).reference
|
||||
val charSequenceInstanceRegister = getInstruction<OneRegisterInstruction>(0).registerA
|
||||
val charSequenceFieldReference = getInstruction<ReferenceInstruction>(dislikesIndex).reference
|
||||
|
||||
val registerCount = implementation!!.registerCount
|
||||
|
||||
@ -282,7 +293,7 @@ object ReturnYouTubeDislikePatch : BytecodePatch(
|
||||
"""
|
||||
)
|
||||
}
|
||||
} ?: throw RollingNumberSetterFingerprint.exception
|
||||
}
|
||||
|
||||
// Rolling Number text views use the measured width of the raw string for layout.
|
||||
// Modify the measure text calculation to include the left drawable separator if needed.
|
||||
@ -306,9 +317,12 @@ object ReturnYouTubeDislikePatch : BytecodePatch(
|
||||
|
||||
// Additional text measurement method. Used if YouTube decides not to animate the likes count
|
||||
// and sometimes used for initial video load.
|
||||
RollingNumberMeasureStaticLabelFingerprint.resolve(context, RollingNumberMeasureStaticLabelParentFingerprint.resultOrThrow().classDef)
|
||||
RollingNumberMeasureStaticLabelFingerprint.result?.also {
|
||||
RollingNumberMeasureStaticLabelFingerprint.alsoResolve(
|
||||
context,
|
||||
RollingNumberMeasureStaticLabelParentFingerprint
|
||||
).let {
|
||||
val measureTextIndex = it.scanResult.patternScanResult!!.startIndex + 1
|
||||
|
||||
it.mutableMethod.apply {
|
||||
val freeRegister = getInstruction<TwoRegisterInstruction>(0).registerA
|
||||
|
||||
@ -320,19 +334,18 @@ object ReturnYouTubeDislikePatch : BytecodePatch(
|
||||
"""
|
||||
)
|
||||
}
|
||||
} ?: throw RollingNumberMeasureStaticLabelFingerprint.exception
|
||||
}
|
||||
|
||||
// The rolling number Span is missing styling since it's initially set as a String.
|
||||
// Modify the UI text view and use the styled like/dislike Span.
|
||||
RollingNumberTextViewFingerprint.result?.let {
|
||||
RollingNumberTextViewFingerprint.resultOrThrow().let {
|
||||
// Initial TextView is set in this method.
|
||||
val initiallyCreatedTextViewMethod = it.mutableMethod
|
||||
|
||||
// Videos less than 24 hours after uploaded, like counts will be updated in real time.
|
||||
// Whenever like counts are updated, TextView is set in this method.
|
||||
val realTimeUpdateTextViewMethod =
|
||||
RollingNumberTextViewAnimationUpdateFingerprint.result?.mutableMethod
|
||||
?: throw RollingNumberTextViewAnimationUpdateFingerprint.exception
|
||||
RollingNumberTextViewAnimationUpdateFingerprint.resultOrThrow().mutableMethod
|
||||
|
||||
arrayOf(
|
||||
initiallyCreatedTextViewMethod,
|
||||
@ -357,7 +370,7 @@ object ReturnYouTubeDislikePatch : BytecodePatch(
|
||||
)
|
||||
}
|
||||
}
|
||||
} ?: throw RollingNumberTextViewFingerprint.exception
|
||||
}
|
||||
|
||||
// endregion
|
||||
|
||||
|
@ -10,9 +10,6 @@ internal object ConversionContextFingerprint : MethodFingerprint(
|
||||
", heightConstraint=",
|
||||
", templateLoggerFactory=",
|
||||
", rootDisposableContainer=",
|
||||
// 18.37.36 and after this String is: ConversionContext{containerInternal=
|
||||
// and before it is: ConversionContext{container=
|
||||
// Use a partial string to match both.
|
||||
"ConversionContext{container"
|
||||
"ConversionContext{containerInternal="
|
||||
)
|
||||
)
|
@ -8,5 +8,6 @@ internal object RollingNumberSetterFingerprint : MethodFingerprint(
|
||||
Opcode.INVOKE_DIRECT,
|
||||
Opcode.IGET_OBJECT
|
||||
),
|
||||
strings = listOf("RollingNumberType required properties missing! Need updateCount, fontName, color and fontSize.")
|
||||
// Partial string match.
|
||||
strings = listOf("RollingNumberType required properties missing! Need")
|
||||
)
|
@ -18,6 +18,7 @@ internal object RollingNumberTextViewFingerprint : MethodFingerprint(
|
||||
Opcode.RETURN_VOID
|
||||
),
|
||||
customFingerprint = { _, classDef ->
|
||||
classDef.superclass == "Landroid/support/v7/widget/AppCompatTextView;"
|
||||
classDef.superclass == "Landroid/support/v7/widget/AppCompatTextView;" ||
|
||||
classDef.superclass == "Lcom/google/android/libraries/youtube/rendering/ui/spec/typography/YouTubeAppCompatTextView;"
|
||||
}
|
||||
)
|
@ -15,18 +15,6 @@ internal object ShortsTextViewFingerprint : MethodFingerprint(
|
||||
null,
|
||||
Opcode.INVOKE_VIRTUAL,
|
||||
Opcode.MOVE_RESULT_OBJECT,
|
||||
Opcode.CHECK_CAST,
|
||||
Opcode.SGET_OBJECT, // insertion point, must be after constructor call to parent class
|
||||
Opcode.INVOKE_VIRTUAL,
|
||||
Opcode.MOVE_RESULT,
|
||||
Opcode.CONST_4,
|
||||
Opcode.IF_EQZ,
|
||||
Opcode.CONST_4,
|
||||
Opcode.IF_EQ,
|
||||
Opcode.CONST_4,
|
||||
Opcode.IF_EQ,
|
||||
Opcode.RETURN_VOID,
|
||||
Opcode.IGET_OBJECT, // TextView field
|
||||
Opcode.IGET_BOOLEAN, // boolean field
|
||||
Opcode.CHECK_CAST
|
||||
)
|
||||
)
|
@ -9,8 +9,6 @@ internal object TextComponentDataFingerprint : MethodFingerprint(
|
||||
parameters = listOf("L", "L"),
|
||||
strings = listOf("text"),
|
||||
customFingerprint = { _, classDef ->
|
||||
val fields = classDef.fields
|
||||
fields.find { it.type == "Ljava/util/BitSet;" } != null &&
|
||||
fields.find { it.type == "[Ljava/lang/String;" } != null
|
||||
classDef.fields.find { it.type == "Ljava/util/BitSet;" } != null
|
||||
}
|
||||
)
|
@ -24,29 +24,11 @@ import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction
|
||||
compatiblePackages = [
|
||||
CompatiblePackage(
|
||||
"com.google.android.youtube", [
|
||||
"18.32.39",
|
||||
"18.37.36",
|
||||
"18.38.44",
|
||||
"18.43.45",
|
||||
"18.45.43",
|
||||
"18.48.39",
|
||||
"18.49.37",
|
||||
"19.01.34",
|
||||
"19.02.39",
|
||||
"19.03.36",
|
||||
"19.04.38",
|
||||
"19.05.36",
|
||||
"19.06.39",
|
||||
"19.07.40",
|
||||
"19.08.36",
|
||||
"19.09.38",
|
||||
"19.10.39",
|
||||
"19.11.43",
|
||||
"19.12.41",
|
||||
"19.13.37",
|
||||
"19.14.43",
|
||||
"19.15.36",
|
||||
"19.16.39",
|
||||
"19.25.37",
|
||||
"19.34.42",
|
||||
]
|
||||
)
|
||||
]
|
||||
|
@ -18,6 +18,6 @@ internal object SetWordmarkHeaderFingerprint : MethodFingerprint(
|
||||
Opcode.IF_EQZ,
|
||||
Opcode.IGET_OBJECT,
|
||||
Opcode.CONST,
|
||||
Opcode.INVOKE_STATIC,
|
||||
null // invoke-static or invoke-virtual
|
||||
)
|
||||
)
|
@ -4,45 +4,28 @@ import app.revanced.patcher.data.BytecodeContext
|
||||
import app.revanced.patcher.extensions.InstructionExtensions.addInstruction
|
||||
import app.revanced.patcher.extensions.InstructionExtensions.getInstructions
|
||||
import app.revanced.patcher.patch.BytecodePatch
|
||||
import app.revanced.patcher.patch.PatchException
|
||||
import app.revanced.patcher.patch.annotation.CompatiblePackage
|
||||
import app.revanced.patcher.patch.annotation.Patch
|
||||
import app.revanced.patches.all.misc.resources.AddResourcesPatch
|
||||
import app.revanced.patches.shared.misc.settings.preference.SwitchPreference
|
||||
import app.revanced.patches.youtube.layout.seekbar.fingerprints.FullscreenSeekbarThumbnailsFingerprint
|
||||
import app.revanced.patches.youtube.misc.integrations.IntegrationsPatch
|
||||
import app.revanced.patches.youtube.misc.playservice.VersionCheckPatch
|
||||
import app.revanced.patches.youtube.misc.settings.SettingsPatch
|
||||
import app.revanced.util.exception
|
||||
|
||||
@Patch(
|
||||
name = "Restore old seekbar thumbnails",
|
||||
description = "Adds an option to restore the old seekbar thumbnails that appear above the seekbar while seeking instead of fullscreen thumbnails.",
|
||||
dependencies = [IntegrationsPatch::class, AddResourcesPatch::class],
|
||||
dependencies = [IntegrationsPatch::class, AddResourcesPatch::class, VersionCheckPatch::class],
|
||||
compatiblePackages = [
|
||||
CompatiblePackage(
|
||||
"com.google.android.youtube", [
|
||||
"18.37.36",
|
||||
"18.38.44",
|
||||
"18.43.45",
|
||||
"18.44.41",
|
||||
"18.45.43",
|
||||
"18.48.39",
|
||||
"18.49.37",
|
||||
"19.01.34",
|
||||
"19.02.39",
|
||||
"19.03.36",
|
||||
"19.04.38",
|
||||
"19.05.36",
|
||||
"19.06.39",
|
||||
"19.07.40",
|
||||
"19.08.36",
|
||||
"19.09.38",
|
||||
"19.10.39",
|
||||
"19.11.43",
|
||||
"19.12.41",
|
||||
"19.13.37",
|
||||
"19.14.43",
|
||||
"19.15.36",
|
||||
"19.16.39",
|
||||
"19.16.39"
|
||||
// 19.17+ is not supported.
|
||||
]
|
||||
)
|
||||
]
|
||||
@ -55,6 +38,11 @@ object RestoreOldSeekbarThumbnailsPatch : BytecodePatch(
|
||||
"Lapp/revanced/integrations/youtube/patches/RestoreOldSeekbarThumbnailsPatch;"
|
||||
|
||||
override fun execute(context: BytecodeContext) {
|
||||
if (VersionCheckPatch.is_19_17_or_greater) {
|
||||
// Give a more informative error, if the user has turned off version checks.
|
||||
throw PatchException("'Restore old seekbar thumbnails' cannot be patched to any version after 19.16.39")
|
||||
}
|
||||
|
||||
AddResourcesPatch(this::class)
|
||||
|
||||
SettingsPatch.PreferenceScreen.SEEKBAR.addPreferences(
|
||||
|
@ -1,20 +1,26 @@
|
||||
package app.revanced.patches.youtube.layout.seekbar
|
||||
|
||||
import app.revanced.patcher.data.BytecodeContext
|
||||
import app.revanced.patcher.extensions.InstructionExtensions.addInstruction
|
||||
import app.revanced.patcher.extensions.InstructionExtensions.addInstructions
|
||||
import app.revanced.patcher.extensions.InstructionExtensions.getInstruction
|
||||
import app.revanced.patcher.patch.BytecodePatch
|
||||
import app.revanced.patcher.patch.annotation.CompatiblePackage
|
||||
import app.revanced.patcher.patch.annotation.Patch
|
||||
import app.revanced.patcher.util.proxy.mutableTypes.MutableMethod
|
||||
import app.revanced.patches.youtube.layout.seekbar.fingerprints.LithoLinearGradientFingerprint
|
||||
import app.revanced.patches.youtube.layout.seekbar.fingerprints.PlayerSeekbarColorFingerprint
|
||||
import app.revanced.patches.youtube.layout.seekbar.fingerprints.PlayerSeekbarGradientConfigFingerprint
|
||||
import app.revanced.patches.youtube.layout.seekbar.fingerprints.SetSeekbarClickedColorFingerprint
|
||||
import app.revanced.patches.youtube.layout.seekbar.fingerprints.ShortsSeekbarColorFingerprint
|
||||
import app.revanced.patches.youtube.layout.theme.LithoColorHookPatch
|
||||
import app.revanced.patches.youtube.layout.theme.LithoColorHookPatch.lithoColorOverrideHook
|
||||
import app.revanced.patches.youtube.misc.integrations.IntegrationsPatch
|
||||
import app.revanced.util.exception
|
||||
import app.revanced.patches.youtube.misc.playservice.VersionCheckPatch
|
||||
import app.revanced.util.indexOfFirstInstructionOrThrow
|
||||
import app.revanced.util.indexOfFirstWideLiteralInstructionValueOrThrow
|
||||
import app.revanced.util.resultOrThrow
|
||||
import com.android.tools.smali.dexlib2.Opcode
|
||||
import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction
|
||||
import com.android.tools.smali.dexlib2.iface.instruction.TwoRegisterInstruction
|
||||
|
||||
@ -24,7 +30,13 @@ import com.android.tools.smali.dexlib2.iface.instruction.TwoRegisterInstruction
|
||||
compatiblePackages = [CompatiblePackage("com.google.android.youtube")]
|
||||
)
|
||||
internal object SeekbarColorBytecodePatch : BytecodePatch(
|
||||
setOf(PlayerSeekbarColorFingerprint, ShortsSeekbarColorFingerprint, SetSeekbarClickedColorFingerprint)
|
||||
setOf(
|
||||
PlayerSeekbarColorFingerprint,
|
||||
ShortsSeekbarColorFingerprint,
|
||||
SetSeekbarClickedColorFingerprint,
|
||||
PlayerSeekbarGradientConfigFingerprint,
|
||||
LithoLinearGradientFingerprint
|
||||
)
|
||||
) {
|
||||
private const val INTEGRATIONS_CLASS_DESCRIPTOR = "Lapp/revanced/integrations/youtube/patches/theme/SeekbarColorPatch;"
|
||||
|
||||
@ -32,25 +44,26 @@ internal object SeekbarColorBytecodePatch : BytecodePatch(
|
||||
fun MutableMethod.addColorChangeInstructions(resourceId: Long) {
|
||||
val registerIndex = indexOfFirstWideLiteralInstructionValueOrThrow(resourceId) + 2
|
||||
val colorRegister = getInstruction<OneRegisterInstruction>(registerIndex).registerA
|
||||
|
||||
addInstructions(
|
||||
registerIndex + 1,
|
||||
"""
|
||||
invoke-static { v$colorRegister }, $INTEGRATIONS_CLASS_DESCRIPTOR->getVideoPlayerSeekbarColor(I)I
|
||||
move-result v$colorRegister
|
||||
"""
|
||||
invoke-static { v$colorRegister }, $INTEGRATIONS_CLASS_DESCRIPTOR->getVideoPlayerSeekbarColor(I)I
|
||||
move-result v$colorRegister
|
||||
"""
|
||||
)
|
||||
}
|
||||
|
||||
PlayerSeekbarColorFingerprint.result?.mutableMethod?.apply {
|
||||
PlayerSeekbarColorFingerprint.resultOrThrow().mutableMethod.apply {
|
||||
addColorChangeInstructions(SeekbarColorResourcePatch.inlineTimeBarColorizedBarPlayedColorDarkId)
|
||||
addColorChangeInstructions(SeekbarColorResourcePatch.inlineTimeBarPlayedNotHighlightedColorId)
|
||||
} ?: throw PlayerSeekbarColorFingerprint.exception
|
||||
}
|
||||
|
||||
ShortsSeekbarColorFingerprint.result?.mutableMethod?.apply {
|
||||
ShortsSeekbarColorFingerprint.resultOrThrow().mutableMethod.apply {
|
||||
addColorChangeInstructions(SeekbarColorResourcePatch.reelTimeBarPlayedColorId)
|
||||
} ?: throw ShortsSeekbarColorFingerprint.exception
|
||||
}
|
||||
|
||||
SetSeekbarClickedColorFingerprint.result?.let { result ->
|
||||
SetSeekbarClickedColorFingerprint.resultOrThrow().let { result ->
|
||||
result.mutableMethod.let {
|
||||
val setColorMethodIndex = result.scanResult.patternScanResult!!.startIndex + 1
|
||||
val method = context
|
||||
@ -69,7 +82,31 @@ internal object SeekbarColorBytecodePatch : BytecodePatch(
|
||||
)
|
||||
}
|
||||
}
|
||||
} ?: throw SetSeekbarClickedColorFingerprint.exception
|
||||
}
|
||||
|
||||
if (VersionCheckPatch.is_19_23_or_greater) {
|
||||
PlayerSeekbarGradientConfigFingerprint.resultOrThrow().mutableMethod.apply {
|
||||
val literalIndex = indexOfFirstWideLiteralInstructionValueOrThrow(
|
||||
PlayerSeekbarGradientConfigFingerprint.PLAYER_SEEKBAR_GRADIENT_FEATURE_FLAG
|
||||
)
|
||||
val resultIndex = indexOfFirstInstructionOrThrow(literalIndex, Opcode.MOVE_RESULT)
|
||||
val register = getInstruction<OneRegisterInstruction>(resultIndex).registerA
|
||||
|
||||
addInstructions(
|
||||
resultIndex + 1,
|
||||
"""
|
||||
invoke-static { v$register }, $INTEGRATIONS_CLASS_DESCRIPTOR->playerSeekbarGradientEnabled(Z)Z
|
||||
move-result v$register
|
||||
"""
|
||||
)
|
||||
}
|
||||
|
||||
LithoLinearGradientFingerprint.resultOrThrow().mutableMethod.apply {
|
||||
addInstruction(0, "invoke-static/range { p4 .. p5 }, " +
|
||||
"$INTEGRATIONS_CLASS_DESCRIPTOR->setLinearGradient([I[F)V"
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
lithoColorOverrideHook(INTEGRATIONS_CLASS_DESCRIPTOR, "getLithoColor")
|
||||
}
|
||||
|
@ -0,0 +1,10 @@
|
||||
package app.revanced.patches.youtube.layout.seekbar.fingerprints
|
||||
|
||||
import app.revanced.patcher.fingerprint.MethodFingerprint
|
||||
import com.android.tools.smali.dexlib2.AccessFlags
|
||||
|
||||
internal object LithoLinearGradientFingerprint : MethodFingerprint(
|
||||
accessFlags = AccessFlags.STATIC.value,
|
||||
returnType = "Landroid/graphics/LinearGradient;",
|
||||
parameters = listOf("F", "F", "F", "F", "[I", "[F"),
|
||||
)
|
@ -0,0 +1,15 @@
|
||||
package app.revanced.patches.youtube.layout.seekbar.fingerprints
|
||||
|
||||
import app.revanced.patcher.extensions.or
|
||||
import app.revanced.patches.youtube.layout.seekbar.fingerprints.PlayerSeekbarGradientConfigFingerprint.PLAYER_SEEKBAR_GRADIENT_FEATURE_FLAG
|
||||
import app.revanced.util.patch.LiteralValueFingerprint
|
||||
import com.android.tools.smali.dexlib2.AccessFlags
|
||||
|
||||
internal object PlayerSeekbarGradientConfigFingerprint : LiteralValueFingerprint(
|
||||
accessFlags = AccessFlags.PUBLIC or AccessFlags.FINAL,
|
||||
returnType = "Z",
|
||||
parameters = listOf(),
|
||||
literalSupplier = { PLAYER_SEEKBAR_GRADIENT_FEATURE_FLAG },
|
||||
) {
|
||||
const val PLAYER_SEEKBAR_GRADIENT_FEATURE_FLAG = 45617850L
|
||||
}
|
@ -23,13 +23,16 @@ import app.revanced.patches.youtube.shared.fingerprints.SeekbarFingerprint
|
||||
import app.revanced.patches.youtube.shared.fingerprints.SeekbarOnDrawFingerprint
|
||||
import app.revanced.patches.youtube.video.information.VideoInformationPatch
|
||||
import app.revanced.patches.youtube.video.videoid.VideoIdPatch
|
||||
import app.revanced.util.exception
|
||||
import app.revanced.util.alsoResolve
|
||||
import app.revanced.util.getReference
|
||||
import app.revanced.util.indexOfFirstInstructionOrThrow
|
||||
import app.revanced.util.indexOfFirstInstructionReversedOrThrow
|
||||
import app.revanced.util.resultOrThrow
|
||||
import com.android.tools.smali.dexlib2.Opcode
|
||||
import com.android.tools.smali.dexlib2.iface.instruction.FiveRegisterInstruction
|
||||
import com.android.tools.smali.dexlib2.iface.instruction.Instruction
|
||||
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.formats.Instruction35c
|
||||
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.StringReference
|
||||
@ -41,24 +44,11 @@ import com.android.tools.smali.dexlib2.iface.reference.StringReference
|
||||
CompatiblePackage(
|
||||
"com.google.android.youtube",
|
||||
[
|
||||
"18.48.39",
|
||||
"18.38.44",
|
||||
"18.49.37",
|
||||
"19.01.34",
|
||||
"19.02.39",
|
||||
"19.03.36",
|
||||
"19.04.38",
|
||||
"19.05.36",
|
||||
"19.06.39",
|
||||
"19.07.40",
|
||||
"19.08.36",
|
||||
"19.09.38",
|
||||
"19.10.39",
|
||||
"19.11.43",
|
||||
"19.12.41",
|
||||
"19.13.37",
|
||||
"19.14.43",
|
||||
"19.15.36",
|
||||
"19.16.39",
|
||||
"19.25.37",
|
||||
"19.34.42",
|
||||
],
|
||||
),
|
||||
],
|
||||
@ -92,12 +82,6 @@ object SponsorBlockBytecodePatch : BytecodePatch(
|
||||
"Lapp/revanced/integrations/youtube/sponsorblock/ui/SponsorBlockViewController;"
|
||||
|
||||
override fun execute(context: BytecodeContext) {
|
||||
LayoutConstructorFingerprint.result?.let {
|
||||
if (!ControlsOverlayFingerprint.resolve(context, it.classDef)) {
|
||||
throw ControlsOverlayFingerprint.exception
|
||||
}
|
||||
} ?: throw LayoutConstructorFingerprint.exception
|
||||
|
||||
/*
|
||||
* Hook the video time methods
|
||||
*/
|
||||
@ -108,67 +92,46 @@ object SponsorBlockBytecodePatch : BytecodePatch(
|
||||
)
|
||||
}
|
||||
|
||||
/*
|
||||
* Set current video id.
|
||||
*/
|
||||
VideoIdPatch.hookBackgroundPlayVideoId("$INTEGRATIONS_SEGMENT_PLAYBACK_CONTROLLER_CLASS_DESCRIPTOR->setCurrentVideoId(Ljava/lang/String;)V")
|
||||
VideoIdPatch.hookBackgroundPlayVideoId(
|
||||
"$INTEGRATIONS_SEGMENT_PLAYBACK_CONTROLLER_CLASS_DESCRIPTOR->setCurrentVideoId(Ljava/lang/String;)V")
|
||||
|
||||
/*
|
||||
* Seekbar drawing
|
||||
*/
|
||||
val seekbarSignatureResult = SeekbarFingerprint.result!!.let {
|
||||
SeekbarOnDrawFingerprint.apply { resolve(context, it.mutableClass) }
|
||||
}.result!!
|
||||
val seekbarMethod = seekbarSignatureResult.mutableMethod
|
||||
val seekbarMethodInstructions = seekbarMethod.implementation!!.instructions
|
||||
|
||||
/*
|
||||
* Get left and right of seekbar rectangle
|
||||
*/
|
||||
val moveRectangleToRegisterIndex = seekbarMethodInstructions.indexOfFirst {
|
||||
it.opcode == Opcode.MOVE_OBJECT_FROM16
|
||||
}
|
||||
// Seekbar drawing
|
||||
SeekbarOnDrawFingerprint.alsoResolve(context, SeekbarFingerprint).mutableMethod.apply {
|
||||
// Get left and right of seekbar rectangle.
|
||||
val moveRectangleToRegisterIndex = indexOfFirstInstructionOrThrow(Opcode.MOVE_OBJECT_FROM16)
|
||||
|
||||
seekbarMethod.addInstruction(
|
||||
moveRectangleToRegisterIndex + 1,
|
||||
"invoke-static/range {p0 .. p0}, " +
|
||||
"$INTEGRATIONS_SEGMENT_PLAYBACK_CONTROLLER_CLASS_DESCRIPTOR->setSponsorBarRect(Ljava/lang/Object;)V",
|
||||
)
|
||||
|
||||
for ((index, instruction) in seekbarMethodInstructions.withIndex()) {
|
||||
if (instruction.opcode != Opcode.INVOKE_STATIC) continue
|
||||
|
||||
val invokeInstruction = instruction as Instruction35c
|
||||
if ((invokeInstruction.reference as MethodReference).name != "round") continue
|
||||
|
||||
val insertIndex = index + 2
|
||||
|
||||
// set the thickness of the segment
|
||||
seekbarMethod.addInstruction(
|
||||
insertIndex,
|
||||
"invoke-static {v${invokeInstruction.registerC}}, " +
|
||||
"$INTEGRATIONS_SEGMENT_PLAYBACK_CONTROLLER_CLASS_DESCRIPTOR->setSponsorBarThickness(I)V",
|
||||
addInstruction(
|
||||
moveRectangleToRegisterIndex + 1,
|
||||
"invoke-static/range { p0 .. p0 }, " +
|
||||
"$INTEGRATIONS_SEGMENT_PLAYBACK_CONTROLLER_CLASS_DESCRIPTOR->setSponsorBarRect(Ljava/lang/Object;)V",
|
||||
)
|
||||
break
|
||||
}
|
||||
|
||||
/*
|
||||
* Draw segment
|
||||
*/
|
||||
// Find the drawCircle call and draw the segment before it
|
||||
for (i in seekbarMethodInstructions.size - 1 downTo 0) {
|
||||
val invokeInstruction = seekbarMethodInstructions[i] as? ReferenceInstruction ?: continue
|
||||
if ((invokeInstruction.reference as MethodReference).name != "drawCircle") continue
|
||||
|
||||
val (canvasInstance, centerY) = (invokeInstruction as FiveRegisterInstruction).let {
|
||||
it.registerC to it.registerE
|
||||
// Set the thickness of the segment.
|
||||
val thicknessIndex = indexOfFirstInstructionOrThrow {
|
||||
opcode == Opcode.INVOKE_STATIC && getReference<MethodReference>()?.name == "round"
|
||||
}
|
||||
seekbarMethod.addInstruction(
|
||||
i,
|
||||
"invoke-static {v$canvasInstance, v$centerY}, $INTEGRATIONS_SEGMENT_PLAYBACK_CONTROLLER_CLASS_DESCRIPTOR->drawSponsorTimeBars(Landroid/graphics/Canvas;F)V",
|
||||
val thicknessRegister = getInstruction<FiveRegisterInstruction>(thicknessIndex).registerC
|
||||
addInstruction(
|
||||
thicknessIndex + 2,
|
||||
"invoke-static { v$thicknessRegister }, " +
|
||||
"$INTEGRATIONS_SEGMENT_PLAYBACK_CONTROLLER_CLASS_DESCRIPTOR->setSponsorBarThickness(I)V",
|
||||
)
|
||||
|
||||
break
|
||||
// Find the drawCircle call and draw the segment before it.
|
||||
val drawCircleIndex = indexOfFirstInstructionReversedOrThrow {
|
||||
getReference<MethodReference>()?.name == "drawCircle"
|
||||
}
|
||||
val drawCircleInstruction = getInstruction<FiveRegisterInstruction>(drawCircleIndex)
|
||||
val canvasInstanceRegister = drawCircleInstruction.registerC
|
||||
val centerYRegister = drawCircleInstruction.registerE
|
||||
|
||||
addInstruction(
|
||||
drawCircleIndex,
|
||||
"invoke-static { v$canvasInstanceRegister, v$centerYRegister }, " +
|
||||
"$INTEGRATIONS_SEGMENT_PLAYBACK_CONTROLLER_CLASS_DESCRIPTOR->" +
|
||||
"drawSponsorTimeBars(Landroid/graphics/Canvas;F)V",
|
||||
)
|
||||
}
|
||||
|
||||
// Change visibility of the buttons.
|
||||
@ -179,24 +142,26 @@ object SponsorBlockBytecodePatch : BytecodePatch(
|
||||
PlayerControlsBytecodePatch.injectVisibilityCheckCall(INTEGRATIONS_VOTING_BUTTON_CONTROLLER_CLASS_DESCRIPTOR)
|
||||
|
||||
// Append the new time to the player layout.
|
||||
val appendTimeFingerprintResult = AppendTimeFingerprint.result!!
|
||||
val appendTimePatternScanStartIndex = appendTimeFingerprintResult.scanResult.patternScanResult!!.startIndex
|
||||
val targetRegister =
|
||||
(appendTimeFingerprintResult.method.implementation!!.instructions.elementAt(appendTimePatternScanStartIndex + 1) as OneRegisterInstruction).registerA
|
||||
AppendTimeFingerprint.resultOrThrow().let {
|
||||
val appendTimePatternScanStartIndex = it.scanResult.patternScanResult!!.startIndex
|
||||
it.mutableMethod.apply {
|
||||
val register = getInstruction<OneRegisterInstruction>(appendTimePatternScanStartIndex + 1).registerA
|
||||
|
||||
appendTimeFingerprintResult.mutableMethod.addInstructions(
|
||||
appendTimePatternScanStartIndex + 2,
|
||||
"""
|
||||
invoke-static {v$targetRegister}, $INTEGRATIONS_SEGMENT_PLAYBACK_CONTROLLER_CLASS_DESCRIPTOR->appendTimeWithoutSegments(Ljava/lang/String;)Ljava/lang/String;
|
||||
move-result-object v$targetRegister
|
||||
""",
|
||||
)
|
||||
addInstructions(
|
||||
appendTimePatternScanStartIndex + 2,
|
||||
"""
|
||||
invoke-static { v$register }, $INTEGRATIONS_SEGMENT_PLAYBACK_CONTROLLER_CLASS_DESCRIPTOR->appendTimeWithoutSegments(Ljava/lang/String;)Ljava/lang/String;
|
||||
move-result-object v$register
|
||||
"""
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
// initialize the player controller
|
||||
// Initialize the player controller.
|
||||
VideoInformationPatch.onCreateHook(INTEGRATIONS_SEGMENT_PLAYBACK_CONTROLLER_CLASS_DESCRIPTOR, "initialize")
|
||||
|
||||
// initialize the sponsorblock view
|
||||
ControlsOverlayFingerprint.result?.let {
|
||||
// Initialize the SponsorBlock view.
|
||||
ControlsOverlayFingerprint.alsoResolve(context, LayoutConstructorFingerprint).let {
|
||||
val startIndex = it.scanResult.patternScanResult!!.startIndex
|
||||
it.mutableMethod.apply {
|
||||
val frameLayoutRegister = (getInstruction(startIndex + 2) as OneRegisterInstruction).registerA
|
||||
@ -205,53 +170,50 @@ object SponsorBlockBytecodePatch : BytecodePatch(
|
||||
"invoke-static {v$frameLayoutRegister}, $INTEGRATIONS_SPONSORBLOCK_VIEW_CONTROLLER_CLASS_DESCRIPTOR->initialize(Landroid/view/ViewGroup;)V",
|
||||
)
|
||||
}
|
||||
} ?: throw ControlsOverlayFingerprint.exception
|
||||
}
|
||||
|
||||
// get rectangle field name
|
||||
RectangleFieldInvalidatorFingerprint.resolve(context, seekbarSignatureResult.classDef)
|
||||
val rectangleFieldInvalidatorInstructions =
|
||||
RectangleFieldInvalidatorFingerprint.result!!.method.implementation!!.instructions
|
||||
val rectangleFieldName =
|
||||
((rectangleFieldInvalidatorInstructions.elementAt(rectangleFieldInvalidatorInstructions.count() - 3) as ReferenceInstruction).reference as FieldReference).name
|
||||
|
||||
// replace the "replaceMeWith*" strings
|
||||
context
|
||||
.proxy(context.classes.first { it.type.endsWith("SegmentPlaybackController;") })
|
||||
.mutableClass
|
||||
.methods
|
||||
.find { it.name == "setSponsorBarRect" }
|
||||
?.let { method ->
|
||||
fun MutableMethod.replaceStringInstruction(index: Int, instruction: Instruction, with: String) {
|
||||
val register = (instruction as OneRegisterInstruction).registerA
|
||||
this.replaceInstruction(
|
||||
index,
|
||||
"const-string v$register, \"$with\"",
|
||||
)
|
||||
}
|
||||
for ((index, it) in method.implementation!!.instructions.withIndex()) {
|
||||
if (it.opcode.ordinal != Opcode.CONST_STRING.ordinal) continue
|
||||
// Set seekbar draw rectangle.
|
||||
RectangleFieldInvalidatorFingerprint.alsoResolve(context, SeekbarOnDrawFingerprint).mutableMethod.apply {
|
||||
val fieldIndex = implementation!!.instructions.count() - 3
|
||||
val fieldReference = getInstruction<ReferenceInstruction>(fieldIndex).reference as FieldReference
|
||||
|
||||
when (((it as ReferenceInstruction).reference as StringReference).string) {
|
||||
"replaceMeWithsetSponsorBarRect" -> method.replaceStringInstruction(
|
||||
// replace the "replaceMeWith*" strings
|
||||
context
|
||||
.proxy(context.classes.first { it.type.endsWith("SegmentPlaybackController;") })
|
||||
.mutableClass
|
||||
.methods
|
||||
.find { it.name == "setSponsorBarRect" }
|
||||
?.let { method ->
|
||||
fun MutableMethod.replaceStringInstruction(index: Int, instruction: Instruction, with: String) {
|
||||
val register = (instruction as OneRegisterInstruction).registerA
|
||||
this.replaceInstruction(
|
||||
index,
|
||||
it,
|
||||
rectangleFieldName,
|
||||
"const-string v$register, \"$with\"",
|
||||
)
|
||||
}
|
||||
}
|
||||
} ?: throw PatchException("Could not find the method which contains the replaceMeWith* strings")
|
||||
for ((index, it) in method.implementation!!.instructions.withIndex()) {
|
||||
if (it.opcode.ordinal != Opcode.CONST_STRING.ordinal) continue
|
||||
|
||||
when (((it as ReferenceInstruction).reference as StringReference).string) {
|
||||
"replaceMeWithsetSponsorBarRect" -> method.replaceStringInstruction(
|
||||
index,
|
||||
it,
|
||||
fieldReference.name,
|
||||
)
|
||||
}
|
||||
}
|
||||
} ?: throw PatchException("Could not find the method which contains the replaceMeWith* strings")
|
||||
}
|
||||
|
||||
// The vote and create segment buttons automatically change their visibility when appropriate,
|
||||
// but if buttons are showing when the end of the video is reached then they will not automatically hide.
|
||||
// Add a hook to forcefully hide when the end of the video is reached.
|
||||
AutoRepeatParentFingerprint.result ?: throw AutoRepeatParentFingerprint.exception
|
||||
AutoRepeatFingerprint.also {
|
||||
it.resolve(context, AutoRepeatParentFingerprint.result!!.classDef)
|
||||
}.result?.mutableMethod?.addInstruction(
|
||||
AutoRepeatFingerprint.alsoResolve(context, AutoRepeatParentFingerprint).mutableMethod.addInstruction(
|
||||
0,
|
||||
"invoke-static {}, $INTEGRATIONS_SPONSORBLOCK_VIEW_CONTROLLER_CLASS_DESCRIPTOR->endOfVideoReached()V",
|
||||
) ?: throw AutoRepeatFingerprint.exception
|
||||
)
|
||||
|
||||
// TODO: isSBChannelWhitelisting implementation
|
||||
// TODO: isSBChannelWhitelisting implementation?
|
||||
}
|
||||
}
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user