mirror of
https://github.com/revanced/revanced-patches.git
synced 2025-12-09 19:03:55 +01:00
Compare commits
80 Commits
v4.13.0-de
...
v4.15.1-de
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
464e6a3673 | ||
|
|
2e9142eda4 | ||
|
|
b4c6d0a7d2 | ||
|
|
c0ee85e12a | ||
|
|
2d326072e2 | ||
|
|
586770aa3a | ||
|
|
9f314c2425 | ||
|
|
c8b3456738 | ||
|
|
e8cb6ee028 | ||
|
|
3e796eb7c2 | ||
|
|
303d2de81d | ||
|
|
0ab7344295 | ||
|
|
ff8fe46685 | ||
|
|
a104eeaf68 | ||
|
|
18b09168cc | ||
|
|
f7209f0a53 | ||
|
|
1fb3fc4857 | ||
|
|
e03c14cc01 | ||
|
|
bed29d00dc | ||
|
|
d36982e245 | ||
|
|
13031f0534 | ||
|
|
b5b6ef5d6f | ||
|
|
5b1e07d861 | ||
|
|
e3220cc10a | ||
|
|
02db9378ea | ||
|
|
f83e314dff | ||
|
|
d5e383b78a | ||
|
|
395e18d830 | ||
|
|
887684e7c7 | ||
|
|
2f7d751f9f | ||
|
|
4886a95713 | ||
|
|
58719239cf | ||
|
|
fcb68cc65e | ||
|
|
16217f012e | ||
|
|
d6f20ee67d | ||
|
|
bccd62e593 | ||
|
|
1322403698 | ||
|
|
a64270514f | ||
|
|
f5de555adf | ||
|
|
4c2ec2870c | ||
|
|
a73e2458e9 | ||
|
|
96e6f43ca0 | ||
|
|
f667d5a238 | ||
|
|
ff2c4564a0 | ||
|
|
b568207e49 | ||
|
|
70470a9162 | ||
|
|
9922f47a49 | ||
|
|
ed532eb528 | ||
|
|
74f3f82927 | ||
|
|
6544cd5fc6 | ||
|
|
4e323aa206 | ||
|
|
c1cee281ff | ||
|
|
0779f9fc5e | ||
|
|
0ee5cf98ab | ||
|
|
6bb848b991 | ||
|
|
188b66ffe7 | ||
|
|
a276425d83 | ||
|
|
e556c3f692 | ||
|
|
cb30248eab | ||
|
|
c5ce742ab4 | ||
|
|
bdd2f7cb0f | ||
|
|
b7600f448d | ||
|
|
5c4bf7676d | ||
|
|
fcd2f9b4c4 | ||
|
|
aa3487aa92 | ||
|
|
ada642f4a7 | ||
|
|
eac758588a | ||
|
|
5d047eae77 | ||
|
|
ed92bf1be6 | ||
|
|
c6318e890f | ||
|
|
7f3b1c54da | ||
|
|
3d0d94b6c8 | ||
|
|
b84e6afebd | ||
|
|
3eab130276 | ||
|
|
95f8e9b3a9 | ||
|
|
d7be94a193 | ||
|
|
e4e20bec6c | ||
|
|
b8bd63a34c | ||
|
|
8b602ca6be | ||
|
|
87eb83607c |
270
CHANGELOG.md
270
CHANGELOG.md
@@ -1,3 +1,273 @@
|
||||
## [4.15.1-dev.1](https://github.com/ReVanced/revanced-patches/compare/v4.15.0...v4.15.1-dev.1) (2024-09-23)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **Twitter - Open links with app chooser:** Fix incorrect version in compatibility list ([#3683](https://github.com/ReVanced/revanced-patches/issues/3683)) ([adafe85](https://github.com/ReVanced/revanced-patches/commit/adafe85d77f6a0031a5523b9b7da69475959d78d))
|
||||
|
||||
# [4.15.0](https://github.com/ReVanced/revanced-patches/compare/v4.14.1...v4.15.0) (2024-09-23)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **TikTok - Playback speed:** Prevent crash by fixing invalid patch ([82d53cb](https://github.com/ReVanced/revanced-patches/commit/82d53cbc3bbfa585ba4337fdfaec9f0f19c802e6))
|
||||
* **TikTok - Settings:** Prevent crash by fixing invalid patch ([8074032](https://github.com/ReVanced/revanced-patches/commit/8074032fad3eff1c03296a882d2e2820da99b592))
|
||||
* **Twitter - Open links with app chooser:** Constrain patch to last working version `10.48.0-release` ([b9955d5](https://github.com/ReVanced/revanced-patches/commit/b9955d5ff6e456593b01f0f25d80ff660d02082a))
|
||||
* **YouTube - Spoof video streams:** Change default client type to Android VR ([74c8637](https://github.com/ReVanced/revanced-patches/commit/74c8637943347078955f51325bc6af92a35d4463))
|
||||
* **YouTube - Spoof video streams:** Change default client type to Android VR ([#3672](https://github.com/ReVanced/revanced-patches/issues/3672)) ([a3306f6](https://github.com/ReVanced/revanced-patches/commit/a3306f6717a09b734354f00363a96abad0ae14e7))
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* **TikTok:** Bump patches to support the latest version 36.5.4 ([e5dcb72](https://github.com/ReVanced/revanced-patches/commit/e5dcb72597092fb32003f11fdf6f861ede4e7ff3))
|
||||
|
||||
# [4.15.0-dev.1](https://github.com/ReVanced/revanced-patches/compare/v4.14.2-dev.2...v4.15.0-dev.1) (2024-09-22)
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* **TikTok:** Bump patches to support the latest version 36.5.4 ([e5dcb72](https://github.com/ReVanced/revanced-patches/commit/e5dcb72597092fb32003f11fdf6f861ede4e7ff3))
|
||||
|
||||
## [4.14.2-dev.2](https://github.com/ReVanced/revanced-patches/compare/v4.14.2-dev.1...v4.14.2-dev.2) (2024-09-21)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **YouTube - Spoof video streams:** Change default client type to Android VR ([74c8637](https://github.com/ReVanced/revanced-patches/commit/74c8637943347078955f51325bc6af92a35d4463))
|
||||
* **YouTube - Spoof video streams:** Change default client type to Android VR ([#3672](https://github.com/ReVanced/revanced-patches/issues/3672)) ([a3306f6](https://github.com/ReVanced/revanced-patches/commit/a3306f6717a09b734354f00363a96abad0ae14e7))
|
||||
|
||||
## [4.14.2-dev.1](https://github.com/ReVanced/revanced-patches/compare/v4.14.1...v4.14.2-dev.1) (2024-09-21)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **TikTok - Playback speed:** Prevent crash by fixing invalid patch ([82d53cb](https://github.com/ReVanced/revanced-patches/commit/82d53cbc3bbfa585ba4337fdfaec9f0f19c802e6))
|
||||
* **TikTok - Settings:** Prevent crash by fixing invalid patch ([8074032](https://github.com/ReVanced/revanced-patches/commit/8074032fad3eff1c03296a882d2e2820da99b592))
|
||||
* **Twitter - Open links with app chooser:** Constrain patch to last working version `10.48.0-release` ([b9955d5](https://github.com/ReVanced/revanced-patches/commit/b9955d5ff6e456593b01f0f25d80ff660d02082a))
|
||||
|
||||
## [4.14.1](https://github.com/ReVanced/revanced-patches/compare/v4.14.0...v4.14.1) (2024-09-18)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **YouTube - Check environment:** Only use fields available since Android 8 ([#3655](https://github.com/ReVanced/revanced-patches/issues/3655)) ([4413533](https://github.com/ReVanced/revanced-patches/commit/441353306572340131030e1c4fee1ab6acb63cd9))
|
||||
|
||||
## [4.14.1-dev.1](https://github.com/ReVanced/revanced-patches/compare/v4.14.0...v4.14.1-dev.1) (2024-09-18)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **YouTube - Check environment:** Only use fields available since Android 8 ([#3655](https://github.com/ReVanced/revanced-patches/issues/3655)) ([4413533](https://github.com/ReVanced/revanced-patches/commit/441353306572340131030e1c4fee1ab6acb63cd9))
|
||||
|
||||
# [4.14.0](https://github.com/ReVanced/revanced-patches/compare/v4.13.3...v4.14.0) (2024-09-18)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **Pixiv - Hide ads:** Fix for latest version ([#3616](https://github.com/ReVanced/revanced-patches/issues/3616)) ([98956e8](https://github.com/ReVanced/revanced-patches/commit/98956e8f1a41347bb435720bbf984969469a7110))
|
||||
* **Soundcloud - Hide ads:** Support latest version ([#3628](https://github.com/ReVanced/revanced-patches/issues/3628)) ([66e7e33](https://github.com/ReVanced/revanced-patches/commit/66e7e33efce9b702fdfcc2b9803e9da8491c1f08))
|
||||
* **SwissID:** Rename `Remove Google Play Integrity Integrity check` to `Remove Google Play Integrity check` ([#3558](https://github.com/ReVanced/revanced-patches/issues/3558)) ([0f5a771](https://github.com/ReVanced/revanced-patches/commit/0f5a771a5cff5684b4a8fd317f4938fe2cf3cbbe))
|
||||
* **YouTube - ReturnYouTubeDislike:** Show estimated like count for videos with hidden likes ([#3601](https://github.com/ReVanced/revanced-patches/issues/3601)) ([005be82](https://github.com/ReVanced/revanced-patches/commit/005be82d71b2a42387b1b57035930b20f4663794))
|
||||
* **YouTube - SponsorBlock:** Add summary text to 'view my segments' button ([df80b9f](https://github.com/ReVanced/revanced-patches/commit/df80b9f92f0d981b9a40b7756d74f8ccc3dcb1e9))
|
||||
* **YouTube - SponsorBlock:** Handle if the user enters an invalid number into any SB settings ([37b3dd1](https://github.com/ReVanced/revanced-patches/commit/37b3dd1e789f8bb16fa1b9dd582e39c89dbe730c))
|
||||
* **YouTube:** Fix issues related to playback by replace streaming data ([#3582](https://github.com/ReVanced/revanced-patches/issues/3582)) ([dfa94d7](https://github.com/ReVanced/revanced-patches/commit/dfa94d70f65150d6ef24ea6378b8e6a317055186))
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* Add `Change data directory location` patch ([#3602](https://github.com/ReVanced/revanced-patches/issues/3602)) ([5998029](https://github.com/ReVanced/revanced-patches/commit/59980292809cc0626bf49a160eeb05a1523c4eda))
|
||||
* Add `Check environment` patch ([#3610](https://github.com/ReVanced/revanced-patches/issues/3610)) ([fbcbdaf](https://github.com/ReVanced/revanced-patches/commit/fbcbdafa4938a35b5fdec46aae7b250a84b9c139))
|
||||
* **Duolingo:** Add `Disable ads` and `Enable debug menu` patch ([#3422](https://github.com/ReVanced/revanced-patches/issues/3422)) ([d0a8599](https://github.com/ReVanced/revanced-patches/commit/d0a8599f76ce653e5d7c98069ad3c58b9ab9c5eb))
|
||||
* **Sync for Reddit:** Add `Fix /user/ endpoint` patch ([46d11f3](https://github.com/ReVanced/revanced-patches/commit/46d11f3530fcdae9ed08b7e93aac235638a92dff))
|
||||
* **Sync for Reddit:** Rename patch to `Use /user/ endpoint` ([98ead49](https://github.com/ReVanced/revanced-patches/commit/98ead493380932cb105530f4ba992673fd364d82))
|
||||
* **YouTube - Hide Shorts components:** Hide 'Use this sound' button ([#3647](https://github.com/ReVanced/revanced-patches/issues/3647)) ([33fc090](https://github.com/ReVanced/revanced-patches/commit/33fc09061431d4aa457d743c09a0de31ec566df1))
|
||||
* **YouTube - Keyword filter:** Add syntax to match whole keywords and not substrings ([#3592](https://github.com/ReVanced/revanced-patches/issues/3592)) ([f5fb351](https://github.com/ReVanced/revanced-patches/commit/f5fb3512cfafe214ba6a6d25ba0825ae1884a0ff))
|
||||
* **YouTube - Spoof client:** Allow forcing AVC codec with iOS ([#3570](https://github.com/ReVanced/revanced-patches/issues/3570)) ([1a49d1f](https://github.com/ReVanced/revanced-patches/commit/1a49d1f3c2a343d05d0abc07c143add486246fd0))
|
||||
* **YouTube Music:** Make working patches compatible with latest versions ([#3556](https://github.com/ReVanced/revanced-patches/issues/3556)) ([12f6f19](https://github.com/ReVanced/revanced-patches/commit/12f6f1966ad04631451940f7b64d785c3ef481a0))
|
||||
* **YouTube:** Add donation link to settings about screen ([#3626](https://github.com/ReVanced/revanced-patches/issues/3626)) ([0684ab5](https://github.com/ReVanced/revanced-patches/commit/0684ab5f183631de5720352049cfd293daa58eb0))
|
||||
|
||||
# [4.14.0-dev.15](https://github.com/ReVanced/revanced-patches/compare/v4.14.0-dev.14...v4.14.0-dev.15) (2024-09-17)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **YouTube:** Fix issues related to playback by replace streaming data ([#3582](https://github.com/ReVanced/revanced-patches/issues/3582)) ([dfa94d7](https://github.com/ReVanced/revanced-patches/commit/dfa94d70f65150d6ef24ea6378b8e6a317055186))
|
||||
|
||||
# [4.14.0-dev.14](https://github.com/ReVanced/revanced-patches/compare/v4.14.0-dev.13...v4.14.0-dev.14) (2024-09-17)
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* **YouTube Music:** Make working patches compatible with latest versions ([#3556](https://github.com/ReVanced/revanced-patches/issues/3556)) ([12f6f19](https://github.com/ReVanced/revanced-patches/commit/12f6f1966ad04631451940f7b64d785c3ef481a0))
|
||||
|
||||
# [4.14.0-dev.13](https://github.com/ReVanced/revanced-patches/compare/v4.14.0-dev.12...v4.14.0-dev.13) (2024-09-17)
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* **YouTube - Hide Shorts components:** Hide 'Use this sound' button ([#3647](https://github.com/ReVanced/revanced-patches/issues/3647)) ([33fc090](https://github.com/ReVanced/revanced-patches/commit/33fc09061431d4aa457d743c09a0de31ec566df1))
|
||||
|
||||
# [4.14.0-dev.12](https://github.com/ReVanced/revanced-patches/compare/v4.14.0-dev.11...v4.14.0-dev.12) (2024-09-14)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **Soundcloud - Hide ads:** Support latest version ([#3628](https://github.com/ReVanced/revanced-patches/issues/3628)) ([66e7e33](https://github.com/ReVanced/revanced-patches/commit/66e7e33efce9b702fdfcc2b9803e9da8491c1f08))
|
||||
|
||||
# [4.14.0-dev.11](https://github.com/ReVanced/revanced-patches/compare/v4.14.0-dev.10...v4.14.0-dev.11) (2024-09-12)
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* **Sync for Reddit:** Rename patch to `Use /user/ endpoint` ([98ead49](https://github.com/ReVanced/revanced-patches/commit/98ead493380932cb105530f4ba992673fd364d82))
|
||||
|
||||
# [4.14.0-dev.10](https://github.com/ReVanced/revanced-patches/compare/v4.14.0-dev.9...v4.14.0-dev.10) (2024-09-12)
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* **Sync for Reddit:** Add `Fix /user/ endpoint` patch ([46d11f3](https://github.com/ReVanced/revanced-patches/commit/46d11f3530fcdae9ed08b7e93aac235638a92dff))
|
||||
|
||||
# [4.14.0-dev.9](https://github.com/ReVanced/revanced-patches/compare/v4.14.0-dev.8...v4.14.0-dev.9) (2024-09-09)
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* **YouTube:** Add donation link to settings about screen ([#3626](https://github.com/ReVanced/revanced-patches/issues/3626)) ([0684ab5](https://github.com/ReVanced/revanced-patches/commit/0684ab5f183631de5720352049cfd293daa58eb0))
|
||||
|
||||
# [4.14.0-dev.8](https://github.com/ReVanced/revanced-patches/compare/v4.14.0-dev.7...v4.14.0-dev.8) (2024-09-09)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **YouTube - SponsorBlock:** Add summary text to 'view my segments' button ([df80b9f](https://github.com/ReVanced/revanced-patches/commit/df80b9f92f0d981b9a40b7756d74f8ccc3dcb1e9))
|
||||
|
||||
# [4.14.0-dev.7](https://github.com/ReVanced/revanced-patches/compare/v4.14.0-dev.6...v4.14.0-dev.7) (2024-09-06)
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* Add `Check environment` patch ([#3610](https://github.com/ReVanced/revanced-patches/issues/3610)) ([fbcbdaf](https://github.com/ReVanced/revanced-patches/commit/fbcbdafa4938a35b5fdec46aae7b250a84b9c139))
|
||||
|
||||
# [4.14.0-dev.6](https://github.com/ReVanced/revanced-patches/compare/v4.14.0-dev.5...v4.14.0-dev.6) (2024-09-06)
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* Add `Change data directory location` patch ([#3602](https://github.com/ReVanced/revanced-patches/issues/3602)) ([5998029](https://github.com/ReVanced/revanced-patches/commit/59980292809cc0626bf49a160eeb05a1523c4eda))
|
||||
|
||||
# [4.14.0-dev.5](https://github.com/ReVanced/revanced-patches/compare/v4.14.0-dev.4...v4.14.0-dev.5) (2024-09-06)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **Pixiv - Hide ads:** Fix for latest version ([#3616](https://github.com/ReVanced/revanced-patches/issues/3616)) ([98956e8](https://github.com/ReVanced/revanced-patches/commit/98956e8f1a41347bb435720bbf984969469a7110))
|
||||
|
||||
# [4.14.0-dev.4](https://github.com/ReVanced/revanced-patches/compare/v4.14.0-dev.3...v4.14.0-dev.4) (2024-09-01)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **YouTube - ReturnYouTubeDislike:** Show estimated like count for videos with hidden likes ([#3601](https://github.com/ReVanced/revanced-patches/issues/3601)) ([005be82](https://github.com/ReVanced/revanced-patches/commit/005be82d71b2a42387b1b57035930b20f4663794))
|
||||
|
||||
# [4.14.0-dev.3](https://github.com/ReVanced/revanced-patches/compare/v4.14.0-dev.2...v4.14.0-dev.3) (2024-08-30)
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* **YouTube - Keyword filter:** Add syntax to match whole keywords and not substrings ([#3592](https://github.com/ReVanced/revanced-patches/issues/3592)) ([f5fb351](https://github.com/ReVanced/revanced-patches/commit/f5fb3512cfafe214ba6a6d25ba0825ae1884a0ff))
|
||||
|
||||
# [4.14.0-dev.2](https://github.com/ReVanced/revanced-patches/compare/v4.14.0-dev.1...v4.14.0-dev.2) (2024-08-24)
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* **Duolingo:** Add `Disable ads` and `Enable debug menu` patch ([#3422](https://github.com/ReVanced/revanced-patches/issues/3422)) ([d0a8599](https://github.com/ReVanced/revanced-patches/commit/d0a8599f76ce653e5d7c98069ad3c58b9ab9c5eb))
|
||||
|
||||
# [4.14.0-dev.1](https://github.com/ReVanced/revanced-patches/compare/v4.13.4-dev.2...v4.14.0-dev.1) (2024-08-22)
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* **YouTube - Spoof client:** Allow forcing AVC codec with iOS ([#3570](https://github.com/ReVanced/revanced-patches/issues/3570)) ([1a49d1f](https://github.com/ReVanced/revanced-patches/commit/1a49d1f3c2a343d05d0abc07c143add486246fd0))
|
||||
|
||||
## [4.13.4-dev.2](https://github.com/ReVanced/revanced-patches/compare/v4.13.4-dev.1...v4.13.4-dev.2) (2024-08-20)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **YouTube - SponsorBlock:** Handle if the user enters an invalid number into any SB settings ([37b3dd1](https://github.com/ReVanced/revanced-patches/commit/37b3dd1e789f8bb16fa1b9dd582e39c89dbe730c))
|
||||
|
||||
## [4.13.4-dev.1](https://github.com/ReVanced/revanced-patches/compare/v4.13.3...v4.13.4-dev.1) (2024-08-18)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **SwissID:** Rename `Remove Google Play Integrity Integrity check` to `Remove Google Play Integrity check` ([#3558](https://github.com/ReVanced/revanced-patches/issues/3558)) ([0f5a771](https://github.com/ReVanced/revanced-patches/commit/0f5a771a5cff5684b4a8fd317f4938fe2cf3cbbe))
|
||||
|
||||
## [4.13.3](https://github.com/ReVanced/revanced-patches/compare/v4.13.2...v4.13.3) (2024-08-15)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **YouTube:** Remove translated string that breaks patching ([a48c2db](https://github.com/ReVanced/revanced-patches/commit/a48c2db53d84767c8fd5d569f9ce1c46c2bfd9a1))
|
||||
|
||||
## [4.13.3-dev.1](https://github.com/ReVanced/revanced-patches/compare/v4.13.2...v4.13.3-dev.1) (2024-08-15)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **YouTube:** Remove translated string that breaks patching ([a48c2db](https://github.com/ReVanced/revanced-patches/commit/a48c2db53d84767c8fd5d569f9ce1c46c2bfd9a1))
|
||||
|
||||
## [4.13.2](https://github.com/ReVanced/revanced-patches/compare/v4.13.1...v4.13.2) (2024-08-15)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **YouTube - GmsCore Support:** Fix patch exception by using correct patch offset ([#3543](https://github.com/ReVanced/revanced-patches/issues/3543)) ([b2b8454](https://github.com/ReVanced/revanced-patches/commit/b2b8454aa992bcb217fb03eb4de5532e0a9bd354))
|
||||
|
||||
## [4.13.2-dev.1](https://github.com/ReVanced/revanced-patches/compare/v4.13.1...v4.13.2-dev.1) (2024-08-15)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **YouTube - GmsCore Support:** Fix patch exception by using correct patch offset ([#3543](https://github.com/ReVanced/revanced-patches/issues/3543)) ([b2b8454](https://github.com/ReVanced/revanced-patches/commit/b2b8454aa992bcb217fb03eb4de5532e0a9bd354))
|
||||
|
||||
## [4.13.1](https://github.com/ReVanced/revanced-patches/compare/v4.13.0...v4.13.1) (2024-08-15)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **YouTube - Check watch history domain name resolution:** Add compatibility field ([6c598f0](https://github.com/ReVanced/revanced-patches/commit/6c598f084ed90ee1318e4c66d8c1751c797b8e3b))
|
||||
|
||||
## [4.13.1-dev.1](https://github.com/ReVanced/revanced-patches/compare/v4.13.0...v4.13.1-dev.1) (2024-08-15)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **YouTube - Check watch history domain name resolution:** Add compatibility field ([6c598f0](https://github.com/ReVanced/revanced-patches/commit/6c598f084ed90ee1318e4c66d8c1751c797b8e3b))
|
||||
|
||||
# [4.13.0](https://github.com/ReVanced/revanced-patches/compare/v4.12.0...v4.13.0) (2024-08-15)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **YouTube - GmsCore support:** Fix notifications not working by using the correct permissions ([19ddae2](https://github.com/ReVanced/revanced-patches/commit/19ddae2d15e513e18eb1556c468cd94bd197685b))
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* **Google Photos:** Add `Spoof features` patch ([#3459](https://github.com/ReVanced/revanced-patches/issues/3459)) ([7c218cd](https://github.com/ReVanced/revanced-patches/commit/7c218cd168aa72eb99bcb47d12dfa45616e8ad88))
|
||||
* **SCB Easy:** Remove broken `Remove debugging detection` patch ([#3518](https://github.com/ReVanced/revanced-patches/issues/3518)) ([f4e23cb](https://github.com/ReVanced/revanced-patches/commit/f4e23cbb8a24638318d8cee20a1991c51855d9d2))
|
||||
* **YouTube:** Add `Check watch history domain name resolution` patch ([#3537](https://github.com/ReVanced/revanced-patches/issues/3537)) ([2af1425](https://github.com/ReVanced/revanced-patches/commit/2af142525cda07a131335faadd4b3889979fd077))
|
||||
|
||||
# [4.13.0-dev.2](https://github.com/ReVanced/revanced-patches/compare/v4.13.0-dev.1...v4.13.0-dev.2) (2024-08-15)
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* **YouTube:** Add `Check watch history domain name resolution` patch ([#3537](https://github.com/ReVanced/revanced-patches/issues/3537)) ([2af1425](https://github.com/ReVanced/revanced-patches/commit/2af142525cda07a131335faadd4b3889979fd077))
|
||||
|
||||
# [4.13.0-dev.1](https://github.com/ReVanced/revanced-patches/compare/v4.12.1-dev.1...v4.13.0-dev.1) (2024-08-15)
|
||||
|
||||
|
||||
|
||||
@@ -16,6 +16,14 @@ public final class app/revanced/patches/all/connectivity/wifi/spoof/SpoofWifiPat
|
||||
public fun transform (Lapp/revanced/patcher/util/proxy/mutableTypes/MutableMethod;Lkotlin/Triple;)V
|
||||
}
|
||||
|
||||
public final class app/revanced/patches/all/directory/ChangeDataDirectoryLocationPatch : app/revanced/patches/all/misc/transformation/BaseTransformInstructionsPatch {
|
||||
public static final field INSTANCE Lapp/revanced/patches/all/directory/ChangeDataDirectoryLocationPatch;
|
||||
public fun filterMap (Lcom/android/tools/smali/dexlib2/iface/ClassDef;Lcom/android/tools/smali/dexlib2/iface/Method;Lcom/android/tools/smali/dexlib2/iface/instruction/Instruction;I)Ljava/lang/Integer;
|
||||
public synthetic fun filterMap (Lcom/android/tools/smali/dexlib2/iface/ClassDef;Lcom/android/tools/smali/dexlib2/iface/Method;Lcom/android/tools/smali/dexlib2/iface/instruction/Instruction;I)Ljava/lang/Object;
|
||||
public fun transform (Lapp/revanced/patcher/util/proxy/mutableTypes/MutableMethod;I)V
|
||||
public synthetic fun transform (Lapp/revanced/patcher/util/proxy/mutableTypes/MutableMethod;Ljava/lang/Object;)V
|
||||
}
|
||||
|
||||
public final class app/revanced/patches/all/interaction/gestures/PredictiveBackGesturePatch : app/revanced/patcher/patch/ResourcePatch {
|
||||
public static final field INSTANCE Lapp/revanced/patches/all/interaction/gestures/PredictiveBackGesturePatch;
|
||||
public synthetic fun execute (Lapp/revanced/patcher/data/Context;)V
|
||||
@@ -243,6 +251,18 @@ public final class app/revanced/patches/cieid/restrictions/root/BypassRootChecks
|
||||
public synthetic fun execute (Lapp/revanced/patcher/data/Context;)V
|
||||
}
|
||||
|
||||
public final class app/revanced/patches/duolingo/ad/DisableAdsPatch : app/revanced/patcher/patch/BytecodePatch {
|
||||
public static final field INSTANCE Lapp/revanced/patches/duolingo/ad/DisableAdsPatch;
|
||||
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/duolingo/debug/EnableDebugMenuPatch : app/revanced/patcher/patch/BytecodePatch {
|
||||
public static final field INSTANCE Lapp/revanced/patches/duolingo/debug/EnableDebugMenuPatch;
|
||||
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
|
||||
@@ -808,6 +828,12 @@ public final class app/revanced/patches/reddit/customclients/syncforreddit/fix/s
|
||||
public static final field INSTANCE Lapp/revanced/patches/reddit/customclients/syncforreddit/fix/slink/FixSLinksPatch;
|
||||
}
|
||||
|
||||
public final class app/revanced/patches/reddit/customclients/syncforreddit/fix/user/UseUserEndpointPatch : app/revanced/patcher/patch/BytecodePatch {
|
||||
public static final field INSTANCE Lapp/revanced/patches/reddit/customclients/syncforreddit/fix/user/UseUserEndpointPatch;
|
||||
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;
|
||||
}
|
||||
@@ -842,6 +868,12 @@ public final class app/revanced/patches/serviceportalbund/detection/root/RootDet
|
||||
public synthetic fun execute (Lapp/revanced/patcher/data/Context;)V
|
||||
}
|
||||
|
||||
public abstract class app/revanced/patches/shared/misc/checks/BaseCheckEnvironmentPatch : app/revanced/patcher/patch/BytecodePatch {
|
||||
public fun <init> (Lapp/revanced/patcher/fingerprint/MethodFingerprint;Ljava/util/Set;Lapp/revanced/patches/shared/misc/integrations/BaseIntegrationsPatch;)V
|
||||
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/shared/misc/fix/verticalscroll/VerticalScrollPatch : app/revanced/patcher/patch/BytecodePatch {
|
||||
public static final field INSTANCE Lapp/revanced/patches/shared/misc/fix/verticalscroll/VerticalScrollPatch;
|
||||
public fun execute (Lapp/revanced/patcher/data/BytecodeContext;)V
|
||||
@@ -1850,6 +1882,10 @@ public final class app/revanced/patches/youtube/misc/backgroundplayback/Backgrou
|
||||
public synthetic fun execute (Lapp/revanced/patcher/data/Context;)V
|
||||
}
|
||||
|
||||
public final class app/revanced/patches/youtube/misc/check/CheckEnvironmentPatch : app/revanced/patches/shared/misc/checks/BaseCheckEnvironmentPatch {
|
||||
public static final field INSTANCE Lapp/revanced/patches/youtube/misc/check/CheckEnvironmentPatch;
|
||||
}
|
||||
|
||||
public final class app/revanced/patches/youtube/misc/debugging/DebuggingPatch : app/revanced/patcher/patch/ResourcePatch {
|
||||
public static final field INSTANCE Lapp/revanced/patches/youtube/misc/debugging/DebuggingPatch;
|
||||
public synthetic fun execute (Lapp/revanced/patcher/data/Context;)V
|
||||
@@ -1880,6 +1916,12 @@ public final class app/revanced/patches/youtube/misc/fix/playback/SpoofSignature
|
||||
public fun execute (Lapp/revanced/patcher/data/ResourceContext;)V
|
||||
}
|
||||
|
||||
public final class app/revanced/patches/youtube/misc/fix/playback/SpoofVideoStreamsPatch : app/revanced/patcher/patch/BytecodePatch {
|
||||
public static final field INSTANCE Lapp/revanced/patches/youtube/misc/fix/playback/SpoofVideoStreamsPatch;
|
||||
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/youtube/misc/fix/playback/UserAgentClientSpoofPatch : app/revanced/patches/all/misc/transformation/BaseTransformInstructionsPatch {
|
||||
public static final field INSTANCE Lapp/revanced/patches/youtube/misc/fix/playback/UserAgentClientSpoofPatch;
|
||||
public synthetic fun filterMap (Lcom/android/tools/smali/dexlib2/iface/ClassDef;Lcom/android/tools/smali/dexlib2/iface/Method;Lcom/android/tools/smali/dexlib2/iface/instruction/Instruction;I)Ljava/lang/Object;
|
||||
|
||||
@@ -31,6 +31,8 @@ dependencies {
|
||||
implementation(libs.guava)
|
||||
// Used in JsonGenerator.
|
||||
implementation(libs.gson)
|
||||
// Android API stubs defined here.
|
||||
compileOnly(project(":stub"))
|
||||
}
|
||||
|
||||
kotlin {
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
org.gradle.parallel = true
|
||||
org.gradle.caching = true
|
||||
kotlin.code.style = official
|
||||
version = 4.13.0-dev.1
|
||||
version = 4.15.1-dev.1
|
||||
|
||||
File diff suppressed because one or more lines are too long
@@ -5,3 +5,5 @@ buildCache {
|
||||
isEnabled = "CI" !in System.getenv()
|
||||
}
|
||||
}
|
||||
|
||||
include(":stub")
|
||||
|
||||
@@ -0,0 +1,73 @@
|
||||
package app.revanced.patches.all.directory
|
||||
|
||||
import app.revanced.patcher.extensions.InstructionExtensions.getInstruction
|
||||
import app.revanced.patcher.extensions.InstructionExtensions.replaceInstruction
|
||||
import app.revanced.patcher.patch.annotation.Patch
|
||||
import app.revanced.patcher.util.proxy.mutableTypes.MutableMethod
|
||||
import app.revanced.patches.all.misc.transformation.BaseTransformInstructionsPatch
|
||||
import app.revanced.util.getReference
|
||||
import com.android.tools.smali.dexlib2.iface.ClassDef
|
||||
import com.android.tools.smali.dexlib2.iface.Method
|
||||
import com.android.tools.smali.dexlib2.iface.instruction.Instruction
|
||||
import com.android.tools.smali.dexlib2.iface.instruction.formats.Instruction35c
|
||||
import com.android.tools.smali.dexlib2.iface.reference.MethodReference
|
||||
import com.android.tools.smali.dexlib2.immutable.reference.ImmutableMethodReference
|
||||
import com.android.tools.smali.dexlib2.util.MethodUtil
|
||||
|
||||
@Patch(
|
||||
name = "Change data directory location",
|
||||
description = "Changes the data directory in the application from " +
|
||||
"the app internal storage directory to /sdcard/android/data accessible by root-less devices." +
|
||||
"Using this patch can cause unexpected issues with some apps.",
|
||||
use = false,
|
||||
)
|
||||
@Suppress("unused")
|
||||
object ChangeDataDirectoryLocationPatch : BaseTransformInstructionsPatch<Int>() {
|
||||
override fun filterMap(
|
||||
classDef: ClassDef,
|
||||
method: Method,
|
||||
instruction: Instruction,
|
||||
instructionIndex: Int,
|
||||
): Int? {
|
||||
val reference = instruction.getReference<MethodReference>() ?: return null
|
||||
|
||||
if (!MethodUtil.methodSignaturesMatch(reference, MethodCall.GetDir.reference)) {
|
||||
return null
|
||||
}
|
||||
|
||||
return instructionIndex
|
||||
}
|
||||
|
||||
override fun transform(
|
||||
mutableMethod: MutableMethod,
|
||||
entry: Int,
|
||||
) = transformMethodCall(entry, mutableMethod)
|
||||
|
||||
private fun transformMethodCall(
|
||||
instructionIndex: Int,
|
||||
mutableMethod: MutableMethod,
|
||||
) {
|
||||
val getDirInstruction = mutableMethod.getInstruction<Instruction35c>(instructionIndex)
|
||||
val contextRegister = getDirInstruction.registerC
|
||||
val dataRegister = getDirInstruction.registerD
|
||||
|
||||
mutableMethod.replaceInstruction(
|
||||
instructionIndex,
|
||||
"invoke-virtual { v$contextRegister, v$dataRegister }, " +
|
||||
"Landroid/content/Context;->getExternalFilesDir(Ljava/lang/String;)Ljava/io/File;",
|
||||
)
|
||||
}
|
||||
|
||||
private enum class MethodCall(
|
||||
val reference: MethodReference,
|
||||
) {
|
||||
GetDir(
|
||||
ImmutableMethodReference(
|
||||
"Landroid/content/Context;",
|
||||
"getDir",
|
||||
listOf("Ljava/lang/String;", "I"),
|
||||
"Ljava/io/File;",
|
||||
),
|
||||
),
|
||||
}
|
||||
}
|
||||
@@ -83,8 +83,9 @@ object AddResourcesPatch : ResourcePatch(), MutableMap<Value, MutableSet<BaseRes
|
||||
"eu-rES" to "eu",
|
||||
"fa-rIR" to "fa",
|
||||
"fi-rFI" to "fi",
|
||||
"tl-rPH" to "tl",
|
||||
"fil-rPH" to "tl",
|
||||
"fr-rFR" to "fr",
|
||||
"ga-rIE" to "ga",
|
||||
"gl-rES" to "gl",
|
||||
"gu-rIN" to "gu",
|
||||
"hi-rIN" to "hi",
|
||||
@@ -139,7 +140,6 @@ object AddResourcesPatch : ResourcePatch(), MutableMap<Value, MutableSet<BaseRes
|
||||
"uz-rUZ" to "uz",
|
||||
"vi-rVN" to "vi",
|
||||
"zh-rCN" to "zh-rCN",
|
||||
"zh-rHK" to "zh-rHK",
|
||||
"zh-rTW" to "zh-rTW",
|
||||
"zu-rZA" to "zu",
|
||||
)
|
||||
|
||||
@@ -0,0 +1,41 @@
|
||||
package app.revanced.patches.duolingo.ad
|
||||
|
||||
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.duolingo.ad.fingerprints.InitializeMonetizationDebugSettingsFingerprint
|
||||
import app.revanced.util.resultOrThrow
|
||||
import com.android.tools.smali.dexlib2.iface.instruction.TwoRegisterInstruction
|
||||
|
||||
@Patch(
|
||||
name = "Disable ads",
|
||||
compatiblePackages = [CompatiblePackage("com.duolingo")]
|
||||
)
|
||||
@Suppress("unused")
|
||||
object DisableAdsPatch : BytecodePatch(
|
||||
setOf(InitializeMonetizationDebugSettingsFingerprint)
|
||||
) {
|
||||
override fun execute(context: BytecodeContext) {
|
||||
// Couple approaches to remove ads exist:
|
||||
//
|
||||
// MonetizationDebugSettings has a boolean value for "disableAds".
|
||||
// OnboardingState has a getter to check if the user has any "adFreeSessions".
|
||||
// SharedPreferences has a debug boolean value with key "disable_ads", which maps to "DebugCategory.DISABLE_ADS".
|
||||
//
|
||||
// MonetizationDebugSettings seems to be the most general setting to work fine.
|
||||
InitializeMonetizationDebugSettingsFingerprint.resultOrThrow().let {
|
||||
it.mutableMethod.apply {
|
||||
val insertIndex = it.scanResult.patternScanResult!!.startIndex
|
||||
val register = getInstruction<TwoRegisterInstruction>(insertIndex).registerA
|
||||
|
||||
addInstructions(
|
||||
insertIndex,
|
||||
"const/4 v$register, 0x1"
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
package app.revanced.patches.duolingo.ad.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 InitializeMonetizationDebugSettingsFingerprint : MethodFingerprint(
|
||||
returnType = "V",
|
||||
accessFlags = AccessFlags.PUBLIC or AccessFlags.CONSTRUCTOR,
|
||||
parameters = listOf(
|
||||
"Z", // disableAds
|
||||
"Z", // useDebugBilling
|
||||
"Z", // showManageSubscriptions
|
||||
"Z", // alwaysShowSuperAds
|
||||
"Lcom/duolingo/debug/FamilyQuestOverride;",
|
||||
),
|
||||
opcodes = listOf(
|
||||
Opcode.IPUT_BOOLEAN
|
||||
)
|
||||
)
|
||||
@@ -0,0 +1,35 @@
|
||||
package app.revanced.patches.duolingo.debug
|
||||
|
||||
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.duolingo.debug.fingerprints.InitializeBuildConfigProviderFingerprint
|
||||
import app.revanced.util.resultOrThrow
|
||||
import com.android.tools.smali.dexlib2.iface.instruction.TwoRegisterInstruction
|
||||
|
||||
@Patch(
|
||||
name = "Enable debug menu",
|
||||
compatiblePackages = [CompatiblePackage("com.duolingo", ["5.158.4"])],
|
||||
use = false
|
||||
)
|
||||
@Suppress("unused")
|
||||
object EnableDebugMenuPatch : BytecodePatch(
|
||||
setOf(InitializeBuildConfigProviderFingerprint)
|
||||
) {
|
||||
override fun execute(context: BytecodeContext) {
|
||||
InitializeBuildConfigProviderFingerprint.resultOrThrow().let {
|
||||
it.mutableMethod.apply {
|
||||
val insertIndex = it.scanResult.patternScanResult!!.startIndex
|
||||
val register = getInstruction<TwoRegisterInstruction>(insertIndex).registerA
|
||||
|
||||
addInstructions(
|
||||
insertIndex,
|
||||
"const/4 v$register, 0x1"
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
package app.revanced.patches.duolingo.debug.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
|
||||
|
||||
/**
|
||||
* The `BuildConfigProvider` class has two booleans:
|
||||
*
|
||||
* - `isChina`: (usually) compares "play" with "china"...except for builds in China
|
||||
* - `isDebug`: compares "release" with "debug" <-- we want to force this to `true`
|
||||
*/
|
||||
internal object InitializeBuildConfigProviderFingerprint : MethodFingerprint(
|
||||
returnType = "V",
|
||||
accessFlags = AccessFlags.PUBLIC or AccessFlags.CONSTRUCTOR,
|
||||
strings = listOf(
|
||||
"debug",
|
||||
"release",
|
||||
"china",
|
||||
),
|
||||
opcodes = listOf(
|
||||
Opcode.IPUT_BOOLEAN
|
||||
)
|
||||
)
|
||||
@@ -10,7 +10,7 @@ import app.revanced.util.exception
|
||||
|
||||
@Patch(
|
||||
name = "Hide ads",
|
||||
description = "Hides ads in stories, discover, profile, etc." +
|
||||
description = "Hides ads in stories, discover, profile, etc. " +
|
||||
"An ad can still appear once when refreshing the home feed.",
|
||||
compatiblePackages = [CompatiblePackage("com.instagram.android")],
|
||||
)
|
||||
|
||||
@@ -13,16 +13,7 @@ import app.revanced.util.exception
|
||||
name = "Hide video ads",
|
||||
description = "Hides ads that appear while listening to or streaming music videos, podcasts, or songs.",
|
||||
compatiblePackages = [
|
||||
CompatiblePackage(
|
||||
"com.google.android.apps.youtube.music",
|
||||
[
|
||||
"6.45.54",
|
||||
"6.51.53",
|
||||
"7.01.53",
|
||||
"7.02.52",
|
||||
"7.03.52",
|
||||
]
|
||||
)
|
||||
CompatiblePackage("com.google.android.apps.youtube.music")
|
||||
],
|
||||
)
|
||||
@Suppress("unused")
|
||||
|
||||
@@ -12,16 +12,7 @@ import com.android.tools.smali.dexlib2.Opcode
|
||||
@Patch(
|
||||
description = "Adds more audio codec options. The new audio codecs usually result in better audio quality.",
|
||||
compatiblePackages = [
|
||||
CompatiblePackage(
|
||||
"com.google.android.apps.youtube.music",
|
||||
[
|
||||
"6.45.54",
|
||||
"6.51.53",
|
||||
"7.01.53",
|
||||
"7.02.52",
|
||||
"7.03.52",
|
||||
]
|
||||
)
|
||||
CompatiblePackage("com.google.android.apps.youtube.music")
|
||||
]
|
||||
)
|
||||
@Deprecated("This patch is no longer needed as the feature is now enabled by default.")
|
||||
|
||||
@@ -12,16 +12,7 @@ import app.revanced.util.exception
|
||||
name = "Enable exclusive audio playback",
|
||||
description = "Enables the option to play audio without video.",
|
||||
compatiblePackages = [
|
||||
CompatiblePackage(
|
||||
"com.google.android.apps.youtube.music",
|
||||
[
|
||||
"6.45.54",
|
||||
"6.51.53",
|
||||
"7.01.53",
|
||||
"7.02.52",
|
||||
"7.03.52",
|
||||
]
|
||||
)
|
||||
CompatiblePackage("com.google.android.apps.youtube.music")
|
||||
]
|
||||
)
|
||||
@Suppress("unused")
|
||||
|
||||
@@ -14,16 +14,7 @@ import app.revanced.patches.music.interaction.permanentrepeat.fingerprints.Repea
|
||||
name = "Permanent repeat",
|
||||
description = "Permanently remember your repeating preference even if the playlist ends or another track is played.",
|
||||
compatiblePackages = [
|
||||
CompatiblePackage(
|
||||
"com.google.android.apps.youtube.music",
|
||||
[
|
||||
"6.45.54",
|
||||
"6.51.53",
|
||||
"7.01.53",
|
||||
"7.02.52",
|
||||
"7.03.52",
|
||||
]
|
||||
)
|
||||
CompatiblePackage("com.google.android.apps.youtube.music")
|
||||
],
|
||||
use = false
|
||||
)
|
||||
|
||||
@@ -14,16 +14,7 @@ import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction
|
||||
name = "Hide category bar",
|
||||
description = "Hides the category bar at the top of the homepage.",
|
||||
compatiblePackages = [
|
||||
CompatiblePackage(
|
||||
"com.google.android.apps.youtube.music",
|
||||
[
|
||||
"6.45.54",
|
||||
"6.51.53",
|
||||
"7.01.53",
|
||||
"7.02.52",
|
||||
"7.03.52",
|
||||
]
|
||||
)
|
||||
CompatiblePackage("com.google.android.apps.youtube.music")
|
||||
],
|
||||
use = false,
|
||||
)
|
||||
|
||||
@@ -17,16 +17,7 @@ import com.android.tools.smali.dexlib2.iface.instruction.FiveRegisterInstruction
|
||||
name = "Hide 'Get Music Premium' label",
|
||||
description = "Hides the \"Get Music Premium\" label from the account menu and settings.",
|
||||
compatiblePackages = [
|
||||
CompatiblePackage(
|
||||
"com.google.android.apps.youtube.music",
|
||||
[
|
||||
"6.45.54",
|
||||
"6.51.53",
|
||||
"7.01.53",
|
||||
"7.02.52",
|
||||
"7.03.52",
|
||||
]
|
||||
)
|
||||
CompatiblePackage("com.google.android.apps.youtube.music")
|
||||
]
|
||||
)
|
||||
@Suppress("unused")
|
||||
|
||||
@@ -23,16 +23,7 @@ import com.android.tools.smali.dexlib2.iface.reference.FieldReference
|
||||
name = "Remove upgrade button",
|
||||
description = "Removes the upgrade tab from the pivot bar.",
|
||||
compatiblePackages = [
|
||||
CompatiblePackage(
|
||||
"com.google.android.apps.youtube.music",
|
||||
[
|
||||
"6.45.54",
|
||||
"6.51.53",
|
||||
"7.01.53",
|
||||
"7.02.52",
|
||||
"7.03.52",
|
||||
]
|
||||
)
|
||||
CompatiblePackage("com.google.android.apps.youtube.music")
|
||||
]
|
||||
)
|
||||
@Suppress("unused")
|
||||
|
||||
@@ -13,16 +13,7 @@ import app.revanced.patches.music.misc.androidauto.fingerprints.CheckCertificate
|
||||
name = "Bypass certificate checks",
|
||||
description = "Bypasses certificate checks which prevent YouTube Music from working on Android Auto.",
|
||||
compatiblePackages = [
|
||||
CompatiblePackage(
|
||||
"com.google.android.apps.youtube.music",
|
||||
[
|
||||
"6.45.54",
|
||||
"6.51.53",
|
||||
"7.01.53",
|
||||
"7.02.52",
|
||||
"7.03.52",
|
||||
]
|
||||
)
|
||||
CompatiblePackage("com.google.android.apps.youtube.music")
|
||||
]
|
||||
)
|
||||
@Suppress("unused")
|
||||
|
||||
@@ -14,16 +14,7 @@ import app.revanced.util.resultOrThrow
|
||||
name = "Remove background playback restrictions",
|
||||
description = "Removes restrictions on background playback, including playing kids videos in the background.",
|
||||
compatiblePackages = [
|
||||
CompatiblePackage(
|
||||
"com.google.android.apps.youtube.music",
|
||||
[
|
||||
"6.45.54",
|
||||
"6.51.53",
|
||||
"7.01.53",
|
||||
"7.02.52",
|
||||
"7.03.52",
|
||||
]
|
||||
)
|
||||
CompatiblePackage("com.google.android.apps.youtube.music")
|
||||
]
|
||||
)
|
||||
@Suppress("unused")
|
||||
|
||||
@@ -23,16 +23,7 @@ object GmsCoreSupportPatch : BaseGmsCoreSupportPatch(
|
||||
integrationsPatchDependency = IntegrationsPatch::class,
|
||||
gmsCoreSupportResourcePatch = GmsCoreSupportResourcePatch,
|
||||
compatiblePackages = setOf(
|
||||
CompatiblePackage(
|
||||
"com.google.android.apps.youtube.music",
|
||||
setOf(
|
||||
"6.45.54",
|
||||
"6.51.53",
|
||||
"7.01.53",
|
||||
"7.02.52",
|
||||
"7.03.52",
|
||||
),
|
||||
),
|
||||
CompatiblePackage("com.google.android.apps.youtube.music"),
|
||||
),
|
||||
fingerprints = setOf(
|
||||
CastDynamiteModuleV2Fingerprint,
|
||||
|
||||
@@ -11,7 +11,7 @@ import app.revanced.util.exception
|
||||
|
||||
@Patch(
|
||||
name = "Spoof Android device ID",
|
||||
description = "Spoofs the Android device ID used by the app for account authentication." +
|
||||
description = "Spoofs the Android device ID used by the app for account authentication. " +
|
||||
"This can be used to copy the account to another device.",
|
||||
compatiblePackages = [
|
||||
CompatiblePackage(
|
||||
|
||||
@@ -1,28 +1,25 @@
|
||||
package app.revanced.patches.pixiv.ads
|
||||
|
||||
import app.revanced.util.exception
|
||||
import app.revanced.patcher.data.BytecodeContext
|
||||
import app.revanced.patcher.extensions.InstructionExtensions.addInstructions
|
||||
import app.revanced.patcher.patch.BytecodePatch
|
||||
import app.revanced.patcher.patch.annotation.CompatiblePackage
|
||||
import app.revanced.patcher.patch.annotation.Patch
|
||||
import app.revanced.patches.pixiv.ads.fingerprints.IsNotPremiumFingerprint
|
||||
import app.revanced.patches.pixiv.ads.fingerprints.ShouldShowAdsFingerprint
|
||||
import app.revanced.util.exception
|
||||
|
||||
@Patch(
|
||||
name = "Hide ads",
|
||||
compatiblePackages = [CompatiblePackage("jp.pxv.android")]
|
||||
compatiblePackages = [CompatiblePackage("jp.pxv.android")],
|
||||
)
|
||||
@Suppress("unused")
|
||||
object HideAdsPatch : BytecodePatch(setOf(IsNotPremiumFingerprint)) {
|
||||
// Always return false in the "isNotPremium" method which normally returns !this.accountManager.isPremium.
|
||||
// However, this is not the method that controls the user's premium status.
|
||||
// Instead, this method is used to determine whether ads should be shown.
|
||||
object HideAdsPatch : BytecodePatch(setOf(ShouldShowAdsFingerprint)) {
|
||||
override fun execute(context: BytecodeContext) =
|
||||
IsNotPremiumFingerprint.result?.mutableClass?.virtualMethods?.first()?.addInstructions(
|
||||
ShouldShowAdsFingerprint.result?.mutableMethod?.addInstructions(
|
||||
0,
|
||||
"""
|
||||
const/4 v0, 0x0
|
||||
return v0
|
||||
"""
|
||||
) ?: throw IsNotPremiumFingerprint.exception
|
||||
}
|
||||
""",
|
||||
) ?: throw ShouldShowAdsFingerprint.exception
|
||||
}
|
||||
|
||||
@@ -1,21 +0,0 @@
|
||||
package app.revanced.patches.pixiv.ads.fingerprints
|
||||
|
||||
import app.revanced.patcher.extensions.or
|
||||
import app.revanced.patcher.fingerprint.MethodFingerprint
|
||||
import com.android.tools.smali.dexlib2.AccessFlags
|
||||
|
||||
|
||||
internal object IsNotPremiumFingerprint : MethodFingerprint(
|
||||
"V",
|
||||
AccessFlags.PUBLIC or AccessFlags.CONSTRUCTOR,
|
||||
listOf("L"),
|
||||
strings = listOf("pixivAccountManager"),
|
||||
customFingerprint = custom@{ _, classDef ->
|
||||
// The "isNotPremium" method is the only method in the class.
|
||||
if (classDef.virtualMethods.count() != 1) return@custom false
|
||||
|
||||
classDef.virtualMethods.first().let { isNotPremiumMethod ->
|
||||
isNotPremiumMethod.parameterTypes.size == 0 && isNotPremiumMethod.returnType == "Z"
|
||||
}
|
||||
}
|
||||
)
|
||||
@@ -0,0 +1,14 @@
|
||||
package app.revanced.patches.pixiv.ads.fingerprints
|
||||
|
||||
import app.revanced.patcher.extensions.or
|
||||
import app.revanced.patcher.fingerprint.MethodFingerprint
|
||||
import com.android.tools.smali.dexlib2.AccessFlags
|
||||
|
||||
|
||||
internal object ShouldShowAdsFingerprint : MethodFingerprint(
|
||||
"Z",
|
||||
AccessFlags.PUBLIC or AccessFlags.FINAL,
|
||||
customFingerprint = { methodDef, classDef ->
|
||||
classDef.type.endsWith("AdUtils;") && methodDef.name == "shouldShowAds"
|
||||
}
|
||||
)
|
||||
@@ -0,0 +1,61 @@
|
||||
package app.revanced.patches.reddit.customclients.syncforreddit.fix.user
|
||||
|
||||
import app.revanced.patcher.data.BytecodeContext
|
||||
import app.revanced.patcher.extensions.InstructionExtensions.getInstruction
|
||||
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.patches.reddit.customclients.syncforreddit.fix.user.fingerprints.*
|
||||
import app.revanced.patches.reddit.customclients.syncforreddit.fix.user.fingerprints.OAuthFriendRequestFingerprint
|
||||
import app.revanced.patches.reddit.customclients.syncforreddit.fix.user.fingerprints.OAuthSubredditInfoRequestHelperFingerprint
|
||||
import app.revanced.patches.reddit.customclients.syncforreddit.fix.user.fingerprints.OAuthUnfriendRequestFingerprint
|
||||
import app.revanced.util.getReference
|
||||
import app.revanced.util.resultOrThrow
|
||||
import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction
|
||||
import com.android.tools.smali.dexlib2.iface.reference.StringReference
|
||||
|
||||
@Patch(
|
||||
name = "Use /user/ endpoint",
|
||||
description = "Replaces the deprecated endpoint for viewing user profiles /u with /user, that used to fix a bug.",
|
||||
compatiblePackages = [
|
||||
CompatiblePackage("com.laurencedawson.reddit_sync"),
|
||||
CompatiblePackage("com.laurencedawson.reddit_sync.pro"),
|
||||
CompatiblePackage("com.laurencedawson.reddit_sync.dev"),
|
||||
],
|
||||
use = false,
|
||||
)
|
||||
@Suppress("unused")
|
||||
object UseUserEndpointPatch : BytecodePatch(
|
||||
fingerprints = setOf(
|
||||
OAuthFriendRequestFingerprint,
|
||||
OAuthSubredditInfoRequestConstructorFingerprint,
|
||||
OAuthSubredditInfoRequestHelperFingerprint,
|
||||
OAuthUnfriendRequestFingerprint,
|
||||
OAuthUserIdRequestFingerprint,
|
||||
OAuthUserInfoRequestFingerprint,
|
||||
),
|
||||
) {
|
||||
override fun execute(context: BytecodeContext) {
|
||||
arrayOf(
|
||||
OAuthFriendRequestFingerprint,
|
||||
OAuthSubredditInfoRequestConstructorFingerprint,
|
||||
OAuthSubredditInfoRequestHelperFingerprint,
|
||||
OAuthUnfriendRequestFingerprint,
|
||||
OAuthUserIdRequestFingerprint,
|
||||
OAuthUserInfoRequestFingerprint,
|
||||
).map(MethodFingerprint::resultOrThrow).map {
|
||||
it.scanResult.stringsScanResult!!.matches.first().index to it.mutableMethod
|
||||
}.forEach { (userPathStringIndex, method) ->
|
||||
val userPathStringInstruction = method.getInstruction<OneRegisterInstruction>(userPathStringIndex)
|
||||
val userPathStringRegister = userPathStringInstruction.registerA
|
||||
val fixedUserPathString = userPathStringInstruction.getReference<StringReference>()!!.string.replace("u/", "user/")
|
||||
|
||||
method.replaceInstruction(
|
||||
userPathStringIndex,
|
||||
"const-string v$userPathStringRegister, \"${fixedUserPathString}\"",
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
package app.revanced.patches.reddit.customclients.syncforreddit.fix.user.fingerprints
|
||||
|
||||
import app.revanced.patcher.fingerprint.MethodFingerprint
|
||||
|
||||
internal abstract class BaseUserEndpointFingerprint(source: String, accessFlags: Int? = null) :
|
||||
MethodFingerprint(
|
||||
accessFlags = accessFlags,
|
||||
strings = listOf("u/"),
|
||||
customFingerprint = { _, classDef -> classDef.sourceFile == source },
|
||||
)
|
||||
@@ -0,0 +1,3 @@
|
||||
package app.revanced.patches.reddit.customclients.syncforreddit.fix.user.fingerprints
|
||||
|
||||
internal object OAuthFriendRequestFingerprint : BaseUserEndpointFingerprint("OAuthFriendRequest.java")
|
||||
@@ -0,0 +1,10 @@
|
||||
package app.revanced.patches.reddit.customclients.syncforreddit.fix.user.fingerprints
|
||||
|
||||
import app.revanced.patcher.extensions.or
|
||||
import com.android.tools.smali.dexlib2.AccessFlags
|
||||
|
||||
internal object OAuthSubredditInfoRequestConstructorFingerprint :
|
||||
BaseUserEndpointFingerprint(
|
||||
"OAuthSubredditInfoRequest.java",
|
||||
AccessFlags.PUBLIC or AccessFlags.CONSTRUCTOR,
|
||||
)
|
||||
@@ -0,0 +1,10 @@
|
||||
package app.revanced.patches.reddit.customclients.syncforreddit.fix.user.fingerprints
|
||||
|
||||
import app.revanced.patcher.extensions.or
|
||||
import com.android.tools.smali.dexlib2.AccessFlags
|
||||
|
||||
internal object OAuthSubredditInfoRequestHelperFingerprint :
|
||||
BaseUserEndpointFingerprint(
|
||||
"OAuthSubredditInfoRequest.java",
|
||||
AccessFlags.PRIVATE or AccessFlags.STATIC,
|
||||
)
|
||||
@@ -0,0 +1,3 @@
|
||||
package app.revanced.patches.reddit.customclients.syncforreddit.fix.user.fingerprints
|
||||
|
||||
internal object OAuthUnfriendRequestFingerprint : BaseUserEndpointFingerprint("OAuthUnfriendRequest.java")
|
||||
@@ -0,0 +1,3 @@
|
||||
package app.revanced.patches.reddit.customclients.syncforreddit.fix.user.fingerprints
|
||||
|
||||
internal object OAuthUserIdRequestFingerprint : BaseUserEndpointFingerprint("OAuthUserIdRequest.java")
|
||||
@@ -0,0 +1,3 @@
|
||||
package app.revanced.patches.reddit.customclients.syncforreddit.fix.user.fingerprints
|
||||
|
||||
internal object OAuthUserInfoRequestFingerprint : BaseUserEndpointFingerprint("OAuthUserInfoRequest.java")
|
||||
@@ -0,0 +1,114 @@
|
||||
package app.revanced.patches.shared.misc.checks
|
||||
|
||||
import android.os.Build.*
|
||||
import app.revanced.patcher.data.BytecodeContext
|
||||
import app.revanced.patcher.extensions.InstructionExtensions.addInstructions
|
||||
import app.revanced.patcher.fingerprint.MethodFingerprint
|
||||
import app.revanced.patcher.patch.BytecodePatch
|
||||
import app.revanced.patcher.util.proxy.mutableTypes.encodedValue.MutableEncodedValue
|
||||
import app.revanced.patcher.util.proxy.mutableTypes.encodedValue.MutableLongEncodedValue
|
||||
import app.revanced.patcher.util.proxy.mutableTypes.encodedValue.MutableStringEncodedValue
|
||||
import app.revanced.patches.all.misc.resources.AddResourcesPatch
|
||||
import app.revanced.patches.shared.misc.checks.fingerprints.PatchInfoBuildFingerprint
|
||||
import app.revanced.patches.shared.misc.checks.fingerprints.PatchInfoFingerprint
|
||||
import app.revanced.patches.shared.misc.integrations.BaseIntegrationsPatch
|
||||
import app.revanced.util.exception
|
||||
import app.revanced.util.resultOrThrow
|
||||
import com.android.tools.smali.dexlib2.immutable.value.ImmutableLongEncodedValue
|
||||
import com.android.tools.smali.dexlib2.immutable.value.ImmutableStringEncodedValue
|
||||
import java.nio.charset.StandardCharsets
|
||||
import java.security.MessageDigest
|
||||
import kotlin.io.encoding.Base64
|
||||
import kotlin.io.encoding.ExperimentalEncodingApi
|
||||
|
||||
abstract class BaseCheckEnvironmentPatch(
|
||||
private val mainActivityOnCreateFingerprint: MethodFingerprint,
|
||||
compatiblePackages: Set<CompatiblePackage>,
|
||||
integrationsPatch: BaseIntegrationsPatch,
|
||||
) : BytecodePatch(
|
||||
description = "Checks, if the application was patched by, otherwise warns the user.",
|
||||
compatiblePackages = compatiblePackages,
|
||||
dependencies = setOf(
|
||||
AddResourcesPatch::class,
|
||||
integrationsPatch::class,
|
||||
),
|
||||
fingerprints = setOf(
|
||||
PatchInfoFingerprint,
|
||||
PatchInfoBuildFingerprint,
|
||||
mainActivityOnCreateFingerprint,
|
||||
),
|
||||
) {
|
||||
override fun execute(context: BytecodeContext) {
|
||||
AddResourcesPatch(BaseCheckEnvironmentPatch::class)
|
||||
|
||||
setPatchInfo()
|
||||
invokeCheck()
|
||||
}
|
||||
|
||||
private fun setPatchInfo() {
|
||||
PatchInfoFingerprint.setClassFields(
|
||||
"PATCH_TIME" to System.currentTimeMillis().encoded,
|
||||
)
|
||||
|
||||
fun setBuildInfo() {
|
||||
PatchInfoBuildFingerprint.setClassFields(
|
||||
"PATCH_BOARD" to BOARD.encodedAndHashed,
|
||||
"PATCH_BOOTLOADER" to BOOTLOADER.encodedAndHashed,
|
||||
"PATCH_BRAND" to BRAND.encodedAndHashed,
|
||||
"PATCH_CPU_ABI" to CPU_ABI.encodedAndHashed,
|
||||
"PATCH_CPU_ABI2" to CPU_ABI2.encodedAndHashed,
|
||||
"PATCH_DEVICE" to DEVICE.encodedAndHashed,
|
||||
"PATCH_DISPLAY" to DISPLAY.encodedAndHashed,
|
||||
"PATCH_FINGERPRINT" to FINGERPRINT.encodedAndHashed,
|
||||
"PATCH_HARDWARE" to HARDWARE.encodedAndHashed,
|
||||
"PATCH_HOST" to HOST.encodedAndHashed,
|
||||
"PATCH_ID" to ID.encodedAndHashed,
|
||||
"PATCH_MANUFACTURER" to MANUFACTURER.encodedAndHashed,
|
||||
"PATCH_MODEL" to MODEL.encodedAndHashed,
|
||||
"PATCH_PRODUCT" to PRODUCT.encodedAndHashed,
|
||||
"PATCH_RADIO" to RADIO.encodedAndHashed,
|
||||
"PATCH_TAGS" to TAGS.encodedAndHashed,
|
||||
"PATCH_TYPE" to TYPE.encodedAndHashed,
|
||||
"PATCH_USER" to USER.encodedAndHashed,
|
||||
)
|
||||
}
|
||||
|
||||
try {
|
||||
Class.forName("android.os.Build")
|
||||
// This only works on Android,
|
||||
// because it uses Android APIs.
|
||||
setBuildInfo()
|
||||
} catch (_: ClassNotFoundException) { }
|
||||
}
|
||||
|
||||
private fun invokeCheck() = mainActivityOnCreateFingerprint.result?.mutableMethod?.addInstructions(
|
||||
0,
|
||||
"invoke-static/range { p0 .. p0 },$INTEGRATIONS_CLASS_DESCRIPTOR->check(Landroid/app/Activity;)V",
|
||||
) ?: throw mainActivityOnCreateFingerprint.exception
|
||||
|
||||
private companion object {
|
||||
private const val INTEGRATIONS_CLASS_DESCRIPTOR =
|
||||
"Lapp/revanced/integrations/shared/checks/CheckEnvironmentPatch;"
|
||||
|
||||
@OptIn(ExperimentalEncodingApi::class)
|
||||
private val String.encodedAndHashed
|
||||
get() = MutableStringEncodedValue(
|
||||
ImmutableStringEncodedValue(
|
||||
Base64.encode(
|
||||
MessageDigest.getInstance("SHA-1")
|
||||
.digest(this.toByteArray(StandardCharsets.UTF_8)),
|
||||
),
|
||||
),
|
||||
)
|
||||
|
||||
private val Long.encoded get() = MutableLongEncodedValue(ImmutableLongEncodedValue(this))
|
||||
|
||||
private fun <T : MutableEncodedValue> MethodFingerprint.setClassFields(vararg fieldNameValues: Pair<String, T>) {
|
||||
val fieldNameValueMap = mapOf(*fieldNameValues)
|
||||
|
||||
resultOrThrow().mutableClass.fields.forEach { field ->
|
||||
field.initialValue = fieldNameValueMap[field.name] ?: return@forEach
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
package app.revanced.patches.shared.misc.checks.fingerprints
|
||||
|
||||
import app.revanced.patcher.fingerprint.MethodFingerprint
|
||||
|
||||
internal object PatchInfoBuildFingerprint : MethodFingerprint(
|
||||
customFingerprint = { _, classDef -> classDef.type == "Lapp/revanced/integrations/shared/checks/PatchInfo\$Build;" },
|
||||
)
|
||||
@@ -0,0 +1,9 @@
|
||||
package app.revanced.patches.shared.misc.checks.fingerprints
|
||||
|
||||
import app.revanced.patcher.fingerprint.MethodFingerprint
|
||||
|
||||
internal object PatchInfoFingerprint : MethodFingerprint(
|
||||
customFingerprint = { _, classDef ->
|
||||
classDef.type == "Lapp/revanced/integrations/shared/checks/PatchInfo;"
|
||||
},
|
||||
)
|
||||
@@ -18,7 +18,7 @@ import app.revanced.patches.shared.misc.gms.fingerprints.GooglePlayUtilityFinger
|
||||
import app.revanced.patches.shared.misc.gms.fingerprints.ServiceCheckFingerprint
|
||||
import app.revanced.util.exception
|
||||
import app.revanced.util.getReference
|
||||
import app.revanced.util.indexOfFirstInstructionOrThrow
|
||||
import app.revanced.util.indexOfFirstInstruction
|
||||
import app.revanced.util.returnEarly
|
||||
import com.android.tools.smali.dexlib2.Opcode
|
||||
import com.android.tools.smali.dexlib2.builder.instruction.BuilderInstruction21c
|
||||
@@ -115,15 +115,16 @@ abstract class BaseGmsCoreSupportPatch(
|
||||
|
||||
// Verify GmsCore is installed and whitelisted for power optimizations and background usage.
|
||||
mainActivityOnCreateFingerprint.result?.mutableMethod?.apply {
|
||||
val setContextIndex = indexOfFirstInstructionOrThrow {
|
||||
val reference = getReference<MethodReference>() ?: return@indexOfFirstInstructionOrThrow false
|
||||
// Temporary fix for patches with an integrations patch that hook the onCreate method as well.
|
||||
val setContextIndex = indexOfFirstInstruction {
|
||||
val reference = getReference<MethodReference>() ?: return@indexOfFirstInstruction false
|
||||
|
||||
reference.toString() == "Lapp/revanced/integrations/shared/Utils;->setContext(Landroid/content/Context;)V"
|
||||
}
|
||||
|
||||
// Add after setContext call, because this patch needs the context.
|
||||
addInstructions(
|
||||
setContextIndex + 1,
|
||||
if (setContextIndex < 0) 0 else setContextIndex + 1,
|
||||
"invoke-static/range { p0 .. p0 }, Lapp/revanced/integrations/shared/GmsCoreSupport;->" +
|
||||
"checkGmsCore(Landroid/app/Activity;)V",
|
||||
)
|
||||
|
||||
@@ -62,7 +62,7 @@ object HideAdsPatch : BytecodePatch(
|
||||
|
||||
// Prevent verification of an HTTP header containing the user's current plan, which would contradict the previous patch.
|
||||
InterceptFingerprint.resultOrThrow().let { result ->
|
||||
val conditionIndex = result.scanResult.patternScanResult!!.endIndex
|
||||
val conditionIndex = result.scanResult.patternScanResult!!.endIndex + 1
|
||||
result.mutableMethod.addInstruction(
|
||||
conditionIndex,
|
||||
"return-object p1",
|
||||
|
||||
@@ -9,14 +9,13 @@ internal object InterceptFingerprint : MethodFingerprint(
|
||||
accessFlags = AccessFlags.PUBLIC.value,
|
||||
parameters = listOf("L"),
|
||||
opcodes = listOf(
|
||||
Opcode.INVOKE_INTERFACE,
|
||||
Opcode.MOVE_RESULT_OBJECT,
|
||||
Opcode.INVOKE_VIRTUAL,
|
||||
Opcode.MOVE_RESULT,
|
||||
Opcode.IF_EQZ,
|
||||
Opcode.INVOKE_INTERFACE,
|
||||
Opcode.MOVE_RESULT_OBJECT
|
||||
),
|
||||
strings = listOf("SC-Mob-UserPlan", "Configuration"),
|
||||
customFingerprint = { _, classDef ->
|
||||
classDef.sourceFile == "ApiUserPlanInterceptor.java"
|
||||
classDef.sourceFile == "ApiUserPlanInterceptor.java" ||
|
||||
classDef.sourceFile == "ApiUserPlanInterceptor.kt"
|
||||
},
|
||||
)
|
||||
|
||||
@@ -9,7 +9,7 @@ import app.revanced.patches.swissid.integritycheck.fingerprints.CheckIntegrityFi
|
||||
import app.revanced.util.resultOrThrow
|
||||
|
||||
@Patch(
|
||||
name = "Remove Google Play Integrity Integrity check",
|
||||
name = "Remove Google Play Integrity check",
|
||||
description = "Removes the Google Play Integrity check. With this it's possible to use SwissID on custom ROMS." +
|
||||
"If the device is rooted, root permissions must be hidden from the app.",
|
||||
compatiblePackages = [CompatiblePackage("com.swisssign.swissid.mobile")],
|
||||
|
||||
@@ -17,16 +17,16 @@ import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction
|
||||
@Patch(
|
||||
name = "Feed filter",
|
||||
description = "Removes ads, livestreams, stories, image videos " +
|
||||
"and videos with a specific amount of views or likes from the feed.",
|
||||
"and videos with a specific amount of views or likes from the feed.",
|
||||
dependencies = [IntegrationsPatch::class, SettingsPatch::class],
|
||||
compatiblePackages = [
|
||||
CompatiblePackage("com.ss.android.ugc.trill", ["32.5.3"]),
|
||||
CompatiblePackage("com.zhiliaoapp.musically", ["32.5.3"])
|
||||
]
|
||||
CompatiblePackage("com.ss.android.ugc.trill", ["36.5.4"]),
|
||||
CompatiblePackage("com.zhiliaoapp.musically", ["36.5.4"]),
|
||||
],
|
||||
)
|
||||
@Suppress("unused")
|
||||
object FeedFilterPatch : BytecodePatch(
|
||||
setOf(FeedApiServiceLIZFingerprint, SettingsStatusLoadFingerprint)
|
||||
setOf(FeedApiServiceLIZFingerprint, SettingsStatusLoadFingerprint),
|
||||
) {
|
||||
override fun execute(context: BytecodeContext) {
|
||||
FeedApiServiceLIZFingerprint.result?.mutableMethod?.apply {
|
||||
@@ -36,13 +36,13 @@ object FeedFilterPatch : BytecodePatch(
|
||||
addInstruction(
|
||||
returnFeedItemInstruction.location.index,
|
||||
"invoke-static { v$feedItemsRegister }, " +
|
||||
"Lapp/revanced/integrations/tiktok/feedfilter/FeedItemsFilter;->filter(Lcom/ss/android/ugc/aweme/feed/model/FeedItemList;)V"
|
||||
"Lapp/revanced/integrations/tiktok/feedfilter/FeedItemsFilter;->filter(Lcom/ss/android/ugc/aweme/feed/model/FeedItemList;)V",
|
||||
)
|
||||
} ?: throw FeedApiServiceLIZFingerprint.exception
|
||||
|
||||
SettingsStatusLoadFingerprint.result?.mutableMethod?.addInstruction(
|
||||
0,
|
||||
"invoke-static {}, Lapp/revanced/integrations/tiktok/settings/SettingsStatus;->enableFeedFilter()V"
|
||||
"invoke-static {}, Lapp/revanced/integrations/tiktok/settings/SettingsStatus;->enableFeedFilter()V",
|
||||
) ?: throw SettingsStatusLoadFingerprint.exception
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,7 +9,7 @@ import app.revanced.patcher.patch.annotation.CompatiblePackage
|
||||
import app.revanced.patcher.patch.annotation.Patch
|
||||
import app.revanced.patcher.util.smali.ExternalLabel
|
||||
import app.revanced.patches.tiktok.interaction.cleardisplay.fingerprints.OnClearDisplayEventFingerprint
|
||||
import app.revanced.patches.tiktok.interaction.cleardisplay.fingerprints.OnRenderFirstFrameFingerprint
|
||||
import app.revanced.patches.tiktok.shared.fingerprints.OnRenderFirstFrameFingerprint
|
||||
import app.revanced.util.exception
|
||||
import app.revanced.util.indexOfFirstInstructionOrThrow
|
||||
import com.android.tools.smali.dexlib2.Opcode
|
||||
@@ -19,16 +19,16 @@ import com.android.tools.smali.dexlib2.iface.instruction.formats.Instruction22c
|
||||
name = "Remember clear display",
|
||||
description = "Remembers the clear display configurations in between videos.",
|
||||
compatiblePackages = [
|
||||
CompatiblePackage("com.ss.android.ugc.trill", ["32.5.3"]),
|
||||
CompatiblePackage("com.zhiliaoapp.musically", ["32.5.3"])
|
||||
]
|
||||
CompatiblePackage("com.ss.android.ugc.trill", ["36.5.4"]),
|
||||
CompatiblePackage("com.zhiliaoapp.musically", ["36.5.4"]),
|
||||
],
|
||||
)
|
||||
@Suppress("unused")
|
||||
object RememberClearDisplayPatch : BytecodePatch(
|
||||
setOf(
|
||||
OnClearDisplayEventFingerprint,
|
||||
OnRenderFirstFrameFingerprint
|
||||
)
|
||||
OnRenderFirstFrameFingerprint,
|
||||
),
|
||||
) {
|
||||
override fun execute(context: BytecodeContext) {
|
||||
OnClearDisplayEventFingerprint.result?.mutableMethod?.let {
|
||||
@@ -40,7 +40,7 @@ object RememberClearDisplayPatch : BytecodePatch(
|
||||
it.addInstructions(
|
||||
isEnabledIndex,
|
||||
"invoke-static { v$isEnabledRegister }, " +
|
||||
"Lapp/revanced/integrations/tiktok/cleardisplay/RememberClearDisplayPatch;->rememberClearDisplayState(Z)V"
|
||||
"Lapp/revanced/integrations/tiktok/cleardisplay/RememberClearDisplayPatch;->rememberClearDisplayState(Z)V",
|
||||
)
|
||||
|
||||
// endregion
|
||||
@@ -54,22 +54,25 @@ object RememberClearDisplayPatch : BytecodePatch(
|
||||
"""
|
||||
# Create a new clearDisplayEvent and post it to the EventBus (https://github.com/greenrobot/EventBus)
|
||||
|
||||
# The state of clear display.
|
||||
invoke-static { }, Lapp/revanced/integrations/tiktok/cleardisplay/RememberClearDisplayPatch;->getClearDisplayState()Z
|
||||
move-result v3
|
||||
if-eqz v3, :clear_display_disabled
|
||||
|
||||
# Clear display type such as 0 = LONG_PRESS, 1 = SCREEN_RECORD etc.
|
||||
const/4 v1, 0x0
|
||||
|
||||
# Enter method (Such as "pinch", "swipe_exit", or an empty string (unknown, what it means)).
|
||||
const-string v2, ""
|
||||
|
||||
# Name of the clear display type which is equivalent to the clear display type.
|
||||
const-string v2, "long_press"
|
||||
const-string v3, "long_press"
|
||||
|
||||
# The state of clear display.
|
||||
invoke-static { }, Lapp/revanced/integrations/tiktok/cleardisplay/RememberClearDisplayPatch;->getClearDisplayState()Z
|
||||
move-result v4
|
||||
if-eqz v4, :clear_display_disabled
|
||||
|
||||
new-instance v0, $clearDisplayEventClass
|
||||
invoke-direct { v0, v1, v2, v3 }, $clearDisplayEventClass-><init>(ILjava/lang/String;Z)V
|
||||
invoke-direct { v0, v1, v2, v3, v4 }, $clearDisplayEventClass-><init>(ILjava/lang/String;Ljava/lang/String;Z)V
|
||||
invoke-virtual { v0 }, $clearDisplayEventClass->post()Lcom/ss/android/ugc/governance/eventbus/IEvent;
|
||||
""",
|
||||
ExternalLabel("clear_display_disabled", getInstruction(0))
|
||||
ExternalLabel("clear_display_disabled", getInstruction(0)),
|
||||
)
|
||||
} ?: throw OnRenderFirstFrameFingerprint.exception
|
||||
|
||||
@@ -1,9 +0,0 @@
|
||||
package app.revanced.patches.tiktok.interaction.cleardisplay.fingerprints
|
||||
|
||||
import app.revanced.patcher.fingerprint.MethodFingerprint
|
||||
|
||||
internal object OnRenderFirstFrameFingerprint : MethodFingerprint(
|
||||
customFingerprint = { methodDef, _ ->
|
||||
methodDef.definingClass.endsWith("/BaseListFragmentPanel;") && methodDef.name == "onRenderFirstFrame"
|
||||
}
|
||||
)
|
||||
@@ -13,14 +13,13 @@ import app.revanced.patcher.util.proxy.mutableTypes.MutableMethod
|
||||
import app.revanced.patches.tiktok.interaction.downloads.fingerprints.ACLCommonShareFingerprint
|
||||
import app.revanced.patches.tiktok.interaction.downloads.fingerprints.ACLCommonShareFingerprint2
|
||||
import app.revanced.patches.tiktok.interaction.downloads.fingerprints.ACLCommonShareFingerprint3
|
||||
import app.revanced.patches.tiktok.interaction.downloads.fingerprints.DownloadPathParentFingerprint
|
||||
import app.revanced.patches.tiktok.interaction.downloads.fingerprints.DownloadUriFingerprint
|
||||
import app.revanced.patches.tiktok.misc.integrations.IntegrationsPatch
|
||||
import app.revanced.patches.tiktok.misc.settings.SettingsPatch
|
||||
import app.revanced.patches.tiktok.misc.settings.fingerprints.SettingsStatusLoadFingerprint
|
||||
import app.revanced.util.exception
|
||||
import app.revanced.util.getReference
|
||||
import app.revanced.util.indexOfFirstInstructionOrThrow
|
||||
import com.android.tools.smali.dexlib2.Opcode
|
||||
import com.android.tools.smali.dexlib2.iface.instruction.formats.Instruction35c
|
||||
import com.android.tools.smali.dexlib2.iface.reference.MethodReference
|
||||
|
||||
@Patch(
|
||||
@@ -28,9 +27,9 @@ import com.android.tools.smali.dexlib2.iface.reference.MethodReference
|
||||
description = "Removes download restrictions and changes the default path to download to.",
|
||||
dependencies = [IntegrationsPatch::class, SettingsPatch::class],
|
||||
compatiblePackages = [
|
||||
CompatiblePackage("com.ss.android.ugc.trill", ["32.5.3"]),
|
||||
CompatiblePackage("com.zhiliaoapp.musically", ["32.5.3"])
|
||||
]
|
||||
CompatiblePackage("com.ss.android.ugc.trill", ["36.5.4"]),
|
||||
CompatiblePackage("com.zhiliaoapp.musically", ["36.5.4"]),
|
||||
],
|
||||
)
|
||||
@Suppress("unused")
|
||||
object DownloadsPatch : BytecodePatch(
|
||||
@@ -38,9 +37,9 @@ object DownloadsPatch : BytecodePatch(
|
||||
ACLCommonShareFingerprint,
|
||||
ACLCommonShareFingerprint2,
|
||||
ACLCommonShareFingerprint3,
|
||||
DownloadPathParentFingerprint,
|
||||
SettingsStatusLoadFingerprint
|
||||
)
|
||||
DownloadUriFingerprint,
|
||||
SettingsStatusLoadFingerprint,
|
||||
),
|
||||
) {
|
||||
override fun execute(context: BytecodeContext) {
|
||||
fun MethodFingerprint.getMethod() = result?.mutableMethod ?: throw exception
|
||||
@@ -52,7 +51,7 @@ object DownloadsPatch : BytecodePatch(
|
||||
"""
|
||||
const/4 v0, 0x0
|
||||
return v0
|
||||
"""
|
||||
""",
|
||||
)
|
||||
},
|
||||
ACLCommonShareFingerprint2 to {
|
||||
@@ -61,7 +60,7 @@ object DownloadsPatch : BytecodePatch(
|
||||
"""
|
||||
const/4 v0, 0x2
|
||||
return v0
|
||||
"""
|
||||
""",
|
||||
)
|
||||
},
|
||||
// Download videos without watermark.
|
||||
@@ -76,48 +75,40 @@ object DownloadsPatch : BytecodePatch(
|
||||
return v0
|
||||
:noremovewatermark
|
||||
nop
|
||||
"""
|
||||
""",
|
||||
)
|
||||
},
|
||||
// Change the download path patch.
|
||||
DownloadPathParentFingerprint to {
|
||||
val targetIndex = indexOfFirstInstructionOrThrow { opcode == Opcode.INVOKE_STATIC }
|
||||
val downloadUriMethod = context
|
||||
.toMethodWalker(this)
|
||||
.nextMethod(targetIndex, true)
|
||||
.getMethod() as MutableMethod
|
||||
|
||||
val firstIndex = downloadUriMethod.indexOfFirstInstructionOrThrow {
|
||||
opcode == Opcode.INVOKE_DIRECT && ((this as Instruction35c).reference as MethodReference).name == "<init>"
|
||||
DownloadUriFingerprint to {
|
||||
val firstIndex = indexOfFirstInstructionOrThrow {
|
||||
getReference<MethodReference>()?.name == "<init>"
|
||||
}
|
||||
val secondIndex = downloadUriMethod.indexOfFirstInstructionOrThrow {
|
||||
opcode == Opcode.INVOKE_STATIC && ((this as Instruction35c).reference as MethodReference).returnType.contains(
|
||||
"Uri"
|
||||
)
|
||||
val secondIndex = indexOfFirstInstructionOrThrow {
|
||||
getReference<MethodReference>()?.returnType?.contains("Uri") == true
|
||||
}
|
||||
|
||||
downloadUriMethod.addInstructions(
|
||||
addInstructions(
|
||||
secondIndex,
|
||||
"""
|
||||
invoke-static {}, Lapp/revanced/integrations/tiktok/download/DownloadsPatch;->getDownloadPath()Ljava/lang/String;
|
||||
move-result-object v0
|
||||
"""
|
||||
invoke-static {}, Lapp/revanced/integrations/tiktok/download/DownloadsPatch;->getDownloadPath()Ljava/lang/String;
|
||||
move-result-object v0
|
||||
""",
|
||||
)
|
||||
|
||||
downloadUriMethod.addInstructions(
|
||||
addInstructions(
|
||||
firstIndex,
|
||||
"""
|
||||
invoke-static {}, Lapp/revanced/integrations/tiktok/download/DownloadsPatch;->getDownloadPath()Ljava/lang/String;
|
||||
move-result-object v0
|
||||
"""
|
||||
invoke-static {}, Lapp/revanced/integrations/tiktok/download/DownloadsPatch;->getDownloadPath()Ljava/lang/String;
|
||||
move-result-object v0
|
||||
""",
|
||||
)
|
||||
},
|
||||
SettingsStatusLoadFingerprint to {
|
||||
addInstruction(
|
||||
0,
|
||||
"invoke-static {}, Lapp/revanced/integrations/tiktok/settings/SettingsStatus;->enableDownload()V"
|
||||
"invoke-static {}, Lapp/revanced/integrations/tiktok/settings/SettingsStatus;->enableDownload()V",
|
||||
)
|
||||
}
|
||||
},
|
||||
).forEach { (fingerprint, patch) ->
|
||||
fingerprint.getMethod().patch()
|
||||
}
|
||||
|
||||
@@ -3,22 +3,18 @@ package app.revanced.patches.tiktok.interaction.downloads.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 DownloadPathParentFingerprint : MethodFingerprint(
|
||||
"L",
|
||||
internal object DownloadUriFingerprint : MethodFingerprint(
|
||||
"Landroid/net/Uri;",
|
||||
AccessFlags.PUBLIC or AccessFlags.STATIC,
|
||||
strings = listOf(
|
||||
"video/mp4"
|
||||
"/",
|
||||
"/Camera",
|
||||
"/Camera/",
|
||||
"video/mp4",
|
||||
),
|
||||
parameters = listOf(
|
||||
"L",
|
||||
"L"
|
||||
"Landroid/content/Context;",
|
||||
"Ljava/lang/String;",
|
||||
),
|
||||
opcodes = listOf(
|
||||
Opcode.CONST_STRING,
|
||||
Opcode.INVOKE_STATIC,
|
||||
Opcode.MOVE_RESULT_OBJECT,
|
||||
Opcode.RETURN_OBJECT
|
||||
)
|
||||
)
|
||||
)
|
||||
@@ -9,30 +9,33 @@ import app.revanced.patcher.patch.PatchException
|
||||
import app.revanced.patcher.patch.annotation.CompatiblePackage
|
||||
import app.revanced.patcher.patch.annotation.Patch
|
||||
import app.revanced.patches.tiktok.interaction.speed.fingerprints.GetSpeedFingerprint
|
||||
import app.revanced.patches.tiktok.interaction.speed.fingerprints.OnRenderFirstFrameFingerprint
|
||||
import app.revanced.patches.tiktok.interaction.speed.fingerprints.SetSpeedFingerprint
|
||||
import app.revanced.patches.tiktok.shared.fingerprints.GetEnterFromFingerprint
|
||||
import app.revanced.patches.tiktok.shared.fingerprints.OnRenderFirstFrameFingerprint
|
||||
import app.revanced.util.exception
|
||||
import app.revanced.util.getReference
|
||||
import app.revanced.util.indexOfFirstInstructionOrThrow
|
||||
import app.revanced.util.resultOrThrow
|
||||
import com.android.tools.smali.dexlib2.iface.instruction.formats.Instruction11x
|
||||
import com.android.tools.smali.dexlib2.iface.reference.MethodReference
|
||||
|
||||
@Patch(
|
||||
name = "Playback speed",
|
||||
description = "Enables the playback speed option for all videos and " +
|
||||
"retains the speed configurations in between videos.",
|
||||
"retains the speed configurations in between videos.",
|
||||
compatiblePackages = [
|
||||
CompatiblePackage("com.ss.android.ugc.trill", ["32.5.3"]),
|
||||
CompatiblePackage("com.zhiliaoapp.musically", ["32.5.3"])
|
||||
]
|
||||
CompatiblePackage("com.ss.android.ugc.trill", ["36.5.4"]),
|
||||
CompatiblePackage("com.zhiliaoapp.musically", ["36.5.4"]),
|
||||
],
|
||||
)
|
||||
@Suppress("unused")
|
||||
object PlaybackSpeedPatch : BytecodePatch(
|
||||
setOf(
|
||||
GetSpeedFingerprint,
|
||||
OnRenderFirstFrameFingerprint,
|
||||
SetSpeedFingerprint
|
||||
)
|
||||
SetSpeedFingerprint,
|
||||
GetEnterFromFingerprint,
|
||||
),
|
||||
) {
|
||||
override fun execute(context: BytecodeContext) {
|
||||
SetSpeedFingerprint.result?.let { onVideoSwiped ->
|
||||
@@ -44,7 +47,7 @@ object PlaybackSpeedPatch : BytecodePatch(
|
||||
addInstruction(
|
||||
injectIndex,
|
||||
"invoke-static { v$register }," +
|
||||
" Lapp/revanced/integrations/tiktok/speed/PlaybackSpeedPatch;->rememberPlaybackSpeed(F)V"
|
||||
" Lapp/revanced/integrations/tiktok/speed/PlaybackSpeedPatch;->rememberPlaybackSpeed(F)V",
|
||||
)
|
||||
} ?: throw GetSpeedFingerprint.exception
|
||||
|
||||
@@ -53,29 +56,29 @@ object PlaybackSpeedPatch : BytecodePatch(
|
||||
OnRenderFirstFrameFingerprint.result?.mutableMethod?.addInstructions(
|
||||
0,
|
||||
"""
|
||||
# Video playback location (e.g. home page, following page or search result page) retrieved using getEnterFrom method.
|
||||
const/4 v0, 0x1
|
||||
invoke-virtual {p0, v0}, Lcom/ss/android/ugc/aweme/feed/panel/BaseListFragmentPanel;->getEnterFrom(Z)Ljava/lang/String;
|
||||
move-result-object v0
|
||||
|
||||
# Model of current video retrieved using getCurrentAweme method.
|
||||
invoke-virtual {p0}, Lcom/ss/android/ugc/aweme/feed/panel/BaseListFragmentPanel;->getCurrentAweme()Lcom/ss/android/ugc/aweme/feed/model/Aweme;
|
||||
move-result-object v1
|
||||
|
||||
# Desired playback speed retrieved using getPlaybackSpeed method.
|
||||
invoke-static {}, Lapp/revanced/integrations/tiktok/speed/PlaybackSpeedPatch;->getPlaybackSpeed()F
|
||||
move-result-object v2
|
||||
invoke-static { v0, v1, v2 }, ${onVideoSwiped.method}
|
||||
"""
|
||||
# Video playback location (e.g. home page, following page or search result page) retrieved using getEnterFrom method.
|
||||
const/4 v0, 0x1
|
||||
invoke-virtual {p0, v0}, ${GetEnterFromFingerprint.resultOrThrow().method}
|
||||
move-result-object v0
|
||||
|
||||
# Model of current video retrieved using getCurrentAweme method.
|
||||
invoke-virtual {p0}, Lcom/ss/android/ugc/aweme/feed/panel/BaseListFragmentPanel;->getCurrentAweme()Lcom/ss/android/ugc/aweme/feed/model/Aweme;
|
||||
move-result-object v1
|
||||
|
||||
# Desired playback speed retrieved using getPlaybackSpeed method.
|
||||
invoke-static {}, Lapp/revanced/integrations/tiktok/speed/PlaybackSpeedPatch;->getPlaybackSpeed()F
|
||||
move-result v2
|
||||
invoke-static { v0, v1, v2 }, ${onVideoSwiped.method}
|
||||
""",
|
||||
) ?: throw OnRenderFirstFrameFingerprint.exception
|
||||
|
||||
// Force enable the playback speed option for all videos.
|
||||
onVideoSwiped.mutableClass.methods.find { method -> method.returnType == "Z" }?.addInstructions(
|
||||
0,
|
||||
"""
|
||||
const/4 v0, 0x1
|
||||
return v0
|
||||
"""
|
||||
const/4 v0, 0x1
|
||||
return v0
|
||||
""",
|
||||
) ?: throw PatchException("Failed to force enable the playback speed option.")
|
||||
} ?: throw SetSpeedFingerprint.exception
|
||||
}
|
||||
|
||||
@@ -24,9 +24,9 @@ import com.android.tools.smali.dexlib2.iface.reference.FieldReference
|
||||
description = "Adds ReVanced settings to TikTok.",
|
||||
dependencies = [IntegrationsPatch::class],
|
||||
compatiblePackages = [
|
||||
CompatiblePackage("com.ss.android.ugc.trill", ["32.5.3"]),
|
||||
CompatiblePackage("com.zhiliaoapp.musically", ["32.5.3"])
|
||||
]
|
||||
CompatiblePackage("com.ss.android.ugc.trill", ["36.5.4"]),
|
||||
CompatiblePackage("com.zhiliaoapp.musically", ["36.5.4"]),
|
||||
],
|
||||
)
|
||||
object SettingsPatch : BytecodePatch(
|
||||
setOf(
|
||||
@@ -34,21 +34,21 @@ object SettingsPatch : BytecodePatch(
|
||||
AddSettingsEntryFingerprint,
|
||||
SettingsEntryFingerprint,
|
||||
SettingsEntryInfoFingerprint,
|
||||
)
|
||||
),
|
||||
) {
|
||||
private const val INTEGRATIONS_CLASS_DESCRIPTOR =
|
||||
"Lapp/revanced/integrations/tiktok/settings/AdPersonalizationActivityHook;"
|
||||
|
||||
private const val INITIALIZE_SETTINGS_METHOD_DESCRIPTOR =
|
||||
"$INTEGRATIONS_CLASS_DESCRIPTOR->initialize(" +
|
||||
"Lcom/bytedance/ies/ugc/aweme/commercialize/compliance/personalization/AdPersonalizationActivity;" +
|
||||
")Z"
|
||||
"Lcom/bytedance/ies/ugc/aweme/commercialize/compliance/personalization/AdPersonalizationActivity;" +
|
||||
")Z"
|
||||
|
||||
private const val CREATE_SETTINGS_ENTRY_METHOD_DESCRIPTOR =
|
||||
"$INTEGRATIONS_CLASS_DESCRIPTOR->createSettingsEntry(" +
|
||||
"Ljava/lang/String;" +
|
||||
"Ljava/lang/String;" +
|
||||
")Ljava/lang/Object;"
|
||||
"Ljava/lang/String;" +
|
||||
"Ljava/lang/String;" +
|
||||
")Ljava/lang/Object;"
|
||||
|
||||
override fun execute(context: BytecodeContext) {
|
||||
// Find the class name of classes which construct a settings entry
|
||||
@@ -70,8 +70,8 @@ object SettingsPatch : BytecodePatch(
|
||||
markIndex + 2,
|
||||
listOf(
|
||||
getUnitManager,
|
||||
addEntry
|
||||
)
|
||||
addEntry,
|
||||
),
|
||||
)
|
||||
|
||||
addInstructions(
|
||||
@@ -81,7 +81,8 @@ object SettingsPatch : BytecodePatch(
|
||||
const-string v1, "$settingsButtonInfoClass"
|
||||
invoke-static {v0, v1}, $CREATE_SETTINGS_ENTRY_METHOD_DESCRIPTOR
|
||||
move-result-object v0
|
||||
"""
|
||||
check-cast v0, ${SettingsEntryFingerprint.result!!.classDef}
|
||||
""",
|
||||
)
|
||||
} ?: throw AddSettingsEntryFingerprint.exception
|
||||
|
||||
@@ -102,12 +103,10 @@ object SettingsPatch : BytecodePatch(
|
||||
if-eqz v$usableRegister, :do_not_open
|
||||
return-void
|
||||
""",
|
||||
ExternalLabel("do_not_open", getInstruction(initializeSettingsIndex))
|
||||
ExternalLabel("do_not_open", getInstruction(initializeSettingsIndex)),
|
||||
)
|
||||
} ?: throw AdPersonalizationActivityOnCreateFingerprint.exception
|
||||
}
|
||||
|
||||
private fun String.toClassName(): String {
|
||||
return substring(1, this.length - 1).replace("/", ".")
|
||||
}
|
||||
}
|
||||
private fun String.toClassName(): String = substring(1, this.length - 1).replace("/", ".")
|
||||
}
|
||||
|
||||
@@ -0,0 +1,24 @@
|
||||
package app.revanced.patches.tiktok.shared.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 GetEnterFromFingerprint : MethodFingerprint(
|
||||
returnType = "Ljava/lang/String;",
|
||||
accessFlags = AccessFlags.PUBLIC or AccessFlags.FINAL,
|
||||
parameters = listOf("Z"),
|
||||
opcodes = listOf(
|
||||
Opcode.INVOKE_VIRTUAL,
|
||||
Opcode.MOVE_RESULT,
|
||||
Opcode.INVOKE_VIRTUAL,
|
||||
Opcode.MOVE_RESULT_OBJECT,
|
||||
Opcode.INVOKE_STATIC,
|
||||
Opcode.MOVE_RESULT_OBJECT,
|
||||
Opcode.RETURN_OBJECT,
|
||||
),
|
||||
customFingerprint = { methodDef, _ ->
|
||||
methodDef.definingClass.endsWith("/BaseListFragmentPanel;")
|
||||
},
|
||||
)
|
||||
@@ -1,9 +1,10 @@
|
||||
package app.revanced.patches.tiktok.interaction.speed.fingerprints
|
||||
package app.revanced.patches.tiktok.shared.fingerprints
|
||||
|
||||
import app.revanced.patcher.fingerprint.MethodFingerprint
|
||||
|
||||
internal object OnRenderFirstFrameFingerprint : MethodFingerprint(
|
||||
strings = listOf("method_enable_viewpager_preload_duration"),
|
||||
customFingerprint = { methodDef, _ ->
|
||||
methodDef.definingClass.endsWith("/BaseListFragmentPanel;") && methodDef.name == "onRenderFirstFrame"
|
||||
}
|
||||
methodDef.definingClass.endsWith("/BaseListFragmentPanel;")
|
||||
},
|
||||
)
|
||||
@@ -12,7 +12,7 @@ import app.revanced.util.exception
|
||||
name = "Open links with app chooser",
|
||||
description = "Instead of opening links directly, open them with an app chooser. " +
|
||||
"As a result you can select a browser to open the link with.",
|
||||
compatiblePackages = [CompatiblePackage("com.twitter.android")],
|
||||
compatiblePackages = [CompatiblePackage("com.twitter.android", ["10.48.0-release.0"])],
|
||||
use = false,
|
||||
)
|
||||
@Suppress("unused")
|
||||
|
||||
@@ -138,8 +138,10 @@ object HideLayoutComponentsPatch : BytecodePatch(
|
||||
SwitchPreference("revanced_hide_keyword_content_search"),
|
||||
TextPreference("revanced_hide_keyword_content_phrases", inputType = InputType.TEXT_MULTI_LINE),
|
||||
NonInteractivePreference("revanced_hide_keyword_content_about"),
|
||||
),
|
||||
),
|
||||
NonInteractivePreference(key = "revanced_hide_keyword_content_about_whole_words",
|
||||
tag = "app.revanced.integrations.youtube.settings.preference.HtmlPreference")
|
||||
)
|
||||
)
|
||||
)
|
||||
|
||||
SettingsPatch.PreferenceScreen.GENERAL_LAYOUT.addPreferences(
|
||||
|
||||
@@ -38,6 +38,7 @@ 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_this_sound_button"),
|
||||
SwitchPreference("revanced_hide_shorts_shop_button"),
|
||||
SwitchPreference("revanced_hide_shorts_tagged_products"),
|
||||
SwitchPreference("revanced_hide_shorts_search_suggestions"),
|
||||
|
||||
@@ -12,7 +12,7 @@ import app.revanced.patches.youtube.misc.settings.SettingsPatch
|
||||
|
||||
@Patch(
|
||||
name = "Bypass image region restrictions",
|
||||
description = "Adds an option to use a different host for user avatar and channel images," +
|
||||
description = "Adds an option to use a different host for user avatar and channel images " +
|
||||
"and can fix missing images that are blocked in some countries.",
|
||||
dependencies = [
|
||||
IntegrationsPatch::class,
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
package app.revanced.patches.youtube.misc.check
|
||||
|
||||
import app.revanced.patches.shared.misc.checks.BaseCheckEnvironmentPatch
|
||||
import app.revanced.patches.youtube.misc.integrations.IntegrationsPatch
|
||||
import app.revanced.patches.youtube.shared.fingerprints.MainActivityOnCreateFingerprint
|
||||
|
||||
@Suppress("unused")
|
||||
object CheckEnvironmentPatch :
|
||||
BaseCheckEnvironmentPatch(
|
||||
mainActivityOnCreateFingerprint = MainActivityOnCreateFingerprint,
|
||||
integrationsPatch = IntegrationsPatch,
|
||||
compatiblePackages = setOf(CompatiblePackage("com.google.android.youtube")),
|
||||
)
|
||||
@@ -0,0 +1,69 @@
|
||||
package app.revanced.patches.youtube.misc.dns
|
||||
|
||||
import app.revanced.patcher.data.BytecodeContext
|
||||
import app.revanced.patcher.extensions.InstructionExtensions.addInstructions
|
||||
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.youtube.misc.integrations.IntegrationsPatch
|
||||
import app.revanced.patches.youtube.shared.fingerprints.MainActivityOnCreateFingerprint
|
||||
import app.revanced.util.resultOrThrow
|
||||
|
||||
@Patch(
|
||||
name = "Check watch history domain name resolution",
|
||||
description = "Checks if the device DNS server is preventing user watch history from being saved.",
|
||||
dependencies = [IntegrationsPatch::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",
|
||||
],
|
||||
),
|
||||
],
|
||||
)
|
||||
@Suppress("unused")
|
||||
internal object CheckWatchHistoryDomainNameResolutionPatch : BytecodePatch(
|
||||
setOf(MainActivityOnCreateFingerprint),
|
||||
) {
|
||||
private const val INTEGRATIONS_CLASS_DESCRIPTOR =
|
||||
"Lapp/revanced/integrations/youtube/patches/CheckWatchHistoryDomainNameResolutionPatch;"
|
||||
|
||||
override fun execute(context: BytecodeContext) {
|
||||
AddResourcesPatch(this::class)
|
||||
|
||||
MainActivityOnCreateFingerprint.resultOrThrow().mutableMethod.addInstructions(
|
||||
// FIXME: Insert index must be greater than the insert index used by GmsCoreSupport,
|
||||
// as both patch the same method and GmsCoreSupport check should be first,
|
||||
// but the patch does not depend on GmsCoreSupport, so it should not be possible to enforce this
|
||||
// unless a third patch is added that this patch and GmsCoreSupport depend on to manage
|
||||
// the order of the patches.
|
||||
1,
|
||||
"invoke-static/range { p0 .. p0 }, $INTEGRATIONS_CLASS_DESCRIPTOR->checkDnsResolver(Landroid/app/Activity;)V",
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -1,390 +1,11 @@
|
||||
package app.revanced.patches.youtube.misc.fix.playback
|
||||
|
||||
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.getInstructions
|
||||
import app.revanced.patcher.extensions.InstructionExtensions.replaceInstruction
|
||||
import app.revanced.patcher.extensions.or
|
||||
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.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.PreferenceScreen
|
||||
import app.revanced.patches.shared.misc.settings.preference.SwitchPreference
|
||||
import app.revanced.patches.youtube.misc.backgroundplayback.BackgroundPlaybackPatch
|
||||
import app.revanced.patches.youtube.misc.fix.playback.fingerprints.*
|
||||
import app.revanced.patches.youtube.misc.playertype.PlayerTypeHookPatch
|
||||
import app.revanced.patches.youtube.misc.settings.SettingsPatch
|
||||
import app.revanced.util.getReference
|
||||
import app.revanced.util.indexOfFirstInstructionOrThrow
|
||||
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.instruction.FiveRegisterInstruction
|
||||
import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction
|
||||
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
|
||||
|
||||
@Patch(
|
||||
name = "Spoof client",
|
||||
description = "Spoofs the client to allow video playback.",
|
||||
dependencies = [
|
||||
SettingsPatch::class,
|
||||
AddResourcesPatch::class,
|
||||
UserAgentClientSpoofPatch::class,
|
||||
// Required since iOS livestream fix partially enables background playback.
|
||||
BackgroundPlaybackPatch::class,
|
||||
PlayerTypeHookPatch::class,
|
||||
],
|
||||
compatiblePackages = [
|
||||
CompatiblePackage(
|
||||
"com.google.android.youtube",
|
||||
[
|
||||
// This patch works with these versions,
|
||||
// but the dependent background playback patch does not.
|
||||
// "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",
|
||||
],
|
||||
),
|
||||
],
|
||||
)
|
||||
@Deprecated("This patch is obsolete.", replaceWith = ReplaceWith("SpoofVideoStreamsPatch"))
|
||||
object SpoofClientPatch : BytecodePatch(
|
||||
setOf(
|
||||
// Client type spoof.
|
||||
BuildInitPlaybackRequestFingerprint,
|
||||
BuildPlayerRequestURIFingerprint,
|
||||
SetPlayerRequestClientTypeFingerprint,
|
||||
CreatePlayerRequestBodyFingerprint,
|
||||
CreatePlayerRequestBodyWithModelFingerprint,
|
||||
CreatePlayerRequestBodyWithVersionReleaseFingerprint,
|
||||
|
||||
// Player gesture config.
|
||||
PlayerGestureConfigSyntheticFingerprint,
|
||||
|
||||
// Player speed menu item.
|
||||
CreatePlaybackSpeedMenuItemFingerprint,
|
||||
|
||||
// Video qualities missing.
|
||||
BuildRequestFingerprint,
|
||||
|
||||
// Livestream audio only background playback.
|
||||
PlayerResponseModelBackgroundAudioPlaybackFingerprint,
|
||||
)
|
||||
dependencies = setOf(SpoofVideoStreamsPatch::class),
|
||||
) {
|
||||
private const val INTEGRATIONS_CLASS_DESCRIPTOR =
|
||||
"Lapp/revanced/integrations/youtube/patches/spoof/SpoofClientPatch;"
|
||||
private const val CLIENT_INFO_CLASS_DESCRIPTOR =
|
||||
"Lcom/google/protos/youtube/api/innertube/InnertubeContext\$ClientInfo;"
|
||||
private const val REQUEST_CLASS_DESCRIPTOR =
|
||||
"Lorg/chromium/net/ExperimentalUrlRequest;"
|
||||
private const val REQUEST_BUILDER_CLASS_DESCRIPTOR =
|
||||
"Lorg/chromium/net/ExperimentalUrlRequest\$Builder;"
|
||||
|
||||
override fun execute(context: BytecodeContext) {
|
||||
AddResourcesPatch(this::class)
|
||||
|
||||
SettingsPatch.PreferenceScreen.MISC.addPreferences(
|
||||
PreferenceScreen(
|
||||
key = "revanced_spoof_client_screen",
|
||||
sorting = PreferenceScreen.Sorting.UNSORTED,
|
||||
preferences = setOf(
|
||||
SwitchPreference("revanced_spoof_client"),
|
||||
SwitchPreference("revanced_spoof_client_use_ios"),
|
||||
),
|
||||
),
|
||||
)
|
||||
|
||||
// region Block /initplayback requests to fall back to /get_watch requests.
|
||||
|
||||
BuildInitPlaybackRequestFingerprint.resultOrThrow().let {
|
||||
val moveUriStringIndex = it.scanResult.patternScanResult!!.startIndex
|
||||
|
||||
it.mutableMethod.apply {
|
||||
val targetRegister = getInstruction<OneRegisterInstruction>(moveUriStringIndex).registerA
|
||||
|
||||
addInstructions(
|
||||
moveUriStringIndex + 1,
|
||||
"""
|
||||
invoke-static { v$targetRegister }, $INTEGRATIONS_CLASS_DESCRIPTOR->blockInitPlaybackRequest(Ljava/lang/String;)Ljava/lang/String;
|
||||
move-result-object v$targetRegister
|
||||
""",
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
// endregion
|
||||
|
||||
// region Block /get_watch requests to fall back to /player requests.
|
||||
|
||||
BuildPlayerRequestURIFingerprint.resultOrThrow().let {
|
||||
val invokeToStringIndex = it.scanResult.patternScanResult!!.startIndex
|
||||
|
||||
it.mutableMethod.apply {
|
||||
val uriRegister = getInstruction<FiveRegisterInstruction>(invokeToStringIndex).registerC
|
||||
|
||||
addInstructions(
|
||||
invokeToStringIndex,
|
||||
"""
|
||||
invoke-static { v$uriRegister }, $INTEGRATIONS_CLASS_DESCRIPTOR->blockGetWatchRequest(Landroid/net/Uri;)Landroid/net/Uri;
|
||||
move-result-object v$uriRegister
|
||||
""",
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
// endregion
|
||||
|
||||
// region Get field references to be used below.
|
||||
|
||||
val (clientInfoField, clientInfoClientTypeField, clientInfoClientVersionField) =
|
||||
SetPlayerRequestClientTypeFingerprint.resultOrThrow().let { result ->
|
||||
// Field in the player request object that holds the client info object.
|
||||
val clientInfoField = result.mutableMethod
|
||||
.getInstructions().find { instruction ->
|
||||
// requestMessage.clientInfo = clientInfoBuilder.build();
|
||||
instruction.opcode == Opcode.IPUT_OBJECT &&
|
||||
instruction.getReference<FieldReference>()?.type == CLIENT_INFO_CLASS_DESCRIPTOR
|
||||
}?.getReference<FieldReference>() ?: throw PatchException("Could not find clientInfoField")
|
||||
|
||||
// Client info object's client type field.
|
||||
val clientInfoClientTypeField = result.mutableMethod
|
||||
.getInstruction(result.scanResult.patternScanResult!!.endIndex)
|
||||
.getReference<FieldReference>() ?: throw PatchException("Could not find clientInfoClientTypeField")
|
||||
|
||||
// Client info object's client version field.
|
||||
val clientInfoClientVersionField = result.mutableMethod
|
||||
.getInstruction(result.scanResult.stringsScanResult!!.matches.first().index + 1)
|
||||
.getReference<FieldReference>()
|
||||
?: throw PatchException("Could not find clientInfoClientVersionField")
|
||||
|
||||
Triple(clientInfoField, clientInfoClientTypeField, clientInfoClientVersionField)
|
||||
}
|
||||
|
||||
val clientInfoClientModelField = CreatePlayerRequestBodyWithModelFingerprint.resultOrThrow().let {
|
||||
val getClientModelIndex =
|
||||
CreatePlayerRequestBodyWithModelFingerprint.indexOfBuildModelInstruction(it.method)
|
||||
|
||||
// The next IPUT_OBJECT instruction after getting the client model is setting the client model field.
|
||||
val index = it.mutableMethod.indexOfFirstInstructionOrThrow(getClientModelIndex) {
|
||||
opcode == Opcode.IPUT_OBJECT
|
||||
}
|
||||
|
||||
it.mutableMethod.getInstruction(index).getReference<FieldReference>()
|
||||
?: throw PatchException("Could not find clientInfoClientModelField")
|
||||
}
|
||||
|
||||
val clientInfoOsVersionField = CreatePlayerRequestBodyWithVersionReleaseFingerprint.resultOrThrow().let {
|
||||
val getOsVersionIndex =
|
||||
CreatePlayerRequestBodyWithVersionReleaseFingerprint.indexOfBuildVersionReleaseInstruction(it.method)
|
||||
|
||||
// The next IPUT_OBJECT instruction after getting the client os version is setting the client os version field.
|
||||
val index = it.mutableMethod.indexOfFirstInstructionOrThrow(getOsVersionIndex) {
|
||||
opcode == Opcode.IPUT_OBJECT
|
||||
}
|
||||
|
||||
it.mutableMethod.getInstruction(index).getReference<FieldReference>()
|
||||
?: throw PatchException("Could not find clientInfoOsVersionField")
|
||||
}
|
||||
|
||||
// endregion
|
||||
|
||||
// region Spoof client type for /player requests.
|
||||
|
||||
CreatePlayerRequestBodyFingerprint.resultOrThrow().let { result ->
|
||||
val setClientInfoMethodName = "patch_setClientInfo"
|
||||
val checkCastIndex = result.scanResult.patternScanResult!!.startIndex
|
||||
var clientInfoContainerClassName: String
|
||||
|
||||
result.mutableMethod.apply {
|
||||
val checkCastInstruction = getInstruction<OneRegisterInstruction>(checkCastIndex)
|
||||
val requestMessageInstanceRegister = checkCastInstruction.registerA
|
||||
clientInfoContainerClassName = checkCastInstruction.getReference<TypeReference>()!!.type
|
||||
|
||||
addInstruction(
|
||||
checkCastIndex + 1,
|
||||
"invoke-static { v$requestMessageInstanceRegister }," +
|
||||
" ${result.classDef.type}->$setClientInfoMethodName($clientInfoContainerClassName)V",
|
||||
)
|
||||
}
|
||||
|
||||
// Change client info to use the spoofed values.
|
||||
// Do this in a helper method, to remove the need of picking out multiple free registers from the hooked code.
|
||||
result.mutableClass.methods.add(
|
||||
ImmutableMethod(
|
||||
result.mutableClass.type,
|
||||
setClientInfoMethodName,
|
||||
listOf(ImmutableMethodParameter(clientInfoContainerClassName, null, "clientInfoContainer")),
|
||||
"V",
|
||||
AccessFlags.PRIVATE or AccessFlags.STATIC,
|
||||
null,
|
||||
null,
|
||||
MutableMethodImplementation(3),
|
||||
).toMutable().apply {
|
||||
addInstructions(
|
||||
"""
|
||||
invoke-static { }, $INTEGRATIONS_CLASS_DESCRIPTOR->isClientSpoofingEnabled()Z
|
||||
move-result v0
|
||||
if-eqz v0, :disabled
|
||||
|
||||
iget-object v0, p0, $clientInfoField
|
||||
|
||||
# Set client type to the spoofed value.
|
||||
iget v1, v0, $clientInfoClientTypeField
|
||||
invoke-static { v1 }, $INTEGRATIONS_CLASS_DESCRIPTOR->getClientTypeId(I)I
|
||||
move-result v1
|
||||
iput v1, v0, $clientInfoClientTypeField
|
||||
|
||||
# Set client model to the spoofed value.
|
||||
iget-object v1, v0, $clientInfoClientModelField
|
||||
invoke-static { v1 }, $INTEGRATIONS_CLASS_DESCRIPTOR->getClientModel(Ljava/lang/String;)Ljava/lang/String;
|
||||
move-result-object v1
|
||||
iput-object v1, v0, $clientInfoClientModelField
|
||||
|
||||
# Set client version to the spoofed value.
|
||||
iget-object v1, v0, $clientInfoClientVersionField
|
||||
invoke-static { v1 }, $INTEGRATIONS_CLASS_DESCRIPTOR->getClientVersion(Ljava/lang/String;)Ljava/lang/String;
|
||||
move-result-object v1
|
||||
iput-object v1, v0, $clientInfoClientVersionField
|
||||
|
||||
# Set client os version to the spoofed value.
|
||||
iget-object v1, v0, $clientInfoOsVersionField
|
||||
invoke-static { v1 }, $INTEGRATIONS_CLASS_DESCRIPTOR->getOsVersion(Ljava/lang/String;)Ljava/lang/String;
|
||||
move-result-object v1
|
||||
iput-object v1, v0, $clientInfoOsVersionField
|
||||
|
||||
:disabled
|
||||
return-void
|
||||
""",
|
||||
)
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
// endregion
|
||||
|
||||
// region Fix player gesture if spoofing to iOS.
|
||||
|
||||
PlayerGestureConfigSyntheticFingerprint.resultOrThrow().let {
|
||||
val endIndex = it.scanResult.patternScanResult!!.endIndex
|
||||
val downAndOutLandscapeAllowedIndex = endIndex - 3
|
||||
val downAndOutPortraitAllowedIndex = endIndex - 9
|
||||
|
||||
arrayOf(
|
||||
downAndOutLandscapeAllowedIndex,
|
||||
downAndOutPortraitAllowedIndex,
|
||||
).forEach { index ->
|
||||
val gestureAllowedMethod = context.toMethodWalker(it.mutableMethod)
|
||||
.nextMethod(index, true)
|
||||
.getMethod() as MutableMethod
|
||||
|
||||
gestureAllowedMethod.apply {
|
||||
val isAllowedIndex = getInstructions().lastIndex
|
||||
val isAllowed = getInstruction<OneRegisterInstruction>(isAllowedIndex).registerA
|
||||
|
||||
addInstructions(
|
||||
isAllowedIndex,
|
||||
"""
|
||||
invoke-static { v$isAllowed }, $INTEGRATIONS_CLASS_DESCRIPTOR->enablePlayerGesture(Z)Z
|
||||
move-result v$isAllowed
|
||||
""",
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// endregion
|
||||
|
||||
// region Fix livestream audio only background play if spoofing to iOS.
|
||||
// This force enables audio background playback.
|
||||
|
||||
PlayerResponseModelBackgroundAudioPlaybackFingerprint.resultOrThrow().mutableMethod.addInstructions(
|
||||
0,
|
||||
"""
|
||||
invoke-static { }, $INTEGRATIONS_CLASS_DESCRIPTOR->overrideBackgroundAudioPlayback()Z
|
||||
move-result v0
|
||||
if-eqz v0, :do_not_override
|
||||
return v0
|
||||
:do_not_override
|
||||
nop
|
||||
"""
|
||||
)
|
||||
|
||||
// endregion
|
||||
|
||||
// Fix playback speed menu item if spoofing to iOS.
|
||||
|
||||
CreatePlaybackSpeedMenuItemFingerprint.resultOrThrow().let {
|
||||
val scanResult = it.scanResult.patternScanResult!!
|
||||
if (scanResult.startIndex != 0) throw PatchException("Unexpected start index: ${scanResult.startIndex}")
|
||||
|
||||
it.mutableMethod.apply {
|
||||
// Find the conditional check if the playback speed menu item is not created.
|
||||
val shouldCreateMenuIndex =
|
||||
indexOfFirstInstructionOrThrow(scanResult.endIndex) { opcode == Opcode.IF_EQZ }
|
||||
val shouldCreateMenuRegister = getInstruction<OneRegisterInstruction>(shouldCreateMenuIndex).registerA
|
||||
|
||||
addInstructions(
|
||||
shouldCreateMenuIndex,
|
||||
"""
|
||||
invoke-static { v$shouldCreateMenuRegister }, $INTEGRATIONS_CLASS_DESCRIPTOR->forceCreatePlaybackSpeedMenu(Z)Z
|
||||
move-result v$shouldCreateMenuRegister
|
||||
""",
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
// endregion
|
||||
|
||||
// region Fix video qualities missing, if spoofing to iOS by overriding the user agent.
|
||||
|
||||
BuildRequestFingerprint.resultOrThrow().let { result ->
|
||||
result.mutableMethod.apply {
|
||||
val buildRequestIndex = getInstructions().lastIndex - 2
|
||||
val requestBuilderRegister = getInstruction<FiveRegisterInstruction>(buildRequestIndex).registerC
|
||||
|
||||
val newRequestBuilderIndex = result.scanResult.patternScanResult!!.endIndex
|
||||
val urlRegister = getInstruction<FiveRegisterInstruction>(newRequestBuilderIndex).registerD
|
||||
|
||||
// Replace "requestBuilder.build(): Request" with "overrideUserAgent(requestBuilder, url): Request".
|
||||
replaceInstruction(
|
||||
buildRequestIndex,
|
||||
"invoke-static { v$requestBuilderRegister, v$urlRegister }, " +
|
||||
"$INTEGRATIONS_CLASS_DESCRIPTOR->" +
|
||||
"overrideUserAgent(${REQUEST_BUILDER_CLASS_DESCRIPTOR}Ljava/lang/String;)" +
|
||||
REQUEST_CLASS_DESCRIPTOR
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
// endregion
|
||||
}
|
||||
}
|
||||
override fun execute(context: BytecodeContext) {}
|
||||
}
|
||||
@@ -1,239 +1,12 @@
|
||||
package app.revanced.patches.youtube.misc.fix.playback
|
||||
|
||||
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.InstructionExtensions.getInstruction
|
||||
import app.revanced.patcher.extensions.InstructionExtensions.replaceInstruction
|
||||
import app.revanced.patcher.patch.BytecodePatch
|
||||
import app.revanced.patcher.patch.annotation.Patch
|
||||
import app.revanced.patcher.util.smali.ExternalLabel
|
||||
import app.revanced.patches.all.misc.resources.AddResourcesPatch
|
||||
import app.revanced.patches.shared.misc.settings.preference.PreferenceScreen
|
||||
import app.revanced.patches.shared.misc.settings.preference.PreferenceScreen.Sorting
|
||||
import app.revanced.patches.shared.misc.settings.preference.SwitchPreference
|
||||
import app.revanced.patches.youtube.misc.fix.playback.fingerprints.*
|
||||
import app.revanced.patches.youtube.misc.playertype.PlayerTypeHookPatch
|
||||
import app.revanced.patches.youtube.misc.settings.SettingsPatch
|
||||
import app.revanced.patches.youtube.video.information.VideoInformationPatch
|
||||
import app.revanced.patches.youtube.video.playerresponse.PlayerResponseMethodHookPatch
|
||||
import app.revanced.util.exception
|
||||
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.ReferenceInstruction
|
||||
|
||||
@Patch(
|
||||
description = "Spoofs the signature to prevent playback issues.",
|
||||
dependencies = [
|
||||
SettingsPatch::class,
|
||||
PlayerTypeHookPatch::class,
|
||||
PlayerResponseMethodHookPatch::class,
|
||||
VideoInformationPatch::class,
|
||||
SpoofSignatureResourcePatch::class,
|
||||
AddResourcesPatch::class,
|
||||
],
|
||||
)
|
||||
@Deprecated("This patch will be removed in the future.")
|
||||
@Deprecated("This patch is obsolete.", replaceWith = ReplaceWith("SpoofVideoStreamsPatch"))
|
||||
object SpoofSignaturePatch : BytecodePatch(
|
||||
setOf(
|
||||
PlayerResponseModelImplGeneralFingerprint,
|
||||
PlayerResponseModelImplLiveStreamFingerprint,
|
||||
PlayerResponseModelImplRecommendedLevelFingerprint,
|
||||
StoryboardRendererSpecFingerprint,
|
||||
StoryboardRendererDecoderSpecFingerprint,
|
||||
StoryboardRendererDecoderRecommendedLevelFingerprint,
|
||||
StoryboardThumbnailParentFingerprint,
|
||||
SpoofSignaturePatchScrubbedPreviewLayoutFingerprint,
|
||||
StatsQueryParameterFingerprint,
|
||||
ParamsMapPutFingerprint,
|
||||
),
|
||||
dependencies = setOf(SpoofVideoStreamsPatch::class),
|
||||
) {
|
||||
private const val INTEGRATIONS_CLASS_DESCRIPTOR =
|
||||
"Lapp/revanced/integrations/youtube/patches/spoof/SpoofSignaturePatch;"
|
||||
|
||||
override fun execute(context: BytecodeContext) {
|
||||
AddResourcesPatch(this::class)
|
||||
|
||||
SettingsPatch.PreferenceScreen.MISC.addPreferences(
|
||||
PreferenceScreen(
|
||||
key = "revanced_spoof_signature_verification_screen",
|
||||
sorting = Sorting.UNSORTED,
|
||||
preferences = setOf(
|
||||
SwitchPreference("revanced_spoof_signature_verification_enabled"),
|
||||
SwitchPreference("revanced_spoof_signature_in_feed_enabled"),
|
||||
SwitchPreference("revanced_spoof_storyboard"),
|
||||
),
|
||||
),
|
||||
)
|
||||
|
||||
// Hook the player parameters.
|
||||
PlayerResponseMethodHookPatch += PlayerResponseMethodHookPatch.Hook.ProtoBufferParameter(
|
||||
"$INTEGRATIONS_CLASS_DESCRIPTOR->spoofParameter(Ljava/lang/String;Ljava/lang/String;Z)Ljava/lang/String;",
|
||||
)
|
||||
|
||||
// Force the seekbar time and chapters to always show up.
|
||||
// This is used if the storyboard spec fetch fails, for viewing paid videos,
|
||||
// or if storyboard spoofing is turned off.
|
||||
StoryboardThumbnailParentFingerprint.result?.classDef?.let { classDef ->
|
||||
StoryboardThumbnailFingerprint.also {
|
||||
it.resolve(
|
||||
context,
|
||||
classDef,
|
||||
)
|
||||
}.result?.let {
|
||||
val endIndex = it.scanResult.patternScanResult!!.endIndex
|
||||
// Replace existing instruction to preserve control flow label.
|
||||
// The replaced return instruction always returns false
|
||||
// (it is the 'no thumbnails found' control path),
|
||||
// so there is no need to pass the existing return value to integrations.
|
||||
it.mutableMethod.replaceInstruction(
|
||||
endIndex,
|
||||
"""
|
||||
invoke-static {}, $INTEGRATIONS_CLASS_DESCRIPTOR->getSeekbarThumbnailOverrideValue()Z
|
||||
""",
|
||||
)
|
||||
// Since this is end of the method must replace one line then add the rest.
|
||||
it.mutableMethod.addInstructions(
|
||||
endIndex + 1,
|
||||
"""
|
||||
move-result v0
|
||||
return v0
|
||||
""",
|
||||
)
|
||||
} ?: throw StoryboardThumbnailFingerprint.exception
|
||||
}
|
||||
|
||||
// If storyboard spoofing is turned off, then hide the empty seekbar thumbnail view.
|
||||
SpoofSignaturePatchScrubbedPreviewLayoutFingerprint.result?.apply {
|
||||
val endIndex = scanResult.patternScanResult!!.endIndex
|
||||
mutableMethod.apply {
|
||||
val imageViewFieldName = getInstruction<ReferenceInstruction>(endIndex).reference
|
||||
addInstructions(
|
||||
implementation!!.instructions.lastIndex,
|
||||
"""
|
||||
iget-object v0, p0, $imageViewFieldName # copy imageview field to a register
|
||||
invoke-static {v0}, $INTEGRATIONS_CLASS_DESCRIPTOR->seekbarImageViewCreated(Landroid/widget/ImageView;)V
|
||||
""",
|
||||
)
|
||||
}
|
||||
} ?: throw SpoofSignaturePatchScrubbedPreviewLayoutFingerprint.exception
|
||||
|
||||
/**
|
||||
* Hook StoryBoard renderer url
|
||||
*/
|
||||
arrayOf(
|
||||
PlayerResponseModelImplGeneralFingerprint,
|
||||
PlayerResponseModelImplLiveStreamFingerprint,
|
||||
).forEach { fingerprint ->
|
||||
fingerprint.result?.let {
|
||||
it.mutableMethod.apply {
|
||||
val getStoryBoardIndex = it.scanResult.patternScanResult!!.endIndex
|
||||
val getStoryBoardRegister =
|
||||
getInstruction<OneRegisterInstruction>(getStoryBoardIndex).registerA
|
||||
|
||||
addInstructions(
|
||||
getStoryBoardIndex,
|
||||
"""
|
||||
invoke-static { v$getStoryBoardRegister }, $INTEGRATIONS_CLASS_DESCRIPTOR->getStoryboardRendererSpec(Ljava/lang/String;)Ljava/lang/String;
|
||||
move-result-object v$getStoryBoardRegister
|
||||
""",
|
||||
)
|
||||
}
|
||||
} ?: throw fingerprint.exception
|
||||
}
|
||||
|
||||
// Hook recommended seekbar thumbnails quality level.
|
||||
StoryboardRendererDecoderRecommendedLevelFingerprint.result?.let {
|
||||
val moveOriginalRecommendedValueIndex = it.scanResult.patternScanResult!!.endIndex
|
||||
val originalValueRegister = it.mutableMethod
|
||||
.getInstruction<OneRegisterInstruction>(moveOriginalRecommendedValueIndex).registerA
|
||||
|
||||
it.mutableMethod.addInstructions(
|
||||
moveOriginalRecommendedValueIndex + 1,
|
||||
"""
|
||||
invoke-static { v$originalValueRegister }, $INTEGRATIONS_CLASS_DESCRIPTOR->getRecommendedLevel(I)I
|
||||
move-result v$originalValueRegister
|
||||
""",
|
||||
)
|
||||
} ?: throw StoryboardRendererDecoderRecommendedLevelFingerprint.exception
|
||||
|
||||
// Hook the recommended precise seeking thumbnails quality level.
|
||||
PlayerResponseModelImplRecommendedLevelFingerprint.result?.let {
|
||||
it.mutableMethod.apply {
|
||||
val moveOriginalRecommendedValueIndex = it.scanResult.patternScanResult!!.endIndex
|
||||
val originalValueRegister =
|
||||
getInstruction<OneRegisterInstruction>(moveOriginalRecommendedValueIndex).registerA
|
||||
|
||||
addInstructions(
|
||||
moveOriginalRecommendedValueIndex,
|
||||
"""
|
||||
invoke-static { v$originalValueRegister }, $INTEGRATIONS_CLASS_DESCRIPTOR->getRecommendedLevel(I)I
|
||||
move-result v$originalValueRegister
|
||||
""",
|
||||
)
|
||||
}
|
||||
} ?: throw PlayerResponseModelImplRecommendedLevelFingerprint.exception
|
||||
|
||||
StoryboardRendererSpecFingerprint.result?.let {
|
||||
it.mutableMethod.apply {
|
||||
val storyBoardUrlParams = 0
|
||||
|
||||
addInstructionsWithLabels(
|
||||
0,
|
||||
"""
|
||||
if-nez p$storyBoardUrlParams, :ignore
|
||||
invoke-static { p$storyBoardUrlParams }, $INTEGRATIONS_CLASS_DESCRIPTOR->getStoryboardRendererSpec(Ljava/lang/String;)Ljava/lang/String;
|
||||
move-result-object p$storyBoardUrlParams
|
||||
""",
|
||||
ExternalLabel("ignore", getInstruction(0)),
|
||||
)
|
||||
}
|
||||
} ?: throw StoryboardRendererSpecFingerprint.exception
|
||||
|
||||
// Hook the seekbar thumbnail decoder and use a NULL spec for live streams.
|
||||
StoryboardRendererDecoderSpecFingerprint.result?.let {
|
||||
val storyBoardUrlIndex = it.scanResult.patternScanResult!!.startIndex + 1
|
||||
val storyboardUrlRegister =
|
||||
it.mutableMethod.getInstruction<OneRegisterInstruction>(storyBoardUrlIndex).registerA
|
||||
|
||||
it.mutableMethod.addInstructions(
|
||||
storyBoardUrlIndex + 1,
|
||||
"""
|
||||
invoke-static { v$storyboardUrlRegister }, $INTEGRATIONS_CLASS_DESCRIPTOR->getStoryboardDecoderRendererSpec(Ljava/lang/String;)Ljava/lang/String;
|
||||
move-result-object v$storyboardUrlRegister
|
||||
""",
|
||||
)
|
||||
} ?: throw StoryboardRendererDecoderSpecFingerprint.exception
|
||||
|
||||
// Fix stats not being tracked.
|
||||
// Due to signature spoofing "adformat" is present in query parameters made for /stats requests,
|
||||
// even though, for regular videos, it should not be.
|
||||
// This breaks stats tracking.
|
||||
// Replace the ad parameter with the video parameter in the query parameters.
|
||||
StatsQueryParameterFingerprint.result?.let {
|
||||
val putMethod = ParamsMapPutFingerprint.result?.method?.toString()
|
||||
?: throw ParamsMapPutFingerprint.exception
|
||||
|
||||
it.mutableMethod.apply {
|
||||
val adParamIndex = it.scanResult.stringsScanResult!!.matches.first().index
|
||||
val videoParamIndex = adParamIndex + 3
|
||||
|
||||
// Replace the ad parameter with the video parameter.
|
||||
replaceInstruction(adParamIndex, getInstruction(videoParamIndex))
|
||||
|
||||
// Call paramsMap.put instead of paramsMap.putIfNotExist
|
||||
// because the key is already present in the map.
|
||||
val putAdParamIndex = adParamIndex + 1
|
||||
val putIfKeyNotExistsInstruction = getInstruction<FiveRegisterInstruction>(putAdParamIndex)
|
||||
replaceInstruction(
|
||||
putAdParamIndex,
|
||||
"invoke-virtual { " +
|
||||
"v${putIfKeyNotExistsInstruction.registerC}, " +
|
||||
"v${putIfKeyNotExistsInstruction.registerD}, " +
|
||||
"v${putIfKeyNotExistsInstruction.registerE} }, " +
|
||||
putMethod,
|
||||
)
|
||||
}
|
||||
} ?: throw StatsQueryParameterFingerprint.exception
|
||||
}
|
||||
override fun execute(context: BytecodeContext) {}
|
||||
}
|
||||
|
||||
|
||||
@@ -2,18 +2,8 @@ package app.revanced.patches.youtube.misc.fix.playback
|
||||
|
||||
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])
|
||||
@Deprecated("This patch will be removed in the future.")
|
||||
object SpoofSignatureResourcePatch : ResourcePatch() {
|
||||
internal var scrubbedPreviewThumbnailResourceId: Long = -1
|
||||
|
||||
override fun execute(context: ResourceContext) {
|
||||
scrubbedPreviewThumbnailResourceId = ResourceMappingPatch[
|
||||
"id",
|
||||
"thumbnail",
|
||||
]
|
||||
}
|
||||
override fun execute(context: ResourceContext) {}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,285 @@
|
||||
package app.revanced.patches.youtube.misc.fix.playback
|
||||
|
||||
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.addInstructionsWithLabels
|
||||
import app.revanced.patcher.extensions.InstructionExtensions.getInstruction
|
||||
import app.revanced.patcher.extensions.InstructionExtensions.getInstructions
|
||||
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.all.misc.resources.AddResourcesPatch
|
||||
import app.revanced.patches.shared.misc.settings.preference.ListPreference
|
||||
import app.revanced.patches.shared.misc.settings.preference.NonInteractivePreference
|
||||
import app.revanced.patches.shared.misc.settings.preference.PreferenceScreen
|
||||
import app.revanced.patches.shared.misc.settings.preference.SwitchPreference
|
||||
import app.revanced.patches.youtube.misc.fix.playback.fingerprints.BuildInitPlaybackRequestFingerprint
|
||||
import app.revanced.patches.youtube.misc.fix.playback.fingerprints.BuildMediaDataSourceFingerprint
|
||||
import app.revanced.patches.youtube.misc.fix.playback.fingerprints.BuildPlayerRequestURIFingerprint
|
||||
import app.revanced.patches.youtube.misc.fix.playback.fingerprints.BuildRequestFingerprint
|
||||
import app.revanced.patches.youtube.misc.fix.playback.fingerprints.CreateStreamingDataFingerprint
|
||||
import app.revanced.patches.youtube.misc.fix.playback.fingerprints.ProtobufClassParseByteBufferFingerprint
|
||||
import app.revanced.patches.youtube.misc.settings.SettingsPatch
|
||||
import app.revanced.util.getReference
|
||||
import app.revanced.util.indexOfFirstInstructionOrThrow
|
||||
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.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.FieldReference
|
||||
import com.android.tools.smali.dexlib2.iface.reference.MethodReference
|
||||
import com.android.tools.smali.dexlib2.immutable.ImmutableMethod
|
||||
import com.android.tools.smali.dexlib2.immutable.ImmutableMethodParameter
|
||||
|
||||
@Patch(
|
||||
name = "Spoof video streams",
|
||||
description = "Spoofs the client video streams to allow video playback.",
|
||||
dependencies = [
|
||||
SettingsPatch::class,
|
||||
AddResourcesPatch::class,
|
||||
UserAgentClientSpoofPatch::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",
|
||||
],
|
||||
),
|
||||
],
|
||||
)
|
||||
object SpoofVideoStreamsPatch : BytecodePatch(
|
||||
setOf(
|
||||
BuildInitPlaybackRequestFingerprint,
|
||||
BuildPlayerRequestURIFingerprint,
|
||||
CreateStreamingDataFingerprint,
|
||||
BuildMediaDataSourceFingerprint,
|
||||
BuildRequestFingerprint,
|
||||
ProtobufClassParseByteBufferFingerprint,
|
||||
),
|
||||
) {
|
||||
private const val INTEGRATIONS_CLASS_DESCRIPTOR =
|
||||
"Lapp/revanced/integrations/youtube/patches/spoof/SpoofVideoStreamsPatch;"
|
||||
|
||||
override fun execute(context: BytecodeContext) {
|
||||
AddResourcesPatch(this::class)
|
||||
|
||||
SettingsPatch.PreferenceScreen.MISC.addPreferences(
|
||||
PreferenceScreen(
|
||||
key = "revanced_spoof_video_streams_screen",
|
||||
sorting = PreferenceScreen.Sorting.UNSORTED,
|
||||
preferences = setOf(
|
||||
SwitchPreference("revanced_spoof_video_streams"),
|
||||
ListPreference(
|
||||
"revanced_spoof_video_streams_client",
|
||||
summaryKey = null
|
||||
),
|
||||
SwitchPreference(
|
||||
"revanced_spoof_video_streams_ios_force_avc",
|
||||
tag = "app.revanced.integrations.youtube.settings.preference.ForceAVCSpoofingPreference",
|
||||
),
|
||||
NonInteractivePreference("revanced_spoof_video_streams_about_android_vr"),
|
||||
NonInteractivePreference("revanced_spoof_video_streams_about_ios"),
|
||||
),
|
||||
),
|
||||
)
|
||||
|
||||
// region Block /initplayback requests to fall back to /get_watch requests.
|
||||
|
||||
BuildInitPlaybackRequestFingerprint.resultOrThrow().let {
|
||||
val moveUriStringIndex = it.scanResult.patternScanResult!!.startIndex
|
||||
|
||||
it.mutableMethod.apply {
|
||||
val targetRegister = getInstruction<OneRegisterInstruction>(moveUriStringIndex).registerA
|
||||
|
||||
addInstructions(
|
||||
moveUriStringIndex + 1,
|
||||
"""
|
||||
invoke-static { v$targetRegister }, $INTEGRATIONS_CLASS_DESCRIPTOR->blockInitPlaybackRequest(Ljava/lang/String;)Ljava/lang/String;
|
||||
move-result-object v$targetRegister
|
||||
""",
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
// endregion
|
||||
|
||||
// region Block /get_watch requests to fall back to /player requests.
|
||||
|
||||
BuildPlayerRequestURIFingerprint.resultOrThrow().let {
|
||||
val invokeToStringIndex = it.scanResult.patternScanResult!!.startIndex
|
||||
|
||||
it.mutableMethod.apply {
|
||||
val uriRegister = getInstruction<FiveRegisterInstruction>(invokeToStringIndex).registerC
|
||||
|
||||
addInstructions(
|
||||
invokeToStringIndex,
|
||||
"""
|
||||
invoke-static { v$uriRegister }, $INTEGRATIONS_CLASS_DESCRIPTOR->blockGetWatchRequest(Landroid/net/Uri;)Landroid/net/Uri;
|
||||
move-result-object v$uriRegister
|
||||
""",
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
// endregion
|
||||
|
||||
// region Get replacement streams at player requests.
|
||||
|
||||
BuildRequestFingerprint.resultOrThrow().mutableMethod.apply {
|
||||
val newRequestBuilderIndex = indexOfFirstInstructionOrThrow {
|
||||
opcode == Opcode.INVOKE_VIRTUAL &&
|
||||
getReference<MethodReference>()?.name == "newUrlRequestBuilder"
|
||||
}
|
||||
val urlRegister = getInstruction<FiveRegisterInstruction>(newRequestBuilderIndex).registerD
|
||||
val freeRegister = getInstruction<OneRegisterInstruction>(newRequestBuilderIndex + 1).registerA
|
||||
|
||||
addInstructions(
|
||||
newRequestBuilderIndex,
|
||||
"""
|
||||
move-object v$freeRegister, p1
|
||||
invoke-static { v$urlRegister, v$freeRegister }, $INTEGRATIONS_CLASS_DESCRIPTOR->fetchStreams(Ljava/lang/String;Ljava/util/Map;)V
|
||||
""",
|
||||
)
|
||||
}
|
||||
|
||||
// endregion
|
||||
|
||||
// region Replace the streaming data with the replacement streams.
|
||||
|
||||
CreateStreamingDataFingerprint.resultOrThrow().let { result ->
|
||||
result.mutableMethod.apply {
|
||||
val setStreamDataMethodName = "patch_setStreamingData"
|
||||
val resultMethodType = result.mutableClass.type
|
||||
val videoDetailsIndex = result.scanResult.patternScanResult!!.endIndex
|
||||
val videoDetailsRegister = getInstruction<TwoRegisterInstruction>(videoDetailsIndex).registerA
|
||||
val videoDetailsClass = getInstruction(videoDetailsIndex).getReference<FieldReference>()!!.type
|
||||
|
||||
addInstruction(
|
||||
videoDetailsIndex + 1,
|
||||
"invoke-direct { p0, v$videoDetailsRegister }, " +
|
||||
"$resultMethodType->$setStreamDataMethodName($videoDetailsClass)V",
|
||||
)
|
||||
|
||||
val protobufClass = ProtobufClassParseByteBufferFingerprint.resultOrThrow().mutableMethod.definingClass
|
||||
val setStreamingDataIndex = result.scanResult.patternScanResult!!.startIndex
|
||||
|
||||
val playerProtoClass = getInstruction(setStreamingDataIndex + 1)
|
||||
.getReference<FieldReference>()!!.definingClass
|
||||
|
||||
val setStreamingDataField = getInstruction(setStreamingDataIndex).getReference<FieldReference>()
|
||||
|
||||
val getStreamingDataField = getInstruction(
|
||||
indexOfFirstInstructionOrThrow {
|
||||
opcode == Opcode.IGET_OBJECT && getReference<FieldReference>()?.definingClass == playerProtoClass
|
||||
}
|
||||
).getReference<FieldReference>()
|
||||
|
||||
// Use a helper method to avoid the need of picking out multiple free registers from the hooked code.
|
||||
result.mutableClass.methods.add(
|
||||
ImmutableMethod(
|
||||
resultMethodType,
|
||||
setStreamDataMethodName,
|
||||
listOf(ImmutableMethodParameter(videoDetailsClass, null, "videoDetails")),
|
||||
"V",
|
||||
AccessFlags.PRIVATE or AccessFlags.FINAL,
|
||||
null,
|
||||
null,
|
||||
MutableMethodImplementation(9),
|
||||
).toMutable().apply {
|
||||
addInstructionsWithLabels(
|
||||
0,
|
||||
"""
|
||||
invoke-static { }, $INTEGRATIONS_CLASS_DESCRIPTOR->isSpoofingEnabled()Z
|
||||
move-result v0
|
||||
if-eqz v0, :disabled
|
||||
|
||||
# Get video id.
|
||||
iget-object v2, p1, $videoDetailsClass->c:Ljava/lang/String;
|
||||
if-eqz v2, :disabled
|
||||
|
||||
# Get streaming data.
|
||||
invoke-static { v2 }, $INTEGRATIONS_CLASS_DESCRIPTOR->getStreamingData(Ljava/lang/String;)Ljava/nio/ByteBuffer;
|
||||
move-result-object v3
|
||||
if-eqz v3, :disabled
|
||||
|
||||
# Parse streaming data.
|
||||
sget-object v4, $playerProtoClass->a:$playerProtoClass
|
||||
invoke-static { v4, v3 }, $protobufClass->parseFrom(${protobufClass}Ljava/nio/ByteBuffer;)$protobufClass
|
||||
move-result-object v5
|
||||
check-cast v5, $playerProtoClass
|
||||
|
||||
# Set streaming data.
|
||||
iget-object v6, v5, $getStreamingDataField
|
||||
if-eqz v6, :disabled
|
||||
iput-object v6, p0, $setStreamingDataField
|
||||
|
||||
:disabled
|
||||
return-void
|
||||
""",
|
||||
)
|
||||
},
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
// endregion
|
||||
|
||||
// region Remove /videoplayback request body to fix playback.
|
||||
// This is needed when using iOS client as streaming data source.
|
||||
|
||||
BuildMediaDataSourceFingerprint.resultOrThrow().let {
|
||||
it.mutableMethod.apply {
|
||||
val targetIndex = getInstructions().lastIndex
|
||||
|
||||
// Instructions are added just before the method returns,
|
||||
// so there's no concern of clobbering in-use registers.
|
||||
addInstructions(
|
||||
targetIndex,
|
||||
"""
|
||||
# Field a: Stream uri.
|
||||
# Field c: Http method.
|
||||
# Field d: Post data.
|
||||
move-object v0, p0 # method has over 15 registers and must copy p0 to a lower register.
|
||||
iget-object v1, v0, $definingClass->a:Landroid/net/Uri;
|
||||
iget v2, v0, $definingClass->c:I
|
||||
iget-object v3, v0, $definingClass->d:[B
|
||||
invoke-static { v1, v2, v3 }, $INTEGRATIONS_CLASS_DESCRIPTOR->removeVideoPlaybackPostBody(Landroid/net/Uri;I[B)[B
|
||||
move-result-object v1
|
||||
iput-object v1, v0, $definingClass->d:[B
|
||||
""",
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
// endregion
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
package app.revanced.patches.youtube.misc.fix.playback.fingerprints
|
||||
|
||||
import app.revanced.patcher.extensions.or
|
||||
import app.revanced.patcher.fingerprint.MethodFingerprint
|
||||
import com.android.tools.smali.dexlib2.AccessFlags
|
||||
|
||||
internal object BuildMediaDataSourceFingerprint : MethodFingerprint(
|
||||
accessFlags = AccessFlags.PUBLIC or AccessFlags.CONSTRUCTOR,
|
||||
returnType = "V",
|
||||
parameters = listOf(
|
||||
"Landroid/net/Uri;",
|
||||
"J",
|
||||
"I",
|
||||
"[B",
|
||||
"Ljava/util/Map;",
|
||||
"J",
|
||||
"J",
|
||||
"Ljava/lang/String;",
|
||||
"I",
|
||||
"Ljava/lang/Object;"
|
||||
)
|
||||
)
|
||||
@@ -3,13 +3,34 @@ package app.revanced.patches.youtube.misc.fix.playback.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 BuildRequestFingerprint : MethodFingerprint(
|
||||
accessFlags = AccessFlags.PUBLIC or AccessFlags.STATIC,
|
||||
returnType = "Lorg/chromium/net/UrlRequest;",
|
||||
opcodes = listOf(
|
||||
Opcode.INVOKE_DIRECT,
|
||||
Opcode.INVOKE_VIRTUAL
|
||||
)
|
||||
customFingerprint = { methodDef, _ ->
|
||||
// Different targets have slightly different parameters
|
||||
|
||||
// Earlier targets have parameters:
|
||||
//L
|
||||
//Ljava/util/Map;
|
||||
//[B
|
||||
//L
|
||||
//L
|
||||
//L
|
||||
//Lorg/chromium/net/UrlRequest$Callback;
|
||||
|
||||
// Later targets have parameters:
|
||||
//L
|
||||
//Ljava/util/Map;
|
||||
//[B
|
||||
//L
|
||||
//L
|
||||
//L
|
||||
//Lorg/chromium/net/UrlRequest\$Callback;
|
||||
//L
|
||||
|
||||
val parameterTypes = methodDef.parameterTypes
|
||||
(parameterTypes.size == 7 || parameterTypes.size == 8)
|
||||
&& parameterTypes[1] == "Ljava/util/Map;" // URL headers.
|
||||
}
|
||||
)
|
||||
|
||||
@@ -1,34 +0,0 @@
|
||||
package app.revanced.patches.youtube.misc.fix.playback.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 CreatePlaybackSpeedMenuItemFingerprint : MethodFingerprint(
|
||||
accessFlags = AccessFlags.PUBLIC or AccessFlags.FINAL,
|
||||
returnType = "V",
|
||||
opcodes = listOf(
|
||||
Opcode.IGET_OBJECT, // First instruction of the method
|
||||
Opcode.IGET_OBJECT,
|
||||
Opcode.IGET_OBJECT,
|
||||
Opcode.CONST_4,
|
||||
Opcode.IF_EQZ,
|
||||
Opcode.INVOKE_INTERFACE,
|
||||
null // MOVE_RESULT or MOVE_RESULT_OBJECT, Return value controls the creation of the playback speed menu item.
|
||||
),
|
||||
// 19.01 and earlier is missing the second parameter.
|
||||
// Since this fingerprint is somewhat weak, work around by checking for both method parameter signatures.
|
||||
customFingerprint = custom@{ methodDef, _ ->
|
||||
// 19.01 and earlier parameters are: "[L"
|
||||
// 19.02+ parameters are "[L", "F"
|
||||
val parameterTypes = methodDef.parameterTypes
|
||||
val firstParameter = parameterTypes.firstOrNull()
|
||||
|
||||
if (firstParameter == null || !firstParameter.startsWith("[L")) {
|
||||
return@custom false
|
||||
}
|
||||
|
||||
parameterTypes.size == 1 || (parameterTypes.size == 2 && parameterTypes[1] == "F")
|
||||
}
|
||||
)
|
||||
@@ -1,15 +0,0 @@
|
||||
package app.revanced.patches.youtube.misc.fix.playback.fingerprints
|
||||
|
||||
import app.revanced.patcher.fingerprint.MethodFingerprint
|
||||
import com.android.tools.smali.dexlib2.Opcode
|
||||
|
||||
internal object CreatePlayerRequestBodyFingerprint : MethodFingerprint(
|
||||
returnType = "V",
|
||||
parameters = listOf("L"),
|
||||
opcodes = listOf(
|
||||
Opcode.CHECK_CAST,
|
||||
Opcode.IGET,
|
||||
Opcode.AND_INT_LIT16,
|
||||
),
|
||||
strings = listOf("ms"),
|
||||
)
|
||||
@@ -1,31 +0,0 @@
|
||||
package app.revanced.patches.youtube.misc.fix.playback.fingerprints
|
||||
|
||||
import app.revanced.patcher.extensions.or
|
||||
import app.revanced.patcher.fingerprint.MethodFingerprint
|
||||
import app.revanced.patches.youtube.misc.fix.playback.fingerprints.CreatePlayerRequestBodyWithModelFingerprint.indexOfBuildModelInstruction
|
||||
import app.revanced.util.containsWideLiteralInstructionValue
|
||||
import app.revanced.util.getReference
|
||||
import app.revanced.util.indexOfFirstInstruction
|
||||
import com.android.tools.smali.dexlib2.AccessFlags
|
||||
import com.android.tools.smali.dexlib2.iface.Method
|
||||
import com.android.tools.smali.dexlib2.iface.reference.FieldReference
|
||||
|
||||
internal object CreatePlayerRequestBodyWithModelFingerprint : MethodFingerprint(
|
||||
returnType = "L",
|
||||
accessFlags = AccessFlags.PUBLIC or AccessFlags.FINAL,
|
||||
parameters = listOf(),
|
||||
customFingerprint = { methodDef, _ ->
|
||||
methodDef.containsWideLiteralInstructionValue(1073741824) &&
|
||||
indexOfBuildModelInstruction(methodDef) >= 0
|
||||
},
|
||||
) {
|
||||
fun indexOfBuildModelInstruction(methodDef: Method) =
|
||||
methodDef.indexOfFirstInstruction {
|
||||
val reference = getReference<FieldReference>()
|
||||
reference?.definingClass == "Landroid/os/Build;" &&
|
||||
reference.name == "MODEL" &&
|
||||
reference.type == "Ljava/lang/String;"
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,31 +0,0 @@
|
||||
package app.revanced.patches.youtube.misc.fix.playback.fingerprints
|
||||
|
||||
import app.revanced.patcher.extensions.or
|
||||
import app.revanced.patcher.fingerprint.MethodFingerprint
|
||||
import app.revanced.patches.youtube.misc.fix.playback.fingerprints.CreatePlayerRequestBodyWithVersionReleaseFingerprint.indexOfBuildVersionReleaseInstruction
|
||||
import app.revanced.util.containsWideLiteralInstructionValue
|
||||
import app.revanced.util.getReference
|
||||
import app.revanced.util.indexOfFirstInstruction
|
||||
import com.android.tools.smali.dexlib2.AccessFlags
|
||||
import com.android.tools.smali.dexlib2.iface.Method
|
||||
import com.android.tools.smali.dexlib2.iface.reference.FieldReference
|
||||
|
||||
internal object CreatePlayerRequestBodyWithVersionReleaseFingerprint : MethodFingerprint(
|
||||
returnType = "L",
|
||||
accessFlags = AccessFlags.PUBLIC or AccessFlags.FINAL,
|
||||
parameters = listOf(),
|
||||
customFingerprint = { methodDef, _ ->
|
||||
methodDef.containsWideLiteralInstructionValue(1073741824) &&
|
||||
indexOfBuildVersionReleaseInstruction(methodDef) >= 0
|
||||
},
|
||||
) {
|
||||
fun indexOfBuildVersionReleaseInstruction(methodDef: Method) =
|
||||
methodDef.indexOfFirstInstruction {
|
||||
val reference = getReference<FieldReference>()
|
||||
reference?.definingClass == "Landroid/os/Build\$VERSION;" &&
|
||||
reference.name == "RELEASE" &&
|
||||
reference.type == "Ljava/lang/String;"
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,24 @@
|
||||
package app.revanced.patches.youtube.misc.fix.playback.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 CreateStreamingDataFingerprint : MethodFingerprint(
|
||||
accessFlags = AccessFlags.PUBLIC or AccessFlags.CONSTRUCTOR,
|
||||
returnType = "V",
|
||||
parameters = listOf("L"),
|
||||
opcodes = listOf(
|
||||
Opcode.IPUT_OBJECT,
|
||||
Opcode.IGET_OBJECT,
|
||||
Opcode.IF_NEZ,
|
||||
Opcode.SGET_OBJECT,
|
||||
Opcode.IPUT_OBJECT
|
||||
),
|
||||
customFingerprint = { methodDef, classDef ->
|
||||
classDef.fields.any { field ->
|
||||
field.name == "a" && field.type.endsWith("/StreamingDataOuterClass\$StreamingData;")
|
||||
}
|
||||
},
|
||||
)
|
||||
@@ -1,25 +0,0 @@
|
||||
package app.revanced.patches.youtube.misc.fix.playback.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
|
||||
|
||||
@Deprecated("Fingerprint is obsolete and will be deleted soon")
|
||||
internal object ParamsMapPutFingerprint : MethodFingerprint(
|
||||
returnType = "V",
|
||||
accessFlags = AccessFlags.PUBLIC or AccessFlags.FINAL,
|
||||
parameters = listOf(
|
||||
"Ljava/lang/String;",
|
||||
"Ljava/lang/String;",
|
||||
),
|
||||
opcodes = listOf(
|
||||
Opcode.CONST_4,
|
||||
Opcode.CONST_4,
|
||||
Opcode.CONST_4,
|
||||
Opcode.MOVE_OBJECT,
|
||||
Opcode.MOVE_OBJECT,
|
||||
Opcode.MOVE_OBJECT,
|
||||
Opcode.INVOKE_DIRECT_RANGE,
|
||||
),
|
||||
)
|
||||
@@ -1,49 +0,0 @@
|
||||
package app.revanced.patches.youtube.misc.fix.playback.fingerprints
|
||||
|
||||
import app.revanced.patcher.extensions.or
|
||||
import app.revanced.patcher.fingerprint.MethodFingerprint
|
||||
import app.revanced.util.getReference
|
||||
import app.revanced.util.indexOfFirstInstruction
|
||||
import com.android.tools.smali.dexlib2.AccessFlags
|
||||
import com.android.tools.smali.dexlib2.Opcode
|
||||
import com.android.tools.smali.dexlib2.iface.Method
|
||||
import com.android.tools.smali.dexlib2.iface.reference.MethodReference
|
||||
|
||||
internal object PlayerGestureConfigSyntheticFingerprint : MethodFingerprint(
|
||||
returnType = "V",
|
||||
accessFlags = AccessFlags.PUBLIC or AccessFlags.FINAL,
|
||||
parameters = listOf("Ljava/lang/Object;"),
|
||||
opcodes = listOf(
|
||||
Opcode.SGET_OBJECT,
|
||||
Opcode.INVOKE_VIRTUAL,
|
||||
Opcode.MOVE_RESULT,
|
||||
Opcode.IF_EQZ,
|
||||
Opcode.IF_EQZ,
|
||||
Opcode.IGET_OBJECT,
|
||||
Opcode.INVOKE_INTERFACE,
|
||||
Opcode.MOVE_RESULT_OBJECT,
|
||||
Opcode.INVOKE_VIRTUAL, // playerGestureConfig.downAndOutLandscapeAllowed.
|
||||
Opcode.MOVE_RESULT,
|
||||
Opcode.CHECK_CAST,
|
||||
Opcode.IPUT_BOOLEAN,
|
||||
Opcode.INVOKE_INTERFACE,
|
||||
Opcode.MOVE_RESULT_OBJECT,
|
||||
Opcode.INVOKE_VIRTUAL, // playerGestureConfig.downAndOutPortraitAllowed.
|
||||
Opcode.MOVE_RESULT,
|
||||
Opcode.IPUT_BOOLEAN,
|
||||
Opcode.RETURN_VOID,
|
||||
),
|
||||
customFingerprint = { methodDef, classDef ->
|
||||
fun indexOfDownAndOutAllowedInstruction(methodDef: Method) =
|
||||
methodDef.indexOfFirstInstruction {
|
||||
val reference = getReference<MethodReference>()
|
||||
reference?.definingClass == "Lcom/google/android/libraries/youtube/innertube/model/media/PlayerConfigModel;" &&
|
||||
reference.parameterTypes.isEmpty() &&
|
||||
reference.returnType == "Z"
|
||||
}
|
||||
|
||||
// This method is always called "a" because this kind of class always has a single method.
|
||||
methodDef.name == "a" && classDef.methods.count() == 2 &&
|
||||
indexOfDownAndOutAllowedInstruction(methodDef) >= 0
|
||||
},
|
||||
)
|
||||
@@ -1,25 +0,0 @@
|
||||
package app.revanced.patches.youtube.misc.fix.playback.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 PlayerResponseModelBackgroundAudioPlaybackFingerprint : MethodFingerprint(
|
||||
returnType = "Z",
|
||||
accessFlags = AccessFlags.PUBLIC or AccessFlags.STATIC,
|
||||
parameters = listOf("Lcom/google/android/libraries/youtube/innertube/model/player/PlayerResponseModel;"),
|
||||
opcodes = listOf(
|
||||
Opcode.CONST_4,
|
||||
Opcode.IF_EQZ,
|
||||
Opcode.INVOKE_INTERFACE,
|
||||
Opcode.MOVE_RESULT_OBJECT,
|
||||
Opcode.INVOKE_VIRTUAL,
|
||||
Opcode.MOVE_RESULT,
|
||||
Opcode.IF_NEZ,
|
||||
Opcode.GOTO,
|
||||
Opcode.RETURN,
|
||||
null, // Opcode.CONST_4 or Opcode.MOVE
|
||||
Opcode.RETURN,
|
||||
)
|
||||
)
|
||||
@@ -1,24 +0,0 @@
|
||||
package app.revanced.patches.youtube.misc.fix.playback.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
|
||||
|
||||
@Deprecated("Fingerprint is obsolete and will be deleted soon")
|
||||
internal object PlayerResponseModelImplGeneralFingerprint : MethodFingerprint(
|
||||
returnType = "Ljava/lang/String;",
|
||||
accessFlags = AccessFlags.PUBLIC or AccessFlags.FINAL,
|
||||
parameters = emptyList(),
|
||||
opcodes = listOf(
|
||||
Opcode.RETURN_OBJECT,
|
||||
Opcode.CONST_4,
|
||||
Opcode.RETURN_OBJECT,
|
||||
),
|
||||
customFingerprint = handler@{ methodDef, _ ->
|
||||
if (!methodDef.definingClass.endsWith("/PlayerResponseModelImpl;")) return@handler false
|
||||
|
||||
methodDef.containsWideLiteralInstructionValue(55735497)
|
||||
},
|
||||
)
|
||||
@@ -1,24 +0,0 @@
|
||||
package app.revanced.patches.youtube.misc.fix.playback.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
|
||||
|
||||
@Deprecated("Fingerprint is obsolete and will be deleted soon")
|
||||
internal object PlayerResponseModelImplLiveStreamFingerprint : MethodFingerprint(
|
||||
returnType = "Ljava/lang/String;",
|
||||
accessFlags = AccessFlags.PUBLIC or AccessFlags.FINAL,
|
||||
parameters = emptyList(),
|
||||
opcodes = listOf(
|
||||
Opcode.RETURN_OBJECT,
|
||||
Opcode.CONST_4,
|
||||
Opcode.RETURN_OBJECT,
|
||||
),
|
||||
customFingerprint = handler@{ methodDef, _ ->
|
||||
if (!methodDef.definingClass.endsWith("/PlayerResponseModelImpl;")) return@handler false
|
||||
|
||||
methodDef.containsWideLiteralInstructionValue(70276274)
|
||||
},
|
||||
)
|
||||
@@ -1,24 +0,0 @@
|
||||
package app.revanced.patches.youtube.misc.fix.playback.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
|
||||
|
||||
@Deprecated("Fingerprint is obsolete and will be deleted soon")
|
||||
internal object PlayerResponseModelImplRecommendedLevelFingerprint : MethodFingerprint(
|
||||
returnType = "I",
|
||||
accessFlags = AccessFlags.PUBLIC or AccessFlags.FINAL,
|
||||
parameters = emptyList(),
|
||||
opcodes = listOf(
|
||||
Opcode.SGET_OBJECT,
|
||||
Opcode.IGET,
|
||||
Opcode.RETURN,
|
||||
),
|
||||
customFingerprint = handler@{ methodDef, _ ->
|
||||
if (!methodDef.definingClass.endsWith("/PlayerResponseModelImpl;")) return@handler false
|
||||
|
||||
methodDef.containsWideLiteralInstructionValue(55735497)
|
||||
},
|
||||
)
|
||||
@@ -0,0 +1,19 @@
|
||||
package app.revanced.patches.youtube.misc.fix.playback.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 ProtobufClassParseByteBufferFingerprint : MethodFingerprint(
|
||||
accessFlags = AccessFlags.PROTECTED or AccessFlags.STATIC,
|
||||
parameters = listOf("L", "Ljava/nio/ByteBuffer;"),
|
||||
returnType = "L",
|
||||
opcodes = listOf(
|
||||
Opcode.SGET_OBJECT,
|
||||
Opcode.INVOKE_STATIC,
|
||||
Opcode.MOVE_RESULT_OBJECT,
|
||||
Opcode.RETURN_OBJECT,
|
||||
),
|
||||
customFingerprint = { methodDef, _ -> methodDef.name == "parseFrom" },
|
||||
)
|
||||
@@ -1,13 +0,0 @@
|
||||
package app.revanced.patches.youtube.misc.fix.playback.fingerprints
|
||||
|
||||
import app.revanced.util.patch.LiteralValueFingerprint
|
||||
import com.android.tools.smali.dexlib2.Opcode
|
||||
|
||||
internal object SetPlayerRequestClientTypeFingerprint : LiteralValueFingerprint(
|
||||
opcodes = listOf(
|
||||
Opcode.IGET,
|
||||
Opcode.IPUT, // Sets ClientInfo.clientId.
|
||||
),
|
||||
strings = listOf("10.29"),
|
||||
literalSupplier = { 134217728 }
|
||||
)
|
||||
@@ -1,28 +0,0 @@
|
||||
package app.revanced.patches.youtube.misc.fix.playback.fingerprints
|
||||
|
||||
import app.revanced.patcher.extensions.or
|
||||
import app.revanced.patches.youtube.misc.fix.playback.SpoofSignatureResourcePatch
|
||||
import app.revanced.util.patch.LiteralValueFingerprint
|
||||
import com.android.tools.smali.dexlib2.AccessFlags
|
||||
import com.android.tools.smali.dexlib2.Opcode
|
||||
|
||||
@Deprecated("Fingerprint is obsolete and will be deleted soon")
|
||||
internal object SpoofSignaturePatchScrubbedPreviewLayoutFingerprint : LiteralValueFingerprint(
|
||||
accessFlags = AccessFlags.PRIVATE or AccessFlags.FINAL,
|
||||
returnType = "V",
|
||||
parameters = listOf("Landroid/content/Context;", "Landroid/util/AttributeSet;", "I", "I"),
|
||||
opcodes = listOf(
|
||||
Opcode.INVOKE_STATIC,
|
||||
Opcode.MOVE_RESULT_OBJECT,
|
||||
Opcode.INVOKE_VIRTUAL,
|
||||
Opcode.MOVE_RESULT,
|
||||
Opcode.INVOKE_VIRTUAL,
|
||||
Opcode.CONST,
|
||||
Opcode.INVOKE_VIRTUAL,
|
||||
Opcode.MOVE_RESULT_OBJECT,
|
||||
Opcode.CHECK_CAST,
|
||||
Opcode.IPUT_OBJECT, // preview imageview
|
||||
),
|
||||
// This resource is used in ~ 40 different locations, but this method has a distinct list of parameters to match to.
|
||||
literalSupplier = { SpoofSignatureResourcePatch.scrubbedPreviewThumbnailResourceId },
|
||||
)
|
||||
@@ -1,8 +0,0 @@
|
||||
package app.revanced.patches.youtube.misc.fix.playback.fingerprints
|
||||
|
||||
import app.revanced.patcher.fingerprint.MethodFingerprint
|
||||
|
||||
@Deprecated("Fingerprint is obsolete and will be deleted soon")
|
||||
internal object StatsQueryParameterFingerprint : MethodFingerprint(
|
||||
strings = listOf("adunit"),
|
||||
)
|
||||
@@ -1,24 +0,0 @@
|
||||
package app.revanced.patches.youtube.misc.fix.playback.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
|
||||
|
||||
/**
|
||||
* Resolves to the same method as [StoryboardRendererDecoderSpecFingerprint].
|
||||
*/
|
||||
@Deprecated("Fingerprint is obsolete and will be deleted soon")
|
||||
internal object StoryboardRendererDecoderRecommendedLevelFingerprint : MethodFingerprint(
|
||||
returnType = "V",
|
||||
accessFlags = AccessFlags.PUBLIC or AccessFlags.FINAL,
|
||||
parameters = listOf("Lcom/google/android/libraries/youtube/innertube/model/player/PlayerResponseModel;"),
|
||||
opcodes = listOf(
|
||||
Opcode.INVOKE_INTERFACE,
|
||||
Opcode.MOVE_RESULT_OBJECT,
|
||||
Opcode.IPUT_OBJECT,
|
||||
Opcode.INVOKE_INTERFACE,
|
||||
Opcode.MOVE_RESULT,
|
||||
),
|
||||
strings = listOf("#-1#"),
|
||||
)
|
||||
@@ -1,24 +0,0 @@
|
||||
package app.revanced.patches.youtube.misc.fix.playback.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
|
||||
|
||||
/**
|
||||
* Resolves to the same method as [StoryboardRendererDecoderRecommendedLevelFingerprint].
|
||||
*/
|
||||
@Deprecated("Fingerprint is obsolete and will be deleted soon")
|
||||
internal object StoryboardRendererDecoderSpecFingerprint : MethodFingerprint(
|
||||
returnType = "V",
|
||||
accessFlags = AccessFlags.PUBLIC or AccessFlags.FINAL,
|
||||
parameters = listOf("Lcom/google/android/libraries/youtube/innertube/model/player/PlayerResponseModel;"),
|
||||
opcodes = listOf(
|
||||
Opcode.INVOKE_INTERFACE, // First instruction of the method.
|
||||
Opcode.MOVE_RESULT_OBJECT,
|
||||
Opcode.CONST_4,
|
||||
Opcode.CONST_4,
|
||||
Opcode.IF_NEZ,
|
||||
),
|
||||
strings = listOf("#-1#"),
|
||||
)
|
||||
@@ -1,13 +0,0 @@
|
||||
package app.revanced.patches.youtube.misc.fix.playback.fingerprints
|
||||
|
||||
import app.revanced.patcher.extensions.or
|
||||
import app.revanced.patcher.fingerprint.MethodFingerprint
|
||||
import com.android.tools.smali.dexlib2.AccessFlags
|
||||
|
||||
@Deprecated("Fingerprint is obsolete and will be deleted soon")
|
||||
internal object StoryboardRendererSpecFingerprint : MethodFingerprint(
|
||||
accessFlags = AccessFlags.PUBLIC or AccessFlags.STATIC,
|
||||
returnType = "L",
|
||||
parameters = listOf("Ljava/lang/String;", "J"),
|
||||
strings = listOf("\\|"),
|
||||
)
|
||||
@@ -1,24 +0,0 @@
|
||||
package app.revanced.patches.youtube.misc.fix.playback.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
|
||||
|
||||
/**
|
||||
* Resolves using the class found in [StoryboardThumbnailParentFingerprint].
|
||||
*/
|
||||
@Deprecated("Fingerprint is obsolete and will be deleted soon")
|
||||
internal object StoryboardThumbnailFingerprint : MethodFingerprint(
|
||||
accessFlags = AccessFlags.PUBLIC or AccessFlags.FINAL,
|
||||
returnType = "Z",
|
||||
parameters = listOf(),
|
||||
opcodes = listOf(
|
||||
Opcode.MOVE_RESULT,
|
||||
Opcode.IF_GTZ,
|
||||
Opcode.GOTO,
|
||||
Opcode.CONST_4,
|
||||
Opcode.RETURN,
|
||||
Opcode.RETURN, // Last instruction of method.
|
||||
),
|
||||
)
|
||||
@@ -1,18 +0,0 @@
|
||||
package app.revanced.patches.youtube.misc.fix.playback.fingerprints
|
||||
|
||||
import app.revanced.patcher.extensions.or
|
||||
import app.revanced.patcher.fingerprint.MethodFingerprint
|
||||
import com.android.tools.smali.dexlib2.AccessFlags
|
||||
|
||||
/**
|
||||
* Here lies code that creates the seekbar thumbnails.
|
||||
*
|
||||
* An additional change here might force the thumbnails to be created,
|
||||
* or possibly a change somewhere else (maybe involving YouTube 18.23.35 class `hte`)
|
||||
*/
|
||||
@Deprecated("Fingerprint is obsolete and will be deleted soon")
|
||||
internal object StoryboardThumbnailParentFingerprint : MethodFingerprint(
|
||||
accessFlags = AccessFlags.PUBLIC or AccessFlags.FINAL,
|
||||
returnType = "Landroid/graphics/Bitmap;",
|
||||
strings = listOf("Storyboard regionDecoder.decodeRegion exception - "),
|
||||
)
|
||||
@@ -32,12 +32,11 @@ object GmsCoreSupportPatch : BaseGmsCoreSupportPatch(
|
||||
CompatiblePackage(
|
||||
"com.google.android.youtube",
|
||||
setOf(
|
||||
// Patch supports these versions but ClientSpoof does not.
|
||||
// "18.37.36",
|
||||
// "18.38.44",
|
||||
// "18.43.45",
|
||||
// "18.44.41",
|
||||
// "18.45.43",
|
||||
"18.37.36",
|
||||
"18.38.44",
|
||||
"18.43.45",
|
||||
"18.44.41",
|
||||
"18.45.43",
|
||||
"18.48.39",
|
||||
"18.49.37",
|
||||
"19.01.34",
|
||||
|
||||
@@ -15,6 +15,7 @@ import app.revanced.patches.shared.misc.settings.preference.IntentPreference
|
||||
import app.revanced.patches.shared.misc.settings.preference.NonInteractivePreference
|
||||
import app.revanced.patches.shared.misc.settings.preference.PreferenceScreen.Sorting
|
||||
import app.revanced.patches.shared.misc.settings.preference.TextPreference
|
||||
import app.revanced.patches.youtube.misc.check.CheckEnvironmentPatch
|
||||
import app.revanced.patches.youtube.misc.integrations.IntegrationsPatch
|
||||
import app.revanced.patches.youtube.misc.settings.fingerprints.LicenseActivityOnCreateFingerprint
|
||||
import app.revanced.patches.youtube.misc.settings.fingerprints.SetThemeFingerprint
|
||||
@@ -30,6 +31,9 @@ import java.io.Closeable
|
||||
IntegrationsPatch::class,
|
||||
SettingsResourcePatch::class,
|
||||
AddResourcesPatch::class,
|
||||
// Currently there is no easy way to make a mandatory patch,
|
||||
// so for now this is a dependent of this patch.
|
||||
CheckEnvironmentPatch::class,
|
||||
],
|
||||
)
|
||||
object SettingsPatch :
|
||||
|
||||
@@ -28,8 +28,6 @@ object SettingsResourcePatch : BaseSettingsResourcePatch(
|
||||
override fun execute(context: ResourceContext) {
|
||||
super.execute(context)
|
||||
|
||||
AddResourcesPatch(this::class)
|
||||
|
||||
// Used for a fingerprint from SettingsPatch.
|
||||
appearanceStringId = ResourceMappingPatch["string", "app_theme_appearance_dark"]
|
||||
|
||||
|
||||
@@ -32,15 +32,16 @@ This is because Crowdin requires temporarily flattening this file and removing t
|
||||
-->
|
||||
<resources>
|
||||
<app id="shared">
|
||||
<patch id="misc.checks.BaseCheckEnvironmentPatch">
|
||||
</patch>
|
||||
<patch id="misc.settings.BaseSettingsResourcePatch">
|
||||
<!-- Settings about dialog. -->
|
||||
</patch>
|
||||
<patch id="misc.gms.BaseGmsCoreSupportResourcePatch">
|
||||
<!-- Translations of this should not be longer than the original English text, otherwise the text can be clipped and not entirely shown. -->
|
||||
</patch>
|
||||
</app>
|
||||
<app id="youtube">
|
||||
<patch id="misc.settings.SettingsResourcePatch">
|
||||
</patch>
|
||||
<patch id="misc.settings.SettingsPatch">
|
||||
</patch>
|
||||
<patch id="misc.debugging.DebuggingPatch">
|
||||
@@ -57,7 +58,7 @@ This is because Crowdin requires temporarily flattening this file and removing t
|
||||
<!-- 'Component path builder strings' is the technical name for identifying the Litho UI layout items to hide. This is an advanced feature and most users will never use this. -->
|
||||
<!-- For localization it is preferred, but not required, if 'LeBlanc' is replaced with a localized name or a familiar word that has upper case letters in the middle of the word.
|
||||
This is because keywords can be in any language, and showing an example in the localized script helps convey this. -->
|
||||
<!-- Translations of this should not be longer than the original English text, otherwise the text can be clipped and not entirely shown. -->
|
||||
<!-- Translations _must_ use a localized example. For languages that do not use spaces between words (Chinese, Japanese, etc) the English AI example should be used since no localized examples exist. Or if using machine translations, or if nobody wants to think of a localized example, then the English 'ai' example should be left as-is. -->
|
||||
<!-- Translations of this should not be longer than the original English text, otherwise the text can be clipped and not entirely shown. -->
|
||||
</patch>
|
||||
<patch id="ad.general.HideAdsResourcePatch">
|
||||
@@ -171,8 +172,6 @@ This is because Crowdin requires temporarily flattening this file and removing t
|
||||
<patch id="layout.sponsorblock.SponsorBlockResourcePatch">
|
||||
<!-- Translations should use language similar to 'revanced_ryd_compact_layout_title' -->
|
||||
<!-- Toast shown if network connection times out. Translations of this should not be longer than the original English or the text can be clipped and not entirely shown. -->
|
||||
<!-- Do not rearrange the (hour):(minute):second) time format operators here.
|
||||
YT shows the same seekbar time format for all languages, and this string is confirming the segment time as it appears in the seekbar. -->
|
||||
<!-- Shown in the settings preferences, and translations can be any text length. -->
|
||||
</patch>
|
||||
<patch id="layout.spoofappversion.SpoofAppVersionPatch">
|
||||
@@ -206,6 +205,8 @@ This is because Crowdin requires temporarily flattening this file and removing t
|
||||
</patch>
|
||||
<patch id="misc.announcements.AnnouncementsPatch">
|
||||
</patch>
|
||||
<patch id="misc.dns.CheckWatchHistoryDomainNameResolutionPatch">
|
||||
</patch>
|
||||
<patch id="misc.autorepeat.AutoRepeatPatch">
|
||||
</patch>
|
||||
<patch id="misc.dimensions.spoof.SpoofDeviceDimensionsPatch">
|
||||
@@ -232,10 +233,7 @@ This is because Crowdin requires temporarily flattening this file and removing t
|
||||
</patch>
|
||||
<patch id="interaction.seekbar.EnableSlideToSeekPatch">
|
||||
</patch>
|
||||
<patch id="misc.fix.playback.SpoofClientPatch">
|
||||
</patch>
|
||||
<!-- This patch is no longer used, these strings are not in use, and these strings will be deleted in the future. -->
|
||||
<patch id="misc.fix.playback.SpoofSignaturePatch">
|
||||
<patch id="misc.fix.playback.SpoofVideoStreamsPatch">
|
||||
</patch>
|
||||
<!-- This patch is no longer used and these strings will soon be deleted. -->
|
||||
<patch id="video.hdrbrightness.HDRBrightnessPatch">
|
||||
|
||||
@@ -32,15 +32,16 @@ This is because Crowdin requires temporarily flattening this file and removing t
|
||||
-->
|
||||
<resources>
|
||||
<app id="shared">
|
||||
<patch id="misc.checks.BaseCheckEnvironmentPatch">
|
||||
</patch>
|
||||
<patch id="misc.settings.BaseSettingsResourcePatch">
|
||||
<!-- Settings about dialog. -->
|
||||
</patch>
|
||||
<patch id="misc.gms.BaseGmsCoreSupportResourcePatch">
|
||||
<!-- Translations of this should not be longer than the original English text, otherwise the text can be clipped and not entirely shown. -->
|
||||
</patch>
|
||||
</app>
|
||||
<app id="youtube">
|
||||
<patch id="misc.settings.SettingsResourcePatch">
|
||||
</patch>
|
||||
<patch id="misc.settings.SettingsPatch">
|
||||
</patch>
|
||||
<patch id="misc.debugging.DebuggingPatch">
|
||||
@@ -57,7 +58,7 @@ This is because Crowdin requires temporarily flattening this file and removing t
|
||||
<!-- 'Component path builder strings' is the technical name for identifying the Litho UI layout items to hide. This is an advanced feature and most users will never use this. -->
|
||||
<!-- For localization it is preferred, but not required, if 'LeBlanc' is replaced with a localized name or a familiar word that has upper case letters in the middle of the word.
|
||||
This is because keywords can be in any language, and showing an example in the localized script helps convey this. -->
|
||||
<!-- Translations of this should not be longer than the original English text, otherwise the text can be clipped and not entirely shown. -->
|
||||
<!-- Translations _must_ use a localized example. For languages that do not use spaces between words (Chinese, Japanese, etc) the English AI example should be used since no localized examples exist. Or if using machine translations, or if nobody wants to think of a localized example, then the English 'ai' example should be left as-is. -->
|
||||
<!-- Translations of this should not be longer than the original English text, otherwise the text can be clipped and not entirely shown. -->
|
||||
</patch>
|
||||
<patch id="ad.general.HideAdsResourcePatch">
|
||||
@@ -171,8 +172,6 @@ This is because Crowdin requires temporarily flattening this file and removing t
|
||||
<patch id="layout.sponsorblock.SponsorBlockResourcePatch">
|
||||
<!-- Translations should use language similar to 'revanced_ryd_compact_layout_title' -->
|
||||
<!-- Toast shown if network connection times out. Translations of this should not be longer than the original English or the text can be clipped and not entirely shown. -->
|
||||
<!-- Do not rearrange the (hour):(minute):second) time format operators here.
|
||||
YT shows the same seekbar time format for all languages, and this string is confirming the segment time as it appears in the seekbar. -->
|
||||
<!-- Shown in the settings preferences, and translations can be any text length. -->
|
||||
</patch>
|
||||
<patch id="layout.spoofappversion.SpoofAppVersionPatch">
|
||||
@@ -206,6 +205,8 @@ This is because Crowdin requires temporarily flattening this file and removing t
|
||||
</patch>
|
||||
<patch id="misc.announcements.AnnouncementsPatch">
|
||||
</patch>
|
||||
<patch id="misc.dns.CheckWatchHistoryDomainNameResolutionPatch">
|
||||
</patch>
|
||||
<patch id="misc.autorepeat.AutoRepeatPatch">
|
||||
</patch>
|
||||
<patch id="misc.dimensions.spoof.SpoofDeviceDimensionsPatch">
|
||||
@@ -232,10 +233,7 @@ This is because Crowdin requires temporarily flattening this file and removing t
|
||||
</patch>
|
||||
<patch id="interaction.seekbar.EnableSlideToSeekPatch">
|
||||
</patch>
|
||||
<patch id="misc.fix.playback.SpoofClientPatch">
|
||||
</patch>
|
||||
<!-- This patch is no longer used, these strings are not in use, and these strings will be deleted in the future. -->
|
||||
<patch id="misc.fix.playback.SpoofSignaturePatch">
|
||||
<patch id="misc.fix.playback.SpoofVideoStreamsPatch">
|
||||
</patch>
|
||||
<!-- This patch is no longer used and these strings will soon be deleted. -->
|
||||
<patch id="video.hdrbrightness.HDRBrightnessPatch">
|
||||
|
||||
@@ -32,6 +32,17 @@ This is because Crowdin requires temporarily flattening this file and removing t
|
||||
-->
|
||||
<resources>
|
||||
<app id="shared">
|
||||
<patch id="misc.checks.BaseCheckEnvironmentPatch">
|
||||
<string name="revanced_check_environment_failed_title">فشلت عمليات التحقق</string>
|
||||
<string name="revanced_check_environment_dialog_open_official_source_button">فتح الموقع الرسمي</string>
|
||||
<string name="revanced_check_environment_dialog_ignore_button">تجاهل</string>
|
||||
<string name="revanced_check_environment_failed_message"><h5>لا يبدو أن هذا التطبيق قد تم تعديله من قبلك.</h5><br>قد لا يعمل هذا التطبيق بشكل صحيح، <b>قد يكون ضارًا أو حتى خطيرًا للاستخدام</b>.<br><br>تشير هذه الفحوصات إلى أن هذا التطبيق تم تعديله مسبقًا أو تم الحصول عليه من شخص آخر:<br><br><small>%1$s</small><br>يوصى بشدة بـ <b>إلغاء تثبيت هذا التطبيق وتعديله بنفسك</b> للتأكد من أنك تستخدم تطبيقًا معتمدًا وآمنًا.<p><br>في حالة تجاهل هذا التحذير، سيتم عرضه مرتين فقط.</string>
|
||||
<string name="revanced_check_environment_not_same_patching_device">تم تعديله على جهاز مختلف</string>
|
||||
<string name="revanced_check_environment_manager_not_expected_installer">لم يتم تثبيته بواسطة ReVanced Manager</string>
|
||||
<string name="revanced_check_environment_not_near_patch_time">تم تعديله قبل أكثر من 10 دقائق</string>
|
||||
<string name="revanced_check_environment_not_near_patch_time_days">تم التعديل منذ %s يوم</string>
|
||||
<string name="revanced_check_environment_not_near_patch_time_invalid">تاريخ إنشاء APK تالف</string>
|
||||
</patch>
|
||||
<patch id="misc.settings.BaseSettingsResourcePatch">
|
||||
<string name="revanced_settings_confirm_user_dialog_title">هل ترغب في المتابعة؟</string>
|
||||
<string name="revanced_settings_reset">إعادة التعيين</string>
|
||||
@@ -42,6 +53,14 @@ This is because Crowdin requires temporarily flattening this file and removing t
|
||||
<string name="revanced_settings_import_reset">إعادة تعيين إعدادات ReVanced إلى الوضع الافتراضي</string>
|
||||
<string name="revanced_settings_import_success">تم استيراد %d إعدادات</string>
|
||||
<string name="revanced_settings_import_failure_parse">فشل الاستيراد: %s</string>
|
||||
<string name="revanced_pref_import_export_title">استيراد / تصدير</string>
|
||||
<string name="revanced_pref_import_export_summary">استيراد / تصدير إعدادات ReVanced</string>
|
||||
<!-- Settings about dialog. -->
|
||||
<string name="revanced_settings_about_links_body">أنت تستخدم إصدار ReVanced Patches <i>%s</i></string>
|
||||
<string name="revanced_settings_about_links_dev_header">ملاحظة</string>
|
||||
<string name="revanced_settings_about_links_dev_body">هذا الإصدار هو إصدار مسبق، وقد تواجه مشاكل غير متوقعة</string>
|
||||
<string name="revanced_settings_about_links_header">الروابط الرسمية</string>
|
||||
<string name="revanced_settings_about_links_donate">تبرع</string>
|
||||
</patch>
|
||||
<patch id="misc.gms.BaseGmsCoreSupportResourcePatch">
|
||||
<!-- Translations of this should not be longer than the original English text, otherwise the text can be clipped and not entirely shown. -->
|
||||
@@ -54,14 +73,6 @@ This is because Crowdin requires temporarily flattening this file and removing t
|
||||
</patch>
|
||||
</app>
|
||||
<app id="youtube">
|
||||
<patch id="misc.settings.SettingsResourcePatch">
|
||||
<string name="revanced_settings_about_links_body">أنت تستخدم إصدار ReVanced Patches <i>%s</i></string>
|
||||
<string name="revanced_settings_about_links_dev_header">ملاحظة</string>
|
||||
<string name="revanced_settings_about_links_dev_body">هذا الإصدار هو إصدار مسبق، وقد تواجه مشاكل غير متوقعة</string>
|
||||
<string name="revanced_settings_about_links_header">الروابط الرسمية</string>
|
||||
<string name="revanced_pref_import_export_title">استيراد / تصدير</string>
|
||||
<string name="revanced_pref_import_export_summary">استيراد / تصدير إعدادات ReVanced</string>
|
||||
</patch>
|
||||
<patch id="misc.settings.SettingsPatch">
|
||||
<string name="revanced_settings_screen_00_about_title">لمحة</string>
|
||||
<string name="revanced_settings_screen_01_ads_title">الإعلانات</string>
|
||||
@@ -242,14 +253,18 @@ This is because Crowdin requires temporarily flattening this file and removing t
|
||||
<string name="revanced_hide_keyword_content_phrases_title">الكلمات المفتاحية المراد إخفاؤها</string>
|
||||
<!-- For localization it is preferred, but not required, if 'LeBlanc' is replaced with a localized name or a familiar word that has upper case letters in the middle of the word.
|
||||
This is because keywords can be in any language, and showing an example in the localized script helps convey this. -->
|
||||
<string name="revanced_hide_keyword_content_phrases_summary">الكلمات المفتاحية والعبارات المراد إخفاؤها، مفصولة بأسطر جديد\n\nالكلمات التي تحتوي على أحرف كبيرة في الوسط يجب إدخالها مع التغليف (مثل: iPhone, TikTok, Leblanc)</string>
|
||||
<string name="revanced_hide_keyword_content_phrases_summary">الكلمات والعبارات الرئيسية التي يجب إخفاؤها، مفصولة بسطر جديد\n\nالكلمات الرئيسية يمكن أن تكون أسماء قنوات أو أي نص يظهر في عناوين الفيديو\n\nيجب إدخال الكلمات التي تحتوي على أحرف كبيرة في الوسط بإستخدام الأحرف الكبيرة (مثال: iPhone، TikTok، LeBlanc)</string>
|
||||
<string name="revanced_hide_keyword_content_about_title">حول تصفية الكلمات المفتاحية</string>
|
||||
<string name="revanced_hide_keyword_content_about_summary">الصفحة الرئيسية/الاشتراك/نتائج البحث يتم تصفيتها لإخفاء المحتوى الذي يطابق عبارات الكلمات المفتاحية\n\nالتقييد\n• بعض المقاطع القصيرة قد لا تكون مخفية\n• بعض مكونات واجهة المستخدم قد لا تكون مخفية\n• البحث عن كلمة رئيسية قد لا يظهر أي نتائج</string>
|
||||
<string name="revanced_hide_keyword_content_about_summary">الصفحة الرئيسية/الاشتراكات/نتائج الإشتراك/يتم تصفية نتائج البحث لإخفاء المحتوى الذي يتطابق مع عبارات الكلمات الرئيسية\n\nالقيود\n• لا يمكن إخفاء فيديوهات Shorts بواسطة اسم القناة\n• قد لا تكون بعض مكونات واجهة المستخدم مخفية\n• قد لا تظهر نتائج بحث عن كلمة رئيسية</string>
|
||||
<string name="revanced_hide_keyword_content_about_whole_words_title">مطابقة الكلمات بأكملها</string>
|
||||
<!-- Translations _must_ use a localized example. For languages that do not use spaces between words (Chinese, Japanese, etc) the English AI example should be used since no localized examples exist. Or if using machine translations, or if nobody wants to think of a localized example, then the English 'ai' example should be left as-is. -->
|
||||
<string name="revanced_hide_keyword_content_about_whole_words_summary">سيؤدي وضع علامة اقتباس مزدوجة حول كلمة رئيسية/عبارة إلى منع التطابقات الجزئية لعناوين الفيديو وأسماء القنوات.<br><br>على سبيل المثال،<br><b>\"ai\"</b> سيخفي الفيديو: <b>How does AI work?</b><br>ولكن لن يخفي: <b>What does fair use mean?</b></string>
|
||||
<!-- Translations of this should not be longer than the original English text, otherwise the text can be clipped and not entirely shown. -->
|
||||
<string name="revanced_hide_keyword_toast_invalid_common">الكلمة المفتاحية غير صالحة. لا يمكن استخدام: \'%s\' كعامل تصفية</string>
|
||||
<!-- Translations of this should not be longer than the original English text, otherwise the text can be clipped and not entirely shown. -->
|
||||
<string name="revanced_hide_keyword_toast_invalid_length">الكلمة المفتاحية غير صالحة. \'%1$s\' أقل من %2$d حرفًا</string>
|
||||
<string name="revanced_hide_keyword_toast_invalid_broad">الكلمة الرئيسية \'%s\' سوف تخفي جميع الفيديوهات</string>
|
||||
<string name="revanced_hide_keyword_toast_invalid_common">لا يمكن استخدام الكلمة الرئيسية: %s</string>
|
||||
<string name="revanced_hide_keyword_toast_invalid_common_whole_word_required">إضافة اقتباسات لاستخدام الكلمة الرئيسية: %s</string>
|
||||
<string name="revanced_hide_keyword_toast_invalid_conflicting">الكلمة الرئيسية لها بيانات متضاربة: %s</string>
|
||||
<string name="revanced_hide_keyword_toast_invalid_length">الكلمة الرئيسية قصيرة جدًا وتتطلب اقتباسات: %s</string>
|
||||
<string name="revanced_hide_keyword_toast_invalid_broad">الكلمة الرئيسية سوف تخفي جميع الفيديوهات: %s</string>
|
||||
</patch>
|
||||
<patch id="ad.general.HideAdsResourcePatch">
|
||||
<string name="revanced_hide_general_ads_title">إخفاء الإعلانات العامة</string>
|
||||
@@ -615,6 +630,9 @@ This is because Crowdin requires temporarily flattening this file and removing t
|
||||
<string name="revanced_hide_shorts_save_sound_button_title">إخفاء حفظ الصوت إلى زر قائمة التشغيل</string>
|
||||
<string name="revanced_hide_shorts_save_sound_button_summary_on">تم إخفاء حفظ الصوت في قائمة التشغيل</string>
|
||||
<string name="revanced_hide_shorts_save_sound_button_summary_off">يتم عرض حفظ الصوت في قائمة التشغيل</string>
|
||||
<string name="revanced_hide_shorts_use_this_sound_button_title">إخفاء زر استخدام هذا الصوت</string>
|
||||
<string name="revanced_hide_shorts_use_this_sound_button_summary_on">تم إخفاء زر استخدام هذا الصوت</string>
|
||||
<string name="revanced_hide_shorts_use_this_sound_button_summary_off">يتم عرض زر استخدام هذا الصوت</string>
|
||||
<string name="revanced_hide_shorts_search_suggestions_title">إخفاء اقتراحات البحث</string>
|
||||
<string name="revanced_hide_shorts_search_suggestions_summary_on">تم إخفاء اقتراحات البحث</string>
|
||||
<string name="revanced_hide_shorts_search_suggestions_summary_off">يتم عرض اقتراحات البحث</string>
|
||||
@@ -678,7 +696,6 @@ This is because Crowdin requires temporarily flattening this file and removing t
|
||||
<string name="revanced_player_overlay_opacity_invalid_toast">شفافية واجهة المشغل يجب أن تكون بين 0-100</string>
|
||||
</patch>
|
||||
<patch id="layout.returnyoutubedislike.ReturnYouTubeDislikeResourcePatch">
|
||||
<string name="revanced_ryd_video_likes_hidden_by_video_owner">مخفي</string>
|
||||
<!-- Toast shown if network connection times out. Translations of this should not be longer than the original English or the text can be clipped and not entirely shown. -->
|
||||
<string name="revanced_ryd_failure_connection_timeout">لم يعجبني غير متاح مؤقتًا (انتهت مهلة API)</string>
|
||||
<string name="revanced_ryd_failure_connection_status_code">لم يعجبني غير متاح (الحالة %d)</string>
|
||||
@@ -774,6 +791,7 @@ This is because Crowdin requires temporarily flattening this file and removing t
|
||||
<string name="revanced_sb_general_skipcount_sum_off">تم تعطيل تتبع مرات التخطي</string>
|
||||
<string name="revanced_sb_general_min_duration">الحد الأدنى لمدة المقطع</string>
|
||||
<string name="revanced_sb_general_min_duration_sum">لن يتم عرض المقاطع الأقصر من هذه القيمة (بالثواني) أو تخطيها</string>
|
||||
<string name="revanced_sb_general_min_duration_invalid">المدة الزمنية غير صالحة</string>
|
||||
<string name="revanced_sb_general_uuid">معرف المستخدم الفريد الخاص بك</string>
|
||||
<string name="revanced_sb_general_uuid_sum">يجب أن يبقى هذا خاصًا. انه مثل كلمة المرور ولا ينبغي مشاركته مع أي شخص. إذا كان شخص ما يملك هذا، فيمكنه انتحال شخصيتك</string>
|
||||
<string name="revanced_sb_general_uuid_invalid">يجب أن يكون معرف المستخدم الخاص 30 حرفًا على الأقل</string>
|
||||
@@ -874,8 +892,6 @@ This is because Crowdin requires temporarily flattening this file and removing t
|
||||
<string name="revanced_sb_new_segment_time_start">الوقت الذي يبدأ عنده المقطع</string>
|
||||
<string name="revanced_sb_new_segment_time_end">الوقت الذي ينتهي عنده المقطع</string>
|
||||
<string name="revanced_sb_new_segment_confirm_title">هل الأوقات صحيحة؟</string>
|
||||
<!-- Do not rearrange the (hour):(minute):second) time format operators here.
|
||||
YT shows the same seekbar time format for all languages, and this string is confirming the segment time as it appears in the seekbar. -->
|
||||
<string name="revanced_sb_new_segment_confirm_content">المقطع من\n\n%1$s\nto\n%2$s\n\n(%3$s)\n\nReady to جاهز للإرسال؟</string>
|
||||
<string name="revanced_sb_new_segment_start_is_before_end">يجب أن تكون البداية قبل النهاية</string>
|
||||
<string name="revanced_sb_new_segment_mark_locations_first">ضع علامة على موقعين في شريط الوقت أولًا</string>
|
||||
@@ -894,6 +910,7 @@ This is because Crowdin requires temporarily flattening this file and removing t
|
||||
<string name="revanced_sb_stats_username_changed">تم تغيير اسم المستخدم بنجاح</string>
|
||||
<string name="revanced_sb_stats_reputation">سمعتك هي <b>%.2f</b></string>
|
||||
<string name="revanced_sb_stats_submissions">لقد أنشأت <b>%s</b> مقطع</string>
|
||||
<string name="revanced_sb_stats_submissions_sum">اضغط هنا لعرض المقاطع الخاصة بك</string>
|
||||
<string name="revanced_sb_stats_saved_zero">متصدرين SponsorBlock</string>
|
||||
<string name="revanced_sb_stats_saved">لقد قمت بحفظ الناس من <b>%s</b> مقطع</string>
|
||||
<string name="revanced_sb_stats_saved_sum_zero">اضغط هنا لرؤية الإحصائيات العالمية وأبرز المساهمين</string>
|
||||
@@ -926,7 +943,7 @@ This is because Crowdin requires temporarily flattening this file and removing t
|
||||
<string name="revanced_spoof_app_version_target_entry_2">18.20.39 - استعادة سرعة الفيديو الواسعة & قائمة الجودة</string>
|
||||
<string name="revanced_spoof_app_version_target_entry_3">18.09.39 - استعادة علامة تبويب المكتبة</string>
|
||||
<string name="revanced_spoof_app_version_target_entry_4">17.41.37 - استعادة رف قائمة التشغيل القديم</string>
|
||||
<string name="revanced_spoof_app_version_target_entry_5">17.30.34 - استعادة تصميم واجهة المستخدم القديم</string>
|
||||
<string name="revanced_spoof_app_version_target_entry_5">17.33.42 - استعادة تصميم واجهة المستخدم القديم</string>
|
||||
</patch>
|
||||
<patch id="layout.startpage.ChangeStartPagePatch">
|
||||
<string name="revanced_start_page_title">تعيين صفحة البداية</string>
|
||||
@@ -1036,6 +1053,11 @@ This is because Crowdin requires temporarily flattening this file and removing t
|
||||
<string name="revanced_announcements_connection_failed">فشل الاتصال بموفر الإعلانات</string>
|
||||
<string name="revanced_announcements_dialog_dismiss">تجاهل</string>
|
||||
</patch>
|
||||
<patch id="misc.dns.CheckWatchHistoryDomainNameResolutionPatch">
|
||||
<string name="revanced_check_watch_history_domain_name_dialog_title">تحذير</string>
|
||||
<string name="revanced_check_watch_history_domain_name_dialog_message">لم يتم حفظ سجل المشاهدة الخاص بك.<br><br>من المرجح أن يكون السبب في ذلك هو مانع إعلانات DNS أو وكيل الشبكة.<br><br>لإصلاح هذه المشكلة، قم بإضافة <b>s.youtube.com</b> إلى القائمة البيضاء أو قم بإيقاف تشغيل جميع أدوات حظر DNS ووكلاء البروكسي.</string>
|
||||
<string name="revanced_check_watch_history_domain_name_dialog_ignore">لا تعرض مرة أخرى</string>
|
||||
</patch>
|
||||
<patch id="misc.autorepeat.AutoRepeatPatch">
|
||||
<string name="revanced_auto_repeat_title">تمكين التكرار التلقائي</string>
|
||||
<string name="revanced_auto_repeat_summary_on">تم تمكين التكرار التلقائي</string>
|
||||
@@ -1110,21 +1132,23 @@ This is because Crowdin requires temporarily flattening this file and removing t
|
||||
<string name="revanced_slide_to_seek_summary_on">تم تمكين Slide to Seek</string>
|
||||
<string name="revanced_slide_to_seek_summary_off">تم تعطيل Slide to Seek</string>
|
||||
</patch>
|
||||
<patch id="misc.fix.playback.SpoofClientPatch">
|
||||
<string name="revanced_spoof_client_screen_title">Spoof Client</string>
|
||||
<string name="revanced_spoof_client_screen_summary">محاكاة العميل لمنع مشكلات التشغيل</string>
|
||||
<string name="revanced_spoof_client_title">Spoof Client</string>
|
||||
<string name="revanced_spoof_client_summary_on">يتم محاكاة العميل</string>
|
||||
<string name="revanced_spoof_client_summary_off">لا يتم محاكاة العميل\n\nقد لا يعمل تشغيل الفيديو</string>
|
||||
<string name="revanced_spoof_client_user_dialog_message">إيقاف تشغيل هذا الإعداد قد يسبب مشاكل في تشغيل الفيديو.</string>
|
||||
<string name="revanced_spoof_client_use_ios_title">Spoof Client to iOS</string>
|
||||
<string name="revanced_spoof_client_use_ios_summary_on">تتم حاليًا محاكاة العميل إلـى iOS\n\nالآثار الجانبية تشمل:\n• قد لا يكون فيديو HDR متوفرًا\n• قد لا يعمل سجل المشاهدة</string>
|
||||
<string name="revanced_spoof_client_use_ios_summary_off">تتم حاليًا محاكاة العميل إلـى Android VR\n\nالآثار الجانبية تشمل:\n• لا يوجد فيديو HDR\n• فيديوهات الأطفال لا يتم تشغيلهم\n• مقاطع الفيديو الموقوفة يمكن أن تستأنف عشوائياً\n• جودة منخفضة لمصغرات شريط التقدم\n• زر التنزيل مخفي\n• بطاقات نهاية الشاشة مخفية</string>
|
||||
<string name="revanced_spoof_client_storyboard_timeout">محاكاة مصغرات العميل غير متوفرة (انتهت مهلة API)</string>
|
||||
<string name="revanced_spoof_client_storyboard_io_exception">محاكاة مصغرات العميل غير متوفرة مؤقتًا: %s</string>
|
||||
</patch>
|
||||
<!-- This patch is no longer used, these strings are not in use, and these strings will be deleted in the future. -->
|
||||
<patch id="misc.fix.playback.SpoofSignaturePatch">
|
||||
<patch id="misc.fix.playback.SpoofVideoStreamsPatch">
|
||||
<string name="revanced_spoof_video_streams_screen_title">Spoof Video Streams</string>
|
||||
<string name="revanced_spoof_video_streams_screen_summary">تزييف تدفقات الفيديو الخاصة بالعميل لمنع حدوث مشكلات أثناء التشغيل</string>
|
||||
<string name="revanced_spoof_video_streams_title">Spoof Video Streams</string>
|
||||
<string name="revanced_spoof_video_streams_summary_on">يتم تزييف تدفقات الفيديو</string>
|
||||
<string name="revanced_spoof_video_streams_summary_off">لا يتم تزييف تدفقات الفيديو\n\nقد لا يعمل تشغيل الفيديو</string>
|
||||
<string name="revanced_spoof_video_streams_user_dialog_message">إيقاف تشغيل هذا الإعداد قد يسبب مشاكل في تشغيل الفيديو.</string>
|
||||
<string name="revanced_spoof_video_streams_client_title">العميل الافتراضي</string>
|
||||
<string name="revanced_spoof_video_streams_ios_force_avc_title">فرض AVC (H.264)</string>
|
||||
<string name="revanced_spoof_video_streams_ios_force_avc_summary_on">ترميز الفيديو هو AVC (H.264)</string>
|
||||
<string name="revanced_spoof_video_streams_ios_force_avc_summary_off">ترميز الفيديو هو VP9 أو AV1</string>
|
||||
<string name="revanced_spoof_video_streams_ios_force_avc_no_hardware_vp9_summary_on">لا يحتوي جهازك على فك تشفير الأجهزة VP9، وهذا الإعداد يعمل دائما عند تمكين تزييف العميل</string>
|
||||
<string name="revanced_spoof_video_streams_ios_force_avc_user_dialog_message">قد يؤدي تمكين هذا إلى تحسين عمر البطارية وإصلاح مشكلة تقطيع التشغيل.\n\nيتمتع تنسيق AVC بدقة قصوى تبلغ 1080P، وسيستخدم تشغيل الفيديو المزيد من بيانات الإنترنت مقارنةً بتنسيق VP9 أو AV1.</string>
|
||||
<string name="revanced_spoof_video_streams_about_ios_title">التأثيرات الجانبية لمحاكاة iOS</string>
|
||||
<string name="revanced_spoof_video_streams_about_ios_summary">• قد لا يتم تشغيل الأفلام أو الفيديوهات المدفوعة\n• تبدأ البثوث المباشرة من البداية\n• قد تنتهي الفيديوهات قبل النهاية بثانية واحدة\n• لا يوجد ترميز الصوت Opus</string>
|
||||
<string name="revanced_spoof_video_streams_about_android_vr_title">التأثيرات الجانبية لمحاكاة Android VR</string>
|
||||
<string name="revanced_spoof_video_streams_about_android_vr_summary">• قائمة المقطع الصوتي مفقودة\n• مستوى الصوت الثابت غير متوفر</string>
|
||||
</patch>
|
||||
<!-- This patch is no longer used and these strings will soon be deleted. -->
|
||||
<patch id="video.hdrbrightness.HDRBrightnessPatch">
|
||||
|
||||
@@ -32,15 +32,16 @@ This is because Crowdin requires temporarily flattening this file and removing t
|
||||
-->
|
||||
<resources>
|
||||
<app id="shared">
|
||||
<patch id="misc.checks.BaseCheckEnvironmentPatch">
|
||||
</patch>
|
||||
<patch id="misc.settings.BaseSettingsResourcePatch">
|
||||
<!-- Settings about dialog. -->
|
||||
</patch>
|
||||
<patch id="misc.gms.BaseGmsCoreSupportResourcePatch">
|
||||
<!-- Translations of this should not be longer than the original English text, otherwise the text can be clipped and not entirely shown. -->
|
||||
</patch>
|
||||
</app>
|
||||
<app id="youtube">
|
||||
<patch id="misc.settings.SettingsResourcePatch">
|
||||
</patch>
|
||||
<patch id="misc.settings.SettingsPatch">
|
||||
</patch>
|
||||
<patch id="misc.debugging.DebuggingPatch">
|
||||
@@ -57,7 +58,7 @@ This is because Crowdin requires temporarily flattening this file and removing t
|
||||
<!-- 'Component path builder strings' is the technical name for identifying the Litho UI layout items to hide. This is an advanced feature and most users will never use this. -->
|
||||
<!-- For localization it is preferred, but not required, if 'LeBlanc' is replaced with a localized name or a familiar word that has upper case letters in the middle of the word.
|
||||
This is because keywords can be in any language, and showing an example in the localized script helps convey this. -->
|
||||
<!-- Translations of this should not be longer than the original English text, otherwise the text can be clipped and not entirely shown. -->
|
||||
<!-- Translations _must_ use a localized example. For languages that do not use spaces between words (Chinese, Japanese, etc) the English AI example should be used since no localized examples exist. Or if using machine translations, or if nobody wants to think of a localized example, then the English 'ai' example should be left as-is. -->
|
||||
<!-- Translations of this should not be longer than the original English text, otherwise the text can be clipped and not entirely shown. -->
|
||||
</patch>
|
||||
<patch id="ad.general.HideAdsResourcePatch">
|
||||
@@ -171,8 +172,6 @@ This is because Crowdin requires temporarily flattening this file and removing t
|
||||
<patch id="layout.sponsorblock.SponsorBlockResourcePatch">
|
||||
<!-- Translations should use language similar to 'revanced_ryd_compact_layout_title' -->
|
||||
<!-- Toast shown if network connection times out. Translations of this should not be longer than the original English or the text can be clipped and not entirely shown. -->
|
||||
<!-- Do not rearrange the (hour):(minute):second) time format operators here.
|
||||
YT shows the same seekbar time format for all languages, and this string is confirming the segment time as it appears in the seekbar. -->
|
||||
<!-- Shown in the settings preferences, and translations can be any text length. -->
|
||||
</patch>
|
||||
<patch id="layout.spoofappversion.SpoofAppVersionPatch">
|
||||
@@ -206,6 +205,8 @@ This is because Crowdin requires temporarily flattening this file and removing t
|
||||
</patch>
|
||||
<patch id="misc.announcements.AnnouncementsPatch">
|
||||
</patch>
|
||||
<patch id="misc.dns.CheckWatchHistoryDomainNameResolutionPatch">
|
||||
</patch>
|
||||
<patch id="misc.autorepeat.AutoRepeatPatch">
|
||||
</patch>
|
||||
<patch id="misc.dimensions.spoof.SpoofDeviceDimensionsPatch">
|
||||
@@ -232,10 +233,7 @@ This is because Crowdin requires temporarily flattening this file and removing t
|
||||
</patch>
|
||||
<patch id="interaction.seekbar.EnableSlideToSeekPatch">
|
||||
</patch>
|
||||
<patch id="misc.fix.playback.SpoofClientPatch">
|
||||
</patch>
|
||||
<!-- This patch is no longer used, these strings are not in use, and these strings will be deleted in the future. -->
|
||||
<patch id="misc.fix.playback.SpoofSignaturePatch">
|
||||
<patch id="misc.fix.playback.SpoofVideoStreamsPatch">
|
||||
</patch>
|
||||
<!-- This patch is no longer used and these strings will soon be deleted. -->
|
||||
<patch id="video.hdrbrightness.HDRBrightnessPatch">
|
||||
|
||||
@@ -32,6 +32,17 @@ This is because Crowdin requires temporarily flattening this file and removing t
|
||||
-->
|
||||
<resources>
|
||||
<app id="shared">
|
||||
<patch id="misc.checks.BaseCheckEnvironmentPatch">
|
||||
<string name="revanced_check_environment_failed_title">Yoxlamalar uğursuz oldu</string>
|
||||
<string name="revanced_check_environment_dialog_open_official_source_button">Xidməti veb saytı aç</string>
|
||||
<string name="revanced_check_environment_dialog_ignore_button">Yan keç</string>
|
||||
<string name="revanced_check_environment_failed_message"><h5>Bu tətbiq sizin tərəfinizdən yamaqlanmayıb.</h5><br>Bu tətbiq düzgün işləməyə bilər, <b>istifadə etmək zərərli və ya hətta təhlükəli ola bilər</b>.<br><br><br>Bu yoxlamalar bu tətbiqin əvvəldən yamaqlandığını və ya başqasından əldə edildiyini göstərir:<br><br><small>%1$s</small><br> <br>onu silməyiniz və özünüz yamaqlamağınız tövsiyə olunur. </b>təsdiqlənmiş və təhlükəsiz tətbiq istifadə etdiyinizə əmin olmaq üçün. <p><br> İnkar edilməzsə, bu xəbərdarlıq yalnız iki dəfə göstəriləcək.</string>
|
||||
<string name="revanced_check_environment_not_same_patching_device">Fərqli cihazda yamaqlanıb</string>
|
||||
<string name="revanced_check_environment_manager_not_expected_installer">ReVanced Manager tərəfindən quraşdırılmayıb</string>
|
||||
<string name="revanced_check_environment_not_near_patch_time">10 dəqiqədən çox əvvəl yamaqlanıb</string>
|
||||
<string name="revanced_check_environment_not_near_patch_time_days">%s gün əvvəl yamaqlanıb</string>
|
||||
<string name="revanced_check_environment_not_near_patch_time_invalid">APK quruluş tarixi pozulub</string>
|
||||
</patch>
|
||||
<patch id="misc.settings.BaseSettingsResourcePatch">
|
||||
<string name="revanced_settings_confirm_user_dialog_title">Davam etmək istəyirsiniz?</string>
|
||||
<string name="revanced_settings_reset">Sıfırla</string>
|
||||
@@ -42,6 +53,14 @@ This is because Crowdin requires temporarily flattening this file and removing t
|
||||
<string name="revanced_settings_import_reset">ReVanced tənzimləmələr standarta təyin edildi</string>
|
||||
<string name="revanced_settings_import_success">%d tənzimləmə idxal edildi</string>
|
||||
<string name="revanced_settings_import_failure_parse">Uğursuz idxal prosesi: %s</string>
|
||||
<string name="revanced_pref_import_export_title">İdxal/İxrac et</string>
|
||||
<string name="revanced_pref_import_export_summary">ReVanced tənzimləmələrin idxal/ixrac et</string>
|
||||
<!-- Settings about dialog. -->
|
||||
<string name="revanced_settings_about_links_body">ReVanced Patches <i>%s</i> versiyasını istifadə edirsiniz</string>
|
||||
<string name="revanced_settings_about_links_dev_header">Qeyd</string>
|
||||
<string name="revanced_settings_about_links_dev_body">Bu versiya ilkin buraxılışdır və gözlənilməz problemlərlə üzləşə bilərsiniz</string>
|
||||
<string name="revanced_settings_about_links_header">Rəsmi bağlantılar</string>
|
||||
<string name="revanced_settings_about_links_donate">İanə ver</string>
|
||||
</patch>
|
||||
<patch id="misc.gms.BaseGmsCoreSupportResourcePatch">
|
||||
<!-- Translations of this should not be longer than the original English text, otherwise the text can be clipped and not entirely shown. -->
|
||||
@@ -54,14 +73,6 @@ This is because Crowdin requires temporarily flattening this file and removing t
|
||||
</patch>
|
||||
</app>
|
||||
<app id="youtube">
|
||||
<patch id="misc.settings.SettingsResourcePatch">
|
||||
<string name="revanced_settings_about_links_body">ReVanced Patches <i>%s</i> versiyasını istifadə edirsiniz</string>
|
||||
<string name="revanced_settings_about_links_dev_header">Qeyd</string>
|
||||
<string name="revanced_settings_about_links_dev_body">Bu versiya ilkin buraxılışdır və gözlənilməz problemlərlə üzləşə bilərsiniz</string>
|
||||
<string name="revanced_settings_about_links_header">Rəsmi bağlantılar</string>
|
||||
<string name="revanced_pref_import_export_title">İdxal/İxrac et</string>
|
||||
<string name="revanced_pref_import_export_summary">ReVanced tənzimləmələrin idxal/ixrac et</string>
|
||||
</patch>
|
||||
<patch id="misc.settings.SettingsPatch">
|
||||
<string name="revanced_settings_screen_00_about_title">Haqqında</string>
|
||||
<string name="revanced_settings_screen_01_ads_title">Reklamlar</string>
|
||||
@@ -242,14 +253,18 @@ This is because Crowdin requires temporarily flattening this file and removing t
|
||||
<string name="revanced_hide_keyword_content_phrases_title">Gizlədiləcək açar sözlər</string>
|
||||
<!-- For localization it is preferred, but not required, if 'LeBlanc' is replaced with a localized name or a familiar word that has upper case letters in the middle of the word.
|
||||
This is because keywords can be in any language, and showing an example in the localized script helps convey this. -->
|
||||
<string name="revanced_hide_keyword_content_phrases_summary">Yeni sətirlərlə ayrılmış gizlədiləcək açar sözlər və ifadələr\n\nOrtada böyük hərf olan sözlər korpusla birlikdə daxil edilməlidir (yəni: iPhone, TikTok, LeBlanc)</string>
|
||||
<string name="revanced_hide_keyword_content_phrases_summary">Yeni sətirlərlə ayrılmış gizlədiləcək açar sözlər və frazalar\n\nAçar sözlər kanal adları və ya video adlarında göstərilən istənilən mətn ola bilər\n\nOrtada böyük hərf olan sözlər korpusla birlikdə qeyd edilməlidir (yəni: iPhone, TikTok, LeBlanc)</string>
|
||||
<string name="revanced_hide_keyword_content_about_title">Açar söz filtrləməsi haqqında</string>
|
||||
<string name="revanced_hide_keyword_content_about_summary">Əsas səhifə/Abunəlik/Axtarış nəticələri açar söz ifadələrinə uyğunlaşan məzmunu gizlətmək üçün filtrlənir\n\nMəhdudiyyətlər\n• Bəzi Shorts gizlənə bilməz\n• Bəzi UI elementləri gizlənə bilməz\n• Açar söz axtarışı heç bir nəticə göstərməyə bilər</string>
|
||||
<string name="revanced_hide_keyword_content_about_summary">Əsas səhifə/Abunəlik/Axtarış nəticələri açar söz ifadələrinə uyğunlaşan məzmunu gizlətmək üçün filtrlənir\n\nMəhdudiyyətlər\n• Shorts-lar kanal adına görə gizlənə bilməz\n• Bəzi UI hissəcikləri gizlədilə bilməz\n• Açar söz axtarışında nəticə olmaya bilər</string>
|
||||
<string name="revanced_hide_keyword_content_about_whole_words_title">Bütün sözləri uyğunlaşdır</string>
|
||||
<!-- Translations _must_ use a localized example. For languages that do not use spaces between words (Chinese, Japanese, etc) the English AI example should be used since no localized examples exist. Or if using machine translations, or if nobody wants to think of a localized example, then the English 'ai' example should be left as-is. -->
|
||||
<string name="revanced_hide_keyword_content_about_whole_words_summary">Açar söz/frazanın qoşa dırnaqlarla əhatə olunması video adları və kanal adlarının qismən uyğunlaşmasına mane olacaq <br><br>Məsələn,<br><b>\"ai\"</b> videonu gizlədəcək:<b>How does AI work?</b><br> lakin gizlətməyəcək: Düzgün;<b>What does fair use mean?</b></string>
|
||||
<!-- Translations of this should not be longer than the original English text, otherwise the text can be clipped and not entirely shown. -->
|
||||
<string name="revanced_hide_keyword_toast_invalid_common">Etibarsız açar sözü. \'%s\' istifadə edilə bilməz</string>
|
||||
<!-- Translations of this should not be longer than the original English text, otherwise the text can be clipped and not entirely shown. -->
|
||||
<string name="revanced_hide_keyword_toast_invalid_length">Etibarsız açar sözü. \'%1$s\', %2$d simvoldan azdır</string>
|
||||
<string name="revanced_hide_keyword_toast_invalid_broad">\"%s\" açar sözü, bütün videolarda gizlədiləcək</string>
|
||||
<string name="revanced_hide_keyword_toast_invalid_common">Açar söz istifadə edilə bilmir: %s</string>
|
||||
<string name="revanced_hide_keyword_toast_invalid_common_whole_word_required">Açar söz istifadəsi üçün istinad əlavə et: %s</string>
|
||||
<string name="revanced_hide_keyword_toast_invalid_conflicting">Açar sözün ziddiyyətli hissəcikləri var: %s</string>
|
||||
<string name="revanced_hide_keyword_toast_invalid_length">Açar söz çox qısadır və istinad tələb edir: %s</string>
|
||||
<string name="revanced_hide_keyword_toast_invalid_broad">Açar söz, bütün videoları gizlədəcək: %s</string>
|
||||
</patch>
|
||||
<patch id="ad.general.HideAdsResourcePatch">
|
||||
<string name="revanced_hide_general_ads_title">Ümumi reklamları gizlət</string>
|
||||
@@ -307,7 +322,7 @@ This is because Crowdin requires temporarily flattening this file and removing t
|
||||
<string name="revanced_copy_video_url_timestamp_summary_off">Düymə göstərilmir</string>
|
||||
</patch>
|
||||
<patch id="interaction.dialog.RemoveViewerDiscretionDialogPatch">
|
||||
<string name="revanced_remove_viewer_discretion_dialog_title">İzləyici mülahizə dialoqunu sil</string>
|
||||
<string name="revanced_remove_viewer_discretion_dialog_title">İzləyici mülahizə dialoqun sil</string>
|
||||
<string name="revanced_remove_viewer_discretion_dialog_summary_on">Dialoq silindi</string>
|
||||
<string name="revanced_remove_viewer_discretion_dialog_summary_off">Dialoq göstərilir</string>
|
||||
<string name="revanced_remove_viewer_discretion_dialog_user_dialog_message">Bu, yaş məhdudiyyətini ötürmür. Sadəcə avtomatik qəbul edir.</string>
|
||||
@@ -615,6 +630,9 @@ This is because Crowdin requires temporarily flattening this file and removing t
|
||||
<string name="revanced_hide_shorts_save_sound_button_title">Səsi pleylistdə saxlama düyməsini gizlət</string>
|
||||
<string name="revanced_hide_shorts_save_sound_button_summary_on">Səsi pleylistdə saxlama gizlidir</string>
|
||||
<string name="revanced_hide_shorts_save_sound_button_summary_off">Səsi pleylistdə saxlama göstərilir</string>
|
||||
<string name="revanced_hide_shorts_use_this_sound_button_title">\"Bu səsi istifadə et\" düyməsini gizlət</string>
|
||||
<string name="revanced_hide_shorts_use_this_sound_button_summary_on">\"Bu səsi istifadə et\" düyməsi gizlidir</string>
|
||||
<string name="revanced_hide_shorts_use_this_sound_button_summary_off">\"Bu səsi istifadə et\" düyməsi göstərilir</string>
|
||||
<string name="revanced_hide_shorts_search_suggestions_title">Axtarış təkliflərini gizlət</string>
|
||||
<string name="revanced_hide_shorts_search_suggestions_summary_on">Axtarış təklifləri gizlədilib</string>
|
||||
<string name="revanced_hide_shorts_search_suggestions_summary_off">Axtarış təklifləri göstərilir</string>
|
||||
@@ -678,7 +696,6 @@ This is because Crowdin requires temporarily flattening this file and removing t
|
||||
<string name="revanced_player_overlay_opacity_invalid_toast">Oynadıcı örtüyünün qeyri-şəffaflığı 0-100 arası olmalıdır</string>
|
||||
</patch>
|
||||
<patch id="layout.returnyoutubedislike.ReturnYouTubeDislikeResourcePatch">
|
||||
<string name="revanced_ryd_video_likes_hidden_by_video_owner">Gizli</string>
|
||||
<!-- Toast shown if network connection times out. Translations of this should not be longer than the original English or the text can be clipped and not entirely shown. -->
|
||||
<string name="revanced_ryd_failure_connection_timeout">\"Bəyənməmə\" müvəqqəti əlçatmazdır(API vaxtı bitdi)</string>
|
||||
<string name="revanced_ryd_failure_connection_status_code">Bəyənməmə əlçatmazdır (status %d)</string>
|
||||
@@ -774,6 +791,7 @@ This is because Crowdin requires temporarily flattening this file and removing t
|
||||
<string name="revanced_sb_general_skipcount_sum_off">Ötürmə sayının izlənməsi aktiv deyil</string>
|
||||
<string name="revanced_sb_general_min_duration">Minimum bölüm müddəti</string>
|
||||
<string name="revanced_sb_general_min_duration_sum">Bölümlər bu dəyərdən (saniyə olaraq) daha qısadırsa göstərilməyəcək və ya ötürülməyəcək</string>
|
||||
<string name="revanced_sb_general_min_duration_invalid">Etibarsız vaxt müddəti</string>
|
||||
<string name="revanced_sb_general_uuid">Şəxsi istifadəçi kimliyiniz</string>
|
||||
<string name="revanced_sb_general_uuid_sum">Bu gizli saxlanılmalıdır. Bu, parol kimidir və heç kimlə paylaşılmamalıdır. Kimsə bunu bilsə, onlar sizi təqlid edə bilər</string>
|
||||
<string name="revanced_sb_general_uuid_invalid">Şəxsi istifadəçi kimliyiniz ən az 30 simvol uzunluğunda olmalıdır</string>
|
||||
@@ -874,8 +892,6 @@ This is because Crowdin requires temporarily flattening this file and removing t
|
||||
<string name="revanced_sb_new_segment_time_start">Bölüm başladığı vaxt</string>
|
||||
<string name="revanced_sb_new_segment_time_end">Bölümün bitmə vaxtı</string>
|
||||
<string name="revanced_sb_new_segment_confirm_title">Vaxtlar düzgündür?</string>
|
||||
<!-- Do not rearrange the (hour):(minute):second) time format operators here.
|
||||
YT shows the same seekbar time format for all languages, and this string is confirming the segment time as it appears in the seekbar. -->
|
||||
<string name="revanced_sb_new_segment_confirm_content">Bölüm \n\n%1$s\n\n%2$s\n\n(%3$s)\n\nTəqdim etməyə hazırsınız?</string>
|
||||
<string name="revanced_sb_new_segment_start_is_before_end">Başlanğıc sondan əvvəl olmalıdır</string>
|
||||
<string name="revanced_sb_new_segment_mark_locations_first">Əvvəlcə vaxt çubuğunda iki yeri doldur</string>
|
||||
@@ -894,6 +910,7 @@ This is because Crowdin requires temporarily flattening this file and removing t
|
||||
<string name="revanced_sb_stats_username_changed">İstifadəçi adı uğurla dəyişdirildi</string>
|
||||
<string name="revanced_sb_stats_reputation">Nüfuzunuz <b>%.2f</b></string>
|
||||
<string name="revanced_sb_stats_submissions"><b>%s</b> bölüm yaratdınız</string>
|
||||
<string name="revanced_sb_stats_submissions_sum">Bölümlərinizə baxmaq üçün bura toxunun</string>
|
||||
<string name="revanced_sb_stats_saved_zero">SponsorBlock liderlik lövhəsi</string>
|
||||
<string name="revanced_sb_stats_saved">İnsanları <b>%s</b> bölümdən xilas etdiniz</string>
|
||||
<string name="revanced_sb_stats_saved_sum_zero">Qlobal statistikaları və başlıca töhfəçiləri görmək üçün bura toxunun</string>
|
||||
@@ -1007,7 +1024,7 @@ This is because Crowdin requires temporarily flattening this file and removing t
|
||||
<string name="revanced_alt_thumbnail_search_title">Axtarış nəticələri</string>
|
||||
<string name="revanced_alt_thumbnail_options_entry_1">Orijinal miniatürlər</string>
|
||||
<string name="revanced_alt_thumbnail_options_entry_2">DeArrow & Orijinal miniatürlər</string>
|
||||
<string name="revanced_alt_thumbnail_options_entry_3">DeArrow & Kadr çəkilişləri</string>
|
||||
<string name="revanced_alt_thumbnail_options_entry_3">DeArrow & Kadr çəkilişlər</string>
|
||||
<string name="revanced_alt_thumbnail_options_entry_4">Kadr çəkilişləri</string>
|
||||
<string name="revanced_alt_thumbnail_dearrow_about_summary">DeArrow YouTube videoları üçün bölük mənbəli miniatürlər təchiz edir. Bu miniatürlər hər zaman YouTube tərəfindən təmin edilənlərdən daha uyğun olur\n\nƏgər aktivləşdirilərsə, video URL-lər API serverinə göndəriləcək və başqa heç bir məlumat göndərilməyəcək. Videoda DeArrow miniatürləri yoxdursa, orijinal və ya hələ də kadr çəkilişləri göstərilir\n\nDeArrow haqqında ətraflı öyrənmək üçün bura toxun</string>
|
||||
<string name="revanced_alt_thumbnail_dearrow_connection_toast_title">API əlçatan deyilsə ani bildiriş göstər</string>
|
||||
@@ -1036,6 +1053,11 @@ This is because Crowdin requires temporarily flattening this file and removing t
|
||||
<string name="revanced_announcements_connection_failed">Elan provayderinə bağlanmaq olmadı</string>
|
||||
<string name="revanced_announcements_dialog_dismiss">Ləğv et</string>
|
||||
</patch>
|
||||
<patch id="misc.dns.CheckWatchHistoryDomainNameResolutionPatch">
|
||||
<string name="revanced_check_watch_history_domain_name_dialog_title">Xәbәrdarlıq</string>
|
||||
<string name="revanced_check_watch_history_domain_name_dialog_message">Baxış tarixçəniz saxlanmır.<br><br>Bu çox güman ki, DNS reklam bloklayıcı və ya şəbəkə proksisinə görədir.<br><br>.Bunu düzəltmək üçün s.youtube.com-u</b> <b>ağ siyahıya salın və ya bütün DNS bloklayıcıları və proksiləri bağlayın.</string>
|
||||
<string name="revanced_check_watch_history_domain_name_dialog_ignore">Təkrar göstərmə</string>
|
||||
</patch>
|
||||
<patch id="misc.autorepeat.AutoRepeatPatch">
|
||||
<string name="revanced_auto_repeat_title">Avto-təkrarlamanı aktivləşdir</string>
|
||||
<string name="revanced_auto_repeat_summary_on">Avtomatik təkrar aktivləşdirilib</string>
|
||||
@@ -1110,21 +1132,23 @@ This is because Crowdin requires temporarily flattening this file and removing t
|
||||
<string name="revanced_slide_to_seek_summary_on">Axtarmaq üçün sürüşdürmə aktivdir</string>
|
||||
<string name="revanced_slide_to_seek_summary_off">Axtarmaq üçün sürüşdürmə aktiv deyil</string>
|
||||
</patch>
|
||||
<patch id="misc.fix.playback.SpoofClientPatch">
|
||||
<string name="revanced_spoof_client_screen_title">Qəbuledicini saxtalaşdır</string>
|
||||
<string name="revanced_spoof_client_screen_summary">Oynatma problemlərinin olmaması üçün client-i saxtalaşdır</string>
|
||||
<string name="revanced_spoof_client_title">Qəbuledicini saxtalaşdır</string>
|
||||
<string name="revanced_spoof_client_summary_on">Qəbuledici saxtalaşdırıldı</string>
|
||||
<string name="revanced_spoof_client_summary_off">Qəbuledici dəyişməyib\n\nVideo oynatma işləməyə bilər</string>
|
||||
<string name="revanced_spoof_client_user_dialog_message">Bu seçimin bağlanması, video oynatma problemlərinə səbəb ola bilər.</string>
|
||||
<string name="revanced_spoof_client_use_ios_title">Qəbuledicini iOS olaraq saxtalaşdır</string>
|
||||
<string name="revanced_spoof_client_use_ios_summary_on">Qəbuledici hazırda iOS üzrə saxtalaşdırılıb\n\nYan təsirlərə daxildir:\n• HDR video mövcud olmaya bilər\n• Baxış tarixçəsi işləməyə bilər</string>
|
||||
<string name="revanced_spoof_client_use_ios_summary_off">Qəbuledici hazırda Android VR\'ə saxtalaşdırılıb. Yan təsirlərə daxildir:\n• HDR video yoxdur\n• Uşaq videoları oynadılmır\n• Fasilə verilmiş videolar gözlənilmədən davam edə bilər\n• Aşağı keyfiyyətli Shorts axtarma çubuğu miniatürləri\n• \"Yüklə\" fəaliyyət düyməsi gizlidir\n• Bitiş ekran kartları gizlidir</string>
|
||||
<string name="revanced_spoof_client_storyboard_timeout">Client kiçik şəkillərini təqlid etmə əlçatmazdır (API vaxtı bitdi)</string>
|
||||
<string name="revanced_spoof_client_storyboard_io_exception">Client kiçik şəkillərini təqlid etmə müvəqqəti əlçatmazdır: %s</string>
|
||||
</patch>
|
||||
<!-- This patch is no longer used, these strings are not in use, and these strings will be deleted in the future. -->
|
||||
<patch id="misc.fix.playback.SpoofSignaturePatch">
|
||||
<patch id="misc.fix.playback.SpoofVideoStreamsPatch">
|
||||
<string name="revanced_spoof_video_streams_screen_title">Video yayımları saxtalaşdır</string>
|
||||
<string name="revanced_spoof_video_streams_screen_summary">Oynatma problemlərin önləmək üçün qəbuledici video yayımların saxtalaşdır</string>
|
||||
<string name="revanced_spoof_video_streams_title">Video yayımları saxtalaşdır</string>
|
||||
<string name="revanced_spoof_video_streams_summary_on">Video yayımları saxtalaşdırılır</string>
|
||||
<string name="revanced_spoof_video_streams_summary_off">Video yayımları saxtalaşmır\n\nVideo oynatma işləməyə bilər</string>
|
||||
<string name="revanced_spoof_video_streams_user_dialog_message">Bu seçimi bağlamaq, video oynatma problemlərinə səbəb olar.</string>
|
||||
<string name="revanced_spoof_video_streams_client_title">İlkin qəbuledici</string>
|
||||
<string name="revanced_spoof_video_streams_ios_force_avc_title">Məcburi AVC (H.264)</string>
|
||||
<string name="revanced_spoof_video_streams_ios_force_avc_summary_on">Video kodlaşdırma: AVC (H.264)</string>
|
||||
<string name="revanced_spoof_video_streams_ios_force_avc_summary_off">Video kodlaşdırma / VP9 və ya AV1</string>
|
||||
<string name="revanced_spoof_video_streams_ios_force_avc_no_hardware_vp9_summary_on">Cihazınızın VP9 hardware decoding\'i yoxdur və bu seçim, \"Qəbuledicini saxtalaşdırma\" aktivləşdikdə həmişəlikdir</string>
|
||||
<string name="revanced_spoof_video_streams_ios_force_avc_user_dialog_message">Bunu aktivləşdirmə batareya ömrünü yaxşılaşdıra və oynatma donmasını düzəldə bilər.\n\nAVC maksimum 1080p görüntü imkanına malikdir və video oynadılması VP9 və ya AV1-dən daha çox internet məlumatı istifadə edəcək.</string>
|
||||
<string name="revanced_spoof_video_streams_about_ios_title">iOS saxtakarlığı yan təsirləri</string>
|
||||
<string name="revanced_spoof_video_streams_about_ios_summary">• Filmlər və ya ödənişli videolar oynadılmaya bilər\n• Canlı yayımlar əvvəldən başlayır\n• Videolar 1 saniyə tez bitə bilər\n• Opus səs kodlama yoxdur</string>
|
||||
<string name="revanced_spoof_video_streams_about_android_vr_title">Android VR saxtakarlığı yan təsirləri</string>
|
||||
<string name="revanced_spoof_video_streams_about_android_vr_summary">• Səs axını menyusu əskikdir\n• Stabil səs səviyyəsi əlçatan deyil</string>
|
||||
</patch>
|
||||
<!-- This patch is no longer used and these strings will soon be deleted. -->
|
||||
<patch id="video.hdrbrightness.HDRBrightnessPatch">
|
||||
|
||||
@@ -32,6 +32,8 @@ This is because Crowdin requires temporarily flattening this file and removing t
|
||||
-->
|
||||
<resources>
|
||||
<app id="shared">
|
||||
<patch id="misc.checks.BaseCheckEnvironmentPatch">
|
||||
</patch>
|
||||
<patch id="misc.settings.BaseSettingsResourcePatch">
|
||||
<string name="revanced_settings_confirm_user_dialog_title">Вы хочаце працягнуць?</string>
|
||||
<string name="revanced_settings_reset">Скінуць</string>
|
||||
@@ -42,6 +44,13 @@ This is because Crowdin requires temporarily flattening this file and removing t
|
||||
<string name="revanced_settings_import_reset">Налады ReVanced скінуты да стандартных</string>
|
||||
<string name="revanced_settings_import_success">Імпартавана %d налад</string>
|
||||
<string name="revanced_settings_import_failure_parse">Памылка імпарту: %s</string>
|
||||
<string name="revanced_pref_import_export_title">Імпарт / Экспарт</string>
|
||||
<string name="revanced_pref_import_export_summary">Імпарт / Экспарт налад ReVanced</string>
|
||||
<!-- Settings about dialog. -->
|
||||
<string name="revanced_settings_about_links_body">Вы выкарыстоўваеце версію ReVanced Patches <i>%s</i></string>
|
||||
<string name="revanced_settings_about_links_dev_header">Нататка</string>
|
||||
<string name="revanced_settings_about_links_dev_body">Гэтая версія з\"яўляецца папярэдняй версіяй, і вы можаце сутыкнуцца з непрадбачанымі праблемамі</string>
|
||||
<string name="revanced_settings_about_links_header">Афіцыйныя спасылкі</string>
|
||||
</patch>
|
||||
<patch id="misc.gms.BaseGmsCoreSupportResourcePatch">
|
||||
<!-- Translations of this should not be longer than the original English text, otherwise the text can be clipped and not entirely shown. -->
|
||||
@@ -54,14 +63,6 @@ This is because Crowdin requires temporarily flattening this file and removing t
|
||||
</patch>
|
||||
</app>
|
||||
<app id="youtube">
|
||||
<patch id="misc.settings.SettingsResourcePatch">
|
||||
<string name="revanced_settings_about_links_body">Вы выкарыстоўваеце версію ReVanced Patches <i>%s</i></string>
|
||||
<string name="revanced_settings_about_links_dev_header">Нататка</string>
|
||||
<string name="revanced_settings_about_links_dev_body">Гэтая версія з\"яўляецца папярэдняй версіяй, і вы можаце сутыкнуцца з непрадбачанымі праблемамі</string>
|
||||
<string name="revanced_settings_about_links_header">Афіцыйныя спасылкі</string>
|
||||
<string name="revanced_pref_import_export_title">Імпарт / Экспарт</string>
|
||||
<string name="revanced_pref_import_export_summary">Імпарт / Экспарт налад ReVanced</string>
|
||||
</patch>
|
||||
<patch id="misc.settings.SettingsPatch">
|
||||
<string name="revanced_settings_screen_00_about_title">Пра праграму</string>
|
||||
<string name="revanced_settings_screen_01_ads_title">Аб\"явы</string>
|
||||
@@ -242,14 +243,9 @@ This is because Crowdin requires temporarily flattening this file and removing t
|
||||
<string name="revanced_hide_keyword_content_phrases_title">Ключавыя словы, якія трэба схаваць</string>
|
||||
<!-- For localization it is preferred, but not required, if 'LeBlanc' is replaced with a localized name or a familiar word that has upper case letters in the middle of the word.
|
||||
This is because keywords can be in any language, and showing an example in the localized script helps convey this. -->
|
||||
<string name="revanced_hide_keyword_content_phrases_summary">Ключавыя словы і фразы, якія трэба схаваць, падзеленыя новымі радкамі\n\nСловы з вялікімі літарамі пасярэдзіне трэба ўводзіць з вялікім рэгістрам (напрыклад: iPhone, TikTok, LeBlanc)</string>
|
||||
<string name="revanced_hide_keyword_content_about_title">Аб фільтрацыі ключавых слоў</string>
|
||||
<string name="revanced_hide_keyword_content_about_summary">Галоўная/Падпіска/Вынікі пошуку фільтруюцца, каб схаваць змесціва, якое супадае з ключавымі фразамі\n\nАбмежаванні\n• Некаторыя шорты могуць быць не схаваны\n• Некаторыя кампаненты карыстальніцкага інтэрфейсу могуць быць не схаваны\n• Пошук па ключавым слове можа не даць вынікаў</string>
|
||||
<!-- Translations _must_ use a localized example. For languages that do not use spaces between words (Chinese, Japanese, etc) the English AI example should be used since no localized examples exist. Or if using machine translations, or if nobody wants to think of a localized example, then the English 'ai' example should be left as-is. -->
|
||||
<!-- Translations of this should not be longer than the original English text, otherwise the text can be clipped and not entirely shown. -->
|
||||
<string name="revanced_hide_keyword_toast_invalid_common">Няправільнае ключавое слова. Немагчыма выкарыстоўваць: \"%s\" у якасці фільтра</string>
|
||||
<!-- Translations of this should not be longer than the original English text, otherwise the text can be clipped and not entirely shown. -->
|
||||
<string name="revanced_hide_keyword_toast_invalid_length">Няправільнае ключавое слова. \"%1$s\" змяшчае менш за %2$d сімвалаў</string>
|
||||
<string name="revanced_hide_keyword_toast_invalid_broad">Ключавое слова \"%s\" схавае ўсе відэа</string>
|
||||
</patch>
|
||||
<patch id="ad.general.HideAdsResourcePatch">
|
||||
<string name="revanced_hide_general_ads_title">Схаваць агульную рэкламу</string>
|
||||
@@ -430,7 +426,7 @@ This is because Crowdin requires temporarily flattening this file and removing t
|
||||
<string name="revanced_hide_home_button_summary_on">Кнопка \"Дадому\" схавана</string>
|
||||
<string name="revanced_hide_home_button_summary_off">Паказана кнопка \"Дадому\".</string>
|
||||
<!-- 'Shorts' should be translated using the same localized wording YouTube displays the tab. -->
|
||||
<string name="revanced_hide_shorts_button_title">Схаваць шорты</string>
|
||||
<string name="revanced_hide_shorts_button_title">Схаваць кнопку \"Shorts\"</string>
|
||||
<string name="revanced_hide_shorts_button_summary_on">Кнопка Shorts схавана</string>
|
||||
<string name="revanced_hide_shorts_button_summary_off">Паказана кнопка Shorts</string>
|
||||
<!-- The Create button has no display name. Translate normally. -->
|
||||
@@ -678,7 +674,6 @@ This is because Crowdin requires temporarily flattening this file and removing t
|
||||
<string name="revanced_player_overlay_opacity_invalid_toast">Непразрыстасць накладання прайгравальніка павінна быць паміж 0-100</string>
|
||||
</patch>
|
||||
<patch id="layout.returnyoutubedislike.ReturnYouTubeDislikeResourcePatch">
|
||||
<string name="revanced_ryd_video_likes_hidden_by_video_owner">Схаваны</string>
|
||||
<!-- Toast shown if network connection times out. Translations of this should not be longer than the original English or the text can be clipped and not entirely shown. -->
|
||||
<string name="revanced_ryd_failure_connection_timeout">Адзнакі \"Не падабаецца\" часова недаступныя (час чакання API скончыўся)</string>
|
||||
<string name="revanced_ryd_failure_connection_status_code">Дызлайкі недаступныя (статус %d)</string>
|
||||
@@ -874,8 +869,6 @@ This is because Crowdin requires temporarily flattening this file and removing t
|
||||
<string name="revanced_sb_new_segment_time_start">Час пачатку сегмента</string>
|
||||
<string name="revanced_sb_new_segment_time_end">Час заканчэння сегмента</string>
|
||||
<string name="revanced_sb_new_segment_confirm_title">Ці правільны час?</string>
|
||||
<!-- Do not rearrange the (hour):(minute):second) time format operators here.
|
||||
YT shows the same seekbar time format for all languages, and this string is confirming the segment time as it appears in the seekbar. -->
|
||||
<string name="revanced_sb_new_segment_confirm_content">Сегмент ад\n\n%1$s\nда\n%2$s\n\n(%3$s)\n\nГатовы адправіць?</string>
|
||||
<string name="revanced_sb_new_segment_start_is_before_end">Пачынаць трэба раней за канец</string>
|
||||
<string name="revanced_sb_new_segment_mark_locations_first">Спачатку адзначце два месцы на панэлі часу</string>
|
||||
@@ -1036,6 +1029,10 @@ This is because Crowdin requires temporarily flattening this file and removing t
|
||||
<string name="revanced_announcements_connection_failed">Не ўдалося падключыцца да пастаўшчыка аб\"яў</string>
|
||||
<string name="revanced_announcements_dialog_dismiss">расслабіцца</string>
|
||||
</patch>
|
||||
<patch id="misc.dns.CheckWatchHistoryDomainNameResolutionPatch">
|
||||
<string name="revanced_check_watch_history_domain_name_dialog_title">Увага</string>
|
||||
<string name="revanced_check_watch_history_domain_name_dialog_ignore">Больш не паказваць</string>
|
||||
</patch>
|
||||
<patch id="misc.autorepeat.AutoRepeatPatch">
|
||||
<string name="revanced_auto_repeat_title">Уключыць аўтаматычны паўтор</string>
|
||||
<string name="revanced_auto_repeat_summary_on">Аўтаматычны паўтор уключаны</string>
|
||||
@@ -1110,21 +1107,8 @@ This is because Crowdin requires temporarily flattening this file and removing t
|
||||
<string name="revanced_slide_to_seek_summary_on">Слайд для пошуку ўключаны</string>
|
||||
<string name="revanced_slide_to_seek_summary_off">Слайд для пошуку не ўключаны</string>
|
||||
</patch>
|
||||
<patch id="misc.fix.playback.SpoofClientPatch">
|
||||
<string name="revanced_spoof_client_screen_title">Падман кліента</string>
|
||||
<string name="revanced_spoof_client_screen_summary">Падробка кліента, каб прадухіліць праблемы з прайграваннем</string>
|
||||
<string name="revanced_spoof_client_title">Падман кліента</string>
|
||||
<string name="revanced_spoof_client_summary_on">Кліент падроблены</string>
|
||||
<string name="revanced_spoof_client_summary_off">Кліент не падроблены\n\nПрайграванне відэа можа не працаваць</string>
|
||||
<string name="revanced_spoof_client_user_dialog_message">Адключэнне гэтай налады можа выклікаць праблемы з прайграваннем відэа.</string>
|
||||
<string name="revanced_spoof_client_use_ios_title">Падробка кліента для iOS</string>
|
||||
<string name="revanced_spoof_client_use_ios_summary_on">Зараз кліент падменены на iOS\n\nПабочныя эфекты ўключаюць:\n• Можа адсутнічаць HDR відэа\n• Можа не працаваць гісторыя праглядаў</string>
|
||||
<string name="revanced_spoof_client_use_ios_summary_off">Кліент у цяперашні час падроблены для Android VR. Пабочныя эфекты ўключаюць:\n• Няма HDR-відэа\n• Дзіцячыя відэа не прайграваюцца\n• Прыпыненыя відэа могуць аднаўляцца выпадковым чынам\n• Нізкая якасць мініяцюр на панэлі пошуку Shorts\n• Кнопка дзеяння Спампаваць схавана\n• Карткі канцавога экрана схаваны</string>
|
||||
<string name="revanced_spoof_client_storyboard_timeout">Мініяцюры кліента Spoof недаступныя (час чакання API скончыўся)</string>
|
||||
<string name="revanced_spoof_client_storyboard_io_exception">Мініяцюры кліента Spoof часова недаступныя: %s</string>
|
||||
</patch>
|
||||
<!-- This patch is no longer used, these strings are not in use, and these strings will be deleted in the future. -->
|
||||
<patch id="misc.fix.playback.SpoofSignaturePatch">
|
||||
<patch id="misc.fix.playback.SpoofVideoStreamsPatch">
|
||||
<string name="revanced_spoof_video_streams_user_dialog_message">Адключэнне гэтай налады можа выклікаць праблемы з прайграваннем відэа.</string>
|
||||
</patch>
|
||||
<!-- This patch is no longer used and these strings will soon be deleted. -->
|
||||
<patch id="video.hdrbrightness.HDRBrightnessPatch">
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -32,6 +32,8 @@ This is because Crowdin requires temporarily flattening this file and removing t
|
||||
-->
|
||||
<resources>
|
||||
<app id="shared">
|
||||
<patch id="misc.checks.BaseCheckEnvironmentPatch">
|
||||
</patch>
|
||||
<patch id="misc.settings.BaseSettingsResourcePatch">
|
||||
<string name="revanced_settings_confirm_user_dialog_title">আপনি কি এগিয়ে যেতে ইচ্ছুক?</string>
|
||||
<string name="revanced_settings_reset">আবার সেট করুন</string>
|
||||
@@ -42,6 +44,13 @@ This is because Crowdin requires temporarily flattening this file and removing t
|
||||
<string name="revanced_settings_import_reset">ReVanced সেটিং ডিফল্ট সেট করা হয়েছে</string>
|
||||
<string name="revanced_settings_import_success">%d সেটিং আমদানি হয়েছে</string>
|
||||
<string name="revanced_settings_import_failure_parse">আমদানি করা যায়নি: %s</string>
|
||||
<string name="revanced_pref_import_export_title">আমদানি এবং রপ্তানি</string>
|
||||
<string name="revanced_pref_import_export_summary">ReVanced সেটিং আমদানি বা রপ্তানি করুন</string>
|
||||
<!-- Settings about dialog. -->
|
||||
<string name="revanced_settings_about_links_body">আপনি ReVanced প্যাচ সংস্করণ <i>%s</i> ব্যবহার করছেন</string>
|
||||
<string name="revanced_settings_about_links_dev_header">দ্রষ্টব্য</string>
|
||||
<string name="revanced_settings_about_links_dev_body">এই সংস্করণ একটি প্রাক-প্রকাশনা এবং এতে আপনি অনাকাঙ্খিত সমস্যার সম্মুখিন হতে পারেন</string>
|
||||
<string name="revanced_settings_about_links_header">অফিশ্যাল লিংকসমূহ</string>
|
||||
</patch>
|
||||
<patch id="misc.gms.BaseGmsCoreSupportResourcePatch">
|
||||
<!-- Translations of this should not be longer than the original English text, otherwise the text can be clipped and not entirely shown. -->
|
||||
@@ -54,14 +63,6 @@ This is because Crowdin requires temporarily flattening this file and removing t
|
||||
</patch>
|
||||
</app>
|
||||
<app id="youtube">
|
||||
<patch id="misc.settings.SettingsResourcePatch">
|
||||
<string name="revanced_settings_about_links_body">আপনি ReVanced প্যাচ সংস্করণ <i>%s</i> ব্যবহার করছেন</string>
|
||||
<string name="revanced_settings_about_links_dev_header">দ্রষ্টব্য</string>
|
||||
<string name="revanced_settings_about_links_dev_body">এই সংস্করণ একটি প্রাক-প্রকাশনা এবং এতে আপনি অনাকাঙ্খিত সমস্যার সম্মুখিন হতে পারেন</string>
|
||||
<string name="revanced_settings_about_links_header">অফিশ্যাল লিংকসমূহ</string>
|
||||
<string name="revanced_pref_import_export_title">আমদানি এবং রপ্তানি</string>
|
||||
<string name="revanced_pref_import_export_summary">ReVanced সেটিং আমদানি বা রপ্তানি করুন</string>
|
||||
</patch>
|
||||
<patch id="misc.settings.SettingsPatch">
|
||||
<string name="revanced_settings_screen_00_about_title">সম্পর্কিত</string>
|
||||
<string name="revanced_settings_screen_01_ads_title">বিজ্ঞাপন</string>
|
||||
@@ -201,6 +202,7 @@ This is because Crowdin requires temporarily flattening this file and removing t
|
||||
<string name="revanced_hide_chips_shelf_summary_off">চিপ শেলপ প্রদর্শিত হয়েছে</string>
|
||||
<string name="revanced_hide_attributes_section_title">বৈশিষ্ট্য বিভাগ লুকান</string>
|
||||
<string name="revanced_hide_attributes_section_summary_on">\'বৈশিষ্ট্যযুক্ত স্থান\', গেম এবং সঙ্গীত বিভাগগুলি লুকানো আছে</string>
|
||||
<string name="revanced_hide_attributes_section_summary_off">\'বৈশিষ্ট্যযুক্ত স্থান\', গেম এবং সঙ্গীত বিভাগগুলি প্রদর্শিত হয়েছে</string>
|
||||
<string name="revanced_hide_info_cards_section_title">তথ্য কার্ড সেকশন লুকান</string>
|
||||
<string name="revanced_hide_info_cards_section_summary_on">তথ্য কার্ড সেকশন লুকিয়ে রয়েছে</string>
|
||||
<string name="revanced_hide_info_cards_section_summary_off">তথ্য কার্ড সেকশন প্রদর্শিত হয়েছে</string>
|
||||
@@ -231,13 +233,9 @@ This is because Crowdin requires temporarily flattening this file and removing t
|
||||
<string name="revanced_hide_keyword_content_phrases_title">লুকানোর জন্য কীওয়ার্ড</string>
|
||||
<!-- For localization it is preferred, but not required, if 'LeBlanc' is replaced with a localized name or a familiar word that has upper case letters in the middle of the word.
|
||||
This is because keywords can be in any language, and showing an example in the localized script helps convey this. -->
|
||||
<string name="revanced_hide_keyword_content_phrases_summary">লুকানোর জন্য কীওয়ার্ড এবং বাক্যাংশ, নতুন লাইনে পৃথক করা\n\nশব্দের মাঝে বড় হাতের অক্ষর থাকলে তা অবশ্যই সঠিক আবরণে লিখতে হবে (উদাহরণ: iPhone, TikTok, LeBlanc)</string>
|
||||
<string name="revanced_hide_keyword_content_about_title">কীওয়ার্ড ফিল্টারিং সম্পর্কে</string>
|
||||
<string name="revanced_hide_keyword_content_about_summary">প্রধান পাতা/সাবস্ক্রিপশন/অনুসন্ধান ফলাফল গুলো কীওয়ার্ড বাক্যাংশের সাথে মিলিয়ে লুকানোর জন্য ফিল্টার করা হয়েছে\n\nসীমাবদ্ধতা\n• কিছু Shorts নাও লুকানো হতে পারে\n• কিছু ইউআই উপাদান নাও লুকানো হতে পারে\n• কোন কীওয়ার্ড সার্চ করলে কোন ফলাফল নাও দেখাতে পারে</string>
|
||||
<!-- Translations _must_ use a localized example. For languages that do not use spaces between words (Chinese, Japanese, etc) the English AI example should be used since no localized examples exist. Or if using machine translations, or if nobody wants to think of a localized example, then the English 'ai' example should be left as-is. -->
|
||||
<!-- Translations of this should not be longer than the original English text, otherwise the text can be clipped and not entirely shown. -->
|
||||
<string name="revanced_hide_keyword_toast_invalid_common">অবৈধ কীওয়ার্ড ফিল্টার \'%s\' ব্যবহার করা যাবে না</string>
|
||||
<!-- Translations of this should not be longer than the original English text, otherwise the text can be clipped and not entirely shown. -->
|
||||
<string name="revanced_hide_keyword_toast_invalid_length">ত্রুটিপূর্ণ কীওয়ার্ড। \'%1$s\' টি %2$d অক্ষর থেকে কম</string>
|
||||
</patch>
|
||||
<patch id="ad.general.HideAdsResourcePatch">
|
||||
<string name="revanced_hide_general_ads_title">সাধারণ বিজ্ঞাপন লুকান</string>
|
||||
@@ -603,7 +601,6 @@ This is because Crowdin requires temporarily flattening this file and removing t
|
||||
<string name="revanced_player_overlay_opacity_invalid_toast">প্লেয়ার ওভারলে অস্বচ্ছতা অবশ্যই ০-১০০ এর মধ্যে হতে হবে</string>
|
||||
</patch>
|
||||
<patch id="layout.returnyoutubedislike.ReturnYouTubeDislikeResourcePatch">
|
||||
<string name="revanced_ryd_video_likes_hidden_by_video_owner">লুকিয়ে রয়েছে</string>
|
||||
<!-- Toast shown if network connection times out. Translations of this should not be longer than the original English or the text can be clipped and not entirely shown. -->
|
||||
<string name="revanced_ryd_failure_connection_timeout">অপছন্দ সাময়িকভাবে উপলভ্য নয় (API সময় শেষ হয়েছে)</string>
|
||||
<string name="revanced_ryd_failure_connection_status_code">অপছন্দ উপলভ্য নয় (অবস্থা %d)</string>
|
||||
@@ -798,8 +795,6 @@ This is because Crowdin requires temporarily flattening this file and removing t
|
||||
<string name="revanced_sb_new_segment_time_start">সেগমেন্টটি শুরু হওয়ার সময়</string>
|
||||
<string name="revanced_sb_new_segment_time_end">সেগমেন্টটি শেষ হওয়ার সময়</string>
|
||||
<string name="revanced_sb_new_segment_confirm_title">সময়কাল কি সঠিক?</string>
|
||||
<!-- Do not rearrange the (hour):(minute):second) time format operators here.
|
||||
YT shows the same seekbar time format for all languages, and this string is confirming the segment time as it appears in the seekbar. -->
|
||||
<string name="revanced_sb_new_segment_confirm_content">সেগমেন্ট সময়কাল\n\n%1$s\nথেকে\n%2$s\n\n(%3$s)\n\nজমা করার জন্য প্রস্তুত?</string>
|
||||
<string name="revanced_sb_new_segment_start_is_before_end">শুরু অবশ্যই শেষের আগে হতে হবে</string>
|
||||
<string name="revanced_sb_new_segment_mark_locations_first">আগে সময় বারে দুটি অবস্থান চিহ্নিত করুন</string>
|
||||
@@ -958,6 +953,10 @@ This is because Crowdin requires temporarily flattening this file and removing t
|
||||
<string name="revanced_announcements_connection_failed">ঘোষনাদাতার সাথে সম্পর্ক স্থাপন ব্যর্থ হয়েছে</string>
|
||||
<string name="revanced_announcements_dialog_dismiss">বাতিল করুন</string>
|
||||
</patch>
|
||||
<patch id="misc.dns.CheckWatchHistoryDomainNameResolutionPatch">
|
||||
<string name="revanced_check_watch_history_domain_name_dialog_title">সতর্কীকরণ</string>
|
||||
<string name="revanced_check_watch_history_domain_name_dialog_ignore">আবার দেখাবেন না</string>
|
||||
</patch>
|
||||
<patch id="misc.autorepeat.AutoRepeatPatch">
|
||||
<string name="revanced_auto_repeat_title">স্বয়ংক্রিয়ভাবে-আবার দেখানো সক্রিয় করুন</string>
|
||||
<string name="revanced_auto_repeat_summary_on">স্বয়ংক্রিয়ভাবে-আবার দেখানো সক্রিয় হয়েছে</string>
|
||||
@@ -1032,19 +1031,8 @@ This is because Crowdin requires temporarily flattening this file and removing t
|
||||
<string name="revanced_slide_to_seek_summary_on">ভিডিওর নির্দিষ্ট অংশে যেতে টানুন সক্রিয় করা হয়েছে</string>
|
||||
<string name="revanced_slide_to_seek_summary_off">ভিডিওর নির্দিষ্ট অংশে যেতে টানুন সক্রিয় করা হয়নি</string>
|
||||
</patch>
|
||||
<patch id="misc.fix.playback.SpoofClientPatch">
|
||||
<string name="revanced_spoof_client_screen_title">ক্লায়েন্ট স্পুফ করুন</string>
|
||||
<string name="revanced_spoof_client_screen_summary">প্লেব্যাক সমস্যা প্রতিরোধ করতে ক্লায়েন্ট স্পুফ করুন</string>
|
||||
<string name="revanced_spoof_client_title">ক্লায়েন্ট স্পুফ করুন</string>
|
||||
<string name="revanced_spoof_client_summary_on">ক্লায়েন্ট স্পুফ করা হয়েছে</string>
|
||||
<string name="revanced_spoof_client_summary_off">ক্লায়েন্ট স্পুফ করা হয়নি\n\nভিডিও প্লেব্যাক ঠিকমতো কাজ নাও করতে পারে</string>
|
||||
<string name="revanced_spoof_client_user_dialog_message">এই সেটিংটি বন্ধ করার ফলে ভিডিও প্লেব্যাক ত্রুটি হতে পারে।</string>
|
||||
<string name="revanced_spoof_client_use_ios_title">ক্লায়েন্ট iOS এ স্পুফ করুন</string>
|
||||
<string name="revanced_spoof_client_storyboard_timeout">ক্লায়েন্ট স্পুফ থাম্বনেইল সাময়িকভাবে উপলভ্য নয় (API সময় শেষ হয়েছে)</string>
|
||||
<string name="revanced_spoof_client_storyboard_io_exception">স্পুফ ক্লায়েন্ট থাম্বনেইল সাময়িকভাবে উপলভ্য নয়: %s</string>
|
||||
</patch>
|
||||
<!-- This patch is no longer used, these strings are not in use, and these strings will be deleted in the future. -->
|
||||
<patch id="misc.fix.playback.SpoofSignaturePatch">
|
||||
<patch id="misc.fix.playback.SpoofVideoStreamsPatch">
|
||||
<string name="revanced_spoof_video_streams_user_dialog_message">এই সেটিংটি বন্ধ করার ফলে ভিডিও প্লেব্যাক ত্রুটি হতে পারে।</string>
|
||||
</patch>
|
||||
<!-- This patch is no longer used and these strings will soon be deleted. -->
|
||||
<patch id="video.hdrbrightness.HDRBrightnessPatch">
|
||||
|
||||
@@ -32,15 +32,16 @@ This is because Crowdin requires temporarily flattening this file and removing t
|
||||
-->
|
||||
<resources>
|
||||
<app id="shared">
|
||||
<patch id="misc.checks.BaseCheckEnvironmentPatch">
|
||||
</patch>
|
||||
<patch id="misc.settings.BaseSettingsResourcePatch">
|
||||
<!-- Settings about dialog. -->
|
||||
</patch>
|
||||
<patch id="misc.gms.BaseGmsCoreSupportResourcePatch">
|
||||
<!-- Translations of this should not be longer than the original English text, otherwise the text can be clipped and not entirely shown. -->
|
||||
</patch>
|
||||
</app>
|
||||
<app id="youtube">
|
||||
<patch id="misc.settings.SettingsResourcePatch">
|
||||
</patch>
|
||||
<patch id="misc.settings.SettingsPatch">
|
||||
</patch>
|
||||
<patch id="misc.debugging.DebuggingPatch">
|
||||
@@ -57,7 +58,7 @@ This is because Crowdin requires temporarily flattening this file and removing t
|
||||
<!-- 'Component path builder strings' is the technical name for identifying the Litho UI layout items to hide. This is an advanced feature and most users will never use this. -->
|
||||
<!-- For localization it is preferred, but not required, if 'LeBlanc' is replaced with a localized name or a familiar word that has upper case letters in the middle of the word.
|
||||
This is because keywords can be in any language, and showing an example in the localized script helps convey this. -->
|
||||
<!-- Translations of this should not be longer than the original English text, otherwise the text can be clipped and not entirely shown. -->
|
||||
<!-- Translations _must_ use a localized example. For languages that do not use spaces between words (Chinese, Japanese, etc) the English AI example should be used since no localized examples exist. Or if using machine translations, or if nobody wants to think of a localized example, then the English 'ai' example should be left as-is. -->
|
||||
<!-- Translations of this should not be longer than the original English text, otherwise the text can be clipped and not entirely shown. -->
|
||||
</patch>
|
||||
<patch id="ad.general.HideAdsResourcePatch">
|
||||
@@ -171,8 +172,6 @@ This is because Crowdin requires temporarily flattening this file and removing t
|
||||
<patch id="layout.sponsorblock.SponsorBlockResourcePatch">
|
||||
<!-- Translations should use language similar to 'revanced_ryd_compact_layout_title' -->
|
||||
<!-- Toast shown if network connection times out. Translations of this should not be longer than the original English or the text can be clipped and not entirely shown. -->
|
||||
<!-- Do not rearrange the (hour):(minute):second) time format operators here.
|
||||
YT shows the same seekbar time format for all languages, and this string is confirming the segment time as it appears in the seekbar. -->
|
||||
<!-- Shown in the settings preferences, and translations can be any text length. -->
|
||||
</patch>
|
||||
<patch id="layout.spoofappversion.SpoofAppVersionPatch">
|
||||
@@ -206,6 +205,8 @@ This is because Crowdin requires temporarily flattening this file and removing t
|
||||
</patch>
|
||||
<patch id="misc.announcements.AnnouncementsPatch">
|
||||
</patch>
|
||||
<patch id="misc.dns.CheckWatchHistoryDomainNameResolutionPatch">
|
||||
</patch>
|
||||
<patch id="misc.autorepeat.AutoRepeatPatch">
|
||||
</patch>
|
||||
<patch id="misc.dimensions.spoof.SpoofDeviceDimensionsPatch">
|
||||
@@ -232,10 +233,7 @@ This is because Crowdin requires temporarily flattening this file and removing t
|
||||
</patch>
|
||||
<patch id="interaction.seekbar.EnableSlideToSeekPatch">
|
||||
</patch>
|
||||
<patch id="misc.fix.playback.SpoofClientPatch">
|
||||
</patch>
|
||||
<!-- This patch is no longer used, these strings are not in use, and these strings will be deleted in the future. -->
|
||||
<patch id="misc.fix.playback.SpoofSignaturePatch">
|
||||
<patch id="misc.fix.playback.SpoofVideoStreamsPatch">
|
||||
</patch>
|
||||
<!-- This patch is no longer used and these strings will soon be deleted. -->
|
||||
<patch id="video.hdrbrightness.HDRBrightnessPatch">
|
||||
|
||||
@@ -32,16 +32,17 @@ This is because Crowdin requires temporarily flattening this file and removing t
|
||||
-->
|
||||
<resources>
|
||||
<app id="shared">
|
||||
<patch id="misc.checks.BaseCheckEnvironmentPatch">
|
||||
</patch>
|
||||
<patch id="misc.settings.BaseSettingsResourcePatch">
|
||||
<string name="revanced_settings_reset">Restablir</string>
|
||||
<!-- Settings about dialog. -->
|
||||
</patch>
|
||||
<patch id="misc.gms.BaseGmsCoreSupportResourcePatch">
|
||||
<!-- Translations of this should not be longer than the original English text, otherwise the text can be clipped and not entirely shown. -->
|
||||
</patch>
|
||||
</app>
|
||||
<app id="youtube">
|
||||
<patch id="misc.settings.SettingsResourcePatch">
|
||||
</patch>
|
||||
<patch id="misc.settings.SettingsPatch">
|
||||
<string name="revanced_settings_screen_00_about_title">Quant a</string>
|
||||
</patch>
|
||||
@@ -59,7 +60,7 @@ This is because Crowdin requires temporarily flattening this file and removing t
|
||||
<!-- 'Component path builder strings' is the technical name for identifying the Litho UI layout items to hide. This is an advanced feature and most users will never use this. -->
|
||||
<!-- For localization it is preferred, but not required, if 'LeBlanc' is replaced with a localized name or a familiar word that has upper case letters in the middle of the word.
|
||||
This is because keywords can be in any language, and showing an example in the localized script helps convey this. -->
|
||||
<!-- Translations of this should not be longer than the original English text, otherwise the text can be clipped and not entirely shown. -->
|
||||
<!-- Translations _must_ use a localized example. For languages that do not use spaces between words (Chinese, Japanese, etc) the English AI example should be used since no localized examples exist. Or if using machine translations, or if nobody wants to think of a localized example, then the English 'ai' example should be left as-is. -->
|
||||
<!-- Translations of this should not be longer than the original English text, otherwise the text can be clipped and not entirely shown. -->
|
||||
</patch>
|
||||
<patch id="ad.general.HideAdsResourcePatch">
|
||||
@@ -175,8 +176,6 @@ This is because Crowdin requires temporarily flattening this file and removing t
|
||||
<string name="revanced_sb_appearance_category">Aparença</string>
|
||||
<!-- Translations should use language similar to 'revanced_ryd_compact_layout_title' -->
|
||||
<!-- Toast shown if network connection times out. Translations of this should not be longer than the original English or the text can be clipped and not entirely shown. -->
|
||||
<!-- Do not rearrange the (hour):(minute):second) time format operators here.
|
||||
YT shows the same seekbar time format for all languages, and this string is confirming the segment time as it appears in the seekbar. -->
|
||||
<!-- Shown in the settings preferences, and translations can be any text length. -->
|
||||
<string name="revanced_sb_stats_loading">S\'està carregant...</string>
|
||||
<string name="revanced_sb_reset">Restablir</string>
|
||||
@@ -214,6 +213,9 @@ This is because Crowdin requires temporarily flattening this file and removing t
|
||||
</patch>
|
||||
<patch id="misc.announcements.AnnouncementsPatch">
|
||||
</patch>
|
||||
<patch id="misc.dns.CheckWatchHistoryDomainNameResolutionPatch">
|
||||
<string name="revanced_check_watch_history_domain_name_dialog_title">Advertència</string>
|
||||
</patch>
|
||||
<patch id="misc.autorepeat.AutoRepeatPatch">
|
||||
</patch>
|
||||
<patch id="misc.dimensions.spoof.SpoofDeviceDimensionsPatch">
|
||||
@@ -240,10 +242,7 @@ This is because Crowdin requires temporarily flattening this file and removing t
|
||||
</patch>
|
||||
<patch id="interaction.seekbar.EnableSlideToSeekPatch">
|
||||
</patch>
|
||||
<patch id="misc.fix.playback.SpoofClientPatch">
|
||||
</patch>
|
||||
<!-- This patch is no longer used, these strings are not in use, and these strings will be deleted in the future. -->
|
||||
<patch id="misc.fix.playback.SpoofSignaturePatch">
|
||||
<patch id="misc.fix.playback.SpoofVideoStreamsPatch">
|
||||
</patch>
|
||||
<!-- This patch is no longer used and these strings will soon be deleted. -->
|
||||
<patch id="video.hdrbrightness.HDRBrightnessPatch">
|
||||
|
||||
@@ -32,6 +32,17 @@ This is because Crowdin requires temporarily flattening this file and removing t
|
||||
-->
|
||||
<resources>
|
||||
<app id="shared">
|
||||
<patch id="misc.checks.BaseCheckEnvironmentPatch">
|
||||
<string name="revanced_check_environment_failed_title">Kontroly selhaly</string>
|
||||
<string name="revanced_check_environment_dialog_open_official_source_button">Otevřít oficiální webovou stránku</string>
|
||||
<string name="revanced_check_environment_dialog_ignore_button">Ignorovat</string>
|
||||
<string name="revanced_check_environment_failed_message"><h5>Zdá se, že tuto aplikaci neupravujete.</h5><br>Tato aplikace nemusí fungovat správně, <b>může být škodlivá nebo dokonce nebezpečná pro použití</b>.<br><br>Z těchto kontrol vyplývá, že tato aplikace je předem upravena nebo získána od někoho jiného:<br><br><small>%1$s</small><br>Je důrazně doporučeno <b>odinstalovat tuto aplikaci a opravit ji sami</b> , abyste se ujistili, že používáte ověřenou a bezpečnou aplikaci.<p><br>Pokud je ignorováno, toto varování se zobrazí pouze dvakrát.</string>
|
||||
<string name="revanced_check_environment_not_same_patching_device">Upraveno na jiném zařízení</string>
|
||||
<string name="revanced_check_environment_manager_not_expected_installer">Není nainstalován ReVanced Manager</string>
|
||||
<string name="revanced_check_environment_not_near_patch_time">Upraveno před více než 10 minutami</string>
|
||||
<string name="revanced_check_environment_not_near_patch_time_days">Patchnuto před %s dny</string>
|
||||
<string name="revanced_check_environment_not_near_patch_time_invalid">APK datum sestavení je poškozeno</string>
|
||||
</patch>
|
||||
<patch id="misc.settings.BaseSettingsResourcePatch">
|
||||
<string name="revanced_settings_title">ReVanced</string>
|
||||
<string name="revanced_settings_confirm_user_dialog_title">Přejete si pokračovat?</string>
|
||||
@@ -43,6 +54,14 @@ This is because Crowdin requires temporarily flattening this file and removing t
|
||||
<string name="revanced_settings_import_reset">Nastavení Revanced resetováno do výchozího stavu</string>
|
||||
<string name="revanced_settings_import_success">Importováno %d nastavení</string>
|
||||
<string name="revanced_settings_import_failure_parse">Importováni selhalo: %s</string>
|
||||
<string name="revanced_pref_import_export_title">Import / Export</string>
|
||||
<string name="revanced_pref_import_export_summary">Importovat/ exportovat nastavení ReVanced</string>
|
||||
<!-- Settings about dialog. -->
|
||||
<string name="revanced_settings_about_links_body">Používáte ReVanced Patches verze <i>%s</i></string>
|
||||
<string name="revanced_settings_about_links_dev_header">Poznámka</string>
|
||||
<string name="revanced_settings_about_links_dev_body">Tato verze je předběžná verze a můžete zaznamenat neočekávané problémy</string>
|
||||
<string name="revanced_settings_about_links_header">Oficiální odkazy</string>
|
||||
<string name="revanced_settings_about_links_donate">Přispět</string>
|
||||
</patch>
|
||||
<patch id="misc.gms.BaseGmsCoreSupportResourcePatch">
|
||||
<!-- Translations of this should not be longer than the original English text, otherwise the text can be clipped and not entirely shown. -->
|
||||
@@ -55,15 +74,6 @@ This is because Crowdin requires temporarily flattening this file and removing t
|
||||
</patch>
|
||||
</app>
|
||||
<app id="youtube">
|
||||
<patch id="misc.settings.SettingsResourcePatch">
|
||||
<string name="revanced_settings">ReVanced</string>
|
||||
<string name="revanced_settings_about_links_body">Používáte ReVanced Patches verze <i>%s</i></string>
|
||||
<string name="revanced_settings_about_links_dev_header">Poznámka</string>
|
||||
<string name="revanced_settings_about_links_dev_body">Tato verze je předběžná verze a můžete zaznamenat neočekávané problémy</string>
|
||||
<string name="revanced_settings_about_links_header">Oficiální odkazy</string>
|
||||
<string name="revanced_pref_import_export_title">Import / Export</string>
|
||||
<string name="revanced_pref_import_export_summary">Importovat/ exportovat nastavení ReVanced</string>
|
||||
</patch>
|
||||
<patch id="misc.settings.SettingsPatch">
|
||||
<string name="revanced_settings_screen_00_about_title">O aplikaci</string>
|
||||
<string name="revanced_settings_screen_01_ads_title">Reklamy</string>
|
||||
@@ -71,7 +81,6 @@ This is because Crowdin requires temporarily flattening this file and removing t
|
||||
<string name="revanced_settings_screen_03_feed_title">Přísun</string>
|
||||
<string name="revanced_settings_screen_04_player_title">Přehrávač</string>
|
||||
<string name="revanced_settings_screen_05_general_title">Celkové rozložení</string>
|
||||
<string name="revanced_settings_screen_06_shorts_title">Shorts</string>
|
||||
<string name="revanced_settings_screen_07_seekbar_title">Lišta</string>
|
||||
<string name="revanced_settings_screen_08_swipe_controls_title">Ovládání gesty</string>
|
||||
<string name="revanced_settings_screen_11_misc_title">Ostatní</string>
|
||||
@@ -245,14 +254,18 @@ This is because Crowdin requires temporarily flattening this file and removing t
|
||||
<string name="revanced_hide_keyword_content_phrases_title">Klíčová slova ke skrytí</string>
|
||||
<!-- For localization it is preferred, but not required, if 'LeBlanc' is replaced with a localized name or a familiar word that has upper case letters in the middle of the word.
|
||||
This is because keywords can be in any language, and showing an example in the localized script helps convey this. -->
|
||||
<string name="revanced_hide_keyword_content_phrases_summary">klíčová slova a fráze ke skrytí, odděleno novými řádky\n\nSlova s velkými písmeny uprostřed musí být zadána s pláštěm (ie: iPhone, TikTok, LeBlanc)</string>
|
||||
<string name="revanced_hide_keyword_content_phrases_summary">klíčová slova a fráze ke skrytí, odděleno novými řádky\n\nKlíčová slova mohou být jména kanálů nebo jakýkoli text zobrazený v nadpisech videa\n\nSlova s velkými písmeny uprostřed musí být zadána se skříní (např: iPhone, iPhone, TikTok, LeBlanc)</string>
|
||||
<string name="revanced_hide_keyword_content_about_title">O filtrování klíčových slov</string>
|
||||
<string name="revanced_hide_keyword_content_about_summary">Výsledky domovského/předplatného/vyhledávání jsou filtrovány pro skrytí obsahu, který odpovídá výrazům klíčových slov\n\nOmezení\n• Některé krátkosti nemusí být skryty\n• Některé komponenty uživatelského rozhraní nemusí být skryté\n• Hledání klíčových slov nemusí zobrazovat žádné výsledky</string>
|
||||
<string name="revanced_hide_keyword_content_about_summary">Výsledky domovského/předplatného/vyhledávání jsou filtrovány pro skrytí obsahu, který odpovídá výrazům klíčových slov\n\nOmezení\n• Krátké nelze skrýt podle názvu kanálu\n• Některé komponenty uživatelského rozhraní nemusí být skryté\n• Hledání klíčového slova nemusí zobrazovat žádné výsledky</string>
|
||||
<string name="revanced_hide_keyword_content_about_whole_words_title">Porovnat celá slova</string>
|
||||
<!-- Translations _must_ use a localized example. For languages that do not use spaces between words (Chinese, Japanese, etc) the English AI example should be used since no localized examples exist. Or if using machine translations, or if nobody wants to think of a localized example, then the English 'ai' example should be left as-is. -->
|
||||
<string name="revanced_hide_keyword_content_about_whole_words_summary">Zaokrouhlení klíčového slova/fráze s dvojitými uvozovkami zabrání částečným shodám s názvy videí a kanálů<br><br>Například<br><b>\"ai\"</b> skryje video: <b>How does AI work?</b><br>, ale nebude skrýt: <b>What does fair use mean?</b></string>
|
||||
<!-- Translations of this should not be longer than the original English text, otherwise the text can be clipped and not entirely shown. -->
|
||||
<string name="revanced_hide_keyword_toast_invalid_common">Neplatné klíčové slovo. Nelze použít: \'%s\' jako filtr</string>
|
||||
<!-- Translations of this should not be longer than the original English text, otherwise the text can be clipped and not entirely shown. -->
|
||||
<string name="revanced_hide_keyword_toast_invalid_length">Neplatné klíčové slovo. \'%1$s\' je menší než %2$d znaků</string>
|
||||
<string name="revanced_hide_keyword_toast_invalid_broad">Klíčové slovo \'%s\' skryje všechna videa</string>
|
||||
<string name="revanced_hide_keyword_toast_invalid_common">Nelze použít klíčové slovo: %s</string>
|
||||
<string name="revanced_hide_keyword_toast_invalid_common_whole_word_required">Přidat uvozovky pro použití klíčového slova: %s</string>
|
||||
<string name="revanced_hide_keyword_toast_invalid_conflicting">Klíčové slovo obsahuje protichůdné deklarace: %s</string>
|
||||
<string name="revanced_hide_keyword_toast_invalid_length">Klíčové slovo je příliš krátké a vyžaduje uvozovky: %s</string>
|
||||
<string name="revanced_hide_keyword_toast_invalid_broad">Klíčové slovo skryje všechna videa: %s</string>
|
||||
</patch>
|
||||
<patch id="ad.general.HideAdsResourcePatch">
|
||||
<string name="revanced_hide_general_ads_title">Skrýt obecné reklamy</string>
|
||||
@@ -433,7 +446,7 @@ This is because Crowdin requires temporarily flattening this file and removing t
|
||||
<string name="revanced_hide_home_button_summary_on">Tlačítko Domů je skryté</string>
|
||||
<string name="revanced_hide_home_button_summary_off">Tlačítko Domů je zobrazeno</string>
|
||||
<!-- 'Shorts' should be translated using the same localized wording YouTube displays the tab. -->
|
||||
<string name="revanced_hide_shorts_button_title">Skrýt krátké</string>
|
||||
<string name="revanced_hide_shorts_button_title">Skrýt Shorts</string>
|
||||
<string name="revanced_hide_shorts_button_summary_on">Tlačítko \"Shorts\" je skryté</string>
|
||||
<string name="revanced_hide_shorts_button_summary_off">Tlačítko \"Shorts\" je viditelné</string>
|
||||
<!-- The Create button has no display name. Translate normally. -->
|
||||
@@ -618,6 +631,9 @@ This is because Crowdin requires temporarily flattening this file and removing t
|
||||
<string name="revanced_hide_shorts_save_sound_button_title">Skrýt zvuk do playlistu</string>
|
||||
<string name="revanced_hide_shorts_save_sound_button_summary_on">Uložit zvuk do playlistu je skrytý</string>
|
||||
<string name="revanced_hide_shorts_save_sound_button_summary_off">Ukládat zvuk do seznamu skladeb je zobrazen</string>
|
||||
<string name="revanced_hide_shorts_use_this_sound_button_title">Skrýt toto tlačítko zvuku</string>
|
||||
<string name="revanced_hide_shorts_use_this_sound_button_summary_on">Použít toto zvukové tlačítko je skryté</string>
|
||||
<string name="revanced_hide_shorts_use_this_sound_button_summary_off">Použít toto zvukové tlačítko je zobrazeno</string>
|
||||
<string name="revanced_hide_shorts_search_suggestions_title">Skrýt návrhy hledání</string>
|
||||
<string name="revanced_hide_shorts_search_suggestions_summary_on">Návrhy hledání jsou skryty</string>
|
||||
<string name="revanced_hide_shorts_search_suggestions_summary_off">Návrhy hledání jsou zobrazeny</string>
|
||||
@@ -681,7 +697,6 @@ This is because Crowdin requires temporarily flattening this file and removing t
|
||||
<string name="revanced_player_overlay_opacity_invalid_toast">Průhlednost překrytí přehrávače musí být od 0 do 100</string>
|
||||
</patch>
|
||||
<patch id="layout.returnyoutubedislike.ReturnYouTubeDislikeResourcePatch">
|
||||
<string name="revanced_ryd_video_likes_hidden_by_video_owner">Hidden</string>
|
||||
<!-- Toast shown if network connection times out. Translations of this should not be longer than the original English or the text can be clipped and not entirely shown. -->
|
||||
<string name="revanced_ryd_failure_connection_timeout">Líbí se mi dočasně nedostupné (vypršel časový limit API)</string>
|
||||
<string name="revanced_ryd_failure_connection_status_code">Nelíbí se mi nedostupné (status %d)</string>
|
||||
@@ -777,6 +792,7 @@ This is because Crowdin requires temporarily flattening this file and removing t
|
||||
<string name="revanced_sb_general_skipcount_sum_off">Přeskočit počet sledování není povoleno</string>
|
||||
<string name="revanced_sb_general_min_duration">Minimální doba trvání segmentu</string>
|
||||
<string name="revanced_sb_general_min_duration_sum">Segmenty kratší než tato hodnota (v sekundách) nebudou zobrazeny nebo přeskočeny</string>
|
||||
<string name="revanced_sb_general_min_duration_invalid">Neplatná doba trvání</string>
|
||||
<string name="revanced_sb_general_uuid">Vaše soukromé ID uživatele</string>
|
||||
<string name="revanced_sb_general_uuid_sum">Toto by mělo být ponecháno v soukromí. To je jako heslo a nemělo by být s nikým sdíleno. Pokud to někdo má, mohou vás zosobnit</string>
|
||||
<string name="revanced_sb_general_uuid_invalid">Soukromé ID uživatele musí mít alespoň 30 znaků</string>
|
||||
@@ -877,8 +893,6 @@ This is because Crowdin requires temporarily flattening this file and removing t
|
||||
<string name="revanced_sb_new_segment_time_start">Čas začátku segmentu</string>
|
||||
<string name="revanced_sb_new_segment_time_end">Čas ukončení segmentu v</string>
|
||||
<string name="revanced_sb_new_segment_confirm_title">Mají časy pravdu?</string>
|
||||
<!-- Do not rearrange the (hour):(minute):second) time format operators here.
|
||||
YT shows the same seekbar time format for all languages, and this string is confirming the segment time as it appears in the seekbar. -->
|
||||
<string name="revanced_sb_new_segment_confirm_content">Segment je od\n\n%1$s\ndo\n%2$s\n\n(%3$s)\n\nPřipraveno k odeslání?</string>
|
||||
<string name="revanced_sb_new_segment_start_is_before_end">Začátek musí být před koncem</string>
|
||||
<string name="revanced_sb_new_segment_mark_locations_first">Nejdříve označte dvě místa v časové liště</string>
|
||||
@@ -897,6 +911,7 @@ This is because Crowdin requires temporarily flattening this file and removing t
|
||||
<string name="revanced_sb_stats_username_changed">Uživatelské jméno bylo úspěšně změněno</string>
|
||||
<string name="revanced_sb_stats_reputation">Tvá reputace je <b>%.2f</b></string>
|
||||
<string name="revanced_sb_stats_submissions">Vytvořili jste <b>%s</b> segmenty</string>
|
||||
<string name="revanced_sb_stats_submissions_sum">Klepnutím sem zobrazíte své segmenty</string>
|
||||
<string name="revanced_sb_stats_saved_zero">Žebříček SponsorBlock</string>
|
||||
<string name="revanced_sb_stats_saved">Uložili jste lidi z <b>%s</b> segmentů</string>
|
||||
<string name="revanced_sb_stats_saved_sum_zero">Klepnutím sem zobrazíte globální statistiky a nejlepší přispěvatelé</string>
|
||||
@@ -978,7 +993,7 @@ This is because Crowdin requires temporarily flattening this file and removing t
|
||||
<string name="revanced_miniplayer_hide_rewind_forward_title">Skrýt přeskočit tlačítka vpřed a zpět</string>
|
||||
<string name="revanced_miniplayer_hide_rewind_forward_summary_on">Přeskočit vpřed a zpět jsou skryty</string>
|
||||
<string name="revanced_miniplayer_hide_rewind_forward_summary_off">Přeskočit vpřed a zpět jsou zobrazeny</string>
|
||||
<string name="revanced_miniplayer_opacity_title">Overlay opacity</string>
|
||||
<string name="revanced_miniplayer_opacity_title">Neprůhlednost překrytí</string>
|
||||
<string name="revanced_miniplayer_opacity_summary">Neprůhlednost mezi 0-100, kde 0 je průhledná</string>
|
||||
<string name="revanced_miniplayer_opacity_invalid_toast">Neprůhlednost překrytí minipřehrávače musí být mezi 0-100</string>
|
||||
</patch>
|
||||
@@ -1040,6 +1055,11 @@ This is because Crowdin requires temporarily flattening this file and removing t
|
||||
<string name="revanced_announcements_connection_failed">Připojení k poskytovateli oznámení se nezdařilo</string>
|
||||
<string name="revanced_announcements_dialog_dismiss">Zrušit</string>
|
||||
</patch>
|
||||
<patch id="misc.dns.CheckWatchHistoryDomainNameResolutionPatch">
|
||||
<string name="revanced_check_watch_history_domain_name_dialog_title">Varování</string>
|
||||
<string name="revanced_check_watch_history_domain_name_dialog_message">Vaše historie sledování není ukládána.<br><br>Příčinou je s největší pravděpodobností DNS blokátor reklam nebo síťový proxy server.<br><br>Chcete-li to opravit, přidejte<b>s.youtube.com</b> na whitelist nebo vypněte všechny DNS blokátory a proxy servery.</string>
|
||||
<string name="revanced_check_watch_history_domain_name_dialog_ignore">Znovu nezobrazovat</string>
|
||||
</patch>
|
||||
<patch id="misc.autorepeat.AutoRepeatPatch">
|
||||
<string name="revanced_auto_repeat_title">Povolit automatické opakování</string>
|
||||
<string name="revanced_auto_repeat_summary_on">Automaticky opakovat je povoleno</string>
|
||||
@@ -1114,35 +1134,23 @@ This is because Crowdin requires temporarily flattening this file and removing t
|
||||
<string name="revanced_slide_to_seek_summary_on">Posunutí pro vyhledání je povoleno</string>
|
||||
<string name="revanced_slide_to_seek_summary_off">Posunutí k vyhledání není povoleno</string>
|
||||
</patch>
|
||||
<patch id="misc.fix.playback.SpoofClientPatch">
|
||||
<string name="revanced_spoof_client_screen_title">Sponzor</string>
|
||||
<string name="revanced_spoof_client_screen_summary">Spořič klienta, aby zabránil problémům s přehráváním</string>
|
||||
<string name="revanced_spoof_client_title">Sponzor</string>
|
||||
<string name="revanced_spoof_client_summary_on">Klient je falešný</string>
|
||||
<string name="revanced_spoof_client_summary_off">Klient není spoofed\n\nPřehrávání videa nemusí fungovat</string>
|
||||
<string name="revanced_spoof_client_user_dialog_message">Vypnutí tohoto nastavení může způsobit problémy při přehrávání videa.</string>
|
||||
<string name="revanced_spoof_client_use_ios_title">Spořič do iOS</string>
|
||||
<string name="revanced_spoof_client_use_ios_summary_on">Klient je v současné době spokojen s iOS\n\nBoční efekty zahrnují:\n• HDR video nemusí být k dispozici\n• Historie sledování nemusí fungovat</string>
|
||||
<string name="revanced_spoof_client_use_ios_summary_off">Klient je v současné době spout s Androidem VR. Boční efekty zahrnují:\n• No HDR video\n• Dětská videa nepřehrávají\n• Pozastavená videa mohou náhodně pokračovat\n• Nízká kvalita krátkých náhledů ve vyhledávacím panelu\n• Tlačítko pro stažení akce je skryté\n• Karty s ukončenou obrazovkou jsou skryté</string>
|
||||
<string name="revanced_spoof_client_storyboard_timeout">Náhledy klientů nejsou k dispozici (vypršel časový limit API)</string>
|
||||
<string name="revanced_spoof_client_storyboard_io_exception">Spouštění náhledů klientů dočasně není k dispozici: %s</string>
|
||||
</patch>
|
||||
<!-- This patch is no longer used, these strings are not in use, and these strings will be deleted in the future. -->
|
||||
<patch id="misc.fix.playback.SpoofSignaturePatch">
|
||||
<string name="revanced_spoof_signature_verification_screen_title">Podpis aplikace</string>
|
||||
<string name="revanced_spoof_signature_verification_screen_summary">Podpis aplikace zabraňující problémům při přehrávání</string>
|
||||
<string name="revanced_spoof_signature_verification_enabled_title">Podpis aplikace</string>
|
||||
<string name="revanced_spoof_signature_verification_enabled_summary_on">Podpis aplikace spoofed\n\nBoční efekty zahrnují:\n• Rozšířená bitrate není k dispozici\n• Videa nelze stáhnout\n• Žádné náhledy pro placená videa</string>
|
||||
<string name="revanced_spoof_signature_verification_enabled_summary_off">Podpis aplikace není falešný\n\nPřehrávání videa nemusí fungovat</string>
|
||||
<string name="revanced_spoof_signature_verification_enabled_user_dialog_message">Vypnutí tohoto nastavení způsobí problémy při přehrávání videa.</string>
|
||||
<string name="revanced_spoof_signature_in_feed_enabled_title">Podpis aplikace do kanálu</string>
|
||||
<string name="revanced_spoof_signature_in_feed_enabled_summary_on">Podpis aplikace spoofed\n\nBoční efekty zahrnují:\n• Video kanálu chybí titulky\n• Automaticky přehrávaná videa se zobrazí ve vaší historii sledování</string>
|
||||
<string name="revanced_spoof_signature_in_feed_enabled_summary_off">Podpis aplikace není falešný pro videa s kanálem\n\nPřed zjištěním problémů s přehráváním se videa kanálu budou přehrávat méně než 1 minutu</string>
|
||||
<string name="revanced_spoof_storyboard_title">Příběh</string>
|
||||
<string name="revanced_spoof_storyboard_summary_on">Skládací krabice</string>
|
||||
<string name="revanced_spoof_storyboard_summary_off">Storyboard není falešný\n\nBoční efekty zahrnují:\n• Žádný ambientní režim\n• Náhledy v panelu vyhledávání jsou skryté</string>
|
||||
<string name="revanced_spoof_storyboard_timeout">Spoof storyboard dočasně není k dispozici (vypršel časový limit API)</string>
|
||||
<string name="revanced_spoof_storyboard_io_exception">Příběhová deska dočasně není k dispozici: %s</string>
|
||||
<patch id="misc.fix.playback.SpoofVideoStreamsPatch">
|
||||
<string name="revanced_spoof_video_streams_screen_title">Spouštěcí video streamy</string>
|
||||
<string name="revanced_spoof_video_streams_screen_summary">Spouštět klientské video streamy, aby se zabránilo problémům s přehráváním</string>
|
||||
<string name="revanced_spoof_video_streams_title">Spouštěcí video streamy</string>
|
||||
<string name="revanced_spoof_video_streams_summary_on">Video streamy jsou falešné</string>
|
||||
<string name="revanced_spoof_video_streams_summary_off">Video streamy nejsou falešné\n\nPřehrávání videa nemusí fungovat</string>
|
||||
<string name="revanced_spoof_video_streams_user_dialog_message">Vypnutí tohoto nastavení může způsobit problémy při přehrávání videa.</string>
|
||||
<string name="revanced_spoof_video_streams_client_title">Výchozí klient</string>
|
||||
<string name="revanced_spoof_video_streams_ios_force_avc_title">Síla AVC (H.264)</string>
|
||||
<string name="revanced_spoof_video_streams_ios_force_avc_summary_on">Video kodek je AVC (H.264)</string>
|
||||
<string name="revanced_spoof_video_streams_ios_force_avc_summary_off">Video kodek je VP9 nebo AV1</string>
|
||||
<string name="revanced_spoof_video_streams_ios_force_avc_no_hardware_vp9_summary_on">Vaše zařízení nemá hardwarové dekódování VP9 a toto nastavení je vždy zapnuto, když je aktivní spoofování klienta</string>
|
||||
<string name="revanced_spoof_video_streams_ios_force_avc_user_dialog_message">Povolení této funkce může zlepšit životnost baterie a opravit stahování přehrávání.\n\nAVC má maximální rozlišení 1080p a video přehrávání bude používat více dat než VP9 nebo AV1.</string>
|
||||
<string name="revanced_spoof_video_streams_about_ios_title">Boční efekty iOS</string>
|
||||
<string name="revanced_spoof_video_streams_about_ios_summary">• Filmy nebo placená videa nemusí přehrávat\n• Živočišné rekony začínající od začátku\n• Videa mohou skončit 1 sekundu na začátku\n• Žádný opus audio kodek</string>
|
||||
<string name="revanced_spoof_video_streams_about_android_vr_title">Boční efekty Android VR</string>
|
||||
<string name="revanced_spoof_video_streams_about_android_vr_summary">• Menu zvukové stopy chybí\n• Stabilní hlasitost není k dispozici</string>
|
||||
</patch>
|
||||
<!-- This patch is no longer used and these strings will soon be deleted. -->
|
||||
<patch id="video.hdrbrightness.HDRBrightnessPatch">
|
||||
|
||||
@@ -32,6 +32,17 @@ This is because Crowdin requires temporarily flattening this file and removing t
|
||||
-->
|
||||
<resources>
|
||||
<app id="shared">
|
||||
<patch id="misc.checks.BaseCheckEnvironmentPatch">
|
||||
<string name="revanced_check_environment_failed_title">Kontrol mislykkedes</string>
|
||||
<string name="revanced_check_environment_dialog_open_official_source_button">Åbn officielle hjemmeside</string>
|
||||
<string name="revanced_check_environment_dialog_ignore_button">Ignorer</string>
|
||||
<string name="revanced_check_environment_failed_message"><h5>Denne app ser ikke ud til at være lappet af dig.</h5><br>Denne app fungerer muligvis ikke korrekt, <b>kan være skadeligt eller endda farligt at bruge</b>.<br><br>Disse kontroller antyder, at denne app er pre-lappet eller opnået fra en anden:<br><br><small>%1$s</small><br>Det anbefales kraftigt at <b>afinstallere denne app og lappe den selv</b> for at sikre, at du bruger en valideret og sikker app.<p><br>Hvis ignoreret, vil denne advarsel kun blive vist to gange.</string>
|
||||
<string name="revanced_check_environment_not_same_patching_device">Rettet på en anden enhed</string>
|
||||
<string name="revanced_check_environment_manager_not_expected_installer">Ikke installeret af ReVanced Manager</string>
|
||||
<string name="revanced_check_environment_not_near_patch_time">Patched mere end 10 minutter siden</string>
|
||||
<string name="revanced_check_environment_not_near_patch_time_days">Patched %s dage siden</string>
|
||||
<string name="revanced_check_environment_not_near_patch_time_invalid">APK byggedato er ødelagt</string>
|
||||
</patch>
|
||||
<patch id="misc.settings.BaseSettingsResourcePatch">
|
||||
<string name="revanced_settings_title">ReVanced</string>
|
||||
<string name="revanced_settings_confirm_user_dialog_title">Ønsker du at fortsætte?</string>
|
||||
@@ -43,6 +54,14 @@ This is because Crowdin requires temporarily flattening this file and removing t
|
||||
<string name="revanced_settings_import_reset">ReVanced indstillinger nulstillet til standard</string>
|
||||
<string name="revanced_settings_import_success">Importerede %d indstillinger</string>
|
||||
<string name="revanced_settings_import_failure_parse">Import mislykkedes: %s</string>
|
||||
<string name="revanced_pref_import_export_title">Import / Eksport</string>
|
||||
<string name="revanced_pref_import_export_summary">Importer / Eksport ReVanced indstillinger</string>
|
||||
<!-- Settings about dialog. -->
|
||||
<string name="revanced_settings_about_links_body">Du bruger ReVanced Patches version <i>%s</i></string>
|
||||
<string name="revanced_settings_about_links_dev_header">Bemærkning</string>
|
||||
<string name="revanced_settings_about_links_dev_body">Denne version er en pre-release og du kan opleve uventede problemer</string>
|
||||
<string name="revanced_settings_about_links_header">Officielle links</string>
|
||||
<string name="revanced_settings_about_links_donate">Donér</string>
|
||||
</patch>
|
||||
<patch id="misc.gms.BaseGmsCoreSupportResourcePatch">
|
||||
<!-- Translations of this should not be longer than the original English text, otherwise the text can be clipped and not entirely shown. -->
|
||||
@@ -55,15 +74,6 @@ This is because Crowdin requires temporarily flattening this file and removing t
|
||||
</patch>
|
||||
</app>
|
||||
<app id="youtube">
|
||||
<patch id="misc.settings.SettingsResourcePatch">
|
||||
<string name="revanced_settings">ReVanced</string>
|
||||
<string name="revanced_settings_about_links_body">Du bruger ReVanced Patches version <i>%s</i></string>
|
||||
<string name="revanced_settings_about_links_dev_header">Bemærkning</string>
|
||||
<string name="revanced_settings_about_links_dev_body">Denne version er en pre-release og du kan opleve uventede problemer</string>
|
||||
<string name="revanced_settings_about_links_header">Officielle links</string>
|
||||
<string name="revanced_pref_import_export_title">Import / Eksport</string>
|
||||
<string name="revanced_pref_import_export_summary">Importer / Eksport ReVanced indstillinger</string>
|
||||
</patch>
|
||||
<patch id="misc.settings.SettingsPatch">
|
||||
<string name="revanced_settings_screen_00_about_title">Om</string>
|
||||
<string name="revanced_settings_screen_01_ads_title">Annoncer</string>
|
||||
@@ -244,14 +254,18 @@ This is because Crowdin requires temporarily flattening this file and removing t
|
||||
<string name="revanced_hide_keyword_content_phrases_title">Nøgleord at skjule</string>
|
||||
<!-- For localization it is preferred, but not required, if 'LeBlanc' is replaced with a localized name or a familiar word that has upper case letters in the middle of the word.
|
||||
This is because keywords can be in any language, and showing an example in the localized script helps convey this. -->
|
||||
<string name="revanced_hide_keyword_content_phrases_summary">Nøgleord og sætninger at skjule, adskilt af nye linjer\n\nOrd med store bogstaver i midten skal indtastes med casing (dvs. iPhone, TikTok, LeBlanc)</string>
|
||||
<string name="revanced_hide_keyword_content_phrases_summary">Nøgleord og sætninger at skjule, adskilt af nye linjer\n\nSøgeord kan være kanalnavne eller enhver tekst vist i video titler\n\nOrd med store bogstaver i midten skal indtastes med casing (dvs. iPhone, TikTok, LeBlanc)</string>
|
||||
<string name="revanced_hide_keyword_content_about_title">Om søgeord filtrering</string>
|
||||
<string name="revanced_hide_keyword_content_about_summary">Hjem/Abonnement/Søgeresultater filtreres for at skjule indhold, der matcher søgeordssætninger\n\nBegrænsninger\n• Nogle Shorts er muligvis ikke skjult\n• Nogle UI-komponenter er muligvis ikke skjult\n• Søger efter et søgeord, kan ikke vise nogen resultater</string>
|
||||
<string name="revanced_hide_keyword_content_about_summary">Hjem/Abonnement/Søgeresultater filtreres for at skjule indhold, der matcher søgeordssætninger\n\nBegrænsninger\n• Korte kan ikke skjules ved kanalnavn\n• Nogle UI-komponenter kan ikke skjules\n• Søger efter et søgeord, kan ikke vise nogen resultater</string>
|
||||
<string name="revanced_hide_keyword_content_about_whole_words_title">Match hele ord</string>
|
||||
<!-- Translations _must_ use a localized example. For languages that do not use spaces between words (Chinese, Japanese, etc) the English AI example should be used since no localized examples exist. Or if using machine translations, or if nobody wants to think of a localized example, then the English 'ai' example should be left as-is. -->
|
||||
<string name="revanced_hide_keyword_content_about_whole_words_summary">Omkring et nøgleord/sætning med dobbelt-citater vil forhindre partielle kampe af videotitler og kanalnavne<br><br>For eksempel<br><b>\"ai\"</b> vil skjule videoen: <b>How does AI work?</b><br>, men skjuler ikke: <b>What does fair use mean?</b></string>
|
||||
<!-- Translations of this should not be longer than the original English text, otherwise the text can be clipped and not entirely shown. -->
|
||||
<string name="revanced_hide_keyword_toast_invalid_common">Ugyldigt søgeord. Kan ikke bruge: \'%s\' som et filter</string>
|
||||
<!-- Translations of this should not be longer than the original English text, otherwise the text can be clipped and not entirely shown. -->
|
||||
<string name="revanced_hide_keyword_toast_invalid_length">Ugyldigt søgeord. \'%1$s\' er mindre end %2$d tegn</string>
|
||||
<string name="revanced_hide_keyword_toast_invalid_broad">Nøgleord \'%s\' vil skjule alle videoer</string>
|
||||
<string name="revanced_hide_keyword_toast_invalid_common">Kan ikke bruge søgeord: %s</string>
|
||||
<string name="revanced_hide_keyword_toast_invalid_common_whole_word_required">Tilføj tilbud for at bruge søgeord: %s</string>
|
||||
<string name="revanced_hide_keyword_toast_invalid_conflicting">Nøgleord har modstridende erklæringer: %s</string>
|
||||
<string name="revanced_hide_keyword_toast_invalid_length">Nøgleord er for kort og kræver tilbud: %s</string>
|
||||
<string name="revanced_hide_keyword_toast_invalid_broad">Nøgleord vil skjule alle videoer: %s</string>
|
||||
</patch>
|
||||
<patch id="ad.general.HideAdsResourcePatch">
|
||||
<string name="revanced_hide_general_ads_title">Skjul generelle annoncer</string>
|
||||
@@ -616,6 +630,9 @@ This is because Crowdin requires temporarily flattening this file and removing t
|
||||
<string name="revanced_hide_shorts_save_sound_button_title">Skjul gem lyd til afspilningslisteknappen</string>
|
||||
<string name="revanced_hide_shorts_save_sound_button_summary_on">Gem lyd til afspilningslisten er skjult</string>
|
||||
<string name="revanced_hide_shorts_save_sound_button_summary_off">Gem lyd til afspilningslisten vises</string>
|
||||
<string name="revanced_hide_shorts_use_this_sound_button_title">Skjul brug denne lydknap</string>
|
||||
<string name="revanced_hide_shorts_use_this_sound_button_summary_on">Brug denne lydknap er skjult</string>
|
||||
<string name="revanced_hide_shorts_use_this_sound_button_summary_off">Brug denne lydknap vises</string>
|
||||
<string name="revanced_hide_shorts_search_suggestions_title">Skjul søgeforslag</string>
|
||||
<string name="revanced_hide_shorts_search_suggestions_summary_on">Søgeforslag er skjult</string>
|
||||
<string name="revanced_hide_shorts_search_suggestions_summary_off">Søgeforslag er vist</string>
|
||||
@@ -679,7 +696,6 @@ This is because Crowdin requires temporarily flattening this file and removing t
|
||||
<string name="revanced_player_overlay_opacity_invalid_toast">Spiller overlay gennemsigtighed skal være mellem 0-100</string>
|
||||
</patch>
|
||||
<patch id="layout.returnyoutubedislike.ReturnYouTubeDislikeResourcePatch">
|
||||
<string name="revanced_ryd_video_likes_hidden_by_video_owner">Hidden</string>
|
||||
<!-- Toast shown if network connection times out. Translations of this should not be longer than the original English or the text can be clipped and not entirely shown. -->
|
||||
<string name="revanced_ryd_failure_connection_timeout">Dislikerer midlertidigt ikke tilgængelig (API-timeout ud)</string>
|
||||
<string name="revanced_ryd_failure_connection_status_code">Dislikationer er ikke tilgængelige (status %d)</string>
|
||||
@@ -775,6 +791,7 @@ This is because Crowdin requires temporarily flattening this file and removing t
|
||||
<string name="revanced_sb_general_skipcount_sum_off">Overspring tælling er ikke aktiveret</string>
|
||||
<string name="revanced_sb_general_min_duration">Minimum linjestykketid</string>
|
||||
<string name="revanced_sb_general_min_duration_sum">Segmenter kortere end denne værdi (i sekunder) vil ikke blive vist eller sprunget over</string>
|
||||
<string name="revanced_sb_general_min_duration_invalid">Ugyldig tidsvarighed</string>
|
||||
<string name="revanced_sb_general_uuid">Dit private bruger-id</string>
|
||||
<string name="revanced_sb_general_uuid_sum">Dette bør holdes privat. Dette er ligesom en adgangskode og bør ikke deles med nogen. Hvis nogen har dette, kan de udgive dig</string>
|
||||
<string name="revanced_sb_general_uuid_invalid">Privat bruger-id skal være mindst 30 tegn langt</string>
|
||||
@@ -875,8 +892,6 @@ This is because Crowdin requires temporarily flattening this file and removing t
|
||||
<string name="revanced_sb_new_segment_time_start">Tidspunkt for segmentet begynder på</string>
|
||||
<string name="revanced_sb_new_segment_time_end">Tidspunkt for segmentet slutter på</string>
|
||||
<string name="revanced_sb_new_segment_confirm_title">Er tiderne korrekte?</string>
|
||||
<!-- Do not rearrange the (hour):(minute):second) time format operators here.
|
||||
YT shows the same seekbar time format for all languages, and this string is confirming the segment time as it appears in the seekbar. -->
|
||||
<string name="revanced_sb_new_segment_confirm_content">Segmentet er fra\n\n%1$s\ntil\n%2$s\n\n(%3$s)\n\nKlar til at indsende?</string>
|
||||
<string name="revanced_sb_new_segment_start_is_before_end">Start skal være før slutningen</string>
|
||||
<string name="revanced_sb_new_segment_mark_locations_first">Markér to steder på tidsbjælken først</string>
|
||||
@@ -895,6 +910,7 @@ This is because Crowdin requires temporarily flattening this file and removing t
|
||||
<string name="revanced_sb_stats_username_changed">Brugernavn ændret</string>
|
||||
<string name="revanced_sb_stats_reputation">Dit omdømme er <b>%.2f</b></string>
|
||||
<string name="revanced_sb_stats_submissions">Du har oprettet <b>%s</b> segmenter</string>
|
||||
<string name="revanced_sb_stats_submissions_sum">Tryk her for at se dine segmenter</string>
|
||||
<string name="revanced_sb_stats_saved_zero">SponsorBlokér leaderboard</string>
|
||||
<string name="revanced_sb_stats_saved">Du har gemt folk fra <b>%s</b> segmenter</string>
|
||||
<string name="revanced_sb_stats_saved_sum_zero">Tryk her for at se de globale statistikker og topbidragsydere</string>
|
||||
@@ -975,7 +991,7 @@ This is because Crowdin requires temporarily flattening this file and removing t
|
||||
<string name="revanced_miniplayer_hide_rewind_forward_title">Skjul overspring fremad og tilbage knapper</string>
|
||||
<string name="revanced_miniplayer_hide_rewind_forward_summary_on">Spring frem og tilbage er skjult</string>
|
||||
<string name="revanced_miniplayer_hide_rewind_forward_summary_off">Spring frem og tilbage vises</string>
|
||||
<string name="revanced_miniplayer_opacity_title">Overlay opacity</string>
|
||||
<string name="revanced_miniplayer_opacity_title">Overlay uigennemsigtighed</string>
|
||||
<string name="revanced_miniplayer_opacity_summary">Gennemsigtighedsværdi mellem 0-100, hvor 0 er gennemsigtig</string>
|
||||
<string name="revanced_miniplayer_opacity_invalid_toast">Miniplayer overlay gennemsigtighed skal være mellem 0-100</string>
|
||||
</patch>
|
||||
@@ -1037,6 +1053,11 @@ This is because Crowdin requires temporarily flattening this file and removing t
|
||||
<string name="revanced_announcements_connection_failed">Kunne ikke forbinde til udbyder af annonceringer</string>
|
||||
<string name="revanced_announcements_dialog_dismiss">Luk</string>
|
||||
</patch>
|
||||
<patch id="misc.dns.CheckWatchHistoryDomainNameResolutionPatch">
|
||||
<string name="revanced_check_watch_history_domain_name_dialog_title">Advarsel</string>
|
||||
<string name="revanced_check_watch_history_domain_name_dialog_message">Din urhistorik gemmes ikke.<br><br>Dette skyldes sandsynligvis en DNS-annonceblokker eller netværksproxy.<br><br>For at løse dette, whitelist <b>s.youtube.com</b> eller slå alle DNS-blokkere og fuldmagter fra.</string>
|
||||
<string name="revanced_check_watch_history_domain_name_dialog_ignore">Vis ikke igen</string>
|
||||
</patch>
|
||||
<patch id="misc.autorepeat.AutoRepeatPatch">
|
||||
<string name="revanced_auto_repeat_title">Aktivér auto-gentag</string>
|
||||
<string name="revanced_auto_repeat_summary_on">Auto-gentag er aktiveret</string>
|
||||
@@ -1111,35 +1132,23 @@ This is because Crowdin requires temporarily flattening this file and removing t
|
||||
<string name="revanced_slide_to_seek_summary_on">Dias for at søge er aktiveret</string>
|
||||
<string name="revanced_slide_to_seek_summary_off">Dias til søgning er ikke aktiveret</string>
|
||||
</patch>
|
||||
<patch id="misc.fix.playback.SpoofClientPatch">
|
||||
<string name="revanced_spoof_client_screen_title">Spoof klient</string>
|
||||
<string name="revanced_spoof_client_screen_summary">Spoof klienten for at forhindre afspilningsproblemer</string>
|
||||
<string name="revanced_spoof_client_title">Spoof klient</string>
|
||||
<string name="revanced_spoof_client_summary_on">Kunden er spoofed</string>
|
||||
<string name="revanced_spoof_client_summary_off">Klienten er ikke forfalsket\n\nVideoafspilning fungerer muligvis ikke</string>
|
||||
<string name="revanced_spoof_client_user_dialog_message">At slå denne indstilling fra kan forårsage problemer med videoafspilning.</string>
|
||||
<string name="revanced_spoof_client_use_ios_title">Spoof klient til iOS</string>
|
||||
<string name="revanced_spoof_client_use_ios_summary_on">Klienten er i øjeblikket spoofed til iOS\n\nBivirkninger omfatter:\n• HDR-video er muligvis ikke tilgængelig\n• Se historie fungerer måske ikke</string>
|
||||
<string name="revanced_spoof_client_use_ios_summary_off">Klienten er i øjeblikket spoofed til Android VR. Bivirkninger omfatter:\n• Ingen HDR-video\n• Kids videoer ikke afspilning\n• Pause videoer kan tilfældigt genoptage\n• Lav kvalitet Shorts søgelinje miniaturer\n• Download handling knap er skjult\n• End screen cards are hidden</string>
|
||||
<string name="revanced_spoof_client_storyboard_timeout">Spoof klient miniaturer ikke tilgængelige (API timemed out)</string>
|
||||
<string name="revanced_spoof_client_storyboard_io_exception">Spoof klient miniaturer midlertidigt ikke tilgængelige: %s</string>
|
||||
</patch>
|
||||
<!-- This patch is no longer used, these strings are not in use, and these strings will be deleted in the future. -->
|
||||
<patch id="misc.fix.playback.SpoofSignaturePatch">
|
||||
<string name="revanced_spoof_signature_verification_screen_title">Spoof app signatur</string>
|
||||
<string name="revanced_spoof_signature_verification_screen_summary">Spoof app-signaturen for at forhindre afspilningsproblemer</string>
|
||||
<string name="revanced_spoof_signature_verification_enabled_title">Spoof app signatur</string>
|
||||
<string name="revanced_spoof_signature_verification_enabled_summary_on">App signatur spoofed\n\nBivirkninger omfatter:\n• Forbedret bitrate er ikke tilgængelig\n• Videoer kan ikke downloades\n• Ingen søgelinje miniaturer til betalte videoer</string>
|
||||
<string name="revanced_spoof_signature_verification_enabled_summary_off">App signatur ikke forfalsket\n\nVideo afspilning fungerer muligvis ikke</string>
|
||||
<string name="revanced_spoof_signature_verification_enabled_user_dialog_message">At slå denne indstilling fra vil forårsage problemer med videoafspilning.</string>
|
||||
<string name="revanced_spoof_signature_in_feed_enabled_title">Spoof app signatur i feed</string>
|
||||
<string name="revanced_spoof_signature_in_feed_enabled_summary_on">App signatur spoofed\n\nBivirkninger omfatter:\n• Feed videoer mangler undertekster\n• Automatisk afspillede feed videoer vil blive vist i din ur historie</string>
|
||||
<string name="revanced_spoof_signature_in_feed_enabled_summary_off">App signatur ikke spoofed for feed videoer\n\nFeed videoer vil spille i mindre end 1 minut, før der opstår afspilningsproblemer</string>
|
||||
<string name="revanced_spoof_storyboard_title">Spoof storyboard</string>
|
||||
<string name="revanced_spoof_storyboard_summary_on">Storyboard spoofed</string>
|
||||
<string name="revanced_spoof_storyboard_summary_off">Storyboard ikke forfalsket\n\nBivirkninger omfatter:\n• Ingen omgivende tilstand\n• Seekbar miniaturer er skjult</string>
|
||||
<string name="revanced_spoof_storyboard_timeout">Spoof storyboard midlertidigt ikke tilgængelig (API timemed out)</string>
|
||||
<string name="revanced_spoof_storyboard_io_exception">Spoof storyboard midlertidigt ikke tilgængelig: %s</string>
|
||||
<patch id="misc.fix.playback.SpoofVideoStreamsPatch">
|
||||
<string name="revanced_spoof_video_streams_screen_title">Spoof video streams</string>
|
||||
<string name="revanced_spoof_video_streams_screen_summary">Spoof klienten video streams for at forhindre afspilning problemer</string>
|
||||
<string name="revanced_spoof_video_streams_title">Spoof video streams</string>
|
||||
<string name="revanced_spoof_video_streams_summary_on">Video streams er spoofed</string>
|
||||
<string name="revanced_spoof_video_streams_summary_off">Videostreams er ikke forfalskede\n\nVideoafspilning fungerer muligvis ikke</string>
|
||||
<string name="revanced_spoof_video_streams_user_dialog_message">At slå denne indstilling fra kan forårsage problemer med videoafspilning.</string>
|
||||
<string name="revanced_spoof_video_streams_client_title">Standard klient</string>
|
||||
<string name="revanced_spoof_video_streams_ios_force_avc_title">Gennemtving AVC (H.264)</string>
|
||||
<string name="revanced_spoof_video_streams_ios_force_avc_summary_on">Video codec er AVC (H.264)</string>
|
||||
<string name="revanced_spoof_video_streams_ios_force_avc_summary_off">Video-codec er VP9 eller AV1</string>
|
||||
<string name="revanced_spoof_video_streams_ios_force_avc_no_hardware_vp9_summary_on">Din enhed har ikke VP9 hardwareafkodning, og denne indstilling er altid tændt, når Client spoofing er aktiveret</string>
|
||||
<string name="revanced_spoof_video_streams_ios_force_avc_user_dialog_message">Aktivering af dette kan forbedre batteriets levetid og rette afspilningsstuttering.\n\nAVC har en maksimal opløsning på 1080p, og videoafspilning vil bruge flere internetdata end VP9 eller AV1.</string>
|
||||
<string name="revanced_spoof_video_streams_about_ios_title">iOS forfalskning bivirkninger</string>
|
||||
<string name="revanced_spoof_video_streams_about_ios_summary">• Film eller betalte videoer kan ikke afspille\n• Livestreams starter fra begyndelsen\n• Videoer kan ende 1 sekund tidlig\n• Ingen opus lydkode</string>
|
||||
<string name="revanced_spoof_video_streams_about_android_vr_title">Android VR spoofing bivirkninger</string>
|
||||
<string name="revanced_spoof_video_streams_about_android_vr_summary">• Menuen Lydspor mangler\n• Stabil lydstyrke er ikke tilgængelig</string>
|
||||
</patch>
|
||||
<!-- This patch is no longer used and these strings will soon be deleted. -->
|
||||
<patch id="video.hdrbrightness.HDRBrightnessPatch">
|
||||
|
||||
@@ -32,6 +32,15 @@ This is because Crowdin requires temporarily flattening this file and removing t
|
||||
-->
|
||||
<resources>
|
||||
<app id="shared">
|
||||
<patch id="misc.checks.BaseCheckEnvironmentPatch">
|
||||
<string name="revanced_check_environment_failed_title">Überprüfungen fehlgeschlagen</string>
|
||||
<string name="revanced_check_environment_dialog_open_official_source_button">Offizielle Webseite öffnen</string>
|
||||
<string name="revanced_check_environment_dialog_ignore_button">Ignorieren</string>
|
||||
<string name="revanced_check_environment_not_same_patching_device">Auf einem anderen Gerät gepatcht</string>
|
||||
<string name="revanced_check_environment_manager_not_expected_installer">Nicht von ReVanced Manager installiert</string>
|
||||
<string name="revanced_check_environment_not_near_patch_time">Vor mehr als 10 Minuten gepatcht</string>
|
||||
<string name="revanced_check_environment_not_near_patch_time_invalid">APK-Erstellungsdatum ist beschädigt</string>
|
||||
</patch>
|
||||
<patch id="misc.settings.BaseSettingsResourcePatch">
|
||||
<string name="revanced_settings_title">ReVanced</string>
|
||||
<string name="revanced_settings_confirm_user_dialog_title">Möchtest du fortfahren?</string>
|
||||
@@ -43,6 +52,14 @@ This is because Crowdin requires temporarily flattening this file and removing t
|
||||
<string name="revanced_settings_import_reset">ReVanced Einstellungen auf Standard zurückgesetzt</string>
|
||||
<string name="revanced_settings_import_success">%d Einstellungen importiert</string>
|
||||
<string name="revanced_settings_import_failure_parse">Import fehlgeschlagen: %s</string>
|
||||
<string name="revanced_pref_import_export_title">Importieren / Exportieren</string>
|
||||
<string name="revanced_pref_import_export_summary">ReVanced Einstellungen importieren / exportieren</string>
|
||||
<!-- Settings about dialog. -->
|
||||
<string name="revanced_settings_about_links_body">Du verwendest ReVanced Patches Version <i>%s</i></string>
|
||||
<string name="revanced_settings_about_links_dev_header">Notiz</string>
|
||||
<string name="revanced_settings_about_links_dev_body">Diese Version ist eine Vorabversion und du könntest unerwartete Probleme haben</string>
|
||||
<string name="revanced_settings_about_links_header">Offizielle Links</string>
|
||||
<string name="revanced_settings_about_links_donate">Spenden</string>
|
||||
</patch>
|
||||
<patch id="misc.gms.BaseGmsCoreSupportResourcePatch">
|
||||
<!-- Translations of this should not be longer than the original English text, otherwise the text can be clipped and not entirely shown. -->
|
||||
@@ -55,15 +72,6 @@ This is because Crowdin requires temporarily flattening this file and removing t
|
||||
</patch>
|
||||
</app>
|
||||
<app id="youtube">
|
||||
<patch id="misc.settings.SettingsResourcePatch">
|
||||
<string name="revanced_settings">ReVanced</string>
|
||||
<string name="revanced_settings_about_links_body">Du verwendest ReVanced Patches Version <i>%s</i></string>
|
||||
<string name="revanced_settings_about_links_dev_header">Notiz</string>
|
||||
<string name="revanced_settings_about_links_dev_body">Diese Version ist eine Vorabversion und du könntest unerwartete Probleme haben</string>
|
||||
<string name="revanced_settings_about_links_header">Offizielle Links</string>
|
||||
<string name="revanced_pref_import_export_title">Importieren / Exportieren</string>
|
||||
<string name="revanced_pref_import_export_summary">ReVanced Einstellungen importieren / exportieren</string>
|
||||
</patch>
|
||||
<patch id="misc.settings.SettingsPatch">
|
||||
<string name="revanced_settings_screen_00_about_title">Über</string>
|
||||
<string name="revanced_settings_screen_01_ads_title">Werbung</string>
|
||||
@@ -71,7 +79,6 @@ This is because Crowdin requires temporarily flattening this file and removing t
|
||||
<string name="revanced_settings_screen_03_feed_title">Feed</string>
|
||||
<string name="revanced_settings_screen_04_player_title">Player</string>
|
||||
<string name="revanced_settings_screen_05_general_title">Generelles Layout</string>
|
||||
<string name="revanced_settings_screen_06_shorts_title">Shorts</string>
|
||||
<string name="revanced_settings_screen_07_seekbar_title">Suchleiste</string>
|
||||
<string name="revanced_settings_screen_08_swipe_controls_title">Wischgesten</string>
|
||||
<string name="revanced_settings_screen_11_misc_title">Sonstiges</string>
|
||||
@@ -245,14 +252,18 @@ This is because Crowdin requires temporarily flattening this file and removing t
|
||||
<string name="revanced_hide_keyword_content_phrases_title">Zu versteckende Stichwörter</string>
|
||||
<!-- For localization it is preferred, but not required, if 'LeBlanc' is replaced with a localized name or a familiar word that has upper case letters in the middle of the word.
|
||||
This is because keywords can be in any language, and showing an example in the localized script helps convey this. -->
|
||||
<string name="revanced_hide_keyword_content_phrases_summary">Stichwörter und zu versteckende Phrasen durch neue Zeilen\n\ngetrennte Wörter mit Großbuchstaben in der Mitte müssen mit dem Gehäuse eingegeben werden (z.B. iPhone, TikTok, LeBlanc)</string>
|
||||
<string name="revanced_hide_keyword_content_phrases_summary">Stichwörter und zu versteckende Phrasen durch neue Zeilen\n\ngetrennte Schlüsselwörter können Kanalnamen oder beliebiger Text sein, der in den Videotiteln\n\nWörter mit Großbuchstaben in der Mitte angezeigt werden muss mit dem Gehäuse eingegeben werden (z.B. iPhone, TikTok, LeBlanc)</string>
|
||||
<string name="revanced_hide_keyword_content_about_title">Über Keyword-Filterung</string>
|
||||
<string name="revanced_hide_keyword_content_about_summary">Home/Abonnement/Suchergebnisse werden gefiltert, um Inhalte auszublenden, die den Schlüsselwörtern entsprechen\n\nBeschränkungen\n • Einige Shorts könnten nicht ausgeblendet werden\n• Einige UI-Komponenten könnten nicht ausgeblendet werden\n• Suche nach einem Schlüsselwort könnte keine Ergebnisse liefern</string>
|
||||
<string name="revanced_hide_keyword_content_about_summary">Home/Abonnement/Suchergebnisse werden gefiltert, um Inhalte zu verstecken, die den Schlüsselwörtern\n\nBeschränkungen\nentsprechen • Shorts können nicht mit dem Kanalnamen\nversteckt werden • Einige UI-Komponenten können nicht versteckt werden\n• Suche nach einem Stichwort kann keine Ergebnisse zeigen</string>
|
||||
<string name="revanced_hide_keyword_content_about_whole_words_title">Ganze Wörter abgleichen</string>
|
||||
<!-- Translations _must_ use a localized example. For languages that do not use spaces between words (Chinese, Japanese, etc) the English AI example should be used since no localized examples exist. Or if using machine translations, or if nobody wants to think of a localized example, then the English 'ai' example should be left as-is. -->
|
||||
<string name="revanced_hide_keyword_content_about_whole_words_summary">Durch das Umschließen mit doppelten Anführungszeichen wird verhindert, dass teilweise Videotitel und Kanalnamen<br><br><br><b>\"ai\"</b> wird das Video ausblenden: <b>How does AI work?</b><br>aber nicht versteckt: <b>What does fair use mean?</b></string>
|
||||
<!-- Translations of this should not be longer than the original English text, otherwise the text can be clipped and not entirely shown. -->
|
||||
<string name="revanced_hide_keyword_toast_invalid_common">Ungültiges Schlüsselwort. Kann nicht verwenden: \'%s\' als Filter</string>
|
||||
<!-- Translations of this should not be longer than the original English text, otherwise the text can be clipped and not entirely shown. -->
|
||||
<string name="revanced_hide_keyword_toast_invalid_length">Ungültiges Schlüsselwort. \'%1$s\' ist weniger als %2$d Zeichen</string>
|
||||
<string name="revanced_hide_keyword_toast_invalid_broad">Schlüsselwort \'%s\' wird alle Videos ausblenden</string>
|
||||
<string name="revanced_hide_keyword_toast_invalid_common">Kann Schlüsselwort nicht verwenden: %s</string>
|
||||
<string name="revanced_hide_keyword_toast_invalid_common_whole_word_required">Zitate hinzufügen, um Schlüsselwort zu verwenden: %s</string>
|
||||
<string name="revanced_hide_keyword_toast_invalid_conflicting">Schlüsselwort hat widersprüchliche Erklärungen: %s</string>
|
||||
<string name="revanced_hide_keyword_toast_invalid_length">Keyword ist zu kurz und erfordert Anführungszeichen: %s</string>
|
||||
<string name="revanced_hide_keyword_toast_invalid_broad">Stichwort wird alle Videos ausblenden: %s</string>
|
||||
</patch>
|
||||
<patch id="ad.general.HideAdsResourcePatch">
|
||||
<string name="revanced_hide_general_ads_title">Allgemeine Werbung ausblenden</string>
|
||||
@@ -376,7 +387,7 @@ This is because Crowdin requires temporarily flattening this file and removing t
|
||||
<patch id="layout.buttons.action.HideButtonsPatch">
|
||||
<string name="revanced_hide_buttons_screen_title">Aktionstasten</string>
|
||||
<string name="revanced_hide_buttons_screen_summary">Verstecke oder zeige Schaltflächen unter Videos</string>
|
||||
<string name="revanced_hide_like_dislike_button_title">Gefällt mir</string>
|
||||
<string name="revanced_hide_like_dislike_button_title">Verstecke Likes und Dislikes</string>
|
||||
<string name="revanced_hide_like_dislike_button_summary_on">\"Gefällt mir\"-Tasten sind ausgeblendet</string>
|
||||
<string name="revanced_hide_like_dislike_button_summary_off">\"Gefällt mir\"-Tasten werden angezeigt</string>
|
||||
<!-- 'Share' should be translated with the same localized wording that YouTube displays. -->
|
||||
@@ -618,15 +629,18 @@ This is because Crowdin requires temporarily flattening this file and removing t
|
||||
<string name="revanced_hide_shorts_save_sound_button_title">Speicherton in Wiedergabelisten-Button ausblenden</string>
|
||||
<string name="revanced_hide_shorts_save_sound_button_summary_on">Ton in Wiedergabeliste speichern ist ausgeblendet</string>
|
||||
<string name="revanced_hide_shorts_save_sound_button_summary_off">Ton in Wiedergabeliste speichern wird angezeigt</string>
|
||||
<string name="revanced_hide_shorts_use_this_sound_button_title">Diese Sound-Taste ausblenden</string>
|
||||
<string name="revanced_hide_shorts_use_this_sound_button_summary_on">Diese Sound-Taste ist ausgeblendet</string>
|
||||
<string name="revanced_hide_shorts_use_this_sound_button_summary_off">Diese Sound-Taste wird angezeigt</string>
|
||||
<string name="revanced_hide_shorts_search_suggestions_title">Suchvorschläge ausblenden</string>
|
||||
<string name="revanced_hide_shorts_search_suggestions_summary_on">Suchvorschläge sind ausgeblendet</string>
|
||||
<string name="revanced_hide_shorts_search_suggestions_summary_off">Suchvorschläge werden angezeigt</string>
|
||||
<string name="revanced_hide_shorts_like_button_title">Verstecke wie Button</string>
|
||||
<string name="revanced_hide_shorts_like_button_title">Verstecke \"Gefällt mir\" Button</string>
|
||||
<string name="revanced_hide_shorts_like_button_summary_on">\"Gefällt mir\" Button ist ausgeblendet</string>
|
||||
<string name="revanced_hide_shorts_like_button_summary_off">\"Gefällt mir\" Button wird angezeigt</string>
|
||||
<string name="revanced_hide_shorts_dislike_button_title">Verstecke nicht wie Button</string>
|
||||
<string name="revanced_hide_shorts_dislike_button_summary_on">Nicht wie Button ist ausgeblendet</string>
|
||||
<string name="revanced_hide_shorts_dislike_button_summary_off">Button wird angezeigt</string>
|
||||
<string name="revanced_hide_shorts_dislike_button_title">Verstecke \"Gefällt mir nicht\" Button</string>
|
||||
<string name="revanced_hide_shorts_dislike_button_summary_on">\"Gefällt mir nicht\" Button ist ausgeblendet</string>
|
||||
<string name="revanced_hide_shorts_dislike_button_summary_off">\"Gefällt mir nicht\" Button wird angezeigt</string>
|
||||
<string name="revanced_hide_shorts_comments_button_title">Kommentar-Button ausblenden</string>
|
||||
<string name="revanced_hide_shorts_comments_button_summary_on">Kommentar-Button ist ausgeblendet</string>
|
||||
<string name="revanced_hide_shorts_comments_button_summary_off">Kommentar-Button wird angezeigt</string>
|
||||
@@ -681,11 +695,10 @@ This is because Crowdin requires temporarily flattening this file and removing t
|
||||
<string name="revanced_player_overlay_opacity_invalid_toast">Spieler-Overlay-Deckkraft muss zwischen 0-100 liegen</string>
|
||||
</patch>
|
||||
<patch id="layout.returnyoutubedislike.ReturnYouTubeDislikeResourcePatch">
|
||||
<string name="revanced_ryd_video_likes_hidden_by_video_owner">Nicht anzeigen</string>
|
||||
<!-- Toast shown if network connection times out. Translations of this should not be longer than the original English or the text can be clipped and not entirely shown. -->
|
||||
<string name="revanced_ryd_failure_connection_timeout">Dislikes vorläufig nicht verfügbar (API Timeout)</string>
|
||||
<string name="revanced_ryd_failure_connection_status_code">Dislikes nicht verfügbar (Status %d)</string>
|
||||
<string name="revanced_ryd_failure_client_rate_limit_requested">Nicht verfügbar (Client-API-Limit erreicht)</string>
|
||||
<string name="revanced_ryd_failure_client_rate_limit_requested">Dislikes nicht verfügbar (Client-API-Limit erreicht)</string>
|
||||
<string name="revanced_ryd_failure_generic">Dislikes nicht verfügbar (%s)</string>
|
||||
<!-- Toast shown if the user enables RYD while a video is opened, and then tries to vote for the video. -->
|
||||
<string name="revanced_ryd_failure_ryd_enabled_while_playing_video_then_user_voted">Video neu laden, um mit Return YouTube Dislike abzustimmen</string>
|
||||
@@ -699,7 +712,7 @@ This is because Crowdin requires temporarily flattening this file and removing t
|
||||
<string name="revanced_ryd_dislike_percentage_summary_on">Dislikes als Prozentsatz angezeigt</string>
|
||||
<string name="revanced_ryd_dislike_percentage_summary_off">Dislikes als Nummer angezeigt</string>
|
||||
<!-- Translations should use language similar to 'revanced_sb_enable_compact_skip_button' -->
|
||||
<string name="revanced_ryd_compact_layout_title">Kompakt wie Button</string>
|
||||
<string name="revanced_ryd_compact_layout_title">Kompakter \"Gefällt mir\" Button</string>
|
||||
<string name="revanced_ryd_compact_layout_summary_on">\"Gefällt mir\" Button für minimale Breite</string>
|
||||
<string name="revanced_ryd_compact_layout_summary_off">\"Gefällt mir\" Button für das beste Aussehen</string>
|
||||
<string name="revanced_ryd_toast_on_connection_error_title">Einen Toast anzeigen, wenn die API nicht verfügbar ist</string>
|
||||
@@ -777,6 +790,7 @@ This is because Crowdin requires temporarily flattening this file and removing t
|
||||
<string name="revanced_sb_general_skipcount_sum_off">Überspringungszähler ist nicht aktiviert</string>
|
||||
<string name="revanced_sb_general_min_duration">Mindestdauer der Segmente</string>
|
||||
<string name="revanced_sb_general_min_duration_sum">Segmente kürzer als dieser Wert (in Sekunden) werden nicht angezeigt oder übersprungen</string>
|
||||
<string name="revanced_sb_general_min_duration_invalid">Ungültige Zeitdauer</string>
|
||||
<string name="revanced_sb_general_uuid">Ihre private Benutzer-Id</string>
|
||||
<string name="revanced_sb_general_uuid_sum">Das sollte vertraulich behandelt werden. Das ist wie ein Passwort und sollte mit niemandem geteilt werden. Wenn jemand das hat, kann er sich für dich ausgeben</string>
|
||||
<string name="revanced_sb_general_uuid_invalid">Private Benutzer-Id muss mindestens 30 Zeichen lang sein</string>
|
||||
@@ -857,7 +871,7 @@ This is because Crowdin requires temporarily flattening this file and removing t
|
||||
<string name="revanced_sb_submit_failed_duplicate">Segment kann nicht abgesendet werden. \nBereits vorhanden</string>
|
||||
<string name="revanced_sb_submit_succeeded">Segment erfolgreich übertragen</string>
|
||||
<!-- Toast shown if network connection times out. Translations of this should not be longer than the original English or the text can be clipped and not entirely shown. -->
|
||||
<string name="revanced_sb_sponsorblock_connection_failure_timeout">SponsorBlock vorübergehend nicht verfügbar (API 🕛 out)</string>
|
||||
<string name="revanced_sb_sponsorblock_connection_failure_timeout">SponsorBlock vorübergehend nicht verfügbar (API Timeout)</string>
|
||||
<string name="revanced_sb_sponsorblock_connection_failure_status">SponsorBlock vorübergehend nicht verfügbar (Status %d)</string>
|
||||
<string name="revanced_sb_sponsorblock_connection_failure_generic">SponsorBlock vorübergehend nicht verfügbar</string>
|
||||
<string name="revanced_sb_vote_failed_timeout">Abstimmung für Segment nicht möglich (API Timeout)</string>
|
||||
@@ -877,8 +891,6 @@ This is because Crowdin requires temporarily flattening this file and removing t
|
||||
<string name="revanced_sb_new_segment_time_start">Das Segiment beginnt ab</string>
|
||||
<string name="revanced_sb_new_segment_time_end">Das Segiment endet bei</string>
|
||||
<string name="revanced_sb_new_segment_confirm_title">Sind diese Zeiten richtig?</string>
|
||||
<!-- Do not rearrange the (hour):(minute):second) time format operators here.
|
||||
YT shows the same seekbar time format for all languages, and this string is confirming the segment time as it appears in the seekbar. -->
|
||||
<string name="revanced_sb_new_segment_confirm_content">Das Segment ist von\n\n\n%1$s\nbis\n%2$s\n\n(%3$s)\n\nBereit zum Absenden?</string>
|
||||
<string name="revanced_sb_new_segment_start_is_before_end">Start muss vor dem Ende sein</string>
|
||||
<string name="revanced_sb_new_segment_mark_locations_first">Markieren sie zuerst zwei Punkte auf der Zeitleiste</string>
|
||||
@@ -889,7 +901,7 @@ This is because Crowdin requires temporarily flattening this file and removing t
|
||||
<string name="revanced_sb_stats">Statistiken</string>
|
||||
<!-- Shown in the settings preferences, and translations can be any text length. -->
|
||||
<string name="revanced_sb_stats_connection_failure">Statistiken vorübergehend nicht verfügbar (API ist herunter)</string>
|
||||
<string name="revanced_sb_stats_loading">Lädt …</string>
|
||||
<string name="revanced_sb_stats_loading">Lädt...</string>
|
||||
<string name="revanced_sb_stats_sb_disabled">SponsorBlock ist deaktiviert</string>
|
||||
<string name="revanced_sb_stats_username">Ihr Benutzername: <b>%s</b></string>
|
||||
<string name="revanced_sb_stats_username_change">Tippe hier, um deinen Benutzernamen zu ändern</string>
|
||||
@@ -897,6 +909,7 @@ This is because Crowdin requires temporarily flattening this file and removing t
|
||||
<string name="revanced_sb_stats_username_changed">Benutzername wurde geändert</string>
|
||||
<string name="revanced_sb_stats_reputation">Dein Ruf ist <b>%.2f</b></string>
|
||||
<string name="revanced_sb_stats_submissions">Du hast <b>%s</b> Segmente erstellt</string>
|
||||
<string name="revanced_sb_stats_submissions_sum">Tippen Sie hier, um Ihre Segmente anzuzeigen</string>
|
||||
<string name="revanced_sb_stats_saved_zero">SponsorBlock Rangliste</string>
|
||||
<string name="revanced_sb_stats_saved">Du hast den Leuten <b>%s</b> Segmente erspart</string>
|
||||
<string name="revanced_sb_stats_saved_sum_zero">Hier tippen, um die globalen Statistiken und Top-Beitragszahler zu sehen</string>
|
||||
@@ -943,7 +956,7 @@ This is because Crowdin requires temporarily flattening this file and removing t
|
||||
<string name="revanced_start_page_entry_5">Shorts</string>
|
||||
<!-- 'You' should be translated using the same localized wording YouTube displays for the You (library) tab. -->
|
||||
<string name="revanced_start_page_entry_6">Tab</string>
|
||||
<string name="revanced_start_page_entry_7">Geiked Videos</string>
|
||||
<string name="revanced_start_page_entry_7">Videos, die ich mag</string>
|
||||
<!-- 'History' should be translated using the same localized wording YouTube displays for the 'history' section in the 'You' tab. -->
|
||||
<string name="revanced_start_page_entry_8">Verlauf</string>
|
||||
<string name="revanced_start_page_entry_9">Beliebt</string>
|
||||
@@ -978,7 +991,7 @@ This is because Crowdin requires temporarily flattening this file and removing t
|
||||
<string name="revanced_miniplayer_hide_rewind_forward_title">Vorwärts- und Rückwärts-Buttons ausblenden</string>
|
||||
<string name="revanced_miniplayer_hide_rewind_forward_summary_on">Vorwärts skippen und zurück sind ausgeblendet</string>
|
||||
<string name="revanced_miniplayer_hide_rewind_forward_summary_off">Vorwärts und zurück springen werden angezeigt</string>
|
||||
<string name="revanced_miniplayer_opacity_title">Overlay opacity</string>
|
||||
<string name="revanced_miniplayer_opacity_title">Deckkraft der Überlagerung</string>
|
||||
<string name="revanced_miniplayer_opacity_summary">Deckkraft Wert zwischen 0-100, wobei 0 transparent ist</string>
|
||||
<string name="revanced_miniplayer_opacity_invalid_toast">Miniplayer-Overlay-Deckkraft muss zwischen 0-100 liegen</string>
|
||||
</patch>
|
||||
@@ -1040,6 +1053,11 @@ This is because Crowdin requires temporarily flattening this file and removing t
|
||||
<string name="revanced_announcements_connection_failed">Verbindung zum Ankündigungsanbieter fehlgeschlagen</string>
|
||||
<string name="revanced_announcements_dialog_dismiss">Verwerfen</string>
|
||||
</patch>
|
||||
<patch id="misc.dns.CheckWatchHistoryDomainNameResolutionPatch">
|
||||
<string name="revanced_check_watch_history_domain_name_dialog_title">Warnung</string>
|
||||
<string name="revanced_check_watch_history_domain_name_dialog_message">Ihr Verlauf wird nicht gespeichert.<br><br>Dies wird höchstwahrscheinlich durch einen DNS-Werbeblocker oder einen Netzwerkproxy verursacht.<br><br>Um dies zu beheben, setze <b>s.youtube.com</b> auf die Whitelist oder schalten Sie alle DNS-Blocker und Proxies aus.</string>
|
||||
<string name="revanced_check_watch_history_domain_name_dialog_ignore">Nicht wieder anzeigen</string>
|
||||
</patch>
|
||||
<patch id="misc.autorepeat.AutoRepeatPatch">
|
||||
<string name="revanced_auto_repeat_title">Auto-Wiederholung aktivieren</string>
|
||||
<string name="revanced_auto_repeat_summary_on">Auto-Wiederholung ist aktiviert</string>
|
||||
@@ -1114,35 +1132,22 @@ This is because Crowdin requires temporarily flattening this file and removing t
|
||||
<string name="revanced_slide_to_seek_summary_on">Slide zum Suchen ist aktiviert</string>
|
||||
<string name="revanced_slide_to_seek_summary_off">Slide zum Suchen ist nicht aktiviert</string>
|
||||
</patch>
|
||||
<patch id="misc.fix.playback.SpoofClientPatch">
|
||||
<string name="revanced_spoof_client_screen_title">Spoof-Client</string>
|
||||
<string name="revanced_spoof_client_screen_summary">Spoof des Clients, um Wiedergabeprobleme zu verhindern</string>
|
||||
<string name="revanced_spoof_client_title">Spoof-Client</string>
|
||||
<string name="revanced_spoof_client_summary_on">Client ist getäuscht</string>
|
||||
<string name="revanced_spoof_client_summary_off">Client ist nicht gefälscht\n\nVideo-Wiedergabe funktioniert möglicherweise nicht</string>
|
||||
<string name="revanced_spoof_client_user_dialog_message">Das Deaktivieren dieser Einstellung kann zu Videowiedergabeproblemen führen.</string>
|
||||
<string name="revanced_spoof_client_use_ios_title">Spoof-Client zu iOS</string>
|
||||
<string name="revanced_spoof_client_use_ios_summary_on">Der Client ist derzeit zu iOS\n\nSeiteneffekten gefälscht:\n• HDR-Video ist möglicherweise nicht verfügbar\n• Verlauf kann nicht funktionieren</string>
|
||||
<string name="revanced_spoof_client_use_ios_summary_off">Der Client ist derzeit auf Android VR gespoofed. Nebeneffekte können sein:\n• Kein HDR Video\n• Kindervideos spielen nicht\n• Pausierte Videos könnten zufällig wieder aufgenommen werden\n• Niedrige Qualität der Shorts-Suchleisten-Thumbnails\n• Download-Button ist ausgeblendet\n• Endbildschirm-Karten werden versteckt</string>
|
||||
<string name="revanced_spoof_client_storyboard_timeout">Spoof-Thumbnails nicht verfügbar (API-Zeitüberschreitung)</string>
|
||||
<string name="revanced_spoof_client_storyboard_io_exception">Spoof-Client-Thumbnails vorübergehend nicht verfügbar: %s</string>
|
||||
</patch>
|
||||
<!-- This patch is no longer used, these strings are not in use, and these strings will be deleted in the future. -->
|
||||
<patch id="misc.fix.playback.SpoofSignaturePatch">
|
||||
<string name="revanced_spoof_signature_verification_screen_title">Spoof-App-Signatur</string>
|
||||
<string name="revanced_spoof_signature_verification_screen_summary">Spoof der App-Signatur, um Wiedergabeprobleme zu vermeiden</string>
|
||||
<string name="revanced_spoof_signature_verification_enabled_title">Spoof-App-Signatur</string>
|
||||
<string name="revanced_spoof_signature_verification_enabled_summary_on">App-Signatur gefälscht\n\nNebeneffekte beinhalten:\n• Erweiterte Bitrate ist nicht verfügbar\n• Videos können nicht\nheruntergeladen werden • Keine Suchleisten-Vorschaubilder für bezahlte Videos</string>
|
||||
<string name="revanced_spoof_signature_verification_enabled_summary_off">App-Signatur nicht gefälscht\n\nVideowiedergabe funktioniert möglicherweise nicht</string>
|
||||
<string name="revanced_spoof_signature_verification_enabled_user_dialog_message">Das Deaktivieren dieser Einstellung führt zu Videowiedergabeproblemen.</string>
|
||||
<string name="revanced_spoof_signature_in_feed_enabled_title">Spoof-App-Signatur im Feed</string>
|
||||
<string name="revanced_spoof_signature_in_feed_enabled_summary_on">App-Signatur gefälscht\n\nNebeneffekte beinhalten:\n• Feed-Videos fehlen Untertitel\n• Automatisch abgespielte Feed-Videos werden in Ihrem Überwachungsverlauf angezeigt</string>
|
||||
<string name="revanced_spoof_signature_in_feed_enabled_summary_off">App-Signatur für Feed-Videos nicht gefälscht\n\nFeed Videos werden weniger als 1 Minute vor Wiedergabeproblemen abgespielt</string>
|
||||
<string name="revanced_spoof_storyboard_title">Spoof-Storyboard</string>
|
||||
<string name="revanced_spoof_storyboard_summary_on">Storyboard gefälscht</string>
|
||||
<string name="revanced_spoof_storyboard_summary_off">Storyboard nicht gefälscht\n\nNebeneffekte beinhalten:\n• Kein Umgebungsmodus\n• Suchleisten-Thumbnails werden ausgeblendet</string>
|
||||
<string name="revanced_spoof_storyboard_timeout">Spoof-Storyboard vorübergehend nicht verfügbar (API Timeout)</string>
|
||||
<string name="revanced_spoof_storyboard_io_exception">Spoof Storyboard vorübergehend nicht verfügbar: %s</string>
|
||||
<patch id="misc.fix.playback.SpoofVideoStreamsPatch">
|
||||
<string name="revanced_spoof_video_streams_screen_title">Spoof-Video-Streams</string>
|
||||
<string name="revanced_spoof_video_streams_screen_summary">Spoof der Client-Videostreams um Wiedergabeprobleme zu verhindern</string>
|
||||
<string name="revanced_spoof_video_streams_title">Spoof-Video-Streams</string>
|
||||
<string name="revanced_spoof_video_streams_summary_on">Video-Streams sind gefälscht</string>
|
||||
<string name="revanced_spoof_video_streams_summary_off">Video-Streams sind nicht gefälscht\n\nVideo-Wiedergabe funktioniert möglicherweise nicht</string>
|
||||
<string name="revanced_spoof_video_streams_user_dialog_message">Das Deaktivieren dieser Einstellung kann zu Videowiedergabeproblemen führen.</string>
|
||||
<string name="revanced_spoof_video_streams_client_title">Standard-Client</string>
|
||||
<string name="revanced_spoof_video_streams_ios_force_avc_title">AVC erzwingen (H.264)</string>
|
||||
<string name="revanced_spoof_video_streams_ios_force_avc_summary_on">Video Codec ist AVC (H.264)</string>
|
||||
<string name="revanced_spoof_video_streams_ios_force_avc_summary_off">Video Codec ist VP9 oder AV1</string>
|
||||
<string name="revanced_spoof_video_streams_ios_force_avc_no_hardware_vp9_summary_on">Ihr Gerät hat keine VP9-Hardware-Dekodierung, und diese Einstellung ist immer aktiviert, wenn Client-Spoofing aktiviert ist</string>
|
||||
<string name="revanced_spoof_video_streams_ios_force_avc_user_dialog_message">Das Aktivieren kann die Akkulaufzeit verbessern und die Wiedergabe-Stutting beheben.\n\nAVC hat eine maximale Auflösung von 1080p, und die Videowiedergabe wird mehr Internet-Daten als VP9 oder AV1 verwenden.</string>
|
||||
<string name="revanced_spoof_video_streams_about_ios_title">iOS Spoofing Nebeneffekte</string>
|
||||
<string name="revanced_spoof_video_streams_about_android_vr_title">Android VR Spoofing Nebeneffekte</string>
|
||||
<string name="revanced_spoof_video_streams_about_android_vr_summary">• Audio Track Menü fehlt\n• Stabile Lautstärke ist nicht verfügbar</string>
|
||||
</patch>
|
||||
<!-- This patch is no longer used and these strings will soon be deleted. -->
|
||||
<patch id="video.hdrbrightness.HDRBrightnessPatch">
|
||||
|
||||
@@ -32,6 +32,17 @@ This is because Crowdin requires temporarily flattening this file and removing t
|
||||
-->
|
||||
<resources>
|
||||
<app id="shared">
|
||||
<patch id="misc.checks.BaseCheckEnvironmentPatch">
|
||||
<string name="revanced_check_environment_failed_title">Αποτυχία ελέγχων</string>
|
||||
<string name="revanced_check_environment_dialog_open_official_source_button">Άνοιγμα επίσημης ιστοσελίδας</string>
|
||||
<string name="revanced_check_environment_dialog_ignore_button">Παράλειψη</string>
|
||||
<string name="revanced_check_environment_failed_message"><h5>Αυτή η εφαρμογή δεν φαίνεται να έχει τροποποιηθεί από εσάς.</h5><br>Αυτή η εφαρμογή μπορεί να μην λειτουργεί σωστά, <b>θα μπορούσε να είναι επιβλαβής ή ακόμα και επικίνδυνη για χρήση</b>.<br><br>Αυτοί οι έλεγχοι υποδηλώνουν ότι αυτή η εφαρμογή έχει τροποποιηθεί στο παρελθόν ή λήφθηκε από κάποιον άλλο:<br><br><small>%1$s</small><br>Συνιστάται έντονα να απεγκαταστήσετε την εφαρμογή <br>και να την τροποποιήσετε μόνοι σας<br> για να διασφαλίσετε ότι χρησιμοποιείτε μια επικυρωμένη και ασφαλή εφαρμογή.<p><br>Εάν αγνοηθεί, αυτή η προειδοποίηση θα εμφανιστεί μόνο δύο φορές.</string>
|
||||
<string name="revanced_check_environment_not_same_patching_device">Τροποποιήθηκε σε διαφορετική συσκευή</string>
|
||||
<string name="revanced_check_environment_manager_not_expected_installer">Δεν έχει εγκατασταθεί μέσω του ReVanced Manager</string>
|
||||
<string name="revanced_check_environment_not_near_patch_time">Τροποποιήθηκε πάνω από 10 λεπτά πριν</string>
|
||||
<string name="revanced_check_environment_not_near_patch_time_days">Τροποποιήθηκε πριν %s μέρες</string>
|
||||
<string name="revanced_check_environment_not_near_patch_time_invalid">Ημερομηνία κατασκευής του APK είναι κατεστραμμένη</string>
|
||||
</patch>
|
||||
<patch id="misc.settings.BaseSettingsResourcePatch">
|
||||
<string name="revanced_settings_confirm_user_dialog_title">Θέλετε να συνεχίσετε;</string>
|
||||
<string name="revanced_settings_reset">Επαναφορά</string>
|
||||
@@ -42,6 +53,14 @@ This is because Crowdin requires temporarily flattening this file and removing t
|
||||
<string name="revanced_settings_import_reset">Επαναφέρθηκαν οι προεπιλεγμένες ρυθμίσεις ReVanced</string>
|
||||
<string name="revanced_settings_import_success">Έγινε εισαγωγή %d ρυθμίσεων</string>
|
||||
<string name="revanced_settings_import_failure_parse">Η εισαγωγή απέτυχε: %s</string>
|
||||
<string name="revanced_pref_import_export_title">Εισαγωγή / Εξαγωγή</string>
|
||||
<string name="revanced_pref_import_export_summary">Εισαγωγή / Εξαγωγή ρυθμίσεων ReVanced</string>
|
||||
<!-- Settings about dialog. -->
|
||||
<string name="revanced_settings_about_links_body">Χρησιμοποιείτε τις τροποποιήσεις ReVanced έκδοσης <i>%s</i></string>
|
||||
<string name="revanced_settings_about_links_dev_header">Σημείωση</string>
|
||||
<string name="revanced_settings_about_links_dev_body">Αυτή η έκδοση είναι σε πρώιμο στάδιο, επομένως πιθανότατα να αντιμετωπίσετε απρόοπτα προβλήματα</string>
|
||||
<string name="revanced_settings_about_links_header">Επίσημοι σύνδεσμοι</string>
|
||||
<string name="revanced_settings_about_links_donate">Δωρεά</string>
|
||||
</patch>
|
||||
<patch id="misc.gms.BaseGmsCoreSupportResourcePatch">
|
||||
<!-- Translations of this should not be longer than the original English text, otherwise the text can be clipped and not entirely shown. -->
|
||||
@@ -54,14 +73,6 @@ This is because Crowdin requires temporarily flattening this file and removing t
|
||||
</patch>
|
||||
</app>
|
||||
<app id="youtube">
|
||||
<patch id="misc.settings.SettingsResourcePatch">
|
||||
<string name="revanced_settings_about_links_body">Χρησιμοποιείτε τις τροποποιήσεις ReVanced έκδοσης <i>%s</i></string>
|
||||
<string name="revanced_settings_about_links_dev_header">Σημείωση</string>
|
||||
<string name="revanced_settings_about_links_dev_body">Αυτή η έκδοση είναι σε πρώιμο στάδιο, επομένως πιθανότατα να αντιμετωπίσετε απρόοπτα προβλήματα</string>
|
||||
<string name="revanced_settings_about_links_header">Επίσημοι σύνδεσμοι</string>
|
||||
<string name="revanced_pref_import_export_title">Εισαγωγή / Εξαγωγή</string>
|
||||
<string name="revanced_pref_import_export_summary">Εισαγωγή / Εξαγωγή ρυθμίσεων ReVanced</string>
|
||||
</patch>
|
||||
<patch id="misc.settings.SettingsPatch">
|
||||
<string name="revanced_settings_screen_00_about_title">Σχετικά με</string>
|
||||
<string name="revanced_settings_screen_01_ads_title">Διαφημίσεις</string>
|
||||
@@ -69,7 +80,6 @@ This is because Crowdin requires temporarily flattening this file and removing t
|
||||
<string name="revanced_settings_screen_03_feed_title">Ροή</string>
|
||||
<string name="revanced_settings_screen_04_player_title">Οθόνη αναπαραγωγής</string>
|
||||
<string name="revanced_settings_screen_05_general_title">Γενική διάταξη</string>
|
||||
<string name="revanced_settings_screen_06_shorts_title">Shorts</string>
|
||||
<string name="revanced_settings_screen_07_seekbar_title">Γραμμή προόδου βίντεο</string>
|
||||
<string name="revanced_settings_screen_08_swipe_controls_title">Έλεγχος με κατακόρυφη σάρωση οθόνης</string>
|
||||
<string name="revanced_settings_screen_11_misc_title">Διάφορα</string>
|
||||
@@ -243,14 +253,18 @@ This is because Crowdin requires temporarily flattening this file and removing t
|
||||
<string name="revanced_hide_keyword_content_phrases_title">Λέξεις-κλειδιά για απόκρυψη</string>
|
||||
<!-- For localization it is preferred, but not required, if 'LeBlanc' is replaced with a localized name or a familiar word that has upper case letters in the middle of the word.
|
||||
This is because keywords can be in any language, and showing an example in the localized script helps convey this. -->
|
||||
<string name="revanced_hide_keyword_content_phrases_summary">Λέξεις-κλειδιά και φράσεις προς απόκρυψη, διαχωρισμένες η μία κάτω από την άλλη\n\nΔώστε προσοχή στα πεζά και κεφάλαια γράμματα διότι ισχύει ευαισθησία πεζότητας (π.χ.: iPhone, TikTok, LeBlanc)</string>
|
||||
<string name="revanced_hide_keyword_content_phrases_summary">Λέξεις-κλειδιά και φράσεις προς απόκρυψη, διαχωρισμένες η μία κάτω από την άλλη\n\nΛέξεις-κλειδιά μπορεί να είναι ονόματα καναλιών ή οποιοδήποτε κείμενο εμφανίζεται σε τίτλους βίντεο\n\nΔώστε προσοχή στα πεζά και κεφάλαια γράμματα διότι ισχύει ευαισθησία πεζότητας (π.χ.: iPhone, TikTok, LeBlanc)</string>
|
||||
<string name="revanced_hide_keyword_content_about_title">Σχετικά με το φιλτράρισμα λέξεων-κλειδιών</string>
|
||||
<string name="revanced_hide_keyword_content_about_summary">Οι καρτέλες «Αρχική», «Εγγραφές» και τα αποτελέσματα αναζήτησης φιλτράρονται για απόκρυψη περιεχομένου που ταιριάζει με τις λέξεις-κλειδιά\n\nΠεριορισμοί\n• Κάποια Shorts ενδέχεται να μην κρύβονται\n• Κάποια στοιχεία UI ενδέχεται να μην κρύβονται\n• Η αναζήτηση για μια λέξη-κλειδί ενδέχεται να μην εμφανίζει κανένα αποτέλεσμα</string>
|
||||
<string name="revanced_hide_keyword_content_about_summary">Οι καρτέλες «Αρχική», «Εγγραφές» και τα αποτελέσματα αναζήτησης φιλτράρονται για απόκρυψη περιεχομένου που ταιριάζει με τις λέξεις-κλειδιά\n\nΠεριορισμοί\n• Τα Shorts δε γίνεται να κρυφτούν με βάση το όνομα καναλιού\n• Κάποια στοιχεία UI ενδέχεται να μην κρύβονται\n• Η αναζήτηση για μια λέξη-κλειδί ενδέχεται να μην εμφανίζει κανένα αποτέλεσμα</string>
|
||||
<string name="revanced_hide_keyword_content_about_whole_words_title">Ταίριασμα ολόκληρων λέξεων</string>
|
||||
<!-- Translations _must_ use a localized example. For languages that do not use spaces between words (Chinese, Japanese, etc) the English AI example should be used since no localized examples exist. Or if using machine translations, or if nobody wants to think of a localized example, then the English 'ai' example should be left as-is. -->
|
||||
<string name="revanced_hide_keyword_content_about_whole_words_summary">Περιβάλλοντας μια λέξη-κλειδί / φράση με διπλά εισαγωγικά θα αποτρέψει μερικές αντιστοιχίες των τίτλων βίντεο και των ονομάτων καναλιών<br><br>Για παράδειγμα,<br><b>\"ai\"</b> θα κρύψει το βίντεο: <b>How does AI work?</b><br>αλλά δεν θα κρύψει: <b>What does fair use mean?</b></string>
|
||||
<!-- Translations of this should not be longer than the original English text, otherwise the text can be clipped and not entirely shown. -->
|
||||
<string name="revanced_hide_keyword_toast_invalid_common">Μη έγκυρη λέξη-κλειδί. Αδυναμία χρήσης: \'%s\' ως φίλτρο</string>
|
||||
<!-- Translations of this should not be longer than the original English text, otherwise the text can be clipped and not entirely shown. -->
|
||||
<string name="revanced_hide_keyword_toast_invalid_length">Μη έγκυρη λέξη-κλειδί. Το \'%1$s\' είναι μικρότερο από %2$d χαρακτήρες</string>
|
||||
<string name="revanced_hide_keyword_toast_invalid_broad">Η λέξη «%s» θα κρύψει όλα τα βίντεο</string>
|
||||
<string name="revanced_hide_keyword_toast_invalid_common">Αδυναμία χρήσης λέξης-κλειδί: %s</string>
|
||||
<string name="revanced_hide_keyword_toast_invalid_common_whole_word_required">Προσθήκη εισαγωγικών για χρήση λέξης-κλειδί: %s</string>
|
||||
<string name="revanced_hide_keyword_toast_invalid_conflicting">Λέξη-κλειδί έχει αντικρουόμενες δηλώσεις: %s</string>
|
||||
<string name="revanced_hide_keyword_toast_invalid_length">Η λέξη-κλειδί είναι πολύ σύντομη και απαιτεί εισαγωγικά: %s</string>
|
||||
<string name="revanced_hide_keyword_toast_invalid_broad">Θα κρυφτούν όλα τα βίντεο με την λέξη-κλειδί: %s</string>
|
||||
</patch>
|
||||
<patch id="ad.general.HideAdsResourcePatch">
|
||||
<string name="revanced_hide_general_ads_title">Γενικές διαφημίσεις</string>
|
||||
@@ -616,6 +630,9 @@ This is because Crowdin requires temporarily flattening this file and removing t
|
||||
<string name="revanced_hide_shorts_save_sound_button_title">Κουμπί αποθήκευσης ήχου σε λίστα αναπαραγωγής</string>
|
||||
<string name="revanced_hide_shorts_save_sound_button_summary_on">Κρυμμένο</string>
|
||||
<string name="revanced_hide_shorts_save_sound_button_summary_off">Εμφανίζεται</string>
|
||||
<string name="revanced_hide_shorts_use_this_sound_button_title">Κουμπί «Χρήση αυτού του ήχου»</string>
|
||||
<string name="revanced_hide_shorts_use_this_sound_button_summary_on">Κρυμμένο</string>
|
||||
<string name="revanced_hide_shorts_use_this_sound_button_summary_off">Εμφανίζεται</string>
|
||||
<string name="revanced_hide_shorts_search_suggestions_title">Προτάσεις αναζήτησης</string>
|
||||
<string name="revanced_hide_shorts_search_suggestions_summary_on">Κρυμμένες</string>
|
||||
<string name="revanced_hide_shorts_search_suggestions_summary_off">Εμφανίζονται</string>
|
||||
@@ -679,7 +696,6 @@ This is because Crowdin requires temporarily flattening this file and removing t
|
||||
<string name="revanced_player_overlay_opacity_invalid_toast">Η αδιαφάνεια φόντου οθόνης αναπαραγωγής πρέπει να είναι μεταξύ 0-100</string>
|
||||
</patch>
|
||||
<patch id="layout.returnyoutubedislike.ReturnYouTubeDislikeResourcePatch">
|
||||
<string name="revanced_ryd_video_likes_hidden_by_video_owner">Κρυμμένα</string>
|
||||
<!-- Toast shown if network connection times out. Translations of this should not be longer than the original English or the text can be clipped and not entirely shown. -->
|
||||
<string name="revanced_ryd_failure_connection_timeout">Dislike προσωρινά μη διαθέσιμα (καθυστέρηση API)</string>
|
||||
<string name="revanced_ryd_failure_connection_status_code">Δεδομένα dislike μη διαθέσιμα (κατάσταση %d)</string>
|
||||
@@ -775,6 +791,7 @@ This is because Crowdin requires temporarily flattening this file and removing t
|
||||
<string name="revanced_sb_general_skipcount_sum_off">Ο μετρητής παραλείψεων δεν είναι ενεργός</string>
|
||||
<string name="revanced_sb_general_min_duration">Ελάχιστη διάρκεια τμήματος</string>
|
||||
<string name="revanced_sb_general_min_duration_sum">Τμήματα μικρότερα από την καθορισμένη τιμή (σε δευτερόλεπτα) δεν θα εμφανίζονται ούτε θα παραλείπονται</string>
|
||||
<string name="revanced_sb_general_min_duration_invalid">Μη έγκυρη διάρκεια χρόνου</string>
|
||||
<string name="revanced_sb_general_uuid">Το ιδιωτικό σας αναγνωριστικό χρήστη</string>
|
||||
<string name="revanced_sb_general_uuid_sum">Αυτό πρέπει να μείνει μυστικό. Είναι σαν έναν κωδικό που δεν πρέπει να μοιραστείτε με κανέναν. Εάν κάποιος αποκτήσει αυτόν τον κωδικό, μπορεί να σας υποδυθεί</string>
|
||||
<string name="revanced_sb_general_uuid_invalid">Το ιδιωτικό αναγνωριστικό χρήστη πρέπει να είναι τουλάχιστον 30 χαρακτήρες</string>
|
||||
@@ -875,8 +892,6 @@ This is because Crowdin requires temporarily flattening this file and removing t
|
||||
<string name="revanced_sb_new_segment_time_start">Χρόνος έναρξης του τμήματος</string>
|
||||
<string name="revanced_sb_new_segment_time_end">Χρόνος λήξης του τμήματος</string>
|
||||
<string name="revanced_sb_new_segment_confirm_title">Είναι σωστοί οι χρόνοι;</string>
|
||||
<!-- Do not rearrange the (hour):(minute):second) time format operators here.
|
||||
YT shows the same seekbar time format for all languages, and this string is confirming the segment time as it appears in the seekbar. -->
|
||||
<string name="revanced_sb_new_segment_confirm_content">Το τμήμα είναι από\n\n%1$s\nσε\n%2$s\n\n(%3$s)\n\nΈτοιμο για υποβολή;</string>
|
||||
<string name="revanced_sb_new_segment_start_is_before_end">Η αρχή πρέπει να είναι πριν από το τέλος</string>
|
||||
<string name="revanced_sb_new_segment_mark_locations_first">Σημειώστε δύο σημεία στην γραμμή προόδου πρώτα</string>
|
||||
@@ -895,6 +910,7 @@ This is because Crowdin requires temporarily flattening this file and removing t
|
||||
<string name="revanced_sb_stats_username_changed">Το όνομα χρήστη άλλαξε επιτυχώς</string>
|
||||
<string name="revanced_sb_stats_reputation">Η φήμη σας είναι <b>%.2f</b></string>
|
||||
<string name="revanced_sb_stats_submissions">Δημιουργήσατε <b>%s</b> τμήματα</string>
|
||||
<string name="revanced_sb_stats_submissions_sum">Πατήστε για να δείτε τα τμήματα σας</string>
|
||||
<string name="revanced_sb_stats_saved_zero">Πίνακας κατάταξης SponsorBlock</string>
|
||||
<string name="revanced_sb_stats_saved">Έχετε σώσει τους συνανθρώπους σας από <b>%s</b> τμήματα</string>
|
||||
<string name="revanced_sb_stats_saved_sum_zero">Πατήστε για να δείτε τα παγκόσμια στατιστικά και τους κορυφαίους συνεισφέροντες</string>
|
||||
@@ -1038,6 +1054,11 @@ This is because Crowdin requires temporarily flattening this file and removing t
|
||||
<string name="revanced_announcements_connection_failed">Αποτυχία σύνδεσης με τον πάροχο ανακοινώσεων</string>
|
||||
<string name="revanced_announcements_dialog_dismiss">Παράλειψη</string>
|
||||
</patch>
|
||||
<patch id="misc.dns.CheckWatchHistoryDomainNameResolutionPatch">
|
||||
<string name="revanced_check_watch_history_domain_name_dialog_title">Προειδοποίηση</string>
|
||||
<string name="revanced_check_watch_history_domain_name_dialog_message">Το ιστορικό παρακολούθησης δεν αποθηκεύεται.<br><br>Πιθανό να συμβαίνει λόγω αποκλεισμού διαφημίσεων μέσω DNS ή μέσω διακομιστή μεσολάβησης δικτύου.<br><br>Μια λύση γι\'αυτό θα ήταν να προσθέσετε σε whitelist το <b>s.youtube.com</b> ή να απενεργοποιήστε τους DNS/proxy blockers.</string>
|
||||
<string name="revanced_check_watch_history_domain_name_dialog_ignore">Να μην εμφανιστεί ξανά</string>
|
||||
</patch>
|
||||
<patch id="misc.autorepeat.AutoRepeatPatch">
|
||||
<string name="revanced_auto_repeat_title">Ενεργοποίηση αυτόματης επανάληψης</string>
|
||||
<string name="revanced_auto_repeat_summary_on">Η αυτόματη επανάληψη είναι ενεργοποιημένη</string>
|
||||
@@ -1112,22 +1133,23 @@ This is because Crowdin requires temporarily flattening this file and removing t
|
||||
<string name="revanced_slide_to_seek_summary_on">Η αναζήτηση στη γραμμή προόδου με χειρονομία οριζόντιας σάρωσης είναι ενεργοποιημένη</string>
|
||||
<string name="revanced_slide_to_seek_summary_off">Η αναζήτηση στη γραμμή προόδου με χειρονομία σάρωσης είναι απενεργοποιημένη</string>
|
||||
</patch>
|
||||
<patch id="misc.fix.playback.SpoofClientPatch">
|
||||
<string name="revanced_spoof_client_screen_title">Παραποίηση προγράμματος πελάτη</string>
|
||||
<string name="revanced_spoof_client_screen_summary">Παραποίηση του προγράμματος πελάτη για την αποφυγή προβλημάτων αναπαραγωγής</string>
|
||||
<string name="revanced_spoof_client_title">Παραποίηση προγράμματος πελάτη</string>
|
||||
<string name="revanced_spoof_client_summary_on">Το πρόγραμμα πελάτη παραποιείται</string>
|
||||
<string name="revanced_spoof_client_summary_off">Το πρόγραμμα πελάτη δεν παραποιείται\n\nΗ αναπαραγωγή βίντεο ενδέχεται να μη λειτουργεί</string>
|
||||
<string name="revanced_spoof_client_user_dialog_message">Η απενεργοποίηση αυτής της ρύθμισης ενδέχεται να προκαλέσει προβλήματα αναπαραγωγής βίντεο.</string>
|
||||
<string name="revanced_spoof_client_use_ios_title">Παραποίηση σε iOS</string>
|
||||
<string name="revanced_spoof_client_use_ios_summary_on">Ο πελάτης αυτή τη στιγμή παραποιείται ως iOS\n\nΟι παρενέργειες περιλαμβάνουν:\n• Δεν υπάρχει η ποιότητα HDR στα βίντεο\n• Το ιστορικό παρακολούθησης μπορεί να μη λειτουργεί</string>
|
||||
<string name="revanced_spoof_client_use_ios_summary_off">Ο πελάτης αυτή τη στιγμή παραποιείται ως Android VR. Οι παρενέργειες περιλαμβάνουν:\n• Δεν υπάρχει η ποιότητα HDR στα βίντεο\n• Δεν λειτουργεί η αναπαραγωγή στα βίντεο για παιδιά\n• Βίντεο που έχετε θέσει σε παύση μπορεί να συνεχίσουν να παίζουν τυχαία\n• Χαμηλή ποιότητα μικρογραφιών μπάρας αναζήτησης στα shorts\n• Το κουμπί λήψης είναι πάντα κρυμμένο\n• Οι κάρτες τελικής οθόνης είναι πάντα κρυμμένες</string>
|
||||
<string name="revanced_spoof_client_storyboard_timeout">Μικρογραφίες προεπισκόπησης μη διαθέσιμες (καθυστέρηση API)</string>
|
||||
<string name="revanced_spoof_client_storyboard_io_exception">Μικρογραφίες προεπισκόπησης προσωρινά μη διαθέσιμες: %s</string>
|
||||
</patch>
|
||||
<!-- This patch is no longer used, these strings are not in use, and these strings will be deleted in the future. -->
|
||||
<patch id="misc.fix.playback.SpoofSignaturePatch">
|
||||
<string name="revanced_spoof_signature_in_feed_enabled_summary_off">Η εγκυρότητα της εφαρμογής δεν παραποιείται για βίντεο στη ροή\n\nΤα βίντεο στη ροή θα αναπαράγονται για λιγότερο από 1 λεπτό πριν αντιμετωπίσουν προβλήματα αναπαραγωγής</string>
|
||||
<patch id="misc.fix.playback.SpoofVideoStreamsPatch">
|
||||
<string name="revanced_spoof_video_streams_screen_title">Παραποίηση ροών βίντεο</string>
|
||||
<string name="revanced_spoof_video_streams_screen_summary">Παραποίηση ροών βίντεο του προγράμματος πελάτη για την αποφυγή προβλημάτων αναπαραγωγής</string>
|
||||
<string name="revanced_spoof_video_streams_title">Παραποίηση ροών βίντεο</string>
|
||||
<string name="revanced_spoof_video_streams_summary_on">Οι ροές βίντεο παραποιούνται</string>
|
||||
<string name="revanced_spoof_video_streams_summary_off">Οι ροές βίντεο δεν παραποιούνται\n\nΗ αναπαραγωγή βίντεο ενδέχεται να μην λειτουργεί</string>
|
||||
<string name="revanced_spoof_video_streams_user_dialog_message">Η απενεργοποίηση αυτής της ρύθμισης ενδέχεται να προκαλέσει προβλήματα αναπαραγωγής βίντεο.</string>
|
||||
<string name="revanced_spoof_video_streams_client_title">Προεπιλεγμένο πρόγραμμα πελάτη</string>
|
||||
<string name="revanced_spoof_video_streams_ios_force_avc_title">Εξαναγκασμός AVC (H.264)</string>
|
||||
<string name="revanced_spoof_video_streams_ios_force_avc_summary_on">Ο κωδικοποιητής βίντεο είναι ο AVC (H.264)</string>
|
||||
<string name="revanced_spoof_video_streams_ios_force_avc_summary_off">Ο κωδικοποιητής βίντεο είναι ο VP9 ή ο AV1</string>
|
||||
<string name="revanced_spoof_video_streams_ios_force_avc_no_hardware_vp9_summary_on">Η συσκευή σας δεν διαθέτει αποκωδικοποίηση υλικού VP9, και αυτή η ρύθμιση είναι πάντα ενεργή όταν είναι ενεργοποιημένη η παραποίηση προγράμματος πελάτη</string>
|
||||
<string name="revanced_spoof_video_streams_ios_force_avc_user_dialog_message">Ενεργοποιώντας αυτόν τον κωδικοποιητή ίσως να βελτιώσει κατανάλωση ενέργειας και ίσως διορθώσει κολλήματα αναπαραγωγής.\n\nΟ AVC έχει μέγιστη ανάλυση 1080p, και καταναλώνει περισσότερα δεδομένα internet από τον VP9 ή τον AV1.</string>
|
||||
<string name="revanced_spoof_video_streams_about_ios_title">Παρενέργειες παραποίησης σε iOS</string>
|
||||
<string name="revanced_spoof_video_streams_about_ios_summary">• Οι ταινίες ή τα επί πληρωμή βίντεο ενδέχεται να μην αναπαράγονται\n• Οι ζωντανές μεταδόσεις ξεκινούν από την αρχή κατά την αναπαραγωγή\n• Τα βίντεο μπορεί να τελειώνουν 1 δευτερόλεπτο νωρίτερα\n• Ο κωδικοποιητής ήχου opus δεν είναι διαθέσιμος</string>
|
||||
<string name="revanced_spoof_video_streams_about_android_vr_title">Παρενέργειες παραποίησης σε Android VR</string>
|
||||
<string name="revanced_spoof_video_streams_about_android_vr_summary">• Το μενού «Κομμάτι ήχου» λείπει\n• Η λειτουργία «Σταθερή ένταση» δεν είναι διαθέσιμη</string>
|
||||
</patch>
|
||||
<!-- This patch is no longer used and these strings will soon be deleted. -->
|
||||
<patch id="video.hdrbrightness.HDRBrightnessPatch">
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user