hysteria generator

This commit is contained in:
arm64v8a
2022-08-09 10:34:57 +08:00
parent 0b7abbe43e
commit a3a0b1a3c3
11 changed files with 369 additions and 73 deletions

View File

@@ -155,6 +155,9 @@ set(PROJECT_SOURCES
ui/edit/edit_trojan_vless.h
ui/edit/edit_trojan_vless.cpp
ui/edit/edit_trojan_vless.ui
ui/edit/gen_hysteria.h
ui/edit/gen_hysteria.cpp
ui/edit/gen_hysteria.ui
ui/edit/edit_naive.h
ui/edit/edit_naive.cpp

View File

@@ -29,19 +29,6 @@ https://matsuridayo.github.io
- `-many` 无视同目录正在运行的实例,强行开启新的实例 (0.11+)
- `-appdata` 开启后配置文件会放在共享目录,无法多开和自动升级 (0.11+)
### 代理
| 协议 | 状态 | 配置编辑 | 分享链接生成 | 分享链接解析 | Clash 配置解析 |
|--------------|--------|------|--------|-----------|------------|
| Socks | ✅ | ✅ | ✅ | ✅ | ✅ |
| HTTP | ✅ | ✅ | ✅ | ✅ | ✅ |
| Shadowsocks | ✅ (经典) | ✅ | ✅ | 常见格式 | ✅ |
| VMess | ✅ | ✅ | ✅ | v2rayN 格式 | ✅ |
| Trojan | ✅ | ✅ | ✅ | 标准&常见格式 | ✅ |
| VLESS | ✅ | ✅ | ✅ | ✅ | 不适用 |
| NaïveProxy | ✅ | ✅ | ✅ | ✅ | 不适用 |
| Hysteria | ✅ | ❌ | ❌ | ❌ | 不适用 |
## Linux 运行 & 简易编译教程
**使用 Linux 系统相信您已具备基本的排错能力,
@@ -85,7 +72,7 @@ git submodule update
2. Qt 版本必须大于等于 5.15
3. 系统为 `x86-64-linux-gnu`
```
```shell
mkdir build
cd build
cmake -GNinja ..
@@ -104,6 +91,16 @@ C++ 部分
依赖搜寻 prefix 为 `libs/deps/bulit`
示例
```shell
./libs/build_deps_all.sh
mkdir build
cd build
cmake -GNinja ..
ninja
```
编译完成后得到 `nekoray`
Go 部分

View File

@@ -492,6 +492,10 @@
<source>Command</source>
<translation></translation>
</message>
<message>
<source>Generator</source>
<translation></translation>
</message>
</context>
<context>
<name>EditNaive</name>
@@ -596,6 +600,37 @@
<translation></translation>
</message>
</context>
<context>
<name>GenHysteria</name>
<message>
<source>Generate</source>
<translation></translation>
</message>
<message>
<source>Allow Insecure</source>
<translation></translation>
</message>
<message>
<source>Certificate Path</source>
<translation></translation>
</message>
<message>
<source>Obfs Password</source>
<translation></translation>
</message>
<message>
<source>Auth String</source>
<translation></translation>
</message>
<message>
<source>Protocol</source>
<translation></translation>
</message>
<message>
<source>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;&lt;a href=&quot;https://github.com/HyNetwork/hysteria/wiki&quot;&gt;&lt;span style=&quot; text-decoration: underline; color:#2980b9;&quot;&gt;Document&lt;/span&gt;&lt;/a&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</source>
<translation>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;&lt;a href=&quot;https://github.com/HyNetwork/hysteria/wiki&quot;&gt;&lt;span style=&quot; text-decoration: underline; color:#2980b9;&quot;&gt;文档&lt;/span&gt;&lt;/a&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</translation>
</message>
</context>
<context>
<name>GroupItem</name>
<message>
@@ -999,8 +1034,8 @@ End: %2</source>
<translation> %1 </translation>
</message>
<message>
<source>New profile from clipboard</source>
<translation></translation>
<source>Add profile from clipboard [ Ctrl+V ]</source>
<translation> [ Ctrl+V ]</translation>
</message>
<message>
<source>Full Test</source>

View File

@@ -127,8 +127,7 @@ void DialogEditProfile::typeSelected(const QString &newType) {
auto _innerWidget = new EditCustom(this);
innerWidget = _innerWidget;
innerEditor = _innerWidget;
// I don't want to write a settings
if (type == "hysteria") {
if (type == "hysteria" || ent->CustomBean()->core == "hysteria") {
_innerWidget->preset_core = type;
_innerWidget->preset_command = "-c %config%";
_innerWidget->preset_config = "{\n"
@@ -141,8 +140,8 @@ void DialogEditProfile::typeSelected(const QString &newType) {
" \"listen\": \"127.0.0.1:%socks_port%\"\n"
" }\n"
"}";
type = "custom";
}
type = "custom";
} else {
validType = false;
}

View File

@@ -3,6 +3,7 @@
#include "qv2ray/v2/ui/widgets/editors/w_JsonEditor.hpp"
#include "fmt/CustomBean.hpp"
#include "ui/edit/gen_hysteria.h"
EditCustom::EditCustom(QWidget *parent) :
QWidget(parent), ui(new Ui::EditCustom) {
@@ -34,17 +35,27 @@ void EditCustom::onStart(QSharedPointer<NekoRay::ProxyEntity> _ent) {
ui->core->addItem(key);
}
if (!preset_core.isEmpty()) {
bean->core = preset_core;
ui->core->setCurrentText(preset_core);
if (!bean->core.isEmpty()) {
ui->core->setDisabled(true);
} else if (!preset_core.isEmpty()) {
bean->core = preset_core;
ui->core->setDisabled(true);
ui->core->setCurrentText(preset_core);
ui->command->setText(preset_command);
ui->config_simple->setText(preset_config);
}
if (!bean->core.isEmpty()) {
ui->core->setDisabled(true);
}
// Generators
if (bean->core == "hysteria") {
ui->generator->setVisible(true);
auto genHy = new GenHysteria(ent, preset_config);
ui->generator->layout()->addWidget(genHy);
connect(genHy, &GenHysteria::config_generated, this, [=](const QString &result) {
ui->config_simple->setText(result);
});
} else {
ui->generator->setVisible(false);
}
}
bool EditCustom::onEnd() {

View File

@@ -7,70 +7,93 @@
<x>0</x>
<y>0</y>
<width>400</width>
<height>394</height>
<height>400</height>
</rect>
</property>
<property name="windowTitle">
<string>EditCustom</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<layout class="QHBoxLayout" name="layout">
<item>
<layout class="QHBoxLayout" name="horizontalLayout">
<layout class="QVBoxLayout" name="verticalLayout_2">
<item>
<widget class="QLabel" name="label">
<property name="sizePolicy">
<sizepolicy hsizetype="Maximum" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>Core</string>
</property>
</widget>
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<widget class="QLabel" name="label">
<property name="sizePolicy">
<sizepolicy hsizetype="Maximum" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>Core</string>
</property>
</widget>
</item>
<item>
<widget class="QComboBox" name="core">
<property name="editable">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="as_json">
<property name="text">
<string>Json</string>
</property>
</widget>
</item>
</layout>
</item>
<item>
<widget class="QComboBox" name="core">
<property name="editable">
<bool>true</bool>
</property>
</widget>
<layout class="QHBoxLayout" name="horizontalLayout_2">
<item>
<widget class="QLabel" name="label_2">
<property name="text">
<string>Command</string>
</property>
</widget>
</item>
<item>
<widget class="QLineEdit" name="command">
<property name="placeholderText">
<string notr="true">%config%</string>
</property>
</widget>
</item>
</layout>
</item>
<item>
<widget class="QPushButton" name="as_json">
<property name="text">
<string>Json</string>
<widget class="QTextEdit" name="config_simple">
<property name="minimumSize">
<size>
<width>0</width>
<height>300</height>
</size>
</property>
</widget>
</item>
</layout>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_2">
<item>
<widget class="QLabel" name="label_2">
<property name="text">
<string>Command</string>
</property>
</widget>
</item>
<item>
<widget class="QLineEdit" name="command">
<property name="placeholderText">
<string notr="true">%config%</string>
</property>
</widget>
</item>
</layout>
</item>
<item>
<widget class="QTextEdit" name="config_simple">
<property name="minimumSize">
<size>
<width>0</width>
<height>300</height>
</size>
<widget class="QGroupBox" name="generator">
<property name="title">
<string>Generator</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<widget class="QWidget" name="fake" native="true">
<property name="sizePolicy">
<sizepolicy hsizetype="Maximum" vsizetype="Maximum">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
</widget>
</item>
</layout>
</widget>
</item>
</layout>
@@ -79,7 +102,6 @@
<tabstop>core</tabstop>
<tabstop>as_json</tabstop>
<tabstop>command</tabstop>
<tabstop>config_simple</tabstop>
</tabstops>
<resources/>
<connections/>

38
ui/edit/gen_hysteria.cpp Normal file
View File

@@ -0,0 +1,38 @@
#include "gen_hysteria.h"
#include "ui_gen_hysteria.h"
#include "fmt/CustomBean.hpp"
GenHysteria::GenHysteria(const QSharedPointer<NekoRay::ProxyEntity> &ent, const QString &preset_config,
QWidget *parent) :
QWidget(parent), ui(new Ui::GenHysteria) {
ui->setupUi(this);
this->ent = ent;
this->preset_config = preset_config;
}
GenHysteria::~GenHysteria() {
delete ui;
}
void GenHysteria::on_gen_clicked() {
auto result = QString2QJsonObject(preset_config);
result["obfs"] = ui->obfs_password->text();
result["insecure"] = ui->allow_insecure->isChecked();
result["protocol"] = ui->protocol->currentText();
result["up_mbps"] = ui->up_mbps->text().toInt();
result["down_mbps"] = ui->down_mbps->text().toInt();
if (!ui->auth_string->text().isEmpty()) {
result["auth_str"] = ui->auth_string->text();
}
if (!ui->alpn->text().isEmpty()) {
result["alpn"] = ui->alpn->text();
}
if (!ui->sni->text().isEmpty()) {
result["server_name"] = ui->sni->text();
}
if (!ui->cert_path->text().isEmpty()) {
result["ca"] = ui->cert_path->text();
}
emit config_generated(QJsonObject2QString(result, false));
}

31
ui/edit/gen_hysteria.h Normal file
View File

@@ -0,0 +1,31 @@
#pragma once
#include <QWidget>
#include "db/ProxyEntity.hpp"
QT_BEGIN_NAMESPACE
namespace Ui { class GenHysteria; }
QT_END_NAMESPACE
class GenHysteria : public QWidget {
Q_OBJECT
public:
explicit GenHysteria(const QSharedPointer<NekoRay::ProxyEntity> &ent, const QString &preset_config,
QWidget *parent = nullptr);
~GenHysteria() override;
private:
Ui::GenHysteria *ui;
QSharedPointer<NekoRay::ProxyEntity> ent;
QString preset_config;
signals:
void config_generated(const QString &result);
private slots:
void on_gen_clicked();
};

159
ui/edit/gen_hysteria.ui Normal file
View File

@@ -0,0 +1,159 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>GenHysteria</class>
<widget class="QWidget" name="GenHysteria">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>400</width>
<height>400</height>
</rect>
</property>
<layout class="QGridLayout" name="gridLayout_2">
<item row="7" column="0">
<widget class="QLabel" name="label_5">
<property name="text">
<string>Certificate Path</string>
</property>
</widget>
</item>
<item row="0" column="0">
<widget class="QLabel" name="label">
<property name="text">
<string>Obfs Password</string>
</property>
</widget>
</item>
<item row="4" column="1">
<widget class="QLineEdit" name="down_mbps">
<property name="text">
<string notr="true">50</string>
</property>
</widget>
</item>
<item row="4" column="0">
<widget class="QLabel" name="label_8">
<property name="text">
<string notr="true">down_mpbs</string>
</property>
</widget>
</item>
<item row="9" column="0">
<widget class="QPushButton" name="gen">
<property name="text">
<string>Generate</string>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="MyLineEdit" name="auth_string"/>
</item>
<item row="2" column="0">
<widget class="QLabel" name="label_3">
<property name="text">
<string>Protocol</string>
</property>
</widget>
</item>
<item row="3" column="0">
<widget class="QLabel" name="label_4">
<property name="text">
<string notr="true">up_mbps</string>
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="QComboBox" name="protocol">
<item>
<property name="text">
<string notr="true">udp</string>
</property>
</item>
<item>
<property name="text">
<string notr="true">wechat-video</string>
</property>
</item>
</widget>
</item>
<item row="0" column="1">
<widget class="MyLineEdit" name="obfs_password"/>
</item>
<item row="3" column="1">
<widget class="QLineEdit" name="up_mbps">
<property name="text">
<string notr="true">10</string>
</property>
</widget>
</item>
<item row="5" column="0">
<widget class="QLabel" name="label_6">
<property name="text">
<string notr="true">SNI</string>
</property>
</widget>
</item>
<item row="7" column="1">
<widget class="MyLineEdit" name="cert_path"/>
</item>
<item row="6" column="1">
<widget class="QLineEdit" name="alpn"/>
</item>
<item row="6" column="0">
<widget class="QLabel" name="label_7">
<property name="text">
<string notr="true">ALPN</string>
</property>
</widget>
</item>
<item row="5" column="1">
<widget class="MyLineEdit" name="sni"/>
</item>
<item row="1" column="0">
<widget class="QLabel" name="label_2">
<property name="text">
<string>Auth String</string>
</property>
</widget>
</item>
<item row="8" column="1">
<widget class="QCheckBox" name="allow_insecure">
<property name="text">
<string>Allow Insecure</string>
</property>
</widget>
</item>
<item row="8" column="0">
<widget class="QLabel" name="label_9">
<property name="text">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;&lt;a href=&quot;https://github.com/HyNetwork/hysteria/wiki&quot;&gt;&lt;span style=&quot; text-decoration: underline; color:#2980b9;&quot;&gt;Document&lt;/span&gt;&lt;/a&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="openExternalLinks">
<bool>true</bool>
</property>
</widget>
</item>
</layout>
</widget>
<customwidgets>
<customwidget>
<class>MyLineEdit</class>
<extends>QLineEdit</extends>
<header>ui/widget/MyLineEdit.h</header>
</customwidget>
</customwidgets>
<tabstops>
<tabstop>obfs_password</tabstop>
<tabstop>auth_string</tabstop>
<tabstop>protocol</tabstop>
<tabstop>up_mbps</tabstop>
<tabstop>down_mbps</tabstop>
<tabstop>sni</tabstop>
<tabstop>alpn</tabstop>
<tabstop>cert_path</tabstop>
<tabstop>gen</tabstop>
</tabstops>
<resources/>
<connections/>
</ui>

View File

@@ -587,7 +587,7 @@
</action>
<action name="menu_add_from_clipboard">
<property name="text">
<string>New profile from clipboard</string>
<string>Add profile from clipboard [ Ctrl+V ]</string>
</property>
</action>
<action name="menu_delete">

View File

@@ -113,6 +113,7 @@ void MainWindow::speedtest_current_group(int mode) {
QList<NekoRay::sys::ExternalProcess *> ext;
if (mode == libcore::TestMode::UrlTest || mode == libcore::FullTest) {
// TODO refactor: use only 1 instance
auto c = NekoRay::BuildConfig(profile, true);
// external test ???
if (!c->ext.isEmpty()) {