mirror of
https://github.com/EasyTier/EasytierGame.git
synced 2025-05-19 10:27:56 +00:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
8ed652ee26 | ||
|
|
9d976707ac | ||
|
|
0b54a623a8 | ||
|
|
7501a5661c | ||
|
|
539092d769 | ||
|
|
cefcc930b8 | ||
|
|
e7d92cce47 | ||
|
|
76bdec0e1d | ||
|
|
997f3798ae | ||
|
|
f9e0b8e1db | ||
|
|
582a4ab819 | ||
|
|
0fde619516 | ||
|
|
410f0dc32b |
@@ -9,26 +9,26 @@
|
||||
import { warn, debug, trace, info, error } from "@tauri-apps/plugin-log";
|
||||
function forwardConsole(fnName: "log" | "debug" | "info" | "warn" | "error", logger: (message: string) => Promise<void>) {
|
||||
const original = console[fnName];
|
||||
console[fnName] = (message) => {
|
||||
console[fnName] = message => {
|
||||
original(message);
|
||||
if (import.meta.env.PROD) {
|
||||
try {
|
||||
if (typeof message === "string") {
|
||||
logger(message);
|
||||
} else {
|
||||
logger(JSON.stringify(message));
|
||||
}
|
||||
} catch (e) {
|
||||
logger(`${message}`);
|
||||
try {
|
||||
if (typeof message === "string") {
|
||||
logger(message);
|
||||
} else {
|
||||
logger(JSON.stringify(message));
|
||||
}
|
||||
} catch (e) {
|
||||
logger(`${message}`);
|
||||
}
|
||||
};
|
||||
}
|
||||
forwardConsole("log", info);
|
||||
forwardConsole("debug", debug);
|
||||
forwardConsole("info", info);
|
||||
forwardConsole("warn", warn);
|
||||
forwardConsole("error", error);
|
||||
if (import.meta.env.PROD) {
|
||||
forwardConsole("log", info);
|
||||
forwardConsole("debug", debug);
|
||||
forwardConsole("info", info);
|
||||
forwardConsole("warn", warn);
|
||||
forwardConsole("error", error);
|
||||
}
|
||||
|
||||
const mainStore = useMainStore();
|
||||
// console.log(mainStore.theme)
|
||||
|
||||
@@ -52,4 +52,8 @@ html.dark body {
|
||||
|
||||
.el-table {
|
||||
font-size: 12px!important;
|
||||
}
|
||||
|
||||
.el-select-dropdown__wrap {
|
||||
max-height: 150px!important;
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
<template>
|
||||
<ElTag size="small" type="danger">内核 >= {{ $attrs.version }}</ElTag>
|
||||
</template>
|
||||
@@ -26,6 +26,8 @@ export const updateConfigJson = async (configJsonSeverUrl: Array<string> | strin
|
||||
enableCustomListener,
|
||||
enablePreventSleep,
|
||||
customListenerData,
|
||||
customListenerV6Data,
|
||||
enableCustomListenerV6,
|
||||
...otherConfig
|
||||
} = mainStore.config;
|
||||
let writeServerUrl: Array<string> | string = serverUrl;
|
||||
|
||||
+14
-1
@@ -7,7 +7,7 @@ import useMainStore from "@/stores/index";
|
||||
import { resourceDir as getResourceDir, join } from "@tauri-apps/api/path";
|
||||
import { invoke } from "@tauri-apps/api/core";
|
||||
// import { ElConfirmPrimary } from "~/utils/element";
|
||||
// import { open } from "@tauri-apps/plugin-shell";
|
||||
import { open } from "@tauri-apps/plugin-shell";
|
||||
|
||||
const DEFAULT_TRAY_NAME = "main";
|
||||
|
||||
@@ -64,6 +64,8 @@ export async function generateMenuItem(beforExit: Function, handleConnection:Fun
|
||||
await MenuItemExchangeConnection("联机 / 断开", handleConnection),
|
||||
await MenuItemTheme(),
|
||||
await PredefinedMenuItem.new({ item: "Separator" }),
|
||||
await MenuItemPublicPeers(),
|
||||
await PredefinedMenuItem.new({ item: "Separator" }),
|
||||
await MenuItemExit("退出", beforExit),
|
||||
];
|
||||
}
|
||||
@@ -81,6 +83,17 @@ export async function MenuItemExit(text: string, beforExit: Function) {
|
||||
});
|
||||
}
|
||||
|
||||
export async function MenuItemPublicPeers() {
|
||||
|
||||
return await MenuItem.new({
|
||||
id: "publicPeers",
|
||||
text: "公共节点",
|
||||
action: async () => {
|
||||
await open("https://easytier.gd.nkbpal.cn/status/easytier")
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
export async function MenuItemShow(text: string) {
|
||||
return await MenuItem.new({
|
||||
id: "show",
|
||||
|
||||
+12
-10
@@ -3,7 +3,7 @@
|
||||
"private": true,
|
||||
"author": "leizi97",
|
||||
"description": "A simple network initiator based on Easytier",
|
||||
"version": "1.3.1",
|
||||
"version": "1.3.5",
|
||||
"scripts": {
|
||||
"dev": "nuxt dev --dotenv env/.env.dev --host 0.0.0.0",
|
||||
"build": "nuxt generate --dotenv env/.env.prod",
|
||||
@@ -11,31 +11,33 @@
|
||||
},
|
||||
"devDependencies": {
|
||||
"@element-plus/icons-vue": "^2.3.1",
|
||||
"@element-plus/nuxt": "^1.1.0",
|
||||
"@nuxtjs/tailwindcss": "^6.12.0",
|
||||
"@element-plus/nuxt": "^1.1.1",
|
||||
"@nuxtjs/tailwindcss": "^6.12.2",
|
||||
"@pinia/nuxt": "0.9.0",
|
||||
"@tauri-apps/api": "^2.1.1",
|
||||
"@tauri-apps/cli": "^2.1.0",
|
||||
"@tauri-apps/plugin-cli": "^2.0.0",
|
||||
"@tauri-apps/plugin-cli": "^2.2.0",
|
||||
"@tauri-apps/plugin-clipboard-manager": "^2.0.0",
|
||||
"@tauri-apps/plugin-fs": "^2.2.0",
|
||||
"@tauri-apps/plugin-log": "^2.2.0",
|
||||
"@tauri-apps/plugin-shell": "^2.2.0",
|
||||
"@tauri-apps/plugin-window-state": "^2.2.0",
|
||||
"@types/lodash-es": "^4.17.12",
|
||||
"@vitejs/plugin-vue-jsx": "^4.1.0",
|
||||
"@vueuse/core": "12.0.0",
|
||||
"@vitejs/plugin-vue-jsx": "^4.1.1",
|
||||
"@vueuse/core": "12.2.0",
|
||||
"archiver": "^7.0.1",
|
||||
"element-plus": "^2.8.7",
|
||||
"element-plus": "^2.9.1",
|
||||
"less": "^4.2.0",
|
||||
"lodash-es": "^4.17.21",
|
||||
"nuxt": "^3.14.1592",
|
||||
"nuxt": "3.15.0",
|
||||
"pinia": "^2.3.0",
|
||||
"pinia-plugin-persistedstate": "^4.1.3",
|
||||
"pinia-plugin-persistedstate": "^4.2.0",
|
||||
"postcss": "^8.4.38",
|
||||
"prettier": "^3.4.1",
|
||||
"prettier-plugin-tailwindcss": "^0.6.9",
|
||||
"typescript": "^5.6.3",
|
||||
"vue-clipboard3": "^2.0.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"@tauri-apps/plugin-dialog": "~2"
|
||||
}
|
||||
}
|
||||
|
||||
+72
-9
@@ -1,9 +1,9 @@
|
||||
<template>
|
||||
<div class="h-full overflow-auto flex flex-col items-start px-[25px]">
|
||||
<div class="flex h-full flex-col items-start overflow-auto px-[25px]">
|
||||
<div><ElCheckbox v-model="mainStore.config.disableIpv6">不使用IPv6</ElCheckbox></div>
|
||||
<div class="flex items-center gap-[15px] flex-nowrap">
|
||||
<div class="flex items-center gap-[5px] flex-nowrap">
|
||||
<ElCheckbox v-model="mainStore.config.enableCustonProtocol">自定义联机时使用的默认协议</ElCheckbox>
|
||||
<div class="flex flex-nowrap items-center gap-[15px]">
|
||||
<div class="flex flex-nowrap items-center gap-[5px]">
|
||||
<ElCheckbox v-model="mainStore.config.enableCustomProtocol">自定义联机时使用的默认协议</ElCheckbox>
|
||||
<ElTooltip content="如果没有支持该协议的节点地址,程序会自动处理,请放心使用">
|
||||
<ElIcon><QuestionFilled /></ElIcon>
|
||||
</ElTooltip>
|
||||
@@ -24,7 +24,7 @@
|
||||
</ElSelect>
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex items-center gap-[15px] flex-nowrap">
|
||||
<div class="flex flex-nowrap items-center gap-[15px]">
|
||||
<ElCheckbox v-model="mainStore.config.saveErrorLog">输出日志到本地</ElCheckbox>
|
||||
<div class="w-[140px]">
|
||||
<ElSelect
|
||||
@@ -49,7 +49,7 @@
|
||||
</ElButton>
|
||||
</div>
|
||||
<div><ElCheckbox v-model="mainStore.config.connectAfterStart">软件启动后,自动"启动联机"(搭配开机自启,无感联机)</ElCheckbox></div>
|
||||
<div class="flex items-center gap-[15px] flex-nowrap">
|
||||
<div class="flex flex-nowrap items-center gap-[15px]">
|
||||
<ElCheckbox v-model="mainStore.createConfigInEasytier">自动生成界面配置文件easytier/config.json</ElCheckbox>
|
||||
<ElButton
|
||||
@click="openConfigJsonDir"
|
||||
@@ -58,7 +58,7 @@
|
||||
打开config.json目录
|
||||
</ElButton>
|
||||
</div>
|
||||
<div><ElCheckbox v-model="mainStore.config.enablePreventSleep">防止休眠</ElCheckbox></div>
|
||||
<div><ElCheckbox v-model="mainStore.config.enablePreventSleep">防止系统休眠(比如:屏幕会一直亮着)</ElCheckbox></div>
|
||||
<ElDivider />
|
||||
<div class="flex items-center gap-[10px]">
|
||||
<ElCheckbox v-model="mainStore.config.disbleListenner">不监听任何端口,只连接到对等节点</ElCheckbox>
|
||||
@@ -124,6 +124,27 @@
|
||||
</template>
|
||||
</ElDialog>
|
||||
</div>
|
||||
<div class="flex items-center gap-[10px]">
|
||||
<ElCheckbox
|
||||
:disabled="mainStore.config.disbleListenner"
|
||||
v-model="mainStore.config.enableCustomListenerV6"
|
||||
>
|
||||
自定义IPV6监听地址
|
||||
</ElCheckbox>
|
||||
<div class="w-[200px]">
|
||||
<ElInput
|
||||
:disabled="mainStore.config.disbleListenner || mainStore.config.enableCustomListenerV6"
|
||||
size="small"
|
||||
:maxlength="100"
|
||||
v-model="mainStore.config.customListenerV6Data"
|
||||
placeholder="请输入自定义IPV6监听地址"
|
||||
/>
|
||||
</div>
|
||||
<ElTooltip content="例如:tcp://[::]:11010,如果未设置,将在随机UDP端口上监听">
|
||||
<ElIcon><QuestionFilled /></ElIcon>
|
||||
</ElTooltip>
|
||||
<CoreVersionWarning version="2.1.0" />
|
||||
</div>
|
||||
<ElDivider />
|
||||
<div class="flex items-center gap-[10px]">
|
||||
<ElCheckbox v-model="mainStore.config.devName">自定义网卡名</ElCheckbox>
|
||||
@@ -165,6 +186,27 @@
|
||||
<div><ElCheckbox v-model="mainStore.config.enablExitNode">允许此节点成为出口节点</ElCheckbox></div>
|
||||
<div><ElCheckbox v-model="mainStore.config.disableEncryption">禁用对等节点通信的加密</ElCheckbox></div>
|
||||
<div><ElCheckbox v-model="mainStore.config.multiThread">启用多线程运行</ElCheckbox></div>
|
||||
<div class="flex items-center gap-[10px]">
|
||||
<ElText>压缩算法</ElText>
|
||||
<div class="w-[160px]">
|
||||
<ElSelect
|
||||
size="small"
|
||||
v-model="mainStore.config.compression"
|
||||
placeholder="请选择压缩算法"
|
||||
>
|
||||
<ElOption
|
||||
v-for="item in [
|
||||
['none', '不压缩(游戏联机推荐)'],
|
||||
['zstd', 'zstd算法']
|
||||
]"
|
||||
:key="item[0]"
|
||||
:label="item[1]"
|
||||
:value="item[0]"
|
||||
></ElOption>
|
||||
</ElSelect>
|
||||
</div>
|
||||
<CoreVersionWarning version="2.1.0" />
|
||||
</div>
|
||||
<ElDivider />
|
||||
|
||||
<div><ElCheckbox v-model="mainStore.config.useSmoltcp">为子网代理启用smoltcp堆栈</ElCheckbox></div>
|
||||
@@ -180,11 +222,13 @@
|
||||
import { QuestionFilled } from "@element-plus/icons-vue";
|
||||
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 { exists, mkdir, BaseDirectory, remove } from "@tauri-apps/plugin-fs";
|
||||
import { ElMessage } from "element-plus";
|
||||
import { reactive } from "vue";
|
||||
import { dataSubscribe } from "@/composables/windows";
|
||||
import { supportProtocols } from "~/utils";
|
||||
import { ATJ, supportProtocols } from "~/utils";
|
||||
import CoreVersionWarning from "@/components/CoreVersionWarning.vue";
|
||||
import { ElConfirmDanger } from "~/utils/element";
|
||||
|
||||
const protocols = supportProtocols();
|
||||
const listenerDialogData = reactive<{ [key: string]: any }>({
|
||||
@@ -226,6 +270,25 @@
|
||||
};
|
||||
|
||||
dataSubscribe(async (...a) => {
|
||||
if (!mainStore.createConfigInEasytier) {
|
||||
// 考虑删除本地config.json文件
|
||||
const configJsonPath = import.meta.env.VITE_CONFIG_FILE_NAME;
|
||||
const isExists = await exists(configJsonPath, { baseDir: BaseDirectory.Resource });
|
||||
// console.log({ isExists });
|
||||
if (isExists) {
|
||||
const [error, _] = await ElConfirmDanger("生成配置文件功能被关闭,是否删除本地config.json", "提示", {
|
||||
confirmButtonText: "删除",
|
||||
cancelButtonText: "保留"
|
||||
});
|
||||
if (!error) {
|
||||
// 删除本地config.json文件
|
||||
const [error, _] = await ATJ(remove(configJsonPath, { baseDir: BaseDirectory.Resource }));
|
||||
if (error) {
|
||||
ElMessage.error("删除失败,请打开目录手动删除");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return {
|
||||
config: { ...mainStore.config },
|
||||
createConfigInEasytier: mainStore.createConfigInEasytier
|
||||
|
||||
+97
-3
@@ -1,6 +1,9 @@
|
||||
<template>
|
||||
<div class="h-full flex flex-col gap-[10px]">
|
||||
<ElRadioGroup v-model="mainStore.cidrEnable">
|
||||
<div class="flex h-full flex-col gap-[10px]">
|
||||
<ElRadioGroup
|
||||
:disabled="!data.isSwitchEnable"
|
||||
v-model="mainStore.cidrEnable"
|
||||
>
|
||||
<ElRadioButton :value="true">开启</ElRadioButton>
|
||||
<ElRadioButton :value="false">关闭</ElRadioButton>
|
||||
</ElRadioGroup>
|
||||
@@ -9,16 +12,107 @@
|
||||
placeholder="例如: 192.168.1.0/24 一行一个"
|
||||
v-model="mainStore.config.proxyNetworks"
|
||||
type="textarea"
|
||||
:rows="30"
|
||||
:rows="5"
|
||||
resize="none"
|
||||
></ElInput>
|
||||
<ElTable
|
||||
stripe
|
||||
border
|
||||
empty-text="暂无数据"
|
||||
:data="data.route"
|
||||
class="mt-[5px]"
|
||||
>
|
||||
<ElTableColumn
|
||||
sortable
|
||||
width="140"
|
||||
label="主机名"
|
||||
prop="hostname"
|
||||
></ElTableColumn>
|
||||
<ElTableColumn
|
||||
width="120"
|
||||
sortable
|
||||
label="虚拟网IP"
|
||||
prop="ipv4"
|
||||
></ElTableColumn>
|
||||
<ElTableColumn
|
||||
sortable
|
||||
label="被代理的子网"
|
||||
prop="proxy_cidrs"
|
||||
></ElTableColumn>
|
||||
</ElTable>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<script setup lang="ts">
|
||||
import useMainStore from "@/stores/index";
|
||||
import { dataSubscribe } from "@/composables/windows";
|
||||
import { invoke } from "@tauri-apps/api/core";
|
||||
import { reactive, onMounted, onBeforeUnmount } from "vue";
|
||||
import { ATJ, parseCliInfo } from "@/utils";
|
||||
import { listen, type UnlistenFn } from "@tauri-apps/api/event";
|
||||
const mainStore = useMainStore();
|
||||
|
||||
const data = reactive<{ [key: string]: any }>({
|
||||
route: [],
|
||||
isStart: false,
|
||||
isSwitchEnable: false,
|
||||
isRunning: false
|
||||
});
|
||||
|
||||
const listenOutput = async () => {
|
||||
data.isRunning = true;
|
||||
const [error, member] = await ATJ(invoke<string>("get_route_by_cli"));
|
||||
data.isRunning = false;
|
||||
// if(!member) return;
|
||||
if (error) {
|
||||
data.route = [];
|
||||
return "";
|
||||
}
|
||||
if (member === "_EasytierGameCliFailedToConnect_") {
|
||||
data.route = [];
|
||||
await listenOutput();
|
||||
return;
|
||||
}
|
||||
const routeInfo = parseCliInfo(member);
|
||||
routeInfo.forEach(value => {
|
||||
if (value.cost === "Local") {
|
||||
value.cost = "本机";
|
||||
}
|
||||
if (value.ipv4 && value.ipv4.includes("/")) {
|
||||
value.ipv4 = value.ipv4.split("/")[0];
|
||||
}
|
||||
});
|
||||
data.route = routeInfo;
|
||||
};
|
||||
|
||||
const listenStart = async () => {
|
||||
const unListen = await listen<boolean>("route", async event => {
|
||||
data.isStart = event.payload;
|
||||
if (data.isStart) {
|
||||
data.isSwitchEnable = false;
|
||||
if (mainStore.cidrEnable && !data.isRunning) {
|
||||
await listenOutput();
|
||||
} else {
|
||||
data.route = [];
|
||||
}
|
||||
} else {
|
||||
data.isSwitchEnable = true;
|
||||
data.route = [];
|
||||
}
|
||||
});
|
||||
return unListen;
|
||||
};
|
||||
|
||||
let unlistenStart: UnlistenFn | null = null;
|
||||
|
||||
onMounted(async () => {
|
||||
unlistenStart = await listenStart();
|
||||
});
|
||||
|
||||
onBeforeUnmount(() => {
|
||||
unlistenStart && unlistenStart();
|
||||
});
|
||||
|
||||
dataSubscribe(async (...a) => {
|
||||
return { cidrEnable: mainStore.cidrEnable, config: { ...mainStore.config } };
|
||||
});
|
||||
|
||||
+180
-56
@@ -55,6 +55,7 @@
|
||||
placeholder="请选择服务器地址"
|
||||
default-first-option
|
||||
v-model="config.serverUrl"
|
||||
no-data-text="无服务器地址"
|
||||
@change="handleServerUrlChange"
|
||||
>
|
||||
<template #prefix>
|
||||
@@ -83,15 +84,34 @@
|
||||
:value="item"
|
||||
>
|
||||
<div class="flex max-w-[calc(100vw-62px)] flex-nowrap items-center gap-[20px] overflow-hidden">
|
||||
<ElTooltip v-if="item && item.length > 30" placement="top" :content="item || '-'">
|
||||
<ElTooltip
|
||||
v-if="item && item.length > 26"
|
||||
placement="top"
|
||||
:content="item || '-'"
|
||||
>
|
||||
<p class="truncate">{{ item }}</p>
|
||||
</ElTooltip>
|
||||
<p v-else class="truncate">{{ item }}</p>
|
||||
<p
|
||||
v-else
|
||||
class="truncate"
|
||||
>
|
||||
{{ item }}
|
||||
</p>
|
||||
<div class="ml-auto flex-shrink-0">
|
||||
<ElButton
|
||||
@click.stop="copyServerUrl(item)"
|
||||
circle
|
||||
size="small"
|
||||
title="复制"
|
||||
:icon="CopyDocument"
|
||||
></ElButton>
|
||||
|
||||
<ElButton
|
||||
@click.stop="handleDeleteServerUrl(item)"
|
||||
round
|
||||
circle
|
||||
size="small"
|
||||
:icon="Delete"
|
||||
title="删除"
|
||||
type="danger"
|
||||
></ElButton>
|
||||
</div>
|
||||
@@ -310,17 +330,24 @@
|
||||
增强工具
|
||||
</ElButton>
|
||||
</div>
|
||||
|
||||
<ElBadge badge-class="!text-[9px] cursor-pointer" :hidden="!data.hasNewVersion" :offset="[6, 7]" value="N">
|
||||
|
||||
<ElBadge
|
||||
badge-class="!text-[9px] cursor-pointer"
|
||||
:hidden="!data.hasNewVersion"
|
||||
:offset="[6, 7]"
|
||||
value="N"
|
||||
>
|
||||
<!-- <ElTooltip :disabled="!data.hasNewVersion" content="有新版发布了!"> -->
|
||||
<ElLink
|
||||
class="ml-[8px] truncate pb-[2px] !text-[9px]"
|
||||
type="info"
|
||||
:underline="false"
|
||||
@click="open('https://github.com/EasyTier/EasytierGame')"
|
||||
>EasytierGame主页</ElLink>
|
||||
<ElLink
|
||||
class="ml-[8px] truncate pb-[2px] !text-[9px]"
|
||||
type="info"
|
||||
:underline="false"
|
||||
@click="open('https://github.com/EasyTier/EasytierGame')"
|
||||
>
|
||||
EasytierGame主页
|
||||
</ElLink>
|
||||
<!-- </ElTooltip> -->
|
||||
</ElBadge>
|
||||
</ElBadge>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -346,7 +373,10 @@
|
||||
>
|
||||
刷新
|
||||
</ElButton>
|
||||
<ElTooltip placement="top" content="打开内核缓存目录">
|
||||
<ElTooltip
|
||||
placement="top"
|
||||
content="打开内核缓存目录"
|
||||
>
|
||||
<ElButton
|
||||
:icon="Folder"
|
||||
size="small"
|
||||
@@ -510,23 +540,24 @@
|
||||
Tools,
|
||||
MagicStick,
|
||||
SetUp,
|
||||
Folder
|
||||
Folder,
|
||||
CopyDocument
|
||||
} from "@element-plus/icons-vue";
|
||||
import { reactive, onBeforeUnmount, onMounted, ref } from "vue";
|
||||
import { reactive, onBeforeUnmount, onMounted, ref, toRaw } from "vue";
|
||||
import { useTray, setTrayRunState, setTrayTooltip, checkNewVersion } from "~/composables/tray";
|
||||
import { getMatches } from "@tauri-apps/plugin-cli";
|
||||
import { initStartWinIpBroadcast } from "~/composables/netcard";
|
||||
import useMainStore from "@/stores/index";
|
||||
import { ElMessage, ElMessageBox } from "element-plus";
|
||||
import { getCurrentWindow } from "@tauri-apps/api/window";
|
||||
import { getAllWebviewWindows } from "@tauri-apps/api/webviewWindow";
|
||||
import { getCurrentWindow, type Window } from "@tauri-apps/api/window";
|
||||
import { getAllWebviewWindows, WebviewWindow } from "@tauri-apps/api/webviewWindow";
|
||||
import etWindows from "@/composables/windows";
|
||||
import { resourceDir as getResourceDir, join } from "@tauri-apps/api/path";
|
||||
import { readDir, exists, mkdir, BaseDirectory, readTextFile } from "@tauri-apps/plugin-fs";
|
||||
import { readDir, exists, mkdir, BaseDirectory, readTextFile, readFile } from "@tauri-apps/plugin-fs";
|
||||
import { updateConfigJson } from "~/composables/configJson";
|
||||
import { writeText, readText } from "@tauri-apps/plugin-clipboard-manager";
|
||||
import { sortedUniq, uniq } from "lodash-es";
|
||||
import { bounce, addQQGroup, supportProtocols, preventSleep, stopPreventSleep } from "~/utils";
|
||||
import { bounce, addQQGroup, supportProtocols, preventSleep, stopPreventSleep, ATJ } from "~/utils";
|
||||
import { ElConfirmDanger, ElConfirmPrimary } from "~/utils/element";
|
||||
import { getServerArgs } from "@/composables/server";
|
||||
|
||||
@@ -539,6 +570,7 @@
|
||||
await invoke("stop_command", { child_id: listenObj.thread_id || 0 });
|
||||
await invoke("stop_command", { child_id: data.winipBcPid || 0 });
|
||||
await invoke("stop_command", { child_id: listenObj.server_thread_id.value || 0 });
|
||||
await stopPreventSleep(); //关闭防休眠
|
||||
},
|
||||
async () => {
|
||||
await handleConnection();
|
||||
@@ -590,6 +622,17 @@
|
||||
data: ""
|
||||
});
|
||||
|
||||
const copyServerUrl = async (serverUrl: string) => {
|
||||
const [err, _] = await ATJ(writeText(serverUrl));
|
||||
|
||||
if (!err) {
|
||||
ElMessage.success("地址已复制");
|
||||
} else {
|
||||
console.error(err);
|
||||
ElMessage.success("复制失败");
|
||||
}
|
||||
};
|
||||
|
||||
const closePrevent = async () => {
|
||||
const appWindow = getCurrentWindow();
|
||||
if (appWindow.label == "main") {
|
||||
@@ -648,6 +691,17 @@
|
||||
mainStore.basePeers = uniq([mainStore.config.serverUrl, ...mainStore.basePeers]);
|
||||
};
|
||||
|
||||
// 手动触发持久化数据
|
||||
const persist = async (appWindow: Window) => {
|
||||
try {
|
||||
appWindow.emitTo({ kind: "Any" }, "global-main-store", { store: { ...mainStore.$state } });
|
||||
mainStore.$persist();
|
||||
} catch (err) {
|
||||
console.error(err);
|
||||
ElMessage.error("手动持久数据失败");
|
||||
}
|
||||
};
|
||||
|
||||
const listenObj: { [key: string]: any } = {
|
||||
unListenOutPut: null,
|
||||
unListenThreadId: null,
|
||||
@@ -742,19 +796,18 @@
|
||||
const appWindow = getCurrentWindow();
|
||||
const unListen = await listen("config", event => {
|
||||
const ipv4 = config.ipv4;
|
||||
console.log(event.payload)
|
||||
mainStore.$patch(event.payload as any);
|
||||
config.ipv4 = ipv4;
|
||||
if(mainStore.config.enablePreventSleep) {
|
||||
if (mainStore.config.enablePreventSleep) {
|
||||
preventSleep();
|
||||
}else {
|
||||
} else {
|
||||
stopPreventSleep();
|
||||
}
|
||||
appWindow.emitTo({ kind: "Any" }, "global-main-store", { store: { ...mainStore.$state } });
|
||||
persist(appWindow);
|
||||
});
|
||||
const unListen2 = mainStore.$subscribe(() => {
|
||||
appWindow.emitTo({ kind: "Any" }, "global-main-store", { store: { ...mainStore.$state } });
|
||||
})
|
||||
persist(appWindow);
|
||||
});
|
||||
this.unListenConfigStart = [unListen, unListen2];
|
||||
},
|
||||
async listenStartStopServer() {
|
||||
@@ -894,9 +947,11 @@
|
||||
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) {
|
||||
const guiJsonStrUint8 = await readFile(path, { baseDir: BaseDirectory.Resource });
|
||||
if (guiJsonStrUint8) {
|
||||
try {
|
||||
const decoder = new TextDecoder("utf-8");
|
||||
const guiJsonStr = decoder.decode(guiJsonStrUint8);
|
||||
const regex = /^(\s*\/\/.*)/gm;
|
||||
const regex2 = /(,?)\s*\/\/.*(?=\n|$|\r\n)/gm;
|
||||
const resultStr = guiJsonStr.replace(regex, "").replace(regex2, "$1");
|
||||
@@ -926,16 +981,16 @@
|
||||
}
|
||||
} catch (err) {
|
||||
console.error(err);
|
||||
ElMessage.error(`config.json格式错误`);
|
||||
ElMessage.error(`config.json格式或编码错误`);
|
||||
} finally {
|
||||
mainStore.$patch({
|
||||
createConfigInEasytier: true // 发现本地存在config.json 默认启用该功能
|
||||
});
|
||||
// mainStore.$patch({
|
||||
// createConfigInEasytier: true // 发现本地存在config.json 默认启用该功能
|
||||
// });
|
||||
}
|
||||
}
|
||||
}
|
||||
const b = bounce(600);
|
||||
mainStore.$subscribe((...a) => {
|
||||
mainStore.$subscribe(async (...a) => {
|
||||
if (mainStore.createConfigInEasytier) {
|
||||
b(async () => {
|
||||
await updateConfigJson(data.configJsonSeverUrl);
|
||||
@@ -960,9 +1015,9 @@
|
||||
|
||||
const initPreventSleep = async () => {
|
||||
if (mainStore.config.enablePreventSleep) {
|
||||
preventSleep();
|
||||
preventSleep();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
const mountedShow = async () => {
|
||||
const args = await getMatches();
|
||||
@@ -975,6 +1030,7 @@
|
||||
|
||||
let logsTimer: NodeJS.Timeout | null = null;
|
||||
let serverLogsTimer: NodeJS.Timeout | null = null;
|
||||
let cidrTimer: NodeJS.Timeout | null = null;
|
||||
|
||||
onMounted(async () => {
|
||||
await initGuiJson();
|
||||
@@ -993,6 +1049,7 @@
|
||||
mountedShow(); // 不需要await
|
||||
closePrevent();
|
||||
data.hasNewVersion = await checkNewVersion();
|
||||
|
||||
});
|
||||
|
||||
onBeforeUnmount(() => {
|
||||
@@ -1003,6 +1060,7 @@
|
||||
listenObj.unListenStartStopServer && listenObj.unListenStartStopServer();
|
||||
logsTimer && clearInterval(logsTimer);
|
||||
serverLogsTimer && clearInterval(serverLogsTimer);
|
||||
cidrTimer && clearInterval(cidrTimer);
|
||||
stopPreventSleep();
|
||||
});
|
||||
|
||||
@@ -1049,13 +1107,13 @@
|
||||
args.push("--network-secret", config.networkPassword);
|
||||
}
|
||||
if (config.ipv4) {
|
||||
args.push("--ipv4", config.ipv4);
|
||||
args.push("--ipv4", config.ipv4.trim());
|
||||
}
|
||||
if (config.serverUrl) {
|
||||
const formatUrl = config.serverUrl.replace(/\\/g, "/");
|
||||
args.push("--peers", ...config.protocol.map(protocol => `${protocol}://${formatUrl}`));
|
||||
}
|
||||
if (config.enableCustonProtocol) {
|
||||
if (config.enableCustomProtocol) {
|
||||
const includes = config.protocol.includes(config.customProtocol);
|
||||
if (includes) {
|
||||
args.push("--default-protocol", config.customProtocol);
|
||||
@@ -1080,17 +1138,22 @@
|
||||
args.push("-l", ...customListener);
|
||||
}
|
||||
}
|
||||
if (!config.disbleListenner && config.enableCustomListenerV6 && config.customListenerV6Data) {
|
||||
args.push("--ipv6-listener", config.customListenerV6Data);
|
||||
}
|
||||
if (!config.disbleListenner && !config.enableCustomListener && config.port) {
|
||||
args.push("-l", config.port);
|
||||
}
|
||||
if (mainStore.cidrEnable && config.proxyNetworks) {
|
||||
// console.error(config.proxyNetworks);
|
||||
const reg = /\d+\.\d+\.\d+\.\d+\/\d+/g;
|
||||
const formatProxyNetworks = config.proxyNetworks
|
||||
.split("\n")
|
||||
.map(item => item.trim())
|
||||
.filter(item => item && reg.test(item));
|
||||
args.push("--proxy-networks", ...formatProxyNetworks);
|
||||
let formatProxyNetworks = config.proxyNetworks.trim().split("\n");
|
||||
const newformatProxyNetworks = formatProxyNetworks
|
||||
.map(el => el.trim())
|
||||
.filter(cidr => {
|
||||
return /^\d+\.\d+\.\d+\.\d+\/\d+$/g.test(cidr);
|
||||
});
|
||||
if (newformatProxyNetworks.length > 0) {
|
||||
args.push("--proxy-networks", ...newformatProxyNetworks);
|
||||
}
|
||||
config.proxyNetworks = formatProxyNetworks.join("\n");
|
||||
}
|
||||
if (config.disableEncryption) {
|
||||
@@ -1123,6 +1186,9 @@
|
||||
if (config.devName && config.devNameValue) {
|
||||
args.push("--dev-name", config.devNameValue);
|
||||
}
|
||||
if (config.compression && config.compression != "none") {
|
||||
args.push("--compression", config.compression);
|
||||
}
|
||||
return args;
|
||||
};
|
||||
|
||||
@@ -1168,7 +1234,6 @@
|
||||
data.startLoading = true;
|
||||
await unListenAll();
|
||||
await listenObj.listenOutput();
|
||||
|
||||
await invoke("run_command", {
|
||||
args
|
||||
});
|
||||
@@ -1200,25 +1265,78 @@
|
||||
if (command === "share_config") {
|
||||
try {
|
||||
const {
|
||||
proxyNetworks,
|
||||
autoStart,
|
||||
connectAfterStart,
|
||||
protocol,
|
||||
serverUrl,
|
||||
networkName,
|
||||
networkPassword,
|
||||
dhcp,
|
||||
disableIpv6,
|
||||
disbleP2p,
|
||||
enableCustomProtocol,
|
||||
customProtocol,
|
||||
disbleListenner,
|
||||
port,
|
||||
enableCustomListener,
|
||||
customListenerData,
|
||||
enableCustomListenerV6,
|
||||
customListenerV6Data,
|
||||
devName,
|
||||
devNameValue,
|
||||
enableNetCardMetric,
|
||||
netCardMetricValue,
|
||||
disableEncryption,
|
||||
multiThread,
|
||||
hostname,
|
||||
enablExitNode,
|
||||
useSmoltcp,
|
||||
saveErrorLog,
|
||||
logLevel,
|
||||
ipv4,
|
||||
...otherConfig
|
||||
latencyfirst,
|
||||
disableUdpHolePunching,
|
||||
relayAllPeerrpc,
|
||||
compression,
|
||||
enablePreventSleep,
|
||||
} = mainStore.config;
|
||||
const WT = btoa(encodeURIComponent(JSON.stringify({ config: otherConfig })));
|
||||
const WT = btoa(
|
||||
encodeURIComponent(
|
||||
JSON.stringify({
|
||||
config: {
|
||||
protocol,
|
||||
serverUrl,
|
||||
networkName,
|
||||
networkPassword,
|
||||
dhcp,
|
||||
disableIpv6,
|
||||
disbleP2p,
|
||||
enableCustomProtocol,
|
||||
customProtocol,
|
||||
disbleListenner,
|
||||
port,
|
||||
enableCustomListener,
|
||||
customListenerData,
|
||||
enableCustomListenerV6,
|
||||
customListenerV6Data,
|
||||
devName,
|
||||
devNameValue,
|
||||
enableNetCardMetric,
|
||||
netCardMetricValue,
|
||||
disableEncryption,
|
||||
multiThread,
|
||||
latencyfirst,
|
||||
disableUdpHolePunching,
|
||||
relayAllPeerrpc,
|
||||
compression,
|
||||
enablePreventSleep
|
||||
}
|
||||
})
|
||||
)
|
||||
);
|
||||
await writeText(WT);
|
||||
ElMessage.success("配置已复制");
|
||||
} catch (err) {
|
||||
console.error(err);
|
||||
ElMessage.error("分享失败");
|
||||
}
|
||||
ElConfirmPrimary(`{action} 虚拟网IP,主机名,子网代理,为子网代理启用smoltcp堆栈,开机自启,软件启动自动联机,出口节点,不生成Tun网卡,错误日志相关配置`, "提示", {
|
||||
confirmButtonText: "知道了",
|
||||
showCancelButton: false,
|
||||
action: "不会分享"
|
||||
});
|
||||
}
|
||||
if (command === "import_config") {
|
||||
importConfigData.data = "";
|
||||
@@ -1236,6 +1354,7 @@
|
||||
});
|
||||
if (!err) {
|
||||
const payload = JSON.parse(decodeURIComponent(atob(importConfigData.data)));
|
||||
payload.config.serverUrl = payload?.config?.serverUrl?.trim() || config.serverUrl;
|
||||
mainStore.$patch({
|
||||
config: {
|
||||
...mainStore.config,
|
||||
@@ -1244,7 +1363,7 @@
|
||||
});
|
||||
ElMessage.success("导入成功");
|
||||
importConfigData.visible = false;
|
||||
mainStore.basePeers = uniq([config.serverUrl, ...mainStore.basePeers]);
|
||||
mainStore.basePeers = uniq([config.serverUrl, ...mainStore.basePeers].filter(el => el.trim()));
|
||||
} else {
|
||||
console.error(err);
|
||||
if (err !== "cancel") {
|
||||
@@ -1335,8 +1454,13 @@
|
||||
},
|
||||
(_, appWindow) => {
|
||||
data.cidrVisible = true;
|
||||
cidrTimer && clearInterval(cidrTimer);
|
||||
cidrTimer = setInterval(() => {
|
||||
appWindow.emitTo({ kind: "WebviewWindow", label: "cidr" }, "route", data.isStart);
|
||||
}, 1000);
|
||||
},
|
||||
() => {
|
||||
cidrTimer && clearInterval(cidrTimer);
|
||||
data.cidrVisible = false;
|
||||
}
|
||||
);
|
||||
|
||||
+2
-2
@@ -16,8 +16,8 @@
|
||||
});
|
||||
|
||||
const listenStart = async () => {
|
||||
const unListen = await listen("logs", event => {
|
||||
data.log = (event.payload as string) || "";
|
||||
const unListen = await listen<string>("logs", event => {
|
||||
data.log = event.payload || "";
|
||||
});
|
||||
return unListen;
|
||||
};
|
||||
|
||||
+21
-12
@@ -1,7 +1,12 @@
|
||||
<template>
|
||||
<div class="overflow-auto h-full">
|
||||
<div class="h-full overflow-auto">
|
||||
<div class="w-[1200px]">
|
||||
<ElText size="small" v-if="!data.member || data.member.length <= 0">{{ "等待成员信息中..." }}</ElText>
|
||||
<ElText
|
||||
size="small"
|
||||
v-if="!data.member || data.member.length <= 0"
|
||||
>
|
||||
{{ "等待成员信息中..." }}
|
||||
</ElText>
|
||||
<ElTable
|
||||
stripe
|
||||
border
|
||||
@@ -14,8 +19,12 @@
|
||||
label="主机名"
|
||||
prop="hostname"
|
||||
>
|
||||
<template #default="{row}">
|
||||
{{ (row.hostname || "").toLowerCase().includes('publicserver') ? (row.hostname || "").replace("PublicServer", "服务器") : (row.hostname || "-") }}
|
||||
<template #default="{ row }">
|
||||
{{
|
||||
(row.hostname || "").toLowerCase().includes("publicserver")
|
||||
? (row.hostname || "").replace("PublicServer", "服务器")
|
||||
: row.hostname || "-"
|
||||
}}
|
||||
</template>
|
||||
</ElTableColumn>
|
||||
<ElTableColumn
|
||||
@@ -30,7 +39,7 @@
|
||||
effect="dark"
|
||||
:type="row.cost == 'p2p' ? 'success' : 'info'"
|
||||
>
|
||||
{{ row.cost }}
|
||||
{{ row.cost ? row.cost.replace("relay", "中转") : row.cost }}
|
||||
</ElTag>
|
||||
</template>
|
||||
</ElTableColumn>
|
||||
@@ -96,9 +105,9 @@
|
||||
<script setup lang="ts">
|
||||
import { invoke } from "@tauri-apps/api/core";
|
||||
import { reactive, onMounted, onBeforeUnmount } from "vue";
|
||||
import { ATJ, parsePeerInfo } from "@/utils";
|
||||
import { ATJ, parseCliInfo } from "@/utils";
|
||||
import { ElConfirmDanger } from "~/utils/element";
|
||||
import { getCurrentWindow } from "@tauri-apps/api/window";
|
||||
import { getCurrentWindow } from "@tauri-apps/api/window";
|
||||
// enum NatType {
|
||||
// // has NAT; but own a single public IP, port is not changed
|
||||
// Unknown = 0;
|
||||
@@ -126,7 +135,7 @@ import { getCurrentWindow } from "@tauri-apps/api/window";
|
||||
};
|
||||
type natKyes = keyof typeof natMaps;
|
||||
|
||||
const data = reactive<{ member: {hostname: string, cost: string, ipv4: string, lat_msg: string, loss_rate: string, nat_type: string}[] }>({
|
||||
const data = reactive<{ member: { hostname: string; cost: string; ipv4: string; lat_msg: string; loss_rate: string; nat_type: string }[] }>({
|
||||
member: []
|
||||
});
|
||||
|
||||
@@ -139,8 +148,8 @@ import { getCurrentWindow } from "@tauri-apps/api/window";
|
||||
["nat_type", "NAT类型"],
|
||||
["version", "版本"],
|
||||
["tunnel_proto", "隧道协议"],
|
||||
['rx_bytes', '接收'],
|
||||
['tx_bytes', '传输']
|
||||
["rx_bytes", "接收"],
|
||||
["tx_bytes", "传输"]
|
||||
];
|
||||
|
||||
let timer: NodeJS.Timeout | null = null;
|
||||
@@ -167,7 +176,7 @@ import { getCurrentWindow } from "@tauri-apps/api/window";
|
||||
}
|
||||
return;
|
||||
}
|
||||
const peerInfo = parsePeerInfo(member);
|
||||
const peerInfo = parseCliInfo(member);
|
||||
peerInfo.forEach(value => {
|
||||
if (value.cost === "Local") {
|
||||
value.cost = "本机";
|
||||
@@ -191,7 +200,7 @@ import { getCurrentWindow } from "@tauri-apps/api/window";
|
||||
const stopTimer = () => {
|
||||
timer && clearTimeout(timer);
|
||||
timer = null;
|
||||
}
|
||||
};
|
||||
|
||||
onMounted(async () => {
|
||||
await listenOutput();
|
||||
|
||||
+163
-9
@@ -8,7 +8,7 @@
|
||||
<ElTabPane
|
||||
label="联机失败解决办法"
|
||||
name="netcard"
|
||||
class="flex flex-col h-full"
|
||||
class="flex h-full flex-col"
|
||||
>
|
||||
<div>
|
||||
<div>
|
||||
@@ -23,7 +23,7 @@
|
||||
</ElTooltip>
|
||||
</div>
|
||||
<ElLink
|
||||
class="!text-[15px] mr-[10px]"
|
||||
class="mr-[10px] !text-[15px]"
|
||||
type="info"
|
||||
:underline="false"
|
||||
@click="open('https://github.com/dechamps/WinIPBroadcast/releases/tag/winipbroadcast-1.6')"
|
||||
@@ -41,14 +41,102 @@
|
||||
></ElSwitch>
|
||||
</div>
|
||||
<div>
|
||||
<ElTooltip content="设置网卡的跃点,提升网卡优先级,尝试将您联机使用的网卡跃点设置为最小,请先查询网卡信息">
|
||||
<ElTooltip
|
||||
content="使用ForceBindIP启动应用 (强制绑定IP或者网卡),如果还有没启动联机,请先启动联机,联机成功后,点击刷新获取easytier生成的网卡"
|
||||
>
|
||||
<ElText>
|
||||
方案2
|
||||
<ElIcon class="ml-[3px]"><QuestionFilled /></ElIcon>
|
||||
</ElText>
|
||||
</ElTooltip>
|
||||
</div>
|
||||
<div class="flex items-center mt-[5px]">
|
||||
<div>
|
||||
<div>
|
||||
<ElLink
|
||||
class="!text-[15px]"
|
||||
type="info"
|
||||
:underline="false"
|
||||
@click="open('https://r1ch.net/projects/forcebindip')"
|
||||
>
|
||||
ForceBindIP
|
||||
</ElLink>
|
||||
</div>
|
||||
<div>
|
||||
<ElRadioGroup
|
||||
class="mr-[30px]"
|
||||
v-model="mainStore.forceBindIpBit"
|
||||
>
|
||||
<ElRadio
|
||||
label="32位"
|
||||
value="32"
|
||||
></ElRadio>
|
||||
<ElRadio
|
||||
label="64位"
|
||||
value="64"
|
||||
></ElRadio>
|
||||
</ElRadioGroup>
|
||||
<ElTooltip
|
||||
placement="top"
|
||||
content="如果目标应用程序在启动时崩溃或出现其他意外行为,请尝试开启它,ForceBindIP 加载程序将等待应用程序进入其消息循环后再注入拦截 DLL"
|
||||
>
|
||||
<ElCheckbox
|
||||
v-model="mainStore.delayInjectDll"
|
||||
label="延迟注入DLL"
|
||||
></ElCheckbox>
|
||||
</ElTooltip>
|
||||
</div>
|
||||
<div class="flex items-center gap-[5px]">
|
||||
<ElSelect
|
||||
placeholder="请输入IP地址或选择网卡"
|
||||
v-model="mainStore.forceBindInput"
|
||||
filterable
|
||||
allow-create
|
||||
no-data-text="暂无网卡数据,请尝试刷新"
|
||||
>
|
||||
<ElOption
|
||||
v-for="guid in data.guids"
|
||||
:key="guid[0]"
|
||||
:label="guid[1]"
|
||||
:value="guid[0]"
|
||||
></ElOption>
|
||||
</ElSelect>
|
||||
<ElButton @click="getGuids">刷新</ElButton>
|
||||
</div>
|
||||
<div class="mt-[5px] flex items-center gap-[5px]">
|
||||
<ElInput
|
||||
placeholder="请选择或输入应用程序路径"
|
||||
:disabled="data.forceBindStart"
|
||||
v-model="mainStore.forceBindFile"
|
||||
></ElInput>
|
||||
<div class="flex items-center">
|
||||
<ElButton
|
||||
@click="handleBrowser"
|
||||
:disabled="data.forceBindStart"
|
||||
>
|
||||
浏览
|
||||
</ElButton>
|
||||
<ElButton
|
||||
:disabled="data.forceBindStart"
|
||||
@click="startForceBindIp"
|
||||
type="primary"
|
||||
>
|
||||
启动
|
||||
</ElButton>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<!-- const guids = await invoke<string[]>("get_network_adapter_guids"); -->
|
||||
</div>
|
||||
<div>
|
||||
<ElTooltip content="设置网卡的跃点,提升网卡优先级,尝试将您联机使用的网卡跃点设置为最小,请先查询网卡信息">
|
||||
<ElText>
|
||||
方案3
|
||||
<ElIcon class="ml-[3px]"><QuestionFilled /></ElIcon>
|
||||
</ElText>
|
||||
</ElTooltip>
|
||||
</div>
|
||||
<div class="mt-[5px] flex items-center">
|
||||
<ElButton
|
||||
@click="initNetCardInfo"
|
||||
size="small"
|
||||
@@ -58,7 +146,7 @@
|
||||
</ElButton>
|
||||
<div
|
||||
v-if="data.row.name"
|
||||
class="ml-auto flex items-center flex-nowrap gap-[10px]"
|
||||
class="ml-auto flex flex-nowrap items-center gap-[10px]"
|
||||
>
|
||||
<ElTooltip content="跃点越小,网卡优先级越高,范围(1-9999)">
|
||||
<ElInput
|
||||
@@ -78,7 +166,7 @@
|
||||
</ElButton>
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex-1 overflow-auto mt-[5px]">
|
||||
<div class="mt-[5px] flex-1 overflow-auto">
|
||||
<ElTable
|
||||
height="100%"
|
||||
empty-text="暂无数据"
|
||||
@@ -103,7 +191,7 @@
|
||||
<ElTabPane
|
||||
label="防火墙"
|
||||
name="firewall"
|
||||
class="flex flex-col h-full"
|
||||
class="flex h-full flex-col"
|
||||
>
|
||||
<div class="flex flex-col items-center">
|
||||
<div class="mb-[10px]">
|
||||
@@ -176,6 +264,7 @@
|
||||
</template>
|
||||
<script setup lang="ts">
|
||||
import { open, Command } from "@tauri-apps/plugin-shell";
|
||||
import { open as dialogOpen } from "@tauri-apps/plugin-dialog";
|
||||
import { ElMessage, type TabPaneName } from "element-plus";
|
||||
import { QuestionFilled } from "@element-plus/icons-vue";
|
||||
import { onMounted, reactive } from "vue";
|
||||
@@ -183,9 +272,11 @@
|
||||
import { handleWinipBcStart, initStartWinIpBroadcast } from "@/composables/netcard";
|
||||
import { isValidIP } from "~/utils";
|
||||
import { dataSubscribe } from "~/composables/windows";
|
||||
import { invoke } from "@tauri-apps/api/core";
|
||||
import { BaseDirectory, exists } from "@tauri-apps/plugin-fs";
|
||||
|
||||
const mainStore = useMainStore();
|
||||
const data = reactive({
|
||||
const data = reactive<{ guids: string[][]; [key: string]: any }>({
|
||||
activeTab: "netcard",
|
||||
winipBcPid: 0,
|
||||
pingNum: 1,
|
||||
@@ -202,7 +293,9 @@
|
||||
name: "",
|
||||
metric: ""
|
||||
},
|
||||
netcardList: []
|
||||
netcardList: [],
|
||||
guids: [],
|
||||
forceBindStart: false
|
||||
});
|
||||
|
||||
const handleTabsChange = async (tabPaneName: TabPaneName) => {
|
||||
@@ -328,17 +421,78 @@
|
||||
}
|
||||
};
|
||||
|
||||
const handleBrowser = async () => {
|
||||
const file = await dialogOpen({
|
||||
multiple: false,
|
||||
directory: false
|
||||
});
|
||||
if (file) {
|
||||
mainStore.forceBindFile = file;
|
||||
} else {
|
||||
ElMessage.error("获取文件路径失败");
|
||||
}
|
||||
};
|
||||
|
||||
const startForceBindIp = async () => {
|
||||
if (!mainStore.forceBindInput) {
|
||||
return ElMessage.error("请输入IP地址或者选择一个网卡");
|
||||
}
|
||||
if (!mainStore.forceBindFile) {
|
||||
return ElMessage.error("请选择一个执行文件");
|
||||
}
|
||||
|
||||
const forceBindIpExe = mainStore.forceBindIpBit == "32" ? "ForceBindIP" : "ForceBindIP64";
|
||||
const isExists = await exists(`easytier/tool/${forceBindIpExe}.exe`, { baseDir: BaseDirectory.Resource });
|
||||
if (!isExists) {
|
||||
return ElMessage.error("forcebindIP文件不存在");
|
||||
}
|
||||
|
||||
data.forceBindStart = true;
|
||||
try {
|
||||
const dealyDll = mainStore.delayInjectDll ? "-i" : "";
|
||||
const child = await Command.create(
|
||||
forceBindIpExe,
|
||||
[dealyDll, mainStore.forceBindInput, mainStore.forceBindFile.replace(/\//g, "\\")].filter(el => el),
|
||||
{
|
||||
encoding: "gb2312"
|
||||
}
|
||||
).spawn();
|
||||
// console.log({child});
|
||||
} catch (err) {
|
||||
ElMessage.error("forcebindIP启动发生未知错误");
|
||||
console.error(err);
|
||||
} finally {
|
||||
data.forceBindStart = false;
|
||||
}
|
||||
};
|
||||
|
||||
dataSubscribe(async (...a) => {
|
||||
return {
|
||||
winIpBcAutoStart: mainStore.winIpBcAutoStart,
|
||||
winipBcStart: mainStore.winipBcStart,
|
||||
winipBcPid: mainStore.winipBcPid,
|
||||
forceBindIpBit: mainStore.forceBindIpBit,
|
||||
delayInjectDll: mainStore.delayInjectDll,
|
||||
forceBindInput: mainStore.forceBindInput,
|
||||
forceBindFile: mainStore.forceBindFile,
|
||||
config: { ...mainStore.config }
|
||||
};
|
||||
});
|
||||
|
||||
const getGuids = async () => {
|
||||
const guids = await invoke<string[][]>("get_network_adapter_guids");
|
||||
data.guids = guids && guids.length > 0 ? guids : [];
|
||||
if (mainStore.forceBindInput.startsWith("{")) {
|
||||
const has = data.guids.find(el => el[0] == mainStore.forceBindInput);
|
||||
if (!has) {
|
||||
mainStore.forceBindInput = "";
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
onMounted(() => {
|
||||
data.pingIp = mainStore.config.ipv4;
|
||||
initStartWinIpBroadcast();
|
||||
getGuids();
|
||||
});
|
||||
</script>
|
||||
|
||||
Generated
+757
-806
File diff suppressed because it is too large
Load Diff
Generated
+182
-22
@@ -183,6 +183,27 @@ version = "0.7.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7c02d123df017efcdfbd739ef81735b36c5ba83ec3c59c80a9d7ecc718f92e50"
|
||||
|
||||
[[package]]
|
||||
name = "ashpd"
|
||||
version = "0.9.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4d43c03d9e36dd40cab48435be0b09646da362c278223ca535493877b2c1dee9"
|
||||
dependencies = [
|
||||
"enumflags2",
|
||||
"futures-channel",
|
||||
"futures-util",
|
||||
"rand 0.8.5",
|
||||
"raw-window-handle",
|
||||
"serde",
|
||||
"serde_repr",
|
||||
"tokio",
|
||||
"url",
|
||||
"wayland-backend",
|
||||
"wayland-client",
|
||||
"wayland-protocols",
|
||||
"zbus",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "async-broadcast"
|
||||
version = "0.7.1"
|
||||
@@ -1166,6 +1187,15 @@ dependencies = [
|
||||
"syn 2.0.87",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "dlib"
|
||||
version = "0.5.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "330c60081dcc4c72131f8eb70510f1ac07223e5d4163db481a04a0befcffa412"
|
||||
dependencies = [
|
||||
"libloading",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "dlopen2"
|
||||
version = "0.7.0"
|
||||
@@ -1189,6 +1219,12 @@ dependencies = [
|
||||
"syn 2.0.87",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "downcast-rs"
|
||||
version = "1.2.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "75b325c5dbd37f80359721ad39aca5a29fb04c89279657cffdda8736d0c0b9d2"
|
||||
|
||||
[[package]]
|
||||
name = "dpi"
|
||||
version = "0.1.1"
|
||||
@@ -1227,10 +1263,11 @@ checksum = "0d6ef0072f8a535281e4876be788938b528e9a1d43900b82c2569af7da799125"
|
||||
|
||||
[[package]]
|
||||
name = "easytier-game"
|
||||
version = "1.3.1"
|
||||
version = "1.3.5"
|
||||
dependencies = [
|
||||
"log",
|
||||
"planif",
|
||||
"rand 0.8.5",
|
||||
"reqwest",
|
||||
"serde",
|
||||
"serde_json",
|
||||
@@ -1239,6 +1276,7 @@ dependencies = [
|
||||
"tauri-build",
|
||||
"tauri-plugin-cli",
|
||||
"tauri-plugin-clipboard-manager",
|
||||
"tauri-plugin-dialog",
|
||||
"tauri-plugin-fs",
|
||||
"tauri-plugin-log",
|
||||
"tauri-plugin-shell",
|
||||
@@ -2787,6 +2825,7 @@ checksum = "0ee638a5da3799329310ad4cfa62fbf045d5f56e3ef5ba4149e7452dcf89d5a8"
|
||||
dependencies = [
|
||||
"bitflags 2.6.0",
|
||||
"block2",
|
||||
"dispatch",
|
||||
"libc",
|
||||
"objc2",
|
||||
]
|
||||
@@ -3247,7 +3286,7 @@ checksum = "42cf17e9a1800f5f396bc67d193dc9411b59012a5876445ef450d449881e1016"
|
||||
dependencies = [
|
||||
"base64 0.22.1",
|
||||
"indexmap 2.6.0",
|
||||
"quick-xml",
|
||||
"quick-xml 0.32.0",
|
||||
"serde",
|
||||
"time",
|
||||
]
|
||||
@@ -3389,6 +3428,15 @@ dependencies = [
|
||||
"memchr",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "quick-xml"
|
||||
version = "0.36.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f7649a7b4df05aed9ea7ec6f628c67c9953a43869b8bc50929569b2999d443fe"
|
||||
dependencies = [
|
||||
"memchr",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "quote"
|
||||
version = "1.0.37"
|
||||
@@ -3614,6 +3662,29 @@ dependencies = [
|
||||
"windows-registry",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rfd"
|
||||
version = "0.15.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8af382a047821a08aa6bfc09ab0d80ff48d45d8726f7cd8e44891f7cb4a4278e"
|
||||
dependencies = [
|
||||
"ashpd",
|
||||
"block2",
|
||||
"glib-sys",
|
||||
"gobject-sys",
|
||||
"gtk-sys",
|
||||
"js-sys",
|
||||
"log",
|
||||
"objc2",
|
||||
"objc2-app-kit",
|
||||
"objc2-foundation",
|
||||
"raw-window-handle",
|
||||
"wasm-bindgen",
|
||||
"wasm-bindgen-futures",
|
||||
"web-sys",
|
||||
"windows-sys 0.48.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ring"
|
||||
version = "0.17.8"
|
||||
@@ -3792,6 +3863,12 @@ dependencies = [
|
||||
"syn 2.0.87",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "scoped-tls"
|
||||
version = "1.0.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e1cf6437eb19a8f4a6cc0f7dca544973b0b78843adbfeb3683d1a94a0024a294"
|
||||
|
||||
[[package]]
|
||||
name = "scopeguard"
|
||||
version = "1.2.0"
|
||||
@@ -4495,9 +4572,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "tauri-plugin-cli"
|
||||
version = "2.0.1"
|
||||
version = "2.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2bccd4692b56822a60874542c7655546c8e7aed3c2e2926166e1498e595bd2a2"
|
||||
checksum = "e5458ae16eac81bdbe8d9da2a9f3e01e8cdedbc381cc1727c01127542c8a61c5"
|
||||
dependencies = [
|
||||
"clap",
|
||||
"log",
|
||||
@@ -4505,7 +4582,7 @@ dependencies = [
|
||||
"serde_json",
|
||||
"tauri",
|
||||
"tauri-plugin",
|
||||
"thiserror 1.0.64",
|
||||
"thiserror 2.0.3",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -4524,10 +4601,28 @@ dependencies = [
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tauri-plugin-fs"
|
||||
version = "2.0.3"
|
||||
name = "tauri-plugin-dialog"
|
||||
version = "2.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "96ba7d46e86db8c830d143ef90ab5a453328365b0cc834c24edea4267b16aba0"
|
||||
checksum = "8b59fd750551b1066744ab956a1cd6b1ea3e1b3763b0b9153ac27a044d596426"
|
||||
dependencies = [
|
||||
"log",
|
||||
"raw-window-handle",
|
||||
"rfd",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"tauri",
|
||||
"tauri-plugin",
|
||||
"tauri-plugin-fs",
|
||||
"thiserror 2.0.3",
|
||||
"url",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tauri-plugin-fs"
|
||||
version = "2.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a1a1edf18000f02903a7c2e5997fb89aca455ecbc0acc15c6535afbb883be223"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"dunce",
|
||||
@@ -4539,16 +4634,18 @@ dependencies = [
|
||||
"serde_repr",
|
||||
"tauri",
|
||||
"tauri-plugin",
|
||||
"thiserror 1.0.64",
|
||||
"tauri-utils",
|
||||
"thiserror 2.0.3",
|
||||
"toml 0.8.2",
|
||||
"url",
|
||||
"uuid",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tauri-plugin-log"
|
||||
version = "2.0.2"
|
||||
version = "2.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8aa13d15daf90230ba26d5a9b4a4612975fa64ce17290cb7f6e0f89bb6997d82"
|
||||
checksum = "eddd784c138c08a43954bc3e735402e6b2b2ee8d8c254a7391f4e77c01273dd5"
|
||||
dependencies = [
|
||||
"android_logger",
|
||||
"byte-unit",
|
||||
@@ -4562,15 +4659,15 @@ dependencies = [
|
||||
"swift-rs",
|
||||
"tauri",
|
||||
"tauri-plugin",
|
||||
"thiserror 1.0.64",
|
||||
"thiserror 2.0.3",
|
||||
"time",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tauri-plugin-shell"
|
||||
version = "2.0.2"
|
||||
version = "2.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0ad7880c5586b6b2104be451e3d7fc0f3800c84bda69e9ba81c828f87cb34267"
|
||||
checksum = "bb2c50a63e60fb8925956cc5b7569f4b750ac197a4d39f13b8dd46ea8e2bad79"
|
||||
dependencies = [
|
||||
"encoding_rs",
|
||||
"log",
|
||||
@@ -4583,30 +4680,30 @@ dependencies = [
|
||||
"shared_child",
|
||||
"tauri",
|
||||
"tauri-plugin",
|
||||
"thiserror 1.0.64",
|
||||
"thiserror 2.0.3",
|
||||
"tokio",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tauri-plugin-single-instance"
|
||||
version = "2.0.1"
|
||||
version = "2.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a25ac834491d089699a2bc9266a662faf373c9f779f05a2235bc6e4d9e61769a"
|
||||
checksum = "0f36019ee9832dc99e4450bb55a21cfad8633b19c2c18bd17c7741939b070ede"
|
||||
dependencies = [
|
||||
"log",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"tauri",
|
||||
"thiserror 1.0.64",
|
||||
"thiserror 2.0.3",
|
||||
"tracing",
|
||||
"windows-sys 0.59.0",
|
||||
"zbus",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tauri-plugin-window-state"
|
||||
version = "2.0.2"
|
||||
version = "2.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "683c8764751fbbcebf3a594bcee24cf84c62773fa0080d1b40fc80698472421e"
|
||||
checksum = "234dd891cc7960fa28f93ea911f3e0d9ce8375ebf9ff303831bdd7a3443d5714"
|
||||
dependencies = [
|
||||
"bitflags 2.6.0",
|
||||
"log",
|
||||
@@ -4614,7 +4711,7 @@ dependencies = [
|
||||
"serde_json",
|
||||
"tauri",
|
||||
"tauri-plugin",
|
||||
"thiserror 1.0.64",
|
||||
"thiserror 2.0.3",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -4851,6 +4948,7 @@ dependencies = [
|
||||
"pin-project-lite",
|
||||
"signal-hook-registry",
|
||||
"socket2",
|
||||
"tracing",
|
||||
"windows-sys 0.52.0",
|
||||
]
|
||||
|
||||
@@ -5321,6 +5419,66 @@ dependencies = [
|
||||
"web-sys",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wayland-backend"
|
||||
version = "0.3.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "056535ced7a150d45159d3a8dc30f91a2e2d588ca0b23f70e56033622b8016f6"
|
||||
dependencies = [
|
||||
"cc",
|
||||
"downcast-rs",
|
||||
"rustix",
|
||||
"scoped-tls",
|
||||
"smallvec",
|
||||
"wayland-sys",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wayland-client"
|
||||
version = "0.31.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b66249d3fc69f76fd74c82cc319300faa554e9d865dab1f7cd66cc20db10b280"
|
||||
dependencies = [
|
||||
"bitflags 2.6.0",
|
||||
"rustix",
|
||||
"wayland-backend",
|
||||
"wayland-scanner",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wayland-protocols"
|
||||
version = "0.32.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7cd0ade57c4e6e9a8952741325c30bf82f4246885dca8bf561898b86d0c1f58e"
|
||||
dependencies = [
|
||||
"bitflags 2.6.0",
|
||||
"wayland-backend",
|
||||
"wayland-client",
|
||||
"wayland-scanner",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wayland-scanner"
|
||||
version = "0.31.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "597f2001b2e5fc1121e3d5b9791d3e78f05ba6bfa4641053846248e3a13661c3"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quick-xml 0.36.2",
|
||||
"quote",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wayland-sys"
|
||||
version = "0.31.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "efa8ac0d8e8ed3e3b5c9fc92c7881406a268e11555abe36493efabe649a29e09"
|
||||
dependencies = [
|
||||
"dlib",
|
||||
"log",
|
||||
"pkg-config",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "web-sys"
|
||||
version = "0.3.70"
|
||||
@@ -5991,6 +6149,7 @@ dependencies = [
|
||||
"serde_repr",
|
||||
"sha1",
|
||||
"static_assertions",
|
||||
"tokio",
|
||||
"tracing",
|
||||
"uds_windows",
|
||||
"windows-sys 0.52.0",
|
||||
@@ -6147,6 +6306,7 @@ dependencies = [
|
||||
"enumflags2",
|
||||
"serde",
|
||||
"static_assertions",
|
||||
"url",
|
||||
"zvariant_derive",
|
||||
]
|
||||
|
||||
|
||||
+10
-8
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "easytier-game"
|
||||
version = "1.3.1"
|
||||
version = "1.3.5"
|
||||
homepage = "https://github.com/EasyTier/EasyTier"
|
||||
repository = "https://github.com/EasyTier/EasytierGame"
|
||||
description = "A simple network initiator based on Easytier"
|
||||
@@ -31,25 +31,27 @@ tauri = { version = "2.1.1", features = [
|
||||
"image-ico",
|
||||
] }
|
||||
|
||||
tauri-plugin-log = "2.0.2"
|
||||
tauri-plugin-shell = "2.0.2"
|
||||
tauri-plugin-log = "2.2.0"
|
||||
tauri-plugin-shell = "2.2.0"
|
||||
reqwest = { version = "0.12", features = ["json"] }
|
||||
zip = "2.2"
|
||||
sysinfo = '0.32.0'
|
||||
planif = { git = "https://github.com/mattrobineau/planif", tag = "1.0.1" }
|
||||
whoami = "1.5.2"
|
||||
tauri-plugin-fs = "2"
|
||||
tauri-plugin-fs = "2.2.0"
|
||||
tauri-plugin-clipboard-manager = "2.0.2"
|
||||
rand = "0.8.5"
|
||||
tokio = { version = "1.41.1", features = ["process"] }
|
||||
tauri-plugin-dialog = "2"
|
||||
# prost = "0.13"
|
||||
# prost-types = "0.13"
|
||||
|
||||
|
||||
[dependencies.windows]
|
||||
version = "0.58.0"
|
||||
features = ["Win32_System_TaskScheduler", "Win32_System_Power"]
|
||||
features = ["Win32_System_TaskScheduler", "Win32_System_Power", "Win32_NetworkManagement_IpHelper", "Win32_NetworkManagement_Ndis", "Win32_Networking_WinSock"]
|
||||
|
||||
[target."cfg(not(any(target_os = \"android\", target_os = \"ios\")))".dependencies]
|
||||
tauri-plugin-cli = "2"
|
||||
tauri-plugin-single-instance = "2.0.1"
|
||||
tauri-plugin-window-state = "2"
|
||||
tauri-plugin-cli = "2.2.0"
|
||||
tauri-plugin-single-instance = "2.2.0"
|
||||
tauri-plugin-window-state = "2.2.0"
|
||||
|
||||
+109
-103
@@ -1,104 +1,110 @@
|
||||
{
|
||||
"$schema": "../gen/schemas/desktop-schema.json",
|
||||
"identifier": "default",
|
||||
"description": "enables the default permissions",
|
||||
"windows": [
|
||||
"main",
|
||||
"log",
|
||||
"member",
|
||||
"cidr",
|
||||
"advance",
|
||||
"tool",
|
||||
"server"
|
||||
],
|
||||
"permissions": [
|
||||
"core:default",
|
||||
"core:window:allow-minimize",
|
||||
"core:window:allow-unminimize",
|
||||
"core:window:allow-hide",
|
||||
"core:window:allow-close",
|
||||
"core:window:allow-set-focus",
|
||||
"core:window:allow-is-visible",
|
||||
"shell:allow-open",
|
||||
"core:window:allow-show",
|
||||
"core:window:allow-create",
|
||||
"core:window:allow-set-position",
|
||||
"core:window:allow-destroy",
|
||||
"core:webview:allow-create-webview-window",
|
||||
"core:webview:allow-set-webview-size",
|
||||
"core:webview:allow-set-webview-position",
|
||||
"core:webview:allow-create-webview",
|
||||
"core:webview:allow-webview-show",
|
||||
"core:webview:allow-webview-hide",
|
||||
"core:webview:allow-webview-close",
|
||||
"core:tray:allow-get-by-id",
|
||||
"core:tray:allow-set-icon",
|
||||
"core:tray:allow-new",
|
||||
{
|
||||
"identifier": "shell:allow-spawn",
|
||||
"allow": [
|
||||
{
|
||||
"args": [
|
||||
"run"
|
||||
],
|
||||
"cmd": "$RESOURCE/easytier/tool/WinIPBroadcast",
|
||||
"name": "WinIPBroadcast"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"identifier": "shell:allow-execute",
|
||||
"allow": [
|
||||
{
|
||||
"args": [
|
||||
"run"
|
||||
],
|
||||
"cmd": "$RESOURCE/easytier/tool/WinIPBroadcast",
|
||||
"name": "WinIPBroadcast"
|
||||
},
|
||||
{
|
||||
"args": true,
|
||||
"cmd": "$RESOURCE/easytier/tool/nssm",
|
||||
"name": "nssm"
|
||||
},
|
||||
{
|
||||
"args": true,
|
||||
"cmd": "explorer",
|
||||
"name": "explorer"
|
||||
},
|
||||
{
|
||||
"args": true,
|
||||
"cmd": "netsh",
|
||||
"name": "netsh"
|
||||
},
|
||||
{
|
||||
"args": true,
|
||||
"cmd": "ping",
|
||||
"name": "ping"
|
||||
}
|
||||
]
|
||||
},
|
||||
"fs:default",
|
||||
"fs:allow-read-dir",
|
||||
"fs:allow-exists",
|
||||
"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",
|
||||
|
||||
"window-state:default",
|
||||
"window-state:allow-save-window-state",
|
||||
"window-state:allow-restore-state",
|
||||
|
||||
|
||||
"cli:default",
|
||||
"cli:allow-cli-matches",
|
||||
|
||||
"log:default",
|
||||
"log:allow-log"
|
||||
]
|
||||
}
|
||||
"$schema": "../gen/schemas/desktop-schema.json",
|
||||
"identifier": "default",
|
||||
"description": "enables the default permissions",
|
||||
"windows": ["main", "log", "member", "cidr", "advance", "tool", "server"],
|
||||
"permissions": [
|
||||
"core:default",
|
||||
"core:window:allow-minimize",
|
||||
"core:window:allow-unminimize",
|
||||
"core:window:allow-hide",
|
||||
"core:window:allow-close",
|
||||
"core:window:allow-set-focus",
|
||||
"core:window:allow-is-visible",
|
||||
"shell:allow-open",
|
||||
"core:window:allow-show",
|
||||
"core:window:allow-create",
|
||||
"core:window:allow-set-position",
|
||||
"core:window:allow-destroy",
|
||||
"core:webview:allow-create-webview-window",
|
||||
"core:webview:allow-set-webview-size",
|
||||
"core:webview:allow-set-webview-position",
|
||||
"core:webview:allow-create-webview",
|
||||
"core:webview:allow-webview-show",
|
||||
"core:webview:allow-webview-hide",
|
||||
"core:webview:allow-webview-close",
|
||||
"core:tray:allow-get-by-id",
|
||||
"core:tray:allow-set-icon",
|
||||
"core:tray:allow-new",
|
||||
{
|
||||
"identifier": "shell:allow-spawn",
|
||||
"allow": [
|
||||
{
|
||||
"args": ["run"],
|
||||
"cmd": "$RESOURCE/easytier/tool/WinIPBroadcast",
|
||||
"name": "WinIPBroadcast"
|
||||
},
|
||||
{
|
||||
"args": true,
|
||||
"cmd": "$RESOURCE/easytier/tool/ForceBindIP",
|
||||
"name": "ForceBindIP"
|
||||
},
|
||||
{
|
||||
"args": true,
|
||||
"cmd": "$RESOURCE/easytier/tool/ForceBindIP64",
|
||||
"name": "ForceBindIP64"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"identifier": "shell:allow-execute",
|
||||
"allow": [
|
||||
{
|
||||
"args": ["run"],
|
||||
"cmd": "$RESOURCE/easytier/tool/WinIPBroadcast",
|
||||
"name": "WinIPBroadcast"
|
||||
},
|
||||
{
|
||||
"args": true,
|
||||
"cmd": "$RESOURCE/easytier/tool/ForceBindIP",
|
||||
"name": "ForceBindIP"
|
||||
},
|
||||
{
|
||||
"args": true,
|
||||
"cmd": "$RESOURCE/easytier/tool/ForceBindIP64",
|
||||
"name": "ForceBindIP64"
|
||||
},
|
||||
{
|
||||
"args": true,
|
||||
"cmd": "$RESOURCE/easytier/tool/nssm",
|
||||
"name": "nssm"
|
||||
},
|
||||
{
|
||||
"args": true,
|
||||
"cmd": "explorer",
|
||||
"name": "explorer"
|
||||
},
|
||||
{
|
||||
"args": true,
|
||||
"cmd": "netsh",
|
||||
"name": "netsh"
|
||||
},
|
||||
{
|
||||
"args": true,
|
||||
"cmd": "ping",
|
||||
"name": "ping"
|
||||
}
|
||||
]
|
||||
},
|
||||
"fs:default",
|
||||
"fs:allow-read-dir",
|
||||
"fs:allow-exists",
|
||||
"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",
|
||||
"window-state:default",
|
||||
"window-state:allow-save-window-state",
|
||||
"window-state:allow-restore-state",
|
||||
"cli:default",
|
||||
"cli:allow-cli-matches",
|
||||
"log:default",
|
||||
"log:allow-log",
|
||||
"dialog:default",
|
||||
"dialog:allow-open"
|
||||
]
|
||||
}
|
||||
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
+111
-5
@@ -9,6 +9,7 @@ use std::fs::{self, File};
|
||||
use std::io::{BufRead, BufReader, Write};
|
||||
use std::os::windows::process::CommandExt;
|
||||
use std::process::{Command, Stdio};
|
||||
use std::ptr;
|
||||
use std::sync::mpsc;
|
||||
use std::{path, thread};
|
||||
use sysinfo::System;
|
||||
@@ -17,16 +18,92 @@ use tauri::Emitter;
|
||||
use tauri::Manager;
|
||||
use windows::core::{BSTR, VARIANT};
|
||||
use windows::Win32::Foundation::VARIANT_BOOL;
|
||||
use windows::Win32::NetworkManagement::IpHelper::{
|
||||
GetAdaptersAddresses, GAA_FLAG_INCLUDE_PREFIX, IP_ADAPTER_ADDRESSES_LH,
|
||||
};
|
||||
use windows::Win32::Networking::WinSock::AF_UNSPEC;
|
||||
use windows::Win32::System::Com::*;
|
||||
use windows::Win32::System::TaskScheduler::*;
|
||||
// use std::ffi::CStr;
|
||||
|
||||
use windows::Win32::System::Power::SetThreadExecutionState;
|
||||
use windows::Win32::System::Power::{
|
||||
ES_CONTINUOUS, ES_DISPLAY_REQUIRED, ES_SYSTEM_REQUIRED, EXECUTION_STATE,
|
||||
};
|
||||
|
||||
use rand::Rng;
|
||||
use tokio::process::Command as tokioCommand;
|
||||
|
||||
#[tauri::command(rename_all = "snake_case")]
|
||||
fn get_network_adapter_guids() -> Vec<[String; 2]> {
|
||||
let mut guids: Vec<[String; 2]> = Vec::new();
|
||||
unsafe {
|
||||
let mut buffer_length: u32 = 0;
|
||||
let mut result = GetAdaptersAddresses(
|
||||
AF_UNSPEC.0.into(),
|
||||
GAA_FLAG_INCLUDE_PREFIX,
|
||||
Some(ptr::null_mut()),
|
||||
Some(ptr::null_mut()),
|
||||
&mut buffer_length,
|
||||
);
|
||||
|
||||
if result != 0 {
|
||||
let mut buffer: Vec<u8> = vec![0; buffer_length as usize];
|
||||
let adapter_addresses: *mut IP_ADAPTER_ADDRESSES_LH = buffer.as_mut_ptr() as *mut _;
|
||||
|
||||
result = GetAdaptersAddresses(
|
||||
AF_UNSPEC.0.into(),
|
||||
GAA_FLAG_INCLUDE_PREFIX,
|
||||
Some(ptr::null_mut()),
|
||||
Some(adapter_addresses),
|
||||
&mut buffer_length,
|
||||
);
|
||||
|
||||
if result == 0 {
|
||||
let mut current_address = adapter_addresses;
|
||||
|
||||
while !current_address.is_null() {
|
||||
let adapter = &*current_address;
|
||||
|
||||
let guid = adapter.AdapterName.to_string().unwrap();
|
||||
let desc = adapter.Description.to_string().unwrap();
|
||||
guids.push([guid, desc]);
|
||||
|
||||
current_address = adapter.Next;
|
||||
}
|
||||
} else {
|
||||
log::error!("GetAdaptersAddresses failed with error");
|
||||
}
|
||||
} else {
|
||||
log::error!("GetAdaptersAddresses failed to retrieve buffer length with error");
|
||||
}
|
||||
}
|
||||
|
||||
return guids;
|
||||
}
|
||||
|
||||
fn generate_random_user_agent() -> String {
|
||||
let user_agents = vec![
|
||||
"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/{version} Safari/537.36",
|
||||
"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/{version} Safari/605.1.15",
|
||||
"Mozilla/5.0 (iPhone; CPU iPhone OS 14_0 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/{version} Mobile/15E148 Safari/604.1",
|
||||
"Mozilla/5.0 (Linux; Android 10; SM-G973F) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/{version} Mobile Safari/537.36",
|
||||
"Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:{version}) Gecko/20100101 Firefox/{version}",
|
||||
];
|
||||
|
||||
let mut rng = rand::thread_rng();
|
||||
let template = user_agents[rng.gen_range(0..user_agents.len())];
|
||||
|
||||
// 生成随机版本号
|
||||
let version_major: u8 = rng.gen_range(70..90);
|
||||
let version_minor: u8 = rng.gen_range(0..10);
|
||||
let version_patch: u8 = rng.gen_range(0..10);
|
||||
let version = format!("{}.{}.{}", version_major, version_minor, version_patch);
|
||||
|
||||
// 替换模板中的版本号占位符
|
||||
template.replace("{version}", &version)
|
||||
}
|
||||
|
||||
#[tauri::command(rename_all = "snake_case")]
|
||||
fn prevent_sleep() -> bool {
|
||||
unsafe {
|
||||
@@ -67,11 +144,11 @@ pub async fn fetch_releases() -> Result<Vec<Release>, Error> {
|
||||
let client = Client::new();
|
||||
// 构建请求的URL
|
||||
let url = format!("https://api.github.com/repos/easytier/easytier/releases",);
|
||||
|
||||
let user_agent = generate_random_user_agent();
|
||||
// 发送HTTP GET请求
|
||||
let response = client
|
||||
.get(&url)
|
||||
.header("User-Agent", "Tauri-fetch")
|
||||
.header("User-Agent", user_agent)
|
||||
.send()
|
||||
.await?;
|
||||
// 反序列化响应体为Release列表
|
||||
@@ -84,11 +161,11 @@ async fn fetch_game_releases() -> [String; 2] {
|
||||
let client = Client::new();
|
||||
// 构建请求的URL
|
||||
let url = format!("https://api.github.com/repos/Easytier/EasytierGame/releases",);
|
||||
|
||||
let user_agent = generate_random_user_agent();
|
||||
// 发送HTTP GET请求
|
||||
if let Ok(response) = client
|
||||
.get(&url)
|
||||
.header("User-Agent", "Tauri-fetch")
|
||||
.header("User-Agent", user_agent)
|
||||
.send()
|
||||
.await
|
||||
{
|
||||
@@ -221,6 +298,32 @@ async fn get_members_by_cli() -> String {
|
||||
}
|
||||
}
|
||||
|
||||
#[tauri::command(rename_all = "snake_case")]
|
||||
async fn get_route_by_cli() -> String {
|
||||
let cli_path = get_tool_exe_path("\\easytier\\easytier-cli.exe");
|
||||
match tokioCommand::new(&cli_path)
|
||||
.arg("route")
|
||||
.creation_flags(0x08000000)
|
||||
.output()
|
||||
.await
|
||||
{
|
||||
Ok(output) => {
|
||||
if output.status.success() {
|
||||
let output_str = String::from_utf8_lossy(&output.stdout);
|
||||
return output_str.trim().to_string();
|
||||
} else {
|
||||
let output_str = String::from_utf8_lossy(&output.stderr);
|
||||
log::error!("{}", output_str.trim().to_string());
|
||||
return "_EasytierGameCliFailedToConnect_".to_string();
|
||||
}
|
||||
}
|
||||
Err(_e) => {
|
||||
log::error!("get route list error");
|
||||
return "".to_string();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[tauri::command(rename_all = "snake_case")]
|
||||
async fn download_easytier_zip(download_url: String, file_name: String) {
|
||||
let cache_dir_path = get_tool_exe_path("\\easytier\\cache");
|
||||
@@ -615,6 +718,7 @@ pub fn run() {
|
||||
|
||||
let context = tauri::generate_context!();
|
||||
tauri::Builder::default()
|
||||
.plugin(tauri_plugin_dialog::init())
|
||||
.plugin(tauri_plugin_cli::init())
|
||||
.plugin(
|
||||
tauri_plugin_window_state::Builder::new()
|
||||
@@ -685,12 +789,14 @@ pub fn run() {
|
||||
fetch_game_releases,
|
||||
download_easytier_zip,
|
||||
get_members_by_cli,
|
||||
get_route_by_cli,
|
||||
search_pid_by_pname,
|
||||
get_exe_directory,
|
||||
spawn_autostart,
|
||||
autostart_is_enabled,
|
||||
prevent_sleep,
|
||||
allow_sleep
|
||||
allow_sleep,
|
||||
get_network_adapter_guids
|
||||
])
|
||||
.run(context)
|
||||
.expect("error while running tauri application");
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"$schema": "../node_modules/@tauri-apps/cli/config.schema.json",
|
||||
"productName": "easytier-game",
|
||||
"version": "1.3.1",
|
||||
"version": "1.3.5",
|
||||
"identifier": "com.tauri.easytier-game",
|
||||
|
||||
"build": {
|
||||
@@ -13,7 +13,7 @@
|
||||
"app": {
|
||||
"windows": [
|
||||
{
|
||||
"title": "easytier-game 1.3.1",
|
||||
"title": "easytier-game 1.3.5",
|
||||
"label": "main",
|
||||
"minWidth": 340,
|
||||
"width": 340,
|
||||
@@ -53,6 +53,10 @@
|
||||
"easytier/icons/",
|
||||
"easytier/config_template.json",
|
||||
"easytier/tool/WinIPBroadcast.exe",
|
||||
"easytier/tool/ForceBindIP.exe",
|
||||
"easytier/tool/ForceBindIP64.exe",
|
||||
"easytier/tool/BindIP.dll",
|
||||
"easytier/tool/BindIP64.dll",
|
||||
"easytier/tool/MicrosoftEdgeWebview2Setup.exe",
|
||||
"easytier/easytier-cli.exe",
|
||||
"easytier/easytier-core.exe",
|
||||
|
||||
+29
-8
@@ -1,9 +1,9 @@
|
||||
import { defineStore } from "pinia";
|
||||
export default defineStore("main", {
|
||||
import { acceptHMRUpdate, defineStore } from "pinia";
|
||||
const store = defineStore("main", {
|
||||
state() {
|
||||
return {
|
||||
config: {
|
||||
protocol: ["tcp", "udp"], // 网络协议
|
||||
protocol: ["tcp"], // 网络协议
|
||||
serverUrl: "public.easytier.top:11010",
|
||||
networkName: "",
|
||||
networkPassword: "",
|
||||
@@ -15,6 +15,8 @@ export default defineStore("main", {
|
||||
disableIpv6: false, // 是否禁用IPv6
|
||||
port: "11010", // 监听端口号
|
||||
enableCustomListener: false, // 是否自定义监听
|
||||
customListenerV6Data: "", //自定义ipv6监听
|
||||
enableCustomListenerV6: false, // 是否自定义监听
|
||||
customListenerData: "", // 自定义监听地址
|
||||
disbleListenner: false, // 是否禁用监听
|
||||
disableEncryption: true, // 是否禁用加密
|
||||
@@ -31,11 +33,12 @@ export default defineStore("main", {
|
||||
logLevel: "error", //日志等级
|
||||
devName: false, //自定义网卡名
|
||||
devNameValue: "", //自定义网卡名
|
||||
enableCustonProtocol: false, //自定义默认协议
|
||||
enableCustomProtocol: false, //自定义默认协议
|
||||
customProtocol: "tcp", //自定义默认协议
|
||||
enableNetCardMetric: false, //启用网卡自定义跃点
|
||||
netCardMetricValue: 1, //自定义网卡跃点值
|
||||
enablePreventSleep: false, //组织系统休眠
|
||||
compression: "none", //加密算法
|
||||
},
|
||||
serverConfig: {
|
||||
enableWhiteList: true, // 是否启用白名单
|
||||
@@ -46,7 +49,7 @@ export default defineStore("main", {
|
||||
port: "11010" // 服务器端口
|
||||
},
|
||||
cidrEnable: false,
|
||||
basePeers: ["public.easytier.top:11010"],
|
||||
basePeers: ["public.easytier.top:11010","public.easytier.net:11010"],
|
||||
theme: false, //主题 false light true dark
|
||||
configStartEnable: false, //使用配置文件启动
|
||||
configPath: "", //配置文件路径
|
||||
@@ -54,6 +57,12 @@ export default defineStore("main", {
|
||||
createConfigInEasytier: false, //在easytier目录生成config.json文件吗
|
||||
githubFastUrl: "https://ghproxy.cc/",
|
||||
|
||||
// forceBindIp配置
|
||||
forceBindIpBit: "64",
|
||||
delayInjectDll: false,
|
||||
forceBindInput: "",
|
||||
forceBindFile: "",
|
||||
|
||||
winipBcPid: 0,
|
||||
winipBcStart: false
|
||||
};
|
||||
@@ -71,7 +80,6 @@ export default defineStore("main", {
|
||||
"config.autoStart",
|
||||
"config.connectAfterStart",
|
||||
"config.disableIpv6",
|
||||
"config.disbleListenner",
|
||||
"config.disableEncryption",
|
||||
"config.multiThread",
|
||||
"config.enablExitNode",
|
||||
@@ -89,11 +97,17 @@ export default defineStore("main", {
|
||||
"config.enableNetCardMetric",
|
||||
"config.netCardMetricValue",
|
||||
"config.port",
|
||||
|
||||
"config.disbleListenner",
|
||||
"config.enableCustomListener",
|
||||
"config.customListenerData",
|
||||
"config.enableCustonProtocol",
|
||||
"config.enableCustomListenerV6",
|
||||
"config.customListenerV6Data",
|
||||
|
||||
"config.enableCustomProtocol",
|
||||
"config.customProtocol",
|
||||
"config.enablePreventSleep",
|
||||
"config.compression",
|
||||
|
||||
"serverConfig.autoStart",
|
||||
// 'serverConfig.enableListener',
|
||||
@@ -109,9 +123,16 @@ export default defineStore("main", {
|
||||
"configPath",
|
||||
"winIpBcAutoStart",
|
||||
"createConfigInEasytier",
|
||||
"githubFastUrl"
|
||||
"githubFastUrl",
|
||||
|
||||
"forceBindIpBit",
|
||||
"delayInjectDll",
|
||||
"forceBindInput",
|
||||
"forceBindFile"
|
||||
]
|
||||
// // 除了这些,其他都要存下来
|
||||
// omit: ["winipBcPid", "winipBcStart"]
|
||||
}
|
||||
});
|
||||
if (import.meta.hot) import.meta.hot.accept(acceptHMRUpdate(store, import.meta.hot));
|
||||
export default store;
|
||||
|
||||
Vendored
+3
@@ -1,6 +1,9 @@
|
||||
interface ImportMetaEnv {
|
||||
readonly VITE_CONFIG_PATH: string;
|
||||
readonly VITE_CONFIG_FILE_NAME: string;
|
||||
readonly VITE_LOG_PATH: string;
|
||||
readonly VITE_CACHE_PATH: string;
|
||||
readonly VITE_AUTO_START_SERVICE_NAME: string;
|
||||
}
|
||||
|
||||
interface ImportMeta {
|
||||
|
||||
+4
-2
@@ -1,7 +1,7 @@
|
||||
import { ElMessageBox } from "element-plus";
|
||||
import { ATJ } from "./index";
|
||||
import { h, type VNode } from "vue";
|
||||
type Opt = { action?: string; confirmButtonText?: string; cancelButtonText?: string; VNode?: VNode | null }
|
||||
type Opt = { action?: string; confirmButtonText?: string; cancelButtonText?: string; VNode?: VNode | null, showCancelButton?:boolean }
|
||||
export const ElConfirmDanger = (
|
||||
content: string,
|
||||
title: string,
|
||||
@@ -81,10 +81,11 @@ export const ElConfirmPrimary = (
|
||||
action: "",
|
||||
confirmButtonText: "确定",
|
||||
cancelButtonText: "取消",
|
||||
showCancelButton: true,
|
||||
VNode: null
|
||||
}
|
||||
): Promise<any | [any, any]> => {
|
||||
const { action = "", confirmButtonText = "确定", cancelButtonText = "取消", VNode = null } = opt;
|
||||
const { action = "", confirmButtonText = "确定", cancelButtonText = "取消", VNode = null, showCancelButton = true } = opt;
|
||||
const formatContentArr = content.split("{action}");
|
||||
const action_length = formatContentArr.length - 1;
|
||||
const messageArr = [];
|
||||
@@ -103,6 +104,7 @@ export const ElConfirmPrimary = (
|
||||
ElMessageBox.confirm(message, title, {
|
||||
closeOnClickModal: false, // 点击遮罩层不关闭弹窗
|
||||
closeOnPressEscape: false, // 按下Esc键不关闭弹窗
|
||||
showCancelButton,
|
||||
cancelButtonText,
|
||||
confirmButtonText,
|
||||
confirmButtonClass: "el-button--primary"
|
||||
|
||||
+3
-2
@@ -81,12 +81,13 @@ export const preventSleep = () => {
|
||||
}, _prevent_timer_count * 1000);
|
||||
}
|
||||
|
||||
export const stopPreventSleep = () => {
|
||||
export const stopPreventSleep = async () => {
|
||||
_prevent_timer && clearInterval(_prevent_timer);
|
||||
_prevent_timer = null;
|
||||
const _result = await invoke('allow_sleep');
|
||||
}
|
||||
|
||||
export const parsePeerInfo = (content: string) => {
|
||||
export const parseCliInfo = (content: string) => {
|
||||
if(!content) return [];
|
||||
// 将表格字符串分割成行
|
||||
const lines = content.split("\n");
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
import useMainStore from "@/stores/index";
|
||||
import * as tauriAutoStart from "@tauri-apps/plugin-autostart";
|
||||
import { open, Command } from "@tauri-apps/plugin-shell";
|
||||
import { invoke } from "@tauri-apps/api/core";
|
||||
|
||||
@@ -52,19 +51,3 @@ const handleAutoStartByNssm = async () => {
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
// 兼容autostart插件
|
||||
const compatibleAutoStart = async () => {
|
||||
const config = useMainStore().config;
|
||||
const is_enable = await tauriAutoStart.isEnabled();
|
||||
if (is_enable) {
|
||||
try {
|
||||
await tauriAutoStart.disable();
|
||||
config.autoStart = false;
|
||||
} catch (err) {
|
||||
// ElMessage.error(`取消自启失败`);
|
||||
}
|
||||
}
|
||||
const serverStatus = await Command.create("nssm", ["status", import.meta.env.VITE_AUTO_START_SERVICE_NAME]).execute();
|
||||
console.log(serverStatus);
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user