Compare commits
10 commits
f3ed0fe6c0
...
9b016251f2
| Author | SHA1 | Date | |
|---|---|---|---|
| 9b016251f2 | |||
|
|
2e1890c9f9 | ||
|
|
df2a986286 | ||
|
|
e5a935a85b | ||
|
|
7683f9ee03 | ||
|
|
e45fd544b5 | ||
|
|
f6cf8b46ec | ||
|
|
9e09e78ab8 | ||
|
|
7ead746d98 | ||
|
|
fe7055298a |
14 changed files with 497 additions and 383 deletions
BIN
boddle.db
BIN
boddle.db
Binary file not shown.
363
boddle.go
363
boddle.go
|
|
@ -1,83 +1,18 @@
|
|||
package main
|
||||
|
||||
import "strings"
|
||||
import "fmt"
|
||||
import "regexp"
|
||||
import "database/sql"
|
||||
import _ "github.com/mattn/go-sqlite3"
|
||||
import (
|
||||
"strings"
|
||||
"fmt"
|
||||
"regexp"
|
||||
"database/sql"
|
||||
"math/rand"
|
||||
_ "github.com/mattn/go-sqlite3"
|
||||
)
|
||||
|
||||
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 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 {
|
||||
|
|
@ -125,17 +60,17 @@ func filter(msg string, foo bot) cmd {
|
|||
LOG_WARN.Printf("invalid query.")
|
||||
return c
|
||||
}
|
||||
group_id := 0
|
||||
if rows.Next() {
|
||||
group_id := 0
|
||||
rows.Scan(&group_id)
|
||||
c.groups = append(c.groups, fmt.Sprintf("%d", group_id))
|
||||
rows.Close()
|
||||
} else {
|
||||
c.valid = false
|
||||
c.error = "Group name " + group + " is invalid."
|
||||
rows.Close()
|
||||
return c
|
||||
if c.add {
|
||||
c.groups = append(c.groups, addgroups([]string{group}, nil)...)
|
||||
}
|
||||
}
|
||||
rows.Close()
|
||||
defer stmt.Close()
|
||||
}
|
||||
c.suffix = res[3]
|
||||
c.valid = true
|
||||
|
|
@ -158,6 +93,7 @@ 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
|
||||
}
|
||||
|
|
@ -174,65 +110,41 @@ func getRandomEntry(c cmd) string {
|
|||
return task
|
||||
}
|
||||
|
||||
// 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)
|
||||
func addgroups(new_groups []string, msg *irc_msg) []string {
|
||||
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 {
|
||||
ret, err := stat_sel.Query(group)
|
||||
if ret.Next() {
|
||||
ret.Close()
|
||||
continue
|
||||
}
|
||||
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 = ?")
|
||||
groupid_res, err := stat_ins.Exec(group)
|
||||
checkErr(err)
|
||||
stat_ins, err := db.Prepare("insert into groups(name) values (?)")
|
||||
defer stat_ins.Close()
|
||||
groupid, err := groupid_res.LastInsertId()
|
||||
checkErr(err)
|
||||
var groups_added []string
|
||||
for _, group := range new_groups {
|
||||
fmt.Println(group)
|
||||
ret, err := stat_sel.Query(group)
|
||||
if ret.Next() {
|
||||
ret.Close()
|
||||
continue
|
||||
}
|
||||
_, err = stat_ins.Exec(group)
|
||||
checkErr(err)
|
||||
groups_added = append(groups_added, group)
|
||||
}
|
||||
groupids_added = append(groupids_added, fmt.Sprintf("%d", groupid))
|
||||
groups_added = append(groups_added, group)
|
||||
}
|
||||
if msg != nil {
|
||||
if len(groups_added) > 0 {
|
||||
sendmsg(foo.conn, msg.channel, "Added " + strings.Join(groups_added, ", ") + " to groups-table!")
|
||||
(*msg).retmsg = "Added " + strings.Join(groups_added, ", ") + " to groups-table!"
|
||||
} else {
|
||||
sendmsg(foo.conn, msg.channel, "Added nothing to groups-table! :(")
|
||||
(*msg).retmsg = "Added nothing to groups-table! :("
|
||||
}
|
||||
return false
|
||||
}
|
||||
return groupids_added
|
||||
}
|
||||
|
||||
sorter_row, err := db.Query(fmt.Sprintf("select id, tag_id, groups_allow, name_allow, has_groups from sorter where name = '%s'", c.cmd))
|
||||
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)
|
||||
checkErr(err)
|
||||
if sorter_row.Next() {
|
||||
var sorter_id string
|
||||
|
|
@ -244,102 +156,167 @@ func parsemsg(msg irc_msg, foo bot) bool {
|
|||
sorter_row.Close()
|
||||
|
||||
if groups_allow != 0 {
|
||||
sendmsg(foo.conn, msg.channel, "This command does not allow groups. :(")
|
||||
(*msg).retmsg = "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 {
|
||||
sorter_groups_row, err := db.Query(fmt.Sprintf("select group_id from sorter_groups where sorter_id = '%s'", sorter_id))
|
||||
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))
|
||||
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 = %d", tag_id))
|
||||
tag_name_row, err := db.Query(fmt.Sprintf("select name from tag where id = %s", 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")
|
||||
sendmsg(foo.conn, msg.channel, "You're using an alias. Please try again with 'add " + tag_name + " [" + strings.Join(c.groups, " ") + "]. Thanks!")
|
||||
(*msg).retmsg = "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")
|
||||
sendmsg(foo.conn, msg.channel, "No entry found, sorry...")
|
||||
(*msg).retmsg = "No entry found, sorry..."
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
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)
|
||||
checkErr(err)
|
||||
LOG_WARN.Printf("added line to table.\n")
|
||||
|
||||
// get ID of content...
|
||||
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, "-"))
|
||||
// for tag and all groups
|
||||
if len(groups) == 0 {
|
||||
stat, err := db.Prepare("insert into brain(line_id, tag_id) values (?,?)")
|
||||
checkErr(err)
|
||||
_, err = stat.Exec(line_id, cmd)
|
||||
checkErr(err)
|
||||
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)
|
||||
checkErr(err)
|
||||
}
|
||||
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)
|
||||
LOG_WARN.Printf("adding new stuff: %s from %s.\n", c.suffix, 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")
|
||||
|
||||
// get ID of content...
|
||||
line_id, err := res.LastInsertId();
|
||||
checkErr(err)
|
||||
|
||||
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(c.groups) == 0 {
|
||||
stat, err := db.Prepare("insert into brain(line_id, tag_id) values (?,?)")
|
||||
checkErr(err)
|
||||
_, 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 c.groups {
|
||||
_, err = stat.Exec(line_id, c.cmd, group)
|
||||
checkErr(err)
|
||||
}
|
||||
LOG_INFO.Printf("inserted foo! \n")
|
||||
defer stat.Close()
|
||||
}
|
||||
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
|
||||
sendmsg(foo.conn, "horscchtey", addLine(msg, c.suffix, c.groups, c.cmd))
|
||||
} else {
|
||||
chooseEntry(msg, &c)
|
||||
}
|
||||
|
||||
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,27 +1,152 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"os"
|
||||
"log"
|
||||
"fmt"
|
||||
"net"
|
||||
"time"
|
||||
"bufio"
|
||||
"strings"
|
||||
"database/sql"
|
||||
configo "github.com/distributedio/configo"
|
||||
_ "github.com/mattn/go-sqlite3"
|
||||
)
|
||||
|
||||
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 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))
|
||||
}
|
||||
|
||||
type bot struct {
|
||||
Conf Config
|
||||
conn net.Conn
|
||||
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)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func main() {
|
||||
|
|
@ -31,33 +156,6 @@ 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",
|
||||
// }
|
||||
|
||||
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))
|
||||
}
|
||||
bot_run(&boddle)
|
||||
}
|
||||
|
|
|
|||
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/horscchtey/bots/boddle/src/v2/boddle.db", check_same_thread=False)
|
||||
connection = sql.connect("/home/boddle/boddle/src/v2/boddle.db", check_same_thread=False)
|
||||
cursor = connection.cursor()
|
||||
|
||||
dispatcher = updater.dispatcher
|
||||
|
|
|
|||
8
conf.go
Normal file
8
conf.go
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
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
Normal file
62
flake.nix
Normal file
|
|
@ -0,0 +1,62 @@
|
|||
{
|
||||
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,15 +1,10 @@
|
|||
#!/bin/bash
|
||||
|
||||
export GOPATH=/home/horscchtey/go
|
||||
export CC=arm-linux-gnueabihf-gcc
|
||||
export CXX=arm-linux-gnueabihf-g++
|
||||
export GOPATH=/home/boddle/go
|
||||
export CGO_ENABLED=1
|
||||
export GOOS=linux
|
||||
export GOARCH=arm
|
||||
export GOARM=7
|
||||
|
||||
declare -a src
|
||||
src+=(bot.go boddle.go logging.go ircfoo.go)
|
||||
src+=(bot.go boddle.go logging.go helpers.go types.go)
|
||||
declare -i nproc="$(nproc)"
|
||||
|
||||
go build -p ${nproc} "${src[@]}"
|
||||
go build -v -p ${nproc} "${src[@]}"
|
||||
|
|
|
|||
13
go.mod
Normal file
13
go.mod
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
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
Normal file
20
go.sum
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
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
Normal file
45
helpers.go
Normal file
|
|
@ -0,0 +1,45 @@
|
|||
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
98
ircfoo.go
|
|
@ -1,98 +0,0 @@
|
|||
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)
|
||||
}
|
||||
|
|
@ -12,9 +12,9 @@ var (
|
|||
)
|
||||
|
||||
func LOG_init() {
|
||||
file := os.Stdout
|
||||
file := os.Stdout
|
||||
|
||||
LOG_INFO = log.New(file, "INFO: ", log.Ldate|log.Ltime|log.Lshortfile)
|
||||
LOG_WARN = log.New(file, "WARNING: ", log.Ldate|log.Ltime|log.Lshortfile)
|
||||
LOG_ERR = log.New(file, "ERROR: ", log.Ldate|log.Ltime|log.Lshortfile)
|
||||
LOG_INFO = log.New(file, "INFO: ", log.Ldate|log.Ltime|log.Lshortfile)
|
||||
LOG_WARN = log.New(file, "WARNING: ", log.Ldate|log.Ltime|log.Lshortfile)
|
||||
LOG_ERR = log.New(file, "ERROR: ", log.Ldate|log.Ltime|log.Lshortfile)
|
||||
}
|
||||
|
|
|
|||
40
pepe.go
40
pepe.go
|
|
@ -1,40 +0,0 @@
|
|||
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
Normal file
34
types.go
Normal file
|
|
@ -0,0 +1,34 @@
|
|||
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