Logo Search packages:      
Sourcecode: verlihub version File versions

int nDirectConnect::nProtocol::cDCProto::DC_MyINFO ( cMessageDC msg,
cConnDC conn 
) [protected]

Treat the DC message in a appropriate way

send it to all only if ... it's not too often it has changed against the last time and send only the version that has changed only to those who want it

Definition at line 337 of file cdcproto.cpp.

References nDirectConnect::cServerDC::BeginUserLogin(), nDirectConnect::cConnDC::ClearTimeOut(), nDirectConnect::cConnDC::CloseNow(), nDirectConnect::cServerDC::ConnCloseMsg(), nDirectConnect::nTables::cDCConf::delayed_myinfo, nDirectConnect::nTables::cDCConf::desc_insert_mode, cObj::ErrLog(), nDirectConnect::cConnDC::GetTheoricalClass(), nDirectConnect::nTables::cDCConf::int_myinfo, nDirectConnect::cUser::IsPassive, cObj::Log(), nDirectConnect::nTables::cDCConf::login_share_max, nDirectConnect::nTables::cDCConf::login_share_min, cObj::LogStream(), nDirectConnect::nTables::cDCConf::max_share, nDirectConnect::nTables::cDCConf::max_share_ops, nDirectConnect::nTables::cDCConf::max_share_reg, nDirectConnect::nTables::cDCConf::max_share_vip, nDirectConnect::cServerDC::mC, nDirectConnect::cServerDC::mCallBacks, nDirectConnect::cUserBase::mClass, nDirectConnect::cConnDC::mConnType, nDirectConnect::cUser::mEmail, nDirectConnect::cUser::mHideShare, nDirectConnect::nTables::cDCConf::min_class_use_hub, nDirectConnect::nTables::cDCConf::min_class_use_hub_passive, nDirectConnect::nTables::cDCConf::min_share, nDirectConnect::nTables::cDCConf::min_share_factor_passive, nDirectConnect::nTables::cDCConf::min_share_ops, nDirectConnect::nTables::cDCConf::min_share_reg, nDirectConnect::nTables::cDCConf::min_share_use_hub, nDirectConnect::nTables::cDCConf::min_share_vip, nDirectConnect::cServerDC::MinDelay(), nDirectConnect::cUserBase::mInList, nDirectConnect::cServerDC::mL, nDirectConnect::cUserBase::mMyINFO, nDirectConnect::cUserBase::mMyINFO_basic, nDirectConnect::cUserBase::mNick, nDirectConnect::cServerDC::mOpchatList, nDirectConnect::cConnDC::mpUser, nDirectConnect::cUser::mShare, nDirectConnect::cUser::mT, nDirectConnect::cServerDC::mTotalShare, nDirectConnect::cServerDC::mUserList, nDirectConnect::cUserCollection::SendToAll(), nDirectConnect::cConnDC::SetLSFlag(), nDirectConnect::cUser::SetRight(), nDirectConnect::nTables::cDCConf::show_desc_len, nDirectConnect::nTables::cDCConf::show_email, nDirectConnect::nTables::cDCConf::show_speed, nDirectConnect::nTables::cDCConf::show_tags, nDirectConnect::nProtocol::cMessageDC::SplitChunks(), nDirectConnect::nTables::cDCConf::tag_allow_none, and nDirectConnect::nTables::cDCConf::tag_min_class_ignore.

{
      string cmsg;
      ostringstream os;
      // server gets this once on login, and then yet many times
      if(msg->SplitChunks())
      {
            if(conn->Log(2)) conn->LogStream() << "MyINFO syntax error, closing" << endl;
            mS->ConnCloseMsg(conn, cmsg, 4000, eCR_SYNTAX);
            return -1;
      }
      string &nick=msg->ChunkString(eCH_MI_NICK);

      // this can't happen without having created user object
      if(!conn->mpUser)
      {
            cmsg = "bad login sequence";
            if(conn->Log(2)) conn->LogStream() << "Myinfo without nick " << nick << endl;
            mS->ConnCloseMsg(conn, cmsg,1000, eCR_LOGIN_ERR);
            if(mS->ErrLog(0)) mS->LogStream() << "Myinfo without nick " << nick << endl;
            return -1;
      }

      // check syntax a bit

      // check nick
      if(nick != conn->mpUser->mNick)
      {
            cmsg = "Wrong MyINFO";
            if(conn->Log(1)) conn->LogStream() << "Claims to be someone else in MyINFO" << endl;
            mS->ConnCloseMsg(conn, cmsg, 1500, eCR_SYNTAX);
            return -1;
      }


      ////////////////////// BEGIN TAG VERRIFICATION
      // parse conention type
      if(conn->mConnType == NULL)
            conn->mConnType = ParseSpeed(msg->ChunkString(eCH_MI_SPEED));

      // analyze check user's tag
      cDCTag tag(msg->ChunkString(eCH_MI_DESC), mS->mC, mS->mL);

      if (!mS->mC.tag_allow_none && tag.mPositionInDesc < 0 && conn->mpUser->mClass < eUC_OPERATOR && conn->mpUser->mClass != eUC_PINGER)
      {
            cmsg = "Turn On your tags!!";
            if(conn->Log(2)) conn->LogStream() << "No tags "<< endl;
            mS->ConnCloseMsg(conn, cmsg, 1000, eCR_TAG_NONE);
            return -1;
      }

      // test for all but kick only  non-ops
      bool TagValid = true;
      int tag_result = 0;
      if ( conn->mpUser->mClass < mS->mC.tag_min_class_ignore )
      {
            TagValid = tag.ValidateTag(os, conn->mConnType, tag_result);
            #ifndef WITHOUT_PLUGINS
            if (TagValid) TagValid = mS->mCallBacks.mOnValidateTag.CallAll(conn, &tag);
            #endif
      }

      if(!TagValid)
      {
            if(conn->Log(2)) conn->LogStream() << "Invalid tags: (" << tag_result << ") " << tag << endl;
            mS->ConnCloseMsg(conn, os.str(), 1000, eCR_TAG_INVALID);
            return -1;
      }

      if( tag.mClientMode == cDCTag::eCM_PASSIVE || 
                  tag.mClientMode == cDCTag::eCM_SOCK5 )
                              conn->mpUser->IsPassive = true;
      ////////////////////// END TAG VERRIFICATION

      // verify conditions
      //    minimal share and maximal
      string &str_share=msg->ChunkString(eCH_MI_SIZE);
      if(str_share.size() > 18) // that is too much
      {
            conn->CloseNow();
            return -1;
      }
      __int64 share = 0,shareB = 0;

      shareB = StringAsLL(str_share);
      share  = shareB/(1024*1024);

      if (conn->GetTheoricalClass() <= eUC_OPERATOR)
      {
            // calculate minimax
            __int64 min_share=mS->mC.min_share;
            __int64 max_share=mS->mC.max_share;
            __int64 min_share_p, min_share_a;
            
            if (conn->GetTheoricalClass() == eUC_PINGER )
            {
                  min_share = 0;
            }
            else
            {
                  if (conn->GetTheoricalClass() >= eUC_REGUSER )
                  {
                        min_share = mS->mC.min_share_reg;
                        max_share = mS->mC.max_share_reg;
                  }
                  if (conn->GetTheoricalClass() >= eUC_VIPUSER )
                  {
                        min_share = mS->mC.min_share_vip;
                        max_share = mS->mC.max_share_vip;
                  }
      
                  if (conn->GetTheoricalClass() >= eUC_OPERATOR)
                  {
                        min_share = mS->mC.min_share_ops;
                        max_share = mS->mC.max_share_ops;
                  }
            }
            min_share_a = min_share;

            min_share_p = (__int64)(min_share * mS->mC.min_share_factor_passive);
            if (conn->mpUser->IsPassive)
                  min_share = min_share_p;
            
            /*if (conn->mpUser->Can(eUR_NOSHARE, mS->mTime.Sec()))
                  min_share = 0;
            */
            if((share < min_share) || (max_share && (share > max_share)))
            {
                  if (share < min_share) cmsg = mS->mC.login_share_min;
                  else cmsg = mS->mC.login_share_max;
                  ReplaceVarInString(cmsg,"share",cmsg,share);
                  ReplaceVarInString(cmsg,"min_share",cmsg,min_share);
                  ReplaceVarInString(cmsg,"min_share_active",cmsg,min_share_a);
                  ReplaceVarInString(cmsg,"min_share_passive",cmsg,min_share_p);
                  ReplaceVarInString(cmsg,"max_share",cmsg,max_share);
                  if(conn->Log(2)) conn->LogStream() << "Share limit."<< endl;
                  mS->ConnCloseMsg(conn, cmsg, 4000, eCR_SHARE_LIMIT);
                  return -1;
            }

            // this is a secon share limit, (if NON-zero)
            // under imit disables search and download
            if(mS->mC.min_share_use_hub && conn->GetTheoricalClass() < eUC_VIPUSER)
            {
                  min_share = mS->mC.min_share_use_hub;
                  if (conn->mpUser->IsPassive)
                        min_share = (__int64)(min_share * mS->mC.min_share_factor_passive);
                  if (share < min_share)
                  {
                        conn->mpUser->SetRight(eUR_SEARCH, 0);
                        conn->mpUser->SetRight(eUR_CTM, 0);
                  }
            }
            if (conn->GetTheoricalClass() < mS->mC.min_class_use_hub) {
                  conn->mpUser->SetRight(eUR_SEARCH, 0);
                  conn->mpUser->SetRight(eUR_CTM, 0);
            }
            if ((conn->GetTheoricalClass() < mS->mC.min_class_use_hub_passive) && !(conn->mpUser->IsPassive == false) ){
                  conn->mpUser->SetRight(eUR_SEARCH, 0);
                  conn->mpUser->SetRight(eUR_CTM, 0);
            }
      }

      // share verified

      // update totalshare
      mS->mTotalShare -= conn->mpUser->mShare;
      conn->mpUser->mShare = shareB;
      mS->mTotalShare += conn->mpUser->mShare;
      conn->mpUser->mEmail = msg->ChunkString(eCH_MI_MAIL);


      #ifndef WITHOUT_PLUGINS
      if (!mS->mCallBacks.mOnParsedMsgMyINFO.CallAll(conn, msg))
            return -2;
      #endif

      // if tag isn't valid, tell it the user
      // check hubs / slots etc...
      string myinfo_full, myinfo_basic,desc, email, speed;


      //$MyINFO $ALL <nick> <interest>$ $<speed>$<e-mail>$<sharesize>$
      //@todo @fixme tag.mPositionInDesc may be incorrect after the description has been modified by a plugin
      tag.ParsePos(msg->ChunkString(eCH_MI_DESC));
      desc.assign(msg->ChunkString(eCH_MI_DESC),0,tag.mPositionInDesc);
      if (mS->mC.desc_insert_mode) {
            switch (tag.mClientMode) {
            case cDCTag::eCM_ACTIVE: desc = "A " + desc; break;
            case cDCTag::eCM_PASSIVE: desc = "P " + desc; break;
            case cDCTag::eCM_SOCK5: desc = "5 " + desc; break;
            default: break;
            }
      }

      if(mS->mC.show_desc_len >= 0) {
            desc.assign(desc,0,mS->mC.show_desc_len);
      }
      
      if(mS->mC.show_email == 0) {
            email= "";
      } else {
            email = msg->ChunkString(eCH_MI_MAIL);
      }

      if(mS->mC.show_speed == 0) {
            speed = "";
      } else {
            speed = msg->ChunkString(eCH_MI_SPEED);
      }

      if(!(conn->mpUser->mHideShare == false)) {
            Create_MyINFO(
                  myinfo_basic,
                  msg->ChunkString(eCH_MI_NICK),
                  desc,
                  speed,
                  email,
                  "0"
                  );
      } else {

      Create_MyINFO(
            myinfo_basic,
            msg->ChunkString(eCH_MI_NICK),
            desc,
            msg->ChunkString(eCH_MI_SPEED),
            email,
            msg->ChunkString(eCH_MI_SIZE)
            );
      }
      // OPS have hidden myinfo
      if (( conn->mpUser->mClass >= eUC_OPERATOR) && (mS->mC.show_tags < 3))
            myinfo_full = myinfo_basic;
      else
            myinfo_full = msg->mStr;

      // login or send to all
      if(conn->mpUser->mInList)
      {
            /** send it to all only if ...
            * it's not too often
            * it has changed against the last time
            * and send only the version that has changed only to those who want it
            */
            if(mS->MinDelay(conn->mpUser->mT.info,mS->mC.int_myinfo))
            {
                  string send_myinfo;
                  if(myinfo_full != conn->mpUser->mMyINFO)
                  {
                        conn->mpUser->mMyINFO = myinfo_full;
                        if(myinfo_basic != conn->mpUser->mMyINFO_basic)
                        {
                              conn->mpUser->mMyINFO_basic = myinfo_basic;
      
                              send_myinfo = GetMyInfo(conn->mpUser, eUC_NORMUSER);
                              mS->mUserList.SendToAll(send_myinfo, mS->mC.delayed_myinfo, true);
      
                        }
                        if( mS->mC.show_tags >=1 ) 
                              mS->mOpchatList.SendToAll(myinfo_full, mS->mC.delayed_myinfo, true);
                  }

            }
      }
      else // user logs in the first time
      {
            // keep it
            conn->mpUser->mMyINFO = myinfo_full;
            conn->mpUser->mMyINFO_basic = myinfo_basic;

            // note, we got it
            conn->SetLSFlag(eLS_MYINFO);
            // if all right, add user to userlist, if not yet there
            if(!mS->BeginUserLogin(conn)) return -1;
      }

      conn->ClearTimeOut(eTO_MYINFO);
      return 0;
}


Generated by  Doxygen 1.6.0   Back to index