From 0048a871d743cb29f1b479068038b3fa8d5540be Mon Sep 17 00:00:00 2001 From: Jens van de Wiel <85284773+JensvandeWiel@users.noreply.github.com> Date: Wed, 22 Nov 2023 14:20:42 +0100 Subject: [PATCH] Added auto restart on quit (#135) * fixed value like 0.1 * initial working --- frontend/src/pages/Server.tsx | 33 ++++- frontend/src/pages/server/Multipliers.tsx | 144 +++++++++++----------- go.mod | 4 +- go.sum | 10 +- server/helpers.go | 63 ++++++++++ server/server.go | 69 +++++------ server/server_controller.go | 24 ++-- 7 files changed, 218 insertions(+), 129 deletions(-) diff --git a/frontend/src/pages/Server.tsx b/frontend/src/pages/Server.tsx index 8f73aaa..d821ffc 100644 --- a/frontend/src/pages/Server.tsx +++ b/frontend/src/pages/Server.tsx @@ -79,9 +79,35 @@ export const Server = ({id, className}: Props) => { }, [serv]); useEffect(() => { - EventsOn("onServerExit", () => setServerStatus(false)) + EventsOn("onServerExit", (id) => { + if (id === serv.id) { + console.log("server stopped") + setServerStatus(false) + } + }) return () => EventsOff("onServerExit") }, []); + useEffect(() => { + EventsOn("onServerStart", (id) => { + if (id === serv.id) { + console.log("server started") + setServerStatus(true) + } + }) + return () => EventsOff("onServerStart") + }, []); + useEffect(() => { + EventsOn("RestartServer", (id) => { + StartServer(id).catch((err) => {addAlert(err, "danger"); console.error(err)}).then(() => setTimeout(function () { + GetServerStatus(id).catch((reason) => {console.error("serverstatus: " + reason); addAlert(reason, "danger")}).then((s) => { + if (typeof s === "boolean") { + setServerStatus(s) + } + }) + }, 200)) + }) + return () => EventsOff("RestartServer") + }, []); useEffect(() => { if (serv.id >= 0) { @@ -125,13 +151,14 @@ export const Server = ({id, className}: Props) => { function startServer() { StartServer(serv.id).catch((err) => {addAlert(err, "danger"); console.error(err)}).then(() => setTimeout(function () { - refreshServerStatus() + setServerStatus(true) + //refreshServerStatus() }, 200)) } function onServerStopButtonClicked() { addAlert("Stopping server...", "neutral") - StopServer(serv.id).then(() => addAlert("Stopped server", "success")).catch((err) => addAlert("error stopping server: " + err, "danger")); + StopServer(serv.id).then(() => {addAlert("Stopped server", "success"); setServerStatus(false)}).catch((err) => addAlert("error stopping server: " + err, "danger")); } function onServerForceStopButtonClicked() { diff --git a/frontend/src/pages/server/Multipliers.tsx b/frontend/src/pages/server/Multipliers.tsx index 30c95cb..f8c659f 100644 --- a/frontend/src/pages/server/Multipliers.tsx +++ b/frontend/src/pages/server/Multipliers.tsx @@ -31,7 +31,7 @@ function GeneralMultipliers({ setServ, serv }: {setServ: React.Dispatch { - if (v >= 0) { + if (v >= 0.0000001) { setServ((p) => { const newState = {...p, convertValues: p.convertValues}; newState.gameUserSettings.serverSettings.itemStackSizeMultiplier = v; @@ -50,7 +50,7 @@ function GeneralMultipliers({ setServ, serv }: {setServ: React.Dispatch { - if (v >= 0) { + if (v >= 0.0000001) { setServ((p) => { const newState = {...p, convertValues: p.convertValues}; newState.gameUserSettings.serverSettings.xPMultiplier = v; @@ -69,7 +69,7 @@ function GeneralMultipliers({ setServ, serv }: {setServ: React.Dispatch { - if (v >= 0) { + if (v >= 0.0000001) { setServ((p) => { const newState = {...p, convertValues: p.convertValues}; newState.game.ScriptShootergameShootergamemode.baseTemperatureMultiplier = v; @@ -88,7 +88,7 @@ function GeneralMultipliers({ setServ, serv }: {setServ: React.Dispatch { - if (v >= 0) { + if (v >= 0.0000001) { setServ((p) => { const newState = {...p, convertValues: p.convertValues}; newState.game.ScriptShootergameShootergamemode.cropDecaySpeedMultiplier = v; @@ -107,7 +107,7 @@ function GeneralMultipliers({ setServ, serv }: {setServ: React.Dispatch { - if (v >= 0) { + if (v >= 0.0000001) { setServ((p) => { const newState = {...p, convertValues: p.convertValues}; newState.game.ScriptShootergameShootergamemode.cropGrowthSpeedMultiplier = v; @@ -126,7 +126,7 @@ function GeneralMultipliers({ setServ, serv }: {setServ: React.Dispatch { - if (v >= 0) { + if (v >= 0.0000001) { setServ((p) => { const newState = {...p, convertValues: p.convertValues}; newState.game.ScriptShootergameShootergamemode.customRecipeEffectivenessMultiplier = v; @@ -145,7 +145,7 @@ function GeneralMultipliers({ setServ, serv }: {setServ: React.Dispatch { - if (v >= 0) { + if (v >= 0.0000001) { setServ((p) => { const newState = {...p, convertValues: p.convertValues}; newState.game.ScriptShootergameShootergamemode.customRecipeEffectivenessMultiplier = v; @@ -164,7 +164,7 @@ function GeneralMultipliers({ setServ, serv }: {setServ: React.Dispatch { - if (v >= 0) { + if (v >= 0.0000001) { setServ((p) => { const newState = {...p, convertValues: p.convertValues}; newState.game.ScriptShootergameShootergamemode.customRecipeSkillMultiplier = v; @@ -183,7 +183,7 @@ function GeneralMultipliers({ setServ, serv }: {setServ: React.Dispatch { - if (v >= 0) { + if (v >= 0.0000001) { setServ((p) => { const newState = {...p, convertValues: p.convertValues}; newState.game.ScriptShootergameShootergamemode.fishingLootQualityMultiplier = v; @@ -202,7 +202,7 @@ function GeneralMultipliers({ setServ, serv }: {setServ: React.Dispatch { - if (v >= 0) { + if (v >= 0.0000001) { setServ((p) => { const newState = {...p, convertValues: p.convertValues}; newState.game.ScriptShootergameShootergamemode.fuelConsumptionIntervalMultiplier = v; @@ -221,7 +221,7 @@ function GeneralMultipliers({ setServ, serv }: {setServ: React.Dispatch { - if (v >= 0) { + if (v >= 0.0000001) { setServ((p) => { const newState = {...p, convertValues: p.convertValues}; newState.game.ScriptShootergameShootergamemode.genericXPMultiplier = v; @@ -240,7 +240,7 @@ function GeneralMultipliers({ setServ, serv }: {setServ: React.Dispatch { - if (v >= 0) { + if (v >= 0.0000001) { setServ((p) => { const newState = {...p, convertValues: p.convertValues}; newState.game.ScriptShootergameShootergamemode.globalCorpseDecompositionTimeMultiplier = v; @@ -259,7 +259,7 @@ function GeneralMultipliers({ setServ, serv }: {setServ: React.Dispatch { - if (v >= 0) { + if (v >= 0.0000001) { setServ((p) => { const newState = {...p, convertValues: p.convertValues}; newState.game.ScriptShootergameShootergamemode.globalItemDecompositionTimeMultiplier = v; @@ -278,7 +278,7 @@ function GeneralMultipliers({ setServ, serv }: {setServ: React.Dispatch { - if (v >= 0) { + if (v >= 0.0000001) { setServ((p) => { const newState = {...p, convertValues: p.convertValues}; newState.game.ScriptShootergameShootergamemode.globalSpoilingTimeMultiplier = v; @@ -297,7 +297,7 @@ function GeneralMultipliers({ setServ, serv }: {setServ: React.Dispatch { - if (v >= 0) { + if (v >= 0.0000001) { setServ((p) => { const newState = {...p, convertValues: p.convertValues}; newState.game.ScriptShootergameShootergamemode.increasePvPRespawnIntervalMultiplier = v; @@ -316,7 +316,7 @@ function GeneralMultipliers({ setServ, serv }: {setServ: React.Dispatch { - if (v >= 0) { + if (v >= 0.0000001) { setServ((p) => { const newState = {...p, convertValues: p.convertValues}; newState.game.ScriptShootergameShootergamemode.killXPMultiplier = v; @@ -335,7 +335,7 @@ function GeneralMultipliers({ setServ, serv }: {setServ: React.Dispatch { - if (v >= 0) { + if (v >= 0.0000001) { setServ((p) => { const newState = {...p, convertValues: p.convertValues}; newState.game.ScriptShootergameShootergamemode.maxFallSpeedMultiplier = v; @@ -354,7 +354,7 @@ function GeneralMultipliers({ setServ, serv }: {setServ: React.Dispatch { - if (v >= 0) { + if (v >= 0.0000001) { setServ((p) => { const newState = {...p, convertValues: p.convertValues}; newState.game.ScriptShootergameShootergamemode.specialXPMultiplier = v; @@ -373,7 +373,7 @@ function GeneralMultipliers({ setServ, serv }: {setServ: React.Dispatch { - if (v >= 0) { + if (v >= 0.0000001) { setServ((p) => { const newState = {...p, convertValues: p.convertValues}; newState.game.ScriptShootergameShootergamemode.supplyCrateLootQualityMultiplier = v; @@ -392,7 +392,7 @@ function GeneralMultipliers({ setServ, serv }: {setServ: React.Dispatch { - if (v >= 0) { + if (v >= 0.0000001) { setServ((p) => { const newState = {...p, convertValues: p.convertValues}; newState.game.ScriptShootergameShootergamemode.useCorpseLifeSpanMultiplier = v; @@ -411,7 +411,7 @@ function GeneralMultipliers({ setServ, serv }: {setServ: React.Dispatch { - if (v >= 0) { + if (v >= 0.0000001) { setServ((p) => { const newState = {...p, convertValues: p.convertValues}; newState.gameUserSettings.serverSettings.perPlatformMaxStructuresMultiplier = v; @@ -430,7 +430,7 @@ function GeneralMultipliers({ setServ, serv }: {setServ: React.Dispatch { - if (v >= 0) { + if (v >= 0.0000001) { setServ((p) => { const newState = {...p, convertValues: p.convertValues}; newState.gameUserSettings.serverSettings.pveStructureDecayPeriodMultiplier = v; @@ -462,7 +462,7 @@ function DinoMultipliers({ setServ, serv }: {setServ: React.Dispatch { - if (v >= 0) { + if (v >= 0.0000001) { setServ((p) => { const newState = {...p, convertValues: p.convertValues}; newState.gameUserSettings.serverSettings.dinoCharacterFoodDrainMultiplier = v; @@ -481,7 +481,7 @@ function DinoMultipliers({ setServ, serv }: {setServ: React.Dispatch { - if (v >= 0) { + if (v >= 0.0000001) { setServ((p) => { const newState = {...p, convertValues: p.convertValues}; newState.gameUserSettings.serverSettings.dinoCharacterFoodDrainMultiplier = v; @@ -500,7 +500,7 @@ function DinoMultipliers({ setServ, serv }: {setServ: React.Dispatch { - if (v >= 0) { + if (v >= 0.0000001) { setServ((p) => { const newState = {...p, convertValues: p.convertValues}; newState.gameUserSettings.serverSettings.dinoCharacterHealthRecoveryMultiplier = v; @@ -519,7 +519,7 @@ function DinoMultipliers({ setServ, serv }: {setServ: React.Dispatch { - if (v >= 0) { + if (v >= 0.0000001) { setServ((p) => { const newState = {...p, convertValues: p.convertValues}; newState.gameUserSettings.serverSettings.dinoCharacterStaminaDrainMultiplier = v; @@ -538,7 +538,7 @@ function DinoMultipliers({ setServ, serv }: {setServ: React.Dispatch { - if (v >= 0) { + if (v >= 0.0000001) { setServ((p) => { const newState = {...p, convertValues: p.convertValues}; newState.gameUserSettings.serverSettings.dinoCountMultiplier = v; @@ -557,7 +557,7 @@ function DinoMultipliers({ setServ, serv }: {setServ: React.Dispatch { - if (v >= 0) { + if (v >= 0.0000001) { setServ((p) => { const newState = {...p, convertValues: p.convertValues}; newState.gameUserSettings.serverSettings.dinoDamageMultiplier = v; @@ -576,7 +576,7 @@ function DinoMultipliers({ setServ, serv }: {setServ: React.Dispatch { - if (v >= 0) { + if (v >= 0.0000001) { setServ((p) => { const newState = {...p, convertValues: p.convertValues}; newState.gameUserSettings.serverSettings.raidDinoCharacterFoodDrainMultiplier = v; @@ -595,7 +595,7 @@ function DinoMultipliers({ setServ, serv }: {setServ: React.Dispatch { - if (v >= 0) { + if (v >= 0.0000001) { setServ((p) => { const newState = {...p, convertValues: p.convertValues}; newState.gameUserSettings.serverSettings.tamedDinoDamageMultiplier = v; @@ -614,7 +614,7 @@ function DinoMultipliers({ setServ, serv }: {setServ: React.Dispatch { - if (v >= 0) { + if (v >= 0.0000001) { setServ((p) => { const newState = {...p, convertValues: p.convertValues}; newState.gameUserSettings.serverSettings.tamedDinoResistanceMultiplier = v; @@ -633,7 +633,7 @@ function DinoMultipliers({ setServ, serv }: {setServ: React.Dispatch { - if (v >= 0) { + if (v >= 0.0000001) { setServ((p) => { const newState = {...p, convertValues: p.convertValues}; newState.gameUserSettings.serverSettings.tamingSpeedMultiplier = v; @@ -652,7 +652,7 @@ function DinoMultipliers({ setServ, serv }: {setServ: React.Dispatch { - if (v >= 0) { + if (v >= 0.0000001) { setServ((p) => { const newState = {...p, convertValues: p.convertValues}; newState.game.ScriptShootergameShootergamemode.babyCuddleGracePeriodMultiplier = v; @@ -671,7 +671,7 @@ function DinoMultipliers({ setServ, serv }: {setServ: React.Dispatch { - if (v >= 0) { + if (v >= 0.0000001) { setServ((p) => { const newState = {...p, convertValues: p.convertValues}; newState.game.ScriptShootergameShootergamemode.babyCuddleIntervalMultiplier = v; @@ -690,7 +690,7 @@ function DinoMultipliers({ setServ, serv }: {setServ: React.Dispatch { - if (v >= 0) { + if (v >= 0.0000001) { setServ((p) => { const newState = {...p, convertValues: p.convertValues}; newState.game.ScriptShootergameShootergamemode.babyCuddleLoseImprintQualitySpeedMultiplier = v; @@ -709,7 +709,7 @@ function DinoMultipliers({ setServ, serv }: {setServ: React.Dispatch { - if (v >= 0) { + if (v >= 0.0000001) { setServ((p) => { const newState = {...p, convertValues: p.convertValues}; newState.game.ScriptShootergameShootergamemode.babyFoodConsumptionSpeedMultiplier = v; @@ -728,7 +728,7 @@ function DinoMultipliers({ setServ, serv }: {setServ: React.Dispatch { - if (v >= 0) { + if (v >= 0.0000001) { setServ((p) => { const newState = {...p, convertValues: p.convertValues}; newState.game.ScriptShootergameShootergamemode.babyImprintAmountMultiplier = v; @@ -747,7 +747,7 @@ function DinoMultipliers({ setServ, serv }: {setServ: React.Dispatch { - if (v >= 0) { + if (v >= 0.0000001) { setServ((p) => { const newState = {...p, convertValues: p.convertValues}; newState.game.ScriptShootergameShootergamemode.babyImprintingStatScaleMultiplier = v; @@ -766,7 +766,7 @@ function DinoMultipliers({ setServ, serv }: {setServ: React.Dispatch { - if (v >= 0) { + if (v >= 0.0000001) { setServ((p) => { const newState = {...p, convertValues: p.convertValues}; newState.game.ScriptShootergameShootergamemode.babyMatureSpeedMultiplier = v; @@ -785,7 +785,7 @@ function DinoMultipliers({ setServ, serv }: {setServ: React.Dispatch { - if (v >= 0) { + if (v >= 0.0000001) { setServ((p) => { const newState = {...p, convertValues: p.convertValues}; newState.game.ScriptShootergameShootergamemode.dinoHarvestingDamageMultiplier = v; @@ -804,7 +804,7 @@ function DinoMultipliers({ setServ, serv }: {setServ: React.Dispatch { - if (v >= 0) { + if (v >= 0.0000001) { setServ((p) => { const newState = {...p, convertValues: p.convertValues}; newState.game.ScriptShootergameShootergamemode.dinoTurretDamageMultiplier = v; @@ -823,7 +823,7 @@ function DinoMultipliers({ setServ, serv }: {setServ: React.Dispatch { - if (v >= 0) { + if (v >= 0.0000001) { setServ((p) => { const newState = {...p, convertValues: p.convertValues}; newState.game.ScriptShootergameShootergamemode.eggHatchSpeedMultiplier = v; @@ -842,7 +842,7 @@ function DinoMultipliers({ setServ, serv }: {setServ: React.Dispatch { - if (v >= 0) { + if (v >= 0.0000001) { setServ((p) => { const newState = {...p, convertValues: p.convertValues}; newState.game.ScriptShootergameShootergamemode.layEggIntervalMultiplier = v; @@ -861,7 +861,7 @@ function DinoMultipliers({ setServ, serv }: {setServ: React.Dispatch { - if (v >= 0) { + if (v >= 0.0000001) { setServ((p) => { const newState = {...p, convertValues: p.convertValues}; newState.game.ScriptShootergameShootergamemode.matingIntervalMultiplier = v; @@ -880,7 +880,7 @@ function DinoMultipliers({ setServ, serv }: {setServ: React.Dispatch { - if (v >= 0) { + if (v >= 0.0000001) { setServ((p) => { const newState = {...p, convertValues: p.convertValues}; newState.game.ScriptShootergameShootergamemode.matingSpeedMultiplier = v; @@ -899,7 +899,7 @@ function DinoMultipliers({ setServ, serv }: {setServ: React.Dispatch { - if (v >= 0) { + if (v >= 0.0000001) { setServ((p) => { const newState = {...p, convertValues: p.convertValues}; newState.game.ScriptShootergameShootergamemode.passiveTameIntervalMultiplier = v; @@ -918,7 +918,7 @@ function DinoMultipliers({ setServ, serv }: {setServ: React.Dispatch { - if (v >= 0) { + if (v >= 0.0000001) { setServ((p) => { const newState = {...p, convertValues: p.convertValues}; newState.game.ScriptShootergameShootergamemode.tamedDinoCharacterFoodDrainMultiplier = v; @@ -937,7 +937,7 @@ function DinoMultipliers({ setServ, serv }: {setServ: React.Dispatch { - if (v >= 0) { + if (v >= 0.0000001) { setServ((p) => { const newState = {...p, convertValues: p.convertValues}; newState.game.ScriptShootergameShootergamemode.tamedDinoTorporDrainMultiplier = v; @@ -956,7 +956,7 @@ function DinoMultipliers({ setServ, serv }: {setServ: React.Dispatch { - if (v >= 0) { + if (v >= 0.0000001) { setServ((p) => { const newState = {...p, convertValues: p.convertValues}; newState.game.ScriptShootergameShootergamemode.wildDinoCharacterFoodDrainMultiplier = v; @@ -975,7 +975,7 @@ function DinoMultipliers({ setServ, serv }: {setServ: React.Dispatch { - if (v >= 0) { + if (v >= 0.0000001) { setServ((p) => { const newState = {...p, convertValues: p.convertValues}; newState.game.ScriptShootergameShootergamemode.wildDinoTorporDrainMultiplier = v; @@ -1007,7 +1007,7 @@ function HarvestingMultipliers({ setServ, serv }: {setServ: React.Dispatch { - if (v >= 0) { + if (v >= 0.0000001) { setServ((p) => { const newState = {...p, convertValues: p.convertValues}; newState.gameUserSettings.serverSettings.harvestAmountMultiplier = v; @@ -1026,7 +1026,7 @@ function HarvestingMultipliers({ setServ, serv }: {setServ: React.Dispatch { - if (v >= 0) { + if (v >= 0.0000001) { setServ((p) => { const newState = {...p, convertValues: p.convertValues}; newState.gameUserSettings.serverSettings.harvestHealthMultiplier = v; @@ -1045,7 +1045,7 @@ function HarvestingMultipliers({ setServ, serv }: {setServ: React.Dispatch { - if (v >= 0) { + if (v >= 0.0000001) { setServ((p) => { const newState = {...p, convertValues: p.convertValues}; newState.gameUserSettings.serverSettings.resourcesRespawnPeriodMultiplier = v; @@ -1064,7 +1064,7 @@ function HarvestingMultipliers({ setServ, serv }: {setServ: React.Dispatch { - if (v >= 0) { + if (v >= 0.0000001) { setServ((p) => { const newState = {...p, convertValues: p.convertValues}; newState.game.ScriptShootergameShootergamemode.harvestXPMultiplier = v; @@ -1096,7 +1096,7 @@ function PlayerMultipliers({ setServ, serv }: {setServ: React.Dispatch { - if (v >= 0) { + if (v >= 0.0000001) { setServ((p) => { const newState = {...p, convertValues: p.convertValues}; newState.gameUserSettings.serverSettings.oxygenSwimSpeedStatMultiplier = v; @@ -1115,7 +1115,7 @@ function PlayerMultipliers({ setServ, serv }: {setServ: React.Dispatch { - if (v >= 0) { + if (v >= 0.0000001) { setServ((p) => { const newState = {...p, convertValues: p.convertValues}; newState.gameUserSettings.serverSettings.playerCharacterFoodDrainMultiplier = v; @@ -1134,7 +1134,7 @@ function PlayerMultipliers({ setServ, serv }: {setServ: React.Dispatch { - if (v >= 0) { + if (v >= 0.0000001) { setServ((p) => { const newState = {...p, convertValues: p.convertValues}; newState.gameUserSettings.serverSettings.playerCharacterHealthRecoveryMultiplier = v; @@ -1153,7 +1153,7 @@ function PlayerMultipliers({ setServ, serv }: {setServ: React.Dispatch { - if (v >= 0) { + if (v >= 0.0000001) { setServ((p) => { const newState = {...p, convertValues: p.convertValues}; newState.gameUserSettings.serverSettings.playerCharacterStaminaDrainMultiplier = v; @@ -1172,7 +1172,7 @@ function PlayerMultipliers({ setServ, serv }: {setServ: React.Dispatch { - if (v >= 0) { + if (v >= 0.0000001) { setServ((p) => { const newState = {...p, convertValues: p.convertValues}; newState.gameUserSettings.serverSettings.playerCharacterWaterDrainMultiplier = v; @@ -1191,7 +1191,7 @@ function PlayerMultipliers({ setServ, serv }: {setServ: React.Dispatch { - if (v >= 0) { + if (v >= 0.0000001) { setServ((p) => { const newState = {...p, convertValues: p.convertValues}; newState.gameUserSettings.serverSettings.playerDamageMultiplier = v; @@ -1210,7 +1210,7 @@ function PlayerMultipliers({ setServ, serv }: {setServ: React.Dispatch { - if (v >= 0) { + if (v >= 0.0000001) { setServ((p) => { const newState = {...p, convertValues: p.convertValues}; newState.gameUserSettings.serverSettings.playerResistanceMultiplier = v; @@ -1229,7 +1229,7 @@ function PlayerMultipliers({ setServ, serv }: {setServ: React.Dispatch { - if (v >= 0) { + if (v >= 0.0000001) { setServ((p) => { const newState = {...p, convertValues: p.convertValues}; newState.game.ScriptShootergameShootergamemode.craftingSkillBonusMultiplier = v; @@ -1248,7 +1248,7 @@ function PlayerMultipliers({ setServ, serv }: {setServ: React.Dispatch { - if (v >= 0) { + if (v >= 0.0000001) { setServ((p) => { const newState = {...p, convertValues: p.convertValues}; newState.game.ScriptShootergameShootergamemode.craftXPMultiplier = v; @@ -1267,7 +1267,7 @@ function PlayerMultipliers({ setServ, serv }: {setServ: React.Dispatch { - if (v >= 0) { + if (v >= 0.0000001) { setServ((p) => { const newState = {...p, convertValues: p.convertValues}; newState.game.ScriptShootergameShootergamemode.hairGrowthSpeedMultiplier = v; @@ -1286,7 +1286,7 @@ function PlayerMultipliers({ setServ, serv }: {setServ: React.Dispatch { - if (v >= 0) { + if (v >= 0.0000001) { setServ((p) => { const newState = {...p, convertValues: p.convertValues}; newState.game.ScriptShootergameShootergamemode.playerHarvestingDamageMultiplier = v; @@ -1305,7 +1305,7 @@ function PlayerMultipliers({ setServ, serv }: {setServ: React.Dispatch { - if (v >= 0) { + if (v >= 0.0000001) { setServ((p) => { const newState = {...p, convertValues: p.convertValues}; newState.game.ScriptShootergameShootergamemode.poopIntervalMultiplier = v; @@ -1338,7 +1338,7 @@ function StructureBuildingMultipliers({ setServ, serv }: {setServ: React.Dispatc sliderMax={25} value={serv?.gameUserSettings.serverSettings.perPlatformMaxStructuresMultiplier} onChange={(v) => { - if (v >= 0) { + if (v >= 0.0000001) { setServ((p) => { const newState = {...p, convertValues: p.convertValues}; newState.gameUserSettings.serverSettings.perPlatformMaxStructuresMultiplier = v; @@ -1357,7 +1357,7 @@ function StructureBuildingMultipliers({ setServ, serv }: {setServ: React.Dispatc sliderMax={25} value={serv?.gameUserSettings.serverSettings.platformSaddleBuildAreaBoundsMultiplier} onChange={(v) => { - if (v >= 0) { + if (v >= 0.0000001) { setServ((p) => { const newState = {...p, convertValues: p.convertValues}; newState.gameUserSettings.serverSettings.platformSaddleBuildAreaBoundsMultiplier = v; @@ -1376,7 +1376,7 @@ function StructureBuildingMultipliers({ setServ, serv }: {setServ: React.Dispatc sliderMax={25} value={serv?.gameUserSettings.serverSettings.structureDamageMultiplier} onChange={(v) => { - if (v >= 0) { + if (v >= 0.0000001) { setServ((p) => { const newState = {...p, convertValues: p.convertValues}; newState.gameUserSettings.serverSettings.structureDamageMultiplier = v; @@ -1395,7 +1395,7 @@ function StructureBuildingMultipliers({ setServ, serv }: {setServ: React.Dispatc sliderMax={25} value={serv?.gameUserSettings.serverSettings.structurePreventResourceRadiusMultiplier} onChange={(v) => { - if (v >= 0) { + if (v >= 0.0000001) { setServ((p) => { const newState = {...p, convertValues: p.convertValues}; newState.gameUserSettings.serverSettings.structurePreventResourceRadiusMultiplier = v; @@ -1413,7 +1413,7 @@ function StructureBuildingMultipliers({ setServ, serv }: {setServ: React.Dispatc sliderMax={25} value={serv?.gameUserSettings.serverSettings.structureResistanceMultiplier} onChange={(v) => { - if (v >= 0) { + if (v >= 0.0000001) { setServ((p) => { const newState = {...p, convertValues: p.convertValues}; newState.gameUserSettings.serverSettings.structureResistanceMultiplier = v; @@ -1433,7 +1433,7 @@ function StructureBuildingMultipliers({ setServ, serv }: {setServ: React.Dispatc sliderMax={25} value={serv?.game.ScriptShootergameShootergamemode.pvPZoneStructureDamageMultiplier} onChange={(v) => { - if (v >= 0) { + if (v >= 0.0000001) { setServ((p) => { const newState = {...p, convertValues: p.convertValues}; newState.game.ScriptShootergameShootergamemode.pvPZoneStructureDamageMultiplier = v; diff --git a/go.mod b/go.mod index 02b3dd7..199299a 100644 --- a/go.mod +++ b/go.mod @@ -3,17 +3,17 @@ module github.com/JensvandeWiel/ArkAscendedServerManager go 1.18 require ( + github.com/StackExchange/wmi v1.2.1 github.com/adrg/xdg v0.4.0 github.com/go-ini/ini v1.67.0 github.com/gorcon/rcon v1.3.4 github.com/hashicorp/go-version v1.6.0 github.com/inconshreveable/go-update v0.0.0-20160112193335-8152e7eb6ccf github.com/jensvandewiel/gosteamcmd v0.1.2 - github.com/keybase/go-ps v0.0.0-20190827175125-91aafc93ba19 github.com/sethvargo/go-password v0.2.0 github.com/sqweek/dialog v0.0.0-20220809060634-e981b270ebbf github.com/wailsapp/wails/v2 v2.6.0 - golang.org/x/sys v0.13.0 + golang.org/x/sys v0.14.0 ) require ( diff --git a/go.sum b/go.sum index 0db804f..13e0ec5 100644 --- a/go.sum +++ b/go.sum @@ -1,3 +1,5 @@ +github.com/StackExchange/wmi v1.2.1 h1:VIkavFPXSjcnS+O8yTq7NI32k0R5Aj+v39y29VYDOSA= +github.com/StackExchange/wmi v1.2.1/go.mod h1:rcmrprowKIVzvc+NUiLncP2uuArMWLCbu9SBzvHz7e8= github.com/TheTitanrain/w32 v0.0.0-20180517000239-4f5cfb03fabf h1:FPsprx82rdrX2jiKyS17BH6IrTmUBYqZa/CXT4uvb+I= github.com/TheTitanrain/w32 v0.0.0-20180517000239-4f5cfb03fabf/go.mod h1:peYoMncQljjNS6tZwI9WVyQB3qZS6u79/N3mBOcnd3I= github.com/UserExistsError/conpty v0.1.1 h1:cHDsU/XeoeDAQmVvCTV53SrXLG39YJ4++Pp3iAi1gXE= @@ -11,6 +13,7 @@ github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/go-ini/ini v1.67.0 h1:z6ZrTEZqSWOTyH2FlglNbNgARyHG8oLW9gMELqKr06A= github.com/go-ini/ini v1.67.0/go.mod h1:ByCAeIL28uOIIG0E3PJtZPDL8WnHpFKFOtgjp+3Ies8= +github.com/go-ole/go-ole v1.2.5/go.mod h1:pprOEPIfldk/42T2oK7lQ4v4JSDwmV0As9GaiUsvbm0= github.com/go-ole/go-ole v1.3.0 h1:Dt6ye7+vXGIKZ7Xtk4s6/xVdGDQynvom7xCFEdWr6uE= github.com/go-ole/go-ole v1.3.0/go.mod h1:5LS6F96DhAwUc7C+1HLexzMXY1xGRSryjyPPKW6zv78= github.com/google/uuid v1.3.1 h1:KjJaJ9iWZ3jOFZIf1Lqf4laDRCasjl0BCmnEGxkdLb4= @@ -25,8 +28,6 @@ github.com/jchv/go-winloader v0.0.0-20210711035445-715c2860da7e h1:Q3+PugElBCf4P github.com/jchv/go-winloader v0.0.0-20210711035445-715c2860da7e/go.mod h1:alcuEEnZsY1WQsagKhZDsoPCRoOijYqhZvPwLG0kzVs= github.com/jensvandewiel/gosteamcmd v0.1.2 h1:NHichoj0v3GvSVN2Fn36dSOLosHAytpaKnLnDHTMQPI= github.com/jensvandewiel/gosteamcmd v0.1.2/go.mod h1:Y7hP+iXFIOs8II68VrbdR+W1wwpB8LXYe9lfgjyTLIw= -github.com/keybase/go-ps v0.0.0-20190827175125-91aafc93ba19 h1:WjT3fLi9n8YWh/Ih8Q1LHAPsTqGddPcHqscN+PJ3i68= -github.com/keybase/go-ps v0.0.0-20190827175125-91aafc93ba19/go.mod h1:hY+WOq6m2FpbvyrI93sMaypsttvaIL5nhVR92dTMUcQ= github.com/labstack/echo/v4 v4.11.2 h1:T+cTLQxWCDfqDEoydYm5kCobjmHwOwcv4OJAPHilmdE= github.com/labstack/echo/v4 v4.11.2/go.mod h1:UcGuQ8V6ZNRmSweBIJkPvGfwCMIlFmiqrPqiEBfPYws= github.com/labstack/gommon v0.4.0 h1:y7cvthEAEbU0yHOf4axH8ZG2NH8knB9iNSoTO8dyIk8= @@ -87,6 +88,7 @@ golang.org/x/exp v0.0.0-20231006140011-7918f672742d/go.mod h1:ldy0pHrwJyGW56pPQz golang.org/x/net v0.0.0-20210505024714-0287a6fb4125/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.17.0 h1:pVaXccu2ozPjCXewfr1S7xza/zcXTity9cCdXQYSjIM= golang.org/x/net v0.17.0/go.mod h1:NxSsAGuq816PNPmqtQdLE42eU2Fs7NoRIZrHJAlaCOE= +golang.org/x/sys v0.0.0-20190916202348-b4ddaad3f8a3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200810151505-1b9f1253b3ed/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -99,8 +101,8 @@ golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.13.0 h1:Af8nKPmuFypiUBjVoU9V20FiaFXOcuZI21p0ycVYYGE= -golang.org/x/sys v0.13.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.14.0 h1:Vz7Qs629MkJkGyHxUlRHizWJRG2j8fbQKjELVSNhy7Q= +golang.org/x/sys v0.14.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.13.0 h1:ablQoSUd0tRdKxZewP80B+BaqeKJuVhuRxj/dkrun3k= diff --git a/server/helpers.go b/server/helpers.go index 0812776..512c89a 100644 --- a/server/helpers.go +++ b/server/helpers.go @@ -2,11 +2,14 @@ package server import ( "fmt" + "github.com/StackExchange/wmi" "io" "io/ioutil" "net" "os" + "os/exec" "path/filepath" + runtime2 "runtime" "strconv" "strings" @@ -271,3 +274,63 @@ func ensureFilePath(filePath string) error { // File already exists return nil } + +type Win32_Process struct { + ProcessID uint32 + ExecutablePath *string +} + +func IsProcessRunningWithPath(processPath string) (bool, error) { + var processes []Win32_Process + + // Use WMI to query processes + query := "SELECT ProcessID, ExecutablePath FROM Win32_Process" + err := wmi.QueryNamespace(query, &processes, `root\CIMv2`) + if err != nil { + return false, err + } + + for _, process := range processes { + if process.ExecutablePath != nil && strings.EqualFold(filepath.Clean(filepath.FromSlash(*process.ExecutablePath)), filepath.Clean(filepath.FromSlash(processPath))) { + return true, nil + } + } + + return false, nil +} + +func GetProcessPid(processPath string) (uint32, error) { + var processes []Win32_Process + + // Use WMI to query processes + query := "SELECT ProcessID, ExecutablePath FROM Win32_Process" + err := wmi.QueryNamespace(query, &processes, `root\CIMv2`) + if err != nil { + return 0, err + } + + for _, process := range processes { + if process.ExecutablePath != nil && strings.EqualFold(filepath.Clean(filepath.FromSlash(*process.ExecutablePath)), filepath.Clean(filepath.FromSlash(processPath))) { + return process.ProcessID, nil + } + } + + return 0, nil +} + +func KillProcessUsingPid(pid uint32) error { + var cmd *exec.Cmd + + switch runtime2.GOOS { + case "windows": + cmd = exec.Command("taskkill", "/F", "/PID", strconv.FormatUint(uint64(pid), 10)) + default: + cmd = exec.Command("kill", "-9", strconv.FormatUint(uint64(pid), 10)) + } + + if err := cmd.Run(); err != nil { + return fmt.Errorf("failed to kill process: %v", err) + } + + return nil +} diff --git a/server/server.go b/server/server.go index cb2f31d..6097f68 100644 --- a/server/server.go +++ b/server/server.go @@ -11,16 +11,16 @@ import ( "time" "github.com/JensvandeWiel/ArkAscendedServerManager/helpers" - "github.com/keybase/go-ps" "github.com/wailsapp/wails/v2/pkg/runtime" ) // Server contains the server "stuff" type Server struct { - Command *exec.Cmd `json:"-"` - ctx context.Context - helpers *helpers.HelpersController + Command *exec.Cmd `json:"-"` + ctx context.Context + helpers *helpers.HelpersController + stopSignal chan bool //PREFERENCES @@ -127,13 +127,17 @@ func (s *Server) Start() error { } go func() { _ = s.Command.Wait() - runtime.EventsEmit(s.ctx, "onServerExit", s.Id) - if s.DiscordWebHookEnabled { - err := helpers.SendToDiscord(time.Now().Format(time.RFC822)+" ("+s.ServerAlias+") Server has stopped", s.DiscordWebHook) - if err != nil { - runtime.LogError(s.ctx, "Error sending message to discord: "+err.Error()) - } + + // Check if the server exited unexpectedly (not through Stop or ForceStop) + select { + case <-s.stopSignal: + // Server was intentionally stopped, do not restart + runtime.LogInfo(s.ctx, "Server was intentionally stopped. Not restarting.") + default: + // Restart the server + time.Sleep(2 * time.Second) + runtime.EventsEmit(s.ctx, "RestartServer", s.Id) } }() } @@ -156,14 +160,17 @@ func (s *Server) ForceStop() error { if s.Command.Process == nil { return fmt.Errorf("error stopping server: server is not running") } - if !s.IsServerRunning() { return fmt.Errorf("error stopping server: server is not running") } - err := s.Command.Process.Kill() - if err != nil { + if pid, err := GetProcessPid(path.Join(s.ServerPath, "ShooterGame\\Binaries\\Win64\\ArkAscendedServer.exe")); err != nil { return fmt.Errorf("error stopping server: %v", err) + } else { + err := KillProcessUsingPid(pid) + if err != nil { + return fmt.Errorf("error killing process: %v", err) + } } if s.DiscordWebHookEnabled { @@ -173,6 +180,8 @@ func (s *Server) ForceStop() error { } } + s.stopSignal <- true + return nil } @@ -187,47 +196,33 @@ func (s *Server) Stop() error { err := s.SaveWorld() if err != nil { - return err + return fmt.Errorf("error sending save world command: %v", err) } _, err = s.helpers.SendRconCommand("doexit", s.IpAddress, s.RCONPort, s.AdminPassword) if err != nil { - return err + return fmt.Errorf("error sending exit command: %v", err) } + s.stopSignal <- true + return nil } +//TODO BROKEN + // GetServerStatus returns the status of the server. func (s *Server) IsServerRunning() bool { - if s.Command == nil { - return false - } - - if s.Command.Process == nil { + //THIS CHECK IS ONLY HERE BECAUSE WE DO NOT OFFICIALY SUPPORT MANAGING SERVERS THAT ARE ALREADY STARTED (WILL BE POSSIBLE IN THE FUTURE) + if s.Command == nil || s.Command.Process == nil { return false } - // Retrieve a list of all processes. - processList, err := ps.Processes() + isRunning, err := IsProcessRunningWithPath(path.Join(s.ServerPath, "ShooterGame\\Binaries\\Win64\\ArkAscendedServer.exe")) if err != nil { return false } - - // Iterate through the list of processes and check if the specified PID exists. - processFound := false - for _, process := range processList { - if process.Pid() == s.Command.Process.Pid { - processFound = true - break - } - } - - if processFound { - return true - } else { - return false - } + return isRunning } // returns questionamrk arguments for the server and dash arguments for the server diff --git a/server/server_controller.go b/server/server_controller.go index a5a6316..9aad665 100644 --- a/server/server_controller.go +++ b/server/server_controller.go @@ -108,17 +108,7 @@ func (c *ServerController) SaveServer(server Server) error { //TODO Make sure oldserv members get passed over to new instance since frontend will change all members even Command (which should not be updated by the frontend) - oldServ, err := c.getServer(server.Id, true) - if err != nil { - newErr := fmt.Errorf("Error saving server: " + err.Error()) - runtime.LogError(c.ctx, newErr.Error()) - return newErr - } - - server.Command = oldServ.Command - server.ctx = c.ctx - - err = c.saveServer(&server) + err := c.saveServer(&server) if err != nil { newErr := fmt.Errorf("Error saving server: " + err.Error()) runtime.LogError(c.ctx, newErr.Error()) @@ -241,6 +231,8 @@ func (c *ServerController) getServerFromDir(id int, shouldReturnNew bool) (Serve return Server{}, fmt.Errorf("Parsing server instance failed: " + err.Error()) } + serv.stopSignal = make(chan bool) + return serv, nil } @@ -335,6 +327,16 @@ func (c *ServerController) saveServer(server *Server) error { if err := CheckIfServerCorrect(server); err != nil { return fmt.Errorf("Parsing server instance failed: " + err.Error()) } + oldServ, err := c.getServer(server.Id, true) + if err != nil { + newErr := fmt.Errorf("Error saving server: " + err.Error()) + runtime.LogError(c.ctx, newErr.Error()) + return newErr + } + + server.Command = oldServ.Command + server.ctx = c.ctx + server.stopSignal = oldServ.stopSignal c.Servers[server.Id] = server serverDir := path.Join(c.serverDir, strconv.Itoa(server.Id))