diff --git a/boddle.db b/boddle.db index f87f152..345a363 100644 Binary files a/boddle.db and b/boddle.db differ diff --git a/boddle.go b/boddle.go index 11c733a..86604cf 100644 --- a/boddle.go +++ b/boddle.go @@ -1,18 +1,83 @@ package main -import ( - "strings" - "fmt" - "regexp" - "database/sql" - "math/rand" - _ "github.com/mattn/go-sqlite3" -) +import "strings" +import "fmt" +import "regexp" +import "database/sql" +import _ "github.com/mattn/go-sqlite3" -var begin_char = []byte{'-'} +type irc_msg struct { + channel string + msg string + author string +} + +type cmd struct { + valid bool + add bool + cmd string + groups []string + suffix string + error string +} + +var begin_char = []byte{'-', '<'} var db *sql.DB var err error +func checkErr(err error) { + if err != nil { + fmt.Printf("::::ERROR:::: %s\n", err) + panic(err) + } +} + +func in (a byte, arr []byte) bool { + for _, x := range arr { + if x == a { + return true + } + } + return false +} + +func unique_str(stringSlice []string) []string { + keys := make(map[string]bool) + list := []string{} + for _, entry := range stringSlice { + if _, value := keys[entry]; !value { + keys[entry] = true + list = append(list, entry) + } + } + return list +} + +func unique_int(intSlice []int) []int { + keys := make(map[int]bool) + list := []int{} + for _, entry := range intSlice { + if _, value := keys[entry]; !value { + keys[entry] = true + list = append(list, entry) + } + } + return list +} + +/* +func unique[T any](tSlice []T) []T { + keys := make(map[T]bool) + list := []T{} + for _, entry := range tSlice { + if _, value := keys[entry]; !value { + keys[entry] = true + list = append(list, entry) + } + } + return list +} +*/ // function to split advise message correctly func filter(msg string, foo bot) cmd { @@ -60,17 +125,17 @@ func filter(msg string, foo bot) cmd { LOG_WARN.Printf("invalid query.") return c } + 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 { - if c.add { - c.groups = append(c.groups, addgroups([]string{group}, nil)...) - } + c.valid = false + c.error = "Group name " + group + " is invalid." + rows.Close() + return c } - rows.Close() - defer stmt.Close() } c.suffix = res[3] c.valid = true @@ -93,7 +158,6 @@ func filter(msg string, foo bot) cmd { } c.cmd = strings.TrimSpace(c.cmd) c.suffix = strings.TrimSpace(c.suffix) - c.groups = unique_str(c.groups) return c } @@ -110,41 +174,65 @@ func getRandomEntry(c cmd) string { return task } -func addgroups(new_groups []string, msg *irc_msg) []string { - 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 - } - groupid_res, err := stat_ins.Exec(group) - checkErr(err) - defer stat_ins.Close() - groupid, err := groupid_res.LastInsertId() - checkErr(err) - groupids_added = append(groupids_added, fmt.Sprintf("%d", groupid)) - groups_added = append(groups_added, group) +// line: +// >befehl <[groups]> +// befehl ist genau ein wort +func parsemsg(msg irc_msg, foo bot) bool { + if len(msg.msg) <= 0 { + return false } - if msg != nil { - if len(groups_added) > 0 { - (*msg).retmsg = "Added " + strings.Join(groups_added, ", ") + " to groups-table!" - } else { - (*msg).retmsg = "Added nothing to groups-table! :(" - } + if !in(msg.msg[0], begin_char) { + return false } - return groupids_added -} + msg.msg = msg.msg[1:] -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) + c := filter(msg.msg, foo) + if !c.valid { + LOG_WARN.Printf("non valid input found.\n") + if c.error != "" { + sendmsg(foo.conn, msg.channel, "Falscher input du SP-Ersti... " + c.error) + } + return false + } + LOG_WARN.Printf("line was parsed, continue with evaluation.\n") + if c.cmd == "" { + LOG_WARN.Printf("no command provided.\n") + return false + } + if c.cmd == "help" { + return false + } + // hard code 'groups' to add new groups to the groups-table + if c.add && (c.cmd == "groups" || c.cmd == "group") { + if (c.groups != nil) { + sendmsg(foo.conn, msg.channel, "Ignoring groups for the groups-adding. Well, what were you expecting...?") + } + new_groups := strings.Fields(c.suffix) + stat_sel, err := db.Prepare("select id from groups where name = ?") + checkErr(err) + stat_ins, err := db.Prepare("insert into groups(name) values (?)") + checkErr(err) + var groups_added []string + 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) + } + if len(groups_added) > 0 { + sendmsg(foo.conn, msg.channel, "Added " + strings.Join(groups_added, ", ") + " to groups-table!") + } else { + sendmsg(foo.conn, msg.channel, "Added nothing to groups-table! :(") + } + return false + } + + sorter_row, err := db.Query(fmt.Sprintf("select id, tag_id, groups_allow, name_allow, has_groups from sorter where name = '%s'", c.cmd)) checkErr(err) if sorter_row.Next() { var sorter_id string @@ -156,167 +244,102 @@ func checkSorter(msg *irc_msg, c *cmd) bool { sorter_row.Close() if groups_allow != 0 { - (*msg).retmsg = "This command does not allow groups. :(" + sendmsg(foo.conn, msg.channel, "This command does not allow groups. :(") return false } - if name_allow != 0 && !(*c).add { + if name_allow != 0 && !c.add { // warning: not allowed - (*c).suffix = "" + c.suffix = "" } - (*c).cmd = tag_id + c.cmd = tag_id if has_groups == 0 { - group_sel, err := db.Prepare("select group_id from sorter_groups where sorter_id = ?") - checkErr(err) - sorter_groups_row, err := group_sel.Query(sorter_id) - //sorter_groups_row, err := db.Query(fmt.Sprintf("select group_id from sorter_groups where sorter_id = '%s'", sorter_id)) + sorter_groups_row, err := db.Query(fmt.Sprintf("select group_id from sorter_groups where sorter_id = '%s'", sorter_id)) checkErr(err) if sorter_groups_row.Next() { var group_id int sorter_groups_row.Scan(&group_id) - (*c).groups = append((*c).groups, fmt.Sprintf("%d", group_id)) + c.groups = append(c.groups, fmt.Sprintf("%d", group_id)) } sorter_groups_row.Close() - if (*c).add { + if c.add { var tag_name string - tag_name_row, err := db.Query(fmt.Sprintf("select name from tag where id = %s", tag_id)) + tag_name_row, err := db.Query(fmt.Sprintf("select name from tag where id = %d", tag_id)) checkErr(err) if tag_name_row.Next() { tag_name_row.Scan(&tag_name) } tag_name_row.Close() LOG_WARN.Printf("Alias used. Tell the user about that.\n") - (*msg).retmsg = "You're using an alias. Please try again with 'add " + tag_name + " [" + strings.Join((*c).groups, " ") + "]. Thanks!" + sendmsg(foo.conn, msg.channel, "You're using an alias. Please try again with 'add " + tag_name + " [" + strings.Join(c.groups, " ") + "]. Thanks!") return false } } } else { LOG_WARN.Printf("no sorter entry, no translation possible\n") - (*msg).retmsg = "No entry found, sorry..." - 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]> -// 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) + sendmsg(foo.conn, msg.channel, "No entry found, sorry...") 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) + 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 } + + 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 } diff --git a/bot.go b/bot.go index c2598df..19bcce1 100644 --- a/bot.go +++ b/bot.go @@ -1,152 +1,27 @@ package main import ( + "os" "log" "fmt" "net" "time" - "bufio" - "strings" - "database/sql" configo "github.com/distributedio/configo" _ "github.com/mattn/go-sqlite3" ) -func sendmsg (conn net.Conn, channel string, msg string) { - mesg := fmt.Sprintf("PRIVMSG %s :%s\r\n", channel, msg) - fmt.Printf(mesg) - conn.Write([]byte(mesg)) +var dead = true + +type Config struct { + Name string `cfg:"name; boddle; printableascii; IRC nick of bot"` + Channels []string `cfg:"channels; required; printableascii; Channel list to join to"` + Server string `cfg:"server; required; netaddr; Server name to connect to"` + Database string `cfg:"database; ./boddle.db; path; Path to database"` } -func scanline_privmsg (msg string, irc *irc_msg) { - LOG_ERR.Printf(msg) - - msg = msg[1:] - t := strings.Split(msg, "!") - (*irc).author, (*irc).channel = t[0], t[1] - t = strings.Split((*irc).channel, "PRIVMSG ") - (*irc).channel = t[1] - t = strings.Split((*irc).channel, " :") - (*irc).channel, (*irc).msg = t[0], t[1] - t = strings.Split((*irc).msg, "\r\n") - (*irc).msg = strings.TrimSpace(t[0]) - if ! strings.HasPrefix((*irc).channel, "#") { - (*irc).channel = (*irc).author - } - (*irc).retmsg = "" -} - -func bot_connect(bot *bot) { - conn, err := net.Dial("tcp", (*bot).Conf.Server) - if err != nil { - LOG_ERR.Printf("Error while dialing server.") - (*bot).conn = nil - return - } - - (*bot).conn = conn - fmt.Fprintf((*bot).conn, "USER %s 1 1 1:%s\r\n", (*bot).Conf.Name, (*bot).Conf.Name) -} - -func bot_register(bot *bot) { - /* connect to irc */ - fmt.Fprintf((*bot).conn, "NICK %s\r\n", (*bot).Conf.Name) - for _, channel := range((*bot).Conf.Channels) { - fmt.Fprintf((*bot).conn, "JOIN %s\r\n", channel) - } -} - -func bot_listen(bot *bot) <-chan string { - c := make(chan string) - bot_register(bot) - - go func(timeoutNormal time.Duration, timeoutVersion time.Duration) { - bufReader := bufio.NewReader((*bot).conn) - - timeoutDuration := timeoutNormal - waitversion := false - - defer func() { - fmt.Println("Closing connection...") - close(c) - (*bot).conn.Close() - }() - - for { - (*bot).conn.SetReadDeadline(time.Now().Add(timeoutDuration)) - - line, err := bufReader.ReadString('\n') - if err != nil { - if nerr, ok := err.(net.Error); ok && nerr.Timeout() { - fmt.Printf("Timeout!\n") - if waitversion { - fmt.Println("VERSION command did not return.") - return - } - - n, err := (*bot).conn.Write([]byte("VERSION\n")) - fmt.Printf("n: %d, err: %s\n", n, err) - if err != nil { - fmt.Println("Writing to channel failed.") - return - } - // wait for return value of VERSION - waitversion = true - timeoutDuration = timeoutVersion - } else { - fmt.Println("Some more serious error occured while reading.") - return - } - continue - } - - // not waiting for version answer right now - timeoutDuration = timeoutNormal - waitversion = false - c <- line - - if strings.Contains(line, "PING") { - (*bot).conn.Write([]byte(strings.Replace(line, "PING", "PONG", 1))) - } else if strings.Contains(line, "You have not registered") { - // set nickname - time.Sleep(10 * time.Second) - bot_register(bot) - } else if strings.Contains(line, "PRIVMSG") { - var msg irc_msg - scanline_privmsg(line, &msg) - LOG_ERR.Printf(msg.author) - parsemsg(&msg, (*bot)) - if msg.retmsg != "" { - sendmsg((*bot).conn, msg.channel, msg.retmsg) - } - } - } - } (4 * time.Minute, 1 * time.Minute) - - return c -} - -func bot_run(bot *bot) { - LOG_INFO.Println("Bot ready to run.") - - LOG_INFO.Println("Opening database.") - db, err = sql.Open("sqlite3", (*bot).Conf.Database) - if err != nil { - LOG_ERR.Println("Opening database failed.") - return - } - - for { - bot_connect(bot) - if bot.conn == nil { - LOG_INFO.Printf("Bot is nil. Try to connect again.") - time.Sleep(10 * time.Second) - continue - } - for val := range bot_listen(bot) { - LOG_INFO.Printf("%s", val) - } - } +type bot struct { + Conf Config + conn net.Conn } func main() { @@ -156,6 +31,33 @@ func main() { if err := configo.Load("./boddle.toml", &boddle.Conf); err != nil { log.Fatal(err) } +// boddle := bot { +// name: "boddle", +// channel: []string{"#faui2k16", "#fau", "#sigbike", "#sigfreibad"}, +// port: 6667, +// server: "irc.fau.de", +// } - bot_run(&boddle) + LOG_INFO.Println("bot started!") + + var botchan <-chan []byte + var line []byte + dead = true + + for { + if dead { + LOG_WARN.Println("died.") + for { + botchan = connect(boddle) + if botchan != nil { + break + } + time.Sleep(10 * time.Second) + } + LOG_INFO.Println("reconnected.") + dead = false + } + line = <-botchan + fmt.Fprintf(os.Stderr, string(line)) + } } diff --git a/bot.py b/bot.py index 21ecae9..d623236 100644 --- a/bot.py +++ b/bot.py @@ -12,7 +12,7 @@ import sqlite3 as sql updater = Updater(token='935673062:AAH4By1EMqAUaD9wgnV3lZQRRBX6e5Lve6g', use_context=True) # sqlite database -connection = sql.connect("/home/boddle/boddle/src/v2/boddle.db", check_same_thread=False) +connection = sql.connect("/home/horscchtey/bots/boddle/src/v2/boddle.db", check_same_thread=False) cursor = connection.cursor() dispatcher = updater.dispatcher diff --git a/conf.go b/conf.go deleted file mode 100644 index ccccef9..0000000 --- a/conf.go +++ /dev/null @@ -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"` -} diff --git a/flake.nix b/flake.nix deleted file mode 100644 index a59231c..0000000 --- a/flake.nix +++ /dev/null @@ -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; - }); - }; -} diff --git a/forraspidothis b/forraspidothis index 6239be8..1bc0a64 100755 --- a/forraspidothis +++ b/forraspidothis @@ -1,10 +1,15 @@ #!/bin/bash -export GOPATH=/home/boddle/go +export GOPATH=/home/horscchtey/go +export CC=arm-linux-gnueabihf-gcc +export CXX=arm-linux-gnueabihf-g++ export CGO_ENABLED=1 +export GOOS=linux +export GOARCH=arm +export GOARM=7 declare -a src -src+=(bot.go boddle.go logging.go helpers.go types.go) +src+=(bot.go boddle.go logging.go ircfoo.go) declare -i nproc="$(nproc)" -go build -v -p ${nproc} "${src[@]}" +go build -p ${nproc} "${src[@]}" diff --git a/go.mod b/go.mod deleted file mode 100644 index 72f9306..0000000 --- a/go.mod +++ /dev/null @@ -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 -) diff --git a/go.sum b/go.sum deleted file mode 100644 index cb9d486..0000000 --- a/go.sum +++ /dev/null @@ -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= diff --git a/helpers.go b/helpers.go deleted file mode 100644 index f59c740..0000000 --- a/helpers.go +++ /dev/null @@ -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 -} diff --git a/ircfoo.go b/ircfoo.go new file mode 100644 index 0000000..2a3e2bd --- /dev/null +++ b/ircfoo.go @@ -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) +} diff --git a/logging.go b/logging.go index 6c03744..02769c6 100644 --- a/logging.go +++ b/logging.go @@ -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) } diff --git a/pepe.go b/pepe.go new file mode 100644 index 0000000..9ba9fd5 --- /dev/null +++ b/pepe.go @@ -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") +} diff --git a/types.go b/types.go deleted file mode 100644 index b2968c4..0000000 --- a/types.go +++ /dev/null @@ -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 -} -