// dialog.go package server /* This file contains dialogs for the client. The dialog helpers are in ask.go. */ import "gitlab.com/beoran/woe/monolog" import "gitlab.com/beoran/woe/world" const NEW_CHARACTER_PRICE = 4 func (me *Client) ExistingAccountDialog() bool { pass := me.AskPassword() for pass == nil { me.Printf("Password may not be empty!\n") pass = me.AskPassword() } if !me.account.Challenge(string(pass)) { me.Printf("Password not correct!\n") me.Printf("Disconnecting!\n") return false } return true } func (me *Client) NewAccountDialog(login string) bool { for me.account == nil { me.Printf("\nWelcome, %s! Creating new account...\n", login) pass1 := me.AskPassword() if pass1 == nil { return false } pass2 := me.AskRepeatPassword() if pass1 == nil { return false } if string(pass1) != string(pass2) { me.Printf("\nPasswords do not match! Please try again!\n") continue } email := me.AskEmail() if email == nil { return false } me.account = world.NewAccount(login, string(pass1), string(email), 7) err := me.account.Save(me.server.DataPath()) if err != nil { monolog.Error("Could not save account %s: %v", login, err) me.Printf("\nFailed to save your account!\nPlease contact a WOE administrator!\n") return false } monolog.Info("Created new account %s", login) me.Printf("\nSaved your account.\n") return true } return false } func (me *Client) AccountDialog() bool { login := me.AskLogin() if login == nil { return false } var err error if me.server.World.GetAccount(string(login)) != nil { me.Printf("Account already logged in!\n") me.Printf("Disconnecting!\n") return false } me.account, err = me.server.World.LoadAccount(string(login)) if err != nil { monolog.Warning("Could not load account %s: %v", login, err) } if me.account != nil { return me.ExistingAccountDialog() } else { return me.NewAccountDialog(string(login)) } } func (me *Client) NewCharacterDialog() bool { noconfirm := true extra := TrivialAskOptionList{TrivialAskOption("Cancel")} me.Printf("New character:\n") charname := me.AskCharacterName() existing, aname, _ := world.LoadCharacterByName(me.server.DataPath(), string(charname)) for existing != nil { if aname == me.account.Name { me.Printf("You already have a character with a similar name!\n") } else { me.Printf("That character name is already taken by someone else.\n") } charname := me.AskCharacterName() existing, aname, _ = world.LoadCharacterByName(me.server.DataPath(), string(charname)) } kinres := me.AskOptionListExtra("Please choose the kin of this character", "Kin?> ", false, noconfirm, KinListAsker(world.KinList), extra) if sopt, ok := kinres.(TrivialAskOption); ok { if string(sopt) == "Cancel" { me.Printf("Character creation canceled.\n") return true } else { return true } } kin := kinres.(world.Kin) genres := me.AskOptionListExtra("Please choose the gender of this character", "Gender?> ", false, noconfirm, GenderListAsker(world.GenderList), extra) if sopt, ok := kinres.(TrivialAskOption); ok { if string(sopt) == "Cancel" { me.Printf("Character creation canceled.\n") return true } else { return true } } gender := genres.(world.Gender) jobres := me.AskOptionListExtra("Please choose the job of this character", "Gender?> ", false, noconfirm, JobListAsker(world.JobList), extra) if sopt, ok := kinres.(TrivialAskOption); ok { if string(sopt) == "Cancel" { me.Printf("Character creation canceled.\n") return true } else { return true } } job := jobres.(world.Job) character := world.NewCharacter(me.account, string(charname), &kin, &gender, &job) me.Printf("%s", character.Being.ToStatus()) ok := me.AskYesNo("Is this character ok?") if !ok { me.Printf("Character creation canceled.\n") return true } me.account.AddCharacter(character) me.account.Points -= NEW_CHARACTER_PRICE me.account.Save(me.server.DataPath()) character.Save(me.server.DataPath()) me.Printf("Character %s saved.\n", character.Being.Name) return true } func (me *Client) DeleteCharacterDialog() bool { extra := []AskOption{TrivialAskOption("Cancel"), TrivialAskOption("Disconnect")} els := me.AccountCharacterList() els = append(els, extra...) result := me.AskOptionList("Character to delete?", "Character?>", false, false, els) if alt, ok := result.(TrivialAskOption); ok { if string(alt) == "Disconnect" { me.Printf("Disconnecting") return false } else if string(alt) == "Cancel" { me.Printf("Canceled") return true } else { monolog.Warning("Internal error, unhandled case.") return true } } character := result.(*world.Character) /* A character that is deleted gives NEW_CHARACTER_PRICE + * level / (NEW_CHARACTER_PRICE * 2) points, but only after the delete. */ np := NEW_CHARACTER_PRICE + character.Level/(NEW_CHARACTER_PRICE*2) me.account.DeleteCharacter(me.server.DataPath(), character) me.account.Points += np return true } func (me *Client) AccountCharacterList() AskOptionSlice { els := make(AskOptionSlice, 0, 16) for i := 0; i < me.account.NumCharacters(); i++ { chara := me.account.GetCharacter(i) els = append(els, chara) } return els } func (me *Client) ChooseCharacterDialog() bool { extra := []AskOption{ SimpleAskOption{"New", "Create New character", "Create a new character. This option costs 4 points.", world.PRIVILEGE_ZERO}, SimpleAskOption{"Disconnect", "Disconnect from server", "Disconnect your client from this server.", world.PRIVILEGE_ZERO}, SimpleAskOption{"Delete", "Delete character", "Delete a character. A character that has been deleted cannot be reinstated. You will receive point bonuses for deleting your characters that depend on their level.", world.PRIVILEGE_ZERO}, } var pchara *world.Character = nil for pchara == nil { els := me.AccountCharacterList() els = append(els, extra...) result := me.AskOptionList("Choose a character?", "Character?>", false, true, els) switch opt := result.(type) { case SimpleAskOption: if opt.Name == "New" { if me.account.Points >= NEW_CHARACTER_PRICE { if !me.NewCharacterDialog() { return false } } else { me.Printf("Sorry, you have no points left to make new characters!\n") } } else if opt.Name == "Disconnect" { me.Printf("Disconnecting\n") return false } else if opt.Name == "Delete" { if !me.DeleteCharacterDialog() { return false } } else { me.Printf("Internal error, alt not valid: %v.", opt) } case *world.Character: pchara = opt default: me.Printf("What???") } me.Printf("You have %d points left.\n", me.account.Points) } me.character = pchara me.Printf("%s\n", me.character.Being.ToStatus()) me.Printf("Welcome, %s!\n", me.character.Name) return true } func (me *Client) CharacterDialog() bool { me.Printf("You have %d remaining points.\n", me.account.Points) for me.account.NumCharacters() < 1 { me.Printf("You have no characters yet!\n") if me.account.Points >= NEW_CHARACTER_PRICE { if !me.NewCharacterDialog() { return false } } else { me.Printf("Sorry, you have no characters, and no points left to make new characters!\n") me.Printf("Please contact the staff of WOE if you think this is a mistake.\n") me.Printf("Disconnecting!\n") return false } } return me.ChooseCharacterDialog() }