📄 clientmanager.cpp
字号:
}
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 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 ClientManager::send(AdcCommand& cmd, const CID& cid) {
Lock l(cs);
OnlineIter i = onlineUsers.find(cid);
if(i != onlineUsers.end()) {
OnlineUser& u = *i->second;
if(cmd.getType() == AdcCommand::TYPE_UDP && !u.getIdentity().isUdpActive()) {
cmd.setType(AdcCommand::TYPE_DIRECT);
cmd.setTo(u.getIdentity().getSID());
u.getClient().send(cmd);
} else {
try {
s.writeTo(u.getIdentity().getIp(), static_cast<short>(Util::toInt(u.getIdentity().getUdpPort())), cmd.toString(getMe()->getCID()));
} catch(const SocketException&) {
dcdebug("Socket exception sending ADC UDP command\n");
}
}
}
}
void ClientManager::infoUpdated() {
Lock l(cs);
for(Client::Iter i = clients.begin(); i != clients.end(); ++i) {
if((*i)->isConnected()) {
(*i)->info(false);
}
}
}
void ClientManager::on(NmdcSearch, Client* aClient, const string& aSeeker, int aSearchType, int64_t aSize,
int aFileType, const string& aString) throw()
{
Speaker<ClientManagerListener>::fire(ClientManagerListener::IncomingSearch(), aString);
bool isPassive = (aSeeker.compare(0, 4, "Hub:") == 0);
// We don't wan't to answer passive searches if we're in passive mode...
if(isPassive && !ClientManager::getInstance()->isActive()) {
return;
}
SearchResult::List l;
ShareManager::getInstance()->search(l, aString, aSearchType, aSize, aFileType, aClient, isPassive ? 5 : 10);
// dcdebug("Found %d items (%s)\n", l.size(), aString.c_str());
if(l.size() > 0) {
if(isPassive) {
string name = aSeeker.substr(4);
// Good, we have a passive seeker, those are easier...
string str;
for(SearchResult::Iter i = l.begin(); i != l.end(); ++i) {
SearchResult* sr = *i;
str += sr->toSR(*aClient);
str[str.length()-1] = 5;
str += name;
str += '|';
sr->decRef();
}
if(str.size() > 0)
aClient->send(str);
} else {
try {
string ip, file;
u_int16_t port = 0;
Util::decodeUrl(aSeeker, ip, port, file);
ip = Socket::resolve(ip);
if(port == 0) port = 412;
for(SearchResult::Iter i = l.begin(); i != l.end(); ++i) {
SearchResult* sr = *i;
s.writeTo(ip, port, sr->toSR(*aClient));
sr->decRef();
}
} catch(const SocketException& /* e */) {
dcdebug("Search caught error\n");
}
}
}
}
void ClientManager::userCommand(const User::Ptr& p, const ::UserCommand& uc, StringMap& params, bool compatibility) {
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));
}
void ClientManager::on(AdcSearch, Client*, const AdcCommand& adc, const CID& from) throw() {
SearchManager::getInstance()->respond(adc, from);
}
Identity ClientManager::getIdentity(const User::Ptr& aUser) {
OnlineIter i = onlineUsers.find(aUser->getCID());
if(i != onlineUsers.end()) {
return i->second->getIdentity();
}
return Identity(aUser, Util::emptyString, 0);
}
void ClientManager::search(int aSizeMode, int64_t aSize, int aFileType, const string& aString, const string& aToken) {
Lock l(cs);
updateCachedIp(); // no point in doing a resolve for every single hub we're searching on
for(Client::Iter i = clients.begin(); i != clients.end(); ++i) {
if((*i)->isConnected()) {
(*i)->search(aSizeMode, aSize, aFileType, aString, aToken);
}
}
}
void ClientManager::search(StringList& who, int aSizeMode, int64_t aSize, int aFileType, const string& aString, const string& aToken) {
Lock l(cs);
updateCachedIp(); // no point in doing a resolve for every single hub we're searching on
for(StringIter it = who.begin(); it != who.end(); ++it) {
string& client = *it;
for(Client::Iter j = clients.begin(); j != clients.end(); ++j) {
Client* c = *j;
if(c->isConnected() && c->getHubUrl() == client) {
c->search(aSizeMode, aSize, aFileType, aString, aToken);
}
}
}
}
void ClientManager::on(TimerManagerListener::Minute, u_int32_t /* aTick */) throw() {
Lock l(cs);
// Collect some garbage...
UserIter i = users.begin();
while(i != users.end()) {
if(i->second->unique()) {
users.erase(i++);
} else {
++i;
}
}
for(Client::Iter j = clients.begin(); j != clients.end(); ++j) {
(*j)->info(false);
}
}
void ClientManager::save() {
Lock l(cs);
try {
string tmp;
File ff(getUsersFile() + ".tmp", File::WRITE, File::CREATE | File::TRUNCATE);
BufferedOutputStream<false> f(&ff);
f.write(SimpleXML::utf8Header);
f.write(LIT("<Users Version=\"1\">\r\n"));
for(UserIter i = users.begin(); i != users.end(); ++i) {
User::Ptr& p = i->second;
if(p->isSet(User::SAVE_NICK) && !p->getCID().isZero() && !p->getFirstNick().empty()) {
f.write(LIT("\t<User CID=\""));
f.write(p->getCID().toBase32());
f.write(LIT("\" Nick=\""));
f.write(SimpleXML::escape(p->getFirstNick(), tmp, true));
f.write(LIT("\"/>\r\n"));
}
}
f.write("</Users>\r\n");
f.flush();
ff.close();
File::deleteFile(getUsersFile());
File::renameFile(getUsersFile() + ".tmp", getUsersFile());
} catch(const FileException&) {
// ...
}
}
void ClientManager::on(Save, SimpleXML*) throw() {
save();
}
User::Ptr& ClientManager::getMe() {
if(!me) {
Lock l(cs);
if(!me) {
me = new User(getMyCID());
me->setFirstNick(SETTING(NICK));
}
}
return me;
}
const CID& ClientManager::getMyPID() {
if(pid.isZero())
pid = CID(SETTING(PRIVATE_ID));
return pid;
}
CID ClientManager::getMyCID() {
TigerHash tiger;
tiger.update(getMyPID().data(), CID::SIZE);
return CID(tiger.finalize());
}
void ClientManager::on(Load, SimpleXML*) throw() {
users.insert(make_pair(getMe()->getCID(), getMe()));
try {
SimpleXML xml;
xml.fromXML(File(getUsersFile(), File::READ, File::OPEN).read());
if(xml.findChild("Users") && xml.getChildAttrib("Version") == "1") {
xml.stepIn();
while(xml.findChild("User")) {
const string& cid = xml.getChildAttrib("CID");
const string& nick = xml.getChildAttrib("Nick");
if(cid.length() != 39 || nick.empty())
continue;
User::Ptr p(new User(CID(cid)));
p->setFirstNick(xml.getChildData());
users.insert(make_pair(p->getCID(), p));
}
}
} catch(const Exception& e) {
dcdebug("Error loading Users.xml: %s\n", e.getError().c_str());
}
}
void ClientManager::on(Failed, Client* client, const string&) throw() {
FavoriteManager::getInstance()->removeUserCommand(client->getHubUrl());
fire(ClientManagerListener::ClientDisconnected(), client);
}
void ClientManager::on(UserCommand, Client* client, int aType, int ctx, const string& name, const string& command) throw() {
if(BOOLSETTING(HUB_USER_COMMANDS)) {
if(aType == ::UserCommand::TYPE_CLEAR) {
FavoriteManager::getInstance()->removeHubUserCommands(ctx, client->getHubUrl());
} else {
FavoriteManager::getInstance()->addUserCommand(aType, ctx, ::UserCommand::FLAG_NOSAVE, name, command, client->getHubUrl());
}
}
}
void ClientManager::updateCachedIp() {
// Best case - the server detected it
if((!BOOLSETTING(NO_IP_OVERRIDE) || SETTING(EXTERNAL_IP).empty())) {
for(Client::Iter i = clients.begin(); i != clients.end(); ++i) {
if(!(*i)->getMyIdentity().getIp().empty()) {
cachedIp = (*i)->getMyIdentity().getIp();
return;
}
}
}
if(!SETTING(EXTERNAL_IP).empty()) {
cachedIp = Socket::resolve(SETTING(EXTERNAL_IP));
return;
}
//if we've come this far just use the first client to get the ip.
if(clients.size() > 0)
cachedIp = (*clients.begin())->getLocalIp();
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -