void UserDbObject::OnConfigUpdate(void) { Dictionary::Ptr fields = make_shared<Dictionary>(); User::Ptr user = static_pointer_cast<User>(GetObject()); /* contact addresses */ Log(LogDebug, "UserDbObject", "contact addresses for '" + user->GetName() + "'"); Dictionary::Ptr vars = user->GetVars(); if (vars) { /* This is sparta. */ for (int i = 1; i <= 6; i++) { String key = "address" + Convert::ToString(i); String val = vars->Get(key); if (val.IsEmpty()) continue; fields->Set("contact_id", DbValue::FromObjectInsertID(user)); fields->Set("address_number", i); fields->Set("address", val); fields->Set("instance_id", 0); /* DbConnection class fills in real ID */ DbQuery query; query.Type = DbQueryInsert; query.Table = "contact_addresses"; query.Fields = fields; OnQuery(query); } } }
Dictionary::Ptr UserDbObject::GetConfigFields(void) const { Dictionary::Ptr fields = new Dictionary(); User::Ptr user = static_pointer_cast<User>(GetObject()); fields->Set("alias", user->GetDisplayName()); fields->Set("email_address", user->GetEmail()); fields->Set("pager_address", user->GetPager()); fields->Set("host_timeperiod_object_id", user->GetPeriod()); fields->Set("service_timeperiod_object_id", user->GetPeriod()); fields->Set("host_notifications_enabled", user->GetEnableNotifications()); fields->Set("service_notifications_enabled", user->GetEnableNotifications()); fields->Set("can_submit_commands", 1); int typeFilter = user->GetTypeFilter(); int stateFilter = user->GetStateFilter(); fields->Set("notify_service_recovery", (typeFilter & NotificationRecovery) != 0); fields->Set("notify_service_warning", (stateFilter & StateFilterWarning) != 0); fields->Set("notify_service_unknown", (stateFilter & StateFilterUnknown) != 0); fields->Set("notify_service_critical", (stateFilter & StateFilterCritical) != 0); fields->Set("notify_service_flapping", (typeFilter & (NotificationFlappingStart | NotificationFlappingEnd)) != 0); fields->Set("notify_service_downtime", (typeFilter & (NotificationDowntimeStart | NotificationDowntimeEnd | NotificationDowntimeRemoved)) != 0); fields->Set("notify_host_recovery", (typeFilter & NotificationRecovery) != 0); fields->Set("notify_host_down", (stateFilter & StateFilterDown) != 0); fields->Set("notify_host_flapping", (typeFilter & (NotificationFlappingStart | NotificationFlappingEnd)) != 0); fields->Set("notify_host_downtime", (typeFilter & (NotificationDowntimeStart | NotificationDowntimeEnd | NotificationDowntimeRemoved)) != 0); return fields; }
/** * @threadsafety Always. */ void CompatLogger::NotificationSentHandler(const Notification::Ptr& notification, const Checkable::Ptr& checkable, const User::Ptr& user, NotificationType notification_type, CheckResult::Ptr const& cr, const String& author, const String& comment_text, const String& command_name) { Host::Ptr host; Service::Ptr service; tie(host, service) = GetHostService(checkable); String notification_type_str = Notification::NotificationTypeToString(notification_type); /* override problem notifications with their current state string */ if (notification_type == NotificationProblem) { if (service) notification_type_str = Service::StateToString(service->GetState()); else notification_type_str = GetHostStateString(host); } String author_comment = ""; if (notification_type == NotificationCustom || notification_type == NotificationAcknowledgement) { author_comment = author + ";" + comment_text; } if (!cr) return; String output; if (cr) output = CompatUtility::GetCheckResultOutput(cr); std::ostringstream msgbuf; if (service) { msgbuf << "SERVICE NOTIFICATION: " << user->GetName() << ";" << host->GetName() << ";" << service->GetShortName() << ";" << notification_type_str << ";" << command_name << ";" << output << ";" << author_comment << ""; } else { msgbuf << "HOST NOTIFICATION: " << user->GetName() << ";" << host->GetName() << ";" << notification_type_str << " " << "(" << GetHostStateString(host) << ");" << command_name << ";" << output << ";" << author_comment << ""; } { ObjectLock oLock(this); WriteLine(msgbuf.str()); Flush(); } }
bool UserGroup::EvaluateObjectRuleOne(const User::Ptr user, const ObjectRule& rule) { DebugInfo di = rule.GetDebugInfo(); std::ostringstream msgbuf; msgbuf << "Evaluating 'object' rule (" << di << ")"; CONTEXT(msgbuf.str()); Dictionary::Ptr locals = make_shared<Dictionary>(); locals->Set("user", user); if (!rule.EvaluateFilter(locals)) return false; std::ostringstream msgbuf2; msgbuf2 << "Assigning membership for group '" << rule.GetName() << "' to user '" << user->GetName() << "' for rule " << di; Log(LogDebug, "UserGroup", msgbuf2.str()); String group_name = rule.GetName(); UserGroup::Ptr group = UserGroup::GetByName(group_name); if (!group) { Log(LogCritical, "UserGroup", "Invalid membership assignment. Group '" + group_name + "' does not exist."); return false; } /* assign user group membership */ group->ResolveGroupMembership(user, true); /* update groups attribute for apply */ user->AddGroup(group_name); return true; }
Value ContactsTable::EmailAccessor(const Value& row) { User::Ptr user = static_cast<User::Ptr>(row); if (!user) return Empty; return user->GetEmail(); }
Value ContactsTable::AliasAccessor(const Value& row) { User::Ptr user = static_cast<User::Ptr>(row); if (!user) return Empty; return user->GetDisplayName(); }
Value ContactsTable::ServiceNotificationsEnabledAccessor(const Value& row) { User::Ptr user = static_cast<User::Ptr>(row); if (!user) return Empty; return (user->GetEnableNotifications() ? 1 : 0); }
Dictionary::Ptr UserDbObject::GetStatusFields(void) const { Dictionary::Ptr fields = new Dictionary(); User::Ptr user = static_pointer_cast<User>(GetObject()); fields->Set("host_notifications_enabled", user->GetEnableNotifications()); fields->Set("service_notifications_enabled", user->GetEnableNotifications()); fields->Set("last_host_notification", DbValue::FromTimestamp(user->GetLastNotification())); fields->Set("last_service_notification", DbValue::FromTimestamp(user->GetLastNotification())); return fields; }
String UserDbObject::CalculateConfigHash(const Dictionary::Ptr& configFields) const { String hashData = DbObject::CalculateConfigHash(configFields); User::Ptr user = static_pointer_cast<User>(GetObject()); Array::Ptr groups = user->GetGroups(); if (groups) hashData += DbObject::HashValue(groups); return SHA256(hashData); }
Value ContactsTable::InServiceNotificationPeriodAccessor(const Value& row) { User::Ptr user = static_cast<User::Ptr>(row); if (!user) return Empty; TimePeriod::Ptr timeperiod = user->GetPeriod(); if (!timeperiod) return Empty; return (timeperiod->IsInside(Utility::GetTime()) ? 1 : 0); }
Value ContactsTable::ServiceNotificationPeriodAccessor(const Value& row) { User::Ptr user = static_cast<User::Ptr>(row); if (!user) return Empty; TimePeriod::Ptr timeperiod = user->GetPeriod(); if (!timeperiod) return Empty; return timeperiod->GetName(); }
void Notification::ExecuteNotificationHelper(NotificationType type, const User::Ptr& user, const CheckResult::Ptr& cr, bool force, const String& author, const String& text) { try { NotificationCommand::Ptr command = GetCommand(); if (!command) { Log(LogDebug, "Notification") << "No command found for notification '" << GetName() << "'. Skipping execution."; return; } command->Execute(this, user, cr, type, author, text); /* required by compatlogger */ Service::OnNotificationSentToUser(this, GetCheckable(), user, type, cr, author, text, command->GetName(), MessageOrigin::Ptr()); Log(LogInformation, "Notification") << "Completed sending '" << NotificationTypeToStringInternal(type) << "' notification '" << GetName() << "' for checkable '" << GetCheckable()->GetName() << "' and user '" << user->GetName() << "'."; } catch (const std::exception& ex) { Log(LogWarning, "Notification") << "Exception occured during notification for checkable '" << GetCheckable()->GetName() << "': " << DiagnosticInformation(ex); } }
void ClusterEvents::NotificationSentUserHandler(const Notification::Ptr& notification, const Checkable::Ptr& checkable, const User::Ptr& user, NotificationType notificationType, const CheckResult::Ptr& cr, const NotificationResult::Ptr& nr, const String& author, const String& commentText, const String& command, const MessageOrigin::Ptr& origin) { ApiListener::Ptr listener = ApiListener::GetInstance(); if (!listener) return; Host::Ptr host; Service::Ptr service; tie(host, service) = GetHostService(checkable); Dictionary::Ptr params = new Dictionary(); params->Set("host", host->GetName()); if (service) params->Set("service", service->GetShortName()); params->Set("notification", notification->GetName()); params->Set("user", user->GetName()); params->Set("type", notificationType); params->Set("cr", Serialize(cr)); params->Set("nr", Serialize(nr)); params->Set("author", author); params->Set("text", commentText); params->Set("command", command); Dictionary::Ptr message = new Dictionary(); message->Set("jsonrpc", "2.0"); message->Set("method", "event::NotificationSentUser"); message->Set("params", params); listener->RelayMessage(origin, nullptr, message, true); }
void UserGroup::AddMember(const User::Ptr& user) { user->AddGroup(GetName()); boost::mutex::scoped_lock lock(m_UserGroupMutex); m_Members.insert(user); }
bool UserGroup::ResolveGroupMembership(const User::Ptr& user, bool add, int rstack) { if (add && rstack > 20) { Log(LogWarning, "UserGroup") << "Too many nested groups for group '" << GetName() << "': User '" << user->GetName() << "' membership assignment failed."; return false; } Array::Ptr groups = GetGroups(); if (groups && groups->GetLength() > 0) { ObjectLock olock(groups); for (const String& name : groups) { UserGroup::Ptr group = UserGroup::GetByName(name); if (group && !group->ResolveGroupMembership(user, add, rstack + 1)) return false; } } if (add) AddMember(user); else RemoveMember(user); return true; }
void ClientManager::connect(const User::Ptr& p) { Lock l(cs); OnlineIter i = onlineUsers.find(p->getCID()); if(i != onlineUsers.end()) { OnlineUser* u = i->second; u->getClient().connect(*u); } }
void UploadManager::reserveSlot(const User::Ptr& aUser) { { Lock l(cs); reservedSlots.insert(aUser); } if(aUser->isOnline()) ClientManager::getInstance()->connect(aUser); }
void ClientManager::privateMessage(const User::Ptr& p, const string& msg) { Lock l(cs); OnlineIter i = onlineUsers.find(p->getCID()); if(i != onlineUsers.end()) { OnlineUser* u = i->second; u->getClient().privateMessage(*u, msg); } }
void UploadManager::reserveSlot(const User::Ptr& aUser) { { Lock l(cs); reservedSlots.insert(aUser); } if(aUser->isOnline()) const_cast<User::Ptr&>(aUser)->connect(); }
void UsersFrame::updateUser(const User::Ptr& aUser) { for(int i = 0; i < ctrlUsers.GetItemCount(); ++i) { UserInfo *ui = ctrlUsers.getItemData(i); if(ui->user == aUser) { ui->columns[COLUMN_SEEN] = aUser->isOnline() ? TSTRING(ONLINE) : Text::toT(Util::formatTime("%Y-%m-%d %H:%M", FavoriteManager::getInstance()->getLastSeen(aUser))); ctrlUsers.updateItem(i); } } }
bool ClientManager::isOp(const User::Ptr& user, const string& aHubUrl) const { Lock l(cs); OnlinePairC p = onlineUsers.equal_range(user->getCID()); for(OnlineIterC i = p.first; i != p.second; ++i) { if(i->second->getClient().getHubUrl() == aHubUrl) { return i->second->getIdentity().isOp(); } } return false; }
void AdcHub::handle(Command::MSG, Command& c) throw() { if(c.getFrom().isZero() || c.getParameters().empty()) return; User::Ptr p = ClientManager::getInstance()->getUser(c.getFrom(), false); if(!p) return; if(c.getParameters().size() == 2 && c.getParameters()[1] == "PM") { // add PM<group-cid> as well const string& msg = c.getParameters()[0]; if(c.getFrom() == getMe()->getCID()) { p = ClientManager::getInstance()->getUser(c.getTo(), false); if(!p) return; } fire(ClientListener::PrivateMessage(), this, p, msg); } else { string msg = '<' + p->getNick() + "> " + c.getParameters()[0]; fire(ClientListener::Message(), this, msg); } }
void NmdcHub::kick(const User::Ptr& aUser, const string& aMsg) { checkstate(); dcdebug("NmdcHub::kick\n"); static const char str[] = "$To: %s From: %s $<%s> You are being kicked because: %s|<%s> %s is kicking %s because: %s|"; string msg2 = toNmdc(Util::validateMessage(aMsg, false)); char* tmp = new char[sizeof(str) + 2*aUser->getNick().length() + 2*msg2.length() + 4*getNick().length()]; const char* u = aUser->getNick().c_str(); const char* n = getNick().c_str(); const char* m = msg2.c_str(); sprintf(tmp, str, u, n, n, m, n, n, u, m); send(tmp); delete[] tmp; // Short, short break to allow the message to reach the NmdcHub... Thread::sleep(200); send("$Kick " + toNmdc(aUser->getNick()) + "|"); }
void UserGroup::EvaluateObjectRules(const User::Ptr& user) { CONTEXT("Evaluating group membership for user '" + user->GetName() + "'"); for (const ConfigItem::Ptr& group : ConfigItem::GetItems("UserGroup")) { if (!group->GetFilter()) continue; EvaluateObjectRule(user, group); } }
void SearchManager::onRES(const AdcCommand& cmd, const User::Ptr& from, const string& remoteIp) { int freeSlots = -1; int64_t size = -1; string file; string tth; string token; for(StringIterC i = cmd.getParameters().begin(); i != cmd.getParameters().end(); ++i) { const string& str = *i; if(str.compare(0, 2, "FN") == 0) { file = Util::toNmdcFile(str.substr(2)); } else if(str.compare(0, 2, "SL") == 0) { freeSlots = Util::toInt(str.substr(2)); } else if(str.compare(0, 2, "SI") == 0) { size = Util::toInt64(str.substr(2)); } else if(str.compare(0, 2, "TR") == 0) { tth = str.substr(2); } else if(str.compare(0, 2, "TO") == 0) { token = str.substr(2); } } if(!file.empty() && freeSlots != -1 && size != -1) { StringList names = ClientManager::getInstance()->getHubNames(from->getCID()); string hubName = names.empty() ? STRING(OFFLINE) : Util::toString(names); StringList hubs = ClientManager::getInstance()->getHubs(from->getCID()); string hub = hubs.empty() ? STRING(OFFLINE) : Util::toString(hubs); SearchResult::Types type = (file[file.length() - 1] == '\\' ? SearchResult::TYPE_DIRECTORY : SearchResult::TYPE_FILE); if(type == SearchResult::TYPE_FILE && tth.empty()) return; /// @todo Something about the slots SearchResult* sr = new SearchResult(from, type, 0, freeSlots, size, file, hubName, hub, remoteIp, TTHValue(tth), token); fire(SearchManagerListener::SR(), sr); sr->decRef(); } }
bool UserGroup::EvaluateObjectRule(const User::Ptr& user, const ConfigItem::Ptr& group) { String group_name = group->GetName(); CONTEXT("Evaluating rule for group '" + group_name + "'"); ScriptFrame frame; if (group->GetScope()) group->GetScope()->CopyTo(frame.Locals); frame.Locals->Set("user", user); if (!group->GetFilter()->Evaluate(frame).GetValue().ToBool()) return false; Log(LogDebug, "UserGroup") << "Assigning membership for group '" << group_name << "' to user '" << user->GetName() << "'"; Array::Ptr groups = user->GetGroups(); groups->Add(group_name); return true; }
void ClientManager::userCommand(const User::Ptr& p, const ::UserCommand& uc, StringMap& params, bool compatibility) { Lock l(cs); OnlineIter i = onlineUsers.find(p->getCID()); if(i == onlineUsers.end()) return; OnlineUser& ou = *i->second; ou.getIdentity().getParams(params, "user", compatibility); ou.getClient().getHubIdentity().getParams(params, "hub", false); ou.getClient().getMyIdentity().getParams(params, "my", compatibility); ou.getClient().escapeParams(params); ou.getClient().sendUserCmd(Util::formatParams(uc.getCommand(), params, false)); }
User::Ptr DirectoryListing::getUserFromFilename(const string& fileName) { // General file list name format: [username].[CID].[xml|xml.bz2|DcLst] string name = Util::getFileName(fileName); // Strip off any extensions if(Util::stricmp(name.c_str() + name.length() - 6, ".DcLst") == 0) { name.erase(name.length() - 6); } if(Util::stricmp(name.c_str() + name.length() - 4, ".bz2") == 0) { name.erase(name.length() - 4); } if(Util::stricmp(name.c_str() + name.length() - 4, ".xml") == 0) { name.erase(name.length() - 4); } // Find CID string::size_type i = name.rfind('.'); if(i == string::npos) { return NULL; } size_t n = name.length() - (i + 1); // CID's always 39 chars long... if(n != 39) return NULL; CID cid(name.substr(i + 1)); if(cid.isZero()) return NULL; User::Ptr p = ClientManager::getInstance()->getUser(cid); if(p->getFirstNick().empty()) p->setFirstNick(name.substr(0, i)); return p; }
Dictionary::Ptr UserDbObject::GetStatusFields(void) const { Dictionary::Ptr fields = make_shared<Dictionary>(); User::Ptr user = static_pointer_cast<User>(GetObject()); fields->Set("host_notifications_enabled", user->GetEnableNotifications()); fields->Set("service_notifications_enabled", user->GetEnableNotifications()); fields->Set("last_host_notification", DbValue::FromTimestamp(user->GetLastNotification())); fields->Set("last_service_notification", DbValue::FromTimestamp(user->GetLastNotification())); fields->Set("modified_attributes", user->GetModifiedAttributes()); fields->Set("modified_host_attributes", Empty); fields->Set("modified_service_attributes", Empty); return fields; }
void NmdcHub::onLine(const string& aLine) throw() { lastActivity = GET_TICK(); if(aLine.length() == 0) return; if(aLine[0] != '$') { // Check if we're being banned... if(state != STATE_CONNECTED) { if(Util::findSubString(aLine, "banned") != string::npos) { reconnect = false; } } Speaker<NmdcHubListener>::fire(NmdcHubListener::Message(), this, Util::validateMessage(fromNmdc(aLine), true)); return; } string cmd; string param; string::size_type x; if( (x = aLine.find(' ')) == string::npos) { cmd = aLine; } else { cmd = aLine.substr(0, x); param = aLine.substr(x+1); } if(cmd == "$Search") { if(state != STATE_CONNECTED) { return; } string::size_type i = 0; string::size_type j = param.find(' ', i); if(j == string::npos || i == j) return; string seeker = fromNmdc(param.substr(i, j-i)); // Filter own searches if(SETTING(CONNECTION_TYPE) == SettingsManager::CONNECTION_ACTIVE) { if(seeker == (getLocalIp() + ":" + Util::toString(SETTING(IN_PORT)))) { return; } } else { // Hub:seeker if(Util::stricmp(seeker.c_str() + 4, getNick().c_str()) == 0) { return; } } i = j + 1; { Lock l(cs); u_int32_t tick = GET_TICK(); seekers.push_back(make_pair(seeker, tick)); // First, check if it's a flooder FloodIter fi; for(fi = flooders.begin(); fi != flooders.end(); ++fi) { if(fi->first == seeker) { return; } } int count = 0; for(fi = seekers.begin(); fi != seekers.end(); ++fi) { if(fi->first == seeker) count++; if(count > 7) { if(seeker.compare(0, 4, "Hub:") == 0) Speaker<NmdcHubListener>::fire(NmdcHubListener::SearchFlood(), this, seeker.substr(4)); else Speaker<NmdcHubListener>::fire(NmdcHubListener::SearchFlood(), this, seeker + STRING(NICK_UNKNOWN)); flooders.push_back(make_pair(seeker, tick)); return; } } } int a; if(param[i] == 'F') { a = SearchManager::SIZE_DONTCARE; } else if(param[i+2] == 'F') { a = SearchManager::SIZE_ATLEAST; } else { a = SearchManager::SIZE_ATMOST; } i += 4; j = param.find('?', i); if(j == string::npos || i == j) return; string size = param.substr(i, j-i); i = j + 1; j = param.find('?', i); if(j == string::npos || i == j) return; int type = Util::toInt(param.substr(i, j-i)) - 1; i = j + 1; param = param.substr(i); if(param.size() > 0) { Speaker<NmdcHubListener>::fire(NmdcHubListener::Search(), this, seeker, a, Util::toInt64(size), type, fromNmdc(param)); if(seeker.compare(0, 4, "Hub:") == 0) { User::Ptr u; { Lock l(cs); User::NickIter ni = users.find(seeker.substr(4)); if(ni != users.end() && !ni->second->isSet(User::PASSIVE)) { u = ni->second; u->setFlag(User::PASSIVE); } } if(u) { updated(u); } } } } else if(cmd == "$MyINFO") { string::size_type i, j; i = 5; j = param.find(' ', i); if( (j == string::npos) || (j == i) ) return; string nick = fromNmdc(param.substr(i, j-i)); i = j + 1; User::Ptr u; dcassert(nick.size() > 0); { Lock l(cs); User::NickIter ni = users.find(nick); if(ni == users.end()) { u = users[nick] = ClientManager::getInstance()->getUser(nick, this); } else { u = ni->second; } } j = param.find('$', i); if(j == string::npos) return; string tmpDesc = Util::validateMessage(fromNmdc(param.substr(i, j-i)), true); // Look for a tag... if(tmpDesc.size() > 0 && tmpDesc[tmpDesc.size()-1] == '>') { x = tmpDesc.rfind('<'); if(x != string::npos) { // Hm, we have something... u->setTag(tmpDesc.substr(x)); tmpDesc.erase(x); } else { u->setTag(Util::emptyString); } } else { u->setTag(Util::emptyString); } u->setDescription(tmpDesc); i = j + 3; j = param.find('$', i); if(j == string::npos) return; u->setConnection(fromNmdc(param.substr(i, j-i-1))); i = j + 1; j = param.find('$', i); if(j == string::npos) return; u->setEmail(Util::validateMessage(fromNmdc(param.substr(i, j-i)), true)); i = j + 1; j = param.find('$', i); if(j == string::npos) return; u->setBytesShared(param.substr(i, j-i)); Speaker<NmdcHubListener>::fire(NmdcHubListener::MyInfo(), this, u); } else if(cmd == "$Quit") { if(!param.empty()) { User::Ptr u; { Lock l(cs); User::NickIter i = users.find(fromNmdc(param)); if(i == users.end()) { dcdebug("C::onLine Quitting user %s not found\n", param.c_str()); return; } u = i->second; users.erase(i); } Speaker<NmdcHubListener>::fire(NmdcHubListener::Quit(), this, u); ClientManager::getInstance()->putUserOffline(u, true); } } else if(cmd == "$ConnectToMe") { if(state != STATE_CONNECTED) { return; } string::size_type i = param.find(' '); string::size_type j; if( (i == string::npos) || ((i + 1) >= param.size()) ) { return; } i++; j = param.find(':', i); if(j == string::npos) { return; } string server = fromNmdc(param.substr(i, j-i)); if(j+1 >= param.size()) { return; } string port = param.substr(j+1); ConnectionManager::getInstance()->connect(server, (short)Util::toInt(port), getNick()); Speaker<NmdcHubListener>::fire(NmdcHubListener::ConnectToMe(), this, server, (short)Util::toInt(port)); } else if(cmd == "$RevConnectToMe") { if(state != STATE_CONNECTED) { return; } User::Ptr u; bool up = false; { Lock l(cs); string::size_type j = param.find(' '); if(j == string::npos) { return; } User::NickIter i = users.find(fromNmdc(param.substr(0, j))); if(i == users.end()) { return; } u = i->second; if(!u->isSet(User::PASSIVE)) { u->setFlag(User::PASSIVE); up = true; } } if(u) { if(SETTING(CONNECTION_TYPE) == SettingsManager::CONNECTION_ACTIVE) { connectToMe(u); Speaker<NmdcHubListener>::fire(NmdcHubListener::RevConnectToMe(), this, u); } else { // Notify the user that we're passive too... if(up) revConnectToMe(u); } if(up) updated(u); } } else if(cmd == "$SR") { SearchManager::getInstance()->onSearchResult(aLine); } else if(cmd == "$HubName") { name = fromNmdc(param); Speaker<NmdcHubListener>::fire(NmdcHubListener::HubName(), this); } else if(cmd == "$Supports") { StringTokenizer<string> st(param, ' '); StringList& sl = st.getTokens(); for(StringIter i = sl.begin(); i != sl.end(); ++i) { if(*i == "UserCommand") { supportFlags |= SUPPORTS_USERCOMMAND; } else if(*i == "NoGetINFO") { supportFlags |= SUPPORTS_NOGETINFO; } else if(*i == "UserIP2") { supportFlags |= SUPPORTS_USERIP2; } } Speaker<NmdcHubListener>::fire(NmdcHubListener::Supports(), this, sl); } else if(cmd == "$UserCommand") { string::size_type i = 0; string::size_type j = param.find(' '); if(j == string::npos) return; int type = Util::toInt(param.substr(0, j)); i = j+1; if(type == UserCommand::TYPE_SEPARATOR || type == UserCommand::TYPE_CLEAR) { int ctx = Util::toInt(param.substr(i)); Speaker<NmdcHubListener>::fire(NmdcHubListener::UserCommand(), this, type, ctx, Util::emptyString, Util::emptyString); } else if(type == UserCommand::TYPE_RAW || type == UserCommand::TYPE_RAW_ONCE) { j = param.find(' ', i); if(j == string::npos) return; int ctx = Util::toInt(param.substr(i)); i = j+1; j = param.find('$'); if(j == string::npos) return; string name = fromNmdc(param.substr(i, j-i)); i = j+1; string command = fromNmdc(param.substr(i, param.length() - i)); Speaker<NmdcHubListener>::fire(NmdcHubListener::UserCommand(), this, type, ctx, Util::validateMessage(name, true, false), Util::validateMessage(command, true, false)); } } else if(cmd == "$Lock") { if(state != STATE_LOCK) { return; } state = STATE_HELLO; if(!param.empty()) { string::size_type j = param.find(" Pk="); string lock, pk; if( j != string::npos ) { lock = param.substr(0, j); pk = param.substr(j + 4); } else { // Workaround for faulty linux hubs... j = param.find(" "); if(j != string::npos) lock = param.substr(0, j); else lock = param; } if(CryptoManager::getInstance()->isExtended(lock)) { StringList feat; feat.push_back("UserCommand"); feat.push_back("NoGetINFO"); feat.push_back("NoHello"); feat.push_back("UserIP2"); feat.push_back("TTHSearch"); if(BOOLSETTING(COMPRESS_TRANSFERS)) feat.push_back("GetZBlock"); supports(feat); } key(CryptoManager::getInstance()->makeKey(lock)); validateNick(getNick()); Speaker<NmdcHubListener>::fire(NmdcHubListener::CLock(), this, lock, pk); } } else if(cmd == "$Hello") { if(!param.empty()) { string nick = fromNmdc(param); User::Ptr u = ClientManager::getInstance()->getUser(nick, this); { Lock l(cs); users[nick] = u; } if(getNick() == nick) { setMe(u); u->setFlag(User::DCPLUSPLUS); if(SETTING(CONNECTION_TYPE) != SettingsManager::CONNECTION_ACTIVE) u->setFlag(User::PASSIVE); else u->unsetFlag(User::PASSIVE); } if(state == STATE_HELLO) { state = STATE_CONNECTED; updateCounts(false); version(); getNickList(); myInfo(); } Speaker<NmdcHubListener>::fire(NmdcHubListener::Hello(), this, u); } } else if(cmd == "$ForceMove") { disconnect(); Speaker<NmdcHubListener>::fire(NmdcHubListener::Redirect(), this, param); } else if(cmd == "$HubIsFull") { Speaker<NmdcHubListener>::fire(NmdcHubListener::HubFull(), this); } else if(cmd == "$ValidateDenide") { // Mind the spelling... disconnect(); Speaker<NmdcHubListener>::fire(NmdcHubListener::ValidateDenied(), this); } else if(cmd == "$UserIP") { if(!param.empty()) { User::List v; StringTokenizer<string> t(fromNmdc(param), "$$"); StringList& l = t.getTokens(); for(StringIter it = l.begin(); it != l.end(); ++it) { string::size_type j = 0; if((j = it->find(' ')) == string::npos) continue; if((j+1) == it->length()) continue; v.push_back(ClientManager::getInstance()->getUser(it->substr(0, j), this)); v.back()->setIp(it->substr(j+1)); } Speaker<NmdcHubListener>::fire(NmdcHubListener::UserIp(), this, v); } } else if(cmd == "$NickList") { if(!param.empty()) { User::List v; StringTokenizer<string> t(fromNmdc(param), "$$"); StringList& sl = t.getTokens(); for(StringIter it = sl.begin(); it != sl.end(); ++it) { v.push_back(ClientManager::getInstance()->getUser(*it, this)); } { Lock l(cs); for(User::Iter it2 = v.begin(); it2 != v.end(); ++it2) { users[(*it2)->getNick()] = *it2; } } if(!(getSupportFlags() & SUPPORTS_NOGETINFO)) { string tmp; // Let's assume 10 characters per nick... tmp.reserve(v.size() * (11 + 10 + getNick().length())); for(User::List::const_iterator i = v.begin(); i != v.end(); ++i) { tmp += "$GetINFO "; tmp += (*i)->getNick(); tmp += ' '; tmp += getNick(); tmp += '|'; } if(!tmp.empty()) { send(tmp); } } Speaker<NmdcHubListener>::fire(NmdcHubListener::NickList(), this, v); } } else if(cmd == "$OpList") { if(!param.empty()) { User::List v; StringTokenizer<string> t(fromNmdc(param), "$$"); StringList& sl = t.getTokens(); for(StringIter it = sl.begin(); it != sl.end(); ++it) { v.push_back(ClientManager::getInstance()->getUser(*it, this)); v.back()->setFlag(User::OP); } { Lock l(cs); for(User::Iter it2 = v.begin(); it2 != v.end(); ++it2) { users[(*it2)->getNick()] = *it2; } } Speaker<NmdcHubListener>::fire(NmdcHubListener::OpList(), this, v); updateCounts(false); // Special...to avoid op's complaining that their count is not correctly // updated when they log in (they'll be counted as registered first...) myInfo(); } } else if(cmd == "$To:") { string::size_type i = param.find("From:"); if(i != string::npos) { i+=6; string::size_type j = param.find("$"); if(j != string::npos) { string from = fromNmdc(param.substr(i, j - 1 - i)); if(from.size() > 0 && param.size() > (j + 1)) { Speaker<NmdcHubListener>::fire(NmdcHubListener::PrivateMessage(), this, ClientManager::getInstance()->getUser(from, this, false), Util::validateMessage(fromNmdc(param.substr(j + 1)), true)); } } } } else if(cmd == "$GetPass") { setRegistered(true); Speaker<NmdcHubListener>::fire(NmdcHubListener::GetPassword(), this); } else if(cmd == "$BadPass") { Speaker<NmdcHubListener>::fire(NmdcHubListener::BadPassword(), this); } else if(cmd == "$LogedIn") { Speaker<NmdcHubListener>::fire(NmdcHubListener::LoggedIn(), this); } else { dcassert(cmd[0] == '$'); dcdebug("NmdcHub::onLine Unknown command %s\n", aLine.c_str()); } }