|
|
|
@ -2,11 +2,21 @@ package main
|
|
|
|
|
|
|
|
|
|
import ( |
|
|
|
|
"fmt" |
|
|
|
|
"io/ioutil" |
|
|
|
|
"os" |
|
|
|
|
"os/exec" |
|
|
|
|
"path/filepath" |
|
|
|
|
"strings" |
|
|
|
|
) |
|
|
|
|
|
|
|
|
|
func runGame(username, timestamp string) { |
|
|
|
|
// check if a lockfile exists
|
|
|
|
|
matches, _ := filepath.Glob(fmt.Sprintf("%s/user/%s/*lock*", config.NethackLauncher.HackDir, username)) |
|
|
|
|
if matches != nil { |
|
|
|
|
clearScreen() |
|
|
|
|
runtimeRecover(username) |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
exec.Command("stty", "-F", "/dev/tty", "echo", "-cbreak").Run() |
|
|
|
|
clearScreen() |
|
|
|
|
|
|
|
|
@ -29,3 +39,101 @@ func runGame(username, timestamp string) {
|
|
|
|
|
exec.Command("exit").Run() |
|
|
|
|
wg.Done() |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
func runtimeRecover(username string) { |
|
|
|
|
fmt.Printf(" %s\n", config.NethackLauncher.ServerDisplay) |
|
|
|
|
println("") |
|
|
|
|
println(" Existing lockfile found.") |
|
|
|
|
println(" This generally means that your last session crashed") |
|
|
|
|
println(" or you are logged in more than once.") |
|
|
|
|
println("") |
|
|
|
|
println(" What would you like to do with the lockfile?") |
|
|
|
|
println(" d) delete it and contiue to a new adventure") |
|
|
|
|
println(" r) recover it and continue your last adventure") |
|
|
|
|
println(" n) nothing at all and get this prompt again next time") |
|
|
|
|
println("") |
|
|
|
|
fmt.Printf(">> ") |
|
|
|
|
|
|
|
|
|
// disable input buffering
|
|
|
|
|
exec.Command("stty", "-F", "/dev/tty", "cbreak", "min", "1").Run() |
|
|
|
|
// do not display entered characters on the screen
|
|
|
|
|
exec.Command("stty", "-F", "/dev/tty", "-echo").Run() |
|
|
|
|
|
|
|
|
|
var b []byte = make([]byte, 1) |
|
|
|
|
for { |
|
|
|
|
os.Stdin.Read(b) |
|
|
|
|
switch string(b) { |
|
|
|
|
case "n": |
|
|
|
|
clearScreen() |
|
|
|
|
return |
|
|
|
|
case "r": |
|
|
|
|
// set user path to save file candidates
|
|
|
|
|
userPath := fmt.Sprintf("%s/user/%s/", config.NethackLauncher.HackDir, username) |
|
|
|
|
|
|
|
|
|
// read in all files
|
|
|
|
|
candidates, err := ioutil.ReadDir(userPath) |
|
|
|
|
if err != nil { |
|
|
|
|
fmt.Println(err) |
|
|
|
|
} |
|
|
|
|
var newestFile string |
|
|
|
|
var newestTime int64 = 0 |
|
|
|
|
for _, f := range candidates { |
|
|
|
|
// loop through save file candidates
|
|
|
|
|
if strings.Contains(f.Name(), "lock") { |
|
|
|
|
fi, err := os.Stat(userPath + f.Name()) |
|
|
|
|
if err != nil { |
|
|
|
|
fmt.Println(err) |
|
|
|
|
} |
|
|
|
|
currTime := fi.ModTime().Unix() |
|
|
|
|
if currTime > newestTime { |
|
|
|
|
newestTime = currTime |
|
|
|
|
newestFile = f.Name() |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// get prefix for latest file
|
|
|
|
|
latestFile := strings.Split(newestFile, ".") |
|
|
|
|
|
|
|
|
|
// run recover on file
|
|
|
|
|
out, err := exec.Command(config.NethackLauncher.RecoverBinary, "-d", fmt.Sprintf("%s/user/%s", config.NethackLauncher.HackDir, username), latestFile[0]).Output() |
|
|
|
|
if err != nil { |
|
|
|
|
fmt.Println(out) |
|
|
|
|
panic(err) |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// make sure save file exists before removing the extra locks
|
|
|
|
|
isEmpty, _ := checkDir(fmt.Sprintf("%s/user/%s/save/", config.NethackLauncher.HackDir, username)) |
|
|
|
|
if !isEmpty { |
|
|
|
|
// save file made it, clean up old cruft
|
|
|
|
|
files, err := filepath.Glob(fmt.Sprintf("%s/*lock*", userPath)) |
|
|
|
|
if err != nil { |
|
|
|
|
panic(err) |
|
|
|
|
} |
|
|
|
|
for _, f := range files { |
|
|
|
|
if err := os.Remove(f); err != nil { |
|
|
|
|
panic(err) |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
// alert user that the save file was recovered
|
|
|
|
|
println("") |
|
|
|
|
println(" Statefile was recovered successfully! (press enter to return)") |
|
|
|
|
fmt.Printf(">> ") |
|
|
|
|
} |
|
|
|
|
return |
|
|
|
|
case "d": |
|
|
|
|
// remove all lockfiles and continue
|
|
|
|
|
userPath := fmt.Sprintf("%s/user/%s/", config.NethackLauncher.HackDir, username) |
|
|
|
|
files, err := filepath.Glob(fmt.Sprintf("%s/*lock*", userPath)) |
|
|
|
|
if err != nil { |
|
|
|
|
panic(err) |
|
|
|
|
} |
|
|
|
|
for _, f := range files { |
|
|
|
|
if err := os.Remove(f); err != nil { |
|
|
|
|
panic(err) |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
return |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|