// When a a client is disconnected void CCharServer::OnClientDisconnect( CClientSocket* thisclient ) { CCharClient* thisclientwc = (CCharClient*)thisclient; if(!thisclientwc->logout) { // Send logout message to friends for(UINT i=0; i<thisclientwc->FriendList.size( ); i++) { CFriendList* Friend = thisclientwc->FriendList.at( i );; CCharClient* otherclient = GetClientByID( Friend->id ); if(otherclient!=NULL) { ChangeMessengerStatus ( thisclientwc, otherclient, 0x08); } } //set logout messga to clan CClans* thisclan = GetClanByID(thisclientwc->clanid); if(thisclan==NULL) return; for(UINT i=0; i<thisclan->ClanMembers.size( ); i++) { CClanMembers* ClanMember = thisclan->ClanMembers.at( i ); CCharClient* otherclient = GetClientByID( ClanMember->id ); if(otherclient!=NULL) ChangeClanStatus (thisclientwc, otherclient, 0xff); } //LMA: Disconnecting a client from chatroom. DisconnectClientFromChat(thisclientwc ); } }
void C4Network2ClientList::HandlePacket(char cStatus, const C4PacketBase *pBasePkt, C4Network2IOConnection *pConn) { // find associated client C4Network2Client *pClient = GetClient(pConn); if (!pClient) return; #define GETPKT(type, name) \ assert(pBasePkt); const type &name = \ static_cast<const type &>(*pBasePkt); switch (cStatus) { case PID_Addr: // address propagation { GETPKT(C4PacketAddr, rPkt) // find client pClient = GetClientByID(rPkt.getClientID()); if (pClient) { C4Network2Address addr = rPkt.getAddr(); // IP zero? Set to IP from where the packet came if (addr.isIPNull()) { addr.SetIP(pConn->getPeerAddr()); } // add (no announce) if (pClient->AddAddr(addr, true)) // new address? Try to connect pClient->DoConnectAttempt(pIO); } } break; case PID_TCPSimOpen: { GETPKT(C4PacketTCPSimOpen, rPkt) pClient = GetClientByID(rPkt.getClientID()); if (pClient) { C4Network2Address addr = rPkt.getAddr(); pClient->DoTCPSimultaneousOpen(pIO, addr); } } break; } #undef GETPKT }
void CClientInfoMgr::RemoveClient (uint32 nID) { if (!m_pClients) return; m_nLocalID = 0; g_pLTClient->GetLocalClientID (&m_nLocalID); // find the client CLIENT_INFO* ptr = GetClientByID(nID, false); if (!ptr) return; if( g_pGameClientShell->ShouldUseRadar() ) { g_pRadar->UpdatePlayerName( nID, "", 0); } // remove the client from the list if (ptr->pNext) ptr->pNext->pPrev = ptr->pPrev; if (ptr->pPrev) ptr->pPrev->pNext = ptr->pNext; if (m_pClients == ptr) m_pClients = ptr->pNext; debug_delete(ptr); }
void CClientInfoMgr::UpdateClient ( char const* pszName, bool bIsAdmin, uint32 nID, uint8 nTeamID ) { // if we have this client in the list, update their info CLIENT_INFO* pClient = GetClientByID(nID, false); if (pClient) { pClient->sName = pszName; pClient->bIsAdmin = bIsAdmin; pClient->nTeamID = nTeamID; UpdateClientSort(pClient); if( g_pGameClientShell->ShouldUseRadar() ) { g_pRadar->UpdatePlayerName(nID, pszName, nTeamID ); } } else { //hmmm... we should have found them... g_pLTClient->CPrint("CClientInfoMgr::UpdateClient () : Unknown Client %d (%s)", nID, pszName); } }
// Messenger Chat bool CCharServer::pakMessengerChat ( CCharClient* thisclient, CPacket* P ) { WORD id = GETWORD((*P),0); char* message = new char[P->Size-41]; if(message==NULL) { Log(MSG_ERROR, "Error allocing memory: pakMessengerChat" ); return false; } memcpy( message, &P->Buffer[35], P->Size-41 ); CCharClient* otherclient = (CCharClient*) GetClientByID(id); if(otherclient!=NULL) { BEGINPACKET( pak, 0x7e2 ); ADDWORD ( pak, thisclient->charid ); ADDWORD ( pak, 0x0000 ); ADDSTRING ( pak, thisclient->charname ); UINT namesize = strlen(thisclient->charname); for (int i=0;i<30-namesize;i++) ADDBYTE ( pak, 0x00 ); ADDBYTE ( pak, 0x00 ); ADDSTRING ( pak, message ); ADDBYTE ( pak, 0x00 ); otherclient->SendPacket(&pak); } delete []message; return true; }
void CClientInfoMgr::AddScore(uint32 nID, uint8 teamId, uint32 nScore) { if (!m_pClients) return; if (teamId == 1 || teamId == 2) { m_Teams[teamId-1].nScore += nScore; CLIENT_INFO* ptr = GetClientByID(nID); if (ptr) { ptr->nFrags += nScore; UpdateClientSort(ptr); } else g_pInterfaceMgr->UpdateClientList(); // update the frag display if (nID == m_nLocalID || m_bIsTeamGame) { UpdateFragDisplay(); } } }
void CClientInfoMgr::PlayerConnected( char const* pszName, uint32 nID ) { m_nLocalID = 0; g_pLTClient->GetLocalClientID (&m_nLocalID); // if we already have this client in the list, just return CLIENT_INFO* pDup = GetClientByID(nID, false); if (pDup) { pDup->sName = pszName; } else { // create the new object CLIENT_INFO* pNew = debug_new(CLIENT_INFO); if (!pNew) return; pNew->nID = nID; pNew->sName = pszName; pNew->bIsAdmin = false; pNew->nTeamID = INVALID_TEAM; pNew->sScore.Init(nID); // if we don't have a list yet, set the list pointer to the new object if (!m_pClients) { m_pClients = pNew; return; } // we do have a list - insert the object CLIENT_INFO* ptr = m_pClients; //insert at head? if (ptr->sScore.GetScore() < pNew->sScore.GetScore()) { pNew->pNext = m_pClients; m_pClients = pNew; return; } CLIENT_INFO* pNext = ptr->pNext; while (pNext && pNext->sScore.GetScore() >= pNew->sScore.GetScore()) { ptr = pNext; pNext = ptr->pNext; } if (pNext) { pNext->pPrev = pNew; } ptr->pNext = pNew; pNew->pNext = pNext; pNew->pPrev = ptr; } }
void PCommands::doCmdkick() { bool SyntaxError = false; if(ArgC < 1) { SyntaxError = true; } if(SyntaxError == true) { Chat->send(source, CHAT_DIRECT, "Usage", "@kick <charID or nickname>"); return; } if(IsArgNumeric(1) == true) { target = GetClientByID(GetArgInt(1)); } else { char tmp_destNick[50]; GetArgText(1, tmp_destNick, 50); target = GetClientByNick(tmp_destNick); } if(target == NULL) // If victim isnt found, return error { Chat->send(source, CHAT_DIRECT, "System", "No such player"); return; } // Make sure only people with a higher level than victim can kick victim if(source->GetAccountLevel() <= target->GetAccountLevel()) { char tmpMsg[200]; snprintf(tmpMsg, 199, "Cant kick %s, target level is higher or equal to yours!", Chars->GetChar(target->GetCharID())->GetName().c_str()); tmpMsg[199] = '\0'; Chat->send(source, CHAT_DIRECT, "System", tmpMsg); return; } // *************** Checks done, proceed with command int final_bantime = std::time(NULL) + 60; // Ban 60 seconds (Anti-Rejoin) PAccount Acc(target->GetAccountID()); Acc.SetBannedUntilTime(final_bantime); Acc.Save(); target->InitCharVanish(); GameServer->ClientDisconnected(target); // Kick Console->Print("%s %s (Lv %d) kicked %s (Lv %d)", Console->ColorText(YELLOW, BLACK, "[GameCommand]"), Chars->GetChar(source->GetCharID())->GetName().c_str(), source->GetAccountLevel(), Chars->GetChar(target->GetCharID())->GetName().c_str(), target->GetAccountLevel()); char successmsg[100]; snprintf(successmsg, 99, "Kicked %s", Chars->GetChar(target->GetCharID())->GetName().c_str()); successmsg[99] = '\0'; Chat->send(source, CHAT_DIRECT, "System", successmsg); }
char const* CClientInfoMgr::GetPlayerName (uint32 nID) { if (!m_pClients) return LTNULL; CLIENT_INFO* ptr = GetClientByID(nID); if (ptr) return ptr->sName.c_str( ); return szUnknownPlayer; }
void PCommands::doCmdshun() { bool SyntaxError = false; if(ArgC < 1) { SyntaxError = true; } if(SyntaxError == true) { Chat->send(source, CHAT_DIRECT, "Usage", "@shun <charID or nickname>"); return; } if(IsArgNumeric(1) == true) { target = GetClientByID(GetArgInt(1)); } else { char tmp_destNick[50]; GetArgText(1, tmp_destNick, 50); target = GetClientByNick(tmp_destNick); } if(target == NULL) // If victim isnt found, return error { Chat->send(source, CHAT_DIRECT, "System", "No such player"); return; } if(source->GetAccountLevel() <= target->GetAccountLevel()) { char tmpMsg[200]; snprintf(tmpMsg, 199, "Cant shun %s, target level is higher or equal to yours!", Chars->GetChar(target->GetCharID())->GetName().c_str()); tmpMsg[199] = '\0'; Chat->send(source, CHAT_DIRECT, "System", tmpMsg); return; } if(target->GetChar()->IsShunned() == false) { target->GetChar()->SetShun(true); char tmpMsg_success[81]; snprintf(tmpMsg_success, 80, "Successfully shunned %s", target->GetChar()->GetName().c_str()); tmpMsg_success[80] = '\0'; Chat->send(source, CHAT_DIRECT, "System", tmpMsg_success); return; } else { Chat->send(source, CHAT_DIRECT, "System", "Player is already shunned"); return; } }
//LMA: disconnect a client from chatroom. bool CCharServer::DisconnectClientFromChat( CCharClient* thisclientwc ) { //LMA: resetting chatroom ID. if(thisclientwc->chatroom_id!=0) { if(chatroom_list.find(thisclientwc->chatroom_id)!=chatroom_list.end()) { for (int k=0; k<chatroom_list[thisclientwc->chatroom_id]->People_list.size(); k++) { if(chatroom_list[thisclientwc->chatroom_id]->People_list.at(k)->charid==thisclientwc->charid) { //Deleting the guy from the chatroom list. chatroom_list[thisclientwc->chatroom_id]->People_list.erase(chatroom_list[thisclientwc->chatroom_id]->People_list.begin()+k); break; } } if (chatroom_list[thisclientwc->chatroom_id]->People_list.size()==0) { chatroom_list.erase(thisclientwc->chatroom_id); } else { //TODO: send a packet to other people to tell them this guy has deconnected from chatroom. for (int k=0; k<chatroom_list[thisclientwc->chatroom_id]->People_list.size(); k++) { CCharClient* otherclient=GetClientByID(chatroom_list[thisclientwc->chatroom_id]->People_list.at(k)->charid); if(otherclient==NULL) { continue; } BEGINPACKET( pak, 0x7e3 ); ADDBYTE ( pak, 0x16 ); ADDWORD ( pak, thisclientwc->userid ); ADDDWORD ( pak, thisclientwc->charid ); ADDSTRING ( pak, thisclientwc->charname ); ADDBYTE ( pak, 0x00 ); otherclient->SendPacket( &pak ); } } } thisclientwc->chatroom_id=0; } return true; }
bool C4Network2ClientList::SendMsgToClient(int32_t iClient, C4NetIOPacket RREF rPkt) { // find client C4Network2Client *pClient = GetClientByID(iClient); if (!pClient) return false; // connected? send directly if (pClient->isConnected()) return pClient->SendMsg(rPkt); // forward C4PacketFwd Fwd; Fwd.SetListType(false); Fwd.AddClient(iClient); Fwd.SetData(rPkt); return SendMsgToHost(MkC4NetIOPacket(PID_FwdReq, Fwd)); }
// Logout from clan bool CCharServer::ClanLogout ( CCharClient* thisclient ) { CClans* thisclan = (CClans*) GetClanByID(thisclient->clanid); if(thisclan!=NULL) { for(UINT i=0;i<thisclan->ClanMembers.size();i++) { CClanMembers* thismember = thisclan->ClanMembers.at( i ); CCharClient* otherclient = (CCharClient*) GetClientByID ( thismember->id ); if(otherclient!=NULL) { ChangeClanStatus (thisclient, otherclient, 0xff);//send channel here } } } return true; }
// Send Clan information bool CCharServer::SendClanInfo (CCharClient* thisclient) { if( thisclient->clanid > 0 ) { CClans *thisclan = GetClanByID(thisclient->clanid); if(thisclan!=NULL) { BEGINPACKET( pak, 0x7e0); ADDBYTE ( pak, 0x33);//0x33 you have invited to clan ADDWORD ( pak, thisclan->id);// clan id ADDBYTE ( pak, 0x00);// ADDBYTE ( pak, 0x00); ADDWORD ( pak, thisclan->back);//Clan Background ADDWORD ( pak, thisclan->logo);//Clan logo ADDBYTE ( pak, thisclan->grade);//Clan grade ADDBYTE ( pak, thisclient->clan_rank);// Clan rank (0 = red rokie / 6 = master) ADDDWORD ( pak, thisclan->cp);//Clan Points ADDDWORD ( pak, 0x00000064); ADDDWORD ( pak, 0x00000000); //Clan found ADDDWORD ( pak, 0x00000000); ADDBYTE ( pak, 0x01); for(int i=34;i<156;i++) ADDBYTE ( pak, 0x00); ADDWORD ( pak, 0x0000); ADDBYTE ( pak, 0x00); ADDSTRING ( pak, thisclan->name);//Clan Name ADDBYTE ( pak, 0x00); ADDSTRING ( pak, thisclan->slogan);//Clan slogan ADDBYTE ( pak, 0x00); ADDSTRING ( pak, thisclan->news);//Clan news ADDBYTE ( pak, 0x00); thisclient->SendPacket(&pak); //Put the player online in clan for(UINT i=0;i<thisclan->ClanMembers.size();i++) { CClanMembers* ClanMember = thisclan->ClanMembers.at( i );; CCharClient* otherclient = GetClientByID( ClanMember->id ); if(otherclient!=NULL) ChangeClanStatus (thisclient, otherclient, thisclient->channel);//send channel here } } } return true; }
void CClientMgr::SentToClient(int iClientID, char* pSendData, int iLen) { CClient* pClient = NULL; pClient = GetClientByID(iClientID); if (NULL == pClient) { g_pSvrLog->AddRunLog(LL_ERROR, "CClientMgr::SentToClient: the client is not exist"); return; } pClient->MutexBufferLock(); int iReturnCode = pClient->Send(pSendData, iLen); pClient->MutexBufferUnLock(); if (0 == iReturnCode) { g_pSvrLog->AddRunLog(LL_ERROR, "CClientMgr::SentToClient: send data failed"); } }
// Send clan members bool CCharServer::pakClanMembers ( CCharClient* thisclient ) { CClans* thisclan = (CClans*) GetClanByID( thisclient->clanid ); if(thisclan!=NULL) { BEGINPACKET( pak, 0x7e0 ); ADDBYTE ( pak, 0x72 );//Send clan members for(UINT i=0;i<thisclan->ClanMembers.size( );i++) { CClanMembers* thismember = thisclan->ClanMembers.at( i ); if(thismember==NULL) continue; CCharClient* otherclient = (CCharClient*) GetClientByID (thismember->id); if(otherclient!=NULL) { ADDBYTE ( pak, thismember->clan_rank ); //clan rank ADDBYTE ( pak, otherclient->channel ); //channel (0x01 = channel 1) ADDWORD ( pak, 0x0000 ); ADDWORD ( pak, 0x0000 ); ADDWORD ( pak, otherclient->level );// Level ADDWORD ( pak, otherclient->job );// Job } else { ADDBYTE ( pak, thismember->clan_rank); //clan rank ADDBYTE ( pak, 0xff ); //channel (0xff = offline) ADDWORD ( pak, 0x0000 ); ADDWORD ( pak, 0x0000 ); ADDWORD ( pak, 0x0000 );// Level ADDWORD ( pak, 0x0000 );// Job } ADDSTRING ( pak, thismember->name ); ADDBYTE ( pak, 0x00 ); } thisclient->SendPacketCpy( &pak ); } return true; }
// Party Manager bool CWorldServer::pakPartyManager( CPlayer* thisclient, CPacket* P ) { unsigned int action = GETBYTE((*P),0); switch(action) { case 0x02://Acepto { if(thisclient->Party->party!=NULL)// have party return true; unsigned int clientid = GETWORD((*P),1); if (clientid == thisclient->clientid) { Log(MSG_WARNING, "User %s tried to party with himself\n", thisclient->CharInfo->charname); return false; //kick the cheater } CPlayer* otherclient = GetClientByID( clientid, thisclient->Position->Map ); if(otherclient==NULL) { BEGINPACKET( pak, 0x7d1 ); ADDBYTE ( pak, 0x00 );//No encontro el ID ADDWORD ( pak, clientid ); ADDBYTE ( pak, 0x00 ); thisclient->client->SendPacket( &pak ); return true; } CParty* party = otherclient->Party->party; if(party!=NULL) { //LMA: Refreshing Capacity if needed party->RefreshMax(); if(party->Members.size()>=party->Capacity) { SendSysMsg( thisclient, "Party is Full" ); return true; } } if(abs(otherclient->Stats->Level-thisclient->Stats->Level)>(Config.Partygap+1)) { BEGINPACKET( pak, 0x7d1 ); ADDBYTE ( pak, 0x07 );//Level inapropiado ADDWORD ( pak, clientid ); ADDBYTE ( pak, 0x00 ); thisclient->client->SendPacket( &pak ); return true; } BEGINPACKET( pak, 0x7d1 ); ADDBYTE ( pak, 0x02 );//Acepto Party ADDWORD ( pak, otherclient->clientid ); ADDBYTE ( pak, 0x00 ); otherclient->client->SendPacket( &pak ); if( party==NULL ) { // new party CParty* thisparty = new CParty; thisparty->AddPlayer( otherclient ); AddParty( thisparty ); otherclient->Party->IsMaster = true; party = thisparty; } //Send Party Level and Party Exp RESETPACKET( pak, 0x7d4 ); // ADDBYTE ( pak, party->PartyLevel ); ADDDWORD ( pak, party->Exp ); thisclient->client->SendPacket( &pak ); thisclient->Party->IsMaster = false; // Send New Party Member info to other players RESETPACKET( pak, 0x7d2 ); ADDBYTE ( pak, party->Option ); ADDBYTE ( pak, 0x01 ); ADDDWORD ( pak, thisclient->CharInfo->charid ); ADDWORD ( pak, thisclient->clientid ); ADDWORD ( pak, thisclient->Stats->MaxHP ); ADDWORD ( pak, thisclient->Stats->HP ); //ADDDWORD ( pak, 0x00000000 );//Tomiz: Was not commented before ADDDWORD ( pak, BuildBuffs( thisclient ));//Tomiz: Buff Data //ADDDWORD ( pak, 0x0000000f );//Tomiz: Was not commented before ADDDWORD ( pak, 0x1f40008c );//Tomiz ADDWORD ( pak, 0x1388 ); ADDSTRING ( pak, thisclient->CharInfo->charname ); ADDBYTE ( pak, 0x00 ); party->SendToMembers( &pak ); // Send To New Party Member the members List RESETPACKET( pak, 0x7d2 ); ADDBYTE ( pak, party->Option ); ADDBYTE ( pak, party->Members.size() ); for(int i=0;i<party->Members.size();i++) { CPlayer* member= party->Members.at(i); ADDDWORD ( pak, member->CharInfo->charid ); ADDWORD ( pak, member->clientid ); ADDWORD ( pak, member->Stats->MaxHP ); ADDWORD ( pak, member->Stats->HP ); //ADDDWORD ( pak, 0x00000000 );//Tomiz: Was not commented before ADDDWORD ( pak, BuildBuffs( member ));//Tomiz: Buff Data //ADDDWORD ( pak, 0x0000000f );//Tomiz: Was not commented before ADDDWORD ( pak, 0x7200005b );//Tomiz ADDWORD ( pak, 0x1388 ); ADDSTRING ( pak, member->CharInfo->charname ); ADDBYTE ( pak, 0x00 ); } thisclient->client->SendPacket( &pak ); party->AddPlayer( thisclient ); } break; case 0x04://No acepto { unsigned int clientid = GETWORD((*P),1); CPlayer* otherclient = GetClientByID( clientid, thisclient->Position->Map ); if(otherclient==NULL) { BEGINPACKET( pak, 0x7d1 ); ADDBYTE ( pak, 0x00 );//No encontro el ID ADDWORD ( pak, clientid ); ADDBYTE ( pak, 0x00 ); thisclient->client->SendPacket( &pak ); return true; } BEGINPACKET( pak, 0x7d1 ); ADDBYTE ( pak, 0x04 );//No acepto ADDWORD ( pak, thisclient->clientid ); ADDBYTE ( pak, 0x00 ); otherclient->client->SendPacket( &pak ); } break; default: Log(MSG_WARNING,"Party Manager unknown action: %i", action); } return true; }
// Messenger actions (add/remove/invite) bool CCharServer::pakMessengerManager ( CCharClient* thisclient, CPacket* P ) { BYTE action = GETBYTE((*P),0); switch (action) { case 0x01://wanna be my friend? { char* nick = new (nothrow) char[P->Size-7]; if(nick==NULL) { Log(MSG_ERROR, "Error allocing memory: pakMessengerManager 1" ); return false; } memcpy( nick, &P->Buffer[1], P->Size-7 ); Log(MSG_INFO,"%s Trying to invite %s",nick,thisclient->charname); CCharClient* otherclient = (CCharClient*) GetClientByName (nick); if(otherclient!=NULL) {//Send friend invitation (check this one) BEGINPACKET( pak, 0x7e1 ); ADDBYTE ( pak, 0x01 ); ADDWORD ( pak, 0x0000 ); ADDSTRING ( pak, thisclient->charname ); ADDBYTE ( pak, 0x00 ); otherclient->SendPacket(&pak); Log(MSG_INFO,"%s exists, invite sent to %s",nick,otherclient->charname); } else {//This charname doesnt exist BEGINPACKET( pak, 0x7e1 ); ADDBYTE ( pak, 0x04 ); ADDSTRING ( pak, nick ); ADDBYTE ( pak, 0x00 ); thisclient->SendPacket(&pak); Log(MSG_INFO,"invite: %s doesn't exist",nick); } delete []nick; } break; case 0x02://yes i want { char* nick = new (nothrow) char[P->Size-9]; if(nick==NULL) { Log(MSG_ERROR, "Error allocing memory: pakMessengerManager 2" ); return false; } memcpy( nick, &P->Buffer[3], P->Size-9 ); CCharClient* otherclient = (CCharClient*) GetClientByName (nick); if(otherclient!=NULL) { BEGINPACKET( pak, 0x7e1 ); ADDBYTE ( pak, 0x02 ); ADDWORD ( pak, thisclient->charid ); ADDBYTE ( pak, 0x00 ); ADDWORD ( pak, 0x0000 ); ADDSTRING ( pak, thisclient->charname ); ADDBYTE ( pak, 0x00); otherclient->SendPacket(&pak); //Add friend to my friend list(sql) if(!DB->QExecute("INSERT INTO list_friend (id,idfriend,namefriend) VALUES (%i,%i,'%s')",otherclient->charid,thisclient->charid,thisclient->charname)) { Log(MSG_WARNING,"error addind %s to %s friend list",otherclient->charname,thisclient->charname); return false; } CFriendList * newfriend1 = new (nothrow) CFriendList; if(newfriend1==NULL) return false; newfriend1->id = otherclient->charid; //friendid strcpy(newfriend1->name, otherclient->charname); //friend name thisclient->FriendList.push_back( newfriend1 ); RESETPACKET( pak, 0x7e1 ); ADDBYTE ( pak, 0x02 ); ADDWORD ( pak, otherclient->charid ); ADDBYTE ( pak, 0x00 ); ADDWORD ( pak, 0x0000 ); ADDSTRING ( pak, otherclient->charname ); ADDBYTE ( pak, 0x00); thisclient->SendPacket(&pak); //Add me to his friend list (sql) if(!DB->QExecute("INSERT INTO list_friend (id,idfriend,namefriend) VALUES (%i,%i,'%s')", thisclient->charid,otherclient->charid,otherclient->charname)) return false; CFriendList * newfriend2 = new (nothrow) CFriendList; if(newfriend2==NULL) return false; newfriend2->id = thisclient->charid; //friendid strcpy(newfriend2->name, thisclient->charname); //friend name otherclient->FriendList.push_back( newfriend2 ); Log(MSG_INFO,"accept %s ok",nick); } else//not founded { BEGINPACKET( pak, 0x7e1 ); ADDBYTE ( pak, 0x04 ); ADDSTRING ( pak, nick ); ADDBYTE ( pak, 0x00 ); thisclient->SendPacket(&pak); Log(MSG_INFO,"accept: %s doesn't exist",nick); } delete []nick; } break; case 0x03://no, i dont want { char* nick = new (nothrow) char[P->Size-9]; if(nick==NULL) { Log(MSG_ERROR, "Error allocing memory: pakMessengerManager 3" ); return false; } memcpy( nick, &P->Buffer[3], P->Size-9 ); CCharClient* otherclient = (CCharClient*) GetClientByName (nick); if(otherclient!=NULL) { BEGINPACKET( pak, 0x7e1 ); ADDBYTE ( pak, 0x03 ); ADDSTRING ( pak, thisclient->charname ); ADDBYTE ( pak, 0x00); otherclient->SendPacket(&pak); Log(MSG_INFO,"refuse: %s ok",nick); } else { BEGINPACKET( pak, 0x7e1 ); ADDBYTE ( pak, 0x04 ); ADDWORD ( pak, 0x0000 ); ADDSTRING ( pak, nick ); ADDBYTE ( pak, 0x00 ); thisclient->SendPacket(&pak); Log(MSG_INFO,"refuse: %s doesn't exist",nick); } } break; case 0x05://delete user. { WORD id = GETWORD ((*P),1); if(!DB->QExecute("DELETE FROM list_friend WHERE id=%i and idfriend=%i",thisclient->charid,id)) { Log(MSG_INFO,"user failed to delete friend slot %i",thisclient->charname,id); return false; } Log(MSG_INFO,"user %s deletes friend slot %i",thisclient->charname,id); CCharClient* otherclient = (CCharClient*) GetClientByID(id); if(otherclient!=NULL) { ChangeMessengerStatus ( thisclient, otherclient, 0x08); } } break; case 0xfa://messenger logout { WORD id = GETWORD ((*P),1); CCharClient* ctherclient = (CCharClient*) GetClientByID(id); if(ctherclient==NULL) return true; ctherclient->logout = true; for(UINT i=0;i<ctherclient->FriendList.size();i++) { CFriendList* thisfriend = ctherclient->FriendList.at( i ); CCharClient* otherclient = (CCharClient*) GetClientByID( thisfriend->id ); if(otherclient!=NULL) { ChangeMessengerStatus ( ctherclient, otherclient, 0x08); } } //Logout in clan ClanLogout ( ctherclient ); } break; default: Log( MSG_INFO, "Friend action unknown: %i", action ); break; } return true; }
// Send away the world IP bool CCharServer::pakRequestWorld( CCharClient* thisclient, CPacket* P ) { if (!thisclient->isLoggedIn) return false; MYSQL_ROW row; MYSQL_RES *result; memset( &thisclient->charname, '\0', 17 ); memcpy( thisclient->charname, &P->Buffer[3], (P->Size-6-4)>16?16:(P->Size-6-4) ); if(!CheckEscapeMySQL(thisclient->charname,17,true)) { Log(MSG_WARNING,"A charname contains incorrect caracters or incorrect size (see warnings above)"); return false; } Log( MSG_INFO,"User %s(%i) selected char '%s'", thisclient->username, thisclient->userid, thisclient->charname); if(!DB->QExecute("UPDATE accounts SET lastchar='%s' WHERE id=%i", thisclient->charname, thisclient->userid)) return false; result = DB->QStore("SELECT host,port,lanip,lansubmask FROM channels WHERE id=%u and owner=%u and type=2", thisclient->channel, Config.ServerID); if(result==NULL) return false; if(mysql_num_rows( result )!=1 ) { Log( MSG_WARNING, "Invalid Server: %i", thisclient->channel ); DB->QFree( ); return false; } row = mysql_fetch_row( result ); BEGINPACKET( pak, 0x711 ); ADDWORD ( pak, atoi(row[1]) ); // PORT ADDDWORD ( pak, thisclient->userid ); ADDDWORD ( pak, 0x87654321 ); if(strcmp(thisclient->ClientSubNet,row[3])==0)//from lan { ADDSTRING( pak, row[2] ); Log(MSG_INFO, "Sending LanIP" ); } else if(strcmp( thisclient->ClientSubNet ,"127.0.0")==0)//same computer { ADDSTRING( pak, "127.0.0.1" ); Log(MSG_INFO, "Sending Localhost IP" ); } else { ADDSTRING( pak, row[0] ); Log(MSG_INFO, "Sending InetIP"); } ADDBYTE ( pak, 0 ); thisclient->SendPacket( &pak ); DB->QFree( ); //CHAR INFORMATION 0 1 2 3 4 result = DB->QStore("SELECT clanid,clan_rank,id,level,classid,rewardpoints FROM characters WHERE char_name='%s'", thisclient->charname); if(result==NULL) return false; if(mysql_num_rows(result)!=1) { Log( MSG_WARNING, "Number of user with charname '%s' is %i", thisclient->charname,mysql_num_rows(result)); DB->QFree( ); return false; } row = mysql_fetch_row( result ); thisclient->clanid = atoi( row[0] ); thisclient->clan_rank = atoi( row[1] ); thisclient->charid = atoi( row[2] ); thisclient->level = atoi( row[3] ); thisclient->job = atoi( row[4] ); thisclient->reward_points=atoi( row[5] ); //LMA: reward points: DB->QFree( ); //MESSENGER INFORMATION // // 0 1 result = DB->QStore("SELECT idfriend,namefriend FROM list_friend WHERE id=%i", thisclient->charid); if(result==NULL) return false; BYTE nfriends = mysql_num_rows(result) & 0xff; RESETPACKET( pak, 0x7e1 );// Friend list command ADDBYTE ( pak, 0x06 );// Sending Friend List ADDBYTE ( pak, nfriends );// # friends while(row = mysql_fetch_row( result )) { CFriendList * newfriend = new CFriendList; assert(newfriend); newfriend->id = atoi(row[0]); //friendid strcpy(newfriend->name, row[1]); //friend name thisclient->FriendList.push_back( newfriend ); ADDWORD (pak, newfriend->id);// friend id ADDWORD (pak, 0x0000 ); CCharClient* otherclient = (CCharClient*) GetClientByID( newfriend->id ); if(otherclient!=NULL) //is online?? { ADDBYTE (pak, 0x07 ); //online ChangeMessengerStatus ( thisclient, otherclient, 0x07); } else { ADDBYTE (pak, 0x08 );//offline } ADDSTRING (pak, newfriend->name); //friend name ADDBYTE (pak, 0x00 ); } thisclient->SendPacket( &pak ); DB->QFree( ); thisclient->logout = false; //SEND CLAN INFORMATION SendClanInfo (thisclient); return true; }
// Create a chatroom. //LMA: adding cases. bool CCharServer::pakTalkChatroom ( CCharClient* thisclient, CPacket* P ) { if(!thisclient->isLoggedIn) return false; if(thisclient->chatroom_id==0) { Log(MSG_WARNING,"Player %s tried to talk in a chatroom but he isn't in any...",thisclient->charname); return true; } if(chatroom_list.find(thisclient->chatroom_id)==chatroom_list.end()) { BEGINPACKET( pak, 0x7e3 ); ADDBYTE ( pak, 0x13 ); thisclient->SendPacket( &pak ); Log(MSG_WARNING,"Player %s tried to talk in chatroom %i but it doesn't exist...",thisclient->charname,thisclient->chatroom_id); return true; } char* chat = new (nothrow) char[P->Size]; if(chat==NULL) { Log(MSG_ERROR, "Error allocing memory" ); return false; } memcpy( chat, &P->Buffer, P->Size ); if (strlen(chat)==0) { return true; } //looping and sending the message to other people. CChatroom* mychatroom=chatroom_list[thisclient->chatroom_id]; int nb_users=mychatroom->People_list.size(); for (int k=0;k<nb_users;k++) { //This case shouldn't happen... if (!mychatroom->People_list.at(k)->is_active) { continue; } CCharClient* otherclient=GetClientByID(mychatroom->People_list.at(k)->charid); if (otherclient==NULL) { continue; } BEGINPACKET( pak, 0x7e4); ADDWORD ( pak, thisclient->userid ); ADDSTRING (pak, chat); ADDBYTE ( pak, 0x00 ); otherclient->SendPacket(&pak); } delete[] chat; return true; }
C4Network2Client *C4Network2ClientList::GetHost() { return GetClientByID(C4ClientIDHost); }
void PCommands::doCmdban() { bool SyntaxError = false; if(ArgC < 2) { SyntaxError = true; } if(SyntaxError == true) { Chat->send(source, CHAT_DIRECT, "Usage", "@ban <charID or nickname> <xS(econds)>/<xM(inutes)>/<xH(ours)>/<xD(ays)>"); return; } if(IsArgNumeric(1) == true) { target = GetClientByID(GetArgInt(1)); } else { char tmp_destNick[50]; GetArgText(1, tmp_destNick, 50); target = GetClientByNick(tmp_destNick); } if(target == NULL) // If victim isnt found, return error { Chat->send(source, CHAT_DIRECT, "System", "No such player"); return; } if(source->GetAccountLevel() <= target->GetAccountLevel()) { char tmpMsg[200]; snprintf(tmpMsg, 199, "Cant ban %s, target level is higher or equal to yours!", Chars->GetChar(target->GetCharID())->GetName().c_str()); tmpMsg[199] = '\0'; Chat->send(source, CHAT_DIRECT, "System", tmpMsg); return; } char tmpTimeVal[10]; GetArgText(2, tmpTimeVal, 10); int loop_i = 0; char tmp_atoi[10]; while(isdigit(tmpTimeVal[loop_i]) != 0 && loop_i < 10) { tmp_atoi[loop_i] = tmpTimeVal[loop_i]; loop_i++; } char timefactor[1]; timefactor[0] = tmpTimeVal[loop_i]; int timevalue = atoi(tmp_atoi); int time_to_ban = 0; if(strcasecmp(timefactor, "s") == 0 ) { time_to_ban = timevalue; } else if(strcasecmp(timefactor, "m") == 0 ) { time_to_ban = timevalue * 60; } else if(strcasecmp(timefactor, "h") == 0 ) { time_to_ban = timevalue * 60 * 60; } else if(strcasecmp(timefactor, "d") == 0 ) { time_to_ban = timevalue * 60 * 60 * 24; } else { Chat->send(source, CHAT_DIRECT, "Usage", "@ban <charID or nickname> <xS(econds)>/<xM(inutes)>/<xH(ours)>/<xD(ays)>"); return; } int final_bantime = std::time(NULL) + time_to_ban; PAccount Acc(target->GetAccountID()); Acc.SetBannedUntilTime(final_bantime); Acc.Save(); target->InitCharVanish(); GameServer->ClientDisconnected(target); // Now kick the player (Hes banned :) ) char tmpMsg_success[81]; snprintf(tmpMsg_success, 80, "Successfully banned %s", target->GetChar()->GetName().c_str()); tmpMsg_success[80] = '\0'; Chat->send(source, CHAT_DIRECT, "System", tmpMsg_success); return; }
//LMA: Talking in a chatroom. bool CCharServer::pakChatrooms ( CCharClient* thisclient, CPacket* P ) { if(!thisclient->isLoggedIn) return false; BYTE action = GETBYTE((*P),0); switch(action) { case 0x01: { //Asking for the chatroom list. if(thisclient->chatroom_id!=0) { //if already in a chatroom you can't ask for that. BEGINPACKET( pak, 0x7e3 ); ADDBYTE ( pak, 0x22 ); thisclient->SendPacket( &pak ); return true; } //LMA: we have to clean the chatrooms if needed if(chatroom_list.size()!=0) { map<DWORD,CChatroom*>::iterator it; for ( it=chatroom_list.begin() ; it != chatroom_list.end(); it++ ) { if((*it).second->People_list.size()==0) { chatroom_list.erase((*it).second->chatroom_id); continue; } //checking members now. for (int k=0;k<(*it).second->People_list.size();k++) { CCharClient* otherclient=GetClientByID((*it).second->People_list.at(k)->charid); if(otherclient==NULL) { (*it).second->People_list.erase((*it).second->People_list.begin()+k); k=0; continue; } } if((*it).second->People_list.size()==0) { chatroom_list.erase((*it).second->chatroom_id); continue; } } } BEGINPACKET( pak, 0x7e3); ADDBYTE ( pak, 0x21 ); ADDBYTE ( pak, chatroom_list.size() ); if(chatroom_list.size()!=0) { map<DWORD,CChatroom*>::iterator it; for ( it=chatroom_list.begin() ; it != chatroom_list.end(); it++ ) { if ((*it).second->is_protected) { ADDBYTE ( pak, 0x01 ); } else { ADDBYTE ( pak, 0x00 ); } ADDWORD ( pak, (*it).second->chatroom_id); ADDBYTE ( pak, (*it).second->People_list.size()); //Nb of people inside. ADDSTRING ( pak, (*it).second->chatroom_name.c_str()); ADDBYTE ( pak, 0x00); } } thisclient->SendPacket( &pak ); } break; case 0x02: { //Creating a chatroom. BYTE protection_asked=GETBYTE((*P),1); BYTE max_people=GETBYTE((*P),2); string chatroom_name = (char*) &P->Buffer[3]; string password=""; if(protection_asked==1) { password = (char*) &P->Buffer[3+chatroom_name.size()+1]; if (password.size()>4) { Log(MSG_WARNING,"Player %s tried to give a weird password %s to his chatroom.",thisclient->charname,password.c_str()); password=""; protection_asked=0; } } if (thisclient->chatroom_id!=0) { //already in a chat room. BEGINPACKET( pak, 0x7e3 ); ADDBYTE ( pak, 0x22 ); thisclient->SendPacket( &pak ); return true; } if(max_people==0||chatroom_name.size()==0) { //bogus (but non blocking) error. BEGINPACKET( pak, 0x7e3 ); ADDBYTE ( pak, 0x13 ); thisclient->SendPacket( &pak ); return true; } //Checking if the chatroom name is already taken? map<DWORD,CChatroom*>::iterator it; for ( it=chatroom_list.begin() ; it != chatroom_list.end(); it++ ) { if ((*it).second->chatroom_name==chatroom_name) { //Name already taken, sorry ^_^ BEGINPACKET( pak, 0x7e3 ); ADDBYTE ( pak, 0x18 ); thisclient->SendPacket( &pak ); return true; } } //getting a chatroom ID, like client Id, loop. last_chatroom_id=GetChatroomID ( last_chatroom_id ); if (last_chatroom_id==0xffff) { //bogus (but non blocking) error. BEGINPACKET( pak, 0x7e3 ); ADDBYTE ( pak, 0x13 ); thisclient->SendPacket( &pak ); return true; } CChatroom* newchatroom=new (nothrow) CChatroom; newchatroom->chatroom_id=last_chatroom_id; newchatroom->chatroom_name=chatroom_name; newchatroom->creation_time=time(NULL); newchatroom->nb_max=max_people; newchatroom->password=""; newchatroom->is_protected=false; if (protection_asked==1) { newchatroom->password=password; newchatroom->is_protected=true; } newchatroom->People_list.clear(); //adding the owner for now. CPeople* mypeople=new (nothrow) CPeople; mypeople->account_id=thisclient->userid; mypeople->charid=thisclient->charid; mypeople->charname=thisclient->charname; mypeople->is_active=true; newchatroom->People_list.push_back(mypeople); //adding the new chatroom. chatroom_list[last_chatroom_id]=newchatroom; thisclient->chatroom_id=last_chatroom_id; BEGINPACKET( pak, 0x7e3); ADDBYTE ( pak, 0x01 ); ADDWORD ( pak, thisclient->userid ); ADDWORD ( pak, last_chatroom_id ); //TODO: check if chat ID? ADDWORD ( pak, 0x2066 ); //???? ADDSTRING ( pak, chatroom_name.c_str()); ADDBYTE ( pak, 0x00); thisclient->SendPacket( &pak ); } break; case 0x03: { //joining a chatroom. WORD chatroom_id=GETWORD((*P),2); if (chatroom_list.find(chatroom_id)==chatroom_list.end()) { //LMA: chatroom not found. Log(MSG_WARNING,"Player %s asked to join chatroom %u but it didn't exist.",thisclient->charname,chatroom_id); BEGINPACKET( pak, 0x7e3 ); ADDBYTE ( pak, 0x13 ); thisclient->SendPacket( &pak ); return true; } //checking the password if needed. if (chatroom_list[chatroom_id]->is_protected==1) { if (P->Size<5) { Log(MSG_WARNING,"The chatroom has a password and the player %s didn't send one.",thisclient->charname); BEGINPACKET( pak, 0x7e3 ); ADDBYTE ( pak, 0x12 ); thisclient->SendPacket( &pak ); return true; } string password = (char*) &P->Buffer[4]; if (password!=chatroom_list[chatroom_id]->password) { Log(MSG_WARNING,"Player %s tried to connect to chatroom %s with a wrong password %s != %s",thisclient->charname,chatroom_list[chatroom_id]->chatroom_name.c_str(),password.c_str(),chatroom_list[chatroom_id]->password.c_str()); BEGINPACKET( pak, 0x7e3 ); ADDBYTE ( pak, 0x12 ); thisclient->SendPacket( &pak ); return true; } } CChatroom* mychatroom=chatroom_list[chatroom_id]; int nb_users=mychatroom->People_list.size(); int max_users=0; bool is_ok=false; for (int k=0;k<nb_users;k++) { if (mychatroom->People_list.at(k)->charid==thisclient->charid) { if (!mychatroom->People_list.at(k)->is_active) { //User leaved earlier? is_ok=true; mychatroom->People_list.at(k)->is_active=true; break; } //player is already in the chatroom... break; } max_users++; } if(max_users<=mychatroom->nb_max) { is_ok=true; } else { //chatroom is full BEGINPACKET( pak, 0x7e3 ); ADDBYTE ( pak, 0x11 ); thisclient->SendPacket( &pak ); return true; } if(!is_ok) { BEGINPACKET( pak, 0x7e3 ); ADDBYTE ( pak, 0x22 ); thisclient->SendPacket( &pak ); return true; } //adding the player. CPeople* mypeople=new (nothrow) CPeople; mypeople->account_id=thisclient->userid; mypeople->charid=thisclient->charid; mypeople->charname=thisclient->charname; mypeople->is_active=true; mychatroom->People_list.push_back(mypeople); BEGINPACKET( pak, 0x7e3); ADDBYTE ( pak, 0x10 ); ADDWORD ( pak, thisclient->userid ); ADDWORD ( pak, 0x9031 ); //???? ADDWORD ( pak, mychatroom->nb_max ); //Nb max people??? ADDSTRING ( pak, mychatroom->chatroom_name.c_str()); ADDBYTE ( pak, 0x00); //looping through people list here. nb_users=mychatroom->People_list.size(); for (int k=0;k<nb_users;k++) { if (mychatroom->People_list.at(k)->charid==thisclient->charid) { continue; } ADDWORD ( pak, mychatroom->People_list.at(k)->account_id ); ADDDWORD ( pak, mychatroom->People_list.at(k)->charid ); ADDSTRING ( pak, mychatroom->People_list.at(k)->charname.c_str()); ADDBYTE ( pak, 0x00); } thisclient->SendPacket( &pak ); thisclient->chatroom_id=mychatroom->chatroom_id; //We must tell the others someone came in... for (int k=0;k<nb_users;k++) { if (mychatroom->People_list.at(k)->charid==thisclient->charid) { continue; } CCharClient* otherclient=GetClientByID(mychatroom->People_list.at(k)->charid); if (otherclient==NULL) { continue; } BEGINPACKET( pak, 0x7e3); ADDBYTE ( pak, 0x14); ADDWORD ( pak, thisclient->userid ); ADDDWORD ( pak, thisclient->charid ); ADDSTRING ( pak, thisclient->charname); ADDBYTE ( pak, 0x00); otherclient->SendPacket( &pak ); } } break; case 0x04: { //Asking to leave the chatroom. It seems for now there's a bug in naRose and you just can't leave? BEGINPACKET( pak, 0x7e3 ); ADDBYTE ( pak, 0x15 ); thisclient->SendPacket( &pak ); DisconnectClientFromChat(thisclient); return true; } default: { Log(MSG_WARNING,"Asking for an uncoded chatroom request %i",action); } break; } return true; }
// Clan manager for all the clan functions bool CCharServer::pakClanManager ( CCharClient* thisclient, CPacket* P ) { if(!thisclient->isLoggedIn) return false; MYSQL_RES *result; MYSQL_ROW row; BYTE action = GETBYTE ((*P),0); switch (action) { case 0x01: break; case 0x02://invite clan { char* nick = new (nothrow) char[P->Size]; if(nick==NULL) { Log(MSG_ERROR, "Error allocing memory" ); return false; } memcpy( nick, &P->Buffer[1], P->Size ); if(strcmp(nick,thisclient->charname)==0) return true; CCharClient* otherclient = (CCharClient*) GetClientByName( nick ); if(otherclient!=NULL) { BEGINPACKET( pak, 0x7e0 ); ADDBYTE ( pak, 0x0b );//invite action ADDSTRING ( pak, thisclient->charname ); ADDBYTE ( pak, 0x0 ); otherclient->SendPacket( &pak ); } delete []nick; } break; case 0x03://Kick from clan { char* nick = new (nothrow) char[P->Size]; if(nick==NULL) { Log(MSG_ERROR, "Error allocing memory" ); return false; } memcpy( nick, &P->Buffer[1], P->Size ); CClans* thisclan = GetClanByID(thisclient->clanid); if(thisclan==NULL) { delete []nick; return true; } BEGINPACKET( pak, 0x7e0 ); ADDBYTE ( pak, 0x81 );//xxx have kicket to yyyy ADDSTRING ( pak, nick ); ADDBYTE ( pak, 0x00); ADDSTRING ( pak, thisclient->charname ); ADDBYTE ( pak, 0x00); SendToClanMembers(thisclient->clanid,&pak); for(UINT i=0;i<thisclan->ClanMembers.size( );i++) { CClanMembers* ClanMember = thisclan->ClanMembers.at( i ); if(strcmp(ClanMember->name,nick)==0) { thisclan->ClanMembers.erase( thisclan->ClanMembers.begin() + i ); break; } } CCharClient* otherclient = (CCharClient*) GetClientByName( nick ); if( otherclient!=NULL ) { otherclient->clanid = 0; otherclient->clan_rank=1; RESETPACKET( pak, 0x7e1 );//Update world clan information ADDBYTE ( pak, 0xfb );//action (kick) ADDSTRING ( pak, nick ); ADDBYTE ( pak, 0x00 ); CChanels* thischannel = GetChannelByID( otherclient->channel ); if(thischannel!=NULL) { send( thischannel->sock, (char*)&pak, pak.Size, 0 ); } else { Log(MSG_ERROR, "Check serverid in worldserver.conf it should be the same as ID in channels in the mysql database %i",thisclient->channel);} pakClanMembers( otherclient ); } if(!DB->QExecute("UPDATE characters SET clanid=0 AND clan_rank=1 WHERE char_name='%s'",nick)) { delete []nick; return false; } delete []nick; } break; case 0x04://up rank { bool online = true; char* nick = new (nothrow) char[P->Size-7]; if(nick==NULL) { Log(MSG_ERROR, "Error allocing memory" ); return false; } memcpy( nick, &P->Buffer[1], P->Size-7 ); int clan_rank=0; int level=0; int job=0; int channel=0xff; if(strcmp(nick,thisclient->charname)==0) { delete []nick; return true; } CCharClient* otherclient = GetClientByName ( nick ); if(otherclient!=NULL) { clan_rank = otherclient->clan_rank; if(otherclient->clan_rank<5) { otherclient->clan_rank++; } else { delete []nick; return true; } CClans* thisclan = GetClanByID(otherclient->clanid); for(UINT i=0;i<thisclan->ClanMembers.size();i++) { CClanMembers* thismember = thisclan->ClanMembers.at(i); if(thismember!=0) { if (thismember->id==otherclient->charid) { thismember->clan_rank=otherclient->clan_rank; } } } job = otherclient->job; level = otherclient->level; channel=otherclient->channel; BEGINPACKET( pak, 0x7e0 ); ADDBYTE ( pak, 0x83 ); ADDSTRING ( pak, nick ); ADDBYTE ( pak, 0x00 ); ADDBYTE ( pak, otherclient->clan_rank ); otherclient->SendPacket(&pak); } else { online=false; result = DB->QStore("SELECT clan_rank,classid,level FROM characters WHERE char_name='%s'",nick); if(result==NULL) { delete []nick; DB->QFree( ); return false; } if(mysql_num_rows(result)!=1) { Log(MSG_WARNING, "Invalid charname: %s" , nick ); delete []nick; DB->QFree( ); return false; } row = mysql_fetch_row( result ); clan_rank=atoi(row[0]); job = atoi(row[1]); level = atoi(row[2]); DB->QFree( ); } if(clan_rank<5) { clan_rank++; } if(!DB->QExecute("UPDATE characters SET clan_rank=%i WHERE char_name='%s'",clan_rank,nick)) { delete []nick; return false; } BEGINPACKET( pak, 0x7e0 ); ADDBYTE ( pak, 0x75 ); ADDBYTE ( pak, clan_rank ); ADDBYTE ( pak, channel );//channel ADDWORD ( pak, 0x0000 ); ADDWORD ( pak, 0x0000 ); ADDWORD ( pak, level ); // level ADDWORD ( pak, job ); // job ADDSTRING ( pak, nick ); // Nick ADDBYTE ( pak, 0x00 ); SendToClanMembers(thisclient->clanid,&pak); if (online==true) { RESETPACKET( pak, 0x7e1 );//update world information ADDBYTE ( pak, 0xfc ); ADDBYTE ( pak, clan_rank ); ADDSTRING ( pak, nick ); ADDBYTE ( pak, 0x00 ); CChanels* thischannel = GetChannelByID( channel ); if(thischannel!=NULL){ send( thischannel->sock, (char*)&pak, pak.Size, 0 );} else { Log(MSG_ERROR, "Check serverid in worldserver.conf it should be the same as ID in channels in the mysql database %i",thisclient->channel);} } delete []nick; } break; case 0x05://down rank { bool online = true; char* nick = new (nothrow) char[P->Size-7]; if(nick==NULL) { Log(MSG_ERROR, "Error allocing memory" ); return false; } memcpy( nick, &P->Buffer[1], P->Size-7 ); int clan_rank=0; int level=0; int job=0; int channel=0xff; if(strcmp(nick,thisclient->charname)==0) { delete []nick; return true; } CCharClient* otherclient = GetClientByName ( nick ); if(otherclient!=NULL) { clan_rank = otherclient->clan_rank; if(otherclient->clan_rank>1) { otherclient->clan_rank--; } else { delete []nick; return true; } CClans* thisclan = GetClanByID(otherclient->clanid); for(UINT i=0;i<thisclan->ClanMembers.size();i++) { CClanMembers* thismember = thisclan->ClanMembers.at(i); if(thismember!=0) { if (thismember->id==otherclient->charid) { thismember->clan_rank=otherclient->clan_rank; } } } job = otherclient->job; level = otherclient->level; channel=otherclient->channel; BEGINPACKET( pak, 0x7e0 ); ADDBYTE ( pak, 0x83 ); ADDSTRING ( pak, nick ); ADDBYTE ( pak, 0x00 ); ADDBYTE ( pak, otherclient->clan_rank ); otherclient->SendPacket(&pak); } else { online=false; result = DB->QStore("SELECT clan_rank,classid,level FROM characters WHERE char_name='%s'",nick); if(result==NULL) { delete []nick; DB->QFree( ); return false; } if(mysql_num_rows(result)!=1) { Log(MSG_WARNING, "Invalid charname: %s" , nick ); delete []nick; DB->QFree( ); return false; } row = mysql_fetch_row( result ); clan_rank=atoi(row[0]); job = atoi(row[1]); level = atoi(row[2]); DB->QFree( ); } if(clan_rank>1) { clan_rank--; } if(!DB->QExecute("UPDATE characters SET clan_rank=%i WHERE char_name='%s'",clan_rank,nick)) { delete []nick; return false; } BEGINPACKET( pak, 0x7e0 ); ADDBYTE ( pak, 0x75 ); ADDBYTE ( pak, clan_rank ); ADDBYTE ( pak, channel );//channel ADDWORD ( pak, 0x0000 ); ADDWORD ( pak, 0x0000 ); ADDWORD ( pak, level ); // level ADDWORD ( pak, job ); // job ADDSTRING ( pak, nick ); // Nick ADDBYTE ( pak, 0x00 ); SendToClanMembers(thisclient->clanid,&pak); if (online==true) { RESETPACKET( pak, 0x7e1 );//update world information ADDBYTE ( pak, 0xfc ); ADDBYTE ( pak, clan_rank ); ADDSTRING ( pak, nick ); ADDBYTE ( pak, 0x00 ); CChanels* thischannel = GetChannelByID( channel ); if(thischannel!=NULL){ send( thischannel->sock, (char*)&pak, pak.Size, 0 );} else { Log(MSG_ERROR, "Check serverid in worldserver.conf it should be the same as ID in channels in the mysql database %i",thisclient->channel);} } delete []nick; } break; case 0x06://Change news { if(thisclient->clan_rank<5) return true; char* news = new (nothrow) char[P->Size-7]; if(news==NULL) { Log(MSG_ERROR, "Error allocing memory" ); return false; } memcpy( news, &P->Buffer[1], P->Size-7 ); CClans* thisclan = GetClanByID(thisclient->clanid); if(thisclan!=NULL) { strcpy(thisclan->news,news); BEGINPACKET( pak, 0x7e0 ); ADDBYTE ( pak, 0x34 ); ADDSTRING ( pak, thisclan->news ); ADDBYTE ( pak, 0x00 ); SendToClanMembers(thisclan->id,&pak); if(!DB->QExecute("UPDATE list_clan SET news='%s' WHERE id=%i", thisclan->news, thisclan->id)) return false; } delete []news; } break; case 0x07://Leave Clan { if( thisclient->clan_rank == 6 ) return true; CClans* thisclan = GetClanByID( thisclient->clanid ); if(thisclan==NULL) return true; BEGINPACKET( pak, 0x7e0 ); ADDBYTE( pak, 0x82 ); ADDSTRING( pak, thisclient->charname ); ADDBYTE( pak, 0x00); SendToClanMembers(thisclient->clanid,&pak); for(UINT i=0;i<thisclan->ClanMembers.size();i++) { CClanMembers* ClanMember = thisclan->ClanMembers.at( i ); if(strcmp(ClanMember->name,thisclient->charname)==0) { thisclan->ClanMembers.erase( thisclan->ClanMembers.begin()+i ); delete ClanMember; break; } } thisclient->clanid = 0; thisclient->clan_rank=1; if(!DB->QExecute("UPDATE characters SET clanid=0 , clan_rank=0 WHERE char_name='%s'",thisclient->charname)) return false; RESETPACKET( pak, 0x7e1 );//Update world clan information ADDBYTE ( pak, 0xfb );//action (leave) ADDSTRING ( pak, thisclient->charname ); ADDBYTE ( pak, 0x00 ); CChanels* thischannel = GetChannelByID( thisclient->channel ); if(thischannel!=NULL){ send( thischannel->sock, (char*)&pak, pak.Size, 0 );} else { Log(MSG_ERROR, "Check serverid in worldserver.conf it should be the same as ID in channels in the mysql database %i",thisclient->channel);} } break; case 0x08: { pakClanMembers ( thisclient ); } break; case 0x09://Give Master { int clan_rank=0; int level=0; int job=0; int channel=0xff; char* nick = new (nothrow) char[P->Size-7]; if(nick==NULL) { Log(MSG_ERROR, "Error allocing memory" ); return false; } memcpy( nick, &P->Buffer[1], P->Size-7 ); if(strcmp(nick,thisclient->charname)==0) { delete []nick; return true; } //Convert to master CCharClient* otherclient = GetClientByName ( nick ); if(otherclient!=NULL) { clan_rank = 6; otherclient->clan_rank = clan_rank; job = otherclient->job; level = otherclient->level; channel = otherclient->channel; BEGINPACKET( pak, 0x7e0 ); ADDBYTE ( pak, 0x83 ); ADDSTRING ( pak, nick ); ADDBYTE ( pak, 0x00 ); ADDBYTE ( pak, otherclient->clan_rank ); otherclient->SendPacket(&pak); } else { // 0 1 result = DB->QStore("SELECT classid,level FROM characters where char_name='%s'",nick); if(result==NULL) { delete []nick; return false; } if(mysql_num_rows(result)!=1) { DB->QFree( ); Log(MSG_WARNING, "Invalid charname: %s" , nick ); delete []nick; return false; } row = mysql_fetch_row( result ); job = atoi(row[0]); level = atoi(row[1]); DB->QFree( ); } if(!DB->QExecute("UPDATE characters SET clan_rank=%i WHERE char_name='%s'",clan_rank,nick)) { delete []nick; return false; } BEGINPACKET( pak, 0x7e0 ); ADDBYTE ( pak, 0x75 ); ADDBYTE ( pak, clan_rank ); ADDBYTE ( pak, channel );//canal ADDWORD ( pak, 0x0000 ); ADDWORD ( pak, 0x0000 ); ADDWORD ( pak, level ); //level? ADDWORD ( pak, job ); // job? ADDSTRING ( pak, nick ); ADDBYTE ( pak, 0x00 ); SendToClanMembers(thisclient->clanid,&pak); RESETPACKET( pak, 0x7e1 );//update world information ADDBYTE ( pak, 0xfc ); ADDBYTE ( pak, clan_rank ); ADDSTRING ( pak, nick ); ADDBYTE ( pak, 0x00 ); CChanels* thischannel = GetChannelByID( channel ); if(thischannel!=NULL){ send( thischannel->sock, (char*)&pak, pak.Size, 0 );} else { Log(MSG_ERROR, "Check serverid in worldserver.conf it should be the same as ID in channels in the mysql database %i",thisclient->channel);} //Convert to commander clan_rank = 4; thisclient->clan_rank=clan_rank; job = thisclient->job; level = thisclient->level; channel = thisclient->channel; RESETPACKET( pak, 0x7e0 ); ADDBYTE ( pak, 0x83 ); ADDSTRING ( pak, thisclient->charname ); ADDBYTE ( pak, 0x00 ); ADDBYTE ( pak, thisclient->clan_rank ); thisclient->SendPacket(&pak); if(!DB->QExecute("UPDATE characters SET clan_rank=%i WHERE char_name='%s'",clan_rank,thisclient->charname)) { delete []nick; return false; } RESETPACKET( pak, 0x7e0 ); ADDBYTE ( pak, 0x75 ); ADDBYTE ( pak, clan_rank ); ADDBYTE ( pak, channel );//canal ADDWORD ( pak, 0x0000 ); ADDWORD ( pak, 0x0000 ); ADDWORD ( pak, level ); //level? ADDWORD ( pak, job ); // job? ADDSTRING ( pak, thisclient->charname ); ADDBYTE ( pak, 0x00 ); SendToClanMembers(thisclient->clanid,&pak); RESETPACKET( pak, 0x7e1 );//update world information ADDBYTE ( pak, 0xfc ); ADDBYTE ( pak, clan_rank ); ADDSTRING ( pak, thisclient->charname ); ADDBYTE ( pak, 0x00 ); thischannel = GetChannelByID( channel ); if(thischannel!=NULL){ send( thischannel->sock, (char*)&pak, pak.Size, 0 );} else { Log(MSG_ERROR, "Check serverid in worldserver.conf it should be the same as ID in channels in the mysql database %i",thisclient->channel);} delete []nick; } break; case 0x0a://disorganize clan { if(thisclient->clan_rank<6) return true; unsigned int clanid = thisclient->clanid; CClans* thisclan = GetClanByID(thisclient->clanid); if(thisclan==NULL) return true; if(thisclan->ClanMembers.size()>1)//Can't be deleted if there are members return true; if(!DB->QExecute("UPDATE characters SET clanid=0 AND clan_rank=1 WHERE clanid=%i",thisclient->clanid)) return false; if(!DB->QExecute("DELETE FROM list_clan WHERE id=%i",thisclient->clanid)) return false; BEGINPACKET( pak, 0x7e0 ); ADDBYTE ( pak, 0x51 ); ADDBYTE ( pak, 0x00 ); SendToClanMembers(thisclient->clanid, &pak); thisclan->ClanMembers.clear( ); //delete from clan list for(UINT i=0;i<ClanList.size( );i++) { CClans* clan = ClanList.at( i ); if(thisclan == clan) { ClanList.erase( ClanList.begin() + i ); delete clan; break; } } RESETPACKET( pak, 0x7e1 );//Update world clan information ADDBYTE ( pak, 0xfd );//action (disorg) ADDWORD ( pak, clanid ); ADDWORD ( pak, thisclient->charid ); CChanels* thischannel = GetChannelByID( thisclient->channel ); if(thischannel!=NULL){ send( thischannel->sock, (char*)&pak, pak.Size, 0 );} else { Log(MSG_ERROR, "Check serverid in worldserver.conf it should be the same as ID in channels in the mysql database %i",thisclient->channel);} thisclient->clanid = 0; thisclient->clan_rank = 1; //send( wct } break; case 0x0c://invitation accepted { char* nick = new (nothrow) char[P->Size-7]; if(nick==NULL) { Log(MSG_ERROR, "Error allocing memory" ); return false; } memcpy( nick, &P->Buffer[1], P->Size-7 ); CCharClient* otherclient = (CCharClient*) GetClientByName(nick ); if(otherclient!=NULL) { thisclient->clanid = otherclient->clanid; thisclient->clan_rank=1; if(!DB->QExecute("UPDATE characters SET clanid=%i , clan_rank=1 WHERE char_name='%s'",thisclient->clanid,thisclient->charname)) { delete []nick; return false; } CClans* thisclan = GetClanByID(thisclient->clanid); if(thisclan==NULL) { Log(MSG_ERROR, "Clan with id %d doesn't exist", thisclient->clanid); delete []nick; return true; } CClanMembers* newmember = new (nothrow) CClanMembers; if(newmember==NULL) { Log( MSG_WARNING, "Error allocing memory" ); delete []nick; return false; } newmember->id = thisclient->charid; strcpy(newmember->name,thisclient->charname); newmember->clan_rank = 1; thisclan->ClanMembers.push_back( newmember ); } else { Log(MSG_ERROR, "Char with name %s doesn't exist", nick); delete []nick; return true; } SendClanInfo(thisclient); pakClanMembers(thisclient); BEGINPACKET( pak, 0x7e0 );//xxx have invited to xxx ADDBYTE( pak, 0x61 ); ADDSTRING( pak, thisclient->charname ); ADDBYTE( pak, 0x00); ADDSTRING( pak, otherclient->charname ); ADDBYTE( pak, 0x00); SendToClanMembers(thisclient->clanid,&pak); RESETPACKET( pak, 0x7e0 ); ADDBYTE ( pak, 0x84 ); ADDWORD ( pak, thisclient->level ); ADDWORD ( pak, thisclient->job ); ADDSTRING ( pak, thisclient->charname ); ADDBYTE ( pak, 0x00 ); SendToClanMembers(thisclient->clanid,&pak); RESETPACKET( pak, 0x7e1 );//update clan info in world ADDBYTE( pak, 0xfa ); ADDWORD( pak, thisclient->charid ); ADDWORD( pak, thisclient->clanid ); CChanels* thischannel = GetChannelByID( thisclient->channel ); if(thischannel!=NULL) { send( thischannel->sock, (char*)&pak, pak.Size, 0 ); } else { Log(MSG_ERROR, "Check serverid in worldserver.conf it should be the same as ID in channels in the mysql database %i",thisclient->channel); } CChanels* otherchannel = GetChannelByID( otherclient->channel ); if(otherchannel!=NULL && thischannel!=otherchannel) { send( thischannel->sock, (char*)&pak, pak.Size, 0 ); } delete []nick; } break; case 0x0d://invitation no accepted { char* nick = new (nothrow) char[P->Size-7]; if(nick==NULL) { Log(MSG_ERROR, "Error allocing memory" ); return false; } memcpy( nick, &P->Buffer[1], P->Size-7 ); CCharClient* otherclient = (CCharClient*) GetClientByName(nick ); if(otherclient!=NULL) { BEGINPACKET( pak, 0x7e0 ); ADDBYTE ( pak, 0x0d ); ADDSTRING ( pak, thisclient->charname ); ADDBYTE ( pak, 0x00 ); otherclient->SendPacket(&pak); } delete []nick; } break; case 0x0f:// Update Clan window with Level and Job { CClans* thisclan = (CClans*) GetClanByID( thisclient->clanid ); if(thisclan!=NULL) { BEGINPACKET( pak, 0x7e0 ); ADDBYTE ( pak, 0x84 ); ADDWORD ( pak, GETWORD ((*P),1) ); ADDWORD ( pak, GETWORD ((*P),3) ); ADDSTRING ( pak, thisclient->charname ); ADDBYTE ( pak, 0x00 ); SendToClanMembers(thisclient->clanid,&pak); } } break; case 0x5C://message from worldserver to load the new clan information { UINT clanid = GETWORD((*P),1); UINT clientrank = GETWORD((*P),3); CClans* thisclan = (CClans*) GetClanByID( clanid ); if(thisclan==NULL) return true; thisclan->cp=GETDWORD ((*P),5); BEGINPACKET( pak, 0x7e0); ADDBYTE ( pak, 0x71); ADDWORD ( pak, clanid); ADDWORD ( pak, 0x0000);// ADDWORD ( pak, thisclan->back );//clan background ADDWORD ( pak, thisclan->logo );//clanlogo ADDBYTE ( pak, thisclan->grade);//clan grade ADDBYTE ( pak, 0xCC); ADDDWORD ( pak, thisclan->cp ); ADDDWORD ( pak, 0x00000064 ); ADDDWORD ( pak, 0x00000000 ); ADDDWORD ( pak, 0x00000000 ); ADDWORD ( pak, 0xCCCC ); ADDWORD ( pak, 0xCCCC ); ADDWORD ( pak, 0xCCCC ); for(int i=0;i<119;i++) ADDBYTE ( pak, 0x00); SendToClanMembers(clanid,&pak); UpdateClanWindow(clanid); } break; case 0xfa://message from worldserver to load the new clan information { int id = GETWORD((*P),1); // clanid int charid = GETWORD((*P),3); // charid int clientid = GETWORD((*P),5); // clientid CCharClient* otherclient = (CCharClient*) GetClientByID ( charid ); if(otherclient==NULL) return true; // Load all our clan information // 0 1 2 3 4 5 6 7 result = DB->QStore("SELECT id,logo,back,name,cp,grade,slogan,news FROM list_clan where id=%i",id); if(result == NULL) return false; if(mysql_num_rows(result)!=1) { DB->QFree( ); Log(MSG_WARNING, "Invalid clan: %i" , id ); return false; } row = mysql_fetch_row(result); //clan info CClans* newclan = new CClans; assert(newclan); newclan->id = atoi(row[0]); newclan->logo = atoi(row[1]); newclan->back = atoi(row[2]); strncpy(newclan->name,row[3],16); newclan->cp = atoi(row[4]); newclan->grade = atoi(row[5]); strncpy(newclan->slogan,row[6],29); strcpy(newclan->news,row[7]); ClanList.push_back( newclan ); DB->QFree( ); //member info CClanMembers* newmember = new CClanMembers; newmember->id = otherclient->charid; strcpy(newmember->name,otherclient->charname); newmember->clan_rank = 6; newclan->ClanMembers.push_back( newmember ); otherclient->clanid = id; otherclient->clan_rank = 6; //Send new clan information BEGINPACKET( pak, 0x7e0); ADDBYTE ( pak, 0x30); ADDWORD ( pak, clientid); ADDWORD ( pak, 0x0100);// ADDWORD ( pak, newclan->back );//clan background ADDWORD ( pak, newclan->logo );//clanlogo ADDBYTE ( pak, newclan->grade);//clan grade ADDBYTE ( pak, otherclient->clan_rank);// clan rank ADDDWORD ( pak, newclan->cp ); ADDDWORD ( pak, 0x00000000 ); // Unk ADDDWORD ( pak, 0x00000000 ); // Clan Funds ADDDWORD ( pak, 0x00000000 ); // Unk ADDWORD ( pak, 0x0000 ); // Unk ADDDWORD ( pak, 0x00000000 ); // Contribution for(int i=0;i<120;i++) ADDBYTE ( pak, 0x00); ADDSTRING ( pak, newclan->name);//clan name ADDBYTE ( pak, 0x00); ADDSTRING ( pak, newclan->slogan);//clan slogan ADDBYTE ( pak, 0x00); otherclient->SendPacket(&pak); } break; case 0xfb: { UINT clanid = GETWORD((*P),1); UINT grade = GETWORD((*P),3); CClans* thisclan = (CClans*) GetClanByID( clanid ); if(thisclan!=NULL) { BEGINPACKET( pak, 0x7e0 ); ADDBYTE ( pak, 0x84 ); ADDWORD ( pak, GETWORD ((*P),1) ); ADDWORD ( pak, GETWORD ((*P),3) ); ADDSTRING ( pak, thisclient->charname ); ADDBYTE ( pak, 0x00 ); SendToClanMembers(thisclient->clanid,&pak); } } default: Log( MSG_INFO, "Clan action unknow %i ", action); break; } return true; }
// Party Actions [invite/leave/kick] bool CWorldServer::pakPartyActions( CPlayer* thisclient, CPacket* P ) { unsigned int action = GETBYTE((*P),0); CMap* map = MapList.Index[thisclient->Position->Map]; switch(action) { case 0x00://Invita a new party case 0x01://invite a existent party { UINT clientid = GETWORD((*P),1); if(thisclient->Party->party!=NULL) { //LMA: Refreshing Capacity if needed thisclient->Party->party->RefreshMax(); if(thisclient->Party->party->Members.size()>=thisclient->Party->party->Capacity) { SendSysMsg( thisclient, "Party is full" ); return true; } } CPlayer* otherclient = map->GetPlayerInMap( clientid );// have to be in same map if(otherclient==NULL) { BEGINPACKET( pak, 0x7d1 ); ADDBYTE ( pak, 0x00 );//No encontro el ID ADDWORD ( pak, clientid ); ADDBYTE ( pak, 0x00 ); thisclient->client->SendPacket( &pak ); return true; } if(otherclient->Party->party!=NULL) { BEGINPACKET( pak, 0x7d1 ); ADDBYTE ( pak, 0x01 );//No puede ser solicitado (ya tiene party) ADDWORD ( pak, clientid ); ADDBYTE ( pak, 0x00 ); thisclient->client->SendPacket( &pak ); return true; } if(abs(otherclient->Stats->Level-thisclient->Stats->Level)>(Config.Partygap+1)) { BEGINPACKET( pak, 0x7d1 ); ADDBYTE ( pak, 0x07 );//Level inapropiado ADDWORD ( pak, clientid ); ADDBYTE ( pak, 0x00 ); thisclient->client->SendPacket( &pak ); return true; } BEGINPACKET( pak, 0x7d0 ); ADDBYTE ( pak, action ); ADDWORD ( pak, thisclient->clientid ); ADDBYTE ( pak, 0x00 ); otherclient->client->SendPacket( &pak ); } break; case 0x02://Leave Party { if(thisclient->Party->party==NULL) return true; CParty* party = thisclient->Party->party; BEGINPACKET( pak, 0x7d2 ); ADDWORD ( pak, 0xff00 ); ADDDWORD ( pak, thisclient->CharInfo->charid ); bool pflag = false; if(!party->RemovePlayer( thisclient )) //if this player is not in this party return true; if(party->Members.size()>1) { for(UINT i=0;i<party->Members.size();i++) { CPlayer* thismember = party->Members.at(i); if(!pflag) { ADDDWORD( pak, thismember->CharInfo->charid ); if(thisclient->Party->IsMaster) thismember->Party->IsMaster = true; pflag = true; } thismember->client->SendPacket( &pak ); } } else { for(UINT i=0;i<party->Members.size();i++) { CPlayer* thismember = party->Members.at(i); BEGINPACKET( pak, 0x7d1 ); ADDBYTE ( pak, 0x05 ); ADDWORD ( pak, 0x0000 ); ADDWORD ( pak, 0x0000 ); thismember->client->SendPacket( &pak ); thismember->Party->party = NULL; thismember->Party->IsMaster = true; } RemoveParty( party ); delete party; } } break; case 0x03: //Tomiz: Give leader New Way { if(thisclient->Party->party==NULL) return true; unsigned int clientid = GETWORD((*P),1); if ( !thisclient->Party->IsMaster || clientid == thisclient->clientid ) return true; CPlayer* otherclient = GetClientByID( clientid ); if(otherclient==NULL) return true; BEGINPACKET(pak, 0x7d1); ADDBYTE(pak, 8); ADDWORD(pak, otherclient->clientid); ADDWORD(pak, 0); otherclient->Party->IsMaster = true; thisclient->Party->IsMaster = false; thisclient->Party->party->SendToMembers( &pak ); } break; case 0x81: //Kick from party { unsigned int charid = GETDWORD((*P),1); if(thisclient->Party->party==NULL) return true; if(!thisclient->Party->IsMaster || thisclient->CharInfo->charid==charid) return true; CParty* party = thisclient->Party->party; CPlayer* thismember = party->GetMemberByCharID( charid ); if(thismember==NULL) return true; BEGINPACKET( pak, 0x7d1 ); // Kicked from party message ADDBYTE ( pak, 0x80 ); ADDDWORD ( pak, thismember->CharInfo->charid ); thismember->client->SendPacket( &pak ); RESETPACKET( pak, 0x7d2 ); ADDWORD ( pak, 0xff00 ); ADDDWORD ( pak, thismember->CharInfo->charid ); bool pflag = false; if(!party->RemovePlayer( thismember )) //if this player is not in this party return true; if(party->Members.size()>1) { for(UINT i=0;i<party->Members.size();i++) { CPlayer* othermember = party->Members.at(i); if(!pflag) { ADDDWORD( pak, othermember->CharInfo->charid ); if(thismember->Party->IsMaster) othermember->Party->IsMaster = true; pflag = true; } othermember->client->SendPacket( &pak ); } } else { for(UINT i=0;i<party->Members.size();i++) { CPlayer* othermember = party->Members.at(i); BEGINPACKET( pak, 0x7d1 ); ADDBYTE ( pak, 0x05 ); ADDWORD ( pak, 0x0000 ); ADDWORD ( pak, 0x0000 ); othermember->client->SendPacket( &pak ); othermember->Party->party = NULL; othermember->Party->IsMaster = true; } RemoveParty( party ); delete party; } } break; default: Log(MSG_WARNING,"Party unknown action: %i", action); } return true; }
void PCommands::doCmdrecall() { bool SyntaxError = false; if ( ArgC < 1 ) { SyntaxError = true; } if ( SyntaxError == true ) { Chat->send( source, CHAT_DIRECT, "Usage", "@recall <charID or nickname>" ); return; } if ( IsArgNumeric( 1 ) == true ) { target = GetClientByID( GetArgInt( 1 ) ); } else { char tmp_destNick[50]; GetArgText( 1, tmp_destNick, 50 ); target = GetClientByNick( tmp_destNick ); } if ( target == NULL ) // If victim isnt found, return error { Chat->send( source, CHAT_DIRECT, "System", "No such player" ); return; } // Check accountlevel (Only higher's can perform commands on lower's) if ( source->GetAccountLevel() <= target->GetAccountLevel() ) { char tmpMsg[200]; snprintf( tmpMsg, 199, "Cant warp %s to you, target level is higher or equal to yours!", Chars->GetChar( target->GetCharID() )->GetName().c_str() ); tmpMsg[199] = '\0'; Chat->send( source, CHAT_DIRECT, "System", tmpMsg ); return; } // Warp target player to GM/Admin int destZone = Chars->GetChar( source->GetCharID() )->GetLocation(); if ( !Worlds->IsValidWorld( destZone ) ) { Console->Print( "%s Can't change location, destZone '%d' is invalid for some reason", Console->ColorText( RED, BLACK, "[PANIC]" ), destZone ); return; } // *************** Checks done, proceed with command if ( target->ChangeCharLocation( destZone ), true ) { PMessage* tmpMsg_zone = MsgBuilder->BuildAptLiftUseMsg( target, destZone, 0 ); target->SendUDPMessage( tmpMsg_zone ); tmpMsg_zone = NULL; u16 nNewX, nNewY, nNewZ; nNewX = source->GetChar()->Coords.mX; nNewY = source->GetChar()->Coords.mY; nNewZ = source->GetChar()->Coords.mZ; target->SetAwaitingWarpto( true, nNewX, nNewY, nNewZ ); char tmpMsg_success[81]; snprintf( tmpMsg_success, 80, "Successfully recalled %s", target->GetChar()->GetName().c_str() ); tmpMsg_success[80] = '\0'; Chat->send( source, CHAT_DIRECT, "System", tmpMsg_success ); return; } else { Console->Print( "%s Unable to change location for player %d to %d", Console->ColorText( RED, BLACK, "[PANIC]" ), target->GetCharID(), destZone ); } }
void RetreiveNetData() { char *buffer; unsigned long bbID; int typeID; while(buffer = bb_serverReceive(bbID,typeID)) { switch(typeID) { case VERSION: { stVersion ver; memcpy(&ver,buffer,sizeof(stVersion)); stStatus status; if(stricmp(ver.Version,CurrentVersion)) //the client doesnt have latest version { //the client needs to get updated CClient *C = GetClientByID(bbID); if(!C) continue; sprintf(C->Version,ver.Version); C->Updating = true; C->NeedList = true; C->OnlyDB = false; status.Status = 1; } else //no update needed { //telling the client he is up to date status.Status = 0; //RemoveClient(bbID); } bb_serverSend((char*)&status,sizeof(stStatus),STATUS,bbID,NET_TCP); break; } case DB_VERSION: { stDBVersion ver; memcpy(&ver,buffer,sizeof(stDBVersion)); stStatus status; // client sent us his db version if( ver.Version != CurrentDBVersion ) //the client db is out of sync { CClient *C = GetClientByID(bbID); if(!C) continue; // send him the latest database C->Updating = true; C->NeedList = true; C->OnlyDB = true; status.Status = 1; } else { //client db is up to date status.Status = 0; RemoveClient(bbID); } bb_serverSend((char*)&status,sizeof(stStatus),STATUS,bbID,NET_TCP); break; } case PING: //a client wants to ping us { //let's send him a pong printf(" > Received a PING query, sending PONG\n"); bb_serverSend(0,0,PONG,bbID,NET_TCP); break; } case LOAD_QUERY: //a client wants to know our current load { stLoadScore ls; ls.LoadScore = CurrentLoad; bb_serverSend((char*)&ls,sizeof(stLoadScore),LOAD_SCORE,bbID,NET_TCP); break; } case ACK: { //we receive an ACK from a client CClient *C = GetClientByID(bbID); if(!C) continue; C->Acked = true; C->mfElaspedSinceLastAck = 0.0f; break; } default: { //unknown packet type, kick the client and ignore it printf(" > Unknown packet type, disconnecting client\n"); bb_serverDisconnectClient(bbID); RemoveClient(bbID); } } } }
void CClientInfoMgr::AddClient ( char const* pszName, bool bIsAdmin, uint32 nID, uint8 nTeamID) { m_nLocalID = 0; g_pLTClient->GetLocalClientID (&m_nLocalID); // if we already have this client in the list, then it's an update, not an add. CLIENT_INFO* pDup = GetClientByID(nID, false); if (pDup) { UpdateClient( pszName, bIsAdmin, nID, nTeamID ); return; } if( g_pGameClientShell->ShouldUseRadar() ) { g_pRadar->UpdatePlayerName(nID, pszName, nTeamID ); } // create the new object CLIENT_INFO* pNew = debug_new(CLIENT_INFO); if (!pNew) return; pNew->nID = nID; pNew->sName = pszName; pNew->bIsAdmin = bIsAdmin; pNew->nTeamID = nTeamID; pNew->sScore.Init(nID); // if we don't have a list yet, set the list pointer to the new object if (!m_pClients) { m_pClients = pNew; return; } // we do have a list - insert the object CLIENT_INFO* ptr = m_pClients; //insert at head? if (ptr->sScore.GetScore() < pNew->sScore.GetScore()) { pNew->pNext = m_pClients; m_pClients = pNew; return; } CLIENT_INFO* pNext = ptr->pNext; while (pNext && pNext->sScore.GetScore() >= pNew->sScore.GetScore()) { ptr = pNext; pNext = ptr->pNext; } if (pNext) { pNext->pPrev = pNew; } ptr->pNext = pNew; pNew->pNext = pNext; pNew->pPrev = ptr; }
CLIENT_INFO* CClientInfoMgr::GetLocalClient() { return GetClientByID(m_nLocalID); }
void PCommands::doCmdSetMainSkill() { u8 tNewLevel = 0; u8 tMainSkill = 0; bool SyntaxError = false; if (ArgC < 2) { SyntaxError = true; } if (IsArgNumeric(1) == false) SyntaxError = true; else tMainSkill = (u16)GetArgInt(1); if (IsArgNumeric(2) == false) SyntaxError = true; else tNewLevel = (u8)GetArgInt(2); if (tNewLevel == 0) SyntaxError = true; if ( source->GetChar()->Skill->IsValidMainSkill(tMainSkill) == false) SyntaxError = true; if (SyntaxError == true) { Chat->send(source, CHAT_DIRECT, "Usage", "@setmainskill <1-5> <1-255> [<charID or nickname>]"); Chat->send(source, CHAT_DIRECT, "Usage", "1:STR 2:DEX 3:CON 4:INT 5:PSI"); return; } PClient *temp_target = NULL; if ( ArgC == 3 ) { if (IsArgNumeric(3) == true) { temp_target = GetClientByID(GetArgInt(3)); } else { char tmp_destNick[50]; GetArgText(3, tmp_destNick, 50); temp_target = GetClientByNick(tmp_destNick); } if (temp_target == NULL) { Chat->send(source, CHAT_DIRECT, "System", "No such player"); return; } } else temp_target = source; // Now setting player's Skill tMainSkill to tNewLevel u8 tOldLevel = 0; u16 tNewSkillPoints = 0; int tLevelDiff = 0; // Grab old Level tOldLevel = temp_target->GetChar()->Skill->GetMainSkill(tMainSkill); tLevelDiff = tNewLevel - tOldLevel; if ( tLevelDiff == 0 ) { Chat->send(source, CHAT_DIRECT, "System", "Not setting anything. No difference at all"); return; } else if ( tLevelDiff > 0 ) // INCreasing mainskill { tNewSkillPoints = tLevelDiff*5; temp_target->GetChar()->Skill->SetSP(tMainSkill, tNewSkillPoints); } else if ( tLevelDiff < 0 ) // DECreasing mainskill { // Set all subskills to zero, and add tNewLevel*5 skillpoints temp_target->GetChar()->Skill->ZeroMSSubSkills(tMainSkill); temp_target->GetChar()->Skill->SetSP(tMainSkill, tNewLevel*5); tNewSkillPoints = 0; // Not perfect, player has to rezone for the correct values. Need a way to do massupdate subskills... // But on the other side, its not very common to DEcrease someone's skills, isnt it? } temp_target->GetChar()->Skill->SetMainSkill(tMainSkill, tNewLevel); char tmp[50]; snprintf(tmp, 50, "Setting Level to %d", tNewLevel); Chat->send(source, CHAT_DIRECT, "System", tmp); //PMessage* PMsgBuilder::BuildLevelUpMessage( PClient* nClient, u8 nMainSkill, u8 nNewLevel, u16 nFreeSkillPoints) PMessage* tmpMsg_setLv = MsgBuilder->BuildLevelUpMessage(temp_target, tMainSkill, tNewLevel, tNewSkillPoints); temp_target->SendUDPMessage(tmpMsg_setLv); tmpMsg_setLv = NULL; temp_target = NULL; }