Compare commits
1 Commits
a54088edbc
...
try-fix-re
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
329a21848f |
3
.github/ISSUE_TEMPLATE/01-bug-report-en.yml
vendored
@@ -1,7 +1,6 @@
|
||||
name: "[English] Bug Report"
|
||||
description: "Create a report to help us debug bugs"
|
||||
title: "[BUG] "
|
||||
labels: ["bug"]
|
||||
body:
|
||||
- type: markdown
|
||||
attributes:
|
||||
@@ -71,7 +70,6 @@ body:
|
||||
- type: textarea
|
||||
id: configure
|
||||
attributes:
|
||||
render: yml
|
||||
label: "Configure File"
|
||||
description: |
|
||||
Please paste or upload the configuration file here.
|
||||
@@ -86,7 +84,6 @@ body:
|
||||
- type: textarea
|
||||
id: logs
|
||||
attributes:
|
||||
render: raw
|
||||
label: "Logs"
|
||||
description: |
|
||||
Please paste or upload the log file here.
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
name: "[English] Feature Request"
|
||||
description: "Create a report to help us improve"
|
||||
title: "[Feature Request] "
|
||||
labels: ["enhancement"]
|
||||
body:
|
||||
- type: markdown
|
||||
attributes:
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
name: "[简体中文] 错误报告"
|
||||
description: "创建错误报告以帮助我们修正应用"
|
||||
title: "[BUG] "
|
||||
labels: ["bug"]
|
||||
body:
|
||||
- type: markdown
|
||||
attributes:
|
||||
@@ -71,7 +70,6 @@ body:
|
||||
- type: textarea
|
||||
id: configure
|
||||
attributes:
|
||||
render: yml
|
||||
label: "配置文件"
|
||||
description: |
|
||||
请在此粘贴和上传配置文件。
|
||||
@@ -86,7 +84,6 @@ body:
|
||||
- type: textarea
|
||||
id: logs
|
||||
attributes:
|
||||
render: raw
|
||||
label: "日志"
|
||||
description: |
|
||||
请在此粘贴或上传日志。
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
name: "[简体中文] 功能请求"
|
||||
description: "您希望的能够在应用中增加功能"
|
||||
title: "[Feature Request] "
|
||||
labels: ["enhancement"]
|
||||
body:
|
||||
- type: markdown
|
||||
attributes:
|
||||
|
||||
33
.github/patch/disable_pidfd_on_android.patch
vendored
@@ -1,33 +0,0 @@
|
||||
From 7115c480196f4bdcbdae5e14ebaa4510540680e9 Mon Sep 17 00:00:00 2001
|
||||
From: Brad Fitzpatrick <bradfitz@tailscale.com>
|
||||
Date: Tue, 27 Jan 2026 09:52:22 -0800
|
||||
Subject: [PATCH] [tailscale] os: disable pidfd on Android
|
||||
|
||||
Updates tailscale/tailscale#13452
|
||||
Updates golang/go#70508
|
||||
Updates tailscale/go#99
|
||||
---
|
||||
src/os/pidfd_linux.go | 10 ++++++++++
|
||||
1 file changed, 10 insertions(+)
|
||||
|
||||
diff --git a/src/os/pidfd_linux.go b/src/os/pidfd_linux.go
|
||||
index 796d8c018c7f2a..5cdbf1175e0db5 100644
|
||||
--- a/src/os/pidfd_linux.go
|
||||
+++ b/src/os/pidfd_linux.go
|
||||
@@ -138,6 +138,16 @@ func (p *Process) pidfdSendSignal(s syscall.Signal) error {
|
||||
|
||||
// pidfdWorks returns whether we can use pidfd on this system.
|
||||
func pidfdWorks() bool {
|
||||
+ if runtime.GOOS == "android" {
|
||||
+ // Tailscale-specific workaround since https://github.com/golang/go/pull/69543/commits/aad6b3b32c81795f86bc4a9e81aad94899daf520
|
||||
+ // does not solve https://github.com/golang/go/issues/69065 for Android apps using Go libraries.
|
||||
+ //
|
||||
+ // See: https://github.com/tailscale/tailscale/issues/13452
|
||||
+ //
|
||||
+ // For now (2025-04-09), we'll just disable pidfd
|
||||
+ // on all Android releases.
|
||||
+ return false
|
||||
+ }
|
||||
return checkPidfdOnce() == nil
|
||||
}
|
||||
|
||||
111
.github/workflows/build-debug.yaml
vendored
@@ -1,111 +0,0 @@
|
||||
name: Build Debug
|
||||
on:
|
||||
pull_request:
|
||||
types: [opened, reopened, synchronize]
|
||||
workflow_dispatch:
|
||||
push:
|
||||
branches:
|
||||
- main
|
||||
|
||||
jobs:
|
||||
BuildDebug:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout Repository
|
||||
uses: actions/checkout@v6
|
||||
|
||||
- name: Checkout submodules
|
||||
run: git submodule update --init --recursive --force
|
||||
|
||||
- name: Setup Java
|
||||
uses: actions/setup-java@v5
|
||||
with:
|
||||
distribution: "temurin"
|
||||
java-version: 21
|
||||
|
||||
- name: Setup Gradle
|
||||
uses: gradle/actions/setup-gradle@v5
|
||||
|
||||
- name: Setup Go
|
||||
uses: actions/setup-go@4a3601121dd01d1626a1e23e37211e3254c1c06c
|
||||
with:
|
||||
go-download-base-url: 'https://github.com/MetaCubeX/go/releases/download/build'
|
||||
go-version: '1.26'
|
||||
|
||||
- name: Apply Patches
|
||||
run: |
|
||||
cd $(go env GOROOT)
|
||||
for p in $GITHUB_WORKSPACE/.github/patch/*.patch; do patch --verbose -p 1 < "$p"; done
|
||||
|
||||
- uses: actions/cache@v5
|
||||
with:
|
||||
path: |
|
||||
~/.cache/go-build
|
||||
~/go/pkg/mod
|
||||
key: ${{ runner.os }}-go-${{ hashFiles('**/go.sum') }}
|
||||
restore-keys: |
|
||||
${{ runner.os }}-go-
|
||||
|
||||
- name: Update CA
|
||||
run: |
|
||||
sudo apt-get update && sudo apt-get install ca-certificates
|
||||
sudo update-ca-certificates
|
||||
cp -f /etc/ssl/certs/ca-certificates.crt core/src/foss/golang/clash/component/ca/ca-certificates.crt
|
||||
|
||||
# - name: Signing properties
|
||||
# env:
|
||||
# SIGNING_STORE_PASSWORD: ${{ secrets.SIGNING_STORE_PASSWORD }}
|
||||
# SIGNING_KEY_ALIAS: ${{ secrets.SIGNING_KEY_ALIAS }}
|
||||
# SIGNING_KEY_PASSWORD: ${{ secrets.SIGNING_KEY_PASSWORD }}
|
||||
# run: |
|
||||
# touch signing.properties
|
||||
# echo keystore.password="$SIGNING_STORE_PASSWORD" > signing.properties
|
||||
# echo key.alias="$SIGNING_KEY_ALIAS" >> signing.properties
|
||||
# echo key.password="$SIGNING_KEY_PASSWORD" >> signing.properties
|
||||
|
||||
# echo "cat signing.properties"
|
||||
# cat signing.properties
|
||||
|
||||
- name: Build
|
||||
if: success()
|
||||
run: ./gradlew --no-daemon app:assembleAlphaRelease
|
||||
|
||||
- name: Upload Aritfact (universal)
|
||||
uses: actions/upload-artifact@v7
|
||||
if: ${{ success() }}
|
||||
with:
|
||||
name: CMFA Debug Unsigned APK (universal)
|
||||
path: |
|
||||
app/build/outputs/apk/alpha/release/*-universal-*.apk
|
||||
|
||||
- name: Upload Aritfact (arm64-v8a)
|
||||
uses: actions/upload-artifact@v7
|
||||
if: ${{ success() }}
|
||||
with:
|
||||
name: CMFA Debug Unsigned APK (arm64-v8a)
|
||||
path: |
|
||||
app/build/outputs/apk/alpha/release/*-arm64-v8a-*.apk
|
||||
|
||||
- name: Upload Aritfact (armeabi-v7a)
|
||||
uses: actions/upload-artifact@v7
|
||||
if: ${{ success() }}
|
||||
with:
|
||||
name: CMFA Debug Unsigned APK (armeabi-v7a)
|
||||
path: |
|
||||
app/build/outputs/apk/alpha/release/*-armeabi-v7a-*.apk
|
||||
|
||||
- name: Upload Aritfact (x86_64)
|
||||
uses: actions/upload-artifact@v7
|
||||
if: ${{ success() }}
|
||||
with:
|
||||
name: CMFA Debug Unsigned APK (x86_64)
|
||||
path: |
|
||||
app/build/outputs/apk/alpha/release/*-x86_64-*.apk
|
||||
|
||||
- name: Upload Aritfact (x86)
|
||||
uses: actions/upload-artifact@v7
|
||||
if: ${{ success() }}
|
||||
with:
|
||||
name: CMFA Debug Unsigned APK (x86)
|
||||
path: |
|
||||
app/build/outputs/apk/alpha/release/*-x86-*.apk
|
||||
95
.github/workflows/build-pre-release.yaml
vendored
@@ -1,95 +0,0 @@
|
||||
name: Build Pre-Release
|
||||
on:
|
||||
workflow_dispatch:
|
||||
push:
|
||||
branches:
|
||||
- main
|
||||
|
||||
jobs:
|
||||
BuildPreRelease:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout Repository
|
||||
uses: actions/checkout@v6
|
||||
|
||||
- name: Checkout submodules
|
||||
run: git submodule update --init --recursive --force
|
||||
|
||||
- name: Setup Java
|
||||
uses: actions/setup-java@v5
|
||||
with:
|
||||
distribution: "temurin"
|
||||
java-version: 21
|
||||
|
||||
- name: Setup Gradle
|
||||
uses: gradle/actions/setup-gradle@v5
|
||||
|
||||
- name: Setup Go
|
||||
uses: actions/setup-go@4a3601121dd01d1626a1e23e37211e3254c1c06c
|
||||
with:
|
||||
go-download-base-url: 'https://github.com/MetaCubeX/go/releases/download/build'
|
||||
go-version: '1.26'
|
||||
|
||||
- name: Apply Patches
|
||||
run: |
|
||||
cd $(go env GOROOT)
|
||||
for p in $GITHUB_WORKSPACE/.github/patch/*.patch; do patch --verbose -p 1 < "$p"; done
|
||||
|
||||
- uses: actions/cache@v5
|
||||
with:
|
||||
path: |
|
||||
~/.cache/go-build
|
||||
~/go/pkg/mod
|
||||
key: ${{ runner.os }}-go-${{ hashFiles('**/go.sum') }}
|
||||
restore-keys: |
|
||||
${{ runner.os }}-go-
|
||||
|
||||
- name: Update CA
|
||||
run: |
|
||||
sudo apt-get update && sudo apt-get install ca-certificates
|
||||
sudo update-ca-certificates
|
||||
cp -f /etc/ssl/certs/ca-certificates.crt core/src/foss/golang/clash/component/ca/ca-certificates.crt
|
||||
|
||||
- name: Signing properties
|
||||
env:
|
||||
SIGNING_STORE_PASSWORD: ${{ secrets.SIGNING_STORE_PASSWORD }}
|
||||
SIGNING_KEY_ALIAS: ${{ secrets.SIGNING_KEY_ALIAS }}
|
||||
SIGNING_KEY_PASSWORD: ${{ secrets.SIGNING_KEY_PASSWORD }}
|
||||
run: |
|
||||
touch signing.properties
|
||||
echo keystore.password="$SIGNING_STORE_PASSWORD" > signing.properties
|
||||
echo key.alias="$SIGNING_KEY_ALIAS" >> signing.properties
|
||||
echo key.password="$SIGNING_KEY_PASSWORD" >> signing.properties
|
||||
|
||||
echo "cat signing.properties"
|
||||
cat signing.properties
|
||||
|
||||
- name: Pre-release Build
|
||||
if: success()
|
||||
run: ./gradlew --no-daemon app:assembleAlphaRelease
|
||||
|
||||
# Delete old Prerelease-alpha
|
||||
- uses: dev-drprasad/delete-tag-and-release@v1.1
|
||||
with:
|
||||
tag_name: Prerelease-alpha
|
||||
github_token: ${{ secrets.GITHUB_TOKEN }}
|
||||
delete_release: true
|
||||
|
||||
- name: Tag Repo
|
||||
uses: richardsimko/update-tag@v1
|
||||
with:
|
||||
tag_name: Prerelease-alpha
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
- name: Upload Alpha
|
||||
uses: softprops/action-gh-release@v2
|
||||
if: ${{ success() }}
|
||||
with:
|
||||
tag_name: Prerelease-alpha
|
||||
files: app/build/outputs/apk/alpha/release/*
|
||||
prerelease: true
|
||||
generate_release_notes: true
|
||||
|
||||
- name: Release Changelog Builder
|
||||
uses: mikepenz/release-changelog-builder-action@v4
|
||||
133
.github/workflows/build-release.yaml
vendored
@@ -1,133 +0,0 @@
|
||||
name: Build Release
|
||||
|
||||
on:
|
||||
workflow_dispatch:
|
||||
inputs:
|
||||
release-tag:
|
||||
description: 'Release Tag (v2.x.x)'
|
||||
required: true
|
||||
|
||||
jobs:
|
||||
BuildRelease:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout Repository
|
||||
uses: actions/checkout@v6
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
- name: Checkout submodules
|
||||
run: git submodule update --init --recursive --force
|
||||
|
||||
- name: Setup Java
|
||||
uses: actions/setup-java@v5
|
||||
with:
|
||||
distribution: "temurin"
|
||||
java-version: 21
|
||||
|
||||
- name: Setup Gradle
|
||||
uses: gradle/actions/setup-gradle@v5
|
||||
|
||||
- name: Setup Go
|
||||
uses: actions/setup-go@4a3601121dd01d1626a1e23e37211e3254c1c06c
|
||||
with:
|
||||
go-download-base-url: 'https://github.com/MetaCubeX/go/releases/download/build'
|
||||
go-version: '1.26'
|
||||
|
||||
- name: Apply Patches
|
||||
run: |
|
||||
cd $(go env GOROOT)
|
||||
for p in $GITHUB_WORKSPACE/.github/patch/*.patch; do patch --verbose -p 1 < "$p"; done
|
||||
|
||||
- uses: actions/cache@v5
|
||||
with:
|
||||
path: |
|
||||
~/.cache/go-build
|
||||
~/go/pkg/mod
|
||||
key: ${{ runner.os }}-go-${{ hashFiles('**/go.sum') }}
|
||||
restore-keys: |
|
||||
${{ runner.os }}-go-
|
||||
|
||||
- name: Convert and set version env
|
||||
id: process-version
|
||||
run: |
|
||||
VERSION_TAG=${{ inputs.release-tag }}
|
||||
VERSION_TAG=${VERSION_TAG#v} # remove the 'v' prefix
|
||||
IFS='.' read -ra VERSION_PARTS <<< "$VERSION_TAG" # split into array
|
||||
VERSION_CODE=$(printf "%1d%02d%03d" "${VERSION_PARTS[0]}" "${VERSION_PARTS[1]}" "${VERSION_PARTS[2]}")
|
||||
|
||||
echo "versonName=$VERSION_TAG" >> $GITHUB_OUTPUT # "1.2.3"
|
||||
echo "versonCode=$VERSION_CODE" >> $GITHUB_OUTPUT # "102003"
|
||||
|
||||
# Re-write version in build.gradle.kts
|
||||
- name: Re-write version
|
||||
uses: Devofure/advance-android-version-actions@v1.5
|
||||
with:
|
||||
gradlePath: build.gradle.kts
|
||||
versionCode: ${{ steps.process-version.outputs.versonCode }}
|
||||
versionName: ${{ steps.process-version.outputs.versonName }}
|
||||
|
||||
# If any change found, commit it and push
|
||||
- name: Commit and push if changes
|
||||
run: |
|
||||
changes=$(git diff --name-only origin/main | wc -l)
|
||||
if [ $changes -gt 0 ]
|
||||
then
|
||||
newVersionName=${{ steps.process-version.outputs.versonName }}
|
||||
newVersionCode=${{ steps.process-version.outputs.versonCode }}
|
||||
git config --global user.name 'GitHub Action'
|
||||
git config --global user.email 'action@github.com'
|
||||
git add build.gradle.kts
|
||||
git commit -am "Bump version to $newVersionName ($newVersionCode)"
|
||||
git tag "v$newVersionName"
|
||||
git push --follow-tags
|
||||
fi
|
||||
|
||||
- name: Update CA
|
||||
run: |
|
||||
sudo apt-get update && sudo apt-get install ca-certificates
|
||||
sudo update-ca-certificates
|
||||
cp -f /etc/ssl/certs/ca-certificates.crt core/src/foss/golang/clash/component/ca/ca-certificates.crt
|
||||
|
||||
- name: Signing properties
|
||||
env:
|
||||
SIGNING_STORE_PASSWORD: ${{ secrets.SIGNING_STORE_PASSWORD }}
|
||||
SIGNING_KEY_ALIAS: ${{ secrets.SIGNING_KEY_ALIAS }}
|
||||
SIGNING_KEY_PASSWORD: ${{ secrets.SIGNING_KEY_PASSWORD }}
|
||||
run: |
|
||||
touch signing.properties
|
||||
echo keystore.password="$SIGNING_STORE_PASSWORD" > signing.properties
|
||||
echo key.alias="$SIGNING_KEY_ALIAS" >> signing.properties
|
||||
echo key.password="$SIGNING_KEY_PASSWORD" >> signing.properties
|
||||
|
||||
echo "cat signing.properties"
|
||||
cat signing.properties
|
||||
|
||||
- name: Release Build
|
||||
if: success()
|
||||
run: ./gradlew --no-daemon app:assembleMetaRelease
|
||||
|
||||
- name: Tag Repo
|
||||
uses: richardsimko/update-tag@v1
|
||||
with:
|
||||
tag_name: ${{ inputs.release-tag }}
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
- name: Upload Release
|
||||
uses: softprops/action-gh-release@v1
|
||||
if: ${{ success() }}
|
||||
with:
|
||||
tag_name: ${{ inputs.release-tag }}
|
||||
files: app/build/outputs/apk/meta/release/*
|
||||
generate_release_notes: true
|
||||
|
||||
- name: Release Changelog Builder
|
||||
uses: mikepenz/release-changelog-builder-action@v4.1.1
|
||||
with:
|
||||
configurationJson: |
|
||||
{
|
||||
"ignore_labels": [
|
||||
"Update"
|
||||
],
|
||||
}
|
||||
48
.github/workflows/build-unsigned.yaml
vendored
Normal file
@@ -0,0 +1,48 @@
|
||||
name: Build Unsigned
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- main
|
||||
paths-ignore:
|
||||
- '.github/**'
|
||||
- '.idea/**'
|
||||
- '.gitattributes'
|
||||
- '.gitignore'
|
||||
- '.gitmodules'
|
||||
- '**.md'
|
||||
- 'LICENSE'
|
||||
- 'NOTICE'
|
||||
pull_request:
|
||||
paths-ignore:
|
||||
- '.github/**'
|
||||
- '.idea/**'
|
||||
- '.gitattributes'
|
||||
- '.gitignore'
|
||||
- '.gitmodules'
|
||||
- '**.md'
|
||||
- 'LICENSE'
|
||||
- 'NOTICE'
|
||||
jobs:
|
||||
BuildUnsigned:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout Repository
|
||||
uses: actions/checkout@v2
|
||||
with:
|
||||
submodules: recursive
|
||||
- name: Setup Java
|
||||
uses: actions/setup-java@v2
|
||||
with:
|
||||
distribution: 'adopt'
|
||||
java-version: 11
|
||||
- name: Gradle cache
|
||||
uses: actions/cache@v2
|
||||
with:
|
||||
path: ~/.gradle/caches
|
||||
key: ${{ runner.os }}-gradle-${{ hashFiles('**/*.gradle*', '**/gradle/wrapper/gradle-wrapper.properties', '**/buildSrc/src/main/kotlin/**.kt') }}
|
||||
- name: Setup Go
|
||||
uses: actions/setup-go@v2
|
||||
with:
|
||||
go-version: 1.17
|
||||
- name: Build
|
||||
run: ./gradlew --no-daemon app:assembleFossRelease
|
||||
88
.github/workflows/update-dependencies.yaml
vendored
@@ -1,88 +0,0 @@
|
||||
name: Update Clash-Core and Go Modules
|
||||
on:
|
||||
repository_dispatch:
|
||||
types:
|
||||
- core-updated
|
||||
workflow_dispatch:
|
||||
|
||||
jobs:
|
||||
update-dependencies:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout Repository
|
||||
uses: actions/checkout@v6
|
||||
|
||||
- name: Checkout and Update submodules
|
||||
run: git submodule update --init --recursive --remote --force
|
||||
|
||||
- name: Setup Java
|
||||
uses: actions/setup-java@v5
|
||||
with:
|
||||
distribution: "temurin"
|
||||
java-version: 21
|
||||
|
||||
- name: Setup Go
|
||||
uses: actions/setup-go@4a3601121dd01d1626a1e23e37211e3254c1c06c
|
||||
with:
|
||||
go-download-base-url: 'https://github.com/MetaCubeX/go/releases/download/build'
|
||||
go-version: '1.26'
|
||||
|
||||
- name: Apply Patches
|
||||
run: |
|
||||
cd $(go env GOROOT)
|
||||
for p in $GITHUB_WORKSPACE/.github/patch/*.patch; do patch --verbose -p 1 < "$p"; done
|
||||
|
||||
- uses: actions/cache@v5
|
||||
with:
|
||||
path: |
|
||||
~/.cache/go-build
|
||||
~/go/pkg/mod
|
||||
key: ${{ runner.os }}-go-${{ hashFiles('**/go.sum') }}
|
||||
restore-keys: |
|
||||
${{ runner.os }}-go-
|
||||
|
||||
- name: Install update-go-mod-replace
|
||||
run: |
|
||||
go install github.com/metacubex/update-go-mod-replace@latest
|
||||
|
||||
- name: Update Foss Gomod
|
||||
run: |
|
||||
cd ${{ github.workspace }}/core/src/foss/golang/
|
||||
update-go-mod-replace ${{ github.workspace }}/core/src/foss/golang/clash/go.mod $(pwd)/go.mod
|
||||
go mod tidy
|
||||
|
||||
- name: Update Main Gomod
|
||||
run: |
|
||||
cd ${{ github.workspace }}/core/src/main/golang/
|
||||
update-go-mod-replace ${{ github.workspace }}/core/src/foss/golang/clash/go.mod $(pwd)/go.mod
|
||||
go mod tidy
|
||||
|
||||
- uses: actions/create-github-app-token@v3
|
||||
id: generate-token
|
||||
with:
|
||||
client-id: ${{ secrets.MAINTAINER_APPID }}
|
||||
private-key: ${{ secrets.MAINTAINER_APP_PRIVATE_KEY }}
|
||||
owner: ${{ github.repository_owner }}
|
||||
|
||||
- name: Create Pull Request
|
||||
id: cpr
|
||||
uses: peter-evans/create-pull-request@v8
|
||||
with:
|
||||
token: ${{ steps.generate-token.outputs.token }}
|
||||
commit-message: Update Dependencies
|
||||
branch: update-dependencies
|
||||
delete-branch: true
|
||||
title: 'Update Dependencies'
|
||||
draft: false
|
||||
body: |
|
||||
- Update Clash-Meta Core
|
||||
- Update Go Module Dependecies
|
||||
labels: |
|
||||
Update
|
||||
|
||||
- name: PR result
|
||||
if: ${{ steps.cpr.outputs.pull-request-number }}
|
||||
run: |
|
||||
echo "Pull Request Number - ${{ steps.cpr.outputs.pull-request-number }}"
|
||||
echo "Pull Request URL - ${{ steps.cpr.outputs.pull-request-url }}"
|
||||
|
||||
3
.gitignore
vendored
@@ -27,9 +27,6 @@ gradle-app.setting
|
||||
/core/src/premium/golang/.idea/*
|
||||
!/core/src/premium/golang/.idea/codeStyles
|
||||
|
||||
# Ignore builtin geofiles
|
||||
app/src/main/assets
|
||||
|
||||
# KeyStore
|
||||
signing.properties
|
||||
*.keystore
|
||||
|
||||
6
.gitmodules
vendored
@@ -1,4 +1,6 @@
|
||||
[submodule "clash-foss"]
|
||||
path = core/src/foss/golang/clash
|
||||
url = https://github.com/MetaCubeX/mihomo
|
||||
branch = Alpha
|
||||
url = https://github.com/Kr328/clash.git
|
||||
[submodule "clash-premium"]
|
||||
path = core/src/premium/golang/clash
|
||||
url = https://github.com/Kr328/clash.git
|
||||
|
||||
9
.idea/codeStyles/Project.xml
generated
@@ -20,6 +20,15 @@
|
||||
<package name="io.ktor" alias="false" withSubpackages="true" />
|
||||
</value>
|
||||
</option>
|
||||
<option name="PACKAGES_IMPORT_LAYOUT">
|
||||
<value>
|
||||
<package name="" alias="false" withSubpackages="true" />
|
||||
<package name="java" alias="false" withSubpackages="true" />
|
||||
<package name="javax" alias="false" withSubpackages="true" />
|
||||
<package name="kotlin" alias="false" withSubpackages="true" />
|
||||
<package name="" alias="true" withSubpackages="true" />
|
||||
</value>
|
||||
</option>
|
||||
<option name="CODE_STYLE_DEFAULTS" value="KOTLIN_OFFICIAL" />
|
||||
</JetCodeStyleSettings>
|
||||
<codeStyleSettings language="XML">
|
||||
|
||||
65
README.md
@@ -1,14 +1,12 @@
|
||||
## Clash Meta for Android
|
||||
## Clash for Android
|
||||
|
||||
A Graphical user interface of [Clash.Meta](https://github.com/MetaCubeX/Clash.Meta) for Android
|
||||
A Graphical user interface of [clash](https://github.com/Dreamacro/clash) for Android
|
||||
|
||||
<a href="https://play.google.com/store/apps/details?id=com.github.kr328.clash"><img width="200px" alt="Get it on Google Play" src="https://play.google.com/intl/en_us/badges/static/images/badges/en_badge_web_generic.png"/></a> or [Releases](https://github.com/Kr328/ClashForAndroid/releases)
|
||||
|
||||
### Feature
|
||||
|
||||
Feature of [Clash.Meta](https://github.com/MetaCubeX/Clash.Meta)
|
||||
|
||||
[<img src="https://fdroid.gitlab.io/artwork/badge/get-it-on.png"
|
||||
alt="Get it on F-Droid"
|
||||
height="80">](https://f-droid.org/packages/com.github.metacubex.clash.meta/)
|
||||
Fully feature of [clash](https://github.com/Dreamacro/clash) ~~(Exclude `external-controller`~~
|
||||
|
||||
### Requirement
|
||||
|
||||
@@ -16,6 +14,14 @@ Feature of [Clash.Meta](https://github.com/MetaCubeX/Clash.Meta)
|
||||
- Android 7.0+ (recommend)
|
||||
- `armeabi-v7a` , `arm64-v8a`, `x86` or `x86_64` Architecture
|
||||
|
||||
### License
|
||||
|
||||
See also [LICENSE](./LICENSE) and [NOTICE](./NOTICE)
|
||||
|
||||
### Privacy Policy
|
||||
|
||||
See also [PRIVACY_POLICY.md](./PRIVACY_POLICY.md)
|
||||
|
||||
### Build
|
||||
|
||||
1. Update submodules
|
||||
@@ -32,15 +38,7 @@ Feature of [Clash.Meta](https://github.com/MetaCubeX/Clash.Meta)
|
||||
sdk.dir=/path/to/android-sdk
|
||||
```
|
||||
|
||||
4. (Optional) Custom app package name. Add the following configuration to `local.properties`.
|
||||
|
||||
```properties
|
||||
# config your ownn applicationId, or it will be 'com.github.metacubex.clash'
|
||||
custom.application.id=com.my.compile.clash
|
||||
# remove application id suffix, or the applicaion id will be 'com.github.metacubex.clash.alpha'
|
||||
remove.suffix=true
|
||||
|
||||
5. Create `signing.properties` in project root with
|
||||
4. Create `signing.properties` in project root with
|
||||
|
||||
```properties
|
||||
keystore.path=/path/to/keystore/file
|
||||
@@ -49,39 +47,10 @@ Feature of [Clash.Meta](https://github.com/MetaCubeX/Clash.Meta)
|
||||
key.password=<key password>
|
||||
```
|
||||
|
||||
6. Build
|
||||
5. Build
|
||||
|
||||
```bash
|
||||
./gradlew app:assembleAlphaRelease
|
||||
./gradlew app:assembleFossRelease
|
||||
```
|
||||
|
||||
### Automation
|
||||
|
||||
APP package name is `com.github.metacubex.clash.meta`
|
||||
|
||||
- Toggle Clash.Meta service status
|
||||
- Send intent to activity `com.github.kr328.clash.ExternalControlActivity` with action `com.github.metacubex.clash.meta.action.TOGGLE_CLASH`
|
||||
- Start Clash.Meta service
|
||||
- Send intent to activity `com.github.kr328.clash.ExternalControlActivity` with action `com.github.metacubex.clash.meta.action.START_CLASH`
|
||||
- Stop Clash.Meta service
|
||||
- Send intent to activity `com.github.kr328.clash.ExternalControlActivity` with action `com.github.metacubex.clash.meta.action.STOP_CLASH`
|
||||
- Import a profile
|
||||
- URL Scheme `clash://install-config?url=<encoded URI>` or `clashmeta://install-config?url=<encoded URI>`
|
||||
|
||||
### Contribution and Project Maintenance
|
||||
|
||||
#### Meta Kernel
|
||||
|
||||
- CMFA uses the kernel from `android-real` branch under `MetaCubeX/Clash.Meta`, which is a merge of the main `Alpha` branch and `android-open`.
|
||||
- If you want to contribute to the kernel, make PRs to `Alpha` branch of the Meta kernel repository.
|
||||
- If you want to contribute Android-specific patches to the kernel, make PRs to `android-open` branch of the Meta kernel repository.
|
||||
|
||||
#### Maintenance
|
||||
|
||||
- When `MetaCubeX/Clash.Meta` kernel is updated to a new version, the `Update Dependencies` actions in this repo will be triggered automatically.
|
||||
- It will pull the new version of the meta kernel, update all the golang dependencies, and create a PR without manual intervention.
|
||||
- If there is any compile error in PR, you need to fix it before merging. Alternatively, you may merge the PR directly.
|
||||
- Manually triggering `Build Pre-Release` actions will compile and publish a `PreRelease` version.
|
||||
- Manually triggering `Build Release` actions will compile, tag and publish a `Release` version.
|
||||
- You must fill the blank `Release Tag` with the tag you want to release in the format of `v1.2.3`.
|
||||
- `versionName` and `versionCode` in `build.gradle.kts` will be automatically bumped to the tag you filled above.
|
||||
6. Pick `app-foss-<arch>-release.apk` in `app/build/outputs/apk/foss/release/`
|
||||
|
||||
@@ -1,7 +1,3 @@
|
||||
import java.net.URL
|
||||
import java.nio.file.Files
|
||||
import java.nio.file.StandardCopyOption
|
||||
|
||||
plugins {
|
||||
kotlin("android")
|
||||
kotlin("kapt")
|
||||
@@ -16,56 +12,21 @@ dependencies {
|
||||
implementation(project(":design"))
|
||||
implementation(project(":common"))
|
||||
|
||||
implementation(libs.kotlin.coroutine)
|
||||
implementation(libs.androidx.core)
|
||||
implementation(libs.androidx.activity)
|
||||
implementation(libs.androidx.fragment)
|
||||
implementation(libs.androidx.appcompat)
|
||||
implementation(libs.androidx.coordinator)
|
||||
implementation(libs.androidx.recyclerview)
|
||||
implementation(libs.google.material)
|
||||
implementation(libs.quickie.bundled)
|
||||
implementation(libs.androidx.activity.ktx)
|
||||
implementation(deps.kotlin.coroutine)
|
||||
implementation(deps.androidx.core)
|
||||
implementation(deps.androidx.activity)
|
||||
implementation(deps.androidx.fragment)
|
||||
implementation(deps.androidx.appcompat)
|
||||
implementation(deps.androidx.coordinator)
|
||||
implementation(deps.androidx.recyclerview)
|
||||
implementation(deps.google.material)
|
||||
|
||||
val premiumImplementation by configurations
|
||||
|
||||
premiumImplementation(deps.appcenter.analytics)
|
||||
premiumImplementation(deps.appcenter.crashes)
|
||||
}
|
||||
|
||||
tasks.getByName("clean", type = Delete::class) {
|
||||
delete(file("release"))
|
||||
}
|
||||
|
||||
val geoFilesDownloadDir = "src/main/assets"
|
||||
|
||||
task("downloadGeoFiles") {
|
||||
|
||||
val geoFilesUrls = mapOf(
|
||||
"https://github.com/MetaCubeX/meta-rules-dat/releases/download/latest/geoip.metadb" to "geoip.metadb",
|
||||
"https://github.com/MetaCubeX/meta-rules-dat/releases/download/latest/geosite.dat" to "geosite.dat",
|
||||
// "https://github.com/MetaCubeX/meta-rules-dat/releases/download/latest/country.mmdb" to "country.mmdb",
|
||||
"https://github.com/MetaCubeX/meta-rules-dat/releases/download/latest/GeoLite2-ASN.mmdb" to "ASN.mmdb",
|
||||
)
|
||||
|
||||
doLast {
|
||||
geoFilesUrls.forEach { (downloadUrl, outputFileName) ->
|
||||
val url = URL(downloadUrl)
|
||||
val outputPath = file("$geoFilesDownloadDir/$outputFileName")
|
||||
outputPath.parentFile.mkdirs()
|
||||
url.openStream().use { input ->
|
||||
Files.copy(input, outputPath.toPath(), StandardCopyOption.REPLACE_EXISTING)
|
||||
println("$outputFileName downloaded to $outputPath")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
afterEvaluate {
|
||||
val downloadGeoFilesTask = tasks["downloadGeoFiles"]
|
||||
|
||||
tasks.forEach {
|
||||
if (it.name.startsWith("assemble")) {
|
||||
it.dependsOn(downloadGeoFilesTask)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
tasks.getByName("clean", type = Delete::class) {
|
||||
delete(file(geoFilesDownloadDir))
|
||||
}
|
||||
14
app/src/foss/java/com/github/kr328/clash/Tracker.kt
Normal file
@@ -0,0 +1,14 @@
|
||||
package com.github.kr328.clash
|
||||
|
||||
import android.app.Application
|
||||
|
||||
@Suppress("UNUSED_PARAMETER")
|
||||
object Tracker {
|
||||
fun initialize(application: Application) {
|
||||
// do nothing
|
||||
}
|
||||
|
||||
fun uploadLogcat(logcat: String) {
|
||||
// do nothing
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,7 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools">
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
package="com.github.kr328.clash">
|
||||
|
||||
<uses-feature
|
||||
android:name="android.software.leanback"
|
||||
@@ -11,11 +12,10 @@
|
||||
|
||||
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
|
||||
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
|
||||
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
|
||||
<uses-permission
|
||||
android:name="android.permission.QUERY_ALL_PACKAGES"
|
||||
tools:ignore="QueryAllPackagesPermission" />
|
||||
<uses-permission android:name="android.permission.FOREGROUND_SERVICE_SPECIAL_USE" />
|
||||
<uses-permission android:name="android.permission.POST_NOTIFICATIONS"/>
|
||||
|
||||
<application
|
||||
android:name=".MainApplication"
|
||||
@@ -42,33 +42,22 @@
|
||||
android:configChanges="uiMode"
|
||||
android:exported="true"
|
||||
android:label="@string/launch_name"
|
||||
android:launchMode="singleTask">
|
||||
android:launchMode="singleTop">
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.APPLICATION_PREFERENCES" />
|
||||
<action android:name="android.intent.action.MAIN" />
|
||||
|
||||
<category android:name="android.intent.category.LAUNCHER" />
|
||||
<category android:name="android.intent.category.LEANBACK_LAUNCHER" />
|
||||
<category android:name="android.intent.category.DEFAULT" />
|
||||
</intent-filter>
|
||||
<intent-filter>
|
||||
<action android:name="android.service.quicksettings.action.QS_TILE_PREFERENCES" />
|
||||
</intent-filter>
|
||||
</activity>
|
||||
<activity-alias
|
||||
android:name=".MainActivityAlias"
|
||||
android:exported="true"
|
||||
android:targetActivity=".MainActivity">
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.MAIN" />
|
||||
<category android:name="android.intent.category.LAUNCHER" />
|
||||
<category android:name="android.intent.category.LEANBACK_LAUNCHER" />
|
||||
<category android:name="android.intent.category.DEFAULT" />
|
||||
</intent-filter>
|
||||
</activity-alias>
|
||||
|
||||
<activity
|
||||
android:name=".ExternalControlActivity"
|
||||
android:excludeFromRecents="true"
|
||||
android:name=".ExternalImportActivity"
|
||||
android:exported="true"
|
||||
android:label="@string/external_control_activity"
|
||||
android:noHistory="true"
|
||||
android:label="@string/import_from_file"
|
||||
android:theme="@android:style/Theme.Translucent.NoTitleBar.Fullscreen">
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.VIEW" />
|
||||
@@ -76,21 +65,9 @@
|
||||
<category android:name="android.intent.category.DEFAULT" />
|
||||
<category android:name="android.intent.category.BROWSABLE" />
|
||||
|
||||
<data android:scheme="clash"/>
|
||||
<data android:scheme="clashmeta"/>
|
||||
<data android:host="install-config"/>
|
||||
</intent-filter>
|
||||
<intent-filter>
|
||||
<action android:name="com.github.metacubex.clash.meta.action.START_CLASH" />
|
||||
<category android:name="android.intent.category.DEFAULT" />
|
||||
</intent-filter>
|
||||
<intent-filter>
|
||||
<action android:name="com.github.metacubex.clash.meta.action.STOP_CLASH" />
|
||||
<category android:name="android.intent.category.DEFAULT" />
|
||||
</intent-filter>
|
||||
<intent-filter>
|
||||
<action android:name="com.github.metacubex.clash.meta.action.TOGGLE_CLASH" />
|
||||
<category android:name="android.intent.category.DEFAULT" />
|
||||
<data
|
||||
android:host="install-config"
|
||||
android:scheme="clash" />
|
||||
</intent-filter>
|
||||
</activity>
|
||||
<activity
|
||||
@@ -159,11 +136,6 @@
|
||||
android:configChanges="uiMode"
|
||||
android:exported="false"
|
||||
android:label="@string/override" />
|
||||
<activity
|
||||
android:name=".MetaFeatureSettingsActivity"
|
||||
android:configChanges="uiMode"
|
||||
android:exported="false"
|
||||
android:label="@string/meta_features" />
|
||||
<activity
|
||||
android:name=".AccessControlActivity"
|
||||
android:configChanges="uiMode"
|
||||
@@ -183,11 +155,7 @@
|
||||
<service
|
||||
android:name=".LogcatService"
|
||||
android:exported="false"
|
||||
android:label="@string/clash_logcat"
|
||||
android:foregroundServiceType="specialUse">
|
||||
<property android:name="android.app.PROPERTY_SPECIAL_USE_FGS_SUBTYPE"
|
||||
android:value="explanation_for_special_use"/>
|
||||
</service>
|
||||
android:label="@string/clash_logcat" />
|
||||
<service
|
||||
android:name=".TileService"
|
||||
android:exported="true"
|
||||
@@ -208,14 +176,5 @@
|
||||
<action android:name="android.intent.action.MY_PACKAGE_REPLACED" />
|
||||
</intent-filter>
|
||||
</receiver>
|
||||
|
||||
<receiver android:name=".DialerReceiver"
|
||||
android:exported="true">
|
||||
<intent-filter>
|
||||
<action android:name="android.provider.Telephony.SECRET_CODE" />
|
||||
<!-- 252746382 is the name of Clash Meta in T9 -->
|
||||
<data android:scheme="android_secret_code" android:host="252746382" />
|
||||
</intent-filter>
|
||||
</receiver>
|
||||
</application>
|
||||
</manifest>
|
||||
|
||||
|
Before Width: | Height: | Size: 14 KiB |
@@ -11,10 +11,7 @@ import com.github.kr328.clash.design.AccessControlDesign
|
||||
import com.github.kr328.clash.design.model.AppInfo
|
||||
import com.github.kr328.clash.design.util.toAppInfo
|
||||
import com.github.kr328.clash.service.store.ServiceStore
|
||||
import com.github.kr328.clash.util.startClashService
|
||||
import com.github.kr328.clash.util.stopClashService
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.delay
|
||||
import kotlinx.coroutines.isActive
|
||||
import kotlinx.coroutines.selects.select
|
||||
import kotlinx.coroutines.withContext
|
||||
@@ -29,15 +26,7 @@ class AccessControlActivity : BaseActivity<AccessControlDesign>() {
|
||||
|
||||
defer {
|
||||
withContext(Dispatchers.IO) {
|
||||
val changed = selected != service.accessControlPackages
|
||||
service.accessControlPackages = selected
|
||||
if (clashRunning && changed) {
|
||||
stopClashService()
|
||||
while (clashRunning) {
|
||||
delay(200)
|
||||
}
|
||||
startClashService()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -57,7 +46,6 @@ class AccessControlActivity : BaseActivity<AccessControlDesign>() {
|
||||
AccessControlDesign.Request.ReloadApps -> {
|
||||
design.patchApps(loadApps(selected))
|
||||
}
|
||||
|
||||
AccessControlDesign.Request.SelectAll -> {
|
||||
val all = withContext(Dispatchers.Default) {
|
||||
design.apps.map(AppInfo::packageName)
|
||||
@@ -68,13 +56,11 @@ class AccessControlActivity : BaseActivity<AccessControlDesign>() {
|
||||
|
||||
design.rebindAll()
|
||||
}
|
||||
|
||||
AccessControlDesign.Request.SelectNone -> {
|
||||
selected.clear()
|
||||
|
||||
design.rebindAll()
|
||||
}
|
||||
|
||||
AccessControlDesign.Request.SelectInvert -> {
|
||||
val all = withContext(Dispatchers.Default) {
|
||||
design.apps.map(AppInfo::packageName).toSet() - selected
|
||||
@@ -85,14 +71,16 @@ class AccessControlActivity : BaseActivity<AccessControlDesign>() {
|
||||
|
||||
design.rebindAll()
|
||||
}
|
||||
|
||||
AccessControlDesign.Request.Import -> {
|
||||
val clipboard = getSystemService<ClipboardManager>()
|
||||
val data = clipboard?.primaryClip
|
||||
|
||||
if (data != null && data.itemCount > 0) {
|
||||
val packages = data.getItemAt(0).text.split("\n").toSet()
|
||||
val all = design.apps.map(AppInfo::packageName).intersect(packages)
|
||||
val all = withContext(Dispatchers.IO) {
|
||||
val packages = data.getItemAt(0).text.split("\n").toSet()
|
||||
|
||||
design.apps.map(AppInfo::packageName).intersect(packages)
|
||||
}
|
||||
|
||||
selected.clear()
|
||||
selected.addAll(all)
|
||||
@@ -100,16 +88,17 @@ class AccessControlActivity : BaseActivity<AccessControlDesign>() {
|
||||
|
||||
design.rebindAll()
|
||||
}
|
||||
|
||||
AccessControlDesign.Request.Export -> {
|
||||
val clipboard = getSystemService<ClipboardManager>()
|
||||
|
||||
val data = ClipData.newPlainText(
|
||||
"packages",
|
||||
selected.joinToString("\n")
|
||||
)
|
||||
withContext(Dispatchers.IO) {
|
||||
val data = ClipData.newPlainText(
|
||||
"packages",
|
||||
selected.joinToString("\n")
|
||||
)
|
||||
|
||||
clipboard?.setPrimaryClip(data)
|
||||
clipboard?.setPrimaryClip(data)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -134,10 +123,7 @@ class AccessControlActivity : BaseActivity<AccessControlDesign>() {
|
||||
it.packageName != packageName
|
||||
}
|
||||
.filter {
|
||||
it.applicationInfo != null
|
||||
}
|
||||
.filter {
|
||||
it.requestedPermissions?.contains(INTERNET) == true || it.applicationInfo!!.uid < android.os.Process.FIRST_APPLICATION_UID
|
||||
it.packageName == "android" || it.requestedPermissions?.contains(INTERNET) == true
|
||||
}
|
||||
.filter {
|
||||
systemApp || !it.isSystemApp
|
||||
@@ -151,6 +137,6 @@ class AccessControlActivity : BaseActivity<AccessControlDesign>() {
|
||||
|
||||
private val PackageInfo.isSystemApp: Boolean
|
||||
get() {
|
||||
return applicationInfo?.flags?.and(ApplicationInfo.FLAG_SYSTEM) != 0
|
||||
return applicationInfo.flags and ApplicationInfo.FLAG_SYSTEM != 0
|
||||
}
|
||||
}
|
||||
@@ -1,12 +1,9 @@
|
||||
package com.github.kr328.clash
|
||||
|
||||
import android.content.ComponentName
|
||||
import android.content.pm.PackageManager
|
||||
import androidx.core.content.pm.ShortcutManagerCompat
|
||||
import com.github.kr328.clash.common.util.componentName
|
||||
import com.github.kr328.clash.design.AppSettingsDesign
|
||||
import com.github.kr328.clash.design.model.Behavior
|
||||
import com.github.kr328.clash.design.store.UiStore.Companion.mainActivityAlias
|
||||
import com.github.kr328.clash.service.store.ServiceStore
|
||||
import com.github.kr328.clash.util.ApplicationObserver
|
||||
import kotlinx.coroutines.isActive
|
||||
@@ -20,7 +17,6 @@ class AppSettingsActivity : BaseActivity<AppSettingsDesign>(), Behavior {
|
||||
ServiceStore(this),
|
||||
this,
|
||||
clashRunning,
|
||||
::onHideIconChange,
|
||||
)
|
||||
|
||||
setContentDesign(design)
|
||||
@@ -63,21 +59,4 @@ class AppSettingsActivity : BaseActivity<AppSettingsDesign>(), Behavior {
|
||||
PackageManager.DONT_KILL_APP,
|
||||
)
|
||||
}
|
||||
|
||||
private fun onHideIconChange(hide: Boolean) {
|
||||
val newState = if (hide) {
|
||||
PackageManager.COMPONENT_ENABLED_STATE_DISABLED
|
||||
} else {
|
||||
PackageManager.COMPONENT_ENABLED_STATE_ENABLED
|
||||
}
|
||||
packageManager.setComponentEnabledSetting(
|
||||
mainActivityAlias,
|
||||
newState,
|
||||
PackageManager.DONT_KILL_APP
|
||||
)
|
||||
if (hide) {
|
||||
// Prevent launcher activity not found.
|
||||
ShortcutManagerCompat.removeAllDynamicShortcuts(this)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,13 +1,11 @@
|
||||
package com.github.kr328.clash
|
||||
|
||||
import android.app.ActivityManager
|
||||
import android.content.res.Configuration
|
||||
import android.os.Build
|
||||
import android.os.Bundle
|
||||
import android.view.View
|
||||
import androidx.activity.result.contract.ActivityResultContract
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import androidx.core.content.getSystemService
|
||||
import com.github.kr328.clash.common.compat.isAllowForceDarkCompat
|
||||
import com.github.kr328.clash.common.compat.isLightNavigationBarCompat
|
||||
import com.github.kr328.clash.common.compat.isLightStatusBarsCompat
|
||||
@@ -26,24 +24,34 @@ import com.github.kr328.clash.util.ActivityResultLifecycle
|
||||
import com.github.kr328.clash.util.ApplicationObserver
|
||||
import kotlinx.coroutines.*
|
||||
import kotlinx.coroutines.channels.Channel
|
||||
import java.util.*
|
||||
import java.util.concurrent.atomic.AtomicInteger
|
||||
import kotlin.coroutines.resume
|
||||
import kotlin.coroutines.suspendCoroutine
|
||||
import com.github.kr328.clash.design.R
|
||||
|
||||
abstract class BaseActivity<D : Design<*>> : AppCompatActivity(),
|
||||
abstract class BaseActivity<D : Design<*>> :
|
||||
AppCompatActivity(),
|
||||
CoroutineScope by MainScope(),
|
||||
Broadcasts.Observer {
|
||||
|
||||
enum class Event {
|
||||
ServiceRecreated,
|
||||
ActivityStart,
|
||||
ActivityStop,
|
||||
ClashStop,
|
||||
ClashStart,
|
||||
ProfileLoaded,
|
||||
ProfileChanged
|
||||
}
|
||||
|
||||
|
||||
protected val uiStore by lazy { UiStore(this) }
|
||||
protected val events = Channel<Event>(Channel.UNLIMITED)
|
||||
protected var activityStarted: Boolean = false
|
||||
protected val clashRunning: Boolean
|
||||
get() = Remote.broadcasts.clashRunning
|
||||
protected var design: D? = null
|
||||
set(value) {
|
||||
private set(value) {
|
||||
field = value
|
||||
|
||||
if (value != null) {
|
||||
setContentView(value.root)
|
||||
} else {
|
||||
@@ -64,14 +72,14 @@ abstract class BaseActivity<D : Design<*>> : AppCompatActivity(),
|
||||
|
||||
suspend fun <I, O> startActivityForResult(
|
||||
contracts: ActivityResultContract<I, O>,
|
||||
input: I,
|
||||
input: I
|
||||
): O = withContext(Dispatchers.Main) {
|
||||
val requestKey = nextRequestKey.getAndIncrement().toString()
|
||||
|
||||
ActivityResultLifecycle().use { lifecycle, start ->
|
||||
suspendCoroutine { c ->
|
||||
activityResultRegistry.register(requestKey, lifecycle, contracts) {
|
||||
c.resume(it)
|
||||
c.resumeWith(Result.success(it))
|
||||
}.apply { start() }.launch(input)
|
||||
}
|
||||
}
|
||||
@@ -81,6 +89,7 @@ abstract class BaseActivity<D : Design<*>> : AppCompatActivity(),
|
||||
suspendCoroutine<Unit> {
|
||||
window.decorView.post {
|
||||
this.design = design
|
||||
|
||||
it.resume(Unit)
|
||||
}
|
||||
}
|
||||
@@ -88,40 +97,49 @@ abstract class BaseActivity<D : Design<*>> : AppCompatActivity(),
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
applyDayNight()
|
||||
|
||||
// Apply excludeFromRecents setting to all app tasks.
|
||||
checkNotNull(getSystemService<ActivityManager>()).appTasks.forEach { task ->
|
||||
task.setExcludeFromRecents(uiStore.hideFromRecents)
|
||||
}
|
||||
applyDayNight()
|
||||
|
||||
launch {
|
||||
main()
|
||||
|
||||
finish()
|
||||
}
|
||||
}
|
||||
|
||||
override fun onStart() {
|
||||
super.onStart()
|
||||
|
||||
activityStarted = true
|
||||
|
||||
Remote.broadcasts.addObserver(this)
|
||||
|
||||
events.trySend(Event.ActivityStart)
|
||||
}
|
||||
|
||||
override fun onStop() {
|
||||
super.onStop()
|
||||
|
||||
activityStarted = false
|
||||
|
||||
Remote.broadcasts.removeObserver(this)
|
||||
|
||||
events.trySend(Event.ActivityStop)
|
||||
}
|
||||
|
||||
override fun onDestroy() {
|
||||
design?.cancel()
|
||||
|
||||
cancel()
|
||||
|
||||
super.onDestroy()
|
||||
}
|
||||
|
||||
override fun finish() {
|
||||
if (deferRunning) return
|
||||
if (deferRunning) {
|
||||
return
|
||||
}
|
||||
|
||||
deferRunning = true
|
||||
|
||||
launch {
|
||||
@@ -151,6 +169,7 @@ abstract class BaseActivity<D : Design<*>> : AppCompatActivity(),
|
||||
|
||||
override fun onSupportNavigateUp(): Boolean {
|
||||
this.onBackPressed()
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
@@ -158,14 +177,6 @@ abstract class BaseActivity<D : Design<*>> : AppCompatActivity(),
|
||||
events.trySend(Event.ProfileChanged)
|
||||
}
|
||||
|
||||
override fun onProfileUpdateCompleted(uuid: UUID?) {
|
||||
events.trySend(Event.ProfileUpdateCompleted)
|
||||
}
|
||||
|
||||
override fun onProfileUpdateFailed(uuid: UUID?, reason: String?) {
|
||||
events.trySend(Event.ProfileUpdateFailed)
|
||||
}
|
||||
|
||||
override fun onProfileLoaded() {
|
||||
events.trySend(Event.ProfileLoaded)
|
||||
}
|
||||
@@ -190,45 +201,49 @@ abstract class BaseActivity<D : Design<*>> : AppCompatActivity(),
|
||||
|
||||
private fun queryDayNight(config: Configuration = resources.configuration): DayNight {
|
||||
return when (uiStore.darkMode) {
|
||||
DarkMode.Auto -> if (config.uiMode and Configuration.UI_MODE_NIGHT_MASK == Configuration.UI_MODE_NIGHT_YES) DayNight.Night else DayNight.Day
|
||||
DarkMode.ForceLight -> DayNight.Day
|
||||
DarkMode.ForceDark -> DayNight.Night
|
||||
DarkMode.Auto -> {
|
||||
if (config.uiMode and Configuration.UI_MODE_NIGHT_MASK == Configuration.UI_MODE_NIGHT_YES)
|
||||
DayNight.Night
|
||||
else
|
||||
DayNight.Day
|
||||
}
|
||||
DarkMode.ForceLight -> {
|
||||
DayNight.Day
|
||||
}
|
||||
DarkMode.ForceDark -> {
|
||||
DayNight.Night
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun applyDayNight(config: Configuration = resources.configuration) {
|
||||
val dayNight = queryDayNight(config)
|
||||
|
||||
when (dayNight) {
|
||||
DayNight.Night -> theme.applyStyle(R.style.AppThemeDark, true)
|
||||
DayNight.Day -> theme.applyStyle(R.style.AppThemeLight, true)
|
||||
DayNight.Night -> {
|
||||
theme.applyStyle(R.style.AppThemeDark, true)
|
||||
}
|
||||
DayNight.Day -> {
|
||||
theme.applyStyle(R.style.AppThemeLight, true)
|
||||
}
|
||||
}
|
||||
|
||||
window.isAllowForceDarkCompat = false
|
||||
window.isSystemBarsTranslucentCompat = true
|
||||
|
||||
|
||||
window.statusBarColor = resolveThemedColor(android.R.attr.statusBarColor)
|
||||
window.navigationBarColor = resolveThemedColor(android.R.attr.navigationBarColor)
|
||||
|
||||
if (Build.VERSION.SDK_INT >= 23) {
|
||||
window.isLightStatusBarsCompat = resolveThemedBoolean(android.R.attr.windowLightStatusBar)
|
||||
window.isLightStatusBarsCompat =
|
||||
resolveThemedBoolean(android.R.attr.windowLightStatusBar)
|
||||
}
|
||||
|
||||
if (Build.VERSION.SDK_INT >= 27) {
|
||||
window.isLightNavigationBarCompat = resolveThemedBoolean(android.R.attr.windowLightNavigationBar)
|
||||
window.isLightNavigationBarCompat =
|
||||
resolveThemedBoolean(android.R.attr.windowLightNavigationBar)
|
||||
}
|
||||
|
||||
this.dayNight = dayNight
|
||||
}
|
||||
|
||||
enum class Event {
|
||||
ServiceRecreated,
|
||||
ActivityStart,
|
||||
ActivityStop,
|
||||
ClashStop,
|
||||
ClashStart,
|
||||
ProfileLoaded,
|
||||
ProfileChanged,
|
||||
ProfileUpdateCompleted,
|
||||
ProfileUpdateFailed,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,13 +0,0 @@
|
||||
package com.github.kr328.clash
|
||||
|
||||
import android.content.BroadcastReceiver
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
|
||||
class DialerReceiver : BroadcastReceiver() {
|
||||
override fun onReceive(context: Context, intent: Intent) {
|
||||
val intent = Intent(context, MainActivity::class.java)
|
||||
.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
|
||||
context.startActivity(intent)
|
||||
}
|
||||
}
|
||||
@@ -1,101 +0,0 @@
|
||||
package com.github.kr328.clash
|
||||
|
||||
import android.app.Activity
|
||||
import android.content.Intent
|
||||
import android.os.Bundle
|
||||
import android.widget.Toast
|
||||
import androidx.activity.result.contract.ActivityResultContracts
|
||||
import com.github.kr328.clash.common.constants.Intents
|
||||
import com.github.kr328.clash.common.util.intent
|
||||
import com.github.kr328.clash.common.util.setUUID
|
||||
import com.github.kr328.clash.design.MainDesign
|
||||
import com.github.kr328.clash.design.ui.ToastDuration
|
||||
import com.github.kr328.clash.remote.Remote
|
||||
import com.github.kr328.clash.remote.StatusClient
|
||||
import com.github.kr328.clash.service.model.Profile
|
||||
import com.github.kr328.clash.util.startClashService
|
||||
import com.github.kr328.clash.util.stopClashService
|
||||
import com.github.kr328.clash.util.withProfile
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.MainScope
|
||||
import kotlinx.coroutines.launch
|
||||
import java.util.*
|
||||
import com.github.kr328.clash.design.R
|
||||
|
||||
class ExternalControlActivity : Activity(), CoroutineScope by MainScope() {
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
@Suppress("DEPRECATION")
|
||||
overridePendingTransition(0, 0)
|
||||
|
||||
when(intent.action) {
|
||||
Intent.ACTION_VIEW -> {
|
||||
val uri = intent.data ?: return finish()
|
||||
val url = uri.getQueryParameter("url") ?: return finish()
|
||||
|
||||
launch {
|
||||
val uuid = withProfile {
|
||||
val type = when (uri.getQueryParameter("type")?.lowercase(Locale.getDefault())) {
|
||||
"url" -> Profile.Type.Url
|
||||
"file" -> Profile.Type.File
|
||||
else -> Profile.Type.Url
|
||||
}
|
||||
val name = uri.getQueryParameter("name") ?: getString(R.string.new_profile)
|
||||
|
||||
create(type, name).also {
|
||||
patch(it, name, url, 0)
|
||||
}
|
||||
}
|
||||
startActivity(PropertiesActivity::class.intent.setUUID(uuid))
|
||||
finish()
|
||||
}
|
||||
}
|
||||
|
||||
Intents.ACTION_TOGGLE_CLASH -> if(Remote.broadcasts.clashRunning) {
|
||||
stopClash()
|
||||
}
|
||||
else {
|
||||
startClash()
|
||||
}
|
||||
|
||||
Intents.ACTION_START_CLASH -> if(!Remote.broadcasts.clashRunning) {
|
||||
startClash()
|
||||
}
|
||||
else {
|
||||
Toast.makeText(this, R.string.external_control_started, Toast.LENGTH_LONG).show()
|
||||
}
|
||||
|
||||
Intents.ACTION_STOP_CLASH -> if(Remote.broadcasts.clashRunning) {
|
||||
stopClash()
|
||||
}
|
||||
else {
|
||||
Toast.makeText(this, R.string.external_control_stopped, Toast.LENGTH_LONG).show()
|
||||
}
|
||||
}
|
||||
return finish()
|
||||
}
|
||||
|
||||
private fun startClash() {
|
||||
// if (currentProfile == null) {
|
||||
// Toast.makeText(this, R.string.no_profile_selected, Toast.LENGTH_LONG).show()
|
||||
// return
|
||||
// }
|
||||
val vpnRequest = startClashService()
|
||||
if (vpnRequest != null) {
|
||||
Toast.makeText(this, R.string.unable_to_start_vpn, Toast.LENGTH_LONG).show()
|
||||
return
|
||||
}
|
||||
Toast.makeText(this, R.string.external_control_started, Toast.LENGTH_LONG).show()
|
||||
}
|
||||
|
||||
private fun stopClash() {
|
||||
stopClashService()
|
||||
Toast.makeText(this, R.string.external_control_stopped, Toast.LENGTH_LONG).show()
|
||||
}
|
||||
|
||||
override fun finish() {
|
||||
super.finish()
|
||||
@Suppress("DEPRECATION")
|
||||
overridePendingTransition(0, 0)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
package com.github.kr328.clash
|
||||
|
||||
import android.app.Activity
|
||||
import android.content.Intent
|
||||
import android.os.Bundle
|
||||
import com.github.kr328.clash.common.util.intent
|
||||
import com.github.kr328.clash.common.util.setUUID
|
||||
import com.github.kr328.clash.service.model.Profile
|
||||
import com.github.kr328.clash.util.withProfile
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.MainScope
|
||||
import kotlinx.coroutines.launch
|
||||
import java.util.*
|
||||
|
||||
class ExternalImportActivity : Activity(), CoroutineScope by MainScope() {
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
|
||||
if (intent.action != Intent.ACTION_VIEW)
|
||||
return finish()
|
||||
|
||||
val uri = intent.data ?: return finish()
|
||||
val url = uri.getQueryParameter("url") ?: return finish()
|
||||
|
||||
launch {
|
||||
val uuid = withProfile {
|
||||
val type = when (uri.getQueryParameter("type")?.lowercase(Locale.getDefault())) {
|
||||
"url" -> Profile.Type.Url
|
||||
"file" -> Profile.Type.File
|
||||
else -> Profile.Type.Url
|
||||
}
|
||||
val name = uri.getQueryParameter("name") ?: getString(R.string.new_profile)
|
||||
|
||||
create(type, name).also {
|
||||
patch(it, name, url, 0)
|
||||
}
|
||||
}
|
||||
|
||||
startActivity(PropertiesActivity::class.intent.setUUID(uuid))
|
||||
|
||||
finish()
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -81,6 +81,24 @@ class FilesActivity : BaseActivity<FilesDesign>() {
|
||||
client.renameDocument(it.file.id, newName)
|
||||
}
|
||||
is FilesDesign.Request.ImportFile -> {
|
||||
if (Build.VERSION.SDK_INT >= 23) {
|
||||
val hasPermission = ContextCompat.checkSelfPermission(
|
||||
this@FilesActivity,
|
||||
Manifest.permission.READ_EXTERNAL_STORAGE
|
||||
) == PackageManager.PERMISSION_GRANTED
|
||||
|
||||
if (!hasPermission) {
|
||||
val granted = startActivityForResult(
|
||||
ActivityResultContracts.RequestPermission(),
|
||||
Manifest.permission.READ_EXTERNAL_STORAGE,
|
||||
)
|
||||
|
||||
if (!granted) {
|
||||
return@onReceive
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
val uri: Uri? = startActivityForResult(
|
||||
ActivityResultContracts.GetContent(),
|
||||
"*/*"
|
||||
@@ -98,7 +116,7 @@ class FilesActivity : BaseActivity<FilesDesign>() {
|
||||
}
|
||||
is FilesDesign.Request.ExportFile -> {
|
||||
val uri: Uri? = startActivityForResult(
|
||||
ActivityResultContracts.CreateDocument("text/plain"),
|
||||
ActivityResultContracts.CreateDocument(),
|
||||
it.file.name
|
||||
)
|
||||
|
||||
|
||||
@@ -8,7 +8,6 @@ import android.os.IBinder
|
||||
import android.widget.Toast
|
||||
import androidx.activity.result.contract.ActivityResultContracts
|
||||
import com.github.kr328.clash.common.compat.startForegroundServiceCompat
|
||||
import com.github.kr328.clash.common.log.Log
|
||||
import com.github.kr328.clash.common.util.fileName
|
||||
import com.github.kr328.clash.common.util.intent
|
||||
import com.github.kr328.clash.common.util.ticker
|
||||
@@ -28,7 +27,6 @@ import kotlinx.coroutines.withContext
|
||||
import java.io.OutputStreamWriter
|
||||
import kotlin.coroutines.resume
|
||||
import kotlin.coroutines.suspendCoroutine
|
||||
import com.github.kr328.clash.design.R
|
||||
|
||||
class LogcatActivity : BaseActivity<LogcatDesign>() {
|
||||
private var conn: ServiceConnection? = null
|
||||
@@ -49,7 +47,6 @@ class LogcatActivity : BaseActivity<LogcatDesign>() {
|
||||
val messages = try {
|
||||
LogcatReader(this, file).readAll()
|
||||
} catch (e: Exception) {
|
||||
Log.e("Fail to read log file ${file.fileName}: ${e.message}")
|
||||
return showInvalid()
|
||||
}
|
||||
|
||||
@@ -70,7 +67,7 @@ class LogcatActivity : BaseActivity<LogcatDesign>() {
|
||||
}
|
||||
LogcatDesign.Request.Export -> {
|
||||
val output = startActivityForResult(
|
||||
ActivityResultContracts.CreateDocument("text/plain"),
|
||||
ActivityResultContracts.CreateDocument(),
|
||||
file.fileName
|
||||
)
|
||||
|
||||
@@ -112,7 +109,7 @@ class LogcatActivity : BaseActivity<LogcatDesign>() {
|
||||
when (it) {
|
||||
LogcatDesign.Request.Close -> {
|
||||
stopService(LogcatService::class.intent)
|
||||
startActivity(LogsActivity::class.intent)
|
||||
|
||||
finish()
|
||||
}
|
||||
else -> Unit
|
||||
|
||||
@@ -14,7 +14,6 @@ import androidx.core.app.NotificationCompat
|
||||
import androidx.core.app.NotificationManagerCompat
|
||||
import com.github.kr328.clash.common.compat.getColorCompat
|
||||
import com.github.kr328.clash.common.compat.pendingIntentFlags
|
||||
import com.github.kr328.clash.common.compat.startForegroundCompat
|
||||
import com.github.kr328.clash.common.log.Log
|
||||
import com.github.kr328.clash.common.util.intent
|
||||
import com.github.kr328.clash.core.model.LogMessage
|
||||
@@ -131,17 +130,17 @@ class LogcatService : Service(), CoroutineScope by CoroutineScope(Dispatchers.De
|
||||
NotificationChannelCompat.Builder(
|
||||
CHANNEL_ID,
|
||||
NotificationManagerCompat.IMPORTANCE_DEFAULT
|
||||
).setName(getString(com.github.kr328.clash.design.R.string.clash_logcat)).build()
|
||||
).setName(getString(R.string.clash_logcat)).build()
|
||||
)
|
||||
}
|
||||
|
||||
private fun showNotification() {
|
||||
val notification = NotificationCompat
|
||||
.Builder(this, CHANNEL_ID)
|
||||
.setSmallIcon(com.github.kr328.clash.service.R.drawable.ic_logo_service)
|
||||
.setColor(getColorCompat(com.github.kr328.clash.design.R.color.color_clash_light))
|
||||
.setContentTitle(getString(com.github.kr328.clash.design.R.string.clash_logcat))
|
||||
.setContentText(getString(com.github.kr328.clash.design.R.string.running))
|
||||
.setSmallIcon(R.drawable.ic_logo_service)
|
||||
.setColor(getColorCompat(R.color.color_clash_light))
|
||||
.setContentTitle(getString(R.string.clash_logcat))
|
||||
.setContentText(getString(R.string.running))
|
||||
.setContentIntent(
|
||||
PendingIntent.getActivity(
|
||||
this,
|
||||
@@ -153,7 +152,7 @@ class LogcatService : Service(), CoroutineScope by CoroutineScope(Dispatchers.De
|
||||
)
|
||||
.build()
|
||||
|
||||
startForegroundCompat(R.id.nf_logcat_status, notification)
|
||||
startForeground(R.id.nf_logcat_status, notification)
|
||||
}
|
||||
|
||||
companion object {
|
||||
|
||||
@@ -11,8 +11,11 @@ import kotlinx.coroutines.selects.select
|
||||
import kotlinx.coroutines.withContext
|
||||
|
||||
class LogsActivity : BaseActivity<LogsDesign>() {
|
||||
|
||||
override suspend fun main() {
|
||||
if (LogcatService.running) {
|
||||
return startActivity(LogcatActivity::class.intent)
|
||||
}
|
||||
|
||||
val design = LogsDesign(this)
|
||||
|
||||
setContentDesign(design)
|
||||
@@ -35,6 +38,7 @@ class LogsActivity : BaseActivity<LogsDesign>() {
|
||||
when (it) {
|
||||
LogsDesign.Request.StartLogcat -> {
|
||||
startActivity(LogcatActivity::class.intent)
|
||||
|
||||
finish()
|
||||
}
|
||||
LogsDesign.Request.DeleteAll -> {
|
||||
|
||||
@@ -1,28 +1,21 @@
|
||||
package com.github.kr328.clash
|
||||
|
||||
import android.content.pm.PackageManager
|
||||
import android.os.Build
|
||||
import android.os.Bundle
|
||||
import android.os.PersistableBundle
|
||||
import androidx.activity.result.contract.ActivityResultContracts
|
||||
import androidx.activity.result.contract.ActivityResultContracts.RequestPermission
|
||||
import androidx.core.app.ActivityCompat
|
||||
import androidx.core.content.ContextCompat
|
||||
import com.github.kr328.clash.common.util.intent
|
||||
import com.github.kr328.clash.common.util.ticker
|
||||
import com.github.kr328.clash.design.MainDesign
|
||||
import com.github.kr328.clash.design.ui.ToastDuration
|
||||
import com.github.kr328.clash.store.TipsStore
|
||||
import com.github.kr328.clash.util.startClashService
|
||||
import com.github.kr328.clash.util.stopClashService
|
||||
import com.github.kr328.clash.util.withClash
|
||||
import com.github.kr328.clash.util.withProfile
|
||||
import com.github.kr328.clash.core.bridge.*
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.isActive
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.selects.select
|
||||
import kotlinx.coroutines.withContext
|
||||
import java.util.concurrent.TimeUnit
|
||||
import com.github.kr328.clash.design.R
|
||||
|
||||
class MainActivity : BaseActivity<MainDesign>() {
|
||||
override suspend fun main() {
|
||||
@@ -30,6 +23,10 @@ class MainActivity : BaseActivity<MainDesign>() {
|
||||
|
||||
setContentDesign(design)
|
||||
|
||||
launch(Dispatchers.IO) {
|
||||
showUpdatedTips(design)
|
||||
}
|
||||
|
||||
design.fetch()
|
||||
|
||||
val ticker = ticker(TimeUnit.SECONDS.toMillis(1))
|
||||
@@ -59,13 +56,8 @@ class MainActivity : BaseActivity<MainDesign>() {
|
||||
startActivity(ProfilesActivity::class.intent)
|
||||
MainDesign.Request.OpenProviders ->
|
||||
startActivity(ProvidersActivity::class.intent)
|
||||
MainDesign.Request.OpenLogs -> {
|
||||
if (LogcatService.running) {
|
||||
startActivity(LogcatActivity::class.intent)
|
||||
} else {
|
||||
startActivity(LogsActivity::class.intent)
|
||||
}
|
||||
}
|
||||
MainDesign.Request.OpenLogs ->
|
||||
startActivity(LogsActivity::class.intent)
|
||||
MainDesign.Request.OpenSettings ->
|
||||
startActivity(SettingsActivity::class.intent)
|
||||
MainDesign.Request.OpenHelp ->
|
||||
@@ -83,6 +75,20 @@ class MainActivity : BaseActivity<MainDesign>() {
|
||||
}
|
||||
}
|
||||
|
||||
private suspend fun showUpdatedTips(design: MainDesign) {
|
||||
val tips = TipsStore(this)
|
||||
|
||||
if (tips.primaryVersion != TipsStore.CURRENT_PRIMARY_VERSION) {
|
||||
tips.primaryVersion = TipsStore.CURRENT_PRIMARY_VERSION
|
||||
|
||||
val pkg = packageManager.getPackageInfo(packageName, 0)
|
||||
|
||||
if (pkg.firstInstallTime != pkg.lastUpdateTime) {
|
||||
design.showUpdatedTips()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private suspend fun MainDesign.fetch() {
|
||||
setClashRunning(clashRunning)
|
||||
|
||||
@@ -139,23 +145,7 @@ class MainActivity : BaseActivity<MainDesign>() {
|
||||
|
||||
private suspend fun queryAppVersionName(): String {
|
||||
return withContext(Dispatchers.IO) {
|
||||
packageManager.getPackageInfo(packageName, 0).versionName + "\n" + Bridge.nativeCoreVersion().replace("_", "-")
|
||||
packageManager.getPackageInfo(packageName, 0).versionName
|
||||
}
|
||||
}
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
|
||||
val requestPermissionLauncher =
|
||||
registerForActivityResult(RequestPermission()
|
||||
) { isGranted: Boolean ->
|
||||
}
|
||||
if (ContextCompat.checkSelfPermission(
|
||||
this,
|
||||
android.Manifest.permission.POST_NOTIFICATIONS
|
||||
) != PackageManager.PERMISSION_GRANTED) {
|
||||
requestPermissionLauncher.launch(android.Manifest.permission.POST_NOTIFICATIONS)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2,27 +2,14 @@ package com.github.kr328.clash
|
||||
|
||||
import android.app.Application
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import androidx.core.content.pm.ShortcutInfoCompat
|
||||
import androidx.core.content.pm.ShortcutManagerCompat
|
||||
import androidx.core.graphics.drawable.IconCompat
|
||||
import com.github.kr328.clash.common.Global
|
||||
import com.github.kr328.clash.common.compat.currentProcessName
|
||||
import com.github.kr328.clash.common.constants.Intents
|
||||
import com.github.kr328.clash.common.log.Log
|
||||
import com.github.kr328.clash.design.store.UiStore
|
||||
import com.github.kr328.clash.remote.Remote
|
||||
import com.github.kr328.clash.service.util.sendServiceRecreated
|
||||
import com.github.kr328.clash.util.clashDir
|
||||
import java.io.File
|
||||
import java.io.FileOutputStream
|
||||
import com.github.kr328.clash.design.R as DesignR
|
||||
|
||||
|
||||
@Suppress("unused")
|
||||
class MainApplication : Application() {
|
||||
private val uiStore by lazy(LazyThreadSafetyMode.NONE) { UiStore(this) }
|
||||
|
||||
override fun attachBaseContext(base: Context?) {
|
||||
super.attachBaseContext(base)
|
||||
|
||||
@@ -32,106 +19,21 @@ class MainApplication : Application() {
|
||||
override fun onCreate() {
|
||||
super.onCreate()
|
||||
|
||||
// Initialize AppCenter
|
||||
Tracker.initialize(this)
|
||||
|
||||
val processName = currentProcessName
|
||||
extractGeoFiles()
|
||||
|
||||
Log.d("Process $processName started")
|
||||
|
||||
if (processName == packageName) {
|
||||
Remote.launch()
|
||||
setupShortcuts()
|
||||
} else {
|
||||
sendServiceRecreated()
|
||||
}
|
||||
}
|
||||
|
||||
private fun setupShortcuts() {
|
||||
if (uiStore.hideAppIcon) {
|
||||
// Prevent launcher activity not found.
|
||||
ShortcutManagerCompat.removeAllDynamicShortcuts(this)
|
||||
return
|
||||
}
|
||||
|
||||
val icon = IconCompat.createWithResource(this, R.mipmap.ic_launcher)
|
||||
val flags = Intent.FLAG_ACTIVITY_NEW_TASK or
|
||||
Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS or
|
||||
Intent.FLAG_ACTIVITY_NO_ANIMATION
|
||||
|
||||
val toggle = ShortcutInfoCompat.Builder(this, "toggle_clash")
|
||||
.setShortLabel(getString(DesignR.string.shortcut_toggle_short))
|
||||
.setLongLabel(getString(DesignR.string.shortcut_toggle_long))
|
||||
.setIcon(icon)
|
||||
.setIntent(
|
||||
Intent(Intents.ACTION_TOGGLE_CLASH)
|
||||
.setClassName(this, ExternalControlActivity::class.java.name)
|
||||
.addFlags(flags)
|
||||
)
|
||||
.setRank(0)
|
||||
.build()
|
||||
|
||||
val start = ShortcutInfoCompat.Builder(this, "start_clash")
|
||||
.setShortLabel(getString(DesignR.string.shortcut_start_short))
|
||||
.setLongLabel(getString(DesignR.string.shortcut_start_long))
|
||||
.setIcon(icon)
|
||||
.setIntent(
|
||||
Intent(Intents.ACTION_START_CLASH)
|
||||
.setClassName(this, ExternalControlActivity::class.java.name)
|
||||
.addFlags(flags)
|
||||
)
|
||||
.setRank(1)
|
||||
.build()
|
||||
|
||||
val stop = ShortcutInfoCompat.Builder(this, "stop_clash")
|
||||
.setShortLabel(getString(DesignR.string.shortcut_stop_short))
|
||||
.setLongLabel(getString(DesignR.string.shortcut_stop_long))
|
||||
.setIcon(icon)
|
||||
.setIntent(
|
||||
Intent(Intents.ACTION_STOP_CLASH)
|
||||
.setClassName(this, ExternalControlActivity::class.java.name)
|
||||
.addFlags(flags)
|
||||
)
|
||||
.setRank(2)
|
||||
.build()
|
||||
|
||||
ShortcutManagerCompat.setDynamicShortcuts(this, listOf(toggle, start, stop))
|
||||
}
|
||||
|
||||
private fun extractGeoFiles() {
|
||||
clashDir.mkdirs()
|
||||
|
||||
val updateDate = packageManager.getPackageInfo(packageName, 0).lastUpdateTime
|
||||
val geoipFile = File(clashDir, "geoip.metadb")
|
||||
if (geoipFile.exists() && geoipFile.lastModified() < updateDate) {
|
||||
geoipFile.delete()
|
||||
}
|
||||
if (!geoipFile.exists()) {
|
||||
FileOutputStream(geoipFile).use {
|
||||
assets.open("geoip.metadb").copyTo(it)
|
||||
}
|
||||
}
|
||||
|
||||
val geositeFile = File(clashDir, "geosite.dat")
|
||||
if (geositeFile.exists() && geositeFile.lastModified() < updateDate) {
|
||||
geositeFile.delete()
|
||||
}
|
||||
if (!geositeFile.exists()) {
|
||||
FileOutputStream(geositeFile).use {
|
||||
assets.open("geosite.dat").copyTo(it)
|
||||
}
|
||||
}
|
||||
|
||||
val asnFile = File(clashDir, "ASN.mmdb")
|
||||
if (asnFile.exists() && asnFile.lastModified() < updateDate) {
|
||||
asnFile.delete()
|
||||
}
|
||||
if (!asnFile.exists()) {
|
||||
FileOutputStream(asnFile).use {
|
||||
assets.open("ASN.mmdb").copyTo(it)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun finalize() {
|
||||
Global.destroy()
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,137 +0,0 @@
|
||||
package com.github.kr328.clash
|
||||
|
||||
import android.database.Cursor
|
||||
import android.net.Uri
|
||||
import android.provider.OpenableColumns
|
||||
import android.widget.Toast
|
||||
import androidx.activity.result.contract.ActivityResultContracts
|
||||
import com.github.kr328.clash.core.Clash
|
||||
import com.github.kr328.clash.design.MetaFeatureSettingsDesign
|
||||
import com.github.kr328.clash.util.clashDir
|
||||
import com.github.kr328.clash.util.withClash
|
||||
import com.google.android.material.dialog.MaterialAlertDialogBuilder
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.isActive
|
||||
import kotlinx.coroutines.selects.select
|
||||
import kotlinx.coroutines.withContext
|
||||
import java.io.File
|
||||
import java.io.FileOutputStream
|
||||
import com.github.kr328.clash.design.R
|
||||
|
||||
|
||||
class MetaFeatureSettingsActivity : BaseActivity<MetaFeatureSettingsDesign>() {
|
||||
override suspend fun main() {
|
||||
val configuration = withClash { queryOverride(Clash.OverrideSlot.Persist) }
|
||||
|
||||
defer {
|
||||
withClash {
|
||||
patchOverride(Clash.OverrideSlot.Persist, configuration)
|
||||
}
|
||||
}
|
||||
|
||||
val design = MetaFeatureSettingsDesign(
|
||||
this,
|
||||
configuration
|
||||
)
|
||||
|
||||
setContentDesign(design)
|
||||
|
||||
while (isActive) {
|
||||
select<Unit> {
|
||||
events.onReceive {
|
||||
|
||||
}
|
||||
design.requests.onReceive {
|
||||
when (it) {
|
||||
MetaFeatureSettingsDesign.Request.ResetOverride -> {
|
||||
if (design.requestResetConfirm()) {
|
||||
defer {
|
||||
withClash {
|
||||
clearOverride(Clash.OverrideSlot.Persist)
|
||||
}
|
||||
}
|
||||
finish()
|
||||
}
|
||||
}
|
||||
MetaFeatureSettingsDesign.Request.ImportGeoIp -> {
|
||||
val uri = startActivityForResult(
|
||||
ActivityResultContracts.GetContent(),
|
||||
"*/*")
|
||||
importGeoFile(uri, MetaFeatureSettingsDesign.Request.ImportGeoIp)
|
||||
}
|
||||
MetaFeatureSettingsDesign.Request.ImportGeoSite -> {
|
||||
val uri = startActivityForResult(
|
||||
ActivityResultContracts.GetContent(),
|
||||
"*/*")
|
||||
importGeoFile(uri, MetaFeatureSettingsDesign.Request.ImportGeoSite)
|
||||
}
|
||||
MetaFeatureSettingsDesign.Request.ImportCountry -> {
|
||||
val uri = startActivityForResult(
|
||||
ActivityResultContracts.GetContent(),
|
||||
"*/*")
|
||||
importGeoFile(uri, MetaFeatureSettingsDesign.Request.ImportCountry)
|
||||
}
|
||||
MetaFeatureSettingsDesign.Request.ImportASN -> {
|
||||
val uri = startActivityForResult(
|
||||
ActivityResultContracts.GetContent(),
|
||||
"*/*")
|
||||
importGeoFile(uri, MetaFeatureSettingsDesign.Request.ImportASN)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private val validDatabaseExtensions = listOf(
|
||||
".metadb", ".db", ".dat", ".mmdb"
|
||||
)
|
||||
|
||||
private suspend fun importGeoFile(uri: Uri?, importType: MetaFeatureSettingsDesign.Request) {
|
||||
val cursor: Cursor? = uri?.let {
|
||||
contentResolver.query(it, null, null, null, null, null)
|
||||
}
|
||||
cursor?.use {
|
||||
if (it.moveToFirst()) {
|
||||
val columnIndex = it.getColumnIndex(OpenableColumns.DISPLAY_NAME)
|
||||
val displayName: String =
|
||||
if (columnIndex != -1) it.getString(columnIndex) else "";
|
||||
val ext = "." + displayName.substringAfterLast(".")
|
||||
|
||||
if (!validDatabaseExtensions.contains(ext)) {
|
||||
MaterialAlertDialogBuilder(this)
|
||||
.setTitle(R.string.geofile_unknown_db_format)
|
||||
.setMessage(getString(R.string.geofile_unknown_db_format_message,
|
||||
validDatabaseExtensions.joinToString("/")))
|
||||
.setPositiveButton("OK") { _, _ -> }
|
||||
.show()
|
||||
return
|
||||
}
|
||||
val outputFileName = when (importType) {
|
||||
MetaFeatureSettingsDesign.Request.ImportGeoIp ->
|
||||
"geoip$ext"
|
||||
MetaFeatureSettingsDesign.Request.ImportGeoSite ->
|
||||
"geosite$ext"
|
||||
MetaFeatureSettingsDesign.Request.ImportCountry ->
|
||||
"country$ext"
|
||||
MetaFeatureSettingsDesign.Request.ImportASN ->
|
||||
"ASN$ext"
|
||||
else -> ""
|
||||
}
|
||||
|
||||
withContext(Dispatchers.IO) {
|
||||
val outputFile = File(clashDir, outputFileName);
|
||||
contentResolver.openInputStream(uri).use { ins ->
|
||||
FileOutputStream(outputFile).use { outs ->
|
||||
ins?.copyTo(outs)
|
||||
}
|
||||
}
|
||||
}
|
||||
Toast.makeText(this, getString(R.string.geofile_imported, displayName),
|
||||
Toast.LENGTH_LONG).show()
|
||||
return
|
||||
}
|
||||
}
|
||||
Toast.makeText(this, R.string.geofile_import_failed, Toast.LENGTH_LONG).show()
|
||||
}
|
||||
}
|
||||
@@ -6,25 +6,15 @@ import android.content.Intent
|
||||
import android.net.Uri
|
||||
import android.provider.Settings
|
||||
import androidx.activity.result.contract.ActivityResultContracts
|
||||
import androidx.lifecycle.lifecycleScope
|
||||
import com.github.kr328.clash.common.constants.Intents
|
||||
import com.github.kr328.clash.common.util.intent
|
||||
import com.github.kr328.clash.common.util.setUUID
|
||||
import com.github.kr328.clash.design.NewProfileDesign
|
||||
import com.github.kr328.clash.design.R
|
||||
import com.github.kr328.clash.design.model.ProfileProvider
|
||||
import com.github.kr328.clash.design.util.showExceptionToast
|
||||
import com.github.kr328.clash.service.model.Profile
|
||||
import com.github.kr328.clash.util.withProfile
|
||||
import io.github.g00fy2.quickie.QRResult
|
||||
import io.github.g00fy2.quickie.QRResult.QRError
|
||||
import io.github.g00fy2.quickie.QRResult.QRMissingPermission
|
||||
import io.github.g00fy2.quickie.QRResult.QRSuccess
|
||||
import io.github.g00fy2.quickie.QRResult.QRUserCanceled
|
||||
import io.github.g00fy2.quickie.ScanQRCode
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.isActive
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.selects.select
|
||||
import kotlinx.coroutines.withContext
|
||||
import java.util.*
|
||||
@@ -33,8 +23,6 @@ class NewProfileActivity : BaseActivity<NewProfileDesign>() {
|
||||
private val self: NewProfileActivity
|
||||
get() = this
|
||||
|
||||
private val scanLauncher = registerForActivityResult(ScanQRCode(), ::scanResultHandler)
|
||||
|
||||
override suspend fun main() {
|
||||
val design = NewProfileDesign(this)
|
||||
|
||||
@@ -56,14 +44,8 @@ class NewProfileActivity : BaseActivity<NewProfileDesign>() {
|
||||
val uuid: UUID? = when (val p = it.provider) {
|
||||
is ProfileProvider.File ->
|
||||
create(Profile.Type.File, name)
|
||||
|
||||
is ProfileProvider.Url ->
|
||||
create(Profile.Type.Url, name)
|
||||
|
||||
is ProfileProvider.QR -> {
|
||||
null
|
||||
}
|
||||
|
||||
is ProfileProvider.External -> {
|
||||
val data = p.get()
|
||||
|
||||
@@ -85,14 +67,9 @@ class NewProfileActivity : BaseActivity<NewProfileDesign>() {
|
||||
launchProperties(uuid)
|
||||
}
|
||||
}
|
||||
|
||||
is NewProfileDesign.Request.OpenDetail -> {
|
||||
launchAppDetailed(it.provider)
|
||||
}
|
||||
|
||||
is NewProfileDesign.Request.LaunchScanner -> {
|
||||
scanLauncher.launch(null)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -160,41 +137,7 @@ class NewProfileActivity : BaseActivity<NewProfileDesign>() {
|
||||
ProfileProvider.External(name.toString(), summary.toString(), icon, intent)
|
||||
}
|
||||
|
||||
listOf(
|
||||
ProfileProvider.File(self),
|
||||
ProfileProvider.Url(self),
|
||||
ProfileProvider.QR(self)
|
||||
) + providers
|
||||
listOf(ProfileProvider.File(self), ProfileProvider.Url(self)) + providers
|
||||
}
|
||||
}
|
||||
|
||||
private fun scanResultHandler(result: QRResult) {
|
||||
lifecycleScope.launch {
|
||||
when (result) {
|
||||
is QRSuccess -> {
|
||||
val url = result.content.rawValue
|
||||
?: result.content.rawBytes?.let { String(it) }.orEmpty()
|
||||
|
||||
createProfileByQrCode(url)
|
||||
}
|
||||
|
||||
QRUserCanceled -> {}
|
||||
QRMissingPermission -> design?.showExceptionToast(getString(R.string.import_from_qr_no_permission))
|
||||
is QRError -> design?.showExceptionToast(getString(R.string.import_from_qr_exception))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private suspend fun createProfileByQrCode(url: String) {
|
||||
withProfile {
|
||||
launchProperties(
|
||||
create(
|
||||
type = Profile.Type.Url,
|
||||
name = getString(R.string.new_profile),
|
||||
url,
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -45,14 +45,45 @@ class OverrideSettingsActivity : BaseActivity<OverrideSettingsDesign>() {
|
||||
withClash {
|
||||
clearOverride(Clash.OverrideSlot.Persist)
|
||||
}
|
||||
|
||||
service.sideloadGeoip = ""
|
||||
}
|
||||
|
||||
finish()
|
||||
}
|
||||
}
|
||||
OverrideSettingsDesign.Request.EditSideloadGeoip -> {
|
||||
withContext(Dispatchers.IO) {
|
||||
val list = querySideloadProviders()
|
||||
val initial = service.sideloadGeoip
|
||||
val exist = list.any { info -> info.packageName == initial }
|
||||
|
||||
service.sideloadGeoip =
|
||||
design.requestSelectSideload(if (exist) initial else "", list)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun querySideloadProviders(): List<AppInfo> {
|
||||
val apps = packageManager.getInstalledPackages(PackageManager.GET_META_DATA)
|
||||
.filter {
|
||||
it.applicationInfo.metaData?.containsKey(Metadata.GEOIP_FILE_NAME)
|
||||
?: false
|
||||
}
|
||||
.map { it.toAppInfo(packageManager) }
|
||||
|
||||
return listOf(
|
||||
AppInfo(
|
||||
packageName = "",
|
||||
label = getString(R.string.use_built_in),
|
||||
icon = getDrawableCompat(R.drawable.ic_baseline_work)!!,
|
||||
installTime = 0,
|
||||
updateDate = 0,
|
||||
)
|
||||
) + apps
|
||||
}
|
||||
}
|
||||
@@ -1,24 +1,14 @@
|
||||
package com.github.kr328.clash
|
||||
|
||||
import android.content.BroadcastReceiver
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.content.IntentFilter
|
||||
import com.github.kr328.clash.common.util.intent
|
||||
import com.github.kr328.clash.common.util.setUUID
|
||||
import com.github.kr328.clash.common.util.ticker
|
||||
import com.github.kr328.clash.design.ProfilesDesign
|
||||
import com.github.kr328.clash.design.ui.ToastDuration
|
||||
import com.github.kr328.clash.service.model.Profile
|
||||
import com.github.kr328.clash.util.withProfile
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.isActive
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.selects.select
|
||||
import kotlinx.coroutines.withContext
|
||||
import java.util.*
|
||||
import java.util.concurrent.TimeUnit
|
||||
import com.github.kr328.clash.design.R
|
||||
|
||||
class ProfilesActivity : BaseActivity<ProfilesDesign>() {
|
||||
override suspend fun main() {
|
||||
@@ -44,16 +34,9 @@ class ProfilesActivity : BaseActivity<ProfilesDesign>() {
|
||||
startActivity(NewProfileActivity::class.intent)
|
||||
ProfilesDesign.Request.UpdateAll ->
|
||||
withProfile {
|
||||
try {
|
||||
queryAll().forEach { p ->
|
||||
if (p.imported && p.type != Profile.Type.File)
|
||||
update(p.uuid)
|
||||
}
|
||||
}
|
||||
finally {
|
||||
withContext(Dispatchers.Main) {
|
||||
design.finishUpdateAll();
|
||||
}
|
||||
queryAll().forEach { p ->
|
||||
if (p.imported && p.type != Profile.Type.File)
|
||||
update(p.uuid)
|
||||
}
|
||||
}
|
||||
is ProfilesDesign.Request.Update ->
|
||||
@@ -91,37 +74,4 @@ class ProfilesActivity : BaseActivity<ProfilesDesign>() {
|
||||
patchProfiles(queryAll())
|
||||
}
|
||||
}
|
||||
|
||||
override fun onProfileUpdateCompleted(uuid: UUID?) {
|
||||
if(uuid == null)
|
||||
return;
|
||||
launch {
|
||||
var name: String? = null;
|
||||
withProfile {
|
||||
name = queryByUUID(uuid)?.name
|
||||
}
|
||||
design?.showToast(
|
||||
getString(R.string.toast_profile_updated_complete, name),
|
||||
ToastDuration.Long
|
||||
)
|
||||
}
|
||||
}
|
||||
override fun onProfileUpdateFailed(uuid: UUID?, reason: String?) {
|
||||
if(uuid == null)
|
||||
return;
|
||||
launch {
|
||||
var name: String? = null;
|
||||
withProfile {
|
||||
name = queryByUUID(uuid)?.name
|
||||
}
|
||||
design?.showToast(
|
||||
getString(R.string.toast_profile_updated_failed, name, reason),
|
||||
ToastDuration.Long
|
||||
){
|
||||
setAction(R.string.edit) {
|
||||
startActivity(PropertiesActivity::class.intent.setUUID(uuid))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -12,11 +12,9 @@ import kotlinx.coroutines.coroutineScope
|
||||
import kotlinx.coroutines.isActive
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.selects.select
|
||||
import com.github.kr328.clash.design.R
|
||||
|
||||
class PropertiesActivity : BaseActivity<PropertiesDesign>() {
|
||||
private var canceled: Boolean = false
|
||||
private lateinit var original: Profile
|
||||
|
||||
override suspend fun main() {
|
||||
setResult(RESULT_CANCELED)
|
||||
@@ -24,7 +22,7 @@ class PropertiesActivity : BaseActivity<PropertiesDesign>() {
|
||||
val uuid = intent.uuid ?: return finish()
|
||||
val design = PropertiesDesign(this)
|
||||
|
||||
original = withProfile { queryByUUID(uuid) } ?: return finish()
|
||||
val original = withProfile { queryByUUID(uuid) } ?: return finish()
|
||||
|
||||
design.profile = original
|
||||
|
||||
@@ -73,7 +71,7 @@ class PropertiesActivity : BaseActivity<PropertiesDesign>() {
|
||||
design?.apply {
|
||||
launch {
|
||||
if (!progressing) {
|
||||
if (original == profile || requestExitWithoutSaving())
|
||||
if (requestExitWithoutSaving())
|
||||
finish()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,7 +9,6 @@ import kotlinx.coroutines.isActive
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.selects.select
|
||||
import java.util.concurrent.TimeUnit
|
||||
import com.github.kr328.clash.design.R
|
||||
|
||||
class ProvidersActivity : BaseActivity<ProvidersDesign>() {
|
||||
override suspend fun main() {
|
||||
|
||||
@@ -5,12 +5,15 @@ import com.github.kr328.clash.core.Clash
|
||||
import com.github.kr328.clash.core.model.Proxy
|
||||
import com.github.kr328.clash.design.ProxyDesign
|
||||
import com.github.kr328.clash.design.model.ProxyState
|
||||
import com.github.kr328.clash.store.TipsStore
|
||||
import com.github.kr328.clash.util.withClash
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.isActive
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.selects.select
|
||||
import kotlinx.coroutines.sync.Semaphore
|
||||
import kotlinx.coroutines.sync.withPermit
|
||||
import java.util.concurrent.TimeUnit
|
||||
|
||||
class ProxyActivity : BaseActivity<ProxyDesign>() {
|
||||
override suspend fun main() {
|
||||
@@ -19,6 +22,7 @@ class ProxyActivity : BaseActivity<ProxyDesign>() {
|
||||
val states = List(names.size) { ProxyState("?") }
|
||||
val unorderedStates = names.indices.map { names[it] to states[it] }.toMap()
|
||||
val reloadLock = Semaphore(10)
|
||||
val tips = TipsStore(this)
|
||||
|
||||
val design = ProxyDesign(
|
||||
this,
|
||||
@@ -29,6 +33,17 @@ class ProxyActivity : BaseActivity<ProxyDesign>() {
|
||||
|
||||
setContentDesign(design)
|
||||
|
||||
launch(Dispatchers.IO) {
|
||||
val pkg = packageManager.getPackageInfo(packageName, 0)
|
||||
val validate = System.currentTimeMillis() - pkg.firstInstallTime > TimeUnit.DAYS.toMillis(5)
|
||||
|
||||
if (tips.requestDonate && validate) {
|
||||
tips.requestDonate = false
|
||||
|
||||
design.requestDonate()
|
||||
}
|
||||
}
|
||||
|
||||
design.requests.send(ProxyDesign.Request.ReloadAll)
|
||||
|
||||
while (isActive) {
|
||||
|
||||
@@ -24,8 +24,6 @@ class SettingsActivity : BaseActivity<SettingsDesign>() {
|
||||
startActivity(NetworkSettingsActivity::class.intent)
|
||||
SettingsDesign.Request.StartOverride ->
|
||||
startActivity(OverrideSettingsActivity::class.intent)
|
||||
SettingsDesign.Request.StartMetaFeature ->
|
||||
startActivity(MetaFeatureSettingsActivity::class.intent)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,13 +9,11 @@ import android.os.Build
|
||||
import android.service.quicksettings.Tile
|
||||
import android.service.quicksettings.TileService
|
||||
import androidx.annotation.RequiresApi
|
||||
import com.github.kr328.clash.common.compat.registerReceiverCompat
|
||||
import com.github.kr328.clash.common.constants.Intents
|
||||
import com.github.kr328.clash.common.constants.Permissions
|
||||
import com.github.kr328.clash.remote.StatusClient
|
||||
import com.github.kr328.clash.util.startClashService
|
||||
import com.github.kr328.clash.util.stopClashService
|
||||
import com.github.kr328.clash.service.R
|
||||
|
||||
@RequiresApi(Build.VERSION_CODES.N)
|
||||
class TileService : TileService() {
|
||||
@@ -38,7 +36,7 @@ class TileService : TileService() {
|
||||
override fun onStartListening() {
|
||||
super.onStartListening()
|
||||
|
||||
registerReceiverCompat(
|
||||
registerReceiver(
|
||||
receiver,
|
||||
IntentFilter().apply {
|
||||
addAction(Intents.ACTION_CLASH_STARTED)
|
||||
|
||||
@@ -16,28 +16,16 @@ class LogcatReader(context: Context, file: LogFile) : AutoCloseable {
|
||||
}
|
||||
|
||||
fun readAll(): List<LogMessage> {
|
||||
var lastTime = Date(0)
|
||||
return reader.lineSequence()
|
||||
.map { it.trim() }
|
||||
.filter { !it.startsWith("#") }
|
||||
.map { it.split(":", limit = 3) }
|
||||
.map {
|
||||
val time = it[0].toLongOrNull()?.let { Date(it) } ?: lastTime
|
||||
val logMessage = if (it[0].toLongOrNull() != null) {
|
||||
LogMessage(
|
||||
time = time,
|
||||
level = LogMessage.Level.valueOf(it[1]),
|
||||
message = it[2]
|
||||
)
|
||||
} else {
|
||||
LogMessage(
|
||||
time = time,
|
||||
level = LogMessage.Level.Warning, // or any default level
|
||||
message = it.joinToString(":")
|
||||
)
|
||||
}
|
||||
lastTime = time
|
||||
logMessage
|
||||
LogMessage(
|
||||
time = Date(it[0].toLong()),
|
||||
level = LogMessage.Level.valueOf(it[1]),
|
||||
message = it[2]
|
||||
)
|
||||
}
|
||||
.toList()
|
||||
}
|
||||
|
||||
@@ -8,7 +8,7 @@ object SystemLogcat {
|
||||
"Go",
|
||||
"DEBUG",
|
||||
"AndroidRuntime",
|
||||
"ClashMetaForAndroid",
|
||||
"ClashForAndroid",
|
||||
"LwIP",
|
||||
)
|
||||
|
||||
|
||||
@@ -5,10 +5,8 @@ import android.content.BroadcastReceiver
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.content.IntentFilter
|
||||
import com.github.kr328.clash.common.compat.registerReceiverCompat
|
||||
import com.github.kr328.clash.common.constants.Intents
|
||||
import com.github.kr328.clash.common.log.Log
|
||||
import java.util.*
|
||||
|
||||
class Broadcasts(private val context: Application) {
|
||||
interface Observer {
|
||||
@@ -16,8 +14,6 @@ class Broadcasts(private val context: Application) {
|
||||
fun onStarted()
|
||||
fun onStopped(cause: String?)
|
||||
fun onProfileChanged()
|
||||
fun onProfileUpdateCompleted(uuid: UUID?)
|
||||
fun onProfileUpdateFailed(uuid: UUID?, reason: String?)
|
||||
fun onProfileLoaded()
|
||||
}
|
||||
|
||||
@@ -56,17 +52,6 @@ class Broadcasts(private val context: Application) {
|
||||
receivers.forEach {
|
||||
it.onProfileChanged()
|
||||
}
|
||||
Intents.ACTION_PROFILE_UPDATE_COMPLETED ->
|
||||
receivers.forEach {
|
||||
it.onProfileUpdateCompleted(
|
||||
UUID.fromString(intent.getStringExtra(Intents.EXTRA_UUID)))
|
||||
}
|
||||
Intents.ACTION_PROFILE_UPDATE_FAILED ->
|
||||
receivers.forEach {
|
||||
it.onProfileUpdateFailed(
|
||||
UUID.fromString(intent.getStringExtra(Intents.EXTRA_UUID)),
|
||||
intent.getStringExtra(Intents.EXTRA_FAIL_REASON))
|
||||
}
|
||||
Intents.ACTION_PROFILE_LOADED -> {
|
||||
receivers.forEach {
|
||||
it.onProfileLoaded()
|
||||
@@ -89,13 +74,11 @@ class Broadcasts(private val context: Application) {
|
||||
return
|
||||
|
||||
try {
|
||||
context.registerReceiverCompat(broadcastReceiver, IntentFilter().apply {
|
||||
context.registerReceiver(broadcastReceiver, IntentFilter().apply {
|
||||
addAction(Intents.ACTION_SERVICE_RECREATED)
|
||||
addAction(Intents.ACTION_CLASH_STARTED)
|
||||
addAction(Intents.ACTION_CLASH_STOPPED)
|
||||
addAction(Intents.ACTION_PROFILE_CHANGED)
|
||||
addAction(Intents.ACTION_PROFILE_UPDATE_COMPLETED)
|
||||
addAction(Intents.ACTION_PROFILE_UPDATE_FAILED)
|
||||
addAction(Intents.ACTION_PROFILE_LOADED)
|
||||
})
|
||||
|
||||
|
||||
@@ -5,7 +5,6 @@ import android.content.Intent
|
||||
import com.github.kr328.clash.ApkBrokenActivity
|
||||
import com.github.kr328.clash.AppCrashedActivity
|
||||
import com.github.kr328.clash.common.Global
|
||||
import com.github.kr328.clash.common.log.Log
|
||||
import com.github.kr328.clash.common.util.intent
|
||||
import com.github.kr328.clash.store.AppStore
|
||||
import com.github.kr328.clash.util.ApplicationObserver
|
||||
@@ -30,25 +29,14 @@ object Remote {
|
||||
fun launch() {
|
||||
ApplicationObserver.attach(Global.application)
|
||||
|
||||
ApplicationObserver.onVisibleChanged {
|
||||
if(it) {
|
||||
Log.d("App becomes visible")
|
||||
service.bind()
|
||||
broadcasts.register()
|
||||
}
|
||||
else {
|
||||
Log.d("App becomes invisible")
|
||||
service.unbind()
|
||||
broadcasts.unregister()
|
||||
}
|
||||
}
|
||||
ApplicationObserver.onVisibleChanged { visible.trySend(it) }
|
||||
|
||||
Global.launch(Dispatchers.IO) {
|
||||
verifyApp()
|
||||
run()
|
||||
}
|
||||
}
|
||||
|
||||
private suspend fun verifyApp() {
|
||||
private suspend fun run() {
|
||||
val context = Global.application
|
||||
val store = AppStore(context)
|
||||
val updatedAt = getLastUpdated(context)
|
||||
@@ -65,6 +53,16 @@ object Remote {
|
||||
store.updatedAt = updatedAt
|
||||
}
|
||||
}
|
||||
|
||||
while (true) {
|
||||
if (visible.receive()) {
|
||||
service.bind()
|
||||
broadcasts.register()
|
||||
} else {
|
||||
service.unbind()
|
||||
broadcasts.unregister()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun getLastUpdated(context: Context): Long {
|
||||
|
||||
@@ -5,8 +5,10 @@ import android.content.ComponentName
|
||||
import android.content.Context
|
||||
import android.content.ServiceConnection
|
||||
import android.os.IBinder
|
||||
import com.github.kr328.clash.Tracker
|
||||
import com.github.kr328.clash.common.log.Log
|
||||
import com.github.kr328.clash.common.util.intent
|
||||
import com.github.kr328.clash.log.SystemLogcat
|
||||
import com.github.kr328.clash.service.RemoteService
|
||||
import com.github.kr328.clash.service.remote.IRemoteService
|
||||
import com.github.kr328.clash.service.remote.unwrap
|
||||
@@ -26,6 +28,8 @@ class Service(private val context: Application, val crashed: () -> Unit) {
|
||||
override fun onServiceDisconnected(name: ComponentName?) {
|
||||
remote.set(null)
|
||||
|
||||
Tracker.uploadLogcat(SystemLogcat.dumpCrash())
|
||||
|
||||
if (System.currentTimeMillis() - lastCrashed < TOGGLE_CRASHED_INTERVAL) {
|
||||
unbind()
|
||||
|
||||
@@ -33,7 +37,8 @@ class Service(private val context: Application, val crashed: () -> Unit) {
|
||||
}
|
||||
|
||||
lastCrashed = System.currentTimeMillis()
|
||||
Log.w("RemoteService killed or crashed")
|
||||
|
||||
Log.w("RemoteManager crashed")
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -7,12 +7,16 @@ import kotlinx.coroutines.NonCancellable
|
||||
import kotlinx.coroutines.withContext
|
||||
|
||||
class ActivityResultLifecycle : LifecycleOwner {
|
||||
override val lifecycle = LifecycleRegistry(this)
|
||||
private val lifecycle = LifecycleRegistry(this)
|
||||
|
||||
init {
|
||||
lifecycle.currentState = Lifecycle.State.INITIALIZED
|
||||
}
|
||||
|
||||
override fun getLifecycle(): Lifecycle {
|
||||
return lifecycle
|
||||
}
|
||||
|
||||
suspend fun <T> use(block: suspend (lifecycle: ActivityResultLifecycle, start: () -> Unit) -> T): T {
|
||||
return try {
|
||||
markCreated()
|
||||
|
||||
@@ -9,8 +9,7 @@ import java.io.File
|
||||
import java.util.zip.ZipFile
|
||||
|
||||
object ApplicationObserver {
|
||||
private val _createdActivities: MutableSet<Activity> = mutableSetOf()
|
||||
private val _visibleActivities: MutableSet<Activity> = mutableSetOf()
|
||||
private val activities: MutableSet<Activity> = mutableSetOf()
|
||||
|
||||
private var visibleChanged: (Boolean) -> Unit = {}
|
||||
|
||||
@@ -24,31 +23,25 @@ object ApplicationObserver {
|
||||
}
|
||||
|
||||
val createdActivities: Set<Activity>
|
||||
get() = _createdActivities
|
||||
get() = activities
|
||||
|
||||
private val activityObserver = object : Application.ActivityLifecycleCallbacks {
|
||||
@Synchronized
|
||||
override fun onActivityCreated(activity: Activity, savedInstanceState: Bundle?) {
|
||||
_createdActivities.add(activity)
|
||||
activities.add(activity)
|
||||
|
||||
appVisible = true
|
||||
}
|
||||
|
||||
@Synchronized
|
||||
override fun onActivityDestroyed(activity: Activity) {
|
||||
_createdActivities.remove(activity)
|
||||
_visibleActivities.remove(activity)
|
||||
appVisible = _visibleActivities.isNotEmpty()
|
||||
}
|
||||
|
||||
override fun onActivityStarted(activity: Activity) {
|
||||
_visibleActivities.add(activity)
|
||||
appVisible = true
|
||||
}
|
||||
|
||||
override fun onActivityStopped(activity: Activity) {
|
||||
_visibleActivities.remove(activity)
|
||||
appVisible = _visibleActivities.isNotEmpty()
|
||||
activities.remove(activity)
|
||||
|
||||
appVisible = activities.isNotEmpty()
|
||||
}
|
||||
|
||||
override fun onActivityStarted(activity: Activity) {}
|
||||
override fun onActivityStopped(activity: Activity) {}
|
||||
override fun onActivityPaused(activity: Activity) {}
|
||||
override fun onActivityResumed(activity: Activity) {}
|
||||
override fun onActivitySaveInstanceState(activity: Activity, outState: Bundle) {}
|
||||
|
||||
@@ -4,7 +4,4 @@ import android.content.Context
|
||||
import java.io.File
|
||||
|
||||
val Context.logsDir: File
|
||||
get() = cacheDir.resolve("logs")
|
||||
|
||||
val Context.clashDir: File
|
||||
get() = filesDir.resolve("clash")
|
||||
get() = cacheDir.resolve("logs")
|
||||
@@ -2,15 +2,19 @@
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:width="108dp"
|
||||
android:height="108dp"
|
||||
android:viewportWidth="403"
|
||||
android:viewportHeight="403"
|
||||
android:name="vector">
|
||||
<group>
|
||||
android:viewportWidth="406.92642"
|
||||
android:viewportHeight="406.92642">
|
||||
<group
|
||||
android:translateX="103.4632"
|
||||
android:translateY="103.4632">
|
||||
<path
|
||||
android:pathData="M 141.08 128.47 C 141.88 128.42 142.72 128.38 143.41 128.8 C 144.51 129.46 145.39 130.41 146.33 131.25 C 160.38 144.1 174.48 156.9 188.53 169.75 C 189.48 170.59 190.37 171.56 191.54 172.11 C 192.45 172.55 193.49 172.33 194.46 172.2 C 197.04 171.76 199.66 171.74 202.26 171.74 C 204.77 171.78 207.29 171.86 209.77 172.27 C 210.77 172.38 211.95 172.71 212.71 171.84 C 228.19 157.7 243.73 143.58 259.23 129.43 C 260.54 128.06 262.55 128.36 264.26 128.57 C 268.58 129.21 272.94 129.51 277.28 130 C 278 130.14 279.02 130.19 279.27 131.05 C 279.61 132.54 279.42 134.07 279.46 135.58 C 279.44 166.17 279.44 196.77 279.42 227.36 C 279.41 228.92 279.51 230.47 279.35 232.01 C 279.29 232.56 279.22 233.21 278.76 233.59 C 277.8 234.01 276.74 234.17 275.72 234.42 C 271.39 235.43 266.98 236.16 262.66 237.26 C 260.49 237.83 258.25 237.61 256.04 237.64 C 254.91 237.63 253.74 237.73 252.61 237.54 C 251.95 237.49 251.48 236.9 251.43 236.26 C 251.19 234.74 251.33 233.2 251.31 231.67 C 251.29 216.61 251.28 201.54 251.29 186.48 C 251.27 185 251.38 183.49 251.17 182.01 C 250.9 180.3 249.11 179.1 247.44 179.31 C 246.51 179.32 245.72 179.9 245.05 180.49 C 237.57 187.38 230 194.15 222.54 201.02 C 221.68 201.76 220.7 202.63 219.48 202.51 C 217.88 202.37 216.37 201.8 214.82 201.44 C 208.61 199.89 202.12 199.7 195.77 200.24 C 192.68 200.67 189.56 201.02 186.59 202 C 185.63 202.27 184.66 202.57 183.67 202.52 C 182.65 202.45 181.86 201.78 181.14 201.15 C 173.72 194.33 166.23 187.63 158.81 180.81 C 158.09 180.18 157.31 179.49 156.33 179.34 C 155.1 179.19 153.83 179.69 152.99 180.59 C 152.26 181.42 152.23 182.56 152.19 183.61 C 152.23 200.72 152.18 217.81 152.21 234.91 C 152.18 235.57 152.18 236.24 151.92 236.87 C 151.53 237.58 150.62 237.61 149.91 237.64 C 147.99 237.68 146.08 237.63 144.16 237.64 C 141.99 237.68 139.9 237.05 137.81 236.62 C 133.97 235.77 130.14 234.91 126.29 234.1 C 125.48 233.9 124.35 233.66 124.2 232.66 C 123.96 230.91 124.13 229.14 124.1 227.36 C 124.06 196.88 124.08 166.41 124.08 135.93 C 124.08 134.49 124 133.06 124.13 131.64 C 124.18 131.12 124.33 130.51 124.84 130.24 C 125.38 130 125.99 129.97 126.56 129.88 C 131.42 129.55 136.25 128.96 141.08 128.47 Z M 198.81 240.82 C 200.99 240.64 203.19 240.7 205.35 240.82 C 207.04 240.8 208.08 242.85 207.31 244.28 C 206.36 246.17 205.38 248.03 204.27 249.84 C 203.56 251.14 201.5 251.39 200.57 250.19 C 199.67 249.09 199.15 247.78 198.44 246.56 C 197.9 245.55 197.21 244.59 196.96 243.44 C 196.7 242.24 197.62 240.99 198.81 240.82 Z"
|
||||
android:fillColor="#3372b6"/>
|
||||
<path
|
||||
android:pathData="M 125.67 244.75 C 126.09 244.7 126.51 244.67 126.95 244.67 C 139.02 244.7 151.09 244.69 163.19 244.69 C 164.26 244.67 165.5 244.94 166.14 245.92 C 166.8 247.02 166.66 248.72 165.52 249.45 C 164.74 249.99 163.74 249.99 162.83 250.02 C 150.88 249.99 138.9 250.01 126.95 250.02 C 126.28 249.99 125.6 249.99 124.97 249.77 C 123.94 249.38 123.25 248.25 123.4 247.15 C 123.49 245.97 124.43 244.86 125.67 244.76 L 125.67 244.75 Z M 239.67 244.75 C 241.29 244.59 242.93 244.72 244.57 244.69 C 255.33 244.67 266.1 244.72 276.86 244.67 C 277.55 244.7 278.27 244.69 278.92 244.97 C 279.88 245.4 280.42 246.44 280.42 247.47 C 280.44 248.67 279.44 249.8 278.24 249.92 C 276.7 250.11 275.15 249.99 273.61 250 L 243.85 250 C 242.33 249.99 240.79 250.12 239.29 249.87 C 238.15 249.67 237.23 248.64 237.31 247.46 C 237.16 246.07 238.34 244.85 239.67 244.75 Z M 162.61 257.67 C 163.41 257.45 164.3 257.33 165.06 257.72 C 166.65 258.45 167.02 260.98 165.6 262.08 C 164.76 262.67 163.74 262.91 162.8 263.24 C 159.22 264.36 155.74 265.76 152.16 266.87 C 148.04 268.17 144 269.71 139.9 271.09 C 136.91 272.06 133.94 273.07 130.97 274.1 C 129.73 274.52 128.54 275.06 127.27 275.33 C 126.49 275.5 125.63 275.35 125.02 274.83 C 124.01 274.03 123.82 272.5 124.4 271.4 C 124.87 270.6 125.82 270.32 126.63 270 C 129.2 269.1 131.73 268.17 134.31 267.36 C 140.78 265.27 147.14 262.84 153.63 260.8 C 156.65 259.81 159.59 258.62 162.61 257.67 Z M 239.3 257.54 C 240.23 257.32 241.14 257.67 242.02 257.92 C 244.84 258.89 247.61 259.97 250.45 260.88 C 257.12 262.99 263.65 265.51 270.34 267.62 C 272.53 268.33 274.71 269.14 276.91 269.9 C 277.73 270.22 278.64 270.49 279.25 271.18 C 280.21 272.5 279.64 274.64 278.1 275.23 C 277.11 275.62 276.06 275.23 275.1 274.93 C 271.13 273.46 267.11 272.14 263.09 270.83 C 259.18 269.47 255.29 268.04 251.36 266.79 C 247.78 265.66 244.32 264.26 240.74 263.16 C 239.79 262.82 238.78 262.59 238.02 261.91 C 236.65 260.58 237.39 257.88 239.3 257.54 Z"
|
||||
android:fillColor="#f39800"/>
|
||||
android:fillColor="#1E4376"
|
||||
android:pathData="M37.7,168.1C61.1-35,58,13.8,84.6,43.8c13.5-1.5,27.2-3.5,40.8-0.7c2.6,0.1,5.4,1.9,7.7,0.2
|
||||
c4.1-6.3,7.4-13.5,11.4-20c12.2-24.4,12.8,19.5,15.5,26.5c5.2,33,10.9,64.5,14.7,97.6c0.3,10.7,5.7,32.9,1.1,33.6
|
||||
c-49.4,5.2-147.7,3.9-160.8-6.3c-15.8-10.5-15.2-35.3,2-43.7c3.6-2,10.7-3.7,11.9,0.7c-2.4,5-8.8,5.8-12.1,11.2
|
||||
C7.2,158.9,23.6,168.9,37.7,168.1z M78.4,74c-10.4,0.5-9.6,14.9-0.1,15.2C88.7,88.7,87.9,74.3,78.4,74z M139.7,89.2
|
||||
c10.5-0.3,9.8-14.7,0.4-15.2C129.6,74.3,130.2,88.7,139.7,89.2z M98.4,99.2c2.2,3.5,5.3,3.3,9.8,0.2c3.8,3.2,8.1,3.3,9.2-0.2
|
||||
c-3.8,1.2-7,0.8-9.4-3.5C105.9,100.1,102.6,100.4,98.4,99.2z"
|
||||
tools:ignore="VectorPath" />
|
||||
</group>
|
||||
</vector>
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<background android:drawable="@color/ic_launcher_background"/>
|
||||
<foreground android:drawable="@drawable/ic_launcher_foreground"/>
|
||||
<monochrome android:drawable="@drawable/ic_launcher_foreground" />
|
||||
<background android:drawable="@color/color_launcher_background" />
|
||||
<foreground android:drawable="@drawable/ic_launcher_foreground" />
|
||||
</adaptive-icon>
|
||||
@@ -1,6 +1,5 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<background android:drawable="@color/ic_launcher_background"/>
|
||||
<foreground android:drawable="@drawable/ic_launcher_foreground"/>
|
||||
<monochrome android:drawable="@drawable/ic_launcher_foreground" />
|
||||
<background android:drawable="@color/color_launcher_background" />
|
||||
<foreground android:drawable="@drawable/ic_launcher_foreground" />
|
||||
</adaptive-icon>
|
||||
|
Before Width: | Height: | Size: 1.6 KiB After Width: | Height: | Size: 1.7 KiB |
|
Before Width: | Height: | Size: 3.6 KiB After Width: | Height: | Size: 3.5 KiB |
|
Before Width: | Height: | Size: 1.1 KiB After Width: | Height: | Size: 1.2 KiB |
|
Before Width: | Height: | Size: 2.3 KiB After Width: | Height: | Size: 2.3 KiB |
|
Before Width: | Height: | Size: 3.3 KiB After Width: | Height: | Size: 6.2 KiB |
|
Before Width: | Height: | Size: 2.2 KiB After Width: | Height: | Size: 2.4 KiB |
|
Before Width: | Height: | Size: 5.1 KiB After Width: | Height: | Size: 5.0 KiB |
|
Before Width: | Height: | Size: 3.5 KiB After Width: | Height: | Size: 3.6 KiB |
|
Before Width: | Height: | Size: 8.2 KiB After Width: | Height: | Size: 7.8 KiB |
|
Before Width: | Height: | Size: 4.9 KiB After Width: | Height: | Size: 5.0 KiB |
|
Before Width: | Height: | Size: 12 KiB After Width: | Height: | Size: 11 KiB |
@@ -1,4 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<color name="ic_banner_background">#FFFFFF</color>
|
||||
</resources>
|
||||
@@ -1,4 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<color name="ic_launcher_background">#FFFFFF</color>
|
||||
</resources>
|
||||
31
app/src/premium/java/com/github/kr328/clash/Tracker.kt
Normal file
@@ -0,0 +1,31 @@
|
||||
package com.github.kr328.clash
|
||||
|
||||
import android.app.Application
|
||||
import com.microsoft.appcenter.AppCenter
|
||||
import com.microsoft.appcenter.analytics.Analytics
|
||||
import com.microsoft.appcenter.crashes.Crashes
|
||||
import com.microsoft.appcenter.crashes.ingestion.models.ErrorAttachmentLog
|
||||
|
||||
object Tracker {
|
||||
fun initialize(application: Application) {
|
||||
if (!BuildConfig.DEBUG) {
|
||||
AppCenter.start(
|
||||
application,
|
||||
BuildConfig.APP_CENTER_KEY,
|
||||
Analytics::class.java, Crashes::class.java
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
fun uploadLogcat(logcat: String) {
|
||||
if (!BuildConfig.DEBUG) {
|
||||
if (logcat.isNotBlank()) {
|
||||
Crashes.trackError(
|
||||
RuntimeException(),
|
||||
mapOf("type" to "app_crashed"),
|
||||
listOf(ErrorAttachmentLog.attachmentWithText(logcat, "logcat.txt"))
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
135
build.gradle.kts
@@ -9,65 +9,45 @@ buildscript {
|
||||
repositories {
|
||||
mavenCentral()
|
||||
google()
|
||||
maven("https://raw.githubusercontent.com/MetaCubeX/maven-backup/main/releases")
|
||||
maven("https://maven.kr328.app/releases")
|
||||
}
|
||||
dependencies {
|
||||
classpath(libs.build.android)
|
||||
classpath(libs.build.kotlin.common)
|
||||
classpath(libs.build.kotlin.serialization)
|
||||
classpath(libs.build.ksp)
|
||||
classpath(libs.build.golang)
|
||||
classpath(deps.build.android)
|
||||
classpath(deps.build.kotlin.common)
|
||||
classpath(deps.build.kotlin.serialization)
|
||||
classpath(deps.build.ksp)
|
||||
classpath(deps.build.golang)
|
||||
}
|
||||
}
|
||||
|
||||
allprojects {
|
||||
repositories {
|
||||
mavenCentral()
|
||||
google()
|
||||
maven("https://maven.kr328.app/releases")
|
||||
}
|
||||
}
|
||||
|
||||
subprojects {
|
||||
repositories {
|
||||
mavenCentral()
|
||||
google()
|
||||
maven("https://raw.githubusercontent.com/MetaCubeX/maven-backup/main/releases")
|
||||
}
|
||||
|
||||
val isApp = name == "app"
|
||||
|
||||
apply(plugin = if (isApp) "com.android.application" else "com.android.library")
|
||||
|
||||
fun queryConfigProperty(key: String): Any? {
|
||||
val localProperties = Properties()
|
||||
val localPropertiesFile = rootProject.file("local.properties")
|
||||
if (localPropertiesFile.exists()) {
|
||||
localProperties.load(localPropertiesFile.inputStream())
|
||||
} else {
|
||||
return null
|
||||
}
|
||||
return localProperties.getProperty(key)
|
||||
}
|
||||
|
||||
extensions.configure<BaseExtension> {
|
||||
buildFeatures.buildConfig = true
|
||||
defaultConfig {
|
||||
if (isApp) {
|
||||
val customApplicationId = queryConfigProperty("custom.application.id") as? String?
|
||||
applicationId = customApplicationId.takeIf { it?.isNotBlank() == true } ?: "com.github.metacubex.clash"
|
||||
}
|
||||
|
||||
project.name.let { name ->
|
||||
namespace = if (name == "app") "com.github.kr328.clash"
|
||||
else "com.github.kr328.clash.$name"
|
||||
applicationId = "com.github.kr328.clash"
|
||||
}
|
||||
|
||||
minSdk = 21
|
||||
targetSdk = 35
|
||||
targetSdk = 31
|
||||
|
||||
versionName = "2.11.27"
|
||||
versionCode = 211027
|
||||
versionName = "2.5.4"
|
||||
versionCode = 205004
|
||||
|
||||
resValue("string", "release_name", "v$versionName")
|
||||
resValue("integer", "release_code", "$versionCode")
|
||||
|
||||
ndk {
|
||||
abiFilters += listOf("arm64-v8a", "armeabi-v7a", "x86", "x86_64")
|
||||
}
|
||||
|
||||
externalNativeBuild {
|
||||
cmake {
|
||||
abiFilters("arm64-v8a", "armeabi-v7a", "x86", "x86_64")
|
||||
@@ -77,69 +57,52 @@ subprojects {
|
||||
if (!isApp) {
|
||||
consumerProguardFiles("consumer-rules.pro")
|
||||
} else {
|
||||
setProperty("archivesBaseName", "cmfa-$versionName")
|
||||
setProperty("archivesBaseName", "cfa-$versionName")
|
||||
}
|
||||
}
|
||||
|
||||
ndkVersion = "29.0.14206865"
|
||||
ndkVersion = "23.0.7599858"
|
||||
|
||||
compileSdkVersion(defaultConfig.targetSdk!!)
|
||||
|
||||
if (isApp) {
|
||||
packagingOptions {
|
||||
resources {
|
||||
excludes.add("DebugProbesKt.bin")
|
||||
}
|
||||
excludes.add("DebugProbesKt.bin")
|
||||
}
|
||||
}
|
||||
|
||||
productFlavors {
|
||||
flavorDimensions("feature")
|
||||
|
||||
val removeSuffix = (queryConfigProperty("remove.suffix") as? String)?.toBoolean() == true
|
||||
|
||||
create("alpha") {
|
||||
create("foss") {
|
||||
isDefault = true
|
||||
dimension = flavorDimensionList[0]
|
||||
if (!removeSuffix) {
|
||||
versionNameSuffix = ".Alpha"
|
||||
}
|
||||
|
||||
versionNameSuffix = ".foss"
|
||||
|
||||
buildConfigField("boolean", "PREMIUM", "Boolean.parseBoolean(\"false\")")
|
||||
|
||||
resValue("string", "launch_name", "@string/launch_name_alpha")
|
||||
resValue("string", "application_name", "@string/application_name_alpha")
|
||||
|
||||
if (isApp && !removeSuffix) {
|
||||
applicationIdSuffix = ".alpha"
|
||||
if (isApp) {
|
||||
applicationIdSuffix = ".foss"
|
||||
}
|
||||
}
|
||||
|
||||
create("meta") {
|
||||
|
||||
create("premium") {
|
||||
dimension = flavorDimensionList[0]
|
||||
if (!removeSuffix) {
|
||||
versionNameSuffix = ".Meta"
|
||||
versionNameSuffix = ".premium"
|
||||
|
||||
buildConfigField("boolean", "PREMIUM", "Boolean.parseBoolean(\"true\")")
|
||||
|
||||
val tracker = rootProject.file("tracker.properties")
|
||||
if (tracker.exists()) {
|
||||
val prop = Properties().apply {
|
||||
tracker.inputStream().use(this::load)
|
||||
}
|
||||
|
||||
buildConfigField(
|
||||
"String",
|
||||
"APP_CENTER_KEY",
|
||||
"\"${prop.getProperty("appcenter.key")!!}\""
|
||||
)
|
||||
}
|
||||
|
||||
buildConfigField("boolean", "PREMIUM", "Boolean.parseBoolean(\"false\")")
|
||||
|
||||
resValue("string", "launch_name", "@string/launch_name_meta")
|
||||
resValue("string", "application_name", "@string/application_name_meta")
|
||||
|
||||
if (isApp && !removeSuffix) {
|
||||
applicationIdSuffix = ".meta"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
sourceSets {
|
||||
getByName("meta") {
|
||||
java.srcDirs("src/foss/java")
|
||||
}
|
||||
getByName("alpha") {
|
||||
java.srcDirs("src/foss/java")
|
||||
}
|
||||
}
|
||||
|
||||
@@ -151,7 +114,7 @@ subprojects {
|
||||
keystore.inputStream().use(this::load)
|
||||
}
|
||||
|
||||
storeFile = rootProject.file("release.keystore")
|
||||
storeFile = rootProject.file(prop.getProperty("keystore.path")!!)
|
||||
storePassword = prop.getProperty("keystore.password")!!
|
||||
keyAlias = prop.getProperty("key.alias")!!
|
||||
keyPassword = prop.getProperty("key.password")!!
|
||||
@@ -163,7 +126,7 @@ subprojects {
|
||||
named("release") {
|
||||
isMinifyEnabled = isApp
|
||||
isShrinkResources = isApp
|
||||
signingConfig = signingConfigs.findByName("release") ?: signingConfigs["debug"]
|
||||
signingConfig = signingConfigs.findByName("release")
|
||||
proguardFiles(
|
||||
getDefaultProguardFile("proguard-android-optimize.txt"),
|
||||
"proguard-rules.pro"
|
||||
@@ -180,6 +143,11 @@ subprojects {
|
||||
}
|
||||
}
|
||||
|
||||
variantFilter {
|
||||
ignore = name.startsWith("premium") && !project(":core")
|
||||
.file("src/premium/golang/clash/go.mod").exists()
|
||||
}
|
||||
|
||||
if (isApp) {
|
||||
this as AppExtension
|
||||
|
||||
@@ -187,16 +155,9 @@ subprojects {
|
||||
abi {
|
||||
isEnable = true
|
||||
isUniversalApk = true
|
||||
reset()
|
||||
include("arm64-v8a", "armeabi-v7a", "x86", "x86_64")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
compileOptions {
|
||||
sourceCompatibility = JavaVersion.VERSION_21
|
||||
targetCompatibility = JavaVersion.VERSION_21
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -6,6 +6,6 @@ plugins {
|
||||
dependencies {
|
||||
compileOnly(project(":hideapi"))
|
||||
|
||||
implementation(libs.kotlin.coroutine)
|
||||
implementation(libs.androidx.core)
|
||||
implementation(deps.kotlin.coroutine)
|
||||
implementation(deps.androidx.core)
|
||||
}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
package="com.github.kr328.clash.common">
|
||||
|
||||
<permission
|
||||
android:name="${applicationId}.permission.RECEIVE_BROADCASTS"
|
||||
|
||||
@@ -2,13 +2,8 @@
|
||||
|
||||
package com.github.kr328.clash.common.compat
|
||||
|
||||
import android.annotation.SuppressLint
|
||||
import android.content.BroadcastReceiver
|
||||
import android.content.Context
|
||||
import android.content.IntentFilter
|
||||
import android.graphics.drawable.Drawable
|
||||
import android.os.Build
|
||||
import android.os.Handler
|
||||
import androidx.annotation.ColorRes
|
||||
import androidx.annotation.DrawableRes
|
||||
import androidx.core.content.ContextCompat
|
||||
@@ -19,19 +14,4 @@ fun Context.getColorCompat(@ColorRes id: Int): Int {
|
||||
|
||||
fun Context.getDrawableCompat(@DrawableRes id: Int): Drawable? {
|
||||
return ContextCompat.getDrawable(this, id)
|
||||
}
|
||||
|
||||
@SuppressLint("UnspecifiedRegisterReceiverFlag")
|
||||
fun Context.registerReceiverCompat(
|
||||
receiver: BroadcastReceiver,
|
||||
filter: IntentFilter,
|
||||
permission: String? = null,
|
||||
handler: Handler? = null
|
||||
) =
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU)
|
||||
registerReceiver(receiver, filter, permission, handler,
|
||||
if (permission == null) Context.RECEIVER_EXPORTED else Context.RECEIVER_NOT_EXPORTED
|
||||
)
|
||||
else
|
||||
registerReceiver(receiver, filter, permission, handler)
|
||||
|
||||
}
|
||||
@@ -1,10 +1,7 @@
|
||||
package com.github.kr328.clash.common.compat
|
||||
|
||||
import android.app.Notification
|
||||
import android.app.Service
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.content.pm.ServiceInfo
|
||||
import android.os.Build
|
||||
|
||||
fun Context.startForegroundServiceCompat(intent: Intent) {
|
||||
@@ -13,12 +10,4 @@ fun Context.startForegroundServiceCompat(intent: Intent) {
|
||||
} else {
|
||||
startService(intent)
|
||||
}
|
||||
}
|
||||
|
||||
fun Service.startForegroundCompat(id: Int, notification: Notification) {
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.UPSIDE_DOWN_CAKE) {
|
||||
startForeground(id, notification, ServiceInfo.FOREGROUND_SERVICE_TYPE_SPECIAL_USE)
|
||||
} else {
|
||||
startForeground(id, notification)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -5,9 +5,6 @@ import com.github.kr328.clash.common.util.packageName
|
||||
object Intents {
|
||||
// Public
|
||||
val ACTION_PROVIDE_URL = "$packageName.action.PROVIDE_URL"
|
||||
val ACTION_START_CLASH = "$packageName.action.START_CLASH"
|
||||
val ACTION_STOP_CLASH = "$packageName.action.STOP_CLASH"
|
||||
val ACTION_TOGGLE_CLASH = "$packageName.action.TOGGLE_CLASH"
|
||||
|
||||
const val EXTRA_NAME = "name"
|
||||
|
||||
@@ -17,8 +14,6 @@ object Intents {
|
||||
val ACTION_CLASH_STOPPED = "$packageName.intent.action.CLASH_STOPPED"
|
||||
val ACTION_CLASH_REQUEST_STOP = "$packageName.intent.action.CLASH_REQUEST_STOP"
|
||||
val ACTION_PROFILE_CHANGED = "$packageName.intent.action.PROFILE_CHANGED"
|
||||
val ACTION_PROFILE_UPDATE_COMPLETED = "$packageName.intent.action.PROFILE_UPDATE_COMPLETED"
|
||||
val ACTION_PROFILE_UPDATE_FAILED = "$packageName.intent.action.PROFILE_UPDATE_FAILED"
|
||||
val ACTION_PROFILE_REQUEST_UPDATE = "$packageName.intent.action.REQUEST_UPDATE"
|
||||
val ACTION_PROFILE_SCHEDULE_UPDATES = "$packageName.intent.action.SCHEDULE_UPDATES"
|
||||
val ACTION_PROFILE_LOADED = "$packageName.intent.action.PROFILE_LOADED"
|
||||
@@ -26,5 +21,4 @@ object Intents {
|
||||
|
||||
const val EXTRA_STOP_REASON = "stop_reason"
|
||||
const val EXTRA_UUID = "uuid"
|
||||
const val EXTRA_FAIL_REASON = "fail_reason"
|
||||
}
|
||||
@@ -1,7 +1,7 @@
|
||||
package com.github.kr328.clash.common.log
|
||||
|
||||
object Log {
|
||||
private const val TAG = "ClashMetaForAndroid"
|
||||
private const val TAG = "ClashForAndroid"
|
||||
|
||||
fun i(message: String, throwable: Throwable? = null) =
|
||||
android.util.Log.i(TAG, message, throwable)
|
||||
|
||||
@@ -1,5 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<string name="receive_clash_broadcasts">Получать оповещения от Clash</string>
|
||||
<string name="receive_broadcasts_of_clash">Получать оповещения от сервисов Clash</string>
|
||||
</resources>
|
||||
1
core/.gitignore
vendored
@@ -1 +0,0 @@
|
||||
/src/main/cpp/version.h
|
||||
@@ -1,6 +1,8 @@
|
||||
import android.databinding.tool.ext.capitalizeUS
|
||||
import com.github.kr328.golang.GolangBuildTask
|
||||
import com.github.kr328.golang.GolangPlugin
|
||||
import java.io.FileOutputStream
|
||||
import java.net.URL
|
||||
import java.time.Duration
|
||||
|
||||
plugins {
|
||||
kotlin("android")
|
||||
@@ -9,17 +11,21 @@ plugins {
|
||||
id("golang-android")
|
||||
}
|
||||
|
||||
val geoipDatabaseUrl =
|
||||
"https://github.com/Dreamacro/maxmind-geoip/releases/latest/download/Country.mmdb"
|
||||
val geoipInvalidate = Duration.ofDays(7)!!
|
||||
val geoipOutput = buildDir.resolve("intermediates/golang_blob")
|
||||
val golangSource = file("src/main/golang/native")
|
||||
|
||||
golang {
|
||||
sourceSets {
|
||||
create("alpha") {
|
||||
tags.set(listOf("foss","with_gvisor","cmfa"))
|
||||
create("foss") {
|
||||
tags.set(listOf("foss"))
|
||||
srcDir.set(file("src/foss/golang"))
|
||||
}
|
||||
create("meta") {
|
||||
tags.set(listOf("foss","with_gvisor","cmfa"))
|
||||
srcDir.set(file("src/foss/golang"))
|
||||
create("premium") {
|
||||
tags.set(listOf("premium", "without_gvisor", "without_system"))
|
||||
srcDir.set(file("src/premium/golang"))
|
||||
}
|
||||
all {
|
||||
fileName.set("libclash.so")
|
||||
@@ -51,9 +57,9 @@ android {
|
||||
dependencies {
|
||||
implementation(project(":common"))
|
||||
|
||||
implementation(libs.androidx.core)
|
||||
implementation(libs.kotlin.coroutine)
|
||||
implementation(libs.kotlin.serialization.json)
|
||||
implementation(deps.androidx.core)
|
||||
implementation(deps.kotlin.coroutine)
|
||||
implementation(deps.kotlin.serialization.json)
|
||||
}
|
||||
|
||||
afterEvaluate {
|
||||
@@ -62,17 +68,50 @@ afterEvaluate {
|
||||
}
|
||||
}
|
||||
|
||||
val abis = listOf("arm64-v8a" to "Arm64V8a", "armeabi-v7a" to "ArmeabiV7a", "x86" to "X86", "x86_64" to "X8664")
|
||||
task("downloadGeoipDatabase") {
|
||||
val databaseFile = geoipOutput.resolve("Country.mmdb")
|
||||
val moduleFile = geoipOutput.resolve("go.mod")
|
||||
val sourceFile = geoipOutput.resolve("blob.go")
|
||||
|
||||
androidComponents.onVariants { variant ->
|
||||
val cmakeName = if (variant.buildType == "debug") "Debug" else "RelWithDebInfo"
|
||||
val moduleContent = """
|
||||
module "cfa/blob"
|
||||
""".trimIndent()
|
||||
|
||||
abis.forEach { (abi, goAbi) ->
|
||||
tasks.configureEach {
|
||||
if (name.startsWith("buildCMake$cmakeName[$abi]")) {
|
||||
dependsOn("externalGolangBuild${variant.name.capitalizeUS()}$goAbi")
|
||||
println("Set up dependency: $name -> externalGolangBuild${variant.name.capitalizeUS()}$goAbi")
|
||||
val sourceContent = """
|
||||
package blob
|
||||
|
||||
import _ "embed"
|
||||
|
||||
//go:embed Country.mmdb
|
||||
var GeoipDatabase []byte
|
||||
""".trimIndent()
|
||||
|
||||
outputs.dir(geoipOutput)
|
||||
|
||||
onlyIf {
|
||||
System.currentTimeMillis() - databaseFile.lastModified() > geoipInvalidate.toMillis()
|
||||
}
|
||||
|
||||
doLast {
|
||||
geoipOutput.mkdirs()
|
||||
|
||||
moduleFile.writeText(moduleContent)
|
||||
sourceFile.writeText(sourceContent)
|
||||
|
||||
URL(geoipDatabaseUrl).openConnection().getInputStream().use { input ->
|
||||
FileOutputStream(databaseFile).use { output ->
|
||||
input.copyTo(output)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
afterEvaluate {
|
||||
val downloadTask = tasks["downloadGeoipDatabase"]
|
||||
|
||||
tasks.forEach {
|
||||
if (it.name.startsWith("externalGolangBuild")) {
|
||||
it.dependsOn(downloadTask)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,117 +1,40 @@
|
||||
module foss
|
||||
|
||||
go 1.20
|
||||
go 1.17
|
||||
|
||||
require cfa v0.0.0
|
||||
|
||||
require (
|
||||
github.com/RyuaNerin/go-krypto v1.3.0 // indirect
|
||||
github.com/Yawning/aez v0.0.0-20211027044916-e49e68abd344 // indirect
|
||||
github.com/ajg/form v1.5.1 // indirect
|
||||
github.com/andybalholm/brotli v1.0.6 // indirect
|
||||
github.com/bahlo/generic-list-go v0.2.0 // indirect
|
||||
github.com/coreos/go-iptables v0.8.0 // indirect
|
||||
github.com/dlclark/regexp2 v1.12.0 // indirect
|
||||
github.com/dunglas/httpsfv v1.0.2 // indirect
|
||||
github.com/enfein/mieru/v3 v3.31.0 // indirect
|
||||
github.com/ericlagergren/aegis v0.0.0-20250325060835-cd0defd64358 // indirect
|
||||
github.com/ericlagergren/polyval v0.0.0-20220411101811-e25bc10ba391 // indirect
|
||||
github.com/ericlagergren/siv v0.0.0-20220507050439-0b757b3aa5f1 // indirect
|
||||
github.com/ericlagergren/subtle v0.0.0-20220507045147-890d697da010 // indirect
|
||||
github.com/fsnotify/fsnotify v1.9.0 // indirect
|
||||
github.com/gaukas/godicttls v0.0.4 // indirect
|
||||
github.com/go-ole/go-ole v1.3.0 // indirect
|
||||
github.com/gobwas/httphead v0.1.0 // indirect
|
||||
github.com/gobwas/pool v0.2.1 // indirect
|
||||
github.com/gobwas/ws v1.4.0 // indirect
|
||||
github.com/gofrs/uuid/v5 v5.4.0 // indirect
|
||||
github.com/golang/snappy v1.0.0 // indirect
|
||||
github.com/google/btree v1.1.3 // indirect
|
||||
github.com/google/go-cmp v0.6.0 // indirect
|
||||
github.com/google/pprof v0.0.0-20240727154555-813a5fbdbec8 // indirect
|
||||
github.com/insomniacslk/dhcp v0.0.0-20250109001534-8abf58130905 // indirect
|
||||
github.com/josharian/native v1.1.0 // indirect
|
||||
github.com/klauspost/compress v1.17.9 // indirect
|
||||
github.com/klauspost/cpuid/v2 v2.2.6 // indirect
|
||||
github.com/klauspost/reedsolomon v1.12.3 // indirect
|
||||
github.com/mdlayher/netlink v1.7.2 // indirect
|
||||
github.com/mdlayher/socket v0.5.1 // indirect
|
||||
github.com/metacubex/amneziawg-go v0.0.0-20251104174305-5a0e9f7e361d // indirect
|
||||
github.com/metacubex/ascon v0.1.0 // indirect
|
||||
github.com/metacubex/bart v0.26.0 // indirect
|
||||
github.com/metacubex/bbolt v0.0.0-20250725135710-010dbbbb7a5b // indirect
|
||||
github.com/metacubex/blake3 v0.1.0 // indirect
|
||||
github.com/metacubex/chacha v0.1.5 // indirect
|
||||
github.com/metacubex/chi v0.1.0 // indirect
|
||||
github.com/metacubex/connect-ip-go v0.0.0-20260412152424-e1625567920a // indirect
|
||||
github.com/metacubex/cpu v0.1.1 // indirect
|
||||
github.com/metacubex/edwards25519 v1.2.0 // indirect
|
||||
github.com/metacubex/fswatch v0.1.1 // indirect
|
||||
github.com/metacubex/gopacket v1.1.20-0.20230608035415-7e2f98a3e759 // indirect
|
||||
github.com/metacubex/gvisor v0.0.0-20251227095601-261ec1326fe8 // indirect
|
||||
github.com/metacubex/hkdf v0.1.0 // indirect
|
||||
github.com/metacubex/hpke v0.1.0 // indirect
|
||||
github.com/metacubex/http v0.1.4 // indirect
|
||||
github.com/metacubex/kcp-go v0.0.0-20260105040817-550693377604 // indirect
|
||||
github.com/metacubex/mhurl v0.1.0 // indirect
|
||||
github.com/metacubex/mihomo v1.7.0 // indirect
|
||||
github.com/metacubex/mlkem v0.1.0 // indirect
|
||||
github.com/metacubex/nftables v0.0.0-20260426003805-208c2c1ba2cb // indirect
|
||||
github.com/metacubex/qpack v0.6.0 // indirect
|
||||
github.com/metacubex/quic-go v0.59.1-0.20260413153657-53bb22f2c306 // indirect
|
||||
github.com/metacubex/randv2 v0.2.0 // indirect
|
||||
github.com/metacubex/restls-client-go v0.1.7 // indirect
|
||||
github.com/metacubex/sing v0.5.7 // indirect
|
||||
github.com/metacubex/sing-mux v0.3.9 // indirect
|
||||
github.com/metacubex/sing-quic v0.0.0-20260414034501-3ea3410d197a // indirect
|
||||
github.com/metacubex/sing-shadowsocks v0.2.12 // indirect
|
||||
github.com/metacubex/sing-shadowsocks2 v0.2.7 // indirect
|
||||
github.com/metacubex/sing-shadowtls v0.0.0-20250503063515-5d9f966d17a2 // indirect
|
||||
github.com/metacubex/sing-tun v0.4.18 // indirect
|
||||
github.com/metacubex/sing-vmess v0.2.5 // indirect
|
||||
github.com/metacubex/sing-wireguard v0.0.0-20260507084707-690d479ec947 // indirect
|
||||
github.com/metacubex/smux v0.0.0-20260105030934-d0c8756d3141 // indirect
|
||||
github.com/metacubex/ssh v0.1.0 // indirect
|
||||
github.com/metacubex/tfo-go v0.0.0-20251130171125-413e892ac443 // indirect
|
||||
github.com/metacubex/tls v0.1.5 // indirect
|
||||
github.com/metacubex/utls v1.8.4 // indirect
|
||||
github.com/metacubex/wireguard-go v0.0.0-20250820062549-a6cecdd7f57f // indirect
|
||||
github.com/metacubex/yamux v0.0.0-20250918083631-dd5f17c0be49 // indirect
|
||||
github.com/miekg/dns v1.1.63 // indirect
|
||||
github.com/mroth/weightedrand/v2 v2.1.0 // indirect
|
||||
github.com/oasisprotocol/deoxysii v0.0.0-20220228165953-2091330c22b7 // indirect
|
||||
github.com/openacid/low v0.1.21 // indirect
|
||||
github.com/oschwald/maxminddb-golang v1.12.0 // indirect
|
||||
github.com/pierrec/lz4/v4 v4.1.14 // indirect
|
||||
github.com/sagernet/netlink v0.0.0-20240612041022-b9a21c07ac6a // indirect
|
||||
github.com/samber/lo v1.53.0 // indirect
|
||||
github.com/sina-ghaderi/poly1305 v0.0.0-20220724002748-c5926b03988b // indirect
|
||||
github.com/sina-ghaderi/rabaead v0.0.0-20220730151906-ab6e06b96e8c // indirect
|
||||
github.com/sina-ghaderi/rabbitio v0.0.0-20220730151941-9ce26f4f872e // indirect
|
||||
github.com/sirupsen/logrus v1.9.4 // indirect
|
||||
github.com/u-root/uio v0.0.0-20230220225925-ffce2a382923 // indirect
|
||||
github.com/vishvananda/netns v0.0.5 // indirect
|
||||
github.com/vmihailenco/msgpack/v5 v5.4.1 // indirect
|
||||
github.com/vmihailenco/tagparser/v2 v2.0.0 // indirect
|
||||
github.com/yosida95/uritemplate/v3 v3.0.2 // indirect
|
||||
gitlab.com/go-extension/aes-ccm v0.0.0-20230221065045-e58665ef23c7 // indirect
|
||||
gitlab.com/yawning/bsaes.git v0.0.0-20190805113838-0a714cd429ec // indirect
|
||||
go4.org/netipx v0.0.0-20231129151722-fdeea329fbba // indirect
|
||||
golang.org/x/crypto v0.33.0 // indirect
|
||||
golang.org/x/exp v0.0.0-20240904232852-e7e105dedf7e // indirect
|
||||
golang.org/x/mod v0.20.0 // indirect
|
||||
golang.org/x/net v0.35.0 // indirect
|
||||
golang.org/x/sync v0.11.0 // indirect
|
||||
golang.org/x/sys v0.30.0 // indirect
|
||||
golang.org/x/text v0.22.0 // indirect
|
||||
golang.org/x/time v0.10.0 // indirect
|
||||
golang.org/x/tools v0.24.0 // indirect
|
||||
google.golang.org/protobuf v1.34.2 // indirect
|
||||
gopkg.in/yaml.v3 v3.0.1 // indirect
|
||||
cfa/blob v0.0.0 // indirect
|
||||
github.com/Dreamacro/clash v1.7.1 // indirect
|
||||
github.com/Dreamacro/go-shadowsocks2 v0.1.7 // indirect
|
||||
github.com/Kr328/tun2socket v0.0.0-20211231120722-962f339492e8 // indirect
|
||||
github.com/dlclark/regexp2 v1.4.0 // indirect
|
||||
github.com/gofrs/uuid v4.2.0+incompatible // indirect
|
||||
github.com/gorilla/websocket v1.4.2 // indirect
|
||||
github.com/insomniacslk/dhcp v0.0.0-20211214070828-5297eed8f489 // indirect
|
||||
github.com/kr/pretty v0.1.0 // indirect
|
||||
github.com/miekg/dns v1.1.45 // indirect
|
||||
github.com/oschwald/geoip2-golang v1.5.0 // indirect
|
||||
github.com/oschwald/maxminddb-golang v1.8.0 // indirect
|
||||
github.com/sirupsen/logrus v1.8.1 // indirect
|
||||
github.com/u-root/uio v0.0.0-20210528151154-e40b768296a7 // indirect
|
||||
go.etcd.io/bbolt v1.3.6 // indirect
|
||||
go.uber.org/atomic v1.9.0 // indirect
|
||||
golang.org/x/crypto v0.0.0-20211215153901-e495a2d5b3d3 // indirect
|
||||
golang.org/x/mod v0.4.2 // indirect
|
||||
golang.org/x/net v0.0.0-20211216030914-fe4d6282115f // indirect
|
||||
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c // indirect
|
||||
golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e // indirect
|
||||
golang.org/x/text v0.3.7 // indirect
|
||||
golang.org/x/tools v0.1.6-0.20210726203631-07bc1bf47fb2 // indirect
|
||||
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 // indirect
|
||||
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 // indirect
|
||||
gopkg.in/yaml.v2 v2.4.0 // indirect
|
||||
)
|
||||
|
||||
replace cfa => ../../main/golang
|
||||
|
||||
replace github.com/metacubex/mihomo => ./clash
|
||||
replace github.com/Dreamacro/clash => ./clash
|
||||
|
||||
replace google.golang.org/protobuf => github.com/metacubex/protobuf-go v0.0.0-20260306035419-7ceee0674686
|
||||
replace cfa/blob => ../../../build/intermediates/golang_blob
|
||||
|
||||
@@ -1,251 +1,153 @@
|
||||
github.com/RyuaNerin/go-krypto v1.3.0 h1:smavTzSMAx8iuVlGb4pEwl9MD2qicqMzuXR2QWp2/Pg=
|
||||
github.com/RyuaNerin/go-krypto v1.3.0/go.mod h1:9R9TU936laAIqAmjcHo/LsaXYOZlymudOAxjaBf62UM=
|
||||
github.com/RyuaNerin/testingutil v0.1.0 h1:IYT6JL57RV3U2ml3dLHZsVtPOP6yNK7WUVdzzlpNrss=
|
||||
github.com/Yawning/aez v0.0.0-20211027044916-e49e68abd344 h1:cDVUiFo+npB0ZASqnw4q90ylaVAbnYyx0JYqK4YcGok=
|
||||
github.com/Yawning/aez v0.0.0-20211027044916-e49e68abd344/go.mod h1:9pIqrY6SXNL8vjRQE5Hd/OL5GyK/9MrGUWs87z/eFfk=
|
||||
github.com/ajg/form v1.5.1 h1:t9c7v8JUKu/XxOGBU0yjNpaMloxGEJhUkqFRq0ibGeU=
|
||||
github.com/ajg/form v1.5.1/go.mod h1:uL1WgH+h2mgNtvBq0339dVnzXdBETtL2LeUXaIv25UY=
|
||||
github.com/andybalholm/brotli v1.0.6 h1:Yf9fFpf49Zrxb9NlQaluyE92/+X7UVHlhMNJN2sxfOI=
|
||||
github.com/andybalholm/brotli v1.0.6/go.mod h1:fO7iG3H7G2nSZ7m0zPUDn85XEX2GTukHGRSepvi9Eig=
|
||||
github.com/bahlo/generic-list-go v0.2.0 h1:5sz/EEAK+ls5wF+NeqDpk5+iNdMDXrh3z3nPnH1Wvgk=
|
||||
github.com/bahlo/generic-list-go v0.2.0/go.mod h1:2KvAjgMlE5NNynlg/5iLrrCCZ2+5xWbdbCW3pNTGyYg=
|
||||
github.com/blang/semver v3.5.1+incompatible/go.mod h1:kRBLl5iJ+tD4TcOOxsy/0fnwebNt5EWlYSAyrTnjyyk=
|
||||
github.com/coreos/go-iptables v0.8.0 h1:MPc2P89IhuVpLI7ETL/2tx3XZ61VeICZjYqDEgNsPRc=
|
||||
github.com/coreos/go-iptables v0.8.0/go.mod h1:Qe8Bv2Xik5FyTXwgIbLAnv2sWSBmvWdFETJConOQ//Q=
|
||||
github.com/Dreamacro/go-shadowsocks2 v0.1.7 h1:8CtbE1HoPPMfrQZGXmlluq6dO2lL31W6WRRE8fabc4Q=
|
||||
github.com/Dreamacro/go-shadowsocks2 v0.1.7/go.mod h1:8p5G4cAj5ZlXwUR+Ww63gfSikr8kvw8uw3TDwLAJpUc=
|
||||
github.com/Kr328/tun2socket v0.0.0-20211231120722-962f339492e8 h1:4Ceb/pU/u7fKGMCE2DNrWIEHkoR1ELRlYJXzbFOR+E0=
|
||||
github.com/Kr328/tun2socket v0.0.0-20211231120722-962f339492e8/go.mod h1:YR9wK13TgI5ww8iKWm91MHiSoHC7Oz0U4beCCmtXqLw=
|
||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
||||
github.com/dlclark/regexp2 v1.12.0 h1:0j4c5qQmnC6XOWNjP3PIXURXN2gWx76rd3KvgdPkCz8=
|
||||
github.com/dlclark/regexp2 v1.12.0/go.mod h1:DHkYz0B9wPfa6wondMfaivmHpzrQ3v9q8cnmRbL6yW8=
|
||||
github.com/dunglas/httpsfv v1.0.2 h1:iERDp/YAfnojSDJ7PW3dj1AReJz4MrwbECSSE59JWL0=
|
||||
github.com/dunglas/httpsfv v1.0.2/go.mod h1:zID2mqw9mFsnt7YC3vYQ9/cjq30q41W+1AnDwH8TiMg=
|
||||
github.com/enfein/mieru/v3 v3.31.0 h1:Fl2ocRCRXJzMygzdRjBHgqI996ZuIDHUmyQyovSf9sA=
|
||||
github.com/enfein/mieru/v3 v3.31.0/go.mod h1:zJBUCsi5rxyvHM8fjFf+GLaEl4OEjjBXr1s5F6Qd3hM=
|
||||
github.com/ericlagergren/aegis v0.0.0-20250325060835-cd0defd64358 h1:kXYqH/sL8dS/FdoFjr12ePjnLPorPo2FsnrHNuXSDyo=
|
||||
github.com/ericlagergren/aegis v0.0.0-20250325060835-cd0defd64358/go.mod h1:hkIFzoiIPZYxdFOOLyDho59b7SrDfo+w3h+yWdlg45I=
|
||||
github.com/ericlagergren/polyval v0.0.0-20220411101811-e25bc10ba391 h1:8j2RH289RJplhA6WfdaPqzg1MjH2K8wX5e0uhAxrw2g=
|
||||
github.com/ericlagergren/polyval v0.0.0-20220411101811-e25bc10ba391/go.mod h1:K2R7GhgxrlJzHw2qiPWsCZXf/kXEJN9PLnQK73Ll0po=
|
||||
github.com/ericlagergren/saferand v0.0.0-20220206064634-960a4dd2bc5c h1:RUzBDdZ+e/HEe2Nh8lYsduiPAZygUfVXJn0Ncj5sHMg=
|
||||
github.com/ericlagergren/siv v0.0.0-20220507050439-0b757b3aa5f1 h1:tlDMEdcPRQKBEz5nGDMvswiajqh7k8ogWRlhRwKy5mY=
|
||||
github.com/ericlagergren/siv v0.0.0-20220507050439-0b757b3aa5f1/go.mod h1:4RfsapbGx2j/vU5xC/5/9qB3kn9Awp1YDiEnN43QrJ4=
|
||||
github.com/ericlagergren/subtle v0.0.0-20220507045147-890d697da010 h1:fuGucgPk5dN6wzfnxl3D0D3rVLw4v2SbBT9jb4VnxzA=
|
||||
github.com/ericlagergren/subtle v0.0.0-20220507045147-890d697da010/go.mod h1:JtBcj7sBuTTRupn7c2bFspMDIObMJsVK8TeUvpShPok=
|
||||
github.com/fsnotify/fsnotify v1.9.0 h1:2Ml+OJNzbYCTzsxtv8vKSFD9PbJjmhYF14k/jKC7S9k=
|
||||
github.com/fsnotify/fsnotify v1.9.0/go.mod h1:8jBTzvmWwFyi3Pb8djgCCO5IBqzKJ/Jwo8TRcHyHii0=
|
||||
github.com/gaukas/godicttls v0.0.4 h1:NlRaXb3J6hAnTmWdsEKb9bcSBD6BvcIjdGdeb0zfXbk=
|
||||
github.com/gaukas/godicttls v0.0.4/go.mod h1:l6EenT4TLWgTdwslVb4sEMOCf7Bv0JAK67deKr9/NCI=
|
||||
github.com/go-ole/go-ole v1.3.0 h1:Dt6ye7+vXGIKZ7Xtk4s6/xVdGDQynvom7xCFEdWr6uE=
|
||||
github.com/go-ole/go-ole v1.3.0/go.mod h1:5LS6F96DhAwUc7C+1HLexzMXY1xGRSryjyPPKW6zv78=
|
||||
github.com/gobwas/httphead v0.1.0 h1:exrUm0f4YX0L7EBwZHuCF4GDp8aJfVeBrlLQrs6NqWU=
|
||||
github.com/gobwas/httphead v0.1.0/go.mod h1:O/RXo79gxV8G+RqlR/otEwx4Q36zl9rqC5u12GKvMCM=
|
||||
github.com/gobwas/pool v0.2.1 h1:xfeeEhW7pwmX8nuLVlqbzVc7udMDrwetjEv+TZIz1og=
|
||||
github.com/gobwas/pool v0.2.1/go.mod h1:q8bcK0KcYlCgd9e7WYLm9LpyS+YeLd8JVDW6WezmKEw=
|
||||
github.com/gobwas/ws v1.4.0 h1:CTaoG1tojrh4ucGPcoJFiAQUAsEWekEWvLy7GsVNqGs=
|
||||
github.com/gobwas/ws v1.4.0/go.mod h1:G3gNqMNtPppf5XUz7O4shetPpcZ1VJ7zt18dlUeakrc=
|
||||
github.com/gofrs/uuid/v5 v5.4.0 h1:EfbpCTjqMuGyq5ZJwxqzn3Cbr2d0rUZU7v5ycAk/e/0=
|
||||
github.com/gofrs/uuid/v5 v5.4.0/go.mod h1:CDOjlDMVAtN56jqyRUZh58JT31Tiw7/oQyEXZV+9bD8=
|
||||
github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||
github.com/golang/snappy v1.0.0 h1:Oy607GVXHs7RtbggtPBnr2RmDArIsAefDwvrdWvRhGs=
|
||||
github.com/golang/snappy v1.0.0/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
|
||||
github.com/google/btree v1.1.3 h1:CVpQJjYgC4VbzxeGVHfvZrv1ctoYCAI8vbl07Fcxlyg=
|
||||
github.com/google/btree v1.1.3/go.mod h1:qOPhT0dTNdNzV6Z/lhRX0YXUafgPLFUh+gZMl761Gm4=
|
||||
github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=
|
||||
github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
|
||||
github.com/google/pprof v0.0.0-20240727154555-813a5fbdbec8 h1:FKHo8hFI3A+7w0aUQuYXQ+6EN5stWmeY/AZqtM8xk9k=
|
||||
github.com/google/pprof v0.0.0-20240727154555-813a5fbdbec8/go.mod h1:K1liHPHnj73Fdn/EKuT8nrFqBihUSKXoLYU0BuatOYo=
|
||||
github.com/google/tink/go v1.6.1 h1:t7JHqO8Ath2w2ig5vjwQYJzhGEZymedQc90lQXUBa4I=
|
||||
github.com/insomniacslk/dhcp v0.0.0-20250109001534-8abf58130905 h1:q3OEI9RaN/wwcx+qgGo6ZaoJkCiDYe/gjDLfq7lQQF4=
|
||||
github.com/insomniacslk/dhcp v0.0.0-20250109001534-8abf58130905/go.mod h1:VvGYjkZoJyKqlmT1yzakUs4mfKMNB0XdODP0+rdml6k=
|
||||
github.com/josharian/native v1.0.1-0.20221213033349-c1e37c09b531/go.mod h1:7X/raswPFr05uY3HiLlYeyQntB6OO7E/d2Cu7qoaN2w=
|
||||
github.com/josharian/native v1.1.0 h1:uuaP0hAbW7Y4l0ZRQ6C9zfb7Mg1mbFKry/xzDAfmtLA=
|
||||
github.com/josharian/native v1.1.0/go.mod h1:7X/raswPFr05uY3HiLlYeyQntB6OO7E/d2Cu7qoaN2w=
|
||||
github.com/klauspost/compress v1.17.9 h1:6KIumPrER1LHsvBVuDa0r5xaG0Es51mhhB9BQB2qeMA=
|
||||
github.com/klauspost/compress v1.17.9/go.mod h1:Di0epgTjJY877eYKx5yC51cX2A2Vl2ibi7bDH9ttBbw=
|
||||
github.com/klauspost/cpuid/v2 v2.2.6 h1:ndNyv040zDGIDh8thGkXYjnFtiN02M1PVVF+JE/48xc=
|
||||
github.com/klauspost/cpuid/v2 v2.2.6/go.mod h1:Lcz8mBdAVJIBVzewtcLocK12l3Y+JytZYpaMropDUws=
|
||||
github.com/klauspost/reedsolomon v1.12.3 h1:tzUznbfc3OFwJaTebv/QdhnFf2Xvb7gZ24XaHLBPmdc=
|
||||
github.com/klauspost/reedsolomon v1.12.3/go.mod h1:3K5rXwABAvzGeR01r6pWZieUALXO/Tq7bFKGIb4m4WI=
|
||||
github.com/mdlayher/netlink v1.7.2 h1:/UtM3ofJap7Vl4QWCPDGXY8d3GIY2UGSDbK+QWmY8/g=
|
||||
github.com/mdlayher/netlink v1.7.2/go.mod h1:xraEF7uJbxLhc5fpHL4cPe221LI2bdttWlU+ZGLfQSw=
|
||||
github.com/mdlayher/socket v0.5.1 h1:VZaqt6RkGkt2OE9l3GcC6nZkqD3xKeQLyfleW/uBcos=
|
||||
github.com/mdlayher/socket v0.5.1/go.mod h1:TjPLHI1UgwEv5J1B5q0zTZq12A/6H7nKmtTanQE37IQ=
|
||||
github.com/metacubex/amneziawg-go v0.0.0-20251104174305-5a0e9f7e361d h1:vAJ0ZT4aO803F1uw2roIA9yH7Sxzox34tVVyye1bz6c=
|
||||
github.com/metacubex/amneziawg-go v0.0.0-20251104174305-5a0e9f7e361d/go.mod h1:MsM/5czONyXMJ3PRr5DbQ4O/BxzAnJWOIcJdLzW6qHY=
|
||||
github.com/metacubex/ascon v0.1.0 h1:6ZWxmXYszT1XXtwkf6nxfFhc/OTtQ9R3Vyj1jN32lGM=
|
||||
github.com/metacubex/ascon v0.1.0/go.mod h1:eV5oim4cVPPdEL8/EYaTZ0iIKARH9pnhAK/fcT5Kacc=
|
||||
github.com/metacubex/bart v0.26.0 h1:d/bBTvVatfVWGfQbiDpYKI1bXUJgjaabB2KpK1Tnk6w=
|
||||
github.com/metacubex/bart v0.26.0/go.mod h1:DCcyfP4MC+Zy7sLK7XeGuMw+P5K9mIRsYOBgiE8icsI=
|
||||
github.com/metacubex/bbolt v0.0.0-20250725135710-010dbbbb7a5b h1:j7dadXD8I2KTmMt8jg1JcaP1ANL3JEObJPdANKcSYPY=
|
||||
github.com/metacubex/bbolt v0.0.0-20250725135710-010dbbbb7a5b/go.mod h1:+WmP0VJZDkDszvpa83HzfUp6QzARl/IKkMorH4+nODw=
|
||||
github.com/metacubex/blake3 v0.1.0 h1:KGnjh/56REO7U+cgZA8dnBhxdP7jByrG7hTP+bu6cqY=
|
||||
github.com/metacubex/blake3 v0.1.0/go.mod h1:CCkLdzFrqf7xmxCdhQFvJsRRV2mwOLDoSPg6vUTB9Uk=
|
||||
github.com/metacubex/chacha v0.1.5 h1:fKWMb/5c7ZrY8Uoqi79PPFxl+qwR7X/q0OrsAubyX2M=
|
||||
github.com/metacubex/chacha v0.1.5/go.mod h1:Djn9bPZxLTXbJFSeyo0/qzEzQI+gUSSzttuzZM75GH8=
|
||||
github.com/metacubex/chi v0.1.0 h1:rjNDyDj50nRpicG43CNkIw4ssiCbmDL8d7wJXKlUCsg=
|
||||
github.com/metacubex/chi v0.1.0/go.mod h1:zM5u5oMQt8b2DjvDHvzadKrP6B2ztmasL1YHRMbVV+g=
|
||||
github.com/metacubex/connect-ip-go v0.0.0-20260412152424-e1625567920a h1:Ph5UfTWDsGruZ+v95Df1ycTflQFmpZBFg2LUvj2kx/M=
|
||||
github.com/metacubex/connect-ip-go v0.0.0-20260412152424-e1625567920a/go.mod h1:xYC8Ik7/rN6no+vTRuWMEziGwm3brA0wNM/zZP9qhOQ=
|
||||
github.com/metacubex/cpu v0.1.1 h1:rRV5HGmeuGzjiKI3hYbL0dCd0qGwM7VUtk4ICXD06mI=
|
||||
github.com/metacubex/cpu v0.1.1/go.mod h1:09VEt4dSRLR+bOA8l4w4NDuzGZ8n5dkMv7e8axgEeTU=
|
||||
github.com/metacubex/edwards25519 v1.2.0 h1:pIQZLBsjQgg3Nl/c86YYFEUAbL5qQRnPq4LrgIw0KK4=
|
||||
github.com/metacubex/edwards25519 v1.2.0/go.mod h1:NCQF3J/Ki7382FJuokwsywEIIEI/gro/3smyXgQJsx0=
|
||||
github.com/metacubex/fswatch v0.1.1 h1:jqU7C/v+g0qc2RUFgmAOPoVvfl2BXXUXEumn6oQuxhU=
|
||||
github.com/metacubex/fswatch v0.1.1/go.mod h1:czrTT7Zlbz7vWft8RQu9Qqh+JoX+Nnb+UabuyN1YsgI=
|
||||
github.com/metacubex/gopacket v1.1.20-0.20230608035415-7e2f98a3e759 h1:cjd4biTvOzK9ubNCCkQ+ldc4YSH/rILn53l/xGBFHHI=
|
||||
github.com/metacubex/gopacket v1.1.20-0.20230608035415-7e2f98a3e759/go.mod h1:UHOv2xu+RIgLwpXca7TLrXleEd4oR3sPatW6IF8wU88=
|
||||
github.com/metacubex/gvisor v0.0.0-20251227095601-261ec1326fe8 h1:hUL81H0Ic/XIDkvtn9M1pmfDdfid7JzYQToY4Ps1TvQ=
|
||||
github.com/metacubex/gvisor v0.0.0-20251227095601-261ec1326fe8/go.mod h1:8LpS0IJW1VmWzUm3ylb0e2SK5QDm5lO/2qwWLZgRpBU=
|
||||
github.com/metacubex/hkdf v0.1.0 h1:fPA6VzXK8cU1foc/TOmGCDmSa7pZbxlnqhl3RNsthaA=
|
||||
github.com/metacubex/hkdf v0.1.0/go.mod h1:3seEfds3smgTAXqUGn+tgEJH3uXdsUjOiduG/2EtvZ4=
|
||||
github.com/metacubex/hpke v0.1.0 h1:gu2jUNhraehWi0P/z5HX2md3d7L1FhPQE6/Q0E9r9xQ=
|
||||
github.com/metacubex/hpke v0.1.0/go.mod h1:vfDm6gfgrwlXUxKDkWbcE44hXtmc1uxLDm2BcR11b3U=
|
||||
github.com/metacubex/http v0.1.4 h1:gU1y8WlqslzxGmedW2ah74fGL6wJYU2HXUkCMJtCa2A=
|
||||
github.com/metacubex/http v0.1.4/go.mod h1:Nxx0zZAo2AhRfanyL+fmmK6ACMtVsfpwIl1aFAik2Eg=
|
||||
github.com/metacubex/kcp-go v0.0.0-20260105040817-550693377604 h1:hJwCVlE3ojViC35MGHB+FBr8TuIf3BUFn2EQ1VIamsI=
|
||||
github.com/metacubex/kcp-go v0.0.0-20260105040817-550693377604/go.mod h1:lpmN3m269b3V5jFCWtffqBLS4U3QQoIid9ugtO+OhVc=
|
||||
github.com/metacubex/mhurl v0.1.0 h1:ZdW4Zxe3j3uJ89gNytOazHu6kbHn5owutN/VfXOI8GE=
|
||||
github.com/metacubex/mhurl v0.1.0/go.mod h1:2qpQImCbXoUs6GwJrjuEXKelPyoimsIXr07eNKZdS00=
|
||||
github.com/metacubex/mlkem v0.1.0 h1:wFClitonSFcmipzzQvax75beLQU+D7JuC+VK1RzSL8I=
|
||||
github.com/metacubex/mlkem v0.1.0/go.mod h1:amhaXZVeYNShuy9BILcR7P0gbeo/QLZsnqCdL8U2PDQ=
|
||||
github.com/metacubex/nftables v0.0.0-20260426003805-208c2c1ba2cb h1:wk6mHYPURSUvWcUv72gNP79oiylFsscBSDPJ6ieV6Iw=
|
||||
github.com/metacubex/nftables v0.0.0-20260426003805-208c2c1ba2cb/go.mod h1:73ZrCfhdkW4F2E2GAlta3km/S2RHhFNogCMtWZV2anQ=
|
||||
github.com/metacubex/protobuf-go v0.0.0-20260306035419-7ceee0674686 h1:PIXmYT2anQt9V8vdmwixtbIJxOpoPXJfIACHPjXEgnE=
|
||||
github.com/metacubex/protobuf-go v0.0.0-20260306035419-7ceee0674686/go.mod h1:eQV7juxFZIdRgjMxtVqP+6BssKoTZQ1RM0fc58BsCZY=
|
||||
github.com/metacubex/qpack v0.6.0 h1:YqClGIMOpiRYLjV1qOs483Od08MdPgRnHjt90FuaAKw=
|
||||
github.com/metacubex/qpack v0.6.0/go.mod h1:lKGSi7Xk94IMvHGOmxS9eIei3bvIqpOAImEBsaOwTkA=
|
||||
github.com/metacubex/quic-go v0.59.1-0.20260413153657-53bb22f2c306 h1:HlGLmLsWJMLSu0CMI9z/BmEnithB4oXM5Rom6/0Qxtg=
|
||||
github.com/metacubex/quic-go v0.59.1-0.20260413153657-53bb22f2c306/go.mod h1:oNzMrmylS897M3zSMuapIdwSwfq6F2qW01Z3NhVRJhk=
|
||||
github.com/metacubex/randv2 v0.2.0 h1:uP38uBvV2SxYfLj53kuvAjbND4RUDfFJjwr4UigMiLs=
|
||||
github.com/metacubex/randv2 v0.2.0/go.mod h1:kFi2SzrQ5WuneuoLLCMkABtiBu6VRrMrWFqSPyj2cxY=
|
||||
github.com/metacubex/restls-client-go v0.1.7 h1:eCwiXCTQb5WJu9IlgYvDBA1OgrINv58dEe7hcN5H15k=
|
||||
github.com/metacubex/restls-client-go v0.1.7/go.mod h1:BN/U52vPw7j8VTSh2vleD/MnmVKCov84mS5VcjVHH4g=
|
||||
github.com/metacubex/sing v0.5.7 h1:8OC+fhKFSv/l9ehEhJRaZZAOuthfZo68SteBVLe8QqM=
|
||||
github.com/metacubex/sing v0.5.7/go.mod h1:ypf0mjwlZm0sKdQSY+yQvmsbWa0hNPtkeqyRMGgoN+w=
|
||||
github.com/metacubex/sing-mux v0.3.9 h1:/aoBD2+sK2qsXDlNDe3hkR0GZuFDtwIZhOeGUx9W0Yk=
|
||||
github.com/metacubex/sing-mux v0.3.9/go.mod h1:8bT7ZKT3clRrJjYc/x5CRYibC1TX/bK73a3r3+2E+Fc=
|
||||
github.com/metacubex/sing-quic v0.0.0-20260414034501-3ea3410d197a h1:977o0ZYYbiQAGuOxql7Q6UN3rEy59OyAE0tELq4gZfI=
|
||||
github.com/metacubex/sing-quic v0.0.0-20260414034501-3ea3410d197a/go.mod h1:6ayFGfzzBE85csgQkM3gf4neFq6s0losHlPRSxY+nuk=
|
||||
github.com/metacubex/sing-shadowsocks v0.2.12 h1:Wqzo8bYXrK5aWqxu/TjlTnYZzAKtKsaFQBdr6IHFaBE=
|
||||
github.com/metacubex/sing-shadowsocks v0.2.12/go.mod h1:2e5EIaw0rxKrm1YTRmiMnDulwbGxH9hAFlrwQLQMQkU=
|
||||
github.com/metacubex/sing-shadowsocks2 v0.2.7 h1:hSuuc0YpsfiqYqt1o+fP4m34BQz4e6wVj3PPBVhor3A=
|
||||
github.com/metacubex/sing-shadowsocks2 v0.2.7/go.mod h1:vOEbfKC60txi0ca+yUlqEwOGc3Obl6cnSgx9Gf45KjE=
|
||||
github.com/metacubex/sing-shadowtls v0.0.0-20250503063515-5d9f966d17a2 h1:gXU+MYPm7Wme3/OAY2FFzVq9d9GxPHOqu5AQfg/ddhI=
|
||||
github.com/metacubex/sing-shadowtls v0.0.0-20250503063515-5d9f966d17a2/go.mod h1:mbfboaXauKJNIHJYxQRa+NJs4JU9NZfkA+I33dS2+9E=
|
||||
github.com/metacubex/sing-tun v0.4.18 h1:WRzAosG0YkT3aZq5RJWtF+RdCgeJ8EpooS5ZM1lkXo0=
|
||||
github.com/metacubex/sing-tun v0.4.18/go.mod h1:g4I/JNplDBhXLF+aQWgFbhNeJPSXQOWS9HvLeNvkgeA=
|
||||
github.com/metacubex/sing-vmess v0.2.5 h1:m9Zt5I27lB9fmLMZfism9sH2LcnAfShZfwSkf6/KJoE=
|
||||
github.com/metacubex/sing-vmess v0.2.5/go.mod h1:AwtlzUgf8COe9tRYAKqWZ+leDH7p5U98a0ZUpYehl8Q=
|
||||
github.com/metacubex/sing-wireguard v0.0.0-20260507084707-690d479ec947 h1:IB03BvRQtvjWScyOK5jSQVJYY8osmZXHL+4VCEFMWcM=
|
||||
github.com/metacubex/sing-wireguard v0.0.0-20260507084707-690d479ec947/go.mod h1:jpAkVLPnCpGSfNyVmj6Cq4YbuZsFepm/Dc+9BAOcR80=
|
||||
github.com/metacubex/smux v0.0.0-20260105030934-d0c8756d3141 h1:DK2l6m2Fc85H2BhiAPgbJygiWhesPlfGmF+9Vw6ARdk=
|
||||
github.com/metacubex/smux v0.0.0-20260105030934-d0c8756d3141/go.mod h1:/yI4OiGOSn0SURhZdJF3CbtPg3nwK700bG8TZLMBvAg=
|
||||
github.com/metacubex/ssh v0.1.0 h1:iGfr99qk/eMHzUnQ/0bTxXT8+8SWqLSHBWDHoAhngzw=
|
||||
github.com/metacubex/ssh v0.1.0/go.mod h1:NUtl0d+/f2cG9ECEpMM8iCVOpmggQlC13oLeDUONDlU=
|
||||
github.com/metacubex/tfo-go v0.0.0-20251130171125-413e892ac443 h1:H6TnfM12tOoTizYE/qBHH3nEuibIelmHI+BVSxVJr8o=
|
||||
github.com/metacubex/tfo-go v0.0.0-20251130171125-413e892ac443/go.mod h1:l9oLnLoEXyGZ5RVLsh7QCC5XsouTUyKk4F2nLm2DHLw=
|
||||
github.com/metacubex/tls v0.1.5 h1:ECcB83dj+zadnhlKcLnUUf1Sq6+vU0f/zoyU0+9oPTc=
|
||||
github.com/metacubex/tls v0.1.5/go.mod h1:0XeVdL0cBw+8i5Hqy3lVeP9IyD/LFTq02ExvHM6rzEM=
|
||||
github.com/metacubex/utls v1.8.4 h1:HmL9nUApDdWSkgUyodfwF6hSjtiwCGGdyhaSpEejKpg=
|
||||
github.com/metacubex/utls v1.8.4/go.mod h1:kncGGVhFaoGn5M3pFe3SXhZCzsbCJayNOH4UEqTKTko=
|
||||
github.com/metacubex/wireguard-go v0.0.0-20250820062549-a6cecdd7f57f h1:FGBPRb1zUabhPhDrlKEjQ9lgIwQ6cHL4x8M9lrERhbk=
|
||||
github.com/metacubex/wireguard-go v0.0.0-20250820062549-a6cecdd7f57f/go.mod h1:oPGcV994OGJedmmxrcK9+ni7jUEMGhR+uVQAdaduIP4=
|
||||
github.com/metacubex/yamux v0.0.0-20250918083631-dd5f17c0be49 h1:lhlqpYHopuTLx9xQt22kSA9HtnyTDmk5XjjQVCGHe2E=
|
||||
github.com/metacubex/yamux v0.0.0-20250918083631-dd5f17c0be49/go.mod h1:MBeEa9IVBphH7vc3LNtW6ZujVXFizotPo3OEiHQ+TNU=
|
||||
github.com/miekg/dns v1.1.63 h1:8M5aAw6OMZfFXTT7K5V0Eu5YiiL8l7nUAkyN6C9YwaY=
|
||||
github.com/miekg/dns v1.1.63/go.mod h1:6NGHfjhpmr5lt3XPLuyfDJi5AXbNIPM9PY6H6sF1Nfs=
|
||||
github.com/mroth/weightedrand/v2 v2.1.0 h1:o1ascnB1CIVzsqlfArQQjeMy1U0NcIbBO5rfd5E/OeU=
|
||||
github.com/mroth/weightedrand/v2 v2.1.0/go.mod h1:f2faGsfOGOwc1p94wzHKKZyTpcJUW7OJ/9U4yfiNAOU=
|
||||
github.com/oasisprotocol/deoxysii v0.0.0-20220228165953-2091330c22b7 h1:1102pQc2SEPp5+xrS26wEaeb26sZy6k9/ZXlZN+eXE4=
|
||||
github.com/oasisprotocol/deoxysii v0.0.0-20220228165953-2091330c22b7/go.mod h1:UqoUn6cHESlliMhOnKLWr+CBH+e3bazUPvFj1XZwAjs=
|
||||
github.com/openacid/errors v0.8.1/go.mod h1:GUQEJJOJE3W9skHm8E8Y4phdl2LLEN8iD7c5gcGgdx0=
|
||||
github.com/openacid/low v0.1.21 h1:Tr2GNu4N/+rGRYdOsEHOE89cxUIaDViZbVmKz29uKGo=
|
||||
github.com/openacid/low v0.1.21/go.mod h1:q+MsKI6Pz2xsCkzV4BLj7NR5M4EX0sGz5AqotpZDVh0=
|
||||
github.com/openacid/must v0.1.3/go.mod h1:luPiXCuJlEo3UUFQngVQokV0MPGryeYvtCbQPs3U1+I=
|
||||
github.com/openacid/testkeys v0.1.6/go.mod h1:MfA7cACzBpbiwekivj8StqX0WIRmqlMsci1c37CA3Do=
|
||||
github.com/oschwald/maxminddb-golang v1.12.0 h1:9FnTOD0YOhP7DGxGsq4glzpGy5+w7pq50AS6wALUMYs=
|
||||
github.com/oschwald/maxminddb-golang v1.12.0/go.mod h1:q0Nob5lTCqyQ8WT6FYgS1L7PXKVVbgiymefNwIjPzgY=
|
||||
github.com/pierrec/lz4/v4 v4.1.14 h1:+fL8AQEZtz/ijeNnpduH0bROTu0O3NZAlPjQxGn8LwE=
|
||||
github.com/pierrec/lz4/v4 v4.1.14/go.mod h1:gZWDp/Ze/IJXGXf23ltt2EXimqmTUXEy0GFuRQyBid4=
|
||||
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/dlclark/regexp2 v1.4.0 h1:F1rxgk7p4uKjwIQxBs9oAXe5CqrXlCduYEJvrF4u93E=
|
||||
github.com/dlclark/regexp2 v1.4.0/go.mod h1:2pZnwuY/m+8K6iRw6wQdMtk+rH5tNGR1i55kozfMjCc=
|
||||
github.com/fanliao/go-promise v0.0.0-20141029170127-1890db352a72/go.mod h1:PjfxuH4FZdUyfMdtBio2lsRr1AKEaVPwelzuHuh8Lqc=
|
||||
github.com/go-chi/chi/v5 v5.0.7/go.mod h1:DslCQbL2OYiznFReuXYUmQ2hGd1aDpCnlMNITLSKoi8=
|
||||
github.com/go-chi/cors v1.2.0/go.mod h1:sSbTewc+6wYHBBCW7ytsFSn836hqM7JxpglAy2Vzc58=
|
||||
github.com/go-chi/render v1.0.1/go.mod h1:pq4Rr7HbnsdaeHagklXub+p6Wd16Af5l9koip1OvJns=
|
||||
github.com/gofrs/uuid v4.0.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM=
|
||||
github.com/gofrs/uuid v4.2.0+incompatible h1:yyYWMnhkhrKwwr8gAOcOCYxOOscHgDS9yZgBrnJfGa0=
|
||||
github.com/gofrs/uuid v4.2.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM=
|
||||
github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=
|
||||
github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
|
||||
github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
|
||||
github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY=
|
||||
github.com/gorilla/websocket v1.4.2 h1:+/TMaTYc4QFitKJxsQ7Yye35DkWvkdLcvGKqM+x0Ufc=
|
||||
github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
|
||||
github.com/hugelgupf/socketpair v0.0.0-20190730060125-05d35a94e714/go.mod h1:2Goc3h8EklBH5mspfHFxBnEoURQCGzQQH1ga9Myjvis=
|
||||
github.com/insomniacslk/dhcp v0.0.0-20210827173440-b95caade3eac/go.mod h1:h+MxyHxRg9NH3terB1nfRIUaQEcI0XOVkdR9LNBlp8E=
|
||||
github.com/insomniacslk/dhcp v0.0.0-20211214070828-5297eed8f489 h1:jhdHqd7DxBrzfuFSoPxjD6nUVaV/1RIn9aHA0WCf/as=
|
||||
github.com/insomniacslk/dhcp v0.0.0-20211214070828-5297eed8f489/go.mod h1:h+MxyHxRg9NH3terB1nfRIUaQEcI0XOVkdR9LNBlp8E=
|
||||
github.com/jsimonetti/rtnetlink v0.0.0-20190606172950-9527aa82566a/go.mod h1:Oz+70psSo5OFh8DBl0Zv2ACw7Esh6pPUphlvZG9x7uw=
|
||||
github.com/jsimonetti/rtnetlink v0.0.0-20200117123717-f846d4f6c1f4/go.mod h1:WGuG/smIU4J/54PblvSbh+xvCZmpJnFgr3ds6Z55XMQ=
|
||||
github.com/jsimonetti/rtnetlink v0.0.0-20201009170750-9c6f07d100c1/go.mod h1:hqoO/u39cqLeBLebZ8fWdE96O7FxrAsRYhnVOdgHxok=
|
||||
github.com/jsimonetti/rtnetlink v0.0.0-20201110080708-d2c240429e6c/go.mod h1:huN4d1phzjhlOsNIjFsw2SVRbwIHj3fJDMEU2SDPTmg=
|
||||
github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU=
|
||||
github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI=
|
||||
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
|
||||
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
|
||||
github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE=
|
||||
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
|
||||
github.com/mdlayher/ethernet v0.0.0-20190606142754-0394541c37b7/go.mod h1:U6ZQobyTjI/tJyq2HG+i/dfSoFUt8/aZCM+GKtmFk/Y=
|
||||
github.com/mdlayher/netlink v0.0.0-20190409211403-11939a169225/go.mod h1:eQB3mZE4aiYnlUsyGGCOpPETfdQq4Jhsgf1fk3cwQaA=
|
||||
github.com/mdlayher/netlink v1.0.0/go.mod h1:KxeJAFOFLG6AjpyDkQ/iIhxygIUKD+vcwqcnu43w/+M=
|
||||
github.com/mdlayher/netlink v1.1.0/go.mod h1:H4WCitaheIsdF9yOYu8CFmCgQthAPIWZmcKp9uZHgmY=
|
||||
github.com/mdlayher/netlink v1.1.1/go.mod h1:WTYpFb/WTvlRJAyKhZL5/uy69TDDpHHu2VZmb2XgV7o=
|
||||
github.com/mdlayher/raw v0.0.0-20190606142536-fef19f00fc18/go.mod h1:7EpbotpCmVZcu+KCX4g9WaRNuu11uyhiW7+Le1dKawg=
|
||||
github.com/mdlayher/raw v0.0.0-20191009151244-50f2db8cc065/go.mod h1:7EpbotpCmVZcu+KCX4g9WaRNuu11uyhiW7+Le1dKawg=
|
||||
github.com/miekg/dns v1.1.43/go.mod h1:+evo5L0630/F6ca/Z9+GAqzhjGyn8/c+TBaOyfEl0V4=
|
||||
github.com/miekg/dns v1.1.45 h1:g5fRIhm9nx7g8osrAvgb16QJfmyMsyOCb+J7LSv+Qzk=
|
||||
github.com/miekg/dns v1.1.45/go.mod h1:e3IlAVfNqAllflbibAZEWOXOQ+Ynzk/dDozDxY7XnME=
|
||||
github.com/oschwald/geoip2-golang v1.5.0 h1:igg2yQIrrcRccB1ytFXqBfOHCjXWIoMv85lVJ1ONZzw=
|
||||
github.com/oschwald/geoip2-golang v1.5.0/go.mod h1:xdvYt5xQzB8ORWFqPnqMwZpCpgNagttWdoZLlJQzg7s=
|
||||
github.com/oschwald/maxminddb-golang v1.8.0 h1:Uh/DSnGoxsyp/KYbY1AuP0tYEwfs0sCph9p/UMXK/Hk=
|
||||
github.com/oschwald/maxminddb-golang v1.8.0/go.mod h1:RXZtst0N6+FY/3qCNmZMBApR19cdQj43/NM9VkrNAis=
|
||||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
github.com/sagernet/netlink v0.0.0-20240612041022-b9a21c07ac6a h1:ObwtHN2VpqE0ZNjr6sGeT00J8uU7JF4cNUdb44/Duis=
|
||||
github.com/sagernet/netlink v0.0.0-20240612041022-b9a21c07ac6a/go.mod h1:xLnfdiJbSp8rNqYEdIW/6eDO4mVoogml14Bh2hSiFpM=
|
||||
github.com/samber/lo v1.53.0 h1:t975lj2py4kJPQ6haz1QMgtId2gtmfktACxIXArw3HM=
|
||||
github.com/samber/lo v1.53.0/go.mod h1:4+MXEGsJzbKGaUEQFKBq2xtfuznW9oz/WrgyzMzRoM0=
|
||||
github.com/sina-ghaderi/poly1305 v0.0.0-20220724002748-c5926b03988b h1:rXHg9GrUEtWZhEkrykicdND3VPjlVbYiLdX9J7gimS8=
|
||||
github.com/sina-ghaderi/poly1305 v0.0.0-20220724002748-c5926b03988b/go.mod h1:X7qrxNQViEaAN9LNZOPl9PfvQtp3V3c7LTo0dvGi0fM=
|
||||
github.com/sina-ghaderi/rabaead v0.0.0-20220730151906-ab6e06b96e8c h1:DjKMC30y6yjG3IxDaeAj3PCoRr+IsO+bzyT+Se2m2Hk=
|
||||
github.com/sina-ghaderi/rabaead v0.0.0-20220730151906-ab6e06b96e8c/go.mod h1:NV/a66PhhWYVmUMaotlXJ8fIEFB98u+c8l/CQIEFLrU=
|
||||
github.com/sina-ghaderi/rabbitio v0.0.0-20220730151941-9ce26f4f872e h1:ur8uMsPIFG3i4Gi093BQITvwH9znsz2VUZmnmwHvpIo=
|
||||
github.com/sina-ghaderi/rabbitio v0.0.0-20220730151941-9ce26f4f872e/go.mod h1:+e5fBW3bpPyo+3uLo513gIUblc03egGjMM0+5GKbzK8=
|
||||
github.com/sirupsen/logrus v1.9.4 h1:TsZE7l11zFCLZnZ+teH4Umoq5BhEIfIzfRDZ1Uzql2w=
|
||||
github.com/sirupsen/logrus v1.9.4/go.mod h1:ftWc9WdOfJ0a92nsE2jF5u5ZwH8Bv2zdeOC42RjbV2g=
|
||||
github.com/sirupsen/logrus v1.8.1 h1:dJKuHgqk1NNQlqoA6BTlM1Wf9DOH3NBjQyu0h9+AZZE=
|
||||
github.com/sirupsen/logrus v1.8.1/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0=
|
||||
github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc=
|
||||
github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA=
|
||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
|
||||
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
|
||||
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
|
||||
github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY=
|
||||
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U=
|
||||
github.com/u-root/uio v0.0.0-20230220225925-ffce2a382923 h1:tHNk7XK9GkmKUR6Gh8gVBKXc2MVSZ4G/NnWLtzw4gNA=
|
||||
github.com/u-root/uio v0.0.0-20230220225925-ffce2a382923/go.mod h1:eLL9Nub3yfAho7qB0MzZizFhTU2QkLeoVsWdHtDW264=
|
||||
github.com/vishvananda/netlink v1.1.0/go.mod h1:cTgwzPIzzgDAYoQrMm0EdrjRUBkTqKYppBueQtXaqoE=
|
||||
github.com/vishvananda/netns v0.0.0-20191106174202-0a2b9b5464df/go.mod h1:JP3t17pCcGlemwknint6hfoeCVQrEMVwxRLRjXpq+BU=
|
||||
github.com/vishvananda/netns v0.0.0-20210104183010-2eb08e3e575f/go.mod h1:DD4vA1DwXk04H54A1oHXtwZmA0grkVMdPxx/VGLCah0=
|
||||
github.com/vishvananda/netns v0.0.5 h1:DfiHV+j8bA32MFM7bfEunvT8IAqQ/NzSJHtcmW5zdEY=
|
||||
github.com/vishvananda/netns v0.0.5/go.mod h1:SpkAiCQRtJ6TvvxPnOSyH3BMl6unz3xZlaprSwhNNJM=
|
||||
github.com/vmihailenco/msgpack/v5 v5.4.1 h1:cQriyiUvjTwOHg8QZaPihLWeRAAVoCpE00IUPn0Bjt8=
|
||||
github.com/vmihailenco/msgpack/v5 v5.4.1/go.mod h1:GaZTsDaehaPpQVyxrf5mtQlH+pc21PIudVV/E3rRQok=
|
||||
github.com/vmihailenco/tagparser/v2 v2.0.0 h1:y09buUbR+b5aycVFQs/g70pqKVZNBmxwAhO7/IwNM9g=
|
||||
github.com/vmihailenco/tagparser/v2 v2.0.0/go.mod h1:Wri+At7QHww0WTrCBeu4J6bNtoV6mEfg5OIWRZA9qds=
|
||||
github.com/xtaci/lossyconn v0.0.0-20190602105132-8df528c0c9ae h1:J0GxkO96kL4WF+AIT3M4mfUVinOCPgf2uUWYFUzN0sM=
|
||||
github.com/yosida95/uritemplate/v3 v3.0.2 h1:Ed3Oyj9yrmi9087+NczuL5BwkIc4wvTb5zIM+UJPGz4=
|
||||
github.com/yosida95/uritemplate/v3 v3.0.2/go.mod h1:ILOh0sOhIJR3+L/8afwt/kE++YT040gmv5BQTMR2HP4=
|
||||
gitlab.com/go-extension/aes-ccm v0.0.0-20230221065045-e58665ef23c7 h1:UNrDfkQqiEYzdMlNsVvBYOAJWZjdktqFE9tQh5BT2+4=
|
||||
gitlab.com/go-extension/aes-ccm v0.0.0-20230221065045-e58665ef23c7/go.mod h1:E+rxHvJG9H6PUdzq9NRG6csuLN3XUx98BfGOVWNYnXs=
|
||||
gitlab.com/yawning/bsaes.git v0.0.0-20190805113838-0a714cd429ec h1:FpfFs4EhNehiVfzQttTuxanPIT43FtkkCFypIod8LHo=
|
||||
gitlab.com/yawning/bsaes.git v0.0.0-20190805113838-0a714cd429ec/go.mod h1:BZ1RAoRPbCxum9Grlv5aeksu2H8BiKehBYooU2LFiOQ=
|
||||
go.uber.org/mock v0.4.0 h1:VcM4ZOtdbR4f6VXfiOpwpVJDL6lCReaZ6mw31wqh7KU=
|
||||
go4.org/netipx v0.0.0-20231129151722-fdeea329fbba h1:0b9z3AuHCjxk0x/opv64kcgZLBseWJUpBw5I82+2U4M=
|
||||
go4.org/netipx v0.0.0-20231129151722-fdeea329fbba/go.mod h1:PLyyIXexvUFg3Owu6p/WfdlivPbZJsZdgWZlrGope/Y=
|
||||
github.com/u-root/uio v0.0.0-20210528114334-82958018845c/go.mod h1:LpEX5FO/cB+WF4TYGY1V5qktpaZLkKkSegbr0V4eYXA=
|
||||
github.com/u-root/uio v0.0.0-20210528151154-e40b768296a7 h1:XMAtQHwKjWHIRwg+8Nj/rzUomQY1q6cM3ncA0wP8GU4=
|
||||
github.com/u-root/uio v0.0.0-20210528151154-e40b768296a7/go.mod h1:LpEX5FO/cB+WF4TYGY1V5qktpaZLkKkSegbr0V4eYXA=
|
||||
github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
|
||||
go.etcd.io/bbolt v1.3.6 h1:/ecaJf0sk1l4l6V4awd65v2C3ILy7MSj+s/x1ADCIMU=
|
||||
go.etcd.io/bbolt v1.3.6/go.mod h1:qXsaaIqmgQH0T+OPdb99Bf+PKfBBQVAdyD6TY9G8XM4=
|
||||
go.uber.org/atomic v1.9.0 h1:ECmE8Bn/WFTYwEW/bpKD3M8VtR/zQVbavAoalC1PYyE=
|
||||
go.uber.org/atomic v1.9.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc=
|
||||
go.uber.org/automaxprocs v1.4.0/go.mod h1:/mTEdr7LvHhs0v7mjdxDreTz1OG5zdZGqgOnhWiR/+Q=
|
||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
golang.org/x/crypto v0.33.0 h1:IOBPskki6Lysi0lo9qQvbxiQ+FvsCC/YWOecCHAixus=
|
||||
golang.org/x/crypto v0.33.0/go.mod h1:bVdXmD7IV/4GdElGPozy6U7lWdRXA4qyRVGJV57uQ5M=
|
||||
golang.org/x/exp v0.0.0-20240904232852-e7e105dedf7e h1:I88y4caeGeuDQxgdoFPUq097j7kNfw6uvuiNxUBfcBk=
|
||||
golang.org/x/exp v0.0.0-20240904232852-e7e105dedf7e/go.mod h1:akd2r19cwCdwSwWeIdzYQGa/EZZyqcOdwWiwj5L5eKQ=
|
||||
golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=
|
||||
golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=
|
||||
golang.org/x/mod v0.20.0 h1:utOm6MM3R3dnawAiJgn0y+xvuYRsm1RKM/4giyfDgV0=
|
||||
golang.org/x/mod v0.20.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c=
|
||||
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/crypto v0.0.0-20210317152858-513c2a44f670/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4=
|
||||
golang.org/x/crypto v0.0.0-20210817164053-32db794688a5/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
|
||||
golang.org/x/crypto v0.0.0-20211215153901-e495a2d5b3d3 h1:0es+/5331RGQPcXlMfP+WrnIIS6dNnNRe0WB02W0F4M=
|
||||
golang.org/x/crypto v0.0.0-20211215153901-e495a2d5b3d3/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
|
||||
golang.org/x/mod v0.4.2 h1:Gz96sIWK3OalVv/I/qNygP42zyoKp3xptRVCWRFEBvo=
|
||||
golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||
golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||
golang.org/x/net v0.0.0-20190419010253-1f3472d942ba/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||
golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks=
|
||||
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.35.0 h1:T5GQRQb2y08kTAByq9L4/bz8cipCdA8FbRTXewonqY8=
|
||||
golang.org/x/net v0.35.0/go.mod h1:EglIi67kWsHKlRzzVMUD93VMSWGFOMSZgxFjparz1Qk=
|
||||
golang.org/x/net v0.0.0-20190827160401-ba9fcec4b297/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20191007182048-72f939374954/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20201010224723-4f7140c49acb/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
|
||||
golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
|
||||
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
|
||||
golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM=
|
||||
golang.org/x/net v0.0.0-20210726213435-c6fcb2dbf985/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
||||
golang.org/x/net v0.0.0-20210903162142-ad29c8ab022f/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
||||
golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
||||
golang.org/x/net v0.0.0-20211216030914-fe4d6282115f h1:hEYJvxw1lSnWIl8X9ofsYMklzaDs90JI2az5YMd4fPM=
|
||||
golang.org/x/net v0.0.0-20211216030914-fe4d6282115f/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
||||
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.11.0 h1:GGz8+XQP4FvTTrjZPzNKTMFtSXH80RAzG+5ghFPgK9w=
|
||||
golang.org/x/sync v0.11.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
|
||||
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c h1:5KslGYwFpkhGh+Q16bwMP3cOontH8FOep7tGV86Y7SQ=
|
||||
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190411185658-b44545bcd369/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190606203320-7fc4e5ec1444/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190804053845-51ab0e2deafa/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200217220822-9197077df867/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20220622161953-175b2fd9d664/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.30.0 h1:QjkSwP/36a20jFYWkSue1YwXzLmsV5Gfq7Eiy72C1uc=
|
||||
golang.org/x/sys v0.30.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||
golang.org/x/term v0.29.0 h1:L6pJp37ocefwRRtYPKSWOWzOtWSxVajvz2ldH/xi3iU=
|
||||
golang.org/x/sys v0.0.0-20190418153312-f0ce4c0180be/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190606122018-79a91cf218c4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190826190057-c7b8b68b1456/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20191008105621-543471e840be/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20191224085550-c709ea063b76/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200202164722-d101bd2416d5/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200923182605-d9f96fdee20d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20201009025420-dfb3f7c4e634/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20201101102859-da207088b7d1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210303074136-134d130e1a04/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20210525143221-35b2ab0089ea/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20211116061358-0a5406a5449c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e h1:fLOSk5Q00efkSvAm+4xcoXD+RRmLmmulPn5I3Y9F2EM=
|
||||
golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.22.0 h1:bofq7m3/HAFvbF51jz3Q9wLg3jkvSPuiZu/pD1XwgtM=
|
||||
golang.org/x/text v0.22.0/go.mod h1:YRoo4H8PVmsu+E3Ou7cqLVH8oXWIHVoX0jqUWALQhfY=
|
||||
golang.org/x/time v0.10.0 h1:3usCWA8tQn0L8+hFJQNgzpWbd89begxN66o1Ojdn5L4=
|
||||
golang.org/x/time v0.10.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM=
|
||||
golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
||||
golang.org/x/tools v0.24.0 h1:J1shsA93PJUEVaUSaay7UXAyE8aimq3GW0pjlolpa24=
|
||||
golang.org/x/tools v0.24.0/go.mod h1:YhNqVBIfWHdzvTLs0d8LCuMhkKUgSUKldakyV7W/WDQ=
|
||||
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/text v0.3.7 h1:olpwvP2KacW1ZWvsR7uQhoyTYvKAupfQrRGBFM352Gk=
|
||||
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
|
||||
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
|
||||
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.1.6-0.20210726203631-07bc1bf47fb2 h1:BonxutuHCTL0rBDnZlKjpGIQFTjyUVTexFOdWkB6Fg0=
|
||||
golang.org/x/tools v0.1.6-0.20210726203631-07bc1bf47fb2/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
|
||||
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
|
||||
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE=
|
||||
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY=
|
||||
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
|
||||
gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
|
||||
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo=
|
||||
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
||||
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android" >
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
package="com.github.kr328.clash.core">
|
||||
|
||||
<uses-permission android:name="android.permission.INTERNET" />
|
||||
</manifest>
|
||||
|
||||
@@ -1,50 +1,7 @@
|
||||
cmake_minimum_required(VERSION 3.0)
|
||||
|
||||
# 获取git hash
|
||||
|
||||
message(STATUS "CMAKE_CURRENT_SOURCE_DIR= ${CMAKE_CURRENT_SOURCE_DIR}")
|
||||
execute_process(
|
||||
COMMAND git submodule foreach git log -1 --format=%H
|
||||
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
|
||||
OUTPUT_VARIABLE COMMIT_HASH
|
||||
)
|
||||
string(REPLACE "\n" ";" COMMIT_HASH "${COMMIT_HASH}")
|
||||
list(GET COMMIT_HASH 1 COMMIT_HASH)
|
||||
string (REGEX REPLACE "[\n\t\r]" "" COMMIT_HASH ${COMMIT_HASH})
|
||||
string(SUBSTRING ${COMMIT_HASH} 0 7 COMMIT_HASH)
|
||||
message(STATUS "git hash= ${COMMIT_HASH}")
|
||||
|
||||
# 获取分支名称
|
||||
execute_process(
|
||||
COMMAND git submodule foreach git branch -r --contains ${COMMIT_HASH}
|
||||
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
|
||||
OUTPUT_VARIABLE CURRENT_BRANCH
|
||||
)
|
||||
string(REPLACE "\n" ";" CURRENT_BRANCH "${CURRENT_BRANCH}")
|
||||
list(GET CURRENT_BRANCH 1 CURRENT_BRANCH)
|
||||
string (REGEX REPLACE "origin/" "" CURRENT_BRANCH ${CURRENT_BRANCH})
|
||||
string (REGEX REPLACE "[\n\t\r]" "" CURRENT_BRANCH ${CURRENT_BRANCH})
|
||||
#string(SUBSTRING ${CURRENT_BRANCH} 0 8 CURRENT_BRANCH)
|
||||
message(STATUS "git current branch = ${CURRENT_BRANCH}")
|
||||
|
||||
# 获取生成时间
|
||||
string(TIMESTAMP COMPILE_TIME "%y%m%d")
|
||||
string (REGEX REPLACE "[\n\t\r]" "" COMPILE_TIME ${COMPILE_TIME})
|
||||
string(REGEX REPLACE "\"" "" COMPILE_TIME ${COMPILE_TIME})
|
||||
|
||||
# 生成版本信息
|
||||
set(GIT_VERSION "${CURRENT_BRANCH}_${COMMIT_HASH}_${COMPILE_TIME}")
|
||||
message(STATUS "version info = ${GIT_VERSION}")
|
||||
|
||||
# 去除空格
|
||||
string(REGEX REPLACE "[ ]+" "" GIT_VERSION "${GIT_VERSION}")
|
||||
|
||||
# 保存变量到文件
|
||||
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/version.h.in ${CMAKE_CURRENT_SOURCE_DIR}/version.h @ONLY)
|
||||
|
||||
project(clash-bridge C)
|
||||
|
||||
|
||||
set(CMAKE_POSITION_INDEPENDENT_CODE on)
|
||||
set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} -O3")
|
||||
|
||||
@@ -66,4 +23,4 @@ include_directories("${GO_SOURCE}")
|
||||
link_directories("${GO_OUTPUT_BASE}/${CMAKE_ANDROID_ARCH_ABI}")
|
||||
|
||||
add_library(bridge SHARED main.c jni_helper.c bridge_helper.c)
|
||||
target_link_libraries(bridge log clash)
|
||||
target_link_libraries(bridge log clash)
|
||||
@@ -8,9 +8,6 @@
|
||||
#include "jni_helper.h"
|
||||
#include "trace.h"
|
||||
|
||||
#include "version.h" // 添加当前编译core版本号变量
|
||||
|
||||
|
||||
JNIEXPORT void JNICALL
|
||||
Java_com_github_kr328_clash_core_bridge_Bridge_nativeInit(JNIEnv *env, jobject thiz,
|
||||
jstring home,
|
||||
@@ -19,9 +16,8 @@ Java_com_github_kr328_clash_core_bridge_Bridge_nativeInit(JNIEnv *env, jobject t
|
||||
|
||||
scoped_string _home = get_string(home);
|
||||
scoped_string _version_name = get_string(version_name);
|
||||
char* _git_version = make_String(GIT_VERSION);
|
||||
|
||||
coreInit(_home, _version_name, _git_version, sdk_version);
|
||||
coreInit(_home, _version_name, sdk_version);
|
||||
}
|
||||
|
||||
JNIEXPORT void JNICALL
|
||||
@@ -112,20 +108,18 @@ Java_com_github_kr328_clash_core_bridge_Bridge_nativeNotifyInstalledAppChanged(J
|
||||
JNIEXPORT void JNICALL
|
||||
Java_com_github_kr328_clash_core_bridge_Bridge_nativeStartTun(JNIEnv *env, jobject thiz,
|
||||
jint fd,
|
||||
jstring stack,
|
||||
jstring gateway,
|
||||
jstring portal,
|
||||
jstring dns,
|
||||
jobject cb) {
|
||||
TRACE_METHOD();
|
||||
|
||||
scoped_string _stack = get_string(stack);
|
||||
scoped_string _gateway = get_string(gateway);
|
||||
scoped_string _portal = get_string(portal);
|
||||
scoped_string _dns = get_string(dns);
|
||||
jobject _interface = new_global(cb);
|
||||
|
||||
startTun(fd, _stack, _gateway, _portal, _dns, _interface);
|
||||
startTun(fd, _gateway, _portal, _dns, _interface);
|
||||
}
|
||||
|
||||
JNIEXPORT void JNICALL
|
||||
@@ -290,6 +284,33 @@ Java_com_github_kr328_clash_core_bridge_Bridge_nativeClearOverride(JNIEnv *env,
|
||||
clearOverride(slot);
|
||||
}
|
||||
|
||||
JNIEXPORT void JNICALL
|
||||
Java_com_github_kr328_clash_core_bridge_Bridge_nativeInstallSideloadGeoip(JNIEnv *env, jobject thiz,
|
||||
jbyteArray data) {
|
||||
TRACE_METHOD();
|
||||
|
||||
if (data == NULL) {
|
||||
installSideloadGeoip(NULL, 0);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
jbyte *bytes = (*env)->GetByteArrayElements(env, data, NULL);
|
||||
int size = (*env)->GetArrayLength(env, data);
|
||||
|
||||
scoped_string err = installSideloadGeoip(bytes, size);
|
||||
|
||||
(*env)->ReleaseByteArrayElements(env, data, bytes, JNI_ABORT);
|
||||
|
||||
if (err != NULL) {
|
||||
(*env)->ThrowNew(
|
||||
env,
|
||||
find_class("com/github/kr328/clash/core/bridge/ClashException"),
|
||||
err
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
JNIEXPORT jstring JNICALL
|
||||
Java_com_github_kr328_clash_core_bridge_Bridge_nativeQueryConfiguration(JNIEnv *env, jobject thiz) {
|
||||
TRACE_METHOD();
|
||||
@@ -309,7 +330,6 @@ Java_com_github_kr328_clash_core_bridge_Bridge_nativeSubscribeLogcat(JNIEnv *env
|
||||
subscribeLogcat(_callback);
|
||||
}
|
||||
|
||||
|
||||
static jmethodID m_tun_interface_mark_socket;
|
||||
static jmethodID m_tun_interface_query_socket_uid;
|
||||
static jmethodID m_completable_complete;
|
||||
@@ -517,13 +537,4 @@ JNI_OnLoad(JavaVM *vm, void *reserved) {
|
||||
release_object_func = &release_jni_object_impl;
|
||||
|
||||
return JNI_VERSION_1_6;
|
||||
}
|
||||
|
||||
JNIEXPORT jstring JNICALL
|
||||
Java_com_github_kr328_clash_core_bridge_Bridge_nativeCoreVersion(JNIEnv *env, jobject thiz) {
|
||||
TRACE_METHOD();
|
||||
|
||||
char* Version = make_String(GIT_VERSION);
|
||||
|
||||
return new_string(Version);
|
||||
}
|
||||
@@ -1,12 +0,0 @@
|
||||
#ifndef VERSION_H_IN
|
||||
#define VERSION_H_IN
|
||||
|
||||
/**
|
||||
* 当前编译core版本号
|
||||
*/
|
||||
|
||||
#define GIT_VERSION @GIT_VERSION@
|
||||
#define make_Str(x) #x
|
||||
#define make_String(x) make_Str(x)
|
||||
|
||||
#endif
|
||||
@@ -5,6 +5,7 @@
|
||||
<option name="MOVE_ALL_IMPORTS_IN_ONE_DECLARATION" value="true" />
|
||||
<option name="MOVE_ALL_STDLIB_IMPORTS_IN_ONE_GROUP" value="true" />
|
||||
<option name="GROUP_STDLIB_IMPORTS" value="true" />
|
||||
<option name="GROUP_CURRENT_PROJECT_IMPORTS" value="true" />
|
||||
</GoCodeStyleSettings>
|
||||
</code_scheme>
|
||||
</component>
|
||||
@@ -1,116 +1,28 @@
|
||||
module cfa
|
||||
|
||||
go 1.20
|
||||
go 1.17
|
||||
|
||||
require (
|
||||
github.com/dlclark/regexp2 v1.12.0
|
||||
github.com/metacubex/mihomo v1.7.0
|
||||
golang.org/x/sync v0.11.0
|
||||
github.com/Dreamacro/clash v1.7.1
|
||||
github.com/Kr328/tun2socket v0.0.0-20211231120722-962f339492e8
|
||||
github.com/dlclark/regexp2 v1.4.0
|
||||
github.com/miekg/dns v1.1.43
|
||||
github.com/oschwald/geoip2-golang v1.5.0
|
||||
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c
|
||||
gopkg.in/yaml.v2 v2.4.0
|
||||
)
|
||||
|
||||
replace github.com/metacubex/mihomo => ../../foss/golang/clash
|
||||
|
||||
require (
|
||||
github.com/RyuaNerin/go-krypto v1.3.0 // indirect
|
||||
github.com/Yawning/aez v0.0.0-20211027044916-e49e68abd344 // indirect
|
||||
github.com/ajg/form v1.5.1 // indirect
|
||||
github.com/andybalholm/brotli v1.0.6 // indirect
|
||||
github.com/bahlo/generic-list-go v0.2.0 // indirect
|
||||
github.com/coreos/go-iptables v0.8.0 // indirect
|
||||
github.com/dunglas/httpsfv v1.0.2 // indirect
|
||||
github.com/enfein/mieru/v3 v3.31.0 // indirect
|
||||
github.com/ericlagergren/aegis v0.0.0-20250325060835-cd0defd64358 // indirect
|
||||
github.com/ericlagergren/polyval v0.0.0-20220411101811-e25bc10ba391 // indirect
|
||||
github.com/ericlagergren/siv v0.0.0-20220507050439-0b757b3aa5f1 // indirect
|
||||
github.com/ericlagergren/subtle v0.0.0-20220507045147-890d697da010 // indirect
|
||||
github.com/fsnotify/fsnotify v1.9.0 // indirect
|
||||
github.com/gaukas/godicttls v0.0.4 // indirect
|
||||
github.com/go-ole/go-ole v1.3.0 // indirect
|
||||
github.com/gobwas/httphead v0.1.0 // indirect
|
||||
github.com/gobwas/pool v0.2.1 // indirect
|
||||
github.com/gobwas/ws v1.4.0 // indirect
|
||||
github.com/gofrs/uuid/v5 v5.4.0 // indirect
|
||||
github.com/golang/snappy v1.0.0 // indirect
|
||||
github.com/google/btree v1.1.3 // indirect
|
||||
github.com/google/go-cmp v0.6.0 // indirect
|
||||
github.com/google/pprof v0.0.0-20240727154555-813a5fbdbec8 // indirect
|
||||
github.com/insomniacslk/dhcp v0.0.0-20250109001534-8abf58130905 // indirect
|
||||
github.com/josharian/native v1.1.0 // indirect
|
||||
github.com/klauspost/compress v1.17.9 // indirect
|
||||
github.com/klauspost/cpuid/v2 v2.2.6 // indirect
|
||||
github.com/klauspost/reedsolomon v1.12.3 // indirect
|
||||
github.com/mdlayher/netlink v1.7.2 // indirect
|
||||
github.com/mdlayher/socket v0.5.1 // indirect
|
||||
github.com/metacubex/amneziawg-go v0.0.0-20251104174305-5a0e9f7e361d // indirect
|
||||
github.com/metacubex/ascon v0.1.0 // indirect
|
||||
github.com/metacubex/bart v0.26.0 // indirect
|
||||
github.com/metacubex/bbolt v0.0.0-20250725135710-010dbbbb7a5b // indirect
|
||||
github.com/metacubex/blake3 v0.1.0 // indirect
|
||||
github.com/metacubex/chacha v0.1.5 // indirect
|
||||
github.com/metacubex/chi v0.1.0 // indirect
|
||||
github.com/metacubex/connect-ip-go v0.0.0-20260412152424-e1625567920a // indirect
|
||||
github.com/metacubex/cpu v0.1.1 // indirect
|
||||
github.com/metacubex/edwards25519 v1.2.0 // indirect
|
||||
github.com/metacubex/fswatch v0.1.1 // indirect
|
||||
github.com/metacubex/gopacket v1.1.20-0.20230608035415-7e2f98a3e759 // indirect
|
||||
github.com/metacubex/gvisor v0.0.0-20251227095601-261ec1326fe8 // indirect
|
||||
github.com/metacubex/hkdf v0.1.0 // indirect
|
||||
github.com/metacubex/hpke v0.1.0 // indirect
|
||||
github.com/metacubex/http v0.1.4 // indirect
|
||||
github.com/metacubex/kcp-go v0.0.0-20260105040817-550693377604 // indirect
|
||||
github.com/metacubex/mhurl v0.1.0 // indirect
|
||||
github.com/metacubex/mlkem v0.1.0 // indirect
|
||||
github.com/metacubex/nftables v0.0.0-20260426003805-208c2c1ba2cb // indirect
|
||||
github.com/metacubex/qpack v0.6.0 // indirect
|
||||
github.com/metacubex/quic-go v0.59.1-0.20260413153657-53bb22f2c306 // indirect
|
||||
github.com/metacubex/randv2 v0.2.0 // indirect
|
||||
github.com/metacubex/restls-client-go v0.1.7 // indirect
|
||||
github.com/metacubex/sing v0.5.7 // indirect
|
||||
github.com/metacubex/sing-mux v0.3.9 // indirect
|
||||
github.com/metacubex/sing-quic v0.0.0-20260414034501-3ea3410d197a // indirect
|
||||
github.com/metacubex/sing-shadowsocks v0.2.12 // indirect
|
||||
github.com/metacubex/sing-shadowsocks2 v0.2.7 // indirect
|
||||
github.com/metacubex/sing-shadowtls v0.0.0-20250503063515-5d9f966d17a2 // indirect
|
||||
github.com/metacubex/sing-tun v0.4.18 // indirect
|
||||
github.com/metacubex/sing-vmess v0.2.5 // indirect
|
||||
github.com/metacubex/sing-wireguard v0.0.0-20260507084707-690d479ec947 // indirect
|
||||
github.com/metacubex/smux v0.0.0-20260105030934-d0c8756d3141 // indirect
|
||||
github.com/metacubex/ssh v0.1.0 // indirect
|
||||
github.com/metacubex/tfo-go v0.0.0-20251130171125-413e892ac443 // indirect
|
||||
github.com/metacubex/tls v0.1.5 // indirect
|
||||
github.com/metacubex/utls v1.8.4 // indirect
|
||||
github.com/metacubex/wireguard-go v0.0.0-20250820062549-a6cecdd7f57f // indirect
|
||||
github.com/metacubex/yamux v0.0.0-20250918083631-dd5f17c0be49 // indirect
|
||||
github.com/miekg/dns v1.1.63 // indirect
|
||||
github.com/mroth/weightedrand/v2 v2.1.0 // indirect
|
||||
github.com/oasisprotocol/deoxysii v0.0.0-20220228165953-2091330c22b7 // indirect
|
||||
github.com/openacid/low v0.1.21 // indirect
|
||||
github.com/oschwald/maxminddb-golang v1.12.0 // indirect
|
||||
github.com/pierrec/lz4/v4 v4.1.14 // indirect
|
||||
github.com/sagernet/netlink v0.0.0-20240612041022-b9a21c07ac6a // indirect
|
||||
github.com/samber/lo v1.53.0 // indirect
|
||||
github.com/sina-ghaderi/poly1305 v0.0.0-20220724002748-c5926b03988b // indirect
|
||||
github.com/sina-ghaderi/rabaead v0.0.0-20220730151906-ab6e06b96e8c // indirect
|
||||
github.com/sina-ghaderi/rabbitio v0.0.0-20220730151941-9ce26f4f872e // indirect
|
||||
github.com/sirupsen/logrus v1.9.4 // indirect
|
||||
github.com/u-root/uio v0.0.0-20230220225925-ffce2a382923 // indirect
|
||||
github.com/vishvananda/netns v0.0.5 // indirect
|
||||
github.com/vmihailenco/msgpack/v5 v5.4.1 // indirect
|
||||
github.com/vmihailenco/tagparser/v2 v2.0.0 // indirect
|
||||
github.com/yosida95/uritemplate/v3 v3.0.2 // indirect
|
||||
gitlab.com/go-extension/aes-ccm v0.0.0-20230221065045-e58665ef23c7 // indirect
|
||||
gitlab.com/yawning/bsaes.git v0.0.0-20190805113838-0a714cd429ec // indirect
|
||||
go4.org/netipx v0.0.0-20231129151722-fdeea329fbba // indirect
|
||||
golang.org/x/crypto v0.33.0 // indirect
|
||||
golang.org/x/exp v0.0.0-20240904232852-e7e105dedf7e // indirect
|
||||
golang.org/x/mod v0.20.0 // indirect
|
||||
golang.org/x/net v0.35.0 // indirect
|
||||
golang.org/x/sys v0.30.0 // indirect
|
||||
golang.org/x/text v0.22.0 // indirect
|
||||
golang.org/x/time v0.10.0 // indirect
|
||||
golang.org/x/tools v0.24.0 // indirect
|
||||
google.golang.org/protobuf v1.34.2 // indirect
|
||||
gopkg.in/yaml.v3 v3.0.1 // indirect
|
||||
github.com/Dreamacro/go-shadowsocks2 v0.1.7 // indirect
|
||||
github.com/gofrs/uuid v4.0.0+incompatible // indirect
|
||||
github.com/gorilla/websocket v1.4.2 // indirect
|
||||
github.com/insomniacslk/dhcp v0.0.0-20210827173440-b95caade3eac // indirect
|
||||
github.com/oschwald/maxminddb-golang v1.8.0 // indirect
|
||||
github.com/sirupsen/logrus v1.8.1 // indirect
|
||||
github.com/u-root/uio v0.0.0-20210528114334-82958018845c // indirect
|
||||
go.uber.org/atomic v1.9.0 // indirect
|
||||
golang.org/x/crypto v0.0.0-20210817164053-32db794688a5 // indirect
|
||||
golang.org/x/net v0.0.0-20210903162142-ad29c8ab022f // indirect
|
||||
golang.org/x/sys v0.0.0-20211116061358-0a5406a5449c // indirect
|
||||
golang.org/x/text v0.3.6 // indirect
|
||||
)
|
||||
|
||||
replace google.golang.org/protobuf => github.com/metacubex/protobuf-go v0.0.0-20260306035419-7ceee0674686
|
||||
|
||||
@@ -1,251 +1,117 @@
|
||||
github.com/RyuaNerin/go-krypto v1.3.0 h1:smavTzSMAx8iuVlGb4pEwl9MD2qicqMzuXR2QWp2/Pg=
|
||||
github.com/RyuaNerin/go-krypto v1.3.0/go.mod h1:9R9TU936laAIqAmjcHo/LsaXYOZlymudOAxjaBf62UM=
|
||||
github.com/RyuaNerin/testingutil v0.1.0 h1:IYT6JL57RV3U2ml3dLHZsVtPOP6yNK7WUVdzzlpNrss=
|
||||
github.com/Yawning/aez v0.0.0-20211027044916-e49e68abd344 h1:cDVUiFo+npB0ZASqnw4q90ylaVAbnYyx0JYqK4YcGok=
|
||||
github.com/Yawning/aez v0.0.0-20211027044916-e49e68abd344/go.mod h1:9pIqrY6SXNL8vjRQE5Hd/OL5GyK/9MrGUWs87z/eFfk=
|
||||
github.com/ajg/form v1.5.1 h1:t9c7v8JUKu/XxOGBU0yjNpaMloxGEJhUkqFRq0ibGeU=
|
||||
github.com/ajg/form v1.5.1/go.mod h1:uL1WgH+h2mgNtvBq0339dVnzXdBETtL2LeUXaIv25UY=
|
||||
github.com/andybalholm/brotli v1.0.6 h1:Yf9fFpf49Zrxb9NlQaluyE92/+X7UVHlhMNJN2sxfOI=
|
||||
github.com/andybalholm/brotli v1.0.6/go.mod h1:fO7iG3H7G2nSZ7m0zPUDn85XEX2GTukHGRSepvi9Eig=
|
||||
github.com/bahlo/generic-list-go v0.2.0 h1:5sz/EEAK+ls5wF+NeqDpk5+iNdMDXrh3z3nPnH1Wvgk=
|
||||
github.com/bahlo/generic-list-go v0.2.0/go.mod h1:2KvAjgMlE5NNynlg/5iLrrCCZ2+5xWbdbCW3pNTGyYg=
|
||||
github.com/blang/semver v3.5.1+incompatible/go.mod h1:kRBLl5iJ+tD4TcOOxsy/0fnwebNt5EWlYSAyrTnjyyk=
|
||||
github.com/coreos/go-iptables v0.8.0 h1:MPc2P89IhuVpLI7ETL/2tx3XZ61VeICZjYqDEgNsPRc=
|
||||
github.com/coreos/go-iptables v0.8.0/go.mod h1:Qe8Bv2Xik5FyTXwgIbLAnv2sWSBmvWdFETJConOQ//Q=
|
||||
github.com/Dreamacro/clash v1.7.1 h1:8iYYiyVf7ZAztwoFeTFihs5rI9Jjic0ZKmf05vQxzFU=
|
||||
github.com/Dreamacro/clash v1.7.1/go.mod h1:C9eLMAlDZSLrkdzGQdOHyeldwRjDbcGR2kaL80KdzGw=
|
||||
github.com/Dreamacro/go-shadowsocks2 v0.1.7 h1:8CtbE1HoPPMfrQZGXmlluq6dO2lL31W6WRRE8fabc4Q=
|
||||
github.com/Dreamacro/go-shadowsocks2 v0.1.7/go.mod h1:8p5G4cAj5ZlXwUR+Ww63gfSikr8kvw8uw3TDwLAJpUc=
|
||||
github.com/Kr328/tun2socket v0.0.0-20211231120722-962f339492e8 h1:4Ceb/pU/u7fKGMCE2DNrWIEHkoR1ELRlYJXzbFOR+E0=
|
||||
github.com/Kr328/tun2socket v0.0.0-20211231120722-962f339492e8/go.mod h1:YR9wK13TgI5ww8iKWm91MHiSoHC7Oz0U4beCCmtXqLw=
|
||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
||||
github.com/dlclark/regexp2 v1.12.0 h1:0j4c5qQmnC6XOWNjP3PIXURXN2gWx76rd3KvgdPkCz8=
|
||||
github.com/dlclark/regexp2 v1.12.0/go.mod h1:DHkYz0B9wPfa6wondMfaivmHpzrQ3v9q8cnmRbL6yW8=
|
||||
github.com/dunglas/httpsfv v1.0.2 h1:iERDp/YAfnojSDJ7PW3dj1AReJz4MrwbECSSE59JWL0=
|
||||
github.com/dunglas/httpsfv v1.0.2/go.mod h1:zID2mqw9mFsnt7YC3vYQ9/cjq30q41W+1AnDwH8TiMg=
|
||||
github.com/enfein/mieru/v3 v3.31.0 h1:Fl2ocRCRXJzMygzdRjBHgqI996ZuIDHUmyQyovSf9sA=
|
||||
github.com/enfein/mieru/v3 v3.31.0/go.mod h1:zJBUCsi5rxyvHM8fjFf+GLaEl4OEjjBXr1s5F6Qd3hM=
|
||||
github.com/ericlagergren/aegis v0.0.0-20250325060835-cd0defd64358 h1:kXYqH/sL8dS/FdoFjr12ePjnLPorPo2FsnrHNuXSDyo=
|
||||
github.com/ericlagergren/aegis v0.0.0-20250325060835-cd0defd64358/go.mod h1:hkIFzoiIPZYxdFOOLyDho59b7SrDfo+w3h+yWdlg45I=
|
||||
github.com/ericlagergren/polyval v0.0.0-20220411101811-e25bc10ba391 h1:8j2RH289RJplhA6WfdaPqzg1MjH2K8wX5e0uhAxrw2g=
|
||||
github.com/ericlagergren/polyval v0.0.0-20220411101811-e25bc10ba391/go.mod h1:K2R7GhgxrlJzHw2qiPWsCZXf/kXEJN9PLnQK73Ll0po=
|
||||
github.com/ericlagergren/saferand v0.0.0-20220206064634-960a4dd2bc5c h1:RUzBDdZ+e/HEe2Nh8lYsduiPAZygUfVXJn0Ncj5sHMg=
|
||||
github.com/ericlagergren/siv v0.0.0-20220507050439-0b757b3aa5f1 h1:tlDMEdcPRQKBEz5nGDMvswiajqh7k8ogWRlhRwKy5mY=
|
||||
github.com/ericlagergren/siv v0.0.0-20220507050439-0b757b3aa5f1/go.mod h1:4RfsapbGx2j/vU5xC/5/9qB3kn9Awp1YDiEnN43QrJ4=
|
||||
github.com/ericlagergren/subtle v0.0.0-20220507045147-890d697da010 h1:fuGucgPk5dN6wzfnxl3D0D3rVLw4v2SbBT9jb4VnxzA=
|
||||
github.com/ericlagergren/subtle v0.0.0-20220507045147-890d697da010/go.mod h1:JtBcj7sBuTTRupn7c2bFspMDIObMJsVK8TeUvpShPok=
|
||||
github.com/fsnotify/fsnotify v1.9.0 h1:2Ml+OJNzbYCTzsxtv8vKSFD9PbJjmhYF14k/jKC7S9k=
|
||||
github.com/fsnotify/fsnotify v1.9.0/go.mod h1:8jBTzvmWwFyi3Pb8djgCCO5IBqzKJ/Jwo8TRcHyHii0=
|
||||
github.com/gaukas/godicttls v0.0.4 h1:NlRaXb3J6hAnTmWdsEKb9bcSBD6BvcIjdGdeb0zfXbk=
|
||||
github.com/gaukas/godicttls v0.0.4/go.mod h1:l6EenT4TLWgTdwslVb4sEMOCf7Bv0JAK67deKr9/NCI=
|
||||
github.com/go-ole/go-ole v1.3.0 h1:Dt6ye7+vXGIKZ7Xtk4s6/xVdGDQynvom7xCFEdWr6uE=
|
||||
github.com/go-ole/go-ole v1.3.0/go.mod h1:5LS6F96DhAwUc7C+1HLexzMXY1xGRSryjyPPKW6zv78=
|
||||
github.com/gobwas/httphead v0.1.0 h1:exrUm0f4YX0L7EBwZHuCF4GDp8aJfVeBrlLQrs6NqWU=
|
||||
github.com/gobwas/httphead v0.1.0/go.mod h1:O/RXo79gxV8G+RqlR/otEwx4Q36zl9rqC5u12GKvMCM=
|
||||
github.com/gobwas/pool v0.2.1 h1:xfeeEhW7pwmX8nuLVlqbzVc7udMDrwetjEv+TZIz1og=
|
||||
github.com/gobwas/pool v0.2.1/go.mod h1:q8bcK0KcYlCgd9e7WYLm9LpyS+YeLd8JVDW6WezmKEw=
|
||||
github.com/gobwas/ws v1.4.0 h1:CTaoG1tojrh4ucGPcoJFiAQUAsEWekEWvLy7GsVNqGs=
|
||||
github.com/gobwas/ws v1.4.0/go.mod h1:G3gNqMNtPppf5XUz7O4shetPpcZ1VJ7zt18dlUeakrc=
|
||||
github.com/gofrs/uuid/v5 v5.4.0 h1:EfbpCTjqMuGyq5ZJwxqzn3Cbr2d0rUZU7v5ycAk/e/0=
|
||||
github.com/gofrs/uuid/v5 v5.4.0/go.mod h1:CDOjlDMVAtN56jqyRUZh58JT31Tiw7/oQyEXZV+9bD8=
|
||||
github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||
github.com/golang/snappy v1.0.0 h1:Oy607GVXHs7RtbggtPBnr2RmDArIsAefDwvrdWvRhGs=
|
||||
github.com/golang/snappy v1.0.0/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
|
||||
github.com/google/btree v1.1.3 h1:CVpQJjYgC4VbzxeGVHfvZrv1ctoYCAI8vbl07Fcxlyg=
|
||||
github.com/google/btree v1.1.3/go.mod h1:qOPhT0dTNdNzV6Z/lhRX0YXUafgPLFUh+gZMl761Gm4=
|
||||
github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=
|
||||
github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
|
||||
github.com/google/pprof v0.0.0-20240727154555-813a5fbdbec8 h1:FKHo8hFI3A+7w0aUQuYXQ+6EN5stWmeY/AZqtM8xk9k=
|
||||
github.com/google/pprof v0.0.0-20240727154555-813a5fbdbec8/go.mod h1:K1liHPHnj73Fdn/EKuT8nrFqBihUSKXoLYU0BuatOYo=
|
||||
github.com/google/tink/go v1.6.1 h1:t7JHqO8Ath2w2ig5vjwQYJzhGEZymedQc90lQXUBa4I=
|
||||
github.com/insomniacslk/dhcp v0.0.0-20250109001534-8abf58130905 h1:q3OEI9RaN/wwcx+qgGo6ZaoJkCiDYe/gjDLfq7lQQF4=
|
||||
github.com/insomniacslk/dhcp v0.0.0-20250109001534-8abf58130905/go.mod h1:VvGYjkZoJyKqlmT1yzakUs4mfKMNB0XdODP0+rdml6k=
|
||||
github.com/josharian/native v1.0.1-0.20221213033349-c1e37c09b531/go.mod h1:7X/raswPFr05uY3HiLlYeyQntB6OO7E/d2Cu7qoaN2w=
|
||||
github.com/josharian/native v1.1.0 h1:uuaP0hAbW7Y4l0ZRQ6C9zfb7Mg1mbFKry/xzDAfmtLA=
|
||||
github.com/josharian/native v1.1.0/go.mod h1:7X/raswPFr05uY3HiLlYeyQntB6OO7E/d2Cu7qoaN2w=
|
||||
github.com/klauspost/compress v1.17.9 h1:6KIumPrER1LHsvBVuDa0r5xaG0Es51mhhB9BQB2qeMA=
|
||||
github.com/klauspost/compress v1.17.9/go.mod h1:Di0epgTjJY877eYKx5yC51cX2A2Vl2ibi7bDH9ttBbw=
|
||||
github.com/klauspost/cpuid/v2 v2.2.6 h1:ndNyv040zDGIDh8thGkXYjnFtiN02M1PVVF+JE/48xc=
|
||||
github.com/klauspost/cpuid/v2 v2.2.6/go.mod h1:Lcz8mBdAVJIBVzewtcLocK12l3Y+JytZYpaMropDUws=
|
||||
github.com/klauspost/reedsolomon v1.12.3 h1:tzUznbfc3OFwJaTebv/QdhnFf2Xvb7gZ24XaHLBPmdc=
|
||||
github.com/klauspost/reedsolomon v1.12.3/go.mod h1:3K5rXwABAvzGeR01r6pWZieUALXO/Tq7bFKGIb4m4WI=
|
||||
github.com/mdlayher/netlink v1.7.2 h1:/UtM3ofJap7Vl4QWCPDGXY8d3GIY2UGSDbK+QWmY8/g=
|
||||
github.com/mdlayher/netlink v1.7.2/go.mod h1:xraEF7uJbxLhc5fpHL4cPe221LI2bdttWlU+ZGLfQSw=
|
||||
github.com/mdlayher/socket v0.5.1 h1:VZaqt6RkGkt2OE9l3GcC6nZkqD3xKeQLyfleW/uBcos=
|
||||
github.com/mdlayher/socket v0.5.1/go.mod h1:TjPLHI1UgwEv5J1B5q0zTZq12A/6H7nKmtTanQE37IQ=
|
||||
github.com/metacubex/amneziawg-go v0.0.0-20251104174305-5a0e9f7e361d h1:vAJ0ZT4aO803F1uw2roIA9yH7Sxzox34tVVyye1bz6c=
|
||||
github.com/metacubex/amneziawg-go v0.0.0-20251104174305-5a0e9f7e361d/go.mod h1:MsM/5czONyXMJ3PRr5DbQ4O/BxzAnJWOIcJdLzW6qHY=
|
||||
github.com/metacubex/ascon v0.1.0 h1:6ZWxmXYszT1XXtwkf6nxfFhc/OTtQ9R3Vyj1jN32lGM=
|
||||
github.com/metacubex/ascon v0.1.0/go.mod h1:eV5oim4cVPPdEL8/EYaTZ0iIKARH9pnhAK/fcT5Kacc=
|
||||
github.com/metacubex/bart v0.26.0 h1:d/bBTvVatfVWGfQbiDpYKI1bXUJgjaabB2KpK1Tnk6w=
|
||||
github.com/metacubex/bart v0.26.0/go.mod h1:DCcyfP4MC+Zy7sLK7XeGuMw+P5K9mIRsYOBgiE8icsI=
|
||||
github.com/metacubex/bbolt v0.0.0-20250725135710-010dbbbb7a5b h1:j7dadXD8I2KTmMt8jg1JcaP1ANL3JEObJPdANKcSYPY=
|
||||
github.com/metacubex/bbolt v0.0.0-20250725135710-010dbbbb7a5b/go.mod h1:+WmP0VJZDkDszvpa83HzfUp6QzARl/IKkMorH4+nODw=
|
||||
github.com/metacubex/blake3 v0.1.0 h1:KGnjh/56REO7U+cgZA8dnBhxdP7jByrG7hTP+bu6cqY=
|
||||
github.com/metacubex/blake3 v0.1.0/go.mod h1:CCkLdzFrqf7xmxCdhQFvJsRRV2mwOLDoSPg6vUTB9Uk=
|
||||
github.com/metacubex/chacha v0.1.5 h1:fKWMb/5c7ZrY8Uoqi79PPFxl+qwR7X/q0OrsAubyX2M=
|
||||
github.com/metacubex/chacha v0.1.5/go.mod h1:Djn9bPZxLTXbJFSeyo0/qzEzQI+gUSSzttuzZM75GH8=
|
||||
github.com/metacubex/chi v0.1.0 h1:rjNDyDj50nRpicG43CNkIw4ssiCbmDL8d7wJXKlUCsg=
|
||||
github.com/metacubex/chi v0.1.0/go.mod h1:zM5u5oMQt8b2DjvDHvzadKrP6B2ztmasL1YHRMbVV+g=
|
||||
github.com/metacubex/connect-ip-go v0.0.0-20260412152424-e1625567920a h1:Ph5UfTWDsGruZ+v95Df1ycTflQFmpZBFg2LUvj2kx/M=
|
||||
github.com/metacubex/connect-ip-go v0.0.0-20260412152424-e1625567920a/go.mod h1:xYC8Ik7/rN6no+vTRuWMEziGwm3brA0wNM/zZP9qhOQ=
|
||||
github.com/metacubex/cpu v0.1.1 h1:rRV5HGmeuGzjiKI3hYbL0dCd0qGwM7VUtk4ICXD06mI=
|
||||
github.com/metacubex/cpu v0.1.1/go.mod h1:09VEt4dSRLR+bOA8l4w4NDuzGZ8n5dkMv7e8axgEeTU=
|
||||
github.com/metacubex/edwards25519 v1.2.0 h1:pIQZLBsjQgg3Nl/c86YYFEUAbL5qQRnPq4LrgIw0KK4=
|
||||
github.com/metacubex/edwards25519 v1.2.0/go.mod h1:NCQF3J/Ki7382FJuokwsywEIIEI/gro/3smyXgQJsx0=
|
||||
github.com/metacubex/fswatch v0.1.1 h1:jqU7C/v+g0qc2RUFgmAOPoVvfl2BXXUXEumn6oQuxhU=
|
||||
github.com/metacubex/fswatch v0.1.1/go.mod h1:czrTT7Zlbz7vWft8RQu9Qqh+JoX+Nnb+UabuyN1YsgI=
|
||||
github.com/metacubex/gopacket v1.1.20-0.20230608035415-7e2f98a3e759 h1:cjd4biTvOzK9ubNCCkQ+ldc4YSH/rILn53l/xGBFHHI=
|
||||
github.com/metacubex/gopacket v1.1.20-0.20230608035415-7e2f98a3e759/go.mod h1:UHOv2xu+RIgLwpXca7TLrXleEd4oR3sPatW6IF8wU88=
|
||||
github.com/metacubex/gvisor v0.0.0-20251227095601-261ec1326fe8 h1:hUL81H0Ic/XIDkvtn9M1pmfDdfid7JzYQToY4Ps1TvQ=
|
||||
github.com/metacubex/gvisor v0.0.0-20251227095601-261ec1326fe8/go.mod h1:8LpS0IJW1VmWzUm3ylb0e2SK5QDm5lO/2qwWLZgRpBU=
|
||||
github.com/metacubex/hkdf v0.1.0 h1:fPA6VzXK8cU1foc/TOmGCDmSa7pZbxlnqhl3RNsthaA=
|
||||
github.com/metacubex/hkdf v0.1.0/go.mod h1:3seEfds3smgTAXqUGn+tgEJH3uXdsUjOiduG/2EtvZ4=
|
||||
github.com/metacubex/hpke v0.1.0 h1:gu2jUNhraehWi0P/z5HX2md3d7L1FhPQE6/Q0E9r9xQ=
|
||||
github.com/metacubex/hpke v0.1.0/go.mod h1:vfDm6gfgrwlXUxKDkWbcE44hXtmc1uxLDm2BcR11b3U=
|
||||
github.com/metacubex/http v0.1.4 h1:gU1y8WlqslzxGmedW2ah74fGL6wJYU2HXUkCMJtCa2A=
|
||||
github.com/metacubex/http v0.1.4/go.mod h1:Nxx0zZAo2AhRfanyL+fmmK6ACMtVsfpwIl1aFAik2Eg=
|
||||
github.com/metacubex/kcp-go v0.0.0-20260105040817-550693377604 h1:hJwCVlE3ojViC35MGHB+FBr8TuIf3BUFn2EQ1VIamsI=
|
||||
github.com/metacubex/kcp-go v0.0.0-20260105040817-550693377604/go.mod h1:lpmN3m269b3V5jFCWtffqBLS4U3QQoIid9ugtO+OhVc=
|
||||
github.com/metacubex/mhurl v0.1.0 h1:ZdW4Zxe3j3uJ89gNytOazHu6kbHn5owutN/VfXOI8GE=
|
||||
github.com/metacubex/mhurl v0.1.0/go.mod h1:2qpQImCbXoUs6GwJrjuEXKelPyoimsIXr07eNKZdS00=
|
||||
github.com/metacubex/mlkem v0.1.0 h1:wFClitonSFcmipzzQvax75beLQU+D7JuC+VK1RzSL8I=
|
||||
github.com/metacubex/mlkem v0.1.0/go.mod h1:amhaXZVeYNShuy9BILcR7P0gbeo/QLZsnqCdL8U2PDQ=
|
||||
github.com/metacubex/nftables v0.0.0-20260426003805-208c2c1ba2cb h1:wk6mHYPURSUvWcUv72gNP79oiylFsscBSDPJ6ieV6Iw=
|
||||
github.com/metacubex/nftables v0.0.0-20260426003805-208c2c1ba2cb/go.mod h1:73ZrCfhdkW4F2E2GAlta3km/S2RHhFNogCMtWZV2anQ=
|
||||
github.com/metacubex/protobuf-go v0.0.0-20260306035419-7ceee0674686 h1:PIXmYT2anQt9V8vdmwixtbIJxOpoPXJfIACHPjXEgnE=
|
||||
github.com/metacubex/protobuf-go v0.0.0-20260306035419-7ceee0674686/go.mod h1:eQV7juxFZIdRgjMxtVqP+6BssKoTZQ1RM0fc58BsCZY=
|
||||
github.com/metacubex/qpack v0.6.0 h1:YqClGIMOpiRYLjV1qOs483Od08MdPgRnHjt90FuaAKw=
|
||||
github.com/metacubex/qpack v0.6.0/go.mod h1:lKGSi7Xk94IMvHGOmxS9eIei3bvIqpOAImEBsaOwTkA=
|
||||
github.com/metacubex/quic-go v0.59.1-0.20260413153657-53bb22f2c306 h1:HlGLmLsWJMLSu0CMI9z/BmEnithB4oXM5Rom6/0Qxtg=
|
||||
github.com/metacubex/quic-go v0.59.1-0.20260413153657-53bb22f2c306/go.mod h1:oNzMrmylS897M3zSMuapIdwSwfq6F2qW01Z3NhVRJhk=
|
||||
github.com/metacubex/randv2 v0.2.0 h1:uP38uBvV2SxYfLj53kuvAjbND4RUDfFJjwr4UigMiLs=
|
||||
github.com/metacubex/randv2 v0.2.0/go.mod h1:kFi2SzrQ5WuneuoLLCMkABtiBu6VRrMrWFqSPyj2cxY=
|
||||
github.com/metacubex/restls-client-go v0.1.7 h1:eCwiXCTQb5WJu9IlgYvDBA1OgrINv58dEe7hcN5H15k=
|
||||
github.com/metacubex/restls-client-go v0.1.7/go.mod h1:BN/U52vPw7j8VTSh2vleD/MnmVKCov84mS5VcjVHH4g=
|
||||
github.com/metacubex/sing v0.5.7 h1:8OC+fhKFSv/l9ehEhJRaZZAOuthfZo68SteBVLe8QqM=
|
||||
github.com/metacubex/sing v0.5.7/go.mod h1:ypf0mjwlZm0sKdQSY+yQvmsbWa0hNPtkeqyRMGgoN+w=
|
||||
github.com/metacubex/sing-mux v0.3.9 h1:/aoBD2+sK2qsXDlNDe3hkR0GZuFDtwIZhOeGUx9W0Yk=
|
||||
github.com/metacubex/sing-mux v0.3.9/go.mod h1:8bT7ZKT3clRrJjYc/x5CRYibC1TX/bK73a3r3+2E+Fc=
|
||||
github.com/metacubex/sing-quic v0.0.0-20260414034501-3ea3410d197a h1:977o0ZYYbiQAGuOxql7Q6UN3rEy59OyAE0tELq4gZfI=
|
||||
github.com/metacubex/sing-quic v0.0.0-20260414034501-3ea3410d197a/go.mod h1:6ayFGfzzBE85csgQkM3gf4neFq6s0losHlPRSxY+nuk=
|
||||
github.com/metacubex/sing-shadowsocks v0.2.12 h1:Wqzo8bYXrK5aWqxu/TjlTnYZzAKtKsaFQBdr6IHFaBE=
|
||||
github.com/metacubex/sing-shadowsocks v0.2.12/go.mod h1:2e5EIaw0rxKrm1YTRmiMnDulwbGxH9hAFlrwQLQMQkU=
|
||||
github.com/metacubex/sing-shadowsocks2 v0.2.7 h1:hSuuc0YpsfiqYqt1o+fP4m34BQz4e6wVj3PPBVhor3A=
|
||||
github.com/metacubex/sing-shadowsocks2 v0.2.7/go.mod h1:vOEbfKC60txi0ca+yUlqEwOGc3Obl6cnSgx9Gf45KjE=
|
||||
github.com/metacubex/sing-shadowtls v0.0.0-20250503063515-5d9f966d17a2 h1:gXU+MYPm7Wme3/OAY2FFzVq9d9GxPHOqu5AQfg/ddhI=
|
||||
github.com/metacubex/sing-shadowtls v0.0.0-20250503063515-5d9f966d17a2/go.mod h1:mbfboaXauKJNIHJYxQRa+NJs4JU9NZfkA+I33dS2+9E=
|
||||
github.com/metacubex/sing-tun v0.4.18 h1:WRzAosG0YkT3aZq5RJWtF+RdCgeJ8EpooS5ZM1lkXo0=
|
||||
github.com/metacubex/sing-tun v0.4.18/go.mod h1:g4I/JNplDBhXLF+aQWgFbhNeJPSXQOWS9HvLeNvkgeA=
|
||||
github.com/metacubex/sing-vmess v0.2.5 h1:m9Zt5I27lB9fmLMZfism9sH2LcnAfShZfwSkf6/KJoE=
|
||||
github.com/metacubex/sing-vmess v0.2.5/go.mod h1:AwtlzUgf8COe9tRYAKqWZ+leDH7p5U98a0ZUpYehl8Q=
|
||||
github.com/metacubex/sing-wireguard v0.0.0-20260507084707-690d479ec947 h1:IB03BvRQtvjWScyOK5jSQVJYY8osmZXHL+4VCEFMWcM=
|
||||
github.com/metacubex/sing-wireguard v0.0.0-20260507084707-690d479ec947/go.mod h1:jpAkVLPnCpGSfNyVmj6Cq4YbuZsFepm/Dc+9BAOcR80=
|
||||
github.com/metacubex/smux v0.0.0-20260105030934-d0c8756d3141 h1:DK2l6m2Fc85H2BhiAPgbJygiWhesPlfGmF+9Vw6ARdk=
|
||||
github.com/metacubex/smux v0.0.0-20260105030934-d0c8756d3141/go.mod h1:/yI4OiGOSn0SURhZdJF3CbtPg3nwK700bG8TZLMBvAg=
|
||||
github.com/metacubex/ssh v0.1.0 h1:iGfr99qk/eMHzUnQ/0bTxXT8+8SWqLSHBWDHoAhngzw=
|
||||
github.com/metacubex/ssh v0.1.0/go.mod h1:NUtl0d+/f2cG9ECEpMM8iCVOpmggQlC13oLeDUONDlU=
|
||||
github.com/metacubex/tfo-go v0.0.0-20251130171125-413e892ac443 h1:H6TnfM12tOoTizYE/qBHH3nEuibIelmHI+BVSxVJr8o=
|
||||
github.com/metacubex/tfo-go v0.0.0-20251130171125-413e892ac443/go.mod h1:l9oLnLoEXyGZ5RVLsh7QCC5XsouTUyKk4F2nLm2DHLw=
|
||||
github.com/metacubex/tls v0.1.5 h1:ECcB83dj+zadnhlKcLnUUf1Sq6+vU0f/zoyU0+9oPTc=
|
||||
github.com/metacubex/tls v0.1.5/go.mod h1:0XeVdL0cBw+8i5Hqy3lVeP9IyD/LFTq02ExvHM6rzEM=
|
||||
github.com/metacubex/utls v1.8.4 h1:HmL9nUApDdWSkgUyodfwF6hSjtiwCGGdyhaSpEejKpg=
|
||||
github.com/metacubex/utls v1.8.4/go.mod h1:kncGGVhFaoGn5M3pFe3SXhZCzsbCJayNOH4UEqTKTko=
|
||||
github.com/metacubex/wireguard-go v0.0.0-20250820062549-a6cecdd7f57f h1:FGBPRb1zUabhPhDrlKEjQ9lgIwQ6cHL4x8M9lrERhbk=
|
||||
github.com/metacubex/wireguard-go v0.0.0-20250820062549-a6cecdd7f57f/go.mod h1:oPGcV994OGJedmmxrcK9+ni7jUEMGhR+uVQAdaduIP4=
|
||||
github.com/metacubex/yamux v0.0.0-20250918083631-dd5f17c0be49 h1:lhlqpYHopuTLx9xQt22kSA9HtnyTDmk5XjjQVCGHe2E=
|
||||
github.com/metacubex/yamux v0.0.0-20250918083631-dd5f17c0be49/go.mod h1:MBeEa9IVBphH7vc3LNtW6ZujVXFizotPo3OEiHQ+TNU=
|
||||
github.com/miekg/dns v1.1.63 h1:8M5aAw6OMZfFXTT7K5V0Eu5YiiL8l7nUAkyN6C9YwaY=
|
||||
github.com/miekg/dns v1.1.63/go.mod h1:6NGHfjhpmr5lt3XPLuyfDJi5AXbNIPM9PY6H6sF1Nfs=
|
||||
github.com/mroth/weightedrand/v2 v2.1.0 h1:o1ascnB1CIVzsqlfArQQjeMy1U0NcIbBO5rfd5E/OeU=
|
||||
github.com/mroth/weightedrand/v2 v2.1.0/go.mod h1:f2faGsfOGOwc1p94wzHKKZyTpcJUW7OJ/9U4yfiNAOU=
|
||||
github.com/oasisprotocol/deoxysii v0.0.0-20220228165953-2091330c22b7 h1:1102pQc2SEPp5+xrS26wEaeb26sZy6k9/ZXlZN+eXE4=
|
||||
github.com/oasisprotocol/deoxysii v0.0.0-20220228165953-2091330c22b7/go.mod h1:UqoUn6cHESlliMhOnKLWr+CBH+e3bazUPvFj1XZwAjs=
|
||||
github.com/openacid/errors v0.8.1/go.mod h1:GUQEJJOJE3W9skHm8E8Y4phdl2LLEN8iD7c5gcGgdx0=
|
||||
github.com/openacid/low v0.1.21 h1:Tr2GNu4N/+rGRYdOsEHOE89cxUIaDViZbVmKz29uKGo=
|
||||
github.com/openacid/low v0.1.21/go.mod h1:q+MsKI6Pz2xsCkzV4BLj7NR5M4EX0sGz5AqotpZDVh0=
|
||||
github.com/openacid/must v0.1.3/go.mod h1:luPiXCuJlEo3UUFQngVQokV0MPGryeYvtCbQPs3U1+I=
|
||||
github.com/openacid/testkeys v0.1.6/go.mod h1:MfA7cACzBpbiwekivj8StqX0WIRmqlMsci1c37CA3Do=
|
||||
github.com/oschwald/maxminddb-golang v1.12.0 h1:9FnTOD0YOhP7DGxGsq4glzpGy5+w7pq50AS6wALUMYs=
|
||||
github.com/oschwald/maxminddb-golang v1.12.0/go.mod h1:q0Nob5lTCqyQ8WT6FYgS1L7PXKVVbgiymefNwIjPzgY=
|
||||
github.com/pierrec/lz4/v4 v4.1.14 h1:+fL8AQEZtz/ijeNnpduH0bROTu0O3NZAlPjQxGn8LwE=
|
||||
github.com/pierrec/lz4/v4 v4.1.14/go.mod h1:gZWDp/Ze/IJXGXf23ltt2EXimqmTUXEy0GFuRQyBid4=
|
||||
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/dlclark/regexp2 v1.4.0 h1:F1rxgk7p4uKjwIQxBs9oAXe5CqrXlCduYEJvrF4u93E=
|
||||
github.com/dlclark/regexp2 v1.4.0/go.mod h1:2pZnwuY/m+8K6iRw6wQdMtk+rH5tNGR1i55kozfMjCc=
|
||||
github.com/fanliao/go-promise v0.0.0-20141029170127-1890db352a72/go.mod h1:PjfxuH4FZdUyfMdtBio2lsRr1AKEaVPwelzuHuh8Lqc=
|
||||
github.com/go-chi/chi/v5 v5.0.4/go.mod h1:DslCQbL2OYiznFReuXYUmQ2hGd1aDpCnlMNITLSKoi8=
|
||||
github.com/go-chi/cors v1.2.0/go.mod h1:sSbTewc+6wYHBBCW7ytsFSn836hqM7JxpglAy2Vzc58=
|
||||
github.com/go-chi/render v1.0.1/go.mod h1:pq4Rr7HbnsdaeHagklXub+p6Wd16Af5l9koip1OvJns=
|
||||
github.com/gofrs/uuid v4.0.0+incompatible h1:1SD/1F5pU8p29ybwgQSwpQk+mwdRrXCYuPhW6m+TnJw=
|
||||
github.com/gofrs/uuid v4.0.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM=
|
||||
github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=
|
||||
github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
|
||||
github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
|
||||
github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY=
|
||||
github.com/gorilla/websocket v1.4.2 h1:+/TMaTYc4QFitKJxsQ7Yye35DkWvkdLcvGKqM+x0Ufc=
|
||||
github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
|
||||
github.com/hugelgupf/socketpair v0.0.0-20190730060125-05d35a94e714/go.mod h1:2Goc3h8EklBH5mspfHFxBnEoURQCGzQQH1ga9Myjvis=
|
||||
github.com/insomniacslk/dhcp v0.0.0-20210827173440-b95caade3eac h1:IO6EfdRnPhxgKOsk9DbewdtQZHKZKnGlW7QCUttvNys=
|
||||
github.com/insomniacslk/dhcp v0.0.0-20210827173440-b95caade3eac/go.mod h1:h+MxyHxRg9NH3terB1nfRIUaQEcI0XOVkdR9LNBlp8E=
|
||||
github.com/jsimonetti/rtnetlink v0.0.0-20190606172950-9527aa82566a/go.mod h1:Oz+70psSo5OFh8DBl0Zv2ACw7Esh6pPUphlvZG9x7uw=
|
||||
github.com/jsimonetti/rtnetlink v0.0.0-20200117123717-f846d4f6c1f4/go.mod h1:WGuG/smIU4J/54PblvSbh+xvCZmpJnFgr3ds6Z55XMQ=
|
||||
github.com/jsimonetti/rtnetlink v0.0.0-20201009170750-9c6f07d100c1/go.mod h1:hqoO/u39cqLeBLebZ8fWdE96O7FxrAsRYhnVOdgHxok=
|
||||
github.com/jsimonetti/rtnetlink v0.0.0-20201110080708-d2c240429e6c/go.mod h1:huN4d1phzjhlOsNIjFsw2SVRbwIHj3fJDMEU2SDPTmg=
|
||||
github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU=
|
||||
github.com/mdlayher/ethernet v0.0.0-20190606142754-0394541c37b7/go.mod h1:U6ZQobyTjI/tJyq2HG+i/dfSoFUt8/aZCM+GKtmFk/Y=
|
||||
github.com/mdlayher/netlink v0.0.0-20190409211403-11939a169225/go.mod h1:eQB3mZE4aiYnlUsyGGCOpPETfdQq4Jhsgf1fk3cwQaA=
|
||||
github.com/mdlayher/netlink v1.0.0/go.mod h1:KxeJAFOFLG6AjpyDkQ/iIhxygIUKD+vcwqcnu43w/+M=
|
||||
github.com/mdlayher/netlink v1.1.0/go.mod h1:H4WCitaheIsdF9yOYu8CFmCgQthAPIWZmcKp9uZHgmY=
|
||||
github.com/mdlayher/netlink v1.1.1/go.mod h1:WTYpFb/WTvlRJAyKhZL5/uy69TDDpHHu2VZmb2XgV7o=
|
||||
github.com/mdlayher/raw v0.0.0-20190606142536-fef19f00fc18/go.mod h1:7EpbotpCmVZcu+KCX4g9WaRNuu11uyhiW7+Le1dKawg=
|
||||
github.com/mdlayher/raw v0.0.0-20191009151244-50f2db8cc065/go.mod h1:7EpbotpCmVZcu+KCX4g9WaRNuu11uyhiW7+Le1dKawg=
|
||||
github.com/miekg/dns v1.1.43 h1:JKfpVSCB84vrAmHzyrsxB5NAr5kLoMXZArPSw7Qlgyg=
|
||||
github.com/miekg/dns v1.1.43/go.mod h1:+evo5L0630/F6ca/Z9+GAqzhjGyn8/c+TBaOyfEl0V4=
|
||||
github.com/oschwald/geoip2-golang v1.5.0 h1:igg2yQIrrcRccB1ytFXqBfOHCjXWIoMv85lVJ1ONZzw=
|
||||
github.com/oschwald/geoip2-golang v1.5.0/go.mod h1:xdvYt5xQzB8ORWFqPnqMwZpCpgNagttWdoZLlJQzg7s=
|
||||
github.com/oschwald/maxminddb-golang v1.8.0 h1:Uh/DSnGoxsyp/KYbY1AuP0tYEwfs0sCph9p/UMXK/Hk=
|
||||
github.com/oschwald/maxminddb-golang v1.8.0/go.mod h1:RXZtst0N6+FY/3qCNmZMBApR19cdQj43/NM9VkrNAis=
|
||||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
github.com/sagernet/netlink v0.0.0-20240612041022-b9a21c07ac6a h1:ObwtHN2VpqE0ZNjr6sGeT00J8uU7JF4cNUdb44/Duis=
|
||||
github.com/sagernet/netlink v0.0.0-20240612041022-b9a21c07ac6a/go.mod h1:xLnfdiJbSp8rNqYEdIW/6eDO4mVoogml14Bh2hSiFpM=
|
||||
github.com/samber/lo v1.53.0 h1:t975lj2py4kJPQ6haz1QMgtId2gtmfktACxIXArw3HM=
|
||||
github.com/samber/lo v1.53.0/go.mod h1:4+MXEGsJzbKGaUEQFKBq2xtfuznW9oz/WrgyzMzRoM0=
|
||||
github.com/sina-ghaderi/poly1305 v0.0.0-20220724002748-c5926b03988b h1:rXHg9GrUEtWZhEkrykicdND3VPjlVbYiLdX9J7gimS8=
|
||||
github.com/sina-ghaderi/poly1305 v0.0.0-20220724002748-c5926b03988b/go.mod h1:X7qrxNQViEaAN9LNZOPl9PfvQtp3V3c7LTo0dvGi0fM=
|
||||
github.com/sina-ghaderi/rabaead v0.0.0-20220730151906-ab6e06b96e8c h1:DjKMC30y6yjG3IxDaeAj3PCoRr+IsO+bzyT+Se2m2Hk=
|
||||
github.com/sina-ghaderi/rabaead v0.0.0-20220730151906-ab6e06b96e8c/go.mod h1:NV/a66PhhWYVmUMaotlXJ8fIEFB98u+c8l/CQIEFLrU=
|
||||
github.com/sina-ghaderi/rabbitio v0.0.0-20220730151941-9ce26f4f872e h1:ur8uMsPIFG3i4Gi093BQITvwH9znsz2VUZmnmwHvpIo=
|
||||
github.com/sina-ghaderi/rabbitio v0.0.0-20220730151941-9ce26f4f872e/go.mod h1:+e5fBW3bpPyo+3uLo513gIUblc03egGjMM0+5GKbzK8=
|
||||
github.com/sirupsen/logrus v1.9.4 h1:TsZE7l11zFCLZnZ+teH4Umoq5BhEIfIzfRDZ1Uzql2w=
|
||||
github.com/sirupsen/logrus v1.9.4/go.mod h1:ftWc9WdOfJ0a92nsE2jF5u5ZwH8Bv2zdeOC42RjbV2g=
|
||||
github.com/sirupsen/logrus v1.8.1 h1:dJKuHgqk1NNQlqoA6BTlM1Wf9DOH3NBjQyu0h9+AZZE=
|
||||
github.com/sirupsen/logrus v1.8.1/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0=
|
||||
github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc=
|
||||
github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA=
|
||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
|
||||
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
|
||||
github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY=
|
||||
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U=
|
||||
github.com/u-root/uio v0.0.0-20230220225925-ffce2a382923 h1:tHNk7XK9GkmKUR6Gh8gVBKXc2MVSZ4G/NnWLtzw4gNA=
|
||||
github.com/u-root/uio v0.0.0-20230220225925-ffce2a382923/go.mod h1:eLL9Nub3yfAho7qB0MzZizFhTU2QkLeoVsWdHtDW264=
|
||||
github.com/vishvananda/netlink v1.1.0/go.mod h1:cTgwzPIzzgDAYoQrMm0EdrjRUBkTqKYppBueQtXaqoE=
|
||||
github.com/vishvananda/netns v0.0.0-20191106174202-0a2b9b5464df/go.mod h1:JP3t17pCcGlemwknint6hfoeCVQrEMVwxRLRjXpq+BU=
|
||||
github.com/vishvananda/netns v0.0.0-20210104183010-2eb08e3e575f/go.mod h1:DD4vA1DwXk04H54A1oHXtwZmA0grkVMdPxx/VGLCah0=
|
||||
github.com/vishvananda/netns v0.0.5 h1:DfiHV+j8bA32MFM7bfEunvT8IAqQ/NzSJHtcmW5zdEY=
|
||||
github.com/vishvananda/netns v0.0.5/go.mod h1:SpkAiCQRtJ6TvvxPnOSyH3BMl6unz3xZlaprSwhNNJM=
|
||||
github.com/vmihailenco/msgpack/v5 v5.4.1 h1:cQriyiUvjTwOHg8QZaPihLWeRAAVoCpE00IUPn0Bjt8=
|
||||
github.com/vmihailenco/msgpack/v5 v5.4.1/go.mod h1:GaZTsDaehaPpQVyxrf5mtQlH+pc21PIudVV/E3rRQok=
|
||||
github.com/vmihailenco/tagparser/v2 v2.0.0 h1:y09buUbR+b5aycVFQs/g70pqKVZNBmxwAhO7/IwNM9g=
|
||||
github.com/vmihailenco/tagparser/v2 v2.0.0/go.mod h1:Wri+At7QHww0WTrCBeu4J6bNtoV6mEfg5OIWRZA9qds=
|
||||
github.com/xtaci/lossyconn v0.0.0-20190602105132-8df528c0c9ae h1:J0GxkO96kL4WF+AIT3M4mfUVinOCPgf2uUWYFUzN0sM=
|
||||
github.com/yosida95/uritemplate/v3 v3.0.2 h1:Ed3Oyj9yrmi9087+NczuL5BwkIc4wvTb5zIM+UJPGz4=
|
||||
github.com/yosida95/uritemplate/v3 v3.0.2/go.mod h1:ILOh0sOhIJR3+L/8afwt/kE++YT040gmv5BQTMR2HP4=
|
||||
gitlab.com/go-extension/aes-ccm v0.0.0-20230221065045-e58665ef23c7 h1:UNrDfkQqiEYzdMlNsVvBYOAJWZjdktqFE9tQh5BT2+4=
|
||||
gitlab.com/go-extension/aes-ccm v0.0.0-20230221065045-e58665ef23c7/go.mod h1:E+rxHvJG9H6PUdzq9NRG6csuLN3XUx98BfGOVWNYnXs=
|
||||
gitlab.com/yawning/bsaes.git v0.0.0-20190805113838-0a714cd429ec h1:FpfFs4EhNehiVfzQttTuxanPIT43FtkkCFypIod8LHo=
|
||||
gitlab.com/yawning/bsaes.git v0.0.0-20190805113838-0a714cd429ec/go.mod h1:BZ1RAoRPbCxum9Grlv5aeksu2H8BiKehBYooU2LFiOQ=
|
||||
go.uber.org/mock v0.4.0 h1:VcM4ZOtdbR4f6VXfiOpwpVJDL6lCReaZ6mw31wqh7KU=
|
||||
go4.org/netipx v0.0.0-20231129151722-fdeea329fbba h1:0b9z3AuHCjxk0x/opv64kcgZLBseWJUpBw5I82+2U4M=
|
||||
go4.org/netipx v0.0.0-20231129151722-fdeea329fbba/go.mod h1:PLyyIXexvUFg3Owu6p/WfdlivPbZJsZdgWZlrGope/Y=
|
||||
github.com/u-root/uio v0.0.0-20210528114334-82958018845c h1:BFvcl34IGnw8yvJi8hlqLFo9EshRInwWBs2M5fGWzQA=
|
||||
github.com/u-root/uio v0.0.0-20210528114334-82958018845c/go.mod h1:LpEX5FO/cB+WF4TYGY1V5qktpaZLkKkSegbr0V4eYXA=
|
||||
go.uber.org/atomic v1.9.0 h1:ECmE8Bn/WFTYwEW/bpKD3M8VtR/zQVbavAoalC1PYyE=
|
||||
go.uber.org/atomic v1.9.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc=
|
||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
golang.org/x/crypto v0.33.0 h1:IOBPskki6Lysi0lo9qQvbxiQ+FvsCC/YWOecCHAixus=
|
||||
golang.org/x/crypto v0.33.0/go.mod h1:bVdXmD7IV/4GdElGPozy6U7lWdRXA4qyRVGJV57uQ5M=
|
||||
golang.org/x/exp v0.0.0-20240904232852-e7e105dedf7e h1:I88y4caeGeuDQxgdoFPUq097j7kNfw6uvuiNxUBfcBk=
|
||||
golang.org/x/exp v0.0.0-20240904232852-e7e105dedf7e/go.mod h1:akd2r19cwCdwSwWeIdzYQGa/EZZyqcOdwWiwj5L5eKQ=
|
||||
golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=
|
||||
golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=
|
||||
golang.org/x/mod v0.20.0 h1:utOm6MM3R3dnawAiJgn0y+xvuYRsm1RKM/4giyfDgV0=
|
||||
golang.org/x/mod v0.20.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c=
|
||||
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/crypto v0.0.0-20210317152858-513c2a44f670/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4=
|
||||
golang.org/x/crypto v0.0.0-20210817164053-32db794688a5 h1:HWj/xjIHfjYU5nVXpTM0s39J9CbLn7Cc5a7IC5rwsMQ=
|
||||
golang.org/x/crypto v0.0.0-20210817164053-32db794688a5/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
|
||||
golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.35.0 h1:T5GQRQb2y08kTAByq9L4/bz8cipCdA8FbRTXewonqY8=
|
||||
golang.org/x/net v0.35.0/go.mod h1:EglIi67kWsHKlRzzVMUD93VMSWGFOMSZgxFjparz1Qk=
|
||||
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.11.0 h1:GGz8+XQP4FvTTrjZPzNKTMFtSXH80RAzG+5ghFPgK9w=
|
||||
golang.org/x/sync v0.11.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
|
||||
golang.org/x/net v0.0.0-20190419010253-1f3472d942ba/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||
golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks=
|
||||
golang.org/x/net v0.0.0-20190827160401-ba9fcec4b297/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20191007182048-72f939374954/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20201010224723-4f7140c49acb/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
|
||||
golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
|
||||
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
|
||||
golang.org/x/net v0.0.0-20210903162142-ad29c8ab022f h1:w6wWR0H+nyVpbSAQbzVEIACVyr/h8l/BEkY6Sokc7Eg=
|
||||
golang.org/x/net v0.0.0-20210903162142-ad29c8ab022f/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
||||
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c h1:5KslGYwFpkhGh+Q16bwMP3cOontH8FOep7tGV86Y7SQ=
|
||||
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190411185658-b44545bcd369/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190606203320-7fc4e5ec1444/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190804053845-51ab0e2deafa/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200217220822-9197077df867/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20220622161953-175b2fd9d664/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.30.0 h1:QjkSwP/36a20jFYWkSue1YwXzLmsV5Gfq7Eiy72C1uc=
|
||||
golang.org/x/sys v0.30.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||
golang.org/x/term v0.29.0 h1:L6pJp37ocefwRRtYPKSWOWzOtWSxVajvz2ldH/xi3iU=
|
||||
golang.org/x/sys v0.0.0-20190418153312-f0ce4c0180be/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190606122018-79a91cf218c4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190826190057-c7b8b68b1456/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20191008105621-543471e840be/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20191224085550-c709ea063b76/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200202164722-d101bd2416d5/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20201009025420-dfb3f7c4e634/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20201101102859-da207088b7d1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210303074136-134d130e1a04/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210525143221-35b2ab0089ea/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20210906170528-6f6e22806c34/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20211116061358-0a5406a5449c h1:DHcbWVXeY+0Y8HHKR+rbLwnoh2F4tNCY7rTiHJ30RmA=
|
||||
golang.org/x/sys v0.0.0-20211116061358-0a5406a5449c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.22.0 h1:bofq7m3/HAFvbF51jz3Q9wLg3jkvSPuiZu/pD1XwgtM=
|
||||
golang.org/x/text v0.22.0/go.mod h1:YRoo4H8PVmsu+E3Ou7cqLVH8oXWIHVoX0jqUWALQhfY=
|
||||
golang.org/x/time v0.10.0 h1:3usCWA8tQn0L8+hFJQNgzpWbd89begxN66o1Ojdn5L4=
|
||||
golang.org/x/time v0.10.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM=
|
||||
golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
||||
golang.org/x/tools v0.24.0 h1:J1shsA93PJUEVaUSaay7UXAyE8aimq3GW0pjlolpa24=
|
||||
golang.org/x/tools v0.24.0/go.mod h1:YhNqVBIfWHdzvTLs0d8LCuMhkKUgSUKldakyV7W/WDQ=
|
||||
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/text v0.3.6 h1:aRYxNxv6iGQlyVaZmk6ZgYEDa+Jg18DxebPSrd6bg1M=
|
||||
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
|
||||
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
|
||||
gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
|
||||
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo=
|
||||
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
||||
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
|
||||
@@ -12,5 +12,5 @@ import (
|
||||
|
||||
_ "golang.org/x/sync/semaphore"
|
||||
|
||||
_ "github.com/metacubex/mihomo/log"
|
||||
_ "github.com/Dreamacro/clash/log"
|
||||
)
|
||||
|
||||
@@ -9,7 +9,7 @@ import (
|
||||
|
||||
"cfa/native/app"
|
||||
|
||||
"github.com/metacubex/mihomo/log"
|
||||
"github.com/Dreamacro/clash/log"
|
||||
)
|
||||
|
||||
func openRemoteContent(url string) (int, error) {
|
||||
|
||||
@@ -3,14 +3,18 @@ package app
|
||||
import (
|
||||
"strings"
|
||||
|
||||
"github.com/metacubex/mihomo/dns"
|
||||
"github.com/Dreamacro/clash/dns"
|
||||
)
|
||||
|
||||
func NotifyDnsChanged(dnsList string) {
|
||||
var addr []string
|
||||
if len(dnsList) > 0 {
|
||||
addr = strings.Split(dnsList, ",")
|
||||
dL := strings.Split(dnsList, ",")
|
||||
|
||||
ns := make([]dns.NameServer, 0, len(dnsList))
|
||||
for _, d := range dL {
|
||||
ns = append(ns, dns.NameServer{Addr: d})
|
||||
}
|
||||
dns.UpdateSystemDNS(addr)
|
||||
|
||||
dns.UpdateSystemDNS(dL)
|
||||
dns.FlushCacheWithDefaultResolver()
|
||||
}
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@ package app
|
||||
import (
|
||||
"github.com/dlclark/regexp2"
|
||||
|
||||
"github.com/metacubex/mihomo/log"
|
||||
"github.com/Dreamacro/clash/log"
|
||||
)
|
||||
|
||||
var uiSubtitlePattern *regexp2.Regexp
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
#include <malloc.h>
|
||||
#include <android/log.h>
|
||||
|
||||
#define TAG "ClashMetaForAndroid"
|
||||
#define TAG "ClashForAndroid"
|
||||
|
||||
typedef const char *c_string;
|
||||
|
||||
|
||||
@@ -4,8 +4,8 @@ var (
|
||||
defaultNameServers = []string{
|
||||
"223.5.5.5",
|
||||
"119.29.29.29",
|
||||
"8.8.4.4",
|
||||
"1.0.0.1",
|
||||
"8.8.8.8",
|
||||
"1.1.1.1",
|
||||
}
|
||||
defaultFakeIPFilter = []string{
|
||||
// Stun Services
|
||||
@@ -17,25 +17,22 @@ var (
|
||||
// Google Voices
|
||||
"lens.l.google.com",
|
||||
|
||||
// Nintendo Switch STUN
|
||||
// Nintendo Switch
|
||||
"*.n.n.srv.nintendo.net",
|
||||
|
||||
// PlayStation STUN
|
||||
// PlayStation
|
||||
"+.stun.playstation.net",
|
||||
|
||||
// XBox
|
||||
"xbox.*.*.microsoft.com",
|
||||
"*.*.xboxlive.com",
|
||||
|
||||
// Microsoft Captive Portal
|
||||
// Microsoft
|
||||
"*.msftncsi.com",
|
||||
"*.msftconnecttest.com",
|
||||
|
||||
// Bilibili CDN
|
||||
"*.mcdn.bilivideo.cn",
|
||||
|
||||
// Windows Default LAN WorkGroup
|
||||
"WORKGROUP",
|
||||
}
|
||||
defaultFakeIPRange = "28.0.0.0/8"
|
||||
)
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
package config
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io"
|
||||
@@ -13,8 +12,7 @@ import (
|
||||
"time"
|
||||
|
||||
"cfa/native/app"
|
||||
|
||||
clashHttp "github.com/metacubex/mihomo/component/http"
|
||||
"github.com/Dreamacro/clash/component/dialer"
|
||||
)
|
||||
|
||||
type Status struct {
|
||||
@@ -24,9 +22,26 @@ type Status struct {
|
||||
MaxProgress int `json:"max"`
|
||||
}
|
||||
|
||||
func openUrl(ctx context.Context, url string) (io.ReadCloser, error) {
|
||||
response, err := clashHttp.HttpRequest(ctx, url, http.MethodGet, http.Header{"User-Agent": {"ClashMetaForAndroid/" + app.VersionName()}}, nil)
|
||||
var client = &http.Client{
|
||||
Transport: &http.Transport{
|
||||
DisableKeepAlives: true,
|
||||
TLSHandshakeTimeout: 10 * time.Second,
|
||||
ExpectContinueTimeout: 1 * time.Second,
|
||||
DialContext: dialer.DialTunnelContext,
|
||||
},
|
||||
Timeout: 60 * time.Second,
|
||||
}
|
||||
|
||||
func openUrl(url string) (io.ReadCloser, error) {
|
||||
request, err := http.NewRequest(http.MethodGet, url, nil)
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
request.Header.Set("User-Agent", "ClashForAndroid/"+app.VersionName())
|
||||
|
||||
response, err := client.Do(request)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -39,15 +54,12 @@ func openContent(url string) (io.ReadCloser, error) {
|
||||
}
|
||||
|
||||
func fetch(url *U.URL, file string) error {
|
||||
ctx, cancel := context.WithTimeout(context.Background(), 60*time.Second)
|
||||
defer cancel()
|
||||
|
||||
var reader io.ReadCloser
|
||||
var err error
|
||||
|
||||
switch url.Scheme {
|
||||
case "http", "https":
|
||||
reader, err = openUrl(ctx, url.String())
|
||||
reader, err = openUrl(url.String())
|
||||
case "content":
|
||||
reader, err = openContent(url.String())
|
||||
default:
|
||||
@@ -112,7 +124,7 @@ func FetchAndValid(
|
||||
return err
|
||||
}
|
||||
|
||||
forEachProviders(rawCfg, func(index int, total int, name string, provider map[string]any, prefix string) {
|
||||
forEachProviders(rawCfg, func(index int, total int, name string, provider map[string]interface{}) {
|
||||
bytes, _ := json.Marshal(&Status{
|
||||
Action: "FetchProviders",
|
||||
Args: []string{name},
|
||||
|
||||
@@ -1,17 +1,19 @@
|
||||
package config
|
||||
|
||||
import (
|
||||
"os"
|
||||
"io/ioutil"
|
||||
P "path"
|
||||
"runtime"
|
||||
"strings"
|
||||
|
||||
"cfa/native/app"
|
||||
"gopkg.in/yaml.v2"
|
||||
|
||||
"github.com/metacubex/mihomo/common/yaml"
|
||||
"github.com/metacubex/mihomo/config"
|
||||
"github.com/metacubex/mihomo/hub"
|
||||
"github.com/metacubex/mihomo/log"
|
||||
"cfa/native/app"
|
||||
"github.com/Dreamacro/clash/constant"
|
||||
"github.com/Dreamacro/clash/log"
|
||||
|
||||
"github.com/Dreamacro/clash/config"
|
||||
"github.com/Dreamacro/clash/hub/executor"
|
||||
)
|
||||
|
||||
func logDns(cfg *config.RawConfig) {
|
||||
@@ -32,7 +34,7 @@ func logDns(cfg *config.RawConfig) {
|
||||
func UnmarshalAndPatch(profilePath string) (*config.RawConfig, error) {
|
||||
configPath := P.Join(profilePath, "config.yaml")
|
||||
|
||||
configData, err := os.ReadFile(configPath)
|
||||
configData, err := ioutil.ReadFile(configPath)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -75,8 +77,7 @@ func Load(path string) error {
|
||||
return err
|
||||
}
|
||||
|
||||
// like hub.Parse()
|
||||
hub.ApplyConfig(cfg)
|
||||
executor.ApplyConfig(cfg, true)
|
||||
|
||||
app.ApplySubtitlePattern(rawCfg.ClashForAndroid.UiSubtitlePattern)
|
||||
|
||||
@@ -86,10 +87,14 @@ func Load(path string) error {
|
||||
}
|
||||
|
||||
func LoadDefault() {
|
||||
cfg, err := config.Parse([]byte{})
|
||||
rawConfig, _ := config.UnmarshalRawConfig([]byte{})
|
||||
|
||||
_ = patchDns(rawConfig, constant.Path.HomeDir())
|
||||
|
||||
cfg, err := config.ParseRawConfig(rawConfig)
|
||||
if err != nil {
|
||||
panic(err.Error())
|
||||
}
|
||||
|
||||
hub.ApplyConfig(cfg)
|
||||
executor.ApplyConfig(cfg, true)
|
||||
}
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
package config
|
||||
|
||||
import (
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
|
||||
"github.com/metacubex/mihomo/constant"
|
||||
"github.com/Dreamacro/clash/constant"
|
||||
)
|
||||
|
||||
type OverrideSlot int
|
||||
@@ -14,7 +14,7 @@ const (
|
||||
OverrideSlotSession
|
||||
)
|
||||
|
||||
const defaultPersistOverride = `{}`
|
||||
const defaultPersistOverride = `{"dns":{"enable": false}, "redir-port": 0, "tproxy-port": 0}`
|
||||
const defaultSessionOverride = `{}`
|
||||
|
||||
var sessionOverride = defaultSessionOverride
|
||||
@@ -31,7 +31,7 @@ func ReadOverride(slot OverrideSlot) string {
|
||||
return defaultPersistOverride
|
||||
}
|
||||
|
||||
buf, err := io.ReadAll(file)
|
||||
buf, err := ioutil.ReadAll(file)
|
||||
if err != nil {
|
||||
return defaultPersistOverride
|
||||
}
|
||||
|
||||
@@ -9,21 +9,18 @@ import (
|
||||
"github.com/dlclark/regexp2"
|
||||
|
||||
"cfa/native/common"
|
||||
C "github.com/Dreamacro/clash/constant"
|
||||
"github.com/Dreamacro/clash/log"
|
||||
|
||||
"github.com/metacubex/mihomo/common/utils"
|
||||
"github.com/metacubex/mihomo/config"
|
||||
C "github.com/metacubex/mihomo/constant"
|
||||
"github.com/metacubex/mihomo/log"
|
||||
"github.com/Dreamacro/clash/config"
|
||||
"github.com/Dreamacro/clash/dns"
|
||||
)
|
||||
|
||||
var processors = []processor{
|
||||
patchExternalController, // must before patchOverride, so we only apply ExternalController in Override settings
|
||||
patchOverride,
|
||||
patchGeneral,
|
||||
patchProfile,
|
||||
patchDns,
|
||||
patchTun,
|
||||
patchListeners,
|
||||
patchProviders,
|
||||
validConfig,
|
||||
}
|
||||
@@ -41,19 +38,10 @@ func patchOverride(cfg *config.RawConfig, _ string) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func patchExternalController(cfg *config.RawConfig, _ string) error {
|
||||
cfg.ExternalController = ""
|
||||
cfg.ExternalControllerTLS = ""
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func patchGeneral(cfg *config.RawConfig, profileDir string) error {
|
||||
func patchGeneral(cfg *config.RawConfig, _ string) error {
|
||||
cfg.Interface = ""
|
||||
cfg.RoutingMark = 0
|
||||
if cfg.ExternalController != "" || cfg.ExternalControllerTLS != "" {
|
||||
cfg.ExternalUI = profileDir + "/ui"
|
||||
}
|
||||
cfg.ExternalUI = ""
|
||||
cfg.ExternalController = ""
|
||||
|
||||
return nil
|
||||
}
|
||||
@@ -67,56 +55,34 @@ func patchProfile(cfg *config.RawConfig, _ string) error {
|
||||
|
||||
func patchDns(cfg *config.RawConfig, _ string) error {
|
||||
if !cfg.DNS.Enable {
|
||||
cfg.DNS = config.DefaultRawConfig().DNS
|
||||
cfg.DNS.Enable = true
|
||||
cfg.DNS.NameServer = defaultNameServers
|
||||
cfg.DNS.EnhancedMode = C.DNSFakeIP
|
||||
cfg.DNS.FakeIPRange = defaultFakeIPRange
|
||||
cfg.DNS.FakeIPFilter = defaultFakeIPFilter
|
||||
cfg.DNS = config.RawDNS{
|
||||
Enable: true,
|
||||
UseHosts: true,
|
||||
DefaultNameserver: defaultNameServers,
|
||||
NameServer: defaultNameServers,
|
||||
EnhancedMode: C.DNSFakeIP,
|
||||
FakeIPRange: defaultFakeIPRange,
|
||||
FakeIPFilter: defaultFakeIPFilter,
|
||||
FallbackFilter: config.RawFallbackFilter{
|
||||
GeoIP: false,
|
||||
},
|
||||
}
|
||||
|
||||
cfg.ClashForAndroid.AppendSystemDNS = true
|
||||
}
|
||||
|
||||
if cfg.ClashForAndroid.AppendSystemDNS {
|
||||
cfg.DNS.NameServer = append(cfg.DNS.NameServer, "system://")
|
||||
cfg.DNS.NameServer = append(cfg.DNS.NameServer, "dhcp://"+dns.SystemDNSPlaceholder)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func patchTun(cfg *config.RawConfig, _ string) error {
|
||||
cfg.Tun.Enable = false
|
||||
cfg.Tun.AutoRoute = false
|
||||
cfg.Tun.AutoDetectInterface = false
|
||||
return nil
|
||||
}
|
||||
|
||||
func patchListeners(cfg *config.RawConfig, _ string) error {
|
||||
newListeners := make([]map[string]any, 0, len(cfg.Listeners))
|
||||
for _, mapping := range cfg.Listeners {
|
||||
if proxyType, existType := mapping["type"].(string); existType {
|
||||
switch proxyType {
|
||||
case "tproxy", "redir", "tun":
|
||||
continue // remove those listeners which is not supported
|
||||
}
|
||||
}
|
||||
newListeners = append(newListeners, mapping)
|
||||
}
|
||||
cfg.Listeners = newListeners
|
||||
return nil
|
||||
}
|
||||
|
||||
func patchProviders(cfg *config.RawConfig, profileDir string) error {
|
||||
forEachProviders(cfg, func(index int, total int, key string, provider map[string]any, prefix string) {
|
||||
path, _ := provider["path"].(string)
|
||||
if len(path) > 0 {
|
||||
path = common.ResolveAsRoot(path)
|
||||
} else if url, ok := provider["url"].(string); ok {
|
||||
path = prefix + "/" + utils.MakeHash([]byte(url)).String() // same as C.GetPathByHash
|
||||
} else {
|
||||
return // both path and url are empty, maybe inline provider
|
||||
forEachProviders(cfg, func(index int, total int, key string, provider map[string]interface{}) {
|
||||
if path, ok := provider["path"].(string); ok {
|
||||
provider["path"] = profileDir + "/providers/" + common.ResolveAsRoot(path)
|
||||
}
|
||||
provider["path"] = profileDir + "/providers/" + path
|
||||
})
|
||||
|
||||
return nil
|
||||
|
||||
26
core/src/main/golang/native/config/provider_open.go
Normal file
@@ -0,0 +1,26 @@
|
||||
// +build !premium
|
||||
|
||||
package config
|
||||
|
||||
import (
|
||||
"io"
|
||||
|
||||
"github.com/Dreamacro/clash/config"
|
||||
)
|
||||
|
||||
func forEachProviders(rawCfg *config.RawConfig, fun func(index int, total int, key string, provider map[string]interface{})) {
|
||||
total := len(rawCfg.ProxyProvider)
|
||||
index := 0
|
||||
|
||||
for k, v := range rawCfg.ProxyProvider {
|
||||
fun(index, total, k, v)
|
||||
|
||||
index++
|
||||
}
|
||||
}
|
||||
|
||||
func destroyProviders(cfg *config.Config) {
|
||||
for _, p := range cfg.Providers {
|
||||
_ = p.(io.Closer).Close()
|
||||
}
|
||||
}
|
||||
@@ -1,43 +1,36 @@
|
||||
// +build premium
|
||||
|
||||
package config
|
||||
|
||||
import (
|
||||
"io"
|
||||
|
||||
"github.com/metacubex/mihomo/config"
|
||||
"github.com/Dreamacro/clash/config"
|
||||
)
|
||||
|
||||
const (
|
||||
PROXIES = "proxies"
|
||||
RULES = "rules"
|
||||
)
|
||||
|
||||
func forEachProviders(rawCfg *config.RawConfig, fun func(index int, total int, key string, provider map[string]any, prefix string)) {
|
||||
func forEachProviders(rawCfg *config.RawConfig, fun func(index int, total int, key string, provider map[string]interface{})) {
|
||||
total := len(rawCfg.ProxyProvider) + len(rawCfg.RuleProvider)
|
||||
index := 0
|
||||
|
||||
for k, v := range rawCfg.ProxyProvider {
|
||||
fun(index, total, k, v, PROXIES)
|
||||
fun(index, total, k, v)
|
||||
|
||||
index++
|
||||
}
|
||||
|
||||
for k, v := range rawCfg.RuleProvider {
|
||||
fun(index, total, k, v, RULES)
|
||||
fun(index, total, k, v)
|
||||
|
||||
index++
|
||||
}
|
||||
}
|
||||
|
||||
func destroyProviders(cfg *config.Config) {
|
||||
for _, p := range cfg.Providers {
|
||||
if p, ok := p.(io.Closer); ok {
|
||||
_ = p.Close()
|
||||
}
|
||||
for _, p := range cfg.ProxyProviders {
|
||||
_ = p.(io.Closer).Close()
|
||||
}
|
||||
|
||||
for _, p := range cfg.RuleProviders {
|
||||
if p, ok := p.(io.Closer); ok {
|
||||
_ = p.Close()
|
||||
}
|
||||
_ = p.(io.Closer).Close()
|
||||
}
|
||||
}
|
||||
@@ -6,7 +6,7 @@ import (
|
||||
"net/http"
|
||||
_ "net/http/pprof"
|
||||
|
||||
"github.com/metacubex/mihomo/log"
|
||||
"github.com/Dreamacro/clash/log"
|
||||
)
|
||||
|
||||
func init() {
|
||||
|
||||
@@ -2,33 +2,26 @@ package delegate
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"strings"
|
||||
"syscall"
|
||||
|
||||
"github.com/metacubex/mihomo/component/process"
|
||||
"github.com/metacubex/mihomo/log"
|
||||
"cfa/blob"
|
||||
|
||||
"github.com/Dreamacro/clash/component/process"
|
||||
"github.com/Dreamacro/clash/log"
|
||||
|
||||
"cfa/native/app"
|
||||
"cfa/native/platform"
|
||||
|
||||
"github.com/metacubex/mihomo/component/dialer"
|
||||
"github.com/metacubex/mihomo/constant"
|
||||
"github.com/Dreamacro/clash/component/dialer"
|
||||
"github.com/Dreamacro/clash/component/mmdb"
|
||||
"github.com/Dreamacro/clash/constant"
|
||||
)
|
||||
|
||||
var errBlocked = errors.New("blocked")
|
||||
|
||||
func Init(home, versionName, gitVersion string, platformVersion int) {
|
||||
log.Infoln("Init core, home: %s, versionName: %s, gitVersion: %s, platformVersion: %d", home, versionName, gitVersion, platformVersion)
|
||||
func Init(home, versionName string, platformVersion int) {
|
||||
mmdb.LoadFromBytes(blob.GeoipDatabase)
|
||||
constant.SetHomeDir(home)
|
||||
// gitVersion = ${CURRENT_BRANCH}_${COMMIT_HASH}_${COMPILE_TIME}
|
||||
if versions := strings.Split(gitVersion, "_"); len(versions) == 3 {
|
||||
constant.Version = fmt.Sprintf("%s-%s-CMFA-%s", strings.ToLower(versions[0]), versions[1], strings.ToLower(versionName))
|
||||
constant.BuildTime = versions[2]
|
||||
} else {
|
||||
constant.Version = gitVersion
|
||||
}
|
||||
constant.Version = strings.ToLower(constant.Version)
|
||||
app.ApplyVersionName(versionName)
|
||||
app.ApplyPlatformVersion(platformVersion)
|
||||
|
||||
|
||||
@@ -8,7 +8,7 @@ import (
|
||||
"time"
|
||||
"unsafe"
|
||||
|
||||
"github.com/metacubex/mihomo/log"
|
||||
"github.com/Dreamacro/clash/log"
|
||||
)
|
||||
|
||||
type message struct {
|
||||
@@ -22,7 +22,9 @@ func init() {
|
||||
sub := log.Subscribe()
|
||||
defer log.UnSubscribe(sub)
|
||||
|
||||
for msg := range sub {
|
||||
for item := range sub {
|
||||
msg := item.(*log.Event)
|
||||
|
||||
cPayload := C.CString(msg.Payload)
|
||||
|
||||
switch msg.LogLevel {
|
||||
@@ -47,7 +49,12 @@ func subscribeLogcat(remote unsafe.Pointer) {
|
||||
sub := log.Subscribe()
|
||||
defer log.UnSubscribe(sub)
|
||||
|
||||
for msg := range sub {
|
||||
for i := range sub {
|
||||
msg, ok := i.(*log.Event)
|
||||
if !ok {
|
||||
continue
|
||||
}
|
||||
|
||||
if msg.LogLevel < log.Level() && !strings.HasPrefix(msg.Payload, "[APP]") {
|
||||
continue
|
||||
}
|
||||
|
||||
@@ -9,13 +9,12 @@ import "C"
|
||||
|
||||
import (
|
||||
"runtime"
|
||||
"runtime/debug"
|
||||
|
||||
"cfa/native/config"
|
||||
"cfa/native/delegate"
|
||||
"cfa/native/tunnel"
|
||||
|
||||
"github.com/metacubex/mihomo/log"
|
||||
"github.com/Dreamacro/clash/log"
|
||||
)
|
||||
|
||||
func main() {
|
||||
@@ -23,13 +22,12 @@ func main() {
|
||||
}
|
||||
|
||||
//export coreInit
|
||||
func coreInit(home, versionName, gitVersion C.c_string, sdkVersion C.int) {
|
||||
func coreInit(home, versionName C.c_string, sdkVersion C.int) {
|
||||
h := C.GoString(home)
|
||||
v := C.GoString(versionName)
|
||||
g := C.GoString(gitVersion)
|
||||
s := int(sdkVersion)
|
||||
|
||||
delegate.Init(h, v, g, s)
|
||||
delegate.Init(h, v, s)
|
||||
|
||||
reset()
|
||||
}
|
||||
@@ -38,10 +36,8 @@ func coreInit(home, versionName, gitVersion C.c_string, sdkVersion C.int) {
|
||||
func reset() {
|
||||
config.LoadDefault()
|
||||
tunnel.ResetStatistic()
|
||||
tunnel.CloseAllConnections()
|
||||
|
||||
runtime.GC()
|
||||
debug.FreeOSMemory()
|
||||
}
|
||||
|
||||
//export forceGc
|
||||
@@ -50,6 +46,5 @@ func forceGc() {
|
||||
log.Infoln("[APP] request force GC")
|
||||
|
||||
runtime.GC()
|
||||
debug.FreeOSMemory()
|
||||
}()
|
||||
}
|
||||
|
||||