Compare commits

..

No commits in common. "9b016251f25e66bcafc9891c139a4ded7d2aebc3" and "f3ed0fe6c0ba5db30c0bbb58783752fdfb35caa4" have entirely different histories.

14 changed files with 388 additions and 502 deletions

BIN
boddle.db

Binary file not shown.

317
boddle.go
View file

@ -1,18 +1,83 @@
package main package main
import ( import "strings"
"strings" import "fmt"
"fmt" import "regexp"
"regexp" import "database/sql"
"database/sql" import _ "github.com/mattn/go-sqlite3"
"math/rand"
_ "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 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 {
@ -60,17 +125,17 @@ func filter(msg string, foo bot) cmd {
LOG_WARN.Printf("invalid query.") LOG_WARN.Printf("invalid query.")
return c return c
} }
if rows.Next() {
group_id := 0 group_id := 0
if rows.Next() {
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))
} else {
if c.add {
c.groups = append(c.groups, addgroups([]string{group}, nil)...)
}
}
rows.Close() 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.suffix = res[3]
c.valid = true c.valid = true
@ -93,7 +158,6 @@ 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
} }
@ -110,41 +174,65 @@ func getRandomEntry(c cmd) string {
return task 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 = ?") 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
} }
groupid_res, err := stat_ins.Exec(group) _, 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 {
(*msg).retmsg = "Added " + strings.Join(groups_added, ", ") + " to groups-table!" sendmsg(foo.conn, msg.channel, "Added " + strings.Join(groups_added, ", ") + " to groups-table!")
} else { } else {
(*msg).retmsg = "Added nothing to groups-table! :(" sendmsg(foo.conn, msg.channel, "Added nothing to groups-table! :(")
} }
} return false
return groupids_added
} }
func checkSorter(msg *irc_msg, c *cmd) bool { sorter_row, err := db.Query(fmt.Sprintf("select id, tag_id, groups_allow, name_allow, has_groups from sorter where name = '%s'", c.cmd))
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
@ -156,72 +244,53 @@ func checkSorter(msg *irc_msg, c *cmd) bool {
sorter_row.Close() sorter_row.Close()
if groups_allow != 0 { 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 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 {
group_sel, err := db.Prepare("select group_id from sorter_groups where sorter_id = ?") sorter_groups_row, err := db.Query(fmt.Sprintf("select group_id from sorter_groups where sorter_id = '%s'", 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 = %s", tag_id)) tag_name_row, err := db.Query(fmt.Sprintf("select name from tag where id = %d", 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")
(*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 return false
} }
} }
} else { } else {
LOG_WARN.Printf("no sorter entry, no translation possible\n") 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 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) { res, err := db.Exec("insert into line (content, author) values (?,?)", c.suffix, msg.author)
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")
@ -229,94 +298,48 @@ func addLine(msg *irc_msg, line string, groups []string, cmd string) string {
line_id, err := res.LastInsertId(); line_id, err := res.LastInsertId();
checkErr(err) 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 // 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 (?,?)") stat, err := db.Prepare("insert into brain(line_id, tag_id) values (?,?)")
checkErr(err) checkErr(err)
_, err = stat.Exec(line_id, cmd) _, err = stat.Exec(line_id, c.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 groups { for _, group := range c.groups {
_, err = stat.Exec(line_id, cmd, group) _, err = stat.Exec(line_id, c.cmd, group)
checkErr(err) checkErr(err)
} }
LOG_INFO.Printf("inserted foo! \n")
defer stat.Close() defer stat.Close()
} }
(*msg).retmsg = fmt.Sprintf("success adding new super funny enjoyable line with ID %d!", line_id) sendmsg(foo.conn, msg.channel, 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,",")) sendmsg(foo.conn, "horscchtey", fmt.Sprintf("new line: > %s < (ID %d), into groups %s", c.suffix, line_id, strings.Join(c.groups,",")))
} return true
// line: }
// >befehl <[groups]> <name>
// befehl ist genau ein wort task := getRandomEntry(c)
func parsemsg(msg *irc_msg, foo bot) bool {
if len((*msg).msg) <= 0 { LOG_INFO.Printf(task)
return false row, err := db.Query(task)
} checkErr(err)
if (*msg).msg == "<3" { res := ""
(*msg).msg = string(begin_char[0]) + "flirt kreisi" if row.Next() {
} row.Scan(&res)
}
if !in((*msg).msg[0], begin_char) { row.Close()
return false
} if len(res) <= 0 {
(*msg).msg = (*msg).msg[1:] LOG_WARN.Printf("no entry found\n")
res = "No matching entry found :("
c := filter((*msg).msg, foo) } else if len(c.suffix) > 0 {
if !c.valid { res = fmt.Sprintf("%s... %s", c.suffix, res)
LOG_WARN.Printf("non valid input found.\n") }
if c.error != "" { sendmsg(foo.conn, msg.channel, res)
(*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
View file

@ -1,152 +1,27 @@
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"
) )
func sendmsg (conn net.Conn, channel string, msg string) { var dead = true
mesg := fmt.Sprintf("PRIVMSG %s :%s\r\n", channel, msg)
fmt.Printf(mesg) type Config struct {
conn.Write([]byte(mesg)) 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) { type bot struct {
LOG_ERR.Printf(msg) Conf Config
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() {
@ -156,6 +31,33 @@ 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",
// }
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
View file

@ -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/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() cursor = connection.cursor()
dispatcher = updater.dispatcher dispatcher = updater.dispatcher

View file

@ -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"`
}

View file

@ -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;
});
};
}

View file

@ -1,10 +1,15 @@
#!/bin/bash #!/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 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 helpers.go types.go) src+=(bot.go boddle.go logging.go ircfoo.go)
declare -i nproc="$(nproc)" declare -i nproc="$(nproc)"
go build -v -p ${nproc} "${src[@]}" go build -p ${nproc} "${src[@]}"

13
go.mod
View file

@ -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
View file

@ -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=

View file

@ -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
View 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
View 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")
}

View file

@ -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
}