diff --git a/config/config.go b/config/config.go index caeebc1..9ad62cf 100644 --- a/config/config.go +++ b/config/config.go @@ -65,6 +65,7 @@ type Config struct { EnableBotNotification bool `json:"enableBotNotification"` // 是否开启机器人广播 EnableRebootLater bool `json:"enableRebootLater"` // 是否开启延时关闭&重启 OverrideDLL bool `json:"overrideDLL"` // 是否由palgo中内置的dll覆盖游戏目录的dll + UsePalServerExe bool `json:"usePalserverexe"` // 是否维持传统启动行为 } // 默认配置 @@ -91,6 +92,7 @@ var defaultConfig = Config{ EnableUe4Debug: false, EnableEngineSetting: true, OverrideDLL: true, + UsePalServerExe: false, BackupInterval: 1800, // 30 分钟 MemoryCheckInterval: 30, // 30 秒 MemoryUsageThreshold: 80, // 80% diff --git a/front/palworld-front/src/pages/IndexView.vue b/front/palworld-front/src/pages/IndexView.vue index b3c74a2..18129e0 100644 --- a/front/palworld-front/src/pages/IndexView.vue +++ b/front/palworld-front/src/pages/IndexView.vue @@ -95,6 +95,11 @@ label="是否覆盖dll(不开请自己管理palguard和ue4的dll)" class="q-my-md" /> + { } catch (error) { console.error('Error saving configuration:', error); $q.notify({ - type: 'negative', - message: '保存配置失败', + type: 'positive', + message: '配置已保存!', }); } }; diff --git a/main.go b/main.go index a39c688..180170a 100644 --- a/main.go +++ b/main.go @@ -29,6 +29,7 @@ import ( "github.com/hoshinonyaruko/palworld-go/bot" "github.com/hoshinonyaruko/palworld-go/config" + "github.com/hoshinonyaruko/palworld-go/status" "github.com/hoshinonyaruko/palworld-go/sys" "github.com/hoshinonyaruko/palworld-go/tool" "github.com/hoshinonyaruko/palworld-go/webui" @@ -115,6 +116,8 @@ func main() { fmt.Println("PalServer.exe exists in the current directory.") } } + //还原状态 + status.SetManualServerShutdown(false) // 设置监控和自动重启 supervisor := NewSupervisor(jsonconfig) diff --git a/mod/mod.go b/mod/mod.go index 0d37659..7f021e2 100644 --- a/mod/mod.go +++ b/mod/mod.go @@ -71,9 +71,8 @@ func BuildEmbeddedFilesMap() (map[string]struct{}, error) { return embeddedFilesPaths, err } -// RemoveEmbeddedFiles 遍历嵌入文件列表,如果它们存在于指定路径下,则删除它们 +// RemoveEmbeddedFiles 遍历嵌入文件列表,如果它们存在于指定路径下且为exe或dll文件,则删除它们 func RemoveEmbeddedFiles(path string) error { - // 动态构建嵌入文件的路径映射 embeddedFilesPaths, err := BuildEmbeddedFilesMap() if err != nil { return err @@ -84,11 +83,17 @@ func RemoveEmbeddedFiles(path string) error { relativePath := strings.TrimPrefix(embeddedPath, "embeds/") externalPath := filepath.Join(path, relativePath) - // 检查文件或目录是否存在于文件系统中 - if _, err := os.Stat(externalPath); err == nil { - // 如果存在,删除文件或目录 - if err := os.RemoveAll(externalPath); err != nil { - return err + // 获取文件扩展名 + ext := filepath.Ext(externalPath) + + // 如果文件扩展名为.exe或.dll,则尝试删除 + if ext == ".exe" || ext == ".dll" { + // 检查文件是否存在 + if _, err := os.Stat(externalPath); err == nil { + // 如果存在,删除文件 + if err := os.Remove(externalPath); err != nil { + return err + } } } } diff --git a/sys/restart_unix.go b/sys/restart_unix.go index ece7845..bc933f5 100644 --- a/sys/restart_unix.go +++ b/sys/restart_unix.go @@ -98,24 +98,34 @@ func RestartService(config config.Config) { if config.WorldSettings.RconEnabled { args = append(args, "-rcon") } - - args = append(args, config.ServerOptions...) // 添加GameWorldSettings参数 - - // 执行启动命令 - log.Printf("启动命令: %s %s", exePath, strings.Join(args, " ")) - - cmd := exec.Command(exePath, args...) - cmd.Dir = config.GamePath // 设置工作目录为游戏路径 - - // 启动进程 - if err := cmd.Start(); err != nil { - log.Printf("Failed to restart game server: %v", err) + // 添加GameWorldSettings参数 + args = append(args, config.ServerOptions...) + + if config.GameService && config.GameServiceName != "" { + cmd := exec.Command("sudo", "systemctl", "restart", config.GameServiceName) + // 启动进程 + if err := cmd.Start(); err != nil { + log.Printf("Failed to restart game server: %v", err) + } else { + log.Printf("Game server restarted successfully") + } } else { - log.Printf("Game server restarted successfully") + // 执行启动命令 + log.Printf("启动命令: %s %s", exePath, strings.Join(args, " ")) + + cmd := exec.Command(exePath, args...) + cmd.Dir = config.GamePath // 设置工作目录为游戏路径 + + // 启动进程 + if err := cmd.Start(); err != nil { + log.Printf("Failed to restart game server: %v", err) + } else { + log.Printf("Game server restarted successfully") + } + + // 获取并打印 PID + log.Printf("Game server started successfully with PID %d", cmd.Process.Pid) + status.SetGlobalPid(cmd.Process.Pid) } - // 获取并打印 PID - log.Printf("Game server started successfully with PID %d", cmd.Process.Pid) - status.SetGlobalPid(cmd.Process.Pid) - } diff --git a/sys/restart_windows.go b/sys/restart_windows.go index 06ee08d..a384141 100644 --- a/sys/restart_windows.go +++ b/sys/restart_windows.go @@ -4,6 +4,7 @@ package sys import ( + "bytes" "fmt" "log" "os" @@ -224,23 +225,26 @@ func RestartService(config config.Config) { } //exePath = filepath.Join(config.GamePath, "Pal", "Binaries", "Win64", "PalServerInject.exe") //只要文件存在就会自动注入,无需PalServerInject.exe了 - exePath = filepath.Join(config.GamePath, "Pal", "Binaries", "Win64", "PalServer-Win64-Test-Cmd.exe") + + } else { + //在这里加一个CheckAndWriteFiles的删除版本(因为只要文件存在就会自动注入) + err := mod.RemoveEmbeddedFiles(filepath.Join(config.GamePath, "Pal", "Binaries", "Win64")) + if err != nil { + log.Printf("Failed to remove files: %v", err) + return + } + } + //自由选择有字版 无字版 + if config.UsePalServerExe { + exePath = filepath.Join(config.GamePath, "PalServer.exe") args = []string{ - "Pal", "-RconEnabled=True", fmt.Sprintf("-AdminPassword=%s", config.WorldSettings.AdminPassword), fmt.Sprintf("-port=%d", config.WorldSettings.PublicPort), fmt.Sprintf("-players=%d", config.WorldSettings.ServerPlayerMaxNum), } } else { - err := mod.RemoveEmbeddedFiles(filepath.Join(config.GamePath, "Pal", "Binaries", "Win64")) - if err != nil { - log.Printf("Failed to remove files: %v", err) - return - } - //在这里加一个CheckAndWriteFiles的删除版本(因为只要文件存在就会自动注入) exePath = filepath.Join(config.GamePath, "Pal", "Binaries", "Win64", "PalServer-Win64-Test-Cmd.exe") - //exePath = "\"" + exePath + "\"" args = []string{ "Pal", "-RconEnabled=True", @@ -290,8 +294,53 @@ func RestartService(config config.Config) { // 获取并打印 PID log.Printf("Game server started successfully with PID %d", cmd.Process.Pid) - status.SetGlobalPid(cmd.Process.Pid) + //使用PalServer.exe启动获取到的pid不一致 + if config.UsePalServerExe { + // PowerShell脚本模板 + psScript := ` + $processName = "%s" + $configGamePath = "%s" + $matchingProcesses = Get-WmiObject Win32_Process | Where-Object { $_.Name -eq $processName } + foreach ($process in $matchingProcesses) { + $commandLine = $process.CommandLine + if ($commandLine -and $commandLine.Contains($configGamePath)) { + Write-Output $process.ProcessId + break + } + } + ` + // 使用config.GamePath和processName填充PowerShell脚本模板 + psScriptFormatted := fmt.Sprintf(psScript, "PalServer-Win64-Test-Cmd.exe", config.GamePath) + + // 调用PowerShell执行脚本 + cmd := exec.Command("powershell", "-Command", psScriptFormatted) + var out bytes.Buffer + cmd.Stdout = &out + err := cmd.Run() + if err != nil { + fmt.Println("Failed to execute PowerShell script:", err) + return + } + + output := strings.TrimSpace(out.String()) + if output == "" { + fmt.Println("No matching process found") + return + } + fmt.Println("Matching Real Server PID:", output) + + // 将output字符串转换为int + pid, err := strconv.Atoi(output) + if err != nil { + fmt.Println("Error converting PID from string to int:", err) + return + } + + status.SetGlobalPid(pid) + } else { + status.SetGlobalPid(cmd.Process.Pid) + } } // ConfigureUE4DebugSettings 根据config.EnableUe4Debug的值配置UE4SS-settings.ini文件 diff --git a/webui/dist2/index.html b/webui/dist2/index.html index 02092f6..7425c29 100644 --- a/webui/dist2/index.html +++ b/webui/dist2/index.html @@ -1,18 +1,18 @@ - - - - - - - - Palworld Server Configuration Generator - - - - - -
- - - + + + + + + + + Palworld Server Configuration Generator + + + + + +
+ + + \ No newline at end of file