package game import ( "crypto/rand" "encoding/base64" "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") ) // 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 != "password" { game.server.Send(Login, []byte{Failure}, address) return ErrWrongPassword } player = game.players.ByAccount(account.ID) if player != nil { game.reconnect(player, address) } else { game.connect(account, address) } return nil } func (game *Game) reconnect(player *Player, address *net.UDPAddr) { player.KeepAlive() game.players.ChangeAddress(player, address) game.sendLoginSuccess(player) player.OnConnect() } 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) }