const char *LH_QtPlugin_TS3::userInit()
{
    if( const char *err = LH_QtPlugin::userInit() ) return err;

    server_action_ = sa_disconnected;
    tryConnectTimer_.start();

    socket_ = new QTcpSocket(this);
    myclid_ = -1;

    setup_connection_details_ = new LH_Qt_QString(this, "", "", LH_FLAG_NOSINK | LH_FLAG_NOSOURCE, lh_type_string_html );
    setup_talking_details_ = new LH_Qt_QString(this, "~hr1", "", LH_FLAG_NOSINK | LH_FLAG_NOSOURCE, lh_type_string_html );
    new LH_Qt_QString( this, "~hr2", "<hr/>", LH_FLAG_NOSINK | LH_FLAG_NOSOURCE , lh_type_string_html);

#ifdef TS3_USER_DEFINED_UID
    setup_nickname_expression_ = new LH_Qt_QString(this, "Nickname Expression", "", LH_FLAG_NOSINK | LH_FLAG_NOSOURCE);
    //setup_nickname_expression_->setTitle("Nickname:");
    setup_nickname_expression_->setHelp("Entering your nickname will enable the plugin to acquire additional information about your status.<br/><br/>Note that this field is actually a Regular Expression, so you can have it match multiple possible names. The first match it finds will be the one it uses.");
    connect(setup_nickname_expression_, SIGNAL(changed()), this, SLOT(updateMyDetails()));
#endif

    setup_user_detail_ = new LH_Qt_QString(this, "~hr3", "", LH_FLAG_NOSINK | LH_FLAG_NOSOURCE , lh_type_string_html);

    setup_nickname_ = new LH_Qt_QString(this, "Nickname", "", LH_FLAG_HIDDEN | LH_FLAG_READONLY | LH_FLAG_NOSAVE | LH_FLAG_NOSINK);
    setup_nickname_->setLink("@/3rdParty/TeamSpeak 3/Nickname");

    setup_talking_ = new LH_Qt_QString(this, "Speaking", "", LH_FLAG_HIDDEN | LH_FLAG_READONLY | LH_FLAG_NOSAVE | LH_FLAG_NOSINK);
    setup_talking_->setLink("@/3rdParty/TeamSpeak 3/Speaking");

    setup_talking_me_ = new LH_Qt_bool(this, "Self Speaking", false, LH_FLAG_HIDDEN | LH_FLAG_READONLY | LH_FLAG_NOSAVE | LH_FLAG_NOSINK);
    setup_talking_me_->setLink("@/3rdParty/TeamSpeak 3/Self Speaking");

    setup_channelname_ = new LH_Qt_QString(this, "Channel", "", LH_FLAG_HIDDEN | LH_FLAG_READONLY | LH_FLAG_NOSAVE | LH_FLAG_NOSINK);
    setup_channelname_->setLink("@/3rdParty/TeamSpeak 3/Channel Name");

    setup_connection_status_ = new LH_Qt_QStringList(this, "Connection Status", QStringList() << "Not Running" << "Not Connected" << "Connected", LH_FLAG_HIDDEN | LH_FLAG_READONLY | LH_FLAG_NOSAVE | LH_FLAG_NOSINK );
    setup_connection_status_->setLink("@/3rdParty/TeamSpeak 3/Connection Status");

    setup_microphone_status_ = new LH_Qt_QStringList(this, "Microphone Status", QStringList() << "N/A" << "None" << "Muted" << "Active",  LH_FLAG_READONLY | LH_FLAG_NOSAVE | LH_FLAG_NOSINK );
    setup_microphone_status_->setLink("@/3rdParty/TeamSpeak 3/Microphone Status");

    setup_speakers_status_   = new LH_Qt_QStringList(this, "Speaker Status"   , QStringList() << "N/A" << "None" << "Muted" << "Active",  LH_FLAG_READONLY | LH_FLAG_NOSAVE | LH_FLAG_NOSINK );
    setup_speakers_status_->setLink("@/3rdParty/TeamSpeak 3/Speaker Status");

    connect(setup_nickname_, SIGNAL(changed()), this, SLOT(updateMyDetails()));
    connect(socket_, SIGNAL(connected()), this, SLOT(TS3Connected()));
    connect(socket_, SIGNAL(disconnected()), this, SLOT(TS3Disconnected()));
    connect(socket_, SIGNAL(readyRead()), this, SLOT(TS3DataReceived()));
    connect(socket_, SIGNAL(error(QAbstractSocket::SocketError)), this, SLOT(TS3ConnectionError(QAbstractSocket::SocketError)));

    updateStatus(false);
    updateTalking(true);
    openConnection();
    return 0;
}
Beispiel #2
0
void TS3::telnetMessage(bufferevent *bev, void *parentPtr)
{
	auto parent = static_cast<TS3*>(parentPtr);
	std::string s;
	char buf[1024];
	int n;
	evbuffer *input = bufferevent_get_input(bev);
	while ((n = evbuffer_remove(input, buf, sizeof(buf))) > 0)
		s.append(buf, n);

	// trim CR LF
	if (s.size() > 2)
		s.erase(s.size() - 2);
	else
		LOG(ERROR) << "Received telnet line that is too short!";

	// Pong messages clutter INFO log badly
	// LOG(INFO) << s;

	switch (parent->_sqState)
	{
	case TS3::State::NotConnected:
		// FIXME: very poor criteria for connection
		static const std::string welcome = "Welcome to the TeamSpeak 3 ServerQuery interface";
		if (s.find(welcome) != s.npos)
		{
			LOG(INFO) << "Connected to ServerQuery interface";
			parent->_sqState = TS3::State::ServerQueryConnected;
			evbuffer_add_printf(bufferevent_get_output(bev), "login %s %s\n",
								parent->GetRawConfigValue("Teamspeak.Login").c_str(),
								parent->GetRawConfigValue("Teamspeak.Password").c_str());
		}
		break;

	case TS3::State::ServerQueryConnected:
		static const std::string okMsg = "error id=0 msg=ok";
		if (beginsWith(s, okMsg))
		{
			LOG(INFO) << "Authorized on TS3 server";
			parent->_sqState = TS3::State::Authrozied;
			evbuffer_add_printf(bufferevent_get_output(bev), "use port=9987\n");
		}
		break;

	case TS3::State::Authrozied:
		if (beginsWith(s, okMsg))
		{
			LOG(INFO) << "Connected to Virtual Server";
			parent->_sqState = TS3::State::VirtualServerConnected;
			evbuffer_add_printf(bufferevent_get_output(bev), "clientupdate client_nickname=%s\n", parent->_nickname.c_str());
		}
		break;

	case TS3::State::VirtualServerConnected:
		if (beginsWith(s, okMsg))
		{
			LOG(INFO) << "Nickname is set";
			parent->_sqState = TS3::State::NickSet;
			evbuffer_add_printf(bufferevent_get_output(bev), "servernotifyregister event=server\n");
		}

		break;

	case TS3::State::NickSet:
		if (beginsWith(s, okMsg))
		{
			LOG(INFO) << "Subscribed to connects/disconnects";
			parent->_sqState = TS3::State::Subscribed;
			evbuffer_add_printf(bufferevent_get_output(bev), "servernotifyregister event=textchannel id=%ld\n", parent->_channelID);
		}
		break;

	case TS3::State::Subscribed:
		if (beginsWith(s, "notifycliententerview"))
		{
			auto tokens = tokenize(s, ' ');
			try {
				parent->TS3Connected(tokens.at(4).substr(5), tokens.at(6).substr(16));
			} catch (std::exception &e) {
				LOG(ERROR) << "Can't parse message: \"" << s << "\" | Exception: " << e.what();
			}
			break;
		}

		if (beginsWith(s, "notifyclientleftview"))
		{
			auto tokens = tokenize(s, ' ');
			try {
				parent->TS3Disconnected(tokens.at(5).substr(5, tokens.at(5).size() - 5));
			} catch (std::exception &e) {
				LOG(ERROR) << "Can't parse message: \"" << s << "\" | Exception: " << e.what();
			}
			break;
		}

		if (beginsWith(s, "notifytextmessage"))
		{
			auto tokens = tokenize(s, ' ');
			try {
				auto nick = ReplaceTS3Spaces(tokens.at(4).substr(12));
				auto message = ReplaceTS3Spaces(tokens.at(2).substr(4));
				parent->TS3Message(nick, message);
			} catch (std::exception &e) {
				LOG(ERROR) << "Can't parse message: \"" << s << "\" | Exceptions: " << e.what();
			}
			break;
		}

		break;
	}

}