mirror of
https://github.com/awfufu/go-hurobot.git
synced 2026-03-01 13:39:42 +08:00
199 lines
3.7 KiB
Go
199 lines
3.7 KiB
Go
package cmds
|
|
|
|
import (
|
|
"strconv"
|
|
"strings"
|
|
|
|
"github.com/google/shlex"
|
|
|
|
"go-hurobot/qbot"
|
|
)
|
|
|
|
var maxCommandLength int = 0
|
|
|
|
type ArgsList struct {
|
|
Contents []string
|
|
Types []qbot.MsgType
|
|
Size int
|
|
}
|
|
|
|
type CmdHandler func(*qbot.Client, *qbot.Message, *ArgsList)
|
|
|
|
var cmdMap map[string]CmdHandler
|
|
|
|
func init() {
|
|
cmdMap = map[string]CmdHandler{
|
|
"echo": cmd_echo,
|
|
"specialtitle": cmd_specialtitle,
|
|
"psql": cmd_psql,
|
|
"group": cmd_group,
|
|
"delete": cmd_delete,
|
|
"llm": cmd_llm,
|
|
"callme": cmd_callme,
|
|
"debug": cmd_debug,
|
|
"essence": cmd_essence,
|
|
"draw": cmd_draw,
|
|
"fx": cmd_er,
|
|
"stock": cmd_stock,
|
|
"crypto": cmd_crypto,
|
|
"event": cmd_event,
|
|
"sh": cmd_sh,
|
|
"rps": cmd_rps,
|
|
"dice": cmd_dice,
|
|
"memberinfo": cmd_memberinfo,
|
|
"info": cmd_info,
|
|
}
|
|
|
|
for key := range cmdMap {
|
|
if len(key) > maxCommandLength {
|
|
maxCommandLength = len(key)
|
|
}
|
|
}
|
|
}
|
|
|
|
func HandleCommand(c *qbot.Client, msg *qbot.Message) bool {
|
|
skip := 0
|
|
if len(msg.Array) == 0 {
|
|
return false
|
|
}
|
|
if msg.Array[0].Type == qbot.Reply {
|
|
skip++
|
|
if len(msg.Array) > 1 && msg.Array[1].Type == qbot.At {
|
|
skip++
|
|
}
|
|
} else if msg.Array[0].Type == qbot.At {
|
|
skip++
|
|
}
|
|
|
|
var raw string
|
|
if skip != 0 {
|
|
if p := findNthClosingBracket(msg.Raw, skip); p != len(msg.Raw) {
|
|
raw = msg.Raw
|
|
msg.Raw = msg.Raw[p:]
|
|
} else {
|
|
return false
|
|
}
|
|
}
|
|
handler := findCommand(getCommandName(msg.Raw))
|
|
if handler != nil {
|
|
if args := splitArguments(msg, skip); args != nil {
|
|
handler(c, msg, args)
|
|
}
|
|
}
|
|
if raw != "" {
|
|
msg.Raw = raw
|
|
}
|
|
return handler != nil
|
|
}
|
|
|
|
func splitArguments(msg *qbot.Message, skip int) *ArgsList {
|
|
result := &ArgsList{
|
|
Contents: make([]string, 0, 20),
|
|
Types: make([]qbot.MsgType, 0, 20),
|
|
Size: 0,
|
|
}
|
|
|
|
if skip < 0 {
|
|
skip = 0
|
|
}
|
|
|
|
if skip >= len(msg.Array) {
|
|
return result
|
|
}
|
|
|
|
for _, item := range msg.Array[skip:] {
|
|
if item.Type == qbot.Text {
|
|
texts, err := shlex.Split(item.Content)
|
|
if err != nil {
|
|
return nil
|
|
}
|
|
result.Contents = append(result.Contents, texts...)
|
|
result.Types = appendRepeatedValues(result.Types, qbot.Text, len(texts))
|
|
result.Size += len(texts)
|
|
} else {
|
|
result.Contents = append(result.Contents, item.Content)
|
|
result.Types = append(result.Types, item.Type)
|
|
result.Size++
|
|
}
|
|
}
|
|
return result
|
|
}
|
|
|
|
func findNthClosingBracket(s string, n int) int {
|
|
count := 0
|
|
for i, char := range s {
|
|
if char == ']' {
|
|
count++
|
|
if count == n {
|
|
i++
|
|
for i < len(s) && s[i] == ' ' {
|
|
i++
|
|
}
|
|
return i
|
|
}
|
|
}
|
|
}
|
|
return 0
|
|
}
|
|
|
|
func findCommand(cmd string) CmdHandler {
|
|
if cmd == "" {
|
|
return nil
|
|
}
|
|
return cmdMap[cmd]
|
|
}
|
|
|
|
func getCommandName(s string) string {
|
|
sliced := false
|
|
if len(s) > maxCommandLength+1 {
|
|
s = s[:maxCommandLength+1]
|
|
sliced = true
|
|
}
|
|
if i := strings.IndexAny(s, " \n"); i != -1 {
|
|
return s[:i]
|
|
}
|
|
if sliced {
|
|
return ""
|
|
}
|
|
return s
|
|
}
|
|
|
|
func decodeSpecialChars(raw string) string {
|
|
replacer := strings.NewReplacer(
|
|
"[", "[",
|
|
"]", "]",
|
|
"&", "&",
|
|
"<", "<",
|
|
">", ">",
|
|
)
|
|
return replacer.Replace(raw)
|
|
}
|
|
|
|
func encodeSpecialChars(raw string) string {
|
|
replacer := strings.NewReplacer(
|
|
"[", "[",
|
|
"]", "]",
|
|
"&", "&",
|
|
"<", "<",
|
|
">", ">",
|
|
)
|
|
return replacer.Replace(raw)
|
|
}
|
|
|
|
func str2uin64(s string) uint64 {
|
|
value, err := strconv.ParseUint(s, 10, 64)
|
|
if err != nil {
|
|
return 0
|
|
}
|
|
return value
|
|
}
|
|
|
|
func appendRepeatedValues[T any](slice []T, value T, count int) []T {
|
|
newSlice := make([]T, len(slice)+count)
|
|
copy(newSlice, slice)
|
|
for i := len(slice); i < len(newSlice); i++ {
|
|
newSlice[i] = value
|
|
}
|
|
return newSlice
|
|
}
|