summaryrefslogtreecommitdiff
path: root/teleirc/matterbridge/bridge/mumble/handlers.go
diff options
context:
space:
mode:
authorMistivia <i@mistivia.com>2025-11-02 15:27:18 +0800
committerMistivia <i@mistivia.com>2025-11-02 15:27:18 +0800
commite9c24f4af7ed56760f6db7941827d09f6db9020b (patch)
tree62128c43b883ce5e3148113350978755779bb5de /teleirc/matterbridge/bridge/mumble/handlers.go
parent58d5e7cfda4781d8a57ec52aefd02983835c301a (diff)
add matterbridge
Diffstat (limited to 'teleirc/matterbridge/bridge/mumble/handlers.go')
-rw-r--r--teleirc/matterbridge/bridge/mumble/handlers.go152
1 files changed, 152 insertions, 0 deletions
diff --git a/teleirc/matterbridge/bridge/mumble/handlers.go b/teleirc/matterbridge/bridge/mumble/handlers.go
new file mode 100644
index 0000000..8120159
--- /dev/null
+++ b/teleirc/matterbridge/bridge/mumble/handlers.go
@@ -0,0 +1,152 @@
+package bmumble
+
+import (
+ "strconv"
+ "time"
+
+ "layeh.com/gumble/gumble"
+
+ "github.com/42wim/matterbridge/bridge/config"
+ "github.com/42wim/matterbridge/bridge/helper"
+)
+
+func (b *Bmumble) handleServerConfig(event *gumble.ServerConfigEvent) {
+ b.serverConfigUpdate <- *event
+}
+
+func (b *Bmumble) handleTextMessage(event *gumble.TextMessageEvent) {
+ sender := "unknown"
+ if event.TextMessage.Sender != nil {
+ sender = event.TextMessage.Sender.Name
+ }
+ // If the text message is received before receiving a ServerSync
+ // and UserState, Client.Self or Self.Channel are nil
+ if event.Client.Self == nil || event.Client.Self.Channel == nil {
+ b.Log.Warn("Connection bootstrap not finished, discarding text message")
+ return
+ }
+ // Convert Mumble HTML messages to markdown
+ parts, err := b.convertHTMLtoMarkdown(event.TextMessage.Message)
+ if err != nil {
+ b.Log.Error(err)
+ }
+ now := time.Now().UTC()
+ for i, part := range parts {
+ // Construct matterbridge message and pass on to the gateway
+ rmsg := config.Message{
+ Channel: strconv.FormatUint(uint64(event.Client.Self.Channel.ID), 10),
+ Username: sender,
+ UserID: sender + "@" + b.Host,
+ Account: b.Account,
+ }
+ if part.Image == nil {
+ rmsg.Text = part.Text
+ } else {
+ fname := b.Account + "_" + strconv.FormatInt(now.UnixNano(), 10) + "_" + strconv.Itoa(i) + part.FileExtension
+ rmsg.Extra = make(map[string][]interface{})
+ if err = helper.HandleDownloadSize(b.Log, &rmsg, fname, int64(len(part.Image)), b.General); err != nil {
+ b.Log.WithError(err).Warn("not including image in message")
+ continue
+ }
+ helper.HandleDownloadData(b.Log, &rmsg, fname, "", "", &part.Image, b.General)
+ }
+ b.Log.Debugf("Sending message to gateway: %+v", rmsg)
+ b.Remote <- rmsg
+ }
+}
+
+func (b *Bmumble) handleConnect(event *gumble.ConnectEvent) {
+ // Set the user's "bio"/comment
+ if comment := b.GetString("UserComment"); comment != "" && event.Client.Self != nil {
+ event.Client.Self.SetComment(comment)
+ }
+ // No need to talk or listen
+ event.Client.Self.SetSelfDeafened(true)
+ event.Client.Self.SetSelfMuted(true)
+ // if the Channel variable is set, this is a reconnect -> rejoin channel
+ if b.Channel != nil {
+ if err := b.doJoin(event.Client, *b.Channel); err != nil {
+ b.Log.Error(err)
+ }
+ b.Remote <- config.Message{
+ Username: "system",
+ Text: "rejoin",
+ Channel: "",
+ Account: b.Account,
+ Event: config.EventRejoinChannels,
+ }
+ }
+}
+
+func (b *Bmumble) handleJoinLeave(event *gumble.UserChangeEvent) {
+ // Ignore events happening before setup is done
+ if b.Channel == nil {
+ return
+ }
+ if b.GetBool("nosendjoinpart") {
+ return
+ }
+ b.Log.Debugf("Received gumble user change event: %+v", event)
+
+ text := ""
+ switch {
+ case event.Type&gumble.UserChangeKicked > 0:
+ text = " was kicked"
+ case event.Type&gumble.UserChangeBanned > 0:
+ text = " was banned"
+ case event.Type&gumble.UserChangeDisconnected > 0:
+ if event.User.Channel != nil && event.User.Channel.ID == *b.Channel {
+ text = " left"
+ }
+ case event.Type&gumble.UserChangeConnected > 0:
+ if event.User.Channel != nil && event.User.Channel.ID == *b.Channel {
+ text = " joined"
+ }
+ case event.Type&gumble.UserChangeChannel > 0:
+ // Treat Mumble channel changes the same as connects/disconnects; as far as matterbridge is concerned, they are identical
+ if event.User.Channel != nil && event.User.Channel.ID == *b.Channel {
+ text = " joined"
+ } else {
+ text = " left"
+ }
+ }
+
+ if text != "" {
+ b.Remote <- config.Message{
+ Username: "system",
+ Text: event.User.Name + text,
+ Channel: strconv.FormatUint(uint64(*b.Channel), 10),
+ Account: b.Account,
+ Event: config.EventJoinLeave,
+ }
+ }
+}
+
+func (b *Bmumble) handleUserModified(event *gumble.UserChangeEvent) {
+ // Ignore events happening before setup is done
+ if b.Channel == nil {
+ return
+ }
+
+ if event.Type&gumble.UserChangeChannel > 0 {
+ // Someone attempted to move the user out of the configured channel; attempt to join back
+ if err := b.doJoin(event.Client, *b.Channel); err != nil {
+ b.Log.Error(err)
+ }
+ }
+}
+
+func (b *Bmumble) handleUserChange(event *gumble.UserChangeEvent) {
+ // The UserChangeEvent is used for both the gumble client itself as well as other clients
+ if event.User != event.Client.Self {
+ // other users
+ b.handleJoinLeave(event)
+ } else {
+ // gumble user
+ b.handleUserModified(event)
+ }
+}
+
+func (b *Bmumble) handleDisconnect(event *gumble.DisconnectEvent) {
+ b.connected <- *event
+}