getting somewhere with db and auth
This commit is contained in:
122
db/db.go
Normal file
122
db/db.go
Normal file
@ -0,0 +1,122 @@
|
||||
package db
|
||||
|
||||
import (
|
||||
"crypto/sha256"
|
||||
"database/sql"
|
||||
"encoding/hex"
|
||||
"errors"
|
||||
"time"
|
||||
|
||||
_ "github.com/mattn/go-sqlite3"
|
||||
)
|
||||
|
||||
var db *sql.DB
|
||||
|
||||
var (
|
||||
ErrUserExists = errors.New("username already exists")
|
||||
ErrInvalidCredentials = errors.New("invalid username or password")
|
||||
)
|
||||
|
||||
func InitDB(dbPath string) error {
|
||||
var err error
|
||||
db, err = sql.Open("sqlite3", dbPath)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Create tables if they don't exist
|
||||
_, err = db.Exec(`
|
||||
CREATE TABLE IF NOT EXISTS players (
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
username TEXT UNIQUE NOT NULL,
|
||||
password_hash TEXT NOT NULL,
|
||||
created_at DATETIME NOT NULL
|
||||
);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS player_states (
|
||||
player_id INTEGER PRIMARY KEY,
|
||||
x INTEGER NOT NULL,
|
||||
y INTEGER NOT NULL,
|
||||
last_seen DATETIME NOT NULL,
|
||||
FOREIGN KEY(player_id) REFERENCES players(id)
|
||||
);
|
||||
`)
|
||||
return err
|
||||
}
|
||||
|
||||
func hashPassword(password string) string {
|
||||
hash := sha256.Sum256([]byte(password))
|
||||
return hex.EncodeToString(hash[:])
|
||||
}
|
||||
|
||||
func RegisterPlayer(username, password string) (int, error) {
|
||||
// Check if username exists
|
||||
var exists bool
|
||||
err := db.QueryRow("SELECT EXISTS(SELECT 1 FROM players WHERE username = ?)", username).Scan(&exists)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
if exists {
|
||||
return 0, ErrUserExists
|
||||
}
|
||||
|
||||
// Create new player
|
||||
result, err := db.Exec(`
|
||||
INSERT INTO players (username, password_hash, created_at)
|
||||
VALUES (?, ?, ?)`,
|
||||
username, hashPassword(password), time.Now().UTC(),
|
||||
)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
id, err := result.LastInsertId()
|
||||
return int(id), err
|
||||
}
|
||||
|
||||
func AuthenticatePlayer(username, password string) (int, error) {
|
||||
var id int
|
||||
var storedHash string
|
||||
err := db.QueryRow(`
|
||||
SELECT id, password_hash
|
||||
FROM players
|
||||
WHERE username = ?`,
|
||||
username,
|
||||
).Scan(&id, &storedHash)
|
||||
|
||||
if err == sql.ErrNoRows {
|
||||
return 0, ErrInvalidCredentials
|
||||
}
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
if storedHash != hashPassword(password) {
|
||||
return 0, ErrInvalidCredentials
|
||||
}
|
||||
|
||||
return id, nil
|
||||
}
|
||||
|
||||
func SavePlayerState(playerID int, x, y int) error {
|
||||
_, err := db.Exec(`
|
||||
INSERT OR REPLACE INTO player_states (
|
||||
player_id, x, y, last_seen
|
||||
) VALUES (?, ?, ?, ?)`,
|
||||
playerID, x, y, time.Now().UTC(),
|
||||
)
|
||||
return err
|
||||
}
|
||||
|
||||
func LoadPlayerState(playerID int) (x, y int, err error) {
|
||||
err = db.QueryRow(`
|
||||
SELECT x, y FROM player_states
|
||||
WHERE player_id = ?`,
|
||||
playerID,
|
||||
).Scan(&x, &y)
|
||||
if err == sql.ErrNoRows {
|
||||
// Return default position for new players
|
||||
return 5, 5, nil
|
||||
}
|
||||
return x, y, err
|
||||
}
|
Reference in New Issue
Block a user