diff --git a/database/database.go b/database/database.go index 00bd2ff..10e4957 100644 --- a/database/database.go +++ b/database/database.go @@ -68,9 +68,10 @@ func New(baseDB *dbutil.Database, log maulogger.Logger) *Database { return db } -func strPtr(val string) *string { +func strPtr[T ~string](val T) *string { if val == "" { return nil } - return &val + valStr := string(val) + return &valStr } diff --git a/database/puppet.go b/database/puppet.go index 6628887..4b65b41 100644 --- a/database/puppet.go +++ b/database/puppet.go @@ -11,7 +11,7 @@ import ( const ( puppetSelect = "SELECT id, name, name_set, avatar, avatar_url, avatar_set," + - " contact_info_set, custom_mxid, access_token, next_batch" + + " contact_info_set, username, discriminator, is_bot, custom_mxid, access_token, next_batch" + " FROM puppet " ) @@ -66,14 +66,19 @@ type Puppet struct { db *Database log log.Logger - ID string - Name string - NameSet bool - Avatar string - AvatarURL id.ContentURI - AvatarSet bool + ID string + Name string + NameSet bool + Avatar string + AvatarURL id.ContentURI + AvatarSet bool + ContactInfoSet bool + Username string + Discriminator string + IsBot bool + CustomMXID id.UserID AccessToken string NextBatch string @@ -84,7 +89,7 @@ func (p *Puppet) Scan(row dbutil.Scannable) *Puppet { var customMXID, accessToken, nextBatch sql.NullString err := row.Scan(&p.ID, &p.Name, &p.NameSet, &p.Avatar, &avatarURL, &p.AvatarSet, &p.ContactInfoSet, - &customMXID, &accessToken, &nextBatch) + &p.Username, &p.Discriminator, &p.IsBot, &customMXID, &accessToken, &nextBatch) if err != nil { if err != sql.ErrNoRows { @@ -105,11 +110,11 @@ func (p *Puppet) Scan(row dbutil.Scannable) *Puppet { func (p *Puppet) Insert() { query := ` - INSERT INTO puppet (id, name, name_set, avatar, avatar_url, avatar_set, contact_info_set, custom_mxid, access_token, next_batch) - VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10) + INSERT INTO puppet (id, name, name_set, avatar, avatar_url, avatar_set, contact_info_set, username, discriminator, is_bot, custom_mxid, access_token, next_batch) + VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13) ` _, err := p.db.Exec(query, p.ID, p.Name, p.NameSet, p.Avatar, p.AvatarURL.String(), p.AvatarSet, p.ContactInfoSet, - strPtr(string(p.CustomMXID)), strPtr(p.AccessToken), strPtr(p.NextBatch)) + p.Username, p.Discriminator, p.IsBot, strPtr(p.CustomMXID), strPtr(p.AccessToken), strPtr(p.NextBatch)) if err != nil { p.log.Warnfln("Failed to insert %s: %v", p.ID, err) @@ -119,12 +124,12 @@ func (p *Puppet) Insert() { func (p *Puppet) Update() { query := ` - UPDATE puppet SET name=$1, name_set=$2, avatar=$3, avatar_url=$4, avatar_set=$5, - contact_info_set=$6, custom_mxid=$7, access_token=$8, next_batch=$9 - WHERE id=$10 + UPDATE puppet SET name=$1, name_set=$2, avatar=$3, avatar_url=$4, avatar_set=$5, contact_info_set=$6, + username=$7, discriminator=$8, is_bot=$9, custom_mxid=$10, access_token=$11, next_batch=$12 + WHERE id=$13 ` - _, err := p.db.Exec(query, p.Name, p.NameSet, p.Avatar, p.AvatarURL.String(), p.AvatarSet, - p.ContactInfoSet, strPtr(string(p.CustomMXID)), strPtr(p.AccessToken), strPtr(p.NextBatch), + _, err := p.db.Exec(query, p.Name, p.NameSet, p.Avatar, p.AvatarURL.String(), p.AvatarSet, p.ContactInfoSet, + p.Username, p.Discriminator, p.IsBot, strPtr(p.CustomMXID), strPtr(p.AccessToken), strPtr(p.NextBatch), p.ID) if err != nil { diff --git a/database/upgrades/00-latest-revision.sql b/database/upgrades/00-latest-revision.sql index 868020c..107979a 100644 --- a/database/upgrades/00-latest-revision.sql +++ b/database/upgrades/00-latest-revision.sql @@ -1,4 +1,4 @@ --- v0 -> v17: Latest revision +-- v0 -> v18: Latest revision CREATE TABLE guild ( dcid TEXT PRIMARY KEY, @@ -68,8 +68,13 @@ CREATE TABLE puppet ( avatar TEXT NOT NULL, avatar_url TEXT NOT NULL, avatar_set BOOLEAN NOT NULL DEFAULT false, + contact_info_set BOOLEAN NOT NULL DEFAULT false, + username TEXT NOT NULL DEFAULT '', + discriminator TEXT NOT NULL DEFAULT '', + is_bot BOOLEAN NOT NULL DEFAULT false, + custom_mxid TEXT, access_token TEXT, next_batch TEXT diff --git a/database/upgrades/18-extra-ghost-metadata.sql b/database/upgrades/18-extra-ghost-metadata.sql new file mode 100644 index 0000000..ed95f86 --- /dev/null +++ b/database/upgrades/18-extra-ghost-metadata.sql @@ -0,0 +1,4 @@ +-- v18: Store additional metadata for ghosts +ALTER TABLE puppet ADD COLUMN username TEXT NOT NULL DEFAULT ''; +ALTER TABLE puppet ADD COLUMN discriminator TEXT NOT NULL DEFAULT ''; +ALTER TABLE puppet ADD COLUMN is_bot BOOLEAN NOT NULL DEFAULT false; diff --git a/puppet.go b/puppet.go index ac1e552..5d3404e 100644 --- a/puppet.go +++ b/puppet.go @@ -281,7 +281,8 @@ func (puppet *Puppet) UpdateInfo(source *User, info *discordgo.User) { puppet.log.Error().Err(err).Msg("Failed to ensure registered") } - changed := puppet.UpdateContactInfo(source, info) + changed := false + changed = puppet.UpdateContactInfo(info) || changed changed = puppet.UpdateName(info) || changed changed = puppet.UpdateAvatar(info) || changed if changed { @@ -289,30 +290,45 @@ func (puppet *Puppet) UpdateInfo(source *User, info *discordgo.User) { } } -func (puppet *Puppet) UpdateContactInfo(source *User, info *discordgo.User) bool { - if puppet.bridge.Config.Homeserver.Software != bridgeconfig.SoftwareHungry { - return false +func (puppet *Puppet) UpdateContactInfo(info *discordgo.User) bool { + changed := false + if puppet.Username != info.Username { + puppet.Username = info.Username + changed = true } - - if puppet.ContactInfoSet { - return false + if puppet.Discriminator != info.Discriminator { + puppet.Discriminator = info.Discriminator + changed = true } + if puppet.IsBot != info.Bot { + puppet.IsBot = info.Bot + changed = true + } + if changed { + puppet.ContactInfoSet = false + puppet.ResendContactInfo() + return true + } + return false +} +func (puppet *Puppet) ResendContactInfo() { + if puppet.bridge.Config.Homeserver.Software != bridgeconfig.SoftwareHungry || puppet.ContactInfoSet { + return + } contactInfo := map[string]any{ "com.beeper.bridge.identifiers": []string{ - fmt.Sprintf("discord:%s#%s", info.Username, info.Discriminator), + fmt.Sprintf("discord:%s#%s", puppet.Username, puppet.Discriminator), }, "com.beeper.bridge.remote_id": puppet.ID, "com.beeper.bridge.service": puppet.bridge.BeeperServiceName, "com.beeper.bridge.network": puppet.bridge.BeeperNetworkName, - "com.beeper.bridge.is_network_bot": info.Bot, + "com.beeper.bridge.is_network_bot": puppet.IsBot, } err := puppet.DefaultIntent().BeeperUpdateProfile(contactInfo) if err != nil { puppet.log.Warn().Err(err).Msg("Failed to store custom contact info in profile") - return false } else { puppet.ContactInfoSet = true - return true } }