Skip to content

Commit

Permalink
spawn on available, and handle renames
Browse files Browse the repository at this point in the history
  • Loading branch information
qaisjp committed Jun 25, 2017
1 parent 6ff96f3 commit 9a61c83
Show file tree
Hide file tree
Showing 6 changed files with 103 additions and 53 deletions.
21 changes: 20 additions & 1 deletion bridge/discord.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ func prepareDiscord(dib *Bridge, botToken, guildID string) (*discordBot, error)
// These events are all fired in separate goroutines
discord.AddHandler(discord.onMessageCreate)
discord.AddHandler(discord.onMemberListChunk)
discord.AddHandler(discord.onMemberUpdate)

return discord, nil
}
Expand Down Expand Up @@ -61,8 +62,26 @@ func (d *discordBot) onMessageCreate(s *discordgo.Session, m *discordgo.MessageC

func (d *discordBot) onMemberListChunk(s *discordgo.Session, m *discordgo.GuildMembersChunk) {
fmt.Println("Chunk received.")

for _, m := range m.Members {
fmt.Println(m.Nick, m.User.Discriminator, m.User.ID, m.User.Mention(), m.User.String())
d.handleMemberUpdate(m)
}
}

func (d *discordBot) onMemberUpdate(s *discordgo.Session, m *discordgo.GuildMemberUpdate) {
fmt.Println("Member updated", m.User.Username, m.Nick)
d.handleMemberUpdate(m.Member)
}

func (d *discordBot) handleMemberUpdate(m *discordgo.Member) {
nickname := m.Nick
if nickname == "" {
nickname = m.User.Username
}

d.h.updateUserChan <- DiscordUser{
Nick: nickname,
Discriminator: m.User.Discriminator,
ID: m.User.ID,
}
}
26 changes: 11 additions & 15 deletions bridge/home.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ type home struct {

discordMessagesChan chan DiscordNewMessage
discordMessageEventsChan chan DiscordMessageEvent
updateUserChan chan DiscordUser
}

func prepareHome(dib *Bridge, discord *discordBot, ircListener *ircListener, ircManager *ircManager) {
Expand All @@ -31,6 +32,7 @@ func prepareHome(dib *Bridge, discord *discordBot, ircListener *ircListener, irc

discordMessagesChan: make(chan DiscordNewMessage),
discordMessageEventsChan: make(chan DiscordMessageEvent),
updateUserChan: make(chan DiscordUser),
}

go dib.h.loop()
Expand All @@ -40,20 +42,6 @@ func (h *home) GetIRCChannels() []string {
return h.dib.chanIRC
}

func (h *home) GetDiscordUserInfo(userID string) (discriminator, username string, err error) {
// TODO: Catch username changes, and cache UserID:Username mappings somewhere
u, err := h.discord.User(userID)
if err != nil {
fmt.Println("Could not find user", err)
return "", "", err
}

discriminator = u.Discriminator
username = u.Username

return
}

func (h *home) loop() {
for {
select {
Expand All @@ -69,18 +57,26 @@ func (h *home) loop() {
case msg := <-h.discordMessageEventsChan:
ircChan := h.dib.chanMapToIRC[msg.channelID]
if ircChan == "" {
fmt.Println("Ignoring message sent from an unhandled channel.")
continue
}

h.ircManager.PulseID(msg.userID)
h.ircManager.SendMessage(msg.userID, ircChan, msg.message)

// Notification to potentially update, or create, a user
case user := <-h.updateUserChan:
if user.ID != "83386293446246400" {
continue
}

h.ircManager.CreateConnection(user.ID, user.Discriminator, user.Nick)
// Done!
case <-h.done:
fmt.Println("Closing all connections!")
h.discord.Close()
h.ircListener.Disconnect()
h.ircManager.DisconnectAll()

default:
}

Expand Down
16 changes: 6 additions & 10 deletions bridge/irc_connection.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,9 @@ import (
type ircConnection struct {
*irc.Connection

userID string
username string
userID string
discriminator string
username string

messages chan DiscordNewMessage

Expand All @@ -39,18 +40,13 @@ func (i *ircConnection) JoinChannels() {
i.SendRaw("JOIN " + strings.Join(channels, ","))
}

func (i *ircConnection) RefreshUsername() (err error) {
username, err := i.manager.generateUsername(i.userID)

if err != nil {
return
}
func (i *ircConnection) UpdateDetails(discriminator string, nickname string) {
username := i.manager.generateUsername(discriminator, nickname)

i.discriminator = discriminator
i.username = username

if i.Connected() {
i.SendRaw("NICK " + username)
}

return
}
50 changes: 23 additions & 27 deletions bridge/irc_manager.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package bridge

import (
"fmt"
"time"

irc "github.com/thoj/go-ircevent"
)
Expand Down Expand Up @@ -30,17 +31,15 @@ func (m *ircManager) DisconnectAll() {
}
}

func (m *ircManager) CreateConnection(userID string) (*ircConnection, error) {
func (m *ircManager) CreateConnection(userID string, discriminator string, nick string) (*ircConnection, error) {
if con, ok := m.ircConnections[userID]; ok {
fmt.Println("Returning cached IRC connection")

con.UpdateDetails(discriminator, nick)
return con, nil
} else if (discriminator == "") && (nick == "") {
panic("Expected nickname and discriminator")
}

username, err := m.generateUsername(userID)
if err != nil {
return nil, err
}
username := m.generateUsername(discriminator, nick)

innerCon := irc.IRC(username, "BetterDiscordBot")
setupIRCConnection(innerCon)
Expand All @@ -57,7 +56,7 @@ func (m *ircManager) CreateConnection(userID string) (*ircConnection, error) {

m.ircConnections[userID] = con

err = con.Connect(m.ircServerAddress)
err := con.Connect(m.ircServerAddress)
if err != nil {
fmt.Println("error opening irc connection,", err)
return nil, err
Expand All @@ -69,34 +68,31 @@ func (m *ircManager) CreateConnection(userID string) (*ircConnection, error) {
}

// TODO: Catch username changes, and cache UserID:Username mappings somewhere
func (m *ircManager) generateUsername(userID string) (string, error) {
_, username, err := m.h.GetDiscordUserInfo(userID)
if err != nil {
return "", err
}

return username + "^d", nil
func (m *ircManager) generateUsername(_ string, nick string) string {
return nick + "^d"
// return fmt.Sprintf("[%s-%s]", username, discriminator), nil
}

func (m *ircManager) PulseID(userID string) {
_, err := m.CreateConnection(userID)

if err != nil {
panic(err)
}
}

func (m *ircManager) SendMessage(userID, channel, message string) {
con, err := m.CreateConnection(userID)
if err != nil {
panic(err)
con, ok := m.ircConnections[userID]
if !ok {
panic("Could not find connection")
}

con.messages <- DiscordNewMessage{
msg := DiscordNewMessage{
ircChannel: channel,
str: message,
}

select {
// Try to send the message immediately
case con.messages <- msg:
// If it can't after 5ms, do it in a separate goroutine
case <-time.After(time.Millisecond * 5):
go func() {
con.messages <- msg
}()
}
}

// TODO
Expand Down
7 changes: 7 additions & 0 deletions bridge/structs.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,3 +12,10 @@ type DiscordNewMessage struct {
ircChannel string
str string
}

// DiscordUser is information that IRC needs to know about a user
type DiscordUser struct {
Nick string // non-unique nickname
Discriminator string // locally unique ID
ID string // globally unique id
}
36 changes: 36 additions & 0 deletions bridge/utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,12 @@ package bridge

import (
"crypto/tls"
"strconv"

"strings"
"unicode/utf8"

"github.com/pkg/errors"

"github.com/thoj/go-ircevent"
)
Expand All @@ -11,3 +17,33 @@ func setupIRCConnection(con *irc.Connection) {
con.UseTLS = true
con.TLSConfig = &tls.Config{InsecureSkipVerify: true} // TODO: REALLY, THIS IS NOT A VERIFIED CONNECTION!
}

// Leftpad is from github.com/douglarek/leftpad
func Leftpad(s string, length int, ch ...rune) string {
c := ' '
if len(ch) > 0 {
c = ch[0]
}
l := length - utf8.RuneCountInString(s)
if l > 0 {
s = strings.Repeat(string(c), l) + s
}
return s
}

// Takes a snowflake and the first half of an IP to make an IP suitable for WEBIRC
func SnowflakeToIP(base string, snowflake string) string {
num, err := strconv.ParseUint(snowflake, 10, 64)
if err != nil {
panic(errors.Wrap(err, "could not convert snowflake to uint"))
}

for i, c := range Leftpad(strconv.FormatUint(num, 16), 16, '0') {
if (i % 4) == 0 {
base += ":"
}
base += string(c)
}

return base
}

0 comments on commit 9a61c83

Please sign in to comment.