~gsthnz/shruggy

f1de7b107caee75cd3ef7b0a9ec2cb78741751a1 — Gustavo Heinz 3 years ago dc6fb08
Add internal plugins to handle incoming messages
M bot.go => bot.go +21 -36
@@ 1,53 1,38 @@
package main

import (
	"crypto/rand"
	"fmt"
	"math/big"
	"git.sr.ht/~gsthnz/shruggy/internal/dice"
	"git.sr.ht/~gsthnz/shruggy/internal/shrug"
	"net"
	"strings"
)

const SHRUG = "¯\\_(ツ)_/¯"
var handlers []Handler

const HELP = `
.help to show this message
.roll to roll dice ('.roll d20' also works)
`
// List of handlers to match and return messages based on received messages.
// See handler.go for the Handler interface
func registerHandlers() {
	handlers = append(handlers,
		Helper{},
		shrug.Shrug{Nick: *nick},
		dice.Dice{},
	)
}

func onConnected(c net.Conn) {
	registerHandlers()
	send(c, fmt.Sprintf("JOIN %s", *channel))
	// TODO Handlers should be able to send messages on startup, this could be
	// removed from here.
	msgChannel(c, "I'm here, type '.help' to check available commands")
}

func handleBotMessage(c net.Conn, msg string) {
	msgChannel(c, "Wat?")
}

func handleBotCommand(c net.Conn, msg string) {
	if strings.HasPrefix(msg, ".help") {
		help := strings.Split(HELP, "\n")
		for _, line := range help {
			msgChannel(c, line)
		}
	}
	if strings.HasPrefix(msg, ".roll") {
		if strings.Contains(msg, "d20") {
			value, _ := rand.Int(rand.Reader, big.NewInt(20))
			msgChannel(c, value.String())
		} else {
			value, _ := rand.Int(rand.Reader, big.NewInt(6))
			msgChannel(c, value.String())
		}
	}
}

func handleChannelMessage(c net.Conn, msg string) {
	if strings.HasPrefix(msg, ".") {
		handleBotCommand(c, msg)
	} else if strings.HasPrefix(msg, *nick) {
		handleBotMessage(c, msg)
	} else if strings.Contains(msg, "shrug") {
		msgChannel(c, SHRUG)
	for _, handler := range handlers {
		if handler.Match(msg) {
			message := handler.Execute(msg)
			msgChannel(c, message)
		}
	}
	return
}

M go.mod => go.mod +6 -0
@@ 1,3 1,9 @@
module git.sr.ht/~gsthnz/shruggy

go 1.16

replace git.sr.ht/~gsthnz/shruggy/internal/dice => ./internal/dice/
require git.sr.ht/~gsthnz/shruggy/internal/dice v0.0.0

replace git.sr.ht/~gsthnz/shruggy/internal/shrug => ./internal/shrug/
require git.sr.ht/~gsthnz/shruggy/internal/shrug v0.0.0

A handler.go => handler.go +28 -0
@@ 0,0 1,28 @@
package main

import (
	"strings"
)

type Handler interface {
	// TODO Perhaps match could be a regex string
	// TODO Instead of a string, we could send a struct with more IRC
	// information
	Match(string) bool
	Execute(string) string
}

const HELP = ".help to show this message"

type Helper struct{}

func (s Helper) Match(msg string) bool {
	if strings.HasPrefix(msg, ".help") {
		return true
	}
	return false
}

func (s Helper) Execute(msg string) string {
	return HELP
}

A internal/dice/dice.go => internal/dice/dice.go +35 -0
@@ 0,0 1,35 @@
package dice

import (
	"fmt"
	"math/rand"
	"strings"
	"time"
)

var HELP = ".roll to roll dice ('.roll d20' also works)"

type Dice struct{}

func (d Dice) Match(msg string) bool {
	if strings.HasPrefix(msg, ".help") {
		return true
	}
	if strings.HasPrefix(msg, ".roll") {
		return true
	}
	return false
}

func (d Dice) Execute(msg string) string {
	rand.Seed(time.Now().UnixNano())
	if strings.HasPrefix(msg, ".help") {
		return HELP
	} else if strings.Contains(msg, "d20") {
		value := rand.Intn(20) + 1
		return fmt.Sprint(value)
	} else {
		value := rand.Intn(6) + 1
		return fmt.Sprint(value)
	}
}

A internal/dice/dice_test.go => internal/dice/dice_test.go +26 -0
@@ 0,0 1,26 @@
package dice

import "testing"

func TestDiceMatcher(t *testing.T) {
	dice := Dice{}
	if !dice.Match(".help") {
		t.Errorf("Did not matched .help")
	}
	if !dice.Match(".roll") {
		t.Errorf("Did not matched .roll")
	}
	if !dice.Match(".roll d20") {
		t.Errorf("Did not matched .roll")
	}
	if dice.Match("roll") {
		t.Errorf("matched roll")
	}
}

func TestDiceExecute(t *testing.T) {
	dice := Dice{}
	if dice.Execute(".help") != HELP {
		t.Errorf("Wrong help")
	}
}

A internal/dice/go.mod => internal/dice/go.mod +3 -0
@@ 0,0 1,3 @@
module git.sr.ht/~gsthnz/shruggy/internal/dice

go 1.16

A internal/shrug/go.mod => internal/shrug/go.mod +3 -0
@@ 0,0 1,3 @@
module git.sr.ht/~gsthnz/shruggy/internal/shrug

go 1.16

A internal/shrug/shrug.go => internal/shrug/shrug.go +27 -0
@@ 0,0 1,27 @@
package shrug

import (
	"strings"
)

const SHRUG = "¯\\_(ツ)_/¯"

type Shrug struct {
	Nick string
}

func (s Shrug) Match(msg string) bool {
	if strings.Contains(msg, s.Nick) {
		return true
	} else if strings.Contains(msg, "shrug") {
		return true
	}
	return false
}

func (s Shrug) Execute(msg string) string {
	if strings.Contains(msg, s.Nick) {
		return "Wat?"
	}
	return SHRUG
}

M main.go => main.go +2 -0
@@ 10,6 10,7 @@ import (
	"syscall"
)

// TODO Move to environment variables
var (
	nick    = flag.String("n", "", "Nick")
	server  = flag.String("s", "", "Server URL")


@@ 27,6 28,7 @@ func parseFlags() {
func main() {
	parseFlags()

    // TODO Support TLS connections
	conn, err := net.Dial("tcp", *server)
	if err != nil {
		panic(err)