1
0
Fork 0
forked from External/grumble

Send correct channel tree. Update mumbleproto. Add comments regarding UserState permission handling.

This commit is contained in:
Mikkel Krautz 2010-11-20 23:05:44 +01:00
parent 8a836ac3af
commit 1e67afca46
5 changed files with 141 additions and 25 deletions

View file

@ -285,20 +285,29 @@ func (client *Client) receiver() {
}
}
// Send the channel list to a client.
func (client *Client) sendChannelList() {
server := client.server
root := server.root
client.sendChannelTree(client.server.root)
}
func (client *Client) sendChannelTree(channel *Channel) {
// Start at the root channel.
err := client.sendProtoMessage(MessageChannelState, &mumbleproto.ChannelState{
ChannelId: proto.Uint32(uint32(root.Id)),
Name: proto.String(root.Name),
Description: proto.String(root.Description),
})
log.Printf("sending channel ID=%i, NAME=%s", channel.Id, channel.Name)
chanstate := &mumbleproto.ChannelState{
ChannelId: proto.Uint32(uint32(channel.Id)),
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 {
// panic!
log.Printf("poanic!")
client.Panic(err.String())
}
for _, subchannel := range channel.children {
client.sendChannelTree(subchannel)
}
}

View file

@ -137,6 +137,98 @@ func (server *Server) handleUserRemoveMessage(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) {

View file

@ -245,6 +245,8 @@ type UserState struct {
Hash *string "PB(bytes,15,opt,name=hash)"
CommentHash []byte "PB(bytes,16,opt,name=comment_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
}
func (this *UserState) Reset() {

View file

@ -106,6 +106,8 @@ message UserState {
optional string hash = 15;
optional bytes comment_hash = 16;
optional bytes texture_hash = 17;
optional bool priority_speaker = 18;
optional bool recording = 19;
}
message BanList {

View file

@ -41,7 +41,6 @@ type Server struct {
udpconn *net.UDPConn
incoming chan *Message
outgoing chan *Message
udpsend chan *Message
voicebroadcast chan *VoiceBroadcast
@ -63,7 +62,10 @@ type Server struct {
BetaCodec int32
PreferAlphaCodec bool
// Channels
chanid int
root *Channel
channels map[int]*Channel
}
// 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.hpclients = make(map[string]*Client)
s.outgoing = make(chan *Message)
s.incoming = make(chan *Message)
s.udpsend = make(chan *Message)
s.voicebroadcast = make(chan *VoiceBroadcast)
@ -86,10 +87,13 @@ func NewServer(addr string, port int) (s *Server, err os.Error) {
s.MaxBandwidth = 300000
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.multiplexer()
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.
// Important control channel messages are routed through this Goroutine
// to keep server state synchronized.
@ -263,7 +284,6 @@ func (server *Server) handleAuthenticate(client *Client, msg *Message) {
// Broadcast the the user entered a channel
server.root.AddClient(client)
log.Printf("server.root = %p", server.root)
err = server.broadcastProtoMessage(MessageUserState, &mumbleproto.UserState{
Session: proto.Uint32(client.Session),
Name: proto.String(client.Username),
@ -364,10 +384,8 @@ func (server *Server) sendUserList(client *Client) {
ChannelId: proto.Uint32(0),
})
log.Printf("Sent one user")
if err != nil {
log.Printf("unable to send!")
// Server panic?
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) {
addr := &net.UDPAddr{
Port: s.port,