Compare commits
No commits in common. "9b016251f25e66bcafc9891c139a4ded7d2aebc3" and "f3ed0fe6c0ba5db30c0bbb58783752fdfb35caa4" have entirely different histories.
9b016251f2
...
f3ed0fe6c0
14 changed files with 388 additions and 502 deletions
BIN
boddle.db
BIN
boddle.db
Binary file not shown.
317
boddle.go
317
boddle.go
|
|
@ -1,18 +1,83 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"strings"
|
||||
"fmt"
|
||||
"regexp"
|
||||
"database/sql"
|
||||
"math/rand"
|
||||
_ "github.com/mattn/go-sqlite3"
|
||||
)
|
||||
import "strings"
|
||||
import "fmt"
|
||||
import "regexp"
|
||||
import "database/sql"
|
||||
import _ "github.com/mattn/go-sqlite3"
|
||||
|
||||
var begin_char = []byte{'-'}
|
||||
type irc_msg struct {
|
||||
channel string
|
||||
msg string
|
||||
author string
|
||||
}
|
||||
|
||||
type cmd struct {
|
||||
valid bool
|
||||
add bool
|
||||
cmd string
|
||||
groups []string
|
||||
suffix string
|
||||
error string
|
||||
}
|
||||
|
||||
var begin_char = []byte{'-', '<'}
|
||||
var db *sql.DB
|
||||
var err error
|
||||
|
||||
func checkErr(err error) {
|
||||
if err != nil {
|
||||
fmt.Printf("::::ERROR:::: %s\n", err)
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
|
||||
func in (a byte, arr []byte) bool {
|
||||
for _, x := range arr {
|
||||
if x == a {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func unique_str(stringSlice []string) []string {
|
||||
keys := make(map[string]bool)
|
||||
list := []string{}
|
||||
for _, entry := range stringSlice {
|
||||
if _, value := keys[entry]; !value {
|
||||
keys[entry] = true
|
||||
list = append(list, entry)
|
||||
}
|
||||
}
|
||||
return list
|
||||
}
|
||||
|
||||
func unique_int(intSlice []int) []int {
|
||||
keys := make(map[int]bool)
|
||||
list := []int{}
|
||||
for _, entry := range intSlice {
|
||||
if _, value := keys[entry]; !value {
|
||||
keys[entry] = true
|
||||
list = append(list, entry)
|
||||
}
|
||||
}
|
||||
return list
|
||||
}
|
||||
|
||||
/*
|
||||
func unique[T any](tSlice []T) []T {
|
||||
keys := make(map[T]bool)
|
||||
list := []T{}
|
||||
for _, entry := range tSlice {
|
||||
if _, value := keys[entry]; !value {
|
||||
keys[entry] = true
|
||||
list = append(list, entry)
|
||||
}
|
||||
}
|
||||
return list
|
||||
}
|
||||
*/
|
||||
|
||||
// function to split advise message correctly
|
||||
func filter(msg string, foo bot) cmd {
|
||||
|
|
@ -60,17 +125,17 @@ func filter(msg string, foo bot) cmd {
|
|||
LOG_WARN.Printf("invalid query.")
|
||||
return c
|
||||
}
|
||||
if rows.Next() {
|
||||
group_id := 0
|
||||
if rows.Next() {
|
||||
rows.Scan(&group_id)
|
||||
c.groups = append(c.groups, fmt.Sprintf("%d", group_id))
|
||||
} else {
|
||||
if c.add {
|
||||
c.groups = append(c.groups, addgroups([]string{group}, nil)...)
|
||||
}
|
||||
}
|
||||
rows.Close()
|
||||
defer stmt.Close()
|
||||
} else {
|
||||
c.valid = false
|
||||
c.error = "Group name " + group + " is invalid."
|
||||
rows.Close()
|
||||
return c
|
||||
}
|
||||
}
|
||||
c.suffix = res[3]
|
||||
c.valid = true
|
||||
|
|
@ -93,7 +158,6 @@ func filter(msg string, foo bot) cmd {
|
|||
}
|
||||
c.cmd = strings.TrimSpace(c.cmd)
|
||||
c.suffix = strings.TrimSpace(c.suffix)
|
||||
c.groups = unique_str(c.groups)
|
||||
|
||||
return c
|
||||
}
|
||||
|
|
@ -110,41 +174,65 @@ func getRandomEntry(c cmd) string {
|
|||
return task
|
||||
}
|
||||
|
||||
func addgroups(new_groups []string, msg *irc_msg) []string {
|
||||
// line:
|
||||
// >befehl <[groups]> <name>
|
||||
// befehl ist genau ein wort
|
||||
func parsemsg(msg irc_msg, foo bot) bool {
|
||||
if len(msg.msg) <= 0 {
|
||||
return false
|
||||
}
|
||||
if !in(msg.msg[0], begin_char) {
|
||||
return false
|
||||
}
|
||||
msg.msg = msg.msg[1:]
|
||||
|
||||
c := filter(msg.msg, foo)
|
||||
if !c.valid {
|
||||
LOG_WARN.Printf("non valid input found.\n")
|
||||
if c.error != "" {
|
||||
sendmsg(foo.conn, msg.channel, "Falscher input du SP-Ersti... " + c.error)
|
||||
}
|
||||
return false
|
||||
}
|
||||
LOG_WARN.Printf("line was parsed, continue with evaluation.\n")
|
||||
if c.cmd == "" {
|
||||
LOG_WARN.Printf("no command provided.\n")
|
||||
return false
|
||||
}
|
||||
if c.cmd == "help" {
|
||||
return false
|
||||
}
|
||||
// hard code 'groups' to add new groups to the groups-table
|
||||
if c.add && (c.cmd == "groups" || c.cmd == "group") {
|
||||
if (c.groups != nil) {
|
||||
sendmsg(foo.conn, msg.channel, "Ignoring groups for the groups-adding. Well, what were you expecting...?")
|
||||
}
|
||||
new_groups := strings.Fields(c.suffix)
|
||||
stat_sel, err := db.Prepare("select id from groups where name = ?")
|
||||
checkErr(err)
|
||||
stat_ins, err := db.Prepare("insert into groups(name) values (?)")
|
||||
checkErr(err)
|
||||
var groups_added []string
|
||||
var groupids_added []string
|
||||
for _, group := range new_groups {
|
||||
fmt.Println(group)
|
||||
ret, err := stat_sel.Query(group)
|
||||
if ret.Next() {
|
||||
ret.Close()
|
||||
continue
|
||||
}
|
||||
groupid_res, err := stat_ins.Exec(group)
|
||||
_, err = stat_ins.Exec(group)
|
||||
checkErr(err)
|
||||
defer stat_ins.Close()
|
||||
groupid, err := groupid_res.LastInsertId()
|
||||
checkErr(err)
|
||||
groupids_added = append(groupids_added, fmt.Sprintf("%d", groupid))
|
||||
groups_added = append(groups_added, group)
|
||||
}
|
||||
if msg != nil {
|
||||
if len(groups_added) > 0 {
|
||||
(*msg).retmsg = "Added " + strings.Join(groups_added, ", ") + " to groups-table!"
|
||||
sendmsg(foo.conn, msg.channel, "Added " + strings.Join(groups_added, ", ") + " to groups-table!")
|
||||
} else {
|
||||
(*msg).retmsg = "Added nothing to groups-table! :("
|
||||
sendmsg(foo.conn, msg.channel, "Added nothing to groups-table! :(")
|
||||
}
|
||||
}
|
||||
return groupids_added
|
||||
return false
|
||||
}
|
||||
|
||||
func checkSorter(msg *irc_msg, c *cmd) bool {
|
||||
sorter_row_sel, err := db.Prepare("select id, tag_id, groups_allow, name_allow, has_groups from sorter where name = ?")
|
||||
checkErr(err)
|
||||
sorter_row, err := sorter_row_sel.Query((*c).cmd)
|
||||
sorter_row, err := db.Query(fmt.Sprintf("select id, tag_id, groups_allow, name_allow, has_groups from sorter where name = '%s'", c.cmd))
|
||||
checkErr(err)
|
||||
if sorter_row.Next() {
|
||||
var sorter_id string
|
||||
|
|
@ -156,72 +244,53 @@ func checkSorter(msg *irc_msg, c *cmd) bool {
|
|||
sorter_row.Close()
|
||||
|
||||
if groups_allow != 0 {
|
||||
(*msg).retmsg = "This command does not allow groups. :("
|
||||
sendmsg(foo.conn, msg.channel, "This command does not allow groups. :(")
|
||||
return false
|
||||
}
|
||||
if name_allow != 0 && !(*c).add {
|
||||
if name_allow != 0 && !c.add {
|
||||
// warning: not allowed
|
||||
(*c).suffix = ""
|
||||
c.suffix = ""
|
||||
}
|
||||
|
||||
(*c).cmd = tag_id
|
||||
c.cmd = tag_id
|
||||
|
||||
if has_groups == 0 {
|
||||
group_sel, err := db.Prepare("select group_id from sorter_groups where sorter_id = ?")
|
||||
checkErr(err)
|
||||
sorter_groups_row, err := group_sel.Query(sorter_id)
|
||||
//sorter_groups_row, err := db.Query(fmt.Sprintf("select group_id from sorter_groups where sorter_id = '%s'", sorter_id))
|
||||
sorter_groups_row, err := db.Query(fmt.Sprintf("select group_id from sorter_groups where sorter_id = '%s'", sorter_id))
|
||||
checkErr(err)
|
||||
if sorter_groups_row.Next() {
|
||||
var group_id int
|
||||
sorter_groups_row.Scan(&group_id)
|
||||
(*c).groups = append((*c).groups, fmt.Sprintf("%d", group_id))
|
||||
c.groups = append(c.groups, fmt.Sprintf("%d", group_id))
|
||||
}
|
||||
sorter_groups_row.Close()
|
||||
if (*c).add {
|
||||
if c.add {
|
||||
var tag_name string
|
||||
tag_name_row, err := db.Query(fmt.Sprintf("select name from tag where id = %s", tag_id))
|
||||
tag_name_row, err := db.Query(fmt.Sprintf("select name from tag where id = %d", tag_id))
|
||||
checkErr(err)
|
||||
if tag_name_row.Next() {
|
||||
tag_name_row.Scan(&tag_name)
|
||||
}
|
||||
tag_name_row.Close()
|
||||
LOG_WARN.Printf("Alias used. Tell the user about that.\n")
|
||||
(*msg).retmsg = "You're using an alias. Please try again with 'add " + tag_name + " [" + strings.Join((*c).groups, " ") + "]. Thanks!"
|
||||
sendmsg(foo.conn, msg.channel, "You're using an alias. Please try again with 'add " + tag_name + " [" + strings.Join(c.groups, " ") + "]. Thanks!")
|
||||
return false
|
||||
}
|
||||
}
|
||||
} else {
|
||||
LOG_WARN.Printf("no sorter entry, no translation possible\n")
|
||||
(*msg).retmsg = "No entry found, sorry..."
|
||||
sendmsg(foo.conn, msg.channel, "No entry found, sorry...")
|
||||
return false
|
||||
}
|
||||
return true
|
||||
|
||||
if c.add {
|
||||
// if there is nothing to add, just return. :-)
|
||||
if (len(c.suffix) <= 0) {
|
||||
return false;
|
||||
}
|
||||
c.suffix = strings.Replace(c.suffix,"\"","'", -1)
|
||||
LOG_WARN.Printf("adding new stuff: %s from %s.\n", c.suffix, msg.author)
|
||||
|
||||
func chooseEntry(msg *irc_msg, c *cmd) {
|
||||
task := getRandomEntry(*c)
|
||||
|
||||
LOG_INFO.Printf(task)
|
||||
row, err := db.Query(task)
|
||||
checkErr(err)
|
||||
if row.Next() {
|
||||
row.Scan(&((*msg).retmsg))
|
||||
}
|
||||
row.Close()
|
||||
|
||||
if len((*msg).retmsg) <= 0 {
|
||||
LOG_WARN.Printf("no entry found\n")
|
||||
(*msg).retmsg = "No matching entry found :("
|
||||
} else if len((*c).suffix) > 0 {
|
||||
(*msg).retmsg = fmt.Sprintf("%s... %s", (*c).suffix, (*msg).retmsg)
|
||||
}
|
||||
}
|
||||
|
||||
func addLine(msg *irc_msg, line string, groups []string, cmd string) string {
|
||||
LOG_WARN.Printf("adding new stuff: %s from %s.\n", line, (*msg).author)
|
||||
|
||||
res, err := db.Exec("insert into line (content, author) values (?,?)", line, (*msg).author)
|
||||
res, err := db.Exec("insert into line (content, author) values (?,?)", c.suffix, msg.author)
|
||||
checkErr(err)
|
||||
LOG_WARN.Printf("added line to table.\n")
|
||||
|
||||
|
|
@ -229,94 +298,48 @@ func addLine(msg *irc_msg, line string, groups []string, cmd string) string {
|
|||
line_id, err := res.LastInsertId();
|
||||
checkErr(err)
|
||||
|
||||
LOG_WARN.Printf("line_id: %d, tag_id: %s, groups: %s\n", line_id, cmd, strings.Join(groups, "-"))
|
||||
LOG_WARN.Printf("line_id: %d, tag_id: %d, groups: %s\n", line_id, c.cmd, strings.Join(c.groups, "-"))
|
||||
// for tag and all groups
|
||||
if len(groups) == 0 {
|
||||
if len(c.groups) == 0 {
|
||||
stat, err := db.Prepare("insert into brain(line_id, tag_id) values (?,?)")
|
||||
checkErr(err)
|
||||
_, err = stat.Exec(line_id, cmd)
|
||||
_, err = stat.Exec(line_id, c.cmd)
|
||||
checkErr(err)
|
||||
LOG_INFO.Printf("inserted foo! \n")
|
||||
defer stat.Close()
|
||||
} else {
|
||||
stat, err := db.Prepare("insert into brain(line_id, tag_id, group_id) values (?,?,?)")
|
||||
checkErr(err)
|
||||
for _, group := range groups {
|
||||
_, err = stat.Exec(line_id, cmd, group)
|
||||
for _, group := range c.groups {
|
||||
_, err = stat.Exec(line_id, c.cmd, group)
|
||||
checkErr(err)
|
||||
}
|
||||
LOG_INFO.Printf("inserted foo! \n")
|
||||
defer stat.Close()
|
||||
}
|
||||
(*msg).retmsg = fmt.Sprintf("success adding new super funny enjoyable line with ID %d!", line_id)
|
||||
return fmt.Sprintf("new line: > %s < (ID %d), into groups %s", line, line_id, strings.Join(groups,","))
|
||||
}
|
||||
// line:
|
||||
// >befehl <[groups]> <name>
|
||||
// befehl ist genau ein wort
|
||||
func parsemsg(msg *irc_msg, foo bot) bool {
|
||||
if len((*msg).msg) <= 0 {
|
||||
return false
|
||||
}
|
||||
if (*msg).msg == "<3" {
|
||||
(*msg).msg = string(begin_char[0]) + "flirt kreisi"
|
||||
}
|
||||
|
||||
if !in((*msg).msg[0], begin_char) {
|
||||
return false
|
||||
}
|
||||
(*msg).msg = (*msg).msg[1:]
|
||||
|
||||
c := filter((*msg).msg, foo)
|
||||
if !c.valid {
|
||||
LOG_WARN.Printf("non valid input found.\n")
|
||||
if c.error != "" {
|
||||
(*msg).retmsg = "Falscher input du SP-Ersti... " + c.error
|
||||
}
|
||||
return false
|
||||
}
|
||||
LOG_WARN.Printf("line was parsed, continue with evaluation.\n")
|
||||
if c.cmd == "" {
|
||||
LOG_WARN.Printf("no command provided.\n")
|
||||
return false
|
||||
}
|
||||
if c.cmd == "help" {
|
||||
(*msg).retmsg = "There is no help in this hell..."
|
||||
return false
|
||||
}
|
||||
if c.cmd == "slap" {
|
||||
who := []string{(*msg).author, "\x01ACTION"}
|
||||
whom := []string{(*msg).author, foo.Conf.Name}
|
||||
LOG_WARN.Printf("suffix: " + c.suffix)
|
||||
if c.suffix != "" {
|
||||
who = append(who, strings.Split(c.suffix, " ")...)
|
||||
whom = append(whom, strings.Split(c.suffix, " ")...)
|
||||
}
|
||||
(*msg).retmsg = who[rand.Intn(len(who))] + " slaps " + whom[rand.Intn(len(whom))] + " around with a large trout."
|
||||
return false
|
||||
}
|
||||
// hard code 'groups' to add new groups to the groups-table
|
||||
if c.add && (c.cmd == "groups" || c.cmd == "group") {
|
||||
if (c.groups != nil) {
|
||||
(*msg).retmsg = "Ignoring groups for the groups-adding. Well, what were you expecting...?"
|
||||
}
|
||||
addgroups(strings.Fields((&c).suffix), msg)
|
||||
return false
|
||||
}
|
||||
|
||||
// have a look at sorter table if command is valid
|
||||
if !checkSorter(msg, &c) {
|
||||
return false
|
||||
}
|
||||
|
||||
// new line for database
|
||||
if c.add {
|
||||
// if there is nothing to add, just return. :-)
|
||||
if (len(c.suffix) <= 0) {
|
||||
return false;
|
||||
}
|
||||
c.suffix = strings.Replace(c.suffix,"\"","'", -1)
|
||||
sendmsg(foo.conn, "horscchtey", addLine(msg, c.suffix, c.groups, c.cmd))
|
||||
} else {
|
||||
chooseEntry(msg, &c)
|
||||
}
|
||||
sendmsg(foo.conn, msg.channel, fmt.Sprintf("success adding new super funny enjoyable line with ID %d!", line_id))
|
||||
sendmsg(foo.conn, "horscchtey", fmt.Sprintf("new line: > %s < (ID %d), into groups %s", c.suffix, line_id, strings.Join(c.groups,",")))
|
||||
return true
|
||||
}
|
||||
|
||||
task := getRandomEntry(c)
|
||||
|
||||
LOG_INFO.Printf(task)
|
||||
row, err := db.Query(task)
|
||||
checkErr(err)
|
||||
res := ""
|
||||
if row.Next() {
|
||||
row.Scan(&res)
|
||||
}
|
||||
row.Close()
|
||||
|
||||
if len(res) <= 0 {
|
||||
LOG_WARN.Printf("no entry found\n")
|
||||
res = "No matching entry found :("
|
||||
} else if len(c.suffix) > 0 {
|
||||
res = fmt.Sprintf("%s... %s", c.suffix, res)
|
||||
}
|
||||
sendmsg(foo.conn, msg.channel, res)
|
||||
|
||||
return true
|
||||
}
|
||||
|
|
|
|||
176
bot.go
176
bot.go
|
|
@ -1,152 +1,27 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"os"
|
||||
"log"
|
||||
"fmt"
|
||||
"net"
|
||||
"time"
|
||||
"bufio"
|
||||
"strings"
|
||||
"database/sql"
|
||||
configo "github.com/distributedio/configo"
|
||||
_ "github.com/mattn/go-sqlite3"
|
||||
)
|
||||
|
||||
func sendmsg (conn net.Conn, channel string, msg string) {
|
||||
mesg := fmt.Sprintf("PRIVMSG %s :%s\r\n", channel, msg)
|
||||
fmt.Printf(mesg)
|
||||
conn.Write([]byte(mesg))
|
||||
var dead = true
|
||||
|
||||
type Config struct {
|
||||
Name string `cfg:"name; boddle; printableascii; IRC nick of bot"`
|
||||
Channels []string `cfg:"channels; required; printableascii; Channel list to join to"`
|
||||
Server string `cfg:"server; required; netaddr; Server name to connect to"`
|
||||
Database string `cfg:"database; ./boddle.db; path; Path to database"`
|
||||
}
|
||||
|
||||
func scanline_privmsg (msg string, irc *irc_msg) {
|
||||
LOG_ERR.Printf(msg)
|
||||
|
||||
msg = msg[1:]
|
||||
t := strings.Split(msg, "!")
|
||||
(*irc).author, (*irc).channel = t[0], t[1]
|
||||
t = strings.Split((*irc).channel, "PRIVMSG ")
|
||||
(*irc).channel = t[1]
|
||||
t = strings.Split((*irc).channel, " :")
|
||||
(*irc).channel, (*irc).msg = t[0], t[1]
|
||||
t = strings.Split((*irc).msg, "\r\n")
|
||||
(*irc).msg = strings.TrimSpace(t[0])
|
||||
if ! strings.HasPrefix((*irc).channel, "#") {
|
||||
(*irc).channel = (*irc).author
|
||||
}
|
||||
(*irc).retmsg = ""
|
||||
}
|
||||
|
||||
func bot_connect(bot *bot) {
|
||||
conn, err := net.Dial("tcp", (*bot).Conf.Server)
|
||||
if err != nil {
|
||||
LOG_ERR.Printf("Error while dialing server.")
|
||||
(*bot).conn = nil
|
||||
return
|
||||
}
|
||||
|
||||
(*bot).conn = conn
|
||||
fmt.Fprintf((*bot).conn, "USER %s 1 1 1:%s\r\n", (*bot).Conf.Name, (*bot).Conf.Name)
|
||||
}
|
||||
|
||||
func bot_register(bot *bot) {
|
||||
/* connect to irc */
|
||||
fmt.Fprintf((*bot).conn, "NICK %s\r\n", (*bot).Conf.Name)
|
||||
for _, channel := range((*bot).Conf.Channels) {
|
||||
fmt.Fprintf((*bot).conn, "JOIN %s\r\n", channel)
|
||||
}
|
||||
}
|
||||
|
||||
func bot_listen(bot *bot) <-chan string {
|
||||
c := make(chan string)
|
||||
bot_register(bot)
|
||||
|
||||
go func(timeoutNormal time.Duration, timeoutVersion time.Duration) {
|
||||
bufReader := bufio.NewReader((*bot).conn)
|
||||
|
||||
timeoutDuration := timeoutNormal
|
||||
waitversion := false
|
||||
|
||||
defer func() {
|
||||
fmt.Println("Closing connection...")
|
||||
close(c)
|
||||
(*bot).conn.Close()
|
||||
}()
|
||||
|
||||
for {
|
||||
(*bot).conn.SetReadDeadline(time.Now().Add(timeoutDuration))
|
||||
|
||||
line, err := bufReader.ReadString('\n')
|
||||
if err != nil {
|
||||
if nerr, ok := err.(net.Error); ok && nerr.Timeout() {
|
||||
fmt.Printf("Timeout!\n")
|
||||
if waitversion {
|
||||
fmt.Println("VERSION command did not return.")
|
||||
return
|
||||
}
|
||||
|
||||
n, err := (*bot).conn.Write([]byte("VERSION\n"))
|
||||
fmt.Printf("n: %d, err: %s\n", n, err)
|
||||
if err != nil {
|
||||
fmt.Println("Writing to channel failed.")
|
||||
return
|
||||
}
|
||||
// wait for return value of VERSION
|
||||
waitversion = true
|
||||
timeoutDuration = timeoutVersion
|
||||
} else {
|
||||
fmt.Println("Some more serious error occured while reading.")
|
||||
return
|
||||
}
|
||||
continue
|
||||
}
|
||||
|
||||
// not waiting for version answer right now
|
||||
timeoutDuration = timeoutNormal
|
||||
waitversion = false
|
||||
c <- line
|
||||
|
||||
if strings.Contains(line, "PING") {
|
||||
(*bot).conn.Write([]byte(strings.Replace(line, "PING", "PONG", 1)))
|
||||
} else if strings.Contains(line, "You have not registered") {
|
||||
// set nickname
|
||||
time.Sleep(10 * time.Second)
|
||||
bot_register(bot)
|
||||
} else if strings.Contains(line, "PRIVMSG") {
|
||||
var msg irc_msg
|
||||
scanline_privmsg(line, &msg)
|
||||
LOG_ERR.Printf(msg.author)
|
||||
parsemsg(&msg, (*bot))
|
||||
if msg.retmsg != "" {
|
||||
sendmsg((*bot).conn, msg.channel, msg.retmsg)
|
||||
}
|
||||
}
|
||||
}
|
||||
} (4 * time.Minute, 1 * time.Minute)
|
||||
|
||||
return c
|
||||
}
|
||||
|
||||
func bot_run(bot *bot) {
|
||||
LOG_INFO.Println("Bot ready to run.")
|
||||
|
||||
LOG_INFO.Println("Opening database.")
|
||||
db, err = sql.Open("sqlite3", (*bot).Conf.Database)
|
||||
if err != nil {
|
||||
LOG_ERR.Println("Opening database failed.")
|
||||
return
|
||||
}
|
||||
|
||||
for {
|
||||
bot_connect(bot)
|
||||
if bot.conn == nil {
|
||||
LOG_INFO.Printf("Bot is nil. Try to connect again.")
|
||||
time.Sleep(10 * time.Second)
|
||||
continue
|
||||
}
|
||||
for val := range bot_listen(bot) {
|
||||
LOG_INFO.Printf("%s", val)
|
||||
}
|
||||
}
|
||||
type bot struct {
|
||||
Conf Config
|
||||
conn net.Conn
|
||||
}
|
||||
|
||||
func main() {
|
||||
|
|
@ -156,6 +31,33 @@ func main() {
|
|||
if err := configo.Load("./boddle.toml", &boddle.Conf); err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
// boddle := bot {
|
||||
// name: "boddle",
|
||||
// channel: []string{"#faui2k16", "#fau", "#sigbike", "#sigfreibad"},
|
||||
// port: 6667,
|
||||
// server: "irc.fau.de",
|
||||
// }
|
||||
|
||||
bot_run(&boddle)
|
||||
LOG_INFO.Println("bot started!")
|
||||
|
||||
var botchan <-chan []byte
|
||||
var line []byte
|
||||
dead = true
|
||||
|
||||
for {
|
||||
if dead {
|
||||
LOG_WARN.Println("died.")
|
||||
for {
|
||||
botchan = connect(boddle)
|
||||
if botchan != nil {
|
||||
break
|
||||
}
|
||||
time.Sleep(10 * time.Second)
|
||||
}
|
||||
LOG_INFO.Println("reconnected.")
|
||||
dead = false
|
||||
}
|
||||
line = <-botchan
|
||||
fmt.Fprintf(os.Stderr, string(line))
|
||||
}
|
||||
}
|
||||
|
|
|
|||
2
bot.py
2
bot.py
|
|
@ -12,7 +12,7 @@ import sqlite3 as sql
|
|||
updater = Updater(token='935673062:AAH4By1EMqAUaD9wgnV3lZQRRBX6e5Lve6g', use_context=True)
|
||||
|
||||
# sqlite database
|
||||
connection = sql.connect("/home/boddle/boddle/src/v2/boddle.db", check_same_thread=False)
|
||||
connection = sql.connect("/home/horscchtey/bots/boddle/src/v2/boddle.db", check_same_thread=False)
|
||||
cursor = connection.cursor()
|
||||
|
||||
dispatcher = updater.dispatcher
|
||||
|
|
|
|||
8
conf.go
8
conf.go
|
|
@ -1,8 +0,0 @@
|
|||
package main
|
||||
|
||||
type Boddle struct {
|
||||
name string `cfg:"name; boddle; printableascii; IRC nick of bot"`
|
||||
channels []string `cfg:"channels; required; printableascii; Channel list to join to"`
|
||||
server string `cfg:"server; required; netaddr; Server name to connect to"`
|
||||
database string `cfg:"database; ./boddle.db; path; Path to database"`
|
||||
}
|
||||
62
flake.nix
62
flake.nix
|
|
@ -1,62 +0,0 @@
|
|||
{
|
||||
description = "boddle, in Anlehnung an bottle";
|
||||
|
||||
outputs = { self, nixpkgs }: let
|
||||
module = { pkgs, lib, config, ... }: {
|
||||
options.services.boddle = {
|
||||
enable = lib.mkEnableOption "enable";
|
||||
# TODO: configurability
|
||||
};
|
||||
|
||||
config.nixpkgs.overlays = [ self.overlay ];
|
||||
|
||||
config.systemd.services.boddle = lib.mkIf config.services.boddle.enable {
|
||||
script = lib.getExe pkgs.boddle;
|
||||
};
|
||||
};
|
||||
|
||||
per-system = fn: builtins.mapAttrs (_: fn) nixpkgs.legacyPackages;
|
||||
|
||||
package = pkgs: pkgs.buildGoModule {
|
||||
meta = {
|
||||
description = "boddle, in Anlehnung an bottle";
|
||||
homepage = "https://git.fbs42.ddnss.de/forgejo/fbs42/boddle";
|
||||
name = "boddle";
|
||||
};
|
||||
pname = "boddle";
|
||||
version = "v0.0.1";
|
||||
vendorHash = "sha256-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA";
|
||||
src = pkgs.fetchgit {
|
||||
url = "https://git.fbs42.ddnss.de/forgejo/fbs42/boddle";
|
||||
hash = "sha256-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA";
|
||||
};
|
||||
};
|
||||
|
||||
devshell = pkgs: pkgs.mkShell {
|
||||
nativeBuildInputs = with pkgs.buildPackages; [
|
||||
go
|
||||
];
|
||||
};
|
||||
|
||||
in {
|
||||
nixosModules = {
|
||||
default = self.nixosModules.boddle;
|
||||
boddle = module;
|
||||
};
|
||||
|
||||
overlay = final: prev: {
|
||||
boddle = package final;
|
||||
};
|
||||
|
||||
packages = per-system (pkgs: {
|
||||
default = package pkgs;
|
||||
boddle = package pkgs;
|
||||
});
|
||||
|
||||
apps = self.packages;
|
||||
|
||||
devShells = per-system (pkgs: {
|
||||
default = devshell pkgs;
|
||||
});
|
||||
};
|
||||
}
|
||||
|
|
@ -1,10 +1,15 @@
|
|||
#!/bin/bash
|
||||
|
||||
export GOPATH=/home/boddle/go
|
||||
export GOPATH=/home/horscchtey/go
|
||||
export CC=arm-linux-gnueabihf-gcc
|
||||
export CXX=arm-linux-gnueabihf-g++
|
||||
export CGO_ENABLED=1
|
||||
export GOOS=linux
|
||||
export GOARCH=arm
|
||||
export GOARM=7
|
||||
|
||||
declare -a src
|
||||
src+=(bot.go boddle.go logging.go helpers.go types.go)
|
||||
src+=(bot.go boddle.go logging.go ircfoo.go)
|
||||
declare -i nproc="$(nproc)"
|
||||
|
||||
go build -v -p ${nproc} "${src[@]}"
|
||||
go build -p ${nproc} "${src[@]}"
|
||||
|
|
|
|||
13
go.mod
13
go.mod
|
|
@ -1,13 +0,0 @@
|
|||
module boddle
|
||||
|
||||
go 1.17
|
||||
|
||||
require (
|
||||
github.com/distributedio/configo v0.0.0-20200107073829-efd79b027816
|
||||
github.com/mattn/go-sqlite3 v1.14.16
|
||||
)
|
||||
|
||||
require (
|
||||
github.com/naoina/go-stringutil v0.1.0 // indirect
|
||||
github.com/shafreeck/toml v0.0.0-20190326060449-44ad86712acc // indirect
|
||||
)
|
||||
20
go.sum
20
go.sum
|
|
@ -1,20 +0,0 @@
|
|||
github.com/distributedio/configo v0.0.0-20200107073829-efd79b027816 h1:V6TyTUY0vUVUOxLnuH6AIOCIOI8psy5h0n4U+qvO4bo=
|
||||
github.com/distributedio/configo v0.0.0-20200107073829-efd79b027816/go.mod h1:Jwz2omP6W/T/XlSfu+BMGW7NEJX3tf5/Qv5gwaiQ+uU=
|
||||
github.com/mattn/go-sqlite3 v1.14.12 h1:TJ1bhYJPV44phC+IMu1u2K/i5RriLTPe+yc68XDJ1Z0=
|
||||
github.com/mattn/go-sqlite3 v1.14.12/go.mod h1:NyWgC/yNuGj7Q9rpYnZvas74GogHl5/Z4A/KQRfk6bU=
|
||||
github.com/mattn/go-sqlite3 v1.14.16 h1:yOQRA0RpS5PFz/oikGwBEqvAWhWg5ufRz4ETLjwpU1Y=
|
||||
github.com/mattn/go-sqlite3 v1.14.16/go.mod h1:2eHXhiwb8IkHr+BDWZGa96P6+rkvnG63S2DGjv9HUNg=
|
||||
github.com/naoina/go-stringutil v0.1.0 h1:rCUeRUHjBjGTSHl0VC00jUPLz8/F9dDzYI70Hzifhks=
|
||||
github.com/naoina/go-stringutil v0.1.0/go.mod h1:XJ2SJL9jCtBh+P9q5btrd/Ylo8XwT/h1USek5+NqSA0=
|
||||
github.com/naoina/toml v0.1.1 h1:PT/lllxVVN0gzzSqSlHEmP8MJB4MY2U7STGxiouV4X8=
|
||||
github.com/naoina/toml v0.1.1/go.mod h1:NBIhNtsFMo3G2szEBne+bO4gS192HuIYRqfvOWb4i1E=
|
||||
github.com/shafreeck/toml v0.0.0-20190326060449-44ad86712acc h1:BrtrZvICmDsYzv7ECoQFwlC5cS+YWDfz/OBpMlMe9HY=
|
||||
github.com/shafreeck/toml v0.0.0-20190326060449-44ad86712acc/go.mod h1:C9DYu7Ddz1xnXil/kyvydcdaUggQeJvFA7vzYpm+Cw4=
|
||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||
golang.org/x/crypto v0.0.0-20190313024323-a1f597ede03a/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||
golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||
golang.org/x/net v0.0.0-20190320064053-1272bf9dcd53/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190318195719-6c81ef8f67ca/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/tools v0.0.0-20190319232107-3f1ed9edd1b4/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
|
||||
45
helpers.go
45
helpers.go
|
|
@ -1,45 +0,0 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
)
|
||||
|
||||
func checkErr(err error) {
|
||||
if err != nil {
|
||||
fmt.Printf("::::ERROR:::: %s\n", err)
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
|
||||
func in (a byte, arr []byte) bool {
|
||||
for _, x := range arr {
|
||||
if x == a {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func unique_str(stringSlice []string) []string {
|
||||
keys := make(map[string]bool)
|
||||
list := []string{}
|
||||
for _, entry := range stringSlice {
|
||||
if _, value := keys[entry]; !value {
|
||||
keys[entry] = true
|
||||
list = append(list, entry)
|
||||
}
|
||||
}
|
||||
return list
|
||||
}
|
||||
|
||||
func unique_int(intSlice []int) []int {
|
||||
keys := make(map[int]bool)
|
||||
list := []int{}
|
||||
for _, entry := range intSlice {
|
||||
if _, value := keys[entry]; !value {
|
||||
keys[entry] = true
|
||||
list = append(list, entry)
|
||||
}
|
||||
}
|
||||
return list
|
||||
}
|
||||
98
ircfoo.go
Normal file
98
ircfoo.go
Normal file
|
|
@ -0,0 +1,98 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net"
|
||||
"os"
|
||||
"bufio"
|
||||
"bytes"
|
||||
"strings"
|
||||
"database/sql"
|
||||
_ "github.com/mattn/go-sqlite3"
|
||||
)
|
||||
|
||||
func sendmsg (conn net.Conn, channel string, msg string) {
|
||||
mesg := fmt.Sprintf("PRIVMSG %s :%s\r\n", channel, msg)
|
||||
fmt.Printf(mesg)
|
||||
conn.Write([]byte(mesg))
|
||||
}
|
||||
|
||||
func scanline_privmsg (msg string) irc_msg {
|
||||
var irc irc_msg
|
||||
|
||||
msg = msg[1:]
|
||||
t := strings.Split(msg, "!")
|
||||
irc.author, irc.channel = t[0], t[1]
|
||||
t = strings.Split(irc.channel, "PRIVMSG ")
|
||||
irc.channel = t[1]
|
||||
t = strings.Split(irc.channel, " :")
|
||||
irc.channel, irc.msg = t[0], t[1]
|
||||
t = strings.Split(irc.msg, "\r\n")
|
||||
irc.msg = strings.TrimSpace(t[0])
|
||||
if ! strings.HasPrefix(irc.channel, "#") {
|
||||
irc.channel = irc.author
|
||||
}
|
||||
return irc
|
||||
}
|
||||
|
||||
func listenToIRC (foo bot) <-chan []byte {
|
||||
c := make(chan []byte)
|
||||
reader := bufio.NewReader(foo.conn)
|
||||
db, err = sql.Open("sqlite3", foo.Conf.Database)
|
||||
if err != nil {
|
||||
LOG_ERR.Printf("opening database failed")
|
||||
return nil
|
||||
}
|
||||
|
||||
var line []byte
|
||||
var err error
|
||||
|
||||
go func() {
|
||||
for {
|
||||
line, err = reader.ReadBytes('\n')
|
||||
if err != nil {
|
||||
LOG_ERR.Printf("Error while reading bytes from connection.\n")
|
||||
dead = true
|
||||
c <- []byte("killed it")
|
||||
return
|
||||
}
|
||||
|
||||
c <- line
|
||||
|
||||
if bytes.Contains([]byte(line), []byte("PING :")) {
|
||||
v := []byte(bytes.Replace([]byte(line), []byte("PING"), []byte("PONG"), 1))
|
||||
fmt.Printf(string(v[:]))
|
||||
foo.conn.Write(v)
|
||||
continue
|
||||
}
|
||||
|
||||
if !bytes.Contains([]byte(line), []byte("PRIVMSG")) {
|
||||
continue
|
||||
}
|
||||
|
||||
parsemsg(scanline_privmsg(string(line)), foo)
|
||||
}
|
||||
} ()
|
||||
return c
|
||||
}
|
||||
|
||||
func connect(boddle bot) <-chan []byte {
|
||||
conn, err := net.Dial("tcp", boddle.Conf.Server)
|
||||
|
||||
if err != nil {
|
||||
fmt.Fprintf(os.Stderr, "Error while dialing server.")
|
||||
LOG_ERR.Printf("Error while connecting to server.")
|
||||
return nil
|
||||
}
|
||||
|
||||
boddle.conn = conn
|
||||
|
||||
/* connect to irc */
|
||||
fmt.Fprintf(boddle.conn, "NICK %s\r\n", boddle.Conf.Name)
|
||||
fmt.Fprintf(boddle.conn, "USER %s 1 1 1:%s\r\n", boddle.Conf.Name, boddle.Conf.Name)
|
||||
for _, channel := range(boddle.Conf.Channels) {
|
||||
fmt.Fprintf(boddle.conn, "JOIN %s\r\n", channel)
|
||||
}
|
||||
|
||||
return listenToIRC(boddle)
|
||||
}
|
||||
40
pepe.go
Normal file
40
pepe.go
Normal file
|
|
@ -0,0 +1,40 @@
|
|||
package main
|
||||
|
||||
var pepe = []string{
|
||||
"░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░",
|
||||
"░░░░░░░░░░░░░░░░░░░░░░░▓▓▒▒▒▒▒▒▓▓▒░░░░░░░░░▓▓░▓▓▒░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░",
|
||||
"░░░░░░░░░░░░░░░░░░░ ▓▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▓░▓▒▒▒▒▒▒▒▒▒▒▒▒▓░░ ░░░░░░░░░░░░░░░░░░░░░░░░░",
|
||||
"░░░░░░░░░░░░░░░░░░▓▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▓▒▒▒▒▒▒▒▒▒▒▒▒▒▓░░░░░░░░░░░░░░░░░░░░░░░░░░░",
|
||||
"░░░░░░░░░░░░░░░░░▓▒▒▒▒▒▒▓▓▓▒▒▒▒▒▒▒▓▓▓▒▓▓▒▒▒▒▒▒▒▒▒▒▒▒▒▓ ░░░░░░░░░░░░░░░░░░░░░░░░░",
|
||||
"░░░░░░░░░░░░░░░▒▓▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▓▓▒▒▒▒▒▒▒▒▒▒▒▒▒▒▓▓░░░░░░░░░░░░░░░░░░░░░░░░",
|
||||
"░░░░░░░░░░░░░░░▓▒▒▒▒▒▒▒▒▒▒▒▒▒▒▓▓░▓▓▒▒▓▓▓░░▒▒▒▒▒▒▓▓░░░░░▓▓▒▓░░░░░░░░░░░░░░░░░░░░░",
|
||||
"░░░░░░░░░░░░░▓▓▒▒▒▒▒▒▒▒▒▒▒▓▓▒▓▓▓▒▒▒▒▒▒▒▒▓▓▓░▓▓▓▓▓▓▒▒▒▒▒▓▓▓▓▓▓░░░░░░░░░░░░░░░░░░░",
|
||||
"░░░░░░░░░░▒▒▒▓▒▒▒▒▒▒▒▒▒▓▒▓▓▓▒▒▒▒▒▒▒▒▓▓▓▒▒▒▒▓▒▒▒▒▓▓▓▒▒▓▓▓▒▒▒▒▓▓░░░░░░░░░░░░░░░░░░",
|
||||
"░░░░░░░░░▓▒▒▒▓▒▒▒▒▒▒▒▓▓▒▒▒▒▒▒▓▓▒░▒█░███░ ▒ ░█▓░████ ░░░░░░░░░░░░░░░░░░",
|
||||
"░░░░░░░░▓▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▓ ░████░ ██░ ▒ ██░██ ░██ ▒░░░░░░░░░░░░░░░░░░",
|
||||
"░░░░░░ ▓▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▓▓▓▒▓▓▒███░███░▓▒▒░▒▒▓▓▓▓░░░▓▓▓▒▒▒▓▒░░░░░░░░░░░░░░░░░░░",
|
||||
"░░░░░░▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▓▓▓▓▓▓▓▓▓▓▓▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▓▒░░░░░░░░░░░░░░░░░░░░░",
|
||||
"░░░░░▒▓▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▓▓▓▒▒▒▒▒▒▓▓▓▒▒▒▒▓▓░▒ ░░░░░░░░░░░░░░░░░░░░░░░",
|
||||
"░░░░░▓▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▓▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▓░░░░░░░░░░░░░░░░░░░░░░░",
|
||||
"░░░░▓▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▓░░░░░░░░░█░░▒▓█▓░█░░░░",
|
||||
"░░░░▓▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▓ ░░░░░░░█▒░█▒▒░▓▒█▒░░",
|
||||
"░░░░░▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▓░▓▒▒▒▓▓░▓▓▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▓░▓░▒░░▓░░▓▓▒░░▒▓█▓▒█░░",
|
||||
"░░░░▓▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▓▒▒▒▒▒▒▒▒▒▒▒▒░▒▒▒▒▒▓░░░░▓▓▓▓▓░░░▓▒▒▒░▒▒░░▒░▓█ ░█▒▒░░▒░▒▓▓░░",
|
||||
"░░░░░▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▓▒▒▒▒▒▒▒▒▒▒▒▒▒▒▓▓▓▓▒▒▒▒░▒▒▒▒▒▒▒▒▒▒▓▓▓▓░░░░░▓▓▓█▒█▒▒▒▒▒▒▒█░░░",
|
||||
"░░░░░▒▓▒▒▒▒▒▒▒▒▒▒▒▓▒▒▒▓▓▓▓▓▓▓▓▓▓▓▒▒▒▒▒▓█░█░▓▒█▓░▒▒▒▒▒▒▒▒▒▓ ░░░░░░▒▒▒▒▒▒▒▒▒▒█░░░░",
|
||||
"░░░░░░░▓▒▒▒▒▒▒▒▒▒▒▒▒▓▓▓▒▒▒▒▒▒▒▒▒▒▒▒▒▒█▓▓░▒█░█▓▒█░░░▓▓▓▓▒░░░░░▒▒▒▒▒▒▒▒▒▒▒▓█▒░░░░░",
|
||||
" ░ ░▒▒ ▒▓▓▓▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▓██▒█▒▒░▒▓▓▒█▒▓░▓░░▒ ░░░░▒░▒▒▒▒▒▒▒▒▒▒▓█░░░░░░░░░",
|
||||
" ▒ ░▓▓▒▓▓░▓▓▒▒▒▒▒▒▒▒▒▒▒▒▒▒█▒█░▒▒▓▒▒█░▓▒▓░█▒▒░░░░░ ░▒▒▒▒▒▒▒▒▓█▒░░░░░░░░░░░",
|
||||
"▒ ░▓▓▓▒▒▒▒▒▒▓▓▓▓▓▓▓▓░▓▒░▒▒▒▒▒▒▒▒▒░▒▒▒▓░░░░░░░▒▒▒▒▒▒▒▒░ ░░░░░░░░░░░░",
|
||||
" ░░░▒▒▒▒▒▓█▓▒▒▒▒▒▒▒▒▒▒▒░░░░░░░░░▒▓▒▒▒▒▒▒▒░ ░░░░░░░░░░░░",
|
||||
" ░▒▒▒▒░▓▒▒█▒ ▒░░░░░░░░░█▒▒▒▒▒▒▒▓▒░░░░░░░░░░░░",
|
||||
" ▓▒▒▒▒▒▒▒▓░ █▒░░░░░▒▒▒▒▒▒▒▒▒█░░░░░░░░░░░░",
|
||||
" ░▓▒▒▒▒▒▒▒░ ░░░░░░░▓▒▒▒▒▒▒▒▓▓░░░░░░░░░░░"};
|
||||
|
||||
|
||||
func printPepe(channel string, foo bot) {
|
||||
for _, x := range pepe {
|
||||
sendmsg(foo.conn, channel, x)
|
||||
}
|
||||
LOG_INFO.Printf("Sent pepe to ppl")
|
||||
}
|
||||
34
types.go
34
types.go
|
|
@ -1,34 +0,0 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"net"
|
||||
)
|
||||
|
||||
type Config struct {
|
||||
Name string `cfg:"name; boddle; printableascii; IRC nick of bot"`
|
||||
Channels []string `cfg:"channels; required; printableascii; Channel list to join to"`
|
||||
Server string `cfg:"server; required; netaddr; Server name to connect to"`
|
||||
Database string `cfg:"database; ./boddle.db; path; Path to database"`
|
||||
}
|
||||
|
||||
type irc_msg struct {
|
||||
channel string
|
||||
msg string
|
||||
author string
|
||||
retmsg string
|
||||
}
|
||||
|
||||
type cmd struct {
|
||||
valid bool
|
||||
add bool
|
||||
cmd string
|
||||
groups []string
|
||||
suffix string
|
||||
error string
|
||||
}
|
||||
|
||||
type bot struct {
|
||||
Conf Config
|
||||
conn net.Conn
|
||||
}
|
||||
|
||||
Loading…
Add table
Add a link
Reference in a new issue