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; }
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; } }