153 lines
3.6 KiB
Go
153 lines
3.6 KiB
Go
|
package draftbot
|
||
|
|
||
|
import (
|
||
|
room "git.fromouter.space/mcg/cardgage/room/api"
|
||
|
"github.com/go-kit/kit/log"
|
||
|
)
|
||
|
|
||
|
// DraftBot is the functional part of draftbot
|
||
|
type DraftBot struct {
|
||
|
API BotInterface
|
||
|
Logger log.Logger
|
||
|
Name string
|
||
|
Rooms map[string]roomInfo
|
||
|
Sessions map[string]*session
|
||
|
}
|
||
|
|
||
|
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)
|
||
|
}
|
||
|
|
||
|
// NewDraftBot creates a new draft bot instance with the given name
|
||
|
// and communication interface
|
||
|
func NewDraftBot(botAPI BotInterface, name string) *DraftBot {
|
||
|
return &DraftBot{
|
||
|
API: botAPI,
|
||
|
Name: name,
|
||
|
Rooms: make(map[string]roomInfo),
|
||
|
Sessions: make(map[string]*session),
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// OnMessage is the function to be called when messages are received
|
||
|
func (d *DraftBot) OnMessage(msg room.ServerMessage) {
|
||
|
switch msg.Type {
|
||
|
case room.MsgMessage:
|
||
|
if d.Logger != nil {
|
||
|
d.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 {
|
||
|
d.handleMessage(msg.RoomID, *msg.Message)
|
||
|
}
|
||
|
case room.MsgEvent:
|
||
|
if d.Logger != nil {
|
||
|
d.Logger.Log("event", "event",
|
||
|
"roomid", msg.RoomID,
|
||
|
"content", msg.Event.Message)
|
||
|
}
|
||
|
d.handleEvent(msg.RoomID, *msg.Event)
|
||
|
}
|
||
|
}
|
||
|
|
||
|
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
|
||
|
d.commands(commandMap{
|
||
|
// Owner wants to create a session
|
||
|
"create": d.cmdfnOnlyOwner(d.cmdCreateSession),
|
||
|
})(roomid, msg)
|
||
|
return
|
||
|
}
|
||
|
|
||
|
// Check if player is in the draft
|
||
|
_, ok = session.Players[msg.From]
|
||
|
if !ok {
|
||
|
// Player not in draft, are they asking to join?
|
||
|
d.commands(commandMap{
|
||
|
// Player wants to join the session
|
||
|
"join": d.cmdJoinSession,
|
||
|
// Owner wants to start the session (but not partecipate)
|
||
|
"start": d.cmdfnOnlyOwner(d.cmdStartSession),
|
||
|
})(roomid, msg)
|
||
|
return
|
||
|
}
|
||
|
|
||
|
// Players in the draft session
|
||
|
d.commands(commandMap{
|
||
|
// Player has picked a card
|
||
|
"pick": d.cmdPickCard,
|
||
|
// Owner wants to start the session
|
||
|
"start": d.cmdfnOnlyOwner(d.cmdStartSession),
|
||
|
})(roomid, msg)
|
||
|
}
|
||
|
|
||
|
func (d *DraftBot) handleEvent(roomid string, evt room.Event) {
|
||
|
switch evt.Type {
|
||
|
|
||
|
// Got added to a new room
|
||
|
case room.EvtNewRoom:
|
||
|
// Add room to the list
|
||
|
d.Rooms[evt.Room.Id] = roomInfo{
|
||
|
Name: evt.Room.Name,
|
||
|
Owner: evt.Room.Creator,
|
||
|
}
|
||
|
|
||
|
// Someone left
|
||
|
case room.EvtLeft:
|
||
|
// Check if room has a running session
|
||
|
sess, ok := d.Sessions[roomid]
|
||
|
if !ok {
|
||
|
break
|
||
|
}
|
||
|
// Check if player is in that session
|
||
|
player, ok := sess.Players[evt.PlayerName]
|
||
|
if !ok {
|
||
|
break
|
||
|
}
|
||
|
// Replace player with bot
|
||
|
//TODO
|
||
|
_ = player
|
||
|
|
||
|
// A room got closed
|
||
|
case room.EvtRoomClosed:
|
||
|
// Check if there's a session there
|
||
|
session, ok := d.Sessions[roomid]
|
||
|
if ok {
|
||
|
// Close session
|
||
|
session.exit <- true
|
||
|
// Remove session from list
|
||
|
delete(d.Sessions, roomid)
|
||
|
}
|
||
|
// Remove room from list
|
||
|
delete(d.Rooms, roomid)
|
||
|
}
|
||
|
}
|
||
|
|
||
|
func (d *DraftBot) handleSessionMessages(roomid string, s *session) {
|
||
|
for msg := range s.messages {
|
||
|
d.sendMessage(roomid, msg)
|
||
|
}
|
||
|
}
|