diff options
Diffstat (limited to 'teleirc/matterbridge/bridge/mumble/handlers.go')
| -rw-r--r-- | teleirc/matterbridge/bridge/mumble/handlers.go | 152 |
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 +} |
