Compare commits

..

3 commits

12 changed files with 599 additions and 33 deletions

42
commands/help.go Normal file
View file

@ -0,0 +1,42 @@
package commands
import (
"fmt"
"strings"
"github.com/Cynosphere/comcord/state"
"github.com/bwmarrin/discordgo"
"github.com/mgutz/ansi"
)
const format string = " %s - %s%s"
func HelpCommand(session *discordgo.Session) {
noColor := state.HasNoColor()
fmt.Println("\r\nCOMcord (c)left 2023\n\r")
index := 0
for key, cmd := range GetAllCommands() {
str := fmt.Sprintf(format, key, cmd.Description, "")
length := len(str)
padding := strings.Repeat(" ", 25 - length)
if noColor {
fmt.Printf(format, key, cmd.Description, padding)
} else {
coloredKey := ansi.Color(key, "yellow+b")
fmt.Printf(format, coloredKey, cmd.Description, padding)
}
index++
if index % 3 == 0 {
fmt.Print("\n\r")
}
}
if index % 3 != 0 {
fmt.Print("\n\r")
}
fmt.Println("\r\nTo begin TALK MODE, press [SPACE]\n\r")
}

33
commands/main.go Normal file
View file

@ -0,0 +1,33 @@
package commands
import "github.com/bwmarrin/discordgo"
var commandMap map[string]Command
type Command struct {
Run func(*discordgo.Session)
Description string
}
func Setup() {
commandMap = make(map[string]Command)
commandMap["q"] = Command{
Run: QuitCommand,
Description: "quit comcord",
}
commandMap["h"] = Command{
Run: HelpCommand,
Description: "command help",
}
}
func GetCommand(key string) (Command, bool) {
command, has := commandMap[key]
return command, has
}
func GetAllCommands() map[string]Command {
return commandMap
}

12
commands/quit.go Normal file
View file

@ -0,0 +1,12 @@
package commands
import (
"os"
"github.com/bwmarrin/discordgo"
)
func QuitCommand(session *discordgo.Session) {
session.Close()
os.Exit(0)
}

59
commands/send.go Normal file
View file

@ -0,0 +1,59 @@
package commands
import (
"fmt"
"strings"
"github.com/Cynosphere/comcord/lib"
"github.com/Cynosphere/comcord/state"
"github.com/bwmarrin/discordgo"
"github.com/ergochat/readline"
"github.com/mgutz/ansi"
)
func SendMode(session *discordgo.Session) {
channelId := state.GetCurrentChannel()
if channelId == "" {
fmt.Print("<not in a channel>\n\r")
return
}
state.SetInPrompt(true)
length := len(session.State.User.Username) + 2
curLength := state.GetNameLength()
prompt := fmt.Sprintf("[%s]%s", session.State.User.Username, strings.Repeat(" ", (curLength - length) + 1))
if !state.HasNoColor() {
prompt = ansi.Color(prompt, "cyan+b")
}
input, _ := readline.NewFromConfig(&readline.Config{
Prompt: prompt,
UniqueEditLine: true,
})
defer input.Close()
out, err := input.Readline()
out = strings.TrimSpace(out)
input.Close()
if out == "" {
if err == readline.ErrInterrupt {
fmt.Print("^C<no message sent>\n\r")
} else {
fmt.Print(prompt, "<no message sent>\n\r")
}
} else {
fmt.Print(prompt, out, "\n\r")
_, err := session.ChannelMessageSend(channelId, out)
if err != nil {
fmt.Print("<failed to send message: ", err, ">\n\r")
}
// TODO: update afk state
}
state.SetInPrompt(false)
lib.ProcessQueue(session)
}

View file

@ -1,9 +0,0 @@
package events
import "github.com/bwmarrin/discordgo"
func MessageCreate(session *discordgo.Session, msg *discordgo.MessageCreate) {
if (msg.Author.ID == session.State.User.ID) {
return
}
}

34
events/messages.go Normal file
View file

@ -0,0 +1,34 @@
package events
import (
"github.com/Cynosphere/comcord/lib"
"github.com/Cynosphere/comcord/state"
"github.com/bwmarrin/discordgo"
)
func MessageCreate(session *discordgo.Session, msg *discordgo.MessageCreate) {
if msg.Author.ID == session.State.User.ID {
return
}
channel, err := session.State.Channel(msg.ChannelID)
if err != nil {
return
}
isDM := channel.Type == discordgo.ChannelTypeDM || channel.Type == discordgo.ChannelTypeGroupDM
if state.IsInPrompt() {
state.AddMessageToQueue(msg.Message)
} else {
lib.ProcessMessage(session, msg.Message, lib.MessageOptions{NoColor: state.HasNoColor()})
}
if isDM {
state.SetLastDM(msg.ChannelID)
}
}
func MessageUpdate(session *discordgo.Session, msg *discordgo.MessageUpdate) {
}

View file

@ -3,11 +3,31 @@ package events
import ( import (
"fmt" "fmt"
"github.com/Cynosphere/comcord/state"
"github.com/bwmarrin/discordgo" "github.com/bwmarrin/discordgo"
"github.com/fatih/color" "github.com/mgutz/ansi"
) )
func Ready(session *discordgo.Session, event *discordgo.Ready) { func Ready(session *discordgo.Session, event *discordgo.Ready) {
fmt.Print("Logged in as: ") fmt.Printf("\rLogged in as: %s\n\r", ansi.Color(fmt.Sprintf("%s (%s)", session.State.User.Username, session.State.User.ID), "yellow"))
color.Yellow("%s (%s)", session.State.User.Username, session.State.User.ID)
state.SetNameLength(len(session.State.User.Username) + 2)
defaultGuild := state.GetConfigValue("defaultGuild")
defaultChannel := state.GetConfigValue("defaultChannel")
if defaultGuild != "" {
_, err := session.State.Guild(defaultGuild)
if err == nil {
if defaultChannel != "" {
state.SetCurrentChannel(defaultChannel)
state.SetLastChannel(defaultGuild, defaultChannel)
}
} else {
fmt.Println("\r% This account is not in the defined default guild.")
}
} else {
if defaultChannel != "" {
fmt.Println("\r% Default channel defined without defining default guild.")
}
}
} }

11
go.mod
View file

@ -3,11 +3,18 @@ module github.com/Cynosphere/comcord
go 1.20 go 1.20
require ( require (
atomicgo.dev/keyboard v0.2.9 // indirect
github.com/bwmarrin/discordgo v0.27.1 // indirect github.com/bwmarrin/discordgo v0.27.1 // indirect
github.com/fatih/color v1.15.0 // indirect github.com/containerd/console v1.0.3 // indirect
github.com/ergochat/readline v0.0.5 // indirect
github.com/gorilla/websocket v1.4.2 // indirect github.com/gorilla/websocket v1.4.2 // indirect
github.com/mattn/go-colorable v0.1.13 // indirect github.com/mattn/go-colorable v0.1.13 // indirect
github.com/mattn/go-isatty v0.0.17 // indirect github.com/mattn/go-isatty v0.0.17 // indirect
github.com/mattn/go-runewidth v0.0.13 // indirect
github.com/mgutz/ansi v0.0.0-20200706080929-d51e80ef957d // indirect
github.com/rivo/uniseg v0.2.0 // indirect
golang.org/x/crypto v0.0.0-20210421170649-83a5a9bb288b // indirect golang.org/x/crypto v0.0.0-20210421170649-83a5a9bb288b // indirect
golang.org/x/sys v0.6.0 // indirect golang.org/x/sys v0.10.0 // indirect
golang.org/x/term v0.10.0 // indirect
golang.org/x/text v0.9.0 // indirect
) )

78
go.sum
View file

@ -1,22 +1,100 @@
atomicgo.dev/keyboard v0.2.9 h1:tOsIid3nlPLZ3lwgG8KZMp/SFmr7P0ssEN5JUsm78K8=
atomicgo.dev/keyboard v0.2.9/go.mod h1:BC4w9g00XkxH/f1HXhW2sXmJFOCWbKn9xrOunSFtExQ=
github.com/MarvinJWendt/testza v0.1.0/go.mod h1:7AxNvlfeHP7Z/hDQ5JtE3OKYT3XFUeLCDE2DQninSqs=
github.com/MarvinJWendt/testza v0.2.1/go.mod h1:God7bhG8n6uQxwdScay+gjm9/LnO4D3kkcZX4hv9Rp8=
github.com/MarvinJWendt/testza v0.2.8/go.mod h1:nwIcjmr0Zz+Rcwfh3/4UhBp7ePKVhuBExvZqnKYWlII=
github.com/MarvinJWendt/testza v0.2.10/go.mod h1:pd+VWsoGUiFtq+hRKSU1Bktnn+DMCSrDrXDpX2bG66k=
github.com/MarvinJWendt/testza v0.2.12/go.mod h1:JOIegYyV7rX+7VZ9r77L/eH6CfJHHzXjB69adAhzZkI=
github.com/MarvinJWendt/testza v0.3.0/go.mod h1:eFcL4I0idjtIx8P9C6KkAuLgATNKpX4/2oUqKc6bF2c=
github.com/MarvinJWendt/testza v0.4.2/go.mod h1:mSdhXiKH8sg/gQehJ63bINcCKp7RtYewEjXsvsVUPbE=
github.com/atomicgo/cursor v0.0.1/go.mod h1:cBON2QmmrysudxNBFthvMtN32r3jxVRIvzkUiF/RuIk=
github.com/bwmarrin/discordgo v0.27.1 h1:ib9AIc/dom1E/fSIulrBwnez0CToJE113ZGt4HoliGY= github.com/bwmarrin/discordgo v0.27.1 h1:ib9AIc/dom1E/fSIulrBwnez0CToJE113ZGt4HoliGY=
github.com/bwmarrin/discordgo v0.27.1/go.mod h1:NJZpH+1AfhIcyQsPeuBKsUtYrRnjkyu0kIVMCHkZtRY= github.com/bwmarrin/discordgo v0.27.1/go.mod h1:NJZpH+1AfhIcyQsPeuBKsUtYrRnjkyu0kIVMCHkZtRY=
github.com/chzyer/logex v1.2.1/go.mod h1:JLbx6lG2kDbNRFnfkgvh4eRJRPX1QCoOIWomwysCBrQ=
github.com/chzyer/readline v1.5.1 h1:upd/6fQk4src78LMRzh5vItIt361/o4uq553V8B5sGI=
github.com/chzyer/readline v1.5.1/go.mod h1:Eh+b79XXUwfKfcPLepksvw2tcLE/Ct21YObkaSkeBlk=
github.com/chzyer/test v1.0.0/go.mod h1:2JlltgoNkt4TW/z9V/IzDdFaMTM2JPIi26O1pF38GC8=
github.com/containerd/console v1.0.3 h1:lIr7SlA5PxZyMV30bDW0MGbiOPXwc63yRuCP0ARubLw=
github.com/containerd/console v1.0.3/go.mod h1:7LqA/THxQ86k76b8c/EMSiaJ3h1eZkMkXar0TQ1gf3U=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/ergochat/readline v0.0.5 h1:PlmCLW9HUTnVfhFburg65pQUDKb0LB43G8hS+ygEkp8=
github.com/ergochat/readline v0.0.5/go.mod h1:8RNv74chpO0eTm6rdD1H6WZGihL5rJ+RfSlhv4fIfjg=
github.com/fatih/color v1.15.0 h1:kOqh6YHBtK8aywxGerMG2Eq3H6Qgoqeo13Bk2Mv/nBs= github.com/fatih/color v1.15.0 h1:kOqh6YHBtK8aywxGerMG2Eq3H6Qgoqeo13Bk2Mv/nBs=
github.com/fatih/color v1.15.0/go.mod h1:0h5ZqXfHYED7Bhv2ZJamyIOUej9KtShiJESRwBDUSsw= github.com/fatih/color v1.15.0/go.mod h1:0h5ZqXfHYED7Bhv2ZJamyIOUej9KtShiJESRwBDUSsw=
github.com/gookit/color v1.4.2/go.mod h1:fqRyamkC1W8uxl+lxCQxOT09l/vYfZ+QeiX3rKQHCoQ=
github.com/gookit/color v1.5.0/go.mod h1:43aQb+Zerm/BWh2GnrgOQm7ffz7tvQXEKV6BFMl7wAo=
github.com/gorilla/websocket v1.4.2 h1:+/TMaTYc4QFitKJxsQ7Yye35DkWvkdLcvGKqM+x0Ufc= github.com/gorilla/websocket v1.4.2 h1:+/TMaTYc4QFitKJxsQ7Yye35DkWvkdLcvGKqM+x0Ufc=
github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
github.com/klauspost/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg=
github.com/klauspost/cpuid/v2 v2.0.10/go.mod h1:g2LTdtYhdyuGPqyWyv7qRAmj1WBqxuObKfj5c0PQa7c=
github.com/klauspost/cpuid/v2 v2.0.12/go.mod h1:g2LTdtYhdyuGPqyWyv7qRAmj1WBqxuObKfj5c0PQa7c=
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA= github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA=
github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg= github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg=
github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM=
github.com/mattn/go-isatty v0.0.17 h1:BTarxUcIeDqL27Mc+vyvdWYSL28zpIhv3RoTdsLMPng= github.com/mattn/go-isatty v0.0.17 h1:BTarxUcIeDqL27Mc+vyvdWYSL28zpIhv3RoTdsLMPng=
github.com/mattn/go-isatty v0.0.17/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= github.com/mattn/go-isatty v0.0.17/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM=
github.com/mattn/go-runewidth v0.0.3/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU=
github.com/mattn/go-runewidth v0.0.13 h1:lTGmDsbAYt5DmK6OnoV7EuIF1wEIFAcxld6ypU4OSgU=
github.com/mattn/go-runewidth v0.0.13/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w=
github.com/mgutz/ansi v0.0.0-20200706080929-d51e80ef957d h1:5PJl274Y63IEHC+7izoQE9x6ikvDFZS2mDVS3drnohI=
github.com/mgutz/ansi v0.0.0-20200706080929-d51e80ef957d/go.mod h1:01TrycV0kFyexm33Z7vhZRXopbI8J3TDReVlkTgMUxE=
github.com/peterh/liner v1.2.2 h1:aJ4AOodmL+JxOZZEL2u9iJf8omNRpqHc/EbrK+3mAXw=
github.com/peterh/liner v1.2.2/go.mod h1:xFwJyiKIXJZUKItq5dGHZSTBRAuG/CpeNpWLyiNRNwI=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/pterm/pterm v0.12.27/go.mod h1:PhQ89w4i95rhgE+xedAoqous6K9X+r6aSOI2eFF7DZI=
github.com/pterm/pterm v0.12.29/go.mod h1:WI3qxgvoQFFGKGjGnJR849gU0TsEOvKn5Q8LlY1U7lg=
github.com/pterm/pterm v0.12.30/go.mod h1:MOqLIyMOgmTDz9yorcYbcw+HsgoZo3BQfg2wtl3HEFE=
github.com/pterm/pterm v0.12.31/go.mod h1:32ZAWZVXD7ZfG0s8qqHXePte42kdz8ECtRyEejaWgXU=
github.com/pterm/pterm v0.12.33/go.mod h1:x+h2uL+n7CP/rel9+bImHD5lF3nM9vJj80k9ybiiTTE=
github.com/pterm/pterm v0.12.36/go.mod h1:NjiL09hFhT/vWjQHSj1athJpx6H8cjpHXNAK5bUw8T8=
github.com/pterm/pterm v0.12.40/go.mod h1:ffwPLwlbXxP+rxT0GsgDTzS3y3rmpAO1NMjUkGTYf8s=
github.com/rivo/uniseg v0.2.0 h1:S1pD9weZBuJdFmowNwbpi7BJ8TNftyUImj/0WQi72jY=
github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc=
github.com/sergi/go-diff v1.2.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/wader/readline v0.0.0-20230307172220-bcb7158e7448 h1:AzpBtmgdXa3uznrb3esNeEoaLqtNEwckRmaUH0qWD6w=
github.com/wader/readline v0.0.0-20230307172220-bcb7158e7448/go.mod h1:Zgz8IJWvJoe7NK23CCPpC109XMCqJCpUhpHcnnA4XaM=
github.com/xo/terminfo v0.0.0-20210125001918-ca9a967f8778/go.mod h1:2MuV+tbUrU1zIOPMxZ5EncGwgmMJsa+9ucAQZXxsObs=
golang.org/x/crypto v0.0.0-20210421170649-83a5a9bb288b h1:7mWr3k41Qtv8XlltBkDkl8LoP3mpSgBW8BUoxtEdbXg= golang.org/x/crypto v0.0.0-20210421170649-83a5a9bb288b h1:7mWr3k41Qtv8XlltBkDkl8LoP3mpSgBW8BUoxtEdbXg=
golang.org/x/crypto v0.0.0-20210421170649-83a5a9bb288b/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4= golang.org/x/crypto v0.0.0-20210421170649-83a5a9bb288b/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4=
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68 h1:nxC68pudNYkKU6jWhgrqdreuFiOQWj1Fs7T3VrH4Pjw= golang.org/x/sys v0.0.0-20201119102817-f84b799fce68 h1:nxC68pudNYkKU6jWhgrqdreuFiOQWj1Fs7T3VrH4Pjw=
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20211013075003-97ac67df715c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20211117180635-dee7805ff2e1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220310020820-b874c991c1a5/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220319134239-a9b59b0215f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220627191245-f75cf1eec38b/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.6.0 h1:MVltZSvRTcU2ljQOhs94SXPftV6DCNnZViHeQps87pQ= golang.org/x/sys v0.6.0 h1:MVltZSvRTcU2ljQOhs94SXPftV6DCNnZViHeQps87pQ=
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.10.0 h1:SqMFp9UcQJZa+pmYuAKjd9xq1f0j5rLcDIk0mj4qAsA=
golang.org/x/sys v0.10.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/term v0.0.0-20210220032956-6a3ed077a48d/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/term v0.0.0-20210615171337-6886f2dfbf5b/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
golang.org/x/term v0.10.0 h1:3R7pNqamzBraeqj/Tj8qt1aQ2HpmlC+Cx/qL/7hn4/c=
golang.org/x/term v0.10.0/go.mod h1:lpqdcUyK/oCiQxvxVrppt5ggO2KCZ5QblwqPnfZ6d5o=
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.7 h1:olpwvP2KacW1ZWvsR7uQhoyTYvKAupfQrRGBFM352Gk=
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
golang.org/x/text v0.9.0 h1:2sjJmO8cDvYveuX97RDLsxlyUxLl+GHoLxBiRdHllBE=
golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=

209
lib/messages.go Normal file
View file

@ -0,0 +1,209 @@
package lib
import (
"fmt"
"math"
"regexp"
"strings"
"time"
"github.com/Cynosphere/comcord/state"
"github.com/bwmarrin/discordgo"
"github.com/mgutz/ansi"
)
var /*const*/ REGEX_CODEBLOCK = regexp.MustCompile(`(?i)\x60\x60\x60(?:([a-z0-9_+\-\.]+?)\n)?\n*([^\n].*?)\n*\x60\x60\x60`)
type MessageOptions struct {
Content string
Name string
Channel string
Bot bool
Attachments []*discordgo.MessageAttachment
Stickers []*discordgo.Sticker
Reply *discordgo.Message
Timestamp time.Time
IsMention bool
IsDM bool
IsJoin bool
IsPin bool
IsDump bool
NoColor bool
InHistory bool
}
func FormatMessage(session *discordgo.Session, options MessageOptions) {
// TODO: timestamps for pin and join
// TODO: history lines
nameLength := len(options.Name) + 2
stateNameLength := state.GetNameLength()
if nameLength > stateNameLength {
state.SetNameLength(nameLength)
}
// TODO: replies
if options.IsDump {
if options.InHistory {
// TODO
} else {
wordCount := len(strings.Split(options.Content, " "))
lineCount := len(strings.Split(options.Content, "\n"))
wordsPlural := ""
linesPlural := ""
if wordCount > 1 {
wordsPlural = "s"
}
if lineCount > 1 {
linesPlural = "s"
}
str := fmt.Sprintf("<%s DUMPs in %d characters of %d word%s in %d line%s>", options.Name, len(options.Content), wordCount, wordsPlural, lineCount, linesPlural)
if options.NoColor {
fmt.Print(str)
}
}
} else {
// TODO: markdown
if options.IsDM {
name := fmt.Sprintf("*%s*", options.Name)
if !options.NoColor {
name = ansi.Color(name, "red+b")
}
fmt.Printf("%s %s\x07\n\r", name, options.Content)
} else if len(options.Content) > 1 &&
(strings.HasPrefix(options.Content, "*") && strings.HasSuffix(options.Content, "*") && !strings.HasPrefix(options.Content, "**") && !strings.HasSuffix(options.Content, "**")) ||
(strings.HasPrefix(options.Content, "_") && strings.HasSuffix(options.Content, "_") && !strings.HasPrefix(options.Content, "__") && !strings.HasSuffix(options.Content, "__")) {
str := fmt.Sprintf("<%s %s>", options.Name, options.Content[1:len(options.Content)-1])
if options.NoColor {
fmt.Print(str + "\n\r")
} else {
fmt.Print(ansi.Color(str, "green+b") + "\n\r")
}
} else if options.IsJoin {
// TODO
} else if options.IsPin {
// TODO
} else {
nameColor := "cyan+b"
if options.IsMention {
nameColor = "red+b"
} else if options.Bot {
nameColor = "yellow+b"
}
name := fmt.Sprintf("[%s]", options.Name)
if !options.NoColor {
name = ansi.Color(name, nameColor)
}
// FIXME: where is this off by 4 actually from
padding := strings.Repeat(" ", int(math.Abs(float64(stateNameLength) - float64(nameLength) - 4)))
str := fmt.Sprintf("%s%s %s", name, padding, options.Content)
if options.IsMention {
str = str + "\x07"
}
fmt.Print(str + "\n\r")
}
}
// TODO: attachments
// TODO: stickers
// TODO: links
// TODO: embeds
// TODO: lines output for history
}
func ProcessMessage(session *discordgo.Session, msg *discordgo.Message, options MessageOptions) {
channel, err := session.State.Channel(msg.ChannelID)
if err != nil {
return
}
guild, err := session.State.Guild(channel.GuildID)
if err != nil {
return
}
selfMember, err := session.State.Member(guild.ID, session.State.User.ID)
if err != nil {
return
}
hasMentionedRole := false
for _, role := range msg.MentionRoles {
for _, selfRole := range selfMember.Roles {
if role == selfRole {
hasMentionedRole = true
break;
}
}
}
isDirectlyMentioned := false
for _, user := range msg.Mentions {
if user.ID == session.State.User.ID {
isDirectlyMentioned = true
break;
}
}
isPing := msg.MentionEveryone || hasMentionedRole || isDirectlyMentioned
isDM := channel.Type == discordgo.ChannelTypeDM || channel.Type == discordgo.ChannelTypeGroupDM
currentChannel := state.GetCurrentChannel()
isCurrentChannel := currentChannel == msg.ChannelID
if !isCurrentChannel && !isDM && !isPing {
return
}
if isPing && !isCurrentChannel && !isDM {
str := fmt.Sprintf("**mentioned by %s in #%s in %s**", msg.Author.Username, channel.Name, guild.Name)
if options.NoColor {
fmt.Print(ansi.Color(str, "red+b"))
} else {
fmt.Print(str)
}
fmt.Print("\x07\n\r")
return
}
content, _ := msg.ContentWithMoreMentionsReplaced(session)
options.Content = content
options.Name = msg.Author.Username
options.Channel = msg.ChannelID
options.Bot = msg.Author.Bot
options.Attachments = msg.Attachments
options.Stickers = msg.StickerItems
options.Reply = msg.ReferencedMessage
options.IsMention = isPing
options.IsDM = isDM
options.IsJoin = msg.Type == discordgo.MessageTypeGuildMemberJoin
options.IsPin = msg.Type == discordgo.MessageTypeChannelPinnedMessage
options.IsDump = REGEX_CODEBLOCK.MatchString(content)
FormatMessage(session, options)
}
func ProcessQueue(session *discordgo.Session) {
queue := state.GetMessageQueue()
for _, msg := range queue {
ProcessMessage(session, msg, MessageOptions{NoColor: state.HasNoColor()})
}
state.EmptyMessageQueue()
}

47
main.go
View file

@ -3,17 +3,25 @@ package main
import ( import (
"fmt" "fmt"
"os" "os"
"os/signal"
"strings" "strings"
"syscall"
"atomicgo.dev/keyboard"
"atomicgo.dev/keyboard/keys"
"github.com/Cynosphere/comcord/commands"
"github.com/Cynosphere/comcord/events" "github.com/Cynosphere/comcord/events"
"github.com/Cynosphere/comcord/rcfile" "github.com/Cynosphere/comcord/rcfile"
"github.com/Cynosphere/comcord/state" "github.com/Cynosphere/comcord/state"
"github.com/bwmarrin/discordgo" "github.com/bwmarrin/discordgo"
"golang.org/x/term"
) )
func main() { func main() {
oldState, err := term.MakeRaw(int(os.Stdin.Fd()))
if err != nil {
panic(err)
}
defer term.Restore(int(os.Stdin.Fd()), oldState)
var config map[string]string = make(map[string]string) var config map[string]string = make(map[string]string)
var token string var token string
@ -47,12 +55,17 @@ func main() {
} }
} }
state.Setup() fmt.Println("\rCOMcord (c)left 2023")
fmt.Println("\rType 'h' for Commands")
fmt.Print("\r")
state.Setup(config)
commands.Setup()
// TODO: user account support // TODO: user account support
client, err := discordgo.New("Bot " + token) client, err := discordgo.New("Bot " + token)
if err != nil { if err != nil {
fmt.Println("% Failed to create client:", err) fmt.Println("\r% Failed to create client:", err)
os.Exit(1) os.Exit(1)
return return
} }
@ -65,17 +78,33 @@ func main() {
err = client.Open() err = client.Open()
if err != nil { if err != nil {
fmt.Println("% Failed to connect to Discord:", err) fmt.Println("\r% Failed to connect to Discord:", err)
os.Exit(1) os.Exit(1)
return return
} }
fmt.Println("COMcord (c)left 2023") keyboard.Listen(func(key keys.Key) (stop bool, err error) {
fmt.Println("Type 'h' for Commands") if !state.IsInPrompt() {
if key.Code == keys.CtrlC {
client.Close()
os.Exit(0)
return true, nil
} else {
command, has := commands.GetCommand(key.String())
if has {
command.Run(client)
} else {
commands.SendMode(client)
}
}
}
sc := make(chan os.Signal, 1) return false, nil
})
/*sc := make(chan os.Signal, 1)
signal.Notify(sc, syscall.SIGINT, syscall.SIGTERM, os.Interrupt) signal.Notify(sc, syscall.SIGINT, syscall.SIGTERM, os.Interrupt)
<-sc <-sc
client.Close() client.Close()*/
} }

View file

@ -7,30 +7,38 @@ import (
) )
type ComcordState struct { type ComcordState struct {
Config map[string]string
Connected bool Connected bool
RPCConnected bool RPCConnected bool
StartTime int64 StartTime int64
CurrentGuild string CurrentGuild string
CurrentChannel string CurrentChannel string
NameLength int32 NameLength int
InPrompt bool InPrompt bool
AFK bool AFK bool
MessageQueue []discordgo.Message MessageQueue []*discordgo.Message
LastChannel map[string]string LastChannel map[string]string
LastDM string
NoColor bool
} }
var state ComcordState var state ComcordState
func Setup() { func Setup(config map[string]string) {
state = ComcordState{} state = ComcordState{}
state.Config = config
state.Connected = true state.Connected = true
state.RPCConnected = false state.RPCConnected = false
state.StartTime = time.Now().Unix() state.StartTime = time.Now().Unix()
state.CurrentGuild = ""
state.CurrentChannel = ""
state.NameLength = 2 state.NameLength = 2
state.InPrompt = false state.InPrompt = false
state.AFK = false state.AFK = false
state.MessageQueue = make([]discordgo.Message, 0) state.MessageQueue = make([]*discordgo.Message, 0)
state.LastChannel = make(map[string]string) state.LastChannel = make(map[string]string)
state.LastDM = ""
state.NoColor = false
} }
func IsConnected() bool { func IsConnected() bool {
@ -69,11 +77,11 @@ func SetCurrentChannel(value string) {
state.CurrentChannel = value state.CurrentChannel = value
} }
func GetNameLength() int32 { func GetNameLength() int {
return state.NameLength return state.NameLength
} }
func SetNameLength(value int32) { func SetNameLength(value int) {
state.NameLength = value state.NameLength = value
} }
@ -93,10 +101,54 @@ func SetAFK(value bool) {
state.AFK = value state.AFK = value
} }
func GetMessageQueue() []discordgo.Message { func GetMessageQueue() []*discordgo.Message {
return state.MessageQueue return state.MessageQueue
} }
func AddMessageToQueue(msg discordgo.Message) { func AddMessageToQueue(msg *discordgo.Message) {
state.MessageQueue = append(state.MessageQueue, msg) state.MessageQueue = append(state.MessageQueue, msg)
} }
func EmptyMessageQueue() {
state.MessageQueue = make([]*discordgo.Message, 0)
}
func SetLastChannel(guild string, channel string) {
state.LastChannel[guild] = channel
}
func GetLastChannel(guild string) string {
channel, has := state.LastChannel[guild]
if has {
return channel
} else {
return ""
}
}
func GetLastDM() string {
return state.LastDM
}
func SetLastDM(value string) {
state.LastDM = value
}
func GetConfigValue(key string) string {
value, has := state.Config[key]
if has {
return value
} else {
return ""
}
}
func SetNoColor(value bool) {
state.NoColor = value
}
func HasNoColor() bool {
return state.NoColor
}