Add testing and fix tons of bugs
Some checks reported errors
continuous-integration/drone/push Build was killed
Some checks reported errors
continuous-integration/drone/push Build was killed
This commit is contained in:
parent
5158ab539a
commit
4a521f595d
8 changed files with 272 additions and 35 deletions
|
@ -7,14 +7,14 @@ steps:
|
||||||
commands:
|
commands:
|
||||||
- cd ./draftbot
|
- cd ./draftbot
|
||||||
- GOPROXY=https://modules.fromouter.space go mod download
|
- GOPROXY=https://modules.fromouter.space go mod download
|
||||||
- CGO_ENABLED=0 go test .
|
- CGO_ENABLED=0 go test ./...
|
||||||
|
|
||||||
- name: build_draftbot
|
- name: build_draftbot
|
||||||
image: golang
|
image: golang
|
||||||
commands:
|
commands:
|
||||||
- cd ./draftbot
|
- cd ./draftbot
|
||||||
- GOPROXY=https://modules.fromouter.space go mod download
|
- GOPROXY=https://modules.fromouter.space go mod download
|
||||||
- CGO_ENABLED=0 go install .
|
- CGO_ENABLED=0 go install ./...
|
||||||
volumes:
|
volumes:
|
||||||
- name: gopath
|
- name: gopath
|
||||||
path: /go
|
path: /go
|
||||||
|
|
66
draftbot/bot/bot_test.go
Normal file
66
draftbot/bot/bot_test.go
Normal file
|
@ -0,0 +1,66 @@
|
||||||
|
package bot_test
|
||||||
|
|
||||||
|
import (
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"git.fromouter.space/mcg/mlp-server-tools/draftbot/bot"
|
||||||
|
|
||||||
|
"git.fromouter.space/mcg/draft"
|
||||||
|
)
|
||||||
|
|
||||||
|
const PACKSIZE = 5
|
||||||
|
|
||||||
|
// Test set that can be used by tests that don't need special features (like alternates)
|
||||||
|
var testSet = &draft.GenericSet{
|
||||||
|
Cards: []draft.Card{{ID: "a"}, {ID: "b"}, {ID: "c"}},
|
||||||
|
PackSize: PACKSIZE,
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestPick(t *testing.T) {
|
||||||
|
const PacksPerPlayer = 3
|
||||||
|
const PlayersPerPod = 5
|
||||||
|
|
||||||
|
// Get provider for test set
|
||||||
|
testProvider := draft.PacksFromSet(PacksPerPlayer, testSet)
|
||||||
|
|
||||||
|
// Create pod
|
||||||
|
pod := draft.MakePod(PlayersPerPod, testProvider)
|
||||||
|
|
||||||
|
// Create a bot for each player in the pod
|
||||||
|
var bots []*bot.Bot
|
||||||
|
for _, player := range pod.Players {
|
||||||
|
bots = append(bots, bot.MakeBot(player))
|
||||||
|
}
|
||||||
|
|
||||||
|
// Simulate a round of drafting
|
||||||
|
// Repeat until all packs are gone
|
||||||
|
// Channels are tested when they should trigger
|
||||||
|
for packnum := 0; packnum < PacksPerPlayer; packnum++ {
|
||||||
|
|
||||||
|
// Open new packs!
|
||||||
|
err := pod.OpenPacks()
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("Got an error while opening packs #%d: %s", packnum, err.Error())
|
||||||
|
}
|
||||||
|
|
||||||
|
for picknum := 0; picknum < PACKSIZE; picknum++ {
|
||||||
|
for _, bot := range bots {
|
||||||
|
bot.PickNext()
|
||||||
|
}
|
||||||
|
|
||||||
|
// Make sure either ReadyNextPick or ReadyNextPack triggers
|
||||||
|
select {
|
||||||
|
case <-pod.ReadyNextPick:
|
||||||
|
// Pass packs around
|
||||||
|
err := pod.NextPacks()
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("Got an error while passing packs: %s", err.Error())
|
||||||
|
}
|
||||||
|
case <-pod.ReadyNextPack:
|
||||||
|
break
|
||||||
|
default:
|
||||||
|
t.Fatal("Either ReadyNextPick/ReadyNextPack should trigger but neither has")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -29,6 +29,7 @@ func NewDraftBot(botAPI BotInterface, name string) *DraftBot {
|
||||||
return &DraftBot{
|
return &DraftBot{
|
||||||
API: botAPI,
|
API: botAPI,
|
||||||
Name: name,
|
Name: name,
|
||||||
|
Rooms: make(map[string]roomInfo),
|
||||||
Sessions: make(map[string]*session),
|
Sessions: make(map[string]*session),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -37,7 +38,7 @@ func NewDraftBot(botAPI BotInterface, name string) *DraftBot {
|
||||||
func (d *DraftBot) OnMessage(msg room.ServerMessage) {
|
func (d *DraftBot) OnMessage(msg room.ServerMessage) {
|
||||||
switch msg.Type {
|
switch msg.Type {
|
||||||
case room.MsgMessage:
|
case room.MsgMessage:
|
||||||
if *logAll {
|
if logAll {
|
||||||
logger.Log("event", "message",
|
logger.Log("event", "message",
|
||||||
"roomid", msg.RoomID,
|
"roomid", msg.RoomID,
|
||||||
"from", msg.Message.From,
|
"from", msg.Message.From,
|
||||||
|
@ -49,7 +50,7 @@ func (d *DraftBot) OnMessage(msg room.ServerMessage) {
|
||||||
d.handleMessage(msg.RoomID, *msg.Message)
|
d.handleMessage(msg.RoomID, *msg.Message)
|
||||||
}
|
}
|
||||||
case room.MsgEvent:
|
case room.MsgEvent:
|
||||||
if *logAll {
|
if logAll {
|
||||||
logger.Log("event", "event",
|
logger.Log("event", "event",
|
||||||
"roomid", msg.RoomID,
|
"roomid", msg.RoomID,
|
||||||
"content", msg.Event.Message)
|
"content", msg.Event.Message)
|
||||||
|
|
|
@ -103,11 +103,7 @@ func (d *DraftBot) cmdPickCard(roomid string, msg room.Message) {
|
||||||
|
|
||||||
func (d *DraftBot) cmdCreateSession(roomid string, msg room.Message) {
|
func (d *DraftBot) cmdCreateSession(roomid string, msg room.Message) {
|
||||||
// Get session options from data
|
// Get session options from data
|
||||||
type sessionOptions struct {
|
var opt SessionOptions
|
||||||
players int
|
|
||||||
options draftOptions
|
|
||||||
}
|
|
||||||
var opt sessionOptions
|
|
||||||
err := mapstructure.Decode(msg.Data, &opt)
|
err := mapstructure.Decode(msg.Data, &opt)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
d.sendMessage(roomid, room.Message{
|
d.sendMessage(roomid, room.Message{
|
||||||
|
@ -118,7 +114,7 @@ func (d *DraftBot) cmdCreateSession(roomid string, msg room.Message) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
sess, err := newSession(opt.players, opt.options)
|
sess, err := newSession(opt.Players, opt.Options)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
d.sendMessage(roomid, room.Message{
|
d.sendMessage(roomid, room.Message{
|
||||||
To: msg.From,
|
To: msg.From,
|
||||||
|
@ -140,7 +136,7 @@ func (d *DraftBot) cmdCreateSession(roomid string, msg room.Message) {
|
||||||
Channel: "draft",
|
Channel: "draft",
|
||||||
Type: "session-open",
|
Type: "session-open",
|
||||||
Data: opt,
|
Data: opt,
|
||||||
Message: fmt.Sprintf("Created a new draft session for %d players, type: %s", opt.players, opt.options.Type),
|
Message: fmt.Sprintf("Created a new draft session for %d players, type: %s", opt.Players, opt.Options.Type),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -2,12 +2,19 @@ package main_test
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"testing"
|
"testing"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"git.fromouter.space/mcg/draft/mlp"
|
||||||
|
|
||||||
"git.fromouter.space/mcg/cardgage/client/bot"
|
"git.fromouter.space/mcg/cardgage/client/bot"
|
||||||
|
lobby "git.fromouter.space/mcg/cardgage/lobby/proto"
|
||||||
room "git.fromouter.space/mcg/cardgage/room/api"
|
room "git.fromouter.space/mcg/cardgage/room/api"
|
||||||
draft "git.fromouter.space/mcg/mlp-server-tools/draftbot"
|
draft "git.fromouter.space/mcg/mlp-server-tools/draftbot"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
const TestBotName = "test-bot"
|
||||||
|
const TestRoomName = "test-room"
|
||||||
|
|
||||||
type MockServer struct {
|
type MockServer struct {
|
||||||
in chan room.ServerMessage
|
in chan room.ServerMessage
|
||||||
out chan room.BotMessage
|
out chan room.BotMessage
|
||||||
|
@ -35,8 +42,163 @@ func (m *MockServer) Bind(fn bot.MessageHandler) {
|
||||||
|
|
||||||
func TestDraftSession(t *testing.T) {
|
func TestDraftSession(t *testing.T) {
|
||||||
mock := makeMockServer()
|
mock := makeMockServer()
|
||||||
draftbot := draft.NewDraftBot(mock, "bot")
|
draftbot := draft.NewDraftBot(mock, TestBotName)
|
||||||
go mock.Bind(draftbot.OnMessage)
|
go mock.Bind(draftbot.OnMessage)
|
||||||
|
|
||||||
//TODO sample session
|
// Create a new room
|
||||||
|
mock.in <- room.ServerMessage{
|
||||||
|
RoomID: TestRoomName,
|
||||||
|
Type: room.MsgEvent,
|
||||||
|
Event: &room.Event{
|
||||||
|
Type: room.EvtNewRoom,
|
||||||
|
Room: &lobby.Room{
|
||||||
|
Id: TestRoomName,
|
||||||
|
Name: "Test draft room",
|
||||||
|
Creator: "test-owner",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create new session with a fake message from owner
|
||||||
|
mock.message("test-owner", "create", draft.SessionOptions{
|
||||||
|
Players: 8, // Two players, six bots
|
||||||
|
Options: draft.DraftOptions{
|
||||||
|
Type: draft.DraftSet,
|
||||||
|
Positioning: draft.PosEven,
|
||||||
|
Set: mlp.SetAbsoluteDiscord,
|
||||||
|
PackCount: 4,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
|
mock.expect(t, "session-open", 5)
|
||||||
|
|
||||||
|
// Join session as owner
|
||||||
|
mock.message("test-owner", "join", nil)
|
||||||
|
mock.expect(t, "player-joined-session", 5)
|
||||||
|
|
||||||
|
// .. and as second player
|
||||||
|
mock.message("test-guest", "join", nil)
|
||||||
|
mock.expect(t, "player-joined-session", 5)
|
||||||
|
|
||||||
|
// Try to start the session
|
||||||
|
mock.message("test-owner", "start", nil)
|
||||||
|
|
||||||
|
// These two can happen in any order, so they get their own special check
|
||||||
|
mock.multiexpect(t, 5, "session-start", "draft-order")
|
||||||
|
|
||||||
|
//TODO make players pick cards etc
|
||||||
|
|
||||||
|
// Close the room
|
||||||
|
mock.in <- room.ServerMessage{
|
||||||
|
RoomID: TestRoomName,
|
||||||
|
Type: room.MsgEvent,
|
||||||
|
Event: &room.Event{
|
||||||
|
Type: room.EvtRoomClosed,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestDraftSessionButEverythingGoesWrong(t *testing.T) {
|
||||||
|
mock := makeMockServer()
|
||||||
|
draftbot := draft.NewDraftBot(mock, TestBotName)
|
||||||
|
go mock.Bind(draftbot.OnMessage)
|
||||||
|
|
||||||
|
// Create a new room
|
||||||
|
mock.in <- room.ServerMessage{
|
||||||
|
Type: room.MsgEvent,
|
||||||
|
Event: &room.Event{
|
||||||
|
Type: room.EvtNewRoom,
|
||||||
|
Room: &lobby.Room{
|
||||||
|
Id: TestRoomName,
|
||||||
|
Name: "Test draft room",
|
||||||
|
Creator: "test-owner",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
// Try creating a new session as NOT the owner
|
||||||
|
mock.message("test-guest", "create", draft.SessionOptions{
|
||||||
|
Players: 8, // Two players, six bots
|
||||||
|
Options: draft.DraftOptions{
|
||||||
|
Type: draft.DraftSet,
|
||||||
|
Positioning: draft.PosEven,
|
||||||
|
Set: mlp.SetAbsoluteDiscord,
|
||||||
|
PackCount: 4,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
mock.expect(t, "must-be-owner", 5)
|
||||||
|
|
||||||
|
//TODO:
|
||||||
|
// Try to start session when session doesn't exist
|
||||||
|
// Try to create session twice
|
||||||
|
// Try to start session with no players
|
||||||
|
// Try to start session as not the owner
|
||||||
|
// Try to make too many players join a session
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *MockServer) expect(t *testing.T, typ string, timeout int) {
|
||||||
|
for {
|
||||||
|
select {
|
||||||
|
case msg := <-m.out:
|
||||||
|
// Skip all actions
|
||||||
|
if msg.Type != room.MsgMessage {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check expected type
|
||||||
|
if msg.Message.Type != typ {
|
||||||
|
// Oh noes
|
||||||
|
t.Fatalf("Expected message \"%s\" but got \"%s\"", typ, msg.Message.Type)
|
||||||
|
}
|
||||||
|
return
|
||||||
|
case <-time.After(time.Duration(timeout) * time.Second):
|
||||||
|
t.Fatalf("Expected message \"%s\" but found nothing (timeout after %d seconds)!", typ, timeout)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *MockServer) multiexpect(t *testing.T, timeout int, types ...string) {
|
||||||
|
for {
|
||||||
|
if len(types) < 1 {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
select {
|
||||||
|
case msg := <-m.out:
|
||||||
|
// Skip all actions
|
||||||
|
if msg.Type != room.MsgMessage {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check expected type
|
||||||
|
found := false
|
||||||
|
for i, typ := range types {
|
||||||
|
if typ == msg.Message.Type {
|
||||||
|
found = true
|
||||||
|
types[i] = types[len(types)-1]
|
||||||
|
types = types[:len(types)-1]
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if !found {
|
||||||
|
// Oh noes
|
||||||
|
t.Fatalf("Expected one of %s but got \"%s\"", types, msg.Message.Type)
|
||||||
|
}
|
||||||
|
return
|
||||||
|
case <-time.After(time.Duration(timeout) * time.Second):
|
||||||
|
t.Fatalf("Expected one of %s but found nothing (timeout after %d seconds)!", types, timeout)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *MockServer) message(from string, typ string, data interface{}) {
|
||||||
|
m.in <- room.ServerMessage{
|
||||||
|
RoomID: TestRoomName,
|
||||||
|
Type: room.MsgMessage,
|
||||||
|
Message: &room.Message{
|
||||||
|
From: from,
|
||||||
|
To: TestBotName,
|
||||||
|
Type: typ,
|
||||||
|
Data: data,
|
||||||
|
},
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -32,6 +32,7 @@ github.com/go-kit/kit v0.8.0 h1:Wz+5lgoB0kkuqLEc6NVmwRknTKP6dTGbSqvhZtBI/j0=
|
||||||
github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
|
github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
|
||||||
github.com/go-logfmt/logfmt v0.4.0 h1:MP4Eh7ZCb31lleYCFuwm0oe4/YGak+5l1vA2NOE80nA=
|
github.com/go-logfmt/logfmt v0.4.0 h1:MP4Eh7ZCb31lleYCFuwm0oe4/YGak+5l1vA2NOE80nA=
|
||||||
github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk=
|
github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk=
|
||||||
|
github.com/go-redis/redis v6.15.2+incompatible h1:9SpNVG76gr6InJGxoZ6IuuxaCOQwDAhzyXg+Bs+0Sb4=
|
||||||
github.com/go-redis/redis v6.15.2+incompatible/go.mod h1:NAIEuMOZ/fxfXJIrKDQDz8wamY7mA7PouImQ2Jvg6kA=
|
github.com/go-redis/redis v6.15.2+incompatible/go.mod h1:NAIEuMOZ/fxfXJIrKDQDz8wamY7mA7PouImQ2Jvg6kA=
|
||||||
github.com/go-stack/stack v1.8.0 h1:5SgMzNM5HxrEjV0ww2lTmX6E2Izsfxas4+YHWRs3Lsk=
|
github.com/go-stack/stack v1.8.0 h1:5SgMzNM5HxrEjV0ww2lTmX6E2Izsfxas4+YHWRs3Lsk=
|
||||||
github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=
|
github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=
|
||||||
|
@ -105,6 +106,7 @@ github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5
|
||||||
github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg=
|
github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg=
|
||||||
github.com/miekg/dns v1.1.13 h1:x7DQtkU0cedzeS8TD36tT/w1Hm4rDtfCaYYAHE7TTBI=
|
github.com/miekg/dns v1.1.13 h1:x7DQtkU0cedzeS8TD36tT/w1Hm4rDtfCaYYAHE7TTBI=
|
||||||
github.com/miekg/dns v1.1.13/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg=
|
github.com/miekg/dns v1.1.13/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg=
|
||||||
|
github.com/minio/highwayhash v1.0.0 h1:iMSDhgUILCr0TNm8LWlSjF8N0ZIj2qbO8WHp6Q/J2BA=
|
||||||
github.com/minio/highwayhash v1.0.0/go.mod h1:xQboMTeM9nY9v/LlAOxFctujiv5+Aq2hR5dxBpaMbdc=
|
github.com/minio/highwayhash v1.0.0/go.mod h1:xQboMTeM9nY9v/LlAOxFctujiv5+Aq2hR5dxBpaMbdc=
|
||||||
github.com/mitchellh/cli v1.0.0/go.mod h1:hNIlj7HEI86fIcpObd7a0FcrxTWetlwJDGcceTlRvqc=
|
github.com/mitchellh/cli v1.0.0/go.mod h1:hNIlj7HEI86fIcpObd7a0FcrxTWetlwJDGcceTlRvqc=
|
||||||
github.com/mitchellh/go-homedir v1.0.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0=
|
github.com/mitchellh/go-homedir v1.0.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0=
|
||||||
|
@ -144,6 +146,7 @@ github.com/sirupsen/logrus v1.4.2 h1:SPIRibHv4MatM3XXNO2BJeFLZwZ2LvZgfQ5+UNI2im4
|
||||||
github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE=
|
github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE=
|
||||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||||
github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||||
|
github.com/stretchr/objx v0.2.0 h1:Hbg2NidpLE8veEBkEZTL3CvlkUIVzuU9jDplZO54c48=
|
||||||
github.com/stretchr/objx v0.2.0/go.mod h1:qt09Ya8vawLte6SNmTgCsAVtYtaKzEcn8ATUoHMkEqE=
|
github.com/stretchr/objx v0.2.0/go.mod h1:qt09Ya8vawLte6SNmTgCsAVtYtaKzEcn8ATUoHMkEqE=
|
||||||
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
|
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
|
||||||
github.com/stretchr/testify v1.3.0 h1:TivCn/peBQ7UY8ooIcPgZFpTNSz0Q2U6UrFlUfqbe0Q=
|
github.com/stretchr/testify v1.3.0 h1:TivCn/peBQ7UY8ooIcPgZFpTNSz0Q2U6UrFlUfqbe0Q=
|
||||||
|
|
|
@ -17,14 +17,15 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
var logger log.Logger
|
var logger log.Logger
|
||||||
var logAll *bool
|
var logAll bool
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
consulAddr := flag.String("consul.addr", "consul:8500", "Consul address")
|
consulAddr := flag.String("consul.addr", "consul:8500", "Consul address")
|
||||||
botName := flag.String("bot.name", "draftbot", "Bot name")
|
botName := flag.String("bot.name", "draftbot", "Bot name")
|
||||||
gameFilter := flag.String("filter.game", "mlpccg-mcg", "What game to filter for (separated by comma)")
|
gameFilter := flag.String("filter.game", "mlpccg-mcg", "What game to filter for (separated by comma)")
|
||||||
tagFilter := flag.String("filter.tag", "draft", "What tags to filter for (separated by comma)")
|
tagFilter := flag.String("filter.tag", "draft", "What tags to filter for (separated by comma)")
|
||||||
logAll = flag.Bool("debug.log", false, "Log a lot of stuff")
|
flag.BoolVar(&logAll, "debug.log", false, "Log a lot of stuff")
|
||||||
|
flag.Parse()
|
||||||
|
|
||||||
logger = log.NewLogfmtLogger(os.Stderr)
|
logger = log.NewLogfmtLogger(os.Stderr)
|
||||||
logger = log.With(logger, "ts", log.DefaultTimestampUTC)
|
logger = log.With(logger, "ts", log.DefaultTimestampUTC)
|
||||||
|
|
|
@ -20,7 +20,7 @@ var (
|
||||||
)
|
)
|
||||||
|
|
||||||
type session struct {
|
type session struct {
|
||||||
Options draftOptions
|
Options DraftOptions
|
||||||
Players map[string]*draft.Player
|
Players map[string]*draft.Player
|
||||||
Bots []*bot.Bot
|
Bots []*bot.Bot
|
||||||
Pod *draft.Pod
|
Pod *draft.Pod
|
||||||
|
@ -35,27 +35,34 @@ type session struct {
|
||||||
|
|
||||||
// Types of drafts
|
// Types of drafts
|
||||||
const (
|
const (
|
||||||
draftBlock = "block"
|
DraftBlock = "block"
|
||||||
draftSet = "set"
|
DraftSet = "set"
|
||||||
draftCube = "cube"
|
DraftCube = "cube"
|
||||||
draftI8PCube = "i8pcube"
|
DraftI8PCube = "i8pcube"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Ways in which players can be positioned along the draft pod
|
// Ways in which players can be positioned along the draft pod
|
||||||
const (
|
const (
|
||||||
posRandom = "random" // Place players randomly
|
PosRandom = "random" // Place players randomly
|
||||||
posEven = "even" // Place players spaced as evenly as possible
|
PosEven = "even" // Place players spaced as evenly as possible
|
||||||
)
|
)
|
||||||
|
|
||||||
type draftOptions struct {
|
// SessionOptions is the data contained in a create session request
|
||||||
|
type SessionOptions struct {
|
||||||
|
Players int `json:"players"`
|
||||||
|
Options DraftOptions `json:"options"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// DraftOptions are the options needed for a draft session
|
||||||
|
type DraftOptions struct {
|
||||||
Type string `json:"type"`
|
Type string `json:"type"`
|
||||||
Positioning string `json:"positioning"`
|
Positioning string `json:"positioning"`
|
||||||
|
|
||||||
// Block draft properties
|
// Block draft properties
|
||||||
Block string `json:"block,omitempty"`
|
Block mlp.BlockID `json:"block,omitempty"`
|
||||||
|
|
||||||
// Set draft properties
|
// Set draft properties
|
||||||
Set string `json:"set,omitempty"`
|
Set mlp.SetID `json:"set,omitempty"`
|
||||||
|
|
||||||
// Cube draft properties
|
// Cube draft properties
|
||||||
CubeURL string `json:"cube_url,omitempty"`
|
CubeURL string `json:"cube_url,omitempty"`
|
||||||
|
@ -69,17 +76,17 @@ type draftOptions struct {
|
||||||
PackCount int `json:"pack_count,omitempty"` // Set and Cube
|
PackCount int `json:"pack_count,omitempty"` // Set and Cube
|
||||||
}
|
}
|
||||||
|
|
||||||
func (do draftOptions) getProvider() (draft.PackProvider, error) {
|
func (do DraftOptions) getProvider() (draft.PackProvider, error) {
|
||||||
switch do.Type {
|
switch do.Type {
|
||||||
case draftBlock:
|
case DraftBlock:
|
||||||
return mlp.BlockPacks(mlp.BlockID(do.Block))
|
return mlp.BlockPacks(do.Block)
|
||||||
case draftSet:
|
case DraftSet:
|
||||||
set, err := mlp.LoadSetHTTP(mlp.SetID(do.Set))
|
set, err := mlp.LoadSetHTTP(do.Set)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
return draft.PacksFromSet(do.PackCount, set), nil
|
return draft.PacksFromSet(do.PackCount, set), nil
|
||||||
case draftCube:
|
case DraftCube:
|
||||||
cards, err := loadCube(do.CubeURL)
|
cards, err := loadCube(do.CubeURL)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
@ -89,7 +96,7 @@ func (do draftOptions) getProvider() (draft.PackProvider, error) {
|
||||||
PackSize: do.PackSize,
|
PackSize: do.PackSize,
|
||||||
}
|
}
|
||||||
return draft.PacksFromSet(do.PackCount, cube), nil
|
return draft.PacksFromSet(do.PackCount, cube), nil
|
||||||
case draftI8PCube:
|
case DraftI8PCube:
|
||||||
cube, err := loadI8PCube(do.CubeURL)
|
cube, err := loadI8PCube(do.CubeURL)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
@ -99,7 +106,7 @@ func (do draftOptions) getProvider() (draft.PackProvider, error) {
|
||||||
return nil, errors.New("unknown draft type")
|
return nil, errors.New("unknown draft type")
|
||||||
}
|
}
|
||||||
|
|
||||||
func newSession(playerCount int, opt draftOptions) (*session, error) {
|
func newSession(playerCount int, opt DraftOptions) (*session, error) {
|
||||||
// Get pack provider for given options
|
// Get pack provider for given options
|
||||||
provider, err := opt.getProvider()
|
provider, err := opt.getProvider()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -109,6 +116,7 @@ func newSession(playerCount int, opt draftOptions) (*session, error) {
|
||||||
return &session{
|
return &session{
|
||||||
Options: opt,
|
Options: opt,
|
||||||
Pod: draft.MakePod(playerCount, provider),
|
Pod: draft.MakePod(playerCount, provider),
|
||||||
|
Players: make(map[string]*draft.Player),
|
||||||
messages: make(chan room.Message),
|
messages: make(chan room.Message),
|
||||||
exit: make(chan bool),
|
exit: make(chan bool),
|
||||||
}, nil
|
}, nil
|
||||||
|
@ -130,7 +138,7 @@ func (s *session) Start() error {
|
||||||
playerSpot := make(map[int]string)
|
playerSpot := make(map[int]string)
|
||||||
|
|
||||||
switch s.Options.Positioning {
|
switch s.Options.Positioning {
|
||||||
case posRandom:
|
case PosRandom:
|
||||||
// Assign a random number to each player
|
// Assign a random number to each player
|
||||||
for pname := range s.Players {
|
for pname := range s.Players {
|
||||||
var pos int
|
var pos int
|
||||||
|
@ -143,7 +151,7 @@ func (s *session) Start() error {
|
||||||
}
|
}
|
||||||
playerSpot[pos] = pname
|
playerSpot[pos] = pname
|
||||||
}
|
}
|
||||||
case posEven:
|
case PosEven:
|
||||||
// Space players evenly
|
// Space players evenly
|
||||||
playerRatio := float64(spots) / float64(players)
|
playerRatio := float64(spots) / float64(players)
|
||||||
i := 0
|
i := 0
|
||||||
|
|
Loading…
Reference in a new issue