Skip to content

Commit

Permalink
Kick & Ban features, permission denied callback
Browse files Browse the repository at this point in the history
Merge pull request #85 from CaptainZidgel/kick-ban
  • Loading branch information
azlux authored Oct 12, 2020
2 parents ee66cf3 + ff2c311 commit 754b4f4
Show file tree
Hide file tree
Showing 7 changed files with 56 additions and 4 deletions.
13 changes: 12 additions & 1 deletion API.md
Original file line number Diff line number Diff line change
Expand Up @@ -69,10 +69,11 @@ Callback names are in `pymumble.constants` module, starting with `PYMUMBLE_CLBK_
- `PYMUMBLE_CLBK_CHANNELREMOVED`: send the removed channel object as parameter
- `PYMUMBLE_CLBK_USERCREATED`: send the added user object as parameter
- `PYMUMBLE_CLBK_USERUPDATED`: send the updated user object and a dict with all the modified fields as parameter
- `PYMUMBLE_CLBK_USERREMOVED`: send the removed user object and the mumble message as parameter
- `PYMUMBLE_CLBK_USERREMOVED`: send the removed user object and the removal event as parameters. The event contains only a `session` field if a user left manually, otherwise it adds an `actor` (person who kicked/banned), `reason`, and `ban` (`True`=ban, `False`=kick).
- `PYMUMBLE_CLBK_SOUNDRECEIVED`: send the user object that received the sound and the SoundChunk object itself
- `PYMUMBLE_CLBK_TEXTMESSAGERECEIVED`: send the received message
- `PYMUMBLE_CLBK_ACLRECEIVED`: send the received acl permissions
- `PYMUMBLE_CLBK_PERMISSIONDENIED`: send the information regarding what caused the action to fail. `event.type` corresponds to [this DenyType enum](https://github.com/mumble-voip/mumble/blob/34c9b2503361163b649a35598de7de727a64148f/src/Mumble.proto#L271).

**Callbacks are executed within the library looping thread. Keep it's work short or you could have jitter issues!**

Expand Down Expand Up @@ -120,6 +121,10 @@ Contain the session number of the `pymumble` connection itself.
Is a shortcut to `Mumble.users[Mumble.users.myself_session]`, pointing to the User object of the current connection.

> `Mumble.denial_type(n)`
Is a shortcut to `mumble_pb2.PermissionDenied.DenyType.Name(n)`, the associated enum name for an action denial cause. (`n` comes from the callback for `PYMUMBLE_CLBK_PERMISSIONDENIED`: `event.type`.

## User object (accessible through Mumble.users[session] or Mumble.users.myself
Contain the users information and method to act on them.
User also contain an instance of the SoundQueue object, containing the audio received from this user.
Expand Down Expand Up @@ -160,6 +165,11 @@ Send a message to the specific user.
Send a register demand to the murmur server (you need to have a certfile

> `user.kick()`
> `user.ban()`
You can pass a keyword argument `reason=` if you'd like, defaults to empty string.

## SoundQueue object (accessible through User.sound)
Contains the audio received from a specific user.
Take care of the decoding and keep track on the timing of the reception.
Expand Down Expand Up @@ -330,3 +340,4 @@ Set Whisper to a specific Channel
> ``Mumble.sound_output.remove_whisper()``
Remove the previously set Whisper

4 changes: 3 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -46,18 +46,20 @@ For client application examples, you can check this list :
- Support OPUS. Speex is not supported
- Receive and send audio, get users and channels status
- Set properties for users (mute, comments, etc.) and go to a specific channel
- Kick and ban users
- Callback mechanism to react on server events
- Manage the blobs (images, long comments, etc.)
- Can send text messages to user and channel
- Ping statistics
- Audio targets (whisper, etc.)
- Read ACL groups

### What is missing:

> I don't need these features, so if you want one, open an issue and I will work on it.
- UDP media. Currently it works only in TCP tunneling mode (the standard fallback of Mumble when UDP is not working)
- Server management (user creation and registration, ACLs, groups, bans, etc.)
- Some server management features (user creation, editing ACLs, etc.)
- Positioning is not managed, but it should be easy to add
- Probably a lot of other small features
- **WONTFIX** The **Python 2** version is available in the [master branch](https://github.com/azlux/pymumble/tree/master). It's working! But since we have moved on to Python 3, the Python 2 version will not receive future improvements.
Expand Down
1 change: 1 addition & 0 deletions pymumble_py3/callbacks.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ def __init__(self):
PYMUMBLE_CLBK_TEXTMESSAGERECEIVED: None, # Send the received message
PYMUMBLE_CLBK_CONTEXTACTIONRECEIVED: None, # Send the contextaction message
PYMUMBLE_CLBK_ACLRECEIVED: None, # Send the received ACL permissions object
PYMUMBLE_CLBK_PERMISSIONDENIED: None, # Permission Denied for some action, send information
})

def set_callback(self, callback, dest):
Expand Down
4 changes: 3 additions & 1 deletion pymumble_py3/constants.py
Original file line number Diff line number Diff line change
Expand Up @@ -71,11 +71,12 @@
PYMUMBLE_CLBK_CHANNELREMOVED = "channel_remove"
PYMUMBLE_CLBK_USERCREATED = "user_created"
PYMUMBLE_CLBK_USERUPDATED = "user_updated"
PYMUMBLE_CLBK_USERREMOVED = "user_remove"
PYMUMBLE_CLBK_USERREMOVED = "user_removed"
PYMUMBLE_CLBK_SOUNDRECEIVED = "sound_received"
PYMUMBLE_CLBK_TEXTMESSAGERECEIVED = "text_received"
PYMUMBLE_CLBK_CONTEXTACTIONRECEIVED = "contextAction_received"
PYMUMBLE_CLBK_ACLRECEIVED = "acl_received"
PYMUMBLE_CLBK_PERMISSIONDENIED = "permission_denied"

# audio types
PYMUMBLE_AUDIO_TYPE_CELT_ALPHA = 0
Expand All @@ -92,3 +93,4 @@
PYMUMBLE_CMD_TEXTPRIVATEMESSAGE = "text_private_message"
PYMUMBLE_CMD_CHANNELUNLINK = "unlink"
PYMUMBLE_CMD_QUERYACL = "get_acl"
PYMUMBLE_CMD_REMOVEUSER = "remove_user"
8 changes: 8 additions & 0 deletions pymumble_py3/messages.py
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,14 @@ def __init__(self, session, params):
self.cmd = PYMUMBLE_CMD_MODUSERSTATE
self.parameters = params

class RemoveUser(Cmd):
"""Command to kick (ban=False) or ban (ban=True) a user"""

def __init__(self, session, params):
Cmd.__init__(self)

self.cmd = PYMUMBLE_CMD_REMOVEUSER
self.parameters = params

class CreateChannel(Cmd):
"""Command to create channel"""
Expand Down
14 changes: 13 additions & 1 deletion pymumble_py3/mumble.py
Original file line number Diff line number Diff line change
Expand Up @@ -376,6 +376,8 @@ def dispatch_control_message(self, type, message):
mess.ParseFromString(message)
self.Log.debug("message: PermissionDenied : %s", mess)

self.callbacks(PYMUMBLE_CLBK_PERMISSIONDENIED, mess)

elif type == PYMUMBLE_MSG_TYPES_ACL:
mess = mumble_pb2.ACL()
mess.ParseFromString(message)
Expand Down Expand Up @@ -673,7 +675,14 @@ def treat_command(self, cmd):
self.send_message(PYMUMBLE_MSG_TYPES_USERSTATE, userstate)
cmd.response = True
self.commands.answer(cmd)

elif cmd.cmd == PYMUMBLE_CMD_REMOVEUSER:
userremove = mumble_pb2.UserRemove()
userremove.session = cmd.parameters["session"]
userremove.reason = cmd.parameters["reason"]
userremove.ban = cmd.parameters["ban"]
self.send_message(PYMUMBLE_MSG_TYPES_USERREMOVE, userremove)
cmd.response = True
self.commands.answer(cmd)
elif cmd.cmd == PYMUMBLE_CMD_QUERYACL:
acl = mumble_pb2.ACL()
acl.channel_id = cmd.parameters["channel_id"]
Expand All @@ -691,6 +700,9 @@ def get_max_image_length(self):
def my_channel(self):
return self.channels[self.users.myself["channel_id"]]

def denial_type(self, n):
return mumble_pb2.PermissionDenied.DenyType.Name(n)

def stop(self):
self.reconnect = None
self.exit = True
Expand Down
16 changes: 16 additions & 0 deletions pymumble_py3/users.py
Original file line number Diff line number Diff line change
Expand Up @@ -246,3 +246,19 @@ def send_text_message(self, message):

cmd = messages.TextPrivateMessage(self["session"], message)
self.mumble_object.execute_command(cmd)

def kick(self, reason=""):
params = {"session": self["session"],
"reason": reason,
"ban": False}

cmd = messages.RemoveUser(self.mumble_object.users.myself_session, params)
self.mumble_object.execute_command(cmd)

def ban(self, reason=""):
params = {"session": self["session"],
"reason": reason,
"ban": True}

cmd = messages.RemoveUser(self.mumble_object.users.myself_session, params)
self.mumble_object.execute_command(cmd)

0 comments on commit 754b4f4

Please sign in to comment.