puppet.go 2.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111
  1. package bridge
  2. import (
  3. "fmt"
  4. "regexp"
  5. "sync"
  6. log "maunium.net/go/maulogger/v2"
  7. "maunium.net/go/mautrix/appservice"
  8. "maunium.net/go/mautrix/id"
  9. "gitlab.com/beeper/discord/database"
  10. )
  11. type Puppet struct {
  12. *database.Puppet
  13. bridge *Bridge
  14. log log.Logger
  15. MXID id.UserID
  16. syncLock sync.Mutex
  17. }
  18. var userIDRegex *regexp.Regexp
  19. func (b *Bridge) NewPuppet(dbPuppet *database.Puppet) *Puppet {
  20. return &Puppet{
  21. Puppet: dbPuppet,
  22. bridge: b,
  23. log: b.log.Sub(fmt.Sprintf("Puppet/%s", dbPuppet.ID)),
  24. MXID: b.FormatPuppetMXID(dbPuppet.ID),
  25. }
  26. }
  27. func (b *Bridge) ParsePuppetMXID(mxid id.UserID) (string, bool) {
  28. if userIDRegex == nil {
  29. pattern := fmt.Sprintf(
  30. "^@%s:%s$",
  31. b.Config.Bridge.FormatUsername("([0-9]+)"),
  32. b.Config.Homeserver.Domain,
  33. )
  34. userIDRegex = regexp.MustCompile(pattern)
  35. }
  36. match := userIDRegex.FindStringSubmatch(string(mxid))
  37. if len(match) == 2 {
  38. return match[1], true
  39. }
  40. return "", false
  41. }
  42. func (b *Bridge) GetPuppetByMXID(mxid id.UserID) *Puppet {
  43. id, ok := b.ParsePuppetMXID(mxid)
  44. if !ok {
  45. return nil
  46. }
  47. return b.GetPuppetByID(id)
  48. }
  49. func (b *Bridge) GetPuppetByID(id string) *Puppet {
  50. b.puppetsLock.Lock()
  51. defer b.puppetsLock.Unlock()
  52. puppet, ok := b.puppets[id]
  53. if !ok {
  54. dbPuppet := b.db.Puppet.Get(id)
  55. if dbPuppet == nil {
  56. dbPuppet = b.db.Puppet.New()
  57. dbPuppet.ID = id
  58. dbPuppet.Insert()
  59. }
  60. puppet = b.NewPuppet(dbPuppet)
  61. b.puppets[puppet.ID] = puppet
  62. }
  63. return puppet
  64. }
  65. func (b *Bridge) FormatPuppetMXID(did string) id.UserID {
  66. return id.NewUserID(
  67. b.Config.Bridge.FormatUsername(did),
  68. b.Config.Homeserver.Domain,
  69. )
  70. }
  71. func (p *Puppet) DefaultIntent() *appservice.IntentAPI {
  72. return p.bridge.as.Intent(p.MXID)
  73. }
  74. func (p *Puppet) SyncContact(user *User) {
  75. p.syncLock.Lock()
  76. defer p.syncLock.Unlock()
  77. dUser, err := user.Session.User(p.ID)
  78. if err != nil {
  79. p.log.Warnfln("failed to sync puppet %s: %v", p.ID, err)
  80. return
  81. }
  82. p.DisplayName = p.bridge.Config.Bridge.FormatDisplayname(dUser)
  83. p.Update()
  84. }