@ -4,14 +4,8 @@ import (
"github.com/bwmarrin/discordgo"
"strings"
"log"
"git.chiefnoah.tech/chiefnoah/GoGetMeHentai/danbooru"
"git.chiefnoah.tech/chiefnoah/GoGetMeHentai/redditbooru"
"git.chiefnoah.tech/chiefnoah/GoGetMeHentai/database"
"net/url"
"io/ioutil"
"math/rand"
"encoding/base64"
"git.chiefnoah.tech/chiefnoah/GoGetMeHentai/config"
"../config"
"../database"
"time"
"strconv"
)
@ -20,100 +14,100 @@ import (
== == == == == == == == == == == == == == == == == == == == == == == == == == == == == == == == == == == == == == == == == == == == == == == == =
* /
var help = CommandProcess {
Triggers : map [ string ] interface { } { "help" : nil } ,
Run : nil ,
Triggers : map [ string ] interface { } { "help" : nil } ,
Run : nil ,
AdditionalParams : [ ] string { } ,
DeleteCommand : true ,
Description : "Displays this dialog" ,
DeleteCommand : true ,
Description : "Displays this dialog" ,
}
var dbooru = CommandProcess {
Triggers : map [ string ] interface { } { "d" : nil , "danbooru" : nil , "moe" : nil } ,
Run : danbooruSearch ,
Triggers : map [ string ] interface { } { "d" : nil , "danbooru" : nil , "moe" : nil } ,
Run : danbooruSearch ,
AdditionalParams : [ ] string { "rating:safe" } ,
DeleteCommand : false ,
Description : "Searches danbooru for tags. Format is ]d [tag, tag, etc.]" ,
DeleteCommand : false ,
Description : "Searches danbooru for tags. Format is ]d [tag, tag, etc.]" ,
}
var dfetch = CommandProcess {
Triggers : map [ string ] interface { } { "search" : nil , "fetch" : nil } ,
Run : danbooruSearch ,
Triggers : map [ string ] interface { } { "search" : nil , "fetch" : nil } ,
Run : danbooruSearch ,
AdditionalParams : [ ] string { } ,
DeleteCommand : true ,
Description : "same as d/danbooru/moe but doesn't delete the query message." ,
DeleteCommand : true ,
Description : "same as d/danbooru/moe but doesn't delete the query message." ,
}
var anime = CommandProcess {
Triggers : map [ string ] interface { } { "a" : nil , "anime" : nil , "show" : nil } ,
Run : myAnimeListSearch ,
Triggers : map [ string ] interface { } { "a" : nil , "anime" : nil , "show" : nil } ,
Run : myAnimeListSearch ,
AdditionalParams : [ ] string { } ,
DeleteCommand : true ,
Description : "Not yet implemented." ,
DeleteCommand : true ,
Description : "Not yet implemented." ,
}
var manga = CommandProcess {
Triggers : map [ string ] interface { } { "m" : nil , "manga" : nil } ,
Run : mangaSearch ,
Triggers : map [ string ] interface { } { "m" : nil , "manga" : nil } ,
Run : mangaSearch ,
AdditionalParams : [ ] string { } ,
Description : "Not yet implemented." ,
Description : "Not yet implemented." ,
}
var hentai = CommandProcess {
Triggers : map [ string ] interface { } { "h" : nil , "lewd" : nil , "hentai" : nil } ,
Run : danbooruSearch ,
Triggers : map [ string ] interface { } { "h" : nil , "lewd" : nil , "hentai" : nil } ,
Run : danbooruSearch ,
AdditionalParams : [ ] string { "rating:explicit" } ,
DeleteCommand : true ,
Description : "Searches danbooru using the explicit tag. NSFW! Format is ]h [tag, tag, etc.]" ,
DeleteCommand : true ,
Description : "Searches danbooru using the explicit tag. NSFW! Format is ]h [tag, tag, etc.]" ,
}
var redditBooru = CommandProcess {
Triggers : map [ string ] interface { } { "rb" : nil , "redditbooru" : nil , } ,
Run : redditBooruSearch ,
Triggers : map [ string ] interface { } { "rb" : nil , "redditbooru" : nil , } ,
Run : redditBooruSearch ,
AdditionalParams : [ ] string { } ,
DeleteCommand : true ,
Description : "Searches RedditBooru for the provided tags. Format is ]rb [tag, tag, etc.]" ,
DeleteCommand : true ,
Description : "Searches RedditBooru for the provided tags. Format is ]rb [tag, tag, etc.]" ,
}
var lennyFace = CommandProcess {
Triggers : map [ string ] interface { } { "lenny" : nil , "asianlenny" : nil , "apple" : nil } ,
Run : lennyFaceReply ,
Triggers : map [ string ] interface { } { "lenny" : nil , "asianlenny" : nil , "apple" : nil } ,
Run : lennyFaceReply ,
AdditionalParams : [ ] string { } ,
DeleteCommand : true ,
Description : "Prints a lenny face to the chat." ,
DeleteCommand : true ,
Description : "Prints a lenny face to the chat." ,
}
//Does exact opposite of what you'd expect
var loli = CommandProcess {
Triggers : map [ string ] interface { } { " loli": nil , "anands-favorite ": nil } ,
Run : danbooruSearch ,
var pettanko = CommandProcess {
Triggers : map [ string ] interface { } { " anands-favorite": nil , "pettanko ": nil } ,
Run : danbooruSearch ,
AdditionalParams : [ ] string { "+small_breasts" } ,
DeleteCommand : false ,
Description : "Anands favorite search. Finds best chest size images." ,
DeleteCommand : false ,
Description : "Anands favorite search. Finds best chest size images." ,
}
var profile = CommandProcess {
Triggers : map [ string ] interface { } { "profile" : nil , "pr" : nil } ,
Run : randomProfileImage ,
Triggers : map [ string ] interface { } { "profile" : nil , "pr" : nil } ,
Run : randomProfileImage ,
AdditionalParams : [ ] string { } ,
DeleteCommand : true ,
Description : "Changes the profile picture of the bot." ,
DeleteCommand : true ,
Description : "Changes the profile picture of the bot." ,
}
var echo = CommandProcess {
Triggers : map [ string ] interface { } { "echo" : nil , "say" : nil } ,
Run : echoCommand ,
Triggers : map [ string ] interface { } { "echo" : nil , "say" : nil } ,
Run : echoCommand ,
AdditionalParams : [ ] string { } ,
DeleteCommand : true ,
Description : "Make the bot say things for you." ,
DeleteCommand : true ,
Description : "Make the bot say things for you." ,
}
/ *
== == == == == == == == == == == == == == == == == == == == == == == == == == == == == == == == == == == == == == == == == == == == == == == == =
* /
//Commands MUST be specified here to be checked.
var enabledCommands [ ] CommandProcess = [ ] CommandProcess { dbooru , dfetch , anime , hentai , loli , manga , redditBooru , lennyFace , profile , echo }
var enabledCommands [ ] CommandProcess = [ ] CommandProcess { dbooru , dfetch , anime , hentai , pettanko , manga , redditBooru , lennyFace , profile , echo }
//Wraps command triggers, additional parameters, and explicitly defines the function to be called when a command is typed
type CommandProcess struct {
Triggers map [ string ] interface { } //Maps for fast lookup, we don't actually care about what they hold
Run func ( * discordgo . Session , * discordgo . Message , [ ] string , bool ) //I explicity define a function that implements Command so we can just loop through all the CommandProcesses and call Run generically
AdditionalParams [ ] string
DeleteCommand bool
Description string
Description string
}
var cfg * config . ConfigWrapper
func Init ( ) {
cfg = config . LoadConfig ( )
}
@ -141,7 +135,7 @@ func ParseCommand(s *discordgo.Session, c *discordgo.Message) {
} else {
timeoutMessage ( s , c , d )
}
//Explicitly check this one otherwise we get a circular reference
//Explicitly check this one otherwise we get a circular reference
}
}
if contains ( help . Triggers , command ) {
@ -151,8 +145,8 @@ func ParseCommand(s *discordgo.Session, c *discordgo.Message) {
}
func timeoutMessage ( s * discordgo . Session , c * discordgo . Message , timeLeft int64 ) {
message , err := s . ChannelMessageSend ( c . ChannelID , "You're going to fast <@!" + c . Author . ID + ">! please wait " +
strconv . Itoa ( int ( cfg . AppConfig . CommandTimeout - timeLeft ) ) + " more seconds" )
message , err := s . ChannelMessageSend ( c . ChannelID , "You're going to fast <@!" + c . Author . ID + ">! please wait " +
strconv . Itoa ( int ( cfg . AppConfig . CommandTimeout - timeLeft ) ) + " more seconds" )
if err != nil || message == nil {
log . Printf ( "Unable to send message to channel: %s" , err )
}
@ -177,156 +171,3 @@ func contains(set map[string]interface{}, s string) bool {
_ , ok := set [ s ]
return ok
}
func helpCommand ( s * discordgo . Session , c * discordgo . Message , tags [ ] string , removeCommand bool ) {
output := ""
for _ , command := range enabledCommands {
for trigger := range command . Triggers {
output += trigger + ", "
}
output += " - " + command . Description + "\n"
}
message , err := s . ChannelMessageSend ( c . ChannelID , output )
if err != nil || message == nil {
log . Printf ( "Unable to send messagea: %s" , err )
}
if removeCommand {
s . ChannelMessageDelete ( c . ChannelID , c . ID )
}
}
//Implements Command interface
//Searches danbooru for the provided tags
func danbooruSearch ( s * discordgo . Session , c * discordgo . Message , tags [ ] string , removeCommand bool ) {
if len ( c . Content ) < 2 {
return
}
query := strings . Split ( c . Content , " " ) [ 1 : ]
query = append ( query , tags ... )
post , err := danbooru . SearchPost ( query )
messageContent := ""
if err != nil || tags == nil || post . LargeFileUrl == "" {
log . Printf ( "Unable to retrieve an image" )
messageContent = "I'm sorry, I was unable to find any images, @" + c . Author . Username + "#" + c . Author . Discriminator + " senpai."
} else {
messageContent = "I was able to find this for you @" + c . Author . Username + "#" + c . Author . Discriminator + " with tags (" + strings . Join ( tags , ", " ) + ") " + danbooru . BASE + post . LargeFileUrl
addCommandEntry ( s , c )
}
message , err := s . ChannelMessageSend ( c . ChannelID , messageContent )
if err != nil || message == nil {
log . Printf ( "Unable to send messagea: %s" , err )
}
if removeCommand {
s . ChannelMessageDelete ( c . ChannelID , c . ID )
}
}
func myAnimeListSearch ( s * discordgo . Session , c * discordgo . Message , a [ ] string , removeCommand bool ) {
}
func hentaiSearch ( s * discordgo . Session , c * discordgo . Message , a [ ] string , removeCommand bool ) {
}
func mangaSearch ( s * discordgo . Session , c * discordgo . Message , a [ ] string , removeCommand bool ) {
}
func redditBooruSearch ( s * discordgo . Session , c * discordgo . Message , additionalParams [ ] string , removeCommand bool ) {
if len ( c . Content ) < 2 {
return
}
query := strings . Split ( c . Content , " " ) [ 1 : ] //drop the command part of the message
p := ""
if len ( query ) == 1 {
p = query [ 0 ]
} else if len ( query ) > 1 {
p = url . QueryEscape ( strings . Join ( query , " " ) ) //join the params with spaces, and URL Query escape them
}
log . Printf ( "Retrieved arguments: %+s" , query )
post , err := redditbooru . Search ( p )
messageContent := ""
if err != nil || query == nil || post . CDNURL == "" {
log . Print ( "Unable to retrieve image from Redditbooru" )
messageContent = "I'm sorry, I was unable to find any images for that query, @" + c . Author . Username + "#" + c . Author . Discriminator + " senpai."
} else {
messageContent = "I found this for you @" + c . Author . Username + "#" + c . Author . Discriminator + " with query \"" + strings . Join ( query , ", " ) + "\"" + post . CDNURL
addCommandEntry ( s , c )
}
message , err := s . ChannelMessageSend ( c . ChannelID , messageContent )
if err != nil || message == nil {
log . Print ( "Unable to send message to discord: " , err )
}
if removeCommand {
s . ChannelMessageDelete ( c . ChannelID , c . ID )
}
}
func lennyFaceReply ( s * discordgo . Session , c * discordgo . Message , additionalParams [ ] string , removeCommand bool ) {
if len ( c . Content ) < 2 {
return
}
command := strings . Split ( c . Content , " " ) [ 0 ] [ 1 : ]
messageContent := ""
if command == "lenny" {
messageContent = "( ͡° ͜ʖ ͡°)"
} else if command == "asianlenny" {
messageContent = "( ͡° ╭ʖ╮ ͡° )"
} else if command == "apple" {
messageContent = "\\_(:3 」__⁄ __ )_"
}
addCommandEntry ( s , c )
message , err := s . ChannelMessageSend ( c . ChannelID , messageContent )
if err != nil || message == nil {
log . Print ( "Unable to send message to discord: " , err )
}
if removeCommand {
s . ChannelMessageDelete ( c . ChannelID , c . ID )
}
}
func randomProfileImage ( s * discordgo . Session , c * discordgo . Message , additionalParams [ ] string , removeCommand bool ) {
botUser , err := s . User ( "@me" )
if err != nil {
log . Print ( "Unable to get bot user!" )
return
}
files , err := ioutil . ReadDir ( "./images" )
if err != nil || len ( files ) == 0 {
log . Print ( "Unable to scan directory for images: " , err )
return
}
r := rand . Intn ( len ( files ) )
image := "data:image/jpeg;base64,"
data , err := ioutil . ReadFile ( "./images/" + files [ r ] . Name ( ) )
if err != nil {
log . Print ( "Unable to load image file :(, " , err )
return
}
image += base64 . StdEncoding . EncodeToString ( data )
_ , err = s . UserUpdate ( "" , "" , botUser . Username , image , "" )
if err != nil {
log . Print ( "Unable to update profile picture " , err )
}
if removeCommand {
s . ChannelMessageDelete ( c . ChannelID , c . ID )
}
}
func echoCommand ( s * discordgo . Session , c * discordgo . Message , additionalParams [ ] string , removeCommand bool ) {
messageSplit := strings . Split ( c . Content , " " ) [ 1 : ]
messageContent := strings . Join ( messageSplit , " " )
message , err := s . ChannelMessageSend ( c . ChannelID , messageContent )
if err != nil || message == nil {
log . Print ( "Unable to send message to discord: " , err )
}
if removeCommand {
s . ChannelMessageDelete ( c . ChannelID , c . ID )
}
}