117 lines
2.6 KiB
Go
117 lines
2.6 KiB
Go
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
|
|
}
|