package main import ( "encoding/json" "errors" "fmt" "log" "os" "path/filepath" "strings" "time" door "git.red-green.com/RedGreen/doorgo" ) var ( d door.Door udb *UserDB u *User ) func SaveTemp() { if d.Disconnected || udb == nil || u == nil { return } stat, err := os.Stat("nodes") if err != nil { if errors.Is(err, os.ErrNotExist) { err = os.Mkdir("nodes", 0775) if err != nil { fmt.Println("Err", err) return } } else { fmt.Println("Err", err) return } } else if !stat.IsDir() { err = os.Remove("nodes") if err != nil { fmt.Println("Err", err) return } err = os.Mkdir("nodes", 0775) if err != nil { fmt.Println("Err", err) return } } tname := filepath.Join("nodes", fmt.Sprintf("%d.json", d.Config.Node)) payload, err := json.MarshalIndent(u, "", " ") if err != nil { fmt.Println("Err", err) return } err = os.WriteFile(tname, payload, 0666) if err != nil { fmt.Println("Err", err) } } func DropTemp() { if d.Disconnected { return } tname := filepath.Join("nodes", fmt.Sprintf("%d.json", d.Config.Node)) err := os.Remove(tname) if err != nil { fmt.Println("Err", err) } } func GetTempByNode(node int) *User { tname := filepath.Join("nodes", fmt.Sprintf("%d.json", node)) payload, err := os.ReadFile(tname) if err != nil { if !errors.Is(err, os.ErrNotExist) { fmt.Println("Err", err) } return nil } var u *User err = json.Unmarshal(payload, &u) if err != nil { fmt.Println("Err", err) return nil } return u } func UpdateTemp() { t := GetTempByNode(d.Config.Node) if t != nil { u = t } } func GetTempByName(name string) *User { ls, err := os.ReadDir("nodes") if err != nil { if !errors.Is(err, os.ErrNotExist) { fmt.Println("Err", err) } return nil } var u *User for _, entry := range ls { if entry.IsDir() { continue } if strings.HasPrefix(entry.Name(), ".") || !strings.HasSuffix(entry.Name(), ".json") { continue } fname := filepath.Join("nodes", entry.Name()) payload, err := os.ReadFile(fname) if err != nil { fmt.Println("Err", fname, err) continue } err = json.Unmarshal(payload, &u) if err != nil { fmt.Println("Err", fname, err) continue } if strings.EqualFold(u.Name, name) { return u } } return nil } func main() { d.Init("Geode") defer d.Close() udb = &UserDB{} err := udb.Open("users.db3") if err != nil { fmt.Printf("UserDB.Open(filename='users.db3') > %v\r\n", err) return } d.WriteS(door.ColorTextS("BRI YEL ON BLA") + "Geode" + door.ColorTextS("WHI ON BLA") + " by " + door.ColorTextS("BRI RED ON BLA") + "Apollo" + door.ColorTextS("BRI BLA ON BLA") + "@" + door.ColorTextS("BRI GRE ON BLA") + "21:1/236" + door.Reset + door.CRNL) LOGIN: for { d.WriteS(door.GotoS(1, 3) + door.Reset + strings.Repeat(" ", door.Width-1) + door.GotoS(1, 4) + strings.Repeat(" ", door.Width-1) + door.GotoS(1, 5) + strings.Repeat(" ", door.Width-1) + door.GotoS(1, 6) + strings.Repeat(" ", door.Width-1) + door.GotoS(1, 7) + strings.Repeat(" ", door.Width-1) + door.GotoS(1, 8) + strings.Repeat(" ", door.Width-1) + door.GotoS(1, 9) + strings.Repeat(" ", door.Width-1)) d.WriteS(door.GotoS(1, 3) + door.ColorTextS("BRI YEL ON BLA") + "Login: " + door.ColorTextS("BRI WHI ON BLU")) name := d.Input(30) if len(name) == 0 { d.WriteS(door.Reset + door.CRNL + "Goodbye!") return } u = udb.FindUserByName(name) if u == nil { u = &User{Name: name} // New User, So get their password and their class of choice d.WriteS(door.GotoS(1, 4) + door.ColorTextS("BRI YEL ON BLA") + "Password: " + door.ColorTextS("BLU ON BLU")) pwd := d.Input(30) if len(pwd) == 0 { d.WriteS(door.Reset + door.CRNL + "Goodbye!") return } err = u.SetPassword(pwd) if err != nil { d.WriteS(door.Reset + door.CRNL + "Err: " + err.Error() + door.CRNL) _, _, err = d.WaitKey(door.Inactivity) if err != nil { if errors.Is(err, door.ErrDisconnected) { return } } continue LOGIN } d.WriteS(door.Reset + door.CRNL) bb := door.ColorTextS("BRI BLA ON BLA") d.WriteS(bb + "[" + door.ColorTextS(C_KNIGHT.ColorText()) + "K" + bb + "] " + door.ColorTextS(C_KNIGHT.ColorText()) + C_KNIGHT.Name() + door.Reset + door.CRNL) d.WriteS(bb + "[" + door.ColorTextS(C_THIEF.ColorText()) + "T" + bb + "] " + door.ColorTextS(C_THIEF.ColorText()) + C_THIEF.Name() + door.Reset + door.CRNL) d.WriteS(bb + "[" + door.ColorTextS(C_CLERIC.ColorText()) + "C" + bb + "] " + door.ColorTextS(C_CLERIC.ColorText()) + C_CLERIC.Name() + door.Reset + door.CRNL) d.WriteS(bb + "[" + door.ColorTextS(C_WIZARD.ColorText()) + "W" + bb + "] " + door.ColorTextS(C_WIZARD.ColorText()) + C_WIZARD.Name() + door.Reset + door.CRNL) d.WriteS(bb + "[" + door.ColorTextS(C_RANGER.ColorText()) + "R" + bb + "] " + door.ColorTextS(C_RANGER.ColorText()) + C_RANGER.Name() + door.Reset + door.CRNL) r, _, err := d.WaitKey(door.Inactivity) if err != nil { if errors.Is(err, door.ErrDisconnected) { return } continue LOGIN } switch r { case 'k', 'K': u.Class = C_KNIGHT u.Health = 30 u.MaxHealth = 30 u.MaxMagic = 0 u.Magic = 0 u.Gold = 200 case 't', 'T': u.Class = C_THIEF u.Health = 20 u.MaxHealth = 20 u.MaxMagic = 0 u.Magic = 0 u.Gold = 250 // Thieves get bonus gold (+50) case 'c', 'C': u.Class = C_CLERIC u.Health = 25 u.MaxHealth = 25 u.MaxMagic = 7 u.Magic = 7 u.Gold = 200 case 'w', 'W': u.Class = C_WIZARD u.Health = 20 u.MaxHealth = 20 u.MaxMagic = 12 u.Magic = 12 u.Gold = 200 case 'r', 'R': u.Class = C_RANGER u.Health = 22 u.MaxHealth = 22 u.MaxMagic = 0 u.Magic = 0 u.Gold = 200 default: continue LOGIN } u.Level = 1 err = udb.SaveUser(u) if err != nil { log.Printf("u = %#v", u) log.Printf("UserDB.SaveUser(u) > %v", err) d.WriteS(door.Reset + door.CRNL + "Err: " + err.Error() + door.CRNL) d.WaitKey(door.Inactivity) return } break LOGIN } else { // Existing User, So verify their password d.WriteS(door.GotoS(1, 4) + door.ColorTextS("BRI YEL ON BLA") + "Password: " + door.ColorTextS("BLU ON BLU")) pwd := d.Input(30) if len(pwd) == 0 { d.WriteS(door.Reset + door.CRNL + "Goodbye!") return } if u.VerifyPassword(pwd) != nil { d.WriteS(door.Reset + door.CRNL + door.ColorTextS("BRI RED ON BLA") + "Invalid Username or Password!" + door.Reset + door.CRNL) d.WaitKey(time.Duration(10) * time.Second) u = nil continue LOGIN } else { d.WriteS(door.Reset + door.CRNL) break LOGIN } } } SaveTemp() defer DropTemp() d.WriteS(door.ColorTextS("BRI CYA ON BLA") + "Welcome " + door.ColorTextS("BRI WHI ON BLA") + u.Name + door.ColorTextS("BRI CYA ON BLA") + " the ") d.WriteS(door.ColorTextS(u.Class.ColorText()) + u.Class.Name()) d.WriteS(door.Reset + door.CRNL) go renderStatusBar("Hello "+u.Name, time.Now().Format("Jan 02 2006 @ 03:04:05PM")) d.WriteS(fmt.Sprintf("Weapon: %s with %s enchantment", u.Weapon.Name(), u.WeaponEnchant.Name()) + door.CRNL) d.WriteS(fmt.Sprintf("Armor: %s with %s enchantment", u.Armor.Name(), u.ArmorEnchant.Name()) + door.CRNL) d.WriteS(fmt.Sprintf("Ranged: %s with %s enchantment", u.RangedWeapon.Name(), u.RangedWeaponEnchant.Name()) + door.CRNL) d.WriteS(fmt.Sprintf("Shield: %s", u.Shield.Name()) + door.CRNL) d.WriteS(fmt.Sprintf("Ring: %s", u.Ring.Name()) + door.CRNL) d.WriteS(fmt.Sprintf("Amulet: %s", u.Amulet.Name()) + door.CRNL) d.WaitKey(door.Inactivity) } func renderStatusBar(msg ...string) { if d.Disconnected || u == nil { return } d.WriteS(door.SavePos + door.GotoS(1, door.Height-1) + door.Reset + strings.Repeat(" ", door.Width-1) + door.RestorePos) d.WriteS(door.SavePos + door.GotoS(1, door.Height) + door.Reset + strings.Repeat(" ", door.Width-1) + door.RestorePos) bb := door.ColorTextS("BRI BLA ON BLA") bar_width := ((door.Width - 3) / 2) - 1 hp := int(float64(bar_width) * (float64(u.Health) / float64(u.MaxHealth))) var pos_txt string if len(msg) >= 1 { pos_txt += msg[0] + " - " } if u.MaxMagic != 0 { pos_txt += fmt.Sprintf("%-3d%% %s %-3d%%", int((float64(u.Health)/float64(u.MaxHealth))*100.0), u.Pos.String(), int((float64(u.Magic)/float64(u.MaxMagic))*100.0)) } else { pos_txt += fmt.Sprintf("%-3d%% %s", int((float64(u.Health)/float64(u.MaxHealth))*100.0), u.Pos.String()) } if len(msg) >= 2 { pos_txt += " - " + msg[1] } d.WriteS(door.SavePos + door.GotoS((door.Width/2)-(len(pos_txt)/2), door.Height-1) + door.ColorTextS("BRI CYA ON BLA") + pos_txt + door.RestorePos) if u.MaxMagic != 0 { mp := int(float64(bar_width) * (float64(u.Magic) / float64(u.MaxMagic))) log.Printf("HP=%d/%d %d%% (%d) MP=%d/%d %d%% (%d) bar_width=%d", u.Health, u.MaxHealth, int((float64(u.Health)/float64(u.MaxHealth))*100.0), hp, u.Magic, u.MaxMagic, int((float64(u.Magic)/float64(u.MaxMagic))*100.0), mp, bar_width) d.WriteS(door.SavePos + door.GotoS(1, door.Height) + bb + "[" + door.ColorTextS("BRI RED ON BLA") + strings.Repeat(door.BARS.Solid, hp) + strings.Repeat(" ", bar_width-hp) + bb + "] [" + door.ColorTextS("BRI MAG ON BLA") + strings.Repeat(door.BARS.Solid, mp) + strings.Repeat(" ", bar_width-mp) + bb + "]" + door.RestorePos) } else { log.Printf("HP=%d/%d %d%% (%d) bar_width=%d", u.Health, u.MaxHealth, int((float64(u.Health)/float64(u.MaxHealth))*100.0), hp, bar_width) d.WriteS(door.SavePos + door.GotoS(1, door.Height) + bb + "[" + door.ColorTextS("BRI RED ON BLA") + strings.Repeat(door.BARS.Solid, hp) + strings.Repeat(" ", bar_width-hp) + bb + "]" + door.RestorePos) } }