diff options
author | silinoron <silinoron@encore> | 2010-12-29 20:20:09 -0800 |
---|---|---|
committer | silinoron <silinoron@encore> | 2010-12-29 20:20:09 -0800 |
commit | e522fbe7ce86b865dbc86cdfde429e02620822b3 (patch) | |
tree | ae50f9c84cc01cbb09eedc7638e04237d7148e6b /src | |
parent | c8adcc95f9046235e6ce6ceac98324b406cbebf9 (diff) |
Core/WorldSession: Cleanup.
Diffstat (limited to 'src')
-rwxr-xr-x | src/server/game/Server/WorldSession.cpp | 213 |
1 files changed, 82 insertions, 131 deletions
diff --git a/src/server/game/Server/WorldSession.cpp b/src/server/game/Server/WorldSession.cpp index 1437ae403f5..bff65566ac3 100755 --- a/src/server/game/Server/WorldSession.cpp +++ b/src/server/game/Server/WorldSession.cpp @@ -42,19 +42,20 @@ #include "ScriptMgr.h" #include "Transport.h" -bool MapSessionFilter::Process(WorldPacket * packet) +bool MapSessionFilter::Process(WorldPacket *packet) { - OpcodeHandler const& opHandle = opcodeTable[packet->GetOpcode()]; + OpcodeHandler const &opHandle = opcodeTable[packet->GetOpcode()]; + //let's check if our opcode can be really processed in Map::Update() - if(opHandle.packetProcessing == PROCESS_INPLACE) + if (opHandle.packetProcessing == PROCESS_INPLACE) return true; //we do not process thread-unsafe packets - if(opHandle.packetProcessing == PROCESS_THREADUNSAFE) + if (opHandle.packetProcessing == PROCESS_THREADUNSAFE) return false; - Player * plr = m_pSession->GetPlayer(); - if(!plr) + Player *plr = m_pSession->GetPlayer(); + if (!plr) return false; //in Map::Update() we do not process packets where player is not in world! @@ -63,20 +64,20 @@ bool MapSessionFilter::Process(WorldPacket * packet) //we should process ALL packets when player is not in world/logged in //OR packet handler is not thread-safe! -bool WorldSessionFilter::Process(WorldPacket* packet) +bool WorldSessionFilter::Process(WorldPacket *packet) { - OpcodeHandler const& opHandle = opcodeTable[packet->GetOpcode()]; + OpcodeHandler const &opHandle = opcodeTable[packet->GetOpcode()]; //check if packet handler is supposed to be safe - if(opHandle.packetProcessing == PROCESS_INPLACE) + if (opHandle.packetProcessing == PROCESS_INPLACE) return true; //thread-unsafe packets should be processed in World::UpdateSessions() - if(opHandle.packetProcessing == PROCESS_THREADUNSAFE) + if (opHandle.packetProcessing == PROCESS_THREADUNSAFE) return true; //no player attached? -> our client! ^^ - Player * plr = m_pSession->GetPlayer(); - if(!plr) + Player *plr = m_pSession->GetPlayer(); + if (!plr) return true; //lets process all packets for non-in-the-world player @@ -118,33 +119,32 @@ WorldSession::~WorldSession() } ///- empty incoming packet queue - WorldPacket* packet = NULL; + WorldPacket *packet = NULL; while (_recvQueue.next(packet)) delete packet; LoginDatabase.PExecute("UPDATE account SET online = 0 WHERE id = %u;", GetAccountId()); } -void WorldSession::SizeError(WorldPacket const& packet, uint32 size) const +void WorldSession::SizeError(WorldPacket const &packet, uint32 size) const { - sLog->outError("Client (account %u) send packet %s (%u) with size " SIZEFMTD " but expected %u (attempt crash server?), skipped", - GetAccountId(),LookupOpcodeName(packet.GetOpcode()),packet.GetOpcode(),packet.size(),size); + sLog->outError("Client (account %u) send packet %s (%u) with size " SIZEFMTD " but expected %u (attempt to crash server?), skipped", + GetAccountId(), LookupOpcodeName(packet.GetOpcode()), packet.GetOpcode(), packet.size(), size); } /// Get the player name -char const* WorldSession::GetPlayerName() const +char const *WorldSession::GetPlayerName() const { return GetPlayer() ? GetPlayer()->GetName() : "<none>"; } /// Send a packet to the client -void WorldSession::SendPacket(WorldPacket const* packet) +void WorldSession::SendPacket(WorldPacket const *packet) { if (!m_Socket) return; - #ifdef TRINITY_DEBUG - +#ifdef TRINITY_DEBUG // Code for network use statistic static uint64 sendPacketCount = 0; static uint64 sendPacketBytes = 0; @@ -176,21 +176,20 @@ void WorldSession::SendPacket(WorldPacket const* packet) sendLastPacketCount = 1; sendLastPacketBytes = packet->wpos(); // wpos is real written size } - - #endif // !TRINITY_DEBUG +#endif // !TRINITY_DEBUG if (m_Socket->SendPacket (*packet) == -1) m_Socket->CloseSocket (); } /// Add an incoming packet to the queue -void WorldSession::QueuePacket(WorldPacket* new_packet) +void WorldSession::QueuePacket(WorldPacket *new_packet) { _recvQueue.add(new_packet); } /// Logging helper for unexpected opcodes -void WorldSession::LogUnexpectedOpcode(WorldPacket* packet, const char *reason) +void WorldSession::LogUnexpectedOpcode(WorldPacket *packet, const char *reason) { sLog->outError("SESSION: received unexpected opcode %s (0x%.4X) %s", LookupOpcodeName(packet->GetOpcode()), @@ -202,11 +201,8 @@ void WorldSession::LogUnexpectedOpcode(WorldPacket* packet, const char *reason) void WorldSession::LogUnprocessedTail(WorldPacket *packet) { sLog->outError("SESSION: opcode %s (0x%.4X) have unprocessed tail data (read stop at %u from %u)", - LookupOpcodeName(packet->GetOpcode()), - packet->GetOpcode(), - uint32(packet->rpos()), uint32(packet->wpos())); - - packet->print_storage(); + LookupOpcodeName(packet->GetOpcode()), packet->GetOpcode(), uint32(packet->rpos()), uint32(packet->wpos())); + packet->print_storage(); } /// Update the WorldSession (triggered by World update) @@ -222,26 +218,17 @@ bool WorldSession::Update(uint32 diff, PacketFilter& updater) ///- Retrieve packets from the receive queue and call the appropriate handlers /// not process packets if socket already closed - WorldPacket* packet = NULL; + WorldPacket *packet = NULL; while (m_Socket && !m_Socket->IsClosed() && _recvQueue.next(packet, updater)) { - /*#if 1 - sLog->outError("MOEP: %s (0x%.4X)", - LookupOpcodeName(packet->GetOpcode()), - packet->GetOpcode()); - #endif*/ - if (packet->GetOpcode() >= NUM_MSG_TYPES) { - sLog->outError("SESSION: received non-existed opcode %s (0x%.4X)", - LookupOpcodeName(packet->GetOpcode()), - packet->GetOpcode()); - + 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()]; + OpcodeHandler &opHandle = opcodeTable[packet->GetOpcode()]; try { switch (opHandle.status) @@ -306,14 +293,10 @@ bool WorldSession::Update(uint32 diff, PacketFilter& updater) LogUnprocessedTail(packet); break; case STATUS_NEVER: - sLog->outError("SESSION: received not allowed opcode %s (0x%.4X)", - LookupOpcodeName(packet->GetOpcode()), - packet->GetOpcode()); + sLog->outError("SESSION: received not allowed opcode %s (0x%.4X)", LookupOpcodeName(packet->GetOpcode()), packet->GetOpcode()); break; case STATUS_UNHANDLED: - sLog->outDebug("SESSION: received not handled opcode %s (0x%.4X)", - LookupOpcodeName(packet->GetOpcode()), - packet->GetOpcode()); + sLog->outDebug("SESSION: received not handled opcode %s (0x%.4X)", LookupOpcodeName(packet->GetOpcode()), packet->GetOpcode()); break; } } @@ -336,22 +319,22 @@ bool WorldSession::Update(uint32 diff, PacketFilter& updater) //check if we are safe to proceed with logout //logout procedure should happen only in World::UpdateSessions() method!!! - if(updater.ProcessLogout()) + if (updater.ProcessLogout()) { - time_t currTime = time(NULL); - ///- If necessary, log the player out - if (ShouldLogOut(currTime) && !m_playerLoading) - LogoutPlayer(true); + 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()) - { - m_Socket->RemoveReference(); - m_Socket = NULL; - } + ///- 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 + if (!m_Socket) + return false; //Will remove this session from the world session map } return true; } @@ -386,17 +369,13 @@ void WorldSession::LogoutPlayer(bool Save) _player->RemoveAllAurasOnDeath(); // build set of player who attack _player or who have pet attacking of _player - std::set<Player*> aset; + std::set<Player *> aset; for (Unit::AttackerSet::const_iterator itr = _player->getAttackers().begin(); itr != _player->getAttackers().end(); ++itr) { - Unit* owner = (*itr)->GetOwner(); // including player controlled case - if (owner) - { - if (owner->GetTypeId() == TYPEID_PLAYER) - aset.insert(owner->ToPlayer()); - } - else - if ((*itr)->GetTypeId() == TYPEID_PLAYER) + Unit *owner = (*itr)->GetOwner(); // including player controlled case + if (owner && owner->GetTypeId() == TYPEID_PLAYER) + aset.insert(owner->ToPlayer()); + else if ((*itr)->GetTypeId() == TYPEID_PLAYER) aset.insert((Player*)(*itr)); } @@ -406,24 +385,24 @@ void WorldSession::LogoutPlayer(bool Save) _player->RepopAtGraveyard(); // give honor to all attackers from set like group case - for (std::set<Player*>::const_iterator itr = aset.begin(); itr != aset.end(); ++itr) - (*itr)->RewardHonor(_player,aset.size()); + for (std::set<Player *>::const_iterator itr = aset.begin(); itr != aset.end(); ++itr) + (*itr)->RewardHonor(_player, aset.size()); // give bg rewards and update counters like kill by first from attackers // this can't be called for all attackers. if (!aset.empty()) if (Battleground *bg = _player->GetBattleground()) - bg->HandleKillPlayer(_player,*aset.begin()); + bg->HandleKillPlayer(_player, *aset.begin()); } else if (_player->HasAuraType(SPELL_AURA_SPIRIT_OF_REDEMPTION)) { // this will kill character by SPELL_AURA_SPIRIT_OF_REDEMPTION _player->RemoveAurasByType(SPELL_AURA_MOD_SHAPESHIFT); - //_player->SetDeathPvP(*); set at SPELL_AURA_SPIRIT_OF_REDEMPTION apply time _player->KillPlayer(); _player->BuildPlayerRepop(); _player->RepopAtGraveyard(); } + //drop a flag if player is carrying it if (Battleground *bg = _player->GetBattleground()) bg->EventPlayerLoggedOut(_player); @@ -501,7 +480,7 @@ void WorldSession::LogoutPlayer(bool Save) // calls to GetMap in this case may cause crashes _player->CleanupsBeforeDelete(); sLog->outChar("Account: %d (IP: %s) Logout Character:[%s] (GUID: %u)", GetAccountId(), GetRemoteAddress().c_str(), _player->GetName() ,_player->GetGUIDLow()); - Map* _map = _player->GetMap(); + Map *_map = _player->GetMap(); _map->Remove(_player, true); SetPlayer(NULL); // deleted in Remove call @@ -511,8 +490,7 @@ void WorldSession::LogoutPlayer(bool Save) ///- Since each account can only have one online character at any given time, ensure all characters for active account are marked as offline //No SQL injection as AccountId is uint32 - CharacterDatabase.PExecute("UPDATE characters SET online = 0 WHERE account = '%u'", - GetAccountId()); + CharacterDatabase.PExecute("UPDATE characters SET online = 0 WHERE account = '%u'", GetAccountId()); sLog->outDebug("SESSION: Sent SMSG_LOGOUT_COMPLETE Message"); } @@ -526,7 +504,7 @@ void WorldSession::LogoutPlayer(bool Save) void WorldSession::KickPlayer() { if (m_Socket) - m_Socket->CloseSocket (); + m_Socket->CloseSocket(); } void WorldSession::SendNotification(const char *format,...) @@ -534,13 +512,13 @@ void WorldSession::SendNotification(const char *format,...) if (format) { va_list ap; - char szStr [1024]; + char szStr[1024]; szStr[0] = '\0'; va_start(ap, format); vsnprintf(szStr, 1024, format, ap); va_end(ap); - WorldPacket data(SMSG_NOTIFICATION, (strlen(szStr)+1)); + WorldPacket data(SMSG_NOTIFICATION, (strlen(szStr) + 1)); data << szStr; SendPacket(&data); } @@ -548,53 +526,45 @@ void WorldSession::SendNotification(const char *format,...) void WorldSession::SendNotification(uint32 string_id,...) { - char const* format = GetTrinityString(string_id); + char const *format = GetTrinityString(string_id); if (format) { va_list ap; - char szStr [1024]; + char szStr[1024]; szStr[0] = '\0'; va_start(ap, string_id); vsnprintf(szStr, 1024, format, ap); va_end(ap); - WorldPacket data(SMSG_NOTIFICATION, (strlen(szStr)+1)); + WorldPacket data(SMSG_NOTIFICATION, (strlen(szStr) + 1)); data << szStr; SendPacket(&data); } } -const char * WorldSession::GetTrinityString(int32 entry) const +const char *WorldSession::GetTrinityString(int32 entry) const { return sObjectMgr->GetTrinityString(entry, GetSessionDbLocaleIndex()); } void WorldSession::Handle_NULL(WorldPacket& recvPacket) { - sLog->outError("SESSION: received unhandled opcode %s (0x%.4X)", - LookupOpcodeName(recvPacket.GetOpcode()), - recvPacket.GetOpcode()); + sLog->outError("SESSION: received unhandled opcode %s (0x%.4X)", LookupOpcodeName(recvPacket.GetOpcode()), recvPacket.GetOpcode()); } void WorldSession::Handle_EarlyProccess(WorldPacket& recvPacket) { - sLog->outError("SESSION: received opcode %s (0x%.4X) that must be processed in WorldSocket::OnRead", - LookupOpcodeName(recvPacket.GetOpcode()), - recvPacket.GetOpcode()); + sLog->outError("SESSION: received opcode %s (0x%.4X) that must be processed in WorldSocket::OnRead", LookupOpcodeName(recvPacket.GetOpcode()), recvPacket.GetOpcode()); } void WorldSession::Handle_ServerSide(WorldPacket& recvPacket) { - sLog->outError("SESSION: received server-side opcode %s (0x%.4X)", - LookupOpcodeName(recvPacket.GetOpcode()), - recvPacket.GetOpcode()); + sLog->outError("SESSION: received server-side opcode %s (0x%.4X)", LookupOpcodeName(recvPacket.GetOpcode()), recvPacket.GetOpcode()); } void WorldSession::Handle_Deprecated(WorldPacket& recvPacket) { - sLog->outError("SESSION: received deprecated opcode %s (0x%.4X)", - LookupOpcodeName(recvPacket.GetOpcode()), - recvPacket.GetOpcode()); + sLog->outError("SESSION: received deprecated opcode %s (0x%.4X)", LookupOpcodeName(recvPacket.GetOpcode()), recvPacket.GetOpcode()); } void WorldSession::SendAuthWaitQue(uint32 position) @@ -617,7 +587,7 @@ void WorldSession::SendAuthWaitQue(uint32 position) void WorldSession::LoadGlobalAccountData() { - PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_LOAD_ACCOUNT_DATA); + PreparedStatement *stmt = CharacterDatabase.GetPreparedStatement(CHAR_LOAD_ACCOUNT_DATA); stmt->setUInt32(0, GetAccountId()); LoadAccountData(CharacterDatabase.Query(stmt), GLOBAL_CACHE_MASK); } @@ -633,25 +603,22 @@ void WorldSession::LoadAccountData(PreparedQueryResult result, uint32 mask) do { - Field* fields = result->Fetch(); + Field *fields = result->Fetch(); uint32 type = fields[0].GetUInt32(); if (type >= NUM_ACCOUNT_DATA_TYPES) { - sLog->outError("Table `%s` have invalid account data type (%u), ignore.", - mask == GLOBAL_CACHE_MASK ? "account_data" : "character_account_data", type); + sLog->outError("Table `%s` have invalid account data type (%u), ignore.", mask == GLOBAL_CACHE_MASK ? "account_data" : "character_account_data", type); continue; } if ((mask & (1 << type)) == 0) { - sLog->outError("Table `%s` have non appropriate for table account data type (%u), ignore.", - mask == GLOBAL_CACHE_MASK ? "account_data" : "character_account_data", type); + sLog->outError("Table `%s` have non appropriate for table account data type (%u), ignore.", mask == GLOBAL_CACHE_MASK ? "account_data" : "character_account_data", type); continue; } m_accountData[type].Time = fields[1].GetUInt32(); m_accountData[type].Data = fields[2].GetString(); - } while (result->NextRow()); } @@ -687,7 +654,7 @@ void WorldSession::SetAccountData(AccountDataType type, time_t time_, std::strin void WorldSession::SendAccountDataTimes(uint32 mask) { - WorldPacket data(SMSG_ACCOUNT_DATA_TIMES, 4+1+4+8*4); // changed in WotLK + WorldPacket data(SMSG_ACCOUNT_DATA_TIMES, 4 + 1 + 4 + 8 * 4); // changed in WotLK data << uint32(time(NULL)); // unix time of something data << uint8(1); data << uint32(mask); // type mask @@ -699,10 +666,11 @@ void WorldSession::SendAccountDataTimes(uint32 mask) void WorldSession::LoadTutorialsData() { - for (int aX = 0 ; aX < MAX_CHARACTER_TUTORIAL_VALUES ; ++aX) + for (int aX = 0; aX < MAX_CHARACTER_TUTORIAL_VALUES; ++aX) m_Tutorials[ aX ] = 0; - QueryResult result = CharacterDatabase.PQuery("SELECT tut0,tut1,tut2,tut3,tut4,tut5,tut6,tut7 FROM character_tutorial WHERE account = '%u'", GetAccountId()); + // is there a good reason why this isn't a prepared statement? + QueryResult result = CharacterDatabase.PQuery("SELECT tut0, tut1, tut2, tut3, tut4, tut5, tut6, tut7 FROM character_tutorial WHERE account = '%u'", GetAccountId()); if (result) { @@ -726,12 +694,14 @@ void WorldSession::SendTutorialsData() SendPacket(&data); } -void WorldSession::SaveTutorialsData(SQLTransaction& trans) +void WorldSession::SaveTutorialsData(SQLTransaction &trans) { if (!m_TutorialsChanged) return; - uint32 Rows=0; + // should these be prepared as well? + + uint32 Rows = 0; // it's better than rebuilding indexes multiple times QueryResult result = CharacterDatabase.PQuery("SELECT count(*) AS r FROM character_tutorial WHERE account = '%u'", GetAccountId()); if (result) @@ -741,7 +711,7 @@ void WorldSession::SaveTutorialsData(SQLTransaction& trans) trans->PAppend("UPDATE character_tutorial SET tut0='%u', tut1='%u', tut2='%u', tut3='%u', tut4='%u', tut5='%u', tut6='%u', tut7='%u' WHERE account = '%u'", m_Tutorials[0], m_Tutorials[1], m_Tutorials[2], m_Tutorials[3], m_Tutorials[4], m_Tutorials[5], m_Tutorials[6], m_Tutorials[7], GetAccountId()); else - trans->PAppend("INSERT INTO character_tutorial (account,tut0,tut1,tut2,tut3,tut4,tut5,tut6,tut7) VALUES ('%u', '%u', '%u', '%u', '%u', '%u', '%u', '%u', '%u')", GetAccountId(), m_Tutorials[0], m_Tutorials[1], m_Tutorials[2], m_Tutorials[3], m_Tutorials[4], m_Tutorials[5], m_Tutorials[6], m_Tutorials[7]); + trans->PAppend("INSERT INTO character_tutorial (account, tut0, tut1, tut2, tut3, tut4, tut5, tut6, tut7) VALUES ('%u', '%u', '%u', '%u', '%u', '%u', '%u', '%u', '%u')", GetAccountId(), m_Tutorials[0], m_Tutorials[1], m_Tutorials[2], m_Tutorials[3], m_Tutorials[4], m_Tutorials[5], m_Tutorials[6], m_Tutorials[7]); m_TutorialsChanged = false; } @@ -762,9 +732,7 @@ void WorldSession::ReadMovementInfo(WorldPacket &data, MovementInfo *mi) data >> mi->t_seat; if (mi->HasExtraMovementFlag(MOVEMENTFLAG2_INTERPOLATED_MOVEMENT)) - { data >> mi->t_time2; - } if (mi->pos.m_positionX != mi->t_pos.m_positionX) if (GetPlayer()->GetTransport()) @@ -772,9 +740,7 @@ void WorldSession::ReadMovementInfo(WorldPacket &data, MovementInfo *mi) } if (mi->HasMovementFlag(MovementFlags(MOVEMENTFLAG_SWIMMING | MOVEMENTFLAG_FLYING)) || (mi->HasExtraMovementFlag(MOVEMENTFLAG2_ALWAYS_ALLOW_PITCHING))) - { data >> mi->pitch; - } data >> mi->fallTime; @@ -787,9 +753,7 @@ void WorldSession::ReadMovementInfo(WorldPacket &data, MovementInfo *mi) } if (mi->HasMovementFlag(MOVEMENTFLAG_SPLINE_ELEVATION)) - { data >> mi->splineElevation; - } } void WorldSession::WriteMovementInfo(WorldPacket *data, MovementInfo *mi) @@ -811,9 +775,7 @@ void WorldSession::WriteMovementInfo(WorldPacket *data, MovementInfo *mi) } if (mi->HasMovementFlag(MovementFlags(MOVEMENTFLAG_SWIMMING | MOVEMENTFLAG_FLYING)) && mi->HasExtraMovementFlag(MOVEMENTFLAG2_ALWAYS_ALLOW_PITCHING)) - { *data << mi->pitch; - } *data << mi->fallTime; @@ -826,9 +788,7 @@ void WorldSession::WriteMovementInfo(WorldPacket *data, MovementInfo *mi) } if (mi->HasMovementFlag(MOVEMENTFLAG_SPLINE_ELEVATION)) - { *data << mi->splineElevation; - } } void WorldSession::ReadAddonsInfo(WorldPacket &data) @@ -854,7 +814,7 @@ void WorldSession::ReadAddonsInfo(WorldPacket &data) ByteBuffer addonInfo; addonInfo.resize(size); - if (uncompress(const_cast<uint8*>(addonInfo.contents()), &uSize, const_cast<uint8*>(data.contents() + pos), data.size() - pos) == Z_OK) + if (uncompress(const_cast<uint8 *>(addonInfo.contents()), &uSize, const_cast<uint8 *>(data.contents() + pos), data.size() - pos) == Z_OK) { uint32 addonsCount; addonInfo >> addonsCount; // addons count @@ -866,7 +826,7 @@ void WorldSession::ReadAddonsInfo(WorldPacket &data) uint32 crc, unk1; // check next addon data format correctness - if (addonInfo.rpos()+1 > addonInfo.size()) + if (addonInfo.rpos() + 1 > addonInfo.size()) return; addonInfo >> addonName; @@ -954,7 +914,7 @@ void WorldSession::SendAddonsInfo() data.append(addonPublicKey, sizeof(addonPublicKey)); } - data << uint32(/*itr->CRC*/ 0); // TODO: Find out the meaning of this. + data << uint32(0); // TODO: Find out the meaning of this. } uint8 unk3 = 0; // 0 is sent here @@ -968,16 +928,7 @@ void WorldSession::SendAddonsInfo() m_addonsList.clear(); - uint32 count = 0; - data << uint32(count); - /*for (uint32 i = 0; i < count; ++i) - { - uint32 - string (16 bytes) - string (16 bytes) - uint32 - uint32 - }*/ + data << uint32(0); // count for an unknown for loop SendPacket(&data); } |