kill bot after 10 minutes idling

should prevent 'ping loss' due to weird network setup
This commit is contained in:
Eva Dengler 2022-03-05 21:39:54 +01:00
commit f6cf8b46ec
8 changed files with 187 additions and 230 deletions

View file

@ -1,70 +1,17 @@
package main
import "strings"
import "fmt"
import "regexp"
import "database/sql"
import _ "github.com/mattn/go-sqlite3"
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
}
import (
"strings"
"fmt"
"regexp"
"database/sql"
_ "github.com/mattn/go-sqlite3"
)
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
}
// function to split advise message correctly
func filter(msg string, foo bot) cmd {
@ -232,7 +179,7 @@ func checkSorter(msg *irc_msg, c *cmd) bool {
sorter_groups_row.Close()
if (*c).add {
var tag_name string
tag_name_row, err := db.Query(fmt.Sprintf("select name from tag where id = %d", tag_id))
tag_name_row, err := db.Query(fmt.Sprintf("select name from tag where id = %s", tag_id))
checkErr(err)
if tag_name_row.Next() {
tag_name_row.Scan(&tag_name)
@ -281,7 +228,7 @@ func addLine(msg *irc_msg, line string, groups []string, cmd string) string {
line_id, err := res.LastInsertId();
checkErr(err)
LOG_WARN.Printf("line_id: %d, tag_id: %d, groups: %s\n", line_id, cmd, strings.Join(groups, "-"))
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 (?,?)")

116
bot.go
View file

@ -6,22 +6,94 @@ import (
"fmt"
"net"
"time"
"bufio"
"bytes"
"strings"
"database/sql"
configo "github.com/distributedio/configo"
_ "github.com/mattn/go-sqlite3"
)
var dead = true
type Config struct {
Name string `cfg:"name; boddle; printableascii; IRC nick of bot"`
Channels []string `cfg:"channels; required; printableascii; Channel list to join to"`
Server string `cfg:"server; required; netaddr; Server name to connect to"`
Database string `cfg:"database; ./boddle.db; path; Path to database"`
func sendmsg (conn net.Conn, channel string, msg string) {
mesg := fmt.Sprintf("PRIVMSG %s :%s\r\n", channel, msg)
fmt.Printf(mesg)
conn.Write([]byte(mesg))
}
type bot struct {
Conf Config
conn net.Conn
func scanline_privmsg (msg string) irc_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
}
irc.retmsg = ""
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
}
go func() {
for {
line, err := reader.ReadString('\n')
if err != nil {
LOG_ERR.Printf("Error while reading bytes from connection.\n")
close(c)
return
}
c <- []byte(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)
} else if bytes.Contains([]byte(line), []byte("PRIVMSG")) {
msg := scanline_privmsg(string(line))
parsemsg(&msg, foo)
if msg.retmsg != "" {
sendmsg(foo.conn, msg.channel, msg.retmsg)
}
}
}
} ()
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))
}
func main() {
@ -35,23 +107,21 @@ func main() {
LOG_INFO.Println("bot started!")
var botchan <-chan []byte
var line []byte
dead = true
for {
if dead {
LOG_WARN.Println("died.")
botchan = connect(&boddle)
for {
botchan = connect(boddle)
if botchan != nil {
break
select {
case res := <-botchan:
fmt.Println(string(res))
case <-time.After(10 * time.Minute):
fmt.Println("timeout - 10 Minutes no ping received.")
// close channel, close connection
boddle.conn.Close()
goto Reconnect
}
time.Sleep(10 * time.Second)
}
LOG_INFO.Println("reconnected.")
dead = false
}
line = <-botchan
fmt.Fprintf(os.Stderr, string(line))
Reconnect:
fmt.Println("trying to reconnect...")
}
}

View file

@ -9,7 +9,7 @@ export GOARCH=arm
export GOARM=7
declare -a src
src+=(bot.go boddle.go logging.go ircfoo.go)
src+=(bot.go boddle.go logging.go helpers.go types.go)
declare -i nproc="$(nproc)"
go build -p ${nproc} "${src[@]}"

45
helpers.go Normal file
View 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
}

View file

@ -1,99 +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
}
irc.retmsg = ""
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
}
go func() {
for {
line, err := reader.ReadString('\n')
if err != nil {
LOG_ERR.Printf("Error while reading bytes from connection.\n")
dead = true
c <- []byte("killed it")
return
}
c <- []byte(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
}
msg := scanline_privmsg(string(line))
parsemsg(&msg, foo)
if msg.retmsg != "" {
sendmsg(foo.conn, msg.channel, msg.retmsg)
}
}
} ()
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
View file

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