You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
Goff/djpianalto.com/goff/goff.go

226 lines
5.7 KiB

package main
import (
"fmt"
"github.com/MikeModder/anpan"
"github.com/bwmarrin/discordgo"
"os"
"os/signal"
"sort"
"strconv"
"strings"
"syscall"
"time"
)
var (
Token string
)
//func init() {
// flag.StringVar(&Token, "t", "", "Bot Token")
// flag.Parse()
//}
func main() {
Token = os.Getenv("DISCORDGO_TOKEN")
dg, err := discordgo.New("Bot " + Token)
if err != nil {
fmt.Println("There was an error when creating the Discord Session, ", err)
return
}
prefixes := []string{
"Go.",
}
owners := []string{
"351794468870946827",
}
// Arguments are:
// prefixes - []string
// owner ids - []string
// ignore bots - bool
// check perms - bool
handler := anpan.NewCommandHandler(prefixes, owners, true, true)
// Arguments:
// name - command name - string
// desc - command description - string
// owneronly - only allow owners to run - bool
// hidden - hide command from non-owners - bool
// 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)
dg.AddHandler(handler.OnMessage)
dg.AddHandler(handler.StatusHandler.OnReady)
err = dg.Open()
if err != nil {
fmt.Println("There was an error opening the connection, ", err)
return
}
fmt.Println("The Bot is now running. Press Ctrl+C to exit.")
sc := make(chan os.Signal, 1)
signal.Notify(sc, syscall.SIGINT, syscall.SIGTERM, os.Interrupt, os.Kill)
<-sc
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),
}
}