From 1585797b527e855b2dacb3020964e8940db4c17d Mon Sep 17 00:00:00 2001 From: Maximilian von Lindern <48887425+mavolin@users.noreply.github.com> Date: Thu, 30 Jul 2020 01:29:01 +0200 Subject: [PATCH] *: Linting and typo fixes (#134) * Linting and typo fixes * Linting and typo fixes * revert comma fix --- README.md | 12 +++---- _example/advanced_bot/bot.go | 10 +++--- _example/advanced_bot/debug.go | 8 ++--- api/api.go | 8 ++--- api/channel.go | 6 ++-- api/emoji.go | 4 +-- api/rate/rate.go | 8 ++--- api/send.go | 3 -- bot/arguments.go | 4 +-- bot/ctx.go | 23 ++++++------ bot/ctx_call.go | 4 +-- bot/ctx_plumb_test.go | 8 ++--- bot/ctx_test.go | 42 +++++++++++----------- bot/extras/arguments/mention_test.go | 14 ++++---- bot/extras/middlewares/middlewares_test.go | 2 +- bot/extras/shellwords/shellwords.go | 2 +- bot/subcommand.go | 12 ++----- discord/user.go | 4 +-- gateway/gateway.go | 31 ++++++++++------ gateway/op.go | 2 +- gateway/ready.go | 10 +++--- state/state.go | 4 +-- state/state_events.go | 2 +- utils/wsutil/conn.go | 6 ++-- utils/wsutil/op.go | 2 +- voice/README.md | 2 +- 26 files changed, 116 insertions(+), 117 deletions(-) diff --git a/README.md b/README.md index 477f3c3..fb0bf1f 100644 --- a/README.md +++ b/README.md @@ -3,7 +3,7 @@ [![Pipeline status](https://gitlab.com/diamondburned/arikawa/badges/master/pipeline.svg?style=flat-square)](https://gitlab.com/diamondburned/arikawa/pipelines ) [![ Coverage](https://gitlab.com/diamondburned/arikawa/badges/master/coverage.svg?style=flat-square)](https://gitlab.com/diamondburned/arikawa/commits/master ) [![ Report Card](https://goreportcard.com/badge/github.com/diamondburned/arikawa?style=flat-square )](https://goreportcard.com/report/github.com/diamondburned/arikawa) -[![Godoc Reference](https://img.shields.io/badge/godoc-reference-blue?style=flat-square )](https://godoc.org/github.com/diamondburned/arikawa ) +[![Godoc Reference](https://img.shields.io/badge/godoc-reference-blue?style=flat-square )](https://pkg.go.dev/github.com/diamondburned/arikawa ) [![ Examples](https://img.shields.io/badge/Example-__example%2F-blueviolet?style=flat-square )](https://github.com/diamondburned/arikawa/tree/master/_example ) [![Discord Gophers](https://img.shields.io/badge/Discord%20Gophers-%23arikawa-%237289da?style=flat-square)](https://discord.gg/7jSf85J ) [![ Hime Arikawa](https://img.shields.io/badge/Hime-Arikawa-ea75a2?style=flat-square )](https://hime-goto.fandom.com/wiki/Hime_Arikawa ) @@ -15,7 +15,7 @@ A Golang library for the Discord API. ### [Simple](https://github.com/diamondburned/arikawa/tree/master/_example/simple) Simple bot example without any state. All it does is logging messages sent into -the console. Run with `BOT_TOKEN="TOKEN" go run .` +the console. Run with `BOT_TOKEN="TOKEN" go run .`. ### [Undeleter](https://github.com/diamondburned/arikawa/tree/master/_example/undeleter) @@ -24,8 +24,8 @@ everything, including messages. It detects when someone deletes a message, logging the content into the console. This example demonstrates the PreHandler feature of this library. PreHandler -calls all handlers that are registered (separately from session), calling them -before the state is updated. +calls all handlers that are registered (separately from the session), calling +them before the state is updated. ### [Advanced Bot](https://github.com/diamondburned/arikawa/tree/master/_example/advanced_bot) @@ -34,7 +34,7 @@ that's built-in. The router turns exported struct methods into commands, its arguments into command arguments, and more. The library has a pretty detailed documentation available in [GoDoc -Reference](https://godoc.org/github.com/diamondburned/arikawa/bot). +Reference](https://pkg.go.dev/github.com/diamondburned/arikawa/bot). ## Comparison: Why not discordgo? @@ -66,7 +66,7 @@ things in the state, which is useful for keeping it updated. ## Testing The package includes integration tests that require `$BOT_TOKEN`. To run these -tests, do +tests, do: ```sh export BOT_TOKEN="" diff --git a/_example/advanced_bot/bot.go b/_example/advanced_bot/bot.go index f206c62..d161e28 100644 --- a/_example/advanced_bot/bot.go +++ b/_example/advanced_bot/bot.go @@ -26,22 +26,22 @@ func (bot *Bot) Setup(sub *bot.Subcommand) { } // Help prints the default help message. -func (bot *Bot) Help(m *gateway.MessageCreateEvent) (string, error) { +func (bot *Bot) Help(*gateway.MessageCreateEvent) (string, error) { return bot.Ctx.Help(), nil } // Add demonstrates the usage of typed arguments. Run it with "~add 1 2". -func (bot *Bot) Add(m *gateway.MessageCreateEvent, a, b int) (string, error) { +func (bot *Bot) Add(_ *gateway.MessageCreateEvent, a, b int) (string, error) { return fmt.Sprintf("%d + %d = %d", a, b, a+b), nil } // Ping is a simple ping example, perhaps the most simple you could make it. -func (bot *Bot) Ping(m *gateway.MessageCreateEvent) (string, error) { +func (bot *Bot) Ping(*gateway.MessageCreateEvent) (string, error) { return "Pong!", nil } // Say demonstrates how arguments.Flag could be used without the flag library. -func (bot *Bot) Say(m *gateway.MessageCreateEvent, f bot.RawArguments) (string, error) { +func (bot *Bot) Say(_ *gateway.MessageCreateEvent, f bot.RawArguments) (string, error) { if f != "" { return string(f), nil } @@ -95,7 +95,7 @@ func (bot *Bot) Repeat(m *gateway.MessageCreateEvent) (string, error) { // Embed is a simple embed creator. Its purpose is to demonstrate the usage of // the ParseContent interface, as well as using the stdlib flag package. -func (bot *Bot) Embed(m *gateway.MessageCreateEvent, f arguments.Flag) (*discord.Embed, error) { +func (bot *Bot) Embed(_ *gateway.MessageCreateEvent, f arguments.Flag) (*discord.Embed, error) { fs := arguments.NewFlagSet() var ( diff --git a/_example/advanced_bot/debug.go b/_example/advanced_bot/debug.go index 78c3c11..d53e529 100644 --- a/_example/advanced_bot/debug.go +++ b/_example/advanced_bot/debug.go @@ -27,7 +27,7 @@ func (d *Debug) Setup(sub *bot.Subcommand) { // Manually set the usage for each function. sub.ChangeCommandInfo("GOOS", "GOOS", "Prints the current operating system") - sub.ChangeCommandInfo("GC", "GC", "Triggers the garbage collecto") + sub.ChangeCommandInfo("GC", "GC", "Triggers the garbage collector") sub.ChangeCommandInfo("Goroutines", "", "Prints the current number of Goroutines") sub.Hide("Die") @@ -35,7 +35,7 @@ func (d *Debug) Setup(sub *bot.Subcommand) { } // ~go goroutines -func (d *Debug) Goroutines(m *gateway.MessageCreateEvent) (string, error) { +func (d *Debug) Goroutines(*gateway.MessageCreateEvent) (string, error) { return fmt.Sprintf( "goroutines: %d", runtime.NumGoroutine(), @@ -43,12 +43,12 @@ func (d *Debug) Goroutines(m *gateway.MessageCreateEvent) (string, error) { } // ~go GOOS -func (d *Debug) GOOS(m *gateway.MessageCreateEvent) (string, error) { +func (d *Debug) GOOS(*gateway.MessageCreateEvent) (string, error) { return strings.Title(runtime.GOOS), nil } // ~go GC -func (d *Debug) GC(m *gateway.MessageCreateEvent) (string, error) { +func (d *Debug) GC(*gateway.MessageCreateEvent) (string, error) { runtime.GC() return "Done.", nil } diff --git a/api/api.go b/api/api.go index 5ee0706..708ad0a 100644 --- a/api/api.go +++ b/api/api.go @@ -13,10 +13,10 @@ import ( var ( BaseEndpoint = "https://discord.com" - APIVersion = "6" - APIPath = "/api/v" + APIVersion + Version = "6" + Path = "/api/v" + Version - Endpoint = BaseEndpoint + APIPath + "/" + Endpoint = BaseEndpoint + Path + "/" EndpointGateway = Endpoint + "gateway" EndpointGatewayBot = EndpointGateway + "/bot" ) @@ -34,7 +34,7 @@ func NewClient(token string) *Client { func NewCustomClient(token string, httpClient *httputil.Client) *Client { ses := Session{ - Limiter: rate.NewLimiter(APIPath), + Limiter: rate.NewLimiter(Path), Token: token, UserAgent: UserAgent, } diff --git a/api/channel.go b/api/channel.go index 2a77d39..9d78b48 100644 --- a/api/channel.go +++ b/api/channel.go @@ -87,10 +87,10 @@ type MoveChannelData struct { // MoveChannel modifies the position of channels in the guild. // // Requires MANAGE_CHANNELS. -func (c *Client) MoveChannel(guildID discord.GuildID, datum []MoveChannelData) error { +func (c *Client) MoveChannel(guildID discord.GuildID, data []MoveChannelData) error { return c.FastRequest( "PATCH", - EndpointGuilds+guildID.String()+"/channels", httputil.WithJSONBody(datum), + EndpointGuilds+guildID.String()+"/channels", httputil.WithJSONBody(data), ) } @@ -193,7 +193,7 @@ func (c *Client) EditChannelPermission( // role in a channel. Only usable for guild channels. // // Requires the MANAGE_ROLES permission. -func (c *Client) DeleteChannelPermission(channelID, overwriteID discord.Snowflake) error { +func (c *Client) DeleteChannelPermission(channelID discord.ChannelID, overwriteID discord.Snowflake) error { return c.FastRequest( "DELETE", EndpointChannels+channelID.String()+"/permissions/"+overwriteID.String(), diff --git a/api/emoji.go b/api/emoji.go index 0ddac5b..66e8c48 100644 --- a/api/emoji.go +++ b/api/emoji.go @@ -18,8 +18,8 @@ func NewCustomEmoji(id discord.EmojiID, name string) Emoji { // Emojis returns a list of emoji objects for the given guild. func (c *Client) Emojis(guildID discord.GuildID) ([]discord.Emoji, error) { - var emjs []discord.Emoji - return emjs, c.RequestJSON(&emjs, "GET", EndpointGuilds+guildID.String()+"/emojis") + var e []discord.Emoji + return e, c.RequestJSON(&e, "GET", EndpointGuilds+guildID.String()+"/emojis") } // Emoji returns an emoji object for the given guild and emoji IDs. diff --git a/api/rate/rate.go b/api/rate/rate.go index 7e950bf..b446197 100644 --- a/api/rate/rate.go +++ b/api/rate/rate.go @@ -28,9 +28,8 @@ type Limiter struct { Prefix string - global *int64 // atomic guarded, unixnano - buckets sync.Map - globalRate time.Duration + global *int64 // atomic guarded, unixnano + buckets sync.Map } type CustomRateLimit struct { @@ -43,7 +42,6 @@ type bucket struct { custom *CustomRateLimit remaining uint64 - limit uint reset time.Time lastReset time.Time // only for custom @@ -102,7 +100,7 @@ func (l *Limiter) Acquire(ctx context.Context, path string) error { if b.remaining == 0 && b.reset.After(time.Now()) { // out of turns, gotta wait - sleep = b.reset.Sub(time.Now()) + sleep = time.Until(b.reset) } else { // maybe global rate limit has it now := time.Now() diff --git a/api/send.go b/api/send.go index 5ff0c5b..6fa0276 100644 --- a/api/send.go +++ b/api/send.go @@ -4,7 +4,6 @@ import ( "io" "mime/multipart" "strconv" - "strings" "github.com/pkg/errors" @@ -15,8 +14,6 @@ import ( const AttachmentSpoilerPrefix = "SPOILER_" -var quoteEscaper = strings.NewReplacer(`\`, `\\`, `"`, `\"`) - // AllowedMentions is a whitelist of mentions for a message. // https://discordapp.com/developers/docs/resources/channel#allowed-mentions-object // diff --git a/bot/arguments.go b/bot/arguments.go index 7a374aa..cb1fb51 100644 --- a/bot/arguments.go +++ b/bot/arguments.go @@ -115,7 +115,7 @@ var ShellwordsEscaper = strings.NewReplacer( var nilV = reflect.Value{} func newArgument(t reflect.Type, variadic bool) (*Argument, error) { - // Allow array types if varidic is true. + // Allow array types if variadic is true. if variadic && t.Kind() == reflect.Slice { t = t.Elem() } @@ -128,7 +128,7 @@ func newArgument(t reflect.Type, variadic bool) (*Argument, error) { ptr = true } - // This shouldn't be varidic. + // This shouldn't be variadic. if !variadic && typeI.Implements(typeICusP) { mt, _ := typeI.MethodByName("CustomParse") diff --git a/bot/ctx.go b/bot/ctx.go index 0e03fdd..0e8b9cf 100644 --- a/bot/ctx.go +++ b/bot/ctx.go @@ -7,11 +7,12 @@ import ( "strings" "sync" + "github.com/pkg/errors" + "github.com/diamondburned/arikawa/api" "github.com/diamondburned/arikawa/bot/extras/shellwords" "github.com/diamondburned/arikawa/gateway" "github.com/diamondburned/arikawa/state" - "github.com/pkg/errors" ) // Prefixer checks a message if it starts with the desired prefix. By default, @@ -181,7 +182,7 @@ func Start( // Wait blocks until SIGINT. func Wait() { - sigs := make(chan os.Signal) + sigs := make(chan os.Signal, 1) signal.Notify(sigs, os.Interrupt) <-sigs } @@ -249,13 +250,13 @@ func (ctx *Context) Subcommands() []*Subcommand { // // Find a command from a subcommand: // cmd = ctx.FindMethod("Starboard", "Reset") // -func (ctx *Context) FindCommand(structname, methodname string) *MethodContext { - if structname == "" { - return ctx.Subcommand.FindCommand(methodname) +func (ctx *Context) FindCommand(structName, methodName string) *MethodContext { + if structName == "" { + return ctx.Subcommand.FindCommand(methodName) } for _, sub := range ctx.subcommands { - if sub.StructName == structname { - return sub.FindCommand(methodname) + if sub.StructName == structName { + return sub.FindCommand(methodName) } } return nil @@ -268,8 +269,8 @@ func (ctx *Context) MustRegisterSubcommand(cmd interface{}) *Subcommand { return ctx.MustRegisterSubcommandCustom(cmd, "") } -// MustReisterSubcommandCustom works similarly to MustRegisterSubcommand, but -// takeks an extra argument for a command name override. +// MustRegisterSubcommandCustom works similarly to MustRegisterSubcommand, but +// takes an extra argument for a command name override. func (ctx *Context) MustRegisterSubcommandCustom(cmd interface{}, name string) *Subcommand { s, err := ctx.RegisterSubcommandCustom(cmd, name) if err != nil { @@ -314,8 +315,8 @@ func (ctx *Context) RegisterSubcommandCustom(cmd interface{}, name string) (*Sub return s, nil } -// Start adds itself into the discordgo Session handlers. This needs to be run. -// The returned function is a delete function, which removes itself from the +// Start adds itself into the session handlers. This needs to be run. The +// returned function is a delete function, which removes itself from the // Session handlers. func (ctx *Context) Start() func() { return ctx.State.AddHandler(func(v interface{}) { diff --git a/bot/ctx_call.go b/bot/ctx_call.go index 71bd90f..120d747 100644 --- a/bot/ctx_call.go +++ b/bot/ctx_call.go @@ -117,7 +117,7 @@ func (ctx *Context) callMessageCreate(mc *gateway.MessageCreateEvent, value refl return nil } - // trim the prefix before splitting, this way multi-words prefices work + // trim the prefix before splitting, this way multi-words prefixes work content := mc.Content[len(pf):] if content == "" { @@ -226,7 +226,7 @@ func (ctx *Context) callMessageCreate(mc *gateway.MessageCreateEvent, value refl vars := make([]reflect.Value, 0, len(arguments)) // Parse the rest with variadic arguments. Go's reflect states that - // varidic parameters will automatically be copied, which is good. + // variadic parameters will automatically be copied, which is good. for i := 0; len(arguments) > 0; i++ { v, err := last.fn(arguments[0]) if err != nil { diff --git a/bot/ctx_plumb_test.go b/bot/ctx_plumb_test.go index 66bde42..363e201 100644 --- a/bot/ctx_plumb_test.go +++ b/bot/ctx_plumb_test.go @@ -30,11 +30,11 @@ func (h *hasPlumb) Plumber(_ *gateway.MessageCreateEvent, c RawArguments) error } func TestSubcommandPlumb(t *testing.T) { - var state = &state.State{ + var s = &state.State{ Store: state.NewDefaultStore(nil), } - c, err := New(state, &testc{}) + c, err := New(s, &testc{}) if err != nil { t.Fatal("Failed to create new context:", err) } @@ -78,11 +78,11 @@ func (h *onlyPlumb) Plumber(_ *gateway.MessageCreateEvent, c RawArguments) error } func TestSubcommandOnlyPlumb(t *testing.T) { - var state = &state.State{ + var s = &state.State{ Store: state.NewDefaultStore(nil), } - c, err := New(state, &testc{}) + c, err := New(s, &testc{}) if err != nil { t.Fatal("Failed to create new context:", err) } diff --git a/bot/ctx_test.go b/bot/ctx_test.go index 8284558..cc840e5 100644 --- a/bot/ctx_test.go +++ b/bot/ctx_test.go @@ -50,7 +50,7 @@ func (t *testc) Custom(_ *gateway.MessageCreateEvent, c *ArgumentParts) { func (t *testc) Variadic(_ *gateway.MessageCreateEvent, c ...*customParsed) { t.Return <- c[len(c)-1] } -func (t *testc) TrailCustom(_ *gateway.MessageCreateEvent, s string, c ArgumentParts) { +func (t *testc) TrailCustom(_ *gateway.MessageCreateEvent, _ string, c ArgumentParts) { t.Return <- c } func (t *testc) Content(_ *gateway.MessageCreateEvent, c RawArguments) { @@ -64,11 +64,11 @@ func (t *testc) OnTyping(*gateway.TypingStartEvent) { } func TestNewContext(t *testing.T) { - var state = &state.State{ + var s = &state.State{ Store: state.NewDefaultStore(nil), } - c, err := New(state, &testc{}) + c, err := New(s, &testc{}) if err != nil { t.Fatal("Failed to create new context:", err) } @@ -80,12 +80,12 @@ func TestNewContext(t *testing.T) { func TestContext(t *testing.T) { var given = &testc{} - var state = &state.State{ + var s = &state.State{ Store: state.NewDefaultStore(nil), Handler: handler.New(), } - s, err := NewSubcommand(given) + sub, err := NewSubcommand(given) if err != nil { t.Fatal("Failed to create subcommand:", err) } @@ -94,8 +94,8 @@ func TestContext(t *testing.T) { Name: "arikawa/bot test", Description: "Just a test.", - Subcommand: s, - State: state, + Subcommand: sub, + State: s, ParseArgs: DefaultArgsParser(), } @@ -105,11 +105,11 @@ func TestContext(t *testing.T) { } if given.Ctx == nil { - t.Fatal("given's Context field is nil") + t.Fatal("given'sub Context field is nil") } if given.Ctx.State.Store == nil { - t.Fatal("given's State is nil") + t.Fatal("given'sub State is nil") } }) @@ -167,11 +167,11 @@ func TestContext(t *testing.T) { ctx.HasPrefix = NewPrefix("~") var ( - strings = "hacka doll no. 3" + send = "hacka doll no. 3" expects = []string{"hacka", "doll", "no.", "3"} ) - if err := expect(ctx, given, expects, "~send "+strings); err.Error() != "oh no" { + if err := expect(ctx, given, expects, "~send "+send); err.Error() != "oh no" { t.Fatal("Unexpected error:", err) } }) @@ -355,26 +355,26 @@ func sendMsg(ctx *Context, given *testc, into interface{}, content string) (call } func BenchmarkConstructor(b *testing.B) { - var state = &state.State{ + var s = &state.State{ Store: state.NewDefaultStore(nil), } for i := 0; i < b.N; i++ { - _, _ = New(state, &testc{}) + _, _ = New(s, &testc{}) } } func BenchmarkCall(b *testing.B) { var given = &testc{} - var state = &state.State{ + var s = &state.State{ Store: state.NewDefaultStore(nil), } - s, _ := NewSubcommand(given) + sub, _ := NewSubcommand(given) var ctx = &Context{ - Subcommand: s, - State: state, + Subcommand: sub, + State: s, HasPrefix: NewPrefix("~"), ParseArgs: DefaultArgsParser(), } @@ -394,15 +394,15 @@ func BenchmarkCall(b *testing.B) { func BenchmarkHelp(b *testing.B) { var given = &testc{} - var state = &state.State{ + var s = &state.State{ Store: state.NewDefaultStore(nil), } - s, _ := NewSubcommand(given) + sub, _ := NewSubcommand(given) var ctx = &Context{ - Subcommand: s, - State: state, + Subcommand: sub, + State: s, HasPrefix: NewPrefix("~"), ParseArgs: DefaultArgsParser(), } diff --git a/bot/extras/arguments/mention_test.go b/bot/extras/arguments/mention_test.go index 59c80fb..4da8b88 100644 --- a/bot/extras/arguments/mention_test.go +++ b/bot/extras/arguments/mention_test.go @@ -2,18 +2,20 @@ package arguments import ( "testing" + + "github.com/diamondburned/arikawa/discord" ) func TestChannelMention(t *testing.T) { test := new(ChannelMention) str := "<#123123>" - id := 123123 + var id discord.ChannelID = 123123 if err := test.Parse(str); err != nil { t.Fatal("Expected", id, "error:", err) } - if id := test.ID(); id != id { + if actualID := test.ID(); actualID != id { t.Fatal("Expected", id, "got", id) } @@ -25,13 +27,13 @@ func TestChannelMention(t *testing.T) { func TestUserMention(t *testing.T) { test := new(UserMention) str := "<@123123>" - id := 123123 + var id discord.UserID = 123123 if err := test.Parse(str); err != nil { t.Fatal("Expected", id, "error:", err) } - if id := test.ID(); id != id { + if actualID := test.ID(); actualID != id { t.Fatal("Expected", id, "got", id) } @@ -43,13 +45,13 @@ func TestUserMention(t *testing.T) { func TestRoleMention(t *testing.T) { test := new(RoleMention) str := "<@&123123>" - id := 123123 + var id discord.RoleID = 123123 if err := test.Parse(str); err != nil { t.Fatal("Expected", id, "error:", err) } - if id := test.ID(); id != id { + if actualID := test.ID(); actualID != id { t.Fatal("Expected", id, "got", id) } diff --git a/bot/extras/middlewares/middlewares_test.go b/bot/extras/middlewares/middlewares_test.go index 454d68f..37bbb7f 100644 --- a/bot/extras/middlewares/middlewares_test.go +++ b/bot/extras/middlewares/middlewares_test.go @@ -172,7 +172,7 @@ func (s *mockStore) Guild(id discord.GuildID) (*discord.Guild, error) { }, nil } -func (s *mockStore) Member(guildID discord.GuildID, userID discord.UserID) (*discord.Member, error) { +func (s *mockStore) Member(_ discord.GuildID, userID discord.UserID) (*discord.Member, error) { return &discord.Member{ User: discord.User{ID: userID}, RoleIDs: []discord.RoleID{discord.RoleID(userID)}, diff --git a/bot/extras/shellwords/shellwords.go b/bot/extras/shellwords/shellwords.go index 7723a55..dc3b164 100644 --- a/bot/extras/shellwords/shellwords.go +++ b/bot/extras/shellwords/shellwords.go @@ -10,7 +10,7 @@ type ErrParse struct { } func Parse(line string) ([]string, error) { - args := []string{} + var args []string buf := "" var escaped, doubleQuoted, singleQuoted bool backtick := "" diff --git a/bot/subcommand.go b/bot/subcommand.go index 52ccc18..33bbb6c 100644 --- a/bot/subcommand.go +++ b/bot/subcommand.go @@ -4,29 +4,21 @@ import ( "reflect" "strings" - "github.com/diamondburned/arikawa/api" - "github.com/diamondburned/arikawa/discord" - "github.com/diamondburned/arikawa/gateway" "github.com/pkg/errors" + + "github.com/diamondburned/arikawa/gateway" ) var ( typeMessageCreate = reflect.TypeOf((*gateway.MessageCreateEvent)(nil)) typeMessageUpdate = reflect.TypeOf((*gateway.MessageUpdateEvent)(nil)) - typeString = reflect.TypeOf("") - typeEmbed = reflect.TypeOf((*discord.Embed)(nil)) - typeSend = reflect.TypeOf((*api.SendMessageData)(nil)) - - typeSubcmd = reflect.TypeOf((*Subcommand)(nil)) - typeIError = reflect.TypeOf((*error)(nil)).Elem() typeIManP = reflect.TypeOf((*ManualParser)(nil)).Elem() typeICusP = reflect.TypeOf((*CustomParser)(nil)).Elem() typeIParser = reflect.TypeOf((*Parser)(nil)).Elem() typeIUsager = reflect.TypeOf((*Usager)(nil)).Elem() typeSetupFn = methodType((*CanSetup)(nil), "Setup") - typeHelpFn = methodType((*CanHelp)(nil), "Help") ) func methodType(iface interface{}, name string) reflect.Type { diff --git a/discord/user.go b/discord/user.go index e7076af..6f3813c 100644 --- a/discord/user.go +++ b/discord/user.go @@ -64,8 +64,8 @@ type UserFlags uint32 const NoFlag UserFlags = 0 const ( - DiscordEmployee UserFlags = 1 << iota - DiscordPartner + Employee UserFlags = 1 << iota + Partner HypeSquadEvents BugHunterLvl1 _ diff --git a/gateway/gateway.go b/gateway/gateway.go index 7700708..222d83b 100644 --- a/gateway/gateway.go +++ b/gateway/gateway.go @@ -36,16 +36,16 @@ var ( ErrWSMaxTries = errors.New("max tries reached") ) -// GatewayBotData contains the GatewayURL as well as extra metadata on how to +// BotData contains the GatewayURL as well as extra metadata on how to // shard bots. -type GatewayBotData struct { +type BotData struct { URL string `json:"url"` Shards int `json:"shards,omitempty"` StartLimit *SessionStartLimit `json:"session_start_limit"` } // SessionStartLimit is the information on the current session start limit. It's -// used in GatewayBotData. +// used in BotData. type SessionStartLimit struct { Total int `json:"total"` Remaining int `json:"remaining"` @@ -54,7 +54,7 @@ type SessionStartLimit struct { // URL asks Discord for a Websocket URL to the Gateway. func URL() (string, error) { - var g GatewayBotData + var g BotData return g.URL, httputil.NewClient().RequestJSON( &g, "GET", @@ -64,8 +64,8 @@ func URL() (string, error) { // BotURL fetches the Gateway URL along with extra metadata. The token // passed in will NOT be prefixed with Bot. -func BotURL(token string) (*GatewayBotData, error) { - var g *GatewayBotData +func BotURL(token string) (*BotData, error) { + var g *BotData return g, httputil.NewClient().RequestJSON( &g, "GET", @@ -214,7 +214,7 @@ func (g *Gateway) Reconnect() { // ReconnectCtx attempts to reconnect until context expires. If context cannot // expire, then the gateway will try to reconnect forever. -func (g *Gateway) ReconnectCtx(ctx context.Context) error { +func (g *Gateway) ReconnectCtx(ctx context.Context) (err error) { wsutil.WSDebug("Reconnecting...") // Guarantee the gateway is already closed. Ignore its error, as we're @@ -222,18 +222,27 @@ func (g *Gateway) ReconnectCtx(ctx context.Context) error { g.Close() for i := 1; ; i++ { + select { + case <-ctx.Done(): + return err + default: + } + wsutil.WSDebug("Trying to dial, attempt", i) // Condition: err == ErrInvalidSession: // If the connection is rate limited (documented behavior): // https://discordapp.com/developers/docs/topics/gateway#rate-limiting - if err := g.OpenContext(ctx); err != nil { - return errors.Wrap(err, "failed to open gateway") + // make sure we don't overwrite our last error + if err = g.OpenContext(ctx); err != nil { + g.ErrorLog(err) + continue } wsutil.WSDebug("Started after attempt:", i) - return nil + + return } } @@ -246,7 +255,7 @@ func (g *Gateway) Open() error { return g.OpenContext(ctx) } -// OpenContext connects to the Websocket and authenticates it. Yuo should +// OpenContext connects to the Websocket and authenticates it. You should // usually use this function over Start(). The given context provides // cancellation and timeout. func (g *Gateway) OpenContext(ctx context.Context) error { diff --git a/gateway/op.go b/gateway/op.go index b9ee08d..2d6e0d6 100644 --- a/gateway/op.go +++ b/gateway/op.go @@ -84,7 +84,7 @@ func (g *Gateway) HandleOP(op *wsutil.OP) error { fn, ok := EventCreator[op.EventName] if !ok { return fmt.Errorf( - "Unknown event %s: %s", + "unknown event %s: %s", op.EventName, string(op.Data), ) } diff --git a/gateway/ready.go b/gateway/ready.go index d44af80..ae8f2e6 100644 --- a/gateway/ready.go +++ b/gateway/ready.go @@ -41,7 +41,7 @@ type UserSettings struct { DeveloperMode bool `json:"developer_mode"` DetectPlatformAccounts bool `json:"detect_platform_accounts"` StreamNotification bool `json:"stream_notification_enabled"` - AccessibilityDetection bool `json:"allow_accessbility_detection"` + AccessibilityDetection bool `json:"allow_accessibility_detection"` ContactSync bool `json:"contact_sync_enabled"` NativePhoneIntegration bool `json:"native_phone_integration_enabled"` @@ -71,10 +71,10 @@ type UserSettings struct { type UserGuildSettings struct { GuildID discord.GuildID `json:"guild_id"` - SupressEveryone bool `json:"suppress_everyone"` - SupressRoles bool `json:"suppress_roles"` - Muted bool `json:"muted"` - MobilePush bool `json:"mobile_push"` + SuppressEveryone bool `json:"suppress_everyone"` + SuppressRoles bool `json:"suppress_roles"` + Muted bool `json:"muted"` + MobilePush bool `json:"mobile_push"` MessageNotifications UserNotification `json:"message_notifications"` ChannelOverrides []SettingsChannelOverride `json:"channel_overrides"` diff --git a/state/state.go b/state/state.go index c7f7e60..8ea9c22 100644 --- a/state/state.go +++ b/state/state.go @@ -83,7 +83,7 @@ type State struct { // List of channels with few messages, so it doesn't bother hitting the API // again. fewMessages map[discord.ChannelID]struct{} - fewMutex sync.Mutex + fewMutex *sync.Mutex // unavailableGuilds is a set of discord.GuildIDs of guilds that became // unavailable when already connected to the gateway, i.e. sent in a @@ -129,7 +129,7 @@ func NewFromSession(s *session.Session, store Store) (*State, error) { Handler: handler.New(), StateLog: func(err error) {}, fewMessages: map[discord.ChannelID]struct{}{}, - fewMutex: sync.Mutex{}, + fewMutex: new(sync.Mutex), unavailableGuilds: moreatomic.NewGuildIDSet(), unreadyGuilds: moreatomic.NewGuildIDSet(), } diff --git a/state/state_events.go b/state/state_events.go index f638930..c58e72e 100644 --- a/state/state_events.go +++ b/state/state_events.go @@ -180,7 +180,7 @@ func (s *State) onEvent(iface interface{}) { case *gateway.MessageDeleteBulkEvent: for _, id := range ev.IDs { if err := s.Store.MessageRemove(ev.ChannelID, id); err != nil { - s.stateErr(err, "failed to delete bulk meessages in state") + s.stateErr(err, "failed to delete bulk messages in state") } } diff --git a/utils/wsutil/conn.go b/utils/wsutil/conn.go index 86b30ca..88f73a9 100644 --- a/utils/wsutil/conn.go +++ b/utils/wsutil/conn.go @@ -158,9 +158,9 @@ func (c *Conn) readLoop() { } func (c *Conn) writeLoop() { - // Closig c.writes would break the loop immediately. - for bytes := range c.writes { - c.errors <- c.Conn.WriteMessage(websocket.TextMessage, bytes) + // Closing c.writes would break the loop immediately. + for b := range c.writes { + c.errors <- c.Conn.WriteMessage(websocket.TextMessage, b) } // Quick deadline: diff --git a/utils/wsutil/op.go b/utils/wsutil/op.go index 510cef1..1de597d 100644 --- a/utils/wsutil/op.go +++ b/utils/wsutil/op.go @@ -54,7 +54,7 @@ func AssertEvent(ev Event, code OPCode, v interface{}) (*OP, error) { if op.Code != code { return op, fmt.Errorf( - "Unexpected OP Code: %d, expected %d (%s)", + "unexpected OP Code: %d, expected %d (%s)", op.Code, code, op.Data, ) } diff --git a/voice/README.md b/voice/README.md index bbdec8c..32a944c 100644 --- a/voice/README.md +++ b/voice/README.md @@ -27,7 +27,7 @@ from the **Discord Gateway**. which will be used to create a new `*heart.PacemakerLoop` and start sending heartbeats to the **Discord Voice Gateway**. * Afterwards, an [Identify Command](https://discordapp.com/developers/docs/topics/voice-connections#establishing-a-voice-websocket-connection-example-voice-identify-payload) or [Resume Command](https://discordapp.com/developers/docs/topics/voice-connections#resuming-voice-connection-example-resume-connection-payload) -is sent to the **Discord Voice Gateway** depending on whether or not the **library** is reconnecting. +is sent to the **Discord Voice Gateway** depending on whether the **library** is reconnecting. ---