Skip to content

Commit

Permalink
servctrl: added StopServerAllowKill
Browse files Browse the repository at this point in the history
if StopServerAllowKill is more than 0, then the specified number is the amount of seconds given to the minecraft server to go offline, after which it is killed
  • Loading branch information
gekigek99 committed May 18, 2021
1 parent bd6e6b3 commit 341335a
Show file tree
Hide file tree
Showing 6 changed files with 51 additions and 8 deletions.
9 changes: 6 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ How to use:
- FileName
- StartServer
- StopServer
- \* StopServerAllowKill
- \* HibernationInfo and StartingInfo
- \* TimeBeforeStoppingEmptyServer
- \* CheckForUpdates
Expand Down Expand Up @@ -69,10 +70,12 @@ Location of server folder and executable:
Commands to start and stop minecraft server:
```yaml
"Commands":{
"StartServer": "java {-Xmx1024M} {-Xms1024M} -jar serverFileName nogui",
"StopServer": "{stop}"
"StartServer": "java {-Xmx1024M} {-Xms1024M} -jar serverFileName nogui",
"StopServer": "{stop}",
"StopServerAllowKill": 10
}

# if StopServerAllowKill is more than 0, then the specified number is the amount of seconds
# given to the minecraft server to go offline, after which it is killed
```
Hibernation and warming up server description
```yaml
Expand Down
3 changes: 2 additions & 1 deletion config.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,8 @@
},
"Commands":{
"StartServer": "java {-Xmx1024M} {-Xms1024M} -jar serverFileName nogui",
"StopServer": "{stop}"
"StopServer": "{stop}",
"StopServerAllowKill": 10
},
"Msh":{
"Port": "25555",
Expand Down
1 change: 1 addition & 0 deletions info.txt
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
- functions containing "[goroutine]" in their comment are meant to be launched as goroutine
- functions containing "[goroutine]" in their comment will return without any parameter
- functions containing "[blocking]" in their comment should not be launched as goroutine
- functions containing "[non-blocking]" in their comment execute commands in a non-blocking manner
+ error management
- every function should return the error parameter
exception for:
Expand Down
5 changes: 3 additions & 2 deletions lib/confctrl/confctrl.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,9 @@ type configuration struct {
Version string `json:"Version"`
} `json:"Server"`
Commands struct {
StartServer string `json:"StartServer"`
StopServer string `json:"StopServer"`
StartServer string `json:"StartServer"`
StopServer string `json:"StopServer"`
StopServerAllowSIGINT int `json:"StopServerAllowSIGINT"`
} `json:"Commands"`
Msh struct {
CheckForUpdates bool `json:"CheckForUpdates"`
Expand Down
1 change: 1 addition & 0 deletions lib/servctrl/cmd.go
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ func CmdStart(dir, command string) error {
}

// Execute executes a command on the specified term
// [non-blocking]
func (term *ServTerm) Execute(command, origin string) (string, error) {
if !term.IsActive {
return "", fmt.Errorf("Execute: terminal not active")
Expand Down
40 changes: 38 additions & 2 deletions lib/servctrl/servctrl.go
Original file line number Diff line number Diff line change
Expand Up @@ -64,20 +64,27 @@ func StopMinecraftServer(playersCheck bool) error {
return fmt.Errorf("stopEmptyMinecraftServer: error executing minecraft server stop command: %v", errExec)
}

// if sigint is allowed, launch a function to check the shutdown of minecraft server
if confctrl.Config.Commands.StopServerAllowSIGINT > 0 {
go sigintMinecraftServerIfOnlineAfterTimeout()
}

// if a player check was not executed and the server is stopping make this function blocking until server is down
if !playersCheck {
if ServStats.Status == "stopping" {
// wait for the terminal to exit
// wait for the terminal to exit then return
debugctrl.Logln("waiting for server terminal to exit")
ServTerminal.Wg.Wait()
} else {
debugctrl.Logln("server was not stopped by stop command, world save might be compromised")
return fmt.Errorf("stopEmptyMinecraftServer: stop command does not seem to be stopping server (no playersCheck)")
}
}

return nil
}

// RequestStopMinecraftServer increases stopInstances by one and starts the timer to execute stopEmptyMinecraftServer(false)
// [goroutine]
func RequestStopMinecraftServer() {
asyncctrl.WithLock(func() { ServStats.StopInstances++ })

Expand All @@ -93,3 +100,32 @@ func RequestStopMinecraftServer() {
}
})
}

// sigintMinecraftServerIfOnlineAfterTimeout waits for the specified time and then if the server is still online sends SIGINT to the process
func sigintMinecraftServerIfOnlineAfterTimeout() {
countdown := confctrl.Config.Commands.StopServerAllowSIGINT

for countdown > 0 {
// if server goes offline it's the correct behaviour -> return
if ServStats.Status == "offline" {
return
}

countdown--
time.Sleep(time.Second)
}

// save world before killing the server, do not check for errors
debugctrl.Logln("saving word before killing the minecraft server process")
_, _ = ServTerminal.Execute("/save-all", "sigintMinecraftServerIfOnlineAfterTimeout")

// give time to save word
time.Sleep(time.Duration(10) * time.Second)

// send kill signal to server
debugctrl.Logln("send kill signal to minecraft server process since it won't stop normally")
err := ServTerminal.cmd.Process.Kill()
if err != nil {
debugctrl.Logln("sigintMinecraftServerIfOnlineAfterTimeout: %v", err)
}
}

0 comments on commit 341335a

Please sign in to comment.