adchub.cpp
来自「一个不错的关于手机模块程序This page contains everythi」· C++ 代码 · 共 556 行 · 第 1/2 页
CPP
556 行
}
void AdcHub::sendUDP(const AdcCommand& cmd) {
try {
Socket s;
s.create(Socket::TYPE_UDP);
Lock l(cs);
SIDMap::const_iterator i = users.find(cmd.getTo());
if(i == users.end()) {
dcdebug("AdcHub::sendUDP: invalid user\n");
return;
}
OnlineUser& u = *i->second;
string tmp = cmd.toString(u.getUser()->getCID());
if(u.getIdentity().isUdpActive()) {
try {
s.writeTo(u.getIdentity().getIp(), (short)Util::toInt(u.getIdentity().getUdpPort()), tmp);
} catch(const SocketException& e) {
dcdebug("AdcHub::sendUDP: write failed: %s\n", e.getError().c_str());
}
}
} catch(SocketException&) {
dcdebug("Can't create UDP socket\n");
}
}
void AdcHub::handle(AdcCommand::STA, AdcCommand& c) throw() {
if(c.getParameters().size() < 2)
return;
OnlineUser* u = findUser(c.getFrom());
if(!u)
return;
// @todo Check for invalid protocol and unset SSL if necessary
fire(ClientListener::Message(), this, *u, c.getParam(1));
}
void AdcHub::handle(AdcCommand::SCH, AdcCommand& c) throw() {
OnlineUser* ou = findUser(c.getFrom());
if(!ou) {
dcdebug("Invalid user in AdcHub::onSCH\n");
return;
}
fire(ClientListener::AdcSearch(), this, c, ou->getUser()->getCID());
}
void AdcHub::handle(AdcCommand::RES, AdcCommand& c) throw() {
OnlineUser* ou = findUser(c.getFrom());
if(!ou) {
dcdebug("Invalid user in AdcHub::onRES\n");
return;
}
SearchManager::getInstance()->onRES(c, ou->getUser());
}
void AdcHub::connect(const OnlineUser& user) {
u_int32_t r = Util::rand();
connect(user, Util::toString(r), BOOLSETTING(USE_SSL) && user.getUser()->isSet(User::SSL));
}
void AdcHub::connect(const OnlineUser& user, string const& token, bool secure) {
if(state != STATE_NORMAL)
return;
const string& proto = secure ? SECURE_CLIENT_PROTOCOL : CLIENT_PROTOCOL;
short port = secure ? ConnectionManager::getInstance()->getSecurePort() : ConnectionManager::getInstance()->getPort();
if(ClientManager::getInstance()->isActive()) {
send(AdcCommand(AdcCommand::CMD_CTM, user.getIdentity().getSID()).addParam(proto).addParam(Util::toString(port)).addParam(token));
} else {
send(AdcCommand(AdcCommand::CMD_RCM, user.getIdentity().getSID()).addParam(proto));
}
}
void AdcHub::disconnect(bool graceless) {
Client::disconnect(graceless);
state = STATE_PROTOCOL;
clearUsers();
}
void AdcHub::hubMessage(const string& aMessage) {
if(state != STATE_NORMAL)
return;
send(AdcCommand(AdcCommand::CMD_MSG, AdcCommand::TYPE_BROADCAST).addParam(aMessage));
}
void AdcHub::privateMessage(const OnlineUser& user, const string& aMessage) {
if(state != STATE_NORMAL)
return;
send(AdcCommand(AdcCommand::CMD_MSG, user.getIdentity().getSID()).addParam(aMessage).addParam("PM", getMySID()));
}
void AdcHub::search(int aSizeMode, int64_t aSize, int aFileType, const string& aString, const string& aToken) {
if(state != STATE_NORMAL)
return;
AdcCommand c(AdcCommand::CMD_SCH, AdcCommand::TYPE_BROADCAST);
if(aFileType == SearchManager::TYPE_TTH) {
c.addParam("TR", aString);
} else {
if(aSizeMode == SearchManager::SIZE_ATLEAST) {
c.addParam("GE", Util::toString(aSize));
} else if(aSizeMode == SearchManager::SIZE_ATMOST) {
c.addParam("LE", Util::toString(aSize));
}
StringTokenizer<string> st(aString, ' ');
for(StringIter i = st.getTokens().begin(); i != st.getTokens().end(); ++i) {
c.addParam("AN", *i);
}
if(aFileType == SearchManager::TYPE_DIRECTORY) {
c.addParam("TY", "2");
}
}
if(!aToken.empty())
c.addParam("TO", aToken);
if(ClientManager::getInstance()->isActive()) {
send(c);
} else {
c.setType(AdcCommand::TYPE_FEATURE);
c.setFeatures("+TCP4");
send(c);
}
}
void AdcHub::password(const string& pwd) {
if(state != STATE_VERIFY)
return;
if(!salt.empty()) {
size_t saltBytes = salt.size() * 5 / 8;
AutoArray<u_int8_t> buf(saltBytes);
Encoder::fromBase32(salt.c_str(), buf, saltBytes);
TigerHash th;
CID cid = getMyIdentity().getUser()->getCID();
th.update(cid.data(), CID::SIZE);
th.update(pwd.data(), pwd.length());
th.update(buf, saltBytes);
send(AdcCommand(AdcCommand::CMD_PAS, AdcCommand::TYPE_HUB).addParam(Encoder::toBase32(th.finalize(), TigerHash::HASH_SIZE)));
salt.clear();
}
}
void AdcHub::info(bool /*alwaysSend*/) {
if(state != STATE_IDENTIFY && state != STATE_NORMAL)
return;
reloadSettings(false);
AdcCommand c(AdcCommand::CMD_INF, AdcCommand::TYPE_BROADCAST);
string tmp;
StringMapIter i;
#define ADDPARAM(var, content) \
tmp = content; \
if((i = lastInfoMap.find(var)) != lastInfoMap.end()) { \
if(i->second != tmp) { \
if(tmp.empty()) \
lastInfoMap.erase(i); \
else \
i->second = tmp; \
c.addParam(var, tmp); \
} \
} else if(!tmp.empty()) { \
c.addParam(var, tmp); \
lastInfoMap[var] = tmp; \
}
updateCounts(false); \
ADDPARAM("ID", ClientManager::getInstance()->getMyCID().toBase32());
ADDPARAM("PD", ClientManager::getInstance()->getMyPID().toBase32());
ADDPARAM("NI", getMyIdentity().getNick());
ADDPARAM("DE", getMyIdentity().getDescription());
ADDPARAM("SL", Util::toString(SETTING(SLOTS)));
ADDPARAM("SS", ShareManager::getInstance()->getShareSizeString());
ADDPARAM("SF", Util::toString(ShareManager::getInstance()->getSharedFiles()));
ADDPARAM("EM", SETTING(EMAIL));
ADDPARAM("HN", Util::toString(counts.normal));
ADDPARAM("HR", Util::toString(counts.registered));
ADDPARAM("HO", Util::toString(counts.op));
ADDPARAM("VE", "++ " VERSIONSTRING);
string su;
if(SSLSocketFactory::getInstance()->hasCerts()) {
su += ADCS_FEATURE + ",";
}
if(ClientManager::getInstance()->isActive()) {
if(BOOLSETTING(NO_IP_OVERRIDE) && !SETTING(EXTERNAL_IP).empty()) {
ADDPARAM("I4", Socket::resolve(SETTING(EXTERNAL_IP)));
} else {
ADDPARAM("I4", "0.0.0.0");
}
ADDPARAM("U4", Util::toString(SearchManager::getInstance()->getPort()));
su += TCP4_FEATURE + ",";
su += UDP4_FEATURE + ",";
} else {
ADDPARAM("I4", "");
ADDPARAM("U4", "");
}
if(!su.empty()) {
su.erase(su.size() - 1);
}
ADDPARAM("SU", su);
#undef ADDPARAM
if(c.getParameters().size() > 0) {
send(c);
}
}
int64_t AdcHub::getAvailable() const {
Lock l(cs);
int64_t x = 0;
for(SIDMap::const_iterator i = users.begin(); i != users.end(); ++i) {
x+=i->second->getIdentity().getBytesShared();
}
return x;
}
string AdcHub::checkNick(const string& aNick) {
string tmp = aNick;
string::size_type i = 0;
while( (i = tmp.find_first_of(" ", i)) != string::npos) {
tmp[i++]='_';
}
return tmp;
}
void AdcHub::on(Connected) throw() {
dcassert(state == STATE_PROTOCOL);
lastInfoMap.clear();
reconnect = true;
send(AdcCommand(AdcCommand::CMD_SUP, AdcCommand::TYPE_HUB).addParam("ADBAS0"));
fire(ClientListener::Connected(), this);
}
void AdcHub::on(Line, const string& aLine) throw() {
if(BOOLSETTING(ADC_DEBUG)) {
fire(ClientListener::StatusMessage(), this, "<ADC>" + aLine + "</ADC>");
}
dispatch(aLine);
}
void AdcHub::on(Failed, const string& aLine) throw() {
clearUsers();
state = STATE_PROTOCOL;
fire(ClientListener::Failed(), this, aLine);
}
void AdcHub::on(TimerManagerListener::Second, u_int32_t aTick) throw() {
if(socket && (getLastActivity() + getReconnDelay() * 1000) < aTick) {
// Nothing's happened for ~120 seconds, check if we're connected, if not, try to connect...
if(!isConnected()) {
// Try to reconnect...
if(reconnect && !getAddress().empty())
Client::connect();
}
}
}
void AdcHub::send(const AdcCommand& cmd) {
dcassert(socket);
if(!socket)
return;
if(cmd.getType() == AdcCommand::TYPE_UDP)
sendUDP(cmd);
send(cmd.toString(sid));
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?