void WorldSession::HandleChannelJoin(WorldPacket& recvPacket) { CHECK_INWORLD_RETURN CHECK_PACKET_SIZE(recvPacket, 1); std::string channelname, pass; uint32 channel_id; recvPacket >> channel_id; recvPacket.readBit(); // has voice recvPacket.readBit(); // zone update uint8 channelLength = recvPacket.readBits(8); uint8 passwordLength = recvPacket.readBits(8); channelname = recvPacket.ReadString(channelLength); pass = recvPacket.ReadString(passwordLength); if (sWorld.settings.gm.gmClientChannelName.size() && !stricmp(sWorld.settings.gm.gmClientChannelName.c_str(), channelname.c_str()) && !GetPermissionCount()) return; Channel* channel = channelmgr.GetCreateChannel(channelname.c_str(), _player, channel_id); if (channel == nullptr) return; channel->AttemptJoin(_player, pass.c_str()); LogDebugFlag(LF_OPCODE, "ChannelJoin %s", channelname.c_str()); }
void WorldSession::nothingToHandle(WorldPacket& recv_data) { if (recv_data.isEmpty() == false) { LogDebugFlag(LF_OPCODE, "Opcode %s (0x%.4X) received. Apply nothingToHandle handler but size is %u!", getOpcodeName(recv_data.GetOpcode()).c_str(), recv_data.GetOpcode(), recv_data.size()); } }
void WorldSession::HandleUpdateProjectilePosition(WorldPacket& recv_data) { uint64_t casterGuid; // guid of the caster uint32_t spellId; // spell ID of casted spell uint8_t castCount; // count how many times it is/was cast float x, y, z; // missile hit position casterGuid = recv_data.unpackGUID(); recv_data >> spellId; recv_data >> castCount; recv_data >> x; recv_data >> y; recv_data >> z; LogDebugFlag(LF_OPCODE, "Recieved spell: %u, count: %i, position: x(%f) y(%f) z(%f)", spellId, castCount, x, y, z); SpellInfo* spell = Spell::checkAndReturnSpellEntry(spellId); if (!spell || spell->ai_target_type == TARGET_FLAG_DEST_LOCATION) return; WorldPacket data(SMSG_SET_PROJECTILE_POSITION, 21); data << uint64_t(casterGuid); data << uint8_t(castCount); data << float(x); data << float(y); data << float(z); SendPacket(&data); }
void WorldSession::HandleCancelAutoRepeatSpellOpcode(WorldPacket& /*recvPacket*/) { LogDebugFlag(LF_OPCODE, "Received CMSG_CANCEL_AUTO_REPEAT_SPELL message."); //on original we automatically enter combat when creature got close to us // GetPlayer()->GetSession()->OutPacket(SMSG_CANCEL_COMBAT); _player->interruptSpellWithSpellType(CURRENT_AUTOREPEAT_SPELL); }
uint8 WorldSession::Update(uint32 InstanceID) { m_currMsTime = Util::getMSTime(); if (!((++_updatecount) % 2) && _socket) _socket->UpdateQueuedPackets(); WorldPacket* packet; OpcodeHandler* Handler; if (InstanceID != instanceId) { // We're being updated by the wrong thread. // "Remove us!" - 2 return 2; } // Socket disconnection. if (!_socket) { // Check if the player is in the process of being moved. We can't // delete him // if we are. if (_player && _player->m_beingPushed) { // Abort.. return 0; } if (!_logoutTime) _logoutTime = m_currMsTime + PLAYER_LOGOUT_DELAY; /* if (_player && _player->DuelingWith) _player->EndDuel(DUEL_WINNER_RETREAT); bDeleted = true; LogoutPlayer(true); // 1 - Delete session completely. return 1; */ } while ((packet = _recvQueue.Pop()) != 0) { ARCEMU_ASSERT(packet != NULL); if (packet->GetOpcode() >= NUM_MSG_TYPES) { LogDebugFlag(LF_OPCODE, "[Session] Received out of range packet with opcode 0x%.4X", packet->GetOpcode()); } else { Handler = &WorldPacketHandlers[packet->GetOpcode()]; if (Handler->status == STATUS_LOGGEDIN && !_player && Handler->handler != 0) { LogDebugFlag(LF_OPCODE, "[Session] Received unexpected/wrong state packet with opcode %s (0x%.4X)", getOpcodeName(packet->GetOpcode()).c_str(), packet->GetOpcode()); } else { // Valid Packet :> if (Handler->handler == 0) { LogDebugFlag(LF_OPCODE, "[Session] Received unhandled packet with opcode %s (0x%.4X)", getOpcodeName(packet->GetOpcode()).c_str(), packet->GetOpcode()); } else { (this->*Handler->handler)(*packet); } } } delete packet; if (InstanceID != instanceId) { // If we hit this -> means a packet has changed our map. return 2; } if (bDeleted) { return 1; } } if (InstanceID != instanceId) { // If we hit this -> means a packet has changed our map. return 2; } if (_logoutTime && (m_currMsTime >= _logoutTime) && instanceId == InstanceID) { // Check if the player is in the process of being moved. We can't // delete him // if we are. if (_player && _player->m_beingPushed) { // Abort.. return 0; } if (_socket == NULL) { bDeleted = true; LogoutPlayer(true); return 1; } else LogoutPlayer(true); } if (m_lastPing + WORLDSOCKET_TIMEOUT < (uint32)UNIXTIME) { // Check if the player is in the process of being moved. We can't // delete him // if we are. if (_player && _player->m_beingPushed) { // Abort.. return 0; } // ping timeout! if (_socket != NULL) { Disconnect(); _socket = NULL; } m_lastPing = (uint32)UNIXTIME; // Prevent calling this code over and // over. if (!_logoutTime) _logoutTime = m_currMsTime + PLAYER_LOGOUT_DELAY; } return 0; }
void SpellFactoryMgr::LoadSpellAreas() { mSpellAreaMap.clear(); mSpellAreaForQuestMap.clear(); mSpellAreaForActiveQuestMap.clear(); mSpellAreaForQuestEndMap.clear(); mSpellAreaForAuraMap.clear(); // 0 1 2 3 4 5 6 7 8 QueryResult* result = WorldDatabase.Query("SELECT spell, area, quest_start, quest_start_active, quest_end, aura_spell, racemask, gender, autocast FROM spell_area"); if (!result) { LOG_DETAIL("Loaded 0 spell area requirements. DB table `spell_area` is empty."); return; } uint32 pCount = 0; do { Field* fields = result->Fetch(); uint32 spell = fields[0].GetUInt32(); SpellArea spellArea; spellArea.spellId = spell; spellArea.areaId = fields[1].GetUInt32(); spellArea.questStart = fields[2].GetUInt32(); spellArea.questStartCanActive = fields[3].GetBool(); spellArea.questEnd = fields[4].GetUInt32(); spellArea.auraSpell = fields[5].GetInt32(); spellArea.raceMask = fields[6].GetUInt32(); spellArea.gender = Gender(fields[7].GetUInt8()); spellArea.autocast = fields[8].GetBool(); { bool ok = true; SpellAreaMapBounds sa_bounds = GetSpellAreaMapBounds(spellArea.spellId); for (SpellAreaMap::const_iterator itr = sa_bounds.first; itr != sa_bounds.second; ++itr) { if (spellArea.spellId != itr->second.spellId) continue; if (spellArea.areaId != itr->second.areaId) continue; if (spellArea.questStart != itr->second.questStart) continue; if (spellArea.auraSpell != itr->second.auraSpell) continue; if ((spellArea.raceMask & itr->second.raceMask) == 0) continue; if (spellArea.gender != itr->second.gender) continue; // duplicate by requirements ok = false; break; } if (!ok) { LOG_ERROR("Spell %u listed in `spell_area` already listed with similar requirements.", spell); continue; } } /* if (spellArea.areaId && !AreaTriggerStorage.LookupEntry(spellArea.areaId)) { printf("Spell %u listed in `spell_area` have wrong area (%u) requirement \n", spell, spellArea.areaId); continue; } */ if (spellArea.questStart && !sMySQLStore.getQuestProperties(spellArea.questStart)) { LOG_ERROR("Spell %u listed in `spell_area` have wrong start quest (%u) requirement.", spell, spellArea.questStart); continue; } if (spellArea.questEnd) { if (!sMySQLStore.getQuestProperties(spellArea.questEnd)) { LOG_ERROR("Spell %u listed in `spell_area` have wrong end quest (%u) requirement.", spell, spellArea.questEnd); continue; } if (spellArea.questEnd == spellArea.questStart && !spellArea.questStartCanActive) { LOG_ERROR("Spell %u listed in `spell_area` have quest (%u) requirement for start and end in same time.", spell, spellArea.questEnd); continue; } } if (spellArea.auraSpell) { SpellInfo const* spellInfo = sSpellCustomizations.GetSpellInfo(abs(spellArea.auraSpell)); if (!spellInfo) { LOG_ERROR("Spell %u listed in `spell_area` have wrong aura spell (%u) requirement.", spell, abs(spellArea.auraSpell)); continue; } if (uint32(abs(spellArea.auraSpell)) == spellArea.spellId) { LogDebugFlag(LF_SPELL, "Spell %u listed in `spell_area` have aura spell (%u) requirement for itself.", spell, abs(spellArea.auraSpell)); continue; } // not allow autocast chains by auraSpell field (but allow use as alternative if not present) if (spellArea.autocast && spellArea.auraSpell > 0) { bool chain = false; SpellAreaForAuraMapBounds saBound = GetSpellAreaForAuraMapBounds(spellArea.spellId); for (SpellAreaForAuraMap::const_iterator itr = saBound.first; itr != saBound.second; ++itr) { if (itr->second->autocast && itr->second->auraSpell > 0) { chain = true; break; } } if (chain) { LogDebugFlag(LF_SPELL, "Spell %u listed in `spell_area` have aura spell (%u) requirement that itself autocast from aura.", spell, spellArea.auraSpell); continue; } SpellAreaMapBounds saBound2 = GetSpellAreaMapBounds(spellArea.auraSpell); for (SpellAreaMap::const_iterator itr2 = saBound2.first; itr2 != saBound2.second; ++itr2) { if (itr2->second.autocast && itr2->second.auraSpell > 0) { chain = true; break; } } if (chain) { LogDebugFlag(LF_SPELL, "Spell %u listed in `spell_area` have aura spell (%u) requirement that itself autocast from aura.", spell, spellArea.auraSpell); continue; } } } if (spellArea.raceMask && (spellArea.raceMask & RACEMASK_ALL_PLAYABLE) == 0) { LOG_ERROR("Spell %u listed in `spell_area` have wrong race mask (%u) requirement.", spell, spellArea.raceMask); continue; } if (spellArea.gender != GENDER_NONE && spellArea.gender != GENDER_FEMALE && spellArea.gender != GENDER_MALE) { LOG_ERROR("Spell %u listed in `spell_area` have wrong gender (%u) requirement.", spell, spellArea.gender); continue; } SpellArea const* sa = &mSpellAreaMap.insert(SpellAreaMap::value_type(spell, spellArea))->second; // for search by current zone/subzone at zone/subzone change if (spellArea.areaId) mSpellAreaForAreaMap.insert(SpellAreaForAreaMap::value_type(spellArea.areaId, sa)); // for search at quest start/reward if (spellArea.questStart) { if (spellArea.questStartCanActive) mSpellAreaForActiveQuestMap.insert(SpellAreaForQuestMap::value_type(spellArea.questStart, sa)); else mSpellAreaForQuestMap.insert(SpellAreaForQuestMap::value_type(spellArea.questStart, sa)); } // for search at quest start/reward if (spellArea.questEnd) mSpellAreaForQuestEndMap.insert(SpellAreaForQuestMap::value_type(spellArea.questEnd, sa)); // for search at aura apply if (spellArea.auraSpell) mSpellAreaForAuraMap.insert(SpellAreaForAuraMap::value_type(abs(spellArea.auraSpell), sa)); ++pCount; } while (result->NextRow()); delete result; LOG_DETAIL("Loaded %u spell area requirements.", pCount); }