package main import ( room "git.fromouter.space/mcg/cardgage/room/api" ) // DraftBot is the functional part of draftbot type DraftBot struct { API BotInterface 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, 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 *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 { d.handleMessage(msg.RoomID, *msg.Message) } case room.MsgEvent: if *logAll { 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, } // 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) } }