Browse Source

Initial Commit

master
BuildTools 3 years ago
commit
a54a107408
  1. 2
      .gitignore
  2. 1
      config.json.bak
  3. 337
      discord.go
  4. 25
      email.go
  5. 83
      main.go
  6. 216
      minecraft.go
  7. 78
      types.go
  8. 153
      userdb.go
  9. 1
      verification.go

2
.gitignore vendored

@ -0,0 +1,2 @@ @@ -0,0 +1,2 @@
minedall
config.json

1
config.json.bak

@ -0,0 +1 @@ @@ -0,0 +1 @@
{"GuildID":"694345617438408755","MonitorChan":"694349670452822076","VerifiedChan":"694349742762754135","AdminChan":"694349831136739379","MonitorRole":"694349539997515818","VerifiedRole":"694349466249199656","AdminRole":"694349424557686895","StartTime":"2020-05-11T16:08:32.331953504-04:00","DiscordToken":"Njk0MzQ2NDYzOTg3MzY3OTk3.XoKSrA.cFeXpq2uohRKN-emquwZpoUPO5w","MyEmail":"olmstea1@sunypoly.edu","EmailPass":"qgoyybrjjkfywllo","SmtpServer":"smtp.gmail.com:587","AuthServer":"smtp.gmail.com","DbFile":"minedall.db","WbFinished":true}

337
discord.go

@ -0,0 +1,337 @@ @@ -0,0 +1,337 @@
package main
import (
"fmt"
"strconv"
"strings"
"time"
"github.com/bwmarrin/discordgo"
"github.com/google/uuid"
)
var session *discordgo.Session
var pendingV []Verification
var rebootTS time.Time
const alpha = "abcdefghijklmnopqrstuvwxyz1234567890"
func configureDiscord() {
dg, err := discordgo.New("Bot " + config.DiscordToken)
if err != nil {
log.LogErrorType(err)
log.LogPanic("Unable to create bot using token.")
}
dg.AddHandler(ready)
dg.AddHandler(readReaction)
dg.AddHandler(messageCreate)
dg.AddHandler(guildMemberAdd)
session = dg
err = dg.Open()
if err != nil {
log.LogErrorType(err)
log.LogPanic("Unable to open websocket")
}
log.LogInfo("Discord link is now online.")
}
func discordExit() {
log.LogCritical("Closing Discord (closing Session)")
session.Close()
}
func sendDiscordMessage(msg string) {
session.ChannelMessageSend(config.VerifiedChan, fixMentions(msg))
}
func sendAdminDiscordMessage(msg string) {
session.ChannelMessageSend(config.AdminChan, msg)
}
func ready(s *discordgo.Session, m *discordgo.Ready) {
s.UpdateStatus(0, "Minecraft")
}
func banUser(s *discordgo.Session, u discordgo.User) {
s.GuildBanCreate(config.GuildID, u.ID, 0)
}
func readReaction(s *discordgo.Session, m *discordgo.MessageReactionAdd) {
defer log.PanicSafe()
if m.Emoji.Name != "⚠" && m.Emoji.Name != "❗" {
return
}
log.LogDebug(fmt.Sprintf("Report emoji: ```%+v```", *m))
msg, err := s.ChannelMessage(m.ChannelID, m.MessageID)
log.LogDebug(fmt.Sprintf("Message retrieved: %+v", *msg))
if err != nil {
s.ChannelMessageSend(config.AdminChan, "A message was reported that I could not detect.")
return
}
reporter, _ := s.GuildMember(config.GuildID, m.UserID)
violator, _ := s.GuildMember(config.GuildID, msg.Author.ID)
s.ChannelMessageSend(config.AdminChan, fmt.Sprintf("A message was reported! %+v reported %+v's message: %+v\n```%+v```", reporter.Nick, violator.Nick, msg.Content, *msg))
var r Report
var violatorUser User
violatorUser.DiscordID = m.UserID
violatorUser.Retrieve()
var reporterUser User
reporterUser.DiscordID = msg.Author.ID
reporterUser.Retrieve()
reporterUser.Write() // Update last seen
r.Time = time.Now()
r.Reporter = reporterUser
r.Abuser = violatorUser
r.Msg = msg.Content
r.Write()
}
func guildMemberAdd(s *discordgo.Session, m *discordgo.GuildMemberAdd) {
defer log.PanicSafe()
s.GuildMemberRoleAdd(config.GuildID, m.User.ID, config.MonitorRole)
st, _ := s.UserChannelCreate(m.User.ID) // Get the ID of PM channel
id := uuid.New() // Generate new UUID4
var v Verification // Set up new Verification
v.DiscordID = m.User.ID // ID is what really matters, username is garbage
v.Created = time.Now() // Setup the created time for reasons
v.Code = id.String() // Generate Random UUID
pendingV = append(pendingV, v)
s.ChannelMessageSend(st.ID, "Hello! You have not yet verified with me. Type !sitnet [your sitnet ID here] to verify who you are. You will get an email explaining what to do next. https://web.cs.sunyit.edu/polymc")
}
func fixMentions(s string) string {
defer log.PanicSafe()
var ret string
if !strings.Contains(s, "@") {
return s
}
parts := strings.Split(s, " ")
for _, part := range parts {
if strings.HasPrefix(part, "@") {
var u User
u.Email = strings.Replace(part, "@", "", -1)
u.Retrieve()
ret += fmt.Sprintf("<@!%+v>", u.DiscordID)
} else {
ret += part
}
ret += " "
}
return ret
}
func setupVerifications(s *discordgo.Session, m *discordgo.MessageCreate) {
defer log.PanicSafe()
st, _ := s.UserChannelCreate(m.Author.ID) // Get the ID of PM channel
id := uuid.New() // Generate new UUID4
var v Verification // Set up new Verification
v.DiscordID = m.Author.ID // ID is what really matters, username is garbage
v.Created = time.Now() // Setup the created time for reasons
v.Code = id.String() // Generate Random UUID
pendingV = append(pendingV, v)
s.ChannelMessageSend(st.ID, "Hello! You have not yet verified with me. Type !sitnet [your sitnet ID here] to verify who you are. You will get an email explaining what to do next. https://web.cs.sunyit.edu/polymc")
}
func alphaOnly(s string) bool {
for _, char := range s {
if !strings.Contains(alpha, strings.ToLower(string(char))) {
return false
}
}
return true
}
func handlePM(s *discordgo.Session, m *discordgo.MessageCreate) {
defer log.PanicSafe()
for k, v := range pendingV {
if v.DiscordID == m.Author.ID {
parts := strings.Split(m.Content, " ")
if strings.HasPrefix(m.Content, "!sitnet") {
if len(parts) != 2 || !alphaOnly(parts[1]) || len(parts[1]) > 12 {
s.ChannelMessageSend(m.ChannelID, "You have sent an invalid SITNET ID. Your SITNET ID is your SUNY Poly email address, up until the @sunypoly.edu. For example, urbanc@sunypoly.edu would have a SITNET ID of urbanc. He would say `!sitnet urbanc`")
return
}
v.SITNET = parts[1]
v.sendEmail()
pendingV[k] = v
s.ChannelMessageSend(m.ChannelID, fmt.Sprintf("Thanks! I have sent an email to %+v@sunypoly.edu from %+v with further instructions.", v.SITNET, config.MyEmail))
}
if strings.HasPrefix(m.Content, "!verify") {
if len(parts) != 3 {
s.ChannelMessageSend(m.ChannelID, "You have sent an invalid verification, please ensure you are sending ```!verify $code $minecraftID``` Please ensure there are no extra spaces, also your minecraftID is case sensitive.")
return
}
if parts[1] != v.Code {
s.ChannelMessageSend(m.ChannelID, "You have sent an invalid verification code, please verify using the code from your email.")
return
}
var u User
u.DiscordID = v.DiscordID
u.Email = v.SITNET
u.McUser = strings.Replace(parts[2], "$", "", -1)
if v.SITNET == parts[2] {
s.ChannelMessageSend(m.ChannelID, "SITNET Can not be the same as Minecraft Username. Please append a dollar sign to the end of your minecraft username if it actually is the same as your sitnet. For example urbanc would put urbanc$ as his minecraft username to dismiss this message.")
return
}
log.LogDebug(fmt.Sprintf("Attempting to write %+v from verification %+v", u, v))
err := u.Write()
if err != nil {
s.ChannelMessageSend(m.ChannelID, "There was an issue with your verification. Please check in with an administrator in the #unverified channel.")
return
}
u.McWhitelist()
s.ChannelMessageSend(m.ChannelID, "Welcome! You have successfully verified. The server address is polymc.cs.sunyit.edu - see you there!")
s.GuildMemberRoleRemove(config.GuildID, u.DiscordID, config.MonitorRole)
s.GuildMemberRoleAdd(config.GuildID, u.DiscordID, config.VerifiedRole)
s.GuildMemberNickname(config.GuildID, u.DiscordID, v.SITNET)
pendingV[k] = pendingV[len(pendingV)-1] // Copy last element to index i.
pendingV = pendingV[:len(pendingV)-1] // Truncate slice.
}
}
}
}
func messageCreate(s *discordgo.Session, m *discordgo.MessageCreate) {
defer log.PanicSafe()
if m.Author.ID == s.State.User.ID {
return
}
if m.GuildID == "" {
handlePM(s, m)
return
}
if m.ChannelID == config.MonitorChan && strings.HasPrefix(m.Content, "!verify") {
for _, v := range pendingV {
if v.DiscordID == m.Author.ID {
return
}
}
setupVerifications(s, m)
return
}
if m.ChannelID == config.MonitorChan {
return
}
var u User
u.DiscordID = m.Author.ID
u.Retrieve()
u.Write() // Update last seen
if strings.HasPrefix(m.Content, "!verify") && m.ChannelID != config.AdminChan {
s.ChannelMessageSend(m.ChannelID, "That command ONLY works for unverified users in the unverified channel. Instead, for account resets try !resetme")
return
}
if strings.HasPrefix(m.Content, "!resetme") {
mcCommand(fmt.Sprintf("whitelist remove %+v", u.McUser))
u.Delete()
s.GuildMemberRoleAdd(config.GuildID, m.Author.ID, config.MonitorRole)
s.GuildMemberRoleRemove(config.GuildID, m.Author.ID, config.VerifiedRole)
return
}
if strings.HasPrefix(m.Content, "!online") {
if len(onlineUsers) == 0 {
s.ChannelMessageSend(m.ChannelID, "There are no users online.")
return
}
str := fmt.Sprintf("The following %+v users are online:\n```", len(onlineUsers))
for _, usr := range onlineUsers {
str += fmt.Sprintf("%+v : %+v\n", usr.Email, usr.McUser)
}
str += "```"
s.ChannelMessageSend(m.ChannelID, str)
return
}
if m.ChannelID == config.VerifiedChan {
log.LogDebug(fmt.Sprintf("Discord message from retrieved user %+v", u))
// if debug message shows complete user, you may replace userStr with u.SITNresET
if m.Member.Nick != u.Email {
s.GuildMemberNickname(config.GuildID, m.Author.ID, u.Email)
}
mcSay(fmt.Sprintf("[%+v]: %+v", u.Email, m.Content))
return
}
if m.ChannelID == config.AdminChan {
go handleAdmin(s, m)
}
}
func manualVerifyUser(s *discordgo.Session, m *discordgo.MessageCreate) {
parts := strings.Split(m.Content, " ")
if len(parts) != 4 {
sendAdminDiscordMessage("Usage !verify $SITNET $McUser $DiscordID")
sendAdminDiscordMessage("Please note, DiscordID is the numerical ID, not their username.")
}
var u User
u.Email = parts[1]
u.McUser = parts[2]
u.DiscordID = parts[3]
u.Write()
}
func handleAdmin(s *discordgo.Session, m *discordgo.MessageCreate) {
if !strings.HasPrefix(m.Content, "!") {
return
}
if strings.HasPrefix(m.Content, "!verify") {
manualVerifyUser(s, m)
}
if strings.HasPrefix(m.Content, "!mc") {
mcCommand(strings.Replace(m.Content, "!mc", "", -1))
return
}
if strings.HasPrefix(m.Content, "!wb") {
if strings.Contains(m.Content, "stop") {
config.WbFinished = true
} else {
config.WbFinished = false
}
}
if strings.HasPrefix(m.Content, "!reboot") {
if serverRebooting {
s.ChannelMessageSend(config.AdminChan, fmt.Sprintf("Reboot pending: %+v", time.Until(rebootTS)))
return
}
serverRebooting = true
rebootTS = time.Now().Add(30 * time.Minute)
parts := strings.Split(m.Content, " ")
if len(parts) == 1 {
s.ChannelMessageSend(config.AdminChan, "A reboot has been queued. I will poll for when users log out and then execute.")
timeout := 120
for {
if len(onlineUsers) == 0 || timeout == 0 {
mcExit()
discordExit()
log.LogPanic("Shutting down server from queued reboot.")
}
time.Sleep(15 * time.Second)
timeout--
}
return
}
if len(parts) != 2 && len(parts) != 3 {
s.ChannelMessageSend(config.AdminChan, "You dumbass. I take one or two arguments.")
return
}
when, err := strconv.Atoi(parts[1])
if err != nil {
s.ChannelMessageSend(config.AdminChan, "The first argument must be an int, number of minutes.")
return
}
reminders := 0
if len(parts) == 3 {
reminders, err = strconv.Atoi(parts[2])
if err != nil {
s.ChannelMessageSend(config.AdminChan, "You supplied a second argument.. So that also has to be an int, number of reminders.")
return
}
}
mcReboot(when, reminders)
}
}

25
email.go

@ -0,0 +1,25 @@ @@ -0,0 +1,25 @@
package main
import "fmt"
import "net/smtp"
func (e Email) send() {
message := fmt.Sprintf("From: %s\n", config.MyEmail)
for _, recipient := range e.Recipients {
message += fmt.Sprintf("To: %s\n", recipient)
}
message += fmt.Sprintf("Subject: %s\n", e.Subject)
message += e.Body
log.LogInfo("Message created")
log.LogDebug(message)
log.LogInfo("Sending message")
err := smtp.SendMail(config.SmtpServer,
smtp.PlainAuth("", config.MyEmail, config.EmailPass, config.AuthServer),
config.MyEmail, e.Recipients, []byte(message))
if err != nil {
log.LogErrorType(err)
return
}
log.LogInfo("Email Sent")
}

83
main.go

@ -0,0 +1,83 @@ @@ -0,0 +1,83 @@
package main
import (
"bufio"
"encoding/json"
"io/ioutil"
"os"
"os/signal"
"strings"
"syscall"
"time"
"github.com/rudi9719/loggy"
)
var (
// Logging Setup
logOpts = loggy.LogOpts{
UseStdout: true,
Level: 5,
OutFile: "Minedall.log",
}
log = loggy.NewLogger(logOpts)
config Config
onlineUsers []User
serverRebooting = false
)
func loadConfig() {
var c Config
confFile, _ := ioutil.ReadFile("config.json")
err := json.Unmarshal([]byte(confFile), &c)
if err != nil {
log.LogErrorType(err)
return
}
config = c
}
func saveConfig() {
file, err := json.Marshal(config)
if err != nil {
log.LogErrorType(err)
}
err = ioutil.WriteFile("config.json", file, 0766)
if err != nil {
log.LogErrorType(err)
} else {
log.LogInfo("Config saved.")
}
}
func main() {
loadConfig()
if config.DiscordToken == "" {
time.Sleep(5 * time.Second)
return
}
config.StartTime = time.Now()
go configureDiscord()
go configureMinecraft()
go dbSetup()
// Wait here until CTRL-C or other term signal is received.
log.LogInfo("Minedall 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)
reader := bufio.NewReader(os.Stdin)
for {
text, _ := reader.ReadString('\n')
if strings.Contains(text, "stop") {
saveConfig()
mcExit()
discordExit()
return
}
mcCommand(text)
}
<-sc
mcExit()
discordExit()
}

216
minecraft.go

@ -0,0 +1,216 @@ @@ -0,0 +1,216 @@
package main
import (
"bufio"
"fmt"
"io"
"os/exec"
"regexp"
"strings"
"time"
)
var (
mcOut io.Reader
mcIn io.Writer
mcStop = false
mcLoaded = false
mcRebooting = false
mcWBRunning = false
)
func (u User) McWhitelist() {
mcCommand(fmt.Sprintf("whitelist add %+v", u.McUser))
mcCommand(fmt.Sprintf("nicknames %+v %+v", u.McUser, u.Email))
}
func configureMinecraft() {
log.LogInfo("Starting MinecraftServer")
server := exec.Command("java", "-XX:+UnlockExperimentalVMOptions", "-XX:+UseG1GC", "-Xms4G", "-Xmx8G", "-Dsun.rmi.dgc.server.gcInterval=2147483646", "-XX:G1NewSizePercent=20", "-XX:MaxGCPauseMillis=50", "-XX:G1HeapRegionSize=32M", "-jar", "/opt/minecraft/paper/server.jar", "nogui")
mcIn, _ = server.StdinPipe()
mcOut, _ = server.StdoutPipe()
mcErr, _ := server.StderrPipe()
mcErrScan := bufio.NewScanner(mcErr)
server.Start()
defer server.Wait()
go listenOut()
for mcErrScan.Scan() {
if mcStop {
break
}
log.LogError(mcErrScan.Text())
}
}
func handleMcOnline(s string) {
log.LogDebug("A user has come online or gone offline.")
s = strings.Replace(s, "&e", "", -1)
var u User
parts := strings.Split(s, " ")
log.LogDebug(fmt.Sprintf("%+v", parts))
if parts[2] == "UUID" {
log.LogDebug(fmt.Sprintf("User %+v detected.", parts[5]))
if serverRebooting {
mcCommand(fmt.Sprintf("kick %+v Server reboot pending.", parts[5]))
}
//mcCommand(fmt.Sprintf("kick %+v Server currently unavailable.", parts[5]))
u.McUser = parts[5]
u.Retrieve()
if u.Email == "" {
u.Email = u.McUser
u.McUser = ""
u.Retrieve()
if u.McUser == "" {
sendAdminDiscordMessage(fmt.Sprintf("Unable to verify %+v", parts[5]))
mcCommand(fmt.Sprintf("kick %+v Verified SITNET not found. Admins have been notified.", parts[5]))
return
}
} else if u.Email != parts[5] {
mcCommand(fmt.Sprintf("lp user %+v parent add player", u.McUser))
mcCommand(fmt.Sprintf("nicknames %+v %+v", u.McUser, u.Email))
}
for _, v := range onlineUsers {
if v.Email == u.Email {
return
}
}
onlineUsers = append(onlineUsers, u)
} else {
log.LogDebug(fmt.Sprintf("User %+v detected.", parts[2]))
u.McUser = parts[2]
u.Retrieve()
for k, v := range onlineUsers {
log.LogDebug(fmt.Sprintf("v.McUser: %+v, parts[2]: %+v", v.McUser, parts[2]))
if v.McUser == parts[2] || v.Email == parts[2] {
onlineUsers[k] = onlineUsers[len(onlineUsers)-1] // Copy last element to index i.
onlineUsers = onlineUsers[:len(onlineUsers)-1] // Truncate slice.
}
}
}
u.Write()
log.LogDebug(fmt.Sprintf("Online users: %+v", onlineUsers))
if len(onlineUsers) == 0 && !config.WbFinished {
log.LogInfo("The last user has logged out.")
mcWorldBuilderToggle(true)
} else {
mcWorldBuilderToggle(false)
}
}
func listenOut() {
outScan := bufio.NewScanner(mcOut)
var re = regexp.MustCompile(`INFO\]: <(.*?)> (.*)`)
for outScan.Scan() {
if mcStop {
break
}
output := outScan.Text()
go log.LogInfo(fmt.Sprintf("server.jar: %+v", output))
if !mcLoaded {
if strings.Contains(output, "For help, type \"help\"") {
mcLoaded = true
sendDiscordMessage("Minecraft server is now available.")
mcWorldBuilderToggle(true)
}
continue
}
if strings.Contains(output, "UUID of player") || strings.Contains(output, "left the game") {
go handleMcOnline(output)
}
match := re.FindStringSubmatch(output)
if match != nil {
if match[1] != "Server" {
var u User
u.McUser = match[1]
u.Retrieve()
if u.Email == "" {
u.McUser = ""
u.Email = match[1]
u.Retrieve()
u.Write()
} else if u.Email != match[1] {
mcCommand(fmt.Sprintf("nicknames %+v %+v", u.McUser, u.Email))
}
log.LogDebug(fmt.Sprintf("Minecraft message from retrieved user %+v", u))
go sendDiscordMessage(fmt.Sprintf("[%s]: %s", u.Email, match[2]))
continue
}
} else if mcLoaded && !strings.Contains(output, " INFO]: [Server] [") && !strings.Contains(output, "[WorldBorder]") {
go sendAdminDiscordMessage(output)
}
}
}
func mcWorldBuilderToggle(b bool) {
log.LogDebug("World builder toggled")
if b && !mcWBRunning {
log.LogDebug("Building world!")
mcCommand("wb world fill 500 300 false")
mcCommand("wb fill confirm")
mcWBRunning = true
return
} else if mcWBRunning {
log.LogDebug("Not building world!")
mcCommand("wb fill cancel")
mcWBRunning = false
}
}
func mcSay(message string) {
mcCommand(fmt.Sprintf("say %+v", mcMention(message)))
}
func mcMention(s string) string {
var ret string
if !strings.Contains(s, "@") {
return s
}
parts := strings.Split(s, " ")
for _, part := range parts {
if strings.HasPrefix(part, "<@!") {
var u User
u.DiscordID = strings.Replace(strings.Replace(part, "<@!", "", -1), ">", "", -1)
u.Retrieve()
ret += "@"
ret += u.Email
} else {
ret += part
}
ret += " "
log.LogDebug(ret)
}
return ret
}
func mcCommand(message string) {
mcIn.Write([]byte(message))
mcIn.Write([]byte("\n"))
}
func mcReboot(when int, reminders int) {
if mcRebooting {
return
}
mcRebooting = true
untilReboot := time.Duration(when) * time.Minute
rebootTime := time.Now().Add(untilReboot)
var untilReminder time.Duration
if reminders != 0 {
untilReminder = time.Duration(when / reminders)
}
for {
mcSay(fmt.Sprintf("A reboot has been scheduled for %+v", untilReboot))
if reminders > 0 {
reminders--
time.Sleep(untilReminder)
continue
}
time.Sleep(time.Until(rebootTime))
mcExit()
discordExit()
}
}
func mcExit() {
log.LogCritical("Closing Minecraft (issuing command `stop`)")
mcCommand("stop")
mcStop = true
mcLoaded = false
}

78
types.go

@ -0,0 +1,78 @@ @@ -0,0 +1,78 @@
package main
import "fmt"
import "time"
import "reflect"
type Config struct {
GuildID string
MonitorChan string
VerifiedChan string
AdminChan string
MonitorRole string
VerifiedRole string
AdminRole string
StartTime time.Time
DiscordToken string
MyEmail string
EmailPass string
SmtpServer string
AuthServer string
DbFile string
WbFinished bool
}
type User struct {
DiscordID string
Email string
McUser string
LastSeen time.Time
LastReported time.Time
}
func userGetField(u *User, field string) string {
r := reflect.ValueOf(u)
f := reflect.Indirect(r).FieldByName(field)
return string(f.String())
}
type Report struct {
Time time.Time
Reporter User
Abuser User
Msg string
Target Target
}
type Target struct {
Type string
Place string
}
type Verification struct {
Created time.Time
DiscordID string
Email Email
SITNET string
Code string
}
func (v Verification) sendEmail() {
var e Email
e.Recipients = append(e.Recipients, fmt.Sprintf("%+v@sunypoly.edu", v.SITNET))
e.Subject = "Minecraft Verification"
e.Body = fmt.Sprintf("Hello!\n\nYou are getting this email because you joined the Minecraft Discord channel for SUNY Poly. If you would like to verify your account so that you can use our Discord server and play on the SUNY Poly Minecraft server, please private message the Minedall bot with the command !verify %+v [your case sensitive minecraft username here]. If you are having trouble with this action, please send a message in the \"unverified\" channel, and a moderator will assist you with the process. \n\nWe hope to see you soon in our server!\nCSNet Staff\nadmins@cs.sunyit.edu", v.Code)
e.send()
}
type Email struct {
Recipients []string
Subject string
Body string
}
type McAccount struct {
id string
name string
}
type McAccountArr []McAccount

153
userdb.go

@ -0,0 +1,153 @@ @@ -0,0 +1,153 @@
package main
import (
"database/sql"
"fmt"
"time"
_ "github.com/mattn/go-sqlite3"
)
// Inital func to ensure database is properly setup
func dbSetup() {
database, _ := sql.Open("sqlite3", config.DbFile)
defer database.Close()
statement, _ := database.Prepare("CREATE TABLE IF NOT EXISTS users (email TEXT PRIMARY KEY, discordID TEXT, mcUser TEXT, lastSeen TEXT, lastReported TEXT)")
statement.Exec()
statement, _ = database.Prepare("CREATE TABLE IF NOT EXISTS reports (email TEXT PRIMARY KEY, reportedBy TEXT, reportMsg TEXT, reportTime TEXT)")
statement.Exec()
}
// Write a user to database, also update last seen to time.Now()
func (u User) Write() error {
database, _ := sql.Open("sqlite3", config.DbFile)
defer database.Close()
if u.Email == "" || u.DiscordID == "" || u.McUser == "" {
log.LogDebug(fmt.Sprintf("Attempted to insert invalid user. DENIED.\n%+v", u))
return nil
}
statement, err := database.Prepare("INSERT INTO users (email, discordID, mcUser, lastSeen, lastReported) VALUES (?, ?, ?, ?, ?)")
if err != nil {
return err
}
log.LogDebug(fmt.Sprintf("Running insert on %+v", u))
statement.Exec(u.Email, u.DiscordID, u.McUser, time.Now(), u.LastReported)
return nil
}
// Delete a user from the database.
func (u User) Delete() error {
database, err := sql.Open("sqlite3", config.DbFile)
if err != nil {
return err
}
defer database.Close()
statement, err := database.Prepare("DELETE FROM users WHERE email=? mcUser=? discordID=?")
if err != nil {
return err
}
_, err = statement.Exec(u.Email, u.McUser, u.DiscordID)
return err
}
// Get a user by a field (deprecated?)
func (u User) GetUserBy(userfield string) {
database, _ := sql.Open("sqlite3", config.DbFile)
defer database.Close()
rows, _ := database.Query("SELECT * FROM users WHERE ? = ?", userfield, userGetField(&u, userfield))
for rows.Next() {
rows.Scan(&u.Email, &u.DiscordID, &u.McUser, &u.LastSeen, &u.LastReported)
}
}
// Retrieve a user and fill in missing values
func (u *User) Retrieve() error {
database, _ := sql.Open("sqlite3", config.DbFile)
defer database.Close()
var parms []interface{}
statement := "SELECT * FROM users WHERE"
first := true
if u.DiscordID != "" {
parms = append(parms, u.DiscordID)
statement += " discordID = ? "
first = false
}
if u.Email != "" {
parms = append(parms, u.Email)
if !first {
statement += " AND "
} else {
first = false
}
statement += " email = ?"
}
if u.McUser != "" {
parms = append(parms, u.McUser)
if !first {
statement += " AND "
} else {
first = false
}
statement += " mcUser = ?"
}
log.LogDebug(fmt.Sprintf("Attempting to query using the following statement: %+v\nParams: %+v", statement, parms))
rows, err := database.Query(statement, parms...)
if err != nil {
return err
}
for rows.Next() {
rows.Scan(&u.Email, &u.DiscordID, &u.McUser, &u.LastSeen, &u.LastReported)
}
go u.Write()
log.LogDebug(fmt.Sprintf("DB Returned: %+v", u))
return nil
}
// Get a slice of all users within the database.
func GetAllUsers() []User {
database, _ := sql.Open("sqlite3", config.DbFile)
defer database.Close()
rows, _ := database.Query("SELECT * FROM users")
var users []User
for rows.Next() {
var u User // Don't need anything else for this
rows.Scan(&u.Email, &u.DiscordID, &u.McUser, &u.LastSeen, &u.LastReported)
users = append(users, u) // You wanna get all users, not just the last one right?
}
return users
}
// Get Reports per user via SITNET
func (u User) GetReports() []Report {
database, _ := sql.Open("sqlite3", config.DbFile)
defer database.Close()
rows, _ := database.Query("SELECT * FROM reports WHERE email = ?", u.Email)
var reports []Report
for rows.Next() {
var r Report
rows.Scan(&r.Abuser, &r.Reporter, &r.Msg, &r.Time)
reports = append(reports, r)
}
return reports
}
// Write a report to the database
func (r Report) Write() error {
//(email TEXT PRIMARY KEY, reportedBy TEXT, reportMsg TEXT, reportTime TEXT)
log.LogDebug(fmt.Sprintf("Attempting Adding report of %+v", r.Abuser))
database, _ := sql.Open("sqlite3", config.DbFile)
defer database.Close()
statement, err := database.Prepare("INSERT INTO reports (email, reportedBy, reportMsg, reportTime) VALUES (?, ?, ?, ?)")
if err != nil {
log.LogDebug(fmt.Sprintf("Adding report of %+v failed with error %+v", r.Abuser, err))
return err
}
_, err = statement.Exec(r.Abuser.Email, r.Reporter.Email, r.Msg, r.Time)
if err != nil {
log.LogDebug(fmt.Sprintf("Execution failed with error %+v", err))
return err
}
return nil
}

1
verification.go

@ -0,0 +1 @@ @@ -0,0 +1 @@
package main
Loading…
Cancel
Save