Compare commits

...
73 Commits
Author SHA1 Message Date
Kr328 8506303693 Chore: bump version 2022-11-17 00:44:11 +08:00
Kr328 8758c561d2 Chore: update PRIVACY_POLICY.md 2022-11-17 00:43:06 +08:00
Kr328 04efed17af Fix: decrease mtu 2022-11-17 00:31:23 +08:00
EdwardWu 769b80b079 Chore: Translation: Update zh-rTW strings (#1537)
* Chore: Translation: Update zh-rTW strings[1/2]

The words usage of the translation strings in the past are in the style of China rather than Taiwan.
I'm Taiwanese, who works on Android and Translation projects.

Signed-off-by: Edward Wu <[email protected]>

* Chore: Translation: Update zh-rTW strings[2/2]

* With latest strings and merge @pan93412 suggest.

Signed-off-by: Edward Wu <[email protected]>
2022-07-04 10:30:43 +08:00
Kr328 628eb2809e Chore: bump version 2022-07-02 11:07:30 +08:00
Kr328 9f76a377ab Improve: increase tun mtu 2022-07-02 11:02:07 +08:00
Kr328 26d3decd06 Chore: remove temp debug code 2022-07-02 11:01:00 +08:00
Kr328 7b7ee554e3 Feature: add option to enable sni sniff 2022-07-02 10:59:56 +08:00
Kr328 eb7cd8923f Chore: bump version 2022-07-01 13:51:13 +08:00
Kr328 c2c09f52cc Feature: enable sniff & disable tun for premium 2022-07-01 13:50:32 +08:00
Kr328 a56b372a39 Chore: update clash core 2022-07-01 13:49:29 +08:00
Kr328 c3bab32b83 Chore: update dependencies & remove appcenter tracker 2022-07-01 12:07:45 +08:00
GrilledPear c18d78db85 Chore: Add <version> to match output apks (#1509) 2022-07-01 11:15:28 +08:00
apevogoci 178e6dcb07 Improve: Try tcp6&udp6 files first when search UID for connection (#1514) 2022-07-01 11:14:50 +08:00
kr328 a405372f6a Fix: operate clipboard on main thread 2022-05-16 20:00:48 +08:00
kr328 b472580ca6 Improve: add label to tun service 2022-05-16 19:53:32 +08:00
kr328 5a587167ae Improve: add workgroup to default fake-ip-filter 2022-05-16 19:47:55 +08:00
kr328 5149caf2b6 Improve: add ifly ime api to http proxy black list 2022-05-16 19:45:13 +08:00
kr328 ffa559a571 Chore: bump version 2022-05-13 13:50:39 +08:00
kr328 5c3ab5470a Chore: update dependencies 2022-05-12 20:15:21 +08:00
kr328 e6859ff56d Fix: use package if only single app in sharedUid group 2022-05-12 20:15:00 +08:00
kr328 f16b0048f3 Chore: update dependencies 2022-04-25 23:13:05 +08:00
kr328 17b3a0d0ed Chore: update clash core 2022-04-25 23:12:54 +08:00
kr328 1e9f38f2bb Chore: bump version 2022-04-25 12:25:50 +08:00
Kr328 ef8f9e5738 Chore: create FUNDING.yml 2022-04-25 12:12:59 +08:00
kr328 bf59ead3b2 Feature: close all connections on reset 2022-04-20 00:39:46 +08:00
kr328 5dbd94e42c Chore: update issue template 2022-04-15 14:31:10 +08:00
kr328 b92fc860eb Chore: bump version 2022-04-14 14:13:56 +08:00
kr328 20bdf171ee Feature: add zero-copy support 2022-04-14 14:13:38 +08:00
kr328 5a6ca2ce12 Chore: bump version 2022-04-11 20:59:27 +08:00
kr328 636941da70 Fix: add *.jd.com to system proxy blacklist 2022-04-11 20:49:00 +08:00
kr328 5bc3975591 Fix: fix traffic format 2022-04-11 20:49:00 +08:00
kr328 5e54e4561c Chore: minor default dns config changes 2022-04-11 20:49:00 +08:00
kr328 a7b560b576 Fix: LoadDefault should not apply dns patch 2022-04-11 20:49:00 +08:00
kr328 5f9d4c1572 Chore: minor default dns changes 2022-04-11 20:49:00 +08:00
kr328 a83ecb8b22 Chore: update clash core 2022-04-11 20:49:00 +08:00
Goooler 1cc88cc04f Chore: cache go on CI (#1440) 2022-03-22 20:36:31 +08:00
Goooler 92bce6c2c6 Chore: optimize CI (#1414)
* Bump checkout action to v3

* Bump setup-java action to v3 & Java 17

* Bump setup-go action to v3

* Use gradle-build-action

* Go 1.18

* Insert a new line
2022-03-22 18:41:06 +08:00
kr328 ab96790c73 Chore: update dependencies 2022-03-22 13:48:02 +08:00
kr328 d5618321e9 Chore: update clash core 2022-03-22 13:47:11 +08:00
Kr328 4b8fc6ae9a Chore: update dependencies 2022-02-21 19:48:35 +08:00
人工知能 152e24748b Chore: update zh-rTW translate (#1386)
* Update strings.xml

* Update strings.xml

* Update strings.xml

* Update strings.xml

* Update strings.xml
2022-02-21 19:40:06 +08:00
Kr328 2efdf21130 Chore: update clash core 2022-02-21 19:24:48 +08:00
Kr328 e99c2b64b0 Fix: add mark for issues template 2022-02-21 11:22:16 +08:00
Kr328 3915d9549e Chore: ignore .github on build 2022-02-21 11:21:00 +08:00
Kr328 23077537f9 Fix: fix issue template 2022-02-21 11:19:43 +08:00
Kr328 de0cbd6b29 Chore: refactor issue template 2022-02-21 11:15:41 +08:00
Kr328 d0efa0690a Chore: fix bug report form 2022-02-21 01:50:30 +08:00
Kr328 5b6d04d558 Chore: replace bug report with issues forms 2022-02-21 01:46:07 +08:00
Kr328 791794f59d Chore: bump version 2022-01-15 00:15:02 +08:00
Kr328 6a6465ae5b Chore: update dependencies 2022-01-15 00:13:05 +08:00
Kr328 056a78c7c4 Improve: update default fake filter list 2022-01-15 00:07:52 +08:00
YeyeBBC 11b0025faf Slightly adjust QuickSettings Tile icon and App icon, making the cat more visually centred rather than geometrically centred. (#1341) 2022-01-15 00:02:25 +08:00
Kr328 3009b29e0c Chore: update dependencies 2022-01-14 23:59:14 +08:00
Kr328 5d52d970a3 Chore: clean code 2022-01-14 23:59:00 +08:00
Kr328 aef0b84275 Fix: disable tproxy & redir by default 2022-01-14 23:58:46 +08:00
Kr328 12c704d89c Chore: reformat build.gradle.kts 2022-01-14 23:40:41 +08:00
Kr328 38e070a565 Chore: update clash core 2022-01-14 23:39:33 +08:00
Kr328 c7d33c684b Chore: clean build gradle 2022-01-14 23:20:01 +08:00
Kr328 b2661d31fd Chore: update dependencies 2022-01-14 23:10:16 +08:00
kr328 53aa718674 Improve: patch all dns to core 2021-11-21 19:56:06 +08:00
okhowang c173114368 Fix: crash with app icon (#1260) 2021-11-21 17:41:21 +08:00
kr328 7006cb516c Chore: update clash core 2021-11-21 17:17:33 +08:00
kr328 7809c30052 Refactor: refactor network observer 2021-11-21 16:55:55 +08:00
kr328 7e46d75159 Chore: update default fake-ip-filter 2021-11-21 13:54:31 +08:00
kr328 87f96b9ec7 Chore: bump version 2021-11-21 13:38:09 +08:00
kr328 3920f338f6 Chore: filter out premium build if unavailable 2021-11-21 13:38:01 +08:00
kr328 2565231867 Chore: remove unused ErrInvalidType 2021-11-21 13:31:34 +08:00
kr328 b7af3f7341 Fix: fix update profile dial 2021-11-21 13:31:25 +08:00
kr328 d93a7af534 Fix: fix network observe 2021-11-21 13:01:56 +08:00
kr328 1dcc8307ee Chore: remove unused patch proxy group 2021-11-21 13:01:44 +08:00
kr328 9936a9469d Fix: fix tun local addr 2021-11-21 13:01:27 +08:00
kr328 0e245b8936 Fix: downgrade kotlin version 2021-11-16 21:04:18 +08:00
75 changed files with 1148 additions and 1409 deletions

No files matched your search

@@ -1,57 +0,0 @@
---
name: "[English] Bug report"
about: Create a report to help us improve
title: "[BUG] "
labels: ''
assignees: ''
---
<!-- Be sure to put a clear title after [BUG] in the text box above -->
<!-- Be sure to put a clear title after [BUG] in the text box above -->
<!-- Be sure to put a clear title after [BUG] in the text box above -->
**Describe the bug**
A clear and concise description of what the bug is.
**To Reproduce**
Steps to reproduce the behavior:
1. Go to '...'
2. Click on '....'
3. Scroll down to '....'
4. See error
**Expected behavior**
A clear and concise description of what you expected to happen.
**Screenshots**
If applicable, add screenshots to help explain your problem.
**Device Info (please complete the following information):**
- Device: [e.g. Pixel 4]
- ROM: [e.g: AOSP]
- ROM Version:
- Android Version [e.g. 10]
**Application Info (please complete the following information):**
- Version: [e.g. 1.1.10]
- Apk File Name: [e.g. app-release-arm64-v8a.apk]
- Distribution Channel: [e.g. Google Play]
**Additional context**
Add any other context about the problem here.
**Configure**
Paste configure file which **removed server info**
```yaml
# paste here
```
**Logs**
Paste logs to help detect problem
```
<paste here>
```
+106
View File
@@ -0,0 +1,106 @@
name: "[English] Bug Report"
description: "Create a report to help us debug bugs"
title: "[BUG] "
body:
- type: markdown
attributes:
value: |
Thanks for taking the time to fill out this bug report!
NOTE: Be sure to put a clear and concise title **AFTER** `[BUG]` in the text box above.
NOTE: We do not provide any services such as proxies, DO NOT feedback any problems not caused by this application here.
<!-- template -->
- type: textarea
id: description
attributes:
label: "Describe the bug"
description: "A clear and concise description of what the bug is."
validations:
required: true
- type: textarea
id: reproduce
attributes:
label: "To Reproduce"
description: "Steps to reproduce the behavior:"
value: |
Step 1: ...
Step 2: ...
Step 3: ...
...
validations:
required: true
- type: textarea
id: device-info
attributes:
label: "Device Info"
description: |
Input your device information.
Example:
- Device: Pixel 4
- ROM: AOSP
- Android Version: 10
value: |
- Device:
- ROM:
- Android Version:
validations:
required: true
- type: textarea
id: app-info
attributes:
label: "Application Info"
description: |
Input application you are using information.
Example:
```
- Version: 2.5.4-premium
- APK filename: cfa-2.5.4-premium-arm64-v8a-release.apk
- Distribution Channel: Google Play
```
value: |
- Version:
- APK filename:
- Distribution Channel:
validations:
required: true
- type: textarea
id: configure
attributes:
render: yml
label: "Configure File"
description: |
Please paste or upload the configuration file here.
TIPS: If you only have a subscription link, please use your browser to download it.
**NOTE: Please remove proxies from the configuration file before uploading it.**
**NOTE: Please remove proxies from the configuration file before uploading it.**
**NOTE: Please remove proxies from the configuration file before uploading it.**
validations:
required: true
- type: textarea
id: logs
attributes:
render: raw
label: "Logs"
description: |
Please paste or upload the log file here.
TIPS: Please use the `Logcat` in application or `adb logcat`. `adb logcat` would be better.
validations:
required: true
- type: textarea
id: screenshot
attributes:
label: "Screenshot"
description: "If applicable, add screenshots to help explain your problem."
placeholder: "Optional"
- type: textarea
id: additional
attributes:
label: "Additional"
description: "Add any other context about the problem here."
@@ -1,24 +0,0 @@
---
name: "[English] Feature request"
about: Suggest an idea for this app
title: "[Feature Request] "
labels: ''
assignees: ''
---
<!-- Be sure to put a clear title after [Feature Request] in the text box above -->
<!-- Be sure to put a clear title after [Feature Request] in the text box above -->
<!-- Be sure to put a clear title after [Feature Request] in the text box above -->
**Is your feature request related to a problem? Please describe.**
A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
**Describe the solution you'd like**
A clear and concise description of what you want to happen.
**Describe alternatives you've considered**
A clear and concise description of any alternative solutions or features you've considered.
**Additional context**
Add any other context or screenshots about the feature request here.
@@ -0,0 +1,26 @@
name: "[English] Feature Request"
description: "Create a report to help us improve"
title: "[Feature Request] "
body:
- type: markdown
attributes:
value: |
Thanks for taking the time to fill out this feature request!
NOTE: Be sure to put a clear and concise title **AFTER** `[Feature Request]` in the text box above.
<!-- template -->
- type: textarea
id: "description"
attributes:
label: "Feature Description"
description: |
A clear and concise description of the feature.
validations:
required: true
- type: textarea
id: "additional"
attributes:
label: "Additional"
description: |
Add any other context or screenshots about the feature request here.
@@ -1,55 +0,0 @@
---
name: "[简体中文] 创建错误报告"
about: 创建错误报告以帮助我们改进应用
title: "[BUG] "
labels: ''
assignees: ''
---
<!-- 请务必在上方文本框处 [BUG] 后填入清晰明了的标题 -->
<!-- 请务必在上方文本框处 [BUG] 后填入清晰明了的标题 -->
<!-- 请务必在上方文本框处 [BUG] 后填入清晰明了的标题 -->
**描述出现的错误**
请简洁的描述你遇到的错误
**如何复现该错误**
复现步骤:
1. ...
2. ...
3. ...
4. ...
**预期行为**
清晰简单的描述你预期的应用应该表现的行为
**屏幕截图**
如果适用, 上传屏幕截图以帮助描述错误
**设备信息 (请完成以下信息):**
- 机型: [例如: Pixel 4]
- 系统/ROM: [例如: MIUI 11]
- Android 版本 [例如: 10]
- ROM版本 [例如: 20.3.19]
**应用信息**
- 版本: [例如: 1.1.10]
- 安装包文件名: [例如: app-release-arm64-v8a.apk]
- 应用来源: [例如: Google Play]
**附加信息**
其他的可能与改错误相关的信息
**配置文件**
在此粘贴 **去除服务器信息的** 的 **配置文件**
```yaml
# 在此粘贴
```
**日志**
粘贴日志以帮助侦测错误
```
<在此粘贴>
```
@@ -0,0 +1,107 @@
name: "[简体中文] 错误报告"
description: "创建错误报告以帮助我们修正应用"
title: "[BUG] "
body:
- type: markdown
attributes:
value: |
感谢您在百忙之中填写此错误报告。
注意: 请务必在上方文本框的 `[BUG]` **之后**填写清晰明了的标题。
注意:这里不提供像是代理服务器之类的服务,请不要反馈非应用自身引起的问题。
<!-- template -->
- type: textarea
id: description
attributes:
label: "描述此错误"
description: "请清晰简洁的描述你遇到的错误。"
validations:
required: true
- type: textarea
id: reproduce
attributes:
label: "如何复现该错误"
description: "复现步骤:"
value: |
步骤 1: ...
步骤 2: ...
步骤 3: ...
...
validations:
required: true
- type: textarea
id: device-info
attributes:
label: "设备信息"
description: |
输入您正在使用的设备信息。
例子:
- 机型: Pixel 4
- 系统类型: MIUI/AOSP
- Android 版本: 10
value: |
- 机型:
- 系统类型:
- Android 版本:
validations:
required: true
- type: textarea
id: app-info
attributes:
label: "应用信息"
description: |
输入您正在使用的应用信息。
例子:
```
- 版本: 2.5.4-premium
- 安装包文件名: cfa-2.5.4-premium-arm64-v8a-release.apk
- 应用来源: Google Play
```
value: |
- 版本:
- 安装包文件名:
- 应用来源:
validations:
required: true
- type: textarea
id: configure
attributes:
render: yml
label: "配置文件"
description: |
请在此粘贴和上传配置文件。
提示:如果您仅有一个订阅链接,请使用浏览器打开此链接以下载配置文件。
**注意: 请在上传配置文件前,移除其中的代理服务器信息。**
**注意: 请在上传配置文件前,移除其中的代理服务器信息。**
**注意: 请在上传配置文件前,移除其中的代理服务器信息。**
validations:
required: true
- type: textarea
id: logs
attributes:
render: raw
label: "日志"
description: |
请在此粘贴或上传日志。
提示: 请使用应用内的 `Logcat` 或 `adb logcat` 捕获日志. `adb logcat` 能更好地帮助侦测问题.
validations:
required: true
- type: textarea
id: screenshot
attributes:
label: "屏幕截图"
description: "如果适用,请在此粘贴或上传屏幕截图。"
placeholder: "可选"
- type: textarea
id: additional
attributes:
label: "附加信息"
description: "其他的可能与改错误相关的信息。"
placeholder: "可选"
@@ -1,21 +0,0 @@
---
name: "[简体中文] 功能请求"
about: 你希望的能够在应用中增加的功能
title: "[Feature Request] "
labels: ''
assignees: ''
---
<!-- 请务必在上方文本框处 [Feature Request] 后填入清晰明了的标题 -->
<!-- 请务必在上方文本框处 [Feature Request] 后填入清晰明了的标题 -->
<!-- 请务必在上方文本框处 [Feature Request] 后填入清晰明了的标题 -->
**功能描述**
请清晰的描述你想要的功能
**描述你希望的实现方式**
清晰的描述应用应该如何实现该功能
**附加信息**
其他的与改功能相关的附加信息
@@ -0,0 +1,26 @@
name: "[简体中文] 功能请求"
description: "您希望的能够在应用中增加功能"
title: "[Feature Request] "
body:
- type: markdown
attributes:
value: |
感谢您在百忙之中填写此功能请求报告。
注意: 请务必在上方文本框的 `[Feature Request]` **之后**填写清晰明了的标题。
<!-- template -->
- type: textarea
id: "description"
attributes:
label: "功能描述"
description: |
简介明了的描述此功能。
validations:
required: true
- type: textarea
id: "additional"
attributes:
label: "附加信息"
description: |
与此功能相关的其他附加信息。
+20 -12
View File
@@ -4,6 +4,7 @@ on:
branches:
- main
paths-ignore:
- '.github/**'
- '.idea/**'
- '.gitattributes'
- '.gitignore'
@@ -13,6 +14,7 @@ on:
- 'NOTICE'
pull_request:
paths-ignore:
- '.github/**'
- '.idea/**'
- '.gitattributes'
- '.gitignore'
@@ -20,27 +22,33 @@ on:
- '**.md'
- 'LICENSE'
- 'NOTICE'
jobs:
BuildUnsigned:
runs-on: ubuntu-latest
steps:
- name: Checkout Repository
uses: actions/checkout@v2
uses: actions/checkout@v3
with:
submodules: recursive
- name: Setup Java
uses: actions/setup-java@v2
uses: actions/setup-java@v3
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') }}
distribution: 'zulu'
java-version: 17
- name: Setup Go
uses: actions/setup-go@v2
uses: actions/setup-go@v3
with:
go-version: 1.17
go-version: 1.18
- uses: actions/cache@v3
with:
path: |
~/.cache/go-build
~/go/pkg/mod
key: ${{ runner.os }}-go-${{ hashFiles('**/go.sum') }}
restore-keys: |
${{ runner.os }}-go-
- name: Build
run: ./gradlew --no-daemon app:assembleFossRelease
uses: gradle/gradle-build-action@v2
with:
arguments: --no-daemon app:assembleFossRelease
+5 -14
View File
@@ -4,24 +4,19 @@ The Clash for Android is built as an Open Source software. This app is provided
This page is used to inform visitors regarding our policies with the collection, use, and disclosure of Personal Information if anyone decided to use our app.
If you choose to use our app, then you agree to the collection and use of information in relation to this policy. The Personal Information that we collect is used for providing and improving the app. We will not use or share your information with anyone except as described in this Privacy Policy.
The terms used in this Privacy Policy have the same meanings as in our Terms and Conditions, which is accessible at Clash for Android unless otherwise defined in this Privacy Policy.
**Information Collection and Use**
For a better experience, while using our app, we may require you to provide us with certain personally identifiable information. The information that we request will be retained by us and used as described in this privacy policy.
We will not upload any of your personally information and that will be stored in the internal storage or memory.
The app does use third party services that may collect information used to identify you.
We collect the following information and store it in memory, and such information will be destroyed when the application is fully exited.
Link to privacy policy of third party service providers used by the app
- Installed Applications
* [Google Play Services](https://www.google.com/policies/privacy/)
* [AppCenter](https://docs.microsoft.com/en-us/appcenter/gdpr/)
This data is used for the PROCESS-NAME rule.
**Log Data**
We want to inform you that whenever you use our app, in a case of an error in the app we collect data and information (through third party products) on your phone called Log Data. This Log Data may include information such as your device Internet Protocol (“IP”) address, device name, operating system version, the configuration of the app when utilizing our App, the time and date of your use of the app, and other statistics.
We do not collect log data unless you use log collector.
**Cookies**
@@ -37,10 +32,6 @@ We value your trust in providing us your Personal Information, thus we are striv
This app may contain links to other sites. If you click on a third-party link, you will be directed to that site. Note that these external sites are not operated by us. Therefore, we strongly advise you to review the Privacy Policy of these websites. We have no control over and assume no responsibility for the content, privacy policies, or practices of any third-party sites or services.
**Children’s Privacy**
These Services do not address anyone under the age of 13\. We do not knowingly collect personally identifiable information from children under 13\. In the case we discover that a child under 13 has provided us with personal information, we immediately delete this from our servers. If you are a parent or guardian and you are aware that your child has provided us with personal information, please contact us so that we will be able to do necessary actions.
**Changes to This Privacy Policy**
We may update our Privacy Policy from time to time. Thus, you are advised to review this page periodically for any changes. We will notify you of any changes by posting the new Privacy Policy on this page. These changes are effective immediately after they are posted on this page.
+1 -1
View File
@@ -53,4 +53,4 @@ See also [PRIVACY_POLICY.md](./PRIVACY_POLICY.md)
./gradlew app:assembleFossRelease
```
6. Pick `app-foss-<arch>-release.apk` in `app/build/outputs/apk/foss/release/`
6. Pick `app-<version>-foss-<arch>-release.apk` in `app/build/outputs/apk/foss/release/`
+8 -13
View File
@@ -12,19 +12,14 @@ dependencies {
implementation(project(":design"))
implementation(project(":common"))
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)
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)
}
tasks.getByName("clean", type = Delete::class) {
@@ -1,14 +0,0 @@
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
}
}
@@ -76,11 +76,8 @@ class AccessControlActivity : BaseActivity<AccessControlDesign>() {
val data = clipboard?.primaryClip
if (data != null && data.itemCount > 0) {
val all = withContext(Dispatchers.IO) {
val packages = data.getItemAt(0).text.split("\n").toSet()
design.apps.map(AppInfo::packageName).intersect(packages)
}
val packages = data.getItemAt(0).text.split("\n").toSet()
val all = design.apps.map(AppInfo::packageName).intersect(packages)
selected.clear()
selected.addAll(all)
@@ -91,14 +88,12 @@ class AccessControlActivity : BaseActivity<AccessControlDesign>() {
AccessControlDesign.Request.Export -> {
val clipboard = getSystemService<ClipboardManager>()
withContext(Dispatchers.IO) {
val data = ClipData.newPlainText(
"packages",
selected.joinToString("\n")
)
val data = ClipData.newPlainText(
"packages",
selected.joinToString("\n")
)
clipboard?.setPrimaryClip(data)
}
clipboard?.setPrimaryClip(data)
}
}
}
@@ -116,7 +116,7 @@ class FilesActivity : BaseActivity<FilesDesign>() {
}
is FilesDesign.Request.ExportFile -> {
val uri: Uri? = startActivityForResult(
ActivityResultContracts.CreateDocument(),
ActivityResultContracts.CreateDocument("text/plain"),
it.file.name
)
@@ -67,7 +67,7 @@ class LogcatActivity : BaseActivity<LogcatDesign>() {
}
LogcatDesign.Request.Export -> {
val output = startActivityForResult(
ActivityResultContracts.CreateDocument(),
ActivityResultContracts.CreateDocument("text/plain"),
file.fileName
)
@@ -19,9 +19,6 @@ class MainApplication : Application() {
override fun onCreate() {
super.onCreate()
// Initialize AppCenter
Tracker.initialize(this)
val processName = currentProcessName
Log.d("Process $processName started")
@@ -5,10 +5,8 @@ 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
@@ -28,8 +26,6 @@ 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()
@@ -9,7 +9,12 @@
android:translateY="103.4632">
<path
android:fillColor="#1E4376"
android:pathData="M47.211,168.128C70.531,-34.962 67.471,13.788 94.071,43.818c13.45,-1.52 27.24,-3.47 40.82,-0.67c2.64,0.13 5.42,1.86 7.71,0.18c4.12,-6.27 7.35,-13.54 11.35,-20c12.19,-24.44 12.85,19.54 15.48,26.52c5.23,32.99 10.89,64.46 14.67,97.59c0.31,10.72 5.74,32.92 1.08,33.56c-49.36,5.23 -147.71,3.91 -160.84,-6.3c-15.85,-10.5 -15.18,-35.33 2.03,-43.72c3.63,-2.03 10.68,-3.72 11.94,0.7c-2.41,4.99 -8.79,5.77 -12.12,11.17C16.621,158.948 33.111,168.888 47.211,168.128zM87.841,74.008c-10.42,0.52 -9.59,14.89 -0.07,15.18C98.191,88.668 97.361,74.298 87.841,74.008zM149.121,89.188c10.46,-0.34 9.85,-14.71 0.38,-15.18C139.031,74.348 139.651,88.718 149.121,89.188zM107.871,99.228c2.16,3.48 5.28,3.29 9.79,0.16c3.81,3.17 8.06,3.28 9.18,-0.19c-3.78,1.17 -7.04,0.79 -9.4,-3.49C115.371,100.108 112.071,100.428 107.871,99.228z"
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,31 +0,0 @@
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"))
)
}
}
}
}
+27 -41
View File
@@ -12,51 +12,39 @@ buildscript {
maven("https://maven.kr328.app/releases")
}
dependencies {
classpath(deps.build.android)
classpath(deps.build.kotlin.common)
classpath(deps.build.kotlin.serialization)
classpath(deps.build.ksp)
classpath(deps.build.golang)
classpath(libs.build.android)
classpath(libs.build.kotlin.common)
classpath(libs.build.kotlin.serialization)
classpath(libs.build.ksp)
classpath(libs.build.golang)
}
}
allprojects {
subprojects {
repositories {
mavenCentral()
google()
maven("https://maven.kr328.app/releases")
}
}
subprojects {
val isApp = name == "app"
apply(plugin = if (isApp) "com.android.application" else "com.android.library")
extensions.configure<BaseExtension> {
val minSdkVersion = 21
val targetSdkVersion = 31
val buildVersionCode = 205002
val buildVersionName = "2.5.2"
val defaultDimension = "feature"
ndkVersion = "23.0.7599858"
compileSdkVersion(targetSdkVersion)
defaultConfig {
if (isApp) {
applicationId = "com.github.kr328.clash"
}
minSdk = minSdkVersion
targetSdk = targetSdkVersion
minSdk = 21
targetSdk = 31
versionName = buildVersionName
versionCode = buildVersionCode
versionName = "2.5.12"
versionCode = 205012
resValue("string", "release_name", "v$buildVersionName")
resValue("integer", "release_code", "$buildVersionCode")
resValue("string", "release_name", "v$versionName")
resValue("integer", "release_code", "$versionCode")
externalNativeBuild {
cmake {
@@ -71,18 +59,24 @@ subprojects {
}
}
ndkVersion = "23.0.7599858"
compileSdkVersion(defaultConfig.targetSdk!!)
if (isApp) {
packagingOptions {
excludes.add("DebugProbesKt.bin")
resources {
excludes.add("DebugProbesKt.bin")
}
}
}
productFlavors {
flavorDimensions(defaultDimension)
flavorDimensions("feature")
create("foss") {
isDefault = true
dimension = defaultDimension
dimension = flavorDimensionList[0]
versionNameSuffix = ".foss"
buildConfigField("boolean", "PREMIUM", "Boolean.parseBoolean(\"false\")")
@@ -92,23 +86,10 @@ subprojects {
}
}
create("premium") {
dimension = defaultDimension
dimension = flavorDimensionList[0]
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")!!}\""
)
}
}
}
@@ -149,6 +130,11 @@ subprojects {
}
}
variantFilter {
ignore = name.startsWith("premium") && !project(":core")
.file("src/premium/golang/clash/go.mod").exists()
}
if (isApp) {
this as AppExtension
+2 -2
View File
@@ -6,6 +6,6 @@ plugins {
dependencies {
compileOnly(project(":hideapi"))
implementation(deps.kotlin.coroutine)
implementation(deps.androidx.core)
implementation(libs.kotlin.coroutine)
implementation(libs.androidx.core)
}
@@ -2,6 +2,8 @@ package com.github.kr328.clash.common.compat
import android.app.ActivityThread
import android.app.Application
import android.graphics.drawable.AdaptiveIconDrawable
import android.graphics.drawable.Drawable
import android.os.Build
import com.github.kr328.clash.common.log.Log
@@ -18,3 +20,12 @@ val Application.currentProcessName: String
packageName
}
}
fun Drawable.foreground(): Drawable {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O &&
this is AdaptiveIconDrawable && this.background == null
) {
return this.foreground
}
return this
}
+3 -3
View File
@@ -57,9 +57,9 @@ android {
dependencies {
implementation(project(":common"))
implementation(deps.androidx.core)
implementation(deps.kotlin.coroutine)
implementation(deps.kotlin.serialization.json)
implementation(libs.androidx.core)
implementation(libs.kotlin.coroutine)
implementation(libs.kotlin.serialization.json)
}
afterEvaluate {
+16 -13
View File
@@ -1,33 +1,36 @@
module foss
go 1.17
go 1.18
require cfa v0.0.0
require (
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-20211116115317-bc437243ffbb // indirect
github.com/Kr328/tun2socket v0.0.0-20220414050025-d07c78d06d34 // indirect
github.com/dlclark/regexp2 v1.4.0 // indirect
github.com/gofrs/uuid v4.1.0+incompatible // indirect
github.com/gorilla/websocket v1.4.2 // indirect
github.com/insomniacslk/dhcp v0.0.0-20211026125128-ad197bcd36fd // indirect
github.com/gofrs/uuid v4.2.0+incompatible // indirect
github.com/gorilla/websocket v1.5.0 // indirect
github.com/insomniacslk/dhcp v0.0.0-20220504074936-1ca156eafb9f // indirect
github.com/kr/pretty v0.1.0 // indirect
github.com/miekg/dns v1.1.43 // indirect
github.com/oschwald/geoip2-golang v1.5.0 // indirect
github.com/oschwald/maxminddb-golang v1.8.0 // indirect
github.com/miekg/dns v1.1.49 // indirect
github.com/oschwald/geoip2-golang v1.7.0 // indirect
github.com/oschwald/maxminddb-golang v1.9.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-20211108221036-ceb1ce70b4fa // indirect
golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2 // indirect
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c // indirect
golang.org/x/sys v0.0.0-20211116061358-0a5406a5449c // indirect
golang.org/x/crypto v0.0.0-20220525230936-793ad666bf5e // indirect
golang.org/x/mod v0.4.2 // indirect
golang.org/x/net v0.0.0-20220617184016-355a448f1bc9 // indirect
golang.org/x/sync v0.0.0-20220601150217-0de741cfad7f // indirect
golang.org/x/sys v0.0.0-20220615213510-4f61da869c0c // 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
gopkg.in/yaml.v3 v3.0.1 // indirect
)
replace cfa => ../../main/golang
+44 -47
View File
@@ -1,31 +1,24 @@
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-20211116115317-bc437243ffbb h1:UT3Nqwlto5MxI17z+d+ShFIIfN1r+hTFuNLSb1wmS6M=
github.com/Kr328/tun2socket v0.0.0-20211116115317-bc437243ffbb/go.mod h1:YR9wK13TgI5ww8iKWm91MHiSoHC7Oz0U4beCCmtXqLw=
github.com/Kr328/tun2socket v0.0.0-20220414050025-d07c78d06d34 h1:USCTqih5d1bUXUxWNS9ZD5Tx/lb0jXHEtRIIx/F9dMc=
github.com/Kr328/tun2socket v0.0.0-20220414050025-d07c78d06d34/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/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.5/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.1.0+incompatible h1:sIa2eCvUTwgjbqXrPLfNwUf9S3i3mpH1O1atV+iL/Wk=
github.com/gofrs/uuid v4.1.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/gorilla/websocket v1.5.0 h1:PPwGk2jz7EePpoHN/+ClbZu8SPxiqlu12wZP/3sWmnc=
github.com/gorilla/websocket v1.5.0/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-20211026125128-ad197bcd36fd h1:jupbuQFZtwOBg/3EmK91/rGaYFkqCb9bwHOnwn7Cav0=
github.com/insomniacslk/dhcp v0.0.0-20211026125128-ad197bcd36fd/go.mod h1:h+MxyHxRg9NH3terB1nfRIUaQEcI0XOVkdR9LNBlp8E=
github.com/insomniacslk/dhcp v0.0.0-20220504074936-1ca156eafb9f h1:l1QCwn715k8nYkj4Ql50rzEog3WnMdrd4YYMMwemxEo=
github.com/insomniacslk/dhcp v0.0.0-20220504074936-1ca156eafb9f/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=
@@ -34,9 +27,8 @@ github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfV
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/kr328/tun2socket v0.0.0-20211114060954-370f53a7d3d7/go.mod h1:4NsuTykBBcrx78C3WMzjkIMC2vJicF6nSQUm1alZqYM=
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
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=
@@ -44,12 +36,12 @@ github.com/mdlayher/netlink v1.1.0/go.mod h1:H4WCitaheIsdF9yOYu8CFmCgQthAPIWZmcK
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/miekg/dns v1.1.49 h1:qe0mQU3Z/XpFeE+AEBo2rqaS1IPBJ3anmqZ4XiZJVG8=
github.com/miekg/dns v1.1.49/go.mod h1:e3IlAVfNqAllflbibAZEWOXOQ+Ynzk/dDozDxY7XnME=
github.com/oschwald/geoip2-golang v1.7.0 h1:JW1r5AKi+vv2ujSxjKthySK3jo8w8oKWPyXsw+Qs/S8=
github.com/oschwald/geoip2-golang v1.7.0/go.mod h1:mdI/C7iK7NVMcIDDtf4bCKMJ7r0o7UwGeCo9eiitCMQ=
github.com/oschwald/maxminddb-golang v1.9.0 h1:tIk4nv6VT9OiPyrnDAfJS1s1xKDQMZOsGojab6EjC1Y=
github.com/oschwald/maxminddb-golang v1.9.0/go.mod h1:TK+s/Z2oZq0rSl4PSeAEoP0bgm82Cp5HyvYbt8K3zLY=
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/sirupsen/logrus v1.8.1 h1:dJKuHgqk1NNQlqoA6BTlM1Wf9DOH3NBjQyu0h9+AZZE=
@@ -59,41 +51,41 @@ github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9
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.7.2 h1:4jaiDzPyXQvSd7D0EjG45355tLlV3VOECpq10pLC+8s=
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.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-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
golang.org/x/crypto v0.0.0-20211108221036-ceb1ce70b4fa h1:idItI2DDfCokpg0N51B2VtiLdJ4vAuXC9fnCb2gACo4=
golang.org/x/crypto v0.0.0-20211108221036-ceb1ce70b4fa/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
golang.org/x/crypto v0.0.0-20220525230936-793ad666bf5e h1:T8NU3HyQ8ClP4SEE+KbFlg6n0NhuTsN4MyznaarGsZM=
golang.org/x/crypto v0.0.0-20220525230936-793ad666bf5e/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.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/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
golang.org/x/net v0.0.0-20211105192438-b53810dc28af/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2 h1:CIJ76btIcR3eFI5EgSo6k1qKw9KJexJuRLI9G7Hp5wE=
golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c h1:5KslGYwFpkhGh+Q16bwMP3cOontH8FOep7tGV86Y7SQ=
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-20220617184016-355a448f1bc9 h1:Yqz/iviulwKwAREEeUd3nbBFn0XuyJqkoft2IlrvOhc=
golang.org/x/net v0.0.0-20220617184016-355a448f1bc9/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20220601150217-0de741cfad7f h1:Ax0t5p6N38Ga0dThY21weqDEyz2oklo4IvDkpigvkD8=
golang.org/x/sync v0.0.0-20220601150217-0de741cfad7f/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=
@@ -103,21 +95,19 @@ golang.org/x/sys v0.0.0-20190606122018-79a91cf218c4/go.mod h1:h1NjWce9XRLGQEsW7w
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-20211107104306-e0b2ad06fe42/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20211110154304-99a53858aa08/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/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220615213510-4f61da869c0c h1:aFV+BgZ4svzjfabn8ERpuB4JI4N6/rdy1iusx77G3oU=
golang.org/x/sys v0.0.0-20220615213510-4f61da869c0c/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.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
@@ -126,12 +116,19 @@ 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=
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=
+3 -3
View File
@@ -1,11 +1,11 @@
module cfa
go 1.17
go 1.18
require (
github.com/Dreamacro/clash v1.7.1
github.com/Kr328/tun2socket v0.0.0-20220414050025-d07c78d06d34
github.com/dlclark/regexp2 v1.4.0
github.com/kr328/tun2socket v0.0.0-20211114060954-370f53a7d3d7
github.com/miekg/dns v1.1.43
github.com/oschwald/geoip2-golang v1.5.0
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c
@@ -23,6 +23,6 @@ require (
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-20211110154304-99a53858aa08 // indirect
golang.org/x/sys v0.0.0-20220319134239-a9b59b0215f8 // indirect
golang.org/x/text v0.3.6 // indirect
)
+4 -10
View File
@@ -2,15 +2,14 @@ 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-20220414050025-d07c78d06d34 h1:USCTqih5d1bUXUxWNS9ZD5Tx/lb0jXHEtRIIx/F9dMc=
github.com/Kr328/tun2socket v0.0.0-20220414050025-d07c78d06d34/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/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=
@@ -29,8 +28,6 @@ github.com/jsimonetti/rtnetlink v0.0.0-20200117123717-f846d4f6c1f4/go.mod h1:WGu
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/kr328/tun2socket v0.0.0-20211114060954-370f53a7d3d7 h1:ln3WnceaKthifUEYKWyiZmZfPH88FTKbOHrEfSCd3dk=
github.com/kr328/tun2socket v0.0.0-20211114060954-370f53a7d3d7/go.mod h1:4NsuTykBBcrx78C3WMzjkIMC2vJicF6nSQUm1alZqYM=
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=
@@ -95,12 +92,9 @@ golang.org/x/sys v0.0.0-20201009025420-dfb3f7c4e634/go.mod h1:h1NjWce9XRLGQEsW7w
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-20211110154304-99a53858aa08 h1:WecRHqgE09JBkh/584XIE6PMz5KKE/vER4izNUi30AQ=
golang.org/x/sys v0.0.0-20211110154304-99a53858aa08/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220319134239-a9b59b0215f8 h1:OH54vjqzRWmbJ62fjuhxy7AxFFgoHN0/DPc/UrL8cAs=
golang.org/x/sys v0.0.0-20220319134239-a9b59b0215f8/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.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
+7 -3
View File
@@ -2,7 +2,6 @@ package app
import (
"net"
"strings"
"syscall"
"cfa/native/platform"
@@ -16,10 +15,15 @@ func MarkSocket(fd int) {
}
func QuerySocketUid(source, target net.Addr) int {
protocol := syscall.IPPROTO_TCP
var protocol int
if strings.HasPrefix(source.String(), "udp") {
switch source.Network() {
case "udp", "udp4", "udp6":
protocol = syscall.IPPROTO_UDP
case "tcp", "tcp4", "tcp6":
protocol = syscall.IPPROTO_TCP
default:
return -1
}
if PlatformVersion() < 29 {
+22 -5
View File
@@ -4,21 +4,38 @@ var (
defaultNameServers = []string{
"223.5.5.5",
"119.29.29.29",
"8.8.8.8",
"1.1.1.1",
"8.8.4.4",
"1.0.0.1",
}
defaultFakeIPFilter = []string{
// stun services
// Stun Services
"+.stun.*.*",
"+.stun.*.*.*",
"+.stun.*.*.*.*",
"+.stun.*.*.*.*.*",
// Google Voices
"lens.l.google.com",
"stun.l.google.com",
// Nintendo Switch
// Nintendo Switch STUN
"*.n.n.srv.nintendo.net",
// PlayStation STUN
"+.stun.playstation.net",
// XBox
"xbox.*.*.microsoft.com",
"*.*.xboxlive.com",
// Microsoft Captive Portal
"*.msftncsi.com",
"*.msftconnecttest.com",
// Bilibili CDN
"*.mcdn.bilivideo.cn",
// Windows Default LAN WorkGroup
"WORKGROUP",
}
defaultFakeIPRange = "28.0.0.0/8"
)
+1 -1
View File
@@ -124,7 +124,7 @@ func FetchAndValid(
return err
}
forEachProviders(rawCfg, func(index int, total int, name string, provider map[string]interface{}) {
forEachProviders(rawCfg, func(index int, total int, name string, provider map[string]any) {
bytes, _ := json.Marshal(&Status{
Action: "FetchProviders",
Args: []string{name},
+1 -6
View File
@@ -9,7 +9,6 @@ import (
"gopkg.in/yaml.v2"
"cfa/native/app"
"github.com/Dreamacro/clash/constant"
"github.com/Dreamacro/clash/log"
"github.com/Dreamacro/clash/config"
@@ -87,11 +86,7 @@ func Load(path string) error {
}
func LoadDefault() {
rawConfig, _ := config.UnmarshalRawConfig([]byte{})
_ = patchDns(rawConfig, constant.Path.HomeDir())
cfg, err := config.ParseRawConfig(rawConfig)
cfg, err := config.Parse([]byte{})
if err != nil {
panic(err.Error())
}
@@ -14,7 +14,7 @@ const (
OverrideSlotSession
)
const defaultPersistOverride = `{"dns":{"enable": false}}`
const defaultPersistOverride = `{"dns":{"enable": false}, "redir-port": 0, "tproxy-port": 0}`
const defaultSessionOverride = `{}`
var sessionOverride = defaultSessionOverride
@@ -65,4 +65,4 @@ func ClearOverride(slot OverrideSlot) {
case OverrideSlotSession:
sessionOverride = defaultSessionOverride
}
}
}
+2 -25
View File
@@ -5,7 +5,6 @@ import (
"errors"
"fmt"
"strings"
"time"
"github.com/dlclark/regexp2"
@@ -17,18 +16,13 @@ import (
"github.com/Dreamacro/clash/dns"
)
const (
defaultHealthCheckUrl = "https://www.gstatic.com/generate_204"
defaultHealthCheckInterval = time.Hour
)
var processors = []processor{
patchOverride,
patchGeneral,
patchProfile,
patchDns,
patchProviders,
patchProxyGroup,
patchTun,
validConfig,
}
@@ -70,9 +64,6 @@ func patchDns(cfg *config.RawConfig, _ string) error {
EnhancedMode: C.DNSFakeIP,
FakeIPRange: defaultFakeIPRange,
FakeIPFilter: defaultFakeIPFilter,
FallbackFilter: config.RawFallbackFilter{
GeoIP: false,
},
}
cfg.ClashForAndroid.AppendSystemDNS = true
@@ -86,7 +77,7 @@ func patchDns(cfg *config.RawConfig, _ string) error {
}
func patchProviders(cfg *config.RawConfig, profileDir string) error {
forEachProviders(cfg, func(index int, total int, key string, provider map[string]interface{}) {
forEachProviders(cfg, func(index int, total int, key string, provider map[string]any) {
if path, ok := provider["path"].(string); ok {
provider["path"] = profileDir + "/providers/" + common.ResolveAsRoot(path)
}
@@ -95,20 +86,6 @@ func patchProviders(cfg *config.RawConfig, profileDir string) error {
return nil
}
func patchProxyGroup(cfg *config.RawConfig, _ string) error {
for _, g := range cfg.ProxyGroup {
if _, exist := g["url"]; !exist {
g["url"] = defaultHealthCheckUrl
}
if _, exist := g["interval"]; !exist {
g["interval"] = int(defaultHealthCheckInterval.Seconds())
}
}
return nil
}
func validConfig(cfg *config.RawConfig, _ string) error {
if len(cfg.Proxy) == 0 && len(cfg.ProxyProvider) == 0 {
return errors.New("profile does not contain `proxies` or `proxy-providers`")
@@ -0,0 +1,9 @@
//go:build !premium
package config
import "github.com/Dreamacro/clash/config"
func patchTun(cfg *config.RawConfig, _ string) error {
return nil
}
@@ -0,0 +1,11 @@
//go:build premium
package config
import "github.com/Dreamacro/clash/config"
func patchTun(cfg *config.RawConfig, _ string) error {
cfg.Tun.Enable = false
return nil
}
@@ -1,4 +1,4 @@
// +build !premium
//go:build !premium
package config
@@ -8,7 +8,7 @@ import (
"github.com/Dreamacro/clash/config"
)
func forEachProviders(rawCfg *config.RawConfig, fun func(index int, total int, key string, provider map[string]interface{})) {
func forEachProviders(rawCfg *config.RawConfig, fun func(index int, total int, key string, provider map[string]any)) {
total := len(rawCfg.ProxyProvider)
index := 0
@@ -1,4 +1,4 @@
// +build premium
//go:build premium
package config
@@ -8,7 +8,7 @@ import (
"github.com/Dreamacro/clash/config"
)
func forEachProviders(rawCfg *config.RawConfig, fun func(index int, total int, key string, provider map[string]interface{})) {
func forEachProviders(rawCfg *config.RawConfig, fun func(index int, total int, key string, provider map[string]any)) {
total := len(rawCfg.ProxyProvider) + len(rawCfg.RuleProvider)
index := 0
+3 -2
View File
@@ -6,11 +6,12 @@ import (
"cfa/blob"
"cfa/native/app"
"cfa/native/platform"
"github.com/Dreamacro/clash/component/process"
"github.com/Dreamacro/clash/log"
"cfa/native/app"
"cfa/native/platform"
"github.com/Dreamacro/clash/component/dialer"
"github.com/Dreamacro/clash/component/mmdb"
"github.com/Dreamacro/clash/constant"
@@ -1,3 +1,5 @@
//go:build !premium
package main
//#include "bridge.h"
@@ -23,7 +25,7 @@ func init() {
defer log.UnSubscribe(sub)
for item := range sub {
msg := item.(*log.Event)
msg := item.(log.Event)
cPayload := C.CString(msg.Payload)
@@ -50,7 +52,7 @@ func subscribeLogcat(remote unsafe.Pointer) {
defer log.UnSubscribe(sub)
for i := range sub {
msg, ok := i.(*log.Event)
msg, ok := i.(log.Event)
if !ok {
continue
}
@@ -0,0 +1,75 @@
//go:build premium
package main
//#include "bridge.h"
import "C"
import (
"strings"
"time"
"unsafe"
"github.com/Dreamacro/clash/log"
)
type message struct {
Level string `json:"level"`
Message string `json:"message"`
Time int64 `json:"time"`
}
func init() {
go func() {
sub := log.Subscribe()
defer log.UnSubscribe(sub)
for msg := range sub {
cPayload := C.CString(msg.Payload)
switch msg.LogLevel {
case log.INFO:
C.log_info(cPayload)
case log.ERROR:
C.log_error(cPayload)
case log.WARNING:
C.log_warn(cPayload)
case log.DEBUG:
C.log_debug(cPayload)
case log.SILENT:
C.log_verbose(cPayload)
}
}
}()
}
//export subscribeLogcat
func subscribeLogcat(remote unsafe.Pointer) {
go func(remote unsafe.Pointer) {
sub := log.Subscribe()
defer log.UnSubscribe(sub)
for msg := range sub {
if msg.LogLevel < log.Level() && !strings.HasPrefix(msg.Payload, "[APP]") {
continue
}
rMsg := &message{
Level: msg.LogLevel.String(),
Message: msg.Payload,
Time: time.Now().UnixNano() / 1000 / 1000,
}
if C.logcat_received(remote, marshalJson(rMsg)) != 0 {
C.release_object(remote)
log.Debugln("Logcat subscriber closed")
break
}
}
}(remote)
log.Infoln("[APP] Logcat level: %s", log.Level().String())
}
+1
View File
@@ -36,6 +36,7 @@ func coreInit(home, versionName C.c_string, sdkVersion C.int) {
func reset() {
config.LoadDefault()
tunnel.ResetStatistic()
tunnel.CloseAllConnections()
runtime.GC()
}
+15 -7
View File
@@ -26,7 +26,7 @@ func QuerySocketUidFromProcFs(source, _ net.Addr) int {
network := source.Network()
if strings.HasSuffix(network, "4") {
if strings.HasSuffix(network, "4") || strings.HasSuffix(network, "6") {
network = network[:len(network)-1]
}
@@ -46,16 +46,24 @@ func QuerySocketUidFromProcFs(source, _ net.Addr) int {
return -1
}
if strings.HasSuffix(source.Network(), "6") {
sIP = sIP.To16()
} else {
sIP = sIP.To4()
}
sIP = sIP.To16()
if sIP == nil {
return -1
}
uid := doQuery(path+"6", sIP, sPort)
if uid == -1 {
sIP = sIP.To4()
if sIP == nil {
return -1
}
uid = doQuery(path, sIP, sPort)
}
return uid
}
func doQuery(path string, sIP net.IP, sPort int) int {
file, err := os.Open(path)
if err != nil {
return -1
@@ -0,0 +1,25 @@
//go:build !premium
package tun
import (
"net"
"strconv"
C "github.com/Dreamacro/clash/constant"
)
func createMetadata(lAddr, rAddr *net.TCPAddr) *C.Metadata {
return &C.Metadata{
NetWork: C.TCP,
Type: C.SOCKS5,
SrcIP: lAddr.IP,
DstIP: rAddr.IP,
SrcPort: strconv.Itoa(lAddr.Port),
DstPort: strconv.Itoa(rAddr.Port),
AddrType: C.AtypIPv4,
Host: "",
RawSrcAddr: lAddr,
RawDstAddr: rAddr,
}
}
@@ -0,0 +1,29 @@
//go:build premium
package tun
import (
"net"
"net/netip"
"strconv"
C "github.com/Dreamacro/clash/constant"
)
func createMetadata(lAddr, rAddr *net.TCPAddr) *C.Metadata {
srcAddr, _ := netip.AddrFromSlice(lAddr.IP)
dstAddr, _ := netip.AddrFromSlice(rAddr.IP)
return &C.Metadata{
NetWork: C.TCP,
Type: C.SOCKS5,
SrcIP: srcAddr,
DstIP: dstAddr,
SrcPort: strconv.Itoa(lAddr.Port),
DstPort: strconv.Itoa(rAddr.Port),
AddrType: C.AtypIPv4,
Host: "",
RawSrcAddr: lAddr,
RawDstAddr: rAddr,
}
}
+11 -17
View File
@@ -5,7 +5,6 @@ import (
"io"
"net"
"os"
"strconv"
"time"
"github.com/Kr328/tun2socket"
@@ -25,7 +24,15 @@ func Start(fd int, gateway, portal, dns string) (io.Closer, error) {
log.Debugln("TUN: fd = %d, gateway = %s, portal = %s, dns = %s", fd, gateway, portal, dns)
device := os.NewFile(uintptr(fd), "/dev/tun")
stack, err := tun2socket.StartTun2Socket(device, net.ParseIP(gateway), net.ParseIP(portal))
ip, network, err := net.ParseCIDR(gateway)
if err != nil {
panic(err.Error())
} else {
network.IP = ip
}
stack, err := tun2socket.StartTun2Socket(device, network, net.ParseIP(portal))
if err != nil {
_ = device.Close()
@@ -46,7 +53,7 @@ func Start(fd int, gateway, portal, dns string) (io.Closer, error) {
continue
}
lAddr := conn.RemoteAddr().(*net.TCPAddr)
lAddr := conn.LocalAddr().(*net.TCPAddr)
rAddr := conn.RemoteAddr().(*net.TCPAddr)
if ipv4LoopBack.Contains(rAddr.IP) {
@@ -91,20 +98,7 @@ func Start(fd int, gateway, portal, dns string) (io.Closer, error) {
continue
}
metadata := &C.Metadata{
NetWork: C.TCP,
Type: C.SOCKS5,
SrcIP: lAddr.IP,
DstIP: rAddr.IP,
SrcPort: strconv.Itoa(lAddr.Port),
DstPort: strconv.Itoa(rAddr.Port),
AddrType: C.AtypIPv4,
Host: "",
RawSrcAddr: lAddr,
RawDstAddr: rAddr,
}
tunnel.TCPIn() <- context.NewConnContext(conn, metadata)
tunnel.TCPIn() <- context.NewConnContext(conn, createMetadata(lAddr, rAddr))
}
}
@@ -5,6 +5,12 @@ import (
"github.com/Dreamacro/clash/tunnel/statistic"
)
func CloseAllConnections() {
for _, c := range statistic.DefaultManager.Snapshot().Connections {
_ = c.Close()
}
}
func closeMatch(filter func(conn C.Conn) bool) {
for _, c := range statistic.DefaultManager.Snapshot().Connections {
if cc, ok := c.(C.Conn); ok {
@@ -0,0 +1,43 @@
package tunnel
import (
"context"
"net"
"strings"
"github.com/Dreamacro/clash/component/dialer"
C "github.com/Dreamacro/clash/constant"
CTX "github.com/Dreamacro/clash/context"
"github.com/Dreamacro/clash/tunnel"
)
func init() {
dialer.DefaultTunnelDialer = func(context context.Context, network, address string) (net.Conn, error) {
if !strings.HasPrefix(network, "tcp") {
return nil, net.UnknownNetworkError("unsupported network")
}
host, port, err := net.SplitHostPort(address)
if err != nil {
return nil, err
}
left, right := net.Pipe()
metadata := &C.Metadata{
NetWork: C.TCP,
Type: C.HTTPCONNECT,
SrcIP: loopback,
SrcPort: "65535",
DstPort: port,
AddrType: C.AtypDomainName,
Host: host,
RawSrcAddr: left.RemoteAddr(),
RawDstAddr: left.LocalAddr(),
}
tunnel.TCPIn() <- CTX.NewConnContext(right, metadata)
return left, nil
}
}
@@ -0,0 +1,7 @@
//go:build !premium
package tunnel
import "net"
var loopback = net.ParseIP("127.0.0.1")
@@ -0,0 +1,7 @@
//go:build premium
package tunnel
import "net/netip"
var loopback = netip.MustParseAddr("127.0.0.1")
@@ -1,9 +1,8 @@
// +build !premium
//go:build !premium
package tunnel
import (
"errors"
"fmt"
"time"
@@ -12,8 +11,6 @@ import (
"github.com/Dreamacro/clash/tunnel"
)
var ErrInvalidType = errors.New("invalid type")
type Provider struct {
Name string `json:"name"`
VehicleType string `json:"vehicleType"`
@@ -1,4 +1,4 @@
// +build premium
//go:build premium
package tunnel
@@ -49,7 +49,7 @@ func QueryProviders() []*Provider {
for _, p := range providers {
updatedAt := time.Time{}
if s, ok := p.(P.UpdatableProvider); ok {
if s, ok := p.(P.UpdatableProvider[any]); ok {
updatedAt = s.UpdatedAt()
}
+2 -2
View File
@@ -7,7 +7,7 @@ import (
"reflect"
)
func marshalJson(obj interface{}) *C.char {
func marshalJson(obj any) *C.char {
res, err := json.Marshal(obj)
if err != nil {
panic(err.Error())
@@ -16,7 +16,7 @@ func marshalJson(obj interface{}) *C.char {
return C.CString(string(res))
}
func marshalString(obj interface{}) *C.char {
func marshalString(obj any) *C.char {
if obj == nil {
return nil
}
@@ -49,6 +49,9 @@ data class ConfigurationOverride(
@SerialName("clash-for-android")
val app: App = App(),
@SerialName("experimental")
val experimental: Experimental = Experimental()
) : Parcelable {
@Serializable
data class Dns(
@@ -107,6 +110,12 @@ data class ConfigurationOverride(
var appendSystemDns: Boolean? = null
)
@Serializable
data class Experimental(
@SerialName("sniff-tls-sni")
var sniffTLSSNI: Boolean? = null,
)
@Serializable
enum class DnsEnhancedMode {
@SerialName("normal")
@@ -22,17 +22,17 @@ private fun trafficString(scaled: Long): String {
scaled > 1024 * 1024 * 1024 * 100L -> {
val data = scaled / 1024 / 1024 / 1024
"${data / 100}.${data % 100} GiB"
String.format("%.2f GiB", data.toFloat() / 100)
}
scaled > 1024 * 1024 * 100L -> {
val data = scaled / 1024 / 1024
"${data / 100}.${data % 100} MiB"
String.format("%.2f MiB", data.toFloat() / 100)
}
scaled > 1024 * 100L -> {
val data = scaled / 1024
"${data / 100}.${data % 100} KiB"
String.format("%.2f KiB", data.toFloat() / 100)
}
else -> {
"$scaled Bytes"
+32 -20
View File
@@ -1,43 +1,55 @@
module premium
go 1.17
go 1.18
require cfa v0.0.0
require (
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-20211116115317-bc437243ffbb // indirect
github.com/Kr328/tun2socket v0.0.0-20220414050025-d07c78d06d34 // indirect
github.com/avast/apkparser v0.0.0-20210223100516-186f320f9bfc // indirect
github.com/avast/apkverifier v0.0.0-20210916093748-2146ff7c4b7f // indirect
github.com/cilium/ebpf v0.9.0 // indirect
github.com/dlclark/regexp2 v1.4.0 // indirect
github.com/gofrs/uuid v4.1.0+incompatible // indirect
github.com/florianl/go-tc v0.4.1 // indirect
github.com/gofrs/uuid v4.2.0+incompatible // indirect
github.com/google/btree v1.0.1 // indirect
github.com/gorilla/websocket v1.4.2 // indirect
github.com/insomniacslk/dhcp v0.0.0-20211026125128-ad197bcd36fd // indirect
github.com/google/go-cmp v0.5.7 // indirect
github.com/google/nftables v0.0.0-20220611213346-a346d51f53b3 // indirect
github.com/gorilla/websocket v1.5.0 // indirect
github.com/insomniacslk/dhcp v0.0.0-20220504074936-1ca156eafb9f // indirect
github.com/josharian/native v1.0.0 // indirect
github.com/klauspost/compress v1.11.13 // indirect
github.com/kr/text v0.1.0 // indirect
github.com/miekg/dns v1.1.43 // indirect
github.com/oschwald/geoip2-golang v1.5.0 // indirect
github.com/oschwald/maxminddb-golang v1.8.0 // indirect
github.com/mdlayher/netlink v1.6.0 // indirect
github.com/mdlayher/socket v0.1.1 // indirect
github.com/miekg/dns v1.1.49 // indirect
github.com/openacid/low v0.1.21 // indirect
github.com/oschwald/geoip2-golang v1.7.0 // indirect
github.com/oschwald/maxminddb-golang v1.9.0 // indirect
github.com/samber/lo v1.21.0 // indirect
github.com/sirupsen/logrus v1.8.1 // indirect
github.com/u-root/uio v0.0.0-20210528114334-82958018845c // indirect
github.com/vishvananda/netns v0.0.0-20211101163701-50045581ed74 // indirect
go.etcd.io/bbolt v1.3.6 // indirect
go.starlark.net v0.0.0-20211013185944-b0039bd2cfe3 // indirect
go.starlark.net v0.0.0-20220328144851-d1966c6b9fcd // indirect
go.uber.org/atomic v1.9.0 // indirect
go4.org/intern v0.0.0-20211027215823-ae77deb06f29 // indirect
go4.org/unsafe/assume-no-moving-gc v0.0.0-20211027215541-db492cf91b37 // indirect
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519 // indirect
golang.org/x/net v0.0.0-20211105192438-b53810dc28af // indirect
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c // indirect
golang.org/x/sys v0.0.0-20211116061358-0a5406a5449c // indirect
golang.org/x/text v0.3.6 // indirect
go4.org/unsafe/assume-no-moving-gc v0.0.0-20220617031537-928513b29760 // indirect
golang.org/x/crypto v0.0.0-20220525230936-793ad666bf5e // indirect
golang.org/x/exp v0.0.0-20220303212507-bbda1eaf7a17 // indirect
golang.org/x/mod v0.6.0-dev.0.20211013180041-c96bc1413d57 // indirect
golang.org/x/net v0.0.0-20220617184016-355a448f1bc9 // indirect
golang.org/x/sync v0.0.0-20220601150217-0de741cfad7f // indirect
golang.org/x/sys v0.0.0-20220615213510-4f61da869c0c // indirect
golang.org/x/text v0.3.7 // indirect
golang.org/x/time v0.0.0-20191024005414-555d28b269f0 // indirect
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 // indirect
golang.org/x/tools v0.1.9 // indirect
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 // indirect
gopkg.in/yaml.v2 v2.4.0 // indirect
gvisor.dev/gvisor v0.0.0-20211104052249-2de3450f76d6 // indirect
inet.af/netaddr v0.0.0-20211027220019-c74959edd3b6 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
gvisor.dev/gvisor v0.0.0-20220428010907-8082b77961ba // indirect
inet.af/netaddr v0.0.0-20220617031823-097006376321 // indirect
)
replace cfa => ../../main/golang
File diff suppressed because it is too large. Load diff
+9 -9
View File
@@ -9,13 +9,13 @@ dependencies {
implementation(project(":core"))
implementation(project(":service"))
implementation(deps.kotlin.coroutine)
implementation(deps.androidx.core)
implementation(deps.androidx.appcompat)
implementation(deps.androidx.activity)
implementation(deps.androidx.coordinator)
implementation(deps.androidx.recyclerview)
implementation(deps.androidx.fragment)
implementation(deps.androidx.viewpager)
implementation(deps.google.material)
implementation(libs.kotlin.coroutine)
implementation(libs.androidx.core)
implementation(libs.androidx.appcompat)
implementation(libs.androidx.activity)
implementation(libs.androidx.coordinator)
implementation(libs.androidx.recyclerview)
implementation(libs.androidx.fragment)
implementation(libs.androidx.viewpager)
implementation(libs.google.material)
}
@@ -26,7 +26,7 @@ class LogcatDesign(
private val binding = DesignLogcatBinding
.inflate(context.layoutInflater, context.root, false)
private val adapter = LogMessageAdapter(context) {
launch(Dispatchers.IO) {
launch {
val data = ClipData.newPlainText("log_message", it.message)
context.getSystemService<ClipboardManager>()?.setPrimaryClip(data)
@@ -223,6 +223,15 @@ class OverrideSettingsDesign(
)
}
if (BuildConfig.PREMIUM) {
selectableList(
value = configuration.experimental::sniffTLSSNI,
values = booleanValues,
valuesText = booleanValuesText,
title = R.string.sniff_tls_sni,
)
}
selectableList(
value = configuration::logLevel,
values = arrayOf(
@@ -2,12 +2,13 @@ package com.github.kr328.clash.design.util
import android.content.pm.PackageInfo
import android.content.pm.PackageManager
import com.github.kr328.clash.common.compat.foreground
import com.github.kr328.clash.design.model.AppInfo
fun PackageInfo.toAppInfo(pm: PackageManager): AppInfo {
return AppInfo(
packageName = packageName,
icon = applicationInfo.loadIcon(pm),
icon = applicationInfo.loadIcon(pm).foreground(),
label = applicationInfo.loadLabel(pm).toString(),
installTime = firstInstallTime,
updateDate = lastUpdateTime,
+78 -74
View File
@@ -1,43 +1,43 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="access_control_packages_summary">為軟體設定訪問權限</string>
<string name="access_control_packages_summary">設定應用程式存取權</string>
<string name="about">關於</string>
<string name="access_control_mode">訪問控制模式</string>
<string name="access_control_packages">訪問控制軟體套件清單</string>
<string name="append_system_dns">追加作業系統 DNS</string>
<string name="application_broken">軟體損毀</string>
<string name="access_control_mode">存取控制套件</string>
<string name="access_control_packages">存取控制應用程式套件清單</string>
<string name="append_system_dns">附加作業系統 DNS</string>
<string name="application_broken">應用程式損毀</string>
<string name="application_name">Clash for Android</string>
<string name="auto_update">自動更新</string>
<string name="behavior">行為</string>
<string name="bypass_private_network">繞過私有網路</string>
<string name="bypass_private_network_summary">繞過私有網路位址</string>
<string name="bypass_private_network">略過私有網路</string>
<string name="bypass_private_network_summary">略過私有網路位址</string>
<string name="cancel">取消</string>
<string name="clash_logcat">Clash 日誌檔採集工具</string>
<string name="clash_logcat">Clash Logcat</string>
<string name="create_profile">建立設定檔</string>
<string name="dark_mode">深色模式</string>
<string name="default_">預設</string>
<string name="delay">延時</string>
<string name="delay">延遲</string>
<string name="delete">刪除</string>
<string name="delete_all_logs">刪除所有日誌檔</string>
<string name="delete_all_logs_warn">所有歷史日誌檔將丟失</string>
<string name="detail">內容</string>
<string name="delete_all_logs">刪除所有紀錄檔</string>
<string name="delete_all_logs_warn">所有歷史紀錄將被刪除</string>
<string name="detail">詳細資料</string>
<string name="direct_mode">直連模式</string>
<string name="disabled">已禁用</string>
<string name="dns_hijacking">DNS 劫持</string>
<string name="disabled">已停用</string>
<string name="dns_hijacking">DNS 攔截攻擊</string>
<string name="dns_hijacking_summary">處理所有 DNS 封包</string>
<string name="duplicate">複製</string>
<string name="edit">編輯</string>
<string name="empty_name">空白名稱</string>
<string name="exit_without_save">退出而不儲存</string>
<string name="exit_without_save_warning">所有變更將會丟失</string>
<string name="exit_without_save_warning">將遺失所有變更</string>
<string name="export">匯出</string>
<string name="external">外部</string>
<string name="file">檔案</string>
<string name="file_exported">檔案已匯出</string>
<string name="format_minutes">%d 分鐘</string>
<string name="format_profile_activated">%s 已啟用</string>
<string name="format_traffic_forwarded">%s 已轉發</string>
<string name="global_mode">全域性模式</string>
<string name="format_traffic_forwarded">%s 已轉送</string>
<string name="global_mode">全域模式</string>
<string name="history">歷史</string>
<string name="import_from_file">從檔案匯入</string>
<string name="import_from_url">從 URL 匯入</string>
@@ -45,23 +45,23 @@
<string name="invalid_url">無效 URL</string>
<string name="launch_name">Clash</string>
<string name="logcat">Logcat</string>
<string name="logs">日誌</string>
<string name="logs">紀錄</string>
<string name="mode">模式</string>
<string name="name">名稱</string>
<string name="network">網路</string>
<string name="new_profile">新設定檔</string>
<string name="not_selected">未選取</string>
<string name="not_selected">未選擇</string>
<string name="ok">確認</string>
<string name="profile">設定檔</string>
<string name="profile_name">設定檔名稱</string>
<string name="profiles">設定檔</string>
<string name="properties">參數</string>
<string name="properties">性質</string>
<string name="proxy">Proxy</string>
<string name="recently">最近</string>
<string name="route_system_traffic">自動轉發作業系統流量</string>
<string name="routing_via_vpn_service">通過 VpnService 自動轉發所有作業系統流量</string>
<string name="route_system_traffic">自動轉送作業系統流量</string>
<string name="routing_via_vpn_service">通過 VpnService 自動轉送所有作業系統流量</string>
<string name="rule_mode">規則模式</string>
<string name="running">運作中</string>
<string name="running">執行中</string>
<string name="settings">設定</string>
<string name="show_traffic">顯示流量</string>
<string name="show_traffic_summary">在通知中自動重新整理流量</string>
@@ -69,27 +69,27 @@
<string name="auto_restart">自動重新啟動</string>
<string name="stopped">已停止</string>
<string name="help">幫助</string>
<string name="tap_to_start">點此啟動</string>
<string name="tap_to_start">輕觸以啟動</string>
<string name="update">更新</string>
<string name="url">URL</string>
<string name="vpn_service_options">VpnService 選項</string>
<string name="options_unavailable">選項在 Clash 運作時不可用</string>
<string name="search">尋找</string>
<string name="system_apps">作業系統軟體</string>
<string name="options_unavailable">選項在 Clash 執行時不可用</string>
<string name="search">搜尋</string>
<string name="system_apps">系統程式</string>
<string name="update_time">更新時間</string>
<string name="package_name">軟體套件名稱</string>
<string name="package_name">套件名稱</string>
<string name="install_time">安裝時間</string>
<string name="clash_for_android">Clash for Android</string>
<string name="feedback">回饋</string>
<string name="github_issues">Github Issues</string>
<string name="tips_properties"><![CDATA[僅接受 <strong>Clash 設定檔</strong>(包含<strong>Proxy</strong>/<strong>規則</strong>)]]></string>
<string name="github_issues">GitHub Issues</string>
<string name="tips_properties"><![CDATA[僅接受 <strong>Clash 設定檔</strong> (包含<strong>Proxy</strong> /<strong>規則</strong>)]]></string>
<string name="loading">載入中</string>
<string name="tips_help"><![CDATA[Clash for Android 是一個<strong>免費軟體</strong>並且我們<strong>不</strong>為其提供任何服務, <strong>請務必不要回報非軟體自身引起的問題</strong>]]></string>
<string name="tips_help"><![CDATA[Clash for Android 是一個<strong>免費應用程式</strong>並且我們<strong>不</strong>為其提供任何服務, <strong>請務必不要回報非應用程式自身引起的問題</strong>]]></string>
<string name="donate">抖內</string>
<string name="allow_all_apps">允許所有軟體</string>
<string name="allow_selected_apps">僅允許已選取的軟體</string>
<string name="deny_selected_apps">不允許已選取的軟體</string>
<string name="no_profile_selected">沒有選取設定檔</string>
<string name="allow_all_apps">允許所有應用程式</string>
<string name="allow_selected_apps">僅允許已選擇的應用程式</string>
<string name="deny_selected_apps">不允許已選擇的應用程式</string>
<string name="no_profile_selected">未選擇設定檔</string>
<string name="copied">已複製</string>
<string name="script_mode">腳本模式</string>
<string name="google_play">Google Play</string>
@@ -97,10 +97,10 @@
<string name="select_all">全選</string>
<string name="select_invert">反選</string>
<string name="select_none">清除</string>
<string name="app">軟體</string>
<string name="follow_system_android_10">跟隨作業系統 (Android 10+)</string>
<string name="always_dark">總是深色模式</string>
<string name="always_light">總是淺色模式</string>
<string name="app">應用程式</string>
<string name="follow_system_android_10">跟隨系統設定 (Android 10+)</string>
<string name="always_dark">深色</string>
<string name="always_light">淺色</string>
<string name="service">服務</string>
<string name="accept_http_content">僅接受 http(s) 和 content 類型</string>
<string name="at_least_15_minutes">至少 15 分鐘</string>
@@ -109,37 +109,37 @@
<string name="dns">DNS</string>
<string name="http_port">HTTP 埠</string>
<string name="socks_port">Socks 埠</string>
<string name="mixed_port">複合埠</string>
<string name="allow_lan">允許來自區域網路的連結</string>
<string name="mixed_port">Mixed 埠</string>
<string name="allow_lan">允許來自區域網路的連線</string>
<string name="bind_address">監聽位址</string>
<string name="log_level">日誌檔級別</string>
<string name="log_level">紀錄等級</string>
<string name="ipv6">IPv6</string>
<string name="hosts">Hosts</string>
<string name="enabled">已啟用</string>
<string name="info">消息</string>
<string name="info">資訊</string>
<string name="warning">警告</string>
<string name="error">錯誤</string>
<string name="debug">調試</string>
<string name="debug">偵錯</string>
<string name="silent">停用</string>
<string name="format_elements">%d 個條目</string>
<string name="strategy">策略</string>
<string name="enhanced_mode">增強模式</string>
<string name="name_server">Name Server</string>
<string name="fallback">Fallback Name Server</string>
<string name="default_name_server">Default Name Server</string>
<string name="name_server">名稱伺服器</string>
<string name="fallback">備用名稱伺服器</string>
<string name="default_name_server">預設名稱伺服器</string>
<string name="fakeip_filter">FakeIP 過濾器</string>
<string name="geoip_fallback">GeoIP Fallback</string>
<string name="ipcidr_fallback">IPCIDR Fallback</string>
<string name="geoip_fallback">GeoIP 備用</string>
<string name="ipcidr_fallback">IPCIDR 備用</string>
<string name="use_built_in">使用內建</string>
<string name="mapping">Real-IP 至 域名映射</string>
<string name="fakeip">Fake-IP 至 域名映射</string>
<string name="mapping">Real-IP 至域名映射</string>
<string name="fakeip">Fake-IP 至域名映射</string>
<string name="sort">排序</string>
<string name="layout">佈局</string>
<string name="layout">版面配置</string>
<string name="single">單欄</string>
<string name="multiple">多欄</string>
<string name="not_selectable">不可選取</string>
<string name="providers">外部資源</string>
<string name="unavailable">不可用</string>
<string name="not_selectable">無法選擇</string>
<string name="providers">提供者</string>
<string name="unavailable">無法使用</string>
<string name="_new">新增</string>
<string name="value">值</string>
<string name="listen">監聽</string>
@@ -162,29 +162,29 @@
<string name="reset">重設</string>
<string name="use_hosts">使用 Hosts</string>
<string name="authentication">認證</string>
<string name="domain_fallback">域名 Fallback</string>
<string name="empty">置空</string>
<string name="domain_fallback">備用域名</string>
<string name="empty">空</string>
<string name="import_from_clipboard">從剪貼簿匯入</string>
<string name="export_to_clipboard">匯出至剪貼簿</string>
<string name="auto_update_minutes">自動更新 (分鐘)</string>
<string name="profile_url">設定檔 URL</string>
<string name="should_not_be_blank">不能為空</string>
<string name="format_fetching_configuration">正在從 %s 下載設定檔</string>
<string name="format_fetching_provider">正在下載外部資源 %s</string>
<string name="format_fetching_provider">正在下載額外資源 %s</string>
<string name="initializing">正在初始化</string>
<string name="verifying">正在校驗</string>
<string name="sideload_geoip">旁載入 GEOIP</string>
<string name="sideload_geoip_summary">外部 GEOIP 資料庫</string>
<string name="sideload_geoip">側載 GeoIP</string>
<string name="sideload_geoip_summary">外部 GeoIP 資料庫</string>
<string name="force_enable">強制啟用</string>
<string name="document">文件</string>
<string name="clash_wiki">Clash Wiki</string>
<string name="invalid_file_name">不規範檔案名稱</string>
<string name="reset_override_settings">重置覆寫設定</string>
<string name="reset_override_settings_message">所有的覆寫設定將會被抹除</string>
<string name="invalid_file_name">無效的檔案名稱</string>
<string name="reset_override_settings">重設覆寫設定</string>
<string name="reset_override_settings_message">所有的覆寫設定將會被移除</string>
<string name="key">鍵</string>
<string name="more">更多</string>
<string name="save">儲存</string>
<string name="delay_test">延時測試</string>
<string name="delay_test">延遲測試</string>
<string name="format_provider_type">%1$s(%2$s)</string>
<string name="rule">規則</string>
<string name="http">HTTP</string>
@@ -195,22 +195,26 @@
<string name="reverse">反轉</string>
<string name="close">關閉</string>
<string name="keyword">關鍵字</string>
<string name="invalid_log_file">無效的日誌檔</string>
<string name="application_crashed">軟體崩潰</string>
<string name="application_broken_tips">軟體缺少必要的運作元件,這通常是由於下載了不完整的 apk 而導致。</string>
<string name="invalid_log_file">無效的紀錄檔</string>
<string name="application_crashed">應用程式崩潰</string>
<string name="application_broken_tips">應用程式缺少必要的執行元件,這通常是由於下載了不完整的 APK 而導致。</string>
<string name="reinstall">重新安裝</string>
<string name="github_releases">Github Releases</string>
<string name="github_releases">GitHub Releases</string>
<string name="unable_to_start_vpn">無法啟動 VPN 元件</string>
<string name="request_donate_tips">如果您覺得本軟體對您有幫助歡迎在 [幫助] 中給予開發者一點抖內</string>
<string name="request_donate_tips">如果您覺得本應用程式對您有幫助,歡迎在 [幫助] 中給予開發人員一些抖內</string>
<string name="request_donate">抖內</string>
<string name="version_updated">軟體已更新</string>
<string name="version_updated">應用程式已更新</string>
<string name="version_updated_tips">設定已被清除,舊版設定檔需要再次儲存。</string>
<string name="active_unsaved_tips">設定檔需要在啟用之前儲存</string>
<string name="active_unsaved_tips">設定檔需要在開啟之前儲存</string>
<string name="mode_switch_tips">僅在本次工作階段中有效</string>
<string name="import_">匯入</string>
<string name="sources">原始碼</string>
<string name="clash_core">Clash 核心</string>
<string name="name_server_policy">Name Server 策略</string>
<string name="block_loopback">阻止本地迴環</string>
<string name="block_loopback_summary">阻止本地迴環連結</string>
<string name="name_server_policy">Name Server 政策</string>
<string name="block_loopback">阻擋本地迴送</string>
<string name="block_loopback_summary">阻擋本地回連結</string>
<string name="geoip_fallback_code">GeoIP 備用區域代碼</string>
<string name="allow_bypass">允許應用程式繞過</string>
<string name="allow_bypass_summary">允許其他程式繞過 VPN</string>
<string name="sniff_tls_sni">嗅探 TLS 的 SNI</string>
</resources>
@@ -216,4 +216,5 @@
<string name="geoip_fallback_code">GeoIP Fallback 区域代码</string>
<string name="allow_bypass">允许应用绕过</string>
<string name="allow_bypass_summary">允许其他应用绕过 VPN</string>
<string name="sniff_tls_sni">嗅探 TLS 的 SNI</string>
</resources>
+1
View File
@@ -145,6 +145,7 @@
<string name="bind_address">Bind Address</string>
<string name="mode">Mode</string>
<string name="log_level">Log Level</string>
<string name="sniff_tls_sni">Sniff TLS SNI</string>
<string name="ipv6">IPv6</string>
<string name="hosts">Hosts</string>
<string name="sideload_geoip">Sideload GEOIP</string>
Binary file not shown.
+2 -2
View File
@@ -1,6 +1,6 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-7.3-all.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-7.4.2-all.zip
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
distributionSha256Sum=00b273629df4ce46e68df232161d5a7c4e495b9a029ce6e0420f071e21316867
distributionSha256Sum=e6d864e3b5bc05cc62041842b306383fc1fefcec359e70cebb1d470a6094ca82
+12 -12
View File
@@ -1,31 +1,31 @@
plugins {
kotlin("android")
kotlin("kapt")
id("kotlinx-serialization")
id("com.android.library")
id("com.google.devtools.ksp")
}
dependencies {
ksp(deps.kaidl.compiler)
kapt(deps.androidx.room.compiler)
implementation(project(":core"))
implementation(project(":common"))
implementation(deps.kotlin.coroutine)
implementation(deps.kotlin.serialization.json)
implementation(deps.androidx.core)
implementation(deps.androidx.room.runtime)
implementation(deps.androidx.room.ktx)
implementation(deps.kaidl.runtime)
implementation(deps.rikkax.multiprocess)
ksp(libs.kaidl.compiler)
ksp(libs.androidx.room.compiler)
implementation(libs.kotlin.coroutine)
implementation(libs.kotlin.serialization.json)
implementation(libs.androidx.core)
implementation(libs.androidx.room.runtime)
implementation(libs.androidx.room.ktx)
implementation(libs.kaidl.runtime)
implementation(libs.rikkax.multiprocess)
}
afterEvaluate {
android {
libraryVariants.forEach {
sourceSets[it.name].java.srcDir(buildDir.resolve("generated/ksp/${it.name}/kotlin"))
sourceSets[it.name].kotlin.srcDir(buildDir.resolve("generated/ksp/${it.name}/kotlin"))
sourceSets[it.name].java.srcDir(buildDir.resolve("generated/ksp/${it.name}/java"))
}
}
}
+4 -2
View File
@@ -12,12 +12,14 @@
<application>
<service
android:name="ClashService"
android:name=".ClashService"
android:exported="false"
android:label="@string/clash_for_android"
android:process=":background" />
<service
android:name="TunService"
android:name=".TunService"
android:exported="false"
android:label="@string/clash_for_android"
android:permission="android.permission.BIND_VPN_SERVICE"
android:process=":background">
<intent-filter>
@@ -62,9 +62,9 @@ class TunService : VpnService(), CoroutineScope by CoroutineScope(Dispatchers.De
true
}
network.onEvent { e ->
network.onEvent { n ->
if (Build.VERSION.SDK_INT in 22..28) @TargetApi(22) {
setUnderlyingNetworks(e.network?.let { arrayOf(it) })
setUnderlyingNetworks(n?.let { arrayOf(it) })
}
false
@@ -207,7 +207,7 @@ class TunService : VpnService(), CoroutineScope by CoroutineScope(Dispatchers.De
TunModule.TunDevice(
fd = establish()?.detachFd()
?: throw NullPointerException("Establish VPN rejected by system"),
gateway = TUN_GATEWAY,
gateway = "$TUN_GATEWAY/$TUN_SUBNET_PREFIX",
portal = TUN_PORTAL,
dns = if (store.dnsHijacking) NET_ANY else TUN_DNS,
)
@@ -223,7 +223,6 @@ class TunService : VpnService(), CoroutineScope by CoroutineScope(Dispatchers.De
private const val TUN_PORTAL = "172.19.0.2"
private const val TUN_DNS = TUN_PORTAL
private const val NET_ANY = "0.0.0.0"
private const val NET_SUBNET_LOOPBACK = "127.0.0.0/8"
private val HTTP_PROXY_LOCAL_LIST: List<String> = listOf(
"localhost",
@@ -239,6 +238,11 @@ class TunService : VpnService(), CoroutineScope by CoroutineScope(Dispatchers.De
"172.31.*",
"192.168.*"
)
private val HTTP_PROXY_BLACK_LIST: List<String> = listOf("*zhihu.com", "*zhimg.com")
private val HTTP_PROXY_BLACK_LIST: List<String> = listOf(
"*zhihu.com",
"*zhimg.com",
"*jd.com",
"100ime-iat-api.xfyun.cn",
)
}
}
@@ -15,7 +15,19 @@ class AppListCacheModule(service: Service) : Module<Unit>(service) {
private fun reload() {
val packages = service.packageManager.getInstalledPackages(0)
.map { it.applicationInfo.uid to it.uniqueUidName() }
.groupBy { it.uniqueUidName() }
.map { (_, v) ->
val info = v[0]
if (v.size == 1) {
// Force use package name if only one app in a single sharedUid group
// Example: firefox
info.applicationInfo.uid to info.packageName
} else {
info.applicationInfo.uid to info.uniqueUidName()
}
}
Clash.notifyInstalledAppsChanged(packages)
@@ -1,113 +1,128 @@
package com.github.kr328.clash.service.clash.module
import android.app.Service
import android.content.Intent
import android.net.*
import android.os.PowerManager
import android.os.Build
import androidx.core.content.getSystemService
import com.github.kr328.clash.common.log.Log
import com.github.kr328.clash.core.Clash
import com.github.kr328.clash.service.util.resolveDns
import com.github.kr328.clash.service.util.resolvePrimaryDns
import kotlinx.coroutines.NonCancellable
import kotlinx.coroutines.channels.Channel
import kotlinx.coroutines.selects.select
import kotlinx.coroutines.channels.trySendBlocking
import kotlinx.coroutines.withContext
class NetworkObserveModule(service: Service) :
Module<NetworkObserveModule.NetworkChanged>(service) {
data class NetworkChanged(val network: Network?)
class NetworkObserveModule(service: Service) : Module<Network?>(service) {
private data class Action(val type: Type, val network: Network) {
enum class Type { Available, Lost, Changed }
}
private val connectivity = service.getSystemService<ConnectivityManager>()!!
private val networks: Channel<Network?> = Channel(Channel.CONFLATED)
private val actions = Channel<Action>(Channel.UNLIMITED)
private val request = NetworkRequest.Builder().apply {
addCapability(NetworkCapabilities.NET_CAPABILITY_NOT_VPN)
addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)
addCapability(NetworkCapabilities.NET_CAPABILITY_NOT_RESTRICTED)
}.build()
private val callback = object : ConnectivityManager.NetworkCallback() {
private var network: Network? = null
override fun onAvailable(network: Network) {
if (this.network != network)
networks.trySend(network)
actions.trySendBlocking(Action(Action.Type.Available, network))
}
this.network = network
override fun onLost(network: Network) {
actions.trySendBlocking(Action(Action.Type.Lost, network))
}
override fun onLinkPropertiesChanged(network: Network, linkProperties: LinkProperties) {
if (this.network == network)
networks.trySend(network)
actions.trySendBlocking(Action(Action.Type.Changed, network))
}
}
private fun register(): Boolean {
return try {
connectivity.registerNetworkCallback(request, callback)
true
} catch (e: Exception) {
Log.w("Observe network changed: $e", e)
false
}
}
private fun unregister(): Boolean {
try {
connectivity.unregisterNetworkCallback(callback)
} catch (e: Exception) {
// ignored
}
return false
}
override suspend fun run() {
val screenToggle = receiveBroadcast(false, Channel.CONFLATED) {
addAction(Intent.ACTION_SCREEN_ON)
addAction(Intent.ACTION_SCREEN_OFF)
}
try {
connectivity.registerNetworkCallback(request, callback)
} catch (e: Exception) {
Log.w("Observe network failed: $e", e)
if (service.getSystemService<PowerManager>()?.isInteractive != false) {
register()
return
}
try {
val networks = mutableSetOf<Network>()
while (true) {
val quit = select<Boolean> {
screenToggle.onReceive {
when (it.action) {
Intent.ACTION_SCREEN_ON ->
register()
Intent.ACTION_SCREEN_OFF ->
unregister()
else ->
false
}
val action = actions.receive()
val resolveDefault = when (action.type) {
Action.Type.Available -> {
networks.add(action.network)
true
}
networks.onReceive {
val dns = connectivity.resolveDns(it)
Clash.notifyDnsChanged(dns)
Log.d("Network changed, system dns = $dns")
enqueueEvent(NetworkChanged(it))
Action.Type.Lost -> {
networks.remove(action.network)
true
}
Action.Type.Changed -> {
false
}
}
if (quit) {
return
val dns = networks.mapNotNull {
connectivity.resolvePrimaryDns(it)
}
Clash.notifyDnsChanged(dns)
Log.d("DNS: $dns")
if (resolveDefault) {
val network = networks.maxByOrNull { net ->
connectivity.getNetworkCapabilities(net)?.let { cap ->
TRANSPORT_PRIORITY.indexOfFirst { cap.hasTransport(it) }
} ?: -1
}
enqueueEvent(network)
Log.d("Network: $network of $networks")
}
}
} finally {
withContext(NonCancellable) {
unregister()
enqueueEvent(null)
Clash.notifyDnsChanged(emptyList())
runCatching {
connectivity.unregisterNetworkCallback(callback)
}
}
}
}
companion object {
private val TRANSPORT_PRIORITY = sequence {
yield(NetworkCapabilities.TRANSPORT_CELLULAR)
if (Build.VERSION.SDK_INT >= 27) {
yield(NetworkCapabilities.TRANSPORT_LOWPAN)
}
yield(NetworkCapabilities.TRANSPORT_BLUETOOTH)
if (Build.VERSION.SDK_INT >= 26) {
yield(NetworkCapabilities.TRANSPORT_WIFI_AWARE)
}
yield(NetworkCapabilities.TRANSPORT_WIFI)
if (Build.VERSION.SDK_INT >= 31) {
yield(NetworkCapabilities.TRANSPORT_USB)
}
yield(NetworkCapabilities.TRANSPORT_ETHERNET)
}.toList()
}
}
@@ -3,9 +3,8 @@ package com.github.kr328.clash.service.util
import android.net.ConnectivityManager
import android.net.Network
fun ConnectivityManager.resolveDns(network: Network?): List<String> {
return network?.run(this::getLinkProperties)
?.dnsServers
?.map { it.asSocketAddressText(53) }
?: emptyList()
}
fun ConnectivityManager.resolvePrimaryDns(network: Network?): String? {
val properties = getLinkProperties(network) ?: return null
return properties.dnsServers.firstOrNull()?.asSocketAddressText(53)
}
@@ -7,6 +7,11 @@
android:tint="@color/color_clash">
<path
android:fillColor="#FFFFFFFF"
android:pathData="M47.211,168.128C70.531,-34.962 67.471,13.788 94.071,43.818c13.45,-1.52 27.24,-3.47 40.82,-0.67c2.64,0.13 5.42,1.86 7.71,0.18c4.12,-6.27 7.35,-13.54 11.35,-20c12.19,-24.44 12.85,19.54 15.48,26.52c5.23,32.99 10.89,64.46 14.67,97.59c0.31,10.72 5.74,32.92 1.08,33.56c-49.36,5.23 -147.71,3.91 -160.84,-6.3c-15.85,-10.5 -15.18,-35.33 2.03,-43.72c3.63,-2.03 10.68,-3.72 11.94,0.7c-2.41,4.99 -8.79,5.77 -12.12,11.17C16.621,158.948 33.111,168.888 47.211,168.128zM87.841,74.008c-10.42,0.52 -9.59,14.89 -0.07,15.18C98.191,88.668 97.361,74.298 87.841,74.008zM149.121,89.188c10.46,-0.34 9.85,-14.71 0.38,-15.18C139.031,74.348 139.651,88.718 149.121,89.188zM107.871,99.228c2.16,3.48 5.28,3.29 9.79,0.16c3.81,3.17 8.06,3.28 9.18,-0.19c-3.78,1.17 -7.04,0.79 -9.4,-3.49C115.371,100.108 112.071,100.428 107.871,99.228z"
android:pathData="M40,163.1C62.1-28,59.3,17.9,84.3,46.2c12.7-1.4,25.6-3.3,38.4-0.7c2.4,0.1,5.1,1.8,7.2,0.2
c3.9-5.9,7-12.7,10.7-18.8c11.5-22.9,12,18.3,14.6,24.9c4.9,31,10.3,60.7,13.8,91.8c0.3,10.1,5.4,30.9,1,31.6
c-46.5,4.9-138.9,3.7-151.2-5.9c-14.9-9.9-14.3-33.2,1.9-41.1c3.4-1.9,10.1-3.5,11.2,0.7c-2.3,4.7-8.3,5.5-11.4,10.5
C11.4,154.4,27,163.8,40.2,163.1z M78.4,74.6c-9.8,0.5-9,14-0.1,14.3C88.2,88.4,87.4,74.8,78.4,74.6z M136.1,88.9
c9.9-0.3,9.2-13.8,0.4-14.3C126.6,74.8,127.2,88.4,136.1,88.9z M97.3,98.3c2.1,3.3,5,3.1,9.2,0.2c3.6,3,7.6,3.1,8.7-0.2
c-3.6,1.1-6.6,0.8-8.8-3.3C104.4,99.1,101.3,99.4,97.3,98.3z"
tools:ignore="VectorPath" />
</vector>
+42 -41
View File
@@ -1,7 +1,3 @@
@file:Suppress("UnstableApiUsage")
enableFeaturePreview("VERSION_CATALOGS")
rootProject.name = "ClashForAndroid"
include(":app")
@@ -11,51 +7,56 @@ include(":design")
include(":common")
include(":hideapi")
pluginManagement {
repositories {
mavenLocal()
mavenCentral()
gradlePluginPortal()
}
}
dependencyResolutionManagement {
versionCatalogs {
create("deps") {
val agp = "7.0.3"
val ksp = "1.6.0-1.0.1"
val kotlin = "1.6.0"
create("libs") {
val agp = "7.2.1"
val kotlin = "1.7.0"
val ksp = "$kotlin-1.0.6"
val golang = "1.0.4"
val coroutine = "1.5.2"
val coreKtx = "1.7.0"
val activity = "1.4.0"
val fragment = "1.3.6"
val appcompat = "1.3.1"
val coordinator = "1.1.0"
val coroutine = "1.6.3"
val coreKtx = "1.8.0"
val activity = "1.5.0"
val fragment = "1.5.0"
val appcompat = "1.4.2"
val coordinator = "1.2.0"
val recyclerview = "1.2.1"
val viewpager = "1.0.0"
val material = "1.4.0"
val appcenter = "4.3.1"
val serialization = "1.3.1"
val material = "1.6.1"
val serialization = "1.3.3"
val kaidl = "1.15"
val room = "2.3.0"
val room = "2.4.2"
val multiprocess = "1.0.0"
alias("build-android").to("com.android.tools.build:gradle:$agp")
alias("build-kotlin-common").to("org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin")
alias("build-kotlin-serialization").to("org.jetbrains.kotlin:kotlin-serialization:$kotlin")
alias("build-ksp").to("com.google.devtools.ksp:symbol-processing-gradle-plugin:$ksp")
alias("build-golang").to("com.github.kr328.golang:gradle-plugin:$golang")
alias("kotlin-coroutine").to("org.jetbrains.kotlinx:kotlinx-coroutines-android:$coroutine")
alias("kotlin-serialization-json").to("org.jetbrains.kotlinx:kotlinx-serialization-json:$serialization")
alias("androidx-core").to("androidx.core:core-ktx:$coreKtx")
alias("androidx-activity").to("androidx.activity:activity:$activity")
alias("androidx-fragment").to("androidx.fragment:fragment:$fragment")
alias("androidx-appcompat").to("androidx.appcompat:appcompat:$appcompat")
alias("androidx-coordinator").to("androidx.coordinatorlayout:coordinatorlayout:$coordinator")
alias("androidx-recyclerview").to("androidx.recyclerview:recyclerview:$recyclerview")
alias("androidx-viewpager").to("androidx.viewpager2:viewpager2:$viewpager")
alias("androidx-room-compiler").to("androidx.room:room-compiler:$room")
alias("androidx-room-runtime").to("androidx.room:room-runtime:$room")
alias("androidx-room-ktx").to("androidx.room:room-ktx:$room")
alias("google-material").to("com.google.android.material:material:$material")
alias("appcenter-analytics").to("com.microsoft.appcenter:appcenter-analytics:$appcenter")
alias("appcenter-crashes").to("com.microsoft.appcenter:appcenter-crashes:$appcenter")
alias("kaidl-compiler").to("com.github.kr328.kaidl:kaidl:$kaidl")
alias("kaidl-runtime").to("com.github.kr328.kaidl:kaidl-runtime:$kaidl")
alias("rikkax-multiprocess").to("dev.rikka.rikkax.preference:multiprocess:$multiprocess")
library("build-android", "com.android.tools.build:gradle:$agp")
library("build-kotlin-common", "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin")
library("build-kotlin-serialization", "org.jetbrains.kotlin:kotlin-serialization:$kotlin")
library("build-ksp", "com.google.devtools.ksp:symbol-processing-gradle-plugin:$ksp")
library("build-golang", "com.github.kr328.golang:gradle-plugin:$golang")
library("kotlin-coroutine", "org.jetbrains.kotlinx:kotlinx-coroutines-android:$coroutine")
library("kotlin-serialization-json", "org.jetbrains.kotlinx:kotlinx-serialization-json:$serialization")
library("androidx-core", "androidx.core:core-ktx:$coreKtx")
library("androidx-activity", "androidx.activity:activity:$activity")
library("androidx-fragment", "androidx.fragment:fragment:$fragment")
library("androidx-appcompat", "androidx.appcompat:appcompat:$appcompat")
library("androidx-coordinator", "androidx.coordinatorlayout:coordinatorlayout:$coordinator")
library("androidx-recyclerview", "androidx.recyclerview:recyclerview:$recyclerview")
library("androidx-viewpager", "androidx.viewpager2:viewpager2:$viewpager")
library("androidx-room-compiler", "androidx.room:room-compiler:$room")
library("androidx-room-runtime", "androidx.room:room-runtime:$room")
library("androidx-room-ktx", "androidx.room:room-ktx:$room")
library("google-material", "com.google.android.material:material:$material")
library("kaidl-compiler", "com.github.kr328.kaidl:kaidl:$kaidl")
library("kaidl-runtime", "com.github.kr328.kaidl:kaidl-runtime:$kaidl")
library("rikkax-multiprocess", "dev.rikka.rikkax.preference:multiprocess:$multiprocess")
}
}
}