2019-06-26 10:56:02 +00:00
package main
import (
2019-06-27 14:59:52 +00:00
"fmt"
2019-06-26 10:56:02 +00:00
room "git.fromouter.space/mcg/cardgage/room/api"
2019-06-27 14:59:52 +00:00
"git.fromouter.space/mcg/draft"
2019-06-26 10:56:02 +00:00
)
type draftBot struct {
2019-06-27 14:59:52 +00:00
API BotInterface
2019-06-27 11:49:57 +00:00
Name string
2019-06-27 14:59:52 +00:00
Rooms map [ string ] roomInfo
2019-06-26 10:56:02 +00:00
Sessions map [ string ] session
}
2019-06-27 14:59:52 +00:00
type roomInfo struct {
Name string
Owner string
}
// BotInterface is the interface needed by draftbot for working in cardgage
// This exists so that draftbot can be attached to a mocked API for testing
type BotInterface interface {
Send ( room . BotMessage )
}
func newDraftBot ( botAPI BotInterface , name string ) * draftBot {
2019-06-26 10:56:02 +00:00
return & draftBot {
2019-06-27 15:12:39 +00:00
API : botAPI ,
2019-06-27 11:49:57 +00:00
Name : name ,
2019-06-26 10:56:02 +00:00
Sessions : make ( map [ string ] session ) ,
}
}
func ( d * draftBot ) onMessage ( msg room . ServerMessage ) {
switch msg . Type {
case room . MsgMessage :
2019-06-27 11:49:57 +00:00
if * logAll {
logger . Log ( "event" , "message" ,
"roomid" , msg . RoomID ,
"from" , msg . Message . From ,
"to" , msg . Message . To ,
"content" , msg . Message . Message )
}
// Only consider messages that speak directly to me
if msg . Message . To == d . Name {
2019-06-27 14:59:52 +00:00
d . handleMessage ( msg . RoomID , * msg . Message )
2019-06-27 11:49:57 +00:00
}
2019-06-26 10:56:02 +00:00
case room . MsgEvent :
2019-06-27 11:49:57 +00:00
if * logAll {
logger . Log ( "event" , "event" ,
"roomid" , msg . RoomID ,
"content" , msg . Event . Message )
}
2019-06-26 10:56:02 +00:00
}
}
2019-06-27 11:49:57 +00:00
2019-06-27 14:59:52 +00:00
func ( d * draftBot ) sendMessage ( roomid string , msg room . Message ) {
d . API . Send ( room . BotMessage {
RoomID : roomid ,
Type : room . MsgMessage ,
Message : & msg ,
} )
}
func ( d * draftBot ) handleMessage ( roomid string , msg room . Message ) {
// Get session in room
session , ok := d . Sessions [ roomid ]
if ! ok {
// Room does not have a currently running session, ignore unless it's the owner asking for specific stuff
//TODO
2019-06-27 16:14:17 +00:00
return
2019-06-27 14:59:52 +00:00
}
// Check if player is in the draft
player , ok := session . Players [ msg . From ]
if ! ok {
// Player not in draft, are they asking to join?
2019-06-27 16:14:17 +00:00
switch msg . Type {
// Player is asking to join
case "join" :
// Players can only join if session didn't start yet
if session . started {
d . sendMessage ( roomid , room . Message {
To : msg . From ,
Type : "session-already-started" ,
Message : "You can't join a running session" ,
} )
return
}
// Check if there are still open slots
if len ( session . Players ) + 1 > len ( session . Pod . Players ) {
d . sendMessage ( roomid , room . Message {
To : msg . From ,
Type : "session-full" ,
Message : "There aren't any spots left" ,
} )
return
}
// Add player to the list
session . Players [ msg . From ] = nil
2019-06-27 16:15:51 +00:00
d . sendMessage ( roomid , room . Message {
Channel : "draft" ,
Type : "player-joined-session" ,
Data : msg . From ,
Message : fmt . Sprintf ( "%s joined the draft session (%d players, %d missing)" , msg . From , len ( session . Players ) , len ( session . Pod . Players ) - len ( session . Players ) ) ,
} )
2019-06-27 16:14:17 +00:00
// Player wants something else
default :
// Tell them can either join or GTFO
d . sendMessage ( roomid , room . Message {
To : msg . From ,
Type : "not-joined-err" ,
Data : "not joined" ,
Message : "You must join the session to do anything" ,
} )
return
}
return
2019-06-27 14:59:52 +00:00
}
switch msg . Type {
// Player has picked a card
case "pick" :
// Get picked card
picked := msg . Data . ( string )
// Try to pick on player struct
err := player . Pick ( draft . Card { ID : picked } )
if err != nil {
if err == draft . ErrNotInPack {
d . sendMessage ( roomid , room . Message {
To : msg . From ,
Type : "invalid-pick" ,
} )
} else {
// Technically not needed, as Pick can only throw ErrNotInPack right now
}
return
}
d . sendMessage ( roomid , room . Message {
Channel : "draft" ,
Type : "card-picked" ,
Data : struct {
Player string
} {
msg . From ,
} ,
Message : fmt . Sprintf ( "%s picked a card from his pack" , msg . From ) ,
} )
}
2019-06-27 11:49:57 +00:00
}