📄 client.cpp
字号:
u = i->second;
if(!u->isSet(User::PASSIVE)) {
u->setFlag(User::PASSIVE);
up = true;
}
}
if(u) {
if(SETTING(CONNECTION_TYPE) == SettingsManager::CONNECTION_ACTIVE) {
fire(ClientListener::REV_CONNECT_TO_ME, 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 = param;
fire(ClientListener::HUB_NAME, this);
} 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;
}
fire(ClientListener::C_LOCK, this, lock, pk);
}
} else if(cmd == "$Hello") {
if(!param.empty()) {
User::Ptr& u = ClientManager::getInstance()->getUser(param, this);
{
Lock l(cs);
users[param] = u;
}
if(u->getNick() == getNick()) {
if(state == STATE_HELLO) {
state = STATE_CONNECTED;
updateCounts(false);
u->setFlag(User::DCPLUSPLUS);
if(SETTING(CONNECTION_TYPE) != SettingsManager::CONNECTION_ACTIVE)
u->setFlag(User::PASSIVE);
}
}
fire(ClientListener::HELLO, this, u);
}
} else if(cmd == "$ForceMove") {
disconnect();
fire(ClientListener::FORCE_MOVE, this, param);
} else if(cmd == "$HubIsFull") {
fire(ClientListener::HUB_FULL, this);
} else if(cmd == "$ValidateDenide") { // Mind the spelling...
disconnect();
fire(ClientListener::VALIDATE_DENIED, this);
} else if(cmd == "$NickList") {
if(!param.empty()) {
User::List v;
string::size_type j, k = 0;
{
Lock l(cs);
while( (j=param.find("$$", k)) != string::npos) {
if(j == k) {
k += 2;
continue;
}
string nick = param.substr(k, j-k);
User::Ptr& u = ClientManager::getInstance()->getUser(nick, this);
users[nick] = u;
v.push_back(u);
k = j + 2;
}
}
fire(ClientListener::NICK_LIST, this, v);
}
} else if(cmd == "$OpList") {
if(!param.empty()) {
User::List v;
string::size_type j, k;
k = 0;
{
Lock l(cs);
while( (j=param.find("$$", k)) != string::npos) {
if(j == k) {
k += 2;
continue;
}
string nick = param.substr(k, j-k);
User::Ptr& u = ClientManager::getInstance()->getUser(nick, this);
users[nick] = u;
u->setFlag(User::OP);
v.push_back(u);
k = j + 2;
}
}
fire(ClientListener::OP_LIST, 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...)
if(lastCounts != counts) {
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 = param.substr(i, j - 1 - i);
if(from.size() > 0 && param.size() > (j + 1)) {
fire(ClientListener::PRIVATE_MESSAGE, this, ClientManager::getInstance()->getUser(from, this, false), Util::validateMessage(param.substr(j + 1), true));
}
}
}
} else if(cmd == "$GetPass") {
registered = true;
fire(ClientListener::GET_PASSWORD, this);
} else if(cmd == "$BadPass") {
fire(ClientListener::BAD_PASSWORD, this);
} else if(cmd == "$LogedIn") {
fire(ClientListener::LOGGED_IN, this);
} else {
dcassert(cmd[0] == '$');
dcdebug("Client::onLine Unknown command %s\n", aLine.c_str());
}
}
void Client::myInfo() {
checkstate();
dcdebug("MyInfo %s...\n", getNick().c_str());
lastCounts = counts;
string tmp1 = ";**\x1fU9";
string tmp2 = "+L9";
string tmp3 = "+G9";
string tmp4 = "+R9";
string tmp5 = "+N9";
string::size_type i;
for(i = 0; i < 6; i++) {
tmp1[i]++;
}
for(i = 0; i < 3; i++) {
tmp2[i]++; tmp3[i]++; tmp4[i]++; tmp5[i]++;
}
char modeChar = '?';
if(SETTING(CONNECTION_TYPE) == SettingsManager::CONNECTION_ACTIVE)
modeChar = 'A';
else if(SETTING(CONNECTION_TYPE) == SettingsManager::CONNECTION_PASSIVE)
modeChar = 'P';
else if(SETTING(CONNECTION_TYPE) == SettingsManager::CONNECTION_SOCKS5)
modeChar = '5';
string uMin = (SETTING(MIN_UPLOAD_SPEED) == 0) ? Util::emptyString : tmp5 + Util::toString(SETTING(MIN_UPLOAD_SPEED));
send("$MyINFO $ALL " + Util::validateNick(getNick()) + " " + Util::validateMessage(getDescription(), false) +
tmp1 + VERSIONSTRING + tmp2 + modeChar + tmp3 + getCounts() + tmp4 + Util::toString(SETTING(SLOTS)) + uMin +
">$ $" + SETTING(CONNECTION) + "\x01$" + Util::validateMessage(SETTING(EMAIL), false) + '$' +
ShareManager::getInstance()->getShareSizeString() + "$|");
}
void Client::disconnect() throw() {
state = STATE_CONNECT;
socket->disconnect();
{
Lock l(cs);
clearUsers();
}
}
void Client::search(int aSizeType, int64_t aSize, int aFileType, const string& aString){
checkstate();
char* buf;
char c1 = (aSizeType == SearchManager::SIZE_DONTCARE) ? 'F' : 'T';
char c2 = (aSizeType == SearchManager::SIZE_ATLEAST) ? 'F' : 'T';
string tmp = aString;
string::size_type i;
while((i = tmp.find(' ')) != string::npos) {
tmp[i] = '$';
}
int chars = 0;
if(SETTING(CONNECTION_TYPE) == SettingsManager::CONNECTION_ACTIVE) {
string x = getLocalIp();
buf = new char[x.length() + aString.length() + 64];
chars = sprintf(buf, "$Search %s:%d %c?%c?%s?%d?%s|", x.c_str(), SETTING(IN_PORT), c1, c2, Util::toString(aSize).c_str(), aFileType+1, tmp.c_str());
} else {
buf = new char[getNick().length() + aString.length() + 64];
chars = sprintf(buf, "$Search Hub:%s %c?%c?%s?%d?%s|", getNick().c_str(), c1, c2, Util::toString(aSize).c_str(), aFileType+1, tmp.c_str());
}
send(buf, chars);
delete[] buf;
}
void Client::kick(const User::Ptr& aUser, const string& aMsg) {
checkstate();
dcdebug("Client::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 = 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 client...
Thread::sleep(200);
send("$Kick " + aUser->getNick() + "|");
}
void Client::kick(User* aUser, const string& aMsg) {
checkstate();
dcdebug("Client::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 = 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 client...
Thread::sleep(100);
send("$Kick " + aUser->getNick() + "|");
}
// TimerManagerListener
void Client::onAction(TimerManagerListener::Types type, u_int32_t aTick) throw() {
if(type == TimerManagerListener::SECOND) {
if(socket && (lastActivity + 120 * 1000) < aTick) {
// Nothing's happened for 120 seconds, check if we're connected, if not, try to connect...
lastActivity = aTick;
// Try to send something for the fun of it...
if(isConnected()) {
dcdebug("Testing writing...\n");
socket->write("|", 1);
} else {
// Try to reconnect...
if(reconnect && !server.empty())
connect();
}
}
{
Lock l(cs);
while(!seekers.empty() && seekers.front().second + (5 * 1000) < aTick) {
seekers.pop_front();
}
while(!flooders.empty() && flooders.front().second + (120 * 1000) < aTick) {
flooders.pop_front();
}
}
}
}
// BufferedSocketListener
void Client::onAction(BufferedSocketListener::Types type, const string& aLine) throw() {
switch(type) {
case BufferedSocketListener::LINE:
onLine(aLine); break;
case BufferedSocketListener::FAILED:
{
Lock l(cs);
clearUsers();
}
if(state == STATE_CONNECTED)
state = STATE_CONNECT;
fire(ClientListener::FAILED, this, aLine); break;
default:
dcassert(0);
}
}
void Client::onAction(BufferedSocketListener::Types type) throw() {
switch(type) {
case BufferedSocketListener::CONNECTING:
fire(ClientListener::CONNECTING, this); break;
case BufferedSocketListener::CONNECTED:
lastActivity = GET_TICK();
fire(ClientListener::CONNECTED, this);
break;
default:
break;
}
}
/**
* @file
* $Id: Client.cpp,v 1.53 2003/07/15 14:53:10 arnetheduck Exp $
*/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -