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.
315
boddle.go
315
boddle.go
|
|
@ -1,83 +1,18 @@
|
||||||
package main
|
package main
|
||||||
|
|
||||||
import "strings"
|
import (
|
||||||
import "fmt"
|
"strings"
|
||||||
import "regexp"
|
"fmt"
|
||||||
import "database/sql"
|
"regexp"
|
||||||
import _ "github.com/mattn/go-sqlite3"
|
"database/sql"
|
||||||
|
"math/rand"
|
||||||
|
_ "github.com/mattn/go-sqlite3"
|
||||||
|
)
|
||||||
|
|
||||||
type irc_msg struct {
|
var begin_char = []byte{'-'}
|
||||||
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 db *sql.DB
|
||||||
var err error
|
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
|
// function to split advise message correctly
|
||||||
func filter(msg string, foo bot) cmd {
|
func filter(msg string, foo bot) cmd {
|
||||||
|
|
@ -125,18 +60,18 @@ func filter(msg string, foo bot) cmd {
|
||||||
LOG_WARN.Printf("invalid query.")
|
LOG_WARN.Printf("invalid query.")
|
||||||
return c
|
return c
|
||||||
}
|
}
|
||||||
group_id := 0
|
|
||||||
if rows.Next() {
|
if rows.Next() {
|
||||||
|
group_id := 0
|
||||||
rows.Scan(&group_id)
|
rows.Scan(&group_id)
|
||||||
c.groups = append(c.groups, fmt.Sprintf("%d", group_id))
|
c.groups = append(c.groups, fmt.Sprintf("%d", group_id))
|
||||||
rows.Close()
|
|
||||||
} else {
|
} else {
|
||||||
c.valid = false
|
if c.add {
|
||||||
c.error = "Group name " + group + " is invalid."
|
c.groups = append(c.groups, addgroups([]string{group}, nil)...)
|
||||||
rows.Close()
|
|
||||||
return c
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
rows.Close()
|
||||||
|
defer stmt.Close()
|
||||||
|
}
|
||||||
c.suffix = res[3]
|
c.suffix = res[3]
|
||||||
c.valid = true
|
c.valid = true
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -158,6 +93,7 @@ func filter(msg string, foo bot) cmd {
|
||||||
}
|
}
|
||||||
c.cmd = strings.TrimSpace(c.cmd)
|
c.cmd = strings.TrimSpace(c.cmd)
|
||||||
c.suffix = strings.TrimSpace(c.suffix)
|
c.suffix = strings.TrimSpace(c.suffix)
|
||||||
|
c.groups = unique_str(c.groups)
|
||||||
|
|
||||||
return c
|
return c
|
||||||
}
|
}
|
||||||
|
|
@ -174,65 +110,41 @@ func getRandomEntry(c cmd) string {
|
||||||
return task
|
return task
|
||||||
}
|
}
|
||||||
|
|
||||||
// line:
|
func addgroups(new_groups []string, msg *irc_msg) []string {
|
||||||
// >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 = ?")
|
stat_sel, err := db.Prepare("select id from groups where name = ?")
|
||||||
checkErr(err)
|
checkErr(err)
|
||||||
stat_ins, err := db.Prepare("insert into groups(name) values (?)")
|
stat_ins, err := db.Prepare("insert into groups(name) values (?)")
|
||||||
checkErr(err)
|
checkErr(err)
|
||||||
var groups_added []string
|
var groups_added []string
|
||||||
|
var groupids_added []string
|
||||||
for _, group := range new_groups {
|
for _, group := range new_groups {
|
||||||
fmt.Println(group)
|
|
||||||
ret, err := stat_sel.Query(group)
|
ret, err := stat_sel.Query(group)
|
||||||
if ret.Next() {
|
if ret.Next() {
|
||||||
ret.Close()
|
ret.Close()
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
_, err = stat_ins.Exec(group)
|
groupid_res, err := stat_ins.Exec(group)
|
||||||
checkErr(err)
|
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)
|
groups_added = append(groups_added, group)
|
||||||
}
|
}
|
||||||
|
if msg != nil {
|
||||||
if len(groups_added) > 0 {
|
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 {
|
} 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)
|
checkErr(err)
|
||||||
if sorter_row.Next() {
|
if sorter_row.Next() {
|
||||||
var sorter_id string
|
var sorter_id string
|
||||||
|
|
@ -244,53 +156,72 @@ func parsemsg(msg irc_msg, foo bot) bool {
|
||||||
sorter_row.Close()
|
sorter_row.Close()
|
||||||
|
|
||||||
if groups_allow != 0 {
|
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
|
return false
|
||||||
}
|
}
|
||||||
if name_allow != 0 && !c.add {
|
if name_allow != 0 && !(*c).add {
|
||||||
// warning: not allowed
|
// warning: not allowed
|
||||||
c.suffix = ""
|
(*c).suffix = ""
|
||||||
}
|
}
|
||||||
|
|
||||||
c.cmd = tag_id
|
(*c).cmd = tag_id
|
||||||
|
|
||||||
if has_groups == 0 {
|
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)
|
checkErr(err)
|
||||||
if sorter_groups_row.Next() {
|
if sorter_groups_row.Next() {
|
||||||
var group_id int
|
var group_id int
|
||||||
sorter_groups_row.Scan(&group_id)
|
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()
|
sorter_groups_row.Close()
|
||||||
if c.add {
|
if (*c).add {
|
||||||
var tag_name string
|
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)
|
checkErr(err)
|
||||||
if tag_name_row.Next() {
|
if tag_name_row.Next() {
|
||||||
tag_name_row.Scan(&tag_name)
|
tag_name_row.Scan(&tag_name)
|
||||||
}
|
}
|
||||||
tag_name_row.Close()
|
tag_name_row.Close()
|
||||||
LOG_WARN.Printf("Alias used. Tell the user about that.\n")
|
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
|
return false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
LOG_WARN.Printf("no sorter entry, no translation possible\n")
|
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 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)
|
|
||||||
|
|
||||||
res, err := db.Exec("insert into line (content, author) values (?,?)", 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)
|
||||||
checkErr(err)
|
checkErr(err)
|
||||||
LOG_WARN.Printf("added line to table.\n")
|
LOG_WARN.Printf("added line to table.\n")
|
||||||
|
|
||||||
|
|
@ -298,48 +229,94 @@ func parsemsg(msg irc_msg, foo bot) bool {
|
||||||
line_id, err := res.LastInsertId();
|
line_id, err := res.LastInsertId();
|
||||||
checkErr(err)
|
checkErr(err)
|
||||||
|
|
||||||
LOG_WARN.Printf("line_id: %d, tag_id: %d, groups: %s\n", line_id, c.cmd, strings.Join(c.groups, "-"))
|
LOG_WARN.Printf("line_id: %d, tag_id: %s, groups: %s\n", line_id, cmd, strings.Join(groups, "-"))
|
||||||
// for tag and all groups
|
// for tag and all groups
|
||||||
if len(c.groups) == 0 {
|
if len(groups) == 0 {
|
||||||
stat, err := db.Prepare("insert into brain(line_id, tag_id) values (?,?)")
|
stat, err := db.Prepare("insert into brain(line_id, tag_id) values (?,?)")
|
||||||
checkErr(err)
|
checkErr(err)
|
||||||
_, err = stat.Exec(line_id, c.cmd)
|
_, err = stat.Exec(line_id, cmd)
|
||||||
checkErr(err)
|
checkErr(err)
|
||||||
LOG_INFO.Printf("inserted foo! \n")
|
|
||||||
defer stat.Close()
|
defer stat.Close()
|
||||||
} else {
|
} else {
|
||||||
stat, err := db.Prepare("insert into brain(line_id, tag_id, group_id) values (?,?,?)")
|
stat, err := db.Prepare("insert into brain(line_id, tag_id, group_id) values (?,?,?)")
|
||||||
checkErr(err)
|
checkErr(err)
|
||||||
for _, group := range c.groups {
|
for _, group := range groups {
|
||||||
_, err = stat.Exec(line_id, c.cmd, group)
|
_, err = stat.Exec(line_id, cmd, group)
|
||||||
checkErr(err)
|
checkErr(err)
|
||||||
}
|
}
|
||||||
LOG_INFO.Printf("inserted foo! \n")
|
|
||||||
defer stat.Close()
|
defer stat.Close()
|
||||||
}
|
}
|
||||||
sendmsg(foo.conn, msg.channel, fmt.Sprintf("success adding new super funny enjoyable line with ID %d!", line_id))
|
(*msg).retmsg = 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 fmt.Sprintf("new line: > %s < (ID %d), into groups %s", line, line_id, strings.Join(groups,","))
|
||||||
return true
|
}
|
||||||
}
|
// line:
|
||||||
|
// >befehl <[groups]> <name>
|
||||||
task := getRandomEntry(c)
|
// befehl ist genau ein wort
|
||||||
|
func parsemsg(msg *irc_msg, foo bot) bool {
|
||||||
LOG_INFO.Printf(task)
|
if len((*msg).msg) <= 0 {
|
||||||
row, err := db.Query(task)
|
return false
|
||||||
checkErr(err)
|
}
|
||||||
res := ""
|
if (*msg).msg == "<3" {
|
||||||
if row.Next() {
|
(*msg).msg = string(begin_char[0]) + "flirt kreisi"
|
||||||
row.Scan(&res)
|
}
|
||||||
}
|
|
||||||
row.Close()
|
if !in((*msg).msg[0], begin_char) {
|
||||||
|
return false
|
||||||
if len(res) <= 0 {
|
}
|
||||||
LOG_WARN.Printf("no entry found\n")
|
(*msg).msg = (*msg).msg[1:]
|
||||||
res = "No matching entry found :("
|
|
||||||
} else if len(c.suffix) > 0 {
|
c := filter((*msg).msg, foo)
|
||||||
res = fmt.Sprintf("%s... %s", c.suffix, res)
|
if !c.valid {
|
||||||
}
|
LOG_WARN.Printf("non valid input found.\n")
|
||||||
sendmsg(foo.conn, msg.channel, res)
|
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)
|
||||||
|
}
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
|
||||||
176
bot.go
176
bot.go
|
|
@ -1,27 +1,152 @@
|
||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"os"
|
|
||||||
"log"
|
"log"
|
||||||
"fmt"
|
"fmt"
|
||||||
"net"
|
"net"
|
||||||
"time"
|
"time"
|
||||||
|
"bufio"
|
||||||
|
"strings"
|
||||||
|
"database/sql"
|
||||||
configo "github.com/distributedio/configo"
|
configo "github.com/distributedio/configo"
|
||||||
_ "github.com/mattn/go-sqlite3"
|
_ "github.com/mattn/go-sqlite3"
|
||||||
)
|
)
|
||||||
|
|
||||||
var dead = true
|
func sendmsg (conn net.Conn, channel string, msg string) {
|
||||||
|
mesg := fmt.Sprintf("PRIVMSG %s :%s\r\n", channel, msg)
|
||||||
type Config struct {
|
fmt.Printf(mesg)
|
||||||
Name string `cfg:"name; boddle; printableascii; IRC nick of bot"`
|
conn.Write([]byte(mesg))
|
||||||
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 bot struct {
|
func scanline_privmsg (msg string, irc *irc_msg) {
|
||||||
Conf Config
|
LOG_ERR.Printf(msg)
|
||||||
conn net.Conn
|
|
||||||
|
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() {
|
func main() {
|
||||||
|
|
@ -31,33 +156,6 @@ func main() {
|
||||||
if err := configo.Load("./boddle.toml", &boddle.Conf); err != nil {
|
if err := configo.Load("./boddle.toml", &boddle.Conf); err != nil {
|
||||||
log.Fatal(err)
|
log.Fatal(err)
|
||||||
}
|
}
|
||||||
// boddle := bot {
|
|
||||||
// name: "boddle",
|
|
||||||
// channel: []string{"#faui2k16", "#fau", "#sigbike", "#sigfreibad"},
|
|
||||||
// port: 6667,
|
|
||||||
// server: "irc.fau.de",
|
|
||||||
// }
|
|
||||||
|
|
||||||
LOG_INFO.Println("bot started!")
|
bot_run(&boddle)
|
||||||
|
|
||||||
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)
|
updater = Updater(token='935673062:AAH4By1EMqAUaD9wgnV3lZQRRBX6e5Lve6g', use_context=True)
|
||||||
|
|
||||||
# sqlite database
|
# 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()
|
cursor = connection.cursor()
|
||||||
|
|
||||||
dispatcher = updater.dispatcher
|
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
|
#!/bin/bash
|
||||||
|
|
||||||
export GOPATH=/home/horscchtey/go
|
export GOPATH=/home/boddle/go
|
||||||
export CC=arm-linux-gnueabihf-gcc
|
|
||||||
export CXX=arm-linux-gnueabihf-g++
|
|
||||||
export CGO_ENABLED=1
|
export CGO_ENABLED=1
|
||||||
export GOOS=linux
|
|
||||||
export GOARCH=arm
|
|
||||||
export GOARM=7
|
|
||||||
|
|
||||||
declare -a src
|
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)"
|
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)
|
|
||||||
}
|
|
||||||
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