diff --git a/djpianalto.com/goff/exts/utils.go b/djpianalto.com/goff/exts/utils.go new file mode 100644 index 0000000..49147b8 --- /dev/null +++ b/djpianalto.com/goff/exts/utils.go @@ -0,0 +1,102 @@ +package exts + +import ( + "djpianalto.com/goff/djpianalto.com/goff/utils" + "fmt" + "github.com/MikeModder/anpan" + "github.com/bwmarrin/discordgo" + "sort" + "strconv" + "strings" + "time" +) + +func PingCommand(ctx anpan.Context, _ []string) error { + timeBefore := time.Now() + msg, _ := ctx.Reply("Pong!") + took := time.Now().Sub(timeBefore) + ctx.Session.ChannelMessageEdit(ctx.Message.ChannelID, msg.ID, fmt.Sprintf("Pong!\nPing Took **%s**", took.String())) + return nil +} + +func SayCommand(ctx anpan.Context, args []string) error { + resp := strings.Join(args, " ") + resp = strings.ReplaceAll(resp, "@everyone", "@\ufff0everyone") + resp = strings.ReplaceAll(resp, "@here", "@\ufff0here") + ctx.Session.ChannelMessageSend(ctx.Message.ChannelID, resp) + return nil +} + +func UserCommand(ctx anpan.Context, args []string) error { + var member *discordgo.Member + if len(args) == 0 { + member, _ = ctx.Session.GuildMember(ctx.Guild.ID, ctx.Message.Author.ID) + } else { + var err error + if len(ctx.Message.Mentions) > 0 { + member, err = ctx.Session.GuildMember(ctx.Guild.ID, ctx.Message.Mentions[0].ID) + } else { + member, err = ctx.Session.GuildMember(ctx.Guild.ID, args[0]) + } + if err != nil { + return err + } + } + thumb := &discordgo.MessageEmbedThumbnail{ + URL: member.User.AvatarURL(""), + } + + var botString string + if member.User.Bot { + botString = "BOT" + } else { + botString = "" + } + + var roles []*discordgo.Role + for _, roleID := range member.Roles { + role, _ := ctx.Session.State.Role(ctx.Guild.ID, roleID) + roles = append(roles, role) + } + sort.Slice(roles, func(i, j int) bool { return roles[i].Position > roles[j].Position }) + var roleMentions []string + for _, role := range roles { + roleMentions = append(roleMentions, role.Mention()) + } + rolesString := strings.Join(roleMentions, " ") + + rolesField := &discordgo.MessageEmbedField{ + Name: "Roles:", + Value: rolesString, + Inline: false, + } + + guildJoinTime, _ := member.JoinedAt.Parse() + guildJoinedField := &discordgo.MessageEmbedField{ + Name: "Joined Guild:", + Value: utils.ParseDateString(guildJoinTime), + Inline: false, + } + + int64ID, _ := strconv.ParseInt(member.User.ID, 10, 64) + s := utils.ParseSnowflake(int64ID) + discordJoinedField := &discordgo.MessageEmbedField{ + Name: "Joined Discord:", + Value: utils.ParseDateString(s.CreationTime), + Inline: false, + } + + embed := &discordgo.MessageEmbed{ + Title: fmt.Sprintf("%v#%v %v", member.User.Username, member.User.Discriminator, botString), + Description: fmt.Sprintf("**%v** (%v)", member.Nick, member.User.ID), + Color: 0, + Thumbnail: thumb, + Fields: []*discordgo.MessageEmbedField{ + guildJoinedField, + discordJoinedField, + rolesField, + }, + } + ctx.Session.ChannelMessageSendEmbed(ctx.Channel.ID, embed) + return nil +} diff --git a/djpianalto.com/goff/goff.go b/djpianalto.com/goff/goff.go index a36dc2b..2923a07 100644 --- a/djpianalto.com/goff/goff.go +++ b/djpianalto.com/goff/goff.go @@ -1,16 +1,13 @@ package main import ( + "djpianalto.com/goff/djpianalto.com/goff/exts" "fmt" "github.com/MikeModder/anpan" "github.com/bwmarrin/discordgo" "os" "os/signal" - "sort" - "strconv" - "strings" "syscall" - "time" ) var ( @@ -52,9 +49,9 @@ func main() { // perms - permissisions required - anpan.Permission (int) // type - command type, sets where the command is available // run - function to run - func(anpan.Context, []string) / CommandRunFunc - handler.AddCommand("ping", "Check the bot's ping", false, false, 0, anpan.CommandTypeEverywhere, pingCommand) - handler.AddCommand("say", "Repeat a message", false, false, 0, anpan.CommandTypeEverywhere, sayCommand) - handler.AddCommand("user", "Show info about a user", false, false, 0, anpan.CommandTypeEverywhere, userCommand) + handler.AddCommand("ping", "Check the bot's ping", false, false, 0, anpan.CommandTypeEverywhere, exts.PingCommand) + handler.AddCommand("say", "Repeat a message", false, false, 0, anpan.CommandTypeEverywhere, exts.SayCommand) + handler.AddCommand("user", "Show info about a user", false, false, 0, anpan.CommandTypeEverywhere, exts.UserCommand) dg.AddHandler(handler.OnMessage) dg.AddHandler(handler.StatusHandler.OnReady) @@ -73,153 +70,3 @@ func main() { fmt.Println("Shutting Down...") dg.Close() } - -func pingCommand(ctx anpan.Context, _ []string) error { - timeBefore := time.Now() - msg, _ := ctx.Reply("Pong!") - took := time.Now().Sub(timeBefore) - ctx.Session.ChannelMessageEdit(ctx.Message.ChannelID, msg.ID, fmt.Sprintf("Pong!\nPing Took **%s**", took.String())) - return nil -} - -func sayCommand(ctx anpan.Context, args []string) error { - resp := strings.Join(args, " ") - resp = strings.ReplaceAll(resp, "@everyone", "@\ufff0everyone") - resp = strings.ReplaceAll(resp, "@here", "@\ufff0here") - ctx.Session.ChannelMessageSend(ctx.Message.ChannelID, resp) - return nil -} - -func userCommand(ctx anpan.Context, args []string) error { - var member *discordgo.Member - if len(args) == 0 { - member, _ = ctx.Session.GuildMember(ctx.Guild.ID, ctx.Message.Author.ID) - } else { - var err error - if len(ctx.Message.Mentions) > 0 { - member, err = ctx.Session.GuildMember(ctx.Guild.ID, ctx.Message.Mentions[0].ID) - } else { - member, err = ctx.Session.GuildMember(ctx.Guild.ID, args[0]) - } - if err != nil { - return err - } - } - thumb := &discordgo.MessageEmbedThumbnail{ - URL: member.User.AvatarURL(""), - } - - var botString string - if member.User.Bot { - botString = "BOT" - } else { - botString = "" - } - - var roles []*discordgo.Role - for _, roleID := range member.Roles { - role, _ := ctx.Session.State.Role(ctx.Guild.ID, roleID) - roles = append(roles, role) - } - sort.Slice(roles, func(i, j int) bool { return roles[i].Position > roles[j].Position }) - var roleMentions []string - for _, role := range roles { - roleMentions = append(roleMentions, role.Mention()) - } - rolesString := strings.Join(roleMentions, " ") - - rolesField := &discordgo.MessageEmbedField{ - Name: "Roles:", - Value: rolesString, - Inline: false, - } - - guildJoinTime, _ := member.JoinedAt.Parse() - guildJoinedField := &discordgo.MessageEmbedField{ - Name: "Joined Guild:", - Value: parseDateString(guildJoinTime), - Inline: false, - } - - int64ID, _ := strconv.ParseInt(member.User.ID, 10, 64) - s := parseSnowflake(int64ID) - discordJoinedField := &discordgo.MessageEmbedField{ - Name: "Joined Discord:", - Value: parseDateString(s.CreationTime), - Inline: false, - } - - embed := &discordgo.MessageEmbed{ - Title: fmt.Sprintf("%v#%v %v", member.User.Username, member.User.Discriminator, botString), - Description: fmt.Sprintf("**%v** (%v)", member.Nick, member.User.ID), - Color: 0, - Thumbnail: thumb, - Fields: []*discordgo.MessageEmbedField{ - guildJoinedField, - discordJoinedField, - rolesField, - }, - } - ctx.Session.ChannelMessageSendEmbed(ctx.Channel.ID, embed) - return nil -} - -func parseDateString(inTime time.Time) string { - d := time.Now().Sub(inTime) - s := int64(d.Seconds()) - days := s / 86400 - s = s - (days * 86400) - hours := s / 3600 - s = s - (hours * 3600) - minutes := s / 60 - seconds := s - (minutes * 60) - dateString := "" - if days != 0 { - dateString += fmt.Sprintf("%v days ", days) - } - if hours != 0 { - dateString += fmt.Sprintf("%v hours ", hours) - } - if minutes != 0 { - dateString += fmt.Sprintf("%v minutes ", minutes) - } - if seconds != 0 { - dateString += fmt.Sprintf("%v seconds ", seconds) - } - if dateString != "" { - dateString += " ago." - } else { - dateString = "Now" - } - stamp := inTime.Format("2006-01-02 15:04:05") - return fmt.Sprintf("%v\n%v", dateString, stamp) -} - -type Snowflake struct { - CreationTime time.Time - WorkerID int8 - ProcessID int8 - Increment int16 -} - -func parseSnowflake(s int64) Snowflake { - const ( - DISCORD_EPOCH = 1420070400000 - TIME_BITS_LOC = 22 - WORKER_ID_LOC = 17 - WORKER_ID_MASK = 0x3E0000 - PROCESS_ID_LOC = 12 - PROCESS_ID_MASK = 0x1F000 - INCREMENT_MASK = 0xFFF - ) - creationTime := time.Unix(((s>>TIME_BITS_LOC)+DISCORD_EPOCH)/1000.0, 0) - workerID := (s & WORKER_ID_MASK) >> WORKER_ID_LOC - processID := (s & PROCESS_ID_MASK) >> PROCESS_ID_LOC - increment := s & INCREMENT_MASK - return Snowflake{ - CreationTime: creationTime, - WorkerID: int8(workerID), - ProcessID: int8(processID), - Increment: int16(increment), - } -} diff --git a/djpianalto.com/goff/utils/date_strings.go b/djpianalto.com/goff/utils/date_strings.go new file mode 100644 index 0000000..bdd37bd --- /dev/null +++ b/djpianalto.com/goff/utils/date_strings.go @@ -0,0 +1,37 @@ +package utils + +import ( + "fmt" + "time" +) + +func ParseDateString(inTime time.Time) string { + d := time.Now().Sub(inTime) + s := int64(d.Seconds()) + days := s / 86400 + s = s - (days * 86400) + hours := s / 3600 + s = s - (hours * 3600) + minutes := s / 60 + seconds := s - (minutes * 60) + dateString := "" + if days != 0 { + dateString += fmt.Sprintf("%v days ", days) + } + if hours != 0 { + dateString += fmt.Sprintf("%v hours ", hours) + } + if minutes != 0 { + dateString += fmt.Sprintf("%v minutes ", minutes) + } + if seconds != 0 { + dateString += fmt.Sprintf("%v seconds ", seconds) + } + if dateString != "" { + dateString += " ago." + } else { + dateString = "Now" + } + stamp := inTime.Format("2006-01-02 15:04:05") + return fmt.Sprintf("%v\n%v", dateString, stamp) +} diff --git a/djpianalto.com/goff/utils/snowflake.go b/djpianalto.com/goff/utils/snowflake.go new file mode 100644 index 0000000..f26978c --- /dev/null +++ b/djpianalto.com/goff/utils/snowflake.go @@ -0,0 +1,32 @@ +package utils + +import "time" + +type Snowflake struct { + CreationTime time.Time + WorkerID int8 + ProcessID int8 + Increment int16 +} + +func ParseSnowflake(s int64) Snowflake { + const ( + DISCORD_EPOCH = 1420070400000 + TIME_BITS_LOC = 22 + WORKER_ID_LOC = 17 + WORKER_ID_MASK = 0x3E0000 + PROCESS_ID_LOC = 12 + PROCESS_ID_MASK = 0x1F000 + INCREMENT_MASK = 0xFFF + ) + creationTime := time.Unix(((s>>TIME_BITS_LOC)+DISCORD_EPOCH)/1000.0, 0) + workerID := (s & WORKER_ID_MASK) >> WORKER_ID_LOC + processID := (s & PROCESS_ID_MASK) >> PROCESS_ID_LOC + increment := s & INCREMENT_MASK + return Snowflake{ + CreationTime: creationTime, + WorkerID: int8(workerID), + ProcessID: int8(processID), + Increment: int16(increment), + } +}