storing player bodies in the database
parent
52a17a7e36
commit
5c6da34d98
@ -0,0 +1,43 @@
|
|||||||
|
package db
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
type Body struct {
|
||||||
|
ID int
|
||||||
|
PlayerID int
|
||||||
|
X float64
|
||||||
|
Y float64
|
||||||
|
Z float64
|
||||||
|
DiedAt time.Time
|
||||||
|
FoundAt *time.Time
|
||||||
|
}
|
||||||
|
|
||||||
|
func (db *SQLite) ListBodies() ([]Body, error) {
|
||||||
|
rows, err := db.db.Query(`select id, player, x, y, z, died_at from bodies where found_at is null`)
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("failed to fetch bodies from db: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
bodies := make([]Body, 0, 64)
|
||||||
|
for rows.Next() {
|
||||||
|
var body Body
|
||||||
|
if err := rows.Scan(&body.ID, &body.PlayerID, &body.X, &body.Y, &body.Z, &body.DiedAt); err != nil {
|
||||||
|
return nil, fmt.Errorf("failed to read bodies response rows: %w", err)
|
||||||
|
}
|
||||||
|
bodies = append(bodies, body)
|
||||||
|
}
|
||||||
|
return bodies, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (db *SQLite) AddBody(body *Body) error {
|
||||||
|
_, err := db.db.Exec(`insert into bodies
|
||||||
|
(player, x, y, z)
|
||||||
|
values (?, ?, ?, ?);`, body.PlayerID, body.X, body.Y, body.Z)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("failed to add body to db: %w", err)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
@ -1,6 +1,58 @@
|
|||||||
package db
|
package db
|
||||||
|
|
||||||
|
import (
|
||||||
|
"crypto/rand"
|
||||||
|
"fmt"
|
||||||
|
"os"
|
||||||
|
|
||||||
|
"golang.org/x/crypto/bcrypt"
|
||||||
|
)
|
||||||
|
|
||||||
|
func cryptostring(n int) string {
|
||||||
|
b := make([]byte, n)
|
||||||
|
rand.Read(b)
|
||||||
|
letters := `abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%*-=+`
|
||||||
|
r := make([]byte, 0, n)
|
||||||
|
for _, n := range b {
|
||||||
|
r = append(r, letters[int(n)%len(letters)])
|
||||||
|
}
|
||||||
|
return string(r)
|
||||||
|
}
|
||||||
|
|
||||||
type Players interface {
|
type Players interface {
|
||||||
CreatePlayer(name, pass string) error
|
CreatePlayer(name, pass string) error
|
||||||
CheckPassword(name, pass string) error
|
CheckPassword(name, pass string) error
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type Player struct {
|
||||||
|
ID int `json:"id"`
|
||||||
|
Name string `json:"name"`
|
||||||
|
Hash string `json:"-"`
|
||||||
|
Salt string `json:"-"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *Player) SetPassword(password string) error {
|
||||||
|
p.Salt = cryptostring(12)
|
||||||
|
cat := []byte(password + p.Salt)
|
||||||
|
hashBytes, err := bcrypt.GenerateFromPassword(cat, 13)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("unable to generate password hash: %w", err)
|
||||||
|
}
|
||||||
|
p.Hash = string(hashBytes)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *Player) HasPassword(password string) bool {
|
||||||
|
cat := []byte(password + p.Salt)
|
||||||
|
if err := bcrypt.CompareHashAndPassword([]byte(p.Hash), cat); err != nil {
|
||||||
|
if err != bcrypt.ErrMismatchedHashAndPassword {
|
||||||
|
fmt.Fprintf(os.Stderr, "error checking password for %v: %v\n", p, err)
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p Player) String() string {
|
||||||
|
return fmt.Sprintf(`Player{ID: %d, Name: "%s"}`, p.ID, p.Name)
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue