use distinct types for player and session ids
This commit is contained in:
		| @@ -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)) | ||||||
| 	}) | 	}) | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user