mirror of
https://github.com/bolucat/Archive.git
synced 2026-04-22 16:07:49 +08:00
Update On Sat Mar 21 19:50:15 CET 2026
This commit is contained in:
@@ -1305,3 +1305,4 @@ Update On Tue Mar 17 20:16:34 CET 2026
|
||||
Update On Wed Mar 18 20:13:21 CET 2026
|
||||
Update On Thu Mar 19 20:11:34 CET 2026
|
||||
Update On Fri Mar 20 20:03:22 CET 2026
|
||||
Update On Sat Mar 21 19:50:06 CET 2026
|
||||
|
||||
+9
-9
@@ -12,19 +12,19 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout Repository
|
||||
uses: actions/checkout@v4
|
||||
uses: actions/checkout@v6
|
||||
|
||||
- name: Checkout submodules
|
||||
run: git submodule update --init --recursive --force
|
||||
|
||||
- name: Setup Java
|
||||
uses: actions/setup-java@v4
|
||||
uses: actions/setup-java@v5
|
||||
with:
|
||||
distribution: "temurin"
|
||||
java-version: 21
|
||||
|
||||
- name: Setup Gradle
|
||||
uses: gradle/actions/setup-gradle@v4
|
||||
uses: gradle/actions/setup-gradle@v5
|
||||
|
||||
- name: Setup Go
|
||||
uses: actions/setup-go@v6
|
||||
@@ -37,7 +37,7 @@ jobs:
|
||||
cd $(go env GOROOT)
|
||||
for p in $GITHUB_WORKSPACE/.github/patch/*.patch; do patch --verbose -p 1 < "$p"; done
|
||||
|
||||
- uses: actions/cache@v4
|
||||
- uses: actions/cache@v5
|
||||
with:
|
||||
path: |
|
||||
~/.cache/go-build
|
||||
@@ -71,7 +71,7 @@ jobs:
|
||||
run: ./gradlew --no-daemon app:assembleAlphaRelease
|
||||
|
||||
- name: Upload Aritfact (universal)
|
||||
uses: actions/upload-artifact@v4
|
||||
uses: actions/upload-artifact@v7
|
||||
if: ${{ success() }}
|
||||
with:
|
||||
name: CMFA Debug Unsigned APK (universal)
|
||||
@@ -79,7 +79,7 @@ jobs:
|
||||
app/build/outputs/apk/alpha/release/*-universal-*.apk
|
||||
|
||||
- name: Upload Aritfact (arm64-v8a)
|
||||
uses: actions/upload-artifact@v4
|
||||
uses: actions/upload-artifact@v7
|
||||
if: ${{ success() }}
|
||||
with:
|
||||
name: CMFA Debug Unsigned APK (arm64-v8a)
|
||||
@@ -87,7 +87,7 @@ jobs:
|
||||
app/build/outputs/apk/alpha/release/*-arm64-v8a-*.apk
|
||||
|
||||
- name: Upload Aritfact (armeabi-v7a)
|
||||
uses: actions/upload-artifact@v4
|
||||
uses: actions/upload-artifact@v7
|
||||
if: ${{ success() }}
|
||||
with:
|
||||
name: CMFA Debug Unsigned APK (armeabi-v7a)
|
||||
@@ -95,7 +95,7 @@ jobs:
|
||||
app/build/outputs/apk/alpha/release/*-armeabi-v7a-*.apk
|
||||
|
||||
- name: Upload Aritfact (x86_64)
|
||||
uses: actions/upload-artifact@v4
|
||||
uses: actions/upload-artifact@v7
|
||||
if: ${{ success() }}
|
||||
with:
|
||||
name: CMFA Debug Unsigned APK (x86_64)
|
||||
@@ -103,7 +103,7 @@ jobs:
|
||||
app/build/outputs/apk/alpha/release/*-x86_64-*.apk
|
||||
|
||||
- name: Upload Aritfact (x86)
|
||||
uses: actions/upload-artifact@v4
|
||||
uses: actions/upload-artifact@v7
|
||||
if: ${{ success() }}
|
||||
with:
|
||||
name: CMFA Debug Unsigned APK (x86)
|
||||
|
||||
@@ -10,19 +10,19 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout Repository
|
||||
uses: actions/checkout@v4
|
||||
uses: actions/checkout@v6
|
||||
|
||||
- name: Checkout submodules
|
||||
run: git submodule update --init --recursive --force
|
||||
|
||||
- name: Setup Java
|
||||
uses: actions/setup-java@v4
|
||||
uses: actions/setup-java@v5
|
||||
with:
|
||||
distribution: "temurin"
|
||||
java-version: 21
|
||||
|
||||
- name: Setup Gradle
|
||||
uses: gradle/actions/setup-gradle@v4
|
||||
uses: gradle/actions/setup-gradle@v5
|
||||
|
||||
- name: Setup Go
|
||||
uses: actions/setup-go@v6
|
||||
@@ -35,7 +35,7 @@ jobs:
|
||||
cd $(go env GOROOT)
|
||||
for p in $GITHUB_WORKSPACE/.github/patch/*.patch; do patch --verbose -p 1 < "$p"; done
|
||||
|
||||
- uses: actions/cache@v4
|
||||
- uses: actions/cache@v5
|
||||
with:
|
||||
path: |
|
||||
~/.cache/go-build
|
||||
|
||||
+4
-4
@@ -12,7 +12,7 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout Repository
|
||||
uses: actions/checkout@v4
|
||||
uses: actions/checkout@v6
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
@@ -20,13 +20,13 @@ jobs:
|
||||
run: git submodule update --init --recursive --force
|
||||
|
||||
- name: Setup Java
|
||||
uses: actions/setup-java@v4
|
||||
uses: actions/setup-java@v5
|
||||
with:
|
||||
distribution: "temurin"
|
||||
java-version: 21
|
||||
|
||||
- name: Setup Gradle
|
||||
uses: gradle/actions/setup-gradle@v4
|
||||
uses: gradle/actions/setup-gradle@v5
|
||||
|
||||
- name: Setup Go
|
||||
uses: actions/setup-go@v6
|
||||
@@ -39,7 +39,7 @@ jobs:
|
||||
cd $(go env GOROOT)
|
||||
for p in $GITHUB_WORKSPACE/.github/patch/*.patch; do patch --verbose -p 1 < "$p"; done
|
||||
|
||||
- uses: actions/cache@v4
|
||||
- uses: actions/cache@v5
|
||||
with:
|
||||
path: |
|
||||
~/.cache/go-build
|
||||
|
||||
@@ -10,13 +10,13 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout Repository
|
||||
uses: actions/checkout@v4
|
||||
uses: actions/checkout@v6
|
||||
|
||||
- name: Checkout and Update submodules
|
||||
run: git submodule update --init --recursive --remote --force
|
||||
|
||||
- name: Setup Java
|
||||
uses: actions/setup-java@v4
|
||||
uses: actions/setup-java@v5
|
||||
with:
|
||||
distribution: "temurin"
|
||||
java-version: 21
|
||||
@@ -32,7 +32,7 @@ jobs:
|
||||
cd $(go env GOROOT)
|
||||
for p in $GITHUB_WORKSPACE/.github/patch/*.patch; do patch --verbose -p 1 < "$p"; done
|
||||
|
||||
- uses: actions/cache@v4
|
||||
- uses: actions/cache@v5
|
||||
with:
|
||||
path: |
|
||||
~/.cache/go-build
|
||||
|
||||
+7
-7
@@ -155,7 +155,7 @@ jobs:
|
||||
- { goos: linux, goarch: amd64, goamd64: v3, output: amd64-v3-go120, goversion: '1.20' }
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v5
|
||||
- uses: actions/checkout@v6
|
||||
|
||||
- name: Set up Go
|
||||
if: ${{ matrix.jobs.goversion == '' }}
|
||||
@@ -386,7 +386,7 @@ jobs:
|
||||
shell: bash
|
||||
|
||||
- name: Archive production artifacts
|
||||
uses: actions/upload-artifact@v4
|
||||
uses: actions/upload-artifact@v7
|
||||
with:
|
||||
name: "${{ matrix.jobs.goos }}-${{ matrix.jobs.output }}"
|
||||
path: |
|
||||
@@ -405,7 +405,7 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Download all workflow run artifacts
|
||||
uses: actions/download-artifact@v4
|
||||
uses: actions/download-artifact@v8
|
||||
with:
|
||||
path: bin/
|
||||
merge-multiple: true
|
||||
@@ -463,7 +463,7 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v5
|
||||
uses: actions/checkout@v6
|
||||
with:
|
||||
ref: Meta
|
||||
fetch-depth: '0'
|
||||
@@ -498,7 +498,7 @@ jobs:
|
||||
bash ./genReleaseNote.sh -v ${PREVERSION}...${CURRENTVERSION}
|
||||
rm ./genReleaseNote.sh
|
||||
|
||||
- uses: actions/download-artifact@v4
|
||||
- uses: actions/download-artifact@v8
|
||||
with:
|
||||
path: bin/
|
||||
merge-multiple: true
|
||||
@@ -522,11 +522,11 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v5
|
||||
uses: actions/checkout@v6
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
- uses: actions/download-artifact@v4
|
||||
- uses: actions/download-artifact@v8
|
||||
with:
|
||||
path: bin/
|
||||
merge-multiple: true
|
||||
|
||||
+1
-1
@@ -42,7 +42,7 @@ jobs:
|
||||
# Fix mingw trying to be smart and converting paths https://github.com/moby/moby/issues/24029#issuecomment-250412919
|
||||
MSYS_NO_PATHCONV: true
|
||||
steps:
|
||||
- uses: actions/checkout@v5
|
||||
- uses: actions/checkout@v6
|
||||
|
||||
- name: Setup Go
|
||||
uses: actions/setup-go@v6
|
||||
|
||||
@@ -165,11 +165,10 @@ func (r *Resolver) ExchangeContext(ctx context.Context, m *D.Msg) (msg *D.Msg, e
|
||||
|
||||
q := m.Question[0]
|
||||
domain := msgToDomain(m)
|
||||
cacheM, expireTime, hit := r.cache.GetWithExpire(q.String())
|
||||
msg, expireTime, hit := getMsgFromCache(r.cache, q)
|
||||
if hit {
|
||||
log.Debugln("[DNS] cache hit %s --> %s, expire at %s", domain, msgToLogString(cacheM), expireTime.Format("2006-01-02 15:04:05"))
|
||||
log.Debugln("[DNS] cache hit %s --> %s, expire at %s", domain, msgToLogString(msg), expireTime.Format("2006-01-02 15:04:05"))
|
||||
now := time.Now()
|
||||
msg = cacheM.Copy()
|
||||
if expireTime.Before(now) {
|
||||
setMsgTTL(msg, uint32(1)) // Continue fetch
|
||||
continueFetch = true
|
||||
@@ -201,14 +200,8 @@ func (r *Resolver) exchangeWithoutCache(ctx context.Context, m *D.Msg) (msg *D.M
|
||||
return
|
||||
}
|
||||
|
||||
msg := result
|
||||
|
||||
if cache {
|
||||
// OPT RRs MUST NOT be cached, forwarded, or stored in or loaded from master files.
|
||||
msg.Extra = lo.Filter(msg.Extra, func(rr D.RR, index int) bool {
|
||||
return rr.Header().Rrtype != D.TypeOPT
|
||||
})
|
||||
putMsgToCache(r.cache, q.String(), q, msg)
|
||||
putMsgToCache(r.cache, q, result)
|
||||
}
|
||||
}()
|
||||
|
||||
|
||||
+23
-3
@@ -45,7 +45,19 @@ func updateTTL(records []D.RR, ttl uint32) {
|
||||
}
|
||||
}
|
||||
|
||||
func putMsgToCache(c dnsCache, key string, q D.Question, msg *D.Msg) {
|
||||
// getMsgFromCache returns a cached dns message if it exists, otherwise returns nil.
|
||||
// the returned msg is a copy of the original msg, so it can be modified without affecting the original msg.
|
||||
func getMsgFromCache(c dnsCache, q D.Question) (*D.Msg, time.Time, bool) {
|
||||
msg, expireTime, hit := c.GetWithExpire(q.String())
|
||||
if msg != nil {
|
||||
msg = msg.Copy() // never modify the original msg
|
||||
}
|
||||
return msg, expireTime, hit
|
||||
}
|
||||
|
||||
// putMsgToCache puts a dns message into the cache.
|
||||
// the msg is copied before being stored in the cache, so it can be modified without affecting the original msg.
|
||||
func putMsgToCache(c dnsCache, q D.Question, msg *D.Msg) {
|
||||
// skip dns cache for acme challenge
|
||||
if q.Qtype == D.TypeTXT && strings.HasPrefix(q.Name, "_acme-challenge.") {
|
||||
log.Debugln("[DNS] dns cache ignored because of acme challenge for: %s", q.Name)
|
||||
@@ -58,12 +70,20 @@ func putMsgToCache(c dnsCache, key string, q D.Question, msg *D.Msg) {
|
||||
// If it does so it MUST NOT cache it for longer than five (5) minutes [...]
|
||||
ttl = serverFailureCacheTTL
|
||||
} else {
|
||||
ttl = minimalTTL(append(append(msg.Answer, msg.Ns...), msg.Extra...))
|
||||
ttl = minimalTTL(lo.Concat(msg.Answer, msg.Ns, msg.Extra))
|
||||
}
|
||||
if ttl == 0 {
|
||||
return
|
||||
}
|
||||
c.SetWithExpire(key, msg.Copy(), time.Now().Add(time.Duration(ttl)*time.Second))
|
||||
|
||||
msg = msg.Copy() // never modify the original msg
|
||||
|
||||
// OPT RRs MUST NOT be cached, forwarded, or stored in or loaded from master files.
|
||||
msg.Extra = lo.Filter(msg.Extra, func(rr D.RR, index int) bool {
|
||||
return rr.Header().Rrtype != D.TypeOPT
|
||||
})
|
||||
|
||||
c.SetWithExpire(q.String(), msg, time.Now().Add(time.Duration(ttl)*time.Second))
|
||||
}
|
||||
|
||||
func setMsgTTL(msg *D.Msg, ttl uint32) {
|
||||
|
||||
+3
-3
@@ -60,10 +60,10 @@ body:
|
||||
attributes:
|
||||
label: 应用日志 / App logs
|
||||
description: |
|
||||
请确保您已移除所有敏感信息,并确保你的日志等级为 `Trace` 或 `Debug`。请参考 [FAQ - 日志目录](https://nyanpasu.elaina.moe/zh-CN/others/faq.html#_2-clash-nyanpasu-%E5%BA%94%E7%94%A8-%E6%97%A5%E8%AE%B0%E7%9B%AE%E5%BD%95%E5%9C%A8%E5%93%AA%E9%87%8C)
|
||||
请确保您已移除所有敏感信息,并确保你的日志等级为 `Trace` 或 `Debug`。请参考 [FAQ - 日志目录](https://nyanpasu.majokeiko.com/zh-CN/others/faq.html#_2-clash-nyanpasu-%E5%BA%94%E7%94%A8-%E6%97%A5%E8%AE%B0%E7%9B%AE%E5%BD%95%E5%9C%A8%E5%93%AA%E9%87%8C)
|
||||
如果您可以打开主界面,可以在设置页的“日志目录”旁找到“收集日志”按钮,点击即可收集日志。(1.5.0 不可用)
|
||||
如果日志过长,请使用 [Gist](https://gist.github.com/) 或 [Hastebin](https://hastebin.com/) 并附上链接。
|
||||
Please make sure you have removed all sensitive information and your log level is `Trace` or `Debug`. Please refer to [FAQ - Logs directory](https://nyanpasu.elaina.moe/others/faq.html#_2-where-is-the-clash-nyanpasu-application-logs-directory)
|
||||
Please make sure you have removed all sensitive information and your log level is `Trace` or `Debug`. Please refer to [FAQ - Logs directory](https://nyanpasu.majokeiko.com/others/faq.html#_2-where-is-the-clash-nyanpasu-application-logs-directory)
|
||||
If you can open the main interface, you can find the "Collect logs" button next to the "Open Logs Dir" in the settings page, click to collect the logs. (Not available in 1.5.0)
|
||||
If the log is too long, please use [Gist](https://gist.github.com/) or [Hastebin](https://hastebin.com/) and provide the link.
|
||||
placeholder: |
|
||||
@@ -149,7 +149,7 @@ body:
|
||||
required: false
|
||||
- label: 您已知悉如果没有提供正确的系统信息,以及日志,您的 Issue 会直接被关闭 / You have known that if you don't provide correct system information and logs, your issue will be closed directly
|
||||
required: true
|
||||
- label: 您已仔细查看并知情 [Q&A](https://nyanpasu.elaina.moe/zh-CN/others/issues) 和 [FAQ](https://nyanpasu.elaina.moe/zh-CN/others/faq) 中的内容 / You have read and understood the contents of [Q&A](https://nyanpasu.elaina.moe/others/issues) and [FAQ](https://nyanpasu.elaina.moe/others/faq)
|
||||
- label: 您已仔细查看并知情 [Q&A](https://nyanpasu.majokeiko.com/zh-CN/others/issues) 和 [FAQ](https://nyanpasu.majokeiko.com/zh-CN/others/faq) 中的内容 / You have read and understood the contents of [Q&A](https://nyanpasu.majokeiko.com/others/issues) and [FAQ](https://nyanpasu.majokeiko.com/others/faq)
|
||||
required: true
|
||||
|
||||
- label: 您已搜索过 [Issue Tracker](https://github.com/libnyanpasu/clash-nyanpasu/issues),没有找到类似内容 / I have searched on [Issue Tracker](https://github.com/libnyanpasu/clash-nyanpasu/issues), No duplicate or related open issue has been found
|
||||
|
||||
@@ -86,7 +86,7 @@ body:
|
||||
- label: 如果您有足够的时间和能力,并愿意为此提交 PR,请勾上此复选框 / Pull request is welcome. Check this if you want to start a pull request
|
||||
required: false
|
||||
|
||||
- label: 您已仔细查看并知情 [Q&A](https://nyanpasu.elaina.moe/zh-CN/others/issues) 中的内容 / You have checked [Q&A](https://nyanpasu.elaina.moe/others/issues) carefully
|
||||
- label: 您已仔细查看并知情 [Q&A](https://nyanpasu.majokeiko.com/zh-CN/others/issues) 中的内容 / You have checked [Q&A](https://nyanpasu.majokeiko.com/others/issues) carefully
|
||||
required: true
|
||||
|
||||
- label: 您已搜索过 [Issue Tracker](https://github.com/libnyanpasu/clash-nyanpasu/issues),没有找到类似内容 / I have searched on [Issue Tracker](https://github.com/libnyanpasu/clash-nyanpasu/issues), No duplicate or related open issue has been found
|
||||
|
||||
+144
-47
@@ -9,11 +9,15 @@ on:
|
||||
type: boolean
|
||||
default: false
|
||||
|
||||
fixed-webview:
|
||||
description: 'Fixed WebView'
|
||||
bundle-type:
|
||||
description: 'Bundle variant'
|
||||
required: true
|
||||
type: boolean
|
||||
default: false
|
||||
type: choice
|
||||
default: 'standard'
|
||||
options:
|
||||
- standard
|
||||
- fixed-webview
|
||||
- both
|
||||
|
||||
nightly:
|
||||
description: 'Nightly prepare'
|
||||
@@ -44,11 +48,11 @@ on:
|
||||
type: boolean
|
||||
default: false
|
||||
|
||||
fixed-webview:
|
||||
description: 'Fixed WebView'
|
||||
required: true
|
||||
type: boolean
|
||||
default: false
|
||||
bundle-type:
|
||||
description: 'Bundle variant: standard | fixed-webview | both'
|
||||
required: false
|
||||
type: string
|
||||
default: 'standard'
|
||||
|
||||
nightly:
|
||||
description: 'Nightly prepare'
|
||||
@@ -137,8 +141,114 @@ jobs:
|
||||
}
|
||||
}
|
||||
|
||||
- name: Build UI
|
||||
run: |
|
||||
pnpm -F ui build
|
||||
|
||||
- name: Set file server folder path
|
||||
if: ${{ inputs.nightly == true }}
|
||||
shell: bash
|
||||
run: |
|
||||
GIT_HASH=$(git rev-parse --short HEAD)
|
||||
echo "FOLDER_PATH=nightly/${GIT_HASH}" >> $GITHUB_ENV
|
||||
|
||||
- name: Prepare (Windows NSIS and Portable)
|
||||
if: ${{ inputs.bundle-type != 'fixed-webview' }}
|
||||
run: ${{ inputs.nightly == true && 'pnpm prepare:nightly --nsis' || 'pnpm prepare:release --nsis' }}
|
||||
|
||||
- name: Tauri build x86_64
|
||||
if: ${{ inputs.arch == 'x86_64' && inputs.bundle-type != 'fixed-webview' }}
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
TAURI_SIGNING_PRIVATE_KEY: ${{ secrets.TAURI_PRIVATE_KEY }}
|
||||
TAURI_SIGNING_PRIVATE_KEY_PASSWORD: ${{ secrets.TAURI_KEY_PASSWORD }}
|
||||
NIGHTLY: ${{ inputs.nightly == true && 'true' || 'false' }}
|
||||
run: |
|
||||
pnpm tauri build ${{ inputs.nightly == true && '-f nightly -c ./backend/tauri/tauri.nightly.conf.json' || '-f default-meta' }}
|
||||
|
||||
- name: Tauri build i686
|
||||
if: ${{ inputs.arch == 'i686' && inputs.bundle-type != 'fixed-webview' }}
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
TAURI_SIGNING_PRIVATE_KEY: ${{ secrets.TAURI_PRIVATE_KEY }}
|
||||
TAURI_SIGNING_PRIVATE_KEY_PASSWORD: ${{ secrets.TAURI_KEY_PASSWORD }}
|
||||
NIGHTLY: ${{ inputs.nightly == true && 'true' || 'false' }}
|
||||
run: |
|
||||
pnpm tauri build ${{ inputs.nightly == true && '-f nightly -c ./backend/tauri/tauri.nightly.conf.json --target i686-pc-windows-msvc' || '-f default-meta --target i686-pc-windows-msvc' }}
|
||||
|
||||
- name: Tauri build arm64
|
||||
if: ${{ inputs.arch == 'aarch64' && inputs.bundle-type != 'fixed-webview' }}
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
TAURI_SIGNING_PRIVATE_KEY: ${{ secrets.TAURI_PRIVATE_KEY }}
|
||||
TAURI_SIGNING_PRIVATE_KEY_PASSWORD: ${{ secrets.TAURI_KEY_PASSWORD }}
|
||||
NIGHTLY: ${{ inputs.nightly == true && 'true' || 'false' }}
|
||||
run: |
|
||||
pnpm tauri build ${{ inputs.nightly == true && '-f nightly -c ./backend/tauri/tauri.nightly.conf.json --target aarch64-pc-windows-msvc' || '-f default-meta --target aarch64-pc-windows-msvc' }}
|
||||
|
||||
- name: Portable Bundle
|
||||
if: ${{ inputs.portable == true && inputs.bundle-type != 'fixed-webview' }}
|
||||
run: |
|
||||
pnpm portable
|
||||
env:
|
||||
RUST_ARCH: ${{ inputs.arch }}
|
||||
TAG_NAME: ${{ inputs.tag }}
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
TAURI_SIGNING_PRIVATE_KEY: ${{ secrets.TAURI_PRIVATE_KEY }}
|
||||
TAURI_SIGNING_PRIVATE_KEY_PASSWORD: ${{ secrets.TAURI_KEY_PASSWORD }}
|
||||
NIGHTLY: ${{ inputs.nightly == true && 'true' || 'false' }}
|
||||
VITE_WIN_PORTABLE: 1
|
||||
|
||||
- name: Upload NSIS Installer
|
||||
if: ${{ inputs.bundle-type != 'fixed-webview' }}
|
||||
uses: actions/upload-artifact@v7
|
||||
with:
|
||||
name: Clash.Nyanpasu-windows-${{ inputs.arch }}-nsis-installer
|
||||
path: |
|
||||
./backend/target/**/bundle/**/*.exe
|
||||
./backend/target/**/bundle/**/*.zip
|
||||
./backend/target/**/bundle/**/*.zip.sig
|
||||
|
||||
- name: Upload portable
|
||||
if: ${{ inputs.portable == true && inputs.bundle-type != 'fixed-webview' }}
|
||||
uses: actions/upload-artifact@v7
|
||||
with:
|
||||
name: Clash.Nyanpasu-windows-${{ inputs.arch }}-portable
|
||||
path: |
|
||||
./*_portable.zip
|
||||
|
||||
- name: Upload to file server
|
||||
if: ${{ inputs.nightly == true && inputs.bundle-type != 'fixed-webview' }}
|
||||
shell: bash
|
||||
continue-on-error: true
|
||||
run: |
|
||||
deno run -A scripts/deno/upload-build-artifacts.ts \
|
||||
"backend/target/**/bundle/nsis/*.exe" \
|
||||
"*_portable.zip"
|
||||
env:
|
||||
FILE_SERVER_TOKEN: ${{ secrets.FILE_SERVER_TOKEN }}
|
||||
FOLDER_PATH: ${{ env.FOLDER_PATH }}
|
||||
|
||||
- name: Upload file server results
|
||||
if: ${{ inputs.nightly == true && inputs.bundle-type != 'fixed-webview' }}
|
||||
uses: actions/upload-artifact@v7
|
||||
with:
|
||||
name: upload-results-windows-${{ inputs.arch }}
|
||||
path: ./upload-results.json
|
||||
if-no-files-found: ignore
|
||||
|
||||
- name: Clean standard build outputs
|
||||
if: ${{ inputs.bundle-type == 'both' }}
|
||||
run: |
|
||||
Get-ChildItem -Path "./backend/target" -Recurse -Include "*.exe", "*.zip", "*.zip.sig" |
|
||||
Where-Object { $_.FullName -like "*\bundle\*" } |
|
||||
Remove-Item -Force -ErrorAction SilentlyContinue
|
||||
Get-ChildItem -Path "." -Filter "*_portable.zip" -ErrorAction SilentlyContinue |
|
||||
Remove-Item -Force
|
||||
Remove-Item -Path "./upload-results.json" -Force -ErrorAction SilentlyContinue
|
||||
|
||||
- name: Download fixed WebView
|
||||
if: ${{ inputs.fixed-webview == true }}
|
||||
if: ${{ inputs.bundle-type != 'standard' }}
|
||||
run: |
|
||||
$condition = '${{ inputs.arch }}'
|
||||
switch ($condition) {
|
||||
@@ -162,20 +272,12 @@ jobs:
|
||||
expand.exe $outfile -F:* ./backend/tauri
|
||||
echo "Extraction finished"
|
||||
|
||||
- name: Prepare (Windows NSIS and Portable)
|
||||
if: ${{ inputs.fixed-webview == false }}
|
||||
run: ${{ inputs.nightly == true && 'pnpm prepare:nightly --nsis' || 'pnpm prepare:release --nsis' }}
|
||||
|
||||
- name: Prepare (Windows NSIS and Portable) with fixed WebView
|
||||
if: ${{ inputs.fixed-webview == true }}
|
||||
if: ${{ inputs.bundle-type != 'standard' }}
|
||||
run: ${{ inputs.nightly == true && 'pnpm prepare:nightly --nsis --fixed-webview' || 'pnpm prepare:release --nsis --fixed-webview' }}
|
||||
|
||||
- name: Build UI
|
||||
run: |
|
||||
pnpm -F ui build
|
||||
# TODO: optimize strategy
|
||||
- name: Tauri build x86_64
|
||||
if: ${{ inputs.arch == 'x86_64' }}
|
||||
- name: Tauri build x86_64 with fixed WebView
|
||||
if: ${{ inputs.arch == 'x86_64' && inputs.bundle-type != 'standard' }}
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
TAURI_SIGNING_PRIVATE_KEY: ${{ secrets.TAURI_PRIVATE_KEY }}
|
||||
@@ -184,8 +286,8 @@ jobs:
|
||||
run: |
|
||||
pnpm tauri build ${{ inputs.nightly == true && '-f nightly -c ./backend/tauri/tauri.nightly.conf.json' || '-f default-meta' }}
|
||||
|
||||
- name: Tauri build i686
|
||||
if: ${{ inputs.arch == 'i686' }}
|
||||
- name: Tauri build i686 with fixed WebView
|
||||
if: ${{ inputs.arch == 'i686' && inputs.bundle-type != 'standard' }}
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
TAURI_SIGNING_PRIVATE_KEY: ${{ secrets.TAURI_PRIVATE_KEY }}
|
||||
@@ -193,8 +295,9 @@ jobs:
|
||||
NIGHTLY: ${{ inputs.nightly == true && 'true' || 'false' }}
|
||||
run: |
|
||||
pnpm tauri build ${{ inputs.nightly == true && '-f nightly -c ./backend/tauri/tauri.nightly.conf.json --target i686-pc-windows-msvc' || '-f default-meta --target i686-pc-windows-msvc' }}
|
||||
- name: Tauri build arm64
|
||||
if: ${{ inputs.arch == 'aarch64' }}
|
||||
|
||||
- name: Tauri build arm64 with fixed WebView
|
||||
if: ${{ inputs.arch == 'aarch64' && inputs.bundle-type != 'standard' }}
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
TAURI_SIGNING_PRIVATE_KEY: ${{ secrets.TAURI_PRIVATE_KEY }}
|
||||
@@ -204,7 +307,7 @@ jobs:
|
||||
pnpm tauri build ${{ inputs.nightly == true && '-f nightly -c ./backend/tauri/tauri.nightly.conf.json --target aarch64-pc-windows-msvc' || '-f default-meta --target aarch64-pc-windows-msvc' }}
|
||||
|
||||
- name: Rename fixed webview bundle name
|
||||
if: ${{ inputs.fixed-webview == true }}
|
||||
if: ${{ inputs.bundle-type != 'standard' }}
|
||||
run: |
|
||||
$files = Get-ChildItem -Path "./backend/target" -Recurse -Include "*.exe", "*.zip", "*.zip.sig" | Where-Object { $_.FullName -like "*\bundle\*" }
|
||||
$condition = '${{ inputs.arch }}'
|
||||
@@ -226,10 +329,10 @@ jobs:
|
||||
Rename-Item -Path $file -NewName $newname
|
||||
}
|
||||
|
||||
- name: Portable Bundle
|
||||
if: ${{ inputs.portable == true }}
|
||||
- name: Portable Bundle with fixed WebView
|
||||
if: ${{ inputs.portable == true && inputs.bundle-type != 'standard' }}
|
||||
run: |
|
||||
pnpm portable ${{ inputs.fixed-webview == true && '--fixed-webview' || '' }}
|
||||
pnpm portable --fixed-webview
|
||||
env:
|
||||
RUST_ARCH: ${{ inputs.arch }}
|
||||
TAG_NAME: ${{ inputs.tag }}
|
||||
@@ -239,46 +342,40 @@ jobs:
|
||||
NIGHTLY: ${{ inputs.nightly == true && 'true' || 'false' }}
|
||||
VITE_WIN_PORTABLE: 1
|
||||
|
||||
- name: Upload NSIS Installer
|
||||
- name: Upload NSIS Installer with fixed WebView
|
||||
if: ${{ inputs.bundle-type != 'standard' }}
|
||||
uses: actions/upload-artifact@v7
|
||||
with:
|
||||
name: Clash.Nyanpasu-windows-${{ inputs.arch }}${{ inputs.fixed-webview == true && '-fixed-webview' || '' }}-nsis-installer
|
||||
name: Clash.Nyanpasu-windows-${{ inputs.arch }}-fixed-webview-nsis-installer
|
||||
path: |
|
||||
./backend/target/**/bundle/**/*.exe
|
||||
./backend/target/**/bundle/**/*.zip
|
||||
./backend/target/**/bundle/**/*.zip.sig
|
||||
|
||||
- name: Upload portable
|
||||
if: ${{ inputs.portable == true }}
|
||||
- name: Upload portable with fixed WebView
|
||||
if: ${{ inputs.portable == true && inputs.bundle-type != 'standard' }}
|
||||
uses: actions/upload-artifact@v7
|
||||
with:
|
||||
name: Clash.Nyanpasu-windows-${{ inputs.arch }}${{ inputs.fixed-webview == true && '-fixed-webview' || '' }}-portable
|
||||
name: Clash.Nyanpasu-windows-${{ inputs.arch }}-fixed-webview-portable
|
||||
path: |
|
||||
./*_portable.zip
|
||||
|
||||
- name: Set file server folder path
|
||||
if: ${{ inputs.nightly == true }}
|
||||
shell: bash
|
||||
run: |
|
||||
GIT_HASH=$(git rev-parse --short HEAD)
|
||||
echo "FOLDER_PATH=nightly/${GIT_HASH}" >> $GITHUB_ENV
|
||||
|
||||
- name: Upload to file server
|
||||
if: ${{ inputs.nightly == true }}
|
||||
- name: Upload to file server with fixed WebView
|
||||
if: ${{ inputs.nightly == true && inputs.bundle-type != 'standard' }}
|
||||
shell: bash
|
||||
continue-on-error: true
|
||||
run: |
|
||||
deno run -A scripts/deno/upload-build-artifacts.ts \
|
||||
"backend/target/**/bundle/**/*.exe" \
|
||||
"backend/target/**/bundle/nsis/*.exe" \
|
||||
"*_portable.zip"
|
||||
env:
|
||||
FILE_SERVER_TOKEN: ${{ secrets.FILE_SERVER_TOKEN }}
|
||||
FOLDER_PATH: ${{ env.FOLDER_PATH }}
|
||||
|
||||
- name: Upload file server results
|
||||
if: ${{ inputs.nightly == true }}
|
||||
- name: Upload file server results with fixed WebView
|
||||
if: ${{ inputs.nightly == true && inputs.bundle-type != 'standard' }}
|
||||
uses: actions/upload-artifact@v7
|
||||
with:
|
||||
name: upload-results-windows-${{ inputs.arch }}${{ inputs.fixed-webview == true && '-fixed-webview' || '' }}
|
||||
name: upload-results-windows-${{ inputs.arch }}-fixed-webview
|
||||
path: ./upload-results.json
|
||||
if-no-files-found: ignore
|
||||
|
||||
@@ -91,7 +91,6 @@ jobs:
|
||||
- name: Upload updater to surge.sh
|
||||
run: |
|
||||
pnpm i -g surge
|
||||
surge manifest/site surge.elaina.moe
|
||||
surge manifest/site nyanpasu.surge.sh
|
||||
env:
|
||||
SURGE_TOKEN: ${{ secrets.SURGE_TOKEN }}
|
||||
|
||||
+3
-42
@@ -21,7 +21,7 @@ jobs:
|
||||
with:
|
||||
portable: true
|
||||
nightly: true
|
||||
fixed-webview: false
|
||||
bundle-type: 'both'
|
||||
arch: 'x86_64'
|
||||
tag: 'pre-release'
|
||||
secrets: inherit
|
||||
@@ -33,7 +33,7 @@ jobs:
|
||||
with:
|
||||
portable: true
|
||||
nightly: true
|
||||
fixed-webview: false
|
||||
bundle-type: 'both'
|
||||
arch: 'aarch64'
|
||||
tag: 'pre-release'
|
||||
secrets: inherit
|
||||
@@ -45,47 +45,11 @@ jobs:
|
||||
with:
|
||||
portable: true
|
||||
nightly: true
|
||||
fixed-webview: false
|
||||
bundle-type: 'both'
|
||||
arch: 'i686'
|
||||
tag: 'pre-release'
|
||||
secrets: inherit
|
||||
|
||||
windows_amd64_build_fixed_webview:
|
||||
name: Windows x86_64 Build with Fixed WebView
|
||||
if: ${{ github.event_name == 'workflow_dispatch' || startsWith(github.repository, 'libnyanpasu') }}
|
||||
uses: ./.github/workflows/deps-build-windows-nsis.yaml
|
||||
with:
|
||||
portable: true
|
||||
nightly: true
|
||||
arch: 'x86_64'
|
||||
fixed-webview: true
|
||||
tag: 'pre-release'
|
||||
secrets: inherit
|
||||
|
||||
windows_aarch64_build_fixed_webview:
|
||||
name: Windows aarch64 Build with Fixed WebView
|
||||
if: ${{ github.event_name == 'workflow_dispatch' || startsWith(github.repository, 'libnyanpasu') }}
|
||||
uses: ./.github/workflows/deps-build-windows-nsis.yaml
|
||||
with:
|
||||
portable: true
|
||||
nightly: true
|
||||
arch: 'aarch64'
|
||||
fixed-webview: true
|
||||
tag: 'pre-release'
|
||||
secrets: inherit
|
||||
|
||||
windows_i686_build_fixed_webview:
|
||||
name: Windows i686 Build with Fixed WebView
|
||||
if: ${{ github.event_name == 'workflow_dispatch' || startsWith(github.repository, 'libnyanpasu') }}
|
||||
uses: ./.github/workflows/deps-build-windows-nsis.yaml
|
||||
with:
|
||||
portable: true
|
||||
nightly: true
|
||||
arch: 'i686'
|
||||
fixed-webview: true
|
||||
tag: 'pre-release'
|
||||
secrets: inherit
|
||||
|
||||
linux_amd64_build:
|
||||
name: Linux amd64 Build
|
||||
if: ${{ github.event_name == 'workflow_dispatch' || startsWith(github.repository, 'libnyanpasu') }}
|
||||
@@ -163,9 +127,6 @@ jobs:
|
||||
windows_amd64_build,
|
||||
windows_i686_build,
|
||||
windows_aarch64_build,
|
||||
windows_amd64_build_fixed_webview,
|
||||
windows_i686_build_fixed_webview,
|
||||
windows_aarch64_build_fixed_webview,
|
||||
linux_amd64_build,
|
||||
linux_i686_build,
|
||||
linux_aarch64_build,
|
||||
|
||||
@@ -15,6 +15,7 @@ jobs:
|
||||
with:
|
||||
portable: true
|
||||
nightly: false
|
||||
bundle-type: 'both'
|
||||
tag: ${{ github.event.release.tag_name }}
|
||||
secrets: inherit
|
||||
|
||||
|
||||
@@ -60,7 +60,7 @@ representative at an online or offline event.
|
||||
|
||||
Instances of abusive, harassing, or otherwise unacceptable behavior may be
|
||||
reported to the community leaders responsible for enforcement at
|
||||
i@elaina.moe.
|
||||
i@majokeiko.com.
|
||||
All complaints will be reviewed and investigated promptly and fairly.
|
||||
|
||||
All community leaders are obligated to respect the privacy and security of the
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<h1 align="center">
|
||||
<img src="https://nyanpasu.elaina.moe/images/banner/nyanpasu_banner.png" alt="Clash Nyanpasu Banner" />
|
||||
<img src="https://nyanpasu.majokeiko.com/images/banner/nyanpasu_banner.png" alt="Clash Nyanpasu Banner" />
|
||||
</h1>
|
||||
|
||||
<h3>Clash Nyanpasu</h3>
|
||||
@@ -21,22 +21,22 @@
|
||||
## Features
|
||||
|
||||
- Built-in support [Clash Premium](https://github.com/Dreamacro/clash), [Mihomo](https://github.com/MetaCubeX/mihomo) & [Clash Rust](https://github.com/Watfaq/clash-rs).
|
||||
- Profiles management and enhancement (by YAML, JavaScript & Lua). [Doc](https://nyanpasu.elaina.moe/tutorial/proxy-chain)
|
||||
- Profiles management and enhancement (by YAML, JavaScript & Lua). [Doc](https://nyanpasu.majokeiko.com/tutorial/proxy-chain)
|
||||
- Provider management support.
|
||||
- Google Material You Design UI and animation support.
|
||||
|
||||
## Preview
|
||||
|
||||

|
||||

|
||||
|
||||

|
||||

|
||||
|
||||
## Links
|
||||
|
||||
- [Install](https://nyanpasu.elaina.moe/tutorial/install)
|
||||
- [FAQ](https://nyanpasu.elaina.moe/others/faq)
|
||||
- [Q&A Convention](https://nyanpasu.elaina.moe/others/issues)
|
||||
- [How To Ask Questions](https://nyanpasu.elaina.moe/others/how-to-ask)
|
||||
- [Install](https://nyanpasu.majokeiko.com/tutorial/install)
|
||||
- [FAQ](https://nyanpasu.majokeiko.com/others/faq)
|
||||
- [Q&A Convention](https://nyanpasu.majokeiko.com/others/issues)
|
||||
- [How To Ask Questions](https://nyanpasu.majokeiko.com/others/how-to-ask)
|
||||
|
||||
## Development
|
||||
|
||||
|
||||
@@ -11,7 +11,6 @@
|
||||
"plugins": {
|
||||
"updater": {
|
||||
"endpoints": [
|
||||
"https://deno.elaina.moe/updater/update-fixed-webview-proxy.json",
|
||||
"https://nyanpasu.surge.sh/updater/update-fixed-webview-proxy.json",
|
||||
"https://gh-proxy.com/https://github.com/libnyanpasu/clash-nyanpasu/releases/download/updater/update-fixed-webview-proxy.json",
|
||||
"https://github.com/libnyanpasu/clash-nyanpasu/releases/download/updater/update-fixed-webview.json"
|
||||
|
||||
@@ -5,7 +5,6 @@
|
||||
"updater": {
|
||||
"pubkey": "dW50cnVzdGVkIGNvbW1lbnQ6IG1pbmlzaWduIHB1YmxpYyBrZXk6IDlBMUM0NjMxREZCNDRGMjYKUldRbVQ3VGZNVVljbW43N0FlWjA4UkNrbTgxSWxSSXJQcExXNkZjUTlTQkIyYkJzL0tsSWF2d0cK",
|
||||
"endpoints": [
|
||||
"https://deno.elaina.moe/updater/update-nightly-proxy.json",
|
||||
"https://nyanpasu.surge.sh/updater/update-nightly-proxy.json",
|
||||
"https://gh-proxy.com/https://github.com/libnyanpasu/clash-nyanpasu/releases/download/updater/update-nightly-proxy.json",
|
||||
"https://github.com/libnyanpasu/clash-nyanpasu/releases/download/updater/update-nightly.json"
|
||||
|
||||
@@ -72,7 +72,6 @@
|
||||
"updater": {
|
||||
"pubkey": "dW50cnVzdGVkIGNvbW1lbnQ6IG1pbmlzaWduIHB1YmxpYyBrZXk6IDlBMUM0NjMxREZCNDRGMjYKUldRbVQ3VGZNVVljbW43N0FlWjA4UkNrbTgxSWxSSXJQcExXNkZjUTlTQkIyYkJzL0tsSWF2d0cK",
|
||||
"endpoints": [
|
||||
"https://deno.elaina.moe/updater/update-proxy.json",
|
||||
"https://nyanpasu.surge.sh/updater/update-proxy.json",
|
||||
"https://gh-proxy.com/https://github.com/libnyanpasu/clash-nyanpasu/releases/download/updater/update-proxy.json",
|
||||
"https://github.com/libnyanpasu/clash-nyanpasu/releases/download/updater/update.json"
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
// nyanpasu merge profile chain template
|
||||
const merge = `# Clash Nyanpasu Merge Template (YAML)
|
||||
# Documentation on https://nyanpasu.elaina.moe/
|
||||
# Documentation on https://nyanpasu.majokeiko.com/
|
||||
# Set the default merge strategy to recursive merge.
|
||||
# Enable the old mode with the override__ prefix.
|
||||
# Use the filter__ prefix to filter lists (removing unwanted content).
|
||||
@@ -9,7 +9,7 @@ const merge = `# Clash Nyanpasu Merge Template (YAML)
|
||||
|
||||
// nyanpasu javascript profile chain template
|
||||
const javascript = `// Clash Nyanpasu JavaScript Template
|
||||
// Documentation on https://nyanpasu.elaina.moe/
|
||||
// Documentation on https://nyanpasu.majokeiko.com/
|
||||
|
||||
/** @type {config} */
|
||||
export default function (profile) {
|
||||
@@ -19,14 +19,14 @@ export default function (profile) {
|
||||
|
||||
// nyanpasu lua profile chain template
|
||||
const luascript = `-- Clash Nyanpasu Lua Script Template
|
||||
-- Documentation on https://nyanpasu.elaina.moe/
|
||||
-- Documentation on https://nyanpasu.majokeiko.com/
|
||||
|
||||
return config;
|
||||
`
|
||||
|
||||
// clash profile template example
|
||||
const profile = `# Clash Nyanpasu Profile Template
|
||||
# Documentation on https://nyanpasu.elaina.moe/
|
||||
# Documentation on https://nyanpasu.majokeiko.com/
|
||||
|
||||
proxies:
|
||||
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
"@dnd-kit/utilities": "3.2.2",
|
||||
"@emotion/styled": "11.14.1",
|
||||
"@hookform/resolvers": "5.2.2",
|
||||
"@inlang/paraglide-js": "2.15.0",
|
||||
"@inlang/paraglide-js": "2.15.1",
|
||||
"@juggle/resize-observer": "3.4.0",
|
||||
"@material/material-color-utilities": "0.4.0",
|
||||
"@mui/icons-material": "7.3.9",
|
||||
@@ -43,7 +43,7 @@
|
||||
"country-emoji": "1.5.6",
|
||||
"dayjs": "1.11.20",
|
||||
"framer-motion": "12.38.0",
|
||||
"i18next": "25.8.20",
|
||||
"i18next": "25.9.0",
|
||||
"jotai": "2.18.1",
|
||||
"json-schema": "0.4.0",
|
||||
"material-react-table": "3.2.1",
|
||||
@@ -69,7 +69,7 @@
|
||||
"@csstools/normalize.css": "12.1.1",
|
||||
"@emotion/babel-plugin": "11.13.5",
|
||||
"@emotion/react": "11.14.0",
|
||||
"@iconify/json": "2.2.452",
|
||||
"@iconify/json": "2.2.453",
|
||||
"@monaco-editor/react": "4.7.0",
|
||||
"@tanstack/react-query": "5.91.3",
|
||||
"@tanstack/react-router": "1.167.5",
|
||||
|
||||
@@ -1,55 +1,55 @@
|
||||
{
|
||||
"default": {
|
||||
"proxies": "https://nyanpasu.elaina.moe/others/field.html#proxies",
|
||||
"proxy-groups": "https://nyanpasu.elaina.moe/others/field.html#proxy-groups",
|
||||
"proxy-providers": "https://nyanpasu.elaina.moe/others/field.html#proxy-providers",
|
||||
"rules": "https://nyanpasu.elaina.moe/others/field.html#rules",
|
||||
"rule-providers": "https://nyanpasu.elaina.moe/others/field.html#rule-providers"
|
||||
"proxies": "https://nyanpasu.majokeiko.com/others/field.html#proxies",
|
||||
"proxy-groups": "https://nyanpasu.majokeiko.com/others/field.html#proxy-groups",
|
||||
"proxy-providers": "https://nyanpasu.majokeiko.com/others/field.html#proxy-providers",
|
||||
"rules": "https://nyanpasu.majokeiko.com/others/field.html#rules",
|
||||
"rule-providers": "https://nyanpasu.majokeiko.com/others/field.html#rule-providers"
|
||||
},
|
||||
"handle": {
|
||||
"mode": "https://nyanpasu.elaina.moe/others/field.html#mode",
|
||||
"port": "https://nyanpasu.elaina.moe/others/field.html#port",
|
||||
"socks-port": "https://nyanpasu.elaina.moe/others/field.html#socks-port",
|
||||
"mixed-port": "https://nyanpasu.elaina.moe/others/field.html#mixed-port",
|
||||
"allow-lan": "https://nyanpasu.elaina.moe/others/field.html#allow-lan",
|
||||
"log-level": "https://nyanpasu.elaina.moe/others/field.html#log-level",
|
||||
"ipv6": "https://nyanpasu.elaina.moe/others/field.html#ipv6",
|
||||
"secret": "https://nyanpasu.elaina.moe/others/field.html#secret",
|
||||
"external-controller": "https://nyanpasu.elaina.moe/others/field.html#external-controller"
|
||||
"mode": "https://nyanpasu.majokeiko.com/others/field.html#mode",
|
||||
"port": "https://nyanpasu.majokeiko.com/others/field.html#port",
|
||||
"socks-port": "https://nyanpasu.majokeiko.com/others/field.html#socks-port",
|
||||
"mixed-port": "https://nyanpasu.majokeiko.com/others/field.html#mixed-port",
|
||||
"allow-lan": "https://nyanpasu.majokeiko.com/others/field.html#allow-lan",
|
||||
"log-level": "https://nyanpasu.majokeiko.com/others/field.html#log-level",
|
||||
"ipv6": "https://nyanpasu.majokeiko.com/others/field.html#ipv6",
|
||||
"secret": "https://nyanpasu.majokeiko.com/others/field.html#secret",
|
||||
"external-controller": "https://nyanpasu.majokeiko.com/others/field.html#external-controller"
|
||||
},
|
||||
"other": {
|
||||
"dns": "https://nyanpasu.elaina.moe/others/field.html#dns",
|
||||
"tun": "https://nyanpasu.elaina.moe/others/field.html#tun",
|
||||
"ebpf": "https://nyanpasu.elaina.moe/others/field.html#ebpf",
|
||||
"hosts": "https://nyanpasu.elaina.moe/others/field.html#hosts",
|
||||
"script": "https://nyanpasu.elaina.moe/others/field.html#script",
|
||||
"profile": "https://nyanpasu.elaina.moe/others/field.html#profile",
|
||||
"payload": "https://nyanpasu.elaina.moe/others/field.html#payload",
|
||||
"tunnels": "https://nyanpasu.elaina.moe/others/field.html#tunnels",
|
||||
"auto-redir": "https://nyanpasu.elaina.moe/others/field.html#auto-redir",
|
||||
"experimental": "https://nyanpasu.elaina.moe/others/field.html#experimental",
|
||||
"interface-name": "https://nyanpasu.elaina.moe/others/field.html#interface-name",
|
||||
"routing-mark": "https://nyanpasu.elaina.moe/others/field.html#routing-mark",
|
||||
"redir-port": "https://nyanpasu.elaina.moe/others/field.html#redir-port",
|
||||
"tproxy-port": "https://nyanpasu.elaina.moe/others/field.html#tproxy-port",
|
||||
"iptables": "https://nyanpasu.elaina.moe/others/field.html#iptables",
|
||||
"external-ui": "https://nyanpasu.elaina.moe/others/field.html#external-ui",
|
||||
"bind-address": "https://nyanpasu.elaina.moe/others/field.html#bind-address",
|
||||
"authentication": "https://nyanpasu.elaina.moe/others/field.html#authentication"
|
||||
"dns": "https://nyanpasu.majokeiko.com/others/field.html#dns",
|
||||
"tun": "https://nyanpasu.majokeiko.com/others/field.html#tun",
|
||||
"ebpf": "https://nyanpasu.majokeiko.com/others/field.html#ebpf",
|
||||
"hosts": "https://nyanpasu.majokeiko.com/others/field.html#hosts",
|
||||
"script": "https://nyanpasu.majokeiko.com/others/field.html#script",
|
||||
"profile": "https://nyanpasu.majokeiko.com/others/field.html#profile",
|
||||
"payload": "https://nyanpasu.majokeiko.com/others/field.html#payload",
|
||||
"tunnels": "https://nyanpasu.majokeiko.com/others/field.html#tunnels",
|
||||
"auto-redir": "https://nyanpasu.majokeiko.com/others/field.html#auto-redir",
|
||||
"experimental": "https://nyanpasu.majokeiko.com/others/field.html#experimental",
|
||||
"interface-name": "https://nyanpasu.majokeiko.com/others/field.html#interface-name",
|
||||
"routing-mark": "https://nyanpasu.majokeiko.com/others/field.html#routing-mark",
|
||||
"redir-port": "https://nyanpasu.majokeiko.com/others/field.html#redir-port",
|
||||
"tproxy-port": "https://nyanpasu.majokeiko.com/others/field.html#tproxy-port",
|
||||
"iptables": "https://nyanpasu.majokeiko.com/others/field.html#iptables",
|
||||
"external-ui": "https://nyanpasu.majokeiko.com/others/field.html#external-ui",
|
||||
"bind-address": "https://nyanpasu.majokeiko.com/others/field.html#bind-address",
|
||||
"authentication": "https://nyanpasu.majokeiko.com/others/field.html#authentication"
|
||||
},
|
||||
"meta": {
|
||||
"tls": "https://nyanpasu.elaina.moe/others/field.html#tls",
|
||||
"sniffer": "https://nyanpasu.elaina.moe/others/field.html#sniffer",
|
||||
"geox-url": "https://nyanpasu.elaina.moe/others/field.html#geox-url",
|
||||
"listeners": "https://nyanpasu.elaina.moe/others/field.html#listeners",
|
||||
"sub-rules": "https://nyanpasu.elaina.moe/others/field.html#sub-rules",
|
||||
"geodata-mode": "https://nyanpasu.elaina.moe/others/field.html#geodata-mode",
|
||||
"unified-delay": "https://nyanpasu.elaina.moe/others/field.html#unified-delay",
|
||||
"tcp-concurrent": "https://nyanpasu.elaina.moe/others/field.html#tcp-concurrent",
|
||||
"enable-process": "https://nyanpasu.elaina.moe/others/field.html#enable-process",
|
||||
"find-process-mode": "https://nyanpasu.elaina.moe/others/field.html#find-process-mode",
|
||||
"skip-auth-prefixes": "https://nyanpasu.elaina.moe/others/field.html#skip-auth-prefixes",
|
||||
"external-controller-tls": "https://nyanpasu.elaina.moe/others/field.html#external-controller-tls",
|
||||
"global-client-fingerprint": "https://nyanpasu.elaina.moe/others/field.html#global-client-fingerprint"
|
||||
"tls": "https://nyanpasu.majokeiko.com/others/field.html#tls",
|
||||
"sniffer": "https://nyanpasu.majokeiko.com/others/field.html#sniffer",
|
||||
"geox-url": "https://nyanpasu.majokeiko.com/others/field.html#geox-url",
|
||||
"listeners": "https://nyanpasu.majokeiko.com/others/field.html#listeners",
|
||||
"sub-rules": "https://nyanpasu.majokeiko.com/others/field.html#sub-rules",
|
||||
"geodata-mode": "https://nyanpasu.majokeiko.com/others/field.html#geodata-mode",
|
||||
"unified-delay": "https://nyanpasu.majokeiko.com/others/field.html#unified-delay",
|
||||
"tcp-concurrent": "https://nyanpasu.majokeiko.com/others/field.html#tcp-concurrent",
|
||||
"enable-process": "https://nyanpasu.majokeiko.com/others/field.html#enable-process",
|
||||
"find-process-mode": "https://nyanpasu.majokeiko.com/others/field.html#find-process-mode",
|
||||
"skip-auth-prefixes": "https://nyanpasu.majokeiko.com/others/field.html#skip-auth-prefixes",
|
||||
"external-controller-tls": "https://nyanpasu.majokeiko.com/others/field.html#external-controller-tls",
|
||||
"global-client-fingerprint": "https://nyanpasu.majokeiko.com/others/field.html#global-client-fingerprint"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
declare const classNames: {
|
||||
readonly item: 'item'
|
||||
readonly shiki: 'shiki'
|
||||
readonly dark: 'dark'
|
||||
}
|
||||
export default classNames
|
||||
@@ -13,7 +13,7 @@ import { Link } from '@tanstack/react-router'
|
||||
|
||||
const WikiItem = () => {
|
||||
const handleClick = useLockFn(async () => {
|
||||
await commands.openThat('https://nyanpasu.elaina.moe')
|
||||
await commands.openThat('https://nyanpasu.majokeiko.com')
|
||||
})
|
||||
|
||||
return (
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
"manifest_version": 1,
|
||||
"latest": {
|
||||
"mihomo": "v1.19.21",
|
||||
"mihomo_alpha": "alpha-dd4eb63",
|
||||
"mihomo_alpha": "alpha-ae374f6",
|
||||
"clash_rs": "v0.9.6",
|
||||
"clash_premium": "2023-09-05-gdcc8d87",
|
||||
"clash_rs_alpha": "0.9.6-alpha+sha.b17ba0a"
|
||||
@@ -69,5 +69,5 @@
|
||||
"linux-armv7hf": "clash-rs-armv7-unknown-linux-gnueabihf"
|
||||
}
|
||||
},
|
||||
"updated_at": "2026-03-19T22:22:44.922Z"
|
||||
"updated_at": "2026-03-20T22:22:49.611Z"
|
||||
}
|
||||
|
||||
@@ -68,7 +68,7 @@
|
||||
"cross-env": "10.1.0",
|
||||
"dedent": "1.7.2",
|
||||
"globals": "17.4.0",
|
||||
"knip": "5.88.1",
|
||||
"knip": "6.0.1",
|
||||
"lint-staged": "16.4.0",
|
||||
"npm-run-all2": "8.0.4",
|
||||
"oxlint": "1.56.0",
|
||||
|
||||
Generated
+276
-49
@@ -59,8 +59,8 @@ importers:
|
||||
specifier: 17.4.0
|
||||
version: 17.4.0
|
||||
knip:
|
||||
specifier: 5.88.1
|
||||
version: 5.88.1(@types/node@24.11.0)(typescript@5.9.3)
|
||||
specifier: 6.0.1
|
||||
version: 6.0.1
|
||||
lint-staged:
|
||||
specifier: 16.4.0
|
||||
version: 16.4.0
|
||||
@@ -183,8 +183,8 @@ importers:
|
||||
specifier: 5.2.2
|
||||
version: 5.2.2(react-hook-form@7.71.2(react@19.2.4))
|
||||
'@inlang/paraglide-js':
|
||||
specifier: 2.15.0
|
||||
version: 2.15.0(babel-plugin-macros@3.1.0)
|
||||
specifier: 2.15.1
|
||||
version: 2.15.1(babel-plugin-macros@3.1.0)
|
||||
'@juggle/resize-observer':
|
||||
specifier: 3.4.0
|
||||
version: 3.4.0
|
||||
@@ -261,8 +261,8 @@ importers:
|
||||
specifier: 12.38.0
|
||||
version: 12.38.0(@emotion/is-prop-valid@1.3.0)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)
|
||||
i18next:
|
||||
specifier: 25.8.20
|
||||
version: 25.8.20(typescript@5.9.3)
|
||||
specifier: 25.9.0
|
||||
version: 25.9.0(typescript@5.9.3)
|
||||
jotai:
|
||||
specifier: 2.18.1
|
||||
version: 2.18.1(@babel/core@7.29.0)(@babel/template@7.28.6)(@types/react@19.2.14)(react@19.2.4)
|
||||
@@ -301,7 +301,7 @@ importers:
|
||||
version: 8.2.0(e309558cb1df3652b39c2e76ceb9cee4)
|
||||
react-i18next:
|
||||
specifier: 15.7.4
|
||||
version: 15.7.4(i18next@25.8.20(typescript@5.9.3))(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(typescript@5.9.3)
|
||||
version: 15.7.4(i18next@25.9.0(typescript@5.9.3))(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(typescript@5.9.3)
|
||||
react-markdown:
|
||||
specifier: 10.1.0
|
||||
version: 10.1.0(@types/react@19.2.14)(react@19.2.4)
|
||||
@@ -334,8 +334,8 @@ importers:
|
||||
specifier: 11.14.0
|
||||
version: 11.14.0(@types/react@19.2.14)(react@19.2.4)
|
||||
'@iconify/json':
|
||||
specifier: 2.2.452
|
||||
version: 2.2.452
|
||||
specifier: 2.2.453
|
||||
version: 2.2.453
|
||||
'@monaco-editor/react':
|
||||
specifier: 4.7.0
|
||||
version: 4.7.0(monaco-editor@0.55.1)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)
|
||||
@@ -500,7 +500,7 @@ importers:
|
||||
version: 6.0.0(react@19.2.4)
|
||||
react-i18next:
|
||||
specifier: 15.7.4
|
||||
version: 15.7.4(i18next@25.8.20(typescript@5.9.3))(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(typescript@5.9.3)
|
||||
version: 15.7.4(i18next@25.9.0(typescript@5.9.3))(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(typescript@5.9.3)
|
||||
react-use:
|
||||
specifier: 17.6.0
|
||||
version: 17.6.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4)
|
||||
@@ -1704,8 +1704,8 @@ packages:
|
||||
prettier-plugin-ember-template-tag:
|
||||
optional: true
|
||||
|
||||
'@iconify/json@2.2.452':
|
||||
resolution: {integrity: sha512-3gUSKSQ3UHRpuvk0GL5WdD3n+WR9MhvxjJ3cFjoBb44kD8yKC/esyxeOZfXdilRmJFvs1y8+j5DM6SIwCtMbXw==}
|
||||
'@iconify/json@2.2.453':
|
||||
resolution: {integrity: sha512-LL3avJyZUFtB/Ts1WbpunFZ58XnodcQn0xMLQbm9gxuuZNpnt2D89n+CstNHpqheynDz+nZVSSvKko1bFXBOTA==}
|
||||
|
||||
'@iconify/types@2.0.0':
|
||||
resolution: {integrity: sha512-+wluvCrRhXrhyOmRDJ3q8mux9JkKy5SJ/v8ol2tu4FVjyYvtEzkc/3pK15ET6RKg4b4w4BmTk1+gsCUhf21Ykg==}
|
||||
@@ -1713,16 +1713,16 @@ packages:
|
||||
'@iconify/utils@3.1.0':
|
||||
resolution: {integrity: sha512-Zlzem1ZXhI1iHeeERabLNzBHdOa4VhQbqAcOQaMKuTuyZCpwKbC2R4Dd0Zo3g9EAc+Y4fiarO8HIHRAth7+skw==}
|
||||
|
||||
'@inlang/paraglide-js@2.15.0':
|
||||
resolution: {integrity: sha512-2ZOa9nssVn4tjkKskqb88KP5A7cTIjo8AiM9xnPvH+vBhRIRenO+ftAbVOHhHcHjcFxy2QFcOfBAH/Cw1LIsUg==}
|
||||
'@inlang/paraglide-js@2.15.1':
|
||||
resolution: {integrity: sha512-7wWKbLWwLx1dkkYz55TnVp+39atKXf7rnlHnL8adSmM73UaAdB9fXDzo24GHSY/6FPGFKSkgHdT2qyJv2whWsA==}
|
||||
hasBin: true
|
||||
|
||||
'@inlang/recommend-sherlock@0.2.1':
|
||||
resolution: {integrity: sha512-ckv8HvHy/iTqaVAEKrr+gnl+p3XFNwe5D2+6w6wJk2ORV2XkcRkKOJ/XsTUJbPSiyi4PI+p+T3bqbmNx/rDUlg==}
|
||||
|
||||
'@inlang/sdk@2.8.0':
|
||||
resolution: {integrity: sha512-w1jysvUDTMgCaONklIgOJAp9dUDl0UhLbsdqfWEwY/GIqoc9IwpuHsrP3pzC+h3DfOpkMMDnDkTpPv8kIZ98iA==}
|
||||
engines: {node: '>=18.0.0'}
|
||||
'@inlang/sdk@2.9.1':
|
||||
resolution: {integrity: sha512-y0C3xaKo6pSGDr3p5OdreRVT3THJpgKVe1lLvG3BE4v9lskp3UfI9cPCbN8X2dpfLt/4ljtehMb5SykpMfJrMg==}
|
||||
engines: {node: '>=20.0.0'}
|
||||
|
||||
'@isaacs/fs-minipass@4.0.1':
|
||||
resolution: {integrity: sha512-wgm9Ehl2jpeqP3zw/7mo3kRHFp5MEDhqAdwy1fTGkHAwnkGOVsgpvQhL8B5n1qlb01jV3n/bI0ZfZp5lWA1k4w==}
|
||||
@@ -1762,8 +1762,8 @@ packages:
|
||||
'@keyv/serialize@1.1.1':
|
||||
resolution: {integrity: sha512-dXn3FZhPv0US+7dtJsIi2R+c7qWYiReoEh5zUntWCf4oSpMNib8FDhSoed6m3QyZdx5hK7iLFkYk3rNxwt8vTA==}
|
||||
|
||||
'@lix-js/sdk@0.4.7':
|
||||
resolution: {integrity: sha512-pRbW+joG12L0ULfMiWYosIW0plmW4AsUdiPCp+Z8rAsElJ+wJ6in58zhD3UwUcd4BNcpldEGjg6PdA7e0RgsDQ==}
|
||||
'@lix-js/sdk@0.4.9':
|
||||
resolution: {integrity: sha512-30mDkXpx704359oRrJI42bjfCspCiaMItngVBbPkiTGypS7xX4jYbHWQkXI8XuJ7VDB69D0MsVU6xfrBAIrM4A==}
|
||||
engines: {node: '>=18'}
|
||||
|
||||
'@lix-js/server-protocol-schema@0.1.1':
|
||||
@@ -2232,42 +2232,91 @@ packages:
|
||||
resolution: {integrity: sha512-16TtZXNOfH8RaRsV+iag5dTYeJvdOdZDBcpEPCULdKS3eTRJqAYxBNZPFaDJ3cx3WNyvbaQ0IxsPpnaR/tgGFA==}
|
||||
engines: {node: '>= 20'}
|
||||
|
||||
'@oxc-parser/binding-android-arm-eabi@0.120.0':
|
||||
resolution: {integrity: sha512-WU3qtINx802wOl8RxAF1v0VvmC2O4D9M8Sv486nLeQ7iPHVmncYZrtBhB4SYyX+XZxj2PNnCcN+PW21jHgiOxg==}
|
||||
engines: {node: ^20.19.0 || >=22.12.0}
|
||||
cpu: [arm]
|
||||
os: [android]
|
||||
|
||||
'@oxc-parser/binding-android-arm64@0.120.0':
|
||||
resolution: {integrity: sha512-SEf80EHdhlbjZEgzeWm0ZA/br4GKMenDW3QB/gtyeTV1gStvvZeFi40ioHDZvds2m4Z9J1bUAUL8yn1/+A6iGg==}
|
||||
engines: {node: ^20.19.0 || >=22.12.0}
|
||||
cpu: [arm64]
|
||||
os: [android]
|
||||
|
||||
'@oxc-parser/binding-android-arm64@0.99.0':
|
||||
resolution: {integrity: sha512-V4jhmKXgQQdRnm73F+r3ZY4pUEsijQeSraFeaCGng7abSNJGs76X6l82wHnmjLGFAeY00LWtjcELs7ZmbJ9+lA==}
|
||||
engines: {node: ^20.19.0 || >=22.12.0}
|
||||
cpu: [arm64]
|
||||
os: [android]
|
||||
|
||||
'@oxc-parser/binding-darwin-arm64@0.120.0':
|
||||
resolution: {integrity: sha512-xVrrbCai8R8CUIBu3CjryutQnEYhZqs1maIqDvtUCFZb8vY33H7uh9mHpL3a0JBIKoBUKjPH8+rzyAeXnS2d6A==}
|
||||
engines: {node: ^20.19.0 || >=22.12.0}
|
||||
cpu: [arm64]
|
||||
os: [darwin]
|
||||
|
||||
'@oxc-parser/binding-darwin-arm64@0.99.0':
|
||||
resolution: {integrity: sha512-Rp41nf9zD5FyLZciS9l1GfK8PhYqrD5kEGxyTOA2esTLeAy37rZxetG2E3xteEolAkeb2WDkVrlxPtibeAncMg==}
|
||||
engines: {node: ^20.19.0 || >=22.12.0}
|
||||
cpu: [arm64]
|
||||
os: [darwin]
|
||||
|
||||
'@oxc-parser/binding-darwin-x64@0.120.0':
|
||||
resolution: {integrity: sha512-xyHBbnJ6mydnQUH7MAcafOkkrNzQC6T+LXgDH/3InEq2BWl/g424IMRiJVSpVqGjB+p2bd0h0WRR8iIwzjU7rw==}
|
||||
engines: {node: ^20.19.0 || >=22.12.0}
|
||||
cpu: [x64]
|
||||
os: [darwin]
|
||||
|
||||
'@oxc-parser/binding-darwin-x64@0.99.0':
|
||||
resolution: {integrity: sha512-WVonp40fPPxo5Gs0POTI57iEFv485TvNKOHMwZRhigwZRhZY2accEAkYIhei9eswF4HN5B44Wybkz7Gd1Qr/5Q==}
|
||||
engines: {node: ^20.19.0 || >=22.12.0}
|
||||
cpu: [x64]
|
||||
os: [darwin]
|
||||
|
||||
'@oxc-parser/binding-freebsd-x64@0.120.0':
|
||||
resolution: {integrity: sha512-UMnVRllquXUYTeNfFKmxTTEdZ/ix1nLl0ducDzMSREoWYGVIHnOOxoKMWlCOvRr9Wk/HZqo2rh1jeumbPGPV9A==}
|
||||
engines: {node: ^20.19.0 || >=22.12.0}
|
||||
cpu: [x64]
|
||||
os: [freebsd]
|
||||
|
||||
'@oxc-parser/binding-freebsd-x64@0.99.0':
|
||||
resolution: {integrity: sha512-H30bjOOttPmG54gAqu6+HzbLEzuNOYO2jZYrIq4At+NtLJwvNhXz28Hf5iEAFZIH/4hMpLkM4VN7uc+5UlNW3Q==}
|
||||
engines: {node: ^20.19.0 || >=22.12.0}
|
||||
cpu: [x64]
|
||||
os: [freebsd]
|
||||
|
||||
'@oxc-parser/binding-linux-arm-gnueabihf@0.120.0':
|
||||
resolution: {integrity: sha512-tkvn2CQ7QdcsMnpfiX3fd3wA3EFsWKYlcQzq9cFw/xc89Al7W6Y4O0FgLVkVQpo0Tnq/qtE1XfkJOnRRA9S/NA==}
|
||||
engines: {node: ^20.19.0 || >=22.12.0}
|
||||
cpu: [arm]
|
||||
os: [linux]
|
||||
|
||||
'@oxc-parser/binding-linux-arm-gnueabihf@0.99.0':
|
||||
resolution: {integrity: sha512-0Z/Th0SYqzSRDPs6tk5lQdW0i73UCupnim3dgq2oW0//UdLonV/5wIZCArfKGC7w9y4h8TxgXpgtIyD1kKzzlQ==}
|
||||
engines: {node: ^20.19.0 || >=22.12.0}
|
||||
cpu: [arm]
|
||||
os: [linux]
|
||||
|
||||
'@oxc-parser/binding-linux-arm-musleabihf@0.120.0':
|
||||
resolution: {integrity: sha512-WN5y135Ic42gQDk9grbwY9++fDhqf8knN6fnP+0WALlAUh4odY/BDK1nfTJRSfpJD9P3r1BwU0m3pW2DU89whQ==}
|
||||
engines: {node: ^20.19.0 || >=22.12.0}
|
||||
cpu: [arm]
|
||||
os: [linux]
|
||||
|
||||
'@oxc-parser/binding-linux-arm-musleabihf@0.99.0':
|
||||
resolution: {integrity: sha512-xo0wqNd5bpbzQVNpAIFbHk1xa+SaS/FGBABCd942SRTnrpxl6GeDj/s1BFaGcTl8MlwlKVMwOcyKrw/2Kdfquw==}
|
||||
engines: {node: ^20.19.0 || >=22.12.0}
|
||||
cpu: [arm]
|
||||
os: [linux]
|
||||
|
||||
'@oxc-parser/binding-linux-arm64-gnu@0.120.0':
|
||||
resolution: {integrity: sha512-1GgQBCcXvFMw99EPdMy+4NZ3aYyXsxjf9kbUUg8HuAy3ZBXzOry5KfFEzT9nqmgZI1cuetvApkiJBZLAPo8uaw==}
|
||||
engines: {node: ^20.19.0 || >=22.12.0}
|
||||
cpu: [arm64]
|
||||
os: [linux]
|
||||
libc: [glibc]
|
||||
|
||||
'@oxc-parser/binding-linux-arm64-gnu@0.99.0':
|
||||
resolution: {integrity: sha512-u26I6LKoLTPTd4Fcpr0aoAtjnGf5/ulMllo+QUiBhupgbVCAlaj4RyXH/mvcjcsl2bVBv9E/gYJZz2JjxQWXBA==}
|
||||
engines: {node: ^20.19.0 || >=22.12.0}
|
||||
@@ -2275,6 +2324,13 @@ packages:
|
||||
os: [linux]
|
||||
libc: [glibc]
|
||||
|
||||
'@oxc-parser/binding-linux-arm64-musl@0.120.0':
|
||||
resolution: {integrity: sha512-gmMQ70gsPdDBgpcErvJEoWNBr7bJooSLlvOBVBSGfOzlP5NvJ3bFvnUeZZ9d+dPrqSngtonf7nyzWUTUj/U+lw==}
|
||||
engines: {node: ^20.19.0 || >=22.12.0}
|
||||
cpu: [arm64]
|
||||
os: [linux]
|
||||
libc: [musl]
|
||||
|
||||
'@oxc-parser/binding-linux-arm64-musl@0.99.0':
|
||||
resolution: {integrity: sha512-qhftDo2D37SqCEl3ZTa367NqWSZNb1Ddp34CTmShLKFrnKdNiUn55RdokLnHtf1AL5ssaQlYDwBECX7XiBWOhw==}
|
||||
engines: {node: ^20.19.0 || >=22.12.0}
|
||||
@@ -2282,6 +2338,20 @@ packages:
|
||||
os: [linux]
|
||||
libc: [musl]
|
||||
|
||||
'@oxc-parser/binding-linux-ppc64-gnu@0.120.0':
|
||||
resolution: {integrity: sha512-T/kZuU0ajop0xhzVMwH5r3srC9Nqup5HaIo+3uFjIN5uPxa0LvSxC1ZqP4aQGJVW5G0z8/nCkjIfSMS91P/wzw==}
|
||||
engines: {node: ^20.19.0 || >=22.12.0}
|
||||
cpu: [ppc64]
|
||||
os: [linux]
|
||||
libc: [glibc]
|
||||
|
||||
'@oxc-parser/binding-linux-riscv64-gnu@0.120.0':
|
||||
resolution: {integrity: sha512-vn21KXLAXzaI3N5CZWlBr1iWeXLl9QFIMor7S1hUjUGTeUuWCoE6JZB040/ZNDwf+JXPX8Ao9KbmJq9FMC2iGw==}
|
||||
engines: {node: ^20.19.0 || >=22.12.0}
|
||||
cpu: [riscv64]
|
||||
os: [linux]
|
||||
libc: [glibc]
|
||||
|
||||
'@oxc-parser/binding-linux-riscv64-gnu@0.99.0':
|
||||
resolution: {integrity: sha512-zxn/xkf519f12FKkpL5XwJipsylfSSnm36h6c1zBDTz4fbIDMGyIhHfWfwM7uUmHo9Aqw1pLxFpY39Etv398+Q==}
|
||||
engines: {node: ^20.19.0 || >=22.12.0}
|
||||
@@ -2289,6 +2359,20 @@ packages:
|
||||
os: [linux]
|
||||
libc: [glibc]
|
||||
|
||||
'@oxc-parser/binding-linux-riscv64-musl@0.120.0':
|
||||
resolution: {integrity: sha512-SUbUxlar007LTGmSLGIC5x/WJvwhdX+PwNzFJ9f/nOzZOrCFbOT4ikt7pJIRg1tXVsEfzk5mWpGO1NFiSs4PIw==}
|
||||
engines: {node: ^20.19.0 || >=22.12.0}
|
||||
cpu: [riscv64]
|
||||
os: [linux]
|
||||
libc: [musl]
|
||||
|
||||
'@oxc-parser/binding-linux-s390x-gnu@0.120.0':
|
||||
resolution: {integrity: sha512-hYiPJTxyfJY2+lMBFk3p2bo0R9GN+TtpPFlRqVchL1qvLG+pznstramHNvJlw9AjaoRUHwp9IKR7UZQnRPGjgQ==}
|
||||
engines: {node: ^20.19.0 || >=22.12.0}
|
||||
cpu: [s390x]
|
||||
os: [linux]
|
||||
libc: [glibc]
|
||||
|
||||
'@oxc-parser/binding-linux-s390x-gnu@0.99.0':
|
||||
resolution: {integrity: sha512-Y1eSDKDS5E4IVC7Oxw+NbYAKRmJPMJTIjW+9xOWwteDHkFqpocKe0USxog+Q1uhzalD9M0p9eXWEWdGQCMDBMQ==}
|
||||
engines: {node: ^20.19.0 || >=22.12.0}
|
||||
@@ -2296,6 +2380,13 @@ packages:
|
||||
os: [linux]
|
||||
libc: [glibc]
|
||||
|
||||
'@oxc-parser/binding-linux-x64-gnu@0.120.0':
|
||||
resolution: {integrity: sha512-q+5jSVZkprJCIy3dzJpApat0InJaoxQLsJuD6DkX8hrUS61z2lHQ1Fe9L2+TYbKHXCLWbL0zXe7ovkIdopBGMQ==}
|
||||
engines: {node: ^20.19.0 || >=22.12.0}
|
||||
cpu: [x64]
|
||||
os: [linux]
|
||||
libc: [glibc]
|
||||
|
||||
'@oxc-parser/binding-linux-x64-gnu@0.99.0':
|
||||
resolution: {integrity: sha512-YVJMfk5cFWB8i2/nIrbk6n15bFkMHqWnMIWkVx7r2KwpTxHyFMfu2IpeVKo1ITDSmt5nBrGdLHD36QRlu2nDLg==}
|
||||
engines: {node: ^20.19.0 || >=22.12.0}
|
||||
@@ -2303,6 +2394,13 @@ packages:
|
||||
os: [linux]
|
||||
libc: [glibc]
|
||||
|
||||
'@oxc-parser/binding-linux-x64-musl@0.120.0':
|
||||
resolution: {integrity: sha512-D9QDDZNnH24e7X4ftSa6ar/2hCavETfW3uk0zgcMIrZNy459O5deTbWrjGzZiVrSWigGtlQwzs2McBP0QsfV1w==}
|
||||
engines: {node: ^20.19.0 || >=22.12.0}
|
||||
cpu: [x64]
|
||||
os: [linux]
|
||||
libc: [musl]
|
||||
|
||||
'@oxc-parser/binding-linux-x64-musl@0.99.0':
|
||||
resolution: {integrity: sha512-2+SDPrie5f90A1b9EirtVggOgsqtsYU5raZwkDYKyS1uvJzjqHCDhG/f4TwQxHmIc5YkczdQfwvN91lwmjsKYQ==}
|
||||
engines: {node: ^20.19.0 || >=22.12.0}
|
||||
@@ -2310,23 +2408,55 @@ packages:
|
||||
os: [linux]
|
||||
libc: [musl]
|
||||
|
||||
'@oxc-parser/binding-openharmony-arm64@0.120.0':
|
||||
resolution: {integrity: sha512-TBU8ZwOUWAOUWVfmI16CYWbvh4uQb9zHnGBHsw5Cp2JUVG044OIY1CSHODLifqzQIMTXvDvLzcL89GGdUIqNrA==}
|
||||
engines: {node: ^20.19.0 || >=22.12.0}
|
||||
cpu: [arm64]
|
||||
os: [openharmony]
|
||||
|
||||
'@oxc-parser/binding-wasm32-wasi@0.120.0':
|
||||
resolution: {integrity: sha512-WG/FOZgDJCpJnuF3ToG/K28rcOmSY7FmFmfBKYb2fmLyhDzPpUldFGV7/Fz4ru0Iz/v4KPmf8xVgO8N3lO4KHA==}
|
||||
engines: {node: '>=14.0.0'}
|
||||
cpu: [wasm32]
|
||||
|
||||
'@oxc-parser/binding-wasm32-wasi@0.99.0':
|
||||
resolution: {integrity: sha512-DKA4j0QerUWSMADziLM5sAyM7V53Fj95CV9SjP77bPfEfT7MnvFKnneaRMqPK1cpzjAGiQF52OBUIKyk0dwOQA==}
|
||||
engines: {node: '>=14.0.0'}
|
||||
cpu: [wasm32]
|
||||
|
||||
'@oxc-parser/binding-win32-arm64-msvc@0.120.0':
|
||||
resolution: {integrity: sha512-1T0HKGcsz/BKo77t7+89L8Qvu4f9DoleKWHp3C5sJEcbCjDOLx3m9m722bWZTY+hANlUEs+yjlK+lBFsA+vrVQ==}
|
||||
engines: {node: ^20.19.0 || >=22.12.0}
|
||||
cpu: [arm64]
|
||||
os: [win32]
|
||||
|
||||
'@oxc-parser/binding-win32-arm64-msvc@0.99.0':
|
||||
resolution: {integrity: sha512-EaB3AvsxqdNUhh9FOoAxRZ2L4PCRwDlDb//QXItwyOJrX7XS+uGK9B1KEUV4FZ/7rDhHsWieLt5e07wl2Ti5AQ==}
|
||||
engines: {node: ^20.19.0 || >=22.12.0}
|
||||
cpu: [arm64]
|
||||
os: [win32]
|
||||
|
||||
'@oxc-parser/binding-win32-ia32-msvc@0.120.0':
|
||||
resolution: {integrity: sha512-L7vfLzbOXsjBXV0rv/6Y3Jd9BRjPeCivINZAqrSyAOZN3moCopDN+Psq9ZrGNZtJzP8946MtlRFZ0Als0wBCOw==}
|
||||
engines: {node: ^20.19.0 || >=22.12.0}
|
||||
cpu: [ia32]
|
||||
os: [win32]
|
||||
|
||||
'@oxc-parser/binding-win32-x64-msvc@0.120.0':
|
||||
resolution: {integrity: sha512-ys+upfqNtSu58huAhJMBKl3XCkGzyVFBlMlGPzHeFKgpFF/OdgNs1MMf8oaJIbgMH8ZxgGF7qfue39eJohmKIg==}
|
||||
engines: {node: ^20.19.0 || >=22.12.0}
|
||||
cpu: [x64]
|
||||
os: [win32]
|
||||
|
||||
'@oxc-parser/binding-win32-x64-msvc@0.99.0':
|
||||
resolution: {integrity: sha512-sJN1Q8h7ggFOyDn0zsHaXbP/MklAVUvhrbq0LA46Qum686P3SZQHjbATqJn9yaVEvaSKXCshgl0vQ1gWkGgpcQ==}
|
||||
engines: {node: ^20.19.0 || >=22.12.0}
|
||||
cpu: [x64]
|
||||
os: [win32]
|
||||
|
||||
'@oxc-project/types@0.120.0':
|
||||
resolution: {integrity: sha512-k1YNu55DuvAip/MGE1FTsIuU3FUCn6v/ujG9V7Nq5Df/kX2CWb13hhwD0lmJGMGqE+bE1MXvv9SZVnMzEXlWcg==}
|
||||
|
||||
'@oxc-project/types@0.99.0':
|
||||
resolution: {integrity: sha512-LLDEhXB7g1m5J+woRSgfKsFPS3LhR9xRhTeIoEBm5WrkwMxn6eZ0Ld0c0K5eHB57ChZX6I3uSmmLjZ8pcjlRcw==}
|
||||
|
||||
@@ -5538,6 +5668,9 @@ packages:
|
||||
get-tsconfig@4.10.1:
|
||||
resolution: {integrity: sha512-auHyJ4AgMz7vgS8Hp3N6HXSmlMdUyhSUrfBF16w153rxtLIEOE+HGqaBppczZvnHLqQJfiHotCYpNhl0lUROFQ==}
|
||||
|
||||
get-tsconfig@4.13.6:
|
||||
resolution: {integrity: sha512-shZT/QMiSHc/YBLxxOkMtgSid5HFoauqCE3/exfsEcwg1WkeqjG+V40yBbBrsD+jW2HDXcs28xOfcbm2jI8Ddw==}
|
||||
|
||||
git-raw-commits@5.0.1:
|
||||
resolution: {integrity: sha512-Y+csSm2GD/PCSh6Isd/WiMjNAydu0VBiG9J7EdQsNA5P9uXvLayqjmTsNlK5Gs9IhblFZqOU0yid5Il5JPoLiQ==}
|
||||
engines: {node: '>=18'}
|
||||
@@ -5664,8 +5797,8 @@ packages:
|
||||
hyphenate-style-name@1.1.0:
|
||||
resolution: {integrity: sha512-WDC/ui2VVRrz3jOVi+XtjqkDjiVjTtFaAGiW37k6b+ohyQ5wYDOGkvCZa8+H0nx3gyvv0+BST9xuOgIyGQ00gw==}
|
||||
|
||||
i18next@25.8.20:
|
||||
resolution: {integrity: sha512-xjo9+lbX/P1tQt3xpO2rfJiBppNfUnNIPKgCvNsTKsvTOCro1Qr/geXVg1N47j5ScOSaXAPq8ET93raK3Rr06A==}
|
||||
i18next@25.9.0:
|
||||
resolution: {integrity: sha512-mJ4rVRNWOTkqh5xnaGR6iMFT5vEw3Y2MTJhcjinR/7u8cRv6dAfC0ofuePh5fVPxoh395p6JdrJTStCcNW66gg==}
|
||||
peerDependencies:
|
||||
typescript: ^5
|
||||
peerDependenciesMeta:
|
||||
@@ -5946,13 +6079,10 @@ packages:
|
||||
resolution: {integrity: sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==}
|
||||
engines: {node: '>=0.10.0'}
|
||||
|
||||
knip@5.88.1:
|
||||
resolution: {integrity: sha512-tpy5o7zu1MjawVkLPuahymVJekYY3kYjvzcoInhIchgePxTlo+api90tBv2KfhAIe5uXh+mez1tAfmbv8/TiZg==}
|
||||
engines: {node: '>=18.18.0'}
|
||||
knip@6.0.1:
|
||||
resolution: {integrity: sha512-qk5m+w6IYEqfRG5546DXZJYl5AXsgFfDD6ULaDvkubqNtLye79sokBg3usURrWFjASMeQtvX19TfldU3jHkMNA==}
|
||||
engines: {node: ^20.19.0 || >=22.12.0}
|
||||
hasBin: true
|
||||
peerDependencies:
|
||||
'@types/node': '>=18'
|
||||
typescript: '>=5.0.4 <7'
|
||||
|
||||
known-css-properties@0.37.0:
|
||||
resolution: {integrity: sha512-JCDrsP4Z1Sb9JwG0aJ8Eo2r7k4Ou5MwmThS/6lcIe1ICyb7UBJKGRIUUdqc2ASdE/42lgz6zFUnzAIhtXnBVrQ==}
|
||||
@@ -5960,9 +6090,9 @@ packages:
|
||||
kolorist@1.8.0:
|
||||
resolution: {integrity: sha512-Y+60/zizpJ3HRH8DCss+q95yr6145JXZo46OTpFvDZWLfRCE4qChOyk1b26nMaNpfHHgxagk9dXT5OP0Tfe+dQ==}
|
||||
|
||||
kysely@0.27.6:
|
||||
resolution: {integrity: sha512-FIyV/64EkKhJmjgC0g2hygpBv5RNWVPyNCqSAD7eTCv6eFWNIi4PN1UvdSJGicN/o35bnevgis4Y0UDC0qi8jQ==}
|
||||
engines: {node: '>=14.0.0'}
|
||||
kysely@0.28.14:
|
||||
resolution: {integrity: sha512-SU3lgh0rPvq7upc6vvdVrCsSMUG1h3ChvHVOY7wJ2fw4C9QEB7X3d5eyYEyULUX7UQtxZJtZXGuT6U2US72UYA==}
|
||||
engines: {node: '>=20.0.0'}
|
||||
|
||||
less@4.2.0:
|
||||
resolution: {integrity: sha512-P3b3HJDBtSzsXUl0im2L7gTO5Ubg8mEN6G8qoTS77iXxXX4Hvu4Qj540PZDvQ8V6DmX6iXo98k7Md0Cm1PrLaA==}
|
||||
@@ -6454,6 +6584,10 @@ packages:
|
||||
resolution: {integrity: sha512-7x81NCL719oNbsq/3mh+hVrAWmFuEYUqrq/Iw3kUzH8ReypT9QQ0BLoJS7/G9k6N81XjW4qHWtjWwe/9eLy1EQ==}
|
||||
engines: {node: '>=12'}
|
||||
|
||||
oxc-parser@0.120.0:
|
||||
resolution: {integrity: sha512-WyPWZlcIm+Fkte63FGfgFB8mAAk33aH9h5N9lphXVOHSXEBFFsmYdOBedVKly363aWABjZdaj/m9lBfEY4wt+w==}
|
||||
engines: {node: ^20.19.0 || >=22.12.0}
|
||||
|
||||
oxc-parser@0.99.0:
|
||||
resolution: {integrity: sha512-MpS1lbd2vR0NZn1v0drpgu7RUFu3x9Rd0kxExObZc2+F+DIrV0BOMval/RO3BYGwssIOerII6iS8EbbpCCZQpQ==}
|
||||
engines: {node: ^20.19.0 || >=22.12.0}
|
||||
@@ -9356,7 +9490,7 @@ snapshots:
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
|
||||
'@iconify/json@2.2.452':
|
||||
'@iconify/json@2.2.453':
|
||||
dependencies:
|
||||
'@iconify/types': 2.0.0
|
||||
pathe: 2.0.3
|
||||
@@ -9369,10 +9503,10 @@ snapshots:
|
||||
'@iconify/types': 2.0.0
|
||||
mlly: 1.8.0
|
||||
|
||||
'@inlang/paraglide-js@2.15.0(babel-plugin-macros@3.1.0)':
|
||||
'@inlang/paraglide-js@2.15.1(babel-plugin-macros@3.1.0)':
|
||||
dependencies:
|
||||
'@inlang/recommend-sherlock': 0.2.1
|
||||
'@inlang/sdk': 2.8.0(babel-plugin-macros@3.1.0)
|
||||
'@inlang/sdk': 2.9.1(babel-plugin-macros@3.1.0)
|
||||
commander: 11.1.0
|
||||
consola: 3.4.0
|
||||
json5: 2.2.3
|
||||
@@ -9385,12 +9519,12 @@ snapshots:
|
||||
dependencies:
|
||||
comment-json: 4.5.0
|
||||
|
||||
'@inlang/sdk@2.8.0(babel-plugin-macros@3.1.0)':
|
||||
'@inlang/sdk@2.9.1(babel-plugin-macros@3.1.0)':
|
||||
dependencies:
|
||||
'@lix-js/sdk': 0.4.7(babel-plugin-macros@3.1.0)
|
||||
'@lix-js/sdk': 0.4.9(babel-plugin-macros@3.1.0)
|
||||
'@sinclair/typebox': 0.31.28
|
||||
kysely: 0.27.6
|
||||
sqlite-wasm-kysely: 0.3.0(kysely@0.27.6)
|
||||
kysely: 0.28.14
|
||||
sqlite-wasm-kysely: 0.3.0(kysely@0.28.14)
|
||||
uuid: 13.0.0
|
||||
transitivePeerDependencies:
|
||||
- babel-plugin-macros
|
||||
@@ -9435,14 +9569,14 @@ snapshots:
|
||||
|
||||
'@keyv/serialize@1.1.1': {}
|
||||
|
||||
'@lix-js/sdk@0.4.7(babel-plugin-macros@3.1.0)':
|
||||
'@lix-js/sdk@0.4.9(babel-plugin-macros@3.1.0)':
|
||||
dependencies:
|
||||
'@lix-js/server-protocol-schema': 0.1.1
|
||||
dedent: 1.5.1(babel-plugin-macros@3.1.0)
|
||||
human-id: 4.1.3
|
||||
js-sha256: 0.11.1
|
||||
kysely: 0.27.6
|
||||
sqlite-wasm-kysely: 0.3.0(kysely@0.27.6)
|
||||
kysely: 0.28.14
|
||||
sqlite-wasm-kysely: 0.3.0(kysely@0.28.14)
|
||||
uuid: 10.0.0
|
||||
transitivePeerDependencies:
|
||||
- babel-plugin-macros
|
||||
@@ -9989,53 +10123,117 @@ snapshots:
|
||||
'@octokit/request-error': 7.0.2
|
||||
'@octokit/webhooks-methods': 6.0.0
|
||||
|
||||
'@oxc-parser/binding-android-arm-eabi@0.120.0':
|
||||
optional: true
|
||||
|
||||
'@oxc-parser/binding-android-arm64@0.120.0':
|
||||
optional: true
|
||||
|
||||
'@oxc-parser/binding-android-arm64@0.99.0':
|
||||
optional: true
|
||||
|
||||
'@oxc-parser/binding-darwin-arm64@0.120.0':
|
||||
optional: true
|
||||
|
||||
'@oxc-parser/binding-darwin-arm64@0.99.0':
|
||||
optional: true
|
||||
|
||||
'@oxc-parser/binding-darwin-x64@0.120.0':
|
||||
optional: true
|
||||
|
||||
'@oxc-parser/binding-darwin-x64@0.99.0':
|
||||
optional: true
|
||||
|
||||
'@oxc-parser/binding-freebsd-x64@0.120.0':
|
||||
optional: true
|
||||
|
||||
'@oxc-parser/binding-freebsd-x64@0.99.0':
|
||||
optional: true
|
||||
|
||||
'@oxc-parser/binding-linux-arm-gnueabihf@0.120.0':
|
||||
optional: true
|
||||
|
||||
'@oxc-parser/binding-linux-arm-gnueabihf@0.99.0':
|
||||
optional: true
|
||||
|
||||
'@oxc-parser/binding-linux-arm-musleabihf@0.120.0':
|
||||
optional: true
|
||||
|
||||
'@oxc-parser/binding-linux-arm-musleabihf@0.99.0':
|
||||
optional: true
|
||||
|
||||
'@oxc-parser/binding-linux-arm64-gnu@0.120.0':
|
||||
optional: true
|
||||
|
||||
'@oxc-parser/binding-linux-arm64-gnu@0.99.0':
|
||||
optional: true
|
||||
|
||||
'@oxc-parser/binding-linux-arm64-musl@0.120.0':
|
||||
optional: true
|
||||
|
||||
'@oxc-parser/binding-linux-arm64-musl@0.99.0':
|
||||
optional: true
|
||||
|
||||
'@oxc-parser/binding-linux-ppc64-gnu@0.120.0':
|
||||
optional: true
|
||||
|
||||
'@oxc-parser/binding-linux-riscv64-gnu@0.120.0':
|
||||
optional: true
|
||||
|
||||
'@oxc-parser/binding-linux-riscv64-gnu@0.99.0':
|
||||
optional: true
|
||||
|
||||
'@oxc-parser/binding-linux-riscv64-musl@0.120.0':
|
||||
optional: true
|
||||
|
||||
'@oxc-parser/binding-linux-s390x-gnu@0.120.0':
|
||||
optional: true
|
||||
|
||||
'@oxc-parser/binding-linux-s390x-gnu@0.99.0':
|
||||
optional: true
|
||||
|
||||
'@oxc-parser/binding-linux-x64-gnu@0.120.0':
|
||||
optional: true
|
||||
|
||||
'@oxc-parser/binding-linux-x64-gnu@0.99.0':
|
||||
optional: true
|
||||
|
||||
'@oxc-parser/binding-linux-x64-musl@0.120.0':
|
||||
optional: true
|
||||
|
||||
'@oxc-parser/binding-linux-x64-musl@0.99.0':
|
||||
optional: true
|
||||
|
||||
'@oxc-parser/binding-openharmony-arm64@0.120.0':
|
||||
optional: true
|
||||
|
||||
'@oxc-parser/binding-wasm32-wasi@0.120.0':
|
||||
dependencies:
|
||||
'@napi-rs/wasm-runtime': 1.1.1
|
||||
optional: true
|
||||
|
||||
'@oxc-parser/binding-wasm32-wasi@0.99.0':
|
||||
dependencies:
|
||||
'@napi-rs/wasm-runtime': 1.0.7
|
||||
optional: true
|
||||
|
||||
'@oxc-parser/binding-win32-arm64-msvc@0.120.0':
|
||||
optional: true
|
||||
|
||||
'@oxc-parser/binding-win32-arm64-msvc@0.99.0':
|
||||
optional: true
|
||||
|
||||
'@oxc-parser/binding-win32-ia32-msvc@0.120.0':
|
||||
optional: true
|
||||
|
||||
'@oxc-parser/binding-win32-x64-msvc@0.120.0':
|
||||
optional: true
|
||||
|
||||
'@oxc-parser/binding-win32-x64-msvc@0.99.0':
|
||||
optional: true
|
||||
|
||||
'@oxc-project/types@0.120.0': {}
|
||||
|
||||
'@oxc-project/types@0.99.0': {}
|
||||
|
||||
'@oxc-resolver/binding-android-arm-eabi@11.19.1':
|
||||
@@ -13155,6 +13353,10 @@ snapshots:
|
||||
dependencies:
|
||||
resolve-pkg-maps: 1.0.0
|
||||
|
||||
get-tsconfig@4.13.6:
|
||||
dependencies:
|
||||
resolve-pkg-maps: 1.0.0
|
||||
|
||||
git-raw-commits@5.0.1(conventional-commits-parser@6.3.0):
|
||||
dependencies:
|
||||
'@conventional-changelog/git-client': 2.6.0(conventional-commits-parser@6.3.0)
|
||||
@@ -13315,7 +13517,7 @@ snapshots:
|
||||
|
||||
hyphenate-style-name@1.1.0: {}
|
||||
|
||||
i18next@25.8.20(typescript@5.9.3):
|
||||
i18next@25.9.0(typescript@5.9.3):
|
||||
dependencies:
|
||||
'@babel/runtime': 7.28.6
|
||||
optionalDependencies:
|
||||
@@ -13519,20 +13721,20 @@ snapshots:
|
||||
|
||||
kind-of@6.0.3: {}
|
||||
|
||||
knip@5.88.1(@types/node@24.11.0)(typescript@5.9.3):
|
||||
knip@6.0.1:
|
||||
dependencies:
|
||||
'@nodelib/fs.walk': 1.2.8
|
||||
'@types/node': 24.11.0
|
||||
fast-glob: 3.3.3
|
||||
formatly: 0.3.0
|
||||
get-tsconfig: 4.13.6
|
||||
jiti: 2.6.1
|
||||
minimist: 1.2.8
|
||||
oxc-parser: 0.120.0
|
||||
oxc-resolver: 11.19.1
|
||||
picocolors: 1.1.1
|
||||
picomatch: 4.0.3
|
||||
smol-toml: 1.6.0
|
||||
strip-json-comments: 5.0.3
|
||||
typescript: 5.9.3
|
||||
unbash: 2.2.0
|
||||
yaml: 2.8.2
|
||||
zod: 4.3.6
|
||||
@@ -13541,7 +13743,7 @@ snapshots:
|
||||
|
||||
kolorist@1.8.0: {}
|
||||
|
||||
kysely@0.27.6: {}
|
||||
kysely@0.28.14: {}
|
||||
|
||||
less@4.2.0:
|
||||
dependencies:
|
||||
@@ -14170,6 +14372,31 @@ snapshots:
|
||||
is-docker: 2.2.1
|
||||
is-wsl: 2.2.0
|
||||
|
||||
oxc-parser@0.120.0:
|
||||
dependencies:
|
||||
'@oxc-project/types': 0.120.0
|
||||
optionalDependencies:
|
||||
'@oxc-parser/binding-android-arm-eabi': 0.120.0
|
||||
'@oxc-parser/binding-android-arm64': 0.120.0
|
||||
'@oxc-parser/binding-darwin-arm64': 0.120.0
|
||||
'@oxc-parser/binding-darwin-x64': 0.120.0
|
||||
'@oxc-parser/binding-freebsd-x64': 0.120.0
|
||||
'@oxc-parser/binding-linux-arm-gnueabihf': 0.120.0
|
||||
'@oxc-parser/binding-linux-arm-musleabihf': 0.120.0
|
||||
'@oxc-parser/binding-linux-arm64-gnu': 0.120.0
|
||||
'@oxc-parser/binding-linux-arm64-musl': 0.120.0
|
||||
'@oxc-parser/binding-linux-ppc64-gnu': 0.120.0
|
||||
'@oxc-parser/binding-linux-riscv64-gnu': 0.120.0
|
||||
'@oxc-parser/binding-linux-riscv64-musl': 0.120.0
|
||||
'@oxc-parser/binding-linux-s390x-gnu': 0.120.0
|
||||
'@oxc-parser/binding-linux-x64-gnu': 0.120.0
|
||||
'@oxc-parser/binding-linux-x64-musl': 0.120.0
|
||||
'@oxc-parser/binding-openharmony-arm64': 0.120.0
|
||||
'@oxc-parser/binding-wasm32-wasi': 0.120.0
|
||||
'@oxc-parser/binding-win32-arm64-msvc': 0.120.0
|
||||
'@oxc-parser/binding-win32-ia32-msvc': 0.120.0
|
||||
'@oxc-parser/binding-win32-x64-msvc': 0.120.0
|
||||
|
||||
oxc-parser@0.99.0:
|
||||
dependencies:
|
||||
'@oxc-project/types': 0.99.0
|
||||
@@ -14546,11 +14773,11 @@ snapshots:
|
||||
dependencies:
|
||||
react: 19.2.4
|
||||
|
||||
react-i18next@15.7.4(i18next@25.8.20(typescript@5.9.3))(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(typescript@5.9.3):
|
||||
react-i18next@15.7.4(i18next@25.9.0(typescript@5.9.3))(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(typescript@5.9.3):
|
||||
dependencies:
|
||||
'@babel/runtime': 7.28.3
|
||||
html-parse-stringify: 3.0.1
|
||||
i18next: 25.8.20(typescript@5.9.3)
|
||||
i18next: 25.9.0(typescript@5.9.3)
|
||||
react: 19.2.4
|
||||
optionalDependencies:
|
||||
react-dom: 19.2.4(react@19.2.4)
|
||||
@@ -15031,10 +15258,10 @@ snapshots:
|
||||
|
||||
sprintf-js@1.1.3: {}
|
||||
|
||||
sqlite-wasm-kysely@0.3.0(kysely@0.27.6):
|
||||
sqlite-wasm-kysely@0.3.0(kysely@0.28.14):
|
||||
dependencies:
|
||||
'@sqlite.org/sqlite-wasm': 3.48.0-build4
|
||||
kysely: 0.27.6
|
||||
kysely: 0.28.14
|
||||
|
||||
stack-generator@2.0.10:
|
||||
dependencies:
|
||||
|
||||
@@ -3,7 +3,7 @@ import { writeAll } from 'jsr:@std/io@0.225/write-all'
|
||||
import { CHUNK_MULTIPLIER, performChunkedUpload } from './file-server.ts'
|
||||
import { consola } from './logger.ts'
|
||||
|
||||
const CACHE_BASE_URL = 'https://file-server.elaina.moe/cache'
|
||||
const CACHE_BASE_URL = 'https://file-server.majokeiko.com/cache'
|
||||
|
||||
// --- cache chunked upload types ---
|
||||
|
||||
|
||||
@@ -5,8 +5,8 @@ import { consola } from './logger.ts'
|
||||
|
||||
// --- constants ---
|
||||
|
||||
export const FILE_SERVER_UPLOAD_URL = 'https://file-server.elaina.moe/upload'
|
||||
export const FILE_SERVER_BIN_URL = 'https://file-server.elaina.moe/bin'
|
||||
export const FILE_SERVER_UPLOAD_URL = 'https://file-server.majokeiko.com/upload'
|
||||
export const FILE_SERVER_BIN_URL = 'https://file-server.majokeiko.com/bin'
|
||||
|
||||
export const UPLOAD_CONCURRENCY = 3
|
||||
export const CHUNK_RETRY_ATTEMPTS = 5
|
||||
|
||||
+5
-5
@@ -14,7 +14,7 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v6
|
||||
- uses: pnpm/action-setup@v4
|
||||
- uses: pnpm/action-setup@v5
|
||||
with:
|
||||
package_json_file: "frontend/package.json"
|
||||
- uses: actions/setup-node@v6
|
||||
@@ -59,7 +59,7 @@ jobs:
|
||||
- uses: actions/setup-go@v6
|
||||
with:
|
||||
go-version: '1.26'
|
||||
- uses: pnpm/action-setup@v4
|
||||
- uses: pnpm/action-setup@v5
|
||||
with:
|
||||
package_json_file: "frontend/package.json"
|
||||
- uses: actions/setup-node@v6
|
||||
@@ -68,7 +68,7 @@ jobs:
|
||||
cache: "pnpm"
|
||||
cache-dependency-path: "frontend/pnpm-lock.yaml"
|
||||
- name: Install Task
|
||||
uses: go-task/setup-task@v1
|
||||
uses: go-task/setup-task@v2
|
||||
- run: task build
|
||||
|
||||
release:
|
||||
@@ -83,7 +83,7 @@ jobs:
|
||||
- uses: actions/setup-go@v6
|
||||
with:
|
||||
go-version: '1.26'
|
||||
- uses: pnpm/action-setup@v4
|
||||
- uses: pnpm/action-setup@v5
|
||||
with:
|
||||
package_json_file: "frontend/package.json"
|
||||
- uses: actions/setup-node@v6
|
||||
@@ -96,7 +96,7 @@ jobs:
|
||||
- name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@v4
|
||||
- name: Install Task
|
||||
uses: go-task/setup-task@v1
|
||||
uses: go-task/setup-task@v2
|
||||
- run: task build:frontend
|
||||
- name: Login to Docker Hub
|
||||
uses: docker/login-action@v4
|
||||
|
||||
+2
-2
@@ -20,7 +20,7 @@ jobs:
|
||||
- name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@v4
|
||||
- name: Install Task
|
||||
uses: go-task/setup-task@v1
|
||||
uses: go-task/setup-task@v2
|
||||
- name: Build site
|
||||
run: task docs
|
||||
|
||||
@@ -41,7 +41,7 @@ jobs:
|
||||
- name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@v4
|
||||
- name: Install Task
|
||||
uses: go-task/setup-task@v1
|
||||
uses: go-task/setup-task@v2
|
||||
- name: Build site
|
||||
run: task docs
|
||||
- name: Upload static files as artifact
|
||||
|
||||
Vendored
+7
-7
@@ -155,7 +155,7 @@ jobs:
|
||||
- { goos: linux, goarch: amd64, goamd64: v3, output: amd64-v3-go120, goversion: '1.20' }
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v5
|
||||
- uses: actions/checkout@v6
|
||||
|
||||
- name: Set up Go
|
||||
if: ${{ matrix.jobs.goversion == '' }}
|
||||
@@ -386,7 +386,7 @@ jobs:
|
||||
shell: bash
|
||||
|
||||
- name: Archive production artifacts
|
||||
uses: actions/upload-artifact@v4
|
||||
uses: actions/upload-artifact@v7
|
||||
with:
|
||||
name: "${{ matrix.jobs.goos }}-${{ matrix.jobs.output }}"
|
||||
path: |
|
||||
@@ -405,7 +405,7 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Download all workflow run artifacts
|
||||
uses: actions/download-artifact@v4
|
||||
uses: actions/download-artifact@v8
|
||||
with:
|
||||
path: bin/
|
||||
merge-multiple: true
|
||||
@@ -463,7 +463,7 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v5
|
||||
uses: actions/checkout@v6
|
||||
with:
|
||||
ref: Meta
|
||||
fetch-depth: '0'
|
||||
@@ -498,7 +498,7 @@ jobs:
|
||||
bash ./genReleaseNote.sh -v ${PREVERSION}...${CURRENTVERSION}
|
||||
rm ./genReleaseNote.sh
|
||||
|
||||
- uses: actions/download-artifact@v4
|
||||
- uses: actions/download-artifact@v8
|
||||
with:
|
||||
path: bin/
|
||||
merge-multiple: true
|
||||
@@ -522,11 +522,11 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v5
|
||||
uses: actions/checkout@v6
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
- uses: actions/download-artifact@v4
|
||||
- uses: actions/download-artifact@v8
|
||||
with:
|
||||
path: bin/
|
||||
merge-multiple: true
|
||||
|
||||
Vendored
+1
-1
@@ -42,7 +42,7 @@ jobs:
|
||||
# Fix mingw trying to be smart and converting paths https://github.com/moby/moby/issues/24029#issuecomment-250412919
|
||||
MSYS_NO_PATHCONV: true
|
||||
steps:
|
||||
- uses: actions/checkout@v5
|
||||
- uses: actions/checkout@v6
|
||||
|
||||
- name: Setup Go
|
||||
uses: actions/setup-go@v6
|
||||
|
||||
+3
-10
@@ -165,11 +165,10 @@ func (r *Resolver) ExchangeContext(ctx context.Context, m *D.Msg) (msg *D.Msg, e
|
||||
|
||||
q := m.Question[0]
|
||||
domain := msgToDomain(m)
|
||||
cacheM, expireTime, hit := r.cache.GetWithExpire(q.String())
|
||||
msg, expireTime, hit := getMsgFromCache(r.cache, q)
|
||||
if hit {
|
||||
log.Debugln("[DNS] cache hit %s --> %s, expire at %s", domain, msgToLogString(cacheM), expireTime.Format("2006-01-02 15:04:05"))
|
||||
log.Debugln("[DNS] cache hit %s --> %s, expire at %s", domain, msgToLogString(msg), expireTime.Format("2006-01-02 15:04:05"))
|
||||
now := time.Now()
|
||||
msg = cacheM.Copy()
|
||||
if expireTime.Before(now) {
|
||||
setMsgTTL(msg, uint32(1)) // Continue fetch
|
||||
continueFetch = true
|
||||
@@ -201,14 +200,8 @@ func (r *Resolver) exchangeWithoutCache(ctx context.Context, m *D.Msg) (msg *D.M
|
||||
return
|
||||
}
|
||||
|
||||
msg := result
|
||||
|
||||
if cache {
|
||||
// OPT RRs MUST NOT be cached, forwarded, or stored in or loaded from master files.
|
||||
msg.Extra = lo.Filter(msg.Extra, func(rr D.RR, index int) bool {
|
||||
return rr.Header().Rrtype != D.TypeOPT
|
||||
})
|
||||
putMsgToCache(r.cache, q.String(), q, msg)
|
||||
putMsgToCache(r.cache, q, result)
|
||||
}
|
||||
}()
|
||||
|
||||
|
||||
+23
-3
@@ -45,7 +45,19 @@ func updateTTL(records []D.RR, ttl uint32) {
|
||||
}
|
||||
}
|
||||
|
||||
func putMsgToCache(c dnsCache, key string, q D.Question, msg *D.Msg) {
|
||||
// getMsgFromCache returns a cached dns message if it exists, otherwise returns nil.
|
||||
// the returned msg is a copy of the original msg, so it can be modified without affecting the original msg.
|
||||
func getMsgFromCache(c dnsCache, q D.Question) (*D.Msg, time.Time, bool) {
|
||||
msg, expireTime, hit := c.GetWithExpire(q.String())
|
||||
if msg != nil {
|
||||
msg = msg.Copy() // never modify the original msg
|
||||
}
|
||||
return msg, expireTime, hit
|
||||
}
|
||||
|
||||
// putMsgToCache puts a dns message into the cache.
|
||||
// the msg is copied before being stored in the cache, so it can be modified without affecting the original msg.
|
||||
func putMsgToCache(c dnsCache, q D.Question, msg *D.Msg) {
|
||||
// skip dns cache for acme challenge
|
||||
if q.Qtype == D.TypeTXT && strings.HasPrefix(q.Name, "_acme-challenge.") {
|
||||
log.Debugln("[DNS] dns cache ignored because of acme challenge for: %s", q.Name)
|
||||
@@ -58,12 +70,20 @@ func putMsgToCache(c dnsCache, key string, q D.Question, msg *D.Msg) {
|
||||
// If it does so it MUST NOT cache it for longer than five (5) minutes [...]
|
||||
ttl = serverFailureCacheTTL
|
||||
} else {
|
||||
ttl = minimalTTL(append(append(msg.Answer, msg.Ns...), msg.Extra...))
|
||||
ttl = minimalTTL(lo.Concat(msg.Answer, msg.Ns, msg.Extra))
|
||||
}
|
||||
if ttl == 0 {
|
||||
return
|
||||
}
|
||||
c.SetWithExpire(key, msg.Copy(), time.Now().Add(time.Duration(ttl)*time.Second))
|
||||
|
||||
msg = msg.Copy() // never modify the original msg
|
||||
|
||||
// OPT RRs MUST NOT be cached, forwarded, or stored in or loaded from master files.
|
||||
msg.Extra = lo.Filter(msg.Extra, func(rr D.RR, index int) bool {
|
||||
return rr.Header().Rrtype != D.TypeOPT
|
||||
})
|
||||
|
||||
c.SetWithExpire(q.String(), msg, time.Now().Add(time.Duration(ttl)*time.Second))
|
||||
}
|
||||
|
||||
func setMsgTTL(msg *D.Msg, ttl uint32) {
|
||||
|
||||
@@ -5,12 +5,12 @@
|
||||
include $(TOPDIR)/rules.mk
|
||||
|
||||
PKG_NAME:=pdnsd
|
||||
PKG_VERSION:=1.3.1
|
||||
PKG_VERSION:=1.3.2
|
||||
PKG_RELEASE:=1
|
||||
|
||||
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
|
||||
PKG_SOURCE_URL:=https://codeload.github.com/kenzok8/pdnsd/tar.gz/$(PKG_VERSION)?
|
||||
PKG_HASH:=28929bfd7874fd86872dc1bf4cd01103d7ebbdad6a457ccd9a8947a2819440be
|
||||
PKG_HASH:=ce76cecc5238ab48c0a78baa8225ce896f204fe9bda61845eeaf70f551b17478
|
||||
|
||||
PKG_BUILD_PARALLEL:=1
|
||||
PKG_INSTALL:=1
|
||||
@@ -54,4 +54,3 @@ endef
|
||||
|
||||
$(eval $(call BuildPackage,pdnsd-alt))
|
||||
|
||||
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
include $(TOPDIR)/rules.mk
|
||||
|
||||
PKG_NAME:=shadowsocksr-libev
|
||||
PKG_VERSION:=2.5.9
|
||||
PKG_VERSION:=2.5.10
|
||||
PKG_RELEASE:=1
|
||||
|
||||
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
|
||||
PKG_SOURCE_URL:=https://codeload.github.com/kenzok8/shadowsocksr-libev/tar.gz/v$(PKG_VERSION)?
|
||||
PKG_HASH:=142d62bf4a1937c96c3f0970eef7391ce8df4efb830e295338a594ddf6493630
|
||||
PKG_HASH:=7699d420bea841f6314a7b9d5c5fa996e02139812c79d39bbc4f786c65c4fffc
|
||||
|
||||
PKG_LICENSE:=GPL-3.0
|
||||
PKG_LICENSE_FILES:=LICENSE
|
||||
|
||||
@@ -6,12 +6,12 @@
|
||||
include $(TOPDIR)/rules.mk
|
||||
|
||||
PKG_NAME:=simple-obfs
|
||||
PKG_VERSION:=0.0.10
|
||||
PKG_VERSION:=0.0.11
|
||||
PKG_RELEASE:=1
|
||||
|
||||
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
|
||||
PKG_SOURCE_URL:=https://codeload.github.com/kenzok8/simple-obfs/tar.gz/v$(PKG_VERSION)?
|
||||
PKG_HASH:=f64eb9f9013fe0798e5159e3cd108909eb4ac949d78d51804d96945af82d363e
|
||||
PKG_HASH:=b5f1de228bbc3fcb7b2e1160c4736e9eb47978bd92b7bb3f0948f6a06bc979f0
|
||||
|
||||
PKG_LICENSE:=GPL-3.0-or-later
|
||||
PKG_LICENSE_FILES:=LICENSE
|
||||
|
||||
@@ -7,12 +7,12 @@
|
||||
include $(TOPDIR)/rules.mk
|
||||
|
||||
PKG_NAME:=trojan
|
||||
PKG_VERSION:=1.16.9
|
||||
PKG_VERSION:=1.17.0
|
||||
PKG_RELEASE:=1
|
||||
|
||||
PKG_SOURCE:=Trojan-$(PKG_VERSION).tar.gz
|
||||
PKG_SOURCE_URL:=https://codeload.github.com/kenzok8/trojan/tar.gz/v$(PKG_VERSION)?
|
||||
PKG_HASH:=c8c65f8227dbffc2853fad9da759391ea9c709e12cee71b78392a4cdb8aeb89c
|
||||
PKG_HASH:=e6772fed325301760e7150ddd483faa77af9046a2aeedbdb51278b4d6d9ae33f
|
||||
|
||||
PKG_BUILD_PARALLEL:=1
|
||||
PKG_BUILD_DEPENDS:=openssl
|
||||
|
||||
@@ -7,12 +7,12 @@
|
||||
include $(TOPDIR)/rules.mk
|
||||
|
||||
PKG_NAME:=v2dat
|
||||
PKG_VERSION:=0.1.2
|
||||
PKG_VERSION:=0.1.3
|
||||
PKG_RELEASE:=1
|
||||
|
||||
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
|
||||
PKG_SOURCE_URL:=https://codeload.github.com/kenzok8/v2dat/tar.gz/v$(PKG_VERSION)?
|
||||
PKG_HASH:=a85229fa6b0c9fbb4cb14c3e4734f5c6b743a779e6337bba09e144720451e1ac
|
||||
PKG_HASH:=301e6c96266a512d5f0caa143c1128ac8b5b9c4bfbf96ec0c7027cc7aa5ce865
|
||||
PKG_BUILD_DIR:=$(BUILD_DIR)/$(PKG_NAME)-$(PKG_VERSION)
|
||||
|
||||
PKG_LICENSE:=GPL-3.0
|
||||
|
||||
@@ -13,6 +13,7 @@ public enum EConfigType
|
||||
WireGuard = 9,
|
||||
HTTP = 10,
|
||||
Anytls = 11,
|
||||
Naive = 12,
|
||||
PolicyGroup = 101,
|
||||
ProxyChain = 102,
|
||||
}
|
||||
|
||||
@@ -193,6 +193,10 @@ public class Global
|
||||
|
||||
public const string Hysteria2ProtocolShare = "hy2://";
|
||||
|
||||
public const string NaiveHttpsProtocolShare = "naive+https://";
|
||||
|
||||
public const string NaiveQuicProtocolShare = "naive+quic://";
|
||||
|
||||
public static readonly Dictionary<EConfigType, string> ProtocolShares = new()
|
||||
{
|
||||
{ EConfigType.VMess, "vmess://" },
|
||||
@@ -203,7 +207,8 @@ public class Global
|
||||
{ EConfigType.Hysteria2, "hysteria2://" },
|
||||
{ EConfigType.TUIC, "tuic://" },
|
||||
{ EConfigType.WireGuard, "wireguard://" },
|
||||
{ EConfigType.Anytls, "anytls://" }
|
||||
{ EConfigType.Anytls, "anytls://" },
|
||||
{ EConfigType.Naive, "naive://" }
|
||||
};
|
||||
|
||||
public static readonly Dictionary<EConfigType, string> ProtocolTypes = new()
|
||||
@@ -217,7 +222,8 @@ public class Global
|
||||
{ EConfigType.Hysteria2, "hysteria2" },
|
||||
{ EConfigType.TUIC, "tuic" },
|
||||
{ EConfigType.WireGuard, "wireguard" },
|
||||
{ EConfigType.Anytls, "anytls" }
|
||||
{ EConfigType.Anytls, "anytls" },
|
||||
{ EConfigType.Naive, "naive" }
|
||||
};
|
||||
|
||||
public static readonly List<string> VmessSecurities =
|
||||
@@ -342,6 +348,7 @@ public class Global
|
||||
EConfigType.Hysteria2,
|
||||
EConfigType.TUIC,
|
||||
EConfigType.Anytls,
|
||||
EConfigType.Naive,
|
||||
EConfigType.WireGuard,
|
||||
EConfigType.SOCKS,
|
||||
EConfigType.HTTP,
|
||||
@@ -558,6 +565,14 @@ public class Global
|
||||
"bbr"
|
||||
];
|
||||
|
||||
public static readonly List<string> NaiveCongestionControls =
|
||||
[
|
||||
"bbr",
|
||||
"bbr2",
|
||||
"cubic",
|
||||
"reno"
|
||||
];
|
||||
|
||||
public static readonly List<string> allowSelectType =
|
||||
[
|
||||
"selector",
|
||||
@@ -660,5 +675,14 @@ public class Global
|
||||
""
|
||||
];
|
||||
|
||||
public static readonly List<string> TunIcmpRoutingPolicies =
|
||||
[
|
||||
"rule",
|
||||
"direct",
|
||||
"unreachable",
|
||||
"drop",
|
||||
"reply",
|
||||
];
|
||||
|
||||
#endregion const
|
||||
}
|
||||
|
||||
@@ -322,6 +322,7 @@ public class CoreConfigContextBuilder
|
||||
context.ProtectDomainList.Add(address);
|
||||
}
|
||||
|
||||
// ech query server name protect
|
||||
if (!node.EchConfigList.IsNullOrEmpty())
|
||||
{
|
||||
var echQuerySni = node.Sni;
|
||||
@@ -338,6 +339,20 @@ public class CoreConfigContextBuilder
|
||||
}
|
||||
}
|
||||
|
||||
// xhttp downloadSettings address protect
|
||||
if (!string.IsNullOrEmpty(node.Extra)
|
||||
&& JsonUtils.ParseJson(node.Extra) is JsonObject extra
|
||||
&& extra.TryGetPropertyValue("downloadSettings", out var dsNode)
|
||||
&& dsNode is JsonObject downloadSettings
|
||||
&& downloadSettings.TryGetPropertyValue("address", out var dAddrNode)
|
||||
&& dAddrNode is JsonValue dAddrValue
|
||||
&& dAddrValue.TryGetValue(out string? dAddr)
|
||||
&& !string.IsNullOrEmpty(dAddr)
|
||||
&& Utils.IsDomain(dAddr))
|
||||
{
|
||||
context.ProtectDomainList.Add(dAddr);
|
||||
}
|
||||
|
||||
return nodeValidatorResult;
|
||||
}
|
||||
|
||||
|
||||
@@ -91,6 +91,7 @@ public static class ConfigHandler
|
||||
{
|
||||
EnableTun = false,
|
||||
Mtu = 9000,
|
||||
IcmpRouting = Global.TunIcmpRoutingPolicies.First(),
|
||||
};
|
||||
config.GuiItem ??= new();
|
||||
config.MsgUIItem ??= new();
|
||||
@@ -269,6 +270,7 @@ public static class ConfigHandler
|
||||
EConfigType.TUIC => await AddTuicServer(config, item),
|
||||
EConfigType.WireGuard => await AddWireguardServer(config, item),
|
||||
EConfigType.Anytls => await AddAnytlsServer(config, item),
|
||||
EConfigType.Naive => await AddNaiveServer(config, item),
|
||||
_ => -1,
|
||||
};
|
||||
return ret;
|
||||
@@ -804,7 +806,7 @@ public static class ConfigHandler
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Add or edit a Anytls server
|
||||
/// Add or edit an Anytls server
|
||||
/// Validates and processes Anytls-specific settings
|
||||
/// </summary>
|
||||
/// <param name="config">Current configuration</param>
|
||||
@@ -831,6 +833,36 @@ public static class ConfigHandler
|
||||
return 0;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Add or edit a Naive server
|
||||
/// Validates and processes Naive-specific settings
|
||||
/// </summary>
|
||||
/// <param name="config">Current configuration</param>
|
||||
/// <param name="profileItem">Naive profile to add</param>
|
||||
/// <param name="toFile">Whether to save to file</param>
|
||||
/// <returns>0 if successful, -1 if failed</returns>
|
||||
public static async Task<int> AddNaiveServer(Config config, ProfileItem profileItem, bool toFile = true)
|
||||
{
|
||||
profileItem.ConfigType = EConfigType.Naive;
|
||||
profileItem.CoreType = ECoreType.sing_box;
|
||||
|
||||
profileItem.Address = profileItem.Address.TrimEx();
|
||||
profileItem.Username = profileItem.Username.TrimEx();
|
||||
profileItem.Password = profileItem.Password.TrimEx();
|
||||
profileItem.Alpn = string.Empty;
|
||||
profileItem.Network = string.Empty;
|
||||
if (profileItem.StreamSecurity.IsNullOrEmpty())
|
||||
{
|
||||
profileItem.StreamSecurity = Global.StreamSecurity;
|
||||
}
|
||||
if (profileItem.Password.IsNullOrEmpty())
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
await AddServerCommon(config, profileItem, toFile);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sort the server list by the specified column
|
||||
/// Updates the sort order in the profile extension data
|
||||
@@ -1077,7 +1109,8 @@ public static class ConfigHandler
|
||||
|
||||
if (toFile)
|
||||
{
|
||||
profileItem.SetProtocolExtra();
|
||||
//profileItem.SetProtocolExtra();
|
||||
profileItem.SetProtocolExtra(profileItem.GetProtocolExtra());
|
||||
await SQLiteHelper.Instance.ReplaceAsync(profileItem);
|
||||
}
|
||||
return 0;
|
||||
@@ -1105,6 +1138,7 @@ public static class ConfigHandler
|
||||
&& AreEqual(o.Address, n.Address)
|
||||
&& o.Port == n.Port
|
||||
&& AreEqual(o.Password, n.Password)
|
||||
&& AreEqual(o.Username, n.Username)
|
||||
&& AreEqual(oProtocolExtra.VlessEncryption, nProtocolExtra.VlessEncryption)
|
||||
&& AreEqual(oProtocolExtra.SsMethod, nProtocolExtra.SsMethod)
|
||||
&& AreEqual(oProtocolExtra.VmessSecurity, nProtocolExtra.VmessSecurity)
|
||||
@@ -1496,6 +1530,7 @@ public static class ConfigHandler
|
||||
EConfigType.TUIC => await AddTuicServer(config, profileItem, false),
|
||||
EConfigType.WireGuard => await AddWireguardServer(config, profileItem, false),
|
||||
EConfigType.Anytls => await AddAnytlsServer(config, profileItem, false),
|
||||
EConfigType.Naive => await AddNaiveServer(config, profileItem, false),
|
||||
_ => -1,
|
||||
};
|
||||
|
||||
|
||||
@@ -19,6 +19,7 @@ public class FmtHandler
|
||||
EConfigType.TUIC => TuicFmt.ToUri(item),
|
||||
EConfigType.WireGuard => WireguardFmt.ToUri(item),
|
||||
EConfigType.Anytls => AnytlsFmt.ToUri(item),
|
||||
EConfigType.Naive => NaiveFmt.ToUri(item),
|
||||
_ => null,
|
||||
};
|
||||
|
||||
@@ -80,6 +81,12 @@ public class FmtHandler
|
||||
{
|
||||
return AnytlsFmt.Resolve(str, out msg);
|
||||
}
|
||||
else if (str.StartsWith(Global.ProtocolShares[EConfigType.Naive])
|
||||
|| str.StartsWith(Global.NaiveHttpsProtocolShare)
|
||||
|| str.StartsWith(Global.NaiveQuicProtocolShare))
|
||||
{
|
||||
return NaiveFmt.Resolve(str, out msg);
|
||||
}
|
||||
else
|
||||
{
|
||||
msg = ResUI.NonvmessOrssProtocol;
|
||||
|
||||
@@ -0,0 +1,91 @@
|
||||
namespace ServiceLib.Handler.Fmt;
|
||||
|
||||
public class NaiveFmt : BaseFmt
|
||||
{
|
||||
public static ProfileItem? Resolve(string str, out string msg)
|
||||
{
|
||||
msg = ResUI.ConfigurationFormatIncorrect;
|
||||
|
||||
var parsedUrl = Utils.TryUri(str);
|
||||
if (parsedUrl == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
ProfileItem item = new()
|
||||
{
|
||||
ConfigType = EConfigType.Naive,
|
||||
Remarks = parsedUrl.GetComponents(UriComponents.Fragment, UriFormat.Unescaped),
|
||||
Address = parsedUrl.IdnHost,
|
||||
Port = parsedUrl.Port,
|
||||
};
|
||||
var protocolExtra = item.GetProtocolExtra();
|
||||
if (parsedUrl.Scheme.Contains("quic"))
|
||||
{
|
||||
protocolExtra = protocolExtra with
|
||||
{
|
||||
NaiveQuic = true,
|
||||
};
|
||||
}
|
||||
var rawUserInfo = Utils.UrlDecode(parsedUrl.UserInfo);
|
||||
if (rawUserInfo.Contains(':'))
|
||||
{
|
||||
var split = rawUserInfo.Split(':', 2);
|
||||
item.Username = split[0];
|
||||
item.Password = split[1];
|
||||
}
|
||||
else
|
||||
{
|
||||
item.Password = rawUserInfo;
|
||||
}
|
||||
|
||||
var query = Utils.ParseQueryString(parsedUrl.Query);
|
||||
ResolveUriQuery(query, ref item);
|
||||
var insecureConcurrency = int.TryParse(GetQueryValue(query, "insecure-concurrency"), out var ic) ? ic : 0;
|
||||
if (insecureConcurrency > 0)
|
||||
{
|
||||
protocolExtra = protocolExtra with
|
||||
{
|
||||
InsecureConcurrency = insecureConcurrency,
|
||||
};
|
||||
}
|
||||
|
||||
item.SetProtocolExtra(protocolExtra);
|
||||
return item;
|
||||
}
|
||||
|
||||
public static string? ToUri(ProfileItem? item)
|
||||
{
|
||||
if (item == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
var remark = string.Empty;
|
||||
if (item.Remarks.IsNotEmpty())
|
||||
{
|
||||
remark = "#" + Utils.UrlEncode(item.Remarks);
|
||||
}
|
||||
var userInfo = item.Username.IsNotEmpty() ? $"{Utils.UrlEncode(item.Username)}:{Utils.UrlEncode(item.Password)}" : Utils.UrlEncode(item.Password);
|
||||
var dicQuery = new Dictionary<string, string>();
|
||||
ToUriQuery(item, Global.None, ref dicQuery);
|
||||
var protocolExtra = item.GetProtocolExtra();
|
||||
if (protocolExtra.InsecureConcurrency > 0)
|
||||
{
|
||||
dicQuery.Add("insecure-concurrency", protocolExtra?.InsecureConcurrency.ToString());
|
||||
}
|
||||
|
||||
var query = dicQuery.Count > 0
|
||||
? ("?" + string.Join("&", dicQuery.Select(x => x.Key + "=" + x.Value).ToArray()))
|
||||
: string.Empty;
|
||||
var url = $"{userInfo}@{GetIpv6(item.Address)}:{item.Port}";
|
||||
|
||||
if (protocolExtra.NaiveQuic == true)
|
||||
{
|
||||
return $"{Global.NaiveQuicProtocolShare}{url}{query}{remark}";
|
||||
}
|
||||
else
|
||||
{
|
||||
return $"{Global.NaiveHttpsProtocolShare}{url}{query}{remark}";
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -30,7 +30,10 @@ public class TuicFmt : BaseFmt
|
||||
|
||||
var query = Utils.ParseQueryString(url.Query);
|
||||
ResolveUriQuery(query, ref item);
|
||||
item.HeaderType = GetQueryValue(query, "congestion_control");
|
||||
item.SetProtocolExtra(item.GetProtocolExtra() with
|
||||
{
|
||||
CongestionControl = GetQueryValue(query, "congestion_control")
|
||||
});
|
||||
|
||||
return item;
|
||||
}
|
||||
@@ -51,7 +54,10 @@ public class TuicFmt : BaseFmt
|
||||
var dicQuery = new Dictionary<string, string>();
|
||||
ToUriQueryLite(item, ref dicQuery);
|
||||
|
||||
dicQuery.Add("congestion_control", item.HeaderType);
|
||||
if (!item.GetProtocolExtra().CongestionControl.IsNullOrEmpty())
|
||||
{
|
||||
dicQuery.Add("congestion_control", item.GetProtocolExtra().CongestionControl);
|
||||
}
|
||||
|
||||
return ToUri(EConfigType.TUIC, item.Address, item.Port, $"{item.Username ?? ""}:{item.Password}", dicQuery, remark);
|
||||
}
|
||||
|
||||
@@ -305,12 +305,11 @@ public sealed class AppManager
|
||||
return await SQLiteHelper.Instance.TableAsync<FullConfigTemplateItem>().FirstOrDefaultAsync(it => it.CoreType == eCoreType);
|
||||
}
|
||||
|
||||
#pragma warning disable CS0618
|
||||
public async Task MigrateProfileExtra()
|
||||
{
|
||||
await MigrateProfileExtraGroup();
|
||||
|
||||
#pragma warning disable CS0618
|
||||
|
||||
const int pageSize = 100;
|
||||
var offset = 0;
|
||||
|
||||
@@ -334,7 +333,6 @@ public sealed class AppManager
|
||||
}
|
||||
|
||||
//await ProfileGroupItemManager.Instance.ClearAll();
|
||||
#pragma warning restore CS0618
|
||||
}
|
||||
|
||||
private async Task<int> MigrateProfileExtraSub(List<ProfileItem> batch)
|
||||
@@ -380,6 +378,7 @@ public sealed class AppManager
|
||||
break;
|
||||
|
||||
case EConfigType.TUIC:
|
||||
extra = extra with { CongestionControl = item.HeaderType.NullIfEmpty(), };
|
||||
item.Username = item.Id;
|
||||
item.Id = item.Security;
|
||||
item.Password = item.Security;
|
||||
@@ -436,7 +435,6 @@ public sealed class AppManager
|
||||
|
||||
private async Task<bool> MigrateProfileExtraGroup()
|
||||
{
|
||||
#pragma warning disable CS0618
|
||||
var list = await SQLiteHelper.Instance.TableAsync<ProfileGroupItem>().ToListAsync();
|
||||
var groupItems = new ConcurrentDictionary<string, ProfileGroupItem>(list.Where(t => !string.IsNullOrEmpty(t.IndexId)).ToDictionary(t => t.IndexId!));
|
||||
|
||||
@@ -501,8 +499,8 @@ public sealed class AppManager
|
||||
return true;
|
||||
|
||||
//await ProfileGroupItemManager.Instance.ClearAll();
|
||||
#pragma warning restore CS0618
|
||||
}
|
||||
#pragma warning restore CS0618
|
||||
|
||||
#endregion SqliteHelper
|
||||
|
||||
|
||||
@@ -144,6 +144,7 @@ public class TunModeItem
|
||||
public string Stack { get; set; }
|
||||
public int Mtu { get; set; }
|
||||
public bool EnableIPv6Address { get; set; }
|
||||
public string IcmpRouting { get; set; }
|
||||
}
|
||||
|
||||
[Serializable]
|
||||
|
||||
@@ -2,6 +2,9 @@ namespace ServiceLib.Models;
|
||||
|
||||
public record ProtocolExtraItem
|
||||
{
|
||||
public bool? Uot { get; init; }
|
||||
public string? CongestionControl { get; init; }
|
||||
|
||||
// vmess
|
||||
public string? AlterId { get; init; }
|
||||
public string? VmessSecurity { get; init; }
|
||||
@@ -29,6 +32,10 @@ public record ProtocolExtraItem
|
||||
public string? Ports { get; init; }
|
||||
public string? HopInterval { get; init; }
|
||||
|
||||
// naiveproxy
|
||||
public int? InsecureConcurrency { get; init; }
|
||||
public bool? NaiveQuic { get; init; }
|
||||
|
||||
// group profile
|
||||
public string? GroupType { get; init; }
|
||||
public string? ChildItems { get; init; }
|
||||
|
||||
@@ -134,10 +134,14 @@ public class Outbound4Sbox : BaseServer4Sbox
|
||||
public int? recv_window_conn { get; set; }
|
||||
public int? recv_window { get; set; }
|
||||
public bool? disable_mtu_discovery { get; set; }
|
||||
public int? insecure_concurrency { get; set; }
|
||||
public bool? udp_over_tcp { get; set; }
|
||||
public string? method { get; set; }
|
||||
public string? username { get; set; }
|
||||
public string? password { get; set; }
|
||||
public string? congestion_control { get; set; }
|
||||
public bool? quic { get; set; }
|
||||
public string? quic_congestion_control { get; set; }
|
||||
public string? version { get; set; }
|
||||
public string? network { get; set; }
|
||||
public string? packet_encoding { get; set; }
|
||||
|
||||
@@ -179,6 +179,8 @@ public class ServersItem4Ray
|
||||
|
||||
public string flow { get; set; }
|
||||
|
||||
public bool? uot { get; set; }
|
||||
|
||||
public List<SocksUsersItem4Ray> users { get; set; }
|
||||
}
|
||||
|
||||
|
||||
+55
-10
@@ -691,7 +691,7 @@ namespace ServiceLib.Resx {
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 查找类似 Add Child 的本地化字符串。
|
||||
/// 查找类似 Add Child 的本地化字符串。
|
||||
/// </summary>
|
||||
public static string menuAddChildServer {
|
||||
get {
|
||||
@@ -718,7 +718,7 @@ namespace ServiceLib.Resx {
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 查找类似 Add [Hysteria2] 的本地化字符串。
|
||||
/// 查找类似 Add [Hysteria2] 的本地化字符串。
|
||||
/// </summary>
|
||||
public static string menuAddHysteria2Server {
|
||||
get {
|
||||
@@ -727,7 +727,16 @@ namespace ServiceLib.Resx {
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 查找类似 Add Policy Group 的本地化字符串。
|
||||
/// 查找类似 Add [NaïveProxy] 的本地化字符串。
|
||||
/// </summary>
|
||||
public static string menuAddNaiveServer {
|
||||
get {
|
||||
return ResourceManager.GetString("menuAddNaiveServer", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 查找类似 Add Policy Group 的本地化字符串。
|
||||
/// </summary>
|
||||
public static string menuAddPolicyGroupServer {
|
||||
get {
|
||||
@@ -772,7 +781,7 @@ namespace ServiceLib.Resx {
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 查找类似 Add [Shadowsocks] 的本地化字符串。
|
||||
/// 查找类似 Add [Shadowsocks] 的本地化字符串。
|
||||
/// </summary>
|
||||
public static string menuAddShadowsocksServer {
|
||||
get {
|
||||
@@ -781,7 +790,7 @@ namespace ServiceLib.Resx {
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 查找类似 Add [SOCKS] 的本地化字符串。
|
||||
/// 查找类似 Add [SOCKS] 的本地化字符串。
|
||||
/// </summary>
|
||||
public static string menuAddSocksServer {
|
||||
get {
|
||||
@@ -790,7 +799,7 @@ namespace ServiceLib.Resx {
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 查找类似 Add [Trojan] 的本地化字符串。
|
||||
/// 查找类似 Add [Trojan] 的本地化字符串。
|
||||
/// </summary>
|
||||
public static string menuAddTrojanServer {
|
||||
get {
|
||||
@@ -799,7 +808,7 @@ namespace ServiceLib.Resx {
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 查找类似 Add [TUIC] 的本地化字符串。
|
||||
/// 查找类似 Add [TUIC] 的本地化字符串。
|
||||
/// </summary>
|
||||
public static string menuAddTuicServer {
|
||||
get {
|
||||
@@ -808,7 +817,7 @@ namespace ServiceLib.Resx {
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 查找类似 Add [VLESS] 的本地化字符串。
|
||||
/// 查找类似 Add [VLESS] 的本地化字符串。
|
||||
/// </summary>
|
||||
public static string menuAddVlessServer {
|
||||
get {
|
||||
@@ -817,7 +826,7 @@ namespace ServiceLib.Resx {
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 查找类似 Add [VMess] 的本地化字符串。
|
||||
/// 查找类似 Add [VMess] 的本地化字符串。
|
||||
/// </summary>
|
||||
public static string menuAddVmessServer {
|
||||
get {
|
||||
@@ -826,7 +835,7 @@ namespace ServiceLib.Resx {
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 查找类似 Add [WireGuard] 的本地化字符串。
|
||||
/// 查找类似 Add [WireGuard] 的本地化字符串。
|
||||
/// </summary>
|
||||
public static string menuAddWireguardServer {
|
||||
get {
|
||||
@@ -3069,6 +3078,15 @@ namespace ServiceLib.Resx {
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 查找类似 ICMP routing policy 的本地化字符串。
|
||||
/// </summary>
|
||||
public static string TbIcmpRoutingPolicy {
|
||||
get {
|
||||
return ResourceManager.GetString("TbIcmpRoutingPolicy", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 查找类似 UUID(id) 的本地化字符串。
|
||||
/// </summary>
|
||||
@@ -3105,6 +3123,15 @@ namespace ServiceLib.Resx {
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 查找类似 Insecure Concurrency 的本地化字符串。
|
||||
/// </summary>
|
||||
public static string TbInsecureConcurrency {
|
||||
get {
|
||||
return ResourceManager.GetString("TbInsecureConcurrency", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 查找类似 Most Stable 的本地化字符串。
|
||||
/// </summary>
|
||||
@@ -4491,6 +4518,24 @@ namespace ServiceLib.Resx {
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 查找类似 UDP over TCP 的本地化字符串。
|
||||
/// </summary>
|
||||
public static string TbUot {
|
||||
get {
|
||||
return ResourceManager.GetString("TbUot", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 查找类似 Username 的本地化字符串。
|
||||
/// </summary>
|
||||
public static string TbUsername {
|
||||
get {
|
||||
return ResourceManager.GetString("TbUsername", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 查找类似 Validate Regional Domain IPs 的本地化字符串。
|
||||
/// </summary>
|
||||
|
||||
@@ -1680,4 +1680,19 @@ The "Get Certificate" action may fail if a self-signed certificate is used or if
|
||||
<data name="menuEditFormat" xml:space="preserve">
|
||||
<value>Format</value>
|
||||
</data>
|
||||
<data name="TbUot" xml:space="preserve">
|
||||
<value>UDP over TCP</value>
|
||||
</data>
|
||||
<data name="menuAddNaiveServer" xml:space="preserve">
|
||||
<value>Add NaïveProxy</value>
|
||||
</data>
|
||||
<data name="TbInsecureConcurrency" xml:space="preserve">
|
||||
<value>Insecure Concurrency</value>
|
||||
</data>
|
||||
<data name="TbUsername" xml:space="preserve">
|
||||
<value>Username</value>
|
||||
</data>
|
||||
<data name="TbIcmpRoutingPolicy" xml:space="preserve">
|
||||
<value>ICMP routing policy</value>
|
||||
</data>
|
||||
</root>
|
||||
@@ -1677,4 +1677,19 @@ The "Get Certificate" action may fail if a self-signed certificate is used or if
|
||||
<data name="menuEditFormat" xml:space="preserve">
|
||||
<value>Format</value>
|
||||
</data>
|
||||
<data name="TbUot" xml:space="preserve">
|
||||
<value>UDP over TCP</value>
|
||||
</data>
|
||||
<data name="menuAddNaiveServer" xml:space="preserve">
|
||||
<value>Ajouter [NaïveProxy]</value>
|
||||
</data>
|
||||
<data name="TbInsecureConcurrency" xml:space="preserve">
|
||||
<value>Insecure Concurrency</value>
|
||||
</data>
|
||||
<data name="TbUsername" xml:space="preserve">
|
||||
<value>Username</value>
|
||||
</data>
|
||||
<data name="TbIcmpRoutingPolicy" xml:space="preserve">
|
||||
<value>ICMP routing policy</value>
|
||||
</data>
|
||||
</root>
|
||||
@@ -1680,4 +1680,19 @@ The "Get Certificate" action may fail if a self-signed certificate is used or if
|
||||
<data name="menuEditFormat" xml:space="preserve">
|
||||
<value>Format</value>
|
||||
</data>
|
||||
<data name="TbUot" xml:space="preserve">
|
||||
<value>UDP over TCP</value>
|
||||
</data>
|
||||
<data name="menuAddNaiveServer" xml:space="preserve">
|
||||
<value>[NaïveProxy] konfiguráció hozzáadása</value>
|
||||
</data>
|
||||
<data name="TbInsecureConcurrency" xml:space="preserve">
|
||||
<value>Insecure Concurrency</value>
|
||||
</data>
|
||||
<data name="TbUsername" xml:space="preserve">
|
||||
<value>Username</value>
|
||||
</data>
|
||||
<data name="TbIcmpRoutingPolicy" xml:space="preserve">
|
||||
<value>ICMP routing policy</value>
|
||||
</data>
|
||||
</root>
|
||||
@@ -514,19 +514,19 @@
|
||||
<value>Add a custom configuration</value>
|
||||
</data>
|
||||
<data name="menuAddShadowsocksServer" xml:space="preserve">
|
||||
<value>Add [Shadowsocks] </value>
|
||||
<value>Add [Shadowsocks]</value>
|
||||
</data>
|
||||
<data name="menuAddSocksServer" xml:space="preserve">
|
||||
<value>Add [SOCKS] </value>
|
||||
<value>Add [SOCKS]</value>
|
||||
</data>
|
||||
<data name="menuAddTrojanServer" xml:space="preserve">
|
||||
<value>Add [Trojan] </value>
|
||||
<value>Add [Trojan]</value>
|
||||
</data>
|
||||
<data name="menuAddVlessServer" xml:space="preserve">
|
||||
<value>Add [VLESS] </value>
|
||||
<value>Add [VLESS]</value>
|
||||
</data>
|
||||
<data name="menuAddVmessServer" xml:space="preserve">
|
||||
<value>Add [VMess] </value>
|
||||
<value>Add [VMess]</value>
|
||||
</data>
|
||||
<data name="menuSelectAll" xml:space="preserve">
|
||||
<value>Select all</value>
|
||||
@@ -1036,7 +1036,7 @@
|
||||
<value>Domain</value>
|
||||
</data>
|
||||
<data name="menuAddHysteria2Server" xml:space="preserve">
|
||||
<value>Add [Hysteria2] </value>
|
||||
<value>Add [Hysteria2]</value>
|
||||
</data>
|
||||
<data name="TbSettingsHysteriaBandwidth" xml:space="preserve">
|
||||
<value>Hysteria Max bandwidth (Up/Down)</value>
|
||||
@@ -1045,7 +1045,7 @@
|
||||
<value>Use System Hosts</value>
|
||||
</data>
|
||||
<data name="menuAddTuicServer" xml:space="preserve">
|
||||
<value>Add [TUIC] </value>
|
||||
<value>Add [TUIC]</value>
|
||||
</data>
|
||||
<data name="TbHeaderType8" xml:space="preserve">
|
||||
<value>Congestion control</value>
|
||||
@@ -1075,7 +1075,7 @@
|
||||
<value>Enable IPv6 Address</value>
|
||||
</data>
|
||||
<data name="menuAddWireguardServer" xml:space="preserve">
|
||||
<value>Add [WireGuard] </value>
|
||||
<value>Add [WireGuard]</value>
|
||||
</data>
|
||||
<data name="TbPrivateKey" xml:space="preserve">
|
||||
<value>Private Key</value>
|
||||
@@ -1495,13 +1495,13 @@
|
||||
<value>Policy Group Type</value>
|
||||
</data>
|
||||
<data name="menuAddPolicyGroupServer" xml:space="preserve">
|
||||
<value>Add Policy Group </value>
|
||||
<value>Add Policy Group</value>
|
||||
</data>
|
||||
<data name="menuAddProxyChainServer" xml:space="preserve">
|
||||
<value>Add Proxy Chain</value>
|
||||
</data>
|
||||
<data name="menuAddChildServer" xml:space="preserve">
|
||||
<value>Add Child </value>
|
||||
<value>Add Child</value>
|
||||
</data>
|
||||
<data name="menuRemoveChildServer" xml:space="preserve">
|
||||
<value>Remove Child </value>
|
||||
@@ -1680,4 +1680,19 @@ The "Get Certificate" action may fail if a self-signed certificate is used or if
|
||||
<data name="menuEditFormat" xml:space="preserve">
|
||||
<value>Format</value>
|
||||
</data>
|
||||
<data name="TbUot" xml:space="preserve">
|
||||
<value>UDP over TCP</value>
|
||||
</data>
|
||||
<data name="menuAddNaiveServer" xml:space="preserve">
|
||||
<value>Add [NaïveProxy]</value>
|
||||
</data>
|
||||
<data name="TbInsecureConcurrency" xml:space="preserve">
|
||||
<value>Insecure Concurrency</value>
|
||||
</data>
|
||||
<data name="TbUsername" xml:space="preserve">
|
||||
<value>Username</value>
|
||||
</data>
|
||||
<data name="TbIcmpRoutingPolicy" xml:space="preserve">
|
||||
<value>ICMP routing policy</value>
|
||||
</data>
|
||||
</root>
|
||||
@@ -1680,4 +1680,19 @@
|
||||
<data name="menuEditFormat" xml:space="preserve">
|
||||
<value>Format</value>
|
||||
</data>
|
||||
<data name="TbUot" xml:space="preserve">
|
||||
<value>UDP over TCP</value>
|
||||
</data>
|
||||
<data name="menuAddNaiveServer" xml:space="preserve">
|
||||
<value>Добавить сервер [NaïveProxy]</value>
|
||||
</data>
|
||||
<data name="TbInsecureConcurrency" xml:space="preserve">
|
||||
<value>Insecure Concurrency</value>
|
||||
</data>
|
||||
<data name="TbUsername" xml:space="preserve">
|
||||
<value>Username</value>
|
||||
</data>
|
||||
<data name="TbIcmpRoutingPolicy" xml:space="preserve">
|
||||
<value>ICMP routing policy</value>
|
||||
</data>
|
||||
</root>
|
||||
|
||||
@@ -517,16 +517,16 @@
|
||||
<value>添加 [Shadowsocks]</value>
|
||||
</data>
|
||||
<data name="menuAddSocksServer" xml:space="preserve">
|
||||
<value>添加 [SOCKS] </value>
|
||||
<value>添加 [SOCKS]</value>
|
||||
</data>
|
||||
<data name="menuAddTrojanServer" xml:space="preserve">
|
||||
<value>添加 [Trojan] </value>
|
||||
<value>添加 [Trojan]</value>
|
||||
</data>
|
||||
<data name="menuAddVlessServer" xml:space="preserve">
|
||||
<value>添加 [VLESS] </value>
|
||||
<value>添加 [VLESS]</value>
|
||||
</data>
|
||||
<data name="menuAddVmessServer" xml:space="preserve">
|
||||
<value>添加 [VMess] </value>
|
||||
<value>添加 [VMess]</value>
|
||||
</data>
|
||||
<data name="menuSelectAll" xml:space="preserve">
|
||||
<value>全选</value>
|
||||
@@ -1033,7 +1033,7 @@
|
||||
<value>Domain</value>
|
||||
</data>
|
||||
<data name="menuAddHysteria2Server" xml:space="preserve">
|
||||
<value>添加 [Hysteria2] </value>
|
||||
<value>添加 [Hysteria2]</value>
|
||||
</data>
|
||||
<data name="TbSettingsHysteriaBandwidth" xml:space="preserve">
|
||||
<value>Hysteria 最大带宽 (Up/Dw)</value>
|
||||
@@ -1042,7 +1042,7 @@
|
||||
<value>使用系统 hosts</value>
|
||||
</data>
|
||||
<data name="menuAddTuicServer" xml:space="preserve">
|
||||
<value>添加 [TUIC] </value>
|
||||
<value>添加 [TUIC]</value>
|
||||
</data>
|
||||
<data name="TbHeaderType8" xml:space="preserve">
|
||||
<value>拥塞控制算法</value>
|
||||
@@ -1072,7 +1072,7 @@
|
||||
<value>启用 IPv6</value>
|
||||
</data>
|
||||
<data name="menuAddWireguardServer" xml:space="preserve">
|
||||
<value>添加 [WireGuard] </value>
|
||||
<value>添加 [WireGuard]</value>
|
||||
</data>
|
||||
<data name="TbPrivateKey" xml:space="preserve">
|
||||
<value>PrivateKey</value>
|
||||
@@ -1102,7 +1102,7 @@
|
||||
<value>*grpc Authority</value>
|
||||
</data>
|
||||
<data name="menuAddHttpServer" xml:space="preserve">
|
||||
<value>添加 [HTTP] </value>
|
||||
<value>添加 [HTTP]</value>
|
||||
</data>
|
||||
<data name="TbSettingsEnableFragment" xml:space="preserve">
|
||||
<value>启用分片 (Fragment)</value>
|
||||
@@ -1381,7 +1381,7 @@
|
||||
<value>Mldsa65Verify</value>
|
||||
</data>
|
||||
<data name="menuAddAnytlsServer" xml:space="preserve">
|
||||
<value>添加 [Anytls] </value>
|
||||
<value>添加 [Anytls]</value>
|
||||
</data>
|
||||
<data name="TbRemoteDNS" xml:space="preserve">
|
||||
<value>远程 DNS</value>
|
||||
@@ -1677,4 +1677,19 @@
|
||||
<data name="menuEditFormat" xml:space="preserve">
|
||||
<value>格式化</value>
|
||||
</data>
|
||||
<data name="TbUot" xml:space="preserve">
|
||||
<value>UDP over TCP</value>
|
||||
</data>
|
||||
<data name="menuAddNaiveServer" xml:space="preserve">
|
||||
<value>添加 [NaïveProxy]</value>
|
||||
</data>
|
||||
<data name="TbInsecureConcurrency" xml:space="preserve">
|
||||
<value>不安全并发</value>
|
||||
</data>
|
||||
<data name="TbUsername" xml:space="preserve">
|
||||
<value>用户名</value>
|
||||
</data>
|
||||
<data name="TbIcmpRoutingPolicy" xml:space="preserve">
|
||||
<value>ICMP 路由策略</value>
|
||||
</data>
|
||||
</root>
|
||||
@@ -1677,4 +1677,19 @@
|
||||
<data name="menuEditFormat" xml:space="preserve">
|
||||
<value>Format</value>
|
||||
</data>
|
||||
<data name="TbUot" xml:space="preserve">
|
||||
<value>UDP over TCP</value>
|
||||
</data>
|
||||
<data name="menuAddNaiveServer" xml:space="preserve">
|
||||
<value>新增 [NaïveProxy] 節點</value>
|
||||
</data>
|
||||
<data name="TbInsecureConcurrency" xml:space="preserve">
|
||||
<value>Insecure Concurrency</value>
|
||||
</data>
|
||||
<data name="TbUsername" xml:space="preserve">
|
||||
<value>Username</value>
|
||||
</data>
|
||||
<data name="TbIcmpRoutingPolicy" xml:space="preserve">
|
||||
<value>ICMP routing policy</value>
|
||||
</data>
|
||||
</root>
|
||||
@@ -112,6 +112,7 @@ public partial class CoreConfigSingboxService
|
||||
outbound.method = AppManager.Instance.GetShadowsocksSecurities(_node).Contains(protocolExtra.SsMethod)
|
||||
? protocolExtra.SsMethod : Global.None;
|
||||
outbound.password = _node.Password;
|
||||
outbound.udp_over_tcp = protocolExtra.Uot == true ? true : null;
|
||||
|
||||
if (_node.Network == nameof(ETransport.tcp) && _node.HeaderType == Global.TcpHeaderHttp)
|
||||
{
|
||||
@@ -269,7 +270,7 @@ public partial class CoreConfigSingboxService
|
||||
{
|
||||
outbound.uuid = _node.Username;
|
||||
outbound.password = _node.Password;
|
||||
outbound.congestion_control = _node.HeaderType;
|
||||
outbound.congestion_control = protocolExtra.CongestionControl;
|
||||
break;
|
||||
}
|
||||
case EConfigType.Anytls:
|
||||
@@ -277,6 +278,22 @@ public partial class CoreConfigSingboxService
|
||||
outbound.password = _node.Password;
|
||||
break;
|
||||
}
|
||||
case EConfigType.Naive:
|
||||
{
|
||||
outbound.username = _node.Username;
|
||||
outbound.password = _node.Password;
|
||||
if (protocolExtra.NaiveQuic == true)
|
||||
{
|
||||
outbound.quic = true;
|
||||
outbound.quic_congestion_control = protocolExtra.CongestionControl.NullIfEmpty();
|
||||
}
|
||||
if (protocolExtra.InsecureConcurrency > 0)
|
||||
{
|
||||
outbound.insecure_concurrency = protocolExtra.InsecureConcurrency;
|
||||
}
|
||||
outbound.udp_over_tcp = protocolExtra.Uot == true ? true : null;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
FillOutboundTls(outbound);
|
||||
@@ -727,13 +744,12 @@ public partial class CoreConfigSingboxService
|
||||
}, null);
|
||||
}
|
||||
var idx = echConfig.IndexOf('+');
|
||||
// NOTE: query_server_name, since sing-box 1.13.0
|
||||
//var queryServerName = idx > 0 ? echConfig[..idx] : null;
|
||||
var queryServerName = idx > 0 ? echConfig[..idx] : null;
|
||||
var echDnsServer = idx > 0 ? echConfig[(idx + 1)..] : echConfig;
|
||||
return (new Ech4Sbox()
|
||||
{
|
||||
enabled = true,
|
||||
query_server_name = null,
|
||||
query_server_name = queryServerName,
|
||||
}, ParseDnsAddress(echDnsServer));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -47,6 +47,36 @@ public partial class CoreConfigSingboxService
|
||||
outbound = Global.DirectTag,
|
||||
process_name = lstDirectExe
|
||||
});
|
||||
|
||||
// ICMP Routing
|
||||
var icmpRouting = _config.TunModeItem.IcmpRouting ?? "";
|
||||
if (!Global.TunIcmpRoutingPolicies.Contains(icmpRouting))
|
||||
{
|
||||
icmpRouting = Global.TunIcmpRoutingPolicies.First();
|
||||
}
|
||||
if (icmpRouting == "direct")
|
||||
{
|
||||
_coreConfig.route.rules.Add(new()
|
||||
{
|
||||
network = ["icmp"],
|
||||
outbound = Global.DirectTag,
|
||||
});
|
||||
}
|
||||
else if (icmpRouting != "rule")
|
||||
{
|
||||
var rejectMethod = icmpRouting switch
|
||||
{
|
||||
"unreachable" => "default",
|
||||
"drop" => "drop",
|
||||
_ => "reply",
|
||||
};
|
||||
_coreConfig.route.rules.Add(new()
|
||||
{
|
||||
network = ["icmp"],
|
||||
action = "reject",
|
||||
method = rejectMethod,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
if (_config.Inbound.First().SniffingEnabled)
|
||||
|
||||
@@ -153,6 +153,7 @@ public partial class CoreConfigV2rayService
|
||||
serversItem.password = _node.Password;
|
||||
serversItem.method = AppManager.Instance.GetShadowsocksSecurities(_node).Contains(protocolExtra.SsMethod)
|
||||
? protocolExtra.SsMethod : "none";
|
||||
serversItem.uot = protocolExtra.Uot == true ? true : null;
|
||||
|
||||
serversItem.ota = false;
|
||||
serversItem.level = 1;
|
||||
|
||||
@@ -61,6 +61,18 @@ public class AddServerViewModel : MyReactiveObject
|
||||
[Reactive]
|
||||
public int WgMtu { get; set; }
|
||||
|
||||
[Reactive]
|
||||
public bool Uot { get; set; }
|
||||
|
||||
[Reactive]
|
||||
public string CongestionControl { get; set; }
|
||||
|
||||
[Reactive]
|
||||
public int? InsecureConcurrency { get; set; }
|
||||
|
||||
[Reactive]
|
||||
public bool NaiveQuic { get; set; }
|
||||
|
||||
public ReactiveCommand<Unit, Unit> FetchCertCmd { get; }
|
||||
public ReactiveCommand<Unit, Unit> FetchCertChainCmd { get; }
|
||||
public ReactiveCommand<Unit, Unit> SaveCmd { get; }
|
||||
@@ -123,6 +135,10 @@ public class AddServerViewModel : MyReactiveObject
|
||||
WgInterfaceAddress = protocolExtra?.WgInterfaceAddress ?? string.Empty;
|
||||
WgReserved = protocolExtra?.WgReserved ?? string.Empty;
|
||||
WgMtu = protocolExtra?.WgMtu ?? 1280;
|
||||
Uot = protocolExtra?.Uot ?? false;
|
||||
CongestionControl = protocolExtra?.CongestionControl ?? string.Empty;
|
||||
InsecureConcurrency = protocolExtra?.InsecureConcurrency > 0 ? protocolExtra.InsecureConcurrency : null;
|
||||
NaiveQuic = protocolExtra?.NaiveQuic ?? false;
|
||||
}
|
||||
|
||||
private async Task SaveServerAsync()
|
||||
@@ -185,6 +201,10 @@ public class AddServerViewModel : MyReactiveObject
|
||||
WgInterfaceAddress = WgInterfaceAddress.NullIfEmpty(),
|
||||
WgReserved = WgReserved.NullIfEmpty(),
|
||||
WgMtu = WgMtu >= 576 ? WgMtu : null,
|
||||
Uot = Uot ? true : null,
|
||||
CongestionControl = CongestionControl.NullIfEmpty(),
|
||||
InsecureConcurrency = InsecureConcurrency > 0 ? InsecureConcurrency : null,
|
||||
NaiveQuic = NaiveQuic ? true : null,
|
||||
});
|
||||
|
||||
if (await ConfigHandler.AddServer(_config, SelectedSource) == 0)
|
||||
|
||||
@@ -18,6 +18,7 @@ public class MainWindowViewModel : MyReactiveObject
|
||||
public ReactiveCommand<Unit, Unit> AddTuicServerCmd { get; }
|
||||
public ReactiveCommand<Unit, Unit> AddWireguardServerCmd { get; }
|
||||
public ReactiveCommand<Unit, Unit> AddAnytlsServerCmd { get; }
|
||||
public ReactiveCommand<Unit, Unit> AddNaiveServerCmd { get; }
|
||||
public ReactiveCommand<Unit, Unit> AddCustomServerCmd { get; }
|
||||
public ReactiveCommand<Unit, Unit> AddPolicyGroupServerCmd { get; }
|
||||
public ReactiveCommand<Unit, Unit> AddProxyChainServerCmd { get; }
|
||||
@@ -117,6 +118,10 @@ public class MainWindowViewModel : MyReactiveObject
|
||||
{
|
||||
await AddServerAsync(EConfigType.Anytls);
|
||||
});
|
||||
AddNaiveServerCmd = ReactiveCommand.CreateFromTask(async () =>
|
||||
{
|
||||
await AddServerAsync(EConfigType.Naive);
|
||||
});
|
||||
AddCustomServerCmd = ReactiveCommand.CreateFromTask(async () =>
|
||||
{
|
||||
await AddServerAsync(EConfigType.Custom);
|
||||
|
||||
@@ -95,6 +95,7 @@ public class OptionSettingViewModel : MyReactiveObject
|
||||
[Reactive] public string TunStack { get; set; }
|
||||
[Reactive] public int TunMtu { get; set; }
|
||||
[Reactive] public bool TunEnableIPv6Address { get; set; }
|
||||
[Reactive] public string TunIcmpRouting { get; set; }
|
||||
|
||||
#endregion Tun mode
|
||||
|
||||
@@ -218,6 +219,7 @@ public class OptionSettingViewModel : MyReactiveObject
|
||||
TunStack = _config.TunModeItem.Stack;
|
||||
TunMtu = _config.TunModeItem.Mtu;
|
||||
TunEnableIPv6Address = _config.TunModeItem.EnableIPv6Address;
|
||||
TunIcmpRouting = _config.TunModeItem.IcmpRouting;
|
||||
|
||||
#endregion Tun mode
|
||||
|
||||
@@ -376,6 +378,7 @@ public class OptionSettingViewModel : MyReactiveObject
|
||||
_config.TunModeItem.Stack = TunStack;
|
||||
_config.TunModeItem.Mtu = TunMtu;
|
||||
_config.TunModeItem.EnableIPv6Address = TunEnableIPv6Address;
|
||||
_config.TunModeItem.IcmpRouting = TunIcmpRouting;
|
||||
|
||||
//coreType
|
||||
await SaveCoreType();
|
||||
|
||||
@@ -198,6 +198,19 @@
|
||||
Width="300"
|
||||
Margin="{StaticResource Margin4}" />
|
||||
|
||||
<TextBlock
|
||||
Grid.Row="3"
|
||||
Grid.Column="0"
|
||||
Margin="{StaticResource Margin4}"
|
||||
VerticalAlignment="Center"
|
||||
Text="{x:Static resx:ResUI.TbUot}" />
|
||||
<ToggleSwitch
|
||||
x:Name="togUotEnabled3"
|
||||
Grid.Row="3"
|
||||
Grid.Column="1"
|
||||
Margin="{StaticResource Margin4}"
|
||||
HorizontalAlignment="Left" />
|
||||
|
||||
<TextBlock
|
||||
Grid.Row="4"
|
||||
Grid.Column="0"
|
||||
@@ -484,7 +497,7 @@
|
||||
VerticalAlignment="Center"
|
||||
Text="{x:Static resx:ResUI.TbHeaderType8}" />
|
||||
<ComboBox
|
||||
x:Name="cmbHeaderType8"
|
||||
x:Name="cmbCongestionControl8"
|
||||
Grid.Row="3"
|
||||
Grid.Column="1"
|
||||
Width="200"
|
||||
@@ -581,12 +594,93 @@
|
||||
VerticalAlignment="Center"
|
||||
Text="{x:Static resx:ResUI.TbId3}" />
|
||||
<TextBox
|
||||
x:Name="txtId10"
|
||||
x:Name="txtId11"
|
||||
Grid.Row="1"
|
||||
Grid.Column="1"
|
||||
Width="400"
|
||||
Margin="{StaticResource Margin4}" />
|
||||
</Grid>
|
||||
<Grid
|
||||
x:Name="gridNaive"
|
||||
Grid.Row="2"
|
||||
ColumnDefinitions="300,Auto"
|
||||
IsVisible="False"
|
||||
RowDefinitions="Auto,Auto,Auto,Auto,Auto,Auto">
|
||||
<TextBlock
|
||||
Grid.Row="1"
|
||||
Grid.Column="0"
|
||||
Margin="{StaticResource Margin4}"
|
||||
VerticalAlignment="Center"
|
||||
Text="{x:Static resx:ResUI.TbUsername}" />
|
||||
<TextBox
|
||||
x:Name="txtId12"
|
||||
Grid.Row="1"
|
||||
Grid.Column="1"
|
||||
Width="400"
|
||||
Margin="{StaticResource Margin4}" />
|
||||
|
||||
<TextBlock
|
||||
Grid.Row="2"
|
||||
Grid.Column="0"
|
||||
Margin="{StaticResource Margin4}"
|
||||
VerticalAlignment="Center"
|
||||
Text="{x:Static resx:ResUI.TbId3}" />
|
||||
<TextBox
|
||||
x:Name="txtSecurity12"
|
||||
Grid.Row="2"
|
||||
Grid.Column="1"
|
||||
Width="400"
|
||||
Margin="{StaticResource Margin4}" />
|
||||
|
||||
<TextBlock
|
||||
Grid.Row="3"
|
||||
Grid.Column="0"
|
||||
Margin="{StaticResource Margin4}"
|
||||
VerticalAlignment="Center"
|
||||
Text="QUIC" />
|
||||
<StackPanel
|
||||
Grid.Row="3"
|
||||
Grid.Column="1"
|
||||
VerticalAlignment="Center"
|
||||
Orientation="Horizontal">
|
||||
<ToggleSwitch
|
||||
x:Name="togNaiveQuic12"
|
||||
Margin="{StaticResource Margin4}"
|
||||
HorizontalAlignment="Left" />
|
||||
<ComboBox
|
||||
x:Name="cmbCongestionControl12"
|
||||
Width="200"
|
||||
Margin="{StaticResource Margin4}"
|
||||
PlaceholderText="{x:Static resx:ResUI.TbHeaderType8}" />
|
||||
</StackPanel>
|
||||
|
||||
<TextBlock
|
||||
Grid.Row="4"
|
||||
Grid.Column="0"
|
||||
Margin="{StaticResource Margin4}"
|
||||
VerticalAlignment="Center"
|
||||
Text="{x:Static resx:ResUI.TbInsecureConcurrency}" />
|
||||
<TextBox
|
||||
x:Name="txtInsecureConcurrency12"
|
||||
Grid.Row="4"
|
||||
Grid.Column="1"
|
||||
Width="200"
|
||||
Margin="{StaticResource Margin4}"
|
||||
HorizontalAlignment="Left" />
|
||||
|
||||
<TextBlock
|
||||
Grid.Row="5"
|
||||
Grid.Column="0"
|
||||
Margin="{StaticResource Margin4}"
|
||||
VerticalAlignment="Center"
|
||||
Text="{x:Static resx:ResUI.TbUot}" />
|
||||
<ToggleSwitch
|
||||
x:Name="togUotEnabled12"
|
||||
Grid.Row="5"
|
||||
Grid.Column="1"
|
||||
Margin="{StaticResource Margin4}"
|
||||
HorizontalAlignment="Left" />
|
||||
</Grid>
|
||||
|
||||
<Separator
|
||||
x:Name="sepa2"
|
||||
|
||||
@@ -80,7 +80,7 @@ public partial class AddServerWindow : WindowBase<AddServerViewModel>
|
||||
cmbFingerprint.SelectedValue = string.Empty;
|
||||
gridFinalmask.IsVisible = false;
|
||||
|
||||
cmbHeaderType8.ItemsSource = Global.TuicCongestionControls;
|
||||
cmbCongestionControl8.ItemsSource = Global.TuicCongestionControls;
|
||||
break;
|
||||
|
||||
case EConfigType.WireGuard:
|
||||
@@ -94,10 +94,28 @@ public partial class AddServerWindow : WindowBase<AddServerViewModel>
|
||||
|
||||
case EConfigType.Anytls:
|
||||
gridAnytls.IsVisible = true;
|
||||
sepa2.IsVisible = false;
|
||||
gridTransport.IsVisible = false;
|
||||
lstStreamSecurity.Add(Global.StreamSecurityReality);
|
||||
cmbCoreType.IsEnabled = false;
|
||||
gridFinalmask.IsVisible = false;
|
||||
break;
|
||||
|
||||
case EConfigType.Naive:
|
||||
gridNaive.IsVisible = true;
|
||||
sepa2.IsVisible = false;
|
||||
gridTransport.IsVisible = false;
|
||||
cmbCoreType.IsEnabled = false;
|
||||
gridFinalmask.IsVisible = false;
|
||||
cmbFingerprint.IsEnabled = false;
|
||||
cmbFingerprint.SelectedValue = string.Empty;
|
||||
cmbAlpn.IsEnabled = false;
|
||||
cmbAlpn.SelectedValue = string.Empty;
|
||||
cmbAllowInsecure.IsEnabled = false;
|
||||
cmbAllowInsecure.SelectedValue = string.Empty;
|
||||
|
||||
cmbCongestionControl12.ItemsSource = Global.NaiveCongestionControls;
|
||||
break;
|
||||
}
|
||||
cmbStreamSecurity.ItemsSource = lstStreamSecurity;
|
||||
|
||||
@@ -122,6 +140,7 @@ public partial class AddServerWindow : WindowBase<AddServerViewModel>
|
||||
case EConfigType.Shadowsocks:
|
||||
this.Bind(ViewModel, vm => vm.SelectedSource.Password, v => v.txtId3.Text).DisposeWith(disposables);
|
||||
this.Bind(ViewModel, vm => vm.SsMethod, v => v.cmbSecurity3.SelectedValue).DisposeWith(disposables);
|
||||
this.Bind(ViewModel, vm => vm.Uot, v => v.togUotEnabled3.IsChecked).DisposeWith(disposables);
|
||||
this.Bind(ViewModel, vm => vm.SelectedSource.MuxEnabled, v => v.togmuxEnabled3.IsChecked).DisposeWith(disposables);
|
||||
break;
|
||||
|
||||
@@ -156,7 +175,7 @@ public partial class AddServerWindow : WindowBase<AddServerViewModel>
|
||||
case EConfigType.TUIC:
|
||||
this.Bind(ViewModel, vm => vm.SelectedSource.Username, v => v.txtId8.Text).DisposeWith(disposables);
|
||||
this.Bind(ViewModel, vm => vm.SelectedSource.Password, v => v.txtSecurity8.Text).DisposeWith(disposables);
|
||||
this.Bind(ViewModel, vm => vm.SelectedSource.HeaderType, v => v.cmbHeaderType8.SelectedValue).DisposeWith(disposables);
|
||||
this.Bind(ViewModel, vm => vm.CongestionControl, v => v.cmbCongestionControl8.SelectedValue).DisposeWith(disposables);
|
||||
break;
|
||||
|
||||
case EConfigType.WireGuard:
|
||||
@@ -168,7 +187,17 @@ public partial class AddServerWindow : WindowBase<AddServerViewModel>
|
||||
break;
|
||||
|
||||
case EConfigType.Anytls:
|
||||
this.Bind(ViewModel, vm => vm.SelectedSource.Password, v => v.txtId10.Text).DisposeWith(disposables);
|
||||
this.Bind(ViewModel, vm => vm.SelectedSource.Password, v => v.txtId11.Text).DisposeWith(disposables);
|
||||
break;
|
||||
|
||||
case EConfigType.Naive:
|
||||
this.Bind(ViewModel, vm => vm.SelectedSource.Username, v => v.txtId12.Text).DisposeWith(disposables);
|
||||
this.Bind(ViewModel, vm => vm.SelectedSource.Password, v => v.txtSecurity12.Text).DisposeWith(disposables);
|
||||
this.Bind(ViewModel, vm => vm.NaiveQuic, v => v.togNaiveQuic12.IsChecked).DisposeWith(disposables);
|
||||
this.Bind(ViewModel, vm => vm.NaiveQuic, v => v.cmbCongestionControl12.IsEnabled).DisposeWith(disposables);
|
||||
this.Bind(ViewModel, vm => vm.CongestionControl, v => v.cmbCongestionControl12.SelectedValue).DisposeWith(disposables);
|
||||
this.Bind(ViewModel, vm => vm.InsecureConcurrency, v => v.txtInsecureConcurrency12.Text).DisposeWith(disposables);
|
||||
this.Bind(ViewModel, vm => vm.Uot, v => v.togUotEnabled12.IsChecked).DisposeWith(disposables);
|
||||
break;
|
||||
}
|
||||
this.Bind(ViewModel, vm => vm.SelectedSource.Network, v => v.cmbNetwork.SelectedValue).DisposeWith(disposables);
|
||||
|
||||
@@ -50,6 +50,7 @@
|
||||
<Separator />
|
||||
<MenuItem x:Name="menuAddTuicServer" Header="{x:Static resx:ResUI.menuAddTuicServer}" />
|
||||
<MenuItem x:Name="menuAddAnytlsServer" Header="{x:Static resx:ResUI.menuAddAnytlsServer}" />
|
||||
<MenuItem x:Name="menuAddNaiveServer" Header="{x:Static resx:ResUI.menuAddNaiveServer}" />
|
||||
</MenuItem>
|
||||
|
||||
<MenuItem Header="{x:Static resx:ResUI.menuSubscription}">
|
||||
|
||||
@@ -72,6 +72,7 @@ public partial class MainWindow : WindowBase<MainWindowViewModel>
|
||||
this.BindCommand(ViewModel, vm => vm.AddTuicServerCmd, v => v.menuAddTuicServer).DisposeWith(disposables);
|
||||
this.BindCommand(ViewModel, vm => vm.AddWireguardServerCmd, v => v.menuAddWireguardServer).DisposeWith(disposables);
|
||||
this.BindCommand(ViewModel, vm => vm.AddAnytlsServerCmd, v => v.menuAddAnytlsServer).DisposeWith(disposables);
|
||||
this.BindCommand(ViewModel, vm => vm.AddNaiveServerCmd, v => v.menuAddNaiveServer).DisposeWith(disposables);
|
||||
this.BindCommand(ViewModel, vm => vm.AddCustomServerCmd, v => v.menuAddCustomServer).DisposeWith(disposables);
|
||||
this.BindCommand(ViewModel, vm => vm.AddPolicyGroupServerCmd, v => v.menuAddPolicyGroupServer).DisposeWith(disposables);
|
||||
this.BindCommand(ViewModel, vm => vm.AddProxyChainServerCmd, v => v.menuAddProxyChainServer).DisposeWith(disposables);
|
||||
|
||||
@@ -824,6 +824,20 @@
|
||||
Margin="{StaticResource Margin4}"
|
||||
HorizontalAlignment="Left" />
|
||||
|
||||
<TextBlock
|
||||
Grid.Row="6"
|
||||
Grid.Column="0"
|
||||
Margin="{StaticResource Margin4}"
|
||||
VerticalAlignment="Center"
|
||||
Text="{x:Static resx:ResUI.TbIcmpRoutingPolicy}" />
|
||||
<ComboBox
|
||||
x:Name="cmbIcmpRoutingPolicy"
|
||||
Grid.Row="6"
|
||||
Grid.Column="1"
|
||||
Width="200"
|
||||
Margin="{StaticResource Margin4}"
|
||||
HorizontalAlignment="Left" />
|
||||
|
||||
<TextBlock
|
||||
Grid.Row="7"
|
||||
Grid.Column="0"
|
||||
|
||||
@@ -34,6 +34,7 @@ public partial class OptionSettingWindow : WindowBase<OptionSettingViewModel>
|
||||
cmbmux4SboxProtocol.ItemsSource = Global.SingboxMuxs;
|
||||
cmbMtu.ItemsSource = Global.TunMtus;
|
||||
cmbStack.ItemsSource = Global.TunStacks;
|
||||
cmbIcmpRoutingPolicy.ItemsSource = Global.TunIcmpRoutingPolicies;
|
||||
|
||||
cmbCoreType1.ItemsSource = Global.CoreTypes;
|
||||
cmbCoreType2.ItemsSource = Global.CoreTypes;
|
||||
@@ -114,6 +115,7 @@ public partial class OptionSettingWindow : WindowBase<OptionSettingViewModel>
|
||||
this.Bind(ViewModel, vm => vm.TunStack, v => v.cmbStack.SelectedValue).DisposeWith(disposables);
|
||||
this.Bind(ViewModel, vm => vm.TunMtu, v => v.cmbMtu.SelectedValue).DisposeWith(disposables);
|
||||
this.Bind(ViewModel, vm => vm.TunEnableIPv6Address, v => v.togEnableIPv6Address.IsChecked).DisposeWith(disposables);
|
||||
this.Bind(ViewModel, vm => vm.TunIcmpRouting, v => v.cmbIcmpRoutingPolicy.SelectedValue).DisposeWith(disposables);
|
||||
|
||||
this.Bind(ViewModel, vm => vm.CoreType1, v => v.cmbCoreType1.SelectedValue).DisposeWith(disposables);
|
||||
this.Bind(ViewModel, vm => vm.CoreType2, v => v.cmbCoreType2.SelectedValue).DisposeWith(disposables);
|
||||
|
||||
@@ -277,6 +277,20 @@
|
||||
Margin="{StaticResource Margin4}"
|
||||
Style="{StaticResource DefComboBox}" />
|
||||
|
||||
<TextBlock
|
||||
Grid.Row="3"
|
||||
Grid.Column="0"
|
||||
Margin="{StaticResource Margin4}"
|
||||
VerticalAlignment="Center"
|
||||
Style="{StaticResource ToolbarTextBlock}"
|
||||
Text="{x:Static resx:ResUI.TbUot}" />
|
||||
<ToggleButton
|
||||
x:Name="togUotEnabled3"
|
||||
Grid.Row="3"
|
||||
Grid.Column="1"
|
||||
Margin="{StaticResource Margin4}"
|
||||
HorizontalAlignment="Left" />
|
||||
|
||||
<TextBlock
|
||||
Grid.Row="4"
|
||||
Grid.Column="0"
|
||||
@@ -646,7 +660,7 @@
|
||||
Style="{StaticResource ToolbarTextBlock}"
|
||||
Text="{x:Static resx:ResUI.TbHeaderType8}" />
|
||||
<ComboBox
|
||||
x:Name="cmbHeaderType8"
|
||||
x:Name="cmbCongestionControl8"
|
||||
Grid.Row="3"
|
||||
Grid.Column="1"
|
||||
Width="200"
|
||||
@@ -772,13 +786,116 @@
|
||||
Style="{StaticResource ToolbarTextBlock}"
|
||||
Text="{x:Static resx:ResUI.TbId3}" />
|
||||
<TextBox
|
||||
x:Name="txtId10"
|
||||
x:Name="txtId11"
|
||||
Grid.Row="1"
|
||||
Grid.Column="1"
|
||||
Width="400"
|
||||
Margin="{StaticResource Margin4}"
|
||||
Style="{StaticResource DefTextBox}" />
|
||||
</Grid>
|
||||
<Grid
|
||||
x:Name="gridNaive"
|
||||
Grid.Row="2"
|
||||
Visibility="Hidden">
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition Height="Auto" />
|
||||
</Grid.RowDefinitions>
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="300" />
|
||||
<ColumnDefinition Width="Auto" />
|
||||
</Grid.ColumnDefinitions>
|
||||
|
||||
<TextBlock
|
||||
Grid.Row="1"
|
||||
Grid.Column="0"
|
||||
Margin="{StaticResource Margin4}"
|
||||
VerticalAlignment="Center"
|
||||
Style="{StaticResource ToolbarTextBlock}"
|
||||
Text="{x:Static resx:ResUI.TbUsername}" />
|
||||
<TextBox
|
||||
x:Name="txtId12"
|
||||
Grid.Row="1"
|
||||
Grid.Column="1"
|
||||
Width="400"
|
||||
Margin="{StaticResource Margin4}"
|
||||
Style="{StaticResource DefTextBox}" />
|
||||
|
||||
<TextBlock
|
||||
Grid.Row="2"
|
||||
Grid.Column="0"
|
||||
Margin="{StaticResource Margin4}"
|
||||
VerticalAlignment="Center"
|
||||
Style="{StaticResource ToolbarTextBlock}"
|
||||
Text="{x:Static resx:ResUI.TbId3}" />
|
||||
<TextBox
|
||||
x:Name="txtSecurity12"
|
||||
Grid.Row="2"
|
||||
Grid.Column="1"
|
||||
Width="400"
|
||||
Margin="{StaticResource Margin4}"
|
||||
Style="{StaticResource DefTextBox}" />
|
||||
|
||||
<TextBlock
|
||||
Grid.Row="3"
|
||||
Grid.Column="0"
|
||||
Margin="{StaticResource Margin4}"
|
||||
VerticalAlignment="Center"
|
||||
Style="{StaticResource ToolbarTextBlock}"
|
||||
Text="QUIC" />
|
||||
<StackPanel
|
||||
Grid.Row="3"
|
||||
Grid.Column="1"
|
||||
VerticalAlignment="Center"
|
||||
Orientation="Horizontal">
|
||||
<ToggleButton
|
||||
x:Name="togNaiveQuic12"
|
||||
Margin="{StaticResource Margin4}"
|
||||
HorizontalAlignment="Left" />
|
||||
<ComboBox
|
||||
x:Name="cmbCongestionControl12"
|
||||
Width="200"
|
||||
Margin="{StaticResource Margin4}"
|
||||
HorizontalAlignment="Right"
|
||||
materialDesign:HintAssist.Hint="{x:Static resx:ResUI.TbHeaderType8}"
|
||||
Style="{StaticResource DefComboBox}" />
|
||||
</StackPanel>
|
||||
|
||||
<TextBlock
|
||||
Grid.Row="4"
|
||||
Grid.Column="0"
|
||||
Margin="{StaticResource Margin4}"
|
||||
VerticalAlignment="Center"
|
||||
Style="{StaticResource ToolbarTextBlock}"
|
||||
Text="{x:Static resx:ResUI.TbInsecureConcurrency}" />
|
||||
<TextBox
|
||||
x:Name="txtInsecureConcurrency12"
|
||||
Grid.Row="4"
|
||||
Grid.Column="1"
|
||||
Width="200"
|
||||
Margin="{StaticResource Margin4}"
|
||||
HorizontalAlignment="Left"
|
||||
Style="{StaticResource DefTextBox}" />
|
||||
|
||||
<TextBlock
|
||||
Grid.Row="5"
|
||||
Grid.Column="0"
|
||||
Margin="{StaticResource Margin4}"
|
||||
VerticalAlignment="Center"
|
||||
Style="{StaticResource ToolbarTextBlock}"
|
||||
Text="{x:Static resx:ResUI.TbUot}" />
|
||||
<ToggleButton
|
||||
x:Name="togUotEnabled12"
|
||||
Grid.Row="5"
|
||||
Grid.Column="1"
|
||||
Margin="{StaticResource Margin4}"
|
||||
HorizontalAlignment="Left" />
|
||||
|
||||
</Grid>
|
||||
|
||||
<Separator
|
||||
x:Name="sepa2"
|
||||
|
||||
@@ -75,7 +75,7 @@ public partial class AddServerWindow
|
||||
cmbFingerprint.Text = string.Empty;
|
||||
gridFinalmask.Visibility = Visibility.Collapsed;
|
||||
|
||||
cmbHeaderType8.ItemsSource = Global.TuicCongestionControls;
|
||||
cmbCongestionControl8.ItemsSource = Global.TuicCongestionControls;
|
||||
break;
|
||||
|
||||
case EConfigType.WireGuard:
|
||||
@@ -89,10 +89,28 @@ public partial class AddServerWindow
|
||||
|
||||
case EConfigType.Anytls:
|
||||
gridAnytls.Visibility = Visibility.Visible;
|
||||
sepa2.Visibility = Visibility.Collapsed;
|
||||
gridTransport.Visibility = Visibility.Collapsed;
|
||||
cmbCoreType.IsEnabled = false;
|
||||
lstStreamSecurity.Add(Global.StreamSecurityReality);
|
||||
gridFinalmask.Visibility = Visibility.Collapsed;
|
||||
break;
|
||||
|
||||
case EConfigType.Naive:
|
||||
gridNaive.Visibility = Visibility.Visible;
|
||||
sepa2.Visibility = Visibility.Collapsed;
|
||||
gridTransport.Visibility = Visibility.Collapsed;
|
||||
cmbCoreType.IsEnabled = false;
|
||||
gridFinalmask.Visibility = Visibility.Collapsed;
|
||||
cmbFingerprint.IsEnabled = false;
|
||||
cmbFingerprint.Text = string.Empty;
|
||||
cmbAlpn.IsEnabled = false;
|
||||
cmbAlpn.Text = string.Empty;
|
||||
cmbAllowInsecure.IsEnabled = false;
|
||||
cmbAllowInsecure.Text = string.Empty;
|
||||
|
||||
cmbCongestionControl12.ItemsSource = Global.NaiveCongestionControls;
|
||||
break;
|
||||
}
|
||||
cmbStreamSecurity.ItemsSource = lstStreamSecurity;
|
||||
|
||||
@@ -117,6 +135,7 @@ public partial class AddServerWindow
|
||||
case EConfigType.Shadowsocks:
|
||||
this.Bind(ViewModel, vm => vm.SelectedSource.Password, v => v.txtId3.Text).DisposeWith(disposables);
|
||||
this.Bind(ViewModel, vm => vm.SsMethod, v => v.cmbSecurity3.Text).DisposeWith(disposables);
|
||||
this.Bind(ViewModel, vm => vm.Uot, v => v.togUotEnabled3.IsChecked).DisposeWith(disposables);
|
||||
this.Bind(ViewModel, vm => vm.SelectedSource.MuxEnabled, v => v.togmuxEnabled3.IsChecked).DisposeWith(disposables);
|
||||
break;
|
||||
|
||||
@@ -151,7 +170,7 @@ public partial class AddServerWindow
|
||||
case EConfigType.TUIC:
|
||||
this.Bind(ViewModel, vm => vm.SelectedSource.Username, v => v.txtId8.Text).DisposeWith(disposables);
|
||||
this.Bind(ViewModel, vm => vm.SelectedSource.Password, v => v.txtSecurity8.Text).DisposeWith(disposables);
|
||||
this.Bind(ViewModel, vm => vm.SelectedSource.HeaderType, v => v.cmbHeaderType8.Text).DisposeWith(disposables);
|
||||
this.Bind(ViewModel, vm => vm.CongestionControl, v => v.cmbCongestionControl8.Text).DisposeWith(disposables);
|
||||
break;
|
||||
|
||||
case EConfigType.WireGuard:
|
||||
@@ -163,7 +182,16 @@ public partial class AddServerWindow
|
||||
break;
|
||||
|
||||
case EConfigType.Anytls:
|
||||
this.Bind(ViewModel, vm => vm.SelectedSource.Password, v => v.txtId10.Text).DisposeWith(disposables);
|
||||
this.Bind(ViewModel, vm => vm.SelectedSource.Password, v => v.txtId11.Text).DisposeWith(disposables);
|
||||
break;
|
||||
|
||||
case EConfigType.Naive:
|
||||
this.Bind(ViewModel, vm => vm.SelectedSource.Username, v => v.txtId12.Text).DisposeWith(disposables);
|
||||
this.Bind(ViewModel, vm => vm.SelectedSource.Password, v => v.txtSecurity12.Text).DisposeWith(disposables);
|
||||
this.Bind(ViewModel, vm => vm.NaiveQuic, v => v.togNaiveQuic12.IsChecked).DisposeWith(disposables);
|
||||
this.Bind(ViewModel, vm => vm.CongestionControl, v => v.cmbCongestionControl12.Text).DisposeWith(disposables);
|
||||
this.Bind(ViewModel, vm => vm.InsecureConcurrency, v => v.txtInsecureConcurrency12.Text).DisposeWith(disposables);
|
||||
this.Bind(ViewModel, vm => vm.Uot, v => v.togUotEnabled12.IsChecked).DisposeWith(disposables);
|
||||
break;
|
||||
}
|
||||
this.Bind(ViewModel, vm => vm.SelectedSource.Network, v => v.cmbNetwork.Text).DisposeWith(disposables);
|
||||
|
||||
@@ -124,6 +124,10 @@
|
||||
x:Name="menuAddAnytlsServer"
|
||||
Height="{StaticResource MenuItemHeight}"
|
||||
Header="{x:Static resx:ResUI.menuAddAnytlsServer}" />
|
||||
<MenuItem
|
||||
x:Name="menuAddNaiveServer"
|
||||
Height="{StaticResource MenuItemHeight}"
|
||||
Header="{x:Static resx:ResUI.menuAddNaiveServer}" />
|
||||
</MenuItem>
|
||||
</Menu>
|
||||
<Separator />
|
||||
|
||||
@@ -71,6 +71,7 @@ public partial class MainWindow
|
||||
this.BindCommand(ViewModel, vm => vm.AddTuicServerCmd, v => v.menuAddTuicServer).DisposeWith(disposables);
|
||||
this.BindCommand(ViewModel, vm => vm.AddWireguardServerCmd, v => v.menuAddWireguardServer).DisposeWith(disposables);
|
||||
this.BindCommand(ViewModel, vm => vm.AddAnytlsServerCmd, v => v.menuAddAnytlsServer).DisposeWith(disposables);
|
||||
this.BindCommand(ViewModel, vm => vm.AddNaiveServerCmd, v => v.menuAddNaiveServer).DisposeWith(disposables);
|
||||
this.BindCommand(ViewModel, vm => vm.AddCustomServerCmd, v => v.menuAddCustomServer).DisposeWith(disposables);
|
||||
this.BindCommand(ViewModel, vm => vm.AddPolicyGroupServerCmd, v => v.menuAddPolicyGroupServer).DisposeWith(disposables);
|
||||
this.BindCommand(ViewModel, vm => vm.AddProxyChainServerCmd, v => v.menuAddProxyChainServer).DisposeWith(disposables);
|
||||
|
||||
@@ -1076,6 +1076,22 @@
|
||||
HorizontalAlignment="Left"
|
||||
Style="{StaticResource DefComboBox}" />
|
||||
|
||||
<TextBlock
|
||||
Grid.Row="6"
|
||||
Grid.Column="0"
|
||||
Margin="{StaticResource Margin8}"
|
||||
VerticalAlignment="Center"
|
||||
Style="{StaticResource ToolbarTextBlock}"
|
||||
Text="{x:Static resx:ResUI.TbIcmpRoutingPolicy}" />
|
||||
<ComboBox
|
||||
x:Name="cmbIcmpRoutingPolicy"
|
||||
Grid.Row="6"
|
||||
Grid.Column="1"
|
||||
Width="200"
|
||||
Margin="{StaticResource Margin8}"
|
||||
HorizontalAlignment="Left"
|
||||
Style="{StaticResource DefComboBox}" />
|
||||
|
||||
<TextBlock
|
||||
Grid.Row="7"
|
||||
Grid.Column="0"
|
||||
|
||||
@@ -31,6 +31,7 @@ public partial class OptionSettingWindow
|
||||
cmbmux4SboxProtocol.ItemsSource = Global.SingboxMuxs;
|
||||
cmbMtu.ItemsSource = Global.TunMtus;
|
||||
cmbStack.ItemsSource = Global.TunStacks;
|
||||
cmbIcmpRoutingPolicy.ItemsSource = Global.TunIcmpRoutingPolicies;
|
||||
|
||||
cmbCoreType1.ItemsSource = Global.CoreTypes;
|
||||
cmbCoreType2.ItemsSource = Global.CoreTypes;
|
||||
@@ -119,6 +120,7 @@ public partial class OptionSettingWindow
|
||||
this.Bind(ViewModel, vm => vm.TunStack, v => v.cmbStack.Text).DisposeWith(disposables);
|
||||
this.Bind(ViewModel, vm => vm.TunMtu, v => v.cmbMtu.Text).DisposeWith(disposables);
|
||||
this.Bind(ViewModel, vm => vm.TunEnableIPv6Address, v => v.togEnableIPv6Address.IsChecked).DisposeWith(disposables);
|
||||
this.Bind(ViewModel, vm => vm.TunIcmpRouting, v => v.cmbIcmpRoutingPolicy.Text).DisposeWith(disposables);
|
||||
|
||||
this.Bind(ViewModel, vm => vm.CoreType1, v => v.cmbCoreType1.Text).DisposeWith(disposables);
|
||||
this.Bind(ViewModel, vm => vm.CoreType2, v => v.cmbCoreType2.Text).DisposeWith(disposables);
|
||||
|
||||
@@ -189,4 +189,15 @@ fun String.concatUrl(vararg paths: String): String {
|
||||
}
|
||||
|
||||
return builder.toString()
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper function to match text either by Regex or literal string.
|
||||
*/
|
||||
fun String.matchesPattern(regex: Regex?, keyword: String?, ignoreCase: Boolean = true): Boolean {
|
||||
if (keyword.isNullOrEmpty()) {
|
||||
return true
|
||||
}
|
||||
return regex?.containsMatchIn(this)
|
||||
?: this.contains(keyword, ignoreCase = ignoreCase)
|
||||
}
|
||||
@@ -71,6 +71,8 @@ class GroupServerFragment : BaseFragment<FragmentGroupServerBinding>(),
|
||||
itemTouchHelper?.attachToRecyclerView(binding.recyclerView)
|
||||
|
||||
binding.refreshLayout.setOnRefreshListener(this)
|
||||
// Set the distance to trigger sync to 160dp
|
||||
binding.refreshLayout.setDistanceToTriggerSync((160 * resources.displayMetrics.density).toInt())
|
||||
|
||||
mainViewModel.updateListAction.observe(viewLifecycleOwner) { index ->
|
||||
if (mainViewModel.subscriptionId != subId) {
|
||||
|
||||
@@ -19,6 +19,7 @@ import com.v2ray.ang.dto.ServersCache
|
||||
import com.v2ray.ang.dto.SubscriptionCache
|
||||
import com.v2ray.ang.dto.SubscriptionUpdateResult
|
||||
import com.v2ray.ang.dto.TestServiceMessage
|
||||
import com.v2ray.ang.extension.matchesPattern
|
||||
import com.v2ray.ang.extension.serializable
|
||||
import com.v2ray.ang.extension.toastError
|
||||
import com.v2ray.ang.extension.toastSuccess
|
||||
@@ -35,6 +36,7 @@ import kotlinx.coroutines.cancelChildren
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.withContext
|
||||
import java.util.Collections
|
||||
import java.util.regex.PatternSyntaxException
|
||||
|
||||
class MainViewModel(application: Application) : AndroidViewModel(application) {
|
||||
private var serverList = mutableListOf<String>() // MmkvManager.decodeServerList()
|
||||
@@ -117,7 +119,12 @@ class MainViewModel(application: Application) : AndroidViewModel(application) {
|
||||
@Synchronized
|
||||
fun updateCache() {
|
||||
serversCache.clear()
|
||||
val kw = keywordFilter.trim().lowercase()
|
||||
val kw = keywordFilter.trim()
|
||||
val searchRegex = try {
|
||||
if (kw.isNotEmpty()) Regex(kw, setOf(RegexOption.IGNORE_CASE)) else null
|
||||
} catch (e: PatternSyntaxException) {
|
||||
null // Fallback to literal search if regex is invalid
|
||||
}
|
||||
for (guid in serverList) {
|
||||
val profile = MmkvManager.decodeServerConfig(guid) ?: continue
|
||||
if (kw.isEmpty()) {
|
||||
@@ -125,11 +132,15 @@ class MainViewModel(application: Application) : AndroidViewModel(application) {
|
||||
continue
|
||||
}
|
||||
|
||||
val remarks = profile.remarks.lowercase()
|
||||
val description = profile.description.orEmpty().lowercase()
|
||||
val server = profile.server.orEmpty().lowercase()
|
||||
|
||||
if (remarks.contains(kw) || description.contains(kw) || server.contains(kw)) {
|
||||
val remarks = profile.remarks
|
||||
val description = profile.description.orEmpty()
|
||||
val server = profile.server.orEmpty()
|
||||
val protocol = profile.configType.name
|
||||
if (remarks.matchesPattern(searchRegex, kw)
|
||||
|| description.matchesPattern(searchRegex, kw)
|
||||
|| server.matchesPattern(searchRegex, kw)
|
||||
|| protocol.matchesPattern(searchRegex, kw)
|
||||
) {
|
||||
serversCache.add(ServersCache(guid, profile))
|
||||
}
|
||||
}
|
||||
@@ -479,4 +490,4 @@ class MainViewModel(application: Application) : AndroidViewModel(application) {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -297,8 +297,8 @@
|
||||
<string name="title_update_config_count">Обновлено профилей: %d</string>
|
||||
<string name="title_update_subscription_result">Обновлено профилей: %1$d (успешно: %2$d, ошибок: %3$d, пропущено: %4$d)</string>
|
||||
<string name="title_update_subscription_no_subscription">Нет подписок</string>
|
||||
<string name="toast_server_not_found_in_group">Selected server not found in current group</string>
|
||||
<string name="toast_fragment_not_available">Unable to locate current view</string>
|
||||
<string name="toast_server_not_found_in_group">Выбранный профиль не найден в текущей группе</string>
|
||||
<string name="toast_fragment_not_available">Фрагмент недоступен</string>
|
||||
|
||||
<string name="tasker_start_service">Запуск службы</string>
|
||||
<string name="tasker_setting_confirm">Подтвердить</string>
|
||||
|
||||
@@ -10,6 +10,8 @@
|
||||
|
||||
[](https://happ.su)
|
||||
|
||||
[](https://blanc.link/VMTSDqW)
|
||||
|
||||
[**Sponsor Xray-core**](https://github.com/XTLS/Xray-core/issues/3668)
|
||||
|
||||
## Donation & NFTs
|
||||
|
||||
@@ -214,7 +214,7 @@ func (s *DoHNameServer) dohHTTPSContext(ctx context.Context, b []byte) ([]byte,
|
||||
|
||||
req.Header.Add("Accept", "application/dns-message")
|
||||
req.Header.Add("Content-Type", "application/dns-message")
|
||||
req.Header.Set("User-Agent", utils.ChromeUA)
|
||||
utils.TryDefaultHeadersWith(req.Header, "fetch")
|
||||
req.Header.Set("X-Padding", utils.H2Base62Pad(crypto.RandBetween(100, 1000)))
|
||||
|
||||
hc := s.httpClient
|
||||
|
||||
@@ -32,6 +32,10 @@ func (o *Observer) GetObservation(ctx context.Context) (proto.Message, error) {
|
||||
return &observatory.ObservationResult{Status: o.createResult()}, nil
|
||||
}
|
||||
|
||||
func (o *Observer) Check(tag []string) {
|
||||
o.hp.Check(tag)
|
||||
}
|
||||
|
||||
func (o *Observer) createResult() []*observatory.OutboundStatus {
|
||||
var result []*observatory.OutboundStatus
|
||||
o.hp.access.Lock()
|
||||
|
||||
@@ -62,7 +62,7 @@ func (s *pingClient) MeasureDelay(httpMethod string) (time.Duration, error) {
|
||||
if err != nil {
|
||||
return rttFailed, err
|
||||
}
|
||||
req.Header.Set("User-Agent", utils.ChromeUA)
|
||||
utils.TryDefaultHeadersWith(req.Header, "nav")
|
||||
|
||||
start := time.Now()
|
||||
resp, err := s.httpClient.Do(req)
|
||||
|
||||
@@ -164,7 +164,7 @@ func (o *Observer) probe(outbound string) ProbeResult {
|
||||
probeURL = o.config.ProbeUrl
|
||||
}
|
||||
req, _ := http.NewRequest(http.MethodGet, probeURL, nil)
|
||||
req.Header.Set("User-Agent", utils.ChromeUA)
|
||||
utils.TryDefaultHeadersWith(req.Header, "nav")
|
||||
response, err := httpClient.Do(req)
|
||||
if err != nil {
|
||||
return errors.New("outbound failed to relay connection").Base(err)
|
||||
|
||||
@@ -4,8 +4,11 @@ package crypto // import "github.com/xtls/xray-core/common/crypto"
|
||||
import (
|
||||
"crypto/rand"
|
||||
"math/big"
|
||||
|
||||
"github.com/xtls/xray-core/common"
|
||||
)
|
||||
|
||||
// [,)
|
||||
func RandBetween(from int64, to int64) int64 {
|
||||
if from == to {
|
||||
return from
|
||||
@@ -16,3 +19,20 @@ func RandBetween(from int64, to int64) int64 {
|
||||
bigInt, _ := rand.Int(rand.Reader, big.NewInt(to-from))
|
||||
return from + bigInt.Int64()
|
||||
}
|
||||
|
||||
// [,]
|
||||
func RandBytesBetween(b []byte, from, to byte) {
|
||||
common.Must2(rand.Read(b))
|
||||
|
||||
if from > to {
|
||||
from, to = to, from
|
||||
}
|
||||
|
||||
if to-from == 255 {
|
||||
return
|
||||
}
|
||||
|
||||
for i := range b {
|
||||
b[i] = from + b[i]%(to-from+1)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,6 +4,8 @@ import (
|
||||
"math/rand"
|
||||
"strconv"
|
||||
"time"
|
||||
"net/http"
|
||||
"strings"
|
||||
|
||||
"github.com/klauspost/cpuid/v2"
|
||||
)
|
||||
@@ -24,5 +26,166 @@ func ChromeVersion() int {
|
||||
return version - 1
|
||||
}
|
||||
|
||||
// ChromeUA provides default browser User-Agent based on CPU-seeded PRNG.
|
||||
var ChromeUA = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/" + strconv.Itoa(ChromeVersion()) + ".0.0.0 Safari/537.36"
|
||||
// The full Chromium brand GREASE implementation
|
||||
var clientHintGreaseNA = []string{" ", "(", ":", "-", ".", "/", ")", ";", "=", "?", "_"}
|
||||
var clientHintVersionNA = []string{"8", "99", "24"}
|
||||
var clientHintShuffle3 = [][3]int{{0, 1, 2}, {0, 2, 1}, {1, 0, 2}, {1, 2, 0}, {2, 0, 1}, {2, 1, 0}}
|
||||
var clientHintShuffle4 = [][4]int{
|
||||
{0, 1, 2, 3}, {0, 1, 3, 2}, {0, 2, 1, 3}, {0, 2, 3, 1}, {0, 3, 1, 2}, {0, 3, 2, 1},
|
||||
{1, 0, 2, 3}, {1, 0, 3, 2}, {1, 2, 0, 3}, {1, 2, 3, 0}, {1, 3, 0, 2}, {1, 3, 2, 0},
|
||||
{2, 0, 1, 3}, {2, 0, 3, 1}, {2, 1, 0, 3}, {2, 1, 3, 0}, {2, 3, 0, 1}, {2, 3, 1, 0},
|
||||
{3, 0, 1, 2}, {3, 0, 2, 1}, {3, 1, 0, 2}, {3, 1, 2, 0}, {3, 2, 0, 1}, {3, 2, 1, 0}}
|
||||
func getGreasedChInvalidBrand(seed int) string {
|
||||
return "\"Not" + clientHintGreaseNA[seed % len(clientHintGreaseNA)] + "A" + clientHintGreaseNA[(seed + 1) % len(clientHintGreaseNA)] + "Brand\";v=\"" + clientHintVersionNA[seed % len(clientHintVersionNA)] + "\"";
|
||||
}
|
||||
func getGreasedChOrder(brandLength int, seed int) []int {
|
||||
switch brandLength {
|
||||
case 1:
|
||||
return []int{0}
|
||||
case 2:
|
||||
return []int{seed % brandLength, (seed + 1) % brandLength}
|
||||
case 3:
|
||||
return clientHintShuffle3[seed % len(clientHintShuffle3)][:]
|
||||
default:
|
||||
return clientHintShuffle4[seed % len(clientHintShuffle4)][:]
|
||||
}
|
||||
return []int{}
|
||||
}
|
||||
func getUngreasedChUa(majorVersion int, forkName string) []string {
|
||||
// Set the capacity to 4, the maximum allowed brand size, so Go will never allocate memory twice
|
||||
baseChUa := make([]string, 0, 4)
|
||||
baseChUa = append(baseChUa, getGreasedChInvalidBrand(majorVersion),
|
||||
"\"Chromium\";v=\"" + strconv.Itoa(majorVersion) + "\"")
|
||||
switch forkName {
|
||||
case "chrome":
|
||||
baseChUa = append(baseChUa, "\"Google Chrome\";v=\"" + strconv.Itoa(majorVersion) + "\"")
|
||||
case "edge":
|
||||
baseChUa = append(baseChUa, "\"Microsoft Edge\";v=\"" + strconv.Itoa(majorVersion) + "\"")
|
||||
}
|
||||
return baseChUa
|
||||
}
|
||||
func getGreasedChUa(majorVersion int, forkName string) string {
|
||||
ungreasedCh := getUngreasedChUa(majorVersion, forkName)
|
||||
shuffleMap := getGreasedChOrder(len(ungreasedCh), majorVersion)
|
||||
shuffledCh := make([]string, len(ungreasedCh))
|
||||
for i, e := range shuffleMap {
|
||||
shuffledCh[e] = ungreasedCh[i]
|
||||
}
|
||||
return strings.Join(shuffledCh, ", ")
|
||||
}
|
||||
|
||||
// It's better to pin on Firefox ESR releases, and there could be a Firefox ESR version generator later.
|
||||
// However, if the Firefox fingerprint in uTLS doesn't have its update cadence match that of Firefox ESR, then it's better to update the Firefox version manually instead every time a new major ESR release is available.
|
||||
var FirefoxUA = "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:140.0) Gecko/20100101 Firefox/140.0"
|
||||
|
||||
// The code below provides a coherent default browser user agent string based on a CPU-seeded PRNG.
|
||||
var AnchoredChromeVersion = ChromeVersion()
|
||||
var ChromeUA = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/" + strconv.Itoa(AnchoredChromeVersion) + ".0.0.0 Safari/537.36"
|
||||
var ChromeUACH = getGreasedChUa(AnchoredChromeVersion, "chrome")
|
||||
var MSEdgeUA = ChromeUA + "Edg/" + strconv.Itoa(AnchoredChromeVersion) + ".0.0.0"
|
||||
var MSEdgeUACH = getGreasedChUa(AnchoredChromeVersion, "edge")
|
||||
|
||||
func applyMasqueradedHeaders(header http.Header, browser string, variant string) {
|
||||
// Browser-specific.
|
||||
switch browser {
|
||||
case "chrome":
|
||||
header["Sec-CH-UA"] = []string{ChromeUACH}
|
||||
header["Sec-CH-UA-Mobile"] = []string{"?0"}
|
||||
header["Sec-CH-UA-Platform"] = []string{"\"Windows\""}
|
||||
header["DNT"] = []string{"1"}
|
||||
header.Set("User-Agent", ChromeUA)
|
||||
header.Set("Accept-Language", "en-US,en;q=0.9")
|
||||
case "edge":
|
||||
header["Sec-CH-UA"] = []string{MSEdgeUACH}
|
||||
header["Sec-CH-UA-Mobile"] = []string{"?0"}
|
||||
header["Sec-CH-UA-Platform"] = []string{"\"Windows\""}
|
||||
header["DNT"] = []string{"1"}
|
||||
header.Set("User-Agent", MSEdgeUA)
|
||||
header.Set("Accept-Language", "en-US,en;q=0.9")
|
||||
case "firefox":
|
||||
header.Set("User-Agent", FirefoxUA)
|
||||
header["DNT"] = []string{"1"}
|
||||
header.Set("Accept-Language", "en-US,en;q=0.5")
|
||||
case "golang":
|
||||
// Expose the default net/http header.
|
||||
header.Del("User-Agent")
|
||||
return
|
||||
}
|
||||
// Context-specific.
|
||||
switch variant {
|
||||
case "nav":
|
||||
if header.Get("Cache-Control") == "" {
|
||||
switch browser {
|
||||
case "chrome", "edge":
|
||||
header.Set("Cache-Control", "max-age=0")
|
||||
}
|
||||
}
|
||||
header.Set("Upgrade-Insecure-Requests", "1")
|
||||
if header.Get("Accept") == "" {
|
||||
switch browser {
|
||||
case "chrome", "edge":
|
||||
header.Set("Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,image/jxl,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7")
|
||||
case "firefox":
|
||||
header.Set("Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8")
|
||||
}
|
||||
}
|
||||
header.Set("Sec-Fetch-Site", "none")
|
||||
header.Set("Sec-Fetch-Mode", "navigate")
|
||||
header.Set("Sec-Fetch-User", "?1")
|
||||
header.Set("Sec-Fetch-Dest", "document")
|
||||
header.Set("Priority", "u=0, i")
|
||||
case "ws":
|
||||
header.Set("Sec-Fetch-Mode", "websocket")
|
||||
header.Set("Sec-Fetch-Dest", "empty")
|
||||
header.Set("Sec-Fetch-Site", "same-origin")
|
||||
if header.Get("Cache-Control") == "" {
|
||||
header.Set("Cache-Control", "no-cache")
|
||||
}
|
||||
if header.Get("Pragma") == "" {
|
||||
header.Set("Pragma", "no-cache")
|
||||
}
|
||||
if header.Get("Accept") == "" {
|
||||
header.Set("Accept", "*/*")
|
||||
}
|
||||
case "fetch":
|
||||
header.Set("Sec-Fetch-Mode", "cors")
|
||||
header.Set("Sec-Fetch-Dest", "empty")
|
||||
header.Set("Sec-Fetch-Site", "same-origin")
|
||||
if header.Get("Priority") == "" {
|
||||
switch browser {
|
||||
case "chrome", "edge":
|
||||
header.Set("Priority", "u=1, i")
|
||||
case "firefox":
|
||||
header.Set("Priority", "u=4")
|
||||
}
|
||||
}
|
||||
if header.Get("Cache-Control") == "" {
|
||||
header.Set("Cache-Control", "no-cache")
|
||||
}
|
||||
if header.Get("Pragma") == "" {
|
||||
header.Set("Pragma", "no-cache")
|
||||
}
|
||||
if header.Get("Accept") == "" {
|
||||
header.Set("Accept", "*/*")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TryDefaultHeadersWith(header http.Header, variant string) {
|
||||
// The global UA special value handler for transports. Used to be called HandleTransportUASettings.
|
||||
// Just a FYI to whoever needing to fix this piece of code after some spontaneous event, I tried to make the two methods separate to let the code be cleaner and more organized.
|
||||
if len(header.Values("User-Agent")) < 1 {
|
||||
applyMasqueradedHeaders(header, "chrome", variant)
|
||||
} else {
|
||||
switch header.Get("User-Agent") {
|
||||
case "chrome":
|
||||
applyMasqueradedHeaders(header, "chrome", variant)
|
||||
case "firefox":
|
||||
applyMasqueradedHeaders(header, "firefox", variant)
|
||||
case "edge":
|
||||
applyMasqueradedHeaders(header, "edge", variant)
|
||||
case "golang":
|
||||
applyMasqueradedHeaders(header, "golang", variant)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -13,6 +13,11 @@ type Observatory interface {
|
||||
GetObservation(ctx context.Context) (proto.Message, error)
|
||||
}
|
||||
|
||||
type BurstObservatory interface {
|
||||
Observatory
|
||||
Check(tag []string)
|
||||
}
|
||||
|
||||
func ObservatoryType() interface{} {
|
||||
return (*Observatory)(nil)
|
||||
}
|
||||
|
||||
@@ -44,6 +44,34 @@ func (v *AuthenticatorRequest) Build() (*http.RequestConfig, error) {
|
||||
Name: "User-Agent",
|
||||
Value: []string{utils.ChromeUA},
|
||||
},
|
||||
{
|
||||
Name: "Sec-CH-UA",
|
||||
Value: []string{utils.ChromeUACH},
|
||||
},
|
||||
{
|
||||
Name: "Sec-CH-UA-Mobile",
|
||||
Value: []string{"?0"},
|
||||
},
|
||||
{
|
||||
Name: "Sec-CH-UA-Platform",
|
||||
Value: []string{"Windows"},
|
||||
},
|
||||
{
|
||||
Name: "Sec-Fetch-Mode",
|
||||
Value: []string{"no-cors", "cors", "same-origin"},
|
||||
},
|
||||
{
|
||||
Name: "Sec-Fetch-Dest",
|
||||
Value: []string{"empty"},
|
||||
},
|
||||
{
|
||||
Name: "Sec-Fetch-Site",
|
||||
Value: []string{"none"},
|
||||
},
|
||||
{
|
||||
Name: "Sec-Fetch-User",
|
||||
Value: []string{"?1"},
|
||||
},
|
||||
{
|
||||
Name: "Accept-Encoding",
|
||||
Value: []string{"gzip, deflate"},
|
||||
|
||||
@@ -909,6 +909,12 @@ func (c *REALITYConfig) Build() (proto.Message, error) {
|
||||
}
|
||||
}
|
||||
|
||||
for _, sn := range config.ServerNames {
|
||||
if strings.Contains(sn, "apple") || strings.Contains(sn, "icloud") {
|
||||
errors.LogWarning(context.Background(), `REALITY: Choosing apple, icloud, etc. as the target may get your IP blocked by the GFW`)
|
||||
}
|
||||
}
|
||||
|
||||
config.LimitFallbackUpload = new(reality.LimitFallback)
|
||||
config.LimitFallbackUpload.AfterBytes = c.LimitFallbackUpload.AfterBytes
|
||||
config.LimitFallbackUpload.BytesPerSec = c.LimitFallbackUpload.BytesPerSec
|
||||
@@ -1254,10 +1260,11 @@ var (
|
||||
)
|
||||
|
||||
type TCPItem struct {
|
||||
Delay Int32Range `json:"delay"`
|
||||
Rand int32 `json:"rand"`
|
||||
Type string `json:"type"`
|
||||
Packet json.RawMessage `json:"packet"`
|
||||
Delay Int32Range `json:"delay"`
|
||||
Rand int32 `json:"rand"`
|
||||
RandRange *Int32Range `json:"randRange"`
|
||||
Type string `json:"type"`
|
||||
Packet json.RawMessage `json:"packet"`
|
||||
}
|
||||
|
||||
type HeaderCustomTCP struct {
|
||||
@@ -1289,10 +1296,18 @@ func (c *HeaderCustomTCP) Build() (proto.Message, error) {
|
||||
}
|
||||
}
|
||||
|
||||
errInvalidRange := errors.New("invalid randRange")
|
||||
|
||||
clients := make([]*custom.TCPSequence, len(c.Clients))
|
||||
for i, value := range c.Clients {
|
||||
clients[i] = &custom.TCPSequence{}
|
||||
for _, item := range value {
|
||||
if item.RandRange == nil {
|
||||
item.RandRange = &Int32Range{From: 0, To: 255}
|
||||
}
|
||||
if item.RandRange.From < 0 || item.RandRange.To > 255 {
|
||||
return nil, errInvalidRange
|
||||
}
|
||||
var err error
|
||||
if item.Packet, err = PraseByteSlice(item.Packet, item.Type); err != nil {
|
||||
return nil, err
|
||||
@@ -1301,6 +1316,8 @@ func (c *HeaderCustomTCP) Build() (proto.Message, error) {
|
||||
DelayMin: int64(item.Delay.From),
|
||||
DelayMax: int64(item.Delay.To),
|
||||
Rand: item.Rand,
|
||||
RandMin: item.RandRange.From,
|
||||
RandMax: item.RandRange.To,
|
||||
Packet: item.Packet,
|
||||
})
|
||||
}
|
||||
@@ -1310,6 +1327,12 @@ func (c *HeaderCustomTCP) Build() (proto.Message, error) {
|
||||
for i, value := range c.Servers {
|
||||
servers[i] = &custom.TCPSequence{}
|
||||
for _, item := range value {
|
||||
if item.RandRange == nil {
|
||||
item.RandRange = &Int32Range{From: 0, To: 255}
|
||||
}
|
||||
if item.RandRange.From < 0 || item.RandRange.To > 255 {
|
||||
return nil, errInvalidRange
|
||||
}
|
||||
var err error
|
||||
if item.Packet, err = PraseByteSlice(item.Packet, item.Type); err != nil {
|
||||
return nil, err
|
||||
@@ -1318,6 +1341,8 @@ func (c *HeaderCustomTCP) Build() (proto.Message, error) {
|
||||
DelayMin: int64(item.Delay.From),
|
||||
DelayMax: int64(item.Delay.To),
|
||||
Rand: item.Rand,
|
||||
RandMin: item.RandRange.From,
|
||||
RandMax: item.RandRange.To,
|
||||
Packet: item.Packet,
|
||||
})
|
||||
}
|
||||
@@ -1327,6 +1352,12 @@ func (c *HeaderCustomTCP) Build() (proto.Message, error) {
|
||||
for i, value := range c.Errors {
|
||||
errors[i] = &custom.TCPSequence{}
|
||||
for _, item := range value {
|
||||
if item.RandRange == nil {
|
||||
item.RandRange = &Int32Range{From: 0, To: 255}
|
||||
}
|
||||
if item.RandRange.From < 0 || item.RandRange.To > 255 {
|
||||
return nil, errInvalidRange
|
||||
}
|
||||
var err error
|
||||
if item.Packet, err = PraseByteSlice(item.Packet, item.Type); err != nil {
|
||||
return nil, err
|
||||
@@ -1335,6 +1366,8 @@ func (c *HeaderCustomTCP) Build() (proto.Message, error) {
|
||||
DelayMin: int64(item.Delay.From),
|
||||
DelayMax: int64(item.Delay.To),
|
||||
Rand: item.Rand,
|
||||
RandMin: item.RandRange.From,
|
||||
RandMax: item.RandRange.To,
|
||||
Packet: item.Packet,
|
||||
})
|
||||
}
|
||||
@@ -1433,9 +1466,10 @@ func (c *NoiseMask) Build() (proto.Message, error) {
|
||||
}
|
||||
|
||||
type UDPItem struct {
|
||||
Rand int32 `json:"rand"`
|
||||
Type string `json:"type"`
|
||||
Packet json.RawMessage `json:"packet"`
|
||||
Rand int32 `json:"rand"`
|
||||
RandRange *Int32Range `json:"randRange"`
|
||||
Type string `json:"type"`
|
||||
Packet json.RawMessage `json:"packet"`
|
||||
}
|
||||
|
||||
type HeaderCustomUDP struct {
|
||||
@@ -1457,25 +1491,41 @@ func (c *HeaderCustomUDP) Build() (proto.Message, error) {
|
||||
|
||||
client := make([]*custom.UDPItem, 0, len(c.Client))
|
||||
for _, item := range c.Client {
|
||||
if item.RandRange == nil {
|
||||
item.RandRange = &Int32Range{From: 0, To: 255}
|
||||
}
|
||||
if item.RandRange.From < 0 || item.RandRange.To > 255 {
|
||||
return nil, errors.New("invalid randRange")
|
||||
}
|
||||
var err error
|
||||
if item.Packet, err = PraseByteSlice(item.Packet, item.Type); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
client = append(client, &custom.UDPItem{
|
||||
Rand: item.Rand,
|
||||
Packet: item.Packet,
|
||||
Rand: item.Rand,
|
||||
RandMin: item.RandRange.From,
|
||||
RandMax: item.RandRange.To,
|
||||
Packet: item.Packet,
|
||||
})
|
||||
}
|
||||
|
||||
server := make([]*custom.UDPItem, 0, len(c.Server))
|
||||
for _, item := range c.Server {
|
||||
if item.RandRange == nil {
|
||||
item.RandRange = &Int32Range{From: 0, To: 255}
|
||||
}
|
||||
if item.RandRange.From < 0 || item.RandRange.To > 255 {
|
||||
return nil, errors.New("invalid randRange")
|
||||
}
|
||||
var err error
|
||||
if item.Packet, err = PraseByteSlice(item.Packet, item.Type); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
server = append(server, &custom.UDPItem{
|
||||
Rand: item.Rand,
|
||||
Packet: item.Packet,
|
||||
Rand: item.Rand,
|
||||
RandMin: item.RandRange.From,
|
||||
RandMax: item.RandRange.To,
|
||||
Packet: item.Packet,
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
@@ -174,6 +174,10 @@ func (c *InboundDetourConfig) Build() (*core.InboundHandlerConfig, error) {
|
||||
return nil, err
|
||||
}
|
||||
receiverSettings.StreamSettings = ss
|
||||
if strings.Contains(ss.SecurityType, "reality") && (receiverSettings.PortList == nil ||
|
||||
len(receiverSettings.PortList.Ports()) != 1 || receiverSettings.PortList.Ports()[0] != 443) {
|
||||
errors.LogWarning(context.Background(), `REALITY: Listening on non-443 ports may get your IP blocked by the GFW`)
|
||||
}
|
||||
}
|
||||
if c.SniffingConfig != nil {
|
||||
s, err := c.SniffingConfig.Build()
|
||||
|
||||
@@ -220,9 +220,7 @@ func setUpHTTPTunnel(ctx context.Context, dest net.Destination, target string, u
|
||||
for _, h := range header {
|
||||
req.Header.Set(h.Key, h.Value)
|
||||
}
|
||||
if req.Header.Get("User-Agent") == "" {
|
||||
req.Header.Set("User-Agent", utils.ChromeUA)
|
||||
}
|
||||
utils.TryDefaultHeadersWith(req.Header, "nav")
|
||||
|
||||
connectHTTP1 := func(rawConn net.Conn) (net.Conn, error) {
|
||||
req.Header.Set("Proxy-Connection", "Keep-Alive")
|
||||
|
||||
@@ -27,7 +27,9 @@ import (
|
||||
"github.com/xtls/xray-core/common/signal"
|
||||
"github.com/xtls/xray-core/common/task"
|
||||
"github.com/xtls/xray-core/core"
|
||||
"github.com/xtls/xray-core/features"
|
||||
"github.com/xtls/xray-core/features/dns"
|
||||
"github.com/xtls/xray-core/features/extension"
|
||||
feature_inbound "github.com/xtls/xray-core/features/inbound"
|
||||
"github.com/xtls/xray-core/features/outbound"
|
||||
"github.com/xtls/xray-core/features/policy"
|
||||
@@ -78,6 +80,7 @@ type Handler struct {
|
||||
validator vless.Validator
|
||||
decryption *encryption.ServerInstance
|
||||
outboundHandlerManager outbound.Manager
|
||||
observer features.Feature
|
||||
defaultDispatcher routing.Dispatcher
|
||||
ctx context.Context
|
||||
fallbacks map[string]map[string]map[string]*Fallback // or nil
|
||||
@@ -93,6 +96,7 @@ func New(ctx context.Context, config *Config, dc dns.Client, validator vless.Val
|
||||
stats: v.GetFeature(stats.ManagerType()).(stats.Manager),
|
||||
validator: validator,
|
||||
outboundHandlerManager: v.GetFeature(outbound.ManagerType()).(outbound.Manager),
|
||||
observer: v.GetFeature(extension.ObservatoryType()),
|
||||
defaultDispatcher: v.GetFeature(routing.DispatcherType()).(routing.Dispatcher),
|
||||
ctx: ctx,
|
||||
}
|
||||
@@ -623,7 +627,7 @@ func (h *Handler) Process(ctx context.Context, network net.Network, connection s
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return r.NewMux(ctx, dispatcher.WrapLink(ctx, h.policyManager, h.stats, &transport.Link{Reader: clientReader, Writer: clientWriter}))
|
||||
return r.NewMux(ctx, dispatcher.WrapLink(ctx, h.policyManager, h.stats, &transport.Link{Reader: clientReader, Writer: clientWriter}), h.observer)
|
||||
}
|
||||
|
||||
if err := dispatch.DispatchLink(ctx, request.Destination(), &transport.Link{
|
||||
@@ -645,7 +649,7 @@ func (r *Reverse) Tag() string {
|
||||
return r.tag
|
||||
}
|
||||
|
||||
func (r *Reverse) NewMux(ctx context.Context, link *transport.Link) error {
|
||||
func (r *Reverse) NewMux(ctx context.Context, link *transport.Link, observer features.Feature) error {
|
||||
muxClient, err := mux.NewClientWorker(*link, mux.ClientStrategy{})
|
||||
if err != nil {
|
||||
return errors.New("failed to create mux client worker").Base(err).AtWarning()
|
||||
@@ -655,6 +659,9 @@ func (r *Reverse) NewMux(ctx context.Context, link *transport.Link) error {
|
||||
return errors.New("failed to create portal worker").Base(err).AtWarning()
|
||||
}
|
||||
r.picker.AddWorker(worker)
|
||||
if burstObs, ok := observer.(extension.BurstObservatory); ok {
|
||||
go burstObs.Check([]string{r.Tag()})
|
||||
}
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
case <-muxClient.WaitClosed():
|
||||
|
||||
@@ -3,14 +3,11 @@ package finalmask
|
||||
import (
|
||||
"context"
|
||||
"net"
|
||||
"sync"
|
||||
|
||||
"github.com/xtls/xray-core/common/errors"
|
||||
)
|
||||
|
||||
const (
|
||||
UDPSize = 4096 + 123
|
||||
)
|
||||
|
||||
type Udpmask interface {
|
||||
UDP()
|
||||
|
||||
@@ -29,27 +26,165 @@ func NewUdpmaskManager(udpmasks []Udpmask) *UdpmaskManager {
|
||||
}
|
||||
|
||||
func (m *UdpmaskManager) WrapPacketConnClient(raw net.PacketConn) (net.PacketConn, error) {
|
||||
var err error
|
||||
var sizes []int
|
||||
var conns []net.PacketConn
|
||||
for i, mask := range m.udpmasks {
|
||||
raw, err = mask.WrapPacketConnClient(raw, i, len(m.udpmasks)-1)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
if _, ok := mask.(headerConn); ok {
|
||||
conn, err := mask.WrapPacketConnClient(nil, i, len(m.udpmasks)-1)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
sizes = append(sizes, conn.(headerSize).Size())
|
||||
conns = append(conns, conn)
|
||||
} else {
|
||||
if len(conns) > 0 {
|
||||
raw = &headerManagerConn{sizes: sizes, conns: conns, PacketConn: raw}
|
||||
sizes = nil
|
||||
conns = nil
|
||||
}
|
||||
var err error
|
||||
raw, err = mask.WrapPacketConnClient(raw, i, len(m.udpmasks)-1)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if len(conns) > 0 {
|
||||
raw = &headerManagerConn{sizes: sizes, conns: conns, PacketConn: raw}
|
||||
sizes = nil
|
||||
conns = nil
|
||||
}
|
||||
return raw, nil
|
||||
}
|
||||
|
||||
func (m *UdpmaskManager) WrapPacketConnServer(raw net.PacketConn) (net.PacketConn, error) {
|
||||
var err error
|
||||
var sizes []int
|
||||
var conns []net.PacketConn
|
||||
for i, mask := range m.udpmasks {
|
||||
raw, err = mask.WrapPacketConnServer(raw, i, len(m.udpmasks)-1)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
if _, ok := mask.(headerConn); ok {
|
||||
conn, err := mask.WrapPacketConnServer(nil, i, len(m.udpmasks)-1)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
sizes = append(sizes, conn.(headerSize).Size())
|
||||
conns = append(conns, conn)
|
||||
} else {
|
||||
if len(conns) > 0 {
|
||||
raw = &headerManagerConn{sizes: sizes, conns: conns, PacketConn: raw}
|
||||
sizes = nil
|
||||
conns = nil
|
||||
}
|
||||
var err error
|
||||
raw, err = mask.WrapPacketConnServer(raw, i, len(m.udpmasks)-1)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if len(conns) > 0 {
|
||||
raw = &headerManagerConn{sizes: sizes, conns: conns, PacketConn: raw}
|
||||
sizes = nil
|
||||
conns = nil
|
||||
}
|
||||
return raw, nil
|
||||
}
|
||||
|
||||
const (
|
||||
UDPSize = 4096
|
||||
)
|
||||
|
||||
type headerConn interface {
|
||||
HeaderConn()
|
||||
}
|
||||
|
||||
type headerSize interface {
|
||||
Size() int
|
||||
}
|
||||
|
||||
type headerManagerConn struct {
|
||||
sizes []int
|
||||
conns []net.PacketConn
|
||||
net.PacketConn
|
||||
m sync.Mutex
|
||||
writeBuf [UDPSize]byte
|
||||
}
|
||||
|
||||
func (c *headerManagerConn) ReadFrom(p []byte) (n int, addr net.Addr, err error) {
|
||||
buf := p
|
||||
if len(buf) < UDPSize {
|
||||
buf = make([]byte, UDPSize)
|
||||
}
|
||||
|
||||
n, addr, err = c.PacketConn.ReadFrom(buf)
|
||||
if n == 0 || err != nil {
|
||||
return 0, addr, err
|
||||
}
|
||||
newBuf := buf[:n]
|
||||
|
||||
sum := 0
|
||||
for _, size := range c.sizes {
|
||||
sum += size
|
||||
}
|
||||
|
||||
if n < sum {
|
||||
errors.LogDebug(context.Background(), addr, " mask read err short length")
|
||||
return 0, addr, nil
|
||||
}
|
||||
|
||||
for i := range c.conns {
|
||||
n, _, err = c.conns[i].ReadFrom(newBuf)
|
||||
if n == 0 || err != nil {
|
||||
errors.LogDebug(context.Background(), addr, " mask read err ", err)
|
||||
return 0, addr, nil
|
||||
}
|
||||
newBuf = newBuf[c.sizes[i] : n+c.sizes[i]]
|
||||
}
|
||||
|
||||
if len(p) < n {
|
||||
errors.LogDebug(context.Background(), addr, " mask read err short buffer")
|
||||
return 0, addr, nil
|
||||
}
|
||||
|
||||
copy(p, buf[sum:sum+n])
|
||||
|
||||
return n, addr, nil
|
||||
}
|
||||
|
||||
func (c *headerManagerConn) WriteTo(p []byte, addr net.Addr) (n int, err error) {
|
||||
c.m.Lock()
|
||||
defer c.m.Unlock()
|
||||
|
||||
sum := 0
|
||||
for _, size := range c.sizes {
|
||||
sum += size
|
||||
}
|
||||
|
||||
if sum+len(p) > UDPSize {
|
||||
errors.LogDebug(context.Background(), addr, " mask write err short write")
|
||||
return 0, nil
|
||||
}
|
||||
|
||||
n = copy(c.writeBuf[sum:], p)
|
||||
|
||||
for i := len(c.conns) - 1; i >= 0; i-- {
|
||||
n, err = c.conns[i].WriteTo(c.writeBuf[sum-c.sizes[i]:n+sum], nil)
|
||||
if n == 0 || err != nil {
|
||||
errors.LogDebug(context.Background(), addr, " mask write err ", err)
|
||||
return 0, nil
|
||||
}
|
||||
sum -= c.sizes[i]
|
||||
}
|
||||
|
||||
n, err = c.PacketConn.WriteTo(c.writeBuf[:n], addr)
|
||||
if n == 0 || err != nil {
|
||||
return n, err
|
||||
}
|
||||
|
||||
return len(p), nil
|
||||
}
|
||||
|
||||
type Tcpmask interface {
|
||||
TCP()
|
||||
|
||||
|
||||
@@ -33,9 +33,6 @@ func NewConnServer(c *Config, raw net.Conn, server bool) (net.Conn, error) {
|
||||
func (c *fragmentConn) TcpMaskConn() {}
|
||||
|
||||
func (c *fragmentConn) RawConn() net.Conn {
|
||||
if c.server {
|
||||
return c
|
||||
}
|
||||
return c.Conn
|
||||
}
|
||||
|
||||
|
||||
@@ -25,3 +25,6 @@ func (c *UDPConfig) WrapPacketConnClient(raw net.PacketConn, level int, levelCou
|
||||
func (c *UDPConfig) WrapPacketConnServer(raw net.PacketConn, level int, levelCount int) (net.PacketConn, error) {
|
||||
return NewConnServerUDP(c, raw)
|
||||
}
|
||||
|
||||
func (c *UDPConfig) HeaderConn() {
|
||||
}
|
||||
|
||||
@@ -26,7 +26,9 @@ type TCPItem struct {
|
||||
DelayMin int64 `protobuf:"varint,1,opt,name=delay_min,json=delayMin,proto3" json:"delay_min,omitempty"`
|
||||
DelayMax int64 `protobuf:"varint,2,opt,name=delay_max,json=delayMax,proto3" json:"delay_max,omitempty"`
|
||||
Rand int32 `protobuf:"varint,3,opt,name=rand,proto3" json:"rand,omitempty"`
|
||||
Packet []byte `protobuf:"bytes,4,opt,name=packet,proto3" json:"packet,omitempty"`
|
||||
RandMin int32 `protobuf:"varint,4,opt,name=rand_min,json=randMin,proto3" json:"rand_min,omitempty"`
|
||||
RandMax int32 `protobuf:"varint,5,opt,name=rand_max,json=randMax,proto3" json:"rand_max,omitempty"`
|
||||
Packet []byte `protobuf:"bytes,6,opt,name=packet,proto3" json:"packet,omitempty"`
|
||||
unknownFields protoimpl.UnknownFields
|
||||
sizeCache protoimpl.SizeCache
|
||||
}
|
||||
@@ -82,6 +84,20 @@ func (x *TCPItem) GetRand() int32 {
|
||||
return 0
|
||||
}
|
||||
|
||||
func (x *TCPItem) GetRandMin() int32 {
|
||||
if x != nil {
|
||||
return x.RandMin
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func (x *TCPItem) GetRandMax() int32 {
|
||||
if x != nil {
|
||||
return x.RandMax
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func (x *TCPItem) GetPacket() []byte {
|
||||
if x != nil {
|
||||
return x.Packet
|
||||
@@ -196,7 +212,9 @@ func (x *TCPConfig) GetErrors() []*TCPSequence {
|
||||
type UDPItem struct {
|
||||
state protoimpl.MessageState `protogen:"open.v1"`
|
||||
Rand int32 `protobuf:"varint,1,opt,name=rand,proto3" json:"rand,omitempty"`
|
||||
Packet []byte `protobuf:"bytes,2,opt,name=packet,proto3" json:"packet,omitempty"`
|
||||
RandMin int32 `protobuf:"varint,2,opt,name=rand_min,json=randMin,proto3" json:"rand_min,omitempty"`
|
||||
RandMax int32 `protobuf:"varint,3,opt,name=rand_max,json=randMax,proto3" json:"rand_max,omitempty"`
|
||||
Packet []byte `protobuf:"bytes,4,opt,name=packet,proto3" json:"packet,omitempty"`
|
||||
unknownFields protoimpl.UnknownFields
|
||||
sizeCache protoimpl.SizeCache
|
||||
}
|
||||
@@ -238,6 +256,20 @@ func (x *UDPItem) GetRand() int32 {
|
||||
return 0
|
||||
}
|
||||
|
||||
func (x *UDPItem) GetRandMin() int32 {
|
||||
if x != nil {
|
||||
return x.RandMin
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func (x *UDPItem) GetRandMax() int32 {
|
||||
if x != nil {
|
||||
return x.RandMax
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func (x *UDPItem) GetPacket() []byte {
|
||||
if x != nil {
|
||||
return x.Packet
|
||||
@@ -301,21 +333,25 @@ var File_transport_internet_finalmask_header_custom_config_proto protoreflect.Fi
|
||||
|
||||
const file_transport_internet_finalmask_header_custom_config_proto_rawDesc = "" +
|
||||
"\n" +
|
||||
"7transport/internet/finalmask/header/custom/config.proto\x12/xray.transport.internet.finalmask.header.custom\"o\n" +
|
||||
"7transport/internet/finalmask/header/custom/config.proto\x12/xray.transport.internet.finalmask.header.custom\"\xa5\x01\n" +
|
||||
"\aTCPItem\x12\x1b\n" +
|
||||
"\tdelay_min\x18\x01 \x01(\x03R\bdelayMin\x12\x1b\n" +
|
||||
"\tdelay_max\x18\x02 \x01(\x03R\bdelayMax\x12\x12\n" +
|
||||
"\x04rand\x18\x03 \x01(\x05R\x04rand\x12\x16\n" +
|
||||
"\x06packet\x18\x04 \x01(\fR\x06packet\"c\n" +
|
||||
"\x04rand\x18\x03 \x01(\x05R\x04rand\x12\x19\n" +
|
||||
"\brand_min\x18\x04 \x01(\x05R\arandMin\x12\x19\n" +
|
||||
"\brand_max\x18\x05 \x01(\x05R\arandMax\x12\x16\n" +
|
||||
"\x06packet\x18\x06 \x01(\fR\x06packet\"c\n" +
|
||||
"\vTCPSequence\x12T\n" +
|
||||
"\bsequence\x18\x01 \x03(\v28.xray.transport.internet.finalmask.header.custom.TCPItemR\bsequence\"\x91\x02\n" +
|
||||
"\tTCPConfig\x12V\n" +
|
||||
"\aclients\x18\x01 \x03(\v2<.xray.transport.internet.finalmask.header.custom.TCPSequenceR\aclients\x12V\n" +
|
||||
"\aservers\x18\x02 \x03(\v2<.xray.transport.internet.finalmask.header.custom.TCPSequenceR\aservers\x12T\n" +
|
||||
"\x06errors\x18\x03 \x03(\v2<.xray.transport.internet.finalmask.header.custom.TCPSequenceR\x06errors\"5\n" +
|
||||
"\x06errors\x18\x03 \x03(\v2<.xray.transport.internet.finalmask.header.custom.TCPSequenceR\x06errors\"k\n" +
|
||||
"\aUDPItem\x12\x12\n" +
|
||||
"\x04rand\x18\x01 \x01(\x05R\x04rand\x12\x16\n" +
|
||||
"\x06packet\x18\x02 \x01(\fR\x06packet\"\xaf\x01\n" +
|
||||
"\x04rand\x18\x01 \x01(\x05R\x04rand\x12\x19\n" +
|
||||
"\brand_min\x18\x02 \x01(\x05R\arandMin\x12\x19\n" +
|
||||
"\brand_max\x18\x03 \x01(\x05R\arandMax\x12\x16\n" +
|
||||
"\x06packet\x18\x04 \x01(\fR\x06packet\"\xaf\x01\n" +
|
||||
"\tUDPConfig\x12P\n" +
|
||||
"\x06client\x18\x01 \x03(\v28.xray.transport.internet.finalmask.header.custom.UDPItemR\x06client\x12P\n" +
|
||||
"\x06server\x18\x02 \x03(\v28.xray.transport.internet.finalmask.header.custom.UDPItemR\x06serverB\xaf\x01\n" +
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user