layeh / gumble

gumble is a Mumble client implementation in Go (golang)
https://pkg.go.dev/mod/layeh.com/gumble
Mozilla Public License 2.0
172 stars 55 forks source link

How to check permissions before moving channel #31

Closed cob16 closed 7 years ago

cob16 commented 7 years ago

Currently my bot will not check if it is permitted to join a channel before joining and therefore crash if it tries to move to a channel it is not permitted to join.

I call perm := event.Sender.Channel.Permission() but I have no idea how to work with the permission object to check for PermissionEnter. I know it's a bitmask but am unsure how to know what bit in the Int to get or really how to get it.

(Sorry if this is a simple question but info on how to do this is hard to come by.)

ghost commented 7 years ago

Currently my bot will crash if it tries to move to a channel it is not permitted to join

This does not seem correct. Is this because your code makes assumptions about being able to enter a channel, or is it a crash from within the gumble library?

Regardless, you can still check for permissions by:

  1. Requesting the channel permissions if Channel.Permission() is nil via Channel.RequestPermission(). An OnChannelChange event will trigger after requesting permissions.
  2. Once you have the permissions, check if it contains PermissionEnter:

    if Channel.Permission() & gumble.PermissionEnter != 0 { // can join channel }

cob16 commented 7 years ago

I assume you meant to put a dereference on Channel.Permission() else this won't compile

if *Channel.Permission() & gumble.PermissionEnter != 0 {
    // can join channel
}

But Strangely I always get a null pointer returned even after calling RequestPermission()


log.Debug(event.Sender.Channel.Permission())
log.Debugf("Requesting Permission to enter %s", event.Sender.Channel.Name)
event.Sender.Channel.RequestPermission()
log.Debug(event.Sender.Channel.Permission())

returns

INFO[0103] User Cob16 (ID:1) called '!joinme'  
DEBU[0103] <nil>                                        
DEBU[0103] Requesting Permission to enter Private       
DEBU[0103] <nil>
ghost commented 7 years ago

@cob16 Sorry, yes, you do have to dereference Channel.Permission().

The reason why that code does not work is because the server hasn't had time to respond to the request. You need to check Channel.Permission() in OnChannelChange:

log.Debug(event.Sender.Channel.Permission())
log.Debugf("Requesting Permission to enter %s", event.Sender.Channel.Name)
if event.Sender.Channel.Permission() == nil {
    // TODO: queue up the action to perform
    event.Sender.Channel.RequestPermission()
} else if *event.Sender.Channel.Permission() & gumble.PermissionEnter != 0 {
    // TODO: do action
}

func (Listener) OnChannelChange(e *ChannelChangeEvent) {
    invalid := !e.Has(gumble.ChannelChangePermission) ||
        !channelThatWeAreWaitingFor(e.Channel) || // TODO
        e.Channel.Permission() == nil
    if invalid {
        return
    }
    if e.Channel.Permission() & gumble.PermissionEnter != 0 {
       // TODO: do queued action
    } else {
        // TODO: cannot enter channel
    }
}