diff --git a/server/db/bodies.go b/server/db/bodies.go index 3a4be62..ddad650 100644 --- a/server/db/bodies.go +++ b/server/db/bodies.go @@ -13,6 +13,7 @@ type Body struct { Z float64 DiedAt time.Time FoundAt *time.Time + FoundBy *int } func (db *SQLite) ListBodies() ([]Body, error) { @@ -41,3 +42,22 @@ func (db *SQLite) AddBody(body *Body) error { } return nil } + +func (db *SQLite) ReadBody(body *Body) error { + args := make([]interface{}, 0, 1) + q := `select id, player, x, y, z, died_at from bodies` + if body.ID != 0 { + q += ` where id = ?` + args = append(args, body.ID) + } else { + q += ` where player = ?` + args = append(args, body.PlayerID) + } + q += ` and found_at is null` + + row := db.db.QueryRow(q, args...) + if err := row.Scan(&body.ID, &body.PlayerID, &body.X, &body.Y, &body.Z, &body.DiedAt); err != nil { + return fmt.Errorf("failed to read body from db: %w", err) + } + return nil +} diff --git a/server/db/sqlite.go b/server/db/sqlite.go index f5c3ce5..f560ca6 100644 --- a/server/db/sqlite.go +++ b/server/db/sqlite.go @@ -80,7 +80,6 @@ func (db *SQLite) ReadPlayer(p *Player) error { if err := row.Scan(&p.ID, &p.Name, &p.Hash, &p.Salt); err != nil { return fmt.Errorf("unable to read player row: %w", err) } - fmt.Printf("read player from db: %v\n", p) return nil } diff --git a/server/go.mod b/server/go.mod index 86e1e67..2c029ad 100644 --- a/server/go.mod +++ b/server/go.mod @@ -7,7 +7,6 @@ require ( github.com/gorilla/websocket v1.4.1 github.com/jordanorelli/blammo v0.0.0-20200201231725-9fd70eb7c1f2 github.com/mattn/go-sqlite3 v2.0.3+incompatible - github.com/prometheus/common v0.4.0 github.com/spf13/cobra v0.0.6 golang.org/x/crypto v0.0.0-20200117160349-530e935923ad ) diff --git a/server/go.sum b/server/go.sum index ffcf581..1e37dc8 100644 --- a/server/go.sum +++ b/server/go.sum @@ -46,8 +46,6 @@ github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T github.com/inconshreveable/mousetrap v1.0.0 h1:Z8tu5sraLXCXIcARxBp/8cbvlwVa7Z1NHg9XEKhtSvM= github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo= -github.com/jordanorelli/blammo v0.0.0-20200121053404-bd13f6b43c9f h1:m1UX7IV22aEt+hw5R/9MkmB2jdF4kRucP9Z/E/ql1JU= -github.com/jordanorelli/blammo v0.0.0-20200121053404-bd13f6b43c9f/go.mod h1:ofUhNTXhWoL77wTBOnWpjPN9s244RK1Hn0XiYhE4E1s= github.com/jordanorelli/blammo v0.0.0-20200201231725-9fd70eb7c1f2 h1:DH2VZ5Z4paQJe0zViSQENrwbgfrt4yyTeckjureCKOw= github.com/jordanorelli/blammo v0.0.0-20200201231725-9fd70eb7c1f2/go.mod h1:hh4DdsA3OoMbUpCM3iftScrKFmrPuTLOqnK1aJmadqk= github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w= diff --git a/server/main.go b/server/main.go index 5ccd1ab..e049781 100644 --- a/server/main.go +++ b/server/main.go @@ -2,6 +2,8 @@ package main import ( "crypto/rand" + "database/sql" + "errors" "fmt" "net" "net/http" @@ -120,6 +122,33 @@ func runPlayerSetPassword(cmd *cobra.Command, args []string) { } } +func runPlayerStatus(cmd *cobra.Command, args []string) { + conn, err := db.OpenSQLite(cmd.Flag("db").Value.String()) + if err != nil { + fmt.Fprintf(os.Stderr, "unable to open sqlite database: %v\n", err) + } + defer conn.Close() + + player := db.Player{Name: args[0]} + if err := conn.ReadPlayer(&player); err != nil { + fmt.Fprintf(os.Stderr, "unable to read player record: %v\n", err) + return + } + + body := db.Body{PlayerID: player.ID} + err = conn.ReadBody(&body) + switch { + case errors.Is(err, sql.ErrNoRows): + fmt.Println("alive") + break + case err == nil: + fmt.Printf("dead since %v\n", body.DiedAt) + break + default: + fmt.Fprintf(os.Stderr, "unable to query for bodies: %v\n", err) + } +} + func main() { cmd := &cobra.Command{ Use: "kloam", @@ -164,5 +193,13 @@ func main() { } player.AddCommand(playerSetPassword) + playerStatus := &cobra.Command{ + Use: "status", + Short: "gets a player's status", + Args: cobra.ExactArgs(1), + Run: runPlayerStatus, + } + player.AddCommand(playerStatus) + cmd.Execute() } diff --git a/server/request.go b/server/request.go index 239c0cd..a38c6ac 100644 --- a/server/request.go +++ b/server/request.go @@ -1,7 +1,9 @@ package main import ( + "database/sql" "encoding/json" + "errors" "fmt" "time" @@ -72,8 +74,10 @@ type login struct { } type loginResult struct { - Passed bool `json:"passed"` - Error string `json:"error,omitempty"` + Passed bool `json:"passed"` + Dead bool `json:"dead"` + DiedAt time.Time `json:"died_at"` + Error string `json:"error,omitempty"` } func (l *login) exec(s *server, from *player) { @@ -93,7 +97,6 @@ func (l *login) exec(s *server, from *player) { fmt.Printf("login read row from database: %v\n", row) if row.HasPassword(l.Password) { - sendResult(loginResult{Passed: true}) from.username = l.Username from.id = row.ID } else { @@ -101,6 +104,22 @@ func (l *login) exec(s *server, from *player) { return } + body := db.Body{PlayerID: row.ID} + if err := s.db.ReadBody(&body); err != nil { + if errors.Is(err, sql.ErrNoRows) { + sendResult(loginResult{Passed: true}) + } else { + sendResult(loginResult{Error: err.Error()}) + return + } + } else { + sendResult(loginResult{ + Passed: true, + Dead: true, + DiedAt: body.DiedAt, + }) + } + messages := make([]string, 0, len(s.souls)) for _, soul := range s.souls {