mirror of
https://github.com/EasyTier/EasytierGame.git
synced 2026-09-20 11:22:37 +00:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
05fe46858d | ||
|
|
a438c48fdc |
+8
-1
@@ -39,7 +39,7 @@ html.dark body {
|
||||
}
|
||||
|
||||
.full-label .el-form-item__label {
|
||||
width: 100%;
|
||||
width: 100%!important;
|
||||
padding-right: 0;
|
||||
}
|
||||
|
||||
@@ -50,6 +50,13 @@ html.dark body {
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.el-select__selection {
|
||||
/* display: none!important; */
|
||||
min-height: 20px!important;
|
||||
flex-wrap: nowrap!important;
|
||||
overflow: hidden!important;
|
||||
}
|
||||
|
||||
.el-table {
|
||||
font-size: 12px !important;
|
||||
}
|
||||
|
||||
+12
-16
@@ -5,7 +5,7 @@ import { uniq, intersection, isNil } from "lodash-es";
|
||||
import { bounce } from "~/utils";
|
||||
|
||||
const b = bounce(600);
|
||||
export type ConfigServerUrlType = Array<string> | string | null | undefined | null;
|
||||
export type ConfigServerUrlType = Array<string>;
|
||||
|
||||
export const updateConfigJsonBounce = (configJsonSeverUrl?: ConfigServerUrlType) => {
|
||||
b(async () => {
|
||||
@@ -22,8 +22,10 @@ export const updateConfigJson = async (configJsonSeverUrl?: ConfigServerUrlType)
|
||||
if (isNil(configJsonSeverUrl)) {
|
||||
configJsonSeverUrl = [];
|
||||
}
|
||||
const isArray = Array.isArray(configJsonSeverUrl);
|
||||
const isString = typeof configJsonSeverUrl === "string";
|
||||
if(typeof(configJsonSeverUrl) == 'string') {
|
||||
configJsonSeverUrl = [configJsonSeverUrl];
|
||||
}
|
||||
configJsonSeverUrl = configJsonSeverUrl || [];
|
||||
try {
|
||||
const {
|
||||
proxyNetworks,
|
||||
@@ -43,20 +45,14 @@ export const updateConfigJson = async (configJsonSeverUrl?: ConfigServerUrlType)
|
||||
udpWhitelistEnable,
|
||||
...otherConfig
|
||||
} = mainStore.config;
|
||||
let writeServerUrl: Array<string> | string = serverUrl;
|
||||
let writeServerUrl: Array<string> = serverUrl;
|
||||
let writeCustomListenerData: Array<string> = (customListenerData || "").split("\n");
|
||||
if (isArray) {
|
||||
writeServerUrl = intersection(
|
||||
uniq([serverUrl, ...configJsonSeverUrl]).filter(boolean => boolean),
|
||||
mainStore.basePeers
|
||||
);
|
||||
}
|
||||
if (isString && configJsonSeverUrl) {
|
||||
writeServerUrl = intersection(
|
||||
uniq([serverUrl, ...(configJsonSeverUrl as string).split(",")]).filter(boolean => boolean),
|
||||
mainStore.basePeers
|
||||
).join(",");
|
||||
}
|
||||
|
||||
writeServerUrl = intersection(
|
||||
uniq([...serverUrl, ...configJsonSeverUrl]).filter(boolean => boolean),
|
||||
mainStore.basePeers
|
||||
);
|
||||
|
||||
await writeTextFile(
|
||||
path,
|
||||
JSON.stringify({ serverUrl: writeServerUrl, enableCustomListener, customListenerData: writeCustomListenerData, ...otherConfig }, null, 4),
|
||||
|
||||
+2
-2
@@ -3,7 +3,7 @@
|
||||
"private": true,
|
||||
"author": "leizi97",
|
||||
"description": "A simple network initiator based on Easytier",
|
||||
"version": "1.4.8",
|
||||
"version": "1.4.9",
|
||||
"scripts": {
|
||||
"dev": "nuxt dev --dotenv env/.env.dev --host 0.0.0.0",
|
||||
"build": "nuxt generate --dotenv env/.env.prod",
|
||||
@@ -31,7 +31,7 @@
|
||||
"element-plus": "2.10.7",
|
||||
"less": "4.2.1",
|
||||
"lodash-es": "^4.17.21",
|
||||
"nuxt": "3.18.1",
|
||||
"nuxt": "3.19.2",
|
||||
"pinia": "3.0.3",
|
||||
"pinia-plugin-persistedstate": "4.4.1",
|
||||
"postcss": "^8.4.38",
|
||||
|
||||
+65
-28
@@ -45,7 +45,7 @@
|
||||
</div>
|
||||
<ElTooltip content="请先停止自建服务和联机后再使用,否则内核被占用的情况下,无法进行内核更换">
|
||||
<ElBadge
|
||||
badge-class="!text-[9px] cursor-pointer"
|
||||
badge-class="!text-[9px] cursor-pointer ml-auto"
|
||||
:hidden="!haveNewCoreVersion"
|
||||
:offset="[-5, 6]"
|
||||
@click.stop="handleCoreManagement"
|
||||
@@ -68,6 +68,9 @@
|
||||
<ElSelect
|
||||
allow-create
|
||||
filterable
|
||||
multiple
|
||||
collapse-tags
|
||||
collapse-tags-tooltip
|
||||
placeholder="请选择服务器地址"
|
||||
default-first-option
|
||||
v-model="mainStore.config.serverUrl"
|
||||
@@ -75,14 +78,13 @@
|
||||
@change="handleServerUrlChange"
|
||||
>
|
||||
<template #prefix>
|
||||
<div :class="mainStore.config.protocol && mainStore.config.protocol.length > 1 ? 'w-[120px]' : 'w-[80px]'">
|
||||
<div :class="mainStore.config.protocol && mainStore.config.protocol.length > 1 ? 'w-[110px]' : 'w-[80px]'">
|
||||
<ElSelect
|
||||
placeholder="协议"
|
||||
multiple
|
||||
collapse-tags
|
||||
@click.stop
|
||||
v-model="mainStore.config.protocol"
|
||||
@change="handleServerUrlChange"
|
||||
>
|
||||
<ElOption
|
||||
v-for="item in protocols"
|
||||
@@ -780,7 +782,7 @@
|
||||
import { updateConfigJson, updateConfigJsonBounce } from "~/composables/configJson";
|
||||
import { writeText, readText } from "@tauri-apps/plugin-clipboard-manager";
|
||||
import { sortedUniq, uniq } from "lodash-es";
|
||||
import { addQQGroup, supportProtocols, preventSleep, stopPreventSleep, ATJ, copyText, isValidWindowsFileName } from "~/utils";
|
||||
import { addQQGroup, supportProtocols, preventSleep, stopPreventSleep, ATJ, copyText, isValidWindowsFileName, mixedArray } from "~/utils";
|
||||
import { ElConfirmDanger, ElConfirmPrimary } from "~/utils/element";
|
||||
import { getServerArgs } from "@/composables/server";
|
||||
import { isIPv6 } from "is-ip";
|
||||
@@ -828,7 +830,7 @@
|
||||
startLoading: false,
|
||||
isStart: false,
|
||||
connectionSuccess: false,
|
||||
configJsonSeverUrl: "" // 本地保存一次,用于回填config.json
|
||||
configJsonSeverUrl: [] // 本地保存一次,用于回填config.json
|
||||
});
|
||||
|
||||
const configStart = reactive<{ list: Array<{ path: string; name: string }>; [key: string]: any }>({
|
||||
@@ -939,30 +941,40 @@
|
||||
const newBasePeers = [...mainStore.basePeers];
|
||||
const idx = newBasePeers.indexOf(url);
|
||||
if (idx >= 0) {
|
||||
if (mainStore.config.serverUrl === url) {
|
||||
mainStore.config.serverUrl = "";
|
||||
const selectIdx = mainStore.config.serverUrl.indexOf(url);
|
||||
if (selectIdx >= 0) {
|
||||
mainStore.config.serverUrl.splice(selectIdx, 1);
|
||||
}
|
||||
newBasePeers.splice(idx, 1);
|
||||
}
|
||||
mainStore.basePeers = uniq([...newBasePeers]);
|
||||
if (mainStore.basePeers.length > 0) {
|
||||
mainStore.config.serverUrl = mainStore.basePeers[0];
|
||||
if (mainStore.basePeers.length > 0 && mainStore.config.serverUrl.length <= 0) {
|
||||
mainStore.config.serverUrl = [mainStore.basePeers[0]];
|
||||
}
|
||||
};
|
||||
|
||||
const handleServerUrlChange = () => {
|
||||
let inputProtocols: string | null = null;
|
||||
let inputProtocols: string[] = [];
|
||||
// console.log(mainStore.config.serverUrl);
|
||||
for (const p of protocols) {
|
||||
if (mainStore.config.serverUrl.toLowerCase().startsWith(`${p}://`)) {
|
||||
inputProtocols = p;
|
||||
break;
|
||||
for (const url of mainStore.config.serverUrl) {
|
||||
if (url.toLowerCase().startsWith(`${p}://`)) {
|
||||
inputProtocols.push(p);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (inputProtocols) {
|
||||
mainStore.config.protocol = [inputProtocols];
|
||||
mainStore.config.serverUrl = mainStore.config.serverUrl.slice(inputProtocols.length + 3);
|
||||
mainStore.config.protocol = uniq([...mainStore.config.protocol, ...inputProtocols]);
|
||||
mainStore.config.serverUrl = (mainStore.config.serverUrl || []).map(url => {
|
||||
for (const p of protocols) {
|
||||
if (url.toLowerCase().startsWith(`${p}://`)) {
|
||||
return url.slice(inputProtocols.length + 3);
|
||||
}
|
||||
}
|
||||
return url;
|
||||
});
|
||||
}
|
||||
mainStore.basePeers = uniq([mainStore.config.serverUrl, ...mainStore.basePeers]);
|
||||
mainStore.basePeers = uniq([...mainStore.config.serverUrl, ...mainStore.basePeers]);
|
||||
};
|
||||
|
||||
const listenObj: { [key: string]: any } = {
|
||||
@@ -1242,6 +1254,13 @@
|
||||
}
|
||||
};
|
||||
|
||||
// 多选serverUrl兼容
|
||||
const compatibleInitServerUrl = async () => {
|
||||
if (typeof mainStore.config.serverUrl == "string") {
|
||||
mainStore.config.serverUrl = [mainStore.config.serverUrl || ""];
|
||||
}
|
||||
};
|
||||
|
||||
const initGuiJson = async () => {
|
||||
const path = import.meta.env.VITE_CONFIG_FILE_NAME;
|
||||
const isExists = await exists(path, { baseDir: BaseDirectory.Resource });
|
||||
@@ -1257,19 +1276,21 @@
|
||||
// const resultStr = guiJsonStr.replace(regex, "").replace(regex2, "$1");
|
||||
// console.log(resultStr);
|
||||
const guiJson = JSON.parse(guiJsonStr);
|
||||
let saveServerUrl = "";
|
||||
let saveServerUrl = [];
|
||||
if (guiJson.serverUrl) {
|
||||
if (Array.isArray(guiJson.serverUrl)) {
|
||||
mainStore.basePeers = uniq([...guiJson.serverUrl, ...mainStore.basePeers]);
|
||||
saveServerUrl = uniq([...guiJson.serverUrl]);
|
||||
}
|
||||
if (typeof guiJson.serverUrl === "string") {
|
||||
mainStore.basePeers = uniq([...guiJson.serverUrl.split(","), ...mainStore.basePeers]);
|
||||
saveServerUrl = [mainStore.basePeers[0] || ""];
|
||||
guiJson.serverUrl = guiJson.serverUrl ? guiJson.serverUrl.split(",") : [];
|
||||
}
|
||||
saveServerUrl = mainStore.basePeers[0] || "";
|
||||
} else {
|
||||
saveServerUrl = mainStore.basePeers.length > 0 ? mainStore.basePeers[0] || "" : "";
|
||||
saveServerUrl = [mainStore.basePeers.length > 0 ? mainStore.basePeers[0] || "" : ""];
|
||||
}
|
||||
data.configJsonSeverUrl = guiJson.serverUrl;
|
||||
data.configJsonSeverUrl = [...guiJson.serverUrl] as any;
|
||||
if (guiJson.enableKcpProxy && guiJson.enableQuicProxy) {
|
||||
// 如果同时开启kcp代理和quic代理,则禁用quic代理
|
||||
guiJson.enableQuicProxy = false;
|
||||
@@ -1338,11 +1359,12 @@
|
||||
});
|
||||
};
|
||||
|
||||
let logsTimer: NodeJS.Timeout | null = null;
|
||||
let serverLogsTimer: NodeJS.Timeout | null = null;
|
||||
let cidrTimer: NodeJS.Timeout | null = null;
|
||||
let logsTimer: number | null = null;
|
||||
let serverLogsTimer: number | null = null;
|
||||
let cidrTimer: number | null = null;
|
||||
|
||||
onMounted(async () => {
|
||||
await compatibleInitServerUrl();
|
||||
await initGuiJson();
|
||||
await compatibleInitAutoStart();
|
||||
// await initAutoStart();
|
||||
@@ -1414,7 +1436,16 @@
|
||||
return [];
|
||||
}
|
||||
}
|
||||
|
||||
if (mainStore.config.serverUrl?.length <= 0) {
|
||||
ElMessage.warning(`请至少选择一个服务器`);
|
||||
return [];
|
||||
}
|
||||
// lodash-es 如何将两个数组的值混合 比如["tcp","udp"] [1,2]
|
||||
// 混合后["tcp1","tcp2","udp1","udp2"]
|
||||
if (mainStore.config.protocol?.length <= 0) {
|
||||
ElMessage.warning(`请至少选择一个协议`);
|
||||
return [];
|
||||
}
|
||||
if (mainStore.config.dhcp) {
|
||||
args.push("-d");
|
||||
}
|
||||
@@ -1431,8 +1462,8 @@
|
||||
args.push("--ipv4", mainStore.config.ipv4.trim());
|
||||
}
|
||||
if (mainStore.config.serverUrl) {
|
||||
const formatUrl = mainStore.config.serverUrl.replace(/\\/g, "/");
|
||||
args.push("--peers", ...mainStore.config.protocol.map(protocol => `${protocol}://${formatUrl}`));
|
||||
const formatUrlArr = mainStore.config.serverUrl.map((url: string) => url.replace(/\\/g, "/"));
|
||||
args.push("--peers", ...mixedArray(mainStore.config.protocol, formatUrlArr, "://"));
|
||||
}
|
||||
if (mainStore.config.enableCustomProtocol) {
|
||||
const includes = mainStore.config.protocol.includes(mainStore.config.customProtocol);
|
||||
@@ -1885,7 +1916,13 @@
|
||||
});
|
||||
if (!err) {
|
||||
const payload = JSON.parse(decodeURIComponent(atob(importConfigData.data)));
|
||||
payload.config.serverUrl = payload?.config?.serverUrl?.trim() || mainStore.config.serverUrl;
|
||||
payload.config.serverUrl = Array.isArray(payload?.config?.serverUrl)
|
||||
? payload?.config?.serverUrl
|
||||
: typeof payload?.config?.serverUrl == "string"
|
||||
? [payload?.config?.serverUrl.split(",")]
|
||||
: typeof mainStore.config.serverUrl == "string"
|
||||
? [mainStore.config.serverUrl]
|
||||
: [];
|
||||
mainStore.$patch({
|
||||
config: {
|
||||
...mainStore.config,
|
||||
@@ -1894,7 +1931,7 @@
|
||||
});
|
||||
ElMessage.success("导入成功");
|
||||
importConfigData.visible = false;
|
||||
mainStore.basePeers = uniq([mainStore.config.serverUrl, ...mainStore.basePeers].filter(el => el.trim()));
|
||||
mainStore.basePeers = uniq([...(mainStore.config.serverUrl || []), ...mainStore.basePeers].filter(el => el.trim()));
|
||||
} else {
|
||||
console.error(err);
|
||||
if (err !== "cancel") {
|
||||
|
||||
+7
-1
@@ -12,7 +12,10 @@
|
||||
@scroll="handleScroll"
|
||||
class="overflow-auto"
|
||||
>
|
||||
<div v-if="!data.log || data.log.length <= 0" class="p-[5px]">
|
||||
<div
|
||||
v-if="!data.log || data.log.length <= 0"
|
||||
class="p-[5px]"
|
||||
>
|
||||
<ElText type="info">等待日志中,请先'启动联机'...</ElText>
|
||||
</div>
|
||||
<div
|
||||
@@ -106,6 +109,9 @@
|
||||
.split("\n")
|
||||
.filter(text => text.trim())
|
||||
.map((text, idx) => {
|
||||
if (idx === 0) {
|
||||
return { id: `${text}-${idx}`, text, type: "primary" };
|
||||
}
|
||||
const toLowerCaseText = text.toLocaleLowerCase();
|
||||
return {
|
||||
id: `${text}-${idx}`,
|
||||
|
||||
+34
-34
@@ -214,7 +214,7 @@
|
||||
};
|
||||
|
||||
// 字节数据排序函数
|
||||
const sortBytes = (a: any, b: any, field: string = 'rx_bytes'): number => {
|
||||
const sortBytes = (a: any, b: any, field: string = "rx_bytes"): number => {
|
||||
const parseBytes = (bytesStr: string): number => {
|
||||
if (!bytesStr || bytesStr === "-" || bytesStr === "") {
|
||||
return 0;
|
||||
@@ -222,7 +222,7 @@
|
||||
|
||||
// 统一转换为小写并去除空格
|
||||
const cleanStr = bytesStr.toLowerCase().trim();
|
||||
|
||||
|
||||
// 使用正则表达式匹配数字和单位
|
||||
const match = cleanStr.match(/^(\d+(?:\.\d+)?)\s*([a-z]*)$/);
|
||||
if (!match) {
|
||||
@@ -238,30 +238,30 @@
|
||||
|
||||
// 根据单位转换为字节数
|
||||
switch (unit) {
|
||||
case 'b':
|
||||
case 'byte':
|
||||
case 'bytes':
|
||||
case '':
|
||||
case "b":
|
||||
case "byte":
|
||||
case "bytes":
|
||||
case "":
|
||||
return value;
|
||||
case 'k':
|
||||
case 'kb':
|
||||
case 'kib':
|
||||
case "k":
|
||||
case "kb":
|
||||
case "kib":
|
||||
return value * 1024;
|
||||
case 'm':
|
||||
case 'mb':
|
||||
case 'mib':
|
||||
case "m":
|
||||
case "mb":
|
||||
case "mib":
|
||||
return value * 1024 * 1024;
|
||||
case 'g':
|
||||
case 'gb':
|
||||
case 'gib':
|
||||
case "g":
|
||||
case "gb":
|
||||
case "gib":
|
||||
return value * 1024 * 1024 * 1024;
|
||||
case 't':
|
||||
case 'tb':
|
||||
case 'tib':
|
||||
case "t":
|
||||
case "tb":
|
||||
case "tib":
|
||||
return value * 1024 * 1024 * 1024 * 1024;
|
||||
case 'p':
|
||||
case 'pb':
|
||||
case 'pib':
|
||||
case "p":
|
||||
case "pb":
|
||||
case "pib":
|
||||
return value * 1024 * 1024 * 1024 * 1024 * 1024;
|
||||
default:
|
||||
return value; // 未知单位当作字节处理
|
||||
@@ -305,11 +305,10 @@
|
||||
["tx_bytes", "传输"]
|
||||
];
|
||||
|
||||
let timer: NodeJS.Timeout | null = null;
|
||||
let timer: number | null = null;
|
||||
|
||||
const listenOutput = async () => {
|
||||
const [error, member] = await ATJ(invoke<string>("get_members_by_cli"));
|
||||
// if(!member) return;
|
||||
if (error) {
|
||||
data.member = [];
|
||||
return "";
|
||||
@@ -329,17 +328,18 @@
|
||||
}
|
||||
return;
|
||||
}
|
||||
const peerInfo = parseCliInfo(member);
|
||||
peerInfo.forEach(value => {
|
||||
if (value.cost === "Local") {
|
||||
value.cost = "本机";
|
||||
}
|
||||
if (value.ipv4 && value.ipv4.includes("/")) {
|
||||
value.ipv4 = value.ipv4.split("/")[0];
|
||||
}
|
||||
});
|
||||
// console.log(peerInfo)
|
||||
data.member = peerInfo;
|
||||
// const peerInfo = parseCliInfo(member);
|
||||
// peerInfo.forEach(value => {
|
||||
// if (value.cost === "Local") {
|
||||
// value.cost = "本机";
|
||||
// }
|
||||
// if (value.ipv4 && value.ipv4.includes("/")) {
|
||||
// value.ipv4 = value.ipv4.split("/")[0];
|
||||
// }
|
||||
// });
|
||||
// data.member = peerInfo;
|
||||
|
||||
data.member = JSON.parse(member);
|
||||
startTimer();
|
||||
};
|
||||
|
||||
|
||||
Generated
+1175
-2164
File diff suppressed because it is too large
Load Diff
Generated
+661
-531
File diff suppressed because it is too large
Load Diff
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "easytier-game"
|
||||
version = "1.4.8"
|
||||
version = "1.4.9"
|
||||
homepage = "https://github.com/EasyTier/EasyTier"
|
||||
repository = "https://github.com/EasyTier/EasytierGame"
|
||||
description = "A simple network initiator based on Easytier"
|
||||
|
||||
Binary file not shown.
Binary file not shown.
@@ -13,7 +13,6 @@ use sysinfo::System;
|
||||
use tauri::tray::{MouseButton, MouseButtonState, TrayIconBuilder, TrayIconEvent};
|
||||
use tauri::Emitter;
|
||||
use tauri::Manager;
|
||||
use windows::Win32::System::Variant::VARIANT;
|
||||
use windows::core::{Interface, BSTR};
|
||||
use windows::Win32::Foundation::VARIANT_BOOL;
|
||||
use windows::Win32::NetworkManagement::IpHelper::{
|
||||
@@ -22,6 +21,7 @@ use windows::Win32::NetworkManagement::IpHelper::{
|
||||
use windows::Win32::Networking::WinSock::AF_UNSPEC;
|
||||
use windows::Win32::System::Com::*;
|
||||
use windows::Win32::System::TaskScheduler::*;
|
||||
use windows::Win32::System::Variant::VARIANT;
|
||||
// use std::ffi::CStr;
|
||||
|
||||
use windows::Win32::System::Power::SetThreadExecutionState;
|
||||
@@ -273,6 +273,8 @@ struct MyResponse {
|
||||
async fn get_members_by_cli() -> String {
|
||||
let cli_path = get_tool_exe_path("\\easytier\\easytier-cli.exe");
|
||||
match tokioCommand::new(&cli_path)
|
||||
.arg("-o")
|
||||
.arg("json")
|
||||
.arg("peer")
|
||||
.arg("list")
|
||||
.creation_flags(0x08000000)
|
||||
@@ -351,6 +353,12 @@ async fn download_easytier_zip(
|
||||
|
||||
let path = path::Path::new(&file_path);
|
||||
println!("download easytier to {}", path.display());
|
||||
if path.exists() {
|
||||
match fs::remove_file(path) {
|
||||
Ok(_) => println!("删除上次下载的Zip文件成功"),
|
||||
Err(_) => log::error!("删除上次下载Zip的文件失败"),
|
||||
}
|
||||
}
|
||||
|
||||
let mut file = match File::create(&path) {
|
||||
Err(why) => panic!("couldn't create {}", why),
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"$schema": "../node_modules/@tauri-apps/cli/config.schema.json",
|
||||
"productName": "easytier-game",
|
||||
"version": "1.4.8",
|
||||
"version": "1.4.9",
|
||||
"identifier": "com.tauri.easytier-game",
|
||||
|
||||
"build": {
|
||||
@@ -12,7 +12,7 @@
|
||||
"app": {
|
||||
"windows": [
|
||||
{
|
||||
"title": "easytier-game 1.4.8",
|
||||
"title": "easytier-game 1.4.9",
|
||||
"label": "main",
|
||||
"minWidth": 340,
|
||||
"width": 340,
|
||||
|
||||
+2
-2
@@ -7,7 +7,7 @@ const store = defineStore("main", {
|
||||
return {
|
||||
config: {
|
||||
protocol: ["tcp"], // 网络协议
|
||||
serverUrl: "public.easytier.top:11010",
|
||||
serverUrl: ["public.easytier.top:11010"],
|
||||
networkName: "",
|
||||
networkPassword: "",
|
||||
hostname: "",
|
||||
@@ -21,7 +21,7 @@ const store = defineStore("main", {
|
||||
autoStart: false, // 是否自动启动
|
||||
connectAfterStart: false, //软件打开后,是否自动连接
|
||||
disableIpv6: false, // 是否禁用IPv6
|
||||
port: "11010", // 监听端口号
|
||||
port: "0", // 监听端口号
|
||||
enableCustomListener: true, // 是否自定义监听
|
||||
customListenerData: "tcp://0.0.0.0:11010\nudp://0.0.0.0:11010", // 自定义监听地址
|
||||
disbleListenner: false, // 是否禁用监听
|
||||
|
||||
+32
-8
@@ -2,11 +2,17 @@ import { invoke } from "@tauri-apps/api/core";
|
||||
import { writeText } from "@tauri-apps/plugin-clipboard-manager";
|
||||
import { open } from "@tauri-apps/plugin-shell";
|
||||
import { ElMessage } from "element-plus";
|
||||
import { flatMap, map } from "lodash-es";
|
||||
|
||||
export const ENV = import.meta.env;
|
||||
|
||||
export const mixedArray = (a: Array<string>, b: Array<string>, split:string="") => {
|
||||
return flatMap(a, protocol => map(b, port => `${protocol}${split}${port}`));
|
||||
};
|
||||
|
||||
//防抖
|
||||
export const bounce = (time = 3000) => {
|
||||
let bounceTimer: NodeJS.Timeout | null = null;
|
||||
let bounceTimer: number | null = null;
|
||||
return (cb: Function) => {
|
||||
bounceTimer && clearTimeout(bounceTimer);
|
||||
bounceTimer = setTimeout(() => {
|
||||
@@ -73,7 +79,7 @@ export const supportProtocols = () => {
|
||||
return _supportProtocols.slice();
|
||||
};
|
||||
|
||||
let _prevent_timer: NodeJS.Timeout | null = null;
|
||||
let _prevent_timer: number | null = null;
|
||||
let _prevent_timer_count = 15; // 秒
|
||||
export const preventSleep = () => {
|
||||
_prevent_timer && clearInterval(_prevent_timer);
|
||||
@@ -127,17 +133,35 @@ export const parseCliInfo = (content: string) => {
|
||||
};
|
||||
|
||||
export function isValidWindowsFileName(name: string) {
|
||||
if(name.length > 255) return false;
|
||||
if (name.length > 255) return false;
|
||||
const reserved_names = [
|
||||
"CON", "PRN", "AUX", "NUL",
|
||||
"COM1", "COM2", "COM3", "COM4", "COM5", "COM6", "COM7", "COM8", "COM9",
|
||||
"LPT1", "LPT2", "LPT3", "LPT4", "LPT5", "LPT6", "LPT7", "LPT8", "LPT9"
|
||||
"CON",
|
||||
"PRN",
|
||||
"AUX",
|
||||
"NUL",
|
||||
"COM1",
|
||||
"COM2",
|
||||
"COM3",
|
||||
"COM4",
|
||||
"COM5",
|
||||
"COM6",
|
||||
"COM7",
|
||||
"COM8",
|
||||
"COM9",
|
||||
"LPT1",
|
||||
"LPT2",
|
||||
"LPT3",
|
||||
"LPT4",
|
||||
"LPT5",
|
||||
"LPT6",
|
||||
"LPT7",
|
||||
"LPT8",
|
||||
"LPT9"
|
||||
];
|
||||
if(reserved_names.includes(name.toUpperCase())) {
|
||||
if (reserved_names.includes(name.toUpperCase())) {
|
||||
return false;
|
||||
}
|
||||
return /^[^<>:"/\\|?*\x00-\x1F]+[^<>:"/\\|?*\x00-\x1F .]$/g.test(name);
|
||||
|
||||
}
|
||||
|
||||
export const addQQGroup = () => {
|
||||
|
||||
Reference in New Issue
Block a user