Compare commits
68 Commits
BotCommand
...
6e1c27ca27
| Author | SHA1 | Date | |
|---|---|---|---|
|
6e1c27ca27
|
|||
|
cb38b8e5c4
|
|||
|
140515f19b
|
|||
|
d4fc69cd50
|
|||
|
6fd9d11417
|
|||
|
283f8dbf65
|
|||
|
cce07513f3
|
|||
|
d13ee51aa6
|
|||
| 7713e3fc02 | |||
| 084ce2aaae | |||
| cf494d4c11 | |||
| 46e67b7f98 | |||
| 07d51266bb | |||
| 7aa9372eaf | |||
| 931825bd5a | |||
| 5c39cbdafb | |||
| 25ea59bff1 | |||
| 908d506f5c | |||
| b323262213 | |||
| 0013b1fe2b | |||
| 09046f48dc | |||
| bd4b4508e5 | |||
|
6232d9e126
|
|||
|
90c5a1c472
|
|||
|
578174e878
|
|||
|
b85794089f
|
|||
|
d85da5989a
|
|||
|
6f3896a90b
|
|||
|
cebc18f0a2
|
|||
|
a97993e830
|
|||
|
01f5ae64ea
|
|||
|
21f5d2bb56
|
|||
|
fef2e7f08f
|
|||
|
7610f22b57
|
|||
|
0df1fae253
|
|||
|
5222b1b3b6
|
|||
|
53b3aa61ab
|
|||
|
ab0455cf5b
|
|||
|
80746f5bff
|
|||
|
304144c607
|
|||
|
2f5c3b6cf3
|
|||
|
70672fd5fd
|
|||
|
4d8e33058a
|
|||
|
3d174fd4f0
|
|||
|
160625396c
|
|||
|
62738d8a88
|
|||
|
37ce86beb7
|
|||
|
6bdc997cbe
|
|||
|
42969ca27c
|
|||
|
b6716eba46
|
|||
|
3d6d5c64b9
|
|||
|
2a5fe0ceef
|
|||
|
fa53c8b1da
|
|||
|
fb2636c9c0
|
|||
|
5dc1f53a59
|
|||
|
fd5d3ce0e7
|
|||
|
526af29391
|
|||
|
03ce2fe74a
|
|||
|
29ab9296ec
|
|||
|
81f7d3ccdc
|
|||
|
77b6e9c780
|
|||
|
06da80de97
|
|||
|
51f9f10b17
|
|||
|
17141a8ea4
|
|||
|
af81e9ddc8
|
|||
|
664daa311a
|
|||
|
43ceafbea0
|
|||
|
575a07dd01
|
24
auth.go
24
auth.go
@ -17,14 +17,14 @@ func reqPass(w http.ResponseWriter, r *http.Request) {
|
||||
username := r.URL.Query()["UserName"][0]
|
||||
log.LogInfo("reqPass username is %+v.", username)
|
||||
var userID string
|
||||
if &dg == nil {
|
||||
if dg == nil {
|
||||
log.LogError("Discord session was nill.")
|
||||
}
|
||||
g, err := dg.GuildMembers(config.GuildID, "", 1000)
|
||||
log.LogInfo("reqPass guild is %+v.", config.GuildID)
|
||||
if err == nil {
|
||||
for _, m := range g {
|
||||
if strings.ToUpper(m.Nick) == strings.ToUpper(username) {
|
||||
if strings.EqualFold(m.Nick, username) {
|
||||
for _, r := range m.Roles {
|
||||
if r == config.AdminRole {
|
||||
userID = m.User.ID
|
||||
@ -40,7 +40,7 @@ func reqPass(w http.ResponseWriter, r *http.Request) {
|
||||
log.LogInfo("reqPass IP is %+v.", ipaddr)
|
||||
log.LogInfo(fmt.Sprintf("reqPass called:```username: %s\nip : %s```", username, ipaddr))
|
||||
go sendPassword(userID, ipaddr)
|
||||
http.Redirect(w, r, "/login", 302)
|
||||
http.Redirect(w, r, "/login", http.StatusTemporaryRedirect)
|
||||
}
|
||||
|
||||
func tryLogin(w http.ResponseWriter, r *http.Request) {
|
||||
@ -147,7 +147,6 @@ func getSessionIdentifier(r *http.Request) string {
|
||||
func detectUser(r *http.Request, callFunc string) (bool, string) {
|
||||
defer log.PanicSafe()
|
||||
log.LogInfo(fmt.Sprintf("%s called detectUser", getSessionIdentifier(r)))
|
||||
ip := r.Header.Get("X-Real-IP")
|
||||
session, err := store.Get(r, "2fa")
|
||||
if err != nil {
|
||||
log.LogDebug(fmt.Sprintf("Unable to open 2fa session in %s", callFunc))
|
||||
@ -155,9 +154,6 @@ func detectUser(r *http.Request, callFunc string) (bool, string) {
|
||||
if session.Values["username"] != nil {
|
||||
return true, fmt.Sprintf("%s", session.Values["username"])
|
||||
}
|
||||
if ip == "154.27.199.33" {
|
||||
return true, "rudi"
|
||||
}
|
||||
return false, ""
|
||||
}
|
||||
|
||||
@ -176,7 +172,7 @@ func idFromUsername(username string) string {
|
||||
log.LogInfo("reqPass guild is %+v.", config.GuildID)
|
||||
if err == nil {
|
||||
for _, m := range g {
|
||||
if strings.ToUpper(m.Nick) == strings.ToUpper(username) {
|
||||
if strings.EqualFold(m.User.Username, username) {
|
||||
userID = m.User.ID
|
||||
log.LogInfo("User ID found for %+v as %+v", username, userID)
|
||||
}
|
||||
@ -186,3 +182,15 @@ func idFromUsername(username string) string {
|
||||
}
|
||||
return userID
|
||||
}
|
||||
|
||||
func isAdmin(m *discordgo.Member) bool {
|
||||
log.LogDebug("Checking %+v for %+v", m.Roles, config.AdminRole)
|
||||
for _, role := range m.Roles {
|
||||
if role == config.AdminRole {
|
||||
return true
|
||||
} else {
|
||||
log.LogDebug("%+v != %+v", role, config.AdminRole)
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
153
commands.go
153
commands.go
@ -5,14 +5,19 @@ import (
|
||||
"math/rand"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"sort"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/rudi9719/loggy"
|
||||
)
|
||||
|
||||
func setupCommands() {
|
||||
reboot := Command{
|
||||
Name: "Reboot",
|
||||
RequiresAdmin: true,
|
||||
Help: "Reboot me, requires token from logs.",
|
||||
Keywords: []string{"reboot", "re", "restart"},
|
||||
Exec: Reboot,
|
||||
}
|
||||
@ -20,6 +25,8 @@ func setupCommands() {
|
||||
|
||||
bumpset := Command{
|
||||
Name: "BumpSet",
|
||||
RequiresAdmin: true,
|
||||
Help: "Set the bump timer (requires time in minutes until next bump).",
|
||||
Keywords: []string{"bs", "bumpset", "bumps"},
|
||||
Exec: BumpSet,
|
||||
}
|
||||
@ -27,6 +34,8 @@ func setupCommands() {
|
||||
|
||||
retrieveVerification := Command{
|
||||
Name: "Retrieve Verification",
|
||||
RequiresAdmin: true,
|
||||
Help: "Retrieve verification either by discord ID or by nickname",
|
||||
Keywords: []string{"veri", "verification", "retrieve"},
|
||||
Exec: RetrieveVerification,
|
||||
}
|
||||
@ -34,6 +43,7 @@ func setupCommands() {
|
||||
|
||||
addQuote := Command{
|
||||
Name: "Add Quote",
|
||||
RequiresAdmin: true,
|
||||
Keywords: []string{"quote", "addq", "q"},
|
||||
Exec: AddQuote,
|
||||
}
|
||||
@ -41,6 +51,8 @@ func setupCommands() {
|
||||
|
||||
snap := Command{
|
||||
Name: "Snap",
|
||||
Help: "Trigger a purge!",
|
||||
RequiresAdmin: false,
|
||||
Keywords: []string{"snap", "purge", "sn"},
|
||||
Exec: Snap,
|
||||
}
|
||||
@ -48,10 +60,65 @@ func setupCommands() {
|
||||
|
||||
status := Command{
|
||||
Name: "Status",
|
||||
RequiresAdmin: true,
|
||||
Help: "Show the current status of Thanos/Verifications and probations",
|
||||
Keywords: []string{"st", "status", "stats"},
|
||||
Exec: Status,
|
||||
}
|
||||
commands = append(commands, status)
|
||||
|
||||
listCommands := Command{
|
||||
Name: "List Commands",
|
||||
RequiresAdmin: false,
|
||||
Keywords: []string{"help", "commands", "cmd", "cmds"},
|
||||
Exec: Commands,
|
||||
}
|
||||
commands = append(commands, listCommands)
|
||||
|
||||
debugLevel := Command{
|
||||
Name: "Debug Level",
|
||||
RequiresAdmin: true,
|
||||
Keywords: []string{"debug"},
|
||||
Exec: Debug,
|
||||
Help: "Set the log level for loggy",
|
||||
}
|
||||
commands = append(commands, debugLevel)
|
||||
|
||||
activityReport := Command{
|
||||
Name: "Activity Report",
|
||||
RequiresAdmin: false,
|
||||
Keywords: []string{"activity", "active", "list"},
|
||||
Exec: ActivityReport,
|
||||
Help: "List activity for the discord. Supply a number to get the top N users (5 would be top 5 users) or all for all users!",
|
||||
}
|
||||
commands = append(commands, activityReport)
|
||||
}
|
||||
|
||||
func Commands(b BotCommand) bool {
|
||||
defer log.PanicSafe()
|
||||
print := "Available commands:\n"
|
||||
for _, cmd := range commands {
|
||||
if cmd.RequiresAdmin {
|
||||
if isAdmin(b.Message.Member) {
|
||||
print += fmt.Sprintf("```%+v\n%+v\n%+v```\n", cmd.Name, cmd.Keywords, cmd.Help)
|
||||
}
|
||||
} else {
|
||||
print += fmt.Sprintf("```%+v\n%+v\n%+v```\n", cmd.Name, cmd.Keywords, cmd.Help)
|
||||
}
|
||||
}
|
||||
b.Session.ChannelMessageSend(b.Message.ChannelID, print)
|
||||
return true
|
||||
}
|
||||
|
||||
func Debug(b BotCommand) bool {
|
||||
defer log.PanicSafe()
|
||||
level, err := strconv.Atoi(b.Parts[0])
|
||||
if err != nil {
|
||||
return false
|
||||
}
|
||||
config.LogOpts.Level = loggy.LogLevel(level)
|
||||
log = loggy.NewLogger(config.LogOpts)
|
||||
return true
|
||||
}
|
||||
|
||||
func Reboot(b BotCommand) bool {
|
||||
@ -63,33 +130,71 @@ func Reboot(b BotCommand) bool {
|
||||
return false
|
||||
}
|
||||
|
||||
func ActivityReport(b BotCommand) bool {
|
||||
useCounter := true
|
||||
counterStop := 4
|
||||
if len(b.Parts) > 0 {
|
||||
test, err := strconv.Atoi(b.Parts[0])
|
||||
if err == nil {
|
||||
counterStop = test
|
||||
} else {
|
||||
useCounter = false
|
||||
}
|
||||
}
|
||||
statistics := "```"
|
||||
n := map[int][]string{}
|
||||
counter := 0
|
||||
var a []int
|
||||
for k, v := range config.Activity {
|
||||
n[v] = append(n[v], k)
|
||||
}
|
||||
for k := range n {
|
||||
a = append(a, k)
|
||||
}
|
||||
sort.Sort(sort.Reverse(sort.IntSlice(a)))
|
||||
for _, k := range a {
|
||||
for _, s := range n[k] {
|
||||
if useCounter && counter == counterStop-1 {
|
||||
return true
|
||||
}
|
||||
user, err := b.Session.GuildMember(config.GuildID, s)
|
||||
if err == nil {
|
||||
statistics += fmt.Sprintf("\n%+v: %+v", user.User.Username, k)
|
||||
counter++
|
||||
} else {
|
||||
log.LogErrorType(err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
statistics += "\n```"
|
||||
return true
|
||||
}
|
||||
|
||||
func BumpSet(b BotCommand) bool {
|
||||
defer log.PanicSafe()
|
||||
bump = false
|
||||
parts := strings.Split(b.Message.Content, " ")
|
||||
timer, err := strconv.Atoi(parts[1])
|
||||
timer, err := strconv.Atoi(b.Parts[0])
|
||||
if err != nil {
|
||||
b.Session.ChannelMessageSend(b.Message.ChannelID, fmt.Sprintf("Unable to decode timer: %+v", parts[1]))
|
||||
b.Session.ChannelMessageSend(b.Message.ChannelID, fmt.Sprintf("Unable to decode timer: %+v", b.Parts[0]))
|
||||
return false
|
||||
}
|
||||
config.BumpTime = time.Now().Add(time.Duration(timer) * time.Minute).Add(-2 * time.Hour)
|
||||
b.Session.ChannelMessageSend(b.Message.ChannelID, fmt.Sprintf("New bump time: %+v, expecting bump at %+v", config.BumpTime, config.BumpTime.Add(2*time.Hour)))
|
||||
b.Session.ChannelMessageSend(b.Message.ChannelID, fmt.Sprintf("New last bump time: <t:%+v:t>, expecting next bump at <t:%+v:t>", config.BumpTime.Unix(), config.BumpTime.Add(2*time.Hour).Unix()))
|
||||
return true
|
||||
}
|
||||
|
||||
func RetrieveVerification(b BotCommand) bool {
|
||||
defer log.PanicSafe()
|
||||
s := b.Session
|
||||
m := b.Message
|
||||
parts := strings.Split(m.Content, " ")
|
||||
discordId := parts[1]
|
||||
discordId := b.Parts[0]
|
||||
_, err := strconv.Atoi(discordId)
|
||||
if err != nil {
|
||||
discordId = idFromUsername(discordId)
|
||||
}
|
||||
user, err := s.GuildMember(config.GuildID, discordId)
|
||||
user, err := b.Session.GuildMember(config.GuildID, discordId)
|
||||
if err != nil {
|
||||
log.LogErrorType(err)
|
||||
return false
|
||||
}
|
||||
|
||||
matches, err := filepath.Glob(fmt.Sprintf("./verifications/*%+v*", discordId))
|
||||
@ -98,7 +203,7 @@ func RetrieveVerification(b BotCommand) bool {
|
||||
return false
|
||||
}
|
||||
if len(matches) != 1 {
|
||||
s.ChannelMessageSend(m.ChannelID, fmt.Sprintf("Error finding verification for ID %+v", discordId))
|
||||
b.Session.ChannelMessageSend(b.Message.ChannelID, fmt.Sprintf("Error finding verification for ID %+v", discordId))
|
||||
return false
|
||||
}
|
||||
|
||||
@ -107,8 +212,8 @@ func RetrieveVerification(b BotCommand) bool {
|
||||
log.LogErrorType(err)
|
||||
return false
|
||||
}
|
||||
msg := fmt.Sprintf("```%+v\nJoined: %+v\n```", user.User.Username, user.JoinedAt)
|
||||
s.ChannelFileSendWithMessage(m.ChannelID, msg, fmt.Sprintf("%+v Verification", discordId), verificationImage)
|
||||
msg := fmt.Sprintf("``` %+v\nJoined: %+v\n```", user.User.Username, user.JoinedAt)
|
||||
b.Session.ChannelFileSendWithMessage(b.Message.ChannelID, msg, matches[0], verificationImage)
|
||||
return true
|
||||
}
|
||||
|
||||
@ -128,36 +233,38 @@ func Snap(b BotCommand) bool {
|
||||
func Status(b BotCommand) bool {
|
||||
defer log.PanicSafe()
|
||||
status := fmt.Sprintf("Uptime: %+v\n", time.Since(startupTime))
|
||||
status += fmt.Sprintf("Last bump: %+v\n", time.Since(config.BumpTime))
|
||||
status += fmt.Sprintf("Last bumper: <@%+v>\n", userFromID(config.LastBumper).Username)
|
||||
status += fmt.Sprintf("Last active time: %+v\n", time.Since(lastActiveTime))
|
||||
status += fmt.Sprintf("Last bump: <t:%+v:t>\n", config.BumpTime.Unix())
|
||||
status += fmt.Sprintf("Last bumper: %+v\n", userFromID(config.LastBumper).Username)
|
||||
status += fmt.Sprintf("Bump needed: %+v\n", bump)
|
||||
if len(config.Unverified) > 0 {
|
||||
status += "Unverified users:\n```"
|
||||
status += "Unverified users:\n"
|
||||
for k, v := range config.Unverified {
|
||||
uvUser := userFromID(k)
|
||||
status += fmt.Sprintf("\n%+v will be removed in %+v", uvUser.Username, time.Until(v.Add(1*time.Hour)))
|
||||
status += fmt.Sprintf("\n%+v will be removed at <t:%+v:t>", uvUser.Username, v.Add(1*time.Hour).Unix())
|
||||
}
|
||||
status += "```"
|
||||
status += "\n"
|
||||
} else {
|
||||
status += "There are no unverified users.\n"
|
||||
}
|
||||
if len(config.Verifications) > 0 {
|
||||
status += "Pending verifications:\n"
|
||||
status += "```"
|
||||
for _, v := range config.Verifications {
|
||||
status += fmt.Sprintf("%+v has submitted a verification.", v.Username)
|
||||
}
|
||||
status += "```"
|
||||
status += "\n"
|
||||
} else {
|
||||
status += "There are no pending verifications."
|
||||
status += "There are no pending verifications.\n"
|
||||
}
|
||||
if len(config.Probations) > 0 {
|
||||
status += "\nThe following users are on probation: \n```"
|
||||
status += "\nThe following users are on probation: \n"
|
||||
for uid, join := range config.Probations {
|
||||
probationUser := userFromID(uid)
|
||||
status += fmt.Sprintf("%+v for another %+v\n", probationUser.Username, time.Until(join.Add(2*time.Hour)))
|
||||
status += fmt.Sprintf("%+v for until <t:%+v:t>\n", probationUser.Username, join.Add(2*time.Hour).Unix())
|
||||
}
|
||||
status += "```"
|
||||
status += "\n"
|
||||
} else {
|
||||
status += "There are no users on probation.\n"
|
||||
}
|
||||
b.Session.ChannelMessageSend(config.AdminChannel, status)
|
||||
statistics := "```"
|
||||
|
||||
21
config.go
21
config.go
@ -59,16 +59,32 @@ func saveConfig() {
|
||||
}
|
||||
|
||||
func adminInteraction(s *discordgo.Session, m string) {
|
||||
defer log.PanicSafe()
|
||||
admin, _ := s.GuildMember(config.GuildID, m)
|
||||
counter, ok := config.Stats[admin.User.ID]
|
||||
if !ok {
|
||||
config.Stats[admin.User.ID] = 0
|
||||
config.Stats[admin.User.ID] = 1
|
||||
} else {
|
||||
config.Stats[admin.User.ID] = counter + 1
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func activeInteraction(s *discordgo.Session, m string) {
|
||||
defer log.PanicSafe()
|
||||
if config.Activity == nil {
|
||||
config.Activity = make(map[string]int)
|
||||
}
|
||||
user, _ := s.GuildMember(config.GuildID, m)
|
||||
counter, ok := config.Activity[user.User.ID]
|
||||
if !ok {
|
||||
config.Activity[user.User.ID] = 1
|
||||
} else {
|
||||
config.Activity[user.User.ID] = counter + 1
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func rebootBump() {
|
||||
time.Sleep(time.Until(config.BumpTime.Add(2 * time.Hour)))
|
||||
dg.ChannelMessageSend(config.AdminChannel, "!d bump is ready")
|
||||
@ -82,9 +98,6 @@ func bumpTimer(s *discordgo.Session) {
|
||||
bump = false
|
||||
config.BumpTime = time.Now()
|
||||
time.Sleep(2 * time.Hour)
|
||||
if time.Since(lastActiveTime) < (5*time.Minute) && lastActiveChan != config.AdminChannel {
|
||||
s.ChannelMessageSend(lastActiveChan, "!d bump is ready, please use it. (say \"!d bump\" without the quotes)")
|
||||
}
|
||||
s.ChannelMessageSend(config.AdminChannel, "!d bump is ready.")
|
||||
bump = true
|
||||
}
|
||||
|
||||
@ -9,29 +9,36 @@ import (
|
||||
|
||||
func ready(s *discordgo.Session, event *discordgo.Ready) {
|
||||
// Set the playing status.
|
||||
s.UpdateGameStatus(0, fmt.Sprintf("DreamDaddy v%+v %+v", version, gitCommit))
|
||||
s.UpdateGameStatus(0, fmt.Sprintf("DreamDaddy rev %+v", gitCommit))
|
||||
}
|
||||
|
||||
func guildMemberUpdate(s *discordgo.Session, m *discordgo.GuildMemberUpdate) {
|
||||
defer log.PanicSafe()
|
||||
for role := range m.Roles {
|
||||
log.LogDebug("Member %+v has been updated", m.User.Username)
|
||||
for _, role := range m.Roles {
|
||||
if fmt.Sprintf("%+v", role) == config.MonitorRole {
|
||||
s.ChannelMessageSend(config.AdminChannel, "New unverified user detected.")
|
||||
log.LogDebug("Role found, Monitor Role")
|
||||
s.ChannelMessageSend(config.MonitorChann, fmt.Sprintf("Welcome %+v, you may PM me your verification, or I will ban you in an hour!\nSay \"!rules\" in this channel, without quotes for the rules. You may private/direct message me for verification instructions.\n\nYou will not be able to read/see other channels or users until you verify.", m.User.Mention()))
|
||||
config.Unverified[m.User.ID] = time.Now()
|
||||
config.Probations[m.User.ID] = time.Now()
|
||||
saveConfig()
|
||||
return
|
||||
}
|
||||
log.LogDebug("Monitor Role not found: %+v != %+v", fmt.Sprintf("%+v", role), config.MonitorRole)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func guildMemberAdd(s *discordgo.Session, m *discordgo.GuildMemberAdd) {
|
||||
defer log.PanicSafe()
|
||||
log.LogDebug("Adding user to Unverified and Probations")
|
||||
config.Unverified[m.User.ID] = time.Now()
|
||||
config.Probations[m.User.ID] = time.Now()
|
||||
log.LogDebug("Giving user monitor role")
|
||||
s.GuildMemberRoleAdd(config.GuildID, m.User.ID, config.MonitorRole)
|
||||
log.LogDebug("Sending Monitored message")
|
||||
s.ChannelMessageSend(config.MonitorChann, fmt.Sprintf("Welcome %+v, you may PM me your verification, or I will ban you in an hour!\nSay \"!rules\" in this channel, without quotes for the rules. You may private/direct message me for verification instructions.\n\nYou will not be able to read/see other channels or users until you verify.", m.User.Mention()))
|
||||
log.LogDebug("Calling saveConfig")
|
||||
saveConfig()
|
||||
}
|
||||
|
||||
@ -106,7 +113,7 @@ func readReaction(s *discordgo.Session, m *discordgo.MessageReactionAdd) {
|
||||
log.LogInfo("%+v has requested ASL for user %+v.", admin.User.Username, user.Username)
|
||||
return
|
||||
} else if m.Emoji.Name == "⛔" {
|
||||
s.GuildBanCreateWithReason(config.GuildID, user.ID, fmt.Sprintf("Underage or too many failed verifications. %+v", admin.User.Username), 5)
|
||||
s.GuildBanCreateWithReason(config.GuildID, user.ID, fmt.Sprintf("Underage female or too many failed verifications. %+v", admin.User.Username), 5)
|
||||
verification.Status = "Banned"
|
||||
} else {
|
||||
return
|
||||
|
||||
@ -2,6 +2,7 @@ package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"regexp"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
@ -10,68 +11,106 @@ import (
|
||||
|
||||
func messageCreate(s *discordgo.Session, m *discordgo.MessageCreate) {
|
||||
defer log.PanicSafe()
|
||||
var b BotCommand
|
||||
if strings.HasPrefix(m.Content, s.State.User.Mention()) {
|
||||
b = BotCommand{
|
||||
Session: s,
|
||||
|
||||
if m.Author.ID == "302050872383242240" && len(m.Embeds) > 0 {
|
||||
if strings.Contains(m.Embeds[0].Description, "minutes until the server can be bumped") {
|
||||
log.LogDebug("Failed bump detected")
|
||||
re := regexp.MustCompile("Please wait another (.*) minutes until the server can be bumped")
|
||||
match := re.FindStringSubmatch(m.Embeds[0].Description)
|
||||
m.Content = fmt.Sprintf("%+v bs %+v", s.State.User.Mention(), match[1])
|
||||
BumpSet(BotCommand{
|
||||
Message: m,
|
||||
Parts: strings.Split(m.Content, " ")[1:],
|
||||
Session: s,
|
||||
Parts: strings.Split(m.Content, " ")[2:],
|
||||
})
|
||||
|
||||
}
|
||||
if strings.Contains(m.Embeds[0].Description, "Bump done!") {
|
||||
log.LogDebug("Finding string %+v", m.Embeds[0].Description)
|
||||
re := regexp.MustCompile("<@(.*)>")
|
||||
match := re.FindStringSubmatch(m.Embeds[0].Description)
|
||||
activeInteraction(s, match[1])
|
||||
config.LastBumper = match[1]
|
||||
}
|
||||
if m.Author.ID == s.State.User.ID || m.Author.Bot {
|
||||
return
|
||||
|
||||
}
|
||||
if m.Author.Bot || m.Author.ID == s.State.User.ID {
|
||||
return
|
||||
}
|
||||
if m.GuildID == "" {
|
||||
handlePM(s, m)
|
||||
return
|
||||
}
|
||||
if m.ChannelID == config.MonitorChann {
|
||||
if isAdmin(m.Member) {
|
||||
adminInteraction(s, m.Author.ID)
|
||||
}
|
||||
|
||||
if m.ChannelID == config.MonitorChann && !isAdmin(m.Member) {
|
||||
if strings.Contains(m.Content, "erif") && !m.Author.Bot {
|
||||
s.ChannelMessageSend(m.ChannelID, fmt.Sprintf("%+v send me a private message for verification.", m.Author.Mention()))
|
||||
}
|
||||
return
|
||||
}
|
||||
for role := range m.Member.Roles {
|
||||
if fmt.Sprintf("%+v", role) == config.AdminRole {
|
||||
adminInteraction(s, m.Author.ID)
|
||||
}
|
||||
}
|
||||
|
||||
if m.ChannelID != config.AdminChannel {
|
||||
lastActiveChan = m.ChannelID
|
||||
lastActiveTime = time.Now()
|
||||
if len(m.Attachments) > 0 {
|
||||
activeInteraction(s, m.Author.ID)
|
||||
}
|
||||
}
|
||||
if strings.HasPrefix(m.Content, "!d bump") {
|
||||
if time.Since(config.BumpTime) < 2*time.Hour {
|
||||
s.ChannelMessageSend(m.ChannelID, fmt.Sprintf("Sorry, <@%+v> already claimed the bump. Better luck next time!", config.LastBumper))
|
||||
return
|
||||
}
|
||||
config.LastBumper = m.Author.ID
|
||||
go bumpTimer(s)
|
||||
return
|
||||
}
|
||||
if time.Since(config.BumpTime) > 2*time.Hour {
|
||||
s.ChannelMessageSend(m.ChannelID, fmt.Sprintf("%+v please say \"!d bump\" without the quotes to bump our server :)", m.Author.Mention()))
|
||||
if strings.Contains(m.Content, s.State.User.ID) {
|
||||
b := BotCommand{
|
||||
Session: s,
|
||||
Message: m,
|
||||
Parts: strings.Split(m.Content, " ")[2:],
|
||||
}
|
||||
if m.ChannelID == config.AdminChannel {
|
||||
if strings.HasPrefix(m.Content, s.State.User.Mention()) {
|
||||
log.LogDebug("%+v", b.Parts)
|
||||
for _, cmd := range commands {
|
||||
for _, keyword := range cmd.Keywords {
|
||||
log.LogDebug("Checking if %+v contains %+v", m.Content, keyword)
|
||||
if strings.Contains(m.Content, keyword) {
|
||||
log.LogDebug("%+v found!", keyword)
|
||||
b.Command = keyword
|
||||
if !cmd.RequiresAdmin {
|
||||
log.LogDebug("%+v does not require admin, running!", cmd.Name)
|
||||
if !cmd.Exec(b) {
|
||||
s.ChannelMessageSend(config.AdminChannel, fmt.Sprintf("There was an error running %+v\n%+v", cmd.Name, cmd.Help))
|
||||
} else {
|
||||
log.LogInfo("Ran command %+v for %+v", cmd.Name, m.Author.Username)
|
||||
}
|
||||
} else {
|
||||
log.LogDebug("%+v does require admin, checking!", cmd.Name)
|
||||
if isAdmin(m.Member) {
|
||||
if !cmd.Exec(b) {
|
||||
s.ChannelMessageSend(config.AdminChannel, fmt.Sprintf("There was an error running %+v\n%+v", cmd.Name, cmd.Help))
|
||||
} else {
|
||||
log.LogInfo("Ran command %+v for %+v", cmd.Name, m.Author.Username)
|
||||
}
|
||||
} else {
|
||||
log.LogInfo("%+v tried to run an admin command (%+v) but isn't an admin.", m.Author.Username, keyword)
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func handlePM(s *discordgo.Session, m *discordgo.MessageCreate) {
|
||||
defer log.PanicSafe()
|
||||
if strings.Contains(m.Content, "Rule") || strings.Contains(m.Content, "rule") {
|
||||
s.ChannelMessageSend(m.ChannelID, "I specifically said to say \"!rules\" without quotes in the unverified channel for the rules.")
|
||||
s.ChannelMessageSend(m.ChannelID, "I specifically said to say \"!rules\" without quotes in the _unverified_ channel for the rules.")
|
||||
}
|
||||
for _, uid := range config.Verifications {
|
||||
user := userFromID(uid.UserID)
|
||||
@ -90,6 +129,14 @@ func handlePM(s *discordgo.Session, m *discordgo.MessageCreate) {
|
||||
s.ChannelMessageSend(m.ChannelID, "You have tried to send an unsupported file (HEIC). Please try again using an image (jpeg, jpg, png, etc).")
|
||||
return
|
||||
}
|
||||
if strings.HasSuffix(strings.ToUpper(m.Attachments[0].ProxyURL), "MP4") {
|
||||
s.ChannelMessageSend(m.ChannelID, "You have tried to send an unsupported file (MP4 Video). Please try again using an image (jpeg, jpg, png, etc).")
|
||||
return
|
||||
}
|
||||
if strings.HasSuffix(strings.ToUpper(m.Attachments[0].ProxyURL), "MP3") {
|
||||
s.ChannelMessageSend(m.ChannelID, "You have tried to send an unsupported file (MP3 Audio). Please try again using an image (jpeg, jpg, png, etc).")
|
||||
return
|
||||
}
|
||||
delete(config.Unverified, m.Author.ID)
|
||||
var v Verification
|
||||
v.Submitted = time.Now()
|
||||
|
||||
56
main.go
56
main.go
@ -15,21 +15,18 @@ import (
|
||||
|
||||
var (
|
||||
startupTime time.Time
|
||||
setupToken = fmt.Sprintf("!setup %+v", rand.Intn(9999)+1000)
|
||||
rebootToken = fmt.Sprintf("!reboot %+v", rand.Intn(9999)+1000)
|
||||
setupToken = fmt.Sprintf("%+v", rand.Intn(9999)+1000)
|
||||
rebootToken = fmt.Sprintf("%+v", rand.Intn(9999)+1000)
|
||||
bump = true
|
||||
config Config
|
||||
log = loggy.NewLogger(config.LogOpts)
|
||||
lastActiveChan string
|
||||
lastActiveTime time.Time
|
||||
token string
|
||||
configFile string
|
||||
setupMsg string
|
||||
dg *discordgo.Session
|
||||
lastPM = make(map[string]time.Time)
|
||||
introMsg = make(map[string]string)
|
||||
quotes = []string{"The hardest choices require the strongest wills.", "You're strong, but I could snap my fingers and you'd all cease to exist.", "Fun isn't something one considers when balancing the universe. But this... does put a smile on my face.", "Perfectly balanced, as all things should be.", "I am inevitable."}
|
||||
version = "3.0"
|
||||
gitCommit string
|
||||
commands []Command
|
||||
)
|
||||
@ -51,7 +48,6 @@ func main() {
|
||||
log = loggy.NewLogger(config.LogOpts)
|
||||
startupTime = time.Now()
|
||||
lastActiveTime = time.Now()
|
||||
lastActiveChan = config.AdminChannel
|
||||
if token == "" {
|
||||
log.LogPanic("No token provided. Please run: disgord-thanos -t <bot token>")
|
||||
}
|
||||
@ -84,7 +80,7 @@ func main() {
|
||||
go purgeTimer(dg)
|
||||
go rebootBump()
|
||||
sc := make(chan os.Signal, 1)
|
||||
signal.Notify(sc, syscall.SIGINT, syscall.SIGTERM, os.Interrupt, os.Kill)
|
||||
signal.Notify(sc, syscall.SIGINT, syscall.SIGTERM, os.Interrupt)
|
||||
<-sc
|
||||
saveConfig()
|
||||
dg.Close()
|
||||
@ -126,7 +122,7 @@ func runPurge(s *discordgo.Session) {
|
||||
lastPM[k] = time.Now()
|
||||
pmChann, _ := s.UserChannelCreate(k)
|
||||
s.ChannelMessageSend(pmChann.ID,
|
||||
fmt.Sprintf("This is a reminder that you have not verified with me and will be removed in %+v. You may reply to this message for verification instructions.", time.Until(v.Add(1*time.Hour))))
|
||||
fmt.Sprintf("This is a reminder that you have not verified with me and will be removed at <t:%+v:t>. You may reply to this message for verification instructions.", v.Add(1*time.Hour).Unix()))
|
||||
if time.Since(v) > (time.Hour * 1) {
|
||||
s.ChannelMessageSend(config.AdminChannel, fmt.Sprintf("%+v was removed.", m.Mention()))
|
||||
s.GuildMemberDeleteWithReason(config.GuildID, k, fmt.Sprintf("Unverified user %+v.", v))
|
||||
@ -152,32 +148,64 @@ func runPurge(s *discordgo.Session) {
|
||||
s.ChannelMessageDelete(config.MonitorChann, message.ID)
|
||||
}
|
||||
}
|
||||
|
||||
go cleanSocials(s)
|
||||
saveConfig()
|
||||
}
|
||||
|
||||
func cleanSocials(s *discordgo.Session) {
|
||||
for _, channel := range config.SocialChanns {
|
||||
go func(channel string, s *discordgo.Session) {
|
||||
messages, _ := s.ChannelMessages(channel, 100, "", "", "")
|
||||
for _, message := range messages {
|
||||
_, err := s.GuildMember(config.GuildID, message.Author.ID)
|
||||
if err != nil {
|
||||
s.ChannelMessageDelete(channel, message.ID)
|
||||
}
|
||||
}
|
||||
}(channel, s)
|
||||
}
|
||||
}
|
||||
|
||||
func verifyMember(s *discordgo.Session, u discordgo.User) {
|
||||
defer log.PanicSafe()
|
||||
log.LogDebug("Adding verified roll")
|
||||
s.GuildMemberRoleAdd(config.GuildID, u.ID, config.VerifiedRole)
|
||||
log.LogDebug("Removing monitor role")
|
||||
s.GuildMemberRoleRemove(config.GuildID, u.ID, config.MonitorRole)
|
||||
st, _ := s.UserChannelCreate(u.ID)
|
||||
log.LogDebug("Creating PM channel")
|
||||
st, err := s.UserChannelCreate(u.ID)
|
||||
if err != nil {
|
||||
log.LogErrorType(err)
|
||||
}
|
||||
log.LogDebug("Sending acceptance message!")
|
||||
s.ChannelMessageSend(st.ID, "Your verification has been accepted, welcome!")
|
||||
m, _ := s.ChannelMessageSend(config.IntroChann, fmt.Sprintf("Welcome %+v please introduce yourself! :) feel free to check out <#710557387937022034> to tag your roles. Also please mute any channels you are not interested in!", u.Mention()))
|
||||
log.LogDebug("Sending Intro message")
|
||||
m, err := s.ChannelMessageSend(config.IntroChann, fmt.Sprintf("Welcome %+v please introduce yourself! :) feel free to check out <#710557387937022034> to tag your roles. Also please mute any channels you are not interested in!", u.Mention()))
|
||||
if err != nil {
|
||||
log.LogErrorType(err)
|
||||
}
|
||||
log.LogDebug("Storing introMsg ID to be deleted later")
|
||||
introMsg[u.ID] = m.ID
|
||||
}
|
||||
|
||||
func rejectVerification(s *discordgo.Session, u discordgo.User) {
|
||||
defer log.PanicSafe()
|
||||
st, _ := s.UserChannelCreate(u.ID)
|
||||
st, err := s.UserChannelCreate(u.ID)
|
||||
if err != nil {
|
||||
log.LogErrorType(err)
|
||||
}
|
||||
if st != nil {
|
||||
s.ChannelMessageSend(st.ID, fmt.Sprintf("Your verification has been rejected. This means it did not clearly show your face, with your pinkie finger held to the corner of your mouth, or the photo looked edited/filtered. No filters will be accepted.\n\nPlease try again before %+v", time.Until(time.Now().Add(1*time.Hour))))
|
||||
s.ChannelMessageSend(st.ID, fmt.Sprintf("Your verification has been rejected. This means it did not clearly show your face, with your pinkie finger held to the corner of your mouth, or the photo looked edited/filtered. No filters will be accepted.\n\nPlease try again before <t:%+v:t>", time.Now().Add(1*time.Hour).Unix()))
|
||||
}
|
||||
config.Unverified[u.ID] = time.Now()
|
||||
}
|
||||
|
||||
func requestAge(s *discordgo.Session, u discordgo.User) {
|
||||
defer log.PanicSafe()
|
||||
st, _ := s.UserChannelCreate(u.ID)
|
||||
st, err := s.UserChannelCreate(u.ID)
|
||||
if err != nil {
|
||||
log.LogErrorType(err)
|
||||
}
|
||||
s.ChannelMessageSend(st.ID, "What is your ASL? (Age/Sex/Language) Please note, this is NOT requesting your gender, but your biological sex. Gender is a social construct, sex is biology and in the context of pornographic images more important.")
|
||||
|
||||
}
|
||||
|
||||
34
site-api.go
34
site-api.go
@ -16,7 +16,6 @@ import (
|
||||
var (
|
||||
store = sessions.NewCookieStore([]byte(os.Getenv("SESSION_KEY")))
|
||||
toks = make(map[string]Tokens)
|
||||
acctLinks = make(map[string]linkedAccount)
|
||||
)
|
||||
|
||||
func topWrapper(r *http.Request) string {
|
||||
@ -60,16 +59,16 @@ func greetUser(w http.ResponseWriter, r *http.Request) {
|
||||
|
||||
if loggedIn {
|
||||
bodyTemplate, _ := ioutil.ReadFile("./static/index.html")
|
||||
fmt.Fprintf(w, string(bodyTemplate))
|
||||
fmt.Fprint(w, string(bodyTemplate))
|
||||
} else {
|
||||
fmt.Fprintf(w, pageBuilder(r, "home"))
|
||||
fmt.Fprint(w, pageBuilder(r, "home"))
|
||||
}
|
||||
}
|
||||
|
||||
func passPage(w http.ResponseWriter, r *http.Request) {
|
||||
defer log.PanicSafe()
|
||||
log.LogInfo(fmt.Sprintf("%s called passPage", getSessionIdentifier(r)))
|
||||
fmt.Fprintf(w, pageBuilder(r, "pass"))
|
||||
fmt.Fprint(w, pageBuilder(r, "pass"))
|
||||
}
|
||||
func loginPage(w http.ResponseWriter, r *http.Request) {
|
||||
defer log.PanicSafe()
|
||||
@ -85,18 +84,18 @@ func loginPage(w http.ResponseWriter, r *http.Request) {
|
||||
if err != nil {
|
||||
log.LogWarn("Error logging out from loginPage()")
|
||||
}
|
||||
fmt.Fprintf(w, pageBuilder(r, "home"))
|
||||
fmt.Fprint(w, pageBuilder(r, "home"))
|
||||
return
|
||||
}
|
||||
fmt.Fprintf(w, pageBuilder(r, "login"))
|
||||
fmt.Fprint(w, pageBuilder(r, "login"))
|
||||
}
|
||||
|
||||
func notFoundPage(w http.ResponseWriter, r *http.Request) {
|
||||
defer log.PanicSafe()
|
||||
go log.LogWarn(fmt.Sprintf("%s triggered notFoundPage", getSessionIdentifier(r)))
|
||||
fmt.Fprintf(w, topWrapper(r))
|
||||
fmt.Fprint(w, topWrapper(r))
|
||||
|
||||
fmt.Fprintf(w, card("Oops! That Page Was Not found.",
|
||||
fmt.Fprint(w, card("Oops! That Page Was Not found.",
|
||||
"Sorry, a 404 error has occured. The requested page not found! <br><br>"+
|
||||
"<iframe width=\"560\" height=\"315\" src=\"https://www.youtube.com/embed/t3otBjVZzT0\" frameborder=\"0\" allow=\"accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture\" allowfullscreen></iframe>",
|
||||
"<div class=\"error-actions\"><a href=\"/\" class=\"btn btn-primary btn-lg\"><span class=\"glyphicon glyphicon-home\"></span>Take Me Home </a> <a href=\"mailto://rudi@nmare.net\" class=\"btn btn-default btn-lg\"><span class=\"glyphicon glyphicon-envelope\"></span> Contact Support </a></div>"))
|
||||
@ -126,7 +125,7 @@ func getPending(w http.ResponseWriter, r *http.Request) {
|
||||
log.LogErrorType(err)
|
||||
notFoundPage(w, r)
|
||||
}
|
||||
fmt.Fprintf(w, string(pending))
|
||||
fmt.Fprint(w, string(pending))
|
||||
} else {
|
||||
notFoundPage(w, r)
|
||||
}
|
||||
@ -140,7 +139,7 @@ func getConfig(w http.ResponseWriter, r *http.Request) {
|
||||
log.LogErrorType(err)
|
||||
notFoundPage(w, r)
|
||||
}
|
||||
fmt.Fprintf(w, string(pending))
|
||||
fmt.Fprint(w, string(pending))
|
||||
} else {
|
||||
notFoundPage(w, r)
|
||||
}
|
||||
@ -154,7 +153,7 @@ func getProbations(w http.ResponseWriter, r *http.Request) {
|
||||
log.LogErrorType(err)
|
||||
notFoundPage(w, r)
|
||||
}
|
||||
fmt.Fprintf(w, string(pending))
|
||||
fmt.Fprint(w, string(pending))
|
||||
} else {
|
||||
notFoundPage(w, r)
|
||||
}
|
||||
@ -193,7 +192,7 @@ func getVerifications(w http.ResponseWriter, r *http.Request) {
|
||||
if err != nil {
|
||||
log.LogErrorType(err)
|
||||
}
|
||||
fmt.Fprintf(w, string(verifications))
|
||||
fmt.Fprint(w, string(verifications))
|
||||
}
|
||||
|
||||
func getUser(w http.ResponseWriter, r *http.Request) {
|
||||
@ -215,16 +214,7 @@ func getUser(w http.ResponseWriter, r *http.Request) {
|
||||
if err != nil {
|
||||
log.LogErrorType(err)
|
||||
}
|
||||
fmt.Fprintf(w, string(ret))
|
||||
}
|
||||
|
||||
func getVerification(w http.ResponseWriter, r *http.Request) {
|
||||
loggedIn, _ := detectUser(r, "getVerification")
|
||||
if !loggedIn {
|
||||
notFoundPage(w, r)
|
||||
return
|
||||
}
|
||||
http.ServeFile(w, r, r.URL.Path)
|
||||
fmt.Fprint(w, string(ret))
|
||||
}
|
||||
|
||||
func runWeb() {
|
||||
|
||||
@ -9,14 +9,13 @@ import (
|
||||
|
||||
var (
|
||||
token string
|
||||
configFile string
|
||||
dg *discordgo.Session
|
||||
guild = "451553644161138712"
|
||||
guild string
|
||||
)
|
||||
|
||||
func init() {
|
||||
flag.StringVar(&token, "t", "", "Bot Token")
|
||||
flag.StringVar(&configFile, "c", "", "Config file")
|
||||
flag.StringVar(&guild, "g", "", "Guild ID")
|
||||
flag.Parse()
|
||||
}
|
||||
|
||||
@ -26,11 +25,11 @@ func main() {
|
||||
}
|
||||
dg, _ = discordgo.New("Bot " + token)
|
||||
_ = dg.Open()
|
||||
unbanAll()
|
||||
runFunction()
|
||||
dg.Close()
|
||||
}
|
||||
|
||||
func unbanAll() {
|
||||
func runFunction() {
|
||||
bans, _ := dg.GuildBans(guild)
|
||||
for _, v := range bans {
|
||||
dg.GuildBanDelete(guild, v.User.ID)
|
||||
9
types.go
9
types.go
@ -18,6 +18,7 @@ type BotCommand struct {
|
||||
// Command is the type to store commands
|
||||
type Command struct {
|
||||
Name string
|
||||
RequiresAdmin bool
|
||||
Help string
|
||||
Keywords []string
|
||||
Exec func(BotCommand) bool
|
||||
@ -31,10 +32,12 @@ type Config struct {
|
||||
MonitorRole string
|
||||
IntroChann string
|
||||
MonitorChann string
|
||||
SocialChanns []string
|
||||
VerifiedRole string
|
||||
BumpTime time.Time
|
||||
LastBumper string
|
||||
Stats map[string]int
|
||||
Activity map[string]int
|
||||
Unverified map[string]time.Time
|
||||
Verifications map[string]Verification
|
||||
Probations map[string]time.Time
|
||||
@ -52,12 +55,6 @@ type Verification struct {
|
||||
Closed time.Time
|
||||
}
|
||||
|
||||
type linkedAccount struct {
|
||||
domainUser string
|
||||
discordUser string
|
||||
sigHash string
|
||||
}
|
||||
|
||||
// Tokens are the Login Token struct
|
||||
type Tokens struct {
|
||||
Username string
|
||||
|
||||
Reference in New Issue
Block a user