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.

373
boddle.go
View file

@ -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]> <name>
// 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]> <name>
// befehl ist genau ein wort
func parsemsg(msg *irc_msg, foo bot) bool {
if len((*msg).msg) <= 0 {
return false
}
if (*msg).msg == "<3" {
(*msg).msg = string(begin_char[0]) + "flirt kreisi"
}
if !in((*msg).msg[0], begin_char) {
return false
}
(*msg).msg = (*msg).msg[1:]
c := filter((*msg).msg, foo)
if !c.valid {
LOG_WARN.Printf("non valid input found.\n")
if c.error != "" {
(*msg).retmsg = "Falscher input du SP-Ersti... " + c.error
}
return false
}
LOG_WARN.Printf("line was parsed, continue with evaluation.\n")
if c.cmd == "" {
LOG_WARN.Printf("no command provided.\n")
return false
}
if c.cmd == "help" {
(*msg).retmsg = "There is no help in this hell..."
return false
}
if c.cmd == "slap" {
who := []string{(*msg).author, "\x01ACTION"}
whom := []string{(*msg).author, foo.Conf.Name}
LOG_WARN.Printf("suffix: " + c.suffix)
if c.suffix != "" {
who = append(who, strings.Split(c.suffix, " ")...)
whom = append(whom, strings.Split(c.suffix, " ")...)
}
(*msg).retmsg = who[rand.Intn(len(who))] + " slaps " + whom[rand.Intn(len(whom))] + " around with a large trout."
return false
}
// hard code 'groups' to add new groups to the groups-table
if c.add && (c.cmd == "groups" || c.cmd == "group") {
if (c.groups != nil) {
(*msg).retmsg = "Ignoring groups for the groups-adding. Well, what were you expecting...?"
}
addgroups(strings.Fields((&c).suffix), msg)
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
}

176
bot.go
View file

@ -1,152 +1,27 @@
package main
import (
"os"
"log"
"fmt"
"net"
"time"
"bufio"
"strings"
"database/sql"
configo "github.com/distributedio/configo"
_ "github.com/mattn/go-sqlite3"
)
func sendmsg (conn net.Conn, channel string, msg string) {
mesg := fmt.Sprintf("PRIVMSG %s :%s\r\n", channel, msg)
fmt.Printf(mesg)
conn.Write([]byte(mesg))
var dead = true
type Config struct {
Name string `cfg:"name; boddle; printableascii; IRC nick of bot"`
Channels []string `cfg:"channels; required; printableascii; Channel list to join to"`
Server string `cfg:"server; required; netaddr; Server name to connect to"`
Database string `cfg:"database; ./boddle.db; path; Path to database"`
}
func scanline_privmsg (msg string, irc *irc_msg) {
LOG_ERR.Printf(msg)
msg = msg[1:]
t := strings.Split(msg, "!")
(*irc).author, (*irc).channel = t[0], t[1]
t = strings.Split((*irc).channel, "PRIVMSG ")
(*irc).channel = t[1]
t = strings.Split((*irc).channel, " :")
(*irc).channel, (*irc).msg = t[0], t[1]
t = strings.Split((*irc).msg, "\r\n")
(*irc).msg = strings.TrimSpace(t[0])
if ! strings.HasPrefix((*irc).channel, "#") {
(*irc).channel = (*irc).author
}
(*irc).retmsg = ""
}
func bot_connect(bot *bot) {
conn, err := net.Dial("tcp", (*bot).Conf.Server)
if err != nil {
LOG_ERR.Printf("Error while dialing server.")
(*bot).conn = nil
return
}
(*bot).conn = conn
fmt.Fprintf((*bot).conn, "USER %s 1 1 1:%s\r\n", (*bot).Conf.Name, (*bot).Conf.Name)
}
func bot_register(bot *bot) {
/* connect to irc */
fmt.Fprintf((*bot).conn, "NICK %s\r\n", (*bot).Conf.Name)
for _, channel := range((*bot).Conf.Channels) {
fmt.Fprintf((*bot).conn, "JOIN %s\r\n", channel)
}
}
func bot_listen(bot *bot) <-chan string {
c := make(chan string)
bot_register(bot)
go func(timeoutNormal time.Duration, timeoutVersion time.Duration) {
bufReader := bufio.NewReader((*bot).conn)
timeoutDuration := timeoutNormal
waitversion := false
defer func() {
fmt.Println("Closing connection...")
close(c)
(*bot).conn.Close()
}()
for {
(*bot).conn.SetReadDeadline(time.Now().Add(timeoutDuration))
line, err := bufReader.ReadString('\n')
if err != nil {
if nerr, ok := err.(net.Error); ok && nerr.Timeout() {
fmt.Printf("Timeout!\n")
if waitversion {
fmt.Println("VERSION command did not return.")
return
}
n, err := (*bot).conn.Write([]byte("VERSION\n"))
fmt.Printf("n: %d, err: %s\n", n, err)
if err != nil {
fmt.Println("Writing to channel failed.")
return
}
// wait for return value of VERSION
waitversion = true
timeoutDuration = timeoutVersion
} else {
fmt.Println("Some more serious error occured while reading.")
return
}
continue
}
// not waiting for version answer right now
timeoutDuration = timeoutNormal
waitversion = false
c <- line
if strings.Contains(line, "PING") {
(*bot).conn.Write([]byte(strings.Replace(line, "PING", "PONG", 1)))
} else if strings.Contains(line, "You have not registered") {
// set nickname
time.Sleep(10 * time.Second)
bot_register(bot)
} else if strings.Contains(line, "PRIVMSG") {
var msg irc_msg
scanline_privmsg(line, &msg)
LOG_ERR.Printf(msg.author)
parsemsg(&msg, (*bot))
if msg.retmsg != "" {
sendmsg((*bot).conn, msg.channel, msg.retmsg)
}
}
}
} (4 * time.Minute, 1 * time.Minute)
return c
}
func bot_run(bot *bot) {
LOG_INFO.Println("Bot ready to run.")
LOG_INFO.Println("Opening database.")
db, err = sql.Open("sqlite3", (*bot).Conf.Database)
if err != nil {
LOG_ERR.Println("Opening database failed.")
return
}
for {
bot_connect(bot)
if bot.conn == nil {
LOG_INFO.Printf("Bot is nil. Try to connect again.")
time.Sleep(10 * time.Second)
continue
}
for val := range bot_listen(bot) {
LOG_INFO.Printf("%s", val)
}
}
type bot struct {
Conf Config
conn net.Conn
}
func main() {
@ -156,6 +31,33 @@ func main() {
if err := configo.Load("./boddle.toml", &boddle.Conf); err != nil {
log.Fatal(err)
}
// boddle := bot {
// name: "boddle",
// channel: []string{"#faui2k16", "#fau", "#sigbike", "#sigfreibad"},
// port: 6667,
// server: "irc.fau.de",
// }
bot_run(&boddle)
LOG_INFO.Println("bot started!")
var botchan <-chan []byte
var line []byte
dead = true
for {
if dead {
LOG_WARN.Println("died.")
for {
botchan = connect(boddle)
if botchan != nil {
break
}
time.Sleep(10 * time.Second)
}
LOG_INFO.Println("reconnected.")
dead = false
}
line = <-botchan
fmt.Fprintf(os.Stderr, string(line))
}
}

2
bot.py
View file

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

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
export GOPATH=/home/boddle/go
export GOPATH=/home/horscchtey/go
export CC=arm-linux-gnueabihf-gcc
export CXX=arm-linux-gnueabihf-g++
export CGO_ENABLED=1
export GOOS=linux
export GOARCH=arm
export GOARM=7
declare -a src
src+=(bot.go boddle.go logging.go helpers.go types.go)
src+=(bot.go boddle.go logging.go ircfoo.go)
declare -i nproc="$(nproc)"
go build -v -p ${nproc} "${src[@]}"
go build -p ${nproc} "${src[@]}"

13
go.mod
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)
}

View file

@ -12,9 +12,9 @@ var (
)
func LOG_init() {
file := os.Stdout
file := os.Stdout
LOG_INFO = log.New(file, "INFO: ", log.Ldate|log.Ltime|log.Lshortfile)
LOG_WARN = log.New(file, "WARNING: ", log.Ldate|log.Ltime|log.Lshortfile)
LOG_ERR = log.New(file, "ERROR: ", log.Ldate|log.Ltime|log.Lshortfile)
LOG_INFO = log.New(file, "INFO: ", log.Ldate|log.Ltime|log.Lshortfile)
LOG_WARN = log.New(file, "WARNING: ", log.Ldate|log.Ltime|log.Lshortfile)
LOG_ERR = log.New(file, "ERROR: ", log.Ldate|log.Ltime|log.Lshortfile)
}

40
pepe.go 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
}