package game import ( "crypto/ed25519" "encoding/base64" "errors" "strings" petname "github.com/dustinkirkland/golang-petname" ) var lastSessionId int = 0 var sessionStorage []Session = []Session{} var nameToSession map[string]*Session = make(map[string]*Session) type Session struct { id int Name string Users []User phrase []string AskedLetters []string DiscoveredPhrase []string Mistakes int userIndex int CurrentUser *User } func NewSession(phrase string) Session { sessionName := petname.Generate(3, "-") s := Session{ id: lastSessionId, Name: sessionName, Users: []User{}, phrase: []string{phrase}, AskedLetters: []string{}, DiscoveredPhrase: make([]string, len(phrase)), Mistakes: 0, userIndex: 0, CurrentUser: nil, } sessionStorage = append(sessionStorage, s) nameToSession[sessionName] = &s lastSessionId++ return s } func GetSession(name string) *Session { return nameToSession[name] } func (s *Session) AddUser(user User) { s.Users = append(s.Users, user) if s.CurrentUser == nil { s.CurrentUser = &s.Users[s.userIndex] } } func (s Session) VerifySignature(signature string, message []byte) *User { for _, u := range s.Users { sig, _ := base64.StdEncoding.DecodeString(signature) if ed25519.Verify(u.PublicKey, message, sig) { return &u } } return nil } func (s *Session) GuessLetter(letter string) (*Session, error) { letter = strings.ToLower(letter) if len(letter) != 1 { return s, errors.New("the letter needs to have a length of one") } for _, asked := range s.AskedLetters { if letter == asked { return s, errors.New("the letter " + letter + " was already asked") } } s.AskedLetters = append(s.AskedLetters, letter) found := false for i, l := range s.phrase { if l == letter { found = true s.DiscoveredPhrase[i] = s.phrase[i] } } if !found { s.Mistakes++ } s.userIndex = (s.userIndex + 1) % len(s.Users) s.CurrentUser = &s.Users[s.userIndex] return s, nil }