This commit is contained in:
parent
9c78ea2d48
commit
7c684af8c3
79 changed files with 3594 additions and 3257 deletions
50
internal/plugin/fun/coin.go
Normal file
50
internal/plugin/fun/coin.go
Normal file
|
@ -0,0 +1,50 @@
|
|||
package fun
|
||||
|
||||
import (
|
||||
"math/rand"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"git.nakama.town/fmartingr/butterrobot/internal/model"
|
||||
"git.nakama.town/fmartingr/butterrobot/internal/plugin"
|
||||
)
|
||||
|
||||
// CoinPlugin flips a coin
|
||||
type CoinPlugin struct {
|
||||
plugin.BasePlugin
|
||||
rand *rand.Rand
|
||||
}
|
||||
|
||||
// NewCoin creates a new CoinPlugin instance
|
||||
func NewCoin() *CoinPlugin {
|
||||
source := rand.NewSource(time.Now().UnixNano())
|
||||
return &CoinPlugin{
|
||||
BasePlugin: plugin.BasePlugin{
|
||||
ID: "fun.coin",
|
||||
Name: "Coin Flip",
|
||||
Help: "Flips a coin when you type 'flip a coin'",
|
||||
},
|
||||
rand: rand.New(source),
|
||||
}
|
||||
}
|
||||
|
||||
// OnMessage handles incoming messages
|
||||
func (p *CoinPlugin) OnMessage(msg *model.Message, config map[string]interface{}) []*model.Message {
|
||||
if !strings.Contains(strings.ToLower(msg.Text), "flip a coin") {
|
||||
return nil
|
||||
}
|
||||
|
||||
result := "Heads"
|
||||
if p.rand.Intn(2) == 0 {
|
||||
result = "Tails"
|
||||
}
|
||||
|
||||
response := &model.Message{
|
||||
Text: result,
|
||||
Chat: msg.Chat,
|
||||
ReplyTo: msg.ID,
|
||||
Channel: msg.Channel,
|
||||
}
|
||||
|
||||
return []*model.Message{response}
|
||||
}
|
118
internal/plugin/fun/dice.go
Normal file
118
internal/plugin/fun/dice.go
Normal file
|
@ -0,0 +1,118 @@
|
|||
package fun
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"math/rand"
|
||||
"regexp"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"git.nakama.town/fmartingr/butterrobot/internal/model"
|
||||
"git.nakama.town/fmartingr/butterrobot/internal/plugin"
|
||||
)
|
||||
|
||||
// DicePlugin rolls dice based on standard dice notation
|
||||
type DicePlugin struct {
|
||||
plugin.BasePlugin
|
||||
rand *rand.Rand
|
||||
}
|
||||
|
||||
// NewDice creates a new DicePlugin instance
|
||||
func NewDice() *DicePlugin {
|
||||
source := rand.NewSource(time.Now().UnixNano())
|
||||
return &DicePlugin{
|
||||
BasePlugin: plugin.BasePlugin{
|
||||
ID: "fun.dice",
|
||||
Name: "Dice Roller",
|
||||
Help: "Rolls dice when you type '!dice [formula]' (default: 1d20)",
|
||||
},
|
||||
rand: rand.New(source),
|
||||
}
|
||||
}
|
||||
|
||||
// OnMessage handles incoming messages
|
||||
func (p *DicePlugin) OnMessage(msg *model.Message, config map[string]interface{}) []*model.Message {
|
||||
if !strings.HasPrefix(strings.TrimSpace(strings.ToLower(msg.Text)), "!dice") {
|
||||
return nil
|
||||
}
|
||||
|
||||
// Extract dice formula
|
||||
formula := strings.TrimSpace(strings.TrimPrefix(msg.Text, "!dice"))
|
||||
formula = strings.TrimSpace(strings.TrimPrefix(formula, "!dice"))
|
||||
|
||||
if formula == "" {
|
||||
formula = "1d20" // Default formula
|
||||
}
|
||||
|
||||
// Parse and roll the dice
|
||||
result, err := p.rollDice(formula)
|
||||
responseText := ""
|
||||
|
||||
if err != nil {
|
||||
responseText = fmt.Sprintf("Error: %s", err.Error())
|
||||
} else {
|
||||
responseText = fmt.Sprintf("%d", result)
|
||||
}
|
||||
|
||||
response := &model.Message{
|
||||
Text: responseText,
|
||||
Chat: msg.Chat,
|
||||
ReplyTo: msg.ID,
|
||||
Channel: msg.Channel,
|
||||
}
|
||||
|
||||
return []*model.Message{response}
|
||||
}
|
||||
|
||||
// rollDice parses a dice formula string and returns the result
|
||||
func (p *DicePlugin) rollDice(formula string) (int, error) {
|
||||
// Support basic dice notation like "2d6", "1d20+5", etc.
|
||||
diceRegex := regexp.MustCompile(`^(\d+)d(\d+)(?:([+-])(\d+))?$`)
|
||||
matches := diceRegex.FindStringSubmatch(formula)
|
||||
|
||||
if matches == nil {
|
||||
return 0, fmt.Errorf("invalid dice formula: %s", formula)
|
||||
}
|
||||
|
||||
// Parse number of dice
|
||||
numDice, err := strconv.Atoi(matches[1])
|
||||
if err != nil || numDice < 1 {
|
||||
return 0, fmt.Errorf("invalid number of dice")
|
||||
}
|
||||
if numDice > 100 {
|
||||
return 0, fmt.Errorf("too many dice (max 100)")
|
||||
}
|
||||
|
||||
// Parse number of sides
|
||||
sides, err := strconv.Atoi(matches[2])
|
||||
if err != nil || sides < 1 {
|
||||
return 0, fmt.Errorf("invalid number of sides")
|
||||
}
|
||||
if sides > 1000 {
|
||||
return 0, fmt.Errorf("too many sides (max 1000)")
|
||||
}
|
||||
|
||||
// Roll the dice
|
||||
total := 0
|
||||
for i := 0; i < numDice; i++ {
|
||||
roll := p.rand.Intn(sides) + 1
|
||||
total += roll
|
||||
}
|
||||
|
||||
// Apply modifier if present
|
||||
if len(matches) > 3 && matches[3] != "" {
|
||||
modifier, err := strconv.Atoi(matches[4])
|
||||
if err != nil {
|
||||
return 0, fmt.Errorf("invalid modifier")
|
||||
}
|
||||
|
||||
if matches[3] == "+" {
|
||||
total += modifier
|
||||
} else if matches[3] == "-" {
|
||||
total -= modifier
|
||||
}
|
||||
}
|
||||
|
||||
return total, nil
|
||||
}
|
40
internal/plugin/fun/loquito.go
Normal file
40
internal/plugin/fun/loquito.go
Normal file
|
@ -0,0 +1,40 @@
|
|||
package fun
|
||||
|
||||
import (
|
||||
"strings"
|
||||
|
||||
"git.nakama.town/fmartingr/butterrobot/internal/model"
|
||||
"git.nakama.town/fmartingr/butterrobot/internal/plugin"
|
||||
)
|
||||
|
||||
// LoquitoPlugin replies with "Loquito tu." when someone says "lo quito"
|
||||
type LoquitoPlugin struct {
|
||||
plugin.BasePlugin
|
||||
}
|
||||
|
||||
// NewLoquito creates a new LoquitoPlugin instance
|
||||
func NewLoquito() *LoquitoPlugin {
|
||||
return &LoquitoPlugin{
|
||||
BasePlugin: plugin.BasePlugin{
|
||||
ID: "fun.loquito",
|
||||
Name: "Loquito Reply",
|
||||
Help: "Replies with 'Loquito tu.' when someone says 'lo quito'",
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
// OnMessage handles incoming messages
|
||||
func (p *LoquitoPlugin) OnMessage(msg *model.Message, config map[string]interface{}) []*model.Message {
|
||||
if !strings.Contains(strings.ToLower(msg.Text), "lo quito") {
|
||||
return nil
|
||||
}
|
||||
|
||||
response := &model.Message{
|
||||
Text: "Loquito tu.",
|
||||
Chat: msg.Chat,
|
||||
ReplyTo: msg.ID,
|
||||
Channel: msg.Channel,
|
||||
}
|
||||
|
||||
return []*model.Message{response}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue