190 lines
4.5 KiB
Go
190 lines
4.5 KiB
Go
package main
|
|
|
|
import (
|
|
"fmt"
|
|
|
|
"github.com/mitchellh/mapstructure"
|
|
|
|
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) {
|
|
// Get session options from data
|
|
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),
|
|
})
|
|
}
|
|
|
|
func (d *DraftBot) cmdStartSession(roomid string, msg room.Message) {
|
|
// 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!",
|
|
})
|
|
}
|
|
|
|
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,
|
|
Type: "must-be-owner",
|
|
Message: "Sorry, only the room's owner can tell me to do that",
|
|
})
|
|
return
|
|
}
|
|
|
|
// Check done, call wrapped function
|
|
wrapped(roomid, msg)
|
|
}
|
|
}
|