Compare commits

...

62 Commits
3.24 ... main

Author SHA1 Message Date
armv9
adef6cd4af 4.0.1 2024-12-12 17:03:36 +09:00
armv9
399b171adf misc change 2024-12-12 17:03:32 +09:00
armv9
6e4c180428 fix: dns outbound 2024-12-12 17:02:37 +09:00
armv9
75c6496151 change: domain rule use domain_suffix 2024-12-12 17:02:14 +09:00
Integral
62c59f6fd3
refactor: replace non-empty QString constructors with QStringLiteral() 2024-11-03 12:50:41 +08:00
armv9
12d6fc24e7 4.0-beta4 2024-10-09 13:32:41 +09:00
armv9
6de7c588b6 update core 2024-10-09 13:32:41 +09:00
armv9
99c8d50943 add url test button on main window 2024-10-09 13:32:41 +09:00
极速蜗牛
2a177256ce
Add /usr/share/sing-box to core asset search path (#1350) 2024-07-20 13:23:24 +08:00
Chi_Tang
b1d1674912
fixed pkgbuild for 4.0 (#1348) 2024-07-13 17:36:39 +08:00
armv9
2dd9cf45eb update readme 2024-07-13 15:57:07 +09:00
armv9
96a6586c5e 4.0-beta3 2024-07-13 15:39:11 +09:00
armv9
375ffec58d remove v2ray_asset_dir 2024-07-13 15:37:07 +09:00
armv9
7aa863b881 remove log high light 2024-07-13 15:26:01 +09:00
armv9
79838d8679 urltest: use dns 2024-07-07 15:25:15 +09:00
armv9
61e27f4014 fix appimage 2024-07-05 11:48:51 +09:00
armv9
e868de0209 4.0-beta2 2024-07-05 11:34:06 +09:00
armv9
6f81ba7773 change exe name 2024-07-05 11:34:06 +09:00
armv9
be0eae662b update qt 2024-07-05 11:16:26 +09:00
armv9
f6cf1414bf hysteria -> hysteria2 2024-07-05 10:29:22 +09:00
armv9
7c783308a7 fix: linux external tun 2024-07-03 16:55:16 +09:00
armv9
cd9bb8f72d v2ray format migration 2024-07-03 16:55:14 +09:00
armv9
df141f9079 fix: win32 gui 2024-07-02 13:26:54 +09:00
armv9
4376ce7d33 Merge branch 'master' of https://github.com/Si1entW4ve/nekoray 2024-07-02 12:31:53 +09:00
armv9
584d50e317 4.0-beta1 2024-07-02 12:11:18 +09:00
armv9
961112ea5b update core 1.9.3 2024-07-02 12:02:34 +09:00
armv9
8a2eab506f remove enable_js_hook 2024-06-28 11:56:47 +09:00
armv9
9bc3be6ea0 remove switch core 2024-06-28 11:54:59 +09:00
armv9
48e04d2173 remove DialogFirstSetup 2024-06-28 11:52:02 +09:00
armv9
3f738cee4e up 2024-06-27 12:04:49 +09:00
Si1ent W4ve
121311c938
fix & rename 2024-03-21 01:45:49 +08:00
purofle
4f45617666
Update README.md 2024-02-24 22:10:13 +08:00
AA
7655f0e16a
Farsi Docs updated (#1154)
* Create Build_Linux_fa.md

The Persian translation of the file Build_Linux.md has been added.

* Update README_fa.md

* change path of file

* Update README_fa.md

* Farsi Docs updated

* HookJS doc fixed
2024-01-09 23:48:52 +08:00
AA
9d8b12ff66
docs: Add Persian Build_Linux file (#1152)
* Create Build_Linux_fa.md

The Persian translation of the file Build_Linux.md has been added.

* Update README_fa.md

* change path of file

* Update README_fa.md
2024-01-08 23:48:58 +08:00
JustMarkov
364ea93cc1
docs: add Russian README (#1078)
* Update README.md

* Create README_ru.md
2024-01-03 22:27:40 +08:00
arm64v8a
894410da39 3.26 2023-12-09 14:59:48 +09:00
arm64v8a
06508634a7 fix: #1024 2023-12-09 14:59:45 +09:00
BlacAmDK
1b078a8aab
fix: RunGuard not works on Qt6 (#1095)
* Revert "fix: RunGuard not works on Qt6"

This reverts commit 32ef100cf3.

* fix: RunGuard not works on Qt6
2023-12-05 22:17:54 +08:00
purofle
beb87352ae
bump version
3.25
2023-11-25 18:48:10 +08:00
Fw[a]rd
5bf393597e
fix: unknown transport type: h2 in vmess protocol (#1062) 2023-11-25 18:44:21 +08:00
BlacAmDK
205caef7a5
Fix Linux autostart config line endings (#1049)
Fix Linux autostart config line endings.
2023-11-21 22:41:37 +08:00
arm64v8a
6087ec741d update core 2023-11-18 10:44:05 +09:00
purofle
7bd8a2f651
refactor: update box
Closes: #1039
2023-11-15 01:13:05 +08:00
purofle
d882424329
refactor: disable httpupgrade
httpupgrade is not implemented in sing-box 1.6.4
2023-11-15 01:12:42 +08:00
purofle
cd8da82c92
fix: Speed may be +InfMiB/s
Closes: #1032
2023-11-14 00:36:29 +08:00
purofle
06e5de0998
fix: go mod tidy 2023-11-14 00:22:47 +08:00
purofle
376ac1c515
update box
Closes: #1038
2023-11-13 23:11:40 +08:00
purofle
937523c6b3
fix: unknown transport type: h2
closes: #1012
2023-11-11 22:52:04 +08:00
purofle
c6caf42ce9
fix: go mod tidy 2023-11-10 01:11:36 +08:00
purofle
1aa59f1314
refactor: update box 2023-11-10 01:02:46 +08:00
エルフです
c9442ebb57
Skip AUR CI for non-project file changes & Unified README format (#1014)
* fix: Skip AUR CI for non-project file changes

* style: Unified README format

* Update README_ja.md

* Update README.md
2023-11-08 12:05:42 +08:00
purofle
a858af3ae4
docs: fix AUR CI Badge url 2023-11-05 11:33:46 +08:00
purofle
5ef732fbb1
Merge pull request #1013 from chitang233/main 2023-11-05 11:19:10 +08:00
Chi_Tang
514fb4c811
feat: update PKGBUILD on pushing 2023-11-05 10:38:08 +08:00
purofle
974bb9167d
refactor: only show httpupgrade on nekobox 2023-11-03 12:47:09 +08:00
Misaka-blog
369cc7c1aa fix: go mod tidy 2023-11-02 15:46:57 +08:00
Misaka-blog
7538075112 Feat: Add support for httpupgrade transport 2023-11-02 15:42:48 +08:00
purofle
32ef100cf3
fix: RunGuard not works on Qt6
Closes: #955
2023-10-31 15:24:26 +08:00
purofle
a6e7dfe717
Merge pull request #991 from mohitd404/main
Closes #989
2023-10-31 09:44:31 +08:00
Mohit Dhote
dad696ef18
Updated CODE_OF_CONDUCT.md file
Fixed #989
2023-10-30 14:49:31 +05:30
Ikko Eltociear Ashimine
7621c0a1df
docs: add Japanese README (#988) 2023-10-30 09:44:49 +08:00
Misaka-blog
4df116508e update box 2023-10-28 23:59:04 +08:00
120 changed files with 845 additions and 4783 deletions

View File

@ -4,13 +4,13 @@ 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:
@ -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
@ -196,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
@ -205,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
View 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
View File

@ -82,3 +82,6 @@ CMakeLists.txt.user*
/deployment
/neko*.sh
/qtsdk
.vs
out

3
.gitmodules vendored
View File

@ -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

View File

@ -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 +0,0 @@
Subproject commit 3fb0770c9ee5ab031a56072520641d4577b694e3

View File

@ -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

View File

@ -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

View File

@ -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;

View File

@ -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());
}
}

View File

@ -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 ()

View File

@ -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)

View File

@ -1,94 +0,0 @@
# NekoRay
مدیریت پیکربندی پروکسی با رابط کاربری مبتنی بر QT , کراس پلتفرم . (بک اند : v2ray / sing-box )
اکنون از Windows / Linux / macOS amd64 پشتیبانی می کند.
## دانلود / Download
### GitHub Releases (Portable ZIP)
فرمت قابل حمل، بدون نصب. برای دانلود باینری های از پیش کامپایل شده به Releases بروید، آنها را باز کرده و از آنها استفاده کنید.
[![GitHub All Releases](https://img.shields.io/github/downloads/Matsuridayo/nekoray/total?label=downloads-total&logo=github&style=flat-square)](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)

View File

@ -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"
}
]
}

View File

@ -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)

View File

@ -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);
}
}
// 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},
};
}
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},
};
}
}
} else {
// index == 0 means last profile in chain / not chain
@ -530,7 +266,6 @@ 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"},
@ -539,34 +274,12 @@ namespace NekoGui {
{"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"},
}},
};
}
// 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"},
};
}
}
}
@ -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;
}
} 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,15 +329,9 @@ 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->multiplex_status == 0) {
if (!dataStore->mux_default_on) needMux = false;
} else if (stream->multiplex_status == 1) {
@ -650,7 +345,6 @@ namespace NekoGui {
}
// common
if (IS_NEKO_BOX) {
// apply domain_strategy
outbound["domain_strategy"] = dataStore->routing->outbound_domain_strategy;
// apply mux
@ -664,22 +358,9 @@ namespace NekoGui {
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 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,14 +541,11 @@ 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://", "://")},
{"address", dataStore->routing->direct_dns},
{"detour", "direct"},
};
if (dataStore->routing->dns_final_out == "bypass") {
@ -875,7 +553,10 @@ namespace NekoGui {
} 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());

View File

@ -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

View File

@ -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) {

View File

@ -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

View File

@ -1,11 +1,10 @@
## 构建 nekoray_core & nekobox_core
## 构建 nekobox_core
### 目录结构
```
| nekoray
| go/cmd/*
| Xray-core
| sing-box-extra
| sing-box
| ......

View File

@ -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 部分编译

View File

@ -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
```

View File

@ -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`

View File

@ -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 部分编译

View File

@ -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;
```

View File

@ -4,4 +4,3 @@
1. Build GUI: `Build_*.md`
2. Build Core: `Build_Core.md`
3. Hook.js usage: `HookJS.md`

View File

@ -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) {

View File

@ -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 {}; };

View File

@ -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,22 +191,7 @@ 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;
outbound["hop_interval"] = hopInterval;
}
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;

View File

@ -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

View File

@ -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) {
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)) {
if (!forceExternal) {
// 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();
} 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) {

View File

@ -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);

View File

@ -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 {};
}
} 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

View File

@ -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

View File

@ -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"};

View File

@ -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));
}
} 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";
}

View File

@ -23,8 +23,6 @@ namespace NekoGui_fmt {
QString DisplayType() override { return "Shadowsocks"; };
CoreObjOutboundBuildResult BuildCoreObjV2Ray() override;
CoreObjOutboundBuildResult BuildCoreObjSingBox() override;
bool TryParseLink(const QString &link);

View File

@ -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);

View File

@ -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);

View File

@ -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);
};

View File

@ -21,8 +21,6 @@ namespace NekoGui_fmt {
QString DisplayType() override { return "VMess"; };
CoreObjOutboundBuildResult BuildCoreObjV2Ray() override;
CoreObjOutboundBuildResult BuildCoreObjSingBox() override;
bool TryParseLink(const QString &link);

View File

@ -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)

View File

@ -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,91 +13,89 @@ 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.5 // 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.7.0 // indirect
github.com/go-chi/chi/v5 v5.0.10 // 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-20231016090811-6a2c8fbdcc1c // 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/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-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/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.16-0.20231021090846-8002db54c028 // indirect
github.com/sagernet/sing-dns v0.1.10 // indirect
github.com/sagernet/sing-mux v0.1.3 // indirect
github.com/sagernet/sing-quic v1.0.0 // 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.17-0.20231026060825-efd9884154a6 // 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-20231006140011-7918f672742d // indirect
golang.org/x/mod v0.13.0 // indirect
golang.org/x/net v0.17.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.14.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-20230822172742-b8732ec3820d // indirect
google.golang.org/grpc v1.59.0 // 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

View File

@ -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.23.0 h1:tP41Zoavr8ptEqaW6j+LQOnyBBhO7OkOMAGrgLopTwY=
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.5 h1:g+wWynZqVALYAlpSQFAa7TscDnUK8mKYtrxMpw6AUKo=
github.com/cloudflare/circl v1.3.5/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.7.0 h1:8JEhPFa5W2WU7YfeZzPNqzMP6Lwt7L2715Ggo0nosvA=
github.com/fsnotify/fsnotify v1.7.0/go.mod h1:40Bi/Hjc2AVfZrqy+aj+yEI+/bRxZnMJyTJwOpGvigM=
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/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-20231016090811-6a2c8fbdcc1c h1:PgxFEySCI41sH0mB7/2XswdXbUykQsRUGod8Rn+NubM=
github.com/insomniacslk/dhcp v0.0.0-20231016090811-6a2c8fbdcc1c/go.mod h1:3A9PQ1cunSDF/1rbTq99Ts4pVnycWg+vlPkfeD2NLFI=
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,56 +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-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-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/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.16-0.20231021090846-8002db54c028 h1:6GbQt7SC9y5Imrq5jDMbXDSaNiMhJ8KBjhjtQRuqQvE=
github.com/sagernet/sing v0.2.16-0.20231021090846-8002db54c028/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-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.17-0.20231026060825-efd9884154a6 h1:4yEXBqQoUgXj7qPSLD6lr+z9/KfsvixO9JUA2i5xnM8=
github.com/sagernet/sing-tun v0.1.17-0.20231026060825-efd9884154a6/go.mod h1:w2+S+uWE94E/pQWSDdDdMIjwAEb645kuGPunr6ZllUg=
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=
@ -176,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=
@ -190,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-20231006140011-7918f672742d h1:jtJma62tbqLibJ5sFQz8bKtEM8rJBtfilJ2qTU199MI=
golang.org/x/exp v0.0.0-20231006140011-7918f672742d/go.mod h1:ldy0pHrwJyGW56pPQzzkH36rKxoZW1tw7ZJpeKx+hdo=
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.13.0 h1:I/DsJXRlw/8l/0c24sM9yb0T4z9liZTduXvdAWYiysY=
golang.org/x/mod v0.13.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c=
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=
@ -226,41 +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.17.0 h1:pVaXccu2ozPjCXewfr1S7xza/zcXTity9cCdXQYSjIM=
golang.org/x/net v0.17.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.11.0 h1:vPL4xzxBM4niKCW6g9whtaWVXTJf1U5e4aZxxFx/gbU=
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.4.0 h1:zxkM55ReGkDlKSM+Fu41A+zmbZuaPVbGMzvvdUPznYQ=
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.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=
@ -269,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.14.0 h1:jvNa2pY0M4r62jkRQ6RwEZZyPcymeL9XZMLBbV7U2nc=
golang.org/x/tools v0.14.0/go.mod h1:uYBEerGOWcJyEORxN+Ek8+TT266gXkNlHdJBwexUsBg=
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=
@ -279,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-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/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.59.0 h1:Z5Iec2pjwb+LEOqzpB2MR12/eKFhDPhuqW91O+4bwUk=
google.golang.org/grpc v1.59.0/go.mod h1:aUPDwccQo6OTjy7Hct4AfBPD1GptF4fyUjIkQ9YtF98=
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=
@ -303,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=

View File

@ -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 {

View File

@ -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

View File

@ -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
}

View File

@ -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

View File

@ -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=

View File

@ -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
}

View File

@ -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"
)

View File

@ -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()
}

View File

@ -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
}
}

View File

@ -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
}

View File

@ -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
},
}
}

View File

@ -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()
}
}
}

View File

@ -1,6 +0,0 @@
//go:build !windows && !linux
package main
func ToolBox() {
}

View File

@ -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"))
}
}
}

View File

@ -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")

View File

@ -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

View File

@ -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 {

View File

@ -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"
}

View File

@ -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 {

View File

@ -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" {

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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
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

View File

@ -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

View File

@ -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) # 下次改

View File

@ -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

View File

@ -1,9 +1,3 @@
if [ ! -z $ENV_NEKORAY ]; then
export COMMIT_SING_BOX_EXTRA="247a7a4522168aa8b151efc4085809cae819345d"
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"

View File

@ -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

View File

@ -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;

View File

@ -18,7 +18,7 @@ namespace NekoGui {
namespace CoreType {
enum CoreType {
V2RAY,
V2RAY, // DO NOT USE
SING_BOX,
};
}

View File

@ -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;

View File

@ -237,7 +237,6 @@ namespace NekoGui {
_add(new configItem("current_group", &current_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 user_agent;
}
@ -336,10 +324,8 @@ namespace NekoGui {
"domain:firebase.io\n"
"domain:crashlytics.com\n";
}
if (IS_NEKO_BOX) {
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));
@ -363,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)
@ -429,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);

View File

@ -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 + "/")

View File

@ -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;

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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;

View File

@ -1 +1 @@
3.24-2023-10-28
4.0.1-2024-12-12

View File

@ -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>

View File

@ -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>

View File

@ -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>

View File

Before

Width:  |  Height:  |  Size: 66 KiB

After

Width:  |  Height:  |  Size: 66 KiB

Binary file not shown.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 60 KiB

View File

@ -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",

View File

@ -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

View File

@ -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;

View File

@ -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,37 +405,6 @@ 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();
@ -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);

View File

@ -149,7 +149,7 @@ bool AutoRun_IsEnabled() {
#include <QProcessEnvironment>
#include <QTextStream>
#define NEWLINE "\r\n"
#define NEWLINE "\n"
// launchatlogin.cpp
// ShadowClash

View File

@ -141,15 +141,7 @@ namespace NekoGui_sys {
void CoreProcess::Start() {
show_stderr = false;
// set extra env
auto v2ray_asset_dir = NekoGui::FindCoreAsset("geoip.dat");
if (!v2ray_asset_dir.isEmpty()) {
v2ray_asset_dir = QFileInfo(v2ray_asset_dir).absolutePath();
env << "XRAY_LOCATION_ASSET=" + v2ray_asset_dir;
}
if (NekoGui::dataStore->core_ray_direct_dns) env << "NKR_CORE_RAY_DIRECT_DNS=1";
if (NekoGui::dataStore->core_ray_windows_disable_auto_interface) env << "NKR_CORE_RAY_WINDOWS_DISABLE_AUTO_INTERFACE=1";
//
// cwd: same as GUI, at ./config
ExternalProcess::Start();
write((NekoGui::dataStore->core_token + "\n").toUtf8());
}

View File

@ -56,7 +56,7 @@ LONG __stdcall CreateCrashHandler(EXCEPTION_POINTERS *pException) {
}
// 创建消息提示
QMessageBox::warning(NULL, "Application crashed",
QString("ErrorCode: %1 ErrorAddr:%2 ErrorFlag: %3 ErrorPara: %4\nVersion: %5\nDump file at %6")
QStringLiteral("ErrorCode: %1 ErrorAddr:%2 ErrorFlag: %3 ErrorPara: %4\nVersion: %5\nDump file at %6")
.arg(errCode)
.arg(errAddr)
.arg(errFlag)

View File

@ -11,18 +11,10 @@
<source>Enable</source>
<translation>فعال کردن</translation>
</message>
<message>
<source>HTTP Listen Port</source>
<translation>پورت HTTP درحال شنود</translation>
</message>
<message>
<source>Listen Address</source>
<translation>آدرس درحال شنود</translation>
</message>
<message>
<source>Socks Listen Port</source>
<translation>پورت ساکس درحال شنود</translation>
</message>
<message>
<source>concurrency</source>
<translation>همزمانی</translation>
@ -71,14 +63,6 @@
<source>Custom Inbound</source>
<translation>ورودی سفارشی</translation>
</message>
<message>
<source>Asset Location</source>
<translation>مکان دارایی</translation>
</message>
<message>
<source>Default: dir of &quot;nekoray&quot;</source>
<translation type="unfinished">مسیر پیش فرض &quot;nekoray&quot;</translation>
</message>
<message>
<source>Concurrent</source>
<translation>هم زمان</translation>
@ -145,26 +129,10 @@
<source>Ignore TLS errors when updating subscription</source>
<translation>هنگام بهروزرسانی اشتراک، خطاهای TLS را نادیده گرفته شود</translation>
</message>
<message>
<source>Switch core</source>
<translation>سوئیچ هسته</translation>
</message>
<message>
<source>Enable hook.js</source>
<translation type="unfinished">فعال سازی hook.js</translation>
</message>
<message>
<source>Advanced system proxy settings. Please select a format.</source>
<translation>تنظیمات پیشرفته پروکسی سیستم. لطفا یک قالب را انتخاب کنید.</translation>
</message>
<message>
<source>Confirmation</source>
<translation>تائیدیه</translation>
</message>
<message>
<source>Switching the core to %1, click &quot;Yes&quot; to complete the switch and the program will restart. This feature may be unstable, please do not switch frequently.</source>
<translation>هسته به 1% تغییر میابد، روی &quot;Yes&quot; کلیک کنید تا تغییر پایان یابد و برنامه ریستارت شود. این قابلیت ممکن است پایدار نباشد، لطفا مکررا تعویض نکنید</translation>
</message>
<message>
<source>Please select a PNG file.</source>
<translation>لطفاً یک فایل PNG انتخاب کنید.</translation>
@ -213,16 +181,6 @@
<source>Override underlying DNS</source>
<translation type="unfinished">لغو دی ان اس زیربنایی</translation>
</message>
<message>
<source>It is recommended to leave it blank, but it sometimes does not work, at this time you can set this option.
For NekoRay, this rewrites the underlying(localhost) DNS in Tun Mode.
For NekoBox, this rewrites the underlying(localhost) DNS in Tun Mode, normal mode, and also URL Test.</source>
<translation type="unfinished">پیشنهاد میشود که این گزینه را انتخاب نشده باقی بگذارید ، اما گاهی اوقات کار نمیکند در این مواقع شما میتوانید این گزینه را انتخاب کنید ، برای Nekoray این گزینه دی ان اس زیربنایی را در حالت تونل بازنویسی میکند ، و برای NekoBox این گزینه دی ان اس زیربنایی را هم در حالت تونل و هم در حالت معمولی و تست آدرس بازنویسی میکند</translation>
</message>
<message>
<source>If you Tun Mode is not working, try to change this option.</source>
<translation type="unfinished">اگر حالت تونل برای شما کار نمیکند ، این گزینه را تغییر دهید</translation>
</message>
<message>
<source>Default On</source>
<translation type="unfinished">به صورت پیشفرض فعال</translation>
@ -259,6 +217,10 @@ For NekoBox, this rewrites the underlying(localhost) DNS in Tun Mode, normal mod
<source>Old Share Link Format</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Mixed (SOCKS+HTTP) Listen Port</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>DialogEditGroup</name>
@ -490,23 +452,6 @@ For NekoBox, this rewrites the underlying(localhost) DNS in Tun Mode, normal mod
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>DialogFirstSetup</name>
<message>
<source>First time setup</source>
<translation type="unfinished">تنظیم دفعه اول</translation>
</message>
<message>
<source>It looks like you are using this software for the first time, please select a core.
These settings can be changed later.</source>
<translation type="unfinished">به نظر میرسد که شما برای اولین بار است که از این نرم افزار استفاده میکنید ، لطفا یک هسته را انتخاب کنید ، این تنظیمات میتواند بعدا تغییر یابد.</translation>
</message>
<message>
<source>Quit</source>
<translation type="unfinished">خروج</translation>
</message>
</context>
<context>
<name>DialogHotkey</name>
<message>
@ -904,14 +849,6 @@ This needs to be run NekoBox with administrator privileges.</source>
<source>Certificate</source>
<translation type="unfinished">گواهی</translation>
</message>
<message>
<source>Auth Type</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Protocol</source>
<translation type="unfinished">پروتکل</translation>
</message>
<message>
<source>Download (Mbps)</source>
<translation type="unfinished">دانلود (مگابیت بر ثانیه)</translation>
@ -944,10 +881,6 @@ This needs to be run NekoBox with administrator privileges.</source>
<source>SNI</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Auth Payload</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Disable SNI</source>
<translation type="unfinished"></translation>
@ -1401,14 +1334,6 @@ This needs to be run NekoBox with administrator privileges.</source>
<source>Imported %1 profile(s)</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Http inbound is not enabled, can&apos;t set system proxy.</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Settings</source>
<translation>تنظیمات</translation>
</message>
<message>
<source>Current server is incompatible with Tun. Please stop the server first, enable Tun Mode, and then restart.</source>
<translation type="unfinished"></translation>
@ -1417,11 +1342,6 @@ This needs to be run NekoBox with administrator privileges.</source>
<source>Not Running</source>
<translation>در حال اجرا نیست</translation>
</message>
<message>
<source>None</source>
<translatorcomment>هیچ یک</translatorcomment>
<translation>هیچ یک</translation>
</message>
<message>
<source>Select</source>
<translation>انتخاب</translation>
@ -1572,6 +1492,10 @@ End: %2</source>
<source>Stop Testing</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>URL Test</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>ProxyItem</name>
@ -1712,6 +1636,10 @@ Direct: %2</source>
<source>Default</source>
<translation type="unfinished">پیش فرض</translation>
</message>
<message>
<source>The last speed test did not exit completely, please wait. If it persists, please restart the program.</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>Qv2ray::ui::widgets::AutoCompleteTextEdit</name>

View File

@ -23,14 +23,6 @@
<source>Edit</source>
<translation>Изменить</translation>
</message>
<message>
<source>Socks Listen Port</source>
<translation>Адрес входящих SOCKS</translation>
</message>
<message>
<source>HTTP Listen Port</source>
<translation>Адрес входящих HTTP</translation>
</message>
<message>
<source>Enable</source>
<translation>Вкл</translation>
@ -115,14 +107,6 @@
<source>Core</source>
<translation>Ядро</translation>
</message>
<message>
<source>Asset Location</source>
<translation>Расположение файлов</translation>
</message>
<message>
<source>Default: dir of &quot;nekoray&quot;</source>
<translation>По умолчанию: текущая папка nekoray</translation>
</message>
<message>
<source>Select</source>
<translation>Выбрать</translation>
@ -143,10 +127,6 @@
<source>Core Options</source>
<translation>Параметры ядра</translation>
</message>
<message>
<source>Switch core</source>
<translation>Выбор ядра</translation>
</message>
<message>
<source>Extra Core</source>
<translation>Дополнительные ядра</translation>
@ -167,10 +147,6 @@
<source>Skip TLS certificate authentication by default (allowInsecure)</source>
<translation>Не проверять подлинность TLS сертификатов по умолчанию</translation>
</message>
<message>
<source>Enable hook.js</source>
<translation>Использовать hook.js</translation>
</message>
<message>
<source>Default uTLS Fingerprint</source>
<translation>uTLS fingerprint по умолчанию</translation>
@ -187,14 +163,6 @@
<source>Please select the core name.</source>
<translation>Выберите имя ядра.</translation>
</message>
<message>
<source>Confirmation</source>
<translation>Подтверждение</translation>
</message>
<message>
<source>Switching the core to %1, click &quot;Yes&quot; to complete the switch and the program will restart. This feature may be unstable, please do not switch frequently.</source>
<translation>Переключаем ядро на %1, нажмите &quot;Да&quot; для изменения и перезапуска программы. Эта функция может быть нестабильной, поэтому, пожалуйста, не переключайте ядро часто.</translation>
</message>
<message>
<source>Please select a PNG file.</source>
<translation>Выберите PNG файл</translation>
@ -227,18 +195,6 @@
<source>Override underlying DNS</source>
<translation>Переопределить нижестоящий DNS</translation>
</message>
<message>
<source>It is recommended to leave it blank, but it sometimes does not work, at this time you can set this option.
For NekoRay, this rewrites the underlying(localhost) DNS in Tun Mode.
For NekoBox, this rewrites the underlying(localhost) DNS in Tun Mode, normal mode, and also URL Test.</source>
<translation>Рекомендуется оставить параметр пустым, но иногда это не срабатывает как надо, и в таком случае можно использовать эту опцию.
Для NekoRay это переопределяет нижестоящий (localhost) DNS в Tun режиме.
Для NekoBox это переопределяет нижестоящий (localhost) DNS в Tun режиме, нормальном режиме, а также при URL тесте.</translation>
</message>
<message>
<source>If you Tun Mode is not working, try to change this option.</source>
<translation>Если TUN-режим не работает, попробуйте изменить эту опцию.</translation>
</message>
<message>
<source>Timeout (s)</source>
<translation>Таймаут (с)</translation>
@ -259,6 +215,10 @@ For NekoBox, this rewrites the underlying(localhost) DNS in Tun Mode, normal mod
<source>Old Share Link Format</source>
<translation>Поделиться ссылкой в старом формате</translation>
</message>
<message>
<source>Mixed (SOCKS+HTTP) Listen Port</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>DialogEditGroup</name>
@ -490,25 +450,6 @@ For NekoBox, this rewrites the underlying(localhost) DNS in Tun Mode, normal mod
<translation>Подтвердить</translation>
</message>
</context>
<context>
<name>DialogFirstSetup</name>
<message>
<source>First time setup</source>
<translation>Первоначальная настройка</translation>
</message>
<message>
<source>It looks like you are using this software for the first time, please select a core.
These settings can be changed later.</source>
<translation>Привет! Кажется, вы запустили эту программу впервые. Пожалуйста, выберите ядро.
Эти настройки будет возможно в дальнейшем изменить.</translation>
</message>
<message>
<source>Quit</source>
<translation>Выход</translation>
</message>
</context>
<context>
<name>DialogHotkey</name>
<message>
@ -907,14 +848,6 @@ https://matsuridayo.github.io/n-configuration/#vpn-tun</translation>
</context>
<context>
<name>EditQUIC</name>
<message>
<source>Auth Type</source>
<translation>Тип авторизации</translation>
</message>
<message>
<source>Protocol</source>
<translation>Протокол</translation>
</message>
<message>
<source>Download (Mbps)</source>
<translation>Скорость приема (Mbps)</translation>
@ -951,10 +884,6 @@ https://matsuridayo.github.io/n-configuration/#vpn-tun</translation>
<source>SNI</source>
<translation>SNI</translation>
</message>
<message>
<source>Auth Payload</source>
<translation>Полезная нагрузка в режиме авторизации</translation>
</message>
<message>
<source>Disable SNI</source>
<translation>Отключить SNI</translation>
@ -1429,14 +1358,6 @@ https://matsuridayo.github.io/n-configuration/#vpn-tun</translation>
<source>Imported %1 profile(s)</source>
<translation>Импортирован(ы) %1 профиль(ей)</translation>
</message>
<message>
<source>Http inbound is not enabled, can&apos;t set system proxy.</source>
<translation>HTTP inbound не включен в настройках, невозможно установить системный прокси.</translation>
</message>
<message>
<source>Settings</source>
<translation>Настройки</translation>
</message>
<message>
<source>Please run NekoBox as admin</source>
<translation>Пожалуйста, запустите NekoBox с правами администратора</translation>
@ -1449,10 +1370,6 @@ https://matsuridayo.github.io/n-configuration/#vpn-tun</translation>
<source>Not Running</source>
<translation>Не запущен</translation>
</message>
<message>
<source>None</source>
<translation>Нет</translation>
</message>
<message>
<source>Select</source>
<translation>Выбор</translation>
@ -1581,6 +1498,10 @@ End: %2</source>
<source>Stop Testing</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>URL Test</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>ProxyItem</name>
@ -1728,6 +1649,10 @@ Release note:
<source>Default</source>
<translation>По умолчанию</translation>
</message>
<message>
<source>The last speed test did not exit completely, please wait. If it persists, please restart the program.</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>Qv2ray::ui::widgets::AutoCompleteTextEdit</name>

Some files were not shown because too many files have changed in this diff Show More