Esempio n. 1
0
func getClients(conn *ts3.Conn) (res []Client, err error) {

	// Get client information from the virtual server.

	r, errMsg := conn.Cmd("clientlist")
	if err := handleError(&errMsg); err != nil {
		return nil, err
	}
	clients := strings.Split(r, "|")
	for i := range clients {
		cliParams := mappingParams(clients[i])
		if cliParams["client_type"] == "0" {
			clid, err := strconv.Atoi(cliParams["clid"])
			if err != nil {
				return nil, err
			}
			cid, err := strconv.Atoi(cliParams["cid"])
			if err != nil {
				return nil, err
			}
			res = append(res, *NewClient(clid, cid, ts3.Unquote(cliParams["client_nickname"])))
		}
	}
	return
}
Esempio n. 2
0
func main() {

	var (
		username   string
		password   string
		serverID   string
		webhookURL string
		output     string
		debug      bool
	)

	flag.StringVar(&username, "u", "", "TS3 server query username")
	flag.StringVar(&password, "p", "", "TS3 server query password")
	flag.StringVar(&serverID, "id", "", "Server ID")
	flag.StringVar(&webhookURL, "url", "", "WebHookURL")
	flag.StringVar(&output, "o", "clients.json", "Output file")
	flag.BoolVar(&debug, "d", false, "Debug")
	flag.Parse()

	if username == "" || password == "" || serverID == "" || webhookURL == "" {
		panic(fmt.Errorf("Not enough options"))
	}

	conn, err := ts3.Dial(":10011", true)
	if err != nil {
		panic(err)
	}
	defer conn.Close()

	// Login to the server.
	err = initConn(conn, username, password)
	if err != nil {
		panic(err)
	}

	// Select a server.
	err = connectToServer(conn, serverID)
	if err != nil {
		panic(err)
	}

	// Get client list.
	newState, err := getClients(conn)
	if err != nil {
		panic(err)
	}

	// Get channel information.
	channels := make(map[int]string)
	for i := range newState {
		find := false
		for k, v := range channels {
			if newState[i].CID == k {
				newState[i].ChannelName = v
				find = true
				break
			}
		}
		if !find {
			channelInfo, err := getChannelInfo(conn, newState[i].CID)
			if err != nil {
				panic(err)
			}
			channelName := ts3.Unquote(channelInfo["channel_name"])
			channels[newState[i].CID] = channelName
			newState[i].ChannelName = channelName
		}
	}

	// If output file is not exist, store state and exit.
	if _, err := os.Stat(output); err != nil {
		if err := storeClients(newState, output); err != nil {
			panic(err)
		}
		os.Exit(0)
	}

	// Getting old state from output file.
	oldState, err := loadClients(output)
	if err != nil {
		panic(err)
	}

	// Prepare to notify new clients.
	var newClients []Client
	for i := range newState {
		if isExist, old := findClient(&newState[i], oldState); isExist && !old.IsNotified {
			newClients = append(newClients, newState[i])
			newState[i].IsNotified = true
		} else if isExist && old.CID != newState[i].CID {
			newClients = append(newClients, newState[i])
			newState[i].IsNotified = true
		} else if isExist && old.IsNotified {
			newState[i].IsNotified = true
		}
	}

	// Notify logged in clients.
	if len(newClients) != 0 {
		if debug {
			// Debug
			channelMap := makeChannelMap(newClients)
			text := buildText(channelMap, true)
			fmt.Println(text)
		} else {
			if err := notifyNewClients(webhookURL, newClients); err != nil {
				panic(err)
			}
		}
	}

	// Prepare to notify leaved clients.
	var leavedClients []Client
	for i := range oldState {
		if oldState[i].IsNotified && !matchClient(&oldState[i], newState) {
			leavedClients = append(leavedClients, oldState[i])
		}
	}

	if len(leavedClients) != 0 {
		if debug {
			// Debug
			channelMap := makeChannelMap(leavedClients)
			text := buildText(channelMap, false)
			fmt.Println(text)
		} else {
			// Notify leaved clients.
			if err := notifyLeavedClients(webhookURL, leavedClients); err != nil {
				panic(err)
			}
		}
	}

	// Store new state.
	err = storeClients(newState, output)
	if err != nil {
		panic(err)
	}
}