mirror of
https://github.com/bolucat/Archive.git
synced 2025-12-24 13:28:37 +08:00
Update On Fri Aug 1 20:44:22 CEST 2025
This commit is contained in:
1
.github/update.log
vendored
1
.github/update.log
vendored
@@ -1076,3 +1076,4 @@ Update On Mon Jul 28 20:43:06 CEST 2025
|
||||
Update On Tue Jul 29 20:43:03 CEST 2025
|
||||
Update On Wed Jul 30 20:44:03 CEST 2025
|
||||
Update On Thu Jul 31 20:43:42 CEST 2025
|
||||
Update On Fri Aug 1 20:44:14 CEST 2025
|
||||
|
||||
@@ -23,17 +23,16 @@ brook server -l :9999 -p hello
|
||||
- [iOS](https://apps.apple.com/us/app/brook-network-tool/id1216002642)
|
||||
- [Android](https://github.com/txthinking/brook/releases/latest/download/Brook.apk)
|
||||
- [macOS](https://apps.apple.com/us/app/brook-network-tool/id1216002642)
|
||||
- [About App Mode on macOS](https://www.txthinking.com/talks/articles/macos-app-mode-en.article)
|
||||
- [Windows](https://github.com/txthinking/brook/releases/latest/download/Brook.msix)
|
||||
- [How to install Brook on Windows](https://www.txthinking.com/talks/articles/msix-brook-en.article)
|
||||
- [Linux](https://github.com/txthinking/brook/releases/latest/download/Brook.bin)
|
||||
- [How to install Brook on Linux](https://www.txthinking.com/talks/articles/linux-app-brook-en.article)
|
||||
- [OpenWrt](https://www.txthinking.com/talks/articles/brook-openwrt-one-en.article)
|
||||
- [How to install Brook on OpenWrt](https://www.txthinking.com/talks/articles/brook-openwrt-en.article)
|
||||
|
||||
> You may want to use `brook link` to customize some parameters
|
||||
|
||||
- [About App Mode on macOS](https://www.txthinking.com/talks/articles/macos-app-mode-en.article)
|
||||
- [How to install Brook on Windows](https://www.txthinking.com/talks/articles/msix-brook-en.article)
|
||||
- [How to install Brook on Linux](https://www.txthinking.com/talks/articles/linux-app-brook-en.article)
|
||||
- [How to install Brook on OpenWrt](https://www.txthinking.com/talks/articles/brook-openwrt-en.article)
|
||||
|
||||
## Docs
|
||||
|
||||
https://www.txthinking.com/brook.html
|
||||
|
||||
@@ -53,7 +53,7 @@ func main() {
|
||||
df := func() {}
|
||||
app := cli.NewApp()
|
||||
app.Name = "Brook"
|
||||
app.Version = "20250202"
|
||||
app.Version = "20250808"
|
||||
app.Usage = "A cross-platform programmable network tool"
|
||||
app.Authors = []*cli.Author{
|
||||
{
|
||||
|
||||
@@ -177,7 +177,7 @@
|
||||
</div>
|
||||
</div>
|
||||
<div style="display: flex;justify-content:center;padding:15px;">
|
||||
<div style="color:grey">Made with <t-icon name="heart" style="color:red;"></t-icon> by <t-link href="https://www.txthinking.com" target="_blank">TxThinking</t-link></div>
|
||||
<t-link href="https://www.txthinking.com" target="_blank" style="color:grey">TxThinking</t-link>
|
||||
</div>
|
||||
<t-back-top shape="circle" container="#top" style="position: fixed" :offset="['24px', '80px']"></t-back-top>
|
||||
</div>
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"version": "20250202",
|
||||
"text": "Brook Store: Get Brook Server without deploying it yourself",
|
||||
"link": "https://store.brook.app/",
|
||||
"text_zh": "Brook Store: 无需自己部署即可获取 Brook Server",
|
||||
"link_zh": "https://store.brook.app/"
|
||||
"version": "20250808",
|
||||
"text": "",
|
||||
"link": "",
|
||||
"text_zh": "",
|
||||
"link_zh": ""
|
||||
}
|
||||
|
||||
@@ -41,6 +41,13 @@
|
||||
"author": "TxThinking",
|
||||
"author_url": "https://www.txthinking.com"
|
||||
},
|
||||
{
|
||||
"name": "Block some AD domains",
|
||||
"url": "https://raw.githubusercontent.com/txthinking/brook/master/programmable/modules/block_ad_domain.tengo",
|
||||
"kind": "module",
|
||||
"author": "TxThinking",
|
||||
"author_url": "https://www.txthinking.com"
|
||||
},
|
||||
{
|
||||
"name": "iOS 豆瓣 v7.66.0 去广告",
|
||||
"url": "https://raw.githubusercontent.com/txthinking/brook/master/programmable/modules/douban.tengo",
|
||||
@@ -50,8 +57,8 @@
|
||||
"author_url": "https://www.txthinking.com"
|
||||
},
|
||||
{
|
||||
"name": "Block some AD domains",
|
||||
"url": "https://raw.githubusercontent.com/txthinking/brook/master/programmable/modules/block_ad_domain.tengo",
|
||||
"name": "小红书定制 IP 归属地",
|
||||
"url": "https://raw.githubusercontent.com/txthinking/brook/master/programmable/modules/xiaohongshu.tengo",
|
||||
"kind": "module",
|
||||
"author": "TxThinking",
|
||||
"author_url": "https://www.txthinking.com"
|
||||
|
||||
20
brook/programmable/modules/xiaohongshu.tengo
Normal file
20
brook/programmable/modules/xiaohongshu.tengo
Normal file
@@ -0,0 +1,20 @@
|
||||
// 小红书定制 IP 归属地
|
||||
// Note: 需要通过 `brooklinks` 预先定一个 key 为 `beijing` 的 brook link
|
||||
modules = append(modules, {
|
||||
dnsquery: func(m) {
|
||||
text := import("text")
|
||||
l := [
|
||||
"fengkongcloud.com",
|
||||
"xhscdn.com",
|
||||
"xhscdn.net",
|
||||
"xiaohongshu.com"
|
||||
]
|
||||
for v in l {
|
||||
if m.domain == v || text.has_suffix(m.domain, "."+v) {
|
||||
return {brooklinkkey: "beijing"}
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
|
||||
@@ -30,7 +30,7 @@ require (
|
||||
github.com/metacubex/sing-shadowsocks v0.2.11
|
||||
github.com/metacubex/sing-shadowsocks2 v0.2.5
|
||||
github.com/metacubex/sing-shadowtls v0.0.0-20250503063515-5d9f966d17a2
|
||||
github.com/metacubex/sing-tun v0.4.7-0.20250721020617-8e7c37ed3d97
|
||||
github.com/metacubex/sing-tun v0.4.7-0.20250801130030-308b828865ae
|
||||
github.com/metacubex/sing-vmess v0.2.4-0.20250731011226-ea28d589924d
|
||||
github.com/metacubex/sing-wireguard v0.0.0-20250503063753-2dc62acc626f
|
||||
github.com/metacubex/smux v0.0.0-20250503055512-501391591dee
|
||||
|
||||
@@ -129,8 +129,8 @@ github.com/metacubex/sing-shadowsocks2 v0.2.5 h1:MnPn0hbcDkSJt6TlpI15XImHKK6IqaO
|
||||
github.com/metacubex/sing-shadowsocks2 v0.2.5/go.mod h1:Zyh+rAQRyevYfG/COCvDs1c/YMhGqCuknn7QrGmoQIw=
|
||||
github.com/metacubex/sing-shadowtls v0.0.0-20250503063515-5d9f966d17a2 h1:gXU+MYPm7Wme3/OAY2FFzVq9d9GxPHOqu5AQfg/ddhI=
|
||||
github.com/metacubex/sing-shadowtls v0.0.0-20250503063515-5d9f966d17a2/go.mod h1:mbfboaXauKJNIHJYxQRa+NJs4JU9NZfkA+I33dS2+9E=
|
||||
github.com/metacubex/sing-tun v0.4.7-0.20250721020617-8e7c37ed3d97 h1:YYpc60UZE2G0pUeHbRw9erDrUDZrPQy8QzWFqA3kHsk=
|
||||
github.com/metacubex/sing-tun v0.4.7-0.20250721020617-8e7c37ed3d97/go.mod h1:2YywXPWW8Z97kTH7RffOeykKzU+l0aiKlglWV1PAS64=
|
||||
github.com/metacubex/sing-tun v0.4.7-0.20250801130030-308b828865ae h1:hKYGuBaJBLqNmySrYrOGDXXsyxXNaR8omO96QDsRI2s=
|
||||
github.com/metacubex/sing-tun v0.4.7-0.20250801130030-308b828865ae/go.mod h1:2YywXPWW8Z97kTH7RffOeykKzU+l0aiKlglWV1PAS64=
|
||||
github.com/metacubex/sing-vmess v0.2.4-0.20250731011226-ea28d589924d h1:koSVAQiYqU/qtJ527e+wbsEPvTaM39HW75LSvh04IT0=
|
||||
github.com/metacubex/sing-vmess v0.2.4-0.20250731011226-ea28d589924d/go.mod h1:21R5R1u90uUvBQF0owoooEu96/SAYYD56nDrwm6nFaM=
|
||||
github.com/metacubex/sing-wireguard v0.0.0-20250503063753-2dc62acc626f h1:Sr/DYKYofKHKc4GF3qkRGNuj6XA6c0eqPgEDN+VAsYU=
|
||||
|
||||
4
clash-nyanpasu/backend/Cargo.lock
generated
4
clash-nyanpasu/backend/Cargo.lock
generated
@@ -8170,9 +8170,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "serde_json"
|
||||
version = "1.0.141"
|
||||
version = "1.0.142"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "30b9eff21ebe718216c6ec64e1d9ac57087aad11efc64e32002bce4a0d4c03d3"
|
||||
checksum = "030fedb782600dcbd6f02d479bf0d817ac3bb40d644745b769d6a96bc3afc5a7"
|
||||
dependencies = [
|
||||
"indexmap 2.10.0",
|
||||
"itoa",
|
||||
|
||||
@@ -2,8 +2,8 @@
|
||||
"manifest_version": 1,
|
||||
"latest": {
|
||||
"mihomo": "v1.19.12",
|
||||
"mihomo_alpha": "alpha-f04af73",
|
||||
"clash_rs": "v0.8.1",
|
||||
"mihomo_alpha": "alpha-e8fddd8",
|
||||
"clash_rs": "v0.8.2",
|
||||
"clash_premium": "2023-09-05-gdcc8d87",
|
||||
"clash_rs_alpha": "0.8.1-alpha+sha.3164865"
|
||||
},
|
||||
@@ -69,5 +69,5 @@
|
||||
"linux-armv7hf": "clash-armv7-unknown-linux-gnueabihf"
|
||||
}
|
||||
},
|
||||
"updated_at": "2025-07-30T22:23:15.357Z"
|
||||
"updated_at": "2025-07-31T22:21:34.711Z"
|
||||
}
|
||||
|
||||
@@ -100,7 +100,7 @@
|
||||
"stylelint": "16.23.0",
|
||||
"stylelint-config-html": "1.1.0",
|
||||
"stylelint-config-recess-order": "7.1.0",
|
||||
"stylelint-config-standard": "38.0.0",
|
||||
"stylelint-config-standard": "39.0.0",
|
||||
"stylelint-declaration-block-no-ignored-properties": "2.8.0",
|
||||
"stylelint-order": "7.0.0",
|
||||
"stylelint-scss": "6.12.1",
|
||||
@@ -111,7 +111,7 @@
|
||||
},
|
||||
"packageManager": "pnpm@10.13.1",
|
||||
"engines": {
|
||||
"node": "22.17.1"
|
||||
"node": "22.18.0"
|
||||
},
|
||||
"pnpm": {
|
||||
"overrides": {
|
||||
|
||||
32
clash-nyanpasu/pnpm-lock.yaml
generated
32
clash-nyanpasu/pnpm-lock.yaml
generated
@@ -149,8 +149,8 @@ importers:
|
||||
specifier: 7.1.0
|
||||
version: 7.1.0(stylelint-order@7.0.0(stylelint@16.23.0(typescript@5.8.3)))(stylelint@16.23.0(typescript@5.8.3))
|
||||
stylelint-config-standard:
|
||||
specifier: 38.0.0
|
||||
version: 38.0.0(stylelint@16.23.0(typescript@5.8.3))
|
||||
specifier: 39.0.0
|
||||
version: 39.0.0(stylelint@16.23.0(typescript@5.8.3))
|
||||
stylelint-declaration-block-no-ignored-properties:
|
||||
specifier: 2.8.0
|
||||
version: 2.8.0(stylelint@16.23.0(typescript@5.8.3))
|
||||
@@ -615,8 +615,8 @@ importers:
|
||||
specifier: 2.26.22
|
||||
version: 2.26.22
|
||||
undici:
|
||||
specifier: 7.12.0
|
||||
version: 7.12.0
|
||||
specifier: 7.13.0
|
||||
version: 7.13.0
|
||||
yargs:
|
||||
specifier: 18.0.0
|
||||
version: 18.0.0
|
||||
@@ -7836,17 +7836,17 @@ packages:
|
||||
stylelint: '>=16.18'
|
||||
stylelint-order: '>=7'
|
||||
|
||||
stylelint-config-recommended@16.0.0:
|
||||
resolution: {integrity: sha512-4RSmPjQegF34wNcK1e1O3Uz91HN8P1aFdFzio90wNK9mjgAI19u5vsU868cVZboKzCaa5XbpvtTzAAGQAxpcXA==}
|
||||
stylelint-config-recommended@17.0.0:
|
||||
resolution: {integrity: sha512-WaMSdEiPfZTSFVoYmJbxorJfA610O0tlYuU2aEwY33UQhSPgFbClrVJYWvy3jGJx+XW37O+LyNLiZOEXhKhJmA==}
|
||||
engines: {node: '>=18.12.0'}
|
||||
peerDependencies:
|
||||
stylelint: ^16.16.0
|
||||
stylelint: ^16.23.0
|
||||
|
||||
stylelint-config-standard@38.0.0:
|
||||
resolution: {integrity: sha512-uj3JIX+dpFseqd/DJx8Gy3PcRAJhlEZ2IrlFOc4LUxBX/PNMEQ198x7LCOE2Q5oT9Vw8nyc4CIL78xSqPr6iag==}
|
||||
stylelint-config-standard@39.0.0:
|
||||
resolution: {integrity: sha512-JabShWORb8Bmc1A47ZyJstran60P3yUdI1zWMpGYPeFiC6xzHXJMkpKAd8EjIhq3HPUplIWWMDJ/xu0AiPd+kA==}
|
||||
engines: {node: '>=18.12.0'}
|
||||
peerDependencies:
|
||||
stylelint: ^16.18.0
|
||||
stylelint: ^16.23.0
|
||||
|
||||
stylelint-declaration-block-no-ignored-properties@2.8.0:
|
||||
resolution: {integrity: sha512-Ws8Cav7Y+SPN0JsV407LrnNXWOrqGjxShf+37GBtnU/C58Syve9c0+I/xpLcFOosST3ternykn3Lp77f3ITnFw==}
|
||||
@@ -8153,8 +8153,8 @@ packages:
|
||||
resolution: {integrity: sha512-raqeBD6NQK4SkWhQzeYKd1KmIG6dllBOTt55Rmkt4HtI9mwdWtJljnrXjAFUBLTSN67HWrOIZ3EPF4kjUw80Bg==}
|
||||
engines: {node: '>=14.0'}
|
||||
|
||||
undici@7.12.0:
|
||||
resolution: {integrity: sha512-GrKEsc3ughskmGA9jevVlIOPMiiAHJ4OFUtaAH+NhfTUSiZ1wMPIQqQvAJUrJspFXJt3EBWgpAeoHEDVT1IBug==}
|
||||
undici@7.13.0:
|
||||
resolution: {integrity: sha512-l+zSMssRqrzDcb3fjMkjjLGmuiiK2pMIcV++mJaAc9vhjSGpvM7h43QgP+OAMb1GImHmbPyG2tBXeuyG5iY4gA==}
|
||||
engines: {node: '>=20.18.1'}
|
||||
|
||||
unicode-canonical-property-names-ecmascript@2.0.1:
|
||||
@@ -16585,14 +16585,14 @@ snapshots:
|
||||
stylelint: 16.23.0(typescript@5.8.3)
|
||||
stylelint-order: 7.0.0(stylelint@16.23.0(typescript@5.8.3))
|
||||
|
||||
stylelint-config-recommended@16.0.0(stylelint@16.23.0(typescript@5.8.3)):
|
||||
stylelint-config-recommended@17.0.0(stylelint@16.23.0(typescript@5.8.3)):
|
||||
dependencies:
|
||||
stylelint: 16.23.0(typescript@5.8.3)
|
||||
|
||||
stylelint-config-standard@38.0.0(stylelint@16.23.0(typescript@5.8.3)):
|
||||
stylelint-config-standard@39.0.0(stylelint@16.23.0(typescript@5.8.3)):
|
||||
dependencies:
|
||||
stylelint: 16.23.0(typescript@5.8.3)
|
||||
stylelint-config-recommended: 16.0.0(stylelint@16.23.0(typescript@5.8.3))
|
||||
stylelint-config-recommended: 17.0.0(stylelint@16.23.0(typescript@5.8.3))
|
||||
|
||||
stylelint-declaration-block-no-ignored-properties@2.8.0(stylelint@16.23.0(typescript@5.8.3)):
|
||||
dependencies:
|
||||
@@ -17001,7 +17001,7 @@ snapshots:
|
||||
dependencies:
|
||||
'@fastify/busboy': 2.1.1
|
||||
|
||||
undici@7.12.0: {}
|
||||
undici@7.13.0: {}
|
||||
|
||||
unicode-canonical-property-names-ecmascript@2.0.1: {}
|
||||
|
||||
|
||||
@@ -26,7 +26,7 @@
|
||||
"picocolors": "1.1.1",
|
||||
"tar": "7.4.3",
|
||||
"telegram": "2.26.22",
|
||||
"undici": "7.12.0",
|
||||
"undici": "7.13.0",
|
||||
"yargs": "18.0.0"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -55,12 +55,22 @@ export async function upload(
|
||||
|
||||
return true;
|
||||
},
|
||||
onError: function (error) {
|
||||
onError: function (error: Error | tus.DetailedError) {
|
||||
if (CURRENT_UPLOAD_LIST[filePath].interval) {
|
||||
clearInterval(CURRENT_UPLOAD_LIST[filePath].interval);
|
||||
}
|
||||
delete CURRENT_UPLOAD_LIST[filePath];
|
||||
reject(new Error(`Upload failed: ${error.message}`));
|
||||
|
||||
const message =
|
||||
error instanceof tus.DetailedError
|
||||
? error.originalResponse === null
|
||||
? "000 No connection"
|
||||
: error.originalResponse.getBody()
|
||||
: "Upload failed";
|
||||
|
||||
console.error(error);
|
||||
|
||||
reject(new Error(message));
|
||||
},
|
||||
onProgress: function (bytesUploaded) {
|
||||
const fileData = CURRENT_UPLOAD_LIST[filePath];
|
||||
|
||||
@@ -132,7 +132,6 @@ import {
|
||||
import { files as api } from "@/api";
|
||||
import ProgressBar from "@/components/ProgressBar.vue";
|
||||
import prettyBytes from "pretty-bytes";
|
||||
import { StatusError } from "@/api/utils.js";
|
||||
|
||||
const USAGE_DEFAULT = { used: "0 B", total: "0 B", usedPercentage: 0 };
|
||||
|
||||
@@ -181,13 +180,9 @@ export default {
|
||||
total: prettyBytes(usage.total, { binary: true }),
|
||||
usedPercentage: Math.round((usage.used / usage.total) * 100),
|
||||
};
|
||||
} catch (error) {
|
||||
if (error instanceof StatusError && error.is_canceled) {
|
||||
return;
|
||||
}
|
||||
this.$showError(error);
|
||||
} finally {
|
||||
return Object.assign(this.usage, usageStats);
|
||||
}
|
||||
return Object.assign(this.usage, usageStats);
|
||||
},
|
||||
toRoot() {
|
||||
this.$router.push({ path: "/files" });
|
||||
|
||||
@@ -26,6 +26,7 @@
|
||||
import {
|
||||
computed,
|
||||
defineAsyncComponent,
|
||||
inject,
|
||||
onBeforeUnmount,
|
||||
onMounted,
|
||||
onUnmounted,
|
||||
@@ -50,6 +51,8 @@ import { name } from "../utils/constants";
|
||||
const Editor = defineAsyncComponent(() => import("@/views/files/Editor.vue"));
|
||||
const Preview = defineAsyncComponent(() => import("@/views/files/Preview.vue"));
|
||||
|
||||
const $showError = inject<IToastError>("$showError")!;
|
||||
|
||||
const layoutStore = useLayoutStore();
|
||||
const fileStore = useFileStore();
|
||||
const uploadStore = useUploadStore();
|
||||
@@ -109,7 +112,7 @@ watch(reload, (newValue) => {
|
||||
newValue && fetchData();
|
||||
});
|
||||
watch(uploadError, (newValue) => {
|
||||
newValue && layoutStore.showError();
|
||||
newValue && $showError(newValue);
|
||||
});
|
||||
|
||||
// Define functions
|
||||
|
||||
@@ -609,6 +609,13 @@ choice
|
||||
bool "madvise"
|
||||
endchoice
|
||||
|
||||
config KERNEL_ARM64_CONTPTE
|
||||
bool "Compile the kernel with Contiguous PTE mappings for user memory"
|
||||
depends on KERNEL_ARM64
|
||||
depends on KERNEL_TRANSPARENT_HUGEPAGE
|
||||
depends on LINUX_6_12
|
||||
default y
|
||||
|
||||
config KERNEL_HUGETLBFS
|
||||
bool
|
||||
|
||||
|
||||
@@ -230,7 +230,7 @@ Below is an example to configure a proxy chain.
|
||||
```
|
||||
|
||||
1. In the `egress` -> `proxies` property, list the information of outbound proxy servers. The current version only supports socks5 outbound, so the value of `protocol` must be set to `SOCKS5_PROXY_PROTOCOL`. If the outbound proxy server requires socks5 username and password authentication, please fill in the `socks5Authentication` property. Otherwise, please remove the `socks5Authentication` property.
|
||||
2. In the `egress` -> `rules` property, list outbound rules. `proxyNames` needs to point to proxies that exist in `egress` -> `proxies` property.
|
||||
2. In the `egress` -> `rules` property, list outbound rules. Outbound actions include `DIRECT`, `PROXY` and `REJECT`. `proxyNames` must be set if `PROXY` action is used. `proxyNames` needs to point to proxies that exist in `egress` -> `proxies` property.
|
||||
|
||||
If you want to turn off the outbound proxy feature, simply set the `egress` property to an empty value `{}`.
|
||||
|
||||
|
||||
@@ -230,7 +230,7 @@ mieru 客户端 -> GFW -> mita 服务器 -> cloudflare 代理客户端 -> cloudf
|
||||
```
|
||||
|
||||
1. 在 `egress` -> `proxies` 属性中列举出站代理服务器的信息。当前版本只支持 socks5 出站,因此 `protocol` 的值必须设定为 `SOCKS5_PROXY_PROTOCOL`。如果出站代理服务器需要 socks5 用户名和密码验证,请填写 `socks5Authentication` 属性。否则,请删除 `socks5Authentication` 属性。
|
||||
2. 在 `egress` -> `rules` 属性中列举出站规则。`proxyNames` 需要指向 `egress` -> `proxies` 属性中存在的代理。
|
||||
2. 在 `egress` -> `rules` 属性中列举出站规则。出站行为包括 `DIRECT`,`PROXY` 和 `REJECT`。其中 `PROXY` 行为必须指定 `proxyNames`。`proxyNames` 需要指向 `egress` -> `proxies` 属性中存在的代理。
|
||||
|
||||
如果想要关闭出站代理功能,将 `egress` 属性设置为空 `{}` 即可。
|
||||
|
||||
|
||||
@@ -30,7 +30,7 @@ require (
|
||||
github.com/metacubex/sing-shadowsocks v0.2.11
|
||||
github.com/metacubex/sing-shadowsocks2 v0.2.5
|
||||
github.com/metacubex/sing-shadowtls v0.0.0-20250503063515-5d9f966d17a2
|
||||
github.com/metacubex/sing-tun v0.4.7-0.20250721020617-8e7c37ed3d97
|
||||
github.com/metacubex/sing-tun v0.4.7-0.20250801130030-308b828865ae
|
||||
github.com/metacubex/sing-vmess v0.2.4-0.20250731011226-ea28d589924d
|
||||
github.com/metacubex/sing-wireguard v0.0.0-20250503063753-2dc62acc626f
|
||||
github.com/metacubex/smux v0.0.0-20250503055512-501391591dee
|
||||
|
||||
@@ -129,8 +129,8 @@ github.com/metacubex/sing-shadowsocks2 v0.2.5 h1:MnPn0hbcDkSJt6TlpI15XImHKK6IqaO
|
||||
github.com/metacubex/sing-shadowsocks2 v0.2.5/go.mod h1:Zyh+rAQRyevYfG/COCvDs1c/YMhGqCuknn7QrGmoQIw=
|
||||
github.com/metacubex/sing-shadowtls v0.0.0-20250503063515-5d9f966d17a2 h1:gXU+MYPm7Wme3/OAY2FFzVq9d9GxPHOqu5AQfg/ddhI=
|
||||
github.com/metacubex/sing-shadowtls v0.0.0-20250503063515-5d9f966d17a2/go.mod h1:mbfboaXauKJNIHJYxQRa+NJs4JU9NZfkA+I33dS2+9E=
|
||||
github.com/metacubex/sing-tun v0.4.7-0.20250721020617-8e7c37ed3d97 h1:YYpc60UZE2G0pUeHbRw9erDrUDZrPQy8QzWFqA3kHsk=
|
||||
github.com/metacubex/sing-tun v0.4.7-0.20250721020617-8e7c37ed3d97/go.mod h1:2YywXPWW8Z97kTH7RffOeykKzU+l0aiKlglWV1PAS64=
|
||||
github.com/metacubex/sing-tun v0.4.7-0.20250801130030-308b828865ae h1:hKYGuBaJBLqNmySrYrOGDXXsyxXNaR8omO96QDsRI2s=
|
||||
github.com/metacubex/sing-tun v0.4.7-0.20250801130030-308b828865ae/go.mod h1:2YywXPWW8Z97kTH7RffOeykKzU+l0aiKlglWV1PAS64=
|
||||
github.com/metacubex/sing-vmess v0.2.4-0.20250731011226-ea28d589924d h1:koSVAQiYqU/qtJ527e+wbsEPvTaM39HW75LSvh04IT0=
|
||||
github.com/metacubex/sing-vmess v0.2.4-0.20250731011226-ea28d589924d/go.mod h1:21R5R1u90uUvBQF0owoooEu96/SAYYD56nDrwm6nFaM=
|
||||
github.com/metacubex/sing-wireguard v0.0.0-20250503063753-2dc62acc626f h1:Sr/DYKYofKHKc4GF3qkRGNuj6XA6c0eqPgEDN+VAsYU=
|
||||
|
||||
@@ -8,12 +8,12 @@
|
||||
include $(TOPDIR)/rules.mk
|
||||
|
||||
PKG_NAME:=ddns-go
|
||||
PKG_VERSION:=6.12.0
|
||||
PKG_VERSION:=6.12.1
|
||||
PKG_RELEASE:=1
|
||||
|
||||
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
|
||||
PKG_SOURCE_URL:=https://codeload.github.com/jeessy2/ddns-go/tar.gz/v$(PKG_VERSION)?
|
||||
PKG_HASH:=59f5a705f08f539c011e12c01b4e82791130bfb4ccfb332f2b6545945fa70e38
|
||||
PKG_HASH:=8e6cf10808f5e89f6527f42f37e55c275f4ae17738f6836c8e9cb5e4318fff43
|
||||
|
||||
PKG_LICENSE:=MIT
|
||||
PKG_LICENSE_FILES:=LICENSE
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
include $(TOPDIR)/rules.mk
|
||||
|
||||
PKG_NAME:=luci-app-amlogic
|
||||
PKG_VERSION:=3.1.260
|
||||
PKG_VERSION:=3.1.261
|
||||
PKG_RELEASE:=1
|
||||
|
||||
PKG_LICENSE:=GPL-2.0 License
|
||||
|
||||
@@ -195,7 +195,11 @@ else
|
||||
# 6. MAINLINE_UBOOT
|
||||
# 7. ANDROID_UBOOT
|
||||
AMLOGIC_SOC="$(echo "${ret}" | awk -F ':' '{print $3}')"
|
||||
FDTFILE="$(echo "${ret}" | awk -F ':' '{print $4}')"
|
||||
FDTFILE="$(
|
||||
grep -oE 'meson[^[:space:]]*\.dtb' /boot/extlinux/extlinux.conf 2>/dev/null ||
|
||||
grep -oE 'meson[^[:space:]]*\.dtb' /boot/uEnv.txt 2>/dev/null ||
|
||||
echo "${ret}" | awk -F':' '{print $4}'
|
||||
)"
|
||||
UBOOT_OVERLOAD="$(echo "${ret}" | awk -F ':' '{print $5}')"
|
||||
MAINLINE_UBOOT="$(echo "${ret}" | awk -F ':' '{print $6}')"
|
||||
ANDROID_UBOOT="$(echo "${ret}" | awk -F ':' '{print $7}')"
|
||||
|
||||
@@ -21,7 +21,7 @@ env:
|
||||
jobs:
|
||||
job_check:
|
||||
name: Check Version
|
||||
runs-on: ubuntu-22.04
|
||||
runs-on: ubuntu-latest
|
||||
outputs:
|
||||
passwall_version: ${{ steps.check_version.outputs.latest_version }}
|
||||
has_update: ${{ steps.check_version.outputs.has_update }}
|
||||
@@ -74,7 +74,7 @@ jobs:
|
||||
name: Build passwall [Luci ${{ matrix.luci_ver }}]
|
||||
needs: job_check
|
||||
if: needs.job_check.outputs.has_update == 'true'
|
||||
runs-on: ubuntu-22.04
|
||||
runs-on: ubuntu-latest
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
@@ -89,50 +89,58 @@ jobs:
|
||||
steps:
|
||||
- name: Install packages
|
||||
run: |
|
||||
sudo -E rm -rf /usr/share/dotnet /etc/mysql /etc/php /etc/apt/sources.list.d /usr/local/lib/android
|
||||
sudo -E rm -rf /usr/share/dotnet /etc/mysql /etc/php /usr/local/lib/android
|
||||
echo "Install packages"
|
||||
sudo -E apt-get -qq update
|
||||
sudo -E apt-get -qq install build-essential clang flex bison g++ gawk gcc-multilib g++-multilib gettext git libncurses-dev libssl-dev python3-distutils python3-setuptools rsync swig unzip zlib1g-dev file wget
|
||||
sudo -E apt-get -qq install ack antlr3 asciidoc autoconf automake autopoint binutils bison build-essential \
|
||||
bzip2 ccache clang cmake cpio curl device-tree-compiler ecj fastjar flex gawk gettext gcc-multilib \
|
||||
g++-multilib git gnutls-dev gperf haveged help2man intltool lib32gcc-s1 libc6-dev-i386 libelf-dev \
|
||||
libglib2.0-dev libgmp3-dev libltdl-dev libmpc-dev libmpfr-dev libncurses-dev libpython3-dev \
|
||||
libreadline-dev libssl-dev libtool libyaml-dev libz-dev lld llvm lrzsz mkisofs msmtp nano \
|
||||
ninja-build p7zip p7zip-full patch pkgconf python3 python3-pip python3-ply python3-docutils \
|
||||
python3-pyelftools qemu-utils re2c rsync scons squashfs-tools subversion swig texinfo uglifyjs \
|
||||
upx-ucl unzip vim wget xmlto xxd zlib1g-dev zstd
|
||||
sudo -E apt-get -qq autoremove --purge
|
||||
sudo -E apt-get -qq clean
|
||||
|
||||
- name: Cache openwrt SDK
|
||||
id: cache-sdk
|
||||
uses: actions/cache@v4
|
||||
with:
|
||||
path: sdk
|
||||
key: openwrt-luci-${{ matrix.luci_ver }}-x86_64
|
||||
|
||||
- name: Initialization environment
|
||||
if: steps.cache-sdk.outputs.cache-hit != 'true'
|
||||
run: |
|
||||
wget ${{ matrix.sdk_url }}
|
||||
file_name=$(echo ${{ matrix.sdk_url }} | awk -F/ '{print $NF}')
|
||||
mkdir sdk && tar --zstd -x -f $file_name -C ./sdk --strip-components=1
|
||||
mkdir sdk
|
||||
if [[ $file_name == *.tar.xz ]]; then
|
||||
tar -xJf $file_name -C ./sdk --strip-components=1
|
||||
elif [[ $file_name == *.tar.zst ]]; then
|
||||
tar --zstd -x -f $file_name -C ./sdk --strip-components=1
|
||||
else
|
||||
echo "Unsupported file format: $file_name"
|
||||
exit 1
|
||||
fi
|
||||
cd sdk
|
||||
echo "src-git base https://github.com/openwrt/openwrt.git;openwrt-${{ matrix.sdk_ver }}" > feeds.conf
|
||||
echo "src-git packages https://github.com/openwrt/packages.git;openwrt-${{ matrix.sdk_ver }}" >> feeds.conf
|
||||
echo "src-git luci https://github.com/openwrt/luci.git;openwrt-${{ matrix.luci_ver }}" >> feeds.conf
|
||||
echo "src-git routing https://github.com/openwrt/routing.git;openwrt-${{ matrix.sdk_ver }}" >> feeds.conf
|
||||
echo "src-git passwall_packages https://github.com/${{ env.packages }}.git;main" >> feeds.conf
|
||||
echo "src-git passwall https://github.com/${{ env.passwall }}.git;${{ github.ref_name }}" >> feeds.conf
|
||||
|
||||
cat > feeds.conf.default << EOF
|
||||
src-git passwall_packages https://github.com/xiaorouji/openwrt-passwall-packages.git;main
|
||||
src-git passwall https://github.com/${{ env.passwall }}.git;${{ github.ref_name }}
|
||||
src-git base https://github.com/openwrt/openwrt.git;openwrt-${{ matrix.sdk_ver }}
|
||||
src-git packages https://github.com/openwrt/packages.git;openwrt-${{ matrix.sdk_ver }}
|
||||
src-git luci https://github.com/openwrt/luci.git;openwrt-${{ matrix.luci_ver }}
|
||||
src-git routing https://github.com/openwrt/routing.git;openwrt-${{ matrix.sdk_ver }}
|
||||
src-git telephony https://github.com/openwrt/telephony.git;openwrt-${{ matrix.sdk_ver }}
|
||||
EOF
|
||||
|
||||
./scripts/feeds update -a
|
||||
./scripts/feeds install -a
|
||||
|
||||
#--------------------------------------begin_patches------------------------------------------
|
||||
echo "Start applying the patch"
|
||||
|
||||
echo "update golang version"
|
||||
rm -rf feeds/packages/lang/golang
|
||||
git clone https://github.com/sbwml/packages_lang_golang -b 24.x feeds/packages/lang/golang
|
||||
|
||||
./scripts/feeds update -a
|
||||
echo "CONFIG_PACKAGE_luci-app-passwall=m" > .config
|
||||
./scripts/feeds install -d n luci-app-passwall
|
||||
make package/luci-app-passwall/download -j8
|
||||
|
||||
- name: Update passwall feeds
|
||||
if: steps.cache-sdk.outputs.cache-hit == 'true'
|
||||
run: |
|
||||
cd sdk
|
||||
sed -i '6s/main/${{ github.ref_name }}/' feeds.conf
|
||||
./scripts/feeds update passwall_packages
|
||||
./scripts/feeds update passwall
|
||||
./scripts/feeds install luci-app-passwall
|
||||
echo "Patch application completed"
|
||||
#--------------------------------------end_patches--------------------------------------------
|
||||
|
||||
- name: Compile passwall
|
||||
id: compile
|
||||
@@ -170,7 +178,7 @@ jobs:
|
||||
job_auto_compile:
|
||||
if: ${{ needs.job_check.outputs.has_update == 'true' && needs.job_check.outputs.prerelease == 'false' }}
|
||||
needs: job_check
|
||||
runs-on: ubuntu-22.04
|
||||
runs-on: ubuntu-latest
|
||||
name: build (${{ matrix.platform }})
|
||||
strategy:
|
||||
fail-fast: false
|
||||
@@ -251,10 +259,17 @@ jobs:
|
||||
steps:
|
||||
- name: Initialization ${{ matrix.platform }} compile environment
|
||||
run: |
|
||||
sudo -E rm -rf /usr/share/dotnet /etc/mysql /etc/php /etc/apt/sources.list.d /usr/local/lib/android
|
||||
echo "install packages!!!!!!"
|
||||
sudo -E rm -rf /usr/share/dotnet /etc/mysql /etc/php /usr/local/lib/android
|
||||
echo "Install packages"
|
||||
sudo -E apt-get -qq update
|
||||
sudo -E apt-get -qq install build-essential clang flex bison g++ gawk gcc-multilib g++-multilib gettext git libncurses-dev libssl-dev python3-distutils python3-setuptools rsync swig unzip zlib1g-dev file wget
|
||||
sudo -E apt-get -qq install ack antlr3 asciidoc autoconf automake autopoint binutils bison build-essential \
|
||||
bzip2 ccache clang cmake cpio curl device-tree-compiler ecj fastjar flex gawk gettext gcc-multilib \
|
||||
g++-multilib git gnutls-dev gperf haveged help2man intltool lib32gcc-s1 libc6-dev-i386 libelf-dev \
|
||||
libglib2.0-dev libgmp3-dev libltdl-dev libmpc-dev libmpfr-dev libncurses-dev libpython3-dev \
|
||||
libreadline-dev libssl-dev libtool libyaml-dev libz-dev lld llvm lrzsz mkisofs msmtp nano \
|
||||
ninja-build p7zip p7zip-full patch pkgconf python3 python3-pip python3-ply python3-docutils \
|
||||
python3-pyelftools qemu-utils re2c rsync scons squashfs-tools subversion swig texinfo uglifyjs \
|
||||
upx-ucl unzip vim wget xmlto xxd zlib1g-dev zstd
|
||||
sudo -E apt-get -qq autoremove --purge
|
||||
sudo -E apt-get -qq clean
|
||||
|
||||
@@ -262,7 +277,15 @@ jobs:
|
||||
run: |
|
||||
wget ${{ matrix.url_sdk }}
|
||||
file_name=$(echo ${{matrix.url_sdk}} | awk -F/ '{print $NF}')
|
||||
mkdir sdk && tar --zstd -x -f $file_name -C ./sdk --strip-components=1
|
||||
mkdir sdk
|
||||
if [[ $file_name == *.tar.xz ]]; then
|
||||
tar -xJf $file_name -C ./sdk --strip-components=1
|
||||
elif [[ $file_name == *.tar.zst ]]; then
|
||||
tar --zstd -x -f $file_name -C ./sdk --strip-components=1
|
||||
else
|
||||
echo "Unsupported file format: $file_name"
|
||||
exit 1
|
||||
fi
|
||||
cd sdk
|
||||
|
||||
- name: SSH connection to Actions
|
||||
@@ -272,19 +295,35 @@ jobs:
|
||||
- name: ${{ matrix.platform }} feeds configuration packages
|
||||
run: |
|
||||
cd sdk
|
||||
echo "src-git base https://github.com/openwrt/openwrt.git;openwrt-${{ matrix.sdk_ver }}" > feeds.conf
|
||||
echo "src-git packages https://github.com/openwrt/packages.git;openwrt-${{ matrix.sdk_ver }}" >> feeds.conf
|
||||
echo "src-git luci https://github.com/openwrt/luci.git;openwrt-${{ matrix.sdk_ver }}" >> feeds.conf
|
||||
echo "src-git routing https://github.com/openwrt/routing.git;openwrt-${{ matrix.sdk_ver }}" >> feeds.conf
|
||||
echo "src-git passwall_packages https://github.com/${{ env.packages }}.git;main" >> feeds.conf
|
||||
echo "src-git passwall https://github.com/${{ env.passwall }}.git;main" >> feeds.conf
|
||||
cat > feeds.conf.default << EOF
|
||||
src-git passwall_packages https://github.com/xiaorouji/openwrt-passwall-packages.git;main
|
||||
src-git passwall https://github.com/${{ env.passwall }}.git;${{ github.ref_name }}
|
||||
src-git base https://github.com/openwrt/openwrt.git;openwrt-${{ matrix.sdk_ver }}
|
||||
src-git packages https://github.com/openwrt/packages.git;openwrt-${{ matrix.sdk_ver }}
|
||||
src-git luci https://github.com/openwrt/luci.git;openwrt-${{ matrix.sdk_ver }}
|
||||
src-git routing https://github.com/openwrt/routing.git;openwrt-${{ matrix.sdk_ver }}
|
||||
src-git telephony https://github.com/openwrt/telephony.git;openwrt-${{ matrix.sdk_ver }}
|
||||
EOF
|
||||
|
||||
|
||||
./scripts/feeds update -a
|
||||
./scripts/feeds install -a -f -p passwall_packages
|
||||
./scripts/feeds install luci-app-passwall
|
||||
./scripts/feeds install -a
|
||||
|
||||
#--------------------------------------begin_patches------------------------------------------
|
||||
echo "Start applying the patch"
|
||||
|
||||
|
||||
echo "update golang version"
|
||||
rm -rf feeds/packages/lang/golang
|
||||
git clone https://github.com/sbwml/packages_lang_golang -b 25.x feeds/packages/lang/golang
|
||||
git clone https://github.com/sbwml/packages_lang_golang -b 24.x feeds/packages/lang/golang
|
||||
|
||||
echo "fixed rust host build error"
|
||||
sed -i 's/--set=llvm\.download-ci-llvm=false/--set=llvm.download-ci-llvm=true/' feeds/packages/lang/rust/Makefile
|
||||
grep -q -- '--ci false \\' feeds/packages/lang/rust/Makefile || sed -i '/x\.py \\/a \ --ci false \\' feeds/packages/lang/rust/Makefile
|
||||
|
||||
|
||||
echo "Patch application completed"
|
||||
#--------------------------------------end_patches--------------------------------------------
|
||||
|
||||
echo "CONFIG_ALL_NONSHARED=n" > .config
|
||||
echo "CONFIG_ALL_KMODS=n" >> .config
|
||||
|
||||
@@ -1,9 +1,6 @@
|
||||
## :mega:注意
|
||||
由于 Sing-box 在 1.12.0 版本中移除 Geo 只保留规则集([详情](https://sing-box.sagernet.org/zh/deprecated/#geoip)),Passwall 为适应这一变更,同时兼容 Xray 和 Sing-box 的分流方式,从 25.3.9 版起,Sing-box 分流将依赖 Geoview 从 Geofile 生成规则集。**未安装 Geoview 将无法使用 Sing-box 分流**。
|
||||
|
||||
## 📌另外:
|
||||
由于 Geoview v0.1.9 及之前版本在转换规则时的一些问题,**请务必将 Geoview 更新到 v0.1.10 版**。
|
||||
|
||||
## 📌如何能编译到最新代码?
|
||||
|
||||
在 `./scripts/feeds install -a` 操作完成后,执行以下命令:
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
include $(TOPDIR)/rules.mk
|
||||
|
||||
PKG_NAME:=luci-app-passwall
|
||||
PKG_VERSION:=25.7.15
|
||||
PKG_VERSION:=25.8.1
|
||||
PKG_RELEASE:=1
|
||||
|
||||
PKG_CONFIG_DEPENDS:= \
|
||||
|
||||
@@ -20,7 +20,7 @@ env:
|
||||
jobs:
|
||||
job_check:
|
||||
name: Check Version
|
||||
runs-on: ubuntu-22.04
|
||||
runs-on: ubuntu-latest
|
||||
outputs:
|
||||
passwall2_version: ${{ steps.check_version.outputs.latest_version }}
|
||||
has_update: ${{ steps.check_version.outputs.has_update }}
|
||||
@@ -73,7 +73,7 @@ jobs:
|
||||
name: Build passwall2 [Luci ${{ matrix.luci_ver }}]
|
||||
needs: job_check
|
||||
if: needs.job_check.outputs.has_update == 'true'
|
||||
runs-on: ubuntu-22.04
|
||||
runs-on: ubuntu-latest
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
@@ -88,50 +88,58 @@ jobs:
|
||||
steps:
|
||||
- name: Install packages
|
||||
run: |
|
||||
sudo -E rm -rf /usr/share/dotnet /etc/mysql /etc/php /etc/apt/sources.list.d /usr/local/lib/android
|
||||
sudo -E rm -rf /usr/share/dotnet /etc/mysql /etc/php /usr/local/lib/android
|
||||
echo "Install packages"
|
||||
sudo -E apt-get -qq update
|
||||
sudo -E apt-get -qq install build-essential clang flex bison g++ gawk gcc-multilib g++-multilib gettext git libncurses-dev libssl-dev python3-distutils python3-setuptools rsync swig unzip zlib1g-dev file wget
|
||||
sudo -E apt-get -qq install ack antlr3 asciidoc autoconf automake autopoint binutils bison build-essential \
|
||||
bzip2 ccache clang cmake cpio curl device-tree-compiler ecj fastjar flex gawk gettext gcc-multilib \
|
||||
g++-multilib git gnutls-dev gperf haveged help2man intltool lib32gcc-s1 libc6-dev-i386 libelf-dev \
|
||||
libglib2.0-dev libgmp3-dev libltdl-dev libmpc-dev libmpfr-dev libncurses-dev libpython3-dev \
|
||||
libreadline-dev libssl-dev libtool libyaml-dev libz-dev lld llvm lrzsz mkisofs msmtp nano \
|
||||
ninja-build p7zip p7zip-full patch pkgconf python3 python3-pip python3-ply python3-docutils \
|
||||
python3-pyelftools qemu-utils re2c rsync scons squashfs-tools subversion swig texinfo uglifyjs \
|
||||
upx-ucl unzip vim wget xmlto xxd zlib1g-dev zstd
|
||||
sudo -E apt-get -qq autoremove --purge
|
||||
sudo -E apt-get -qq clean
|
||||
|
||||
- name: Cache openwrt SDK
|
||||
id: cache-sdk
|
||||
uses: actions/cache@v4
|
||||
with:
|
||||
path: sdk
|
||||
key: openwrt-luci-${{ matrix.luci_ver }}-x86_64
|
||||
|
||||
- name: Initialization environment
|
||||
if: steps.cache-sdk.outputs.cache-hit != 'true'
|
||||
run: |
|
||||
wget ${{ matrix.sdk_url }}
|
||||
file_name=$(echo ${{ matrix.sdk_url }} | awk -F/ '{print $NF}')
|
||||
mkdir sdk && tar --zstd -x -f $file_name -C ./sdk --strip-components=1
|
||||
mkdir sdk
|
||||
if [[ $file_name == *.tar.xz ]]; then
|
||||
tar -xJf $file_name -C ./sdk --strip-components=1
|
||||
elif [[ $file_name == *.tar.zst ]]; then
|
||||
tar --zstd -x -f $file_name -C ./sdk --strip-components=1
|
||||
else
|
||||
echo "Unsupported file format: $file_name"
|
||||
exit 1
|
||||
fi
|
||||
cd sdk
|
||||
echo "src-git base https://github.com/openwrt/openwrt.git;openwrt-${{ matrix.sdk_ver }}" > feeds.conf
|
||||
echo "src-git packages https://github.com/openwrt/packages.git;openwrt-${{ matrix.sdk_ver }}" >> feeds.conf
|
||||
echo "src-git luci https://github.com/openwrt/luci.git;openwrt-${{ matrix.luci_ver }}" >> feeds.conf
|
||||
echo "src-git routing https://git.openwrt.org/feed/routing.git;openwrt-${{ matrix.sdk_ver }}" >> feeds.conf
|
||||
echo "src-git passwall_packages https://github.com/${{ env.packages }}.git;main" >> feeds.conf
|
||||
echo "src-git passwall2 https://github.com/${{ env.passwall2 }}.git;${{ github.ref_name }}" >> feeds.conf
|
||||
|
||||
cat > feeds.conf.default << EOF
|
||||
src-git passwall_packages https://github.com/${{ env.packages }}.git;main
|
||||
src-git passwall2 https://github.com/${{ env.passwall2 }}.git;${{ github.ref_name }}
|
||||
src-git base https://github.com/openwrt/openwrt.git;openwrt-${{ matrix.sdk_ver }}
|
||||
src-git packages https://github.com/openwrt/packages.git;openwrt-${{ matrix.sdk_ver }}
|
||||
src-git luci https://github.com/openwrt/luci.git;openwrt-${{ matrix.luci_ver }}
|
||||
src-git routing https://github.com/openwrt/routing.git;openwrt-${{ matrix.sdk_ver }}
|
||||
src-git telephony https://github.com/openwrt/telephony.git;openwrt-${{ matrix.sdk_ver }}
|
||||
EOF
|
||||
|
||||
./scripts/feeds update -a
|
||||
./scripts/feeds install -a
|
||||
|
||||
#--------------------------------------begin_patches------------------------------------------
|
||||
echo "Start applying the patch"
|
||||
|
||||
echo "update golang version"
|
||||
rm -rf feeds/packages/lang/golang
|
||||
git clone https://github.com/sbwml/packages_lang_golang -b 24.x feeds/packages/lang/golang
|
||||
|
||||
./scripts/feeds update -a
|
||||
echo "CONFIG_PACKAGE_luci-app-passwall2=m" > .config
|
||||
./scripts/feeds install -d n luci-app-passwall2
|
||||
make package/luci-app-passwall2/download -j$(nproc)
|
||||
|
||||
- name: Update passwall2 feeds
|
||||
if: steps.cache-sdk.outputs.cache-hit == 'true'
|
||||
run: |
|
||||
cd sdk
|
||||
sed -i '6s/main/${{ github.ref_name }}/' feeds.conf
|
||||
./scripts/feeds update passwall_packages
|
||||
./scripts/feeds update passwall2
|
||||
./scripts/feeds install luci-app-passwall2
|
||||
echo "Patch application completed"
|
||||
#--------------------------------------end_patches--------------------------------------------
|
||||
|
||||
- name: Compile passwall2
|
||||
id: compile
|
||||
@@ -169,7 +177,7 @@ jobs:
|
||||
job_auto_compile:
|
||||
if: ${{ needs.job_check.outputs.has_update == 'true' && needs.job_check.outputs.prerelease == 'false' }}
|
||||
needs: job_check
|
||||
runs-on: ubuntu-22.04
|
||||
runs-on: ubuntu-latest
|
||||
name: build (${{ matrix.platform }})
|
||||
strategy:
|
||||
fail-fast: false
|
||||
@@ -250,10 +258,17 @@ jobs:
|
||||
steps:
|
||||
- name: Initialization ${{ matrix.platform }} compile environment
|
||||
run: |
|
||||
sudo -E rm -rf /usr/share/dotnet /etc/mysql /etc/php /etc/apt/sources.list.d /usr/local/lib/android
|
||||
echo "install packages!!!!!!"
|
||||
sudo -E rm -rf /usr/share/dotnet /etc/mysql /etc/php /usr/local/lib/android
|
||||
echo "Install packages"
|
||||
sudo -E apt-get -qq update
|
||||
sudo -E apt-get -qq install build-essential clang flex bison g++ gawk gcc-multilib g++-multilib gettext git libncurses-dev libssl-dev python3-distutils python3-setuptools rsync swig unzip zlib1g-dev file wget
|
||||
sudo -E apt-get -qq install ack antlr3 asciidoc autoconf automake autopoint binutils bison build-essential \
|
||||
bzip2 ccache clang cmake cpio curl device-tree-compiler ecj fastjar flex gawk gettext gcc-multilib \
|
||||
g++-multilib git gnutls-dev gperf haveged help2man intltool lib32gcc-s1 libc6-dev-i386 libelf-dev \
|
||||
libglib2.0-dev libgmp3-dev libltdl-dev libmpc-dev libmpfr-dev libncurses-dev libpython3-dev \
|
||||
libreadline-dev libssl-dev libtool libyaml-dev libz-dev lld llvm lrzsz mkisofs msmtp nano \
|
||||
ninja-build p7zip p7zip-full patch pkgconf python3 python3-pip python3-ply python3-docutils \
|
||||
python3-pyelftools qemu-utils re2c rsync scons squashfs-tools subversion swig texinfo uglifyjs \
|
||||
upx-ucl unzip vim wget xmlto xxd zlib1g-dev zstd
|
||||
sudo -E apt-get -qq autoremove --purge
|
||||
sudo -E apt-get -qq clean
|
||||
|
||||
@@ -261,7 +276,15 @@ jobs:
|
||||
run: |
|
||||
wget ${{ matrix.url_sdk }}
|
||||
file_name=$(echo ${{matrix.url_sdk}} | awk -F/ '{print $NF}')
|
||||
mkdir sdk && tar --zstd -x -f $file_name -C ./sdk --strip-components=1
|
||||
mkdir sdk
|
||||
if [[ $file_name == *.tar.xz ]]; then
|
||||
tar -xJf $file_name -C ./sdk --strip-components=1
|
||||
elif [[ $file_name == *.tar.zst ]]; then
|
||||
tar --zstd -x -f $file_name -C ./sdk --strip-components=1
|
||||
else
|
||||
echo "Unsupported file format: $file_name"
|
||||
exit 1
|
||||
fi
|
||||
cd sdk
|
||||
|
||||
- name: SSH connection to Actions
|
||||
@@ -271,20 +294,37 @@ jobs:
|
||||
- name: ${{ matrix.platform }} feeds configuration packages
|
||||
run: |
|
||||
cd sdk
|
||||
echo "src-git base https://github.com/openwrt/openwrt.git;openwrt-${{ matrix.sdk_ver }}" > feeds.conf
|
||||
echo "src-git packages https://github.com/openwrt/packages.git;openwrt-${{ matrix.sdk_ver }}" >> feeds.conf
|
||||
echo "src-git luci https://github.com/openwrt/luci.git;openwrt-${{ matrix.sdk_ver }}" >> feeds.conf
|
||||
echo "src-git routing https://git.openwrt.org/feed/routing.git;openwrt-${{ matrix.sdk_ver }}" >> feeds.conf
|
||||
echo "src-git passwall_packages https://github.com/${{ env.packages }}.git;main" >> feeds.conf
|
||||
echo "src-git passwall2 https://github.com/${{ env.passwall2 }}.git;main" >> feeds.conf
|
||||
cat > feeds.conf.default << EOF
|
||||
src-git passwall_packages https://github.com/${{ env.packages }}.git;main
|
||||
src-git passwall2 https://github.com/${{ env.passwall2 }}.git;${{ github.ref_name }}
|
||||
src-git base https://github.com/openwrt/openwrt.git;openwrt-${{ matrix.sdk_ver }}
|
||||
src-git packages https://github.com/openwrt/packages.git;openwrt-${{ matrix.sdk_ver }}
|
||||
src-git luci https://github.com/openwrt/luci.git;openwrt-${{ matrix.sdk_ver }}
|
||||
src-git routing https://github.com/openwrt/routing.git;openwrt-${{ matrix.sdk_ver }}
|
||||
src-git telephony https://github.com/openwrt/telephony.git;openwrt-${{ matrix.sdk_ver }}
|
||||
EOF
|
||||
|
||||
./scripts/feeds update -a
|
||||
./scripts/feeds install -a -f -p passwall_packages
|
||||
./scripts/feeds install luci-app-passwall2
|
||||
./scripts/feeds install -a
|
||||
|
||||
|
||||
#--------------------------------------begin_patches------------------------------------------
|
||||
echo "Start applying the patch"
|
||||
|
||||
|
||||
echo "update golang version"
|
||||
rm -rf feeds/packages/lang/golang
|
||||
git clone https://github.com/sbwml/packages_lang_golang -b 24.x feeds/packages/lang/golang
|
||||
|
||||
echo "fixed rust host build error"
|
||||
sed -i 's/--set=llvm\.download-ci-llvm=false/--set=llvm.download-ci-llvm=true/' feeds/packages/lang/rust/Makefile
|
||||
grep -q -- '--ci false \\' feeds/packages/lang/rust/Makefile || sed -i '/x\.py \\/a \ --ci false \\' feeds/packages/lang/rust/Makefile
|
||||
|
||||
|
||||
echo "Patch application completed"
|
||||
#--------------------------------------end_patches--------------------------------------------
|
||||
|
||||
|
||||
echo "CONFIG_ALL_NONSHARED=n" > .config
|
||||
echo "CONFIG_ALL_KMODS=n" >> .config
|
||||
echo "CONFIG_ALL=n" >> .config
|
||||
|
||||
@@ -27,14 +27,14 @@ require (
|
||||
github.com/sagernet/gomobile v0.1.7
|
||||
github.com/sagernet/gvisor v0.0.0-20250325023245-7a9c0f5725fb
|
||||
github.com/sagernet/quic-go v0.52.0-beta.1
|
||||
github.com/sagernet/sing v0.7.0-beta.1.0.20250722151551-64142925accb
|
||||
github.com/sagernet/sing v0.7.0-beta.2
|
||||
github.com/sagernet/sing-mux v0.3.2
|
||||
github.com/sagernet/sing-quic v0.5.0-beta.3
|
||||
github.com/sagernet/sing-shadowsocks v0.2.8
|
||||
github.com/sagernet/sing-shadowsocks2 v0.2.1
|
||||
github.com/sagernet/sing-shadowtls v0.2.1-0.20250503051639-fcd445d33c11
|
||||
github.com/sagernet/sing-tun v0.6.10-0.20250721014417-ebbe32588cfb
|
||||
github.com/sagernet/sing-vmess v0.2.5
|
||||
github.com/sagernet/sing-tun v0.7.0-beta.1
|
||||
github.com/sagernet/sing-vmess v0.2.6
|
||||
github.com/sagernet/smux v1.5.34-mod.2
|
||||
github.com/sagernet/tailscale v1.80.3-mod.5
|
||||
github.com/sagernet/wireguard-go v0.0.1-beta.7
|
||||
|
||||
@@ -167,8 +167,8 @@ github.com/sagernet/nftables v0.3.0-beta.4/go.mod h1:OQXAjvjNGGFxaTgVCSTRIhYB5/l
|
||||
github.com/sagernet/quic-go v0.52.0-beta.1 h1:hWkojLg64zjV+MJOvJU/kOeWndm3tiEfBLx5foisszs=
|
||||
github.com/sagernet/quic-go v0.52.0-beta.1/go.mod h1:OV+V5kEBb8kJS7k29MzDu6oj9GyMc7HA07sE1tedxz4=
|
||||
github.com/sagernet/sing v0.6.9/go.mod h1:ARkL0gM13/Iv5VCZmci/NuoOlePoIsW0m7BWfln/Hak=
|
||||
github.com/sagernet/sing v0.7.0-beta.1.0.20250722151551-64142925accb h1:9DU5JA9Cow/bUfdP1v1pYMbAkFiW17UbI4b/iEPjVnc=
|
||||
github.com/sagernet/sing v0.7.0-beta.1.0.20250722151551-64142925accb/go.mod h1:ARkL0gM13/Iv5VCZmci/NuoOlePoIsW0m7BWfln/Hak=
|
||||
github.com/sagernet/sing v0.7.0-beta.2 h1:UImAKtHGQX205lGYYXKA2qnEeVSml+hKS1oaOwvA14c=
|
||||
github.com/sagernet/sing v0.7.0-beta.2/go.mod h1:ARkL0gM13/Iv5VCZmci/NuoOlePoIsW0m7BWfln/Hak=
|
||||
github.com/sagernet/sing-mux v0.3.2 h1:meZVFiiStvHThb/trcpAkCrmtJOuItG5Dzl1RRP5/NE=
|
||||
github.com/sagernet/sing-mux v0.3.2/go.mod h1:pht8iFY4c9Xltj7rhVd208npkNaeCxzyXCgulDPLUDA=
|
||||
github.com/sagernet/sing-quic v0.5.0-beta.3 h1:X/acRNsqQNfDlmwE7SorHfaZiny5e67hqIzM/592ric=
|
||||
@@ -179,10 +179,10 @@ github.com/sagernet/sing-shadowsocks2 v0.2.1 h1:dWV9OXCeFPuYGHb6IRqlSptVnSzOelnq
|
||||
github.com/sagernet/sing-shadowsocks2 v0.2.1/go.mod h1:RnXS0lExcDAovvDeniJ4IKa2IuChrdipolPYWBv9hWQ=
|
||||
github.com/sagernet/sing-shadowtls v0.2.1-0.20250503051639-fcd445d33c11 h1:tK+75l64tm9WvEFrYRE1t0YxoFdWQqw/h7Uhzj0vJ+w=
|
||||
github.com/sagernet/sing-shadowtls v0.2.1-0.20250503051639-fcd445d33c11/go.mod h1:sWqKnGlMipCHaGsw1sTTlimyUpgzP4WP3pjhCsYt9oA=
|
||||
github.com/sagernet/sing-tun v0.6.10-0.20250721014417-ebbe32588cfb h1:cvHEzjk3sVy80UA9PFKX15MzSP0g1uKwUspOm2ds3no=
|
||||
github.com/sagernet/sing-tun v0.6.10-0.20250721014417-ebbe32588cfb/go.mod h1:AHJuRrLbNRJuivuFZ2VhXwDj4ViYp14szG5EkkKAqRQ=
|
||||
github.com/sagernet/sing-vmess v0.2.5 h1:UI9KKqfDnMiyvNRknhd2ZCiHdvBl/Gv+Vg/y1yC6RIU=
|
||||
github.com/sagernet/sing-vmess v0.2.5/go.mod h1:5aYoOtYksAyS0NXDm0qKeTYW1yoE1bJVcv+XLcVoyJs=
|
||||
github.com/sagernet/sing-tun v0.7.0-beta.1 h1:mBIFXYAnGO5ey/HcCYanqnBx61E7yF8zTFGRZonGYmY=
|
||||
github.com/sagernet/sing-tun v0.7.0-beta.1/go.mod h1:AHJuRrLbNRJuivuFZ2VhXwDj4ViYp14szG5EkkKAqRQ=
|
||||
github.com/sagernet/sing-vmess v0.2.6 h1:1c4dGzeGy0kpBXXrT1sgiMZtHhdJylIT8eWrGhJYZec=
|
||||
github.com/sagernet/sing-vmess v0.2.6/go.mod h1:5aYoOtYksAyS0NXDm0qKeTYW1yoE1bJVcv+XLcVoyJs=
|
||||
github.com/sagernet/smux v1.5.34-mod.2 h1:gkmBjIjlJ2zQKpLigOkFur5kBKdV6bNRoFu2WkltRQ4=
|
||||
github.com/sagernet/smux v1.5.34-mod.2/go.mod h1:0KW0+R+ycvA2INW4gbsd7BNyg+HEfLIAxa5N02/28Zc=
|
||||
github.com/sagernet/tailscale v1.80.3-mod.5 h1:7V7z+p2C//TGtff20pPnDCt3qP6uFyY62peJoKF9z/A=
|
||||
|
||||
@@ -5,12 +5,12 @@
|
||||
include $(TOPDIR)/rules.mk
|
||||
|
||||
PKG_NAME:=brook
|
||||
PKG_VERSION:=20250202
|
||||
PKG_VERSION:=20250808
|
||||
PKG_RELEASE:=1
|
||||
|
||||
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
|
||||
PKG_SOURCE_URL:=https://codeload.github.com/txthinking/brook/tar.gz/v$(PKG_VERSION)?
|
||||
PKG_HASH:=2ee6bf43345b2cbf883eeaa8350da161352610e4fee82c29b0d3411a3e761f1f
|
||||
PKG_HASH:=d78e8066ba5377c3841c8b6dcc6949cccbc04f3e475a3ac34587721438cde494
|
||||
|
||||
PKG_MAINTAINER:=Tianling Shen <cnsztl@immortalwrt.org>
|
||||
PKG_LICENSE:=GPL-3.0
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
include $(TOPDIR)/rules.mk
|
||||
|
||||
PKG_NAME:=luci-app-passwall
|
||||
PKG_VERSION:=25.7.15
|
||||
PKG_VERSION:=25.8.1
|
||||
PKG_RELEASE:=1
|
||||
|
||||
PKG_CONFIG_DEPENDS:= \
|
||||
|
||||
@@ -130,7 +130,7 @@ public sealed class CoreInfoHandler
|
||||
{
|
||||
CoreType = ECoreType.hysteria,
|
||||
CoreExes = ["hysteria"],
|
||||
Arguments = "-c {0}",
|
||||
Arguments = "",
|
||||
Url = GetCoreUrl(ECoreType.hysteria),
|
||||
},
|
||||
|
||||
@@ -180,7 +180,7 @@ public sealed class CoreInfoHandler
|
||||
{
|
||||
CoreType = ECoreType.hysteria2,
|
||||
CoreExes = ["hysteria-windows-amd64", "hysteria-linux-amd64", "hysteria"],
|
||||
Arguments = "-c {0}",
|
||||
Arguments = "",
|
||||
Url = GetCoreUrl(ECoreType.hysteria2),
|
||||
},
|
||||
|
||||
|
||||
@@ -6,21 +6,21 @@ import (
|
||||
)
|
||||
|
||||
type DokodemoConfig struct {
|
||||
Host *Address `json:"address"`
|
||||
PortValue uint16 `json:"port"`
|
||||
NetworkList *NetworkList `json:"network"`
|
||||
Redirect bool `json:"followRedirect"`
|
||||
UserLevel uint32 `json:"userLevel"`
|
||||
Address *Address `json:"address"`
|
||||
Port uint16 `json:"port"`
|
||||
Network *NetworkList `json:"network"`
|
||||
FollowRedirect bool `json:"followRedirect"`
|
||||
UserLevel uint32 `json:"userLevel"`
|
||||
}
|
||||
|
||||
func (v *DokodemoConfig) Build() (proto.Message, error) {
|
||||
config := new(dokodemo.Config)
|
||||
if v.Host != nil {
|
||||
config.Address = v.Host.Build()
|
||||
if v.Address != nil {
|
||||
config.Address = v.Address.Build()
|
||||
}
|
||||
config.Port = uint32(v.PortValue)
|
||||
config.Networks = v.NetworkList.Build()
|
||||
config.FollowRedirect = v.Redirect
|
||||
config.Port = uint32(v.Port)
|
||||
config.Networks = v.Network.Build()
|
||||
config.FollowRedirect = v.FollowRedirect
|
||||
config.UserLevel = v.UserLevel
|
||||
return config, nil
|
||||
}
|
||||
|
||||
@@ -412,8 +412,9 @@ type TLSConfig struct {
|
||||
MasterKeyLog string `json:"masterKeyLog"`
|
||||
ServerNameToVerify string `json:"serverNameToVerify"`
|
||||
VerifyPeerCertInNames []string `json:"verifyPeerCertInNames"`
|
||||
ECHConfigList string `json:"echConfigList"`
|
||||
ECHServerKeys string `json:"echServerKeys"`
|
||||
ECHConfigList string `json:"echConfigList"`
|
||||
ECHForceQuery bool `json:"echForceQuery"`
|
||||
}
|
||||
|
||||
// Build implements Buildable.
|
||||
@@ -485,8 +486,6 @@ func (c *TLSConfig) Build() (proto.Message, error) {
|
||||
}
|
||||
config.VerifyPeerCertInNames = c.VerifyPeerCertInNames
|
||||
|
||||
config.EchConfigList = c.ECHConfigList
|
||||
|
||||
if c.ECHServerKeys != "" {
|
||||
EchPrivateKey, err := base64.StdEncoding.DecodeString(c.ECHServerKeys)
|
||||
if err != nil {
|
||||
@@ -494,6 +493,8 @@ func (c *TLSConfig) Build() (proto.Message, error) {
|
||||
}
|
||||
config.EchServerKeys = EchPrivateKey
|
||||
}
|
||||
config.EchForceQuery = c.ECHForceQuery
|
||||
config.EchConfigList = c.ECHConfigList
|
||||
|
||||
return config, nil
|
||||
}
|
||||
|
||||
@@ -21,6 +21,7 @@ import (
|
||||
|
||||
var (
|
||||
inboundConfigLoader = NewJSONConfigLoader(ConfigCreatorCache{
|
||||
"tunnel": func() interface{} { return new(DokodemoConfig) },
|
||||
"dokodemo-door": func() interface{} { return new(DokodemoConfig) },
|
||||
"http": func() interface{} { return new(HTTPServerConfig) },
|
||||
"shadowsocks": func() interface{} { return new(ShadowsocksServerConfig) },
|
||||
@@ -33,8 +34,10 @@ var (
|
||||
}, "protocol", "settings")
|
||||
|
||||
outboundConfigLoader = NewJSONConfigLoader(ConfigCreatorCache{
|
||||
"block": func() interface{} { return new(BlackholeConfig) },
|
||||
"blackhole": func() interface{} { return new(BlackholeConfig) },
|
||||
"loopback": func() interface{} { return new(LoopbackConfig) },
|
||||
"direct": func() interface{} { return new(FreedomConfig) },
|
||||
"freedom": func() interface{} { return new(FreedomConfig) },
|
||||
"http": func() interface{} { return new(HTTPClientConfig) },
|
||||
"shadowsocks": func() interface{} { return new(ShadowsocksClientConfig) },
|
||||
@@ -242,7 +245,7 @@ func (c *InboundDetourConfig) Build() (*core.InboundHandlerConfig, error) {
|
||||
return nil, errors.New("failed to load inbound detour config for protocol ", c.Protocol).Base(err)
|
||||
}
|
||||
if dokodemoConfig, ok := rawConfig.(*DokodemoConfig); ok {
|
||||
receiverSettings.ReceiveOriginalDestination = dokodemoConfig.Redirect
|
||||
receiverSettings.ReceiveOriginalDestination = dokodemoConfig.FollowRedirect
|
||||
}
|
||||
ts, err := rawConfig.(Buildable).Build()
|
||||
if err != nil {
|
||||
|
||||
@@ -3,6 +3,8 @@ package dokodemo
|
||||
import (
|
||||
"context"
|
||||
"runtime"
|
||||
"strconv"
|
||||
"strings"
|
||||
"sync/atomic"
|
||||
|
||||
"github.com/xtls/xray-core/common"
|
||||
@@ -73,6 +75,25 @@ func (d *DokodemoDoor) Process(ctx context.Context, network net.Network, conn st
|
||||
Port: d.port,
|
||||
}
|
||||
|
||||
if !d.config.FollowRedirect {
|
||||
host, port, err := net.SplitHostPort(conn.LocalAddr().String())
|
||||
if dest.Address == nil {
|
||||
if err != nil {
|
||||
dest.Address = net.DomainAddress("localhost")
|
||||
} else {
|
||||
if strings.Contains(host, ".") {
|
||||
dest.Address = net.LocalHostIP
|
||||
} else {
|
||||
dest.Address = net.LocalHostIPv6
|
||||
}
|
||||
}
|
||||
}
|
||||
if dest.Port == 0 {
|
||||
dest.Port = net.Port(common.Must2(strconv.Atoi(port)).(int))
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
destinationOverridden := false
|
||||
if d.config.FollowRedirect {
|
||||
outbounds := session.OutboundsFromContext(ctx)
|
||||
|
||||
@@ -217,8 +217,9 @@ type Config struct {
|
||||
// @Document After allow_insecure (automatically), if the server's cert can't be verified by any of these names, pinned_peer_certificate_chain_sha256 will be tried.
|
||||
// @Critical
|
||||
VerifyPeerCertInNames []string `protobuf:"bytes,17,rep,name=verify_peer_cert_in_names,json=verifyPeerCertInNames,proto3" json:"verify_peer_cert_in_names,omitempty"`
|
||||
EchConfigList string `protobuf:"bytes,18,opt,name=ech_config_list,json=echConfigList,proto3" json:"ech_config_list,omitempty"`
|
||||
EchServerKeys []byte `protobuf:"bytes,19,opt,name=ech_server_keys,json=echServerKeys,proto3" json:"ech_server_keys,omitempty"`
|
||||
EchServerKeys []byte `protobuf:"bytes,18,opt,name=ech_server_keys,json=echServerKeys,proto3" json:"ech_server_keys,omitempty"`
|
||||
EchConfigList string `protobuf:"bytes,19,opt,name=ech_config_list,json=echConfigList,proto3" json:"ech_config_list,omitempty"`
|
||||
EchForceQuery bool `protobuf:"varint,20,opt,name=ech_force_query,json=echForceQuery,proto3" json:"ech_force_query,omitempty"`
|
||||
}
|
||||
|
||||
func (x *Config) Reset() {
|
||||
@@ -363,6 +364,13 @@ func (x *Config) GetVerifyPeerCertInNames() []string {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (x *Config) GetEchServerKeys() []byte {
|
||||
if x != nil {
|
||||
return x.EchServerKeys
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (x *Config) GetEchConfigList() string {
|
||||
if x != nil {
|
||||
return x.EchConfigList
|
||||
@@ -370,11 +378,11 @@ func (x *Config) GetEchConfigList() string {
|
||||
return ""
|
||||
}
|
||||
|
||||
func (x *Config) GetEchServerKeys() []byte {
|
||||
func (x *Config) GetEchForceQuery() bool {
|
||||
if x != nil {
|
||||
return x.EchServerKeys
|
||||
return x.EchForceQuery
|
||||
}
|
||||
return nil
|
||||
return false
|
||||
}
|
||||
|
||||
var File_transport_internet_tls_config_proto protoreflect.FileDescriptor
|
||||
@@ -408,7 +416,7 @@ var file_transport_internet_tls_config_proto_rawDesc = []byte{
|
||||
0x4e, 0x43, 0x49, 0x50, 0x48, 0x45, 0x52, 0x4d, 0x45, 0x4e, 0x54, 0x10, 0x00, 0x12, 0x14, 0x0a,
|
||||
0x10, 0x41, 0x55, 0x54, 0x48, 0x4f, 0x52, 0x49, 0x54, 0x59, 0x5f, 0x56, 0x45, 0x52, 0x49, 0x46,
|
||||
0x59, 0x10, 0x01, 0x12, 0x13, 0x0a, 0x0f, 0x41, 0x55, 0x54, 0x48, 0x4f, 0x52, 0x49, 0x54, 0x59,
|
||||
0x5f, 0x49, 0x53, 0x53, 0x55, 0x45, 0x10, 0x02, 0x22, 0xea, 0x06, 0x0a, 0x06, 0x43, 0x6f, 0x6e,
|
||||
0x5f, 0x49, 0x53, 0x53, 0x55, 0x45, 0x10, 0x02, 0x22, 0x92, 0x07, 0x0a, 0x06, 0x43, 0x6f, 0x6e,
|
||||
0x66, 0x69, 0x67, 0x12, 0x25, 0x0a, 0x0e, 0x61, 0x6c, 0x6c, 0x6f, 0x77, 0x5f, 0x69, 0x6e, 0x73,
|
||||
0x65, 0x63, 0x75, 0x72, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0d, 0x61, 0x6c, 0x6c,
|
||||
0x6f, 0x77, 0x49, 0x6e, 0x73, 0x65, 0x63, 0x75, 0x72, 0x65, 0x12, 0x4a, 0x0a, 0x0b, 0x63, 0x65,
|
||||
@@ -458,20 +466,22 @@ var file_transport_internet_tls_config_proto_rawDesc = []byte{
|
||||
0x65, 0x72, 0x69, 0x66, 0x79, 0x5f, 0x70, 0x65, 0x65, 0x72, 0x5f, 0x63, 0x65, 0x72, 0x74, 0x5f,
|
||||
0x69, 0x6e, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x18, 0x11, 0x20, 0x03, 0x28, 0x09, 0x52, 0x15,
|
||||
0x76, 0x65, 0x72, 0x69, 0x66, 0x79, 0x50, 0x65, 0x65, 0x72, 0x43, 0x65, 0x72, 0x74, 0x49, 0x6e,
|
||||
0x4e, 0x61, 0x6d, 0x65, 0x73, 0x12, 0x26, 0x0a, 0x0f, 0x65, 0x63, 0x68, 0x5f, 0x63, 0x6f, 0x6e,
|
||||
0x66, 0x69, 0x67, 0x5f, 0x6c, 0x69, 0x73, 0x74, 0x18, 0x12, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d,
|
||||
0x65, 0x63, 0x68, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x4c, 0x69, 0x73, 0x74, 0x12, 0x26, 0x0a,
|
||||
0x0f, 0x65, 0x63, 0x68, 0x5f, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x5f, 0x6b, 0x65, 0x79, 0x73,
|
||||
0x18, 0x13, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0d, 0x65, 0x63, 0x68, 0x53, 0x65, 0x72, 0x76, 0x65,
|
||||
0x72, 0x4b, 0x65, 0x79, 0x73, 0x42, 0x73, 0x0a, 0x1f, 0x63, 0x6f, 0x6d, 0x2e, 0x78, 0x72, 0x61,
|
||||
0x79, 0x2e, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x69, 0x6e, 0x74, 0x65,
|
||||
0x72, 0x6e, 0x65, 0x74, 0x2e, 0x74, 0x6c, 0x73, 0x50, 0x01, 0x5a, 0x30, 0x67, 0x69, 0x74, 0x68,
|
||||
0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x78, 0x74, 0x6c, 0x73, 0x2f, 0x78, 0x72, 0x61, 0x79,
|
||||
0x2d, 0x63, 0x6f, 0x72, 0x65, 0x2f, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x70, 0x6f, 0x72, 0x74, 0x2f,
|
||||
0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x65, 0x74, 0x2f, 0x74, 0x6c, 0x73, 0xaa, 0x02, 0x1b, 0x58,
|
||||
0x72, 0x61, 0x79, 0x2e, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x49, 0x6e,
|
||||
0x74, 0x65, 0x72, 0x6e, 0x65, 0x74, 0x2e, 0x54, 0x6c, 0x73, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74,
|
||||
0x6f, 0x33,
|
||||
0x4e, 0x61, 0x6d, 0x65, 0x73, 0x12, 0x26, 0x0a, 0x0f, 0x65, 0x63, 0x68, 0x5f, 0x73, 0x65, 0x72,
|
||||
0x76, 0x65, 0x72, 0x5f, 0x6b, 0x65, 0x79, 0x73, 0x18, 0x12, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0d,
|
||||
0x65, 0x63, 0x68, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x4b, 0x65, 0x79, 0x73, 0x12, 0x26, 0x0a,
|
||||
0x0f, 0x65, 0x63, 0x68, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x5f, 0x6c, 0x69, 0x73, 0x74,
|
||||
0x18, 0x13, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x65, 0x63, 0x68, 0x43, 0x6f, 0x6e, 0x66, 0x69,
|
||||
0x67, 0x4c, 0x69, 0x73, 0x74, 0x12, 0x26, 0x0a, 0x0f, 0x65, 0x63, 0x68, 0x5f, 0x66, 0x6f, 0x72,
|
||||
0x63, 0x65, 0x5f, 0x71, 0x75, 0x65, 0x72, 0x79, 0x18, 0x14, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0d,
|
||||
0x65, 0x63, 0x68, 0x46, 0x6f, 0x72, 0x63, 0x65, 0x51, 0x75, 0x65, 0x72, 0x79, 0x42, 0x73, 0x0a,
|
||||
0x1f, 0x63, 0x6f, 0x6d, 0x2e, 0x78, 0x72, 0x61, 0x79, 0x2e, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x70,
|
||||
0x6f, 0x72, 0x74, 0x2e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x65, 0x74, 0x2e, 0x74, 0x6c, 0x73,
|
||||
0x50, 0x01, 0x5a, 0x30, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x78,
|
||||
0x74, 0x6c, 0x73, 0x2f, 0x78, 0x72, 0x61, 0x79, 0x2d, 0x63, 0x6f, 0x72, 0x65, 0x2f, 0x74, 0x72,
|
||||
0x61, 0x6e, 0x73, 0x70, 0x6f, 0x72, 0x74, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x65, 0x74,
|
||||
0x2f, 0x74, 0x6c, 0x73, 0xaa, 0x02, 0x1b, 0x58, 0x72, 0x61, 0x79, 0x2e, 0x54, 0x72, 0x61, 0x6e,
|
||||
0x73, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x65, 0x74, 0x2e, 0x54,
|
||||
0x6c, 0x73, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
|
||||
}
|
||||
|
||||
var (
|
||||
|
||||
@@ -92,7 +92,9 @@ message Config {
|
||||
*/
|
||||
repeated string verify_peer_cert_in_names = 17;
|
||||
|
||||
string ech_config_list = 18;
|
||||
bytes ech_server_keys = 18;
|
||||
|
||||
bytes ech_server_keys = 19;
|
||||
}
|
||||
string ech_config_list = 19;
|
||||
|
||||
bool ech_force_query = 20;
|
||||
}
|
||||
@@ -32,8 +32,26 @@ func ApplyECH(c *Config, config *tls.Config) error {
|
||||
nameToQuery := c.ServerName
|
||||
var DNSServer string
|
||||
|
||||
// for server
|
||||
if len(c.EchServerKeys) != 0 {
|
||||
KeySets, err := ConvertToGoECHKeys(c.EchServerKeys)
|
||||
if err != nil {
|
||||
return errors.New("Failed to unmarshal ECHKeySetList: ", err)
|
||||
}
|
||||
config.EncryptedClientHelloKeys = KeySets
|
||||
}
|
||||
|
||||
// for client
|
||||
if len(c.EchConfigList) != 0 {
|
||||
defer func() {
|
||||
// if failed to get ECHConfig, use an invalid one to make connection fail
|
||||
if err != nil {
|
||||
if c.EchForceQuery {
|
||||
ECHConfig = []byte{1, 1, 4, 5, 1, 4}
|
||||
}
|
||||
}
|
||||
config.EncryptedClientHelloConfigList = ECHConfig
|
||||
}()
|
||||
// direct base64 config
|
||||
if strings.Contains(c.EchConfigList, "://") {
|
||||
// query config from dns
|
||||
@@ -51,7 +69,7 @@ func ApplyECH(c *Config, config *tls.Config) error {
|
||||
if nameToQuery == "" {
|
||||
return errors.New("Using DNS for ECH Config needs serverName or use Server format example.com+https://1.1.1.1/dns-query")
|
||||
}
|
||||
ECHConfig, err = QueryRecord(nameToQuery, DNSServer)
|
||||
ECHConfig, err = QueryRecord(nameToQuery, DNSServer, c.EchForceQuery)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -61,17 +79,6 @@ func ApplyECH(c *Config, config *tls.Config) error {
|
||||
return errors.New("Failed to unmarshal ECHConfigList: ", err)
|
||||
}
|
||||
}
|
||||
|
||||
config.EncryptedClientHelloConfigList = ECHConfig
|
||||
}
|
||||
|
||||
// for server
|
||||
if len(c.EchServerKeys) != 0 {
|
||||
KeySets, err := ConvertToGoECHKeys(c.EchServerKeys)
|
||||
if err != nil {
|
||||
return errors.New("Failed to unmarshal ECHKeySetList: ", err)
|
||||
}
|
||||
config.EncryptedClientHelloKeys = KeySets
|
||||
}
|
||||
|
||||
return nil
|
||||
@@ -86,9 +93,11 @@ type ECHConfigCache struct {
|
||||
type echConfigRecord struct {
|
||||
config []byte
|
||||
expire time.Time
|
||||
err error
|
||||
}
|
||||
|
||||
var (
|
||||
// key value must be like this: "example.com|udp://1.1.1.1"
|
||||
GlobalECHConfigCache = utils.NewTypedSyncMap[string, *ECHConfigCache]()
|
||||
clientForECHDOH = utils.NewTypedSyncMap[string, *http.Client]()
|
||||
)
|
||||
@@ -96,7 +105,7 @@ var (
|
||||
// Update updates the ECH config for given domain and server.
|
||||
// this method is concurrent safe, only one update request will be sent, others get the cache.
|
||||
// if isLockedUpdate is true, it will not try to acquire the lock.
|
||||
func (c *ECHConfigCache) Update(domain string, server string, isLockedUpdate bool) ([]byte, error) {
|
||||
func (c *ECHConfigCache) Update(domain string, server string, forceQuery bool, isLockedUpdate bool) ([]byte, error) {
|
||||
if !isLockedUpdate {
|
||||
c.UpdateLock.Lock()
|
||||
defer c.UpdateLock.Unlock()
|
||||
@@ -105,13 +114,23 @@ func (c *ECHConfigCache) Update(domain string, server string, isLockedUpdate boo
|
||||
configRecord := c.configRecord.Load()
|
||||
if configRecord.expire.After(time.Now()) {
|
||||
errors.LogDebug(context.Background(), "Cache hit for domain after double check: ", domain)
|
||||
return configRecord.config, nil
|
||||
return configRecord.config, configRecord.err
|
||||
}
|
||||
// Query ECH config from DNS server
|
||||
errors.LogDebug(context.Background(), "Trying to query ECH config for domain: ", domain, " with ECH server: ", server)
|
||||
echConfig, ttl, err := dnsQuery(server, domain)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
if forceQuery {
|
||||
return nil, err
|
||||
} else {
|
||||
configRecord = &echConfigRecord{
|
||||
config: nil,
|
||||
expire: time.Now().Add(10 * time.Minute),
|
||||
err: err,
|
||||
}
|
||||
c.configRecord.Store(configRecord)
|
||||
return echConfig, err
|
||||
}
|
||||
}
|
||||
configRecord = &echConfigRecord{
|
||||
config: echConfig,
|
||||
@@ -123,30 +142,31 @@ func (c *ECHConfigCache) Update(domain string, server string, isLockedUpdate boo
|
||||
|
||||
// QueryRecord returns the ECH config for given domain.
|
||||
// If the record is not in cache or expired, it will query the DNS server and update the cache.
|
||||
func QueryRecord(domain string, server string) ([]byte, error) {
|
||||
echConfigCache, ok := GlobalECHConfigCache.Load(domain)
|
||||
func QueryRecord(domain string, server string, forceQuery bool) ([]byte, error) {
|
||||
GlobalECHConfigCacheKey := domain + "|" + server
|
||||
echConfigCache, ok := GlobalECHConfigCache.Load(GlobalECHConfigCacheKey)
|
||||
if !ok {
|
||||
echConfigCache = &ECHConfigCache{}
|
||||
echConfigCache.configRecord.Store(&echConfigRecord{})
|
||||
echConfigCache, _ = GlobalECHConfigCache.LoadOrStore(domain, echConfigCache)
|
||||
echConfigCache, _ = GlobalECHConfigCache.LoadOrStore(GlobalECHConfigCacheKey, echConfigCache)
|
||||
}
|
||||
configRecord := echConfigCache.configRecord.Load()
|
||||
if configRecord.expire.After(time.Now()) {
|
||||
errors.LogDebug(context.Background(), "Cache hit for domain: ", domain)
|
||||
return configRecord.config, nil
|
||||
return configRecord.config, configRecord.err
|
||||
}
|
||||
|
||||
// If expire is zero value, it means we are in initial state, wait for the query to finish
|
||||
// otherwise return old value immediately and update in a goroutine
|
||||
// but if the cache is too old, wait for update
|
||||
if configRecord.expire == (time.Time{}) || configRecord.expire.Add(time.Hour*6).Before(time.Now()) {
|
||||
return echConfigCache.Update(domain, server, false)
|
||||
return echConfigCache.Update(domain, server, false, forceQuery)
|
||||
} else {
|
||||
// If someone already acquired the lock, it means it is updating, do not start another update goroutine
|
||||
if echConfigCache.UpdateLock.TryLock() {
|
||||
go func() {
|
||||
defer echConfigCache.UpdateLock.Unlock()
|
||||
echConfigCache.Update(domain, server, true)
|
||||
echConfigCache.Update(domain, server, true, forceQuery)
|
||||
}()
|
||||
}
|
||||
return configRecord.config, nil
|
||||
@@ -165,7 +185,7 @@ func dnsQuery(server string, domain string) ([]byte, uint32, error) {
|
||||
m.Id = 0
|
||||
msg, err := m.Pack()
|
||||
if err != nil {
|
||||
return []byte{}, 0, err
|
||||
return nil, 0, err
|
||||
}
|
||||
var client *http.Client
|
||||
if client, _ = clientForECHDOH.Load(server); client == nil {
|
||||
@@ -194,20 +214,20 @@ func dnsQuery(server string, domain string) ([]byte, uint32, error) {
|
||||
}
|
||||
req, err := http.NewRequest("POST", server, bytes.NewReader(msg))
|
||||
if err != nil {
|
||||
return []byte{}, 0, err
|
||||
return nil, 0, err
|
||||
}
|
||||
req.Header.Set("Content-Type", "application/dns-message")
|
||||
resp, err := client.Do(req)
|
||||
if err != nil {
|
||||
return []byte{}, 0, err
|
||||
return nil, 0, err
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
respBody, err := io.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
return []byte{}, 0, err
|
||||
return nil, 0, err
|
||||
}
|
||||
if resp.StatusCode != http.StatusOK {
|
||||
return []byte{}, 0, errors.New("query failed with response code:", resp.StatusCode)
|
||||
return nil, 0, errors.New("query failed with response code:", resp.StatusCode)
|
||||
}
|
||||
dnsResolve = respBody
|
||||
} else if strings.HasPrefix(server, "udp://") { // for classic udp dns server
|
||||
@@ -231,24 +251,25 @@ func dnsQuery(server string, domain string) ([]byte, uint32, error) {
|
||||
}
|
||||
}()
|
||||
if err != nil {
|
||||
return []byte{}, 0, err
|
||||
return nil, 0, err
|
||||
}
|
||||
msg, err := m.Pack()
|
||||
if err != nil {
|
||||
return []byte{}, 0, err
|
||||
return nil, 0, err
|
||||
}
|
||||
conn.Write(msg)
|
||||
udpResponse := make([]byte, 512)
|
||||
conn.SetReadDeadline(time.Now().Add(5 * time.Second))
|
||||
_, err = conn.Read(udpResponse)
|
||||
if err != nil {
|
||||
return []byte{}, 0, err
|
||||
return nil, 0, err
|
||||
}
|
||||
dnsResolve = udpResponse
|
||||
}
|
||||
respMsg := new(dns.Msg)
|
||||
err := respMsg.Unpack(dnsResolve)
|
||||
if err != nil {
|
||||
return []byte{}, 0, errors.New("failed to unpack dns response for ECH: ", err)
|
||||
return nil, 0, errors.New("failed to unpack dns response for ECH: ", err)
|
||||
}
|
||||
if len(respMsg.Answer) > 0 {
|
||||
for _, answer := range respMsg.Answer {
|
||||
@@ -262,7 +283,7 @@ func dnsQuery(server string, domain string) ([]byte, uint32, error) {
|
||||
}
|
||||
}
|
||||
}
|
||||
return []byte{}, 0, errors.New("no ech record found")
|
||||
return nil, 0, errors.New("no ech record found")
|
||||
}
|
||||
|
||||
// reference github.com/OmarTariq612/goech
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
package tls_test
|
||||
package tls
|
||||
|
||||
import (
|
||||
"io"
|
||||
@@ -8,13 +8,12 @@ import (
|
||||
"testing"
|
||||
|
||||
"github.com/xtls/xray-core/common"
|
||||
. "github.com/xtls/xray-core/transport/internet/tls"
|
||||
)
|
||||
|
||||
func TestECHDial(t *testing.T) {
|
||||
config := &Config{
|
||||
ServerName: "encryptedsni.com",
|
||||
EchConfigList: "udp://1.1.1.1",
|
||||
ServerName: "cloudflare.com",
|
||||
EchConfigList: "encryptedsni.com+udp://1.1.1.1",
|
||||
}
|
||||
// test concurrent Dial(to test cache problem)
|
||||
wg := sync.WaitGroup{}
|
||||
@@ -28,7 +27,7 @@ func TestECHDial(t *testing.T) {
|
||||
TLSClientConfig: TLSConfig,
|
||||
},
|
||||
}
|
||||
resp, err := client.Get("https://encryptedsni.com/cdn-cgi/trace")
|
||||
resp, err := client.Get("https://cloudflare.com/cdn-cgi/trace")
|
||||
common.Must(err)
|
||||
defer resp.Body.Close()
|
||||
body, err := io.ReadAll(resp.Body)
|
||||
@@ -40,4 +39,51 @@ func TestECHDial(t *testing.T) {
|
||||
}()
|
||||
}
|
||||
wg.Wait()
|
||||
// check cache
|
||||
echConfigCache, ok := GlobalECHConfigCache.Load("encryptedsni.com|udp://1.1.1.1")
|
||||
if !ok {
|
||||
t.Error("ECH config cache not found")
|
||||
|
||||
}
|
||||
ok = echConfigCache.UpdateLock.TryLock()
|
||||
if !ok {
|
||||
t.Error("ECH config cache dead lock detected")
|
||||
}
|
||||
echConfigCache.UpdateLock.Unlock()
|
||||
configRecord := echConfigCache.configRecord.Load()
|
||||
if configRecord == nil {
|
||||
t.Error("ECH config record not found in cache")
|
||||
}
|
||||
}
|
||||
|
||||
func TestECHDialFail(t *testing.T) {
|
||||
config := &Config{
|
||||
ServerName: "cloudflare.com",
|
||||
EchConfigList: "udp://1.1.1.1",
|
||||
}
|
||||
TLSConfig := config.GetTLSConfig()
|
||||
TLSConfig.NextProtos = []string{"http/1.1"}
|
||||
client := &http.Client{
|
||||
Transport: &http.Transport{
|
||||
TLSClientConfig: TLSConfig,
|
||||
},
|
||||
}
|
||||
resp, err := client.Get("https://cloudflare.com/cdn-cgi/trace")
|
||||
common.Must(err)
|
||||
defer resp.Body.Close()
|
||||
_, err = io.ReadAll(resp.Body)
|
||||
common.Must(err)
|
||||
// check cache
|
||||
echConfigCache, ok := GlobalECHConfigCache.Load("cloudflare.com|udp://1.1.1.1")
|
||||
if !ok {
|
||||
t.Error("ECH config cache not found")
|
||||
}
|
||||
configRecord := echConfigCache.configRecord.Load()
|
||||
if configRecord == nil {
|
||||
t.Error("ECH config record not found in cache")
|
||||
return
|
||||
}
|
||||
if configRecord.err == nil {
|
||||
t.Error("unexpected nil error in ECH config record")
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,104 +1,107 @@
|
||||
from .common import InfoExtractor
|
||||
from ..networking.exceptions import HTTPError
|
||||
from .streaks import StreaksBaseIE
|
||||
from ..utils import (
|
||||
ExtractorError,
|
||||
clean_html,
|
||||
int_or_none,
|
||||
str_or_none,
|
||||
unified_timestamp,
|
||||
urljoin,
|
||||
url_or_none,
|
||||
)
|
||||
from ..utils.traversal import find_element, traverse_obj
|
||||
from ..utils.traversal import traverse_obj
|
||||
|
||||
|
||||
class TBSJPEpisodeIE(InfoExtractor):
|
||||
class TBSJPBaseIE(StreaksBaseIE):
|
||||
def _search_window_app_json(self, webpage, name, item_id, **kwargs):
|
||||
return self._search_json(r'window\.app\s*=', webpage, f'{name} info', item_id, **kwargs)
|
||||
|
||||
|
||||
class TBSJPEpisodeIE(TBSJPBaseIE):
|
||||
_VALID_URL = r'https?://cu\.tbs\.co\.jp/episode/(?P<id>[\d_]+)'
|
||||
_GEO_BYPASS = False
|
||||
_TESTS = [{
|
||||
'url': 'https://cu.tbs.co.jp/episode/23613_2044134_1000049010',
|
||||
'skip': 'streams geo-restricted, Japan only. Also, will likely expire eventually',
|
||||
'url': 'https://cu.tbs.co.jp/episode/14694_2094162_1000123656',
|
||||
'skip': 'geo-blocked to japan + 7-day expiry',
|
||||
'info_dict': {
|
||||
'title': 'VIVANT 第三話 誤送金完結へ!絶体絶命の反撃開始',
|
||||
'id': '23613_2044134_1000049010',
|
||||
'title': 'クロちゃん、寝て起きたら川のほとりにいてその向こう岸に亡くなった父親がいたら死の淵にいるかと思う説 ほか',
|
||||
'id': '14694_2094162_1000123656',
|
||||
'ext': 'mp4',
|
||||
'upload_date': '20230728',
|
||||
'duration': 3517,
|
||||
'release_timestamp': 1691118230,
|
||||
'episode': '第三話 誤送金完結へ!絶体絶命の反撃開始',
|
||||
'release_date': '20230804',
|
||||
'categories': 'count:11',
|
||||
'episode_number': 3,
|
||||
'timestamp': 1690522538,
|
||||
'description': 'md5:2b796341af1ef772034133174ba4a895',
|
||||
'series': 'VIVANT',
|
||||
'display_id': 'ref:14694_2094162_1000123656',
|
||||
'description': 'md5:1a82fcdeb5e2e82190544bb72721c46e',
|
||||
'uploader': 'TBS',
|
||||
'uploader_id': 'tbs',
|
||||
'duration': 2752,
|
||||
'thumbnail': 'md5:d8855c8c292683c95a84cafdb42300bc',
|
||||
'categories': ['エンタメ', '水曜日のダウンタウン', 'ダウンタウン', '浜田雅功', '松本人志', '水ダウ', '動画', 'バラエティ'],
|
||||
'cast': ['浜田 雅功', '藤本 敏史', 'ビビる 大木', '千原 ジュニア', '横澤 夏子', 'せいや', 'あの', '服部 潤'],
|
||||
'genres': ['variety'],
|
||||
'series': '水曜日のダウンタウン',
|
||||
'series_id': '14694',
|
||||
'episode': 'クロちゃん、寝て起きたら川のほとりにいてその向こう岸に亡くなった父親がいたら死の淵にいるかと思う説 ほか',
|
||||
'episode_number': 341,
|
||||
'episode_id': '14694_2094162_1000123656',
|
||||
'timestamp': 1753778992,
|
||||
'upload_date': '20250729',
|
||||
'release_timestamp': 1753880402,
|
||||
'release_date': '20250730',
|
||||
'modified_timestamp': 1753880741,
|
||||
'modified_date': '20250730',
|
||||
'live_status': 'not_live',
|
||||
},
|
||||
}]
|
||||
|
||||
def _real_extract(self, url):
|
||||
video_id = self._match_id(url)
|
||||
webpage = self._download_webpage(url, video_id)
|
||||
meta = self._search_json(r'window\.app\s*=', webpage, 'episode info', video_id, fatal=False)
|
||||
meta = self._search_window_app_json(webpage, 'episode', video_id, fatal=False)
|
||||
episode = traverse_obj(meta, ('falcorCache', 'catalog', 'episode', video_id, 'value'))
|
||||
|
||||
tf_path = self._search_regex(
|
||||
r'<script[^>]+src=["\'](/assets/tf\.[^"\']+\.js)["\']', webpage, 'stream API config')
|
||||
tf_js = self._download_webpage(urljoin(url, tf_path), video_id, note='Downloading stream API config')
|
||||
video_url = self._search_regex(r'videoPlaybackUrl:\s*[\'"]([^\'"]+)[\'"]', tf_js, 'stream API url')
|
||||
api_key = self._search_regex(r'api_key:\s*[\'"]([^\'"]+)[\'"]', tf_js, 'stream API key')
|
||||
|
||||
try:
|
||||
source_meta = self._download_json(f'{video_url}ref:{video_id}', video_id,
|
||||
headers={'X-Streaks-Api-Key': api_key},
|
||||
note='Downloading stream metadata')
|
||||
except ExtractorError as e:
|
||||
if isinstance(e.cause, HTTPError) and e.cause.status == 403:
|
||||
self.raise_geo_restricted(countries=['JP'])
|
||||
raise
|
||||
|
||||
formats, subtitles = [], {}
|
||||
for src in traverse_obj(source_meta, ('sources', ..., 'src')):
|
||||
fmts, subs = self._extract_m3u8_formats_and_subtitles(src, video_id, fatal=False)
|
||||
formats.extend(fmts)
|
||||
self._merge_subtitles(subs, target=subtitles)
|
||||
|
||||
return {
|
||||
'title': traverse_obj(webpage, ({find_element(tag='h3')}, {clean_html})),
|
||||
'id': video_id,
|
||||
**self._extract_from_streaks_api(
|
||||
'tbs', f'ref:{video_id}', headers={'Origin': 'https://cu.tbs.co.jp'}),
|
||||
**traverse_obj(episode, {
|
||||
'categories': ('keywords', {list}),
|
||||
'id': ('content_id', {str}),
|
||||
'description': ('description', 0, 'value'),
|
||||
'timestamp': ('created_at', {unified_timestamp}),
|
||||
'release_timestamp': ('pub_date', {unified_timestamp}),
|
||||
'title': ('title', ..., 'value', {str}, any),
|
||||
'cast': (
|
||||
'credit', ..., 'name', ..., 'value', {clean_html}, any,
|
||||
{lambda x: x.split(',')}, ..., {str.strip}, filter, all, filter),
|
||||
'categories': ('keywords', ..., {str}, filter, all, filter),
|
||||
'description': ('description', ..., 'value', {clean_html}, any),
|
||||
'duration': ('tv_episode_info', 'duration', {int_or_none}),
|
||||
'episode': ('title', lambda _, v: not v.get('is_phonetic'), 'value', {str}, any),
|
||||
'episode_id': ('content_id', {str}),
|
||||
'episode_number': ('tv_episode_info', 'episode_number', {int_or_none}),
|
||||
'episode': ('title', lambda _, v: not v.get('is_phonetic'), 'value'),
|
||||
'series': ('custom_data', 'program_name'),
|
||||
}, get_all=False),
|
||||
'formats': formats,
|
||||
'subtitles': subtitles,
|
||||
'genres': ('genre', ..., {str}, filter, all, filter),
|
||||
'release_timestamp': ('pub_date', {unified_timestamp}),
|
||||
'series': ('custom_data', 'program_name', {str}),
|
||||
'tags': ('tags', ..., {str}, filter, all, filter),
|
||||
'thumbnail': ('artwork', ..., 'url', {url_or_none}, any),
|
||||
'timestamp': ('created_at', {unified_timestamp}),
|
||||
'uploader': ('tv_show_info', 'networks', ..., {str}, any),
|
||||
}),
|
||||
**traverse_obj(episode, ('tv_episode_info', {
|
||||
'duration': ('duration', {int_or_none}),
|
||||
'episode_number': ('episode_number', {int_or_none}),
|
||||
'series_id': ('show_content_id', {str}),
|
||||
})),
|
||||
'id': video_id,
|
||||
}
|
||||
|
||||
|
||||
class TBSJPProgramIE(InfoExtractor):
|
||||
class TBSJPProgramIE(TBSJPBaseIE):
|
||||
_VALID_URL = r'https?://cu\.tbs\.co\.jp/program/(?P<id>\d+)'
|
||||
_TESTS = [{
|
||||
'url': 'https://cu.tbs.co.jp/program/23601',
|
||||
'playlist_mincount': 4,
|
||||
'url': 'https://cu.tbs.co.jp/program/14694',
|
||||
'playlist_mincount': 1,
|
||||
'info_dict': {
|
||||
'id': '23601',
|
||||
'categories': ['エンタメ', 'ミライカプセル', '会社', '働く', 'バラエティ', '動画'],
|
||||
'description': '幼少期の夢は大人になって、どう成長したのだろうか?\nそしてその夢は今後、どのように広がっていくのか?\nいま話題の会社で働く人の「夢の成長」を描く',
|
||||
'series': 'ミライカプセル -I have a dream-',
|
||||
'title': 'ミライカプセル -I have a dream-',
|
||||
'id': '14694',
|
||||
'title': '水曜日のダウンタウン',
|
||||
'description': 'md5:cf1d46c76c2755d7f87512498718b837',
|
||||
'categories': ['エンタメ', '水曜日のダウンタウン', 'ダウンタウン', '浜田雅功', '松本人志', '水ダウ', '動画', 'バラエティ'],
|
||||
'series': '水曜日のダウンタウン',
|
||||
},
|
||||
}]
|
||||
|
||||
def _real_extract(self, url):
|
||||
programme_id = self._match_id(url)
|
||||
webpage = self._download_webpage(url, programme_id)
|
||||
meta = self._search_json(r'window\.app\s*=', webpage, 'programme info', programme_id)
|
||||
|
||||
meta = self._search_window_app_json(webpage, 'programme', programme_id)
|
||||
programme = traverse_obj(meta, ('falcorCache', 'catalog', 'program', programme_id, 'false', 'value'))
|
||||
|
||||
return {
|
||||
@@ -116,7 +119,7 @@ class TBSJPProgramIE(InfoExtractor):
|
||||
}
|
||||
|
||||
|
||||
class TBSJPPlaylistIE(InfoExtractor):
|
||||
class TBSJPPlaylistIE(TBSJPBaseIE):
|
||||
_VALID_URL = r'https?://cu\.tbs\.co\.jp/playlist/(?P<id>[\da-f]+)'
|
||||
_TESTS = [{
|
||||
'url': 'https://cu.tbs.co.jp/playlist/184f9970e7ba48e4915f1b252c55015e',
|
||||
@@ -129,8 +132,8 @@ class TBSJPPlaylistIE(InfoExtractor):
|
||||
|
||||
def _real_extract(self, url):
|
||||
playlist_id = self._match_id(url)
|
||||
page = self._download_webpage(url, playlist_id)
|
||||
meta = self._search_json(r'window\.app\s*=', page, 'playlist info', playlist_id)
|
||||
webpage = self._download_webpage(url, playlist_id)
|
||||
meta = self._search_window_app_json(webpage, 'playlist', playlist_id)
|
||||
playlist = traverse_obj(meta, ('falcorCache', 'playList', playlist_id))
|
||||
|
||||
def entries():
|
||||
|
||||
Reference in New Issue
Block a user