mirror of https://github.com/velour/catbase.git
Big overhaul again! Replaced fluffle's goirc library with velour/irc.
Hopefully this new library will provide me with some benefits such as being able to actually get and respond to a WHO message. Yet to do is to fix sendMessage to be a channel on Bot with a goroutine that formats and sends messages on. Also, figuring out how to handle the WHO response and populate users.
This commit is contained in:
parent
8cf2b997a2
commit
2c0dc55452
78
bot/bot.go
78
bot/bot.go
|
@ -1,8 +1,8 @@
|
||||||
package bot
|
package bot
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"code.google.com/p/velour/irc"
|
||||||
"github.com/chrissexton/alepale/config"
|
"github.com/chrissexton/alepale/config"
|
||||||
irc "github.com/fluffle/goirc/client"
|
|
||||||
"html/template"
|
"html/template"
|
||||||
"labix.org/v2/mgo"
|
"labix.org/v2/mgo"
|
||||||
"log"
|
"log"
|
||||||
|
@ -11,6 +11,8 @@ import (
|
||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
const actionPrefix = "\x01ACTION"
|
||||||
|
|
||||||
// Bot type provides storage for bot-wide information, configs, and database connections
|
// Bot type provides storage for bot-wide information, configs, and database connections
|
||||||
type Bot struct {
|
type Bot struct {
|
||||||
// Each plugin must be registered in our plugins handler. To come: a map so that this
|
// Each plugin must be registered in our plugins handler. To come: a map so that this
|
||||||
|
@ -24,7 +26,7 @@ type Bot struct {
|
||||||
Me User
|
Me User
|
||||||
|
|
||||||
// Conn allows us to send messages and modify our connection state
|
// Conn allows us to send messages and modify our connection state
|
||||||
Conn *irc.Conn
|
Client *irc.Client
|
||||||
|
|
||||||
Config *config.Config
|
Config *config.Config
|
||||||
|
|
||||||
|
@ -78,23 +80,6 @@ func (l *Logger) Run() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// User type stores user history. This is a vehicle that will follow the user for the active
|
|
||||||
// session
|
|
||||||
type User struct {
|
|
||||||
// Current nickname known
|
|
||||||
Name string
|
|
||||||
|
|
||||||
// LastSeen DateTime
|
|
||||||
|
|
||||||
// Alternative nicknames seen
|
|
||||||
Alts []string
|
|
||||||
|
|
||||||
// Last N messages sent to the user
|
|
||||||
MessageLog []string
|
|
||||||
|
|
||||||
Admin bool
|
|
||||||
}
|
|
||||||
|
|
||||||
type Message struct {
|
type Message struct {
|
||||||
User *User
|
User *User
|
||||||
Channel, Body string
|
Channel, Body string
|
||||||
|
@ -110,7 +95,7 @@ type Variable struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewBot creates a Bot for a given connection and set of handlers.
|
// NewBot creates a Bot for a given connection and set of handlers.
|
||||||
func NewBot(config *config.Config, c *irc.Conn) *Bot {
|
func NewBot(config *config.Config, c *irc.Client) *Bot {
|
||||||
session, err := mgo.Dial(config.DbServer)
|
session, err := mgo.Dial(config.DbServer)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
|
@ -123,12 +108,9 @@ func NewBot(config *config.Config, c *irc.Conn) *Bot {
|
||||||
|
|
||||||
RunNewLogger(logIn, logOut)
|
RunNewLogger(logIn, logOut)
|
||||||
|
|
||||||
config.Nick = c.Me.Nick
|
|
||||||
|
|
||||||
users := []User{
|
users := []User{
|
||||||
User{
|
User{
|
||||||
Name: config.Nick,
|
Name: config.Nick,
|
||||||
MessageLog: make([]string, 0),
|
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -138,7 +120,7 @@ func NewBot(config *config.Config, c *irc.Conn) *Bot {
|
||||||
PluginOrdering: make([]string, 0),
|
PluginOrdering: make([]string, 0),
|
||||||
Users: users,
|
Users: users,
|
||||||
Me: users[0],
|
Me: users[0],
|
||||||
Conn: c,
|
Client: c,
|
||||||
DbSession: session,
|
DbSession: session,
|
||||||
Db: db,
|
Db: db,
|
||||||
varColl: db.C("variables"),
|
varColl: db.C("variables"),
|
||||||
|
@ -166,25 +148,44 @@ func (b *Bot) AddHandler(name string, h Handler) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Sends message to channel
|
|
||||||
func (b *Bot) SendMessage(channel, message string) {
|
func (b *Bot) SendMessage(channel, message string) {
|
||||||
b.Conn.Privmsg(channel, message)
|
for len(message) > 0 {
|
||||||
|
m := irc.Msg{
|
||||||
|
Cmd: "PRIVMSG",
|
||||||
|
Args: []string{channel, message},
|
||||||
|
}
|
||||||
|
_, err := m.RawString()
|
||||||
|
if err != nil {
|
||||||
|
mtl := err.(irc.MsgTooLong)
|
||||||
|
m.Args[1] = message[:mtl.NTrunc]
|
||||||
|
message = message[mtl.NTrunc:]
|
||||||
|
} else {
|
||||||
|
message = ""
|
||||||
|
}
|
||||||
|
b.Client.Out <- m
|
||||||
|
}
|
||||||
|
|
||||||
// Notify plugins that we've said something
|
|
||||||
b.selfSaid(channel, message)
|
b.selfSaid(channel, message)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Sends action to channel
|
// Sends action to channel
|
||||||
func (b *Bot) SendAction(channel, message string) {
|
func (b *Bot) SendAction(channel, message string) {
|
||||||
b.Conn.Action(channel, message)
|
// TODO: ADD CTCP ACTION
|
||||||
|
message = actionPrefix + " " + message + "\x01"
|
||||||
|
|
||||||
|
b.SendMessage(channel, message)
|
||||||
|
|
||||||
// Notify plugins that we've said something
|
// Notify plugins that we've said something
|
||||||
b.selfSaid(channel, message)
|
b.selfSaid(channel, message)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Handles incomming PRIVMSG requests
|
// Handles incomming PRIVMSG requests
|
||||||
func (b *Bot) MsgRecieved(conn *irc.Conn, line *irc.Line) {
|
func (b *Bot) MsgRecieved(client *irc.Client, inMsg irc.Msg) {
|
||||||
msg := b.buildMessage(conn, line)
|
if inMsg.User == "" {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
msg := b.buildMessage(client, inMsg)
|
||||||
|
|
||||||
if strings.HasPrefix(msg.Body, "help") && msg.Command {
|
if strings.HasPrefix(msg.Body, "help") && msg.Command {
|
||||||
parts := strings.Fields(strings.ToLower(msg.Body))
|
parts := strings.Fields(strings.ToLower(msg.Body))
|
||||||
|
@ -204,6 +205,23 @@ RET:
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (b *Bot) EventRecieved(conn *irc.Client, inMsg irc.Msg) {
|
||||||
|
if inMsg.User == "" {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
msg := b.buildMessage(conn, inMsg)
|
||||||
|
for _, name := range b.PluginOrdering {
|
||||||
|
p := b.Plugins[name]
|
||||||
|
if p.Event(inMsg.Cmd, msg) {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (b *Bot) Who(channel string) []User {
|
||||||
|
return b.Users
|
||||||
|
}
|
||||||
|
|
||||||
var rootIndex string = `
|
var rootIndex string = `
|
||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html>
|
<html>
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
package bot
|
package bot
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"code.google.com/p/velour/irc"
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"labix.org/v2/mgo/bson"
|
"labix.org/v2/mgo/bson"
|
||||||
|
@ -10,7 +11,6 @@ import (
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
import irc "github.com/fluffle/goirc/client"
|
|
||||||
|
|
||||||
// Interface used for compatibility with the Plugin interface
|
// Interface used for compatibility with the Plugin interface
|
||||||
type Handler interface {
|
type Handler interface {
|
||||||
|
@ -21,35 +21,6 @@ type Handler interface {
|
||||||
RegisterWeb() *string
|
RegisterWeb() *string
|
||||||
}
|
}
|
||||||
|
|
||||||
// Checks to see if our user exists and if any changes have occured to it
|
|
||||||
// This uses a linear scan for now, oh well.
|
|
||||||
func (b *Bot) checkuser(nick string) *User {
|
|
||||||
var user *User = nil
|
|
||||||
for _, usr := range b.Users {
|
|
||||||
if usr.Name == nick {
|
|
||||||
user = &usr
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if user == nil {
|
|
||||||
isadmin := false
|
|
||||||
for _, u := range b.Config.Admins {
|
|
||||||
if nick == u {
|
|
||||||
isadmin = true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
user = &User{
|
|
||||||
Name: nick,
|
|
||||||
Alts: make([]string, 1),
|
|
||||||
MessageLog: make([]string, 50),
|
|
||||||
Admin: isadmin,
|
|
||||||
}
|
|
||||||
b.Users = append(b.Users, *user)
|
|
||||||
}
|
|
||||||
|
|
||||||
return user
|
|
||||||
}
|
|
||||||
|
|
||||||
// Checks to see if the user is asking for help, returns true if so and handles the situation.
|
// Checks to see if the user is asking for help, returns true if so and handles the situation.
|
||||||
func (b *Bot) checkHelp(channel string, parts []string) {
|
func (b *Bot) checkHelp(channel string, parts []string) {
|
||||||
if len(parts) == 1 {
|
if len(parts) == 1 {
|
||||||
|
@ -82,7 +53,7 @@ func (b *Bot) checkHelp(channel string, parts []string) {
|
||||||
// Checks if message is a command and returns its curtailed version
|
// Checks if message is a command and returns its curtailed version
|
||||||
func (b *Bot) isCmd(message string) (bool, string) {
|
func (b *Bot) isCmd(message string) (bool, string) {
|
||||||
cmdc := b.Config.CommandChar
|
cmdc := b.Config.CommandChar
|
||||||
botnick := strings.ToLower(b.Conn.Me.Nick)
|
botnick := strings.ToLower(b.Config.Nick)
|
||||||
iscmd := false
|
iscmd := false
|
||||||
lowerMessage := strings.ToLower(message)
|
lowerMessage := strings.ToLower(message)
|
||||||
|
|
||||||
|
@ -112,39 +83,43 @@ func (b *Bot) isCmd(message string) (bool, string) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Builds our internal message type out of a Conn & Line from irc
|
// Builds our internal message type out of a Conn & Line from irc
|
||||||
func (b *Bot) buildMessage(conn *irc.Conn, line *irc.Line) Message {
|
func (b *Bot) buildMessage(conn *irc.Client, inMsg irc.Msg) Message {
|
||||||
// Check for the user
|
// Check for the user
|
||||||
user := b.checkuser(line.Nick)
|
user := b.GetUser(inMsg.Origin)
|
||||||
|
|
||||||
channel := line.Args[0]
|
channel := inMsg.Args[0]
|
||||||
if channel == conn.Me.Nick {
|
if channel == b.Config.Nick {
|
||||||
channel = line.Nick
|
channel = inMsg.Args[0]
|
||||||
}
|
}
|
||||||
|
|
||||||
isaction := line.Cmd == "ACTION"
|
isAction := false
|
||||||
|
|
||||||
var message string
|
var message string
|
||||||
if len(line.Args) > 1 {
|
if len(inMsg.Args) > 1 {
|
||||||
message = line.Args[1]
|
message = inMsg.Args[1]
|
||||||
|
|
||||||
|
isAction = strings.HasPrefix(message, actionPrefix)
|
||||||
|
if isAction {
|
||||||
|
message = strings.TrimRight(message[len(actionPrefix):], "\x01")
|
||||||
|
message = strings.TrimSpace(message)
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
iscmd := false
|
iscmd := false
|
||||||
filteredMessage := message
|
filteredMessage := message
|
||||||
if !isaction {
|
if !isAction {
|
||||||
iscmd, filteredMessage = b.isCmd(message)
|
iscmd, filteredMessage = b.isCmd(message)
|
||||||
}
|
}
|
||||||
|
|
||||||
user.MessageLog = append(user.MessageLog, message)
|
|
||||||
|
|
||||||
msg := Message{
|
msg := Message{
|
||||||
User: user,
|
User: user,
|
||||||
Channel: channel,
|
Channel: channel,
|
||||||
Body: filteredMessage,
|
Body: filteredMessage,
|
||||||
Raw: message,
|
Raw: message,
|
||||||
Command: iscmd,
|
Command: iscmd,
|
||||||
Action: isaction,
|
Action: isAction,
|
||||||
Time: time.Now(),
|
Time: time.Now(),
|
||||||
Host: line.Host,
|
Host: inMsg.Host,
|
||||||
}
|
}
|
||||||
|
|
||||||
return msg
|
return msg
|
||||||
|
@ -175,7 +150,8 @@ func (b *Bot) Filter(message Message, input string) string {
|
||||||
}
|
}
|
||||||
|
|
||||||
if strings.Contains(input, "$someone") {
|
if strings.Contains(input, "$someone") {
|
||||||
someone := b.Users[rand.Intn(len(b.Users))].Name
|
nicks := b.Who(message.Channel)
|
||||||
|
someone := nicks[rand.Intn(len(nicks))].Name
|
||||||
input = strings.Replace(input, "$someone", someone, -1)
|
input = strings.Replace(input, "$someone", someone, -1)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -232,16 +208,6 @@ func (b *Bot) Help(channel string, parts []string) {
|
||||||
b.SendMessage(channel, msg)
|
b.SendMessage(channel, msg)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (b *Bot) ActionRecieved(conn *irc.Conn, line *irc.Line) {
|
|
||||||
msg := b.buildMessage(conn, line)
|
|
||||||
for _, name := range b.PluginOrdering {
|
|
||||||
p := b.Plugins[name]
|
|
||||||
if p.Event(line.Cmd, msg) {
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Send our own musings to the plugins
|
// Send our own musings to the plugins
|
||||||
func (b *Bot) selfSaid(channel, message string) {
|
func (b *Bot) selfSaid(channel, message string) {
|
||||||
msg := Message{
|
msg := Message{
|
||||||
|
|
|
@ -0,0 +1,110 @@
|
||||||
|
package bot
|
||||||
|
|
||||||
|
import (
|
||||||
|
// "labix.org/v2/mgo"
|
||||||
|
"labix.org/v2/mgo/bson"
|
||||||
|
"log"
|
||||||
|
)
|
||||||
|
|
||||||
|
// User type stores user history. This is a vehicle that will follow the user for the active
|
||||||
|
// session
|
||||||
|
type User struct {
|
||||||
|
// Current nickname known
|
||||||
|
Name string
|
||||||
|
|
||||||
|
// LastSeen DateTime
|
||||||
|
|
||||||
|
// Alternative nicknames seen
|
||||||
|
Alts []string
|
||||||
|
Parent string
|
||||||
|
|
||||||
|
Admin bool
|
||||||
|
|
||||||
|
bot *Bot
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewUser(nick string) *User {
|
||||||
|
return &User{
|
||||||
|
Name: nick,
|
||||||
|
Admin: false,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (b *Bot) GetUser(nick string) *User {
|
||||||
|
coll := b.Db.C("users")
|
||||||
|
query := coll.Find(bson.M{"nick": nick})
|
||||||
|
var user *User
|
||||||
|
|
||||||
|
if count, err := query.Count(); err != nil {
|
||||||
|
log.Printf("Error fetching user, %s: %s\n", nick, err)
|
||||||
|
user = NewUser(nick)
|
||||||
|
coll.Insert(NewUser(nick))
|
||||||
|
} else if count == 1 {
|
||||||
|
query.One(user)
|
||||||
|
} else if count == 0 {
|
||||||
|
// create the user
|
||||||
|
user = NewUser(nick)
|
||||||
|
coll.Insert(NewUser(nick))
|
||||||
|
} else {
|
||||||
|
log.Printf("Error: %s appears to have more than one user?\n", nick)
|
||||||
|
query.One(user)
|
||||||
|
}
|
||||||
|
|
||||||
|
// grab linked user, if any
|
||||||
|
if user.Parent != "" {
|
||||||
|
query := coll.Find(bson.M{"Name": user.Parent})
|
||||||
|
if count, err := query.Count(); err != nil && count == 1 {
|
||||||
|
query.One(user)
|
||||||
|
} else {
|
||||||
|
log.Printf("Error: bad linkage on %s -> %s.\n",
|
||||||
|
user.Name,
|
||||||
|
user.Parent)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
user.bot = b
|
||||||
|
|
||||||
|
found := false
|
||||||
|
for _, u := range b.Users {
|
||||||
|
if u.Name == user.Name {
|
||||||
|
found = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if !found {
|
||||||
|
b.Users = append(b.Users, *user)
|
||||||
|
}
|
||||||
|
|
||||||
|
return user
|
||||||
|
}
|
||||||
|
|
||||||
|
// Modify user entry to be a link to other, return other
|
||||||
|
func (u *User) LinkUser(other string) *User {
|
||||||
|
coll := u.bot.Db.C("users")
|
||||||
|
user := u.bot.GetUser(u.Name)
|
||||||
|
otherUser := u.bot.GetUser(other)
|
||||||
|
|
||||||
|
otherUser.Alts = append(otherUser.Alts, user.Alts...)
|
||||||
|
user.Alts = []string{}
|
||||||
|
user.Parent = other
|
||||||
|
|
||||||
|
err := coll.Update(bson.M{"Name": u.Name}, u)
|
||||||
|
if err != nil {
|
||||||
|
log.Printf("Error updating user: %s\n", u.Name)
|
||||||
|
}
|
||||||
|
|
||||||
|
err = coll.Update(bson.M{"Name": other}, otherUser)
|
||||||
|
if err != nil {
|
||||||
|
log.Printf("Error updating other user: %s\n", other)
|
||||||
|
}
|
||||||
|
|
||||||
|
return otherUser
|
||||||
|
}
|
||||||
|
|
||||||
|
func (b *Bot) checkAdmin(nick string) bool {
|
||||||
|
for _, u := range b.Config.Admins {
|
||||||
|
if nick == u {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
|
@ -5,8 +5,9 @@
|
||||||
"MainChannel": "#AlePaleTest",
|
"MainChannel": "#AlePaleTest",
|
||||||
"Plugins": [],
|
"Plugins": [],
|
||||||
"Server": "127.0.0.1:6666",
|
"Server": "127.0.0.1:6666",
|
||||||
"Nick": "alepaletest",
|
"Nick": "AlePaleTest",
|
||||||
"Pass": "AlePaleTest:test",
|
"Pass": "AlePaleTest:test",
|
||||||
|
"FullName": "Ale Pale",
|
||||||
"CommandChar": "!",
|
"CommandChar": "!",
|
||||||
"QuoteChance": 0.99,
|
"QuoteChance": 0.99,
|
||||||
"QuoteTime": 1,
|
"QuoteTime": 1,
|
||||||
|
|
|
@ -13,6 +13,7 @@ type Config struct {
|
||||||
MainChannel string
|
MainChannel string
|
||||||
Plugins []string
|
Plugins []string
|
||||||
Nick, Server, Pass string
|
Nick, Server, Pass string
|
||||||
|
FullName string
|
||||||
Version string
|
Version string
|
||||||
CommandChar string
|
CommandChar string
|
||||||
QuoteChance float64
|
QuoteChance float64
|
||||||
|
|
234
main.go
234
main.go
|
@ -1,98 +1,178 @@
|
||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"code.google.com/p/velour/irc"
|
||||||
"flag"
|
"flag"
|
||||||
"fmt"
|
|
||||||
"github.com/chrissexton/alepale/bot"
|
"github.com/chrissexton/alepale/bot"
|
||||||
"github.com/chrissexton/alepale/config"
|
"github.com/chrissexton/alepale/config"
|
||||||
"github.com/chrissexton/alepale/plugins"
|
"github.com/chrissexton/alepale/plugins"
|
||||||
|
"io"
|
||||||
|
"log"
|
||||||
|
"os"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
// DefaultPort is the port used to connect to
|
||||||
|
// the server if one is not specified.
|
||||||
|
defaultPort = "6667"
|
||||||
|
|
||||||
|
// InitialTimeout is the initial amount of time
|
||||||
|
// to delay before reconnecting. Each failed
|
||||||
|
// reconnection doubles the timout until
|
||||||
|
// a connection is made successfully.
|
||||||
|
initialTimeout = 2 * time.Second
|
||||||
|
|
||||||
|
// PingTime is the amount of inactive time
|
||||||
|
// to wait before sending a ping to the server.
|
||||||
|
pingTime = 120 * time.Second
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
Client *irc.Client
|
||||||
|
Bot *bot.Bot
|
||||||
|
Config *config.Config
|
||||||
)
|
)
|
||||||
import irc "github.com/fluffle/goirc/client"
|
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
|
var err error
|
||||||
// These belong in the JSON file
|
var cfile = flag.String("config", "config.json",
|
||||||
// var server = flag.String("server", "irc.freenode.net", "Server to connect to.")
|
"Config file to load. (Defaults to config.json)")
|
||||||
// var nick = flag.String("nick", "CrappyBot", "Nick to set upon connection.")
|
|
||||||
// var pass = flag.String("pass", "", "IRC server password to use")
|
|
||||||
// var channel = flag.String("channel", "#AlePaleTest", "Channel to connet to.")
|
|
||||||
|
|
||||||
var cfile = flag.String("config", "config.json", "Config file to load. (Defaults to config.json)")
|
|
||||||
flag.Parse() // parses the logging flags.
|
flag.Parse() // parses the logging flags.
|
||||||
|
|
||||||
config := config.Readconfig(Version, *cfile)
|
Config = config.Readconfig(Version, *cfile)
|
||||||
|
|
||||||
c := irc.SimpleClient(config.Nick)
|
Client, err = irc.DialServer(Config.Server,
|
||||||
// Optionally, enable SSL
|
Config.Nick,
|
||||||
c.SSL = false
|
Config.FullName,
|
||||||
|
Config.Pass)
|
||||||
|
|
||||||
// Add handlers to do things here!
|
if err != nil {
|
||||||
// e.g. join a channel on connect.
|
log.Fatal(err)
|
||||||
c.AddHandler("connected",
|
|
||||||
func(conn *irc.Conn, line *irc.Line) {
|
|
||||||
for _, channel := range config.Channels {
|
|
||||||
conn.Join(channel)
|
|
||||||
fmt.Printf("Now talking in %s.\n", channel)
|
|
||||||
}
|
}
|
||||||
})
|
|
||||||
|
Bot = bot.NewBot(Config, Client)
|
||||||
|
// Bot.AddHandler(plugins.NewTestPlugin(Bot))
|
||||||
|
Bot.AddHandler("admin", plugins.NewAdminPlugin(Bot))
|
||||||
|
Bot.AddHandler("first", plugins.NewFirstPlugin(Bot))
|
||||||
|
Bot.AddHandler("downtime", plugins.NewDowntimePlugin(Bot))
|
||||||
|
Bot.AddHandler("talker", plugins.NewTalkerPlugin(Bot))
|
||||||
|
Bot.AddHandler("dice", plugins.NewDicePlugin(Bot))
|
||||||
|
Bot.AddHandler("beers", plugins.NewBeersPlugin(Bot))
|
||||||
|
Bot.AddHandler("counter", plugins.NewCounterPlugin(Bot))
|
||||||
|
Bot.AddHandler("remember", plugins.NewRememberPlugin(Bot))
|
||||||
|
Bot.AddHandler("skeleton", plugins.NewSkeletonPlugin(Bot))
|
||||||
|
Bot.AddHandler("your", plugins.NewYourPlugin(Bot))
|
||||||
|
// catches anything left, will always return true
|
||||||
|
Bot.AddHandler("factoid", plugins.NewFactoidPlugin(Bot))
|
||||||
|
|
||||||
|
handleConnection()
|
||||||
|
|
||||||
// And a signal on disconnect
|
// And a signal on disconnect
|
||||||
quit := make(chan bool)
|
quit := make(chan bool)
|
||||||
|
|
||||||
c.AddHandler("disconnected",
|
|
||||||
func(conn *irc.Conn, line *irc.Line) { quit <- true })
|
|
||||||
|
|
||||||
b := bot.NewBot(config, c)
|
|
||||||
// b.AddHandler(plugins.NewTestPlugin(b))
|
|
||||||
b.AddHandler("admin", plugins.NewAdminPlugin(b))
|
|
||||||
b.AddHandler("first", plugins.NewFirstPlugin(b))
|
|
||||||
b.AddHandler("downtime", plugins.NewDowntimePlugin(b))
|
|
||||||
b.AddHandler("talker", plugins.NewTalkerPlugin(b))
|
|
||||||
b.AddHandler("dice", plugins.NewDicePlugin(b))
|
|
||||||
b.AddHandler("beers", plugins.NewBeersPlugin(b))
|
|
||||||
b.AddHandler("counter", plugins.NewCounterPlugin(b))
|
|
||||||
b.AddHandler("remember", plugins.NewRememberPlugin(b))
|
|
||||||
b.AddHandler("skeleton", plugins.NewSkeletonPlugin(b))
|
|
||||||
b.AddHandler("your", plugins.NewYourPlugin(b))
|
|
||||||
// catches anything left, will always return true
|
|
||||||
b.AddHandler("factoid", plugins.NewFactoidPlugin(b))
|
|
||||||
|
|
||||||
c.AddHandler("NICK", func(conn *irc.Conn, line *irc.Line) {
|
|
||||||
b.ActionRecieved(conn, line)
|
|
||||||
})
|
|
||||||
|
|
||||||
c.AddHandler("NAMES", func(conn *irc.Conn, line *irc.Line) {
|
|
||||||
b.ActionRecieved(conn, line)
|
|
||||||
})
|
|
||||||
|
|
||||||
c.AddHandler("MODE", func(conn *irc.Conn, line *irc.Line) {
|
|
||||||
b.ActionRecieved(conn, line)
|
|
||||||
})
|
|
||||||
|
|
||||||
c.AddHandler("PART", func(conn *irc.Conn, line *irc.Line) {
|
|
||||||
b.ActionRecieved(conn, line)
|
|
||||||
})
|
|
||||||
|
|
||||||
c.AddHandler("QUIT", func(conn *irc.Conn, line *irc.Line) {
|
|
||||||
b.ActionRecieved(conn, line)
|
|
||||||
})
|
|
||||||
|
|
||||||
c.AddHandler("JOIN", func(conn *irc.Conn, line *irc.Line) {
|
|
||||||
b.ActionRecieved(conn, line)
|
|
||||||
})
|
|
||||||
|
|
||||||
c.AddHandler("ACTION", func(conn *irc.Conn, line *irc.Line) {
|
|
||||||
b.MsgRecieved(conn, line)
|
|
||||||
})
|
|
||||||
|
|
||||||
c.AddHandler("PRIVMSG", func(conn *irc.Conn, line *irc.Line) {
|
|
||||||
b.MsgRecieved(conn, line)
|
|
||||||
})
|
|
||||||
|
|
||||||
// Tell client to connect
|
|
||||||
if err := c.Connect(config.Server, config.Pass); err != nil {
|
|
||||||
fmt.Printf("Connection error: %s\n", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Wait for disconnect
|
// Wait for disconnect
|
||||||
<-quit
|
<-quit
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func handleConnection() {
|
||||||
|
t := time.NewTimer(pingTime)
|
||||||
|
|
||||||
|
defer func() {
|
||||||
|
t.Stop()
|
||||||
|
close(Client.Out)
|
||||||
|
for err := range Client.Errors {
|
||||||
|
if err != io.EOF {
|
||||||
|
log.Println(err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
|
||||||
|
for {
|
||||||
|
select {
|
||||||
|
case msg, ok := <-Client.In:
|
||||||
|
if !ok { // disconnect
|
||||||
|
return
|
||||||
|
}
|
||||||
|
t.Stop()
|
||||||
|
t = time.NewTimer(pingTime)
|
||||||
|
handleMsg(msg)
|
||||||
|
|
||||||
|
case <-t.C:
|
||||||
|
Client.Out <- irc.Msg{Cmd: irc.PING, Args: []string{Client.Server}}
|
||||||
|
t = time.NewTimer(pingTime)
|
||||||
|
|
||||||
|
case err, ok := <-Client.Errors:
|
||||||
|
if ok && err != io.EOF {
|
||||||
|
log.Println(err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// HandleMsg handles IRC messages from the server.
|
||||||
|
func handleMsg(msg irc.Msg) {
|
||||||
|
switch msg.Cmd {
|
||||||
|
case irc.ERROR:
|
||||||
|
log.Println(1, "Received error: "+msg.Raw)
|
||||||
|
|
||||||
|
case irc.PING:
|
||||||
|
Client.Out <- irc.Msg{Cmd: irc.PONG}
|
||||||
|
|
||||||
|
case irc.PONG:
|
||||||
|
// OK, ignore
|
||||||
|
|
||||||
|
case irc.ERR_NOSUCHNICK:
|
||||||
|
Bot.EventRecieved(Client, msg)
|
||||||
|
|
||||||
|
case irc.ERR_NOSUCHCHANNEL:
|
||||||
|
Bot.EventRecieved(Client, msg)
|
||||||
|
|
||||||
|
case irc.RPL_MOTD:
|
||||||
|
Bot.EventRecieved(Client, msg)
|
||||||
|
|
||||||
|
case irc.RPL_NAMREPLY:
|
||||||
|
Bot.EventRecieved(Client, msg)
|
||||||
|
|
||||||
|
case irc.RPL_TOPIC:
|
||||||
|
Bot.EventRecieved(Client, msg)
|
||||||
|
|
||||||
|
case irc.KICK:
|
||||||
|
Bot.EventRecieved(Client, msg)
|
||||||
|
|
||||||
|
case irc.TOPIC:
|
||||||
|
Bot.EventRecieved(Client, msg)
|
||||||
|
|
||||||
|
case irc.MODE:
|
||||||
|
Bot.EventRecieved(Client, msg)
|
||||||
|
|
||||||
|
case irc.JOIN:
|
||||||
|
Bot.EventRecieved(Client, msg)
|
||||||
|
|
||||||
|
case irc.PART:
|
||||||
|
Bot.EventRecieved(Client, msg)
|
||||||
|
|
||||||
|
case irc.QUIT:
|
||||||
|
os.Exit(1)
|
||||||
|
|
||||||
|
case irc.NOTICE:
|
||||||
|
Bot.EventRecieved(Client, msg)
|
||||||
|
|
||||||
|
case irc.PRIVMSG:
|
||||||
|
Bot.MsgRecieved(Client, msg)
|
||||||
|
|
||||||
|
case irc.NICK:
|
||||||
|
Bot.EventRecieved(Client, msg)
|
||||||
|
|
||||||
|
case irc.RPL_WHOREPLY:
|
||||||
|
Bot.EventRecieved(Client, msg)
|
||||||
|
|
||||||
|
case irc.RPL_ENDOFWHO:
|
||||||
|
Bot.EventRecieved(Client, msg)
|
||||||
|
|
||||||
|
default:
|
||||||
|
cmd := irc.CmdNames[msg.Cmd]
|
||||||
|
log.Println("(" + cmd + ") " + msg.Raw)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue