diff --git a/nethack-launcher.go b/nethack-launcher.go index ba210d9..e690beb 100644 --- a/nethack-launcher.go +++ b/nethack-launcher.go @@ -10,6 +10,7 @@ import ( "os/exec" "strconv" "strings" + "sync" "time" "github.com/unixvoid/glogger" @@ -39,6 +40,7 @@ type Config struct { var ( config = Config{} + wg sync.WaitGroup ) func main() { @@ -63,6 +65,9 @@ func main() { // create initial files needed by nethack createInitialFiles() + // start janitor + go janitor(redisClient) + // start homescreen screenFunction := printWelcomeScreen(redisClient) fmt.Printf("screen %s recieved\n", screenFunction) @@ -206,19 +211,25 @@ func printUserScreen(redisClient *redis.Client, username string) string { // have a janitor that watches inprogress set // janitor looks at every user in 'inprogress' and checks if the key remains // if the key is gone, janitor kills the user from redis set - // restart display - nhCommand := fmt.Sprintf("nethack -d %s -u %s\n", config.NethackLauncher.HackDir, username) - ttyrecPath := fmt.Sprintf("%s/user/%s/ttyrec/yeet.ttyrec", config.NethackLauncher.HackDir, username) - exec.Command("stty", "-F", "/dev/tty", "echo", "-cbreak").Run() - clearScreen() - nh := exec.Command("ttyrec", ttyrecPath, "-e", nhCommand) - nh.Stdout = os.Stdout - nh.Stdin = os.Stdin - nh.Stderr = os.Stderr - nh.Run() - exec.Command("exit").Run() + wg.Add(1) + go runGame(username) + watcher := startWatcher(username, redisClient) + wg.Wait() + fmt.Println("CLOSING") + close(watcher) + //nhCommand := fmt.Sprintf("nethack -d %s -u %s\n", config.NethackLauncher.HackDir, username) + //ttyrecPath := fmt.Sprintf("%s/user/%s/ttyrec/yeet.ttyrec", config.NethackLauncher.HackDir, username) + //exec.Command("stty", "-F", "/dev/tty", "echo", "-cbreak").Run() + //clearScreen() + //nh := exec.Command("ttyrec", ttyrecPath, "-e", nhCommand) + //nh.Stdout = os.Stdout + //nh.Stdin = os.Stdin + //nh.Stderr = os.Stderr + //nh.Run() + //exec.Command("exit").Run() printUserScreen(redisClient, username) case "q": + exec.Command("stty", "-F", "/dev/tty", "echo", "-cbreak").Run() clearScreen() os.Exit(0) default: @@ -460,6 +471,42 @@ func printProgressScreen(redisClient *redis.Client) { } } +func runGame(username string) { + nhCommand := fmt.Sprintf("nethack -d %s -u %s\n", config.NethackLauncher.HackDir, username) + ttyrecPath := fmt.Sprintf("%s/user/%s/ttyrec/yeet.ttyrec", config.NethackLauncher.HackDir, username) + exec.Command("stty", "-F", "/dev/tty", "echo", "-cbreak").Run() + clearScreen() + nh := exec.Command("ttyrec", ttyrecPath, "-e", nhCommand) + nh.Stdout = os.Stdout + nh.Stdin = os.Stdin + nh.Stderr = os.Stderr + nh.Run() + exec.Command("exit").Run() + wg.Done() +} + +func startWatcher(username string, redisClient *redis.Client) chan struct{} { + // create initial keys + redisClient.SAdd("inprogress", username) + redisClient.Set(fmt.Sprintf("inprogress:%s", username), "", 0) + + ch := make(chan struct{}) + // enter inital inprogress yet + go func() { + for { + select { + case <-ch: + return + default: + // SADD + redisClient.Expire(fmt.Sprintf("inprogress:%s", username), 10*time.Second) + time.Sleep(8 * time.Second) + } + } + }() + return ch +} + func createInitialFiles() { // create necessary directories if they dont exist if _, err := os.Stat(config.NethackLauncher.HackDir); os.IsNotExist(err) { @@ -484,6 +531,28 @@ func createInitialFiles() { } } +func janitor(redisClient *redis.Client) { + // loop through the set + for { + inprogress, err := redisClient.SMembers("inprogress").Result() + if err != nil { + panic(err) + } + for _, i := range inprogress { + // for each user, make sure the expire key exists + exists, err := redisClient.Exists(fmt.Sprintf("inprogress:%s", i)).Result() + if err != nil { + panic(err) + } + if !exists { + redisClient.SRem("inprogress", i) + } + } + + time.Sleep(10 * time.Second) + } +} + func gethighscore(w http.ResponseWriter, r *http.Request) { // run script output, err := exec.Command(config.NethackLauncher.ReclistLocation,