void WorldSession::HandleLootMasterGiveOpcode( WorldPacket & recv_data ) { CHECK_PACKET_SIZE(recv_data,8+1+8); uint8 slotid; uint64 lootguid, target_playerguid; recv_data >> lootguid >> slotid >> target_playerguid; if(!_player->GetGroup() || _player->GetGroup()->GetLooterGuid() != _player->GetGUID()) { _player->SendLootRelease(GetPlayer()->GetLootGUID()); return; } Player *target = ObjectAccessor::FindPlayer(MAKE_NEW_GUID(target_playerguid, 0, HIGHGUID_PLAYER)); if(!target) return; sLog.outDebug("WorldSession::HandleLootMasterGiveOpcode (CMSG_LOOT_MASTER_GIVE, 0x02A3) Target = [%s].", target->GetName()); if(_player->GetLootGUID() != lootguid) return; Loot *pLoot = NULL; if(IS_CREATURE_GUID(GetPlayer()->GetLootGUID())) { Creature *pCreature = ObjectAccessor::GetCreature(*GetPlayer(), lootguid); if(!pCreature) return; pLoot = &pCreature->loot; } else if(IS_GAMEOBJECT_GUID(GetPlayer()->GetLootGUID())) { GameObject *pGO = ObjectAccessor::GetGameObject(*GetPlayer(), lootguid); if(!pGO) return; pLoot = &pGO->loot; } if(!pLoot) return; if (slotid > pLoot->items.size()) { sLog.outDebug("AutoLootItem: Player %s might be using a hack! (slot %d, size %d)",GetPlayer()->GetName(), slotid, pLoot->items.size()); return; } LootItem& item = pLoot->items[slotid]; ItemPosCountVec dest; uint8 msg = target->CanStoreNewItem( NULL_BAG, NULL_SLOT, dest, item.itemid, item.count ); if ( msg != EQUIP_ERR_OK ) { target->SendEquipError( msg, NULL, NULL ); _player->SendEquipError( msg, NULL, NULL ); // send duplicate of error massage to master looter return; } // not move item from loot to target inventory Item * newitem = target->StoreNewItem( dest, item.itemid, true, item.randomPropertyId ); target->SendNewItem(newitem, uint32(item.count), false, false, true ); // mark as looted item.count=0; item.is_looted=true; pLoot->NotifyItemRemoved(slotid); --pLoot->unlootedCount; }
void WorldSession::HandleOfferPetitionOpcode(WorldPacket& recvData) { TC_LOG_DEBUG("network", "Received opcode CMSG_OFFER_PETITION"); // ok uint8 playerCount = 0; ObjectGuid petitionGuid, playerGuid; uint32 type; Player* player; recvData.read_skip<uint32>(); recvData.ReadGuidMask(playerGuid, 4, 1); petitionGuid[2] = recvData.ReadBit(); playerGuid[6] = recvData.ReadBit(); petitionGuid[1] = recvData.ReadBit(); playerGuid[2] = recvData.ReadBit(); petitionGuid[4] = recvData.ReadBit(); recvData.ReadGuidMask(playerGuid, 3, 7); recvData.ReadGuidMask(petitionGuid, 0, 6); recvData.ReadGuidMask(playerGuid, 5, 0); recvData.ReadGuidMask(petitionGuid, 3, 5, 7); recvData.ReadByteSeq(playerGuid[7]); recvData.ReadGuidBytes(petitionGuid, 1, 4, 2); recvData.ReadByteSeq(playerGuid[6]); recvData.ReadGuidBytes(petitionGuid, 3, 0, 5); recvData.ReadGuidBytes(playerGuid, 0, 2, 5, 3, 4); recvData.ReadByteSeq(petitionGuid[7]); recvData.ReadByteSeq(playerGuid[1]); recvData.ReadByteSeq(petitionGuid[6]); player = ObjectAccessor::FindPlayer(playerGuid); if (!player) return; PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_PETITION_TYPE); stmt->setUInt32(0, GUID_LOPART(petitionGuid)); PreparedQueryResult result = CharacterDatabase.Query(stmt); if (!result) return; Field* fields = result->Fetch(); type = fields[0].GetUInt8(); TC_LOG_DEBUG("network", "OFFER PETITION: type %u, GUID1 %u, to player id: %u", type, GUID_LOPART(petitionGuid), GUID_LOPART(playerGuid)); if (!sWorld->getBoolConfig(CONFIG_ALLOW_TWO_SIDE_INTERACTION_GUILD) && GetPlayer()->GetTeam() != player->GetTeam()) { Guild::SendCommandResult(this, GUILD_COMMAND_CREATE, ERR_GUILD_NOT_ALLIED); return; } if (player->GetGuildId()) { Guild::SendCommandResult(this, GUILD_COMMAND_INVITE, ERR_ALREADY_IN_GUILD_S, _player->GetName()); return; } if (player->GetGuildIdInvited()) { Guild::SendCommandResult(this, GUILD_COMMAND_INVITE, ERR_ALREADY_INVITED_TO_GUILD_S, _player->GetName()); return; } stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_PETITION_SIGNATURE); stmt->setUInt32(0, GUID_LOPART(petitionGuid)); result = CharacterDatabase.Query(stmt); // result == NULL also correct charter without signs if (result) playerCount = uint8(result->GetRowCount()); ObjectGuid* playerGuids = new ObjectGuid[playerCount]; for (uint8 i = 0; i < playerCount; ++i) { Field* fields2 = result->Fetch(); uint32 lowGuid = fields2[0].GetUInt32(); playerGuids[i] = MAKE_NEW_GUID(lowGuid, 0, HIGHGUID_PLAYER); result->NextRow(); } WorldPacket data(SMSG_PETITION_SHOW_SIGNATURES, (9 + 9 + 3 + 4 + playerCount * (9 + 4))); data.WriteBit(playerGuid[1]); data.WriteBit(petitionGuid[3]); data.WriteBit(playerGuid[3]); data.WriteGuidMask(petitionGuid, 4, 0); data.WriteGuidMask(playerGuid, 7, 5); data.WriteGuidMask(petitionGuid, 1, 5, 7); data.WriteGuidMask(playerGuid, 0, 6); data.WriteBit(petitionGuid[6]); data.WriteGuidMask(playerGuid, 2, 4); data.WriteBits(playerCount, 21); for (int i = 0; i < playerCount; i++) { data.WriteGuidMask(playerGuids[i], 2, 0, 4, 7, 5, 1, 6, 3); } data.WriteBit(petitionGuid[2]); data.FlushBits(); for (int i = 0; i < playerCount; i++) { data.WriteGuidBytes(playerGuids[i], 6, 0, 1, 3, 2, 5, 7, 4); data << uint32(1); // Choice ??? Blizzard also stores declined players ??? } data.WriteGuidBytes(petitionGuid, 6, 5, 4); data.WriteByteSeq(playerGuid[4]); data.WriteByteSeq(petitionGuid[1]); data << uint32(GUID_LOPART(petitionGuid)); // guildID data.WriteGuidBytes(petitionGuid, 2, 3, 7); data.WriteGuidBytes(playerGuid, 5, 6, 3, 7, 1, 0); data.WriteByteSeq(petitionGuid[0]); data.WriteByteSeq(playerGuid[2]); delete[] playerGuids; player->GetSession()->SendPacket(&data); }
bool Item::LoadFromDB(uint32 guid, uint64 owner_guid, Field* fields, uint32 entry) { // 0 1 2 3 4 5 6 7 8 9 10 //result = CharacterDatabase.PQuery("SELECT creatorGuid, giftCreatorGuid, count, duration, charges, flags, enchantments, randomPropertyId, durability, playedTime, text FROM item_instance WHERE guid = '%u'", guid); // create item before any checks for store correct guid // and allow use "FSetState(ITEM_REMOVED); SaveToDB();" for deleting item from DB Object::_Create(guid, 0, HIGHGUID_ITEM); // Set entry, MUST be before proto check SetEntry(entry); SetFloatValue(OBJECT_FIELD_SCALE_X, 1.0f); ItemTemplate const* proto = GetTemplate(); if (!proto) return false; // set owner (not if item is only loaded for gbank/auction/mail if (owner_guid != 0) SetOwnerGUID(owner_guid); bool need_save = false; // need explicit save data at load fixes SetUInt64Value(ITEM_FIELD_CREATOR, MAKE_NEW_GUID(fields[0].GetUInt32(), 0, HIGHGUID_PLAYER)); SetUInt64Value(ITEM_FIELD_GIFTCREATOR, MAKE_NEW_GUID(fields[1].GetUInt32(), 0, HIGHGUID_PLAYER)); SetCount(fields[2].GetUInt32()); uint32 duration = fields[3].GetUInt32(); SetUInt32Value(ITEM_FIELD_DURATION, duration); // update duration if need, and remove if not need if ((proto->Duration == 0) != (duration == 0)) { SetUInt32Value(ITEM_FIELD_DURATION, abs(proto->Duration)); need_save = true; } Tokens tokens(fields[4].GetString(), ' ', MAX_ITEM_PROTO_SPELLS); if (tokens.size() == MAX_ITEM_PROTO_SPELLS) for (uint8 i = 0; i < MAX_ITEM_PROTO_SPELLS; ++i) SetSpellCharges(i, atoi(tokens[i])); SetUInt32Value(ITEM_FIELD_FLAGS, fields[5].GetUInt32()); // Remove bind flag for items vs NO_BIND set if (IsSoulBound() && proto->Bonding == NO_BIND) { ApplyModFlag(ITEM_FIELD_FLAGS, ITEM_FLAG_SOULBOUND, false); need_save = true; } std::string enchants = fields[6].GetString(); _LoadIntoDataField(enchants.c_str(), ITEM_FIELD_ENCHANTMENT_1_1, MAX_ENCHANTMENT_SLOT * MAX_ENCHANTMENT_OFFSET); SetInt32Value(ITEM_FIELD_RANDOM_PROPERTIES_ID, fields[7].GetInt16()); // recalculate suffix factor if (GetItemRandomPropertyId() < 0) UpdateItemSuffixFactor(); uint32 durability = fields[8].GetUInt16(); SetUInt32Value(ITEM_FIELD_DURABILITY, durability); // update max durability (and durability) if need SetUInt32Value(ITEM_FIELD_MAXDURABILITY, proto->MaxDurability); if (durability > proto->MaxDurability) { SetUInt32Value(ITEM_FIELD_DURABILITY, proto->MaxDurability); need_save = true; } SetUInt32Value(ITEM_FIELD_CREATE_PLAYED_TIME, fields[9].GetUInt32()); SetText(fields[10].GetString()); if (need_save) // normal item changed state set not work at loading { PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_UPDATE_ITEM_INSTANCE_ON_LOAD); stmt->setUInt32(0, GetUInt32Value(ITEM_FIELD_DURATION)); stmt->setUInt32(1, GetUInt32Value(ITEM_FIELD_FLAGS)); stmt->setUInt32(2, GetUInt32Value(ITEM_FIELD_DURABILITY)); stmt->setUInt32(3, guid); CharacterDatabase.Execute(stmt); } return true; }
void WorldSession::HandleLootMasterGiveOpcode(WorldPacket& recvData) { uint8 slotid; uint64 lootguid, target_playerguid; recvData >> lootguid >> slotid >> target_playerguid; if (!_player->GetGroup() || _player->GetGroup()->GetMasterLooterGuid() != _player->GetGUID() || _player->GetGroup()->GetLootMethod() != MASTER_LOOT) { _player->SendLootRelease(GetPlayer()->GetLootGUID()); return; } Player* target = ObjectAccessor::FindPlayer(MAKE_NEW_GUID(target_playerguid, 0, HIGHGUID_PLAYER)); if (!target) return; TC_LOG_DEBUG("network", "WorldSession::HandleLootMasterGiveOpcode (CMSG_LOOT_MASTER_GIVE, 0x02A3) Target = [%s].", target->GetName().c_str()); if (_player->GetLootGUID() != lootguid) return; if (!_player->IsInRaidWith(target) || !_player->IsInMap(target)) { TC_LOG_INFO("loot", "MasterLootItem: Player %s tried to give an item to ineligible player %s !", GetPlayer()->GetName().c_str(), target->GetName().c_str()); return; } Loot* loot = NULL; if (IS_CRE_OR_VEH_GUID(GetPlayer()->GetLootGUID())) { Creature* creature = GetPlayer()->GetMap()->GetCreature(lootguid); if (!creature) return; loot = &creature->loot; } else if (IS_GAMEOBJECT_GUID(GetPlayer()->GetLootGUID())) { GameObject* pGO = GetPlayer()->GetMap()->GetGameObject(lootguid); if (!pGO) return; loot = &pGO->loot; } if (!loot) return; if (slotid >= loot->items.size() + loot->quest_items.size()) { TC_LOG_DEBUG("loot", "MasterLootItem: Player %s might be using a hack! (slot %d, size %lu)", GetPlayer()->GetName().c_str(), slotid, (unsigned long)loot->items.size()); return; } LootItem& item = slotid >= loot->items.size() ? loot->quest_items[slotid - loot->items.size()] : loot->items[slotid]; ItemPosCountVec dest; InventoryResult msg = target->CanStoreNewItem(NULL_BAG, NULL_SLOT, dest, item.itemid, item.count); if (item.follow_loot_rules && !item.AllowedForPlayer(target)) msg = EQUIP_ERR_YOU_CAN_NEVER_USE_THAT_ITEM; if (msg != EQUIP_ERR_OK) { target->SendEquipError(msg, NULL, NULL, item.itemid); // send duplicate of error massage to master looter _player->SendEquipError(msg, NULL, NULL, item.itemid); return; } // list of players allowed to receive this item in trade AllowedLooterSet looters = item.GetAllowedLooters(); // not move item from loot to target inventory Item* newitem = target->StoreNewItem(dest, item.itemid, true, item.randomPropertyId, looters); target->SendNewItem(newitem, uint32(item.count), false, false, true); target->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_LOOT_ITEM, item.itemid, item.count); target->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_LOOT_TYPE, loot->loot_type, item.count); target->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_LOOT_EPIC_ITEM, item.itemid, item.count); // mark as looted item.count=0; item.is_looted=true; loot->NotifyItemRemoved(slotid); --loot->unlootedCount; }
void WorldSession::SendPetitionQueryOpcode(uint64 petitionGuid) { ObjectGuid ownerGuid = 0; uint32 type; std::string name = "NO_NAME_FOR_GUID"; PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_PETITION); stmt->setUInt32(0, GUID_LOPART(petitionGuid)); PreparedQueryResult result = CharacterDatabase.Query(stmt); if (result) { Field* fields = result->Fetch(); ownerGuid = MAKE_NEW_GUID(fields[0].GetUInt32(), 0, HIGHGUID_PLAYER); name = fields[1].GetString(); type = fields[2].GetUInt8(); } else { TC_LOG_DEBUG("network", "CMSG_PETITION_QUERY failed for petition (GUID: %u)", GUID_LOPART(petitionGuid)); return; } WorldPacket data(SMSG_PETITION_QUERY_RESPONSE, (4+8+name.size()+1+1+4*12+2+10)); data << uint32(GUID_LOPART(petitionGuid)); // guild/team guid (in Trinity always same as GUID_LOPART(petition guid) data.WriteBit(1); // hasData; for (int i = 0; i < 10; i++) data.WriteBits(0, 6); // Unk strings; data.WriteGuidMask(ownerGuid, 2, 4); data.WriteBits(0, 12); data.WriteGuidMask(ownerGuid, 0, 7, 3, 6, 5); data.WriteBits(name.size(), 7); //NameLen data.WriteBit(ownerGuid[1]); data.FlushBits(); data.WriteByteSeq(ownerGuid[5]); data << uint32(0); data.WriteString(name); data << uint32(0); data.WriteByteSeq(ownerGuid[4]); data << uint32(type); // Type - 4 guild data.WriteByteSeq(ownerGuid[6]); data << uint32(0); data << uint32(sWorld->getIntConfig(CONFIG_MIN_PETITION_SIGNS)); // Required sign count data.WriteGuidBytes(ownerGuid, 1, 7, 0); data << uint32(0); data << uint32(0); data.WriteByteSeq(ownerGuid[2]); data << uint32(time(NULL) + YEAR); // Deadline data << uint16(0); data << uint32(0); data.WriteByteSeq(ownerGuid[3]); data << uint32(0); data << uint32(0); data << uint32(0); data << uint32(0); SendPacket(&data); }
//called when player takes item attached in mail void WorldSession::HandleMailTakeItem(WorldPacket & recv_data) { uint64 mailbox; uint32 mailId; uint32 itemId; recv_data >> mailbox; recv_data >> mailId; recv_data >> itemId; // item guid low if (!GetPlayer()->GetGameObjectIfCanInteractWith(mailbox, GAMEOBJECT_TYPE_MAILBOX)) return; Player* player = _player; Mail* m = player->GetMail(mailId); if (!m || m->state == MAIL_STATE_DELETED || m->deliver_time > time(NULL)) { player->SendMailResult(mailId, MAIL_ITEM_TAKEN, MAIL_ERR_INTERNAL_ERROR); return; } // prevent cheating with skip client money check if (!player->HasEnoughMoney(m->COD)) { player->SendMailResult(mailId, MAIL_ITEM_TAKEN, MAIL_ERR_NOT_ENOUGH_MONEY); return; } Item* it = player->GetMItem(itemId); ItemPosCountVec dest; uint8 msg = _player->CanStoreItem(NULL_BAG, NULL_SLOT, dest, it, false); if (msg == EQUIP_ERR_OK) { SQLTransaction trans = CharacterDatabase.BeginTransaction(); m->RemoveItem(itemId); m->removedItems.push_back(itemId); if (m->COD > 0) //if there is COD, take COD money from player and send them to sender by mail { uint64 sender_guid = MAKE_NEW_GUID(m->sender, 0, HIGHGUID_PLAYER); Player* receive = ObjectAccessor::FindPlayer(sender_guid); uint32 sender_accId = 0; if (!AccountMgr::IsPlayerAccount(GetSecurity()) && sWorld->getBoolConfig(CONFIG_GM_LOG_TRADE)) { std::string sender_name; if (receive) { sender_accId = receive->GetSession()->GetAccountId(); sender_name = receive->GetName(); } else { // can be calculated early sender_accId = sObjectMgr->GetPlayerAccountIdByGUID(sender_guid); if (!sObjectMgr->GetPlayerNameByGUID(sender_guid, sender_name)) sender_name = sObjectMgr->GetSkyFireStringForDBCLocale(LANG_UNKNOWN); } sLog->outCommand(GetAccountId(), "GM %s (Account: %u) receive mail item: %s (Entry: %u Count: %u) and send COD money: %u to player: %s (Account: %u)", GetPlayerName(), GetAccountId(), it->GetTemplate()->Name1.c_str(), it->GetEntry(), it->GetCount(), m->COD, sender_name.c_str(), sender_accId); } else if (!receive) sender_accId = sObjectMgr->GetPlayerAccountIdByGUID(sender_guid); // check player existence if (receive || sender_accId) { MailDraft(m->subject, "") .AddMoney(m->COD) .SendMailTo(trans, MailReceiver(receive, m->sender), MailSender(MAIL_NORMAL, m->receiver), MAIL_CHECK_MASK_COD_PAYMENT); } player->ModifyMoney(-int32(m->COD)); } m->COD = 0; m->state = MAIL_STATE_CHANGED; player->m_mailsUpdated = true; player->RemoveMItem(it->GetGUIDLow()); uint32 count = it->GetCount(); // save counts before store and possible merge with deleting player->MoveItemToInventory(dest, it, true); player->SaveInventoryAndGoldToDB(trans); player->_SaveMail(trans); CharacterDatabase.CommitTransaction(trans); player->SendMailResult(mailId, MAIL_ITEM_TAKEN, MAIL_OK, 0, itemId, count); } else player->SendMailResult(mailId, MAIL_ITEM_TAKEN, MAIL_ERR_EQUIP_ERROR, msg); }
bool ChatHandler::HandleCharacterWhisperCommand(const char* args) { if(!*args) return false; char *character_name_str = strtok((char*)args, " "); if(!character_name_str) return false; std::string character_name = character_name_str; if(!normalizePlayerName(character_name)) return false; char *from_name_str = strtok(NULL, " "); if(!from_name_str) return false; std::string from_name = from_name_str; if(!normalizePlayerName(from_name)) return false; Player *player = sObjectMgr.GetPlayer(character_name.c_str()); if(!player || !player->GetSession()) { PSendSysMessage("Character %s not found or not online", character_name.c_str()); return true; } from_name = std::string("[GM]") + from_name; // set GM name for replies - more than one GM cannot speak with same player at same time // maybe also needed in ::HandleNameQueryOpcode() ? // force SMSG_NAME_QUERY_RESPONSE if name changed to update client display // note : guid 1 should be reserved dummy !!! if (player->rcGmName != from_name) { player->rcGmName = from_name; WorldPacket data( SMSG_NAME_QUERY_RESPONSE, (8+1+1+1+1+1+1+10) ); data.appendPackGUID(MAKE_NEW_GUID(1, 0, HIGHGUID_PLAYER)); data << uint8(0); // added in 3.1 data << from_name.c_str(); data << uint32(0); // not needed here data data << uint8(0); // is not declined player->GetSession()->SendPacket(&data); } // all the tailing text is our msg char* msgStr = strtok(NULL, ""); if(!msgStr) return false; WorldPacket data(SMSG_MESSAGECHAT, 200); data << (uint8)CHAT_MSG_WHISPER; data << (uint32)LANG_UNIVERSAL; data << (uint64)1; // from guid - reserved dummy data << (uint32)LANG_UNIVERSAL; data << (uint64)player->GetGUID(); data << (uint32)(strlen(msgStr)+1); data << msgStr; data << (uint8)4; player->GetSession()->SendPacket(&data); return true; }
static bool HandleGroupListCommand(ChatHandler* handler, char const* args) { Player* playerTarget; uint64 guidTarget; std::string nameTarget; uint32 parseGUID = MAKE_NEW_GUID(atol((char*)args), 0, HIGHGUID_PLAYER); if (sObjectMgr->GetPlayerNameByGUID(parseGUID, nameTarget)) { playerTarget = sObjectMgr->GetPlayerByLowGUID(parseGUID); guidTarget = parseGUID; } else if (!handler->extractPlayerTarget((char*)args, &playerTarget, &guidTarget, &nameTarget)) return false; Group* groupTarget = NULL; if (playerTarget) groupTarget = playerTarget->GetGroup(); if (!groupTarget) { PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_GROUP_MEMBER); stmt->setUInt32(0, guidTarget); PreparedQueryResult resultGroup = CharacterDatabase.Query(stmt); if (resultGroup) groupTarget = sGroupMgr->GetGroupByDbStoreId((*resultGroup)[0].GetUInt32()); } if (!groupTarget) { handler->PSendSysMessage(LANG_GROUP_NOT_IN_GROUP, nameTarget.c_str()); handler->SetSentErrorMessage(true); return false; } handler->PSendSysMessage(LANG_GROUP_TYPE, (groupTarget->isRaidGroup() ? "raid" : "party")); Group::MemberSlotList const& members = groupTarget->GetMemberSlots(); for (Group::MemberSlotList::const_iterator itr = members.begin(); itr != members.end(); ++itr) { Group::MemberSlot const& slot = *itr; std::string flags; if (slot.flags & MEMBER_FLAG_ASSISTANT) flags = "Assistant"; if (slot.flags & MEMBER_FLAG_MAINTANK) { if (!flags.empty()) flags.append(", "); flags.append("MainTank"); } if (slot.flags & MEMBER_FLAG_MAINASSIST) { if (!flags.empty()) flags.append(", "); flags.append("MainAssist"); } if (flags.empty()) flags = "None"; Player* p = ObjectAccessor::FindPlayer((*itr).guid); const char* onlineState = (p && p->IsInWorld()) ? "online" : "offline"; handler->PSendSysMessage(LANG_GROUP_PLAYER_NAME_GUID, slot.name.c_str(), onlineState, GUID_LOPART(slot.guid), flags.c_str()); } return true; }
bool Item::LoadFromDB(uint32 guid, uint64 owner_guid, QueryResult *result) { // create item before any checks for store correct guid // and allow use "FSetState(ITEM_REMOVED); SaveToDB();" for deleting item from DB Object::_Create(guid, 0, HIGHGUID_ITEM); bool delete_result = false; if(!result) { result = CharacterDatabase.PQuery("SELECT data FROM item_instance WHERE guid = '%u'", guid); delete_result = true; } if (!result) { sLog.outError("Item (GUID: %u owner: %u) not found in table `item_instance`, can't load. ",guid,GUID_LOPART(owner_guid)); return false; } Field *fields = result->Fetch(); if(!LoadValues(fields[0].GetString())) { sLog.outError("Item #%d have broken data in `data` field. Can't be loaded.",guid); if (delete_result) delete result; return false; } bool need_save = false; // need explicit save data at load fixes // overwrite possible wrong/corrupted guid uint64 new_item_guid = MAKE_NEW_GUID(guid,0, HIGHGUID_ITEM); if(GetUInt64Value(OBJECT_FIELD_GUID) != new_item_guid) { SetUInt64Value(OBJECT_FIELD_GUID, MAKE_NEW_GUID(guid,0, HIGHGUID_ITEM)); need_save = true; } if (delete_result) delete result; ItemPrototype const* proto = GetProto(); if(!proto) return false; // update max durability (and durability) if need if(proto->MaxDurability!= GetUInt32Value(ITEM_FIELD_MAXDURABILITY)) { SetUInt32Value(ITEM_FIELD_MAXDURABILITY,proto->MaxDurability); if(GetUInt32Value(ITEM_FIELD_DURABILITY) > proto->MaxDurability) SetUInt32Value(ITEM_FIELD_DURABILITY,proto->MaxDurability); need_save = true; } // recalculate suffix factor if(GetItemRandomPropertyId() < 0) { if(UpdateItemSuffixFactor()) need_save = true; } // Remove bind flag for items vs NO_BIND set if (IsSoulBound() && proto->Bonding == NO_BIND) { ApplyModFlag(ITEM_FIELD_FLAGS,ITEM_FLAGS_BINDED, false); need_save = true; } // update duration if need, and remove if not need if ((proto->Duration == 0) != (GetUInt32Value(ITEM_FIELD_DURATION) == 0)) { SetUInt32Value(ITEM_FIELD_DURATION, proto->Duration); need_save = true; } // set correct owner if (owner_guid != 0 && GetOwnerGUID() != owner_guid) { SetOwnerGUID(owner_guid); need_save = true; } if (need_save) // normal item changed state set not work at loading { std::ostringstream ss; ss << "UPDATE item_instance SET data = '"; for(uint16 i = 0; i < m_valuesCount; ++i ) ss << GetUInt32Value(i) << " "; ss << "', owner_guid = '" << GUID_LOPART(GetOwnerGUID()) << "' WHERE guid = '" << guid << "'"; CharacterDatabase.Execute( ss.str().c_str() ); } //Set extended cost for refundable item if(HasFlag(ITEM_FIELD_FLAGS, ITEM_FLAGS_REFUNDABLE)) { QueryResult *result_ext = CharacterDatabase.PQuery("SELECT ExtendedCost, price FROM item_instance WHERE guid = '%u'", guid); if(result_ext) { m_ExtendedCostId = result_ext->Fetch()[0].GetUInt32(); m_price = result_ext->Fetch()[1].GetUInt32(); delete result_ext; } } return true; }
void WorldSession::HandleSendMail(WorldPacket & recv_data ) { uint64 mailbox, unk3; std::string receiver, subject, body; uint32 unk1, unk2, money, COD; uint8 unk4; recv_data >> mailbox; recv_data >> receiver; if (!GetPlayer()->GetGameObjectIfCanInteractWith(mailbox, GAMEOBJECT_TYPE_MAILBOX)) return; recv_data >> subject; recv_data >> body; recv_data >> unk1; // stationery? recv_data >> unk2; // 0x00000000 MailItemsInfo mi; uint8 items_count; recv_data >> items_count; // attached items count if(items_count > 12) // client limit { GetPlayer()->SendMailResult(0, MAIL_SEND, MAIL_ERR_TOO_MANY_ATTACHMENTS); return; } if(items_count) { for(uint8 i = 0; i < items_count; ++i) { uint8 item_slot; uint64 item_guid; recv_data >> item_slot; recv_data >> item_guid; mi.AddItem(GUID_LOPART(item_guid), item_slot); } } recv_data >> money >> COD; // money and cod recv_data >> unk3; // const 0 recv_data >> unk4; // const 0 items_count = mi.size(); // this is the real size after the duplicates have been removed if (receiver.empty()) return; Player* pl = _player; uint64 rc = 0; if(normalizePlayerName(receiver)) rc = objmgr.GetPlayerGUIDByName(receiver); if (!rc) { sLog.outDetail("Player %u is sending mail to %s (GUID: not existed!) with subject %s and body %s includes %u items, %u copper and %u COD copper with unk1 = %u, unk2 = %u", pl->GetGUIDLow(), receiver.c_str(), subject.c_str(), body.c_str(), items_count, money, COD, unk1, unk2); pl->SendMailResult(0, MAIL_SEND, MAIL_ERR_RECIPIENT_NOT_FOUND); return; } sLog.outDetail("Player %u is sending mail to %s (GUID: %u) with subject %s and body %s includes %u items, %u copper and %u COD copper with unk1 = %u, unk2 = %u", pl->GetGUIDLow(), receiver.c_str(), GUID_LOPART(rc), subject.c_str(), body.c_str(), items_count, money, COD, unk1, unk2); if(pl->GetGUID() == rc) { pl->SendMailResult(0, MAIL_SEND, MAIL_ERR_CANNOT_SEND_TO_SELF); return; } uint32 cost = items_count ? 30 * items_count : 30; // price hardcoded in client uint32 reqmoney = cost + money; if (pl->GetMoney() < reqmoney) { pl->SendMailResult(0, MAIL_SEND, MAIL_ERR_NOT_ENOUGH_MONEY); return; } Player *receive = objmgr.GetPlayer(rc); uint32 rc_team = 0; uint8 mails_count = 0; //do not allow to send to one player more than 100 mails if(receive) { rc_team = receive->GetTeam(); mails_count = receive->GetMailSize(); } else { rc_team = objmgr.GetPlayerTeamByGUID(rc); QueryResult* result = CharacterDatabase.PQuery("SELECT COUNT(*) FROM mail WHERE receiver = '%u'", GUID_LOPART(rc)); if(result) { Field *fields = result->Fetch(); mails_count = fields[0].GetUInt32(); delete result; } } //do not allow to have more than 100 mails in mailbox.. mails count is in opcode uint8!!! - so max can be 255.. if (mails_count > 100) { pl->SendMailResult(0, MAIL_SEND, MAIL_ERR_RECIPIENT_CAP_REACHED); return; } // test the receiver's Faction... if (!sWorld.getConfig(CONFIG_ALLOW_TWO_SIDE_INTERACTION_MAIL) && pl->GetTeam() != rc_team && GetSecurity() == SEC_PLAYER) { pl->SendMailResult(0, MAIL_SEND, MAIL_ERR_NOT_YOUR_TEAM); return; } uint32 rc_account = 0; if(receive) rc_account = receive->GetSession()->GetAccountId(); else rc_account = objmgr.GetPlayerAccountIdByGUID(rc); if (items_count) { for(MailItemMap::iterator mailItemIter = mi.begin(); mailItemIter != mi.end(); ++mailItemIter) { MailItem& mailItem = mailItemIter->second; if(!mailItem.item_guidlow) { pl->SendMailResult(0, MAIL_SEND, MAIL_ERR_MAIL_ATTACHMENT_INVALID); return; } mailItem.item = pl->GetItemByGuid(MAKE_NEW_GUID(mailItem.item_guidlow, 0, HIGHGUID_ITEM)); // prevent sending bag with items (cheat: can be placed in bag after adding equipped empty bag to mail) if(!mailItem.item) { pl->SendMailResult(0, MAIL_SEND, MAIL_ERR_MAIL_ATTACHMENT_INVALID); return; } if(!mailItem.item->CanBeTraded(true)) { pl->SendMailResult(0, MAIL_SEND, MAIL_ERR_EQUIP_ERROR, EQUIP_ERR_MAIL_BOUND_ITEM); return; } if(mailItem.item->IsBoundAccountWide() && mailItem.item->IsSoulBound() && pl->GetSession()->GetAccountId() != rc_account) { pl->SendMailResult(0, MAIL_SEND, MAIL_ERR_EQUIP_ERROR, EQUIP_ERR_ARTEFACTS_ONLY_FOR_OWN_CHARACTERS); return; } if (mailItem.item->HasFlag(ITEM_FIELD_FLAGS, ITEM_FLAGS_CONJURED) || mailItem.item->GetUInt32Value(ITEM_FIELD_DURATION)) { pl->SendMailResult(0, MAIL_SEND, MAIL_ERR_EQUIP_ERROR, EQUIP_ERR_MAIL_BOUND_ITEM); return; } if(COD && mailItem.item->HasFlag(ITEM_FIELD_FLAGS, ITEM_FLAGS_WRAPPED)) { pl->SendMailResult(0, MAIL_SEND, MAIL_ERR_CANT_SEND_WRAPPED_COD); return; } } } pl->SendMailResult(0, MAIL_SEND, MAIL_OK); uint32 itemTextId = 0; if (!body.empty()) { itemTextId = objmgr.CreateItemText( body ); } pl->ModifyMoney( -int32(reqmoney) ); pl->GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_GOLD_SPENT_FOR_MAIL, cost); bool needItemDelay = false; if(items_count > 0 || money > 0) { if (items_count > 0) { for(MailItemMap::iterator mailItemIter = mi.begin(); mailItemIter != mi.end(); ++mailItemIter) { MailItem& mailItem = mailItemIter->second; if(!mailItem.item) continue; mailItem.item_template = mailItem.item ? mailItem.item->GetEntry() : 0; if( GetSecurity() > SEC_PLAYER && sWorld.getConfig(CONFIG_GM_LOG_TRADE) ) { sLog.outCommand(GetAccountId(), "GM %s (Account: %u) mail item: %s (Entry: %u Count: %u) to player: %s (Account: %u)", GetPlayerName(), GetAccountId(), mailItem.item->GetProto()->Name1, mailItem.item->GetEntry(), mailItem.item->GetCount(), receiver.c_str(), rc_account); } pl->MoveItemFromInventory(mailItem.item->GetBagSlot(), mailItem.item->GetSlot(), true); CharacterDatabase.BeginTransaction(); mailItem.item->DeleteFromInventoryDB(); //deletes item from character's inventory mailItem.item->SaveToDB(); // recursive and not have transaction guard into self, item not in inventory and can be save standalone // owner in data will set at mail receive and item extracting CharacterDatabase.PExecute("UPDATE item_instance SET owner_guid = '%u' WHERE guid='%u'", GUID_LOPART(rc), mailItem.item->GetGUIDLow()); CharacterDatabase.CommitTransaction(); } // if item send to character at another account, then apply item delivery delay needItemDelay = pl->GetSession()->GetAccountId() != rc_account; } if(money > 0 && GetSecurity() > SEC_PLAYER && sWorld.getConfig(CONFIG_GM_LOG_TRADE)) { sLog.outCommand(GetAccountId(),"GM %s (Account: %u) mail money: %u to player: %s (Account: %u)", GetPlayerName(), GetAccountId(), money, receiver.c_str(), rc_account); } } // If theres is an item, there is a one hour delivery delay if sent to another account's character. uint32 deliver_delay = needItemDelay ? sWorld.getConfig(CONFIG_MAIL_DELIVERY_DELAY) : 0; // will delete item or place to receiver mail list WorldSession::SendMailTo(receive, MAIL_NORMAL, MAIL_STATIONERY_NORMAL, pl->GetGUIDLow(), GUID_LOPART(rc), subject, itemTextId, &mi, money, COD, MAIL_CHECK_MASK_NONE, deliver_delay); CharacterDatabase.BeginTransaction(); pl->SaveInventoryAndGoldToDB(); CharacterDatabase.CommitTransaction(); }
//called when player lists his received mails void WorldSession::HandleGetMailList(WorldPacket & recv_data ) { uint64 mailbox; recv_data >> mailbox; if (!GetPlayer()->GetGameObjectIfCanInteractWith(mailbox, GAMEOBJECT_TYPE_MAILBOX)) return; Player* pl = _player; //load players mails, and mailed items if(!pl->m_mailsLoaded) pl ->_LoadMail(); // client can't work with packets > max int16 value const uint32 maxPacketSize = 32767; uint32 mails_count = 0; // real send to client mails amount WorldPacket data(SMSG_MAIL_LIST_RESULT, (200)); // guess size data << uint8(0); // mail's count time_t cur_time = time(NULL); for(PlayerMails::iterator itr = pl->GetmailBegin(); itr != pl->GetmailEnd(); ++itr) { // skip deleted or not delivered (deliver delay not expired) mails if ((*itr)->state == MAIL_STATE_DELETED || cur_time < (*itr)->deliver_time) continue; uint8 item_count = (*itr)->items.size(); // max count is MAX_MAIL_ITEMS (12) size_t next_mail_size = 2+4+1+8+4*8+((*itr)->subject.size()+1)+1+item_count*(1+4+4+6*3*4+4+4+1+4+4+4); if(data.wpos()+next_mail_size > maxPacketSize) break; uint32 show_flags = 0; if ((*itr)->messageType != MAIL_NORMAL) show_flags |= MAIL_SHOW_DELETE; if ((*itr)->messageType == MAIL_AUCTION) show_flags |= MAIL_SHOW_AUCTION; if ((*itr)->HasItems() && (*itr)->messageType == MAIL_NORMAL) show_flags |= MAIL_SHOW_RETURN; data << (uint16) 0x0040; // unknown 2.3.0, different values data << (uint32) (*itr)->messageID; // Message ID data << (uint8) (*itr)->messageType; // Message Type switch((*itr)->messageType) { case MAIL_NORMAL: // sender guid data << uint64(MAKE_NEW_GUID((*itr)->sender, 0, HIGHGUID_PLAYER)); break; case MAIL_CREATURE: case MAIL_GAMEOBJECT: case MAIL_AUCTION: data << (uint32) (*itr)->sender; // creature/gameobject entry, auction id break; case MAIL_ITEM: // item entry (?) sender = "Unknown", NYI break; } data << (uint32) (*itr)->COD; // COD data << (uint32) (*itr)->itemTextId; // sure about this data << (uint32) 0; // unknown data << (uint32) (*itr)->stationery; // stationery (Stationery.dbc) data << (uint32) (*itr)->money; // Gold data << (uint32) show_flags; // unknown, 0x4 - auction, 0x10 - normal // Time data << (float) ((*itr)->expire_time-time(NULL))/DAY; data << (uint32) (*itr)->mailTemplateId; // mail template (MailTemplate.dbc) data << (*itr)->subject; // Subject string - once 00, when mail type = 3 data << (uint8) item_count; // client limit is 0x10 for(uint8 i = 0; i < item_count; ++i) { Item *item = pl->GetMItem((*itr)->items[i].item_guid); // item index (0-6?) data << (uint8) i; // item guid low? data << (uint32) (item ? item->GetGUIDLow() : 0); // entry data << (uint32) (item ? item->GetEntry() : 0); for(uint8 j = 0; j < MAX_INSPECTED_ENCHANTMENT_SLOT; ++j) { // unsure data << (uint32) (item ? item->GetEnchantmentCharges((EnchantmentSlot)j) : 0); // unsure data << (uint32) (item ? item->GetEnchantmentDuration((EnchantmentSlot)j) : 0); // unsure data << (uint32) (item ? item->GetEnchantmentId((EnchantmentSlot)j) : 0); } // can be negative data << (uint32) (item ? item->GetItemRandomPropertyId() : 0); // unk data << (uint32) (item ? item->GetItemSuffixFactor() : 0); // stack count data << (uint32) (item ? item->GetCount() : 0); // charges data << (uint32) (item ? item->GetSpellCharges() : 0); // durability data << (uint32) (item ? item->GetUInt32Value(ITEM_FIELD_MAXDURABILITY) : 0); // durability data << (uint32) (item ? item->GetUInt32Value(ITEM_FIELD_DURABILITY) : 0); // unknown wotlk data << (uint8) 0; } mails_count += 1; } data.put<uint8>(0, mails_count); // set real send mails to client SendPacket(&data); // recalculate m_nextMailDelivereTime and unReadMails _player->UpdateNextMailTimeAndUnreads(); }
//teleport to creature static bool HandleGoCreatureCommand(ChatHandler* handler, char const* args) { if (!*args) return false; Player* player = handler->GetSession()->GetPlayer(); // "id" or number or [name] Shift-click form |color|Hcreature_entry:creature_id|h[name]|h|r char* param1 = handler->extractKeyFromLink((char*)args, "Hcreature"); if (!param1) return false; std::ostringstream whereClause; // User wants to teleport to the NPC's template entry if (strcmp(param1, "id") == 0) { // Get the "creature_template.entry" // number or [name] Shift-click form |color|Hcreature_entry:creature_id|h[name]|h|r char* tail = strtok(NULL, ""); if (!tail) return false; char* id = handler->extractKeyFromLink(tail, "Hcreature_entry"); if (!id) return false; int32 entry = atoi(id); if (!entry) return false; whereClause << "WHERE id = '" << entry << '\''; } else { int32 guid = atoi(param1); // Number is invalid - maybe the user specified the mob's name if (!guid) { std::string name = param1; WorldDatabase.EscapeString(name); whereClause << ", creature_template WHERE creature.id = creature_template.entry AND creature_template.name "_LIKE_" '" << name << '\''; } else whereClause << "WHERE guid = '" << guid << '\''; } QueryResult result = WorldDatabase.PQuery("SELECT position_x, position_y, position_z, orientation, map, guid, id FROM creature %s", whereClause.str().c_str()); if (!result) { handler->SendSysMessage(LANG_COMMAND_GOCREATNOTFOUND); handler->SetSentErrorMessage(true); return false; } if (result->GetRowCount() > 1) handler->SendSysMessage(LANG_COMMAND_GOCREATMULTIPLE); Field* fields = result->Fetch(); float x = fields[0].GetFloat(); float y = fields[1].GetFloat(); float z = fields[2].GetFloat(); float ort = fields[3].GetFloat(); int mapId = fields[4].GetUInt16(); uint32 guid = fields[5].GetUInt32(); uint32 id = fields[6].GetUInt32(); // if creature is in same map with caster go at its current location if (Creature* creature = sObjectAccessor->GetCreature(*player, MAKE_NEW_GUID(guid, id, HIGHGUID_UNIT))) { x = creature->GetPositionX(); y = creature->GetPositionY(); z = creature->GetPositionZ(); ort = creature->GetOrientation(); } if (!MapManager::IsValidMapCoord(mapId, x, y, z, ort)) { handler->PSendSysMessage(LANG_INVALID_TARGET_COORD, x, y, mapId); handler->SetSentErrorMessage(true); return false; } // stop flight if need if (player->isInFlight()) { player->GetMotionMaster()->MovementExpired(); player->CleanupAfterTaxiFlight(); } // save only in non-flight case else player->SaveRecallPosition(); player->TeleportTo(mapId, x, y, z, ort); return true; }
bool ArenaTeam::LoadMembersFromDB(QueryResult arenaTeamMembersResult) { if (!arenaTeamMembersResult) return false; bool captainPresentInTeam = false; do { Field *fields = arenaTeamMembersResult->Fetch(); //prevent crash if db records are broken, when all members in result are already processed and current team hasn't got any members if (!fields) break; uint32 arenaTeamId = fields[0].GetUInt32(); if (arenaTeamId < m_TeamId) { //there is in table arena_team_member record which doesn't have arenateamid in arena_team table, report error sLog.outErrorDb("ArenaTeam %u does not exist but it has record in arena_team_member table, deleting it!", arenaTeamId); CharacterDatabase.PExecute("DELETE FROM arena_team_member WHERE arenateamid = '%u'", arenaTeamId); continue; } if (arenaTeamId > m_TeamId) //we loaded all members for this arena_team already, break cycle break; uint32 player_guid = fields[1].GetUInt32(); QueryResult result = CharacterDatabase.PQuery( "SELECT personal_rating, matchmaker_rating FROM character_arena_stats WHERE guid = '%u' AND slot = '%u'", player_guid, GetSlot()); uint32 personalrating = 0; uint32 matchmakerrating = 1500; if (result) { personalrating = (*result)[0].GetUInt32(); matchmakerrating = (*result)[1].GetUInt32(); } ArenaTeamMember newmember; newmember.guid = MAKE_NEW_GUID(player_guid, 0, HIGHGUID_PLAYER); newmember.games_week = fields[2].GetUInt32(); newmember.wins_week = fields[3].GetUInt32(); newmember.games_season = fields[4].GetUInt32(); newmember.wins_season = fields[5].GetUInt32(); newmember.name = fields[6].GetString(); newmember.Class = fields[7].GetUInt8(); newmember.personal_rating = personalrating; newmember.matchmaker_rating = matchmakerrating; //check if member exists in characters table if (newmember.name.empty()) { sLog.outErrorDb("ArenaTeam %u has member with empty name - probably player %u doesn't exist, deleting him from memberlist!", arenaTeamId, GUID_LOPART(newmember.guid)); this->DelMember(newmember.guid); continue; } if (newmember.guid == GetCaptain()) captainPresentInTeam = true; m_members.push_back(newmember); }while (arenaTeamMembersResult->NextRow()); if (Empty() || !captainPresentInTeam) { // arena team is empty or captain is not in team, delete from db sLog.outErrorDb("ArenaTeam %u does not have any members or its captain is not in team, disbanding it...", m_TeamId); return false; } return true; }
void WorldSession::HandleCalendarEventInvite(WorldPacket& recvData) { sLog->outDebug(LOG_FILTER_NETWORKIO, "CMSG_CALENDAR_EVENT_INVITE"); uint64 playerGuid = _player->GetGUID(); uint64 eventId; uint64 inviteId; std::string name; bool isPreInvite; bool isGuildEvent; uint64 inviteeGuid = 0; uint32 inviteeTeam = 0; uint32 inviteeGuildId = 0; recvData >> eventId >> inviteId >> name >> isPreInvite >> isGuildEvent; if (Player* player = sObjectAccessor->FindPlayerByName(name.c_str())) { // Invitee is online inviteeGuid = player->GetGUID(); inviteeTeam = player->GetTeam(); inviteeGuildId = player->GetGuildId(); } else { // Invitee offline, get data from database PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_GUID_RACE_ACC_BY_NAME); stmt->setString(0, name); if (PreparedQueryResult result = CharacterDatabase.Query(stmt)) { Field* fields = result->Fetch(); inviteeGuid = MAKE_NEW_GUID(fields[0].GetUInt32(), 0, HIGHGUID_PLAYER); inviteeTeam = Player::TeamForRace(fields[1].GetUInt8()); inviteeGuildId = Player::GetGuildIdFromDB(inviteeGuid); } } if (!inviteeGuid) { sCalendarMgr->SendCalendarCommandResult(playerGuid, CALENDAR_ERROR_PLAYER_NOT_FOUND); return; } if (_player->GetTeam() != inviteeTeam && !sWorld->getBoolConfig(CONFIG_ALLOW_TWO_SIDE_INTERACTION_CALENDAR)) { sCalendarMgr->SendCalendarCommandResult(playerGuid, CALENDAR_ERROR_NOT_ALLIED); return; } if (QueryResult result = CharacterDatabase.PQuery("SELECT flags FROM character_social WHERE guid = " UI64FMTD " AND friend = " UI64FMTD, inviteeGuid, playerGuid)) { Field* fields = result->Fetch(); if (fields[0].GetUInt8() & SOCIAL_FLAG_IGNORED) { sCalendarMgr->SendCalendarCommandResult(playerGuid, CALENDAR_ERROR_IGNORING_YOU_S, name.c_str()); return; } } if (!isPreInvite) { if (CalendarEvent* calendarEvent = sCalendarMgr->GetEvent(eventId)) { if (calendarEvent->IsGuildEvent() && calendarEvent->GetGuildId() == inviteeGuildId) { // we can't invite guild members to guild events sCalendarMgr->SendCalendarCommandResult(playerGuid, CALENDAR_ERROR_NO_GUILD_INVITES); return; } // 946684800 is 01/01/2000 00:00:00 - default response time CalendarInvite* invite = new CalendarInvite(sCalendarMgr->GetFreeInviteId(), eventId, inviteeGuid, playerGuid, 946684800, CALENDAR_STATUS_INVITED, CALENDAR_RANK_PLAYER, ""); sCalendarMgr->AddInvite(calendarEvent, invite); } else sCalendarMgr->SendCalendarCommandResult(playerGuid, CALENDAR_ERROR_EVENT_INVALID); } else { if (isGuildEvent && inviteeGuildId == _player->GetGuildId()) { sCalendarMgr->SendCalendarCommandResult(playerGuid, CALENDAR_ERROR_NO_GUILD_INVITES); return; } // 946684800 is 01/01/2000 00:00:00 - default response time CalendarInvite* invite = new CalendarInvite(inviteId, 0, inviteeGuid, playerGuid, 946684800, CALENDAR_STATUS_INVITED, CALENDAR_RANK_PLAYER, ""); sCalendarMgr->SendCalendarEventInvite(*invite); } }
//does not clear ram void AuctionHouseMgr::SendAuctionWonMail( AuctionEntry *auction ) { Item *pItem = GetAItem(auction->item_guidlow); if(!pItem) return; uint64 bidder_guid = MAKE_NEW_GUID(auction->bidder, 0, HIGHGUID_PLAYER); Player *bidder = objmgr.GetPlayer(bidder_guid); uint32 bidder_accId = 0; // data for gm.log if( sWorld.getConfig(CONFIG_GM_LOG_TRADE) ) { uint32 bidder_security = 0; std::string bidder_name; if (bidder) { bidder_accId = bidder->GetSession()->GetAccountId(); bidder_security = bidder->GetSession()->GetSecurity(); bidder_name = bidder->GetName(); } else { bidder_accId = objmgr.GetPlayerAccountIdByGUID(bidder_guid); bidder_security = accmgr.GetSecurity(bidder_accId); if(bidder_security > SEC_PLAYER ) // not do redundant DB requests { if(!objmgr.GetPlayerNameByGUID(bidder_guid,bidder_name)) bidder_name = objmgr.GetMangosStringForDBCLocale(LANG_UNKNOWN); } } if( bidder_security > SEC_PLAYER ) { std::string owner_name; if(!objmgr.GetPlayerNameByGUID(auction->owner,owner_name)) owner_name = objmgr.GetMangosStringForDBCLocale(LANG_UNKNOWN); uint32 owner_accid = objmgr.GetPlayerAccountIdByGUID(auction->owner); sLog.outCommand(bidder_accId,"GM %s (Account: %u) won item in auction: %s (Entry: %u Count: %u) and pay money: %u. Original owner %s (Account: %u)", bidder_name.c_str(),bidder_accId,pItem->GetProto()->Name1,pItem->GetEntry(),pItem->GetCount(),auction->bid,owner_name.c_str(),owner_accid); } } else if(!bidder) bidder_accId = objmgr.GetPlayerAccountIdByGUID(bidder_guid); // receiver exist if(bidder || bidder_accId) { std::ostringstream msgAuctionWonSubject; msgAuctionWonSubject << auction->item_template << ":0:" << AUCTION_WON; std::ostringstream msgAuctionWonBody; msgAuctionWonBody.width(16); msgAuctionWonBody << std::right << std::hex << auction->owner; msgAuctionWonBody << std::dec << ":" << auction->bid << ":" << auction->buyout; sLog.outDebug( "AuctionWon body string : %s", msgAuctionWonBody.str().c_str() ); //prepare mail data... : uint32 itemTextId = objmgr.CreateItemText( msgAuctionWonBody.str() ); // set owner to bidder (to prevent delete item with sender char deleting) // owner in `data` will set at mail receive and item extracting CharacterDatabase.PExecute("UPDATE item_instance SET owner_guid = '%u' WHERE guid='%u'",auction->bidder,pItem->GetGUIDLow()); CharacterDatabase.CommitTransaction(); MailItemsInfo mi; mi.AddItem(auction->item_guidlow, auction->item_template, pItem); if (bidder) bidder->GetSession()->SendAuctionBidderNotification( auction->GetHouseId(), auction->Id, bidder_guid, 0, 0, auction->item_template); else RemoveAItem(pItem->GetGUIDLow()); // we have to remove the item, before we delete it !! // will delete item or place to receiver mail list WorldSession::SendMailTo(bidder, MAIL_AUCTION, MAIL_STATIONERY_AUCTION, auction->GetHouseId(), auction->bidder, msgAuctionWonSubject.str(), itemTextId, &mi, 0, 0, MAIL_CHECK_MASK_AUCTION); } // receiver not exist else { CharacterDatabase.PExecute("DELETE FROM item_instance WHERE guid='%u'", pItem->GetGUIDLow()); RemoveAItem(pItem->GetGUIDLow()); // we have to remove the item, before we delete it !! delete pItem; } }
static bool HandleWpModifyCommand(ChatHandler* handler, const char* args) { if (!*args) return false; // first arg: add del text emote spell waittime move char* show_str = strtok((char*)args, " "); if (!show_str) { return false; } std::string show = show_str; // Check // Remember: "show" must also be the name of a column! if ((show != "delay") && (show != "action") && (show != "action_chance") && (show != "move_flag") && (show != "del") && (show != "move") && (show != "wpadd") ) { return false; } // Next arg is: <PATHID> <WPNUM> <ARGUMENT> char* arg_str = NULL; // Did user provide a GUID // or did the user select a creature? // -> variable lowguid is filled with the GUID of the NPC uint32 pathid = 0; uint32 point = 0; uint32 wpGuid = 0; Creature* target = handler->getSelectedCreature(); if (!target || target->GetEntry() != VISUAL_WAYPOINT) { handler->SendSysMessage("|cffff33ffERROR: You must select a waypoint.|r"); return false; } // The visual waypoint wpGuid = target->GetGUIDLow(); // User did select a visual waypoint? // Check the creature QueryResult result = WorldDatabase.PQuery("SELECT id, point FROM waypoint_data WHERE wpguid = %u", wpGuid); if (!result) { handler->PSendSysMessage(LANG_WAYPOINT_NOTFOUNDSEARCH, target->GetGUIDLow()); // Select waypoint number from database // Since we compare float values, we have to deal with // some difficulties. // Here we search for all waypoints that only differ in one from 1 thousand // (0.001) - There is no other way to compare C++ floats with mySQL floats // See also: http://dev.mysql.com/doc/refman/5.0/en/problems-with-float.html const char* maxDIFF = "0.01"; result = WorldDatabase.PQuery("SELECT id, point FROM waypoint_data WHERE (abs(position_x - %f) <= %s) and (abs(position_y - %f) <= %s) and (abs(position_z - %f) <= %s)", target->GetPositionX(), maxDIFF, target->GetPositionY(), maxDIFF, target->GetPositionZ(), maxDIFF); if (!result) { handler->PSendSysMessage(LANG_WAYPOINT_NOTFOUNDDBPROBLEM, wpGuid); return true; } } do { Field* fields = result->Fetch(); pathid = fields[0].GetUInt32(); point = fields[1].GetUInt32(); } while (result->NextRow()); // We have the waypoint number and the GUID of the "master npc" // Text is enclosed in "<>", all other arguments not arg_str = strtok((char*)NULL, " "); // Check for argument if (show != "del" && show != "move" && arg_str == NULL) { handler->PSendSysMessage(LANG_WAYPOINT_ARGUMENTREQ, show_str); return false; } if (show == "del" && target) { handler->PSendSysMessage("|cff00ff00DEBUG: wp modify del, PathID: |r|cff00ffff%u|r", pathid); // wpCreature Creature* wpCreature = NULL; if (wpGuid != 0) { wpCreature = handler->GetSession()->GetPlayer()->GetMap()->GetCreature(MAKE_NEW_GUID(wpGuid, VISUAL_WAYPOINT, HIGHGUID_UNIT)); wpCreature->CombatStop(); wpCreature->DeleteFromDB(); wpCreature->AddObjectToRemoveList(); } WorldDatabase.PExecute("DELETE FROM waypoint_data WHERE id='%u' AND point='%u'", pathid, point); WorldDatabase.PExecute("UPDATE waypoint_data SET point=point-1 WHERE id='%u' AND point>'%u'", pathid, point); handler->PSendSysMessage(LANG_WAYPOINT_REMOVED); return true; } // del if (show == "move" && target) { handler->PSendSysMessage("|cff00ff00DEBUG: wp move, PathID: |r|cff00ffff%u|r", pathid); Player* chr = handler->GetSession()->GetPlayer(); Map* map = chr->GetMap(); { // wpCreature Creature* wpCreature = NULL; // What to do: // Move the visual spawnpoint // Respawn the owner of the waypoints if (wpGuid != 0) { wpCreature = handler->GetSession()->GetPlayer()->GetMap()->GetCreature(MAKE_NEW_GUID(wpGuid, VISUAL_WAYPOINT, HIGHGUID_UNIT)); wpCreature->CombatStop(); wpCreature->DeleteFromDB(); wpCreature->AddObjectToRemoveList(); // re-create Creature* wpCreature2 = new Creature; if (!wpCreature2->Create(sObjectMgr->GenerateLowGuid(HIGHGUID_UNIT), map, chr->GetPhaseMaskForSpawn(), VISUAL_WAYPOINT, 0, 0, chr->GetPositionX(), chr->GetPositionY(), chr->GetPositionZ(), chr->GetOrientation())) { handler->PSendSysMessage(LANG_WAYPOINT_VP_NOTCREATED, VISUAL_WAYPOINT); delete wpCreature2; return false; } wpCreature2->SaveToDB(map->GetId(), (1 << map->GetSpawnMode()), chr->GetPhaseMaskForSpawn()); // To call _LoadGoods(); _LoadQuests(); CreateTrainerSpells(); //TODO: Should we first use "Create" then use "LoadFromDB"? if (!wpCreature2->LoadCreatureFromDB(wpCreature2->GetDBTableGUIDLow(), map)) { handler->PSendSysMessage(LANG_WAYPOINT_VP_NOTCREATED, VISUAL_WAYPOINT); delete wpCreature2; return false; } //sMapMgr->GetMap(npcCreature->GetMapId())->Add(wpCreature2); } WorldDatabase.PExecute("UPDATE waypoint_data SET position_x = '%f', position_y = '%f', position_z = '%f' where id = '%u' AND point='%u'", chr->GetPositionX(), chr->GetPositionY(), chr->GetPositionZ(), pathid, point); handler->PSendSysMessage(LANG_WAYPOINT_CHANGED); } return true; } // move const char *text = arg_str; if (text == 0) { // show_str check for present in list of correct values, no sql injection possible WorldDatabase.PExecute("UPDATE waypoint_data SET %s=NULL WHERE id='%u' AND point='%u'", show_str, pathid, point); } else { // show_str check for present in list of correct values, no sql injection possible std::string text2 = text; WorldDatabase.EscapeString(text2); WorldDatabase.PExecute("UPDATE waypoint_data SET %s='%s' WHERE id='%u' AND point='%u'", show_str, text2.c_str(), pathid, point); } handler->PSendSysMessage(LANG_WAYPOINT_CHANGED_NO, show_str); return true; }
/// Process queued scripts void Map::ScriptsProcess() { if (m_scriptSchedule.empty()) return; ///- Process overdue queued scripts ScriptScheduleMap::iterator iter = m_scriptSchedule.begin(); // ok as multimap is a *sorted* associative container while (!m_scriptSchedule.empty() && (iter->first <= sWorld->GetGameTime())) { ScriptAction const& step = iter->second; Object* source = NULL; if (step.sourceGUID) { switch (GUID_HIPART(step.sourceGUID)) { case HIGHGUID_ITEM: // as well as HIGHGUID_CONTAINER if (Player* player = HashMapHolder<Player>::Find(step.ownerGUID)) source = player->GetItemByGuid(step.sourceGUID); break; case HIGHGUID_UNIT: case HIGHGUID_VEHICLE: source = HashMapHolder<Creature>::Find(step.sourceGUID); break; case HIGHGUID_PET: source = HashMapHolder<Pet>::Find(step.sourceGUID); break; case HIGHGUID_PLAYER: source = HashMapHolder<Player>::Find(step.sourceGUID); break; case HIGHGUID_GAMEOBJECT: source = HashMapHolder<GameObject>::Find(step.sourceGUID); break; case HIGHGUID_CORPSE: source = HashMapHolder<Corpse>::Find(step.sourceGUID); break; case HIGHGUID_MO_TRANSPORT: for (MapManager::TransportSet::iterator itr2 = sMapMgr->m_Transports.begin(); itr2 != sMapMgr->m_Transports.end(); ++itr2) { if ((*itr2)->GetGUID() == step.sourceGUID) { source = *itr2; break; } } break; default: sLog->outError("%s source with unsupported high guid (GUID: " UI64FMTD ", high guid: %u).", step.script->GetDebugInfo().c_str(), step.sourceGUID, GUID_HIPART(step.sourceGUID)); break; } } Object* target = NULL; if (step.targetGUID) { switch (GUID_HIPART(step.targetGUID)) { case HIGHGUID_UNIT: case HIGHGUID_VEHICLE: target = HashMapHolder<Creature>::Find(step.targetGUID); break; case HIGHGUID_PET: target = HashMapHolder<Pet>::Find(step.targetGUID); break; case HIGHGUID_PLAYER: // empty GUID case also target = HashMapHolder<Player>::Find(step.targetGUID); break; case HIGHGUID_GAMEOBJECT: target = HashMapHolder<GameObject>::Find(step.targetGUID); break; case HIGHGUID_CORPSE: target = HashMapHolder<Corpse>::Find(step.targetGUID); break; default: sLog->outError("%s target with unsupported high guid (GUID: " UI64FMTD ", high guid: %u).", step.script->GetDebugInfo().c_str(), step.targetGUID, GUID_HIPART(step.targetGUID)); break; } } switch (step.script->command) { case SCRIPT_COMMAND_TALK: if (step.script->Talk.ChatType > CHAT_TYPE_WHISPER && step.script->Talk.ChatType != CHAT_MSG_RAID_BOSS_WHISPER) { sLog->outError("%s invalid chat type (%u) specified, skipping.", step.script->GetDebugInfo().c_str(), step.script->Talk.ChatType); break; } if (step.script->Talk.Flags & SF_TALK_USE_PLAYER) { if (Player* pSource = _GetScriptPlayerSourceOrTarget(source, target, step.script)) { LocaleConstant loc_idx = pSource->GetSession()->GetSessionDbLocaleIndex(); std::string text(sObjectMgr->GetTrinityString(step.script->Talk.TextID, loc_idx)); switch (step.script->Talk.ChatType) { case CHAT_TYPE_SAY: pSource->Say(text, LANG_UNIVERSAL); break; case CHAT_TYPE_YELL: pSource->Yell(text, LANG_UNIVERSAL); break; case CHAT_TYPE_TEXT_EMOTE: case CHAT_TYPE_BOSS_EMOTE: pSource->TextEmote(text); break; case CHAT_TYPE_WHISPER: case CHAT_MSG_RAID_BOSS_WHISPER: { uint64 targetGUID = target ? target->GetGUID() : 0; if (!targetGUID || !IS_PLAYER_GUID(targetGUID)) sLog->outError("%s attempt to whisper to non-player unit, skipping.", step.script->GetDebugInfo().c_str()); else pSource->Whisper(text, LANG_UNIVERSAL, targetGUID); break; } default: break; // must be already checked at load } } } else { // Source or target must be Creature. if (Creature* cSource = _GetScriptCreatureSourceOrTarget(source, target, step.script)) { uint64 targetGUID = target ? target->GetGUID() : 0; switch (step.script->Talk.ChatType) { case CHAT_TYPE_SAY: cSource->Say(step.script->Talk.TextID, LANG_UNIVERSAL, targetGUID); break; case CHAT_TYPE_YELL: cSource->Yell(step.script->Talk.TextID, LANG_UNIVERSAL, targetGUID); break; case CHAT_TYPE_TEXT_EMOTE: cSource->TextEmote(step.script->Talk.TextID, targetGUID); break; case CHAT_TYPE_BOSS_EMOTE: cSource->MonsterTextEmote(step.script->Talk.TextID, targetGUID, true); break; case CHAT_TYPE_WHISPER: if (!targetGUID || !IS_PLAYER_GUID(targetGUID)) sLog->outError("%s attempt to whisper to non-player unit, skipping.", step.script->GetDebugInfo().c_str()); else cSource->Whisper(step.script->Talk.TextID, targetGUID); break; case CHAT_MSG_RAID_BOSS_WHISPER: if (!targetGUID || !IS_PLAYER_GUID(targetGUID)) sLog->outError("%s attempt to raidbosswhisper to non-player unit, skipping.", step.script->GetDebugInfo().c_str()); else cSource->MonsterWhisper(step.script->Talk.TextID, targetGUID, true); break; default: break; // must be already checked at load } } } break; case SCRIPT_COMMAND_EMOTE: // Source or target must be Creature. if (Creature* cSource = _GetScriptCreatureSourceOrTarget(source, target, step.script)) { if (step.script->Emote.Flags & SF_EMOTE_USE_STATE) cSource->SetUInt32Value(UNIT_NPC_EMOTESTATE, step.script->Emote.EmoteID); else cSource->HandleEmoteCommand(step.script->Emote.EmoteID); } break; case SCRIPT_COMMAND_FIELD_SET: // Source or target must be Creature. if (Creature* cSource = _GetScriptCreatureSourceOrTarget(source, target, step.script)) { // Validate field number. if (step.script->FieldSet.FieldID <= OBJECT_FIELD_ENTRY || step.script->FieldSet.FieldID >= cSource->GetValuesCount()) sLog->outError("%s wrong field %u (max count: %u) in object (TypeId: %u, Entry: %u, GUID: %u) specified, skipping.", step.script->GetDebugInfo().c_str(), step.script->FieldSet.FieldID, cSource->GetValuesCount(), cSource->GetTypeId(), cSource->GetEntry(), cSource->GetGUIDLow()); else cSource->SetUInt32Value(step.script->FieldSet.FieldID, step.script->FieldSet.FieldValue); } break; case SCRIPT_COMMAND_MOVE_TO: // Source or target must be Creature. if (Creature* cSource = _GetScriptCreatureSourceOrTarget(source, target, step.script)) { Unit * unit = (Unit*)cSource; if (step.script->MoveTo.TravelTime != 0) { float speed = unit->GetDistance(step.script->MoveTo.DestX, step.script->MoveTo.DestY, step.script->MoveTo.DestZ) / ((float)step.script->MoveTo.TravelTime * 0.001f); unit->MonsterMoveWithSpeed(step.script->MoveTo.DestX, step.script->MoveTo.DestY, step.script->MoveTo.DestZ, speed); } else unit->NearTeleportTo(step.script->MoveTo.DestX, step.script->MoveTo.DestY, step.script->MoveTo.DestZ, unit->GetOrientation()); } break; case SCRIPT_COMMAND_FLAG_SET: // Source or target must be Creature. if (Creature* cSource = _GetScriptCreatureSourceOrTarget(source, target, step.script)) { // Validate field number. if (step.script->FlagToggle.FieldID <= OBJECT_FIELD_ENTRY || step.script->FlagToggle.FieldID >= cSource->GetValuesCount()) sLog->outError("%s wrong field %u (max count: %u) in object (TypeId: %u, Entry: %u, GUID: %u) specified, skipping.", step.script->GetDebugInfo().c_str(), step.script->FlagToggle.FieldID, source->GetValuesCount(), source->GetTypeId(), source->GetEntry(), source->GetGUIDLow()); else cSource->SetFlag(step.script->FlagToggle.FieldID, step.script->FlagToggle.FieldValue); } break; case SCRIPT_COMMAND_FLAG_REMOVE: // Source or target must be Creature. if (Creature* cSource = _GetScriptCreatureSourceOrTarget(source, target, step.script)) { // Validate field number. if (step.script->FlagToggle.FieldID <= OBJECT_FIELD_ENTRY || step.script->FlagToggle.FieldID >= cSource->GetValuesCount()) sLog->outError("%s wrong field %u (max count: %u) in object (TypeId: %u, Entry: %u, GUID: %u) specified, skipping.", step.script->GetDebugInfo().c_str(), step.script->FlagToggle.FieldID, source->GetValuesCount(), source->GetTypeId(), source->GetEntry(), source->GetGUIDLow()); else cSource->RemoveFlag(step.script->FlagToggle.FieldID, step.script->FlagToggle.FieldValue); } break; case SCRIPT_COMMAND_TELEPORT_TO: if (step.script->TeleportTo.Flags & SF_TELEPORT_USE_CREATURE) { // Source or target must be Creature. if (Creature* cSource = _GetScriptCreatureSourceOrTarget(source, target, step.script, true)) cSource->NearTeleportTo(step.script->TeleportTo.DestX, step.script->TeleportTo.DestY, step.script->TeleportTo.DestZ, step.script->TeleportTo.Orientation); } else { // Source or target must be Player. if (Player* pSource = _GetScriptPlayerSourceOrTarget(source, target, step.script)) pSource->TeleportTo(step.script->TeleportTo.MapID, step.script->TeleportTo.DestX, step.script->TeleportTo.DestY, step.script->TeleportTo.DestZ, step.script->TeleportTo.Orientation); } break; case SCRIPT_COMMAND_QUEST_EXPLORED: { if (!source) { sLog->outError("%s source object is NULL.", step.script->GetDebugInfo().c_str()); break; } if (!target) { sLog->outError("%s target object is NULL.", step.script->GetDebugInfo().c_str()); break; } // when script called for item spell casting then target == (unit or GO) and source is player WorldObject* worldObject; Player* plrTarget = target->ToPlayer(); if (plrTarget) { if (source->GetTypeId() != TYPEID_UNIT && source->GetTypeId() != TYPEID_GAMEOBJECT && source->GetTypeId() != TYPEID_PLAYER) { sLog->outError("%s source is not unit, gameobject or player (TypeId: %u, Entry: %u, GUID: %u), skipping.", step.script->GetDebugInfo().c_str(), source->GetTypeId(), source->GetEntry(), source->GetGUIDLow()); break; } worldObject = dynamic_cast<WorldObject*>(source); } else { plrTarget = source->ToPlayer(); if (plrTarget) { if (target->GetTypeId() != TYPEID_UNIT && target->GetTypeId() != TYPEID_GAMEOBJECT && target->GetTypeId() != TYPEID_PLAYER) { sLog->outError("%s target is not unit, gameobject or player (TypeId: %u, Entry: %u, GUID: %u), skipping.", step.script->GetDebugInfo().c_str(), target->GetTypeId(), target->GetEntry(), target->GetGUIDLow()); break; } worldObject = dynamic_cast<WorldObject*>(target); } else { sLog->outError("%s neither source nor target is player (source: TypeId: %u, Entry: %u, GUID: %u; target: TypeId: %u, Entry: %u, GUID: %u), skipping.", step.script->GetDebugInfo().c_str(), source->GetTypeId(), source->GetEntry(), source->GetGUIDLow(), target->GetTypeId(), target->GetEntry(), target->GetGUIDLow()); break; } } // quest id and flags checked at script loading if ((worldObject->GetTypeId() != TYPEID_UNIT || ((Unit*)worldObject)->isAlive()) && (step.script->QuestExplored.Distance == 0 || worldObject->IsWithinDistInMap(plrTarget, float(step.script->QuestExplored.Distance)))) plrTarget->AreaExploredOrEventHappens(step.script->QuestExplored.QuestID); else plrTarget->FailQuest(step.script->QuestExplored.QuestID); break; } case SCRIPT_COMMAND_KILL_CREDIT: // Source or target must be Player. if (Player* pSource = _GetScriptPlayerSourceOrTarget(source, target, step.script)) { if (step.script->KillCredit.Flags & SF_KILLCREDIT_REWARD_GROUP) pSource->RewardPlayerAndGroupAtEvent(step.script->KillCredit.CreatureEntry, pSource); else pSource->KilledMonsterCredit(step.script->KillCredit.CreatureEntry, 0); } break; case SCRIPT_COMMAND_RESPAWN_GAMEOBJECT: if (!step.script->RespawnGameobject.GOGuid) { sLog->outError("%s gameobject guid (datalong) is not specified.", step.script->GetDebugInfo().c_str()); break; } // Source or target must be WorldObject. if (WorldObject* pSummoner = _GetScriptWorldObject(source, true, step.script)) { GameObject* pGO = _FindGameObject(pSummoner, step.script->RespawnGameobject.GOGuid); if (!pGO) { sLog->outError("%s gameobject was not found (guid: %u).", step.script->GetDebugInfo().c_str(), step.script->RespawnGameobject.GOGuid); break; } if (pGO->GetGoType() == GAMEOBJECT_TYPE_FISHINGNODE || pGO->GetGoType() == GAMEOBJECT_TYPE_DOOR || pGO->GetGoType() == GAMEOBJECT_TYPE_BUTTON || pGO->GetGoType() == GAMEOBJECT_TYPE_TRAP) { sLog->outError("%s can not be used with gameobject of type %u (guid: %u).", step.script->GetDebugInfo().c_str(), uint32(pGO->GetGoType()), step.script->RespawnGameobject.GOGuid); break; } // Check that GO is not spawned if (!pGO->isSpawned()) { int32 nTimeToDespawn = std::max(5, int32(step.script->RespawnGameobject.DespawnDelay)); pGO->SetLootState(GO_READY); pGO->SetRespawnTime(nTimeToDespawn); pGO->GetMap()->AddToMap(pGO); } } break; case SCRIPT_COMMAND_TEMP_SUMMON_CREATURE: { // Source must be WorldObject. if (WorldObject* pSummoner = _GetScriptWorldObject(source, true, step.script)) { if (!step.script->TempSummonCreature.CreatureEntry) sLog->outError("%s creature entry (datalong) is not specified.", step.script->GetDebugInfo().c_str()); else { float x = step.script->TempSummonCreature.PosX; float y = step.script->TempSummonCreature.PosY; float z = step.script->TempSummonCreature.PosZ; float o = step.script->TempSummonCreature.Orientation; if (!pSummoner->SummonCreature(step.script->TempSummonCreature.CreatureEntry, x, y, z, o, TEMPSUMMON_TIMED_OR_DEAD_DESPAWN, step.script->TempSummonCreature.DespawnDelay)) sLog->outError("%s creature was not spawned (entry: %u).", step.script->GetDebugInfo().c_str(), step.script->TempSummonCreature.CreatureEntry); } } break; } case SCRIPT_COMMAND_OPEN_DOOR: case SCRIPT_COMMAND_CLOSE_DOOR: _ScriptProcessDoor(source, target, step.script); break; case SCRIPT_COMMAND_ACTIVATE_OBJECT: // Source must be Unit. if (Unit* pSource = _GetScriptUnit(source, true, step.script)) { // Target must be GameObject. if (!target) { sLog->outError("%s target object is NULL.", step.script->GetDebugInfo().c_str()); break; } if (target->GetTypeId() != TYPEID_GAMEOBJECT) { sLog->outError("%s target object is not gameobject (TypeId: %u, Entry: %u, GUID: %u), skipping.", step.script->GetDebugInfo().c_str(), target->GetTypeId(), target->GetEntry(), target->GetGUIDLow()); break; } if (GameObject* pGO = target->ToGameObject()) pGO->Use(pSource); } break; case SCRIPT_COMMAND_REMOVE_AURA: { // Source (datalong2 != 0) or target (datalong2 == 0) must be Unit. bool bReverse = step.script->RemoveAura.Flags & SF_REMOVEAURA_REVERSE; if (Unit* pTarget = _GetScriptUnit(bReverse ? source : target, bReverse, step.script)) pTarget->RemoveAurasDueToSpell(step.script->RemoveAura.SpellID); break; } case SCRIPT_COMMAND_CAST_SPELL: { // TODO: Allow gameobjects to be targets and casters if (!source && !target) { sLog->outError("%s source and target objects are NULL.", step.script->GetDebugInfo().c_str()); break; } Unit* uSource = NULL; Unit* uTarget = NULL; // source/target cast spell at target/source (script->datalong2: 0: s->t 1: s->s 2: t->t 3: t->s switch (step.script->CastSpell.Flags) { case SF_CASTSPELL_SOURCE_TO_TARGET: // source -> target uSource = source ? source->ToUnit() : NULL; uTarget = target ? target->ToUnit() : NULL; break; case SF_CASTSPELL_SOURCE_TO_SOURCE: // source -> source uSource = source ? source->ToUnit() : NULL; uTarget = uSource; break; case SF_CASTSPELL_TARGET_TO_TARGET: // target -> target uSource = target ? target->ToUnit() : NULL; uTarget = uSource; break; case SF_CASTSPELL_TARGET_TO_SOURCE: // target -> source uSource = target ? target->ToUnit() : NULL; uTarget = source ? source->ToUnit() : NULL; break; case SF_CASTSPELL_SEARCH_CREATURE: // source -> creature with entry uSource = source ? source->ToUnit() : NULL; uTarget = uSource ? GetClosestCreatureWithEntry(uSource, abs(step.script->CastSpell.CreatureEntry), step.script->CastSpell.SearchRadius) : NULL; break; } if (!uSource || !uSource->isType(TYPEMASK_UNIT)) { sLog->outError("%s no source unit found for spell %u", step.script->GetDebugInfo().c_str(), step.script->CastSpell.SpellID); break; } if (!uTarget || !uTarget->isType(TYPEMASK_UNIT)) { sLog->outError("%s no target unit found for spell %u", step.script->GetDebugInfo().c_str(), step.script->CastSpell.SpellID); break; } bool triggered = (step.script->CastSpell.Flags != 4) ? step.script->CastSpell.CreatureEntry & SF_CASTSPELL_TRIGGERED : step.script->CastSpell.CreatureEntry < 0; uSource->CastSpell(uTarget, step.script->CastSpell.SpellID, triggered); break; } case SCRIPT_COMMAND_PLAY_SOUND: // Source must be WorldObject. if (WorldObject* pSource = _GetScriptWorldObject(source, true, step.script)) { // PlaySound.Flags bitmask: 0/1=anyone/target Player* pTarget = NULL; if (step.script->PlaySound.Flags & SF_PLAYSOUND_TARGET_PLAYER) { // Target must be Player. pTarget = _GetScriptPlayer(target, false, step.script); if (!pTarget) break; } // PlaySound.Flags bitmask: 0/2=without/with distance dependent if (step.script->PlaySound.Flags & SF_PLAYSOUND_DISTANCE_SOUND) pSource->PlayDistanceSound(step.script->PlaySound.SoundID, pTarget); else pSource->PlayDirectSound(step.script->PlaySound.SoundID, pTarget); } break; case SCRIPT_COMMAND_CREATE_ITEM: // Target or source must be Player. if (Player* pReceiver = _GetScriptPlayerSourceOrTarget(source, target, step.script)) { ItemPosCountVec dest; InventoryResult msg = pReceiver->CanStoreNewItem(NULL_BAG, NULL_SLOT, dest, step.script->CreateItem.ItemEntry, step.script->CreateItem.Amount); if (msg == EQUIP_ERR_OK) { if (Item* item = pReceiver->StoreNewItem(dest, step.script->CreateItem.ItemEntry, true)) pReceiver->SendNewItem(item, step.script->CreateItem.Amount, false, true); } else pReceiver->SendEquipError(msg, NULL, NULL, step.script->CreateItem.ItemEntry); } break; case SCRIPT_COMMAND_DESPAWN_SELF: // Target or source must be Creature. if (Creature* cSource = _GetScriptCreatureSourceOrTarget(source, target, step.script, true)) cSource->DespawnOrUnsummon(step.script->DespawnSelf.DespawnDelay); break; case SCRIPT_COMMAND_LOAD_PATH: // Source must be Unit. if (Unit* pSource = _GetScriptUnit(source, true, step.script)) { if (!sWaypointMgr->GetPath(step.script->LoadPath.PathID)) sLog->outError("%s source object has an invalid path (%u), skipping.", step.script->GetDebugInfo().c_str(), step.script->LoadPath.PathID); else pSource->GetMotionMaster()->MovePath(step.script->LoadPath.PathID, step.script->LoadPath.IsRepeatable); } break; case SCRIPT_COMMAND_CALLSCRIPT_TO_UNIT: { if (!step.script->CallScript.CreatureEntry) { sLog->outError("%s creature entry is not specified, skipping.", step.script->GetDebugInfo().c_str()); break; } if (!step.script->CallScript.ScriptID) { sLog->outError("%s script id is not specified, skipping.", step.script->GetDebugInfo().c_str()); break; } Creature* cTarget = NULL; if (source) //using grid searcher { WorldObject* wSource = dynamic_cast <WorldObject*> (source); CellCoord p(Trinity::ComputeCellCoord(wSource->GetPositionX(), wSource->GetPositionY())); Cell cell(p); Trinity::CreatureWithDbGUIDCheck target_check(wSource, step.script->CallScript.CreatureEntry); Trinity::CreatureSearcher<Trinity::CreatureWithDbGUIDCheck> checker(wSource, cTarget, target_check); TypeContainerVisitor<Trinity::CreatureSearcher <Trinity::CreatureWithDbGUIDCheck>, GridTypeMapContainer > unit_checker(checker); cell.Visit(p, unit_checker, *wSource->GetMap(), *wSource, wSource->GetGridActivationRange()); } else //check hashmap holders { if (CreatureData const* data = sObjectMgr->GetCreatureData(step.script->CallScript.CreatureEntry)) cTarget = ObjectAccessor::GetObjectInWorld<Creature>(data->mapid, data->posX, data->posY, MAKE_NEW_GUID(step.script->CallScript.CreatureEntry, data->id, HIGHGUID_UNIT), cTarget); } if (!cTarget) { sLog->outError("%s target was not found (entry: %u)", step.script->GetDebugInfo().c_str(), step.script->CallScript.CreatureEntry); break; } //Lets choose our ScriptMap map ScriptMapMap* datamap = GetScriptsMapByType(ScriptsType(step.script->CallScript.ScriptType)); //if no scriptmap present... if (!datamap) { sLog->outError("%s unknown scriptmap (%u) specified, skipping.", step.script->GetDebugInfo().c_str(), step.script->CallScript.ScriptType); break; } // Insert script into schedule but do not start it ScriptsStart(*datamap, step.script->CallScript.ScriptID, cTarget, NULL); break; } case SCRIPT_COMMAND_KILL: // Source or target must be Creature. if (Creature* cSource = _GetScriptCreatureSourceOrTarget(source, target, step.script)) { if (cSource->isDead()) sLog->outError("%s creature is already dead (Entry: %u, GUID: %u)", step.script->GetDebugInfo().c_str(), cSource->GetEntry(), cSource->GetGUIDLow()); else { cSource->setDeathState(JUST_DIED); if (step.script->Kill.RemoveCorpse == 1) cSource->RemoveCorpse(); } } break; case SCRIPT_COMMAND_ORIENTATION: // Source must be Unit. if (Unit* pSource = _GetScriptUnit(source, true, step.script)) { if (step.script->Orientation.Flags& SF_ORIENTATION_FACE_TARGET) { // Target must be Unit. Unit* pTarget = _GetScriptUnit(target, false, step.script); if (!pTarget) break; pSource->SetInFront(pTarget); } else pSource->SetOrientation(step.script->Orientation.Orientation); pSource->SendMovementFlagUpdate(); } break; case SCRIPT_COMMAND_EQUIP: // Source must be Creature. if (Creature* cSource = _GetScriptCreature(source, true, step.script)) cSource->LoadEquipment(step.script->Equip.EquipmentID); break; case SCRIPT_COMMAND_MODEL: // Source must be Creature. if (Creature* cSource = _GetScriptCreature(source, true, step.script)) cSource->SetDisplayId(step.script->Model.ModelID); break; case SCRIPT_COMMAND_CLOSE_GOSSIP: // Source must be Player. if (Player* pSource = _GetScriptPlayer(source, true, step.script)) pSource->PlayerTalkClass->SendCloseGossip(); break; case SCRIPT_COMMAND_PLAYMOVIE: // Source must be Player. if (Player* pSource = _GetScriptPlayer(source, true, step.script)) pSource->SendMovieStart(step.script->PlayMovie.MovieID); break; default: sLog->outError("Unknown script command %s.", step.script->GetDebugInfo().c_str()); break; } m_scriptSchedule.erase(iter); iter = m_scriptSchedule.begin(); sScriptMgr->DecreaseScheduledScriptCount(); } }
static bool HandleWpShowCommand(ChatHandler* handler, const char* args) { if (!*args) return false; // first arg: on, off, first, last char* show_str = strtok((char*)args, " "); if (!show_str) return false; // second arg: GUID (optional, if a creature is selected) char* guid_str = strtok((char*)NULL, " "); uint32 pathid = 0; Creature* target = handler->getSelectedCreature(); // Did player provide a PathID? if (!guid_str) { // No PathID provided // -> Player must have selected a creature if (!target) { handler->SendSysMessage(LANG_SELECT_CREATURE); handler->SetSentErrorMessage(true); return false; } pathid = target->GetWaypointPath(); } else { // PathID provided // Warn if player also selected a creature // -> Creature selection is ignored <- if (target) handler->SendSysMessage(LANG_WAYPOINT_CREATSELECTED); pathid = atoi((char*)guid_str); } std::string show = show_str; uint32 Maxpoint; //handler->PSendSysMessage("wpshow - show: %s", show); // Show info for the selected waypoint if (show == "info") { // Check if the user did specify a visual waypoint if (target->GetEntry() != VISUAL_WAYPOINT) { handler->PSendSysMessage(LANG_WAYPOINT_VP_SELECT); handler->SetSentErrorMessage(true); return false; } QueryResult result = WorldDatabase.PQuery("SELECT id, point, delay, move_flag, action, action_chance FROM waypoint_data WHERE wpguid = %u", target->GetGUIDLow()); if (!result) { handler->SendSysMessage(LANG_WAYPOINT_NOTFOUNDDBPROBLEM); return true; } handler->SendSysMessage("|cff00ffffDEBUG: wp show info:|r"); do { Field* fields = result->Fetch(); pathid = fields[0].GetUInt32(); uint32 point = fields[1].GetUInt32(); uint32 delay = fields[2].GetUInt32(); uint32 flag = fields[3].GetUInt32(); uint32 ev_id = fields[4].GetUInt32(); uint32 ev_chance = fields[5].GetUInt32(); handler->PSendSysMessage("|cff00ff00Show info: for current point: |r|cff00ffff%u|r|cff00ff00, Path ID: |r|cff00ffff%u|r", point, pathid); handler->PSendSysMessage("|cff00ff00Show info: delay: |r|cff00ffff%u|r", delay); handler->PSendSysMessage("|cff00ff00Show info: Move flag: |r|cff00ffff%u|r", flag); handler->PSendSysMessage("|cff00ff00Show info: Waypoint event: |r|cff00ffff%u|r", ev_id); handler->PSendSysMessage("|cff00ff00Show info: Event chance: |r|cff00ffff%u|r", ev_chance); } while (result->NextRow()); return true; } if (show == "on") { QueryResult result = WorldDatabase.PQuery("SELECT point, position_x, position_y, position_z FROM waypoint_data WHERE id = '%u'", pathid); if (!result) { handler->SendSysMessage("|cffff33ffPath no found.|r"); handler->SetSentErrorMessage(true); return false; } handler->PSendSysMessage("|cff00ff00DEBUG: wp on, PathID: |cff00ffff%u|r", pathid); // Delete all visuals for this NPC QueryResult result2 = WorldDatabase.PQuery("SELECT wpguid FROM waypoint_data WHERE id = '%u' and wpguid <> 0", pathid); if (result2) { bool hasError = false; do { Field* fields = result2->Fetch(); uint32 wpguid = fields[0].GetUInt32(); Creature* creature = handler->GetSession()->GetPlayer()->GetMap()->GetCreature(MAKE_NEW_GUID(wpguid, VISUAL_WAYPOINT, HIGHGUID_UNIT)); if (!creature) { handler->PSendSysMessage(LANG_WAYPOINT_NOTREMOVED, wpguid); hasError = true; WorldDatabase.PExecute("DELETE FROM creature WHERE guid = '%u'", wpguid); } else { creature->CombatStop(); creature->DeleteFromDB(); creature->AddObjectToRemoveList(); } } while (result2->NextRow()); if (hasError) { handler->PSendSysMessage(LANG_WAYPOINT_TOOFAR1); handler->PSendSysMessage(LANG_WAYPOINT_TOOFAR2); handler->PSendSysMessage(LANG_WAYPOINT_TOOFAR3); } } do { Field* fields = result->Fetch(); uint32 point = fields[0].GetUInt32(); float x = fields[1].GetFloat(); float y = fields[2].GetFloat(); float z = fields[3].GetFloat(); uint32 id = VISUAL_WAYPOINT; Player* chr = handler->GetSession()->GetPlayer(); Map* map = chr->GetMap(); float o = chr->GetOrientation(); Creature* wpCreature = new Creature; if (!wpCreature->Create(sObjectMgr->GenerateLowGuid(HIGHGUID_UNIT), map, chr->GetPhaseMaskForSpawn(), id, 0, 0, x, y, z, o)) { handler->PSendSysMessage(LANG_WAYPOINT_VP_NOTCREATED, id); delete wpCreature; return false; } // set "wpguid" column to the visual waypoint WorldDatabase.PExecute("UPDATE waypoint_data SET wpguid = '%u' WHERE id = '%u' and point = '%u'", wpCreature->GetGUIDLow(), pathid, point); wpCreature->SaveToDB(map->GetId(), (1 << map->GetSpawnMode()), chr->GetPhaseMaskForSpawn()); // To call _LoadGoods(); _LoadQuests(); CreateTrainerSpells(); if (!wpCreature->LoadCreatureFromDB(wpCreature->GetDBTableGUIDLow(), map)) { handler->PSendSysMessage(LANG_WAYPOINT_VP_NOTCREATED, id); delete wpCreature; return false; } if (target) { wpCreature->SetDisplayId(target->GetDisplayId()); wpCreature->SetFloatValue(OBJECT_FIELD_SCALE_X, 0.5f); wpCreature->SetLevel(point > STRONG_MAX_LEVEL ? STRONG_MAX_LEVEL : point); } } while (result->NextRow()); handler->SendSysMessage("|cff00ff00Showing the current creature's path.|r"); return true; } if (show == "first") { handler->PSendSysMessage("|cff00ff00DEBUG: wp first, GUID: %u|r", pathid); QueryResult result = WorldDatabase.PQuery("SELECT position_x, position_y, position_z FROM waypoint_data WHERE point='1' AND id = '%u'", pathid); if (!result) { handler->PSendSysMessage(LANG_WAYPOINT_NOTFOUND, pathid); handler->SetSentErrorMessage(true); return false; } Field* fields = result->Fetch(); float x = fields[0].GetFloat(); float y = fields[1].GetFloat(); float z = fields[2].GetFloat(); uint32 id = VISUAL_WAYPOINT; Player* chr = handler->GetSession()->GetPlayer(); float o = chr->GetOrientation(); Map* map = chr->GetMap(); Creature* creature = new Creature; if (!creature->Create(sObjectMgr->GenerateLowGuid(HIGHGUID_UNIT), map, chr->GetPhaseMaskForSpawn(), id, 0, 0, x, y, z, o)) { handler->PSendSysMessage(LANG_WAYPOINT_VP_NOTCREATED, id); delete creature; return false; } creature->SaveToDB(map->GetId(), (1 << map->GetSpawnMode()), chr->GetPhaseMaskForSpawn()); if (!creature->LoadCreatureFromDB(creature->GetDBTableGUIDLow(), map)) { handler->PSendSysMessage(LANG_WAYPOINT_VP_NOTCREATED, id); delete creature; return false; } if (target) { creature->SetDisplayId(target->GetDisplayId()); creature->SetFloatValue(OBJECT_FIELD_SCALE_X, 0.5f); } return true; } if (show == "last") { handler->PSendSysMessage("|cff00ff00DEBUG: wp last, PathID: |r|cff00ffff%u|r", pathid); QueryResult result = WorldDatabase.PQuery("SELECT MAX(point) FROM waypoint_data WHERE id = '%u'", pathid); if (result) Maxpoint = (*result)[0].GetUInt32(); else Maxpoint = 0; result = WorldDatabase.PQuery("SELECT position_x, position_y, position_z, orientation FROM waypoint_data WHERE point ='%u' AND id = '%u'", Maxpoint, pathid); if (!result) { handler->PSendSysMessage(LANG_WAYPOINT_NOTFOUNDLAST, pathid); handler->SetSentErrorMessage(true); return false; } Field* fields = result->Fetch(); float x = fields[0].GetFloat(); float y = fields[1].GetFloat(); float z = fields[2].GetFloat(); float o = fields[3].GetFloat(); uint32 id = VISUAL_WAYPOINT; Player* chr = handler->GetSession()->GetPlayer(); Map* map = chr->GetMap(); Creature* creature = new Creature; if (!creature->Create(sObjectMgr->GenerateLowGuid(HIGHGUID_UNIT), map, chr->GetPhaseMaskForSpawn(), id, 0, 0, x, y, z, o)) { handler->PSendSysMessage(LANG_WAYPOINT_NOTCREATED, id); delete creature; return false; } creature->SaveToDB(map->GetId(), (1 << map->GetSpawnMode()), chr->GetPhaseMaskForSpawn()); if (!creature->LoadCreatureFromDB(creature->GetDBTableGUIDLow(), map)) { handler->PSendSysMessage(LANG_WAYPOINT_NOTCREATED, id); delete creature; return false; } if (target) { creature->SetDisplayId(target->GetDisplayId()); creature->SetFloatValue(OBJECT_FIELD_SCALE_X, 0.5f); } return true; } if (show == "off") { QueryResult result = WorldDatabase.PQuery("SELECT guid FROM creature WHERE id = '%u'", 1); if (!result) { handler->SendSysMessage(LANG_WAYPOINT_VP_NOTFOUND); handler->SetSentErrorMessage(true); return false; } bool hasError = false; do { Field* fields = result->Fetch(); uint32 guid = fields[0].GetUInt32(); Creature* creature = handler->GetSession()->GetPlayer()->GetMap()->GetCreature(MAKE_NEW_GUID(guid, VISUAL_WAYPOINT, HIGHGUID_UNIT)); if (!creature) { handler->PSendSysMessage(LANG_WAYPOINT_NOTREMOVED, guid); hasError = true; WorldDatabase.PExecute("DELETE FROM creature WHERE guid = '%u'", guid); } else { creature->CombatStop(); creature->DeleteFromDB(); creature->AddObjectToRemoveList(); } } while (result->NextRow()); // set "wpguid" column to "empty" - no visual waypoint spawned WorldDatabase.PExecute("UPDATE waypoint_data SET wpguid = '0'"); //WorldDatabase.PExecute("UPDATE creature_movement SET wpguid = '0' WHERE wpguid <> '0'"); if (hasError) { handler->PSendSysMessage(LANG_WAYPOINT_TOOFAR1); handler->PSendSysMessage(LANG_WAYPOINT_TOOFAR2); handler->PSendSysMessage(LANG_WAYPOINT_TOOFAR3); } handler->SendSysMessage(LANG_WAYPOINT_VP_ALLREMOVED); return true; } handler->PSendSysMessage("|cffff33ffDEBUG: wpshow - no valid command found|r"); return true; }
//called when player lists his received mails void WorldSession::HandleGetMailList(WorldPacket & recv_data) { uint64 mailbox; recv_data >> mailbox; if (!GetPlayer()->GetGameObjectIfCanInteractWith(mailbox, GAMEOBJECT_TYPE_MAILBOX)) return; Player* player = _player; //load players mails, and mailed items if (!player->m_mailsLoaded) player ->_LoadMail(); // client can't work with packets > max int16 value const uint32 maxPacketSize = 32767; uint32 mailsCount = 0; // real send to client mails amount uint32 realCount = 0; // real mails amount WorldPacket data(SMSG_MAIL_LIST_RESULT, (200)); // guess size data << uint32(0); // real mail's count data << uint8(0); // mail's count time_t cur_time = time(NULL); for (PlayerMails::iterator itr = player->GetMailBegin(); itr != player->GetMailEnd(); ++itr) { // packet send mail count as uint8, prevent overflow if (mailsCount >= 254) { realCount += 1; continue; } // skip deleted or not delivered (deliver delay not expired) mails if ((*itr)->state == MAIL_STATE_DELETED || cur_time < (*itr)->deliver_time) continue; uint8 item_count = (*itr)->items.size(); // max count is MAX_MAIL_ITEMS (12) size_t next_mail_size = 2+4+1+((*itr)->messageType == MAIL_NORMAL ? 8 : 4)+4*8+((*itr)->subject.size()+1)+((*itr)->body.size()+1)+1+item_count*(1+4+4+7*3*4+4+4+4+4+4+4+1); if (data.wpos()+next_mail_size > maxPacketSize) { realCount += 1; continue; } data << uint16(next_mail_size); // Message size data << uint32((*itr)->messageID); // Message ID data << uint8((*itr)->messageType); // Message Type switch ((*itr)->messageType) { case MAIL_NORMAL: // sender guid data << uint64(MAKE_NEW_GUID((*itr)->sender, 0, HIGHGUID_PLAYER)); break; case MAIL_CREATURE: case MAIL_GAMEOBJECT: case MAIL_AUCTION: data << uint32((*itr)->sender); // creature/gameobject entry, auction id break; case MAIL_ITEM: // item entry (?) sender = "Unknown", NYI data << uint32(0); // item entry break; } data << uint64((*itr)->COD); // COD data << uint32(0); // probably changed in 3.3.3 data << uint32((*itr)->stationery); // stationery (Stationery.dbc) data << uint64((*itr)->money); // Gold data << uint32((*itr)->checked); // flags data << float(((*itr)->expire_time-time(NULL))/DAY); // Time data << uint32((*itr)->mailTemplateId); // mail template (MailTemplate.dbc) data << (*itr)->subject; // Subject string - once 00, when mail type = 3, max 256 data << (*itr)->body; // message? max 8000 data << uint8(item_count); // client limit is 0x10 for (uint8 i = 0; i < item_count; ++i) { Item* item = player->GetMItem((*itr)->items[i].item_guid); // item index (0-6?) data << uint8(i); // item guid low? data << uint32((item ? item->GetGUIDLow() : 0)); // entry data << uint32((item ? item->GetEntry() : 0)); for (uint8 j = 0; j < MAX_INSPECTED_ENCHANTMENT_SLOT; ++j) { data << uint32((item ? item->GetEnchantmentId((EnchantmentSlot)j) : 0)); data << uint32((item ? item->GetEnchantmentDuration((EnchantmentSlot)j) : 0)); data << uint32((item ? item->GetEnchantmentCharges((EnchantmentSlot)j) : 0)); } // Hack Alert! for (uint8 mail_hack = 0; mail_hack < 2; ++mail_hack) { data << uint32(0); data << uint32(0); data << uint32(0); } // can be negative data << int32((item ? item->GetItemRandomPropertyId() : 0)); // unk data << uint32((item ? item->GetItemSuffixFactor() : 0)); // stack count data << uint32((item ? item->GetCount() : 0)); // charges data << uint32((item ? item->GetSpellCharges() : 0)); // durability data << uint32((item ? item->GetUInt32Value(ITEM_FIELD_MAXDURABILITY) : 0)); // durability data << uint32((item ? item->GetUInt32Value(ITEM_FIELD_DURABILITY) : 0)); // unknown wotlk data << uint8(0); } realCount += 1; mailsCount += 1; } data.put<uint32>(0, realCount); // this will display warning about undelivered mail to player if realCount > mailsCount data.put<uint8>(4, mailsCount); // set real send mails to client SendPacket(&data); // recalculate m_nextMailDelivereTime and unReadMails _player->UpdateNextMailTimeAndUnreads(); }
//show info of player bool ChatHandler::HandlePInfoCommand(const char* args) { Player* target; uint64 target_guid; std::string target_name; uint32 parseGUID = MAKE_NEW_GUID(atol((char*)args), 0, HIGHGUID_PLAYER); if (sObjectMgr->GetPlayerNameByGUID(parseGUID, target_name)) { target = sObjectMgr->GetPlayerByLowGUID(parseGUID); target_guid = parseGUID; } else if (!extractPlayerTarget((char*)args, &target, &target_guid, &target_name)) return false; uint32 accId = 0; uint32 money = 0; uint32 total_player_time = 0; uint8 level = 0; uint32 latency = 0; uint8 race; uint8 Class; int64 muteTime = 0; int64 banTime = -1; uint32 mapId; uint32 areaId; uint32 phase = 0; // get additional information from Player object if (target) { // check online security if (HasLowerSecurity(target, 0)) return false; accId = target->GetSession()->GetAccountId(); money = target->GetMoney(); total_player_time = target->GetTotalPlayedTime(); level = target->getLevel(); latency = target->GetSession()->GetLatency(); race = target->getRace(); Class = target->getClass(); muteTime = target->GetSession()->m_muteTime; mapId = target->GetMapId(); areaId = target->GetAreaId(); phase = target->GetPhaseMask(); } // get additional information from DB else { // check offline security if (HasLowerSecurity(NULL, target_guid)) return false; PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_CHAR_PINFO); stmt->setUInt32(0, GUID_LOPART(target_guid)); PreparedQueryResult result = CharacterDatabase.Query(stmt); if (!result) return false; Field* fields = result->Fetch(); total_player_time = fields[0].GetUInt32(); level = fields[1].GetUInt8(); money = fields[2].GetUInt32(); accId = fields[3].GetUInt32(); race = fields[4].GetUInt8(); Class = fields[5].GetUInt8(); mapId = fields[6].GetUInt16(); areaId = fields[7].GetUInt16(); } std::string username = GetTrinityString(LANG_ERROR); std::string email = GetTrinityString(LANG_ERROR); std::string last_ip = GetTrinityString(LANG_ERROR); uint32 security = 0; std::string last_login = GetTrinityString(LANG_ERROR); PreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_SEL_PINFO); stmt->setInt32(0, int32(realmID)); stmt->setUInt32(1, accId); PreparedQueryResult result = LoginDatabase.Query(stmt); if (result) { Field* fields = result->Fetch(); username = fields[0].GetString(); security = fields[1].GetUInt8(); email = fields[2].GetString(); muteTime = fields[5].GetUInt64(); if (email.empty()) email = "-"; if (!m_session || m_session->GetSecurity() >= AccountTypes(security)) { last_ip = fields[3].GetString(); last_login = fields[4].GetString(); uint32 ip = inet_addr(last_ip.c_str()); #if TRINITY_ENDIAN == BIGENDIAN EndianConvertReverse(ip); #endif PreparedStatement* stmt = WorldDatabase.GetPreparedStatement(WORLD_SEL_IP2NATION_COUNTRY); stmt->setUInt32(0, ip); PreparedQueryResult result2 = WorldDatabase.Query(stmt); if (result2) { Field* fields2 = result2->Fetch(); last_ip.append(" ("); last_ip.append(fields2[0].GetString()); last_ip.append(")"); } } else { last_ip = "-"; last_login = "******"; } } std::string nameLink = playerLink(target_name); PSendSysMessage(LANG_PINFO_ACCOUNT, (target?"":GetTrinityString(LANG_OFFLINE)), nameLink.c_str(), GUID_LOPART(target_guid), username.c_str(), accId, email.c_str(), security, last_ip.c_str(), last_login.c_str(), latency); std::string bannedby = "unknown"; std::string banreason = ""; stmt = LoginDatabase.GetPreparedStatement(LOGIN_SEL_PINFO_BANS); stmt->setUInt32(0, accId); PreparedQueryResult result2 = LoginDatabase.Query(stmt); if (!result2) { stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_PINFO_BANS); stmt->setUInt32(0, GUID_LOPART(target_guid)); result2 = CharacterDatabase.Query(stmt); } if (result2) { Field* fields = result2->Fetch(); banTime = int64(fields[1].GetBool() ? 0 : fields[0].GetUInt32()); bannedby = fields[2].GetString(); banreason = fields[3].GetString(); } if (muteTime > 0) PSendSysMessage(LANG_PINFO_MUTE, secsToTimeString(muteTime - time(NULL), true).c_str()); if (banTime >= 0) PSendSysMessage(LANG_PINFO_BAN, banTime > 0 ? secsToTimeString(banTime - time(NULL), true).c_str() : "permanently", bannedby.c_str(), banreason.c_str()); std::string race_s, Class_s; switch (race) { case RACE_HUMAN: race_s = "Human"; break; case RACE_ORC: race_s = "Orc"; break; case RACE_DWARF: race_s = "Dwarf"; break; case RACE_NIGHTELF: race_s = "Night Elf"; break; case RACE_UNDEAD_PLAYER: race_s = "Undead"; break; case RACE_TAUREN: race_s = "Tauren"; break; case RACE_GNOME: race_s = "Gnome"; break; case RACE_TROLL: race_s = "Troll"; break; case RACE_BLOODELF: race_s = "Blood Elf"; break; case RACE_DRAENEI: race_s = "Draenei"; break; } switch (Class) { case CLASS_WARRIOR: Class_s = "Warrior"; break; case CLASS_PALADIN: Class_s = "Paladin"; break; case CLASS_HUNTER: Class_s = "Hunter"; break; case CLASS_ROGUE: Class_s = "Rogue"; break; case CLASS_PRIEST: Class_s = "Priest"; break; case CLASS_DEATH_KNIGHT: Class_s = "Death Knight"; break; case CLASS_SHAMAN: Class_s = "Shaman"; break; case CLASS_MAGE: Class_s = "Mage"; break; case CLASS_WARLOCK: Class_s = "Warlock"; break; case CLASS_DRUID: Class_s = "Druid"; break; } std::string timeStr = secsToTimeString(total_player_time, true, true); uint32 gold = money /GOLD; uint32 silv = (money % GOLD) / SILVER; uint32 copp = (money % GOLD) % SILVER; PSendSysMessage(LANG_PINFO_LEVEL, race_s.c_str(), Class_s.c_str(), timeStr.c_str(), level, gold, silv, copp); // Add map, zone, subzone and phase to output int locale = GetSessionDbcLocale(); std::string areaName = "<unknown>"; std::string zoneName = ""; MapEntry const* map = sMapStore.LookupEntry(mapId); AreaTableEntry const* area = GetAreaEntryByAreaID(areaId); if (area) { areaName = area->area_name[locale]; AreaTableEntry const* zone = GetAreaEntryByAreaID(area->zone); if (zone) zoneName = zone->area_name[locale]; } if (target) { if (!zoneName.empty()) PSendSysMessage(LANG_PINFO_MAP_ONLINE, map->name[locale], zoneName.c_str(), areaName.c_str(), phase); else PSendSysMessage(LANG_PINFO_MAP_ONLINE, map->name[locale], areaName.c_str(), "<unknown>", phase); } else PSendSysMessage(LANG_PINFO_MAP_OFFLINE, map->name[locale], areaName.c_str()); return true; }
//does not clear ram void AuctionHouseMgr::SendAuctionWonMail(AuctionEntry* auction, SQLTransaction& trans) { Item* pItem = GetAItem(auction->itemGUIDLow); if (!pItem) return; uint32 bidderAccId = 0; uint64 bidderGuid = MAKE_NEW_GUID(auction->bidder, 0, HIGHGUID_PLAYER); Player* bidder = ObjectAccessor::FindPlayer(bidderGuid); // data for gm.log std::string bidderName; bool logGmTrade = false; if (bidder) { bidderAccId = bidder->GetSession()->GetAccountId(); bidderName = bidder->GetName(); logGmTrade = bidder->GetSession()->HasPermission(RBAC_PERM_LOG_GM_TRADE); } else { bidderAccId = sObjectMgr->GetPlayerAccountIdByGUID(bidderGuid); logGmTrade = AccountMgr::HasPermission(bidderAccId, RBAC_PERM_LOG_GM_TRADE, realmID); if (logGmTrade && !sObjectMgr->GetPlayerNameByGUID(bidderGuid, bidderName)) bidderName = sObjectMgr->GetTrinityStringForDBCLocale(LANG_UNKNOWN); } if (logGmTrade) { std::string ownerName; if (!sObjectMgr->GetPlayerNameByGUID(auction->owner, ownerName)) ownerName = sObjectMgr->GetTrinityStringForDBCLocale(LANG_UNKNOWN); uint32 ownerAccId = sObjectMgr->GetPlayerAccountIdByGUID(auction->owner); sLog->outCommand(bidderAccId, "GM %s (Account: %u) won item in auction: %s (Entry: %u Count: %u) and pay money: %u. Original owner %s (Account: %u)", bidderName.c_str(), bidderAccId, pItem->GetTemplate()->Name1.c_str(), pItem->GetEntry(), pItem->GetCount(), auction->bid, ownerName.c_str(), ownerAccId); } // receiver exist if (bidder || bidderAccId) { // set owner to bidder (to prevent delete item with sender char deleting) // owner in `data` will set at mail receive and item extracting PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_UPD_ITEM_OWNER); stmt->setUInt32(0, auction->bidder); stmt->setUInt32(1, pItem->GetGUIDLow()); trans->Append(stmt); if (bidder) { bidder->GetSession()->SendAuctionBidderNotification(auction->GetHouseId(), auction->Id, bidderGuid, 0, 0, auction->itemEntry); // FIXME: for offline player need also bidder->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_WON_AUCTIONS, 1); } MailDraft(auction->BuildAuctionMailSubject(AUCTION_WON), AuctionEntry::BuildAuctionMailBody(auction->owner, auction->bid, auction->buyout, 0, 0)) .AddItem(pItem) .SendMailTo(trans, MailReceiver(bidder, auction->bidder), auction, MAIL_CHECK_MASK_COPIED); } }
static bool HandleGameObjectTargetCommand(ChatHandler* handler, char const* args) { Player* player = handler->GetSession()->GetPlayer(); QueryResult result; GameEventMgr::ActiveEvents const& activeEventsList = sGameEventMgr->GetActiveEventList(); if (*args) { // number or [name] Shift-click form |color|Hgameobject_entry:go_id|h[name]|h|r char* id = handler->extractKeyFromLink((char*)args, "Hgameobject_entry"); if (!id) return false; uint32 objectId = atol(id); if (objectId) result = WorldDatabase.PQuery("SELECT guid, id, position_x, position_y, position_z, orientation, map, phaseMask, (POW(position_x - '%f', 2) + POW(position_y - '%f', 2) + POW(position_z - '%f', 2)) AS order_ FROM gameobject WHERE map = '%i' AND id = '%u' ORDER BY order_ ASC LIMIT 1", player->GetPositionX(), player->GetPositionY(), player->GetPositionZ(), player->GetMapId(), objectId); else { std::string name = id; WorldDatabase.EscapeString(name); result = WorldDatabase.PQuery( "SELECT guid, id, position_x, position_y, position_z, orientation, map, phaseMask, (POW(position_x - %f, 2) + POW(position_y - %f, 2) + POW(position_z - %f, 2)) AS order_ " "FROM gameobject, gameobject_template WHERE gameobject_template.entry = gameobject.id AND map = %i AND name "_LIKE_" "_CONCAT3_("'%%'", "'%s'", "'%%'")" ORDER BY order_ ASC LIMIT 1", player->GetPositionX(), player->GetPositionY(), player->GetPositionZ(), player->GetMapId(), name.c_str()); } } else { std::ostringstream eventFilter; eventFilter << " AND (eventEntry IS NULL "; bool initString = true; for (GameEventMgr::ActiveEvents::const_iterator itr = activeEventsList.begin(); itr != activeEventsList.end(); ++itr) { if (initString) { eventFilter << "OR eventEntry IN (" << *itr; initString = false; } else eventFilter << ',' << *itr; } if (!initString) eventFilter << "))"; else eventFilter << ')'; result = WorldDatabase.PQuery("SELECT gameobject.guid, id, position_x, position_y, position_z, orientation, map, phaseMask, " "(POW(position_x - %f, 2) + POW(position_y - %f, 2) + POW(position_z - %f, 2)) AS order_ FROM gameobject " "LEFT OUTER JOIN game_event_gameobject on gameobject.guid = game_event_gameobject.guid WHERE map = '%i' %s ORDER BY order_ ASC LIMIT 10", handler->GetSession()->GetPlayer()->GetPositionX(), handler->GetSession()->GetPlayer()->GetPositionY(), handler->GetSession()->GetPlayer()->GetPositionZ(), handler->GetSession()->GetPlayer()->GetMapId(), eventFilter.str().c_str()); } if (!result) { handler->SendSysMessage(LANG_COMMAND_TARGETOBJNOTFOUND); return true; } bool found = false; float x, y, z, o; uint32 guidLow, id; uint16 mapId, phase; uint32 poolId; do { Field* fields = result->Fetch(); guidLow = fields[0].GetUInt32(); id = fields[1].GetUInt32(); x = fields[2].GetFloat(); y = fields[3].GetFloat(); z = fields[4].GetFloat(); o = fields[5].GetFloat(); mapId = fields[6].GetUInt16(); phase = fields[7].GetUInt16(); poolId = sPoolMgr->IsPartOfAPool<GameObject>(guidLow); if (!poolId || sPoolMgr->IsSpawnedObject<GameObject>(guidLow)) found = true; } while (result->NextRow() && !found); if (!found) { handler->PSendSysMessage(LANG_GAMEOBJECT_NOT_EXIST, id); return false; } GameObjectTemplate const* objectInfo = sObjectMgr->GetGameObjectTemplate(id); if (!objectInfo) { handler->PSendSysMessage(LANG_GAMEOBJECT_NOT_EXIST, id); return false; } GameObject* target = handler->GetSession()->GetPlayer()->GetMap()->GetGameObject(MAKE_NEW_GUID(guidLow, id, HIGHGUID_GAMEOBJECT)); handler->PSendSysMessage(LANG_GAMEOBJECT_DETAIL, guidLow, objectInfo->name.c_str(), guidLow, id, x, y, z, mapId, o, phase); if (target) { int32 curRespawnDelay = int32(target->GetRespawnTimeEx() - time(NULL)); if (curRespawnDelay < 0) curRespawnDelay = 0; std::string curRespawnDelayStr = secsToTimeString(curRespawnDelay, true); std::string defRespawnDelayStr = secsToTimeString(target->GetRespawnDelay(), true); handler->PSendSysMessage(LANG_COMMAND_RAWPAWNTIMES, defRespawnDelayStr.c_str(), curRespawnDelayStr.c_str()); } return true; }
void WorldSession::HandlePetitionShowSignOpcode(WorldPacket& recvData) { TC_LOG_DEBUG("network", "Received opcode CMSG_PETITION_SHOW_SIGNATURES"); uint8 playerCount = 0; ObjectGuid petitionGuid; recvData.ReadGuidMask(petitionGuid, 3, 7, 2, 4, 5, 6, 0, 1); recvData.ReadGuidBytes(petitionGuid, 2, 4, 5, 7, 1, 0, 3, 6); // solve (possible) some strange compile problems with explicit use GUID_LOPART(petitionguid) at some GCC versions (wrong code optimization in compiler?) uint32 petitionGuidLow = GUID_LOPART(petitionGuid); PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_PETITION_TYPE); stmt->setUInt32(0, petitionGuidLow); PreparedQueryResult result = CharacterDatabase.Query(stmt); if (!result) { TC_LOG_DEBUG("entities.player.items", "Petition %u is not found for player %u %s", GUID_LOPART(petitionGuid), GetPlayer()->GetGUIDLow(), GetPlayer()->GetName().c_str()); return; } Field* fields = result->Fetch(); uint32 type = fields[0].GetUInt8(); // if guild petition and has guild => error, return; if (type == GUILD_CHARTER_TYPE && _player->GetGuildId()) return; stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_PETITION_SIGNATURE); stmt->setUInt32(0, petitionGuidLow); result = CharacterDatabase.Query(stmt); // result == NULL also correct in case no sign yet if (result) playerCount = uint8(result->GetRowCount()); TC_LOG_DEBUG("network", "CMSG_PETITION_SHOW_SIGNATURES petition entry: '%u'", petitionGuidLow); ObjectGuid playerGuid = _player->GetGUID(); ObjectGuid* playerGuids = new ObjectGuid[playerCount]; for (uint8 i = 0; i < playerCount; ++i) { Field* fields2 = result->Fetch(); uint32 lowGuid = fields2[0].GetUInt32(); playerGuids[i] = MAKE_NEW_GUID(lowGuid, 0, HIGHGUID_PLAYER); result->NextRow(); } WorldPacket data(SMSG_PETITION_SHOW_SIGNATURES, (9 + 9 + 3 + 4 + playerCount * (9 + 4))); data.WriteBit(playerGuid[1]); data.WriteBit(petitionGuid[3]); data.WriteBit(playerGuid[3]); data.WriteGuidMask(petitionGuid, 4, 0); data.WriteGuidMask(playerGuid, 7, 5); data.WriteGuidMask(petitionGuid, 1, 5, 7); data.WriteGuidMask(playerGuid, 0, 6); data.WriteBit(petitionGuid[6]); data.WriteGuidMask(playerGuid, 2, 4); data.WriteBits(playerCount, 21); for (int i = 0; i < playerCount; i++) { data.WriteGuidMask(playerGuids[i], 2, 0, 4, 7, 5, 1, 6, 3); } data.WriteBit(petitionGuid[2]); data.FlushBits(); for (int i = 0; i < playerCount; i++) { data.WriteGuidBytes(playerGuids[i], 6, 0, 1, 3, 2, 5, 7, 4); data << uint32(1); // Choice ??? Blizzard also stores declined players ??? } data.WriteGuidBytes(petitionGuid, 6, 5, 4); data.WriteByteSeq(playerGuid[4]); data.WriteByteSeq(petitionGuid[1]); data << uint32(petitionGuidLow); // guildID data.WriteGuidBytes(petitionGuid, 2, 3, 7); data.WriteGuidBytes(playerGuid, 5, 6, 3, 7, 1, 0); data.WriteByteSeq(petitionGuid[0]); data.WriteByteSeq(playerGuid[2]); delete[] playerGuids; SendPacket(&data); }
void PoolGroup<Creature>::ReSpawn1Object(PoolObject* obj) { if (CreatureData const* data = sObjectMgr->GetCreatureData(obj->guid)) if (Creature* pCreature = ObjectAccessor::GetObjectInWorld(MAKE_NEW_GUID(obj->guid, data->id, HIGHGUID_UNIT), (Creature*)NULL)) pCreature->GetMap()->Add(pCreature); }
void WorldSession::HandlePetitionSignOpcode(WorldPacket& recvData) { TC_LOG_DEBUG("network", "Received opcode CMSG_PETITION_SIGN"); // ok Field* fields; ObjectGuid petitionGuid; recvData.read_skip<uint8>(); recvData.ReadGuidMask(petitionGuid, 4, 2, 0, 1, 5, 3, 6, 7); recvData.ReadGuidBytes(petitionGuid, 6, 1, 7, 2, 5, 3, 0, 4); PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_PETITION_SIGNATURES); stmt->setUInt32(0, GUID_LOPART(petitionGuid)); stmt->setUInt32(1, GUID_LOPART(petitionGuid)); PreparedQueryResult result = CharacterDatabase.Query(stmt); if (!result) { TC_LOG_ERROR("network", "Petition %u is not found for player %u %s", GUID_LOPART(petitionGuid), GetPlayer()->GetGUIDLow(), GetPlayer()->GetName().c_str()); return; } fields = result->Fetch(); uint64 ownerGuid = MAKE_NEW_GUID(fields[0].GetUInt32(), 0, HIGHGUID_PLAYER); uint64 signs = fields[1].GetUInt64(); uint8 type = fields[2].GetUInt8(); uint32 playerGuid = _player->GetGUIDLow(); if (GUID_LOPART(ownerGuid) == playerGuid) return; // not let enemies sign guild charter if (!sWorld->getBoolConfig(CONFIG_ALLOW_TWO_SIDE_INTERACTION_GUILD) && GetPlayer()->GetTeam() != sObjectMgr->GetPlayerTeamByGUID(ownerGuid)) { Guild::SendCommandResult(this, GUILD_COMMAND_CREATE, ERR_GUILD_NOT_ALLIED); return; } if (_player->GetGuildId()) { Guild::SendCommandResult(this, GUILD_COMMAND_INVITE, ERR_ALREADY_IN_GUILD_S, _player->GetName()); return; } if (_player->GetGuildIdInvited()) { Guild::SendCommandResult(this, GUILD_COMMAND_INVITE, ERR_ALREADY_INVITED_TO_GUILD_S, _player->GetName()); return; } if (++signs > type) // client signs maximum return; // Client doesn't allow to sign petition two times by one character, but not check sign by another character from same account // not allow sign another player from already sign player account stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_PETITION_SIG_BY_ACCOUNT); stmt->setUInt32(0, GetAccountId()); stmt->setUInt32(1, GUID_LOPART(petitionGuid)); result = CharacterDatabase.Query(stmt); if (result) { // close at signer side SendPetitionSignResults(petitionGuid, _player->GetGUID(), PETITION_SIGN_ALREADY_SIGNED); return; } stmt = CharacterDatabase.GetPreparedStatement(CHAR_INS_PETITION_SIGNATURE); stmt->setUInt32(0, GUID_LOPART(ownerGuid)); stmt->setUInt32(1, GUID_LOPART(petitionGuid)); stmt->setUInt32(2, playerGuid); stmt->setUInt32(3, GetAccountId()); CharacterDatabase.Execute(stmt); TC_LOG_DEBUG("network", "PETITION SIGN: GUID %u by player: %s (GUID: %u Account: %u)", GUID_LOPART(petitionGuid), _player->GetName().c_str(), playerGuid, GetAccountId()); // close at signer side SendPetitionSignResults(petitionGuid, _player->GetGUID(), PETITION_SIGN_OK); // update signs count on charter, required testing... //Item* item = _player->GetItemByGuid(petitionguid)); //if (item) // item->SetUInt32Value(ITEM_FIELD_ENCHANTMENT+1, signs); // update for owner if online if (Player* owner = ObjectAccessor::FindPlayer(ownerGuid)) owner->GetSession()->SendPetitionSignResults(petitionGuid, _player->GetGUID(), PETITION_SIGN_OK); }
void PoolGroup<GameObject>::ReSpawn1Object(PoolObject* obj) { if (GameObjectData const* data = sObjectMgr->GetGOData(obj->guid)) if (GameObject* pGameobject = ObjectAccessor::GetObjectInWorld(MAKE_NEW_GUID(obj->guid, data->id, HIGHGUID_GAMEOBJECT), (GameObject*)NULL)) pGameobject->GetMap()->Add(pGameobject); }
void WorldSession::HandleTurnInPetitionOpcode(WorldPacket& recvData) { TC_LOG_DEBUG("network", "Received opcode CMSG_TURN_IN_PETITION"); // Get petition guid from packet WorldPacket data; ObjectGuid petitionGuid; recvData.ReadGuidMask(petitionGuid, 1, 2, 3, 0, 5, 7, 4, 6); recvData.ReadGuidBytes(petitionGuid, 2, 1, 4, 6, 0, 7, 5, 3); // Check if player really has the required petition charter Item* item = _player->GetItemByGuid(petitionGuid); if (!item) return; TC_LOG_DEBUG("network", "Petition %u turned in by %u", GUID_LOPART(petitionGuid), _player->GetGUIDLow()); // Get petition data from db uint32 ownerguidlo; uint32 type; std::string name; PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_PETITION); stmt->setUInt32(0, GUID_LOPART(petitionGuid)); PreparedQueryResult result = CharacterDatabase.Query(stmt); if (result) { Field* fields = result->Fetch(); ownerguidlo = fields[0].GetUInt32(); name = fields[1].GetString(); type = fields[2].GetUInt8(); } else { TC_LOG_ERROR("network", "Player %s (guid: %u) tried to turn in petition (guid: %u) that is not present in the database", _player->GetName().c_str(), _player->GetGUIDLow(), GUID_LOPART(petitionGuid)); return; } // Only the petition owner can turn in the petition if (_player->GetGUIDLow() != ownerguidlo) return; // Petition type (guild/arena) specific checks // Check if player is already in a guild if (_player->GetGuildId()) { data.Initialize(SMSG_TURN_IN_PETITION_RESULTS, 1); data.WriteBits(PETITION_TURN_ALREADY_IN_GUILD, 4); data.FlushBits(); _player->GetSession()->SendPacket(&data); return; } // Check if guild name is already taken if (sGuildMgr->GetGuildByName(name)) { Guild::SendCommandResult(this, GUILD_COMMAND_CREATE, ERR_GUILD_NAME_EXISTS_S, name); return; } // Get petition signatures from db uint8 signatures; stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_PETITION_SIGNATURE); stmt->setUInt32(0, GUID_LOPART(petitionGuid)); result = CharacterDatabase.Query(stmt); if (result) signatures = uint8(result->GetRowCount()); else signatures = 0; uint32 requiredSignatures; if (type == GUILD_CHARTER_TYPE) requiredSignatures = sWorld->getIntConfig(CONFIG_MIN_PETITION_SIGNS); else requiredSignatures = type-1; // Notify player if signatures are missing if (signatures < requiredSignatures) { data.Initialize(SMSG_TURN_IN_PETITION_RESULTS, 1); data.WriteBits(PETITION_TURN_NEED_MORE_SIGNATURES, 4); data.FlushBits(); SendPacket(&data); return; } // Proceed with guild/arena team creation // Delete charter item _player->DestroyItem(item->GetBagSlot(), item->GetSlot(), true); // Create guild Guild* guild = new Guild; if (!guild->Create(_player, name)) { delete guild; return; } // Register guild and add guild master sGuildMgr->AddGuild(guild); Guild::SendCommandResult(this, GUILD_COMMAND_CREATE, ERR_GUILD_COMMAND_SUCCESS, name); // Add members from signatures for (uint8 i = 0; i < signatures; ++i) { Field* fields = result->Fetch(); guild->AddMember(MAKE_NEW_GUID(fields[0].GetUInt32(), 0, HIGHGUID_PLAYER)); result->NextRow(); } SQLTransaction trans = CharacterDatabase.BeginTransaction(); stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_PETITION_BY_GUID); stmt->setUInt32(0, GUID_LOPART(petitionGuid)); trans->Append(stmt); stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_PETITION_SIGNATURE_BY_GUID); stmt->setUInt32(0, GUID_LOPART(petitionGuid)); trans->Append(stmt); CharacterDatabase.CommitTransaction(trans); // created TC_LOG_DEBUG("network", "TURN IN PETITION GUID %u", GUID_LOPART(petitionGuid)); data.Initialize(SMSG_TURN_IN_PETITION_RESULTS, 1); data.WriteBits(PETITION_TURN_OK, 4); data.FlushBits(); SendPacket(&data); }
AccountOpResult DeleteAccount(uint32 accountId) { // Check if accounts exists PreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_SEL_ACCOUNT_BY_ID); stmt->setUInt32(0, accountId); PreparedQueryResult result = LoginDatabase.Query(stmt); if (!result) return AOR_NAME_NOT_EXIST; // Obtain accounts characters stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_CHARS_BY_ACCOUNT_ID); stmt->setUInt32(0, accountId); result = CharacterDatabase.Query(stmt); if (result) { do { uint32 guidLow = (*result)[0].GetUInt32(); uint64 guid = MAKE_NEW_GUID(guidLow, 0, HIGHGUID_PLAYER); // Kick if player is online if (Player* p = ObjectAccessor::FindPlayer(guid)) { WorldSession* s = p->GetSession(); s->KickPlayer(); // mark session to remove at next session list update s->LogoutPlayer(false); // logout player without waiting next session list update } Player::DeleteFromDB(guid, accountId, false); // no need to update realm characters } while (result->NextRow()); } // table realm specific but common for all characters of account for realm stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_TUTORIALS); stmt->setUInt32(0, accountId); CharacterDatabase.Execute(stmt); stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_ACCOUNT_DATA); stmt->setUInt32(0, accountId); CharacterDatabase.Execute(stmt); stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_CHARACTER_BAN); stmt->setUInt32(0, accountId); CharacterDatabase.Execute(stmt); SQLTransaction trans = LoginDatabase.BeginTransaction(); stmt = LoginDatabase.GetPreparedStatement(LOGIN_DEL_ACCOUNT); stmt->setUInt32(0, accountId); trans->Append(stmt); stmt = LoginDatabase.GetPreparedStatement(LOGIN_DEL_ACCOUNT_ACCESS); stmt->setUInt32(0, accountId); trans->Append(stmt); stmt = LoginDatabase.GetPreparedStatement(LOGIN_DEL_REALM_CHARACTERS); stmt->setUInt32(0, accountId); trans->Append(stmt); stmt = LoginDatabase.GetPreparedStatement(LOGIN_DEL_ACCOUNT_BANNED); stmt->setUInt32(0, accountId); trans->Append(stmt); LoginDatabase.CommitTransaction(trans); return AOR_OK; }
//this function is called when client bids or buys out auction void WorldSession::HandleAuctionPlaceBid(WorldPacket & recv_data) { uint64 auctioneer; uint32 auctionId; uint64 price; recv_data >> auctioneer; recv_data >> auctionId >> price; if (!auctionId || !price) return; //check for cheaters Creature *pCreature = GetPlayer()->GetNPCIfCanInteractWith(auctioneer, UNIT_NPC_FLAG_AUCTIONEER); if (!pCreature) { sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: HandleAuctionPlaceBid - Unit (GUID: %u) not found or you can't interact with him.", uint32(GUID_LOPART(auctioneer))); return; } // remove fake death if (GetPlayer()->HasUnitState(UNIT_STAT_DIED)) GetPlayer()->RemoveAurasByType(SPELL_AURA_FEIGN_DEATH); AuctionHouseObject *auctionHouse = sAuctionMgr->GetAuctionsMap(pCreature->getFaction()); AuctionEntry *auction = auctionHouse->GetAuction(auctionId); Player *pl = GetPlayer(); if (!auction || auction->owner == pl->GetGUIDLow()) { //you cannot bid your own auction: SendAuctionCommandResult(0, AUCTION_PLACE_BID, CANNOT_BID_YOUR_AUCTION_ERROR); return; } // impossible have online own another character (use this for speedup check in case online owner) Player* auction_owner = sObjectMgr->GetPlayer(MAKE_NEW_GUID(auction->owner, 0, HIGHGUID_PLAYER)); if (!auction_owner && sObjectMgr->GetPlayerAccountIdByGUID(MAKE_NEW_GUID(auction->owner, 0, HIGHGUID_PLAYER)) == pl->GetSession()->GetAccountId()) { //you cannot bid your another character auction: SendAuctionCommandResult(0, AUCTION_PLACE_BID, CANNOT_BID_YOUR_AUCTION_ERROR); return; } // cheating if (price <= auction->bid || price < auction->startbid) return; // price too low for next bid if not buyout if ((price < auction->buyout || auction->buyout == 0) && price < auction->bid + auction->GetAuctionOutBid()) { //auction has already higher bid, client tests it! return; } if (!pl->HasEnoughMoney((uint32)price)) { //you don't have enought money!, client tests! //SendAuctionCommandResult(auction->auctionId, AUCTION_PLACE_BID, ???); return; } SQLTransaction trans = CharacterDatabase.BeginTransaction(); if (price < auction->buyout || auction->buyout == 0) { if (auction->bidder > 0) { if (auction->bidder == pl->GetGUIDLow()) pl->ModifyMoney(-int32(price - auction->bid)); else { // mail to last bidder and return money sAuctionMgr->SendAuctionOutbiddedMail(auction, price, GetPlayer(), trans); pl->ModifyMoney(-int32(price)); } } else pl->ModifyMoney(-int32(price)); auction->bidder = pl->GetGUIDLow(); auction->bid = price; GetPlayer()->GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_HIGHEST_AUCTION_BID, price); trans->PAppend("UPDATE auctionhouse SET buyguid = '%u', lastbid = '%u' WHERE id = '%u'", auction->bidder, auction->bid, auction->Id); SendAuctionCommandResult(auction->Id, AUCTION_PLACE_BID, AUCTION_OK, 0); } else { //buyout: if (pl->GetGUIDLow() == auction->bidder) pl->ModifyMoney(-int32(auction->buyout - auction->bid)); else { pl->ModifyMoney(-int32(auction->buyout)); if (auction->bidder) //buyout for bidded auction .. sAuctionMgr->SendAuctionOutbiddedMail(auction, auction->buyout, GetPlayer(), trans); } auction->bidder = pl->GetGUIDLow(); auction->bid = auction->buyout; GetPlayer()->GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_HIGHEST_AUCTION_BID, auction->buyout); //- Mails must be under transaction control too to prevent data loss sAuctionMgr->SendAuctionSalePendingMail(auction, trans); sAuctionMgr->SendAuctionSuccessfulMail(auction, trans); sAuctionMgr->SendAuctionWonMail(auction, trans); SendAuctionCommandResult(auction->Id, AUCTION_PLACE_BID, AUCTION_OK); auction->DeleteFromDB(trans); uint32 item_template = auction->item_template; sAuctionMgr->RemoveAItem(auction->item_guidlow); auctionHouse->RemoveAuction(auction, item_template); } pl->SaveInventoryAndGoldToDB(trans); CharacterDatabase.CommitTransaction(trans); }
bool Item::LoadFromDB(uint32 guid, uint64 owner_guid, Field* fields, uint32 entry) { // 0 1 2 3 4 5 6 7 8 9 10 //result = CharacterDatabase.PQuery("SELECT creatorGuid, giftCreatorGuid, count, duration, charges, flags, enchantments, randomPropertyId, durability, playedTime, text FROM item_instance WHERE guid = '%u'", guid); // create item before any checks for store correct guid // and allow use "FSetState(ITEM_REMOVED); SaveToDB();" for deleting item from DB Object::_Create(guid, 0, HIGHGUID_ITEM); // Set entry, MUST be before proto check SetEntry(entry); SetFloatValue(OBJECT_FIELD_SCALE_X, 1.0f); ItemTemplate const* proto = GetTemplate(); if (!proto) return false; // set owner (not if item is only loaded for gbank/auction/mail if (owner_guid != 0) SetOwnerGUID(owner_guid); bool need_save = false; // need explicit save data at load fixes SetUInt64Value(ITEM_FIELD_CREATOR, MAKE_NEW_GUID(fields[0].GetUInt32(), 0, HIGHGUID_PLAYER)); SetUInt64Value(ITEM_FIELD_GIFTCREATOR, MAKE_NEW_GUID(fields[1].GetUInt32(), 0, HIGHGUID_PLAYER)); SetCount(fields[2].GetUInt32()); uint32 duration = fields[3].GetUInt32(); SetUInt32Value(ITEM_FIELD_DURATION, duration); // update duration if need, and remove if not need if ((proto->Duration == 0) != (duration == 0)) { SetUInt32Value(ITEM_FIELD_DURATION, abs(proto->Duration)); need_save = true; } Tokens tokens(fields[4].GetString(), ' ', MAX_ITEM_PROTO_SPELLS); if (tokens.size() == MAX_ITEM_PROTO_SPELLS) for (uint8 i = 0; i < MAX_ITEM_PROTO_SPELLS; ++i) SetSpellCharges(i, atoi(tokens[i])); SetUInt32Value(ITEM_FIELD_FLAGS, fields[5].GetUInt32()); // Remove bind flag for items vs NO_BIND set if (IsSoulBound() && proto->Bonding == NO_BIND) { ApplyModFlag(ITEM_FIELD_FLAGS, ITEM_FLAG_SOULBOUND, false); need_save = true; } std::string enchants = fields[6].GetString(); //_LoadIntoDataField(enchants.c_str(), ITEM_FIELD_ENCHANTMENT_1_1, MAX_ENCHANTMENT_SLOT * MAX_ENCHANTMENT_OFFSET); { // NOTE: // in the recent update of reforge system, definition of EnchantmentSlot has been changed, // and MAX_ENCHANTMENT_SLOT has been changed from 13 to 14, // which makes enchantments column of item_instance table incompatible with previous version. // in this case we will load only first 9 enchantment slots (0-8, for permanent, temporary, sockets, bonus, prismatic and reforge) // and ignore the remaining ones (9-13, for random properties). // which means item random properties will be lost after this update. // after player logging in and saving the inventory, enchantments column will be properly updated. uint32 count = MAX_ENCHANTMENT_SLOT * MAX_ENCHANTMENT_OFFSET; Tokens tokens(enchants, ' ', count); if (tokens.size() < MAX_ENCHANTMENT_SLOT * MAX_ENCHANTMENT_OFFSET) count = REFORGE_ENCHANTMENT_SLOT * MAX_ENCHANTMENT_OFFSET; for (uint32 index = 0; index < count; ++index) m_uint32Values[ITEM_FIELD_ENCHANTMENT_1_1 + index] = index < tokens.size() ? atol(tokens[index]) : 0; } SetInt32Value(ITEM_FIELD_RANDOM_PROPERTIES_ID, fields[7].GetInt16()); // recalculate suffix factor if (GetItemRandomPropertyId() < 0) UpdateItemSuffixFactor(); uint32 durability = fields[8].GetUInt16(); SetUInt32Value(ITEM_FIELD_DURABILITY, durability); // update max durability (and durability) if need SetUInt32Value(ITEM_FIELD_MAXDURABILITY, proto->MaxDurability); if (durability > proto->MaxDurability) { SetUInt32Value(ITEM_FIELD_DURABILITY, proto->MaxDurability); need_save = true; } SetUInt32Value(ITEM_FIELD_CREATE_PLAYED_TIME, fields[9].GetUInt32()); SetText(fields[10].GetString()); if (need_save) // normal item changed state set not work at loading { PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_UPDATE_ITEM_INSTANCE_ON_LOAD); stmt->setUInt32(0, GetUInt32Value(ITEM_FIELD_DURATION)); stmt->setUInt32(1, GetUInt32Value(ITEM_FIELD_FLAGS)); stmt->setUInt32(2, GetUInt32Value(ITEM_FIELD_DURABILITY)); stmt->setUInt32(3, guid); CharacterDatabase.Execute(stmt); } return true; }