adchub.cpp
来自「一个不错的关于手机模块程序This page contains everythi」· C++ 代码 · 共 556 行 · 第 1/2 页
CPP
556 行
/*
* Copyright (C) 2001-2006 Jacek Sieka, arnetheduck on gmail point com
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#include "stdinc.h"
#include "DCPlusPlus.h"
#include "AdcHub.h"
#include "ClientManager.h"
#include "ShareManager.h"
#include "StringTokenizer.h"
#include "AdcCommand.h"
#include "ConnectionManager.h"
#include "version.h"
#include "Util.h"
#include "UserCommand.h"
#include "FavoriteManager.h"
#include "SSLSocket.h"
const string AdcHub::CLIENT_PROTOCOL("ADC/0.10");
const string AdcHub::SECURE_CLIENT_PROTOCOL("ADCS/0.10");
const string AdcHub::ADCS_FEATURE("ADC0");
const string AdcHub::TCP4_FEATURE("TCP4");
const string AdcHub::UDP4_FEATURE("UDP4");
AdcHub::AdcHub(const string& aHubURL, bool secure) : Client(aHubURL, '\n', secure), state(STATE_PROTOCOL), sid(0), reconnect(true) {
TimerManager::getInstance()->addListener(this);
}
AdcHub::~AdcHub() throw() {
TimerManager::getInstance()->removeListener(this);
clearUsers();
}
OnlineUser& AdcHub::getUser(const u_int32_t aSID, const CID& aCID) {
OnlineUser* u = findUser(aSID);
if(u) {
return *u;
}
User::Ptr p = ClientManager::getInstance()->getUser(aCID);
{
Lock l(cs);
u = users.insert(make_pair(aSID, new OnlineUser(p, *this, aSID))).first->second;
}
if(!aCID.isZero())
ClientManager::getInstance()->putOnline(*u);
return *u;
}
OnlineUser* AdcHub::findUser(const u_int32_t aSID) const {
Lock l(cs);
SIDMap::const_iterator i = users.find(aSID);
return i == users.end() ? NULL : i->second;
}
void AdcHub::putUser(const u_int32_t aSID) {
Lock l(cs);
SIDIter i = users.find(aSID);
if(i == users.end())
return;
if(aSID != AdcCommand::HUB_SID)
ClientManager::getInstance()->putOffline(*i->second);
fire(ClientListener::UserRemoved(), this, *i->second);
delete i->second;
users.erase(i);
}
void AdcHub::clearUsers() {
Lock l(cs);
for(SIDIter i = users.begin(); i != users.end(); ++i) {
if(i->first != AdcCommand::HUB_SID)
ClientManager::getInstance()->putOffline(*i->second);
delete i->second;
}
users.clear();
}
void AdcHub::handle(AdcCommand::INF, AdcCommand& c) throw() {
if(c.getParameters().empty())
return;
string cid;
OnlineUser* u = 0;
if(c.getParam("ID", 0, cid))
u = &getUser(c.getFrom(), CID(cid));
else if(c.getFrom() == AdcCommand::HUB_SID)
u = &getUser(c.getFrom(), CID());
else
u = findUser(c.getFrom());
if(!u) {
dcdebug("AdcHub::INF Unknown user / no ID\n");
return;
}
for(StringIterC i = c.getParameters().begin(); i != c.getParameters().end(); ++i) {
if(i->length() < 2)
continue;
u->getIdentity().set(i->c_str(), i->substr(2));
}
if(u->getIdentity().isBot()) {
u->getUser()->setFlag(User::BOT);
} else {
u->getUser()->unsetFlag(User::BOT);
}
if(u->getUser()->getFirstNick().empty()) {
u->getUser()->setFirstNick(u->getIdentity().getNick());
}
if(u->getIdentity().supports(ADCS_FEATURE)) {
u->getUser()->setFlag(User::SSL);
}
if(u->getIdentity().isHub()) {
setHubIdentity(u->getIdentity());
fire(ClientListener::HubUpdated(), this);
}
if(u->getUser() == ClientManager::getInstance()->getMe()) {
state = STATE_NORMAL;
setMyIdentity(u->getIdentity());
updateCounts(false);
}
fire(ClientListener::UserUpdated(), this, *u);
}
void AdcHub::handle(AdcCommand::SUP, AdcCommand& c) throw() {
if(state != STATE_PROTOCOL) /** @todo SUP changes */
return;
if(find(c.getParameters().begin(), c.getParameters().end(), "ADBASE") == c.getParameters().end()
&& find(c.getParameters().begin(), c.getParameters().end(), "ADBAS0") == c.getParameters().end())
{
fire(ClientListener::StatusMessage(), this, "Failed to negotiate base protocol"); // @todo internationalize
socket->disconnect(false);
return;
}
}
void AdcHub::handle(AdcCommand::SID, AdcCommand& c) throw() {
if(state != STATE_PROTOCOL) {
dcdebug("Invalid state for SID\n");
return;
}
if(c.getParameters().empty())
return;
sid = AdcCommand::toSID(c.getParam(0));
state = STATE_IDENTIFY;
info(true);
}
void AdcHub::handle(AdcCommand::MSG, AdcCommand& c) throw() {
if(c.getParameters().empty())
return;
OnlineUser* from = findUser(c.getFrom());
if(!from)
return;
string pmFrom;
if(c.getParam("PM", 1, pmFrom)) { // add PM<group-cid> as well
OnlineUser* to = findUser(c.getTo());
if(!to)
return;
OnlineUser* replyTo = findUser(AdcCommand::toSID(pmFrom));
if(!replyTo)
return;
fire(ClientListener::PrivateMessage(), this, *from, *to, *replyTo, c.getParam(0));
} else {
fire(ClientListener::Message(), this, *from, c.getParam(0));
}
}
void AdcHub::handle(AdcCommand::GPA, AdcCommand& c) throw() {
if(c.getParameters().empty())
return;
salt = c.getParam(0);
state = STATE_VERIFY;
fire(ClientListener::GetPassword(), this);
}
void AdcHub::handle(AdcCommand::QUI, AdcCommand& c) throw() {
putUser(AdcCommand::toSID(c.getParam(0)));
}
void AdcHub::handle(AdcCommand::CTM, AdcCommand& c) throw() {
OnlineUser* u = findUser(c.getFrom());
if(!u || u->getUser() == ClientManager::getInstance()->getMe())
return;
if(c.getParameters().size() < 3)
return;
bool secure;
if(c.getParam(0) == CLIENT_PROTOCOL) {
secure = false;
} else if(c.getParam(0) == SECURE_CLIENT_PROTOCOL) {
secure = true;
} else {
send(AdcCommand(AdcCommand::SEV_FATAL, AdcCommand::ERROR_PROTOCOL_UNSUPPORTED, "Protocol unknown", AdcCommand::TYPE_DIRECT).setTo(c.getFrom()));
return;
}
if(!u->getIdentity().isTcpActive()) {
send(AdcCommand(AdcCommand::SEV_FATAL, AdcCommand::ERROR_PROTOCOL_GENERIC, "IP unknown", AdcCommand::TYPE_DIRECT).setTo(c.getFrom()));
return;
}
string token;
c.getParam("TO", 2, token);
ConnectionManager::getInstance()->adcConnect(*u, (short)Util::toInt(c.getParameters()[1]), token, secure);
}
void AdcHub::handle(AdcCommand::RCM, AdcCommand& c) throw() {
if(!ClientManager::getInstance()->isActive())
return;
OnlineUser* u = findUser(c.getFrom());
if(!u || u->getUser() == ClientManager::getInstance()->getMe())
return;
if(c.getParameters().empty() || (c.getParameters()[0] != CLIENT_PROTOCOL && c.getParameters()[0] != SECURE_CLIENT_PROTOCOL))
return;
string token;
c.getParam("TO", 1, token);
connect(*u, token, c.getParameters()[0] == SECURE_CLIENT_PROTOCOL);
}
void AdcHub::handle(AdcCommand::CMD, AdcCommand& c) throw() {
if(c.getParameters().size() < 1)
return;
const string& name = c.getParam(0);
bool rem = c.hasFlag("RM", 1);
if(rem) {
int cmd = FavoriteManager::getInstance()->findUserCommand(name);
if(cmd != -1)
FavoriteManager::getInstance()->removeUserCommand(cmd);
}
bool sep = c.hasFlag("SP", 1);
string sctx;
if(!c.getParam("CT", 1, sctx))
return;
int ctx = Util::toInt(sctx);
if(ctx <= 0)
return;
if(sep) {
FavoriteManager::getInstance()->addUserCommand(UserCommand::TYPE_SEPARATOR, ctx, UserCommand::FLAG_NOSAVE, name, "", getHubUrl());
return;
}
bool once = c.hasFlag("CO", 1);
string txt;
if(!c.getParam("TT", 1, txt))
return;
FavoriteManager::getInstance()->addUserCommand(once ? UserCommand::TYPE_RAW_ONCE : UserCommand::TYPE_RAW, ctx, UserCommand::FLAG_NOSAVE, name, txt, getHubUrl());
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?