mirror of
https://github.com/diamondburned/arikawa.git
synced 2024-09-27 20:58:50 +00:00
Bot: Added a Prefixer API which breaks the old Prefix string API
This commit is contained in:
parent
58f0feb143
commit
09ae9fbb07
|
@ -18,7 +18,7 @@ func main() {
|
||||||
commands := &Bot{}
|
commands := &Bot{}
|
||||||
|
|
||||||
wait, err := bot.Start(token, commands, func(ctx *bot.Context) error {
|
wait, err := bot.Start(token, commands, func(ctx *bot.Context) error {
|
||||||
ctx.Prefix = "!"
|
ctx.HasPrefix = bot.NewPrefix("!", "~")
|
||||||
|
|
||||||
// Subcommand demo, but this can be in another package.
|
// Subcommand demo, but this can be in another package.
|
||||||
ctx.MustRegisterSubcommand(&Debug{})
|
ctx.MustRegisterSubcommand(&Debug{})
|
||||||
|
|
|
@ -29,8 +29,6 @@ func main() {
|
||||||
log.Fatalln("Failed to connect:", err)
|
log.Fatalln("Failed to connect:", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
defer s.Close()
|
|
||||||
|
|
||||||
u, err := s.Me()
|
u, err := s.Me()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatalln("Failed to get myself:", err)
|
log.Fatalln("Failed to get myself:", err)
|
||||||
|
@ -38,7 +36,7 @@ func main() {
|
||||||
|
|
||||||
log.Println("Started as", u.Username)
|
log.Println("Started as", u.Username)
|
||||||
|
|
||||||
// Block until a fatal error or SIGINT.
|
// Block until a fatal error or SIGINT. Wait also calls Close().
|
||||||
if err := s.Wait(); err != nil {
|
if err := s.Wait(); err != nil {
|
||||||
log.Fatalln("Gateway fatal error:", err)
|
log.Fatalln("Gateway fatal error:", err)
|
||||||
}
|
}
|
||||||
|
|
|
@ -39,8 +39,6 @@ func main() {
|
||||||
log.Fatalln("Failed to connect:", err)
|
log.Fatalln("Failed to connect:", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
defer s.Close()
|
|
||||||
|
|
||||||
u, err := s.Me()
|
u, err := s.Me()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatalln("Failed to get myself:", err)
|
log.Fatalln("Failed to get myself:", err)
|
||||||
|
@ -48,7 +46,7 @@ func main() {
|
||||||
|
|
||||||
log.Println("Started as", u.Username)
|
log.Println("Started as", u.Username)
|
||||||
|
|
||||||
// Block until a fatal error or SIGINT.
|
// Block until a fatal error or SIGINT. Wait also calls Close().
|
||||||
if err := s.Wait(); err != nil {
|
if err := s.Wait(); err != nil {
|
||||||
log.Fatalln("Gateway fatal error:", err)
|
log.Fatalln("Gateway fatal error:", err)
|
||||||
}
|
}
|
||||||
|
|
30
bot/ctx.go
30
bot/ctx.go
|
@ -12,6 +12,23 @@ import (
|
||||||
"github.com/pkg/errors"
|
"github.com/pkg/errors"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// Prefixer checks a message if it starts with the desired prefix. By default,
|
||||||
|
// NewPrefix() is used.
|
||||||
|
type Prefixer func(*gateway.MessageCreateEvent) (prefix string, ok bool)
|
||||||
|
|
||||||
|
// NewPrefix creates a simple prefix checker using strings. As the default
|
||||||
|
// prefix is "!", the function is called as NewPrefix("!").
|
||||||
|
func NewPrefix(prefixes ...string) Prefixer {
|
||||||
|
return func(msg *gateway.MessageCreateEvent) (string, bool) {
|
||||||
|
for _, prefix := range prefixes {
|
||||||
|
if strings.HasPrefix(msg.Content, prefix) {
|
||||||
|
return prefix, true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return "", false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// TODO: add variadic arguments
|
// TODO: add variadic arguments
|
||||||
|
|
||||||
// Context is the bot state for commands and subcommands.
|
// Context is the bot state for commands and subcommands.
|
||||||
|
@ -56,8 +73,9 @@ type Context struct {
|
||||||
// Descriptive help body
|
// Descriptive help body
|
||||||
Description string
|
Description string
|
||||||
|
|
||||||
// The prefix for commands
|
// Called to check a message's prefix. The default prefix is "!". Refer to
|
||||||
Prefix string
|
// NewPrefix().
|
||||||
|
HasPrefix Prefixer
|
||||||
|
|
||||||
// FormatError formats any errors returned by anything, including the method
|
// FormatError formats any errors returned by anything, including the method
|
||||||
// commands or the reflect functions. This also includes invalid usage
|
// commands or the reflect functions. This also includes invalid usage
|
||||||
|
@ -152,7 +170,7 @@ func New(s *state.State, cmd interface{}) (*Context, error) {
|
||||||
ctx := &Context{
|
ctx := &Context{
|
||||||
Subcommand: c,
|
Subcommand: c,
|
||||||
State: s,
|
State: s,
|
||||||
Prefix: "~",
|
HasPrefix: NewPrefix("~"),
|
||||||
FormatError: func(err error) string {
|
FormatError: func(err error) string {
|
||||||
// Escape all pings, including @everyone.
|
// Escape all pings, including @everyone.
|
||||||
return strings.Replace(err.Error(), "@", "@\u200b", -1)
|
return strings.Replace(err.Error(), "@", "@\u200b", -1)
|
||||||
|
@ -176,6 +194,8 @@ func (ctx *Context) Wait() error {
|
||||||
return ctx.Session.Wait()
|
return ctx.Session.Wait()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Subcommands returns the slice of subcommands. To add subcommands, use
|
||||||
|
// RegisterSubcommand().
|
||||||
func (ctx *Context) Subcommands() []*Subcommand {
|
func (ctx *Context) Subcommands() []*Subcommand {
|
||||||
// Getter is not useless, refer to the struct doc for reason.
|
// Getter is not useless, refer to the struct doc for reason.
|
||||||
return ctx.subcommands
|
return ctx.subcommands
|
||||||
|
@ -348,7 +368,7 @@ func (ctx *Context) help(hideAdmin bool) string {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
help.WriteString(indent + ctx.Prefix + cmd.Command)
|
help.WriteString(indent + cmd.Command)
|
||||||
|
|
||||||
switch {
|
switch {
|
||||||
case len(cmd.Usage()) > 0:
|
case len(cmd.Usage()) > 0:
|
||||||
|
@ -364,7 +384,7 @@ func (ctx *Context) help(hideAdmin bool) string {
|
||||||
var subcommands = ctx.Subcommands()
|
var subcommands = ctx.Subcommands()
|
||||||
|
|
||||||
for _, sub := range subcommands {
|
for _, sub := range subcommands {
|
||||||
if help := sub.Help(ctx.Prefix, indent, hideAdmin); help != "" {
|
if help := sub.Help(indent, hideAdmin); help != "" {
|
||||||
subHelp.WriteString(help)
|
subHelp.WriteString(help)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -114,13 +114,13 @@ func (ctx *Context) callCmd(ev interface{}) error {
|
||||||
|
|
||||||
func (ctx *Context) callMessageCreate(mc *gateway.MessageCreateEvent) error {
|
func (ctx *Context) callMessageCreate(mc *gateway.MessageCreateEvent) error {
|
||||||
// check if prefix
|
// check if prefix
|
||||||
if !strings.HasPrefix(mc.Content, ctx.Prefix) {
|
pf, ok := ctx.HasPrefix(mc)
|
||||||
// not a command, ignore
|
if !ok {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// trim the prefix before splitting, this way multi-words prefices work
|
// trim the prefix before splitting, this way multi-words prefices work
|
||||||
content := mc.Content[len(ctx.Prefix):]
|
content := mc.Content[len(pf):]
|
||||||
|
|
||||||
if content == "" {
|
if content == "" {
|
||||||
return nil // just the prefix only
|
return nil // just the prefix only
|
||||||
|
@ -197,7 +197,6 @@ func (ctx *Context) callMessageCreate(mc *gateway.MessageCreateEvent) error {
|
||||||
return &ErrUnknownCommand{
|
return &ErrUnknownCommand{
|
||||||
Command: args[1],
|
Command: args[1],
|
||||||
Parent: args[0],
|
Parent: args[0],
|
||||||
Prefix: ctx.Prefix,
|
|
||||||
ctx: s.Commands,
|
ctx: s.Commands,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -213,7 +212,6 @@ func (ctx *Context) callMessageCreate(mc *gateway.MessageCreateEvent) error {
|
||||||
|
|
||||||
return &ErrUnknownCommand{
|
return &ErrUnknownCommand{
|
||||||
Command: args[0],
|
Command: args[0],
|
||||||
Prefix: ctx.Prefix,
|
|
||||||
ctx: ctx.Commands,
|
ctx: ctx.Commands,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -293,7 +291,6 @@ func (ctx *Context) callMessageCreate(mc *gateway.MessageCreateEvent) error {
|
||||||
|
|
||||||
return &ErrInvalidUsage{
|
return &ErrInvalidUsage{
|
||||||
Args: args,
|
Args: args,
|
||||||
Prefix: ctx.Prefix,
|
|
||||||
Index: len(args) - 1,
|
Index: len(args) - 1,
|
||||||
Err: err,
|
Err: err,
|
||||||
Ctx: cmd,
|
Ctx: cmd,
|
||||||
|
@ -307,7 +304,6 @@ func (ctx *Context) callMessageCreate(mc *gateway.MessageCreateEvent) error {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return &ErrInvalidUsage{
|
return &ErrInvalidUsage{
|
||||||
Args: args,
|
Args: args,
|
||||||
Prefix: ctx.Prefix,
|
|
||||||
Index: i,
|
Index: i,
|
||||||
Err: err.Error(),
|
Err: err.Error(),
|
||||||
Ctx: cmd,
|
Ctx: cmd,
|
||||||
|
|
17
bot/error.go
17
bot/error.go
|
@ -8,8 +8,6 @@ type ErrUnknownCommand struct {
|
||||||
Command string
|
Command string
|
||||||
Parent string
|
Parent string
|
||||||
|
|
||||||
Prefix string
|
|
||||||
|
|
||||||
// TODO: list available commands?
|
// TODO: list available commands?
|
||||||
// Here, as a reminder
|
// Here, as a reminder
|
||||||
ctx []*CommandContext
|
ctx []*CommandContext
|
||||||
|
@ -20,7 +18,7 @@ func (err *ErrUnknownCommand) Error() string {
|
||||||
}
|
}
|
||||||
|
|
||||||
var UnknownCommandString = func(err *ErrUnknownCommand) string {
|
var UnknownCommandString = func(err *ErrUnknownCommand) string {
|
||||||
var header = "Unknown command: " + err.Prefix
|
var header = "Unknown command: "
|
||||||
if err.Parent != "" {
|
if err.Parent != "" {
|
||||||
header += err.Parent + " " + err.Command
|
header += err.Parent + " " + err.Command
|
||||||
} else {
|
} else {
|
||||||
|
@ -32,8 +30,6 @@ var UnknownCommandString = func(err *ErrUnknownCommand) string {
|
||||||
|
|
||||||
type ErrInvalidUsage struct {
|
type ErrInvalidUsage struct {
|
||||||
Args []string
|
Args []string
|
||||||
Prefix string
|
|
||||||
|
|
||||||
Index int
|
Index int
|
||||||
Err string
|
Err string
|
||||||
|
|
||||||
|
@ -55,16 +51,13 @@ var InvalidUsageString = func(err *ErrInvalidUsage) string {
|
||||||
return "Missing arguments. Refer to help."
|
return "Missing arguments. Refer to help."
|
||||||
}
|
}
|
||||||
|
|
||||||
body := "Invalid usage at " + err.Prefix
|
body := "Invalid usage at " +
|
||||||
|
|
||||||
// Write the first part
|
// Write the first part
|
||||||
body += strings.Join(err.Args[:err.Index], " ")
|
strings.Join(err.Args[:err.Index], " ") +
|
||||||
|
|
||||||
// Write the wrong part
|
// Write the wrong part
|
||||||
body += " __" + err.Args[err.Index] + "__ "
|
" __" + err.Args[err.Index] + "__ " +
|
||||||
|
|
||||||
// Write the last part
|
// Write the last part
|
||||||
body += strings.Join(err.Args[err.Index+1:], " ")
|
strings.Join(err.Args[err.Index+1:], " ")
|
||||||
|
|
||||||
if err.Err != "" {
|
if err.Err != "" {
|
||||||
body += "\nError: " + err.Err
|
body += "\nError: " + err.Err
|
||||||
|
|
|
@ -173,7 +173,7 @@ func (sub *Subcommand) ChangeCommandInfo(methodName, cmd, desc string) bool {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
func (sub *Subcommand) Help(prefix, indent string, hideAdmin bool) string {
|
func (sub *Subcommand) Help(indent string, hideAdmin bool) string {
|
||||||
if sub.Flag.Is(AdminOnly) && hideAdmin {
|
if sub.Flag.Is(AdminOnly) && hideAdmin {
|
||||||
return ""
|
return ""
|
||||||
}
|
}
|
||||||
|
@ -205,8 +205,7 @@ func (sub *Subcommand) Help(prefix, indent string, hideAdmin bool) string {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
commands += indent + indent +
|
commands += indent + indent + sub.Command + " " + cmd.Command
|
||||||
prefix + sub.Command + " " + cmd.Command
|
|
||||||
|
|
||||||
switch {
|
switch {
|
||||||
case len(cmd.Usage()) > 0:
|
case len(cmd.Usage()) > 0:
|
||||||
|
|
Loading…
Reference in a new issue