go: Refactor admin commands

master
Luther Wen Xu 2019-10-12 19:29:33 +07:00
parent 60af28773a
commit 0272d11a44
Signed by untrusted user: chanbakjsd
GPG Key ID: B7D77E3E9D102B70
5 changed files with 132 additions and 43 deletions

@ -0,0 +1,25 @@
package config
//==Message Util==
const UsageTitle = "使用方法Command Usage"
const UsageColour = 0xF00000
const ErrorStack = "纠错信息Debug Info"
const SuccessTitle = "成功Success"
const SuccessColour = 0x00E000
//==Commands==
const SendAsUsage = "!sendas <频道ID> <信息>\n!sendas <channel ID> <message>"
const SendAsSuccessfulDescription = "成功发送该信息。\nSent the message successfully."
const SendAsSuccessfulMessageID = "Discord编号 // Discord ID"
const EditAsUsage = "!editas <频道ID> <信息ID> <信息>\n!editas <channel ID> <message ID> <message>"
const EditAsSuccessfulDescription = "成功编辑该信息。\nEdited the message successfully."
//VTL is view trust level
const VTLColour = 0xE0E000
const VTLSingleUserTitle = "<@%s>的信誉分 <@%s>'s Trust Score"
const VTLSingleUserValue = "分数 Trust Score"
const VTLSingleUserServerTotal = "伺服器总分 Server Total"
const VTLSingleUserPercentage = "百分比 Percentage"
const VTLGlobalTitle = "伺服器信誉分报告 Server Trust Score Report"
const VTLGlobalFieldFormat = "%.1f/%.1f (%.2f%%)"

@ -2,86 +2,99 @@ package modules
import (
"fmt"
"strings"
"github.com/bwmarrin/discordgo"
"TerraOceanBot/discord/backend"
"TerraOceanBot/discord/config"
)
//adminID is my Discord user ID (chanbakjsd#7968).
const adminID = "218983355746746369"
func sendAs(s *discordgo.Session, m *discordgo.MessageCreate, command []string) {
func adminOnly(passOn CommandHandler) CommandHandler {
return func(s *discordgo.Session, m *discordgo.MessageCreate, command []string) {
if m.Author.ID != adminID {
return
}
if len(command) < 3 {
return
}
message := strings.SplitN(m.Content, " ", 3)
msg, err := s.ChannelMessageSend(message[1], message[2])
if err != nil {
s.ChannelMessageSend(m.ChannelID, err.Error())
passOn(s, m, command)
}
s.ChannelMessageSend(m.ChannelID, "The message has been sent. Discord ID: "+msg.ID)
}
func editAs(s *discordgo.Session, m *discordgo.MessageCreate, command []string) {
if m.Author.ID != adminID {
return
}
if len(command) < 4 {
return
}
message := strings.SplitN(m.Content, " ", 4)
_, err := s.ChannelMessageEdit(message[1], message[2], message[3])
var sendAs = adminOnly(enforceArgumentCount(config.SendAsUsage, 3,
//!sendas <channel ID> <message>
func(s *discordgo.Session, m *discordgo.MessageCreate, command []string) {
msg, err := s.ChannelMessageSend(command[1], command[2])
if err != nil {
s.ChannelMessageSend(m.ChannelID, err.Error())
}
s.ChannelMessageSend(m.ChannelID, "The message has been edited.")
sendError(s, m.ChannelID, err)
return
}
initNewEmbed(config.SuccessTitle, config.SendAsSuccessfulDescription, config.SuccessColour).
AddField(config.SendAsSuccessfulMessageID, msg.ID).
Send(s, m.ChannelID)
},
))
func viewTrustLevel(s *discordgo.Session, m *discordgo.MessageCreate, command []string) {
if m.Author.ID != adminID {
var editAs = adminOnly(enforceArgumentCount(config.EditAsUsage, 4,
//!editas <channel ID> <message ID> <message>
func(s *discordgo.Session, m *discordgo.MessageCreate, command []string) {
_, err := s.ChannelMessageEdit(command[1], command[2], command[3])
if err != nil {
sendError(s, m.ChannelID, err)
return
}
initNewEmbed(config.SuccessTitle, config.EditAsSuccessfulDescription, config.SuccessColour).
Send(s, m.ChannelID)
},
))
var viewTrustLevel = adminOnly(func(s *discordgo.Session, m *discordgo.MessageCreate, command []string) {
if len(command) > 1 {
value, err := backend.GetTrust(s, command[1])
if err != nil {
s.ChannelMessageSend(m.ChannelID, err.Error())
sendError(s, m.ChannelID, err)
return
}
total, err := backend.GetTotalTrust(s)
if err != nil {
s.ChannelMessageSend(m.ChannelID, err.Error())
sendError(s, m.ChannelID, err)
return
}
s.ChannelMessageSend(m.ChannelID, fmt.Sprintf("Trust level is %.1f/%.1f (%.2f%%) for user <@%d>.", value, total, value/total*100, command[1]))
newEmbed().SetColour(config.VTLColour).
SetTitle(fmt.Sprintf(config.VTLSingleUserTitle, command[1], command[1])).
AddField(config.VTLSingleUserValue, formatFloat(value, 1)).
AddField(config.VTLSingleUserServerTotal, formatFloat(total, 1)).
AddField(config.VTLSingleUserPercentage, formatFloat(value/total*100, 2)).
Send(s, m.ChannelID)
return
}
total, err := backend.GetTotalTrust(s)
if err != nil {
s.ChannelMessageSend(m.ChannelID, err.Error())
sendError(s, m.ChannelID, err)
return
}
message := ""
members, err := backend.GetAllMembers(s)
if err != nil {
s.ChannelMessageSend(m.ChannelID, err.Error())
sendError(s, m.ChannelID, err)
return
}
//Generate message
message := newEmbed().SetColour(config.VTLColour).SetTitle(config.VTLGlobalTitle)
for _, v := range members {
value, err := backend.GetTrust(s, v.User.ID)
if err == backend.ErrNotMember {
continue
}
if err != nil {
s.ChannelMessageSend(m.ChannelID, err.Error())
sendError(s, m.ChannelID, err)
return
}
message += fmt.Sprintf("%s#%s - %.1f/%.1f (%.2f%%)\n", v.User.Username, v.User.Discriminator, value, total, value/total*100)
}
s.ChannelMessageSend(m.ChannelID, message)
message.AddInlineField(
v.User.Username+"#"+v.User.Discriminator,
fmt.Sprintf(config.VTLGlobalFieldFormat, value, total, value/total*100),
)
}
message.Send(s, m.ChannelID)
})

@ -2,9 +2,10 @@ package modules
import "github.com/bwmarrin/discordgo"
type CommandHandler func(s *discordgo.Session, m *discordgo.MessageCreate, commands []string)
type Command struct {
Name string
Handler func(s *discordgo.Session, m *discordgo.MessageCreate, commands []string)
Handler CommandHandler
}
var Commands = []Command{

@ -10,9 +10,15 @@ func newEmbed() *embed {
return &embed{&discordgo.MessageEmbed{}}
}
func (e *embed) Errorify() *embed {
func initNewEmbed(title, description string, colour int) *embed {
return newEmbed().SetTitle(title).SetDescription(description).SetColour(colour)
}
func initNewErrorEmbed(description string) *embed {
e := newEmbed()
e.Color = 0xE00000
e.Title = "发生错误An error has occurred!"
e.Description = description
return e
}
@ -39,6 +45,19 @@ func (e *embed) AddField(name, value string) *embed {
return e
}
func (e *embed) AddInlineField(name, value string) *embed {
e.Fields = append(e.Fields, &discordgo.MessageEmbedField{
Name: name,
Value: value,
Inline: true,
})
return e
}
func (e *embed) Build() *discordgo.MessageEmbed {
return e.MessageEmbed
}
func (e *embed) Send(s *discordgo.Session, channelID string) {
s.ChannelMessageSendEmbed(channelID, e.Build())
}

@ -2,6 +2,9 @@ package modules
import (
"fmt"
"runtime"
"strconv"
"strings"
"github.com/bwmarrin/discordgo"
@ -76,3 +79,31 @@ func auditLog(s *discordgo.Session, message string) {
fmt.Println(err)
}
}
func enforceArgumentCount(usage string, count int, passOn CommandHandler) CommandHandler {
return func(s *discordgo.Session, m *discordgo.MessageCreate, command []string) {
if len(command) < count {
s.ChannelMessageSendEmbed(
m.ChannelID,
newEmbed().SetTitle(config.UsageTitle).SetDescription(usage).SetColour(config.UsageColour).Build(),
)
return
}
command[count-1] = strings.Join(command[count-1:], " ")
passOn(s, m, command[:count])
}
}
func sendError(s *discordgo.Session, channelID string, err error) {
stackCache := make([]byte, 512)
count := runtime.Stack(stackCache, false)
stack := string(stackCache[:count])
if count == 512 {
stack += "..."
}
initNewErrorEmbed(err.Error()).AddField(config.ErrorStack, stack).Send(s, channelID)
}
func formatFloat(n float64, precision int) string {
return strconv.FormatFloat(n, 'f', precision, 64)
}