Skip to content

Commit

Permalink
Improve nickname handling (#3)
Browse files Browse the repository at this point in the history
- Moves the clean code out of the ircnick package and into the main
  package.
- Stores DiscordUser in the ircConnection rather than storing individual
  details here and there.
- Handle nickname length (does not handle username length though)
  • Loading branch information
qaisjp committed Dec 25, 2017
1 parent 8b47f0f commit a6afa23
Show file tree
Hide file tree
Showing 5 changed files with 49 additions and 52 deletions.
1 change: 1 addition & 0 deletions bridge/discord.go
Original file line number Diff line number Diff line change
Expand Up @@ -247,6 +247,7 @@ func (d *discordBot) handleMemberUpdate(m *discordgo.Member) {

d.bridge.updateUserChan <- DiscordUser{
ID: m.User.ID,
Username: m.User.Username,
Discriminator: m.User.Discriminator,
Nick: GetMemberNick(m),
Bot: m.User.Bot,
Expand Down
24 changes: 9 additions & 15 deletions bridge/irc_connection.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,8 @@ import (
type ircConnection struct {
innerCon *irc.Connection

userID string
discriminator string
originalNick string
nick string
discord DiscordUser
nick string

messages chan IRCMessage

Expand All @@ -38,24 +36,20 @@ func (i *ircConnection) OnWelcome(e *irc.Event) {
}

func (i *ircConnection) JoinChannels() {
channels := i.manager.RequestChannels(i.userID)
channels := i.manager.RequestChannels(i.discord.ID)
i.innerCon.SendRaw("JOIN " + strings.Join(channels, ","))
}

func (i *ircConnection) UpdateDetails(discriminator, nick string) {
func (i *ircConnection) UpdateDetails(discord DiscordUser) {
// if their details haven't changed, don't do anything
if (i.originalNick == nick) && (i.discriminator == discriminator) {
if (i.discord.Nick == discord.Nick) && (i.discord.Discriminator == discord.Discriminator) {
return
}

i.originalNick = nick
i.discord = discord
i.nick = i.manager.generateNickname(i.discord)

nick = i.manager.generateNickname(discriminator, nick)

i.discriminator = discriminator
i.nick = nick

go i.innerCon.Nick(nick)
go i.innerCon.Nick(i.nick)
}

func (i *ircConnection) OnPrivateMessage(e *irc.Event) {
Expand All @@ -64,7 +58,7 @@ func (i *ircConnection) OnPrivateMessage(e *irc.Event) {
if e.Message() == "help" {
i.innerCon.Privmsg(e.Nick, "help, who")
} else if e.Message() == "who" {
i.innerCon.Privmsgf(e.Nick, "I am: %s#%s with ID %s", i.originalNick, i.discriminator, i.userID)
i.innerCon.Privmsgf(e.Nick, "I am: %s#%s with ID %s", i.discord.Nick, i.discord.Discriminator, i.discord.ID)
} else {
i.innerCon.Privmsg(e.Nick, "Private messaging Discord users is not supported, but I support commands! Type 'help'.")
}
Expand Down
48 changes: 37 additions & 11 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"
"math"
"time"

"github.com/qaisjp/go-discord-irc/ircnick"
Expand All @@ -25,7 +26,7 @@ func NewIRCManager(bridge *Bridge) *IRCManager {
}

func (m *IRCManager) CloseConnection(i *ircConnection) {
delete(m.ircConnections, i.userID)
delete(m.ircConnections, i.discord.ID)
close(i.messages)
i.innerCon.Quit()
}
Expand All @@ -52,7 +53,7 @@ func (m *IRCManager) HandleUser(user DiscordUser) {
// from `online` to `dnd` (online related states)
// In UpdateDetails we handle nickname changes so it is
// OK to call the below potentially redundant function
con.UpdateDetails(user.Discriminator, user.Nick)
con.UpdateDetails(user)
return
}

Expand All @@ -61,10 +62,10 @@ func (m *IRCManager) HandleUser(user DiscordUser) {
return
}

nick := m.generateNickname(user.Discriminator, user.Nick)
nick := m.generateNickname(user)

innerCon := irc.IRC(nick, "discord")
// innerCon.Debug = true
innerCon.Debug = m.bridge.Config.Debug

var ip string
{
Expand All @@ -89,9 +90,8 @@ func (m *IRCManager) HandleUser(user DiscordUser) {
con := &ircConnection{
innerCon: innerCon,

userID: user.ID,
discriminator: user.Discriminator,
nick: user.Nick,
discord: user,
nick: nick,

messages: make(chan IRCMessage),

Expand All @@ -115,11 +115,37 @@ func (m *IRCManager) HandleUser(user DiscordUser) {
return
}

func (m *IRCManager) generateNickname(_ string, nick string) string {
// First clean it
nick = ircnick.NickClean(nick)
func (m *IRCManager) generateNickname(discord DiscordUser) string {
username := discord.Username
discriminator := discord.Discriminator
nick := discord.Nick

return nick + m.bridge.Config.Suffix
// https://github.com/lp0/charybdis/blob/9ced2a7932dddd069636fe6fe8e9faa6db904703/ircd/client.c#L854-L884
if nick[0] == '-' {
nick = "_" + nick
}
if ircnick.IsDigit(nick[0]) {
nick = "_" + nick
}

newNick := []byte(nick)

// Replace bad characters with underscores
for i, c := range []byte(nick) {
if !ircnick.IsNickChar(c) || ircnick.IsFakeNickChar(c) {
newNick[i] = '_'
}
}

suffix := m.bridge.Config.Suffix
nick = string(newNick) + suffix

if len(nick) > 30 {
length := int(math.Min(float64(len(username)), float64(30-len(discriminator)-len(suffix))))
return username[:length] + discriminator + suffix
}

return nick
}

func (m *IRCManager) SendMessage(channel string, msg *DiscordMessage) {
Expand Down
3 changes: 2 additions & 1 deletion bridge/structs.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,8 @@ type IRCMessage struct {
// DiscordUser is information that IRC needs to know about a user
type DiscordUser struct {
ID string // globally unique id
Discriminator string // locally unique ID
Username string
Discriminator string
Nick string // still non-unique
Bot bool // are they a bot?
Online bool
Expand Down
25 changes: 0 additions & 25 deletions ircnick/clean.go

This file was deleted.

0 comments on commit a6afa23

Please sign in to comment.