mirror of
https://github.com/MatsuriDayo/nekoray.git
synced 2025-12-19 22:50:08 +08:00
Compare commits
70 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
adef6cd4af | ||
|
|
399b171adf | ||
|
|
6e4c180428 | ||
|
|
75c6496151 | ||
|
|
62c59f6fd3 | ||
|
|
12d6fc24e7 | ||
|
|
6de7c588b6 | ||
|
|
99c8d50943 | ||
|
|
2a177256ce | ||
|
|
b1d1674912 | ||
|
|
2dd9cf45eb | ||
|
|
96a6586c5e | ||
|
|
375ffec58d | ||
|
|
7aa863b881 | ||
|
|
79838d8679 | ||
|
|
61e27f4014 | ||
|
|
e868de0209 | ||
|
|
6f81ba7773 | ||
|
|
be0eae662b | ||
|
|
f6cf1414bf | ||
|
|
7c783308a7 | ||
|
|
cd9bb8f72d | ||
|
|
df141f9079 | ||
|
|
4376ce7d33 | ||
|
|
584d50e317 | ||
|
|
961112ea5b | ||
|
|
8a2eab506f | ||
|
|
9bc3be6ea0 | ||
|
|
48e04d2173 | ||
|
|
3f738cee4e | ||
|
|
121311c938 | ||
|
|
4f45617666 | ||
|
|
7655f0e16a | ||
|
|
9d8b12ff66 | ||
|
|
364ea93cc1 | ||
|
|
894410da39 | ||
|
|
06508634a7 | ||
|
|
1b078a8aab | ||
|
|
beb87352ae | ||
|
|
5bf393597e | ||
|
|
205caef7a5 | ||
|
|
6087ec741d | ||
|
|
7bd8a2f651 | ||
|
|
d882424329 | ||
|
|
cd8da82c92 | ||
|
|
06e5de0998 | ||
|
|
376ac1c515 | ||
|
|
937523c6b3 | ||
|
|
c6caf42ce9 | ||
|
|
1aa59f1314 | ||
|
|
c9442ebb57 | ||
|
|
a858af3ae4 | ||
|
|
5ef732fbb1 | ||
|
|
514fb4c811 | ||
|
|
974bb9167d | ||
|
|
369cc7c1aa | ||
|
|
7538075112 | ||
|
|
32ef100cf3 | ||
|
|
a6e7dfe717 | ||
|
|
dad696ef18 | ||
|
|
7621c0a1df | ||
|
|
4df116508e | ||
|
|
11e1eaf232 | ||
|
|
b623e4ca96 | ||
|
|
0597580857 | ||
|
|
1bebdc546c | ||
|
|
20805c4ed0 | ||
|
|
bc83fc5700 | ||
|
|
e2e066551c | ||
|
|
0175f5d456 |
22
.github/ISSUE_TEMPLATE/bug-report-en.md
vendored
Normal file
22
.github/ISSUE_TEMPLATE/bug-report-en.md
vendored
Normal file
@ -0,0 +1,22 @@
|
||||
---
|
||||
name: 'Bug Report'
|
||||
about: 'Please troubleshoot server-side issues and upgrade to the latest client before raising a question.'
|
||||
title: 'BUG: '
|
||||
labels: ''
|
||||
assignees: ''
|
||||
|
||||
---
|
||||
|
||||
## Describe the problem
|
||||
|
||||
Expected behavior:
|
||||
|
||||
Actual behavior:
|
||||
|
||||
## How to reproduce
|
||||
|
||||
Provide helpful screenshots, videos, text descriptions, subscription links, etc.
|
||||
|
||||
## log
|
||||
|
||||
If you have logs, please upload them. Please see the detailed steps for exporting logs in the documentation.
|
||||
4
.github/ISSUE_TEMPLATE/bug-report-zh_cn.md
vendored
4
.github/ISSUE_TEMPLATE/bug-report-zh_cn.md
vendored
@ -1,6 +1,6 @@
|
||||
---
|
||||
name: 'Bug Report zh_CN'
|
||||
about: '问题反馈,在提出问题前请先自行排除服务器端问题和升级到最新客户端。'
|
||||
name: '问题反馈'
|
||||
about: '在提出问题前请先自行排除服务器端问题和升级到最新客户端。'
|
||||
title: 'BUG: '
|
||||
labels: ''
|
||||
assignees: ''
|
||||
|
||||
12
.github/ISSUE_TEMPLATE/feature_request-en.md
vendored
Normal file
12
.github/ISSUE_TEMPLATE/feature_request-en.md
vendored
Normal file
@ -0,0 +1,12 @@
|
||||
---
|
||||
name: 'Feature Request'
|
||||
about: 'Make suggestions for new features of the software'
|
||||
title: ''
|
||||
labels: ''
|
||||
assignees: ''
|
||||
|
||||
---
|
||||
|
||||
## Description suggestions
|
||||
|
||||
## Necessity of recommendations
|
||||
@ -1,6 +1,6 @@
|
||||
---
|
||||
name: 'Feature Request zh_CN'
|
||||
about: '功能请求,提出建议。'
|
||||
name: '功能请求'
|
||||
about: '对软件的新功能提出建议。'
|
||||
title: ''
|
||||
labels: ''
|
||||
assignees: ''
|
||||
|
||||
@ -4,20 +4,20 @@ on:
|
||||
workflow_dispatch:
|
||||
inputs:
|
||||
tag:
|
||||
description: 'Release Tag'
|
||||
description: "Release Tag"
|
||||
required: true
|
||||
publish:
|
||||
description: 'Publish: If want ignore'
|
||||
description: "Publish: If want ignore"
|
||||
required: false
|
||||
artifact-pack:
|
||||
description: 'artifact-pack: If want ignore'
|
||||
description: "artifact-pack: If want ignore"
|
||||
required: false
|
||||
jobs:
|
||||
build-go:
|
||||
strategy:
|
||||
matrix:
|
||||
cross_os: [ windows, linux ]
|
||||
cross_arch: [ amd64 ]
|
||||
cross_os: [windows, linux]
|
||||
cross_arch: [amd64]
|
||||
include:
|
||||
- cross_os: public_res
|
||||
cross_arch: public_res
|
||||
@ -38,7 +38,7 @@ jobs:
|
||||
if: steps.cache-common.outputs.cache-hit != 'true'
|
||||
uses: actions/setup-go@v3
|
||||
with:
|
||||
go-version: ^1.21
|
||||
go-version: ^1.22
|
||||
- name: Build golang parts
|
||||
if: steps.cache-common.outputs.cache-hit != 'true'
|
||||
shell: bash
|
||||
@ -51,7 +51,7 @@ jobs:
|
||||
if: steps.cache-common.outputs.cache-hit != 'true'
|
||||
run: tar czvf artifacts.tgz ./deployment
|
||||
- name: Uploading Artifact
|
||||
uses: actions/upload-artifact@master
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: NekoRay-${{ github.sha }}-Common-${{ matrix.cross_os }}-${{ matrix.cross_arch }}
|
||||
path: artifacts.tgz
|
||||
@ -61,7 +61,7 @@ jobs:
|
||||
include:
|
||||
- platform: windows-2022
|
||||
arch: x64
|
||||
qt_version: "6.5"
|
||||
qt_version: "6.7"
|
||||
- platform: ubuntu-20.04
|
||||
arch: x64
|
||||
qt_version: "5.12"
|
||||
@ -141,7 +141,7 @@ jobs:
|
||||
shell: bash
|
||||
run: tar czvf artifacts.tgz ./deployment
|
||||
- name: Uploading Artifact
|
||||
uses: actions/upload-artifact@master
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: NekoRay-${{ github.sha }}-${{ matrix.platform }}-${{ matrix.arch }}-Qt${{ matrix.qt_version }}
|
||||
path: artifacts.tgz
|
||||
@ -179,7 +179,6 @@ jobs:
|
||||
zip -r $version_standalone-windows64.zip nekoray
|
||||
rm -rf nekoray
|
||||
- name: Pack Debian
|
||||
if: github.event.inputs.publish != 'y'
|
||||
run: |
|
||||
source libs/env_deploy.sh
|
||||
find . -name artifacts.tgz | xargs -n1 tar xvzf
|
||||
@ -197,7 +196,7 @@ jobs:
|
||||
cp -r public_res/* linux64
|
||||
####
|
||||
bash ../libs/package_appimage.sh
|
||||
mv nekoray-x86_64.AppImage $version_standalone-linux-x64.AppImage
|
||||
mv nekobox-x86_64.AppImage $version_standalone-linux-x64.AppImage
|
||||
- name: Clean Up
|
||||
run: |
|
||||
cd deployment
|
||||
@ -206,7 +205,7 @@ jobs:
|
||||
rm -rf public_res
|
||||
rm -rf *.pdb
|
||||
- name: Uploading Artifact
|
||||
uses: actions/upload-artifact@master
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: Deployment-${{ github.sha }}
|
||||
path: deployment
|
||||
18
.github/workflows/update-pkgbuild.yml
vendored
Normal file
18
.github/workflows/update-pkgbuild.yml
vendored
Normal file
@ -0,0 +1,18 @@
|
||||
name: AUR CI
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- main
|
||||
paths-ignore:
|
||||
- '**.md'
|
||||
- 'LICENSE'
|
||||
- '!.github/workflows/**'
|
||||
|
||||
jobs:
|
||||
update:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: chitang233/aur-pkgbuild-builder@main
|
||||
with:
|
||||
deploy_key: ${{ secrets.DEPLOY_KEY }}
|
||||
package_name: 'nekoray-git'
|
||||
3
.gitignore
vendored
3
.gitignore
vendored
@ -82,3 +82,6 @@ CMakeLists.txt.user*
|
||||
/deployment
|
||||
/neko*.sh
|
||||
/qtsdk
|
||||
|
||||
.vs
|
||||
out
|
||||
3
.gitmodules
vendored
3
.gitmodules
vendored
@ -1,6 +1,3 @@
|
||||
[submodule "3rdparty/QHotkey"]
|
||||
path = 3rdparty/QHotkey
|
||||
url = https://github.com/Skycoder42/QHotkey.git
|
||||
[submodule "3rdparty/qjs"]
|
||||
path = 3rdparty/qjs
|
||||
url = https://github.com/MatsuriDayo/qjs
|
||||
|
||||
3
3rdparty/RunGuard.hpp
vendored
3
3rdparty/RunGuard.hpp
vendored
@ -75,9 +75,6 @@ bool RunGuard::isAnotherRunning(quint64 *data_out) {
|
||||
}
|
||||
|
||||
bool RunGuard::tryToRun(quint64 *data_in) {
|
||||
if (isAnotherRunning(nullptr)) // Extra check
|
||||
return false;
|
||||
|
||||
memLock.acquire();
|
||||
const bool result = sharedMem.create(sizeof(quint64));
|
||||
if (result) memcpy(sharedMem.data(), data_in, sizeof(quint64));
|
||||
|
||||
1
3rdparty/qjs
vendored
1
3rdparty/qjs
vendored
@ -1 +0,0 @@
|
||||
Subproject commit 3fb0770c9ee5ab031a56072520641d4577b694e3
|
||||
@ -353,7 +353,7 @@ namespace Qv2ray::components::proxy {
|
||||
// execute and get the code
|
||||
const auto returnCode = QProcess::execute(action.first, action.second);
|
||||
// print out the commands and result codes
|
||||
DEBUG(QString("[%1] Program: %2, Args: %3").arg(returnCode).arg(action.first).arg(action.second.join(";")));
|
||||
DEBUG(QStringLiteral("[%1] Program: %2, Args: %3").arg(returnCode).arg(action.first).arg(action.second.join(";")));
|
||||
// give the code back
|
||||
results << (returnCode == QProcess::NormalExit);
|
||||
}
|
||||
@ -423,7 +423,7 @@ namespace Qv2ray::components::proxy {
|
||||
// execute and get the code
|
||||
const auto returnCode = QProcess::execute(action.first, action.second);
|
||||
// print out the commands and result codes
|
||||
DEBUG(QString("[%1] Program: %2, Args: %3").arg(returnCode).arg(action.first).arg(action.second.join(";")));
|
||||
DEBUG(QStringLiteral("[%1] Program: %2, Args: %3").arg(returnCode).arg(action.first).arg(action.second.join(";")));
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
132
3rdparty/qv2ray/v2/ui/LogHighlighter.cpp
vendored
132
3rdparty/qv2ray/v2/ui/LogHighlighter.cpp
vendored
@ -1,132 +0,0 @@
|
||||
#include "LogHighlighter.hpp"
|
||||
|
||||
#define TO_EOL "(([\\s\\S]*)|([\\d\\D]*)|([\\w\\W]*))$"
|
||||
#define REGEX_IPV6_ADDR \
|
||||
R"(\[\s*((([0-9A-Fa-f]{1,4}:){7}([0-9A-Fa-f]{1,4}|:))|(([0-9A-Fa-f]{1,4}:){6}(:[0-9A-Fa-f]{1,4}|((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3})|:))|(([0-9A-Fa-f]{1,4}:){5}(((:[0-9A-Fa-f]{1,4}){1,2})|:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3})|:))|(([0-9A-Fa-f]{1,4}:){4}(((:[0-9A-Fa-f]{1,4}){1,3})|((:[0-9A-Fa-f]{1,4})?:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){3}(((:[0-9A-Fa-f]{1,4}){1,4})|((:[0-9A-Fa-f]{1,4}){0,2}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){2}(((:[0-9A-Fa-f]{1,4}){1,5})|((:[0-9A-Fa-f]{1,4}){0,3}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){1}(((:[0-9A-Fa-f]{1,4}){1,6})|((:[0-9A-Fa-f]{1,4}){0,4}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(:(((:[0-9A-Fa-f]{1,4}){1,7})|((:[0-9A-Fa-f]{1,4}){0,5}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:)))(%.+)?\s*\])"
|
||||
#define REGEX_IPV4_ADDR \
|
||||
R"((\d{1,2}|1\d\d|2[0-4]\d|25[0-5])\.(\d{1,2}|1\d\d|2[0-4]\d|25[0-5])\.(\d{1,2}|1\d\d|2[0-4]\d|25[0-5])\.(\d{1,2}|1\d\d|2[0-4]\d|25[0-5]))"
|
||||
#define REGEX_PORT_NUMBER R"(([0-9]|[1-9]\d{1,3}|[1-5]\d{4}|6[0-5]{2}[0-3][0-5])*)"
|
||||
|
||||
namespace Qv2ray::ui {
|
||||
SyntaxHighlighter::SyntaxHighlighter(bool darkMode, QTextDocument *parent) : QSyntaxHighlighter(parent) {
|
||||
HighlightingRule rule;
|
||||
|
||||
if (darkMode) {
|
||||
tcpudpFormat.setForeground(QColor(0, 200, 230));
|
||||
ipHostFormat.setForeground(Qt::yellow);
|
||||
warningFormat.setForeground(QColor(255, 160, 15));
|
||||
warningFormat2.setForeground(Qt::cyan);
|
||||
} else {
|
||||
ipHostFormat.setForeground(QColor(0, 52, 130));
|
||||
tcpudpFormat.setForeground(QColor(0, 52, 130));
|
||||
warningFormat.setBackground(QColor(255, 160, 15));
|
||||
warningFormat.setForeground(Qt::white);
|
||||
warningFormat2.setForeground(Qt::darkCyan);
|
||||
}
|
||||
const static QColor darkGreenColor(10, 180, 0);
|
||||
|
||||
acceptedFormat.setForeground(darkGreenColor);
|
||||
acceptedFormat.setFontItalic(true);
|
||||
acceptedFormat.setFontWeight(QFont::Bold);
|
||||
rule.pattern = QRegularExpression("\\saccepted\\s");
|
||||
rule.format = acceptedFormat;
|
||||
highlightingRules.append(rule);
|
||||
//
|
||||
rejectedFormat.setFontWeight(QFont::Bold);
|
||||
rejectedFormat.setBackground(Qt::red);
|
||||
rejectedFormat.setForeground(Qt::white);
|
||||
rejectedFormat.setFontWeight(QFont::Bold);
|
||||
rule.pattern = QRegularExpression("\\srejected\\s" TO_EOL);
|
||||
rule.format = rejectedFormat;
|
||||
highlightingRules.append(rule);
|
||||
//
|
||||
dateFormat.setForeground(darkMode ? Qt::cyan : Qt::darkCyan);
|
||||
rule.pattern = QRegularExpression("\\d\\d\\d\\d/\\d\\d/\\d\\d");
|
||||
rule.format = dateFormat;
|
||||
highlightingRules.append(rule);
|
||||
//
|
||||
timeFormat.setForeground(darkMode ? Qt::cyan : Qt::darkCyan);
|
||||
rule.pattern = QRegularExpression("\\d\\d:\\d\\d:\\d\\d");
|
||||
rule.format = timeFormat;
|
||||
highlightingRules.append(rule);
|
||||
//
|
||||
debugFormat.setForeground(Qt::darkGray);
|
||||
rule.pattern = QRegularExpression("\\[D[Ee][Bb][Uu].*?\\]");
|
||||
rule.format = debugFormat;
|
||||
highlightingRules.append(rule);
|
||||
//
|
||||
infoFormat.setForeground(darkMode ? Qt::lightGray : Qt::darkCyan);
|
||||
rule.pattern = QRegularExpression("\\[I[Nn][Ff][Oo].*?\\]");
|
||||
rule.format = infoFormat;
|
||||
highlightingRules.append(rule);
|
||||
//
|
||||
warningFormat.setFontWeight(QFont::Bold);
|
||||
warningFormat2.setFontWeight(QFont::Bold);
|
||||
rule.pattern = QRegularExpression("\\[W[Aa][Rr][Nn].*?\\]");
|
||||
rule.format = warningFormat2;
|
||||
highlightingRules.append(rule);
|
||||
//
|
||||
rule.pattern = QRegularExpression("\\[E[Rr][Rr][Oo].*?\\]");
|
||||
rule.format = rejectedFormat;
|
||||
highlightingRules.append(rule);
|
||||
|
||||
//
|
||||
v2rayComponentFormat.setForeground(darkMode ? darkGreenColor : Qt::darkYellow);
|
||||
rule.pattern = QRegularExpression(R"( (\w+\/)+\w+: )");
|
||||
rule.format = v2rayComponentFormat;
|
||||
highlightingRules.append(rule);
|
||||
//
|
||||
failedFormat.setFontWeight(QFont::Bold);
|
||||
failedFormat.setBackground(Qt::red);
|
||||
failedFormat.setForeground(Qt::white);
|
||||
rule.pattern = QRegularExpression("failed");
|
||||
rule.format = failedFormat;
|
||||
highlightingRules.append(rule);
|
||||
//
|
||||
rule.pattern = QRegularExpression(">>>>+");
|
||||
rule.format = warningFormat;
|
||||
highlightingRules.append(rule);
|
||||
//
|
||||
rule.pattern = QRegularExpression("<<<<+");
|
||||
rule.format = warningFormat;
|
||||
highlightingRules.append(rule);
|
||||
|
||||
{
|
||||
// IP IPv6 Host;
|
||||
rule.pattern = QRegularExpression(REGEX_IPV4_ADDR ":" REGEX_PORT_NUMBER);
|
||||
rule.pattern.setPatternOptions(QRegularExpression::ExtendedPatternSyntaxOption);
|
||||
rule.format = ipHostFormat;
|
||||
highlightingRules.append(rule);
|
||||
//
|
||||
rule.pattern = QRegularExpression(REGEX_IPV6_ADDR ":" REGEX_PORT_NUMBER);
|
||||
rule.pattern.setPatternOptions(QRegularExpression::ExtendedPatternSyntaxOption);
|
||||
rule.format = ipHostFormat;
|
||||
highlightingRules.append(rule);
|
||||
//
|
||||
rule.pattern = QRegularExpression("([a-zA-Z0-9]([a-zA-Z0-9\\-]{0,61}[a-zA-Z0-9])?\\.)+[a-zA-Z]{2,6}(/|):" REGEX_PORT_NUMBER);
|
||||
rule.pattern.setPatternOptions(QRegularExpression::PatternOption::ExtendedPatternSyntaxOption);
|
||||
rule.format = ipHostFormat;
|
||||
highlightingRules.append(rule);
|
||||
}
|
||||
|
||||
for (const auto &pattern: {"tcp:", "udp:"}) {
|
||||
tcpudpFormat.setFontWeight(QFont::Bold);
|
||||
rule.pattern = QRegularExpression(pattern);
|
||||
rule.format = tcpudpFormat;
|
||||
highlightingRules.append(rule);
|
||||
}
|
||||
}
|
||||
|
||||
void SyntaxHighlighter::highlightBlock(const QString &text) {
|
||||
for (const HighlightingRule &rule: highlightingRules) {
|
||||
QRegularExpressionMatchIterator matchIterator = rule.pattern.globalMatch(text);
|
||||
|
||||
while (matchIterator.hasNext()) {
|
||||
QRegularExpressionMatch match = matchIterator.next();
|
||||
setFormat(match.capturedStart(), match.capturedLength(), rule.format);
|
||||
}
|
||||
}
|
||||
|
||||
setCurrentBlockState(0);
|
||||
}
|
||||
} // namespace Qv2ray::ui
|
||||
92
3rdparty/qv2ray/v2/ui/LogHighlighter.hpp
vendored
92
3rdparty/qv2ray/v2/ui/LogHighlighter.hpp
vendored
@ -1,92 +0,0 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2016 The Qt Company Ltd.
|
||||
** Contact: https://www.qt.io/licensing/
|
||||
**
|
||||
** This file is part of the examples of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:BSD$
|
||||
** Commercial License Usage
|
||||
** Licensees holding valid commercial Qt licenses may use this file in
|
||||
** accordance with the commercial license agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and The Qt Company. For licensing terms
|
||||
** and conditions see https://www.qt.io/terms-conditions. For further
|
||||
** information use the contact form at https://www.qt.io/contact-us.
|
||||
**
|
||||
** BSD License Usage
|
||||
** Alternatively, you may use this file under the terms of the BSD license
|
||||
** as follows:
|
||||
**
|
||||
** "Redistribution and use in source and binary forms, with or without
|
||||
** modification, are permitted provided that the following conditions are
|
||||
** met:
|
||||
** * Redistributions of source code must retain the above copyright
|
||||
** notice, this list of conditions and the following disclaimer.
|
||||
** * Redistributions in binary form must reproduce the above copyright
|
||||
** notice, this list of conditions and the following disclaimer in
|
||||
** the documentation and/or other materials provided with the
|
||||
** distribution.
|
||||
** * Neither the name of The Qt Company Ltd nor the names of its
|
||||
** contributors may be used to endorse or promote products derived
|
||||
** from this software without specific prior written permission.
|
||||
**
|
||||
**
|
||||
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
|
||||
**
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <QRegularExpression>
|
||||
#include <QSyntaxHighlighter>
|
||||
#include <QTextCharFormat>
|
||||
#include <QTextDocument>
|
||||
|
||||
namespace Qv2ray {
|
||||
namespace ui {
|
||||
class SyntaxHighlighter : public QSyntaxHighlighter {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit SyntaxHighlighter(bool darkMode, QTextDocument *parent = nullptr);
|
||||
|
||||
protected:
|
||||
void highlightBlock(const QString &text) override;
|
||||
|
||||
private:
|
||||
struct HighlightingRule {
|
||||
QRegularExpression pattern;
|
||||
QTextCharFormat format;
|
||||
};
|
||||
QVector<HighlightingRule> highlightingRules;
|
||||
|
||||
QTextCharFormat tcpudpFormat;
|
||||
QTextCharFormat dateFormat;
|
||||
QTextCharFormat acceptedFormat;
|
||||
QTextCharFormat rejectedFormat;
|
||||
QTextCharFormat failedFormat;
|
||||
QTextCharFormat warningFormat;
|
||||
QTextCharFormat warningFormat2;
|
||||
QTextCharFormat infoFormat;
|
||||
QTextCharFormat debugFormat;
|
||||
QTextCharFormat timeFormat;
|
||||
QTextCharFormat ipHostFormat;
|
||||
QTextCharFormat v2rayComponentFormat;
|
||||
};
|
||||
} // namespace ui
|
||||
} // namespace Qv2ray
|
||||
|
||||
using namespace Qv2ray::ui;
|
||||
@ -191,13 +191,13 @@ QVariant QJsonModel::data(const QModelIndex &index, int role) const {
|
||||
|
||||
if (role == Qt::DisplayRole) {
|
||||
if (index.column() == 0)
|
||||
return QString("%1").arg(item->key());
|
||||
return QStringLiteral("%1").arg(item->key());
|
||||
|
||||
if (index.column() == 1)
|
||||
return QString("%1").arg(item->value());
|
||||
return QStringLiteral("%1").arg(item->value());
|
||||
} else if (Qt::EditRole == role) {
|
||||
if (index.column() == 1) {
|
||||
return QString("%1").arg(item->value());
|
||||
return QStringLiteral("%1").arg(item->value());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
cmake_minimum_required(VERSION 3.5)
|
||||
|
||||
project(nekoray VERSION 0.1 LANGUAGES CXX)
|
||||
project(nekobox VERSION 0.1 LANGUAGES CXX)
|
||||
|
||||
set(CMAKE_INCLUDE_CURRENT_DIR ON)
|
||||
|
||||
@ -30,9 +30,7 @@ if (NKR_CROSS)
|
||||
endif ()
|
||||
|
||||
#### Platform Variables ####
|
||||
if (APPLE)
|
||||
include("cmake/macos/macos.cmake")
|
||||
elseif (WIN32)
|
||||
if (WIN32)
|
||||
include("cmake/windows/windows.cmake")
|
||||
else ()
|
||||
include("cmake/linux/linux.cmake")
|
||||
@ -65,10 +63,6 @@ include("cmake/nkr.cmake")
|
||||
|
||||
find_package(Threads)
|
||||
|
||||
if (NKR_PACKAGE OR NKR_PACKAGE_MACOS)
|
||||
nkr_add_compile_definitions(NKR_CPP_USE_APPDATA)
|
||||
endif ()
|
||||
|
||||
#### NKR EXTERNAL ####
|
||||
|
||||
if (NKR_NO_EXTERNAL)
|
||||
@ -76,15 +70,6 @@ if (NKR_NO_EXTERNAL)
|
||||
set(NKR_NO_YAML 1)
|
||||
set(NKR_NO_ZXING 1)
|
||||
set(NKR_NO_QHOTKEY 1)
|
||||
set(NKR_NO_QUICKJS 1)
|
||||
endif ()
|
||||
|
||||
# quickjs (static submodule)
|
||||
if (NKR_NO_QUICKJS)
|
||||
nkr_add_compile_definitions(NKR_NO_QUICKJS)
|
||||
else ()
|
||||
add_subdirectory(3rdparty/qjs)
|
||||
list(APPEND NKR_EXTERNAL_TARGETS quickjs)
|
||||
endif ()
|
||||
|
||||
# grpc
|
||||
@ -140,14 +125,12 @@ set(PROJECT_SOURCES
|
||||
main/main.cpp
|
||||
main/NekoGui.cpp
|
||||
main/NekoGui_Utils.cpp
|
||||
main/QJS.cpp
|
||||
main/HTTPRequestHelper.cpp
|
||||
|
||||
3rdparty/base64.cpp
|
||||
3rdparty/qrcodegen.cpp
|
||||
3rdparty/QtExtKeySequenceEdit.cpp
|
||||
|
||||
3rdparty/qv2ray/v2/ui/LogHighlighter.cpp
|
||||
3rdparty/qv2ray/v2/ui/QvAutoCompleteTextEdit.cpp
|
||||
3rdparty/qv2ray/v2/components/proxy/QvProxyConfigurator.cpp
|
||||
3rdparty/qv2ray/v2/ui/widgets/common/QJsonModel.cpp
|
||||
@ -166,7 +149,6 @@ set(PROJECT_SOURCES
|
||||
db/ConfigBuilder.cpp
|
||||
|
||||
fmt/AbstractBean.cpp
|
||||
fmt/Bean2CoreObj_ray.cpp
|
||||
fmt/Bean2CoreObj_box.cpp
|
||||
fmt/Bean2External.cpp
|
||||
fmt/Bean2Link.cpp
|
||||
@ -241,10 +223,6 @@ set(PROJECT_SOURCES
|
||||
ui/dialog_hotkey.h
|
||||
ui/dialog_hotkey.ui
|
||||
|
||||
ui/dialog_first_setup.cpp
|
||||
ui/dialog_first_setup.h
|
||||
ui/dialog_first_setup.ui
|
||||
|
||||
ui/widget/ProxyItem.cpp
|
||||
ui/widget/ProxyItem.h
|
||||
ui/widget/ProxyItem.ui
|
||||
@ -259,23 +237,23 @@ set(PROJECT_SOURCES
|
||||
|
||||
# Qt exe
|
||||
if (${QT_VERSION_MAJOR} GREATER_EQUAL 6)
|
||||
qt_add_executable(nekoray
|
||||
qt_add_executable(nekobox
|
||||
MANUAL_FINALIZATION
|
||||
${PROJECT_SOURCES}
|
||||
)
|
||||
# Define target properties for Android with Qt 6 as:
|
||||
# set_property(TARGET nekoray APPEND PROPERTY QT_ANDROID_PACKAGE_SOURCE_DIR
|
||||
# set_property(TARGET nekobox APPEND PROPERTY QT_ANDROID_PACKAGE_SOURCE_DIR
|
||||
# ${CMAKE_CURRENT_SOURCE_DIR}/android)
|
||||
# For more information, see https://doc.qt.io/qt-6/qt-add-executable.html#target-creation
|
||||
else ()
|
||||
if (ANDROID)
|
||||
add_library(nekoray SHARED
|
||||
add_library(nekobox SHARED
|
||||
${PROJECT_SOURCES}
|
||||
)
|
||||
# Define properties for Android with Qt 5 after find_package() calls as:
|
||||
# set(ANDROID_PACKAGE_SOURCE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/android")
|
||||
else ()
|
||||
add_executable(nekoray
|
||||
add_executable(nekobox
|
||||
${PROJECT_SOURCES}
|
||||
)
|
||||
endif ()
|
||||
@ -283,22 +261,11 @@ endif ()
|
||||
|
||||
# Target
|
||||
|
||||
set_property(TARGET nekoray PROPERTY AUTOUIC ON)
|
||||
set_property(TARGET nekoray PROPERTY AUTOMOC ON)
|
||||
set_property(TARGET nekoray PROPERTY AUTORCC ON)
|
||||
set_property(TARGET nekobox PROPERTY AUTOUIC ON)
|
||||
set_property(TARGET nekobox PROPERTY AUTOMOC ON)
|
||||
set_property(TARGET nekobox PROPERTY AUTORCC ON)
|
||||
|
||||
# Target Source macOS
|
||||
|
||||
set(MACOSX_ICON ${CMAKE_SOURCE_DIR}/res/nekoray.icns)
|
||||
if (APPLE)
|
||||
target_sources(nekoray PRIVATE ${MACOSX_ICON})
|
||||
endif ()
|
||||
set_target_properties(nekoray PROPERTIES
|
||||
MACOSX_BUNDLE_ICON_FILE "nekoray.icns"
|
||||
RESOURCE ${MACOSX_ICON}
|
||||
MACOSX_BUNDLE_INFO_PLIST ${CMAKE_SOURCE_DIR}/res/MacOSXBundleInfo.plist
|
||||
MACOSX_BUNDLE_GUI_IDENTIFIER moe.nekoray.macosx
|
||||
MACOSX_BUNDLE TRUE
|
||||
set_target_properties(nekobox PROPERTIES
|
||||
WIN32_EXECUTABLE TRUE
|
||||
)
|
||||
|
||||
@ -313,17 +280,17 @@ set(LUPDATE_OPTIONS
|
||||
-locations none -no-obsolete
|
||||
)
|
||||
if (${QT_VERSION_MAJOR} GREATER_EQUAL 6)
|
||||
qt_add_lupdate(nekoray TS_FILES ${TS_FILES} OPTIONS ${LUPDATE_OPTIONS})
|
||||
qt_add_lrelease(nekoray TS_FILES ${TS_FILES} QM_FILES_OUTPUT_VARIABLE QM_FILES)
|
||||
qt_add_lupdate(nekobox TS_FILES ${TS_FILES} OPTIONS ${LUPDATE_OPTIONS})
|
||||
qt_add_lrelease(nekobox TS_FILES ${TS_FILES} QM_FILES_OUTPUT_VARIABLE QM_FILES)
|
||||
else ()
|
||||
qt5_create_translation(QM_FILES ${PROJECT_SOURCES} ${TS_FILES} OPTIONS ${LUPDATE_OPTIONS})
|
||||
endif ()
|
||||
configure_file(translations/translations.qrc ${CMAKE_BINARY_DIR} COPYONLY)
|
||||
target_sources(nekoray PRIVATE ${CMAKE_BINARY_DIR}/translations.qrc)
|
||||
target_sources(nekobox PRIVATE ${CMAKE_BINARY_DIR}/translations.qrc)
|
||||
|
||||
# Target Link
|
||||
|
||||
target_link_libraries(nekoray PRIVATE
|
||||
target_link_libraries(nekobox PRIVATE
|
||||
Qt${QT_VERSION_MAJOR}::Widgets Qt${QT_VERSION_MAJOR}::Network Qt${QT_VERSION_MAJOR}::Svg
|
||||
Threads::Threads
|
||||
${NKR_EXTERNAL_TARGETS}
|
||||
@ -331,5 +298,5 @@ target_link_libraries(nekoray PRIVATE
|
||||
)
|
||||
|
||||
if (QT_VERSION_MAJOR EQUAL 6)
|
||||
qt_finalize_executable(nekoray)
|
||||
qt_finalize_executable(nekobox)
|
||||
endif ()
|
||||
|
||||
61
README.md
61
README.md
@ -1,17 +1,13 @@
|
||||
# NekoRay / NekoBox For PC
|
||||
# NekoBox For PC
|
||||
|
||||
Qt based cross-platform GUI proxy configuration manager (backend: v2ray / sing-box)
|
||||
Qt based cross-platform GUI proxy configuration manager (backend: sing-box)
|
||||
|
||||
Support Windows / Linux out of the box now.
|
||||
|
||||
基于 Qt 的跨平台代理配置管理器 (后端 v2ray / sing-box)
|
||||
基于 Qt 的跨平台代理配置管理器 (后端 sing-box)
|
||||
|
||||
目前支持 Windows / Linux 开箱即用
|
||||
|
||||
## Readme Translations
|
||||
|
||||
中文 / English / [fa_IR](README_fa.md)
|
||||
|
||||
## 下载 / Download
|
||||
|
||||
### GitHub Releases (Portable ZIP)
|
||||
@ -27,17 +23,20 @@ Support Windows / Linux out of the box now.
|
||||
### Package
|
||||
|
||||
#### AUR
|
||||
|
||||
- [nekoray](https://aur.archlinux.org/packages/nekoray)
|
||||
- [nekoray-git](https://aur.archlinux.org/packages/nekoray-git)
|
||||
|
||||
#### archlinuxcn
|
||||
|
||||
- [nekoray](https://github.com/archlinuxcn/repo/tree/master/archlinuxcn/nekoray)
|
||||
- [nekoray-git](https://github.com/archlinuxcn/repo/tree/master/archlinuxcn/nekoray-git)
|
||||
|
||||
#### Scoop extras
|
||||
#### Scoop Extras
|
||||
|
||||
`scoop install nekoray`
|
||||
|
||||
## 更改记录 & 发布频道 / Changelog & Telegram channel
|
||||
## 更改记录 & 发布频道 / Changelog & Telegram Channel
|
||||
|
||||
https://t.me/Matsuridayo
|
||||
|
||||
@ -47,24 +46,23 @@ https://matsuridayo.github.io
|
||||
|
||||
## 代理 / Proxy
|
||||
|
||||
* SOCKS (4/4a/5)
|
||||
* HTTP(S)
|
||||
* Shadowsocks
|
||||
* VMess
|
||||
* VLESS
|
||||
* Trojan
|
||||
* TUIC ( sing-box )
|
||||
* NaïveProxy ( Custom Core )
|
||||
* Hysteria ( Custom Core or sing-box )
|
||||
* Hysteria2 ( Custom Core or sing-box )
|
||||
* Custom Outbound
|
||||
* Custom Config
|
||||
* Custom Core
|
||||
- SOCKS (4/4a/5)
|
||||
- HTTP(S)
|
||||
- Shadowsocks
|
||||
- VMess
|
||||
- VLESS
|
||||
- Trojan
|
||||
- TUIC ( sing-box )
|
||||
- NaïveProxy ( Custom Core )
|
||||
- Hysteria2 ( Custom Core or sing-box )
|
||||
- Custom Outbound
|
||||
- Custom Config
|
||||
- Custom Core
|
||||
|
||||
## 订阅 / Subscription
|
||||
|
||||
* Raw: some widely used formats (like shadowsocks, clash and v2rayN)
|
||||
* 原始格式:一些广泛使用的格式(如 shadowsocks、clash 和 v2rayN)
|
||||
- Raw: some widely used formats (like Shadowsocks, Clash and v2rayN)
|
||||
- 原始格式: 一些广泛使用的格式 (如 Shadowsocks、Clash 和 v2rayN)
|
||||
|
||||
## 运行参数
|
||||
|
||||
@ -78,14 +76,6 @@ https://matsuridayo.github.io
|
||||
|
||||
[Linux 运行教程](docs/Run_Linux.md)
|
||||
|
||||
## macOS
|
||||
|
||||
由于缺乏维护,不再提供 macOS 版本下载。
|
||||
|
||||
您还可以在下面的存储库中非正式地获取更新版本。[非官方发布 / Unofficial releases](https://github.com/aaaamirabbas/nekoray-macos/releases)
|
||||
|
||||
仍可以参照下方教程自行编译,常见问题请参考历史 Issue,欢迎 Pull Request 修复。
|
||||
|
||||
## 编译教程 / Compile Tutorial
|
||||
|
||||
请看 [技术文档 / Technical documentation](https://github.com/MatsuriDayo/nekoray/tree/main/docs)
|
||||
@ -106,9 +96,6 @@ XMR
|
||||
|
||||
`49bwESYQjoRL3xmvTcjZKHEKaiGywjLYVQJMUv79bXonGiyDCs8AzE3KiGW2ytTybBCpWJUvov8SjZZEGg66a4e59GXa6k5`
|
||||
|
||||
* 您也可以通过 [Google Play](https://play.google.com/store/apps/details?id=moe.nb4a) 购买捐赠,另有支付宝微信购买方式,见 TG 频道置顶。
|
||||
* Donating via [Google Play](https://play.google.com/store/apps/details?id=moe.nb4a), using credit cards.
|
||||
|
||||
## Credits
|
||||
|
||||
Core:
|
||||
@ -116,8 +103,8 @@ Core:
|
||||
- [v2fly/v2ray-core](https://github.com/v2fly/v2ray-core) ( < 3.10 )
|
||||
- [MatsuriDayo/Matsuri](https://github.com/MatsuriDayo/Matsuri) ( < 3.10 )
|
||||
- [MatsuriDayo/v2ray-core](https://github.com/MatsuriDayo/v2ray-core) ( < 3.10 )
|
||||
- [XTLS/Xray-core](https://github.com/XTLS/Xray-core) ( >= 3.10 )
|
||||
- [MatsuriDayo/Xray-core](https://github.com/MatsuriDayo/Xray-core) ( >= 3.10 )
|
||||
- [XTLS/Xray-core](https://github.com/XTLS/Xray-core) ( 3.10 <= Version <= 3.26 )
|
||||
- [MatsuriDayo/Xray-core](https://github.com/MatsuriDayo/Xray-core) ( 3.10 <= Version <= 3.26 )
|
||||
- [SagerNet/sing-box](https://github.com/SagerNet/sing-box)
|
||||
- [Matsuridayo/sing-box-extra](https://github.com/MatsuriDayo/sing-box-extra)
|
||||
|
||||
|
||||
94
README_fa.md
94
README_fa.md
@ -1,94 +0,0 @@
|
||||
# NekoRay
|
||||
|
||||
مدیریت پیکربندی پروکسی با رابط کاربری مبتنی بر QT , کراس پلتفرم . (بک اند : v2ray / sing-box )
|
||||
|
||||
اکنون از Windows / Linux / macOS amd64 پشتیبانی می کند.
|
||||
|
||||
## دانلود / Download
|
||||
|
||||
### GitHub Releases (Portable ZIP)
|
||||
|
||||
فرمت قابل حمل، بدون نصب. برای دانلود باینری های از پیش کامپایل شده به Releases بروید، آنها را باز کرده و از آنها استفاده کنید.
|
||||
|
||||
[](https://github.com/Matsuridayo/nekoray/releases)
|
||||
|
||||
[Download](https://github.com/Matsuridayo/nekoray/releases)
|
||||
|
||||
### بسته
|
||||
|
||||
1. AUR [nekoray-git](https://aur.archlinux.org/packages/nekoray-git)
|
||||
2. Scoop extras: `scoop install nekoray`
|
||||
3. Homebrew (unoffical): [homebrew-nekoray](https://github.com/tdjnodj/homebrew-nekoray)
|
||||
4. APT (unoffical): [tdjnodj/apt](https://github.com/tdjnodj/apt)
|
||||
|
||||
## تغییرات برنامه و کانال تلگرام / Changelog & Telegram channel
|
||||
|
||||
https://t.me/Matsuridayo
|
||||
|
||||
## صفحه مستندات / Homepage & Documents
|
||||
|
||||
https://matsuridayo.github.io
|
||||
|
||||
## پروکسی / Proxy
|
||||
|
||||
* SOCKS (4/4a/5)
|
||||
* HTTP(S)
|
||||
* Shadowsocks
|
||||
* VMess
|
||||
* VLESS
|
||||
* Trojan
|
||||
* NaïveProxy ( Custom Core )
|
||||
* Hysteria ( Custom Core or sing-box )
|
||||
* Hysteria2 ( Custom Core or sing-box )
|
||||
* Custom Outbound
|
||||
* Custom Core
|
||||
|
||||
## اشتراک / Subscription
|
||||
|
||||
* فرمت های خام: برخی از فرمت های پرکاربرد (مانند shadowsocks، clash و v2rayN)
|
||||
|
||||
## پارامترهای عملیاتی
|
||||
|
||||
- `-many` نمونه در حال اجرا همان دایرکتوری را نادیده بگیرید و به اجبار یک نمونه جدید راه اندازی کنید(0.11+)
|
||||
- `-appdata` پس از باز کردن، فایل پیکربندی در دایرکتوری مشترک قرار می گیرد و نمی توان آن را بیشتر باز کرد و به طور خودکار ارتقا داد. (0.11+)
|
||||
|
||||
## Windows
|
||||
|
||||
اگر به شما می گوید که DLL وجود ندارد و نمی تواند اجرا شود، لطفاً [Microsoft C++ Runtime Library] (https://aka.ms/vs/17/release/vc_redist.x64.exe) را دانلود و نصب کنید.
|
||||
|
||||
## Linux
|
||||
|
||||
[آموزش اجرای لینوکس](docs/Run_Linux.md)
|
||||
## آموزش کامپایل
|
||||
|
||||
[Linux](docs/Build_Linux.md)
|
||||
|
||||
[Windows](docs/Build_Windows.md)
|
||||
|
||||
[macOs](docs/Build_MacOS_fa.md)
|
||||
|
||||
## کمک مالی / Donate
|
||||
|
||||
از کمک های مالی برای حمایت از توسعه پروژه استقبال می شود。
|
||||
|
||||
USDT TRC20
|
||||
|
||||
`TRhnA7SXE5Sap5gSG3ijxRmdYFiD4KRhPs`
|
||||
|
||||
XMR
|
||||
|
||||
`49bwESYQjoRL3xmvTcjZKHEKaiGywjLYVQJMUv79bXonGiyDCs8AzE3KiGW2ytTybBCpWJUvov8SjZZEGg66a4e59GXa6k5`
|
||||
|
||||
## Credits
|
||||
|
||||
- [v2fly/v2ray-core](https://github.com/v2fly/v2ray-core)
|
||||
- [MatsuriDayo/Matsuri](https://github.com/MatsuriDayo/Matsuri)
|
||||
- [MatsuriDayo/v2ray-core](https://github.com/MatsuriDayo/v2ray-core)
|
||||
- [SagerNet/sing-box](https://github.com/SagerNet/sing-box)
|
||||
- [Qv2ray](https://github.com/Qv2ray/Qv2ray)
|
||||
- [Qt](https://www.qt.io/)
|
||||
- [protobuf](https://github.com/protocolbuffers/protobuf)
|
||||
- [yaml-cpp](https://github.com/jbeder/yaml-cpp)
|
||||
- [zxing-cpp](https://github.com/nu-book/zxing-cpp)
|
||||
- [QHotkey](https://github.com/Skycoder42/QHotkey)
|
||||
- [AppImageKit](https://github.com/AppImage/AppImageKit)
|
||||
18
appdmg.json
18
appdmg.json
@ -1,18 +0,0 @@
|
||||
{
|
||||
"title": "nekoray",
|
||||
"icon": "res/nekoray.icns",
|
||||
"contents": [
|
||||
{
|
||||
"x": 448,
|
||||
"y": 344,
|
||||
"type": "link",
|
||||
"path": "/Applications"
|
||||
},
|
||||
{
|
||||
"x": 192,
|
||||
"y": 344,
|
||||
"type": "file",
|
||||
"path": "build/nekoray.app"
|
||||
}
|
||||
]
|
||||
}
|
||||
@ -4,12 +4,12 @@ set(PLATFORM_LIBRARIES wininet wsock32 ws2_32 user32 rasapi32 iphlpapi)
|
||||
include(cmake/windows/generate_product_version.cmake)
|
||||
generate_product_version(
|
||||
QV2RAY_RC
|
||||
ICON "${CMAKE_SOURCE_DIR}/res/nekoray.ico"
|
||||
NAME "nekoray"
|
||||
BUNDLE "nekoray"
|
||||
COMPANY_NAME "nekoray"
|
||||
COMPANY_COPYRIGHT "nekoray"
|
||||
FILE_DESCRIPTION "nekoray"
|
||||
ICON "${CMAKE_SOURCE_DIR}/res/nekobox.ico"
|
||||
NAME "nekobox"
|
||||
BUNDLE "nekobox"
|
||||
COMPANY_NAME "nekobox"
|
||||
COMPANY_COPYRIGHT "nekobox"
|
||||
FILE_DESCRIPTION "nekobox"
|
||||
)
|
||||
add_definitions(-DUNICODE -D_UNICODE -DNOMINMAX)
|
||||
set(GUI_TYPE WIN32)
|
||||
|
||||
@ -2,14 +2,12 @@
|
||||
#include "db/Database.hpp"
|
||||
#include "fmt/includes.h"
|
||||
#include "fmt/Preset.hpp"
|
||||
#include "main/QJS.hpp"
|
||||
|
||||
#include <QApplication>
|
||||
#include <QFile>
|
||||
#include <QFileInfo>
|
||||
|
||||
#define BOX_UNDERLYING_DNS dataStore->core_box_underlying_dns.isEmpty() ? "underlying://0.0.0.0" : dataStore->core_box_underlying_dns
|
||||
#define BOX_UNDERLYING_DNS_EXPORT dataStore->core_box_underlying_dns.isEmpty() ? (status->forExport ? "local" : "underlying://0.0.0.0") : dataStore->core_box_underlying_dns
|
||||
#define BOX_UNDERLYING_DNS dataStore->core_box_underlying_dns.isEmpty() ? "local" : dataStore->core_box_underlying_dns
|
||||
|
||||
namespace NekoGui {
|
||||
|
||||
@ -24,30 +22,48 @@ namespace NekoGui {
|
||||
}
|
||||
|
||||
QString genTunName() {
|
||||
auto tun_name = "nekoray-tun";
|
||||
auto tun_name = "neko-tun";
|
||||
#ifdef Q_OS_MACOS
|
||||
tun_name = "utun9";
|
||||
#endif
|
||||
return tun_name;
|
||||
}
|
||||
|
||||
void MergeJson(const QJsonObject &custom, QJsonObject &outbound) {
|
||||
void MergeJson(QJsonObject &dst, const QJsonObject &src) {
|
||||
// 合并
|
||||
if (custom.isEmpty()) return;
|
||||
for (const auto &key: custom.keys()) {
|
||||
if (outbound.contains(key)) {
|
||||
auto v = custom[key];
|
||||
auto v_orig = outbound[key];
|
||||
if (v.isObject() && v_orig.isObject()) { // isObject 则合并?
|
||||
auto vo = v.toObject();
|
||||
QJsonObject vo_orig = v_orig.toObject();
|
||||
MergeJson(vo, vo_orig);
|
||||
outbound[key] = vo_orig;
|
||||
if (src.isEmpty()) return;
|
||||
for (const auto &key: src.keys()) {
|
||||
auto v_src = src[key];
|
||||
if (dst.contains(key)) {
|
||||
auto v_dst = dst[key];
|
||||
if (v_src.isObject() && v_dst.isObject()) { // isObject 则合并?
|
||||
auto v_src_obj = v_src.toObject();
|
||||
auto v_dst_obj = v_dst.toObject();
|
||||
MergeJson(v_dst_obj, v_src_obj);
|
||||
dst[key] = v_dst_obj;
|
||||
} else {
|
||||
outbound[key] = v;
|
||||
dst[key] = v_src;
|
||||
}
|
||||
} else if (v_src.isArray()) {
|
||||
if (key.startsWith("+")) {
|
||||
auto key2 = SubStrAfter(key, "+");
|
||||
auto v_dst = dst[key2];
|
||||
auto v_src_arr = v_src.toArray();
|
||||
auto v_dst_arr = v_dst.toArray();
|
||||
QJSONARRAY_ADD(v_src_arr, v_dst_arr)
|
||||
dst[key2] = v_src_arr;
|
||||
} else if (key.endsWith("+")) {
|
||||
auto key2 = SubStrBefore(key, "+");
|
||||
auto v_dst = dst[key2];
|
||||
auto v_src_arr = v_src.toArray();
|
||||
auto v_dst_arr = v_dst.toArray();
|
||||
QJSONARRAY_ADD(v_dst_arr, v_src_arr)
|
||||
dst[key2] = v_dst_arr;
|
||||
} else {
|
||||
dst[key] = v_src;
|
||||
}
|
||||
} else {
|
||||
outbound[key] = custom[key];
|
||||
dst[key] = v_src;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -66,36 +82,19 @@ namespace NekoGui {
|
||||
if (customBean != nullptr && customBean->core == "internal-full") {
|
||||
result->coreConfig = QString2QJsonObject(customBean->config_simple);
|
||||
} else {
|
||||
if (IS_NEKO_BOX) {
|
||||
BuildConfigSingBox(status);
|
||||
} else {
|
||||
BuildConfigV2Ray(status);
|
||||
}
|
||||
BuildConfigSingBox(status);
|
||||
}
|
||||
|
||||
// apply custom config
|
||||
MergeJson(QString2QJsonObject(ent->bean->custom_config), result->coreConfig);
|
||||
MergeJson(result->coreConfig, QString2QJsonObject(ent->bean->custom_config));
|
||||
|
||||
// hook.js
|
||||
if (result->error.isEmpty() && !forTest) {
|
||||
auto source = qjs::ReadHookJS();
|
||||
if (!source.isEmpty()) {
|
||||
qjs::QJS js(source);
|
||||
auto js_result = js.EvalFunction("hook.hook_core_config", QJsonObject2QString(result->coreConfig, true));
|
||||
auto js_result_json = QString2QJsonObject(js_result);
|
||||
if (!js_result_json.isEmpty() && result->coreConfig != js_result_json) {
|
||||
MW_show_log("hook.js modified your " + software_core_name + " json config.");
|
||||
result->coreConfig = js_result_json;
|
||||
}
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
QString BuildChain(int chainId, const std::shared_ptr<BuildConfigStatus> &status) {
|
||||
auto group = profileManager->GetGroup(status->ent->gid);
|
||||
if (group == nullptr) {
|
||||
status->result->error = QString("This profile is not in any group, your data may be corrupted.");
|
||||
status->result->error = QStringLiteral("This profile is not in any group, your data may be corrupted.");
|
||||
return {};
|
||||
}
|
||||
|
||||
@ -107,11 +106,11 @@ namespace NekoGui {
|
||||
for (auto id: list) {
|
||||
resolved += profileManager->GetProfile(id);
|
||||
if (resolved.last() == nullptr) {
|
||||
status->result->error = QString("chain missing ent: %1").arg(id);
|
||||
status->result->error = QStringLiteral("chain missing ent: %1").arg(id);
|
||||
break;
|
||||
}
|
||||
if (resolved.last()->type == "chain") {
|
||||
status->result->error = QString("chain in chain is not allowed: %1").arg(id);
|
||||
status->result->error = QStringLiteral("chain in chain is not allowed: %1").arg(id);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -128,7 +127,7 @@ namespace NekoGui {
|
||||
if (group->front_proxy_id >= 0) {
|
||||
auto fEnt = profileManager->GetProfile(group->front_proxy_id);
|
||||
if (fEnt == nullptr) {
|
||||
status->result->error = QString("front proxy ent not found.");
|
||||
status->result->error = QStringLiteral("front proxy ent not found.");
|
||||
return {};
|
||||
}
|
||||
ents += resolveChain(fEnt);
|
||||
@ -172,254 +171,6 @@ namespace NekoGui {
|
||||
status->ipListDirect += line; \
|
||||
}
|
||||
|
||||
// V2Ray
|
||||
|
||||
void BuildConfigV2Ray(const std::shared_ptr<BuildConfigStatus> &status) {
|
||||
// Log
|
||||
auto logObj = QJsonObject{{"loglevel", dataStore->log_level}};
|
||||
status->result->coreConfig.insert("log", logObj);
|
||||
|
||||
// Inbounds
|
||||
QJsonObject sniffing{
|
||||
{"destOverride", QJsonArray{"http", "tls", "quic"}},
|
||||
{"enabled", true},
|
||||
{"metadataOnly", false},
|
||||
{"routeOnly", dataStore->routing->sniffing_mode == SniffingMode::FOR_ROUTING},
|
||||
};
|
||||
|
||||
// socks-in
|
||||
if (IsValidPort(dataStore->inbound_socks_port) && !status->forTest) {
|
||||
QJsonObject inboundObj;
|
||||
inboundObj["tag"] = "socks-in";
|
||||
inboundObj["protocol"] = "socks";
|
||||
inboundObj["listen"] = dataStore->inbound_address;
|
||||
inboundObj["port"] = dataStore->inbound_socks_port;
|
||||
QJsonObject socksSettings = {{"udp", true}};
|
||||
if (dataStore->routing->sniffing_mode != SniffingMode::DISABLE) {
|
||||
inboundObj["sniffing"] = sniffing;
|
||||
}
|
||||
if (dataStore->inbound_auth->NeedAuth()) {
|
||||
socksSettings["auth"] = "password";
|
||||
socksSettings["accounts"] = QJsonArray{
|
||||
QJsonObject{
|
||||
{"user", dataStore->inbound_auth->username},
|
||||
{"pass", dataStore->inbound_auth->password},
|
||||
},
|
||||
};
|
||||
}
|
||||
inboundObj["settings"] = socksSettings;
|
||||
status->inbounds += inboundObj;
|
||||
}
|
||||
// http-in
|
||||
if (IsValidPort(dataStore->inbound_http_port) && !status->forTest) {
|
||||
QJsonObject inboundObj;
|
||||
inboundObj["tag"] = "http-in";
|
||||
inboundObj["protocol"] = "http";
|
||||
inboundObj["listen"] = dataStore->inbound_address;
|
||||
inboundObj["port"] = dataStore->inbound_http_port;
|
||||
if (dataStore->routing->sniffing_mode != SniffingMode::DISABLE) {
|
||||
inboundObj["sniffing"] = sniffing;
|
||||
}
|
||||
if (dataStore->inbound_auth->NeedAuth()) {
|
||||
inboundObj["settings"] = QJsonObject{
|
||||
{"accounts", QJsonArray{
|
||||
QJsonObject{
|
||||
{"user", dataStore->inbound_auth->username},
|
||||
{"pass", dataStore->inbound_auth->password},
|
||||
},
|
||||
}},
|
||||
};
|
||||
}
|
||||
status->inbounds += inboundObj;
|
||||
}
|
||||
|
||||
// Outbounds
|
||||
auto tagProxy = BuildChain(0, status);
|
||||
if (!status->result->error.isEmpty()) return;
|
||||
|
||||
// direct & bypass & block
|
||||
status->outbounds += QJsonObject{
|
||||
{"protocol", "freedom"},
|
||||
{"domainStrategy", dataStore->core_ray_freedom_domainStrategy},
|
||||
{"tag", "direct"},
|
||||
};
|
||||
status->outbounds += QJsonObject{
|
||||
{"protocol", "freedom"},
|
||||
{"domainStrategy", dataStore->core_ray_freedom_domainStrategy},
|
||||
{"tag", "bypass"},
|
||||
};
|
||||
status->outbounds += QJsonObject{
|
||||
{"protocol", "blackhole"},
|
||||
{"tag", "block"},
|
||||
};
|
||||
|
||||
// DNS out
|
||||
if (!status->forTest) {
|
||||
QJsonObject dnsOut;
|
||||
dnsOut["protocol"] = "dns";
|
||||
dnsOut["tag"] = "dns-out";
|
||||
QJsonObject dnsOut_settings;
|
||||
dnsOut_settings["network"] = "tcp";
|
||||
dnsOut_settings["port"] = 53;
|
||||
dnsOut_settings["address"] = "8.8.8.8";
|
||||
dnsOut_settings["userLevel"] = 1;
|
||||
dnsOut["settings"] = dnsOut_settings;
|
||||
dnsOut["proxySettings"] = QJsonObject{{"tag", tagProxy},
|
||||
{"transportLayer", true}};
|
||||
|
||||
status->outbounds += dnsOut;
|
||||
status->routingRules += QJsonObject{
|
||||
{"type", "field"},
|
||||
{"port", "53"},
|
||||
{"inboundTag", QJsonArray{"socks-in", "http-in"}},
|
||||
{"outboundTag", "dns-out"},
|
||||
};
|
||||
}
|
||||
|
||||
// custom inbound
|
||||
if (!status->forTest) QJSONARRAY_ADD(status->inbounds, QString2QJsonObject(dataStore->custom_inbound)["inbounds"].toArray())
|
||||
|
||||
status->result->coreConfig.insert("inbounds", status->inbounds);
|
||||
status->result->coreConfig.insert("outbounds", status->outbounds);
|
||||
|
||||
// user rule
|
||||
if (!status->forTest) {
|
||||
DOMAIN_USER_RULE
|
||||
IP_USER_RULE
|
||||
}
|
||||
|
||||
// final add DNS
|
||||
QJsonObject dns;
|
||||
QJsonArray dnsServers;
|
||||
|
||||
// Remote or FakeDNS
|
||||
QJsonObject dnsServerRemote;
|
||||
dnsServerRemote["address"] = dataStore->routing->remote_dns;
|
||||
dnsServerRemote["domains"] = QList2QJsonArray<QString>(status->domainListDNSRemote);
|
||||
dnsServerRemote["queryStrategy"] = dataStore->routing->remote_dns_strategy;
|
||||
if (!status->forTest) dnsServers += dnsServerRemote;
|
||||
|
||||
// Direct
|
||||
auto directDnsAddress = dataStore->routing->direct_dns;
|
||||
if (directDnsAddress.contains("://")) {
|
||||
auto directDnsIp = SubStrBefore(SubStrAfter(directDnsAddress, "://"), "/");
|
||||
if (IsIpAddress(directDnsIp)) {
|
||||
status->routingRules.push_front(QJsonObject{
|
||||
{"type", "field"},
|
||||
{"ip", QJsonArray{directDnsIp}},
|
||||
{"outboundTag", "direct"},
|
||||
});
|
||||
} else {
|
||||
status->routingRules.push_front(QJsonObject{
|
||||
{"type", "field"},
|
||||
{"domain", QJsonArray{directDnsIp}},
|
||||
{"outboundTag", "direct"},
|
||||
});
|
||||
}
|
||||
} else if (directDnsAddress != "localhost") {
|
||||
status->routingRules.push_front(QJsonObject{
|
||||
{"type", "field"},
|
||||
{"ip", QJsonArray{directDnsAddress}},
|
||||
{"outboundTag", "direct"},
|
||||
});
|
||||
}
|
||||
QJsonObject directObj{
|
||||
{"address", directDnsAddress.replace("https://", "https+local://")},
|
||||
{"queryStrategy", dataStore->routing->direct_dns_strategy},
|
||||
{"domains", QList2QJsonArray<QString>(status->domainListDNSDirect)},
|
||||
};
|
||||
if (dataStore->routing->dns_final_out == "bypass") {
|
||||
dnsServers.prepend(directObj);
|
||||
} else {
|
||||
dnsServers.append(directObj);
|
||||
}
|
||||
|
||||
dns["disableFallback"] = true;
|
||||
dns["servers"] = dnsServers;
|
||||
dns["tag"] = "dns";
|
||||
|
||||
if (dataStore->routing->use_dns_object) {
|
||||
dns = QString2QJsonObject(dataStore->routing->dns_object);
|
||||
}
|
||||
status->result->coreConfig.insert("dns", dns);
|
||||
|
||||
// Routing
|
||||
QJsonObject routing;
|
||||
routing["domainStrategy"] = dataStore->routing->domain_strategy;
|
||||
if (status->forTest) routing["domainStrategy"] = "AsIs";
|
||||
|
||||
// final add user rule (block)
|
||||
QJsonObject routingRule_tmp;
|
||||
routingRule_tmp["type"] = "field";
|
||||
routingRule_tmp["outboundTag"] = "block";
|
||||
if (!status->ipListBlock.isEmpty()) {
|
||||
auto tmp = routingRule_tmp;
|
||||
tmp["ip"] = QList2QJsonArray<QString>(status->ipListBlock);
|
||||
status->routingRules += tmp;
|
||||
}
|
||||
if (!status->domainListBlock.isEmpty()) {
|
||||
auto tmp = routingRule_tmp;
|
||||
tmp["domain"] = QList2QJsonArray<QString>(status->domainListBlock);
|
||||
status->routingRules += tmp;
|
||||
}
|
||||
|
||||
// final add user rule (proxy)
|
||||
routingRule_tmp["outboundTag"] = "proxy";
|
||||
if (!status->ipListRemote.isEmpty()) {
|
||||
auto tmp = routingRule_tmp;
|
||||
tmp["ip"] = QList2QJsonArray<QString>(status->ipListRemote);
|
||||
status->routingRules += tmp;
|
||||
}
|
||||
if (!status->domainListRemote.isEmpty()) {
|
||||
auto tmp = routingRule_tmp;
|
||||
tmp["domain"] = QList2QJsonArray<QString>(status->domainListRemote);
|
||||
status->routingRules += tmp;
|
||||
}
|
||||
|
||||
// final add user rule (bypass)
|
||||
routingRule_tmp["outboundTag"] = "bypass";
|
||||
if (!status->ipListDirect.isEmpty()) {
|
||||
auto tmp = routingRule_tmp;
|
||||
tmp["ip"] = QList2QJsonArray<QString>(status->ipListDirect);
|
||||
status->routingRules += tmp;
|
||||
}
|
||||
if (!status->domainListDirect.isEmpty()) {
|
||||
auto tmp = routingRule_tmp;
|
||||
tmp["domain"] = QList2QJsonArray<QString>(status->domainListDirect);
|
||||
status->routingRules += tmp;
|
||||
}
|
||||
|
||||
// def_outbound
|
||||
if (!status->forTest) status->routingRules += QJsonObject{
|
||||
{"type", "field"},
|
||||
{"port", "0-65535"},
|
||||
{"outboundTag", dataStore->routing->def_outbound},
|
||||
};
|
||||
|
||||
// final add routing rule
|
||||
auto routingRules = QString2QJsonObject(dataStore->routing->custom)["rules"].toArray();
|
||||
if (status->forTest) routingRules = {};
|
||||
if (!status->forTest) QJSONARRAY_ADD(routingRules, QString2QJsonObject(dataStore->custom_route_global)["rules"].toArray())
|
||||
QJSONARRAY_ADD(routingRules, status->routingRules)
|
||||
routing["rules"] = routingRules;
|
||||
status->result->coreConfig.insert("routing", routing);
|
||||
|
||||
// Policy & stats
|
||||
QJsonObject policy;
|
||||
QJsonObject levels;
|
||||
QJsonObject level1;
|
||||
level1["connIdle"] = 30;
|
||||
levels["1"] = level1;
|
||||
policy["levels"] = levels;
|
||||
|
||||
QJsonObject policySystem;
|
||||
policySystem["statsOutboundDownlink"] = true;
|
||||
policySystem["statsOutboundUplink"] = true;
|
||||
policy["system"] = policySystem;
|
||||
status->result->coreConfig.insert("policy", policy);
|
||||
status->result->coreConfig.insert("stats", QJsonObject());
|
||||
}
|
||||
|
||||
QString BuildChainInternal(int chainId, const QList<std::shared_ptr<ProxyEntity>> &ents,
|
||||
const std::shared_ptr<BuildConfigStatus> &status) {
|
||||
QString chainTag = "c-" + Int2String(chainId);
|
||||
@ -469,29 +220,14 @@ namespace NekoGui {
|
||||
// chain rules: past
|
||||
if (pastExternalStat == 0) {
|
||||
auto replaced = status->outbounds.last().toObject();
|
||||
if (IS_NEKO_BOX) {
|
||||
replaced["detour"] = tagOut;
|
||||
} else {
|
||||
replaced["proxySettings"] = QJsonObject{
|
||||
{"tag", tagOut},
|
||||
{"transportLayer", true},
|
||||
};
|
||||
}
|
||||
replaced["detour"] = tagOut;
|
||||
status->outbounds.removeLast();
|
||||
status->outbounds += replaced;
|
||||
} else {
|
||||
if (IS_NEKO_BOX) {
|
||||
status->routingRules += QJsonObject{
|
||||
{"inbound", QJsonArray{pastTag + "-mapping"}},
|
||||
{"outbound", tagOut},
|
||||
};
|
||||
} else {
|
||||
status->routingRules += QJsonObject{
|
||||
{"type", "field"},
|
||||
{"inboundTag", QJsonArray{pastTag + "-mapping"}},
|
||||
{"outboundTag", tagOut},
|
||||
};
|
||||
}
|
||||
status->routingRules += QJsonObject{
|
||||
{"inbound", QJsonArray{pastTag + "-mapping"}},
|
||||
{"outbound", tagOut},
|
||||
};
|
||||
}
|
||||
} else {
|
||||
// index == 0 means last profile in chain / not chain
|
||||
@ -530,43 +266,20 @@ namespace NekoGui {
|
||||
if (thisExternalStat == 2) dataStore->need_keep_vpn_off = true;
|
||||
if (thisExternalStat == 1) {
|
||||
// mapping
|
||||
if (IS_NEKO_BOX) {
|
||||
status->inbounds += QJsonObject{
|
||||
{"type", "direct"},
|
||||
{"tag", tagOut + "-mapping"},
|
||||
{"listen", "127.0.0.1"},
|
||||
{"listen_port", ext_mapping_port},
|
||||
{"override_address", ent->bean->serverAddress},
|
||||
{"override_port", ent->bean->serverPort},
|
||||
};
|
||||
} else {
|
||||
status->inbounds += QJsonObject{
|
||||
{"protocol", "dokodemo-door"},
|
||||
{"tag", tagOut + "-mapping"},
|
||||
{"listen", "127.0.0.1"},
|
||||
{"port", ext_mapping_port},
|
||||
{"settings", QJsonObject{
|
||||
// to
|
||||
{"address", ent->bean->serverAddress},
|
||||
{"port", ent->bean->serverPort},
|
||||
{"network", "tcp,udp"},
|
||||
}},
|
||||
};
|
||||
}
|
||||
status->inbounds += QJsonObject{
|
||||
{"type", "direct"},
|
||||
{"tag", tagOut + "-mapping"},
|
||||
{"listen", "127.0.0.1"},
|
||||
{"listen_port", ext_mapping_port},
|
||||
{"override_address", ent->bean->serverAddress},
|
||||
{"override_port", ent->bean->serverPort},
|
||||
};
|
||||
// no chain rule and not outbound, so need to set to direct
|
||||
if (isFirstProfile) {
|
||||
if (IS_NEKO_BOX) {
|
||||
status->routingRules += QJsonObject{
|
||||
{"inbound", QJsonArray{tagOut + "-mapping"}},
|
||||
{"outbound", "direct"},
|
||||
};
|
||||
} else {
|
||||
status->routingRules += QJsonObject{
|
||||
{"type", "field"},
|
||||
{"inboundTag", QJsonArray{tagOut + "-mapping"}},
|
||||
{"outboundTag", "direct"},
|
||||
};
|
||||
}
|
||||
status->routingRules += QJsonObject{
|
||||
{"inbound", QJsonArray{tagOut + "-mapping"}},
|
||||
{"outbound", "direct"},
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@ -589,23 +302,11 @@ namespace NekoGui {
|
||||
status->result->extRs.emplace_back(std::make_shared<NekoGui_fmt::ExternalBuildResult>(extR));
|
||||
|
||||
// SOCKS OUTBOUND
|
||||
if (IS_NEKO_BOX) {
|
||||
outbound["type"] = "socks";
|
||||
outbound["server"] = "127.0.0.1";
|
||||
outbound["server_port"] = ext_socks_port;
|
||||
} else {
|
||||
outbound["protocol"] = "socks";
|
||||
QJsonObject settings;
|
||||
QJsonArray servers;
|
||||
QJsonObject server;
|
||||
server["address"] = "127.0.0.1";
|
||||
server["port"] = ext_socks_port;
|
||||
servers.push_back(server);
|
||||
settings["servers"] = servers;
|
||||
outbound["settings"] = settings;
|
||||
}
|
||||
outbound["type"] = "socks";
|
||||
outbound["server"] = "127.0.0.1";
|
||||
outbound["server_port"] = ext_socks_port;
|
||||
} else {
|
||||
const auto coreR = IS_NEKO_BOX ? ent->bean->BuildCoreObjSingBox() : ent->bean->BuildCoreObjV2Ray();
|
||||
const auto coreR = ent->bean->BuildCoreObjSingBox();
|
||||
if (coreR.outbound.isEmpty()) {
|
||||
status->result->error = "unsupported outbound";
|
||||
return {};
|
||||
@ -628,14 +329,8 @@ namespace NekoGui {
|
||||
needMux &= dataStore->mux_concurrency > 0;
|
||||
|
||||
if (stream != nullptr) {
|
||||
if (IS_NEKO_BOX) {
|
||||
if (stream->network == "grpc" || stream->network == "quic" || (stream->network == "http" && stream->security == "tls")) {
|
||||
needMux = false;
|
||||
}
|
||||
} else {
|
||||
if (stream->network == "grpc" || stream->network == "quic") {
|
||||
needMux = false;
|
||||
}
|
||||
if (stream->network == "grpc" || stream->network == "quic" || (stream->network == "http" && stream->security == "tls")) {
|
||||
needMux = false;
|
||||
}
|
||||
if (stream->multiplex_status == 0) {
|
||||
if (!dataStore->mux_default_on) needMux = false;
|
||||
@ -650,36 +345,22 @@ namespace NekoGui {
|
||||
}
|
||||
|
||||
// common
|
||||
if (IS_NEKO_BOX) {
|
||||
// apply domain_strategy
|
||||
outbound["domain_strategy"] = dataStore->routing->outbound_domain_strategy;
|
||||
// apply mux
|
||||
if (!muxApplied && needMux) {
|
||||
auto muxObj = QJsonObject{
|
||||
{"enabled", true},
|
||||
{"protocol", dataStore->mux_protocol},
|
||||
{"padding", dataStore->mux_padding},
|
||||
{"max_streams", dataStore->mux_concurrency},
|
||||
};
|
||||
outbound["multiplex"] = muxObj;
|
||||
muxApplied = true;
|
||||
}
|
||||
} else {
|
||||
// apply domain_strategy
|
||||
if (!status->forTest) outbound["domainStrategy"] = dataStore->routing->outbound_domain_strategy;
|
||||
// apply mux
|
||||
if (!muxApplied && needMux) {
|
||||
auto muxObj = QJsonObject{
|
||||
{"enabled", true},
|
||||
{"concurrency", dataStore->mux_concurrency},
|
||||
};
|
||||
outbound["mux"] = muxObj;
|
||||
muxApplied = true;
|
||||
}
|
||||
// apply domain_strategy
|
||||
outbound["domain_strategy"] = dataStore->routing->outbound_domain_strategy;
|
||||
// apply mux
|
||||
if (!muxApplied && needMux) {
|
||||
auto muxObj = QJsonObject{
|
||||
{"enabled", true},
|
||||
{"protocol", dataStore->mux_protocol},
|
||||
{"padding", dataStore->mux_padding},
|
||||
{"max_streams", dataStore->mux_concurrency},
|
||||
};
|
||||
outbound["multiplex"] = muxObj;
|
||||
muxApplied = true;
|
||||
}
|
||||
|
||||
// apply custom outbound settings
|
||||
MergeJson(QString2QJsonObject(ent->bean->custom_outbound), outbound);
|
||||
MergeJson(outbound, QString2QJsonObject(ent->bean->custom_outbound));
|
||||
|
||||
// Bypass Lookup for the first profile
|
||||
auto serverAddress = ent->bean->serverAddress;
|
||||
@ -735,7 +416,7 @@ namespace NekoGui {
|
||||
}
|
||||
|
||||
// tun-in
|
||||
if (IS_NEKO_BOX_INTERNAL_TUN && dataStore->spmode_vpn && !status->forTest) {
|
||||
if (dataStore->vpn_internal_tun && dataStore->spmode_vpn && !status->forTest) {
|
||||
QJsonObject inboundObj;
|
||||
inboundObj["tag"] = "tun-in";
|
||||
inboundObj["type"] = "tun";
|
||||
@ -823,7 +504,7 @@ namespace NekoGui {
|
||||
} else if (item.startsWith("keyword:")) {
|
||||
domain_keyword += item.replace("keyword:", "").toLower();
|
||||
} else {
|
||||
domain_full += item.toLower();
|
||||
domain_subdomain += item.toLower();
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -860,22 +541,22 @@ namespace NekoGui {
|
||||
};
|
||||
|
||||
// Direct
|
||||
auto directDNSAddress = dataStore->routing->direct_dns;
|
||||
if (directDNSAddress == "localhost") directDNSAddress = BOX_UNDERLYING_DNS_EXPORT;
|
||||
if (!status->forTest) {
|
||||
QJsonObject directObj{
|
||||
{"tag", "dns-direct"},
|
||||
{"address_resolver", "dns-local"},
|
||||
{"strategy", dataStore->routing->direct_dns_strategy},
|
||||
{"address", directDNSAddress.replace("+local://", "://")},
|
||||
{"detour", "direct"},
|
||||
};
|
||||
if (dataStore->routing->dns_final_out == "bypass") {
|
||||
dnsServers.prepend(directObj);
|
||||
} else {
|
||||
dnsServers.append(directObj);
|
||||
}
|
||||
QJsonObject directObj{
|
||||
{"tag", "dns-direct"},
|
||||
{"address_resolver", "dns-local"},
|
||||
{"strategy", dataStore->routing->direct_dns_strategy},
|
||||
{"address", dataStore->routing->direct_dns},
|
||||
{"detour", "direct"},
|
||||
};
|
||||
if (dataStore->routing->dns_final_out == "bypass") {
|
||||
dnsServers.prepend(directObj);
|
||||
} else {
|
||||
dnsServers.append(directObj);
|
||||
}
|
||||
dnsRules.append(QJsonObject{
|
||||
{"outbound", "any"},
|
||||
{"server", "dns-direct"},
|
||||
});
|
||||
|
||||
// block
|
||||
if (!status->forTest)
|
||||
@ -885,7 +566,7 @@ namespace NekoGui {
|
||||
};
|
||||
|
||||
// Fakedns
|
||||
if (dataStore->fake_dns && IS_NEKO_BOX_INTERNAL_TUN && dataStore->spmode_vpn && !status->forTest) {
|
||||
if (dataStore->fake_dns && dataStore->vpn_internal_tun && dataStore->spmode_vpn && !status->forTest) {
|
||||
dnsServers += QJsonObject{
|
||||
{"tag", "dns-fake"},
|
||||
{"address", "fakeip"},
|
||||
@ -897,10 +578,10 @@ namespace NekoGui {
|
||||
};
|
||||
}
|
||||
|
||||
// Underlying 100% Working DNS
|
||||
// Underlying 100% Working DNS ?
|
||||
dnsServers += QJsonObject{
|
||||
{"tag", "dns-local"},
|
||||
{"address", BOX_UNDERLYING_DNS_EXPORT},
|
||||
{"address", BOX_UNDERLYING_DNS},
|
||||
{"detour", "direct"},
|
||||
};
|
||||
|
||||
@ -927,7 +608,7 @@ namespace NekoGui {
|
||||
}
|
||||
|
||||
// fakedns rule
|
||||
if (dataStore->fake_dns && IS_NEKO_BOX_INTERNAL_TUN && dataStore->spmode_vpn && !status->forTest) {
|
||||
if (dataStore->fake_dns && dataStore->vpn_internal_tun && dataStore->spmode_vpn && !status->forTest) {
|
||||
dnsRules += QJsonObject{
|
||||
{"inbound", "tun-in"},
|
||||
{"server", "dns-fake"},
|
||||
@ -985,7 +666,7 @@ namespace NekoGui {
|
||||
};
|
||||
|
||||
// tun user rule
|
||||
if (IS_NEKO_BOX_INTERNAL_TUN && dataStore->spmode_vpn && !status->forTest) {
|
||||
if (dataStore->vpn_internal_tun && dataStore->spmode_vpn && !status->forTest) {
|
||||
auto match_out = dataStore->vpn_rule_white ? "proxy" : "bypass";
|
||||
|
||||
QString process_name_rule = dataStore->vpn_rule_process.trimmed();
|
||||
@ -1025,7 +706,7 @@ namespace NekoGui {
|
||||
QJSONARRAY_ADD(routingRules, status->routingRules)
|
||||
auto routeObj = QJsonObject{
|
||||
{"rules", routingRules},
|
||||
{"auto_detect_interface", dataStore->spmode_vpn},
|
||||
{"auto_detect_interface", dataStore->spmode_vpn}, // TODO force enable?
|
||||
{
|
||||
"geoip",
|
||||
QJsonObject{
|
||||
@ -1063,8 +744,8 @@ namespace NekoGui {
|
||||
|
||||
QString WriteVPNSingBoxConfig() {
|
||||
// tun user rule
|
||||
auto match_out = dataStore->vpn_rule_white ? "nekoray-socks" : "direct";
|
||||
auto no_match_out = dataStore->vpn_rule_white ? "direct" : "nekoray-socks";
|
||||
auto match_out = dataStore->vpn_rule_white ? "neko-socks" : "direct";
|
||||
auto no_match_out = dataStore->vpn_rule_white ? "direct" : "neko-socks";
|
||||
|
||||
QString process_name_rule = dataStore->vpn_rule_process.trimmed();
|
||||
if (!process_name_rule.isEmpty()) {
|
||||
@ -1106,16 +787,6 @@ namespace NekoGui {
|
||||
.replace("%DNS_ADDRESS%", BOX_UNDERLYING_DNS)
|
||||
.replace("%FAKE_DNS_INBOUND%", dataStore->fake_dns ? "tun-in" : "empty")
|
||||
.replace("%PORT%", Int2String(dataStore->inbound_socks_port));
|
||||
// hook.js
|
||||
auto source = qjs::ReadHookJS();
|
||||
if (!source.isEmpty()) {
|
||||
qjs::QJS js(source);
|
||||
auto js_result = js.EvalFunction("hook.hook_tun_config", config);
|
||||
if (config != js_result) {
|
||||
MW_show_log("hook.js modified your Tun config.");
|
||||
config = js_result;
|
||||
}
|
||||
}
|
||||
// write config
|
||||
QFile file;
|
||||
file.setFileName(QFileInfo(configFn).fileName());
|
||||
@ -1125,7 +796,7 @@ namespace NekoGui {
|
||||
return QFileInfo(file).absoluteFilePath();
|
||||
}
|
||||
|
||||
QString WriteVPNLinuxScript(const QString &protectPath, const QString &configPath) {
|
||||
QString WriteVPNLinuxScript(const QString &configPath) {
|
||||
#ifdef Q_OS_WIN
|
||||
return {};
|
||||
#endif
|
||||
@ -1134,19 +805,7 @@ namespace NekoGui {
|
||||
if (QFile::exists("vpn/vpn-run-root.sh")) scriptFn = "vpn/vpn-run-root.sh";
|
||||
auto script = ReadFileText(scriptFn)
|
||||
.replace("./nekobox_core", QApplication::applicationDirPath() + "/nekobox_core")
|
||||
.replace("$PROTECT_LISTEN_PATH", protectPath)
|
||||
.replace("$CONFIG_PATH", configPath)
|
||||
.replace("$TABLE_FWMARK", "514");
|
||||
// hook.js
|
||||
auto source = qjs::ReadHookJS();
|
||||
if (!source.isEmpty()) {
|
||||
qjs::QJS js(source);
|
||||
auto js_result = js.EvalFunction("hook.hook_tun_script", script);
|
||||
if (script != js_result) {
|
||||
MW_show_log("hook.js modified your Tun script.");
|
||||
script = js_result;
|
||||
}
|
||||
}
|
||||
.replace("$CONFIG_PATH", configPath);
|
||||
// write script
|
||||
QFile file2;
|
||||
file2.setFileName(QFileInfo(scriptFn).fileName());
|
||||
|
||||
@ -46,8 +46,6 @@ namespace NekoGui {
|
||||
|
||||
std::shared_ptr<BuildConfigResult> BuildConfig(const std::shared_ptr<ProxyEntity> &ent, bool forTest, bool forExport);
|
||||
|
||||
void BuildConfigV2Ray(const std::shared_ptr<BuildConfigStatus> &status);
|
||||
|
||||
void BuildConfigSingBox(const std::shared_ptr<BuildConfigStatus> &status);
|
||||
|
||||
QString BuildChain(int chainId, const std::shared_ptr<BuildConfigStatus> &status);
|
||||
@ -57,5 +55,5 @@ namespace NekoGui {
|
||||
|
||||
QString WriteVPNSingBoxConfig();
|
||||
|
||||
QString WriteVPNLinuxScript(const QString &protectPath, const QString &configPath);
|
||||
QString WriteVPNLinuxScript(const QString &configPath);
|
||||
} // namespace NekoGui
|
||||
|
||||
@ -42,7 +42,7 @@ namespace NekoGui {
|
||||
// Load Proxys
|
||||
QList<int> delProfile;
|
||||
for (auto id: profilesIdOrder) {
|
||||
auto ent = LoadProxyEntity(QString("profiles/%1.json").arg(id));
|
||||
auto ent = LoadProxyEntity(QStringLiteral("profiles/%1.json").arg(id));
|
||||
// Corrupted profile?
|
||||
if (ent == nullptr || ent->bean == nullptr || ent->bean->version == -114514) {
|
||||
delProfile << id;
|
||||
@ -58,7 +58,7 @@ namespace NekoGui {
|
||||
auto loadedOrder = groupsTabOrder;
|
||||
groupsTabOrder = {};
|
||||
for (auto id: groupsIdOrder) {
|
||||
auto ent = LoadGroup(QString("groups/%1.json").arg(id));
|
||||
auto ent = LoadGroup(QStringLiteral("groups/%1.json").arg(id));
|
||||
// Corrupted group?
|
||||
if (ent->id != id) {
|
||||
continue;
|
||||
@ -103,7 +103,7 @@ namespace NekoGui {
|
||||
auto newId = i++;
|
||||
profile->id = newId;
|
||||
profile->gid = gidOld2New[gid];
|
||||
profile->fn = QString("profiles/%1.json").arg(newId);
|
||||
profile->fn = QStringLiteral("profiles/%1.json").arg(newId);
|
||||
profile->Save();
|
||||
newProfiles[newId] = profile;
|
||||
newProfilesIdOrder << newId;
|
||||
@ -122,7 +122,7 @@ namespace NekoGui {
|
||||
auto group = groups[oldGid];
|
||||
QFile::remove(group->fn);
|
||||
group->id = newId;
|
||||
group->fn = QString("groups/%1.json").arg(newId);
|
||||
group->fn = QStringLiteral("groups/%1.json").arg(newId);
|
||||
group->Save();
|
||||
newGroups[newId] = group;
|
||||
newGroupsIdOrder << newId;
|
||||
@ -184,8 +184,6 @@ namespace NekoGui {
|
||||
bean = new NekoGui_fmt::TrojanVLESSBean(NekoGui_fmt::TrojanVLESSBean::proxy_VLESS);
|
||||
} else if (type == "naive") {
|
||||
bean = new NekoGui_fmt::NaiveBean();
|
||||
} else if (type == "hysteria") {
|
||||
bean = new NekoGui_fmt::QUICBean(NekoGui_fmt::QUICBean::proxy_Hysteria);
|
||||
} else if (type == "hysteria2") {
|
||||
bean = new NekoGui_fmt::QUICBean(NekoGui_fmt::QUICBean::proxy_Hysteria2);
|
||||
} else if (type == "tuic") {
|
||||
@ -229,7 +227,7 @@ namespace NekoGui {
|
||||
if (latency < 0) {
|
||||
return QObject::tr("Unavailable");
|
||||
} else if (latency > 0) {
|
||||
return UNICODE_LRO + QString("%1 ms").arg(latency);
|
||||
return UNICODE_LRO + QStringLiteral("%1 ms").arg(latency);
|
||||
} else {
|
||||
return "";
|
||||
}
|
||||
@ -270,7 +268,7 @@ namespace NekoGui {
|
||||
profiles[ent->id] = ent;
|
||||
profilesIdOrder.push_back(ent->id);
|
||||
|
||||
ent->fn = QString("profiles/%1.json").arg(ent->id);
|
||||
ent->fn = QStringLiteral("profiles/%1.json").arg(ent->id);
|
||||
ent->Save();
|
||||
return true;
|
||||
}
|
||||
@ -280,7 +278,7 @@ namespace NekoGui {
|
||||
if (dataStore->started_id == id) return;
|
||||
profiles.erase(id);
|
||||
profilesIdOrder.removeAll(id);
|
||||
QFile(QString("profiles/%1.json").arg(id)).remove();
|
||||
QFile(QStringLiteral("profiles/%1.json").arg(id)).remove();
|
||||
}
|
||||
|
||||
void ProfileManager::MoveProfile(const std::shared_ptr<ProxyEntity> &ent, int gid) {
|
||||
@ -344,7 +342,7 @@ namespace NekoGui {
|
||||
groupsIdOrder.push_back(ent->id);
|
||||
groupsTabOrder.push_back(ent->id);
|
||||
|
||||
ent->fn = QString("groups/%1.json").arg(ent->id);
|
||||
ent->fn = QStringLiteral("groups/%1.json").arg(ent->id);
|
||||
ent->Save();
|
||||
return true;
|
||||
}
|
||||
@ -361,7 +359,7 @@ namespace NekoGui {
|
||||
groups.erase(gid);
|
||||
groupsIdOrder.removeAll(gid);
|
||||
groupsTabOrder.removeAll(gid);
|
||||
QFile(QString("groups/%1.json").arg(gid)).remove();
|
||||
QFile(QStringLiteral("groups/%1.json").arg(gid)).remove();
|
||||
}
|
||||
|
||||
std::shared_ptr<Group> ProfileManager::GetGroup(int id) {
|
||||
|
||||
@ -29,12 +29,12 @@ namespace NekoGui_traffic {
|
||||
}
|
||||
|
||||
[[nodiscard]] QString DisplaySpeed() const {
|
||||
return UNICODE_LRO + QString("%1↑ %2↓").arg(ReadableSize(uplink_rate), ReadableSize(downlink_rate));
|
||||
return UNICODE_LRO + QStringLiteral("%1↑ %2↓").arg(ReadableSize(uplink_rate), ReadableSize(downlink_rate));
|
||||
}
|
||||
|
||||
[[nodiscard]] QString DisplayTraffic() const {
|
||||
if (downlink + uplink == 0) return "";
|
||||
return UNICODE_LRO + QString("%1↑ %2↓").arg(ReadableSize(uplink), ReadableSize(downlink));
|
||||
return UNICODE_LRO + QStringLiteral("%1↑ %2↓").arg(ReadableSize(uplink), ReadableSize(downlink));
|
||||
}
|
||||
};
|
||||
} // namespace NekoGui_traffic
|
||||
|
||||
@ -1,11 +1,10 @@
|
||||
## 构建 nekoray_core & nekobox_core
|
||||
## 构建 nekobox_core
|
||||
|
||||
### 目录结构
|
||||
|
||||
```
|
||||
| nekoray
|
||||
| go/cmd/*
|
||||
| Xray-core
|
||||
| sing-box-extra
|
||||
| sing-box
|
||||
| ......
|
||||
|
||||
@ -22,9 +22,9 @@ cmake -GNinja ..
|
||||
ninja
|
||||
```
|
||||
|
||||
编译完成后得到 `nekoray`
|
||||
编译完成后得到 `nekobox`
|
||||
|
||||
解压 Release 的压缩包,替换其中的 `nekoray`,删除 `launcher` 即可使用。
|
||||
解压 Release 的压缩包,替换其中的 `nekobox`,删除 `launcher` 即可使用。
|
||||
|
||||
## 复杂编译法
|
||||
|
||||
@ -38,15 +38,13 @@ ninja
|
||||
| NKR_NO_QHOTKEY | | 不包含 qhotkey |
|
||||
| NKR_NO_ZXING | | 不包含 zxing |
|
||||
| NKR_NO_GRPC | | 不包含 gRPC |
|
||||
| NKR_NO_QUICKJS | | 不包含 quickjs |
|
||||
| NKR_PACKAGE | | 编译 package 版本 (aur) |
|
||||
| NKR_PACKAGE_MACOS | | 编译 macos 版本 |
|
||||
| NKR_LIBS | ./libs/deps/built | 依赖搜索目录 |
|
||||
| NKR_DISABLE_LIBS | | 禁用 NKR_LIBS |
|
||||
|
||||
1. `NKR_LIBS` 的值会被追加到 `CMAKE_PREFIX_PATH`
|
||||
2. `NKR_PACKAGE` 打开后,`NKR_LIBS` 的默认值为 `./libs/deps/package` ,具体依赖请看 `build_deps_all.sh`
|
||||
3. `NKR_PACKAGE_MACOS` 或 `NKR_PACKAGE` 打开后,应用将使用 appdata 目录存放配置,自动更新等功能将被禁用。
|
||||
3. `NKR_PACKAGE` 打开后,应用将使用 appdata 目录存放配置,自动更新等功能将被禁用。
|
||||
|
||||
### C++ 部分
|
||||
|
||||
@ -71,7 +69,7 @@ cmake -GNinja ..
|
||||
ninja
|
||||
```
|
||||
|
||||
编译完成后得到 `nekoray`
|
||||
编译完成后得到 `nekobox`
|
||||
|
||||
### Go 部分编译
|
||||
|
||||
|
||||
@ -1,67 +0,0 @@
|
||||
提示:编译通过不代表所有功能可用,Tun 系统代理 这种功能大概率是不可用的。如果您懂得修复,我们欢迎您的 Pull Request。
|
||||
|
||||
Tip: Passing the compilation does not mean that all functions are available, and the function of Tun system proxy is probably not available. If you know how to fix it, we welcome your Pull Request.
|
||||
|
||||
## git clone 源码
|
||||
|
||||
```
|
||||
git clone https://github.com/MatsuriDayo/nekoray.git --recursive
|
||||
```
|
||||
|
||||
## 先决条件
|
||||
|
||||
1. 安装 `CMake` `Ninja` `npm`
|
||||
2. 安装 Qt `5.15.x` 编译环境,并设置好有关环境变量,以免 CMake 找不到 Qt。 (`qtbase` `qtsvg` `qttools`)
|
||||
3. 安装 `appdmg` (`sudo npm install -g appdmg`)
|
||||
|
||||
## CMake 参数
|
||||
|
||||
同 Build_Linux
|
||||
|
||||
## C++ 部分
|
||||
|
||||
### 编译安装 C/C++ 依赖
|
||||
|
||||
(这一步可能要挂梯)
|
||||
|
||||
```shell
|
||||
./libs/build_deps_all.sh
|
||||
```
|
||||
|
||||
### 编译本体
|
||||
|
||||
```shell
|
||||
mkdir build
|
||||
cd build
|
||||
cmake -GNinja -DCMAKE_BUILD_TYPE=Release -DNKR_PACKAGE_MACOS=1 ..
|
||||
ninja
|
||||
```
|
||||
|
||||
### Go 部分编译
|
||||
|
||||
请看 [Build_Core.md](./Build_Core.md)
|
||||
|
||||
## 打包
|
||||
|
||||
如有疑问,请参考[这个脚本](https://github.com/MatsuriDayo/nekoray/blob/main/libs/deploy_macos.sh)
|
||||
|
||||
### 准备core
|
||||
|
||||
将 编译得到的 `nekoray_core` `nekobox_core` 放入 `build/nekoray.app/Contents/MacOS`
|
||||
|
||||
### 准备geo文件(可选)
|
||||
|
||||
```shell
|
||||
curl -Lso build/nekoray.app/Contents/MacOS/geoip.dat "https://github.com/Loyalsoldier/v2ray-rules-dat/releases/latest/download/geoip.dat"
|
||||
curl -Lso build/nekoray.app/Contents/MacOS/geosite.dat "https://github.com/v2fly/domain-list-community/releases/latest/download/dlc.dat"
|
||||
curl -Lso build/nekoray.app/Contents/MacOS/geoip.db "https://github.com/SagerNet/sing-geoip/releases/latest/download/geoip.db"
|
||||
curl -Lso build/nekoray.app/Contents/MacOS/geosite.db "https://github.com/SagerNet/sing-geosite/releases/latest/download/geosite.db"
|
||||
```
|
||||
|
||||
如果打包时没有包含geo文件,可在应用内设置 `v2ray资源路径` 代替。
|
||||
|
||||
### 在nekoray目录下打包
|
||||
|
||||
```shell
|
||||
appdmg appdmg.json /path/to/nekoray.dmg
|
||||
```
|
||||
@ -1,163 +0,0 @@
|
||||
Tip: Passing the compilation does not mean that all functions are available, and the function of Tun system proxy is probably not available. If you know how to fix it, we welcome your Pull Request.
|
||||
|
||||
## پروژه Nekoray را از منبع آن دریافت کنید
|
||||
در `Terminal` در مسیر دلخواه خود، دستور زیر را وارد کنید و دکمه `return` را بفشارید.
|
||||
```shell
|
||||
git clone https://github.com/MatsuriDayo/nekoray.git --recursive
|
||||
```
|
||||
اگر `git` روی دستگاه از پیش نصب نباشد، دستگاه، خودکار نصب آن را پیشنهاد میکند. مرحلههای نصب را به انجام برسانید و سپس دوباره دستور پیش گفته را در `Terminal` اجرا کنید.
|
||||
|
||||
سپس وارد پوشه `nekoray` شوید.
|
||||
برای کامپایل کردن پروژه، پیشنیازهای زیر را نصب کنید. برای این، دستور زیر را در `Terminal` وارد کنید و دکمه `Return` را بفشارید.
|
||||
|
||||
|
||||
```shell
|
||||
cd nekoray
|
||||
```
|
||||
<br>
|
||||
|
||||
## پیشنیازها
|
||||
|
||||
###۱. `CMake`
|
||||
|
||||
برای نصب `CMake` دستور زیر را در `terminal` وارد کنید و دکمه `return` را بفشارید.
|
||||
```shell
|
||||
brew install cmake
|
||||
```
|
||||
اگر با خطای `zsh: command not found: brew` روبهرو شدید به این معنی است که `homebrew` در دستگاه شما نصب نیست. برای نصب آن نخست باید `XCode's command line tools` را نصب کنید. اگر به این مشکل برخورده اید، گام های `۱.۱`، `۱.۲` و `۱.۳` را دنبال کنید.
|
||||
|
||||
<br>
|
||||
|
||||
####۱.۱. نصب `XCode's command line tools`
|
||||
|
||||
دستور زیر را در `terminal` وادر کنید و دکمه `return` را بفشارید.
|
||||
```shell
|
||||
xcode-select --install
|
||||
```
|
||||
|
||||
<br>
|
||||
|
||||
####۱.۲. نصب `homebrew`
|
||||
|
||||
دستور زیر را در `terminal` وارد کنید و دکمه `return` را بفشارید.
|
||||
```shell
|
||||
curl -fsSL -o install.sh https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh
|
||||
```
|
||||
|
||||
<br>
|
||||
|
||||
####۱.۳. حال میتوانید با دستوری که پیشتر گفتیم، `CMake` را نصب کنید.
|
||||
|
||||
<br>
|
||||
|
||||
###۲. `Ninja`
|
||||
|
||||
برای نصب `Ninja` دستور زیر را در `terminal` وارد کنید و دکمه `return` را بفشارید.
|
||||
```shell
|
||||
sudo port install ninja
|
||||
```
|
||||
اگر با خطای `sudo: port: command not found` روبهرو شدید، به این معنی است که `MacPorts` روی دستگاه شما نصب نیست. نسخه `MacPorts` متناسب با نسخه `macOs` خود را بارگری و نصب کنید. سپس بار دیگر، دستور نصب `Ninja` را در `terminal` وارد کرده و دکمه `return` را بفشارید.
|
||||
|
||||
<br>
|
||||
|
||||
###۳. `npm`
|
||||
|
||||
برای نصب `npm` دستور زیر را در `terminal` وارد کنید و دکمه `return` را بفشارید.
|
||||
```shell
|
||||
brew install npm
|
||||
```
|
||||
|
||||
<br>
|
||||
|
||||
###۴. `qtbase`
|
||||
|
||||
برای نصب `qtbase` دستور زیر را در `terminal` وارد کنید و دکمه `return` را بفشارید.
|
||||
```shell
|
||||
sudo port install qt5-qtbase
|
||||
```
|
||||
|
||||
<br>
|
||||
|
||||
###۵. `qtsvg`
|
||||
|
||||
برای نصب `qtsvg` دستور زیر را در `terminal` وارد کنید و دکمه `return` را بفشارید.
|
||||
```shell
|
||||
sudo port install qt5-qtsvg
|
||||
```
|
||||
|
||||
<br>
|
||||
|
||||
###۶. `qttools`
|
||||
|
||||
برای نصب `qttools` دستور زیر را در `terminal` وارد کنید و دکمه `return` را بفشارید.
|
||||
```shell
|
||||
sudo port install qt5-qttools
|
||||
```
|
||||
|
||||
<br>
|
||||
|
||||
###۷. `appdmg`
|
||||
|
||||
برای نصب `appdmg` دستور زیر را در `terminal` وارد کنید و دکمه `return` را بفشارید.
|
||||
```shell
|
||||
sudo npm install -g appdmg
|
||||
```
|
||||
|
||||
<br>
|
||||
|
||||
## C++
|
||||
|
||||
### وابستگیهای C و ++C را کامپایل و نصب کنید.
|
||||
|
||||
دستور زیر را در `terminal` وارد کرده و دکمه `return` را بفشارید.
|
||||
|
||||
```shell
|
||||
./libs/build_deps_all.sh
|
||||
```
|
||||
|
||||
<br>
|
||||
|
||||
### آنتولوژی را کامپایل کنید.
|
||||
|
||||
دستور زیر را در `terminal` وارد کرده و دکمه `return` را بفشارید.
|
||||
```shell
|
||||
mkdir build
|
||||
cd build
|
||||
cmake -GNinja -DCMAKE_BUILD_TYPE=Release -DNKR_PACKAGE_MACOS=1 ..
|
||||
ninja
|
||||
```
|
||||
|
||||
<br>
|
||||
|
||||
## هسته نرم افزار
|
||||
|
||||
### هسته نرم افزار را کامپایل کنید.
|
||||
|
||||
چگونگی کامپایل کردن هسته نرم افزار را [اینجا ](./Build_Core_fa.md)بخوانید.
|
||||
|
||||
<br>
|
||||
|
||||
### جایگذاری هسته
|
||||
|
||||
فایل کامپایل شده `nekoray_core` و `nekobox_core` را در مسیر زیر کپی کنید.
|
||||
`build/nekoray.app/Contents/MacOS`
|
||||
|
||||
<br>
|
||||
|
||||
## فایلهای جغرافی را تهیه کنید. (اختیاری)
|
||||
|
||||
اگر مایلید، با اجرای دستورهای زیر در `Terminal` فایل های جغرافی را تهیه کنید.
|
||||
|
||||
```shell
|
||||
curl -Lso build/nekoray.app/Contents/MacOS/geoip.dat "https://github.com/Loyalsoldier/v2ray-rules-dat/releases/latest/download/geoip.dat"
|
||||
curl -Lso build/nekoray.app/Contents/MacOS/geosite.dat "https://github.com/v2fly/domain-list-community/releases/latest/download/dlc.dat"
|
||||
curl -Lso build/nekoray.app/Contents/MacOS/geoip.db "https://github.com/SagerNet/sing-geoip/releases/latest/download/geoip.db"
|
||||
curl -Lso build/nekoray.app/Contents/MacOS/geosite.db "https://github.com/SagerNet/sing-geosite/releases/latest/download/geosite.db"
|
||||
```
|
||||
<br>
|
||||
|
||||
## پایان کار
|
||||
|
||||
فایل اجرایی `Nekoray` در مسیر زیر قرار دارد. میتوانید آن را در مسیر دلخواه کپی کنید.
|
||||
|
||||
`مسیر پروژه Nekoray/build`
|
||||
@ -55,9 +55,9 @@ cmake -GNinja -DCMAKE_BUILD_TYPE=Release -DCMAKE_PREFIX_PATH=D:/path/to/qt/5.15.
|
||||
ninja
|
||||
```
|
||||
|
||||
编译完成后得到 `nekoray.exe`
|
||||
编译完成后得到 `nekobox.exe`
|
||||
|
||||
最后运行 `windeployqt nekoray.exe` 自动复制所需 DLL 等文件到当前目录
|
||||
最后运行 `windeployqt nekobox.exe` 自动复制所需 DLL 等文件到当前目录
|
||||
|
||||
### Go 部分编译
|
||||
|
||||
|
||||
106
docs/HookJS.md
106
docs/HookJS.md
@ -1,106 +0,0 @@
|
||||
# hook.js 使用
|
||||
## 如何启用
|
||||
|
||||
1. 打开 `基本设置 - 安全 - 启用 hook.js 功能`
|
||||
2. js 代码请放置于 `config/hook.nekoray.js` 或 `config/hook.nekobox.js`
|
||||
|
||||
## 技术信息
|
||||
|
||||
* JS Engine: QuickJS ES2020
|
||||
* 提供的接口:如下面代码所示
|
||||
|
||||
## 示例代码 (typescript)
|
||||
|
||||
```ts
|
||||
const globalAny: any = globalThis
|
||||
|
||||
// 目前提供的方法
|
||||
interface nekoray_in {
|
||||
log(...a: any): void
|
||||
}
|
||||
|
||||
// 目前提供的 hook 点
|
||||
interface nekoray_hook {
|
||||
hook_core_config(config: string): string
|
||||
hook_tun_config(config: string): string
|
||||
hook_tun_script(script: string): string
|
||||
hook_import(content: string): string
|
||||
}
|
||||
|
||||
class my_hook implements nekoray_hook {
|
||||
private nekoray = globalAny.nekoray as nekoray_in
|
||||
|
||||
hook_core_config(config: string): string {
|
||||
var json = JSON.parse(config)
|
||||
var my_rule = {
|
||||
"geosite": "cn",
|
||||
"server": "dns-direct",
|
||||
"disable_cache": true
|
||||
}
|
||||
json["dns"]["rules"].push(my_rule)
|
||||
return JSON.stringify(json)
|
||||
}
|
||||
|
||||
hook_tun_config(config: string): string {
|
||||
return config // 返回输入,表示不修改
|
||||
}
|
||||
|
||||
hook_tun_script(script: string): string {
|
||||
console.log("Script") // 输出到 stdout
|
||||
this.nekoray.log("Script:", script) // 输出到日志
|
||||
return script
|
||||
}
|
||||
|
||||
hook_import(content: string): string {
|
||||
var newContent: Array<any> = []
|
||||
content.split("\n").forEach((line: any) => {
|
||||
if (line.startsWith("vmess://")) {
|
||||
newContent.push(line)
|
||||
}
|
||||
})
|
||||
return newContent.join("\n")
|
||||
}
|
||||
}
|
||||
|
||||
globalAny.hook = new my_hook
|
||||
```
|
||||
|
||||
## 示例代码 (javascript)
|
||||
|
||||
```js
|
||||
var globalAny = globalThis;
|
||||
var my_hook = /** @class */ (function () {
|
||||
function my_hook() {
|
||||
this.nekoray = globalAny.nekoray;
|
||||
}
|
||||
my_hook.prototype.hook_core_config = function (config) {
|
||||
var json = JSON.parse(config);
|
||||
var my_rule = {
|
||||
"geosite": "cn",
|
||||
"server": "dns-direct",
|
||||
"disable_cache": true
|
||||
};
|
||||
json["dns"]["rules"].push(my_rule);
|
||||
return JSON.stringify(json);
|
||||
};
|
||||
my_hook.prototype.hook_tun_config = function (config) {
|
||||
return config; // 返回输入,表示不修改
|
||||
};
|
||||
my_hook.prototype.hook_tun_script = function (script) {
|
||||
console.log("Script"); // 输出到 stdout
|
||||
this.nekoray.log("Script:", script); // 输出到日志
|
||||
return script;
|
||||
};
|
||||
my_hook.prototype.hook_import = function (content) {
|
||||
var newContent = [];
|
||||
content.split("\n").forEach(function (line) {
|
||||
if (line.startsWith("vmess://")) {
|
||||
newContent.push(line);
|
||||
}
|
||||
});
|
||||
return newContent.join("\n");
|
||||
};
|
||||
return my_hook;
|
||||
}());
|
||||
globalAny.hook = new my_hook;
|
||||
```
|
||||
@ -4,4 +4,3 @@
|
||||
|
||||
1. Build GUI: `Build_*.md`
|
||||
2. Build Core: `Build_Core.md`
|
||||
3. Hook.js usage: `HookJS.md`
|
||||
|
||||
@ -38,7 +38,7 @@ namespace NekoGui_fmt {
|
||||
}
|
||||
|
||||
QString AbstractBean::DisplayTypeAndName() {
|
||||
return QString("[%1] %2").arg(DisplayType(), DisplayName());
|
||||
return QStringLiteral("[%1] %2").arg(DisplayType(), DisplayName());
|
||||
}
|
||||
|
||||
void AbstractBean::ResolveDomainToIP(const std::function<void()> &onFinished) {
|
||||
|
||||
@ -59,8 +59,6 @@ namespace NekoGui_fmt {
|
||||
|
||||
virtual int NeedExternal(bool isFirstProfile) { return 0; };
|
||||
|
||||
virtual CoreObjOutboundBuildResult BuildCoreObjV2Ray() { return {}; };
|
||||
|
||||
virtual CoreObjOutboundBuildResult BuildCoreObjSingBox() { return {}; };
|
||||
|
||||
virtual ExternalBuildResult BuildExternal(int mapping_port, int socks_port, int external_stat) { return {}; };
|
||||
|
||||
@ -28,6 +28,9 @@ namespace NekoGui_fmt {
|
||||
if (!host.isEmpty()) transport["host"] = QList2QJsonArray(host.split(","));
|
||||
} else if (network == "grpc") {
|
||||
if (!path.isEmpty()) transport["service_name"] = path;
|
||||
} else if (network == "httpupgrade") {
|
||||
if (!path.isEmpty()) transport["path"] = path;
|
||||
if (!host.isEmpty()) transport["host"] = host;
|
||||
}
|
||||
outbound->insert("transport", transport);
|
||||
} else if (header_type == "http") {
|
||||
@ -188,23 +191,16 @@ namespace NekoGui_fmt {
|
||||
{"tls", coreTlsObj},
|
||||
};
|
||||
|
||||
if (proxy_type == proxy_Hysteria) {
|
||||
outbound["type"] = "hysteria";
|
||||
outbound["obfs"] = obfsPassword;
|
||||
outbound["disable_mtu_discovery"] = disableMtuDiscovery;
|
||||
outbound["recv_window"] = streamReceiveWindow;
|
||||
outbound["recv_window_conn"] = connectionReceiveWindow;
|
||||
outbound["up_mbps"] = uploadMbps;
|
||||
outbound["down_mbps"] = downloadMbps;
|
||||
|
||||
if (!hopPort.trimmed().isEmpty()) outbound["hop_ports"] = hopPort;
|
||||
if (authPayloadType == hysteria_auth_base64) outbound["auth"] = authPayload;
|
||||
if (authPayloadType == hysteria_auth_string) outbound["auth_str"] = authPayload;
|
||||
} else if (proxy_type == proxy_Hysteria2) {
|
||||
if (proxy_type == proxy_Hysteria2) {
|
||||
outbound["type"] = "hysteria2";
|
||||
outbound["password"] = password;
|
||||
outbound["up_mbps"] = uploadMbps;
|
||||
outbound["down_mbps"] = downloadMbps;
|
||||
|
||||
if (!hopPort.trimmed().isEmpty()) {
|
||||
outbound["hop_ports"] = hopPort;
|
||||
outbound["hop_interval"] = hopInterval;
|
||||
}
|
||||
if (!obfsPassword.isEmpty()) {
|
||||
outbound["obfs"] = QJsonObject{
|
||||
{"type", "salamander"},
|
||||
|
||||
@ -1,211 +0,0 @@
|
||||
#include "db/ProxyEntity.hpp"
|
||||
#include "fmt/includes.h"
|
||||
|
||||
#define MAKE_SETTINGS_STREAM_SETTINGS \
|
||||
outbound["settings"] = settings; \
|
||||
auto streamSettings = stream->BuildStreamSettingsV2Ray(); \
|
||||
outbound["streamSettings"] = streamSettings;
|
||||
|
||||
namespace NekoGui_fmt {
|
||||
QJsonObject V2rayStreamSettings::BuildStreamSettingsV2Ray() {
|
||||
QJsonObject streamSettings{{"network", network}};
|
||||
|
||||
if (network == "ws") {
|
||||
QJsonObject ws;
|
||||
if (!host.isEmpty()) ws["headers"] = QJsonObject{{"Host", host}};
|
||||
// ws path & ed
|
||||
if (!path.isEmpty()) ws["path"] = path;
|
||||
streamSettings["wsSettings"] = ws;
|
||||
} else if (network == "http") {
|
||||
QJsonObject http;
|
||||
if (!path.isEmpty()) http["path"] = path;
|
||||
if (!host.isEmpty()) http["host"] = QList2QJsonArray(host.split(","));
|
||||
streamSettings["httpSettings"] = http;
|
||||
} else if (network == "grpc") {
|
||||
QJsonObject grpc;
|
||||
if (!path.isEmpty()) grpc["serviceName"] = path;
|
||||
streamSettings["grpcSettings"] = grpc;
|
||||
} else if (network == "quic") {
|
||||
QJsonObject quic;
|
||||
if (!header_type.isEmpty()) quic["header"] = QJsonObject{{"type", header_type}};
|
||||
if (!path.isEmpty()) quic["key"] = path;
|
||||
if (!host.isEmpty()) quic["security"] = host;
|
||||
streamSettings["quicSettings"] = quic;
|
||||
} else if (network == "tcp" && !header_type.isEmpty()) {
|
||||
QJsonObject header{{"type", header_type}};
|
||||
if (header_type == "http") {
|
||||
header["request"] = QJsonObject{
|
||||
{"path", QList2QJsonArray(path.split(","))},
|
||||
{"headers", QJsonObject{{"Host", QList2QJsonArray(host.split(","))}}},
|
||||
};
|
||||
}
|
||||
streamSettings["tcpSettings"] = QJsonObject{{"header", header}};
|
||||
}
|
||||
|
||||
if (security == "tls") {
|
||||
QJsonObject tls;
|
||||
if (!utlsFingerprint.isEmpty()) tls["fingerprint"] = utlsFingerprint;
|
||||
if (!sni.trimmed().isEmpty()) tls["serverName"] = sni;
|
||||
if (reality_pbk.trimmed().isEmpty()) {
|
||||
if (allow_insecure || NekoGui::dataStore->skip_cert) tls["allowInsecure"] = true;
|
||||
if (!alpn.trimmed().isEmpty()) tls["alpn"] = QList2QJsonArray(alpn.split(","));
|
||||
if (!certificate.trimmed().isEmpty()) {
|
||||
tls["disableSystemRoot"] = true;
|
||||
tls["certificates"] = QJsonArray{
|
||||
QJsonObject{
|
||||
{"usage", "verify"},
|
||||
{"certificate", QList2QJsonArray(SplitLines(certificate.trimmed()))},
|
||||
},
|
||||
};
|
||||
}
|
||||
streamSettings["tlsSettings"] = tls;
|
||||
streamSettings["security"] = "tls";
|
||||
} else {
|
||||
tls["publicKey"] = reality_pbk;
|
||||
tls["shortId"] = reality_sid;
|
||||
tls["spiderX"] = reality_spx;
|
||||
if (utlsFingerprint.isEmpty()) tls["fingerprint"] = "chrome";
|
||||
streamSettings["realitySettings"] = tls;
|
||||
streamSettings["security"] = "reality";
|
||||
}
|
||||
}
|
||||
|
||||
return streamSettings;
|
||||
}
|
||||
|
||||
CoreObjOutboundBuildResult SocksHttpBean::BuildCoreObjV2Ray() {
|
||||
CoreObjOutboundBuildResult result;
|
||||
|
||||
QJsonObject outbound;
|
||||
outbound["protocol"] = socks_http_type == type_HTTP ? "http" : "socks";
|
||||
|
||||
QJsonObject settings;
|
||||
QJsonArray servers;
|
||||
QJsonObject server;
|
||||
|
||||
server["address"] = serverAddress;
|
||||
server["port"] = serverPort;
|
||||
|
||||
QJsonArray users;
|
||||
QJsonObject user;
|
||||
user["user"] = username;
|
||||
user["pass"] = password;
|
||||
users.push_back(user);
|
||||
if (!username.isEmpty() && !password.isEmpty()) server["users"] = users;
|
||||
|
||||
servers.push_back(server);
|
||||
settings["servers"] = servers;
|
||||
|
||||
MAKE_SETTINGS_STREAM_SETTINGS
|
||||
|
||||
result.outbound = outbound;
|
||||
return result;
|
||||
}
|
||||
|
||||
CoreObjOutboundBuildResult ShadowSocksBean::BuildCoreObjV2Ray() {
|
||||
CoreObjOutboundBuildResult result;
|
||||
|
||||
QJsonObject outbound{{"protocol", "shadowsocks"}};
|
||||
|
||||
QJsonObject settings;
|
||||
QJsonArray servers;
|
||||
QJsonObject server;
|
||||
|
||||
server["address"] = serverAddress;
|
||||
server["port"] = serverPort;
|
||||
server["method"] = method;
|
||||
server["password"] = password;
|
||||
|
||||
if (uot != 0) {
|
||||
server["uot"] = true;
|
||||
server["UoTVersion"] = uot;
|
||||
} else {
|
||||
server["uot"] = false;
|
||||
}
|
||||
|
||||
servers.push_back(server);
|
||||
settings["servers"] = servers;
|
||||
|
||||
if (!plugin.trimmed().isEmpty()) {
|
||||
settings["plugin"] = SubStrBefore(plugin, ";");
|
||||
settings["pluginOpts"] = SubStrAfter(plugin, ";");
|
||||
}
|
||||
|
||||
MAKE_SETTINGS_STREAM_SETTINGS
|
||||
|
||||
result.outbound = outbound;
|
||||
return result;
|
||||
}
|
||||
|
||||
CoreObjOutboundBuildResult VMessBean::BuildCoreObjV2Ray() {
|
||||
CoreObjOutboundBuildResult result;
|
||||
QJsonObject outbound{{"protocol", "vmess"}};
|
||||
|
||||
QJsonObject settings{
|
||||
{"vnext", QJsonArray{
|
||||
QJsonObject{
|
||||
{"address", serverAddress},
|
||||
{"port", serverPort},
|
||||
{"users", QJsonArray{
|
||||
QJsonObject{
|
||||
{"id", uuid.trimmed()},
|
||||
{"alterId", aid},
|
||||
{"security", security},
|
||||
}}},
|
||||
}}}};
|
||||
|
||||
MAKE_SETTINGS_STREAM_SETTINGS
|
||||
|
||||
result.outbound = outbound;
|
||||
return result;
|
||||
}
|
||||
|
||||
CoreObjOutboundBuildResult TrojanVLESSBean::BuildCoreObjV2Ray() {
|
||||
CoreObjOutboundBuildResult result;
|
||||
QJsonObject outbound{
|
||||
{"protocol", proxy_type == proxy_VLESS ? "vless" : "trojan"},
|
||||
};
|
||||
|
||||
QJsonObject settings;
|
||||
if (proxy_type == proxy_VLESS) {
|
||||
if (flow == "none") {
|
||||
flow = "";
|
||||
}
|
||||
settings = QJsonObject{
|
||||
{"vnext", QJsonArray{
|
||||
QJsonObject{
|
||||
{"address", serverAddress},
|
||||
{"port", serverPort},
|
||||
{"users", QJsonArray{
|
||||
QJsonObject{
|
||||
{"id", password.trimmed()},
|
||||
{"encryption", "none"},
|
||||
{"flow", flow},
|
||||
}}},
|
||||
}}}};
|
||||
} else {
|
||||
settings = QJsonObject{
|
||||
{"servers", QJsonArray{
|
||||
QJsonObject{
|
||||
{"address", serverAddress},
|
||||
{"port", serverPort},
|
||||
{"password", password},
|
||||
}}}};
|
||||
}
|
||||
|
||||
MAKE_SETTINGS_STREAM_SETTINGS
|
||||
|
||||
result.outbound = outbound;
|
||||
return result;
|
||||
}
|
||||
|
||||
CoreObjOutboundBuildResult CustomBean::BuildCoreObjV2Ray() {
|
||||
CoreObjOutboundBuildResult result;
|
||||
|
||||
if (core == "internal") {
|
||||
result.outbound = QString2QJsonObject(config_simple);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
} // namespace NekoGui_fmt
|
||||
@ -9,7 +9,7 @@
|
||||
#define WriteTempFile(fn, data) \
|
||||
QDir dir; \
|
||||
if (!dir.exists("temp")) dir.mkdir("temp"); \
|
||||
QFile f(QString("temp/") + fn); \
|
||||
QFile f(QStringLiteral("temp/") + fn); \
|
||||
bool ok = f.open(QIODevice::WriteOnly | QIODevice::Truncate); \
|
||||
if (ok) { \
|
||||
f.write(data); \
|
||||
@ -36,54 +36,26 @@ namespace NekoGui_fmt {
|
||||
}
|
||||
|
||||
int QUICBean::NeedExternal(bool isFirstProfile) {
|
||||
auto hysteriaCore = [=] {
|
||||
auto extCore = [=] {
|
||||
if (isFirstProfile) {
|
||||
if (NekoGui::dataStore->spmode_vpn && hyProtocol != hysteria_protocol_facktcp && hopPort.trimmed().isEmpty()) {
|
||||
if (NekoGui::dataStore->spmode_vpn && hopPort.trimmed().isEmpty()) {
|
||||
return 1;
|
||||
}
|
||||
return 2;
|
||||
} else {
|
||||
if (hyProtocol == hysteria_protocol_facktcp || !hopPort.trimmed().isEmpty()) {
|
||||
if (!hopPort.trimmed().isEmpty()) {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
};
|
||||
|
||||
auto hysteria2Core = [=] {
|
||||
if (isFirstProfile) {
|
||||
if (NekoGui::dataStore->spmode_vpn || !hopPort.trimmed().isEmpty()) {
|
||||
return 1;
|
||||
}
|
||||
return 2;
|
||||
}
|
||||
return 1;
|
||||
};
|
||||
|
||||
auto tuicCore = [=] {
|
||||
if (isFirstProfile) {
|
||||
if (NekoGui::dataStore->spmode_vpn) {
|
||||
return 1;
|
||||
}
|
||||
return 2;
|
||||
}
|
||||
return 1;
|
||||
};
|
||||
|
||||
if (IS_NEKO_BOX) {
|
||||
if (!forceExternal && (proxy_type == proxy_TUIC || hyProtocol == hysteria_protocol_udp)) {
|
||||
// sing-box support
|
||||
return 0;
|
||||
} else {
|
||||
// hysteria core support
|
||||
return hysteriaCore();
|
||||
}
|
||||
} else if (proxy_type == proxy_TUIC) {
|
||||
return tuicCore();
|
||||
} else if (proxy_type == proxy_Hysteria2) {
|
||||
return hysteria2Core();
|
||||
if (!forceExternal) {
|
||||
// sing-box support
|
||||
return 0;
|
||||
} else {
|
||||
return hysteriaCore();
|
||||
// external core support
|
||||
return extCore();
|
||||
}
|
||||
}
|
||||
|
||||
@ -189,7 +161,7 @@ namespace NekoGui_fmt {
|
||||
QJsonObject transport;
|
||||
transport["type"] = "udp";
|
||||
transport["udp"] = QJsonObject{
|
||||
{"hopInterval", hopInterval},
|
||||
{"hopInterval", QString::number(hopInterval) + "s"},
|
||||
};
|
||||
config["transport"] = transport;
|
||||
|
||||
@ -241,68 +213,11 @@ namespace NekoGui_fmt {
|
||||
WriteTempFile("hysteria2_" + GetRandomString(10) + ".json", result.config_export.toUtf8());
|
||||
result.arguments = QStringList{"-c", TempFile};
|
||||
|
||||
return result;
|
||||
|
||||
} else { // Hysteria
|
||||
ExternalBuildResult result{NekoGui::dataStore->extraCore->Get("hysteria")};
|
||||
|
||||
QJsonObject config;
|
||||
|
||||
// determine server format
|
||||
auto is_direct = external_stat == 2;
|
||||
auto sniGen = sni;
|
||||
if (sni.isEmpty() && !IsIpAddress(serverAddress)) sniGen = serverAddress;
|
||||
|
||||
auto server = serverAddress;
|
||||
if (!hopPort.trimmed().isEmpty()) {
|
||||
server = WrapIPV6Host(server) + ":" + hopPort;
|
||||
} else {
|
||||
server = WrapIPV6Host(server) + ":" + Int2String(serverPort);
|
||||
}
|
||||
config["server"] = is_direct ? server : "127.0.0.1:" + Int2String(mapping_port);
|
||||
|
||||
// listen
|
||||
config["socks5"] = QJsonObject{
|
||||
{"listen", "127.0.0.1:" + Int2String(socks_port)},
|
||||
};
|
||||
|
||||
// misc
|
||||
|
||||
config["retry"] = 5;
|
||||
config["fast_open"] = true;
|
||||
config["lazy_start"] = true;
|
||||
config["obfs"] = obfsPassword;
|
||||
config["up_mbps"] = uploadMbps;
|
||||
config["down_mbps"] = downloadMbps;
|
||||
|
||||
if (authPayloadType == hysteria_auth_base64) config["auth"] = authPayload;
|
||||
if (authPayloadType == hysteria_auth_string) config["auth_str"] = authPayload;
|
||||
|
||||
if (hyProtocol == hysteria_protocol_facktcp) config["protocol"] = "faketcp";
|
||||
if (hyProtocol == hysteria_protocol_wechat_video) config["protocol"] = "wechat-video";
|
||||
|
||||
if (!sniGen.isEmpty()) config["server_name"] = sniGen;
|
||||
if (!alpn.isEmpty()) config["alpn"] = alpn;
|
||||
|
||||
if (!caText.trimmed().isEmpty()) {
|
||||
WriteTempFile("hysteria_" + GetRandomString(10) + ".crt", caText.toUtf8());
|
||||
config["ca"] = TempFile;
|
||||
}
|
||||
|
||||
if (allowInsecure) config["insecure"] = true;
|
||||
if (streamReceiveWindow > 0) config["recv_window_conn"] = streamReceiveWindow;
|
||||
if (connectionReceiveWindow > 0) config["recv_window"] = connectionReceiveWindow;
|
||||
if (disableMtuDiscovery) config["disable_mtu_discovery"] = true;
|
||||
config["hop_interval"] = hopInterval;
|
||||
|
||||
//
|
||||
|
||||
result.config_export = QJsonObject2QString(config, false);
|
||||
WriteTempFile("hysteria_" + GetRandomString(10) + ".json", result.config_export.toUtf8());
|
||||
result.arguments = QStringList{"--no-check", "-c", TempFile};
|
||||
|
||||
return result;
|
||||
}
|
||||
ExternalBuildResult e;
|
||||
e.error = "unknown type";
|
||||
return e;
|
||||
}
|
||||
|
||||
ExternalBuildResult CustomBean::BuildExternal(int mapping_port, int socks_port, int external_stat) {
|
||||
|
||||
@ -13,7 +13,7 @@ namespace NekoGui_fmt {
|
||||
url.setScheme("http");
|
||||
}
|
||||
} else {
|
||||
url.setScheme(QString("socks%1").arg(socks_http_type));
|
||||
url.setScheme(QStringLiteral("socks%1").arg(socks_http_type));
|
||||
}
|
||||
if (!name.isEmpty()) url.setFragment(name);
|
||||
if (!username.isEmpty()) url.setUserName(username);
|
||||
@ -51,7 +51,7 @@ namespace NekoGui_fmt {
|
||||
// type
|
||||
query.addQueryItem("type", stream->network);
|
||||
|
||||
if (stream->network == "ws" || stream->network == "http") {
|
||||
if (stream->network == "ws" || stream->network == "http" || stream->network == "httpupgrade") {
|
||||
if (!stream->path.isEmpty()) query.addQueryItem("path", stream->path);
|
||||
if (!stream->host.isEmpty()) query.addQueryItem("host", stream->host);
|
||||
} else if (stream->network == "grpc") {
|
||||
@ -152,7 +152,7 @@ namespace NekoGui_fmt {
|
||||
// type
|
||||
query.addQueryItem("type", stream->network);
|
||||
|
||||
if (stream->network == "ws" || stream->network == "http") {
|
||||
if (stream->network == "ws" || stream->network == "http" || stream->network == "httpupgrade") {
|
||||
if (!stream->path.isEmpty()) query.addQueryItem("path", stream->path);
|
||||
if (!stream->host.isEmpty()) query.addQueryItem("host", stream->host);
|
||||
} else if (stream->network == "grpc") {
|
||||
@ -182,29 +182,7 @@ namespace NekoGui_fmt {
|
||||
|
||||
QString QUICBean::ToShareLink() {
|
||||
QUrl url;
|
||||
if (proxy_type == proxy_Hysteria) {
|
||||
url.setScheme("hysteria");
|
||||
url.setHost(serverAddress);
|
||||
url.setPort(serverPort);
|
||||
QUrlQuery q;
|
||||
q.addQueryItem("upmbps", Int2String(uploadMbps));
|
||||
q.addQueryItem("downmbps", Int2String(downloadMbps));
|
||||
if (!obfsPassword.isEmpty()) {
|
||||
q.addQueryItem("obfs", "xplus");
|
||||
q.addQueryItem("obfsParam", obfsPassword);
|
||||
}
|
||||
if (authPayloadType == hysteria_auth_string) q.addQueryItem("auth", authPayload);
|
||||
if (hyProtocol == hysteria_protocol_facktcp) q.addQueryItem("protocol", "faketcp");
|
||||
if (hyProtocol == hysteria_protocol_wechat_video) q.addQueryItem("protocol", "wechat-video");
|
||||
if (!hopPort.trimmed().isEmpty()) q.addQueryItem("mport", hopPort);
|
||||
if (allowInsecure) q.addQueryItem("insecure", "1");
|
||||
if (!sni.isEmpty()) q.addQueryItem("peer", sni);
|
||||
if (!alpn.isEmpty()) q.addQueryItem("alpn", alpn);
|
||||
if (connectionReceiveWindow > 0) q.addQueryItem("recv_window", Int2String(connectionReceiveWindow));
|
||||
if (streamReceiveWindow > 0) q.addQueryItem("recv_window_conn", Int2String(streamReceiveWindow));
|
||||
if (!q.isEmpty()) url.setQuery(q);
|
||||
if (!name.isEmpty()) url.setFragment(name);
|
||||
} else if (proxy_type == proxy_TUIC) {
|
||||
if (proxy_type == proxy_TUIC) {
|
||||
url.setScheme("tuic");
|
||||
url.setUserName(uuid);
|
||||
url.setPassword(password);
|
||||
@ -235,7 +213,7 @@ namespace NekoGui_fmt {
|
||||
q.addQueryItem("obfs", "salamander");
|
||||
q.addQueryItem("obfs-password", obfsPassword);
|
||||
}
|
||||
// if (!hopPort.trimmed().isEmpty()) q.addQueryItem("mport", hopPort);
|
||||
if (!hopPort.trimmed().isEmpty()) q.addQueryItem("mport", hopPort);
|
||||
if (allowInsecure) q.addQueryItem("insecure", "1");
|
||||
if (!sni.isEmpty()) q.addQueryItem("sni", sni);
|
||||
if (!q.isEmpty()) url.setQuery(q);
|
||||
|
||||
@ -24,7 +24,7 @@ namespace NekoGui_fmt {
|
||||
QString DisplayType() override {
|
||||
if (core == "internal") {
|
||||
auto obj = QString2QJsonObject(config_simple);
|
||||
return obj[IS_NEKO_BOX ? "type" : "protocol"].toString();
|
||||
return obj["type"].toString();
|
||||
} else if (core == "internal-full") {
|
||||
return software_core_name + " config";
|
||||
}
|
||||
@ -36,11 +36,7 @@ namespace NekoGui_fmt {
|
||||
QString DisplayAddress() override {
|
||||
if (core == "internal") {
|
||||
auto obj = QString2QJsonObject(config_simple);
|
||||
if (IS_NEKO_BOX) {
|
||||
return ::DisplayAddress(obj["server"].toString(), obj["server_port"].toInt());
|
||||
} else {
|
||||
return {};
|
||||
}
|
||||
return ::DisplayAddress(obj["server"].toString(), obj["server_port"].toInt());
|
||||
} else if (core == "internal-full") {
|
||||
return {};
|
||||
}
|
||||
@ -52,7 +48,5 @@ namespace NekoGui_fmt {
|
||||
ExternalBuildResult BuildExternal(int mapping_port, int socks_port, int external_stat) override;
|
||||
|
||||
CoreObjOutboundBuildResult BuildCoreObjSingBox() override;
|
||||
|
||||
CoreObjOutboundBuildResult BuildCoreObjV2Ray() override;
|
||||
};
|
||||
} // namespace NekoGui_fmt
|
||||
@ -54,7 +54,13 @@ namespace NekoGui_fmt {
|
||||
if (serverPort == -1) serverPort = 443;
|
||||
|
||||
// security
|
||||
stream->network = GetQueryValue(query, "type", "tcp");
|
||||
|
||||
auto type = GetQueryValue(query, "type", "tcp");
|
||||
if (type == "h2") {
|
||||
type = "http";
|
||||
}
|
||||
stream->network = type;
|
||||
|
||||
if (proxy_type == proxy_Trojan) {
|
||||
stream->security = GetQueryValue(query, "security", "tls").replace("reality", "tls").replace("none", "");
|
||||
} else {
|
||||
@ -81,6 +87,9 @@ namespace NekoGui_fmt {
|
||||
} else if (stream->network == "http") {
|
||||
stream->path = GetQueryValue(query, "path", "");
|
||||
stream->host = GetQueryValue(query, "host", "").replace("|", ",");
|
||||
} else if (stream->network == "httpupgrade") {
|
||||
stream->path = GetQueryValue(query, "path", "");
|
||||
stream->host = GetQueryValue(query, "host", "");
|
||||
} else if (stream->network == "grpc") {
|
||||
stream->path = GetQueryValue(query, "serviceName", "");
|
||||
} else if (stream->network == "tcp") {
|
||||
@ -154,7 +163,12 @@ namespace NekoGui_fmt {
|
||||
stream->sni = objN["sni"].toString();
|
||||
stream->header_type = objN["type"].toString();
|
||||
auto net = objN["net"].toString();
|
||||
if (!net.isEmpty()) stream->network = net;
|
||||
if (!net.isEmpty()) {
|
||||
if (net == "h2") {
|
||||
net = "http";
|
||||
}
|
||||
stream->network = net;
|
||||
}
|
||||
auto scy = objN["scy"].toString();
|
||||
if (!scy.isEmpty()) security = scy;
|
||||
// TLS (XTLS?)
|
||||
@ -177,7 +191,11 @@ namespace NekoGui_fmt {
|
||||
security = GetQueryValue(query, "encryption", "auto");
|
||||
|
||||
// security
|
||||
stream->network = GetQueryValue(query, "type", "tcp");
|
||||
auto type = GetQueryValue(query, "type", "tcp");
|
||||
if (type == "h2") {
|
||||
type = "http";
|
||||
}
|
||||
stream->network = type;
|
||||
stream->security = GetQueryValue(query, "security", "tls").replace("reality", "tls");
|
||||
auto sni1 = GetQueryValue(query, "sni");
|
||||
auto sni2 = GetQueryValue(query, "peer");
|
||||
@ -199,6 +217,9 @@ namespace NekoGui_fmt {
|
||||
} else if (stream->network == "http") {
|
||||
stream->path = GetQueryValue(query, "path", "");
|
||||
stream->host = GetQueryValue(query, "host", "").replace("|", ",");
|
||||
} else if (stream->network == "httpupgrade") {
|
||||
stream->path = GetQueryValue(query, "path", "");
|
||||
stream->host = GetQueryValue(query, "host", "");
|
||||
} else if (stream->network == "grpc") {
|
||||
stream->path = GetQueryValue(query, "serviceName", "");
|
||||
} else if (stream->network == "tcp") {
|
||||
@ -235,37 +256,7 @@ namespace NekoGui_fmt {
|
||||
auto query = QUrlQuery(url.query());
|
||||
if (url.host().isEmpty() || url.port() == -1) return false;
|
||||
|
||||
if (url.scheme() == "hysteria") {
|
||||
// https://hysteria.network/docs/uri-scheme/
|
||||
if (!query.hasQueryItem("upmbps") || !query.hasQueryItem("downmbps")) return false;
|
||||
|
||||
name = url.fragment(QUrl::FullyDecoded);
|
||||
serverAddress = url.host();
|
||||
serverPort = url.port();
|
||||
hopPort = query.queryItemValue("mport");
|
||||
obfsPassword = query.queryItemValue("obfsParam");
|
||||
allowInsecure = QStringList{"1", "true"}.contains(query.queryItemValue("insecure"));
|
||||
uploadMbps = query.queryItemValue("upmbps").toInt();
|
||||
downloadMbps = query.queryItemValue("downmbps").toInt();
|
||||
|
||||
auto protocolStr = (query.hasQueryItem("protocol") ? query.queryItemValue("protocol") : "udp").toLower();
|
||||
if (protocolStr == "faketcp") {
|
||||
hyProtocol = NekoGui_fmt::QUICBean::hysteria_protocol_facktcp;
|
||||
} else if (protocolStr.startsWith("wechat")) {
|
||||
hyProtocol = NekoGui_fmt::QUICBean::hysteria_protocol_wechat_video;
|
||||
}
|
||||
|
||||
if (query.hasQueryItem("auth")) {
|
||||
authPayload = query.queryItemValue("auth");
|
||||
authPayloadType = NekoGui_fmt::QUICBean::hysteria_auth_string;
|
||||
}
|
||||
|
||||
alpn = query.queryItemValue("alpn");
|
||||
sni = FIRST_OR_SECOND(query.queryItemValue("peer"), query.queryItemValue("sni"));
|
||||
|
||||
connectionReceiveWindow = query.queryItemValue("recv_window").toInt();
|
||||
streamReceiveWindow = query.queryItemValue("recv_window_conn").toInt();
|
||||
} else if (url.scheme() == "tuic") {
|
||||
if (url.scheme() == "tuic") {
|
||||
// by daeuniverse
|
||||
// https://github.com/daeuniverse/dae/discussions/182
|
||||
|
||||
@ -287,7 +278,7 @@ namespace NekoGui_fmt {
|
||||
name = url.fragment(QUrl::FullyDecoded);
|
||||
serverAddress = url.host();
|
||||
serverPort = url.port();
|
||||
// hopPort = query.queryItemValue("mport");
|
||||
hopPort = query.queryItemValue("mport");
|
||||
obfsPassword = query.queryItemValue("obfs-password");
|
||||
allowInsecure = QStringList{"1", "true"}.contains(query.queryItemValue("insecure"));
|
||||
|
||||
|
||||
@ -1,15 +1,6 @@
|
||||
#pragma once
|
||||
|
||||
namespace Preset {
|
||||
namespace Xray {
|
||||
inline QStringList UtlsFingerPrint = {"", "chrome", "firefox", "edge", "safari", "360", "qq", "ios", "android", "random", "randomized"};
|
||||
inline QStringList ShadowsocksMethods = {"aes-128-gcm", "aes-256-gcm", "aes-192-gcm", "chacha20-ietf-poly1305", "xchacha20-ietf-poly1305",
|
||||
"2022-blake3-aes-128-gcm", "2022-blake3-aes-256-gcm", "2022-blake3-chacha20-poly1305",
|
||||
"aes-128-ctr", "aes-192-ctr", "aes-256-ctr", "aes-128-cfb", "aes-192-cfb", "aes-256-cfb",
|
||||
"rc4", "rc4-md5", "bf-cfb", "chacha20", "chacha20-ietf", "xchacha20", "none"};
|
||||
inline QStringList Flows = {"xtls-rprx-vision", "xtls-rprx-vision-udp443"};
|
||||
} // namespace Xray
|
||||
|
||||
namespace SingBox {
|
||||
inline QStringList VpnImplementation = {"gvisor", "system", "mixed"};
|
||||
inline QStringList DomainStrategy = {"", "ipv4_only", "ipv6_only", "prefer_ipv4", "prefer_ipv6"};
|
||||
|
||||
@ -5,32 +5,19 @@
|
||||
namespace NekoGui_fmt {
|
||||
class QUICBean : public AbstractBean {
|
||||
public:
|
||||
static constexpr int proxy_Hysteria = 0;
|
||||
// static constexpr int proxy_Hysteria = 0;
|
||||
static constexpr int proxy_TUIC = 1;
|
||||
static constexpr int proxy_Hysteria2 = 3;
|
||||
int proxy_type = proxy_Hysteria;
|
||||
int proxy_type = proxy_Hysteria2;
|
||||
|
||||
bool forceExternal = false;
|
||||
|
||||
// Hysteria 1
|
||||
|
||||
static constexpr int hysteria_protocol_udp = 0;
|
||||
static constexpr int hysteria_protocol_facktcp = 1;
|
||||
static constexpr int hysteria_protocol_wechat_video = 2;
|
||||
int hyProtocol = 0;
|
||||
|
||||
static constexpr int hysteria_auth_none = 0;
|
||||
static constexpr int hysteria_auth_string = 1;
|
||||
static constexpr int hysteria_auth_base64 = 2;
|
||||
int authPayloadType = 0;
|
||||
QString authPayload = "";
|
||||
|
||||
// Hysteria 1&2
|
||||
// Hysteria 2
|
||||
|
||||
QString obfsPassword = "";
|
||||
|
||||
int uploadMbps = 100;
|
||||
int downloadMbps = 100;
|
||||
int uploadMbps = 0;
|
||||
int downloadMbps = 0;
|
||||
|
||||
qint64 streamReceiveWindow = 0;
|
||||
qint64 connectionReceiveWindow = 0;
|
||||
@ -62,8 +49,7 @@ namespace NekoGui_fmt {
|
||||
|
||||
explicit QUICBean(int _proxy_type) : AbstractBean(0) {
|
||||
proxy_type = _proxy_type;
|
||||
if (proxy_type == proxy_Hysteria || proxy_type == proxy_Hysteria2) {
|
||||
_add(new configItem("authPayload", &authPayload, itemType::string));
|
||||
if (proxy_type == proxy_Hysteria2) {
|
||||
_add(new configItem("obfsPassword", &obfsPassword, itemType::string));
|
||||
_add(new configItem("uploadMbps", &uploadMbps, itemType::integer));
|
||||
_add(new configItem("downloadMbps", &downloadMbps, itemType::integer));
|
||||
@ -72,14 +58,7 @@ namespace NekoGui_fmt {
|
||||
_add(new configItem("disableMtuDiscovery", &disableMtuDiscovery, itemType::boolean));
|
||||
_add(new configItem("hopInterval", &hopInterval, itemType::integer));
|
||||
_add(new configItem("hopPort", &hopPort, itemType::string));
|
||||
if (proxy_type == proxy_Hysteria) { // hy1
|
||||
_add(new configItem("authPayloadType", &authPayloadType, itemType::integer));
|
||||
_add(new configItem("protocol", &hyProtocol, itemType::integer));
|
||||
} else { // hy2
|
||||
uploadMbps = 0;
|
||||
downloadMbps = 0;
|
||||
_add(new configItem("password", &password, itemType::string));
|
||||
}
|
||||
_add(new configItem("password", &password, itemType::string));
|
||||
} else if (proxy_type == proxy_TUIC) {
|
||||
_add(new configItem("uuid", &uuid, itemType::string));
|
||||
_add(new configItem("password", &password, itemType::string));
|
||||
@ -108,8 +87,6 @@ namespace NekoGui_fmt {
|
||||
return software_core_name;
|
||||
} else if (proxy_type == proxy_TUIC) {
|
||||
return "tuic";
|
||||
} else if (proxy_type == proxy_Hysteria) {
|
||||
return "hysteria";
|
||||
} else {
|
||||
return "hysteria2";
|
||||
}
|
||||
@ -118,8 +95,6 @@ namespace NekoGui_fmt {
|
||||
QString DisplayType() override {
|
||||
if (proxy_type == proxy_TUIC) {
|
||||
return "TUIC";
|
||||
} else if (proxy_type == proxy_Hysteria) {
|
||||
return "Hysteria1";
|
||||
} else {
|
||||
return "Hysteria2";
|
||||
}
|
||||
|
||||
@ -23,8 +23,6 @@ namespace NekoGui_fmt {
|
||||
|
||||
QString DisplayType() override { return "Shadowsocks"; };
|
||||
|
||||
CoreObjOutboundBuildResult BuildCoreObjV2Ray() override;
|
||||
|
||||
CoreObjOutboundBuildResult BuildCoreObjSingBox() override;
|
||||
|
||||
bool TryParseLink(const QString &link);
|
||||
|
||||
@ -26,8 +26,6 @@ namespace NekoGui_fmt {
|
||||
|
||||
QString DisplayType() override { return socks_http_type == type_HTTP ? "HTTP" : "Socks"; };
|
||||
|
||||
CoreObjOutboundBuildResult BuildCoreObjV2Ray() override;
|
||||
|
||||
CoreObjOutboundBuildResult BuildCoreObjSingBox() override;
|
||||
|
||||
bool TryParseLink(const QString &link);
|
||||
|
||||
@ -24,8 +24,6 @@ namespace NekoGui_fmt {
|
||||
|
||||
QString DisplayType() override { return proxy_type == proxy_VLESS ? "VLESS" : "Trojan"; };
|
||||
|
||||
CoreObjOutboundBuildResult BuildCoreObjV2Ray() override;
|
||||
|
||||
CoreObjOutboundBuildResult BuildCoreObjSingBox() override;
|
||||
|
||||
bool TryParseLink(const QString &link);
|
||||
|
||||
@ -8,7 +8,7 @@ namespace NekoGui_fmt {
|
||||
QString network = "tcp";
|
||||
QString security = "";
|
||||
QString packet_encoding = "";
|
||||
// ws/http/grpc/tcp-http
|
||||
// ws/http/grpc/tcp-http/httpupgrade
|
||||
QString path = "";
|
||||
QString host = "";
|
||||
// kcp/quic/tcp-http
|
||||
@ -49,8 +49,6 @@ namespace NekoGui_fmt {
|
||||
_add(new configItem("mux_s", &multiplex_status, itemType::integer));
|
||||
}
|
||||
|
||||
QJsonObject BuildStreamSettingsV2Ray();
|
||||
|
||||
void BuildStreamSettingsSingBox(QJsonObject *outbound);
|
||||
};
|
||||
|
||||
|
||||
@ -21,8 +21,6 @@ namespace NekoGui_fmt {
|
||||
|
||||
QString DisplayType() override { return "VMess"; };
|
||||
|
||||
CoreObjOutboundBuildResult BuildCoreObjV2Ray() override;
|
||||
|
||||
CoreObjOutboundBuildResult BuildCoreObjSingBox() override;
|
||||
|
||||
bool TryParseLink(const QString &link);
|
||||
|
||||
@ -7,16 +7,16 @@ import (
|
||||
|
||||
"github.com/matsuridayo/libneko/neko_common"
|
||||
"github.com/matsuridayo/libneko/neko_log"
|
||||
"github.com/matsuridayo/sing-box-extra/boxapi"
|
||||
"github.com/matsuridayo/sing-box-extra/boxbox"
|
||||
"github.com/matsuridayo/sing-box-extra/boxmain"
|
||||
box "github.com/sagernet/sing-box"
|
||||
"github.com/sagernet/sing-box/boxapi"
|
||||
boxmain "github.com/sagernet/sing-box/cmd/sing-box"
|
||||
)
|
||||
|
||||
var instance *boxbox.Box
|
||||
var instance *box.Box
|
||||
var instance_cancel context.CancelFunc
|
||||
|
||||
func setupCore() {
|
||||
boxmain.DisableColor()
|
||||
boxmain.SetDisableColor(true)
|
||||
//
|
||||
neko_log.SetupLog(50*1024, "./neko.log")
|
||||
//
|
||||
@ -24,7 +24,7 @@ func setupCore() {
|
||||
return instance
|
||||
}
|
||||
neko_common.DialContext = func(ctx context.Context, specifiedInstance interface{}, network, addr string) (net.Conn, error) {
|
||||
if i, ok := specifiedInstance.(*boxbox.Box); ok {
|
||||
if i, ok := specifiedInstance.(*box.Box); ok {
|
||||
return boxapi.DialContext(ctx, i, network, addr)
|
||||
}
|
||||
if instance != nil {
|
||||
@ -33,7 +33,7 @@ func setupCore() {
|
||||
return neko_common.DialContextSystem(ctx, network, addr)
|
||||
}
|
||||
neko_common.DialUDP = func(ctx context.Context, specifiedInstance interface{}) (net.PacketConn, error) {
|
||||
if i, ok := specifiedInstance.(*boxbox.Box); ok {
|
||||
if i, ok := specifiedInstance.(*box.Box); ok {
|
||||
return boxapi.DialUDP(ctx, i)
|
||||
}
|
||||
if instance != nil {
|
||||
@ -42,7 +42,7 @@ func setupCore() {
|
||||
return neko_common.DialUDPSystem(ctx)
|
||||
}
|
||||
neko_common.CreateProxyHttpClient = func(specifiedInstance interface{}) *http.Client {
|
||||
if i, ok := specifiedInstance.(*boxbox.Box); ok {
|
||||
if i, ok := specifiedInstance.(*box.Box); ok {
|
||||
return boxapi.CreateProxyHttpClient(i)
|
||||
}
|
||||
return boxapi.CreateProxyHttpClient(instance)
|
||||
|
||||
@ -4,7 +4,6 @@ go 1.19
|
||||
|
||||
require (
|
||||
github.com/matsuridayo/libneko v1.0.0 // replaced
|
||||
github.com/matsuridayo/sing-box-extra v1.0.0 // replaced
|
||||
github.com/sagernet/sing-box v1.0.0 // replaced
|
||||
// github.com/sagernet/sing-dns v1.0.0 // indirect; replaced
|
||||
grpc_server v1.0.0
|
||||
@ -14,93 +13,93 @@ require (
|
||||
berty.tech/go-libtor v1.0.385 // indirect
|
||||
cloud.google.com/go/compute/metadata v0.2.3 // indirect
|
||||
github.com/ajg/form v1.5.1 // indirect
|
||||
github.com/andybalholm/brotli v1.0.5 // indirect
|
||||
github.com/caddyserver/certmagic v0.19.2 // indirect
|
||||
github.com/cloudflare/circl v1.3.3 // indirect
|
||||
github.com/andybalholm/brotli v1.0.6 // indirect
|
||||
github.com/caddyserver/certmagic v0.20.0 // indirect
|
||||
github.com/cloudflare/circl v1.3.7 // indirect
|
||||
github.com/cretz/bine v0.2.0 // indirect
|
||||
github.com/dustin/go-humanize v1.0.1 // indirect
|
||||
github.com/fsnotify/fsnotify v1.6.0 // indirect
|
||||
github.com/go-chi/chi/v5 v5.0.10 // indirect
|
||||
github.com/fsnotify/fsnotify v1.7.0 // indirect
|
||||
github.com/gaukas/godicttls v0.0.4 // indirect
|
||||
github.com/go-chi/chi/v5 v5.0.12 // indirect
|
||||
github.com/go-chi/cors v1.2.1 // indirect
|
||||
github.com/go-chi/render v1.0.3 // indirect
|
||||
github.com/go-ole/go-ole v1.3.0 // indirect
|
||||
github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 // indirect
|
||||
github.com/gofrs/uuid/v5 v5.0.0 // indirect
|
||||
github.com/golang/protobuf v1.5.3 // indirect
|
||||
github.com/gobwas/httphead v0.1.0 // indirect
|
||||
github.com/gobwas/pool v0.2.1 // indirect
|
||||
github.com/gofrs/uuid/v5 v5.2.0 // indirect
|
||||
github.com/google/btree v1.1.2 // indirect
|
||||
github.com/google/pprof v0.0.0-20210407192527-94a9f03dee38 // indirect
|
||||
github.com/google/pprof v0.0.0-20231101202521-4ca4178f5c7a // indirect
|
||||
github.com/grpc-ecosystem/go-grpc-middleware v1.3.0 // indirect
|
||||
github.com/hashicorp/yamux v0.1.1 // indirect
|
||||
github.com/inconshreveable/mousetrap v1.1.0 // indirect
|
||||
github.com/insomniacslk/dhcp v0.0.0-20230908212754-65c27093e38a // indirect
|
||||
github.com/insomniacslk/dhcp v0.0.0-20231206064809-8c70d406f6d2 // indirect
|
||||
github.com/josharian/native v1.1.0 // indirect
|
||||
github.com/klauspost/compress v1.15.15 // indirect
|
||||
github.com/klauspost/compress v1.17.4 // indirect
|
||||
github.com/klauspost/cpuid/v2 v2.2.5 // indirect
|
||||
github.com/libdns/alidns v1.0.3 // indirect
|
||||
github.com/libdns/cloudflare v0.1.0 // indirect
|
||||
github.com/libdns/libdns v0.2.1 // indirect
|
||||
github.com/libdns/cloudflare v0.1.1 // indirect
|
||||
github.com/libdns/libdns v0.2.2 // indirect
|
||||
github.com/logrusorgru/aurora v2.0.3+incompatible // indirect
|
||||
github.com/metacubex/tfo-go v0.0.0-20240821025650-e9be0afd5e7d // indirect
|
||||
github.com/mholt/acmez v1.2.0 // indirect
|
||||
github.com/miekg/dns v1.1.56 // indirect
|
||||
github.com/onsi/ginkgo/v2 v2.9.5 // indirect
|
||||
github.com/miekg/dns v1.1.59 // indirect
|
||||
github.com/onsi/ginkgo/v2 v2.9.7 // indirect
|
||||
github.com/ooni/go-libtor v1.1.8 // indirect
|
||||
github.com/oschwald/maxminddb-golang v1.12.0 // indirect
|
||||
github.com/pierrec/lz4/v4 v4.1.14 // indirect
|
||||
github.com/quic-go/qpack v0.4.0 // indirect
|
||||
github.com/quic-go/qtls-go1-20 v0.3.4 // indirect
|
||||
github.com/sagernet/bbolt v0.0.0-20231008142710-b2d6e2f20458 // indirect
|
||||
github.com/sagernet/cloudflare-tls v0.0.0-20230829051644-4a68352d0c4a // indirect
|
||||
github.com/sagernet/go-tun2socks v1.16.12-0.20220818015926-16cb67876a61 // indirect
|
||||
github.com/sagernet/gvisor v0.0.0-20230930141345-5fef6f2e17ab // indirect
|
||||
github.com/sagernet/netlink v0.0.0-20220905062125-8043b4a9aa97 // indirect
|
||||
github.com/sagernet/quic-go v0.0.0-20231008035953-32727fef9460 // indirect
|
||||
github.com/quic-go/qtls-go1-20 v0.4.1 // indirect
|
||||
github.com/sagernet/bbolt v0.0.0-20231014093535-ea5cb2fe9f0a // indirect
|
||||
github.com/sagernet/cloudflare-tls v0.0.0-20231208171750-a4483c1b7cd1 // indirect
|
||||
github.com/sagernet/gvisor v0.0.0-20240428053021-e691de28565f // indirect
|
||||
github.com/sagernet/netlink v0.0.0-20240523065131-45e60152f9ba // indirect
|
||||
github.com/sagernet/quic-go v0.47.0-beta.2 // indirect
|
||||
github.com/sagernet/reality v0.0.0-20230406110435-ee17307e7691 // indirect
|
||||
github.com/sagernet/sing v0.2.14-0.20231011041941-e4d9384bcd84 // indirect
|
||||
github.com/sagernet/sing-dns v0.1.10 // indirect
|
||||
github.com/sagernet/sing-mux v0.1.3 // indirect
|
||||
github.com/sagernet/sing-quic v0.1.3-0.20231011042217-13b8d0b8f74b // indirect
|
||||
github.com/sagernet/sing-shadowsocks v0.2.5 // indirect
|
||||
github.com/sagernet/sing-shadowsocks2 v0.1.4 // indirect
|
||||
github.com/sagernet/sing v0.4.3 // indirect
|
||||
github.com/sagernet/sing-dns v0.2.3 // indirect
|
||||
github.com/sagernet/sing-mux v0.2.0 // indirect
|
||||
github.com/sagernet/sing-quic v0.2.2 // indirect
|
||||
github.com/sagernet/sing-shadowsocks v0.2.7 // indirect
|
||||
github.com/sagernet/sing-shadowsocks2 v0.2.0 // indirect
|
||||
github.com/sagernet/sing-shadowtls v0.1.4 // indirect
|
||||
github.com/sagernet/sing-tun v0.1.16-0.20231006112722-19cc8b9e81aa // indirect
|
||||
github.com/sagernet/sing-vmess v0.1.8 // indirect
|
||||
github.com/sagernet/smux v0.0.0-20230312102458-337ec2a5af37 // indirect
|
||||
github.com/sagernet/tfo-go v0.0.0-20230816093905-5a5c285d44a6 // indirect
|
||||
github.com/sagernet/utls v0.0.0-20230309024959-6732c2ab36f2 // indirect
|
||||
github.com/sagernet/websocket v0.0.0-20220913015213-615516348b4e // indirect
|
||||
github.com/sagernet/wireguard-go v0.0.0-20230807125731-5d4a7ef2dc5f // indirect
|
||||
github.com/scjalliance/comshim v0.0.0-20230315213746-5e51f40bd3b9 // indirect
|
||||
github.com/spf13/cobra v1.7.0 // indirect
|
||||
github.com/sagernet/sing-tun v0.3.3 // indirect
|
||||
github.com/sagernet/sing-vmess v0.1.12 // indirect
|
||||
github.com/sagernet/smux v0.0.0-20231208180855-7041f6ea79e7 // indirect
|
||||
github.com/sagernet/utls v1.5.4 // indirect
|
||||
github.com/sagernet/wireguard-go v0.0.0-20231215174105-89dec3b2f3e8 // indirect
|
||||
github.com/sagernet/ws v0.0.0-20231204124109-acfe8907c854 // indirect
|
||||
github.com/spf13/cobra v1.8.0 // indirect
|
||||
github.com/spf13/pflag v1.0.5 // indirect
|
||||
github.com/u-root/uio v0.0.0-20230220225925-ffce2a382923 // indirect
|
||||
github.com/vishvananda/netns v0.0.0-20211101163701-50045581ed74 // indirect
|
||||
github.com/zeebo/blake3 v0.2.3 // indirect
|
||||
go.uber.org/multierr v1.11.0 // indirect
|
||||
go.uber.org/zap v1.26.0 // indirect
|
||||
go4.org/netipx v0.0.0-20230824141953-6213f710f925 // indirect
|
||||
golang.org/x/crypto v0.14.0 // indirect
|
||||
golang.org/x/exp v0.0.0-20231005195138-3e424a577f31 // indirect
|
||||
golang.org/x/mod v0.12.0 // indirect
|
||||
golang.org/x/net v0.16.0 // indirect
|
||||
golang.org/x/sys v0.13.0 // indirect
|
||||
golang.org/x/text v0.13.0 // indirect
|
||||
golang.org/x/time v0.3.0 // indirect
|
||||
golang.org/x/tools v0.13.0 // indirect
|
||||
go.uber.org/zap v1.27.0 // indirect
|
||||
go4.org/netipx v0.0.0-20231129151722-fdeea329fbba // indirect
|
||||
golang.org/x/crypto v0.23.0 // indirect
|
||||
golang.org/x/exp v0.0.0-20240416160154-fe59bbe5cc7f // indirect
|
||||
golang.org/x/mod v0.18.0 // indirect
|
||||
golang.org/x/net v0.25.0 // indirect
|
||||
golang.org/x/sync v0.8.0 // indirect
|
||||
golang.org/x/sys v0.25.0 // indirect
|
||||
golang.org/x/text v0.18.0 // indirect
|
||||
golang.org/x/time v0.5.0 // indirect
|
||||
golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d // indirect
|
||||
golang.zx2c4.com/wireguard/wgctrl v0.0.0-20230429144221-925a1e7659e6 // indirect
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20230711160842-782d3b101e98 // indirect
|
||||
google.golang.org/grpc v1.58.2 // indirect
|
||||
google.golang.org/protobuf v1.31.0 // indirect
|
||||
lukechampine.com/blake3 v1.2.1 // indirect
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20240227224415-6ceb2ff114de // indirect
|
||||
google.golang.org/grpc v1.63.2 // indirect
|
||||
google.golang.org/protobuf v1.33.0 // indirect
|
||||
lukechampine.com/blake3 v1.3.0 // indirect
|
||||
)
|
||||
|
||||
replace grpc_server => ../../grpc_server
|
||||
|
||||
replace github.com/matsuridayo/libneko => ../../../../libneko
|
||||
|
||||
replace github.com/matsuridayo/sing-box-extra => ../../../../sing-box-extra
|
||||
|
||||
replace github.com/sagernet/sing-box => ../../../../sing-box
|
||||
|
||||
replace github.com/sagernet/sing-quic => ../../../../sing-quic
|
||||
|
||||
// replace github.com/sagernet/sing => ../../../../sing
|
||||
|
||||
// replace github.com/sagernet/sing-dns => ../../../../sing-dns
|
||||
|
||||
@ -2,41 +2,38 @@ berty.tech/go-libtor v1.0.385 h1:RWK94C3hZj6Z2GdvePpHJLnWYobFr3bY/OdUJ5aoEXw=
|
||||
berty.tech/go-libtor v1.0.385/go.mod h1:9swOOQVb+kmvuAlsgWUK/4c52pm69AdbJsxLzk+fJEw=
|
||||
cloud.google.com/go v0.26.0 h1:e0WKqKTd5BnrG8aKH3J3h+QvEIQtSUcf2n5UZ5ZgLtQ=
|
||||
cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
|
||||
cloud.google.com/go/compute v1.21.0 h1:JNBsyXVoOoNJtTQcnEY5uYpZIbeCTYIeDe0Xh1bySMk=
|
||||
cloud.google.com/go/compute v1.24.0 h1:phWcR2eWzRJaL/kOiJwfFsPs4BaKq1j6vnpZrc1YlVg=
|
||||
cloud.google.com/go/compute/metadata v0.2.3 h1:mg4jlk7mCAj6xXp9UJ4fjI9VUI5rubuGBW5aJ7UnBMY=
|
||||
cloud.google.com/go/compute/metadata v0.2.3/go.mod h1:VAV5nSsACxMJvgaAuX6Pk2AawlZn8kiOGuCv6gTkwuA=
|
||||
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
|
||||
github.com/ajg/form v1.5.1 h1:t9c7v8JUKu/XxOGBU0yjNpaMloxGEJhUkqFRq0ibGeU=
|
||||
github.com/ajg/form v1.5.1/go.mod h1:uL1WgH+h2mgNtvBq0339dVnzXdBETtL2LeUXaIv25UY=
|
||||
github.com/andybalholm/brotli v1.0.5 h1:8uQZIdzKmjc/iuPu7O2ioW48L81FgatrcpfFmiq/cCs=
|
||||
github.com/andybalholm/brotli v1.0.5/go.mod h1:fO7iG3H7G2nSZ7m0zPUDn85XEX2GTukHGRSepvi9Eig=
|
||||
github.com/caddyserver/certmagic v0.19.2 h1:HZd1AKLx4592MalEGQS39DKs2ZOAJCEM/xYPMQ2/ui0=
|
||||
github.com/caddyserver/certmagic v0.19.2/go.mod h1:fsL01NomQ6N+kE2j37ZCnig2MFosG+MIO4ztnmG/zz8=
|
||||
github.com/andybalholm/brotli v1.0.6 h1:Yf9fFpf49Zrxb9NlQaluyE92/+X7UVHlhMNJN2sxfOI=
|
||||
github.com/andybalholm/brotli v1.0.6/go.mod h1:fO7iG3H7G2nSZ7m0zPUDn85XEX2GTukHGRSepvi9Eig=
|
||||
github.com/caddyserver/certmagic v0.20.0 h1:bTw7LcEZAh9ucYCRXyCpIrSAGplplI0vGYJ4BpCQ/Fc=
|
||||
github.com/caddyserver/certmagic v0.20.0/go.mod h1:N4sXgpICQUskEWpj7zVzvWD41p3NYacrNoZYiRM2jTg=
|
||||
github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
|
||||
github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI=
|
||||
github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI=
|
||||
github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU=
|
||||
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
|
||||
github.com/cloudflare/circl v1.3.3 h1:fE/Qz0QdIGqeWfnwq0RE0R7MI51s0M2E4Ga9kq5AEMs=
|
||||
github.com/cloudflare/circl v1.3.3/go.mod h1:5XYMA4rFBvNIrhs50XuiBJ15vF2pZn4nnUKZrLbUZFA=
|
||||
github.com/cloudflare/circl v1.3.7 h1:qlCDlTPz2n9fu58M0Nh1J/JzcFpfgkFHHX3O35r5vcU=
|
||||
github.com/cloudflare/circl v1.3.7/go.mod h1:sRTcRWXGLrKw6yIGJ+l7amYJFfAXbZG0kBSc8r4zxgA=
|
||||
github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc=
|
||||
github.com/cpuguy83/go-md2man/v2 v2.0.2/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
|
||||
github.com/cpuguy83/go-md2man/v2 v2.0.3/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
|
||||
github.com/cretz/bine v0.1.0/go.mod h1:6PF6fWAvYtwjRGkAuDEJeWNOv3a2hUouSP/yRYXmvHw=
|
||||
github.com/cretz/bine v0.2.0 h1:8GiDRGlTgz+o8H9DSnsl+5MeBK4HsExxgl6WgzOCuZo=
|
||||
github.com/cretz/bine v0.2.0/go.mod h1:WU4o9QR9wWp8AVKtTM1XD5vUHkEqnf2vVSo6dBqbetI=
|
||||
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/dustin/go-humanize v1.0.1 h1:GzkhY7T5VNhEkwH0PVJgjz+fX1rhBrR7pRT3mDkpeCY=
|
||||
github.com/dustin/go-humanize v1.0.1/go.mod h1:Mu1zIs6XwVuF/gI1OepvI0qD18qycQx+mFykh5fBlto=
|
||||
github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
|
||||
github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
|
||||
github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98=
|
||||
github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
|
||||
github.com/fsnotify/fsnotify v1.6.0 h1:n+5WquG0fcWoWp6xPWfHdbskMCQaFnG6PfBrh1Ky4HY=
|
||||
github.com/fsnotify/fsnotify v1.6.0/go.mod h1:sl3t1tCWJFWoRz9R8WJCbQihKKwmorjAbSClcnxKAGw=
|
||||
github.com/go-chi/chi/v5 v5.0.10 h1:rLz5avzKpjqxrYwXNfmjkrYYXOyLJd37pz53UFHC6vk=
|
||||
github.com/go-chi/chi/v5 v5.0.10/go.mod h1:DslCQbL2OYiznFReuXYUmQ2hGd1aDpCnlMNITLSKoi8=
|
||||
github.com/fsnotify/fsnotify v1.7.0 h1:8JEhPFa5W2WU7YfeZzPNqzMP6Lwt7L2715Ggo0nosvA=
|
||||
github.com/fsnotify/fsnotify v1.7.0/go.mod h1:40Bi/Hjc2AVfZrqy+aj+yEI+/bRxZnMJyTJwOpGvigM=
|
||||
github.com/gaukas/godicttls v0.0.4 h1:NlRaXb3J6hAnTmWdsEKb9bcSBD6BvcIjdGdeb0zfXbk=
|
||||
github.com/gaukas/godicttls v0.0.4/go.mod h1:l6EenT4TLWgTdwslVb4sEMOCf7Bv0JAK67deKr9/NCI=
|
||||
github.com/go-chi/chi/v5 v5.0.12 h1:9euLV5sTrTNTRUU9POmDUvfxyj6LAABLUcEWO+JJb4s=
|
||||
github.com/go-chi/chi/v5 v5.0.12/go.mod h1:DslCQbL2OYiznFReuXYUmQ2hGd1aDpCnlMNITLSKoi8=
|
||||
github.com/go-chi/cors v1.2.1 h1:xEC8UT3Rlp2QuWNEr4Fs/c2EAGVKBwy/1vHx3bppil4=
|
||||
github.com/go-chi/cors v1.2.1/go.mod h1:sSbTewc+6wYHBBCW7ytsFSn836hqM7JxpglAy2Vzc58=
|
||||
github.com/go-chi/render v1.0.3 h1:AsXqd2a1/INaIfUSKq3G5uA8weYx20FOsM7uSoCyyt4=
|
||||
@ -49,40 +46,40 @@ github.com/go-ole/go-ole v1.3.0/go.mod h1:5LS6F96DhAwUc7C+1HLexzMXY1xGRSryjyPPKW
|
||||
github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=
|
||||
github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 h1:tfuBGBXKqDEevZMzYi5KSi8KkcZtzBcTgAUUtapy0OI=
|
||||
github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572/go.mod h1:9Pwr4B2jHnOSGXyyzV8ROjYa2ojvAY6HCGYYfMoC3Ls=
|
||||
github.com/gofrs/uuid/v5 v5.0.0 h1:p544++a97kEL+svbcFbCQVM9KFu0Yo25UoISXGNNH9M=
|
||||
github.com/gofrs/uuid/v5 v5.0.0/go.mod h1:CDOjlDMVAtN56jqyRUZh58JT31Tiw7/oQyEXZV+9bD8=
|
||||
github.com/gobwas/httphead v0.1.0 h1:exrUm0f4YX0L7EBwZHuCF4GDp8aJfVeBrlLQrs6NqWU=
|
||||
github.com/gobwas/httphead v0.1.0/go.mod h1:O/RXo79gxV8G+RqlR/otEwx4Q36zl9rqC5u12GKvMCM=
|
||||
github.com/gobwas/pool v0.2.1 h1:xfeeEhW7pwmX8nuLVlqbzVc7udMDrwetjEv+TZIz1og=
|
||||
github.com/gobwas/pool v0.2.1/go.mod h1:q8bcK0KcYlCgd9e7WYLm9LpyS+YeLd8JVDW6WezmKEw=
|
||||
github.com/gofrs/uuid/v5 v5.2.0 h1:qw1GMx6/y8vhVsx626ImfKMuS5CvJmhIKKtuyvfajMM=
|
||||
github.com/gofrs/uuid/v5 v5.2.0/go.mod h1:CDOjlDMVAtN56jqyRUZh58JT31Tiw7/oQyEXZV+9bD8=
|
||||
github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q=
|
||||
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
|
||||
github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
|
||||
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||
github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||
github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw=
|
||||
github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk=
|
||||
github.com/golang/protobuf v1.5.3 h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg=
|
||||
github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY=
|
||||
github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek=
|
||||
github.com/google/btree v1.1.2 h1:xf4v41cLI2Z6FxbKm+8Bu+m8ifhj15JuZ9sa0jZCMUU=
|
||||
github.com/google/btree v1.1.2/go.mod h1:qOPhT0dTNdNzV6Z/lhRX0YXUafgPLFUh+gZMl761Gm4=
|
||||
github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=
|
||||
github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38=
|
||||
github.com/google/pprof v0.0.0-20210407192527-94a9f03dee38 h1:yAJXTCF9TqKcTiHJAE8dj7HMvPfh66eeA2JYW7eFpSE=
|
||||
github.com/google/pprof v0.0.0-20210407192527-94a9f03dee38/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
|
||||
github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=
|
||||
github.com/google/pprof v0.0.0-20231101202521-4ca4178f5c7a h1:fEBsGL/sjAuJrgah5XqmmYsTLzJp/TO9Lhy39gkverk=
|
||||
github.com/google/pprof v0.0.0-20231101202521-4ca4178f5c7a/go.mod h1:czg5+yv1E0ZGTi6S6vVK1mke0fV+FaUhNGcd6VRS9Ik=
|
||||
github.com/grpc-ecosystem/go-grpc-middleware v1.3.0 h1:+9834+KizmvFV7pXQGSXQTsaWhq2GjuNUt0aUU0YBYw=
|
||||
github.com/grpc-ecosystem/go-grpc-middleware v1.3.0/go.mod h1:z0ButlSOZa5vEBq9m2m2hlwIgKw+rp3sdCBRoJY+30Y=
|
||||
github.com/hashicorp/yamux v0.1.1 h1:yrQxtgseBDrq9Y652vSRDvsKCJKOUD+GzTS4Y0Y8pvE=
|
||||
github.com/hashicorp/yamux v0.1.1/go.mod h1:CtWFDAQgb7dxtzFs4tWbplKIe2jSi3+5vKbgIO0SLnQ=
|
||||
github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
|
||||
github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8=
|
||||
github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw=
|
||||
github.com/insomniacslk/dhcp v0.0.0-20230908212754-65c27093e38a h1:S33o3djA1nPRd+d/bf7jbbXytXuK/EoXow7+aa76grQ=
|
||||
github.com/insomniacslk/dhcp v0.0.0-20230908212754-65c27093e38a/go.mod h1:zmdm3sTSDP3vOOX3CEWRkkRHtKr1DxBx+J1OQFoDQQs=
|
||||
github.com/insomniacslk/dhcp v0.0.0-20231206064809-8c70d406f6d2 h1:9K06NfxkBh25x56yVhWWlKFE8YpicaSfHwoV8SFbueA=
|
||||
github.com/insomniacslk/dhcp v0.0.0-20231206064809-8c70d406f6d2/go.mod h1:3A9PQ1cunSDF/1rbTq99Ts4pVnycWg+vlPkfeD2NLFI=
|
||||
github.com/josharian/native v1.0.1-0.20221213033349-c1e37c09b531/go.mod h1:7X/raswPFr05uY3HiLlYeyQntB6OO7E/d2Cu7qoaN2w=
|
||||
github.com/josharian/native v1.1.0 h1:uuaP0hAbW7Y4l0ZRQ6C9zfb7Mg1mbFKry/xzDAfmtLA=
|
||||
github.com/josharian/native v1.1.0/go.mod h1:7X/raswPFr05uY3HiLlYeyQntB6OO7E/d2Cu7qoaN2w=
|
||||
github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8=
|
||||
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
|
||||
github.com/klauspost/compress v1.15.15 h1:EF27CXIuDsYJ6mmvtBRlEuB2UVOqHG1tAXgZ7yIO+lw=
|
||||
github.com/klauspost/compress v1.15.15/go.mod h1:ZcK2JAFqKOpnBlxcLsJzYfrS9X1akm9fHZNnD9+Vo/4=
|
||||
github.com/klauspost/compress v1.17.4 h1:Ej5ixsIri7BrIjBkRZLTo6ghwrEtHFk7ijlczPW4fZ4=
|
||||
github.com/klauspost/compress v1.17.4/go.mod h1:/dCuZOvVtNoHsyb+cuJD3itjs3NbnF6KH9zAO4BDxPM=
|
||||
github.com/klauspost/cpuid/v2 v2.0.12/go.mod h1:g2LTdtYhdyuGPqyWyv7qRAmj1WBqxuObKfj5c0PQa7c=
|
||||
github.com/klauspost/cpuid/v2 v2.2.5 h1:0E5MSMDEoAulmXNFquVs//DdoomxaoTY1kUhbc/qbZg=
|
||||
github.com/klauspost/cpuid/v2 v2.2.5/go.mod h1:Lcz8mBdAVJIBVzewtcLocK12l3Y+JytZYpaMropDUws=
|
||||
@ -90,20 +87,22 @@ github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxv
|
||||
github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc=
|
||||
github.com/libdns/alidns v1.0.3 h1:LFHuGnbseq5+HCeGa1aW8awyX/4M2psB9962fdD2+yQ=
|
||||
github.com/libdns/alidns v1.0.3/go.mod h1:e18uAG6GanfRhcJj6/tps2rCMzQJaYVcGKT+ELjdjGE=
|
||||
github.com/libdns/cloudflare v0.1.0 h1:93WkJaGaiXCe353LHEP36kAWCUw0YjFqwhkBkU2/iic=
|
||||
github.com/libdns/cloudflare v0.1.0/go.mod h1:a44IP6J1YH6nvcNl1PverfJviADgXUnsozR3a7vBKN8=
|
||||
github.com/libdns/cloudflare v0.1.1 h1:FVPfWwP8zZCqj268LZjmkDleXlHPlFU9KC4OJ3yn054=
|
||||
github.com/libdns/cloudflare v0.1.1/go.mod h1:9VK91idpOjg6v7/WbjkEW49bSCxj00ALesIFDhJ8PBU=
|
||||
github.com/libdns/libdns v0.2.0/go.mod h1:yQCXzk1lEZmmCPa857bnk4TsOiqYasqpyOEeSObbb40=
|
||||
github.com/libdns/libdns v0.2.1 h1:Wu59T7wSHRgtA0cfxC+n1c/e+O3upJGWytknkmFEDis=
|
||||
github.com/libdns/libdns v0.2.1/go.mod h1:yQCXzk1lEZmmCPa857bnk4TsOiqYasqpyOEeSObbb40=
|
||||
github.com/libdns/libdns v0.2.2 h1:O6ws7bAfRPaBsgAYt8MDe2HcNBGC29hkZ9MX2eUSX3s=
|
||||
github.com/libdns/libdns v0.2.2/go.mod h1:4Bj9+5CQiNMVGf87wjX4CY3HQJypUHRuLvlsfsZqLWQ=
|
||||
github.com/logrusorgru/aurora v2.0.3+incompatible h1:tOpm7WcpBTn4fjmVfgpQq0EfczGlG91VSDkswnjF5A8=
|
||||
github.com/logrusorgru/aurora v2.0.3+incompatible/go.mod h1:7rIyQOR62GCctdiQpZ/zOJlFyk6y+94wXzv6RNZgaR4=
|
||||
github.com/metacubex/tfo-go v0.0.0-20240821025650-e9be0afd5e7d h1:j9LtzkYstLFoNvXW824QQeN7Y26uPL5249kzWKbzO9U=
|
||||
github.com/metacubex/tfo-go v0.0.0-20240821025650-e9be0afd5e7d/go.mod h1:c7bVFM9f5+VzeZ/6Kg77T/jrg1Xp8QpqlSHvG/aXVts=
|
||||
github.com/mholt/acmez v1.2.0 h1:1hhLxSgY5FvH5HCnGUuwbKY2VQVo8IU7rxXKSnZ7F30=
|
||||
github.com/mholt/acmez v1.2.0/go.mod h1:VT9YwH1xgNX1kmYY89gY8xPJC84BFAisjo8Egigt4kE=
|
||||
github.com/miekg/dns v1.1.56 h1:5imZaSeoRNvpM9SzWNhEcP9QliKiz20/dA2QabIGVnE=
|
||||
github.com/miekg/dns v1.1.56/go.mod h1:cRm6Oo2C8TY9ZS/TqsSrseAcncm74lfK5G+ikN2SWWY=
|
||||
github.com/onsi/ginkgo/v2 v2.9.5 h1:+6Hr4uxzP4XIUyAkg61dWBw8lb/gc4/X5luuxN/EC+Q=
|
||||
github.com/onsi/ginkgo/v2 v2.9.5/go.mod h1:tvAoo1QUJwNEU2ITftXTpR7R1RbCzoZUOs3RonqW57k=
|
||||
github.com/onsi/gomega v1.27.6 h1:ENqfyGeS5AX/rlXDd/ETokDz93u0YufY1Pgxuy/PvWE=
|
||||
github.com/miekg/dns v1.1.59 h1:C9EXc/UToRwKLhK5wKU/I4QVsBUc8kE6MkHBkeypWZs=
|
||||
github.com/miekg/dns v1.1.59/go.mod h1:nZpewl5p6IvctfgrckopVx2OlSEHPRO/U4SYkRklrEk=
|
||||
github.com/onsi/ginkgo/v2 v2.9.7 h1:06xGQy5www2oN160RtEZoTvnP2sPhEfePYmCDc2szss=
|
||||
github.com/onsi/ginkgo/v2 v2.9.7/go.mod h1:cxrmXWykAwTwhQsJOPfdIDiJ+l2RYq7U8hFU+M/1uw0=
|
||||
github.com/onsi/gomega v1.27.7 h1:fVih9JD6ogIiHUN6ePK7HJidyEDpWGVB5mzM7cWNXoU=
|
||||
github.com/ooni/go-libtor v1.1.8 h1:Wo3V3DVTxl5vZdxtQakqYP+DAHx7pPtAFSl1bnAa08w=
|
||||
github.com/ooni/go-libtor v1.1.8/go.mod h1:q1YyLwRD9GeMyeerVvwc0vJ2YgwDLTp2bdVcrh/JXyI=
|
||||
github.com/opentracing/opentracing-go v1.1.0/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o=
|
||||
@ -117,58 +116,49 @@ github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZN
|
||||
github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
|
||||
github.com/quic-go/qpack v0.4.0 h1:Cr9BXA1sQS2SmDUWjSofMPNKmvF6IiIfDRmgU0w1ZCo=
|
||||
github.com/quic-go/qpack v0.4.0/go.mod h1:UZVnYIfi5GRk+zI9UMaCPsmZ2xKJP7XBUvVyT1Knj9A=
|
||||
github.com/quic-go/qtls-go1-20 v0.3.4 h1:MfFAPULvst4yoMgY9QmtpYmfij/em7O8UUi+bNVm7Cg=
|
||||
github.com/quic-go/qtls-go1-20 v0.3.4/go.mod h1:X9Nh97ZL80Z+bX/gUXMbipO6OxdiDi58b/fMC9mAL+k=
|
||||
github.com/quic-go/qtls-go1-20 v0.4.1 h1:D33340mCNDAIKBqXuAvexTNMUByrYmFYVfKfDN5nfFs=
|
||||
github.com/quic-go/qtls-go1-20 v0.4.1/go.mod h1:X9Nh97ZL80Z+bX/gUXMbipO6OxdiDi58b/fMC9mAL+k=
|
||||
github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
|
||||
github.com/sagernet/bbolt v0.0.0-20231008142710-b2d6e2f20458 h1:7NXD6FUQucBklrw/TLCqeAARyFuoK9fD5iJ+Y/EHHBQ=
|
||||
github.com/sagernet/bbolt v0.0.0-20231008142710-b2d6e2f20458/go.mod h1:63s7jpZqcDAIpj8oI/1v4Izok+npJOHACFCU6+huCkM=
|
||||
github.com/sagernet/cloudflare-tls v0.0.0-20230829051644-4a68352d0c4a h1:wZHruBxZCsQLXHAozWpnJBL3wJ/XufDpz0qKtgpSnA4=
|
||||
github.com/sagernet/cloudflare-tls v0.0.0-20230829051644-4a68352d0c4a/go.mod h1:dNV1ZP9y3qx5ltULeKaQZTZWTLHflgW5DES+Ses7cMI=
|
||||
github.com/sagernet/go-tun2socks v1.16.12-0.20220818015926-16cb67876a61 h1:5+m7c6AkmAylhauulqN/c5dnh8/KssrE9c93TQrXldA=
|
||||
github.com/sagernet/go-tun2socks v1.16.12-0.20220818015926-16cb67876a61/go.mod h1:QUQ4RRHD6hGGHdFMEtR8T2P6GS6R3D/CXKdaYHKKXms=
|
||||
github.com/sagernet/gvisor v0.0.0-20230930141345-5fef6f2e17ab h1:u+xQoi/Yc6bNUvTfrDD6HhGRybn2lzrhf5vmS+wb4Ho=
|
||||
github.com/sagernet/gvisor v0.0.0-20230930141345-5fef6f2e17ab/go.mod h1:3akUhSHSVtLuJaYcW5JPepUraBOW06Ibz2HKwaK5rOk=
|
||||
github.com/sagernet/netlink v0.0.0-20220905062125-8043b4a9aa97 h1:iL5gZI3uFp0X6EslacyapiRz7LLSJyr4RajF/BhMVyE=
|
||||
github.com/sagernet/netlink v0.0.0-20220905062125-8043b4a9aa97/go.mod h1:xLnfdiJbSp8rNqYEdIW/6eDO4mVoogml14Bh2hSiFpM=
|
||||
github.com/sagernet/quic-go v0.0.0-20231008035953-32727fef9460 h1:dAe4OIJAtE0nHOzTHhAReQteh3+sa63rvXbuIpbeOTY=
|
||||
github.com/sagernet/quic-go v0.0.0-20231008035953-32727fef9460/go.mod h1:uJGpmJCOcMQqMlHKc3P1Vz6uygmpz4bPeVIoOhdVQnM=
|
||||
github.com/sagernet/bbolt v0.0.0-20231014093535-ea5cb2fe9f0a h1:+NkI2670SQpQWvkkD2QgdTuzQG263YZ+2emfpeyGqW0=
|
||||
github.com/sagernet/bbolt v0.0.0-20231014093535-ea5cb2fe9f0a/go.mod h1:63s7jpZqcDAIpj8oI/1v4Izok+npJOHACFCU6+huCkM=
|
||||
github.com/sagernet/cloudflare-tls v0.0.0-20231208171750-a4483c1b7cd1 h1:YbmpqPQEMdlk9oFSKYWRqVuu9qzNiOayIonKmv1gCXY=
|
||||
github.com/sagernet/cloudflare-tls v0.0.0-20231208171750-a4483c1b7cd1/go.mod h1:J2yAxTFPDjrDPhuAi9aWFz2L3ox9it4qAluBBbN0H5k=
|
||||
github.com/sagernet/gvisor v0.0.0-20240428053021-e691de28565f h1:NkhuupzH5ch7b/Y/6ZHJWrnNLoiNnSJaow6DPb8VW2I=
|
||||
github.com/sagernet/gvisor v0.0.0-20240428053021-e691de28565f/go.mod h1:KXmw+ouSJNOsuRpg4wgwwCQuunrGz4yoAqQjsLjc6N0=
|
||||
github.com/sagernet/netlink v0.0.0-20240523065131-45e60152f9ba h1:EY5AS7CCtfmARNv2zXUOrsEMPFDGYxaw65JzA2p51Vk=
|
||||
github.com/sagernet/netlink v0.0.0-20240523065131-45e60152f9ba/go.mod h1:xLnfdiJbSp8rNqYEdIW/6eDO4mVoogml14Bh2hSiFpM=
|
||||
github.com/sagernet/quic-go v0.47.0-beta.2 h1:1tCGWFOSaXIeuQaHrwOMJIYvlupjTcaVInGQw5ArULU=
|
||||
github.com/sagernet/quic-go v0.47.0-beta.2/go.mod h1:bLVKvElSEMNv7pu7SZHscW02TYigzQ5lQu3Nh4wNh8Q=
|
||||
github.com/sagernet/reality v0.0.0-20230406110435-ee17307e7691 h1:5Th31OC6yj8byLGkEnIYp6grlXfo1QYUfiYFGjewIdc=
|
||||
github.com/sagernet/reality v0.0.0-20230406110435-ee17307e7691/go.mod h1:B8lp4WkQ1PwNnrVMM6KyuFR20pU8jYBD+A4EhJovEXU=
|
||||
github.com/sagernet/sing v0.0.0-20220817130738-ce854cda8522/go.mod h1:QVsS5L/ZA2Q5UhQwLrn0Trw+msNd/NPGEhBKR/ioWiY=
|
||||
github.com/sagernet/sing v0.1.8/go.mod h1:jt1w2u7lJQFFSGLiRrRIs5YWmx4kAPfWuOejuDW9qMk=
|
||||
github.com/sagernet/sing v0.2.14-0.20231011041941-e4d9384bcd84 h1:bPpV5QTOm6s9oJUCdfInImOgsWueoZWaJ7IpRkZuEsk=
|
||||
github.com/sagernet/sing v0.2.14-0.20231011041941-e4d9384bcd84/go.mod h1:AhNEHu0GXrpqkuzvTwvC8+j2cQUU/dh+zLEmq4C99pg=
|
||||
github.com/sagernet/sing-dns v0.1.10 h1:iIU7nRBlUYj+fF2TaktGIvRiTFFrHwSMedLQsvlTZCI=
|
||||
github.com/sagernet/sing-dns v0.1.10/go.mod h1:vtUimtf7Nq9EdvD5WTpfCr69KL1M7bcgOVKiYBiAY/c=
|
||||
github.com/sagernet/sing-mux v0.1.3 h1:fAf7PZa2A55mCeh0KKM02f1k2Y4vEmxuZZ/51ahkkLA=
|
||||
github.com/sagernet/sing-mux v0.1.3/go.mod h1:wGeIeiiFLx4HUM5LAg65wrNZ/X1muOimqK0PEhNbPi0=
|
||||
github.com/sagernet/sing-quic v0.1.3-0.20231011042217-13b8d0b8f74b h1:u95u1icfN2Ya7FTkuWfyNrC4llMn8AYwD+ZsGkVWkac=
|
||||
github.com/sagernet/sing-quic v0.1.3-0.20231011042217-13b8d0b8f74b/go.mod h1:1M7xP4802K9Kz6BQ7LlA7UeCapWvWlH1Htmk2bAqkWc=
|
||||
github.com/sagernet/sing-shadowsocks v0.2.5 h1:qxIttos4xu6ii7MTVJYA8EFQR7Q3KG6xMqmLJIFtBaY=
|
||||
github.com/sagernet/sing-shadowsocks v0.2.5/go.mod h1:MGWGkcU2xW2G2mfArT9/QqpVLOGU+dBaahZCtPHdt7A=
|
||||
github.com/sagernet/sing-shadowsocks2 v0.1.4 h1:vht2M8t3m5DTgXR2j24KbYOygG5aOp+MUhpQnAux728=
|
||||
github.com/sagernet/sing-shadowsocks2 v0.1.4/go.mod h1:Mgdee99NxxNd5Zld3ixIs18yVs4x2dI2VTDDE1N14Wc=
|
||||
github.com/sagernet/sing v0.2.18/go.mod h1:OL6k2F0vHmEzXz2KW19qQzu172FDgSbUSODylighuVo=
|
||||
github.com/sagernet/sing v0.4.3 h1:Ty/NAiNnVd6844k7ujlL5lkzydhcTH5Psc432jXA4Y8=
|
||||
github.com/sagernet/sing v0.4.3/go.mod h1:ieZHA/+Y9YZfXs2I3WtuwgyCZ6GPsIR7HdKb1SdEnls=
|
||||
github.com/sagernet/sing-dns v0.2.3 h1:YzeBUn2tR38F7HtvGEQ0kLRLmZWMEgi/+7wqa4Twb1k=
|
||||
github.com/sagernet/sing-dns v0.2.3/go.mod h1:BJpJv6XLnrUbSyIntOT6DG9FW0f4fETmPAHvNjOprLg=
|
||||
github.com/sagernet/sing-mux v0.2.0 h1:4C+vd8HztJCWNYfufvgL49xaOoOHXty2+EAjnzN3IYo=
|
||||
github.com/sagernet/sing-mux v0.2.0/go.mod h1:khzr9AOPocLa+g53dBplwNDz4gdsyx/YM3swtAhlkHQ=
|
||||
github.com/sagernet/sing-shadowsocks v0.2.7 h1:zaopR1tbHEw5Nk6FAkM05wCslV6ahVegEZaKMv9ipx8=
|
||||
github.com/sagernet/sing-shadowsocks v0.2.7/go.mod h1:0rIKJZBR65Qi0zwdKezt4s57y/Tl1ofkaq6NlkzVuyE=
|
||||
github.com/sagernet/sing-shadowsocks2 v0.2.0 h1:wpZNs6wKnR7mh1wV9OHwOyUr21VkS3wKFHi+8XwgADg=
|
||||
github.com/sagernet/sing-shadowsocks2 v0.2.0/go.mod h1:RnXS0lExcDAovvDeniJ4IKa2IuChrdipolPYWBv9hWQ=
|
||||
github.com/sagernet/sing-shadowtls v0.1.4 h1:aTgBSJEgnumzFenPvc+kbD9/W0PywzWevnVpEx6Tw3k=
|
||||
github.com/sagernet/sing-shadowtls v0.1.4/go.mod h1:F8NBgsY5YN2beQavdgdm1DPlhaKQlaL6lpDdcBglGK4=
|
||||
github.com/sagernet/sing-tun v0.1.16-0.20231006112722-19cc8b9e81aa h1:lQVFeYJ916CXunKB3JrsOQqCtT16OAitMXw8Z0lRNvY=
|
||||
github.com/sagernet/sing-tun v0.1.16-0.20231006112722-19cc8b9e81aa/go.mod h1:d5kKDDW3I8Tr1OSWNaHXzrnsg1LbOx9sYVx83cHPhm8=
|
||||
github.com/sagernet/sing-vmess v0.1.8 h1:XVWad1RpTy9b5tPxdm5MCU8cGfrTGdR8qCq6HV2aCNc=
|
||||
github.com/sagernet/sing-vmess v0.1.8/go.mod h1:vhx32UNzTDUkNwOyIjcZQohre1CaytquC5mPplId8uA=
|
||||
github.com/sagernet/smux v0.0.0-20230312102458-337ec2a5af37 h1:HuE6xSwco/Xed8ajZ+coeYLmioq0Qp1/Z2zczFaV8as=
|
||||
github.com/sagernet/smux v0.0.0-20230312102458-337ec2a5af37/go.mod h1:3skNSftZDJWTGVtVaM2jfbce8qHnmH/AGDRe62iNOg0=
|
||||
github.com/sagernet/tfo-go v0.0.0-20230816093905-5a5c285d44a6 h1:Px+hN4Vzgx+iCGVnWH5A8eR7JhNnIV3rGQmBxA7cw6Q=
|
||||
github.com/sagernet/tfo-go v0.0.0-20230816093905-5a5c285d44a6/go.mod h1:zovq6vTvEM6ECiqE3Eeb9rpIylPpamPcmrJ9tv0Bt0M=
|
||||
github.com/sagernet/utls v0.0.0-20230309024959-6732c2ab36f2 h1:kDUqhc9Vsk5HJuhfIATJ8oQwBmpOZJuozQG7Vk88lL4=
|
||||
github.com/sagernet/utls v0.0.0-20230309024959-6732c2ab36f2/go.mod h1:JKQMZq/O2qnZjdrt+B57olmfgEmLtY9iiSIEYtWvoSM=
|
||||
github.com/sagernet/websocket v0.0.0-20220913015213-615516348b4e h1:7uw2njHFGE+VpWamge6o56j2RWk4omF6uLKKxMmcWvs=
|
||||
github.com/sagernet/websocket v0.0.0-20220913015213-615516348b4e/go.mod h1:45TUl8+gH4SIKr4ykREbxKWTxkDlSzFENzctB1dVRRY=
|
||||
github.com/sagernet/wireguard-go v0.0.0-20230807125731-5d4a7ef2dc5f h1:Kvo8w8Y9lzFGB/7z09MJ3TR99TFtfI/IuY87Ygcycho=
|
||||
github.com/sagernet/wireguard-go v0.0.0-20230807125731-5d4a7ef2dc5f/go.mod h1:mySs0abhpc/gLlvhoq7HP1RzOaRmIXVeZGCh++zoApk=
|
||||
github.com/scjalliance/comshim v0.0.0-20230315213746-5e51f40bd3b9 h1:rc/CcqLH3lh8n+csdOuDfP+NuykE0U6AeYSJJHKDgSg=
|
||||
github.com/scjalliance/comshim v0.0.0-20230315213746-5e51f40bd3b9/go.mod h1:a/83NAfUXvEuLpmxDssAXxgUgrEy12MId3Wd7OTs76s=
|
||||
github.com/sagernet/sing-tun v0.3.3 h1:LZnQNmfGcNG2KPTPkLgc+Lo7k606QJVkPp2DnjriwUk=
|
||||
github.com/sagernet/sing-tun v0.3.3/go.mod h1:DxLIyhjWU/HwGYoX0vNGg2c5QgTQIakphU1MuERR5tQ=
|
||||
github.com/sagernet/sing-vmess v0.1.12 h1:2gFD8JJb+eTFMoa8FIVMnknEi+vCSfaiTXTfEYAYAPg=
|
||||
github.com/sagernet/sing-vmess v0.1.12/go.mod h1:luTSsfyBGAc9VhtCqwjR+dt1QgqBhuYBCONB/POhF8I=
|
||||
github.com/sagernet/smux v0.0.0-20231208180855-7041f6ea79e7 h1:DImB4lELfQhplLTxeq2z31Fpv8CQqqrUwTbrIRumZqQ=
|
||||
github.com/sagernet/smux v0.0.0-20231208180855-7041f6ea79e7/go.mod h1:FP9X2xjT/Az1EsG/orYYoC+5MojWnuI7hrffz8fGwwo=
|
||||
github.com/sagernet/utls v1.5.4 h1:KmsEGbB2dKUtCNC+44NwAdNAqnqQ6GA4pTO0Yik56co=
|
||||
github.com/sagernet/utls v1.5.4/go.mod h1:CTGxPWExIloRipK3XFpYv0OVyhO8kk3XCGW/ieyTh1s=
|
||||
github.com/sagernet/wireguard-go v0.0.0-20231215174105-89dec3b2f3e8 h1:R0OMYAScomNAVpTfbHFpxqJpvwuhxSRi+g6z7gZhABs=
|
||||
github.com/sagernet/wireguard-go v0.0.0-20231215174105-89dec3b2f3e8/go.mod h1:K4J7/npM+VAMUeUmTa2JaA02JmyheP0GpRBOUvn3ecc=
|
||||
github.com/sagernet/ws v0.0.0-20231204124109-acfe8907c854 h1:6uUiZcDRnZSAegryaUGwPC/Fj13JSHwiTftrXhMmYOc=
|
||||
github.com/sagernet/ws v0.0.0-20231204124109-acfe8907c854/go.mod h1:LtfoSK3+NG57tvnVEHgcuBW9ujgE8enPSgzgwStwCAA=
|
||||
github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE=
|
||||
github.com/spf13/cobra v1.7.0 h1:hyqWnYt1ZQShIddO5kBpj3vu05/++x6tJ6dg8EC572I=
|
||||
github.com/spf13/cobra v1.7.0/go.mod h1:uLxZILRyS/50WlhOIKD7W6V5bgeIt+4sICxh6uRMrb0=
|
||||
github.com/spf13/cobra v1.8.0 h1:7aJaZx1B85qltLMc546zn58BxxfZdR/W22ej9CFoEf0=
|
||||
github.com/spf13/cobra v1.8.0/go.mod h1:WXLWApfZ71AjXPya3WOlMsY9yMs7YeiHhFVlvLyhcho=
|
||||
github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA=
|
||||
github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
|
||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
@ -178,7 +168,7 @@ github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UV
|
||||
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/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk=
|
||||
github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg=
|
||||
github.com/u-root/uio v0.0.0-20230220225925-ffce2a382923 h1:tHNk7XK9GkmKUR6Gh8gVBKXc2MVSZ4G/NnWLtzw4gNA=
|
||||
github.com/u-root/uio v0.0.0-20230220225925-ffce2a382923/go.mod h1:eLL9Nub3yfAho7qB0MzZizFhTU2QkLeoVsWdHtDW264=
|
||||
github.com/vishvananda/netns v0.0.0-20211101163701-50045581ed74 h1:gga7acRE695APm9hlsSMoOoE65U4/TcqNj90mc69Rlg=
|
||||
@ -192,32 +182,32 @@ github.com/zeebo/blake3 v0.2.3/go.mod h1:mjJjZpnsyIVtVgTOSpJ9vmRE4wgDeyt2HU3qXvv
|
||||
github.com/zeebo/pcg v1.0.1 h1:lyqfGeWiv4ahac6ttHs+I5hwtH/+1mrhlCtVNQM2kHo=
|
||||
github.com/zeebo/pcg v1.0.1/go.mod h1:09F0S9iiKrwn9rlI5yjLkmrug154/YRW6KnnXVDM/l4=
|
||||
go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE=
|
||||
go.uber.org/goleak v1.2.0 h1:xqgm/S+aQvhWFTtR0XK3Jvg7z8kGV8P4X14IzwN3Eqk=
|
||||
go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto=
|
||||
go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0=
|
||||
go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0=
|
||||
go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y=
|
||||
go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q=
|
||||
go.uber.org/zap v1.26.0 h1:sI7k6L95XOKS281NhVKOFCUNIvv9e0w4BF8N3u+tCRo=
|
||||
go.uber.org/zap v1.26.0/go.mod h1:dtElttAiwGvoJ/vj4IwHBS/gXsEu/pZ50mUIRWuG0so=
|
||||
go4.org/netipx v0.0.0-20230824141953-6213f710f925 h1:eeQDDVKFkx0g4Hyy8pHgmZaK0EqB4SD6rvKbUdN3ziQ=
|
||||
go4.org/netipx v0.0.0-20230824141953-6213f710f925/go.mod h1:PLyyIXexvUFg3Owu6p/WfdlivPbZJsZdgWZlrGope/Y=
|
||||
go.uber.org/zap v1.27.0 h1:aJMhYGrd5QSmlpLMr2MftRKl7t8J8PTZPA732ud/XR8=
|
||||
go.uber.org/zap v1.27.0/go.mod h1:GB2qFLM7cTU87MWRP2mPIjqfIDnGu+VIO4V/SdhGo2E=
|
||||
go4.org/netipx v0.0.0-20231129151722-fdeea329fbba h1:0b9z3AuHCjxk0x/opv64kcgZLBseWJUpBw5I82+2U4M=
|
||||
go4.org/netipx v0.0.0-20231129151722-fdeea329fbba/go.mod h1:PLyyIXexvUFg3Owu6p/WfdlivPbZJsZdgWZlrGope/Y=
|
||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||
golang.org/x/crypto v0.0.0-20190404164418-38d8ce5564a5/go.mod h1:WFFai1msRO1wXaEeE5yQxYXgSfI8pQAWXbQop6sCtWE=
|
||||
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-20210513164829-c07d793c2f9a/go.mod h1:P+XmwS30IXTQdn5tA2iutPOUgjI07+tq3H3K9MVA1s8=
|
||||
golang.org/x/crypto v0.14.0 h1:wBqGXzWJW6m1XrIKlAH0Hs1JJ7+9KBwnIO8v66Q9cHc=
|
||||
golang.org/x/crypto v0.14.0/go.mod h1:MVFd36DqK4CsrnJYDkBA3VC4m2GkXAM0PvzMCn4JQf4=
|
||||
golang.org/x/crypto v0.23.0 h1:dIJU/v2J8Mdglj/8rJ6UUOM3Zc9zLZxVZwwxMooUSAI=
|
||||
golang.org/x/crypto v0.23.0/go.mod h1:CKFgDieR+mRhux2Lsu27y0fO304Db0wZe70UKqHu0v8=
|
||||
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||
golang.org/x/exp v0.0.0-20231005195138-3e424a577f31 h1:9k5exFQKQglLo+RoP+4zMjOFE14P6+vyR0baDAi0Rcs=
|
||||
golang.org/x/exp v0.0.0-20231005195138-3e424a577f31/go.mod h1:S2oDrQGGwySpoQPVqRShND87VCbxmc6bL1Yd2oYrm6k=
|
||||
golang.org/x/exp v0.0.0-20240416160154-fe59bbe5cc7f h1:99ci1mjWVBWwJiEKYY6jWa4d2nTQVIEhZIptnrVb1XY=
|
||||
golang.org/x/exp v0.0.0-20240416160154-fe59bbe5cc7f/go.mod h1:/lliqkxwWAhPjf5oSOIJup2XcqJaw8RGS6k3TGEc7GI=
|
||||
golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
|
||||
golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU=
|
||||
golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
|
||||
golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||
golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||
golang.org/x/mod v0.12.0 h1:rmsUpXtvNzj340zd98LZ4KntptpfRHwpFOHG188oHXc=
|
||||
golang.org/x/mod v0.12.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
|
||||
golang.org/x/mod v0.18.0 h1:5+9lSbEzPSdWkH32vYPBwEpX8KwDbM52Ud9xBUvNlb0=
|
||||
golang.org/x/mod v0.18.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c=
|
||||
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
@ -228,42 +218,42 @@ golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLL
|
||||
golang.org/x/net v0.0.0-20201021035429-f5854403a974/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-20210525063256-abc453219eb5/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
||||
golang.org/x/net v0.16.0 h1:7eBu7KsSvFDtSXUIDbh3aqlK4DPsZ1rByC8PFfBThos=
|
||||
golang.org/x/net v0.16.0/go.mod h1:NxSsAGuq816PNPmqtQdLE42eU2Fs7NoRIZrHJAlaCOE=
|
||||
golang.org/x/net v0.25.0 h1:d/OCCoBEUq33pjydKrGQhw7IlUPI2Oylr+8qLx49kac=
|
||||
golang.org/x/net v0.25.0/go.mod h1:JkAGAh7GEvH74S6FOH42FLoXpXbE/aqXSrIQjXgsiwM=
|
||||
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
||||
golang.org/x/oauth2 v0.10.0 h1:zHCpF2Khkwy4mMB4bv0U37YtJdTGW8jI0glAApi0Kh8=
|
||||
golang.org/x/oauth2 v0.17.0 h1:6m3ZPmLEFdVxKKWnKq4VqZ60gutO35zm+zrAHVmHyDQ=
|
||||
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.3.0 h1:ftCYgMx6zT/asHUrPw8BLLscYtGznsLAnjq5RH9P66E=
|
||||
golang.org/x/sync v0.8.0 h1:3NFvSEYkUoMifnESzZl15y791HH1qU2xm6eCJU5ZPXQ=
|
||||
golang.org/x/sync v0.8.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
|
||||
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190403152447-81d4e9dc473e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200217220822-9197077df867/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20220622161953-175b2fd9d664/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220731174439-a90be440212d/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220908164124-27713097b956/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.13.0 h1:Af8nKPmuFypiUBjVoU9V20FiaFXOcuZI21p0ycVYYGE=
|
||||
golang.org/x/sys v0.13.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.14.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||
golang.org/x/sys v0.25.0 h1:r+8e+loiHxRqhXVl6ML1nO3l1+oFoWbnlu2Ehimmi34=
|
||||
golang.org/x/sys v0.25.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||
golang.org/x/term v0.13.0 h1:bb+I9cTfFazGW51MZqBVmZy7+JEJMouUHTUSKVQLBek=
|
||||
golang.org/x/term v0.20.0 h1:VnkxpohqXaOBYJtBmEppKUG6mXpi+4O6purfc2+sMhw=
|
||||
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=
|
||||
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/text v0.13.0 h1:ablQoSUd0tRdKxZewP80B+BaqeKJuVhuRxj/dkrun3k=
|
||||
golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=
|
||||
golang.org/x/time v0.3.0 h1:rg5rLMjNzMS1RkNLzCG38eapWhnYLFYXDXj2gOlr8j4=
|
||||
golang.org/x/time v0.3.0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
golang.org/x/text v0.18.0 h1:XvMDiNzPAl0jr17s6W9lcaIhGUfUORdGCNsuLmPG224=
|
||||
golang.org/x/text v0.18.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY=
|
||||
golang.org/x/time v0.5.0 h1:o7cqy6amK/52YcAKIPlM3a+Fpj35zvRj2TP+e1xFSfk=
|
||||
golang.org/x/time v0.5.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM=
|
||||
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY=
|
||||
@ -272,8 +262,8 @@ golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBn
|
||||
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
|
||||
golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
|
||||
golang.org/x/tools v0.13.0 h1:Iey4qkscZuv0VvIt8E0neZjtPVQFSc870HQ448QgEmQ=
|
||||
golang.org/x/tools v0.13.0/go.mod h1:HvlwmtVNQAhOuCjW7xxvovg8wbNq7LwfXh/k7wXUl58=
|
||||
golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d h1:vU5i/LfpvrRCpgM/VPfJLg5KjxD3E+hfT1SH+d9zLwg=
|
||||
golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d/go.mod h1:aiJjzUbINMkxbQROHiO6hDPo2LHcIPhhQsa9DLh0yGk=
|
||||
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=
|
||||
@ -282,23 +272,21 @@ golang.zx2c4.com/wireguard/wgctrl v0.0.0-20230429144221-925a1e7659e6 h1:CawjfCvY
|
||||
golang.zx2c4.com/wireguard/wgctrl v0.0.0-20230429144221-925a1e7659e6/go.mod h1:3rxYc4HtVcSG9gVaTs2GEBdehh+sYPOwKtyUWEOTb80=
|
||||
google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
|
||||
google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
|
||||
google.golang.org/appengine v1.6.7 h1:FZR1q0exgwxzPzp/aF+VccGrSfxfPpkBqjIIEq3ru6c=
|
||||
google.golang.org/appengine v1.6.8 h1:IhEN5q69dyKagZPYMSdIjS2HqprW324FRQZJcGqPAsM=
|
||||
google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
|
||||
google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc=
|
||||
google.golang.org/genproto v0.0.0-20200423170343-7949de9c1215/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20230711160842-782d3b101e98 h1:bVf09lpb+OJbByTj913DRJioFFAjf/ZGxEz7MajTp2U=
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20230711160842-782d3b101e98/go.mod h1:TUfxEVdsvPg18p6AslUXFoLdpED4oBnGwyqk3dV1XzM=
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20240227224415-6ceb2ff114de h1:cZGRis4/ot9uVm639a+rHCUaG0JJHEsdyzSQTMX+suY=
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20240227224415-6ceb2ff114de/go.mod h1:H4O17MA/PE9BsGx3w+a+W2VOLLD1Qf7oJneAoU6WktY=
|
||||
google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
|
||||
google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg=
|
||||
google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY=
|
||||
google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
|
||||
google.golang.org/grpc v1.29.1/go.mod h1:itym6AZVZYACWQqET3MqgPpjcuV5QH3BxFS3IjizoKk=
|
||||
google.golang.org/grpc v1.58.2 h1:SXUpjxeVF3FKrTYQI4f4KvbGD5u2xccdYdurwowix5I=
|
||||
google.golang.org/grpc v1.58.2/go.mod h1:tgX3ZQDlNJGU96V6yHh1T/JeoBQ2TXdr43YbYSsCJk0=
|
||||
google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
|
||||
google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
|
||||
google.golang.org/protobuf v1.31.0 h1:g0LDEJHgrBl9N9r17Ru3sqWhkIx2NB67okBHPwC7hs8=
|
||||
google.golang.org/protobuf v1.31.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
|
||||
google.golang.org/grpc v1.63.2 h1:MUeiw1B2maTVZthpU5xvASfTh3LDbxHd6IJ6QQVU+xM=
|
||||
google.golang.org/grpc v1.63.2/go.mod h1:WAX/8DgncnokcFUldAxq7GeB5DXHDbMF+lLvDomNkRA=
|
||||
google.golang.org/protobuf v1.33.0 h1:uNO2rsAINq/JlFpSdYEKIZ0uKD/R9cpdv0T+yoGwGmI=
|
||||
google.golang.org/protobuf v1.33.0/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
@ -306,5 +294,5 @@ gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
||||
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
||||
honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
||||
lukechampine.com/blake3 v1.2.1 h1:YuqqRuaqsGV71BV/nm9xlI0MKUv4QC54jQnBChWbGnI=
|
||||
lukechampine.com/blake3 v1.2.1/go.mod h1:0OFRp7fBtAylGVCO40o87sbupkyIGgbpv1+M1k1LM6k=
|
||||
lukechampine.com/blake3 v1.3.0 h1:sJ3XhFINmHSrYCgl958hscfIa3bw8x4DqMP3u1YvoYE=
|
||||
lukechampine.com/blake3 v1.3.0/go.mod h1:0OFRp7fBtAylGVCO40o87sbupkyIGgbpv1+M1k1LM6k=
|
||||
|
||||
@ -4,7 +4,6 @@ import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"grpc_server"
|
||||
"grpc_server/gen"
|
||||
@ -12,9 +11,9 @@ import (
|
||||
"github.com/matsuridayo/libneko/neko_common"
|
||||
"github.com/matsuridayo/libneko/neko_log"
|
||||
"github.com/matsuridayo/libneko/speedtest"
|
||||
"github.com/matsuridayo/sing-box-extra/boxapi"
|
||||
"github.com/matsuridayo/sing-box-extra/boxbox"
|
||||
"github.com/matsuridayo/sing-box-extra/boxmain"
|
||||
box "github.com/sagernet/sing-box"
|
||||
"github.com/sagernet/sing-box/boxapi"
|
||||
boxmain "github.com/sagernet/sing-box/cmd/sing-box"
|
||||
|
||||
"log"
|
||||
|
||||
@ -76,7 +75,8 @@ func (s *server) Stop(ctx context.Context, in *gen.EmptyReq) (out *gen.ErrorResp
|
||||
return
|
||||
}
|
||||
|
||||
instance.CloseWithTimeout(instance_cancel, time.Second*2, log.Println)
|
||||
instance_cancel()
|
||||
instance.Close()
|
||||
|
||||
instance = nil
|
||||
|
||||
@ -94,7 +94,7 @@ func (s *server) Test(ctx context.Context, in *gen.TestReq) (out *gen.TestResp,
|
||||
}()
|
||||
|
||||
if in.Mode == gen.TestMode_UrlTest {
|
||||
var i *boxbox.Box
|
||||
var i *box.Box
|
||||
var cancel context.CancelFunc
|
||||
if in.Config != nil {
|
||||
// Test instance
|
||||
@ -114,7 +114,7 @@ func (s *server) Test(ctx context.Context, in *gen.TestReq) (out *gen.TestResp,
|
||||
}
|
||||
}
|
||||
// Latency
|
||||
out.Ms, err = speedtest.UrlTest(boxapi.CreateProxyHttpClient(i), in.Url, in.Timeout)
|
||||
out.Ms, err = speedtest.UrlTest(boxapi.CreateProxyHttpClient(i), in.Url, in.Timeout, speedtest.UrlTestStandard_RTT)
|
||||
} else if in.Mode == gen.TestMode_TcpPing {
|
||||
out.Ms, err = speedtest.TcpPing(in.Address, in.Timeout)
|
||||
} else if in.Mode == gen.TestMode_FullTest {
|
||||
|
||||
@ -8,13 +8,12 @@ import (
|
||||
"grpc_server"
|
||||
|
||||
"github.com/matsuridayo/libneko/neko_common"
|
||||
"github.com/matsuridayo/sing-box-extra/boxbox"
|
||||
"github.com/matsuridayo/sing-box-extra/boxmain"
|
||||
_ "github.com/matsuridayo/sing-box-extra/distro/all"
|
||||
boxmain "github.com/sagernet/sing-box/cmd/sing-box"
|
||||
"github.com/sagernet/sing-box/constant"
|
||||
)
|
||||
|
||||
func main() {
|
||||
fmt.Println("sing-box-extra:", boxbox.Version, "NekoBox:", neko_common.Version_neko)
|
||||
fmt.Println("sing-box:", constant.Version, "NekoBox:", neko_common.Version_neko)
|
||||
fmt.Println()
|
||||
|
||||
// nekobox_core
|
||||
|
||||
@ -1,122 +0,0 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"log"
|
||||
"net"
|
||||
"net/http"
|
||||
"os"
|
||||
"time"
|
||||
|
||||
"github.com/matsuridayo/libneko/neko_common"
|
||||
"github.com/matsuridayo/libneko/neko_log"
|
||||
|
||||
appLog "github.com/xtls/xray-core/app/log"
|
||||
commonLog "github.com/xtls/xray-core/common/log"
|
||||
v2rayNet "github.com/xtls/xray-core/common/net"
|
||||
core "github.com/xtls/xray-core/core"
|
||||
"github.com/xtls/xray-core/features/dns"
|
||||
)
|
||||
|
||||
var instance *NekoV2RayInstance
|
||||
var getNekorayTunIndex = func() int { return 0 } // Windows only
|
||||
var underlyingNetDialer *net.Dialer
|
||||
|
||||
type v2rayLogWriter struct {
|
||||
}
|
||||
|
||||
func (w *v2rayLogWriter) Write(s string) error {
|
||||
log.Print(s)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (w *v2rayLogWriter) Close() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func setupCore() {
|
||||
// core setup
|
||||
os.Setenv("v2ray.conf.geoloader", "memconservative")
|
||||
neko_log.SetupLog(50*1024, "./neko.log")
|
||||
_ = appLog.RegisterHandlerCreator(appLog.LogType_Console, func(lt appLog.LogType, options appLog.HandlerCreatorOptions) (commonLog.Handler, error) {
|
||||
return commonLog.NewLogger(func() commonLog.Writer {
|
||||
return &v2rayLogWriter{}
|
||||
}), nil
|
||||
})
|
||||
// localdns setup
|
||||
resolver_def := &net.Resolver{PreferGo: false}
|
||||
resolver_go := &net.Resolver{PreferGo: true}
|
||||
if underlyingNetDialer != nil && os.Getenv("NKR_CORE_RAY_DIRECT_DNS") == "1" {
|
||||
resolver_def.Dial = underlyingNetDialer.DialContext
|
||||
resolver_go.Dial = underlyingNetDialer.DialContext
|
||||
log.Println("using NKR_CORE_RAY_DIRECT_DNS")
|
||||
}
|
||||
v2rayNet.LookupIP = func(host string) (ips []net.IP, err error) {
|
||||
// fix old sekai
|
||||
defer func() {
|
||||
if len(ips) == 0 {
|
||||
log.Println("LookupIP error:", host, err)
|
||||
err = dns.ErrEmptyResponse
|
||||
}
|
||||
}()
|
||||
// Normal mode use system resolver (go bug)
|
||||
if getNekorayTunIndex() == 0 {
|
||||
return resolver_def.LookupIP(context.Background(), "ip", host)
|
||||
}
|
||||
// Windows Tun Mode use Go resolver
|
||||
return resolver_go.LookupIP(context.Background(), "ip", host)
|
||||
}
|
||||
neko_common.GetCurrentInstance = func() interface{} {
|
||||
return instance
|
||||
}
|
||||
neko_common.DialContext = func(ctx context.Context, specifiedInstance interface{}, network, addr string) (net.Conn, error) {
|
||||
dest, err := v2rayNet.ParseDestination(fmt.Sprintf("%s:%s", network, addr))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if i, ok := specifiedInstance.(*NekoV2RayInstance); ok {
|
||||
return core.Dial(ctx, i.Instance, dest)
|
||||
}
|
||||
if instance != nil {
|
||||
return core.Dial(ctx, instance.Instance, dest)
|
||||
}
|
||||
return neko_common.DialContextSystem(ctx, network, addr)
|
||||
}
|
||||
neko_common.DialUDP = func(ctx context.Context, specifiedInstance interface{}) (net.PacketConn, error) {
|
||||
if i, ok := specifiedInstance.(*NekoV2RayInstance); ok {
|
||||
return core.DialUDP(ctx, i.Instance)
|
||||
}
|
||||
if instance != nil {
|
||||
return core.DialUDP(ctx, instance.Instance)
|
||||
}
|
||||
return neko_common.DialUDPSystem(ctx)
|
||||
}
|
||||
neko_common.CreateProxyHttpClient = func(specifiedInstance interface{}) *http.Client {
|
||||
if i, ok := specifiedInstance.(*NekoV2RayInstance); ok {
|
||||
return createProxyHttpClient(i)
|
||||
}
|
||||
return createProxyHttpClient(instance)
|
||||
}
|
||||
}
|
||||
|
||||
// PROXY
|
||||
|
||||
func createProxyHttpClient(i *NekoV2RayInstance) *http.Client {
|
||||
transport := &http.Transport{
|
||||
TLSHandshakeTimeout: time.Second * 3,
|
||||
ResponseHeaderTimeout: time.Second * 3,
|
||||
}
|
||||
|
||||
if i != nil {
|
||||
transport.DialContext = func(ctx context.Context, network, addr string) (net.Conn, error) {
|
||||
return neko_common.DialContext(ctx, i, network, addr)
|
||||
}
|
||||
}
|
||||
|
||||
client := &http.Client{
|
||||
Transport: transport,
|
||||
}
|
||||
|
||||
return client
|
||||
}
|
||||
@ -1,74 +0,0 @@
|
||||
module nekoray_core
|
||||
|
||||
go 1.21
|
||||
|
||||
toolchain go1.21.0
|
||||
|
||||
require (
|
||||
github.com/jsimonetti/rtnetlink v1.2.2
|
||||
github.com/matsuridayo/libneko v1.0.0 // replaced
|
||||
github.com/xtls/xray-core v1.0.0 // replaced
|
||||
grpc_server v1.0.0
|
||||
kernel.org/pub/linux/libs/security/libcap/cap v1.2.65
|
||||
)
|
||||
|
||||
require (
|
||||
cloud.google.com/go/compute/metadata v0.2.3 // indirect
|
||||
github.com/aead/chacha20 v0.0.0-20180709150244-8b13a72661da // indirect
|
||||
github.com/andybalholm/brotli v1.0.5 // indirect
|
||||
github.com/dgryski/go-metro v0.0.0-20211217172704-adc40b04c140 // indirect
|
||||
github.com/francoispqt/gojay v1.2.13 // indirect
|
||||
github.com/gaukas/godicttls v0.0.4 // indirect
|
||||
github.com/ghodss/yaml v1.0.1-0.20220118164431-d8423dcdf344 // indirect
|
||||
github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 // indirect
|
||||
github.com/golang/mock v1.6.0 // indirect
|
||||
github.com/golang/protobuf v1.5.3 // indirect
|
||||
github.com/google/btree v1.1.2 // indirect
|
||||
github.com/google/go-cmp v0.5.9 // indirect
|
||||
github.com/google/pprof v0.0.0-20230821062121-407c9e7a662f // indirect
|
||||
github.com/gorilla/websocket v1.5.0 // indirect
|
||||
github.com/grpc-ecosystem/go-grpc-middleware v1.3.0 // indirect
|
||||
github.com/josharian/native v1.0.0 // indirect
|
||||
github.com/klauspost/compress v1.16.7 // indirect
|
||||
github.com/klauspost/cpuid/v2 v2.2.5 // indirect
|
||||
github.com/mdlayher/netlink v1.6.0 // indirect
|
||||
github.com/mdlayher/socket v0.1.1 // indirect
|
||||
github.com/onsi/ginkgo/v2 v2.12.0 // indirect
|
||||
github.com/pelletier/go-toml v1.9.5 // indirect
|
||||
github.com/pires/go-proxyproto v0.7.0 // indirect
|
||||
github.com/quic-go/qtls-go1-20 v0.3.3 // indirect
|
||||
github.com/quic-go/quic-go v0.38.1 // indirect
|
||||
github.com/refraction-networking/utls v1.4.3 // indirect
|
||||
github.com/riobard/go-bloom v0.0.0-20200614022211-cdc8013cb5b3 // indirect
|
||||
github.com/sagernet/sing v0.2.9 // indirect
|
||||
github.com/sagernet/sing-shadowsocks v0.2.4 // indirect
|
||||
github.com/sagernet/wireguard-go v0.0.0-20221116151939-c99467f53f2c // indirect
|
||||
github.com/seiflotfy/cuckoofilter v0.0.0-20220411075957-e3b120b3f5fb // indirect
|
||||
github.com/v2fly/ss-bloomring v0.0.0-20210312155135-28617310f63e // indirect
|
||||
github.com/xtls/reality v0.0.0-20230828171259-e426190d57f6 // indirect
|
||||
go.uber.org/atomic v1.11.0 // indirect
|
||||
go4.org/netipx v0.0.0-20230824141953-6213f710f925 // indirect
|
||||
golang.org/x/crypto v0.12.0 // indirect
|
||||
golang.org/x/exp v0.0.0-20230725093048-515e97ebf090 // indirect
|
||||
golang.org/x/mod v0.12.0 // indirect
|
||||
golang.org/x/net v0.14.0 // indirect
|
||||
golang.org/x/sync v0.3.0 // indirect
|
||||
golang.org/x/sys v0.11.0 // indirect
|
||||
golang.org/x/text v0.12.0 // indirect
|
||||
golang.org/x/time v0.3.0 // indirect
|
||||
golang.org/x/tools v0.12.0 // indirect
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20230822172742-b8732ec3820d // indirect
|
||||
google.golang.org/grpc v1.57.0 // indirect
|
||||
google.golang.org/protobuf v1.31.0 // indirect
|
||||
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 // indirect
|
||||
gopkg.in/yaml.v2 v2.4.0 // indirect
|
||||
gvisor.dev/gvisor v0.0.0-20230822212503-5bf4e5f98744 // indirect
|
||||
kernel.org/pub/linux/libs/security/libcap/psx v1.2.65 // indirect
|
||||
lukechampine.com/blake3 v1.2.1 // indirect
|
||||
)
|
||||
|
||||
replace github.com/matsuridayo/libneko v1.0.0 => ../../../../libneko
|
||||
|
||||
replace grpc_server v1.0.0 => ../../grpc_server
|
||||
|
||||
replace github.com/xtls/xray-core => ../../../../Xray-core
|
||||
@ -1,394 +0,0 @@
|
||||
cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
|
||||
cloud.google.com/go v0.31.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
|
||||
cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
|
||||
cloud.google.com/go v0.37.0 h1:69FNAINiZfsEuwH3fKq8QrAAnHz+2m4XL4kVYi5BX0Q=
|
||||
cloud.google.com/go v0.37.0/go.mod h1:TS1dMSSfndXH133OKGwekG838Om/cQT0BUHV3HcBgoo=
|
||||
cloud.google.com/go/compute v1.19.1 h1:am86mquDUgjGNWxiGn+5PGLbmgiWXlE/yNWpIpNvuXY=
|
||||
cloud.google.com/go/compute v1.19.1/go.mod h1:6ylj3a05WF8leseCdIf77NK0g1ey+nj5IKd5/kvShxE=
|
||||
cloud.google.com/go/compute/metadata v0.2.3 h1:mg4jlk7mCAj6xXp9UJ4fjI9VUI5rubuGBW5aJ7UnBMY=
|
||||
cloud.google.com/go/compute/metadata v0.2.3/go.mod h1:VAV5nSsACxMJvgaAuX6Pk2AawlZn8kiOGuCv6gTkwuA=
|
||||
dmitri.shuralyov.com/app/changes v0.0.0-20180602232624-0a106ad413e3/go.mod h1:Yl+fi1br7+Rr3LqpNJf1/uxUdtRUV+Tnj0o93V2B9MU=
|
||||
dmitri.shuralyov.com/html/belt v0.0.0-20180602232347-f7d459c86be0/go.mod h1:JLBrvjyP0v+ecvNYvCpyZgu5/xkfAUhi6wJj28eUfSU=
|
||||
dmitri.shuralyov.com/service/change v0.0.0-20181023043359-a85b471d5412/go.mod h1:a1inKt/atXimZ4Mv927x+r7UpyzRUf4emIoiiSC2TN4=
|
||||
dmitri.shuralyov.com/state v0.0.0-20180228185332-28bcc343414c/go.mod h1:0PRwlb0D6DFvNNtx+9ybjezNCa8XF0xaYcETyp6rHWU=
|
||||
git.apache.org/thrift.git v0.0.0-20180902110319-2566ecd5d999/go.mod h1:fPE2ZNJGynbRyZ4dJvy6G277gSllfV2HJqblrnkyeyg=
|
||||
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
|
||||
github.com/aead/chacha20 v0.0.0-20180709150244-8b13a72661da h1:KjTM2ks9d14ZYCvmHS9iAKVt9AyzRSqNU1qabPih5BY=
|
||||
github.com/aead/chacha20 v0.0.0-20180709150244-8b13a72661da/go.mod h1:eHEWzANqSiWQsof+nXEI9bUVUyV6F53Fp89EuCh2EAA=
|
||||
github.com/andybalholm/brotli v1.0.5 h1:8uQZIdzKmjc/iuPu7O2ioW48L81FgatrcpfFmiq/cCs=
|
||||
github.com/andybalholm/brotli v1.0.5/go.mod h1:fO7iG3H7G2nSZ7m0zPUDn85XEX2GTukHGRSepvi9Eig=
|
||||
github.com/anmitsu/go-shlex v0.0.0-20161002113705-648efa622239/go.mod h1:2FmKhYUyUczH0OGQWaF5ceTx0UBShxjsH6f8oGKYe2c=
|
||||
github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q=
|
||||
github.com/bradfitz/go-smtpd v0.0.0-20170404230938-deb6d6237625/go.mod h1:HYsPBTaaSFSlLx/70C2HPIMNZpVV8+vt/A+FMnYP11g=
|
||||
github.com/buger/jsonparser v0.0.0-20181115193947-bf1c66bbce23/go.mod h1:bbYlZJ7hK1yFx9hf58LP0zeX7UjIGs20ufpu3evjr+s=
|
||||
github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
|
||||
github.com/cilium/ebpf v0.9.1/go.mod h1:+OhNOIXx/Fnu1IE8bJz2dzOA+VSfyTfdNUVdlQnxUFY=
|
||||
github.com/cilium/ebpf v0.9.3 h1:5KtxXZU+scyERvkJMEm16TbScVvuuMrlhPly78ZMbSc=
|
||||
github.com/cilium/ebpf v0.9.3/go.mod h1:w27N4UjpaQ9X/DGrSugxUG+H+NhgntDuPb5lCzxCn8A=
|
||||
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
|
||||
github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc=
|
||||
github.com/coreos/go-systemd v0.0.0-20181012123002-c6f51f82210d/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4=
|
||||
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
|
||||
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/dgryski/go-metro v0.0.0-20200812162917-85c65e2d0165/go.mod h1:c9O8+fpSOX1DM8cPNSkX/qsBWdkD4yd2dpciOWQjpBw=
|
||||
github.com/dgryski/go-metro v0.0.0-20211217172704-adc40b04c140 h1:y7y0Oa6UawqTFPCDw9JG6pdKt4F9pAhHv0B7FMGaGD0=
|
||||
github.com/dgryski/go-metro v0.0.0-20211217172704-adc40b04c140/go.mod h1:c9O8+fpSOX1DM8cPNSkX/qsBWdkD4yd2dpciOWQjpBw=
|
||||
github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk=
|
||||
github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
|
||||
github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
|
||||
github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98=
|
||||
github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
|
||||
github.com/flynn/go-shlex v0.0.0-20150515145356-3f9db97f8568/go.mod h1:xEzjJPgXI435gkrCt3MPfRiAkVrwSbHsst4LCFVfpJc=
|
||||
github.com/francoispqt/gojay v1.2.13 h1:d2m3sFjloqoIUQU3TsHBgj6qg/BVGlTBeHDUmyJnXKk=
|
||||
github.com/francoispqt/gojay v1.2.13/go.mod h1:ehT5mTG4ua4581f1++1WLG0vPdaA9HaiDsoyrBGkyDY=
|
||||
github.com/frankban/quicktest v1.14.0/go.mod h1:NeW+ay9A/U67EYXNFA1nPE8e/tnQv/09mUdL/ijj8og=
|
||||
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
|
||||
github.com/gaukas/godicttls v0.0.4 h1:NlRaXb3J6hAnTmWdsEKb9bcSBD6BvcIjdGdeb0zfXbk=
|
||||
github.com/gaukas/godicttls v0.0.4/go.mod h1:l6EenT4TLWgTdwslVb4sEMOCf7Bv0JAK67deKr9/NCI=
|
||||
github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
|
||||
github.com/ghodss/yaml v1.0.1-0.20220118164431-d8423dcdf344 h1:Arcl6UOIS/kgO2nW3A65HN+7CMjSDP/gofXL4CZt1V4=
|
||||
github.com/ghodss/yaml v1.0.1-0.20220118164431-d8423dcdf344/go.mod h1:GIjDIg/heH5DOkXY3YJ/wNhfHsQHoXGjl8G8amsYQ1I=
|
||||
github.com/gliderlabs/ssh v0.1.1/go.mod h1:U7qILu1NlMHj9FlMhZLlkCdDnU1DBEAqr0aevW3Awn0=
|
||||
github.com/go-errors/errors v1.0.1/go.mod h1:f4zRHt4oKfwPJE5k8C9vpYG+aDHdBFUsgrm6/TyX73Q=
|
||||
github.com/go-kit/kit v0.9.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
|
||||
github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk=
|
||||
github.com/go-logr/logr v1.2.4 h1:g01GSCwiDw2xSZfjJ2/T9M+S6pFdcNtFYsp+Y43HYDQ=
|
||||
github.com/go-logr/logr v1.2.4/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=
|
||||
github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=
|
||||
github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 h1:tfuBGBXKqDEevZMzYi5KSi8KkcZtzBcTgAUUtapy0OI=
|
||||
github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572/go.mod h1:9Pwr4B2jHnOSGXyyzV8ROjYa2ojvAY6HCGYYfMoC3Ls=
|
||||
github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=
|
||||
github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q=
|
||||
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
|
||||
github.com/golang/lint v0.0.0-20180702182130-06c8688daad7/go.mod h1:tluoj9z5200jBnyusfRPU2LqT6J+DAorxEvtC7LHB+E=
|
||||
github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
|
||||
github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
|
||||
github.com/golang/mock v1.6.0 h1:ErTB+efbowRARo13NNdxyJji2egdxLGQhRaY+DUumQc=
|
||||
github.com/golang/mock v1.6.0/go.mod h1:p6yTPP+5HYm5mzsMV8JkE6ZKdX+/wYM6Hr+LicevLPs=
|
||||
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||
github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||
github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||
github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw=
|
||||
github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk=
|
||||
github.com/golang/protobuf v1.5.3 h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg=
|
||||
github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY=
|
||||
github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
|
||||
github.com/google/btree v1.1.2 h1:xf4v41cLI2Z6FxbKm+8Bu+m8ifhj15JuZ9sa0jZCMUU=
|
||||
github.com/google/btree v1.1.2/go.mod h1:qOPhT0dTNdNzV6Z/lhRX0YXUafgPLFUh+gZMl761Gm4=
|
||||
github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=
|
||||
github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.5.7/go.mod h1:n+brtR0CgQNWTVd5ZUFpTBC8YFBDLK/h/bpaJ8/DtOE=
|
||||
github.com/google/go-cmp v0.5.8/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
|
||||
github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38=
|
||||
github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
|
||||
github.com/google/go-github v17.0.0+incompatible/go.mod h1:zLgOLi98H3fifZn+44m+umXrS52loVEgC2AApnigrVQ=
|
||||
github.com/google/go-querystring v1.0.0/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck=
|
||||
github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs=
|
||||
github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc=
|
||||
github.com/google/pprof v0.0.0-20230821062121-407c9e7a662f h1:pDhu5sgp8yJlEF/g6osliIIpF9K4F5jvkULXa4daRDQ=
|
||||
github.com/google/pprof v0.0.0-20230821062121-407c9e7a662f/go.mod h1:czg5+yv1E0ZGTi6S6vVK1mke0fV+FaUhNGcd6VRS9Ik=
|
||||
github.com/googleapis/gax-go v2.0.0+incompatible/go.mod h1:SFVmujtThgffbyetf+mdk2eWhX2bMyUtNHzFKcPA9HY=
|
||||
github.com/googleapis/gax-go/v2 v2.0.3/go.mod h1:LLvjysVCY1JZeum8Z6l8qUty8fiNwE08qbEPm1M08qg=
|
||||
github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY=
|
||||
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/gregjones/httpcache v0.0.0-20180305231024-9cad4c3443a7/go.mod h1:FecbI9+v66THATjSRHfNgh1IVFe/9kFxbXtjV0ctIMA=
|
||||
github.com/grpc-ecosystem/go-grpc-middleware v1.3.0 h1:+9834+KizmvFV7pXQGSXQTsaWhq2GjuNUt0aUU0YBYw=
|
||||
github.com/grpc-ecosystem/go-grpc-middleware v1.3.0/go.mod h1:z0ButlSOZa5vEBq9m2m2hlwIgKw+rp3sdCBRoJY+30Y=
|
||||
github.com/grpc-ecosystem/grpc-gateway v1.5.0/go.mod h1:RSKVYQBd5MCa4OVpNdGskqpgL2+G+NZTnrVHpWWfpdw=
|
||||
github.com/jellevandenhooff/dkim v0.0.0-20150330215556-f50fe3d243e1/go.mod h1:E0B/fFc00Y+Rasa88328GlI/XbtyysCtTHZS8h7IrBU=
|
||||
github.com/josharian/native v1.0.0 h1:Ts/E8zCSEsG17dUqv7joXJFybuMLjQfWE04tsBODTxk=
|
||||
github.com/josharian/native v1.0.0/go.mod h1:7X/raswPFr05uY3HiLlYeyQntB6OO7E/d2Cu7qoaN2w=
|
||||
github.com/jsimonetti/rtnetlink v1.2.2 h1:Ok9vYMcpxfHyF/iRqNTYJPDLxVaVItvPamAhtzttDBY=
|
||||
github.com/jsimonetti/rtnetlink v1.2.2/go.mod h1:T3BJ2qI9ZJFkUYWLrzECdcXhCvaGRfnMFmoYF0X8w2A=
|
||||
github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU=
|
||||
github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU=
|
||||
github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8=
|
||||
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
|
||||
github.com/klauspost/compress v1.16.7 h1:2mk3MPGNzKyxErAw8YaohYh69+pa4sIQSC0fPGCFR9I=
|
||||
github.com/klauspost/compress v1.16.7/go.mod h1:ntbaceVETuRiXiv4DpjP66DpAtAGkEQskQzEyD//IeE=
|
||||
github.com/klauspost/cpuid/v2 v2.2.5 h1:0E5MSMDEoAulmXNFquVs//DdoomxaoTY1kUhbc/qbZg=
|
||||
github.com/klauspost/cpuid/v2 v2.2.5/go.mod h1:Lcz8mBdAVJIBVzewtcLocK12l3Y+JytZYpaMropDUws=
|
||||
github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
|
||||
github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc=
|
||||
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
|
||||
github.com/kr/pretty v0.3.0 h1:WgNl7dwNpEZ6jJ9k1snq4pZsg7DOEN8hP9Xw0Tsjwk0=
|
||||
github.com/kr/pretty v0.3.0/go.mod h1:640gp4NfQd8pI5XOwp5fnNeVWj67G7CFk/SaSQn7NBk=
|
||||
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
|
||||
github.com/kr/pty v1.1.3/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
|
||||
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
|
||||
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
|
||||
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
|
||||
github.com/lunixbochs/vtclean v1.0.0/go.mod h1:pHhQNgMf3btfWnGBVipUOjRYhoOsdGqdm/+2c2E2WMI=
|
||||
github.com/mailru/easyjson v0.0.0-20190312143242-1de009706dbe/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
|
||||
github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=
|
||||
github.com/mdlayher/netlink v1.6.0 h1:rOHX5yl7qnlpiVkFWoqccueppMtXzeziFjWAjLg6sz0=
|
||||
github.com/mdlayher/netlink v1.6.0/go.mod h1:0o3PlBmGst1xve7wQ7j/hwpNaFaH4qCRyWCdcZk8/vA=
|
||||
github.com/mdlayher/socket v0.1.1 h1:q3uOGirUPfAV2MUoaC7BavjQ154J7+JOkTWyiV+intI=
|
||||
github.com/mdlayher/socket v0.1.1/go.mod h1:mYV5YIZAfHh4dzDVzI8x8tWLWCliuX8Mon5Awbj+qDs=
|
||||
github.com/microcosm-cc/bluemonday v1.0.1/go.mod h1:hsXNsILzKxV+sX77C5b8FSuKF00vh2OMYv+xgHpAMF4=
|
||||
github.com/miekg/dns v1.1.55 h1:GoQ4hpsj0nFLYe+bWiCToyrBEJXkQfOOIvFGFy0lEgo=
|
||||
github.com/miekg/dns v1.1.55/go.mod h1:uInx36IzPl7FYnDcMeVWxj9byh7DutNykX4G9Sj60FY=
|
||||
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
|
||||
github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
|
||||
github.com/neelance/astrewrite v0.0.0-20160511093645-99348263ae86/go.mod h1:kHJEU3ofeGjhHklVoIGuVj85JJwZ6kWPaJwCIxgnFmo=
|
||||
github.com/neelance/sourcemap v0.0.0-20151028013722-8c68805598ab/go.mod h1:Qr6/a/Q4r9LP1IltGz7tA7iOK1WonHEYhu1HRBA7ZiM=
|
||||
github.com/onsi/ginkgo/v2 v2.12.0 h1:UIVDowFPwpg6yMUpPjGkYvf06K3RAiJXUhCxEwQVHRI=
|
||||
github.com/onsi/ginkgo/v2 v2.12.0/go.mod h1:ZNEzXISYlqpb8S36iN71ifqLi3vVD1rVJGvWRCJOUpQ=
|
||||
github.com/onsi/gomega v1.27.10 h1:naR28SdDFlqrG6kScpT8VWpu1xWY5nJRCF3XaYyBjhI=
|
||||
github.com/onsi/gomega v1.27.10/go.mod h1:RsS8tutOdbdgzbPtzzATp12yT7kM5I5aElG3evPbQ0M=
|
||||
github.com/opentracing/opentracing-go v1.1.0/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o=
|
||||
github.com/openzipkin/zipkin-go v0.1.1/go.mod h1:NtoC/o8u3JlF1lSlyPNswIbeQH9bJTmOf0Erfk+hxe8=
|
||||
github.com/pelletier/go-toml v1.9.5 h1:4yBQzkHv+7BHq2PQUZF3Mx0IYxG7LsP222s7Agd3ve8=
|
||||
github.com/pelletier/go-toml v1.9.5/go.mod h1:u1nR/EPcESfeI/szUZKdtJ0xRNbUoANCkoOuaOx1Y+c=
|
||||
github.com/pires/go-proxyproto v0.7.0 h1:IukmRewDQFWC7kfnb66CSomk2q/seBuilHBYFwyq0Hs=
|
||||
github.com/pires/go-proxyproto v0.7.0/go.mod h1:Vz/1JPY/OACxWGQNIRY2BeyDmpoaWmEP40O9LbuiFR4=
|
||||
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||
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/prometheus/client_golang v0.8.0/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw=
|
||||
github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo=
|
||||
github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
|
||||
github.com/prometheus/common v0.0.0-20180801064454-c7de2306084e/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro=
|
||||
github.com/prometheus/procfs v0.0.0-20180725123919-05ee40e3a273/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
|
||||
github.com/quic-go/qtls-go1-20 v0.3.3 h1:17/glZSLI9P9fDAeyCHBFSWSqJcwx1byhLwP5eUIDCM=
|
||||
github.com/quic-go/qtls-go1-20 v0.3.3/go.mod h1:X9Nh97ZL80Z+bX/gUXMbipO6OxdiDi58b/fMC9mAL+k=
|
||||
github.com/quic-go/quic-go v0.38.1 h1:M36YWA5dEhEeT+slOu/SwMEucbYd0YFidxG3KlGPZaE=
|
||||
github.com/quic-go/quic-go v0.38.1/go.mod h1:ijnZM7JsFIkp4cRyjxJNIzdSfCLmUMg9wdyhGmg+SN4=
|
||||
github.com/refraction-networking/utls v1.4.3 h1:BdWS3BSzCwWCFfMIXP3mjLAyQkdmog7diaD/OqFbAzM=
|
||||
github.com/refraction-networking/utls v1.4.3/go.mod h1:4u9V/awOSBrRw6+federGmVJQfPtemEqLBXkML1b0bo=
|
||||
github.com/riobard/go-bloom v0.0.0-20200614022211-cdc8013cb5b3 h1:f/FNXud6gA3MNr8meMVVGxhp+QBTqY91tM8HjEuMjGg=
|
||||
github.com/riobard/go-bloom v0.0.0-20200614022211-cdc8013cb5b3/go.mod h1:HgjTstvQsPGkxUsCd2KWxErBblirPizecHcpD3ffK+s=
|
||||
github.com/rogpeppe/go-internal v1.6.1 h1:/FiVV8dS/e+YqF2JvO3yXRFbBLTIuSDkuC7aBOAvL+k=
|
||||
github.com/rogpeppe/go-internal v1.6.1/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc=
|
||||
github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g=
|
||||
github.com/sagernet/sing v0.2.9 h1:3wsTz+JG5Wzy65eZnh6AuCrD2QqcRF6Iq6f7ttmJsAo=
|
||||
github.com/sagernet/sing v0.2.9/go.mod h1:Ta8nHnDLAwqySzKhGoKk4ZIB+vJ3GTKj7UPrWYvM+4w=
|
||||
github.com/sagernet/sing-shadowsocks v0.2.4 h1:s/CqXlvFAZhlIoHWUwPw5CoNnQ9Ibki9pckjuugtVfY=
|
||||
github.com/sagernet/sing-shadowsocks v0.2.4/go.mod h1:80fNKP0wnqlu85GZXV1H1vDPC/2t+dQbFggOw4XuFUM=
|
||||
github.com/sagernet/wireguard-go v0.0.0-20221116151939-c99467f53f2c h1:vK2wyt9aWYHHvNLWniwijBu/n4pySypiKRhN32u/JGo=
|
||||
github.com/sagernet/wireguard-go v0.0.0-20221116151939-c99467f53f2c/go.mod h1:euOmN6O5kk9dQmgSS8Df4psAl3TCjxOz0NW60EWkSaI=
|
||||
github.com/seiflotfy/cuckoofilter v0.0.0-20220411075957-e3b120b3f5fb h1:XfLJSPIOUX+osiMraVgIrMR27uMXnRJWGm1+GL8/63U=
|
||||
github.com/seiflotfy/cuckoofilter v0.0.0-20220411075957-e3b120b3f5fb/go.mod h1:bR6DqgcAl1zTcOX8/pE2Qkj9XO00eCNqmKb7lXP8EAg=
|
||||
github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo=
|
||||
github.com/shurcooL/component v0.0.0-20170202220835-f88ec8f54cc4/go.mod h1:XhFIlyj5a1fBNx5aJTbKoIq0mNaPvOagO+HjB3EtxrY=
|
||||
github.com/shurcooL/events v0.0.0-20181021180414-410e4ca65f48/go.mod h1:5u70Mqkb5O5cxEA8nxTsgrgLehJeAw6Oc4Ab1c/P1HM=
|
||||
github.com/shurcooL/github_flavored_markdown v0.0.0-20181002035957-2122de532470/go.mod h1:2dOwnU2uBioM+SGy2aZoq1f/Sd1l9OkAeAUvjSyvgU0=
|
||||
github.com/shurcooL/go v0.0.0-20180423040247-9e1955d9fb6e/go.mod h1:TDJrrUr11Vxrven61rcy3hJMUqaf/CLWYhHNPmT14Lk=
|
||||
github.com/shurcooL/go-goon v0.0.0-20170922171312-37c2f522c041/go.mod h1:N5mDOmsrJOB+vfqUK+7DmDyjhSLIIBnXo9lvZJj3MWQ=
|
||||
github.com/shurcooL/gofontwoff v0.0.0-20180329035133-29b52fc0a18d/go.mod h1:05UtEgK5zq39gLST6uB0cf3NEHjETfB4Fgr3Gx5R9Vw=
|
||||
github.com/shurcooL/gopherjslib v0.0.0-20160914041154-feb6d3990c2c/go.mod h1:8d3azKNyqcHP1GaQE/c6dDgjkgSx2BZ4IoEi4F1reUI=
|
||||
github.com/shurcooL/highlight_diff v0.0.0-20170515013008-09bb4053de1b/go.mod h1:ZpfEhSmds4ytuByIcDnOLkTHGUI6KNqRNPDLHDk+mUU=
|
||||
github.com/shurcooL/highlight_go v0.0.0-20181028180052-98c3abbbae20/go.mod h1:UDKB5a1T23gOMUJrI+uSuH0VRDStOiUVSjBTRDVBVag=
|
||||
github.com/shurcooL/home v0.0.0-20181020052607-80b7ffcb30f9/go.mod h1:+rgNQw2P9ARFAs37qieuu7ohDNQ3gds9msbT2yn85sg=
|
||||
github.com/shurcooL/htmlg v0.0.0-20170918183704-d01228ac9e50/go.mod h1:zPn1wHpTIePGnXSHpsVPWEktKXHr6+SS6x/IKRb7cpw=
|
||||
github.com/shurcooL/httperror v0.0.0-20170206035902-86b7830d14cc/go.mod h1:aYMfkZ6DWSJPJ6c4Wwz3QtW22G7mf/PEgaB9k/ik5+Y=
|
||||
github.com/shurcooL/httpfs v0.0.0-20171119174359-809beceb2371/go.mod h1:ZY1cvUeJuFPAdZ/B6v7RHavJWZn2YPVFQ1OSXhCGOkg=
|
||||
github.com/shurcooL/httpgzip v0.0.0-20180522190206-b1c53ac65af9/go.mod h1:919LwcH0M7/W4fcZ0/jy0qGght1GIhqyS/EgWGH2j5Q=
|
||||
github.com/shurcooL/issues v0.0.0-20181008053335-6292fdc1e191/go.mod h1:e2qWDig5bLteJ4fwvDAc2NHzqFEthkqn7aOZAOpj+PQ=
|
||||
github.com/shurcooL/issuesapp v0.0.0-20180602232740-048589ce2241/go.mod h1:NPpHK2TI7iSaM0buivtFUc9offApnI0Alt/K8hcHy0I=
|
||||
github.com/shurcooL/notifications v0.0.0-20181007000457-627ab5aea122/go.mod h1:b5uSkrEVM1jQUspwbixRBhaIjIzL2xazXp6kntxYle0=
|
||||
github.com/shurcooL/octicon v0.0.0-20181028054416-fa4f57f9efb2/go.mod h1:eWdoE5JD4R5UVWDucdOPg1g2fqQRq78IQa9zlOV1vpQ=
|
||||
github.com/shurcooL/reactions v0.0.0-20181006231557-f2e0b4ca5b82/go.mod h1:TCR1lToEk4d2s07G3XGfz2QrgHXg4RJBvjrOozvoWfk=
|
||||
github.com/shurcooL/sanitized_anchor_name v0.0.0-20170918181015-86672fcb3f95/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc=
|
||||
github.com/shurcooL/users v0.0.0-20180125191416-49c67e49c537/go.mod h1:QJTqeLYEDaXHZDBsXlPCDqdhQuJkuw4NOtaxYe3xii4=
|
||||
github.com/shurcooL/webdavfs v0.0.0-20170829043945-18c3829fa133/go.mod h1:hKmq5kWdCj2z2KEozexVbfEZIWiTjhE0+UjmZgPqehw=
|
||||
github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE=
|
||||
github.com/sourcegraph/annotate v0.0.0-20160123013949-f4cad6c6324d/go.mod h1:UdhH50NIW0fCiwBSr0co2m7BnFLdv4fQTgdqdJTHFeE=
|
||||
github.com/sourcegraph/syntaxhighlight v0.0.0-20170531221838-bd320f5d308e/go.mod h1:HuIsMU8RRBOtsCgI77wP899iHVBQpCmg4ErYMZB+2IA=
|
||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
|
||||
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.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk=
|
||||
github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
|
||||
github.com/tarm/serial v0.0.0-20180830185346-98f6abe2eb07/go.mod h1:kDXzergiv9cbyO7IOYJZWg1U88JhDg3PB6klq9Hg2pA=
|
||||
github.com/v2fly/ss-bloomring v0.0.0-20210312155135-28617310f63e h1:5QefA066A1tF8gHIiADmOVOV5LS43gt3ONnlEl3xkwI=
|
||||
github.com/v2fly/ss-bloomring v0.0.0-20210312155135-28617310f63e/go.mod h1:5t19P9LBIrNamL6AcMQOncg/r10y3Pc01AbHeMhwlpU=
|
||||
github.com/viant/assertly v0.4.8/go.mod h1:aGifi++jvCrUaklKEKT0BU95igDNaqkvz+49uaYMPRU=
|
||||
github.com/viant/toolbox v0.24.0/go.mod h1:OxMCG57V0PXuIP2HNQrtJf2CjqdmbrOx5EkMILuUhzM=
|
||||
github.com/xtls/reality v0.0.0-20230828171259-e426190d57f6 h1:T+YCYGfFdzyaKTDCdZn/hEiKvsw6yUfd+e4hze0rCUw=
|
||||
github.com/xtls/reality v0.0.0-20230828171259-e426190d57f6/go.mod h1:rkuAY1S9F8eI8gDiPDYvACE8e2uwkyg8qoOTuwWov7Y=
|
||||
github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||
github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||
github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
|
||||
go.opencensus.io v0.18.0/go.mod h1:vKdFvxhtzZ9onBp9VKHK8z/sRpBMnKAsufL7wlDrCOA=
|
||||
go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE=
|
||||
go.uber.org/atomic v1.11.0 h1:ZvwS0R+56ePWxUNi+Atn9dWONBPp/AUETXlHW0DxSjE=
|
||||
go.uber.org/atomic v1.11.0/go.mod h1:LUxbIzbOniOlMKjJjyPfpl4v+PKK2cNJn91OQbhoJI0=
|
||||
go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0=
|
||||
go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q=
|
||||
go4.org v0.0.0-20180809161055-417644f6feb5/go.mod h1:MkTOUMDaeVYJUOUsaDXIhWPZYa1yOyC1qaOBpL57BhE=
|
||||
go4.org/netipx v0.0.0-20230824141953-6213f710f925 h1:eeQDDVKFkx0g4Hyy8pHgmZaK0EqB4SD6rvKbUdN3ziQ=
|
||||
go4.org/netipx v0.0.0-20230824141953-6213f710f925/go.mod h1:PLyyIXexvUFg3Owu6p/WfdlivPbZJsZdgWZlrGope/Y=
|
||||
golang.org/x/build v0.0.0-20190111050920-041ab4dc3f9d/go.mod h1:OWs+y06UdEOHN4y+MfF/py+xQ/tYqIWW03b70/CG9Rw=
|
||||
golang.org/x/crypto v0.0.0-20181030102418-4d3f4d9ffa16/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||
golang.org/x/crypto v0.0.0-20190313024323-a1f597ede03a/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.12.0 h1:tFM/ta59kqch6LlvYnPa0yx5a83cL2nHflFhYKvv9Yk=
|
||||
golang.org/x/crypto v0.12.0/go.mod h1:NF0Gs7EO5K4qLn+Ylc+fih8BSTeIjAP05siRnAh98yw=
|
||||
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||
golang.org/x/exp v0.0.0-20230725093048-515e97ebf090 h1:Di6/M8l0O2lCLc6VVRWhgCiApHV8MnQurBnFSHsQtNY=
|
||||
golang.org/x/exp v0.0.0-20230725093048-515e97ebf090/go.mod h1:FXUEEKJgO7OQYeo8N01OfiKP8RXMtf6e8aTskBGqWdc=
|
||||
golang.org/x/lint v0.0.0-20180702182130-06c8688daad7/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
|
||||
golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
|
||||
golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU=
|
||||
golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
|
||||
golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||
golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||
golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||
golang.org/x/mod v0.12.0 h1:rmsUpXtvNzj340zd98LZ4KntptpfRHwpFOHG188oHXc=
|
||||
golang.org/x/mod v0.12.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
|
||||
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20181029044818-c44066c5c816/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20181106065722-10aee1819953/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||
golang.org/x/net v0.0.0-20190313220215-9f648a60d977/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
|
||||
golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM=
|
||||
golang.org/x/net v0.0.0-20210928044308-7d9f5e0b762b/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
||||
golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk=
|
||||
golang.org/x/net v0.14.0 h1:BONx9s002vGdD9umnlX1Po8vOZmrgH34qlHcD1MfK14=
|
||||
golang.org/x/net v0.14.0/go.mod h1:PpSgVXXLK0OxS0F31C1/tv6XNguvCrnXIDrFMspZIUI=
|
||||
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
||||
golang.org/x/oauth2 v0.0.0-20181017192945-9dcd33a902f4/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
||||
golang.org/x/oauth2 v0.0.0-20181203162652-d668ce993890/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
||||
golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
||||
golang.org/x/oauth2 v0.7.0 h1:qe6s0zUXlPX80/dITx3440hWZ7GwMwgDDyrSGTPJG/g=
|
||||
golang.org/x/oauth2 v0.7.0/go.mod h1:hPLQkd9LyjfXTiRohC/41GhcFqxisoUQ99sCUOHO9x4=
|
||||
golang.org/x/perf v0.0.0-20180704124530-6e6d33e29852/go.mod h1:JLpeXjPJfIyPr5TlbXLkXWLhP8nz10XfvxElABhCtcw=
|
||||
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/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.3.0 h1:ftCYgMx6zT/asHUrPw8BLLscYtGznsLAnjq5RH9P66E=
|
||||
golang.org/x/sync v0.3.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y=
|
||||
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20181029174526-d69651ed3497/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190316082340-a2f829d7f35f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/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-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-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220128215802-99c3d69c2c27/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220408201424-a24fb2fb8a0f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.11.0 h1:eG7RXZHdqOJ1i+0lgLgCpSXAp6M3LYlAo6osgSi0xOM=
|
||||
golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
|
||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
|
||||
golang.org/x/text v0.12.0 h1:k+n5B8goJNdU7hSvEtMUz3d1Q6D/XW4COJSJR6fN0mc=
|
||||
golang.org/x/text v0.12.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=
|
||||
golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
golang.org/x/time v0.3.0 h1:rg5rLMjNzMS1RkNLzCG38eapWhnYLFYXDXj2gOlr8j4=
|
||||
golang.org/x/time v0.3.0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
golang.org/x/tools v0.0.0-20180828015842-6cd1fcedba52/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20181030000716-a0a13e073c7b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY=
|
||||
golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
|
||||
golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
|
||||
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
|
||||
golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
|
||||
golang.org/x/tools v0.1.1/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
|
||||
golang.org/x/tools v0.12.0 h1:YW6HUoUmYBpwSgyaGaZq1fHjrBjX1rlpZ54T6mu2kss=
|
||||
golang.org/x/tools v0.12.0/go.mod h1:Sc0INKfu04TlqNoRA1hgpFZbhYXHPr4V5DzpSBTPqQM=
|
||||
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/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
google.golang.org/api v0.0.0-20180910000450-7ca32eb868bf/go.mod h1:4mhQ8q/RsB7i+udVvVy5NUi08OU8ZlA0gRVgrF7VFY0=
|
||||
google.golang.org/api v0.0.0-20181030000543-1d582fd0359e/go.mod h1:4mhQ8q/RsB7i+udVvVy5NUi08OU8ZlA0gRVgrF7VFY0=
|
||||
google.golang.org/api v0.1.0/go.mod h1:UGEZY7KEX120AnNLIHFMKIo4obdJhkp2tPbaPlQx13Y=
|
||||
google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
|
||||
google.golang.org/appengine v1.2.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
|
||||
google.golang.org/appengine v1.3.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
|
||||
google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
|
||||
google.golang.org/appengine v1.6.7 h1:FZR1q0exgwxzPzp/aF+VccGrSfxfPpkBqjIIEq3ru6c=
|
||||
google.golang.org/appengine v1.6.7/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=
|
||||
google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
|
||||
google.golang.org/genproto v0.0.0-20180831171423-11092d34479b/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
|
||||
google.golang.org/genproto v0.0.0-20181029155118-b69ba1387ce2/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
|
||||
google.golang.org/genproto v0.0.0-20181202183823-bd91e49a0898/go.mod h1:7Ep/1NZk928CDR8SjdVbjWNpdIf6nzjE3BTgJDr2Atg=
|
||||
google.golang.org/genproto v0.0.0-20190306203927-b5d61aea6440/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
|
||||
google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc=
|
||||
google.golang.org/genproto v0.0.0-20200423170343-7949de9c1215/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20230822172742-b8732ec3820d h1:uvYuEyMHKNt+lT4K3bN6fGswmK8qSvcreM3BwjDh+y4=
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20230822172742-b8732ec3820d/go.mod h1:+Bk1OCOj40wS2hwAMA+aCW9ypzm63QTBBHp6lQ3p+9M=
|
||||
google.golang.org/grpc v1.14.0/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmEdcZw=
|
||||
google.golang.org/grpc v1.16.0/go.mod h1:0JHn/cJsOMiMfNA9+DeHDlAU7KAAB5GDlYFpa9MZMio=
|
||||
google.golang.org/grpc v1.17.0/go.mod h1:6QZJwpn2B+Zp71q/5VxRsJ6NXXVCE5NRUHRo+f3cWCs=
|
||||
google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
|
||||
google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg=
|
||||
google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY=
|
||||
google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
|
||||
google.golang.org/grpc v1.29.1/go.mod h1:itym6AZVZYACWQqET3MqgPpjcuV5QH3BxFS3IjizoKk=
|
||||
google.golang.org/grpc v1.57.0 h1:kfzNeI/klCGD2YPMUlaGNT3pxvYfga7smW3Vth8Zsiw=
|
||||
google.golang.org/grpc v1.57.0/go.mod h1:Sd+9RMTACXwmub0zcNY2c4arhtrbBYD1AUHI/dt16Mo=
|
||||
google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
|
||||
google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
|
||||
google.golang.org/protobuf v1.31.0 h1:g0LDEJHgrBl9N9r17Ru3sqWhkIx2NB67okBHPwC7hs8=
|
||||
google.golang.org/protobuf v1.31.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 h1:YR8cESwS4TdDjEe65xsg0ogRM/Nc3DYOhEAlW+xobZo=
|
||||
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=
|
||||
gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw=
|
||||
gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
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/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
gopkg.in/yaml.v3 v3.0.0-20200605160147-a5ece683394c/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=
|
||||
grpc.go4.org v0.0.0-20170609214715-11d0a25b4919/go.mod h1:77eQGdRu53HpSqPFJFmuJdjuHRquDANNeA4x7B8WQ9o=
|
||||
gvisor.dev/gvisor v0.0.0-20230822212503-5bf4e5f98744 h1:tE44CyJgxEGzoPtHs9GI7ddKdgEGCREQBP54AmaVM+I=
|
||||
gvisor.dev/gvisor v0.0.0-20230822212503-5bf4e5f98744/go.mod h1:lYEMhXbxgudVhALYsMQrBaUAjM3NMinh8mKL1CJv7rc=
|
||||
honnef.co/go/tools v0.0.0-20180728063816-88497007e858/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
||||
honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
||||
honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
||||
honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
||||
kernel.org/pub/linux/libs/security/libcap/cap v1.2.65 h1:gIDtZoGnKeoIZ7XaKRmljMib4JV/TsjUhSzAeShNl6U=
|
||||
kernel.org/pub/linux/libs/security/libcap/cap v1.2.65/go.mod h1:Fp9fDSuNh1vVDA7sozXklfQ+LxXMpB5/H4hDR8eu+0s=
|
||||
kernel.org/pub/linux/libs/security/libcap/psx v1.2.65 h1:v2G3aCgEMr8qh4GpOGMukkv92EE7jtY+Uh9mB7cAACk=
|
||||
kernel.org/pub/linux/libs/security/libcap/psx v1.2.65/go.mod h1:+l6Ee2F59XiJ2I6WR5ObpC1utCQJZ/VLsEbQCD8RG24=
|
||||
lukechampine.com/blake3 v1.2.1 h1:YuqqRuaqsGV71BV/nm9xlI0MKUv4QC54jQnBChWbGnI=
|
||||
lukechampine.com/blake3 v1.2.1/go.mod h1:0OFRp7fBtAylGVCO40o87sbupkyIGgbpv1+M1k1LM6k=
|
||||
sourcegraph.com/sourcegraph/go-diff v0.5.0/go.mod h1:kuch7UrkMzY0X+p9CRK03kfuPQ2zzQcaEFbx8wA8rck=
|
||||
sourcegraph.com/sqs/pbtypes v0.0.0-20180604144634-d3ebe8f20ae4/go.mod h1:ketZ/q3QxT9HOBeFhu6RdvsftgpsbFHBF5Cas6cDKZ0=
|
||||
@ -1,162 +0,0 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"grpc_server"
|
||||
"grpc_server/gen"
|
||||
"log"
|
||||
|
||||
"github.com/matsuridayo/libneko/neko_common"
|
||||
"github.com/matsuridayo/libneko/speedtest"
|
||||
|
||||
"github.com/xtls/xray-core/nekoutils"
|
||||
)
|
||||
|
||||
type server struct {
|
||||
grpc_server.BaseServer
|
||||
}
|
||||
|
||||
func (s *server) Start(ctx context.Context, in *gen.LoadConfigReq) (out *gen.ErrorResp, _ error) {
|
||||
var err error
|
||||
|
||||
defer func() {
|
||||
out = &gen.ErrorResp{}
|
||||
if err != nil {
|
||||
out.Error = err.Error()
|
||||
instance = nil
|
||||
}
|
||||
}()
|
||||
|
||||
if neko_common.Debug {
|
||||
log.Println("Start:", in.CoreConfig)
|
||||
log.Println("EnableNekorayConnections:", in.EnableNekorayConnections)
|
||||
}
|
||||
|
||||
if instance != nil {
|
||||
err = errors.New("instance already started")
|
||||
return
|
||||
}
|
||||
|
||||
instance, err = NewNekoV2rayInstance(in.CoreConfig)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
nekoutils.SetConnectionPoolV2RayEnabled(instance.CorePtr(), in.EnableNekorayConnections)
|
||||
|
||||
err = instance.Start()
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
func (s *server) Stop(ctx context.Context, in *gen.EmptyReq) (out *gen.ErrorResp, _ error) {
|
||||
var err error
|
||||
|
||||
defer func() {
|
||||
out = &gen.ErrorResp{}
|
||||
if err != nil {
|
||||
out.Error = err.Error()
|
||||
}
|
||||
}()
|
||||
|
||||
if instance == nil {
|
||||
return
|
||||
}
|
||||
|
||||
err = instance.Close()
|
||||
instance = nil
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
func (s *server) Test(ctx context.Context, in *gen.TestReq) (out *gen.TestResp, _ error) {
|
||||
var err error
|
||||
out = &gen.TestResp{Ms: 0}
|
||||
|
||||
defer func() {
|
||||
if err != nil {
|
||||
out.Error = err.Error()
|
||||
}
|
||||
}()
|
||||
|
||||
if neko_common.Debug {
|
||||
log.Println("Test:", in)
|
||||
}
|
||||
|
||||
if in.Mode == gen.TestMode_UrlTest {
|
||||
var i *NekoV2RayInstance
|
||||
|
||||
if in.Config != nil {
|
||||
// Test instance
|
||||
i, err = NewNekoV2rayInstance(in.Config.CoreConfig)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
defer i.Close()
|
||||
|
||||
err = i.Start()
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
} else {
|
||||
// Test running instance
|
||||
i = instance
|
||||
if i == nil {
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
// Latency
|
||||
var t int32
|
||||
t, err = speedtest.UrlTest(createProxyHttpClient(i), in.Url, in.Timeout)
|
||||
out.Ms = t // sn: ms==0 是错误
|
||||
} else if in.Mode == gen.TestMode_TcpPing {
|
||||
out.Ms, err = speedtest.TcpPing(in.Address, in.Timeout)
|
||||
} else if in.Mode == gen.TestMode_FullTest {
|
||||
if in.Config == nil {
|
||||
return
|
||||
}
|
||||
// Test instance
|
||||
i, err := NewNekoV2rayInstance(in.Config.CoreConfig)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
defer i.Close()
|
||||
|
||||
err = i.Start()
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
return grpc_server.DoFullTest(ctx, in, i)
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
func (s *server) QueryStats(ctx context.Context, in *gen.QueryStatsReq) (out *gen.QueryStatsResp, _ error) {
|
||||
out = &gen.QueryStatsResp{}
|
||||
if instance != nil && instance.StatsManager != nil {
|
||||
counter := instance.StatsManager.GetCounter(fmt.Sprintf("outbound>>>%s>>>traffic>>>%s", in.Tag, in.Direct))
|
||||
if counter != nil {
|
||||
out.Traffic = counter.Set(0)
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func (s *server) ListConnections(ctx context.Context, in *gen.EmptyReq) (out *gen.ListConnectionsResp, _ error) {
|
||||
// nekoray_connections_json
|
||||
|
||||
out = &gen.ListConnectionsResp{}
|
||||
if instance != nil {
|
||||
out.NekorayConnectionsJson = nekoutils.ListConnections(instance.CorePtr())
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
@ -1,86 +0,0 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
// The following are necessary as they register handlers in their init functions.
|
||||
|
||||
// Mandatory features. Can't remove unless there are replacements.
|
||||
_ "github.com/xtls/xray-core/app/dispatcher"
|
||||
_ "github.com/xtls/xray-core/app/proxyman/inbound"
|
||||
_ "github.com/xtls/xray-core/app/proxyman/outbound"
|
||||
|
||||
// Default commander and all its services. This is an optional feature.
|
||||
_ "github.com/xtls/xray-core/app/commander"
|
||||
_ "github.com/xtls/xray-core/app/log/command"
|
||||
_ "github.com/xtls/xray-core/app/proxyman/command"
|
||||
_ "github.com/xtls/xray-core/app/stats/command"
|
||||
|
||||
// Developer preview services
|
||||
_ "github.com/xtls/xray-core/app/observatory/command"
|
||||
|
||||
// Other optional features.
|
||||
_ "github.com/xtls/xray-core/app/dns"
|
||||
_ "github.com/xtls/xray-core/app/dns/fakedns"
|
||||
_ "github.com/xtls/xray-core/app/log"
|
||||
_ "github.com/xtls/xray-core/app/metrics"
|
||||
_ "github.com/xtls/xray-core/app/policy"
|
||||
_ "github.com/xtls/xray-core/app/reverse"
|
||||
_ "github.com/xtls/xray-core/app/router"
|
||||
_ "github.com/xtls/xray-core/app/stats"
|
||||
|
||||
// Fix dependency cycle caused by core import in internet package
|
||||
_ "github.com/xtls/xray-core/transport/internet/tagged/taggedimpl"
|
||||
|
||||
// Developer preview features
|
||||
_ "github.com/xtls/xray-core/app/observatory"
|
||||
|
||||
// Inbound and outbound proxies.
|
||||
_ "github.com/xtls/xray-core/proxy/blackhole"
|
||||
_ "github.com/xtls/xray-core/proxy/dns"
|
||||
_ "github.com/xtls/xray-core/proxy/dokodemo"
|
||||
_ "github.com/xtls/xray-core/proxy/freedom"
|
||||
_ "github.com/xtls/xray-core/proxy/http"
|
||||
_ "github.com/xtls/xray-core/proxy/loopback"
|
||||
_ "github.com/xtls/xray-core/proxy/shadowsocks"
|
||||
_ "github.com/xtls/xray-core/proxy/socks"
|
||||
_ "github.com/xtls/xray-core/proxy/trojan"
|
||||
_ "github.com/xtls/xray-core/proxy/vless/inbound"
|
||||
_ "github.com/xtls/xray-core/proxy/vless/outbound"
|
||||
_ "github.com/xtls/xray-core/proxy/vmess/inbound"
|
||||
_ "github.com/xtls/xray-core/proxy/vmess/outbound"
|
||||
_ "github.com/xtls/xray-core/proxy/wireguard"
|
||||
|
||||
// Transports
|
||||
_ "github.com/xtls/xray-core/transport/internet/domainsocket"
|
||||
_ "github.com/xtls/xray-core/transport/internet/grpc"
|
||||
_ "github.com/xtls/xray-core/transport/internet/http"
|
||||
_ "github.com/xtls/xray-core/transport/internet/kcp"
|
||||
_ "github.com/xtls/xray-core/transport/internet/quic"
|
||||
_ "github.com/xtls/xray-core/transport/internet/reality"
|
||||
_ "github.com/xtls/xray-core/transport/internet/tcp"
|
||||
_ "github.com/xtls/xray-core/transport/internet/tls"
|
||||
_ "github.com/xtls/xray-core/transport/internet/udp"
|
||||
_ "github.com/xtls/xray-core/transport/internet/websocket"
|
||||
|
||||
// Transport headers
|
||||
_ "github.com/xtls/xray-core/transport/internet/headers/http"
|
||||
_ "github.com/xtls/xray-core/transport/internet/headers/noop"
|
||||
_ "github.com/xtls/xray-core/transport/internet/headers/srtp"
|
||||
_ "github.com/xtls/xray-core/transport/internet/headers/tls"
|
||||
_ "github.com/xtls/xray-core/transport/internet/headers/utp"
|
||||
_ "github.com/xtls/xray-core/transport/internet/headers/wechat"
|
||||
_ "github.com/xtls/xray-core/transport/internet/headers/wireguard"
|
||||
|
||||
// JSON & TOML & YAML
|
||||
_ "github.com/xtls/xray-core/main/json"
|
||||
// _ "github.com/xtls/xray-core/main/toml"
|
||||
// _ "github.com/xtls/xray-core/main/yaml"
|
||||
|
||||
// Load config from file or http(s)
|
||||
// _ "github.com/xtls/xray-core/main/confloader/external"
|
||||
|
||||
// Commands
|
||||
// _ "github.com/xtls/xray-core/main/commands/all"
|
||||
|
||||
// Custom
|
||||
_ "github.com/xtls/xray-core/proxy/shadowsocks/plugin/v2ray_plugin"
|
||||
)
|
||||
@ -1,50 +0,0 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"log"
|
||||
"strings"
|
||||
|
||||
core "github.com/xtls/xray-core/core"
|
||||
"github.com/xtls/xray-core/features/stats"
|
||||
"github.com/xtls/xray-core/nekoutils"
|
||||
)
|
||||
|
||||
type NekoV2RayInstance struct {
|
||||
*core.Instance
|
||||
|
||||
StatsManager stats.Manager
|
||||
}
|
||||
|
||||
func NewNekoV2rayInstance(configStr string) (*NekoV2RayInstance, error) {
|
||||
// load v4 or v5 config
|
||||
var config *core.Config
|
||||
var err error
|
||||
|
||||
config, err = core.LoadConfig("json", strings.NewReader(configStr))
|
||||
if err != nil {
|
||||
log.Println(configStr, err.Error())
|
||||
return nil, err
|
||||
}
|
||||
|
||||
c, err := core.New(config)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
instance := &NekoV2RayInstance{
|
||||
Instance: c,
|
||||
}
|
||||
instance.StatsManager = c.GetFeature(stats.ManagerType()).(stats.Manager)
|
||||
|
||||
return instance, nil
|
||||
}
|
||||
|
||||
func (i *NekoV2RayInstance) CorePtr() uintptr {
|
||||
return 0
|
||||
}
|
||||
|
||||
func (i *NekoV2RayInstance) Close() error {
|
||||
nekoutils.ResetConnections(i.CorePtr())
|
||||
nekoutils.SetConnectionPoolV2RayEnabled(i.CorePtr(), false)
|
||||
return i.Instance.Close()
|
||||
}
|
||||
@ -1,32 +0,0 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"grpc_server"
|
||||
"os"
|
||||
_ "unsafe"
|
||||
|
||||
"github.com/matsuridayo/libneko/neko_common"
|
||||
)
|
||||
|
||||
//go:linkname build github.com/xtls/xray-core/core.build
|
||||
var build string
|
||||
|
||||
func main() {
|
||||
build = "Matsuridayo/nekoray"
|
||||
fmt.Println("Xray:", neko_common.Version_v2ray, "NekoRay:", neko_common.Version_neko)
|
||||
fmt.Println()
|
||||
|
||||
// nekoray_core
|
||||
if len(os.Args) > 1 && os.Args[1] == "nekoray" {
|
||||
neko_common.RunMode = neko_common.RunMode_NekoRay_Core
|
||||
grpc_server.RunCore(setupCore, &server{})
|
||||
return
|
||||
}
|
||||
|
||||
// tool
|
||||
if len(os.Args) > 1 && os.Args[1] == "tool" {
|
||||
ToolBox()
|
||||
return
|
||||
}
|
||||
}
|
||||
@ -1,194 +0,0 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"encoding/binary"
|
||||
"log"
|
||||
"net"
|
||||
"os"
|
||||
"strings"
|
||||
"sync"
|
||||
"syscall"
|
||||
"unsafe"
|
||||
|
||||
"github.com/matsuridayo/libneko/iphlpapi"
|
||||
|
||||
"github.com/xtls/xray-core/transport/internet"
|
||||
)
|
||||
|
||||
// https://docs.microsoft.com/en-us/windows/win32/api/ipmib/ns-ipmib-mib_ipforwardrow
|
||||
var routes []iphlpapi.RouteRow
|
||||
var interfaces []net.Interface
|
||||
var lock sync.Mutex
|
||||
|
||||
func init() {
|
||||
if os.Getenv("NKR_CORE_RAY_WINDOWS_DISABLE_AUTO_INTERFACE") == "1" {
|
||||
log.Println("using NKR_CORE_RAY_WINDOWS_DISABLE_AUTO_INTERFACE")
|
||||
} else {
|
||||
initRoute()
|
||||
}
|
||||
//
|
||||
getNekorayTunIndex = func() (index int) {
|
||||
lock.Lock()
|
||||
defer lock.Unlock()
|
||||
for _, intf := range interfaces {
|
||||
if intf.Name == "nekoray-tun" {
|
||||
index = intf.Index
|
||||
return
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
func initRoute() {
|
||||
internet.RegisterListenerController(func(network, address string, conn syscall.RawConn) error {
|
||||
var err error
|
||||
conn.Control(func(fd uintptr) {
|
||||
bindInterfaceIndex := getBindInterfaceIndex(address)
|
||||
if bindInterfaceIndex != 0 {
|
||||
if err = bindInterface(fd, bindInterfaceIndex, true, true); err != nil {
|
||||
log.Println("bind inbound interface", network, address, err)
|
||||
}
|
||||
}
|
||||
})
|
||||
return err
|
||||
})
|
||||
internet.RegisterDialerController(func(network, address string, conn syscall.RawConn) error {
|
||||
var err error
|
||||
conn.Control(func(fd uintptr) {
|
||||
bindInterfaceIndex := getBindInterfaceIndex(address)
|
||||
if bindInterfaceIndex != 0 {
|
||||
var v4, v6 bool
|
||||
if strings.HasSuffix(network, "6") {
|
||||
v4 = false
|
||||
v6 = true
|
||||
} else {
|
||||
v4 = true
|
||||
v6 = false
|
||||
}
|
||||
if err = bindInterface(fd, bindInterfaceIndex, v4, v6); err != nil {
|
||||
log.Println("bind outbound interface", network, address, err)
|
||||
}
|
||||
}
|
||||
})
|
||||
return err
|
||||
})
|
||||
underlyingNetDialer = &net.Dialer{
|
||||
Control: func(network, address string, c syscall.RawConn) error {
|
||||
c.Control(func(fd uintptr) {
|
||||
bindInterfaceIndex := getBindInterfaceIndex(address)
|
||||
if bindInterfaceIndex != 0 {
|
||||
var v4, v6 bool
|
||||
if strings.HasSuffix(network, "6") {
|
||||
v4 = false
|
||||
v6 = true
|
||||
} else {
|
||||
v4 = true
|
||||
v6 = false
|
||||
}
|
||||
if err := bindInterface(fd, bindInterfaceIndex, v4, v6); err != nil {
|
||||
log.Println("underlyingNetDialer: bind interface", network, address, err)
|
||||
}
|
||||
}
|
||||
})
|
||||
return nil
|
||||
},
|
||||
}
|
||||
//
|
||||
updateRoutes()
|
||||
iphlpapi.RegisterNotifyRouteChange2(func(callerContext uintptr, row uintptr, notificationType uint32) uintptr {
|
||||
updateRoutes()
|
||||
return 0
|
||||
}, false)
|
||||
}
|
||||
|
||||
func updateRoutes() {
|
||||
lock.Lock()
|
||||
defer lock.Unlock()
|
||||
|
||||
var err error
|
||||
routes, err = iphlpapi.GetRoutes()
|
||||
if err != nil {
|
||||
log.Println("warning: GetRoutes failed", err)
|
||||
}
|
||||
interfaces, err = net.Interfaces()
|
||||
if err != nil {
|
||||
log.Println("warning: Interfaces failed", err)
|
||||
}
|
||||
}
|
||||
|
||||
func getBindInterfaceIndex(address string) uint32 {
|
||||
host, _, _ := net.SplitHostPort(address)
|
||||
if net.ParseIP(host).IsLoopback() {
|
||||
return 0
|
||||
}
|
||||
|
||||
lock.Lock()
|
||||
defer lock.Unlock()
|
||||
|
||||
if interfaces == nil {
|
||||
log.Println("warning: no interfaces info")
|
||||
return 0
|
||||
}
|
||||
|
||||
var nextInterface int
|
||||
for i, intf := range interfaces {
|
||||
if intf.Name == "nekoray-tun" {
|
||||
if len(interfaces) > i+1 {
|
||||
nextInterface = interfaces[i+1].Index
|
||||
}
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
// Not in Tun Mode
|
||||
if nextInterface == 0 {
|
||||
return 0
|
||||
}
|
||||
|
||||
if routes == nil {
|
||||
log.Println("warning: no routes info")
|
||||
return 0
|
||||
}
|
||||
|
||||
for _, route := range routes {
|
||||
// MIB_IPROUTE_TYPE_INDIRECT
|
||||
if route.ForwardType == 4 {
|
||||
// MIB_IPPROTO_NETMGMT
|
||||
if route.ForwardProto == 3 {
|
||||
if route.GetForwardMask().IsUnspecified() {
|
||||
return route.ForwardIfIndex
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Default route not found
|
||||
return uint32(nextInterface)
|
||||
}
|
||||
|
||||
const (
|
||||
IP_UNICAST_IF = 31 // nolint: golint,stylecheck
|
||||
IPV6_UNICAST_IF = 31 // nolint: golint,stylecheck
|
||||
)
|
||||
|
||||
func bindInterface(fd uintptr, interfaceIndex uint32, v4, v6 bool) error {
|
||||
if v4 {
|
||||
/* MSDN says for IPv4 this needs to be in net byte order, so that it's like an IP address with leading zeros. */
|
||||
bytes := make([]byte, 4)
|
||||
binary.BigEndian.PutUint32(bytes, interfaceIndex)
|
||||
interfaceIndex_v4 := *(*uint32)(unsafe.Pointer(&bytes[0]))
|
||||
|
||||
if err := syscall.SetsockoptInt(syscall.Handle(fd), syscall.IPPROTO_IP, IP_UNICAST_IF, int(interfaceIndex_v4)); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
if v6 {
|
||||
if err := syscall.SetsockoptInt(syscall.Handle(fd), syscall.IPPROTO_IPV6, IPV6_UNICAST_IF, int(interfaceIndex)); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
@ -1,125 +0,0 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"log"
|
||||
"net"
|
||||
"strings"
|
||||
"syscall"
|
||||
|
||||
"github.com/jsimonetti/rtnetlink"
|
||||
"github.com/xtls/xray-core/transport/internet"
|
||||
linuxcap "kernel.org/pub/linux/libs/security/libcap/cap"
|
||||
)
|
||||
|
||||
var rtnetlink_conn *rtnetlink.Conn
|
||||
var cap_net_admin = 0
|
||||
|
||||
func nekorayLinuxProtect(fd int) bool {
|
||||
if cap_net_admin == 0 {
|
||||
str := strings.ToLower(linuxcap.GetProc().String())
|
||||
if strings.Contains(str, "cap_net_admin") || str == "=ep" {
|
||||
cap_net_admin = 1
|
||||
} else {
|
||||
cap_net_admin = -1
|
||||
}
|
||||
}
|
||||
|
||||
// check is in Tun Mode
|
||||
if is_fwmark_exist(514) {
|
||||
if cap_net_admin == 1 {
|
||||
// have permission
|
||||
if err := syscall.SetsockoptInt(fd, syscall.SOL_SOCKET, syscall.SO_MARK, 514); err != nil {
|
||||
log.Println("syscall.SetsockoptInt:", err)
|
||||
return false
|
||||
}
|
||||
} else {
|
||||
// don't have permission
|
||||
if err := cmsgProtect(fd, "./protect"); err != nil {
|
||||
log.Println("cmsgProtect:", err)
|
||||
return false
|
||||
}
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
func cmsgProtect(fd int, unixPath string) error {
|
||||
socket, err := syscall.Socket(syscall.AF_UNIX, syscall.SOCK_STREAM, 0)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer syscall.Close(socket)
|
||||
|
||||
syscall.SetsockoptTimeval(socket, syscall.SOL_SOCKET, syscall.SO_RCVTIMEO, &syscall.Timeval{Sec: 3})
|
||||
syscall.SetsockoptTimeval(socket, syscall.SOL_SOCKET, syscall.SO_SNDTIMEO, &syscall.Timeval{Sec: 3})
|
||||
|
||||
err = syscall.Connect(socket, &syscall.SockaddrUnix{Name: unixPath})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
err = syscall.Sendmsg(socket, nil, syscall.UnixRights(fd), nil, 0)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
dummy := []byte{1}
|
||||
n, err := syscall.Read(socket, dummy)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if n != 1 {
|
||||
return fmt.Errorf("cmsgProtect protect failed")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func is_fwmark_exist(number int) bool {
|
||||
var err error
|
||||
|
||||
if rtnetlink_conn == nil {
|
||||
rtnetlink_conn, err = rtnetlink.Dial(nil)
|
||||
if err != nil {
|
||||
log.Println(err)
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
rules, err := rtnetlink_conn.Rule.List()
|
||||
if err != nil {
|
||||
rtnetlink_conn = nil
|
||||
return false
|
||||
}
|
||||
|
||||
for _, rule := range rules {
|
||||
if rule.Attributes != nil && rule.Attributes.FwMark != nil && uint32(number) == *rule.Attributes.FwMark {
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
func init() {
|
||||
internet.RegisterListenerController(func(network, address string, conn syscall.RawConn) error {
|
||||
conn.Control(func(fd uintptr) {
|
||||
nekorayLinuxProtect(int(fd))
|
||||
})
|
||||
return nil
|
||||
})
|
||||
internet.RegisterDialerController(func(network, address string, conn syscall.RawConn) error {
|
||||
conn.Control(func(fd uintptr) {
|
||||
nekorayLinuxProtect(int(fd))
|
||||
})
|
||||
return nil
|
||||
})
|
||||
underlyingNetDialer = &net.Dialer{
|
||||
Control: func(network, address string, c syscall.RawConn) error {
|
||||
c.Control(func(fd uintptr) {
|
||||
nekorayLinuxProtect(int(fd))
|
||||
})
|
||||
return nil
|
||||
},
|
||||
}
|
||||
}
|
||||
@ -1,91 +0,0 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"flag"
|
||||
"io"
|
||||
"log"
|
||||
"net"
|
||||
"net/http"
|
||||
"os"
|
||||
"syscall"
|
||||
|
||||
"github.com/jsimonetti/rtnetlink"
|
||||
linuxcap "kernel.org/pub/linux/libs/security/libcap/cap"
|
||||
)
|
||||
|
||||
func ToolBox() {
|
||||
//
|
||||
var protectListenPath string
|
||||
var protectFwMark int
|
||||
//
|
||||
flag.StringVar(&protectListenPath, "protect-listen-path", "", "Set unix protect server listen path (Linux ROOT only)")
|
||||
flag.IntVar(&protectFwMark, "protect-fwmark", 0, "Set unix protect fwmark (Linux ROOT only)")
|
||||
flag.CommandLine.Parse(os.Args[3:])
|
||||
//
|
||||
switch os.Args[2] {
|
||||
case "rule":
|
||||
{
|
||||
// Dial a connection to the rtnetlink socket
|
||||
conn, err := rtnetlink.Dial(nil)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
defer conn.Close()
|
||||
|
||||
// Request a list of rules
|
||||
rules, err := conn.Rule.List()
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
for _, rule := range rules {
|
||||
log.Printf("%+v", rule)
|
||||
log.Printf("%+v", rule.Attributes)
|
||||
}
|
||||
|
||||
for _, rule := range rules {
|
||||
if rule.Attributes.FwMark != nil {
|
||||
log.Printf("%+v", rule.Attributes)
|
||||
log.Println(*rule.Attributes.FwMark, *rule.Attributes.Table)
|
||||
}
|
||||
}
|
||||
}
|
||||
case "cap":
|
||||
{
|
||||
set := linuxcap.GetProc()
|
||||
if set != nil {
|
||||
log.Println(set)
|
||||
}
|
||||
}
|
||||
// case "protect":
|
||||
// {
|
||||
// if protectListenPath == "" {
|
||||
// log.Println("missing protect-listen-path")
|
||||
// return
|
||||
// }
|
||||
// protect_server.ServeProtect(protectListenPath, protectFwMark)
|
||||
// }
|
||||
case "btd": // Test the permission
|
||||
{
|
||||
d := &net.Dialer{
|
||||
Control: func(network, address string, c syscall.RawConn) (err error) {
|
||||
c.Control(func(fd uintptr) {
|
||||
err = syscall.BindToDevice(int(fd), os.Args[3])
|
||||
})
|
||||
return
|
||||
},
|
||||
}
|
||||
c := http.Client{
|
||||
Transport: &http.Transport{
|
||||
DialContext: d.DialContext,
|
||||
},
|
||||
}
|
||||
resp, err := c.Get(os.Args[4])
|
||||
if err != nil {
|
||||
log.Fatalln(err)
|
||||
}
|
||||
io.Copy(os.Stdout, resp.Body)
|
||||
resp.Body.Close()
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1,6 +0,0 @@
|
||||
//go:build !windows && !linux
|
||||
|
||||
package main
|
||||
|
||||
func ToolBox() {
|
||||
}
|
||||
@ -1,27 +0,0 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"log"
|
||||
"net"
|
||||
"os"
|
||||
)
|
||||
|
||||
func ToolBox() {
|
||||
switch os.Args[2] {
|
||||
case "if":
|
||||
{
|
||||
intfs, err := net.Interfaces()
|
||||
if err != nil {
|
||||
log.Fatalln(err)
|
||||
}
|
||||
for _, intf := range intfs {
|
||||
log.Println(intf)
|
||||
}
|
||||
for _, route := range routes {
|
||||
log.Println(route)
|
||||
}
|
||||
log.Println("TUN:", getNekorayTunIndex())
|
||||
log.Println("Upstream:", getBindInterfaceIndex("8.8.8.8:8888"))
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -17,7 +17,7 @@ func Launcher() {
|
||||
_debug := flag.Bool("debug", false, "Debug mode")
|
||||
flag.Parse()
|
||||
|
||||
cmd := exec.Command("./nekoray", flag.Args()...)
|
||||
cmd := exec.Command("./nekobox", flag.Args()...)
|
||||
|
||||
ld_env := "LD_LIBRARY_PATH=" + filepath.Join(wd, "./usr/lib")
|
||||
qt_plugin_env := "QT_PLUGIN_PATH=" + filepath.Join(wd, "./usr/plugins")
|
||||
|
||||
@ -30,9 +30,9 @@ func main() {
|
||||
time.Sleep(time.Second)
|
||||
Updater()
|
||||
// 3. start
|
||||
exec.Command("./nekoray.exe").Start()
|
||||
exec.Command("./nekobox.exe").Start()
|
||||
} else {
|
||||
// 1. nekoray stop it self and run "updater.exe"
|
||||
// 1. main prog quit and run "updater.exe"
|
||||
Copy("./updater.exe", "./updater.old")
|
||||
exec.Command("./updater.old", os.Args[1:]...).Start()
|
||||
}
|
||||
@ -43,7 +43,7 @@ func main() {
|
||||
if os.Getenv("NKR_FROM_LAUNCHER") == "1" {
|
||||
Launcher()
|
||||
} else {
|
||||
exec.Command("./nekoray").Start()
|
||||
exec.Command("./nekobox").Start()
|
||||
}
|
||||
}
|
||||
return
|
||||
|
||||
@ -71,6 +71,11 @@ func Updater() {
|
||||
os.RemoveAll("./nekoray_update")
|
||||
os.RemoveAll("./nekoray.zip")
|
||||
os.RemoveAll("./nekoray.tar.gz")
|
||||
|
||||
// nekoray -> nekobox
|
||||
os.Remove("./nekoray.exe")
|
||||
os.Remove("./nekoray.png")
|
||||
os.Remove("./nekoray_core.exe")
|
||||
}
|
||||
|
||||
func Exist(path string) bool {
|
||||
|
||||
@ -7,6 +7,7 @@ import (
|
||||
"grpc_server/gen"
|
||||
"io"
|
||||
"log"
|
||||
"math"
|
||||
"net"
|
||||
"net/http"
|
||||
"strings"
|
||||
@ -16,6 +17,11 @@ import (
|
||||
"github.com/matsuridayo/libneko/speedtest"
|
||||
)
|
||||
|
||||
const (
|
||||
KiB = 1024
|
||||
MiB = 1024 * KiB
|
||||
)
|
||||
|
||||
func getBetweenStr(str, start, end string) string {
|
||||
n := strings.Index(str, start)
|
||||
if n == -1 {
|
||||
@ -37,7 +43,7 @@ func DoFullTest(ctx context.Context, in *gen.TestReq, instance interface{}) (out
|
||||
// Latency
|
||||
var latency string
|
||||
if in.FullLatency {
|
||||
t, _ := speedtest.UrlTest(httpClient, in.Url, in.Timeout)
|
||||
t, _ := speedtest.UrlTest(httpClient, in.Url, in.Timeout, speedtest.UrlTestStandard_RTT)
|
||||
out.Ms = t
|
||||
if t > 0 {
|
||||
latency = fmt.Sprint(t, "ms")
|
||||
@ -124,11 +130,14 @@ func DoFullTest(ctx context.Context, in *gen.TestReq, instance interface{}) (out
|
||||
if err == nil && resp != nil && resp.Body != nil {
|
||||
bodyClose = resp.Body
|
||||
defer resp.Body.Close()
|
||||
//
|
||||
time_start := time.Now()
|
||||
|
||||
timeStart := time.Now()
|
||||
n, _ := io.Copy(io.Discard, resp.Body)
|
||||
time_end := time.Now()
|
||||
result <- fmt.Sprintf("%.2fMiB/s", (float64(n)/time_end.Sub(time_start).Seconds())/1048576)
|
||||
timeEnd := time.Now()
|
||||
|
||||
duration := math.Max(timeEnd.Sub(timeStart).Seconds(), 0.000001)
|
||||
resultSpeed := (float64(n) / duration) / MiB
|
||||
result <- fmt.Sprintf("%.2fMiB/s", resultSpeed)
|
||||
} else {
|
||||
result <- "Error"
|
||||
}
|
||||
|
||||
@ -94,10 +94,7 @@ func RunCore(setupCore func(), server gen.LibcoreServiceServer) {
|
||||
)
|
||||
gen.RegisterLibcoreServiceServer(s, server)
|
||||
|
||||
name := "nekoray_core"
|
||||
if neko_common.RunMode == neko_common.RunMode_NekoBox_Core {
|
||||
name = "nekobox_core"
|
||||
}
|
||||
name := "nekobox_core"
|
||||
|
||||
log.Printf("%s grpc server listening at %v\n", name, lis.Addr())
|
||||
if err := s.Serve(lis); err != nil {
|
||||
|
||||
@ -53,10 +53,6 @@ func (s *BaseServer) Update(ctx context.Context, in *gen.UpdateReq) (*gen.Update
|
||||
var search string
|
||||
if runtime.GOOS == "windows" && runtime.GOARCH == "amd64" {
|
||||
search = "windows64"
|
||||
// check Qt5 update after nekoray v3.3
|
||||
if _, err := os.Stat("../Qt5Core.dll"); err == nil {
|
||||
search = "windows7-x64"
|
||||
}
|
||||
} else if runtime.GOOS == "linux" && runtime.GOARCH == "amd64" {
|
||||
search = "linux64"
|
||||
} else if runtime.GOOS == "darwin" {
|
||||
|
||||
@ -6,8 +6,6 @@ source libs/env_deploy.sh
|
||||
[ "$GOOS" == "windows" ] && [ "$GOARCH" == "arm64" ] && DEST=$DEPLOYMENT/windows-arm64 || true
|
||||
[ "$GOOS" == "linux" ] && [ "$GOARCH" == "amd64" ] && DEST=$DEPLOYMENT/linux64 || true
|
||||
[ "$GOOS" == "linux" ] && [ "$GOARCH" == "arm64" ] && DEST=$DEPLOYMENT/linux-arm64 || true
|
||||
[ "$GOOS" == "darwin" ] && [ "$GOARCH" == "amd64" ] && DEST=$DEPLOYMENT/macos-amd64 || true
|
||||
[ "$GOOS" == "darwin" ] && [ "$GOARCH" == "arm64" ] && DEST=$DEPLOYMENT/macos-arm64 || true
|
||||
if [ -z $DEST ]; then
|
||||
echo "Please set GOOS GOARCH"
|
||||
exit 1
|
||||
@ -23,16 +21,7 @@ pushd go/cmd/updater
|
||||
[ "$GOOS" == "linux" ] && mv $DEST/updater $DEST/launcher || true
|
||||
popd
|
||||
|
||||
#### Go: nekoray_core ####
|
||||
neko_common="github.com/matsuridayo/libneko/neko_common"
|
||||
pushd ../Xray-core
|
||||
Version_Xray=$(git log --pretty=format:'%h' -n 1)
|
||||
popd
|
||||
pushd go/cmd/nekoray_core
|
||||
go build -v -o $DEST -trimpath -ldflags "-w -s -X $neko_common.Version_v2ray=$Version_Xray -X $neko_common.Version_neko=$version_standalone"
|
||||
popd
|
||||
|
||||
#### Go: nekobox_core ####
|
||||
pushd go/cmd/nekobox_core
|
||||
go build -v -o $DEST -trimpath -ldflags "-w -s -X $neko_common.Version_neko=$version_standalone" -tags "with_clash_api,with_gvisor,with_quic,with_wireguard,with_utls,with_ech"
|
||||
go build -v -o $DEST -trimpath -ldflags "-w -s -X github.com/matsuridayo/libneko/neko_common.Version_neko=$version_standalone" -tags "with_clash_api,with_gvisor,with_quic,with_wireguard,with_utls,with_ech"
|
||||
popd
|
||||
|
||||
@ -7,7 +7,7 @@ rm -rf $DEST
|
||||
mkdir -p $DEST
|
||||
|
||||
#### copy binary ####
|
||||
cp $BUILD/nekoray $DEST
|
||||
cp $BUILD/nekobox $DEST
|
||||
|
||||
#### Download: prebuilt runtime ####
|
||||
curl -Lso usr.zip https://github.com/MatsuriDayo/nekoray_qt_runtime/releases/download/20220503/20230202-5.12.8-ubuntu20.04-linux64.zip
|
||||
|
||||
@ -1,29 +0,0 @@
|
||||
#!/bin/bash
|
||||
set -e
|
||||
|
||||
if [[ $(uname -m) == 'arm64' ]]; then
|
||||
ARCH="arm64"
|
||||
else
|
||||
ARCH="amd64"
|
||||
fi
|
||||
|
||||
source libs/env_deploy.sh
|
||||
DEST=$DEPLOYMENT/macos-$ARCH
|
||||
rm -rf $DEST
|
||||
mkdir -p $DEST
|
||||
|
||||
#### copy golang & public_res => .app ####
|
||||
pushd download-artifact
|
||||
find . -name artifacts.tgz | xargs -n1 tar xvzf
|
||||
mv deployment/public_res/* deployment/macos-$ARCH
|
||||
mv deployment/macos-$ARCH/* $BUILD/nekoray.app/Contents/MacOS
|
||||
popd
|
||||
|
||||
#### deploy qt & DLL runtime => .app ####
|
||||
pushd $BUILD
|
||||
macdeployqt nekoray.app -verbose=3
|
||||
popd
|
||||
|
||||
#### pack dmg ###
|
||||
sudo npm install -g appdmg
|
||||
appdmg appdmg.json $DEST/nekoray.dmg
|
||||
@ -2,20 +2,16 @@
|
||||
set -e
|
||||
|
||||
source libs/env_deploy.sh
|
||||
if [ "$DL_QT_VER" == "5.15" ]; then
|
||||
DEST=$DEPLOYMENT/windows7-x64
|
||||
else
|
||||
DEST=$DEPLOYMENT/windows64
|
||||
fi
|
||||
DEST=$DEPLOYMENT/windows64
|
||||
rm -rf $DEST
|
||||
mkdir -p $DEST
|
||||
|
||||
#### copy exe ####
|
||||
cp $BUILD/nekoray.exe $DEST
|
||||
cp $BUILD/nekobox.exe $DEST
|
||||
|
||||
#### deploy qt & DLL runtime ####
|
||||
pushd $DEST
|
||||
windeployqt nekoray.exe --no-compiler-runtime --no-system-d3d-compiler --no-opengl-sw --verbose 2
|
||||
windeployqt nekobox.exe --no-compiler-runtime --no-system-d3d-compiler --no-opengl-sw --verbose 2
|
||||
rm -rf translations
|
||||
rm -rf libEGL.dll libGLESv2.dll Qt6Pdf.dll
|
||||
|
||||
|
||||
@ -3,7 +3,7 @@ cd qtsdk
|
||||
if [ "$DL_QT_VER" == "5.15" ]; then
|
||||
curl -LSO https://github.com/MatsuriDayo/nekoray_qt_runtime/releases/download/20220503/Qt5.15.7-Windows-x86_64-VS2019-16.11.20-20221103.7z
|
||||
else
|
||||
curl -LSO https://github.com/MatsuriDayo/nekoray_qt_runtime/releases/download/20220503/Qt6.5.2-Windows-x86_64-VS2022-17.6.5-20230803.7z
|
||||
curl -LSO https://github.com/MatsuriDayo/nekoray_qt_runtime/releases/download/20220503/Qt6.7.2-Windows-x86_64-VS2022-17.10.3-20240621.7z
|
||||
fi
|
||||
7z x *.7z
|
||||
rm *.7z
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
SRC_ROOT="$PWD"
|
||||
DEPLOYMENT="$SRC_ROOT/deployment"
|
||||
BUILD="$SRC_ROOT/build"
|
||||
version_standalone="nekoray-"$(cat nekoray_version.txt)
|
||||
version_standalone="nekoray-"$(cat nekoray_version.txt) # 下次改
|
||||
|
||||
@ -7,24 +7,35 @@ source libs/get_source_env.sh
|
||||
pushd ..
|
||||
|
||||
####
|
||||
if [ ! -d "sing-box-extra" ]; then
|
||||
git clone --no-checkout https://github.com/MatsuriDayo/sing-box-extra.git
|
||||
fi
|
||||
pushd sing-box-extra
|
||||
git checkout "$COMMIT_SING_BOX_EXTRA"
|
||||
|
||||
ENV_SING_BOX_EXTRA=1
|
||||
source $SRC_ROOT/libs/get_source_env.sh
|
||||
NO_ENV=1 ./libs/get_source.sh
|
||||
if [ ! -d "sing-box" ]; then
|
||||
git clone --no-checkout https://github.com/MatsuriDayo/sing-box.git
|
||||
fi
|
||||
pushd sing-box
|
||||
git checkout "$COMMIT_SING_BOX"
|
||||
|
||||
popd
|
||||
|
||||
####
|
||||
if [ ! -d "Xray-core" ]; then
|
||||
git clone --no-checkout https://github.com/MatsuriDayo/Xray-core.git
|
||||
|
||||
if [ ! -d "sing-quic" ]; then
|
||||
git clone --no-checkout https://github.com/MatsuriDayo/sing-quic.git
|
||||
fi
|
||||
pushd Xray-core
|
||||
git checkout "$COMMIT_MATSURI_XRAY"
|
||||
popd
|
||||
pushd sing-quic
|
||||
git checkout "$COMMIT_SING_QUIC"
|
||||
|
||||
popd
|
||||
|
||||
####
|
||||
|
||||
if [ ! -d "libneko" ]; then
|
||||
git clone --no-checkout https://github.com/MatsuriDayo/libneko.git
|
||||
fi
|
||||
pushd libneko
|
||||
git checkout "$COMMIT_LIBNEKO"
|
||||
|
||||
popd
|
||||
|
||||
####
|
||||
|
||||
popd
|
||||
|
||||
@ -1,9 +1,3 @@
|
||||
if [ ! -z $ENV_NEKORAY ]; then
|
||||
export COMMIT_SING_BOX_EXTRA="f95483a6bfe3894efdf917f4ccceac8c0aec1693"
|
||||
export COMMIT_MATSURI_XRAY="01208225ee7e508044cca8eb6776a117bcecd997"
|
||||
fi
|
||||
|
||||
if [ ! -z $ENV_SING_BOX_EXTRA ]; then
|
||||
source libs/get_source_env.sh
|
||||
# export COMMIT_LIBNEKO="a26f0dbb1467bd181f76e2560e956633d9637e9d"
|
||||
fi
|
||||
export COMMIT_SING_BOX="06557f6cef23160668122a17a818b378b5a216b5"
|
||||
export COMMIT_SING_QUIC="b49ce60d9b3622d5238fee96bfd3c5f6e3915b42"
|
||||
export COMMIT_LIBNEKO="1c47a3af71990a7b2192e03292b4d246c308ef0b"
|
||||
|
||||
@ -2,37 +2,37 @@
|
||||
|
||||
sudo apt-get install fuse -y
|
||||
|
||||
cp -r linux64 nekoray.AppDir
|
||||
cp -r linux64 nekobox.AppDir
|
||||
|
||||
# The file for Appimage
|
||||
|
||||
rm nekoray.AppDir/launcher
|
||||
rm nekobox.AppDir/launcher
|
||||
|
||||
cat >nekoray.AppDir/nekoray.desktop <<-EOF
|
||||
cat >nekobox.AppDir/nekobox.desktop <<-EOF
|
||||
[Desktop Entry]
|
||||
Name=nekoray
|
||||
Exec=echo "NekoRay started"
|
||||
Icon=nekoray
|
||||
Name=nekobox
|
||||
Exec=echo "nekobox started"
|
||||
Icon=nekobox
|
||||
Type=Application
|
||||
Categories=Network
|
||||
EOF
|
||||
|
||||
cat >nekoray.AppDir/AppRun <<-EOF
|
||||
cat >nekobox.AppDir/AppRun <<-EOF
|
||||
#!/bin/bash
|
||||
echo "PATH: \${PATH}"
|
||||
echo "NekoRay runing on: \$APPDIR"
|
||||
LD_LIBRARY_PATH=\${APPDIR}/usr/lib QT_PLUGIN_PATH=\${APPDIR}/usr/plugins \${APPDIR}/nekoray -appdata "\$@"
|
||||
echo "nekobox runing on: \$APPDIR"
|
||||
LD_LIBRARY_PATH=\${APPDIR}/usr/lib QT_PLUGIN_PATH=\${APPDIR}/usr/plugins \${APPDIR}/nekobox -appdata "\$@"
|
||||
EOF
|
||||
|
||||
chmod +x nekoray.AppDir/AppRun
|
||||
chmod +x nekobox.AppDir/AppRun
|
||||
|
||||
# build
|
||||
|
||||
curl -fLSO https://github.com/AppImage/AppImageKit/releases/latest/download/appimagetool-x86_64.AppImage
|
||||
chmod +x appimagetool-x86_64.AppImage
|
||||
./appimagetool-x86_64.AppImage nekoray.AppDir
|
||||
./appimagetool-x86_64.AppImage nekobox.AppDir
|
||||
|
||||
# clean
|
||||
|
||||
rm appimagetool-x86_64.AppImage
|
||||
rm -rf nekoray.AppDir
|
||||
rm -rf nekobox.AppDir
|
||||
|
||||
@ -24,9 +24,9 @@ if [ ! -s /usr/share/applications/nekoray.desktop ]; then
|
||||
cat >/usr/share/applications/nekoray.desktop<<-END
|
||||
[Desktop Entry]
|
||||
Name=nekoray
|
||||
Comment=Qt based cross-platform GUI proxy configuration manager (backend: Xray / sing-box)
|
||||
Exec=sh -c "PATH=/opt/nekoray:\$PATH /opt/nekoray/nekoray -appdata"
|
||||
Icon=/opt/nekoray/nekoray.png
|
||||
Comment=Qt based cross-platform GUI proxy configuration manager (backend: sing-box)
|
||||
Exec=sh -c "PATH=/opt/nekoray:\$PATH /opt/nekoray/nekobox -appdata"
|
||||
Icon=/opt/nekoray/nekobox.png
|
||||
Terminal=false
|
||||
Type=Application
|
||||
Categories=Network;Application;
|
||||
|
||||
@ -18,7 +18,7 @@ namespace NekoGui {
|
||||
|
||||
namespace CoreType {
|
||||
enum CoreType {
|
||||
V2RAY,
|
||||
V2RAY, // DO NOT USE
|
||||
SING_BOX,
|
||||
};
|
||||
}
|
||||
|
||||
@ -18,7 +18,7 @@ namespace NekoGui_network {
|
||||
if (NekoGui::dataStore->sub_use_proxy) {
|
||||
QNetworkProxy p;
|
||||
// Note: sing-box mixed socks5 protocol error
|
||||
p.setType(IS_NEKO_BOX ? QNetworkProxy::HttpProxy : QNetworkProxy::Socks5Proxy);
|
||||
p.setType(QNetworkProxy::HttpProxy);
|
||||
p.setHostName("127.0.0.1");
|
||||
p.setPort(NekoGui::dataStore->inbound_socks_port);
|
||||
if (NekoGui::dataStore->inbound_auth->NeedAuth()) {
|
||||
@ -51,7 +51,7 @@ namespace NekoGui_network {
|
||||
for (const auto &err: errors) {
|
||||
error_str << err.errorString();
|
||||
}
|
||||
MW_show_log(QString("SSL Errors: %1 %2").arg(error_str.join(","), NekoGui::dataStore->sub_insecure ? "(Ignored)" : ""));
|
||||
MW_show_log(QStringLiteral("SSL Errors: %1 %2").arg(error_str.join(","), NekoGui::dataStore->sub_insecure ? "(Ignored)" : ""));
|
||||
});
|
||||
// Wait for response
|
||||
auto abortTimer = new QTimer;
|
||||
|
||||
@ -237,7 +237,6 @@ namespace NekoGui {
|
||||
_add(new configItem("current_group", ¤t_group, itemType::integer));
|
||||
_add(new configItem("inbound_address", &inbound_address, itemType::string));
|
||||
_add(new configItem("inbound_socks_port", &inbound_socks_port, itemType::integer));
|
||||
_add(new configItem("inbound_http_port", &inbound_http_port, itemType::integer));
|
||||
_add(new configItem("log_level", &log_level, itemType::string));
|
||||
_add(new configItem("mux_protocol", &mux_protocol, itemType::string));
|
||||
_add(new configItem("mux_concurrency", &mux_concurrency, itemType::integer));
|
||||
@ -248,7 +247,6 @@ namespace NekoGui {
|
||||
_add(new configItem("theme", &theme, itemType::string));
|
||||
_add(new configItem("custom_inbound", &custom_inbound, itemType::string));
|
||||
_add(new configItem("custom_route", &custom_route_global, itemType::string));
|
||||
_add(new configItem("v2ray_asset_dir", &v2ray_asset_dir, itemType::string));
|
||||
_add(new configItem("sub_use_proxy", &sub_use_proxy, itemType::boolean));
|
||||
_add(new configItem("remember_id", &remember_id, itemType::integer));
|
||||
_add(new configItem("remember_enable", &remember_enable, itemType::boolean));
|
||||
@ -276,7 +274,6 @@ namespace NekoGui {
|
||||
_add(new configItem("sub_clear", &sub_clear, itemType::boolean));
|
||||
_add(new configItem("sub_insecure", &sub_insecure, itemType::boolean));
|
||||
_add(new configItem("sub_auto_update", &sub_auto_update, itemType::integer));
|
||||
_add(new configItem("enable_js_hook", &enable_js_hook, itemType::integer));
|
||||
_add(new configItem("log_ignore", &log_ignore, itemType::stringList));
|
||||
_add(new configItem("start_minimal", &start_minimal, itemType::boolean));
|
||||
_add(new configItem("max_log_line", &max_log_line, itemType::integer));
|
||||
@ -285,12 +282,7 @@ namespace NekoGui {
|
||||
_add(new configItem("core_box_clash_api", &core_box_clash_api, itemType::integer));
|
||||
_add(new configItem("core_box_clash_api_secret", &core_box_clash_api_secret, itemType::string));
|
||||
_add(new configItem("core_box_underlying_dns", &core_box_underlying_dns, itemType::string));
|
||||
_add(new configItem("core_ray_direct_dns", &core_ray_direct_dns, itemType::boolean));
|
||||
_add(new configItem("core_ray_freedom_domainStrategy", &core_ray_freedom_domainStrategy, itemType::string));
|
||||
_add(new configItem("vpn_internal_tun", &vpn_internal_tun, itemType::boolean));
|
||||
#ifdef Q_OS_WIN
|
||||
_add(new configItem("core_ray_windows_disable_auto_interface", &core_ray_windows_disable_auto_interface, itemType::boolean));
|
||||
#endif
|
||||
}
|
||||
|
||||
void DataStore::UpdateStartedId(int id) {
|
||||
@ -311,11 +303,7 @@ namespace NekoGui {
|
||||
if (isDefault) {
|
||||
QString version = SubStrBefore(NKR_VERSION, "-");
|
||||
if (!version.contains(".")) version = "2.0";
|
||||
if (IS_NEKO_BOX) {
|
||||
return "NekoBox/PC/" + version + " (Prefer ClashMeta Format)";
|
||||
} else {
|
||||
return "NekoRay/PC/" + version + " (Prefer ClashMeta Format)";
|
||||
}
|
||||
return "NekoBox/PC/" + version + " (Prefer ClashMeta Format)";
|
||||
}
|
||||
return user_agent;
|
||||
}
|
||||
@ -333,15 +321,11 @@ namespace NekoGui {
|
||||
block_domain =
|
||||
"geosite:category-ads-all\n"
|
||||
"domain:appcenter.ms\n"
|
||||
"domain:app-measurement.com\n"
|
||||
"domain:firebase.io\n"
|
||||
"domain:crashlytics.com\n"
|
||||
"domain:google-analytics.com";
|
||||
}
|
||||
if (IS_NEKO_BOX) {
|
||||
if (!Preset::SingBox::DomainStrategy.contains(domain_strategy)) domain_strategy = "";
|
||||
if (!Preset::SingBox::DomainStrategy.contains(outbound_domain_strategy)) outbound_domain_strategy = "";
|
||||
"domain:crashlytics.com\n";
|
||||
}
|
||||
if (!Preset::SingBox::DomainStrategy.contains(domain_strategy)) domain_strategy = "";
|
||||
if (!Preset::SingBox::DomainStrategy.contains(outbound_domain_strategy)) outbound_domain_strategy = "";
|
||||
_add(new configItem("direct_ip", &this->direct_ip, itemType::string));
|
||||
_add(new configItem("direct_domain", &this->direct_domain, itemType::string));
|
||||
_add(new configItem("proxy_ip", &this->proxy_ip, itemType::string));
|
||||
@ -365,7 +349,7 @@ namespace NekoGui {
|
||||
}
|
||||
|
||||
QString Routing::DisplayRouting() const {
|
||||
return QString("[Proxy] %1\n[Proxy] %2\n[Direct] %3\n[Direct] %4\n[Block] %5\n[Block] %6\n[Default Outbound] %7\n[DNS] %8")
|
||||
return QStringLiteral("[Proxy] %1\n[Proxy] %2\n[Direct] %3\n[Direct] %4\n[Block] %5\n[Block] %6\n[Default Outbound] %7\n[DNS] %8")
|
||||
.arg(SplitLinesSkipSharp(proxy_domain).join(","), 10)
|
||||
.arg(SplitLinesSkipSharp(proxy_ip).join(","), 10)
|
||||
.arg(SplitLinesSkipSharp(direct_domain).join(","), 10)
|
||||
@ -431,16 +415,13 @@ namespace NekoGui {
|
||||
// System Utils
|
||||
|
||||
QString FindCoreAsset(const QString &name) {
|
||||
QStringList search{NekoGui::dataStore->v2ray_asset_dir};
|
||||
QStringList search{};
|
||||
search << QApplication::applicationDirPath();
|
||||
search << "/usr/share/sing-geoip";
|
||||
search << "/usr/share/sing-geosite";
|
||||
search << "/usr/share/xray";
|
||||
search << "/usr/local/share/xray";
|
||||
search << "/opt/xray";
|
||||
search << "/usr/share/v2ray";
|
||||
search << "/usr/local/share/v2ray";
|
||||
search << "/opt/v2ray";
|
||||
search << "/usr/share/sing-box";
|
||||
search << "/usr/lib/nekobox";
|
||||
search << "/usr/share/nekobox";
|
||||
for (const auto &dir: search) {
|
||||
if (dir.isEmpty()) continue;
|
||||
QFileInfo asset(dir + "/" + name);
|
||||
|
||||
@ -8,7 +8,7 @@
|
||||
// Switch core support
|
||||
|
||||
namespace NekoGui {
|
||||
inline int coreType = CoreType::V2RAY;
|
||||
inline int coreType = CoreType::SING_BOX;
|
||||
|
||||
QString FindCoreAsset(const QString &name);
|
||||
|
||||
@ -17,7 +17,5 @@ namespace NekoGui {
|
||||
bool IsAdmin();
|
||||
} // namespace NekoGui
|
||||
|
||||
#define IS_NEKO_BOX (NekoGui::coreType == NekoGui::CoreType::SING_BOX)
|
||||
#define IS_NEKO_BOX_INTERNAL_TUN (IS_NEKO_BOX && NekoGui::dataStore->vpn_internal_tun)
|
||||
#define ROUTES_PREFIX_NAME QString(IS_NEKO_BOX ? "routes_box" : "routes")
|
||||
#define ROUTES_PREFIX_NAME QStringLiteral("routes_box")
|
||||
#define ROUTES_PREFIX QString(ROUTES_PREFIX_NAME + "/")
|
||||
|
||||
@ -14,9 +14,9 @@ namespace NekoGui {
|
||||
QString custom = "{\"rules\": []}";
|
||||
|
||||
// DNS
|
||||
QString remote_dns = "https://8.8.8.8/dns-query";
|
||||
QString remote_dns = "https://dns.google/dns-query";
|
||||
QString remote_dns_strategy = "";
|
||||
QString direct_dns = "localhost";
|
||||
QString direct_dns = "https://doh.pub/dns-query";
|
||||
QString direct_dns_strategy = "";
|
||||
bool dns_routing = true;
|
||||
bool use_dns_object = false;
|
||||
@ -93,7 +93,7 @@ namespace NekoGui {
|
||||
// Saved
|
||||
|
||||
// Misc
|
||||
QString log_level = "warning";
|
||||
QString log_level = "info";
|
||||
QString test_latency_url = "http://cp.cloudflare.com/";
|
||||
QString test_download_url = "http://cachefly.cachefly.net/10mb.test";
|
||||
int test_download_timeout = 30;
|
||||
@ -102,12 +102,11 @@ namespace NekoGui {
|
||||
int traffic_loop_interval = 1000;
|
||||
bool connection_statistics = false;
|
||||
int current_group = 0; // group id
|
||||
QString mux_protocol = "";
|
||||
QString mux_protocol = "h2mux";
|
||||
bool mux_padding = false;
|
||||
int mux_concurrency = 8;
|
||||
bool mux_default_on = false;
|
||||
QString theme = "0";
|
||||
QString v2ray_asset_dir = "";
|
||||
int language = 0;
|
||||
QString mw_size = "";
|
||||
bool check_include_pre = false;
|
||||
@ -126,7 +125,6 @@ namespace NekoGui {
|
||||
|
||||
// Security
|
||||
bool skip_cert = false;
|
||||
int enable_js_hook = 0;
|
||||
QString utlsFingerprint = "";
|
||||
|
||||
// Remember
|
||||
@ -137,7 +135,6 @@ namespace NekoGui {
|
||||
// Socks & HTTP Inbound
|
||||
QString inbound_address = "127.0.0.1";
|
||||
int inbound_socks_port = 2080; // or Mixed
|
||||
int inbound_http_port = 2081;
|
||||
InboundAuthorization *inbound_auth = new InboundAuthorization;
|
||||
QString custom_inbound = "{\"inbounds\": []}";
|
||||
|
||||
@ -167,9 +164,6 @@ namespace NekoGui {
|
||||
int core_box_clash_api = -9090;
|
||||
QString core_box_clash_api_secret = "";
|
||||
QString core_box_underlying_dns = "";
|
||||
bool core_ray_direct_dns = false;
|
||||
bool core_ray_windows_disable_auto_interface = false;
|
||||
QString core_ray_freedom_domainStrategy = "";
|
||||
|
||||
// Other Core
|
||||
ExtraCore *extraCore = new ExtraCore;
|
||||
|
||||
@ -8,8 +8,8 @@
|
||||
|
||||
//
|
||||
|
||||
inline QString software_name = "NekoRay";
|
||||
inline QString software_core_name = "Xray";
|
||||
inline QString software_name = "NekoBox";
|
||||
inline QString software_core_name = "sing-box";
|
||||
|
||||
// Main Functions
|
||||
|
||||
|
||||
148
main/QJS.cpp
148
main/QJS.cpp
@ -1,148 +0,0 @@
|
||||
#include "QJS.hpp"
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#define JS_STRICT_NAN_BOXING
|
||||
#endif
|
||||
|
||||
#include "3rdparty/qjs/nekoray_qjs.h"
|
||||
#include "main/NekoGui.hpp"
|
||||
|
||||
namespace qjs {
|
||||
#ifndef NKR_NO_QUICKJS
|
||||
namespace exception {
|
||||
static void js_dump_obj(JSContext *ctx, QString &out, JSValueConst val) {
|
||||
const char *str;
|
||||
|
||||
str = JS_ToCString(ctx, val);
|
||||
if (str) {
|
||||
out.append(str);
|
||||
out.append('\n');
|
||||
JS_FreeCString(ctx, str);
|
||||
} else {
|
||||
out += "[exception]\n";
|
||||
}
|
||||
}
|
||||
|
||||
static void js_std_dump_error1(JSContext *ctx, QString &out, JSValueConst exception_val) {
|
||||
JSValue val;
|
||||
auto is_error = JS_IsError(ctx, exception_val);
|
||||
js_dump_obj(ctx, out, exception_val);
|
||||
if (is_error) {
|
||||
val = JS_GetPropertyStr(ctx, exception_val, "stack");
|
||||
if (!JS_IsUndefined(val)) {
|
||||
js_dump_obj(ctx, out, val);
|
||||
}
|
||||
JS_FreeValue(ctx, val);
|
||||
}
|
||||
}
|
||||
|
||||
QString js_std_dump_error(JSContext *ctx) {
|
||||
QString result;
|
||||
JSValue exception_val;
|
||||
|
||||
exception_val = JS_GetException(ctx);
|
||||
js_std_dump_error1(ctx, result, exception_val);
|
||||
JS_FreeValue(ctx, exception_val);
|
||||
|
||||
return result;
|
||||
}
|
||||
} // namespace exception
|
||||
|
||||
JSValue func_log(JSContext *ctx, JSValue this_val, int argc, JSValue *argv) {
|
||||
QString qString;
|
||||
|
||||
int i;
|
||||
const char *str;
|
||||
size_t len;
|
||||
|
||||
for (i = 0; i < argc; i++) {
|
||||
if (i != 0) qString.append(' ');
|
||||
str = JS_ToCStringLen(ctx, &len, argv[i]);
|
||||
if (!str)
|
||||
return JS_EXCEPTION;
|
||||
qString.append(str);
|
||||
JS_FreeCString(ctx, str);
|
||||
}
|
||||
|
||||
MW_show_log(qString);
|
||||
qDebug() << "func_log:" << qString;
|
||||
|
||||
return JS_UNDEFINED;
|
||||
}
|
||||
#endif
|
||||
|
||||
#define NEKO_CTX ((nekoray_qjs_context *) this->neko_ctx)
|
||||
|
||||
QJS::QJS() {
|
||||
#ifndef NKR_NO_QUICKJS
|
||||
MW_show_log("loading quickjs......");
|
||||
//
|
||||
this->neko_ctx = malloc(sizeof(nekoray_qjs_context));
|
||||
nekoray_qjs_new_arg arg;
|
||||
arg.neko_ctx = NEKO_CTX;
|
||||
arg.enable_std = NekoGui::dataStore->enable_js_hook == 2 ? 1 : 0;
|
||||
arg.func_log = func_log;
|
||||
nekoray_qjs_new(arg);
|
||||
#endif
|
||||
}
|
||||
|
||||
QJS::QJS(const QByteArray &jsSource) : QJS() {
|
||||
this->Eval(jsSource);
|
||||
}
|
||||
|
||||
QJS::~QJS() {
|
||||
#ifndef NKR_NO_QUICKJS
|
||||
nekoray_qjs_free(NEKO_CTX);
|
||||
free(this->neko_ctx);
|
||||
#endif
|
||||
}
|
||||
|
||||
QString QJS::Eval(const QByteArray &jsSource) const {
|
||||
#ifndef NKR_NO_QUICKJS
|
||||
auto result = nekoray_qjs_eval(NEKO_CTX, jsSource.data(), jsSource.length());
|
||||
if (JS_IsException(result)) {
|
||||
MW_show_log(exception::js_std_dump_error(NEKO_CTX->ctx));
|
||||
return {};
|
||||
}
|
||||
auto cString = JS_ToCString(NEKO_CTX->ctx, result);
|
||||
QString qString(cString);
|
||||
JS_FreeCString(NEKO_CTX->ctx, cString);
|
||||
JS_FreeValue(NEKO_CTX->ctx, result);
|
||||
return qString;
|
||||
#else
|
||||
return {};
|
||||
#endif
|
||||
}
|
||||
|
||||
QString QJS::Eval(const QString &jsSource) const {
|
||||
return this->Eval(jsSource.toUtf8());
|
||||
}
|
||||
|
||||
QString QJS::EvalFile(const QString &jsPath) const {
|
||||
return this->Eval(ReadFile(jsPath));
|
||||
}
|
||||
|
||||
QString QJS::EvalFunction(const QString &funcName, const QString &arg) const {
|
||||
#ifndef NKR_NO_QUICKJS
|
||||
auto ba1 = arg.toUtf8();
|
||||
JSValue globalObj = JS_GetGlobalObject(NEKO_CTX->ctx);
|
||||
JSValue tempObj = JS_NewStringLen(NEKO_CTX->ctx, ba1.data(), ba1.length());
|
||||
JS_SetPropertyStr(NEKO_CTX->ctx, globalObj, "tempObj", tempObj);
|
||||
auto result = this->Eval(QString("%1(tempObj)").arg(funcName));
|
||||
JS_DeleteProperty(NEKO_CTX->ctx, globalObj, JS_NewAtom(NEKO_CTX->ctx, "tempObj"), 1); // Free tempObj
|
||||
JS_FreeValue(NEKO_CTX->ctx, globalObj);
|
||||
return result;
|
||||
#else
|
||||
return {};
|
||||
#endif
|
||||
}
|
||||
|
||||
QByteArray ReadHookJS() {
|
||||
#ifndef NKR_NO_QUICKJS
|
||||
if (NekoGui::dataStore->enable_js_hook > 0) {
|
||||
return ReadFile(QString("./hook.%1.js").arg(software_name.toLower()));
|
||||
}
|
||||
#endif
|
||||
return {};
|
||||
}
|
||||
} // namespace qjs
|
||||
23
main/QJS.hpp
23
main/QJS.hpp
@ -1,23 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
class QByteArray;
|
||||
class QString;
|
||||
|
||||
namespace qjs {
|
||||
class QJS {
|
||||
public:
|
||||
QJS();
|
||||
explicit QJS(const QByteArray &jsSource);
|
||||
~QJS();
|
||||
|
||||
QString Eval(const QByteArray &jsSource) const;
|
||||
QString Eval(const QString &jsSource) const;
|
||||
QString EvalFile(const QString &jsPath) const;
|
||||
QString EvalFunction(const QString &funcName, const QString &arg) const;
|
||||
|
||||
private:
|
||||
void *neko_ctx;
|
||||
};
|
||||
|
||||
QByteArray ReadHookJS();
|
||||
} // namespace qjs
|
||||
@ -13,7 +13,6 @@
|
||||
#include "main/NekoGui.hpp"
|
||||
|
||||
#include "ui/mainwindow_interface.h"
|
||||
#include "ui/dialog_first_setup.h"
|
||||
|
||||
#ifdef Q_OS_WIN
|
||||
#include "sys/windows/MiniDump.h"
|
||||
@ -141,7 +140,7 @@ int main(int argc, char* argv[]) {
|
||||
return 0;
|
||||
}
|
||||
// Some Bad System
|
||||
QMessageBox::warning(nullptr, "NekoRay", "RunGuard disallow to run, use -many to force start.");
|
||||
QMessageBox::warning(nullptr, "NekoGui", "RunGuard disallow to run, use -many to force start.");
|
||||
return 0;
|
||||
}
|
||||
MF_release_runguard = [&] { guard.release(); };
|
||||
@ -149,7 +148,7 @@ int main(int argc, char* argv[]) {
|
||||
// icons
|
||||
#if (QT_VERSION >= QT_VERSION_CHECK(5, 11, 0))
|
||||
QIcon::setFallbackSearchPaths(QStringList{
|
||||
":/nekoray",
|
||||
":/neko",
|
||||
":/icon",
|
||||
});
|
||||
#endif
|
||||
@ -159,28 +158,6 @@ int main(int argc, char* argv[]) {
|
||||
QIcon::setThemeName("breeze");
|
||||
}
|
||||
|
||||
// Load coreType
|
||||
auto coreLoaded = ReadFileText("groups/coreType");
|
||||
if (coreLoaded.isEmpty()) {
|
||||
NekoGui::coreType = -1;
|
||||
loadTranslate(QLocale().name());
|
||||
auto dialogFirstSetup = new DialogFirstSetup;
|
||||
dialogFirstSetup->exec();
|
||||
dialogFirstSetup->deleteLater();
|
||||
if (NekoGui::coreType < 0) {
|
||||
return 0;
|
||||
} else {
|
||||
QDir().mkdir("groups");
|
||||
QFile file;
|
||||
file.setFileName("groups/coreType");
|
||||
file.open(QIODevice::ReadWrite | QIODevice::Truncate);
|
||||
file.write(Int2String(NekoGui::coreType).toUtf8());
|
||||
file.close();
|
||||
}
|
||||
} else {
|
||||
NekoGui::coreType = coreLoaded.toInt();
|
||||
}
|
||||
|
||||
// Dir
|
||||
QDir dir;
|
||||
bool dir_success = true;
|
||||
@ -200,9 +177,6 @@ int main(int argc, char* argv[]) {
|
||||
|
||||
// Load dataStore
|
||||
switch (NekoGui::coreType) {
|
||||
case NekoGui::CoreType::V2RAY:
|
||||
NekoGui::dataStore->fn = "groups/nekoray.json";
|
||||
break;
|
||||
case NekoGui::CoreType::SING_BOX:
|
||||
NekoGui::dataStore->fn = "groups/nekobox.json";
|
||||
break;
|
||||
|
||||
@ -1 +1 @@
|
||||
3.23-2023-10-14
|
||||
4.0.1-2024-12-12
|
||||
|
||||
@ -1,38 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>CFBundleDevelopmentRegion</key>
|
||||
<string>English</string>
|
||||
<key>CFBundleExecutable</key>
|
||||
<string>${MACOSX_BUNDLE_EXECUTABLE_NAME}</string>
|
||||
<key>CFBundleGetInfoString</key>
|
||||
<string>${MACOSX_BUNDLE_INFO_STRING}</string>
|
||||
<key>CFBundleIconFile</key>
|
||||
<string>${MACOSX_BUNDLE_ICON_FILE}</string>
|
||||
<key>CFBundleIdentifier</key>
|
||||
<string>${MACOSX_BUNDLE_GUI_IDENTIFIER}</string>
|
||||
<key>CFBundleInfoDictionaryVersion</key>
|
||||
<string>6.0</string>
|
||||
<key>CFBundleLongVersionString</key>
|
||||
<string>${MACOSX_BUNDLE_LONG_VERSION_STRING}</string>
|
||||
<key>CFBundleName</key>
|
||||
<string>${MACOSX_BUNDLE_BUNDLE_NAME}</string>
|
||||
<key>CFBundlePackageType</key>
|
||||
<string>APPL</string>
|
||||
<key>CFBundleShortVersionString</key>
|
||||
<string>${MACOSX_BUNDLE_SHORT_VERSION_STRING}</string>
|
||||
<key>CFBundleSignature</key>
|
||||
<string>????</string>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>${MACOSX_BUNDLE_BUNDLE_VERSION}</string>
|
||||
<key>CSResourcesFileMapped</key>
|
||||
<true/>
|
||||
<key>NSHumanReadableCopyright</key>
|
||||
<string>${MACOSX_BUNDLE_COPYRIGHT}</string>
|
||||
<key>NSPrincipalClass</key>
|
||||
<string>NSApplication</string>
|
||||
<key>NSHighResolutionCapable</key>
|
||||
<string>True</string>
|
||||
</dict>
|
||||
</plist>
|
||||
@ -4,7 +4,7 @@
|
||||
|
||||
<body>
|
||||
<h3>
|
||||
<p>Please put your clash dashboard files to "nekoray/config/dashboard" dir.</p>
|
||||
<p>Please put your clash dashboard files to "./config/dashboard" dir.</p>
|
||||
<p>For example, you can download from the following URL.</p>
|
||||
<p>
|
||||
<a href="https://github.com/MetaCubeX/Yacd-meta/archive/refs/heads/gh-pages.zip">Download Yacd-meta</a>
|
||||
|
||||
@ -16,7 +16,6 @@
|
||||
</qresource>
|
||||
<qresource prefix="/neko">
|
||||
<file alias="nekobox.png">public/nekobox.png</file>
|
||||
<file alias="nekoray.png">public/nekoray.png</file>
|
||||
<file>neko.css</file>
|
||||
<file>vpn/vpn-run-root.sh</file>
|
||||
<file>vpn/sing-box-vpn.json</file>
|
||||
|
||||
|
Before Width: | Height: | Size: 66 KiB After Width: | Height: | Size: 66 KiB |
BIN
res/nekoray.icns
BIN
res/nekoray.icns
Binary file not shown.
Binary file not shown.
|
Before Width: | Height: | Size: 60 KiB |
@ -12,7 +12,7 @@
|
||||
{
|
||||
"tag": "dns-remote",
|
||||
"address": "8.8.8.8",
|
||||
"detour": "nekoray-socks"
|
||||
"detour": "neko-socks"
|
||||
},
|
||||
{
|
||||
"tag": "dns-direct",
|
||||
@ -75,7 +75,7 @@
|
||||
"outbounds": [
|
||||
{
|
||||
"type": "socks",
|
||||
"tag": "nekoray-socks",
|
||||
"tag": "neko-socks",
|
||||
"udp_fragment": true,
|
||||
//%SOCKS_USER_PASS%
|
||||
"server": "127.0.0.1",
|
||||
|
||||
@ -6,40 +6,25 @@ if [ "$EUID" -ne 0 ]; then
|
||||
echo "[Warning] Tun script not running as root"
|
||||
fi
|
||||
|
||||
if [ "$(uname)" == "Darwin" ]; then
|
||||
IS_MACOS=1
|
||||
fi
|
||||
|
||||
[ -z $TABLE_FWMARK ] && echo "Please set env TABLE_FWMARK" && exit
|
||||
command -v pkill >/dev/null 2>&1 || echo "[Warning] pkill not found"
|
||||
|
||||
BASEDIR=$(dirname "$0")
|
||||
cd $BASEDIR
|
||||
|
||||
pre_start_linux() {
|
||||
# set bypass: fwmark
|
||||
ip rule add pref 8999 fwmark $TABLE_FWMARK table main || return
|
||||
ip -6 rule add pref 8999 fwmark $TABLE_FWMARK table main || return
|
||||
|
||||
# for Tun2Socket
|
||||
iptables -I INPUT -s 172.19.0.2 -d 172.19.0.1 -p tcp -j ACCEPT
|
||||
ip6tables -I INPUT -s fdfe:dcba:9876::2 -d fdfe:dcba:9876::1 -p tcp -j ACCEPT
|
||||
}
|
||||
|
||||
start() {
|
||||
[ -z $IS_MACOS ] && pre_start_linux
|
||||
"./nekobox_core" run -c "$CONFIG_PATH" --protect-listen-path "$PROTECT_LISTEN_PATH" --protect-fwmark $TABLE_FWMARK
|
||||
pre_start_linux
|
||||
"./nekobox_core" run -c "$CONFIG_PATH"
|
||||
}
|
||||
|
||||
stop() {
|
||||
[ -z $IS_MACOS ] || return
|
||||
for local in $BYPASS_IPS; do
|
||||
ip rule del to $local table main
|
||||
done
|
||||
iptables -D INPUT -s 172.19.0.2 -d 172.19.0.1 -p tcp -j ACCEPT
|
||||
ip6tables -D INPUT -s fdfe:dcba:9876::2 -d fdfe:dcba:9876::1 -p tcp -j ACCEPT
|
||||
ip rule del fwmark $TABLE_FWMARK
|
||||
ip -6 rule del fwmark $TABLE_FWMARK
|
||||
}
|
||||
|
||||
if [ "$1" != "stop" ]; then
|
||||
|
||||
@ -205,7 +205,7 @@ namespace NekoGui_rpc {
|
||||
|
||||
#define NOT_OK \
|
||||
*rpcOK = false; \
|
||||
onError(QString("QNetworkReply::NetworkError code: %1\n").arg(status));
|
||||
onError(QStringLiteral("QNetworkReply::NetworkError code: %1\n").arg(status));
|
||||
|
||||
void Client::Exit() {
|
||||
libcore::EmptyReq request;
|
||||
|
||||
@ -1,7 +1,6 @@
|
||||
#include "db/ProfileFilter.hpp"
|
||||
#include "fmt/includes.h"
|
||||
#include "fmt/Preset.hpp"
|
||||
#include "main/QJS.hpp"
|
||||
#include "main/HTTPRequestHelper.hpp"
|
||||
|
||||
#include "GroupUpdater.hpp"
|
||||
@ -123,14 +122,6 @@ namespace NekoGui_sub {
|
||||
if (!ok) return;
|
||||
}
|
||||
|
||||
// Hysteria1
|
||||
if (str.startsWith("hysteria://")) {
|
||||
needFix = false;
|
||||
ent = NekoGui::ProfileManager::NewProxyEntity("hysteria");
|
||||
auto ok = ent->QUICBean()->TryParseLink(str);
|
||||
if (!ok) return;
|
||||
}
|
||||
|
||||
// Hysteria2
|
||||
if (str.startsWith("hysteria2://") || str.startsWith("hy2://")) {
|
||||
needFix = false;
|
||||
@ -201,7 +192,7 @@ namespace NekoGui_sub {
|
||||
try {
|
||||
return n.as<int>();
|
||||
} catch (const YAML::Exception &ex2) {
|
||||
ex2.what();
|
||||
qDebug() << ex2.what();
|
||||
}
|
||||
qDebug() << ex.what();
|
||||
return def;
|
||||
@ -414,41 +405,10 @@ namespace NekoGui_sub {
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else if (type == "hysteria") {
|
||||
auto bean = ent->QUICBean();
|
||||
|
||||
bean->hopPort = Node2QString(proxy["ports"]);
|
||||
|
||||
bean->allowInsecure = Node2Bool(proxy["skip-cert-verify"]);
|
||||
auto alpn = Node2QStringList(proxy["alpn"]);
|
||||
bean->caText = Node2QString(proxy["ca-str"]);
|
||||
if (!alpn.isEmpty()) bean->alpn = alpn[0];
|
||||
bean->sni = Node2QString(proxy["sni"]);
|
||||
|
||||
auto auth_str = FIRST_OR_SECOND(Node2QString(proxy["auth_str"]), Node2QString(proxy["auth-str"]));
|
||||
auto auth = Node2QString(proxy["auth"]);
|
||||
if (!auth_str.isEmpty()) {
|
||||
bean->authPayloadType = NekoGui_fmt::QUICBean::hysteria_auth_string;
|
||||
bean->authPayload = auth_str;
|
||||
}
|
||||
if (!auth.isEmpty()) {
|
||||
bean->authPayloadType = NekoGui_fmt::QUICBean::hysteria_auth_base64;
|
||||
bean->authPayload = auth;
|
||||
}
|
||||
bean->obfsPassword = Node2QString(proxy["obfs"]);
|
||||
|
||||
if (Node2Bool(proxy["disable_mtu_discovery"]) || Node2Bool(proxy["disable-mtu-discovery"])) bean->disableMtuDiscovery = true;
|
||||
bean->streamReceiveWindow = Node2Int(proxy["recv-window"]);
|
||||
bean->connectionReceiveWindow = Node2Int(proxy["recv-window-conn"]);
|
||||
|
||||
auto upMbps = Node2QString(proxy["up"]).split(" ")[0].toInt();
|
||||
auto downMbps = Node2QString(proxy["down"]).split(" ")[0].toInt();
|
||||
if (upMbps > 0) bean->uploadMbps = upMbps;
|
||||
if (downMbps > 0) bean->downloadMbps = downMbps;
|
||||
} else if (type == "hysteria2") {
|
||||
auto bean = ent->QUICBean();
|
||||
|
||||
// bean->hopPort = Node2QString(proxy["ports"]);
|
||||
bean->hopPort = Node2QString(proxy["ports"]);
|
||||
|
||||
bean->allowInsecure = Node2Bool(proxy["skip-cert-verify"]);
|
||||
bean->caText = Node2QString(proxy["ca-str"]);
|
||||
@ -593,17 +553,6 @@ namespace NekoGui_sub {
|
||||
}
|
||||
}
|
||||
|
||||
// hook.js
|
||||
auto source = qjs::ReadHookJS();
|
||||
if (!source.isEmpty()) {
|
||||
qjs::QJS js(source);
|
||||
auto js_result = js.EvalFunction("hook.hook_import", content);
|
||||
if (content != js_result) {
|
||||
MW_show_log("hook.js modified your import content.");
|
||||
content = js_result;
|
||||
}
|
||||
}
|
||||
|
||||
// 解析并添加 profile
|
||||
rawUpdater->update(content);
|
||||
|
||||
|
||||
@ -149,7 +149,7 @@ bool AutoRun_IsEnabled() {
|
||||
#include <QProcessEnvironment>
|
||||
#include <QTextStream>
|
||||
|
||||
#define NEWLINE "\r\n"
|
||||
#define NEWLINE "\n"
|
||||
|
||||
// launchatlogin.cpp
|
||||
// ShadowClash
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user