102 lines
2.2 KiB
Go
102 lines
2.2 KiB
Go
package game
|
|
|
|
import (
|
|
"crypto/rand"
|
|
"crypto/sha256"
|
|
"encoding/base64"
|
|
"encoding/hex"
|
|
"encoding/json"
|
|
"errors"
|
|
"net"
|
|
)
|
|
|
|
const (
|
|
Success = 0
|
|
Failure = 1
|
|
)
|
|
|
|
var (
|
|
ErrAlreadyLoggedIn = errors.New("already logged in")
|
|
ErrUnknownAccount = errors.New("unknown account")
|
|
ErrWrongPassword = errors.New("wrong password")
|
|
testPassword = sha256Text("password")
|
|
)
|
|
|
|
// Login checks the account credentials and gives a network peer access to an account.
|
|
func (game *Game) Login(data []byte, address *net.UDPAddr) error {
|
|
player := game.players.ByAddress(address)
|
|
|
|
if player != nil {
|
|
game.server.Send(Login, []byte{Failure}, address)
|
|
return ErrAlreadyLoggedIn
|
|
}
|
|
|
|
username, password, err := getLoginData(data)
|
|
|
|
if err != nil {
|
|
game.server.Send(Login, []byte{Failure}, address)
|
|
return err
|
|
}
|
|
|
|
account := GetAccountByName(username)
|
|
|
|
if account == nil {
|
|
game.server.Send(Login, []byte{Failure}, address)
|
|
return ErrUnknownAccount
|
|
}
|
|
|
|
if password != testPassword {
|
|
game.server.Send(Login, []byte{Failure}, address)
|
|
return ErrWrongPassword
|
|
}
|
|
|
|
player = game.players.ByAccount(account.ID)
|
|
|
|
if player != nil {
|
|
game.server.Send(Login, []byte{Failure}, address)
|
|
return ErrAlreadyLoggedIn
|
|
}
|
|
|
|
game.connect(account, address)
|
|
return nil
|
|
}
|
|
|
|
func (game *Game) connect(account *Account, address *net.UDPAddr) {
|
|
player := NewPlayer(address, account, game)
|
|
player.authToken = createAuthToken()
|
|
player.KeepAlive()
|
|
game.sendLoginSuccess(player)
|
|
game.players.Add(player)
|
|
}
|
|
|
|
func (game *Game) sendLoginSuccess(player *Player) {
|
|
response := []byte{Success}
|
|
response = AppendString(response, player.ID)
|
|
response = AppendString(response, player.authToken)
|
|
game.server.Send(Login, response, player.address)
|
|
}
|
|
|
|
func getLoginData(data []byte) (string, string, error) {
|
|
loginRequest := [2]string{}
|
|
err := json.Unmarshal(data, &loginRequest)
|
|
|
|
if err != nil {
|
|
return "", "", err
|
|
}
|
|
|
|
username := loginRequest[0]
|
|
password := loginRequest[1]
|
|
return username, password, nil
|
|
}
|
|
|
|
func createAuthToken() string {
|
|
randomBytes := make([]byte, 32)
|
|
rand.Read(randomBytes)
|
|
return base64.StdEncoding.EncodeToString(randomBytes)
|
|
}
|
|
|
|
func sha256Text(password string) string {
|
|
sum := sha256.Sum256([]byte(password))
|
|
return hex.EncodeToString(sum[:])
|
|
}
|