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.

267 lines
7.7 KiB

package main
import (
"flag"
"fmt"
"os"
"os/signal"
"strings"
"syscall"
"github.com/bwmarrin/discordgo"
)
var (
dg *discordgo.Session
token string
gitCommit string
ghostTypes []Spookster
games = make(map[string]Game)
fingeyEmoji = "🖐"
freezingEmoji = "❄"
spiritBoxEmoji = "📻"
ghostWritingEmoji = "📖"
emf5Emoji = "🚥"
ghostOrbsEmoji = "⚪"
deleteEmoji = "❌"
)
func init() {
flag.StringVar(&token, "t", "", "Bot Token")
flag.Parse()
}
func main() {
if token == "" {
fmt.Println("No token provided. Please run: phasmobot -t <bot token>")
}
go setupGhostTypes()
var err error
dg, err = discordgo.New("Bot " + token)
if err != nil {
fmt.Println("Unable to create bot using token.")
}
err = dg.Open()
if err != nil {
fmt.Println("Unable to create bot using token.")
}
dg.AddHandler(ready)
dg.AddHandler(messageCreate)
dg.AddHandler(readReactions)
sc := make(chan os.Signal, 1)
signal.Notify(sc, syscall.SIGINT, syscall.SIGTERM, os.Interrupt)
<-sc
dg.Close()
}
func ready(s *discordgo.Session, event *discordgo.Ready) {
// Set the playing status.
s.UpdateGameStatus(0, fmt.Sprintf("PhasmoBot %+v", gitCommit))
}
func readReactions(s *discordgo.Session, m *discordgo.MessageReactionAdd) {
if m.UserID == s.State.User.ID {
return
}
if m.Emoji.Name == deleteEmoji {
msg, _ := s.ChannelMessage(m.ChannelID, m.MessageID)
if msg.Author.ID == s.State.User.ID {
s.ChannelMessageDelete(m.ChannelID, m.MessageID)
}
return
}
if _, ok := games[m.ChannelID]; !ok {
return
}
fmt.Println("Checking reaction from ", m.UserID)
g := games[m.ChannelID]
if m.Emoji.Name == fingeyEmoji {
g.Evidence = append(g.Evidence, EMF5)
} else if m.Emoji.Name == freezingEmoji {
g.Evidence = append(g.Evidence, FreezingTemps)
} else if m.Emoji.Name == spiritBoxEmoji {
g.Evidence = append(g.Evidence, SpiritBox)
} else if m.Emoji.Name == ghostWritingEmoji {
g.Evidence = append(g.Evidence, GhostWriting)
} else if m.Emoji.Name == emf5Emoji {
g.Evidence = append(g.Evidence, EMF5)
} else if m.Emoji.Name == ghostOrbsEmoji {
g.Evidence = append(g.Evidence, GhostOrbs)
} else {
go s.MessageReactionRemove(m.ChannelID, g.PostID, m.Emoji.ID, m.UserID)
}
s.MessageReactionRemove(m.ChannelID, g.PostID, fingeyEmoji, "@me")
s.MessageReactionRemove(m.ChannelID, g.PostID, freezingEmoji, "@me")
s.MessageReactionRemove(m.ChannelID, g.PostID, spiritBoxEmoji, "@me")
s.MessageReactionRemove(m.ChannelID, g.PostID, ghostWritingEmoji, "@me")
s.MessageReactionRemove(m.ChannelID, g.PostID, emf5Emoji, "@me")
s.MessageReactionRemove(m.ChannelID, g.PostID, ghostOrbsEmoji, "@me")
g.EliminateGhosts(g.Evidence[len(g.Evidence)-1])
for _, v := range g.PossibleEvidence {
switch v {
case 0:
s.MessageReactionAdd(m.ChannelID, g.PostID, emf5Emoji)
case 1:
s.MessageReactionAdd(m.ChannelID, g.PostID, freezingEmoji)
case 2:
s.MessageReactionAdd(m.ChannelID, g.PostID, spiritBoxEmoji)
case 3:
s.MessageReactionAdd(m.ChannelID, g.PostID, ghostWritingEmoji)
case 4:
s.MessageReactionAdd(m.ChannelID, g.PostID, fingeyEmoji)
case 5:
s.MessageReactionAdd(m.ChannelID, g.PostID, ghostOrbsEmoji)
}
}
if len(g.Evidence) == 3 {
s.GuildMemberNickname(m.GuildID, "@me", "")
msg, _ := s.ChannelMessageSend(m.ChannelID, fmt.Sprintf("%+v was a %+v", g.Ghost.GhostName, g.PossibleGhosts[0].GhostType))
s.MessageReactionAdd(m.ChannelID, g.PostID, deleteEmoji)
s.MessageReactionAdd(m.ChannelID, msg.ID, deleteEmoji)
}
games[m.ChannelID] = g
}
func messageCreate(s *discordgo.Session, m *discordgo.MessageCreate) {
if m.Author.ID == s.State.User.ID {
return
}
if !strings.HasPrefix(m.Content, "!") {
return
}
if _, ok := games[m.ChannelID]; !ok || strings.HasPrefix(m.Content, "!reset") {
games[m.ChannelID] = Game{
Identifier: m.ChannelID,
}
}
g := games[m.ChannelID]
parts := strings.Split(m.Content, " ")
if strings.HasPrefix(m.Content, "!name") {
g.Ghost.GhostName = strings.Join(parts[1:], " ")
s.GuildMemberNickname(m.GuildID, "@me", g.Ghost.GhostName)
}
if strings.HasPrefix(m.Content, "!room") {
if len(parts) == 2 {
g.RoomID = parts[1]
} else {
if g.RoomID != "" {
msg, _ := s.ChannelMessageSend(m.ChannelID, fmt.Sprintf("The room code is `%+v`", g.RoomID))
s.MessageReactionAdd(m.ChannelID, msg.ID, deleteEmoji)
}
}
}
if strings.HasPrefix(m.Content, "!o") {
if strings.Contains(m.Content, "emf") {
g.Objective = append(g.Objective, EMF)
}
if strings.Contains(m.Content, "photo") {
g.Objective = append(g.Objective, Photo)
}
if strings.Contains(m.Content, "event") {
g.Objective = append(g.Objective, Event)
}
if strings.Contains(m.Content, "crucifix") {
g.Objective = append(g.Objective, Crucifix)
}
if strings.Contains(m.Content, "motion") {
g.Objective = append(g.Objective, Motion)
}
if strings.Contains(m.Content, "clean") {
g.Objective = append(g.Objective, SmudgeCleanse)
}
if strings.Contains(m.Content, "hunt") {
g.Objective = append(g.Objective, SmudgeHunt)
}
if strings.Contains(m.Content, "salt") {
g.Objective = append(g.Objective, Salt)
}
if strings.Contains(m.Content, "candle") {
g.Objective = append(g.Objective, Candle)
}
if strings.Contains(m.Content, "sanity") {
g.Objective = append(g.Objective, LowSanity)
}
if strings.Contains(m.Content, "escape") {
g.Objective = append(g.Objective, MemberEscape)
}
if strings.Contains(m.Content, "death") {
g.Objective = append(g.Objective, NoDeaths)
}
}
if strings.HasPrefix(m.Content, "!c") {
if strings.Contains(m.Content, "emf") {
g.CompleteObjective(EMF, s)
}
if strings.Contains(m.Content, "photo") {
g.CompleteObjective(Photo, s)
}
if strings.Contains(m.Content, "event") {
g.CompleteObjective(Event, s)
}
if strings.Contains(m.Content, "crucifix") {
g.CompleteObjective(Crucifix, s)
}
if strings.Contains(m.Content, "motion") {
g.CompleteObjective(Motion, s)
}
if strings.Contains(m.Content, "clean") {
g.CompleteObjective(SmudgeCleanse, s)
}
if strings.Contains(m.Content, "hunt") {
g.CompleteObjective(SmudgeHunt, s)
}
if strings.Contains(m.Content, "salt") {
g.CompleteObjective(Salt, s)
}
if strings.Contains(m.Content, "candle") {
g.CompleteObjective(Candle, s)
}
if strings.Contains(m.Content, "sanity") {
g.CompleteObjective(LowSanity, s)
}
if strings.Contains(m.Content, "escape") {
g.CompleteObjective(MemberEscape, s)
}
if strings.Contains(m.Content, "death") {
g.CompleteObjective(NoDeaths, s)
}
}
if len(g.Objective) == 3 && g.PostID == "" {
post, _ := s.ChannelMessageSend(m.ChannelID, "The investigation begins! Click below to log evidence.")
g.PossibleGhosts = append(g.PossibleGhosts, ghostTypes...)
g.PostID = post.ID
go s.MessageReactionAdd(m.ChannelID, post.ID, fingeyEmoji)
go s.MessageReactionAdd(m.ChannelID, post.ID, freezingEmoji)
go s.MessageReactionAdd(m.ChannelID, post.ID, spiritBoxEmoji)
go s.MessageReactionAdd(m.ChannelID, post.ID, ghostWritingEmoji)
go s.MessageReactionAdd(m.ChannelID, post.ID, emf5Emoji)
go s.MessageReactionAdd(m.ChannelID, post.ID, ghostOrbsEmoji)
}
games[m.ChannelID] = g
}
func (g *Game) CompleteObjective(objective int, s *discordgo.Session) {
var tasks []int
ret := "Current objectives: ``` \n"
for _, v := range g.Objective {
if v != objective {
tasks = append(tasks, v)
ret += fmt.Sprintf("%+v\n", objectiveToStr(v))
}
}
ret += "```"
msg, err := s.ChannelMessageSend(g.Identifier, ret)
if err == nil {
s.MessageReactionAdd(g.Identifier, msg.ID, deleteEmoji)
} else {
fmt.Println(err)
fmt.Println(ret)
}
g.Objective = tasks
games[g.Identifier] = *g
}