mirror of
https://github.com/mumble-voip/grumble.git
synced 2025-12-19 21:59:59 -08:00
Send correct channel tree. Update mumbleproto. Add comments regarding UserState permission handling.
This commit is contained in:
parent
8a836ac3af
commit
1e67afca46
5 changed files with 141 additions and 25 deletions
29
client.go
29
client.go
|
|
@ -285,20 +285,29 @@ func (client *Client) receiver() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Send the channel list to a client.
|
|
||||||
func (client *Client) sendChannelList() {
|
func (client *Client) sendChannelList() {
|
||||||
server := client.server
|
client.sendChannelTree(client.server.root)
|
||||||
root := server.root
|
}
|
||||||
|
|
||||||
|
func (client *Client) sendChannelTree(channel *Channel) {
|
||||||
// Start at the root channel.
|
// Start at the root channel.
|
||||||
err := client.sendProtoMessage(MessageChannelState, &mumbleproto.ChannelState{
|
log.Printf("sending channel ID=%i, NAME=%s", channel.Id, channel.Name)
|
||||||
ChannelId: proto.Uint32(uint32(root.Id)),
|
chanstate := &mumbleproto.ChannelState{
|
||||||
Name: proto.String(root.Name),
|
ChannelId: proto.Uint32(uint32(channel.Id)),
|
||||||
Description: proto.String(root.Description),
|
Name: proto.String(channel.Name),
|
||||||
})
|
Description: proto.String(channel.Description),
|
||||||
|
}
|
||||||
|
if channel.parent != nil {
|
||||||
|
chanstate.Parent = proto.Uint32(uint32(channel.parent.Id))
|
||||||
|
}
|
||||||
|
|
||||||
|
err := client.sendProtoMessage(MessageChannelState, chanstate)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
// panic!
|
client.Panic(err.String())
|
||||||
log.Printf("poanic!")
|
}
|
||||||
|
|
||||||
|
for _, subchannel := range channel.children {
|
||||||
|
client.sendChannelTree(subchannel)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
92
message.go
92
message.go
|
|
@ -137,6 +137,98 @@ func (server *Server) handleUserRemoveMessage(client *Client, msg *Message) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (server *Server) handleUserStateMessage(client *Client, msg *Message) {
|
func (server *Server) handleUserStateMessage(client *Client, msg *Message) {
|
||||||
|
log.Printf("UserState!")
|
||||||
|
userstate := &mumbleproto.UserState{}
|
||||||
|
err := proto.Unmarshal(msg.buf, userstate)
|
||||||
|
if err != nil {
|
||||||
|
client.Panic(err.String())
|
||||||
|
}
|
||||||
|
|
||||||
|
if userstate.Session == nil {
|
||||||
|
log.Printf("UserState without session.")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
actor := server.clients[client.Session]
|
||||||
|
user := server.clients[*userstate.Session]
|
||||||
|
|
||||||
|
log.Printf("actor = %v", actor)
|
||||||
|
log.Printf("user = %v", user)
|
||||||
|
|
||||||
|
userstate.Session = proto.Uint32(user.Session)
|
||||||
|
userstate.Actor = proto.Uint32(actor.Session)
|
||||||
|
|
||||||
|
// Has a channel ID
|
||||||
|
if userstate.ChannelId != nil {
|
||||||
|
// Destination channel
|
||||||
|
dstChan := server.channels[int(*userstate.ChannelId)]
|
||||||
|
log.Printf("dstChan = %v", dstChan)
|
||||||
|
|
||||||
|
// If the user and the actor aren't the same, check whether the actor has the 'move' permission
|
||||||
|
// on the user's channel to move.
|
||||||
|
|
||||||
|
// Check whether the actor has 'move' permissions on dstChan. Check whether user has 'enter'
|
||||||
|
// permissions on dstChan.
|
||||||
|
|
||||||
|
// Check whether the channel is full.
|
||||||
|
}
|
||||||
|
|
||||||
|
if userstate.Mute != nil || userstate.Deaf != nil || userstate.Suppress != nil || userstate.PrioritySpeaker != nil {
|
||||||
|
// Disallow for SuperUser
|
||||||
|
|
||||||
|
// Check whether the actor has 'mutedeafen' permission on user's channel.
|
||||||
|
|
||||||
|
// Check if this was a suppress operation. Only the server can suppress users.
|
||||||
|
}
|
||||||
|
|
||||||
|
// Comment set/clear
|
||||||
|
if userstate.Comment != nil {
|
||||||
|
comment := *userstate.Comment
|
||||||
|
log.Printf("comment = %v", comment)
|
||||||
|
|
||||||
|
// Clearing another user's comment.
|
||||||
|
if user != actor {
|
||||||
|
// Check if actor has 'move' permissions on the root channel. It is needed
|
||||||
|
// to clear another user's comment.
|
||||||
|
|
||||||
|
// Only allow empty text.
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check if the text is allowed.
|
||||||
|
|
||||||
|
// Only set the comment if it is different from the current
|
||||||
|
// user comment.
|
||||||
|
}
|
||||||
|
|
||||||
|
// Texture change
|
||||||
|
if userstate.Texture != nil {
|
||||||
|
// Check the length of the texture
|
||||||
|
}
|
||||||
|
|
||||||
|
// Registration
|
||||||
|
if userstate.UserId != nil {
|
||||||
|
// If user == actor, check for 'selfregister' permission on root channel.
|
||||||
|
// If user != actor, check for 'register' permission on root channel.
|
||||||
|
|
||||||
|
// Check if the UserId in the message is >= 0. A registration attempt
|
||||||
|
// must use a negative UserId.
|
||||||
|
}
|
||||||
|
|
||||||
|
// Prevent self-targetting state changes to be applied to other users
|
||||||
|
// That is, if actor != user, then:
|
||||||
|
// Discard message if it has any of the following things set:
|
||||||
|
// - SelfDeaf
|
||||||
|
// - SelfMute
|
||||||
|
// - Texture
|
||||||
|
// - PluginContext
|
||||||
|
// - PluginIdentity
|
||||||
|
// - Recording
|
||||||
|
if actor != user && (userstate.SelfDeaf != nil || userstate.SelfMute != nil ||
|
||||||
|
userstate.Texture != nil || userstate.PluginContext != nil || userstate.PluginIdentity != nil ||
|
||||||
|
userstate.Recording != nil) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (server *Server) handleBanListMessage(client *Client, msg *Message) {
|
func (server *Server) handleBanListMessage(client *Client, msg *Message) {
|
||||||
|
|
|
||||||
|
|
@ -245,6 +245,8 @@ type UserState struct {
|
||||||
Hash *string "PB(bytes,15,opt,name=hash)"
|
Hash *string "PB(bytes,15,opt,name=hash)"
|
||||||
CommentHash []byte "PB(bytes,16,opt,name=comment_hash)"
|
CommentHash []byte "PB(bytes,16,opt,name=comment_hash)"
|
||||||
TextureHash []byte "PB(bytes,17,opt,name=texture_hash)"
|
TextureHash []byte "PB(bytes,17,opt,name=texture_hash)"
|
||||||
|
PrioritySpeaker *bool "PB(varint,18,opt,name=priority_speaker)"
|
||||||
|
Recording *bool "PB(varint,19,opt,name=recording)"
|
||||||
XXX_unrecognized []byte
|
XXX_unrecognized []byte
|
||||||
}
|
}
|
||||||
func (this *UserState) Reset() {
|
func (this *UserState) Reset() {
|
||||||
|
|
|
||||||
|
|
@ -106,6 +106,8 @@ message UserState {
|
||||||
optional string hash = 15;
|
optional string hash = 15;
|
||||||
optional bytes comment_hash = 16;
|
optional bytes comment_hash = 16;
|
||||||
optional bytes texture_hash = 17;
|
optional bytes texture_hash = 17;
|
||||||
|
optional bool priority_speaker = 18;
|
||||||
|
optional bool recording = 19;
|
||||||
}
|
}
|
||||||
|
|
||||||
message BanList {
|
message BanList {
|
||||||
|
|
|
||||||
41
server.go
41
server.go
|
|
@ -41,7 +41,6 @@ type Server struct {
|
||||||
udpconn *net.UDPConn
|
udpconn *net.UDPConn
|
||||||
|
|
||||||
incoming chan *Message
|
incoming chan *Message
|
||||||
outgoing chan *Message
|
|
||||||
udpsend chan *Message
|
udpsend chan *Message
|
||||||
voicebroadcast chan *VoiceBroadcast
|
voicebroadcast chan *VoiceBroadcast
|
||||||
|
|
||||||
|
|
@ -63,7 +62,10 @@ type Server struct {
|
||||||
BetaCodec int32
|
BetaCodec int32
|
||||||
PreferAlphaCodec bool
|
PreferAlphaCodec bool
|
||||||
|
|
||||||
|
// Channels
|
||||||
|
chanid int
|
||||||
root *Channel
|
root *Channel
|
||||||
|
channels map[int]*Channel
|
||||||
}
|
}
|
||||||
|
|
||||||
// Allocate a new Murmur instance
|
// Allocate a new Murmur instance
|
||||||
|
|
@ -78,7 +80,6 @@ func NewServer(addr string, port int) (s *Server, err os.Error) {
|
||||||
s.hclients = make(map[string][]*Client)
|
s.hclients = make(map[string][]*Client)
|
||||||
s.hpclients = make(map[string]*Client)
|
s.hpclients = make(map[string]*Client)
|
||||||
|
|
||||||
s.outgoing = make(chan *Message)
|
|
||||||
s.incoming = make(chan *Message)
|
s.incoming = make(chan *Message)
|
||||||
s.udpsend = make(chan *Message)
|
s.udpsend = make(chan *Message)
|
||||||
s.voicebroadcast = make(chan *VoiceBroadcast)
|
s.voicebroadcast = make(chan *VoiceBroadcast)
|
||||||
|
|
@ -86,10 +87,13 @@ func NewServer(addr string, port int) (s *Server, err os.Error) {
|
||||||
s.MaxBandwidth = 300000
|
s.MaxBandwidth = 300000
|
||||||
s.MaxUsers = 10
|
s.MaxUsers = 10
|
||||||
|
|
||||||
s.root = NewChannel(0, "Root")
|
s.channels = make(map[int]*Channel)
|
||||||
|
|
||||||
|
s.root = s.NewChannel("Root")
|
||||||
|
subChan := s.NewChannel("SubChannel")
|
||||||
|
s.root.AddChild(subChan)
|
||||||
|
|
||||||
go s.handler()
|
go s.handler()
|
||||||
go s.multiplexer()
|
|
||||||
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
@ -152,6 +156,23 @@ func (server *Server) RemoveClient(client *Client) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Add a new channel to the server.
|
||||||
|
func (server *Server) NewChannel(name string) (channel *Channel) {
|
||||||
|
channel = NewChannel(server.chanid, name)
|
||||||
|
server.channels[channel.Id] = channel
|
||||||
|
server.chanid += 1
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// Remove a channel from the server.
|
||||||
|
func (server *Server) RemoveChanel(channel *Channel) {
|
||||||
|
if (channel.Id == 0) {
|
||||||
|
log.Printf("Attempted to remove root channel.")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
server.channels[channel.Id] = nil, false
|
||||||
|
}
|
||||||
|
|
||||||
// This is the synchronous handler goroutine.
|
// This is the synchronous handler goroutine.
|
||||||
// Important control channel messages are routed through this Goroutine
|
// Important control channel messages are routed through this Goroutine
|
||||||
// to keep server state synchronized.
|
// to keep server state synchronized.
|
||||||
|
|
@ -263,7 +284,6 @@ func (server *Server) handleAuthenticate(client *Client, msg *Message) {
|
||||||
|
|
||||||
// Broadcast the the user entered a channel
|
// Broadcast the the user entered a channel
|
||||||
server.root.AddClient(client)
|
server.root.AddClient(client)
|
||||||
log.Printf("server.root = %p", server.root)
|
|
||||||
err = server.broadcastProtoMessage(MessageUserState, &mumbleproto.UserState{
|
err = server.broadcastProtoMessage(MessageUserState, &mumbleproto.UserState{
|
||||||
Session: proto.Uint32(client.Session),
|
Session: proto.Uint32(client.Session),
|
||||||
Name: proto.String(client.Username),
|
Name: proto.String(client.Username),
|
||||||
|
|
@ -364,10 +384,8 @@ func (server *Server) sendUserList(client *Client) {
|
||||||
ChannelId: proto.Uint32(0),
|
ChannelId: proto.Uint32(0),
|
||||||
})
|
})
|
||||||
|
|
||||||
log.Printf("Sent one user")
|
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Printf("unable to send!")
|
// Server panic?
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -432,13 +450,6 @@ func (server *Server) handleIncomingMessage(client *Client, msg *Message) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (server *Server) multiplexer() {
|
|
||||||
for {
|
|
||||||
_ = <-server.outgoing
|
|
||||||
log.Printf("recvd message to multiplex")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *Server) SetupUDP() (err os.Error) {
|
func (s *Server) SetupUDP() (err os.Error) {
|
||||||
addr := &net.UDPAddr{
|
addr := &net.UDPAddr{
|
||||||
Port: s.port,
|
Port: s.port,
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue