2019-06-28 09:03:42 +00:00
package main
import (
"fmt"
2019-06-28 10:54:58 +00:00
"github.com/mitchellh/mapstructure"
2019-06-28 09:03:42 +00:00
room "git.fromouter.space/mcg/cardgage/room/api"
"git.fromouter.space/mcg/draft"
)
type commandHandler func ( roomid string , msg room . Message )
type commandMap map [ string ] commandHandler
func ( d * DraftBot ) commands ( commands commandMap ) commandHandler {
return func ( roomid string , msg room . Message ) {
action , ok := commands [ msg . Type ]
if ! ok {
cmdlist := [ ] string { }
for cmd := range commands {
cmdlist = append ( cmdlist , cmd )
}
d . sendMessage ( roomid , room . Message {
To : msg . From ,
Type : "command-unavailable" ,
Message : fmt . Sprintf ( "Available commands (at this state) are: %s" , cmdlist ) ,
} )
return
}
action ( roomid , msg )
}
}
func ( d * DraftBot ) cmdJoinSession ( roomid string , msg room . Message ) {
// Get session
session , _ := d . Sessions [ roomid ]
// 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
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 ) ) ,
} )
}
func ( d * DraftBot ) cmdPickCard ( roomid string , msg room . Message ) {
// Get session
session , _ := d . Sessions [ roomid ]
// Get player
player , _ := session . Players [ msg . From ]
// 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 ) ,
} )
}
func ( d * DraftBot ) cmdCreateSession ( roomid string , msg room . Message ) {
2019-06-28 10:54:58 +00:00
// Get session options from data
type sessionOptions struct {
players int
options draftOptions
}
var opt sessionOptions
err := mapstructure . Decode ( msg . Data , & opt )
if err != nil {
d . sendMessage ( roomid , room . Message {
To : msg . From ,
Type : "invalid-data" ,
Message : "Error parsing session options: " + err . Error ( ) ,
} )
return
}
sess , err := newSession ( opt . players , opt . options )
if err != nil {
d . sendMessage ( roomid , room . Message {
To : msg . From ,
Type : "session-create-error" ,
Data : err . Error ( ) ,
Message : "Error creating session: " + err . Error ( ) ,
} )
return
}
// All ok, assign session
d . Sessions [ roomid ] = sess
// Start handling messages for the session
go d . handleSessionMessages ( roomid , sess )
// Tell everyone about the new session
d . sendMessage ( roomid , room . Message {
Channel : "draft" ,
Type : "session-open" ,
Data : opt ,
Message : fmt . Sprintf ( "Created a new draft session for %d players, type: %s" , opt . players , opt . options . Type ) ,
} )
2019-06-28 09:03:42 +00:00
}
func ( d * DraftBot ) cmdStartSession ( roomid string , msg room . Message ) {
2019-06-28 10:54:58 +00:00
// Get session
session , _ := d . Sessions [ roomid ]
// Try starting the session
err := session . Start ( )
if err != nil {
d . sendMessage ( roomid , room . Message {
To : msg . From ,
Type : "session-start-error" ,
Data : err . Error ( ) ,
Message : "Could not start session: " + err . Error ( ) ,
} )
return
}
// Tell everyone about the new session
d . sendMessage ( roomid , room . Message {
Channel : "draft" ,
Type : "session-start" ,
Message : "Session started, get drafting!" ,
} )
2019-06-28 09:03:42 +00:00
}
func ( d * DraftBot ) cmdfnOnlyOwner ( wrapped commandHandler ) commandHandler {
return func ( roomid string , msg room . Message ) {
// Get room the message was sent from
roomData , ok := d . Rooms [ roomid ]
if ! ok {
// Message from a room we're not in?
// Ignore it for now
return
}
// Make sure the message is coming from the room owner
if msg . From != roomData . Owner {
d . sendMessage ( roomid , room . Message {
To : msg . From ,
2019-06-28 10:54:58 +00:00
Type : "must-be-owner" ,
Message : "Sorry, only the room's owner can tell me to do that" ,
2019-06-28 09:03:42 +00:00
} )
return
}
// Check done, call wrapped function
wrapped ( roomid , msg )
}
}