mirror of
https://github.com/younesaassila/ttv-lol-pro.git
synced 2025-05-09 02:44:29 +02:00
Compare commits
21 Commits
v2.4.0-bet
...
v2
Author | SHA1 | Date | |
---|---|---|---|
![]() |
fa1c74e23e | ||
![]() |
9d86b37d00 | ||
![]() |
e7f00f4e56 | ||
![]() |
4693ceb9a5 | ||
![]() |
21fc889cbd | ||
![]() |
2cba7c1509 | ||
![]() |
6df1cc7638 | ||
![]() |
de97812b24 | ||
![]() |
b0b0cb09a9 | ||
![]() |
f9fcce5cac | ||
![]() |
6fcae2eea1 | ||
![]() |
9f45b77b83 | ||
![]() |
010265c8f0 | ||
![]() |
ac50e0c8b2 | ||
![]() |
be39a5344f | ||
![]() |
2a79647fae | ||
![]() |
7ab206e3d8 | ||
![]() |
66d3ef30b1 | ||
![]() |
f2aee154ba | ||
![]() |
a7e7aa0e93 | ||
![]() |
62e34f55b0 |
2
.github/workflows/build.yml
vendored
2
.github/workflows/build.yml
vendored
@ -6,11 +6,13 @@ on:
|
|||||||
tags-ignore: ["**"]
|
tags-ignore: ["**"]
|
||||||
pull_request:
|
pull_request:
|
||||||
branches: ["**"]
|
branches: ["**"]
|
||||||
|
types: [opened, synchronize, reopened, ready_for_review]
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
build:
|
build:
|
||||||
name: Build
|
name: Build
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
|
if: ${{ !github.event.pull_request.draft }}
|
||||||
concurrency: build-${{ github.ref }}
|
concurrency: build-${{ github.ref }}
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
|
2
.github/workflows/codeql.yml
vendored
2
.github/workflows/codeql.yml
vendored
@ -18,6 +18,7 @@ on:
|
|||||||
pull_request:
|
pull_request:
|
||||||
# The branches below must be a subset of the branches above
|
# The branches below must be a subset of the branches above
|
||||||
branches: ["v2"]
|
branches: ["v2"]
|
||||||
|
types: [opened, synchronize, reopened, ready_for_review]
|
||||||
schedule:
|
schedule:
|
||||||
- cron: "32 9 * * 6"
|
- cron: "32 9 * * 6"
|
||||||
|
|
||||||
@ -25,6 +26,7 @@ jobs:
|
|||||||
analyze:
|
analyze:
|
||||||
name: Analyze
|
name: Analyze
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
|
if: ${{ !github.event.pull_request.draft }}
|
||||||
concurrency: codeql-${{ github.ref }}
|
concurrency: codeql-${{ github.ref }}
|
||||||
permissions:
|
permissions:
|
||||||
actions: read
|
actions: read
|
||||||
|
8
.github/workflows/dependency-review.yml
vendored
8
.github/workflows/dependency-review.yml
vendored
@ -5,14 +5,20 @@
|
|||||||
# Source repository: https://github.com/actions/dependency-review-action
|
# Source repository: https://github.com/actions/dependency-review-action
|
||||||
# Public documentation: https://docs.github.com/en/code-security/supply-chain-security/understanding-your-software-supply-chain/about-dependency-review#dependency-review-enforcement
|
# Public documentation: https://docs.github.com/en/code-security/supply-chain-security/understanding-your-software-supply-chain/about-dependency-review#dependency-review-enforcement
|
||||||
name: "Dependency Review"
|
name: "Dependency Review"
|
||||||
on: [pull_request]
|
on:
|
||||||
|
pull_request:
|
||||||
|
branches: ["**"]
|
||||||
|
types: [opened, synchronize, reopened, ready_for_review]
|
||||||
|
|
||||||
permissions:
|
permissions:
|
||||||
contents: read
|
contents: read
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
dependency-review:
|
dependency-review:
|
||||||
|
name: Dependency Review
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
|
if: ${{ !github.event.pull_request.draft }}
|
||||||
|
concurrency: dependencies-${{ github.ref }}
|
||||||
steps:
|
steps:
|
||||||
- name: "Checkout Repository"
|
- name: "Checkout Repository"
|
||||||
uses: actions/checkout@v4
|
uses: actions/checkout@v4
|
||||||
|
132
package-lock.json
generated
132
package-lock.json
generated
@ -15,8 +15,8 @@
|
|||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@parcel/config-webextension": "^2.13.3",
|
"@parcel/config-webextension": "^2.13.3",
|
||||||
"@types/chrome": "^0.0.300",
|
"@types/chrome": "^0.0.304",
|
||||||
"@types/node": "^22.13.0",
|
"@types/node": "^22.13.2",
|
||||||
"@types/webextension-polyfill": "^0.12.1",
|
"@types/webextension-polyfill": "^0.12.1",
|
||||||
"buffer": "^6.0.3",
|
"buffer": "^6.0.3",
|
||||||
"parcel": "^2.13.3",
|
"parcel": "^2.13.3",
|
||||||
@ -1833,9 +1833,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@swc/core": {
|
"node_modules/@swc/core": {
|
||||||
"version": "1.10.12",
|
"version": "1.10.16",
|
||||||
"resolved": "https://registry.npmjs.org/@swc/core/-/core-1.10.12.tgz",
|
"resolved": "https://registry.npmjs.org/@swc/core/-/core-1.10.16.tgz",
|
||||||
"integrity": "sha512-+iUL0PYpPm6N9AdV1wvafakvCqFegQus1aoEDxgFsv3/uNVNIyRaupf/v/Zkp5hbep2EzhtoJR0aiJIzDbXWHg==",
|
"integrity": "sha512-nOINg/OUcZazCW7B55QV2/UB8QAqz9FYe4+z229+4RYboBTZ102K7ebOEjY5sKn59JgAkhjZTz+5BKmXpDFopw==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"hasInstallScript": true,
|
"hasInstallScript": true,
|
||||||
"license": "Apache-2.0",
|
"license": "Apache-2.0",
|
||||||
@ -1851,16 +1851,16 @@
|
|||||||
"url": "https://opencollective.com/swc"
|
"url": "https://opencollective.com/swc"
|
||||||
},
|
},
|
||||||
"optionalDependencies": {
|
"optionalDependencies": {
|
||||||
"@swc/core-darwin-arm64": "1.10.12",
|
"@swc/core-darwin-arm64": "1.10.16",
|
||||||
"@swc/core-darwin-x64": "1.10.12",
|
"@swc/core-darwin-x64": "1.10.16",
|
||||||
"@swc/core-linux-arm-gnueabihf": "1.10.12",
|
"@swc/core-linux-arm-gnueabihf": "1.10.16",
|
||||||
"@swc/core-linux-arm64-gnu": "1.10.12",
|
"@swc/core-linux-arm64-gnu": "1.10.16",
|
||||||
"@swc/core-linux-arm64-musl": "1.10.12",
|
"@swc/core-linux-arm64-musl": "1.10.16",
|
||||||
"@swc/core-linux-x64-gnu": "1.10.12",
|
"@swc/core-linux-x64-gnu": "1.10.16",
|
||||||
"@swc/core-linux-x64-musl": "1.10.12",
|
"@swc/core-linux-x64-musl": "1.10.16",
|
||||||
"@swc/core-win32-arm64-msvc": "1.10.12",
|
"@swc/core-win32-arm64-msvc": "1.10.16",
|
||||||
"@swc/core-win32-ia32-msvc": "1.10.12",
|
"@swc/core-win32-ia32-msvc": "1.10.16",
|
||||||
"@swc/core-win32-x64-msvc": "1.10.12"
|
"@swc/core-win32-x64-msvc": "1.10.16"
|
||||||
},
|
},
|
||||||
"peerDependencies": {
|
"peerDependencies": {
|
||||||
"@swc/helpers": "*"
|
"@swc/helpers": "*"
|
||||||
@ -1872,9 +1872,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@swc/core-darwin-arm64": {
|
"node_modules/@swc/core-darwin-arm64": {
|
||||||
"version": "1.10.12",
|
"version": "1.10.16",
|
||||||
"resolved": "https://registry.npmjs.org/@swc/core-darwin-arm64/-/core-darwin-arm64-1.10.12.tgz",
|
"resolved": "https://registry.npmjs.org/@swc/core-darwin-arm64/-/core-darwin-arm64-1.10.16.tgz",
|
||||||
"integrity": "sha512-pOANQegUTAriW7jq3SSMZGM5l89yLVMs48R0F2UG6UZsH04SiViCnDctOGlA/Sa++25C+rL9MGMYM1jDLylBbg==",
|
"integrity": "sha512-iikIxwqCQ4Bvz79vJ4ELh26efPf1u5D9TFdmXSJUBs7C3mmMHvk5zyWD9A9cTowXiW6WHs2gE58U1R9HOTTIcg==",
|
||||||
"cpu": [
|
"cpu": [
|
||||||
"arm64"
|
"arm64"
|
||||||
],
|
],
|
||||||
@ -1889,9 +1889,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@swc/core-darwin-x64": {
|
"node_modules/@swc/core-darwin-x64": {
|
||||||
"version": "1.10.12",
|
"version": "1.10.16",
|
||||||
"resolved": "https://registry.npmjs.org/@swc/core-darwin-x64/-/core-darwin-x64-1.10.12.tgz",
|
"resolved": "https://registry.npmjs.org/@swc/core-darwin-x64/-/core-darwin-x64-1.10.16.tgz",
|
||||||
"integrity": "sha512-m4kbpIDDsN1FrwfNQMU+FTrss356xsXvatLbearwR+V0lqOkjLBP0VmRvQfHEg+uy13VPyrT9gj4HLoztlci7w==",
|
"integrity": "sha512-R2Eb9aktWd62vPfW9H/c/OaQ0e94iURibBo4uzUUcgxNNmB4+wb6piKbHxGdr/5bEsT+vJ1lwZFSRzfb45E7DA==",
|
||||||
"cpu": [
|
"cpu": [
|
||||||
"x64"
|
"x64"
|
||||||
],
|
],
|
||||||
@ -1906,9 +1906,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@swc/core-linux-arm-gnueabihf": {
|
"node_modules/@swc/core-linux-arm-gnueabihf": {
|
||||||
"version": "1.10.12",
|
"version": "1.10.16",
|
||||||
"resolved": "https://registry.npmjs.org/@swc/core-linux-arm-gnueabihf/-/core-linux-arm-gnueabihf-1.10.12.tgz",
|
"resolved": "https://registry.npmjs.org/@swc/core-linux-arm-gnueabihf/-/core-linux-arm-gnueabihf-1.10.16.tgz",
|
||||||
"integrity": "sha512-OY9LcupgqEu8zVK+rJPes6LDJJwPDmwaShU96beTaxX2K6VrXbpwm5WbPS/8FfQTsmpnuA7dCcMPUKhNgmzTrQ==",
|
"integrity": "sha512-mkqN3HBAMnuiSGZ/k2utScuH8rAPshvNj0T1LjBWon+X9DkMNHSA+aMLdWsy0yZKF1zjOPc4L3Uq2l2wzhUlzA==",
|
||||||
"cpu": [
|
"cpu": [
|
||||||
"arm"
|
"arm"
|
||||||
],
|
],
|
||||||
@ -1923,9 +1923,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@swc/core-linux-arm64-gnu": {
|
"node_modules/@swc/core-linux-arm64-gnu": {
|
||||||
"version": "1.10.12",
|
"version": "1.10.16",
|
||||||
"resolved": "https://registry.npmjs.org/@swc/core-linux-arm64-gnu/-/core-linux-arm64-gnu-1.10.12.tgz",
|
"resolved": "https://registry.npmjs.org/@swc/core-linux-arm64-gnu/-/core-linux-arm64-gnu-1.10.16.tgz",
|
||||||
"integrity": "sha512-nJD587rO0N4y4VZszz3xzVr7JIiCzSMhEMWnPjuh+xmPxDBz0Qccpr8xCr1cSxpl1uY7ERkqAGlKr6CwoV5kVg==",
|
"integrity": "sha512-PH/+q/L5nVZJ91CU07CL6Q9Whs6iR6nneMZMAgtVF9Ix8ST0cWVItdUhs6D38kFklCFhaOrpHhS01HlMJ72vWw==",
|
||||||
"cpu": [
|
"cpu": [
|
||||||
"arm64"
|
"arm64"
|
||||||
],
|
],
|
||||||
@ -1940,9 +1940,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@swc/core-linux-arm64-musl": {
|
"node_modules/@swc/core-linux-arm64-musl": {
|
||||||
"version": "1.10.12",
|
"version": "1.10.16",
|
||||||
"resolved": "https://registry.npmjs.org/@swc/core-linux-arm64-musl/-/core-linux-arm64-musl-1.10.12.tgz",
|
"resolved": "https://registry.npmjs.org/@swc/core-linux-arm64-musl/-/core-linux-arm64-musl-1.10.16.tgz",
|
||||||
"integrity": "sha512-oqhSmV+XauSf0C//MoQnVErNUB/5OzmSiUzuazyLsD5pwqKNN+leC3JtRQ/QVzaCpr65jv9bKexT9+I2Tt3xDw==",
|
"integrity": "sha512-1169+C9XbydKKc6Ec1XZxTGKtHjZHDIFn0r+Nqp/QSVwkORrOY1Vz2Hdu7tn/lWMg36ZkGePS+LnnyV67s/7yg==",
|
||||||
"cpu": [
|
"cpu": [
|
||||||
"arm64"
|
"arm64"
|
||||||
],
|
],
|
||||||
@ -1957,9 +1957,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@swc/core-linux-x64-gnu": {
|
"node_modules/@swc/core-linux-x64-gnu": {
|
||||||
"version": "1.10.12",
|
"version": "1.10.16",
|
||||||
"resolved": "https://registry.npmjs.org/@swc/core-linux-x64-gnu/-/core-linux-x64-gnu-1.10.12.tgz",
|
"resolved": "https://registry.npmjs.org/@swc/core-linux-x64-gnu/-/core-linux-x64-gnu-1.10.16.tgz",
|
||||||
"integrity": "sha512-XldSIHyjD7m1Gh+/8rxV3Ok711ENLI420CU2EGEqSe3VSGZ7pHJvJn9ZFbYpWhsLxPqBYMFjp3Qw+J6OXCPXCA==",
|
"integrity": "sha512-n2rV0XwkjoHn4MDJmpYp5RBrnyi94/6GsJVpbn6f+/eqSrZn3mh3dT7pdZc9zCN1Qp9eDHo+uI6e/wgvbL22uA==",
|
||||||
"cpu": [
|
"cpu": [
|
||||||
"x64"
|
"x64"
|
||||||
],
|
],
|
||||||
@ -1974,9 +1974,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@swc/core-linux-x64-musl": {
|
"node_modules/@swc/core-linux-x64-musl": {
|
||||||
"version": "1.10.12",
|
"version": "1.10.16",
|
||||||
"resolved": "https://registry.npmjs.org/@swc/core-linux-x64-musl/-/core-linux-x64-musl-1.10.12.tgz",
|
"resolved": "https://registry.npmjs.org/@swc/core-linux-x64-musl/-/core-linux-x64-musl-1.10.16.tgz",
|
||||||
"integrity": "sha512-wvPXzJxzPgTqhyp1UskOx1hRTtdWxlyFD1cGWOxgLsMik0V9xKRgqKnMPv16Nk7L9xl6quQ6DuUHj9ID7L3oVw==",
|
"integrity": "sha512-EevCpwreBrkPrJjQVIbiM81lK42ukNNSlBmrSRxxbx2V9VGmOd5qxX0cJBn0TRRSLIPi62BuMS76F9iYjqsjgg==",
|
||||||
"cpu": [
|
"cpu": [
|
||||||
"x64"
|
"x64"
|
||||||
],
|
],
|
||||||
@ -1991,9 +1991,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@swc/core-win32-arm64-msvc": {
|
"node_modules/@swc/core-win32-arm64-msvc": {
|
||||||
"version": "1.10.12",
|
"version": "1.10.16",
|
||||||
"resolved": "https://registry.npmjs.org/@swc/core-win32-arm64-msvc/-/core-win32-arm64-msvc-1.10.12.tgz",
|
"resolved": "https://registry.npmjs.org/@swc/core-win32-arm64-msvc/-/core-win32-arm64-msvc-1.10.16.tgz",
|
||||||
"integrity": "sha512-TUYzWuu1O7uyIcRfxdm6Wh1u+gNnrW5M1DUgDOGZLsyQzgc2Zjwfh2llLhuAIilvCVg5QiGbJlpibRYJ/8QGsg==",
|
"integrity": "sha512-BvE7RWAnKJeELVQWLok6env5I4GUVBTZSvaSN/VPgxnTjF+4PsTeQptYx0xCYhp5QCv68wWYsBnZKuPDS+SBsw==",
|
||||||
"cpu": [
|
"cpu": [
|
||||||
"arm64"
|
"arm64"
|
||||||
],
|
],
|
||||||
@ -2008,9 +2008,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@swc/core-win32-ia32-msvc": {
|
"node_modules/@swc/core-win32-ia32-msvc": {
|
||||||
"version": "1.10.12",
|
"version": "1.10.16",
|
||||||
"resolved": "https://registry.npmjs.org/@swc/core-win32-ia32-msvc/-/core-win32-ia32-msvc-1.10.12.tgz",
|
"resolved": "https://registry.npmjs.org/@swc/core-win32-ia32-msvc/-/core-win32-ia32-msvc-1.10.16.tgz",
|
||||||
"integrity": "sha512-4Qrw+0Xt+Fe2rz4OJ/dEPMeUf/rtuFWWAj/e0vL7J5laUHirzxawLRE5DCJLQTarOiYR6mWnmadt9o3EKzV6Xg==",
|
"integrity": "sha512-7Jf/7AeCgbLR/JsQgMJuacHIq4Jeie3knf6+mXxn8aCvRypsOTIEu0eh7j24SolOboxK1ijqJ86GyN1VA2Rebg==",
|
||||||
"cpu": [
|
"cpu": [
|
||||||
"ia32"
|
"ia32"
|
||||||
],
|
],
|
||||||
@ -2025,9 +2025,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@swc/core-win32-x64-msvc": {
|
"node_modules/@swc/core-win32-x64-msvc": {
|
||||||
"version": "1.10.12",
|
"version": "1.10.16",
|
||||||
"resolved": "https://registry.npmjs.org/@swc/core-win32-x64-msvc/-/core-win32-x64-msvc-1.10.12.tgz",
|
"resolved": "https://registry.npmjs.org/@swc/core-win32-x64-msvc/-/core-win32-x64-msvc-1.10.16.tgz",
|
||||||
"integrity": "sha512-YiloZXLW7rUxJpALwHXaGjVaAEn+ChoblG7/3esque+Y7QCyheoBUJp2DVM1EeVA43jBfZ8tvYF0liWd9Tpz1A==",
|
"integrity": "sha512-p0blVm0R8bjaTtmW+FoPmLxLSQdRNbqhuWcR/8g80OzMSkka9mk5/J3kn/5JRVWh+MaR9LHRHZc1Q1L8zan13g==",
|
||||||
"cpu": [
|
"cpu": [
|
||||||
"x64"
|
"x64"
|
||||||
],
|
],
|
||||||
@ -2079,9 +2079,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@types/chrome": {
|
"node_modules/@types/chrome": {
|
||||||
"version": "0.0.300",
|
"version": "0.0.304",
|
||||||
"resolved": "https://registry.npmjs.org/@types/chrome/-/chrome-0.0.300.tgz",
|
"resolved": "https://registry.npmjs.org/@types/chrome/-/chrome-0.0.304.tgz",
|
||||||
"integrity": "sha512-vS5bUmNjMrbPut43Q8plS8GTAiJE+pBOxw1ovGC4LcwiGNKTithAH7TxhzHeX4wNq/FsaLj5KaW7riI0CgYjIg==",
|
"integrity": "sha512-ms9CLILU+FEMK7gcmgz/Mtn2E81YQWiMIzCFF8ktp98EVNIIfoqaDTD4+ailOCq1sGjbnEmfJxQ1FAsQtk5M3A==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
@ -2114,9 +2114,9 @@
|
|||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
"node_modules/@types/node": {
|
"node_modules/@types/node": {
|
||||||
"version": "22.13.0",
|
"version": "22.13.2",
|
||||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-22.13.0.tgz",
|
"resolved": "https://registry.npmjs.org/@types/node/-/node-22.13.2.tgz",
|
||||||
"integrity": "sha512-ClIbNe36lawluuvq3+YYhnIN2CELi+6q8NpnM7PYp4hBn/TatfboPgVSm2rwKRfnV2M+Ty9GWDFI64KEe+kysA==",
|
"integrity": "sha512-Z+r8y3XL9ZpI2EY52YYygAFmo2/oWfNSj4BCpAXE2McAexDk8VcnBMGC9Djn9gTKt4d2T/hhXqmPzo4hfIXtTg==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
@ -2311,9 +2311,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/caniuse-lite": {
|
"node_modules/caniuse-lite": {
|
||||||
"version": "1.0.30001696",
|
"version": "1.0.30001699",
|
||||||
"resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001696.tgz",
|
"resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001699.tgz",
|
||||||
"integrity": "sha512-pDCPkvzfa39ehJtJ+OwGT/2yvT2SbjfHhiIW2LWOAcMQ7BzwxT/XuyUp4OTOd0XFWA6BKw0JalnBHgSi5DGJBQ==",
|
"integrity": "sha512-b+uH5BakXZ9Do9iK+CkDmctUSEqZl+SP056vc5usa0PL+ev5OHw003rZXcnjNDv3L8P5j6rwT6C0BPKSikW08w==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"funding": [
|
"funding": [
|
||||||
{
|
{
|
||||||
@ -2642,9 +2642,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/electron-to-chromium": {
|
"node_modules/electron-to-chromium": {
|
||||||
"version": "1.5.90",
|
"version": "1.5.98",
|
||||||
"resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.90.tgz",
|
"resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.98.tgz",
|
||||||
"integrity": "sha512-C3PN4aydfW91Natdyd449Kw+BzhLmof6tzy5W1pFC5SpQxVXT+oyiyOG9AgYYSN9OdA/ik3YkCrpwqI8ug5Tug==",
|
"integrity": "sha512-bI/LbtRBxU2GzK7KK5xxFd2y9Lf9XguHooPYbcXWy6wUoT8NMnffsvRhPmSeUHLSDKAEtKuTaEtK4Ms15zkIEA==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "ISC"
|
"license": "ISC"
|
||||||
},
|
},
|
||||||
@ -2892,9 +2892,9 @@
|
|||||||
"license": "BSD-3-Clause"
|
"license": "BSD-3-Clause"
|
||||||
},
|
},
|
||||||
"node_modules/import-fresh": {
|
"node_modules/import-fresh": {
|
||||||
"version": "3.3.0",
|
"version": "3.3.1",
|
||||||
"resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz",
|
"resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.1.tgz",
|
||||||
"integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==",
|
"integrity": "sha512-TR3KfrTZTYLPB6jUjfx6MF9WcWrHL9su5TObK4ZkYgBdWKPOFoSoQIdEuTuR82pmtxH2spWG9h6etwfr1pLBqQ==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
@ -3651,9 +3651,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/postcss": {
|
"node_modules/postcss": {
|
||||||
"version": "8.5.1",
|
"version": "8.5.2",
|
||||||
"resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.1.tgz",
|
"resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.2.tgz",
|
||||||
"integrity": "sha512-6oz2beyjc5VMn/KV1pPw8fliQkhBXrVn1Z3TVyqZxU8kZpzEKhBdmCFqI6ZbmGtamQvQGuU1sgPTk8ZrXDD7jQ==",
|
"integrity": "sha512-MjOadfU3Ys9KYoX0AdkBlFEF1Vx37uCCeN4ZHnmwm9FfpbsGWMZeBLMmmpY+6Ocqod7mkdZ0DT31OlbsFrLlkA==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"funding": [
|
"funding": [
|
||||||
{
|
{
|
||||||
@ -4022,9 +4022,9 @@
|
|||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
"node_modules/semver": {
|
"node_modules/semver": {
|
||||||
"version": "7.7.0",
|
"version": "7.7.1",
|
||||||
"resolved": "https://registry.npmjs.org/semver/-/semver-7.7.0.tgz",
|
"resolved": "https://registry.npmjs.org/semver/-/semver-7.7.1.tgz",
|
||||||
"integrity": "sha512-DrfFnPzblFmNrIZzg5RzHegbiRWg7KMR7btwi2yjHwx06zsUbO5g613sVwEV7FTwmzJu+Io0lJe2GJ3LxqpvBQ==",
|
"integrity": "sha512-hlq8tAfn0m/61p4BVRcPzIGr6LKiMwo4VM6dGi6pt4qcRkmNzTcWq6eCEjEh+qXjkMDvPlOFFSGwQjoEa6gyMA==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "ISC",
|
"license": "ISC",
|
||||||
"bin": {
|
"bin": {
|
||||||
|
@ -48,8 +48,8 @@
|
|||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@parcel/config-webextension": "^2.13.3",
|
"@parcel/config-webextension": "^2.13.3",
|
||||||
"@types/chrome": "^0.0.300",
|
"@types/chrome": "^0.0.304",
|
||||||
"@types/node": "^22.13.0",
|
"@types/node": "^22.13.2",
|
||||||
"@types/webextension-polyfill": "^0.12.1",
|
"@types/webextension-polyfill": "^0.12.1",
|
||||||
"buffer": "^6.0.3",
|
"buffer": "^6.0.3",
|
||||||
"parcel": "^2.13.3",
|
"parcel": "^2.13.3",
|
||||||
|
@ -4,7 +4,8 @@ export default function isChannelWhitelisted(
|
|||||||
channelName: string | null
|
channelName: string | null
|
||||||
): boolean {
|
): boolean {
|
||||||
if (!channelName) return false;
|
if (!channelName) return false;
|
||||||
|
const channelNameLower = channelName.toLowerCase();
|
||||||
return store.state.whitelistedChannels.some(
|
return store.state.whitelistedChannels.some(
|
||||||
c => c.toLowerCase() === channelName.toLowerCase()
|
channel => channel.toLowerCase() === channelNameLower
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -1,9 +1,24 @@
|
|||||||
import { Address6 } from "ip-address";
|
import { Address6 } from "ip-address";
|
||||||
import type { ProxyInfo } from "../../types";
|
import type { ProxyInfo, ProxyType } from "../../types";
|
||||||
|
|
||||||
|
const DEFAULT_PORTS: Readonly<Record<ProxyType, number>> = Object.freeze({
|
||||||
|
direct: 0,
|
||||||
|
http: 80,
|
||||||
|
https: 443,
|
||||||
|
socks: 1080,
|
||||||
|
socks4: 1080,
|
||||||
|
});
|
||||||
|
|
||||||
export function getProxyInfoFromUrl(
|
export function getProxyInfoFromUrl(
|
||||||
url: string
|
url: string
|
||||||
): ProxyInfo & { type: "http"; host: string; port: number } {
|
): ProxyInfo & { host: string; port: number } {
|
||||||
|
let type: ProxyType | undefined = undefined;
|
||||||
|
if (url.includes("://")) {
|
||||||
|
const [protocol] = url.split("://", 1);
|
||||||
|
type = protocol as ProxyType;
|
||||||
|
url = url.substring(protocol.length + 3, url.length);
|
||||||
|
}
|
||||||
|
|
||||||
const lastIndexOfAt = url.lastIndexOf("@");
|
const lastIndexOfAt = url.lastIndexOf("@");
|
||||||
const hostname = url.substring(lastIndexOfAt + 1, url.length);
|
const hostname = url.substring(lastIndexOfAt + 1, url.length);
|
||||||
const lastIndexOfColon = getLastIndexOfColon(hostname);
|
const lastIndexOfColon = getLastIndexOfColon(hostname);
|
||||||
@ -12,7 +27,7 @@ export function getProxyInfoFromUrl(
|
|||||||
let port: number | undefined = undefined;
|
let port: number | undefined = undefined;
|
||||||
if (lastIndexOfColon === -1) {
|
if (lastIndexOfColon === -1) {
|
||||||
host = hostname;
|
host = hostname;
|
||||||
port = 3128; // Default port
|
port = type ? DEFAULT_PORTS[type] : 3128; // Default port
|
||||||
} else {
|
} else {
|
||||||
host = hostname.substring(0, lastIndexOfColon);
|
host = hostname.substring(0, lastIndexOfColon);
|
||||||
port = Number(hostname.substring(lastIndexOfColon + 1, hostname.length));
|
port = Number(hostname.substring(lastIndexOfColon + 1, hostname.length));
|
||||||
@ -31,7 +46,7 @@ export function getProxyInfoFromUrl(
|
|||||||
}
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
type: "http",
|
type: type ?? "http",
|
||||||
host,
|
host,
|
||||||
port,
|
port,
|
||||||
username,
|
username,
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import store from "../../store";
|
import store from "../../store";
|
||||||
import { ProxyRequestType } from "../../types";
|
import { ProxyRequestType, ProxyType } from "../../types";
|
||||||
import isRequestTypeProxied from "./isRequestTypeProxied";
|
import isRequestTypeProxied from "./isRequestTypeProxied";
|
||||||
import { getProxyInfoFromUrl, getUrlFromProxyInfo } from "./proxyInfo";
|
import { getProxyInfoFromUrl, getUrlFromProxyInfo } from "./proxyInfo";
|
||||||
import {
|
import {
|
||||||
@ -11,6 +11,14 @@ import {
|
|||||||
} from "./regexes";
|
} from "./regexes";
|
||||||
import updateDnsResponses from "./updateDnsResponses";
|
import updateDnsResponses from "./updateDnsResponses";
|
||||||
|
|
||||||
|
const PROXY_TYPE_MAP: Readonly<Record<ProxyType, string>> = Object.freeze({
|
||||||
|
direct: "DIRECT",
|
||||||
|
http: "PROXY",
|
||||||
|
https: "HTTPS",
|
||||||
|
socks: "SOCKS5",
|
||||||
|
socks4: "SOCKS4",
|
||||||
|
});
|
||||||
|
|
||||||
export function updateProxySettings(requestFilter?: ProxyRequestType[]) {
|
export function updateProxySettings(requestFilter?: ProxyRequestType[]) {
|
||||||
const { optimizedProxiesEnabled, passportLevel } = store.state;
|
const { optimizedProxiesEnabled, passportLevel } = store.state;
|
||||||
|
|
||||||
@ -92,7 +100,7 @@ function getProxyInfoStringFromUrls(urls: string[]): string {
|
|||||||
return [
|
return [
|
||||||
...urls.map(url => {
|
...urls.map(url => {
|
||||||
const proxyInfo = getProxyInfoFromUrl(url);
|
const proxyInfo = getProxyInfoFromUrl(url);
|
||||||
return `PROXY ${getUrlFromProxyInfo({
|
return `${PROXY_TYPE_MAP[proxyInfo.type]} ${getUrlFromProxyInfo({
|
||||||
...proxyInfo,
|
...proxyInfo,
|
||||||
// Don't include username/password in PAC script.
|
// Don't include username/password in PAC script.
|
||||||
username: undefined,
|
username: undefined,
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
export const passportHostRegex = /^passport\.twitch\.tv$/i;
|
export const passportHostRegex = /^passport\.twitch\.tv$/i;
|
||||||
export const twitchApiChannelNameRegex = /\/hls\/(.+)\.m3u8/i;
|
export const twitchApiChannelNameRegex = /\/hls\/(.+)\.m3u8/i;
|
||||||
export const twitchChannelNameRegex =
|
export const twitchChannelNameRegex =
|
||||||
/^https?:\/\/(?:www|m)\.twitch\.tv\/(?:videos\/|popout\/|moderator\/)?((?!(?:directory|jobs|p|privacy|store|turbo)\b)\w+)/i;
|
/^https?:\/\/(?:www|m)\.twitch\.tv\/(?:videos\/|popout\/|moderator\/)?((?!(?:directory|downloads|jobs|p|privacy|search|settings|store|turbo)\b)\w+)/i;
|
||||||
export const twitchGqlHostRegex = /^gql\.twitch\.tv$/i;
|
export const twitchGqlHostRegex = /^gql\.twitch\.tv$/i;
|
||||||
export const twitchTvHostRegex = /^(?:www|m)\.twitch\.tv$/i;
|
export const twitchTvHostRegex = /^(?:www|m)\.twitch\.tv$/i;
|
||||||
export const usherHostRegex = /^usher\.ttvnw\.net$/i;
|
export const usherHostRegex = /^usher\.ttvnw\.net$/i;
|
||||||
|
@ -1,10 +0,0 @@
|
|||||||
import store from "../../store";
|
|
||||||
|
|
||||||
export default function wasChannelSubscriber(
|
|
||||||
channelName: string | null
|
|
||||||
): boolean {
|
|
||||||
if (!channelName) return false;
|
|
||||||
return store.state.activeChannelSubscriptions.some(
|
|
||||||
c => c.toLowerCase() === channelName.toLowerCase()
|
|
||||||
);
|
|
||||||
}
|
|
@ -47,10 +47,13 @@ function onStoreLoad() {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Clear stats for stream on page load/reload.
|
* Clear stats for stream on page load/reload.
|
||||||
|
* @param channelName
|
||||||
|
* @param delayMs
|
||||||
* @returns
|
* @returns
|
||||||
*/
|
*/
|
||||||
function clearStats(channelName: string | null) {
|
async function clearStats(channelName: string | null, delayMs?: number) {
|
||||||
if (!channelName) return;
|
if (!channelName) return;
|
||||||
|
if (delayMs) await new Promise(resolve => setTimeout(resolve, delayMs));
|
||||||
const channelNameLower = channelName.toLowerCase();
|
const channelNameLower = channelName.toLowerCase();
|
||||||
if (store.state.streamStatuses.hasOwnProperty(channelNameLower)) {
|
if (store.state.streamStatuses.hasOwnProperty(channelNameLower)) {
|
||||||
delete store.state.streamStatuses[channelNameLower];
|
delete store.state.streamStatuses[channelNameLower];
|
||||||
@ -102,7 +105,7 @@ function onPageMessage(event: MessageEvent) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const { message, responseType, responseMessageType } = event.data;
|
const { message } = event.data;
|
||||||
if (!message) return;
|
if (!message) return;
|
||||||
|
|
||||||
if (message.type === MessageType.GetStoreState) {
|
if (message.type === MessageType.GetStoreState) {
|
||||||
@ -142,48 +145,50 @@ function onPageMessage(event: MessageEvent) {
|
|||||||
}
|
}
|
||||||
// ---
|
// ---
|
||||||
else if (message.type === MessageType.ChannelSubStatusChange) {
|
else if (message.type === MessageType.ChannelSubStatusChange) {
|
||||||
const { channelName, wasSubscribed, isSubscribed } = message;
|
const { channelNameLower, wasSubscribed, isSubscribed } = message;
|
||||||
const isWhitelisted = isChannelWhitelisted(channelName);
|
const isWhitelisted = isChannelWhitelisted(channelNameLower);
|
||||||
console.log("[TTV LOL PRO] ChannelSubStatusChange", {
|
console.log("[TTV LOL PRO] ChannelSubStatusChange", {
|
||||||
channelName,
|
channelNameLower,
|
||||||
wasSubscribed,
|
wasSubscribed,
|
||||||
isSubscribed,
|
isSubscribed,
|
||||||
isWhitelisted,
|
isWhitelisted,
|
||||||
});
|
});
|
||||||
if (store.state.whitelistChannelSubscriptions && channelName != null) {
|
const currentChannelNameLower = findChannelFromTwitchTvUrl(
|
||||||
|
location.href
|
||||||
|
)?.toLowerCase();
|
||||||
|
if (store.state.whitelistChannelSubscriptions && channelNameLower != null) {
|
||||||
if (!wasSubscribed && isSubscribed) {
|
if (!wasSubscribed && isSubscribed) {
|
||||||
store.state.activeChannelSubscriptions.push(channelName);
|
store.state.activeChannelSubscriptions.push(channelNameLower);
|
||||||
// Add to whitelist.
|
// Add to whitelist.
|
||||||
if (!isWhitelisted) {
|
if (!isWhitelisted) {
|
||||||
console.log(`[TTV LOL PRO] Adding '${channelName}' to whitelist.`);
|
console.log(
|
||||||
store.state.whitelistedChannels.push(channelName);
|
`[TTV LOL PRO] Adding '${channelNameLower}' to whitelist.`
|
||||||
|
);
|
||||||
|
store.state.whitelistedChannels.push(channelNameLower);
|
||||||
|
if (channelNameLower === currentChannelNameLower) {
|
||||||
|
location.reload();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} else if (wasSubscribed && !isSubscribed) {
|
} else if (wasSubscribed && !isSubscribed) {
|
||||||
store.state.activeChannelSubscriptions =
|
store.state.activeChannelSubscriptions =
|
||||||
store.state.activeChannelSubscriptions.filter(
|
store.state.activeChannelSubscriptions.filter(
|
||||||
c => c.toLowerCase() !== channelName.toLowerCase()
|
channel => channel.toLowerCase() !== channelNameLower
|
||||||
);
|
);
|
||||||
// Remove from whitelist.
|
// Remove from whitelist.
|
||||||
if (isWhitelisted) {
|
if (isWhitelisted) {
|
||||||
console.log(
|
console.log(
|
||||||
`[TTV LOL PRO] Removing '${channelName}' from whitelist.`
|
`[TTV LOL PRO] Removing '${channelNameLower}' from whitelist.`
|
||||||
);
|
);
|
||||||
store.state.whitelistedChannels =
|
store.state.whitelistedChannels =
|
||||||
store.state.whitelistedChannels.filter(
|
store.state.whitelistedChannels.filter(
|
||||||
c => c.toLowerCase() !== channelName.toLowerCase()
|
channel => channel.toLowerCase() !== channelNameLower
|
||||||
);
|
);
|
||||||
|
if (channelNameLower === currentChannelNameLower) {
|
||||||
|
location.reload();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
window.postMessage({
|
|
||||||
type: responseType,
|
|
||||||
message: {
|
|
||||||
type: responseMessageType,
|
|
||||||
whitelistedChannels: JSON.parse(
|
|
||||||
JSON.stringify(store.state.whitelistedChannels)
|
|
||||||
),
|
|
||||||
},
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
// ---
|
// ---
|
||||||
else if (message.type === MessageType.UsherResponse) {
|
else if (message.type === MessageType.UsherResponse) {
|
||||||
@ -208,6 +213,6 @@ function onPageMessage(event: MessageEvent) {
|
|||||||
}
|
}
|
||||||
// ---
|
// ---
|
||||||
else if (message.type === MessageType.ClearStats) {
|
else if (message.type === MessageType.ClearStats) {
|
||||||
clearStats(message.channelName);
|
clearStats(message.channelName, 2000);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -28,7 +28,7 @@ type ListOptions = {
|
|||||||
getPromptPlaceholder(insertMode: InsertMode): string;
|
getPromptPlaceholder(insertMode: InsertMode): string;
|
||||||
isAddAllowed(text: string): AllowedResult;
|
isAddAllowed(text: string): AllowedResult;
|
||||||
isEditAllowed(text: string): AllowedResult;
|
isEditAllowed(text: string): AllowedResult;
|
||||||
onEdit?(text: string): void;
|
onChange?(oldText: string | undefined, newText: string): void;
|
||||||
focusPrompt: boolean;
|
focusPrompt: boolean;
|
||||||
hidePromptMarker: boolean;
|
hidePromptMarker: boolean;
|
||||||
insertMode: InsertMode;
|
insertMode: InsertMode;
|
||||||
@ -85,6 +85,9 @@ const optimizedProxiesListElement = $(
|
|||||||
) as HTMLOListElement;
|
) as HTMLOListElement;
|
||||||
const normalProxiesInputElement = $("#normal") as HTMLInputElement;
|
const normalProxiesInputElement = $("#normal") as HTMLInputElement;
|
||||||
const normalProxiesListElement = $("#normal-proxies-list") as HTMLOListElement;
|
const normalProxiesListElement = $("#normal-proxies-list") as HTMLOListElement;
|
||||||
|
const otherProtocolsCheckboxElement = $(
|
||||||
|
"#other-protocols-checkbox"
|
||||||
|
) as HTMLInputElement;
|
||||||
// Ad log
|
// Ad log
|
||||||
const adLogEnabledCheckboxElement = $(
|
const adLogEnabledCheckboxElement = $(
|
||||||
"#ad-log-enabled-checkbox"
|
"#ad-log-enabled-checkbox"
|
||||||
@ -159,12 +162,6 @@ function main() {
|
|||||||
}
|
}
|
||||||
return [true];
|
return [true];
|
||||||
},
|
},
|
||||||
isEditAllowed(text) {
|
|
||||||
if (!/^[a-z0-9_]+$/i.test(text)) {
|
|
||||||
return [false, `'${text}' is not a valid channel name`];
|
|
||||||
}
|
|
||||||
return [true];
|
|
||||||
},
|
|
||||||
});
|
});
|
||||||
whitelistSubscriptionsCheckboxElement.checked =
|
whitelistSubscriptionsCheckboxElement.checked =
|
||||||
store.state.whitelistChannelSubscriptions;
|
store.state.whitelistChannelSubscriptions;
|
||||||
@ -180,44 +177,21 @@ function main() {
|
|||||||
if (store.state.optimizedProxiesEnabled)
|
if (store.state.optimizedProxiesEnabled)
|
||||||
optimizedProxiesInputElement.checked = true;
|
optimizedProxiesInputElement.checked = true;
|
||||||
else normalProxiesInputElement.checked = true;
|
else normalProxiesInputElement.checked = true;
|
||||||
const onProxyTypeChange = () => {
|
const onProxyModeChange = () => {
|
||||||
store.state.optimizedProxiesEnabled = optimizedProxiesInputElement.checked;
|
store.state.optimizedProxiesEnabled = optimizedProxiesInputElement.checked;
|
||||||
if (isChromium && store.state.chromiumProxyActive) {
|
if (isChromium && store.state.chromiumProxyActive) {
|
||||||
updateProxySettings();
|
updateProxySettings();
|
||||||
}
|
}
|
||||||
updateProxyUsage();
|
updateProxyUsage();
|
||||||
};
|
};
|
||||||
optimizedProxiesInputElement.addEventListener("change", onProxyTypeChange);
|
optimizedProxiesInputElement.addEventListener("change", onProxyModeChange);
|
||||||
normalProxiesInputElement.addEventListener("change", onProxyTypeChange);
|
normalProxiesInputElement.addEventListener("change", onProxyModeChange);
|
||||||
listInit(optimizedProxiesListElement, "optimizedProxies", {
|
loadProxiesLists();
|
||||||
getPromptPlaceholder: insertMode => {
|
otherProtocolsCheckboxElement.checked = store.state.allowOtherProxyProtocols;
|
||||||
if (insertMode == "prepend") return "Enter a proxy URL… (Primary)";
|
otherProtocolsCheckboxElement.addEventListener("change", () => {
|
||||||
return "Enter a proxy URL… (Fallback)";
|
store.state.allowOtherProxyProtocols =
|
||||||
},
|
otherProtocolsCheckboxElement.checked;
|
||||||
isAddAllowed: isOptimizedProxyUrlAllowed,
|
loadProxiesLists();
|
||||||
isEditAllowed: isOptimizedProxyUrlAllowed,
|
|
||||||
onEdit() {
|
|
||||||
if (isChromium && store.state.chromiumProxyActive) {
|
|
||||||
updateProxySettings();
|
|
||||||
}
|
|
||||||
},
|
|
||||||
hidePromptMarker: true,
|
|
||||||
insertMode: "both",
|
|
||||||
});
|
|
||||||
listInit(normalProxiesListElement, "normalProxies", {
|
|
||||||
getPromptPlaceholder: insertMode => {
|
|
||||||
if (insertMode == "prepend") return "Enter a proxy URL… (Primary)";
|
|
||||||
return "Enter a proxy URL… (Fallback)";
|
|
||||||
},
|
|
||||||
isAddAllowed: isNormalProxyUrlAllowed,
|
|
||||||
isEditAllowed: isNormalProxyUrlAllowed,
|
|
||||||
onEdit() {
|
|
||||||
if (isChromium && store.state.chromiumProxyActive) {
|
|
||||||
updateProxySettings();
|
|
||||||
}
|
|
||||||
},
|
|
||||||
hidePromptMarker: true,
|
|
||||||
insertMode: "both",
|
|
||||||
});
|
});
|
||||||
// Ad log
|
// Ad log
|
||||||
adLogEnabledCheckboxElement.checked = store.state.adLogEnabled;
|
adLogEnabledCheckboxElement.checked = store.state.adLogEnabled;
|
||||||
@ -304,6 +278,37 @@ function updateProxyUsage() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function loadProxiesLists() {
|
||||||
|
listInit(optimizedProxiesListElement, "optimizedProxies", {
|
||||||
|
getPromptPlaceholder: insertMode => {
|
||||||
|
if (insertMode == "prepend") return "Enter a proxy URL… (Primary)";
|
||||||
|
return "Enter a proxy URL… (Fallback)";
|
||||||
|
},
|
||||||
|
isAddAllowed: isOptimizedProxyUrlAllowed,
|
||||||
|
onChange() {
|
||||||
|
if (isChromium && store.state.chromiumProxyActive) {
|
||||||
|
updateProxySettings();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
hidePromptMarker: true,
|
||||||
|
insertMode: "both",
|
||||||
|
});
|
||||||
|
listInit(normalProxiesListElement, "normalProxies", {
|
||||||
|
getPromptPlaceholder: insertMode => {
|
||||||
|
if (insertMode == "prepend") return "Enter a proxy URL… (Primary)";
|
||||||
|
return "Enter a proxy URL… (Fallback)";
|
||||||
|
},
|
||||||
|
isAddAllowed: isNormalProxyUrlAllowed,
|
||||||
|
onChange() {
|
||||||
|
if (isChromium && store.state.chromiumProxyActive) {
|
||||||
|
updateProxySettings();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
hidePromptMarker: true,
|
||||||
|
insertMode: "both",
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
function isOptimizedProxyUrlAllowed(url: string): AllowedResult {
|
function isOptimizedProxyUrlAllowed(url: string): AllowedResult {
|
||||||
const urlLower = url.toLowerCase();
|
const urlLower = url.toLowerCase();
|
||||||
|
|
||||||
@ -336,8 +341,17 @@ function isOptimizedProxyUrlAllowed(url: string): AllowedResult {
|
|||||||
return [false, "TTV LOL PRO v1 proxies are not compatible"];
|
return [false, "TTV LOL PRO v1 proxies are not compatible"];
|
||||||
}
|
}
|
||||||
|
|
||||||
if (/^https?:\/\//i.test(url)) {
|
if (url.includes("://")) {
|
||||||
return [false, "Proxy URLs must not contain a protocol (e.g. 'http://')"];
|
const [protocol] = url.split("://", 1);
|
||||||
|
if (!store.state.allowOtherProxyProtocols) {
|
||||||
|
return [
|
||||||
|
false,
|
||||||
|
"Proxy URLs are not allowed to contain a protocol (e.g. 'http://')",
|
||||||
|
];
|
||||||
|
} else if (!["http", "https", "socks", "socks4"].includes(protocol)) {
|
||||||
|
return [false, `'${protocol}' is not a supported protocol`];
|
||||||
|
}
|
||||||
|
url = url.substring(protocol.length + 3, url.length);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (url.includes("/")) {
|
if (url.includes("/")) {
|
||||||
@ -401,6 +415,7 @@ function listInit(
|
|||||||
storeKey: StoreStringArrayKey,
|
storeKey: StoreStringArrayKey,
|
||||||
options: Partial<ListOptions> = {}
|
options: Partial<ListOptions> = {}
|
||||||
) {
|
) {
|
||||||
|
listElement.innerHTML = ""; // Reset list element.
|
||||||
const listOptions: ListOptions = { ...DEFAULT_LIST_OPTIONS, ...options };
|
const listOptions: ListOptions = { ...DEFAULT_LIST_OPTIONS, ...options };
|
||||||
for (const text of store.state[storeKey]) {
|
for (const text of store.state[storeKey]) {
|
||||||
_listAppend(listElement, storeKey, text, {
|
_listAppend(listElement, storeKey, text, {
|
||||||
@ -460,18 +475,19 @@ function _listAppend(
|
|||||||
return console.error(`Item '${text}' not found in '${storeKey}' array`);
|
return console.error(`Item '${text}' not found in '${storeKey}' array`);
|
||||||
|
|
||||||
const textInput = e.target as HTMLInputElement;
|
const textInput = e.target as HTMLInputElement;
|
||||||
|
const oldText = text;
|
||||||
const newText = textInput.value.trim();
|
const newText = textInput.value.trim();
|
||||||
// Remove item if text is empty.
|
// Remove item if text is empty.
|
||||||
if (newText === "") {
|
if (newText === "") {
|
||||||
store.state[storeKey].splice(itemIndex, 1);
|
store.state[storeKey].splice(itemIndex, 1);
|
||||||
listItem.remove();
|
listItem.remove();
|
||||||
if (options.onEdit) options.onEdit(newText);
|
if (options.onChange) options.onChange(oldText, newText);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// Check if text is valid.
|
// Check if text is valid.
|
||||||
const [allowed, error] = options.isEditAllowed(newText);
|
const [allowed, error] = options.isAddAllowed(newText);
|
||||||
if (!allowed) {
|
if (!allowed) {
|
||||||
alert(error || "You cannot edit this item");
|
alert(error || "You cannot add this item");
|
||||||
textInput.value = text;
|
textInput.value = text;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -480,7 +496,7 @@ function _listAppend(
|
|||||||
textInput.placeholder = options.getItemPlaceholder(newText);
|
textInput.placeholder = options.getItemPlaceholder(newText);
|
||||||
textInput.value = newText; // Update text in case it was trimmed.
|
textInput.value = newText; // Update text in case it was trimmed.
|
||||||
text = newText; // Update current text variable.
|
text = newText; // Update current text variable.
|
||||||
if (options.onEdit) options.onEdit(newText);
|
if (options.onChange) options.onChange(oldText, newText);
|
||||||
});
|
});
|
||||||
|
|
||||||
listItem.append(textInput);
|
listItem.append(textInput);
|
||||||
@ -535,7 +551,7 @@ function _listPrompt(
|
|||||||
if (options.insertMode === "prepend") newArray.unshift(text);
|
if (options.insertMode === "prepend") newArray.unshift(text);
|
||||||
else newArray.push(text);
|
else newArray.push(text);
|
||||||
store.state[storeKey] = newArray;
|
store.state[storeKey] = newArray;
|
||||||
if (options.onEdit) options.onEdit(text);
|
if (options.onChange) options.onChange(undefined, text);
|
||||||
|
|
||||||
listItem.remove();
|
listItem.remove();
|
||||||
_listAppend(listElement, storeKey, text, options);
|
_listAppend(listElement, storeKey, text, options);
|
||||||
@ -556,6 +572,7 @@ function _listPrompt(
|
|||||||
exportButtonElement.addEventListener("click", () => {
|
exportButtonElement.addEventListener("click", () => {
|
||||||
const state: Partial<State> = {
|
const state: Partial<State> = {
|
||||||
adLogEnabled: store.state.adLogEnabled,
|
adLogEnabled: store.state.adLogEnabled,
|
||||||
|
allowOtherProxyProtocols: store.state.allowOtherProxyProtocols,
|
||||||
anonymousMode: store.state.anonymousMode,
|
anonymousMode: store.state.anonymousMode,
|
||||||
normalProxies: store.state.normalProxies,
|
normalProxies: store.state.normalProxies,
|
||||||
optimizedProxies: store.state.optimizedProxies,
|
optimizedProxies: store.state.optimizedProxies,
|
||||||
|
@ -200,6 +200,34 @@
|
|||||||
>List of other proxies</a
|
>List of other proxies</a
|
||||||
>" discussion on TTV LOL PRO's GitHub repository.
|
>" discussion on TTV LOL PRO's GitHub repository.
|
||||||
</small>
|
</small>
|
||||||
|
<br /><br />
|
||||||
|
<ul class="options-list">
|
||||||
|
<li>
|
||||||
|
<input
|
||||||
|
type="checkbox"
|
||||||
|
name="other-protocols-checkbox"
|
||||||
|
id="other-protocols-checkbox"
|
||||||
|
/>
|
||||||
|
<label for="other-protocols-checkbox">
|
||||||
|
Allow the use of other protocols
|
||||||
|
</label>
|
||||||
|
<span class="tag">For advanced users only</span>
|
||||||
|
<br />
|
||||||
|
<small>
|
||||||
|
This option allows you to use protocols other than HTTP.
|
||||||
|
</small>
|
||||||
|
<br />
|
||||||
|
<small>
|
||||||
|
Supported protocols are HTTPS (<code>https://</code>), SOCKS4
|
||||||
|
(<code>socks4://</code>), and SOCKS5 (<code>socks://</code>).
|
||||||
|
</small>
|
||||||
|
<br />
|
||||||
|
<small>
|
||||||
|
To provide a protocol, use the format
|
||||||
|
<code>protocol://hostname:port</code>
|
||||||
|
</small>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
<!-- Ad log -->
|
<!-- Ad log -->
|
||||||
|
@ -44,14 +44,10 @@ export function getFetch(pageState: PageState): typeof fetch {
|
|||||||
cachedPlaybackTokenRequestHeaders,
|
cachedPlaybackTokenRequestHeaders,
|
||||||
cachedPlaybackTokenRequestBody
|
cachedPlaybackTokenRequestBody
|
||||||
);
|
);
|
||||||
const message = {
|
pageState.sendMessageToWorkerScripts(pageState.twitchWorkers, {
|
||||||
type: MessageType.NewPlaybackAccessTokenResponse,
|
type: MessageType.NewPlaybackAccessTokenResponse,
|
||||||
newPlaybackAccessToken,
|
newPlaybackAccessToken,
|
||||||
};
|
});
|
||||||
pageState.sendMessageToWorkerScripts(
|
|
||||||
pageState.twitchWorkers,
|
|
||||||
message
|
|
||||||
);
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@ -75,9 +71,13 @@ export function getFetch(pageState: PageState): typeof fetch {
|
|||||||
console.log("[TTV LOL PRO] Cleared stats (getFetch).");
|
console.log("[TTV LOL PRO] Cleared stats (getFetch).");
|
||||||
if (!message.channelName) break;
|
if (!message.channelName) break;
|
||||||
const channelNameLower = message.channelName.toLowerCase();
|
const channelNameLower = message.channelName.toLowerCase();
|
||||||
usherManifests = usherManifests.filter(
|
for (let i = 0; i < usherManifests.length; i++) {
|
||||||
manifest => manifest.channelName !== channelNameLower
|
if (
|
||||||
);
|
usherManifests[i].channelName?.toLowerCase() === channelNameLower
|
||||||
|
) {
|
||||||
|
usherManifests[i].deleted = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
if (cachedPlaybackTokenRequestBody?.includes(channelNameLower)) {
|
if (cachedPlaybackTokenRequestBody?.includes(channelNameLower)) {
|
||||||
cachedPlaybackTokenRequestHeaders = null;
|
cachedPlaybackTokenRequestHeaders = null;
|
||||||
cachedPlaybackTokenRequestBody = null;
|
cachedPlaybackTokenRequestBody = null;
|
||||||
@ -199,7 +199,7 @@ export function getFetch(pageState: PageState): typeof fetch {
|
|||||||
pageState.state?.anonymousMode === true ||
|
pageState.state?.anonymousMode === true ||
|
||||||
(shouldFlagRequest && willFailIntegrityCheckIfProxied);
|
(shouldFlagRequest && willFailIntegrityCheckIfProxied);
|
||||||
if (shouldOverrideRequest) {
|
if (shouldOverrideRequest) {
|
||||||
const newRequest = await getDefaultPlaybackAccessTokenRequest(
|
const newRequest = getDefaultPlaybackAccessTokenRequest(
|
||||||
channelName,
|
channelName,
|
||||||
pageState.state?.anonymousMode === true
|
pageState.state?.anonymousMode === true
|
||||||
);
|
);
|
||||||
@ -268,36 +268,6 @@ export function getFetch(pageState: PageState): typeof fetch {
|
|||||||
encodeURIComponent('"player_type":"frontpage"')
|
encodeURIComponent('"player_type":"frontpage"')
|
||||||
);
|
);
|
||||||
const channelName = findChannelFromUsherUrl(url);
|
const channelName = findChannelFromUsherUrl(url);
|
||||||
if (
|
|
||||||
pageState.state?.whitelistChannelSubscriptions &&
|
|
||||||
channelName != null
|
|
||||||
) {
|
|
||||||
const wasSubscribed = wasChannelSubscriber(channelName, pageState);
|
|
||||||
const isSubscribed = url.includes(
|
|
||||||
encodeURIComponent('"subscriber":true')
|
|
||||||
);
|
|
||||||
const hasSubStatusChanged =
|
|
||||||
(wasSubscribed && !isSubscribed) || (!wasSubscribed && isSubscribed);
|
|
||||||
if (hasSubStatusChanged) {
|
|
||||||
try {
|
|
||||||
const response =
|
|
||||||
await pageState.sendMessageToContentScriptAndWaitForResponse(
|
|
||||||
pageState.scope,
|
|
||||||
{
|
|
||||||
type: MessageType.ChannelSubStatusChange,
|
|
||||||
channelName,
|
|
||||||
wasSubscribed,
|
|
||||||
isSubscribed,
|
|
||||||
},
|
|
||||||
MessageType.ChannelSubStatusChangeResponse
|
|
||||||
);
|
|
||||||
if (typeof response.whitelistedChannels === "object") {
|
|
||||||
pageState.state.whitelistedChannels =
|
|
||||||
response.whitelistedChannels;
|
|
||||||
}
|
|
||||||
} catch {}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
const isWhitelisted = isChannelWhitelisted(channelName, pageState);
|
const isWhitelisted = isChannelWhitelisted(channelName, pageState);
|
||||||
if (!isLivestream || isFrontpage || isWhitelisted) {
|
if (!isLivestream || isFrontpage || isWhitelisted) {
|
||||||
console.log(
|
console.log(
|
||||||
@ -433,6 +403,68 @@ export function getFetch(pageState: PageState): typeof fetch {
|
|||||||
|
|
||||||
//#region Responses
|
//#region Responses
|
||||||
|
|
||||||
|
graphqlRes: if (
|
||||||
|
host != null &&
|
||||||
|
twitchGqlHostRegex.test(host) &&
|
||||||
|
response.status < 400
|
||||||
|
) {
|
||||||
|
await waitForStore(pageState);
|
||||||
|
if (!pageState.state?.whitelistChannelSubscriptions) break graphqlRes;
|
||||||
|
responseBody ??= await readResponseBody();
|
||||||
|
// Preliminary check to avoid parsing the response body if possible.
|
||||||
|
if (
|
||||||
|
!responseBody.includes('"UserSelfConnection"') ||
|
||||||
|
!responseBody.includes('"subscriptionBenefit"') ||
|
||||||
|
!responseBody.includes('"login"')
|
||||||
|
) {
|
||||||
|
break graphqlRes;
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
let channelName: string;
|
||||||
|
let isSubscribed: boolean;
|
||||||
|
const body = JSON.parse(responseBody);
|
||||||
|
if (Array.isArray(body)) {
|
||||||
|
const match = body.find(
|
||||||
|
(obj: any) =>
|
||||||
|
obj.data &&
|
||||||
|
obj.data.user &&
|
||||||
|
obj.data.user.login != null &&
|
||||||
|
obj.data.user.self &&
|
||||||
|
"subscriptionBenefit" in obj.data.user.self
|
||||||
|
);
|
||||||
|
if (match == null) break graphqlRes;
|
||||||
|
channelName = match.data.user.login;
|
||||||
|
isSubscribed = match.data.user.self.subscriptionBenefit != null;
|
||||||
|
} else {
|
||||||
|
const isMatch =
|
||||||
|
body.data &&
|
||||||
|
body.data.user &&
|
||||||
|
body.data.user.login != null &&
|
||||||
|
body.data.user.self &&
|
||||||
|
"subscriptionBenefit" in body.data.user.self;
|
||||||
|
if (!isMatch) break graphqlRes;
|
||||||
|
channelName = body.data.user.login;
|
||||||
|
isSubscribed = body.data.user.self.subscriptionBenefit != null;
|
||||||
|
}
|
||||||
|
if (!channelName) break graphqlRes;
|
||||||
|
const isLivestream = !/^\d+$/.test(channelName); // VODs have numeric IDs.
|
||||||
|
if (!isLivestream) break graphqlRes;
|
||||||
|
const wasSubscribed = wasChannelSubscriber(channelName, pageState);
|
||||||
|
const hasSubStatusChanged =
|
||||||
|
(wasSubscribed && !isSubscribed) || (!wasSubscribed && isSubscribed);
|
||||||
|
if (hasSubStatusChanged) {
|
||||||
|
pageState.sendMessageToContentScript({
|
||||||
|
type: MessageType.ChannelSubStatusChange,
|
||||||
|
channelNameLower: channelName.toLowerCase(),
|
||||||
|
wasSubscribed,
|
||||||
|
isSubscribed,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.error("[TTV LOL PRO] Failed to parse GraphQL response:", error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Twitch Usher responses.
|
// Twitch Usher responses.
|
||||||
usherRes: if (
|
usherRes: if (
|
||||||
host != null &&
|
host != null &&
|
||||||
@ -440,6 +472,7 @@ export function getFetch(pageState: PageState): typeof fetch {
|
|||||||
response.status < 400
|
response.status < 400
|
||||||
) {
|
) {
|
||||||
//#region Usher responses.
|
//#region Usher responses.
|
||||||
|
// No need to wait for store here because all Usher requests have already waited for it.
|
||||||
const isLivestream = !url.includes("/vod/");
|
const isLivestream = !url.includes("/vod/");
|
||||||
const isFrontpage = url.includes(
|
const isFrontpage = url.includes(
|
||||||
encodeURIComponent('"player_type":"frontpage"')
|
encodeURIComponent('"player_type":"frontpage"')
|
||||||
@ -449,6 +482,7 @@ export function getFetch(pageState: PageState): typeof fetch {
|
|||||||
if (!isLivestream) break usherRes;
|
if (!isLivestream) break usherRes;
|
||||||
|
|
||||||
responseBody ??= await readResponseBody();
|
responseBody ??= await readResponseBody();
|
||||||
|
usherManifests = usherManifests.filter(manifest => !manifest.deleted); // Clean up deleted manifests.
|
||||||
const assignedMap = parseUsherManifest(responseBody);
|
const assignedMap = parseUsherManifest(responseBody);
|
||||||
if (assignedMap != null) {
|
if (assignedMap != null) {
|
||||||
console.debug(
|
console.debug(
|
||||||
@ -461,9 +495,12 @@ export function getFetch(pageState: PageState): typeof fetch {
|
|||||||
replacementMap: null,
|
replacementMap: null,
|
||||||
consecutiveMidrollResponses: 0,
|
consecutiveMidrollResponses: 0,
|
||||||
consecutiveMidrollCooldown: 0,
|
consecutiveMidrollCooldown: 0,
|
||||||
|
deleted: false,
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
console.debug("[TTV LOL PRO] Received Usher response.");
|
console.error(
|
||||||
|
"[TTV LOL PRO] Received Usher response but failed to parse it."
|
||||||
|
);
|
||||||
}
|
}
|
||||||
// Send Video Weaver URLs to content script.
|
// Send Video Weaver URLs to content script.
|
||||||
const videoWeaverUrls = [...(assignedMap?.values() ?? [])];
|
const videoWeaverUrls = [...(assignedMap?.values() ?? [])];
|
||||||
@ -509,14 +546,11 @@ export function getFetch(pageState: PageState): typeof fetch {
|
|||||||
console.log("[TTV LOL PRO] Midroll ad detected.");
|
console.log("[TTV LOL PRO] Midroll ad detected.");
|
||||||
manifest.consecutiveMidrollResponses += 1;
|
manifest.consecutiveMidrollResponses += 1;
|
||||||
manifest.consecutiveMidrollCooldown = 15;
|
manifest.consecutiveMidrollCooldown = 15;
|
||||||
const isWhitelisted = isChannelWhitelisted(
|
await waitForStore(pageState);
|
||||||
manifest.channelName,
|
|
||||||
pageState
|
|
||||||
);
|
|
||||||
const shouldUpdateReplacementMap =
|
const shouldUpdateReplacementMap =
|
||||||
pageState.state?.optimizedProxiesEnabled === true &&
|
pageState.state?.optimizedProxiesEnabled === true &&
|
||||||
manifest.consecutiveMidrollResponses <= 2 && // Avoid infinite loop.
|
manifest.consecutiveMidrollResponses <= 2 && // Avoid infinite loop.
|
||||||
!isWhitelisted;
|
!videoWeaverUrlsToNotProxy.has(url);
|
||||||
if (shouldUpdateReplacementMap) {
|
if (shouldUpdateReplacementMap) {
|
||||||
const success = await updateVideoWeaverReplacementMap(
|
const success = await updateVideoWeaverReplacementMap(
|
||||||
pageState,
|
pageState,
|
||||||
@ -649,9 +683,10 @@ function isChannelWhitelisted(
|
|||||||
pageState: PageState
|
pageState: PageState
|
||||||
): boolean {
|
): boolean {
|
||||||
if (!channelName) return false;
|
if (!channelName) return false;
|
||||||
|
const channelNameLower = channelName.toLowerCase();
|
||||||
return (
|
return (
|
||||||
pageState.state?.whitelistedChannels.some(
|
pageState.state?.whitelistedChannels.some(
|
||||||
c => c.toLowerCase() === channelName.toLowerCase()
|
channel => channel.toLowerCase() === channelNameLower
|
||||||
) ?? false
|
) ?? false
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -661,9 +696,10 @@ function wasChannelSubscriber(
|
|||||||
pageState: PageState
|
pageState: PageState
|
||||||
): boolean {
|
): boolean {
|
||||||
if (!channelName) return false;
|
if (!channelName) return false;
|
||||||
|
const channelNameLower = channelName.toLowerCase();
|
||||||
return (
|
return (
|
||||||
pageState.state?.activeChannelSubscriptions.some(
|
pageState.state?.activeChannelSubscriptions.some(
|
||||||
c => c.toLowerCase() === channelName.toLowerCase()
|
channel => channel.toLowerCase() === channelNameLower
|
||||||
) ?? false
|
) ?? false
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -719,10 +755,6 @@ function cancelRequest(): never {
|
|||||||
throw new Error();
|
throw new Error();
|
||||||
}
|
}
|
||||||
|
|
||||||
async function sleep(ms: number): Promise<void> {
|
|
||||||
return new Promise(resolve => setTimeout(resolve, ms));
|
|
||||||
}
|
|
||||||
|
|
||||||
//#region Video Weaver URL replacement
|
//#region Video Weaver URL replacement
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -731,10 +763,10 @@ async function sleep(ms: number): Promise<void> {
|
|||||||
* @param anonymousMode
|
* @param anonymousMode
|
||||||
* @returns
|
* @returns
|
||||||
*/
|
*/
|
||||||
async function getDefaultPlaybackAccessTokenRequest(
|
function getDefaultPlaybackAccessTokenRequest(
|
||||||
channel: string | null = null,
|
channel: string | null = null,
|
||||||
anonymousMode: boolean = false
|
anonymousMode: boolean = false
|
||||||
): Promise<Request | null> {
|
): Request | null {
|
||||||
// We can use `location.href` because we're in the page script.
|
// We can use `location.href` because we're in the page script.
|
||||||
const channelName = channel ?? findChannelFromTwitchTvUrl(location.href);
|
const channelName = channel ?? findChannelFromTwitchTvUrl(location.href);
|
||||||
if (!channelName) return null;
|
if (!channelName) return null;
|
||||||
@ -790,7 +822,7 @@ async function fetchReplacementPlaybackAccessToken(
|
|||||||
): Promise<PlaybackAccessToken | null> {
|
): Promise<PlaybackAccessToken | null> {
|
||||||
// Not using the cached request because we'd need to check if integrity requests are proxied.
|
// Not using the cached request because we'd need to check if integrity requests are proxied.
|
||||||
try {
|
try {
|
||||||
let request = await getDefaultPlaybackAccessTokenRequest(
|
let request = getDefaultPlaybackAccessTokenRequest(
|
||||||
null,
|
null,
|
||||||
pageState.state?.anonymousMode === true
|
pageState.state?.anonymousMode === true
|
||||||
);
|
);
|
||||||
|
@ -39,6 +39,7 @@ const pageState: PageState = {
|
|||||||
sendMessageToWorkerScriptsAndWaitForResponse,
|
sendMessageToWorkerScriptsAndWaitForResponse,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const NATIVE_FETCH = window.fetch;
|
||||||
window.fetch = getFetch(pageState);
|
window.fetch = getFetch(pageState);
|
||||||
|
|
||||||
const NATIVE_WORKER = window.Worker;
|
const NATIVE_WORKER = window.Worker;
|
||||||
|
@ -32,9 +32,7 @@ async function sendMessageAndWaitForResponse(
|
|||||||
): Promise<any> {
|
): Promise<any> {
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
if (!recipient) {
|
if (!recipient) {
|
||||||
console.error("[TTV LOL PRO] Message recipient is undefined.");
|
return reject(new Error("Message recipient is undefined."));
|
||||||
resolve(undefined);
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const listener = (event: MessageEvent) => {
|
const listener = (event: MessageEvent) => {
|
||||||
|
@ -36,6 +36,7 @@ export interface UsherManifest {
|
|||||||
replacementMap: Map<string, string> | null; // Same as above, but with new URLs.
|
replacementMap: Map<string, string> | null; // Same as above, but with new URLs.
|
||||||
consecutiveMidrollResponses: number; // Used to avoid infinite loops.
|
consecutiveMidrollResponses: number; // Used to avoid infinite loops.
|
||||||
consecutiveMidrollCooldown: number; // Used to avoid infinite loops.
|
consecutiveMidrollCooldown: number; // Used to avoid infinite loops.
|
||||||
|
deleted: boolean; // Deletion flag for cleanup.
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface PlaybackAccessToken {
|
export interface PlaybackAccessToken {
|
||||||
|
@ -7,6 +7,7 @@ export default function getDefaultState() {
|
|||||||
adLog: [],
|
adLog: [],
|
||||||
adLogEnabled: true,
|
adLogEnabled: true,
|
||||||
adLogLastSent: 0,
|
adLogLastSent: 0,
|
||||||
|
allowOtherProxyProtocols: false,
|
||||||
anonymousMode: true,
|
anonymousMode: true,
|
||||||
chromiumProxyActive: false,
|
chromiumProxyActive: false,
|
||||||
dnsResponses: [],
|
dnsResponses: [],
|
||||||
|
@ -10,6 +10,7 @@ export interface State {
|
|||||||
adLog: AdLogEntry[];
|
adLog: AdLogEntry[];
|
||||||
adLogEnabled: boolean;
|
adLogEnabled: boolean;
|
||||||
adLogLastSent: number;
|
adLogLastSent: number;
|
||||||
|
allowOtherProxyProtocols: boolean;
|
||||||
anonymousMode: boolean;
|
anonymousMode: boolean;
|
||||||
chromiumProxyActive: boolean;
|
chromiumProxyActive: boolean;
|
||||||
dnsResponses: DnsResponse[];
|
dnsResponses: DnsResponse[];
|
||||||
|
@ -3,9 +3,11 @@ export type KeyOfType<T, V> = keyof {
|
|||||||
[P in keyof T as T[P] extends V ? P : never]: any;
|
[P in keyof T as T[P] extends V ? P : never]: any;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export type ProxyType = "direct" | "http" | "https" | "socks" | "socks4";
|
||||||
|
|
||||||
// From https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/proxy/ProxyInfo
|
// From https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/proxy/ProxyInfo
|
||||||
export interface ProxyInfo {
|
export interface ProxyInfo {
|
||||||
type: "direct" | "http" | "https" | "socks" | "socks4";
|
type: ProxyType;
|
||||||
host?: string;
|
host?: string;
|
||||||
port?: number;
|
port?: number;
|
||||||
username?: string;
|
username?: string;
|
||||||
@ -79,11 +81,10 @@ export const enum MessageType {
|
|||||||
EnableFullMode = "TLP_EnableFullMode",
|
EnableFullMode = "TLP_EnableFullMode",
|
||||||
EnableFullModeResponse = "TLP_EnableFullModeResponse",
|
EnableFullModeResponse = "TLP_EnableFullModeResponse",
|
||||||
DisableFullMode = "TLP_DisableFullMode",
|
DisableFullMode = "TLP_DisableFullMode",
|
||||||
ChannelSubStatusChange = "TLP_ChannelSubStatusChange",
|
|
||||||
ChannelSubStatusChangeResponse = "TLP_ChannelSubStatusChangeResponse",
|
|
||||||
UsherResponse = "TLP_UsherResponse",
|
UsherResponse = "TLP_UsherResponse",
|
||||||
NewPlaybackAccessToken = "TLP_NewPlaybackAccessToken",
|
NewPlaybackAccessToken = "TLP_NewPlaybackAccessToken",
|
||||||
NewPlaybackAccessTokenResponse = "TLP_NewPlaybackAccessTokenResponse",
|
NewPlaybackAccessTokenResponse = "TLP_NewPlaybackAccessTokenResponse",
|
||||||
|
ChannelSubStatusChange = "TLP_ChannelSubStatusChange",
|
||||||
MultipleAdBlockersInUse = "TLP_MultipleAdBlockersInUse",
|
MultipleAdBlockersInUse = "TLP_MultipleAdBlockersInUse",
|
||||||
ClearStats = "TLP_ClearStats",
|
ClearStats = "TLP_ClearStats",
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user