新增生成config.json界面基础配置的高级选项

This commit is contained in:
黑先森
2024-11-13 16:42:55 +08:00
parent 1c8314c6fa
commit 92d25ab907
19 changed files with 355 additions and 206 deletions
+5
View File
@@ -41,6 +41,11 @@ Releases [https://github.com/EasyTier/EasytierGame/releases](https://github.c
![game-step9](/assets/game-step9.png)
- 1.1.8 新增了 生成 easytier/config.json 的功能 会将一部分配置写入到 config.json 文件中,方便用户自定义配置,你可以在高级设置里启用和关闭这个功能(默认关闭)
**需要注意的是,如果config.json存在,每次启动easytierGame默认按照config.json的配置为准**
**你可以查看 config_template.json 里的注释进行配置**
![game-step10](/assets/game-step10.png)
## 特性
- 基于easytier组网工具开发,界面清晰简单
Binary file not shown.

After

Width:  |  Height:  |  Size: 29 KiB

+16
View File
@@ -0,0 +1,16 @@
import { BaseDirectory, writeTextFile } from "@tauri-apps/plugin-fs";
import useMainStore from "@/stores/index";
import { ElMessage } from "element-plus";
export const updateConfigJson = async () => {
const mainStore = useMainStore();
const path = import.meta.env.VITE_CONFIG_FILE_NAME;
try {
const { proxyNetworks, autoStart, relayAllPeerrpc, coonectAfterStart, multiThread, enablExitNode, useSmoltcp, saveErrorLog, logLevel, ...otherConfig } =
mainStore.config;
await writeTextFile(path, JSON.stringify(otherConfig, null, 4), { baseDir: BaseDirectory.Resource });
} catch (err) {
console.log(err);
ElMessage.error(`更新config.json失败`);
}
}
+12 -8
View File
@@ -1,14 +1,18 @@
import { type UnlistenFn } from "@tauri-apps/api/event";
import { getCurrentWindow, PhysicalPosition, type WindowOptions, Window } from "@tauri-apps/api/window";
import { getCurrentWindow, PhysicalPosition, type WindowOptions, Window, currentMonitor } from "@tauri-apps/api/window";
import { WebviewWindow } from "@tauri-apps/api/webviewWindow";
import type { WebviewLabel, WebviewOptions, } from "@tauri-apps/api/webview";
import type { WebviewLabel, WebviewOptions } from "@tauri-apps/api/webview";
export default async (
label: WebviewLabel,
options?: Omit<WebviewOptions, "x" | "y" | "width" | "height"> & WindowOptions,
afterCreatedFunc?: (webviewWindow: WebviewWindow, appWindow: Window) => void | null,
beforeCloseFunc?: () => void | null
) => {
let defaultOpts = {
let unListenlogClose: UnlistenFn | null = null;
let unlistenLogCreated: UnlistenFn | null = null;
let dialog = await WebviewWindow.getByLabel(label);
if (!dialog) {
let defaultOpts: {[key:string]: any, parent: Window | undefined} = {
parent: undefined,
closable: true,
resizable: true,
@@ -21,17 +25,17 @@ export default async (
const appWindow = getCurrentWindow();
if (appWindow) {
const appSize = await appWindow.outerSize();
// const monitor = await currentMonitor();
// console.log(monitor)
const factor = await appWindow.scaleFactor();
const appPosition = await appWindow.outerPosition();
// console.log((appPosition.x + appSize.width) / 1.25);
const logicalPosition = new PhysicalPosition(appPosition.x + appSize.width, appPosition.y).toLogical(factor);
defaultOpts.parent = appWindow as any;
defaultOpts.parent = appWindow;
// console.log(logicalPosition);
defaultOpts.x = logicalPosition.x;
defaultOpts.y = logicalPosition.y;
}
let unListenlogClose: UnlistenFn | null = null;
let unlistenLogCreated: UnlistenFn | null = null;
let dialog = await WebviewWindow.getByLabel(label);
if (!dialog) {
dialog = new WebviewWindow(label, { ...defaultOpts, ...options });
unlistenLogCreated = await dialog.once("tauri://webview-created", async () => {
if (dialog) {
+1
View File
@@ -1,3 +1,4 @@
VITE_CONFIG_PATH=easytier/config/
VITE_CONFIG_FILE_NAME=easytier/config.json
VITE_LOG_PATH=easytier/logs/
VITE_AUTO_START_SERVICE_NAME=easytierGameAutoStart
+1
View File
@@ -1,3 +1,4 @@
VITE_CONFIG_PATH=easytier/config/
VITE_CONFIG_FILE_NAME=easytier/config.json
VITE_LOG_PATH=easytier/logs/
VITE_AUTO_START_SERVICE_NAME=easytierGameAutoStart
+1 -1
View File
@@ -3,7 +3,7 @@
"private": true,
"author": "leizi97",
"description": "A simple network initiator based on Easytier",
"version": "1.1.7",
"version": "1.1.8",
"scripts": {
"dev": "nuxt dev --dotenv env/.env.dev --host 0.0.0.0",
"build": "nuxt generate --dotenv env/.env.prod"
+38 -7
View File
@@ -3,30 +3,47 @@
<div><ElCheckbox v-model="mainStore.config.disableIpv6">不使用IPv6</ElCheckbox></div>
<div class="flex items-center gap-[10px]">
<ElCheckbox v-model="mainStore.config.devName">自定义网卡名</ElCheckbox>
<ElInput maxlength="10" v-model="mainStore.config.devNameValue" placeholder="请输入网卡名"/>
<ElInput
maxlength="10"
v-model="mainStore.config.devNameValue"
placeholder="请输入网卡名"
/>
</div>
<div><ElCheckbox v-model="mainStore.config.disbleListenner">不监听任何端口只连接到对等节点</ElCheckbox></div>
<div><ElCheckbox v-model="mainStore.config.coonectAfterStart">软件启动后自动"启动联机"(搭配开机自启无感联机)</ElCheckbox></div>
<div class="flex items-center gap-[15px] flex-nowrap">
<ElCheckbox v-model="mainStore.config.saveErrorLog">输出日志到本地</ElCheckbox>
<div class="w-[140px]">
<ElSelect
v-model="mainStore.config.logLevel"
placeholder="请选择日志等级"
class="ml-[5px]">
class="ml-[5px]"
>
<ElOption
v-for="item in data"
:key="item"
:label="`level - ${item}`"
:value="item"></ElOption>
:value="item"
></ElOption>
</ElSelect>
</div>
<ElButton
@click="openLogDir"
size="small">
size="small"
>
打开日志目录
</ElButton>
</div>
<div><ElCheckbox v-model="mainStore.config.coonectAfterStart">软件启动后自动"启动联机"(搭配开机自启无感联机)</ElCheckbox></div>
<div class="flex items-center gap-[15px] flex-nowrap">
<ElCheckbox v-model="mainStore.createConfigInEasytier">自动生成界面配置文件easytier/config.json</ElCheckbox>
<ElButton
@click="openConfigJsonDir"
size="small"
>
打开config.json目录
</ElButton>
</div>
<ElDivider />
<div><ElCheckbox v-model="mainStore.config.enablExitNode">允许此节点成为出口节点</ElCheckbox></div>
<div><ElCheckbox v-model="mainStore.config.disableEncryption">禁用对等节点通信的加密默认为false必须与对等节点相同</ElCheckbox></div>
@@ -47,6 +64,7 @@
import { resourceDir as getResourceDir, join } from "@tauri-apps/api/path";
import { Command } from "@tauri-apps/plugin-shell";
import { exists, mkdir, BaseDirectory } from "@tauri-apps/plugin-fs";
import { ElMessage } from "element-plus";
const mainStore = useMainStore();
const appWindow = getCurrentWindow();
@@ -63,8 +81,21 @@
}
await Command.create("explorer", [logDirPath]).execute();
};
mainStore.$subscribe((...a) => {
const openConfigJsonDir = async () => {
const resourceDir = await getResourceDir();
const easytierDir = await join(resourceDir, "easytier/");
const isExists = await exists("easytier/", { baseDir: BaseDirectory.Resource });
if (isExists) {
await Command.create("explorer", [easytierDir]).execute();
} else {
ElMessage.error("config.json的目录不存在");
}
};
mainStore.$subscribe(async (...a) => {
// console.log("subscribe", a);
appWindow.emitTo("main", "config", { config: { ...mainStore.config } });
await appWindow.emitTo("main", "config", { config: { ...mainStore.config }, createConfigInEasytier: mainStore.createConfigInEasytier });
// if(mainStore.createConfigInEasytier) {
// updateConfigJson();
// }
});
</script>
+75 -12
View File
@@ -303,6 +303,8 @@
<ElDialog
width="95%"
top="10px"
append-to-body
:z-index="10"
class="!mb-0"
v-model="importConfigData.visible"
:close-on-press-escape="false"
@@ -316,7 +318,7 @@
></ElInput>
<template #footer>
<div>
<el-text type="danger">导入成功后您当前的配置将被完全替换</el-text>
<el-text type="danger">导入成功后您当前的部分配置将被替换</el-text>
</div>
<div class="text-right">
<ElButton
@@ -332,6 +334,8 @@
<ElDialog
width="95%"
top="30px"
append-to-body
:z-index="10"
class="!mb-0"
v-model="configStart.visible"
:close-on-press-escape="false"
@@ -400,8 +404,10 @@
import etWindows from "@/composables/windows";
import * as tauriAutoStart from "@tauri-apps/plugin-autostart";
import { resourceDir as getResourceDir, join } from "@tauri-apps/api/path";
import { readDir, exists, mkdir, BaseDirectory } from "@tauri-apps/plugin-fs";
import { readDir, exists, mkdir, BaseDirectory, readTextFile } from "@tauri-apps/plugin-fs";
import { updateConfigJson } from "~/composables/configJson";
import { writeText, readText } from "@tauri-apps/plugin-clipboard-manager";
import { bounce } from "~/utils";
let is_close = false;
@@ -506,7 +512,6 @@
const start = logArr.length > 1000 ? logArr.length - 1000 : 0;
data.log = logArr.slice(start).join("\n");
data.log += (event.payload as string) + "\n";
});
this.unListenOutPut = unListen;
},
@@ -630,15 +635,15 @@
const compatibleInitAutoStart = async () => {
try {
const is_enable_by_task = (await invoke("autostart_is_enabled")) as boolean;
if (is_enable_by_task) {
await tauriAutoStart.enable();
await invoke("spawn_autostart", { enabled: false });
}
// const is_enable_by_task = (await invoke("autostart_is_enabled")) as boolean;
// if (is_enable_by_task) {
// await tauriAutoStart.enable();
// await invoke("spawn_autostart", { enabled: false });
// }
const is_enable = await tauriAutoStart.isEnabled();
config.autoStart = is_enable;
} catch (err) {
await invoke("spawn_autostart", { enabled: false });
// await invoke("spawn_autostart", { enabled: false });
await tauriAutoStart.disable();
config.autoStart = false;
}
@@ -651,10 +656,49 @@
}
};
const initGuiJson = async () => {
const path = import.meta.env.VITE_CONFIG_FILE_NAME;
const isExists = await exists(path, { baseDir: BaseDirectory.Resource });
if (isExists) {
const guiJsonStr = await readTextFile(path, { baseDir: BaseDirectory.Resource });
if (guiJsonStr) {
try {
const regex = /^(\s*\/\/.*)/gm;
const regex2 = /(,?)\s*\/\/.*(?=\n|$|\r\n)/gm;
const resultStr = guiJsonStr.replace(regex, "").replace(regex2, "$1");
const guiJson = JSON.parse(resultStr);
mainStore.$patch({
config: {
...mainStore.config,
...guiJson
}
});
if (guiJson.serverUrl) {
mainStore.basePeers = [...new Set([guiJson.serverUrl, ...mainStore.basePeers])];
}
} catch (err) {
ElMessage.error(`config.json格式错误`);
}
}
}
const b = bounce(600);
mainStore.$subscribe(
(...a) => {
if (mainStore.createConfigInEasytier) {
b(async () => {
await updateConfigJson();
});
}
},
{ immediate: true }
);
};
let logsTimer: NodeJS.Timeout | null = null;
onMounted(async () => {
// await handleUpdateCore(); //默认不自动更新
await initGuiJson();
await compatibleInitAutoStart();
// await initAutoStart();
await initStartWinIpBroadcast();
@@ -788,7 +832,7 @@
if (args[0] === "-c") {
ElMessage.warning({
message: "使用配置文件中.",
duration: 5000,
duration: 5000
});
}
data.log = ""; //清空日志
@@ -826,7 +870,20 @@
}
if (command === "share_config") {
try {
const WT = btoa(encodeURIComponent(JSON.stringify({ config: mainStore.config })))
const {
proxyNetworks,
autoStart,
coonectAfterStart,
multiThread,
hostname,
enablExitNode,
useSmoltcp,
saveErrorLog,
logLevel,
ipv4,
...otherConfig
} = mainStore.config;
const WT = btoa(encodeURIComponent(JSON.stringify({ config: otherConfig })));
await writeText(WT);
ElMessage.success("配置已复制");
} catch (err) {
@@ -847,11 +904,17 @@
cancelButtonText: "取消"
});
const payload = JSON.parse(decodeURIComponent(atob(importConfigData.data)));
mainStore.$patch(payload);
mainStore.$patch({
config: {
...mainStore.config,
...payload.config
}
});
ElMessage.success("导入成功");
importConfigData.visible = false;
mainStore.basePeers = [...new Set([config.serverUrl, ...mainStore.basePeers])];
} catch (err) {
console.log(err);
if (err !== "cancel") {
ElMessage.error("导入失败");
}
+1 -1
View File
@@ -2,4 +2,4 @@
# will have compiled files and executables
/target/
/gen/schemas
/easytier/
/easytier/logs
+1 -1
View File
@@ -1176,7 +1176,7 @@ checksum = "0d6ef0072f8a535281e4876be788938b528e9a1d43900b82c2569af7da799125"
[[package]]
name = "easytier-game"
version = "1.1.7"
version = "1.1.8"
dependencies = [
"log",
"planif",
+1 -1
View File
@@ -1,6 +1,6 @@
[package]
name = "easytier-game"
version = "1.1.7"
version = "1.1.8"
homepage = "https://github.com/EasyTier/EasyTier"
repository = "https://github.com/EasyTier/EasytierGame"
description = "A simple network initiator based on Easytier"
+2
View File
@@ -84,6 +84,8 @@
"fs:allow-open",
"fs:allow-resource-read",
"fs:allow-resource-read-recursive",
"fs:allow-resource-write",
"fs:allow-resource-write-recursive",
"clipboard-manager:allow-clear",
"clipboard-manager:allow-read-text",
"clipboard-manager:allow-write-text"
+22
View File
@@ -0,0 +1,22 @@
{
// 如果您的配置过于复杂,可以参考 使用配置文件进行联机的办法,以下是基础的界面配置,用于快速分享联机
"protocol": [
"tcp",
"udp"
], // 协议类型
"serverUrl": "public.easytier.top:11010", // easytier服务地址
"networkName": "", // 网络名
"networkPassword": "", // 网络密码
"hostname": "configTest", // 主机名
"ipv4": "10.126.126.1", // IP地址(选填,下面有dhcp)
"disableIpv6": false, // 禁用ipv6
"disbleListenner": true, // 禁用端口监听
"disableEncryption": false, // 禁用加密
"noTun": false, // 禁用tun
"latencyfirst": false, // 延迟优先
"disableUdpHolePunching": false, // 禁用udp打洞
"disbleP2p": false, // 禁用p2p, 强制中转
"dhcp": false, // 动态分配IP
"devName": false, // 是否启用自定义网卡名
"devNameValue": "" // 网卡名(启用devName之后才生效)
}
Binary file not shown.
+3 -2
View File
@@ -1,7 +1,7 @@
{
"$schema": "../node_modules/@tauri-apps/cli/config.schema.json",
"productName": "easytier-game",
"version": "1.1.7",
"version": "1.1.8",
"identifier": "com.tauri.easytier-game",
"build": {
@@ -13,7 +13,7 @@
"app": {
"windows": [
{
"title": "easytier-game 1.1.7",
"title": "easytier-game 1.1.8",
"minWidth": 340,
"width": 340,
"height": 305,
@@ -39,6 +39,7 @@
"resources": [
"easytier/config/",
"easytier/icons/",
"easytier/config_template.json",
"easytier/tool/WinIPBroadcast.exe",
"easytier/easytier-cli.exe",
"easytier/easytier-core.exe",
+1
View File
@@ -35,6 +35,7 @@ export default defineStore("main", {
configStartEnable: false, //使用配置文件启动
configPath: "", //配置文件路径
winIpBcAutoStart: true,
createConfigInEasytier: false, //在easytier目录生成config.json文件吗
winipBcPid: 0,
winipBcStart: false,
+1
View File
@@ -6,6 +6,7 @@
"components/**/*.ts",
"components/**/*.js",
"components/**/*.vue",
"composables/**/*.ts",
"app.vue",
"pages/**/*.ts",
"pages/**/*.js",
+1
View File
@@ -1,5 +1,6 @@
interface ImportMetaEnv {
readonly VITE_CONFIG_PATH: string;
readonly VITE_CONFIG_FILE_NAME: string;
}
interface ImportMeta {