Example #1
0
func (l Conn) OnUserChange(e *gumble.UserChangeEvent) {
	l.client.Do(func() {
		switch {
		case e.Type.Has(gumble.UserChangeChannel):
			if !e.User.IsRegistered() {
				// this shouldn't happen, the mumble authenticator
				// is down, so we'll let users join channel by themselves
				e.User.Send("The mumble authentication service is down, please contact admins, or try reconnecting.")
				return
			}

			if e.User.Channel.IsRoot() {
				lobbyID, team := database.GetCurrentLobby(e.User.UserID)

				if lobbyID != 0 {
					moveUserToLobbyChannel(e.Client, e.User, lobbyID, team)
					return
				}
			}

			if allowed, reason := isUserAllowed(e.User, e.User.Channel); !allowed {
				e.User.Send(reason)
				lobbyID, team := database.GetCurrentLobby(e.User.UserID)

				if lobbyID != 0 {
					moveUserToLobbyChannel(e.Client, e.User, lobbyID, team)
				} else if !database.IsAdmin(e.User.UserID) {
					e.User.Move(e.Client.Channels[0])
				}

			} else if !e.User.Channel.IsRoot() &&
				!strings.HasPrefix(e.User.Channel.Name, "Lobby") {
				// user joined the correct team channel

				bytes, _ := json.Marshal(event.Event{
					Name:     event.PlayerMumbleJoined,
					PlayerID: e.User.UserID,
				}) // we don't need to know the lobby id, helen can do that

				amqpChannel.Publish(
					"",
					queueName,
					false,
					false,
					amqp.Publishing{
						ContentType: "application/json",
						Body:        bytes,
					})
			} else {
				//Either the lobby ended, and the player joined
				//the root channel, in which case Helen wouldn't
				//do anything, or the player joined the root
				//channel while the lobby was going on,
				//in which case Helen changes the in-mumble
				//status for the player to false
				bytes, _ := json.Marshal(event.Event{
					Name:     event.PlayerMumbleLeft,
					PlayerID: e.User.UserID,
				})
				amqpChannel.Publish(
					"",
					queueName,
					false,
					false,
					amqp.Publishing{
						ContentType: "application/json",
						Body:        bytes,
					})

			}
		case e.Type.Has(gumble.UserChangeConnected):
			if !e.User.IsRegistered() {
				e.User.Send("The mumble authentication service is down, please contact admins, or try reconnecting.")
			}
			e.User.Send("Welcome to TF2Stadium!")

		case e.Type.Has(gumble.UserChangeDisconnected):
			bytes, _ := json.Marshal(event.Event{
				Name:     event.PlayerMumbleLeft,
				PlayerID: e.User.UserID,
			})

			amqpChannel.Publish(
				"",
				queueName,
				false,
				false,
				amqp.Publishing{
					ContentType: "application/json",
					Body:        bytes,
				})

		}
	})
}
Example #2
0
func channelManage(conn *Conn) {
	for {
		select {
		case lobbyID := <-conn.Create:
			name := fmt.Sprintf("Lobby #%d", lobbyID)

			conn.lobbyRootWait.Add(1)
			conn.client.Do(func() { conn.client.Channels[0].Add(name, false) })
			conn.lobbyRootWait.Wait()

			conn.client.Do(func() {
				channel := conn.client.Channels[0].Find(name)
				channel.SetDescription("Mumble channel for TF2Stadium " + name)

				log.Printf("#%d: Creating RED and BLU", lobbyID)
				channel.Add("RED", false)
				channel.Add("BLU", false)
			})
			log.Printf("#%d: Done", lobbyID)
		case lobbyID := <-conn.Remove:
			name := fmt.Sprintf("Lobby #%d", lobbyID)

			conn.client.Do(func() {
				root := conn.client.Channels[0].Find(name) // root lobby channel
				if root == nil {
					log.Printf("Couldn't find channel `%s`", name)
					return
				}

				totalUsers := 0
				for _, channel := range root.Children {
					totalUsers += len(channel.Users)

					channel.Remove()
				}

				if totalUsers == 0 { // no users in both channels, remove it entirely
					root.Remove()
				} else {
					root.Send("Removing channel after 10 minutes", false)
					time.AfterFunc(10*time.Minute, func() {
						conn.client.Do(func() {
							root := conn.client.Channels[0].Find(name)
							if root == nil {
								log.Printf("Couldn't find channel `%s`", name)
								return
							}
							root.Remove()
						})
					})
				}
				return
			})
			log.Printf("#%d: Deleted channels", lobbyID)
		case userID := <-conn.RemoveUser:
			conn.client.Do(func() {
				for _, user := range conn.client.Users {
					if user.Channel.ID != 0 && user.UserID == uint32(userID) {
						user.Move(conn.client.Channels[0])
						break
					}
				}
			})
		case userID := <-conn.MoveUser:
			lobbyID, team := database.GetCurrentLobby(uint32(userID))
			if lobbyID == 0 {
				continue
			}
			conn.client.Do(func() {
				for _, user := range conn.client.Users {
					if user.UserID == uint32(userID) {
						moveUserToLobbyChannel(conn.client, user, lobbyID, team)
						break
					}
				}
			})
		}
	}
}