use distinct types for player and session ids
This commit is contained in:
parent
d61c70da86
commit
73b5ac7960
@ -3,14 +3,16 @@ package game
|
|||||||
import (
|
import (
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
|
"github.com/google/uuid"
|
||||||
|
|
||||||
"git.sunturtle.xyz/studio/shotgun/player"
|
"git.sunturtle.xyz/studio/shotgun/player"
|
||||||
"git.sunturtle.xyz/studio/shotgun/serve"
|
"git.sunturtle.xyz/studio/shotgun/serve"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestNewGame(t *testing.T) {
|
func TestNewGame(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
dealer := player.ID{1}
|
dealer := player.ID{UUID: uuid.UUID{1}}
|
||||||
chall := player.ID{2}
|
chall := player.ID{UUID: uuid.UUID{2}}
|
||||||
for i := 0; i < 10000; i++ {
|
for i := 0; i < 10000; i++ {
|
||||||
g := New(dealer, chall)
|
g := New(dealer, chall)
|
||||||
checks := []struct {
|
checks := []struct {
|
||||||
@ -41,7 +43,7 @@ func TestNewGame(t *testing.T) {
|
|||||||
|
|
||||||
func TestGameStartRound(t *testing.T) {
|
func TestGameStartRound(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
g := New(player.ID{1}, player.ID{2})
|
g := New(player.ID{UUID: uuid.UUID{1}}, player.ID{UUID: uuid.UUID{2}})
|
||||||
for i := int8(1); i < 100; i++ {
|
for i := int8(1); i < 100; i++ {
|
||||||
checks := []struct {
|
checks := []struct {
|
||||||
failed bool
|
failed bool
|
||||||
@ -77,7 +79,7 @@ func TestGameStartRound(t *testing.T) {
|
|||||||
|
|
||||||
func TestGameStartGroup(t *testing.T) {
|
func TestGameStartGroup(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
g := New(player.ID{1}, player.ID{2})
|
g := New(player.ID{UUID: uuid.UUID{1}}, player.ID{UUID: uuid.UUID{2}})
|
||||||
for i := uint(1); i < 10000; i++ {
|
for i := uint(1); i < 10000; i++ {
|
||||||
checks := []struct {
|
checks := []struct {
|
||||||
failed bool
|
failed bool
|
||||||
@ -114,7 +116,7 @@ func TestGameStartGroup(t *testing.T) {
|
|||||||
|
|
||||||
func TestGameNextTurn(t *testing.T) {
|
func TestGameNextTurn(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
g := New(player.ID{1}, player.ID{2})
|
g := New(player.ID{UUID: uuid.UUID{1}}, player.ID{UUID: uuid.UUID{2}})
|
||||||
for i := int8(1); i < 100; i++ {
|
for i := int8(1); i < 100; i++ {
|
||||||
checks := []struct {
|
checks := []struct {
|
||||||
failed bool
|
failed bool
|
||||||
@ -143,8 +145,8 @@ func TestGameNextTurn(t *testing.T) {
|
|||||||
|
|
||||||
func TestGamePlayers(t *testing.T) {
|
func TestGamePlayers(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
dealer := player.ID{1}
|
dealer := player.ID{UUID: uuid.UUID{1}}
|
||||||
chall := player.ID{2}
|
chall := player.ID{UUID: uuid.UUID{2}}
|
||||||
g := New(dealer, chall)
|
g := New(dealer, chall)
|
||||||
if g.CurrentPlayer().id != chall {
|
if g.CurrentPlayer().id != chall {
|
||||||
t.Errorf("challenger isn't current player at start")
|
t.Errorf("challenger isn't current player at start")
|
||||||
@ -183,7 +185,7 @@ func TestGamePlayers(t *testing.T) {
|
|||||||
|
|
||||||
func TestGamePopShell(t *testing.T) {
|
func TestGamePopShell(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
g := New(player.ID{1}, player.ID{2})
|
g := New(player.ID{UUID: uuid.UUID{1}}, player.ID{UUID: uuid.UUID{2}})
|
||||||
if live := g.popShell(); live != g.shellArray[0] {
|
if live := g.popShell(); live != g.shellArray[0] {
|
||||||
t.Errorf("first pop %t, wanted %t", live, g.shellArray[0])
|
t.Errorf("first pop %t, wanted %t", live, g.shellArray[0])
|
||||||
}
|
}
|
||||||
@ -208,8 +210,8 @@ func TestGamePopShell(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestGamePeek(t *testing.T) {
|
func TestGamePeek(t *testing.T) {
|
||||||
dealer := player.ID{1}
|
dealer := player.ID{UUID: uuid.UUID{1}}
|
||||||
chall := player.ID{2}
|
chall := player.ID{UUID: uuid.UUID{2}}
|
||||||
t.Run("empty", func(t *testing.T) {
|
t.Run("empty", func(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
g := New(dealer, chall)
|
g := New(dealer, chall)
|
||||||
@ -270,8 +272,8 @@ func TestGameEmpty(t *testing.T) {
|
|||||||
|
|
||||||
func TestGameWinner(t *testing.T) {
|
func TestGameWinner(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
dealer := player.ID{1}
|
dealer := player.ID{UUID: uuid.UUID{1}}
|
||||||
chall := player.ID{2}
|
chall := player.ID{UUID: uuid.UUID{2}}
|
||||||
cases := []struct {
|
cases := []struct {
|
||||||
name string
|
name string
|
||||||
p0, p1 int8
|
p0, p1 int8
|
||||||
@ -311,8 +313,8 @@ func TestGameWinner(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestGameShoot(t *testing.T) {
|
func TestGameShoot(t *testing.T) {
|
||||||
dealer := player.ID{1}
|
dealer := player.ID{UUID: uuid.UUID{1}}
|
||||||
chall := player.ID{2}
|
chall := player.ID{UUID: uuid.UUID{2}}
|
||||||
cases := []struct {
|
cases := []struct {
|
||||||
name string
|
name string
|
||||||
live bool
|
live bool
|
||||||
@ -399,7 +401,7 @@ func TestGameShoot(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestConcede(t *testing.T) {
|
func TestConcede(t *testing.T) {
|
||||||
dealer, chall := player.ID{1}, player.ID{2}
|
dealer, chall := player.ID{UUID: uuid.UUID{1}}, player.ID{UUID: uuid.UUID{2}}
|
||||||
cases := []struct {
|
cases := []struct {
|
||||||
name string
|
name string
|
||||||
p player.ID
|
p player.ID
|
||||||
@ -417,7 +419,7 @@ func TestConcede(t *testing.T) {
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "neither",
|
name: "neither",
|
||||||
p: player.ID{3},
|
p: player.ID{UUID: uuid.UUID{3}},
|
||||||
winner: player.ID{},
|
winner: player.ID{},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
@ -436,7 +438,7 @@ func TestConcede(t *testing.T) {
|
|||||||
|
|
||||||
func TestGameDTO(t *testing.T) {
|
func TestGameDTO(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
dealer, chall := player.ID{1}, player.ID{2}
|
dealer, chall := player.ID{UUID: uuid.UUID{1}}, player.ID{UUID: uuid.UUID{2}}
|
||||||
g := New(dealer, chall)
|
g := New(dealer, chall)
|
||||||
{
|
{
|
||||||
want := serve.Game{
|
want := serve.Game{
|
||||||
|
@ -5,6 +5,8 @@ import (
|
|||||||
"sync/atomic"
|
"sync/atomic"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
|
"github.com/google/uuid"
|
||||||
|
|
||||||
"git.sunturtle.xyz/studio/shotgun/lobby"
|
"git.sunturtle.xyz/studio/shotgun/lobby"
|
||||||
"git.sunturtle.xyz/studio/shotgun/player"
|
"git.sunturtle.xyz/studio/shotgun/player"
|
||||||
)
|
)
|
||||||
@ -20,7 +22,7 @@ func TestQueue(t *testing.T) {
|
|||||||
for i := 0; i < N; i++ {
|
for i := 0; i < N; i++ {
|
||||||
i := i
|
i := i
|
||||||
go func() {
|
go func() {
|
||||||
id, _, deal := l.Queue(context.Background(), player.ID{uint8(i), uint8(i >> 8)})
|
id, _, deal := l.Queue(context.Background(), player.ID{UUID: uuid.UUID{uint8(i), uint8(i >> 8)}})
|
||||||
if deal {
|
if deal {
|
||||||
dealers.Add(1)
|
dealers.Add(1)
|
||||||
} else {
|
} else {
|
||||||
|
@ -85,7 +85,7 @@ func Login(ctx context.Context, db RowQuerier, user, pass string) (ID, error) {
|
|||||||
slog.ErrorContext(ctx, "login failed", "user", user)
|
slog.ErrorContext(ctx, "login failed", "user", user)
|
||||||
return ID{}, fmt.Errorf("invalid credentials")
|
return ID{}, fmt.Errorf("invalid credentials")
|
||||||
}
|
}
|
||||||
return ID(id), nil
|
return ID{id}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
const initUsers = `CREATE TABLE shotgun_users (
|
const initUsers = `CREATE TABLE shotgun_users (
|
||||||
|
@ -31,7 +31,7 @@ func TestLogin(t *testing.T) {
|
|||||||
if err == nil {
|
if err == nil {
|
||||||
t.Errorf("logging in nonexistent user didn't err")
|
t.Errorf("logging in nonexistent user didn't err")
|
||||||
}
|
}
|
||||||
if id != uuid.Nil {
|
if id.UUID != uuid.Nil {
|
||||||
t.Errorf("got nonzero user %v before registering", id)
|
t.Errorf("got nonzero user %v before registering", id)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -43,7 +43,7 @@ func TestLogin(t *testing.T) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
t.Errorf("couldn't login after registering: %v", err)
|
t.Errorf("couldn't login after registering: %v", err)
|
||||||
}
|
}
|
||||||
if id == uuid.Nil {
|
if id.UUID == uuid.Nil {
|
||||||
t.Errorf("got zero player id after registering")
|
t.Errorf("got zero player id after registering")
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -51,7 +51,7 @@ func TestLogin(t *testing.T) {
|
|||||||
if err == nil {
|
if err == nil {
|
||||||
t.Errorf("logged in with wrong password")
|
t.Errorf("logged in with wrong password")
|
||||||
}
|
}
|
||||||
if wrong != uuid.Nil {
|
if wrong.UUID != uuid.Nil {
|
||||||
t.Errorf("got nonzero user %v with wrong password (real is %v)", wrong, id)
|
t.Errorf("got nonzero user %v with wrong password (real is %v)", wrong, id)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -4,4 +4,6 @@ package player
|
|||||||
import "github.com/google/uuid"
|
import "github.com/google/uuid"
|
||||||
|
|
||||||
// ID is a unique ID for a player.
|
// ID is a unique ID for a player.
|
||||||
type ID = uuid.UUID
|
type ID struct {
|
||||||
|
uuid.UUID
|
||||||
|
}
|
||||||
|
@ -11,7 +11,9 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
// Session is a session ID.
|
// Session is a session ID.
|
||||||
type Session = uuid.UUID
|
type Session struct {
|
||||||
|
uuid.UUID
|
||||||
|
}
|
||||||
|
|
||||||
// InitSessions initializes an SQLite table relating player IDs to sessions.
|
// InitSessions initializes an SQLite table relating player IDs to sessions.
|
||||||
func InitSessions(ctx context.Context, db Execer) error {
|
func InitSessions(ctx context.Context, db Execer) error {
|
||||||
@ -32,7 +34,7 @@ func StartSession(ctx context.Context, db Execer, p ID, now time.Time) (Session,
|
|||||||
return Session{}, fmt.Errorf("couldn't start session: %w", err)
|
return Session{}, fmt.Errorf("couldn't start session: %w", err)
|
||||||
}
|
}
|
||||||
slog.InfoContext(ctx, "session started", "player", p, "session", id, "now", now)
|
slog.InfoContext(ctx, "session started", "player", p, "session", id, "now", now)
|
||||||
return Session(id), nil
|
return Session{id}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// FromSession gets the player ID associated with a session and updates the
|
// FromSession gets the player ID associated with a session and updates the
|
||||||
|
@ -27,13 +27,13 @@ func TestSessions(t *testing.T) {
|
|||||||
t.Fatalf("couldn't init sessions: %v", err)
|
t.Fatalf("couldn't init sessions: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
p := player.ID{1}
|
p := player.ID{uuid.UUID{1}}
|
||||||
now := time.Unix(0, 0)
|
now := time.Unix(0, 0)
|
||||||
id, err := player.StartSession(ctx, conn, p, now)
|
id, err := player.StartSession(ctx, conn, p, now)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("couldn't start session: %v", err)
|
t.Fatalf("couldn't start session: %v", err)
|
||||||
}
|
}
|
||||||
if id == uuid.Nil {
|
if id.UUID == uuid.Nil {
|
||||||
t.Errorf("got zero session id at start")
|
t.Errorf("got zero session id at start")
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -41,7 +41,7 @@ func TestSessions(t *testing.T) {
|
|||||||
if err == nil {
|
if err == nil {
|
||||||
t.Errorf("no error on expired session")
|
t.Errorf("no error on expired session")
|
||||||
}
|
}
|
||||||
if u != uuid.Nil {
|
if u.UUID != uuid.Nil {
|
||||||
t.Errorf("got nonzero player %v from expired session", u)
|
t.Errorf("got nonzero player %v from expired session", u)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -49,7 +49,7 @@ func TestSessions(t *testing.T) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
t.Errorf("couldn't get player from session: %v", err)
|
t.Errorf("couldn't get player from session: %v", err)
|
||||||
}
|
}
|
||||||
if u == uuid.Nil {
|
if u.UUID == uuid.Nil {
|
||||||
t.Errorf("got zero player from session")
|
t.Errorf("got zero player from session")
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -57,7 +57,7 @@ func TestSessions(t *testing.T) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
t.Errorf("couldn't get player from extended session: %v", err)
|
t.Errorf("couldn't get player from extended session: %v", err)
|
||||||
}
|
}
|
||||||
if u == uuid.Nil {
|
if u.UUID == uuid.Nil {
|
||||||
t.Errorf("got zero player from extended session")
|
t.Errorf("got zero player from extended session")
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -69,7 +69,7 @@ func TestSessions(t *testing.T) {
|
|||||||
if err == nil {
|
if err == nil {
|
||||||
t.Errorf("no error on logged out session")
|
t.Errorf("no error on logged out session")
|
||||||
}
|
}
|
||||||
if u != uuid.Nil {
|
if u.UUID != uuid.Nil {
|
||||||
t.Errorf("got nonzero player %v from logged out session", u)
|
t.Errorf("got nonzero player %v from logged out session", u)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -6,6 +6,8 @@ import (
|
|||||||
"net/netip"
|
"net/netip"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
|
"github.com/google/uuid"
|
||||||
|
|
||||||
"git.sunturtle.xyz/studio/shotgun/player"
|
"git.sunturtle.xyz/studio/shotgun/player"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -21,7 +23,7 @@ func WithPlayerID(next http.Handler) http.Handler {
|
|||||||
http.Error(w, "missing or invalid X-Forwarded-For header; check server configuration", http.StatusInternalServerError)
|
http.Error(w, "missing or invalid X-Forwarded-For header; check server configuration", http.StatusInternalServerError)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
id := player.ID(addr.As16())
|
id := player.ID{UUID: uuid.UUID(addr.As16())}
|
||||||
ctx := ctxWith(r.Context(), id)
|
ctx := ctxWith(r.Context(), id)
|
||||||
next.ServeHTTP(w, r.WithContext(ctx))
|
next.ServeHTTP(w, r.WithContext(ctx))
|
||||||
})
|
})
|
||||||
|
Loading…
Reference in New Issue
Block a user