You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
126 lines
3.3 KiB
126 lines
3.3 KiB
package main |
|
|
|
import ( |
|
"bufio" |
|
"fmt" |
|
"io/ioutil" |
|
"os" |
|
"os/exec" |
|
"path/filepath" |
|
"strings" |
|
|
|
"gopkg.in/redis.v5" |
|
) |
|
|
|
func recoverSave(redisClient *redis.Client, username string) { |
|
// if no statefile exist, exit early as we cannot recover |
|
matches, _ := filepath.Glob(fmt.Sprintf("%s/user/%s/*lock*", config.NethackLauncher.HackDir, username)) |
|
if matches == nil { |
|
fmt.Printf(" %s\n", config.NethackLauncher.ServerDisplay) |
|
println("") |
|
println(" The dungeon crumbles around you, darkness remains...") |
|
println(" Godspeed adventurer..") |
|
println("") |
|
println(" No statefiles exist. (press enter to return)") |
|
println("") |
|
fmt.Printf(">> ") |
|
|
|
scanner := bufio.NewScanner(os.Stdin) |
|
for scanner.Scan() { |
|
if scanner.Text() == "" { |
|
printUserScreen(redisClient, username) |
|
} |
|
} |
|
} |
|
|
|
fmt.Printf(" %s\n", config.NethackLauncher.ServerDisplay) |
|
println("") |
|
println(" Recover utility.") |
|
println("") |
|
// check if dir is empty |
|
isEmpty, _ := checkDir(fmt.Sprintf("%s/user/%s/save/", config.NethackLauncher.HackDir, username)) |
|
if !isEmpty { |
|
// save file exists, overwrite? |
|
println(" Save file already exists!") |
|
println(" Overwrite? (y/n)") |
|
println("") |
|
fmt.Printf(">> ") |
|
} else { |
|
println(" Attempt to recover statefile? (y/n)") |
|
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() |
|
printUserScreen(redisClient, username) |
|
case "y": |
|
// 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(">> ") |
|
} |
|
case "\n": |
|
clearScreen() |
|
printUserScreen(redisClient, username) |
|
default: |
|
} |
|
} |
|
}
|
|
|