mirror of
https://github.com/awfufu/go-hurobot.git
synced 2026-03-01 13:39:42 +08:00
feat: add command calc
This commit is contained in:
1
go.mod
1
go.mod
@@ -3,6 +3,7 @@ module github.com/awfufu/go-hurobot
|
||||
go 1.25.5
|
||||
|
||||
require (
|
||||
github.com/Knetic/govaluate v3.0.0+incompatible
|
||||
github.com/awfufu/qbot v0.2.2
|
||||
github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510
|
||||
gopkg.in/yaml.v3 v3.0.1
|
||||
|
||||
2
go.sum
2
go.sum
@@ -1,3 +1,5 @@
|
||||
github.com/Knetic/govaluate v3.0.0+incompatible h1:7o6+MAPhYTCF0+fdvoz1xDedhRb4f6s9Tn1Tt7/WTEg=
|
||||
github.com/Knetic/govaluate v3.0.0+incompatible/go.mod h1:r7JcOSlj0wfOMncg0iLm8Leh48TZaKVeNIfJntJ2wa0=
|
||||
github.com/awfufu/qbot v0.2.2 h1:rl7+j6JNjGzjjO5AHNqRXdM09Gwc+mQGsgBerJYVfVg=
|
||||
github.com/awfufu/qbot v0.2.2/go.mod h1:t6pYm54N7/YrxoMYFerZe2qx0t505iPeQQpTJvTNY+8=
|
||||
github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 h1:El6M4kTTCOh6aBiKaUGG7oYTSPP8MxqL4YI3kZKwcP4=
|
||||
|
||||
116
internal/cmds/calc.go
Normal file
116
internal/cmds/calc.go
Normal file
@@ -0,0 +1,116 @@
|
||||
package cmds
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"math"
|
||||
|
||||
"github.com/Knetic/govaluate"
|
||||
"github.com/awfufu/qbot"
|
||||
)
|
||||
|
||||
const calcHelpMsg string = `Calculates the result of a mathematical expression.
|
||||
Usage: /calc -l|<expression>
|
||||
Options:
|
||||
-l List supported functions
|
||||
Example: /calc 1+1`
|
||||
|
||||
var calcCommand *Command = &Command{
|
||||
Name: "calc",
|
||||
HelpMsg: calcHelpMsg,
|
||||
Permission: getCmdPermLevel("calc"),
|
||||
NeedRawMsg: false,
|
||||
MinArgs: 2,
|
||||
Exec: calcExec,
|
||||
}
|
||||
|
||||
func unaryMathOp(op func(float64) float64) func(args ...any) (any, error) {
|
||||
return func(args ...any) (any, error) {
|
||||
if len(args) != 1 {
|
||||
return nil, fmt.Errorf("expected 1 argument")
|
||||
}
|
||||
val, ok := args[0].(float64)
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("argument must be a number")
|
||||
}
|
||||
return op(val), nil
|
||||
}
|
||||
}
|
||||
|
||||
func binaryMathOp(op func(float64, float64) float64) func(args ...any) (any, error) {
|
||||
return func(args ...any) (any, error) {
|
||||
if len(args) != 2 {
|
||||
return nil, fmt.Errorf("expected 2 arguments")
|
||||
}
|
||||
val1, ok1 := args[0].(float64)
|
||||
val2, ok2 := args[1].(float64)
|
||||
if !ok1 || !ok2 {
|
||||
return nil, fmt.Errorf("arguments must be numbers")
|
||||
}
|
||||
return op(val1, val2), nil
|
||||
}
|
||||
}
|
||||
|
||||
var calcFunctions = map[string]govaluate.ExpressionFunction{
|
||||
"sin": unaryMathOp(math.Sin),
|
||||
"cos": unaryMathOp(math.Cos),
|
||||
"tan": unaryMathOp(math.Tan),
|
||||
"asin": unaryMathOp(math.Asin),
|
||||
"acos": unaryMathOp(math.Acos),
|
||||
"atan": unaryMathOp(math.Atan),
|
||||
"sqrt": unaryMathOp(math.Sqrt),
|
||||
"cbrt": unaryMathOp(math.Cbrt),
|
||||
"abs": unaryMathOp(math.Abs),
|
||||
"ceil": unaryMathOp(math.Ceil),
|
||||
"floor": unaryMathOp(math.Floor),
|
||||
"round": unaryMathOp(math.Round),
|
||||
"ln": unaryMathOp(math.Log),
|
||||
"log2": unaryMathOp(math.Log2),
|
||||
"log10": unaryMathOp(math.Log10),
|
||||
"exp": unaryMathOp(math.Exp),
|
||||
"pow": binaryMathOp(math.Pow),
|
||||
"max": binaryMathOp(math.Max),
|
||||
"min": binaryMathOp(math.Min),
|
||||
}
|
||||
|
||||
func calcExec(b *qbot.Sender, msg *qbot.Message) {
|
||||
exprString := ""
|
||||
for _, item := range msg.Array[1:] {
|
||||
if item.Type() == qbot.TextType {
|
||||
exprString += item.Text()
|
||||
} else {
|
||||
b.SendGroupMsg(msg.GroupID, "invalid expression")
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
if exprString == "-l" {
|
||||
var functionsList string
|
||||
for k := range calcFunctions {
|
||||
functionsList += k + ", "
|
||||
}
|
||||
functionsList = functionsList[:len(functionsList)-2]
|
||||
b.SendGroupMsg(msg.GroupID, "supported functions: "+functionsList)
|
||||
return
|
||||
}
|
||||
|
||||
expression, err := govaluate.NewEvaluableExpressionWithFunctions(exprString, calcFunctions)
|
||||
if err != nil {
|
||||
b.SendGroupMsg(msg.GroupID, fmt.Sprintf("%v", err))
|
||||
return
|
||||
}
|
||||
|
||||
result, err := expression.Evaluate(map[string]any{
|
||||
"pi": math.Pi,
|
||||
"PI": math.Pi,
|
||||
"π": math.Pi,
|
||||
"e": math.E,
|
||||
"E": math.E,
|
||||
})
|
||||
|
||||
if err != nil {
|
||||
b.SendGroupMsg(msg.GroupID, fmt.Sprintf("%v", err))
|
||||
return
|
||||
}
|
||||
|
||||
b.SendGroupMsg(msg.GroupID, fmt.Sprintf("%v", result))
|
||||
}
|
||||
@@ -39,6 +39,7 @@ func init() {
|
||||
"sh": shCommand,
|
||||
"specialtitle": specialtitleCommand,
|
||||
"which": whichCommand,
|
||||
"calc": calcCommand,
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user