void CBaseSplitterOutputPin::MakeISCRHappy() { CComPtr<IPin> pPinTo = this, pTmp; while (pPinTo && SUCCEEDED(pPinTo->ConnectedTo(&pTmp)) && (pPinTo = pTmp)) { pTmp = nullptr; CComPtr<IBaseFilter> pBF = GetFilterFromPin(pPinTo); if (GetCLSID(pBF) == GUIDFromCString(_T("{48025243-2D39-11CE-875D-00608CB78066}"))) { // ISCR CAutoPtr<Packet> p(DEBUG_NEW Packet()); p->TrackNumber = DWORD_ERROR; p->rtStart = -1; p->rtStop = 0; p->bSyncPoint = FALSE; p->SetData(" ", 2); QueuePacket(p); break; } pPinTo = GetFirstPin(pBF, PINDIR_OUTPUT); } }
void SendForumCategories(vector<ForumCategory*>& categories, BaseSocket* pRouter, FCSOCKET clientSocket) { PEPacket* pkt = new PEPacket; __FCPKT_FORUM_GET_CATEGORIES_RESP* d = NULL; size_t catCount = categories.size(), index = 0; size_t pktLen = sizeof(__FCPKT_FORUM_GET_CATEGORIES_RESP) + ( (catCount-1) * sizeof(__FCPKT_FORUM_GET_CATEGORIES_RESP::category_info)); d = (__FCPKT_FORUM_GET_CATEGORIES_RESP*) new FCBYTE[ pktLen ]; memset(d, 0, pktLen); d->category_count = (FCSHORT)catCount; ForumCategory* pCat = NULL; vector<ForumCategory*>::iterator it = categories.begin(); while ( it != categories.end() ) { pCat = (*it); d->categories[index].category_id = pCat->GetID(); d->categories[index].parent_id = pCat->GetParentID(); d->categories[index].thread_count = (FCULONG)pCat->GetPostCount(); strncpy( d->categories[index].name, pCat->GetName().c_str(), sizeof(d->categories[index].name) ); strncpy( d->categories[index].desc, pCat->GetDescription().c_str(), sizeof(d->categories[index].desc) ); it++; index++; } // send the packet PEPacketHelper::CreatePacket(*pkt, FCPKT_RESPONSE, FCMSG_FORUM_GET_CATEGORIES, ST_None); PEPacketHelper::SetPacketData(*pkt, (void*)d, pktLen); // send notification to Client pkt->SetFieldValue("target", (void*)&clientSocket); QueuePacket(pkt, pRouter); // clear the data portion delete [] (FCBYTE*)d; }
void Client::SendLogServer() { EQApplicationPacket *outapp = new EQApplicationPacket(OP_LogServer, sizeof(LogServer_Struct)); LogServer_Struct *l=(LogServer_Struct *)outapp->pBuffer; const char *wsn=WorldConfig::get()->ShortName.c_str(); memcpy(l->worldshortname,wsn,strlen(wsn)); if(RuleB(Mail, EnableMailSystem)) l->enablemail = 1; if(RuleB(Chat, EnableVoiceMacros)) l->enablevoicemacros = 1; l->enable_pvp = (RuleI(World, PVPSettings)); if(RuleB(World, IsGMPetitionWindowEnabled)) l->enable_petition_wnd = 1; if(RuleI(World, FVNoDropFlag) == 1 || RuleI(World, FVNoDropFlag) == 2 && GetAdmin() > RuleI(Character, MinStatusForNoDropExemptions)) l->enable_FV = 1; QueuePacket(outapp); safe_delete(outapp); }
void Client::SendAlternateAdvancementPoints() { auto outapp = new EQApplicationPacket(OP_RespondAA, sizeof(AATable_Struct)); AATable_Struct* aa2 = (AATable_Struct *)outapp->pBuffer; int i = 0; for(auto &aa : zone->aa_abilities) { uint32 charges = 0; auto ranks = GetAA(aa.second->first_rank_id, &charges); if(ranks) { AA::Rank *rank = aa.second->GetRankByPointsSpent(ranks); if(rank) { aa2->aa_list[i].AA = rank->id; aa2->aa_list[i].value = rank->total_cost; aa2->aa_list[i].charges = charges; i++; } } } aa2->aa_spent = GetSpentAA(); QueuePacket(outapp); safe_delete(outapp); }
/// Update the WorldSession (triggered by World update) bool WorldSession::Update(uint32 diff, PacketFilter& updater) { /// Update Timeout timer. UpdateTimeOutTime(diff); ///- Before we process anything: /// If necessary, kick the player from the character select screen if (IsConnectionIdle()) m_Socket->CloseSocket(); ///- Retrieve packets from the receive queue and call the appropriate handlers /// not process packets if socket already closed WorldPacket* packet = NULL; //! Delete packet after processing by default bool deletePacket = true; //! To prevent infinite loop WorldPacket* firstDelayedPacket = NULL; //! If _recvQueue.peek() == firstDelayedPacket it means that in this Update call, we've processed all //! *properly timed* packets, and we're now at the part of the queue where we find //! delayed packets that were re-enqueued due to improper timing. To prevent an infinite //! loop caused by re-enqueueing the same packets over and over again, we stop updating this session //! and continue updating others. The re-enqueued packets will be handled in the next Update call for this session. //uint32 processedPackets = 0; uint32 msTime = getMSTime(); uint32 currentMSTime = msTime; //bool output = false; std::list<std::pair<uint32, uint32> > processedOpcodes; while (m_Socket && !m_Socket->IsClosed() && !_recvQueue.empty() && _recvQueue.peek(true) != firstDelayedPacket && _recvQueue.next(packet, updater)) { sLog->outDebug(LOG_FILTER_NETWORKIO, "SESSION: IN opcode %s (0x%.4X)", LookupOpcodeName(packet->GetOpcode()), packet->GetOpcode()); if (packet->GetOpcode() >= NUM_MSG_TYPES) { sLog->outError("SESSION: received non-existed opcode %s (0x%.4X)", LookupOpcodeName(packet->GetOpcode()), packet->GetOpcode()); sScriptMgr->OnUnknownPacketReceive(m_Socket, WorldPacket(*packet)); } else { OpcodeHandler &opHandle = opcodeTable[packet->GetOpcode()]; try { switch (opHandle.status) { case STATUS_LOGGEDIN: if (!_player) { // skip STATUS_LOGGEDIN opcode unexpected errors if player logout sometime ago - this can be network lag delayed packets //! If player didn't log out a while ago, it means packets are being sent while the server does not recognize //! the client to be in world yet. We will re-add the packets to the bottom of the queue and process them later. if (!m_playerRecentlyLogout) { //! Prevent infinite loop if (!firstDelayedPacket) firstDelayedPacket = packet; //! Because checking a bool is faster than reallocating memory deletePacket = false; QueuePacket(packet); //! Log sLog->outDebug(LOG_FILTER_NETWORKIO, "Re-enqueueing packet with opcode %s (0x%.4X) with with status STATUS_LOGGEDIN. " "Player is currently not in world yet.", opHandle.name, packet->GetOpcode()); } } else if (_player->IsInWorld()) { sScriptMgr->OnPacketReceive(m_Socket, WorldPacket(*packet)); (this->*opHandle.handler)(*packet); if (sLog->IsOutDebug() && packet->rpos() < packet->wpos()) LogUnprocessedTail(packet); } // lag can cause STATUS_LOGGEDIN opcodes to arrive after the player started a transfer break; case STATUS_LOGGEDIN_OR_RECENTLY_LOGGOUT: if (!_player && !m_playerRecentlyLogout && !m_playerLogout) // There's a short delay between _player = null and m_playerRecentlyLogout = true during logout LogUnexpectedOpcode(packet, "STATUS_LOGGEDIN_OR_RECENTLY_LOGGOUT", "the player has not logged in yet and not recently logout"); else { // not expected _player or must checked in packet handler sScriptMgr->OnPacketReceive(m_Socket, WorldPacket(*packet)); (this->*opHandle.handler)(*packet); if (sLog->IsOutDebug() && packet->rpos() < packet->wpos()) LogUnprocessedTail(packet); } break; case STATUS_TRANSFER: if (!_player) LogUnexpectedOpcode(packet, "STATUS_TRANSFER", "the player has not logged in yet"); else if (_player->IsInWorld()) LogUnexpectedOpcode(packet, "STATUS_TRANSFER", "the player is still in world"); else { sScriptMgr->OnPacketReceive(m_Socket, WorldPacket(*packet)); (this->*opHandle.handler)(*packet); if (sLog->IsOutDebug() && packet->rpos() < packet->wpos()) LogUnprocessedTail(packet); } break; case STATUS_AUTHED: // prevent cheating with skip queue wait if (m_inQueue) { LogUnexpectedOpcode(packet, "STATUS_AUTHED", "the player not pass queue yet"); break; } // some auth opcodes can be recieved before STATUS_LOGGEDIN_OR_RECENTLY_LOGGOUT opcodes // however when we recieve CMSG_CHAR_ENUM we are surely no longer during the logout process. if (packet->GetOpcode() == CMSG_CHAR_ENUM) m_playerRecentlyLogout = false; sScriptMgr->OnPacketReceive(m_Socket, WorldPacket(*packet)); (this->*opHandle.handler)(*packet); if (sLog->IsOutDebug() && packet->rpos() < packet->wpos()) LogUnprocessedTail(packet); break; case STATUS_NEVER: sLog->outDebug(LOG_FILTER_NETWORKIO, "SESSION (account: %u, guidlow: %u, char: %s): received not allowed opcode %s (0x%.4X)", GetAccountId(), m_GUIDLow, _player ? _player->GetName() : "<none>", LookupOpcodeName(packet->GetOpcode()), packet->GetOpcode()); break; case STATUS_UNHANDLED: sLog->outDebug(LOG_FILTER_NETWORKIO, "SESSION (account: %u, guidlow: %u, char: %s): received not handled opcode %s (0x%.4X)", GetAccountId(), m_GUIDLow, _player ? _player->GetName() : "<none>", LookupOpcodeName(packet->GetOpcode()), packet->GetOpcode()); break; } } catch (ByteBufferException &) { sLog->outError("WorldSession::Update ByteBufferException occured while parsing a packet (opcode: %u) from client %s, accountid=%i. Skipped packet.", packet->GetOpcode(), GetRemoteAddress().c_str(), GetAccountId()); if (sLog->IsOutDebug()) { sLog->outDebug(LOG_FILTER_NETWORKIO, "Dumping error causing packet:"); packet->hexlike(); } } } uint32 temporary = getMSTime(); processedOpcodes.push_back(std::pair<uint32, uint32>(packet->GetOpcode(), getMSTimeDiff(currentMSTime, temporary))); if (deletePacket) delete packet; deletePacket = true; /*#define MAX_PROCESSED_PACKETS_IN_SAME_WORLDSESSION_UPDATE 50 processedPackets++; //process only a max amout of packets in 1 Update() call. //Any leftover will be processed in next update if (processedPackets > MAX_PROCESSED_PACKETS_IN_SAME_WORLDSESSION_UPDATE) { output = true; break; } #define MAX_PROCESS_MSTIME_IN_SAME_WORLDSESSION_UPDATE 5 currentMSTime = getMSTime(); if (getUSTimeDiff(msTime, currentMSTime) > MAX_PROCESS_MSTIME_IN_SAME_WORLDSESSION_UPDATE) { output = true; break; }*/ } /*if (output) { std::stringstream ss; ss << "Session: " << GetAccountId() << " Player: " << GetPlayerName(); std::list<std::pair<uint32, uint32> >::iterator itr = processedOpcodes.begin(); for (; itr != processedOpcodes.end(); ++itr) ss << " " << itr->first << "-" << itr->second << "ms"; sLog->outPerformance(ss.str().c_str()); }*/ ProcessQueryCallbacks(); if (_newNode) { if (Player *player = GetPlayer()) { if (player->IsSaveCommited()) { WorldPacket data(NODE_MISC_DATA); data << uint32(CL_DEF_TRANSFER_TO_NODE); data << _newNode; SendPacket(&data); _newNode = 0; } } } //check if we are safe to proceed with logout //logout procedure should happen only in World::UpdateSessions() method!!! if (updater.ProcessLogout()) { time_t currTime = time(NULL); ///- If necessary, log the player out if (ShouldLogOut(currTime) && !m_playerLoading) LogoutPlayer(true); ///- Cleanup socket pointer if need if (m_Socket && m_Socket->IsClosed()) { expireTime -= expireTime > diff ? diff : expireTime; if (expireTime < diff || forceExit) { m_Socket->RemoveReference(); m_Socket = NULL; } } if (!m_Socket) return false; //Will remove this session from the world session map } return true; }
void Client::ProcessOP_Beg(APPLAYER* pApp) { /* if(pApp->size != sizeof(Beg_Struct)) { cout << "Wrong size on OP_Beg. Got: " << pApp->size << ", Expected: " << sizeof(Beg_Struct) << endl; return; }*/ if(pApp->size = sizeof(Beg_Struct)) { Beg_Struct* beg_info = (Beg_Struct*)pApp->pBuffer; Message(BLACK,"Begging makes zone a sad panda :( (Our struct is wrong)"); beg_info->success = 0; QueuePacket(pApp); } else { //Yeahlight: Purge client's invisibility CancelAllInvisibility(); Beg_Struct* beg_info = (Beg_Struct*)pApp->pBuffer; Mob* target = entity_list.GetMob(beg_info->target); Mob* player = entity_list.GetMob(beg_info->begger); //Beg_Struct* beg_info = (Beg_Struct*)pApp->pBuffer; // Validate Player // Added this check to keep people from fudging packets to make // mobs attack other through begging. Flag as a hack also. if(this->GetID() != player->GetID()) { cout << "[ hack ]" << this->GetName() << " is begging for another player: "; cout << player->GetName() << endl; // This will make the client not able to beg anymore. // Could we send qa packet back with 'beg_info->success = 0? // Nah, I'd rather just leave the hackers with a broken client. -neorab return; } // Validate Time // Should not be able to send two beg requests within 10 seconds. // Flag beg spammers as hackers. Drop the packet and move on. int32 time_to_beg = beg_timer->GetRemainingTime(); if(time_to_beg != 0) { cout << "[ hack ]" << player->GetName() << " is begging to fast. "; cout << 10000 - time_to_beg << "ms since last beg." << endl; // This will make the client not able to beg anymore. return; } beg_timer->Start(10000); // Validate Target // Should not be able to beg from other players, corpses or pets. // Basiclly, the client will have to have the same thing targeted // as the packet says they do. If they target a pet and send a beg // packet with the pet as the target, this won't catch it. But it'll // stop the average dumbass forging packets. Mob* tmptar = this->GetTarget(); if((tmptar->GetID() != target->GetID()) || target->IsNPC() != true) { cout << "[ hack ]" << player->GetName() << " is begging from: " << target->GetName(); cout << "but has [" << tmptar->GetName() << "] targeted." << endl; // This will make the client not able to beg anymore. return; } // Validate Skill // Look the skill up, flag the account for hacks if they don't match. int8 beg_skill = this->GetSkill(BEGGING); if(beg_skill != beg_info->skill) { cout << "[ hack ]" << player->GetName() << " is trying to beg at " << beg_info->skill; cout << "but is [" << beg_skill << "] skill." << endl; // This will make the client not able to beg anymore. return; } // Pets. // You cannot succeed or crit fail on pets. if(target->CastToNPC()->GetOwner() == 0) { // Roll The Dice for Success // the threshold is the number you have to be under to have begged successfully // skill level / 8000 (0 - 4% liner based on skill) // + Charisma Modifier (same as skill level) * active charisma % (20% for ever 51 levels) double success_threshold = ((double)beg_skill / 8000) + (( (int)((double)beg_skill / 51) * 0.20) * ((double)player->GetCHA() / 8500)); double the_dice = MakeRandomFloat(0.000, 1.000); if(the_dice <= success_threshold) { char message[255]; sprintf(message, "%s says, \"Here %s, take this and LEAVE ME ALONE!\"", target->GetName(), player->GetName()); Message(WHITE, message); beg_info->success = 4; if(the_dice == success_threshold) { beg_info->coins = 2; } else { beg_info->coins = 1; } } // Critical Failure =) else { beg_info->success = 0; // Random Attack (5% @ 0skill 1% @ 200 skill) the_dice = MakeRandomFloat(0.000, 1.000); if(the_dice <= (0.05 - (int)((double)beg_skill / 50) * 0.01)) { char message[255]; sprintf(message, "%s says, \"Beggers like you always bring out the worst in me.\"", target->GetName()); target->CastToNPC()->AddToHateList(player); Message(DARK_RED, message); } } } // This is a pet, never allow them to succeed. else { beg_info->success = 0; } // Random Skill-Up // This was a bitch skill to learn. Let's do ~1/2% change to skill up. // I'm not using the CheckAddSkill function here because that does not // let us control it quite like this. I really don't believe every // skill uses the same formula. -neorab int dice = MakeRandomInt(0, 200); if(dice <= 1) { if(GetSkill(BEGGING) < CheckMaxSkill(BEGGING, this->race, this->class_, this->level)) { SetSkill(BEGGING, GetSkill(BEGGING)+1); } } // Save Player Profile // The return told the client they got more money, we should save that // server side to reflect the extra cash. if(beg_info->success != 0) { AddMoneyToPP(beg_info->coins, 0, 0, 0, false); } QueuePacket(pApp); } }
void CGameServerPlayer::ProcessScriptCommand(const PacketData& subPacket) { uint32 clientTime = *reinterpret_cast<const uint32*>(&subPacket[0x18]); uint32 sourceId = *reinterpret_cast<const uint32*>(&subPacket[0x20]); uint32 targetId = *reinterpret_cast<const uint32*>(&subPacket[0x24]); const char* commandName = reinterpret_cast<const char*>(subPacket.data()) + 0x31; CLog::GetInstance().LogDebug(LOG_NAME, "ProcessScriptCommand: %s Source Id = 0x%0.8X, Target Id = 0x%0.8X.", commandName, sourceId, targetId); auto playerActor = m_instance.GetActor<CPlayerActor>(PLAYER_ID); if(playerActor == nullptr) { CLog::GetInstance().LogError(LOG_NAME, "Failed to get player actor."); return; } if(!strcmp(commandName, "commandRequest")) { //commandRequest (emote, changing equipment, ...) playerActor->ProcessCommandRequest(targetId, subPacket); } else if(!strcmp(commandName, "commandContent")) { switch(targetId) { case 0xA0F05E9B: //Quit CLog::GetInstance().LogDebug(LOG_NAME, "Quit."); m_disconnect = true; break; case 0xA0F05E9C: //Teleport CLog::GetInstance().LogDebug(LOG_NAME, "Teleport."); m_disconnect = true; break; } } else if(!strcmp(commandName, "commandForced")) { playerActor->ProcessCommandForced(targetId); } else if(!strcmp(commandName, "commandDefault")) { playerActor->ProcessCommandDefault(targetId); } else if(!strcmp(commandName, "talkDefault")) { switch(targetId) { case 0x47A00007: //Talking to the door inside the room { static const uint8 commandRequestPacket[] = { 0x01, 0x00, 0x00, 0x00, 0xC0, 0x00, 0x01, 0x00, 0x52, 0xE2, 0xA4, 0xEE, 0x3B, 0x01, 0x00, 0x00, 0xb0, 0x00, 0x03, 0x00, 0x41, 0x29, 0x9b, 0x02, 0x41, 0x29, 0x9b, 0x02, 0x00, 0xe0, 0xd2, 0xfe, 0x14, 0x00, 0x30, 0x01, 0x00, 0x00, 0x00, 0x00, 0xd3, 0xe9, 0xe0, 0x50, 0x00, 0x00, 0x00, 0x00, 0x41, 0x29, 0x9b, 0x02, 0x07, 0x00, 0xa0, 0x47, 0x01, 0x74, 0x61, 0x6c, 0x6b, 0x44, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x64, 0x65, 0x6c, 0x65, 0x67, 0x61, 0x74, 0x65, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x02, 0x9b, 0x29, 0x41, 0x06, 0xa0, 0xf1, 0xaf, 0xcd, 0x02, 0x64, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x54, 0x61, 0x6c, 0x6b, 0x57, 0x69, 0x74, 0x68, 0x49, 0x6e, 0x6e, 0x5f, 0x45, 0x78, 0x69, 0x74, 0x44, 0x6f, 0x6f, 0x72, 0x00, 0x05, 0x05, 0x05, 0x05, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x62, 0xe8, 0x4e, 0x40, 0x00, 0x00, 0x00, }; QueuePacket(PacketData(std::begin(commandRequestPacket), std::end(commandRequestPacket))); } break; default: #if 0 //Talking Test (doesn't work) { static const uint8 commandRequestPacket[] = { 0x01, 0x01, 0x00, 0x00, 0xC0, 0x00, 0x01, 0x00, 0xD2, 0x16, 0x9E, 0xEE, 0x3B, 0x01, 0x00, 0x00, 0xB0, 0x00, 0x03, 0x00, 0x41, 0x29, 0x9B, 0x02, 0x41, 0x29, 0x9B, 0x02, 0x00, 0xE0, 0xD2, 0xFE, 0x14, 0x00, 0x30, 0x01, 0x00, 0x00, 0x00, 0x00, 0x14, 0xED, 0xE0, 0x50, 0x00, 0x00, 0x00, 0x00, 0x41, 0x29, 0x9B, 0x02, 0x82, 0x00, 0x70, 0x46, 0x01, 0x74, 0x61, 0x6C, 0x6B, 0x44, 0x65, 0x66, 0x61, 0x75, 0x6C, 0x74, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x73, 0x77, 0x69, 0x74, 0x63, 0x68, 0x45, 0x76, 0x65, 0x6E, 0x74, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0xA0, 0xF1, 0xAF, 0xCD, 0x06, 0xA0, 0xF1, 0xB4, 0x00, 0x05, 0x05, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x03, 0xF1, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x6C, 0xB8, 0x45, 0x40, 0x00, 0x00, 0x00, }; QueuePacket(PacketData(std::begin(commandRequestPacket), std::end(commandRequestPacket))); } #endif m_disconnect = true; break; } } else { //Anything else will probably crash, so just bail m_disconnect = true; } }
bool Client::UseDiscipline(uint32 spell_id, uint32 target) { // Dont let client waste a reuse timer if they can't use the disc if (IsStunned() || IsFeared() || IsMezzed() || IsAmnesiad() || IsPet()) { return(false); } //make sure we have the spell... int r; for(r = 0; r < MAX_PP_DISCIPLINES; r++) { if(m_pp.disciplines.values[r] == spell_id) break; } if(r == MAX_PP_DISCIPLINES) return(false); //not found. //Check the disc timer pTimerType DiscTimer = pTimerDisciplineReuseStart + spells[spell_id].EndurTimerIndex; if(!p_timers.Expired(&database, DiscTimer)) { /*char val1[20]={0};*/ //unused /*char val2[20]={0};*/ //unused uint32 remain = p_timers.GetRemainingTime(DiscTimer); //Message_StringID(0, DISCIPLINE_CANUSEIN, ConvertArray((remain)/60,val1), ConvertArray(remain%60,val2)); Message(0, "You can use this discipline in %d minutes %d seconds.", ((remain)/60), (remain%60)); return(false); } //make sure we can use it.. if(!IsValidSpell(spell_id)) { Message(13, "This tome contains invalid knowledge."); return(false); } //can we use the spell? const SPDat_Spell_Struct &spell = spells[spell_id]; uint8 level_to_use = spell.classes[GetClass() - 1]; if(level_to_use == 255) { Message(13, "Your class cannot learn from this tome."); //should summon them a new one... return(false); } if(level_to_use > GetLevel()) { Message_StringID(13, DISC_LEVEL_USE_ERROR); //should summon them a new one... return(false); } if(GetEndurance() > spell.EndurCost) { SetEndurance(GetEndurance() - spell.EndurCost); } else { Message(11, "You are too fatigued to use this skill right now."); return(false); } if(spell.recast_time > 0) { uint32 reduced_recast = spell.recast_time / 1000; reduced_recast -= CastToClient()->GetFocusEffect(focusReduceRecastTime, spell_id); if(reduced_recast < 0) reduced_recast = 0; CastSpell(spell_id, target, DISCIPLINE_SPELL_SLOT, -1, -1, 0, -1, (uint32)DiscTimer, reduced_recast); if(spells[spell_id].EndurTimerIndex < MAX_DISCIPLINE_TIMERS) { EQApplicationPacket *outapp = new EQApplicationPacket(OP_DisciplineTimer, sizeof(DisciplineTimer_Struct)); DisciplineTimer_Struct *dts = (DisciplineTimer_Struct *)outapp->pBuffer; dts->TimerID = spells[spell_id].EndurTimerIndex; dts->Duration = reduced_recast; QueuePacket(outapp); safe_delete(outapp); } } else { CastSpell(spell_id, target, DISCIPLINE_SPELL_SLOT); } return(true); }
void TestCaseDeviceSetRegister() { struct TransactionLayerPacket *PacketQueueStore; int DeviceInitRetryCounter; int PacketWasAccepted; //init the device if( HostState.DeviceFinishedInitialize != 1 || HostState.DeviceFinishedEnum != 1 ) TestCaseDeviceInit(); //read configs if( DeviceState.DeviceLinkTranSettingReg.Fields.MAX_BLK_LEN == 0 || DeviceState.DeviceLinkTranSettingReg.Fields.N_FCU == 0 ) TestCaseDeviceCapabilities(); ///////////////////////////////////////// // Write the value of CFG Reg MAX_BLKLEN to determine block length - page 164 - begin ///////////////////////////////////////// //get a packet store from queue PacketQueueStore = GetPacketQueueStore(); // can be used to ensure we are reading a packet that we were waiting the reply for. Can be used for async communication InitNewHostDeviceTransaction(); //build packet to be sent { u_CFG_LINK_TRAN_REG RegValue; EmbededMemCpy( RegValue.DataC, DeviceState.DeviceLinkTranReg.DataC, sizeof( DeviceState.DeviceLinkTranReg.DataC ) ); RegValue.Fields.MaxBlkLen = 64; //test value ! Change it later BuildPcktCCMDDeviceSetReg( PacketQueueStore->Packet, &PacketQueueStore->PacketSize, RA_Configuration + RA_CFG_GENERIC_SETTINGS, DeviceState.DeviceLinkTranReg.DataC ); } //queue the packet to be sent to the device PacketQueueStore->SendCount = 0; DeviceInitRetryCounter = 0; PacketWasAccepted = 0; while( PacketWasAccepted == 0 && DeviceInitRetryCounter < MAX_PACKET_RESEND_ON_NO_REPLY ) { // queue the packet to be sent. Could be an async implementation in the future PacketQueueStore->SendCount++; QueuePacket( PacketQueueStore ); //non async implementation of data send SendPacketToDevice( PacketQueueStore ); //wait for device reply WaitDevicePacketReply( PacketQueueStore ); // after MAX_PACKET_RESEND_ON_NO_REPLY send tries Host needs to treat init configuration as BAD ParsePcktCCMDDeviceRegisterSet( PacketQueueStore, RA_Configuration + RA_CFG_GENERIC_SETTINGS ); DeviceInitRetryCounter++; } if( DeviceInitRetryCounter >= MAX_PACKET_RESEND_ON_NO_REPLY ) assert( 0 ); ///////////////////////////////////////// // Write the value of CFG Reg MAX_BLKLEN to determine block length - page 164 - end ///////////////////////////////////////// ///////////////////////////////////////// // Read the value of CFG Reg MAX_BLKLEN to determine block length - page 164 - begin ///////////////////////////////////////// //get a packet store from queue PacketQueueStore = GetPacketQueueStore(); // can be used to ensure we are reading a packet that we were waiting the reply for. Can be used for async communication InitNewHostDeviceTransaction(); //build packet to be sent BuildPcktCCMDDeviceQueryReg( PacketQueueStore->Packet, &PacketQueueStore->PacketSize, RA_Configuration + RA_CFG_LINK_TRAN ); //queue the packet to be sent to the device PacketQueueStore->SendCount = 0; DeviceInitRetryCounter = 0; PacketWasAccepted = 0; while( PacketWasAccepted == 0 && DeviceInitRetryCounter < MAX_PACKET_RESEND_ON_NO_REPLY ) { // queue the packet to be sent. Could be an async implementation in the future PacketQueueStore->SendCount++; QueuePacket( PacketQueueStore ); //non async implementation of data send SendPacketToDevice( PacketQueueStore ); //wait for device reply WaitDevicePacketReply( PacketQueueStore ); // after MAX_PACKET_RESEND_ON_NO_REPLY send tries Host needs to treat init configuration as BAD PacketWasAccepted = ParsePcktCCMDDeviceRegisterQuery( PacketQueueStore, RA_Configuration + RA_CFG_LINK_TRAN ); DeviceInitRetryCounter++; } if( DeviceInitRetryCounter >= MAX_PACKET_RESEND_ON_NO_REPLY ) assert( 0 ); ///////////////////////////////////////// // Read the value of CFG Reg MAX_BLKLEN to determine block length - page 164 - end ///////////////////////////////////////// }
// @merth: I have no idea what this struct is for, so it's hardcoded for now void Client::SendApproveWorld() { EQApplicationPacket* outapp; // Send OPCode: OP_ApproveWorld, size: 544 outapp = new EQApplicationPacket(OP_ApproveWorld, sizeof(ApproveWorld_Struct)); ApproveWorld_Struct* aw = (ApproveWorld_Struct*)outapp->pBuffer; uchar foo[] = { //0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x95,0x5E,0x30,0xA5,0xCA,0xD4,0xEA,0xF5, //0xCB,0x14,0xFC,0xF7,0x78,0xE2,0x73,0x15,0x90,0x17,0xCE,0x7A,0xEB,0xEC,0x3C,0x34, //0x5C,0x6D,0x10,0x05,0xFC,0xEA,0xED,0x19,0xC5,0x0D,0x7A,0x82,0x17,0xCC,0xCC,0x71, //0x56,0x38,0xDF,0x78,0x8D,0xE6,0x44,0xD3,0x6F,0xDB,0xE3,0xCF,0x21,0x30,0x75,0x2F, //0xCD,0xDC,0xE9,0xB4,0xA4,0x4E,0x58,0xDE,0xEE,0x54,0xDD,0x87,0xDA,0xE9,0xC6,0xC8, //0x02,0xDD,0xC4,0xFD,0x94,0x36,0x32,0xAD,0x1B,0x39,0x0F,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x37,0x87,0x13,0xbe,0xc8,0xa7,0x77,0xcb, 0x27,0xed,0xe1,0xe6,0x5d,0x1c,0xaa,0xd3,0x3c,0x26,0x3b,0x6d,0x8c,0xdb,0x36,0x8d, 0x91,0x72,0xf5,0xbb,0xe0,0x5c,0x50,0x6f,0x09,0x6d,0xc9,0x1e,0xe7,0x2e,0xf4,0x38, 0x1b,0x5e,0xa8,0xc2,0xfe,0xb4,0x18,0x4a,0xf7,0x72,0x85,0x13,0xf5,0x63,0x6c,0x16, 0x69,0xf4,0xe0,0x17,0xff,0x87,0x11,0xf3,0x2b,0xb7,0x73,0x04,0x37,0xca,0xd5,0x77, 0xf8,0x03,0x20,0x0a,0x56,0x8b,0xfb,0x35,0xff,0x59,0x00,0x00,0x00,0x00,0x00,0x00, //0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x1f,0x42,0x69,0x2a,0x87,0xdd,0x04,0x3d, //0x7f,0xb1,0xb3,0xbb,0xde,0xd5,0x5f,0xfc,0x1f,0xb3,0x25,0x94,0x16,0xd5,0xf3,0x97, //0x43,0xdf,0xb9,0x69,0x68,0xdf,0x2b,0x64,0x98,0xf5,0x44,0xbe,0x38,0x65,0xef,0xff, //0x36,0x89,0x90,0xcf,0x26,0xbb,0x9f,0x76,0xd5,0xaf,0x6d,0xf2,0x08,0xbe,0xce,0xd8, //0x3e,0x4b,0x53,0x8a,0xf3,0x44,0x7c,0x19,0x49,0x5d,0x97,0x99,0xd8,0x8b,0xee,0x10, //0x1a,0x7d,0xb7,0x8b,0x49,0x9b,0x40,0x8c,0xea,0x49,0x09,0x00,0x00,0x00,0x00,0x00, // 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x15,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x53,0xC3,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x00 }; memcpy(aw->unknown544, foo, sizeof(foo)); QueuePacket(outapp); safe_delete(outapp); }
HRESULT CBaseSplitterOutputPin::QueueEndOfStream() { return QueuePacket(CAutoPtr<Packet>()); // NULL means EndOfStream }
void Client::SetLevel(uint8 set_level, bool command) { if (GetEXPForLevel(set_level) == 0xFFFFFFFF) { Log.Out(Logs::General, Logs::Error, "Client::SetLevel() GetEXPForLevel(%i) = 0xFFFFFFFF", set_level); return; } EQApplicationPacket* outapp = new EQApplicationPacket(OP_LevelUpdate, sizeof(LevelUpdate_Struct)); LevelUpdate_Struct* lu = (LevelUpdate_Struct*)outapp->pBuffer; lu->level = set_level; if(m_pp.level2 != 0) lu->level_old = m_pp.level2; else lu->level_old = level; level = set_level; if(IsRaidGrouped()) { Raid *r = this->GetRaid(); if(r){ r->UpdateLevel(GetName(), set_level); } } if(set_level > m_pp.level2) { if(m_pp.level2 == 0) m_pp.points += 5; else m_pp.points += (5 * (set_level - m_pp.level2)); m_pp.level2 = set_level; } if(set_level > m_pp.level) { parse->EventPlayer(EVENT_LEVEL_UP, this, "", 0); /* QS: PlayerLogLevels */ if (RuleB(QueryServ, PlayerLogLevels)){ std::string event_desc = StringFormat("Leveled UP :: to Level:%i from Level:%i in zoneid:%i instid:%i", set_level, m_pp.level, this->GetZoneID(), this->GetInstanceID()); QServ->PlayerLogEvent(Player_Log_Levels, this->CharacterID(), event_desc); } } else if (set_level < m_pp.level){ /* QS: PlayerLogLevels */ if (RuleB(QueryServ, PlayerLogLevels)){ std::string event_desc = StringFormat("Leveled DOWN :: to Level:%i from Level:%i in zoneid:%i instid:%i", set_level, m_pp.level, this->GetZoneID(), this->GetInstanceID()); QServ->PlayerLogEvent(Player_Log_Levels, this->CharacterID(), event_desc); } } m_pp.level = set_level; if (command){ m_pp.exp = GetEXPForLevel(set_level); Message(CC_Yellow, "Welcome to level %i!", set_level); lu->exp = 0; } else { float tmpxp = (float) ( (float) m_pp.exp - GetEXPForLevel( GetLevel() )) / ( (float) GetEXPForLevel(GetLevel()+1) - GetEXPForLevel(GetLevel())); lu->exp = (uint32)(330.0f * tmpxp); } QueuePacket(outapp); safe_delete(outapp); this->SendAppearancePacket(AT_WhoLevel, set_level); // who level change Log.Out(Logs::General, Logs::Normal, "Setting Level for %s to %i", GetName(), set_level); CalcBonuses(); if(!RuleB(Character, HealOnLevel)) { int mhp = CalcMaxHP(); if(GetHP() > mhp) SetHP(mhp); } else { SetHP(CalcMaxHP()); // Why not, lets give them a free heal } if(!RuleB(Character, ManaOnLevel)) { int mp = CalcMaxMana(); if(GetMana() > mp) SetMana(mp); } else { SetMana(CalcMaxMana()); // Why not, lets give them a free heal } SendHPUpdate(); SendManaUpdate(); UpdateWho(); Save(); }
void Client::SendAlternateAdvancementRank(int aa_id, int level) { if(!zone) return; auto ability_rank = zone->GetAlternateAdvancementAbilityAndRank(aa_id, level); auto ability = ability_rank.first; auto rank = ability_rank.second; if(!ability) { return; } if(!(ability->classes & (1 << GetClass()))) { return; } if(!CanUseAlternateAdvancementRank(rank)) { return; } int size = sizeof(AARankInfo_Struct) + (sizeof(AARankEffect_Struct) * rank->effects.size()) + (sizeof(AARankPrereq_Struct) * rank->prereqs.size()); auto outapp = new EQApplicationPacket(OP_SendAATable, size); AARankInfo_Struct *aai = (AARankInfo_Struct*)outapp->pBuffer; aai->id = rank->id; aai->upper_hotkey_sid = rank->upper_hotkey_sid; aai->lower_hotkey_sid = rank->lower_hotkey_sid; aai->title_sid = rank->title_sid; aai->desc_sid = rank->desc_sid; aai->cost = rank->cost; aai->seq = aa_id; aai->type = ability->type; aai->spell = rank->spell; aai->spell_type = rank->spell_type; aai->spell_refresh = rank->recast_time; aai->classes = ability->classes; aai->level_req = rank->level_req; aai->current_level = level; aai->max_level = ability->GetMaxLevel(this); aai->prev_id = rank->prev_id; if((rank->next && !CanUseAlternateAdvancementRank(rank->next)) || ability->charges > 0) { aai->next_id = -1; } else { aai->next_id = rank->next_id; } aai->total_cost = rank->total_cost; aai->expansion = rank->expansion; aai->category = ability->category; aai->charges = ability->charges; aai->grant_only = ability->grant_only; aai->total_effects = rank->effects.size(); aai->total_prereqs = rank->prereqs.size(); outapp->SetWritePosition(sizeof(AARankInfo_Struct)); for(auto &effect : rank->effects) { outapp->WriteSInt32(effect.effect_id); outapp->WriteSInt32(effect.base1); outapp->WriteSInt32(effect.base2); outapp->WriteSInt32(effect.slot); } for(auto &prereq : rank->prereqs) { outapp->WriteSInt32(prereq.first); outapp->WriteSInt32(prereq.second); } QueuePacket(outapp); safe_delete(outapp); }
HRESULT CLAVOutputPin::QueueEndOfStream() { return QueuePacket(NULL); // NULL means EndOfStream }
HRESULT CLAVOutputPin::QueueEndOfStream() { return QueuePacket(nullptr); // nullptr means EndOfStream }
/// Update the WorldSession (triggered by World update) bool WorldSession::Update(uint32 diff, PacketFilter& updater) { /// Update Timeout timer. UpdateTimeOutTime(diff); ///- Before we process anything: /// If necessary, kick the player from the character select screen if (IsConnectionIdle()) m_Socket->CloseSocket(); const uint32 opcodeMinTime = 50; uint32 opcodeStartTime; uint32 opcodeProcessTime; ///- Retrieve packets from the receive queue and call the appropriate handlers /// not process packets if socket already closed WorldPacket* packet = NULL; //! Delete packet after processing by default bool deletePacket = true; //! To prevent infinite loop WorldPacket* firstDelayedPacket = NULL; //! If _recvQueue.peek() == firstDelayedPacket it means that in this Update call, we've processed all //! *properly timed* packets, and we're now at the part of the queue where we find //! delayed packets that were re-enqueued due to improper timing. To prevent an infinite //! loop caused by re-enqueueing the same packets over and over again, we stop updating this session //! and continue updating others. The re-enqueued packets will be handled in the next Update call for this session. while (m_Socket && !m_Socket->IsClosed() && !_recvQueue.empty() && _recvQueue.peek(true) != firstDelayedPacket && _recvQueue.next(packet, updater)) { opcodeStartTime = getMSTime(); OpcodeHandler const* opHandle = opcodeTable[packet->GetOpcode()]; try { switch (opHandle->Status) { case STATUS_LOGGEDIN: if (!_player) { // skip STATUS_LOGGEDIN opcode unexpected errors if player logout sometime ago - this can be network lag delayed packets //! If player didn't log out a while ago, it means packets are being sent while the server does not recognize //! the client to be in world yet. We will re-add the packets to the bottom of the queue and process them later. if (!m_playerRecentlyLogout) { //! Prevent infinite loop if (!firstDelayedPacket) firstDelayedPacket = packet; //! Because checking a bool is faster than reallocating memory deletePacket = false; QueuePacket(packet); //! Log sLog->outDebug(LOG_FILTER_NETWORKIO, "Re-enqueueing packet with opcode %s with with status STATUS_LOGGEDIN. " "Player is currently not in world yet.", GetOpcodeNameForLogging(packet->GetOpcode()).c_str()); } } else if (_player->IsInWorld()) { sScriptMgr->OnPacketReceive(m_Socket, WorldPacket(*packet)); (this->*opHandle->Handler)(*packet); LogUnprocessedTail(packet); } // lag can cause STATUS_LOGGEDIN opcodes to arrive after the player started a transfer break; case STATUS_LOGGEDIN_OR_RECENTLY_LOGGOUT: if (!_player && !m_playerRecentlyLogout && !m_playerLogout) // There's a short delay between _player = null and m_playerRecentlyLogout = true during logout LogUnexpectedOpcode(packet, "STATUS_LOGGEDIN_OR_RECENTLY_LOGGOUT", "the player has not logged in yet and not recently logout"); else { // not expected _player or must checked in packet hanlder sScriptMgr->OnPacketReceive(m_Socket, WorldPacket(*packet)); (this->*opHandle->Handler)(*packet); LogUnprocessedTail(packet); } break; case STATUS_TRANSFER: if (!_player) LogUnexpectedOpcode(packet, "STATUS_TRANSFER", "the player has not logged in yet"); else if (_player->IsInWorld()) LogUnexpectedOpcode(packet, "STATUS_TRANSFER", "the player is still in world"); else { sScriptMgr->OnPacketReceive(m_Socket, WorldPacket(*packet)); (this->*opHandle->Handler)(*packet); LogUnprocessedTail(packet); } break; case STATUS_AUTHED: // prevent cheating with skip queue wait if (m_inQueue) { LogUnexpectedOpcode(packet, "STATUS_AUTHED", "the player not pass queue yet"); break; } // some auth opcodes can be recieved before STATUS_LOGGEDIN_OR_RECENTLY_LOGGOUT opcodes // however when we recieve CMSG_CHAR_ENUM we are surely no longer during the logout process. if (packet->GetOpcode() == CMSG_CHAR_ENUM) m_playerRecentlyLogout = false; sScriptMgr->OnPacketReceive(m_Socket, WorldPacket(*packet)); (this->*opHandle->Handler)(*packet); LogUnprocessedTail(packet); break; case STATUS_NEVER: sLog->outError(LOG_FILTER_OPCODES, "Received not allowed opcode %s from %s", GetOpcodeNameForLogging(packet->GetOpcode()).c_str(), GetPlayerInfo().c_str()); break; case STATUS_UNHANDLED: sLog->outInfo(LOG_FILTER_BAD_OPCODE_HANDLER, "STATUS_UNHANDLED: %s (len: %u)", GetOpcodeNameForLogging(packet->GetOpcode()).c_str(), packet->size()); sLog->outError(LOG_FILTER_OPCODES, "Received not handled opcode %s from %s", GetOpcodeNameForLogging(packet->GetOpcode()).c_str(), GetPlayerInfo().c_str()); break; } } catch(ByteBufferException &) { sLog->outInfo(LOG_FILTER_BAD_OPCODE_HANDLER, "EXCEPTION: %s (len: %u)", GetOpcodeNameForLogging(packet->GetOpcode()).c_str(), packet->size()); sLog->outError(LOG_FILTER_NETWORKIO, "WorldSession::Update ByteBufferException occured while parsing a packet (opcode: %u) from client %s, accountid=%i. Skipped packet.", packet->GetOpcode(), GetRemoteAddress().c_str(), GetAccountId()); packet->hexlike(); } opcodeProcessTime = GetMSTimeDiffToNow(opcodeStartTime); if (opcodeProcessTime >= opcodeMinTime) { PreparedStatement *stmt = WorldDatabase.GetPreparedStatement(WORLD_INS_SLOW_OPCODE); stmt->setUInt32(0, packet->GetOpcode()); stmt->setUInt32(1, opcodeProcessTime); WorldDatabase.Execute(stmt); } if (deletePacket) delete packet; } if (m_Socket && !m_Socket->IsClosed() && _warden) _warden->Update(); ProcessQueryCallbacks(); //check if we are safe to proceed with logout //logout procedure should happen only in World::UpdateSessions() method!!! if (updater.ProcessLogout()) { time_t currTime = time(NULL); ///- If necessary, log the player out if (ShouldLogOut(currTime) && !m_playerLoading) LogoutPlayer(true); if (m_Socket && GetPlayer() && _warden) _warden->Update(); ///- Cleanup socket pointer if need if (m_Socket && m_Socket->IsClosed()) { expireTime -= expireTime > diff ? diff : expireTime; if (expireTime < diff || forceExit) { m_Socket->RemoveReference(); m_Socket = NULL; } } if (!m_Socket) return false; //Will remove this session from the world session map } return true; }
bool Client::BindWound(Mob* bindtar,bool fail){ APPLAYER* bwout_app = new APPLAYER(OP_BindWound,sizeof(BindWound_Struct)); BindWound_Struct* bwout = (BindWound_Struct*)bwout_app->pBuffer; if(!fail){ if(GetFeigned()){ // Break Feign Death for Bind Wound SetFeigned(false); // } int cap = 50; // Set % Cap/Heal Cap int hp_cap = bindtar->GetMaxHP()/2; // if(GetClass() == MONK && GetSkill(BIND_WOUND) > 200){ // cap = 70; // hp_cap += bindtar->GetMaxHP()/5; // } if(!bindwound_timer->Enabled()){ // Begin Bind Wound if(bindtar->GetHP() >= hp_cap){ // INITIAL CAP CHECK Message(DARK_BLUE, "You cannot bandage your target past %d percent of their hit points.", cap); bwout->type = 3; // QueuePacket(bwout_app); // bwout->type = 2; // QueuePacket(bwout_app); // safe_delete(bwout_app); // return true; } int16 bndg_slot = FindItemTypeInInventory(ItemTypeBandage); // Consume Bandage RemoveOneCharge(bndg_slot,true); // bindwound_timer->Start(10000); // Start Timer bindwound_target = bindtar; bwout->type = 3; // Unlock Interface QueuePacket(bwout_app); // bwout->type = 0; // if(!bindtar){ // Target Dead bwout->type = 4; // QueuePacket(bwout_app); // bwout->type = 0; // bindwound_timer->Disable(); // bindwound_target = 0; // } else if(bindtar!=this) // Send Bind Message to target if not binding self bindtar->CastToClient()->Message(DARK_BLUE,"You are being bandaged. Stay relatively still."); } else{ // END Bind Wound bindwound_timer->Disable(); // Stop Timer bindwound_target = 0; if(!bindtar){ // Target Not Found bwout->type = 5; // QueuePacket(bwout_app); // bwout->type = 0; // } if((!GetFeigned() && bindtar->DistNoRoot(this->CastToMob()) <= 400)){ //// **** TAKEN FROM EQEMU, FD Check/Distance? bwout->type = 1; // Finish Bind QueuePacket(bwout_app); // bwout->type = 0; // if(this!=bindtar) // Message to target bindtar->CastToClient()->Message(YELLOW,"The bandaging is complete."); CheckAddSkill(BIND_WOUND); // Check Skill Up if(bindtar->GetHP() < hp_cap){ // END CAP CHECK (Does not include heal amount) int heal = 3; // Set Heal Amount if(GetSkill(BIND_WOUND) > 200) // // heal += GetSkill(BIND_WOUND)*4/10; // // else if(GetSkill(BIND_WOUND) >= 10) // // heal += GetSkill(BIND_WOUND)/4; // // bindtar->SetHP(bindtar->GetHP()+heal); // Set Hp + Update bindtar->SendHPUpdate(); // } else{ // Over Cap Message(DARK_BLUE, "You cannot bandage your target past %d percent of their hit points.", cap); if(this != bindtar) // bindtar->CastToClient()->Message(DARK_BLUE, "You cannot be bandaged past %d percent of your max hit points.",cap); } } else if(bindtar!=this){ // Failed Moved/Moved Away bwout->type = 6; // QueuePacket(bwout_app); // bwout->type = 0; // } else{ //Feigned/Out of Range and binding self Not sure if anything needs to go here or not } } } else if(bindwound_timer->Enabled()){ // Failed: Ended Via Sit/Stand/Feign if(!GetFeigned()){ // Sit/Stand bindwound_timer->Disable(); // bwout->type = 3; // QueuePacket(bwout_app); // bwout->type = 7; // QueuePacket(bwout_app); // } else{ bindwound_timer->Disable(); // Feign Death bindwound_target = 0; // Message(YELLOW,"You have moved and your attempt to bandage has failed."); } } safe_delete(bwout_app); // Delete packet return true; }
/// Update the WorldSession (triggered by World update) bool WorldSession::Update(uint32 diff, PacketFilter& updater) { /// Update Timeout timer. UpdateTimeOutTime(diff); ///- Before we process anything: /// If necessary, kick the player from the character select screen //Playerbot /* if (IsConnectionIdle()) m_Socket->CloseSocket(); */ ///- Retrieve packets from the receive queue and call the appropriate handlers /// not process packets if socket already closed WorldPacket* packet = NULL; //! Delete packet after processing by default bool deletePacket = true; //! To prevent infinite loop WorldPacket* firstDelayedPacket = NULL; //! If _recvQueue.peek() == firstDelayedPacket it means that in this Update call, we've processed all //! *properly timed* packets, and we're now at the part of the queue where we find //! delayed packets that were re-enqueued due to improper timing. To prevent an infinite //! loop caused by re-enqueueing the same packets over and over again, we stop updating this session //! and continue updating others. The re-enqueued packets will be handled in the next Update call for this session. while (m_Socket && !m_Socket->IsClosed() && !_recvQueue.empty() && _recvQueue.peek(true) != firstDelayedPacket && _recvQueue.next(packet, updater)) { if (packet->GetOpcode() >= NUM_MSG_TYPES) { sLog->outError(LOG_FILTER_OPCODES, "Received non-existed opcode %s from %s", GetOpcodeNameForLogging(packet->GetOpcode()).c_str() , GetPlayerInfo().c_str()); sScriptMgr->OnUnknownPacketReceive(m_Socket, WorldPacket(*packet)); } else { OpcodeHandler &opHandle = opcodeTable[packet->GetOpcode()]; try { switch (opHandle.status) { case STATUS_LOGGEDIN: if (!_player) { // skip STATUS_LOGGEDIN opcode unexpected errors if player logout sometime ago - this can be network lag delayed packets //! If player didn't log out a while ago, it means packets are being sent while the server does not recognize //! the client to be in world yet. We will re-add the packets to the bottom of the queue and process them later. if (!m_playerRecentlyLogout) { //! Prevent infinite loop if (!firstDelayedPacket) firstDelayedPacket = packet; //! Because checking a bool is faster than reallocating memory deletePacket = false; QueuePacket(packet); //! Log sLog->outDebug(LOG_FILTER_NETWORKIO, "Re-enqueueing packet with opcode %s with with status STATUS_LOGGEDIN. " "Player is currently not in world yet.", GetOpcodeNameForLogging(packet->GetOpcode()).c_str()); } } else if (_player->IsInWorld()) { sScriptMgr->OnPacketReceive(m_Socket, WorldPacket(*packet)); (this->*opHandle.handler)(*packet); LogUnprocessedTail(packet); } // lag can cause STATUS_LOGGEDIN opcodes to arrive after the player started a transfer //Playerbot mod if (_player && _player->GetPlayerbotMgr()) _player->GetPlayerbotMgr()->HandleMasterIncomingPacket(*packet); //End Playerbot mod break; case STATUS_LOGGEDIN_OR_RECENTLY_LOGGOUT: if (!_player && !m_playerRecentlyLogout && !m_playerLogout) // There's a short delay between _player = null and m_playerRecentlyLogout = true during logout LogUnexpectedOpcode(packet, "STATUS_LOGGEDIN_OR_RECENTLY_LOGGOUT", "the player has not logged in yet and not recently logout"); else { // not expected _player or must checked in packet handler sScriptMgr->OnPacketReceive(m_Socket, WorldPacket(*packet)); (this->*opHandle.handler)(*packet); LogUnprocessedTail(packet); } break; case STATUS_TRANSFER: if (!_player) LogUnexpectedOpcode(packet, "STATUS_TRANSFER", "the player has not logged in yet"); else if (_player->IsInWorld()) LogUnexpectedOpcode(packet, "STATUS_TRANSFER", "the player is still in world"); else { sScriptMgr->OnPacketReceive(m_Socket, WorldPacket(*packet)); (this->*opHandle.handler)(*packet); LogUnprocessedTail(packet); } break; case STATUS_AUTHED: // prevent cheating with skip queue wait if (m_inQueue) { LogUnexpectedOpcode(packet, "STATUS_AUTHED", "the player not pass queue yet"); break; } // some auth opcodes can be recieved before STATUS_LOGGEDIN_OR_RECENTLY_LOGGOUT opcodes // however when we recieve CMSG_CHAR_ENUM we are surely no longer during the logout process. if (packet->GetOpcode() == CMSG_CHAR_ENUM) m_playerRecentlyLogout = false; sScriptMgr->OnPacketReceive(m_Socket, WorldPacket(*packet)); (this->*opHandle.handler)(*packet); LogUnprocessedTail(packet); break; case STATUS_NEVER: sLog->outError(LOG_FILTER_OPCODES, "Received not allowed opcode %s from %s", GetOpcodeNameForLogging(packet->GetOpcode()).c_str() , GetPlayerInfo().c_str()); break; case STATUS_UNHANDLED: sLog->outDebug(LOG_FILTER_OPCODES, "Received not handled opcode %s from %s", GetOpcodeNameForLogging(packet->GetOpcode()).c_str() , GetPlayerInfo().c_str()); break; } } catch(ByteBufferException &) { sLog->outError(LOG_FILTER_GENERAL, "WorldSession::Update ByteBufferException occured while parsing a packet (opcode: %u) from client %s, accountid=%i. Skipped packet.", packet->GetOpcode(), GetRemoteAddress().c_str(), GetAccountId()); packet->hexlike(); } } if (deletePacket) delete packet; } if (m_Socket && !m_Socket->IsClosed() && _warden) _warden->Update(); ProcessQueryCallbacks(); // Playerbot mod - Process player bot packets // The PlayerbotAI class adds to the packet queue to simulate a real player // since Playerbots are known to the World obj only by its master's WorldSession object // we need to process all master's bot's packets. if (GetPlayer() && GetPlayer()->GetPlayerbotMgr()) { for (PlayerBotMap::const_iterator itr = GetPlayer()->GetPlayerbotMgr()->GetPlayerBotsBegin(); itr != GetPlayer()->GetPlayerbotMgr()->GetPlayerBotsEnd(); ++itr) { Player* const botPlayer = itr->second; if (!botPlayer) continue; WorldSession* const pBotWorldSession = botPlayer->GetSession(); if (!pBotWorldSession) continue; if (botPlayer->IsBeingTeleported()) botPlayer->GetPlayerbotAI()->HandleTeleportAck(); else if (botPlayer->IsInWorld()) { WorldPacket* packet; while (!_recvQueue.empty() && _recvQueue.peek(true) != firstDelayedPacket && pBotWorldSession->_recvQueue.next(packet, updater)) { OpcodeHandler& opHandle = opcodeTable[packet->GetOpcode()]; //sScriptMgr->OnPacketReceive(m_Socket, WorldPacket(*packet)); (pBotWorldSession->*opHandle.handler)(*packet); delete packet; } } } } //check if we are safe to proceed with logout //logout procedure should happen only in World::UpdateSessions() method!!! if (updater.ProcessLogout()) { time_t currTime = time(NULL); ///- If necessary, log the player out if (ShouldLogOut(currTime) && !m_playerLoading) LogoutPlayer(true); if (m_Socket && GetPlayer() && _warden) _warden->Update(); ///- Cleanup socket pointer if need if (m_Socket && m_Socket->IsClosed()) { m_Socket->RemoveReference(); m_Socket = NULL; } if (!m_Socket) return false; //Will remove this session from the world session map } return true; }
/// Update the WorldSession (triggered by World update) bool WorldSession::Update(uint32 diff, PacketFilter& updater) { /// Update Timeout timer. UpdateTimeOutTime(diff); ///- Before we process anything: /// If necessary, kick the player from the character select screen if (IsConnectionIdle()) m_Socket->CloseSocket(); ///- Retrieve packets from the receive queue and call the appropriate handlers /// not process packets if socket already closed WorldPacket* packet = NULL; //! Delete packet after processing by default bool deletePacket = true; //! To prevent infinite loop WorldPacket* firstDelayedPacket = NULL; //! If _recvQueue.peek() == firstDelayedPacket it means that in this Update call, we've processed all //! *properly timed* packets, and we're now at the part of the queue where we find //! delayed packets that were re-enqueued due to improper timing. To prevent an infinite //! loop caused by re-enqueueing the same packets over and over again, we stop updating this session //! and continue updating others. The re-enqueued packets will be handled in the next Update call for this session. uint32 processedPackets = 0; while (m_Socket && !m_Socket->IsClosed() && !_recvQueue.empty() && _recvQueue.peek(true) != firstDelayedPacket && _recvQueue.next(packet, updater)) { if (!AntiDOS.EvaluateOpcode(*packet)) KickPlayer(); OpcodeHandler const* opHandle = clientOpcodeTable[packet->GetOpcode()]; try { switch (opHandle->Status) { case STATUS_LOGGEDIN: if (!_player) { // skip STATUS_LOGGEDIN opcode unexpected errors if player logout sometime ago - this can be network lag delayed packets //! If player didn't log out a while ago, it means packets are being sent while the server does not recognize //! the client to be in world yet. We will re-add the packets to the bottom of the queue and process them later. if (!m_playerRecentlyLogout) { //! Prevent infinite loop if (!firstDelayedPacket) firstDelayedPacket = packet; //! Because checking a bool is faster than reallocating memory deletePacket = false; QueuePacket(packet); //! Log TC_LOG_DEBUG("network", "Re-enqueueing packet with opcode %s with with status STATUS_LOGGEDIN. " "Player is currently not in world yet.", GetOpcodeNameForLogging(packet->GetOpcode(), false).c_str()); } } else if (_player->IsInWorld()) { sScriptMgr->OnPacketReceive(m_Socket, WorldPacket(*packet)); (this->*opHandle->Handler)(*packet); LogUnprocessedTail(packet); } // lag can cause STATUS_LOGGEDIN opcodes to arrive after the player started a transfer break; case STATUS_LOGGEDIN_OR_RECENTLY_LOGGOUT: if (!_player && !m_playerRecentlyLogout && !m_playerLogout) // There's a short delay between _player = null and m_playerRecentlyLogout = true during logout LogUnexpectedOpcode(packet, "STATUS_LOGGEDIN_OR_RECENTLY_LOGGOUT", "the player has not logged in yet and not recently logout"); else { // not expected _player or must checked in packet hanlder sScriptMgr->OnPacketReceive(m_Socket, WorldPacket(*packet)); (this->*opHandle->Handler)(*packet); LogUnprocessedTail(packet); } break; case STATUS_TRANSFER: if (!_player) LogUnexpectedOpcode(packet, "STATUS_TRANSFER", "the player has not logged in yet"); else if (_player->IsInWorld()) LogUnexpectedOpcode(packet, "STATUS_TRANSFER", "the player is still in world"); else { sScriptMgr->OnPacketReceive(m_Socket, WorldPacket(*packet)); (this->*opHandle->Handler)(*packet); LogUnprocessedTail(packet); } break; case STATUS_AUTHED: // prevent cheating with skip queue wait if (m_inQueue) { LogUnexpectedOpcode(packet, "STATUS_AUTHED", "the player not pass queue yet"); break; } // some auth opcodes can be recieved before STATUS_LOGGEDIN_OR_RECENTLY_LOGGOUT opcodes // however when we recieve CMSG_CHAR_ENUM we are surely no longer during the logout process. if (packet->GetOpcode() == CMSG_CHAR_ENUM) m_playerRecentlyLogout = false; sScriptMgr->OnPacketReceive(m_Socket, WorldPacket(*packet)); (this->*opHandle->Handler)(*packet); LogUnprocessedTail(packet); break; case STATUS_NEVER: TC_LOG_ERROR("network.opcode", "Received not allowed opcode %s from %s", GetOpcodeNameForLogging(packet->GetOpcode(), false).c_str() , GetPlayerInfo().c_str()); break; case STATUS_UNHANDLED: TC_LOG_ERROR("network.opcode", "Received not handled opcode %s from %s", GetOpcodeNameForLogging(packet->GetOpcode(), false).c_str() , GetPlayerInfo().c_str()); break; } } catch (ByteBufferException const&) { TC_LOG_ERROR("network", "WorldSession::Update ByteBufferException occured while parsing a packet (opcode: %s) from client %s, accountid=%i. Skipped packet.", GetOpcodeNameForLogging(packet->GetOpcode(), false).c_str(), GetRemoteAddress().c_str(), GetAccountId()); packet->hexlike(); } if (deletePacket) delete packet; deletePacket = true; #define MAX_PROCESSED_PACKETS_IN_SAME_WORLDSESSION_UPDATE 100 processedPackets++; //process only a max amout of packets in 1 Update() call. //Any leftover will be processed in next update if (processedPackets > MAX_PROCESSED_PACKETS_IN_SAME_WORLDSESSION_UPDATE) break; } if (m_Socket && !m_Socket->IsClosed() && _warden) _warden->Update(); ProcessQueryCallbacks(); //check if we are safe to proceed with logout //logout procedure should happen only in World::UpdateSessions() method!!! if (updater.ProcessLogout()) { time_t currTime = time(NULL); ///- If necessary, log the player out if (ShouldLogOut(currTime) && !m_playerLoading) LogoutPlayer(true); if (m_Socket && GetPlayer() && _warden) _warden->Update(); ///- Cleanup socket pointer if need if (m_Socket && m_Socket->IsClosed()) { m_Socket->RemoveReference(); m_Socket = NULL; } if (!m_Socket) return false; //Will remove this session from the world session map } return true; }
bool Client::HandleGenerateRandomNamePacket(const EQApplicationPacket *app) { // creates up to a 10 char name char vowels[18]="aeiouyaeiouaeioe"; char cons[48]="bcdfghjklmnpqrstvwxzybcdgklmnprstvwbcdgkpstrkd"; char rndname[17]="\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"; char paircons[33]="ngrkndstshthphsktrdrbrgrfrclcr"; int rndnum=MakeRandomInt(0, 75),n=1; bool dlc=false; bool vwl=false; bool dbl=false; if (rndnum>63) { // rndnum is 0 - 75 where 64-75 is cons pair, 17-63 is cons, 0-16 is vowel rndnum=(rndnum-61)*2; // name can't start with "ng" "nd" or "rk" rndname[0]=paircons[rndnum]; rndname[1]=paircons[rndnum+1]; n=2; } else if (rndnum>16) { rndnum-=17; rndname[0]=cons[rndnum]; } else { rndname[0]=vowels[rndnum]; vwl=true; } int namlen=MakeRandomInt(5, 10); for (int i=n;i<namlen;i++) { dlc=false; if (vwl) //last char was a vowel { // so pick a cons or cons pair rndnum=MakeRandomInt(0, 62); if (rndnum>46) { // pick a cons pair if (i>namlen-3) // last 2 chars in name? { // name can only end in cons pair "rk" "st" "sh" "th" "ph" "sk" "nd" or "ng" rndnum=MakeRandomInt(0, 7)*2; } else { // pick any from the set rndnum=(rndnum-47)*2; } rndname[i]=paircons[rndnum]; rndname[i+1]=paircons[rndnum+1]; dlc=true; // flag keeps second letter from being doubled below i+=1; } else { // select a single cons rndname[i]=cons[rndnum]; } } else { // select a vowel rndname[i]=vowels[MakeRandomInt(0, 16)]; } vwl=!vwl; if (!dbl && !dlc) { // one chance at double letters in name if (!MakeRandomInt(0, i+9)) // chances decrease towards end of name { rndname[i+1]=rndname[i]; dbl=true; i+=1; } } } rndname[0]=toupper(rndname[0]); NameGeneration_Struct* ngs = (NameGeneration_Struct*)app->pBuffer; memset(ngs->name,0,64); strcpy(ngs->name,rndname); QueuePacket(app); return true; }
/// Update the WorldSession (triggered by World update) bool WorldSession::Update(uint32 diff, PacketFilter& updater) { uint32 sessionDiff = getMSTime(); uint32 nbPacket = 0; std::map<uint32, OpcodeInfo> pktHandle; // opcodeId / OpcodeInfo /// Antispam Timer update if (sWorld->getBoolConfig(CONFIG_ANTISPAM_ENABLED)) UpdateAntispamTimer(diff); /// Update Timeout timer. UpdateTimeOutTime(diff); ///- Before we process anything: /// If necessary, kick the player from the character select screen if (IsConnectionIdle()) m_Socket->CloseSocket(); ///- Retrieve packets from the receive queue and call the appropriate handlers /// not process packets if socket already closed WorldPacket* packet = NULL; //! Delete packet after processing by default bool deletePacket = true; //! To prevent infinite loop WorldPacket* firstDelayedPacket = NULL; //! If _recvQueue.peek() == firstDelayedPacket it means that in this Update call, we've processed all //! *properly timed* packets, and we're now at the part of the queue where we find //! delayed packets that were re-enqueued due to improper timing. To prevent an infinite //! loop caused by re-enqueueing the same packets over and over again, we stop updating this session //! and continue updating others. The re-enqueued packets will be handled in the next Update call for this session. uint32 processedPackets = 0; while (m_Socket && !m_Socket->IsClosed() && !_recvQueue.empty() && _recvQueue.peek(true) != firstDelayedPacket && _recvQueue.next(packet, updater)) { const OpcodeHandler* opHandle = opcodeTable[packet->GetOpcode()]; uint32 pktTime = getMSTime(); try { switch (opHandle->status) { case STATUS_LOGGEDIN: if (!_player) { // skip STATUS_LOGGEDIN opcode unexpected errors if player logout sometime ago - this can be network lag delayed packets //! If player didn't log out a while ago, it means packets are being sent while the server does not recognize //! the client to be in world yet. We will re-add the packets to the bottom of the queue and process them later. if (!m_playerRecentlyLogout) { //! Prevent infinite loop if (!firstDelayedPacket) firstDelayedPacket = packet; //! Because checking a bool is faster than reallocating memory deletePacket = false; QueuePacket(packet); //! Log sLog->outDebug(LOG_FILTER_NETWORKIO, "Re-enqueueing packet with opcode %s with with status STATUS_LOGGEDIN. " "Player is currently not in world yet.", GetOpcodeNameForLogging(packet->GetOpcode()).c_str()); } } else if (_player->IsInWorld()) { sScriptMgr->OnPacketReceive(m_Socket, WorldPacket(*packet)); #ifdef ELUNA if (!sEluna->OnPacketReceive(this, *packet)) break; #endif (this->*opHandle->handler)(*packet); if (sLog->ShouldLog(LOG_FILTER_NETWORKIO, LOG_LEVEL_TRACE) && packet->rpos() < packet->wpos()) LogUnprocessedTail(packet); } // lag can cause STATUS_LOGGEDIN opcodes to arrive after the player started a transfer break; case STATUS_LOGGEDIN_OR_RECENTLY_LOGGOUT: if (!_player && !m_playerRecentlyLogout && !m_playerLogout) // There's a short delay between _player = null and m_playerRecentlyLogout = true during logout LogUnexpectedOpcode(packet, "STATUS_LOGGEDIN_OR_RECENTLY_LOGGOUT", "the player has not logged in yet and not recently logout"); else { // not expected _player or must checked in packet hanlder sScriptMgr->OnPacketReceive(m_Socket, WorldPacket(*packet)); #ifdef ELUNA if (!sEluna->OnPacketReceive(this, *packet)) break; #endif (this->*opHandle->handler)(*packet); if (sLog->ShouldLog(LOG_FILTER_NETWORKIO, LOG_LEVEL_TRACE) && packet->rpos() < packet->wpos()) LogUnprocessedTail(packet); } break; case STATUS_TRANSFER: if (!_player) LogUnexpectedOpcode(packet, "STATUS_TRANSFER", "the player has not logged in yet"); else if (_player->IsInWorld()) LogUnexpectedOpcode(packet, "STATUS_TRANSFER", "the player is still in world"); else { sScriptMgr->OnPacketReceive(m_Socket, WorldPacket(*packet)); #ifdef ELUNA if (!sEluna->OnPacketReceive(this, *packet)) break; #endif (this->*opHandle->handler)(*packet); if (sLog->ShouldLog(LOG_FILTER_NETWORKIO, LOG_LEVEL_TRACE) && packet->rpos() < packet->wpos()) LogUnprocessedTail(packet); } break; case STATUS_AUTHED: // prevent cheating with skip queue wait if (m_inQueue) { LogUnexpectedOpcode(packet, "STATUS_AUTHED", "the player not pass queue yet"); break; } // some auth opcodes can be recieved before STATUS_LOGGEDIN_OR_RECENTLY_LOGGOUT opcodes // however when we recieve CMSG_CHAR_ENUM we are surely no longer during the logout process. if (packet->GetOpcode() == CMSG_CHAR_ENUM) m_playerRecentlyLogout = false; sScriptMgr->OnPacketReceive(m_Socket, WorldPacket(*packet)); #ifdef ELUNA if (!sEluna->OnPacketReceive(this, *packet)) break; #endif (this->*opHandle->handler)(*packet); if (sLog->ShouldLog(LOG_FILTER_NETWORKIO, LOG_LEVEL_TRACE) && packet->rpos() < packet->wpos()) LogUnprocessedTail(packet); break; case STATUS_NEVER: sLog->outError(LOG_FILTER_OPCODES, "Received not allowed opcode %s from %s", GetOpcodeNameForLogging(packet->GetOpcode()).c_str() , GetPlayerName(false).c_str()); break; case STATUS_UNHANDLED: sLog->outError(LOG_FILTER_OPCODES, "Received not handled opcode %s from %s", GetOpcodeNameForLogging(packet->GetOpcode()).c_str() , GetPlayerName(false).c_str()); break; } } catch(ByteBufferException &) { sLog->outError(LOG_FILTER_NETWORKIO, "WorldSession::Update ByteBufferException occured while parsing a packet (opcode: %u) from client %s, accountid=%i. Skipped packet.", packet->GetOpcode(), GetRemoteAddress().c_str(), GetAccountId()); packet->hexlike(); } nbPacket++; std::map<uint32, OpcodeInfo>::iterator itr = pktHandle.find(packet->GetOpcode()); if (itr == pktHandle.end()) pktHandle.insert(std::make_pair(packet->GetOpcode(), OpcodeInfo(1, getMSTime() - pktTime))); else { OpcodeInfo& data = (*itr).second; data.nbPkt += 1; data.totalTime += getMSTime() - pktTime; } if (deletePacket) delete packet; #define MAX_PROCESSED_PACKETS_IN_SAME_WORLDSESSION_UPDATE 500 processedPackets++; //process only a max amout of packets in 1 Update() call. //Any leftover will be processed in next update if (processedPackets > MAX_PROCESSED_PACKETS_IN_SAME_WORLDSESSION_UPDATE) break; } if (m_Socket && !m_Socket->IsClosed() && _warden) _warden->Update(); ProcessQueryCallbacks(); //check if we are safe to proceed with logout //logout procedure should happen only in World::UpdateSessions() method!!! if (updater.ProcessLogout()) { time_t currTime = time(NULL); ///- If necessary, log the player out if (ShouldLogOut(currTime) && !m_playerLoading) LogoutPlayer(true); if (m_Socket && GetPlayer() && _warden) _warden->Update(); ///- Cleanup socket pointer if need if (m_Socket && m_Socket->IsClosed()) { m_Socket->RemoveReference(); m_Socket = NULL; } if (!m_Socket) return false; //Will remove this session from the world session map } sessionDiff = getMSTime() - sessionDiff; if (sessionDiff > 50) { sLog->outInfo(LOG_FILTER_PLAYER, "Session of account [%u] take more than 50 ms to execute (%u ms)", GetAccountId(), sessionDiff); for (auto itr : pktHandle) sLog->outInfo(LOG_FILTER_PLAYER, "Session of account -----> %u %s (%u ms)", itr.second.nbPkt, GetOpcodeNameForLogging((Opcodes)itr.first).c_str(), itr.second.totalTime); } return true; }
void Client::Clearance(int8 response) { ZoneServer* zs = nullptr; if(instanceID > 0) { zs = zoneserver_list.FindByInstanceID(instanceID); } else { zs = zoneserver_list.FindByZoneID(zoneID); } if(zs == 0 || response == -1 || response == 0) { if (zs == 0) { clog(WORLD__CLIENT_ERR,"Unable to find zoneserver in Client::Clearance!!"); } else { clog(WORLD__CLIENT_ERR, "Invalid response %d in Client::Clearance", response); } ZoneUnavail(); return; } EQApplicationPacket* outapp; if (zs->GetCAddress() == nullptr) { clog(WORLD__CLIENT_ERR, "Unable to do zs->GetCAddress() in Client::Clearance!!"); ZoneUnavail(); return; } if (zoneID == 0) { clog(WORLD__CLIENT_ERR, "zoneID is nullptr in Client::Clearance!!"); ZoneUnavail(); return; } const char* zonename = database.GetZoneName(zoneID); if (zonename == 0) { clog(WORLD__CLIENT_ERR, "zonename is nullptr in Client::Clearance!!"); ZoneUnavail(); return; } // @bp This is the chat server /* char packetData[] = "64.37.148.34.9876,MyServer,Testchar,23cd2c95"; outapp = new EQApplicationPacket(OP_0x0282, sizeof(packetData)); strcpy((char*)outapp->pBuffer, packetData); QueuePacket(outapp); delete outapp; */ // Send zone server IP data outapp = new EQApplicationPacket(OP_ZoneServerInfo, sizeof(ZoneServerInfo_Struct)); ZoneServerInfo_Struct* zsi = (ZoneServerInfo_Struct*)outapp->pBuffer; const char *zs_addr=zs->GetCAddress(); if (!zs_addr[0]) { if (cle->IsLocalClient()) { struct in_addr in; in.s_addr = zs->GetIP(); zs_addr=inet_ntoa(in); if (!strcmp(zs_addr,"127.0.0.1")) zs_addr=WorldConfig::get()->LocalAddress.c_str(); } else { zs_addr=WorldConfig::get()->WorldAddress.c_str(); } } strcpy(zsi->ip, zs_addr); zsi->port =zs->GetCPort(); clog(WORLD__CLIENT,"Sending client to zone %s (%d:%d) at %s:%d",zonename,zoneID,instanceID,zsi->ip,zsi->port); QueuePacket(outapp); safe_delete(outapp); if (cle) cle->SetOnline(CLE_Status_Zoning); }
void Client::DoTributeUpdate() { EQApplicationPacket outapp(OP_TributeUpdate, sizeof(TributeInfo_Struct)); TributeInfo_Struct *tis = (TributeInfo_Struct *) outapp.pBuffer; tis->active = m_pp.tribute_active ? 1 : 0; tis->tribute_master_id = tribute_master_id; //Dont know what this is for int r; for (r = 0; r < EQEmu::legacy::TRIBUTE_SIZE; r++) { if(m_pp.tributes[r].tribute != TRIBUTE_NONE) { tis->tributes[r] = m_pp.tributes[r].tribute; tis->tiers[r] = m_pp.tributes[r].tier; } else { tis->tributes[r] = TRIBUTE_NONE; tis->tiers[r] = 0; } } QueuePacket(&outapp); SendTributeTimer(); if(m_pp.tribute_active) { //send and equip tribute items... for (r = 0; r < EQEmu::legacy::TRIBUTE_SIZE; r++) { uint32 tid = m_pp.tributes[r].tribute; if(tid == TRIBUTE_NONE) { if (m_inv[EQEmu::legacy::TRIBUTE_BEGIN + r]) DeleteItemInInventory(EQEmu::legacy::TRIBUTE_BEGIN + r, 0, false); continue; } if(tribute_list.count(tid) != 1) { if (m_inv[EQEmu::legacy::TRIBUTE_BEGIN + r]) DeleteItemInInventory(EQEmu::legacy::TRIBUTE_BEGIN + r, 0, false); continue; } //sanity check if(m_pp.tributes[r].tier >= MAX_TRIBUTE_TIERS) { if (m_inv[EQEmu::legacy::TRIBUTE_BEGIN + r]) DeleteItemInInventory(EQEmu::legacy::TRIBUTE_BEGIN + r, 0, false); m_pp.tributes[r].tier = 0; continue; } TributeData &d = tribute_list[tid]; TributeLevel_Struct &tier = d.tiers[m_pp.tributes[r].tier]; uint32 item_id = tier.tribute_item_id; //summon the item for them const ItemInst* inst = database.CreateItem(item_id, 1); if(inst == nullptr) continue; PutItemInInventory(EQEmu::legacy::TRIBUTE_BEGIN + r, *inst, false); SendItemPacket(EQEmu::legacy::TRIBUTE_BEGIN + r, inst, ItemPacketTributeItem); safe_delete(inst); } } else { //unequip tribute items... for (r = 0; r < EQEmu::legacy::TRIBUTE_SIZE; r++) { if (m_inv[EQEmu::legacy::TRIBUTE_BEGIN + r]) DeleteItemInInventory(EQEmu::legacy::TRIBUTE_BEGIN + r, 0, false); } } CalcBonuses(); }
void CGameServerPlayer::SendTeleportSequence(uint32 levelId, uint32 musicId, float x, float y, float z, float angle) { QueuePacket(PacketData(std::begin(g_client0_moor1), std::end(g_client0_moor1))); QueuePacket(PacketData(std::begin(g_client0_moor2), std::end(g_client0_moor2))); QueuePacket(PacketData(std::begin(g_client0_moor3), std::end(g_client0_moor3))); QueuePacket(PacketData(std::begin(g_client0_moor4), std::end(g_client0_moor4))); QueuePacket(PacketData(std::begin(g_client0_moor5), std::end(g_client0_moor5))); QueuePacket(PacketData(std::begin(g_client0_moor6), std::end(g_client0_moor6))); QueuePacket(PacketData(std::begin(g_client0_moor7), std::end(g_client0_moor7))); QueuePacket(PacketData(std::begin(g_client0_moor8), std::end(g_client0_moor8))); QueuePacket(PacketData(std::begin(g_client0_moor9), std::end(g_client0_moor9))); { CCompositePacket result; { CSetMusicPacket packet; packet.SetSourceId(PLAYER_ID); packet.SetTargetId(PLAYER_ID); packet.SetMusicId(musicId); result.AddPacket(packet.ToPacketData()); } { CSetWeatherPacket packet; packet.SetSourceId(PLAYER_ID); packet.SetTargetId(PLAYER_ID); packet.SetWeatherId(CSetWeatherPacket::WEATHER_CLEAR); result.AddPacket(packet.ToPacketData()); } { CSetMapPacket packet; packet.SetSourceId(PLAYER_ID); packet.SetTargetId(PLAYER_ID); packet.SetMapId(levelId); result.AddPacket(packet.ToPacketData()); } QueuePacket(result.ToPacketData()); } QueuePacket(PacketData(std::begin(g_client0_moor11), std::end(g_client0_moor11))); QueuePacket(PacketData(std::begin(g_client0_moor12), std::end(g_client0_moor12))); { PacketData outgoingPacket(std::begin(g_client0_moor13), std::end(g_client0_moor13)); { const uint32 setInitialPositionBase = 0x360; CSetInitialPositionPacket setInitialPosition; setInitialPosition.SetSourceId(PLAYER_ID); setInitialPosition.SetTargetId(PLAYER_ID); setInitialPosition.SetX(x); setInitialPosition.SetY(y); setInitialPosition.SetZ(z); setInitialPosition.SetAngle(angle); auto setInitialPositionPacket = setInitialPosition.ToPacketData(); memcpy(outgoingPacket.data() + setInitialPositionBase, setInitialPositionPacket.data(), setInitialPositionPacket.size()); } QueuePacket(outgoingPacket); } QueuePacket(GetInventoryInfo()); QueuePacket(PacketData(std::begin(g_client0_moor21), std::end(g_client0_moor21))); //QueuePacket(PacketData(std::begin(g_client0_moor22), std::end(g_client0_moor22))); if(!m_zoneMasterCreated) { //Zone Master QueuePacket(PacketData(std::begin(g_client0_moor23), std::end(g_client0_moor23))); /* QueuePacket(PacketData(std::begin(g_client0_moor24), std::end(g_client0_moor24))); QueuePacket(PacketData(std::begin(g_client0_moor25), std::end(g_client0_moor25))); QueuePacket(PacketData(std::begin(g_client0_moor26), std::end(g_client0_moor26))); QueuePacket(PacketData(std::begin(g_client0_moor27), std::end(g_client0_moor27))); QueuePacket(PacketData(std::begin(g_client0_moor28), std::end(g_client0_moor28))); QueuePacket(PacketData(std::begin(g_client0_moor29), std::end(g_client0_moor29))); QueuePacket(PacketData(std::begin(g_client0_moor30), std::end(g_client0_moor30))); QueuePacket(PacketData(std::begin(g_client0_moor31), std::end(g_client0_moor31))); QueuePacket(PacketData(std::begin(g_client0_moor32), std::end(g_client0_moor32))); QueuePacket(PacketData(std::begin(g_client0_moor33), std::end(g_client0_moor33))); QueuePacket(PacketData(std::begin(g_client0_moor34), std::end(g_client0_moor34))); QueuePacket(PacketData(std::begin(g_client0_moor35), std::end(g_client0_moor35))); QueuePacket(PacketData(std::begin(g_client0_moor36), std::end(g_client0_moor36))); QueuePacket(PacketData(std::begin(g_client0_moor37), std::end(g_client0_moor37))); */ //Enables chat? // QueuePacket(PacketData(std::begin(g_client0_moor38), std::end(g_client0_moor38))); { CCompositePacket packet; packet.AddPacket(PacketData(std::begin(g_client0_moor38), std::end(g_client0_moor38))); QueuePacket(packet.ToPacketData()); } // QueuePacket(PacketData(std::begin(g_client0_moor39), std::end(g_client0_moor39))); // QueuePacket(PacketData(std::begin(g_client0_moor40), std::end(g_client0_moor40))); ResetInstance(); //Only makes sense in Black Shroud for now if(levelId == CSetMapPacket::MAP_BLACKSHROUD) { const auto& actorDatabase = CGlobalData::GetInstance().GetActorDatabase(); for(const auto& actorInfo : actorDatabase.GetActors()) { SpawnNpc(actorInfo.id, actorInfo.baseModelId, actorInfo.nameStringId, std::get<0>(actorInfo.pos), std::get<1>(actorInfo.pos), std::get<2>(actorInfo.pos), 0); } } m_zoneMasterCreated = true; } }
bool Client::HandleEnterWorldPacket(const EQApplicationPacket *app) { if (GetAccountID() == 0) { clog(WORLD__CLIENT_ERR,"Enter world with no logged in account"); eqs->Close(); return true; } if(GetAdmin() < 0) { clog(WORLD__CLIENT,"Account banned or suspended."); eqs->Close(); return true; } if (RuleI(World, MaxClientsPerIP) >= 0) { client_list.GetCLEIP(this->GetIP()); //Check current CLE Entry IPs against incoming connection } EnterWorld_Struct *ew=(EnterWorld_Struct *)app->pBuffer; strn0cpy(char_name, ew->name, 64); EQApplicationPacket *outapp; uint32 tmpaccid = 0; charid = database.GetCharacterInfo(char_name, &tmpaccid, &zoneID, &instanceID); if (charid == 0 || tmpaccid != GetAccountID()) { clog(WORLD__CLIENT_ERR,"Could not get CharInfo for '%s'",char_name); eqs->Close(); return true; } // Make sure this account owns this character if (tmpaccid != GetAccountID()) { clog(WORLD__CLIENT_ERR,"This account does not own the character named '%s'",char_name); eqs->Close(); return true; } if(!pZoning && ew->return_home && !ew->tutorial) { CharacterSelect_Struct* cs = new CharacterSelect_Struct; memset(cs, 0, sizeof(CharacterSelect_Struct)); database.GetCharSelectInfo(GetAccountID(), cs); bool home_enabled = false; for(int x = 0; x < 10; ++x) { if(strcasecmp(cs->name[x], char_name) == 0) { if(cs->gohome[x] == 1) { home_enabled = true; break; } } } safe_delete(cs); if(home_enabled) { zoneID = database.MoveCharacterToBind(charid,4); } else { clog(WORLD__CLIENT_ERR,"'%s' is trying to go home before they're able...",char_name); database.SetHackerFlag(GetAccountName(), char_name, "MQGoHome: player tried to go home before they were able."); eqs->Close(); return true; } } if(!pZoning && (RuleB(World, EnableTutorialButton) && (ew->tutorial || StartInTutorial))) { CharacterSelect_Struct* cs = new CharacterSelect_Struct; memset(cs, 0, sizeof(CharacterSelect_Struct)); database.GetCharSelectInfo(GetAccountID(), cs); bool tutorial_enabled = false; for(int x = 0; x < 10; ++x) { if(strcasecmp(cs->name[x], char_name) == 0) { if(cs->tutorial[x] == 1) { tutorial_enabled = true; break; } } } safe_delete(cs); if(tutorial_enabled) { zoneID = RuleI(World, TutorialZoneID); database.MoveCharacterToZone(charid, database.GetZoneName(zoneID)); } else { clog(WORLD__CLIENT_ERR,"'%s' is trying to go to tutorial but are not allowed...",char_name); database.SetHackerFlag(GetAccountName(), char_name, "MQTutorial: player tried to enter the tutorial without having tutorial enabled for this character."); eqs->Close(); return true; } } if (zoneID == 0 || !database.GetZoneName(zoneID)) { // This is to save people in an invalid zone, once it's removed from the DB database.MoveCharacterToZone(charid, "arena"); clog(WORLD__CLIENT_ERR, "Zone not found in database zone_id=%i, moveing char to arena character:%s", zoneID, char_name); } if(instanceID > 0) { if(!database.VerifyInstanceAlive(instanceID, GetCharID())) { zoneID = database.MoveCharacterToBind(charid); instanceID = 0; } else { if(!database.VerifyZoneInstance(zoneID, instanceID)) { zoneID = database.MoveCharacterToBind(charid); instanceID = 0; } } } if(!pZoning) { database.SetGroupID(char_name, 0, charid); database.SetFirstLogon(charid, 1); if (RuleB(World, AnnounceJoinQuits) == true) //this is having an issue, its not taking a true false swap, only takes default. { zoneserver_list.SendEmoteMessage(0, 0, 0, 15, "%s is logging on!", GetCharName()); clog(WORLD__CLIENT_ERR, "Character is logging on: %s", GetCharName()); } } else{ uint32 groupid=database.GetGroupID(char_name); if(groupid>0){ char* leader=0; char leaderbuf[64]={0}; if((leader=database.GetGroupLeaderForLogin(char_name,leaderbuf)) && strlen(leader)>1){ EQApplicationPacket* outapp3 = new EQApplicationPacket(OP_GroupUpdate,sizeof(GroupJoin_Struct)); GroupJoin_Struct* gj=(GroupJoin_Struct*)outapp3->pBuffer; gj->action=8; strcpy(gj->yourname,char_name); strcpy(gj->membername,leader); QueuePacket(outapp3); safe_delete(outapp3); } } } outapp = new EQApplicationPacket(OP_MOTD); char tmp[500] = {0}; if (database.GetVariable("MOTD", tmp, 500)) { outapp->size = strlen(tmp)+1; outapp->pBuffer = new uchar[outapp->size]; memset(outapp->pBuffer,0,outapp->size); strcpy((char*)outapp->pBuffer, tmp); } else { // Null Message of the Day. :) outapp->size = 1; outapp->pBuffer = new uchar[outapp->size]; outapp->pBuffer[0] = 0; } QueuePacket(outapp); safe_delete(outapp); int MailKey = MakeRandomInt(1, INT_MAX); database.SetMailKey(charid, GetIP(), MailKey); char ConnectionType; ConnectionType = 'C'; EQApplicationPacket *outapp2 = new EQApplicationPacket(OP_SetChatServer); char buffer[112]; const WorldConfig *Config = WorldConfig::get(); sprintf(buffer,"%s,%i,%s.%s,%c%08X", Config->ChatHost.c_str(), Config->ChatPort, Config->ShortName.c_str(), this->GetCharName(), ConnectionType, MailKey ); outapp2->size=strlen(buffer)+1; outapp2->pBuffer = new uchar[outapp2->size]; memcpy(outapp2->pBuffer,buffer,outapp2->size); QueuePacket(outapp2); safe_delete(outapp2); EnterWorld(); return true; }
void Client::SendTradeskillDetails(uint32 recipe_id) { char errbuf[MYSQL_ERRMSG_SIZE]; MYSQL_RES *result; MYSQL_ROW row; char *query = 0; uint32 qlen = 0; uint8 qcount = 0; //pull the list of components qlen = MakeAnyLenString(&query, "SELECT tre.item_id,tre.componentcount,i.icon,i.Name " " FROM tradeskill_recipe_entries AS tre " " LEFT JOIN items AS i ON tre.item_id = i.id " " WHERE tre.componentcount > 0 AND tre.recipe_id=%u", recipe_id); if (!database.RunQuery(query, qlen, errbuf, &result)) { LogFile->write(EQEMuLog::Error, "Error in SendTradeskillDetails query '%s': %s", query, errbuf); safe_delete_array(query); return; } safe_delete_array(query); qcount = mysql_num_rows(result); if(qcount < 1) { LogFile->write(EQEMuLog::Error, "Error in SendTradeskillDetails: no components returned"); return; } if(qcount > 10) { LogFile->write(EQEMuLog::Error, "Error in SendTradeskillDetails: too many components returned (%u)", qcount); return; } //biggest this packet can ever be: // 64 * 10 + 8 * 10 + 4 + 4 * 10 = 764 char *buf = new char[775]; //dynamic so we can just give it to EQApplicationPacket uint8 r,k; uint32 *header = (uint32 *) buf; //Hell if I know why this is in the wrong byte order.... *header = htonl(recipe_id); char *startblock = buf; startblock += sizeof(uint32); uint32 *ffff_start = (uint32 *) startblock; //fill in the FFFF's as if there were 0 items for(r = 0; r < 10; r++) { *ffff_start = 0xFFFFFFFF; ffff_start++; } char * datastart = (char *) ffff_start; char * cblock = (char *) ffff_start; uint32 *itemptr; uint32 *iconptr; uint32 len; uint32 datalen = 0; uint8 count = 0; for(r = 0; r < qcount; r++) { row = mysql_fetch_row(result); //watch for references to items which are not in the //items table, which the left join will make NULL... if(row[2] == NULL || row[3] == NULL) { continue; } uint32 item = (uint32)atoi(row[0]); uint8 num = (uint8) atoi(row[1]); uint32 icon = (uint32) atoi(row[2]); const char *name = row[3]; len = strlen(name); if(len > 63) len = 63; //Hell if I know why these are in the wrong byte order.... item = htonl(item); icon = htonl(icon); //if we get more than 10 items, just start skipping them... for(k = 0; k < num && count < 10; k++) { itemptr = (uint32 *) cblock; cblock += sizeof(uint32); datalen += sizeof(uint32); iconptr = (uint32 *) cblock; cblock += sizeof(uint32); datalen += sizeof(uint32); *itemptr = item; *iconptr = icon; strncpy(cblock, name, len); cblock[len] = '\0'; //just making sure. cblock += len + 1; //get the null datalen += len + 1; //get the null count++; } } mysql_free_result(result); //now move the item data over top of the FFFFs uint8 dist = sizeof(uint32) * (10 - count); startblock += dist; memmove(startblock, datastart, datalen); uint32 total = sizeof(uint32) + dist + datalen; EQApplicationPacket* outapp = new EQApplicationPacket(OP_RecipeDetails); outapp->size = total; outapp->pBuffer = (uchar*) buf; QueuePacket(outapp); DumpPacket(outapp); safe_delete(outapp); }
//--------------------------------------------------------------------------------- int HandleCommand(t_connection c[], DWORD dwIndex, t_packet *packet, DWORD dwUserID, int cn) { const int ttype = packet->h.header.type; switch(ttype) { case CMD_NONE : break; case CMD_PING : break; case CMD_LOST_CONNECTION : closeconnection(c, cn, CCT_NORMAL); break; case CMD_IM_GAME_SERVER : break; case CMD_ACCESS_CHAR_DB : // 010613 YGI { const int server_id = packet->u.server_access_char_db.server_id; memcpy(c[cn].id, packet->u.server_access_char_db.id, ID_LENGTH); memcpy(c[cn].name, packet->u.server_access_char_db.name, NM_LENGTH); if(GetCharDB_SQL(c, cn) != 1) break; if(GetCharGameDB_SQL(c, cn) != 1 ) break; LPCHARLIST ch = &c[cn].chrlst; if(!CheckRookieServerAble(ch->Level))//021230 lsw { break; } ch->server_id = cn; // 030923 HK YGI int ret = get_BinaryData_from_Chr_Info( (UCHAR *)ch->Ws, (UCHAR *)ch->Ps, (UCHAR *)ch->Skill, (UCHAR *)ch->skillexp, (UCHAR *)ch->tac_skillEXP, (UCHAR *)var[cn], (UCHAR *)ch->inv, (UCHAR *)ch->equip, (UCHAR *)ch->quick, (UCHAR *)ch->party, (UCHAR *)ch->relation, (UCHAR *)ch->employment, (UCHAR *)ch->Item, c[cn].id, c[cn].name ) ; if( ret != 1 ) break; ret = get_BinaryData_from_Chr_Info2 ( (UCHAR *)c[cn].chrlst.bank, c[cn].id, c[cn].name ) ; if( ret != 1 ) break; ///////////////////////////// ResetCharInfo(var[cn], ch); // PutEventItem( 2, &c[cn] ); // 이벤트용 아이템 넣어 주기 // BBD 040308 Map서버가 주기로 했음 int refresh_inventory = CheckEventITem( ch ); CheckEventJoin(&c[cn].chrlst); // 020115 LTS ///////////////////////////////////////////////////////////////////////////////////// memset(packet, 0, sizeof(t_packet)); packet->h.header.type = CMD_ACCEPT_CHAR_DB; packet->h.header.size = sizeof(t_server_accept_char_db); t_server_accept_char_db *tp = &(packet->u.server_accept_char_db); strcpy( tp->name, c[cn].name );// 030923 HK YGI tp->server_id = server_id; tp->Level = ch->Level; tp->Exp = ch->Exp; tp->Gender = ch->Gender; tp->Face = ch->Face; tp->nGuildCode = ch->nGuildCode; // CSD-030324 tp->Class = ch->Class; tp->Spell = ch->Spell; tp->Job = ch->Job; // 0212 YGI tp->Str = ch->Str; tp->Con = ch->Con; tp->Dex = ch->Dex; tp->Wis = ch->Wis; tp->Int = ch->Int; tp->MoveP = ch->MoveP; tp->Char = ch->Char; tp->Endu = ch->Endu; tp->Moral = ch->Moral; tp->Money = ch->Money; tp->nLife = ch->Hp; tp->nMaxHp = ch->HpMax; tp->nMana = ch->Mana; tp->nMaxMp = ch->ManaMax; tp->nHungry = ch->Hungry; tp->nMaxHungry = ch->HungryMax; tp->Condition = ch->Condition; tp->SprNo = ch->SprNo; tp->X = ch->X; tp->Y = ch->Y; memcpy( tp->MapName, ch->MapName, 20); tp->Peacests = ch->Peacests; tp->Sight = ch->Sight; tp->BodyR = ch->BodyR; tp->BodyG = ch->BodyG; tp->BodyB = ch->BodyB; tp->ClothR = ch->ClothR; tp->ClothG = ch->ClothG; tp->ClothB = ch->ClothB; tp->Age = ch->Age; tp->Luck = ch->Luck; tp->wsps = ch->wsps; memcpy( &tp->nation, &ch->name_status, sizeof( DWORD ) ); // 1004 YGI tp->accessory[0] = ch->accessory[0]; tp->accessory[1] = ch->accessory[1]; tp->accessory[2] = ch->accessory[2]; tp->accessory[3] = ch->accessory[3]; ch->mantle = ch->equip[ WT_NECK].item_no; tp->mantle = ch->mantle; tp->bAlive = ch->bAlive; tp->openhouse = ch->openhouse; tp->disease[0] = ch->disease[0]; tp->disease[1] = ch->disease[1]; tp->disease[2] = ch->disease[2]; tp->disease[3] = ch->disease[3]; tp->disease[4] = ch->disease[4]; tp->disease[5] = ch->disease[5]; tp->total_id = ch->total_id; tp->nPoison = ch->nPoison; tp->nCurse = ch->nCurse; tp->nFire = ch->nFire; tp->nIce = ch->nIce; tp->nElect = ch->nElect; tp->nHoly = ch->nHoly; tp->viewtype = ch->viewtype; // 0212 YGI tp->social_status = ch->social_status; tp->fame = ch->fame; tp->fame_pk = ch->fame_pk; // 010915 LTS //Fame_PK -> NWCharacter로 교체 DB에는 실제로 NWCharacter의 값이 들어갑니다. tp->NWCharacter = ch->NWCharacter; // 010915 LTS tp->EventJoin = ch->EventJoin; // 020115 LTS tp->nUserAge = GetUserAge(c[cn].id); // 030929 kyo memcpy(tp->aStepInfo, ch->aStepInfo, sizeof(ch->aStepInfo)); if(!QueuePacket(c, cn, packet, 1)){break;} ///////////////////////////////////////////////////////////////////////// memset(packet, 0, sizeof(t_packet)); t_server_accept_char_game_db *tsac = &(packet->u.server_accept_char_game_db); packet->h.header.type = CMD_ACCEPT_CHAR_GAME_DB; packet->h.header.size = sizeof(t_server_accept_char_game_db); strcpy( tsac->name, c[cn].name );// 030923 HK YGI tsac->server_id = server_id; tsac->BankMoney = ch->BankMoney; memcpy( &tsac->win_defeat, &ch->WinLoseScore, sizeof( DWORD ) ); tsac->LadderScore = ch->LadderScore; tsac->LastLoan = ch->LastLoan; tsac->nk3 = ch->nk[N_VYSEUS]; tsac->nk4 = ch->nk[N_ZYPERN]; tsac->nk6 = ch->nk[N_YILSE]; tsac->killmon = ch->killmon; tsac->killanimal = ch->killanimal; tsac->killpc = ch->killpc; tsac->reserved_point= ch->reserved_point; tsac->Tactics = ch->Tactics; if(!QueuePacket(c, cn, packet, 1)) break; /////////////////////////////////////////////////////////////////////// memset(packet, 0, sizeof(t_packet)); packet->h.header.type = CMD_ACCEPT_BINARY_DATA; packet->h.header.size = sizeof(t_server_accept_binary_data); packet->u.server_accept_binary_data.server_id = server_id; strcpy( packet->u.server_accept_binary_data.name, c[cn].name );// 030923 HK YGI memcpy((UCHAR *)packet->u.server_accept_binary_data.Ws, (UCHAR *)ch->Ws, SIZE_OF_WS); memcpy((UCHAR *)packet->u.server_accept_binary_data.Ps, (UCHAR *)ch->Ps, SIZE_OF_PS); memcpy((UCHAR *)packet->u.server_accept_binary_data.Skill, (UCHAR *)ch->Skill, SIZE_OF_SKILL); memcpy((UCHAR *)packet->u.server_accept_binary_data.skillexp, (UCHAR *)ch->skillexp, SIZE_OF_SKILL_EXP); memcpy((UCHAR *)packet->u.server_accept_binary_data.tac_skillEXP, (UCHAR *)ch->tac_skillEXP, SIZE_OF_TAC_SKILL_EXP); memcpy((UCHAR *)packet->u.server_accept_binary_data.equip, (UCHAR *)ch->equip, SIZE_OF_EQUIP); memcpy((UCHAR *)packet->u.server_accept_binary_data.quick, (UCHAR *)ch->quick, SIZE_OF_QUICK); memcpy((UCHAR *)packet->u.server_accept_binary_data.party, (UCHAR *)ch->party, SIZE_OF_PARTY); memcpy((UCHAR *)packet->u.server_accept_binary_data.relation, (UCHAR *)ch->relation, SIZE_OF_RELATION); memcpy((UCHAR *)packet->u.server_accept_binary_data.employment, (UCHAR *)ch->employment, SIZE_OF_EMPLOYMENT); if(!QueuePacket(c, cn, packet, 1)) break; /////////////////////////////////////////////////////////////////////// memset(packet, 0, sizeof(t_packet)); packet->h.header.type = CMD_ACCEPT_SCRIPT_DATA; packet->h.header.size = sizeof(t_server_accept_script_data); packet->u.server_accept_script_data.server_id = server_id; strcpy( packet->u.server_accept_script_data.name, c[cn].name );// 030923 HK YGI memcpy((UCHAR *)packet->u.server_accept_script_data.script_var, (UCHAR *)var[cn], SIZE_OF_SCRIPT_VAR); if(!QueuePacket(c, cn, packet, 1)) break; /////////////////////////////////////////////////////////////////////// memset(packet, 0, sizeof(t_packet)); packet->h.header.type = CMD_ACCEPT_INV_DATA; packet->h.header.size = sizeof(t_server_accept_inv_data); packet->u.server_accept_inv_data.server_id = server_id; strcpy( packet->u.server_accept_inv_data.name, c[cn].name );// 030923 HK YGI memcpy((UCHAR *)packet->u.server_accept_inv_data.inv, (UCHAR *)ch->inv, SIZE_OF_INV); //021030 YGI packet->u.server_accept_inv_data.refresh_inventory = refresh_inventory; if(!QueuePacket(c, cn, packet, 1)) break; /////////////////////////////////////////////////////////////////////// memset(packet, 0, sizeof(t_packet)); packet->h.header.type = CMD_ACCEPT_ITEM_DATA; packet->h.header.size = sizeof(t_server_accept_item_data); packet->u.server_accept_item_data.server_id = server_id; strcpy( packet->u.server_accept_item_data.name, c[cn].name );// 030923 HK YGI memcpy((UCHAR *)packet->u.server_accept_item_data.Item, (UCHAR *)c[cn].chrlst.Item, SIZE_OF_ITEMINDEX); if(!QueuePacket(c, cn, packet, 1)) break; /////////////////////////////////////////////////////////////////////// memset(packet, 0, sizeof(t_packet)); packet->h.header.type = CMD_ACCEPT_BANKITEM_DATA; packet->h.header.size = sizeof(t_server_accept_bankitem_data); packet->u.server_accept_bankitem_data.server_id = server_id; strcpy( packet->u.server_accept_bankitem_data.name, c[cn].name );// 030923 HK YGI memcpy((UCHAR *)packet->u.server_accept_bankitem_data.bankitem, (UCHAR *)c[cn].chrlst.bank, SIZE_OF_BANKITEM); if(!QueuePacket(c, cn, packet, 1)) break; }break; case CMD_ACCESS_LOGIN : { ::CheckIDAutherizing(*packet,cn); }break; case CMD_PARTY_ACCESS : { ::SendPartyInforForGameserver( packet->u.kein.server_req_party_db.server_id, packet->u.kein.server_req_party_db.ct, packet->u.kein.server_req_party_db.name, c, cn ); }break; case CMD_REQ_PARTY_TOGETHER : { ::SendPartyInfoOfOtherCharToGameserver( packet->u.kein.server_req_party_together.party_name, packet->u.kein.server_req_party_together.my_name, packet->u.kein.server_req_party_together.server_id, c, cn ); }break; case CMD_CONNECT_INFO : // 4개중의 하나의 캐릭터를 선택했다 { // 캐릭터초기화이후실행 0405 KHS // 0405 YGI new char int is_new_char = 0; if( ::GetCharNew(is_new_char, packet->u.client_connect_info.name ) ) // 4월 1일 새롭게 만든 캐릭터 인가? { if( is_new_char ) { break; }// 1: 예전 캐릭터 0: 새로운 캐릭터 } else { break; } if( !CheckIsRealName( connections[cn].id, packet->u.client_connect_info.name ) ) { break; } // 010301 khs probide to hacking.. memset(c[cn].name, 0, NM_LENGTH); strcpy(c[cn].name, packet->u.client_connect_info.name); StartMap = packet->u.client_connect_info.startmap; StartPosition = packet->u.client_connect_info.startposition; if( StartMap < 0 || StartMap > 1 ) StartMap = 0; if( StartPosition == 99 ) { } else if( StartPosition < 1 || StartPosition > 20 ) { StartPosition = 1; } c[cn].chrlst.startmap = StartMap; c[cn].chrlst.startposition = StartPosition; memset(packet, 0, sizeof(t_packet)); int ret = GetCharDB_SQL(c, cn); if( ret ) { CheckStartMap( c, cn, StartPosition ); // 1004 YGI ret = GetCharGameDB_SQL(c,cn); } if( c[cn].chrlst.Hp == 0 ) { c[cn].chrlst.bAlive = DEAD_; c[cn].chrlst.Condition = CON_DEATH; c[cn].chrlst.viewtype = VIEWTYPE_GHOST_; } else { c[cn].chrlst.bAlive = ALIVE_; c[cn].chrlst.Condition = CON_NORMAL; c[cn].chrlst.viewtype = VIEWTYPE_NORMAL_; } if( c[cn].chrlst.startposition != 99 ) // 원래의 위치에 들어간다. { strcpy( c[cn].mapname, StartMapPosition[ StartMap][ StartPosition ] ); strcpy( c[cn].chrlst.MapName, StartMapPosition[ StartMap][ StartPosition ] ); } if(ret == 1) { //< CSD-030324 extern void CheckNewGuildCode( CHARLIST *ch ); CheckNewGuildCode( &c[cn].chrlst ); //> CSD-030324 packet->h.header.type = CMD_USER_DB; { PutPacketCharDB( c, cn, packet ); } packet->h.header.size = sizeof(t_server_user_db_data); if(!QueuePacket(c, cn, packet, 1)) break; } else // Invalid DB { ::MyLog(1, "Invalid DB [%s]", c[cn].name); packet->h.header.type = CMD_INVALID_DB; packet->h.header.size = 0; QueuePacket(c, cn, packet, 1); break; } break; } case CMD_CHR_ITEM_INFO_0 : { //------------------------------------------------------------ // Send Char Binary Data //------------------------------------------------------------ get_BinaryData_from_Chr_Info( (UCHAR *)c[cn].chrlst.Ws, (UCHAR *)c[cn].chrlst.Ps, (UCHAR *)c[cn].chrlst.Skill, (UCHAR *)c[cn].chrlst.skillexp, (UCHAR *)c[cn].chrlst.tac_skillEXP, (UCHAR *)var[c[cn].chrlst.server_id], (UCHAR *)c[cn].chrlst.inv, (UCHAR *)c[cn].chrlst.equip, (UCHAR *)c[cn].chrlst.quick, (UCHAR *)c[cn].chrlst.party, (UCHAR *)c[cn].chrlst.relation, (UCHAR *)c[cn].chrlst.employment, (UCHAR *)c[cn].chrlst.Item, c[cn].id, c[cn].name ) ; // PutEventItem( 1, &c[cn] ); // 이벤트용 아이템 넣어 주기 // BBD 040308 Map서버가 주기로 했음 SendItemQuick( c, cn ); // 마법을 배우지 않고 모든 마법을 사용하려면 이곳에서 Ws/Ps를 Setting해주면 된다. for( int i = 0 ; i < 1000 ; i ++) { if( c[cn].chrlst.Item[i] == 0) break; } c[cn].chrlst.ItemMax = i; SendLearnedItem( c, cn ); // 0730 YGI break; } case CMD_CHR_ITEM_INFO_1 : SendItemEquip( c, cn ); break; case CMD_CHR_ITEM_INFO_2 : SendItemInventory( packet->u.client_item_inv.count, c, cn ); break; case CMD_CHAR_INFO_MAGIC : SendCharInfoMagic( c, cn ); break; case CMD_CHAR_INFO_SKILL : { SendCharInfoSkill( c, cn ); ::MyLog(0, "Send [%s]Info to [%s]", c[cn].name, c[cn].id); }break; case CMD_CHAR_INFO_TAC_SKILL_EXP : SendCharInfotac_skillEXP( c, cn ); break; case CMD_CONNECT_INFO1 : { char *map_name = 0; int ret = 0; if( c[cn].chrlst.startposition == 99 ) { ret = GetMapName_SQL( c, cn); // 001126 KHS if( ret == 1 ) map_name = c[cn].mapname; } else { map_name = StartMapPosition[ c[cn].chrlst.startmap][c[cn].chrlst.startposition]; } if( map_name ) { ret = 0; int port = MapPort( map_name ); if( port ) { ret = 1; packet->u.kein.server_connect_info_kein.data1.port = port; ret += CheckEventObject( map_name, &packet->u.kein.server_connect_info_kein.u.data3); ret += CheckEventSound( map_name, &packet->u.kein.server_connect_info_kein.u.data3); } } if( ret ) { //----------------------------------------------------------------- //----------------------------------------------------------------- packet->h.header.type = CMD_CONNECT_INFO; packet->h.header.size = sizeof(t_server_connect_info); if( ret == 4 ) // object + sound { packet->h.header.size += sizeof(k_event_object_sound); } else if( ret == 3 ) // sound { packet->h.header.size += sizeof(k_event_sound); int sound_no = packet->u.kein.server_connect_info_kein.u.data3.sound_no; packet->u.kein.server_connect_info_kein.u.data4.sound_no = sound_no; } else if( ret == 2 ) // object { packet->h.header.size += sizeof(k_event_object); } packet->u.server_connect_info.startposition = c[cn].chrlst.startposition; if(!QueuePacket(c, cn, packet, 1)) { break; } //----------------------------------------------------------------- c[cn].state = CONNECT_JOIN; } else // Invalid DB { ::MyLog(0, "Invalid User DB [%s]", c[cn].name); packet->h.header.type = CMD_INVALID_DB; packet->h.header.size = 0; QueuePacket(c, cn, packet, 1); break; } break; } case CMD_CREATE_CHAR : { int ret = CreateChar_SQL(c, cn, packet); if(ret == 1) { packet->h.header.type = CMD_ACCEPT_CREATE; packet->h.header.size = 1; packet->u.data[0]= 0 ; QueuePacket(c, cn, packet, 1); ::MyLog( 0, "%s (ID:%s) is Generated ! IP %s", c[cn].id, c[cn].chrlst.Name, c[cn].ip_address ); break; } else { int is_delete = 1; switch( ret ) { case -100 : ::MyLog( 0, "Fail:Character Generation ( Already character %s, ID:%s :%d)", packet->u.client_create_char.name, c[cn].id, ret ); RecvHackingUser( c[cn].id, packet->u.client_create_char.name, 20009, " ", "Not his Char" ); is_delete = 0; // 지우지 않는다. break; case -30 : ::MyLog( 0, "Fail : Try to make Character but NO ID in chr_log_info ( %s, ID:%s )", packet->u.client_create_char.name, c[cn].id ); break; default : ::MyLog( 0, "Fail : Character Generation( %s, ID:%s :%d)", packet->u.client_create_char.name, c[cn].id, ret ); break; } if(is_delete) { delete_char_create_fail( packet->u.client_create_char.name ); } packet->h.header.type = CMD_INVALID_DB; packet->h.header.size = 1; packet->u.data[0]= 0 ; QueuePacket(c, cn, packet, 1); break; } break; } case CMD_DELETE_CHAR : { const char* szName = packet->u.client_delete_char.szName; int ret = DeleteChar_SQL( c[cn].id, szName ,packet->u.client_delete_char.szSecretKeyCode ); if(ret == 1) { MyLog( LOG_NORMAL, "Success : Character Deleted (%s, ID:%s)", szName, c[cn].id ); RecvHackingUser( c[cn].id, szName, HACKING_DELETE_CHAR_NORMAL_, c[cn].ip_address, "Character Deleted !! Normally.." ); packet->h.header.type = CMD_ACCEPT_DELETE; packet->h.header.size = 1; packet->u.data[0]= 0 ; QueuePacket(c, cn, packet, 1); break; } else { MyLog( LOG_NORMAL, "Delete Fail !"); packet->h.header.type = CMD_INVALID_DB; packet->h.header.size = 1; packet->u.data[0]= 0 ; QueuePacket(c, cn, packet, 1); break; } break; } case CMD_ISTHERE_CHARNAME : RecvIsThereCharName( cn, packet->u.client_isthere_charname.name ); break; case CMD_CHECK_BETA_TEST : CheckBetaIdTest( cn, packet->u.kein.beta_check_id.id ); break; case CMD_SPECIAL_ITEM : RecvUpdateSpecial( &(packet->u.server_special_item) ); break; case CMD_UPDATE_CHAR_DB: { int iRet = RecvUpdateCharDB( &(packet->u.update_char_db) ); if(iRet != 1) { MyLog(0,"RecvUpdateCharDB Failed"); } }break; case CMD_UPDATE_BINARY_DATA0 : { int iRet = RecvUpdateBinaryData( &(packet->u.server_update_binary_data0) ); if(iRet != 1) { MyLog(0,"RecvUpdateBinaryData Failed"); } }break; case CMD_UPDATE_BINARY_DATA1 : { int iRet = RecvUpdateBinaryData1( &(packet->u.server_update_binary_data1) ); if(iRet != 1) { MyLog(0,"RecvUpdateBinaryData1 Failed"); } }break; case CMD_UPDATE_SCRIPT_DATA : { int iRet = RecvUpdateScriptData( &(packet->u.server_update_script_data) ); if(iRet != 1) { MyLog(0,"RecvUpdateScriptData Failed"); } }break; case CMD_UPDATE_INV_DATA : { int iRet = RecvUpdateInvData( &(packet->u.server_update_inv_data) ); if(iRet != 1) { MyLog(0,"RecvUpdateInvData Failed"); } }break; case CMD_UPDATE_ITEM_DATA : { int iRet = RecvUpdateItemData( &(packet->u.server_update_item_data ) ); if(iRet != 1) { MyLog(0,"RecvUpdateItemData Failed"); } }break; case CMD_UPDATE_BANKITEM_DATA : { int iRet = RecvUpdateBankItemData( c, cn, &(packet->u.server_update_bankitem_data)); if(iRet != 1) { MyLog(0,"RecvUpdateBankItemData Failed"); } }break; case CMD_REQ_DELETE_USERID : onepass.DeleteUsedID_SQL_ForPay( packet->u.gs_req_delete_userid.mapname, packet->u.gs_req_delete_userid.id, 0 ); break; case CMD_REQ_INSERT_USERID : { if(!::CheckIsRealName(packet->u.gs_req_insert_userid.id, packet->u.gs_req_insert_userid.name ) ) { break; } t_packet tp; gs_req_insert_userid* pGRIU = &packet->u.gs_req_insert_userid; if( ::UpdateLogintablebyChangeMap( pGRIU->id, pGRIU->mapname )) // LoginTable에 없음.. 즉, 들어갈수 있음.. { tp.h.header.type = CMD_JOINABLE; tp.u.ls_joinable.server_id = packet->u.gs_req_insert_userid.server_id; tp.h.header.size = sizeof( t_ls_joinable ); } else { tp.h.header.type = CMD_UPDATING; tp.u.ls_updating.server_id = packet->u.gs_req_insert_userid.server_id; tp.h.header.size = sizeof( t_ls_updating ); } ::QueuePacket( c, cn, &tp, 1 ); }break; ///////////// network2.h을 위해.. 0224 YGI /////////////// case CMD_CREATE_ABILITY : SendCreateAbility( cn ); break; case CMD_THROW_DICE : SendThrowDice( packet->u.kein.client_throw_dice.type, cn ); break; case CMD_HOW_MANY_IN_MAP : UpdateTotalMapConnections( packet->u.how_many_in_map.map, packet->u.how_many_in_map.how ); break; case CMD_UPDATE_VERY_IMPORTANT_STATUS : RecvUpdateCharacterVeryImportantStatus( &(packet->u.update_very_important_status) ); break; case CMD_UPDATE_VERY_IMPORTANT_TACTICS : RecvUpdateTacticSkillExpData( &(packet->u.update_very_important_tactics )); break; case CMD_ITEM_DURATION_CHANGE : case CMD_TACTICS_PARRYING_EXP : case CMD_REQ_PARTY_MEMBER : case CMD_LEVELUP_POINT : case CMD_DELETE_ITEM : MyLog( LOG_NORMAL, "No Useful Protocol...%d from %d", packet->h.header.type, cn) ; break; case CMD_SEALSTONEFROMKING : RecvSealStoneFromKing( packet->u.sealstone_fromking.nation ); break; case CMD_SEALSTONE_STATUS : RecvSealStoneStatus( packet ); break; case CMD_NATION2NATION_RELATION : RecvNation2NationRelation( cn, &(packet->u.nation2nation_relation) ); break; case CMD_HACKING_USER : { t_hacking_user *tp = &(packet->u.hacking_user ); RecvHackingUser( tp->id, tp->name, tp->type, tp->ip, tp->cause ); } break; case CMD_RARE_ITEM_MAKE_LOG : { RecvRareItemMakeLog( &packet->u.rare_item_make_log ); } break; case CMD_SET_COMMANDER : // 010915 LTS case CMD_SET_WARFIELD_POSSESSION : case CMD_DELETE_EVENT_JOIN : // 020115 LTS case CMD_SAVE_WARNO : // LTS NEW NATIONWAR CheckHandleByNationWar(packet,c,cn); break; //<soto-030504 case CMD_NEW_EVENT: if(LottoDBMgr())LottoDBMgr()->RecvNewEvent(&packet->u.Lotto_Info,cn); break; case CMD_WINNER_CHECK: if(LottoDBMgr())LottoDBMgr()->RecvWinnerCheck(&packet->u.Check_Winner,cn); break; case CMD_DEL_LOTTO_USER: { if (LottoDBMgr()) { LottoDBMgr()->RecvDelUser(&packet->u.Check_Winner, cn); // BBD 040127 인자추가 } break; } case CMD_LOTTERY_INFO: if(LottoDBMgr())LottoDBMgr()->RecvLottery(&packet->u.Lotto_Info,cn); break; case CMD_CHECK_WINNER_MENU: if(LottoDBMgr())LottoDBMgr()->RecvCheckOpenWinnerMenu(&packet->u.Lotto_Winner_Menu,cn); break; //>soto-030504 //<soto-HK case CMD_CAN_BUY: if(LottoDBMgr()) { if(LocalMgr.IsAbleNation(TAIWAN | HONGKONG | CHINA)) { if(GetShopDemon() != NULL) { DebugPrintf("GetShopDemon() Request CMD_CAN_BUY"); GetShopDemon()->RecvCanBuyLotto(&packet->u.Lotto_Buy,cn); } else { DebugPrintf("GetShopDemon() is NULL =====> CMD_CAN_BUY"); } } else { LottoDBMgr()->RecvCanBuyLotto(&packet->u.Lotto_Buy,cn); } } break; case CMD_LOTTO_BUY: if(LottoDBMgr()) { if(LocalMgr.IsAbleNation(TAIWAN | HONGKONG | CHINA)) { if(GetShopDemon() != NULL) { DebugPrintf("GetShopDemon() Request CMD_LOTTO_BUY"); GetShopDemon()->RecvLottoBuy(&packet->u.Lotto_Buy,cn); } else { DebugPrintf("GetShopDemon() is NULL =====> CMD_LOTTO_BUY"); } } else { LottoDBMgr()->RecvLottoBuy(&packet->u.Lotto_Buy); } } else { } break; //>soto-HK //<soto-Lotto추가 case CMD_LOTTO_SEEK: { if(LottoDBMgr()) { LottoDBMgr()->RecvLottoSeek(&packet->u.Lotto_Seek,cn); } } break; //>soto-Lotto추가. default : { // 0308 YGI int msg = CheckHandleByKein( packet, c, cn ); if(msg == 1) { break; } else { if(HandleCommand2(c, dwIndex, packet, dwUserID, cn))//020505 lsw { break; } else { MyLog( LOG_NORMAL, "ERROR : Unknown Protocol(%d) dwIndex:%d, dwUserID:%d, cn:%d ip:%d", packet->h.header.type, dwIndex, dwUserID, cn, c[cn].ip_address ); return msg; } } } } if( debug_SavePacketExeTimeIng() ) { if( ttype != CMD_NONE ) { { DWORD t = ViewCheckRoutine( 9999 ); if( t < 30 ) { Debug( "%2d:%d:%d %20s[%20s] Recv : %5d- %3d\n", g_hour,g_min,g_sec, c[cn].id, c[cn].name, ttype, t ); } else if( t < 100 ) { Debug( "%2d:%d:%d %20s[%20s] Recv : %5d--- %3d\n", g_hour,g_min,g_sec, c[cn].id, c[cn].name, ttype, t ); } else if( t < 200 ) { Debug( "%2d:%d:%d %20s[%20s] Recv : %5d------ %3d\n", g_hour,g_min,g_sec,c[cn].id, c[cn].name, ttype, t ); } else { Debug( "%2d:%d:%d %20s[%20s] Recv : %5d---------- %3d\n", g_hour,g_min,g_sec, c[cn].id, c[cn].name, ttype, t ); } } } } return(1); }
void Client::SendDisciplineUpdate() { EQApplicationPacket app(OP_DisciplineUpdate, sizeof(Disciplines_Struct)); Disciplines_Struct *d = (Disciplines_Struct*)app.pBuffer; memcpy(d, &m_pp.disciplines, sizeof(m_pp.disciplines)); QueuePacket(&app); }
/// Update the WorldSession (triggered by World update) bool WorldSession::Update(uint32 diff, PacketFilter& updater) { /// Update Timeout timer. UpdateTimeOutTime(diff); ///- Before we process anything: /// If necessary, kick the player from the character select screen if (IsConnectionIdle()) m_Socket->CloseSocket(); ///- Retrieve packets from the receive queue and call the appropriate handlers /// not process packets if socket already closed WorldPacket* packet = NULL; //! Delete packet after processing by default bool deletePacket = true; //! To prevent infinite loop WorldPacket* firstDelayedPacket = NULL; //! If _recvQueue.peek() == firstDelayedPacket it means that in this Update call, we've processed all //! *properly timed* packets, and we're now at the part of the queue where we find //! delayed packets that were re-enqueued due to improper timing. To prevent an infinite //! loop caused by re-enqueueing the same packets over and over again, we stop updating this session //! and continue updating others. The re-enqueued packets will be handled in the next Update call for this session. while (m_Socket && !m_Socket->IsClosed() && !_recvQueue.empty() && _recvQueue.peek(true) != firstDelayedPacket && _recvQueue.next(packet, updater)) { if (packet->GetOpcode() >= NUM_MSG_TYPES) { sLog->outError("SESSION: received non-existed opcode %s (0x%.4X)", LookupOpcodeName(packet->GetOpcode()), packet->GetOpcode()); sScriptMgr->OnUnknownPacketReceive(m_Socket, WorldPacket(*packet)); } else { OpcodeHandler &opHandle = opcodeTable[packet->GetOpcode()]; try { switch (opHandle.status) { case STATUS_LOGGEDIN: if (!_player) { // skip STATUS_LOGGEDIN opcode unexpected errors if player logout sometime ago - this can be network lag delayed packets //! If player didn't log out a while ago, it means packets are being sent while the server does not recognize //! the client to be in world yet. We will re-add the packets to the bottom of the queue and process them later. if (!m_playerRecentlyLogout) { //! Prevent infinite loop if (!firstDelayedPacket) firstDelayedPacket = packet; //! Because checking a bool is faster than reallocating memory deletePacket = false; QueuePacket(packet); //! Log sLog->outDebug(LOG_FILTER_NETWORKIO, "Re-enqueueing packet with opcode %s (0x%.4X) with with status STATUS_LOGGEDIN. " "Player is currently not in world yet.", opHandle.name, packet->GetOpcode()); } } else if (_player->IsInWorld()) { sScriptMgr->OnPacketReceive(m_Socket, WorldPacket(*packet)); (this->*opHandle.handler)(*packet); if (sLog->IsOutDebug() && packet->rpos() < packet->wpos()) LogUnprocessedTail(packet); } // lag can cause STATUS_LOGGEDIN opcodes to arrive after the player started a transfer break; case STATUS_LOGGEDIN_OR_RECENTLY_LOGGOUT: if (!_player && !m_playerRecentlyLogout) LogUnexpectedOpcode(packet, "STATUS_LOGGEDIN_OR_RECENTLY_LOGGOUT", "the player has not logged in yet and not recently logout"); else { // not expected _player or must checked in packet handler sScriptMgr->OnPacketReceive(m_Socket, WorldPacket(*packet)); (this->*opHandle.handler)(*packet); if (sLog->IsOutDebug() && packet->rpos() < packet->wpos()) LogUnprocessedTail(packet); } break; case STATUS_TRANSFER: if (!_player) LogUnexpectedOpcode(packet, "STATUS_TRANSFER", "the player has not logged in yet"); else if (_player->IsInWorld()) LogUnexpectedOpcode(packet, "STATUS_TRANSFER", "the player is still in world"); else { sScriptMgr->OnPacketReceive(m_Socket, WorldPacket(*packet)); (this->*opHandle.handler)(*packet); if (sLog->IsOutDebug() && packet->rpos() < packet->wpos()) LogUnprocessedTail(packet); } break; case STATUS_AUTHED: // prevent cheating with skip queue wait if (m_inQueue) { LogUnexpectedOpcode(packet, "STATUS_AUTHED", "the player not pass queue yet"); break; } // single from authed time opcodes send in to after logout time // and before other STATUS_LOGGEDIN_OR_RECENTLY_LOGGOUT opcodes. if (packet->GetOpcode() != CMSG_SET_ACTIVE_VOICE_CHANNEL) m_playerRecentlyLogout = false; sScriptMgr->OnPacketReceive(m_Socket, WorldPacket(*packet)); (this->*opHandle.handler)(*packet); if (sLog->IsOutDebug() && packet->rpos() < packet->wpos()) LogUnprocessedTail(packet); break; case STATUS_NEVER: sLog->outError("SESSION (account: %u, guidlow: %u, char: %s): received not allowed opcode %s (0x%.4X)", GetAccountId(), m_GUIDLow, _player ? _player->GetName() : "<none>", LookupOpcodeName(packet->GetOpcode()), packet->GetOpcode()); break; case STATUS_UNHANDLED: sLog->outDebug(LOG_FILTER_NETWORKIO, "SESSION (account: %u, guidlow: %u, char: %s): received not handled opcode %s (0x%.4X)", GetAccountId(), m_GUIDLow, _player ? _player->GetName() : "<none>", LookupOpcodeName(packet->GetOpcode()), packet->GetOpcode()); break; } } catch(ByteBufferException &) { sLog->outError("WorldSession::Update ByteBufferException occured while parsing a packet (opcode: %u) from client %s, accountid=%i. Skipped packet.", packet->GetOpcode(), GetRemoteAddress().c_str(), GetAccountId()); if (sLog->IsOutDebug()) { sLog->outDebug(LOG_FILTER_NETWORKIO, "Dumping error causing packet:"); packet->hexlike(); } } } if (deletePacket) delete packet; } if (m_Socket && !m_Socket->IsClosed() && _warden) _warden->Update(); ProcessQueryCallbacks(); //check if we are safe to proceed with logout //logout procedure should happen only in World::UpdateSessions() method!!! if (updater.ProcessLogout()) { time_t currTime = time(NULL); ///- If necessary, log the player out if (ShouldLogOut(currTime) && !m_playerLoading) LogoutPlayer(true); if (m_Socket && GetPlayer() && _warden) _warden->Update(); ///- Cleanup socket pointer if need if (m_Socket && m_Socket->IsClosed()) { m_Socket->RemoveReference(); m_Socket = NULL; } if (!m_Socket) return false; //Will remove this session from the world session map } return true; }
void Client::SetLevel(uint8 set_level, bool command) { if (GetEXPForLevel(set_level) == 0xFFFFFFFF) { LogFile->write(EQEMuLog::Error,"Client::SetLevel() GetEXPForLevel(%i) = 0xFFFFFFFF", set_level); return; } EQApplicationPacket* outapp = new EQApplicationPacket(OP_LevelUpdate, sizeof(LevelUpdate_Struct)); LevelUpdate_Struct* lu = (LevelUpdate_Struct*)outapp->pBuffer; lu->level = set_level; if(m_pp.level2 != 0) lu->level_old = m_pp.level2; else lu->level_old = level; level = set_level; if(IsRaidGrouped()) { Raid *r = this->GetRaid(); if(r){ r->UpdateLevel(GetName(), set_level); } } if(set_level > m_pp.level2) { if(m_pp.level2 == 0) m_pp.points += 5; else m_pp.points += (5 * (set_level - m_pp.level2)); m_pp.level2 = set_level; } if(set_level > m_pp.level) { parse->EventPlayer(EVENT_LEVEL_UP, this, "", 0); } m_pp.level = set_level; if (command){ m_pp.exp = GetEXPForLevel(set_level); Message(15, "Welcome to level %i!", set_level); lu->exp = 0; } else { float tmpxp = (float) ( (float) m_pp.exp - GetEXPForLevel( GetLevel() )) / ( (float) GetEXPForLevel(GetLevel()+1) - GetEXPForLevel(GetLevel())); lu->exp = (uint32)(330.0f * tmpxp); } QueuePacket(outapp); safe_delete(outapp); this->SendAppearancePacket(AT_WhoLevel, set_level); // who level change LogFile->write(EQEMuLog::Normal,"Setting Level for %s to %i", GetName(), set_level); CalcBonuses(); if(!RuleB(Character, HealOnLevel)) { int mhp = CalcMaxHP(); if(GetHP() > mhp) SetHP(mhp); } else { SetHP(CalcMaxHP()); // Why not, lets give them a free heal } DoTributeUpdate(); SendHPUpdate(); SetMana(CalcMaxMana()); UpdateWho(); if(GetMerc()) UpdateMercLevel(); Save(); }