158
commands.go
158
commands.go
@@ -32,6 +32,7 @@ import (
|
||||
|
||||
"maunium.net/go/mautrix"
|
||||
"maunium.net/go/mautrix/appservice"
|
||||
"maunium.net/go/mautrix/bridge/bridgeconfig"
|
||||
"maunium.net/go/mautrix/bridge/commands"
|
||||
"maunium.net/go/mautrix/event"
|
||||
"maunium.net/go/mautrix/id"
|
||||
@@ -58,6 +59,9 @@ func (br *DiscordBridge) RegisterCommands() {
|
||||
cmdPing,
|
||||
cmdReconnect,
|
||||
cmdDisconnect,
|
||||
cmdBridge,
|
||||
cmdUnbridge,
|
||||
cmdDeletePortal,
|
||||
cmdSetRelay,
|
||||
cmdUnsetRelay,
|
||||
cmdGuilds,
|
||||
@@ -406,14 +410,16 @@ func fnSetRelay(ce *WrappedCommandEvent) {
|
||||
ce.Reply("Portal with room ID %s not found", ce.Args[0])
|
||||
return
|
||||
}
|
||||
levels, err := portal.MainIntent().PowerLevels(ce.RoomID)
|
||||
if err != nil {
|
||||
ce.ZLog.Warn().Err(err).Msg("Failed to check room power levels")
|
||||
ce.Reply("Failed to get room power levels to see if you're allowed to use that command")
|
||||
return
|
||||
} else if levels.GetUserLevel(ce.User.GetMXID()) < levels.GetEventLevel(roomModerator) {
|
||||
ce.Reply("You don't have admin rights in that room")
|
||||
return
|
||||
if ce.User.PermissionLevel < bridgeconfig.PermissionLevelAdmin {
|
||||
levels, err := portal.MainIntent().PowerLevels(ce.RoomID)
|
||||
if err != nil {
|
||||
ce.ZLog.Warn().Err(err).Msg("Failed to check room power levels")
|
||||
ce.Reply("Failed to get room power levels to see if you're allowed to use that command")
|
||||
return
|
||||
} else if levels.GetUserLevel(ce.User.GetMXID()) < levels.GetEventLevel(roomModerator) {
|
||||
ce.Reply("You don't have admin rights in that room")
|
||||
return
|
||||
}
|
||||
}
|
||||
ce.Args = ce.Args[1:]
|
||||
} else if portal == nil {
|
||||
@@ -640,6 +646,142 @@ func fnGuildBridgingMode(ce *WrappedCommandEvent) {
|
||||
ce.Reply("Set guild bridging mode to %s", mode.Description())
|
||||
}
|
||||
|
||||
var cmdBridge = &commands.FullHandler{
|
||||
Func: wrapCommand(fnBridge),
|
||||
Name: "bridge",
|
||||
Help: commands.HelpMeta{
|
||||
Section: HelpSectionPortalManagement,
|
||||
Description: "Bridge this room to a specific Discord channel",
|
||||
Args: "[--replace[=delete]] <_channel ID_>",
|
||||
},
|
||||
RequiresEventLevel: roomModerator,
|
||||
}
|
||||
|
||||
func isNumber(str string) bool {
|
||||
for _, chr := range str {
|
||||
if chr < '0' || chr > '9' {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
func fnBridge(ce *WrappedCommandEvent) {
|
||||
if ce.Portal != nil {
|
||||
ce.Reply("This is already a portal room. Unbridge with `$cmdprefix unbridge` first if you want to link it to a different channel.")
|
||||
return
|
||||
}
|
||||
var channelID string
|
||||
var unbridgeOld, deleteOld bool
|
||||
fail := true
|
||||
for _, arg := range ce.Args {
|
||||
arg = strings.ToLower(arg)
|
||||
if arg == "--replace" {
|
||||
unbridgeOld = true
|
||||
} else if arg == "--replace=delete" {
|
||||
unbridgeOld = true
|
||||
deleteOld = true
|
||||
} else if channelID == "" && isNumber(arg) {
|
||||
channelID = arg
|
||||
fail = false
|
||||
} else {
|
||||
fail = true
|
||||
break
|
||||
}
|
||||
}
|
||||
if fail {
|
||||
ce.Reply("**Usage**: `$cmdprefix bridge [--replace[=delete]] <channel ID>`")
|
||||
return
|
||||
}
|
||||
portal := ce.User.GetExistingPortalByID(channelID)
|
||||
if portal == nil {
|
||||
ce.Reply("Channel not found")
|
||||
return
|
||||
}
|
||||
portal.roomCreateLock.Lock()
|
||||
defer portal.roomCreateLock.Lock()
|
||||
if portal.MXID != "" {
|
||||
hasUnbridgePermission := ce.User.PermissionLevel >= bridgeconfig.PermissionLevelAdmin
|
||||
if !hasUnbridgePermission {
|
||||
levels, err := portal.MainIntent().PowerLevels(portal.MXID)
|
||||
if errors.Is(err, mautrix.MNotFound) {
|
||||
ce.ZLog.Debug().Err(err).Msg("Got M_NOT_FOUND trying to get power levels to check if user can unbridge it, assuming the room is gone")
|
||||
hasUnbridgePermission = true
|
||||
} else if err != nil {
|
||||
ce.ZLog.Warn().Err(err).Msg("Failed to check room power levels")
|
||||
ce.Reply("Failed to get power levels in old room to see if you're allowed to unbridge it")
|
||||
return
|
||||
} else {
|
||||
hasUnbridgePermission = levels.GetUserLevel(ce.User.GetMXID()) >= levels.GetEventLevel(roomModerator)
|
||||
}
|
||||
}
|
||||
if !unbridgeOld || !hasUnbridgePermission {
|
||||
extraHelp := "Rerun the command with `--replace` or `--replace=delete` to unbridge the old room."
|
||||
if !hasUnbridgePermission {
|
||||
extraHelp = "Additionally, you do not have the permissions to unbridge the old room."
|
||||
}
|
||||
ce.Reply("That channel is already bridged to [%s](https://matrix.to/#/%s). %s", portal.Name, portal.MXID, extraHelp)
|
||||
return
|
||||
}
|
||||
ce.ZLog.Debug().
|
||||
Str("old_room_id", portal.MXID.String()).
|
||||
Bool("delete", deleteOld).
|
||||
Msg("Unbridging old room")
|
||||
portal.removeFromSpace()
|
||||
portal.RemoveMXID()
|
||||
portal.cleanup(deleteOld)
|
||||
ce.ZLog.Info().
|
||||
Str("old_room_id", portal.MXID.String()).
|
||||
Bool("delete", deleteOld).
|
||||
Msg("Unbridged old room to make space for new bridge")
|
||||
}
|
||||
if portal.Guild != nil && portal.Guild.BridgingMode < database.GuildBridgeIfPortalExists {
|
||||
ce.ZLog.Debug().Str("guild_id", portal.Guild.ID).Msg("Bumping bridging mode of portal guild to if-portal-exists")
|
||||
portal.Guild.BridgingMode = database.GuildBridgeIfPortalExists
|
||||
portal.Guild.Update()
|
||||
}
|
||||
ce.ZLog.Debug().Str("channel_id", portal.Key.ChannelID).Msg("Bridging room")
|
||||
portal.MXID = ce.RoomID
|
||||
portal.updateRoomName()
|
||||
portal.updateRoomAvatar()
|
||||
portal.updateRoomTopic()
|
||||
portal.updateSpace()
|
||||
portal.UpdateBridgeInfo()
|
||||
portal.Update()
|
||||
ce.Reply("Room successfully bridged")
|
||||
ce.ZLog.Info().Str("channel_id", portal.Key.ChannelID).Msg("Manual bridging complete")
|
||||
}
|
||||
|
||||
var cmdUnbridge = &commands.FullHandler{
|
||||
Func: wrapCommand(fnUnbridge),
|
||||
Name: "unbridge",
|
||||
Help: commands.HelpMeta{
|
||||
Section: HelpSectionPortalManagement,
|
||||
Description: "Unbridge this room from the linked Discord channel",
|
||||
},
|
||||
RequiresPortal: true,
|
||||
RequiresEventLevel: roomModerator,
|
||||
}
|
||||
|
||||
var cmdDeletePortal = &commands.FullHandler{
|
||||
Func: wrapCommand(fnUnbridge),
|
||||
Name: "delete-portal",
|
||||
Help: commands.HelpMeta{
|
||||
Section: HelpSectionPortalManagement,
|
||||
Description: "Unbridge this room and kick all Matrix users",
|
||||
},
|
||||
RequiresPortal: true,
|
||||
RequiresEventLevel: roomModerator,
|
||||
}
|
||||
|
||||
func fnUnbridge(ce *WrappedCommandEvent) {
|
||||
ce.Portal.roomCreateLock.Lock()
|
||||
defer ce.Portal.roomCreateLock.Lock()
|
||||
ce.Portal.removeFromSpace()
|
||||
ce.Portal.RemoveMXID()
|
||||
ce.Portal.cleanup(ce.Command == "delete-portal")
|
||||
}
|
||||
|
||||
var cmdDeleteAllPortals = &commands.FullHandler{
|
||||
Func: wrapCommand(fnDeleteAllPortals),
|
||||
Name: "delete-all-portals",
|
||||
|
||||
18
portal.go
18
portal.go
@@ -160,7 +160,9 @@ func (br *DiscordBridge) GetExistingPortalByID(key database.PortalKey) *Portal {
|
||||
defer br.portalsLock.Unlock()
|
||||
portal, ok := br.portalsByID[key]
|
||||
if !ok {
|
||||
portal, ok = br.portalsByID[database.NewPortalKey(key.ChannelID, "")]
|
||||
if key.Receiver != "" {
|
||||
portal, ok = br.portalsByID[database.NewPortalKey(key.ChannelID, "")]
|
||||
}
|
||||
if !ok {
|
||||
return br.loadPortal(br.DB.Portal.GetByID(key), nil, -1)
|
||||
}
|
||||
@@ -1732,6 +1734,11 @@ func (portal *Portal) UpdateNameDirect(name string) bool {
|
||||
portal.log.Debugfln("Updating name %q -> %q", portal.Name, name)
|
||||
portal.Name = name
|
||||
portal.NameSet = false
|
||||
portal.updateRoomName()
|
||||
return true
|
||||
}
|
||||
|
||||
func (portal *Portal) updateRoomName() {
|
||||
if portal.MXID != "" {
|
||||
_, err := portal.MainIntent().SetRoomName(portal.MXID, portal.Name)
|
||||
if err != nil {
|
||||
@@ -1740,7 +1747,6 @@ func (portal *Portal) UpdateNameDirect(name string) bool {
|
||||
portal.NameSet = true
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
func (portal *Portal) UpdateAvatarFromPuppet(puppet *Puppet) bool {
|
||||
@@ -1779,7 +1785,7 @@ func (portal *Portal) UpdateGroupDMAvatar(iconID string) bool {
|
||||
}
|
||||
|
||||
func (portal *Portal) updateRoomAvatar() {
|
||||
if portal.MXID == "" {
|
||||
if portal.MXID == "" || portal.AvatarURL.IsEmpty() {
|
||||
return
|
||||
}
|
||||
_, err := portal.MainIntent().SetRoomAvatar(portal.MXID, portal.AvatarURL)
|
||||
@@ -1797,6 +1803,11 @@ func (portal *Portal) UpdateTopic(topic string) bool {
|
||||
portal.log.Debugfln("Updating topic %q -> %q", portal.Topic, topic)
|
||||
portal.Topic = topic
|
||||
portal.TopicSet = false
|
||||
portal.updateRoomTopic()
|
||||
return true
|
||||
}
|
||||
|
||||
func (portal *Portal) updateRoomTopic() {
|
||||
if portal.MXID != "" {
|
||||
_, err := portal.MainIntent().SetRoomTopic(portal.MXID, portal.Topic)
|
||||
if err != nil {
|
||||
@@ -1805,7 +1816,6 @@ func (portal *Portal) UpdateTopic(topic string) bool {
|
||||
portal.TopicSet = true
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
func (portal *Portal) removeFromSpace() {
|
||||
|
||||
Reference in New Issue
Block a user