diff --git a/ClientCommand.cpp b/ClientCommand.cpp index af555dc4..dbcaf36d 100644 --- a/ClientCommand.cpp +++ b/ClientCommand.cpp @@ -928,41 +928,22 @@ void CClient::UserCommand(const CString& sLine) { PutStatus("BufferCount for [" + sChan + "] set to [" + CString(pChan->GetBufferCount()) + "]"); } else if (m_pUser->IsAdmin() && sCommand.Equals("TRAFFIC")) { - CZNC::Get().UpdateTrafficStats(); - const map& msUsers = CZNC::Get().GetUserMap(); + map >::const_iterator it; + map > traffic = + CZNC::Get().GetTrafficStats(); CTable Table; Table.AddColumn("Username"); Table.AddColumn("In"); Table.AddColumn("Out"); Table.AddColumn("Total"); - unsigned long long users_total_in = 0; - unsigned long long users_total_out = 0; - for (map::const_iterator it = msUsers.begin(); it != msUsers.end(); it++) { + + for (it = traffic.begin(); it != traffic.end(); it++) { Table.AddRow(); Table.SetCell("Username", it->first); - Table.SetCell("In", CString::ToByteStr(it->second->BytesRead())); - Table.SetCell("Out", CString::ToByteStr(it->second->BytesWritten())); - Table.SetCell("Total", CString::ToByteStr(it->second->BytesRead() + it->second->BytesWritten())); - users_total_in += it->second->BytesRead(); - users_total_out += it->second->BytesWritten(); + Table.SetCell("In", CString::ToByteStr(it->second.first)); + Table.SetCell("Out", CString::ToByteStr(it->second.second)); + Table.SetCell("Total", CString::ToByteStr(it->second.first + it->second.second)); } - Table.AddRow(); - Table.SetCell("Username", ""); - Table.SetCell("In", CString::ToByteStr(users_total_in)); - Table.SetCell("Out", CString::ToByteStr(users_total_out)); - Table.SetCell("Total", CString::ToByteStr(users_total_in + users_total_out)); - - Table.AddRow(); - Table.SetCell("Username", ""); - Table.SetCell("In", CString::ToByteStr(CZNC::Get().BytesRead())); - Table.SetCell("Out", CString::ToByteStr(CZNC::Get().BytesWritten())); - Table.SetCell("Total", CString::ToByteStr(CZNC::Get().BytesRead() + CZNC::Get().BytesWritten())); - - Table.AddRow(); - Table.SetCell("Username", ""); - Table.SetCell("In", CString::ToByteStr(users_total_in + CZNC::Get().BytesRead())); - Table.SetCell("Out", CString::ToByteStr(users_total_out + CZNC::Get().BytesWritten())); - Table.SetCell("Total", CString::ToByteStr(users_total_in + CZNC::Get().BytesRead() + users_total_out + CZNC::Get().BytesWritten())); PutStatus(Table); } else if (m_pUser->IsAdmin() && sCommand.Equals("UPTIME")) { diff --git a/znc.cpp b/znc.cpp index d29db9e6..b52b6934 100644 --- a/znc.cpp +++ b/znc.cpp @@ -1726,23 +1726,46 @@ CZNC& CZNC::Get() { return *pZNC; } -void CZNC::UpdateTrafficStats() { - CSockManager* p = &m_Manager; - for (unsigned int a = 0; a < p->size(); a++) { - if ((*p)[a]->GetSockName().Left(5) == "IRC::") { - CIRCSock *i = (CIRCSock *)(*p)[a]; - i->GetUser()->AddBytesRead((*p)[a]->GetBytesRead()); - (*p)[a]->ResetBytesRead(); - i->GetUser()->AddBytesWritten((*p)[a]->GetBytesWritten()); - (*p)[a]->ResetBytesWritten(); - } else if ((*p)[a]->GetSockName().Left(5) == "USR::") { - CClient *c = (CClient *)(*p)[a]; - c->GetUser()->AddBytesRead((*p)[a]->GetBytesRead()); - (*p)[a]->ResetBytesRead(); - c->GetUser()->AddBytesWritten((*p)[a]->GetBytesWritten()); - (*p)[a]->ResetBytesWritten(); +map > CZNC::GetTrafficStats() { + map > ret; + unsigned long long uiUsers_in, uiUsers_out, uiZNC_in, uiZNC_out; + const map& msUsers = CZNC::Get().GetUserMap(); + + uiUsers_in = uiUsers_out = 0; + uiZNC_in = BytesRead(); + uiZNC_out = BytesWritten(); + + for (map::const_iterator it = msUsers.begin(); it != msUsers.end(); it++) { + ret[it->first] = std::pair + (it->second->BytesRead(), it->second->BytesWritten()); + uiUsers_in += it->second->BytesRead(); + uiUsers_out += it->second->BytesWritten(); + } + + for (CSockManager::const_iterator it = m_Manager.begin(); it != m_Manager.end(); it++) { + if ((*it)->GetSockName().Left(5) == "IRC::") { + CIRCSock *p = (CIRCSock *) *it; + ret[p->GetUser()->GetUserName()].first += p->GetBytesRead(); + ret[p->GetUser()->GetUserName()].second += p->GetBytesWritten(); + uiUsers_in += p->GetBytesRead(); + uiUsers_out += p->GetBytesWritten(); + } else if ((*it)->GetSockName().Left(5) == "USR::") { + CClient *p = (CClient *) *it; + ret[p->GetUser()->GetUserName()].first += p->GetBytesRead(); + ret[p->GetUser()->GetUserName()].second += p->GetBytesWritten(); + uiUsers_in += p->GetBytesRead(); + uiUsers_out += p->GetBytesWritten(); + } else { + uiZNC_in += (*it)->GetBytesRead(); + uiZNC_out += (*it)->GetBytesWritten(); } } + + ret[""] = std::pair(uiUsers_in, uiUsers_out); + ret[""] = std::pair(uiZNC_in, uiZNC_out); + ret[""] = std::pair(uiUsers_in + uiZNC_in, uiUsers_out + uiZNC_out); + + return ret; } void CZNC::AuthUser(CSmartPtr AuthClass) { diff --git a/znc.h b/znc.h index 44913dcf..3549cb68 100644 --- a/znc.h +++ b/znc.h @@ -124,7 +124,10 @@ public: void AddBytesWritten(unsigned long long u) { m_uBytesWritten += u; } unsigned long long BytesRead() const { return m_uBytesRead; } unsigned long long BytesWritten() const { return m_uBytesWritten; } - void UpdateTrafficStats(); + // Returns a map which maps user names to , special + // "usernames" are (All users total), (Traffic which couldn't be + // accounted to any user) and (Total traffic, + ). + map > GetTrafficStats(); // Authenticate a user. // The result is passed back via callbacks to CAuthBase.