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, "-") p := strings.Split(phrase, "") s := Session{ id: lastSessionId, Name: sessionName, Users: make([]User, 0), phrase: p, AskedLetters: []string{}, DiscoveredPhrase: make([]string, len(p)), Mistakes: 0, userIndex: 0, CurrentUser: nil, } sessionStorage = append(sessionStorage, s) nameToSession[sessionName] = &sessionStorage[len(sessionStorage)-1] lastSessionId++ return &sessionStorage[len(sessionStorage)-1] } func GetSession(name string) (*Session, error) { s, ok := nameToSession[name] if !ok { return s, errors.New("can't find session " + name) } return s, nil } func (s *Session) AddUser(user User) { s.Users = append(s.Users, user) // fmt.Printf("#### Adding %v:\t%p\n", s.Users[len(s.Users)-1].Name, &(s.Users[len(s.Users)-1])) // append changes the pointers to the users because it needs to resize that slice s.CurrentUser = &(s.Users[s.userIndex]) } func (s *Session) VerifySignature(signature string, message []byte) (*User, error) { sig, err := base64.StdEncoding.DecodeString(signature) if err != nil { return nil, err } for i := range s.Users { // fmt.Printf("looking %v:\t%p\n", s.Users[i].Name, &(s.Users[i])) if ed25519.Verify(s.Users[i].PublicKey, message, sig) { return &s.Users[i], nil } } return nil, errors.New("this user was not fount in the current session") } 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 }